@sideboard-ai/core 0.1.217 → 0.1.219
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-QGGYL2G4.js → abletime-BF253OZT.js} +5 -4
- package/dist/{abletime-GDZLZRMY.js → abletime-D6773P33.js} +5 -5
- package/dist/{abletime-oauth-F335TWKY.js → abletime-oauth-H4672PRH.js} +4 -3
- package/dist/{abletime-oauth-3X3BAPTF.js → abletime-oauth-KQPVVBKA.js} +4 -4
- package/dist/{abletime-rest-PLJVY3H3.js → abletime-rest-DAFPXZ7H.js} +4 -4
- package/dist/{abletime-rest-LAGTPAJL.js → abletime-rest-OPEVV3XC.js} +4 -3
- package/dist/agents/cursor-runner.js +5 -5
- package/dist/{agents-HETHRRZJ.js → agents-IFVGY77W.js} +9 -9
- package/dist/{agents-WBDDLRBY.js → agents-IK3U4Z2O.js} +8 -7
- package/dist/{app-settings-XCRNCEEE.js → app-settings-5RQMQKSB.js} +2 -1
- package/dist/{app-settings-2TN3WLZV.js → app-settings-V2BBCX2H.js} +2 -2
- package/dist/{chunk-MN6YUD4O.js → chunk-3NWUHXU3.js} +3 -3
- package/dist/{chunk-G4TANQC3.js → chunk-646I442S.js} +5 -5
- package/dist/{chunk-FNQNJOHY.js → chunk-ABOBTSO6.js} +4 -1
- package/dist/{chunk-YVE4PXCJ.js → chunk-CLI5DVU4.js} +2 -2
- package/dist/{chunk-C32SBNA3.js → chunk-EIICOB7P.js} +457 -294
- package/dist/{chunk-LS6TSOCE.js → chunk-HSYE5ID6.js} +5 -5
- package/dist/{chunk-UFHNSFAS.js → chunk-HVUVQXZ2.js} +5 -1
- package/dist/{chunk-7MTVRNP4.js → chunk-IAP5NXQ4.js} +1206 -1192
- package/dist/{chunk-SALM35KD.js → chunk-IILG7DPX.js} +5 -5
- package/dist/{chunk-DFTVZEZY.js → chunk-K642ORWF.js} +1085 -1057
- package/dist/{chunk-NI243N27.js → chunk-KTZESHYH.js} +15 -7
- package/dist/{chunk-FNGXKY5W.js → chunk-N2VST3NL.js} +68 -8
- package/dist/{chunk-XYKVRRC2.js → chunk-NFWPDEN4.js} +15 -7
- package/dist/{chunk-KFD2OXCE.js → chunk-P2EAAM3H.js} +68 -8
- package/dist/{chunk-QQKDGPUI.js → chunk-PO4M4JAJ.js} +1 -1
- package/dist/{chunk-2M5B7YNY.js → chunk-RRW2XWAY.js} +2 -2
- package/dist/{chunk-REZRGCKV.js → chunk-SOGGKYFV.js} +3 -3
- package/dist/{chunk-3OHR73VK.js → chunk-SVXIJ2IC.js} +1 -1
- package/dist/{chunk-SYFVUF2C.js → chunk-SZJZEFTY.js} +1 -1
- package/dist/{chunk-42IULNIY.js → chunk-THLVCXLF.js} +3 -3
- package/dist/{chunk-JZHRZ3DR.js → chunk-TQBUXKIB.js} +5 -5
- package/dist/chunk-WWUABK6B.js +56 -0
- package/dist/{chunk-D2IKXMF3.js → chunk-XGE6YUO6.js} +453 -289
- package/dist/{chunk-BTC2D6LS.js → chunk-Y5JES2VV.js} +3 -51
- package/dist/{connected-teams-WK47ATT7.js → connected-teams-LX5DLL2I.js} +3 -2
- package/dist/{connected-teams-PU4AMFNA.js → connected-teams-PQETXUWV.js} +3 -2
- package/dist/{coordinator-prompt-FQX6ALAI.js → coordinator-prompt-JLMQVORO.js} +6 -6
- package/dist/{coordinator-prompt-LE2GQZ2X.js → coordinator-prompt-VZ7OSRLD.js} +6 -5
- package/dist/{global-workspace-6P236KKG.js → global-workspace-3FDAUNN2.js} +6 -6
- package/dist/{global-workspace-KT3FRHZL.js → global-workspace-QPSJEXGR.js} +6 -5
- package/dist/index.cjs +1107 -826
- package/dist/index.d.cts +15 -1
- package/dist/index.d.ts +15 -1
- package/dist/index.js +24 -18
- package/dist/mcp/run-stdio.cjs +1912 -1652
- package/dist/mcp/run-stdio.js +16 -14
- package/dist/{orchestrator-MI7A5DQZ.js → orchestrator-5VVR7LOU.js} +9 -8
- package/dist/{orchestrator-WVZPTHBV.js → orchestrator-LFC3V3AX.js} +10 -10
- package/dist/{run-EBWL2Q4N.js → run-QDZCTP4Y.js} +2 -1
- package/dist/{run-CAGKZLHA.js → run-UEQM4JMZ.js} +2 -1
- package/dist/{workspaces-R5LJCJRB.js → workspaces-76W7IEKR.js} +8 -6
- package/dist/{workspaces-KM7KTLVO.js → workspaces-TDBA64II.js} +8 -5
- package/dist/{worktree-MDMTCAHX.js → worktree-7V67XTEO.js} +5 -5
- package/dist/{worktree-VXRI7LYM.js → worktree-I573UOPD.js} +5 -4
- package/dist/{worktree-exclude-N5X5I422.js → worktree-exclude-K7QK4RI5.js} +3 -2
- package/dist/{worktree-exclude-X54WSOXM.js → worktree-exclude-L32WEBX6.js} +3 -2
- package/package.json +1 -1
- package/dist/{chunk-L5CIEBLR.js → chunk-EWHJNJHV.js} +3 -3
|
@@ -42,7 +42,7 @@ import {
|
|
|
42
42
|
summarizeTurnStderr,
|
|
43
43
|
toolDescription,
|
|
44
44
|
turnFailChatText
|
|
45
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-IAP5NXQ4.js";
|
|
46
46
|
import {
|
|
47
47
|
SLACK_REPLY_FORMATTING,
|
|
48
48
|
addWorkspace,
|
|
@@ -65,7 +65,7 @@ import {
|
|
|
65
65
|
stageAbsolutePathsAsAttachments,
|
|
66
66
|
stageBuffersAsAttachments,
|
|
67
67
|
syncWorkspacesFromThreads
|
|
68
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-P2EAAM3H.js";
|
|
69
69
|
import {
|
|
70
70
|
addPrStackLayer,
|
|
71
71
|
allocateTeamName,
|
|
@@ -99,7 +99,6 @@ import {
|
|
|
99
99
|
mergeAgentGitAuthEnv,
|
|
100
100
|
mergePr,
|
|
101
101
|
normalizeWorktreePath,
|
|
102
|
-
originGhRepoEnv,
|
|
103
102
|
pushBranch,
|
|
104
103
|
removeWorktree,
|
|
105
104
|
resolveAgentGitAuthEnv,
|
|
@@ -115,7 +114,7 @@ import {
|
|
|
115
114
|
worktreeDisplayLabelForGroup,
|
|
116
115
|
worktreeNameFromPath,
|
|
117
116
|
worktreeSlugForTicket
|
|
118
|
-
} from "./chunk-
|
|
117
|
+
} from "./chunk-NFWPDEN4.js";
|
|
119
118
|
import {
|
|
120
119
|
ATTACHMENTS_DIR,
|
|
121
120
|
DETACHED_JOBS_DIR,
|
|
@@ -136,7 +135,7 @@ import {
|
|
|
136
135
|
} from "./chunk-HY2GFZ5S.js";
|
|
137
136
|
import {
|
|
138
137
|
ensureWorktreeSideboardIgnored
|
|
139
|
-
} from "./chunk-
|
|
138
|
+
} from "./chunk-SZJZEFTY.js";
|
|
140
139
|
import {
|
|
141
140
|
clearStaleIndexLocks,
|
|
142
141
|
enrichPathWithNpmGlobalBin,
|
|
@@ -144,7 +143,7 @@ import {
|
|
|
144
143
|
git,
|
|
145
144
|
resolveGitDirsForLockRecovery,
|
|
146
145
|
run
|
|
147
|
-
} from "./chunk-
|
|
146
|
+
} from "./chunk-ABOBTSO6.js";
|
|
148
147
|
import {
|
|
149
148
|
HISTORY_CLEANUP_INTERVAL_HOURS_DEFAULT,
|
|
150
149
|
applyTurnUsage,
|
|
@@ -174,12 +173,11 @@ import {
|
|
|
174
173
|
resolveOrchestratorDefaults,
|
|
175
174
|
resolveVaultKey,
|
|
176
175
|
resolveViewerProfileForRepo,
|
|
177
|
-
stripNestedElectronEnv,
|
|
178
176
|
sumUsageList,
|
|
179
177
|
updateAdvancedSettings,
|
|
180
178
|
usageOnLimit,
|
|
181
179
|
writeSecureJson
|
|
182
|
-
} from "./chunk-
|
|
180
|
+
} from "./chunk-Y5JES2VV.js";
|
|
183
181
|
import {
|
|
184
182
|
writePrivateFile
|
|
185
183
|
} from "./chunk-NSTQ6QKD.js";
|
|
@@ -196,6 +194,9 @@ import {
|
|
|
196
194
|
workspaceSettingsSourceLabel,
|
|
197
195
|
worktreesRoot
|
|
198
196
|
} from "./chunk-EQNRWDLN.js";
|
|
197
|
+
import {
|
|
198
|
+
stripNestedElectronEnv
|
|
199
|
+
} from "./chunk-WWUABK6B.js";
|
|
199
200
|
import {
|
|
200
201
|
examplePrefixedBranch,
|
|
201
202
|
sanitizeGitBranchPrefix
|
|
@@ -417,7 +418,7 @@ async function continueSourceThread(threadId, prompt) {
|
|
|
417
418
|
await continueOnReply(threadId, prompt);
|
|
418
419
|
return;
|
|
419
420
|
}
|
|
420
|
-
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-
|
|
421
|
+
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-5VVR7LOU.js");
|
|
421
422
|
await getOrchestrator2().send(threadId, prompt);
|
|
422
423
|
} catch {
|
|
423
424
|
}
|
|
@@ -683,20 +684,104 @@ import { existsSync as existsSync19 } from "fs";
|
|
|
683
684
|
import { createInterface } from "readline";
|
|
684
685
|
import { execa } from "execa";
|
|
685
686
|
|
|
687
|
+
// src/agents/turn-trace.ts
|
|
688
|
+
import { appendFileSync } from "fs";
|
|
689
|
+
import { join as join4 } from "path";
|
|
690
|
+
function traceTurn(phase, extra) {
|
|
691
|
+
try {
|
|
692
|
+
const line = `${JSON.stringify({ t: (/* @__PURE__ */ new Date()).toISOString(), phase, ...extra })}
|
|
693
|
+
`;
|
|
694
|
+
appendFileSync(join4(appDataDir(), "turn-spawn.log"), line);
|
|
695
|
+
} catch {
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
async function withTimeout(promise, ms, label) {
|
|
699
|
+
let timer;
|
|
700
|
+
try {
|
|
701
|
+
return await Promise.race([
|
|
702
|
+
promise,
|
|
703
|
+
new Promise((_, reject) => {
|
|
704
|
+
timer = setTimeout(
|
|
705
|
+
() => reject(new Error(`${label} timed out after ${ms}ms`)),
|
|
706
|
+
ms
|
|
707
|
+
);
|
|
708
|
+
})
|
|
709
|
+
]);
|
|
710
|
+
} finally {
|
|
711
|
+
if (timer) clearTimeout(timer);
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
// src/hook/agent-host-env.ts
|
|
716
|
+
import { delimiter } from "path";
|
|
717
|
+
var DROP_EXACT = /* @__PURE__ */ new Set([
|
|
718
|
+
"NODE_PATH",
|
|
719
|
+
"NODE_ENV_ELECTRON_VITE",
|
|
720
|
+
"INIT_CWD",
|
|
721
|
+
"npm_command",
|
|
722
|
+
"npm_execpath",
|
|
723
|
+
"npm_node_execpath",
|
|
724
|
+
"npm_lifecycle_event",
|
|
725
|
+
"npm_lifecycle_script",
|
|
726
|
+
"PNPM_SCRIPT_SRC_DIR",
|
|
727
|
+
"PNPM_STORE_DIR",
|
|
728
|
+
"PORT",
|
|
729
|
+
"SIDEBOARD_ROOT_PATH",
|
|
730
|
+
"SIDEBOARD_IS_LOCAL",
|
|
731
|
+
"SIDEBOARD_WORKSPACE_PATH",
|
|
732
|
+
"SIDEBOARD_WORKSPACE_NAME",
|
|
733
|
+
"SIDEBOARD_PORT",
|
|
734
|
+
"CONDUCTOR_ROOT_PATH",
|
|
735
|
+
"CONDUCTOR_IS_LOCAL",
|
|
736
|
+
"CONDUCTOR_WORKSPACE_PATH",
|
|
737
|
+
"CONDUCTOR_WORKSPACE_NAME",
|
|
738
|
+
"CONDUCTOR_PORT",
|
|
739
|
+
"CONDUCTOR_DEFAULT_BRANCH",
|
|
740
|
+
"SIDEBOARD_DEFAULT_BRANCH"
|
|
741
|
+
]);
|
|
742
|
+
var DROP_PREFIXES = [
|
|
743
|
+
"npm_package_",
|
|
744
|
+
"npm_config_",
|
|
745
|
+
"PNPM_",
|
|
746
|
+
"SIDEBOARD_PORT_",
|
|
747
|
+
"CONDUCTOR_PORT_"
|
|
748
|
+
];
|
|
749
|
+
var HOST_PATH_NOISE = /(?:^|\/)node_modules\/\.bin(?:\/|$)|node-gyp-bin|electron-vite/i;
|
|
750
|
+
function isAgentHostEnvKey(key) {
|
|
751
|
+
if (DROP_EXACT.has(key)) return true;
|
|
752
|
+
return DROP_PREFIXES.some((prefix) => key.startsWith(prefix));
|
|
753
|
+
}
|
|
754
|
+
function stripHostToolingPath(pathValue) {
|
|
755
|
+
if (!pathValue?.trim()) return "";
|
|
756
|
+
return pathValue.split(delimiter).filter((part) => part && !HOST_PATH_NOISE.test(part.replace(/\\/g, "/"))).join(delimiter);
|
|
757
|
+
}
|
|
758
|
+
function sanitizeAgentHostEnv(env, cwd) {
|
|
759
|
+
for (const key of Object.keys(env)) {
|
|
760
|
+
if (isAgentHostEnvKey(key)) delete env[key];
|
|
761
|
+
}
|
|
762
|
+
env.PATH = stripHostToolingPath(env.PATH);
|
|
763
|
+
const worktree = cwd?.trim();
|
|
764
|
+
if (worktree) {
|
|
765
|
+
env.PWD = worktree;
|
|
766
|
+
env.INIT_CWD = worktree;
|
|
767
|
+
}
|
|
768
|
+
return env;
|
|
769
|
+
}
|
|
770
|
+
|
|
686
771
|
// src/hook/worktree-pkg-cache.ts
|
|
687
772
|
import { existsSync as existsSync3, mkdirSync } from "fs";
|
|
688
|
-
import { join as
|
|
773
|
+
import { join as join5 } from "path";
|
|
689
774
|
var WORKTREE_PKG_CACHE_REL = ".context/.sideboard/pkg-cache";
|
|
690
775
|
function worktreePkgCacheRoot(worktreePath) {
|
|
691
|
-
return
|
|
776
|
+
return join5(worktreePath, WORKTREE_PKG_CACHE_REL);
|
|
692
777
|
}
|
|
693
778
|
function worktreePkgCacheEnv(worktreePath) {
|
|
694
779
|
const root = worktreePkgCacheRoot(worktreePath);
|
|
695
|
-
const store =
|
|
696
|
-
const pnpmCache =
|
|
697
|
-
const npmCache =
|
|
698
|
-
const nodeGyp =
|
|
699
|
-
const electron =
|
|
780
|
+
const store = join5(root, "pnpm-store");
|
|
781
|
+
const pnpmCache = join5(root, "pnpm");
|
|
782
|
+
const npmCache = join5(root, "npm");
|
|
783
|
+
const nodeGyp = join5(root, "node-gyp");
|
|
784
|
+
const electron = join5(root, "electron");
|
|
700
785
|
return {
|
|
701
786
|
npm_config_store_dir: store,
|
|
702
787
|
PNPM_STORE_DIR: store,
|
|
@@ -810,9 +895,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
810
895
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
811
896
|
);
|
|
812
897
|
}
|
|
813
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
898
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-QPSJEXGR.js");
|
|
814
899
|
if (isGlobalThread2(thread)) {
|
|
815
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
900
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-VZ7OSRLD.js");
|
|
816
901
|
ensureGlobalCoordinatorCwd2(
|
|
817
902
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
818
903
|
);
|
|
@@ -821,26 +906,54 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
821
906
|
assertOrchestratorCapableAgent(thread.agent);
|
|
822
907
|
}
|
|
823
908
|
const adapter = getAdapter(thread.agent);
|
|
824
|
-
const
|
|
909
|
+
const orch = isOrchestratorThread(thread);
|
|
910
|
+
traceTurn("spawn.buildTurn.start", {
|
|
911
|
+
threadId: thread.id,
|
|
912
|
+
agent: thread.agent,
|
|
913
|
+
orch,
|
|
914
|
+
cwd: thread.worktreePath
|
|
915
|
+
});
|
|
916
|
+
const cmd = await withTimeout(
|
|
917
|
+
adapter.buildTurn(thread, input),
|
|
918
|
+
2e4,
|
|
919
|
+
"buildTurn"
|
|
920
|
+
);
|
|
921
|
+
traceTurn("spawn.buildTurn.done", { file: cmd.file, cwd: cmd.cwd });
|
|
825
922
|
if (cmd.cwd !== thread.worktreePath) {
|
|
826
923
|
throw new Error(
|
|
827
924
|
`Agent cwd must be the thread worktree (got ${cmd.cwd}, expected ${thread.worktreePath})`
|
|
828
925
|
);
|
|
829
926
|
}
|
|
830
927
|
const env = childEnvWithAppSettings(cmd.env);
|
|
928
|
+
sanitizeAgentHostEnv(env, cmd.cwd);
|
|
929
|
+
ensureAgentPath(env);
|
|
831
930
|
applyPromptCacheTtlEnv(thread.agent, env);
|
|
832
931
|
applyAgentRunnerHeapEnv(env);
|
|
833
|
-
if (!
|
|
932
|
+
if (!orch) {
|
|
834
933
|
applyWorktreePkgCacheEnv(env, thread.worktreePath);
|
|
835
934
|
}
|
|
836
935
|
try {
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
936
|
+
traceTurn("spawn.gitAuth.start");
|
|
937
|
+
mergeAgentGitAuthEnv(
|
|
938
|
+
env,
|
|
939
|
+
await withTimeout(
|
|
940
|
+
resolveAgentGitAuthEnv(env, { cwd: thread.worktreePath }),
|
|
941
|
+
8e3,
|
|
942
|
+
"gitAuth"
|
|
943
|
+
)
|
|
944
|
+
);
|
|
945
|
+
if (!orch) {
|
|
946
|
+
const slug = await withTimeout(
|
|
947
|
+
resolveGithubRepoSlug(thread.worktreePath),
|
|
948
|
+
8e3,
|
|
949
|
+
"resolveGithubRepoSlug"
|
|
950
|
+
);
|
|
951
|
+
if (slug) env.GH_REPO = slug;
|
|
841
952
|
}
|
|
953
|
+
traceTurn("spawn.gitAuth.done", { ghRepo: env.GH_REPO ?? null });
|
|
842
954
|
} catch (err) {
|
|
843
955
|
const detail = err instanceof Error ? err.message : String(err);
|
|
956
|
+
traceTurn("spawn.gitAuth.fail", { detail });
|
|
844
957
|
console.warn(`[sideboard] git auth env failed (${thread.worktreePath}): ${detail}`);
|
|
845
958
|
}
|
|
846
959
|
const child = execa(cmd.file, cmd.args, {
|
|
@@ -853,6 +966,7 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
853
966
|
// so Claude doesn't wait ~3s for an empty pipe.
|
|
854
967
|
stdin: cmd.stdin != null ? "pipe" : "ignore"
|
|
855
968
|
});
|
|
969
|
+
traceTurn("spawn.execa", { pid: child.pid ?? null, file: cmd.file });
|
|
856
970
|
if (cmd.stdin != null && child.stdin) {
|
|
857
971
|
child.stdin.write(cmd.stdin);
|
|
858
972
|
child.stdin.end();
|
|
@@ -1084,14 +1198,14 @@ import {
|
|
|
1084
1198
|
readFileSync as readFileSync4
|
|
1085
1199
|
} from "fs";
|
|
1086
1200
|
import { createServer } from "net";
|
|
1087
|
-
import { basename, dirname as dirname2, join as
|
|
1201
|
+
import { basename, dirname as dirname2, join as join7 } from "path";
|
|
1088
1202
|
import { execa as execa2 } from "execa";
|
|
1089
1203
|
import { createInterface as createInterface2 } from "readline";
|
|
1090
1204
|
|
|
1091
1205
|
// src/review/request-review.ts
|
|
1092
1206
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
1093
1207
|
import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync } from "fs";
|
|
1094
|
-
import { dirname, join as
|
|
1208
|
+
import { dirname, join as join6 } from "path";
|
|
1095
1209
|
|
|
1096
1210
|
// src/threads/chat-tabs.ts
|
|
1097
1211
|
import { randomUUID } from "crypto";
|
|
@@ -1839,12 +1953,12 @@ function readTextIfPresent(abs) {
|
|
|
1839
1953
|
}
|
|
1840
1954
|
}
|
|
1841
1955
|
function readLocalGuidelines(worktreePath) {
|
|
1842
|
-
const localAbs =
|
|
1956
|
+
const localAbs = join6(worktreePath, REVIEW_REQUEST_PATH);
|
|
1843
1957
|
const localContent = readTextIfPresent(localAbs);
|
|
1844
1958
|
if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
|
|
1845
1959
|
return { path: REVIEW_REQUEST_PATH, content: localContent };
|
|
1846
1960
|
}
|
|
1847
|
-
const legacyAbs =
|
|
1961
|
+
const legacyAbs = join6(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
|
|
1848
1962
|
const legacyContent = readTextIfPresent(legacyAbs);
|
|
1849
1963
|
if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
|
|
1850
1964
|
return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
|
|
@@ -1868,7 +1982,7 @@ function contextGuidelines(content, source) {
|
|
|
1868
1982
|
};
|
|
1869
1983
|
}
|
|
1870
1984
|
function writeContextGuidelines(worktreePath, content) {
|
|
1871
|
-
const abs =
|
|
1985
|
+
const abs = join6(worktreePath, CONTEXT_REVIEW_PATH);
|
|
1872
1986
|
mkdirSync2(dirname(abs), { recursive: true });
|
|
1873
1987
|
const body = content.endsWith("\n") ? content : `${content}
|
|
1874
1988
|
`;
|
|
@@ -1876,19 +1990,19 @@ function writeContextGuidelines(worktreePath, content) {
|
|
|
1876
1990
|
return body;
|
|
1877
1991
|
}
|
|
1878
1992
|
function readSideboardReview(worktreePath, repoPath) {
|
|
1879
|
-
const fromWorktree = readTextIfPresent(
|
|
1993
|
+
const fromWorktree = readTextIfPresent(join6(worktreePath, REPO_REVIEW_PATH));
|
|
1880
1994
|
if (fromWorktree) return fromWorktree;
|
|
1881
1995
|
const repo = repoPath?.replace(/\/+$/, "");
|
|
1882
1996
|
const wt = worktreePath.replace(/\/+$/, "");
|
|
1883
1997
|
if (!repo || repo === wt) return null;
|
|
1884
|
-
return readTextIfPresent(
|
|
1998
|
+
return readTextIfPresent(join6(repo, REPO_REVIEW_PATH));
|
|
1885
1999
|
}
|
|
1886
2000
|
function ensureReviewGuidelinesFile(worktreePath, repoPath) {
|
|
1887
|
-
const skillContent = readTextIfPresent(
|
|
2001
|
+
const skillContent = readTextIfPresent(join6(worktreePath, REVIEW_SKILL_PATH));
|
|
1888
2002
|
if (skillContent) {
|
|
1889
2003
|
return { ...skillGuidelines(skillContent, "skill"), wrote: false };
|
|
1890
2004
|
}
|
|
1891
|
-
const contextContent = readTextIfPresent(
|
|
2005
|
+
const contextContent = readTextIfPresent(join6(worktreePath, CONTEXT_REVIEW_PATH));
|
|
1892
2006
|
if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
|
|
1893
2007
|
return { ...contextGuidelines(contextContent, "local"), wrote: false };
|
|
1894
2008
|
}
|
|
@@ -1951,7 +2065,7 @@ function matchSimpleGlob(pattern, name) {
|
|
|
1951
2065
|
return new RegExp(`^${escaped}$`).test(name);
|
|
1952
2066
|
}
|
|
1953
2067
|
function readWorktreeInclude(repoPath) {
|
|
1954
|
-
const path =
|
|
2068
|
+
const path = join7(repoPath, ".worktreeinclude");
|
|
1955
2069
|
if (!existsSync5(path)) return [];
|
|
1956
2070
|
return readFileSync4(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
1957
2071
|
}
|
|
@@ -1992,9 +2106,9 @@ function copyConfiguredFiles(repoPath, worktreePath) {
|
|
|
1992
2106
|
const patterns = resolveFilesToCopy(repoPath);
|
|
1993
2107
|
const copied = [];
|
|
1994
2108
|
for (const rel of patterns) {
|
|
1995
|
-
const src =
|
|
2109
|
+
const src = join7(repoPath, rel);
|
|
1996
2110
|
if (!existsSync5(src)) continue;
|
|
1997
|
-
const dest =
|
|
2111
|
+
const dest = join7(worktreePath, rel);
|
|
1998
2112
|
mkdirSync3(dirname2(dest), { recursive: true });
|
|
1999
2113
|
copyFileSync(src, dest);
|
|
2000
2114
|
copied.push(rel);
|
|
@@ -2299,7 +2413,7 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
|
|
|
2299
2413
|
// src/store/setup-log.ts
|
|
2300
2414
|
import { createHash } from "crypto";
|
|
2301
2415
|
import { existsSync as existsSync6, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
|
|
2302
|
-
import { join as
|
|
2416
|
+
import { join as join8 } from "path";
|
|
2303
2417
|
var EMPTY = {
|
|
2304
2418
|
output: "",
|
|
2305
2419
|
running: false,
|
|
@@ -2341,7 +2455,7 @@ function materialize(mem) {
|
|
|
2341
2455
|
};
|
|
2342
2456
|
}
|
|
2343
2457
|
function setupLogPath(threadId) {
|
|
2344
|
-
return
|
|
2458
|
+
return join8(threadsDir(), `${threadId}.setup.log.json`);
|
|
2345
2459
|
}
|
|
2346
2460
|
function setupLogKeyForWorktree(worktreePath) {
|
|
2347
2461
|
const norm = normalizeWorktreePath(worktreePath);
|
|
@@ -2442,7 +2556,7 @@ function finishSetupLog(threadId, exitCode, source) {
|
|
|
2442
2556
|
|
|
2443
2557
|
// src/git/orphan-cleanup.ts
|
|
2444
2558
|
import { existsSync as existsSync7, readdirSync as readdirSync2, statSync } from "fs";
|
|
2445
|
-
import { join as
|
|
2559
|
+
import { join as join9 } from "path";
|
|
2446
2560
|
function isSideboardWorktreePath(path) {
|
|
2447
2561
|
return path.includes("/.sideboard/worktrees/") || path.includes("/sideboard/workspaces/");
|
|
2448
2562
|
}
|
|
@@ -2489,9 +2603,9 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
2489
2603
|
if (existsSync7(root)) {
|
|
2490
2604
|
for (const entry of readdirSync2(root, { withFileTypes: true })) {
|
|
2491
2605
|
if (!entry.isDirectory()) continue;
|
|
2492
|
-
const path =
|
|
2606
|
+
const path = join9(root, entry.name).replace(/\/$/, "");
|
|
2493
2607
|
if (known.has(path) || seen.has(path)) continue;
|
|
2494
|
-
if (!existsSync7(
|
|
2608
|
+
if (!existsSync7(join9(path, ".git"))) continue;
|
|
2495
2609
|
seen.add(path);
|
|
2496
2610
|
let mtimeMs = 0;
|
|
2497
2611
|
try {
|
|
@@ -2696,7 +2810,7 @@ async function applyThreadIntoMain(thread, opts) {
|
|
|
2696
2810
|
|
|
2697
2811
|
// src/git/clone-repo.ts
|
|
2698
2812
|
import { existsSync as existsSync8 } from "fs";
|
|
2699
|
-
import { basename as basename2, join as
|
|
2813
|
+
import { basename as basename2, join as join10 } from "path";
|
|
2700
2814
|
import { execa as execa4 } from "execa";
|
|
2701
2815
|
async function cloneRepoIntoSideboard(opts) {
|
|
2702
2816
|
const url = opts.url.trim();
|
|
@@ -2707,7 +2821,7 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
2707
2821
|
name = leaf || "repo";
|
|
2708
2822
|
}
|
|
2709
2823
|
name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
|
|
2710
|
-
const dest =
|
|
2824
|
+
const dest = join10(sideboardReposDir(), name);
|
|
2711
2825
|
if (existsSync8(dest)) {
|
|
2712
2826
|
const repoPath2 = await resolveRepoRoot(dest);
|
|
2713
2827
|
const workspace2 = await ensureWorkspace(repoPath2);
|
|
@@ -2726,9 +2840,9 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
2726
2840
|
|
|
2727
2841
|
// src/store/desktop-host.ts
|
|
2728
2842
|
import { readFileSync as readFileSync6, unlinkSync, writeFileSync as writeFileSync3 } from "fs";
|
|
2729
|
-
import { join as
|
|
2843
|
+
import { join as join11 } from "path";
|
|
2730
2844
|
function desktopHostPidPath() {
|
|
2731
|
-
return
|
|
2845
|
+
return join11(appDataDir(), "desktop-host.pid");
|
|
2732
2846
|
}
|
|
2733
2847
|
function readDesktopHostPid() {
|
|
2734
2848
|
try {
|
|
@@ -2803,14 +2917,14 @@ function notifyParentOfChildHalt(child, status, send) {
|
|
|
2803
2917
|
|
|
2804
2918
|
// src/mcp/wait-for-job.ts
|
|
2805
2919
|
import {
|
|
2806
|
-
appendFileSync,
|
|
2920
|
+
appendFileSync as appendFileSync2,
|
|
2807
2921
|
existsSync as existsSync9,
|
|
2808
2922
|
mkdirSync as mkdirSync4,
|
|
2809
2923
|
readdirSync as readdirSync3,
|
|
2810
2924
|
readFileSync as readFileSync7,
|
|
2811
2925
|
writeFileSync as writeFileSync4
|
|
2812
2926
|
} from "fs";
|
|
2813
|
-
import { dirname as dirname3, join as
|
|
2927
|
+
import { dirname as dirname3, join as join12 } from "path";
|
|
2814
2928
|
|
|
2815
2929
|
// src/mcp/wait-for-turn.ts
|
|
2816
2930
|
var MCP_WAIT_FOR_TURN_MAX_MS = 45e3;
|
|
@@ -2882,7 +2996,7 @@ function readIntFile(file) {
|
|
|
2882
2996
|
return Number.isInteger(n) ? n : null;
|
|
2883
2997
|
}
|
|
2884
2998
|
function jobDir(root, id, legacy = false) {
|
|
2885
|
-
return
|
|
2999
|
+
return join12(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
|
|
2886
3000
|
}
|
|
2887
3001
|
function resolveJobDir(root, id) {
|
|
2888
3002
|
const modern = jobDir(root, id, false);
|
|
@@ -2892,7 +3006,7 @@ function resolveJobDir(root, id) {
|
|
|
2892
3006
|
return modern;
|
|
2893
3007
|
}
|
|
2894
3008
|
function listJobIdsIn(root, rel) {
|
|
2895
|
-
const dir =
|
|
3009
|
+
const dir = join12(root, rel);
|
|
2896
3010
|
if (!existsSync9(dir)) return [];
|
|
2897
3011
|
return readdirSync3(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
|
|
2898
3012
|
}
|
|
@@ -2906,7 +3020,7 @@ function listRunningDetachedJobs(worktreePath) {
|
|
|
2906
3020
|
const running = [];
|
|
2907
3021
|
for (const id of ids) {
|
|
2908
3022
|
const dir = resolveJobDir(root, id);
|
|
2909
|
-
const pid = readIntFile(
|
|
3023
|
+
const pid = readIntFile(join12(dir, "pid"));
|
|
2910
3024
|
if (jobTreeAlive(pid)) running.push(id);
|
|
2911
3025
|
}
|
|
2912
3026
|
return running.sort();
|
|
@@ -2919,6 +3033,7 @@ function looksLikeDeferredDonePromise(text) {
|
|
|
2919
3033
|
return /\b(i['’]?ll|i will)\s+let you know\b/i.test(unquoted) || /\blet you know when\b/i.test(unquoted) || /\b(check back|ping me)\s+when\b/i.test(unquoted) || /\bi(?:['’]ll| will)\s+(report|update you)\s+when\b/i.test(unquoted);
|
|
2920
3034
|
}
|
|
2921
3035
|
function isJobContinuePrompt(text) {
|
|
3036
|
+
if (typeof text !== "string") return false;
|
|
2922
3037
|
const t = text.trim();
|
|
2923
3038
|
return t.startsWith("Detached job still running:") || t.startsWith("You ended the turn after promising to report later");
|
|
2924
3039
|
}
|
|
@@ -3009,15 +3124,15 @@ function takeDelta(logFile, cursorFile) {
|
|
|
3009
3124
|
return { delta: capJobLogDelta(lines.slice(start).join("\n")), nextCursor: lines.length };
|
|
3010
3125
|
}
|
|
3011
3126
|
function snapshotJob(dir) {
|
|
3012
|
-
const pid = readIntFile(
|
|
3127
|
+
const pid = readIntFile(join12(dir, "pid"));
|
|
3013
3128
|
const running = jobTreeAlive(pid);
|
|
3014
3129
|
return {
|
|
3015
3130
|
pid,
|
|
3016
3131
|
running,
|
|
3017
|
-
exitCode: readIntFile(
|
|
3018
|
-
log:
|
|
3019
|
-
cursor:
|
|
3020
|
-
progress: tailProgress(
|
|
3132
|
+
exitCode: readIntFile(join12(dir, "exit")),
|
|
3133
|
+
log: join12(dir, "log"),
|
|
3134
|
+
cursor: join12(dir, "present.cursor"),
|
|
3135
|
+
progress: tailProgress(join12(dir, "log"))
|
|
3021
3136
|
};
|
|
3022
3137
|
}
|
|
3023
3138
|
function toResult(id, snap, extra) {
|
|
@@ -3105,7 +3220,7 @@ function appendJobLog(logFile, line) {
|
|
|
3105
3220
|
mkdirSync4(dirname3(logFile), { recursive: true });
|
|
3106
3221
|
const body = line.endsWith("\n") ? line : `${line}
|
|
3107
3222
|
`;
|
|
3108
|
-
|
|
3223
|
+
appendFileSync2(logFile, body);
|
|
3109
3224
|
} catch {
|
|
3110
3225
|
}
|
|
3111
3226
|
}
|
|
@@ -3151,7 +3266,7 @@ async function stopDetachedJob(cwd, id, opts) {
|
|
|
3151
3266
|
killProcessTree(targetPid, "SIGKILL");
|
|
3152
3267
|
await sleep(100);
|
|
3153
3268
|
}
|
|
3154
|
-
const exitFile =
|
|
3269
|
+
const exitFile = join12(dir, "exit");
|
|
3155
3270
|
if (!existsSync9(exitFile)) {
|
|
3156
3271
|
try {
|
|
3157
3272
|
writeFileSync4(exitFile, "1\n");
|
|
@@ -3746,7 +3861,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
3746
3861
|
});
|
|
3747
3862
|
await requireAgent(resolved.agent);
|
|
3748
3863
|
if (input.cowboy) {
|
|
3749
|
-
const { cowboyModeEnabled } = await import("./app-settings-
|
|
3864
|
+
const { cowboyModeEnabled } = await import("./app-settings-5RQMQKSB.js");
|
|
3750
3865
|
if (!cowboyModeEnabled()) {
|
|
3751
3866
|
throw new Error(
|
|
3752
3867
|
"Cowboy mode is off. Enable it in Settings \u2192 Advanced."
|
|
@@ -3804,7 +3919,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
3804
3919
|
let sourceIsFork = false;
|
|
3805
3920
|
if (!input.cowboy && sourceType === "branch" && (!sourceRef || sourceRef === "HEAD" || sourceRef === "default")) {
|
|
3806
3921
|
if (isAbleTimeConnected() && getIssueSource() === "abletime") {
|
|
3807
|
-
const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-
|
|
3922
|
+
const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-BF253OZT.js");
|
|
3808
3923
|
const task = await ensureAbleTimeTask({
|
|
3809
3924
|
title: title?.trim() || "Untitled work",
|
|
3810
3925
|
description: input.prompt?.trim() || void 0
|
|
@@ -4280,19 +4395,19 @@ import {
|
|
|
4280
4395
|
rmSync
|
|
4281
4396
|
} from "fs";
|
|
4282
4397
|
import { tmpdir } from "os";
|
|
4283
|
-
import { join as
|
|
4398
|
+
import { join as join13 } from "path";
|
|
4284
4399
|
import { createRequire } from "module";
|
|
4285
|
-
var CONDUCTOR_APP_SUPPORT =
|
|
4400
|
+
var CONDUCTOR_APP_SUPPORT = join13(
|
|
4286
4401
|
process.env.HOME ?? "",
|
|
4287
4402
|
"Library",
|
|
4288
4403
|
"Application Support",
|
|
4289
4404
|
"com.conductor.app"
|
|
4290
4405
|
);
|
|
4291
|
-
var CONDUCTOR_DB =
|
|
4292
|
-
var CURSOR_SDK_STORE =
|
|
4406
|
+
var CONDUCTOR_DB = join13(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
4407
|
+
var CURSOR_SDK_STORE = join13(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
4293
4408
|
function thisModuleFile() {
|
|
4294
4409
|
const cjsFile = typeof __filename !== "undefined" ? __filename : "";
|
|
4295
|
-
return cjsFile || process.argv[1] ||
|
|
4410
|
+
return cjsFile || process.argv[1] || join13(process.cwd(), "package.json");
|
|
4296
4411
|
}
|
|
4297
4412
|
function openReadonlySqlite(file) {
|
|
4298
4413
|
const req = createRequire(thisModuleFile());
|
|
@@ -4320,7 +4435,7 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
4320
4435
|
return null;
|
|
4321
4436
|
}
|
|
4322
4437
|
for (const hash of hashes) {
|
|
4323
|
-
const agentsFile =
|
|
4438
|
+
const agentsFile = join13(CURSOR_SDK_STORE, hash, "agents.ndjson");
|
|
4324
4439
|
if (!existsSync12(agentsFile)) continue;
|
|
4325
4440
|
let text;
|
|
4326
4441
|
try {
|
|
@@ -4352,7 +4467,7 @@ async function adoptThread(input) {
|
|
|
4352
4467
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
4353
4468
|
}
|
|
4354
4469
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
4355
|
-
const { stdout: branch } = await import("./run-
|
|
4470
|
+
const { stdout: branch } = await import("./run-QDZCTP4Y.js").then(
|
|
4356
4471
|
({ git: git2 }) => git2(["rev-parse", "--abbrev-ref", "HEAD"], input.worktreePath)
|
|
4357
4472
|
);
|
|
4358
4473
|
const thread = createEmptyThread({
|
|
@@ -4367,9 +4482,9 @@ async function adoptThread(input) {
|
|
|
4367
4482
|
messages: input.messages ?? []
|
|
4368
4483
|
});
|
|
4369
4484
|
writeThread(thread);
|
|
4370
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
4485
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-TDBA64II.js");
|
|
4371
4486
|
await ensureWorkspace2(repoPath);
|
|
4372
|
-
const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-
|
|
4487
|
+
const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-K7QK4RI5.js");
|
|
4373
4488
|
await ensureWorktreeSideboardIgnored2(input.worktreePath);
|
|
4374
4489
|
return thread;
|
|
4375
4490
|
}
|
|
@@ -4377,8 +4492,8 @@ function listConductorWorkspaces() {
|
|
|
4377
4492
|
if (!existsSync12(CONDUCTOR_DB)) {
|
|
4378
4493
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
4379
4494
|
}
|
|
4380
|
-
const tmp = mkdtempSync(
|
|
4381
|
-
const snapshot =
|
|
4495
|
+
const tmp = mkdtempSync(join13(tmpdir(), "sideboard-conductor-"));
|
|
4496
|
+
const snapshot = join13(tmp, "conductor.db");
|
|
4382
4497
|
try {
|
|
4383
4498
|
copyFileSync2(CONDUCTOR_DB, snapshot);
|
|
4384
4499
|
for (const suffix of ["-wal", "-shm"]) {
|
|
@@ -4468,8 +4583,8 @@ function importConductorWorkspace(workspaceId) {
|
|
|
4468
4583
|
if (!existsSync12(CONDUCTOR_DB)) {
|
|
4469
4584
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
4470
4585
|
}
|
|
4471
|
-
const tmp = mkdtempSync(
|
|
4472
|
-
const snapshot =
|
|
4586
|
+
const tmp = mkdtempSync(join13(tmpdir(), "sideboard-conductor-"));
|
|
4587
|
+
const snapshot = join13(tmp, "conductor.db");
|
|
4473
4588
|
try {
|
|
4474
4589
|
copyFileSync2(CONDUCTOR_DB, snapshot);
|
|
4475
4590
|
for (const suffix of ["-wal", "-shm"]) {
|
|
@@ -4850,7 +4965,7 @@ async function createPrStack(input, onSetupLine) {
|
|
|
4850
4965
|
|
|
4851
4966
|
// src/diff/diff.ts
|
|
4852
4967
|
import { existsSync as existsSync14, mkdirSync as mkdirSync5, readFileSync as readFileSync10, statSync as statSync2, writeFileSync as writeFileSync6 } from "fs";
|
|
4853
|
-
import { dirname as dirname4, join as
|
|
4968
|
+
import { dirname as dirname4, join as join14 } from "path";
|
|
4854
4969
|
async function inspectGitWorktree(worktreePath) {
|
|
4855
4970
|
if (!worktreePath || !existsSync14(worktreePath)) return "missing_worktree";
|
|
4856
4971
|
const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
|
|
@@ -4996,7 +5111,7 @@ new file mode 100644
|
|
|
4996
5111
|
};
|
|
4997
5112
|
}
|
|
4998
5113
|
async function untrackedPatch(worktreePath, path, maxHunk) {
|
|
4999
|
-
const abs =
|
|
5114
|
+
const abs = join14(worktreePath, path);
|
|
5000
5115
|
try {
|
|
5001
5116
|
const st = statSync2(abs);
|
|
5002
5117
|
if (st.isFile() && st.size > maxHunk) {
|
|
@@ -5466,6 +5581,15 @@ async function getDiff(worktreePath, repoPath, opts) {
|
|
|
5466
5581
|
mergeBase: needsMergeBase ? mergeBase : null
|
|
5467
5582
|
};
|
|
5468
5583
|
}
|
|
5584
|
+
function statWorktreePath(worktreePath, relativePath) {
|
|
5585
|
+
assertSafeRelativePath(relativePath);
|
|
5586
|
+
const abs = join14(worktreePath, relativePath);
|
|
5587
|
+
if (!existsSync14(abs)) return "missing";
|
|
5588
|
+
const st = statSync2(abs);
|
|
5589
|
+
if (st.isDirectory()) return "dir";
|
|
5590
|
+
if (st.isFile()) return "file";
|
|
5591
|
+
return "missing";
|
|
5592
|
+
}
|
|
5469
5593
|
async function listWorktreeFiles(worktreePath, opts) {
|
|
5470
5594
|
const maxFiles = opts?.maxFiles ?? 5e3;
|
|
5471
5595
|
const tracked = await git(["ls-files", "-z"], worktreePath, { reject: false });
|
|
@@ -5501,7 +5625,7 @@ var DEFAULT_UPLOAD_MAX_BYTES = 5e7;
|
|
|
5501
5625
|
function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
5502
5626
|
assertSafeRelativePath(relativePath);
|
|
5503
5627
|
const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
|
|
5504
|
-
const abs =
|
|
5628
|
+
const abs = join14(worktreePath, relativePath);
|
|
5505
5629
|
const st = statSync2(abs);
|
|
5506
5630
|
if (!st.isFile()) {
|
|
5507
5631
|
throw new Error(`Not a file: ${relativePath}`);
|
|
@@ -5521,7 +5645,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
5521
5645
|
function readWorktreeFile(worktreePath, relativePath, opts) {
|
|
5522
5646
|
assertSafeRelativePath(relativePath);
|
|
5523
5647
|
const maxBytes = opts?.maxBytes ?? 2e5;
|
|
5524
|
-
const abs =
|
|
5648
|
+
const abs = join14(worktreePath, relativePath);
|
|
5525
5649
|
const st = statSync2(abs);
|
|
5526
5650
|
if (!st.isFile()) {
|
|
5527
5651
|
throw new Error(`Not a file: ${relativePath}`);
|
|
@@ -5569,7 +5693,7 @@ function assertSafeRelativePath(relativePath) {
|
|
|
5569
5693
|
}
|
|
5570
5694
|
function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
5571
5695
|
assertSafeRelativePath(relativePath);
|
|
5572
|
-
const abs =
|
|
5696
|
+
const abs = join14(worktreePath, relativePath);
|
|
5573
5697
|
mkdirSync5(dirname4(abs), { recursive: true });
|
|
5574
5698
|
writeFileSync6(abs, content, "utf8");
|
|
5575
5699
|
return { path: relativePath };
|
|
@@ -5763,7 +5887,7 @@ async function confirmLand(thread, opts) {
|
|
|
5763
5887
|
if (preview.dirty) {
|
|
5764
5888
|
committed = await commitAll(thread.worktreePath, meta.commitMessage);
|
|
5765
5889
|
}
|
|
5766
|
-
const { git: git2 } = await import("./run-
|
|
5890
|
+
const { git: git2 } = await import("./run-QDZCTP4Y.js");
|
|
5767
5891
|
const { stdout: headOut } = await git2(
|
|
5768
5892
|
["rev-parse", "--abbrev-ref", "HEAD"],
|
|
5769
5893
|
thread.worktreePath,
|
|
@@ -5795,7 +5919,7 @@ async function confirmLand(thread, opts) {
|
|
|
5795
5919
|
// src/skills/discover.ts
|
|
5796
5920
|
import { existsSync as existsSync15, readdirSync as readdirSync5, readFileSync as readFileSync11, statSync as statSync3 } from "fs";
|
|
5797
5921
|
import { homedir } from "os";
|
|
5798
|
-
import { join as
|
|
5922
|
+
import { join as join15 } from "path";
|
|
5799
5923
|
|
|
5800
5924
|
// src/skills/bundled/long-running.ts
|
|
5801
5925
|
var LONG_RUNNING_SKILL_COMMAND = "long-running";
|
|
@@ -5960,7 +6084,7 @@ function scanSkillsDir(dir, source, out) {
|
|
|
5960
6084
|
}
|
|
5961
6085
|
for (const entry of entries) {
|
|
5962
6086
|
if (entry.startsWith(".")) continue;
|
|
5963
|
-
const skillMd =
|
|
6087
|
+
const skillMd = join15(dir, entry, "SKILL.md");
|
|
5964
6088
|
if (!existsSync15(skillMd)) continue;
|
|
5965
6089
|
try {
|
|
5966
6090
|
if (!statSync3(skillMd).isFile()) continue;
|
|
@@ -5982,12 +6106,12 @@ function scanClaudePluginSkills(pluginsRoot, out) {
|
|
|
5982
6106
|
return;
|
|
5983
6107
|
}
|
|
5984
6108
|
if (lookingForSkillsDir && entries.includes("SKILL.md")) {
|
|
5985
|
-
const skill = readSkill(
|
|
6109
|
+
const skill = readSkill(join15(dir, "SKILL.md"), "cli");
|
|
5986
6110
|
if (skill) out.push(skill);
|
|
5987
6111
|
}
|
|
5988
6112
|
for (const entry of entries) {
|
|
5989
6113
|
if (entry === "node_modules" || entry === ".git") continue;
|
|
5990
|
-
const full =
|
|
6114
|
+
const full = join15(dir, entry);
|
|
5991
6115
|
try {
|
|
5992
6116
|
if (!statSync3(full).isDirectory()) continue;
|
|
5993
6117
|
} catch {
|
|
@@ -6007,17 +6131,17 @@ function discoverSkills(worktreePath) {
|
|
|
6007
6131
|
const home = homedir();
|
|
6008
6132
|
const collected = [];
|
|
6009
6133
|
for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
|
|
6010
|
-
scanSkillsDir(
|
|
6134
|
+
scanSkillsDir(join15(worktreePath, rel), "workspace", collected);
|
|
6011
6135
|
}
|
|
6012
6136
|
for (const abs of [
|
|
6013
|
-
|
|
6014
|
-
|
|
6015
|
-
|
|
6016
|
-
|
|
6137
|
+
join15(home, ".claude/skills"),
|
|
6138
|
+
join15(home, ".cursor/skills"),
|
|
6139
|
+
join15(home, ".sideboard/skills"),
|
|
6140
|
+
join15(home, ".brightsy/skills")
|
|
6017
6141
|
]) {
|
|
6018
6142
|
scanSkillsDir(abs, "user", collected);
|
|
6019
6143
|
}
|
|
6020
|
-
scanClaudePluginSkills(
|
|
6144
|
+
scanClaudePluginSkills(join15(home, ".claude/plugins"), collected);
|
|
6021
6145
|
collected.push(...bundledSkills());
|
|
6022
6146
|
const rank = {
|
|
6023
6147
|
workspace: 0,
|
|
@@ -6189,16 +6313,28 @@ function shiftQueuedItem(queue, queueAttachments) {
|
|
|
6189
6313
|
|
|
6190
6314
|
// src/agents/instructions.ts
|
|
6191
6315
|
import { existsSync as existsSync17 } from "fs";
|
|
6192
|
-
import { join as
|
|
6316
|
+
import { join as join17 } from "path";
|
|
6193
6317
|
|
|
6194
6318
|
// src/skills/detached-job-path.ts
|
|
6195
6319
|
import { existsSync as existsSync16 } from "fs";
|
|
6196
|
-
import { dirname as dirname5, join as
|
|
6320
|
+
import { dirname as dirname5, join as join16 } from "path";
|
|
6197
6321
|
import { fileURLToPath } from "url";
|
|
6198
6322
|
var DETACHED_JOB_FILENAMES = ["detached-job.cjs", "detached-job.js"];
|
|
6323
|
+
function compiledModuleDir() {
|
|
6324
|
+
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
6325
|
+
if (cjsDir) return cjsDir;
|
|
6326
|
+
try {
|
|
6327
|
+
const url = import.meta.url;
|
|
6328
|
+
if (typeof url === "string" && url.length > 0) {
|
|
6329
|
+
return dirname5(fileURLToPath(url));
|
|
6330
|
+
}
|
|
6331
|
+
} catch {
|
|
6332
|
+
}
|
|
6333
|
+
return null;
|
|
6334
|
+
}
|
|
6199
6335
|
function detachedJobScriptIn(dir) {
|
|
6200
6336
|
for (const name of DETACHED_JOB_FILENAMES) {
|
|
6201
|
-
const script =
|
|
6337
|
+
const script = join16(dir, "scripts", name);
|
|
6202
6338
|
if (existsSync16(script)) return script;
|
|
6203
6339
|
}
|
|
6204
6340
|
return null;
|
|
@@ -6211,7 +6347,8 @@ function packagedDetachedJobPath() {
|
|
|
6211
6347
|
function resolveDetachedJobScript() {
|
|
6212
6348
|
const packaged = packagedDetachedJobPath();
|
|
6213
6349
|
if (packaged) return packaged;
|
|
6214
|
-
let dir =
|
|
6350
|
+
let dir = compiledModuleDir();
|
|
6351
|
+
if (!dir) return null;
|
|
6215
6352
|
for (let i = 0; i < 8; i++) {
|
|
6216
6353
|
const candidate = detachedJobScriptIn(dir);
|
|
6217
6354
|
if (candidate) return candidate;
|
|
@@ -6382,9 +6519,9 @@ function formatPrGateDirective() {
|
|
|
6382
6519
|
}
|
|
6383
6520
|
function formatProcessGuideDirective(opts) {
|
|
6384
6521
|
const worktree = opts?.worktreePath?.trim();
|
|
6385
|
-
const hasGraphSkill = !!worktree && existsSync17(
|
|
6386
|
-
const hasReviewSkill = !!worktree && existsSync17(
|
|
6387
|
-
const hasInstallSkill = !!worktree && existsSync17(
|
|
6522
|
+
const hasGraphSkill = !!worktree && existsSync17(join17(worktree, ".claude/skills/graph-engineering/SKILL.md"));
|
|
6523
|
+
const hasReviewSkill = !!worktree && existsSync17(join17(worktree, ".claude/skills/review/SKILL.md"));
|
|
6524
|
+
const hasInstallSkill = !!worktree && existsSync17(join17(worktree, ".claude/skills/worktree-install/SKILL.md"));
|
|
6388
6525
|
return [
|
|
6389
6526
|
"Process guides (recurring work only):",
|
|
6390
6527
|
hasGraphSkill ? "- Migrations, ports, batch fixes, and other fan-out: follow `.claude/skills/graph-engineering/SKILL.md` (`/graph-engineering`). Judge first; state on disk; grow the rulebook; do not patch around it." : null,
|
|
@@ -6585,7 +6722,7 @@ async function syncThreadBranchFromGit(threadId) {
|
|
|
6585
6722
|
// src/store/schedules.ts
|
|
6586
6723
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
6587
6724
|
import { existsSync as existsSync18, readFileSync as readFileSync12 } from "fs";
|
|
6588
|
-
import { join as
|
|
6725
|
+
import { join as join18 } from "path";
|
|
6589
6726
|
import { Cron } from "croner";
|
|
6590
6727
|
var DURATION_RE = /^(\d+)(s|m|h|d)$/i;
|
|
6591
6728
|
var UNIT_MS = {
|
|
@@ -6595,7 +6732,7 @@ var UNIT_MS = {
|
|
|
6595
6732
|
d: 864e5
|
|
6596
6733
|
};
|
|
6597
6734
|
function schedulesPath() {
|
|
6598
|
-
return
|
|
6735
|
+
return join18(appDataDir(), "schedules.json");
|
|
6599
6736
|
}
|
|
6600
6737
|
function parseDurationMs(every) {
|
|
6601
6738
|
const m = every.trim().match(DURATION_RE);
|
|
@@ -6820,7 +6957,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
6820
6957
|
${prompt}`;
|
|
6821
6958
|
}
|
|
6822
6959
|
async function defaultDeps() {
|
|
6823
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
6960
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-5VVR7LOU.js");
|
|
6824
6961
|
const orch = getOrchestrator2();
|
|
6825
6962
|
return {
|
|
6826
6963
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -7122,7 +7259,7 @@ var Orchestrator = class {
|
|
|
7122
7259
|
orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
|
|
7123
7260
|
});
|
|
7124
7261
|
}
|
|
7125
|
-
const { autoCleanupOrphansEnabled } = await import("./app-settings-
|
|
7262
|
+
const { autoCleanupOrphansEnabled } = await import("./app-settings-5RQMQKSB.js");
|
|
7126
7263
|
if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
|
|
7127
7264
|
await cleanupOrphanWorktrees({ repoPaths });
|
|
7128
7265
|
}
|
|
@@ -7154,7 +7291,7 @@ var Orchestrator = class {
|
|
|
7154
7291
|
}
|
|
7155
7292
|
if (thread.queue.length > 0) {
|
|
7156
7293
|
this.haltDrain.delete(thread.id);
|
|
7157
|
-
|
|
7294
|
+
this.armDrain(thread.id);
|
|
7158
7295
|
}
|
|
7159
7296
|
}
|
|
7160
7297
|
}
|
|
@@ -7409,7 +7546,7 @@ var Orchestrator = class {
|
|
|
7409
7546
|
}
|
|
7410
7547
|
await setup;
|
|
7411
7548
|
if (skipSetup) return;
|
|
7412
|
-
const { autoRunAfterSetupEnabled } = await import("./app-settings-
|
|
7549
|
+
const { autoRunAfterSetupEnabled } = await import("./app-settings-5RQMQKSB.js");
|
|
7413
7550
|
if (autoRunAfterSetupEnabled()) {
|
|
7414
7551
|
try {
|
|
7415
7552
|
await this.startDev(threadId);
|
|
@@ -7490,7 +7627,7 @@ var Orchestrator = class {
|
|
|
7490
7627
|
this.emit({ type: "status_changed", threadId: thread.id, status: "queued" });
|
|
7491
7628
|
}
|
|
7492
7629
|
if (thisProcessShouldDrainAgentQueues() && !shouldSteer) {
|
|
7493
|
-
|
|
7630
|
+
this.armDrain(thread.id);
|
|
7494
7631
|
}
|
|
7495
7632
|
return this.requireThread(thread.id);
|
|
7496
7633
|
});
|
|
@@ -7570,9 +7707,15 @@ var Orchestrator = class {
|
|
|
7570
7707
|
if (inFlight || foreignLive) {
|
|
7571
7708
|
this.stop(thread.id, { clearQueue: false, continueQueue: true });
|
|
7572
7709
|
}
|
|
7573
|
-
|
|
7710
|
+
this.armDrain(thread.id);
|
|
7574
7711
|
return this.requireThread(thread.id);
|
|
7575
7712
|
}
|
|
7713
|
+
armDrain(threadId) {
|
|
7714
|
+
void this.drainQueue(threadId).catch((err) => {
|
|
7715
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
7716
|
+
console.error(`[sideboard] drainQueue ${threadId}: ${detail}`);
|
|
7717
|
+
});
|
|
7718
|
+
}
|
|
7576
7719
|
async drainQueue(threadId) {
|
|
7577
7720
|
if (this.draining.has(threadId)) return;
|
|
7578
7721
|
this.draining.add(threadId);
|
|
@@ -7644,196 +7787,205 @@ var Orchestrator = class {
|
|
|
7644
7787
|
this.emit({ type: "status_changed", threadId, status: "running" });
|
|
7645
7788
|
this.emit({ type: "turn_started", threadId, prompt });
|
|
7646
7789
|
try {
|
|
7647
|
-
|
|
7648
|
-
|
|
7649
|
-
|
|
7650
|
-
|
|
7651
|
-
try {
|
|
7652
|
-
const compact = await maybeCompactContext(thread);
|
|
7653
|
-
if (compact.didCompact) {
|
|
7654
|
-
thread = updateThread(threadId, {
|
|
7655
|
-
messages: compact.thread.messages,
|
|
7656
|
-
sessionId: compact.thread.sessionId
|
|
7657
|
-
});
|
|
7658
|
-
this.emit({
|
|
7659
|
-
type: "context_compacted",
|
|
7660
|
-
threadId,
|
|
7661
|
-
olderCount: compact.olderCount ?? 0,
|
|
7662
|
-
method: compact.method ?? "extractive"
|
|
7663
|
-
});
|
|
7790
|
+
try {
|
|
7791
|
+
const baseline = await captureTurnBaseline(thread.worktreePath);
|
|
7792
|
+
if (baseline) this.turnBaselines.set(threadId, baseline);
|
|
7793
|
+
} catch {
|
|
7664
7794
|
}
|
|
7665
|
-
|
|
7666
|
-
|
|
7667
|
-
|
|
7668
|
-
|
|
7669
|
-
|
|
7670
|
-
|
|
7671
|
-
|
|
7672
|
-
|
|
7673
|
-
|
|
7674
|
-
|
|
7675
|
-
|
|
7676
|
-
|
|
7677
|
-
|
|
7678
|
-
|
|
7679
|
-
|
|
7680
|
-
|
|
7681
|
-
|
|
7682
|
-
|
|
7683
|
-
thread.worktreePath,
|
|
7684
|
-
gitPrompt,
|
|
7685
|
-
{
|
|
7686
|
-
attachments: autoContinue ? [] : sentAttachments ?? []
|
|
7795
|
+
try {
|
|
7796
|
+
const compact = await maybeCompactContext(thread);
|
|
7797
|
+
if (compact.didCompact) {
|
|
7798
|
+
thread = updateThread(threadId, {
|
|
7799
|
+
messages: compact.thread.messages,
|
|
7800
|
+
sessionId: compact.thread.sessionId
|
|
7801
|
+
});
|
|
7802
|
+
this.emit({
|
|
7803
|
+
type: "context_compacted",
|
|
7804
|
+
threadId,
|
|
7805
|
+
olderCount: compact.olderCount ?? 0,
|
|
7806
|
+
method: compact.method ?? "extractive"
|
|
7807
|
+
});
|
|
7808
|
+
}
|
|
7809
|
+
} catch (err) {
|
|
7810
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
7811
|
+
this.emit({ type: "error", threadId, message: `context compact failed: ${message}` });
|
|
7812
|
+
thread = this.requireThread(threadId);
|
|
7687
7813
|
}
|
|
7688
|
-
|
|
7689
|
-
|
|
7690
|
-
|
|
7691
|
-
|
|
7692
|
-
|
|
7693
|
-
|
|
7694
|
-
|
|
7695
|
-
|
|
7696
|
-
|
|
7697
|
-
|
|
7698
|
-
|
|
7699
|
-
|
|
7700
|
-
|
|
7701
|
-
|
|
7702
|
-
|
|
7703
|
-
|
|
7704
|
-
|
|
7705
|
-
|
|
7706
|
-
|
|
7707
|
-
|
|
7708
|
-
|
|
7709
|
-
|
|
7710
|
-
|
|
7711
|
-
|
|
7712
|
-
ticketProvider: issueTicket?.provider
|
|
7713
|
-
}) : null;
|
|
7714
|
-
const viewerContextReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatViewerContextReminder() : null;
|
|
7715
|
-
const reviewWriteGateReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) && isReviewWriteGatedThread(
|
|
7716
|
-
thread,
|
|
7717
|
-
thread.worktreePath ? threadsSharingWorktree(thread.worktreePath) : []
|
|
7718
|
-
) ? formatReviewWriteGateReminder() : null;
|
|
7719
|
-
const slackReplyContext = formatSlackRepliesForTurn(
|
|
7720
|
-
pendingSlackExternalReplies(thread.messages)
|
|
7721
|
-
);
|
|
7722
|
-
const turnReminders = [
|
|
7723
|
-
worktreeReminder,
|
|
7724
|
-
optionalServicesReminder,
|
|
7725
|
-
issueToolsReminder,
|
|
7726
|
-
reviewWriteGateReminder,
|
|
7727
|
-
viewerContextReminder,
|
|
7728
|
-
artifactReminder,
|
|
7729
|
-
longRunningReminder
|
|
7730
|
-
].filter(Boolean).join("\n\n") || void 0;
|
|
7731
|
-
const prGateDirective = thread.agent !== "brightsy" && !isOrchestratorThread(thread) && mentionsPrGoal(prompt) ? formatPrGateDirective() : null;
|
|
7732
|
-
const agentPrompt = [
|
|
7733
|
-
thread.planMode ? PLAN_MODE_INSTRUCTION : null,
|
|
7734
|
-
orchestrationReminder,
|
|
7735
|
-
prGateDirective,
|
|
7736
|
-
slackReplyContext,
|
|
7737
|
-
expandedPrompt
|
|
7738
|
-
].filter(Boolean).join("\n\n");
|
|
7739
|
-
if (!autoContinue && sentAttachments) {
|
|
7740
|
-
updateThread(threadId, { pendingTurnAttachments: [] });
|
|
7741
|
-
}
|
|
7742
|
-
const adapter = getAdapter(thread.agent);
|
|
7743
|
-
const resolved = await adapter.resolveSessionId(thread.worktreePath, thread.sessionId);
|
|
7744
|
-
if (resolved && resolved !== thread.sessionId) {
|
|
7745
|
-
updateThread(threadId, { sessionId: resolved });
|
|
7746
|
-
}
|
|
7747
|
-
const fresh = this.requireThread(threadId);
|
|
7748
|
-
if (!fresh.worktreePath?.trim()) {
|
|
7749
|
-
throw new Error(
|
|
7750
|
-
`Thread ${threadId} has no worktreePath \u2014 refusing to start an agent outside an isolated worktree`
|
|
7814
|
+
const promptText = typeof prompt === "string" ? prompt : "";
|
|
7815
|
+
const autoContinue = isJobContinuePrompt(promptText) || promptText.startsWith("The previous agent process ended before it finished.");
|
|
7816
|
+
const parked = takePendingTurnAttachments(thread);
|
|
7817
|
+
const sentAttachments = !autoContinue && parked.length > 0 ? parked : void 0;
|
|
7818
|
+
appendMessage(threadId, {
|
|
7819
|
+
role: "user",
|
|
7820
|
+
text: promptText,
|
|
7821
|
+
...sentAttachments ? { attachments: sentAttachments } : {},
|
|
7822
|
+
...autoContinue ? { origin: "continue" } : {},
|
|
7823
|
+
ts: (/* @__PURE__ */ new Date()).toISOString()
|
|
7824
|
+
});
|
|
7825
|
+
traceTurn("runTurn.afterUserMessage", {
|
|
7826
|
+
threadId,
|
|
7827
|
+
agent: thread.agent,
|
|
7828
|
+
orch: isOrchestratorThread(thread)
|
|
7829
|
+
});
|
|
7830
|
+
thread = this.requireThread(threadId);
|
|
7831
|
+
const gitPrompt = expandCanonicalGitRequest(promptText);
|
|
7832
|
+
const { agentPrompt: expandedPrompt } = expandComposerPrompt(
|
|
7833
|
+
thread.worktreePath,
|
|
7834
|
+
gitPrompt,
|
|
7835
|
+
{
|
|
7836
|
+
attachments: autoContinue ? [] : sentAttachments ?? []
|
|
7837
|
+
}
|
|
7751
7838
|
);
|
|
7752
|
-
|
|
7753
|
-
|
|
7754
|
-
|
|
7755
|
-
|
|
7756
|
-
|
|
7757
|
-
|
|
7758
|
-
|
|
7759
|
-
|
|
7760
|
-
|
|
7761
|
-
|
|
7762
|
-
|
|
7763
|
-
|
|
7764
|
-
|
|
7765
|
-
|
|
7766
|
-
|
|
7767
|
-
|
|
7768
|
-
|
|
7769
|
-
|
|
7770
|
-
|
|
7771
|
-
|
|
7772
|
-
|
|
7773
|
-
|
|
7774
|
-
|
|
7775
|
-
|
|
7776
|
-
|
|
7777
|
-
|
|
7778
|
-
|
|
7779
|
-
|
|
7780
|
-
|
|
7781
|
-
|
|
7782
|
-
|
|
7783
|
-
)
|
|
7784
|
-
|
|
7785
|
-
|
|
7786
|
-
|
|
7839
|
+
const slackInbound = /^(Slack DM|Slack @mention)(?:\n|$)/.test(
|
|
7840
|
+
expandedPrompt.trim()
|
|
7841
|
+
);
|
|
7842
|
+
const orchestrationReminder = isOrchestratorThread(thread) ? [
|
|
7843
|
+
coordinatorTurnReminder({
|
|
7844
|
+
parentId: threadId,
|
|
7845
|
+
goal: thread.sourceRef || thread.title
|
|
7846
|
+
}),
|
|
7847
|
+
slackInbound ? [
|
|
7848
|
+
"This turn is a Slack DM or @mention. Your reply is posted back in Slack \u2014 keep it concise. Sideboard signs it with this Mac's destination name; do not prefix the name yourself.",
|
|
7849
|
+
SLACK_REPLY_FORMATTING
|
|
7850
|
+
].join("\n") : null
|
|
7851
|
+
].filter(Boolean).join("\n") : null;
|
|
7852
|
+
const artifactReminder = thread.agent !== "brightsy" ? formatUiReminder() : null;
|
|
7853
|
+
const longRunningReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatLongRunningReminder() : null;
|
|
7854
|
+
const worktreeReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatWorktreeReminder() : null;
|
|
7855
|
+
const optionalServicesReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatOptionalServicesReminder(loadAppSettings().integrations) : null;
|
|
7856
|
+
const issueTicket = issueTicketFromThread(thread, resolveEffectiveIssueSource());
|
|
7857
|
+
const issueToolsReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatIssueToolsReminder({
|
|
7858
|
+
linear: isLinearConnected(),
|
|
7859
|
+
abletime: isAbleTimeConnected(),
|
|
7860
|
+
github: true,
|
|
7861
|
+
ticketId: issueTicket?.id,
|
|
7862
|
+
ticketProvider: issueTicket?.provider
|
|
7863
|
+
}) : null;
|
|
7864
|
+
const viewerContextReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatViewerContextReminder() : null;
|
|
7865
|
+
const reviewWriteGateReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) && isReviewWriteGatedThread(
|
|
7866
|
+
thread,
|
|
7867
|
+
thread.worktreePath ? threadsSharingWorktree(thread.worktreePath) : []
|
|
7868
|
+
) ? formatReviewWriteGateReminder() : null;
|
|
7869
|
+
const slackReplyContext = formatSlackRepliesForTurn(
|
|
7870
|
+
pendingSlackExternalReplies(thread.messages)
|
|
7871
|
+
);
|
|
7872
|
+
const turnReminders = [
|
|
7873
|
+
worktreeReminder,
|
|
7874
|
+
optionalServicesReminder,
|
|
7875
|
+
issueToolsReminder,
|
|
7876
|
+
reviewWriteGateReminder,
|
|
7877
|
+
viewerContextReminder,
|
|
7878
|
+
artifactReminder,
|
|
7879
|
+
longRunningReminder
|
|
7880
|
+
].filter(Boolean).join("\n\n") || void 0;
|
|
7881
|
+
const prGateDirective = thread.agent !== "brightsy" && !isOrchestratorThread(thread) && mentionsPrGoal(promptText) ? formatPrGateDirective() : null;
|
|
7882
|
+
const agentPrompt = [
|
|
7883
|
+
thread.planMode ? PLAN_MODE_INSTRUCTION : null,
|
|
7884
|
+
orchestrationReminder,
|
|
7885
|
+
prGateDirective,
|
|
7886
|
+
slackReplyContext,
|
|
7887
|
+
expandedPrompt
|
|
7888
|
+
].filter(Boolean).join("\n\n");
|
|
7889
|
+
if (!autoContinue && sentAttachments) {
|
|
7890
|
+
updateThread(threadId, { pendingTurnAttachments: [] });
|
|
7891
|
+
}
|
|
7892
|
+
const adapter = getAdapter(thread.agent);
|
|
7893
|
+
const resolved = await adapter.resolveSessionId(thread.worktreePath, thread.sessionId);
|
|
7894
|
+
if (resolved && resolved !== thread.sessionId) {
|
|
7895
|
+
updateThread(threadId, { sessionId: resolved });
|
|
7896
|
+
}
|
|
7897
|
+
const fresh = this.requireThread(threadId);
|
|
7898
|
+
if (!fresh.worktreePath?.trim()) {
|
|
7899
|
+
throw new Error(
|
|
7900
|
+
`Thread ${threadId} has no worktreePath \u2014 refusing to start an agent outside an isolated worktree`
|
|
7787
7901
|
);
|
|
7788
7902
|
}
|
|
7789
|
-
|
|
7790
|
-
|
|
7791
|
-
|
|
7792
|
-
|
|
7793
|
-
const
|
|
7794
|
-
|
|
7795
|
-
|
|
7796
|
-
|
|
7797
|
-
|
|
7798
|
-
|
|
7903
|
+
const isBrightsy = fresh.agent === "brightsy";
|
|
7904
|
+
const isOrchestration = isOrchestratorThread(fresh);
|
|
7905
|
+
const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-5RQMQKSB.js");
|
|
7906
|
+
const gitAuthMode = getGithubGitAuthMode();
|
|
7907
|
+
const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
|
|
7908
|
+
githubSlug: await withTimeout(
|
|
7909
|
+
resolveGithubRepoSlug(fresh.worktreePath),
|
|
7910
|
+
8e3,
|
|
7911
|
+
"resolveGithubRepoSlug"
|
|
7912
|
+
).catch(() => null),
|
|
7913
|
+
gitAuthMode
|
|
7799
7914
|
});
|
|
7800
|
-
|
|
7801
|
-
|
|
7802
|
-
|
|
7803
|
-
const
|
|
7804
|
-
|
|
7805
|
-
|
|
7806
|
-
|
|
7807
|
-
|
|
7808
|
-
|
|
7809
|
-
|
|
7915
|
+
const artifactDirective = isBrightsy ? null : formatArtifactDirective();
|
|
7916
|
+
const longRunningDirective = isBrightsy || isOrchestration ? null : formatLongRunningDirective();
|
|
7917
|
+
const optionalServicesDirective = isBrightsy || isOrchestration ? null : formatOptionalServicesDirective(loadAppSettings().integrations);
|
|
7918
|
+
const freshIssueTicket = issueTicketFromThread(fresh, resolveEffectiveIssueSource());
|
|
7919
|
+
const issueToolsDirective = isBrightsy || isOrchestration ? null : formatIssueToolsDirective({
|
|
7920
|
+
linear: isLinearConnected(),
|
|
7921
|
+
abletime: isAbleTimeConnected(),
|
|
7922
|
+
github: true,
|
|
7923
|
+
ticketId: freshIssueTicket?.id,
|
|
7924
|
+
ticketProvider: freshIssueTicket?.provider
|
|
7925
|
+
});
|
|
7926
|
+
const reviewWriteGateDirective = isBrightsy || isOrchestration || !isReviewWriteGatedThread(
|
|
7927
|
+
fresh,
|
|
7928
|
+
fresh.worktreePath ? threadsSharingWorktree(fresh.worktreePath) : []
|
|
7929
|
+
) ? null : formatReviewWriteGateDirective();
|
|
7930
|
+
let viewerContextDirective = null;
|
|
7931
|
+
if (!isBrightsy && !isOrchestration) {
|
|
7932
|
+
try {
|
|
7933
|
+
viewerContextDirective = formatViewerContextDirective(
|
|
7934
|
+
resolveViewerProfileForRepo(fresh.repoPath || fresh.worktreePath)
|
|
7935
|
+
);
|
|
7936
|
+
} catch {
|
|
7937
|
+
viewerContextDirective = formatViewerContextDirective(
|
|
7938
|
+
resolveViewerProfileForRepo()
|
|
7939
|
+
);
|
|
7940
|
+
}
|
|
7810
7941
|
}
|
|
7811
|
-
|
|
7812
|
-
|
|
7813
|
-
|
|
7814
|
-
|
|
7815
|
-
|
|
7816
|
-
|
|
7817
|
-
|
|
7818
|
-
|
|
7819
|
-
)
|
|
7942
|
+
const settings = loadWorkspaceSettings(fresh.worktreePath, fresh.repoPath);
|
|
7943
|
+
let renameBranchDirective = null;
|
|
7944
|
+
if (!isBrightsy && !isOrchestration && autoRenameBranchEnabled()) {
|
|
7945
|
+
const { resolveGitBranchPrefix } = await import("./branch-prefix-7DTIUJT2.js");
|
|
7946
|
+
renameBranchDirective = formatRenameBranchDirective(fresh, {
|
|
7947
|
+
customPrompt: settings?.prompts?.renameBranch,
|
|
7948
|
+
branchPrefix: resolveGitBranchPrefix({
|
|
7949
|
+
setting: gitBranchPrefixSetting()
|
|
7950
|
+
})
|
|
7820
7951
|
});
|
|
7821
7952
|
}
|
|
7822
|
-
|
|
7823
|
-
|
|
7824
|
-
|
|
7825
|
-
|
|
7826
|
-
|
|
7827
|
-
|
|
7828
|
-
|
|
7829
|
-
|
|
7830
|
-
|
|
7831
|
-
|
|
7832
|
-
|
|
7833
|
-
|
|
7834
|
-
|
|
7835
|
-
|
|
7953
|
+
let seed = null;
|
|
7954
|
+
if (!fresh.sessionId) {
|
|
7955
|
+
const prior = fresh.messages.slice(0, -1);
|
|
7956
|
+
seed = isBrightsy ? buildBrightsySessionSeed(prior) : buildSessionSeed(prior);
|
|
7957
|
+
}
|
|
7958
|
+
let coordinatorDirective = null;
|
|
7959
|
+
if (isOrchestration) {
|
|
7960
|
+
if (isGlobalThread(fresh)) {
|
|
7961
|
+
ensureGlobalCoordinatorCwd({ orchestratorThreadId: fresh.id });
|
|
7962
|
+
}
|
|
7963
|
+
if (!fresh.sessionId) {
|
|
7964
|
+
const inventory = await enrichWorkspacesWithGithub(this.listWorkspaces());
|
|
7965
|
+
coordinatorDirective = coordinatorSystemPrompt({
|
|
7966
|
+
goal: fresh.sourceRef || fresh.title || "Orchestration",
|
|
7967
|
+
parentId: fresh.id,
|
|
7968
|
+
workspaces: inventory,
|
|
7969
|
+
audience: /^(Slack DM|Slack @mention)(?:\n|$)/.test(
|
|
7970
|
+
expandedPrompt.trim()
|
|
7971
|
+
) ? "slack" : "desktop"
|
|
7972
|
+
});
|
|
7973
|
+
}
|
|
7974
|
+
}
|
|
7975
|
+
const cachedPrefix = fresh.sessionId ? "" : [
|
|
7976
|
+
coordinatorDirective,
|
|
7977
|
+
worktreeDirective,
|
|
7978
|
+
optionalServicesDirective,
|
|
7979
|
+
issueToolsDirective,
|
|
7980
|
+
reviewWriteGateDirective,
|
|
7981
|
+
viewerContextDirective,
|
|
7982
|
+
artifactDirective,
|
|
7983
|
+
longRunningDirective,
|
|
7984
|
+
renameBranchDirective,
|
|
7985
|
+
seed
|
|
7986
|
+
].filter(Boolean).join("\n\n---\n\n");
|
|
7836
7987
|
const stderrTail = [];
|
|
7988
|
+
traceTurn("runTurn.beforeSpawn", { threadId, agent: fresh.agent });
|
|
7837
7989
|
const handle = await spawnAgentTurn(
|
|
7838
7990
|
fresh,
|
|
7839
7991
|
{
|
|
@@ -8633,6 +8785,18 @@ var Orchestrator = class {
|
|
|
8633
8785
|
const thread = this.requireThread(threadRef);
|
|
8634
8786
|
return listWorktreeFiles(thread.worktreePath);
|
|
8635
8787
|
}
|
|
8788
|
+
async statPath(threadRef, relativePath) {
|
|
8789
|
+
const thread = this.requireThread(threadRef);
|
|
8790
|
+
if (relativePath.includes("..") || relativePath.startsWith("/")) {
|
|
8791
|
+
return "missing";
|
|
8792
|
+
}
|
|
8793
|
+
if (!relativePath || relativePath === ".") return "dir";
|
|
8794
|
+
try {
|
|
8795
|
+
return statWorktreePath(thread.worktreePath, relativePath);
|
|
8796
|
+
} catch {
|
|
8797
|
+
return "missing";
|
|
8798
|
+
}
|
|
8799
|
+
}
|
|
8636
8800
|
async readFile(threadRef, relativePath) {
|
|
8637
8801
|
const thread = this.requireThread(threadRef);
|
|
8638
8802
|
if (relativePath.includes("..") || relativePath.startsWith("/")) {
|
|
@@ -8788,7 +8952,7 @@ var Orchestrator = class {
|
|
|
8788
8952
|
if (!titled.userSetTitle && meta.title && titled.title !== meta.title) {
|
|
8789
8953
|
updateThread(thread.id, { title: meta.title });
|
|
8790
8954
|
}
|
|
8791
|
-
const { autoArchiveOnMergeEnabled } = await import("./app-settings-
|
|
8955
|
+
const { autoArchiveOnMergeEnabled } = await import("./app-settings-5RQMQKSB.js");
|
|
8792
8956
|
const latest = this.requireThread(thread.id);
|
|
8793
8957
|
if (!shouldAutoArchiveOnPrMerge({
|
|
8794
8958
|
previousPrState: prevState || null,
|
|
@@ -9067,7 +9231,7 @@ var Orchestrator = class {
|
|
|
9067
9231
|
this.enforceHistoryRetention();
|
|
9068
9232
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
9069
9233
|
try {
|
|
9070
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
9234
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-TDBA64II.js");
|
|
9071
9235
|
await ensureWorkspace2(thread.repoPath);
|
|
9072
9236
|
} catch {
|
|
9073
9237
|
}
|
|
@@ -9094,7 +9258,7 @@ var Orchestrator = class {
|
|
|
9094
9258
|
await runArchiveScript(thread.repoPath, thread.worktreePath);
|
|
9095
9259
|
} catch {
|
|
9096
9260
|
}
|
|
9097
|
-
const { deleteBranchOnPurgeEnabled } = await import("./app-settings-
|
|
9261
|
+
const { deleteBranchOnPurgeEnabled } = await import("./app-settings-5RQMQKSB.js");
|
|
9098
9262
|
const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
|
|
9099
9263
|
await removeWorktree(thread.repoPath, thread.worktreePath, {
|
|
9100
9264
|
deleteBranch: deleteBranch ? thread.branchName : void 0
|
|
@@ -9121,13 +9285,13 @@ var Orchestrator = class {
|
|
|
9121
9285
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
9122
9286
|
);
|
|
9123
9287
|
}
|
|
9124
|
-
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-
|
|
9288
|
+
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-I573UOPD.js");
|
|
9125
9289
|
const slug = thread.worktreePath.split("/").pop();
|
|
9126
9290
|
const dest = thread.worktreePath;
|
|
9127
9291
|
await withRepoGitLock(thread.repoPath, async () => {
|
|
9128
9292
|
await git(["worktree", "add", dest, thread.branchName], thread.repoPath);
|
|
9129
9293
|
});
|
|
9130
|
-
const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-
|
|
9294
|
+
const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-K7QK4RI5.js");
|
|
9131
9295
|
await ensureWorktreeSideboardIgnored2(dest);
|
|
9132
9296
|
void createThreadWorktree2;
|
|
9133
9297
|
void slug;
|
|
@@ -9231,7 +9395,7 @@ async function startOrchestration(opts) {
|
|
|
9231
9395
|
sourceRef: "default",
|
|
9232
9396
|
...createOpts
|
|
9233
9397
|
}).catch(async () => {
|
|
9234
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
9398
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-I573UOPD.js");
|
|
9235
9399
|
const repo = await resolveRepoRoot2(repoPath);
|
|
9236
9400
|
const def = await resolveDefaultBranch2(repo);
|
|
9237
9401
|
return orch.createThread({
|