Engineering

7 min lezen 20 apr 2026

De .sky-taal: een diepgaande analyse

Waarom een nieuwe taal?

De meeste workflowtools gaan ofwel te ver in abstractie (drag-and-drop, geen ontsnappingsmogelijkheid) of te laag niveau (Python schrijven, eigen toestandsmachine beheren). We wilden iets er tussenin: tekstgebaseerd, versiebeheervriendelijk, leesbaar voor niet-technici, maar expressief genoeg voor echte productie-workflows.

Het resultaat is .sky.

De vier bloktypes

Elk .sky-bestand is een reeks blokken gescheiden door Unicode-scheidingstekens.

Meta-blok (⊕meta⊕ ... ⊕⊕)

Defineert de workflow zelf: naam, beschrijving, triggerconfiguratie, vereiste geheimen en outputstijl.

⊕meta⊕
name = "fix-issue"
description = "Triage a GitHub issue and plan a fix"
trigger.github.events = ["issues.labeled"]
secrets = ["GITHUB_TOKEN"]
output_style = "terse"
⊕⊕

Knooppuntconfiguratieblok (§name§ ... §§)

Configureert een enkel knooppunt: model, inspanningsniveau, afhankelijkheden, budget, isolatiemodus.

§plan§
model = "opus"
effort = "high"
depends_on = ["fetch"]
isolation = "worktree"
max_budget_usd = 0.5
§§

Promptblok (∆name∆ ... ∆∆)

De daadwerkelijke instructies voor het knooppunt. Ondersteunt sjabloonvariabelen van eerdere knooppuntuitvoer.

∆plan∆
Issue details:
$fetch.output

Write a concise implementation plan with root cause, files to change, and test strategy.
∆∆

Doc-blok (※※ ... ※※)

Inline documentatie. Verwijderd tijdens runtime, nuttig voor het beschrijven van wat de workflow doet.

Sjabloonvariabelen

.sky ondersteunt drie variabeletypes:

  • {{variable}} — invoer op workflowniveau
  • $node.output — uitvoer van een benoemd knooppunt
  • ${env:SECRET_NAME} — omgevingsgeheimen

Wat vandaag wordt ondersteund

De huidige runtime ondersteunt HTTP-ophaalnooppunten, LLM-knooppunten met model/inspanning/budgetconfiguratie, GitHub-triggers en worktree-isolatie. Meer knooppunttypen komen in de volgende release.

TypeScript

Sterk getypeerd, async-first HTTP-client

TypeScript
interface User {
  id: number;
  name: string;
  email: string;
}

async function fetchUser(id: number): Promise<User> {
  const url = 'https://api.example.com/users/' + String(id);
  const res = await fetch(url, {
    headers: { Authorization: 'Bearer ' + process.env.API_KEY },
  });
  if (!res.ok) throw new Error('HTTP ' + res.status);
  return res.json() as Promise<User>;
}

Python

Async met httpx, idiomatische foutafhandeling

Python
import httpx

async def fetch_user(user_id: int) -> dict:
    async with httpx.AsyncClient() as client:
        response = await client.get(
            f"https://api.example.com/users/{user_id}",
            headers={"Authorization": f"Bearer {API_KEY}"},
        )
        response.raise_for_status()
        return response.json()

Go

Standaardbibliotheek, nul afhankelijkheden

Go
func fetchUser(id int) (*User, error) {
    url := fmt.Sprintf("https://api.example.com/users/%d", id)
    req, _ := http.NewRequest("GET", url, nil)
    req.Header.Set("Authorization", "Bearer "+apiKey)
    resp, err := http.DefaultClient.Do(req)
    if err != nil { return nil, err }
    defer resp.Body.Close()
    var user User
    return &user, json.NewDecoder(resp.Body).Decode(&user)
}