@sideboard-ai/core 0.1.226 → 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.
@@ -418,7 +418,7 @@ async function continueSourceThread(threadId, prompt) {
418
418
  await continueOnReply(threadId, prompt);
419
419
  return;
420
420
  }
421
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-OTEYZHTZ.js");
421
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-CWOSAYAE.js");
422
422
  await getOrchestrator2().send(threadId, prompt);
423
423
  } catch {
424
424
  }
@@ -1143,6 +1143,12 @@ function samePrIdentity(a, b) {
1143
1143
  const rn = right.match(/\/pull\/(\d+)/i)?.[1];
1144
1144
  return Boolean(ln && rn && ln === rn);
1145
1145
  }
1146
+ function shouldStopRunOnPrRetarget(previousPrUrl, nextPrUrl) {
1147
+ const prev = (previousPrUrl ?? "").trim();
1148
+ const next = (nextPrUrl ?? "").trim();
1149
+ if (!prev || !next) return false;
1150
+ return !samePrIdentity(prev, next);
1151
+ }
1146
1152
  function shouldPersistFetchedPrMeta(opts) {
1147
1153
  const meta = opts.metaUrl?.trim() || "";
1148
1154
  if (!meta) return false;
@@ -2190,17 +2196,27 @@ function killListenersOnPorts(ports) {
2190
2196
  "-Command",
2191
2197
  `Get-NetTCPConnection -LocalPort ${port} -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }`
2192
2198
  ],
2193
- { stdio: "ignore" }
2194
- );
2195
- } else {
2196
- execFileSync(
2197
- "zsh",
2198
- [
2199
- "-lc",
2200
- `pids=$(lsof -tiTCP:${port} -sTCP:LISTEN 2>/dev/null); [ -n "$pids" ] && kill -TERM $pids 2>/dev/null; true`
2201
- ],
2202
- { stdio: "ignore" }
2199
+ { stdio: "ignore", timeout: 3e3 }
2203
2200
  );
2201
+ continue;
2202
+ }
2203
+ let raw = "";
2204
+ try {
2205
+ raw = execFileSync("lsof", [`-tiTCP:${port}`, "-sTCP:LISTEN"], {
2206
+ encoding: "utf8",
2207
+ stdio: ["ignore", "pipe", "ignore"],
2208
+ timeout: 2e3
2209
+ });
2210
+ } catch {
2211
+ continue;
2212
+ }
2213
+ for (const token of raw.trim().split(/\s+/)) {
2214
+ const pid = Number(token);
2215
+ if (!Number.isFinite(pid) || pid <= 0) continue;
2216
+ try {
2217
+ process.kill(pid, "SIGTERM");
2218
+ } catch {
2219
+ }
2204
2220
  }
2205
2221
  } catch {
2206
2222
  }
@@ -6967,7 +6983,7 @@ function formatScheduledPrompt(name, prompt) {
6967
6983
  ${prompt}`;
6968
6984
  }
6969
6985
  async function defaultDeps() {
6970
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-OTEYZHTZ.js");
6986
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-CWOSAYAE.js");
6971
6987
  const orch = getOrchestrator2();
6972
6988
  return {
6973
6989
  findThread: (id) => findThreadByRef(id),
@@ -8923,6 +8939,9 @@ var Orchestrator = class {
8923
8939
  this.assertNotGlobal(thread, "Land");
8924
8940
  const result = await confirmLand(thread, opts);
8925
8941
  if (result.prUrl) {
8942
+ if (shouldStopRunOnPrRetarget(thread.prUrl, result.prUrl)) {
8943
+ this.stopDev(thread.id);
8944
+ }
8926
8945
  const patch = { prUrl: result.prUrl };
8927
8946
  try {
8928
8947
  const meta = await getPrMeta(thread.worktreePath, result.prUrl);
@@ -9032,6 +9051,9 @@ var Orchestrator = class {
9032
9051
  async persistPrMetaAndMaybeArchive(thread, meta) {
9033
9052
  const prevState = normalizePrState(thread.prState);
9034
9053
  const nextState = normalizePrState(meta.state);
9054
+ if (shouldStopRunOnPrRetarget(thread.prUrl, meta.url)) {
9055
+ this.stopDev(thread.id);
9056
+ }
9035
9057
  const siblings = threadsSharingWorktree(thread.worktreePath);
9036
9058
  const targets = siblings.length > 0 ? siblings : [thread];
9037
9059
  for (const t of targets) {
@@ -9074,6 +9096,9 @@ var Orchestrator = class {
9074
9096
  if (current?.position != null && thread.stackLayer !== current.position) {
9075
9097
  patch.stackLayer = current.position;
9076
9098
  }
9099
+ if (current?.prUrl && shouldStopRunOnPrRetarget(thread.prUrl, current.prUrl)) {
9100
+ this.stopDev(thread.id);
9101
+ }
9077
9102
  if (current?.prUrl && current.prUrl !== thread.prUrl) patch.prUrl = current.prUrl;
9078
9103
  if (current?.title && current.title !== thread.prTitle) patch.prTitle = current.title;
9079
9104
  if (current?.branchName && current.branchName !== thread.branchName) {
@@ -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-IEU7U3RP.js");
485
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-VKPHI64Q.js");
486
486
  await getOrchestrator2().send(threadId, prompt);
487
487
  } catch {
488
488
  }
@@ -1148,6 +1148,12 @@ function samePrIdentity(a, b) {
1148
1148
  const rn = right.match(/\/pull\/(\d+)/i)?.[1];
1149
1149
  return Boolean(ln && rn && ln === rn);
1150
1150
  }
1151
+ function shouldStopRunOnPrRetarget(previousPrUrl, nextPrUrl) {
1152
+ const prev = (previousPrUrl ?? "").trim();
1153
+ const next = (nextPrUrl ?? "").trim();
1154
+ if (!prev || !next) return false;
1155
+ return !samePrIdentity(prev, next);
1156
+ }
1151
1157
  function shouldPersistFetchedPrMeta(opts) {
1152
1158
  const meta = opts.metaUrl?.trim() || "";
1153
1159
  if (!meta) return false;
@@ -2248,17 +2254,27 @@ function killListenersOnPorts(ports) {
2248
2254
  "-Command",
2249
2255
  `Get-NetTCPConnection -LocalPort ${port} -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }`
2250
2256
  ],
2251
- { stdio: "ignore" }
2252
- );
2253
- } else {
2254
- execFileSync(
2255
- "zsh",
2256
- [
2257
- "-lc",
2258
- `pids=$(lsof -tiTCP:${port} -sTCP:LISTEN 2>/dev/null); [ -n "$pids" ] && kill -TERM $pids 2>/dev/null; true`
2259
- ],
2260
- { stdio: "ignore" }
2257
+ { stdio: "ignore", timeout: 3e3 }
2261
2258
  );
2259
+ continue;
2260
+ }
2261
+ let raw = "";
2262
+ try {
2263
+ raw = execFileSync("lsof", [`-tiTCP:${port}`, "-sTCP:LISTEN"], {
2264
+ encoding: "utf8",
2265
+ stdio: ["ignore", "pipe", "ignore"],
2266
+ timeout: 2e3
2267
+ });
2268
+ } catch {
2269
+ continue;
2270
+ }
2271
+ for (const token of raw.trim().split(/\s+/)) {
2272
+ const pid = Number(token);
2273
+ if (!Number.isFinite(pid) || pid <= 0) continue;
2274
+ try {
2275
+ process.kill(pid, "SIGTERM");
2276
+ } catch {
2277
+ }
2262
2278
  }
2263
2279
  } catch {
2264
2280
  }
@@ -7342,7 +7358,7 @@ function formatScheduledPrompt(name, prompt) {
7342
7358
  ${prompt}`;
7343
7359
  }
7344
7360
  async function defaultDeps() {
7345
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-IEU7U3RP.js");
7361
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-VKPHI64Q.js");
7346
7362
  const orch = getOrchestrator2();
7347
7363
  return {
7348
7364
  findThread: (id) => findThreadByRef(id),
@@ -9298,6 +9314,9 @@ var Orchestrator = class {
9298
9314
  this.assertNotGlobal(thread, "Land");
9299
9315
  const result = await confirmLand(thread, opts);
9300
9316
  if (result.prUrl) {
9317
+ if (shouldStopRunOnPrRetarget(thread.prUrl, result.prUrl)) {
9318
+ this.stopDev(thread.id);
9319
+ }
9301
9320
  const patch = { prUrl: result.prUrl };
9302
9321
  try {
9303
9322
  const meta = await getPrMeta(thread.worktreePath, result.prUrl);
@@ -9407,6 +9426,9 @@ var Orchestrator = class {
9407
9426
  async persistPrMetaAndMaybeArchive(thread, meta) {
9408
9427
  const prevState = normalizePrState(thread.prState);
9409
9428
  const nextState = normalizePrState(meta.state);
9429
+ if (shouldStopRunOnPrRetarget(thread.prUrl, meta.url)) {
9430
+ this.stopDev(thread.id);
9431
+ }
9410
9432
  const siblings = threadsSharingWorktree(thread.worktreePath);
9411
9433
  const targets = siblings.length > 0 ? siblings : [thread];
9412
9434
  for (const t of targets) {
@@ -9449,6 +9471,9 @@ var Orchestrator = class {
9449
9471
  if (current?.position != null && thread.stackLayer !== current.position) {
9450
9472
  patch.stackLayer = current.position;
9451
9473
  }
9474
+ if (current?.prUrl && shouldStopRunOnPrRetarget(thread.prUrl, current.prUrl)) {
9475
+ this.stopDev(thread.id);
9476
+ }
9452
9477
  if (current?.prUrl && current.prUrl !== thread.prUrl) patch.prUrl = current.prUrl;
9453
9478
  if (current?.title && current.title !== thread.prTitle) patch.prTitle = current.title;
9454
9479
  if (current?.branchName && current.branchName !== thread.branchName) {
package/dist/index.cjs CHANGED
@@ -16084,6 +16084,12 @@ function samePrIdentity(a, b) {
16084
16084
  const rn = right.match(/\/pull\/(\d+)/i)?.[1];
16085
16085
  return Boolean(ln && rn && ln === rn);
16086
16086
  }
16087
+ function shouldStopRunOnPrRetarget(previousPrUrl, nextPrUrl) {
16088
+ const prev = (previousPrUrl ?? "").trim();
16089
+ const next = (nextPrUrl ?? "").trim();
16090
+ if (!prev || !next) return false;
16091
+ return !samePrIdentity(prev, next);
16092
+ }
16087
16093
  function shouldPersistFetchedPrMeta(opts) {
16088
16094
  const meta = opts.metaUrl?.trim() || "";
16089
16095
  if (!meta) return false;
@@ -17232,17 +17238,27 @@ function killListenersOnPorts(ports) {
17232
17238
  "-Command",
17233
17239
  `Get-NetTCPConnection -LocalPort ${port} -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }`
17234
17240
  ],
17235
- { stdio: "ignore" }
17236
- );
17237
- } else {
17238
- (0, import_node_child_process5.execFileSync)(
17239
- "zsh",
17240
- [
17241
- "-lc",
17242
- `pids=$(lsof -tiTCP:${port} -sTCP:LISTEN 2>/dev/null); [ -n "$pids" ] && kill -TERM $pids 2>/dev/null; true`
17243
- ],
17244
- { stdio: "ignore" }
17241
+ { stdio: "ignore", timeout: 3e3 }
17245
17242
  );
17243
+ continue;
17244
+ }
17245
+ let raw = "";
17246
+ try {
17247
+ raw = (0, import_node_child_process5.execFileSync)("lsof", [`-tiTCP:${port}`, "-sTCP:LISTEN"], {
17248
+ encoding: "utf8",
17249
+ stdio: ["ignore", "pipe", "ignore"],
17250
+ timeout: 2e3
17251
+ });
17252
+ } catch {
17253
+ continue;
17254
+ }
17255
+ for (const token of raw.trim().split(/\s+/)) {
17256
+ const pid = Number(token);
17257
+ if (!Number.isFinite(pid) || pid <= 0) continue;
17258
+ try {
17259
+ process.kill(pid, "SIGTERM");
17260
+ } catch {
17261
+ }
17246
17262
  }
17247
17263
  } catch {
17248
17264
  }
@@ -25214,6 +25230,9 @@ var init_orchestrator = __esm({
25214
25230
  this.assertNotGlobal(thread, "Land");
25215
25231
  const result = await confirmLand(thread, opts);
25216
25232
  if (result.prUrl) {
25233
+ if (shouldStopRunOnPrRetarget(thread.prUrl, result.prUrl)) {
25234
+ this.stopDev(thread.id);
25235
+ }
25217
25236
  const patch = { prUrl: result.prUrl };
25218
25237
  try {
25219
25238
  const meta = await getPrMeta(thread.worktreePath, result.prUrl);
@@ -25323,6 +25342,9 @@ var init_orchestrator = __esm({
25323
25342
  async persistPrMetaAndMaybeArchive(thread, meta) {
25324
25343
  const prevState = normalizePrState(thread.prState);
25325
25344
  const nextState = normalizePrState(meta.state);
25345
+ if (shouldStopRunOnPrRetarget(thread.prUrl, meta.url)) {
25346
+ this.stopDev(thread.id);
25347
+ }
25326
25348
  const siblings = threadsSharingWorktree(thread.worktreePath);
25327
25349
  const targets = siblings.length > 0 ? siblings : [thread];
25328
25350
  for (const t of targets) {
@@ -25365,6 +25387,9 @@ var init_orchestrator = __esm({
25365
25387
  if (current?.position != null && thread.stackLayer !== current.position) {
25366
25388
  patch.stackLayer = current.position;
25367
25389
  }
25390
+ if (current?.prUrl && shouldStopRunOnPrRetarget(thread.prUrl, current.prUrl)) {
25391
+ this.stopDev(thread.id);
25392
+ }
25368
25393
  if (current?.prUrl && current.prUrl !== thread.prUrl) patch.prUrl = current.prUrl;
25369
25394
  if (current?.title && current.title !== thread.prTitle) patch.prTitle = current.title;
25370
25395
  if (current?.branchName && current.branchName !== thread.branchName) {
package/dist/index.d.cts CHANGED
@@ -3899,7 +3899,8 @@ interface ScriptHandle {
3899
3899
  * Free TCP listeners on ports we allocated for a run script.
3900
3900
  * Used when the in-memory process handle is gone (app restart) or as a
3901
3901
  * backstop when process-group kill leaves grandchildren bound.
3902
- * Synchronous so Stop / startup reap free the port before the next Start.
3902
+ * Uses `lsof`/`process.kill` directly (no login shell) so Stop / quit stay
3903
+ * responsive on the Electron main thread.
3903
3904
  */
3904
3905
  declare function killListenersOnPorts(ports: number[]): void;
3905
3906
  declare function runSetupScript(repoPath: string, worktreePath: string, onLine?: (line: string) => void, opts?: {
package/dist/index.d.ts CHANGED
@@ -3899,7 +3899,8 @@ interface ScriptHandle {
3899
3899
  * Free TCP listeners on ports we allocated for a run script.
3900
3900
  * Used when the in-memory process handle is gone (app restart) or as a
3901
3901
  * backstop when process-group kill leaves grandchildren bound.
3902
- * Synchronous so Stop / startup reap free the port before the next Start.
3902
+ * Uses `lsof`/`process.kill` directly (no login shell) so Stop / quit stay
3903
+ * responsive on the Electron main thread.
3903
3904
  */
3904
3905
  declare function killListenersOnPorts(ports: number[]): void;
3905
3906
  declare function runSetupScript(repoPath: string, worktreePath: string, onLine?: (line: string) => void, opts?: {
package/dist/index.js CHANGED
@@ -319,7 +319,7 @@ import {
319
319
  worktreeCleanupSettings,
320
320
  wrapReviewSkillMarkdown,
321
321
  writeWorktreeFile
322
- } from "./chunk-VQDYONM4.js";
322
+ } from "./chunk-I2HOATRJ.js";
323
323
  import {
324
324
  LEGACY_PLAN_FILE_REL,
325
325
  PLAN_FILE_NAME,
@@ -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;
@@ -14441,17 +14447,27 @@ function killListenersOnPorts(ports) {
14441
14447
  "-Command",
14442
14448
  `Get-NetTCPConnection -LocalPort ${port} -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }`
14443
14449
  ],
14444
- { stdio: "ignore" }
14445
- );
14446
- } else {
14447
- (0, import_node_child_process4.execFileSync)(
14448
- "zsh",
14449
- [
14450
- "-lc",
14451
- `pids=$(lsof -tiTCP:${port} -sTCP:LISTEN 2>/dev/null); [ -n "$pids" ] && kill -TERM $pids 2>/dev/null; true`
14452
- ],
14453
- { stdio: "ignore" }
14450
+ { stdio: "ignore", timeout: 3e3 }
14454
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
+ }
14455
14471
  }
14456
14472
  } catch {
14457
14473
  }
@@ -23421,6 +23437,9 @@ var init_orchestrator = __esm({
23421
23437
  this.assertNotGlobal(thread, "Land");
23422
23438
  const result = await confirmLand(thread, opts);
23423
23439
  if (result.prUrl) {
23440
+ if (shouldStopRunOnPrRetarget(thread.prUrl, result.prUrl)) {
23441
+ this.stopDev(thread.id);
23442
+ }
23424
23443
  const patch = { prUrl: result.prUrl };
23425
23444
  try {
23426
23445
  const meta = await getPrMeta(thread.worktreePath, result.prUrl);
@@ -23530,6 +23549,9 @@ var init_orchestrator = __esm({
23530
23549
  async persistPrMetaAndMaybeArchive(thread, meta) {
23531
23550
  const prevState = normalizePrState(thread.prState);
23532
23551
  const nextState = normalizePrState(meta.state);
23552
+ if (shouldStopRunOnPrRetarget(thread.prUrl, meta.url)) {
23553
+ this.stopDev(thread.id);
23554
+ }
23533
23555
  const siblings = threadsSharingWorktree(thread.worktreePath);
23534
23556
  const targets = siblings.length > 0 ? siblings : [thread];
23535
23557
  for (const t of targets) {
@@ -23572,6 +23594,9 @@ var init_orchestrator = __esm({
23572
23594
  if (current?.position != null && thread.stackLayer !== current.position) {
23573
23595
  patch.stackLayer = current.position;
23574
23596
  }
23597
+ if (current?.prUrl && shouldStopRunOnPrRetarget(thread.prUrl, current.prUrl)) {
23598
+ this.stopDev(thread.id);
23599
+ }
23575
23600
  if (current?.prUrl && current.prUrl !== thread.prUrl) patch.prUrl = current.prUrl;
23576
23601
  if (current?.title && current.title !== thread.prTitle) patch.prTitle = current.title;
23577
23602
  if (current?.branchName && current.branchName !== thread.branchName) {
@@ -50,7 +50,7 @@ import {
50
50
  syncBoardPins,
51
51
  updateSchedule,
52
52
  waitForDetachedJob
53
- } from "../chunk-EGKSFWVZ.js";
53
+ } from "../chunk-FUDJ6NFM.js";
54
54
  import "../chunk-JFOPOMK7.js";
55
55
  import "../chunk-YWI3IBP2.js";
56
56
  import {
@@ -10,7 +10,7 @@ import {
10
10
  resolveSendFollowUp,
11
11
  startOrchestration,
12
12
  waitForPidExit
13
- } from "./chunk-EGKSFWVZ.js";
13
+ } from "./chunk-FUDJ6NFM.js";
14
14
  import "./chunk-JFOPOMK7.js";
15
15
  import "./chunk-YWI3IBP2.js";
16
16
  import "./chunk-SQHRPJ7P.js";
@@ -8,7 +8,7 @@ import {
8
8
  resolveSendFollowUp,
9
9
  startOrchestration,
10
10
  waitForPidExit
11
- } from "./chunk-VQDYONM4.js";
11
+ } from "./chunk-I2HOATRJ.js";
12
12
  import "./chunk-DJU54RYW.js";
13
13
  import "./chunk-VUW3VKLW.js";
14
14
  import "./chunk-N2VST3NL.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sideboard-ai/core",
3
- "version": "0.1.226",
3
+ "version": "0.1.227",
4
4
  "description": "Sideboard core — orchestration, agents, git worktrees, MCP server",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",