stageflow 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/dist/agent/claudeAdapter.js +31 -1
- package/dist/agent/piAdapter.d.ts +6 -4
- package/dist/agent/piAdapter.js +66 -24
- package/dist/agent/piIsolatedMcp.d.ts +23 -0
- package/dist/agent/piIsolatedMcp.js +223 -0
- package/dist/agent/piIsolatedMcpProbe.d.ts +15 -0
- package/dist/agent/piIsolatedMcpProbe.js +292 -0
- package/dist/agent/port.d.ts +2 -0
- package/dist/agent/port.js +1 -1
- package/dist/config/loadPipeline.js +1 -0
- package/dist/config/loadStage.d.ts +1 -0
- package/dist/config/loadStage.js +69 -0
- package/dist/config/normalizePipelineStageEntry.js +7 -1
- package/dist/config/pipelineStageKeys.js +1 -0
- package/dist/config/resolveStageMcpServers.d.ts +35 -0
- package/dist/config/resolveStageMcpServers.js +207 -0
- package/dist/config/validateCatalog.d.ts +1 -1
- package/dist/config/validateCatalog.js +51 -0
- package/dist/mcp/readArtifact.d.ts +2 -0
- package/dist/mcp/readArtifact.js +25 -1
- package/dist/package-meta.d.ts +1 -1
- package/dist/package-meta.js +1 -1
- package/dist/runtime/stageAttemptBootstrap.js +38 -2
- package/dist/runtime/verifiedStageExecution.d.ts +2 -0
- package/dist/runtime/verifiedStageExecution.js +10 -2
- package/dist/server/http.js +23 -4
- package/dist/server/projectMcpRoutes.d.ts +6 -0
- package/dist/server/projectMcpRoutes.js +38 -0
- package/dist/types/pipeline.d.ts +2 -0
- package/dist/types/stage.d.ts +2 -1
- package/dist/ui/assets/index-Yzh42vhf.js +118 -0
- package/dist/ui/index.html +1 -1
- package/package.json +4 -1
- package/skills/stageflow-author/SKILL.md +20 -2
- package/skills/stageflow-author/references/catalog-mapping.md +63 -2
- package/skills/stageflow-author/references/stage-prompt-template.md +63 -4
- package/skills/stageflow-session-capture/references/catalog-authoring.md +4 -1
- package/dist/ui/assets/index-CXGz4nL7.js +0 -118
package/dist/ui/index.html
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Figtree:wght@400;500;600;700&display=swap" />
|
|
14
14
|
<link rel="icon" type="image/svg+xml" href="/stageflow-icon.svg" />
|
|
15
15
|
<title>Stageflow</title>
|
|
16
|
-
<script type="module" crossorigin src="/assets/index-
|
|
16
|
+
<script type="module" crossorigin src="/assets/index-Yzh42vhf.js"></script>
|
|
17
17
|
<link rel="stylesheet" crossorigin href="/assets/index-uVHiae8s.css">
|
|
18
18
|
</head>
|
|
19
19
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stageflow",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "Stageflow — CLI pipeline runtime for configurable stages on Pi",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -63,9 +63,12 @@
|
|
|
63
63
|
"@anthropic-ai/claude-agent-sdk": "^0.3.263",
|
|
64
64
|
"@earendil-works/pi-ai": "^0.84.1",
|
|
65
65
|
"@earendil-works/pi-coding-agent": "^0.84.1",
|
|
66
|
+
"@earendil-works/pi-tui": "^0.84.4",
|
|
66
67
|
"@modelcontextprotocol/node": "^2.0.0",
|
|
67
68
|
"@modelcontextprotocol/server": "^2.0.0",
|
|
68
69
|
"better-sqlite3": "^13.0.3",
|
|
70
|
+
"jiti": "^2.7.0",
|
|
71
|
+
"pi-mcp-adapter": "^2.32.1",
|
|
69
72
|
"typebox": "^1.3.7",
|
|
70
73
|
"yaml": "^2.9.0",
|
|
71
74
|
"zod": "^4.4.3"
|
|
@@ -35,9 +35,27 @@ Ask until you can name every step, how they sequence, any decision point, and an
|
|
|
35
35
|
|
|
36
36
|
## Map
|
|
37
37
|
|
|
38
|
-
Read [`references/catalog-mapping.md`](references/catalog-mapping.md). Apply those rules to the confirmed structure. Read [`references/stage-prompt-template.md`](references/stage-prompt-template.md) for each stage's `system_prompt`, `model`, and `gate_kinds`.
|
|
38
|
+
Read [`references/catalog-mapping.md`](references/catalog-mapping.md). Apply those rules to the confirmed structure. Read [`references/stage-prompt-template.md`](references/stage-prompt-template.md) for each stage's `system_prompt`, `model`, and `gate_kinds`. Apply the Anti-patterns section below while mapping. When the human needs hard advance gates, plan `completion` / `recovery` on pipeline entries. When a review can demand changes, include an address-feedback stage before approve/ship.
|
|
39
39
|
|
|
40
|
-
**Done when** you have a pipeline id, one stage id per step, `needs` / `fork` wiring,
|
|
40
|
+
**Done when** you have a pipeline id, one stage id per step, `needs` / `fork` wiring, a prompt plan per stage, and any `completion` / `recovery` / remediation stages the structure requires.
|
|
41
|
+
|
|
42
|
+
## Anti-patterns
|
|
43
|
+
|
|
44
|
+
Author these contracts explicitly. They come from long runs that failed after hours of real work.
|
|
45
|
+
|
|
46
|
+
| Always do | How |
|
|
47
|
+
|---|---|
|
|
48
|
+
| End every attempt on a tool call | Prompt: last call is `emit_stage_envelope`, or `ask_operator` while waiting on HITL. Each clonable instance emits on its own. |
|
|
49
|
+
| Land required files in the attempt artifact dir | Prompt `write_stage_artifact`. Pipeline `completion.checks` with `type: artifact`. `ask_operator` `artifact_backed` references that same path. |
|
|
50
|
+
| Make implement stages change the checkout | Pipeline `checkout_changes` + `path_fields`; stage `payload_schema` with required checkout-relative path arrays. Exploration-only is its own stage or a failure emit. |
|
|
51
|
+
| Hand successors clean envelopes | `summary` / `payload` = outcomes and artifact pointers only. Name required `payload_schema` fields in the prompt. |
|
|
52
|
+
| Give review blockers a place to land | Wire `review → address-feedback → approve/ship`. Put `verdict` / `blocking_findings` (or equivalent) in the review `payload_schema`. |
|
|
53
|
+
| Bind success to the full checklist | If a plan lists N commands, success requires all of them in `commands_run` with exit 0. Cheap checks first; slow suites last or in a verify stage. Size `timeout_ms` to the work. |
|
|
54
|
+
| Use configured models on every sibling | Same configured `model` family after a fork/fan-out unless the human asks otherwise. Reliable model on publish/PR stages. |
|
|
55
|
+
| Finish publish in the accept attempt | After `artifact_backed` accept: side effects (commit/push/PR) → final artifact → emit in the same attempt. Fix emit/schema errors by re-emitting. |
|
|
56
|
+
| Emit full clone assignments | When `clonable: true`, parent success uses `clone_forks` with full envelopes matching `clone_input_schema`. Leave clonable unset when the clone count is unknown. |
|
|
57
|
+
|
|
58
|
+
Throwaway checkout deliverables (HTML spike, scratch file): prompt builtin `write` at a checkout-relative path, `artifacts: []` on emit, path in `payload`.
|
|
41
59
|
|
|
42
60
|
## Locate
|
|
43
61
|
|
|
@@ -28,15 +28,56 @@ Collision handling lives in [`catalog-write-conventions.md`](catalog-write-conve
|
|
|
28
28
|
|
|
29
29
|
Default `select` is `one` unless the human says more than one branch can run.
|
|
30
30
|
|
|
31
|
-
Map linear chains, sibling fan-out, generic fan-in (`needs` array), and single-level `fork`.
|
|
31
|
+
Map linear chains, sibling fan-out, generic fan-in (`needs` array), and single-level `fork`.
|
|
32
32
|
|
|
33
33
|
A review, approval, or sign-off step is a gated stage: put `gate_kinds` on that stage file and follow [`stage-prompt-template.md`](stage-prompt-template.md).
|
|
34
34
|
|
|
35
|
+
## Review then fix then approve
|
|
36
|
+
|
|
37
|
+
When the human wants a review that can demand changes, then a later approve/ship:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
… → review → address-feedback → approve
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Do not wire approve/ship as the immediate child of review. Pipelines are forward-only; without an address-feedback stage, blocking findings have nowhere to land. The address-feedback stage is the only post-review editor; the approve stage is the backstop.
|
|
44
|
+
|
|
45
|
+
## Completion and recovery
|
|
46
|
+
|
|
47
|
+
Put `completion` / `recovery` on the **pipeline** stage entry (the `uses:` wrapper), not on the stage body. Use when the human needs a hard gate before advance:
|
|
48
|
+
|
|
49
|
+
| Need | Pipeline wiring |
|
|
50
|
+
|---|---|
|
|
51
|
+
| Required file under the attempt artifact dir | `completion.checks` with `type: artifact`, `path`, usually `nonempty: true` |
|
|
52
|
+
| HITL must complete | `type: gate` with `kind` that appears in the stage's `gate_kinds` |
|
|
53
|
+
| Implement must change the checkout | `type: checkout_changes` with `path_fields` naming required arrays in `payload_schema` |
|
|
54
|
+
| Auto-retry after verification fail | `recovery: { mode: repair, max_attempts: N, retry_safety: idempotent, include_failed_checks: true }` |
|
|
55
|
+
| Side-effecting publish / ship | `recovery: { mode: manual, retry_safety: side_effecting }` |
|
|
56
|
+
|
|
57
|
+
`completion.mode` is `all`. Check `id` values must be unique within the stage. Wire these for writer stages and final gates; prompts alone do not enforce them.
|
|
58
|
+
|
|
59
|
+
## Clonable successors
|
|
60
|
+
|
|
61
|
+
A runtime clone count is not knowable from a vague description — leave `clonable` and `clone_forks` unset and prefer sibling stages or a single review.
|
|
62
|
+
|
|
63
|
+
When the human explicitly wants N parallel instances of **one** successor catalog id (e.g. several review lenses, several prototype variants):
|
|
64
|
+
|
|
65
|
+
- On that successor pipeline entry: `clonable: true` and `clone_cap` (integer ≥ 2).
|
|
66
|
+
- That successor must have at least one child (a join / address-feedback / collect stage). It cannot be a DAG leaf.
|
|
67
|
+
- Parent success emit uses `clone_forks` for that successor (not `fork_choice`). Each clone assignment is a full envelope; validate assignments with `clone_input_schema` on the clonable stage body.
|
|
68
|
+
- Join stages that wait on the clonable parent read clone-list `priorEnvelopes`, not `priorEnvelopesByStage`.
|
|
69
|
+
|
|
70
|
+
`fork` + `fork_choice` picks which **branch stage ids** run. `clone_forks` spawns **N instances** of one successor id.
|
|
71
|
+
|
|
72
|
+
## Models
|
|
73
|
+
|
|
74
|
+
Confirm providers before writing. After a fork, give every sibling the same configured `model` unless the human asks for different ones. Prefer a reliable configured model on side-effecting final stages.
|
|
75
|
+
|
|
35
76
|
## Worked examples
|
|
36
77
|
|
|
37
78
|
### Review loop (linear)
|
|
38
79
|
|
|
39
|
-
Three sequential steps; the middle one is a sign-off.
|
|
80
|
+
Three sequential steps; the middle one is a sign-off. Reject/revise stays inside the gated `review` stage.
|
|
40
81
|
|
|
41
82
|
```yaml
|
|
42
83
|
id: review-loop
|
|
@@ -53,6 +94,26 @@ stages:
|
|
|
53
94
|
|
|
54
95
|
`review` carries `gate_kinds: [artifact_backed]`. Full set: [`../assets/examples/linear-review/`](../assets/examples/linear-review/).
|
|
55
96
|
|
|
97
|
+
### Review with separate fix stage
|
|
98
|
+
|
|
99
|
+
When review can emit blockers and a later stage approves or ships, insert address-feedback between them:
|
|
100
|
+
|
|
101
|
+
```yaml
|
|
102
|
+
stages:
|
|
103
|
+
- id: implement
|
|
104
|
+
uses: ./implement.yaml
|
|
105
|
+
- id: review
|
|
106
|
+
uses: ./review.yaml
|
|
107
|
+
needs: implement
|
|
108
|
+
- id: address-feedback
|
|
109
|
+
uses: ./address-feedback.yaml
|
|
110
|
+
needs: review
|
|
111
|
+
- id: approve
|
|
112
|
+
uses: ./approve.yaml
|
|
113
|
+
needs: address-feedback
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Do not make `approve` / `ship` `needs: review` when blockers are expected.
|
|
56
117
|
### Release gate (fork, select one)
|
|
57
118
|
|
|
58
119
|
One deciding step, then exactly one successor.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Stage prompt template
|
|
2
2
|
|
|
3
|
-
Every external stage file has `id`, `system_prompt`, and `model`. Filename stem matches `id`. Default `model` is `anthropic/claude-sonnet-4-5`. When the human names a different model, write that string verbatim.
|
|
3
|
+
Every external stage file has `id`, `system_prompt`, and `model`. Filename stem matches `id`. Default `model` is `anthropic/claude-sonnet-4-5`. When the human names a different model, write that string verbatim. Before writing models, confirm at least one provider is `configured` (see the skill Provider gate). Sibling stages after a fork should use the same configured model family unless the human asks otherwise.
|
|
4
4
|
|
|
5
5
|
## Base
|
|
6
6
|
|
|
@@ -14,12 +14,48 @@ system_prompt: |
|
|
|
14
14
|
Write any output this step produces via write_stage_artifact.
|
|
15
15
|
|
|
16
16
|
When finished, call emit_stage_envelope exactly once with status, summary,
|
|
17
|
-
artifacts, and a payload the next stage can use.
|
|
17
|
+
artifacts, and a payload the next stage can use. Your last tool call in this
|
|
18
|
+
attempt must be emit_stage_envelope (or ask_operator if waiting on HITL).
|
|
19
|
+
An empty final message is a stage failure.
|
|
18
20
|
model: anthropic/claude-sonnet-4-5
|
|
19
21
|
```
|
|
20
22
|
|
|
21
23
|
The prompt has no `ask_operator` line. It ends on the `emit_stage_envelope` instruction. Call `emit_stage_envelope` once per attempt.
|
|
22
24
|
|
|
25
|
+
When the pipeline entry will carry `completion.checks` with `type: artifact`, add this line after the goal:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
Required files must be created with write_stage_artifact. Checkout write/edit
|
|
29
|
+
does not satisfy completion checks.
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
When the stage must change the project checkout (implement, patch, edit source), add:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
Success requires real checkout edits. Put checkout-relative paths in
|
|
36
|
+
payload.changed_files. Do not put stages/.../artifacts paths there. A report
|
|
37
|
+
or map alone is a failure emit, not success.
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
When the deliverable is throwaway checkout content instead of a stage artifact:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
Write the deliverable with builtin write at <checkout-relative path>.
|
|
44
|
+
Set artifacts: [] on emit. Put that path in payload.<field>.
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Summary and payload
|
|
48
|
+
|
|
49
|
+
Add to every stage (base, gated, or fork):
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
summary and payload are handed to the next stage verbatim. State outcomes and
|
|
53
|
+
artifact pointers only. Do not repeat this stage's prohibitions in summary —
|
|
54
|
+
downstream will obey them literally.
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
When `payload_schema` is on the stage file, name the required fields in the prompt so the emit matches.
|
|
58
|
+
|
|
23
59
|
## Gated
|
|
24
60
|
|
|
25
61
|
When the step is a review, approval, or sign-off, add `gate_kinds` and resolve the gate before emit. Match this sequence: `write_stage_artifact` → `ask_operator` → `emit_stage_envelope` on accept.
|
|
@@ -32,7 +68,8 @@ system_prompt: |
|
|
|
32
68
|
<one-line goal>. Get operator acceptance before completing this stage.
|
|
33
69
|
|
|
34
70
|
1. Write the reviewable output via write_stage_artifact.
|
|
35
|
-
2. Call ask_operator with kind artifact_backed referencing that artifact path
|
|
71
|
+
2. Call ask_operator with kind artifact_backed referencing that artifact path
|
|
72
|
+
(stage artifact path, not a checkout path).
|
|
36
73
|
3. On reject or change text: revise the artifact and call ask_operator again
|
|
37
74
|
with artifact_backed in this same stage. Do not complete yet.
|
|
38
75
|
4. Call emit_stage_envelope with an advancing success status only after the
|
|
@@ -42,6 +79,14 @@ model: anthropic/claude-sonnet-4-5
|
|
|
42
79
|
|
|
43
80
|
Use the `gate_kinds` value that matches the human's review: `artifact_backed` for a file to accept, `confirm` for yes/no, `free_text` for an open reply, `multi_question` for a batch. `ask_operator` does not complete the stage.
|
|
44
81
|
|
|
82
|
+
When the gated stage also publishes or opens a PR after accept, append:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
After the operator accepts, immediately finish publish side effects in this
|
|
86
|
+
same attempt (commit, push, open PR as required), write any final artifact,
|
|
87
|
+
then emit. Do not pause after accept. Do not ask_operator for emit/schema errors.
|
|
88
|
+
```
|
|
89
|
+
|
|
45
90
|
## Fork
|
|
46
91
|
|
|
47
92
|
When the pipeline entry has `fork`, the success emit names immediate successors in `fork_choice`. Add this block to the base (or gated) prompt:
|
|
@@ -50,6 +95,20 @@ When the pipeline entry has `fork`, the success emit names immediate successors
|
|
|
50
95
|
On a success emit, include fork_choice naming immediate successor id(s) that
|
|
51
96
|
should run. Name only ids listed as this stage's children. select: one →
|
|
52
97
|
exactly one id. select: subset → one or more of those ids.
|
|
98
|
+
Normalize free_text answers before mapping (trim, lowercase, collapse spaces
|
|
99
|
+
and hyphens). If unmapped, ask_operator again; do not emit.
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`fork_choice` on a failure emit is ignored. Leave `clone_forks` unset unless the human explicitly asked for clonable fan-out (see [`catalog-mapping.md`](catalog-mapping.md)).
|
|
103
|
+
|
|
104
|
+
## Clonable parent
|
|
105
|
+
|
|
106
|
+
When a successor is `clonable: true`, the parent success emit uses `clone_forks` (not `fork_choice`) for that successor. Add:
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
On success, include clone_forks covering every clonable successor exactly once.
|
|
110
|
+
Each clone entry is a full envelope with status, summary, artifacts, and payload
|
|
111
|
+
matching that successor's clone_input_schema — not a stub object.
|
|
53
112
|
```
|
|
54
113
|
|
|
55
|
-
|
|
114
|
+
Clonable child stages use the base (or gated) prompt. Remind them they are one clone among others and must emit independently.
|
|
@@ -16,9 +16,12 @@ Every `system_prompt` ends with a mandatory `emit_stage_envelope` footer, for ex
|
|
|
16
16
|
|
|
17
17
|
```
|
|
18
18
|
When finished, call emit_stage_envelope once with status, summary, artifacts,
|
|
19
|
-
and a payload the next stage can use.
|
|
19
|
+
and a payload the next stage can use. Your last tool call in this attempt must
|
|
20
|
+
be emit_stage_envelope. An empty final message is a stage failure.
|
|
20
21
|
```
|
|
21
22
|
|
|
23
|
+
Write reviewable or required outputs with `write_stage_artifact`, not checkout `write`/`edit`, unless the step's deliverable is intentionally checkout-only. `summary` is for the next stage — outcomes and artifact pointers only; do not put this stage's prohibitions in the summary.
|
|
24
|
+
|
|
22
25
|
Omit `gate_kinds`. A human-review checkpoint from the source session stays as prose in the stage approach, not a HITL gate.
|
|
23
26
|
|
|
24
27
|
Worked example: `assets/example-pipeline/research.yaml` and `assets/example-pipeline/implement.yaml`.
|