@sideboard-ai/core 0.1.225 → 0.1.227
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-5L66IONI.js → chunk-FUDJ6NFM.js} +142 -26
- package/dist/{chunk-MPSXJ7WU.js → chunk-I2HOATRJ.js} +143 -26
- package/dist/index.cjs +144 -26
- package/dist/index.d.cts +22 -1
- package/dist/index.d.ts +22 -1
- package/dist/index.js +3 -1
- package/dist/mcp/run-stdio.cjs +145 -29
- package/dist/mcp/run-stdio.js +1 -1
- package/dist/{orchestrator-ZAJ2M4UW.js → orchestrator-CWOSAYAE.js} +1 -1
- package/dist/{orchestrator-O3FNYIRE.js → orchestrator-VKPHI64Q.js} +1 -1
- package/package.json +1 -1
package/dist/mcp/run-stdio.cjs
CHANGED
|
@@ -13346,6 +13346,12 @@ function samePrIdentity(a, b) {
|
|
|
13346
13346
|
const rn = right.match(/\/pull\/(\d+)/i)?.[1];
|
|
13347
13347
|
return Boolean(ln && rn && ln === rn);
|
|
13348
13348
|
}
|
|
13349
|
+
function shouldStopRunOnPrRetarget(previousPrUrl, nextPrUrl) {
|
|
13350
|
+
const prev = (previousPrUrl ?? "").trim();
|
|
13351
|
+
const next = (nextPrUrl ?? "").trim();
|
|
13352
|
+
if (!prev || !next) return false;
|
|
13353
|
+
return !samePrIdentity(prev, next);
|
|
13354
|
+
}
|
|
13349
13355
|
function shouldPersistFetchedPrMeta(opts) {
|
|
13350
13356
|
const meta = opts.metaUrl?.trim() || "";
|
|
13351
13357
|
if (!meta) return false;
|
|
@@ -14429,6 +14435,44 @@ function pipeLines(stream, onLine) {
|
|
|
14429
14435
|
const rl = (0, import_node_readline3.createInterface)({ input: stream });
|
|
14430
14436
|
rl.on("line", onLine);
|
|
14431
14437
|
}
|
|
14438
|
+
function killListenersOnPorts(ports) {
|
|
14439
|
+
for (const port of ports) {
|
|
14440
|
+
if (!Number.isFinite(port) || port <= 0) continue;
|
|
14441
|
+
try {
|
|
14442
|
+
if (process.platform === "win32") {
|
|
14443
|
+
(0, import_node_child_process4.execFileSync)(
|
|
14444
|
+
"powershell",
|
|
14445
|
+
[
|
|
14446
|
+
"-NoProfile",
|
|
14447
|
+
"-Command",
|
|
14448
|
+
`Get-NetTCPConnection -LocalPort ${port} -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }`
|
|
14449
|
+
],
|
|
14450
|
+
{ stdio: "ignore", timeout: 3e3 }
|
|
14451
|
+
);
|
|
14452
|
+
continue;
|
|
14453
|
+
}
|
|
14454
|
+
let raw = "";
|
|
14455
|
+
try {
|
|
14456
|
+
raw = (0, import_node_child_process4.execFileSync)("lsof", [`-tiTCP:${port}`, "-sTCP:LISTEN"], {
|
|
14457
|
+
encoding: "utf8",
|
|
14458
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
14459
|
+
timeout: 2e3
|
|
14460
|
+
});
|
|
14461
|
+
} catch {
|
|
14462
|
+
continue;
|
|
14463
|
+
}
|
|
14464
|
+
for (const token of raw.trim().split(/\s+/)) {
|
|
14465
|
+
const pid = Number(token);
|
|
14466
|
+
if (!Number.isFinite(pid) || pid <= 0) continue;
|
|
14467
|
+
try {
|
|
14468
|
+
process.kill(pid, "SIGTERM");
|
|
14469
|
+
} catch {
|
|
14470
|
+
}
|
|
14471
|
+
}
|
|
14472
|
+
} catch {
|
|
14473
|
+
}
|
|
14474
|
+
}
|
|
14475
|
+
}
|
|
14432
14476
|
function killScriptTree(child, ports = []) {
|
|
14433
14477
|
const pid = child.pid;
|
|
14434
14478
|
if (pid) {
|
|
@@ -14451,26 +14495,7 @@ function killScriptTree(child, ports = []) {
|
|
|
14451
14495
|
}
|
|
14452
14496
|
}
|
|
14453
14497
|
}
|
|
14454
|
-
|
|
14455
|
-
if (!Number.isFinite(port) || port <= 0) continue;
|
|
14456
|
-
if (process.platform === "win32") {
|
|
14457
|
-
void (0, import_execa4.execa)(
|
|
14458
|
-
"powershell",
|
|
14459
|
-
[
|
|
14460
|
-
"-NoProfile",
|
|
14461
|
-
"-Command",
|
|
14462
|
-
`Get-NetTCPConnection -LocalPort ${port} -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }`
|
|
14463
|
-
],
|
|
14464
|
-
{ reject: false }
|
|
14465
|
-
);
|
|
14466
|
-
} else {
|
|
14467
|
-
void (0, import_execa4.execa)(
|
|
14468
|
-
"zsh",
|
|
14469
|
-
["-lc", `pids=$(lsof -tiTCP:${port} -sTCP:LISTEN 2>/dev/null); [ -n "$pids" ] && kill -TERM $pids 2>/dev/null; true`],
|
|
14470
|
-
{ reject: false }
|
|
14471
|
-
);
|
|
14472
|
-
}
|
|
14473
|
-
}
|
|
14498
|
+
killListenersOnPorts(ports);
|
|
14474
14499
|
}
|
|
14475
14500
|
async function spawnWorkspaceScript(command, opts) {
|
|
14476
14501
|
const loginEnv = await captureLoginEnv();
|
|
@@ -14661,11 +14686,12 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
|
|
|
14661
14686
|
done: handle.done
|
|
14662
14687
|
};
|
|
14663
14688
|
}
|
|
14664
|
-
var import_node_fs37, import_node_net, import_node_path39, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
|
|
14689
|
+
var import_node_fs37, import_node_child_process4, import_node_net, import_node_path39, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
|
|
14665
14690
|
var init_conductor = __esm({
|
|
14666
14691
|
"src/hook/conductor.ts"() {
|
|
14667
14692
|
"use strict";
|
|
14668
14693
|
import_node_fs37 = require("fs");
|
|
14694
|
+
import_node_child_process4 = require("child_process");
|
|
14669
14695
|
import_node_net = require("net");
|
|
14670
14696
|
import_node_path39 = require("path");
|
|
14671
14697
|
import_execa4 = require("execa");
|
|
@@ -18497,7 +18523,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
18497
18523
|
}
|
|
18498
18524
|
let repoPath = worktreePath;
|
|
18499
18525
|
try {
|
|
18500
|
-
repoPath = (0,
|
|
18526
|
+
repoPath = (0, import_node_child_process5.execFileSync)("git", ["rev-parse", "--show-toplevel"], {
|
|
18501
18527
|
cwd: worktreePath,
|
|
18502
18528
|
encoding: "utf8"
|
|
18503
18529
|
}).trim();
|
|
@@ -18526,11 +18552,11 @@ function importConductorWorkspace(workspaceId) {
|
|
|
18526
18552
|
async function importConductorWorkspaceAsync(workspaceId) {
|
|
18527
18553
|
return importConductorWorkspace(workspaceId);
|
|
18528
18554
|
}
|
|
18529
|
-
var
|
|
18555
|
+
var import_node_child_process5, import_node_fs45, import_node_os14, import_node_path45, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
|
|
18530
18556
|
var init_adopt = __esm({
|
|
18531
18557
|
"src/threads/adopt.ts"() {
|
|
18532
18558
|
"use strict";
|
|
18533
|
-
|
|
18559
|
+
import_node_child_process5 = require("child_process");
|
|
18534
18560
|
import_node_fs45 = require("fs");
|
|
18535
18561
|
import_node_os14 = require("os");
|
|
18536
18562
|
import_node_path45 = require("path");
|
|
@@ -20929,7 +20955,7 @@ function setCaffeinateHold(enabled, opts) {
|
|
|
20929
20955
|
if (platform !== "darwin") {
|
|
20930
20956
|
return idleState(platform);
|
|
20931
20957
|
}
|
|
20932
|
-
const spawnImpl = hooks.spawn ??
|
|
20958
|
+
const spawnImpl = hooks.spawn ?? import_node_child_process6.spawn;
|
|
20933
20959
|
const child = spawnImpl("caffeinate", ["-dimsu"], {
|
|
20934
20960
|
detached: true,
|
|
20935
20961
|
stdio: "ignore"
|
|
@@ -20956,11 +20982,11 @@ function releaseCaffeinateHoldForThread(threadId) {
|
|
|
20956
20982
|
}
|
|
20957
20983
|
return setCaffeinateHold(false, { threadId: id });
|
|
20958
20984
|
}
|
|
20959
|
-
var
|
|
20985
|
+
var import_node_child_process6, import_node_fs52, import_node_path51, hooks;
|
|
20960
20986
|
var init_caffeinate_hold = __esm({
|
|
20961
20987
|
"src/store/caffeinate-hold.ts"() {
|
|
20962
20988
|
"use strict";
|
|
20963
|
-
|
|
20989
|
+
import_node_child_process6 = require("child_process");
|
|
20964
20990
|
import_node_fs52 = require("fs");
|
|
20965
20991
|
import_node_path51 = require("path");
|
|
20966
20992
|
init_paths();
|
|
@@ -21458,6 +21484,16 @@ function writeLiveStatus(threadId, status, lastError) {
|
|
|
21458
21484
|
if (!latest || latest.status === "archived") return latest;
|
|
21459
21485
|
return setStatus(threadId, status, lastError);
|
|
21460
21486
|
}
|
|
21487
|
+
function collectActiveRunPorts(runs) {
|
|
21488
|
+
const ports = /* @__PURE__ */ new Set();
|
|
21489
|
+
for (const run2 of runs) {
|
|
21490
|
+
const list = run2.ports?.length ? run2.ports : run2.port != null ? [run2.port] : [];
|
|
21491
|
+
for (const p of list) {
|
|
21492
|
+
if (Number.isFinite(p) && p > 0) ports.add(p);
|
|
21493
|
+
}
|
|
21494
|
+
}
|
|
21495
|
+
return [...ports];
|
|
21496
|
+
}
|
|
21461
21497
|
function getOrchestrator() {
|
|
21462
21498
|
if (!singleton) {
|
|
21463
21499
|
singleton = new Orchestrator();
|
|
@@ -21733,6 +21769,9 @@ var init_orchestrator = __esm({
|
|
|
21733
21769
|
this.emit({ type: "status_changed", threadId: thread.id, status: "stopped" });
|
|
21734
21770
|
}
|
|
21735
21771
|
}
|
|
21772
|
+
if (reclaimStaleTurns) {
|
|
21773
|
+
this.reapOrphanedRunScripts();
|
|
21774
|
+
}
|
|
21736
21775
|
const repoPaths = (repoPath ? [repoPath] : [...new Set(listThreads({ includeArchived: true }).map((t) => t.repoPath))]).filter((p) => !isGlobalRepoPath(p));
|
|
21737
21776
|
await this.reconcileOrphans(repoPaths);
|
|
21738
21777
|
try {
|
|
@@ -22951,13 +22990,30 @@ var init_orchestrator = __esm({
|
|
|
22951
22990
|
worktreeRunProcessKey(thread.worktreePath, scriptName),
|
|
22952
22991
|
...siblings.map((t) => `${t.id}:run:${scriptName}`)
|
|
22953
22992
|
];
|
|
22993
|
+
let hadHandle2 = false;
|
|
22954
22994
|
for (const key of keys) {
|
|
22955
22995
|
const proc = this.processes.get(key);
|
|
22956
|
-
if (proc)
|
|
22996
|
+
if (proc) {
|
|
22997
|
+
proc.kill();
|
|
22998
|
+
hadHandle2 = true;
|
|
22999
|
+
}
|
|
22957
23000
|
this.processes.delete(key);
|
|
22958
23001
|
}
|
|
23002
|
+
const legacyKey = worktreeDevProcessKey(thread.worktreePath);
|
|
23003
|
+
const legacy = this.processes.get(legacyKey);
|
|
23004
|
+
if (legacy?.scriptName === scriptName || !legacy?.scriptName && scriptName === "dev") {
|
|
23005
|
+
if (legacy && !hadHandle2) {
|
|
23006
|
+
legacy.kill();
|
|
23007
|
+
hadHandle2 = true;
|
|
23008
|
+
}
|
|
23009
|
+
this.processes.delete(legacyKey);
|
|
23010
|
+
}
|
|
23011
|
+
const run2 = shared.activeRuns.find((r) => r.scriptName === scriptName);
|
|
23012
|
+
if (!hadHandle2 && run2) {
|
|
23013
|
+
killListenersOnPorts(collectActiveRunPorts([run2]));
|
|
23014
|
+
}
|
|
22959
23015
|
const remaining = shared.activeRuns.filter((r) => r.scriptName !== scriptName);
|
|
22960
|
-
const isPrimary = shared.devPort != null &&
|
|
23016
|
+
const isPrimary = shared.devPort != null && run2?.port === shared.devPort;
|
|
22961
23017
|
this.syncWorktreeRuns(
|
|
22962
23018
|
thread.worktreePath,
|
|
22963
23019
|
remaining,
|
|
@@ -22966,15 +23022,66 @@ var init_orchestrator = __esm({
|
|
|
22966
23022
|
this.emit({ type: "dev_server_stopped", threadId: thread.id, scriptName });
|
|
22967
23023
|
return;
|
|
22968
23024
|
}
|
|
23025
|
+
let hadHandle = false;
|
|
22969
23026
|
for (const [key, proc] of [...this.processes.entries()]) {
|
|
22970
23027
|
if (isWorktreeRunProcessKey(key, thread.worktreePath) || siblings.some((t) => key.startsWith(`${t.id}:run:`) || key === `${t.id}:dev`)) {
|
|
22971
23028
|
proc.kill();
|
|
23029
|
+
hadHandle = true;
|
|
22972
23030
|
this.processes.delete(key);
|
|
22973
23031
|
}
|
|
22974
23032
|
}
|
|
23033
|
+
if (!hadHandle && shared.activeRuns.length > 0) {
|
|
23034
|
+
killListenersOnPorts(collectActiveRunPorts(shared.activeRuns));
|
|
23035
|
+
}
|
|
22975
23036
|
this.syncWorktreeRuns(thread.worktreePath, [], null);
|
|
22976
23037
|
this.emit({ type: "dev_server_stopped", threadId: thread.id });
|
|
22977
23038
|
}
|
|
23039
|
+
/**
|
|
23040
|
+
* App quit: tear down every registered run/setup child and free persisted
|
|
23041
|
+
* ports so the next launch is not blocked by orphans.
|
|
23042
|
+
*/
|
|
23043
|
+
stopAllRunScripts() {
|
|
23044
|
+
for (const [key, proc] of [...this.processes.entries()]) {
|
|
23045
|
+
if (proc.kind !== "dev" && proc.kind !== "setup") continue;
|
|
23046
|
+
try {
|
|
23047
|
+
proc.kill();
|
|
23048
|
+
} catch {
|
|
23049
|
+
}
|
|
23050
|
+
this.processes.delete(key);
|
|
23051
|
+
}
|
|
23052
|
+
this.reapOrphanedRunScripts({ force: true });
|
|
23053
|
+
}
|
|
23054
|
+
/**
|
|
23055
|
+
* After restart (or force quit), in-memory handles are gone but `activeRuns`
|
|
23056
|
+
* and OS listeners may remain. Kill by port and clear disk metadata.
|
|
23057
|
+
* Skips worktrees that still have a live handle unless `force` (quit path).
|
|
23058
|
+
*/
|
|
23059
|
+
reapOrphanedRunScripts(opts) {
|
|
23060
|
+
const force = opts?.force === true;
|
|
23061
|
+
const seen = /* @__PURE__ */ new Set();
|
|
23062
|
+
for (const thread of listThreads({ includeArchived: true })) {
|
|
23063
|
+
if (thread.status === "archived") continue;
|
|
23064
|
+
if (isGlobalThread(thread)) continue;
|
|
23065
|
+
const wt = normalizeWorktreePath(thread.worktreePath);
|
|
23066
|
+
if (seen.has(wt)) continue;
|
|
23067
|
+
seen.add(wt);
|
|
23068
|
+
const siblings = threadsSharingWorktree(thread.worktreePath);
|
|
23069
|
+
const shared = mergeWorktreeActiveRuns(siblings);
|
|
23070
|
+
if (shared.activeRuns.length === 0 && shared.devPort == null) continue;
|
|
23071
|
+
const hasLiveHandle = [...this.processes.keys()].some(
|
|
23072
|
+
(k) => isWorktreeRunProcessKey(k, thread.worktreePath) || siblings.some((t) => k.startsWith(`${t.id}:run:`) || k === `${t.id}:dev`)
|
|
23073
|
+
);
|
|
23074
|
+
if (!force && hasLiveHandle) continue;
|
|
23075
|
+
killListenersOnPorts(collectActiveRunPorts(shared.activeRuns));
|
|
23076
|
+
if (shared.devPort != null) {
|
|
23077
|
+
killListenersOnPorts([shared.devPort]);
|
|
23078
|
+
}
|
|
23079
|
+
this.syncWorktreeRuns(thread.worktreePath, [], null);
|
|
23080
|
+
for (const sibling of siblings) {
|
|
23081
|
+
this.emit({ type: "dev_server_stopped", threadId: sibling.id });
|
|
23082
|
+
}
|
|
23083
|
+
}
|
|
23084
|
+
}
|
|
22978
23085
|
syncWorktreeRuns(worktreePath, activeRuns, devPort) {
|
|
22979
23086
|
for (const sibling of threadsSharingWorktree(worktreePath)) {
|
|
22980
23087
|
updateThread(sibling.id, { activeRuns, devPort });
|
|
@@ -23330,6 +23437,9 @@ var init_orchestrator = __esm({
|
|
|
23330
23437
|
this.assertNotGlobal(thread, "Land");
|
|
23331
23438
|
const result = await confirmLand(thread, opts);
|
|
23332
23439
|
if (result.prUrl) {
|
|
23440
|
+
if (shouldStopRunOnPrRetarget(thread.prUrl, result.prUrl)) {
|
|
23441
|
+
this.stopDev(thread.id);
|
|
23442
|
+
}
|
|
23333
23443
|
const patch = { prUrl: result.prUrl };
|
|
23334
23444
|
try {
|
|
23335
23445
|
const meta = await getPrMeta(thread.worktreePath, result.prUrl);
|
|
@@ -23439,6 +23549,9 @@ var init_orchestrator = __esm({
|
|
|
23439
23549
|
async persistPrMetaAndMaybeArchive(thread, meta) {
|
|
23440
23550
|
const prevState = normalizePrState(thread.prState);
|
|
23441
23551
|
const nextState = normalizePrState(meta.state);
|
|
23552
|
+
if (shouldStopRunOnPrRetarget(thread.prUrl, meta.url)) {
|
|
23553
|
+
this.stopDev(thread.id);
|
|
23554
|
+
}
|
|
23442
23555
|
const siblings = threadsSharingWorktree(thread.worktreePath);
|
|
23443
23556
|
const targets = siblings.length > 0 ? siblings : [thread];
|
|
23444
23557
|
for (const t of targets) {
|
|
@@ -23481,6 +23594,9 @@ var init_orchestrator = __esm({
|
|
|
23481
23594
|
if (current?.position != null && thread.stackLayer !== current.position) {
|
|
23482
23595
|
patch.stackLayer = current.position;
|
|
23483
23596
|
}
|
|
23597
|
+
if (current?.prUrl && shouldStopRunOnPrRetarget(thread.prUrl, current.prUrl)) {
|
|
23598
|
+
this.stopDev(thread.id);
|
|
23599
|
+
}
|
|
23484
23600
|
if (current?.prUrl && current.prUrl !== thread.prUrl) patch.prUrl = current.prUrl;
|
|
23485
23601
|
if (current?.title && current.title !== thread.prTitle) patch.prTitle = current.title;
|
|
23486
23602
|
if (current?.branchName && current.branchName !== thread.branchName) {
|
package/dist/mcp/run-stdio.js
CHANGED