@linimin/pi-letscook 0.1.68 → 0.1.70
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/.agent/README.md +2 -3
- package/.agent/verify_completion_control_plane.sh +21 -34
- package/CHANGELOG.md +16 -0
- package/README.md +23 -26
- package/agents/completion-bootstrapper.md +1 -2
- package/agents/completion-regrounder.md +10 -16
- package/extensions/completion/driver.ts +69 -136
- package/extensions/completion/index.ts +94 -81
- package/extensions/completion/policy-guards.ts +1 -1
- package/extensions/completion/prompt-surfaces.ts +63 -161
- package/extensions/completion/proposal.ts +26 -61
- package/extensions/completion/role-runner.ts +161 -57
- package/extensions/completion/state-store.ts +43 -85
- package/extensions/completion/types.ts +2 -3
- package/package.json +1 -1
- package/scripts/active-slice-contract-test.sh +21 -0
- package/scripts/canonical-evidence-artifact-test.sh +57 -65
- package/scripts/context-proposal-test.sh +1430 -310
- package/scripts/legacy-cleanup-test.sh +1 -1
- package/scripts/refocus-test.sh +459 -185
- package/scripts/release-check.sh +14 -15
- package/scripts/role-runner-contract-test.sh +4 -2
- package/scripts/smoke-test.sh +36 -78
- package/skills/completion-protocol/SKILL.md +8 -9
- package/skills/completion-protocol/references/completion.md +2 -37
- package/skills/cook-handoff-boundary/SKILL.md +19 -18
|
@@ -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
|
|
20
|
+
import { buildAdvisoryStartupBrief } from "./prompt-surfaces";
|
|
20
21
|
import type { CompletionStateSnapshot } from "./types";
|
|
21
22
|
|
|
22
23
|
type ContextProposalAnalysis = {
|
|
@@ -38,7 +39,7 @@ type ContextProposalAlternate = {
|
|
|
38
39
|
analysis: ContextProposalAnalysis;
|
|
39
40
|
goalText: string;
|
|
40
41
|
basisPreview: string;
|
|
41
|
-
source: "session" | "analyst" | "handoff_capsule"
|
|
42
|
+
source: "session" | "analyst" | "handoff_capsule";
|
|
42
43
|
};
|
|
43
44
|
|
|
44
45
|
type ContextProposal = ContextProposalAlternate & {
|
|
@@ -71,10 +72,10 @@ type ActiveWorkflowProposalAssessment = {
|
|
|
71
72
|
proposal?: ContextProposal;
|
|
72
73
|
blockedFailureMessage?: string;
|
|
73
74
|
reason:
|
|
74
|
-
| "
|
|
75
|
-
| "
|
|
76
|
-
| "
|
|
77
|
-
| "
|
|
75
|
+
| "matching_mission"
|
|
76
|
+
| "missing_explicit_handoff"
|
|
77
|
+
| "fresh_explicit_handoff"
|
|
78
|
+
| "fresh_explicit_handoff_not_startable";
|
|
78
79
|
};
|
|
79
80
|
|
|
80
81
|
type ExistingWorkflowChooserOptions = {
|
|
@@ -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,9 +123,11 @@ 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>;
|
|
130
|
+
deriveCookStartupProposal: (ctx: DriverContext, projectName: string) => Promise<CookContextProposalResult>;
|
|
129
131
|
confirmContextProposal: (
|
|
130
132
|
ctx: { hasUI: boolean; ui: any },
|
|
131
133
|
proposal: ContextProposal,
|
|
@@ -136,12 +138,7 @@ export type CompletionDriverDeps = {
|
|
|
136
138
|
scaffoldCompletionFiles: (
|
|
137
139
|
root: string,
|
|
138
140
|
missionAnchor: string,
|
|
139
|
-
options?: {
|
|
140
|
-
analysis?: ContextProposalAnalysis;
|
|
141
|
-
continuationReason?: string;
|
|
142
|
-
advisoryStartupBrief?: Record<string, unknown>;
|
|
143
|
-
approvedStartupPlan?: Record<string, unknown>;
|
|
144
|
-
},
|
|
141
|
+
options?: { analysis?: ContextProposalAnalysis; continuationReason?: string; advisoryStartupBrief?: Record<string, unknown> },
|
|
145
142
|
) => Promise<{ root: string; created: string[] }>;
|
|
146
143
|
maybeWriteActiveWorkflowRoutingSnapshot: (assessment: ActiveWorkflowProposalAssessment) => void;
|
|
147
144
|
missionAnchorsLikelyEquivalent: (left: string, right: string) => boolean;
|
|
@@ -192,6 +189,7 @@ export function completionContinuationFingerprint(snapshot: CompletionStateSnaps
|
|
|
192
189
|
const nextMandatoryRole = asString(snapshot.state?.next_mandatory_role);
|
|
193
190
|
if (!nextMandatoryRole) return undefined;
|
|
194
191
|
return JSON.stringify({
|
|
192
|
+
workflow_session_id: asString(snapshot.state?.workflow_session_id) ?? null,
|
|
195
193
|
mission_anchor: asString(snapshot.state?.mission_anchor) ?? asString(snapshot.plan?.mission_anchor) ?? null,
|
|
196
194
|
task_type: currentTaskType(snapshot) ?? null,
|
|
197
195
|
evaluation_profile: currentEvaluationProfile(snapshot) ?? null,
|
|
@@ -209,24 +207,16 @@ function noteQueuedDriverPrompt(rootKey: string, fingerprint: string): void {
|
|
|
209
207
|
const tracker = driverContinuationByRoot.get(rootKey);
|
|
210
208
|
if (tracker && tracker.fingerprint === fingerprint) {
|
|
211
209
|
tracker.attempts += 1;
|
|
212
|
-
tracker.inFlight = false;
|
|
213
210
|
tracker.warned = false;
|
|
214
211
|
return;
|
|
215
212
|
}
|
|
216
213
|
driverContinuationByRoot.set(rootKey, {
|
|
217
214
|
fingerprint,
|
|
218
215
|
attempts: 1,
|
|
219
|
-
inFlight: false,
|
|
220
216
|
warned: false,
|
|
221
217
|
});
|
|
222
218
|
}
|
|
223
219
|
|
|
224
|
-
export function markQueuedDriverPromptInFlight(rootKey: string, fingerprint: string): void {
|
|
225
|
-
const tracker = driverContinuationByRoot.get(rootKey);
|
|
226
|
-
if (!tracker || tracker.fingerprint !== fingerprint) return;
|
|
227
|
-
tracker.inFlight = true;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
220
|
function clearDriverContinuationTracker(rootKey: string): void {
|
|
231
221
|
driverContinuationByRoot.delete(rootKey);
|
|
232
222
|
}
|
|
@@ -245,7 +235,6 @@ function rememberParkedDriverContinuation(rootKey: string, fingerprint: string):
|
|
|
245
235
|
const tracker = driverContinuationByRoot.get(rootKey);
|
|
246
236
|
if (!tracker || tracker.fingerprint !== fingerprint) return;
|
|
247
237
|
tracker.warned = true;
|
|
248
|
-
tracker.inFlight = false;
|
|
249
238
|
}
|
|
250
239
|
|
|
251
240
|
function summarizeProposalForChoice(proposal: ContextProposalAlternate): string {
|
|
@@ -259,15 +248,16 @@ function summarizeProposalForChoice(proposal: ContextProposalAlternate): string
|
|
|
259
248
|
async function queueCompletionDriverPrompt(
|
|
260
249
|
pi: ExtensionAPI,
|
|
261
250
|
ctx: { cwd: string; hasUI: boolean; ui: any },
|
|
262
|
-
rootKey: string,
|
|
263
|
-
fingerprint: string,
|
|
264
251
|
prompt: string,
|
|
265
252
|
kind: "kickoff" | "resume" | "auto-resume",
|
|
266
253
|
deps: CompletionDriverDeps,
|
|
254
|
+
tracker?: { rootKey: string; fingerprint: string },
|
|
267
255
|
): Promise<boolean> {
|
|
268
256
|
const snapshotPath = kind === "auto-resume" ? deps.completionTestAutoContinuePromptPath() : deps.completionTestDriverPromptPath();
|
|
269
257
|
deps.maybeWriteTestSnapshot(snapshotPath, `${prompt}\n`);
|
|
270
|
-
|
|
258
|
+
if (kind === "auto-resume" && tracker) {
|
|
259
|
+
noteQueuedDriverPrompt(tracker.rootKey, tracker.fingerprint);
|
|
260
|
+
}
|
|
271
261
|
if (deps.shouldSkipDriverKickoffForTests()) {
|
|
272
262
|
deps.emitCommandText(ctx, `Skipped completion workflow ${kind} prompt (test mode)`, "info");
|
|
273
263
|
return false;
|
|
@@ -296,26 +286,23 @@ export async function autoContinueWorkflowIfNeeded(
|
|
|
296
286
|
}
|
|
297
287
|
if (!isWorkflowDriverActive(snapshot) || deps.hasRunningCompletionRole(rootKey)) return;
|
|
298
288
|
const tracker = driverContinuationByRoot.get(rootKey);
|
|
299
|
-
if (tracker && tracker.fingerprint === fingerprint) {
|
|
300
|
-
if (
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
`Completion workflow is parked before mandatory role dispatch: ${asString(snapshot.state?.next_mandatory_role) ?? "(unknown)"}. Rerun /cook to continue from canonical state.`,
|
|
308
|
-
"warning",
|
|
309
|
-
);
|
|
310
|
-
}
|
|
311
|
-
return;
|
|
312
|
-
}
|
|
313
|
-
} else {
|
|
314
|
-
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
|
+
);
|
|
315
297
|
}
|
|
298
|
+
return;
|
|
316
299
|
}
|
|
317
|
-
const resumePrompt = deps.completionResumePrompt(
|
|
318
|
-
|
|
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 });
|
|
319
306
|
}
|
|
320
307
|
|
|
321
308
|
async function assessActiveWorkflowProposalRouting(
|
|
@@ -331,7 +318,7 @@ async function assessActiveWorkflowProposalRouting(
|
|
|
331
318
|
action: "blocked",
|
|
332
319
|
currentMissionAnchor: currentMission,
|
|
333
320
|
blockedFailureMessage: proposalResult.blockedFailureMessage,
|
|
334
|
-
reason: "
|
|
321
|
+
reason: "fresh_explicit_handoff_not_startable",
|
|
335
322
|
};
|
|
336
323
|
deps.maybeWriteActiveWorkflowRoutingSnapshot(assessment);
|
|
337
324
|
return assessment;
|
|
@@ -341,7 +328,7 @@ async function assessActiveWorkflowProposalRouting(
|
|
|
341
328
|
const assessment: ActiveWorkflowProposalAssessment = {
|
|
342
329
|
action: "continue",
|
|
343
330
|
currentMissionAnchor: currentMission,
|
|
344
|
-
reason: "
|
|
331
|
+
reason: "missing_explicit_handoff",
|
|
345
332
|
};
|
|
346
333
|
deps.maybeWriteActiveWorkflowRoutingSnapshot(assessment);
|
|
347
334
|
return assessment;
|
|
@@ -351,7 +338,7 @@ async function assessActiveWorkflowProposalRouting(
|
|
|
351
338
|
action: "continue",
|
|
352
339
|
currentMissionAnchor: currentMission,
|
|
353
340
|
proposal,
|
|
354
|
-
reason: "
|
|
341
|
+
reason: "matching_mission",
|
|
355
342
|
};
|
|
356
343
|
deps.maybeWriteActiveWorkflowRoutingSnapshot(assessment);
|
|
357
344
|
return assessment;
|
|
@@ -360,7 +347,7 @@ async function assessActiveWorkflowProposalRouting(
|
|
|
360
347
|
action: "refocus",
|
|
361
348
|
currentMissionAnchor: currentMission,
|
|
362
349
|
proposal,
|
|
363
|
-
reason: "
|
|
350
|
+
reason: "fresh_explicit_handoff",
|
|
364
351
|
};
|
|
365
352
|
deps.maybeWriteActiveWorkflowRoutingSnapshot(assessment);
|
|
366
353
|
return assessment;
|
|
@@ -374,16 +361,13 @@ async function resumeActiveWorkflowFromCanonicalState(
|
|
|
374
361
|
): Promise<void> {
|
|
375
362
|
const mission = currentMissionAnchor(snapshot);
|
|
376
363
|
pi.setSessionName(`completion: ${mission.slice(0, 60)}`);
|
|
377
|
-
const resumePrompt = deps.completionResumePrompt(
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
current_phase: asString(snapshot.state?.current_phase) ?? null,
|
|
383
|
-
next_mandatory_role: asString(snapshot.state?.next_mandatory_role) ?? null,
|
|
384
|
-
});
|
|
364
|
+
const resumePrompt = deps.completionResumePrompt(
|
|
365
|
+
currentTaskType(snapshot) ?? "(missing)",
|
|
366
|
+
currentEvaluationProfile(snapshot) ?? "(missing)",
|
|
367
|
+
asString(snapshot.state?.workflow_session_id),
|
|
368
|
+
);
|
|
385
369
|
const resumeKind = deps.shouldTestAutoContinueOnSessionStart() && deps.completionTestAutoContinuePromptPath() ? "auto-resume" : "resume";
|
|
386
|
-
await queueCompletionDriverPrompt(pi, ctx,
|
|
370
|
+
await queueCompletionDriverPrompt(pi, ctx, resumePrompt, resumeKind, deps);
|
|
387
371
|
}
|
|
388
372
|
|
|
389
373
|
async function confirmExistingWorkflowProposal(
|
|
@@ -423,8 +407,8 @@ async function confirmExistingWorkflowProposal(
|
|
|
423
407
|
const continueChoice = "Continue current workflow\n\nKeep the current mission and treat the new goal as extra direction only.";
|
|
424
408
|
const buildRefocusChoice = (candidate: ContextProposalAlternate, variant: "primary" | "alternate") =>
|
|
425
409
|
variant === "primary"
|
|
426
|
-
? `${options.refocusChoiceLabel ?? "Start new workflow from
|
|
427
|
-
: `${options.alternateChoiceLabel ?? "Start alternate workflow from
|
|
410
|
+
? `${options.refocusChoiceLabel ?? "Start new workflow from recent discussion\n\nReview the proposed replacement in a final Start/Cancel confirmation before /cook rewrites canonical workflow state."}\n\n${summarizeProposalForChoice(candidate)}`
|
|
411
|
+
: `${options.alternateChoiceLabel ?? "Start alternate workflow from recent discussion\n\nReview this alternate replacement in a final Start/Cancel confirmation before /cook rewrites canonical workflow state."}\n\n${summarizeProposalForChoice(candidate)}`;
|
|
428
412
|
const refocusChoices = candidateProposals.map((candidate, index) => buildRefocusChoice(candidate, index === 0 ? "primary" : "alternate"));
|
|
429
413
|
const cancelChoice = `Cancel\n\nKeep the current workflow unchanged. ${deps.mainChatRerunGuidance}`;
|
|
430
414
|
deps.maybeWriteTestSnapshot(
|
|
@@ -483,7 +467,6 @@ async function refocusCompletionMission(
|
|
|
483
467
|
analysis: ContextProposalAnalysis | undefined,
|
|
484
468
|
deps: CompletionDriverDeps,
|
|
485
469
|
advisoryStartupBrief?: Record<string, unknown>,
|
|
486
|
-
approvedStartupPlan?: Record<string, unknown>,
|
|
487
470
|
): Promise<void> {
|
|
488
471
|
const requiredStopJudges = asNumber(snapshot.profile?.required_stop_judges) ?? 3;
|
|
489
472
|
const root = snapshot.files.root;
|
|
@@ -511,32 +494,11 @@ async function refocusCompletionMission(
|
|
|
511
494
|
plan_basis: "user_refocus",
|
|
512
495
|
};
|
|
513
496
|
const nextActive = defaultActiveSlice(missionAnchor, { taskType: routing.taskType, evaluationProfile: routing.evaluationProfile });
|
|
514
|
-
const nextStartupPlan =
|
|
515
|
-
approvedStartupPlan ?? {
|
|
516
|
-
artifact_type: "completion-startup-plan",
|
|
517
|
-
schema_version: 1,
|
|
518
|
-
status: "approved",
|
|
519
|
-
source: "recent_discussion",
|
|
520
|
-
captured_at: null,
|
|
521
|
-
mission_anchor: missionAnchor,
|
|
522
|
-
goal_text: rawGoal,
|
|
523
|
-
task_type: routing.taskType,
|
|
524
|
-
evaluation_profile: routing.evaluationProfile,
|
|
525
|
-
scope: [],
|
|
526
|
-
constraints: [],
|
|
527
|
-
acceptance: [],
|
|
528
|
-
risks: [],
|
|
529
|
-
notes: ["No approved startup plan summary is available for this refocused workflow."],
|
|
530
|
-
planned_surfaces: [],
|
|
531
|
-
verification_intent: [],
|
|
532
|
-
sequencing_hints: [],
|
|
533
|
-
};
|
|
534
497
|
await Promise.all([
|
|
535
498
|
fsp.writeFile(path.join(snapshot.files.agentDir, "mission.md"), buildMission(path.basename(root), missionAnchor), "utf8"),
|
|
536
499
|
writeJsonFile(snapshot.files.profilePath, nextProfile),
|
|
537
500
|
writeJsonFile(snapshot.files.statePath, nextState),
|
|
538
|
-
writeJsonFile(snapshot.files.
|
|
539
|
-
fsp.writeFile(snapshot.files.startupPlanMarkdownPath, buildApprovedStartupPlanMarkdown(nextStartupPlan as any), "utf8"),
|
|
501
|
+
writeJsonFile(snapshot.files.startupBriefPath, defaultStartupBrief(missionAnchor, { taskType: routing.taskType, evaluationProfile: routing.evaluationProfile }, advisoryStartupBrief)),
|
|
540
502
|
writeJsonFile(snapshot.files.planPath, nextPlan),
|
|
541
503
|
writeJsonFile(snapshot.files.activePath, nextActive),
|
|
542
504
|
writeJsonFile(snapshot.files.verificationEvidencePath, defaultVerificationEvidence()),
|
|
@@ -574,22 +536,16 @@ export async function runCookEntry(
|
|
|
574
536
|
return;
|
|
575
537
|
}
|
|
576
538
|
const decision = await deps.confirmContextProposal(ctx, proposal, {
|
|
577
|
-
title: "Start a completion workflow from this startup
|
|
539
|
+
title: "Start a completion workflow from this startup brief?",
|
|
578
540
|
});
|
|
579
541
|
if (!decision) {
|
|
580
|
-
deps.emitCommandText(ctx, buildCookCancellationMessage("Cancelled
|
|
542
|
+
deps.emitCommandText(ctx, buildCookCancellationMessage("Cancelled recent-discussion workflow proposal", deps), "info");
|
|
581
543
|
return;
|
|
582
544
|
}
|
|
583
545
|
goal = decision.goalText;
|
|
584
546
|
kickoffMissionAnchor = decision.missionAnchor;
|
|
585
547
|
kickoffAnalysis = decision.analysis;
|
|
586
548
|
const startupRouting = deps.finalizeContextProposalAnalysis(kickoffAnalysis, [goal ?? kickoffMissionAnchor ?? projectName]);
|
|
587
|
-
const advisoryStartupBrief = buildAdvisoryStartupBrief({ proposal, analysis: decision.analysis });
|
|
588
|
-
const approvedStartupPlan = buildApprovedStartupPlan({
|
|
589
|
-
proposal,
|
|
590
|
-
analysis: decision.analysis,
|
|
591
|
-
missionAnchor: kickoffMissionAnchor ?? projectName,
|
|
592
|
-
});
|
|
593
549
|
const created = await deps.scaffoldCompletionFiles(root, kickoffMissionAnchor ?? projectName, {
|
|
594
550
|
analysis: startupRouting,
|
|
595
551
|
continuationReason: deps.buildContextProposalContinuationReason(
|
|
@@ -597,12 +553,11 @@ export async function runCookEntry(
|
|
|
597
553
|
goal ?? kickoffMissionAnchor ?? projectName,
|
|
598
554
|
startupRouting,
|
|
599
555
|
),
|
|
600
|
-
advisoryStartupBrief,
|
|
601
|
-
approvedStartupPlan,
|
|
556
|
+
advisoryStartupBrief: buildAdvisoryStartupBrief({ proposal, analysis: decision.analysis }),
|
|
602
557
|
});
|
|
603
558
|
deps.emitCommandText(
|
|
604
559
|
ctx,
|
|
605
|
-
`Initialized completion control plane in ${created.root}${created.created.length > 0 ? ` (${created.created.length} files created)` : ""}
|
|
560
|
+
`Initialized completion control plane in ${created.root}${created.created.length > 0 ? ` (${created.created.length} files created)` : ""}`,
|
|
606
561
|
"info",
|
|
607
562
|
);
|
|
608
563
|
snapshot = await loadCompletionSnapshot(root);
|
|
@@ -626,7 +581,7 @@ export async function runCookEntry(
|
|
|
626
581
|
return;
|
|
627
582
|
}
|
|
628
583
|
const decision = await deps.confirmContextProposal(ctx, proposal, {
|
|
629
|
-
title: "The previous completion workflow is done. Start the next workflow round from this startup
|
|
584
|
+
title: "The previous completion workflow is done. Start the next workflow round from this startup brief?",
|
|
630
585
|
});
|
|
631
586
|
if (!decision) {
|
|
632
587
|
deps.emitCommandText(ctx, buildCookCancellationMessage("Cancelled next workflow round proposal", deps), "info");
|
|
@@ -635,23 +590,16 @@ export async function runCookEntry(
|
|
|
635
590
|
goal = decision.goalText;
|
|
636
591
|
kickoffIntent = "refocus";
|
|
637
592
|
kickoffMissionAnchor = decision.missionAnchor;
|
|
638
|
-
const advisoryStartupBrief = buildAdvisoryStartupBrief({ proposal, analysis: decision.analysis });
|
|
639
|
-
const approvedStartupPlan = buildApprovedStartupPlan({
|
|
640
|
-
proposal,
|
|
641
|
-
analysis: decision.analysis,
|
|
642
|
-
missionAnchor: decision.missionAnchor,
|
|
643
|
-
});
|
|
644
593
|
await refocusCompletionMission(
|
|
645
594
|
snapshot,
|
|
646
595
|
decision.missionAnchor,
|
|
647
596
|
decision.goalText,
|
|
648
597
|
decision.analysis,
|
|
649
598
|
deps,
|
|
650
|
-
|
|
651
|
-
approvedStartupPlan,
|
|
599
|
+
buildAdvisoryStartupBrief({ proposal, analysis: decision.analysis }),
|
|
652
600
|
);
|
|
653
601
|
snapshot = (await loadCompletionSnapshot(snapshot.files.root)) ?? snapshot;
|
|
654
|
-
deps.emitCommandText(ctx, `Started a new completion workflow round
|
|
602
|
+
deps.emitCommandText(ctx, `Started a new completion workflow round from explicit primary-agent handoff: ${decision.missionAnchor}`, "info");
|
|
655
603
|
} else {
|
|
656
604
|
const assessment = await assessActiveWorkflowProposalRouting(ctx, snapshot, deps);
|
|
657
605
|
if (assessment.action === "blocked") {
|
|
@@ -662,19 +610,19 @@ export async function runCookEntry(
|
|
|
662
610
|
await resumeActiveWorkflowFromCanonicalState(pi, ctx, snapshot, deps);
|
|
663
611
|
return;
|
|
664
612
|
}
|
|
665
|
-
const
|
|
613
|
+
const explicitReplacement = assessment.reason === "fresh_explicit_handoff";
|
|
666
614
|
const decision = await confirmExistingWorkflowProposal(ctx, snapshot, assessment.proposal, deps, {
|
|
667
|
-
intro:
|
|
668
|
-
? "A
|
|
615
|
+
intro: explicitReplacement
|
|
616
|
+
? "A fresh explicit primary-agent handoff proposes replacing the current workflow. Choose how /cook should proceed:"
|
|
669
617
|
: "A replacement workflow is ready. Choose how /cook should proceed:",
|
|
670
|
-
proposedMissionLabel:
|
|
671
|
-
? "Proposed mission from
|
|
618
|
+
proposedMissionLabel: explicitReplacement
|
|
619
|
+
? "Proposed mission from explicit primary-agent handoff"
|
|
672
620
|
: "Proposed mission",
|
|
673
|
-
refocusChoiceLabel:
|
|
674
|
-
? "Start new workflow from
|
|
621
|
+
refocusChoiceLabel: explicitReplacement
|
|
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."
|
|
675
623
|
: "Start new workflow\n\nReview the proposed replacement in a final Start/Cancel confirmation before /cook rewrites canonical workflow state.",
|
|
676
|
-
alternateChoiceLabel:
|
|
677
|
-
? "Start alternate workflow from
|
|
624
|
+
alternateChoiceLabel: explicitReplacement
|
|
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."
|
|
678
626
|
: undefined,
|
|
679
627
|
comparison: "strict",
|
|
680
628
|
});
|
|
@@ -688,9 +636,9 @@ export async function runCookEntry(
|
|
|
688
636
|
}
|
|
689
637
|
const selectedProposal = decision.proposal;
|
|
690
638
|
const proposalDecision = await deps.confirmContextProposal(ctx, selectedProposal, {
|
|
691
|
-
title: assessment.reason === "
|
|
692
|
-
? "Start the replacement workflow from this
|
|
693
|
-
: "Start the replacement workflow from this startup
|
|
639
|
+
title: assessment.reason === "fresh_explicit_handoff"
|
|
640
|
+
? "Start the replacement workflow from this explicit startup brief?"
|
|
641
|
+
: "Start the replacement workflow from this startup brief?",
|
|
694
642
|
});
|
|
695
643
|
if (!proposalDecision) {
|
|
696
644
|
deps.emitCommandText(ctx, buildCookCancellationMessage("Cancelled replacement workflow proposal", deps), "info");
|
|
@@ -699,27 +647,20 @@ export async function runCookEntry(
|
|
|
699
647
|
goal = proposalDecision.goalText;
|
|
700
648
|
kickoffIntent = "refocus";
|
|
701
649
|
kickoffMissionAnchor = proposalDecision.missionAnchor;
|
|
702
|
-
const advisoryStartupBrief = buildAdvisoryStartupBrief({ proposal: selectedProposal, analysis: proposalDecision.analysis });
|
|
703
|
-
const approvedStartupPlan = buildApprovedStartupPlan({
|
|
704
|
-
proposal: selectedProposal,
|
|
705
|
-
analysis: proposalDecision.analysis,
|
|
706
|
-
missionAnchor: proposalDecision.missionAnchor,
|
|
707
|
-
});
|
|
708
650
|
await refocusCompletionMission(
|
|
709
651
|
snapshot,
|
|
710
652
|
proposalDecision.missionAnchor,
|
|
711
653
|
proposalDecision.goalText,
|
|
712
654
|
proposalDecision.analysis,
|
|
713
655
|
deps,
|
|
714
|
-
|
|
715
|
-
approvedStartupPlan,
|
|
656
|
+
buildAdvisoryStartupBrief({ proposal: selectedProposal, analysis: proposalDecision.analysis }),
|
|
716
657
|
);
|
|
717
658
|
snapshot = (await loadCompletionSnapshot(snapshot.files.root)) ?? snapshot;
|
|
718
659
|
deps.emitCommandText(
|
|
719
660
|
ctx,
|
|
720
|
-
assessment.reason === "
|
|
721
|
-
? `Refocused completion mission from
|
|
722
|
-
: `Refocused completion mission
|
|
661
|
+
assessment.reason === "fresh_explicit_handoff"
|
|
662
|
+
? `Refocused completion mission from explicit primary-agent handoff to: ${proposalDecision.missionAnchor}`
|
|
663
|
+
: `Refocused completion mission to: ${proposalDecision.missionAnchor}`,
|
|
723
664
|
"info",
|
|
724
665
|
);
|
|
725
666
|
}
|
|
@@ -733,17 +674,9 @@ export async function runCookEntry(
|
|
|
733
674
|
currentEvaluationProfile(snapshot) ?? "(missing)",
|
|
734
675
|
kickoffIntent,
|
|
735
676
|
kickoffMissionAnchor,
|
|
677
|
+
asString(snapshot.state?.workflow_session_id),
|
|
736
678
|
);
|
|
737
|
-
|
|
738
|
-
const fingerprint = completionContinuationFingerprint(snapshot) ?? JSON.stringify({
|
|
739
|
-
kind: "kickoff",
|
|
740
|
-
mission_anchor: kickoffMissionAnchor,
|
|
741
|
-
goal: kickoffGoal,
|
|
742
|
-
intent: kickoffIntent,
|
|
743
|
-
task_type: currentTaskType(snapshot) ?? "(missing)",
|
|
744
|
-
evaluation_profile: currentEvaluationProfile(snapshot) ?? "(missing)",
|
|
745
|
-
});
|
|
746
|
-
await queueCompletionDriverPrompt(pi, ctx, rootKey, fingerprint, kickoffPrompt, "kickoff", deps);
|
|
679
|
+
await queueCompletionDriverPrompt(pi, ctx, kickoffPrompt, "kickoff", deps);
|
|
747
680
|
}
|
|
748
681
|
|
|
749
682
|
export function registerCookCommand(pi: ExtensionAPI, deps: CompletionDriverDeps): void {
|