docs: auto-derive declared_outputs from script scan
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user