@sideboard-ai/core 0.1.238 → 0.1.240
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agents-6NAPLJU2.js → agents-CDQCQVWU.js} +1 -1
- package/dist/{agents-HJU23LIF.js → agents-PBRIHUYM.js} +1 -1
- package/dist/{chunk-WRUBICEF.js → chunk-3Q4PVZ3U.js} +14 -9
- package/dist/{chunk-E6UJGLPM.js → chunk-JJSHAVJB.js} +337 -144
- package/dist/{chunk-K6UTJOE6.js → chunk-QXYWLO6W.js} +16 -10
- package/dist/{chunk-32DG3DA2.js → chunk-WPNPIDJS.js} +361 -146
- package/dist/index.cjs +539 -300
- package/dist/index.d.cts +40 -5
- package/dist/index.d.ts +40 -5
- package/dist/index.js +25 -3
- package/dist/mcp/run-stdio.cjs +506 -301
- package/dist/mcp/run-stdio.js +3 -3
- package/dist/{orchestrator-HPMDB2SG.js → orchestrator-A2Q5O4W2.js} +2 -2
- package/dist/{orchestrator-AAYKR4AI.js → orchestrator-MIIKXPHH.js} +2 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3980,12 +3980,14 @@ function skillCommandFromInput(input) {
|
|
|
3980
3980
|
}
|
|
3981
3981
|
return void 0;
|
|
3982
3982
|
}
|
|
3983
|
+
function looksLikeComposerSkillExpansion(text7) {
|
|
3984
|
+
const t = text7.trim();
|
|
3985
|
+
return /^## Skill: \//m.test(t) && /Follow this skill for the request above:/i.test(t);
|
|
3986
|
+
}
|
|
3983
3987
|
function looksLikeSkillBody(text7) {
|
|
3984
3988
|
const t = text7.trim();
|
|
3985
3989
|
if (!t) return false;
|
|
3986
|
-
if (
|
|
3987
|
-
return true;
|
|
3988
|
-
}
|
|
3990
|
+
if (looksLikeComposerSkillExpansion(t)) return true;
|
|
3989
3991
|
return skillNameFromFrontmatter(t) != null;
|
|
3990
3992
|
}
|
|
3991
3993
|
function skillNameFromFrontmatter(text7) {
|
|
@@ -4006,11 +4008,13 @@ function isCompactToolName(name) {
|
|
|
4006
4008
|
short
|
|
4007
4009
|
);
|
|
4008
4010
|
}
|
|
4009
|
-
function isContextCompactInProgress(text7) {
|
|
4010
|
-
return /^Compressing context/i.test(text7.trim());
|
|
4011
|
-
}
|
|
4012
4011
|
function isContextCompactDone(text7) {
|
|
4013
|
-
return
|
|
4012
|
+
return /\bContext compressed\b/i.test(text7.trim());
|
|
4013
|
+
}
|
|
4014
|
+
function isContextCompactInProgress(text7) {
|
|
4015
|
+
const t = text7.trim();
|
|
4016
|
+
if (isContextCompactDone(t)) return false;
|
|
4017
|
+
return /^Compressing context/i.test(t);
|
|
4014
4018
|
}
|
|
4015
4019
|
function looksLikeConversationSummary(text7) {
|
|
4016
4020
|
const t = text7.trim();
|
|
@@ -4517,7 +4521,7 @@ function applyAgentEvent(parts, event) {
|
|
|
4517
4521
|
);
|
|
4518
4522
|
}
|
|
4519
4523
|
const acc = next[next.length - 1];
|
|
4520
|
-
if (acc?.type === "text" &&
|
|
4524
|
+
if (acc?.type === "text" && looksLikeComposerSkillExpansion(acc.text)) {
|
|
4521
4525
|
next[next.length - 1] = skillToolFromTextPart(acc, `skill-${next.length}`);
|
|
4522
4526
|
} else if (acc?.type === "text" && looksLikeConversationSummary(acc.text)) {
|
|
4523
4527
|
next[next.length - 1] = compactToolPart(acc.text, `compact-${next.length}`, {
|
|
@@ -13264,10 +13268,10 @@ function eventsFromClaudeSystem(obj) {
|
|
|
13264
13268
|
if (subtype === "api_retry") {
|
|
13265
13269
|
const attempt = obj.attempt;
|
|
13266
13270
|
const max = obj.max_retries;
|
|
13267
|
-
const
|
|
13271
|
+
const delay2 = obj.retry_delay_ms;
|
|
13268
13272
|
return {
|
|
13269
13273
|
type: "thinking",
|
|
13270
|
-
data: `API retry ${attempt ?? "?"}/${max ?? "?"}${typeof
|
|
13274
|
+
data: `API retry ${attempt ?? "?"}/${max ?? "?"}${typeof delay2 === "number" ? ` (wait ${delay2}ms)` : ""}`
|
|
13271
13275
|
};
|
|
13272
13276
|
}
|
|
13273
13277
|
if (subtype === "status") {
|
|
@@ -13282,7 +13286,8 @@ function eventsFromClaudeSystem(obj) {
|
|
|
13282
13286
|
const trigger = meta.trigger ? ` (${meta.trigger})` : "";
|
|
13283
13287
|
const thinking = {
|
|
13284
13288
|
type: "thinking",
|
|
13285
|
-
data: `Context compressed${trigger}
|
|
13289
|
+
data: `Context compressed${trigger}`,
|
|
13290
|
+
replace: true
|
|
13286
13291
|
};
|
|
13287
13292
|
if (meta.postTokens != null && meta.postTokens > 0) {
|
|
13288
13293
|
return [
|
|
@@ -17481,15 +17486,76 @@ var init_request_review = __esm({
|
|
|
17481
17486
|
}
|
|
17482
17487
|
});
|
|
17483
17488
|
|
|
17489
|
+
// src/hook/worktree-run-ports.ts
|
|
17490
|
+
function worktreeRunPortsPath(worktreePath) {
|
|
17491
|
+
return (0, import_node_path44.join)(worktreePath, RUN_PORTS_REL);
|
|
17492
|
+
}
|
|
17493
|
+
function isPort(value) {
|
|
17494
|
+
return typeof value === "number" && Number.isInteger(value) && value > 0 && value <= 65535;
|
|
17495
|
+
}
|
|
17496
|
+
function parseFile(raw) {
|
|
17497
|
+
try {
|
|
17498
|
+
const parsed = JSON.parse(raw);
|
|
17499
|
+
if (!parsed || typeof parsed !== "object") return {};
|
|
17500
|
+
const scripts = parsed.scripts;
|
|
17501
|
+
if (!scripts || typeof scripts !== "object") return {};
|
|
17502
|
+
const next = {};
|
|
17503
|
+
for (const [name, ports] of Object.entries(scripts)) {
|
|
17504
|
+
if (!name || !Array.isArray(ports)) continue;
|
|
17505
|
+
const cleaned = ports.filter(isPort);
|
|
17506
|
+
if (cleaned.length) next[name] = cleaned;
|
|
17507
|
+
}
|
|
17508
|
+
return { scripts: next };
|
|
17509
|
+
} catch {
|
|
17510
|
+
return {};
|
|
17511
|
+
}
|
|
17512
|
+
}
|
|
17513
|
+
function loadWorktreeRunPorts(worktreePath, scriptName) {
|
|
17514
|
+
if (!worktreePath.trim() || !scriptName.trim()) return null;
|
|
17515
|
+
try {
|
|
17516
|
+
const raw = (0, import_node_fs44.readFileSync)(worktreeRunPortsPath(worktreePath), "utf8");
|
|
17517
|
+
const ports = parseFile(raw).scripts?.[scriptName];
|
|
17518
|
+
return ports?.length ? ports : null;
|
|
17519
|
+
} catch {
|
|
17520
|
+
return null;
|
|
17521
|
+
}
|
|
17522
|
+
}
|
|
17523
|
+
function saveWorktreeRunPorts(worktreePath, scriptName, ports) {
|
|
17524
|
+
if (!worktreePath.trim() || !scriptName.trim()) return;
|
|
17525
|
+
const cleaned = ports.filter(isPort);
|
|
17526
|
+
if (!cleaned.length) return;
|
|
17527
|
+
const path2 = worktreeRunPortsPath(worktreePath);
|
|
17528
|
+
let current = {};
|
|
17529
|
+
try {
|
|
17530
|
+
current = parseFile((0, import_node_fs44.readFileSync)(path2, "utf8"));
|
|
17531
|
+
} catch {
|
|
17532
|
+
current = {};
|
|
17533
|
+
}
|
|
17534
|
+
const scripts = { ...current.scripts ?? {} };
|
|
17535
|
+
scripts[scriptName] = cleaned;
|
|
17536
|
+
(0, import_node_fs44.mkdirSync)((0, import_node_path44.dirname)(path2), { recursive: true });
|
|
17537
|
+
(0, import_node_fs44.writeFileSync)(path2, `${JSON.stringify({ scripts }, null, 2)}
|
|
17538
|
+
`, "utf8");
|
|
17539
|
+
}
|
|
17540
|
+
var import_node_fs44, import_node_path44, RUN_PORTS_REL;
|
|
17541
|
+
var init_worktree_run_ports = __esm({
|
|
17542
|
+
"src/hook/worktree-run-ports.ts"() {
|
|
17543
|
+
"use strict";
|
|
17544
|
+
import_node_fs44 = require("fs");
|
|
17545
|
+
import_node_path44 = require("path");
|
|
17546
|
+
RUN_PORTS_REL = ".context/.sideboard/run-ports.json";
|
|
17547
|
+
}
|
|
17548
|
+
});
|
|
17549
|
+
|
|
17484
17550
|
// src/hook/conductor.ts
|
|
17485
17551
|
function matchSimpleGlob(pattern, name) {
|
|
17486
17552
|
const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
|
|
17487
17553
|
return new RegExp(`^${escaped}$`).test(name);
|
|
17488
17554
|
}
|
|
17489
17555
|
function readWorktreeInclude(repoPath) {
|
|
17490
|
-
const path2 = (0,
|
|
17491
|
-
if (!(0,
|
|
17492
|
-
return (0,
|
|
17556
|
+
const path2 = (0, import_node_path45.join)(repoPath, ".worktreeinclude");
|
|
17557
|
+
if (!(0, import_node_fs45.existsSync)(path2)) return [];
|
|
17558
|
+
return (0, import_node_fs45.readFileSync)(path2, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
17493
17559
|
}
|
|
17494
17560
|
function resolveFilesToCopy(repoPath) {
|
|
17495
17561
|
const fromInclude = readWorktreeInclude(repoPath);
|
|
@@ -17499,10 +17565,10 @@ function resolveFilesToCopy(repoPath) {
|
|
|
17499
17565
|
if (settings?.fileIncludeGlobs?.length) {
|
|
17500
17566
|
const matched = [];
|
|
17501
17567
|
try {
|
|
17502
|
-
for (const entry of (0,
|
|
17568
|
+
for (const entry of (0, import_node_fs45.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
17503
17569
|
if (!entry.isFile()) continue;
|
|
17504
17570
|
for (const glob of settings.fileIncludeGlobs) {
|
|
17505
|
-
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0,
|
|
17571
|
+
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path45.basename)(glob), entry.name)) {
|
|
17506
17572
|
matched.push(entry.name);
|
|
17507
17573
|
break;
|
|
17508
17574
|
}
|
|
@@ -17514,7 +17580,7 @@ function resolveFilesToCopy(repoPath) {
|
|
|
17514
17580
|
}
|
|
17515
17581
|
const defaults = [];
|
|
17516
17582
|
try {
|
|
17517
|
-
for (const entry of (0,
|
|
17583
|
+
for (const entry of (0, import_node_fs45.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
17518
17584
|
if (entry.isFile() && entry.name.startsWith(".env")) {
|
|
17519
17585
|
defaults.push(entry.name);
|
|
17520
17586
|
}
|
|
@@ -17528,11 +17594,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
|
|
|
17528
17594
|
const patterns = resolveFilesToCopy(repoPath);
|
|
17529
17595
|
const copied = [];
|
|
17530
17596
|
for (const rel of patterns) {
|
|
17531
|
-
const src = (0,
|
|
17532
|
-
if (!(0,
|
|
17533
|
-
const dest = (0,
|
|
17534
|
-
(0,
|
|
17535
|
-
(0,
|
|
17597
|
+
const src = (0, import_node_path45.join)(repoPath, rel);
|
|
17598
|
+
if (!(0, import_node_fs45.existsSync)(src)) continue;
|
|
17599
|
+
const dest = (0, import_node_path45.join)(worktreePath, rel);
|
|
17600
|
+
(0, import_node_fs45.mkdirSync)((0, import_node_path45.dirname)(dest), { recursive: true });
|
|
17601
|
+
(0, import_node_fs45.copyFileSync)(src, dest);
|
|
17536
17602
|
copied.push(rel);
|
|
17537
17603
|
}
|
|
17538
17604
|
return copied;
|
|
@@ -17567,7 +17633,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
|
|
|
17567
17633
|
const env = stripNestedElectronEnv({
|
|
17568
17634
|
...baseEnv ?? process.env
|
|
17569
17635
|
});
|
|
17570
|
-
const name = opts.workspaceName ?? (0,
|
|
17636
|
+
const name = opts.workspaceName ?? (0, import_node_path45.basename)(opts.worktreePath);
|
|
17571
17637
|
const ports = opts.ports ?? [];
|
|
17572
17638
|
const primary = ports[0];
|
|
17573
17639
|
env.SIDEBOARD_WORKSPACE_NAME = name;
|
|
@@ -17607,6 +17673,57 @@ function killableListenerPids(raw, selfPid = process.pid) {
|
|
|
17607
17673
|
}
|
|
17608
17674
|
return pids;
|
|
17609
17675
|
}
|
|
17676
|
+
function listUnixListenerPids(port, selfPid) {
|
|
17677
|
+
try {
|
|
17678
|
+
const raw = (0, import_node_child_process5.execFileSync)("lsof", [`-tiTCP:${port}`, "-sTCP:LISTEN"], {
|
|
17679
|
+
encoding: "utf8",
|
|
17680
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
17681
|
+
timeout: 2e3
|
|
17682
|
+
});
|
|
17683
|
+
return killableListenerPids(raw, selfPid);
|
|
17684
|
+
} catch {
|
|
17685
|
+
return [];
|
|
17686
|
+
}
|
|
17687
|
+
}
|
|
17688
|
+
function listenerCwd(pid) {
|
|
17689
|
+
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
17690
|
+
try {
|
|
17691
|
+
const raw = (0, import_node_child_process5.execFileSync)("lsof", ["-a", "-p", String(pid), "-d", "cwd", "-Fn"], {
|
|
17692
|
+
encoding: "utf8",
|
|
17693
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
17694
|
+
timeout: 2e3
|
|
17695
|
+
});
|
|
17696
|
+
for (const line of raw.split("\n")) {
|
|
17697
|
+
if (line.startsWith("n") && line.length > 1) return line.slice(1);
|
|
17698
|
+
}
|
|
17699
|
+
} catch {
|
|
17700
|
+
}
|
|
17701
|
+
return null;
|
|
17702
|
+
}
|
|
17703
|
+
function realpathOrResolve(path2) {
|
|
17704
|
+
try {
|
|
17705
|
+
return (0, import_node_fs45.realpathSync)(path2);
|
|
17706
|
+
} catch {
|
|
17707
|
+
return (0, import_node_path45.resolve)(path2);
|
|
17708
|
+
}
|
|
17709
|
+
}
|
|
17710
|
+
function isOtherWorktreeListenerCwd(cwd, worktreePath) {
|
|
17711
|
+
const wt = realpathOrResolve(worktreePath);
|
|
17712
|
+
const c = realpathOrResolve(cwd);
|
|
17713
|
+
if (c === wt || c.startsWith(wt + import_node_path45.sep)) return false;
|
|
17714
|
+
const parent = (0, import_node_path45.dirname)(wt);
|
|
17715
|
+
const thisName = (0, import_node_path45.basename)(wt);
|
|
17716
|
+
if (!thisName || c === parent) return false;
|
|
17717
|
+
if (!c.startsWith(parent + import_node_path45.sep)) return false;
|
|
17718
|
+
const first = c.slice(parent.length + 1).split(import_node_path45.sep)[0];
|
|
17719
|
+
return Boolean(first) && first !== thisName;
|
|
17720
|
+
}
|
|
17721
|
+
function signalPid(pid, signal) {
|
|
17722
|
+
try {
|
|
17723
|
+
process.kill(pid, signal);
|
|
17724
|
+
} catch {
|
|
17725
|
+
}
|
|
17726
|
+
}
|
|
17610
17727
|
function killListenersOnPorts(ports) {
|
|
17611
17728
|
const selfPid = process.pid;
|
|
17612
17729
|
for (const port of ports) {
|
|
@@ -17624,26 +17741,32 @@ function killListenersOnPorts(ports) {
|
|
|
17624
17741
|
);
|
|
17625
17742
|
continue;
|
|
17626
17743
|
}
|
|
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
|
-
}
|
|
17744
|
+
for (const pid of listUnixListenerPids(port, selfPid)) {
|
|
17745
|
+
signalPid(pid, "SIGTERM");
|
|
17642
17746
|
}
|
|
17643
17747
|
} catch {
|
|
17644
17748
|
}
|
|
17645
17749
|
}
|
|
17646
17750
|
}
|
|
17751
|
+
function killStaleWorktreeListeners(ports, worktreePath, signal = "SIGTERM") {
|
|
17752
|
+
if (!worktreePath.trim()) {
|
|
17753
|
+
killListenersOnPorts(ports);
|
|
17754
|
+
return;
|
|
17755
|
+
}
|
|
17756
|
+
if (process.platform === "win32") {
|
|
17757
|
+
killListenersOnPorts(ports);
|
|
17758
|
+
return;
|
|
17759
|
+
}
|
|
17760
|
+
const selfPid = process.pid;
|
|
17761
|
+
for (const port of ports) {
|
|
17762
|
+
if (!Number.isFinite(port) || port <= 0) continue;
|
|
17763
|
+
for (const pid of listUnixListenerPids(port, selfPid)) {
|
|
17764
|
+
const cwd = listenerCwd(pid);
|
|
17765
|
+
if (cwd && isOtherWorktreeListenerCwd(cwd, worktreePath)) continue;
|
|
17766
|
+
signalPid(pid, signal);
|
|
17767
|
+
}
|
|
17768
|
+
}
|
|
17769
|
+
}
|
|
17647
17770
|
function killScriptTree(child, ports = []) {
|
|
17648
17771
|
const pid = child.pid;
|
|
17649
17772
|
if (pid) {
|
|
@@ -17805,7 +17928,7 @@ function getRunMode(worktreePath, repoPath) {
|
|
|
17805
17928
|
return loadWorkspaceSettings(worktreePath, repoPath)?.runMode ?? "concurrent";
|
|
17806
17929
|
}
|
|
17807
17930
|
async function reservePort() {
|
|
17808
|
-
return new Promise((
|
|
17931
|
+
return new Promise((resolve2, reject) => {
|
|
17809
17932
|
const server = (0, import_node_net.createServer)();
|
|
17810
17933
|
let released = false;
|
|
17811
17934
|
const release = () => new Promise((res) => {
|
|
@@ -17822,7 +17945,7 @@ async function reservePort() {
|
|
|
17822
17945
|
void release().then(() => reject(new Error("Failed to allocate port")));
|
|
17823
17946
|
return;
|
|
17824
17947
|
}
|
|
17825
|
-
|
|
17948
|
+
resolve2({ port: addr.port, release });
|
|
17826
17949
|
});
|
|
17827
17950
|
server.on("error", reject);
|
|
17828
17951
|
});
|
|
@@ -17833,7 +17956,8 @@ async function allocatePort() {
|
|
|
17833
17956
|
return held.port;
|
|
17834
17957
|
}
|
|
17835
17958
|
async function tryReservePort(port) {
|
|
17836
|
-
|
|
17959
|
+
if (!Number.isInteger(port) || port <= 0 || port > 65535) return null;
|
|
17960
|
+
return new Promise((resolve2) => {
|
|
17837
17961
|
const server = (0, import_node_net.createServer)();
|
|
17838
17962
|
let released = false;
|
|
17839
17963
|
const release = () => new Promise((res) => {
|
|
@@ -17844,23 +17968,63 @@ async function tryReservePort(port) {
|
|
|
17844
17968
|
released = true;
|
|
17845
17969
|
server.close(() => res());
|
|
17846
17970
|
});
|
|
17847
|
-
server.once("error", () =>
|
|
17971
|
+
server.once("error", () => {
|
|
17972
|
+
try {
|
|
17973
|
+
server.close();
|
|
17974
|
+
} catch {
|
|
17975
|
+
}
|
|
17976
|
+
resolve2(null);
|
|
17977
|
+
});
|
|
17848
17978
|
server.listen(port, "127.0.0.1", () => {
|
|
17849
|
-
|
|
17979
|
+
resolve2({ port, release });
|
|
17850
17980
|
});
|
|
17851
17981
|
});
|
|
17852
17982
|
}
|
|
17853
|
-
async function
|
|
17854
|
-
const held = [
|
|
17855
|
-
const
|
|
17983
|
+
async function tryReservePorts(ports) {
|
|
17984
|
+
const held = [];
|
|
17985
|
+
for (const port of ports) {
|
|
17986
|
+
const next = await tryReservePort(port);
|
|
17987
|
+
if (!next) {
|
|
17988
|
+
await Promise.all(held.map((h) => h.release()));
|
|
17989
|
+
return null;
|
|
17990
|
+
}
|
|
17991
|
+
held.push(next);
|
|
17992
|
+
}
|
|
17993
|
+
return held;
|
|
17994
|
+
}
|
|
17995
|
+
function normalizePreferredPorts(ports, size) {
|
|
17996
|
+
if (!ports?.length) return [];
|
|
17997
|
+
const seen = /* @__PURE__ */ new Set();
|
|
17998
|
+
const out = [];
|
|
17999
|
+
for (const p of ports) {
|
|
18000
|
+
if (!Number.isInteger(p) || p <= 0 || p > 65535 || seen.has(p)) continue;
|
|
18001
|
+
seen.add(p);
|
|
18002
|
+
out.push(p);
|
|
18003
|
+
if (out.length >= size) break;
|
|
18004
|
+
}
|
|
18005
|
+
return out;
|
|
18006
|
+
}
|
|
18007
|
+
function delay(ms) {
|
|
18008
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
18009
|
+
}
|
|
18010
|
+
async function fillPortRange(held, size) {
|
|
18011
|
+
if (held.length >= size) return held;
|
|
18012
|
+
const base = held[0]?.port;
|
|
18013
|
+
const taken = new Set(held.map((h) => h.port));
|
|
17856
18014
|
try {
|
|
17857
|
-
|
|
17858
|
-
|
|
17859
|
-
const
|
|
18015
|
+
let offset = 0;
|
|
18016
|
+
while (held.length < size) {
|
|
18017
|
+
const candidate = base != null ? base + offset : null;
|
|
18018
|
+
offset += 1;
|
|
18019
|
+
if (candidate != null && taken.has(candidate)) continue;
|
|
18020
|
+
const next = candidate != null ? await tryReservePort(candidate) : null;
|
|
17860
18021
|
if (next) {
|
|
17861
18022
|
held.push(next);
|
|
18023
|
+
taken.add(next.port);
|
|
17862
18024
|
} else {
|
|
17863
|
-
|
|
18025
|
+
const ephemeral = await reservePort();
|
|
18026
|
+
held.push(ephemeral);
|
|
18027
|
+
taken.add(ephemeral.port);
|
|
17864
18028
|
}
|
|
17865
18029
|
}
|
|
17866
18030
|
return held;
|
|
@@ -17869,6 +18033,49 @@ async function reservePortRange(size = PORT_RANGE_SIZE) {
|
|
|
17869
18033
|
throw err;
|
|
17870
18034
|
}
|
|
17871
18035
|
}
|
|
18036
|
+
async function tryReserveAvailablePorts(ports) {
|
|
18037
|
+
const held = [];
|
|
18038
|
+
for (const port of ports) {
|
|
18039
|
+
const next = await tryReservePort(port);
|
|
18040
|
+
if (next) held.push(next);
|
|
18041
|
+
}
|
|
18042
|
+
return held;
|
|
18043
|
+
}
|
|
18044
|
+
async function reclaimPreferredPorts(ports, worktreePath) {
|
|
18045
|
+
const primary = ports[0];
|
|
18046
|
+
if (primary == null) return null;
|
|
18047
|
+
const takePrimary = async () => {
|
|
18048
|
+
const held2 = await tryReserveAvailablePorts(ports);
|
|
18049
|
+
if (held2.some((h) => h.port === primary)) return held2;
|
|
18050
|
+
await Promise.all(held2.map((h) => h.release()));
|
|
18051
|
+
return null;
|
|
18052
|
+
};
|
|
18053
|
+
let held = await takePrimary();
|
|
18054
|
+
if (held) return held;
|
|
18055
|
+
if (worktreePath) {
|
|
18056
|
+
killStaleWorktreeListeners(ports, worktreePath, "SIGTERM");
|
|
18057
|
+
} else {
|
|
18058
|
+
killListenersOnPorts(ports);
|
|
18059
|
+
}
|
|
18060
|
+
for (let i = 0; i < RECLAIM_TRIES; i++) {
|
|
18061
|
+
await delay(RECLAIM_RETRY_DELAY_MS);
|
|
18062
|
+
held = await takePrimary();
|
|
18063
|
+
if (held) return held;
|
|
18064
|
+
if (i === 2 && worktreePath) {
|
|
18065
|
+
killStaleWorktreeListeners(ports, worktreePath, "SIGKILL");
|
|
18066
|
+
}
|
|
18067
|
+
}
|
|
18068
|
+
return null;
|
|
18069
|
+
}
|
|
18070
|
+
async function reservePortRange(size = PORT_RANGE_SIZE, opts) {
|
|
18071
|
+
const preferred = normalizePreferredPorts(opts?.preferred, size);
|
|
18072
|
+
if (preferred.length) {
|
|
18073
|
+
const reused = await reclaimPreferredPorts(preferred, opts?.worktreePath);
|
|
18074
|
+
if (reused) return fillPortRange(reused, size);
|
|
18075
|
+
}
|
|
18076
|
+
const held = [await reservePort()];
|
|
18077
|
+
return fillPortRange(held, size);
|
|
18078
|
+
}
|
|
17872
18079
|
async function allocatePortRange(size = PORT_RANGE_SIZE) {
|
|
17873
18080
|
const held = await reservePortRange(size);
|
|
17874
18081
|
const ports = held.map((h) => h.port);
|
|
@@ -17878,8 +18085,13 @@ async function allocatePortRange(size = PORT_RANGE_SIZE) {
|
|
|
17878
18085
|
async function startDevServer(repoPath, worktreePath, onLine, opts) {
|
|
17879
18086
|
const script = getRunScript(worktreePath, repoPath, opts?.scriptName);
|
|
17880
18087
|
if (!script) return null;
|
|
17881
|
-
const
|
|
18088
|
+
const preferred = loadWorktreeRunPorts(worktreePath, script.name) ?? opts?.preferredPorts;
|
|
18089
|
+
const held = await reservePortRange(PORT_RANGE_SIZE, {
|
|
18090
|
+
preferred: preferred ?? void 0,
|
|
18091
|
+
worktreePath
|
|
18092
|
+
});
|
|
17882
18093
|
const ports = held.map((h) => h.port);
|
|
18094
|
+
saveWorktreeRunPorts(worktreePath, script.name, ports);
|
|
17883
18095
|
try {
|
|
17884
18096
|
const handle = await spawnWorkspaceScript(script.command, {
|
|
17885
18097
|
worktreePath,
|
|
@@ -17902,14 +18114,14 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
|
|
|
17902
18114
|
throw err;
|
|
17903
18115
|
}
|
|
17904
18116
|
}
|
|
17905
|
-
var
|
|
18117
|
+
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
18118
|
var init_conductor = __esm({
|
|
17907
18119
|
"src/hook/conductor.ts"() {
|
|
17908
18120
|
"use strict";
|
|
17909
|
-
|
|
18121
|
+
import_node_fs45 = require("fs");
|
|
17910
18122
|
import_node_child_process5 = require("child_process");
|
|
17911
18123
|
import_node_net = require("net");
|
|
17912
|
-
|
|
18124
|
+
import_node_path45 = require("path");
|
|
17913
18125
|
import_execa4 = require("execa");
|
|
17914
18126
|
import_node_readline3 = require("readline");
|
|
17915
18127
|
init_settings();
|
|
@@ -17920,8 +18132,12 @@ var init_conductor = __esm({
|
|
|
17920
18132
|
init_git_auth_mode();
|
|
17921
18133
|
init_request_review();
|
|
17922
18134
|
init_worktree_exclude();
|
|
18135
|
+
init_worktree_run_ports();
|
|
18136
|
+
init_worktree_run_ports();
|
|
17923
18137
|
init_nested_electron_env();
|
|
17924
18138
|
PORT_RANGE_SIZE = 10;
|
|
18139
|
+
RECLAIM_RETRY_DELAY_MS = 40;
|
|
18140
|
+
RECLAIM_TRIES = 8;
|
|
17925
18141
|
cachedLoginEnv = null;
|
|
17926
18142
|
}
|
|
17927
18143
|
});
|
|
@@ -17937,9 +18153,9 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
17937
18153
|
repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
|
|
17938
18154
|
);
|
|
17939
18155
|
const homeRoot = sideboardWorkspacesDir();
|
|
17940
|
-
if ((0,
|
|
18156
|
+
if ((0, import_node_fs46.existsSync)(homeRoot)) {
|
|
17941
18157
|
try {
|
|
17942
|
-
for (const entry of (0,
|
|
18158
|
+
for (const entry of (0, import_node_fs46.readdirSync)(homeRoot, { withFileTypes: true })) {
|
|
17943
18159
|
if (!entry.isDirectory()) continue;
|
|
17944
18160
|
void entry;
|
|
17945
18161
|
}
|
|
@@ -17949,7 +18165,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
17949
18165
|
const orphans = [];
|
|
17950
18166
|
const seen = /* @__PURE__ */ new Set();
|
|
17951
18167
|
for (const repoPath of repos) {
|
|
17952
|
-
if (!repoPath || !(0,
|
|
18168
|
+
if (!repoPath || !(0, import_node_fs46.existsSync)(repoPath)) continue;
|
|
17953
18169
|
try {
|
|
17954
18170
|
const wts = await listWorktrees(repoPath);
|
|
17955
18171
|
for (const wt of wts) {
|
|
@@ -17960,7 +18176,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
17960
18176
|
seen.add(path2);
|
|
17961
18177
|
let mtimeMs = 0;
|
|
17962
18178
|
try {
|
|
17963
|
-
mtimeMs = (0,
|
|
18179
|
+
mtimeMs = (0, import_node_fs46.statSync)(path2).mtimeMs;
|
|
17964
18180
|
} catch {
|
|
17965
18181
|
mtimeMs = 0;
|
|
17966
18182
|
}
|
|
@@ -17970,16 +18186,16 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
17970
18186
|
}
|
|
17971
18187
|
try {
|
|
17972
18188
|
const root = worktreesRoot(repoPath);
|
|
17973
|
-
if ((0,
|
|
17974
|
-
for (const entry of (0,
|
|
18189
|
+
if ((0, import_node_fs46.existsSync)(root)) {
|
|
18190
|
+
for (const entry of (0, import_node_fs46.readdirSync)(root, { withFileTypes: true })) {
|
|
17975
18191
|
if (!entry.isDirectory()) continue;
|
|
17976
|
-
const path2 = (0,
|
|
18192
|
+
const path2 = (0, import_node_path46.join)(root, entry.name).replace(/\/$/, "");
|
|
17977
18193
|
if (known.has(path2) || seen.has(path2)) continue;
|
|
17978
|
-
if (!(0,
|
|
18194
|
+
if (!(0, import_node_fs46.existsSync)((0, import_node_path46.join)(path2, ".git"))) continue;
|
|
17979
18195
|
seen.add(path2);
|
|
17980
18196
|
let mtimeMs = 0;
|
|
17981
18197
|
try {
|
|
17982
|
-
mtimeMs = (0,
|
|
18198
|
+
mtimeMs = (0, import_node_fs46.statSync)(path2).mtimeMs;
|
|
17983
18199
|
} catch {
|
|
17984
18200
|
mtimeMs = Date.now();
|
|
17985
18201
|
}
|
|
@@ -18040,12 +18256,12 @@ function worktreeCleanupSettings() {
|
|
|
18040
18256
|
autoCleanupOrphans: a.autoCleanupOrphans
|
|
18041
18257
|
};
|
|
18042
18258
|
}
|
|
18043
|
-
var
|
|
18259
|
+
var import_node_fs46, import_node_path46;
|
|
18044
18260
|
var init_orphan_cleanup = __esm({
|
|
18045
18261
|
"src/git/orphan-cleanup.ts"() {
|
|
18046
18262
|
"use strict";
|
|
18047
|
-
|
|
18048
|
-
|
|
18263
|
+
import_node_fs46 = require("fs");
|
|
18264
|
+
import_node_path46 = require("path");
|
|
18049
18265
|
init_worktree();
|
|
18050
18266
|
init_thread_store();
|
|
18051
18267
|
init_paths();
|
|
@@ -18220,12 +18436,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
18220
18436
|
if (!url) throw new Error("Clone URL is required");
|
|
18221
18437
|
let name = opts.name?.trim();
|
|
18222
18438
|
if (!name) {
|
|
18223
|
-
const leaf = (0,
|
|
18439
|
+
const leaf = (0, import_node_path47.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
|
|
18224
18440
|
name = leaf || "repo";
|
|
18225
18441
|
}
|
|
18226
18442
|
name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
|
|
18227
|
-
const dest = (0,
|
|
18228
|
-
if ((0,
|
|
18443
|
+
const dest = (0, import_node_path47.join)(sideboardReposDir(), name);
|
|
18444
|
+
if ((0, import_node_fs47.existsSync)(dest)) {
|
|
18229
18445
|
const repoPath2 = await resolveRepoRoot(dest);
|
|
18230
18446
|
const workspace2 = await ensureWorkspace(repoPath2);
|
|
18231
18447
|
return { repoPath: repoPath2, workspace: workspace2 };
|
|
@@ -18240,12 +18456,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
18240
18456
|
const workspace = await ensureWorkspace(repoPath);
|
|
18241
18457
|
return { repoPath, workspace };
|
|
18242
18458
|
}
|
|
18243
|
-
var
|
|
18459
|
+
var import_node_fs47, import_node_path47, import_execa6;
|
|
18244
18460
|
var init_clone_repo = __esm({
|
|
18245
18461
|
"src/git/clone-repo.ts"() {
|
|
18246
18462
|
"use strict";
|
|
18247
|
-
|
|
18248
|
-
|
|
18463
|
+
import_node_fs47 = require("fs");
|
|
18464
|
+
import_node_path47 = require("path");
|
|
18249
18465
|
import_execa6 = require("execa");
|
|
18250
18466
|
init_paths();
|
|
18251
18467
|
init_workspaces();
|
|
@@ -18374,24 +18590,24 @@ function jobTreeAlive(pid) {
|
|
|
18374
18590
|
return jobAlive(pid) || processGroupAlive(pid);
|
|
18375
18591
|
}
|
|
18376
18592
|
function readIntFile(file) {
|
|
18377
|
-
if (!(0,
|
|
18378
|
-
const n = Number.parseInt((0,
|
|
18593
|
+
if (!(0, import_node_fs48.existsSync)(file)) return null;
|
|
18594
|
+
const n = Number.parseInt((0, import_node_fs48.readFileSync)(file, "utf8").trim(), 10);
|
|
18379
18595
|
return Number.isInteger(n) ? n : null;
|
|
18380
18596
|
}
|
|
18381
18597
|
function jobDir(root, id, legacy = false) {
|
|
18382
|
-
return (0,
|
|
18598
|
+
return (0, import_node_path48.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
|
|
18383
18599
|
}
|
|
18384
18600
|
function resolveJobDir(root, id) {
|
|
18385
18601
|
const modern = jobDir(root, id, false);
|
|
18386
|
-
if ((0,
|
|
18602
|
+
if ((0, import_node_fs48.existsSync)(modern)) return modern;
|
|
18387
18603
|
const legacy = jobDir(root, id, true);
|
|
18388
|
-
if ((0,
|
|
18604
|
+
if ((0, import_node_fs48.existsSync)(legacy)) return legacy;
|
|
18389
18605
|
return modern;
|
|
18390
18606
|
}
|
|
18391
18607
|
function listJobIdsIn(root, rel) {
|
|
18392
|
-
const dir = (0,
|
|
18393
|
-
if (!(0,
|
|
18394
|
-
return (0,
|
|
18608
|
+
const dir = (0, import_node_path48.join)(root, rel);
|
|
18609
|
+
if (!(0, import_node_fs48.existsSync)(dir)) return [];
|
|
18610
|
+
return (0, import_node_fs48.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
|
|
18395
18611
|
}
|
|
18396
18612
|
function listRunningDetachedJobs(worktreePath) {
|
|
18397
18613
|
const root = worktreePath.trim();
|
|
@@ -18403,7 +18619,7 @@ function listRunningDetachedJobs(worktreePath) {
|
|
|
18403
18619
|
const running = [];
|
|
18404
18620
|
for (const id of ids) {
|
|
18405
18621
|
const dir = resolveJobDir(root, id);
|
|
18406
|
-
const pid = readIntFile((0,
|
|
18622
|
+
const pid = readIntFile((0, import_node_path48.join)(dir, "pid"));
|
|
18407
18623
|
if (jobTreeAlive(pid)) running.push(id);
|
|
18408
18624
|
}
|
|
18409
18625
|
return running.sort();
|
|
@@ -18486,8 +18702,8 @@ function planJobContinue(opts) {
|
|
|
18486
18702
|
return { action: "none" };
|
|
18487
18703
|
}
|
|
18488
18704
|
function tailProgress(logFile, maxLines = 12) {
|
|
18489
|
-
if (!(0,
|
|
18490
|
-
const lines = (0,
|
|
18705
|
+
if (!(0, import_node_fs48.existsSync)(logFile)) return "(no log yet)";
|
|
18706
|
+
const lines = (0, import_node_fs48.readFileSync)(logFile, "utf8").split("\n");
|
|
18491
18707
|
return lines.slice(-maxLines).join("\n");
|
|
18492
18708
|
}
|
|
18493
18709
|
function lastProgressLine(progress) {
|
|
@@ -18495,8 +18711,8 @@ function lastProgressLine(progress) {
|
|
|
18495
18711
|
return last ? last.slice(0, 72) : void 0;
|
|
18496
18712
|
}
|
|
18497
18713
|
function readLogLines(file) {
|
|
18498
|
-
if (!(0,
|
|
18499
|
-
const lines = (0,
|
|
18714
|
+
if (!(0, import_node_fs48.existsSync)(file)) return [];
|
|
18715
|
+
const lines = (0, import_node_fs48.readFileSync)(file, "utf8").split("\n");
|
|
18500
18716
|
if (lines.length && lines[lines.length - 1] === "") lines.pop();
|
|
18501
18717
|
return lines;
|
|
18502
18718
|
}
|
|
@@ -18507,15 +18723,15 @@ function takeDelta(logFile, cursorFile) {
|
|
|
18507
18723
|
return { delta: capJobLogDelta(lines.slice(start).join("\n")), nextCursor: lines.length };
|
|
18508
18724
|
}
|
|
18509
18725
|
function snapshotJob(dir) {
|
|
18510
|
-
const pid = readIntFile((0,
|
|
18726
|
+
const pid = readIntFile((0, import_node_path48.join)(dir, "pid"));
|
|
18511
18727
|
const running = jobTreeAlive(pid);
|
|
18512
18728
|
return {
|
|
18513
18729
|
pid,
|
|
18514
18730
|
running,
|
|
18515
|
-
exitCode: readIntFile((0,
|
|
18516
|
-
log: (0,
|
|
18517
|
-
cursor: (0,
|
|
18518
|
-
progress: tailProgress((0,
|
|
18731
|
+
exitCode: readIntFile((0, import_node_path48.join)(dir, "exit")),
|
|
18732
|
+
log: (0, import_node_path48.join)(dir, "log"),
|
|
18733
|
+
cursor: (0, import_node_path48.join)(dir, "present.cursor"),
|
|
18734
|
+
progress: tailProgress((0, import_node_path48.join)(dir, "log"))
|
|
18519
18735
|
};
|
|
18520
18736
|
}
|
|
18521
18737
|
function toResult(id, snap, extra) {
|
|
@@ -18524,8 +18740,8 @@ function toResult(id, snap, extra) {
|
|
|
18524
18740
|
const stillRunning = snap.running && !ok;
|
|
18525
18741
|
const { delta, nextCursor } = takeDelta(snap.log, snap.cursor);
|
|
18526
18742
|
try {
|
|
18527
|
-
(0,
|
|
18528
|
-
(0,
|
|
18743
|
+
(0, import_node_fs48.mkdirSync)((0, import_node_path48.dirname)(snap.cursor), { recursive: true });
|
|
18744
|
+
(0, import_node_fs48.writeFileSync)(snap.cursor, `${nextCursor}
|
|
18529
18745
|
`);
|
|
18530
18746
|
} catch {
|
|
18531
18747
|
}
|
|
@@ -18546,7 +18762,7 @@ function toResult(id, snap, extra) {
|
|
|
18546
18762
|
};
|
|
18547
18763
|
}
|
|
18548
18764
|
async function sleepMs(ms) {
|
|
18549
|
-
await new Promise((
|
|
18765
|
+
await new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
18550
18766
|
}
|
|
18551
18767
|
async function waitForDetachedJob(cwd, id, opts) {
|
|
18552
18768
|
const jobId = sanitizeDetachedJobId(id);
|
|
@@ -18554,7 +18770,7 @@ async function waitForDetachedJob(cwd, id, opts) {
|
|
|
18554
18770
|
const dir = resolveJobDir(root, jobId);
|
|
18555
18771
|
const timeoutMs = mcpWaitForJobTimeoutMs(opts?.timeoutMs);
|
|
18556
18772
|
const sleep2 = opts?.sleep ?? sleepMs;
|
|
18557
|
-
if (!(0,
|
|
18773
|
+
if (!(0, import_node_fs48.existsSync)(dir)) {
|
|
18558
18774
|
return {
|
|
18559
18775
|
stillRunning: false,
|
|
18560
18776
|
ok: false,
|
|
@@ -18600,10 +18816,10 @@ function killProcessTree(pid, signal) {
|
|
|
18600
18816
|
}
|
|
18601
18817
|
function appendJobLog(logFile, line) {
|
|
18602
18818
|
try {
|
|
18603
|
-
(0,
|
|
18819
|
+
(0, import_node_fs48.mkdirSync)((0, import_node_path48.dirname)(logFile), { recursive: true });
|
|
18604
18820
|
const body = line.endsWith("\n") ? line : `${line}
|
|
18605
18821
|
`;
|
|
18606
|
-
(0,
|
|
18822
|
+
(0, import_node_fs48.appendFileSync)(logFile, body);
|
|
18607
18823
|
} catch {
|
|
18608
18824
|
}
|
|
18609
18825
|
}
|
|
@@ -18613,7 +18829,7 @@ async function stopDetachedJob(cwd, id, opts) {
|
|
|
18613
18829
|
const dir = resolveJobDir(root, jobId);
|
|
18614
18830
|
const sleep2 = opts?.sleep ?? sleepMs;
|
|
18615
18831
|
const why = opts?.reason?.trim() ?? "";
|
|
18616
|
-
if (!(0,
|
|
18832
|
+
if (!(0, import_node_fs48.existsSync)(dir)) {
|
|
18617
18833
|
return {
|
|
18618
18834
|
stillRunning: false,
|
|
18619
18835
|
ok: false,
|
|
@@ -18649,10 +18865,10 @@ async function stopDetachedJob(cwd, id, opts) {
|
|
|
18649
18865
|
killProcessTree(targetPid, "SIGKILL");
|
|
18650
18866
|
await sleep2(100);
|
|
18651
18867
|
}
|
|
18652
|
-
const exitFile = (0,
|
|
18653
|
-
if (!(0,
|
|
18868
|
+
const exitFile = (0, import_node_path48.join)(dir, "exit");
|
|
18869
|
+
if (!(0, import_node_fs48.existsSync)(exitFile)) {
|
|
18654
18870
|
try {
|
|
18655
|
-
(0,
|
|
18871
|
+
(0, import_node_fs48.writeFileSync)(exitFile, "1\n");
|
|
18656
18872
|
} catch {
|
|
18657
18873
|
}
|
|
18658
18874
|
}
|
|
@@ -18672,12 +18888,12 @@ async function stopDetachedJob(cwd, id, opts) {
|
|
|
18672
18888
|
hint: stopped ? MCP_STOP_JOB_HINT : MCP_WAIT_JOB_STILL_RUNNING_HINT
|
|
18673
18889
|
};
|
|
18674
18890
|
}
|
|
18675
|
-
var
|
|
18891
|
+
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
18892
|
var init_wait_for_job = __esm({
|
|
18677
18893
|
"src/mcp/wait-for-job.ts"() {
|
|
18678
18894
|
"use strict";
|
|
18679
|
-
|
|
18680
|
-
|
|
18895
|
+
import_node_fs48 = require("fs");
|
|
18896
|
+
import_node_path48 = require("path");
|
|
18681
18897
|
init_workspace_scratch();
|
|
18682
18898
|
init_wait_for_turn();
|
|
18683
18899
|
MAX_JOB_CONTINUES = 8;
|
|
@@ -18922,14 +19138,14 @@ async function startAbleTimeOAuth(opts) {
|
|
|
18922
19138
|
const pkce = createAbleTimePkce();
|
|
18923
19139
|
const authorizeUrl = ableTimeOAuthAuthorizeUrl(clientId, state, pkce.challenge, host);
|
|
18924
19140
|
const timeoutMs = opts?.timeoutMs ?? 5 * 6e4;
|
|
18925
|
-
const code = await new Promise((
|
|
19141
|
+
const code = await new Promise((resolve2, reject) => {
|
|
18926
19142
|
let settled = false;
|
|
18927
19143
|
const finish = (err, value) => {
|
|
18928
19144
|
if (settled) return;
|
|
18929
19145
|
settled = true;
|
|
18930
19146
|
cleanup();
|
|
18931
19147
|
if (err) reject(err);
|
|
18932
|
-
else
|
|
19148
|
+
else resolve2(value);
|
|
18933
19149
|
};
|
|
18934
19150
|
const server = (0, import_node_http.createServer)((req, res) => {
|
|
18935
19151
|
try {
|
|
@@ -20222,7 +20438,7 @@ function reuseLiveThread(input, repoPath, match) {
|
|
|
20222
20438
|
}
|
|
20223
20439
|
async function createThread(input, _onSetupLine) {
|
|
20224
20440
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
20225
|
-
if (!(0,
|
|
20441
|
+
if (!(0, import_node_fs49.existsSync)(repoPath)) {
|
|
20226
20442
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
20227
20443
|
}
|
|
20228
20444
|
const reused = reuseLiveThread(input, repoPath, {
|
|
@@ -20407,11 +20623,11 @@ async function listLinearIssues(agent, repoPath) {
|
|
|
20407
20623
|
}
|
|
20408
20624
|
return adapter.listLinearIssues(repoPath);
|
|
20409
20625
|
}
|
|
20410
|
-
var
|
|
20626
|
+
var import_node_fs49;
|
|
20411
20627
|
var init_create = __esm({
|
|
20412
20628
|
"src/threads/create.ts"() {
|
|
20413
20629
|
"use strict";
|
|
20414
|
-
|
|
20630
|
+
import_node_fs49 = require("fs");
|
|
20415
20631
|
init_detect();
|
|
20416
20632
|
init_worktree();
|
|
20417
20633
|
init_home_board();
|
|
@@ -20563,20 +20779,20 @@ function writeTurnLive(threadId, progress) {
|
|
|
20563
20779
|
const path2 = threadLivePath(threadId);
|
|
20564
20780
|
const tmp = `${path2}.${process.pid}.tmp`;
|
|
20565
20781
|
try {
|
|
20566
|
-
(0,
|
|
20567
|
-
(0,
|
|
20782
|
+
(0, import_node_fs50.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
|
|
20783
|
+
(0, import_node_fs50.renameSync)(tmp, path2);
|
|
20568
20784
|
} catch {
|
|
20569
20785
|
try {
|
|
20570
|
-
(0,
|
|
20786
|
+
(0, import_node_fs50.unlinkSync)(tmp);
|
|
20571
20787
|
} catch {
|
|
20572
20788
|
}
|
|
20573
20789
|
}
|
|
20574
20790
|
}
|
|
20575
20791
|
function readTurnLive(threadId) {
|
|
20576
20792
|
const path2 = threadLivePath(threadId);
|
|
20577
|
-
if (!(0,
|
|
20793
|
+
if (!(0, import_node_fs50.existsSync)(path2)) return null;
|
|
20578
20794
|
try {
|
|
20579
|
-
const raw = JSON.parse((0,
|
|
20795
|
+
const raw = JSON.parse((0, import_node_fs50.readFileSync)(path2, "utf8"));
|
|
20580
20796
|
if (!raw || typeof raw.summary !== "string") return null;
|
|
20581
20797
|
return raw;
|
|
20582
20798
|
} catch {
|
|
@@ -20588,17 +20804,17 @@ function clearTurnLive(threadId) {
|
|
|
20588
20804
|
if (buf?.timer) clearTimeout(buf.timer);
|
|
20589
20805
|
buffers.delete(threadId);
|
|
20590
20806
|
const path2 = threadLivePath(threadId);
|
|
20591
|
-
if (!(0,
|
|
20807
|
+
if (!(0, import_node_fs50.existsSync)(path2)) return;
|
|
20592
20808
|
try {
|
|
20593
|
-
(0,
|
|
20809
|
+
(0, import_node_fs50.unlinkSync)(path2);
|
|
20594
20810
|
} catch {
|
|
20595
20811
|
}
|
|
20596
20812
|
}
|
|
20597
|
-
var
|
|
20813
|
+
var import_node_fs50, buffers, FLUSH_MS, MAX_PARTS;
|
|
20598
20814
|
var init_turn_live = __esm({
|
|
20599
20815
|
"src/store/turn-live.ts"() {
|
|
20600
20816
|
"use strict";
|
|
20601
|
-
|
|
20817
|
+
import_node_fs50 = require("fs");
|
|
20602
20818
|
init_message_parts();
|
|
20603
20819
|
init_paths();
|
|
20604
20820
|
buffers = /* @__PURE__ */ new Map();
|
|
@@ -20842,7 +21058,7 @@ var init_quota_failover = __esm({
|
|
|
20842
21058
|
// src/threads/adopt.ts
|
|
20843
21059
|
function thisModuleFile2() {
|
|
20844
21060
|
const cjsFile = typeof __filename !== "undefined" ? __filename : "";
|
|
20845
|
-
return cjsFile || process.argv[1] || (0,
|
|
21061
|
+
return cjsFile || process.argv[1] || (0, import_node_path49.join)(process.cwd(), "package.json");
|
|
20846
21062
|
}
|
|
20847
21063
|
function openReadonlySqlite(file) {
|
|
20848
21064
|
const req = (0, import_node_module5.createRequire)(thisModuleFile2());
|
|
@@ -20860,21 +21076,21 @@ function mapAgentType(raw) {
|
|
|
20860
21076
|
return null;
|
|
20861
21077
|
}
|
|
20862
21078
|
function resolveConductorCursorAgentId(workspacePath) {
|
|
20863
|
-
if (!workspacePath || !(0,
|
|
21079
|
+
if (!workspacePath || !(0, import_node_fs51.existsSync)(CURSOR_SDK_STORE)) return null;
|
|
20864
21080
|
const normalized = workspacePath.replace(/\/$/, "");
|
|
20865
21081
|
let best = null;
|
|
20866
21082
|
let hashes;
|
|
20867
21083
|
try {
|
|
20868
|
-
hashes = (0,
|
|
21084
|
+
hashes = (0, import_node_fs51.readdirSync)(CURSOR_SDK_STORE);
|
|
20869
21085
|
} catch {
|
|
20870
21086
|
return null;
|
|
20871
21087
|
}
|
|
20872
21088
|
for (const hash of hashes) {
|
|
20873
|
-
const agentsFile = (0,
|
|
20874
|
-
if (!(0,
|
|
21089
|
+
const agentsFile = (0, import_node_path49.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
|
|
21090
|
+
if (!(0, import_node_fs51.existsSync)(agentsFile)) continue;
|
|
20875
21091
|
let text7;
|
|
20876
21092
|
try {
|
|
20877
|
-
text7 = (0,
|
|
21093
|
+
text7 = (0, import_node_fs51.readFileSync)(agentsFile, "utf8");
|
|
20878
21094
|
} catch {
|
|
20879
21095
|
continue;
|
|
20880
21096
|
}
|
|
@@ -20898,7 +21114,7 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
20898
21114
|
return best?.agentId ?? null;
|
|
20899
21115
|
}
|
|
20900
21116
|
async function adoptThread(input) {
|
|
20901
|
-
if (!(0,
|
|
21117
|
+
if (!(0, import_node_fs51.existsSync)(input.worktreePath)) {
|
|
20902
21118
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
20903
21119
|
}
|
|
20904
21120
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
@@ -20927,18 +21143,18 @@ function conductorDbPath() {
|
|
|
20927
21143
|
return CONDUCTOR_DB;
|
|
20928
21144
|
}
|
|
20929
21145
|
function listConductorWorkspaces() {
|
|
20930
|
-
if (!(0,
|
|
21146
|
+
if (!(0, import_node_fs51.existsSync)(CONDUCTOR_DB)) {
|
|
20931
21147
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
20932
21148
|
}
|
|
20933
|
-
const tmp = (0,
|
|
20934
|
-
const snapshot = (0,
|
|
21149
|
+
const tmp = (0, import_node_fs51.mkdtempSync)((0, import_node_path49.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
|
|
21150
|
+
const snapshot = (0, import_node_path49.join)(tmp, "conductor.db");
|
|
20935
21151
|
try {
|
|
20936
|
-
(0,
|
|
21152
|
+
(0, import_node_fs51.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
20937
21153
|
for (const suffix of ["-wal", "-shm"]) {
|
|
20938
21154
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
20939
|
-
if ((0,
|
|
21155
|
+
if ((0, import_node_fs51.existsSync)(src)) {
|
|
20940
21156
|
try {
|
|
20941
|
-
(0,
|
|
21157
|
+
(0, import_node_fs51.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
20942
21158
|
} catch {
|
|
20943
21159
|
}
|
|
20944
21160
|
}
|
|
@@ -21014,22 +21230,22 @@ function listConductorWorkspaces() {
|
|
|
21014
21230
|
db.close();
|
|
21015
21231
|
}
|
|
21016
21232
|
} finally {
|
|
21017
|
-
(0,
|
|
21233
|
+
(0, import_node_fs51.rmSync)(tmp, { recursive: true, force: true });
|
|
21018
21234
|
}
|
|
21019
21235
|
}
|
|
21020
21236
|
function importConductorWorkspace(workspaceId) {
|
|
21021
|
-
if (!(0,
|
|
21237
|
+
if (!(0, import_node_fs51.existsSync)(CONDUCTOR_DB)) {
|
|
21022
21238
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
21023
21239
|
}
|
|
21024
|
-
const tmp = (0,
|
|
21025
|
-
const snapshot = (0,
|
|
21240
|
+
const tmp = (0, import_node_fs51.mkdtempSync)((0, import_node_path49.join)((0, import_node_os14.tmpdir)(), "sideboard-conductor-"));
|
|
21241
|
+
const snapshot = (0, import_node_path49.join)(tmp, "conductor.db");
|
|
21026
21242
|
try {
|
|
21027
|
-
(0,
|
|
21243
|
+
(0, import_node_fs51.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
21028
21244
|
for (const suffix of ["-wal", "-shm"]) {
|
|
21029
21245
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
21030
|
-
if ((0,
|
|
21246
|
+
if ((0, import_node_fs51.existsSync)(src)) {
|
|
21031
21247
|
try {
|
|
21032
|
-
(0,
|
|
21248
|
+
(0, import_node_fs51.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
21033
21249
|
} catch {
|
|
21034
21250
|
}
|
|
21035
21251
|
}
|
|
@@ -21047,7 +21263,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
21047
21263
|
).get(workspaceId);
|
|
21048
21264
|
if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
|
|
21049
21265
|
const worktreePath = String(row.workspacePath);
|
|
21050
|
-
if (!(0,
|
|
21266
|
+
if (!(0, import_node_fs51.existsSync)(worktreePath)) {
|
|
21051
21267
|
throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
|
|
21052
21268
|
}
|
|
21053
21269
|
let sessionId = null;
|
|
@@ -21110,31 +21326,31 @@ function importConductorWorkspace(workspaceId) {
|
|
|
21110
21326
|
db.close();
|
|
21111
21327
|
}
|
|
21112
21328
|
} finally {
|
|
21113
|
-
(0,
|
|
21329
|
+
(0, import_node_fs51.rmSync)(tmp, { recursive: true, force: true });
|
|
21114
21330
|
}
|
|
21115
21331
|
}
|
|
21116
21332
|
async function importConductorWorkspaceAsync(workspaceId) {
|
|
21117
21333
|
return importConductorWorkspace(workspaceId);
|
|
21118
21334
|
}
|
|
21119
|
-
var import_node_child_process6,
|
|
21335
|
+
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
21336
|
var init_adopt = __esm({
|
|
21121
21337
|
"src/threads/adopt.ts"() {
|
|
21122
21338
|
"use strict";
|
|
21123
21339
|
import_node_child_process6 = require("child_process");
|
|
21124
|
-
|
|
21340
|
+
import_node_fs51 = require("fs");
|
|
21125
21341
|
import_node_os14 = require("os");
|
|
21126
|
-
|
|
21342
|
+
import_node_path49 = require("path");
|
|
21127
21343
|
import_node_module5 = require("module");
|
|
21128
21344
|
init_worktree();
|
|
21129
21345
|
init_thread_store();
|
|
21130
|
-
CONDUCTOR_APP_SUPPORT = (0,
|
|
21346
|
+
CONDUCTOR_APP_SUPPORT = (0, import_node_path49.join)(
|
|
21131
21347
|
process.env.HOME ?? "",
|
|
21132
21348
|
"Library",
|
|
21133
21349
|
"Application Support",
|
|
21134
21350
|
"com.conductor.app"
|
|
21135
21351
|
);
|
|
21136
|
-
CONDUCTOR_DB = (0,
|
|
21137
|
-
CURSOR_SDK_STORE = (0,
|
|
21352
|
+
CONDUCTOR_DB = (0, import_node_path49.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
21353
|
+
CURSOR_SDK_STORE = (0, import_node_path49.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
21138
21354
|
}
|
|
21139
21355
|
});
|
|
21140
21356
|
|
|
@@ -21201,7 +21417,7 @@ async function openStackLayer(input, _onSetupLine) {
|
|
|
21201
21417
|
let createdWorktree = false;
|
|
21202
21418
|
const trees = await listWorktrees(repoPath);
|
|
21203
21419
|
const checkedOut = trees.find((w) => w.branch === branchName);
|
|
21204
|
-
if (checkedOut?.path && (0,
|
|
21420
|
+
if (checkedOut?.path && (0, import_node_fs52.existsSync)(checkedOut.path)) {
|
|
21205
21421
|
if (input.reuseExistingWorktree !== false) {
|
|
21206
21422
|
worktreePath = checkedOut.path;
|
|
21207
21423
|
} else {
|
|
@@ -21343,7 +21559,7 @@ async function initStackFromThread(input, onSetupLine) {
|
|
|
21343
21559
|
async function createPrStack(input, onSetupLine) {
|
|
21344
21560
|
await requireAgent(input.agent);
|
|
21345
21561
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
21346
|
-
if (!(0,
|
|
21562
|
+
if (!(0, import_node_fs52.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
|
|
21347
21563
|
if (!input.branches.length) throw new Error("At least one branch name required");
|
|
21348
21564
|
const status = await detectGhStack(repoPath);
|
|
21349
21565
|
if (!status.available) throw new Error(status.reason);
|
|
@@ -21410,7 +21626,7 @@ async function createPrStack(input, onSetupLine) {
|
|
|
21410
21626
|
}
|
|
21411
21627
|
}
|
|
21412
21628
|
const claimed = new Set(threads.map((t) => t.worktreePath));
|
|
21413
|
-
if (!claimed.has(bootstrap.worktreePath) && (0,
|
|
21629
|
+
if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs52.existsSync)(bootstrap.worktreePath)) {
|
|
21414
21630
|
try {
|
|
21415
21631
|
await removeWorktree(repoPath, bootstrap.worktreePath, {
|
|
21416
21632
|
deleteBranch: bootstrap.branchName
|
|
@@ -21430,11 +21646,11 @@ function stackAgentDefaultsFrom(input) {
|
|
|
21430
21646
|
planMode: input.planMode
|
|
21431
21647
|
};
|
|
21432
21648
|
}
|
|
21433
|
-
var
|
|
21649
|
+
var import_node_fs52;
|
|
21434
21650
|
var init_stack_layers = __esm({
|
|
21435
21651
|
"src/threads/stack-layers.ts"() {
|
|
21436
21652
|
"use strict";
|
|
21437
|
-
|
|
21653
|
+
import_node_fs52 = require("fs");
|
|
21438
21654
|
init_detect();
|
|
21439
21655
|
init_run();
|
|
21440
21656
|
init_stack();
|
|
@@ -21447,7 +21663,7 @@ var init_stack_layers = __esm({
|
|
|
21447
21663
|
|
|
21448
21664
|
// src/diff/diff.ts
|
|
21449
21665
|
async function inspectGitWorktree(worktreePath) {
|
|
21450
|
-
if (!worktreePath || !(0,
|
|
21666
|
+
if (!worktreePath || !(0, import_node_fs53.existsSync)(worktreePath)) return "missing_worktree";
|
|
21451
21667
|
const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
|
|
21452
21668
|
reject: false
|
|
21453
21669
|
});
|
|
@@ -21455,7 +21671,7 @@ async function inspectGitWorktree(worktreePath) {
|
|
|
21455
21671
|
return "ok";
|
|
21456
21672
|
}
|
|
21457
21673
|
async function initializeGitRepository(worktreePath) {
|
|
21458
|
-
if (!worktreePath || !(0,
|
|
21674
|
+
if (!worktreePath || !(0, import_node_fs53.existsSync)(worktreePath)) {
|
|
21459
21675
|
throw new Error("Worktree not found");
|
|
21460
21676
|
}
|
|
21461
21677
|
const status = await inspectGitWorktree(worktreePath);
|
|
@@ -21589,11 +21805,11 @@ new file mode 100644
|
|
|
21589
21805
|
};
|
|
21590
21806
|
}
|
|
21591
21807
|
async function untrackedPatch(worktreePath, path2, maxHunk) {
|
|
21592
|
-
const abs = (0,
|
|
21808
|
+
const abs = (0, import_node_path50.join)(worktreePath, path2);
|
|
21593
21809
|
try {
|
|
21594
|
-
const st = (0,
|
|
21810
|
+
const st = (0, import_node_fs53.statSync)(abs);
|
|
21595
21811
|
if (st.isFile() && st.size > maxHunk) {
|
|
21596
|
-
const buf = (0,
|
|
21812
|
+
const buf = (0, import_node_fs53.readFileSync)(abs).subarray(0, maxHunk);
|
|
21597
21813
|
return syntheticAddPatch(path2, buf.toString("utf8"), maxHunk);
|
|
21598
21814
|
}
|
|
21599
21815
|
} catch {
|
|
@@ -22060,9 +22276,9 @@ async function getDiff(worktreePath, repoPath, opts) {
|
|
|
22060
22276
|
}
|
|
22061
22277
|
function statWorktreePath(worktreePath, relativePath) {
|
|
22062
22278
|
assertSafeRelativePath(relativePath);
|
|
22063
|
-
const abs = (0,
|
|
22064
|
-
if (!(0,
|
|
22065
|
-
const st = (0,
|
|
22279
|
+
const abs = (0, import_node_path50.join)(worktreePath, relativePath);
|
|
22280
|
+
if (!(0, import_node_fs53.existsSync)(abs)) return "missing";
|
|
22281
|
+
const st = (0, import_node_fs53.statSync)(abs);
|
|
22066
22282
|
if (st.isDirectory()) return "dir";
|
|
22067
22283
|
if (st.isFile()) return "file";
|
|
22068
22284
|
return "missing";
|
|
@@ -22091,8 +22307,8 @@ function isImageRelativePath(relativePath) {
|
|
|
22091
22307
|
function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
22092
22308
|
assertSafeRelativePath(relativePath);
|
|
22093
22309
|
const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
|
|
22094
|
-
const abs = (0,
|
|
22095
|
-
const st = (0,
|
|
22310
|
+
const abs = (0, import_node_path50.join)(worktreePath, relativePath);
|
|
22311
|
+
const st = (0, import_node_fs53.statSync)(abs);
|
|
22096
22312
|
if (!st.isFile()) {
|
|
22097
22313
|
throw new Error(`Not a file: ${relativePath}`);
|
|
22098
22314
|
}
|
|
@@ -22101,7 +22317,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
22101
22317
|
`File too large to upload (${st.size} bytes; max ${maxBytes})`
|
|
22102
22318
|
);
|
|
22103
22319
|
}
|
|
22104
|
-
const buf = (0,
|
|
22320
|
+
const buf = (0, import_node_fs53.readFileSync)(abs);
|
|
22105
22321
|
return {
|
|
22106
22322
|
path: relativePath,
|
|
22107
22323
|
contentBase64: buf.toString("base64"),
|
|
@@ -22111,12 +22327,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
22111
22327
|
function readWorktreeFile(worktreePath, relativePath, opts) {
|
|
22112
22328
|
assertSafeRelativePath(relativePath);
|
|
22113
22329
|
const maxBytes = opts?.maxBytes ?? 2e5;
|
|
22114
|
-
const abs = (0,
|
|
22115
|
-
const st = (0,
|
|
22330
|
+
const abs = (0, import_node_path50.join)(worktreePath, relativePath);
|
|
22331
|
+
const st = (0, import_node_fs53.statSync)(abs);
|
|
22116
22332
|
if (!st.isFile()) {
|
|
22117
22333
|
throw new Error(`Not a file: ${relativePath}`);
|
|
22118
22334
|
}
|
|
22119
|
-
const buf = (0,
|
|
22335
|
+
const buf = (0, import_node_fs53.readFileSync)(abs);
|
|
22120
22336
|
if (isImageRelativePath(relativePath)) {
|
|
22121
22337
|
const maxImageBytes = Math.max(maxBytes, 15e6);
|
|
22122
22338
|
const truncated2 = buf.length > maxImageBytes;
|
|
@@ -22159,9 +22375,9 @@ function assertSafeRelativePath(relativePath) {
|
|
|
22159
22375
|
}
|
|
22160
22376
|
function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
22161
22377
|
assertSafeRelativePath(relativePath);
|
|
22162
|
-
const abs = (0,
|
|
22163
|
-
(0,
|
|
22164
|
-
(0,
|
|
22378
|
+
const abs = (0, import_node_path50.join)(worktreePath, relativePath);
|
|
22379
|
+
(0, import_node_fs53.mkdirSync)((0, import_node_path50.dirname)(abs), { recursive: true });
|
|
22380
|
+
(0, import_node_fs53.writeFileSync)(abs, content, "utf8");
|
|
22165
22381
|
return { path: relativePath };
|
|
22166
22382
|
}
|
|
22167
22383
|
async function getWorktreeDirtyStat(worktreePath) {
|
|
@@ -22201,12 +22417,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
|
22201
22417
|
truncated: full.files.length > maxFiles
|
|
22202
22418
|
};
|
|
22203
22419
|
}
|
|
22204
|
-
var
|
|
22420
|
+
var import_node_fs53, import_node_path50, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
|
|
22205
22421
|
var init_diff = __esm({
|
|
22206
22422
|
"src/diff/diff.ts"() {
|
|
22207
22423
|
"use strict";
|
|
22208
|
-
|
|
22209
|
-
|
|
22424
|
+
import_node_fs53 = require("fs");
|
|
22425
|
+
import_node_path50 = require("path");
|
|
22210
22426
|
init_run();
|
|
22211
22427
|
init_worktree();
|
|
22212
22428
|
mergeBaseCache = /* @__PURE__ */ new Map();
|
|
@@ -22563,7 +22779,7 @@ function parseFrontmatter(content) {
|
|
|
22563
22779
|
}
|
|
22564
22780
|
function readSkill(skillMd, source) {
|
|
22565
22781
|
try {
|
|
22566
|
-
const content = (0,
|
|
22782
|
+
const content = (0, import_node_fs54.readFileSync)(skillMd, "utf8");
|
|
22567
22783
|
const { name: fmName, description } = parseFrontmatter(content);
|
|
22568
22784
|
const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
|
|
22569
22785
|
const name = fmName || dirName;
|
|
@@ -22582,19 +22798,19 @@ function readSkill(skillMd, source) {
|
|
|
22582
22798
|
}
|
|
22583
22799
|
}
|
|
22584
22800
|
function scanSkillsDir(dir, source, out) {
|
|
22585
|
-
if (!(0,
|
|
22801
|
+
if (!(0, import_node_fs54.existsSync)(dir)) return;
|
|
22586
22802
|
let entries;
|
|
22587
22803
|
try {
|
|
22588
|
-
entries = (0,
|
|
22804
|
+
entries = (0, import_node_fs54.readdirSync)(dir);
|
|
22589
22805
|
} catch {
|
|
22590
22806
|
return;
|
|
22591
22807
|
}
|
|
22592
22808
|
for (const entry of entries) {
|
|
22593
22809
|
if (entry.startsWith(".")) continue;
|
|
22594
|
-
const skillMd = (0,
|
|
22595
|
-
if (!(0,
|
|
22810
|
+
const skillMd = (0, import_node_path51.join)(dir, entry, "SKILL.md");
|
|
22811
|
+
if (!(0, import_node_fs54.existsSync)(skillMd)) continue;
|
|
22596
22812
|
try {
|
|
22597
|
-
if (!(0,
|
|
22813
|
+
if (!(0, import_node_fs54.statSync)(skillMd).isFile()) continue;
|
|
22598
22814
|
} catch {
|
|
22599
22815
|
continue;
|
|
22600
22816
|
}
|
|
@@ -22603,24 +22819,24 @@ function scanSkillsDir(dir, source, out) {
|
|
|
22603
22819
|
}
|
|
22604
22820
|
}
|
|
22605
22821
|
function scanClaudePluginSkills(pluginsRoot, out) {
|
|
22606
|
-
if (!(0,
|
|
22822
|
+
if (!(0, import_node_fs54.existsSync)(pluginsRoot)) return;
|
|
22607
22823
|
const walk = (dir, depth, lookingForSkillsDir) => {
|
|
22608
22824
|
if (depth > 7) return;
|
|
22609
22825
|
let entries;
|
|
22610
22826
|
try {
|
|
22611
|
-
entries = (0,
|
|
22827
|
+
entries = (0, import_node_fs54.readdirSync)(dir);
|
|
22612
22828
|
} catch {
|
|
22613
22829
|
return;
|
|
22614
22830
|
}
|
|
22615
22831
|
if (lookingForSkillsDir && entries.includes("SKILL.md")) {
|
|
22616
|
-
const skill = readSkill((0,
|
|
22832
|
+
const skill = readSkill((0, import_node_path51.join)(dir, "SKILL.md"), "cli");
|
|
22617
22833
|
if (skill) out.push(skill);
|
|
22618
22834
|
}
|
|
22619
22835
|
for (const entry of entries) {
|
|
22620
22836
|
if (entry === "node_modules" || entry === ".git") continue;
|
|
22621
|
-
const full = (0,
|
|
22837
|
+
const full = (0, import_node_path51.join)(dir, entry);
|
|
22622
22838
|
try {
|
|
22623
|
-
if (!(0,
|
|
22839
|
+
if (!(0, import_node_fs54.statSync)(full).isDirectory()) continue;
|
|
22624
22840
|
} catch {
|
|
22625
22841
|
continue;
|
|
22626
22842
|
}
|
|
@@ -22638,17 +22854,17 @@ function discoverSkills(worktreePath) {
|
|
|
22638
22854
|
const home = (0, import_node_os15.homedir)();
|
|
22639
22855
|
const collected = [];
|
|
22640
22856
|
for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
|
|
22641
|
-
scanSkillsDir((0,
|
|
22857
|
+
scanSkillsDir((0, import_node_path51.join)(worktreePath, rel), "workspace", collected);
|
|
22642
22858
|
}
|
|
22643
22859
|
for (const abs of [
|
|
22644
|
-
(0,
|
|
22645
|
-
(0,
|
|
22646
|
-
(0,
|
|
22647
|
-
(0,
|
|
22860
|
+
(0, import_node_path51.join)(home, ".claude/skills"),
|
|
22861
|
+
(0, import_node_path51.join)(home, ".cursor/skills"),
|
|
22862
|
+
(0, import_node_path51.join)(home, ".sideboard/skills"),
|
|
22863
|
+
(0, import_node_path51.join)(home, ".brightsy/skills")
|
|
22648
22864
|
]) {
|
|
22649
22865
|
scanSkillsDir(abs, "user", collected);
|
|
22650
22866
|
}
|
|
22651
|
-
scanClaudePluginSkills((0,
|
|
22867
|
+
scanClaudePluginSkills((0, import_node_path51.join)(home, ".claude/plugins"), collected);
|
|
22652
22868
|
collected.push(...bundledSkills());
|
|
22653
22869
|
const rank = {
|
|
22654
22870
|
workspace: 0,
|
|
@@ -22674,7 +22890,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
|
|
|
22674
22890
|
\u2026(truncated)` : body;
|
|
22675
22891
|
}
|
|
22676
22892
|
}
|
|
22677
|
-
const raw = (0,
|
|
22893
|
+
const raw = (0, import_node_fs54.readFileSync)(skillPath, "utf8");
|
|
22678
22894
|
if (raw.startsWith("---")) {
|
|
22679
22895
|
const end = raw.indexOf("\n---", 3);
|
|
22680
22896
|
if (end >= 0) {
|
|
@@ -22688,13 +22904,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
|
|
|
22688
22904
|
|
|
22689
22905
|
\u2026(truncated)` : raw;
|
|
22690
22906
|
}
|
|
22691
|
-
var
|
|
22907
|
+
var import_node_fs54, import_node_os15, import_node_path51, BUNDLED_SKILL_PREFIX;
|
|
22692
22908
|
var init_discover = __esm({
|
|
22693
22909
|
"src/skills/discover.ts"() {
|
|
22694
22910
|
"use strict";
|
|
22695
|
-
|
|
22911
|
+
import_node_fs54 = require("fs");
|
|
22696
22912
|
import_node_os15 = require("os");
|
|
22697
|
-
|
|
22913
|
+
import_node_path51 = require("path");
|
|
22698
22914
|
init_long_running();
|
|
22699
22915
|
BUNDLED_SKILL_PREFIX = "bundled:";
|
|
22700
22916
|
}
|
|
@@ -22849,7 +23065,7 @@ function compiledModuleDir() {
|
|
|
22849
23065
|
try {
|
|
22850
23066
|
const url = import_meta4.url;
|
|
22851
23067
|
if (typeof url === "string" && url.length > 0) {
|
|
22852
|
-
return (0,
|
|
23068
|
+
return (0, import_node_path52.dirname)((0, import_node_url4.fileURLToPath)(url));
|
|
22853
23069
|
}
|
|
22854
23070
|
} catch {
|
|
22855
23071
|
}
|
|
@@ -22857,8 +23073,8 @@ function compiledModuleDir() {
|
|
|
22857
23073
|
}
|
|
22858
23074
|
function detachedJobScriptIn(dir) {
|
|
22859
23075
|
for (const name of DETACHED_JOB_FILENAMES) {
|
|
22860
|
-
const script = (0,
|
|
22861
|
-
if ((0,
|
|
23076
|
+
const script = (0, import_node_path52.join)(dir, "scripts", name);
|
|
23077
|
+
if ((0, import_node_fs55.existsSync)(script)) return script;
|
|
22862
23078
|
}
|
|
22863
23079
|
return null;
|
|
22864
23080
|
}
|
|
@@ -22875,7 +23091,7 @@ function resolveDetachedJobScript() {
|
|
|
22875
23091
|
for (let i = 0; i < 8; i++) {
|
|
22876
23092
|
const candidate = detachedJobScriptIn(dir);
|
|
22877
23093
|
if (candidate) return candidate;
|
|
22878
|
-
const parent = (0,
|
|
23094
|
+
const parent = (0, import_node_path52.dirname)(dir);
|
|
22879
23095
|
if (parent === dir) break;
|
|
22880
23096
|
dir = parent;
|
|
22881
23097
|
}
|
|
@@ -22886,12 +23102,12 @@ function formatDetachedJobInvoke(scriptPath) {
|
|
|
22886
23102
|
if (resolved) return `node ${JSON.stringify(resolved)}`;
|
|
22887
23103
|
return "node scripts/detached-job.cjs";
|
|
22888
23104
|
}
|
|
22889
|
-
var
|
|
23105
|
+
var import_node_fs55, import_node_path52, import_node_url4, import_meta4, DETACHED_JOB_FILENAMES;
|
|
22890
23106
|
var init_detached_job_path = __esm({
|
|
22891
23107
|
"src/skills/detached-job-path.ts"() {
|
|
22892
23108
|
"use strict";
|
|
22893
|
-
|
|
22894
|
-
|
|
23109
|
+
import_node_fs55 = require("fs");
|
|
23110
|
+
import_node_path52 = require("path");
|
|
22895
23111
|
import_node_url4 = require("url");
|
|
22896
23112
|
init_packaged_runtime();
|
|
22897
23113
|
import_meta4 = {};
|
|
@@ -22992,9 +23208,9 @@ function formatWorktreeDirective(thread, opts) {
|
|
|
22992
23208
|
);
|
|
22993
23209
|
} else {
|
|
22994
23210
|
const slug = opts?.githubSlug ?? "<origin-owner/name>";
|
|
22995
|
-
const
|
|
23211
|
+
const resolve2 = opts?.githubSlug ? "" : " Resolve `<origin-owner/name>` with `git remote get-url origin` in this worktree.";
|
|
22996
23212
|
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.${
|
|
23213
|
+
`- 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
23214
|
);
|
|
22999
23215
|
}
|
|
23000
23216
|
lines.push(
|
|
@@ -23103,9 +23319,9 @@ function formatPrGateDirective() {
|
|
|
23103
23319
|
}
|
|
23104
23320
|
function formatProcessGuideDirective(opts) {
|
|
23105
23321
|
const worktree = opts?.worktreePath?.trim();
|
|
23106
|
-
const hasGraphSkill = !!worktree && (0,
|
|
23107
|
-
const hasReviewSkill = !!worktree && (0,
|
|
23108
|
-
const hasInstallSkill = !!worktree && (0,
|
|
23322
|
+
const hasGraphSkill = !!worktree && (0, import_node_fs56.existsSync)((0, import_node_path53.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
|
|
23323
|
+
const hasReviewSkill = !!worktree && (0, import_node_fs56.existsSync)((0, import_node_path53.join)(worktree, ".claude/skills/review/SKILL.md"));
|
|
23324
|
+
const hasInstallSkill = !!worktree && (0, import_node_fs56.existsSync)((0, import_node_path53.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
|
|
23109
23325
|
return [
|
|
23110
23326
|
"Process guides (recurring work only):",
|
|
23111
23327
|
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 +23360,12 @@ function formatArtifactDirective() {
|
|
|
23144
23360
|
function formatUiReminder() {
|
|
23145
23361
|
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
23362
|
}
|
|
23147
|
-
var
|
|
23363
|
+
var import_node_fs56, import_node_path53, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
|
|
23148
23364
|
var init_instructions = __esm({
|
|
23149
23365
|
"src/agents/instructions.ts"() {
|
|
23150
23366
|
"use strict";
|
|
23151
|
-
|
|
23152
|
-
|
|
23367
|
+
import_node_fs56 = require("fs");
|
|
23368
|
+
import_node_path53 = require("path");
|
|
23153
23369
|
init_git_auth_mode();
|
|
23154
23370
|
init_branch_prefix();
|
|
23155
23371
|
init_worktree_labels();
|
|
@@ -23535,40 +23751,40 @@ __export(plan_file_exports, {
|
|
|
23535
23751
|
writePlanFile: () => writePlanFile
|
|
23536
23752
|
});
|
|
23537
23753
|
function ensureAttachmentsGitignore(worktreePath) {
|
|
23538
|
-
const gitignoreAbs = (0,
|
|
23539
|
-
if ((0,
|
|
23540
|
-
(0,
|
|
23541
|
-
(0,
|
|
23754
|
+
const gitignoreAbs = (0, import_node_path54.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
|
|
23755
|
+
if ((0, import_node_fs57.existsSync)(gitignoreAbs)) return;
|
|
23756
|
+
(0, import_node_fs57.mkdirSync)((0, import_node_path54.dirname)(gitignoreAbs), { recursive: true });
|
|
23757
|
+
(0, import_node_fs57.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
|
|
23542
23758
|
}
|
|
23543
23759
|
function planFileAbs(worktreePath) {
|
|
23544
|
-
return (0,
|
|
23760
|
+
return (0, import_node_path54.join)(worktreePath, PLAN_FILE_REL);
|
|
23545
23761
|
}
|
|
23546
23762
|
function readTextIfPresent2(abs) {
|
|
23547
|
-
if (!(0,
|
|
23763
|
+
if (!(0, import_node_fs57.existsSync)(abs)) return null;
|
|
23548
23764
|
try {
|
|
23549
|
-
const content = (0,
|
|
23765
|
+
const content = (0, import_node_fs57.readFileSync)(abs, "utf8");
|
|
23550
23766
|
return content.trim() ? content : null;
|
|
23551
23767
|
} catch {
|
|
23552
23768
|
return null;
|
|
23553
23769
|
}
|
|
23554
23770
|
}
|
|
23555
23771
|
function readPlanFile(worktreePath) {
|
|
23556
|
-
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0,
|
|
23772
|
+
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
23773
|
}
|
|
23558
23774
|
function writePlanFile(worktreePath, content) {
|
|
23559
23775
|
ensureAttachmentsGitignore(worktreePath);
|
|
23560
23776
|
const abs = planFileAbs(worktreePath);
|
|
23561
|
-
(0,
|
|
23777
|
+
(0, import_node_fs57.mkdirSync)((0, import_node_path54.dirname)(abs), { recursive: true });
|
|
23562
23778
|
const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
|
|
23563
|
-
(0,
|
|
23779
|
+
(0, import_node_fs57.writeFileSync)(abs, body, "utf8");
|
|
23564
23780
|
return PLAN_FILE_REL;
|
|
23565
23781
|
}
|
|
23566
|
-
var
|
|
23782
|
+
var import_node_fs57, import_node_path54;
|
|
23567
23783
|
var init_plan_file = __esm({
|
|
23568
23784
|
"src/plan/plan-file.ts"() {
|
|
23569
23785
|
"use strict";
|
|
23570
|
-
|
|
23571
|
-
|
|
23786
|
+
import_node_fs57 = require("fs");
|
|
23787
|
+
import_node_path54 = require("path");
|
|
23572
23788
|
init_workspace_scratch();
|
|
23573
23789
|
init_plan_present();
|
|
23574
23790
|
init_plan_present();
|
|
@@ -23630,9 +23846,9 @@ function recoverFinishedCursorRun(opts) {
|
|
|
23630
23846
|
return best;
|
|
23631
23847
|
}
|
|
23632
23848
|
function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
|
|
23633
|
-
if (!(0,
|
|
23849
|
+
if (!(0, import_node_fs58.existsSync)(runsPath)) return null;
|
|
23634
23850
|
try {
|
|
23635
|
-
const lines = (0,
|
|
23851
|
+
const lines = (0, import_node_fs58.readFileSync)(runsPath, "utf8").split("\n");
|
|
23636
23852
|
let best = null;
|
|
23637
23853
|
for (const line of lines) {
|
|
23638
23854
|
const trimmed = line.trim();
|
|
@@ -23658,11 +23874,11 @@ function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
|
|
|
23658
23874
|
return null;
|
|
23659
23875
|
}
|
|
23660
23876
|
}
|
|
23661
|
-
var
|
|
23877
|
+
var import_node_fs58;
|
|
23662
23878
|
var init_cursor_recover = __esm({
|
|
23663
23879
|
"src/agents/cursor-recover.ts"() {
|
|
23664
23880
|
"use strict";
|
|
23665
|
-
|
|
23881
|
+
import_node_fs58 = require("fs");
|
|
23666
23882
|
init_cursor_store();
|
|
23667
23883
|
}
|
|
23668
23884
|
});
|
|
@@ -23816,7 +24032,7 @@ async function startOrchestration(opts) {
|
|
|
23816
24032
|
}
|
|
23817
24033
|
return updated;
|
|
23818
24034
|
}
|
|
23819
|
-
var import_node_events, import_node_crypto13,
|
|
24035
|
+
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
24036
|
var init_orchestrator = __esm({
|
|
23821
24037
|
"src/orchestrator/orchestrator.ts"() {
|
|
23822
24038
|
"use strict";
|
|
@@ -23824,7 +24040,7 @@ var init_orchestrator = __esm({
|
|
|
23824
24040
|
init_injected_notices();
|
|
23825
24041
|
init_task_state();
|
|
23826
24042
|
import_node_crypto13 = require("crypto");
|
|
23827
|
-
|
|
24043
|
+
import_node_fs59 = require("fs");
|
|
23828
24044
|
init_error_detail();
|
|
23829
24045
|
init_run();
|
|
23830
24046
|
init_stale_lock();
|
|
@@ -24003,7 +24219,7 @@ var init_orchestrator = __esm({
|
|
|
24003
24219
|
this.lightReconcileAt.set(repoPath, Date.now());
|
|
24004
24220
|
for (const thread of listThreads()) {
|
|
24005
24221
|
if (isGlobalThread(thread) || thread.repoPath !== repoPath) continue;
|
|
24006
|
-
if (!(0,
|
|
24222
|
+
if (!(0, import_node_fs59.existsSync)(thread.worktreePath)) {
|
|
24007
24223
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
24008
24224
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
24009
24225
|
}
|
|
@@ -24032,7 +24248,7 @@ var init_orchestrator = __esm({
|
|
|
24032
24248
|
}
|
|
24033
24249
|
continue;
|
|
24034
24250
|
}
|
|
24035
|
-
if (!(0,
|
|
24251
|
+
if (!(0, import_node_fs59.existsSync)(thread.worktreePath)) {
|
|
24036
24252
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
24037
24253
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
24038
24254
|
continue;
|
|
@@ -24200,8 +24416,8 @@ var init_orchestrator = __esm({
|
|
|
24200
24416
|
scheduleQuotaResume(threadId, resumeAt) {
|
|
24201
24417
|
this.clearQuotaResumeTimer(threadId);
|
|
24202
24418
|
updateThread(threadId, { quotaResumeAt: resumeAt.toISOString() });
|
|
24203
|
-
const
|
|
24204
|
-
const capped = Math.min(
|
|
24419
|
+
const delay2 = Math.max(5e3, resumeAt.getTime() - Date.now());
|
|
24420
|
+
const capped = Math.min(delay2, 2147483647);
|
|
24205
24421
|
const timer = setTimeout(() => {
|
|
24206
24422
|
this.quotaResumeTimers.delete(threadId);
|
|
24207
24423
|
void this.resumeAfterQuotaWait(threadId);
|
|
@@ -25256,6 +25472,7 @@ var init_orchestrator = __esm({
|
|
|
25256
25472
|
return { port: shared.devPort, scriptName: resolvedName, ports: [shared.devPort] };
|
|
25257
25473
|
}
|
|
25258
25474
|
}
|
|
25475
|
+
const preferredPorts = active?.ports?.length ? active.ports : active?.port != null ? [active.port] : void 0;
|
|
25259
25476
|
if (active && !existing) {
|
|
25260
25477
|
killListenersOnPorts(collectActiveRunPorts([active]));
|
|
25261
25478
|
this.syncWorktreeRuns(
|
|
@@ -25294,7 +25511,7 @@ var init_orchestrator = __esm({
|
|
|
25294
25511
|
thread.repoPath,
|
|
25295
25512
|
thread.worktreePath,
|
|
25296
25513
|
runOutput.push,
|
|
25297
|
-
{ scriptName: resolvedName }
|
|
25514
|
+
{ scriptName: resolvedName, preferredPorts }
|
|
25298
25515
|
);
|
|
25299
25516
|
} catch (err) {
|
|
25300
25517
|
runOutput.flush();
|
|
@@ -25743,7 +25960,7 @@ var init_orchestrator = __esm({
|
|
|
25743
25960
|
return thread;
|
|
25744
25961
|
}
|
|
25745
25962
|
const start = Date.now();
|
|
25746
|
-
return new Promise((
|
|
25963
|
+
return new Promise((resolve2, reject) => {
|
|
25747
25964
|
let settled = false;
|
|
25748
25965
|
let timer;
|
|
25749
25966
|
const finish = (fn) => {
|
|
@@ -25761,7 +25978,7 @@ var init_orchestrator = __esm({
|
|
|
25761
25978
|
finish(() => reject(new Error(`Thread not found: ${thread.id}`)));
|
|
25762
25979
|
return;
|
|
25763
25980
|
}
|
|
25764
|
-
finish(() =>
|
|
25981
|
+
finish(() => resolve2(latest));
|
|
25765
25982
|
return;
|
|
25766
25983
|
}
|
|
25767
25984
|
if (event.type === "status_changed") {
|
|
@@ -25771,7 +25988,7 @@ var init_orchestrator = __esm({
|
|
|
25771
25988
|
return;
|
|
25772
25989
|
}
|
|
25773
25990
|
if (!["running", "queued"].includes(latest.status)) {
|
|
25774
|
-
finish(() =>
|
|
25991
|
+
finish(() => resolve2(latest));
|
|
25775
25992
|
}
|
|
25776
25993
|
}
|
|
25777
25994
|
});
|
|
@@ -25783,12 +26000,12 @@ var init_orchestrator = __esm({
|
|
|
25783
26000
|
}
|
|
25784
26001
|
const current = this.healStaleReportedActivity(raw);
|
|
25785
26002
|
if (!this.threadLooksLive(current)) {
|
|
25786
|
-
finish(() =>
|
|
26003
|
+
finish(() => resolve2(current));
|
|
25787
26004
|
return;
|
|
25788
26005
|
}
|
|
25789
26006
|
if (Date.now() - start > timeoutMs) {
|
|
25790
26007
|
if (opts?.resolveIfStillRunning) {
|
|
25791
|
-
finish(() =>
|
|
26008
|
+
finish(() => resolve2(current));
|
|
25792
26009
|
} else {
|
|
25793
26010
|
finish(() => reject(new Error("wait_for_turn timed out")));
|
|
25794
26011
|
}
|
|
@@ -26380,7 +26597,7 @@ var init_orchestrator = __esm({
|
|
|
26380
26597
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
26381
26598
|
return restored2;
|
|
26382
26599
|
}
|
|
26383
|
-
if (!(0,
|
|
26600
|
+
if (!(0, import_node_fs59.existsSync)(thread.worktreePath)) {
|
|
26384
26601
|
if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
|
|
26385
26602
|
throw new Error(
|
|
26386
26603
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
@@ -26526,14 +26743,14 @@ function armOne(schedule) {
|
|
|
26526
26743
|
if (!schedule.enabled) return;
|
|
26527
26744
|
const at = new Date(schedule.nextRunAt);
|
|
26528
26745
|
if (Number.isNaN(at.getTime())) return;
|
|
26529
|
-
const
|
|
26530
|
-
if (
|
|
26746
|
+
const delay2 = Math.max(0, at.getTime() - Date.now());
|
|
26747
|
+
if (delay2 <= 250) {
|
|
26531
26748
|
void fireSchedule(schedule.id).then(() => {
|
|
26532
26749
|
if (isThisProcessDesktopHost()) armSchedules();
|
|
26533
26750
|
});
|
|
26534
26751
|
return;
|
|
26535
26752
|
}
|
|
26536
|
-
const capped = Math.min(
|
|
26753
|
+
const capped = Math.min(delay2, SET_TIMEOUT_MAX);
|
|
26537
26754
|
const timer = setTimeout(() => {
|
|
26538
26755
|
timers.delete(schedule.id);
|
|
26539
26756
|
const live = getSchedule(schedule.id);
|
|
@@ -26671,6 +26888,7 @@ __export(index_exports, {
|
|
|
26671
26888
|
PLAN_FILE_REL: () => PLAN_FILE_REL,
|
|
26672
26889
|
PLAN_MODE_INSTRUCTION: () => PLAN_MODE_INSTRUCTION,
|
|
26673
26890
|
PLAN_QUESTION_ANSWERS_PREFIX: () => PLAN_QUESTION_ANSWERS_PREFIX,
|
|
26891
|
+
PORT_RANGE_SIZE: () => PORT_RANGE_SIZE,
|
|
26674
26892
|
PROFILE_NOTES_MAX: () => PROFILE_NOTES_MAX,
|
|
26675
26893
|
PR_DETAILS_JSON_FIELDS: () => PR_DETAILS_JSON_FIELDS,
|
|
26676
26894
|
REPO_REVIEW_NAME: () => REPO_REVIEW_NAME,
|
|
@@ -26681,6 +26899,7 @@ __export(index_exports, {
|
|
|
26681
26899
|
REVIEW_REQUEST_TEMPLATE: () => REVIEW_REQUEST_TEMPLATE,
|
|
26682
26900
|
REVIEW_SKILL_NAME: () => REVIEW_SKILL_NAME,
|
|
26683
26901
|
REVIEW_SKILL_PATH: () => REVIEW_SKILL_PATH,
|
|
26902
|
+
RUN_PORTS_REL: () => RUN_PORTS_REL,
|
|
26684
26903
|
RUN_SCRIPT_DESKTOP_ADOPT_MS: () => RUN_SCRIPT_DESKTOP_ADOPT_MS,
|
|
26685
26904
|
SEED_FULL_TOOL_MESSAGES: () => SEED_FULL_TOOL_MESSAGES,
|
|
26686
26905
|
SEED_MAX_CHARS: () => SEED_MAX_CHARS,
|
|
@@ -27111,6 +27330,7 @@ __export(index_exports, {
|
|
|
27111
27330
|
isOptionalServiceId: () => isOptionalServiceId,
|
|
27112
27331
|
isOrchestratorCapableAgent: () => isOrchestratorCapableAgent,
|
|
27113
27332
|
isOrchestratorThread: () => isOrchestratorThread,
|
|
27333
|
+
isOtherWorktreeListenerCwd: () => isOtherWorktreeListenerCwd,
|
|
27114
27334
|
isPidAlive: () => isPidAlive,
|
|
27115
27335
|
isPlaceholderBranch: () => isPlaceholderBranch,
|
|
27116
27336
|
isPlanQuestionAnswersMessage: () => isPlanQuestionAnswersMessage,
|
|
@@ -27142,6 +27362,7 @@ __export(index_exports, {
|
|
|
27142
27362
|
issueSourceLabel: () => issueSourceLabel,
|
|
27143
27363
|
issueTicketFromThread: () => issueTicketFromThread,
|
|
27144
27364
|
killListenersOnPorts: () => killListenersOnPorts,
|
|
27365
|
+
killStaleWorktreeListeners: () => killStaleWorktreeListeners,
|
|
27145
27366
|
killableListenerPids: () => killableListenerPids,
|
|
27146
27367
|
lastAgentReply: () => lastAgentReply,
|
|
27147
27368
|
lastAssistantMessageText: () => lastAssistantMessageText,
|
|
@@ -27189,6 +27410,7 @@ __export(index_exports, {
|
|
|
27189
27410
|
listWorkspaces: () => listWorkspaces,
|
|
27190
27411
|
listWorktreeFiles: () => listWorktreeFiles,
|
|
27191
27412
|
listWorktrees: () => listWorktrees,
|
|
27413
|
+
listenerCwd: () => listenerCwd,
|
|
27192
27414
|
liveActivitySummary: () => liveActivitySummary,
|
|
27193
27415
|
loadAppSettings: () => loadAppSettings,
|
|
27194
27416
|
loadBrightsyConfig: () => loadBrightsyConfig,
|
|
@@ -27196,9 +27418,11 @@ __export(index_exports, {
|
|
|
27196
27418
|
loadHomeBoardInputs: () => loadHomeBoardInputs,
|
|
27197
27419
|
loadRepoSettings: () => loadRepoSettings,
|
|
27198
27420
|
loadWorkspaceSettings: () => loadWorkspaceSettings,
|
|
27421
|
+
loadWorktreeRunPorts: () => loadWorktreeRunPorts,
|
|
27199
27422
|
localhostPreviewUrl: () => localhostPreviewUrl,
|
|
27200
27423
|
locksDir: () => locksDir,
|
|
27201
27424
|
loginAgent: () => loginAgent,
|
|
27425
|
+
looksLikeComposerSkillExpansion: () => looksLikeComposerSkillExpansion,
|
|
27202
27426
|
looksLikeConversationSummary: () => looksLikeConversationSummary,
|
|
27203
27427
|
looksLikeSkillBody: () => looksLikeSkillBody,
|
|
27204
27428
|
lookupSoccerTeam: () => lookupSoccerTeam,
|
|
@@ -27389,6 +27613,7 @@ __export(index_exports, {
|
|
|
27389
27613
|
saveAbleTimeConnection: () => saveAbleTimeConnection,
|
|
27390
27614
|
saveAppSettings: () => saveAppSettings,
|
|
27391
27615
|
saveLinearOAuth: () => saveLinearOAuth,
|
|
27616
|
+
saveWorktreeRunPorts: () => saveWorktreeRunPorts,
|
|
27392
27617
|
schedulesPath: () => schedulesPath,
|
|
27393
27618
|
scrubGithubTokensFromChildEnv: () => scrubGithubTokensFromChildEnv,
|
|
27394
27619
|
searchAbleTimeTasks: () => searchAbleTimeTasks,
|
|
@@ -27478,6 +27703,8 @@ __export(index_exports, {
|
|
|
27478
27703
|
toolFilePath: () => toolFilePath,
|
|
27479
27704
|
totalTokens: () => totalTokens,
|
|
27480
27705
|
trustSystemCertificates: () => trustSystemCertificates,
|
|
27706
|
+
tryReservePort: () => tryReservePort,
|
|
27707
|
+
tryReservePorts: () => tryReservePorts,
|
|
27481
27708
|
turnCostUsdFromCursorUsage: () => turnCostUsdFromCursorUsage,
|
|
27482
27709
|
updateAbleTimeTask: () => updateAbleTimeTask,
|
|
27483
27710
|
updateAdvancedSettings: () => updateAdvancedSettings,
|
|
@@ -27516,6 +27743,7 @@ __export(index_exports, {
|
|
|
27516
27743
|
worktreeDisplayLabel: () => worktreeDisplayLabel,
|
|
27517
27744
|
worktreeDisplayLabelForGroup: () => worktreeDisplayLabelForGroup,
|
|
27518
27745
|
worktreeNameFromPath: () => worktreeNameFromPath,
|
|
27746
|
+
worktreeRunPortsPath: () => worktreeRunPortsPath,
|
|
27519
27747
|
worktreeSlugForTicket: () => worktreeSlugForTicket,
|
|
27520
27748
|
worktreesRoot: () => worktreesRoot,
|
|
27521
27749
|
wrapReviewSkillMarkdown: () => wrapReviewSkillMarkdown,
|
|
@@ -28002,14 +28230,14 @@ async function startLinearOAuth(opts) {
|
|
|
28002
28230
|
const pkce = createLinearPkce();
|
|
28003
28231
|
const authorizeUrl = linearOAuthAuthorizeUrl(clientId, state, pkce.challenge);
|
|
28004
28232
|
const timeoutMs = opts?.timeoutMs ?? 5 * 6e4;
|
|
28005
|
-
const code = await new Promise((
|
|
28233
|
+
const code = await new Promise((resolve2, reject) => {
|
|
28006
28234
|
let settled = false;
|
|
28007
28235
|
const finish = (err, value) => {
|
|
28008
28236
|
if (settled) return;
|
|
28009
28237
|
settled = true;
|
|
28010
28238
|
cleanup();
|
|
28011
28239
|
if (err) reject(err);
|
|
28012
|
-
else
|
|
28240
|
+
else resolve2(value);
|
|
28013
28241
|
};
|
|
28014
28242
|
const server = (0, import_node_http2.createServer)((req, res) => {
|
|
28015
28243
|
try {
|
|
@@ -30171,7 +30399,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
|
30171
30399
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
30172
30400
|
var import_zod9 = require("zod");
|
|
30173
30401
|
var import_node_crypto17 = require("crypto");
|
|
30174
|
-
var
|
|
30402
|
+
var import_node_path60 = require("path");
|
|
30175
30403
|
init_orchestrator();
|
|
30176
30404
|
init_task_state();
|
|
30177
30405
|
init_worktree();
|
|
@@ -30507,8 +30735,8 @@ ${link}` : link;
|
|
|
30507
30735
|
}
|
|
30508
30736
|
|
|
30509
30737
|
// src/slack/outbound-watch.ts
|
|
30510
|
-
var
|
|
30511
|
-
var
|
|
30738
|
+
var import_node_fs61 = require("fs");
|
|
30739
|
+
var import_node_path57 = require("path");
|
|
30512
30740
|
init_paths();
|
|
30513
30741
|
init_private_file();
|
|
30514
30742
|
init_secure_file();
|
|
@@ -30516,19 +30744,19 @@ init_thread_store();
|
|
|
30516
30744
|
init_injected_notices();
|
|
30517
30745
|
|
|
30518
30746
|
// src/slack/reply-target.ts
|
|
30519
|
-
var
|
|
30520
|
-
var
|
|
30747
|
+
var import_node_fs60 = require("fs");
|
|
30748
|
+
var import_node_path55 = require("path");
|
|
30521
30749
|
init_paths();
|
|
30522
30750
|
init_private_file();
|
|
30523
30751
|
init_secure_file();
|
|
30524
30752
|
function storePath2() {
|
|
30525
|
-
return (0,
|
|
30753
|
+
return (0, import_node_path55.join)(appDataDir(), "slack-reply-to.json");
|
|
30526
30754
|
}
|
|
30527
30755
|
function readStore2() {
|
|
30528
30756
|
const path2 = storePath2();
|
|
30529
|
-
if (!(0,
|
|
30757
|
+
if (!(0, import_node_fs60.existsSync)(path2)) return {};
|
|
30530
30758
|
try {
|
|
30531
|
-
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0,
|
|
30759
|
+
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs60.readFileSync)(path2, "utf8"));
|
|
30532
30760
|
return parsed?.targets && typeof parsed.targets === "object" ? parsed.targets : {};
|
|
30533
30761
|
} catch {
|
|
30534
30762
|
return {};
|
|
@@ -30545,11 +30773,11 @@ function getSlackReplyTarget(threadId) {
|
|
|
30545
30773
|
}
|
|
30546
30774
|
|
|
30547
30775
|
// src/slack/workspaces.ts
|
|
30548
|
-
var
|
|
30776
|
+
var import_node_path56 = require("path");
|
|
30549
30777
|
init_paths();
|
|
30550
30778
|
init_secure_file();
|
|
30551
30779
|
function storePath3() {
|
|
30552
|
-
return (0,
|
|
30780
|
+
return (0, import_node_path56.join)(appDataDir(), "slack-workspaces.json");
|
|
30553
30781
|
}
|
|
30554
30782
|
function readStore3() {
|
|
30555
30783
|
try {
|
|
@@ -30665,7 +30893,7 @@ var POLL_INTERVAL_MS = 12e3;
|
|
|
30665
30893
|
var lastPollMs = 0;
|
|
30666
30894
|
var nameCache = /* @__PURE__ */ new Map();
|
|
30667
30895
|
function storePath4() {
|
|
30668
|
-
return (0,
|
|
30896
|
+
return (0, import_node_path57.join)(appDataDir(), "slack-outbound-watch.json");
|
|
30669
30897
|
}
|
|
30670
30898
|
function watchId(teamId, channelId, ts) {
|
|
30671
30899
|
return `${teamId}:${channelId}:${ts}`;
|
|
@@ -30678,9 +30906,9 @@ function tsNewer(a, b) {
|
|
|
30678
30906
|
}
|
|
30679
30907
|
function readStore4() {
|
|
30680
30908
|
const path2 = storePath4();
|
|
30681
|
-
if (!(0,
|
|
30909
|
+
if (!(0, import_node_fs61.existsSync)(path2)) return [];
|
|
30682
30910
|
try {
|
|
30683
|
-
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0,
|
|
30911
|
+
const parsed = isSecureFileEncrypted(path2) ? readSecureJson(path2) : JSON.parse((0, import_node_fs61.readFileSync)(path2, "utf8"));
|
|
30684
30912
|
return Array.isArray(parsed?.watches) ? parsed.watches : [];
|
|
30685
30913
|
} catch {
|
|
30686
30914
|
return [];
|
|
@@ -32431,27 +32659,27 @@ init_gh_errors();
|
|
|
32431
32659
|
init_git_auth_mode();
|
|
32432
32660
|
|
|
32433
32661
|
// src/board/load-home-board.ts
|
|
32434
|
-
var
|
|
32435
|
-
var
|
|
32662
|
+
var import_node_fs63 = require("fs");
|
|
32663
|
+
var import_node_path59 = require("path");
|
|
32436
32664
|
init_worktree();
|
|
32437
32665
|
init_paths();
|
|
32438
32666
|
|
|
32439
32667
|
// src/board/board-pins.ts
|
|
32440
32668
|
var import_node_crypto16 = require("crypto");
|
|
32441
|
-
var
|
|
32442
|
-
var
|
|
32669
|
+
var import_node_fs62 = require("fs");
|
|
32670
|
+
var import_node_path58 = require("path");
|
|
32443
32671
|
init_paths();
|
|
32444
32672
|
init_home_board();
|
|
32445
32673
|
var FILE = "home-board-pins.json";
|
|
32446
32674
|
var VERSION = 1;
|
|
32447
32675
|
function pinsFile() {
|
|
32448
|
-
return (0,
|
|
32676
|
+
return (0, import_node_path58.join)(appDataDir(), FILE);
|
|
32449
32677
|
}
|
|
32450
32678
|
function readDisk() {
|
|
32451
32679
|
const path2 = pinsFile();
|
|
32452
|
-
if (!(0,
|
|
32680
|
+
if (!(0, import_node_fs62.existsSync)(path2)) return [];
|
|
32453
32681
|
try {
|
|
32454
|
-
const raw = JSON.parse((0,
|
|
32682
|
+
const raw = JSON.parse((0, import_node_fs62.readFileSync)(path2, "utf8"));
|
|
32455
32683
|
if (raw?.version !== VERSION || !Array.isArray(raw.items)) return [];
|
|
32456
32684
|
return raw.items.filter((item) => item?.id && item.kind && item.ref);
|
|
32457
32685
|
} catch {
|
|
@@ -32459,8 +32687,8 @@ function readDisk() {
|
|
|
32459
32687
|
}
|
|
32460
32688
|
}
|
|
32461
32689
|
function writeDisk(items) {
|
|
32462
|
-
(0,
|
|
32463
|
-
(0,
|
|
32690
|
+
(0, import_node_fs62.mkdirSync)(appDataDir(), { recursive: true });
|
|
32691
|
+
(0, import_node_fs62.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
|
|
32464
32692
|
}
|
|
32465
32693
|
function listBoardPins() {
|
|
32466
32694
|
return readDisk();
|
|
@@ -32512,7 +32740,7 @@ function replaceBoardPins(items) {
|
|
|
32512
32740
|
}
|
|
32513
32741
|
function clearBoardPins() {
|
|
32514
32742
|
try {
|
|
32515
|
-
(0,
|
|
32743
|
+
(0, import_node_fs62.unlinkSync)(pinsFile());
|
|
32516
32744
|
} catch {
|
|
32517
32745
|
}
|
|
32518
32746
|
}
|
|
@@ -32529,7 +32757,7 @@ function homeBoardWorkspaceKey(workspaces) {
|
|
|
32529
32757
|
return workspaces.map((w) => w.path).filter(Boolean).sort().join("\n");
|
|
32530
32758
|
}
|
|
32531
32759
|
function cacheFile() {
|
|
32532
|
-
return (0,
|
|
32760
|
+
return (0, import_node_path59.join)(appDataDir(), "home-board-cache.json");
|
|
32533
32761
|
}
|
|
32534
32762
|
function emptyInputs() {
|
|
32535
32763
|
return {
|
|
@@ -32555,9 +32783,9 @@ function shouldCacheHomeBoardInputs(inputs) {
|
|
|
32555
32783
|
}
|
|
32556
32784
|
function readDiskCache() {
|
|
32557
32785
|
const path2 = cacheFile();
|
|
32558
|
-
if (!(0,
|
|
32786
|
+
if (!(0, import_node_fs63.existsSync)(path2)) return null;
|
|
32559
32787
|
try {
|
|
32560
|
-
const raw = JSON.parse((0,
|
|
32788
|
+
const raw = JSON.parse((0, import_node_fs63.readFileSync)(path2, "utf8"));
|
|
32561
32789
|
if (raw?.version !== CACHE_VERSION || typeof raw.fetchedAt !== "number") {
|
|
32562
32790
|
return null;
|
|
32563
32791
|
}
|
|
@@ -32571,14 +32799,14 @@ function readDiskCache() {
|
|
|
32571
32799
|
}
|
|
32572
32800
|
function writeDiskCache(entry) {
|
|
32573
32801
|
try {
|
|
32574
|
-
(0,
|
|
32575
|
-
(0,
|
|
32802
|
+
(0, import_node_fs63.mkdirSync)(appDataDir(), { recursive: true });
|
|
32803
|
+
(0, import_node_fs63.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
|
|
32576
32804
|
} catch {
|
|
32577
32805
|
}
|
|
32578
32806
|
}
|
|
32579
32807
|
function deleteDiskCache() {
|
|
32580
32808
|
try {
|
|
32581
|
-
(0,
|
|
32809
|
+
(0, import_node_fs63.unlinkSync)(cacheFile());
|
|
32582
32810
|
} catch {
|
|
32583
32811
|
}
|
|
32584
32812
|
}
|
|
@@ -32765,14 +32993,14 @@ function orchCreateThreadAgentNote(input) {
|
|
|
32765
32993
|
var MAX_ORCH_THREADS = 5;
|
|
32766
32994
|
var CREATE_THREAD_TIMEOUT_MS = 9e4;
|
|
32767
32995
|
function withTimeout2(promise, ms, label) {
|
|
32768
|
-
return new Promise((
|
|
32996
|
+
return new Promise((resolve2, reject) => {
|
|
32769
32997
|
const timer = setTimeout(() => {
|
|
32770
32998
|
reject(new Error(`${label} timed out after ${Math.round(ms / 1e3)}s`));
|
|
32771
32999
|
}, ms);
|
|
32772
33000
|
promise.then(
|
|
32773
33001
|
(value) => {
|
|
32774
33002
|
clearTimeout(timer);
|
|
32775
|
-
|
|
33003
|
+
resolve2(value);
|
|
32776
33004
|
},
|
|
32777
33005
|
(err) => {
|
|
32778
33006
|
clearTimeout(timer);
|
|
@@ -32944,7 +33172,7 @@ async function startMcpServer() {
|
|
|
32944
33172
|
async () => {
|
|
32945
33173
|
const threads = orch.getThreads(true);
|
|
32946
33174
|
const lines = threads.map((t) => {
|
|
32947
|
-
const repo = t.repoPath === GLOBAL_WORKSPACE_ID2 ? "Orchestration" : (0,
|
|
33175
|
+
const repo = t.repoPath === GLOBAL_WORKSPACE_ID2 ? "Orchestration" : (0, import_node_path60.basename)(t.repoPath) || t.repoPath;
|
|
32948
33176
|
const live = orch.threadLooksLive(t) ? readTurnLive(t.id) : null;
|
|
32949
33177
|
const parent = t.parentThreadId ? ` parent:${t.parentThreadId.slice(0, 8)}` : "";
|
|
32950
33178
|
const preview = lastMessagePreview(t.messages, 80);
|
|
@@ -34398,13 +34626,13 @@ async function runCloudConnect(opts) {
|
|
|
34398
34626
|
log(`poll error: ${msg}`);
|
|
34399
34627
|
}
|
|
34400
34628
|
}
|
|
34401
|
-
await new Promise((
|
|
34402
|
-
const t = setTimeout(
|
|
34629
|
+
await new Promise((resolve2) => {
|
|
34630
|
+
const t = setTimeout(resolve2, pollMs);
|
|
34403
34631
|
opts.signal?.addEventListener(
|
|
34404
34632
|
"abort",
|
|
34405
34633
|
() => {
|
|
34406
34634
|
clearTimeout(t);
|
|
34407
|
-
|
|
34635
|
+
resolve2();
|
|
34408
34636
|
},
|
|
34409
34637
|
{ once: true }
|
|
34410
34638
|
);
|
|
@@ -34612,14 +34840,14 @@ function slackOAuthAuthorizeUrl(clientId, state) {
|
|
|
34612
34840
|
return `https://slack.com/oauth/v2/authorize?${params.toString()}`;
|
|
34613
34841
|
}
|
|
34614
34842
|
function sleep(ms, signal) {
|
|
34615
|
-
return new Promise((
|
|
34843
|
+
return new Promise((resolve2, reject) => {
|
|
34616
34844
|
if (signal?.aborted) {
|
|
34617
34845
|
reject(new SlackOAuthCancelledError());
|
|
34618
34846
|
return;
|
|
34619
34847
|
}
|
|
34620
34848
|
const timer = setTimeout(() => {
|
|
34621
34849
|
signal?.removeEventListener("abort", onAbort);
|
|
34622
|
-
|
|
34850
|
+
resolve2();
|
|
34623
34851
|
}, ms);
|
|
34624
34852
|
const onAbort = () => {
|
|
34625
34853
|
clearTimeout(timer);
|
|
@@ -34811,12 +35039,12 @@ function resolveWebSocket(ctor) {
|
|
|
34811
35039
|
return nodeWebSocketCtor();
|
|
34812
35040
|
}
|
|
34813
35041
|
function wait(ms, signal) {
|
|
34814
|
-
return new Promise((
|
|
35042
|
+
return new Promise((resolve2, reject) => {
|
|
34815
35043
|
if (signal?.aborted) {
|
|
34816
35044
|
reject(new Error("aborted"));
|
|
34817
35045
|
return;
|
|
34818
35046
|
}
|
|
34819
|
-
const t = setTimeout(
|
|
35047
|
+
const t = setTimeout(resolve2, ms);
|
|
34820
35048
|
signal?.addEventListener(
|
|
34821
35049
|
"abort",
|
|
34822
35050
|
() => {
|
|
@@ -34861,14 +35089,14 @@ async function runSlackSocketMode(opts) {
|
|
|
34861
35089
|
}
|
|
34862
35090
|
}
|
|
34863
35091
|
function connectSession(ws, opts, log) {
|
|
34864
|
-
return new Promise((
|
|
35092
|
+
return new Promise((resolve2, reject) => {
|
|
34865
35093
|
let settled = false;
|
|
34866
35094
|
const finish = (err) => {
|
|
34867
35095
|
if (settled) return;
|
|
34868
35096
|
settled = true;
|
|
34869
35097
|
opts.signal?.removeEventListener("abort", onAbort);
|
|
34870
35098
|
if (err) reject(err);
|
|
34871
|
-
else
|
|
35099
|
+
else resolve2();
|
|
34872
35100
|
};
|
|
34873
35101
|
const onAbort = () => {
|
|
34874
35102
|
try {
|
|
@@ -35039,12 +35267,12 @@ var CLAIM_FALLBACK_MS = 400;
|
|
|
35039
35267
|
var BACKOFF_START_MS2 = 1e3;
|
|
35040
35268
|
var BACKOFF_MAX_MS2 = 3e4;
|
|
35041
35269
|
function wait2(ms, signal) {
|
|
35042
|
-
return new Promise((
|
|
35270
|
+
return new Promise((resolve2, reject) => {
|
|
35043
35271
|
if (signal?.aborted) {
|
|
35044
35272
|
reject(new Error("aborted"));
|
|
35045
35273
|
return;
|
|
35046
35274
|
}
|
|
35047
|
-
const t = setTimeout(
|
|
35275
|
+
const t = setTimeout(resolve2, ms);
|
|
35048
35276
|
signal?.addEventListener(
|
|
35049
35277
|
"abort",
|
|
35050
35278
|
() => {
|
|
@@ -35103,7 +35331,7 @@ async function runSlackRelayClient(opts) {
|
|
|
35103
35331
|
}
|
|
35104
35332
|
}
|
|
35105
35333
|
function connectSession2(ws, opts, log) {
|
|
35106
|
-
return new Promise((
|
|
35334
|
+
return new Promise((resolve2, reject) => {
|
|
35107
35335
|
let settled = false;
|
|
35108
35336
|
const pending = /* @__PURE__ */ new Map();
|
|
35109
35337
|
let relayAnswersClaims = false;
|
|
@@ -35137,7 +35365,7 @@ function connectSession2(ws, opts, log) {
|
|
|
35137
35365
|
stopKeepalive();
|
|
35138
35366
|
opts.signal?.removeEventListener("abort", onAbort);
|
|
35139
35367
|
if (err) reject(err);
|
|
35140
|
-
else
|
|
35368
|
+
else resolve2();
|
|
35141
35369
|
};
|
|
35142
35370
|
const onAbort = () => {
|
|
35143
35371
|
try {
|
|
@@ -36063,9 +36291,9 @@ var import_node_http4 = require("http");
|
|
|
36063
36291
|
var import_ws3 = require("ws");
|
|
36064
36292
|
|
|
36065
36293
|
// src/slack/relay-static.ts
|
|
36066
|
-
var
|
|
36294
|
+
var import_node_fs64 = require("fs");
|
|
36067
36295
|
var import_promises = require("fs/promises");
|
|
36068
|
-
var
|
|
36296
|
+
var import_node_path61 = __toESM(require("path"), 1);
|
|
36069
36297
|
var TYPES = {
|
|
36070
36298
|
".css": "text/css; charset=utf-8",
|
|
36071
36299
|
".html": "text/html; charset=utf-8",
|
|
@@ -36096,9 +36324,9 @@ function resolveStaticPath(root, requestUrl) {
|
|
|
36096
36324
|
return null;
|
|
36097
36325
|
}
|
|
36098
36326
|
if (!pathname.startsWith("/") || pathname.includes("\0")) return null;
|
|
36099
|
-
const rootResolved =
|
|
36100
|
-
const candidate =
|
|
36101
|
-
if (candidate !== rootResolved && !candidate.startsWith(rootResolved +
|
|
36327
|
+
const rootResolved = import_node_path61.default.resolve(root);
|
|
36328
|
+
const candidate = import_node_path61.default.resolve(rootResolved, `.${pathname}`);
|
|
36329
|
+
if (candidate !== rootResolved && !candidate.startsWith(rootResolved + import_node_path61.default.sep)) {
|
|
36102
36330
|
return null;
|
|
36103
36331
|
}
|
|
36104
36332
|
return candidate;
|
|
@@ -36112,7 +36340,7 @@ async function fileSize(file) {
|
|
|
36112
36340
|
}
|
|
36113
36341
|
}
|
|
36114
36342
|
function sendFile(req, res, file, size) {
|
|
36115
|
-
const ext =
|
|
36343
|
+
const ext = import_node_path61.default.extname(file).toLowerCase();
|
|
36116
36344
|
res.writeHead(200, {
|
|
36117
36345
|
"Content-Type": TYPES[ext] ?? "application/octet-stream",
|
|
36118
36346
|
"Content-Length": size,
|
|
@@ -36122,7 +36350,7 @@ function sendFile(req, res, file, size) {
|
|
|
36122
36350
|
res.end();
|
|
36123
36351
|
return true;
|
|
36124
36352
|
}
|
|
36125
|
-
(0,
|
|
36353
|
+
(0, import_node_fs64.createReadStream)(file).pipe(res);
|
|
36126
36354
|
return true;
|
|
36127
36355
|
}
|
|
36128
36356
|
async function tryServeStatic(req, res, root) {
|
|
@@ -36131,7 +36359,7 @@ async function tryServeStatic(req, res, root) {
|
|
|
36131
36359
|
if (!candidate) return false;
|
|
36132
36360
|
const direct = await fileSize(candidate);
|
|
36133
36361
|
if (direct != null) return sendFile(req, res, candidate, direct);
|
|
36134
|
-
const asIndex =
|
|
36362
|
+
const asIndex = import_node_path61.default.join(candidate, "index.html");
|
|
36135
36363
|
const indexSize = await fileSize(asIndex);
|
|
36136
36364
|
if (indexSize != null) return sendFile(req, res, asIndex, indexSize);
|
|
36137
36365
|
return false;
|
|
@@ -36331,9 +36559,9 @@ async function startSlackRelayServer(opts) {
|
|
|
36331
36559
|
});
|
|
36332
36560
|
const port = opts.port ?? 0;
|
|
36333
36561
|
const host = opts.host ?? "0.0.0.0";
|
|
36334
|
-
await new Promise((
|
|
36562
|
+
await new Promise((resolve2, reject) => {
|
|
36335
36563
|
httpServer.once("error", reject);
|
|
36336
|
-
httpServer.listen(port, host, () =>
|
|
36564
|
+
httpServer.listen(port, host, () => resolve2());
|
|
36337
36565
|
});
|
|
36338
36566
|
const address = httpServer.address();
|
|
36339
36567
|
const boundPort = typeof address === "object" && address ? address.port : typeof port === "number" ? port : 0;
|
|
@@ -36362,11 +36590,11 @@ async function startSlackRelayServer(opts) {
|
|
|
36362
36590
|
close: async () => {
|
|
36363
36591
|
opts.signal?.removeEventListener("abort", onAbort);
|
|
36364
36592
|
ac.abort();
|
|
36365
|
-
await new Promise((
|
|
36366
|
-
wss.close(() =>
|
|
36593
|
+
await new Promise((resolve2) => {
|
|
36594
|
+
wss.close(() => resolve2());
|
|
36367
36595
|
});
|
|
36368
|
-
await new Promise((
|
|
36369
|
-
httpServer.close((err) => err ? reject(err) :
|
|
36596
|
+
await new Promise((resolve2, reject) => {
|
|
36597
|
+
httpServer.close((err) => err ? reject(err) : resolve2());
|
|
36370
36598
|
});
|
|
36371
36599
|
await socketModeDone.catch(() => void 0);
|
|
36372
36600
|
}
|
|
@@ -36462,6 +36690,7 @@ async function startSlackRelayServer(opts) {
|
|
|
36462
36690
|
PLAN_FILE_REL,
|
|
36463
36691
|
PLAN_MODE_INSTRUCTION,
|
|
36464
36692
|
PLAN_QUESTION_ANSWERS_PREFIX,
|
|
36693
|
+
PORT_RANGE_SIZE,
|
|
36465
36694
|
PROFILE_NOTES_MAX,
|
|
36466
36695
|
PR_DETAILS_JSON_FIELDS,
|
|
36467
36696
|
REPO_REVIEW_NAME,
|
|
@@ -36472,6 +36701,7 @@ async function startSlackRelayServer(opts) {
|
|
|
36472
36701
|
REVIEW_REQUEST_TEMPLATE,
|
|
36473
36702
|
REVIEW_SKILL_NAME,
|
|
36474
36703
|
REVIEW_SKILL_PATH,
|
|
36704
|
+
RUN_PORTS_REL,
|
|
36475
36705
|
RUN_SCRIPT_DESKTOP_ADOPT_MS,
|
|
36476
36706
|
SEED_FULL_TOOL_MESSAGES,
|
|
36477
36707
|
SEED_MAX_CHARS,
|
|
@@ -36902,6 +37132,7 @@ async function startSlackRelayServer(opts) {
|
|
|
36902
37132
|
isOptionalServiceId,
|
|
36903
37133
|
isOrchestratorCapableAgent,
|
|
36904
37134
|
isOrchestratorThread,
|
|
37135
|
+
isOtherWorktreeListenerCwd,
|
|
36905
37136
|
isPidAlive,
|
|
36906
37137
|
isPlaceholderBranch,
|
|
36907
37138
|
isPlanQuestionAnswersMessage,
|
|
@@ -36933,6 +37164,7 @@ async function startSlackRelayServer(opts) {
|
|
|
36933
37164
|
issueSourceLabel,
|
|
36934
37165
|
issueTicketFromThread,
|
|
36935
37166
|
killListenersOnPorts,
|
|
37167
|
+
killStaleWorktreeListeners,
|
|
36936
37168
|
killableListenerPids,
|
|
36937
37169
|
lastAgentReply,
|
|
36938
37170
|
lastAssistantMessageText,
|
|
@@ -36980,6 +37212,7 @@ async function startSlackRelayServer(opts) {
|
|
|
36980
37212
|
listWorkspaces,
|
|
36981
37213
|
listWorktreeFiles,
|
|
36982
37214
|
listWorktrees,
|
|
37215
|
+
listenerCwd,
|
|
36983
37216
|
liveActivitySummary,
|
|
36984
37217
|
loadAppSettings,
|
|
36985
37218
|
loadBrightsyConfig,
|
|
@@ -36987,9 +37220,11 @@ async function startSlackRelayServer(opts) {
|
|
|
36987
37220
|
loadHomeBoardInputs,
|
|
36988
37221
|
loadRepoSettings,
|
|
36989
37222
|
loadWorkspaceSettings,
|
|
37223
|
+
loadWorktreeRunPorts,
|
|
36990
37224
|
localhostPreviewUrl,
|
|
36991
37225
|
locksDir,
|
|
36992
37226
|
loginAgent,
|
|
37227
|
+
looksLikeComposerSkillExpansion,
|
|
36993
37228
|
looksLikeConversationSummary,
|
|
36994
37229
|
looksLikeSkillBody,
|
|
36995
37230
|
lookupSoccerTeam,
|
|
@@ -37180,6 +37415,7 @@ async function startSlackRelayServer(opts) {
|
|
|
37180
37415
|
saveAbleTimeConnection,
|
|
37181
37416
|
saveAppSettings,
|
|
37182
37417
|
saveLinearOAuth,
|
|
37418
|
+
saveWorktreeRunPorts,
|
|
37183
37419
|
schedulesPath,
|
|
37184
37420
|
scrubGithubTokensFromChildEnv,
|
|
37185
37421
|
searchAbleTimeTasks,
|
|
@@ -37269,6 +37505,8 @@ async function startSlackRelayServer(opts) {
|
|
|
37269
37505
|
toolFilePath,
|
|
37270
37506
|
totalTokens,
|
|
37271
37507
|
trustSystemCertificates,
|
|
37508
|
+
tryReservePort,
|
|
37509
|
+
tryReservePorts,
|
|
37272
37510
|
turnCostUsdFromCursorUsage,
|
|
37273
37511
|
updateAbleTimeTask,
|
|
37274
37512
|
updateAdvancedSettings,
|
|
@@ -37307,6 +37545,7 @@ async function startSlackRelayServer(opts) {
|
|
|
37307
37545
|
worktreeDisplayLabel,
|
|
37308
37546
|
worktreeDisplayLabelForGroup,
|
|
37309
37547
|
worktreeNameFromPath,
|
|
37548
|
+
worktreeRunPortsPath,
|
|
37310
37549
|
worktreeSlugForTicket,
|
|
37311
37550
|
worktreesRoot,
|
|
37312
37551
|
wrapReviewSkillMarkdown,
|