@sideboard-ai/core 0.1.136 → 0.1.142
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/{abletime-VTP4JR63.js → abletime-DI55AJX3.js} +2 -2
- package/dist/{abletime-DDTV7WO3.js → abletime-QEVAE67D.js} +2 -2
- package/dist/agents/cursor-runner.cjs +0 -0
- package/dist/agents/cursor-runner.js +1 -1
- package/dist/{agents-QNTTLMG2.js → agents-E5AAMHDY.js} +12 -8
- package/dist/{agents-ELWR7A2T.js → agents-OEEOIKUB.js} +11 -7
- package/dist/{app-settings-U5RZKUXG.js → app-settings-WJDCJFSY.js} +3 -1
- package/dist/{app-settings-YQ7YX2CC.js → app-settings-ZCN632OJ.js} +3 -1
- package/dist/caffeinate-hold-NBRUWYXO.js +0 -0
- package/dist/{chunk-4XKUHP6G.js → chunk-4D4PEBGB.js} +2 -2
- package/dist/{chunk-QAV3HGVS.js → chunk-4Q45TLZ5.js} +8 -8
- package/dist/chunk-6GN5WPYZ.js +0 -0
- package/dist/chunk-B3SJXYIJ.js +0 -0
- package/dist/chunk-BD2ICC4D.js +0 -0
- package/dist/{chunk-GKKHXZCT.js → chunk-BGQBELGJ.js} +201 -2
- package/dist/{chunk-2XXAAIN3.js → chunk-BOD5V52W.js} +1 -1
- package/dist/{chunk-JPBRMUM6.js → chunk-CG25RYQQ.js} +87 -41
- package/dist/chunk-ED4UPEJX.js +0 -0
- package/dist/{chunk-J5IBSVB3.js → chunk-EUXOHTUK.js} +42 -25
- package/dist/{chunk-K5YT5GX2.js → chunk-FADNFPZO.js} +4 -4
- package/dist/{chunk-TIGKDMIA.js → chunk-FGOD5MQ4.js} +550 -69
- package/dist/{chunk-MDCKV2NF.js → chunk-HC5N3BDL.js} +2 -2
- package/dist/{chunk-GJBHOJCZ.js → chunk-I77RYPOH.js} +201 -2
- package/dist/{chunk-WS5LFFU3.js → chunk-JUWVAMRS.js} +333 -64
- package/dist/chunk-KGZBYWZ3.js +0 -0
- package/dist/chunk-KLBOWJ74.js +0 -0
- package/dist/chunk-KPIYENTF.js +0 -0
- package/dist/chunk-N5PM7HGQ.js +0 -0
- package/dist/chunk-NSTQ6QKD.js +0 -0
- package/dist/{chunk-HQQNLDVC.js → chunk-O3JEC2UJ.js} +8 -8
- package/dist/{chunk-TQ4S5AGJ.js → chunk-OHWN4JEL.js} +7 -5
- package/dist/{chunk-GSKRGF7B.js → chunk-R2W7A2UO.js} +4 -4
- package/dist/chunk-S42XV45P.js +0 -0
- package/dist/{chunk-PM3C2J6K.js → chunk-TUGKX5BD.js} +42 -25
- package/dist/{chunk-IFZ4MOTN.js → chunk-UG5N7ET3.js} +7 -5
- package/dist/{chunk-CYM5DCHI.js → chunk-VHTIHOHE.js} +87 -42
- package/dist/{chunk-AT346U23.js → chunk-VZJVKQHH.js} +1 -1
- package/dist/{chunk-FSCQXMGI.js → chunk-WT5HSFOU.js} +1 -0
- package/dist/connected-teams-IJUJQ7R6.js +0 -0
- package/dist/{coordinator-prompt-IPL4Z6SL.js → coordinator-prompt-2LD3C74O.js} +4 -4
- package/dist/{coordinator-prompt-2OWSUAUR.js → coordinator-prompt-FBX7Y4EM.js} +4 -4
- package/dist/cursor-recover-NOQYOFRF.js +0 -0
- package/dist/{global-workspace-NIKZAKOO.js → global-workspace-NG7SU3GV.js} +5 -5
- package/dist/{global-workspace-JDUCUL7S.js → global-workspace-OCV77UYF.js} +5 -5
- package/dist/index.cjs +1064 -187
- package/dist/index.d.cts +239 -62
- package/dist/index.d.ts +239 -62
- package/dist/index.js +144 -20
- package/dist/mcp/run-stdio.cjs +759 -170
- package/dist/mcp/run-stdio.js +46 -18
- package/dist/oauth-YJBAURIJ.js +0 -0
- package/dist/{orchestrator-KK3CUW37.js → orchestrator-4BEZJ2BU.js} +8 -8
- package/dist/{orchestrator-6I47JMU2.js → orchestrator-I2T44CRP.js} +9 -9
- package/dist/paths-QCI3MTO5.js +0 -0
- package/dist/plan-file-PHVKUAEE.js +0 -0
- package/dist/run-USF6FRKV.js +0 -0
- 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/title-4WAKWZRF.js +0 -0
- package/dist/{workspaces-5EWNNALF.js → workspaces-4FUQW5LD.js} +6 -6
- package/dist/{workspaces-KZA3TCEE.js → workspaces-PU5YHQ7Z.js} +6 -6
- package/dist/{worktree-MX7XBX6Z.js → worktree-GKLPPNWR.js} +3 -3
- package/dist/{worktree-BC6XDMQK.js → worktree-Z22HTSCU.js} +3 -3
- package/package.json +9 -8
- package/LICENSE +0 -190
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
looksLikeInvalidAgentSession,
|
|
20
20
|
looksLikeV8Oom,
|
|
21
21
|
normalizeParseResult,
|
|
22
|
+
packagedMcpDir,
|
|
22
23
|
parseBrightsyCliLine,
|
|
23
24
|
parseSessionQuotaResetAt,
|
|
24
25
|
partsToAssistantText,
|
|
@@ -31,13 +32,13 @@ import {
|
|
|
31
32
|
summarizeTurnStderr,
|
|
32
33
|
toolDescription,
|
|
33
34
|
turnFailChatText
|
|
34
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-CG25RYQQ.js";
|
|
35
36
|
import {
|
|
36
37
|
addWorkspace,
|
|
37
38
|
ensureWorkspace,
|
|
38
39
|
removeWorkspace,
|
|
39
40
|
syncWorkspacesFromThreads
|
|
40
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-4D4PEBGB.js";
|
|
41
42
|
import {
|
|
42
43
|
extractPresentedPlan,
|
|
43
44
|
readPlanFile,
|
|
@@ -62,14 +63,14 @@ import {
|
|
|
62
63
|
persistPendingFileAttachments,
|
|
63
64
|
stageAbsolutePathsAsAttachments,
|
|
64
65
|
stageBuffersAsAttachments
|
|
65
|
-
} from "./chunk-
|
|
66
|
+
} from "./chunk-FADNFPZO.js";
|
|
66
67
|
import {
|
|
67
68
|
SLACK_REPLY_FORMATTING,
|
|
68
69
|
coordinatorSystemPrompt,
|
|
69
70
|
coordinatorTurnReminder,
|
|
70
71
|
enrichWorkspacesWithGithub,
|
|
71
72
|
ensureGlobalCoordinatorCwd
|
|
72
|
-
} from "./chunk-
|
|
73
|
+
} from "./chunk-OHWN4JEL.js";
|
|
73
74
|
import {
|
|
74
75
|
addPrStackLayer,
|
|
75
76
|
allocateTeamName,
|
|
@@ -114,7 +115,7 @@ import {
|
|
|
114
115
|
withRepoGitLock,
|
|
115
116
|
worktreeDisplayLabelForGroup,
|
|
116
117
|
worktreeNameFromPath
|
|
117
|
-
} from "./chunk-
|
|
118
|
+
} from "./chunk-4Q45TLZ5.js";
|
|
118
119
|
import {
|
|
119
120
|
ATTACHMENTS_DIR,
|
|
120
121
|
LEGACY_ATTACHMENTS_DIR
|
|
@@ -130,7 +131,7 @@ import {
|
|
|
130
131
|
updateThread,
|
|
131
132
|
withThreadLock,
|
|
132
133
|
writeThread
|
|
133
|
-
} from "./chunk-
|
|
134
|
+
} from "./chunk-EUXOHTUK.js";
|
|
134
135
|
import {
|
|
135
136
|
clearStaleIndexLocks,
|
|
136
137
|
enrichPathWithNpmGlobalBin,
|
|
@@ -154,7 +155,7 @@ import {
|
|
|
154
155
|
stripNestedElectronEnv,
|
|
155
156
|
updateAdvancedSettings,
|
|
156
157
|
writeSecureJson
|
|
157
|
-
} from "./chunk-
|
|
158
|
+
} from "./chunk-BGQBELGJ.js";
|
|
158
159
|
import {
|
|
159
160
|
writePrivateFile
|
|
160
161
|
} from "./chunk-NSTQ6QKD.js";
|
|
@@ -278,7 +279,7 @@ function slackTokenFor(ws, kind = "read") {
|
|
|
278
279
|
const token2 = ws.user_token?.trim();
|
|
279
280
|
if (!token2) {
|
|
280
281
|
throw new Error(
|
|
281
|
-
`Slack search needs a user token for ${ws.team_name}. Reconnect via
|
|
282
|
+
`Slack search needs a user token for ${ws.team_name}. Reconnect via Settings \u2192 Remote \u2192 Slack (browser) or paste an xoxp- token.`
|
|
282
283
|
);
|
|
283
284
|
}
|
|
284
285
|
return token2;
|
|
@@ -293,7 +294,7 @@ function requireSlackWorkspace(teamId) {
|
|
|
293
294
|
const ws = getSlackWorkspace(teamId);
|
|
294
295
|
if (!ws) {
|
|
295
296
|
const connected = listSlackWorkspaces();
|
|
296
|
-
const hint = connected.length === 0 ? "Connect a workspace in
|
|
297
|
+
const hint = connected.length === 0 ? "Connect a workspace in Settings \u2192 Remote \u2192 Slack." : `Connected: ${connected.map((t) => `${t.team_name} (${t.team_id})`).join(", ")}`;
|
|
297
298
|
throw new Error(`Unknown Slack team_id "${teamId}". ${hint}`);
|
|
298
299
|
}
|
|
299
300
|
return ws;
|
|
@@ -387,7 +388,7 @@ async function continueSourceThread(threadId, prompt) {
|
|
|
387
388
|
await continueOnReply(threadId, prompt);
|
|
388
389
|
return;
|
|
389
390
|
}
|
|
390
|
-
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-
|
|
391
|
+
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-4BEZJ2BU.js");
|
|
391
392
|
await getOrchestrator2().send(threadId, prompt);
|
|
392
393
|
} catch {
|
|
393
394
|
}
|
|
@@ -647,7 +648,7 @@ async function pollSlackOutboundWatches(opts) {
|
|
|
647
648
|
}
|
|
648
649
|
|
|
649
650
|
// src/orchestrator/orchestrator.ts
|
|
650
|
-
import { existsSync as
|
|
651
|
+
import { existsSync as existsSync16 } from "fs";
|
|
651
652
|
|
|
652
653
|
// src/agents/spawn.ts
|
|
653
654
|
import { createInterface } from "readline";
|
|
@@ -728,9 +729,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
728
729
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
729
730
|
);
|
|
730
731
|
}
|
|
731
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
732
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-OCV77UYF.js");
|
|
732
733
|
if (isGlobalThread2(thread)) {
|
|
733
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
734
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-FBX7Y4EM.js");
|
|
734
735
|
ensureGlobalCoordinatorCwd2(
|
|
735
736
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
736
737
|
);
|
|
@@ -977,6 +978,49 @@ import { dirname, join as join4 } from "path";
|
|
|
977
978
|
// src/threads/chat-tabs.ts
|
|
978
979
|
import { randomUUID } from "crypto";
|
|
979
980
|
|
|
981
|
+
// src/composer/context-estimate.ts
|
|
982
|
+
var CHARS_PER_CONTEXT_TOKEN = 4;
|
|
983
|
+
function estimateMessageChars(message) {
|
|
984
|
+
let n = message.text.length + 16;
|
|
985
|
+
for (const part of message.parts ?? []) {
|
|
986
|
+
n += estimatePartChars(part);
|
|
987
|
+
}
|
|
988
|
+
return n;
|
|
989
|
+
}
|
|
990
|
+
function estimatePartChars(part) {
|
|
991
|
+
switch (part.type) {
|
|
992
|
+
case "text":
|
|
993
|
+
case "thinking":
|
|
994
|
+
return part.text.length;
|
|
995
|
+
case "tool": {
|
|
996
|
+
const input = part.input ? JSON.stringify(part.input) : "";
|
|
997
|
+
return part.name.length + (part.description?.length ?? 0) + (part.detail?.length ?? 0) + (part.result?.length ?? 0) + input.length + 32;
|
|
998
|
+
}
|
|
999
|
+
default:
|
|
1000
|
+
return 0;
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
function estimateThreadChars(messages) {
|
|
1004
|
+
return messages.reduce((sum, m) => sum + estimateMessageChars(m), 0);
|
|
1005
|
+
}
|
|
1006
|
+
function estimateOccupancyTokens(messages) {
|
|
1007
|
+
return Math.ceil(estimateThreadChars(messages) / CHARS_PER_CONTEXT_TOKEN);
|
|
1008
|
+
}
|
|
1009
|
+
function applyForwardOccupancy(messages) {
|
|
1010
|
+
const tokens = estimateOccupancyTokens(messages);
|
|
1011
|
+
if (tokens <= 0) return messages;
|
|
1012
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
1013
|
+
const m = messages[i];
|
|
1014
|
+
if (m?.role !== "agent" || !m.usage) continue;
|
|
1015
|
+
const current = contextTokens(m.usage);
|
|
1016
|
+
if (tokens >= current) return messages;
|
|
1017
|
+
const next = messages.slice();
|
|
1018
|
+
next[i] = { ...m, usage: { ...m.usage, lastRequestTokens: tokens } };
|
|
1019
|
+
return next;
|
|
1020
|
+
}
|
|
1021
|
+
return messages;
|
|
1022
|
+
}
|
|
1023
|
+
|
|
980
1024
|
// src/composer/summarize.ts
|
|
981
1025
|
var MAX_TRANSCRIPT_CHARS = 12e4;
|
|
982
1026
|
var MAX_SUMMARY_CHARS = 6e3;
|
|
@@ -1085,29 +1129,6 @@ var CONTEXT_KEEP_RECENT_CHARS = 24e3;
|
|
|
1085
1129
|
var CONTEXT_KEEP_RECENT_MESSAGES = 12;
|
|
1086
1130
|
var CONTEXT_MIN_MESSAGES = 10;
|
|
1087
1131
|
var SESSION_RESET_OCCUPANCY_TOKENS = 75e4;
|
|
1088
|
-
function estimateMessageChars(message) {
|
|
1089
|
-
let n = message.text.length + 16;
|
|
1090
|
-
for (const part of message.parts ?? []) {
|
|
1091
|
-
n += estimatePartChars(part);
|
|
1092
|
-
}
|
|
1093
|
-
return n;
|
|
1094
|
-
}
|
|
1095
|
-
function estimatePartChars(part) {
|
|
1096
|
-
switch (part.type) {
|
|
1097
|
-
case "text":
|
|
1098
|
-
case "thinking":
|
|
1099
|
-
return part.text.length;
|
|
1100
|
-
case "tool": {
|
|
1101
|
-
const input = part.input ? JSON.stringify(part.input) : "";
|
|
1102
|
-
return part.name.length + (part.description?.length ?? 0) + (part.detail?.length ?? 0) + (part.result?.length ?? 0) + input.length + 32;
|
|
1103
|
-
}
|
|
1104
|
-
default:
|
|
1105
|
-
return 0;
|
|
1106
|
-
}
|
|
1107
|
-
}
|
|
1108
|
-
function estimateThreadChars(messages) {
|
|
1109
|
-
return messages.reduce((sum, m) => sum + estimateMessageChars(m), 0);
|
|
1110
|
-
}
|
|
1111
1132
|
function shouldCompactContext(messages, thresholds = {}) {
|
|
1112
1133
|
const maxChars = thresholds.maxChars ?? CONTEXT_COMPACT_CHARS;
|
|
1113
1134
|
const minMessages = thresholds.minMessages ?? CONTEXT_MIN_MESSAGES;
|
|
@@ -1244,8 +1265,11 @@ async function maybeCompactContext(thread, thresholds = {}, summarize = summariz
|
|
|
1244
1265
|
const { summary, method } = await summarize(transcript, {
|
|
1245
1266
|
cwd: thread.worktreePath
|
|
1246
1267
|
});
|
|
1247
|
-
|
|
1268
|
+
let messages = applyCompaction(thread.messages, summary, thresholds);
|
|
1248
1269
|
const resetSession = shouldResetSessionForOccupancy({ messages: thread.messages });
|
|
1270
|
+
if (resetSession) {
|
|
1271
|
+
messages = applyForwardOccupancy(messages);
|
|
1272
|
+
}
|
|
1249
1273
|
const next = {
|
|
1250
1274
|
...thread,
|
|
1251
1275
|
messages,
|
|
@@ -2787,7 +2811,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
2787
2811
|
});
|
|
2788
2812
|
await requireAgent(resolved.agent);
|
|
2789
2813
|
if (input.cowboy) {
|
|
2790
|
-
const { cowboyModeEnabled } = await import("./app-settings-
|
|
2814
|
+
const { cowboyModeEnabled } = await import("./app-settings-ZCN632OJ.js");
|
|
2791
2815
|
if (!cowboyModeEnabled()) {
|
|
2792
2816
|
throw new Error(
|
|
2793
2817
|
"Cowboy mode is off. Enable it in Settings \u2192 Advanced."
|
|
@@ -2843,7 +2867,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
2843
2867
|
let sourceIsFork = false;
|
|
2844
2868
|
if (!input.cowboy && sourceType === "branch" && (!sourceRef || sourceRef === "HEAD" || sourceRef === "default")) {
|
|
2845
2869
|
if (isAbleTimeConnected() && getIssueSource() === "abletime") {
|
|
2846
|
-
const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-
|
|
2870
|
+
const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-DI55AJX3.js");
|
|
2847
2871
|
const task = await ensureAbleTimeTask({
|
|
2848
2872
|
title: title?.trim() || "Untitled work",
|
|
2849
2873
|
description: input.prompt?.trim() || void 0
|
|
@@ -2916,7 +2940,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
2916
2940
|
return readThread(thread.id) ?? thread;
|
|
2917
2941
|
}
|
|
2918
2942
|
async function listLinearIssues(agent, repoPath) {
|
|
2919
|
-
const { getAdapter: getAdapter2 } = await import("./agents-
|
|
2943
|
+
const { getAdapter: getAdapter2 } = await import("./agents-OEEOIKUB.js");
|
|
2920
2944
|
await requireAgent(agent, { requireLinear: true });
|
|
2921
2945
|
const adapter = getAdapter2(agent);
|
|
2922
2946
|
if (!adapter.listLinearIssues) {
|
|
@@ -3313,7 +3337,7 @@ async function adoptThread(input) {
|
|
|
3313
3337
|
messages: input.messages ?? []
|
|
3314
3338
|
});
|
|
3315
3339
|
writeThread(thread);
|
|
3316
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
3340
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-4FUQW5LD.js");
|
|
3317
3341
|
await ensureWorkspace2(repoPath);
|
|
3318
3342
|
return thread;
|
|
3319
3343
|
}
|
|
@@ -4643,6 +4667,93 @@ async function confirmLand(thread, opts) {
|
|
|
4643
4667
|
import { existsSync as existsSync12, readdirSync as readdirSync4, readFileSync as readFileSync9, statSync as statSync3 } from "fs";
|
|
4644
4668
|
import { homedir } from "os";
|
|
4645
4669
|
import { join as join11 } from "path";
|
|
4670
|
+
|
|
4671
|
+
// src/skills/bundled/long-running.ts
|
|
4672
|
+
var LONG_RUNNING_SKILL_COMMAND = "long-running";
|
|
4673
|
+
var LONG_RUNNING_SKILL_NAME = "long-running";
|
|
4674
|
+
var BUNDLED_LONG_RUNNING_PATH = "bundled:long-running";
|
|
4675
|
+
var LONG_RUNNING_SKILL_DESCRIPTION = "Detach and wait on any long worktree job (pack, test, deploy) so a new chat turn does not SIGTERM it, and the human does not have to poll. Use when a command may run more than ~30s, or the user mentions wait / status / aborted builds.";
|
|
4676
|
+
var LONG_RUNNING_SKILL_BODY = `# Long-running jobs
|
|
4677
|
+
|
|
4678
|
+
A Sideboard or Cursor **worktree turn** SIGTERMs the agent shell (and its process group) when the user sends another message or the turn is interrupted. \`block_until_ms: 0\` is not enough \u2014 the child stays in that group.
|
|
4679
|
+
|
|
4680
|
+
Do **not** ask the human to check back. Detach, then **wait** in 45s slices (same idea as MCP \`wait_for_turn\`) until \`stillRunning\` is false.
|
|
4681
|
+
|
|
4682
|
+
## Tool
|
|
4683
|
+
|
|
4684
|
+
Use the helper from the Sideboard playbook \u2014 an absolute \`node "\u2026" start\` path injected each turn. If this worktree has \`scripts/detached-job.js\`, that is the same tool.
|
|
4685
|
+
|
|
4686
|
+
\`\`\`bash
|
|
4687
|
+
# Start (exits in ~1s; job survives this turn)
|
|
4688
|
+
node <detached-job.js> start <id> -- <command> [args...]
|
|
4689
|
+
|
|
4690
|
+
# Wait \u2014 returns within ~45s even if the job is still going
|
|
4691
|
+
node <detached-job.js> wait <id>
|
|
4692
|
+
|
|
4693
|
+
# Block until the process exits (humans / a turn that will not be interrupted)
|
|
4694
|
+
node <detached-job.js> wait <id> --until-done
|
|
4695
|
+
|
|
4696
|
+
node <detached-job.js> status <id>
|
|
4697
|
+
\`\`\`
|
|
4698
|
+
|
|
4699
|
+
\`<id>\` is kebab-case (\`mac-release\`, \`core-test\`, \`fly-deploy\`). State is \`.sideboard/detached-jobs/<id>/\` (local scratch).
|
|
4700
|
+
|
|
4701
|
+
Wait JSON:
|
|
4702
|
+
|
|
4703
|
+
- \`stillRunning: true\` \u2192 exit 2 \u2192 **call wait again**. Progress is in \`progress\` / \`phase\`. Do not start a second job. Do not ping the user.
|
|
4704
|
+
- \`ok: true\` \u2192 exit 0 \u2192 continue the rest of the task.
|
|
4705
|
+
- \`failed: true\` \u2192 exit 1 \u2192 read \`progress\`, fix, start **once**.
|
|
4706
|
+
|
|
4707
|
+
## Sideboard UI (append-only log)
|
|
4708
|
+
|
|
4709
|
+
The side column **is** the live view. Use \`present_artifact\` **\`type=log\`** with a stable \`artifact_id\` (the job id). Each call **appends** \u2014 send only \`delta\` from wait JSON, not the full log and not HTML.
|
|
4710
|
+
|
|
4711
|
+
\`\`\`
|
|
4712
|
+
present_artifact
|
|
4713
|
+
title: <short title>
|
|
4714
|
+
type: log
|
|
4715
|
+
artifact_id: <id>
|
|
4716
|
+
content: <wait.delta> # new lines only; empty is ok
|
|
4717
|
+
status: running | ok | failed # from wait.status
|
|
4718
|
+
phase: <wait.phase>
|
|
4719
|
+
\`\`\`
|
|
4720
|
+
|
|
4721
|
+
After **start**, present once (\`status=running\`, empty or first lines). After **every wait**, present the same id with \`content=delta\`. Do **not** dump the log in chat. Do **not** also fence HTML.
|
|
4722
|
+
|
|
4723
|
+
Ad-hoc pid/log (legacy or another tool\u2019s files):
|
|
4724
|
+
|
|
4725
|
+
\`\`\`bash
|
|
4726
|
+
node <detached-job.js> wait --pid-file FILE --log-file FILE [--ok-pattern TEXT]
|
|
4727
|
+
\`\`\`
|
|
4728
|
+
|
|
4729
|
+
## Agent loop
|
|
4730
|
+
|
|
4731
|
+
1. \`start\` once. If JSON says \`already-running\`, do not start again.
|
|
4732
|
+
2. Immediately \`present_artifact\` \`type=log\` (same \`artifact_id\`, \`status=running\`) \u2014 the human should see **working** in the side column, not a \u201Ccheck back later\u201D message.
|
|
4733
|
+
3. Loop \`wait\` (use \`--timeout-ms 15000\` for a livelier pane). After each slice, \`present_artifact\` the same id with \`content=delta\` only.
|
|
4734
|
+
4. On \`ok\`, present once more (\`status=ok\`, last \`delta\`) and finish the task. On \`failed\`, fix from the log.
|
|
4735
|
+
|
|
4736
|
+
Never tell the user \u201Csay status when it\u2019s done.\u201D You wait.
|
|
4737
|
+
`;
|
|
4738
|
+
|
|
4739
|
+
// src/skills/discover.ts
|
|
4740
|
+
var BUNDLED_SKILL_PREFIX = "bundled:";
|
|
4741
|
+
function bundledSkills() {
|
|
4742
|
+
return [
|
|
4743
|
+
{
|
|
4744
|
+
id: BUNDLED_LONG_RUNNING_PATH,
|
|
4745
|
+
name: LONG_RUNNING_SKILL_NAME,
|
|
4746
|
+
command: LONG_RUNNING_SKILL_COMMAND,
|
|
4747
|
+
description: LONG_RUNNING_SKILL_DESCRIPTION.slice(0, 240),
|
|
4748
|
+
path: BUNDLED_LONG_RUNNING_PATH,
|
|
4749
|
+
source: "bundled"
|
|
4750
|
+
}
|
|
4751
|
+
];
|
|
4752
|
+
}
|
|
4753
|
+
function bundledSkillBody(id) {
|
|
4754
|
+
if (id === LONG_RUNNING_SKILL_COMMAND) return LONG_RUNNING_SKILL_BODY;
|
|
4755
|
+
return null;
|
|
4756
|
+
}
|
|
4646
4757
|
function toCommand(name) {
|
|
4647
4758
|
return name.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
4648
4759
|
}
|
|
@@ -4760,7 +4871,13 @@ function discoverSkills(worktreePath) {
|
|
|
4760
4871
|
scanSkillsDir(abs, "user", collected);
|
|
4761
4872
|
}
|
|
4762
4873
|
scanClaudePluginSkills(join11(home, ".claude/plugins"), collected);
|
|
4763
|
-
|
|
4874
|
+
collected.push(...bundledSkills());
|
|
4875
|
+
const rank = {
|
|
4876
|
+
workspace: 0,
|
|
4877
|
+
user: 1,
|
|
4878
|
+
cli: 2,
|
|
4879
|
+
bundled: 3
|
|
4880
|
+
};
|
|
4764
4881
|
const byCommand = /* @__PURE__ */ new Map();
|
|
4765
4882
|
for (const skill of collected) {
|
|
4766
4883
|
const prev = byCommand.get(skill.command);
|
|
@@ -4771,6 +4888,14 @@ function discoverSkills(worktreePath) {
|
|
|
4771
4888
|
return [...byCommand.values()].sort((a, b) => a.command.localeCompare(b.command));
|
|
4772
4889
|
}
|
|
4773
4890
|
function readSkillBody(skillPath, maxChars = 12e3) {
|
|
4891
|
+
if (skillPath.startsWith(BUNDLED_SKILL_PREFIX)) {
|
|
4892
|
+
const body = bundledSkillBody(skillPath.slice(BUNDLED_SKILL_PREFIX.length));
|
|
4893
|
+
if (body) {
|
|
4894
|
+
return body.length > maxChars ? `${body.slice(0, maxChars)}
|
|
4895
|
+
|
|
4896
|
+
\u2026(truncated)` : body;
|
|
4897
|
+
}
|
|
4898
|
+
}
|
|
4774
4899
|
const raw = readFileSync9(skillPath, "utf8");
|
|
4775
4900
|
if (raw.startsWith("---")) {
|
|
4776
4901
|
const end = raw.indexOf("\n---", 3);
|
|
@@ -4864,8 +4989,39 @@ function expandComposerPrompt(worktreePath, prompt, opts) {
|
|
|
4864
4989
|
}
|
|
4865
4990
|
|
|
4866
4991
|
// src/agents/instructions.ts
|
|
4867
|
-
import { existsSync as
|
|
4868
|
-
import { join as
|
|
4992
|
+
import { existsSync as existsSync14, readFileSync as readFileSync10, statSync as statSync4 } from "fs";
|
|
4993
|
+
import { join as join13 } from "path";
|
|
4994
|
+
|
|
4995
|
+
// src/skills/detached-job-path.ts
|
|
4996
|
+
import { existsSync as existsSync13 } from "fs";
|
|
4997
|
+
import { dirname as dirname4, join as join12 } from "path";
|
|
4998
|
+
import { fileURLToPath } from "url";
|
|
4999
|
+
function packagedDetachedJobPath() {
|
|
5000
|
+
const dir = packagedMcpDir();
|
|
5001
|
+
if (!dir) return null;
|
|
5002
|
+
const script = join12(dir, "scripts", "detached-job.js");
|
|
5003
|
+
return existsSync13(script) ? script : null;
|
|
5004
|
+
}
|
|
5005
|
+
function resolveDetachedJobScript() {
|
|
5006
|
+
const packaged = packagedDetachedJobPath();
|
|
5007
|
+
if (packaged) return packaged;
|
|
5008
|
+
let dir = dirname4(fileURLToPath(import.meta.url));
|
|
5009
|
+
for (let i = 0; i < 8; i++) {
|
|
5010
|
+
const candidate = join12(dir, "scripts", "detached-job.js");
|
|
5011
|
+
if (existsSync13(candidate)) return candidate;
|
|
5012
|
+
const parent = dirname4(dir);
|
|
5013
|
+
if (parent === dir) break;
|
|
5014
|
+
dir = parent;
|
|
5015
|
+
}
|
|
5016
|
+
return null;
|
|
5017
|
+
}
|
|
5018
|
+
function formatDetachedJobInvoke(scriptPath) {
|
|
5019
|
+
const resolved = scriptPath === void 0 ? resolveDetachedJobScript() : scriptPath;
|
|
5020
|
+
if (resolved) return `node ${JSON.stringify(resolved)}`;
|
|
5021
|
+
return "node scripts/detached-job.js";
|
|
5022
|
+
}
|
|
5023
|
+
|
|
5024
|
+
// src/agents/instructions.ts
|
|
4869
5025
|
function normPath(p) {
|
|
4870
5026
|
return p.replace(/\/+$/, "");
|
|
4871
5027
|
}
|
|
@@ -4973,6 +5129,7 @@ function formatWorktreeReminder() {
|
|
|
4973
5129
|
function formatProcessGuideDirective() {
|
|
4974
5130
|
return [
|
|
4975
5131
|
"Process guides (recurring work only):",
|
|
5132
|
+
"- Long jobs (pack, test, deploy, anything that may run more than ~30s): Sideboard always provides `/long-running`. Detach and wait \u2014 do not ask the human to poll.",
|
|
4976
5133
|
"- If `.claude/skills/graph-engineering/SKILL.md` exists, follow it (`/graph-engineering`) for migrations, ports, batch fixes, and other fan-out. Judge first; state on disk; grow the rulebook; do not patch around it.",
|
|
4977
5134
|
"- If this same shape of work will happen again, write `.claude/skills/<kebab-name>/SKILL.md` in this worktree (Claude Code project skill). Sideboard `/name`, Claude Code, and `attach` all load that path. Do not leave the method only in chat.",
|
|
4978
5135
|
"- Merge-readiness notes: create or edit `.claude/skills/review/SKILL.md` and commit it. That file is allowed. Do not use `.sideboard/review.md` for new notes (legacy; setup copies it into the skill).",
|
|
@@ -4980,6 +5137,23 @@ function formatProcessGuideDirective() {
|
|
|
4980
5137
|
"- Skip a guide for a one-off. If a matching skill exists, follow it. Same miss twice \u2192 edit the skill, do not patch around it."
|
|
4981
5138
|
].join("\n");
|
|
4982
5139
|
}
|
|
5140
|
+
function formatLongRunningDirective(opts) {
|
|
5141
|
+
const invoke = formatDetachedJobInvoke(opts?.scriptPath);
|
|
5142
|
+
return [
|
|
5143
|
+
"Long-running jobs (mandatory when a command may run more than ~30s):",
|
|
5144
|
+
"A Sideboard worktree turn SIGTERMs the agent shell (and its process group) when the user sends another message or the turn is interrupted. `block_until_ms: 0` is not enough. Do not ask the human to poll.",
|
|
5145
|
+
`Helper (same tool as \`scripts/detached-job.js\` when that file exists in the worktree): \`${invoke}\``,
|
|
5146
|
+
`- Start once: \`${invoke} start <id> -- <command> [args...]\` (cwd = this worktree). If JSON says already-running, do not start again.`,
|
|
5147
|
+
"- Immediately `present_artifact` `type=log` with `artifact_id=<id>` and `status=running` \u2014 the side column is the live view.",
|
|
5148
|
+
`- Loop \`${invoke} wait <id>\` (returns in ~45s). stillRunning \u2192 present the same id with \`content=delta\` only \u2192 wait again. Do not resend the full log or HTML.`,
|
|
5149
|
+
"- ok \u2192 finish the task. failed \u2192 read the log, fix, start once.",
|
|
5150
|
+
"State: `.sideboard/detached-jobs/<id>/` (local scratch). Full guide: `/long-running` (always available)."
|
|
5151
|
+
].join("\n");
|
|
5152
|
+
}
|
|
5153
|
+
function formatLongRunningReminder(opts) {
|
|
5154
|
+
const invoke = formatDetachedJobInvoke(opts?.scriptPath);
|
|
5155
|
+
return `Long jobs: \`${invoke} start <id> -- <cmd>\`, loop wait, present_artifact type=log (delta). Do not ask the human to poll.`;
|
|
5156
|
+
}
|
|
4983
5157
|
function formatArtifactDirective() {
|
|
4984
5158
|
return [
|
|
4985
5159
|
"Sideboard side column (desktop UI):",
|
|
@@ -5009,6 +5183,91 @@ function formatUiReminder() {
|
|
|
5009
5183
|
return "Sideboard UI: markdown table is enough to read data; present_schema if they ask to edit/filter (even after markdown); present_files for the file manager. html fence or present_artifact, not both for the same document. type=log appends (same artifact_id, new lines only). ask_user only for a real multiple-choice (not hellos or \u201Cwhat next?\u201D) \u2014 reply in chat. Do not say artifacts/CMS UI are unavailable.";
|
|
5010
5184
|
}
|
|
5011
5185
|
|
|
5186
|
+
// src/integrations/optional-services.ts
|
|
5187
|
+
var OPTIONAL_SERVICES = [
|
|
5188
|
+
{
|
|
5189
|
+
id: "vercel",
|
|
5190
|
+
label: "Vercel",
|
|
5191
|
+
hint: "Deploys and project settings. Agents use the `vercel` CLI (`VERCEL_TOKEN`).",
|
|
5192
|
+
tokenPlaceholder: "token from vercel.com/account/tokens",
|
|
5193
|
+
tokenDocs: "https://vercel.com/account/tokens",
|
|
5194
|
+
envKey: "VERCEL_TOKEN",
|
|
5195
|
+
cli: "vercel",
|
|
5196
|
+
npmPackage: "vercel"
|
|
5197
|
+
},
|
|
5198
|
+
{
|
|
5199
|
+
id: "supabase",
|
|
5200
|
+
label: "Supabase",
|
|
5201
|
+
hint: "Database and project management. Agents use the `supabase` CLI (`SUPABASE_ACCESS_TOKEN`).",
|
|
5202
|
+
tokenPlaceholder: "sbp_\u2026",
|
|
5203
|
+
tokenDocs: "https://supabase.com/dashboard/account/tokens",
|
|
5204
|
+
envKey: "SUPABASE_ACCESS_TOKEN",
|
|
5205
|
+
cli: "supabase",
|
|
5206
|
+
npmPackage: "supabase"
|
|
5207
|
+
},
|
|
5208
|
+
{
|
|
5209
|
+
id: "posthog",
|
|
5210
|
+
label: "PostHog",
|
|
5211
|
+
hint: "Product analytics. No first-class CLI \u2014 agents use the HTTP API (`POSTHOG_PERSONAL_API_KEY`).",
|
|
5212
|
+
tokenPlaceholder: "phx_\u2026",
|
|
5213
|
+
tokenDocs: "https://app.posthog.com/settings/user-api-keys",
|
|
5214
|
+
envKey: "POSTHOG_PERSONAL_API_KEY",
|
|
5215
|
+
hostEnvKey: "POSTHOG_HOST",
|
|
5216
|
+
defaultHost: "https://us.posthog.com",
|
|
5217
|
+
hostPlaceholder: "https://us.posthog.com"
|
|
5218
|
+
},
|
|
5219
|
+
{
|
|
5220
|
+
id: "sentry",
|
|
5221
|
+
label: "Sentry",
|
|
5222
|
+
hint: "Error tracking. Agents use `sentry-cli` (`SENTRY_AUTH_TOKEN`).",
|
|
5223
|
+
tokenPlaceholder: "sntrys_\u2026 or auth token",
|
|
5224
|
+
tokenDocs: "https://sentry.io/settings/account/api/auth-tokens/",
|
|
5225
|
+
envKey: "SENTRY_AUTH_TOKEN",
|
|
5226
|
+
cli: "sentry-cli",
|
|
5227
|
+
npmPackage: "@sentry/cli",
|
|
5228
|
+
hostEnvKey: "SENTRY_URL",
|
|
5229
|
+
defaultHost: "https://sentry.io",
|
|
5230
|
+
hostPlaceholder: "https://sentry.io"
|
|
5231
|
+
}
|
|
5232
|
+
];
|
|
5233
|
+
function optionalServiceConnected(id, integrations) {
|
|
5234
|
+
if (id === "vercel") return Boolean(integrations.vercelToken?.trim());
|
|
5235
|
+
if (id === "supabase") return Boolean(integrations.supabaseAccessToken?.trim());
|
|
5236
|
+
if (id === "posthog") return Boolean(integrations.posthogPersonalApiKey?.trim());
|
|
5237
|
+
return Boolean(integrations.sentryAuthToken?.trim());
|
|
5238
|
+
}
|
|
5239
|
+
function connectedOptionalServices(integrations) {
|
|
5240
|
+
return OPTIONAL_SERVICES.filter((spec) => optionalServiceConnected(spec.id, integrations));
|
|
5241
|
+
}
|
|
5242
|
+
function formatOptionalServicesDirective(integrations) {
|
|
5243
|
+
const connected = connectedOptionalServices(integrations);
|
|
5244
|
+
if (connected.length === 0) return null;
|
|
5245
|
+
const lines = [
|
|
5246
|
+
"Optional connectors (connected \u2014 tokens are already in this process env):"
|
|
5247
|
+
];
|
|
5248
|
+
for (const spec of connected) {
|
|
5249
|
+
if (spec.cli) {
|
|
5250
|
+
const extras = spec.hostEnvKey ? ` / \`${spec.hostEnvKey}\`` : "";
|
|
5251
|
+
lines.push(
|
|
5252
|
+
`- ${spec.label}: use the \`${spec.cli}\` CLI (\`${spec.envKey}\`${extras}). Do not add a ${spec.label} MCP.`
|
|
5253
|
+
);
|
|
5254
|
+
} else {
|
|
5255
|
+
const extras = spec.hostEnvKey ? ` / \`${spec.hostEnvKey}\`` : "";
|
|
5256
|
+
lines.push(
|
|
5257
|
+
`- ${spec.label}: no first-class CLI \u2014 call the HTTP API with \`${spec.envKey}\`${extras}. Do not add a ${spec.label} MCP.`
|
|
5258
|
+
);
|
|
5259
|
+
}
|
|
5260
|
+
}
|
|
5261
|
+
lines.push(
|
|
5262
|
+
"If a CLI is missing, say so or use the HTTP API with the same token. The user can Install CLI from Settings \u2192 Connectors. Do not ask the user to install a vendor MCP."
|
|
5263
|
+
);
|
|
5264
|
+
return lines.join("\n");
|
|
5265
|
+
}
|
|
5266
|
+
function formatOptionalServicesReminder(integrations) {
|
|
5267
|
+
if (connectedOptionalServices(integrations).length === 0) return null;
|
|
5268
|
+
return "Settings \u2192 Connectors: prefer official CLIs (`vercel`, `supabase`, `sentry-cli`) or the PostHog HTTP API with injected env. Do not add vendor MCPs.";
|
|
5269
|
+
}
|
|
5270
|
+
|
|
5012
5271
|
// src/threads/sync-branch.ts
|
|
5013
5272
|
async function syncThreadBranchFromGit(threadId) {
|
|
5014
5273
|
const thread = readThread(threadId);
|
|
@@ -5041,8 +5300,8 @@ async function syncThreadBranchFromGit(threadId) {
|
|
|
5041
5300
|
|
|
5042
5301
|
// src/store/schedules.ts
|
|
5043
5302
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
5044
|
-
import { existsSync as
|
|
5045
|
-
import { join as
|
|
5303
|
+
import { existsSync as existsSync15, readFileSync as readFileSync11 } from "fs";
|
|
5304
|
+
import { join as join14 } from "path";
|
|
5046
5305
|
import { Cron } from "croner";
|
|
5047
5306
|
var DURATION_RE = /^(\d+)(s|m|h|d)$/i;
|
|
5048
5307
|
var UNIT_MS = {
|
|
@@ -5052,7 +5311,7 @@ var UNIT_MS = {
|
|
|
5052
5311
|
d: 864e5
|
|
5053
5312
|
};
|
|
5054
5313
|
function schedulesPath() {
|
|
5055
|
-
return
|
|
5314
|
+
return join14(appDataDir(), "schedules.json");
|
|
5056
5315
|
}
|
|
5057
5316
|
function parseDurationMs(every) {
|
|
5058
5317
|
const m = every.trim().match(DURATION_RE);
|
|
@@ -5152,7 +5411,7 @@ function normalizeTask(raw) {
|
|
|
5152
5411
|
}
|
|
5153
5412
|
function readAll() {
|
|
5154
5413
|
const path = schedulesPath();
|
|
5155
|
-
if (!
|
|
5414
|
+
if (!existsSync15(path)) return [];
|
|
5156
5415
|
try {
|
|
5157
5416
|
const parsed = JSON.parse(readFileSync11(path, "utf8"));
|
|
5158
5417
|
if (!Array.isArray(parsed)) return [];
|
|
@@ -5277,7 +5536,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
5277
5536
|
${prompt}`;
|
|
5278
5537
|
}
|
|
5279
5538
|
async function defaultDeps() {
|
|
5280
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
5539
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-4BEZJ2BU.js");
|
|
5281
5540
|
const orch = getOrchestrator2();
|
|
5282
5541
|
return {
|
|
5283
5542
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -5483,7 +5742,7 @@ var Orchestrator = class {
|
|
|
5483
5742
|
}
|
|
5484
5743
|
continue;
|
|
5485
5744
|
}
|
|
5486
|
-
if (!
|
|
5745
|
+
if (!existsSync16(thread.worktreePath)) {
|
|
5487
5746
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
5488
5747
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
5489
5748
|
continue;
|
|
@@ -5502,7 +5761,7 @@ var Orchestrator = class {
|
|
|
5502
5761
|
orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
|
|
5503
5762
|
});
|
|
5504
5763
|
}
|
|
5505
|
-
const { autoCleanupOrphansEnabled } = await import("./app-settings-
|
|
5764
|
+
const { autoCleanupOrphansEnabled } = await import("./app-settings-ZCN632OJ.js");
|
|
5506
5765
|
if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
|
|
5507
5766
|
await cleanupOrphanWorktrees({ repoPaths });
|
|
5508
5767
|
}
|
|
@@ -5553,7 +5812,7 @@ var Orchestrator = class {
|
|
|
5553
5812
|
if (thread.status === "archived") continue;
|
|
5554
5813
|
const handle = this.activeTurns.get(thread.id);
|
|
5555
5814
|
if (handle) {
|
|
5556
|
-
const pid =
|
|
5815
|
+
const pid = handle.pid;
|
|
5557
5816
|
if (typeof pid === "number" && pid > 0 && !isPidAlive(pid)) {
|
|
5558
5817
|
handle.kill();
|
|
5559
5818
|
}
|
|
@@ -5742,7 +6001,7 @@ var Orchestrator = class {
|
|
|
5742
6001
|
}
|
|
5743
6002
|
await setup;
|
|
5744
6003
|
if (skipSetup) return;
|
|
5745
|
-
const { autoRunAfterSetupEnabled } = await import("./app-settings-
|
|
6004
|
+
const { autoRunAfterSetupEnabled } = await import("./app-settings-ZCN632OJ.js");
|
|
5746
6005
|
if (autoRunAfterSetupEnabled()) {
|
|
5747
6006
|
try {
|
|
5748
6007
|
await this.startDev(threadId);
|
|
@@ -6004,7 +6263,9 @@ var Orchestrator = class {
|
|
|
6004
6263
|
].join("\n") : null
|
|
6005
6264
|
].filter(Boolean).join("\n") : null;
|
|
6006
6265
|
const artifactReminder = thread.agent !== "brightsy" ? formatUiReminder() : null;
|
|
6266
|
+
const longRunningReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatLongRunningReminder() : null;
|
|
6007
6267
|
const worktreeReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatWorktreeReminder() : null;
|
|
6268
|
+
const optionalServicesReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatOptionalServicesReminder(loadAppSettings().integrations) : null;
|
|
6008
6269
|
const slackReplyContext = formatSlackRepliesForTurn(
|
|
6009
6270
|
pendingSlackExternalReplies(thread.messages)
|
|
6010
6271
|
);
|
|
@@ -6012,7 +6273,9 @@ var Orchestrator = class {
|
|
|
6012
6273
|
thread.planMode ? PLAN_MODE_INSTRUCTION : null,
|
|
6013
6274
|
orchestrationReminder,
|
|
6014
6275
|
worktreeReminder,
|
|
6276
|
+
optionalServicesReminder,
|
|
6015
6277
|
artifactReminder,
|
|
6278
|
+
longRunningReminder,
|
|
6016
6279
|
slackReplyContext,
|
|
6017
6280
|
expandedPrompt
|
|
6018
6281
|
].filter(Boolean).join("\n\n");
|
|
@@ -6032,7 +6295,7 @@ var Orchestrator = class {
|
|
|
6032
6295
|
}
|
|
6033
6296
|
const isBrightsy = fresh.agent === "brightsy";
|
|
6034
6297
|
const isOrchestration = isOrchestratorThread(fresh);
|
|
6035
|
-
const { autoRenameBranchEnabled, getGithubGitAuthMode } = await import("./app-settings-
|
|
6298
|
+
const { autoRenameBranchEnabled, getGithubGitAuthMode } = await import("./app-settings-ZCN632OJ.js");
|
|
6036
6299
|
const gitAuthMode = getGithubGitAuthMode();
|
|
6037
6300
|
const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
|
|
6038
6301
|
githubSlug: await resolveGithubRepoSlug(fresh.worktreePath).catch(
|
|
@@ -6041,6 +6304,8 @@ var Orchestrator = class {
|
|
|
6041
6304
|
gitAuthMode
|
|
6042
6305
|
});
|
|
6043
6306
|
const artifactDirective = isBrightsy ? null : formatArtifactDirective();
|
|
6307
|
+
const longRunningDirective = isBrightsy || isOrchestration ? null : formatLongRunningDirective();
|
|
6308
|
+
const optionalServicesDirective = isBrightsy || isOrchestration ? null : formatOptionalServicesDirective(loadAppSettings().integrations);
|
|
6044
6309
|
const settings = loadWorkspaceSettings(fresh.worktreePath, fresh.repoPath);
|
|
6045
6310
|
const renameBranchDirective = !isBrightsy && !isOrchestration && autoRenameBranchEnabled() ? formatRenameBranchDirective(fresh, {
|
|
6046
6311
|
customPrompt: settings?.prompts?.renameBranch
|
|
@@ -6070,7 +6335,9 @@ var Orchestrator = class {
|
|
|
6070
6335
|
const cachedPrefix = fresh.sessionId ? "" : [
|
|
6071
6336
|
coordinatorDirective,
|
|
6072
6337
|
worktreeDirective,
|
|
6338
|
+
optionalServicesDirective,
|
|
6073
6339
|
artifactDirective,
|
|
6340
|
+
longRunningDirective,
|
|
6074
6341
|
renameBranchDirective,
|
|
6075
6342
|
seed
|
|
6076
6343
|
].filter(Boolean).join("\n\n---\n\n");
|
|
@@ -6177,7 +6444,9 @@ var Orchestrator = class {
|
|
|
6177
6444
|
const retryPrefix = [
|
|
6178
6445
|
coordinatorDirective,
|
|
6179
6446
|
worktreeDirective,
|
|
6447
|
+
optionalServicesDirective,
|
|
6180
6448
|
artifactDirective,
|
|
6449
|
+
longRunningDirective,
|
|
6181
6450
|
renameBranchDirective,
|
|
6182
6451
|
retrySeed
|
|
6183
6452
|
].filter(Boolean).join("\n\n---\n\n");
|
|
@@ -6377,7 +6646,7 @@ var Orchestrator = class {
|
|
|
6377
6646
|
const stopped = writeLiveStatus(thread.id, "stopped") ?? readThread(thread.id) ?? thread;
|
|
6378
6647
|
if (stopped.status === "stopped") {
|
|
6379
6648
|
this.emit({ type: "status_changed", threadId: thread.id, status: "stopped" });
|
|
6380
|
-
if (opts?.notifyParent !== false) {
|
|
6649
|
+
if (inFlight && opts?.notifyParent !== false) {
|
|
6381
6650
|
notifyParentOfChildHalt(stopped, "stopped", (id, prompt) => this.send(id, prompt));
|
|
6382
6651
|
}
|
|
6383
6652
|
}
|
|
@@ -6854,7 +7123,7 @@ var Orchestrator = class {
|
|
|
6854
7123
|
updateThread(thread.id, { title: meta.title });
|
|
6855
7124
|
}
|
|
6856
7125
|
}
|
|
6857
|
-
const { autoArchiveOnMergeEnabled } = await import("./app-settings-
|
|
7126
|
+
const { autoArchiveOnMergeEnabled } = await import("./app-settings-ZCN632OJ.js");
|
|
6858
7127
|
const latest = this.requireThread(thread.id);
|
|
6859
7128
|
if (!shouldAutoArchiveOnPrMerge({
|
|
6860
7129
|
previousPrState: prevState || null,
|
|
@@ -7136,7 +7405,7 @@ var Orchestrator = class {
|
|
|
7136
7405
|
}
|
|
7137
7406
|
async archiveUnlocked(threadRef) {
|
|
7138
7407
|
const thread = this.requireThread(threadRef);
|
|
7139
|
-
this.stop(thread.id);
|
|
7408
|
+
this.stop(thread.id, { notifyParent: false });
|
|
7140
7409
|
this.releaseOrchestratorCaffeinate(thread);
|
|
7141
7410
|
if (isGlobalThread(thread)) {
|
|
7142
7411
|
const archived2 = setStatus(thread.id, "archived");
|
|
@@ -7164,7 +7433,7 @@ var Orchestrator = class {
|
|
|
7164
7433
|
this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
|
|
7165
7434
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
7166
7435
|
try {
|
|
7167
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
7436
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-4FUQW5LD.js");
|
|
7168
7437
|
await ensureWorkspace2(thread.repoPath);
|
|
7169
7438
|
} catch {
|
|
7170
7439
|
}
|
|
@@ -7177,7 +7446,7 @@ var Orchestrator = class {
|
|
|
7177
7446
|
}
|
|
7178
7447
|
async purgeUnlocked(threadRef, opts) {
|
|
7179
7448
|
const thread = this.requireThread(threadRef);
|
|
7180
|
-
this.stop(thread.id);
|
|
7449
|
+
this.stop(thread.id, { notifyParent: false });
|
|
7181
7450
|
this.releaseOrchestratorCaffeinate(thread);
|
|
7182
7451
|
if (isGlobalThread(thread)) {
|
|
7183
7452
|
deleteThreadRecord(thread.id);
|
|
@@ -7191,7 +7460,7 @@ var Orchestrator = class {
|
|
|
7191
7460
|
await runArchiveScript(thread.repoPath, thread.worktreePath);
|
|
7192
7461
|
} catch {
|
|
7193
7462
|
}
|
|
7194
|
-
const { deleteBranchOnPurgeEnabled } = await import("./app-settings-
|
|
7463
|
+
const { deleteBranchOnPurgeEnabled } = await import("./app-settings-ZCN632OJ.js");
|
|
7195
7464
|
const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
|
|
7196
7465
|
await removeWorktree(thread.repoPath, thread.worktreePath, {
|
|
7197
7466
|
deleteBranch: deleteBranch ? thread.branchName : void 0
|
|
@@ -7212,13 +7481,13 @@ var Orchestrator = class {
|
|
|
7212
7481
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
7213
7482
|
return restored2;
|
|
7214
7483
|
}
|
|
7215
|
-
if (!
|
|
7484
|
+
if (!existsSync16(thread.worktreePath)) {
|
|
7216
7485
|
if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
|
|
7217
7486
|
throw new Error(
|
|
7218
7487
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
7219
7488
|
);
|
|
7220
7489
|
}
|
|
7221
|
-
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-
|
|
7490
|
+
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-Z22HTSCU.js");
|
|
7222
7491
|
const slug = thread.worktreePath.split("/").pop();
|
|
7223
7492
|
const dest = thread.worktreePath;
|
|
7224
7493
|
await withRepoGitLock(thread.repoPath, async () => {
|
|
@@ -7326,7 +7595,7 @@ async function startOrchestration(opts) {
|
|
|
7326
7595
|
sourceRef: "default",
|
|
7327
7596
|
...createOpts
|
|
7328
7597
|
}).catch(async () => {
|
|
7329
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
7598
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-Z22HTSCU.js");
|
|
7330
7599
|
const repo = await resolveRepoRoot2(repoPath);
|
|
7331
7600
|
const def = await resolveDefaultBranch2(repo);
|
|
7332
7601
|
return orch.createThread({
|
|
@@ -7336,7 +7605,7 @@ async function startOrchestration(opts) {
|
|
|
7336
7605
|
repoPath: repo
|
|
7337
7606
|
});
|
|
7338
7607
|
});
|
|
7339
|
-
const { updateThread: upd } = await import("./thread-store-
|
|
7608
|
+
const { updateThread: upd } = await import("./thread-store-57ZLHR3A.js");
|
|
7340
7609
|
const updated = upd(thread.id, {
|
|
7341
7610
|
sourceType: "orchestration",
|
|
7342
7611
|
sourceRef: goal
|