@sideboard-ai/core 0.1.231 → 0.1.233
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/cursor-runner.cjs +167 -62
- package/dist/agents/cursor-runner.js +16 -9
- package/dist/{agents-ENAQHQRZ.js → agents-J2CUJHPC.js} +16 -6
- package/dist/{agents-TCTEAK6M.js → agents-LDYMFW6N.js} +17 -7
- package/dist/{chunk-TQBUXKIB.js → chunk-26T43LBM.js} +97 -11
- package/dist/{chunk-PO4M4JAJ.js → chunk-2P4XKWV2.js} +1 -1
- package/dist/{chunk-ABOBTSO6.js → chunk-2UG25RMK.js} +18 -5
- package/dist/{chunk-4CZ25DO2.js → chunk-4VFOJZPS.js} +2 -2
- package/dist/{chunk-N5TX66CD.js → chunk-7H2CVVLF.js} +2 -2
- package/dist/{chunk-HZLZ34FK.js → chunk-BGHDWCAV.js} +69 -30
- package/dist/{chunk-SZJZEFTY.js → chunk-DD67JWTN.js} +1 -1
- package/dist/{chunk-JJRRLCCS.js → chunk-NLETJP7Z.js} +64 -30
- package/dist/{chunk-FA4CPYCY.js → chunk-PZQNE5X4.js} +81 -41
- package/dist/{chunk-HVUVQXZ2.js → chunk-QVN2WOKJ.js} +18 -5
- package/dist/{chunk-HZFLKVGC.js → chunk-S2OEFXST.js} +1 -1
- package/dist/{chunk-SXFRXNBM.js → chunk-SPAMHHJH.js} +1 -1
- package/dist/{chunk-ZXJMAKEP.js → chunk-TNVJPFHM.js} +5 -5
- package/dist/{chunk-UNTOZA3C.js → chunk-TWXSZYR2.js} +1 -1
- package/dist/{chunk-6L25K7BE.js → chunk-TXMFBL3X.js} +195 -73
- package/dist/{connected-teams-PIBQTOJU.js → connected-teams-JUJAQZZE.js} +2 -2
- package/dist/{connected-teams-RVD3PFAG.js → connected-teams-KQUDU7LZ.js} +2 -2
- package/dist/{coordinator-prompt-YKLXQTWH.js → coordinator-prompt-CE7MN6QY.js} +4 -4
- package/dist/{coordinator-prompt-DFXYTM6D.js → coordinator-prompt-IGDMFKCD.js} +4 -4
- package/dist/{global-workspace-EYZKYHAO.js → global-workspace-7WH24UFO.js} +4 -4
- package/dist/{global-workspace-4SPANNJT.js → global-workspace-NCIC2Y2U.js} +4 -4
- package/dist/index.cjs +542 -337
- package/dist/index.d.cts +32 -4
- package/dist/index.d.ts +32 -4
- package/dist/index.js +31 -8
- package/dist/mcp/run-stdio.cjs +465 -315
- package/dist/mcp/run-stdio.js +7 -7
- package/dist/{orchestrator-ZT3SJVKF.js → orchestrator-BXALNM4M.js} +8 -8
- package/dist/{orchestrator-HMJPNUN5.js → orchestrator-NLZMHTLX.js} +7 -7
- package/dist/{run-UEQM4JMZ.js → run-PCX5QWR4.js} +1 -1
- package/dist/{run-QDZCTP4Y.js → run-TB7RBII2.js} +1 -1
- package/dist/{workspaces-73Y7IJY2.js → workspaces-H2TRFDE2.js} +4 -4
- package/dist/{workspaces-FQCSCTNH.js → workspaces-NSQZSDQD.js} +4 -4
- package/dist/{worktree-DOPRKG7K.js → worktree-FMIX4BRV.js} +3 -3
- package/dist/{worktree-36VEFUJN.js → worktree-W7BSI4GU.js} +3 -3
- package/dist/{worktree-exclude-K7QK4RI5.js → worktree-exclude-5N2KTYIT.js} +2 -2
- package/dist/{worktree-exclude-L32WEBX6.js → worktree-exclude-RXZPTCNH.js} +2 -2
- package/package.json +2 -2
|
@@ -2,8 +2,9 @@ import {
|
|
|
2
2
|
appDataDir
|
|
3
3
|
} from "./chunk-WFUDY6PC.js";
|
|
4
4
|
import {
|
|
5
|
+
npmGlobalNodeModules,
|
|
5
6
|
run
|
|
6
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-QVN2WOKJ.js";
|
|
7
8
|
import {
|
|
8
9
|
isElectronLikeCommand,
|
|
9
10
|
wrapElectronAsNodeLaunch
|
|
@@ -750,6 +751,87 @@ async function resolveNodeLaunch(scriptPath) {
|
|
|
750
751
|
};
|
|
751
752
|
}
|
|
752
753
|
|
|
754
|
+
// src/agents/cursor-sdk-resolve.ts
|
|
755
|
+
import { existsSync as existsSync4, readFileSync as readFileSync2 } from "fs";
|
|
756
|
+
import { createRequire } from "module";
|
|
757
|
+
import { basename, dirname as dirname2, join as join4 } from "path";
|
|
758
|
+
import { fileURLToPath, pathToFileURL } from "url";
|
|
759
|
+
var CURSOR_SDK_INSTALL_HINT = "Cursor SDK is not installed. Settings \u2192 Agents \u2192 Cursor \u2192 Install (`npm i -g @cursor/sdk`). Sideboard does not ship the SDK \u2014 update it anytime without a new Sideboard build.";
|
|
760
|
+
function thisModuleFile() {
|
|
761
|
+
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
762
|
+
if (cjsDir) return join4(cjsDir, "cursor-sdk-resolve.js");
|
|
763
|
+
try {
|
|
764
|
+
return fileURLToPath(import.meta.url);
|
|
765
|
+
} catch {
|
|
766
|
+
return join4(process.cwd(), "package.json");
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
function packageRootLooksLikeSdk(dir) {
|
|
770
|
+
try {
|
|
771
|
+
const raw = readFileSync2(join4(dir, "package.json"), "utf8");
|
|
772
|
+
const pkg = JSON.parse(raw);
|
|
773
|
+
return pkg.name === "@cursor/sdk" && existsSync4(dir);
|
|
774
|
+
} catch {
|
|
775
|
+
return false;
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
function resolvedPackageRoot(fromFile) {
|
|
779
|
+
try {
|
|
780
|
+
const req = createRequire(fromFile);
|
|
781
|
+
const pkgJson = req.resolve("@cursor/sdk/package.json");
|
|
782
|
+
const root = dirname2(pkgJson);
|
|
783
|
+
return packageRootLooksLikeSdk(root) ? root : null;
|
|
784
|
+
} catch {
|
|
785
|
+
return null;
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
function resolveCursorSdkRoot(opts) {
|
|
789
|
+
const env = opts?.env ?? process.env;
|
|
790
|
+
const override = env.SIDEBOARD_CURSOR_SDK?.trim();
|
|
791
|
+
if (override) {
|
|
792
|
+
return packageRootLooksLikeSdk(override) ? override : null;
|
|
793
|
+
}
|
|
794
|
+
const globalNm = npmGlobalNodeModules(env);
|
|
795
|
+
if (globalNm) {
|
|
796
|
+
const globalRoot = join4(globalNm, "@cursor/sdk");
|
|
797
|
+
if (packageRootLooksLikeSdk(globalRoot)) return globalRoot;
|
|
798
|
+
}
|
|
799
|
+
const cwdPkg = join4(process.cwd(), "package.json");
|
|
800
|
+
return resolvedPackageRoot(thisModuleFile()) ?? resolvedPackageRoot(cwdPkg);
|
|
801
|
+
}
|
|
802
|
+
function isCursorSdkInstalled(opts) {
|
|
803
|
+
return Boolean(resolveCursorSdkRoot(opts));
|
|
804
|
+
}
|
|
805
|
+
async function importCursorSdk(opts) {
|
|
806
|
+
const root = resolveCursorSdkRoot(opts);
|
|
807
|
+
if (!root) return null;
|
|
808
|
+
try {
|
|
809
|
+
const req = createRequire(join4(root, "package.json"));
|
|
810
|
+
const entry = req.resolve("@cursor/sdk");
|
|
811
|
+
return await import(pathToFileURL(entry).href);
|
|
812
|
+
} catch {
|
|
813
|
+
return null;
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
function cursorSdkPlatformRipgrepPackage() {
|
|
817
|
+
return `@cursor/sdk-${process.platform}-${process.arch}`;
|
|
818
|
+
}
|
|
819
|
+
function nodeModulesDirForPackageRoot(packageRoot) {
|
|
820
|
+
const parent = dirname2(packageRoot);
|
|
821
|
+
return basename(parent).startsWith("@") ? dirname2(parent) : parent;
|
|
822
|
+
}
|
|
823
|
+
function cursorSdkRipgrepCandidate(opts) {
|
|
824
|
+
const root = resolveCursorSdkRoot(opts);
|
|
825
|
+
if (!root) return null;
|
|
826
|
+
const nm = nodeModulesDirForPackageRoot(root);
|
|
827
|
+
const pkg = cursorSdkPlatformRipgrepPackage();
|
|
828
|
+
const bin = process.platform === "win32" ? "rg.exe" : "rg";
|
|
829
|
+
const sibling = join4(nm, pkg, "bin", bin);
|
|
830
|
+
if (existsSync4(sibling)) return sibling;
|
|
831
|
+
const nested = join4(root, "node_modules", pkg, "bin", bin);
|
|
832
|
+
return existsSync4(nested) ? nested : null;
|
|
833
|
+
}
|
|
834
|
+
|
|
753
835
|
// src/agents/cursor-events.ts
|
|
754
836
|
function usageFromCursor(usage) {
|
|
755
837
|
if (!usage) return null;
|
|
@@ -1059,9 +1141,9 @@ function parseCursorRunnerLine(line) {
|
|
|
1059
1141
|
}
|
|
1060
1142
|
|
|
1061
1143
|
// src/agents/cursor-ripgrep.ts
|
|
1062
|
-
import { existsSync as
|
|
1063
|
-
import { createRequire } from "module";
|
|
1064
|
-
import { dirname as
|
|
1144
|
+
import { existsSync as existsSync5 } from "fs";
|
|
1145
|
+
import { createRequire as createRequire2 } from "module";
|
|
1146
|
+
import { dirname as dirname3, isAbsolute, join as join5, parse, resolve as resolvePath } from "path";
|
|
1065
1147
|
var RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
|
|
1066
1148
|
function rgBinaryName() {
|
|
1067
1149
|
return process.platform === "win32" ? "rg.exe" : "rg";
|
|
@@ -1073,19 +1155,19 @@ function usableRipgrepPath(candidate) {
|
|
|
1073
1155
|
const raw = candidate?.trim();
|
|
1074
1156
|
if (!raw || !isAbsolute(raw)) return null;
|
|
1075
1157
|
const readable = nodeReadableScriptPath(raw);
|
|
1076
|
-
if (!
|
|
1158
|
+
if (!existsSync5(readable) || isAsarPath(readable)) return null;
|
|
1077
1159
|
return readable;
|
|
1078
1160
|
}
|
|
1079
1161
|
function walkForBundledRipgrep(startFile) {
|
|
1080
1162
|
if (!startFile) return null;
|
|
1081
1163
|
const pkg = platformRipgrepPackage();
|
|
1082
1164
|
const name = rgBinaryName();
|
|
1083
|
-
let dir =
|
|
1165
|
+
let dir = dirname3(resolvePath(startFile));
|
|
1084
1166
|
const root = parse(dir).root;
|
|
1085
1167
|
while (dir !== root) {
|
|
1086
|
-
const hit = usableRipgrepPath(
|
|
1168
|
+
const hit = usableRipgrepPath(join5(dir, "node_modules", pkg, "bin", name));
|
|
1087
1169
|
if (hit) return hit;
|
|
1088
|
-
const next =
|
|
1170
|
+
const next = dirname3(dir);
|
|
1089
1171
|
if (next === dir) break;
|
|
1090
1172
|
dir = next;
|
|
1091
1173
|
}
|
|
@@ -1093,9 +1175,9 @@ function walkForBundledRipgrep(startFile) {
|
|
|
1093
1175
|
}
|
|
1094
1176
|
function requireResolveBundledRipgrep(fromFile) {
|
|
1095
1177
|
try {
|
|
1096
|
-
const req =
|
|
1178
|
+
const req = createRequire2(fromFile);
|
|
1097
1179
|
const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
|
|
1098
|
-
return usableRipgrepPath(
|
|
1180
|
+
return usableRipgrepPath(join5(dirname3(pkgJson), "bin", rgBinaryName()));
|
|
1099
1181
|
} catch {
|
|
1100
1182
|
return null;
|
|
1101
1183
|
}
|
|
@@ -1111,7 +1193,7 @@ function resolveCursorRipgrepPath(opts) {
|
|
|
1111
1193
|
const start = opts?.startFile?.trim() || process.argv[1] || // CJS bundle only — ESM has no __filename; argv[1] is the running script.
|
|
1112
1194
|
// eslint-disable-next-line camelcase
|
|
1113
1195
|
(typeof __filename !== "undefined" ? __filename : "");
|
|
1114
|
-
return walkForBundledRipgrep(start) ?? requireResolveBundledRipgrep(start);
|
|
1196
|
+
return walkForBundledRipgrep(start) ?? usableRipgrepPath(cursorSdkRipgrepCandidate({ env })) ?? requireResolveBundledRipgrep(start);
|
|
1115
1197
|
}
|
|
1116
1198
|
function cursorRipgrepEnv(opts) {
|
|
1117
1199
|
const path = resolveCursorRipgrepPath(opts);
|
|
@@ -1154,6 +1236,10 @@ export {
|
|
|
1154
1236
|
isAsarPath,
|
|
1155
1237
|
applyNodeLaunch,
|
|
1156
1238
|
resolveNodeLaunch,
|
|
1239
|
+
CURSOR_SDK_INSTALL_HINT,
|
|
1240
|
+
resolveCursorSdkRoot,
|
|
1241
|
+
isCursorSdkInstalled,
|
|
1242
|
+
importCursorSdk,
|
|
1157
1243
|
preferredCursorCostCents,
|
|
1158
1244
|
turnCostUsdFromCursorUsage,
|
|
1159
1245
|
fetchCursorTurnCostUsd,
|
|
@@ -65,6 +65,14 @@ function ensureAgentPath(env = process.env) {
|
|
|
65
65
|
}
|
|
66
66
|
function enrichPathWithNpmGlobalBin(env = process.env) {
|
|
67
67
|
ensureAgentPath(env);
|
|
68
|
+
const prefix = npmGlobalPrefix(env);
|
|
69
|
+
if (prefix) {
|
|
70
|
+
const binDir = process.platform === "win32" ? prefix : join(prefix, "bin");
|
|
71
|
+
prependPathDir(env, binDir);
|
|
72
|
+
}
|
|
73
|
+
return env.PATH ?? "";
|
|
74
|
+
}
|
|
75
|
+
function npmGlobalPrefix(env = process.env) {
|
|
68
76
|
try {
|
|
69
77
|
const prefix = execFileSync("npm", ["prefix", "-g"], {
|
|
70
78
|
encoding: "utf8",
|
|
@@ -72,13 +80,16 @@ function enrichPathWithNpmGlobalBin(env = process.env) {
|
|
|
72
80
|
timeout: 8e3,
|
|
73
81
|
stdio: ["ignore", "pipe", "ignore"]
|
|
74
82
|
}).trim().split(/\r?\n/).find(Boolean);
|
|
75
|
-
|
|
76
|
-
const binDir = process.platform === "win32" ? prefix : join(prefix, "bin");
|
|
77
|
-
prependPathDir(env, binDir);
|
|
78
|
-
}
|
|
83
|
+
return prefix || null;
|
|
79
84
|
} catch {
|
|
85
|
+
return null;
|
|
80
86
|
}
|
|
81
|
-
|
|
87
|
+
}
|
|
88
|
+
function npmGlobalNodeModules(env = process.env) {
|
|
89
|
+
const prefix = npmGlobalPrefix(env);
|
|
90
|
+
if (!prefix) return null;
|
|
91
|
+
const dir = process.platform === "win32" ? join(prefix, "node_modules") : join(prefix, "lib", "node_modules");
|
|
92
|
+
return existsSync(dir) ? dir : null;
|
|
82
93
|
}
|
|
83
94
|
function posixShellSingleQuote(value) {
|
|
84
95
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
@@ -309,6 +320,8 @@ export {
|
|
|
309
320
|
isConductorBundledCli,
|
|
310
321
|
ensureAgentPath,
|
|
311
322
|
enrichPathWithNpmGlobalBin,
|
|
323
|
+
npmGlobalPrefix,
|
|
324
|
+
npmGlobalNodeModules,
|
|
312
325
|
posixShellSingleQuote,
|
|
313
326
|
resolveCommandBinarySync,
|
|
314
327
|
withExportedPath,
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
} from "./chunk-XJETIO4K.js";
|
|
9
9
|
import {
|
|
10
10
|
ensureWorktreeSideboardIgnored
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-DD67JWTN.js";
|
|
12
12
|
import {
|
|
13
13
|
gh,
|
|
14
14
|
git,
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
githubGhConfigEnv,
|
|
19
19
|
materializeGithubAgentAuth,
|
|
20
20
|
resolveGhAuthToken
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-2UG25RMK.js";
|
|
22
22
|
import {
|
|
23
23
|
getGithubGitAuthMode,
|
|
24
24
|
getGithubPat
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-6K64FJDD.js";
|
|
4
4
|
import {
|
|
5
5
|
ensureWorktreeSideboardIgnored
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-2P4XKWV2.js";
|
|
7
7
|
import {
|
|
8
8
|
getGithubGitAuthMode,
|
|
9
9
|
getGithubPat
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
githubGhConfigEnv,
|
|
24
24
|
materializeGithubAgentAuth,
|
|
25
25
|
resolveGhAuthToken
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-QVN2WOKJ.js";
|
|
27
27
|
|
|
28
28
|
// src/git/worktree.ts
|
|
29
29
|
import { randomBytes } from "crypto";
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
resolveQuotaFallbackAgent,
|
|
25
25
|
stripBrightsyNdjsonNoise,
|
|
26
26
|
toolDescription
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-PZQNE5X4.js";
|
|
28
28
|
import {
|
|
29
29
|
SLACK_REPLY_FORMATTING,
|
|
30
30
|
addWorkspace,
|
|
@@ -47,7 +47,7 @@ import {
|
|
|
47
47
|
stageAbsolutePathsAsAttachments,
|
|
48
48
|
stageBuffersAsAttachments,
|
|
49
49
|
syncWorkspacesFromThreads
|
|
50
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-S2OEFXST.js";
|
|
51
51
|
import {
|
|
52
52
|
addPrStackLayer,
|
|
53
53
|
allocateTeamName,
|
|
@@ -96,7 +96,7 @@ import {
|
|
|
96
96
|
worktreeDisplayLabelForGroup,
|
|
97
97
|
worktreeNameFromPath,
|
|
98
98
|
worktreeSlugForTicket
|
|
99
|
-
} from "./chunk-
|
|
99
|
+
} from "./chunk-7H2CVVLF.js";
|
|
100
100
|
import {
|
|
101
101
|
ATTACHMENTS_DIR,
|
|
102
102
|
DETACHED_JOBS_DIR,
|
|
@@ -105,7 +105,7 @@ import {
|
|
|
105
105
|
} from "./chunk-6K64FJDD.js";
|
|
106
106
|
import {
|
|
107
107
|
ensureWorktreeSideboardIgnored
|
|
108
|
-
} from "./chunk-
|
|
108
|
+
} from "./chunk-2P4XKWV2.js";
|
|
109
109
|
import {
|
|
110
110
|
httpFetch
|
|
111
111
|
} from "./chunk-N7WZ6NIN.js";
|
|
@@ -128,7 +128,7 @@ import {
|
|
|
128
128
|
shouldRetryFailedAgentTurn,
|
|
129
129
|
summarizeTurnStderr,
|
|
130
130
|
turnFailChatText
|
|
131
|
-
} from "./chunk-
|
|
131
|
+
} from "./chunk-26T43LBM.js";
|
|
132
132
|
import {
|
|
133
133
|
HISTORY_CLEANUP_INTERVAL_HOURS_DEFAULT,
|
|
134
134
|
applyTurnUsage,
|
|
@@ -206,7 +206,7 @@ import {
|
|
|
206
206
|
git,
|
|
207
207
|
resolveGitDirsForLockRecovery,
|
|
208
208
|
run
|
|
209
|
-
} from "./chunk-
|
|
209
|
+
} from "./chunk-QVN2WOKJ.js";
|
|
210
210
|
import {
|
|
211
211
|
stripNestedElectronEnv
|
|
212
212
|
} from "./chunk-4TR3HZFT.js";
|
|
@@ -482,7 +482,7 @@ async function continueSourceThread(threadId, prompt) {
|
|
|
482
482
|
await continueOnReply(threadId, prompt);
|
|
483
483
|
return;
|
|
484
484
|
}
|
|
485
|
-
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-
|
|
485
|
+
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-BXALNM4M.js");
|
|
486
486
|
await getOrchestrator2().send(threadId, prompt);
|
|
487
487
|
} catch {
|
|
488
488
|
}
|
|
@@ -901,9 +901,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
901
901
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
902
902
|
);
|
|
903
903
|
}
|
|
904
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
904
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-NCIC2Y2U.js");
|
|
905
905
|
if (isGlobalThread2(thread)) {
|
|
906
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
906
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-IGDMFKCD.js");
|
|
907
907
|
ensureGlobalCoordinatorCwd2(
|
|
908
908
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
909
909
|
);
|
|
@@ -2243,7 +2243,17 @@ function pipeLines(stream, onLine) {
|
|
|
2243
2243
|
const rl = createInterface2({ input: stream });
|
|
2244
2244
|
rl.on("line", onLine);
|
|
2245
2245
|
}
|
|
2246
|
+
function killableListenerPids(raw, selfPid = process.pid) {
|
|
2247
|
+
const pids = [];
|
|
2248
|
+
for (const token of raw.trim().split(/\s+/)) {
|
|
2249
|
+
const pid = Number(token);
|
|
2250
|
+
if (!Number.isFinite(pid) || pid <= 0 || pid === selfPid) continue;
|
|
2251
|
+
pids.push(pid);
|
|
2252
|
+
}
|
|
2253
|
+
return pids;
|
|
2254
|
+
}
|
|
2246
2255
|
function killListenersOnPorts(ports) {
|
|
2256
|
+
const selfPid = process.pid;
|
|
2247
2257
|
for (const port of ports) {
|
|
2248
2258
|
if (!Number.isFinite(port) || port <= 0) continue;
|
|
2249
2259
|
try {
|
|
@@ -2253,7 +2263,7 @@ function killListenersOnPorts(ports) {
|
|
|
2253
2263
|
[
|
|
2254
2264
|
"-NoProfile",
|
|
2255
2265
|
"-Command",
|
|
2256
|
-
`Get-NetTCPConnection -LocalPort ${port} -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }`
|
|
2266
|
+
`Get-NetTCPConnection -LocalPort ${port} -ErrorAction SilentlyContinue | Where-Object { $_.OwningProcess -ne ${selfPid} } | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }`
|
|
2257
2267
|
],
|
|
2258
2268
|
{ stdio: "ignore", timeout: 3e3 }
|
|
2259
2269
|
);
|
|
@@ -2269,9 +2279,7 @@ function killListenersOnPorts(ports) {
|
|
|
2269
2279
|
} catch {
|
|
2270
2280
|
continue;
|
|
2271
2281
|
}
|
|
2272
|
-
for (const
|
|
2273
|
-
const pid = Number(token);
|
|
2274
|
-
if (!Number.isFinite(pid) || pid <= 0) continue;
|
|
2282
|
+
for (const pid of killableListenerPids(raw, selfPid)) {
|
|
2275
2283
|
try {
|
|
2276
2284
|
process.kill(pid, "SIGTERM");
|
|
2277
2285
|
} catch {
|
|
@@ -2324,6 +2332,9 @@ async function spawnWorkspaceScript(command, opts) {
|
|
|
2324
2332
|
);
|
|
2325
2333
|
} catch {
|
|
2326
2334
|
}
|
|
2335
|
+
if (opts.heldPorts?.length) {
|
|
2336
|
+
await Promise.all(opts.heldPorts.map((h) => h.release()));
|
|
2337
|
+
}
|
|
2327
2338
|
const shell = process.platform === "darwin" ? "zsh" : "bash";
|
|
2328
2339
|
const child = execa2(shell, ["-lc", command], {
|
|
2329
2340
|
cwd: opts.worktreePath,
|
|
@@ -2515,11 +2526,11 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
|
|
|
2515
2526
|
const held = await reservePortRange(PORT_RANGE_SIZE);
|
|
2516
2527
|
const ports = held.map((h) => h.port);
|
|
2517
2528
|
try {
|
|
2518
|
-
await Promise.all(held.map((h) => h.release()));
|
|
2519
2529
|
const handle = await spawnWorkspaceScript(script.command, {
|
|
2520
2530
|
worktreePath,
|
|
2521
2531
|
repoPath,
|
|
2522
2532
|
ports,
|
|
2533
|
+
heldPorts: held,
|
|
2523
2534
|
defaultBranch: opts?.defaultBranch,
|
|
2524
2535
|
onLine
|
|
2525
2536
|
});
|
|
@@ -2986,6 +2997,9 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
2986
2997
|
function isUnclaimedRunScriptRequest(req) {
|
|
2987
2998
|
return Boolean(req && !req.claimedAt && !req.fulfilledAt && !req.error);
|
|
2988
2999
|
}
|
|
3000
|
+
function isAdoptableRunScriptRequest(req) {
|
|
3001
|
+
return Boolean(req && !req.fulfilledAt && !req.error);
|
|
3002
|
+
}
|
|
2989
3003
|
|
|
2990
3004
|
// src/store/desktop-host.ts
|
|
2991
3005
|
import { readFileSync as readFileSync6, unlinkSync, writeFileSync as writeFileSync3 } from "fs";
|
|
@@ -4252,7 +4266,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
4252
4266
|
return readThread(thread.id) ?? thread;
|
|
4253
4267
|
}
|
|
4254
4268
|
async function listLinearIssues(agent, repoPath) {
|
|
4255
|
-
const { getAdapter: getAdapter2 } = await import("./agents-
|
|
4269
|
+
const { getAdapter: getAdapter2 } = await import("./agents-LDYMFW6N.js");
|
|
4256
4270
|
await requireAgent(agent, { requireLinear: true });
|
|
4257
4271
|
const adapter = getAdapter2(agent);
|
|
4258
4272
|
if (!adapter.listLinearIssues) {
|
|
@@ -4710,7 +4724,7 @@ async function adoptThread(input) {
|
|
|
4710
4724
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
4711
4725
|
}
|
|
4712
4726
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
4713
|
-
const { stdout: branch } = await import("./run-
|
|
4727
|
+
const { stdout: branch } = await import("./run-PCX5QWR4.js").then(
|
|
4714
4728
|
({ git: git2 }) => git2(["rev-parse", "--abbrev-ref", "HEAD"], input.worktreePath)
|
|
4715
4729
|
);
|
|
4716
4730
|
const thread = createEmptyThread({
|
|
@@ -4725,9 +4739,9 @@ async function adoptThread(input) {
|
|
|
4725
4739
|
messages: input.messages ?? []
|
|
4726
4740
|
});
|
|
4727
4741
|
writeThread(thread);
|
|
4728
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
4742
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-H2TRFDE2.js");
|
|
4729
4743
|
await ensureWorkspace2(repoPath);
|
|
4730
|
-
const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-
|
|
4744
|
+
const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-RXZPTCNH.js");
|
|
4731
4745
|
await ensureWorktreeSideboardIgnored2(input.worktreePath);
|
|
4732
4746
|
return thread;
|
|
4733
4747
|
}
|
|
@@ -6143,7 +6157,7 @@ async function confirmLand(thread, opts) {
|
|
|
6143
6157
|
if (preview.dirty) {
|
|
6144
6158
|
committed = await commitAll(thread.worktreePath, meta.commitMessage);
|
|
6145
6159
|
}
|
|
6146
|
-
const { git: git2 } = await import("./run-
|
|
6160
|
+
const { git: git2 } = await import("./run-PCX5QWR4.js");
|
|
6147
6161
|
const { stdout: headOut } = await git2(
|
|
6148
6162
|
["rev-parse", "--abbrev-ref", "HEAD"],
|
|
6149
6163
|
thread.worktreePath,
|
|
@@ -7407,7 +7421,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
7407
7421
|
${prompt}`;
|
|
7408
7422
|
}
|
|
7409
7423
|
async function defaultDeps() {
|
|
7410
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
7424
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-BXALNM4M.js");
|
|
7411
7425
|
const orch = getOrchestrator2();
|
|
7412
7426
|
return {
|
|
7413
7427
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -7591,6 +7605,8 @@ var Orchestrator = class {
|
|
|
7591
7605
|
jobContinueNudged = /* @__PURE__ */ new Set();
|
|
7592
7606
|
/** In-flight startDev per worktree run key — agent MCP + UI Start must not double-spawn. */
|
|
7593
7607
|
startingDev = /* @__PURE__ */ new Map();
|
|
7608
|
+
/** Serialize desktop apply of `runScriptRequest` per thread (start then stop). */
|
|
7609
|
+
applyingRunScriptThreads = /* @__PURE__ */ new Set();
|
|
7594
7610
|
/**
|
|
7595
7611
|
* MCP/CLI poll budget while Electron main adopts `runScriptRequest`.
|
|
7596
7612
|
* Tests shorten this so a missing desktop does not wait 20s.
|
|
@@ -7777,11 +7793,19 @@ var Orchestrator = class {
|
|
|
7777
7793
|
for (const thread of listThreads()) {
|
|
7778
7794
|
if (thread.status === "archived") continue;
|
|
7779
7795
|
const req = thread.runScriptRequest;
|
|
7780
|
-
if (!
|
|
7781
|
-
|
|
7796
|
+
if (!isAdoptableRunScriptRequest(req) || !req) continue;
|
|
7797
|
+
if (this.applyingRunScriptThreads.has(thread.id)) continue;
|
|
7798
|
+
const claimedAt = req.claimedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
7782
7799
|
const claimed = { ...req, claimedAt };
|
|
7800
|
+
this.applyingRunScriptThreads.add(thread.id);
|
|
7783
7801
|
updateThread(thread.id, { runScriptRequest: claimed });
|
|
7784
|
-
void this.applyRunScriptRequest(thread.id, claimed)
|
|
7802
|
+
void this.applyRunScriptRequest(thread.id, claimed).finally(() => {
|
|
7803
|
+
this.applyingRunScriptThreads.delete(thread.id);
|
|
7804
|
+
const latest = readThread(thread.id)?.runScriptRequest;
|
|
7805
|
+
if (latest && latest.requestId !== req.requestId && isAdoptableRunScriptRequest(latest)) {
|
|
7806
|
+
this.adoptPersistedRunScripts();
|
|
7807
|
+
}
|
|
7808
|
+
});
|
|
7785
7809
|
}
|
|
7786
7810
|
}
|
|
7787
7811
|
async applyRunScriptRequest(threadId, req) {
|
|
@@ -9037,9 +9061,8 @@ var Orchestrator = class {
|
|
|
9037
9061
|
if (fulfilled && !run2) {
|
|
9038
9062
|
throw new Error("Desktop reported the run script started, but it is not active.");
|
|
9039
9063
|
}
|
|
9040
|
-
} else {
|
|
9041
|
-
|
|
9042
|
-
if (fulfilled || gone) return null;
|
|
9064
|
+
} else if (fulfilled) {
|
|
9065
|
+
return null;
|
|
9043
9066
|
}
|
|
9044
9067
|
await new Promise((r) => setTimeout(r, 40));
|
|
9045
9068
|
}
|
|
@@ -9047,12 +9070,26 @@ var Orchestrator = class {
|
|
|
9047
9070
|
op === "start" ? "Desktop did not start the run script in time. Is Sideboard.app running this worktree?" : "Desktop did not stop the run script in time."
|
|
9048
9071
|
);
|
|
9049
9072
|
}
|
|
9073
|
+
async awaitStartingDev(worktreePath, scriptName) {
|
|
9074
|
+
const keys = scriptName ? [worktreeRunProcessKey(worktreePath, scriptName)] : [...this.startingDev.keys()].filter((k) => isWorktreeRunProcessKey(k, worktreePath));
|
|
9075
|
+
await Promise.all(
|
|
9076
|
+
keys.map(async (key) => {
|
|
9077
|
+
const pending = this.startingDev.get(key);
|
|
9078
|
+
if (!pending) return;
|
|
9079
|
+
try {
|
|
9080
|
+
await pending;
|
|
9081
|
+
} catch {
|
|
9082
|
+
}
|
|
9083
|
+
})
|
|
9084
|
+
);
|
|
9085
|
+
}
|
|
9050
9086
|
async stopDev(threadRef, scriptName) {
|
|
9051
9087
|
const thread = this.requireThread(threadRef);
|
|
9052
9088
|
if (!this.shouldOwnRunScripts()) {
|
|
9053
9089
|
await this.requestDesktopRunScript(thread, "stop", scriptName);
|
|
9054
9090
|
return;
|
|
9055
9091
|
}
|
|
9092
|
+
await this.awaitStartingDev(thread.worktreePath, scriptName);
|
|
9056
9093
|
const siblings = threadsSharingWorktree(thread.worktreePath);
|
|
9057
9094
|
const shared = mergeWorktreeActiveRuns(siblings);
|
|
9058
9095
|
if (scriptName) {
|
|
@@ -9915,7 +9952,7 @@ var Orchestrator = class {
|
|
|
9915
9952
|
this.enforceHistoryRetention();
|
|
9916
9953
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
9917
9954
|
try {
|
|
9918
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
9955
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-H2TRFDE2.js");
|
|
9919
9956
|
await ensureWorkspace2(thread.repoPath);
|
|
9920
9957
|
} catch {
|
|
9921
9958
|
}
|
|
@@ -9969,13 +10006,13 @@ var Orchestrator = class {
|
|
|
9969
10006
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
9970
10007
|
);
|
|
9971
10008
|
}
|
|
9972
|
-
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-
|
|
10009
|
+
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-W7BSI4GU.js");
|
|
9973
10010
|
const slug = thread.worktreePath.split("/").pop();
|
|
9974
10011
|
const dest = thread.worktreePath;
|
|
9975
10012
|
await withRepoGitLock(thread.repoPath, async () => {
|
|
9976
10013
|
await git(["worktree", "add", dest, thread.branchName], thread.repoPath);
|
|
9977
10014
|
});
|
|
9978
|
-
const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-
|
|
10015
|
+
const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-RXZPTCNH.js");
|
|
9979
10016
|
await ensureWorktreeSideboardIgnored2(dest);
|
|
9980
10017
|
void createThreadWorktree2;
|
|
9981
10018
|
void slug;
|
|
@@ -10079,7 +10116,7 @@ async function startOrchestration(opts) {
|
|
|
10079
10116
|
sourceRef: "default",
|
|
10080
10117
|
...createOpts
|
|
10081
10118
|
}).catch(async () => {
|
|
10082
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
10119
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-W7BSI4GU.js");
|
|
10083
10120
|
const repo = await resolveRepoRoot2(repoPath);
|
|
10084
10121
|
const def = await resolveDefaultBranch2(repo);
|
|
10085
10122
|
return orch.createThread({
|
|
@@ -10102,6 +10139,7 @@ async function startOrchestration(opts) {
|
|
|
10102
10139
|
|
|
10103
10140
|
export {
|
|
10104
10141
|
isUnclaimedRunScriptRequest,
|
|
10142
|
+
isAdoptableRunScriptRequest,
|
|
10105
10143
|
isHomeBoardThread,
|
|
10106
10144
|
BOARD_COLUMN_DEFS,
|
|
10107
10145
|
HOME_BOARD_CACHE_TTL_MS,
|
|
@@ -10234,6 +10272,7 @@ export {
|
|
|
10234
10272
|
copyConfiguredFiles,
|
|
10235
10273
|
captureLoginEnv,
|
|
10236
10274
|
buildWorkspaceScriptEnv,
|
|
10275
|
+
killableListenerPids,
|
|
10237
10276
|
killListenersOnPorts,
|
|
10238
10277
|
runSetupScript,
|
|
10239
10278
|
runConventionSetup,
|