@brainervirus/workit-core 0.8.7 → 0.8.9
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/package.json +1 -1
- package/scripts/doctor-check.ts +16 -0
- package/scripts/install-cursor-plugin.sh +16 -0
- package/skills/wk-handoff/SKILL.md +2 -0
- package/skills/wk-implement/SKILL.md +3 -1
- package/src/core/doctor.ts +239 -18
- package/src/core/flow-state.ts +425 -59
- package/src/core/menu.ts +3 -1
- package/src/core/reminder.ts +11 -0
- package/src/core/sdd.ts +59 -0
- package/templates/execution-contract.md +4 -2
- package/templates/superpowers-doc-contract.md +4 -1
package/src/core/menu.ts
CHANGED
|
@@ -16,14 +16,16 @@ export const SOURCE_MENU_LABELS = [
|
|
|
16
16
|
"Handoff",
|
|
17
17
|
"Review spec first",
|
|
18
18
|
"Review plan first",
|
|
19
|
+
"Change model first",
|
|
19
20
|
] as const;
|
|
20
21
|
|
|
21
|
-
/** Display labels a marked destination presents — exactly
|
|
22
|
+
/** Display labels a marked destination presents — exactly five, no Handoff (CA-08). */
|
|
22
23
|
export const DESTINATION_MENU_LABELS = [
|
|
23
24
|
"Subagent-driven",
|
|
24
25
|
"Inline",
|
|
25
26
|
"Review spec first",
|
|
26
27
|
"Review plan first",
|
|
28
|
+
"Change model first",
|
|
27
29
|
] as const;
|
|
28
30
|
|
|
29
31
|
/**
|
package/src/core/reminder.ts
CHANGED
|
@@ -51,6 +51,17 @@ export const SDD_REMINDER_TEXT = `<workflow-sdd-reminder>
|
|
|
51
51
|
An approved plan is subagent-driven — execute it via \`wk-implement\` / \`task\` delegation. Never implement the approved plan inline in the main session.
|
|
52
52
|
</workflow-sdd-reminder>`;
|
|
53
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Worker-only context (CA-16): an authorized direct child of the activating
|
|
56
|
+
* coordinator receives ONLY this compact contract — never the coordinator
|
|
57
|
+
* bootstrap or SDD_REMINDER_TEXT. It carries the worker duties (brief, TDD,
|
|
58
|
+
* commit range, report) and no coordination instructions.
|
|
59
|
+
*/
|
|
60
|
+
export const SDD_WORKER_REMINDER_TEXT = `<workflow-sdd-worker>
|
|
61
|
+
You are an authorized delegated worker for an active subagent-driven plan.
|
|
62
|
+
Execute only the supplied task brief: follow TDD (failing test first), land exactly one contiguous non-empty commit range for your task, then report status, commits, and test results to the coordinator. Do not manage coordinator bookkeeping or launch another agent harness.
|
|
63
|
+
</workflow-sdd-worker>`;
|
|
64
|
+
|
|
54
65
|
export const DOC_RENDER_TEXT = `<workflow-doc-render>
|
|
55
66
|
When delivering a spec or plan, by default render the full markdown content of the doc in chat (headings, tables, mermaid fences preserved) — NOT a backtick-wrapped raw block.
|
|
56
67
|
If the doc exceeds the render threshold (more than 150 lines, over 8KB, or more than 3 mermaid diagrams), deliver only the clickable link \`[spec.md](docs/<slug>/spec.md)\` + a 3-5 bullet summary.
|
package/src/core/sdd.ts
CHANGED
|
@@ -292,3 +292,62 @@ export function sddAppendProgress({
|
|
|
292
292
|
const rel = posix(path.relative(contained.base, path_));
|
|
293
293
|
return { ok: true, line: trimmed, progress_path: rel };
|
|
294
294
|
}
|
|
295
|
+
|
|
296
|
+
export type AdvisoryResult =
|
|
297
|
+
| { ok: true; advisory: string; advisories_path: string }
|
|
298
|
+
| { error: string; code: string };
|
|
299
|
+
|
|
300
|
+
export function sddAppendAdvisory({
|
|
301
|
+
advisories_path,
|
|
302
|
+
task_id,
|
|
303
|
+
text,
|
|
304
|
+
workspace_root,
|
|
305
|
+
}: {
|
|
306
|
+
advisories_path: string;
|
|
307
|
+
task_id: unknown;
|
|
308
|
+
text: unknown;
|
|
309
|
+
workspace_root: string;
|
|
310
|
+
}): AdvisoryResult {
|
|
311
|
+
if (typeof task_id !== "number" || !Number.isSafeInteger(task_id) || task_id <= 0) {
|
|
312
|
+
return { error: "task_id must be a positive safe integer", code: "advisory_task_invalid" };
|
|
313
|
+
}
|
|
314
|
+
if (typeof text !== "string") {
|
|
315
|
+
return {
|
|
316
|
+
error: "advisory text must be a string of 1-1000 characters after normalization",
|
|
317
|
+
code: "advisory_text_invalid",
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
if (text.includes("\r") || text.includes("\n")) {
|
|
321
|
+
return {
|
|
322
|
+
error: "advisory text must be a single line (no CR/LF)",
|
|
323
|
+
code: "advisory_text_invalid",
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
const collapsed = text.trim().replace(/[ \t]+/g, " ");
|
|
327
|
+
if (collapsed.length === 0 || collapsed.length > 1000) {
|
|
328
|
+
return {
|
|
329
|
+
error: "advisory text must be 1-1000 characters after trim and horizontal-space collapse",
|
|
330
|
+
code: "advisory_text_invalid",
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
if (!/^docs\/[^/]+\/sdd\/advisories\.md$/.test(advisories_path)) {
|
|
334
|
+
return {
|
|
335
|
+
error: `advisories_path must be docs/<slug>/sdd/advisories.md: ${advisories_path}`,
|
|
336
|
+
code: "advisory_path_invalid",
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
const contained = resolveDocsPath({ workspace_root, path: advisories_path });
|
|
340
|
+
if (!contained.ok) return { error: contained.error, code: "advisory_path_invalid" };
|
|
341
|
+
const abs = contained.path;
|
|
342
|
+
if (existsSync(abs) && statSync(abs).isDirectory()) {
|
|
343
|
+
return {
|
|
344
|
+
error: `advisory target is a directory: ${advisories_path}`,
|
|
345
|
+
code: "advisory_target_invalid",
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
mkdirSync(path.dirname(abs), { recursive: true });
|
|
349
|
+
const line = `- Task ${task_id}: ${collapsed}\n`;
|
|
350
|
+
appendFileSync(abs, line, "utf8");
|
|
351
|
+
const rel = posix(path.relative(contained.base, abs));
|
|
352
|
+
return { ok: true, advisory: collapsed, advisories_path: rel };
|
|
353
|
+
}
|
|
@@ -7,12 +7,13 @@ Load `using-superpowers`, `subagent-driven-development`, `test-driven-developmen
|
|
|
7
7
|
|
|
8
8
|
## Handoff destination
|
|
9
9
|
|
|
10
|
-
This session is a handoff destination for a continued plan. The originating session already recorded the post-plan menu choice; present exactly these four choices and never re-offer the originating handoff option:
|
|
10
|
+
This session is a handoff destination for a continued plan. The originating session already recorded the post-plan menu choice; present exactly these four choices plus model deferral and never re-offer the originating handoff option:
|
|
11
11
|
|
|
12
12
|
- Subagent-driven
|
|
13
13
|
- Inline
|
|
14
14
|
- Review spec first
|
|
15
15
|
- Review plan first
|
|
16
|
+
- Change model first
|
|
16
17
|
|
|
17
18
|
<workflow-handoff-destination>true</workflow-handoff-destination>
|
|
18
19
|
|
|
@@ -24,6 +25,7 @@ This session is a handoff destination for a continued plan. The originating sess
|
|
|
24
25
|
- Use native `todowrite` for visible task state as well as the gitignored ledger.
|
|
25
26
|
- Use native `question` for branch/stash choices and guarded external mutations; call mutation tools only after approval with `confirmed: true` (grounded in the recorded NativeChoiceEvidence).
|
|
26
27
|
- Flow-tool confirmations are never agent-typed booleans and never caller-supplied evidence objects: on OpenCode the plugin records the user's native-`question` answer as a host-observed one-use receipt (`attested: true`, `callID`, `selectedLabel`, `recordedAt`) consumed by `workflow_spec_approve` / `workflow_plan_approve` / `workflow_plan_menu` — no evidence argument exists, and delegated worker status comes from host session parentage (`parentID`), never a caller `role` field. On Cursor, confirmations are policy-only (`attested: false`) and subagent-driven execution is rejected as unsupported.
|
|
28
|
+
- Delegated authority is direct-child-only: a worker is the session whose host `parentID` exactly equals the activating coordinator's recorded `coordinator_session_id`; missing, mismatched, or multi-owner lineage fails closed with `delegation_lineage_denied`, and nested `opencode` launches are denied during active delegated work. An authorized child receives only the compact worker contract (execute the supplied brief, follow TDD, land one contiguous non-empty commit range, report results) — never coordinator guidance, `wk-implement`, or ledger management; coordinator bookkeeping via `workflow_sdd_*` stays with the coordinator session.
|
|
27
29
|
- On Cursor, for every repository-scoped `workflow_*` call, pass the active Cursor workspace as `workspace_root`; never rely on the MCP process default.
|
|
28
30
|
- Use native `task` with only the built-in `explore` and `general` agents.
|
|
29
31
|
|
|
@@ -52,7 +54,7 @@ For each top-level task absent from `completed_task_ids`:
|
|
|
52
54
|
3. Delegate read-only discovery, when needed, to an `explore` agent. Delegate implementation to a fresh `general` agent. Product changes follow TDD.
|
|
53
55
|
4. Create a working-state diff with `workflow_sdd_review_package` and `confirmed: true`.
|
|
54
56
|
5. Delegate spec-compliance review and code-quality review to separate `general` agents.
|
|
55
|
-
6. **Blocking** findings (Critical, Important, or spec-compliance) may trigger at most **two** fix+re-review rounds per task. **Advisory** findings (Minor, style, YAGNI, taste) never pause the loop — append them
|
|
57
|
+
6. **Blocking** findings (Critical, Important, or spec-compliance) may trigger at most **two** fix+re-review rounds per task. **Advisory** findings (Minor, style, YAGNI, taste) never pause the loop — append them with `workflow_sdd_append_advisory` (`--task <id> --text <text>`, `confirmed: true`) instead of an unrestricted file edit.
|
|
56
58
|
7. Append the validated ledger entry with `workflow_sdd_append_progress` and `confirmed: true`; mark the todo completed.
|
|
57
59
|
|
|
58
60
|
## Final gate
|
|
@@ -60,10 +60,13 @@ On success, use native `question` / Cursor `AskQuestion` with exactly these opti
|
|
|
60
60
|
3. Handoff → load `wk-handoff` (new session only)
|
|
61
61
|
4. Review spec first
|
|
62
62
|
5. Review plan first
|
|
63
|
+
6. Change model first
|
|
64
|
+
|
|
65
|
+
`Change model first` is display-only deferral: it ends the turn without calling `workflow_plan_menu` and re-presents the menu on the next turn. Every other choice must call `workflow_plan_menu` immediately after the answer and before any skill, branch question, mutation, or handoff.
|
|
63
66
|
|
|
64
67
|
Never emit Superpowers text beginning “Two execution options”.
|
|
65
68
|
|
|
66
|
-
A handoff destination session (the seeded contract carries `<workflow-handoff-destination>true</workflow-handoff-destination>`) presents exactly
|
|
69
|
+
A handoff destination session (the seeded contract carries `<workflow-handoff-destination>true</workflow-handoff-destination>`) presents exactly five choices — Subagent-driven, Inline, Review spec first, Review plan first, Change model first — and never re-offers the originating handoff option.
|
|
67
70
|
|
|
68
71
|
- Specs/plans must follow `templates/spec-template.md` / `templates/plan-template.md` (mandated diagrams, tables, CA-XX).
|
|
69
72
|
|