@oh-my-pi/pi-coding-agent 3.30.0 → 3.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +71 -0
- package/package.json +5 -5
- package/src/cli/args.ts +4 -0
- package/src/core/agent-session.ts +29 -2
- package/src/core/bash-executor.ts +2 -1
- package/src/core/custom-commands/bundled/review/index.ts +369 -14
- package/src/core/custom-commands/bundled/wt/index.ts +1 -1
- package/src/core/session-manager.ts +158 -246
- package/src/core/session-storage.ts +379 -0
- package/src/core/settings-manager.ts +155 -4
- package/src/core/system-prompt.ts +62 -64
- package/src/core/tools/ask.ts +5 -4
- package/src/core/tools/bash-interceptor.ts +26 -61
- package/src/core/tools/bash.ts +13 -8
- package/src/core/tools/edit-diff.ts +11 -4
- package/src/core/tools/edit.ts +7 -13
- package/src/core/tools/find.ts +111 -50
- package/src/core/tools/gemini-image.ts +128 -147
- package/src/core/tools/grep.ts +397 -415
- package/src/core/tools/index.test.ts +5 -1
- package/src/core/tools/index.ts +6 -8
- package/src/core/tools/ls.ts +12 -10
- package/src/core/tools/lsp/client.ts +58 -9
- package/src/core/tools/lsp/config.ts +205 -656
- package/src/core/tools/lsp/defaults.json +465 -0
- package/src/core/tools/lsp/index.ts +55 -32
- package/src/core/tools/lsp/rust-analyzer.ts +49 -10
- package/src/core/tools/lsp/types.ts +1 -0
- package/src/core/tools/lsp/utils.ts +1 -1
- package/src/core/tools/read.ts +150 -74
- package/src/core/tools/render-utils.ts +70 -10
- package/src/core/tools/review.ts +38 -126
- package/src/core/tools/task/artifacts.ts +5 -4
- package/src/core/tools/task/executor.ts +94 -83
- package/src/core/tools/task/index.ts +129 -92
- package/src/core/tools/task/parallel.ts +30 -3
- package/src/core/tools/task/render.ts +85 -39
- package/src/core/tools/task/types.ts +15 -6
- package/src/core/tools/task/worker.ts +124 -89
- package/src/core/tools/web-fetch.ts +112 -377
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/artifacthub.ts +6 -1
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/arxiv.ts +8 -4
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/aur.ts +6 -2
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/biorxiv.ts +6 -1
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/bluesky.ts +10 -3
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/brew.ts +6 -2
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/cheatsh.ts +6 -1
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/chocolatey.ts +6 -1
- package/src/core/tools/web-scrapers/choosealicense.ts +110 -0
- package/src/core/tools/web-scrapers/cisa-kev.ts +100 -0
- package/src/core/tools/web-scrapers/clojars.ts +180 -0
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/coingecko.ts +6 -1
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/crates-io.ts +7 -2
- package/src/core/tools/web-scrapers/crossref.ts +149 -0
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/devto.ts +8 -4
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/discogs.ts +6 -1
- package/src/core/tools/web-scrapers/discourse.ts +221 -0
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/dockerhub.ts +7 -3
- package/src/core/tools/web-scrapers/fdroid.ts +158 -0
- package/src/core/tools/web-scrapers/firefox-addons.ts +214 -0
- package/src/core/tools/web-scrapers/flathub.ts +239 -0
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/github-gist.ts +6 -2
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/github.ts +63 -32
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/gitlab.ts +31 -19
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/go-pkg.ts +8 -4
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/hackage.ts +6 -1
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/hackernews.ts +18 -18
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/hex.ts +3 -3
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/huggingface.ts +10 -10
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/iacr.ts +8 -4
- package/src/core/tools/web-scrapers/index.ts +250 -0
- package/src/core/tools/web-scrapers/jetbrains-marketplace.ts +169 -0
- package/src/core/tools/web-scrapers/lemmy.ts +220 -0
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/lobsters.ts +3 -3
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/mastodon.ts +11 -3
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/maven.ts +6 -1
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/mdn.ts +2 -2
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/metacpan.ts +13 -7
- package/src/core/tools/web-scrapers/musicbrainz.ts +273 -0
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/npm.ts +12 -5
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/nuget.ts +9 -5
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/nvd.ts +6 -1
- package/src/core/tools/web-scrapers/ollama.ts +267 -0
- package/src/core/tools/web-scrapers/open-vsx.ts +119 -0
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/opencorporates.ts +2 -0
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/openlibrary.ts +18 -12
- package/src/core/tools/web-scrapers/orcid.ts +299 -0
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/osv.ts +6 -1
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/packagist.ts +6 -2
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/pub-dev.ts +3 -3
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/pubmed.ts +8 -4
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/pypi.ts +7 -3
- package/src/core/tools/web-scrapers/rawg.ts +124 -0
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/readthedocs.ts +7 -3
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/reddit.ts +6 -2
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/repology.ts +6 -1
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/rfc.ts +7 -3
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/rubygems.ts +6 -1
- package/src/core/tools/web-scrapers/searchcode.ts +217 -0
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/sec-edgar.ts +6 -1
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/semantic-scholar.ts +2 -2
- package/src/core/tools/web-scrapers/snapcraft.ts +200 -0
- package/src/core/tools/web-scrapers/sourcegraph.ts +373 -0
- package/src/core/tools/web-scrapers/spdx.ts +121 -0
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/spotify.ts +3 -3
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/stackoverflow.ts +3 -2
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/terraform.ts +11 -3
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/tldr.ts +6 -2
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/twitter.ts +15 -3
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/types.ts +98 -27
- package/src/core/tools/web-scrapers/utils.ts +162 -0
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/vimeo.ts +3 -3
- package/src/core/tools/web-scrapers/vscode-marketplace.ts +195 -0
- package/src/core/tools/web-scrapers/w3c.ts +163 -0
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/wikidata.ts +13 -5
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/wikipedia.ts +7 -3
- package/src/core/tools/{web-fetch-handlers → web-scrapers}/youtube.ts +72 -20
- package/src/core/tools/write.ts +21 -18
- package/src/core/voice.ts +3 -2
- package/src/lib/worktree/collapse.ts +2 -1
- package/src/lib/worktree/git.ts +2 -18
- package/src/main.ts +59 -3
- package/src/modes/interactive/components/extensions/extension-dashboard.ts +33 -19
- package/src/modes/interactive/components/extensions/extension-list.ts +15 -8
- package/src/modes/interactive/components/hook-editor.ts +2 -1
- package/src/modes/interactive/components/model-selector.ts +19 -4
- package/src/modes/interactive/interactive-mode.ts +41 -38
- package/src/modes/interactive/theme/theme.ts +58 -58
- package/src/modes/rpc/rpc-mode.ts +10 -9
- package/src/prompts/review-request.md +27 -0
- package/src/prompts/reviewer.md +64 -68
- package/src/prompts/tools/output.md +22 -3
- package/src/prompts/tools/task.md +32 -33
- package/src/utils/clipboard.ts +2 -1
- package/examples/extensions/subagent/agents/reviewer.md +0 -35
- package/src/core/tools/web-fetch-handlers/index.ts +0 -69
- package/src/core/tools/web-fetch-handlers/utils.ts +0 -91
- /package/src/core/tools/{web-fetch-handlers → web-scrapers}/academic.test.ts +0 -0
- /package/src/core/tools/{web-fetch-handlers → web-scrapers}/business.test.ts +0 -0
- /package/src/core/tools/{web-fetch-handlers → web-scrapers}/dev-platforms.test.ts +0 -0
- /package/src/core/tools/{web-fetch-handlers → web-scrapers}/documentation.test.ts +0 -0
- /package/src/core/tools/{web-fetch-handlers → web-scrapers}/finance-media.test.ts +0 -0
- /package/src/core/tools/{web-fetch-handlers → web-scrapers}/git-hosting.test.ts +0 -0
- /package/src/core/tools/{web-fetch-handlers → web-scrapers}/media.test.ts +0 -0
- /package/src/core/tools/{web-fetch-handlers → web-scrapers}/package-managers-2.test.ts +0 -0
- /package/src/core/tools/{web-fetch-handlers → web-scrapers}/package-managers.test.ts +0 -0
- /package/src/core/tools/{web-fetch-handlers → web-scrapers}/package-registries.test.ts +0 -0
- /package/src/core/tools/{web-fetch-handlers → web-scrapers}/research.test.ts +0 -0
- /package/src/core/tools/{web-fetch-handlers → web-scrapers}/security.test.ts +0 -0
- /package/src/core/tools/{web-fetch-handlers → web-scrapers}/social-extended.test.ts +0 -0
- /package/src/core/tools/{web-fetch-handlers → web-scrapers}/social.test.ts +0 -0
- /package/src/core/tools/{web-fetch-handlers → web-scrapers}/stackexchange.test.ts +0 -0
- /package/src/core/tools/{web-fetch-handlers → web-scrapers}/standards.test.ts +0 -0
- /package/src/core/tools/{web-fetch-handlers → web-scrapers}/wikipedia.test.ts +0 -0
- /package/src/core/tools/{web-fetch-handlers → web-scrapers}/youtube.test.ts +0 -0
|
@@ -19,6 +19,7 @@ import type { AgentSessionEvent } from "../../agent-session";
|
|
|
19
19
|
import { parseModelPattern, parseModelString } from "../../model-resolver";
|
|
20
20
|
import { createAgentSession, discoverAuthStorage, discoverModels } from "../../sdk";
|
|
21
21
|
import { SessionManager } from "../../session-manager";
|
|
22
|
+
import { untilAborted } from "../../utils";
|
|
22
23
|
import type { SubagentWorkerRequest, SubagentWorkerResponse, SubagentWorkerStartPayload } from "./worker-protocol";
|
|
23
24
|
|
|
24
25
|
type PostMessageFn = (message: SubagentWorkerResponse) => void;
|
|
@@ -53,11 +54,33 @@ const isAgentEvent = (event: AgentSessionEvent): event is AgentEvent => {
|
|
|
53
54
|
return agentEventTypes.has(event.type as AgentEvent["type"]);
|
|
54
55
|
};
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
interface RunState {
|
|
58
|
+
abortController: AbortController;
|
|
59
|
+
startTime: number;
|
|
60
|
+
session: { abort: () => Promise<void>; dispose: () => Promise<void> } | null;
|
|
61
|
+
unsubscribe: (() => void) | null;
|
|
62
|
+
sendDoneOnce: (message: Extract<SubagentWorkerResponse, { type: "done" }>) => void;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const createSendDoneOnce = (): RunState["sendDoneOnce"] => {
|
|
66
|
+
let sent = false;
|
|
67
|
+
return (message) => {
|
|
68
|
+
if (sent) return;
|
|
69
|
+
sent = true;
|
|
70
|
+
postMessageSafe(message);
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const createRunState = (): RunState => ({
|
|
75
|
+
abortController: new AbortController(),
|
|
76
|
+
startTime: Date.now(),
|
|
77
|
+
session: null,
|
|
78
|
+
unsubscribe: null,
|
|
79
|
+
sendDoneOnce: createSendDoneOnce(),
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
let activeRun: RunState | null = null;
|
|
83
|
+
let pendingAbort = false;
|
|
61
84
|
|
|
62
85
|
/**
|
|
63
86
|
* Resolve model string to Model object with optional thinking level.
|
|
@@ -98,26 +121,35 @@ function resolveModelOverride(
|
|
|
98
121
|
* - OMP_BLOCKED_AGENT: payload.blockedAgent (prevents same-agent recursion)
|
|
99
122
|
* - OMP_SPAWNS: payload.spawnsEnv (controls nested spawn permissions)
|
|
100
123
|
*/
|
|
101
|
-
async function runTask(payload: SubagentWorkerStartPayload): Promise<void> {
|
|
102
|
-
const
|
|
124
|
+
async function runTask(runState: RunState, payload: SubagentWorkerStartPayload): Promise<void> {
|
|
125
|
+
const { signal } = runState.abortController;
|
|
126
|
+
const startTime = runState.startTime;
|
|
103
127
|
let exitCode = 0;
|
|
104
128
|
let error: string | undefined;
|
|
105
129
|
let aborted = false;
|
|
130
|
+
const sessionAbortController = new AbortController();
|
|
106
131
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
if (
|
|
132
|
+
// Helper to check abort status - throws if aborted to exit early
|
|
133
|
+
const checkAbort = (): void => {
|
|
134
|
+
if (signal.aborted) {
|
|
110
135
|
aborted = true;
|
|
111
136
|
exitCode = 1;
|
|
112
|
-
|
|
137
|
+
throw new Error("Aborted");
|
|
113
138
|
}
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
try {
|
|
142
|
+
// Check for pre-start abort
|
|
143
|
+
checkAbort();
|
|
114
144
|
|
|
115
145
|
// Set working directory (CLI does this implicitly)
|
|
116
146
|
process.chdir(payload.cwd);
|
|
117
147
|
|
|
118
148
|
// Discover auth and models (equivalent to CLI's discoverAuthStorage/discoverModels)
|
|
119
149
|
const authStorage = await discoverAuthStorage();
|
|
150
|
+
checkAbort();
|
|
120
151
|
const modelRegistry = await discoverModels(authStorage);
|
|
152
|
+
checkAbort();
|
|
121
153
|
|
|
122
154
|
// Resolve model override (equivalent to CLI's parseModelPattern with --model)
|
|
123
155
|
const { model, thinkingLevel } = resolveModelOverride(payload.model, modelRegistry);
|
|
@@ -126,6 +158,7 @@ async function runTask(payload: SubagentWorkerStartPayload): Promise<void> {
|
|
|
126
158
|
const sessionManager = payload.sessionFile
|
|
127
159
|
? await SessionManager.open(payload.sessionFile)
|
|
128
160
|
: SessionManager.inMemory(payload.cwd);
|
|
161
|
+
checkAbort();
|
|
129
162
|
|
|
130
163
|
// Create agent session (equivalent to CLI's createAgentSession)
|
|
131
164
|
// Note: hasUI: false disables interactive features
|
|
@@ -149,18 +182,16 @@ async function runTask(payload: SubagentWorkerStartPayload): Promise<void> {
|
|
|
149
182
|
spawns: payload.spawnsEnv,
|
|
150
183
|
});
|
|
151
184
|
|
|
152
|
-
|
|
185
|
+
runState.session = session;
|
|
186
|
+
checkAbort();
|
|
153
187
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
188
|
+
signal.addEventListener(
|
|
189
|
+
"abort",
|
|
190
|
+
() => {
|
|
191
|
+
void session.abort();
|
|
192
|
+
},
|
|
193
|
+
{ once: true, signal: sessionAbortController.signal },
|
|
194
|
+
);
|
|
164
195
|
|
|
165
196
|
// Initialize extensions (equivalent to CLI's extension initialization)
|
|
166
197
|
// Note: Does not support --extension CLI flag or extension CLI flags
|
|
@@ -191,7 +222,7 @@ async function runTask(payload: SubagentWorkerStartPayload): Promise<void> {
|
|
|
191
222
|
let completeCalled = false;
|
|
192
223
|
|
|
193
224
|
// Subscribe to events and forward to parent (equivalent to --mode json output)
|
|
194
|
-
unsubscribe = session.subscribe((event: AgentSessionEvent) => {
|
|
225
|
+
runState.unsubscribe = session.subscribe((event: AgentSessionEvent) => {
|
|
195
226
|
if (isAgentEvent(event)) {
|
|
196
227
|
postMessageSafe({ type: "event", event });
|
|
197
228
|
// Track when complete tool is called
|
|
@@ -206,7 +237,7 @@ async function runTask(payload: SubagentWorkerStartPayload): Promise<void> {
|
|
|
206
237
|
|
|
207
238
|
// Retry loop if complete was not called
|
|
208
239
|
let retryCount = 0;
|
|
209
|
-
while (!completeCalled && retryCount < MAX_COMPLETE_RETRIES && !
|
|
240
|
+
while (!completeCalled && retryCount < MAX_COMPLETE_RETRIES && !signal.aborted) {
|
|
210
241
|
retryCount++;
|
|
211
242
|
const reminder = `<system-reminder>
|
|
212
243
|
CRITICAL: You stopped without calling the complete tool. This is reminder ${retryCount} of ${MAX_COMPLETE_RETRIES}.
|
|
@@ -231,58 +262,93 @@ Call complete now.`;
|
|
|
231
262
|
}
|
|
232
263
|
} catch (err) {
|
|
233
264
|
exitCode = 1;
|
|
234
|
-
|
|
265
|
+
// Don't record abort as error - it's handled via the aborted flag
|
|
266
|
+
if (!signal.aborted) {
|
|
267
|
+
error = err instanceof Error ? err.stack || err.message : String(err);
|
|
268
|
+
}
|
|
235
269
|
} finally {
|
|
236
270
|
// Handle abort requested during execution
|
|
237
|
-
if (
|
|
271
|
+
if (signal.aborted) {
|
|
238
272
|
aborted = true;
|
|
239
273
|
if (exitCode === 0) exitCode = 1;
|
|
240
274
|
}
|
|
241
275
|
|
|
242
|
-
|
|
276
|
+
sessionAbortController.abort();
|
|
277
|
+
|
|
278
|
+
if (runState.unsubscribe) {
|
|
243
279
|
try {
|
|
244
|
-
unsubscribe();
|
|
280
|
+
runState.unsubscribe();
|
|
245
281
|
} catch {
|
|
246
282
|
// Ignore unsubscribe errors
|
|
247
283
|
}
|
|
248
|
-
unsubscribe = null;
|
|
284
|
+
runState.unsubscribe = null;
|
|
249
285
|
}
|
|
250
286
|
|
|
251
287
|
// Cleanup session with timeout to prevent hanging
|
|
252
|
-
if (
|
|
253
|
-
const session =
|
|
254
|
-
|
|
288
|
+
if (runState.session) {
|
|
289
|
+
const session = runState.session;
|
|
290
|
+
runState.session = null;
|
|
255
291
|
try {
|
|
256
|
-
await
|
|
292
|
+
await untilAborted(AbortSignal.timeout(5000), () => session.dispose());
|
|
257
293
|
} catch {
|
|
258
294
|
// Ignore cleanup errors
|
|
259
295
|
}
|
|
260
296
|
}
|
|
261
297
|
|
|
262
|
-
|
|
298
|
+
if (activeRun === runState) {
|
|
299
|
+
activeRun = null;
|
|
300
|
+
}
|
|
263
301
|
|
|
264
302
|
// Send completion message to parent (only once)
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
aborted,
|
|
273
|
-
});
|
|
274
|
-
}
|
|
303
|
+
runState.sendDoneOnce({
|
|
304
|
+
type: "done",
|
|
305
|
+
exitCode,
|
|
306
|
+
durationMs: Date.now() - startTime,
|
|
307
|
+
error,
|
|
308
|
+
aborted,
|
|
309
|
+
});
|
|
275
310
|
}
|
|
276
311
|
}
|
|
277
312
|
|
|
278
313
|
/** Handle abort request from parent */
|
|
279
314
|
function handleAbort(): void {
|
|
280
|
-
|
|
281
|
-
if (
|
|
282
|
-
|
|
315
|
+
const runState = activeRun;
|
|
316
|
+
if (!runState) {
|
|
317
|
+
pendingAbort = true;
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
runState.abortController.abort();
|
|
321
|
+
if (runState.session) {
|
|
322
|
+
void runState.session.abort();
|
|
283
323
|
}
|
|
284
324
|
}
|
|
285
325
|
|
|
326
|
+
const reportFatal = (message: string): void => {
|
|
327
|
+
const runState = activeRun;
|
|
328
|
+
if (runState) {
|
|
329
|
+
runState.abortController.abort();
|
|
330
|
+
if (runState.session) {
|
|
331
|
+
void runState.session.abort();
|
|
332
|
+
}
|
|
333
|
+
runState.sendDoneOnce({
|
|
334
|
+
type: "done",
|
|
335
|
+
exitCode: 1,
|
|
336
|
+
durationMs: Date.now() - runState.startTime,
|
|
337
|
+
error: message,
|
|
338
|
+
aborted: false,
|
|
339
|
+
});
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
postMessageSafe({
|
|
344
|
+
type: "done",
|
|
345
|
+
exitCode: 1,
|
|
346
|
+
durationMs: 0,
|
|
347
|
+
error: message,
|
|
348
|
+
aborted: false,
|
|
349
|
+
});
|
|
350
|
+
};
|
|
351
|
+
|
|
286
352
|
// Global error handlers to ensure we always send a done message
|
|
287
353
|
// Using self instead of globalThis for proper worker scope typing
|
|
288
354
|
declare const self: {
|
|
@@ -292,53 +358,17 @@ declare const self: {
|
|
|
292
358
|
};
|
|
293
359
|
|
|
294
360
|
self.addEventListener("error", (event) => {
|
|
295
|
-
|
|
296
|
-
doneSent = true;
|
|
297
|
-
abortRequested = true;
|
|
298
|
-
if (activeSession) {
|
|
299
|
-
void activeSession.abort();
|
|
300
|
-
}
|
|
301
|
-
postMessageSafe({
|
|
302
|
-
type: "done",
|
|
303
|
-
exitCode: 1,
|
|
304
|
-
durationMs: 0,
|
|
305
|
-
error: `Uncaught error: ${event.message || "Unknown error"}`,
|
|
306
|
-
aborted: false,
|
|
307
|
-
});
|
|
361
|
+
reportFatal(`Uncaught error: ${event.message || "Unknown error"}`);
|
|
308
362
|
});
|
|
309
363
|
|
|
310
364
|
self.addEventListener("unhandledrejection", (event) => {
|
|
311
|
-
if (!running || doneSent) return;
|
|
312
|
-
doneSent = true;
|
|
313
|
-
abortRequested = true;
|
|
314
|
-
if (activeSession) {
|
|
315
|
-
void activeSession.abort();
|
|
316
|
-
}
|
|
317
365
|
const reason = event.reason;
|
|
318
366
|
const message = reason instanceof Error ? reason.stack || reason.message : String(reason);
|
|
319
|
-
|
|
320
|
-
type: "done",
|
|
321
|
-
exitCode: 1,
|
|
322
|
-
durationMs: 0,
|
|
323
|
-
error: `Unhandled rejection: ${message}`,
|
|
324
|
-
aborted: false,
|
|
325
|
-
});
|
|
367
|
+
reportFatal(`Unhandled rejection: ${message}`);
|
|
326
368
|
});
|
|
327
369
|
|
|
328
370
|
self.addEventListener("messageerror", () => {
|
|
329
|
-
|
|
330
|
-
doneSent = true;
|
|
331
|
-
abortRequested = true;
|
|
332
|
-
if (activeSession) {
|
|
333
|
-
void activeSession.abort();
|
|
334
|
-
}
|
|
335
|
-
postMessageSafe({
|
|
336
|
-
type: "done",
|
|
337
|
-
exitCode: 1,
|
|
338
|
-
durationMs: 0,
|
|
339
|
-
error: "Failed to deserialize parent message",
|
|
340
|
-
aborted: false,
|
|
341
|
-
});
|
|
371
|
+
reportFatal("Failed to deserialize parent message");
|
|
342
372
|
});
|
|
343
373
|
|
|
344
374
|
// Message handler - receives start/abort commands from parent
|
|
@@ -353,8 +383,13 @@ globalThis.addEventListener("message", (event: WorkerMessageEvent<SubagentWorker
|
|
|
353
383
|
|
|
354
384
|
if (message.type === "start") {
|
|
355
385
|
// Only allow one task per worker
|
|
356
|
-
if (
|
|
357
|
-
|
|
358
|
-
|
|
386
|
+
if (activeRun) return;
|
|
387
|
+
const runState = createRunState();
|
|
388
|
+
if (pendingAbort) {
|
|
389
|
+
pendingAbort = false;
|
|
390
|
+
runState.abortController.abort();
|
|
391
|
+
}
|
|
392
|
+
activeRun = runState;
|
|
393
|
+
void runTask(runState, message.payload);
|
|
359
394
|
}
|
|
360
395
|
});
|