Engineering
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
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
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
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)
}