@sideboard-ai/core 0.1.238 → 0.1.239
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/{chunk-E6UJGLPM.js → chunk-CDG4CLWQ.js} +326 -147
- package/dist/{chunk-32DG3DA2.js → chunk-D5SDZSEA.js} +337 -148
- package/dist/index.cjs +501 -295
- package/dist/index.d.cts +33 -2
- package/dist/index.d.ts +33 -2
- package/dist/index.js +22 -2
- package/dist/mcp/run-stdio.cjs +482 -296
- package/dist/mcp/run-stdio.js +2 -2
- package/dist/{orchestrator-AAYKR4AI.js → orchestrator-3ZP4WTQ4.js} +1 -1
- package/dist/{orchestrator-HPMDB2SG.js → orchestrator-R75VDUR2.js} +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -13264,10 +13264,10 @@ function eventsFromClaudeSystem(obj) {
|
|
|
13264
13264
|
if (subtype === "api_retry") {
|
|
13265
13265
|
const attempt = obj.attempt;
|
|
13266
13266
|
const max = obj.max_retries;
|
|
13267
|
-
const
|
|
13267
|
+
const delay2 = obj.retry_delay_ms;
|
|
13268
13268
|
return {
|
|
13269
13269
|
type: "thinking",
|
|
13270
|
-
data: `API retry ${attempt ?? "?"}/${max ?? "?"}${typeof
|
|
13270
|
+
data: `API retry ${attempt ?? "?"}/${max ?? "?"}${typeof delay2 === "number" ? ` (wait ${delay2}ms)` : ""}`
|
|
13271
13271
|
};
|
|
13272
13272
|
}
|
|
13273
13273
|
if (subtype === "status") {
|
|
@@ -17481,15 +17481,76 @@ var init_request_review = __esm({
|
|
|
17481
17481
|
}
|
|
17482
17482
|
});
|
|
17483
17483
|
|
|
17484
|
+
// src/hook/worktree-run-ports.ts
|
|
17485
|
+
function worktreeRunPortsPath(worktreePath) {
|
|
17486
|
+
return (0, import_node_path44.join)(worktreePath, RUN_PORTS_REL);
|
|
17487
|
+
}
|
|
17488
|
+
function isPort(value) {
|
|
17489
|
+
return typeof value === "number" && Number.isInteger(value) && value > 0 && value <= 65535;
|
|
17490
|
+
}
|
|
17491
|
+
function parseFile(raw) {
|
|
17492
|
+
try {
|
|
17493
|
+
const parsed = JSON.parse(raw);
|
|
17494
|
+
if (!parsed || typeof parsed !== "object") return {};
|
|
17495
|
+
const scripts = parsed.scripts;
|
|
17496
|
+
if (!scripts || typeof scripts !== "object") return {};
|
|
17497
|
+
const next = {};
|
|
17498
|
+
for (const [name, ports] of Object.entries(scripts)) {
|
|
17499
|
+
if (!name || !Array.isArray(ports)) continue;
|
|
17500
|
+
const cleaned = ports.filter(isPort);
|
|
17501
|
+
if (cleaned.length) next[name] = cleaned;
|
|
17502
|
+
}
|
|
17503
|
+
return { scripts: next };
|
|
17504
|
+
} catch {
|
|
17505
|
+
return {};
|
|
17506
|
+
}
|
|
17507
|
+
}
|
|
17508
|
+
function loadWorktreeRunPorts(worktreePath, scriptName) {
|
|
17509
|
+
if (!worktreePath.trim() || !scriptName.trim()) return null;
|
|
17510
|
+
try {
|
|
17511
|
+
const raw = (0, import_node_fs44.readFileSync)(worktreeRunPortsPath(worktreePath), "utf8");
|
|
17512
|
+
const ports = parseFile(raw).scripts?.[scriptName];
|
|
17513
|
+
return ports?.length ? ports : null;
|
|
17514
|
+
} catch {
|
|
17515
|
+
return null;
|
|
17516
|
+
}
|
|
17517
|
+
}
|
|
17518
|
+
function saveWorktreeRunPorts(worktreePath, scriptName, ports) {
|
|
17519
|
+
if (!worktreePath.trim() || !scriptName.trim()) return;
|
|
17520
|
+
const cleaned = ports.filter(isPort);
|
|
17521
|
+
if (!cleaned.length) return;
|
|
17522
|
+
const path2 = worktreeRunPortsPath(worktreePath);
|
|
17523
|
+
let current = {};
|
|
17524
|
+
try {
|
|
17525
|
+
current = parseFile((0, import_node_fs44.readFileSync)(path2, "utf8"));
|
|
17526
|
+
} catch {
|
|
17527
|
+
current = {};
|
|
17528
|
+
}
|
|
17529
|
+
const scripts = { ...current.scripts ?? {} };
|
|
17530
|
+
scripts[scriptName] = cleaned;
|
|
17531
|
+
(0, import_node_fs44.mkdirSync)((0, import_node_path44.dirname)(path2), { recursive: true });
|
|
17532
|
+
(0, import_node_fs44.writeFileSync)(path2, `${JSON.stringify({ scripts }, null, 2)}
|
|
17533
|
+
`, "utf8");
|
|
17534
|
+
}
|
|
17535
|
+
var import_node_fs44, import_node_path44, RUN_PORTS_REL;
|
|
17536
|
+
var init_worktree_run_ports = __esm({
|
|
17537
|
+
"src/hook/worktree-run-ports.ts"() {
|
|
17538
|
+
"use strict";
|
|
17539
|
+
import_node_fs44 = require("fs");
|
|
17540
|
+
import_node_path44 = require("path");
|
|
17541
|
+
RUN_PORTS_REL = ".context/.sideboard/run-ports.json";
|
|
17542
|
+
}
|
|
17543
|
+
});
|
|
17544
|
+
|
|
17484
17545
|
// src/hook/conductor.ts
|
|
17485
17546
|
function matchSimpleGlob(pattern, name) {
|
|
17486
17547
|
const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
|
|
17487
17548
|
return new RegExp(`^${escaped}$`).test(name);
|
|
17488
17549
|
}
|
|
17489
17550
|
function readWorktreeInclude(repoPath) {
|
|
17490
|
-
const path2 = (0,
|
|
17491
|
-
if (!(0,
|
|
17492
|
-
return (0,
|
|
17551
|
+
const path2 = (0, import_node_path45.join)(repoPath, ".worktreeinclude");
|
|
17552
|
+
if (!(0, import_node_fs45.existsSync)(path2)) return [];
|
|
17553
|
+
return (0, import_node_fs45.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
17493
17554
|
}
|
|
17494
17555
|
function resolveFilesToCopy(repoPath) {
|
|
17495
17556
|
const fromInclude = readWorktreeInclude(repoPath);
|
|
@@ -17499,10 +17560,10 @@ function resolveFilesToCopy(repoPath) {
|
|
|
17499
17560
|
if (settings?.fileIncludeGlobs?.length) {
|
|
17500
17561
|
const matched = [];
|
|
17501
17562
|
try {
|
|
17502
|
-
for (const entry of (0,
|
|
17563
|
+
for (const entry of (0, import_node_fs45.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
17503
17564
|
if (!entry.isFile()) continue;
|
|
17504
17565
|
for (const glob of settings.fileIncludeGlobs) {
|
|
17505
|
-
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0,
|
|
17566
|
+
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path45.basename)(glob), entry.name)) {
|
|
17506
17567
|
matched.push(entry.name);
|
|
17507
17568
|
break;
|
|
17508
17569
|
}
|
|
@@ -17514,7 +17575,7 @@ function resolveFilesToCopy(repoPath) {
|
|
|
17514
17575
|
}
|
|
17515
17576
|
const defaults = [];
|
|
17516
17577
|
try {
|
|
17517
|
-
for (const entry of (0,
|
|
17578
|
+
for (const entry of (0, import_node_fs45.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
17518
17579
|
if (entry.isFile() && entry.name.startsWith(".env")) {
|
|
17519
17580
|
defaults.push(entry.name);
|
|
17520
17581
|
}
|
|
@@ -17528,11 +17589,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
|
|
|
17528
17589
|
const patterns = resolveFilesToCopy(repoPath);
|
|
17529
17590
|
const copied = [];
|
|
17530
17591
|
for (const rel of patterns) {
|
|
17531
|
-
const src = (0,
|
|
17532
|
-
if (!(0,
|
|
17533
|
-
const dest = (0,
|
|
17534
|
-
(0,
|
|
17535
|
-
(0,
|
|
17592
|
+
const src = (0, import_node_path45.join)(repoPath, rel);
|
|
17593
|
+
if (!(0, import_node_fs45.existsSync)(src)) continue;
|
|
17594
|
+
const dest = (0, import_node_path45.join)(worktreePath, rel);
|
|
17595
|
+
(0, import_node_fs45.mkdirSync)((0, import_node_path45.dirname)(dest), { recursive: true });
|
|
17596
|
+
(0, import_node_fs45.copyFileSync)(src, dest);
|
|
17536
17597
|
copied.push(rel);
|
|
17537
17598
|
}
|
|
17538
17599
|
return copied;
|
|
@@ -17567,7 +17628,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
|
|
|
17567
17628
|
const env = stripNestedElectronEnv({
|
|
17568
17629
|
...baseEnv ?? process.env
|
|
17569
17630
|
});
|
|
17570
|
-
const name = opts.workspaceName ?? (0,
|
|
17631
|
+
const name = opts.workspaceName ?? (0, import_node_path45.basename)(opts.worktreePath);
|
|
17571
17632
|
const ports = opts.ports ?? [];
|
|
17572
17633
|
const primary = ports[0];
|
|
17573
17634
|
env.SIDEBOARD_WORKSPACE_NAME = name;
|
|
@@ -17607,6 +17668,57 @@ function killableListenerPids(raw, selfPid = process.pid) {
|
|
|
17607
17668
|
}
|
|
17608
17669
|
return pids;
|
|
17609
17670
|
}
|
|
17671
|
+
function listUnixListenerPids(port, selfPid) {
|
|
17672
|
+
try {
|
|
17673
|
+
const raw = (0, import_node_child_process5.execFileSync)("lsof", [`-tiTCP:${port}`, "-sTCP:LISTEN"], {
|
|
17674
|
+
encoding: "utf8",
|
|
17675
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
17676
|
+
timeout: 2e3
|
|
17677
|
+
});
|
|
17678
|
+
return killableListenerPids(raw, selfPid);
|
|
17679
|
+
} catch {
|
|
17680
|
+
return [];
|
|
17681
|
+
}
|
|
17682
|
+
}
|
|
17683
|
+
function listenerCwd(pid) {
|
|
17684
|
+
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
17685
|
+
try {
|
|
17686
|
+
const raw = (0, import_node_child_process5.execFileSync)("lsof", ["-a", "-p", String(pid), "-d", "cwd", "-Fn"], {
|
|
17687
|
+
encoding: "utf8",
|
|
17688
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
17689
|
+
timeout: 2e3
|
|
17690
|
+
});
|
|
17691
|
+
for (const line of raw.split("\n")) {
|
|
17692
|
+
if (line.startsWith("n") && line.length > 1) return line.slice(1);
|
|
17693
|
+
}
|
|
17694
|
+
} catch {
|
|
17695
|
+
}
|
|
17696
|
+
return null;
|
|
17697
|
+
}
|
|
17698
|
+
function realpathOrResolve(path2) {
|
|
17699
|
+
try {
|
|
17700
|
+
return (0, import_node_fs45.realpathSync)(path2);
|
|
17701
|
+
} catch {
|
|
17702
|
+
return (0, import_node_path45.resolve)(path2);
|
|
17703
|
+
}
|
|
17704
|
+
}
|
|
17705
|
+
function isOtherWorktreeListenerCwd(cwd, worktreePath) {
|
|
17706
|
+
const wt = realpathOrResolve(worktreePath);
|
|
17707
|
+
const c = realpathOrResolve(cwd);
|
|
17708
|
+
if (c === wt || c.startsWith(wt + import_node_path45.sep)) return false;
|
|
17709
|
+
const parent = (0, import_node_path45.dirname)(wt);
|
|
17710
|
+
const thisName = (0, import_node_path45.basename)(wt);
|
|
17711
|
+
if (!thisName || c === parent) return false;
|
|
17712
|
+
if (!c.startsWith(parent + import_node_path45.sep)) return false;
|
|
17713
|
+
const first = c.slice(parent.length + 1).split(import_node_path45.sep)[0];
|
|
17714
|
+
return Boolean(first) && first !== thisName;
|
|
17715
|
+
}
|
|
17716
|
+
function signalPid(pid, signal) {
|
|
17717
|
+
try {
|
|
17718
|
+
process.kill(pid, signal);
|
|
17719
|
+
} catch {
|
|
17720
|
+
}
|
|
17721
|
+
}
|
|
17610
17722
|
function killListenersOnPorts(ports) {
|
|
17611
17723
|
const selfPid = process.pid;
|
|
17612
17724
|
for (const port of ports) {
|
|
@@ -17624,26 +17736,32 @@ function killListenersOnPorts(ports) {
|
|
|
17624
17736
|
);
|
|
17625
17737
|
continue;
|
|
17626
17738
|
}
|
|
17627
|
-
|
|
17628
|
-
|
|
17629
|
-
raw = (0, import_node_child_process5.execFileSync)("lsof", [`-tiTCP:${port}`, "-sTCP:LISTEN"], {
|
|
17630
|
-
encoding: "utf8",
|
|
17631
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
17632
|
-
timeout: 2e3
|
|
17633
|
-
});
|
|
17634
|
-
} catch {
|
|
17635
|
-
continue;
|
|
17636
|
-
}
|
|
17637
|
-
for (const pid of killableListenerPids(raw, selfPid)) {
|
|
17638
|
-
try {
|
|
17639
|
-
process.kill(pid, "SIGTERM");
|
|
17640
|
-
} catch {
|
|
17641
|
-
}
|
|
17739
|
+
for (const pid of listUnixListenerPids(port, selfPid)) {
|
|
17740
|
+
signalPid(pid, "SIGTERM");
|
|
17642
17741
|
}
|
|
17643
17742
|
} catch {
|
|
17644
17743
|
}
|
|
17645
17744
|
}
|
|
17646
17745
|
}
|
|
17746
|
+
function killStaleWorktreeListeners(ports, worktreePath, signal = "SIGTERM") {
|
|
17747
|
+
if (!worktreePath.trim()) {
|
|
17748
|
+
killListenersOnPorts(ports);
|
|
17749
|
+
return;
|
|
17750
|
+
}
|
|
17751
|
+
if (process.platform === "win32") {
|
|
17752
|
+
killListenersOnPorts(ports);
|
|
17753
|
+
return;
|
|
17754
|
+
}
|
|
17755
|
+
const selfPid = process.pid;
|
|
17756
|
+
for (const port of ports) {
|
|
17757
|
+
if (!Number.isFinite(port) || port <= 0) continue;
|
|
17758
|
+
for (const pid of listUnixListenerPids(port, selfPid)) {
|
|
17759
|
+
const cwd = listenerCwd(pid);
|
|
17760
|
+
if (cwd && isOtherWorktreeListenerCwd(cwd, worktreePath)) continue;
|
|
17761
|
+
signalPid(pid, signal);
|
|
17762
|
+
}
|
|
17763
|
+
}
|
|
17764
|
+
}
|
|
17647
17765
|
function killScriptTree(child, ports = []) {
|
|
17648
17766
|
const pid = child.pid;
|
|
17649
17767
|
if (pid) {
|
|
@@ -17805,7 +17923,7 @@ function getRunMode(worktreePath, repoPath) {
|
|
|
17805
17923
|
return loadWorkspaceSettings(worktreePath, repoPath)?.runMode ?? "concurrent";
|
|
17806
17924
|
}
|
|
17807
17925
|
async function reservePort() {
|
|
17808
|
-
return new Promise((
|
|
17926
|
+
return new Promise((resolve2, reject) => {
|
|
17809
17927
|
const server = (0, import_node_net.createServer)();
|
|
17810
17928
|
let released = false;
|
|
17811
17929
|
const release = () => new Promise((res) => {
|
|
@@ -17822,7 +17940,7 @@ async function reservePort() {
|
|
|
17822
17940
|
void release().then(() => reject(new Error("Failed to allocate port")));
|
|
17823
17941
|
return;
|
|
17824
17942
|
}
|
|
17825
|
-
|
|
17943
|
+
resolve2({ port: addr.port, release });
|
|
17826
17944
|
});
|
|
17827
17945
|
server.on("error", reject);
|
|
17828
17946
|
});
|
|
@@ -17833,7 +17951,8 @@ async function allocatePort() {
|
|
|
17833
17951
|
return held.port;
|
|
17834
17952
|
}
|
|
17835
17953
|
async function tryReservePort(port) {
|
|
17836
|
-
|
|
17954
|
+
if (!Number.isInteger(port) || port <= 0 || port > 65535) return null;
|
|
17955
|
+
return new Promise((resolve2) => {
|
|
17837
17956
|
const server = (0, import_node_net.createServer)();
|
|
17838
17957
|
let released = false;
|
|
17839
17958
|
const release = () => new Promise((res) => {
|
|
@@ -17844,24 +17963,54 @@ async function tryReservePort(port) {
|
|
|
17844
17963
|
released = true;
|
|
17845
17964
|
server.close(() => res());
|
|
17846
17965
|
});
|
|
17847
|
-
server.once("error", () =>
|
|
17966
|
+
server.once("error", () => {
|
|
17967
|
+
try {
|
|
17968
|
+
server.close();
|
|
17969
|
+
} catch {
|
|
17970
|
+
}
|
|
17971
|
+
resolve2(null);
|
|
17972
|
+
});
|
|
17848
17973
|
server.listen(port, "127.0.0.1", () => {
|
|
17849
|
-
|
|
17974
|
+
resolve2({ port, release });
|
|
17850
17975
|
});
|
|
17851
17976
|
});
|
|
17852
17977
|
}
|
|
17853
|
-
async function
|
|
17854
|
-
const held = [
|
|
17855
|
-
const
|
|
17978
|
+
async function tryReservePorts(ports) {
|
|
17979
|
+
const held = [];
|
|
17980
|
+
for (const port of ports) {
|
|
17981
|
+
const next = await tryReservePort(port);
|
|
17982
|
+
if (!next) {
|
|
17983
|
+
await Promise.all(held.map((h) => h.release()));
|
|
17984
|
+
return null;
|
|
17985
|
+
}
|
|
17986
|
+
held.push(next);
|
|
17987
|
+
}
|
|
17988
|
+
return held;
|
|
17989
|
+
}
|
|
17990
|
+
function normalizePreferredPorts(ports, size) {
|
|
17991
|
+
if (!ports?.length) return [];
|
|
17992
|
+
const seen = /* @__PURE__ */ new Set();
|
|
17993
|
+
const out = [];
|
|
17994
|
+
for (const p of ports) {
|
|
17995
|
+
if (!Number.isInteger(p) || p <= 0 || p > 65535 || seen.has(p)) continue;
|
|
17996
|
+
seen.add(p);
|
|
17997
|
+
out.push(p);
|
|
17998
|
+
if (out.length >= size) break;
|
|
17999
|
+
}
|
|
18000
|
+
return out;
|
|
18001
|
+
}
|
|
18002
|
+
function delay(ms) {
|
|
18003
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
18004
|
+
}
|
|
18005
|
+
async function fillPortRange(held, size) {
|
|
18006
|
+
if (held.length >= size) return held;
|
|
18007
|
+
const base = held[0]?.port;
|
|
17856
18008
|
try {
|
|
17857
|
-
for (let i =
|
|
17858
|
-
const candidate = base + i;
|
|
17859
|
-
const next = await tryReservePort(candidate);
|
|
17860
|
-
if (next)
|
|
17861
|
-
|
|
17862
|
-
} else {
|
|
17863
|
-
held.push(await reservePort());
|
|
17864
|
-
}
|
|
18009
|
+
for (let i = held.length; i < size; i++) {
|
|
18010
|
+
const candidate = base != null ? base + i : null;
|
|
18011
|
+
const next = candidate != null ? await tryReservePort(candidate) : null;
|
|
18012
|
+
if (next) held.push(next);
|
|
18013
|
+
else held.push(await reservePort());
|
|
17865
18014
|
}
|
|
17866
18015
|
return held;
|
|
17867
18016
|
} catch (err) {
|
|
@@ -17869,6 +18018,33 @@ async function reservePortRange(size = PORT_RANGE_SIZE) {
|
|
|
17869
18018
|
throw err;
|
|
17870
18019
|
}
|
|
17871
18020
|
}
|
|
18021
|
+
async function reclaimPreferredPorts(ports, worktreePath) {
|
|
18022
|
+
let held = await tryReservePorts(ports);
|
|
18023
|
+
if (held) return held;
|
|
18024
|
+
if (worktreePath) {
|
|
18025
|
+
killStaleWorktreeListeners(ports, worktreePath, "SIGTERM");
|
|
18026
|
+
} else {
|
|
18027
|
+
killListenersOnPorts(ports);
|
|
18028
|
+
}
|
|
18029
|
+
for (let i = 0; i < RECLAIM_TRIES; i++) {
|
|
18030
|
+
await delay(RECLAIM_RETRY_DELAY_MS);
|
|
18031
|
+
held = await tryReservePorts(ports);
|
|
18032
|
+
if (held) return held;
|
|
18033
|
+
if (i === 2 && worktreePath) {
|
|
18034
|
+
killStaleWorktreeListeners(ports, worktreePath, "SIGKILL");
|
|
18035
|
+
}
|
|
18036
|
+
}
|
|
18037
|
+
return null;
|
|
18038
|
+
}
|
|
18039
|
+
async function reservePortRange(size = PORT_RANGE_SIZE, opts) {
|
|
18040
|
+
const preferred = normalizePreferredPorts(opts?.preferred, size);
|
|
18041
|
+
if (preferred.length) {
|
|
18042
|
+
const reused = await reclaimPreferredPorts(preferred, opts?.worktreePath);
|
|
18043
|
+
if (reused) return fillPortRange(reused, size);
|
|
18044
|
+
}
|
|
18045
|
+
const held = [await reservePort()];
|
|
18046
|
+
return fillPortRange(held, size);
|
|
18047
|
+
}
|
|
17872
18048
|
async function allocatePortRange(size = PORT_RANGE_SIZE) {
|
|
17873
18049
|
const held = await reservePortRange(size);
|
|
17874
18050
|
const ports = held.map((h) => h.port);
|
|
@@ -17878,8 +18054,13 @@ async function allocatePortRange(size = PORT_RANGE_SIZE) {
|
|
|
17878
18054
|
async function startDevServer(repoPath, worktreePath, onLine, opts) {
|
|
17879
18055
|
const script = getRunScript(worktreePath, repoPath, opts?.scriptName);
|
|
17880
18056
|
if (!script) return null;
|
|
17881
|
-
const
|
|
18057
|
+
const preferred = loadWorktreeRunPorts(worktreePath, script.name) ?? opts?.preferredPorts;
|
|
18058
|
+
const held = await reservePortRange(PORT_RANGE_SIZE, {
|
|
18059
|
+
preferred: preferred ?? void 0,
|
|
18060
|
+
worktreePath
|
|
18061
|
+
});
|
|
17882
18062
|
const ports = held.map((h) => h.port);
|
|
18063
|
+
saveWorktreeRunPorts(worktreePath, script.name, ports);
|
|
17883
18064
|
try {
|
|
17884
18065
|
const handle = await spawnWorkspaceScript(script.command, {
|
|
17885
18066
|
worktreePath,
|
|
@@ -17902,14 +18083,14 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
|
|
|
17902
18083
|
throw err;
|
|
17903
18084
|
}
|
|
17904
18085
|
}
|
|
17905
|
-
var
|
|
18086
|
+
var import_node_fs45, import_node_child_process5, import_node_net, import_node_path45, import_execa4, import_node_readline3, PORT_RANGE_SIZE, RECLAIM_RETRY_DELAY_MS, RECLAIM_TRIES, cachedLoginEnv;
|
|
17906
18087
|
var init_conductor = __esm({
|
|
17907
18088
|
"src/hook/conductor.ts"() {
|
|
17908
18089
|
"use strict";
|
|
17909
|
-
|
|
18090
|
+
import_node_fs45 = require("fs");
|
|
17910
18091
|
import_node_child_process5 = require("child_process");
|
|
17911
18092
|
import_node_net = require("net");
|
|
17912
|
-
|
|
18093
|
+
import_node_path45 = require("path");
|
|
17913
18094
|
import_execa4 = require("execa");
|
|
17914
18095
|
import_node_readline3 = require("readline");
|
|
17915
18096
|
init_settings();
|
|
@@ -17920,8 +18101,12 @@ var init_conductor = __esm({
|
|
|
17920
18101
|
init_git_auth_mode();
|
|
17921
18102
|
init_request_review();
|
|
17922
18103
|
init_worktree_exclude();
|
|
18104
|
+
init_worktree_run_ports();
|
|
18105
|
+
init_worktree_run_ports();
|
|
17923
18106
|
init_nested_electron_env();
|
|
17924
18107
|
PORT_RANGE_SIZE = 10;
|
|
18108
|
+
RECLAIM_RETRY_DELAY_MS = 40;
|
|
18109
|
+
RECLAIM_TRIES = 8;
|
|
17925
18110
|
cachedLoginEnv = null;
|
|
17926
18111
|
}
|
|
17927
18112
|
});
|
|
@@ -17937,9 +18122,9 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
17937
18122
|
repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
|
|
17938
18123
|
);
|
|
17939
18124
|
const homeRoot = sideboardWorkspacesDir();
|
|
17940
|
-
if ((0,
|
|
18125
|
+
if ((0, import_node_fs46.existsSync)(homeRoot)) {
|
|
17941
18126
|
try {
|
|
17942
|
-
for (const entry of (0,
|
|
18127
|
+
for (const entry of (0, import_node_fs46.readdirSync)(homeRoot, { withFileTypes: true })) {
|
|
17943
18128
|
if (!entry.isDirectory()) continue;
|
|
17944
18129
|
void entry;
|
|
17945
18130
|
}
|
|
@@ -17949,7 +18134,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
17949
18134
|
const orphans = [];
|
|
17950
18135
|
const seen = /* @__PURE__ */ new Set();
|
|
17951
18136
|
for (const repoPath of repos) {
|
|
17952
|
-
if (!repoPath || !(0,
|
|
18137
|
+
if (!repoPath || !(0, import_node_fs46.existsSync)(repoPath)) continue;
|
|
17953
18138
|
try {
|
|
17954
18139
|
const wts = await listWorktrees(repoPath);
|
|
17955
18140
|
for (const wt of wts) {
|
|
@@ -17960,7 +18145,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
17960
18145
|
seen.add(path2);
|
|
17961
18146
|
let mtimeMs = 0;
|
|
17962
18147
|
try {
|
|
17963
|
-
mtimeMs = (0,
|
|
18148
|
+
mtimeMs = (0, import_node_fs46.statSync)(path2).mtimeMs;
|
|
17964
18149
|
} catch {
|
|
17965
18150
|
mtimeMs = 0;
|
|
17966
18151
|
}
|
|
@@ -17970,16 +18155,16 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
17970
18155
|
}
|
|
17971
18156
|
try {
|
|
17972
18157
|
const root = worktreesRoot(repoPath);
|
|
17973
|
-
if ((0,
|
|
17974
|
-
for (const entry of (0,
|
|
18158
|
+
if ((0, import_node_fs46.existsSync)(root)) {
|
|
18159
|
+
for (const entry of (0, import_node_fs46.readdirSync)(root, { withFileTypes: true })) {
|
|
17975
18160
|
if (!entry.isDirectory()) continue;
|
|
17976
|
-
const path2 = (0,
|
|
18161
|
+
const path2 = (0, import_node_path46.join)(root, entry.name).replace(/\/$/, "");
|
|
17977
18162
|
if (known.has(path2) || seen.has(path2)) continue;
|
|
17978
|
-
if (!(0,
|
|
18163
|
+
if (!(0, import_node_fs46.existsSync)((0, import_node_path46.join)(path2, ".git"))) continue;
|
|
17979
18164
|
seen.add(path2);
|
|
17980
18165
|
let mtimeMs = 0;
|
|
17981
18166
|
try {
|
|
17982
|
-
mtimeMs = (0,
|
|
18167
|
+
mtimeMs = (0, import_node_fs46.statSync)(path2).mtimeMs;
|
|
17983
18168
|
} catch {
|
|
17984
18169
|
mtimeMs = Date.now();
|
|
17985
18170
|
}
|
|
@@ -18040,12 +18225,12 @@ function worktreeCleanupSettings() {
|
|
|
18040
18225
|
autoCleanupOrphans: a.autoCleanupOrphans
|
|
18041
18226
|
};
|
|
18042
18227
|
}
|
|
18043
|
-
var
|
|
18228
|
+
var import_node_fs46, import_node_path46;
|
|
18044
18229
|
var init_orphan_cleanup = __esm({
|
|
18045
18230
|
"src/git/orphan-cleanup.ts"() {
|
|
18046
18231
|
"use strict";
|
|
18047
|
-
|
|
18048
|
-
|
|
18232
|
+
import_node_fs46 = require("fs");
|
|
18233
|
+
import_node_path46 = require("path");
|
|
18049
18234
|
init_worktree();
|
|
18050
18235
|
init_thread_store();
|
|
18051
18236
|
init_paths();
|
|
@@ -18220,12 +18405,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
18220
18405
|
if (!url) throw new Error("Clone URL is required");
|
|
18221
18406
|
let name = opts.name?.trim();
|
|
18222
18407
|
if (!name) {
|
|
18223
|
-
const leaf = (0,
|
|
18408
|
+
const leaf = (0, import_node_path47.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
|
|
18224
18409
|
name = leaf || "repo";
|
|
18225
18410
|
}
|
|
18226
18411
|
name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
|
|
18227
|
-
const dest = (0,
|
|
18228
|
-
if ((0,
|
|
18412
|
+
const dest = (0, import_node_path47.join)(sideboardReposDir(), name);
|
|
18413
|
+
if ((0, import_node_fs47.existsSync)(dest)) {
|
|
18229
18414
|
const repoPath2 = await resolveRepoRoot(dest);
|
|
18230
18415
|
const workspace2 = await ensureWorkspace(repoPath2);
|
|
18231
18416
|
return { repoPath: repoPath2, workspace: workspace2 };
|
|
@@ -18240,12 +18425,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
18240
18425
|
const workspace = await ensureWorkspace(repoPath);
|
|
18241
18426
|
return { repoPath, workspace };
|
|
18242
18427
|
}
|
|
18243
|
-
var
|
|
18428
|
+
var import_node_fs47, import_node_path47, import_execa6;
|
|
18244
18429
|
var init_clone_repo = __esm({
|
|
18245
18430
|
"src/git/clone-repo.ts"() {
|
|
18246
18431
|
"use strict";
|
|
18247
|
-
|
|
18248
|
-
|
|
18432
|
+
import_node_fs47 = require("fs");
|
|
18433
|
+
import_node_path47 = require("path");
|
|
18249
18434
|
import_execa6 = require("execa");
|
|
18250
18435
|
init_paths();
|
|
18251
18436
|
init_workspaces();
|
|
@@ -18374,24 +18559,24 @@ function jobTreeAlive(pid) {
|
|
|
18374
18559
|
return jobAlive(pid) || processGroupAlive(pid);
|
|
18375
18560
|
}
|
|
18376
18561
|
function readIntFile(file) {
|
|
18377
|
-
if (!(0,
|
|
18378
|
-
const n = Number.parseInt((0,
|
|
18562
|
+
if (!(0, import_node_fs48.existsSync)(file)) return null;
|
|
18563
|
+
const n = Number.parseInt((0, import_node_fs48.readFileSync)(file, "utf8").trim(), 10);
|
|
18379
18564
|
return Number.isInteger(n) ? n : null;
|
|
18380
18565
|
}
|
|
18381
18566
|
function jobDir(root, id, legacy = false) {
|
|
18382
|
-
return (0,
|
|
18567
|
+
return (0, import_node_path48.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
|
|
18383
18568
|
}
|
|
18384
18569
|
function resolveJobDir(root, id) {
|
|
18385
18570
|
const modern = jobDir(root, id, false);
|
|
18386
|
-
if ((0,
|
|
18571
|
+
if ((0, import_node_fs48.existsSync)(modern)) return modern;
|
|
18387
18572
|
const legacy = jobDir(root, id, true);
|
|
18388
|
-
if ((0,
|
|
18573
|
+
if ((0, import_node_fs48.existsSync)(legacy)) return legacy;
|
|
18389
18574
|
return modern;
|
|
18390
18575
|
}
|
|
18391
18576
|
function listJobIdsIn(root, rel) {
|
|
18392
|
-
const dir = (0,
|
|
18393
|
-
if (!(0,
|
|
18394
|
-
return (0,
|
|
18577
|
+
const dir = (0, import_node_path48.join)(root, rel);
|
|
18578
|
+
if (!(0, import_node_fs48.existsSync)(dir)) return [];
|
|
18579
|
+
return (0, import_node_fs48.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
|
|
18395
18580
|
}
|
|
18396
18581
|
function listRunningDetachedJobs(worktreePath) {
|
|
18397
18582
|
const root = worktreePath.trim();
|
|
@@ -18403,7 +18588,7 @@ function listRunningDetachedJobs(worktreePath) {
|
|
|
18403
18588
|
const running = [];
|
|
18404
18589
|
for (const id of ids) {
|
|
18405
18590
|
const dir = resolveJobDir(root, id);
|
|
18406
|
-
const pid = readIntFile((0,
|
|
18591
|
+
const pid = readIntFile((0, import_node_path48.join)(dir, "pid"));
|
|
18407
18592
|
if (jobTreeAlive(pid)) running.push(id);
|
|
18408
18593
|
}
|
|
18409
18594
|
return running.sort();
|
|
@@ -18486,8 +18671,8 @@ function planJobContinue(opts) {
|
|
|
18486
18671
|
return { action: "none" };
|
|
18487
18672
|
}
|
|
18488
18673
|
function tailProgress(logFile, maxLines = 12) {
|
|
18489
|
-
if (!(0,
|
|
18490
|
-
const lines = (0,
|
|
18674
|
+
if (!(0, import_node_fs48.existsSync)(logFile)) return "(no log yet)";
|
|
18675
|
+
const lines = (0, import_node_fs48.readFileSync)(logFile, "utf8").split("\n");
|
|
18491
18676
|
return lines.slice(-maxLines).join("\n");
|
|
18492
18677
|
}
|
|
18493
18678
|
function lastProgressLine(progress) {
|
|
@@ -18495,8 +18680,8 @@ function lastProgressLine(progress) {
|
|
|
18495
18680
|
return last ? last.slice(0, 72) : void 0;
|
|
18496
18681
|
}
|
|
18497
18682
|
function readLogLines(file) {
|
|
18498
|
-
if (!(0,
|
|
18499
|
-
const lines = (0,
|
|
18683
|
+
if (!(0, import_node_fs48.existsSync)(file)) return [];
|
|
18684
|
+
const lines = (0, import_node_fs48.readFileSync)(file, "utf8").split("\n");
|
|
18500
18685
|
if (lines.length && lines[lines.length - 1] === "") lines.pop();
|
|
18501
18686
|
return lines;
|
|
18502
18687
|
}
|
|
@@ -18507,15 +18692,15 @@ function takeDelta(logFile, cursorFile) {
|
|
|
18507
18692
|
return { delta: capJobLogDelta(lines.slice(start).join("\n")), nextCursor: lines.length };
|
|
18508
18693
|
}
|
|
18509
18694
|
function snapshotJob(dir) {
|
|
18510
|
-
const pid = readIntFile((0,
|
|
18695
|
+
const pid = readIntFile((0, import_node_path48.join)(dir, "pid"));
|
|
18511
18696
|
const running = jobTreeAlive(pid);
|
|
18512
18697
|
return {
|
|
18513
18698
|
pid,
|
|
18514
18699
|
running,
|
|
18515
|
-
exitCode: readIntFile((0,
|
|
18516
|
-
log: (0,
|
|
18517
|
-
cursor: (0,
|
|
18518
|
-
progress: tailProgress((0,
|
|
18700
|
+
exitCode: readIntFile((0, import_node_path48.join)(dir, "exit")),
|
|
18701
|
+
log: (0, import_node_path48.join)(dir, "log"),
|
|
18702
|
+
cursor: (0, import_node_path48.join)(dir, "present.cursor"),
|
|
18703
|
+
progress: tailProgress((0, import_node_path48.join)(dir, "log"))
|
|
18519
18704
|
};
|
|
18520
18705
|
}
|
|
18521
18706
|
function toResult(id, snap, extra) {
|
|
@@ -18524,8 +18709,8 @@ function toResult(id, snap, extra) {
|
|
|
18524
18709
|
const stillRunning = snap.running && !ok;
|
|
18525
18710
|
const { delta, nextCursor } = takeDelta(snap.log, snap.cursor);
|
|
18526
18711
|
try {
|
|
18527
|
-
(0,
|
|
18528
|
-
(0,
|
|
18712
|
+
(0, import_node_fs48.mkdirSync)((0, import_node_path48.dirname)(snap.cursor), { recursive: true });
|
|
18713
|
+
(0, import_node_fs48.writeFileSync)(snap.cursor, `${nextCursor}
|
|
18529
18714
|
`);
|
|
18530
18715
|
} catch {
|
|
18531
18716
|
}
|
|
@@ -18546,7 +18731,7 @@ function toResult(id, snap, extra) {
|
|
|
18546
18731
|
};
|
|
18547
18732
|
}
|
|
18548
18733
|
async function sleepMs(ms) {
|
|
18549
|
-
await new Promise((
|
|
18734
|
+
await new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
18550
18735
|
}
|
|
18551
18736
|
async function waitForDetachedJob(cwd, id, opts) {
|
|
18552
18737
|
const jobId = sanitizeDetachedJobId(id);
|
|
@@ -18554,7 +18739,7 @@ async function waitForDetachedJob(cwd, id, opts) {
|
|
|
18554
18739
|
const dir = resolveJobDir(root, jobId);
|
|
18555
18740
|
const timeoutMs = mcpWaitForJobTimeoutMs(opts?.timeoutMs);
|
|
18556
18741
|
const sleep2 = opts?.sleep ?? sleepMs;
|
|
18557
|
-
if (!(0,
|
|
18742
|
+
if (!(0, import_node_fs48.existsSync)(dir)) {
|
|
18558
18743
|
return {
|
|
18559
18744
|
stillRunning: false,
|
|
18560
18745
|
ok: false,
|
|
@@ -18600,10 +18785,10 @@ function killProcessTree(pid, signal) {
|
|
|
18600
18785
|
}
|
|
18601
18786
|
function appendJobLog(logFile, line) {
|
|
18602
18787
|
try {
|
|
18603
|
-
(0,
|
|
18788
|
+
(0, import_node_fs48.mkdirSync)((0, import_node_path48.dirname)(logFile), { recursive: true });
|
|
18604
18789
|
const body = line.endsWith("\n") ? line : `${line}
|
|
18605
18790
|
`;
|
|
18606
|
-
(0,
|
|
18791
|
+
(0, import_node_fs48.appendFileSync)(logFile, body);
|
|
18607
18792
|
} catch {
|
|
18608
18793
|
}
|
|
18609
18794
|
}
|
|
@@ -18613,7 +18798,7 @@ async function stopDetachedJob(cwd, id, opts) {
|
|
|
18613
18798
|
const dir = resolveJobDir(root, jobId);
|
|
18614
18799
|
const sleep2 = opts?.sleep ?? sleepMs;
|
|
18615
18800
|
const why = opts?.reason?.trim() ?? "";
|
|
18616
|
-
if (!(0,
|
|
18801
|
+
if (!(0, import_node_fs48.existsSync)(dir)) {
|
|
18617
18802
|
return {
|
|
18618
18803
|
stillRunning: false,
|
|
18619
18804
|
ok: false,
|
|
@@ -18649,10 +18834,10 @@ async function stopDetachedJob(cwd, id, opts) {
|
|
|
18649
18834
|
killProcessTree(targetPid, "SIGKILL");
|
|
18650
18835
|
await sleep2(100);
|
|
18651
18836
|
}
|
|
18652
|
-
const exitFile = (0,
|
|
18653
|
-
if (!(0,
|
|
18837
|
+
const exitFile = (0, import_node_path48.join)(dir, "exit");
|
|
18838
|
+
if (!(0, import_node_fs48.existsSync)(exitFile)) {
|
|
18654
18839
|
try {
|
|
18655
|
-
(0,
|
|
18840
|
+
(0, import_node_fs48.writeFileSync)(exitFile, "1\n");
|
|
18656
18841
|
} catch {
|
|
18657
18842
|
}
|
|
18658
18843
|
}
|
|
@@ -18672,12 +18857,12 @@ async function stopDetachedJob(cwd, id, opts) {
|
|
|
18672
18857
|
hint: stopped ? MCP_STOP_JOB_HINT : MCP_WAIT_JOB_STILL_RUNNING_HINT
|
|
18673
18858
|
};
|
|
18674
18859
|
}
|
|
18675
|
-
var
|
|
18860
|
+
var import_node_fs48, import_node_path48, MAX_JOB_CONTINUES, MAX_JOB_DELTA_LINES, MAX_JOB_DELTA_CHARS, DEFERRED_DONE_MAX_CHARS, GH_WATCH_REFRESH, MCP_WAIT_JOB_STILL_RUNNING_HINT, MCP_STOP_JOB_HINT, JOB_ID_RE;
|
|
18676
18861
|
var init_wait_for_job = __esm({
|
|
18677
18862
|
"src/mcp/wait-for-job.ts"() {
|
|
18678
18863
|
"use strict";
|
|
18679
|
-
|
|
18680
|
-
|
|
18864
|
+
import_node_fs48 = require("fs");
|
|
18865
|
+
import_node_path48 = require("path");
|
|
18681
18866
|
init_workspace_scratch();
|
|
18682
18867
|
init_wait_for_turn();
|
|
18683
18868
|
MAX_JOB_CONTINUES = 8;
|
|
@@ -18922,14 +19107,14 @@ async function startAbleTimeOAuth(opts) {
|
|
|
18922
19107
|
const pkce = createAbleTimePkce();
|
|
18923
19108
|
const authorizeUrl = ableTimeOAuthAuthorizeUrl(clientId, state, pkce.challenge, host);
|
|
18924
19109
|
const timeoutMs = opts?.timeoutMs ?? 5 * 6e4;
|
|
18925
|
-
const code = await new Promise((
|
|
19110
|
+
const code = await new Promise((resolve2, reject) => {
|
|
18926
19111
|
let settled = false;
|
|
18927
19112
|
const finish = (err, value) => {
|
|
18928
19113
|
if (settled) return;
|
|
18929
19114
|
settled = true;
|
|
18930
19115
|
cleanup();
|
|
18931
19116
|
if (err) reject(err);
|
|
18932
|
-
else
|
|
19117
|
+
else resolve2(value);
|
|
18933
19118
|
};
|
|
18934
19119
|
const server = (0, import_node_http.createServer)((req, res) => {
|
|
18935
19120
|
try {
|
|
@@ -20222,7 +20407,7 @@ function reuseLiveThread(input, repoPath, match) {
|
|
|
20222
20407
|
}
|
|
20223
20408
|
async function createThread(input, _onSetupLine) {
|
|
20224
20409
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
20225
|
-
if (!(0,
|
|
20410
|
+
if (!(0, import_node_fs49.existsSync)(repoPath)) {
|
|
20226
20411
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
20227
20412
|
}
|
|
20228
20413
|
const reused = reuseLiveThread(input, repoPath, {
|
|
@@ -20407,11 +20592,11 @@ async function listLinearIssues(agent, repoPath) {
|
|
|
20407
20592
|
}
|
|
20408
20593
|
return adapter.listLinearIssues(repoPath);
|
|
20409
20594
|
}
|
|
20410
|
-
var
|
|
20595
|
+
var import_node_fs49;
|
|
20411
20596
|
var init_create = __esm({
|
|
20412
20597
|
"src/threads/create.ts"() {
|
|
20413
20598
|
"use strict";
|
|
20414
|
-
|
|
20599
|
+
import_node_fs49 = require("fs");
|
|
20415
20600
|
init_detect();
|
|
20416
20601
|
init_worktree();
|
|
20417
20602
|
init_home_board();
|
|
@@ -20563,20 +20748,20 @@ function writeTurnLive(threadId, progress) {
|
|
|
20563
20748
|
const path2 = threadLivePath(threadId);
|
|
20564
20749
|
const tmp = `${path2}.${process.pid}.tmp`;
|
|
20565
20750
|
try {
|
|
20566
|
-
(0,
|
|
20567
|
-
(0,
|
|
20751
|
+
(0, import_node_fs50.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
|
|
20752
|
+
(0, import_node_fs50.renameSync)(tmp, path2);
|
|
20568
20753
|
} catch {
|
|
20569
20754
|
try {
|
|
20570
|
-
(0,
|
|
20755
|
+
(0, import_node_fs50.unlinkSync)(tmp);
|
|
20571
20756
|
} catch {
|
|
20572
20757
|
}
|
|
20573
20758
|
}
|
|
20574
20759
|
}
|
|
20575
20760
|
function readTurnLive(threadId) {
|
|
20576
20761
|
const path2 = threadLivePath(threadId);
|
|
20577
|
-
if (!(0,
|
|
20762
|
+
if (!(0, import_node_fs50.existsSync)(path2)) return null;
|
|
20578
20763
|
try {
|
|
20579
|
-
const raw = JSON.parse((0,
|
|
20764
|
+
const raw = JSON.parse((0, import_node_fs50.readFileSync)(path2, "utf8"));
|
|
20580
20765
|
if (!raw || typeof raw.summary !== "string") return null;
|
|
20581
20766
|
return raw;
|
|
20582
20767
|
} catch {
|
|
@@ -20588,17 +20773,17 @@ function clearTurnLive(threadId) {
|
|
|
20588
20773
|
if (buf?.timer) clearTimeout(buf.timer);
|
|
20589
20774
|
buffers.delete(threadId);
|
|
20590
20775
|
const path2 = threadLivePath(threadId);
|
|
20591
|
-
if (!(0,
|
|
20776
|
+
if (!(0, import_node_fs50.existsSync)(path2)) return;
|
|
20592
20777
|
try {
|
|
20593
|
-
(0,
|
|
20778
|
+
(0, import_node_fs50.unlinkSync)(path2);
|
|
20594
20779
|
} catch {
|
|
20595
20780
|
}
|
|
20596
20781
|
}
|
|
20597
|
-
var
|
|
20782
|
+
var import_node_fs50, buffers, FLUSH_MS, MAX_PARTS;
|
|
20598
20783
|
var init_turn_live = __esm({
|
|
20599
20784
|
"src/store/turn-live.ts"() {
|
|
20600
20785
|
"use strict";
|
|
20601
|
-
|
|
20786
|
+
import_node_fs50 = require("fs");
|
|
20602
20787
|
init_message_parts();
|
|
20603
20788
|
init_paths();
|
|
20604
20789
|
buffers = /* @__PURE__ */ new Map();
|
|
@@ -20842,7 +21027,7 @@ var init_quota_failover = __esm({
|
|
|
20842
21027
|
// src/threads/adopt.ts
|
|
20843
21028
|
function thisModuleFile2() {
|
|
20844
21029
|
const cjsFile = typeof __filename !== "undefined" ? __filename : "";
|
|
20845
|
-
return cjsFile || process.argv[1] || (0,
|
|
21030
|
+
return cjsFile || process.argv[1] || (0, import_node_path49.join)(process.cwd(), "package.json");
|
|
20846
21031
|
}
|
|
20847
21032
|
function openReadonlySqlite(file) {
|
|
20848
21033
|
const req = (0, import_node_module5.createRequire)(thisModuleFile2());
|
|
@@ -20860,21 +21045,21 @@ function mapAgentType(raw) {
|
|
|
20860
21045
|
return null;
|
|
20861
21046
|
}
|
|
20862
21047
|
function resolveConductorCursorAgentId(workspacePath) {
|
|
20863
|
-
if (!workspacePath || !(0,
|
|
21048
|
+
if (!workspacePath || !(0, import_node_fs51.existsSync)(CURSOR_SDK_STORE)) return null;
|
|
20864
21049
|
const normalized = workspacePath.replace(/\/$/, "");
|
|
20865
21050
|
let best = null;
|
|
20866
21051
|
let hashes;
|
|
20867
21052
|
try {
|
|
20868
|
-
hashes = (0,
|
|
21053
|
+
hashes = (0, import_node_fs51.readdirSync)(CURSOR_SDK_STORE);
|
|
20869
21054
|
} catch {
|
|
20870
21055
|
return null;
|
|
20871
21056
|
}
|
|
20872
21057
|
for (const hash of hashes) {
|
|
20873
|
-
const agentsFile = (0,
|
|
20874
|
-
if (!(0,
|
|
21058
|
+
const agentsFile = (0, import_node_path49.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
|
|
21059
|
+
if (!(0, import_node_fs51.existsSync)(agentsFile)) continue;
|
|
20875
21060
|
let text7;
|
|
20876
21061
|
try {
|
|
20877
|
-
text7 = (0,
|
|
21062
|
+
text7 = (0, import_node_fs51.readFileSync)(agentsFile, "utf8");
|
|
20878
21063
|
} catch {
|
|
20879
21064
|
continue;
|
|
20880
21065
|
}
|
|
@@ -20898,7 +21083,7 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
20898
21083
|
return best?.agentId ?? null;
|
|
20899
21084
|
}
|
|
20900
21085
|
async function adoptThread(input) {
|
|
20901
|
-
if (!(0,
|
|
21086
|
+
if (!(0, import_node_fs51.existsSync)(input.worktreePath)) {
|
|
20902
21087
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
20903
21088
|
}
|
|
20904
21089
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
@@ -20927,18 +21112,18 @@ function conductorDbPath() {
|
|
|
20927
21112
|
return CONDUCTOR_DB;
|
|
20928
21113
|
}
|
|
20929
21114
|
function listConductorWorkspaces() {
|
|
20930
|
-
if (!(0,
|
|
21115
|
+
if (!(0, import_node_fs51.existsSync)(CONDUCTOR_DB)) {
|
|
20931
21116
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
20932
21117
|
}
|
|
20933
|
-
const tmp = (0,
|
|
20934
|
-
const snapshot = (0,
|
|
21118
|
+
const tmp = (0, import_node_fs51.mkdtempSync)((0, import_node_path49.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
|
|
21119
|
+
const snapshot = (0, import_node_path49.join)(tmp, "conductor.db");
|
|
20935
21120
|
try {
|
|
20936
|
-
(0,
|
|
21121
|
+
(0, import_node_fs51.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
20937
21122
|
for (const suffix of ["-wal", "-shm"]) {
|
|
20938
21123
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
20939
|
-
if ((0,
|
|
21124
|
+
if ((0, import_node_fs51.existsSync)(src)) {
|
|
20940
21125
|
try {
|
|
20941
|
-
(0,
|
|
21126
|
+
(0, import_node_fs51.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
20942
21127
|
} catch {
|
|
20943
21128
|
}
|
|
20944
21129
|
}
|
|
@@ -21014,22 +21199,22 @@ function listConductorWorkspaces() {
|
|
|
21014
21199
|
db.close();
|
|
21015
21200
|
}
|
|
21016
21201
|
} finally {
|
|
21017
|
-
(0,
|
|
21202
|
+
(0, import_node_fs51.rmSync)(tmp, { recursive: true, force: true });
|
|
21018
21203
|
}
|
|
21019
21204
|
}
|
|
21020
21205
|
function importConductorWorkspace(workspaceId) {
|
|
21021
|
-
if (!(0,
|
|
21206
|
+
if (!(0, import_node_fs51.existsSync)(CONDUCTOR_DB)) {
|
|
21022
21207
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
21023
21208
|
}
|
|
21024
|
-
const tmp = (0,
|
|
21025
|
-
const snapshot = (0,
|
|
21209
|
+
const tmp = (0, import_node_fs51.mkdtempSync)((0, import_node_path49.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
|
|
21210
|
+
const snapshot = (0, import_node_path49.join)(tmp, "conductor.db");
|
|
21026
21211
|
try {
|
|
21027
|
-
(0,
|
|
21212
|
+
(0, import_node_fs51.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
21028
21213
|
for (const suffix of ["-wal", "-shm"]) {
|
|
21029
21214
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
21030
|
-
if ((0,
|
|
21215
|
+
if ((0, import_node_fs51.existsSync)(src)) {
|
|
21031
21216
|
try {
|
|
21032
|
-
(0,
|
|
21217
|
+
(0, import_node_fs51.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
21033
21218
|
} catch {
|
|
21034
21219
|
}
|
|
21035
21220
|
}
|
|
@@ -21047,7 +21232,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
21047
21232
|
).get(workspaceId);
|
|
21048
21233
|
if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
|
|
21049
21234
|
const worktreePath = String(row.workspacePath);
|
|
21050
|
-
if (!(0,
|
|
21235
|
+
if (!(0, import_node_fs51.existsSync)(worktreePath)) {
|
|
21051
21236
|
throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
|
|
21052
21237
|
}
|
|
21053
21238
|
let sessionId = null;
|
|
@@ -21110,31 +21295,31 @@ function importConductorWorkspace(workspaceId) {
|
|
|
21110
21295
|
db.close();
|
|
21111
21296
|
}
|
|
21112
21297
|
} finally {
|
|
21113
|
-
(0,
|
|
21298
|
+
(0, import_node_fs51.rmSync)(tmp, { recursive: true, force: true });
|
|
21114
21299
|
}
|
|
21115
21300
|
}
|
|
21116
21301
|
async function importConductorWorkspaceAsync(workspaceId) {
|
|
21117
21302
|
return importConductorWorkspace(workspaceId);
|
|
21118
21303
|
}
|
|
21119
|
-
var import_node_child_process6,
|
|
21304
|
+
var import_node_child_process6, import_node_fs51, import_node_os14, import_node_path49, import_node_module5, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
|
|
21120
21305
|
var init_adopt = __esm({
|
|
21121
21306
|
"src/threads/adopt.ts"() {
|
|
21122
21307
|
"use strict";
|
|
21123
21308
|
import_node_child_process6 = require("child_process");
|
|
21124
|
-
|
|
21309
|
+
import_node_fs51 = require("fs");
|
|
21125
21310
|
import_node_os14 = require("os");
|
|
21126
|
-
|
|
21311
|
+
import_node_path49 = require("path");
|
|
21127
21312
|
import_node_module5 = require("module");
|
|
21128
21313
|
init_worktree();
|
|
21129
21314
|
init_thread_store();
|
|
21130
|
-
CONDUCTOR_APP_SUPPORT = (0,
|
|
21315
|
+
CONDUCTOR_APP_SUPPORT = (0, import_node_path49.join)(
|
|
21131
21316
|
process.env.HOME ?? "",
|
|
21132
21317
|
"Library",
|
|
21133
21318
|
"Application Support",
|
|
21134
21319
|
"com.conductor.app"
|
|
21135
21320
|
);
|
|
21136
|
-
CONDUCTOR_DB = (0,
|
|
21137
|
-
CURSOR_SDK_STORE = (0,
|
|
21321
|
+
CONDUCTOR_DB = (0, import_node_path49.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
21322
|
+
CURSOR_SDK_STORE = (0, import_node_path49.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
21138
21323
|
}
|
|
21139
21324
|
});
|
|
21140
21325
|
|
|
@@ -21201,7 +21386,7 @@ async function openStackLayer(input, _onSetupLine) {
|
|
|
21201
21386
|
let createdWorktree = false;
|
|
21202
21387
|
const trees = await listWorktrees(repoPath);
|
|
21203
21388
|
const checkedOut = trees.find((w) => w.branch === branchName);
|
|
21204
|
-
if (checkedOut?.path && (0,
|
|
21389
|
+
if (checkedOut?.path && (0, import_node_fs52.existsSync)(checkedOut.path)) {
|
|
21205
21390
|
if (input.reuseExistingWorktree !== false) {
|
|
21206
21391
|
worktreePath = checkedOut.path;
|
|
21207
21392
|
} else {
|
|
@@ -21343,7 +21528,7 @@ async function initStackFromThread(input, onSetupLine) {
|
|
|
21343
21528
|
async function createPrStack(input, onSetupLine) {
|
|
21344
21529
|
await requireAgent(input.agent);
|
|
21345
21530
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
21346
|
-
if (!(0,
|
|
21531
|
+
if (!(0, import_node_fs52.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
|
|
21347
21532
|
if (!input.branches.length) throw new Error("At least one branch name required");
|
|
21348
21533
|
const status = await detectGhStack(repoPath);
|
|
21349
21534
|
if (!status.available) throw new Error(status.reason);
|
|
@@ -21410,7 +21595,7 @@ async function createPrStack(input, onSetupLine) {
|
|
|
21410
21595
|
}
|
|
21411
21596
|
}
|
|
21412
21597
|
const claimed = new Set(threads.map((t) => t.worktreePath));
|
|
21413
|
-
if (!claimed.has(bootstrap.worktreePath) && (0,
|
|
21598
|
+
if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs52.existsSync)(bootstrap.worktreePath)) {
|
|
21414
21599
|
try {
|
|
21415
21600
|
await removeWorktree(repoPath, bootstrap.worktreePath, {
|
|
21416
21601
|
deleteBranch: bootstrap.branchName
|
|
@@ -21430,11 +21615,11 @@ function stackAgentDefaultsFrom(input) {
|
|
|
21430
21615
|
planMode: input.planMode
|
|
21431
21616
|
};
|
|
21432
21617
|
}
|
|
21433
|
-
var
|
|
21618
|
+
var import_node_fs52;
|
|
21434
21619
|
var init_stack_layers = __esm({
|
|
21435
21620
|
"src/threads/stack-layers.ts"() {
|
|
21436
21621
|
"use strict";
|
|
21437
|
-
|
|
21622
|
+
import_node_fs52 = require("fs");
|
|
21438
21623
|
init_detect();
|
|
21439
21624
|
init_run();
|
|
21440
21625
|
init_stack();
|
|
@@ -21447,7 +21632,7 @@ var init_stack_layers = __esm({
|
|
|
21447
21632
|
|
|
21448
21633
|
// src/diff/diff.ts
|
|
21449
21634
|
async function inspectGitWorktree(worktreePath) {
|
|
21450
|
-
if (!worktreePath || !(0,
|
|
21635
|
+
if (!worktreePath || !(0, import_node_fs53.existsSync)(worktreePath)) return "missing_worktree";
|
|
21451
21636
|
const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
|
|
21452
21637
|
reject: false
|
|
21453
21638
|
});
|
|
@@ -21455,7 +21640,7 @@ async function inspectGitWorktree(worktreePath) {
|
|
|
21455
21640
|
return "ok";
|
|
21456
21641
|
}
|
|
21457
21642
|
async function initializeGitRepository(worktreePath) {
|
|
21458
|
-
if (!worktreePath || !(0,
|
|
21643
|
+
if (!worktreePath || !(0, import_node_fs53.existsSync)(worktreePath)) {
|
|
21459
21644
|
throw new Error("Worktree not found");
|
|
21460
21645
|
}
|
|
21461
21646
|
const status = await inspectGitWorktree(worktreePath);
|
|
@@ -21589,11 +21774,11 @@ new file mode 100644
|
|
|
21589
21774
|
};
|
|
21590
21775
|
}
|
|
21591
21776
|
async function untrackedPatch(worktreePath, path2, maxHunk) {
|
|
21592
|
-
const abs = (0,
|
|
21777
|
+
const abs = (0, import_node_path50.join)(worktreePath, path2);
|
|
21593
21778
|
try {
|
|
21594
|
-
const st = (0,
|
|
21779
|
+
const st = (0, import_node_fs53.statSync)(abs);
|
|
21595
21780
|
if (st.isFile() && st.size > maxHunk) {
|
|
21596
|
-
const buf = (0,
|
|
21781
|
+
const buf = (0, import_node_fs53.readFileSync)(abs).subarray(0, maxHunk);
|
|
21597
21782
|
return syntheticAddPatch(path2, buf.toString("utf8"), maxHunk);
|
|
21598
21783
|
}
|
|
21599
21784
|
} catch {
|
|
@@ -22060,9 +22245,9 @@ async function getDiff(worktreePath, repoPath, opts) {
|
|
|
22060
22245
|
}
|
|
22061
22246
|
function statWorktreePath(worktreePath, relativePath) {
|
|
22062
22247
|
assertSafeRelativePath(relativePath);
|
|
22063
|
-
const abs = (0,
|
|
22064
|
-
if (!(0,
|
|
22065
|
-
const st = (0,
|
|
22248
|
+
const abs = (0, import_node_path50.join)(worktreePath, relativePath);
|
|
22249
|
+
if (!(0, import_node_fs53.existsSync)(abs)) return "missing";
|
|
22250
|
+
const st = (0, import_node_fs53.statSync)(abs);
|
|
22066
22251
|
if (st.isDirectory()) return "dir";
|
|
22067
22252
|
if (st.isFile()) return "file";
|
|
22068
22253
|
return "missing";
|
|
@@ -22091,8 +22276,8 @@ function isImageRelativePath(relativePath) {
|
|
|
22091
22276
|
function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
22092
22277
|
assertSafeRelativePath(relativePath);
|
|
22093
22278
|
const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
|
|
22094
|
-
const abs = (0,
|
|
22095
|
-
const st = (0,
|
|
22279
|
+
const abs = (0, import_node_path50.join)(worktreePath, relativePath);
|
|
22280
|
+
const st = (0, import_node_fs53.statSync)(abs);
|
|
22096
22281
|
if (!st.isFile()) {
|
|
22097
22282
|
throw new Error(`Not a file: ${relativePath}`);
|
|
22098
22283
|
}
|
|
@@ -22101,7 +22286,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
22101
22286
|
`File too large to upload (${st.size} bytes; max ${maxBytes})`
|
|
22102
22287
|
);
|
|
22103
22288
|
}
|
|
22104
|
-
const buf = (0,
|
|
22289
|
+
const buf = (0, import_node_fs53.readFileSync)(abs);
|
|
22105
22290
|
return {
|
|
22106
22291
|
path: relativePath,
|
|
22107
22292
|
contentBase64: buf.toString("base64"),
|
|
@@ -22111,12 +22296,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
22111
22296
|
function readWorktreeFile(worktreePath, relativePath, opts) {
|
|
22112
22297
|
assertSafeRelativePath(relativePath);
|
|
22113
22298
|
const maxBytes = opts?.maxBytes ?? 2e5;
|
|
22114
|
-
const abs = (0,
|
|
22115
|
-
const st = (0,
|
|
22299
|
+
const abs = (0, import_node_path50.join)(worktreePath, relativePath);
|
|
22300
|
+
const st = (0, import_node_fs53.statSync)(abs);
|
|
22116
22301
|
if (!st.isFile()) {
|
|
22117
22302
|
throw new Error(`Not a file: ${relativePath}`);
|
|
22118
22303
|
}
|
|
22119
|
-
const buf = (0,
|
|
22304
|
+
const buf = (0, import_node_fs53.readFileSync)(abs);
|
|
22120
22305
|
if (isImageRelativePath(relativePath)) {
|
|
22121
22306
|
const maxImageBytes = Math.max(maxBytes, 15e6);
|
|
22122
22307
|
const truncated2 = buf.length > maxImageBytes;
|
|
@@ -22159,9 +22344,9 @@ function assertSafeRelativePath(relativePath) {
|
|
|
22159
22344
|
}
|
|
22160
22345
|
function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
22161
22346
|
assertSafeRelativePath(relativePath);
|
|
22162
|
-
const abs = (0,
|
|
22163
|
-
(0,
|
|
22164
|
-
(0,
|
|
22347
|
+
const abs = (0, import_node_path50.join)(worktreePath, relativePath);
|
|
22348
|
+
(0, import_node_fs53.mkdirSync)((0, import_node_path50.dirname)(abs), { recursive: true });
|
|
22349
|
+
(0, import_node_fs53.writeFileSync)(abs, content, "utf8");
|
|
22165
22350
|
return { path: relativePath };
|
|
22166
22351
|
}
|
|
22167
22352
|
async function getWorktreeDirtyStat(worktreePath) {
|
|
@@ -22201,12 +22386,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
|
22201
22386
|
truncated: full.files.length > maxFiles
|
|
22202
22387
|
};
|
|
22203
22388
|
}
|
|
22204
|
-
var
|
|
22389
|
+
var import_node_fs53, import_node_path50, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
|
|
22205
22390
|
var init_diff = __esm({
|
|
22206
22391
|
"src/diff/diff.ts"() {
|
|
22207
22392
|
"use strict";
|
|
22208
|
-
|
|
22209
|
-
|
|
22393
|
+
import_node_fs53 = require("fs");
|
|
22394
|
+
import_node_path50 = require("path");
|
|
22210
22395
|
init_run();
|
|
22211
22396
|
init_worktree();
|
|
22212
22397
|
mergeBaseCache = /* @__PURE__ */ new Map();
|
|
@@ -22563,7 +22748,7 @@ function parseFrontmatter(content) {
|
|
|
22563
22748
|
}
|
|
22564
22749
|
function readSkill(skillMd, source) {
|
|
22565
22750
|
try {
|
|
22566
|
-
const content = (0,
|
|
22751
|
+
const content = (0, import_node_fs54.readFileSync)(skillMd, "utf8");
|
|
22567
22752
|
const { name: fmName, description } = parseFrontmatter(content);
|
|
22568
22753
|
const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
|
|
22569
22754
|
const name = fmName || dirName;
|
|
@@ -22582,19 +22767,19 @@ function readSkill(skillMd, source) {
|
|
|
22582
22767
|
}
|
|
22583
22768
|
}
|
|
22584
22769
|
function scanSkillsDir(dir, source, out) {
|
|
22585
|
-
if (!(0,
|
|
22770
|
+
if (!(0, import_node_fs54.existsSync)(dir)) return;
|
|
22586
22771
|
let entries;
|
|
22587
22772
|
try {
|
|
22588
|
-
entries = (0,
|
|
22773
|
+
entries = (0, import_node_fs54.readdirSync)(dir);
|
|
22589
22774
|
} catch {
|
|
22590
22775
|
return;
|
|
22591
22776
|
}
|
|
22592
22777
|
for (const entry of entries) {
|
|
22593
22778
|
if (entry.startsWith(".")) continue;
|
|
22594
|
-
const skillMd = (0,
|
|
22595
|
-
if (!(0,
|
|
22779
|
+
const skillMd = (0, import_node_path51.join)(dir, entry, "SKILL.md");
|
|
22780
|
+
if (!(0, import_node_fs54.existsSync)(skillMd)) continue;
|
|
22596
22781
|
try {
|
|
22597
|
-
if (!(0,
|
|
22782
|
+
if (!(0, import_node_fs54.statSync)(skillMd).isFile()) continue;
|
|
22598
22783
|
} catch {
|
|
22599
22784
|
continue;
|
|
22600
22785
|
}
|
|
@@ -22603,24 +22788,24 @@ function scanSkillsDir(dir, source, out) {
|
|
|
22603
22788
|
}
|
|
22604
22789
|
}
|
|
22605
22790
|
function scanClaudePluginSkills(pluginsRoot, out) {
|
|
22606
|
-
if (!(0,
|
|
22791
|
+
if (!(0, import_node_fs54.existsSync)(pluginsRoot)) return;
|
|
22607
22792
|
const walk = (dir, depth, lookingForSkillsDir) => {
|
|
22608
22793
|
if (depth > 7) return;
|
|
22609
22794
|
let entries;
|
|
22610
22795
|
try {
|
|
22611
|
-
entries = (0,
|
|
22796
|
+
entries = (0, import_node_fs54.readdirSync)(dir);
|
|
22612
22797
|
} catch {
|
|
22613
22798
|
return;
|
|
22614
22799
|
}
|
|
22615
22800
|
if (lookingForSkillsDir && entries.includes("SKILL.md")) {
|
|
22616
|
-
const skill = readSkill((0,
|
|
22801
|
+
const skill = readSkill((0, import_node_path51.join)(dir, "SKILL.md"), "cli");
|
|
22617
22802
|
if (skill) out.push(skill);
|
|
22618
22803
|
}
|
|
22619
22804
|
for (const entry of entries) {
|
|
22620
22805
|
if (entry === "node_modules" || entry === ".git") continue;
|
|
22621
|
-
const full = (0,
|
|
22806
|
+
const full = (0, import_node_path51.join)(dir, entry);
|
|
22622
22807
|
try {
|
|
22623
|
-
if (!(0,
|
|
22808
|
+
if (!(0, import_node_fs54.statSync)(full).isDirectory()) continue;
|
|
22624
22809
|
} catch {
|
|
22625
22810
|
continue;
|
|
22626
22811
|
}
|
|
@@ -22638,17 +22823,17 @@ function discoverSkills(worktreePath) {
|
|
|
22638
22823
|
const home = (0, import_node_os15.homedir)();
|
|
22639
22824
|
const collected = [];
|
|
22640
22825
|
for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
|
|
22641
|
-
scanSkillsDir((0,
|
|
22826
|
+
scanSkillsDir((0, import_node_path51.join)(worktreePath, rel), "workspace", collected);
|
|
22642
22827
|
}
|
|
22643
22828
|
for (const abs of [
|
|
22644
|
-
(0,
|
|
22645
|
-
(0,
|
|
22646
|
-
(0,
|
|
22647
|
-
(0,
|
|
22829
|
+
(0, import_node_path51.join)(home, ".claude/skills"),
|
|
22830
|
+
(0, import_node_path51.join)(home, ".cursor/skills"),
|
|
22831
|
+
(0, import_node_path51.join)(home, ".sideboard/skills"),
|
|
22832
|
+
(0, import_node_path51.join)(home, ".brightsy/skills")
|
|
22648
22833
|
]) {
|
|
22649
22834
|
scanSkillsDir(abs, "user", collected);
|
|
22650
22835
|
}
|
|
22651
|
-
scanClaudePluginSkills((0,
|
|
22836
|
+
scanClaudePluginSkills((0, import_node_path51.join)(home, ".claude/plugins"), collected);
|
|
22652
22837
|
collected.push(...bundledSkills());
|
|
22653
22838
|
const rank = {
|
|
22654
22839
|
workspace: 0,
|
|
@@ -22674,7 +22859,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
|
|
|
22674
22859
|
\u2026(truncated)` : body;
|
|
22675
22860
|
}
|
|
22676
22861
|
}
|
|
22677
|
-
const raw = (0,
|
|
22862
|
+
const raw = (0, import_node_fs54.readFileSync)(skillPath, "utf8");
|
|
22678
22863
|
if (raw.startsWith("---")) {
|
|
22679
22864
|
const end = raw.indexOf("\n---", 3);
|
|
22680
22865
|
if (end >= 0) {
|
|
@@ -22688,13 +22873,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
|
|
|
22688
22873
|
|
|
22689
22874
|
\u2026(truncated)` : raw;
|
|
22690
22875
|
}
|
|
22691
|
-
var
|
|
22876
|
+
var import_node_fs54, import_node_os15, import_node_path51, BUNDLED_SKILL_PREFIX;
|
|
22692
22877
|
var init_discover = __esm({
|
|
22693
22878
|
"src/skills/discover.ts"() {
|
|
22694
22879
|
"use strict";
|
|
22695
|
-
|
|
22880
|
+
import_node_fs54 = require("fs");
|
|
22696
22881
|
import_node_os15 = require("os");
|
|
22697
|
-
|
|
22882
|
+
import_node_path51 = require("path");
|
|
22698
22883
|
init_long_running();
|
|
22699
22884
|
BUNDLED_SKILL_PREFIX = "bundled:";
|
|
22700
22885
|
}
|
|
@@ -22849,7 +23034,7 @@ function compiledModuleDir() {
|
|
|
22849
23034
|
try {
|
|
22850
23035
|
const url = import_meta4.url;
|
|
22851
23036
|
if (typeof url === "string" && url.length > 0) {
|
|
22852
|
-
return (0,
|
|
23037
|
+
return (0, import_node_path52.dirname)((0, import_node_url4.fileURLToPath)(url));
|
|
22853
23038
|
}
|
|
22854
23039
|
} catch {
|
|
22855
23040
|
}
|
|
@@ -22857,8 +23042,8 @@ function compiledModuleDir() {
|
|
|
22857
23042
|
}
|
|
22858
23043
|
function detachedJobScriptIn(dir) {
|
|
22859
23044
|
for (const name of DETACHED_JOB_FILENAMES) {
|
|
22860
|
-
const script = (0,
|
|
22861
|
-
if ((0,
|
|
23045
|
+
const script = (0, import_node_path52.join)(dir, "scripts", name);
|
|
23046
|
+
if ((0, import_node_fs55.existsSync)(script)) return script;
|
|
22862
23047
|
}
|
|
22863
23048
|
return null;
|
|
22864
23049
|
}
|
|
@@ -22875,7 +23060,7 @@ function resolveDetachedJobScript() {
|
|
|
22875
23060
|
for (let i = 0; i < 8; i++) {
|
|
22876
23061
|
const candidate = detachedJobScriptIn(dir);
|
|
22877
23062
|
if (candidate) return candidate;
|
|
22878
|
-
const parent = (0,
|
|
23063
|
+
const parent = (0, import_node_path52.dirname)(dir);
|
|
22879
23064
|
if (parent === dir) break;
|
|
22880
23065
|
dir = parent;
|
|
22881
23066
|
}
|
|
@@ -22886,12 +23071,12 @@ function formatDetachedJobInvoke(scriptPath) {
|
|
|
22886
23071
|
if (resolved) return `node ${JSON.stringify(resolved)}`;
|
|
22887
23072
|
return "node scripts/detached-job.cjs";
|
|
22888
23073
|
}
|
|
22889
|
-
var
|
|
23074
|
+
var import_node_fs55, import_node_path52, import_node_url4, import_meta4, DETACHED_JOB_FILENAMES;
|
|
22890
23075
|
var init_detached_job_path = __esm({
|
|
22891
23076
|
"src/skills/detached-job-path.ts"() {
|
|
22892
23077
|
"use strict";
|
|
22893
|
-
|
|
22894
|
-
|
|
23078
|
+
import_node_fs55 = require("fs");
|
|
23079
|
+
import_node_path52 = require("path");
|
|
22895
23080
|
import_node_url4 = require("url");
|
|
22896
23081
|
init_packaged_runtime();
|
|
22897
23082
|
import_meta4 = {};
|
|
@@ -22992,9 +23177,9 @@ function formatWorktreeDirective(thread, opts) {
|
|
|
22992
23177
|
);
|
|
22993
23178
|
} else {
|
|
22994
23179
|
const slug = opts?.githubSlug ?? "<origin-owner/name>";
|
|
22995
|
-
const
|
|
23180
|
+
const resolve2 = opts?.githubSlug ? "" : " Resolve `<origin-owner/name>` with `git remote get-url origin` in this worktree.";
|
|
22996
23181
|
lines.push(
|
|
22997
|
-
`- Prefer a draft PR first: \`gh pr create --draft -R ${slug}\` (update via \`gh pr edit -R ${slug}\`). Always pass \`-R\` \u2014 bare \`gh pr create\` may target upstream on dual-remote checkouts.${
|
|
23182
|
+
`- Prefer a draft PR first: \`gh pr create --draft -R ${slug}\` (update via \`gh pr edit -R ${slug}\`). Always pass \`-R\` \u2014 bare \`gh pr create\` may target upstream on dual-remote checkouts.${resolve2} Mark ready for review only when asked. If GitHub rejects the body as too long, retry with a short \`--body-file\` \u2014 do not paste a changelog or diff into \`--body\`.`
|
|
22998
23183
|
);
|
|
22999
23184
|
}
|
|
23000
23185
|
lines.push(
|
|
@@ -23103,9 +23288,9 @@ function formatPrGateDirective() {
|
|
|
23103
23288
|
}
|
|
23104
23289
|
function formatProcessGuideDirective(opts) {
|
|
23105
23290
|
const worktree = opts?.worktreePath?.trim();
|
|
23106
|
-
const hasGraphSkill = !!worktree && (0,
|
|
23107
|
-
const hasReviewSkill = !!worktree && (0,
|
|
23108
|
-
const hasInstallSkill = !!worktree && (0,
|
|
23291
|
+
const hasGraphSkill = !!worktree && (0, import_node_fs56.existsSync)((0, import_node_path53.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
|
|
23292
|
+
const hasReviewSkill = !!worktree && (0, import_node_fs56.existsSync)((0, import_node_path53.join)(worktree, ".claude/skills/review/SKILL.md"));
|
|
23293
|
+
const hasInstallSkill = !!worktree && (0, import_node_fs56.existsSync)((0, import_node_path53.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
|
|
23109
23294
|
return [
|
|
23110
23295
|
"Process guides (recurring work only):",
|
|
23111
23296
|
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,
|
|
@@ -23144,12 +23329,12 @@ function formatArtifactDirective() {
|
|
|
23144
23329
|
function formatUiReminder() {
|
|
23145
23330
|
return "Sideboard UI: markdown table is enough to read data; present_schema if they ask to edit/filter (even after markdown); present_files for the file manager. html fence or present_artifact, not both for the same document. type=log appends (same artifact_id, new lines only). ask_user only for a real multiple-choice (not hellos, \u201Cwhat next?\u201D, or after a review) \u2014 reply in chat. ask_user wakes the parent orchestrator; notify_orchestrator if blocked without a picker. Do not say artifacts/CMS UI are unavailable. Dev / preview: run_dev_script (same as the Dev button) returns {url, port, preview} (SIDEBOARD_PORT \u2014 never guess :3000). preview=url \u2192 open url; preview=window \u2192 Electron window is the app, url is renderer/HMR only. list_run_scripts active[].url if already running; get_run_log for the Run-tab terminal; stop_dev_script to stop.";
|
|
23146
23331
|
}
|
|
23147
|
-
var
|
|
23332
|
+
var import_node_fs56, import_node_path53, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
|
|
23148
23333
|
var init_instructions = __esm({
|
|
23149
23334
|
"src/agents/instructions.ts"() {
|
|
23150
23335
|
"use strict";
|
|
23151
|
-
|
|
23152
|
-
|
|
23336
|
+
import_node_fs56 = require("fs");
|
|
23337
|
+
import_node_path53 = require("path");
|
|
23153
23338
|
init_git_auth_mode();
|
|
23154
23339
|
init_branch_prefix();
|
|
23155
23340
|
init_worktree_labels();
|
|
@@ -23535,40 +23720,40 @@ __export(plan_file_exports, {
|
|
|
23535
23720
|
writePlanFile: () => writePlanFile
|
|
23536
23721
|
});
|
|
23537
23722
|
function ensureAttachmentsGitignore(worktreePath) {
|
|
23538
|
-
const gitignoreAbs = (0,
|
|
23539
|
-
if ((0,
|
|
23540
|
-
(0,
|
|
23541
|
-
(0,
|
|
23723
|
+
const gitignoreAbs = (0, import_node_path54.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
|
|
23724
|
+
if ((0, import_node_fs57.existsSync)(gitignoreAbs)) return;
|
|
23725
|
+
(0, import_node_fs57.mkdirSync)((0, import_node_path54.dirname)(gitignoreAbs), { recursive: true });
|
|
23726
|
+
(0, import_node_fs57.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
|
|
23542
23727
|
}
|
|
23543
23728
|
function planFileAbs(worktreePath) {
|
|
23544
|
-
return (0,
|
|
23729
|
+
return (0, import_node_path54.join)(worktreePath, PLAN_FILE_REL);
|
|
23545
23730
|
}
|
|
23546
23731
|
function readTextIfPresent2(abs) {
|
|
23547
|
-
if (!(0,
|
|
23732
|
+
if (!(0, import_node_fs57.existsSync)(abs)) return null;
|
|
23548
23733
|
try {
|
|
23549
|
-
const content = (0,
|
|
23734
|
+
const content = (0, import_node_fs57.readFileSync)(abs, "utf8");
|
|
23550
23735
|
return content.trim() ? content : null;
|
|
23551
23736
|
} catch {
|
|
23552
23737
|
return null;
|
|
23553
23738
|
}
|
|
23554
23739
|
}
|
|
23555
23740
|
function readPlanFile(worktreePath) {
|
|
23556
|
-
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0,
|
|
23741
|
+
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path54.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path54.join)(worktreePath, LEGACY_PLAN_FILE_REL));
|
|
23557
23742
|
}
|
|
23558
23743
|
function writePlanFile(worktreePath, content) {
|
|
23559
23744
|
ensureAttachmentsGitignore(worktreePath);
|
|
23560
23745
|
const abs = planFileAbs(worktreePath);
|
|
23561
|
-
(0,
|
|
23746
|
+
(0, import_node_fs57.mkdirSync)((0, import_node_path54.dirname)(abs), { recursive: true });
|
|
23562
23747
|
const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
|
|
23563
|
-
(0,
|
|
23748
|
+
(0, import_node_fs57.writeFileSync)(abs, body, "utf8");
|
|
23564
23749
|
return PLAN_FILE_REL;
|
|
23565
23750
|
}
|
|
23566
|
-
var
|
|
23751
|
+
var import_node_fs57, import_node_path54;
|
|
23567
23752
|
var init_plan_file = __esm({
|
|
23568
23753
|
"src/plan/plan-file.ts"() {
|
|
23569
23754
|
"use strict";
|
|
23570
|
-
|
|
23571
|
-
|
|
23755
|
+
import_node_fs57 = require("fs");
|
|
23756
|
+
import_node_path54 = require("path");
|
|
23572
23757
|
init_workspace_scratch();
|
|
23573
23758
|
init_plan_present();
|
|
23574
23759
|
init_plan_present();
|
|
@@ -23630,9 +23815,9 @@ function recoverFinishedCursorRun(opts) {
|
|
|
23630
23815
|
return best;
|
|
23631
23816
|
}
|
|
23632
23817
|
function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
|
|
23633
|
-
if (!(0,
|
|
23818
|
+
if (!(0, import_node_fs58.existsSync)(runsPath)) return null;
|
|
23634
23819
|
try {
|
|
23635
|
-
const lines = (0,
|
|
23820
|
+
const lines = (0, import_node_fs58.readFileSync)(runsPath, "utf8").split("\n");
|
|
23636
23821
|
let best = null;
|
|
23637
23822
|
for (const line of lines) {
|
|
23638
23823
|
const trimmed = line.trim();
|
|
@@ -23658,11 +23843,11 @@ function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
|
|
|
23658
23843
|
return null;
|
|
23659
23844
|
}
|
|
23660
23845
|
}
|
|
23661
|
-
var
|
|
23846
|
+
var import_node_fs58;
|
|
23662
23847
|
var init_cursor_recover = __esm({
|
|
23663
23848
|
"src/agents/cursor-recover.ts"() {
|
|
23664
23849
|
"use strict";
|
|
23665
|
-
|
|
23850
|
+
import_node_fs58 = require("fs");
|
|
23666
23851
|
init_cursor_store();
|
|
23667
23852
|
}
|
|
23668
23853
|
});
|
|
@@ -23816,7 +24001,7 @@ async function startOrchestration(opts) {
|
|
|
23816
24001
|
}
|
|
23817
24002
|
return updated;
|
|
23818
24003
|
}
|
|
23819
|
-
var import_node_events, import_node_crypto13,
|
|
24004
|
+
var import_node_events, import_node_crypto13, import_node_fs59, LIVE_TURN_SPAWN_GRACE_MS, RUN_SCRIPT_DESKTOP_ADOPT_MS, STALE_AGENT_PID_WAIT_MS, LIGHT_RECONCILE_THROTTLE_MS, Orchestrator, singleton;
|
|
23820
24005
|
var init_orchestrator = __esm({
|
|
23821
24006
|
"src/orchestrator/orchestrator.ts"() {
|
|
23822
24007
|
"use strict";
|
|
@@ -23824,7 +24009,7 @@ var init_orchestrator = __esm({
|
|
|
23824
24009
|
init_injected_notices();
|
|
23825
24010
|
init_task_state();
|
|
23826
24011
|
import_node_crypto13 = require("crypto");
|
|
23827
|
-
|
|
24012
|
+
import_node_fs59 = require("fs");
|
|
23828
24013
|
init_error_detail();
|
|
23829
24014
|
init_run();
|
|
23830
24015
|
init_stale_lock();
|
|
@@ -24003,7 +24188,7 @@ var init_orchestrator = __esm({
|
|
|
24003
24188
|
this.lightReconcileAt.set(repoPath, Date.now());
|
|
24004
24189
|
for (const thread of listThreads()) {
|
|
24005
24190
|
if (isGlobalThread(thread) || thread.repoPath !== repoPath) continue;
|
|
24006
|
-
if (!(0,
|
|
24191
|
+
if (!(0, import_node_fs59.existsSync)(thread.worktreePath)) {
|
|
24007
24192
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
24008
24193
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
24009
24194
|
}
|
|
@@ -24032,7 +24217,7 @@ var init_orchestrator = __esm({
|
|
|
24032
24217
|
}
|
|
24033
24218
|
continue;
|
|
24034
24219
|
}
|
|
24035
|
-
if (!(0,
|
|
24220
|
+
if (!(0, import_node_fs59.existsSync)(thread.worktreePath)) {
|
|
24036
24221
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
24037
24222
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
24038
24223
|
continue;
|
|
@@ -24200,8 +24385,8 @@ var init_orchestrator = __esm({
|
|
|
24200
24385
|
scheduleQuotaResume(threadId, resumeAt) {
|
|
24201
24386
|
this.clearQuotaResumeTimer(threadId);
|
|
24202
24387
|
updateThread(threadId, { quotaResumeAt: resumeAt.toISOString() });
|
|
24203
|
-
const
|
|
24204
|
-
const capped = Math.min(
|
|
24388
|
+
const delay2 = Math.max(5e3, resumeAt.getTime() - Date.now());
|
|
24389
|
+
const capped = Math.min(delay2, 2147483647);
|
|
24205
24390
|
const timer = setTimeout(() => {
|
|
24206
24391
|
this.quotaResumeTimers.delete(threadId);
|
|
24207
24392
|
void this.resumeAfterQuotaWait(threadId);
|
|
@@ -25256,6 +25441,7 @@ var init_orchestrator = __esm({
|
|
|
25256
25441
|
return { port: shared.devPort, scriptName: resolvedName, ports: [shared.devPort] };
|
|
25257
25442
|
}
|
|
25258
25443
|
}
|
|
25444
|
+
const preferredPorts = active?.ports?.length ? active.ports : active?.port != null ? [active.port] : void 0;
|
|
25259
25445
|
if (active && !existing) {
|
|
25260
25446
|
killListenersOnPorts(collectActiveRunPorts([active]));
|
|
25261
25447
|
this.syncWorktreeRuns(
|
|
@@ -25294,7 +25480,7 @@ var init_orchestrator = __esm({
|
|
|
25294
25480
|
thread.repoPath,
|
|
25295
25481
|
thread.worktreePath,
|
|
25296
25482
|
runOutput.push,
|
|
25297
|
-
{ scriptName: resolvedName }
|
|
25483
|
+
{ scriptName: resolvedName, preferredPorts }
|
|
25298
25484
|
);
|
|
25299
25485
|
} catch (err) {
|
|
25300
25486
|
runOutput.flush();
|
|
@@ -25743,7 +25929,7 @@ var init_orchestrator = __esm({
|
|
|
25743
25929
|
return thread;
|
|
25744
25930
|
}
|
|
25745
25931
|
const start = Date.now();
|
|
25746
|
-
return new Promise((
|
|
25932
|
+
return new Promise((resolve2, reject) => {
|
|
25747
25933
|
let settled = false;
|
|
25748
25934
|
let timer;
|
|
25749
25935
|
const finish = (fn) => {
|
|
@@ -25761,7 +25947,7 @@ var init_orchestrator = __esm({
|
|
|
25761
25947
|
finish(() => reject(new Error(`Thread not found: ${thread.id}`)));
|
|
25762
25948
|
return;
|
|
25763
25949
|
}
|
|
25764
|
-
finish(() =>
|
|
25950
|
+
finish(() => resolve2(latest));
|
|
25765
25951
|
return;
|
|
25766
25952
|
}
|
|
25767
25953
|
if (event.type === "status_changed") {
|
|
@@ -25771,7 +25957,7 @@ var init_orchestrator = __esm({
|
|
|
25771
25957
|
return;
|
|
25772
25958
|
}
|
|
25773
25959
|
if (!["running", "queued"].includes(latest.status)) {
|
|
25774
|
-
finish(() =>
|
|
25960
|
+
finish(() => resolve2(latest));
|
|
25775
25961
|
}
|
|
25776
25962
|
}
|
|
25777
25963
|
});
|
|
@@ -25783,12 +25969,12 @@ var init_orchestrator = __esm({
|
|
|
25783
25969
|
}
|
|
25784
25970
|
const current = this.healStaleReportedActivity(raw);
|
|
25785
25971
|
if (!this.threadLooksLive(current)) {
|
|
25786
|
-
finish(() =>
|
|
25972
|
+
finish(() => resolve2(current));
|
|
25787
25973
|
return;
|
|
25788
25974
|
}
|
|
25789
25975
|
if (Date.now() - start > timeoutMs) {
|
|
25790
25976
|
if (opts?.resolveIfStillRunning) {
|
|
25791
|
-
finish(() =>
|
|
25977
|
+
finish(() => resolve2(current));
|
|
25792
25978
|
} else {
|
|
25793
25979
|
finish(() => reject(new Error("wait_for_turn timed out")));
|
|
25794
25980
|
}
|
|
@@ -26380,7 +26566,7 @@ var init_orchestrator = __esm({
|
|
|
26380
26566
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
26381
26567
|
return restored2;
|
|
26382
26568
|
}
|
|
26383
|
-
if (!(0,
|
|
26569
|
+
if (!(0, import_node_fs59.existsSync)(thread.worktreePath)) {
|
|
26384
26570
|
if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
|
|
26385
26571
|
throw new Error(
|
|
26386
26572
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
@@ -26526,14 +26712,14 @@ function armOne(schedule) {
|
|
|
26526
26712
|
if (!schedule.enabled) return;
|
|
26527
26713
|
const at = new Date(schedule.nextRunAt);
|
|
26528
26714
|
if (Number.isNaN(at.getTime())) return;
|
|
26529
|
-
const
|
|
26530
|
-
if (
|
|
26715
|
+
const delay2 = Math.max(0, at.getTime() - Date.now());
|
|
26716
|
+
if (delay2 <= 250) {
|
|
26531
26717
|
void fireSchedule(schedule.id).then(() => {
|
|
26532
26718
|
if (isThisProcessDesktopHost()) armSchedules();
|
|
26533
26719
|
});
|
|
26534
26720
|
return;
|
|
26535
26721
|
}
|
|
26536
|
-
const capped = Math.min(
|
|
26722
|
+
const capped = Math.min(delay2, SET_TIMEOUT_MAX);
|
|
26537
26723
|
const timer = setTimeout(() => {
|
|
26538
26724
|
timers.delete(schedule.id);
|
|
26539
26725
|
const live = getSchedule(schedule.id);
|
|
@@ -26671,6 +26857,7 @@ __export(index_exports, {
|
|
|
26671
26857
|
PLAN_FILE_REL: () => PLAN_FILE_REL,
|
|
26672
26858
|
PLAN_MODE_INSTRUCTION: () => PLAN_MODE_INSTRUCTION,
|
|
26673
26859
|
PLAN_QUESTION_ANSWERS_PREFIX: () => PLAN_QUESTION_ANSWERS_PREFIX,
|
|
26860
|
+
PORT_RANGE_SIZE: () => PORT_RANGE_SIZE,
|
|
26674
26861
|
PROFILE_NOTES_MAX: () => PROFILE_NOTES_MAX,
|
|
26675
26862
|
PR_DETAILS_JSON_FIELDS: () => PR_DETAILS_JSON_FIELDS,
|
|
26676
26863
|
REPO_REVIEW_NAME: () => REPO_REVIEW_NAME,
|
|
@@ -26681,6 +26868,7 @@ __export(index_exports, {
|
|
|
26681
26868
|
REVIEW_REQUEST_TEMPLATE: () => REVIEW_REQUEST_TEMPLATE,
|
|
26682
26869
|
REVIEW_SKILL_NAME: () => REVIEW_SKILL_NAME,
|
|
26683
26870
|
REVIEW_SKILL_PATH: () => REVIEW_SKILL_PATH,
|
|
26871
|
+
RUN_PORTS_REL: () => RUN_PORTS_REL,
|
|
26684
26872
|
RUN_SCRIPT_DESKTOP_ADOPT_MS: () => RUN_SCRIPT_DESKTOP_ADOPT_MS,
|
|
26685
26873
|
SEED_FULL_TOOL_MESSAGES: () => SEED_FULL_TOOL_MESSAGES,
|
|
26686
26874
|
SEED_MAX_CHARS: () => SEED_MAX_CHARS,
|
|
@@ -27111,6 +27299,7 @@ __export(index_exports, {
|
|
|
27111
27299
|
isOptionalServiceId: () => isOptionalServiceId,
|
|
27112
27300
|
isOrchestratorCapableAgent: () => isOrchestratorCapableAgent,
|
|
27113
27301
|
isOrchestratorThread: () => isOrchestratorThread,
|
|
27302
|
+
isOtherWorktreeListenerCwd: () => isOtherWorktreeListenerCwd,
|
|
27114
27303
|
isPidAlive: () => isPidAlive,
|
|
27115
27304
|
isPlaceholderBranch: () => isPlaceholderBranch,
|
|
27116
27305
|
isPlanQuestionAnswersMessage: () => isPlanQuestionAnswersMessage,
|
|
@@ -27142,6 +27331,7 @@ __export(index_exports, {
|
|
|
27142
27331
|
issueSourceLabel: () => issueSourceLabel,
|
|
27143
27332
|
issueTicketFromThread: () => issueTicketFromThread,
|
|
27144
27333
|
killListenersOnPorts: () => killListenersOnPorts,
|
|
27334
|
+
killStaleWorktreeListeners: () => killStaleWorktreeListeners,
|
|
27145
27335
|
killableListenerPids: () => killableListenerPids,
|
|
27146
27336
|
lastAgentReply: () => lastAgentReply,
|
|
27147
27337
|
lastAssistantMessageText: () => lastAssistantMessageText,
|
|
@@ -27189,6 +27379,7 @@ __export(index_exports, {
|
|
|
27189
27379
|
listWorkspaces: () => listWorkspaces,
|
|
27190
27380
|
listWorktreeFiles: () => listWorktreeFiles,
|
|
27191
27381
|
listWorktrees: () => listWorktrees,
|
|
27382
|
+
listenerCwd: () => listenerCwd,
|
|
27192
27383
|
liveActivitySummary: () => liveActivitySummary,
|
|
27193
27384
|
loadAppSettings: () => loadAppSettings,
|
|
27194
27385
|
loadBrightsyConfig: () => loadBrightsyConfig,
|
|
@@ -27196,6 +27387,7 @@ __export(index_exports, {
|
|
|
27196
27387
|
loadHomeBoardInputs: () => loadHomeBoardInputs,
|
|
27197
27388
|
loadRepoSettings: () => loadRepoSettings,
|
|
27198
27389
|
loadWorkspaceSettings: () => loadWorkspaceSettings,
|
|
27390
|
+
loadWorktreeRunPorts: () => loadWorktreeRunPorts,
|
|
27199
27391
|
localhostPreviewUrl: () => localhostPreviewUrl,
|
|
27200
27392
|
locksDir: () => locksDir,
|
|
27201
27393
|
loginAgent: () => loginAgent,
|
|
@@ -27389,6 +27581,7 @@ __export(index_exports, {
|
|
|
27389
27581
|
saveAbleTimeConnection: () => saveAbleTimeConnection,
|
|
27390
27582
|
saveAppSettings: () => saveAppSettings,
|
|
27391
27583
|
saveLinearOAuth: () => saveLinearOAuth,
|
|
27584
|
+
saveWorktreeRunPorts: () => saveWorktreeRunPorts,
|
|
27392
27585
|
schedulesPath: () => schedulesPath,
|
|
27393
27586
|
scrubGithubTokensFromChildEnv: () => scrubGithubTokensFromChildEnv,
|
|
27394
27587
|
searchAbleTimeTasks: () => searchAbleTimeTasks,
|
|
@@ -27478,6 +27671,8 @@ __export(index_exports, {
|
|
|
27478
27671
|
toolFilePath: () => toolFilePath,
|
|
27479
27672
|
totalTokens: () => totalTokens,
|
|
27480
27673
|
trustSystemCertificates: () => trustSystemCertificates,
|
|
27674
|
+
tryReservePort: () => tryReservePort,
|
|
27675
|
+
tryReservePorts: () => tryReservePorts,
|
|
27481
27676
|
turnCostUsdFromCursorUsage: () => turnCostUsdFromCursorUsage,
|
|
27482
27677
|
updateAbleTimeTask: () => updateAbleTimeTask,
|
|
27483
27678
|
updateAdvancedSettings: () => updateAdvancedSettings,
|
|
@@ -27516,6 +27711,7 @@ __export(index_exports, {
|
|
|
27516
27711
|
worktreeDisplayLabel: () => worktreeDisplayLabel,
|
|
27517
27712
|
worktreeDisplayLabelForGroup: () => worktreeDisplayLabelForGroup,
|
|
27518
27713
|
worktreeNameFromPath: () => worktreeNameFromPath,
|
|
27714
|
+
worktreeRunPortsPath: () => worktreeRunPortsPath,
|
|
27519
27715
|
worktreeSlugForTicket: () => worktreeSlugForTicket,
|
|
27520
27716
|
worktreesRoot: () => worktreesRoot,
|
|
27521
27717
|
wrapReviewSkillMarkdown: () => wrapReviewSkillMarkdown,
|
|
@@ -28002,14 +28198,14 @@ async function startLinearOAuth(opts) {
|
|
|
28002
28198
|
const pkce = createLinearPkce();
|
|
28003
28199
|
const authorizeUrl = linearOAuthAuthorizeUrl(clientId, state, pkce.challenge);
|
|
28004
28200
|
const timeoutMs = opts?.timeoutMs ?? 5 * 6e4;
|
|
28005
|
-
const code = await new Promise((
|
|
28201
|
+
const code = await new Promise((resolve2, reject) => {
|
|
28006
28202
|
let settled = false;
|
|
28007
28203
|
const finish = (err, value) => {
|
|
28008
28204
|
if (settled) return;
|
|
28009
28205
|
settled = true;
|
|
28010
28206
|
cleanup();
|
|
28011
28207
|
if (err) reject(err);
|
|
28012
|
-
else
|
|
28208
|
+
else resolve2(value);
|
|
28013
28209
|
};
|
|
28014
28210
|
const server = (0, import_node_http2.createServer)((req, res) => {
|
|
28015
28211
|
try {
|
|
@@ -30171,7 +30367,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
|
30171
30367
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
30172
30368
|
var import_zod9 = require("zod");
|
|
30173
30369
|
var import_node_crypto17 = require("crypto");
|
|
30174
|
-
var
|
|
30370
|
+
var import_node_path60 = require("path");
|
|
30175
30371
|
init_orchestrator();
|
|
30176
30372
|
init_task_state();
|
|
30177
30373
|
init_worktree();
|
|
@@ -30507,8 +30703,8 @@ ${link}` : link;
|
|
|
30507
30703
|
}
|
|
30508
30704
|
|
|
30509
30705
|
// src/slack/outbound-watch.ts
|
|
30510
|
-
var
|
|
30511
|
-
var
|
|
30706
|
+
var import_node_fs61 = require("fs");
|
|
30707
|
+
var import_node_path57 = require("path");
|
|
30512
30708
|
init_paths();
|
|
30513
30709
|
init_private_file();
|
|
30514
30710
|
init_secure_file();
|
|
@@ -30516,19 +30712,19 @@ init_thread_store();
|
|
|
30516
30712
|
init_injected_notices();
|
|
30517
30713
|
|
|
30518
30714
|
// src/slack/reply-target.ts
|
|
30519
|
-
var
|
|
30520
|
-
var
|
|
30715
|
+
var import_node_fs60 = require("fs");
|
|
30716
|
+
var import_node_path55 = require("path");
|
|
30521
30717
|
init_paths();
|
|
30522
30718
|
init_private_file();
|
|
30523
30719
|
init_secure_file();
|
|
30524
30720
|
function storePath2() {
|
|
30525
|
-
return (0,
|
|
30721
|
+
return (0, import_node_path55.join)(appDataDir(), "slack-reply-to.json");
|
|
30526
30722
|
}
|
|
30527
30723
|
function readStore2() {
|
|
30528
30724
|
const path2 = storePath2();
|
|
30529
|
-
if (!(0,
|
|
30725
|
+
if (!(0, import_node_fs60.existsSync)(path2)) return {};
|
|
30530
30726
|
try {
|
|
30531
|
-
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0,
|
|
30727
|
+
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs60.readFileSync)(path2, "utf8"));
|
|
30532
30728
|
return parsed?.targets && typeof parsed.targets === "object" ? parsed.targets : {};
|
|
30533
30729
|
} catch {
|
|
30534
30730
|
return {};
|
|
@@ -30545,11 +30741,11 @@ function getSlackReplyTarget(threadId) {
|
|
|
30545
30741
|
}
|
|
30546
30742
|
|
|
30547
30743
|
// src/slack/workspaces.ts
|
|
30548
|
-
var
|
|
30744
|
+
var import_node_path56 = require("path");
|
|
30549
30745
|
init_paths();
|
|
30550
30746
|
init_secure_file();
|
|
30551
30747
|
function storePath3() {
|
|
30552
|
-
return (0,
|
|
30748
|
+
return (0, import_node_path56.join)(appDataDir(), "slack-workspaces.json");
|
|
30553
30749
|
}
|
|
30554
30750
|
function readStore3() {
|
|
30555
30751
|
try {
|
|
@@ -30665,7 +30861,7 @@ var POLL_INTERVAL_MS = 12e3;
|
|
|
30665
30861
|
var lastPollMs = 0;
|
|
30666
30862
|
var nameCache = /* @__PURE__ */ new Map();
|
|
30667
30863
|
function storePath4() {
|
|
30668
|
-
return (0,
|
|
30864
|
+
return (0, import_node_path57.join)(appDataDir(), "slack-outbound-watch.json");
|
|
30669
30865
|
}
|
|
30670
30866
|
function watchId(teamId, channelId, ts) {
|
|
30671
30867
|
return `${teamId}:${channelId}:${ts}`;
|
|
@@ -30678,9 +30874,9 @@ function tsNewer(a, b) {
|
|
|
30678
30874
|
}
|
|
30679
30875
|
function readStore4() {
|
|
30680
30876
|
const path2 = storePath4();
|
|
30681
|
-
if (!(0,
|
|
30877
|
+
if (!(0, import_node_fs61.existsSync)(path2)) return [];
|
|
30682
30878
|
try {
|
|
30683
|
-
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0,
|
|
30879
|
+
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs61.readFileSync)(path2, "utf8"));
|
|
30684
30880
|
return Array.isArray(parsed?.watches) ? parsed.watches : [];
|
|
30685
30881
|
} catch {
|
|
30686
30882
|
return [];
|
|
@@ -32431,27 +32627,27 @@ init_gh_errors();
|
|
|
32431
32627
|
init_git_auth_mode();
|
|
32432
32628
|
|
|
32433
32629
|
// src/board/load-home-board.ts
|
|
32434
|
-
var
|
|
32435
|
-
var
|
|
32630
|
+
var import_node_fs63 = require("fs");
|
|
32631
|
+
var import_node_path59 = require("path");
|
|
32436
32632
|
init_worktree();
|
|
32437
32633
|
init_paths();
|
|
32438
32634
|
|
|
32439
32635
|
// src/board/board-pins.ts
|
|
32440
32636
|
var import_node_crypto16 = require("crypto");
|
|
32441
|
-
var
|
|
32442
|
-
var
|
|
32637
|
+
var import_node_fs62 = require("fs");
|
|
32638
|
+
var import_node_path58 = require("path");
|
|
32443
32639
|
init_paths();
|
|
32444
32640
|
init_home_board();
|
|
32445
32641
|
var FILE = "home-board-pins.json";
|
|
32446
32642
|
var VERSION = 1;
|
|
32447
32643
|
function pinsFile() {
|
|
32448
|
-
return (0,
|
|
32644
|
+
return (0, import_node_path58.join)(appDataDir(), FILE);
|
|
32449
32645
|
}
|
|
32450
32646
|
function readDisk() {
|
|
32451
32647
|
const path2 = pinsFile();
|
|
32452
|
-
if (!(0,
|
|
32648
|
+
if (!(0, import_node_fs62.existsSync)(path2)) return [];
|
|
32453
32649
|
try {
|
|
32454
|
-
const raw = JSON.parse((0,
|
|
32650
|
+
const raw = JSON.parse((0, import_node_fs62.readFileSync)(path2, "utf8"));
|
|
32455
32651
|
if (raw?.version !== VERSION || !Array.isArray(raw.items)) return [];
|
|
32456
32652
|
return raw.items.filter((item) => item?.id && item.kind && item.ref);
|
|
32457
32653
|
} catch {
|
|
@@ -32459,8 +32655,8 @@ function readDisk() {
|
|
|
32459
32655
|
}
|
|
32460
32656
|
}
|
|
32461
32657
|
function writeDisk(items) {
|
|
32462
|
-
(0,
|
|
32463
|
-
(0,
|
|
32658
|
+
(0, import_node_fs62.mkdirSync)(appDataDir(), { recursive: true });
|
|
32659
|
+
(0, import_node_fs62.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
|
|
32464
32660
|
}
|
|
32465
32661
|
function listBoardPins() {
|
|
32466
32662
|
return readDisk();
|
|
@@ -32512,7 +32708,7 @@ function replaceBoardPins(items) {
|
|
|
32512
32708
|
}
|
|
32513
32709
|
function clearBoardPins() {
|
|
32514
32710
|
try {
|
|
32515
|
-
(0,
|
|
32711
|
+
(0, import_node_fs62.unlinkSync)(pinsFile());
|
|
32516
32712
|
} catch {
|
|
32517
32713
|
}
|
|
32518
32714
|
}
|
|
@@ -32529,7 +32725,7 @@ function homeBoardWorkspaceKey(workspaces) {
|
|
|
32529
32725
|
return workspaces.map((w) => w.path).filter(Boolean).sort().join("\n");
|
|
32530
32726
|
}
|
|
32531
32727
|
function cacheFile() {
|
|
32532
|
-
return (0,
|
|
32728
|
+
return (0, import_node_path59.join)(appDataDir(), "home-board-cache.json");
|
|
32533
32729
|
}
|
|
32534
32730
|
function emptyInputs() {
|
|
32535
32731
|
return {
|
|
@@ -32555,9 +32751,9 @@ function shouldCacheHomeBoardInputs(inputs) {
|
|
|
32555
32751
|
}
|
|
32556
32752
|
function readDiskCache() {
|
|
32557
32753
|
const path2 = cacheFile();
|
|
32558
|
-
if (!(0,
|
|
32754
|
+
if (!(0, import_node_fs63.existsSync)(path2)) return null;
|
|
32559
32755
|
try {
|
|
32560
|
-
const raw = JSON.parse((0,
|
|
32756
|
+
const raw = JSON.parse((0, import_node_fs63.readFileSync)(path2, "utf8"));
|
|
32561
32757
|
if (raw?.version !== CACHE_VERSION || typeof raw.fetchedAt !== "number") {
|
|
32562
32758
|
return null;
|
|
32563
32759
|
}
|
|
@@ -32571,14 +32767,14 @@ function readDiskCache() {
|
|
|
32571
32767
|
}
|
|
32572
32768
|
function writeDiskCache(entry) {
|
|
32573
32769
|
try {
|
|
32574
|
-
(0,
|
|
32575
|
-
(0,
|
|
32770
|
+
(0, import_node_fs63.mkdirSync)(appDataDir(), { recursive: true });
|
|
32771
|
+
(0, import_node_fs63.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
|
|
32576
32772
|
} catch {
|
|
32577
32773
|
}
|
|
32578
32774
|
}
|
|
32579
32775
|
function deleteDiskCache() {
|
|
32580
32776
|
try {
|
|
32581
|
-
(0,
|
|
32777
|
+
(0, import_node_fs63.unlinkSync)(cacheFile());
|
|
32582
32778
|
} catch {
|
|
32583
32779
|
}
|
|
32584
32780
|
}
|
|
@@ -32765,14 +32961,14 @@ function orchCreateThreadAgentNote(input) {
|
|
|
32765
32961
|
var MAX_ORCH_THREADS = 5;
|
|
32766
32962
|
var CREATE_THREAD_TIMEOUT_MS = 9e4;
|
|
32767
32963
|
function withTimeout2(promise, ms, label) {
|
|
32768
|
-
return new Promise((
|
|
32964
|
+
return new Promise((resolve2, reject) => {
|
|
32769
32965
|
const timer = setTimeout(() => {
|
|
32770
32966
|
reject(new Error(`${label} timed out after ${Math.round(ms / 1e3)}s`));
|
|
32771
32967
|
}, ms);
|
|
32772
32968
|
promise.then(
|
|
32773
32969
|
(value) => {
|
|
32774
32970
|
clearTimeout(timer);
|
|
32775
|
-
|
|
32971
|
+
resolve2(value);
|
|
32776
32972
|
},
|
|
32777
32973
|
(err) => {
|
|
32778
32974
|
clearTimeout(timer);
|
|
@@ -32944,7 +33140,7 @@ async function startMcpServer() {
|
|
|
32944
33140
|
async () => {
|
|
32945
33141
|
const threads = orch.getThreads(true);
|
|
32946
33142
|
const lines = threads.map((t) => {
|
|
32947
|
-
const repo = t.repoPath === GLOBAL_WORKSPACE_ID2 ? "Orchestration" : (0,
|
|
33143
|
+
const repo = t.repoPath === GLOBAL_WORKSPACE_ID2 ? "Orchestration" : (0, import_node_path60.basename)(t.repoPath) || t.repoPath;
|
|
32948
33144
|
const live = orch.threadLooksLive(t) ? readTurnLive(t.id) : null;
|
|
32949
33145
|
const parent = t.parentThreadId ? ` parent:${t.parentThreadId.slice(0, 8)}` : "";
|
|
32950
33146
|
const preview = lastMessagePreview(t.messages, 80);
|
|
@@ -34398,13 +34594,13 @@ async function runCloudConnect(opts) {
|
|
|
34398
34594
|
log(`poll error: ${msg}`);
|
|
34399
34595
|
}
|
|
34400
34596
|
}
|
|
34401
|
-
await new Promise((
|
|
34402
|
-
const t = setTimeout(
|
|
34597
|
+
await new Promise((resolve2) => {
|
|
34598
|
+
const t = setTimeout(resolve2, pollMs);
|
|
34403
34599
|
opts.signal?.addEventListener(
|
|
34404
34600
|
"abort",
|
|
34405
34601
|
() => {
|
|
34406
34602
|
clearTimeout(t);
|
|
34407
|
-
|
|
34603
|
+
resolve2();
|
|
34408
34604
|
},
|
|
34409
34605
|
{ once: true }
|
|
34410
34606
|
);
|
|
@@ -34612,14 +34808,14 @@ function slackOAuthAuthorizeUrl(clientId, state) {
|
|
|
34612
34808
|
return `https://slack.com/oauth/v2/authorize?${params.toString()}`;
|
|
34613
34809
|
}
|
|
34614
34810
|
function sleep(ms, signal) {
|
|
34615
|
-
return new Promise((
|
|
34811
|
+
return new Promise((resolve2, reject) => {
|
|
34616
34812
|
if (signal?.aborted) {
|
|
34617
34813
|
reject(new SlackOAuthCancelledError());
|
|
34618
34814
|
return;
|
|
34619
34815
|
}
|
|
34620
34816
|
const timer = setTimeout(() => {
|
|
34621
34817
|
signal?.removeEventListener("abort", onAbort);
|
|
34622
|
-
|
|
34818
|
+
resolve2();
|
|
34623
34819
|
}, ms);
|
|
34624
34820
|
const onAbort = () => {
|
|
34625
34821
|
clearTimeout(timer);
|
|
@@ -34811,12 +35007,12 @@ function resolveWebSocket(ctor) {
|
|
|
34811
35007
|
return nodeWebSocketCtor();
|
|
34812
35008
|
}
|
|
34813
35009
|
function wait(ms, signal) {
|
|
34814
|
-
return new Promise((
|
|
35010
|
+
return new Promise((resolve2, reject) => {
|
|
34815
35011
|
if (signal?.aborted) {
|
|
34816
35012
|
reject(new Error("aborted"));
|
|
34817
35013
|
return;
|
|
34818
35014
|
}
|
|
34819
|
-
const t = setTimeout(
|
|
35015
|
+
const t = setTimeout(resolve2, ms);
|
|
34820
35016
|
signal?.addEventListener(
|
|
34821
35017
|
"abort",
|
|
34822
35018
|
() => {
|
|
@@ -34861,14 +35057,14 @@ async function runSlackSocketMode(opts) {
|
|
|
34861
35057
|
}
|
|
34862
35058
|
}
|
|
34863
35059
|
function connectSession(ws, opts, log) {
|
|
34864
|
-
return new Promise((
|
|
35060
|
+
return new Promise((resolve2, reject) => {
|
|
34865
35061
|
let settled = false;
|
|
34866
35062
|
const finish = (err) => {
|
|
34867
35063
|
if (settled) return;
|
|
34868
35064
|
settled = true;
|
|
34869
35065
|
opts.signal?.removeEventListener("abort", onAbort);
|
|
34870
35066
|
if (err) reject(err);
|
|
34871
|
-
else
|
|
35067
|
+
else resolve2();
|
|
34872
35068
|
};
|
|
34873
35069
|
const onAbort = () => {
|
|
34874
35070
|
try {
|
|
@@ -35039,12 +35235,12 @@ var CLAIM_FALLBACK_MS = 400;
|
|
|
35039
35235
|
var BACKOFF_START_MS2 = 1e3;
|
|
35040
35236
|
var BACKOFF_MAX_MS2 = 3e4;
|
|
35041
35237
|
function wait2(ms, signal) {
|
|
35042
|
-
return new Promise((
|
|
35238
|
+
return new Promise((resolve2, reject) => {
|
|
35043
35239
|
if (signal?.aborted) {
|
|
35044
35240
|
reject(new Error("aborted"));
|
|
35045
35241
|
return;
|
|
35046
35242
|
}
|
|
35047
|
-
const t = setTimeout(
|
|
35243
|
+
const t = setTimeout(resolve2, ms);
|
|
35048
35244
|
signal?.addEventListener(
|
|
35049
35245
|
"abort",
|
|
35050
35246
|
() => {
|
|
@@ -35103,7 +35299,7 @@ async function runSlackRelayClient(opts) {
|
|
|
35103
35299
|
}
|
|
35104
35300
|
}
|
|
35105
35301
|
function connectSession2(ws, opts, log) {
|
|
35106
|
-
return new Promise((
|
|
35302
|
+
return new Promise((resolve2, reject) => {
|
|
35107
35303
|
let settled = false;
|
|
35108
35304
|
const pending = /* @__PURE__ */ new Map();
|
|
35109
35305
|
let relayAnswersClaims = false;
|
|
@@ -35137,7 +35333,7 @@ function connectSession2(ws, opts, log) {
|
|
|
35137
35333
|
stopKeepalive();
|
|
35138
35334
|
opts.signal?.removeEventListener("abort", onAbort);
|
|
35139
35335
|
if (err) reject(err);
|
|
35140
|
-
else
|
|
35336
|
+
else resolve2();
|
|
35141
35337
|
};
|
|
35142
35338
|
const onAbort = () => {
|
|
35143
35339
|
try {
|
|
@@ -36063,9 +36259,9 @@ var import_node_http4 = require("http");
|
|
|
36063
36259
|
var import_ws3 = require("ws");
|
|
36064
36260
|
|
|
36065
36261
|
// src/slack/relay-static.ts
|
|
36066
|
-
var
|
|
36262
|
+
var import_node_fs64 = require("fs");
|
|
36067
36263
|
var import_promises = require("fs/promises");
|
|
36068
|
-
var
|
|
36264
|
+
var import_node_path61 = __toESM(require("path"), 1);
|
|
36069
36265
|
var TYPES = {
|
|
36070
36266
|
".css": "text/css; charset=utf-8",
|
|
36071
36267
|
".html": "text/html; charset=utf-8",
|
|
@@ -36096,9 +36292,9 @@ function resolveStaticPath(root, requestUrl) {
|
|
|
36096
36292
|
return null;
|
|
36097
36293
|
}
|
|
36098
36294
|
if (!pathname.startsWith("/") || pathname.includes("\0")) return null;
|
|
36099
|
-
const rootResolved =
|
|
36100
|
-
const candidate =
|
|
36101
|
-
if (candidate !== rootResolved && !candidate.startsWith(rootResolved +
|
|
36295
|
+
const rootResolved = import_node_path61.default.resolve(root);
|
|
36296
|
+
const candidate = import_node_path61.default.resolve(rootResolved, `.${pathname}`);
|
|
36297
|
+
if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path61.default.sep)) {
|
|
36102
36298
|
return null;
|
|
36103
36299
|
}
|
|
36104
36300
|
return candidate;
|
|
@@ -36112,7 +36308,7 @@ async function fileSize(file) {
|
|
|
36112
36308
|
}
|
|
36113
36309
|
}
|
|
36114
36310
|
function sendFile(req, res, file, size) {
|
|
36115
|
-
const ext =
|
|
36311
|
+
const ext = import_node_path61.default.extname(file).toLowerCase();
|
|
36116
36312
|
res.writeHead(200, {
|
|
36117
36313
|
"Content-Type": TYPES[ext] ?? "application/octet-stream",
|
|
36118
36314
|
"Content-Length": size,
|
|
@@ -36122,7 +36318,7 @@ function sendFile(req, res, file, size) {
|
|
|
36122
36318
|
res.end();
|
|
36123
36319
|
return true;
|
|
36124
36320
|
}
|
|
36125
|
-
(0,
|
|
36321
|
+
(0, import_node_fs64.createReadStream)(file).pipe(res);
|
|
36126
36322
|
return true;
|
|
36127
36323
|
}
|
|
36128
36324
|
async function tryServeStatic(req, res, root) {
|
|
@@ -36131,7 +36327,7 @@ async function tryServeStatic(req, res, root) {
|
|
|
36131
36327
|
if (!candidate) return false;
|
|
36132
36328
|
const direct = await fileSize(candidate);
|
|
36133
36329
|
if (direct != null) return sendFile(req, res, candidate, direct);
|
|
36134
|
-
const asIndex =
|
|
36330
|
+
const asIndex = import_node_path61.default.join(candidate, "index.html");
|
|
36135
36331
|
const indexSize = await fileSize(asIndex);
|
|
36136
36332
|
if (indexSize != null) return sendFile(req, res, asIndex, indexSize);
|
|
36137
36333
|
return false;
|
|
@@ -36331,9 +36527,9 @@ async function startSlackRelayServer(opts) {
|
|
|
36331
36527
|
});
|
|
36332
36528
|
const port = opts.port ?? 0;
|
|
36333
36529
|
const host = opts.host ?? "0.0.0.0";
|
|
36334
|
-
await new Promise((
|
|
36530
|
+
await new Promise((resolve2, reject) => {
|
|
36335
36531
|
httpServer.once("error", reject);
|
|
36336
|
-
httpServer.listen(port, host, () =>
|
|
36532
|
+
httpServer.listen(port, host, () => resolve2());
|
|
36337
36533
|
});
|
|
36338
36534
|
const address = httpServer.address();
|
|
36339
36535
|
const boundPort = typeof address === "object" && address ? address.port : typeof port === "number" ? port : 0;
|
|
@@ -36362,11 +36558,11 @@ async function startSlackRelayServer(opts) {
|
|
|
36362
36558
|
close: async () => {
|
|
36363
36559
|
opts.signal?.removeEventListener("abort", onAbort);
|
|
36364
36560
|
ac.abort();
|
|
36365
|
-
await new Promise((
|
|
36366
|
-
wss.close(() =>
|
|
36561
|
+
await new Promise((resolve2) => {
|
|
36562
|
+
wss.close(() => resolve2());
|
|
36367
36563
|
});
|
|
36368
|
-
await new Promise((
|
|
36369
|
-
httpServer.close((err) => err ? reject(err) :
|
|
36564
|
+
await new Promise((resolve2, reject) => {
|
|
36565
|
+
httpServer.close((err) => err ? reject(err) : resolve2());
|
|
36370
36566
|
});
|
|
36371
36567
|
await socketModeDone.catch(() => void 0);
|
|
36372
36568
|
}
|
|
@@ -36462,6 +36658,7 @@ async function startSlackRelayServer(opts) {
|
|
|
36462
36658
|
PLAN_FILE_REL,
|
|
36463
36659
|
PLAN_MODE_INSTRUCTION,
|
|
36464
36660
|
PLAN_QUESTION_ANSWERS_PREFIX,
|
|
36661
|
+
PORT_RANGE_SIZE,
|
|
36465
36662
|
PROFILE_NOTES_MAX,
|
|
36466
36663
|
PR_DETAILS_JSON_FIELDS,
|
|
36467
36664
|
REPO_REVIEW_NAME,
|
|
@@ -36472,6 +36669,7 @@ async function startSlackRelayServer(opts) {
|
|
|
36472
36669
|
REVIEW_REQUEST_TEMPLATE,
|
|
36473
36670
|
REVIEW_SKILL_NAME,
|
|
36474
36671
|
REVIEW_SKILL_PATH,
|
|
36672
|
+
RUN_PORTS_REL,
|
|
36475
36673
|
RUN_SCRIPT_DESKTOP_ADOPT_MS,
|
|
36476
36674
|
SEED_FULL_TOOL_MESSAGES,
|
|
36477
36675
|
SEED_MAX_CHARS,
|
|
@@ -36902,6 +37100,7 @@ async function startSlackRelayServer(opts) {
|
|
|
36902
37100
|
isOptionalServiceId,
|
|
36903
37101
|
isOrchestratorCapableAgent,
|
|
36904
37102
|
isOrchestratorThread,
|
|
37103
|
+
isOtherWorktreeListenerCwd,
|
|
36905
37104
|
isPidAlive,
|
|
36906
37105
|
isPlaceholderBranch,
|
|
36907
37106
|
isPlanQuestionAnswersMessage,
|
|
@@ -36933,6 +37132,7 @@ async function startSlackRelayServer(opts) {
|
|
|
36933
37132
|
issueSourceLabel,
|
|
36934
37133
|
issueTicketFromThread,
|
|
36935
37134
|
killListenersOnPorts,
|
|
37135
|
+
killStaleWorktreeListeners,
|
|
36936
37136
|
killableListenerPids,
|
|
36937
37137
|
lastAgentReply,
|
|
36938
37138
|
lastAssistantMessageText,
|
|
@@ -36980,6 +37180,7 @@ async function startSlackRelayServer(opts) {
|
|
|
36980
37180
|
listWorkspaces,
|
|
36981
37181
|
listWorktreeFiles,
|
|
36982
37182
|
listWorktrees,
|
|
37183
|
+
listenerCwd,
|
|
36983
37184
|
liveActivitySummary,
|
|
36984
37185
|
loadAppSettings,
|
|
36985
37186
|
loadBrightsyConfig,
|
|
@@ -36987,6 +37188,7 @@ async function startSlackRelayServer(opts) {
|
|
|
36987
37188
|
loadHomeBoardInputs,
|
|
36988
37189
|
loadRepoSettings,
|
|
36989
37190
|
loadWorkspaceSettings,
|
|
37191
|
+
loadWorktreeRunPorts,
|
|
36990
37192
|
localhostPreviewUrl,
|
|
36991
37193
|
locksDir,
|
|
36992
37194
|
loginAgent,
|
|
@@ -37180,6 +37382,7 @@ async function startSlackRelayServer(opts) {
|
|
|
37180
37382
|
saveAbleTimeConnection,
|
|
37181
37383
|
saveAppSettings,
|
|
37182
37384
|
saveLinearOAuth,
|
|
37385
|
+
saveWorktreeRunPorts,
|
|
37183
37386
|
schedulesPath,
|
|
37184
37387
|
scrubGithubTokensFromChildEnv,
|
|
37185
37388
|
searchAbleTimeTasks,
|
|
@@ -37269,6 +37472,8 @@ async function startSlackRelayServer(opts) {
|
|
|
37269
37472
|
toolFilePath,
|
|
37270
37473
|
totalTokens,
|
|
37271
37474
|
trustSystemCertificates,
|
|
37475
|
+
tryReservePort,
|
|
37476
|
+
tryReservePorts,
|
|
37272
37477
|
turnCostUsdFromCursorUsage,
|
|
37273
37478
|
updateAbleTimeTask,
|
|
37274
37479
|
updateAdvancedSettings,
|
|
@@ -37307,6 +37512,7 @@ async function startSlackRelayServer(opts) {
|
|
|
37307
37512
|
worktreeDisplayLabel,
|
|
37308
37513
|
worktreeDisplayLabelForGroup,
|
|
37309
37514
|
worktreeNameFromPath,
|
|
37515
|
+
worktreeRunPortsPath,
|
|
37310
37516
|
worktreeSlugForTicket,
|
|
37311
37517
|
worktreesRoot,
|
|
37312
37518
|
wrapReviewSkillMarkdown,
|