From 56f06b9eaf9d570b2301d7d38158a84b654163ef Mon Sep 17 00:00:00 2001 From: mrhid6 Date: Tue, 21 Jul 2026 10:05:45 +0100 Subject: [PATCH] docs: auto-derive declared_outputs from script scan --- ...hoc-steps-import-export-defaults-design.md | 55 ++++++++++++++++++- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/docs/superpowers/specs/2026-07-21-adhoc-steps-import-export-defaults-design.md b/docs/superpowers/specs/2026-07-21-adhoc-steps-import-export-defaults-design.md index 60bf34d..bd28deb 100644 --- a/docs/superpowers/specs/2026-07-21-adhoc-steps-import-export-defaults-design.md +++ b/docs/superpowers/specs/2026-07-21-adhoc-steps-import-export-defaults-design.md @@ -4,7 +4,7 @@ Date: 2026-07-21 ## Summary -Three related additions to the workflow step system: +Four related additions to the workflow step system: 1. **Ad-hoc steps** — steps defined inline in a single workflow, not written to the shared step library. @@ -12,6 +12,8 @@ Three related additions to the workflow step system: target the shared library or a workflow as an inline ad-hoc step. 3. **Default steps** — JSON files in a bind-mounted directory, seeded into the library on boot and re-syncable on demand. Org-ready for a future SaaS plan. +4. **Auto-derived outputs** — `declared_outputs` is scanned from the script + (writes to `$WORKFLOW_ENV`) instead of being entered by hand. Existing model: shared steps live in the `workflow_steps` collection; a `Workflow.Steps[]` is a list of `WorkflowStepRef` that reference a library step by @@ -182,7 +184,53 @@ Signature stays global today. When Orgs land, `SeedDefaultSteps(orgID)` seeds per-org and the upsert key becomes `{ org_id, slug, source }`. No schema churn blocks that later change. -## 5. Web +## 5. Auto-derived outputs + +Today `WorkflowStep.DeclaredOutputs` is entered by hand and consumed only by the +UI (no runtime reads it — outputs are captured at run time by `parseEnvFile` on +the agent). Replace manual entry with a server-side scan of the script. + +At run time the agent exposes an env file path in `$WORKFLOW_ENV` (bash) / +`$env:WORKFLOW_ENV` (powershell); a step emits an output by appending a +`KEY=value` line to it, e.g. `echo "test=123" >> $WORKFLOW_ENV`. + +### Scanner + +`services.DeriveOutputs(script string) []string`: + +- Scan line by line. For each line that references `WORKFLOW_ENV`, extract every + `KEY=` assignment target on that line, where `KEY` matches + `[A-Za-z_][A-Za-z0-9_]*`. +- Covers the common forms across both interpreters (line mentions `WORKFLOW_ENV` + and contains `KEY=...`): + - `echo "test=123" >> $WORKFLOW_ENV` + - `echo "test=123" >> "$WORKFLOW_ENV"` + - `printf 'k=v\n' >> $WORKFLOW_ENV` + - `"k=v" >> $env:WORKFLOW_ENV` / `Add-Content $env:WORKFLOW_ENV "k=v"` +- Deduplicate, preserve first-seen order. Best-effort heuristic — false positives + are acceptable (they only widen the documented output list); it never affects + what the agent actually captures. + +### Wiring + +- `CreateStep` and `UpdateStep` set `DeclaredOutputs = DeriveOutputs(s.Script)`, + ignoring any client-sent value. +- Inline ad-hoc steps: `DeriveOutputs` is applied when the workflow is saved (for + each `ref.Inline`), so inline outputs are derived too. +- `ParseStepDoc` (import) also derives outputs, so `declared_outputs` in an + imported/exported file is informational and always recomputed on import. +- `SeedDefaultSteps` derives outputs the same way when upserting. + +`DeclaredOutputs` stays in the model and JSON (still shown in the UI and used to +wire step-to-step input references), it is just no longer user-authored. + +### Web + +The step editor's "declared outputs" input becomes a read-only, auto-populated +display (derived from the script, refreshed on save / on script edit). No manual +add/remove. + +## 6. Web `web/app/workflows/[id]/page.tsx` and the steps list page. @@ -208,6 +256,9 @@ blocks that later change. - `SeedDefaultSteps`: insert-then-update idempotency; user steps untouched; user-edited default step reverted on re-sync; counts correct. - `DeleteStep` cascade ignores ad-hoc refs. +- `DeriveOutputs`: extracts keys from each interpreter form above, dedupes, + preserves order, ignores lines not referencing `WORKFLOW_ENV`; create/update/ + import/seed all populate `declared_outputs` from it and ignore client input. ## Out of scope