@sideboard-ai/core 0.1.216 → 0.1.218
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-WBDDLRBY.js → agents-NWJ7DFJD.js} +8 -7
- package/dist/{agents-HETHRRZJ.js → agents-YABJUV3V.js} +9 -9
- 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-7MTVRNP4.js → chunk-FSIJGLSV.js} +1173 -1186
- package/dist/{chunk-LS6TSOCE.js → chunk-HSYE5ID6.js} +5 -5
- package/dist/{chunk-UFHNSFAS.js → chunk-HVUVQXZ2.js} +5 -1
- package/dist/{chunk-SALM35KD.js → chunk-IILG7DPX.js} +5 -5
- package/dist/{chunk-D2IKXMF3.js → chunk-JWBPSD7Q.js} +453 -289
- package/dist/{chunk-NI243N27.js → chunk-KTZESHYH.js} +15 -7
- package/dist/{chunk-KFD2OXCE.js → chunk-MW57SKKR.js} +19 -6
- package/dist/{chunk-XYKVRRC2.js → chunk-NFWPDEN4.js} +15 -7
- package/dist/{chunk-FNGXKY5W.js → chunk-OPYBLX4V.js} +19 -6
- 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-C32SBNA3.js → chunk-SRFFIFW6.js} +457 -294
- 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-DFTVZEZY.js → chunk-XRHTRXZN.js} +1051 -1050
- 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-5V7GEPBG.js} +6 -6
- package/dist/{coordinator-prompt-LE2GQZ2X.js → coordinator-prompt-J4QSNTKE.js} +6 -5
- package/dist/{global-workspace-6P236KKG.js → global-workspace-4TEMLESD.js} +6 -6
- package/dist/{global-workspace-KT3FRHZL.js → global-workspace-XPTFHMKL.js} +6 -5
- package/dist/index.cjs +1027 -821
- package/dist/index.d.cts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +22 -18
- package/dist/mcp/run-stdio.cjs +1838 -1651
- package/dist/mcp/run-stdio.js +16 -14
- package/dist/{orchestrator-WVZPTHBV.js → orchestrator-HKW3VLGX.js} +10 -10
- package/dist/{orchestrator-MI7A5DQZ.js → orchestrator-SWRTYFHX.js} +9 -8
- package/dist/{run-EBWL2Q4N.js → run-QDZCTP4Y.js} +2 -1
- package/dist/{run-CAGKZLHA.js → run-UEQM4JMZ.js} +2 -1
- package/dist/{workspaces-KM7KTLVO.js → workspaces-2HQP654Q.js} +6 -5
- package/dist/{workspaces-R5LJCJRB.js → workspaces-BCBBMMXB.js} +6 -6
- 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
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
resolveQuotaFallbackAgent,
|
|
25
25
|
stripBrightsyNdjsonNoise,
|
|
26
26
|
toolDescription
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-XRHTRXZN.js";
|
|
28
28
|
import {
|
|
29
29
|
SLACK_REPLY_FORMATTING,
|
|
30
30
|
addWorkspace,
|
|
@@ -47,7 +47,7 @@ import {
|
|
|
47
47
|
stageAbsolutePathsAsAttachments,
|
|
48
48
|
stageBuffersAsAttachments,
|
|
49
49
|
syncWorkspacesFromThreads
|
|
50
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-OPYBLX4V.js";
|
|
51
51
|
import {
|
|
52
52
|
addPrStackLayer,
|
|
53
53
|
allocateTeamName,
|
|
@@ -81,7 +81,6 @@ import {
|
|
|
81
81
|
mergeAgentGitAuthEnv,
|
|
82
82
|
mergePr,
|
|
83
83
|
normalizeWorktreePath,
|
|
84
|
-
originGhRepoEnv,
|
|
85
84
|
pushBranch,
|
|
86
85
|
removeWorktree,
|
|
87
86
|
resolveAgentGitAuthEnv,
|
|
@@ -97,7 +96,7 @@ import {
|
|
|
97
96
|
worktreeDisplayLabelForGroup,
|
|
98
97
|
worktreeNameFromPath,
|
|
99
98
|
worktreeSlugForTicket
|
|
100
|
-
} from "./chunk-
|
|
99
|
+
} from "./chunk-KTZESHYH.js";
|
|
101
100
|
import {
|
|
102
101
|
ATTACHMENTS_DIR,
|
|
103
102
|
DETACHED_JOBS_DIR,
|
|
@@ -106,7 +105,7 @@ import {
|
|
|
106
105
|
} from "./chunk-6K64FJDD.js";
|
|
107
106
|
import {
|
|
108
107
|
ensureWorktreeSideboardIgnored
|
|
109
|
-
} from "./chunk-
|
|
108
|
+
} from "./chunk-PO4M4JAJ.js";
|
|
110
109
|
import {
|
|
111
110
|
httpFetch
|
|
112
111
|
} from "./chunk-N7WZ6NIN.js";
|
|
@@ -129,7 +128,7 @@ import {
|
|
|
129
128
|
shouldRetryFailedAgentTurn,
|
|
130
129
|
summarizeTurnStderr,
|
|
131
130
|
turnFailChatText
|
|
132
|
-
} from "./chunk-
|
|
131
|
+
} from "./chunk-TQBUXKIB.js";
|
|
133
132
|
import {
|
|
134
133
|
HISTORY_CLEANUP_INTERVAL_HOURS_DEFAULT,
|
|
135
134
|
applyTurnUsage,
|
|
@@ -164,10 +163,7 @@ import {
|
|
|
164
163
|
updateAdvancedSettings,
|
|
165
164
|
usageOnLimit,
|
|
166
165
|
writeSecureJson
|
|
167
|
-
} from "./chunk-
|
|
168
|
-
import {
|
|
169
|
-
stripNestedElectronEnv
|
|
170
|
-
} from "./chunk-4TR3HZFT.js";
|
|
166
|
+
} from "./chunk-EWHJNJHV.js";
|
|
171
167
|
import {
|
|
172
168
|
examplePrefixedBranch,
|
|
173
169
|
sanitizeGitBranchPrefix
|
|
@@ -210,7 +206,10 @@ import {
|
|
|
210
206
|
git,
|
|
211
207
|
resolveGitDirsForLockRecovery,
|
|
212
208
|
run
|
|
213
|
-
} from "./chunk-
|
|
209
|
+
} from "./chunk-HVUVQXZ2.js";
|
|
210
|
+
import {
|
|
211
|
+
stripNestedElectronEnv
|
|
212
|
+
} from "./chunk-4TR3HZFT.js";
|
|
214
213
|
|
|
215
214
|
// src/orchestrator/orchestrator.ts
|
|
216
215
|
import { EventEmitter } from "events";
|
|
@@ -483,7 +482,7 @@ async function continueSourceThread(threadId, prompt) {
|
|
|
483
482
|
await continueOnReply(threadId, prompt);
|
|
484
483
|
return;
|
|
485
484
|
}
|
|
486
|
-
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-
|
|
485
|
+
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-HKW3VLGX.js");
|
|
487
486
|
await getOrchestrator2().send(threadId, prompt);
|
|
488
487
|
} catch {
|
|
489
488
|
}
|
|
@@ -749,20 +748,104 @@ import { existsSync as existsSync19 } from "fs";
|
|
|
749
748
|
import { createInterface } from "readline";
|
|
750
749
|
import { execa } from "execa";
|
|
751
750
|
|
|
751
|
+
// src/agents/turn-trace.ts
|
|
752
|
+
import { appendFileSync } from "fs";
|
|
753
|
+
import { join as join4 } from "path";
|
|
754
|
+
function traceTurn(phase, extra) {
|
|
755
|
+
try {
|
|
756
|
+
const line = `${JSON.stringify({ t: (/* @__PURE__ */ new Date()).toISOString(), phase, ...extra })}
|
|
757
|
+
`;
|
|
758
|
+
appendFileSync(join4(appDataDir(), "turn-spawn.log"), line);
|
|
759
|
+
} catch {
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
async function withTimeout(promise, ms, label) {
|
|
763
|
+
let timer;
|
|
764
|
+
try {
|
|
765
|
+
return await Promise.race([
|
|
766
|
+
promise,
|
|
767
|
+
new Promise((_, reject) => {
|
|
768
|
+
timer = setTimeout(
|
|
769
|
+
() => reject(new Error(`${label} timed out after ${ms}ms`)),
|
|
770
|
+
ms
|
|
771
|
+
);
|
|
772
|
+
})
|
|
773
|
+
]);
|
|
774
|
+
} finally {
|
|
775
|
+
if (timer) clearTimeout(timer);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
// src/hook/agent-host-env.ts
|
|
780
|
+
import { delimiter } from "path";
|
|
781
|
+
var DROP_EXACT = /* @__PURE__ */ new Set([
|
|
782
|
+
"NODE_PATH",
|
|
783
|
+
"NODE_ENV_ELECTRON_VITE",
|
|
784
|
+
"INIT_CWD",
|
|
785
|
+
"npm_command",
|
|
786
|
+
"npm_execpath",
|
|
787
|
+
"npm_node_execpath",
|
|
788
|
+
"npm_lifecycle_event",
|
|
789
|
+
"npm_lifecycle_script",
|
|
790
|
+
"PNPM_SCRIPT_SRC_DIR",
|
|
791
|
+
"PNPM_STORE_DIR",
|
|
792
|
+
"PORT",
|
|
793
|
+
"SIDEBOARD_ROOT_PATH",
|
|
794
|
+
"SIDEBOARD_IS_LOCAL",
|
|
795
|
+
"SIDEBOARD_WORKSPACE_PATH",
|
|
796
|
+
"SIDEBOARD_WORKSPACE_NAME",
|
|
797
|
+
"SIDEBOARD_PORT",
|
|
798
|
+
"CONDUCTOR_ROOT_PATH",
|
|
799
|
+
"CONDUCTOR_IS_LOCAL",
|
|
800
|
+
"CONDUCTOR_WORKSPACE_PATH",
|
|
801
|
+
"CONDUCTOR_WORKSPACE_NAME",
|
|
802
|
+
"CONDUCTOR_PORT",
|
|
803
|
+
"CONDUCTOR_DEFAULT_BRANCH",
|
|
804
|
+
"SIDEBOARD_DEFAULT_BRANCH"
|
|
805
|
+
]);
|
|
806
|
+
var DROP_PREFIXES = [
|
|
807
|
+
"npm_package_",
|
|
808
|
+
"npm_config_",
|
|
809
|
+
"PNPM_",
|
|
810
|
+
"SIDEBOARD_PORT_",
|
|
811
|
+
"CONDUCTOR_PORT_"
|
|
812
|
+
];
|
|
813
|
+
var HOST_PATH_NOISE = /(?:^|\/)node_modules\/\.bin(?:\/|$)|node-gyp-bin|electron-vite/i;
|
|
814
|
+
function isAgentHostEnvKey(key) {
|
|
815
|
+
if (DROP_EXACT.has(key)) return true;
|
|
816
|
+
return DROP_PREFIXES.some((prefix) => key.startsWith(prefix));
|
|
817
|
+
}
|
|
818
|
+
function stripHostToolingPath(pathValue) {
|
|
819
|
+
if (!pathValue?.trim()) return "";
|
|
820
|
+
return pathValue.split(delimiter).filter((part) => part && !HOST_PATH_NOISE.test(part.replace(/\\/g, "/"))).join(delimiter);
|
|
821
|
+
}
|
|
822
|
+
function sanitizeAgentHostEnv(env, cwd) {
|
|
823
|
+
for (const key of Object.keys(env)) {
|
|
824
|
+
if (isAgentHostEnvKey(key)) delete env[key];
|
|
825
|
+
}
|
|
826
|
+
env.PATH = stripHostToolingPath(env.PATH);
|
|
827
|
+
const worktree = cwd?.trim();
|
|
828
|
+
if (worktree) {
|
|
829
|
+
env.PWD = worktree;
|
|
830
|
+
env.INIT_CWD = worktree;
|
|
831
|
+
}
|
|
832
|
+
return env;
|
|
833
|
+
}
|
|
834
|
+
|
|
752
835
|
// src/hook/worktree-pkg-cache.ts
|
|
753
836
|
import { existsSync as existsSync3, mkdirSync } from "fs";
|
|
754
|
-
import { join as
|
|
837
|
+
import { join as join5 } from "path";
|
|
755
838
|
var WORKTREE_PKG_CACHE_REL = ".context/.sideboard/pkg-cache";
|
|
756
839
|
function worktreePkgCacheRoot(worktreePath) {
|
|
757
|
-
return
|
|
840
|
+
return join5(worktreePath, WORKTREE_PKG_CACHE_REL);
|
|
758
841
|
}
|
|
759
842
|
function worktreePkgCacheEnv(worktreePath) {
|
|
760
843
|
const root = worktreePkgCacheRoot(worktreePath);
|
|
761
|
-
const store =
|
|
762
|
-
const pnpmCache =
|
|
763
|
-
const npmCache =
|
|
764
|
-
const nodeGyp =
|
|
765
|
-
const electron =
|
|
844
|
+
const store = join5(root, "pnpm-store");
|
|
845
|
+
const pnpmCache = join5(root, "pnpm");
|
|
846
|
+
const npmCache = join5(root, "npm");
|
|
847
|
+
const nodeGyp = join5(root, "node-gyp");
|
|
848
|
+
const electron = join5(root, "electron");
|
|
766
849
|
return {
|
|
767
850
|
npm_config_store_dir: store,
|
|
768
851
|
PNPM_STORE_DIR: store,
|
|
@@ -817,9 +900,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
817
900
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
818
901
|
);
|
|
819
902
|
}
|
|
820
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
903
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-4TEMLESD.js");
|
|
821
904
|
if (isGlobalThread2(thread)) {
|
|
822
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
905
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-5V7GEPBG.js");
|
|
823
906
|
ensureGlobalCoordinatorCwd2(
|
|
824
907
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
825
908
|
);
|
|
@@ -828,26 +911,54 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
828
911
|
assertOrchestratorCapableAgent(thread.agent);
|
|
829
912
|
}
|
|
830
913
|
const adapter = getAdapter(thread.agent);
|
|
831
|
-
const
|
|
914
|
+
const orch = isOrchestratorThread(thread);
|
|
915
|
+
traceTurn("spawn.buildTurn.start", {
|
|
916
|
+
threadId: thread.id,
|
|
917
|
+
agent: thread.agent,
|
|
918
|
+
orch,
|
|
919
|
+
cwd: thread.worktreePath
|
|
920
|
+
});
|
|
921
|
+
const cmd = await withTimeout(
|
|
922
|
+
adapter.buildTurn(thread, input),
|
|
923
|
+
2e4,
|
|
924
|
+
"buildTurn"
|
|
925
|
+
);
|
|
926
|
+
traceTurn("spawn.buildTurn.done", { file: cmd.file, cwd: cmd.cwd });
|
|
832
927
|
if (cmd.cwd !== thread.worktreePath) {
|
|
833
928
|
throw new Error(
|
|
834
929
|
`Agent cwd must be the thread worktree (got ${cmd.cwd}, expected ${thread.worktreePath})`
|
|
835
930
|
);
|
|
836
931
|
}
|
|
837
932
|
const env = childEnvWithAppSettings(cmd.env);
|
|
933
|
+
sanitizeAgentHostEnv(env, cmd.cwd);
|
|
934
|
+
ensureAgentPath(env);
|
|
838
935
|
applyPromptCacheTtlEnv(thread.agent, env);
|
|
839
936
|
applyAgentRunnerHeapEnv(env);
|
|
840
|
-
if (!
|
|
937
|
+
if (!orch) {
|
|
841
938
|
applyWorktreePkgCacheEnv(env, thread.worktreePath);
|
|
842
939
|
}
|
|
843
940
|
try {
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
941
|
+
traceTurn("spawn.gitAuth.start");
|
|
942
|
+
mergeAgentGitAuthEnv(
|
|
943
|
+
env,
|
|
944
|
+
await withTimeout(
|
|
945
|
+
resolveAgentGitAuthEnv(env, { cwd: thread.worktreePath }),
|
|
946
|
+
8e3,
|
|
947
|
+
"gitAuth"
|
|
948
|
+
)
|
|
949
|
+
);
|
|
950
|
+
if (!orch) {
|
|
951
|
+
const slug = await withTimeout(
|
|
952
|
+
resolveGithubRepoSlug(thread.worktreePath),
|
|
953
|
+
8e3,
|
|
954
|
+
"resolveGithubRepoSlug"
|
|
955
|
+
);
|
|
956
|
+
if (slug) env.GH_REPO = slug;
|
|
848
957
|
}
|
|
958
|
+
traceTurn("spawn.gitAuth.done", { ghRepo: env.GH_REPO ?? null });
|
|
849
959
|
} catch (err) {
|
|
850
960
|
const detail = err instanceof Error ? err.message : String(err);
|
|
961
|
+
traceTurn("spawn.gitAuth.fail", { detail });
|
|
851
962
|
console.warn(`[sideboard] git auth env failed (${thread.worktreePath}): ${detail}`);
|
|
852
963
|
}
|
|
853
964
|
const child = execa(cmd.file, cmd.args, {
|
|
@@ -860,6 +971,7 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
860
971
|
// so Claude doesn't wait ~3s for an empty pipe.
|
|
861
972
|
stdin: cmd.stdin != null ? "pipe" : "ignore"
|
|
862
973
|
});
|
|
974
|
+
traceTurn("spawn.execa", { pid: child.pid ?? null, file: cmd.file });
|
|
863
975
|
if (cmd.stdin != null && child.stdin) {
|
|
864
976
|
child.stdin.write(cmd.stdin);
|
|
865
977
|
child.stdin.end();
|
|
@@ -1091,14 +1203,14 @@ import {
|
|
|
1091
1203
|
readFileSync as readFileSync4
|
|
1092
1204
|
} from "fs";
|
|
1093
1205
|
import { createServer } from "net";
|
|
1094
|
-
import { basename, dirname as dirname2, join as
|
|
1206
|
+
import { basename, dirname as dirname2, join as join7 } from "path";
|
|
1095
1207
|
import { execa as execa2 } from "execa";
|
|
1096
1208
|
import { createInterface as createInterface2 } from "readline";
|
|
1097
1209
|
|
|
1098
1210
|
// src/review/request-review.ts
|
|
1099
1211
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
1100
1212
|
import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync } from "fs";
|
|
1101
|
-
import { dirname, join as
|
|
1213
|
+
import { dirname, join as join6 } from "path";
|
|
1102
1214
|
|
|
1103
1215
|
// src/threads/chat-tabs.ts
|
|
1104
1216
|
import { randomUUID } from "crypto";
|
|
@@ -1889,12 +2001,12 @@ function readTextIfPresent(abs) {
|
|
|
1889
2001
|
}
|
|
1890
2002
|
}
|
|
1891
2003
|
function readLocalGuidelines(worktreePath) {
|
|
1892
|
-
const localAbs =
|
|
2004
|
+
const localAbs = join6(worktreePath, REVIEW_REQUEST_PATH);
|
|
1893
2005
|
const localContent = readTextIfPresent(localAbs);
|
|
1894
2006
|
if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
|
|
1895
2007
|
return { path: REVIEW_REQUEST_PATH, content: localContent };
|
|
1896
2008
|
}
|
|
1897
|
-
const legacyAbs =
|
|
2009
|
+
const legacyAbs = join6(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
|
|
1898
2010
|
const legacyContent = readTextIfPresent(legacyAbs);
|
|
1899
2011
|
if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
|
|
1900
2012
|
return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
|
|
@@ -1918,7 +2030,7 @@ function contextGuidelines(content, source) {
|
|
|
1918
2030
|
};
|
|
1919
2031
|
}
|
|
1920
2032
|
function writeContextGuidelines(worktreePath, content) {
|
|
1921
|
-
const abs =
|
|
2033
|
+
const abs = join6(worktreePath, CONTEXT_REVIEW_PATH);
|
|
1922
2034
|
mkdirSync2(dirname(abs), { recursive: true });
|
|
1923
2035
|
const body = content.endsWith("\n") ? content : `${content}
|
|
1924
2036
|
`;
|
|
@@ -1926,19 +2038,19 @@ function writeContextGuidelines(worktreePath, content) {
|
|
|
1926
2038
|
return body;
|
|
1927
2039
|
}
|
|
1928
2040
|
function readSideboardReview(worktreePath, repoPath) {
|
|
1929
|
-
const fromWorktree = readTextIfPresent(
|
|
2041
|
+
const fromWorktree = readTextIfPresent(join6(worktreePath, REPO_REVIEW_PATH));
|
|
1930
2042
|
if (fromWorktree) return fromWorktree;
|
|
1931
2043
|
const repo = repoPath?.replace(/\/+$/, "");
|
|
1932
2044
|
const wt = worktreePath.replace(/\/+$/, "");
|
|
1933
2045
|
if (!repo || repo === wt) return null;
|
|
1934
|
-
return readTextIfPresent(
|
|
2046
|
+
return readTextIfPresent(join6(repo, REPO_REVIEW_PATH));
|
|
1935
2047
|
}
|
|
1936
2048
|
function ensureReviewGuidelinesFile(worktreePath, repoPath) {
|
|
1937
|
-
const skillContent = readTextIfPresent(
|
|
2049
|
+
const skillContent = readTextIfPresent(join6(worktreePath, REVIEW_SKILL_PATH));
|
|
1938
2050
|
if (skillContent) {
|
|
1939
2051
|
return { ...skillGuidelines(skillContent, "skill"), wrote: false };
|
|
1940
2052
|
}
|
|
1941
|
-
const contextContent = readTextIfPresent(
|
|
2053
|
+
const contextContent = readTextIfPresent(join6(worktreePath, CONTEXT_REVIEW_PATH));
|
|
1942
2054
|
if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
|
|
1943
2055
|
return { ...contextGuidelines(contextContent, "local"), wrote: false };
|
|
1944
2056
|
}
|
|
@@ -1976,7 +2088,7 @@ function buildReviewRequestAttachment(content, opts) {
|
|
|
1976
2088
|
};
|
|
1977
2089
|
}
|
|
1978
2090
|
function readExistingReviewRequestFile(worktreePath) {
|
|
1979
|
-
return readTextIfPresent(
|
|
2091
|
+
return readTextIfPresent(join6(worktreePath, REVIEW_SKILL_PATH)) ?? readTextIfPresent(join6(worktreePath, CONTEXT_REVIEW_PATH)) ?? readTextIfPresent(join6(worktreePath, REPO_REVIEW_PATH)) ?? readTextIfPresent(join6(worktreePath, REVIEW_REQUEST_PATH)) ?? readTextIfPresent(join6(worktreePath, LEGACY_REVIEW_REQUEST_PATH));
|
|
1980
2092
|
}
|
|
1981
2093
|
async function requestReview(threadRef, send) {
|
|
1982
2094
|
const from = findThreadByRef(threadRef);
|
|
@@ -2011,7 +2123,7 @@ function matchSimpleGlob(pattern, name) {
|
|
|
2011
2123
|
return new RegExp(`^${escaped}$`).test(name);
|
|
2012
2124
|
}
|
|
2013
2125
|
function readWorktreeInclude(repoPath) {
|
|
2014
|
-
const path =
|
|
2126
|
+
const path = join7(repoPath, ".worktreeinclude");
|
|
2015
2127
|
if (!existsSync5(path)) return [];
|
|
2016
2128
|
return readFileSync4(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
2017
2129
|
}
|
|
@@ -2052,9 +2164,9 @@ function copyConfiguredFiles(repoPath, worktreePath) {
|
|
|
2052
2164
|
const patterns = resolveFilesToCopy(repoPath);
|
|
2053
2165
|
const copied = [];
|
|
2054
2166
|
for (const rel of patterns) {
|
|
2055
|
-
const src =
|
|
2167
|
+
const src = join7(repoPath, rel);
|
|
2056
2168
|
if (!existsSync5(src)) continue;
|
|
2057
|
-
const dest =
|
|
2169
|
+
const dest = join7(worktreePath, rel);
|
|
2058
2170
|
mkdirSync3(dirname2(dest), { recursive: true });
|
|
2059
2171
|
copyFileSync(src, dest);
|
|
2060
2172
|
copied.push(rel);
|
|
@@ -2359,7 +2471,7 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
|
|
|
2359
2471
|
// src/store/setup-log.ts
|
|
2360
2472
|
import { createHash } from "crypto";
|
|
2361
2473
|
import { existsSync as existsSync6, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
|
|
2362
|
-
import { join as
|
|
2474
|
+
import { join as join8 } from "path";
|
|
2363
2475
|
var EMPTY = {
|
|
2364
2476
|
output: "",
|
|
2365
2477
|
running: false,
|
|
@@ -2401,7 +2513,7 @@ function materialize(mem) {
|
|
|
2401
2513
|
};
|
|
2402
2514
|
}
|
|
2403
2515
|
function setupLogPath(threadId) {
|
|
2404
|
-
return
|
|
2516
|
+
return join8(threadsDir(), `${threadId}.setup.log.json`);
|
|
2405
2517
|
}
|
|
2406
2518
|
function setupLogKeyForWorktree(worktreePath) {
|
|
2407
2519
|
const norm = normalizeWorktreePath(worktreePath);
|
|
@@ -2510,7 +2622,7 @@ function finishSetupLog(threadId, exitCode, source) {
|
|
|
2510
2622
|
|
|
2511
2623
|
// src/git/orphan-cleanup.ts
|
|
2512
2624
|
import { existsSync as existsSync7, readdirSync as readdirSync2, statSync } from "fs";
|
|
2513
|
-
import { join as
|
|
2625
|
+
import { join as join9 } from "path";
|
|
2514
2626
|
function isSideboardWorktreePath(path) {
|
|
2515
2627
|
return path.includes("/.sideboard/worktrees/") || path.includes("/sideboard/workspaces/");
|
|
2516
2628
|
}
|
|
@@ -2557,9 +2669,9 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
2557
2669
|
if (existsSync7(root)) {
|
|
2558
2670
|
for (const entry of readdirSync2(root, { withFileTypes: true })) {
|
|
2559
2671
|
if (!entry.isDirectory()) continue;
|
|
2560
|
-
const path =
|
|
2672
|
+
const path = join9(root, entry.name).replace(/\/$/, "");
|
|
2561
2673
|
if (known.has(path) || seen.has(path)) continue;
|
|
2562
|
-
if (!existsSync7(
|
|
2674
|
+
if (!existsSync7(join9(path, ".git"))) continue;
|
|
2563
2675
|
seen.add(path);
|
|
2564
2676
|
let mtimeMs = 0;
|
|
2565
2677
|
try {
|
|
@@ -2773,7 +2885,7 @@ async function applyThreadIntoMain(thread, opts) {
|
|
|
2773
2885
|
|
|
2774
2886
|
// src/git/clone-repo.ts
|
|
2775
2887
|
import { existsSync as existsSync8 } from "fs";
|
|
2776
|
-
import { basename as basename2, join as
|
|
2888
|
+
import { basename as basename2, join as join10 } from "path";
|
|
2777
2889
|
import { execa as execa4 } from "execa";
|
|
2778
2890
|
async function cloneRepoIntoSideboard(opts) {
|
|
2779
2891
|
const url = opts.url.trim();
|
|
@@ -2784,7 +2896,7 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
2784
2896
|
name = leaf || "repo";
|
|
2785
2897
|
}
|
|
2786
2898
|
name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
|
|
2787
|
-
const dest =
|
|
2899
|
+
const dest = join10(sideboardReposDir(), name);
|
|
2788
2900
|
if (existsSync8(dest)) {
|
|
2789
2901
|
const repoPath2 = await resolveRepoRoot(dest);
|
|
2790
2902
|
const workspace2 = await ensureWorkspace(repoPath2);
|
|
@@ -2803,9 +2915,9 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
2803
2915
|
|
|
2804
2916
|
// src/store/desktop-host.ts
|
|
2805
2917
|
import { readFileSync as readFileSync6, unlinkSync, writeFileSync as writeFileSync3 } from "fs";
|
|
2806
|
-
import { join as
|
|
2918
|
+
import { join as join11 } from "path";
|
|
2807
2919
|
function desktopHostPidPath() {
|
|
2808
|
-
return
|
|
2920
|
+
return join11(appDataDir(), "desktop-host.pid");
|
|
2809
2921
|
}
|
|
2810
2922
|
function claimDesktopHost(pid = process.pid) {
|
|
2811
2923
|
writeFileSync3(desktopHostPidPath(), `${pid}
|
|
@@ -2891,14 +3003,14 @@ function notifyParentOfChildHalt(child, status, send) {
|
|
|
2891
3003
|
|
|
2892
3004
|
// src/mcp/wait-for-job.ts
|
|
2893
3005
|
import {
|
|
2894
|
-
appendFileSync,
|
|
3006
|
+
appendFileSync as appendFileSync2,
|
|
2895
3007
|
existsSync as existsSync9,
|
|
2896
3008
|
mkdirSync as mkdirSync4,
|
|
2897
3009
|
readdirSync as readdirSync3,
|
|
2898
3010
|
readFileSync as readFileSync7,
|
|
2899
3011
|
writeFileSync as writeFileSync4
|
|
2900
3012
|
} from "fs";
|
|
2901
|
-
import { dirname as dirname3, join as
|
|
3013
|
+
import { dirname as dirname3, join as join12 } from "path";
|
|
2902
3014
|
|
|
2903
3015
|
// src/mcp/wait-for-turn.ts
|
|
2904
3016
|
var MCP_WAIT_FOR_TURN_MAX_MS = 45e3;
|
|
@@ -2970,7 +3082,7 @@ function readIntFile(file) {
|
|
|
2970
3082
|
return Number.isInteger(n) ? n : null;
|
|
2971
3083
|
}
|
|
2972
3084
|
function jobDir(root, id, legacy = false) {
|
|
2973
|
-
return
|
|
3085
|
+
return join12(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
|
|
2974
3086
|
}
|
|
2975
3087
|
function resolveJobDir(root, id) {
|
|
2976
3088
|
const modern = jobDir(root, id, false);
|
|
@@ -2980,7 +3092,7 @@ function resolveJobDir(root, id) {
|
|
|
2980
3092
|
return modern;
|
|
2981
3093
|
}
|
|
2982
3094
|
function listJobIdsIn(root, rel) {
|
|
2983
|
-
const dir =
|
|
3095
|
+
const dir = join12(root, rel);
|
|
2984
3096
|
if (!existsSync9(dir)) return [];
|
|
2985
3097
|
return readdirSync3(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
|
|
2986
3098
|
}
|
|
@@ -2994,7 +3106,7 @@ function listRunningDetachedJobs(worktreePath) {
|
|
|
2994
3106
|
const running = [];
|
|
2995
3107
|
for (const id of ids) {
|
|
2996
3108
|
const dir = resolveJobDir(root, id);
|
|
2997
|
-
const pid = readIntFile(
|
|
3109
|
+
const pid = readIntFile(join12(dir, "pid"));
|
|
2998
3110
|
if (jobTreeAlive(pid)) running.push(id);
|
|
2999
3111
|
}
|
|
3000
3112
|
return running.sort();
|
|
@@ -3007,6 +3119,7 @@ function looksLikeDeferredDonePromise(text) {
|
|
|
3007
3119
|
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);
|
|
3008
3120
|
}
|
|
3009
3121
|
function isJobContinuePrompt(text) {
|
|
3122
|
+
if (typeof text !== "string") return false;
|
|
3010
3123
|
const t = text.trim();
|
|
3011
3124
|
return t.startsWith("Detached job still running:") || t.startsWith("You ended the turn after promising to report later");
|
|
3012
3125
|
}
|
|
@@ -3097,15 +3210,15 @@ function takeDelta(logFile, cursorFile) {
|
|
|
3097
3210
|
return { delta: capJobLogDelta(lines.slice(start).join("\n")), nextCursor: lines.length };
|
|
3098
3211
|
}
|
|
3099
3212
|
function snapshotJob(dir) {
|
|
3100
|
-
const pid = readIntFile(
|
|
3213
|
+
const pid = readIntFile(join12(dir, "pid"));
|
|
3101
3214
|
const running = jobTreeAlive(pid);
|
|
3102
3215
|
return {
|
|
3103
3216
|
pid,
|
|
3104
3217
|
running,
|
|
3105
|
-
exitCode: readIntFile(
|
|
3106
|
-
log:
|
|
3107
|
-
cursor:
|
|
3108
|
-
progress: tailProgress(
|
|
3218
|
+
exitCode: readIntFile(join12(dir, "exit")),
|
|
3219
|
+
log: join12(dir, "log"),
|
|
3220
|
+
cursor: join12(dir, "present.cursor"),
|
|
3221
|
+
progress: tailProgress(join12(dir, "log"))
|
|
3109
3222
|
};
|
|
3110
3223
|
}
|
|
3111
3224
|
function toResult(id, snap, extra) {
|
|
@@ -3193,7 +3306,7 @@ function appendJobLog(logFile, line) {
|
|
|
3193
3306
|
mkdirSync4(dirname3(logFile), { recursive: true });
|
|
3194
3307
|
const body = line.endsWith("\n") ? line : `${line}
|
|
3195
3308
|
`;
|
|
3196
|
-
|
|
3309
|
+
appendFileSync2(logFile, body);
|
|
3197
3310
|
} catch {
|
|
3198
3311
|
}
|
|
3199
3312
|
}
|
|
@@ -3239,7 +3352,7 @@ async function stopDetachedJob(cwd, id, opts) {
|
|
|
3239
3352
|
killProcessTree(targetPid, "SIGKILL");
|
|
3240
3353
|
await sleep(100);
|
|
3241
3354
|
}
|
|
3242
|
-
const exitFile =
|
|
3355
|
+
const exitFile = join12(dir, "exit");
|
|
3243
3356
|
if (!existsSync9(exitFile)) {
|
|
3244
3357
|
try {
|
|
3245
3358
|
writeFileSync4(exitFile, "1\n");
|
|
@@ -3905,7 +4018,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
3905
4018
|
});
|
|
3906
4019
|
await requireAgent(resolved.agent);
|
|
3907
4020
|
if (input.cowboy) {
|
|
3908
|
-
const { cowboyModeEnabled } = await import("./app-settings-
|
|
4021
|
+
const { cowboyModeEnabled } = await import("./app-settings-V2BBCX2H.js");
|
|
3909
4022
|
if (!cowboyModeEnabled()) {
|
|
3910
4023
|
throw new Error(
|
|
3911
4024
|
"Cowboy mode is off. Enable it in Settings \u2192 Advanced."
|
|
@@ -3963,7 +4076,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
3963
4076
|
let sourceIsFork = false;
|
|
3964
4077
|
if (!input.cowboy && sourceType === "branch" && (!sourceRef || sourceRef === "HEAD" || sourceRef === "default")) {
|
|
3965
4078
|
if (isAbleTimeConnected() && getIssueSource() === "abletime") {
|
|
3966
|
-
const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-
|
|
4079
|
+
const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-D6773P33.js");
|
|
3967
4080
|
const task = await ensureAbleTimeTask({
|
|
3968
4081
|
title: title?.trim() || "Untitled work",
|
|
3969
4082
|
description: input.prompt?.trim() || void 0
|
|
@@ -4065,7 +4178,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
4065
4178
|
return readThread(thread.id) ?? thread;
|
|
4066
4179
|
}
|
|
4067
4180
|
async function listLinearIssues(agent, repoPath) {
|
|
4068
|
-
const { getAdapter: getAdapter2 } = await import("./agents-
|
|
4181
|
+
const { getAdapter: getAdapter2 } = await import("./agents-YABJUV3V.js");
|
|
4069
4182
|
await requireAgent(agent, { requireLinear: true });
|
|
4070
4183
|
const adapter = getAdapter2(agent);
|
|
4071
4184
|
if (!adapter.listLinearIssues) {
|
|
@@ -4451,19 +4564,19 @@ import {
|
|
|
4451
4564
|
rmSync
|
|
4452
4565
|
} from "fs";
|
|
4453
4566
|
import { tmpdir } from "os";
|
|
4454
|
-
import { join as
|
|
4567
|
+
import { join as join13 } from "path";
|
|
4455
4568
|
import { createRequire } from "module";
|
|
4456
|
-
var CONDUCTOR_APP_SUPPORT =
|
|
4569
|
+
var CONDUCTOR_APP_SUPPORT = join13(
|
|
4457
4570
|
process.env.HOME ?? "",
|
|
4458
4571
|
"Library",
|
|
4459
4572
|
"Application Support",
|
|
4460
4573
|
"com.conductor.app"
|
|
4461
4574
|
);
|
|
4462
|
-
var CONDUCTOR_DB =
|
|
4463
|
-
var CURSOR_SDK_STORE =
|
|
4575
|
+
var CONDUCTOR_DB = join13(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
4576
|
+
var CURSOR_SDK_STORE = join13(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
4464
4577
|
function thisModuleFile() {
|
|
4465
4578
|
const cjsFile = typeof __filename !== "undefined" ? __filename : "";
|
|
4466
|
-
return cjsFile || process.argv[1] ||
|
|
4579
|
+
return cjsFile || process.argv[1] || join13(process.cwd(), "package.json");
|
|
4467
4580
|
}
|
|
4468
4581
|
function openReadonlySqlite(file) {
|
|
4469
4582
|
const req = createRequire(thisModuleFile());
|
|
@@ -4491,7 +4604,7 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
4491
4604
|
return null;
|
|
4492
4605
|
}
|
|
4493
4606
|
for (const hash of hashes) {
|
|
4494
|
-
const agentsFile =
|
|
4607
|
+
const agentsFile = join13(CURSOR_SDK_STORE, hash, "agents.ndjson");
|
|
4495
4608
|
if (!existsSync12(agentsFile)) continue;
|
|
4496
4609
|
let text;
|
|
4497
4610
|
try {
|
|
@@ -4523,7 +4636,7 @@ async function adoptThread(input) {
|
|
|
4523
4636
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
4524
4637
|
}
|
|
4525
4638
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
4526
|
-
const { stdout: branch } = await import("./run-
|
|
4639
|
+
const { stdout: branch } = await import("./run-UEQM4JMZ.js").then(
|
|
4527
4640
|
({ git: git2 }) => git2(["rev-parse", "--abbrev-ref", "HEAD"], input.worktreePath)
|
|
4528
4641
|
);
|
|
4529
4642
|
const thread = createEmptyThread({
|
|
@@ -4538,9 +4651,9 @@ async function adoptThread(input) {
|
|
|
4538
4651
|
messages: input.messages ?? []
|
|
4539
4652
|
});
|
|
4540
4653
|
writeThread(thread);
|
|
4541
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
4654
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-BCBBMMXB.js");
|
|
4542
4655
|
await ensureWorkspace2(repoPath);
|
|
4543
|
-
const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-
|
|
4656
|
+
const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-L32WEBX6.js");
|
|
4544
4657
|
await ensureWorktreeSideboardIgnored2(input.worktreePath);
|
|
4545
4658
|
return thread;
|
|
4546
4659
|
}
|
|
@@ -4551,8 +4664,8 @@ function listConductorWorkspaces() {
|
|
|
4551
4664
|
if (!existsSync12(CONDUCTOR_DB)) {
|
|
4552
4665
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
4553
4666
|
}
|
|
4554
|
-
const tmp = mkdtempSync(
|
|
4555
|
-
const snapshot =
|
|
4667
|
+
const tmp = mkdtempSync(join13(tmpdir(), "sideboard-conductor-"));
|
|
4668
|
+
const snapshot = join13(tmp, "conductor.db");
|
|
4556
4669
|
try {
|
|
4557
4670
|
copyFileSync2(CONDUCTOR_DB, snapshot);
|
|
4558
4671
|
for (const suffix of ["-wal", "-shm"]) {
|
|
@@ -4642,8 +4755,8 @@ function importConductorWorkspace(workspaceId) {
|
|
|
4642
4755
|
if (!existsSync12(CONDUCTOR_DB)) {
|
|
4643
4756
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
4644
4757
|
}
|
|
4645
|
-
const tmp = mkdtempSync(
|
|
4646
|
-
const snapshot =
|
|
4758
|
+
const tmp = mkdtempSync(join13(tmpdir(), "sideboard-conductor-"));
|
|
4759
|
+
const snapshot = join13(tmp, "conductor.db");
|
|
4647
4760
|
try {
|
|
4648
4761
|
copyFileSync2(CONDUCTOR_DB, snapshot);
|
|
4649
4762
|
for (const suffix of ["-wal", "-shm"]) {
|
|
@@ -5034,7 +5147,7 @@ function stackAgentDefaultsFrom(input) {
|
|
|
5034
5147
|
|
|
5035
5148
|
// src/diff/diff.ts
|
|
5036
5149
|
import { existsSync as existsSync14, mkdirSync as mkdirSync5, readFileSync as readFileSync10, statSync as statSync2, writeFileSync as writeFileSync6 } from "fs";
|
|
5037
|
-
import { dirname as dirname4, join as
|
|
5150
|
+
import { dirname as dirname4, join as join14 } from "path";
|
|
5038
5151
|
async function inspectGitWorktree(worktreePath) {
|
|
5039
5152
|
if (!worktreePath || !existsSync14(worktreePath)) return "missing_worktree";
|
|
5040
5153
|
const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
|
|
@@ -5180,7 +5293,7 @@ new file mode 100644
|
|
|
5180
5293
|
};
|
|
5181
5294
|
}
|
|
5182
5295
|
async function untrackedPatch(worktreePath, path, maxHunk) {
|
|
5183
|
-
const abs =
|
|
5296
|
+
const abs = join14(worktreePath, path);
|
|
5184
5297
|
try {
|
|
5185
5298
|
const st = statSync2(abs);
|
|
5186
5299
|
if (st.isFile() && st.size > maxHunk) {
|
|
@@ -5650,6 +5763,15 @@ async function getDiff(worktreePath, repoPath, opts) {
|
|
|
5650
5763
|
mergeBase: needsMergeBase ? mergeBase : null
|
|
5651
5764
|
};
|
|
5652
5765
|
}
|
|
5766
|
+
function statWorktreePath(worktreePath, relativePath) {
|
|
5767
|
+
assertSafeRelativePath(relativePath);
|
|
5768
|
+
const abs = join14(worktreePath, relativePath);
|
|
5769
|
+
if (!existsSync14(abs)) return "missing";
|
|
5770
|
+
const st = statSync2(abs);
|
|
5771
|
+
if (st.isDirectory()) return "dir";
|
|
5772
|
+
if (st.isFile()) return "file";
|
|
5773
|
+
return "missing";
|
|
5774
|
+
}
|
|
5653
5775
|
async function listWorktreeFiles(worktreePath, opts) {
|
|
5654
5776
|
const maxFiles = opts?.maxFiles ?? 5e3;
|
|
5655
5777
|
const tracked = await git(["ls-files", "-z"], worktreePath, { reject: false });
|
|
@@ -5685,7 +5807,7 @@ var DEFAULT_UPLOAD_MAX_BYTES = 5e7;
|
|
|
5685
5807
|
function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
5686
5808
|
assertSafeRelativePath(relativePath);
|
|
5687
5809
|
const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
|
|
5688
|
-
const abs =
|
|
5810
|
+
const abs = join14(worktreePath, relativePath);
|
|
5689
5811
|
const st = statSync2(abs);
|
|
5690
5812
|
if (!st.isFile()) {
|
|
5691
5813
|
throw new Error(`Not a file: ${relativePath}`);
|
|
@@ -5705,7 +5827,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
5705
5827
|
function readWorktreeFile(worktreePath, relativePath, opts) {
|
|
5706
5828
|
assertSafeRelativePath(relativePath);
|
|
5707
5829
|
const maxBytes = opts?.maxBytes ?? 2e5;
|
|
5708
|
-
const abs =
|
|
5830
|
+
const abs = join14(worktreePath, relativePath);
|
|
5709
5831
|
const st = statSync2(abs);
|
|
5710
5832
|
if (!st.isFile()) {
|
|
5711
5833
|
throw new Error(`Not a file: ${relativePath}`);
|
|
@@ -5753,7 +5875,7 @@ function assertSafeRelativePath(relativePath) {
|
|
|
5753
5875
|
}
|
|
5754
5876
|
function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
5755
5877
|
assertSafeRelativePath(relativePath);
|
|
5756
|
-
const abs =
|
|
5878
|
+
const abs = join14(worktreePath, relativePath);
|
|
5757
5879
|
mkdirSync5(dirname4(abs), { recursive: true });
|
|
5758
5880
|
writeFileSync6(abs, content, "utf8");
|
|
5759
5881
|
return { path: relativePath };
|
|
@@ -5947,7 +6069,7 @@ async function confirmLand(thread, opts) {
|
|
|
5947
6069
|
if (preview.dirty) {
|
|
5948
6070
|
committed = await commitAll(thread.worktreePath, meta.commitMessage);
|
|
5949
6071
|
}
|
|
5950
|
-
const { git: git2 } = await import("./run-
|
|
6072
|
+
const { git: git2 } = await import("./run-UEQM4JMZ.js");
|
|
5951
6073
|
const { stdout: headOut } = await git2(
|
|
5952
6074
|
["rev-parse", "--abbrev-ref", "HEAD"],
|
|
5953
6075
|
thread.worktreePath,
|
|
@@ -5979,7 +6101,7 @@ async function confirmLand(thread, opts) {
|
|
|
5979
6101
|
// src/skills/discover.ts
|
|
5980
6102
|
import { existsSync as existsSync15, readdirSync as readdirSync5, readFileSync as readFileSync11, statSync as statSync3 } from "fs";
|
|
5981
6103
|
import { homedir } from "os";
|
|
5982
|
-
import { join as
|
|
6104
|
+
import { join as join15 } from "path";
|
|
5983
6105
|
|
|
5984
6106
|
// src/skills/bundled/long-running.ts
|
|
5985
6107
|
var LONG_RUNNING_SKILL_COMMAND = "long-running";
|
|
@@ -6144,7 +6266,7 @@ function scanSkillsDir(dir, source, out) {
|
|
|
6144
6266
|
}
|
|
6145
6267
|
for (const entry of entries) {
|
|
6146
6268
|
if (entry.startsWith(".")) continue;
|
|
6147
|
-
const skillMd =
|
|
6269
|
+
const skillMd = join15(dir, entry, "SKILL.md");
|
|
6148
6270
|
if (!existsSync15(skillMd)) continue;
|
|
6149
6271
|
try {
|
|
6150
6272
|
if (!statSync3(skillMd).isFile()) continue;
|
|
@@ -6166,12 +6288,12 @@ function scanClaudePluginSkills(pluginsRoot, out) {
|
|
|
6166
6288
|
return;
|
|
6167
6289
|
}
|
|
6168
6290
|
if (lookingForSkillsDir && entries.includes("SKILL.md")) {
|
|
6169
|
-
const skill = readSkill(
|
|
6291
|
+
const skill = readSkill(join15(dir, "SKILL.md"), "cli");
|
|
6170
6292
|
if (skill) out.push(skill);
|
|
6171
6293
|
}
|
|
6172
6294
|
for (const entry of entries) {
|
|
6173
6295
|
if (entry === "node_modules" || entry === ".git") continue;
|
|
6174
|
-
const full =
|
|
6296
|
+
const full = join15(dir, entry);
|
|
6175
6297
|
try {
|
|
6176
6298
|
if (!statSync3(full).isDirectory()) continue;
|
|
6177
6299
|
} catch {
|
|
@@ -6191,17 +6313,17 @@ function discoverSkills(worktreePath) {
|
|
|
6191
6313
|
const home = homedir();
|
|
6192
6314
|
const collected = [];
|
|
6193
6315
|
for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
|
|
6194
|
-
scanSkillsDir(
|
|
6316
|
+
scanSkillsDir(join15(worktreePath, rel), "workspace", collected);
|
|
6195
6317
|
}
|
|
6196
6318
|
for (const abs of [
|
|
6197
|
-
|
|
6198
|
-
|
|
6199
|
-
|
|
6200
|
-
|
|
6319
|
+
join15(home, ".claude/skills"),
|
|
6320
|
+
join15(home, ".cursor/skills"),
|
|
6321
|
+
join15(home, ".sideboard/skills"),
|
|
6322
|
+
join15(home, ".brightsy/skills")
|
|
6201
6323
|
]) {
|
|
6202
6324
|
scanSkillsDir(abs, "user", collected);
|
|
6203
6325
|
}
|
|
6204
|
-
scanClaudePluginSkills(
|
|
6326
|
+
scanClaudePluginSkills(join15(home, ".claude/plugins"), collected);
|
|
6205
6327
|
collected.push(...bundledSkills());
|
|
6206
6328
|
const rank = {
|
|
6207
6329
|
workspace: 0,
|
|
@@ -6373,16 +6495,28 @@ function shiftQueuedItem(queue, queueAttachments) {
|
|
|
6373
6495
|
|
|
6374
6496
|
// src/agents/instructions.ts
|
|
6375
6497
|
import { existsSync as existsSync17 } from "fs";
|
|
6376
|
-
import { join as
|
|
6498
|
+
import { join as join17 } from "path";
|
|
6377
6499
|
|
|
6378
6500
|
// src/skills/detached-job-path.ts
|
|
6379
6501
|
import { existsSync as existsSync16 } from "fs";
|
|
6380
|
-
import { dirname as dirname5, join as
|
|
6502
|
+
import { dirname as dirname5, join as join16 } from "path";
|
|
6381
6503
|
import { fileURLToPath } from "url";
|
|
6382
6504
|
var DETACHED_JOB_FILENAMES = ["detached-job.cjs", "detached-job.js"];
|
|
6505
|
+
function compiledModuleDir() {
|
|
6506
|
+
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
6507
|
+
if (cjsDir) return cjsDir;
|
|
6508
|
+
try {
|
|
6509
|
+
const url = import.meta.url;
|
|
6510
|
+
if (typeof url === "string" && url.length > 0) {
|
|
6511
|
+
return dirname5(fileURLToPath(url));
|
|
6512
|
+
}
|
|
6513
|
+
} catch {
|
|
6514
|
+
}
|
|
6515
|
+
return null;
|
|
6516
|
+
}
|
|
6383
6517
|
function detachedJobScriptIn(dir) {
|
|
6384
6518
|
for (const name of DETACHED_JOB_FILENAMES) {
|
|
6385
|
-
const script =
|
|
6519
|
+
const script = join16(dir, "scripts", name);
|
|
6386
6520
|
if (existsSync16(script)) return script;
|
|
6387
6521
|
}
|
|
6388
6522
|
return null;
|
|
@@ -6395,7 +6529,8 @@ function packagedDetachedJobPath() {
|
|
|
6395
6529
|
function resolveDetachedJobScript() {
|
|
6396
6530
|
const packaged = packagedDetachedJobPath();
|
|
6397
6531
|
if (packaged) return packaged;
|
|
6398
|
-
let dir =
|
|
6532
|
+
let dir = compiledModuleDir();
|
|
6533
|
+
if (!dir) return null;
|
|
6399
6534
|
for (let i = 0; i < 8; i++) {
|
|
6400
6535
|
const candidate = detachedJobScriptIn(dir);
|
|
6401
6536
|
if (candidate) return candidate;
|
|
@@ -6588,9 +6723,9 @@ function formatPrGateDirective() {
|
|
|
6588
6723
|
}
|
|
6589
6724
|
function formatProcessGuideDirective(opts) {
|
|
6590
6725
|
const worktree = opts?.worktreePath?.trim();
|
|
6591
|
-
const hasGraphSkill = !!worktree && existsSync17(
|
|
6592
|
-
const hasReviewSkill = !!worktree && existsSync17(
|
|
6593
|
-
const hasInstallSkill = !!worktree && existsSync17(
|
|
6726
|
+
const hasGraphSkill = !!worktree && existsSync17(join17(worktree, ".claude/skills/graph-engineering/SKILL.md"));
|
|
6727
|
+
const hasReviewSkill = !!worktree && existsSync17(join17(worktree, ".claude/skills/review/SKILL.md"));
|
|
6728
|
+
const hasInstallSkill = !!worktree && existsSync17(join17(worktree, ".claude/skills/worktree-install/SKILL.md"));
|
|
6594
6729
|
return [
|
|
6595
6730
|
"Process guides (recurring work only):",
|
|
6596
6731
|
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,
|
|
@@ -6953,7 +7088,7 @@ async function syncThreadBranchFromGit(threadId) {
|
|
|
6953
7088
|
// src/store/schedules.ts
|
|
6954
7089
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
6955
7090
|
import { existsSync as existsSync18, readFileSync as readFileSync12 } from "fs";
|
|
6956
|
-
import { join as
|
|
7091
|
+
import { join as join18 } from "path";
|
|
6957
7092
|
import { Cron } from "croner";
|
|
6958
7093
|
var DURATION_RE = /^(\d+)(s|m|h|d)$/i;
|
|
6959
7094
|
var UNIT_MS = {
|
|
@@ -6963,7 +7098,7 @@ var UNIT_MS = {
|
|
|
6963
7098
|
d: 864e5
|
|
6964
7099
|
};
|
|
6965
7100
|
function schedulesPath() {
|
|
6966
|
-
return
|
|
7101
|
+
return join18(appDataDir(), "schedules.json");
|
|
6967
7102
|
}
|
|
6968
7103
|
function parseDurationMs(every) {
|
|
6969
7104
|
const m = every.trim().match(DURATION_RE);
|
|
@@ -7197,7 +7332,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
7197
7332
|
${prompt}`;
|
|
7198
7333
|
}
|
|
7199
7334
|
async function defaultDeps() {
|
|
7200
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
7335
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-HKW3VLGX.js");
|
|
7201
7336
|
const orch = getOrchestrator2();
|
|
7202
7337
|
return {
|
|
7203
7338
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -7499,7 +7634,7 @@ var Orchestrator = class {
|
|
|
7499
7634
|
orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
|
|
7500
7635
|
});
|
|
7501
7636
|
}
|
|
7502
|
-
const { autoCleanupOrphansEnabled } = await import("./app-settings-
|
|
7637
|
+
const { autoCleanupOrphansEnabled } = await import("./app-settings-V2BBCX2H.js");
|
|
7503
7638
|
if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
|
|
7504
7639
|
await cleanupOrphanWorktrees({ repoPaths });
|
|
7505
7640
|
}
|
|
@@ -7531,7 +7666,7 @@ var Orchestrator = class {
|
|
|
7531
7666
|
}
|
|
7532
7667
|
if (thread.queue.length > 0) {
|
|
7533
7668
|
this.haltDrain.delete(thread.id);
|
|
7534
|
-
|
|
7669
|
+
this.armDrain(thread.id);
|
|
7535
7670
|
}
|
|
7536
7671
|
}
|
|
7537
7672
|
}
|
|
@@ -7786,7 +7921,7 @@ var Orchestrator = class {
|
|
|
7786
7921
|
}
|
|
7787
7922
|
await setup;
|
|
7788
7923
|
if (skipSetup) return;
|
|
7789
|
-
const { autoRunAfterSetupEnabled } = await import("./app-settings-
|
|
7924
|
+
const { autoRunAfterSetupEnabled } = await import("./app-settings-V2BBCX2H.js");
|
|
7790
7925
|
if (autoRunAfterSetupEnabled()) {
|
|
7791
7926
|
try {
|
|
7792
7927
|
await this.startDev(threadId);
|
|
@@ -7867,7 +8002,7 @@ var Orchestrator = class {
|
|
|
7867
8002
|
this.emit({ type: "status_changed", threadId: thread.id, status: "queued" });
|
|
7868
8003
|
}
|
|
7869
8004
|
if (thisProcessShouldDrainAgentQueues() && !shouldSteer) {
|
|
7870
|
-
|
|
8005
|
+
this.armDrain(thread.id);
|
|
7871
8006
|
}
|
|
7872
8007
|
return this.requireThread(thread.id);
|
|
7873
8008
|
});
|
|
@@ -7947,9 +8082,15 @@ var Orchestrator = class {
|
|
|
7947
8082
|
if (inFlight || foreignLive) {
|
|
7948
8083
|
this.stop(thread.id, { clearQueue: false, continueQueue: true });
|
|
7949
8084
|
}
|
|
7950
|
-
|
|
8085
|
+
this.armDrain(thread.id);
|
|
7951
8086
|
return this.requireThread(thread.id);
|
|
7952
8087
|
}
|
|
8088
|
+
armDrain(threadId) {
|
|
8089
|
+
void this.drainQueue(threadId).catch((err) => {
|
|
8090
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
8091
|
+
console.error(`[sideboard] drainQueue ${threadId}: ${detail}`);
|
|
8092
|
+
});
|
|
8093
|
+
}
|
|
7953
8094
|
async drainQueue(threadId) {
|
|
7954
8095
|
if (this.draining.has(threadId)) return;
|
|
7955
8096
|
this.draining.add(threadId);
|
|
@@ -8021,196 +8162,205 @@ var Orchestrator = class {
|
|
|
8021
8162
|
this.emit({ type: "status_changed", threadId, status: "running" });
|
|
8022
8163
|
this.emit({ type: "turn_started", threadId, prompt });
|
|
8023
8164
|
try {
|
|
8024
|
-
|
|
8025
|
-
|
|
8026
|
-
|
|
8027
|
-
|
|
8028
|
-
try {
|
|
8029
|
-
const compact = await maybeCompactContext(thread);
|
|
8030
|
-
if (compact.didCompact) {
|
|
8031
|
-
thread = updateThread(threadId, {
|
|
8032
|
-
messages: compact.thread.messages,
|
|
8033
|
-
sessionId: compact.thread.sessionId
|
|
8034
|
-
});
|
|
8035
|
-
this.emit({
|
|
8036
|
-
type: "context_compacted",
|
|
8037
|
-
threadId,
|
|
8038
|
-
olderCount: compact.olderCount ?? 0,
|
|
8039
|
-
method: compact.method ?? "extractive"
|
|
8040
|
-
});
|
|
8165
|
+
try {
|
|
8166
|
+
const baseline = await captureTurnBaseline(thread.worktreePath);
|
|
8167
|
+
if (baseline) this.turnBaselines.set(threadId, baseline);
|
|
8168
|
+
} catch {
|
|
8041
8169
|
}
|
|
8042
|
-
|
|
8043
|
-
|
|
8044
|
-
|
|
8045
|
-
|
|
8046
|
-
|
|
8047
|
-
|
|
8048
|
-
|
|
8049
|
-
|
|
8050
|
-
|
|
8051
|
-
|
|
8052
|
-
|
|
8053
|
-
|
|
8054
|
-
|
|
8055
|
-
|
|
8056
|
-
|
|
8057
|
-
|
|
8058
|
-
|
|
8059
|
-
|
|
8060
|
-
thread.worktreePath,
|
|
8061
|
-
gitPrompt,
|
|
8062
|
-
{
|
|
8063
|
-
attachments: autoContinue ? [] : sentAttachments ?? []
|
|
8170
|
+
try {
|
|
8171
|
+
const compact = await maybeCompactContext(thread);
|
|
8172
|
+
if (compact.didCompact) {
|
|
8173
|
+
thread = updateThread(threadId, {
|
|
8174
|
+
messages: compact.thread.messages,
|
|
8175
|
+
sessionId: compact.thread.sessionId
|
|
8176
|
+
});
|
|
8177
|
+
this.emit({
|
|
8178
|
+
type: "context_compacted",
|
|
8179
|
+
threadId,
|
|
8180
|
+
olderCount: compact.olderCount ?? 0,
|
|
8181
|
+
method: compact.method ?? "extractive"
|
|
8182
|
+
});
|
|
8183
|
+
}
|
|
8184
|
+
} catch (err) {
|
|
8185
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
8186
|
+
this.emit({ type: "error", threadId, message: `context compact failed: ${message}` });
|
|
8187
|
+
thread = this.requireThread(threadId);
|
|
8064
8188
|
}
|
|
8065
|
-
|
|
8066
|
-
|
|
8067
|
-
|
|
8068
|
-
|
|
8069
|
-
|
|
8070
|
-
|
|
8071
|
-
|
|
8072
|
-
|
|
8073
|
-
|
|
8074
|
-
|
|
8075
|
-
|
|
8076
|
-
|
|
8077
|
-
|
|
8078
|
-
|
|
8079
|
-
|
|
8080
|
-
|
|
8081
|
-
|
|
8082
|
-
|
|
8083
|
-
|
|
8084
|
-
|
|
8085
|
-
|
|
8086
|
-
|
|
8087
|
-
|
|
8088
|
-
|
|
8089
|
-
ticketProvider: issueTicket?.provider
|
|
8090
|
-
}) : null;
|
|
8091
|
-
const viewerContextReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatViewerContextReminder() : null;
|
|
8092
|
-
const reviewWriteGateReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) && isReviewWriteGatedThread(
|
|
8093
|
-
thread,
|
|
8094
|
-
thread.worktreePath ? threadsSharingWorktree(thread.worktreePath) : []
|
|
8095
|
-
) ? formatReviewWriteGateReminder() : null;
|
|
8096
|
-
const slackReplyContext = formatSlackRepliesForTurn(
|
|
8097
|
-
pendingSlackExternalReplies(thread.messages)
|
|
8098
|
-
);
|
|
8099
|
-
const turnReminders = [
|
|
8100
|
-
worktreeReminder,
|
|
8101
|
-
optionalServicesReminder,
|
|
8102
|
-
issueToolsReminder,
|
|
8103
|
-
reviewWriteGateReminder,
|
|
8104
|
-
viewerContextReminder,
|
|
8105
|
-
artifactReminder,
|
|
8106
|
-
longRunningReminder
|
|
8107
|
-
].filter(Boolean).join("\n\n") || void 0;
|
|
8108
|
-
const prGateDirective = thread.agent !== "brightsy" && !isOrchestratorThread(thread) && mentionsPrGoal(prompt) ? formatPrGateDirective() : null;
|
|
8109
|
-
const agentPrompt = [
|
|
8110
|
-
thread.planMode ? PLAN_MODE_INSTRUCTION : null,
|
|
8111
|
-
orchestrationReminder,
|
|
8112
|
-
prGateDirective,
|
|
8113
|
-
slackReplyContext,
|
|
8114
|
-
expandedPrompt
|
|
8115
|
-
].filter(Boolean).join("\n\n");
|
|
8116
|
-
if (!autoContinue && sentAttachments) {
|
|
8117
|
-
updateThread(threadId, { pendingTurnAttachments: [] });
|
|
8118
|
-
}
|
|
8119
|
-
const adapter = getAdapter(thread.agent);
|
|
8120
|
-
const resolved = await adapter.resolveSessionId(thread.worktreePath, thread.sessionId);
|
|
8121
|
-
if (resolved && resolved !== thread.sessionId) {
|
|
8122
|
-
updateThread(threadId, { sessionId: resolved });
|
|
8123
|
-
}
|
|
8124
|
-
const fresh = this.requireThread(threadId);
|
|
8125
|
-
if (!fresh.worktreePath?.trim()) {
|
|
8126
|
-
throw new Error(
|
|
8127
|
-
`Thread ${threadId} has no worktreePath \u2014 refusing to start an agent outside an isolated worktree`
|
|
8189
|
+
const promptText = typeof prompt === "string" ? prompt : "";
|
|
8190
|
+
const autoContinue = isJobContinuePrompt(promptText) || promptText.startsWith("The previous agent process ended before it finished.");
|
|
8191
|
+
const parked = takePendingTurnAttachments(thread);
|
|
8192
|
+
const sentAttachments = !autoContinue && parked.length > 0 ? parked : void 0;
|
|
8193
|
+
appendMessage(threadId, {
|
|
8194
|
+
role: "user",
|
|
8195
|
+
text: promptText,
|
|
8196
|
+
...sentAttachments ? { attachments: sentAttachments } : {},
|
|
8197
|
+
...autoContinue ? { origin: "continue" } : {},
|
|
8198
|
+
ts: (/* @__PURE__ */ new Date()).toISOString()
|
|
8199
|
+
});
|
|
8200
|
+
traceTurn("runTurn.afterUserMessage", {
|
|
8201
|
+
threadId,
|
|
8202
|
+
agent: thread.agent,
|
|
8203
|
+
orch: isOrchestratorThread(thread)
|
|
8204
|
+
});
|
|
8205
|
+
thread = this.requireThread(threadId);
|
|
8206
|
+
const gitPrompt = expandCanonicalGitRequest(promptText);
|
|
8207
|
+
const { agentPrompt: expandedPrompt } = expandComposerPrompt(
|
|
8208
|
+
thread.worktreePath,
|
|
8209
|
+
gitPrompt,
|
|
8210
|
+
{
|
|
8211
|
+
attachments: autoContinue ? [] : sentAttachments ?? []
|
|
8212
|
+
}
|
|
8128
8213
|
);
|
|
8129
|
-
|
|
8130
|
-
|
|
8131
|
-
|
|
8132
|
-
|
|
8133
|
-
|
|
8134
|
-
|
|
8135
|
-
|
|
8136
|
-
|
|
8137
|
-
|
|
8138
|
-
|
|
8139
|
-
|
|
8140
|
-
|
|
8141
|
-
|
|
8142
|
-
|
|
8143
|
-
|
|
8144
|
-
|
|
8145
|
-
|
|
8146
|
-
|
|
8147
|
-
|
|
8148
|
-
|
|
8149
|
-
|
|
8150
|
-
|
|
8151
|
-
|
|
8152
|
-
|
|
8153
|
-
|
|
8154
|
-
|
|
8155
|
-
|
|
8156
|
-
|
|
8157
|
-
|
|
8158
|
-
|
|
8159
|
-
|
|
8160
|
-
)
|
|
8161
|
-
|
|
8162
|
-
|
|
8163
|
-
|
|
8214
|
+
const slackInbound = /^(Slack DM|Slack @mention)(?:\n|$)/.test(
|
|
8215
|
+
expandedPrompt.trim()
|
|
8216
|
+
);
|
|
8217
|
+
const orchestrationReminder = isOrchestratorThread(thread) ? [
|
|
8218
|
+
coordinatorTurnReminder({
|
|
8219
|
+
parentId: threadId,
|
|
8220
|
+
goal: thread.sourceRef || thread.title
|
|
8221
|
+
}),
|
|
8222
|
+
slackInbound ? [
|
|
8223
|
+
"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.",
|
|
8224
|
+
SLACK_REPLY_FORMATTING
|
|
8225
|
+
].join("\n") : null
|
|
8226
|
+
].filter(Boolean).join("\n") : null;
|
|
8227
|
+
const artifactReminder = thread.agent !== "brightsy" ? formatUiReminder() : null;
|
|
8228
|
+
const longRunningReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatLongRunningReminder() : null;
|
|
8229
|
+
const worktreeReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatWorktreeReminder() : null;
|
|
8230
|
+
const optionalServicesReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatOptionalServicesReminder(loadAppSettings().integrations) : null;
|
|
8231
|
+
const issueTicket = issueTicketFromThread(thread, resolveEffectiveIssueSource());
|
|
8232
|
+
const issueToolsReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatIssueToolsReminder({
|
|
8233
|
+
linear: isLinearConnected(),
|
|
8234
|
+
abletime: isAbleTimeConnected(),
|
|
8235
|
+
github: true,
|
|
8236
|
+
ticketId: issueTicket?.id,
|
|
8237
|
+
ticketProvider: issueTicket?.provider
|
|
8238
|
+
}) : null;
|
|
8239
|
+
const viewerContextReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatViewerContextReminder() : null;
|
|
8240
|
+
const reviewWriteGateReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) && isReviewWriteGatedThread(
|
|
8241
|
+
thread,
|
|
8242
|
+
thread.worktreePath ? threadsSharingWorktree(thread.worktreePath) : []
|
|
8243
|
+
) ? formatReviewWriteGateReminder() : null;
|
|
8244
|
+
const slackReplyContext = formatSlackRepliesForTurn(
|
|
8245
|
+
pendingSlackExternalReplies(thread.messages)
|
|
8246
|
+
);
|
|
8247
|
+
const turnReminders = [
|
|
8248
|
+
worktreeReminder,
|
|
8249
|
+
optionalServicesReminder,
|
|
8250
|
+
issueToolsReminder,
|
|
8251
|
+
reviewWriteGateReminder,
|
|
8252
|
+
viewerContextReminder,
|
|
8253
|
+
artifactReminder,
|
|
8254
|
+
longRunningReminder
|
|
8255
|
+
].filter(Boolean).join("\n\n") || void 0;
|
|
8256
|
+
const prGateDirective = thread.agent !== "brightsy" && !isOrchestratorThread(thread) && mentionsPrGoal(promptText) ? formatPrGateDirective() : null;
|
|
8257
|
+
const agentPrompt = [
|
|
8258
|
+
thread.planMode ? PLAN_MODE_INSTRUCTION : null,
|
|
8259
|
+
orchestrationReminder,
|
|
8260
|
+
prGateDirective,
|
|
8261
|
+
slackReplyContext,
|
|
8262
|
+
expandedPrompt
|
|
8263
|
+
].filter(Boolean).join("\n\n");
|
|
8264
|
+
if (!autoContinue && sentAttachments) {
|
|
8265
|
+
updateThread(threadId, { pendingTurnAttachments: [] });
|
|
8266
|
+
}
|
|
8267
|
+
const adapter = getAdapter(thread.agent);
|
|
8268
|
+
const resolved = await adapter.resolveSessionId(thread.worktreePath, thread.sessionId);
|
|
8269
|
+
if (resolved && resolved !== thread.sessionId) {
|
|
8270
|
+
updateThread(threadId, { sessionId: resolved });
|
|
8271
|
+
}
|
|
8272
|
+
const fresh = this.requireThread(threadId);
|
|
8273
|
+
if (!fresh.worktreePath?.trim()) {
|
|
8274
|
+
throw new Error(
|
|
8275
|
+
`Thread ${threadId} has no worktreePath \u2014 refusing to start an agent outside an isolated worktree`
|
|
8164
8276
|
);
|
|
8165
8277
|
}
|
|
8166
|
-
|
|
8167
|
-
|
|
8168
|
-
|
|
8169
|
-
|
|
8170
|
-
const
|
|
8171
|
-
|
|
8172
|
-
|
|
8173
|
-
|
|
8174
|
-
|
|
8175
|
-
|
|
8278
|
+
const isBrightsy = fresh.agent === "brightsy";
|
|
8279
|
+
const isOrchestration = isOrchestratorThread(fresh);
|
|
8280
|
+
const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-V2BBCX2H.js");
|
|
8281
|
+
const gitAuthMode = getGithubGitAuthMode();
|
|
8282
|
+
const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
|
|
8283
|
+
githubSlug: await withTimeout(
|
|
8284
|
+
resolveGithubRepoSlug(fresh.worktreePath),
|
|
8285
|
+
8e3,
|
|
8286
|
+
"resolveGithubRepoSlug"
|
|
8287
|
+
).catch(() => null),
|
|
8288
|
+
gitAuthMode
|
|
8176
8289
|
});
|
|
8177
|
-
|
|
8178
|
-
|
|
8179
|
-
|
|
8180
|
-
const
|
|
8181
|
-
|
|
8182
|
-
|
|
8183
|
-
|
|
8184
|
-
|
|
8185
|
-
|
|
8186
|
-
|
|
8290
|
+
const artifactDirective = isBrightsy ? null : formatArtifactDirective();
|
|
8291
|
+
const longRunningDirective = isBrightsy || isOrchestration ? null : formatLongRunningDirective();
|
|
8292
|
+
const optionalServicesDirective = isBrightsy || isOrchestration ? null : formatOptionalServicesDirective(loadAppSettings().integrations);
|
|
8293
|
+
const freshIssueTicket = issueTicketFromThread(fresh, resolveEffectiveIssueSource());
|
|
8294
|
+
const issueToolsDirective = isBrightsy || isOrchestration ? null : formatIssueToolsDirective({
|
|
8295
|
+
linear: isLinearConnected(),
|
|
8296
|
+
abletime: isAbleTimeConnected(),
|
|
8297
|
+
github: true,
|
|
8298
|
+
ticketId: freshIssueTicket?.id,
|
|
8299
|
+
ticketProvider: freshIssueTicket?.provider
|
|
8300
|
+
});
|
|
8301
|
+
const reviewWriteGateDirective = isBrightsy || isOrchestration || !isReviewWriteGatedThread(
|
|
8302
|
+
fresh,
|
|
8303
|
+
fresh.worktreePath ? threadsSharingWorktree(fresh.worktreePath) : []
|
|
8304
|
+
) ? null : formatReviewWriteGateDirective();
|
|
8305
|
+
let viewerContextDirective = null;
|
|
8306
|
+
if (!isBrightsy && !isOrchestration) {
|
|
8307
|
+
try {
|
|
8308
|
+
viewerContextDirective = formatViewerContextDirective(
|
|
8309
|
+
resolveViewerProfileForRepo(fresh.repoPath || fresh.worktreePath)
|
|
8310
|
+
);
|
|
8311
|
+
} catch {
|
|
8312
|
+
viewerContextDirective = formatViewerContextDirective(
|
|
8313
|
+
resolveViewerProfileForRepo()
|
|
8314
|
+
);
|
|
8315
|
+
}
|
|
8187
8316
|
}
|
|
8188
|
-
|
|
8189
|
-
|
|
8190
|
-
|
|
8191
|
-
|
|
8192
|
-
|
|
8193
|
-
|
|
8194
|
-
|
|
8195
|
-
|
|
8196
|
-
)
|
|
8317
|
+
const settings = loadWorkspaceSettings(fresh.worktreePath, fresh.repoPath);
|
|
8318
|
+
let renameBranchDirective = null;
|
|
8319
|
+
if (!isBrightsy && !isOrchestration && autoRenameBranchEnabled()) {
|
|
8320
|
+
const { resolveGitBranchPrefix } = await import("./branch-prefix-N3KTCRCE.js");
|
|
8321
|
+
renameBranchDirective = formatRenameBranchDirective(fresh, {
|
|
8322
|
+
customPrompt: settings?.prompts?.renameBranch,
|
|
8323
|
+
branchPrefix: resolveGitBranchPrefix({
|
|
8324
|
+
setting: gitBranchPrefixSetting()
|
|
8325
|
+
})
|
|
8197
8326
|
});
|
|
8198
8327
|
}
|
|
8199
|
-
|
|
8200
|
-
|
|
8201
|
-
|
|
8202
|
-
|
|
8203
|
-
|
|
8204
|
-
|
|
8205
|
-
|
|
8206
|
-
|
|
8207
|
-
|
|
8208
|
-
|
|
8209
|
-
|
|
8210
|
-
|
|
8211
|
-
|
|
8212
|
-
|
|
8328
|
+
let seed = null;
|
|
8329
|
+
if (!fresh.sessionId) {
|
|
8330
|
+
const prior = fresh.messages.slice(0, -1);
|
|
8331
|
+
seed = isBrightsy ? buildBrightsySessionSeed(prior) : buildSessionSeed(prior);
|
|
8332
|
+
}
|
|
8333
|
+
let coordinatorDirective = null;
|
|
8334
|
+
if (isOrchestration) {
|
|
8335
|
+
if (isGlobalThread(fresh)) {
|
|
8336
|
+
ensureGlobalCoordinatorCwd({ orchestratorThreadId: fresh.id });
|
|
8337
|
+
}
|
|
8338
|
+
if (!fresh.sessionId) {
|
|
8339
|
+
const inventory = await enrichWorkspacesWithGithub(this.listWorkspaces());
|
|
8340
|
+
coordinatorDirective = coordinatorSystemPrompt({
|
|
8341
|
+
goal: fresh.sourceRef || fresh.title || "Orchestration",
|
|
8342
|
+
parentId: fresh.id,
|
|
8343
|
+
workspaces: inventory,
|
|
8344
|
+
audience: /^(Slack DM|Slack @mention)(?:\n|$)/.test(
|
|
8345
|
+
expandedPrompt.trim()
|
|
8346
|
+
) ? "slack" : "desktop"
|
|
8347
|
+
});
|
|
8348
|
+
}
|
|
8349
|
+
}
|
|
8350
|
+
const cachedPrefix = fresh.sessionId ? "" : [
|
|
8351
|
+
coordinatorDirective,
|
|
8352
|
+
worktreeDirective,
|
|
8353
|
+
optionalServicesDirective,
|
|
8354
|
+
issueToolsDirective,
|
|
8355
|
+
reviewWriteGateDirective,
|
|
8356
|
+
viewerContextDirective,
|
|
8357
|
+
artifactDirective,
|
|
8358
|
+
longRunningDirective,
|
|
8359
|
+
renameBranchDirective,
|
|
8360
|
+
seed
|
|
8361
|
+
].filter(Boolean).join("\n\n---\n\n");
|
|
8213
8362
|
const stderrTail = [];
|
|
8363
|
+
traceTurn("runTurn.beforeSpawn", { threadId, agent: fresh.agent });
|
|
8214
8364
|
const handle = await spawnAgentTurn(
|
|
8215
8365
|
fresh,
|
|
8216
8366
|
{
|
|
@@ -9010,6 +9160,18 @@ var Orchestrator = class {
|
|
|
9010
9160
|
const thread = this.requireThread(threadRef);
|
|
9011
9161
|
return listWorktreeFiles(thread.worktreePath);
|
|
9012
9162
|
}
|
|
9163
|
+
async statPath(threadRef, relativePath) {
|
|
9164
|
+
const thread = this.requireThread(threadRef);
|
|
9165
|
+
if (relativePath.includes("..") || relativePath.startsWith("/")) {
|
|
9166
|
+
return "missing";
|
|
9167
|
+
}
|
|
9168
|
+
if (!relativePath || relativePath === ".") return "dir";
|
|
9169
|
+
try {
|
|
9170
|
+
return statWorktreePath(thread.worktreePath, relativePath);
|
|
9171
|
+
} catch {
|
|
9172
|
+
return "missing";
|
|
9173
|
+
}
|
|
9174
|
+
}
|
|
9013
9175
|
async readFile(threadRef, relativePath) {
|
|
9014
9176
|
const thread = this.requireThread(threadRef);
|
|
9015
9177
|
if (relativePath.includes("..") || relativePath.startsWith("/")) {
|
|
@@ -9165,7 +9327,7 @@ var Orchestrator = class {
|
|
|
9165
9327
|
if (!titled.userSetTitle && meta.title && titled.title !== meta.title) {
|
|
9166
9328
|
updateThread(thread.id, { title: meta.title });
|
|
9167
9329
|
}
|
|
9168
|
-
const { autoArchiveOnMergeEnabled } = await import("./app-settings-
|
|
9330
|
+
const { autoArchiveOnMergeEnabled } = await import("./app-settings-V2BBCX2H.js");
|
|
9169
9331
|
const latest = this.requireThread(thread.id);
|
|
9170
9332
|
if (!shouldAutoArchiveOnPrMerge({
|
|
9171
9333
|
previousPrState: prevState || null,
|
|
@@ -9444,7 +9606,7 @@ var Orchestrator = class {
|
|
|
9444
9606
|
this.enforceHistoryRetention();
|
|
9445
9607
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
9446
9608
|
try {
|
|
9447
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
9609
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-BCBBMMXB.js");
|
|
9448
9610
|
await ensureWorkspace2(thread.repoPath);
|
|
9449
9611
|
} catch {
|
|
9450
9612
|
}
|
|
@@ -9471,7 +9633,7 @@ var Orchestrator = class {
|
|
|
9471
9633
|
await runArchiveScript(thread.repoPath, thread.worktreePath);
|
|
9472
9634
|
} catch {
|
|
9473
9635
|
}
|
|
9474
|
-
const { deleteBranchOnPurgeEnabled } = await import("./app-settings-
|
|
9636
|
+
const { deleteBranchOnPurgeEnabled } = await import("./app-settings-V2BBCX2H.js");
|
|
9475
9637
|
const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
|
|
9476
9638
|
await removeWorktree(thread.repoPath, thread.worktreePath, {
|
|
9477
9639
|
deleteBranch: deleteBranch ? thread.branchName : void 0
|
|
@@ -9498,13 +9660,13 @@ var Orchestrator = class {
|
|
|
9498
9660
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
9499
9661
|
);
|
|
9500
9662
|
}
|
|
9501
|
-
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-
|
|
9663
|
+
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-7V67XTEO.js");
|
|
9502
9664
|
const slug = thread.worktreePath.split("/").pop();
|
|
9503
9665
|
const dest = thread.worktreePath;
|
|
9504
9666
|
await withRepoGitLock(thread.repoPath, async () => {
|
|
9505
9667
|
await git(["worktree", "add", dest, thread.branchName], thread.repoPath);
|
|
9506
9668
|
});
|
|
9507
|
-
const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-
|
|
9669
|
+
const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-L32WEBX6.js");
|
|
9508
9670
|
await ensureWorktreeSideboardIgnored2(dest);
|
|
9509
9671
|
void createThreadWorktree2;
|
|
9510
9672
|
void slug;
|
|
@@ -9608,7 +9770,7 @@ async function startOrchestration(opts) {
|
|
|
9608
9770
|
sourceRef: "default",
|
|
9609
9771
|
...createOpts
|
|
9610
9772
|
}).catch(async () => {
|
|
9611
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
9773
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-7V67XTEO.js");
|
|
9612
9774
|
const repo = await resolveRepoRoot2(repoPath);
|
|
9613
9775
|
const def = await resolveDefaultBranch2(repo);
|
|
9614
9776
|
return orch.createThread({
|
|
@@ -9820,6 +9982,7 @@ export {
|
|
|
9820
9982
|
captureTurnBaseline,
|
|
9821
9983
|
listBranchCommits,
|
|
9822
9984
|
getDiff,
|
|
9985
|
+
statWorktreePath,
|
|
9823
9986
|
listWorktreeFiles,
|
|
9824
9987
|
readWorktreeFileForUpload,
|
|
9825
9988
|
readWorktreeFile,
|