@linimin/pi-letscook 0.1.53 → 0.1.55

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 CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ### Changed
6
+
7
+ - made `/cook` derive a confirmable startup brief from recent discussion before any canonical workflow rewrite, then preserve the confirmed brief in canonical state as advisory intake for later re-grounding
8
+ - removed inline `/cook` arguments from the shipped entry path again so explicit bare `/cook` is the only public command, and fail closed when recent discussion is insufficient or unreliable
9
+
10
+ ## 0.1.54
11
+
12
+ ### Changed
13
+
14
+ - removed workflow-aware prompt interception so only explicit `/cook` or `/cook <hint>` enters the workflow; ordinary prompts now always stay on the main chat path
15
+ - updated docs and release checks to describe explicit `/cook` entry instead of router-managed natural-language takeover
16
+
5
17
  ## 0.1.53
6
18
 
7
19
  ### Changed
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
- 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.
5
+ `/cook` is the explicit workflow boundary for starting, continuing, refocusing, or beginning the next round of long-running repo work.
6
6
 
7
7
  ## Use it when
8
8
 
@@ -31,13 +31,12 @@ Then run `/reload` in Pi.
31
31
  `pi install npm:@linimin/pi-letscook`
32
32
  2. Run `/reload` in Pi.
33
33
  3. In the main chat, describe the concrete repo change you want.
34
- 4. Run `/cook` or `/cook <hint>`.
35
- 5. Review the proposal and choose **Start** or **Cancel**.
34
+ 4. Run `/cook`.
35
+ 5. Review the startup brief and choose **Start** or **Cancel**.
36
36
  6. Later, run `/cook` again to continue, refocus, or start the next round.
37
37
 
38
38
  ```text
39
39
  /cook
40
- /cook login redirect
41
40
  ```
42
41
 
43
42
  ## Common actions
@@ -45,35 +44,28 @@ Then run `/reload` in Pi.
45
44
  | If you want to... | Do this |
46
45
  |---|---|
47
46
  | Start a long-running task | Discuss the concrete repo change in the main chat, then run `/cook` |
48
- | Bias mission detection toward one intent | Run `/cook <hint>` |
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 |
51
47
  | Continue the current workflow | Run `/cook` |
52
- | Use the canonical fallback when natural-language routing does not fire or you want to bypass it | Run `/cook` explicitly |
48
+ | Refocus or start the next round | Discuss the new concrete repo change in the main chat, then run `/cook` |
53
49
 
54
50
  ## What `/cook` expects
55
51
 
56
52
  - recent main-chat discussion about concrete repo changes
53
+ - enough detail to derive a startup brief with mission, scope, constraints or non-goals, acceptance, and notes or risks
57
54
  - README/CHANGELOG updates still count as concrete repo changes
58
55
  - assistant-produced summaries and plan/spec/design-doc/proposal-only artifacts do not
59
56
 
60
- `/cook <hint>` acts as a high-priority intent hint for interpreting recent discussion, but it does not bypass fail-closed behavior or the approval-only Start/Cancel confirmation flow.
61
-
62
57
  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`.
63
58
 
64
- ## Natural-language routing modes
59
+ If you pass inline arguments to `/cook`, it also fails closed and tells you to move that intent into the main chat before rerunning bare `/cook`.
65
60
 
66
- Set `PI_COMPLETION_TRIGGER_MODE` before starting Pi if you want to change how natural-language routing behaves:
61
+ ## Workflow entry
67
62
 
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.
63
+ Only explicit `/cook` enters the workflow. Ordinary prompts stay in the main chat and go straight to the primary agent.
70
64
 
71
65
  Important behavior:
72
- - natural-language routing is only a shortcut into `/cook`; `/cook` is still the canonical workflow boundary and manual fallback
66
+ - `/cook` is the canonical workflow boundary and manual entry point
73
67
  - 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
68
+ - explicit slash commands other than `/cook` continue normally in the main chat
77
69
 
78
70
  ## Typical examples
79
71
 
@@ -84,28 +76,15 @@ I want to add login redirect handling and tests.
84
76
  /cook
85
77
  ```
86
78
 
87
- Bias proposal derivation toward a specific intent:
88
-
89
- ```text
90
- /cook login redirect
91
- ```
92
-
93
- Hand off from discussion into the same `/cook` flow:
94
-
95
- ```text
96
- We should implement the natural-language routing path next.
97
- 開始做
98
- ```
99
-
100
79
  ## What happens when you run `/cook`
101
80
 
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.
81
+ `/cook` first derives a startup brief from recent discussion, then shows the existing approval-only Start/Cancel gate.
103
82
 
104
83
  | Repo state | What you'll see |
105
84
  |---|---|
106
- | No workflow yet | A startup proposal built from recent main-chat discussion. You choose **Start** or **Cancel**. Weak or planning-only discussion fails closed. |
107
- | Active workflow exists | Usually a resume of the current workflow. If recent discussion clearly points to a different concrete repo change, `/cook` shows a chooser first and only rewrites canonical state after confirmation. Ambiguous discussion stays conservative. |
108
- | Previous workflow is `done` | A next-round proposal from recent main-chat discussion, again behind **Start** or **Cancel**. Discussion that only restates already-finished work fails closed. |
85
+ | No workflow yet | A startup brief built from recent main-chat discussion. You choose **Start** or **Cancel**. Weak, unreliable, or planning-only discussion fails closed. |
86
+ | Active workflow exists | Usually a resume of the current workflow. If recent discussion clearly points to a different concrete repo change, `/cook` shows a chooser first and only rewrites canonical state after you confirm the new startup brief. Ambiguous discussion stays conservative. |
87
+ | Previous workflow is `done` | A next-round startup brief from recent main-chat discussion, again behind **Start** or **Cancel**. Discussion that only restates already-finished work fails closed. |
109
88
 
110
89
  ## Confirmation and fail-closed behavior
111
90
 
@@ -115,11 +94,12 @@ We should implement the natural-language routing path next.
115
94
  - actions are **Start** and **Cancel**
116
95
  - **Cancel** is side-effect free: discuss changes in the main chat and rerun `/cook`
117
96
  - 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**
119
97
  - when recent discussion suggests a different workflow, `/cook` shows a chooser before any canonical state rewrite
120
98
 
121
99
  When you accept startup or refocus, `/cook` persists the chosen workflow state in canonical `.agent/**` files before the re-ground round begins.
122
100
 
101
+ The confirmed startup brief is also preserved there as advisory intake for later re-grounding. It does not replace `.agent/plan.json` or `.agent/active-slice.json`, which remain under regrounder authority.
102
+
123
103
  ## Observability
124
104
 
125
105
  When canonical `.agent/**` state exists and no role is actively running, the extension shows a completion widget sourced from that state. The widget summarizes:
@@ -258,7 +238,6 @@ Run validation from the package root:
258
238
  npm run smoke-test
259
239
  npm run refocus-test
260
240
  npm run context-proposal-test
261
- bash ./scripts/cook-trigger-routing-test.sh
262
241
  bash scripts/canonical-evidence-artifact-test.sh
263
242
  npm run observability-status-test
264
243
  npm run evaluator-calibration-test
@@ -266,7 +245,7 @@ npm run rubric-contract-test
266
245
  npm run release-check
267
246
  ```
268
247
 
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`.
248
+ `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 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`.
270
249
 
271
250
  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.
272
251
 
@@ -2,7 +2,11 @@ import { promises as fsp } from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
4
4
  import {
5
+ buildMission,
5
6
  buildProfileRecord,
7
+ currentEvaluationProfile,
8
+ currentMissionAnchor,
9
+ currentTaskType,
6
10
  defaultActiveSlice,
7
11
  defaultPlan,
8
12
  defaultState,
@@ -12,7 +16,8 @@ import {
12
16
  loadCompletionSnapshot,
13
17
  writeJsonFile,
14
18
  } from "./state-store";
15
- import type { CompletionStateSnapshot, CookNaturalLanguageHandoff, CookTriggerWorkflowBias } from "./types";
19
+ import { buildAdvisoryStartupBrief } from "./prompt-surfaces";
20
+ import type { CompletionStateSnapshot } from "./types";
16
21
 
17
22
  type ContextProposalAnalysis = {
18
23
  taskType?: string;
@@ -82,7 +87,6 @@ type DriverContinuationTracker = {
82
87
  };
83
88
 
84
89
  export type CompletionDriverDeps = {
85
- bareOnlyGuidance: string;
86
90
  structuredDiscussionFailureDetail: string;
87
91
  mainChatRerunGuidance: string;
88
92
  cookCommandSpec: {
@@ -104,14 +108,9 @@ export type CompletionDriverDeps = {
104
108
  evaluationProfile: string,
105
109
  intent?: "auto" | "continue" | "refocus",
106
110
  missionAnchor?: string,
107
- naturalLanguageHandoff?: CookNaturalLanguageHandoff,
108
111
  ) => string;
109
- completionResumePrompt: (
110
- taskType: string,
111
- evaluationProfile: string,
112
- naturalLanguageHandoff?: CookNaturalLanguageHandoff,
113
- ) => string;
114
- deriveCookContextProposal: (ctx: DriverContext, projectName: string, hintText?: string) => Promise<ContextProposal | undefined>;
112
+ completionResumePrompt: (taskType: string, evaluationProfile: string) => string;
113
+ deriveCookContextProposal: (ctx: DriverContext, projectName: string) => Promise<ContextProposal | undefined>;
115
114
  confirmContextProposal: (
116
115
  ctx: { hasUI: boolean; ui: any },
117
116
  proposal: ContextProposal,
@@ -122,7 +121,7 @@ export type CompletionDriverDeps = {
122
121
  scaffoldCompletionFiles: (
123
122
  root: string,
124
123
  missionAnchor: string,
125
- options?: { analysis?: ContextProposalAnalysis; continuationReason?: string },
124
+ options?: { analysis?: ContextProposalAnalysis; continuationReason?: string; advisoryStartupBrief?: Record<string, unknown> },
126
125
  ) => Promise<{ root: string; created: string[] }>;
127
126
  maybeWriteActiveWorkflowRoutingSnapshot: (assessment: ActiveWorkflowProposalAssessment) => void;
128
127
  missionAnchorsLikelyEquivalent: (left: string, right: string) => boolean;
@@ -168,33 +167,6 @@ function buildCookStructuredDiscussionFailureMessage(deps: CompletionDriverDeps,
168
167
  return prefix ? `${prefix} ${deps.structuredDiscussionFailureDetail}` : deps.structuredDiscussionFailureDetail;
169
168
  }
170
169
 
171
- function currentMissionAnchor(snapshot: CompletionStateSnapshot): string {
172
- return (
173
- asString(snapshot.state?.mission_anchor) ??
174
- asString(snapshot.plan?.mission_anchor) ??
175
- asString(snapshot.active?.mission_anchor) ??
176
- path.basename(snapshot.files.root)
177
- );
178
- }
179
-
180
- function currentTaskType(snapshot: CompletionStateSnapshot): string | undefined {
181
- return (
182
- asString(snapshot.active?.task_type) ??
183
- asString(snapshot.state?.task_type) ??
184
- asString(snapshot.plan?.task_type) ??
185
- asString(snapshot.profile?.task_type)
186
- );
187
- }
188
-
189
- function currentEvaluationProfile(snapshot: CompletionStateSnapshot): string | undefined {
190
- return (
191
- asString(snapshot.active?.evaluation_profile) ??
192
- asString(snapshot.state?.evaluation_profile) ??
193
- asString(snapshot.plan?.evaluation_profile) ??
194
- asString(snapshot.profile?.evaluation_profile)
195
- );
196
- }
197
-
198
170
  export function completionContinuationFingerprint(snapshot: CompletionStateSnapshot): string | undefined {
199
171
  if (asString(snapshot.state?.continuation_policy) !== "continue") return undefined;
200
172
  const nextMandatoryRole = asString(snapshot.state?.next_mandatory_role);
@@ -330,11 +302,10 @@ async function assessActiveWorkflowProposalRouting(
330
302
  ctx: DriverContext,
331
303
  snapshot: CompletionStateSnapshot,
332
304
  deps: CompletionDriverDeps,
333
- hintText?: string,
334
305
  ): Promise<ActiveWorkflowProposalAssessment> {
335
306
  const currentMission = currentMissionAnchor(snapshot);
336
307
  const projectName = path.basename(snapshot.files.root);
337
- const proposal = await deps.deriveCookContextProposal(ctx, projectName, hintText);
308
+ const proposal = await deps.deriveCookContextProposal(ctx, projectName);
338
309
  if (!proposal) {
339
310
  const assessment: ActiveWorkflowProposalAssessment = {
340
311
  action: "unclear",
@@ -379,15 +350,10 @@ async function resumeActiveWorkflowFromCanonicalState(
379
350
  ctx: { cwd: string; hasUI: boolean; ui: any },
380
351
  snapshot: CompletionStateSnapshot,
381
352
  deps: CompletionDriverDeps,
382
- naturalLanguageHandoff?: CookNaturalLanguageHandoff,
383
353
  ): Promise<void> {
384
354
  const mission = currentMissionAnchor(snapshot);
385
355
  pi.setSessionName(`completion: ${mission.slice(0, 60)}`);
386
- const resumePrompt = deps.completionResumePrompt(
387
- currentTaskType(snapshot) ?? "(missing)",
388
- currentEvaluationProfile(snapshot) ?? "(missing)",
389
- naturalLanguageHandoff,
390
- );
356
+ const resumePrompt = deps.completionResumePrompt(currentTaskType(snapshot) ?? "(missing)", currentEvaluationProfile(snapshot) ?? "(missing)");
391
357
  const rootKey = deps.completionRootKey(snapshot, deps.getCtxCwd(ctx));
392
358
  const fingerprint = completionContinuationFingerprint(snapshot) ?? JSON.stringify({
393
359
  kind: "resume",
@@ -495,6 +461,7 @@ async function refocusCompletionMission(
495
461
  rawGoal: string,
496
462
  analysis: ContextProposalAnalysis | undefined,
497
463
  deps: CompletionDriverDeps,
464
+ advisoryStartupBrief?: Record<string, unknown>,
498
465
  ): Promise<void> {
499
466
  const requiredStopJudges = asNumber(snapshot.profile?.required_stop_judges) ?? 3;
500
467
  const root = snapshot.files.root;
@@ -513,7 +480,7 @@ async function refocusCompletionMission(
513
480
  taskType: routing.taskType,
514
481
  evaluationProfile: routing.evaluationProfile,
515
482
  continuationReason: deps.buildContextProposalContinuationReason("User refocused workflow via /cook:", rawGoal, routing),
516
- }),
483
+ }, advisoryStartupBrief),
517
484
  remaining_stop_judges: requiredStopJudges,
518
485
  next_mandatory_action: "Reconcile canonical state from current repo truth for the refocused mission",
519
486
  };
@@ -536,59 +503,11 @@ function isWorkflowDone(snapshot: CompletionStateSnapshot | undefined): boolean
536
503
  return asString(snapshot?.state?.continuation_policy) === "done";
537
504
  }
538
505
 
539
- function buildMission(projectName: string, missionAnchor: string): string {
540
- return `# Mission\n\nProject: ${projectName}\n\nMission anchor:\n${missionAnchor}\n\nThis file is a tracked human-readable statement of the repo's completion mission. Re-grounders may refine this file when repo truth becomes clearer, but it must stay truthful to shipped behavior and the active completion objective.\n`;
541
- }
542
-
543
- export type CookInvocationOrigin = "command" | "natural-language-trigger";
544
-
545
- export type RunCookEntryOptions = {
546
- origin: CookInvocationOrigin;
547
- hintText?: string;
548
- originalInput?: string;
549
- triggerText?: string;
550
- preferredRoutingBias?: CookTriggerWorkflowBias;
551
- clarificationCapsule?: CookNaturalLanguageHandoff["clarificationCapsule"];
552
- adoptedArtifact?: CookNaturalLanguageHandoff["adoptedArtifact"];
553
- };
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
-
574
506
  export async function runCookEntry(
575
507
  pi: ExtensionAPI,
576
508
  ctx: DriverContext,
577
509
  deps: CompletionDriverDeps,
578
- options: RunCookEntryOptions,
579
510
  ): Promise<void> {
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;
592
511
  let goal: string | undefined;
593
512
  const cwd = deps.getCtxCwd(ctx);
594
513
  let snapshot = await loadCompletionSnapshot(cwd);
@@ -600,13 +519,13 @@ export async function runCookEntry(
600
519
  if (!snapshot) {
601
520
  const root = findRepoRoot(cwd) ?? cwd;
602
521
  const projectName = path.basename(root);
603
- const proposal = await deps.deriveCookContextProposal(ctx, projectName, explicitHint);
522
+ const proposal = await deps.deriveCookContextProposal(ctx, projectName);
604
523
  if (!proposal) {
605
524
  deps.emitCommandText(ctx, buildCookStructuredDiscussionFailureMessage(deps), "info");
606
525
  return;
607
526
  }
608
527
  const decision = await deps.confirmContextProposal(ctx, proposal, {
609
- title: "Start a completion workflow from the recent discussion?",
528
+ title: "Start a completion workflow from this startup brief?",
610
529
  });
611
530
  if (!decision) {
612
531
  deps.emitCommandText(ctx, buildCookCancellationMessage("Cancelled recent-discussion workflow proposal", deps), "info");
@@ -623,6 +542,7 @@ export async function runCookEntry(
623
542
  goal ?? kickoffMissionAnchor ?? projectName,
624
543
  startupRouting,
625
544
  ),
545
+ advisoryStartupBrief: buildAdvisoryStartupBrief({ proposal, analysis: decision.analysis }),
626
546
  });
627
547
  deps.emitCommandText(
628
548
  ctx,
@@ -639,13 +559,13 @@ export async function runCookEntry(
639
559
  if (!goal) {
640
560
  if (workflowDone) {
641
561
  const projectName = path.basename(snapshot.files.root);
642
- const proposal = await deps.deriveCookContextProposal(ctx, projectName, explicitHint);
562
+ const proposal = await deps.deriveCookContextProposal(ctx, projectName);
643
563
  if (!proposal) {
644
564
  deps.emitCommandText(ctx, buildCookStructuredDiscussionFailureMessage(deps, "The previous completion workflow is already done."), "info");
645
565
  return;
646
566
  }
647
567
  const decision = await deps.confirmContextProposal(ctx, proposal, {
648
- title: "The previous completion workflow is done. Start the next workflow round from the recent discussion?",
568
+ title: "The previous completion workflow is done. Start the next workflow round from this startup brief?",
649
569
  });
650
570
  if (!decision) {
651
571
  deps.emitCommandText(ctx, buildCookCancellationMessage("Cancelled next workflow round proposal", deps), "info");
@@ -654,13 +574,20 @@ export async function runCookEntry(
654
574
  goal = decision.goalText;
655
575
  kickoffIntent = "refocus";
656
576
  kickoffMissionAnchor = decision.missionAnchor;
657
- await refocusCompletionMission(snapshot, decision.missionAnchor, decision.goalText, decision.analysis, deps);
577
+ await refocusCompletionMission(
578
+ snapshot,
579
+ decision.missionAnchor,
580
+ decision.goalText,
581
+ decision.analysis,
582
+ deps,
583
+ buildAdvisoryStartupBrief({ proposal, analysis: decision.analysis }),
584
+ );
658
585
  snapshot = (await loadCompletionSnapshot(snapshot.files.root)) ?? snapshot;
659
586
  deps.emitCommandText(ctx, `Started a new completion workflow round from recent discussion: ${decision.missionAnchor}`, "info");
660
587
  } else {
661
- const assessment = await assessActiveWorkflowProposalRouting(ctx, snapshot, deps, explicitHint);
588
+ const assessment = await assessActiveWorkflowProposalRouting(ctx, snapshot, deps);
662
589
  if (!assessment.proposal || assessment.action === "continue") {
663
- await resumeActiveWorkflowFromCanonicalState(pi, ctx, snapshot, deps, naturalLanguageHandoff);
590
+ await resumeActiveWorkflowFromCanonicalState(pi, ctx, snapshot, deps);
664
591
  return;
665
592
  }
666
593
  const decision = await confirmExistingWorkflowProposal(ctx, snapshot, assessment.proposal, deps, {
@@ -678,15 +605,15 @@ export async function runCookEntry(
678
605
  return;
679
606
  }
680
607
  if (decision.action === "continue") {
681
- await resumeActiveWorkflowFromCanonicalState(pi, ctx, snapshot, deps, naturalLanguageHandoff);
608
+ await resumeActiveWorkflowFromCanonicalState(pi, ctx, snapshot, deps);
682
609
  return;
683
610
  }
684
611
  const selectedProposal = decision.proposal;
685
612
  const proposalDecision = await deps.confirmContextProposal(ctx, selectedProposal, {
686
613
  title:
687
614
  assessment.action === "refocus"
688
- ? "Start the replacement workflow from recent discussion?"
689
- : "Start the latest inferred workflow from recent discussion?",
615
+ ? "Start the replacement workflow from this startup brief?"
616
+ : "Start the latest inferred workflow from this startup brief?",
690
617
  });
691
618
  if (!proposalDecision) {
692
619
  deps.emitCommandText(ctx, buildCookCancellationMessage("Cancelled replacement workflow proposal", deps), "info");
@@ -695,7 +622,14 @@ export async function runCookEntry(
695
622
  goal = proposalDecision.goalText;
696
623
  kickoffIntent = "refocus";
697
624
  kickoffMissionAnchor = proposalDecision.missionAnchor;
698
- await refocusCompletionMission(snapshot, proposalDecision.missionAnchor, proposalDecision.goalText, proposalDecision.analysis, deps);
625
+ await refocusCompletionMission(
626
+ snapshot,
627
+ proposalDecision.missionAnchor,
628
+ proposalDecision.goalText,
629
+ proposalDecision.analysis,
630
+ deps,
631
+ buildAdvisoryStartupBrief({ proposal: selectedProposal, analysis: proposalDecision.analysis }),
632
+ );
699
633
  snapshot = (await loadCompletionSnapshot(snapshot.files.root)) ?? snapshot;
700
634
  deps.emitCommandText(ctx, `Refocused completion mission from recent discussion to: ${proposalDecision.missionAnchor}`, "info");
701
635
  }
@@ -709,7 +643,6 @@ export async function runCookEntry(
709
643
  currentEvaluationProfile(snapshot) ?? "(missing)",
710
644
  kickoffIntent,
711
645
  kickoffMissionAnchor,
712
- naturalLanguageHandoff,
713
646
  );
714
647
  const rootKey = deps.completionRootKey(snapshot, deps.getCtxCwd(ctx));
715
648
  const fingerprint = completionContinuationFingerprint(snapshot) ?? JSON.stringify({
@@ -727,10 +660,11 @@ export function registerCookCommand(pi: ExtensionAPI, deps: CompletionDriverDeps
727
660
  pi.registerCommand("cook", {
728
661
  description: deps.cookCommandSpec.description,
729
662
  handler: async (args, ctx) => {
730
- await runCookEntry(pi, ctx, deps, {
731
- origin: "command",
732
- hintText: args,
733
- });
663
+ if (args.trim().length > 0) {
664
+ deps.emitCommandText(ctx, "/cook no longer accepts inline arguments. Discuss the concrete repo change in the main chat and rerun /cook.", "info");
665
+ return;
666
+ }
667
+ await runCookEntry(pi, ctx, deps);
734
668
  },
735
669
  });
736
670
  }