@sideboard-ai/core 0.1.135 → 0.1.139
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/{agents-RTQFF7PY.js → agents-665S7Z3R.js} +5 -5
- package/dist/{agents-O3AJMI2Y.js → agents-OC3XM7UE.js} +5 -5
- package/dist/{chunk-KBBXNS2V.js → chunk-23KCPND2.js} +49 -6
- package/dist/{chunk-2ESCEK2Q.js → chunk-5XH5M6RA.js} +244 -5
- package/dist/{chunk-57GIFU3X.js → chunk-7SYFWPOZ.js} +5 -5
- package/dist/{chunk-N62K3KXX.js → chunk-CDJISVKN.js} +79 -6
- package/dist/{chunk-QAV3HGVS.js → chunk-DJJ3DTT4.js} +1 -1
- package/dist/{chunk-HQQNLDVC.js → chunk-DKXZCIB2.js} +1 -1
- package/dist/{chunk-XUEI4GCF.js → chunk-E2RE7P2S.js} +286 -5
- package/dist/{chunk-J5IBSVB3.js → chunk-EUXOHTUK.js} +42 -25
- package/dist/{chunk-RDULVW3E.js → chunk-HLIHBGVO.js} +2 -2
- package/dist/{chunk-K7EX47QG.js → chunk-RTX3AY42.js} +5 -5
- package/dist/{chunk-LOKXPQ4U.js → chunk-SSBM4GZX.js} +2 -2
- package/dist/{chunk-PM3C2J6K.js → chunk-TUGKX5BD.js} +42 -25
- package/dist/{chunk-Z5LYMW7M.js → chunk-YZQEJOAU.js} +189 -248
- package/dist/{chunk-XIKEUCNC.js → chunk-ZCLHAOFR.js} +211 -299
- package/dist/{coordinator-prompt-FYMWE33S.js → coordinator-prompt-43O6EPA2.js} +3 -3
- package/dist/{coordinator-prompt-Y737IIFR.js → coordinator-prompt-4TXU6Q3R.js} +3 -3
- package/dist/{global-workspace-6KH6BSKL.js → global-workspace-VIU57E3Y.js} +4 -4
- package/dist/{global-workspace-ZFKNLBZA.js → global-workspace-ZDYKHQ4O.js} +4 -4
- package/dist/index.cjs +1019 -670
- package/dist/index.d.cts +41 -3
- package/dist/index.d.ts +41 -3
- package/dist/index.js +83 -24
- package/dist/mcp/run-stdio.cjs +831 -544
- package/dist/mcp/run-stdio.js +55 -16
- package/dist/{orchestrator-3YDPPZHZ.js → orchestrator-WEFXUHFX.js} +7 -7
- package/dist/{orchestrator-2BRAPJ47.js → orchestrator-ZCMYSDTC.js} +7 -7
- package/dist/{thread-store-FADXSMEJ.js → thread-store-57ZLHR3A.js} +1 -1
- package/dist/{thread-store-CRLQJ2HM.js → thread-store-WGASXXXR.js} +1 -1
- package/dist/{workspaces-3RRF3LVF.js → workspaces-4HYGNH4B.js} +5 -5
- package/dist/{workspaces-AYI5DHK4.js → workspaces-ALCTB65T.js} +5 -5
- package/dist/{worktree-MX7XBX6Z.js → worktree-GXD2NGOZ.js} +2 -2
- package/dist/{worktree-BC6XDMQK.js → worktree-NSNZODAM.js} +2 -2
- package/package.json +1 -1
|
@@ -18,15 +18,16 @@ import {
|
|
|
18
18
|
stripBrightsyNdjsonNoise,
|
|
19
19
|
sumUsageList,
|
|
20
20
|
toolDescription
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-CDJISVKN.js";
|
|
22
22
|
import {
|
|
23
23
|
addWorkspace,
|
|
24
24
|
ensureWorkspace,
|
|
25
25
|
removeWorkspace,
|
|
26
26
|
syncWorkspacesFromThreads
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-SSBM4GZX.js";
|
|
28
28
|
import {
|
|
29
29
|
assertOrchestratorCapableAgent,
|
|
30
|
+
attachmentsFromWorktreePaths,
|
|
30
31
|
coerceOrchestratorAgent,
|
|
31
32
|
createGlobalChat,
|
|
32
33
|
healOrchestrationSoccerTitles,
|
|
@@ -36,15 +37,18 @@ import {
|
|
|
36
37
|
isOrchestratorCapableAgent,
|
|
37
38
|
isOrchestratorThread,
|
|
38
39
|
isSlackCoordinatorThread,
|
|
39
|
-
orchestratorSessionPoisonedByBuiltins
|
|
40
|
-
|
|
40
|
+
orchestratorSessionPoisonedByBuiltins,
|
|
41
|
+
persistPendingFileAttachments,
|
|
42
|
+
stageAbsolutePathsAsAttachments,
|
|
43
|
+
stageBuffersAsAttachments
|
|
44
|
+
} from "./chunk-E2RE7P2S.js";
|
|
41
45
|
import {
|
|
42
46
|
SLACK_REPLY_FORMATTING,
|
|
43
47
|
coordinatorSystemPrompt,
|
|
44
48
|
coordinatorTurnReminder,
|
|
45
49
|
enrichWorkspacesWithGithub,
|
|
46
50
|
ensureGlobalCoordinatorCwd
|
|
47
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-7SYFWPOZ.js";
|
|
48
52
|
import {
|
|
49
53
|
extractPresentedPlan,
|
|
50
54
|
readPlanFile,
|
|
@@ -114,11 +118,10 @@ import {
|
|
|
114
118
|
withRepoGitLock,
|
|
115
119
|
worktreeDisplayLabelForGroup,
|
|
116
120
|
worktreeNameFromPath
|
|
117
|
-
} from "./chunk-
|
|
121
|
+
} from "./chunk-DKXZCIB2.js";
|
|
118
122
|
import {
|
|
119
123
|
ATTACHMENTS_DIR,
|
|
120
|
-
LEGACY_ATTACHMENTS_DIR
|
|
121
|
-
attachmentsGitignoreBody
|
|
124
|
+
LEGACY_ATTACHMENTS_DIR
|
|
122
125
|
} from "./chunk-FKOIHGKV.js";
|
|
123
126
|
import {
|
|
124
127
|
childEnvWithAppSettings,
|
|
@@ -152,7 +155,7 @@ import {
|
|
|
152
155
|
updateThread,
|
|
153
156
|
withThreadLock,
|
|
154
157
|
writeThread
|
|
155
|
-
} from "./chunk-
|
|
158
|
+
} from "./chunk-TUGKX5BD.js";
|
|
156
159
|
import {
|
|
157
160
|
appDataDir,
|
|
158
161
|
findConventionSetup,
|
|
@@ -445,7 +448,7 @@ async function continueSourceThread(threadId, prompt) {
|
|
|
445
448
|
await continueOnReply(threadId, prompt);
|
|
446
449
|
return;
|
|
447
450
|
}
|
|
448
|
-
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-
|
|
451
|
+
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-WEFXUHFX.js");
|
|
449
452
|
await getOrchestrator2().send(threadId, prompt);
|
|
450
453
|
} catch {
|
|
451
454
|
}
|
|
@@ -705,7 +708,7 @@ async function pollSlackOutboundWatches(opts) {
|
|
|
705
708
|
}
|
|
706
709
|
|
|
707
710
|
// src/orchestrator/orchestrator.ts
|
|
708
|
-
import { existsSync as
|
|
711
|
+
import { existsSync as existsSync15 } from "fs";
|
|
709
712
|
|
|
710
713
|
// src/agents/spawn.ts
|
|
711
714
|
import { createInterface } from "readline";
|
|
@@ -725,9 +728,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
725
728
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
726
729
|
);
|
|
727
730
|
}
|
|
728
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
731
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-ZDYKHQ4O.js");
|
|
729
732
|
if (isGlobalThread2(thread)) {
|
|
730
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
733
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-43O6EPA2.js");
|
|
731
734
|
ensureGlobalCoordinatorCwd2(
|
|
732
735
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
733
736
|
);
|
|
@@ -974,6 +977,60 @@ import { dirname, join as join4 } from "path";
|
|
|
974
977
|
// src/threads/chat-tabs.ts
|
|
975
978
|
import { randomUUID } from "crypto";
|
|
976
979
|
|
|
980
|
+
// src/composer/context-estimate.ts
|
|
981
|
+
var CHARS_PER_CONTEXT_TOKEN = 4;
|
|
982
|
+
function estimateMessageChars(message) {
|
|
983
|
+
let n = message.text.length + 16;
|
|
984
|
+
for (const part of message.parts ?? []) {
|
|
985
|
+
n += estimatePartChars(part);
|
|
986
|
+
}
|
|
987
|
+
return n;
|
|
988
|
+
}
|
|
989
|
+
function estimatePartChars(part) {
|
|
990
|
+
switch (part.type) {
|
|
991
|
+
case "text":
|
|
992
|
+
case "thinking":
|
|
993
|
+
return part.text.length;
|
|
994
|
+
case "tool": {
|
|
995
|
+
const input = part.input ? JSON.stringify(part.input) : "";
|
|
996
|
+
return part.name.length + (part.description?.length ?? 0) + (part.detail?.length ?? 0) + (part.result?.length ?? 0) + input.length + 32;
|
|
997
|
+
}
|
|
998
|
+
default:
|
|
999
|
+
return 0;
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
function estimateThreadChars(messages) {
|
|
1003
|
+
return messages.reduce((sum, m) => sum + estimateMessageChars(m), 0);
|
|
1004
|
+
}
|
|
1005
|
+
function estimateOccupancyTokens(messages) {
|
|
1006
|
+
return Math.ceil(estimateThreadChars(messages) / CHARS_PER_CONTEXT_TOKEN);
|
|
1007
|
+
}
|
|
1008
|
+
function threadHasCompactedContext(messages) {
|
|
1009
|
+
return messages.some((m) => m.role === "summary");
|
|
1010
|
+
}
|
|
1011
|
+
function forwardContextUsage(usage, messages) {
|
|
1012
|
+
if (!usage) return null;
|
|
1013
|
+
if (!threadHasCompactedContext(messages)) return usage;
|
|
1014
|
+
const remaining = estimateOccupancyTokens(messages);
|
|
1015
|
+
const current = contextTokens(usage);
|
|
1016
|
+
if (remaining <= 0 || remaining >= current) return usage;
|
|
1017
|
+
return { ...usage, lastRequestTokens: remaining };
|
|
1018
|
+
}
|
|
1019
|
+
function applyForwardOccupancy(messages) {
|
|
1020
|
+
const tokens = estimateOccupancyTokens(messages);
|
|
1021
|
+
if (tokens <= 0) return messages;
|
|
1022
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
1023
|
+
const m = messages[i];
|
|
1024
|
+
if (m?.role !== "agent" || !m.usage) continue;
|
|
1025
|
+
const current = contextTokens(m.usage);
|
|
1026
|
+
if (tokens >= current) return messages;
|
|
1027
|
+
const next = messages.slice();
|
|
1028
|
+
next[i] = { ...m, usage: { ...m.usage, lastRequestTokens: tokens } };
|
|
1029
|
+
return next;
|
|
1030
|
+
}
|
|
1031
|
+
return messages;
|
|
1032
|
+
}
|
|
1033
|
+
|
|
977
1034
|
// src/composer/summarize.ts
|
|
978
1035
|
var MAX_TRANSCRIPT_CHARS = 12e4;
|
|
979
1036
|
var MAX_SUMMARY_CHARS = 6e3;
|
|
@@ -1082,29 +1139,6 @@ var CONTEXT_KEEP_RECENT_CHARS = 24e3;
|
|
|
1082
1139
|
var CONTEXT_KEEP_RECENT_MESSAGES = 12;
|
|
1083
1140
|
var CONTEXT_MIN_MESSAGES = 10;
|
|
1084
1141
|
var SESSION_RESET_OCCUPANCY_TOKENS = 75e4;
|
|
1085
|
-
function estimateMessageChars(message) {
|
|
1086
|
-
let n = message.text.length + 16;
|
|
1087
|
-
for (const part of message.parts ?? []) {
|
|
1088
|
-
n += estimatePartChars(part);
|
|
1089
|
-
}
|
|
1090
|
-
return n;
|
|
1091
|
-
}
|
|
1092
|
-
function estimatePartChars(part) {
|
|
1093
|
-
switch (part.type) {
|
|
1094
|
-
case "text":
|
|
1095
|
-
case "thinking":
|
|
1096
|
-
return part.text.length;
|
|
1097
|
-
case "tool": {
|
|
1098
|
-
const input = part.input ? JSON.stringify(part.input) : "";
|
|
1099
|
-
return part.name.length + (part.description?.length ?? 0) + (part.detail?.length ?? 0) + (part.result?.length ?? 0) + input.length + 32;
|
|
1100
|
-
}
|
|
1101
|
-
default:
|
|
1102
|
-
return 0;
|
|
1103
|
-
}
|
|
1104
|
-
}
|
|
1105
|
-
function estimateThreadChars(messages) {
|
|
1106
|
-
return messages.reduce((sum, m) => sum + estimateMessageChars(m), 0);
|
|
1107
|
-
}
|
|
1108
1142
|
function shouldCompactContext(messages, thresholds = {}) {
|
|
1109
1143
|
const maxChars = thresholds.maxChars ?? CONTEXT_COMPACT_CHARS;
|
|
1110
1144
|
const minMessages = thresholds.minMessages ?? CONTEXT_MIN_MESSAGES;
|
|
@@ -1241,8 +1275,11 @@ async function maybeCompactContext(thread, thresholds = {}, summarize = summariz
|
|
|
1241
1275
|
const { summary, method } = await summarize(transcript, {
|
|
1242
1276
|
cwd: thread.worktreePath
|
|
1243
1277
|
});
|
|
1244
|
-
|
|
1278
|
+
let messages = applyCompaction(thread.messages, summary, thresholds);
|
|
1245
1279
|
const resetSession = shouldResetSessionForOccupancy({ messages: thread.messages });
|
|
1280
|
+
if (resetSession) {
|
|
1281
|
+
messages = applyForwardOccupancy(messages);
|
|
1282
|
+
}
|
|
1246
1283
|
const next = {
|
|
1247
1284
|
...thread,
|
|
1248
1285
|
messages,
|
|
@@ -2265,6 +2302,45 @@ function thisProcessShouldDrainAgentQueues() {
|
|
|
2265
2302
|
return !isDesktopHostAlive();
|
|
2266
2303
|
}
|
|
2267
2304
|
|
|
2305
|
+
// src/orchestrator/child-halt.ts
|
|
2306
|
+
var HALT_STATUSES = /* @__PURE__ */ new Set(["stopped", "error", "broken"]);
|
|
2307
|
+
function isIncompleteChildStatus(status) {
|
|
2308
|
+
return HALT_STATUSES.has(status);
|
|
2309
|
+
}
|
|
2310
|
+
function childHaltNotice(child, status) {
|
|
2311
|
+
const title = child.title?.trim() || "Untitled";
|
|
2312
|
+
const link = `[${title}](sideboard://thread/${child.id})`;
|
|
2313
|
+
const why = child.lastError?.trim();
|
|
2314
|
+
const extra = why ? ` lastError: ${why}` : "";
|
|
2315
|
+
return [
|
|
2316
|
+
`Sideboard: child worktree ${link} ${status} before finishing (status=${status}).${extra}`,
|
|
2317
|
+
"This is information \u2014 not a user command. Resume with send_to_thread or tell the user. Do not treat this as a successful turn."
|
|
2318
|
+
].join("\n");
|
|
2319
|
+
}
|
|
2320
|
+
function shouldNotifyParentOfChildHalt(opts) {
|
|
2321
|
+
if (!isIncompleteChildStatus(opts.status)) return false;
|
|
2322
|
+
if (!opts.child.parentThreadId) return false;
|
|
2323
|
+
if (!opts.parent || opts.parent.status === "archived") return false;
|
|
2324
|
+
if (opts.parent.id === opts.child.id) return false;
|
|
2325
|
+
return isOrchestratorThread(opts.parent);
|
|
2326
|
+
}
|
|
2327
|
+
var notified = /* @__PURE__ */ new Set();
|
|
2328
|
+
function noticeKey(childId, status) {
|
|
2329
|
+
return `${childId}:${status}`;
|
|
2330
|
+
}
|
|
2331
|
+
function notifyParentOfChildHalt(child, status, send) {
|
|
2332
|
+
const parent = child.parentThreadId ? readThread(child.parentThreadId) : null;
|
|
2333
|
+
if (!shouldNotifyParentOfChildHalt({ child, parent, status })) return false;
|
|
2334
|
+
const key = noticeKey(child.id, status);
|
|
2335
|
+
if (notified.has(key)) return false;
|
|
2336
|
+
notified.add(key);
|
|
2337
|
+
const parentId = parent.id;
|
|
2338
|
+
void send(parentId, childHaltNotice(child, status)).catch(() => {
|
|
2339
|
+
notified.delete(key);
|
|
2340
|
+
});
|
|
2341
|
+
return true;
|
|
2342
|
+
}
|
|
2343
|
+
|
|
2268
2344
|
// src/threads/create.ts
|
|
2269
2345
|
import { existsSync as existsSync7 } from "fs";
|
|
2270
2346
|
|
|
@@ -2743,6 +2819,9 @@ function assembleHomeBoard(input) {
|
|
|
2743
2819
|
var HOME_BOARD_AGENT_HINT = "Home is a Kanban of worktrees (one card per checkout; sibling chat tabs nest as inner cards). create_thread reuses a live worktree for the same ticket, PR, or named branch \u2014 do not recreate it. Columns are the path to merge: New (no PR) \u2192 Draft (draft PR) \u2192 Review (open PR) \u2192 Merged. Archive removes the card to Settings \u2192 History. Queued/running are activity on the card, not columns. Orchestration chats stay in the sidebar. Do not invent status.";
|
|
2744
2820
|
|
|
2745
2821
|
// src/threads/create.ts
|
|
2822
|
+
function persistCreateAttachments(worktreePath, attachments) {
|
|
2823
|
+
return persistPendingFileAttachments(worktreePath, attachments ?? []);
|
|
2824
|
+
}
|
|
2746
2825
|
async function createThread(input, _onSetupLine) {
|
|
2747
2826
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
2748
2827
|
if (!existsSync7(repoPath)) {
|
|
@@ -2762,7 +2841,16 @@ async function createThread(input, _onSetupLine) {
|
|
|
2762
2841
|
repoPath: canonicalizeRepoPath(t.repoPath)
|
|
2763
2842
|
}))
|
|
2764
2843
|
);
|
|
2765
|
-
if (existing)
|
|
2844
|
+
if (existing) {
|
|
2845
|
+
const thread2 = readThread(existing.id) ?? existing;
|
|
2846
|
+
if (!input.attachments?.length) return thread2;
|
|
2847
|
+
return updateThread(thread2.id, {
|
|
2848
|
+
attachments: persistCreateAttachments(thread2.worktreePath, [
|
|
2849
|
+
...thread2.attachments,
|
|
2850
|
+
...input.attachments
|
|
2851
|
+
])
|
|
2852
|
+
});
|
|
2853
|
+
}
|
|
2766
2854
|
}
|
|
2767
2855
|
const resolved = resolveNewThreadOptions({
|
|
2768
2856
|
agent: input.agent,
|
|
@@ -2810,7 +2898,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
2810
2898
|
effort: resolved.effort,
|
|
2811
2899
|
fast: resolved.fast,
|
|
2812
2900
|
planMode: Boolean(input.planMode),
|
|
2813
|
-
attachments: input.attachments
|
|
2901
|
+
attachments: persistCreateAttachments(repoPath, input.attachments),
|
|
2814
2902
|
sourceIsFork: false,
|
|
2815
2903
|
parentThreadId: input.parentThreadId ?? null,
|
|
2816
2904
|
status: "idle",
|
|
@@ -2889,7 +2977,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
2889
2977
|
effort: resolved.effort,
|
|
2890
2978
|
fast: resolved.fast,
|
|
2891
2979
|
planMode: Boolean(input.planMode),
|
|
2892
|
-
attachments,
|
|
2980
|
+
attachments: persistCreateAttachments(worktreePath, attachments),
|
|
2893
2981
|
sourceIsFork,
|
|
2894
2982
|
parentThreadId: input.parentThreadId ?? null,
|
|
2895
2983
|
status: "idle",
|
|
@@ -2901,7 +2989,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
2901
2989
|
return readThread(thread.id) ?? thread;
|
|
2902
2990
|
}
|
|
2903
2991
|
async function listLinearIssues(agent, repoPath) {
|
|
2904
|
-
const { getAdapter: getAdapter2 } = await import("./agents-
|
|
2992
|
+
const { getAdapter: getAdapter2 } = await import("./agents-665S7Z3R.js");
|
|
2905
2993
|
await requireAgent(agent, { requireLinear: true });
|
|
2906
2994
|
const adapter = getAdapter2(agent);
|
|
2907
2995
|
if (!adapter.listLinearIssues) {
|
|
@@ -3298,7 +3386,7 @@ async function adoptThread(input) {
|
|
|
3298
3386
|
messages: input.messages ?? []
|
|
3299
3387
|
});
|
|
3300
3388
|
writeThread(thread);
|
|
3301
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
3389
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-ALCTB65T.js");
|
|
3302
3390
|
await ensureWorkspace2(repoPath);
|
|
3303
3391
|
return thread;
|
|
3304
3392
|
}
|
|
@@ -4861,232 +4949,9 @@ function expandComposerPrompt(worktreePath, prompt, opts) {
|
|
|
4861
4949
|
};
|
|
4862
4950
|
}
|
|
4863
4951
|
|
|
4864
|
-
// src/composer/stage-files.ts
|
|
4865
|
-
import { copyFileSync as copyFileSync3, existsSync as existsSync13, mkdirSync as mkdirSync4, readFileSync as readFileSync10, statSync as statSync4, writeFileSync as writeFileSync5 } from "fs";
|
|
4866
|
-
import { basename as basename3, extname, join as join12 } from "path";
|
|
4867
|
-
import { randomUUID as randomUUID4 } from "crypto";
|
|
4868
|
-
var IMAGE_EXTENSIONS2 = /* @__PURE__ */ new Set([
|
|
4869
|
-
"png",
|
|
4870
|
-
"jpg",
|
|
4871
|
-
"jpeg",
|
|
4872
|
-
"gif",
|
|
4873
|
-
"webp",
|
|
4874
|
-
"svg",
|
|
4875
|
-
"bmp",
|
|
4876
|
-
"ico"
|
|
4877
|
-
]);
|
|
4878
|
-
var IMAGE_MIME_BY_EXT = {
|
|
4879
|
-
png: "image/png",
|
|
4880
|
-
jpg: "image/jpeg",
|
|
4881
|
-
jpeg: "image/jpeg",
|
|
4882
|
-
gif: "image/gif",
|
|
4883
|
-
webp: "image/webp",
|
|
4884
|
-
svg: "image/svg+xml",
|
|
4885
|
-
bmp: "image/bmp",
|
|
4886
|
-
ico: "image/x-icon"
|
|
4887
|
-
};
|
|
4888
|
-
var MAX_INLINE_BYTES = 4e5;
|
|
4889
|
-
var MAX_PREVIEW_BYTES = 5e6;
|
|
4890
|
-
function fileExtension(filePath) {
|
|
4891
|
-
const base = basename3(filePath).toLowerCase();
|
|
4892
|
-
return base.includes(".") ? base.split(".").pop() || "" : "";
|
|
4893
|
-
}
|
|
4894
|
-
function isImageFilePath(filePath) {
|
|
4895
|
-
return IMAGE_EXTENSIONS2.has(fileExtension(filePath));
|
|
4896
|
-
}
|
|
4897
|
-
function imageMimeType(filePath) {
|
|
4898
|
-
return IMAGE_MIME_BY_EXT[fileExtension(filePath)] || "image/png";
|
|
4899
|
-
}
|
|
4900
|
-
function ensureAttachmentsDir(worktreePath) {
|
|
4901
|
-
const dir = join12(worktreePath, ATTACHMENTS_DIR);
|
|
4902
|
-
mkdirSync4(dir, { recursive: true });
|
|
4903
|
-
const gi = join12(dir, ".gitignore");
|
|
4904
|
-
if (!existsSync13(gi)) {
|
|
4905
|
-
writeFileSync5(gi, attachmentsGitignoreBody(), "utf8");
|
|
4906
|
-
}
|
|
4907
|
-
return dir;
|
|
4908
|
-
}
|
|
4909
|
-
function uniqueAttachmentName(dir, originalName) {
|
|
4910
|
-
const safe = originalName.replace(/[/\\]/g, "_") || "file";
|
|
4911
|
-
if (!existsSync13(join12(dir, safe))) return safe;
|
|
4912
|
-
const ext = extname(safe);
|
|
4913
|
-
const stem = ext ? safe.slice(0, -ext.length) : safe;
|
|
4914
|
-
for (let i = 1; i < 1e4; i++) {
|
|
4915
|
-
const candidate = `${stem}-${i}${ext}`;
|
|
4916
|
-
if (!existsSync13(join12(dir, candidate))) return candidate;
|
|
4917
|
-
}
|
|
4918
|
-
return `${stem}-${randomUUID4()}${ext}`;
|
|
4919
|
-
}
|
|
4920
|
-
function previewDataUrlFromBuf(filePath, buf) {
|
|
4921
|
-
if (!isImageFilePath(filePath)) return void 0;
|
|
4922
|
-
if (buf.length > MAX_PREVIEW_BYTES) return void 0;
|
|
4923
|
-
return `data:${imageMimeType(filePath)};base64,${buf.toString("base64")}`;
|
|
4924
|
-
}
|
|
4925
|
-
function attachmentFromBuffer(name, buf, opts) {
|
|
4926
|
-
const previewDataUrl = previewDataUrlFromBuf(name, buf);
|
|
4927
|
-
if (isImageFilePath(name)) {
|
|
4928
|
-
const pathHint = opts.path ? `\`${opts.path}\`` : opts.sourceLabel || name;
|
|
4929
|
-
return {
|
|
4930
|
-
id: randomUUID4(),
|
|
4931
|
-
name,
|
|
4932
|
-
kind: "file",
|
|
4933
|
-
path: opts.path,
|
|
4934
|
-
previewDataUrl,
|
|
4935
|
-
content: [
|
|
4936
|
-
`Image attached: ${pathHint}`,
|
|
4937
|
-
opts.path ? `Use the Read tool on \`${opts.path}\` to view this image.` : "The image is shown in the composer; copy it into the worktree if you need to inspect pixels."
|
|
4938
|
-
].join("\n")
|
|
4939
|
-
};
|
|
4940
|
-
}
|
|
4941
|
-
if (buf.length > MAX_INLINE_BYTES) {
|
|
4942
|
-
return {
|
|
4943
|
-
id: randomUUID4(),
|
|
4944
|
-
name,
|
|
4945
|
-
kind: "file",
|
|
4946
|
-
path: opts.path,
|
|
4947
|
-
content: opts.path ? `(file too large to attach inline: \`${opts.path}\`, ${buf.length} bytes \u2014 use the Read tool)` : `(file too large to attach inline: ${opts.sourceLabel || name}, ${buf.length} bytes)`
|
|
4948
|
-
};
|
|
4949
|
-
}
|
|
4950
|
-
if (buf.includes(0)) {
|
|
4951
|
-
return {
|
|
4952
|
-
id: randomUUID4(),
|
|
4953
|
-
name,
|
|
4954
|
-
kind: "file",
|
|
4955
|
-
path: opts.path,
|
|
4956
|
-
content: opts.path ? `(binary file at \`${opts.path}\` \u2014 use tools to inspect)` : `(binary file attached by path only: ${opts.sourceLabel || name})`
|
|
4957
|
-
};
|
|
4958
|
-
}
|
|
4959
|
-
return {
|
|
4960
|
-
id: randomUUID4(),
|
|
4961
|
-
name,
|
|
4962
|
-
kind: "file",
|
|
4963
|
-
path: opts.path,
|
|
4964
|
-
content: buf.toString("utf8")
|
|
4965
|
-
};
|
|
4966
|
-
}
|
|
4967
|
-
function attachmentFromAbsolutePath(absolutePath) {
|
|
4968
|
-
const name = basename3(absolutePath);
|
|
4969
|
-
try {
|
|
4970
|
-
const st = statSync4(absolutePath);
|
|
4971
|
-
if (!st.isFile()) {
|
|
4972
|
-
return {
|
|
4973
|
-
id: randomUUID4(),
|
|
4974
|
-
name,
|
|
4975
|
-
kind: "file",
|
|
4976
|
-
content: `(not a file: ${absolutePath})`
|
|
4977
|
-
};
|
|
4978
|
-
}
|
|
4979
|
-
const buf = readFileSync10(absolutePath);
|
|
4980
|
-
return attachmentFromBuffer(name, buf, { sourceLabel: absolutePath });
|
|
4981
|
-
} catch (err) {
|
|
4982
|
-
return {
|
|
4983
|
-
id: randomUUID4(),
|
|
4984
|
-
name,
|
|
4985
|
-
kind: "file",
|
|
4986
|
-
content: `(could not read ${absolutePath}: ${err instanceof Error ? err.message : String(err)})`
|
|
4987
|
-
};
|
|
4988
|
-
}
|
|
4989
|
-
}
|
|
4990
|
-
function stageAbsolutePathsAsAttachments(worktreePath, absolutePaths) {
|
|
4991
|
-
if (absolutePaths.length === 0) return [];
|
|
4992
|
-
const dir = ensureAttachmentsDir(worktreePath);
|
|
4993
|
-
const out = [];
|
|
4994
|
-
for (const abs of absolutePaths) {
|
|
4995
|
-
const originalName = basename3(abs);
|
|
4996
|
-
try {
|
|
4997
|
-
const st = statSync4(abs);
|
|
4998
|
-
if (!st.isFile()) continue;
|
|
4999
|
-
const name = uniqueAttachmentName(dir, originalName);
|
|
5000
|
-
const destAbs = join12(dir, name);
|
|
5001
|
-
copyFileSync3(abs, destAbs);
|
|
5002
|
-
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
5003
|
-
const buf = readFileSync10(destAbs);
|
|
5004
|
-
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
5005
|
-
} catch (err) {
|
|
5006
|
-
out.push({
|
|
5007
|
-
id: randomUUID4(),
|
|
5008
|
-
name: originalName,
|
|
5009
|
-
kind: "file",
|
|
5010
|
-
content: `(could not attach ${abs}: ${err instanceof Error ? err.message : String(err)})`
|
|
5011
|
-
});
|
|
5012
|
-
}
|
|
5013
|
-
}
|
|
5014
|
-
return out;
|
|
5015
|
-
}
|
|
5016
|
-
function stageBuffersAsAttachments(worktreePath, buffers2) {
|
|
5017
|
-
if (buffers2.length === 0) return [];
|
|
5018
|
-
const dir = ensureAttachmentsDir(worktreePath);
|
|
5019
|
-
const out = [];
|
|
5020
|
-
for (const item of buffers2) {
|
|
5021
|
-
const originalName = (item.name || "file").replace(/[/\\]/g, "_") || "file";
|
|
5022
|
-
try {
|
|
5023
|
-
const buf = Buffer.from(item.dataBase64, "base64");
|
|
5024
|
-
const name = uniqueAttachmentName(dir, originalName);
|
|
5025
|
-
const destAbs = join12(dir, name);
|
|
5026
|
-
writeFileSync5(destAbs, buf);
|
|
5027
|
-
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
5028
|
-
out.push(attachmentFromBuffer(name, buf, { path: rel }));
|
|
5029
|
-
} catch (err) {
|
|
5030
|
-
out.push({
|
|
5031
|
-
id: randomUUID4(),
|
|
5032
|
-
name: originalName,
|
|
5033
|
-
kind: "file",
|
|
5034
|
-
content: `(could not attach ${originalName}: ${err instanceof Error ? err.message : String(err)})`
|
|
5035
|
-
});
|
|
5036
|
-
}
|
|
5037
|
-
}
|
|
5038
|
-
return out;
|
|
5039
|
-
}
|
|
5040
|
-
function attachmentsFromBuffers(buffers2) {
|
|
5041
|
-
return buffers2.map((item) => {
|
|
5042
|
-
const name = (item.name || "file").replace(/[/\\]/g, "_") || "file";
|
|
5043
|
-
try {
|
|
5044
|
-
const buf = Buffer.from(item.dataBase64, "base64");
|
|
5045
|
-
return attachmentFromBuffer(name, buf, { sourceLabel: name });
|
|
5046
|
-
} catch (err) {
|
|
5047
|
-
return {
|
|
5048
|
-
id: randomUUID4(),
|
|
5049
|
-
name,
|
|
5050
|
-
kind: "file",
|
|
5051
|
-
content: `(could not attach ${name}: ${err instanceof Error ? err.message : String(err)})`
|
|
5052
|
-
};
|
|
5053
|
-
}
|
|
5054
|
-
});
|
|
5055
|
-
}
|
|
5056
|
-
function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
|
|
5057
|
-
const out = [];
|
|
5058
|
-
for (const rel of relativePaths) {
|
|
5059
|
-
if (!rel || rel.includes("..") || rel.startsWith("/")) {
|
|
5060
|
-
out.push({
|
|
5061
|
-
id: randomUUID4(),
|
|
5062
|
-
name: basename3(rel) || "file",
|
|
5063
|
-
kind: "file",
|
|
5064
|
-
content: `(invalid path: ${rel})`
|
|
5065
|
-
});
|
|
5066
|
-
continue;
|
|
5067
|
-
}
|
|
5068
|
-
const name = basename3(rel);
|
|
5069
|
-
try {
|
|
5070
|
-
const abs = join12(worktreePath, rel);
|
|
5071
|
-
const st = statSync4(abs);
|
|
5072
|
-
if (!st.isFile()) continue;
|
|
5073
|
-
const buf = readFileSync10(abs);
|
|
5074
|
-
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
5075
|
-
} catch (err) {
|
|
5076
|
-
out.push({
|
|
5077
|
-
id: randomUUID4(),
|
|
5078
|
-
name,
|
|
5079
|
-
kind: "file",
|
|
5080
|
-
content: `(could not read ${rel}: ${err instanceof Error ? err.message : String(err)})`
|
|
5081
|
-
});
|
|
5082
|
-
}
|
|
5083
|
-
}
|
|
5084
|
-
return out;
|
|
5085
|
-
}
|
|
5086
|
-
|
|
5087
4952
|
// src/agents/instructions.ts
|
|
5088
|
-
import { existsSync as
|
|
5089
|
-
import { join as
|
|
4953
|
+
import { existsSync as existsSync13, readFileSync as readFileSync10, statSync as statSync4 } from "fs";
|
|
4954
|
+
import { join as join12 } from "path";
|
|
5090
4955
|
function normPath(p) {
|
|
5091
4956
|
return p.replace(/\/+$/, "");
|
|
5092
4957
|
}
|
|
@@ -5250,11 +5115,11 @@ function loadAgentInstructions(worktreePath, agent) {
|
|
|
5250
5115
|
const out = [];
|
|
5251
5116
|
for (const rel of candidates) {
|
|
5252
5117
|
if (seenPaths.has(rel)) continue;
|
|
5253
|
-
const abs =
|
|
5254
|
-
if (!
|
|
5118
|
+
const abs = join12(worktreePath, rel);
|
|
5119
|
+
if (!existsSync13(abs)) continue;
|
|
5255
5120
|
try {
|
|
5256
|
-
if (!
|
|
5257
|
-
let content =
|
|
5121
|
+
if (!statSync4(abs).isFile()) continue;
|
|
5122
|
+
let content = readFileSync10(abs, "utf8");
|
|
5258
5123
|
if (!content.trim()) continue;
|
|
5259
5124
|
if (content.length > MAX_CHARS_PER_FILE) {
|
|
5260
5125
|
content = `${content.slice(0, MAX_CHARS_PER_FILE)}
|
|
@@ -5326,9 +5191,9 @@ async function syncThreadBranchFromGit(threadId) {
|
|
|
5326
5191
|
}
|
|
5327
5192
|
|
|
5328
5193
|
// src/store/schedules.ts
|
|
5329
|
-
import { randomUUID as
|
|
5330
|
-
import { existsSync as
|
|
5331
|
-
import { join as
|
|
5194
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
5195
|
+
import { existsSync as existsSync14, readFileSync as readFileSync11 } from "fs";
|
|
5196
|
+
import { join as join13 } from "path";
|
|
5332
5197
|
import { Cron } from "croner";
|
|
5333
5198
|
var DURATION_RE = /^(\d+)(s|m|h|d)$/i;
|
|
5334
5199
|
var UNIT_MS = {
|
|
@@ -5338,7 +5203,7 @@ var UNIT_MS = {
|
|
|
5338
5203
|
d: 864e5
|
|
5339
5204
|
};
|
|
5340
5205
|
function schedulesPath() {
|
|
5341
|
-
return
|
|
5206
|
+
return join13(appDataDir(), "schedules.json");
|
|
5342
5207
|
}
|
|
5343
5208
|
function parseDurationMs(every) {
|
|
5344
5209
|
const m = every.trim().match(DURATION_RE);
|
|
@@ -5444,9 +5309,9 @@ function normalizeTask(raw) {
|
|
|
5444
5309
|
}
|
|
5445
5310
|
function readAll() {
|
|
5446
5311
|
const path = schedulesPath();
|
|
5447
|
-
if (!
|
|
5312
|
+
if (!existsSync14(path)) return [];
|
|
5448
5313
|
try {
|
|
5449
|
-
const parsed = JSON.parse(
|
|
5314
|
+
const parsed = JSON.parse(readFileSync11(path, "utf8"));
|
|
5450
5315
|
if (!Array.isArray(parsed)) return [];
|
|
5451
5316
|
return parsed.map((row) => {
|
|
5452
5317
|
try {
|
|
@@ -5471,7 +5336,7 @@ function buildTask(input, now) {
|
|
|
5471
5336
|
const ts = nowIso(now);
|
|
5472
5337
|
const agent = input.agent ? coerceOrchestratorAgent(input.agent) : null;
|
|
5473
5338
|
return {
|
|
5474
|
-
id:
|
|
5339
|
+
id: randomUUID4(),
|
|
5475
5340
|
name: input.name?.trim() || defaultScheduleName(prompt),
|
|
5476
5341
|
prompt,
|
|
5477
5342
|
enabled: input.enabled !== false,
|
|
@@ -5572,7 +5437,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
5572
5437
|
${prompt}`;
|
|
5573
5438
|
}
|
|
5574
5439
|
async function defaultDeps() {
|
|
5575
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
5440
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-WEFXUHFX.js");
|
|
5576
5441
|
const orch = getOrchestrator2();
|
|
5577
5442
|
return {
|
|
5578
5443
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -5778,7 +5643,7 @@ var Orchestrator = class {
|
|
|
5778
5643
|
}
|
|
5779
5644
|
continue;
|
|
5780
5645
|
}
|
|
5781
|
-
if (!
|
|
5646
|
+
if (!existsSync15(thread.worktreePath)) {
|
|
5782
5647
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
5783
5648
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
5784
5649
|
continue;
|
|
@@ -5815,6 +5680,9 @@ var Orchestrator = class {
|
|
|
5815
5680
|
* MCP-created review threads don't stay `queued` after the MCP child exits.
|
|
5816
5681
|
*/
|
|
5817
5682
|
adoptPersistedQueues() {
|
|
5683
|
+
if (thisProcessShouldDrainAgentQueues()) {
|
|
5684
|
+
this.healStaleRunningTurns();
|
|
5685
|
+
}
|
|
5818
5686
|
for (const thread of listThreads()) {
|
|
5819
5687
|
if (thread.status === "stopped" || thread.status === "archived") continue;
|
|
5820
5688
|
const pid = thread.agentPid;
|
|
@@ -5835,6 +5703,32 @@ var Orchestrator = class {
|
|
|
5835
5703
|
}
|
|
5836
5704
|
}
|
|
5837
5705
|
}
|
|
5706
|
+
/**
|
|
5707
|
+
* Mid-session: a worktree can sit at `running` after the agent process dies
|
|
5708
|
+
* (Cursor/CLI crash, OOM) while wait_for_turn still reports stillRunning.
|
|
5709
|
+
* Reclaim those and wake the parent orchestration chat.
|
|
5710
|
+
*/
|
|
5711
|
+
healStaleRunningTurns() {
|
|
5712
|
+
for (const thread of listThreads()) {
|
|
5713
|
+
if (thread.status === "archived") continue;
|
|
5714
|
+
const handle = this.activeTurns.get(thread.id);
|
|
5715
|
+
if (handle) {
|
|
5716
|
+
const pid = handle.pid;
|
|
5717
|
+
if (typeof pid === "number" && pid > 0 && !isPidAlive(pid)) {
|
|
5718
|
+
handle.kill();
|
|
5719
|
+
}
|
|
5720
|
+
continue;
|
|
5721
|
+
}
|
|
5722
|
+
if (!this.shouldReclaimRunningThread(thread)) continue;
|
|
5723
|
+
setStatus(thread.id, "stopped", "Process died (agent exited)");
|
|
5724
|
+
this.emit({ type: "status_changed", threadId: thread.id, status: "stopped" });
|
|
5725
|
+
this.emit({ type: "turn_finished", threadId: thread.id, exitCode: 1 });
|
|
5726
|
+
const latest = readThread(thread.id);
|
|
5727
|
+
if (latest) {
|
|
5728
|
+
notifyParentOfChildHalt(latest, "stopped", (id, prompt) => this.send(id, prompt));
|
|
5729
|
+
}
|
|
5730
|
+
}
|
|
5731
|
+
}
|
|
5838
5732
|
clearQuotaResumeTimer(threadId) {
|
|
5839
5733
|
const timer = this.quotaResumeTimers.get(threadId);
|
|
5840
5734
|
if (timer) clearTimeout(timer);
|
|
@@ -6552,6 +6446,12 @@ var Orchestrator = class {
|
|
|
6552
6446
|
assistantText: chatText,
|
|
6553
6447
|
partsCount: parts.length
|
|
6554
6448
|
});
|
|
6449
|
+
if (!this.crashContinued.has(threadId)) {
|
|
6450
|
+
const failed = readThread(threadId);
|
|
6451
|
+
if (failed) {
|
|
6452
|
+
notifyParentOfChildHalt(failed, "error", (id, prompt2) => this.send(id, prompt2));
|
|
6453
|
+
}
|
|
6454
|
+
}
|
|
6555
6455
|
}
|
|
6556
6456
|
}
|
|
6557
6457
|
} catch (err) {
|
|
@@ -6576,6 +6476,12 @@ var Orchestrator = class {
|
|
|
6576
6476
|
assistantText: "",
|
|
6577
6477
|
partsCount: 0
|
|
6578
6478
|
});
|
|
6479
|
+
if (!this.crashContinued.has(threadId)) {
|
|
6480
|
+
const failed = readThread(threadId);
|
|
6481
|
+
if (failed) {
|
|
6482
|
+
notifyParentOfChildHalt(failed, "error", (id, prompt2) => this.send(id, prompt2));
|
|
6483
|
+
}
|
|
6484
|
+
}
|
|
6579
6485
|
}
|
|
6580
6486
|
} finally {
|
|
6581
6487
|
this.startingTurns.delete(threadId);
|
|
@@ -6631,6 +6537,9 @@ var Orchestrator = class {
|
|
|
6631
6537
|
const stopped = writeLiveStatus(thread.id, "stopped") ?? readThread(thread.id) ?? thread;
|
|
6632
6538
|
if (stopped.status === "stopped") {
|
|
6633
6539
|
this.emit({ type: "status_changed", threadId: thread.id, status: "stopped" });
|
|
6540
|
+
if (inFlight && opts?.notifyParent !== false) {
|
|
6541
|
+
notifyParentOfChildHalt(stopped, "stopped", (id, prompt) => this.send(id, prompt));
|
|
6542
|
+
}
|
|
6634
6543
|
}
|
|
6635
6544
|
return stopped;
|
|
6636
6545
|
}
|
|
@@ -6875,21 +6784,25 @@ var Orchestrator = class {
|
|
|
6875
6784
|
fn();
|
|
6876
6785
|
};
|
|
6877
6786
|
const off = this.on((event) => {
|
|
6878
|
-
if (
|
|
6787
|
+
if (!("threadId" in event) || event.threadId !== thread.id) return;
|
|
6788
|
+
if (event.type === "turn_finished" || event.type === "error") {
|
|
6879
6789
|
const latest = readThread(thread.id);
|
|
6880
6790
|
if (!latest) {
|
|
6881
6791
|
finish(() => reject(new Error(`Thread not found: ${thread.id}`)));
|
|
6882
6792
|
return;
|
|
6883
6793
|
}
|
|
6884
6794
|
finish(() => resolve(latest));
|
|
6795
|
+
return;
|
|
6885
6796
|
}
|
|
6886
|
-
if (event.type === "
|
|
6797
|
+
if (event.type === "status_changed") {
|
|
6887
6798
|
const latest = readThread(thread.id);
|
|
6888
6799
|
if (!latest) {
|
|
6889
6800
|
finish(() => reject(new Error(`Thread not found: ${thread.id}`)));
|
|
6890
6801
|
return;
|
|
6891
6802
|
}
|
|
6892
|
-
|
|
6803
|
+
if (!["running", "queued"].includes(latest.status)) {
|
|
6804
|
+
finish(() => resolve(latest));
|
|
6805
|
+
}
|
|
6893
6806
|
}
|
|
6894
6807
|
});
|
|
6895
6808
|
timer = setInterval(() => {
|
|
@@ -6924,7 +6837,7 @@ var Orchestrator = class {
|
|
|
6924
6837
|
const thread = this.requireThread(threadRef);
|
|
6925
6838
|
const lastAgent = [...thread.messages].reverse().find((m) => m.role === "agent");
|
|
6926
6839
|
const lastError = thread.lastError ?? null;
|
|
6927
|
-
const text = (lastAgent?.text ?? "").trim() || (thread.status === "error" ? lastError ?? "" : "");
|
|
6840
|
+
const text = (lastAgent?.text ?? "").trim() || (thread.status === "error" || thread.status === "stopped" || thread.status === "broken" ? lastError ?? "" : "");
|
|
6928
6841
|
const stillRunning = thread.status === "running" || thread.status === "queued";
|
|
6929
6842
|
const live = stillRunning ? readTurnLive(thread.id) : null;
|
|
6930
6843
|
const queuedHint = thread.status === "queued" && !live?.summary ? "Queued \u2014 waiting for a concurrency slot" : null;
|
|
@@ -7383,7 +7296,7 @@ var Orchestrator = class {
|
|
|
7383
7296
|
}
|
|
7384
7297
|
async archiveUnlocked(threadRef) {
|
|
7385
7298
|
const thread = this.requireThread(threadRef);
|
|
7386
|
-
this.stop(thread.id);
|
|
7299
|
+
this.stop(thread.id, { notifyParent: false });
|
|
7387
7300
|
this.releaseOrchestratorCaffeinate(thread);
|
|
7388
7301
|
if (isGlobalThread(thread)) {
|
|
7389
7302
|
const archived2 = setStatus(thread.id, "archived");
|
|
@@ -7411,7 +7324,7 @@ var Orchestrator = class {
|
|
|
7411
7324
|
this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
|
|
7412
7325
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
7413
7326
|
try {
|
|
7414
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
7327
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-ALCTB65T.js");
|
|
7415
7328
|
await ensureWorkspace2(thread.repoPath);
|
|
7416
7329
|
} catch {
|
|
7417
7330
|
}
|
|
@@ -7424,7 +7337,7 @@ var Orchestrator = class {
|
|
|
7424
7337
|
}
|
|
7425
7338
|
async purgeUnlocked(threadRef, opts) {
|
|
7426
7339
|
const thread = this.requireThread(threadRef);
|
|
7427
|
-
this.stop(thread.id);
|
|
7340
|
+
this.stop(thread.id, { notifyParent: false });
|
|
7428
7341
|
this.releaseOrchestratorCaffeinate(thread);
|
|
7429
7342
|
if (isGlobalThread(thread)) {
|
|
7430
7343
|
deleteThreadRecord(thread.id);
|
|
@@ -7459,13 +7372,13 @@ var Orchestrator = class {
|
|
|
7459
7372
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
7460
7373
|
return restored2;
|
|
7461
7374
|
}
|
|
7462
|
-
if (!
|
|
7375
|
+
if (!existsSync15(thread.worktreePath)) {
|
|
7463
7376
|
if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
|
|
7464
7377
|
throw new Error(
|
|
7465
7378
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
7466
7379
|
);
|
|
7467
7380
|
}
|
|
7468
|
-
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-
|
|
7381
|
+
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-GXD2NGOZ.js");
|
|
7469
7382
|
const slug = thread.worktreePath.split("/").pop();
|
|
7470
7383
|
const dest = thread.worktreePath;
|
|
7471
7384
|
await withRepoGitLock(thread.repoPath, async () => {
|
|
@@ -7573,7 +7486,7 @@ async function startOrchestration(opts) {
|
|
|
7573
7486
|
sourceRef: "default",
|
|
7574
7487
|
...createOpts
|
|
7575
7488
|
}).catch(async () => {
|
|
7576
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
7489
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-GXD2NGOZ.js");
|
|
7577
7490
|
const repo = await resolveRepoRoot2(repoPath);
|
|
7578
7491
|
const def = await resolveDefaultBranch2(repo);
|
|
7579
7492
|
return orch.createThread({
|
|
@@ -7583,7 +7496,7 @@ async function startOrchestration(opts) {
|
|
|
7583
7496
|
repoPath: repo
|
|
7584
7497
|
});
|
|
7585
7498
|
});
|
|
7586
|
-
const { updateThread: upd } = await import("./thread-store-
|
|
7499
|
+
const { updateThread: upd } = await import("./thread-store-WGASXXXR.js");
|
|
7587
7500
|
const updated = upd(thread.id, {
|
|
7588
7501
|
sourceType: "orchestration",
|
|
7589
7502
|
sourceRef: goal
|
|
@@ -7639,6 +7552,13 @@ export {
|
|
|
7639
7552
|
spawnAgentTurn,
|
|
7640
7553
|
AGENT_GIT_ACTIONS,
|
|
7641
7554
|
agentGitPrompt,
|
|
7555
|
+
CHARS_PER_CONTEXT_TOKEN,
|
|
7556
|
+
estimateMessageChars,
|
|
7557
|
+
estimateThreadChars,
|
|
7558
|
+
estimateOccupancyTokens,
|
|
7559
|
+
threadHasCompactedContext,
|
|
7560
|
+
forwardContextUsage,
|
|
7561
|
+
applyForwardOccupancy,
|
|
7642
7562
|
summarizeConversation,
|
|
7643
7563
|
extractiveSummary,
|
|
7644
7564
|
CONTEXT_COMPACT_CHARS,
|
|
@@ -7646,8 +7566,6 @@ export {
|
|
|
7646
7566
|
CONTEXT_KEEP_RECENT_MESSAGES,
|
|
7647
7567
|
CONTEXT_MIN_MESSAGES,
|
|
7648
7568
|
SESSION_RESET_OCCUPANCY_TOKENS,
|
|
7649
|
-
estimateMessageChars,
|
|
7650
|
-
estimateThreadChars,
|
|
7651
7569
|
shouldCompactContext,
|
|
7652
7570
|
splitForCompaction,
|
|
7653
7571
|
formatMessagesAsTranscript,
|
|
@@ -7760,12 +7678,6 @@ export {
|
|
|
7760
7678
|
discoverSkills,
|
|
7761
7679
|
readSkillBody,
|
|
7762
7680
|
expandComposerPrompt,
|
|
7763
|
-
isImageFilePath,
|
|
7764
|
-
attachmentFromAbsolutePath,
|
|
7765
|
-
stageAbsolutePathsAsAttachments,
|
|
7766
|
-
stageBuffersAsAttachments,
|
|
7767
|
-
attachmentsFromBuffers,
|
|
7768
|
-
attachmentsFromWorktreePaths,
|
|
7769
7681
|
formatRenameBranchDirective,
|
|
7770
7682
|
formatWorktreeDirective,
|
|
7771
7683
|
formatWorktreeReminder,
|