@kenkaiiii/ggcoder 4.3.212 → 4.3.213
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/README.md +5 -8
- package/dist/cli.d.ts +3 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +112 -61
- package/dist/cli.js.map +1 -1
- package/dist/core/continue-replay-inventory.test.d.ts +2 -0
- package/dist/core/continue-replay-inventory.test.d.ts.map +1 -0
- package/dist/core/continue-replay-inventory.test.js +42 -0
- package/dist/core/continue-replay-inventory.test.js.map +1 -0
- package/dist/core/goal-controller.d.ts +2 -0
- package/dist/core/goal-controller.d.ts.map +1 -1
- package/dist/core/goal-controller.js +283 -24
- package/dist/core/goal-controller.js.map +1 -1
- package/dist/core/goal-controller.test.js +413 -16
- package/dist/core/goal-controller.test.js.map +1 -1
- package/dist/core/goal-lifecycle-smoke.test.js +48 -6
- package/dist/core/goal-lifecycle-smoke.test.js.map +1 -1
- package/dist/core/goal-prerequisites.d.ts +5 -0
- package/dist/core/goal-prerequisites.d.ts.map +1 -1
- package/dist/core/goal-prerequisites.js +37 -0
- package/dist/core/goal-prerequisites.js.map +1 -1
- package/dist/core/goal-prerequisites.test.js +29 -1
- package/dist/core/goal-prerequisites.test.js.map +1 -1
- package/dist/core/goal-references.d.ts +14 -0
- package/dist/core/goal-references.d.ts.map +1 -0
- package/dist/core/goal-references.js +153 -0
- package/dist/core/goal-references.js.map +1 -0
- package/dist/core/goal-references.test.d.ts +2 -0
- package/dist/core/goal-references.test.d.ts.map +1 -0
- package/dist/core/goal-references.test.js +77 -0
- package/dist/core/goal-references.test.js.map +1 -0
- package/dist/core/goal-store.d.ts +25 -0
- package/dist/core/goal-store.d.ts.map +1 -1
- package/dist/core/goal-store.js +150 -36
- package/dist/core/goal-store.js.map +1 -1
- package/dist/core/goal-store.test.js +19 -2
- package/dist/core/goal-store.test.js.map +1 -1
- package/dist/core/goal-verifier.d.ts.map +1 -1
- package/dist/core/goal-verifier.js +4 -1
- package/dist/core/goal-verifier.js.map +1 -1
- package/dist/core/goal-verifier.test.js +43 -0
- package/dist/core/goal-verifier.test.js.map +1 -1
- package/dist/core/goal-worker.d.ts +2 -0
- package/dist/core/goal-worker.d.ts.map +1 -1
- package/dist/core/goal-worker.js +33 -9
- package/dist/core/goal-worker.js.map +1 -1
- package/dist/core/goal-worker.test.js +49 -1
- package/dist/core/goal-worker.test.js.map +1 -1
- package/dist/core/prompt-commands.d.ts.map +1 -1
- package/dist/core/prompt-commands.js +28 -846
- package/dist/core/prompt-commands.js.map +1 -1
- package/dist/core/prompt-commands.test.js +40 -78
- package/dist/core/prompt-commands.test.js.map +1 -1
- package/dist/core/runtime-mode.d.ts +14 -0
- package/dist/core/runtime-mode.d.ts.map +1 -0
- package/dist/core/runtime-mode.js +10 -0
- package/dist/core/runtime-mode.js.map +1 -0
- package/dist/core/session-restore-display.test.d.ts +2 -0
- package/dist/core/session-restore-display.test.d.ts.map +1 -0
- package/dist/core/session-restore-display.test.js +100 -0
- package/dist/core/session-restore-display.test.js.map +1 -0
- package/dist/core/verify-commands.js +4 -4
- package/dist/core/verify-commands.js.map +1 -1
- package/dist/system-prompt.d.ts +2 -1
- package/dist/system-prompt.d.ts.map +1 -1
- package/dist/system-prompt.js +51 -37
- package/dist/system-prompt.js.map +1 -1
- package/dist/system-prompt.test.js +147 -40
- package/dist/system-prompt.test.js.map +1 -1
- package/dist/tools/bash.d.ts +3 -2
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +11 -4
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/edit.d.ts +5 -3
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +14 -4
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/edit.test.js +0 -10
- package/dist/tools/edit.test.js.map +1 -1
- package/dist/tools/goal-mode.test.d.ts +2 -0
- package/dist/tools/goal-mode.test.d.ts.map +1 -0
- package/dist/tools/goal-mode.test.js +121 -0
- package/dist/tools/goal-mode.test.js.map +1 -0
- package/dist/tools/goals.d.ts +15 -3
- package/dist/tools/goals.d.ts.map +1 -1
- package/dist/tools/goals.js +336 -26
- package/dist/tools/goals.js.map +1 -1
- package/dist/tools/goals.test.js +346 -6
- package/dist/tools/goals.test.js.map +1 -1
- package/dist/tools/index.d.ts +7 -10
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +6 -19
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/plan-mode.test.js +34 -224
- package/dist/tools/plan-mode.test.js.map +1 -1
- package/dist/tools/prompt-hints.d.ts.map +1 -1
- package/dist/tools/prompt-hints.js +2 -6
- package/dist/tools/prompt-hints.js.map +1 -1
- package/dist/tools/subagent.d.ts +3 -2
- package/dist/tools/subagent.d.ts.map +1 -1
- package/dist/tools/subagent.js +4 -9
- package/dist/tools/subagent.js.map +1 -1
- package/dist/tools/write.d.ts +5 -3
- package/dist/tools/write.d.ts.map +1 -1
- package/dist/tools/write.js +14 -13
- package/dist/tools/write.js.map +1 -1
- package/dist/tools/write.test.js +0 -16
- package/dist/tools/write.test.js.map +1 -1
- package/dist/ui/App.d.ts +144 -28
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +1143 -862
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/activity-phrases.d.ts.map +1 -1
- package/dist/ui/activity-phrases.js +0 -2
- package/dist/ui/activity-phrases.js.map +1 -1
- package/dist/ui/app-state-persistence.test.js +173 -5
- package/dist/ui/app-state-persistence.test.js.map +1 -1
- package/dist/ui/chat-layout-pinning.test.d.ts +2 -0
- package/dist/ui/chat-layout-pinning.test.d.ts.map +1 -0
- package/dist/ui/chat-layout-pinning.test.js +407 -0
- package/dist/ui/chat-layout-pinning.test.js.map +1 -0
- package/dist/ui/components/ActivityIndicator.d.ts +1 -2
- package/dist/ui/components/ActivityIndicator.d.ts.map +1 -1
- package/dist/ui/components/ActivityIndicator.js +63 -94
- package/dist/ui/components/ActivityIndicator.js.map +1 -1
- package/dist/ui/components/AssistantMessage.d.ts +6 -2
- package/dist/ui/components/AssistantMessage.d.ts.map +1 -1
- package/dist/ui/components/AssistantMessage.js +9 -4
- package/dist/ui/components/AssistantMessage.js.map +1 -1
- package/dist/ui/components/AssistantMessage.test.d.ts +2 -0
- package/dist/ui/components/AssistantMessage.test.d.ts.map +1 -0
- package/dist/ui/components/AssistantMessage.test.js +369 -0
- package/dist/ui/components/AssistantMessage.test.js.map +1 -0
- package/dist/ui/components/BackgroundTasksBar.d.ts +1 -3
- package/dist/ui/components/BackgroundTasksBar.d.ts.map +1 -1
- package/dist/ui/components/BackgroundTasksBar.js +2 -4
- package/dist/ui/components/BackgroundTasksBar.js.map +1 -1
- package/dist/ui/components/Banner.d.ts +1 -3
- package/dist/ui/components/Banner.d.ts.map +1 -1
- package/dist/ui/components/Banner.js +7 -3
- package/dist/ui/components/Banner.js.map +1 -1
- package/dist/ui/components/Footer.d.ts +26 -4
- package/dist/ui/components/Footer.d.ts.map +1 -1
- package/dist/ui/components/Footer.js +73 -21
- package/dist/ui/components/Footer.js.map +1 -1
- package/dist/ui/components/GoalOverlay.d.ts +28 -20
- package/dist/ui/components/GoalOverlay.d.ts.map +1 -1
- package/dist/ui/components/GoalOverlay.js +283 -253
- package/dist/ui/components/GoalOverlay.js.map +1 -1
- package/dist/ui/components/InputArea.d.ts +2 -6
- package/dist/ui/components/InputArea.d.ts.map +1 -1
- package/dist/ui/components/InputArea.js +40 -32
- package/dist/ui/components/InputArea.js.map +1 -1
- package/dist/ui/components/InputArea.test.js +11 -1
- package/dist/ui/components/InputArea.test.js.map +1 -1
- package/dist/ui/components/Markdown.d.ts +11 -11
- package/dist/ui/components/Markdown.d.ts.map +1 -1
- package/dist/ui/components/Markdown.js +25 -198
- package/dist/ui/components/Markdown.js.map +1 -1
- package/dist/ui/components/PlanOverlay.d.ts.map +1 -1
- package/dist/ui/components/PlanOverlay.js +1 -1
- package/dist/ui/components/PlanOverlay.js.map +1 -1
- package/dist/ui/components/ServerToolExecution.d.ts.map +1 -1
- package/dist/ui/components/ServerToolExecution.js +3 -2
- package/dist/ui/components/ServerToolExecution.js.map +1 -1
- package/dist/ui/components/SlashCommandMenu.d.ts +4 -3
- package/dist/ui/components/SlashCommandMenu.d.ts.map +1 -1
- package/dist/ui/components/SlashCommandMenu.js +38 -26
- package/dist/ui/components/SlashCommandMenu.js.map +1 -1
- package/dist/ui/components/StreamingArea.d.ts +11 -2
- package/dist/ui/components/StreamingArea.d.ts.map +1 -1
- package/dist/ui/components/StreamingArea.js +20 -23
- package/dist/ui/components/StreamingArea.js.map +1 -1
- package/dist/ui/components/StreamingArea.test.d.ts +2 -0
- package/dist/ui/components/StreamingArea.test.d.ts.map +1 -0
- package/dist/ui/components/StreamingArea.test.js +18 -0
- package/dist/ui/components/StreamingArea.test.js.map +1 -0
- package/dist/ui/components/ToolExecution.d.ts.map +1 -1
- package/dist/ui/components/ToolExecution.js +11 -27
- package/dist/ui/components/ToolExecution.js.map +1 -1
- package/dist/ui/components/ToolGroupExecution.d.ts.map +1 -1
- package/dist/ui/components/ToolGroupExecution.js +9 -124
- package/dist/ui/components/ToolGroupExecution.js.map +1 -1
- package/dist/ui/components/UserMessage.d.ts.map +1 -1
- package/dist/ui/components/UserMessage.js +15 -10
- package/dist/ui/components/UserMessage.js.map +1 -1
- package/dist/ui/components/UserMessage.test.d.ts +2 -0
- package/dist/ui/components/UserMessage.test.d.ts.map +1 -0
- package/dist/ui/components/UserMessage.test.js +39 -0
- package/dist/ui/components/UserMessage.test.js.map +1 -0
- package/dist/ui/footer-status-layout.test.js +21 -7
- package/dist/ui/footer-status-layout.test.js.map +1 -1
- package/dist/ui/goal-events.d.ts +8 -0
- package/dist/ui/goal-events.d.ts.map +1 -1
- package/dist/ui/goal-events.js +28 -8
- package/dist/ui/goal-events.js.map +1 -1
- package/dist/ui/goal-events.test.js +40 -2
- package/dist/ui/goal-events.test.js.map +1 -1
- package/dist/ui/goal-lifecycle-orchestration.test.js +127 -34
- package/dist/ui/goal-lifecycle-orchestration.test.js.map +1 -1
- package/dist/ui/goal-overlay.test.js +121 -43
- package/dist/ui/goal-overlay.test.js.map +1 -1
- package/dist/ui/goal-summary.d.ts +14 -0
- package/dist/ui/goal-summary.d.ts.map +1 -0
- package/dist/ui/goal-summary.js +194 -0
- package/dist/ui/goal-summary.js.map +1 -0
- package/dist/ui/hooks/useAgentLoop.d.ts +8 -2
- package/dist/ui/hooks/useAgentLoop.d.ts.map +1 -1
- package/dist/ui/hooks/useAgentLoop.js +20 -9
- package/dist/ui/hooks/useAgentLoop.js.map +1 -1
- package/dist/ui/hooks/useAgentLoop.test.d.ts +2 -0
- package/dist/ui/hooks/useAgentLoop.test.d.ts.map +1 -0
- package/dist/ui/hooks/useAgentLoop.test.js +8 -0
- package/dist/ui/hooks/useAgentLoop.test.js.map +1 -0
- package/dist/ui/hooks/useTerminalSize.d.ts +5 -9
- package/dist/ui/hooks/useTerminalSize.d.ts.map +1 -1
- package/dist/ui/hooks/useTerminalSize.js +9 -14
- package/dist/ui/hooks/useTerminalSize.js.map +1 -1
- package/dist/ui/live-item-flush.d.ts +2 -2
- package/dist/ui/live-item-flush.d.ts.map +1 -1
- package/dist/ui/live-item-flush.js +8 -4
- package/dist/ui/live-item-flush.js.map +1 -1
- package/dist/ui/long-prompt-regression-harness.test.d.ts +2 -0
- package/dist/ui/long-prompt-regression-harness.test.d.ts.map +1 -0
- package/dist/ui/long-prompt-regression-harness.test.js +195 -0
- package/dist/ui/long-prompt-regression-harness.test.js.map +1 -0
- package/dist/ui/plan-overlay.test.js +7 -29
- package/dist/ui/plan-overlay.test.js.map +1 -1
- package/dist/ui/queued-message.test.d.ts.map +1 -1
- package/dist/ui/queued-message.test.js +76 -14
- package/dist/ui/queued-message.test.js.map +1 -1
- package/dist/ui/render.d.ts +21 -24
- package/dist/ui/render.d.ts.map +1 -1
- package/dist/ui/render.js +46 -28
- package/dist/ui/render.js.map +1 -1
- package/dist/ui/render.test.d.ts +2 -0
- package/dist/ui/render.test.d.ts.map +1 -0
- package/dist/ui/render.test.js +16 -0
- package/dist/ui/render.test.js.map +1 -0
- package/dist/ui/scroll-stabilization.test.js +1 -1
- package/dist/ui/scroll-stabilization.test.js.map +1 -1
- package/dist/ui/slash-command-images.test.js +79 -4
- package/dist/ui/slash-command-images.test.js.map +1 -1
- package/dist/ui/terminal-history.d.ts +26 -0
- package/dist/ui/terminal-history.d.ts.map +1 -0
- package/dist/ui/terminal-history.js +910 -0
- package/dist/ui/terminal-history.js.map +1 -0
- package/dist/ui/terminal-history.test.d.ts +2 -0
- package/dist/ui/terminal-history.test.d.ts.map +1 -0
- package/dist/ui/terminal-history.test.js +314 -0
- package/dist/ui/terminal-history.test.js.map +1 -0
- package/dist/ui/tool-group-summary.d.ts +16 -0
- package/dist/ui/tool-group-summary.d.ts.map +1 -0
- package/dist/ui/tool-group-summary.js +123 -0
- package/dist/ui/tool-group-summary.js.map +1 -0
- package/dist/ui/tui-history-parity.test.d.ts +2 -0
- package/dist/ui/tui-history-parity.test.d.ts.map +1 -0
- package/dist/ui/tui-history-parity.test.js +243 -0
- package/dist/ui/tui-history-parity.test.js.map +1 -0
- package/dist/ui/utils/assistant-stream-split.d.ts +6 -0
- package/dist/ui/utils/assistant-stream-split.d.ts.map +1 -0
- package/dist/ui/utils/assistant-stream-split.js +37 -0
- package/dist/ui/utils/assistant-stream-split.js.map +1 -0
- package/dist/ui/utils/assistant-stream-split.test.d.ts +2 -0
- package/dist/ui/utils/assistant-stream-split.test.d.ts.map +1 -0
- package/dist/ui/utils/assistant-stream-split.test.js +58 -0
- package/dist/ui/utils/assistant-stream-split.test.js.map +1 -0
- package/dist/ui/utils/latex-to-unicode.d.ts +22 -0
- package/dist/ui/utils/latex-to-unicode.d.ts.map +1 -0
- package/dist/ui/utils/latex-to-unicode.js +538 -0
- package/dist/ui/utils/latex-to-unicode.js.map +1 -0
- package/dist/ui/utils/markdown-renderer.d.ts +20 -0
- package/dist/ui/utils/markdown-renderer.d.ts.map +1 -0
- package/dist/ui/utils/markdown-renderer.js +327 -0
- package/dist/ui/utils/markdown-renderer.js.map +1 -0
- package/dist/ui/utils/markdown-table.d.ts +9 -0
- package/dist/ui/utils/markdown-table.d.ts.map +1 -0
- package/dist/ui/utils/markdown-table.js +95 -0
- package/dist/ui/utils/markdown-table.js.map +1 -0
- package/dist/ui/utils/text-utils.d.ts +8 -0
- package/dist/ui/utils/text-utils.d.ts.map +1 -0
- package/dist/ui/utils/text-utils.js +16 -0
- package/dist/ui/utils/text-utils.js.map +1 -0
- package/dist/ui/utils/token-to-ansi.js +19 -9
- package/dist/ui/utils/token-to-ansi.js.map +1 -1
- package/dist/ui/utils/user-message-display.d.ts +7 -0
- package/dist/ui/utils/user-message-display.d.ts.map +1 -0
- package/dist/ui/utils/user-message-display.js +26 -0
- package/dist/ui/utils/user-message-display.js.map +1 -0
- package/dist/utils/format.js +0 -9
- package/dist/utils/format.js.map +1 -1
- package/package.json +9 -5
- package/dist/tools/enter-plan.d.ts +0 -8
- package/dist/tools/enter-plan.d.ts.map +0 -1
- package/dist/tools/enter-plan.js +0 -30
- package/dist/tools/enter-plan.js.map +0 -1
- package/dist/tools/exit-plan.d.ts +0 -8
- package/dist/tools/exit-plan.d.ts.map +0 -1
- package/dist/tools/exit-plan.js +0 -36
- package/dist/tools/exit-plan.js.map +0 -1
- package/dist/tools/tasks.d.ts +0 -16
- package/dist/tools/tasks.d.ts.map +0 -1
- package/dist/tools/tasks.js +0 -133
- package/dist/tools/tasks.js.map +0 -1
- package/dist/ui/components/EyesOverlay.d.ts +0 -10
- package/dist/ui/components/EyesOverlay.d.ts.map +0 -1
- package/dist/ui/components/EyesOverlay.js +0 -220
- package/dist/ui/components/EyesOverlay.js.map +0 -1
- package/dist/ui/components/TaskOverlay.d.ts +0 -10
- package/dist/ui/components/TaskOverlay.d.ts.map +0 -1
- package/dist/ui/components/TaskOverlay.js +0 -267
- package/dist/ui/components/TaskOverlay.js.map +0 -1
package/dist/tools/goals.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { log } from "../core/logger.js";
|
|
4
|
-
import { canCompleteGoalRun, decideGoalNextAction } from "../core/goal-controller.js";
|
|
4
|
+
import { canCompleteGoalRun, decideGoalNextAction, hasFreshGoalCompletionAudit, } from "../core/goal-controller.js";
|
|
5
5
|
import { runGoalPrerequisiteCheckCommand } from "../core/goal-prerequisites.js";
|
|
6
|
-
import { appendGoalDecision, appendGoalEvidence, createGoalEvidence, formatGoalBlockingPrerequisiteList, formatGoalBlockingPrerequisites, getActiveGoalRun, getGoalRun, goalHasBlockingPrerequisites, loadGoalRuns, upsertGoalRun, updateGoalTask, } from "../core/goal-store.js";
|
|
6
|
+
import { appendGoalBlockers, appendGoalDecision, appendGoalEvidence, createGoalEvidence, formatGoalBlockingPrerequisiteList, formatGoalBlockingPrerequisites, getActiveGoalRun, getGoalRun, goalHasBlockingPrerequisites, loadGoalRuns, upsertGoalRun, updateGoalTask, } from "../core/goal-store.js";
|
|
7
|
+
import { referencesRequiringAcknowledgement } from "../core/goal-references.js";
|
|
8
|
+
import { getActiveGoalMode } from "../core/runtime-mode.js";
|
|
7
9
|
const PrerequisiteInput = z.object({
|
|
8
10
|
id: z.string().optional().describe("Stable prerequisite id"),
|
|
9
11
|
label: z.string().describe("Human-readable prerequisite label"),
|
|
@@ -52,7 +54,9 @@ const GoalsParams = z.object({
|
|
|
52
54
|
"prerequisite",
|
|
53
55
|
"task",
|
|
54
56
|
"evidence",
|
|
57
|
+
"evidence_plan",
|
|
55
58
|
"verify",
|
|
59
|
+
"audit",
|
|
56
60
|
"status",
|
|
57
61
|
"pause",
|
|
58
62
|
"resume",
|
|
@@ -82,6 +86,11 @@ const GoalsParams = z.object({
|
|
|
82
86
|
.array(EvidencePlanInput)
|
|
83
87
|
.optional()
|
|
84
88
|
.describe("Planned proof paths for end-to-end verification"),
|
|
89
|
+
evidence_plan_item_id: z.string().optional().describe("Evidence-plan item id to update"),
|
|
90
|
+
evidence_plan_status: z
|
|
91
|
+
.enum(["planned", "ready", "blocked"])
|
|
92
|
+
.optional()
|
|
93
|
+
.describe("Updated evidence-plan item status"),
|
|
85
94
|
verifier_command: z.string().optional().describe("Command that verifies the goal end-to-end"),
|
|
86
95
|
verifier_description: z.string().optional().describe("Natural-language verifier description"),
|
|
87
96
|
task_id: z.string().optional().describe("Goal task id to update"),
|
|
@@ -172,6 +181,11 @@ function asEvidenceKind(value) {
|
|
|
172
181
|
}
|
|
173
182
|
return "summary";
|
|
174
183
|
}
|
|
184
|
+
function asEvidencePlanStatus(value) {
|
|
185
|
+
if (value === "ready" || value === "blocked" || value === "planned")
|
|
186
|
+
return value;
|
|
187
|
+
return "planned";
|
|
188
|
+
}
|
|
175
189
|
function asEvidenceMechanism(value) {
|
|
176
190
|
if (value === "command" ||
|
|
177
191
|
value === "test" ||
|
|
@@ -194,6 +208,12 @@ function asVerificationStatus(value) {
|
|
|
194
208
|
return value;
|
|
195
209
|
return "unknown";
|
|
196
210
|
}
|
|
211
|
+
function formatRunReferences(run) {
|
|
212
|
+
if (!run.references?.length)
|
|
213
|
+
return "";
|
|
214
|
+
const lines = run.references.map((reference) => `- ${reference.id}: ${reference.kind}; ${reference.label}${reference.value ? `; value=${reference.value}` : ""}${reference.path ? `; path=${reference.path}` : ""}`);
|
|
215
|
+
return `\nReferences:\n${lines.join("\n")}`;
|
|
216
|
+
}
|
|
197
217
|
function formatRun(run) {
|
|
198
218
|
const prereqs = run.prerequisites.length
|
|
199
219
|
? `${run.prerequisites.filter((item) => item.status === "met").length}/${run.prerequisites.length} prereqs met`
|
|
@@ -206,31 +226,144 @@ function formatRun(run) {
|
|
|
206
226
|
: run.verifier?.command
|
|
207
227
|
? "verifier configured"
|
|
208
228
|
: "no verifier";
|
|
229
|
+
const refs = run.references?.length ? `, ${run.references.length} reference(s)` : "";
|
|
230
|
+
const audit = run.completionAudit
|
|
231
|
+
? `, final audit ${run.completionAudit.status}`
|
|
232
|
+
: run.verifier?.lastResult?.status === "pass"
|
|
233
|
+
? ", final audit missing"
|
|
234
|
+
: "";
|
|
209
235
|
const blocker = goalHasBlockingPrerequisites(run)
|
|
210
236
|
? `\nUser prerequisites: ${formatGoalBlockingPrerequisites(run)}`
|
|
211
237
|
: "";
|
|
212
|
-
return `[${run.status}] ${run.title} (id: ${run.id.slice(0, 8)}) — ${prereqs}, ${tasks}, ${verifier}${blocker}`;
|
|
238
|
+
return `[${run.status}] ${run.title} (id: ${run.id.slice(0, 8)}) — ${prereqs}, ${tasks}, ${verifier}${refs}${audit}${blocker}${formatRunReferences(run)}`;
|
|
213
239
|
}
|
|
214
240
|
function recoverableTaskStatus(status) {
|
|
215
241
|
return status === "pending" || status === "failed";
|
|
216
242
|
}
|
|
217
243
|
function statusAfterTaskPatch(run, status) {
|
|
218
|
-
if (run.status !== "failed" || !recoverableTaskStatus(status))
|
|
244
|
+
if ((run.status !== "failed" && run.status !== "passed") || !recoverableTaskStatus(status)) {
|
|
245
|
+
return run.status;
|
|
246
|
+
}
|
|
247
|
+
return goalHasBlockingPrerequisites(run) ? "blocked" : "ready";
|
|
248
|
+
}
|
|
249
|
+
const SETUP_BLOCKER_PREFIX = "Goal setup incomplete:";
|
|
250
|
+
function referencesAcknowledged(references, fields) {
|
|
251
|
+
const required = referencesRequiringAcknowledgement(references ?? []);
|
|
252
|
+
if (required.length === 0)
|
|
253
|
+
return true;
|
|
254
|
+
const haystack = fields.join("\n").toLowerCase();
|
|
255
|
+
return required.every((reference) => {
|
|
256
|
+
const tokens = [reference.id, reference.label, reference.value, reference.path]
|
|
257
|
+
.filter((token) => !!token?.trim())
|
|
258
|
+
.map((token) => token.toLowerCase());
|
|
259
|
+
return tokens.some((token) => haystack.includes(token));
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
function hasOriginalGoalPromptReference(references) {
|
|
263
|
+
return (references ?? []).some((reference) => reference.id === "original-goal-prompt" &&
|
|
264
|
+
reference.kind === "prompt" &&
|
|
265
|
+
reference.content?.trim());
|
|
266
|
+
}
|
|
267
|
+
function setupBlockersForRun(run) {
|
|
268
|
+
const blockers = [];
|
|
269
|
+
const contractFields = [
|
|
270
|
+
run.goal ?? "",
|
|
271
|
+
...run.successCriteria,
|
|
272
|
+
...(run.references ?? []).map((reference) => `${reference.id} ${reference.label} ${reference.content ?? ""}`),
|
|
273
|
+
...(run.evidence ?? []).map((item) => `${item.label}\n${item.path ?? ""}\n${item.content ?? ""}`),
|
|
274
|
+
].join("\n");
|
|
275
|
+
const requiresReliabilityContract = /GOAL_PLAN/.test(contractFields);
|
|
276
|
+
if (requiresReliabilityContract && !hasOriginalGoalPromptReference(run.references)) {
|
|
277
|
+
blockers.push(`${SETUP_BLOCKER_PREFIX} durable [original-goal-prompt] reference is required.`);
|
|
278
|
+
}
|
|
279
|
+
const plannerFields = [
|
|
280
|
+
run.goal ?? "",
|
|
281
|
+
...(run.evidence ?? []).map((item) => `${item.label}\n${item.path ?? ""}\n${item.content ?? ""}`),
|
|
282
|
+
].join("\n");
|
|
283
|
+
if (requiresReliabilityContract &&
|
|
284
|
+
(!/GOAL_PLAN/.test(plannerFields) ||
|
|
285
|
+
!/research=/.test(plannerFields) ||
|
|
286
|
+
!/success=/.test(plannerFields))) {
|
|
287
|
+
blockers.push(`${SETUP_BLOCKER_PREFIX} durable planner GOAL_PLAN evidence/state is required.`);
|
|
288
|
+
}
|
|
289
|
+
if (run.successCriteria.length === 0)
|
|
290
|
+
blockers.push(`${SETUP_BLOCKER_PREFIX} success criteria are required.`);
|
|
291
|
+
if (run.evidencePlan.length === 0)
|
|
292
|
+
blockers.push(`${SETUP_BLOCKER_PREFIX} evidence_plan is required.`);
|
|
293
|
+
if (!run.verifier?.command)
|
|
294
|
+
blockers.push(`${SETUP_BLOCKER_PREFIX} verifier_command is required.`);
|
|
295
|
+
const referenceFields = [
|
|
296
|
+
...run.successCriteria,
|
|
297
|
+
...run.evidencePlan.map((item) => `${item.id} ${item.label} ${item.description} ${item.command ?? ""} ${item.path ?? ""} ${item.evidence ?? ""}`),
|
|
298
|
+
...run.tasks.map((task) => `${task.title} ${task.prompt}`),
|
|
299
|
+
run.verifier?.description ?? "",
|
|
300
|
+
run.verifier?.command ?? "",
|
|
301
|
+
];
|
|
302
|
+
if (!referencesAcknowledged(run.references, referenceFields)) {
|
|
303
|
+
blockers.push(`${SETUP_BLOCKER_PREFIX} every non-prompt Goal reference must be named in success criteria, task prompts, evidence_plan, or verifier metadata.`);
|
|
304
|
+
}
|
|
305
|
+
return blockers;
|
|
306
|
+
}
|
|
307
|
+
function blockersAfterSetupCheck(run, setupBlockers) {
|
|
308
|
+
if (run.status !== "draft")
|
|
309
|
+
return run.blockers;
|
|
310
|
+
return Array.from(new Set([
|
|
311
|
+
...run.blockers.filter((blocker) => !blocker.startsWith(SETUP_BLOCKER_PREFIX)),
|
|
312
|
+
...setupBlockers,
|
|
313
|
+
]));
|
|
314
|
+
}
|
|
315
|
+
function statusAfterSetupCheck(run, setupBlockers) {
|
|
316
|
+
if (run.status !== "draft")
|
|
219
317
|
return run.status;
|
|
318
|
+
if (setupBlockers.length > 0)
|
|
319
|
+
return "draft";
|
|
220
320
|
return goalHasBlockingPrerequisites(run) ? "blocked" : "ready";
|
|
221
321
|
}
|
|
322
|
+
function validatePassAuditContract(run, summary, outputPath) {
|
|
323
|
+
const verifier = run.verifier?.lastResult;
|
|
324
|
+
if (!verifier)
|
|
325
|
+
return "cannot audit completion before a verifier result exists.";
|
|
326
|
+
if (!summary.startsWith("FINAL_AUDIT_PASS"))
|
|
327
|
+
return "pass audit summary must start with FINAL_AUDIT_PASS.";
|
|
328
|
+
if (!summary.includes(`verifier_checked_at=${verifier.checkedAt}`)) {
|
|
329
|
+
return `pass audit summary must include verifier_checked_at=${verifier.checkedAt}.`;
|
|
330
|
+
}
|
|
331
|
+
if (!outputPath && !summary.match(/(?:output|artifact|log|path)=\S+/)) {
|
|
332
|
+
return "pass audit must include output_path or an output/artifact/log/path reference in the summary.";
|
|
333
|
+
}
|
|
334
|
+
const contractFields = [
|
|
335
|
+
run.goal,
|
|
336
|
+
...run.successCriteria,
|
|
337
|
+
...(run.references ?? []).map((reference) => `${reference.id} ${reference.label} ${reference.content ?? ""}`),
|
|
338
|
+
...run.evidence.map((item) => `${item.label}\n${item.path ?? ""}\n${item.content ?? ""}`),
|
|
339
|
+
].join("\n");
|
|
340
|
+
const requiresReliabilityContract = /GOAL_PLAN/.test(contractFields);
|
|
341
|
+
if (requiresReliabilityContract && !summary.includes("original-goal-prompt")) {
|
|
342
|
+
return "pass audit summary must explicitly reference original-goal-prompt.";
|
|
343
|
+
}
|
|
344
|
+
if (requiresReliabilityContract && !summary.includes("GOAL_PLAN")) {
|
|
345
|
+
return "pass audit summary must explicitly reference durable GOAL_PLAN evidence.";
|
|
346
|
+
}
|
|
347
|
+
if (!referencesAcknowledged(run.references, [summary, outputPath ?? ""])) {
|
|
348
|
+
return "pass audit summary or output_path must explicitly reference every non-prompt Goal reference id, label, URL, or path.";
|
|
349
|
+
}
|
|
350
|
+
return undefined;
|
|
351
|
+
}
|
|
222
352
|
async function resolveRun(cwd, id) {
|
|
223
353
|
if (id)
|
|
224
354
|
return getGoalRun(cwd, id);
|
|
225
355
|
return getActiveGoalRun(cwd);
|
|
226
356
|
}
|
|
227
|
-
export function createGoalsTool(cwd) {
|
|
357
|
+
export function createGoalsTool(cwd, goalModeRef, getGoalReferences) {
|
|
228
358
|
return {
|
|
229
359
|
name: "goals",
|
|
230
|
-
description: "Manage durable Goal runs for /goal and Ctrl+G workflows. Use this instead of tasks when the user wants a programmatic goal loop: define success criteria first, check prerequisites before launching workers, persist harness/diagnostics/evidence, add standalone worker tasks, and only mark the goal complete when verifier evidence proves the original objective. Do not require paid services or signups without recording a blocker and asking the user for the missing prerequisite.",
|
|
360
|
+
description: "Manage durable Goal runs for /goal and Ctrl+G workflows. Use this instead of tasks when the user wants a programmatic goal loop: define success criteria first, check prerequisites before launching workers, persist harness/diagnostics/evidence, add standalone worker tasks, record final completion audits, and only mark the goal complete when verifier plus final-audit evidence proves the original objective. Do not require paid services or signups without recording a blocker and asking the user for the missing prerequisite.",
|
|
231
361
|
parameters: GoalsParams,
|
|
232
362
|
executionMode: "sequential",
|
|
233
363
|
async execute(args) {
|
|
364
|
+
if (getActiveGoalMode(goalModeRef) === "planner") {
|
|
365
|
+
return "Error: goals is restricted in Goal planner mode. Emit a compact GOAL_PLAN block only; setup creates durable Goal state.";
|
|
366
|
+
}
|
|
234
367
|
switch (args.action) {
|
|
235
368
|
case "create": {
|
|
236
369
|
if (!args.title)
|
|
@@ -273,28 +406,58 @@ export function createGoalsTool(cwd) {
|
|
|
273
406
|
const nextPrerequisites = prerequisites ?? existing?.prerequisites ?? [];
|
|
274
407
|
const missingPrerequisites = formatGoalBlockingPrerequisiteList(nextPrerequisites);
|
|
275
408
|
const hasBlockingPrerequisites = missingPrerequisites !== "Goal has no missing user prerequisites.";
|
|
409
|
+
const references = [...(getGoalReferences?.() ?? existing?.references ?? [])];
|
|
410
|
+
const plannerEvidence = args.summary?.includes("GOAL_PLAN")
|
|
411
|
+
? [
|
|
412
|
+
createGoalEvidence({
|
|
413
|
+
kind: "summary",
|
|
414
|
+
label: "Planner GOAL_PLAN",
|
|
415
|
+
content: args.summary,
|
|
416
|
+
}),
|
|
417
|
+
]
|
|
418
|
+
: undefined;
|
|
419
|
+
const draftProbe = {
|
|
420
|
+
goal: args.goal,
|
|
421
|
+
successCriteria: args.success_criteria ?? existing?.successCriteria ?? [],
|
|
422
|
+
evidencePlan: evidencePlan ?? existing?.evidencePlan ?? [],
|
|
423
|
+
references,
|
|
424
|
+
tasks: existing?.tasks ?? [],
|
|
425
|
+
evidence: plannerEvidence ?? existing?.evidence ?? [],
|
|
426
|
+
verifier,
|
|
427
|
+
};
|
|
428
|
+
const setupBlockers = setupBlockersForRun(draftProbe);
|
|
429
|
+
const blockers = Array.from(new Set([
|
|
430
|
+
...(args.blockers ?? existing?.blockers ?? []),
|
|
431
|
+
...(hasBlockingPrerequisites ? [missingPrerequisites] : []),
|
|
432
|
+
...setupBlockers,
|
|
433
|
+
]));
|
|
276
434
|
const run = await upsertGoalRun(cwd, {
|
|
277
435
|
...(args.run_id ? { id: args.run_id } : {}),
|
|
278
436
|
title: args.title,
|
|
279
437
|
goal: args.goal,
|
|
280
|
-
status:
|
|
281
|
-
|
|
438
|
+
status: setupBlockers.length > 0
|
|
439
|
+
? "draft"
|
|
440
|
+
: hasBlockingPrerequisites
|
|
441
|
+
? "blocked"
|
|
442
|
+
: (existing?.status ?? "ready"),
|
|
443
|
+
successCriteria: draftProbe.successCriteria,
|
|
282
444
|
prerequisites: nextPrerequisites,
|
|
283
445
|
harness: harness ?? existing?.harness ?? [],
|
|
284
|
-
evidencePlan: evidencePlan
|
|
446
|
+
evidencePlan: draftProbe.evidencePlan,
|
|
447
|
+
references: draftProbe.references,
|
|
448
|
+
...(plannerEvidence ? { evidence: plannerEvidence } : {}),
|
|
285
449
|
...(verifier ? { verifier } : {}),
|
|
286
|
-
blockers
|
|
287
|
-
? Array.from(new Set([...(args.blockers ?? existing?.blockers ?? []), missingPrerequisites]))
|
|
288
|
-
: (args.blockers ?? []),
|
|
450
|
+
blockers,
|
|
289
451
|
});
|
|
290
452
|
await appendGoalDecision(cwd, run.id, {
|
|
291
453
|
kind: args.run_id ? "update" : "create",
|
|
292
|
-
reason: `criteria=${run.successCriteria.length}; prerequisites=${run.prerequisites.length}; harness=${run.harness.length}; evidence_plan=${run.evidencePlan.length}; verifier=${run.verifier?.command ? "configured" : "missing"}`,
|
|
454
|
+
reason: `criteria=${run.successCriteria.length}; prerequisites=${run.prerequisites.length}; harness=${run.harness.length}; evidence_plan=${run.evidencePlan.length}; references=${run.references?.length ?? 0}; verifier=${run.verifier?.command ? "configured" : "missing"}`,
|
|
293
455
|
});
|
|
294
456
|
log("INFO", "goals", `Goal created: ${run.title}`, { id: run.id, status: run.status });
|
|
457
|
+
const setupMessage = setupBlockers.length > 0 ? ` Setup blockers: ${setupBlockers.join(" ")}` : "";
|
|
295
458
|
return goalHasBlockingPrerequisites(run)
|
|
296
|
-
? `Goal ${args.run_id ? "updated" : "created"}: "${run.title}" (id: ${run.id.slice(0, 8)}, ${run.status}). User prerequisites: ${formatGoalBlockingPrerequisites(run)}`
|
|
297
|
-
: `Goal ${args.run_id ? "updated" : "created"}: "${run.title}" (id: ${run.id.slice(0, 8)}, ${run.status})`;
|
|
459
|
+
? `Goal ${args.run_id ? "updated" : "created"}: "${run.title}" (id: ${run.id.slice(0, 8)}, ${run.status}). User prerequisites: ${formatGoalBlockingPrerequisites(run)}${setupMessage}`
|
|
460
|
+
: `Goal ${args.run_id ? "updated" : "created"}: "${run.title}" (id: ${run.id.slice(0, 8)}, ${run.status}).${setupMessage}`;
|
|
298
461
|
}
|
|
299
462
|
case "status": {
|
|
300
463
|
if (args.run_id) {
|
|
@@ -345,12 +508,17 @@ export function createGoalsTool(cwd) {
|
|
|
345
508
|
else {
|
|
346
509
|
prerequisites.push(patch);
|
|
347
510
|
}
|
|
348
|
-
const
|
|
349
|
-
const updated = await upsertGoalRun(cwd, {
|
|
511
|
+
const prerequisiteRun = {
|
|
350
512
|
...run,
|
|
351
513
|
prerequisites,
|
|
352
|
-
status:
|
|
353
|
-
blockers:
|
|
514
|
+
status: goalHasBlockingPrerequisites({ ...run, prerequisites }) ? "blocked" : "ready",
|
|
515
|
+
blockers: goalHasBlockingPrerequisites({ ...run, prerequisites }) ? run.blockers : [],
|
|
516
|
+
};
|
|
517
|
+
const setupBlockers = setupBlockersForRun(prerequisiteRun);
|
|
518
|
+
const updated = await upsertGoalRun(cwd, {
|
|
519
|
+
...prerequisiteRun,
|
|
520
|
+
status: statusAfterSetupCheck(prerequisiteRun, setupBlockers),
|
|
521
|
+
blockers: blockersAfterSetupCheck(prerequisiteRun, setupBlockers),
|
|
354
522
|
});
|
|
355
523
|
await appendGoalDecision(cwd, updated.id, {
|
|
356
524
|
kind: "prerequisites",
|
|
@@ -373,6 +541,10 @@ export function createGoalsTool(cwd) {
|
|
|
373
541
|
if (!taskExisted && (!args.task_title || !args.task_prompt)) {
|
|
374
542
|
return "Error: task_title and task_prompt are required when adding a task.";
|
|
375
543
|
}
|
|
544
|
+
if (!taskExisted &&
|
|
545
|
+
!referencesAcknowledged(run.references, [args.task_title ?? "", args.task_prompt ?? ""])) {
|
|
546
|
+
return "Error: task_prompt must explicitly include each non-prompt Goal reference id, label, URL, or path so workers cannot silently ignore the user's references.";
|
|
547
|
+
}
|
|
376
548
|
const taskStatus = asTaskStatus(args.task_status);
|
|
377
549
|
const updated = await updateGoalTask(cwd, run.id, taskId, {
|
|
378
550
|
id: taskId,
|
|
@@ -384,10 +556,18 @@ export function createGoalsTool(cwd) {
|
|
|
384
556
|
...(args.summary ? { lastSummary: args.summary } : {}),
|
|
385
557
|
});
|
|
386
558
|
const recovered = updated
|
|
387
|
-
? await
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
559
|
+
? await (async () => {
|
|
560
|
+
const taskPatchedRun = {
|
|
561
|
+
...updated,
|
|
562
|
+
status: statusAfterTaskPatch(updated, taskStatus),
|
|
563
|
+
};
|
|
564
|
+
const setupBlockers = setupBlockersForRun(taskPatchedRun);
|
|
565
|
+
return upsertGoalRun(updated.projectPath, {
|
|
566
|
+
...taskPatchedRun,
|
|
567
|
+
status: statusAfterSetupCheck(taskPatchedRun, setupBlockers),
|
|
568
|
+
blockers: blockersAfterSetupCheck(taskPatchedRun, setupBlockers),
|
|
569
|
+
});
|
|
570
|
+
})()
|
|
391
571
|
: null;
|
|
392
572
|
if (!recovered)
|
|
393
573
|
return `Error: no task found matching id "${taskId}".`;
|
|
@@ -412,6 +592,48 @@ export function createGoalsTool(cwd) {
|
|
|
412
592
|
return "Error: failed to append evidence.";
|
|
413
593
|
return `Evidence added to "${updated.title}".`;
|
|
414
594
|
}
|
|
595
|
+
case "evidence_plan": {
|
|
596
|
+
const run = await resolveRun(cwd, args.run_id);
|
|
597
|
+
if (!run)
|
|
598
|
+
return "Error: no active goal run found.";
|
|
599
|
+
const evidencePlanItemId = args.evidence_plan_item_id;
|
|
600
|
+
if (!evidencePlanItemId)
|
|
601
|
+
return "Error: evidence_plan_item_id is required.";
|
|
602
|
+
const evidencePlan = [...run.evidencePlan];
|
|
603
|
+
const index = evidencePlan.findIndex((item) => item.id === evidencePlanItemId || item.id.startsWith(evidencePlanItemId));
|
|
604
|
+
if (index < 0) {
|
|
605
|
+
return `Error: no evidence-plan item found matching id "${args.evidence_plan_item_id}".`;
|
|
606
|
+
}
|
|
607
|
+
const existing = evidencePlan[index];
|
|
608
|
+
const status = asEvidencePlanStatus(args.evidence_plan_status);
|
|
609
|
+
evidencePlan[index] = {
|
|
610
|
+
...existing,
|
|
611
|
+
status,
|
|
612
|
+
...(args.instructions ? { instructions: args.instructions } : {}),
|
|
613
|
+
...(args.evidence_content || args.summary
|
|
614
|
+
? { evidence: args.evidence_content ?? args.summary }
|
|
615
|
+
: {}),
|
|
616
|
+
...(args.evidence_path ? { path: args.evidence_path } : {}),
|
|
617
|
+
};
|
|
618
|
+
const canRecoverBlockedRun = run.status === "blocked" && status === "ready" && !goalHasBlockingPrerequisites(run);
|
|
619
|
+
const evidencePlanRun = {
|
|
620
|
+
...run,
|
|
621
|
+
evidencePlan,
|
|
622
|
+
status: canRecoverBlockedRun ? "ready" : run.status,
|
|
623
|
+
blockers: canRecoverBlockedRun ? [] : run.blockers,
|
|
624
|
+
};
|
|
625
|
+
const setupBlockers = setupBlockersForRun(evidencePlanRun);
|
|
626
|
+
const updated = await upsertGoalRun(cwd, {
|
|
627
|
+
...evidencePlanRun,
|
|
628
|
+
status: statusAfterSetupCheck(evidencePlanRun, setupBlockers),
|
|
629
|
+
blockers: blockersAfterSetupCheck(evidencePlanRun, setupBlockers),
|
|
630
|
+
});
|
|
631
|
+
await appendGoalDecision(cwd, updated.id, {
|
|
632
|
+
kind: "evidence_plan",
|
|
633
|
+
reason: `Evidence-plan item ${existing.label} is ${status}.`,
|
|
634
|
+
});
|
|
635
|
+
return `Evidence-plan item updated for "${updated.title}": "${existing.label}" is ${status}.`;
|
|
636
|
+
}
|
|
415
637
|
case "verify": {
|
|
416
638
|
const run = await resolveRun(cwd, args.run_id);
|
|
417
639
|
if (!run)
|
|
@@ -435,6 +657,17 @@ export function createGoalsTool(cwd) {
|
|
|
435
657
|
: {}),
|
|
436
658
|
lastResult: result,
|
|
437
659
|
},
|
|
660
|
+
...(result.status === "pass"
|
|
661
|
+
? {
|
|
662
|
+
completionAudit: {
|
|
663
|
+
status: "unknown",
|
|
664
|
+
summary: "Final completion audit pending for latest verifier result.",
|
|
665
|
+
checkedAt: result.checkedAt,
|
|
666
|
+
verifierCheckedAt: result.checkedAt,
|
|
667
|
+
...(result.outputPath ? { outputPath: result.outputPath } : {}),
|
|
668
|
+
},
|
|
669
|
+
}
|
|
670
|
+
: {}),
|
|
438
671
|
evidence: [
|
|
439
672
|
...run.evidence,
|
|
440
673
|
createGoalEvidence({
|
|
@@ -464,6 +697,61 @@ export function createGoalsTool(cwd) {
|
|
|
464
697
|
});
|
|
465
698
|
return `Verifier recorded for "${updated.title}": ${result.status}.`;
|
|
466
699
|
}
|
|
700
|
+
case "audit": {
|
|
701
|
+
const run = await resolveRun(cwd, args.run_id);
|
|
702
|
+
if (!run)
|
|
703
|
+
return "Error: no active goal run found.";
|
|
704
|
+
const verifierResult = run.verifier?.lastResult;
|
|
705
|
+
if (!verifierResult || verifierResult.status !== "pass") {
|
|
706
|
+
return "Error: cannot audit completion before a passing verifier result exists.";
|
|
707
|
+
}
|
|
708
|
+
const auditStatus = asVerificationStatus(args.verification_status);
|
|
709
|
+
const auditSummary = args.summary ?? "Final completion audit recorded.";
|
|
710
|
+
const auditOutputPath = args.output_path ?? verifierResult.outputPath;
|
|
711
|
+
if (auditStatus === "pass") {
|
|
712
|
+
const contractError = validatePassAuditContract(run, auditSummary, auditOutputPath);
|
|
713
|
+
if (contractError)
|
|
714
|
+
return `Error: invalid final completion audit pass contract: ${contractError}`;
|
|
715
|
+
}
|
|
716
|
+
const completionAudit = {
|
|
717
|
+
status: auditStatus,
|
|
718
|
+
summary: auditSummary,
|
|
719
|
+
checkedAt: new Date().toISOString(),
|
|
720
|
+
verifierCheckedAt: verifierResult.checkedAt,
|
|
721
|
+
...(auditOutputPath ? { outputPath: auditOutputPath } : {}),
|
|
722
|
+
};
|
|
723
|
+
const runWithAudit = {
|
|
724
|
+
...run,
|
|
725
|
+
completionAudit,
|
|
726
|
+
evidence: [
|
|
727
|
+
...run.evidence,
|
|
728
|
+
createGoalEvidence({
|
|
729
|
+
kind: "summary",
|
|
730
|
+
label: `Final completion audit ${completionAudit.status}`,
|
|
731
|
+
content: completionAudit.summary,
|
|
732
|
+
...(completionAudit.outputPath ? { path: completionAudit.outputPath } : {}),
|
|
733
|
+
}),
|
|
734
|
+
],
|
|
735
|
+
};
|
|
736
|
+
const auditCheck = hasFreshGoalCompletionAudit(runWithAudit);
|
|
737
|
+
const completion = canCompleteGoalRun(runWithAudit);
|
|
738
|
+
const updated = await upsertGoalRun(cwd, {
|
|
739
|
+
...runWithAudit,
|
|
740
|
+
status: completionAudit.status === "pass" && auditCheck.ok && completion.ok
|
|
741
|
+
? "passed"
|
|
742
|
+
: goalHasBlockingPrerequisites(runWithAudit)
|
|
743
|
+
? "blocked"
|
|
744
|
+
: "ready",
|
|
745
|
+
blockers: completionAudit.status === "pass" && auditCheck.ok ? [] : run.blockers,
|
|
746
|
+
activeWorkerId: undefined,
|
|
747
|
+
});
|
|
748
|
+
await appendGoalDecision(cwd, updated.id, {
|
|
749
|
+
kind: "completion_audit",
|
|
750
|
+
reason: auditCheck.reason,
|
|
751
|
+
content: `status=${completionAudit.status}; verifierCheckedAt=${completionAudit.verifierCheckedAt ?? ""}; outputPath=${completionAudit.outputPath ?? ""}`,
|
|
752
|
+
});
|
|
753
|
+
return `Completion audit recorded for "${updated.title}": ${completionAudit.status}.`;
|
|
754
|
+
}
|
|
467
755
|
case "pause":
|
|
468
756
|
case "resume":
|
|
469
757
|
case "complete": {
|
|
@@ -471,8 +759,12 @@ export function createGoalsTool(cwd) {
|
|
|
471
759
|
if (!run)
|
|
472
760
|
return "Error: no active goal run found.";
|
|
473
761
|
let status;
|
|
474
|
-
if (args.action === "pause")
|
|
762
|
+
if (args.action === "pause") {
|
|
763
|
+
if (run.activeWorkerId || run.tasks.some((task) => task.status === "running")) {
|
|
764
|
+
return `Error: cannot pause goal while worker ${run.activeWorkerId ?? "task"} is active. Stop the worker first or wait for it to finish.`;
|
|
765
|
+
}
|
|
475
766
|
status = "paused";
|
|
767
|
+
}
|
|
476
768
|
else if (args.action === "resume") {
|
|
477
769
|
const missing = goalHasBlockingPrerequisites(run)
|
|
478
770
|
? formatGoalBlockingPrerequisites(run)
|
|
@@ -481,7 +773,7 @@ export function createGoalsTool(cwd) {
|
|
|
481
773
|
const updated = await upsertGoalRun(cwd, {
|
|
482
774
|
...run,
|
|
483
775
|
status: "blocked",
|
|
484
|
-
blockers:
|
|
776
|
+
blockers: appendGoalBlockers(run.blockers, missing),
|
|
485
777
|
evidence: [
|
|
486
778
|
...run.evidence,
|
|
487
779
|
createGoalEvidence({
|
|
@@ -509,7 +801,25 @@ export function createGoalsTool(cwd) {
|
|
|
509
801
|
],
|
|
510
802
|
};
|
|
511
803
|
const decision = decideGoalNextAction(resumed);
|
|
512
|
-
const
|
|
804
|
+
const blockedReason = decision.kind === "blocked" ? decision.reason : undefined;
|
|
805
|
+
const updated = await upsertGoalRun(cwd, {
|
|
806
|
+
...resumed,
|
|
807
|
+
...(blockedReason
|
|
808
|
+
? {
|
|
809
|
+
status: "blocked",
|
|
810
|
+
continueRequestedAt: undefined,
|
|
811
|
+
blockers: appendGoalBlockers(run.blockers, blockedReason),
|
|
812
|
+
evidence: [
|
|
813
|
+
...resumed.evidence,
|
|
814
|
+
createGoalEvidence({
|
|
815
|
+
kind: "summary",
|
|
816
|
+
label: "Goal resume blocked",
|
|
817
|
+
content: blockedReason,
|
|
818
|
+
}),
|
|
819
|
+
],
|
|
820
|
+
}
|
|
821
|
+
: {}),
|
|
822
|
+
});
|
|
513
823
|
await appendGoalDecision(cwd, updated.id, {
|
|
514
824
|
kind: "resume",
|
|
515
825
|
reason: decision.kind === "wait" ||
|