@linimin/pi-letscook 0.1.51 → 0.1.53
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/CHANGELOG.md +15 -0
- package/README.md +17 -11
- package/extensions/completion/driver.ts +51 -6
- package/extensions/completion/index.ts +15 -7
- package/extensions/completion/input-routing.ts +514 -45
- package/extensions/completion/prompt-surfaces.ts +298 -22
- package/extensions/completion/role-runner.ts +35 -11
- package/extensions/completion/types.ts +76 -4
- package/package.json +1 -1
- package/scripts/cook-trigger-routing-test.sh +857 -49
- package/scripts/release-check.sh +30 -26
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.1.53
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- removed assist mode from public routing behavior so natural-language entry is now either off or router, and made router the default trigger mode while keeping `/cook` as the canonical workflow boundary
|
|
10
|
+
- removed obsolete cook planning docs that no longer match the shipped router-only workflow entry behavior
|
|
11
|
+
|
|
12
|
+
## 0.1.52
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- updated README/help/release parity copy to describe the shipped `off` / `assist` / `router` natural-language routing behavior truthfully while keeping `/cook` as the canonical confirm-first workflow boundary and manual fallback
|
|
17
|
+
- documented the explicit router-mode **Send as normal chat** recovery path as a user choice, not as a silent downgrade, and kept public copy scoped to currently shipped router behavior rather than future auto-mode plans
|
|
18
|
+
- made `npm run release-check` fail closed on the shipped workflow-aware router docs/help contract while continuing to rerun `bash ./scripts/cook-trigger-routing-test.sh` alongside the existing `/cook` smoke/refocus/context regressions
|
|
19
|
+
|
|
5
20
|
## 0.1.51
|
|
6
21
|
|
|
7
22
|
### Added
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
`/cook` turns main-chat discussion about concrete repo changes into a resumable repo workflow stored in repo-local `.agent/**` state.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Natural-language routing is optional and shipped in two modes: `off` disables it, and `router` reviews each non-bypass user turn before implementation starts while leaving ordinary questions in the main chat. In every mode, `/cook` remains the canonical workflow boundary and manual fallback.
|
|
6
6
|
|
|
7
7
|
## Use it when
|
|
8
8
|
|
|
@@ -46,9 +46,10 @@ Then run `/reload` in Pi.
|
|
|
46
46
|
|---|---|
|
|
47
47
|
| Start a long-running task | Discuss the concrete repo change in the main chat, then run `/cook` |
|
|
48
48
|
| Bias mission detection toward one intent | Run `/cook <hint>` |
|
|
49
|
-
|
|
|
49
|
+
| Change natural-language routing behavior | Set `PI_COMPLETION_TRIGGER_MODE=off` or `router` before starting Pi |
|
|
50
|
+
| Hand off from discussion into the same `/cook` flow | In `router`, say `開始做`, `開始實作`, or `go ahead`, then accept the confirmation |
|
|
50
51
|
| Continue the current workflow | Run `/cook` |
|
|
51
|
-
| Use the canonical fallback when
|
|
52
|
+
| Use the canonical fallback when natural-language routing does not fire or you want to bypass it | Run `/cook` explicitly |
|
|
52
53
|
|
|
53
54
|
## What `/cook` expects
|
|
54
55
|
|
|
@@ -60,15 +61,19 @@ Then run `/reload` in Pi.
|
|
|
60
61
|
|
|
61
62
|
If recent discussion is missing, weak, ambiguous, assistant-produced, or only describes planning artifacts instead of concrete repo changes, `/cook` fails closed, leaves canonical `.agent/**` state unchanged, and tells you to clarify the mission in the main chat before rerunning `/cook`.
|
|
62
63
|
|
|
63
|
-
## Natural-language
|
|
64
|
+
## Natural-language routing modes
|
|
64
65
|
|
|
65
|
-
|
|
66
|
+
Set `PI_COMPLETION_TRIGGER_MODE` before starting Pi if you want to change how natural-language routing behaves:
|
|
67
|
+
|
|
68
|
+
- `off` — natural-language routing is disabled. Only explicit `/cook` or `/cook <hint>` can enter the workflow.
|
|
69
|
+
- `router` *(default)* — the workflow-aware router reviews each non-bypass normal user turn before implementation starts. Ordinary questions stay in the main chat, while direct start/resume/refocus/next-round prompts can offer the shared `/cook` flow with confirmation or clarification. Short execution handoff phrases such as `開始做`, `開始實作`, or `go ahead` are covered by the same router path.
|
|
66
70
|
|
|
67
71
|
Important behavior:
|
|
68
|
-
-
|
|
69
|
-
-
|
|
70
|
-
-
|
|
71
|
-
-
|
|
72
|
+
- natural-language routing is only a shortcut into `/cook`; `/cook` is still the canonical workflow boundary and manual fallback
|
|
73
|
+
- startup, refocus, and next-round routing stay confirm-first; nothing silently starts a workflow
|
|
74
|
+
- unclear router offers and classifier recovery stay fail-closed
|
|
75
|
+
- in router mode, the original message only reaches the normal chat path if you explicitly choose **Send as normal chat**
|
|
76
|
+
- explicit slash commands and ordinary main-chat questions continue normally unless you choose the workflow boundary
|
|
72
77
|
|
|
73
78
|
## Typical examples
|
|
74
79
|
|
|
@@ -94,7 +99,7 @@ We should implement the natural-language routing path next.
|
|
|
94
99
|
|
|
95
100
|
## What happens when you run `/cook`
|
|
96
101
|
|
|
97
|
-
`/cook` supports both bare discussion-driven startup and optional inline intent hints.
|
|
102
|
+
`/cook` supports both bare discussion-driven startup and optional inline intent hints. Explicit `/cook` is always the canonical fallback, even when natural-language routing is enabled in `router` mode.
|
|
98
103
|
|
|
99
104
|
| Repo state | What you'll see |
|
|
100
105
|
|---|---|
|
|
@@ -110,6 +115,7 @@ We should implement the natural-language routing path next.
|
|
|
110
115
|
- actions are **Start** and **Cancel**
|
|
111
116
|
- **Cancel** is side-effect free: discuss changes in the main chat and rerun `/cook`
|
|
112
117
|
- weak, ambiguous, assistant-produced, or planning-only discussion does not start a workflow
|
|
118
|
+
- router-mode false positives and classifier failures stay fail-closed unless you explicitly choose **Send as normal chat**
|
|
113
119
|
- when recent discussion suggests a different workflow, `/cook` shows a chooser before any canonical state rewrite
|
|
114
120
|
|
|
115
121
|
When you accept startup or refocus, `/cook` persists the chosen workflow state in canonical `.agent/**` files before the re-ground round begins.
|
|
@@ -260,7 +266,7 @@ npm run rubric-contract-test
|
|
|
260
266
|
npm run release-check
|
|
261
267
|
```
|
|
262
268
|
|
|
263
|
-
`npm run release-check` is the broad packaged-release verifier. It begins with `bash .agent/verify_completion_control_plane.sh`, so missing or stale `.agent/verification-evidence.json` parity fails closed before the broader suite runs, then asserts the shipped
|
|
269
|
+
`npm run release-check` is the broad packaged-release verifier. It begins with `bash .agent/verify_completion_control_plane.sh`, so missing or stale `.agent/verification-evidence.json` parity fails closed before the broader suite runs, then asserts the shipped `/cook` public parity surfaces in `README.md`, `CHANGELOG.md`, and the `/cook` help/fail-closed copy in `extensions/completion/index.ts`, reruns `bash ./scripts/cook-trigger-routing-test.sh` for workflow-aware router coverage including explicit **Send as normal chat** recovery, reruns the startup/refocus/context checks — including the critique-aware `/cook` confirmation regression and the smoke auto-resume prompt path — includes deterministic canonical evidence artifact coverage and includes deterministic active-slice contract coverage plus observability coverage, evaluator calibration, and the rubric-contract regression, and finishes with `npm pack --dry-run`.
|
|
264
270
|
|
|
265
271
|
The direct package-root verifier commands above intentionally self-isolate the repo-local extension when they shell back into `pi`, so you should not need to wrap them with `pi --no-extensions` even if `@linimin/pi-letscook` is also installed globally on the same machine.
|
|
266
272
|
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
loadCompletionSnapshot,
|
|
13
13
|
writeJsonFile,
|
|
14
14
|
} from "./state-store";
|
|
15
|
-
import type { CompletionStateSnapshot } from "./types";
|
|
15
|
+
import type { CompletionStateSnapshot, CookNaturalLanguageHandoff, CookTriggerWorkflowBias } from "./types";
|
|
16
16
|
|
|
17
17
|
type ContextProposalAnalysis = {
|
|
18
18
|
taskType?: string;
|
|
@@ -104,8 +104,13 @@ export type CompletionDriverDeps = {
|
|
|
104
104
|
evaluationProfile: string,
|
|
105
105
|
intent?: "auto" | "continue" | "refocus",
|
|
106
106
|
missionAnchor?: string,
|
|
107
|
+
naturalLanguageHandoff?: CookNaturalLanguageHandoff,
|
|
108
|
+
) => string;
|
|
109
|
+
completionResumePrompt: (
|
|
110
|
+
taskType: string,
|
|
111
|
+
evaluationProfile: string,
|
|
112
|
+
naturalLanguageHandoff?: CookNaturalLanguageHandoff,
|
|
107
113
|
) => string;
|
|
108
|
-
completionResumePrompt: (taskType: string, evaluationProfile: string) => string;
|
|
109
114
|
deriveCookContextProposal: (ctx: DriverContext, projectName: string, hintText?: string) => Promise<ContextProposal | undefined>;
|
|
110
115
|
confirmContextProposal: (
|
|
111
116
|
ctx: { hasUI: boolean; ui: any },
|
|
@@ -374,10 +379,15 @@ async function resumeActiveWorkflowFromCanonicalState(
|
|
|
374
379
|
ctx: { cwd: string; hasUI: boolean; ui: any },
|
|
375
380
|
snapshot: CompletionStateSnapshot,
|
|
376
381
|
deps: CompletionDriverDeps,
|
|
382
|
+
naturalLanguageHandoff?: CookNaturalLanguageHandoff,
|
|
377
383
|
): Promise<void> {
|
|
378
384
|
const mission = currentMissionAnchor(snapshot);
|
|
379
385
|
pi.setSessionName(`completion: ${mission.slice(0, 60)}`);
|
|
380
|
-
const resumePrompt = deps.completionResumePrompt(
|
|
386
|
+
const resumePrompt = deps.completionResumePrompt(
|
|
387
|
+
currentTaskType(snapshot) ?? "(missing)",
|
|
388
|
+
currentEvaluationProfile(snapshot) ?? "(missing)",
|
|
389
|
+
naturalLanguageHandoff,
|
|
390
|
+
);
|
|
381
391
|
const rootKey = deps.completionRootKey(snapshot, deps.getCtxCwd(ctx));
|
|
382
392
|
const fingerprint = completionContinuationFingerprint(snapshot) ?? JSON.stringify({
|
|
383
393
|
kind: "resume",
|
|
@@ -536,15 +546,49 @@ export type RunCookEntryOptions = {
|
|
|
536
546
|
origin: CookInvocationOrigin;
|
|
537
547
|
hintText?: string;
|
|
538
548
|
originalInput?: string;
|
|
549
|
+
triggerText?: string;
|
|
550
|
+
preferredRoutingBias?: CookTriggerWorkflowBias;
|
|
551
|
+
clarificationCapsule?: CookNaturalLanguageHandoff["clarificationCapsule"];
|
|
552
|
+
adoptedArtifact?: CookNaturalLanguageHandoff["adoptedArtifact"];
|
|
539
553
|
};
|
|
540
554
|
|
|
555
|
+
function buildNaturalLanguageDerivationHint(handoff: CookNaturalLanguageHandoff | undefined): string | undefined {
|
|
556
|
+
if (!handoff) return undefined;
|
|
557
|
+
const lines: string[] = [];
|
|
558
|
+
if (handoff.hintText) lines.push(`Focus hint: ${handoff.hintText}`);
|
|
559
|
+
if (handoff.clarificationCapsule?.goal) lines.push(`Clarified goal: ${handoff.clarificationCapsule.goal}`);
|
|
560
|
+
if (handoff.clarificationCapsule?.scope?.length) lines.push(`Clarified scope: ${handoff.clarificationCapsule.scope.join(" | ")}`);
|
|
561
|
+
if (handoff.clarificationCapsule?.nonGoal?.length) lines.push(`Clarified non-goal: ${handoff.clarificationCapsule.nonGoal.join(" | ")}`);
|
|
562
|
+
if (handoff.clarificationCapsule?.doneWhen?.length) lines.push(`Clarified done-when: ${handoff.clarificationCapsule.doneWhen.join(" | ")}`);
|
|
563
|
+
if (handoff.clarificationCapsule?.selectedWorkflowBias) {
|
|
564
|
+
lines.push(`Clarified routing bias: ${handoff.clarificationCapsule.selectedWorkflowBias}`);
|
|
565
|
+
}
|
|
566
|
+
if (handoff.adoptedArtifact) {
|
|
567
|
+
lines.push(`User explicitly adopted artifact: ${handoff.adoptedArtifact.title}`);
|
|
568
|
+
if (handoff.adoptedArtifact.path) lines.push(`Adopted artifact path: ${handoff.adoptedArtifact.path}`);
|
|
569
|
+
if (handoff.adoptedArtifact.preview) lines.push(`Adopted artifact preview: ${handoff.adoptedArtifact.preview}`);
|
|
570
|
+
}
|
|
571
|
+
return lines.length > 0 ? lines.join("\n") : undefined;
|
|
572
|
+
}
|
|
573
|
+
|
|
541
574
|
export async function runCookEntry(
|
|
542
575
|
pi: ExtensionAPI,
|
|
543
576
|
ctx: DriverContext,
|
|
544
577
|
deps: CompletionDriverDeps,
|
|
545
578
|
options: RunCookEntryOptions,
|
|
546
579
|
): Promise<void> {
|
|
547
|
-
const
|
|
580
|
+
const naturalLanguageHandoff =
|
|
581
|
+
options.origin === "natural-language-trigger"
|
|
582
|
+
? {
|
|
583
|
+
preferredRoutingBias: options.preferredRoutingBias,
|
|
584
|
+
triggerText: options.triggerText?.trim() ? options.triggerText.trim() : options.originalInput?.trim() ? options.originalInput.trim() : undefined,
|
|
585
|
+
hintText: options.hintText?.trim() ? options.hintText.trim() : undefined,
|
|
586
|
+
clarificationCapsule: options.clarificationCapsule,
|
|
587
|
+
adoptedArtifact: options.adoptedArtifact,
|
|
588
|
+
}
|
|
589
|
+
: undefined;
|
|
590
|
+
const derivationHint = buildNaturalLanguageDerivationHint(naturalLanguageHandoff);
|
|
591
|
+
const explicitHint = [options.hintText?.trim(), derivationHint].filter((value): value is string => Boolean(value)).join("\n\n") || undefined;
|
|
548
592
|
let goal: string | undefined;
|
|
549
593
|
const cwd = deps.getCtxCwd(ctx);
|
|
550
594
|
let snapshot = await loadCompletionSnapshot(cwd);
|
|
@@ -616,7 +660,7 @@ export async function runCookEntry(
|
|
|
616
660
|
} else {
|
|
617
661
|
const assessment = await assessActiveWorkflowProposalRouting(ctx, snapshot, deps, explicitHint);
|
|
618
662
|
if (!assessment.proposal || assessment.action === "continue") {
|
|
619
|
-
await resumeActiveWorkflowFromCanonicalState(pi, ctx, snapshot, deps);
|
|
663
|
+
await resumeActiveWorkflowFromCanonicalState(pi, ctx, snapshot, deps, naturalLanguageHandoff);
|
|
620
664
|
return;
|
|
621
665
|
}
|
|
622
666
|
const decision = await confirmExistingWorkflowProposal(ctx, snapshot, assessment.proposal, deps, {
|
|
@@ -634,7 +678,7 @@ export async function runCookEntry(
|
|
|
634
678
|
return;
|
|
635
679
|
}
|
|
636
680
|
if (decision.action === "continue") {
|
|
637
|
-
await resumeActiveWorkflowFromCanonicalState(pi, ctx, snapshot, deps);
|
|
681
|
+
await resumeActiveWorkflowFromCanonicalState(pi, ctx, snapshot, deps, naturalLanguageHandoff);
|
|
638
682
|
return;
|
|
639
683
|
}
|
|
640
684
|
const selectedProposal = decision.proposal;
|
|
@@ -665,6 +709,7 @@ export async function runCookEntry(
|
|
|
665
709
|
currentEvaluationProfile(snapshot) ?? "(missing)",
|
|
666
710
|
kickoffIntent,
|
|
667
711
|
kickoffMissionAnchor,
|
|
712
|
+
naturalLanguageHandoff,
|
|
668
713
|
);
|
|
669
714
|
const rootKey = deps.completionRootKey(snapshot, deps.getCtxCwd(ctx));
|
|
670
715
|
const fingerprint = completionContinuationFingerprint(snapshot) ?? JSON.stringify({
|
|
@@ -42,6 +42,7 @@ import {
|
|
|
42
42
|
buildContextProposalContinuationReason as buildExtractedContextProposalContinuationReason,
|
|
43
43
|
buildEvaluationRoleContextLines as buildExtractedEvaluationRoleContextLines,
|
|
44
44
|
buildEvaluationRoleReminderText as buildExtractedEvaluationRoleReminderText,
|
|
45
|
+
buildNaturalLanguageHandoffMetadataLines,
|
|
45
46
|
buildResumeCapsule as buildExtractedResumeCapsule,
|
|
46
47
|
buildSystemReminder as buildExtractedSystemReminder,
|
|
47
48
|
maybeWriteContextProposalConfirmationSnapshot,
|
|
@@ -78,7 +79,7 @@ import {
|
|
|
78
79
|
} from "./state-store";
|
|
79
80
|
import { parseFirstNumber, parseYesNo } from "./transcription";
|
|
80
81
|
import type { TranscriptionResult } from "./transcription";
|
|
81
|
-
import type { CompletionStateSnapshot, CompletionRole, JsonRecord, LiveRoleActivity } from "./types";
|
|
82
|
+
import type { CompletionStateSnapshot, CompletionRole, CookNaturalLanguageHandoff, JsonRecord, LiveRoleActivity } from "./types";
|
|
82
83
|
|
|
83
84
|
const PROTOCOL_ID = "completion";
|
|
84
85
|
const ROLE_NAMES = [
|
|
@@ -208,9 +209,9 @@ function maybeWriteTestSnapshot(targetPath: string | undefined, content: string)
|
|
|
208
209
|
|
|
209
210
|
const COOK_MAIN_CHAT_RERUN_GUIDANCE = "Discuss changes in the main chat and rerun /cook.";
|
|
210
211
|
const COOK_BARE_ONLY_GUIDANCE =
|
|
211
|
-
"/cook remains the canonical workflow boundary.
|
|
212
|
+
"/cook remains the canonical workflow boundary. Natural-language routing can stay off or run in router mode to review each non-bypass user turn before implementation starts, but the shared /cook flow still owns mission selection and confirmation.";
|
|
212
213
|
const COOK_STRUCTURED_DISCUSSION_FAILURE_DETAIL =
|
|
213
|
-
"/cook failed closed because recent discussion did not produce a clear execution-ready Mission/Scope/Constraints/Acceptance proposal for concrete repo changes.
|
|
214
|
+
"/cook failed closed because recent discussion did not produce a clear execution-ready Mission/Scope/Constraints/Acceptance proposal for concrete repo changes. Router mode only offers the same /cook flow, and router recovery only replays to normal chat when you explicitly choose Send as normal chat, so clarify the concrete repo changes in the main chat and rerun /cook.";
|
|
214
215
|
|
|
215
216
|
function buildCookCancellationMessage(prefix: string): string {
|
|
216
217
|
return `${prefix}. ${COOK_MAIN_CHAT_RERUN_GUIDANCE}`;
|
|
@@ -895,18 +896,25 @@ function completionKickoff(
|
|
|
895
896
|
evaluationProfile: string,
|
|
896
897
|
intent: "auto" | "continue" | "refocus" = "auto",
|
|
897
898
|
missionAnchor?: string,
|
|
899
|
+
naturalLanguageHandoff?: CookNaturalLanguageHandoff,
|
|
898
900
|
): string {
|
|
901
|
+
const naturalLanguageHandoffBlock = buildNaturalLanguageHandoffMetadataLines(naturalLanguageHandoff).join("\n");
|
|
899
902
|
const intentBlock =
|
|
900
903
|
intent === "continue" && missionAnchor
|
|
901
904
|
? `Existing canonical mission anchor:\n${missionAnchor}\n\nWorkflow intent:\n- Continue the existing workflow.\n- Treat the new user text as supplemental direction unless canonical reconciliation proves the mission itself must change.\n\n`
|
|
902
905
|
: intent === "refocus" && missionAnchor
|
|
903
906
|
? `Updated canonical mission anchor:\n${missionAnchor}\n\nWorkflow intent:\n- The user explicitly refocused the workflow before this kickoff.\n- Re-read canonical .agent/** state and continue from the refocused mission.\n\n`
|
|
904
907
|
: "";
|
|
905
|
-
return `/skill:completion-protocol Start or continue the completion workflow for this repo.\n\nBefore acting, read:\n- ${SKILL_PATH}\n- ${REFERENCE_PATH}\n\nCanonical routing profile:\n- task_type: ${taskType}\n- evaluation_profile: ${evaluationProfile}\n\nUser goal:\n${goal}\n\n${intentBlock}Driver instructions:\n- Canonical truth is in .agent/**. Re-read .agent/state.json, .agent/plan.json, .agent/active-slice.json, and .agent/verification-evidence.json before acting when they exist.\n- If tracked completion contract files are missing or onboarding is required, invoke completion_role with role completion-bootstrapper.\n- Otherwise follow the mandatory dispatch rules from completion-protocol.\n- For selected, in-progress, committed, or done slices, treat .agent/active-slice.json as the canonical implementation contract and route to completion-regrounder if it drifts from the selected plan slice or the exact handoff is unclear.\n- Consume .agent/verification-evidence.json instead of temp-only verification summaries when it is populated.\n- Use completion_role for all completion-* role work. Do not directly implement tracked product changes yourself.\n- Continue dispatching mandatory roles while continuation_policy == continue.\n- Only stop for the user when continuation_policy is await_user_input, blocked, paused, or done.`;
|
|
908
|
+
return `/skill:completion-protocol Start or continue the completion workflow for this repo.\n\nBefore acting, read:\n- ${SKILL_PATH}\n- ${REFERENCE_PATH}\n\nCanonical routing profile:\n- task_type: ${taskType}\n- evaluation_profile: ${evaluationProfile}\n\nUser goal:\n${goal}\n\n${naturalLanguageHandoffBlock}${intentBlock}Driver instructions:\n- Canonical truth is in .agent/**. Re-read .agent/state.json, .agent/plan.json, .agent/active-slice.json, and .agent/verification-evidence.json before acting when they exist.\n- If tracked completion contract files are missing or onboarding is required, invoke completion_role with role completion-bootstrapper.\n- Otherwise follow the mandatory dispatch rules from completion-protocol.\n- For selected, in-progress, committed, or done slices, treat .agent/active-slice.json as the canonical implementation contract and route to completion-regrounder if it drifts from the selected plan slice or the exact handoff is unclear.\n- Consume .agent/verification-evidence.json instead of temp-only verification summaries when it is populated.\n- Use completion_role for all completion-* role work. Do not directly implement tracked product changes yourself.\n- Continue dispatching mandatory roles while continuation_policy == continue.\n- Only stop for the user when continuation_policy is await_user_input, blocked, paused, or done.`;
|
|
906
909
|
}
|
|
907
910
|
|
|
908
|
-
function completionResumePrompt(
|
|
909
|
-
|
|
911
|
+
function completionResumePrompt(
|
|
912
|
+
taskType: string,
|
|
913
|
+
evaluationProfile: string,
|
|
914
|
+
naturalLanguageHandoff?: CookNaturalLanguageHandoff,
|
|
915
|
+
): string {
|
|
916
|
+
const naturalLanguageHandoffBlock = buildNaturalLanguageHandoffMetadataLines(naturalLanguageHandoff).join("\n");
|
|
917
|
+
return `/skill:completion-protocol Resume the completion workflow from canonical state.\n\nBefore acting, read:\n- ${SKILL_PATH}\n- ${REFERENCE_PATH}\n\nCanonical routing profile:\n- task_type: ${taskType}\n- evaluation_profile: ${evaluationProfile}\n\n${naturalLanguageHandoffBlock}Resume instructions:\n- Re-read .agent/state.json, .agent/plan.json, .agent/active-slice.json, and .agent/verification-evidence.json before acting.\n- If canonical state is missing, invalid, contradictory, stale, or ambiguous, route to completion-regrounder first.\n- For selected, in-progress, committed, or done slices, treat .agent/active-slice.json as the canonical implementation contract and route to completion-regrounder if it drifts from the selected plan slice or the exact handoff is unclear.\n- Consume .agent/verification-evidence.json instead of temp-only verification summaries when it is populated.\n- Continue from next_mandatory_role and next_mandatory_action.\n- Use completion_role for all completion-* role work.\n- Continue dispatching mandatory roles while continuation_policy == continue.\n- Only stop for the user when continuation_policy is await_user_input, blocked, paused, or done.`;
|
|
910
918
|
}
|
|
911
919
|
|
|
912
920
|
export default function completionExtension(pi: ExtensionAPI) {
|
|
@@ -923,7 +931,7 @@ export default function completionExtension(pi: ExtensionAPI) {
|
|
|
923
931
|
structuredDiscussionFailureDetail: COOK_STRUCTURED_DISCUSSION_FAILURE_DETAIL,
|
|
924
932
|
mainChatRerunGuidance: COOK_MAIN_CHAT_RERUN_GUIDANCE,
|
|
925
933
|
cookCommandSpec: {
|
|
926
|
-
description: "/cook workflow: start, continue, refocus, or start the next round;
|
|
934
|
+
description: "/cook workflow: start, continue, refocus, or start the next round; /cook stays canonical while natural-language routing can be off or router",
|
|
927
935
|
},
|
|
928
936
|
buildContextProposalContinuationReason,
|
|
929
937
|
completionKickoff,
|