@selesai/code 0.5.16 → 0.5.18
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/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +1 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +6 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +2 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/extensions/workflow/adapter.ts +221 -196
- package/dist/extensions/workflow/extension.ts +0 -2
- package/dist/extensions/workflow/modes/prototype.ts +1 -3
- package/dist/extensions/workflow/modes/quick.ts +1 -3
- package/dist/extensions/workflow/modes/task.ts +1 -13
- package/dist/extensions/workflow/state-machine.ts +1 -6
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +1 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.test.d.ts +2 -0
- package/dist/modes/interactive/interactive-mode.test.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-mode.test.js +45 -0
- package/dist/modes/interactive/interactive-mode.test.js.map +1 -0
- package/dist/skills/workflow-creation/SKILL.md +2 -2
- package/docs/workflows.md +10 -23
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive-mode.test.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-mode.test.ts"],"names":[],"mappings":"","sourcesContent":["import { describe, expect, it, vi } from \"vitest\";\nimport { InteractiveMode } from \"./interactive-mode.js\";\n\ndescribe(\"InteractiveMode handleEvent tool_execution_update\", () => {\n\tit(\"refreshes displayed args from execution update\", () => {\n\t\tconst component = {\n\t\t\tupdateArgs: vi.fn(),\n\t\t\tupdateResult: vi.fn(),\n\t\t};\n\t\tconst requestRender = vi.fn();\n\n\t\tconst mode = Object.create(InteractiveMode.prototype) as InteractiveMode;\n\t\tmode.isInitialized = true;\n\t\tmode.footer = { invalidate: vi.fn() } as any;\n\t\tmode.pendingTools = new Map([[\"tc-1\", component as any]]);\n\t\tmode.ui = { requestRender } as any as InteractiveMode[\"ui\"];\n\n\t\tmode.handleEvent({\n\t\t\ttype: \"tool_execution_update\",\n\t\t\ttoolCallId: \"tc-1\",\n\t\t\ttoolName: \"bash\",\n\t\t\targs: { command: \"rtk ls -la\" },\n\t\t\tpartialResult: { content: [], details: undefined },\n\t\t} as any);\n\n\t\texpect(component.updateArgs).toHaveBeenCalledTimes(1);\n\t\texpect(component.updateArgs).toHaveBeenCalledWith({ command: \"rtk ls -la\" });\n\t\texpect(component.updateResult).toHaveBeenCalledTimes(1);\n\t\texpect(component.updateResult).toHaveBeenCalledWith(\n\t\t\t{ content: [], details: undefined, isError: false },\n\t\t\ttrue,\n\t\t);\n\t\texpect(requestRender).toHaveBeenCalledTimes(1);\n\t});\n\n\tit(\"is a no-op when update references an unknown tool\", () => {\n\t\tconst requestRender = vi.fn();\n\t\tconst mode = Object.create(InteractiveMode.prototype) as InteractiveMode;\n\t\tmode.isInitialized = true;\n\t\tmode.footer = { invalidate: vi.fn() } as any;\n\t\tmode.pendingTools = new Map();\n\t\tmode.ui = { requestRender } as any as InteractiveMode[\"ui\"];\n\n\t\tmode.handleEvent({\n\t\t\ttype: \"tool_execution_update\",\n\t\t\ttoolCallId: \"missing\",\n\t\t\ttoolName: \"bash\",\n\t\t\targs: { command: \"rtk ls -la\" },\n\t\t\tpartialResult: { content: [], details: undefined },\n\t\t} as any);\n\n\t\texpect(requestRender).not.toHaveBeenCalled();\n\t});\n});\n"]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { InteractiveMode } from "./interactive-mode.js";
|
|
3
|
+
describe("InteractiveMode handleEvent tool_execution_update", () => {
|
|
4
|
+
it("refreshes displayed args from execution update", () => {
|
|
5
|
+
const component = {
|
|
6
|
+
updateArgs: vi.fn(),
|
|
7
|
+
updateResult: vi.fn(),
|
|
8
|
+
};
|
|
9
|
+
const requestRender = vi.fn();
|
|
10
|
+
const mode = Object.create(InteractiveMode.prototype);
|
|
11
|
+
mode.isInitialized = true;
|
|
12
|
+
mode.footer = { invalidate: vi.fn() };
|
|
13
|
+
mode.pendingTools = new Map([["tc-1", component]]);
|
|
14
|
+
mode.ui = { requestRender };
|
|
15
|
+
mode.handleEvent({
|
|
16
|
+
type: "tool_execution_update",
|
|
17
|
+
toolCallId: "tc-1",
|
|
18
|
+
toolName: "bash",
|
|
19
|
+
args: { command: "rtk ls -la" },
|
|
20
|
+
partialResult: { content: [], details: undefined },
|
|
21
|
+
});
|
|
22
|
+
expect(component.updateArgs).toHaveBeenCalledTimes(1);
|
|
23
|
+
expect(component.updateArgs).toHaveBeenCalledWith({ command: "rtk ls -la" });
|
|
24
|
+
expect(component.updateResult).toHaveBeenCalledTimes(1);
|
|
25
|
+
expect(component.updateResult).toHaveBeenCalledWith({ content: [], details: undefined, isError: false }, true);
|
|
26
|
+
expect(requestRender).toHaveBeenCalledTimes(1);
|
|
27
|
+
});
|
|
28
|
+
it("is a no-op when update references an unknown tool", () => {
|
|
29
|
+
const requestRender = vi.fn();
|
|
30
|
+
const mode = Object.create(InteractiveMode.prototype);
|
|
31
|
+
mode.isInitialized = true;
|
|
32
|
+
mode.footer = { invalidate: vi.fn() };
|
|
33
|
+
mode.pendingTools = new Map();
|
|
34
|
+
mode.ui = { requestRender };
|
|
35
|
+
mode.handleEvent({
|
|
36
|
+
type: "tool_execution_update",
|
|
37
|
+
toolCallId: "missing",
|
|
38
|
+
toolName: "bash",
|
|
39
|
+
args: { command: "rtk ls -la" },
|
|
40
|
+
partialResult: { content: [], details: undefined },
|
|
41
|
+
});
|
|
42
|
+
expect(requestRender).not.toHaveBeenCalled();
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
//# sourceMappingURL=interactive-mode.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive-mode.test.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-mode.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,QAAQ,CAAC,mDAAmD,EAAE,GAAG,EAAE,CAAC;IACnE,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE,CAAC;QAC1D,MAAM,SAAS,GAAG;YACjB,UAAU,EAAE,EAAE,CAAC,EAAE,EAAE;YACnB,YAAY,EAAE,EAAE,CAAC,EAAE,EAAE;SACrB,CAAC;QACF,MAAM,aAAa,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAE9B,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,SAAS,CAAoB,CAAC;QACzE,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,EAAE,UAAU,EAAE,EAAE,CAAC,EAAE,EAAE,EAAS,CAAC;QAC7C,IAAI,CAAC,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,SAAgB,CAAC,CAAC,CAAC,CAAC;QAC1D,IAAI,CAAC,EAAE,GAAG,EAAE,aAAa,EAAkC,CAAC;QAE5D,IAAI,CAAC,WAAW,CAAC;YAChB,IAAI,EAAE,uBAAuB;YAC7B,UAAU,EAAE,MAAM;YAClB,QAAQ,EAAE,MAAM;YAChB,IAAI,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE;YAC/B,aAAa,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE;SAC3C,CAAC,CAAC;QAEV,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACtD,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,oBAAoB,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC;QAC7E,MAAM,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACxD,MAAM,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,oBAAoB,CAClD,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,EACnD,IAAI,CACJ,CAAC;QACF,MAAM,CAAC,aAAa,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAAA,CAC/C,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE,CAAC;QAC7D,MAAM,aAAa,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,SAAS,CAAoB,CAAC;QACzE,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,EAAE,UAAU,EAAE,EAAE,CAAC,EAAE,EAAE,EAAS,CAAC;QAC7C,IAAI,CAAC,YAAY,GAAG,IAAI,GAAG,EAAE,CAAC;QAC9B,IAAI,CAAC,EAAE,GAAG,EAAE,aAAa,EAAkC,CAAC;QAE5D,IAAI,CAAC,WAAW,CAAC;YAChB,IAAI,EAAE,uBAAuB;YAC7B,UAAU,EAAE,SAAS;YACrB,QAAQ,EAAE,MAAM;YAChB,IAAI,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE;YAC/B,aAAa,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE;SAC3C,CAAC,CAAC;QAEV,MAAM,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IAAA,CAC7C,CAAC,CAAC;AAAA,CACH,CAAC,CAAC","sourcesContent":["import { describe, expect, it, vi } from \"vitest\";\nimport { InteractiveMode } from \"./interactive-mode.js\";\n\ndescribe(\"InteractiveMode handleEvent tool_execution_update\", () => {\n\tit(\"refreshes displayed args from execution update\", () => {\n\t\tconst component = {\n\t\t\tupdateArgs: vi.fn(),\n\t\t\tupdateResult: vi.fn(),\n\t\t};\n\t\tconst requestRender = vi.fn();\n\n\t\tconst mode = Object.create(InteractiveMode.prototype) as InteractiveMode;\n\t\tmode.isInitialized = true;\n\t\tmode.footer = { invalidate: vi.fn() } as any;\n\t\tmode.pendingTools = new Map([[\"tc-1\", component as any]]);\n\t\tmode.ui = { requestRender } as any as InteractiveMode[\"ui\"];\n\n\t\tmode.handleEvent({\n\t\t\ttype: \"tool_execution_update\",\n\t\t\ttoolCallId: \"tc-1\",\n\t\t\ttoolName: \"bash\",\n\t\t\targs: { command: \"rtk ls -la\" },\n\t\t\tpartialResult: { content: [], details: undefined },\n\t\t} as any);\n\n\t\texpect(component.updateArgs).toHaveBeenCalledTimes(1);\n\t\texpect(component.updateArgs).toHaveBeenCalledWith({ command: \"rtk ls -la\" });\n\t\texpect(component.updateResult).toHaveBeenCalledTimes(1);\n\t\texpect(component.updateResult).toHaveBeenCalledWith(\n\t\t\t{ content: [], details: undefined, isError: false },\n\t\t\ttrue,\n\t\t);\n\t\texpect(requestRender).toHaveBeenCalledTimes(1);\n\t});\n\n\tit(\"is a no-op when update references an unknown tool\", () => {\n\t\tconst requestRender = vi.fn();\n\t\tconst mode = Object.create(InteractiveMode.prototype) as InteractiveMode;\n\t\tmode.isInitialized = true;\n\t\tmode.footer = { invalidate: vi.fn() } as any;\n\t\tmode.pendingTools = new Map();\n\t\tmode.ui = { requestRender } as any as InteractiveMode[\"ui\"];\n\n\t\tmode.handleEvent({\n\t\t\ttype: \"tool_execution_update\",\n\t\t\ttoolCallId: \"missing\",\n\t\t\ttoolName: \"bash\",\n\t\t\targs: { command: \"rtk ls -la\" },\n\t\t\tpartialResult: { content: [], details: undefined },\n\t\t} as any);\n\n\t\texpect(requestRender).not.toHaveBeenCalled();\n\t});\n});\n"]}
|
|
@@ -33,7 +33,7 @@ Done when every proposed behavior has one owner: state machine, shared adapter,
|
|
|
33
33
|
For a new mode, add `src/extensions/workflow/modes/<name>.ts`, modeled on `quick.ts`, with only `WorkflowConfig` and `WorkflowModeRegistration`:
|
|
34
34
|
|
|
35
35
|
- ordered phases, phase artifacts, prompts, validators, close artifacts/validators;
|
|
36
|
-
- unique mode/status/entry identities and start/resume/end
|
|
36
|
+
- unique mode/status/entry identities and slash-command name; shared start/resume/end tools select the mode;
|
|
37
37
|
- prompts that name exact artifact paths and use `write_workflow_artifact` only for workflow artifacts.
|
|
38
38
|
|
|
39
39
|
Register the mode once in `MODES` in `extension.ts`; document its lifecycle and commands in `docs/workflows.md`.
|
|
@@ -47,7 +47,7 @@ The shared adapter owns UUID artifact directories, atomic saves, resume, loop re
|
|
|
47
47
|
- Persisted state changes after start, artifact/loop transition, resume reconciliation, and explicit end.
|
|
48
48
|
- Never auto-resume on `session_start`; an explicit selector attaches a run.
|
|
49
49
|
- Artifact completion advances durable state then stops the parent turn; the user deliberately continues the attached mode.
|
|
50
|
-
- Terminal-ready stays active. Only `
|
|
50
|
+
- Terminal-ready stays active. Only `end_workflow({ mode })` marks the record completed and terminates.
|
|
51
51
|
- One `ExtensionAPI` hosts all modes: shared writer once, stale reload handlers inert, one attached run total.
|
|
52
52
|
- Builder/reviewer loops use adapter-owned rounds, review files, markers, and max-iteration pause.
|
|
53
53
|
|
package/docs/workflows.md
CHANGED
|
@@ -18,10 +18,10 @@ src/extensions/workflow/
|
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
- **`state-machine.ts`** is the deep module. It owns the phase graph, artifact gating, skip rules, the terminal close gate, and the reentrancy guard. It imports nothing external — no `node:fs`, no pi API, no `pi-tui`, no `typebox`. Every method returns a `WorkflowEffect` (a discriminated union in domain vocabulary) that the adapter pattern-matches on.
|
|
21
|
-
- **`adapter.ts`** is the thin glue. It owns Pi/fs wiring, durable state, explicit resume, loop review persistence, and the git-based `reuse` skip predicate. Parent-written artifacts advance durable phase state
|
|
21
|
+
- **`adapter.ts`** is the thin glue. It owns Pi/fs wiring, durable state, explicit resume, loop review persistence, and the git-based `reuse` skip predicate. Parent-written artifacts advance durable phase state and queue hidden engine continuations; every built-in mode flows automatically.
|
|
22
22
|
- **`workflow.json`** in each artifact directory is the canonical, versioned run record. It is atomically replaced after state changes; session custom entries are only pointers for UI/history and never reconstruct an active run.
|
|
23
|
-
- **`extension.ts`** imports each mode's registration object and calls `createWorkflowExtension(config, options)(pi)` for each
|
|
24
|
-
- **A mode file** is pure data: the phase list,
|
|
23
|
+
- **`extension.ts`** imports each mode's registration object and calls `createWorkflowExtension(config, options)(pi)` for each. One extension load registers one shared writer plus `start_workflow`, `resume_workflow`, and `end_workflow`; each lifecycle call selects a mode.
|
|
24
|
+
- **A mode file** is pure data: the phase list, per-phase artifact filenames, prompt generators, terminal close artifacts, and command/status/entry identities. Prompts receive `{ artifactDir, userPrompt }`. Each mode exports a `WorkflowModeRegistration` object (e.g. `prototypeMode`, `quickMode`); it does not call `createWorkflowExtension` itself.
|
|
25
25
|
|
|
26
26
|
## To add a future mode
|
|
27
27
|
|
|
@@ -91,16 +91,6 @@ export const rigorousMode: WorkflowModeRegistration = {
|
|
|
91
91
|
commandName: "rigorous",
|
|
92
92
|
commandDescription:
|
|
93
93
|
"Run the rigorous workflow (grill → spec → research → plan → reuse → handoff → loop → audit → sign-off)",
|
|
94
|
-
toolNames: {
|
|
95
|
-
start: "start_rigorous_workflow",
|
|
96
|
-
resume: "resume_rigorous_workflow",
|
|
97
|
-
end: "end_rigorous_workflow",
|
|
98
|
-
},
|
|
99
|
-
toolLabels: {
|
|
100
|
-
start: "Start Rigorous Workflow",
|
|
101
|
-
resume: "Resume Rigorous Workflow",
|
|
102
|
-
end: "End Rigorous Workflow",
|
|
103
|
-
},
|
|
104
94
|
};
|
|
105
95
|
|
|
106
96
|
export default rigorousMode;
|
|
@@ -116,20 +106,20 @@ import { rigorousMode } from "./modes/rigorous.ts";
|
|
|
116
106
|
const MODES = [prototypeMode, quickMode, rigorousMode] as const;
|
|
117
107
|
```
|
|
118
108
|
|
|
119
|
-
That's it. The loader picks it up at boot (`package.json` loads only `./extension.ts`);
|
|
109
|
+
That's it. The loader picks it up at boot (`package.json` loads only `./extension.ts`); the shared lifecycle tools accept `mode: "rigorous"`, and the `/rigorous` command is registered automatically. There is no `next` tool — phases auto-advance as artifacts land and only `end_workflow({ mode: "rigorous" })` completes the terminal phase.
|
|
120
110
|
|
|
121
111
|
## Built-in modes
|
|
122
112
|
|
|
123
113
|
### `task` — plan → codebase exploration → handoff → build/review loop
|
|
124
114
|
|
|
125
|
-
Task now follows the same phase shape as the other modes, minus grilling/research/audit: an architect subagent produces a validated `plan.md`, an optional explorer subagent produces `reuse.md`, a recapper subagent produces a validated `handoff.md`, and then a builder↔commentator review loop runs (max 3 blocking rounds). A clean review makes the workflow terminal-ready; `
|
|
115
|
+
Task now follows the same phase shape as the other modes, minus grilling/research/audit: an architect subagent produces a validated `plan.md`, an optional explorer subagent produces `reuse.md`, a recapper subagent produces a validated `handoff.md`, and then a builder↔commentator review loop runs (max 3 blocking rounds). A clean review makes the workflow terminal-ready; `end_workflow({ mode: "task" })` completes it.
|
|
126
116
|
|
|
127
|
-
Lifecycle: `plan → reuse → handoff → loop (build ↔ review) → terminal-ready →
|
|
117
|
+
Lifecycle: `plan → reuse → handoff → loop (build ↔ review) → terminal-ready → end_workflow({ mode: "task" })`
|
|
128
118
|
|
|
129
119
|
- `/workflow-task <goal>` — start a new run
|
|
130
120
|
- `/workflow-task resume` — list and resume active runs
|
|
131
121
|
- `/workflow-task help` — show the lifecycle
|
|
132
|
-
- Valid
|
|
122
|
+
- Valid phase artifacts automatically queue the next phase prompt (the workflow does not pause at artifact boundaries)
|
|
133
123
|
- No grilling, research, or audit phases
|
|
134
124
|
- `reuse.md` is optional; it is skipped automatically when the project has no git history
|
|
135
125
|
|
|
@@ -146,7 +136,6 @@ Lifecycle: `plan → reuse → handoff → loop (build ↔ review) → terminal-
|
|
|
146
136
|
| `statusKey` | `string` | Footer status key. |
|
|
147
137
|
| `entryType` | `string` | Session-history custom-type. It stores a pointer only; `workflow.json` is canonical. |
|
|
148
138
|
| `footerLabel` | `string` | Label shown in the footer (`● label · step/total phase`). |
|
|
149
|
-
| `continueAfterArtifact?` | `boolean` | Queue the next phase prompt after the parent writes a valid artifact. `task` enables this at every parent-owned artifact boundary (plan, reuse, handoff) so the workflow flows automatically into the loop. |
|
|
150
139
|
|
|
151
140
|
### Adapter options
|
|
152
141
|
|
|
@@ -154,8 +143,6 @@ The second argument to `createWorkflowExtension`:
|
|
|
154
143
|
|
|
155
144
|
| Field | Description |
|
|
156
145
|
|---|---|
|
|
157
|
-
| `toolNames` | `{ start, resume, end }` — registered tool names. Artifacts advance phase state; the user explicitly continues the attached run. |
|
|
158
|
-
| `toolLabels` | Human-readable labels for the tools. |
|
|
159
146
|
| `commandName` | The `/<command>` name users type to kick off the workflow. |
|
|
160
147
|
| `commandDescription` | Description shown in the command list. |
|
|
161
148
|
|
|
@@ -165,14 +152,14 @@ Each started workflow receives a UUID artifact directory under `.selesai/artifac
|
|
|
165
152
|
|
|
166
153
|
Runs are **never** auto-resumed on session start. At most one run can be attached to a Pi instance, but older active runs remain resumable:
|
|
167
154
|
|
|
168
|
-
- `resume_workflow({ run: "<id-or-path>" })
|
|
155
|
+
- `start_workflow({ mode, goal })`, `resume_workflow({ mode, run: "<id-or-path>" })`, and `end_workflow({ mode })`, where `mode` is `prototype`, `quick`, or `task`
|
|
169
156
|
- `/workflow-prototype resume <id-or-artifact-dir-or-workflow.json>` / `/workflow-quick resume ...` / `/workflow-task resume ...`
|
|
170
157
|
- `/workflow-prototype resume`, `/workflow-quick resume`, or `/workflow-task resume` lists active runs (and offers a UI picker when available).
|
|
171
158
|
- `/workflow-prototype help`, `/workflow-quick help`, or `/workflow-task help` shows the start, resume, continue, and explicit-completion lifecycle.
|
|
172
159
|
|
|
173
|
-
Resume validates the selected file is under the artifacts base, belongs to that mode, is active, and matches its containing directory. It reconciles the current expected artifact once before emitting the current prompt, covering a crash after `write_workflow_artifact` writes the file but before the phase-state write.
|
|
160
|
+
Resume validates the selected file is under the artifacts base, belongs to that mode, is active, and matches its containing directory. It reconciles the current expected artifact once before emitting the current prompt, covering a crash after `write_workflow_artifact` writes the file but before the phase-state write. Valid artifact writes queue one hidden engine-controlled continuation using `steer` and terminate the current parent turn; invalid writes stay in the current phase and do not terminate. Prompts injected by start, resume, and continue commands are hidden custom messages rather than visible synthetic user messages. Transition-capable calls (`write_workflow_artifact`, loop commentator transitions, and `end_workflow`) must be the sole tool call in their assistant batch; the adapter fails closed when that cannot be proven. Corrupt records are skipped during discovery. Reloads never auto-resume; explicit `resume_workflow` remains required.
|
|
174
161
|
|
|
175
|
-
A valid terminal artifact makes a workflow **terminal-ready**; it does not complete the run. Call
|
|
162
|
+
A valid terminal artifact makes a workflow **terminal-ready**; it does not complete the run. Call `end_workflow({ mode })` to write `status: "completed"`, append the done entry, and terminate. This is the only completion path.
|
|
176
163
|
|
|
177
164
|
## Artifact ownership
|
|
178
165
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@selesai/code",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.18",
|
|
4
4
|
"description": "Maintained, extension-first Pi coding agent with built-in workflows, subagents, web research, questions, skills, and an enhanced terminal UI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|