@prestyj/cli 4.3.205 → 4.3.207
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/dist/cli.js +38 -26
- package/dist/cli.js.map +1 -1
- package/dist/core/compaction/compactor.d.ts.map +1 -1
- package/dist/core/compaction/compactor.js +6 -0
- package/dist/core/compaction/compactor.js.map +1 -1
- package/dist/core/compaction/compactor.test.js +16 -0
- package/dist/core/compaction/compactor.test.js.map +1 -1
- package/dist/core/goal-controller.d.ts +57 -0
- package/dist/core/goal-controller.d.ts.map +1 -0
- package/dist/core/goal-controller.js +285 -0
- package/dist/core/goal-controller.js.map +1 -0
- package/dist/core/goal-controller.test.d.ts +2 -0
- package/dist/core/goal-controller.test.d.ts.map +1 -0
- package/dist/core/goal-controller.test.js +419 -0
- package/dist/core/goal-controller.test.js.map +1 -0
- package/dist/core/goal-lifecycle-smoke.test.d.ts +2 -0
- package/dist/core/goal-lifecycle-smoke.test.d.ts.map +1 -0
- package/dist/core/goal-lifecycle-smoke.test.js +207 -0
- package/dist/core/goal-lifecycle-smoke.test.js.map +1 -0
- package/dist/core/goal-store.d.ts +164 -0
- package/dist/core/goal-store.d.ts.map +1 -0
- package/dist/core/goal-store.js +721 -0
- package/dist/core/goal-store.js.map +1 -0
- package/dist/core/goal-store.test.d.ts +2 -0
- package/dist/core/goal-store.test.d.ts.map +1 -0
- package/dist/core/goal-store.test.js +341 -0
- package/dist/core/goal-store.test.js.map +1 -0
- package/dist/core/goal-verifier.d.ts +17 -0
- package/dist/core/goal-verifier.d.ts.map +1 -0
- package/dist/core/goal-verifier.js +84 -0
- package/dist/core/goal-verifier.js.map +1 -0
- package/dist/core/goal-verifier.test.d.ts +2 -0
- package/dist/core/goal-verifier.test.d.ts.map +1 -0
- package/dist/core/goal-verifier.test.js +88 -0
- package/dist/core/goal-verifier.test.js.map +1 -0
- package/dist/core/goal-worker-dev-server-lifecycle.test.d.ts +2 -0
- package/dist/core/goal-worker-dev-server-lifecycle.test.d.ts.map +1 -0
- package/dist/core/goal-worker-dev-server-lifecycle.test.js +68 -0
- package/dist/core/goal-worker-dev-server-lifecycle.test.js.map +1 -0
- package/dist/core/goal-worker.d.ts +51 -0
- package/dist/core/goal-worker.d.ts.map +1 -0
- package/dist/core/goal-worker.js +339 -0
- package/dist/core/goal-worker.js.map +1 -0
- package/dist/core/goal-worker.test.d.ts +2 -0
- package/dist/core/goal-worker.test.d.ts.map +1 -0
- package/dist/core/goal-worker.test.js +224 -0
- package/dist/core/goal-worker.test.js.map +1 -0
- package/dist/core/model-registry.test.js +51 -1
- package/dist/core/model-registry.test.js.map +1 -1
- package/dist/core/process-manager-dev-server-repro.test.d.ts +2 -0
- package/dist/core/process-manager-dev-server-repro.test.d.ts.map +1 -0
- package/dist/core/process-manager-dev-server-repro.test.js +100 -0
- package/dist/core/process-manager-dev-server-repro.test.js.map +1 -0
- package/dist/core/process-manager.js +2 -2
- package/dist/core/process-manager.js.map +1 -1
- package/dist/core/prompt-commands.d.ts.map +1 -1
- package/dist/core/prompt-commands.js +52 -0
- package/dist/core/prompt-commands.js.map +1 -1
- package/dist/core/prompt-commands.test.js +24 -0
- package/dist/core/prompt-commands.test.js.map +1 -1
- package/dist/interactive.d.ts.map +1 -1
- package/dist/interactive.js +20 -11
- package/dist/interactive.js.map +1 -1
- package/dist/system-prompt.d.ts.map +1 -1
- package/dist/system-prompt.js +18 -40
- package/dist/system-prompt.js.map +1 -1
- package/dist/system-prompt.test.js +124 -1
- package/dist/system-prompt.test.js.map +1 -1
- package/dist/tools/edit-diff.d.ts.map +1 -1
- package/dist/tools/edit-diff.js +71 -32
- package/dist/tools/edit-diff.js.map +1 -1
- package/dist/tools/edit-diff.test.js +14 -0
- package/dist/tools/edit-diff.test.js.map +1 -1
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +38 -18
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/edit.test.js +56 -6
- package/dist/tools/edit.test.js.map +1 -1
- package/dist/tools/goals.d.ts +110 -0
- package/dist/tools/goals.d.ts.map +1 -0
- package/dist/tools/goals.js +500 -0
- package/dist/tools/goals.js.map +1 -0
- package/dist/tools/goals.test.d.ts +2 -0
- package/dist/tools/goals.test.d.ts.map +1 -0
- package/dist/tools/goals.test.js +431 -0
- package/dist/tools/goals.test.js.map +1 -0
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +3 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/source-path.js +1 -1
- package/dist/ui/App.d.ts +73 -4
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +1068 -140
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/app-state-persistence.test.d.ts +2 -0
- package/dist/ui/app-state-persistence.test.d.ts.map +1 -0
- package/dist/ui/app-state-persistence.test.js +130 -0
- package/dist/ui/app-state-persistence.test.js.map +1 -0
- package/dist/ui/components/BackgroundTasksBar.d.ts +16 -1
- package/dist/ui/components/BackgroundTasksBar.d.ts.map +1 -1
- package/dist/ui/components/BackgroundTasksBar.js +15 -2
- package/dist/ui/components/BackgroundTasksBar.js.map +1 -1
- package/dist/ui/components/Banner.d.ts +2 -1
- package/dist/ui/components/Banner.d.ts.map +1 -1
- package/dist/ui/components/Banner.js +3 -3
- package/dist/ui/components/Banner.js.map +1 -1
- package/dist/ui/components/GoalOverlay.d.ts +74 -0
- package/dist/ui/components/GoalOverlay.d.ts.map +1 -0
- package/dist/ui/components/GoalOverlay.js +675 -0
- package/dist/ui/components/GoalOverlay.js.map +1 -0
- package/dist/ui/components/GoalStatusBar.d.ts +24 -0
- package/dist/ui/components/GoalStatusBar.d.ts.map +1 -0
- package/dist/ui/components/GoalStatusBar.js +113 -0
- package/dist/ui/components/GoalStatusBar.js.map +1 -0
- package/dist/ui/components/InputArea.d.ts +2 -1
- package/dist/ui/components/InputArea.d.ts.map +1 -1
- package/dist/ui/components/InputArea.js +44 -2
- package/dist/ui/components/InputArea.js.map +1 -1
- package/dist/ui/components/InputArea.test.d.ts +2 -0
- package/dist/ui/components/InputArea.test.d.ts.map +1 -0
- package/dist/ui/components/InputArea.test.js +79 -0
- package/dist/ui/components/InputArea.test.js.map +1 -0
- package/dist/ui/components/ToolExecution.d.ts.map +1 -1
- package/dist/ui/components/ToolExecution.js +27 -2
- package/dist/ui/components/ToolExecution.js.map +1 -1
- package/dist/ui/footer-status-layout.test.d.ts +2 -0
- package/dist/ui/footer-status-layout.test.d.ts.map +1 -0
- package/dist/ui/footer-status-layout.test.js +56 -0
- package/dist/ui/footer-status-layout.test.js.map +1 -0
- package/dist/ui/goal-events.d.ts +107 -0
- package/dist/ui/goal-events.d.ts.map +1 -0
- package/dist/ui/goal-events.js +323 -0
- package/dist/ui/goal-events.js.map +1 -0
- package/dist/ui/goal-events.test.d.ts +2 -0
- package/dist/ui/goal-events.test.d.ts.map +1 -0
- package/dist/ui/goal-events.test.js +293 -0
- package/dist/ui/goal-events.test.js.map +1 -0
- package/dist/ui/goal-overlay.test.d.ts +2 -0
- package/dist/ui/goal-overlay.test.d.ts.map +1 -0
- package/dist/ui/goal-overlay.test.js +276 -0
- package/dist/ui/goal-overlay.test.js.map +1 -0
- package/dist/ui/goal-status-bar.test.d.ts +2 -0
- package/dist/ui/goal-status-bar.test.d.ts.map +1 -0
- package/dist/ui/goal-status-bar.test.js +143 -0
- package/dist/ui/goal-status-bar.test.js.map +1 -0
- package/dist/ui/live-item-flush.test.js +48 -0
- package/dist/ui/live-item-flush.test.js.map +1 -1
- package/dist/ui/render.d.ts +11 -4
- package/dist/ui/render.d.ts.map +1 -1
- package/dist/ui/render.js +12 -3
- package/dist/ui/render.js.map +1 -1
- package/dist/ui/scroll-stabilization.test.d.ts +2 -0
- package/dist/ui/scroll-stabilization.test.d.ts.map +1 -0
- package/dist/ui/scroll-stabilization.test.js +70 -0
- package/dist/ui/scroll-stabilization.test.js.map +1 -0
- package/dist/ui/slash-command-images.test.d.ts +2 -0
- package/dist/ui/slash-command-images.test.d.ts.map +1 -0
- package/dist/ui/slash-command-images.test.js +47 -0
- package/dist/ui/slash-command-images.test.js.map +1 -0
- package/package.json +4 -4
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import { DEFAULT_GOAL_VERIFIER_FIX_LIMIT } from "../core/goal-controller.js";
|
|
2
|
+
import { formatGoalBlockingPrerequisites, goalHasBlockingPrerequisites, } from "../core/goal-store.js";
|
|
3
|
+
export const GOAL_WORKER_EVENT_PREFIX = "[event:goal_worker_complete]";
|
|
4
|
+
export const GOAL_VERIFIER_EVENT_PREFIX = "[event:goal_verifier_complete]";
|
|
5
|
+
export const GOAL_EVENT_PAYLOAD_PREFIX = "goal_event_payload: ";
|
|
6
|
+
export const GOAL_EVENT_PAYLOAD_VERSION = 1;
|
|
7
|
+
const GOAL_ORCHESTRATOR_INSTRUCTIONS = `orchestrator_instructions:
|
|
8
|
+
1. Call goals({ action: "status", run_id }) before deciding.
|
|
9
|
+
2. Briefly say what the orchestrator is doing so the chat shows progress.
|
|
10
|
+
3. Inspect durable tasks, verifier state, blockers, and evidence.
|
|
11
|
+
4. Take exactly one next control-loop action: add/update the next Goal task, run/record verification, pause/block with evidence, or complete only if verifier evidence proves the success criteria.
|
|
12
|
+
5. Do not merely narrate and do not ask the user to open the Goal pane.`;
|
|
13
|
+
function headerValue(value) {
|
|
14
|
+
return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\s+/g, " ");
|
|
15
|
+
}
|
|
16
|
+
function formatPayloadLine(payload) {
|
|
17
|
+
return `${GOAL_EVENT_PAYLOAD_PREFIX}${JSON.stringify(payload)}`;
|
|
18
|
+
}
|
|
19
|
+
export function buildGoalStateSnapshot(run) {
|
|
20
|
+
const latestEvidence = run.evidence.at(-1);
|
|
21
|
+
return {
|
|
22
|
+
status: run.status,
|
|
23
|
+
userPrerequisites: goalHasBlockingPrerequisites(run)
|
|
24
|
+
? formatGoalBlockingPrerequisites(run)
|
|
25
|
+
: "(none)",
|
|
26
|
+
verifier: run.verifier
|
|
27
|
+
? {
|
|
28
|
+
description: run.verifier.description,
|
|
29
|
+
...(run.verifier.command ? { command: run.verifier.command } : {}),
|
|
30
|
+
...(run.verifier.lastResult
|
|
31
|
+
? {
|
|
32
|
+
lastStatus: run.verifier.lastResult.status,
|
|
33
|
+
...(run.verifier.lastResult.outputPath
|
|
34
|
+
? { outputPath: run.verifier.lastResult.outputPath }
|
|
35
|
+
: {}),
|
|
36
|
+
}
|
|
37
|
+
: {}),
|
|
38
|
+
}
|
|
39
|
+
: null,
|
|
40
|
+
blockers: [...run.blockers],
|
|
41
|
+
prerequisites: run.prerequisites.map((item) => ({
|
|
42
|
+
id: item.id,
|
|
43
|
+
label: item.label,
|
|
44
|
+
status: item.status,
|
|
45
|
+
...(item.instructions ? { instructions: item.instructions } : {}),
|
|
46
|
+
...(item.evidence ? { evidence: item.evidence } : {}),
|
|
47
|
+
})),
|
|
48
|
+
evidencePlan: run.evidencePlan.map((item) => ({
|
|
49
|
+
id: item.id,
|
|
50
|
+
label: item.label,
|
|
51
|
+
status: item.status,
|
|
52
|
+
mechanism: item.mechanism,
|
|
53
|
+
...(item.command ? { command: item.command } : {}),
|
|
54
|
+
...(item.path ? { path: item.path } : {}),
|
|
55
|
+
...(item.evidence ? { evidence: item.evidence } : {}),
|
|
56
|
+
})),
|
|
57
|
+
tasks: run.tasks.map((task) => ({
|
|
58
|
+
id: task.id,
|
|
59
|
+
title: task.title,
|
|
60
|
+
status: task.status,
|
|
61
|
+
attempts: task.attempts,
|
|
62
|
+
...(task.workerId ? { workerId: task.workerId } : {}),
|
|
63
|
+
})),
|
|
64
|
+
evidenceCount: run.evidence.length,
|
|
65
|
+
...(latestEvidence
|
|
66
|
+
? {
|
|
67
|
+
latestEvidence: {
|
|
68
|
+
label: latestEvidence.label,
|
|
69
|
+
kind: latestEvidence.kind,
|
|
70
|
+
...(latestEvidence.path ? { path: latestEvidence.path } : {}),
|
|
71
|
+
},
|
|
72
|
+
}
|
|
73
|
+
: {}),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function formatGoalState(snapshot) {
|
|
77
|
+
const tasks = snapshot.tasks
|
|
78
|
+
.map((task) => `- ${task.id}: ${task.status}; attempts=${task.attempts}; title=${task.title}`)
|
|
79
|
+
.join("\n") || "(none)";
|
|
80
|
+
const blockers = snapshot.blockers.length > 0
|
|
81
|
+
? snapshot.blockers.map((blocker) => `- ${blocker}`).join("\n")
|
|
82
|
+
: "(none)";
|
|
83
|
+
const verifier = snapshot.verifier?.command
|
|
84
|
+
? `${snapshot.verifier.command}; last=${snapshot.verifier.lastStatus ?? "none"}; output=${snapshot.verifier.outputPath ?? "none"}`
|
|
85
|
+
: "(none - define an exact verifier before completion)";
|
|
86
|
+
const prerequisites = snapshot.prerequisites.length
|
|
87
|
+
? snapshot.prerequisites
|
|
88
|
+
.map((item) => `- ${item.id}: ${item.status}; ${item.label}${item.instructions ? `; instructions=${item.instructions}` : ""}${item.evidence ? `; evidence=${item.evidence}` : ""}`)
|
|
89
|
+
.join("\n")
|
|
90
|
+
: "(none)";
|
|
91
|
+
const evidencePlan = snapshot.evidencePlan.length
|
|
92
|
+
? snapshot.evidencePlan.map((item) => `- ${item.id}: ${item.status}; ${item.label}`).join("\n")
|
|
93
|
+
: "(none)";
|
|
94
|
+
const latestEvidence = snapshot.latestEvidence
|
|
95
|
+
? `${snapshot.latestEvidence.label}${snapshot.latestEvidence.path ? ` (${snapshot.latestEvidence.path})` : ""}`
|
|
96
|
+
: "(none)";
|
|
97
|
+
return `current_goal_state:\nstatus: ${snapshot.status}\nuser_prerequisites: ${snapshot.userPrerequisites}\nverifier: ${verifier}\nevidence_count: ${snapshot.evidenceCount}\nlatest_evidence: ${latestEvidence}\nblockers:\n${blockers}\nprerequisites:\n${prerequisites}\nevidence_plan:\n${evidencePlan}\ntasks:\n${tasks}`;
|
|
98
|
+
}
|
|
99
|
+
export function buildGoalWorkerSyntheticEventPayload(run, taskTitle, completion) {
|
|
100
|
+
const summary = completion.summary.trim() || "(empty)";
|
|
101
|
+
return {
|
|
102
|
+
version: GOAL_EVENT_PAYLOAD_VERSION,
|
|
103
|
+
kind: "worker",
|
|
104
|
+
runId: run.id,
|
|
105
|
+
goal: run.title,
|
|
106
|
+
taskId: completion.worker.goalTaskId,
|
|
107
|
+
task: taskTitle,
|
|
108
|
+
worker: completion.worker.id,
|
|
109
|
+
workerLogFile: completion.worker.logFile,
|
|
110
|
+
status: completion.status,
|
|
111
|
+
exitCode: completion.exitCode,
|
|
112
|
+
toolsUsed: [...completion.toolsUsed],
|
|
113
|
+
summary,
|
|
114
|
+
goalState: buildGoalStateSnapshot(run),
|
|
115
|
+
...(completion.reason ? { reason: completion.reason } : {}),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
export function formatGoalWorkerCompletionEvent(run, taskTitle, completion) {
|
|
119
|
+
const payload = buildGoalWorkerSyntheticEventPayload(run, taskTitle, completion);
|
|
120
|
+
const toolsUsed = payload.toolsUsed.length > 0
|
|
121
|
+
? payload.toolsUsed.map((tool) => `${tool.ok ? "✓" : "✗"}${tool.name}`).join(", ")
|
|
122
|
+
: "(none)";
|
|
123
|
+
const reason = payload.reason ? ` reason=${payload.reason}` : "";
|
|
124
|
+
return `${GOAL_WORKER_EVENT_PREFIX} run_id="${headerValue(payload.runId)}" goal="${headerValue(payload.goal)}" task_id="${headerValue(payload.taskId)}" task="${headerValue(payload.task)}" worker="${headerValue(payload.worker)}" status=${payload.status} exit_code=${payload.exitCode}${reason}
|
|
125
|
+
${formatPayloadLine(payload)}
|
|
126
|
+
tools_used: ${toolsUsed}
|
|
127
|
+
${formatGoalState(payload.goalState)}
|
|
128
|
+
summary:
|
|
129
|
+
${payload.summary}
|
|
130
|
+
|
|
131
|
+
${GOAL_ORCHESTRATOR_INSTRUCTIONS}`;
|
|
132
|
+
}
|
|
133
|
+
export function buildGoalVerifierSyntheticEventPayload(run, status, command, exitCode, summary) {
|
|
134
|
+
const fixAttempts = run.tasks.filter((task) => task.title === "Fix verifier failure").length;
|
|
135
|
+
const outputPath = run.verifier?.lastResult?.outputPath;
|
|
136
|
+
return {
|
|
137
|
+
version: GOAL_EVENT_PAYLOAD_VERSION,
|
|
138
|
+
kind: "verifier",
|
|
139
|
+
runId: run.id,
|
|
140
|
+
goal: run.title,
|
|
141
|
+
status,
|
|
142
|
+
exitCode,
|
|
143
|
+
command,
|
|
144
|
+
...(outputPath ? { outputPath } : {}),
|
|
145
|
+
fixAttempts,
|
|
146
|
+
fixLimit: DEFAULT_GOAL_VERIFIER_FIX_LIMIT,
|
|
147
|
+
completionGuidance: status === "pass"
|
|
148
|
+
? "Complete only if goals(status) shows success criteria, required evidence, and verifier output match the original objective exactly."
|
|
149
|
+
: "Create one bounded fix task with the verifier command, exit code, output path, and failure summary unless the limit or repeated-failure guard is reached.",
|
|
150
|
+
summary: summary.trim() || "(empty)",
|
|
151
|
+
goalState: buildGoalStateSnapshot(run),
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
export function formatGoalVerifierCompletionEvent(run, status, command, exitCode, summary) {
|
|
155
|
+
const payload = buildGoalVerifierSyntheticEventPayload(run, status, command, exitCode, summary);
|
|
156
|
+
return `${GOAL_VERIFIER_EVENT_PREFIX} run_id="${headerValue(payload.runId)}" goal="${headerValue(payload.goal)}" status=${payload.status} exit_code=${payload.exitCode}
|
|
157
|
+
${formatPayloadLine(payload)}
|
|
158
|
+
command: ${payload.command}
|
|
159
|
+
output_path: ${payload.outputPath ?? "not recorded"}
|
|
160
|
+
fix_attempts: ${payload.fixAttempts}/${payload.fixLimit}
|
|
161
|
+
completion_guidance: ${payload.completionGuidance}
|
|
162
|
+
${formatGoalState(payload.goalState)}
|
|
163
|
+
summary:
|
|
164
|
+
${payload.summary}
|
|
165
|
+
|
|
166
|
+
${GOAL_ORCHESTRATOR_INSTRUCTIONS}`;
|
|
167
|
+
}
|
|
168
|
+
export function isGoalSyntheticEvent(text) {
|
|
169
|
+
return text.startsWith(GOAL_WORKER_EVENT_PREFIX) || text.startsWith(GOAL_VERIFIER_EVENT_PREFIX);
|
|
170
|
+
}
|
|
171
|
+
function isObject(value) {
|
|
172
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
173
|
+
}
|
|
174
|
+
function isStringArray(value) {
|
|
175
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
176
|
+
}
|
|
177
|
+
function isGoalWorkerToolUse(value) {
|
|
178
|
+
return isObject(value) && typeof value.name === "string" && typeof value.ok === "boolean";
|
|
179
|
+
}
|
|
180
|
+
function isGoalWorkerToolUseArray(value) {
|
|
181
|
+
return Array.isArray(value) && value.every(isGoalWorkerToolUse);
|
|
182
|
+
}
|
|
183
|
+
function isGoalStateSnapshot(value) {
|
|
184
|
+
if (!isObject(value))
|
|
185
|
+
return false;
|
|
186
|
+
if (typeof value.status !== "string")
|
|
187
|
+
return false;
|
|
188
|
+
if (typeof value.userPrerequisites !== "string")
|
|
189
|
+
return false;
|
|
190
|
+
if (!isStringArray(value.blockers))
|
|
191
|
+
return false;
|
|
192
|
+
if (!Array.isArray(value.prerequisites))
|
|
193
|
+
return false;
|
|
194
|
+
if (!Array.isArray(value.evidencePlan))
|
|
195
|
+
return false;
|
|
196
|
+
if (!Array.isArray(value.tasks))
|
|
197
|
+
return false;
|
|
198
|
+
if (typeof value.evidenceCount !== "number")
|
|
199
|
+
return false;
|
|
200
|
+
if (value.verifier !== null && value.verifier !== undefined && !isObject(value.verifier)) {
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
if (value.latestEvidence !== undefined && !isObject(value.latestEvidence))
|
|
204
|
+
return false;
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
function isGoalSyntheticEventPayload(value) {
|
|
208
|
+
if (!isObject(value))
|
|
209
|
+
return false;
|
|
210
|
+
if (value.version !== GOAL_EVENT_PAYLOAD_VERSION)
|
|
211
|
+
return false;
|
|
212
|
+
if (value.kind !== "worker" && value.kind !== "verifier")
|
|
213
|
+
return false;
|
|
214
|
+
if (typeof value.runId !== "string")
|
|
215
|
+
return false;
|
|
216
|
+
if (typeof value.goal !== "string")
|
|
217
|
+
return false;
|
|
218
|
+
if (typeof value.status !== "string")
|
|
219
|
+
return false;
|
|
220
|
+
if (typeof value.exitCode !== "number")
|
|
221
|
+
return false;
|
|
222
|
+
if (typeof value.summary !== "string")
|
|
223
|
+
return false;
|
|
224
|
+
if (!isGoalStateSnapshot(value.goalState))
|
|
225
|
+
return false;
|
|
226
|
+
if (value.kind === "worker") {
|
|
227
|
+
return (typeof value.taskId === "string" &&
|
|
228
|
+
typeof value.task === "string" &&
|
|
229
|
+
typeof value.worker === "string" &&
|
|
230
|
+
typeof value.workerLogFile === "string" &&
|
|
231
|
+
isGoalWorkerToolUseArray(value.toolsUsed) &&
|
|
232
|
+
(value.reason === undefined || typeof value.reason === "string"));
|
|
233
|
+
}
|
|
234
|
+
return (typeof value.command === "string" &&
|
|
235
|
+
typeof value.fixAttempts === "number" &&
|
|
236
|
+
typeof value.fixLimit === "number" &&
|
|
237
|
+
typeof value.completionGuidance === "string" &&
|
|
238
|
+
(value.outputPath === undefined || typeof value.outputPath === "string"));
|
|
239
|
+
}
|
|
240
|
+
function parsePayload(text) {
|
|
241
|
+
const payloadLine = text.split("\n").find((line) => line.startsWith(GOAL_EVENT_PAYLOAD_PREFIX));
|
|
242
|
+
if (!payloadLine)
|
|
243
|
+
return null;
|
|
244
|
+
try {
|
|
245
|
+
const parsed = JSON.parse(payloadLine.slice(GOAL_EVENT_PAYLOAD_PREFIX.length));
|
|
246
|
+
return isGoalSyntheticEventPayload(parsed) ? parsed : null;
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
function quotedField(text, field) {
|
|
253
|
+
const match = new RegExp(`${field}="([^"]*)"`).exec(text);
|
|
254
|
+
return match?.[1];
|
|
255
|
+
}
|
|
256
|
+
function tokenField(text, field) {
|
|
257
|
+
const match = new RegExp(`${field}=([^\\s\\n]+)`).exec(text);
|
|
258
|
+
return match?.[1];
|
|
259
|
+
}
|
|
260
|
+
function goalSyntheticEventInfoFromPayload(payload) {
|
|
261
|
+
const base = {
|
|
262
|
+
kind: payload.kind,
|
|
263
|
+
runId: payload.runId,
|
|
264
|
+
goal: payload.goal,
|
|
265
|
+
status: payload.status,
|
|
266
|
+
exitCode: payload.exitCode,
|
|
267
|
+
summary: payload.summary,
|
|
268
|
+
goalState: payload.goalState,
|
|
269
|
+
payload,
|
|
270
|
+
};
|
|
271
|
+
if (payload.kind === "worker") {
|
|
272
|
+
return {
|
|
273
|
+
...base,
|
|
274
|
+
taskId: payload.taskId,
|
|
275
|
+
task: payload.task,
|
|
276
|
+
worker: payload.worker,
|
|
277
|
+
toolsUsed: payload.toolsUsed,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
return {
|
|
281
|
+
...base,
|
|
282
|
+
command: payload.command,
|
|
283
|
+
...(payload.outputPath ? { outputPath: payload.outputPath } : {}),
|
|
284
|
+
fixAttempts: payload.fixAttempts,
|
|
285
|
+
fixLimit: payload.fixLimit,
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
export function parseGoalSyntheticEvent(text) {
|
|
289
|
+
const kind = text.startsWith(GOAL_WORKER_EVENT_PREFIX)
|
|
290
|
+
? "worker"
|
|
291
|
+
: text.startsWith(GOAL_VERIFIER_EVENT_PREFIX)
|
|
292
|
+
? "verifier"
|
|
293
|
+
: null;
|
|
294
|
+
if (kind === null)
|
|
295
|
+
return null;
|
|
296
|
+
const payload = parsePayload(text);
|
|
297
|
+
if (payload)
|
|
298
|
+
return goalSyntheticEventInfoFromPayload(payload);
|
|
299
|
+
const exitCodeRaw = tokenField(text, "exit_code");
|
|
300
|
+
const exitCode = exitCodeRaw === undefined ? undefined : Number(exitCodeRaw);
|
|
301
|
+
return {
|
|
302
|
+
kind,
|
|
303
|
+
...(quotedField(text, "run_id") ? { runId: quotedField(text, "run_id") } : {}),
|
|
304
|
+
...(quotedField(text, "goal") ? { goal: quotedField(text, "goal") } : {}),
|
|
305
|
+
...(quotedField(text, "task_id") ? { taskId: quotedField(text, "task_id") } : {}),
|
|
306
|
+
...(quotedField(text, "task") ? { task: quotedField(text, "task") } : {}),
|
|
307
|
+
...(quotedField(text, "worker") ? { worker: quotedField(text, "worker") } : {}),
|
|
308
|
+
...(tokenField(text, "status") ? { status: tokenField(text, "status") } : {}),
|
|
309
|
+
...(exitCode !== undefined && Number.isFinite(exitCode) ? { exitCode } : {}),
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
export function shouldContinueGoalRun(run) {
|
|
313
|
+
if (run.status === "blocked" ||
|
|
314
|
+
run.status === "paused" ||
|
|
315
|
+
run.status === "passed" ||
|
|
316
|
+
run.status === "failed") {
|
|
317
|
+
return false;
|
|
318
|
+
}
|
|
319
|
+
if (run.activeWorkerId)
|
|
320
|
+
return false;
|
|
321
|
+
return !run.tasks.some((task) => task.status === "running");
|
|
322
|
+
}
|
|
323
|
+
//# sourceMappingURL=goal-events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"goal-events.js","sourceRoot":"","sources":["../../src/ui/goal-events.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"goal-events.test.d.ts","sourceRoot":"","sources":["../../src/ui/goal-events.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { GOAL_EVENT_PAYLOAD_PREFIX, GOAL_VERIFIER_EVENT_PREFIX, GOAL_WORKER_EVENT_PREFIX, buildGoalStateSnapshot, formatGoalVerifierCompletionEvent, formatGoalWorkerCompletionEvent, isGoalSyntheticEvent, parseGoalSyntheticEvent, shouldContinueGoalRun, } from "./goal-events.js";
|
|
3
|
+
function goalRun(overrides = {}) {
|
|
4
|
+
return {
|
|
5
|
+
id: "goal-12345678",
|
|
6
|
+
title: "Fix messy web output",
|
|
7
|
+
goal: "Fix web search and fetch output clarity",
|
|
8
|
+
status: "ready",
|
|
9
|
+
createdAt: "2024-01-01T00:00:00.000Z",
|
|
10
|
+
updatedAt: "2024-01-01T00:00:00.000Z",
|
|
11
|
+
projectPath: "/tmp/project",
|
|
12
|
+
successCriteria: ["Verifier passes"],
|
|
13
|
+
prerequisites: [],
|
|
14
|
+
harness: [],
|
|
15
|
+
evidencePlan: [],
|
|
16
|
+
tasks: [],
|
|
17
|
+
evidence: [],
|
|
18
|
+
blockers: [],
|
|
19
|
+
...overrides,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function workerCompletion(overrides = {}) {
|
|
23
|
+
return {
|
|
24
|
+
worker: {
|
|
25
|
+
id: "worker-a",
|
|
26
|
+
pid: 123,
|
|
27
|
+
goalRunId: "goal-12345678",
|
|
28
|
+
goalTaskId: "task-a",
|
|
29
|
+
cwd: "/tmp/project",
|
|
30
|
+
provider: "anthropic",
|
|
31
|
+
model: "claude-test",
|
|
32
|
+
startedAt: "2024-01-01T00:00:00.000Z",
|
|
33
|
+
logFile: "/tmp/worker.ndjson",
|
|
34
|
+
status: "done",
|
|
35
|
+
exitCode: 0,
|
|
36
|
+
},
|
|
37
|
+
summary: "Changed: web output cleaner\nVerified: npm run typecheck\nStatus: DONE",
|
|
38
|
+
status: "done",
|
|
39
|
+
exitCode: 0,
|
|
40
|
+
toolsUsed: [
|
|
41
|
+
{ name: "read", ok: true },
|
|
42
|
+
{ name: "edit", ok: true },
|
|
43
|
+
{ name: "bash", ok: true },
|
|
44
|
+
],
|
|
45
|
+
...overrides,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
describe("goal event formatting", () => {
|
|
49
|
+
it("formats worker completion as a synthetic orchestrator event", () => {
|
|
50
|
+
const event = formatGoalWorkerCompletionEvent(goalRun(), "Implement cleaner web output", workerCompletion());
|
|
51
|
+
expect(event).toContain(GOAL_WORKER_EVENT_PREFIX);
|
|
52
|
+
expect(event).toContain('run_id="goal-12345678"');
|
|
53
|
+
expect(event).toContain('task_id="task-a"');
|
|
54
|
+
expect(event).toContain('worker="worker-a"');
|
|
55
|
+
expect(event).toContain("status=done");
|
|
56
|
+
expect(event).toContain("exit_code=0");
|
|
57
|
+
expect(event).toContain(GOAL_EVENT_PAYLOAD_PREFIX);
|
|
58
|
+
expect(event).toContain("tools_used: ✓read, ✓edit, ✓bash");
|
|
59
|
+
expect(event).toContain("current_goal_state:");
|
|
60
|
+
expect(event).toContain("user_prerequisites: (none)");
|
|
61
|
+
expect(event).toContain("tasks:\n(none)");
|
|
62
|
+
expect(event).toContain("summary:\nChanged: web output cleaner");
|
|
63
|
+
expect(event).toContain("orchestrator_instructions:");
|
|
64
|
+
expect(event).toContain('Call goals({ action: "status", run_id }) before deciding.');
|
|
65
|
+
expect(event).toContain("Briefly say what the orchestrator is doing");
|
|
66
|
+
expect(isGoalSyntheticEvent(event)).toBe(true);
|
|
67
|
+
expect(parseGoalSyntheticEvent(event)).toMatchObject({
|
|
68
|
+
kind: "worker",
|
|
69
|
+
runId: "goal-12345678",
|
|
70
|
+
goal: "Fix messy web output",
|
|
71
|
+
taskId: "task-a",
|
|
72
|
+
task: "Implement cleaner web output",
|
|
73
|
+
worker: "worker-a",
|
|
74
|
+
status: "done",
|
|
75
|
+
exitCode: 0,
|
|
76
|
+
summary: expect.stringContaining("Changed: web output cleaner"),
|
|
77
|
+
toolsUsed: [
|
|
78
|
+
{ name: "read", ok: true },
|
|
79
|
+
{ name: "edit", ok: true },
|
|
80
|
+
{ name: "bash", ok: true },
|
|
81
|
+
],
|
|
82
|
+
goalState: expect.objectContaining({ status: "ready", evidenceCount: 0 }),
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
it("includes exact user prerequisite instructions in synthetic state", () => {
|
|
86
|
+
const event = formatGoalWorkerCompletionEvent(goalRun({
|
|
87
|
+
status: "blocked",
|
|
88
|
+
prerequisites: [
|
|
89
|
+
{
|
|
90
|
+
id: "supabase-token",
|
|
91
|
+
label: "Supabase token",
|
|
92
|
+
status: "missing",
|
|
93
|
+
instructions: "Provide SUPABASE_ACCESS_TOKEN in chat or the local environment.",
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
}), "Collect prerequisites", workerCompletion());
|
|
97
|
+
expect(event).toContain("user_prerequisites: Supabase token: Provide SUPABASE_ACCESS_TOKEN in chat or the local environment.");
|
|
98
|
+
expect(event).toContain("- supabase-token: missing; Supabase token; instructions=Provide SUPABASE_ACCESS_TOKEN in chat or the local environment.");
|
|
99
|
+
});
|
|
100
|
+
it("formats failed worker completion with failed tool markers", () => {
|
|
101
|
+
const event = formatGoalWorkerCompletionEvent(goalRun(), "Fix verifier failure", workerCompletion({
|
|
102
|
+
status: "failed",
|
|
103
|
+
exitCode: 1,
|
|
104
|
+
summary: "Status: BLOCKED",
|
|
105
|
+
toolsUsed: [{ name: "bash", ok: false }],
|
|
106
|
+
}));
|
|
107
|
+
expect(event).toContain("status=failed");
|
|
108
|
+
expect(event).toContain("exit_code=1");
|
|
109
|
+
expect(event).toContain("tools_used: ✗bash");
|
|
110
|
+
expect(isGoalSyntheticEvent(event)).toBe(true);
|
|
111
|
+
expect(parseGoalSyntheticEvent(event)).toMatchObject({
|
|
112
|
+
kind: "worker",
|
|
113
|
+
status: "failed",
|
|
114
|
+
exitCode: 1,
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
it("formats crashed worker completion as failed synthetic event", () => {
|
|
118
|
+
const event = formatGoalWorkerCompletionEvent(goalRun(), "Run disposable worker", workerCompletion({
|
|
119
|
+
status: "failed",
|
|
120
|
+
exitCode: 1,
|
|
121
|
+
reason: "spawn_error",
|
|
122
|
+
summary: "Failed to spawn Goal worker: spawn exploded",
|
|
123
|
+
toolsUsed: [],
|
|
124
|
+
}));
|
|
125
|
+
expect(event).toContain("status=failed");
|
|
126
|
+
expect(event).toContain("reason=spawn_error");
|
|
127
|
+
expect(event).toContain("Failed to spawn Goal worker: spawn exploded");
|
|
128
|
+
expect(parseGoalSyntheticEvent(event)).toMatchObject({
|
|
129
|
+
kind: "worker",
|
|
130
|
+
runId: "goal-12345678",
|
|
131
|
+
status: "failed",
|
|
132
|
+
exitCode: 1,
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
it("formats stopped worker completion as failed synthetic event when a stop is summarized", () => {
|
|
136
|
+
const event = formatGoalWorkerCompletionEvent(goalRun(), "Stop disposable worker", workerCompletion({
|
|
137
|
+
status: "failed",
|
|
138
|
+
exitCode: 1,
|
|
139
|
+
summary: "Worker stopped by user.",
|
|
140
|
+
worker: { ...workerCompletion().worker, status: "stopped", exitCode: null },
|
|
141
|
+
toolsUsed: [],
|
|
142
|
+
}));
|
|
143
|
+
expect(event).toContain("status=failed");
|
|
144
|
+
expect(event).toContain("Worker stopped by user.");
|
|
145
|
+
expect(parseGoalSyntheticEvent(event)).toMatchObject({
|
|
146
|
+
kind: "worker",
|
|
147
|
+
status: "failed",
|
|
148
|
+
exitCode: 1,
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
it("formats verifier completion as a synthetic orchestrator event", () => {
|
|
152
|
+
const event = formatGoalVerifierCompletionEvent(goalRun(), "pass", "npm run typecheck && node scripts/test-web-tools.mjs", 0, "Verifier passed");
|
|
153
|
+
expect(event).toContain(GOAL_VERIFIER_EVENT_PREFIX);
|
|
154
|
+
expect(event).toContain('run_id="goal-12345678"');
|
|
155
|
+
expect(event).toContain("status=pass");
|
|
156
|
+
expect(event).toContain("exit_code=0");
|
|
157
|
+
expect(event).toContain("command: npm run typecheck && node scripts/test-web-tools.mjs");
|
|
158
|
+
expect(event).toContain("summary:\nVerifier passed");
|
|
159
|
+
expect(event).toContain("current_goal_state:");
|
|
160
|
+
expect(event).toContain("verifier: (none - define an exact verifier before completion)");
|
|
161
|
+
expect(event).toContain("Complete only if goals(status) shows success criteria");
|
|
162
|
+
expect(event).toContain("fix_attempts: 0/5");
|
|
163
|
+
expect(isGoalSyntheticEvent(event)).toBe(true);
|
|
164
|
+
expect(parseGoalSyntheticEvent(event)).toMatchObject({
|
|
165
|
+
kind: "verifier",
|
|
166
|
+
runId: "goal-12345678",
|
|
167
|
+
goal: "Fix messy web output",
|
|
168
|
+
status: "pass",
|
|
169
|
+
exitCode: 0,
|
|
170
|
+
command: "npm run typecheck && node scripts/test-web-tools.mjs",
|
|
171
|
+
fixAttempts: 0,
|
|
172
|
+
fixLimit: 5,
|
|
173
|
+
summary: "Verifier passed",
|
|
174
|
+
goalState: expect.objectContaining({ status: "ready", evidenceCount: 0 }),
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
it("formats verifier failure as corrective orchestrator input", () => {
|
|
178
|
+
const event = formatGoalVerifierCompletionEvent(goalRun(), "fail", "pnpm test", 1, "Verifier failed");
|
|
179
|
+
expect(event).toContain("status=fail");
|
|
180
|
+
expect(event).toContain("exit_code=1");
|
|
181
|
+
expect(event).toContain("Verifier failed");
|
|
182
|
+
expect(event).toContain("Inspect durable tasks, verifier state, blockers, and evidence.");
|
|
183
|
+
expect(parseGoalSyntheticEvent(event)).toMatchObject({
|
|
184
|
+
kind: "verifier",
|
|
185
|
+
runId: "goal-12345678",
|
|
186
|
+
goal: "Fix messy web output",
|
|
187
|
+
status: "fail",
|
|
188
|
+
exitCode: 1,
|
|
189
|
+
command: "pnpm test",
|
|
190
|
+
summary: "Verifier failed",
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
it("round-trips structured payloads containing quotes and newlines", () => {
|
|
194
|
+
const run = goalRun({
|
|
195
|
+
title: 'Fix "quoted" output',
|
|
196
|
+
tasks: [
|
|
197
|
+
{
|
|
198
|
+
id: "task-a",
|
|
199
|
+
title: 'Handle "quotes"',
|
|
200
|
+
prompt: "Do work",
|
|
201
|
+
status: "done",
|
|
202
|
+
attempts: 1,
|
|
203
|
+
},
|
|
204
|
+
],
|
|
205
|
+
evidence: [
|
|
206
|
+
{
|
|
207
|
+
id: "evidence-a",
|
|
208
|
+
kind: "log",
|
|
209
|
+
label: "Verifier log",
|
|
210
|
+
path: "artifacts/goal.log",
|
|
211
|
+
content: "ok",
|
|
212
|
+
createdAt: "2024-01-01T00:00:00.000Z",
|
|
213
|
+
},
|
|
214
|
+
],
|
|
215
|
+
});
|
|
216
|
+
const event = formatGoalWorkerCompletionEvent(run, 'Handle "quotes"', workerCompletion({ summary: 'Line one\nLine "two"' }));
|
|
217
|
+
const parsed = parseGoalSyntheticEvent(event);
|
|
218
|
+
expect(parsed).toMatchObject({
|
|
219
|
+
kind: "worker",
|
|
220
|
+
goal: 'Fix "quoted" output',
|
|
221
|
+
task: 'Handle "quotes"',
|
|
222
|
+
summary: 'Line one\nLine "two"',
|
|
223
|
+
goalState: expect.objectContaining({
|
|
224
|
+
evidenceCount: 1,
|
|
225
|
+
latestEvidence: expect.objectContaining({ path: "artifacts/goal.log" }),
|
|
226
|
+
}),
|
|
227
|
+
});
|
|
228
|
+
expect(parsed?.payload?.kind).toBe("worker");
|
|
229
|
+
});
|
|
230
|
+
it("builds a compact typed goal state snapshot for orchestrator review", () => {
|
|
231
|
+
const snapshot = buildGoalStateSnapshot(goalRun({
|
|
232
|
+
status: "blocked",
|
|
233
|
+
blockers: ["Need token"],
|
|
234
|
+
prerequisites: [
|
|
235
|
+
{
|
|
236
|
+
id: "token",
|
|
237
|
+
label: "API token",
|
|
238
|
+
status: "missing",
|
|
239
|
+
instructions: "Provide API_TOKEN.",
|
|
240
|
+
},
|
|
241
|
+
],
|
|
242
|
+
evidencePlan: [
|
|
243
|
+
{
|
|
244
|
+
id: "verifier-log",
|
|
245
|
+
label: "Verifier log",
|
|
246
|
+
mechanism: "command",
|
|
247
|
+
description: "Verifier output",
|
|
248
|
+
status: "planned",
|
|
249
|
+
command: "pnpm test",
|
|
250
|
+
},
|
|
251
|
+
],
|
|
252
|
+
}));
|
|
253
|
+
expect(snapshot).toMatchObject({
|
|
254
|
+
status: "blocked",
|
|
255
|
+
userPrerequisites: "API token: Provide API_TOKEN.",
|
|
256
|
+
blockers: ["Need token"],
|
|
257
|
+
prerequisites: [expect.objectContaining({ id: "token", status: "missing" })],
|
|
258
|
+
evidencePlan: [expect.objectContaining({ id: "verifier-log", command: "pnpm test" })],
|
|
259
|
+
evidenceCount: 0,
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
it("classifies only prefixed worker/verifier pings as synthetic events so display can hide them", () => {
|
|
263
|
+
expect(isGoalSyntheticEvent(formatGoalWorkerCompletionEvent(goalRun(), "Task", workerCompletion()))).toBe(true);
|
|
264
|
+
expect(isGoalSyntheticEvent(formatGoalVerifierCompletionEvent(goalRun(), "fail", "pnpm test", 1, "Verifier failed"))).toBe(true);
|
|
265
|
+
expect(isGoalSyntheticEvent("Please inspect the goal")).toBe(false);
|
|
266
|
+
expect(isGoalSyntheticEvent(`note ${GOAL_WORKER_EVENT_PREFIX}`)).toBe(false);
|
|
267
|
+
expect(parseGoalSyntheticEvent("Please inspect the goal")).toBeNull();
|
|
268
|
+
});
|
|
269
|
+
it("continues non-terminal goals that have no active worker or running task", () => {
|
|
270
|
+
expect(shouldContinueGoalRun(goalRun({ status: "ready" }))).toBe(true);
|
|
271
|
+
expect(shouldContinueGoalRun(goalRun({ status: "running" }))).toBe(true);
|
|
272
|
+
expect(shouldContinueGoalRun(goalRun({ status: "verifying" }))).toBe(true);
|
|
273
|
+
});
|
|
274
|
+
it("does not continue terminal or already-active goals", () => {
|
|
275
|
+
expect(shouldContinueGoalRun(goalRun({ status: "blocked" }))).toBe(false);
|
|
276
|
+
expect(shouldContinueGoalRun(goalRun({ status: "paused" }))).toBe(false);
|
|
277
|
+
expect(shouldContinueGoalRun(goalRun({ status: "passed" }))).toBe(false);
|
|
278
|
+
expect(shouldContinueGoalRun(goalRun({ status: "failed" }))).toBe(false);
|
|
279
|
+
expect(shouldContinueGoalRun(goalRun({ activeWorkerId: "worker-a" }))).toBe(false);
|
|
280
|
+
expect(shouldContinueGoalRun(goalRun({
|
|
281
|
+
tasks: [
|
|
282
|
+
{
|
|
283
|
+
id: "task-a",
|
|
284
|
+
title: "Running task",
|
|
285
|
+
prompt: "Do work",
|
|
286
|
+
status: "running",
|
|
287
|
+
attempts: 1,
|
|
288
|
+
},
|
|
289
|
+
],
|
|
290
|
+
}))).toBe(false);
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
//# sourceMappingURL=goal-events.test.js.map
|