@linimin/pi-letscook 0.1.67 → 0.1.69

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.
@@ -9,6 +9,7 @@ import {
9
9
  currentTaskType,
10
10
  defaultActiveSlice,
11
11
  defaultPlan,
12
+ defaultStartupBrief,
12
13
  defaultState,
13
14
  defaultVerificationEvidence,
14
15
  detectDocsSurfaces,
@@ -16,7 +17,7 @@ import {
16
17
  loadCompletionSnapshot,
17
18
  writeJsonFile,
18
19
  } from "./state-store";
19
- import { buildAdvisoryStartupBrief, buildApprovedStartupPlan, buildApprovedStartupPlanMarkdown } from "./prompt-surfaces";
20
+ import { buildAdvisoryStartupBrief } from "./prompt-surfaces";
20
21
  import type { CompletionStateSnapshot } from "./types";
21
22
 
22
23
  type ContextProposalAnalysis = {
@@ -97,7 +98,6 @@ type DriverContext = {
97
98
  type DriverContinuationTracker = {
98
99
  fingerprint: string;
99
100
  attempts: number;
100
- inFlight: boolean;
101
101
  warned: boolean;
102
102
  };
103
103
 
@@ -123,8 +123,9 @@ export type CompletionDriverDeps = {
123
123
  evaluationProfile: string,
124
124
  intent?: "auto" | "continue" | "refocus",
125
125
  missionAnchor?: string,
126
+ workflowSessionId?: string,
126
127
  ) => string;
127
- completionResumePrompt: (taskType: string, evaluationProfile: string) => string;
128
+ completionResumePrompt: (taskType: string, evaluationProfile: string, workflowSessionId?: string) => string;
128
129
  deriveCookContextProposal: (ctx: DriverContext, projectName: string) => Promise<CookContextProposalResult>;
129
130
  deriveCookStartupProposal: (ctx: DriverContext, projectName: string) => Promise<CookContextProposalResult>;
130
131
  confirmContextProposal: (
@@ -137,12 +138,7 @@ export type CompletionDriverDeps = {
137
138
  scaffoldCompletionFiles: (
138
139
  root: string,
139
140
  missionAnchor: string,
140
- options?: {
141
- analysis?: ContextProposalAnalysis;
142
- continuationReason?: string;
143
- advisoryStartupBrief?: Record<string, unknown>;
144
- approvedStartupPlan?: Record<string, unknown>;
145
- },
141
+ options?: { analysis?: ContextProposalAnalysis; continuationReason?: string; advisoryStartupBrief?: Record<string, unknown> },
146
142
  ) => Promise<{ root: string; created: string[] }>;
147
143
  maybeWriteActiveWorkflowRoutingSnapshot: (assessment: ActiveWorkflowProposalAssessment) => void;
148
144
  missionAnchorsLikelyEquivalent: (left: string, right: string) => boolean;
@@ -193,6 +189,7 @@ export function completionContinuationFingerprint(snapshot: CompletionStateSnaps
193
189
  const nextMandatoryRole = asString(snapshot.state?.next_mandatory_role);
194
190
  if (!nextMandatoryRole) return undefined;
195
191
  return JSON.stringify({
192
+ workflow_session_id: asString(snapshot.state?.workflow_session_id) ?? null,
196
193
  mission_anchor: asString(snapshot.state?.mission_anchor) ?? asString(snapshot.plan?.mission_anchor) ?? null,
197
194
  task_type: currentTaskType(snapshot) ?? null,
198
195
  evaluation_profile: currentEvaluationProfile(snapshot) ?? null,
@@ -210,24 +207,16 @@ function noteQueuedDriverPrompt(rootKey: string, fingerprint: string): void {
210
207
  const tracker = driverContinuationByRoot.get(rootKey);
211
208
  if (tracker && tracker.fingerprint === fingerprint) {
212
209
  tracker.attempts += 1;
213
- tracker.inFlight = false;
214
210
  tracker.warned = false;
215
211
  return;
216
212
  }
217
213
  driverContinuationByRoot.set(rootKey, {
218
214
  fingerprint,
219
215
  attempts: 1,
220
- inFlight: false,
221
216
  warned: false,
222
217
  });
223
218
  }
224
219
 
225
- export function markQueuedDriverPromptInFlight(rootKey: string, fingerprint: string): void {
226
- const tracker = driverContinuationByRoot.get(rootKey);
227
- if (!tracker || tracker.fingerprint !== fingerprint) return;
228
- tracker.inFlight = true;
229
- }
230
-
231
220
  function clearDriverContinuationTracker(rootKey: string): void {
232
221
  driverContinuationByRoot.delete(rootKey);
233
222
  }
@@ -246,7 +235,6 @@ function rememberParkedDriverContinuation(rootKey: string, fingerprint: string):
246
235
  const tracker = driverContinuationByRoot.get(rootKey);
247
236
  if (!tracker || tracker.fingerprint !== fingerprint) return;
248
237
  tracker.warned = true;
249
- tracker.inFlight = false;
250
238
  }
251
239
 
252
240
  function summarizeProposalForChoice(proposal: ContextProposalAlternate): string {
@@ -260,15 +248,16 @@ function summarizeProposalForChoice(proposal: ContextProposalAlternate): string
260
248
  async function queueCompletionDriverPrompt(
261
249
  pi: ExtensionAPI,
262
250
  ctx: { cwd: string; hasUI: boolean; ui: any },
263
- rootKey: string,
264
- fingerprint: string,
265
251
  prompt: string,
266
252
  kind: "kickoff" | "resume" | "auto-resume",
267
253
  deps: CompletionDriverDeps,
254
+ tracker?: { rootKey: string; fingerprint: string },
268
255
  ): Promise<boolean> {
269
256
  const snapshotPath = kind === "auto-resume" ? deps.completionTestAutoContinuePromptPath() : deps.completionTestDriverPromptPath();
270
257
  deps.maybeWriteTestSnapshot(snapshotPath, `${prompt}\n`);
271
- noteQueuedDriverPrompt(rootKey, fingerprint);
258
+ if (kind === "auto-resume" && tracker) {
259
+ noteQueuedDriverPrompt(tracker.rootKey, tracker.fingerprint);
260
+ }
272
261
  if (deps.shouldSkipDriverKickoffForTests()) {
273
262
  deps.emitCommandText(ctx, `Skipped completion workflow ${kind} prompt (test mode)`, "info");
274
263
  return false;
@@ -297,26 +286,23 @@ export async function autoContinueWorkflowIfNeeded(
297
286
  }
298
287
  if (!isWorkflowDriverActive(snapshot) || deps.hasRunningCompletionRole(rootKey)) return;
299
288
  const tracker = driverContinuationByRoot.get(rootKey);
300
- if (tracker && tracker.fingerprint === fingerprint) {
301
- if (tracker.inFlight) {
302
- tracker.inFlight = false;
303
- if (tracker.attempts >= DRIVER_AUTO_CONTINUE_MAX_ATTEMPTS) {
304
- if (!isDriverContinuationStateParked(rootKey, fingerprint)) {
305
- rememberParkedDriverContinuation(rootKey, fingerprint);
306
- deps.emitCommandText(
307
- ctx,
308
- `Completion workflow is parked before mandatory role dispatch: ${asString(snapshot.state?.next_mandatory_role) ?? "(unknown)"}. Rerun /cook to continue from canonical state.`,
309
- "warning",
310
- );
311
- }
312
- return;
313
- }
314
- } else {
315
- return;
289
+ if (tracker && tracker.fingerprint === fingerprint && tracker.attempts >= DRIVER_AUTO_CONTINUE_MAX_ATTEMPTS) {
290
+ if (!isDriverContinuationStateParked(rootKey, fingerprint)) {
291
+ rememberParkedDriverContinuation(rootKey, fingerprint);
292
+ deps.emitCommandText(
293
+ ctx,
294
+ `Completion workflow is parked before mandatory role dispatch: ${asString(snapshot.state?.next_mandatory_role) ?? "(unknown)"}. Rerun /cook to continue from canonical state.`,
295
+ "warning",
296
+ );
316
297
  }
298
+ return;
317
299
  }
318
- const resumePrompt = deps.completionResumePrompt(currentTaskType(snapshot) ?? "(missing)", currentEvaluationProfile(snapshot) ?? "(missing)");
319
- await queueCompletionDriverPrompt(pi, ctx, rootKey, fingerprint, resumePrompt, "auto-resume", deps);
300
+ const resumePrompt = deps.completionResumePrompt(
301
+ currentTaskType(snapshot) ?? "(missing)",
302
+ currentEvaluationProfile(snapshot) ?? "(missing)",
303
+ asString(snapshot.state?.workflow_session_id),
304
+ );
305
+ await queueCompletionDriverPrompt(pi, ctx, resumePrompt, "auto-resume", deps, { rootKey, fingerprint });
320
306
  }
321
307
 
322
308
  async function assessActiveWorkflowProposalRouting(
@@ -375,16 +361,13 @@ async function resumeActiveWorkflowFromCanonicalState(
375
361
  ): Promise<void> {
376
362
  const mission = currentMissionAnchor(snapshot);
377
363
  pi.setSessionName(`completion: ${mission.slice(0, 60)}`);
378
- const resumePrompt = deps.completionResumePrompt(currentTaskType(snapshot) ?? "(missing)", currentEvaluationProfile(snapshot) ?? "(missing)");
379
- const rootKey = deps.completionRootKey(snapshot, deps.getCtxCwd(ctx));
380
- const fingerprint = completionContinuationFingerprint(snapshot) ?? JSON.stringify({
381
- kind: "resume",
382
- mission_anchor: mission,
383
- current_phase: asString(snapshot.state?.current_phase) ?? null,
384
- next_mandatory_role: asString(snapshot.state?.next_mandatory_role) ?? null,
385
- });
364
+ const resumePrompt = deps.completionResumePrompt(
365
+ currentTaskType(snapshot) ?? "(missing)",
366
+ currentEvaluationProfile(snapshot) ?? "(missing)",
367
+ asString(snapshot.state?.workflow_session_id),
368
+ );
386
369
  const resumeKind = deps.shouldTestAutoContinueOnSessionStart() && deps.completionTestAutoContinuePromptPath() ? "auto-resume" : "resume";
387
- await queueCompletionDriverPrompt(pi, ctx, rootKey, fingerprint, resumePrompt, resumeKind, deps);
370
+ await queueCompletionDriverPrompt(pi, ctx, resumePrompt, resumeKind, deps);
388
371
  }
389
372
 
390
373
  async function confirmExistingWorkflowProposal(
@@ -484,7 +467,6 @@ async function refocusCompletionMission(
484
467
  analysis: ContextProposalAnalysis | undefined,
485
468
  deps: CompletionDriverDeps,
486
469
  advisoryStartupBrief?: Record<string, unknown>,
487
- approvedStartupPlan?: Record<string, unknown>,
488
470
  ): Promise<void> {
489
471
  const requiredStopJudges = asNumber(snapshot.profile?.required_stop_judges) ?? 3;
490
472
  const root = snapshot.files.root;
@@ -512,32 +494,11 @@ async function refocusCompletionMission(
512
494
  plan_basis: "user_refocus",
513
495
  };
514
496
  const nextActive = defaultActiveSlice(missionAnchor, { taskType: routing.taskType, evaluationProfile: routing.evaluationProfile });
515
- const nextStartupPlan =
516
- approvedStartupPlan ?? {
517
- artifact_type: "completion-startup-plan",
518
- schema_version: 1,
519
- status: "approved",
520
- source: "recent_discussion",
521
- captured_at: null,
522
- mission_anchor: missionAnchor,
523
- goal_text: rawGoal,
524
- task_type: routing.taskType,
525
- evaluation_profile: routing.evaluationProfile,
526
- scope: [],
527
- constraints: [],
528
- acceptance: [],
529
- risks: [],
530
- notes: ["No approved startup plan summary is available for this refocused workflow."],
531
- planned_surfaces: [],
532
- verification_intent: [],
533
- sequencing_hints: [],
534
- };
535
497
  await Promise.all([
536
498
  fsp.writeFile(path.join(snapshot.files.agentDir, "mission.md"), buildMission(path.basename(root), missionAnchor), "utf8"),
537
499
  writeJsonFile(snapshot.files.profilePath, nextProfile),
538
500
  writeJsonFile(snapshot.files.statePath, nextState),
539
- writeJsonFile(snapshot.files.startupPlanPath, nextStartupPlan),
540
- fsp.writeFile(snapshot.files.startupPlanMarkdownPath, buildApprovedStartupPlanMarkdown(nextStartupPlan as any), "utf8"),
501
+ writeJsonFile(snapshot.files.startupBriefPath, defaultStartupBrief(missionAnchor, { taskType: routing.taskType, evaluationProfile: routing.evaluationProfile }, advisoryStartupBrief)),
541
502
  writeJsonFile(snapshot.files.planPath, nextPlan),
542
503
  writeJsonFile(snapshot.files.activePath, nextActive),
543
504
  writeJsonFile(snapshot.files.verificationEvidencePath, defaultVerificationEvidence()),
@@ -575,7 +536,7 @@ export async function runCookEntry(
575
536
  return;
576
537
  }
577
538
  const decision = await deps.confirmContextProposal(ctx, proposal, {
578
- title: "Start a completion workflow from this startup plan?",
539
+ title: "Start a completion workflow from this startup brief?",
579
540
  });
580
541
  if (!decision) {
581
542
  deps.emitCommandText(ctx, buildCookCancellationMessage("Cancelled recent-discussion workflow proposal", deps), "info");
@@ -585,12 +546,6 @@ export async function runCookEntry(
585
546
  kickoffMissionAnchor = decision.missionAnchor;
586
547
  kickoffAnalysis = decision.analysis;
587
548
  const startupRouting = deps.finalizeContextProposalAnalysis(kickoffAnalysis, [goal ?? kickoffMissionAnchor ?? projectName]);
588
- const advisoryStartupBrief = buildAdvisoryStartupBrief({ proposal, analysis: decision.analysis });
589
- const approvedStartupPlan = buildApprovedStartupPlan({
590
- proposal,
591
- analysis: decision.analysis,
592
- missionAnchor: kickoffMissionAnchor ?? projectName,
593
- });
594
549
  const created = await deps.scaffoldCompletionFiles(root, kickoffMissionAnchor ?? projectName, {
595
550
  analysis: startupRouting,
596
551
  continuationReason: deps.buildContextProposalContinuationReason(
@@ -598,12 +553,11 @@ export async function runCookEntry(
598
553
  goal ?? kickoffMissionAnchor ?? projectName,
599
554
  startupRouting,
600
555
  ),
601
- advisoryStartupBrief,
602
- approvedStartupPlan,
556
+ advisoryStartupBrief: buildAdvisoryStartupBrief({ proposal, analysis: decision.analysis }),
603
557
  });
604
558
  deps.emitCommandText(
605
559
  ctx,
606
- `Initialized completion control plane in ${created.root}${created.created.length > 0 ? ` (${created.created.length} files created)` : ""} and recorded the approved startup plan under .agent/startup-plan.json`,
560
+ `Initialized completion control plane in ${created.root}${created.created.length > 0 ? ` (${created.created.length} files created)` : ""}`,
607
561
  "info",
608
562
  );
609
563
  snapshot = await loadCompletionSnapshot(root);
@@ -627,7 +581,7 @@ export async function runCookEntry(
627
581
  return;
628
582
  }
629
583
  const decision = await deps.confirmContextProposal(ctx, proposal, {
630
- title: "The previous completion workflow is done. Start the next workflow round from this startup plan?",
584
+ title: "The previous completion workflow is done. Start the next workflow round from this startup brief?",
631
585
  });
632
586
  if (!decision) {
633
587
  deps.emitCommandText(ctx, buildCookCancellationMessage("Cancelled next workflow round proposal", deps), "info");
@@ -636,23 +590,16 @@ export async function runCookEntry(
636
590
  goal = decision.goalText;
637
591
  kickoffIntent = "refocus";
638
592
  kickoffMissionAnchor = decision.missionAnchor;
639
- const advisoryStartupBrief = buildAdvisoryStartupBrief({ proposal, analysis: decision.analysis });
640
- const approvedStartupPlan = buildApprovedStartupPlan({
641
- proposal,
642
- analysis: decision.analysis,
643
- missionAnchor: decision.missionAnchor,
644
- });
645
593
  await refocusCompletionMission(
646
594
  snapshot,
647
595
  decision.missionAnchor,
648
596
  decision.goalText,
649
597
  decision.analysis,
650
598
  deps,
651
- advisoryStartupBrief,
652
- approvedStartupPlan,
599
+ buildAdvisoryStartupBrief({ proposal, analysis: decision.analysis }),
653
600
  );
654
601
  snapshot = (await loadCompletionSnapshot(snapshot.files.root)) ?? snapshot;
655
- deps.emitCommandText(ctx, `Started a new completion workflow round and recorded the approved startup plan: ${decision.missionAnchor}`, "info");
602
+ deps.emitCommandText(ctx, `Started a new completion workflow round from explicit primary-agent handoff: ${decision.missionAnchor}`, "info");
656
603
  } else {
657
604
  const assessment = await assessActiveWorkflowProposalRouting(ctx, snapshot, deps);
658
605
  if (assessment.action === "blocked") {
@@ -666,16 +613,16 @@ export async function runCookEntry(
666
613
  const explicitReplacement = assessment.reason === "fresh_explicit_handoff";
667
614
  const decision = await confirmExistingWorkflowProposal(ctx, snapshot, assessment.proposal, deps, {
668
615
  intro: explicitReplacement
669
- ? "A fresh explicit primary-agent startup plan proposes replacing the current workflow. Choose how /cook should proceed:"
616
+ ? "A fresh explicit primary-agent handoff proposes replacing the current workflow. Choose how /cook should proceed:"
670
617
  : "A replacement workflow is ready. Choose how /cook should proceed:",
671
618
  proposedMissionLabel: explicitReplacement
672
- ? "Proposed mission from explicit primary-agent startup plan"
619
+ ? "Proposed mission from explicit primary-agent handoff"
673
620
  : "Proposed mission",
674
621
  refocusChoiceLabel: explicitReplacement
675
- ? "Start new workflow from explicit primary-agent startup plan\n\nReview the proposed replacement in a final Start/Cancel confirmation before /cook rewrites canonical workflow state."
622
+ ? "Start new workflow from explicit primary-agent handoff\n\nReview the proposed replacement in a final Start/Cancel confirmation before /cook rewrites canonical workflow state."
676
623
  : "Start new workflow\n\nReview the proposed replacement in a final Start/Cancel confirmation before /cook rewrites canonical workflow state.",
677
624
  alternateChoiceLabel: explicitReplacement
678
- ? "Start alternate workflow from explicit primary-agent startup plan\n\nReview this alternate replacement in a final Start/Cancel confirmation before /cook rewrites canonical workflow state."
625
+ ? "Start alternate workflow from explicit primary-agent handoff\n\nReview this alternate replacement in a final Start/Cancel confirmation before /cook rewrites canonical workflow state."
679
626
  : undefined,
680
627
  comparison: "strict",
681
628
  });
@@ -690,8 +637,8 @@ export async function runCookEntry(
690
637
  const selectedProposal = decision.proposal;
691
638
  const proposalDecision = await deps.confirmContextProposal(ctx, selectedProposal, {
692
639
  title: assessment.reason === "fresh_explicit_handoff"
693
- ? "Start the replacement workflow from this explicit startup plan?"
694
- : "Start the replacement workflow from this startup plan?",
640
+ ? "Start the replacement workflow from this explicit startup brief?"
641
+ : "Start the replacement workflow from this startup brief?",
695
642
  });
696
643
  if (!proposalDecision) {
697
644
  deps.emitCommandText(ctx, buildCookCancellationMessage("Cancelled replacement workflow proposal", deps), "info");
@@ -700,27 +647,20 @@ export async function runCookEntry(
700
647
  goal = proposalDecision.goalText;
701
648
  kickoffIntent = "refocus";
702
649
  kickoffMissionAnchor = proposalDecision.missionAnchor;
703
- const advisoryStartupBrief = buildAdvisoryStartupBrief({ proposal: selectedProposal, analysis: proposalDecision.analysis });
704
- const approvedStartupPlan = buildApprovedStartupPlan({
705
- proposal: selectedProposal,
706
- analysis: proposalDecision.analysis,
707
- missionAnchor: proposalDecision.missionAnchor,
708
- });
709
650
  await refocusCompletionMission(
710
651
  snapshot,
711
652
  proposalDecision.missionAnchor,
712
653
  proposalDecision.goalText,
713
654
  proposalDecision.analysis,
714
655
  deps,
715
- advisoryStartupBrief,
716
- approvedStartupPlan,
656
+ buildAdvisoryStartupBrief({ proposal: selectedProposal, analysis: proposalDecision.analysis }),
717
657
  );
718
658
  snapshot = (await loadCompletionSnapshot(snapshot.files.root)) ?? snapshot;
719
659
  deps.emitCommandText(
720
660
  ctx,
721
661
  assessment.reason === "fresh_explicit_handoff"
722
- ? `Refocused completion mission from explicit primary-agent startup plan and rewrote the approved startup plan to: ${proposalDecision.missionAnchor}`
723
- : `Refocused completion mission and rewrote the approved startup plan to: ${proposalDecision.missionAnchor}`,
662
+ ? `Refocused completion mission from explicit primary-agent handoff to: ${proposalDecision.missionAnchor}`
663
+ : `Refocused completion mission to: ${proposalDecision.missionAnchor}`,
724
664
  "info",
725
665
  );
726
666
  }
@@ -734,17 +674,9 @@ export async function runCookEntry(
734
674
  currentEvaluationProfile(snapshot) ?? "(missing)",
735
675
  kickoffIntent,
736
676
  kickoffMissionAnchor,
677
+ asString(snapshot.state?.workflow_session_id),
737
678
  );
738
- const rootKey = deps.completionRootKey(snapshot, deps.getCtxCwd(ctx));
739
- const fingerprint = completionContinuationFingerprint(snapshot) ?? JSON.stringify({
740
- kind: "kickoff",
741
- mission_anchor: kickoffMissionAnchor,
742
- goal: kickoffGoal,
743
- intent: kickoffIntent,
744
- task_type: currentTaskType(snapshot) ?? "(missing)",
745
- evaluation_profile: currentEvaluationProfile(snapshot) ?? "(missing)",
746
- });
747
- await queueCompletionDriverPrompt(pi, ctx, rootKey, fingerprint, kickoffPrompt, "kickoff", deps);
679
+ await queueCompletionDriverPrompt(pi, ctx, kickoffPrompt, "kickoff", deps);
748
680
  }
749
681
 
750
682
  export function registerCookCommand(pi: ExtensionAPI, deps: CompletionDriverDeps): void {