@sideboard-ai/core 0.1.303 → 0.1.304

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.
Files changed (84) hide show
  1. package/dist/{abletime-APP3DZ4P.js → abletime-SJUVZVRU.js} +6 -6
  2. package/dist/{abletime-RYDAQ3FE.js → abletime-T5YSJLNZ.js} +6 -6
  3. package/dist/{abletime-oauth-ZURGXSY6.js → abletime-oauth-2TOOZ2FN.js} +5 -5
  4. package/dist/{abletime-oauth-KTERKARA.js → abletime-oauth-73TFJME4.js} +5 -5
  5. package/dist/{abletime-rest-4TVIWLZK.js → abletime-rest-5TDRIFEV.js} +5 -5
  6. package/dist/{abletime-rest-EUB6RW7K.js → abletime-rest-PNUGH2FS.js} +5 -5
  7. package/dist/agents/claude-runner.js +2 -2
  8. package/dist/agents/cursor-runner.js +5 -5
  9. package/dist/{agents-3GN4E2X3.js → agents-IWNQOQOU.js} +12 -12
  10. package/dist/{agents-XLHFVC64.js → agents-PGU5WVSO.js} +10 -10
  11. package/dist/{app-settings-2IH42VA5.js → app-settings-CC65VPBL.js} +3 -3
  12. package/dist/{app-settings-3OQWRKOK.js → app-settings-DZ5AY7N5.js} +3 -3
  13. package/dist/{caffeinate-hold-7JM5H5P3.js → caffeinate-hold-H7TTUDGM.js} +2 -2
  14. package/dist/{caffeinate-hold-DYJGWK6Y.js → caffeinate-hold-ZNUEZGHB.js} +2 -2
  15. package/dist/{chunk-545DY7CQ.js → chunk-33HIBNSF.js} +106 -64
  16. package/dist/{chunk-FA3V56KF.js → chunk-3UDRWMIM.js} +2 -2
  17. package/dist/{chunk-7IAMHN2N.js → chunk-42JGPPVS.js} +1 -1
  18. package/dist/{chunk-BRFDPV7Z.js → chunk-5QX2NYXL.js} +4 -4
  19. package/dist/{chunk-DW6NNYUJ.js → chunk-5SFA27CF.js} +61 -8
  20. package/dist/{chunk-XCXUVX7I.js → chunk-62ESCTJ4.js} +1 -1
  21. package/dist/{chunk-SSETL5EX.js → chunk-6424BACS.js} +2 -2
  22. package/dist/{chunk-RSATPXU4.js → chunk-A2YXQC65.js} +264 -2
  23. package/dist/{chunk-GEFH4QFX.js → chunk-BIPXOHZI.js} +3 -3
  24. package/dist/{chunk-HSF2RQSQ.js → chunk-CFTOKVQN.js} +5 -5
  25. package/dist/{chunk-3D3GGL6X.js → chunk-CW4FIIDE.js} +3 -3
  26. package/dist/{chunk-5DZUWGKV.js → chunk-DC3VZXMA.js} +1 -1
  27. package/dist/{chunk-5MVOZLN7.js → chunk-DLGGLV2M.js} +3 -3
  28. package/dist/{chunk-WZCPZVUC.js → chunk-EGTCXNQM.js} +3 -3
  29. package/dist/{chunk-3TZRSKFJ.js → chunk-EZYZGDWU.js} +422 -175
  30. package/dist/{chunk-7AYOOG77.js → chunk-G2L3CR3A.js} +471 -107
  31. package/dist/{chunk-EHT2DRT4.js → chunk-H4UEFJRI.js} +4 -0
  32. package/dist/{chunk-P2GHFJOB.js → chunk-HG25AYBV.js} +2 -2
  33. package/dist/{chunk-GS6O65Q2.js → chunk-I34DCC4L.js} +104 -62
  34. package/dist/{chunk-UN5Q7POQ.js → chunk-J2LNLI4S.js} +1 -1
  35. package/dist/{chunk-MOP5L5QZ.js → chunk-JARCAPKL.js} +3 -3
  36. package/dist/{chunk-FAXOEKQR.js → chunk-JWW66PO3.js} +5 -5
  37. package/dist/{chunk-3HO2OY5T.js → chunk-KI45T4DI.js} +1 -1
  38. package/dist/{chunk-NOT4SEAM.js → chunk-LAWLUOWQ.js} +1 -1
  39. package/dist/{chunk-UWQ6UCIB.js → chunk-LG6RJBIY.js} +1 -1
  40. package/dist/{chunk-IOY2LF3Y.js → chunk-MMVMQ34G.js} +1 -1
  41. package/dist/{chunk-LZVWKJXY.js → chunk-OLSLE3LO.js} +3 -3
  42. package/dist/{chunk-RAGDMEIB.js → chunk-OVNIP265.js} +59 -8
  43. package/dist/{chunk-BU6HH5VA.js → chunk-PHMFAU35.js} +66 -2
  44. package/dist/{chunk-ISEYRGMP.js → chunk-RU6DTCCV.js} +2 -2
  45. package/dist/{chunk-R3R3ZDFC.js → chunk-SZ3XS2WM.js} +2 -2
  46. package/dist/{chunk-B42H6GJR.js → chunk-U4WACWBC.js} +3 -3
  47. package/dist/{chunk-VGNLMGBK.js → chunk-VEVFHO6K.js} +5 -5
  48. package/dist/{chunk-4RZRHTSZ.js → chunk-WMZIANPV.js} +1 -1
  49. package/dist/{chunk-H5XL4KUS.js → chunk-WOU343SI.js} +4 -0
  50. package/dist/{chunk-QDDTVIWE.js → chunk-WRZRX4Q7.js} +2 -2
  51. package/dist/{chunk-YCDHLK2Z.js → chunk-X3FSWWW2.js} +4 -4
  52. package/dist/{chunk-QDA6NXRA.js → chunk-YDUHLWI5.js} +1 -1
  53. package/dist/{chunk-J54UPHXZ.js → chunk-YJBUYGPN.js} +1 -1
  54. package/dist/{conductor-ATST6OMC.js → conductor-YBXURAUL.js} +10 -8
  55. package/dist/{conductor-2AVFGSQJ.js → conductor-ZFRXTVGP.js} +10 -8
  56. package/dist/{connected-teams-BJ6PMIST.js → connected-teams-BBNYTR3I.js} +2 -2
  57. package/dist/{connected-teams-AB7ZHJVO.js → connected-teams-WLWIVYGD.js} +2 -2
  58. package/dist/{coordinator-prompt-TIAI6A47.js → coordinator-prompt-GZCWQAAV.js} +7 -7
  59. package/dist/{coordinator-prompt-CQPUNMRX.js → coordinator-prompt-YAZRQ4BI.js} +7 -7
  60. package/dist/{cursor-recover-A6V5UVFT.js → cursor-recover-OWPQUHFH.js} +2 -2
  61. package/dist/{cursor-recover-MB3T2K5T.js → cursor-recover-TEBFKAZ4.js} +2 -2
  62. package/dist/{global-workspace-7YABMLQG.js → global-workspace-BZAVBOH3.js} +7 -7
  63. package/dist/{global-workspace-UZJUHGQP.js → global-workspace-H6X32IJZ.js} +7 -7
  64. package/dist/index.cjs +13486 -12609
  65. package/dist/index.d.cts +94 -14
  66. package/dist/index.d.ts +94 -14
  67. package/dist/index.js +11807 -11663
  68. package/dist/{managed-accounts-2AK5RIAF.js → managed-accounts-JJTAKHMG.js} +2 -2
  69. package/dist/{managed-accounts-46A4KRUE.js → managed-accounts-PITLFLKU.js} +2 -2
  70. package/dist/mcp/run-stdio.cjs +1037 -616
  71. package/dist/mcp/run-stdio.js +20 -20
  72. package/dist/{optional-cli-JQVNSMSU.js → optional-cli-QDIT57VD.js} +5 -5
  73. package/dist/{optional-cli-PZXDOVJJ.js → optional-cli-QY6V5S5N.js} +6 -6
  74. package/dist/{orchestrator-CZPRDLHV.js → orchestrator-IKKSYIQ3.js} +16 -16
  75. package/dist/{orchestrator-COX6QO2B.js → orchestrator-JGHYZDDB.js} +14 -14
  76. package/dist/{paths-HYT5WOOX.js → paths-HAAJNTTE.js} +1 -1
  77. package/dist/{paths-5JYXTAPC.js → paths-PHWEVXD5.js} +1 -1
  78. package/dist/{thread-store-PNX4HVLO.js → thread-store-HY22M5A7.js} +3 -3
  79. package/dist/{thread-store-VC4AIKN3.js → thread-store-XMUQDO5O.js} +3 -3
  80. package/dist/{workspaces-GZ7F5EJR.js → workspaces-AGOLRBYZ.js} +7 -7
  81. package/dist/{workspaces-6DJL4IST.js → workspaces-BQUDYTBX.js} +7 -7
  82. package/dist/{worktree-2BYVRYPJ.js → worktree-C5VI46RZ.js} +6 -6
  83. package/dist/{worktree-VXPOY2LE.js → worktree-FMK57ULT.js} +6 -6
  84. package/package.json +4 -1
@@ -363,6 +363,8 @@ function parseSettingsFile(path, source) {
363
363
  if (Array.isArray(copySection?.paths)) {
364
364
  filesToCopy.push(...copySection.paths.map(String));
365
365
  }
366
+ const worktree = data.worktree;
367
+ const sharedDirectories = Array.isArray(worktree?.shared_directories) ? worktree.shared_directories.map(String).map((item) => item.trim()).filter(Boolean) : [];
366
368
  const fileIncludeGlobs = [];
367
369
  if (Array.isArray(data.file_include_globs)) {
368
370
  fileIncludeGlobs.push(...data.file_include_globs.map(String));
@@ -414,6 +416,7 @@ function parseSettingsFile(path, source) {
414
416
  fileIncludeGlobs: fileIncludeGlobs.length ? fileIncludeGlobs : void 0,
415
417
  runScripts,
416
418
  worktreesRoot: worktreesRoot2,
419
+ sharedDirectories: sharedDirectories.length ? sharedDirectories : void 0,
417
420
  editor,
418
421
  prompts: hasPrompts ? prompts : void 0
419
422
  };
@@ -445,6 +448,7 @@ function mergeSettings(base, overlay) {
445
448
  fileIncludeGlobs: overlay.fileIncludeGlobs ?? base.fileIncludeGlobs,
446
449
  runScripts: mergeRunScripts(base.runScripts, overlay.runScripts),
447
450
  worktreesRoot: overlay.worktreesRoot ?? base.worktreesRoot,
451
+ sharedDirectories: overlay.sharedDirectories ?? base.sharedDirectories,
448
452
  editor: overlay.editor ?? base.editor,
449
453
  prompts: hasPrompts ? prompts : void 0
450
454
  };
@@ -3862,6 +3866,44 @@ var init_account_profile = __esm({
3862
3866
  }
3863
3867
  });
3864
3868
 
3869
+ // src/remote/protocol.ts
3870
+ function normalizeRemoteRelayUrl(raw) {
3871
+ let text7 = raw.trim();
3872
+ if (!text7) return null;
3873
+ if (!/^[a-z][a-z0-9+.-]*:\/\//i.test(text7)) text7 = `wss://${text7}`;
3874
+ let url;
3875
+ try {
3876
+ url = new URL(text7);
3877
+ } catch {
3878
+ return null;
3879
+ }
3880
+ if (url.protocol === "https:") url.protocol = "wss:";
3881
+ else if (url.protocol === "http:") url.protocol = "ws:";
3882
+ if (url.protocol !== "ws:" && url.protocol !== "wss:") return null;
3883
+ if (url.username || url.password) return null;
3884
+ const path = url.pathname.replace(/\/+$/, "") || "/";
3885
+ if (path !== "/" && path !== REMOTE_RELAY_PATH) return null;
3886
+ url.pathname = REMOTE_RELAY_PATH;
3887
+ url.search = "";
3888
+ url.hash = "";
3889
+ return url.toString();
3890
+ }
3891
+ function remoteRelayUrl(configured) {
3892
+ const fromSettings = configured?.trim() ? normalizeRemoteRelayUrl(configured) : null;
3893
+ if (fromSettings) return fromSettings;
3894
+ const fromEnv = process.env.SIDEBOARD_REMOTE_RELAY_URL?.trim();
3895
+ if (fromEnv) return normalizeRemoteRelayUrl(fromEnv) || BAKED_REMOTE_RELAY_URL;
3896
+ return BAKED_REMOTE_RELAY_URL;
3897
+ }
3898
+ var REMOTE_RELAY_PATH, BAKED_REMOTE_RELAY_URL;
3899
+ var init_protocol = __esm({
3900
+ "src/remote/protocol.ts"() {
3901
+ "use strict";
3902
+ REMOTE_RELAY_PATH = "/remote";
3903
+ BAKED_REMOTE_RELAY_URL = `wss://relay.sideboard.cloud${REMOTE_RELAY_PATH}`;
3904
+ }
3905
+ });
3906
+
3865
3907
  // src/store/private-file.ts
3866
3908
  function writePrivateFile2(path, contents) {
3867
3909
  (0, import_node_fs12.mkdirSync)((0, import_node_path13.dirname)(path), { recursive: true });
@@ -4038,6 +4080,12 @@ function normalizeVault(raw) {
4038
4080
  if (typeof raw.remoteHostSecret === "string" && raw.remoteHostSecret.trim()) {
4039
4081
  out.remoteHostSecret = raw.remoteHostSecret.trim();
4040
4082
  }
4083
+ if (typeof raw.remoteHostPrivateKey === "string" && raw.remoteHostPrivateKey.trim()) {
4084
+ out.remoteHostPrivateKey = raw.remoteHostPrivateKey.trim();
4085
+ }
4086
+ if (typeof raw.remotePhoneToken === "string" && raw.remotePhoneToken.trim()) {
4087
+ out.remotePhoneToken = raw.remotePhoneToken.trim();
4088
+ }
4041
4089
  if (typeof raw.remoteAccountToken === "string" && raw.remoteAccountToken.trim()) {
4042
4090
  out.remoteAccountToken = raw.remoteAccountToken.trim();
4043
4091
  }
@@ -4882,6 +4930,10 @@ function normalizeIntegrations(raw) {
4882
4930
  const email = source.remoteAccountEmail.trim().toLowerCase();
4883
4931
  if (email) out.remoteAccountEmail = email;
4884
4932
  }
4933
+ if (typeof source.remoteRelayUrl === "string") {
4934
+ const url = normalizeRemoteRelayUrl(source.remoteRelayUrl);
4935
+ if (url) out.remoteRelayUrl = url;
4936
+ }
4885
4937
  if (typeof source.githubGitAuthMode === "string" && GIT_AUTH_MODES.has(source.githubGitAuthMode)) {
4886
4938
  out.githubGitAuthMode = source.githubGitAuthMode;
4887
4939
  }
@@ -5244,6 +5296,9 @@ function persistSplit(settings) {
5244
5296
  vault[key] = integrations[key];
5245
5297
  delete integrations[key];
5246
5298
  }
5299
+ const previous = loadSecretVault();
5300
+ if (previous.remoteHostPrivateKey) vault.remoteHostPrivateKey = previous.remoteHostPrivateKey;
5301
+ if (previous.remotePhoneToken) vault.remotePhoneToken = previous.remotePhoneToken;
5247
5302
  writePrivateFile2(
5248
5303
  appSettingsPath(),
5249
5304
  `${JSON.stringify({ ...settings, environment: {}, integrations }, null, 2)}
@@ -5474,6 +5529,25 @@ function updateIntegrationsSettings(patch) {
5474
5529
  integrations.remoteAccountEmail = patch.remoteAccountEmail.trim().toLowerCase();
5475
5530
  }
5476
5531
  }
5532
+ if ("remoteRelayUrl" in patch) {
5533
+ const previous = remoteRelayUrl(integrations.remoteRelayUrl);
5534
+ if (patch.remoteRelayUrl == null || patch.remoteRelayUrl.trim() === "") {
5535
+ delete integrations.remoteRelayUrl;
5536
+ } else {
5537
+ const url = normalizeRemoteRelayUrl(patch.remoteRelayUrl);
5538
+ if (!url) {
5539
+ throw new Error(
5540
+ "Relay URL must be a WebSocket address, for example wss://relay.example.com/remote."
5541
+ );
5542
+ }
5543
+ integrations.remoteRelayUrl = url;
5544
+ }
5545
+ const next = remoteRelayUrl(integrations.remoteRelayUrl);
5546
+ if (new URL(previous).origin !== new URL(next).origin) {
5547
+ delete integrations.remoteAccountToken;
5548
+ delete integrations.remoteAccountEmail;
5549
+ }
5550
+ }
5477
5551
  if ("githubGitAuthMode" in patch) {
5478
5552
  if (patch.githubGitAuthMode == null) {
5479
5553
  delete integrations.githubGitAuthMode;
@@ -6227,6 +6301,7 @@ var init_app_settings = __esm({
6227
6301
  init_thinking_effort();
6228
6302
  init_nested_electron_env();
6229
6303
  init_account_profile();
6304
+ init_protocol();
6230
6305
  init_paths();
6231
6306
  init_private_file();
6232
6307
  init_secret_vault();
@@ -11199,9 +11274,257 @@ var init_brightsy = __esm({
11199
11274
  }
11200
11275
  });
11201
11276
 
11277
+ // src/mcp-ui/meta.ts
11278
+ function parseMcpServerLaunch(entry) {
11279
+ const command = typeof entry.command === "string" ? entry.command.trim() : "";
11280
+ if (command) {
11281
+ const args = Array.isArray(entry.args) ? entry.args.filter((a) => typeof a === "string") : [];
11282
+ const env = stringRecord(entry.env);
11283
+ const cwd = typeof entry.cwd === "string" && entry.cwd.trim() ? entry.cwd.trim() : void 0;
11284
+ return {
11285
+ kind: "stdio",
11286
+ command,
11287
+ args,
11288
+ ...env ? { env } : {},
11289
+ ...cwd ? { cwd } : {}
11290
+ };
11291
+ }
11292
+ const url = typeof entry.url === "string" ? entry.url.trim() : "";
11293
+ if (!url) return null;
11294
+ let parsed;
11295
+ try {
11296
+ parsed = new URL(url);
11297
+ } catch {
11298
+ return null;
11299
+ }
11300
+ if (parsed.protocol !== "https:" && parsed.protocol !== "http:") return null;
11301
+ const type = typeof entry.type === "string" ? entry.type.trim().toLowerCase() : "";
11302
+ const headers = stringRecord(entry.headers);
11303
+ return {
11304
+ kind: type === "sse" ? "sse" : "http",
11305
+ url: parsed.toString(),
11306
+ ...headers ? { headers } : {}
11307
+ };
11308
+ }
11309
+ function stringRecord(value) {
11310
+ const rec = asRecord3(value);
11311
+ const out = {};
11312
+ for (const [key, item] of Object.entries(rec)) {
11313
+ if (typeof item === "string") out[key] = item;
11314
+ }
11315
+ return Object.keys(out).length > 0 ? out : void 0;
11316
+ }
11317
+ function asRecord3(value) {
11318
+ if (!value || typeof value !== "object" || Array.isArray(value)) return {};
11319
+ return value;
11320
+ }
11321
+ var init_meta = __esm({
11322
+ "src/mcp-ui/meta.ts"() {
11323
+ "use strict";
11324
+ }
11325
+ });
11326
+
11327
+ // src/agents/claude-plugins.ts
11328
+ function claudePluginServerId(pluginName, serverName) {
11329
+ return `plugin_${pluginName}_${serverName}`.replace(/[^A-Za-z0-9_-]/g, "_");
11330
+ }
11331
+ function listEnabledClaudePluginMcpServers(opts) {
11332
+ const home = opts?.home ?? (0, import_node_os10.homedir)();
11333
+ const pluginsRoot = claudePluginsRoot(home);
11334
+ const enabled = enabledPluginIds(home, opts?.projectDirs ?? []);
11335
+ const installed = readInstalledPlugins((0, import_node_path28.join)(pluginsRoot, "installed_plugins.json"));
11336
+ const out = {};
11337
+ for (const [id, on] of enabled) {
11338
+ if (!on) continue;
11339
+ const root = installPathFor(id, installed);
11340
+ if (!root || !(0, import_node_fs26.existsSync)(root)) continue;
11341
+ const pluginName = manifestName(root) || id.split("@")[0]?.trim() || "";
11342
+ if (!pluginName) continue;
11343
+ const dataDir = (0, import_node_path28.join)(pluginsRoot, "data", pluginDataId(id));
11344
+ for (const [serverName, entry] of Object.entries(loadPluginMcpServers(root))) {
11345
+ const expanded = expandPluginEntry(entry, root, dataDir);
11346
+ if (!parseMcpServerLaunch(expanded)) continue;
11347
+ const key = claudePluginServerId(pluginName, serverName);
11348
+ if (!key || key === "plugin__") continue;
11349
+ out[key] = expanded;
11350
+ }
11351
+ }
11352
+ return out;
11353
+ }
11354
+ function claudePluginsRoot(home) {
11355
+ const override = process.env.CLAUDE_CODE_PLUGIN_CACHE_DIR?.trim();
11356
+ if (override && (0, import_node_path28.isAbsolute)(override)) return override;
11357
+ return (0, import_node_path28.join)(home, ".claude", "plugins");
11358
+ }
11359
+ function pluginDataId(pluginId) {
11360
+ return pluginId.replace(/[^A-Za-z0-9_-]/g, "-");
11361
+ }
11362
+ function enabledPluginIds(home, projectDirs) {
11363
+ const enabled = /* @__PURE__ */ new Map();
11364
+ applyEnabled(enabled, readEnabledPlugins((0, import_node_path28.join)(home, ".claude", "settings.json")));
11365
+ const dirs = [...new Set(projectDirs.map((dir) => dir.trim()).filter(Boolean))];
11366
+ for (const dir of dirs) {
11367
+ applyEnabled(enabled, readEnabledPlugins((0, import_node_path28.join)(dir, ".claude", "settings.json")));
11368
+ }
11369
+ for (const dir of dirs) {
11370
+ applyEnabled(enabled, readEnabledPlugins((0, import_node_path28.join)(dir, ".claude", "settings.local.json")));
11371
+ }
11372
+ return enabled;
11373
+ }
11374
+ function applyEnabled(into, next) {
11375
+ for (const [id, on] of Object.entries(next)) {
11376
+ const key = id.trim();
11377
+ if (!key) continue;
11378
+ into.set(key, on);
11379
+ }
11380
+ }
11381
+ function readEnabledPlugins(path) {
11382
+ const root = readJson(path);
11383
+ const raw = root.enabledPlugins;
11384
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
11385
+ const out = {};
11386
+ for (const [id, value] of Object.entries(raw)) {
11387
+ if (value === true || value === false) out[id] = value;
11388
+ }
11389
+ return out;
11390
+ }
11391
+ function readInstalledPlugins(path) {
11392
+ const root = readJson(path);
11393
+ const plugins = root.plugins;
11394
+ if (!plugins || typeof plugins !== "object" || Array.isArray(plugins)) return {};
11395
+ const out = {};
11396
+ for (const [id, value] of Object.entries(plugins)) {
11397
+ const rows = Array.isArray(value) ? value : [value];
11398
+ const installs = [];
11399
+ for (const row of rows) {
11400
+ if (!row || typeof row !== "object" || Array.isArray(row)) continue;
11401
+ const installPath = row.installPath;
11402
+ installs.push({
11403
+ ...typeof installPath === "string" && installPath.trim() ? { installPath: installPath.trim() } : {}
11404
+ });
11405
+ }
11406
+ if (installs.length) out[id] = installs;
11407
+ }
11408
+ return out;
11409
+ }
11410
+ function installPathFor(id, installed) {
11411
+ const rows = installed[id] ?? [];
11412
+ for (let i = rows.length - 1; i >= 0; i--) {
11413
+ const path = rows[i]?.installPath;
11414
+ if (path && (0, import_node_fs26.existsSync)(path)) return path;
11415
+ }
11416
+ return null;
11417
+ }
11418
+ function manifestName(root) {
11419
+ const manifest = readJson((0, import_node_path28.join)(root, ".claude-plugin", "plugin.json"));
11420
+ return typeof manifest.name === "string" ? manifest.name.trim() : "";
11421
+ }
11422
+ function loadPluginMcpServers(root) {
11423
+ const servers = {};
11424
+ mergeServerMap(servers, serversFromFile((0, import_node_path28.join)(root, ".mcp.json"), root));
11425
+ const manifest = readJson((0, import_node_path28.join)(root, ".claude-plugin", "plugin.json"));
11426
+ mergeServerMap(servers, serversFromManifest(manifest.mcpServers, root));
11427
+ return servers;
11428
+ }
11429
+ function serversFromManifest(value, root) {
11430
+ if (!value) return {};
11431
+ if (typeof value === "string") return serversFromFile(resolveInside(root, value), root);
11432
+ if (Array.isArray(value)) {
11433
+ const out = {};
11434
+ for (const item of value) {
11435
+ if (typeof item === "string") mergeServerMap(out, serversFromFile(resolveInside(root, item), root));
11436
+ else mergeServerMap(out, serverMap(item, root));
11437
+ }
11438
+ return out;
11439
+ }
11440
+ return serverMap(value, root);
11441
+ }
11442
+ function serversFromFile(path, root) {
11443
+ if (!path || !(0, import_node_fs26.existsSync)(path)) return {};
11444
+ return serverMap(readJson(path), root);
11445
+ }
11446
+ function serverMap(value, root) {
11447
+ if (!value || typeof value !== "object" || Array.isArray(value)) return {};
11448
+ const record = value;
11449
+ const wrapped = record.mcpServers;
11450
+ const source = wrapped && typeof wrapped === "object" && !Array.isArray(wrapped) ? wrapped : record;
11451
+ if (typeof wrapped === "string") return serversFromFile(resolveInside(root, wrapped), root);
11452
+ const out = {};
11453
+ for (const [name, entry] of Object.entries(source)) {
11454
+ if (!name.trim() || !entry || typeof entry !== "object" || Array.isArray(entry)) continue;
11455
+ const row = entry;
11456
+ if (row.disabled === true) continue;
11457
+ if (typeof row.command !== "string" && typeof row.url !== "string") continue;
11458
+ out[name.trim()] = row;
11459
+ }
11460
+ return out;
11461
+ }
11462
+ function mergeServerMap(into, extra) {
11463
+ for (const [name, entry] of Object.entries(extra)) into[name] = entry;
11464
+ }
11465
+ function expandPluginEntry(entry, root, dataDir) {
11466
+ const next = { ...entry };
11467
+ if (typeof next.command === "string") next.command = expandVars(next.command, root, dataDir);
11468
+ if (Array.isArray(next.args)) {
11469
+ next.args = next.args.map((arg) => typeof arg === "string" ? expandVars(arg, root, dataDir) : arg);
11470
+ }
11471
+ if (typeof next.url === "string") next.url = expandVars(next.url, root, dataDir);
11472
+ if (next.env && typeof next.env === "object" && !Array.isArray(next.env)) {
11473
+ const env = {};
11474
+ for (const [key, value] of Object.entries(next.env)) {
11475
+ if (typeof value === "string") env[key] = expandVars(value, root, dataDir);
11476
+ }
11477
+ env.CLAUDE_PLUGIN_ROOT = env.CLAUDE_PLUGIN_ROOT || root;
11478
+ env.CLAUDE_PLUGIN_DATA = env.CLAUDE_PLUGIN_DATA || dataDir;
11479
+ next.env = env;
11480
+ } else if (typeof next.command === "string") {
11481
+ next.env = { CLAUDE_PLUGIN_ROOT: root, CLAUDE_PLUGIN_DATA: dataDir };
11482
+ }
11483
+ if (next.headers && typeof next.headers === "object" && !Array.isArray(next.headers)) {
11484
+ const headers = {};
11485
+ for (const [key, value] of Object.entries(next.headers)) {
11486
+ if (typeof value === "string") headers[key] = expandVars(value, root, dataDir);
11487
+ }
11488
+ next.headers = headers;
11489
+ }
11490
+ return next;
11491
+ }
11492
+ function expandVars(value, root, dataDir) {
11493
+ return value.replaceAll("${CLAUDE_PLUGIN_ROOT}", root).replaceAll("${CLAUDE_PLUGIN_DATA}", dataDir);
11494
+ }
11495
+ function resolveInside(root, spec) {
11496
+ const trimmed = spec.trim();
11497
+ if (!trimmed || trimmed.endsWith(".mcpb") || trimmed.endsWith(".dxt")) return null;
11498
+ if (/^https?:\/\//i.test(trimmed)) return null;
11499
+ const abs = (0, import_node_path28.resolve)(root, trimmed);
11500
+ const rel = (0, import_node_path28.relative)(root, abs);
11501
+ if (!rel || rel.startsWith("..") || (0, import_node_path28.isAbsolute)(rel)) return null;
11502
+ return abs;
11503
+ }
11504
+ function readJson(path) {
11505
+ if (!(0, import_node_fs26.existsSync)(path)) return {};
11506
+ try {
11507
+ const parsed = JSON.parse((0, import_node_fs26.readFileSync)(path, "utf8"));
11508
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
11509
+ return parsed;
11510
+ } catch {
11511
+ return {};
11512
+ }
11513
+ }
11514
+ var import_node_fs26, import_node_os10, import_node_path28;
11515
+ var init_claude_plugins = __esm({
11516
+ "src/agents/claude-plugins.ts"() {
11517
+ "use strict";
11518
+ import_node_fs26 = require("fs");
11519
+ import_node_os10 = require("os");
11520
+ import_node_path28 = require("path");
11521
+ init_meta();
11522
+ }
11523
+ });
11524
+
11202
11525
  // src/agent-rpc/protocol.ts
11203
11526
  var AGENT_RPC_PROTOCOL_VERSION, AGENT_RPC_TOKEN_QUERY, AGENT_RPC_NATIVE_ENV, AGENT_RPC_URL_ENV, AGENT_RPC_TOKEN_ENV, AGENT_RPC_CWD_ENV, AGENT_RPC_CLAUDE_SDK_SERVER;
11204
- var init_protocol = __esm({
11527
+ var init_protocol2 = __esm({
11205
11528
  "src/agent-rpc/protocol.ts"() {
11206
11529
  "use strict";
11207
11530
  AGENT_RPC_PROTOCOL_VERSION = 1;
@@ -11245,7 +11568,7 @@ var SIDEBOARD_MCP_PROFILE_ENV, SIDEBOARD_THREAD_ID_ENV, AGENT_RPC_PILOT_MCP_TOOL
11245
11568
  var init_profile = __esm({
11246
11569
  "src/mcp/profile.ts"() {
11247
11570
  "use strict";
11248
- init_protocol();
11571
+ init_protocol2();
11249
11572
  init_paths();
11250
11573
  SIDEBOARD_MCP_PROFILE_ENV = "SIDEBOARD_MCP_PROFILE";
11251
11574
  SIDEBOARD_THREAD_ID_ENV = "SIDEBOARD_THREAD_ID";
@@ -11292,43 +11615,43 @@ function electronResourcesPath() {
11292
11615
  function packagedCursorRuntimeDir() {
11293
11616
  const resources = electronResourcesPath();
11294
11617
  if (!resources) return null;
11295
- const dir = (0, import_node_path28.join)(resources, "cursor-runtime");
11296
- if (!(0, import_node_fs26.existsSync)((0, import_node_path28.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
11618
+ const dir = (0, import_node_path29.join)(resources, "cursor-runtime");
11619
+ if (!(0, import_node_fs27.existsSync)((0, import_node_path29.join)(dir, "core-dist", "agents", "cursor-runner.js"))) return null;
11297
11620
  return dir;
11298
11621
  }
11299
11622
  function packagedCursorRunnerPath() {
11300
11623
  const dir = packagedCursorRuntimeDir();
11301
- return dir ? (0, import_node_path28.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
11624
+ return dir ? (0, import_node_path29.join)(dir, "core-dist", "agents", "cursor-runner.js") : null;
11302
11625
  }
11303
11626
  function packagedMcpDir() {
11304
11627
  const resources = electronResourcesPath();
11305
11628
  if (!resources) return null;
11306
- const dir = (0, import_node_path28.join)(resources, "sideboard-mcp");
11307
- if (!(0, import_node_fs26.existsSync)((0, import_node_path28.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
11629
+ const dir = (0, import_node_path29.join)(resources, "sideboard-mcp");
11630
+ if (!(0, import_node_fs27.existsSync)((0, import_node_path29.join)(dir, "core-dist", "mcp", "run-stdio.js"))) return null;
11308
11631
  return dir;
11309
11632
  }
11310
11633
  function packagedMcpStdioPath() {
11311
11634
  const dir = packagedMcpDir();
11312
- return dir ? (0, import_node_path28.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
11635
+ return dir ? (0, import_node_path29.join)(dir, "core-dist", "mcp", "run-stdio.js") : null;
11313
11636
  }
11314
11637
  function packagedBundledNodePath() {
11315
11638
  const resources = electronResourcesPath();
11316
11639
  if (!resources) return null;
11317
- const bin = (0, import_node_path28.join)(resources, "node", "bin", "node");
11318
- if (!(0, import_node_fs26.existsSync)(bin)) return null;
11640
+ const bin = (0, import_node_path29.join)(resources, "node", "bin", "node");
11641
+ if (!(0, import_node_fs27.existsSync)(bin)) return null;
11319
11642
  return bin;
11320
11643
  }
11321
11644
  function packagedCursorRipgrepCandidate(platformPkg, binName) {
11322
11645
  const dir = packagedCursorRuntimeDir();
11323
11646
  if (!dir) return null;
11324
- return (0, import_node_path28.join)(dir, "node_modules", platformPkg, "bin", binName);
11647
+ return (0, import_node_path29.join)(dir, "node_modules", platformPkg, "bin", binName);
11325
11648
  }
11326
- var import_node_fs26, import_node_path28;
11649
+ var import_node_fs27, import_node_path29;
11327
11650
  var init_packaged_runtime = __esm({
11328
11651
  "src/agents/packaged-runtime.ts"() {
11329
11652
  "use strict";
11330
- import_node_fs26 = require("fs");
11331
- import_node_path28 = require("path");
11653
+ import_node_fs27 = require("fs");
11654
+ import_node_path29 = require("path");
11332
11655
  }
11333
11656
  });
11334
11657
 
@@ -11363,7 +11686,7 @@ function unpackedAsarPath(filePath) {
11363
11686
  if (!isAsarPath(filePath)) return null;
11364
11687
  const unpacked = filePath.replace(/\.asar(?=[/\\])/, ".asar.unpacked");
11365
11688
  if (unpacked === filePath) return null;
11366
- return (0, import_node_fs27.existsSync)(unpacked) ? unpacked : null;
11689
+ return (0, import_node_fs28.existsSync)(unpacked) ? unpacked : null;
11367
11690
  }
11368
11691
  function nodeReadableScriptPath(scriptPath) {
11369
11692
  return unpackedAsarPath(scriptPath) ?? scriptPath;
@@ -11403,37 +11726,37 @@ function pickPreferredNode(candidates) {
11403
11726
  return best;
11404
11727
  }
11405
11728
  function versionDirNodeBins(root, toBin) {
11406
- if (!(0, import_node_fs27.existsSync)(root)) return [];
11729
+ if (!(0, import_node_fs28.existsSync)(root)) return [];
11407
11730
  try {
11408
- return (0, import_node_fs27.readdirSync)(root).map(toBin);
11731
+ return (0, import_node_fs28.readdirSync)(root).map(toBin);
11409
11732
  } catch {
11410
11733
  return [];
11411
11734
  }
11412
11735
  }
11413
- function defaultNodeBinCandidates(home = (0, import_node_os10.homedir)()) {
11736
+ function defaultNodeBinCandidates(home = (0, import_node_os11.homedir)()) {
11414
11737
  const kegs = ["/opt/homebrew", "/usr/local"].flatMap(
11415
- (prefix) => PREFERRED_LTS_MAJORS.map((major) => (0, import_node_path29.join)(prefix, "opt", `node@${major}`, "bin", "node"))
11738
+ (prefix) => PREFERRED_LTS_MAJORS.map((major) => (0, import_node_path30.join)(prefix, "opt", `node@${major}`, "bin", "node"))
11416
11739
  );
11417
11740
  return [
11418
11741
  ...kegs,
11419
11742
  "/opt/homebrew/bin/node",
11420
11743
  "/usr/local/bin/node",
11421
- (0, import_node_path29.join)(home, ".local/share/fnm/aliases/default/bin/node"),
11422
- (0, import_node_path29.join)(home, ".nvm/current/bin/node"),
11423
- (0, import_node_path29.join)(home, ".volta/bin/node"),
11424
- (0, import_node_path29.join)(home, ".asdf/shims/node"),
11425
- (0, import_node_path29.join)(home, ".local/share/mise/shims/node"),
11744
+ (0, import_node_path30.join)(home, ".local/share/fnm/aliases/default/bin/node"),
11745
+ (0, import_node_path30.join)(home, ".nvm/current/bin/node"),
11746
+ (0, import_node_path30.join)(home, ".volta/bin/node"),
11747
+ (0, import_node_path30.join)(home, ".asdf/shims/node"),
11748
+ (0, import_node_path30.join)(home, ".local/share/mise/shims/node"),
11426
11749
  ...versionDirNodeBins(
11427
- (0, import_node_path29.join)(home, ".nvm", "versions", "node"),
11428
- (name) => (0, import_node_path29.join)(home, ".nvm", "versions", "node", name, "bin", "node")
11750
+ (0, import_node_path30.join)(home, ".nvm", "versions", "node"),
11751
+ (name) => (0, import_node_path30.join)(home, ".nvm", "versions", "node", name, "bin", "node")
11429
11752
  ),
11430
11753
  ...versionDirNodeBins(
11431
- (0, import_node_path29.join)(home, ".local/share/fnm", "node-versions"),
11432
- (name) => (0, import_node_path29.join)(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
11754
+ (0, import_node_path30.join)(home, ".local/share/fnm", "node-versions"),
11755
+ (name) => (0, import_node_path30.join)(home, ".local/share/fnm", "node-versions", name, "installation", "bin", "node")
11433
11756
  ),
11434
11757
  ...versionDirNodeBins(
11435
- (0, import_node_path29.join)(home, ".volta", "tools", "image", "node"),
11436
- (name) => (0, import_node_path29.join)(home, ".volta", "tools", "image", "node", name, "bin", "node")
11758
+ (0, import_node_path30.join)(home, ".volta", "tools", "image", "node"),
11759
+ (name) => (0, import_node_path30.join)(home, ".volta", "tools", "image", "node", name, "bin", "node")
11437
11760
  )
11438
11761
  ];
11439
11762
  }
@@ -11442,10 +11765,10 @@ function uniqueExistingNodeBins(paths) {
11442
11765
  const out = [];
11443
11766
  for (const raw of paths) {
11444
11767
  const p = raw.trim();
11445
- if (!p || !(0, import_node_fs27.existsSync)(p) || isElectronLikeCommand(p)) continue;
11768
+ if (!p || !(0, import_node_fs28.existsSync)(p) || isElectronLikeCommand(p)) continue;
11446
11769
  let key = p;
11447
11770
  try {
11448
- key = (0, import_node_fs27.realpathSync)(p);
11771
+ key = (0, import_node_fs28.realpathSync)(p);
11449
11772
  } catch {
11450
11773
  continue;
11451
11774
  }
@@ -11525,13 +11848,13 @@ async function resolveNodeLaunch(scriptPath) {
11525
11848
  env: { ELECTRON_RUN_AS_NODE: "1" }
11526
11849
  };
11527
11850
  }
11528
- var import_node_fs27, import_node_os10, import_node_path29, AGENT_RUNNER_MAX_OLD_SPACE_MB, MAX_OLD_SPACE_FLAG, PREFERRED_LTS_MAJORS;
11851
+ var import_node_fs28, import_node_os11, import_node_path30, AGENT_RUNNER_MAX_OLD_SPACE_MB, MAX_OLD_SPACE_FLAG, PREFERRED_LTS_MAJORS;
11529
11852
  var init_node_launch = __esm({
11530
11853
  "src/agents/node-launch.ts"() {
11531
11854
  "use strict";
11532
- import_node_fs27 = require("fs");
11533
- import_node_os10 = require("os");
11534
- import_node_path29 = require("path");
11855
+ import_node_fs28 = require("fs");
11856
+ import_node_os11 = require("os");
11857
+ import_node_path30 = require("path");
11535
11858
  init_nested_electron_env();
11536
11859
  init_system_ca();
11537
11860
  init_run();
@@ -11634,39 +11957,39 @@ function corePackageDir() {
11634
11957
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
11635
11958
  if (cjsDir) return cjsDir;
11636
11959
  try {
11637
- const url = import_meta.url;
11960
+ const url = import_meta2.url;
11638
11961
  if (typeof url === "string" && url.length > 0) {
11639
- return (0, import_node_path30.dirname)((0, import_node_url.fileURLToPath)(url));
11962
+ return (0, import_node_path31.dirname)((0, import_node_url.fileURLToPath)(url));
11640
11963
  }
11641
11964
  } catch {
11642
11965
  }
11643
11966
  try {
11644
- const req = (0, import_node_module.createRequire)((0, import_node_path30.join)(process.cwd(), "package.json"));
11645
- return (0, import_node_path30.dirname)(req.resolve("@sideboard-ai/core"));
11967
+ const req = (0, import_node_module.createRequire)((0, import_node_path31.join)(process.cwd(), "package.json"));
11968
+ return (0, import_node_path31.dirname)(req.resolve("@sideboard-ai/core"));
11646
11969
  } catch {
11647
11970
  return process.cwd();
11648
11971
  }
11649
11972
  }
11650
11973
  function findSideboardMcpJsEntry() {
11651
11974
  const override = process.env.SIDEBOARD_MCP_ENTRY?.trim() || process.env.SIDEBOARD_CLI?.trim();
11652
- if (override && (0, import_node_fs28.existsSync)(override)) return override;
11975
+ if (override && (0, import_node_fs29.existsSync)(override)) return override;
11653
11976
  const packaged = packagedMcpStdioPath();
11654
11977
  if (packaged) return packaged;
11655
11978
  let dir = corePackageDir();
11656
11979
  for (let i = 0; i < 10; i++) {
11657
11980
  const candidates = [
11658
- (0, import_node_path30.join)(dir, "mcp/run-stdio.js"),
11659
- (0, import_node_path30.join)(dir, "mcp/run-stdio.cjs"),
11660
- (0, import_node_path30.join)(dir, "dist/mcp/run-stdio.js"),
11661
- (0, import_node_path30.join)(dir, "dist/mcp/run-stdio.cjs"),
11662
- (0, import_node_path30.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
11663
- (0, import_node_path30.join)(dir, "packages/cli/dist/index.js"),
11664
- (0, import_node_path30.join)(dir, "cli/dist/index.js")
11981
+ (0, import_node_path31.join)(dir, "mcp/run-stdio.js"),
11982
+ (0, import_node_path31.join)(dir, "mcp/run-stdio.cjs"),
11983
+ (0, import_node_path31.join)(dir, "dist/mcp/run-stdio.js"),
11984
+ (0, import_node_path31.join)(dir, "dist/mcp/run-stdio.cjs"),
11985
+ (0, import_node_path31.join)(dir, "packages/core/dist/mcp/run-stdio.js"),
11986
+ (0, import_node_path31.join)(dir, "packages/cli/dist/index.js"),
11987
+ (0, import_node_path31.join)(dir, "cli/dist/index.js")
11665
11988
  ];
11666
11989
  for (const p of candidates) {
11667
- if ((0, import_node_fs28.existsSync)(p) && !isAsarPath(p)) return p;
11990
+ if ((0, import_node_fs29.existsSync)(p) && !isAsarPath(p)) return p;
11668
11991
  }
11669
- const parent = (0, import_node_path30.dirname)(dir);
11992
+ const parent = (0, import_node_path31.dirname)(dir);
11670
11993
  if (parent === dir) break;
11671
11994
  dir = parent;
11672
11995
  }
@@ -11827,19 +12150,19 @@ function mcpServersRecord(servers, extraServers) {
11827
12150
  function writeMcpServersConfig(servers, extraServers) {
11828
12151
  const mcpServers = mcpServersRecord(servers, extraServers);
11829
12152
  if (Object.keys(mcpServers).length === 0) return null;
11830
- const dir = (0, import_node_fs28.mkdtempSync)((0, import_node_path30.join)((0, import_node_os11.tmpdir)(), "sideboard-mcp-"));
11831
- const cfgPath = (0, import_node_path30.join)(dir, "mcp.json");
11832
- (0, import_node_fs28.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
12153
+ const dir = (0, import_node_fs29.mkdtempSync)((0, import_node_path31.join)((0, import_node_os12.tmpdir)(), "sideboard-mcp-"));
12154
+ const cfgPath = (0, import_node_path31.join)(dir, "mcp.json");
12155
+ (0, import_node_fs29.writeFileSync)(cfgPath, JSON.stringify({ mcpServers }, null, 2));
11833
12156
  return cfgPath;
11834
12157
  }
11835
- var import_node_fs28, import_node_module, import_node_os11, import_node_path30, import_node_url, import_meta, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, SIDEBOARD_GITHUB_MCP_ALLOWED_TOOLS, SIDEBOARD_LINEAR_MCP_ALLOWED_TOOLS, SIDEBOARD_ABLETIME_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
12158
+ var import_node_fs29, import_node_module, import_node_os12, import_node_path31, import_node_url, import_meta2, SIDEBOARD_MCP_ALLOWED_TOOLS, SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS, SIDEBOARD_GITHUB_MCP_ALLOWED_TOOLS, SIDEBOARD_LINEAR_MCP_ALLOWED_TOOLS, SIDEBOARD_ABLETIME_MCP_ALLOWED_TOOLS, brightsyMcpCommandCache, BRIGHTSY_WORD;
11836
12159
  var init_injected_mcp = __esm({
11837
12160
  "src/agents/injected-mcp.ts"() {
11838
12161
  "use strict";
11839
- import_node_fs28 = require("fs");
12162
+ import_node_fs29 = require("fs");
11840
12163
  import_node_module = require("module");
11841
- import_node_os11 = require("os");
11842
- import_node_path30 = require("path");
12164
+ import_node_os12 = require("os");
12165
+ import_node_path31 = require("path");
11843
12166
  import_node_url = require("url");
11844
12167
  init_run();
11845
12168
  init_config();
@@ -11851,7 +12174,7 @@ var init_injected_mcp = __esm({
11851
12174
  init_packaged_runtime();
11852
12175
  init_nested_electron_env();
11853
12176
  init_git_auth_mode();
11854
- import_meta = {};
12177
+ import_meta2 = {};
11855
12178
  SIDEBOARD_MCP_ALLOWED_TOOLS = [
11856
12179
  "mcp__sideboard",
11857
12180
  "mcp__sideboard__*"
@@ -11893,15 +12216,15 @@ var init_injected_mcp = __esm({
11893
12216
 
11894
12217
  // src/agents/user-mcp-config.ts
11895
12218
  function userClaudeMcpConfigPath() {
11896
- return (0, import_node_path31.join)((0, import_node_os12.homedir)(), ".claude.json");
12219
+ return (0, import_node_path32.join)((0, import_node_os13.homedir)(), ".claude.json");
11897
12220
  }
11898
- var import_node_fs29, import_node_os12, import_node_path31;
12221
+ var import_node_fs30, import_node_os13, import_node_path32;
11899
12222
  var init_user_mcp_config = __esm({
11900
12223
  "src/agents/user-mcp-config.ts"() {
11901
12224
  "use strict";
11902
- import_node_fs29 = require("fs");
11903
- import_node_os12 = require("os");
11904
- import_node_path31 = require("path");
12225
+ import_node_fs30 = require("fs");
12226
+ import_node_os13 = require("os");
12227
+ import_node_path32 = require("path");
11905
12228
  init_paths();
11906
12229
  init_injected_mcp();
11907
12230
  }
@@ -11929,25 +12252,25 @@ function listMcpNamesFromCodexToml(text7) {
11929
12252
  }
11930
12253
  function readJsonObject2(path) {
11931
12254
  try {
11932
- return JSON.parse((0, import_node_fs30.readFileSync)(path, "utf8"));
12255
+ return JSON.parse((0, import_node_fs31.readFileSync)(path, "utf8"));
11933
12256
  } catch {
11934
12257
  return {};
11935
12258
  }
11936
12259
  }
11937
12260
  function readText(path) {
11938
12261
  try {
11939
- return (0, import_node_fs30.readFileSync)(path, "utf8");
12262
+ return (0, import_node_fs31.readFileSync)(path, "utf8");
11940
12263
  } catch {
11941
12264
  return "";
11942
12265
  }
11943
12266
  }
11944
- function userCodexConfigPaths(home = (0, import_node_os13.homedir)()) {
11945
- return [(0, import_node_path32.join)(home, ".codex", "config.toml"), (0, import_node_path32.join)(home, ".config", "codex", "config.toml")];
12267
+ function userCodexConfigPaths(home = (0, import_node_os14.homedir)()) {
12268
+ return [(0, import_node_path33.join)(home, ".codex", "config.toml"), (0, import_node_path33.join)(home, ".config", "codex", "config.toml")];
11946
12269
  }
11947
- function userOpencodeConfigPaths(home = (0, import_node_os13.homedir)()) {
12270
+ function userOpencodeConfigPaths(home = (0, import_node_os14.homedir)()) {
11948
12271
  return [
11949
- (0, import_node_path32.join)(home, ".config", "opencode", "opencode.json"),
11950
- (0, import_node_path32.join)(home, ".config", "opencode", "opencode.jsonc")
12272
+ (0, import_node_path33.join)(home, ".config", "opencode", "opencode.json"),
12273
+ (0, import_node_path33.join)(home, ".config", "opencode", "opencode.jsonc")
11951
12274
  ];
11952
12275
  }
11953
12276
  function userMcpNamesToDisable(opts) {
@@ -11966,29 +12289,35 @@ function userMcpNamesToDisable(opts) {
11966
12289
  }
11967
12290
  return out;
11968
12291
  }
11969
- function listUserCodexMcpNames(home = (0, import_node_os13.homedir)()) {
12292
+ function listUserCodexMcpNames(home = (0, import_node_os14.homedir)()) {
11970
12293
  const names = [];
11971
12294
  for (const path of userCodexConfigPaths(home)) {
11972
- if (!(0, import_node_fs30.existsSync)(path)) continue;
12295
+ if (!(0, import_node_fs31.existsSync)(path)) continue;
11973
12296
  names.push(...listMcpNamesFromCodexToml(readText(path)));
11974
12297
  }
11975
12298
  return names;
11976
12299
  }
11977
- function listUserOpencodeMcpNames(home = (0, import_node_os13.homedir)()) {
12300
+ function listUserOpencodeMcpNames(home = (0, import_node_os14.homedir)()) {
11978
12301
  const names = [];
11979
12302
  for (const path of userOpencodeConfigPaths(home)) {
11980
- if (!(0, import_node_fs30.existsSync)(path)) continue;
12303
+ if (!(0, import_node_fs31.existsSync)(path)) continue;
11981
12304
  names.push(...listMcpNamesFromJsonMap(readJsonObject2(path), "mcp"));
11982
12305
  }
11983
12306
  return names;
11984
12307
  }
11985
- function userClaudeMcpConfigObject(home = (0, import_node_os13.homedir)()) {
11986
- const claudePath = home === (0, import_node_os13.homedir)() ? userClaudeMcpConfigPath() : (0, import_node_path32.join)(home, ".claude.json");
11987
- if (!(0, import_node_fs30.existsSync)(claudePath)) return {};
12308
+ function userClaudeMcpConfigObject(home = (0, import_node_os14.homedir)()) {
12309
+ const claudePath = home === (0, import_node_os14.homedir)() ? userClaudeMcpConfigPath() : (0, import_node_path33.join)(home, ".claude.json");
12310
+ if (!(0, import_node_fs31.existsSync)(claudePath)) return {};
11988
12311
  return asObject(asObject(readJsonObject2(claudePath)).mcpServers);
11989
12312
  }
11990
- function listUserClaudeMcpServerEntries(home = (0, import_node_os13.homedir)()) {
12313
+ function listUserClaudeMcpServerEntries(home = (0, import_node_os14.homedir)(), projectDirs) {
11991
12314
  const out = {};
12315
+ for (const [name, entry] of Object.entries(
12316
+ listEnabledClaudePluginMcpServers({ home, projectDirs })
12317
+ )) {
12318
+ if (!name || isInjectedOrchMcpName(name)) continue;
12319
+ out[name] = entry;
12320
+ }
11992
12321
  for (const [rawName, value] of Object.entries(userClaudeMcpConfigObject(home))) {
11993
12322
  const name = rawName.trim();
11994
12323
  if (!name || isInjectedOrchMcpName(name)) continue;
@@ -12017,13 +12346,14 @@ function toCodexUnattendedAppsArgs() {
12017
12346
  "features.plugins=false"
12018
12347
  ];
12019
12348
  }
12020
- var import_node_fs30, import_node_os13, import_node_path32, import_smol_toml2;
12349
+ var import_node_fs31, import_node_os14, import_node_path33, import_smol_toml2;
12021
12350
  var init_orch_mcp_isolation = __esm({
12022
12351
  "src/agents/orch-mcp-isolation.ts"() {
12023
12352
  "use strict";
12024
- import_node_fs30 = require("fs");
12025
- import_node_os13 = require("os");
12026
- import_node_path32 = require("path");
12353
+ import_node_fs31 = require("fs");
12354
+ init_claude_plugins();
12355
+ import_node_os14 = require("os");
12356
+ import_node_path33 = require("path");
12027
12357
  import_smol_toml2 = require("smol-toml");
12028
12358
  init_user_mcp_config();
12029
12359
  }
@@ -12082,11 +12412,11 @@ var init_types = __esm({
12082
12412
 
12083
12413
  // src/agent-rpc/metadata.ts
12084
12414
  function agentRuntimeMetadataPath() {
12085
- return (0, import_node_path33.join)(appDataDir(), "agent-runtime.json");
12415
+ return (0, import_node_path34.join)(appDataDir(), "agent-runtime.json");
12086
12416
  }
12087
12417
  function readAgentRuntimeMetadata() {
12088
12418
  try {
12089
- const raw = JSON.parse((0, import_node_fs31.readFileSync)(agentRuntimeMetadataPath(), "utf8"));
12419
+ const raw = JSON.parse((0, import_node_fs32.readFileSync)(agentRuntimeMetadataPath(), "utf8"));
12090
12420
  if (!raw || typeof raw !== "object") return null;
12091
12421
  const rec = raw;
12092
12422
  if (typeof rec.runtimeId !== "string" || !rec.runtimeId.trim()) return null;
@@ -12134,14 +12464,14 @@ function agentRuntimeLooksLive(meta = readAgentRuntimeMetadata()) {
12134
12464
  if (!meta) return false;
12135
12465
  return pidAlive(meta.pid);
12136
12466
  }
12137
- var import_node_fs31, import_node_path33;
12467
+ var import_node_fs32, import_node_path34;
12138
12468
  var init_metadata = __esm({
12139
12469
  "src/agent-rpc/metadata.ts"() {
12140
12470
  "use strict";
12141
- import_node_fs31 = require("fs");
12142
- import_node_path33 = require("path");
12471
+ import_node_fs32 = require("fs");
12472
+ import_node_path34 = require("path");
12143
12473
  init_paths();
12144
- init_protocol();
12474
+ init_protocol2();
12145
12475
  }
12146
12476
  });
12147
12477
 
@@ -12161,7 +12491,7 @@ var init_rpc_env = __esm({
12161
12491
  "src/agent-rpc/rpc-env.ts"() {
12162
12492
  "use strict";
12163
12493
  init_metadata();
12164
- init_protocol();
12494
+ init_protocol2();
12165
12495
  }
12166
12496
  });
12167
12497
 
@@ -12171,7 +12501,7 @@ var init_client = __esm({
12171
12501
  "src/agent-rpc/client.ts"() {
12172
12502
  "use strict";
12173
12503
  import_ws = require("ws");
12174
- init_protocol();
12504
+ init_protocol2();
12175
12505
  init_metadata();
12176
12506
  }
12177
12507
  });
@@ -12209,11 +12539,11 @@ function entryDir() {
12209
12539
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
12210
12540
  if (cjsDir) return cjsDir;
12211
12541
  try {
12212
- return (0, import_node_path34.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
12542
+ return (0, import_node_path35.dirname)((0, import_node_url2.fileURLToPath)(import_meta3.url));
12213
12543
  } catch {
12214
12544
  try {
12215
12545
  const req = (0, import_node_module2.createRequire)(process.cwd() + "/");
12216
- return (0, import_node_path34.dirname)(req.resolve("@sideboard-ai/core"));
12546
+ return (0, import_node_path35.dirname)(req.resolve("@sideboard-ai/core"));
12217
12547
  } catch {
12218
12548
  return process.cwd();
12219
12549
  }
@@ -12222,20 +12552,20 @@ function entryDir() {
12222
12552
  function claudeRunnerPath() {
12223
12553
  const packagedDir = packagedCursorRuntimeDir();
12224
12554
  if (packagedDir) {
12225
- const packaged = (0, import_node_path34.join)(packagedDir, "core-dist", "agents", "claude-runner.js");
12226
- if ((0, import_node_fs32.existsSync)(packaged)) return packaged;
12555
+ const packaged = (0, import_node_path35.join)(packagedDir, "core-dist", "agents", "claude-runner.js");
12556
+ if ((0, import_node_fs33.existsSync)(packaged)) return packaged;
12227
12557
  }
12228
12558
  const root = entryDir();
12229
12559
  const candidates = [
12230
- (0, import_node_path34.join)(root, "agents", "claude-runner.js"),
12231
- (0, import_node_path34.join)(root, "agents", "claude-runner.cjs"),
12232
- (0, import_node_path34.join)(root, "dist", "agents", "claude-runner.js"),
12233
- (0, import_node_path34.join)(root, "dist", "agents", "claude-runner.cjs"),
12234
- (0, import_node_path34.join)(root, "claude-runner.ts"),
12235
- (0, import_node_path34.join)(root, "src", "agents", "claude-runner.ts")
12560
+ (0, import_node_path35.join)(root, "agents", "claude-runner.js"),
12561
+ (0, import_node_path35.join)(root, "agents", "claude-runner.cjs"),
12562
+ (0, import_node_path35.join)(root, "dist", "agents", "claude-runner.js"),
12563
+ (0, import_node_path35.join)(root, "dist", "agents", "claude-runner.cjs"),
12564
+ (0, import_node_path35.join)(root, "claude-runner.ts"),
12565
+ (0, import_node_path35.join)(root, "src", "agents", "claude-runner.ts")
12236
12566
  ];
12237
12567
  for (const candidate of candidates) {
12238
- if ((0, import_node_fs32.existsSync)(candidate)) return candidate;
12568
+ if ((0, import_node_fs33.existsSync)(candidate)) return candidate;
12239
12569
  }
12240
12570
  return candidates[0];
12241
12571
  }
@@ -12259,19 +12589,19 @@ async function buildClaudeRpcTurnCommand(req) {
12259
12589
  }
12260
12590
  };
12261
12591
  }
12262
- var import_node_fs32, import_node_module2, import_node_path34, import_node_url2, import_meta2;
12592
+ var import_node_fs33, import_node_module2, import_node_path35, import_node_url2, import_meta3;
12263
12593
  var init_claude_host = __esm({
12264
12594
  "src/agents/claude-host.ts"() {
12265
12595
  "use strict";
12266
- import_node_fs32 = require("fs");
12596
+ import_node_fs33 = require("fs");
12267
12597
  import_node_module2 = require("module");
12268
- import_node_path34 = require("path");
12598
+ import_node_path35 = require("path");
12269
12599
  import_node_url2 = require("url");
12270
- init_protocol();
12600
+ init_protocol2();
12271
12601
  init_pilot_tools();
12272
12602
  init_node_launch();
12273
12603
  init_packaged_runtime();
12274
- import_meta2 = {};
12604
+ import_meta3 = {};
12275
12605
  }
12276
12606
  });
12277
12607
 
@@ -12674,11 +13004,12 @@ function parseIssuesJson(raw) {
12674
13004
  }
12675
13005
  return [];
12676
13006
  }
12677
- var import_node_fs33, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
13007
+ var import_node_fs34, import_node_os15, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
12678
13008
  var init_claude = __esm({
12679
13009
  "src/agents/claude.ts"() {
12680
13010
  "use strict";
12681
- import_node_fs33 = require("fs");
13011
+ import_node_fs34 = require("fs");
13012
+ import_node_os15 = require("os");
12682
13013
  init_run();
12683
13014
  init_app_settings();
12684
13015
  init_claude_mcp();
@@ -12696,7 +13027,7 @@ var init_claude = __esm({
12696
13027
  async detect() {
12697
13028
  const claude = resolveClaudeExecutable();
12698
13029
  if (claude !== "claude") {
12699
- if (!(0, import_node_fs33.existsSync)(claude)) {
13030
+ if (!(0, import_node_fs34.existsSync)(claude)) {
12700
13031
  return {
12701
13032
  agent: "claude",
12702
13033
  installed: false,
@@ -12759,7 +13090,7 @@ var init_claude = __esm({
12759
13090
  });
12760
13091
  const injectedBrightsyNames = injectedServers.filter((s) => s.name === "brightsy" || s.name.startsWith("brightsy_")).map((s) => s.name);
12761
13092
  const chromeOn = claudeChromeEnabled();
12762
- const userMcpEntries = isOrchestrator ? {} : listUserClaudeMcpServerEntries();
13093
+ const userMcpEntries = isOrchestrator ? {} : listUserClaudeMcpServerEntries((0, import_node_os15.homedir)(), [thread.repoPath, thread.worktreePath]);
12763
13094
  let allowedTools;
12764
13095
  if (isOrchestrator) {
12765
13096
  allowedTools = [
@@ -12996,7 +13327,7 @@ async function listCodexModels() {
12996
13327
  if (codex === "codex") {
12997
13328
  const which = await run("which", ["codex"], { reject: false });
12998
13329
  if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
12999
- } else if (!(0, import_node_fs34.existsSync)(codex)) {
13330
+ } else if (!(0, import_node_fs35.existsSync)(codex)) {
13000
13331
  return FALLBACK_CODEX_MODELS;
13001
13332
  }
13002
13333
  const listed = await run(codex, ["debug", "models"], { reject: false });
@@ -13031,12 +13362,12 @@ function usageFromCodex(usage) {
13031
13362
  }
13032
13363
  function codexConfigHasNetworkAccess() {
13033
13364
  const candidates = [
13034
- (0, import_node_path35.join)((0, import_node_os14.homedir)(), ".codex", "config.toml"),
13035
- (0, import_node_path35.join)((0, import_node_os14.homedir)(), ".config", "codex", "config.toml")
13365
+ (0, import_node_path36.join)((0, import_node_os16.homedir)(), ".codex", "config.toml"),
13366
+ (0, import_node_path36.join)((0, import_node_os16.homedir)(), ".config", "codex", "config.toml")
13036
13367
  ];
13037
13368
  for (const path of candidates) {
13038
- if (!(0, import_node_fs34.existsSync)(path)) continue;
13039
- const text7 = (0, import_node_fs34.readFileSync)(path, "utf8");
13369
+ if (!(0, import_node_fs35.existsSync)(path)) continue;
13370
+ const text7 = (0, import_node_fs35.readFileSync)(path, "utf8");
13040
13371
  if (/network_access\s*=\s*true/.test(text7)) return true;
13041
13372
  }
13042
13373
  return false;
@@ -13061,28 +13392,28 @@ function unwrapCodexMcpResult(result) {
13061
13392
  return String(result);
13062
13393
  }
13063
13394
  }
13064
- function asRecord3(value) {
13395
+ function asRecord4(value) {
13065
13396
  if (value && typeof value === "object" && !Array.isArray(value)) {
13066
13397
  return value;
13067
13398
  }
13068
13399
  return void 0;
13069
13400
  }
13070
13401
  function codexLooksAuthenticated() {
13071
- const authPath = (0, import_node_path35.join)((0, import_node_os14.homedir)(), ".codex", "auth.json");
13072
- if (!(0, import_node_fs34.existsSync)(authPath)) return false;
13402
+ const authPath = (0, import_node_path36.join)((0, import_node_os16.homedir)(), ".codex", "auth.json");
13403
+ if (!(0, import_node_fs35.existsSync)(authPath)) return false;
13073
13404
  try {
13074
- return (0, import_node_fs34.statSync)(authPath).size > 2;
13405
+ return (0, import_node_fs35.statSync)(authPath).size > 2;
13075
13406
  } catch {
13076
13407
  return false;
13077
13408
  }
13078
13409
  }
13079
- var import_node_fs34, import_node_os14, import_node_path35, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
13410
+ var import_node_fs35, import_node_os16, import_node_path36, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
13080
13411
  var init_codex = __esm({
13081
13412
  "src/agents/codex.ts"() {
13082
13413
  "use strict";
13083
- import_node_fs34 = require("fs");
13084
- import_node_os14 = require("os");
13085
- import_node_path35 = require("path");
13414
+ import_node_fs35 = require("fs");
13415
+ import_node_os16 = require("os");
13416
+ import_node_path36 = require("path");
13086
13417
  init_run();
13087
13418
  init_app_settings();
13088
13419
  init_global_workspace();
@@ -13108,7 +13439,7 @@ var init_codex = __esm({
13108
13439
  async detect() {
13109
13440
  const codex = resolveAgentExecutable("codex");
13110
13441
  if (codex !== "codex") {
13111
- if (!(0, import_node_fs34.existsSync)(codex)) {
13442
+ if (!(0, import_node_fs35.existsSync)(codex)) {
13112
13443
  return {
13113
13444
  agent: "codex",
13114
13445
  installed: false,
@@ -13241,7 +13572,7 @@ var init_codex = __esm({
13241
13572
  }
13242
13573
  if (itemType === "mcp_tool_call" && item.id && item.server && item.tool) {
13243
13574
  const name = `mcp__${item.server}__${item.tool}`;
13244
- const input = asRecord3(item.arguments);
13575
+ const input = asRecord4(item.arguments);
13245
13576
  const events = [
13246
13577
  { type: "tool_use", id: item.id, name, input }
13247
13578
  ];
@@ -13386,18 +13717,18 @@ var init_codex = __esm({
13386
13717
  // src/agents/cursor-sdk-resolve.ts
13387
13718
  function thisModuleFile() {
13388
13719
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
13389
- if (cjsDir) return (0, import_node_path36.join)(cjsDir, "cursor-sdk-resolve.js");
13720
+ if (cjsDir) return (0, import_node_path37.join)(cjsDir, "cursor-sdk-resolve.js");
13390
13721
  try {
13391
- return (0, import_node_url3.fileURLToPath)(import_meta3.url);
13722
+ return (0, import_node_url3.fileURLToPath)(import_meta4.url);
13392
13723
  } catch {
13393
- return (0, import_node_path36.join)(process.cwd(), "package.json");
13724
+ return (0, import_node_path37.join)(process.cwd(), "package.json");
13394
13725
  }
13395
13726
  }
13396
13727
  function packageRootLooksLikeSdk(dir) {
13397
13728
  try {
13398
- const raw = (0, import_node_fs35.readFileSync)((0, import_node_path36.join)(dir, "package.json"), "utf8");
13729
+ const raw = (0, import_node_fs36.readFileSync)((0, import_node_path37.join)(dir, "package.json"), "utf8");
13399
13730
  const pkg = JSON.parse(raw);
13400
- return pkg.name === "@cursor/sdk" && (0, import_node_fs35.existsSync)(dir);
13731
+ return pkg.name === "@cursor/sdk" && (0, import_node_fs36.existsSync)(dir);
13401
13732
  } catch {
13402
13733
  return false;
13403
13734
  }
@@ -13406,7 +13737,7 @@ function resolvedPackageRoot(fromFile) {
13406
13737
  try {
13407
13738
  const req = (0, import_node_module3.createRequire)(fromFile);
13408
13739
  const pkgJson = req.resolve("@cursor/sdk/package.json");
13409
- const root = (0, import_node_path36.dirname)(pkgJson);
13740
+ const root = (0, import_node_path37.dirname)(pkgJson);
13410
13741
  return packageRootLooksLikeSdk(root) ? root : null;
13411
13742
  } catch {
13412
13743
  return null;
@@ -13420,10 +13751,10 @@ function resolveCursorSdkRoot(opts) {
13420
13751
  }
13421
13752
  const globalNm = npmGlobalNodeModules(env);
13422
13753
  if (globalNm) {
13423
- const globalRoot = (0, import_node_path36.join)(globalNm, "@cursor/sdk");
13754
+ const globalRoot = (0, import_node_path37.join)(globalNm, "@cursor/sdk");
13424
13755
  if (packageRootLooksLikeSdk(globalRoot)) return globalRoot;
13425
13756
  }
13426
- const cwdPkg = (0, import_node_path36.join)(process.cwd(), "package.json");
13757
+ const cwdPkg = (0, import_node_path37.join)(process.cwd(), "package.json");
13427
13758
  return resolvedPackageRoot(thisModuleFile()) ?? resolvedPackageRoot(cwdPkg);
13428
13759
  }
13429
13760
  function isCursorSdkInstalled(opts) {
@@ -13439,13 +13770,13 @@ function exportTarget(value) {
13439
13770
  }
13440
13771
  function cursorSdkEsmEntry(root) {
13441
13772
  try {
13442
- const pkg = JSON.parse((0, import_node_fs35.readFileSync)((0, import_node_path36.join)(root, "package.json"), "utf8"));
13773
+ const pkg = JSON.parse((0, import_node_fs36.readFileSync)((0, import_node_path37.join)(root, "package.json"), "utf8"));
13443
13774
  const exp = pkg.exports;
13444
13775
  const dot = exp && typeof exp === "object" && !Array.isArray(exp) && "." in exp ? exp["."] : exp;
13445
13776
  const rel = exportTarget(dot) ?? (typeof pkg.module === "string" ? pkg.module : null);
13446
13777
  if (!rel) return null;
13447
- const entry = (0, import_node_path36.join)(root, rel);
13448
- return (0, import_node_fs35.existsSync)(entry) ? entry : null;
13778
+ const entry = (0, import_node_path37.join)(root, rel);
13779
+ return (0, import_node_fs36.existsSync)(entry) ? entry : null;
13449
13780
  } catch {
13450
13781
  return null;
13451
13782
  }
@@ -13461,7 +13792,7 @@ async function importCursorSdk(opts) {
13461
13792
  try {
13462
13793
  let entry = cursorSdkEsmEntry(root);
13463
13794
  if (!entry) {
13464
- const req = (0, import_node_module3.createRequire)((0, import_node_path36.join)(root, "package.json"));
13795
+ const req = (0, import_node_module3.createRequire)((0, import_node_path37.join)(root, "package.json"));
13465
13796
  entry = req.resolve("@cursor/sdk");
13466
13797
  }
13467
13798
  return unwrapCursorSdkModule(await import((0, import_node_url3.pathToFileURL)(entry).href));
@@ -13473,8 +13804,8 @@ function cursorSdkPlatformRipgrepPackage() {
13473
13804
  return `@cursor/sdk-${process.platform}-${process.arch}`;
13474
13805
  }
13475
13806
  function nodeModulesDirForPackageRoot(packageRoot) {
13476
- const parent = (0, import_node_path36.dirname)(packageRoot);
13477
- return (0, import_node_path36.basename)(parent).startsWith("@") ? (0, import_node_path36.dirname)(parent) : parent;
13807
+ const parent = (0, import_node_path37.dirname)(packageRoot);
13808
+ return (0, import_node_path37.basename)(parent).startsWith("@") ? (0, import_node_path37.dirname)(parent) : parent;
13478
13809
  }
13479
13810
  function cursorSdkRipgrepCandidate(opts) {
13480
13811
  const root = resolveCursorSdkRoot(opts);
@@ -13482,21 +13813,21 @@ function cursorSdkRipgrepCandidate(opts) {
13482
13813
  const nm = nodeModulesDirForPackageRoot(root);
13483
13814
  const pkg = cursorSdkPlatformRipgrepPackage();
13484
13815
  const bin = process.platform === "win32" ? "rg.exe" : "rg";
13485
- const sibling = (0, import_node_path36.join)(nm, pkg, "bin", bin);
13486
- if ((0, import_node_fs35.existsSync)(sibling)) return sibling;
13487
- const nested = (0, import_node_path36.join)(root, "node_modules", pkg, "bin", bin);
13488
- return (0, import_node_fs35.existsSync)(nested) ? nested : null;
13816
+ const sibling = (0, import_node_path37.join)(nm, pkg, "bin", bin);
13817
+ if ((0, import_node_fs36.existsSync)(sibling)) return sibling;
13818
+ const nested = (0, import_node_path37.join)(root, "node_modules", pkg, "bin", bin);
13819
+ return (0, import_node_fs36.existsSync)(nested) ? nested : null;
13489
13820
  }
13490
- var import_node_fs35, import_node_module3, import_node_path36, import_node_url3, import_meta3, CURSOR_SDK_INSTALL_HINT;
13821
+ var import_node_fs36, import_node_module3, import_node_path37, import_node_url3, import_meta4, CURSOR_SDK_INSTALL_HINT;
13491
13822
  var init_cursor_sdk_resolve = __esm({
13492
13823
  "src/agents/cursor-sdk-resolve.ts"() {
13493
13824
  "use strict";
13494
- import_node_fs35 = require("fs");
13825
+ import_node_fs36 = require("fs");
13495
13826
  import_node_module3 = require("module");
13496
- import_node_path36 = require("path");
13827
+ import_node_path37 = require("path");
13497
13828
  import_node_url3 = require("url");
13498
13829
  init_path();
13499
- import_meta3 = {};
13830
+ import_meta4 = {};
13500
13831
  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.";
13501
13832
  }
13502
13833
  });
@@ -13535,21 +13866,21 @@ function platformRipgrepPackage() {
13535
13866
  }
13536
13867
  function usableRipgrepPath(candidate) {
13537
13868
  const raw = candidate?.trim();
13538
- if (!raw || !(0, import_node_path37.isAbsolute)(raw)) return null;
13869
+ if (!raw || !(0, import_node_path38.isAbsolute)(raw)) return null;
13539
13870
  const readable = nodeReadableScriptPath(raw);
13540
- if (!(0, import_node_fs36.existsSync)(readable) || isAsarPath(readable)) return null;
13871
+ if (!(0, import_node_fs37.existsSync)(readable) || isAsarPath(readable)) return null;
13541
13872
  return readable;
13542
13873
  }
13543
13874
  function walkForBundledRipgrep(startFile) {
13544
13875
  if (!startFile) return null;
13545
13876
  const pkg = platformRipgrepPackage();
13546
13877
  const name = rgBinaryName();
13547
- let dir = (0, import_node_path37.dirname)((0, import_node_path37.resolve)(startFile));
13548
- const root = (0, import_node_path37.parse)(dir).root;
13878
+ let dir = (0, import_node_path38.dirname)((0, import_node_path38.resolve)(startFile));
13879
+ const root = (0, import_node_path38.parse)(dir).root;
13549
13880
  while (dir !== root) {
13550
- const hit = usableRipgrepPath((0, import_node_path37.join)(dir, "node_modules", pkg, "bin", name));
13881
+ const hit = usableRipgrepPath((0, import_node_path38.join)(dir, "node_modules", pkg, "bin", name));
13551
13882
  if (hit) return hit;
13552
- const next = (0, import_node_path37.dirname)(dir);
13883
+ const next = (0, import_node_path38.dirname)(dir);
13553
13884
  if (next === dir) break;
13554
13885
  dir = next;
13555
13886
  }
@@ -13559,7 +13890,7 @@ function requireResolveBundledRipgrep(fromFile) {
13559
13890
  try {
13560
13891
  const req = (0, import_node_module4.createRequire)(fromFile);
13561
13892
  const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
13562
- return usableRipgrepPath((0, import_node_path37.join)((0, import_node_path37.dirname)(pkgJson), "bin", rgBinaryName()));
13893
+ return usableRipgrepPath((0, import_node_path38.join)((0, import_node_path38.dirname)(pkgJson), "bin", rgBinaryName()));
13563
13894
  } catch {
13564
13895
  return null;
13565
13896
  }
@@ -13581,13 +13912,13 @@ function cursorRipgrepEnv(opts) {
13581
13912
  const path = resolveCursorRipgrepPath(opts);
13582
13913
  return path ? { [RIPGREP_ENV]: path } : {};
13583
13914
  }
13584
- var import_node_fs36, import_node_module4, import_node_path37, RIPGREP_ENV;
13915
+ var import_node_fs37, import_node_module4, import_node_path38, RIPGREP_ENV;
13585
13916
  var init_cursor_ripgrep = __esm({
13586
13917
  "src/agents/cursor-ripgrep.ts"() {
13587
13918
  "use strict";
13588
- import_node_fs36 = require("fs");
13919
+ import_node_fs37 = require("fs");
13589
13920
  import_node_module4 = require("module");
13590
- import_node_path37 = require("path");
13921
+ import_node_path38 = require("path");
13591
13922
  init_cursor_sdk_resolve();
13592
13923
  init_node_launch();
13593
13924
  init_packaged_runtime();
@@ -13631,11 +13962,11 @@ function entryDir2() {
13631
13962
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
13632
13963
  if (cjsDir) return cjsDir;
13633
13964
  try {
13634
- return (0, import_node_path38.dirname)((0, import_node_url4.fileURLToPath)(import_meta4.url));
13965
+ return (0, import_node_path39.dirname)((0, import_node_url4.fileURLToPath)(import_meta5.url));
13635
13966
  } catch {
13636
13967
  try {
13637
13968
  const req = (0, import_node_module5.createRequire)(process.cwd() + "/");
13638
- return (0, import_node_path38.dirname)(req.resolve("@sideboard-ai/core"));
13969
+ return (0, import_node_path39.dirname)(req.resolve("@sideboard-ai/core"));
13639
13970
  } catch {
13640
13971
  return process.cwd();
13641
13972
  }
@@ -13646,27 +13977,27 @@ function cursorRunnerPath() {
13646
13977
  if (packaged) return packaged;
13647
13978
  const root = entryDir2();
13648
13979
  const candidates = [
13649
- (0, import_node_path38.join)(root, "agents", "cursor-runner.js"),
13650
- (0, import_node_path38.join)(root, "agents", "cursor-runner.cjs"),
13980
+ (0, import_node_path39.join)(root, "agents", "cursor-runner.js"),
13981
+ (0, import_node_path39.join)(root, "agents", "cursor-runner.cjs"),
13651
13982
  // If somehow resolved from package root instead of dist/
13652
- (0, import_node_path38.join)(root, "dist", "agents", "cursor-runner.js"),
13653
- (0, import_node_path38.join)(root, "dist", "agents", "cursor-runner.cjs"),
13983
+ (0, import_node_path39.join)(root, "dist", "agents", "cursor-runner.js"),
13984
+ (0, import_node_path39.join)(root, "dist", "agents", "cursor-runner.cjs"),
13654
13985
  // Source tree (dev): packages/core/src/agents/cursor-runner.ts
13655
- (0, import_node_path38.join)(root, "cursor-runner.ts"),
13656
- (0, import_node_path38.join)(root, "src", "agents", "cursor-runner.ts")
13986
+ (0, import_node_path39.join)(root, "cursor-runner.ts"),
13987
+ (0, import_node_path39.join)(root, "src", "agents", "cursor-runner.ts")
13657
13988
  ];
13658
13989
  for (const candidate of candidates) {
13659
- if ((0, import_node_fs37.existsSync)(candidate)) return candidate;
13990
+ if ((0, import_node_fs38.existsSync)(candidate)) return candidate;
13660
13991
  }
13661
13992
  return candidates[0];
13662
13993
  }
13663
- var import_node_fs37, import_node_module5, import_node_path38, import_node_url4, import_meta4, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
13994
+ var import_node_fs38, import_node_module5, import_node_path39, import_node_url4, import_meta5, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
13664
13995
  var init_cursor = __esm({
13665
13996
  "src/agents/cursor.ts"() {
13666
13997
  "use strict";
13667
- import_node_fs37 = require("fs");
13998
+ import_node_fs38 = require("fs");
13668
13999
  import_node_module5 = require("module");
13669
- import_node_path38 = require("path");
14000
+ import_node_path39 = require("path");
13670
14001
  import_node_url4 = require("url");
13671
14002
  init_run();
13672
14003
  init_app_settings();
@@ -13680,7 +14011,7 @@ var init_cursor = __esm({
13680
14011
  init_packaged_runtime();
13681
14012
  init_turn_input();
13682
14013
  init_cursor_events();
13683
- import_meta4 = {};
14014
+ import_meta5 = {};
13684
14015
  FALLBACK_CURSOR_MODELS = [
13685
14016
  { id: "default", displayName: "Auto" },
13686
14017
  { id: "composer-2.5", displayName: "Composer 2.5" },
@@ -13790,22 +14121,22 @@ var init_cursor = __esm({
13790
14121
 
13791
14122
  // src/agent-rpc/opencode-hook.ts
13792
14123
  function writeOpencodeRpcPlugin() {
13793
- const configDir = (0, import_node_path39.join)(appDataDir(), "agent-rpc", "opencode");
13794
- const pluginDir = (0, import_node_path39.join)(configDir, "plugins");
13795
- (0, import_node_fs38.mkdirSync)(pluginDir, { recursive: true });
13796
- const pluginFile = (0, import_node_path39.join)(pluginDir, "sideboard-rpc.js");
13797
- (0, import_node_fs38.writeFileSync)(pluginFile, OPENCODE_PLUGIN_SOURCE);
14124
+ const configDir = (0, import_node_path40.join)(appDataDir(), "agent-rpc", "opencode");
14125
+ const pluginDir = (0, import_node_path40.join)(configDir, "plugins");
14126
+ (0, import_node_fs39.mkdirSync)(pluginDir, { recursive: true });
14127
+ const pluginFile = (0, import_node_path40.join)(pluginDir, "sideboard-rpc.js");
14128
+ (0, import_node_fs39.writeFileSync)(pluginFile, OPENCODE_PLUGIN_SOURCE);
13798
14129
  return { configDir, pluginFile };
13799
14130
  }
13800
- var import_node_fs38, import_node_path39, OPENCODE_PLUGIN_SOURCE;
14131
+ var import_node_fs39, import_node_path40, OPENCODE_PLUGIN_SOURCE;
13801
14132
  var init_opencode_hook = __esm({
13802
14133
  "src/agent-rpc/opencode-hook.ts"() {
13803
14134
  "use strict";
13804
- import_node_fs38 = require("fs");
13805
- import_node_path39 = require("path");
14135
+ import_node_fs39 = require("fs");
14136
+ import_node_path40 = require("path");
13806
14137
  init_paths();
13807
14138
  init_pilot_tools();
13808
- init_protocol();
14139
+ init_protocol2();
13809
14140
  OPENCODE_PLUGIN_SOURCE = `import { tool } from "@opencode-ai/plugin"
13810
14141
 
13811
14142
  const URL = process.env[${JSON.stringify(AGENT_RPC_URL_ENV)}] || ""
@@ -13954,7 +14285,7 @@ var init_opencode_host = __esm({
13954
14285
  });
13955
14286
 
13956
14287
  // src/agents/opencode.ts
13957
- function asRecord4(value) {
14288
+ function asRecord5(value) {
13958
14289
  if (value && typeof value === "object" && !Array.isArray(value)) {
13959
14290
  return value;
13960
14291
  }
@@ -13999,7 +14330,7 @@ async function listOpencodeModels() {
13999
14330
  if (opencode === "opencode") {
14000
14331
  const which = await run("which", ["opencode"], { reject: false });
14001
14332
  if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
14002
- } else if (!(0, import_node_fs39.existsSync)(opencode)) {
14333
+ } else if (!(0, import_node_fs40.existsSync)(opencode)) {
14003
14334
  return FALLBACK_OPENCODE_MODELS;
14004
14335
  }
14005
14336
  const listed = await run(opencode, ["models"], { reject: false });
@@ -14029,11 +14360,11 @@ function usageFromOpencode(tokens) {
14029
14360
  cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
14030
14361
  };
14031
14362
  }
14032
- var import_node_fs39, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
14363
+ var import_node_fs40, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
14033
14364
  var init_opencode = __esm({
14034
14365
  "src/agents/opencode.ts"() {
14035
14366
  "use strict";
14036
- import_node_fs39 = require("fs");
14367
+ import_node_fs40 = require("fs");
14037
14368
  init_run();
14038
14369
  init_app_settings();
14039
14370
  init_error_detail();
@@ -14059,7 +14390,7 @@ var init_opencode = __esm({
14059
14390
  async detect() {
14060
14391
  const opencode = resolveAgentExecutable("opencode");
14061
14392
  if (opencode !== "opencode") {
14062
- if (!(0, import_node_fs39.existsSync)(opencode)) {
14393
+ if (!(0, import_node_fs40.existsSync)(opencode)) {
14063
14394
  return {
14064
14395
  agent: "opencode",
14065
14396
  installed: false,
@@ -14150,7 +14481,7 @@ var init_opencode = __esm({
14150
14481
  const name = part?.tool ?? part?.name ?? obj.tool ?? obj.name ?? "tool";
14151
14482
  const state = part?.state;
14152
14483
  const input = (state?.input && typeof state.input === "object" ? state.input : void 0) ?? part?.input ?? obj.input;
14153
- const metadata = asRecord4(state?.metadata);
14484
+ const metadata = asRecord5(state?.metadata);
14154
14485
  const id = opencodeToolId(
14155
14486
  name,
14156
14487
  part?.callID ?? part?.id ?? obj.id,
@@ -14185,7 +14516,7 @@ var init_opencode = __esm({
14185
14516
  }
14186
14517
  if (obj.type === "subtask_event") {
14187
14518
  const parentId = str3(obj.childSessionID) ?? str3(obj.childSessionId);
14188
- const part = asRecord4(obj.part);
14519
+ const part = asRecord5(obj.part);
14189
14520
  if (!parentId || !part) return null;
14190
14521
  if (part.type === "text" && str3(part.text)) {
14191
14522
  return withTaskParent(
@@ -14196,8 +14527,8 @@ var init_opencode = __esm({
14196
14527
  if (part.type === "tool" || str3(part.tool)) {
14197
14528
  const name = str3(part.tool) ?? str3(part.name) ?? "tool";
14198
14529
  const id = str3(part.callID) ?? str3(part.id) ?? `${parentId}-${name}`;
14199
- const state = asRecord4(part.state);
14200
- const input = asRecord4(state?.input) ?? asRecord4(part.input);
14530
+ const state = asRecord5(part.state);
14531
+ const input = asRecord5(state?.input) ?? asRecord5(part.input);
14201
14532
  const nested = [
14202
14533
  withEventParentId({ type: "tool_use", id, name, input }, parentId)
14203
14534
  ];
@@ -14452,12 +14783,12 @@ function parseSessionQuotaResetAt(text7, now = /* @__PURE__ */ new Date()) {
14452
14783
  }
14453
14784
  return at;
14454
14785
  }
14455
- const relative = text7.match(
14786
+ const relative2 = text7.match(
14456
14787
  /resets\s+in\s+(\d+)\s*(minutes?|hours?|days?)/i
14457
14788
  );
14458
- if (relative) {
14459
- const n = Number(relative[1]);
14460
- const unit = relative[2].toLowerCase();
14789
+ if (relative2) {
14790
+ const n = Number(relative2[1]);
14791
+ const unit = relative2[2].toLowerCase();
14461
14792
  const ms = unit.startsWith("day") ? n * 24 * 60 * 60 * 1e3 : unit.startsWith("hour") ? n * 60 * 60 * 1e3 : n * 60 * 1e3;
14462
14793
  return new Date(now.getTime() + ms);
14463
14794
  }
@@ -14534,13 +14865,13 @@ var init_claude_usage = __esm({
14534
14865
  });
14535
14866
 
14536
14867
  // src/agents/claude-usage-client.ts
14537
- var import_node_fs40, import_node_os15, import_node_path40, CLAUDE_USAGE_ERROR_TTL_MS, CLAUDE_USAGE_STALE_OK_MS;
14868
+ var import_node_fs41, import_node_os17, import_node_path41, CLAUDE_USAGE_ERROR_TTL_MS, CLAUDE_USAGE_STALE_OK_MS;
14538
14869
  var init_claude_usage_client = __esm({
14539
14870
  "src/agents/claude-usage-client.ts"() {
14540
14871
  "use strict";
14541
- import_node_fs40 = require("fs");
14542
- import_node_os15 = require("os");
14543
- import_node_path40 = require("path");
14872
+ import_node_fs41 = require("fs");
14873
+ import_node_os17 = require("os");
14874
+ import_node_path41 = require("path");
14544
14875
  init_run();
14545
14876
  init_fetch();
14546
14877
  init_app_settings();
@@ -14652,11 +14983,11 @@ async function installNpmGlobalPackage(opts) {
14652
14983
  message: !opts.cliBin ? `Installed ${opts.npmPackage}` : binPath ? `Installed ${opts.npmPackage} \u2192 ${binPath}` : `Installed ${opts.npmPackage} (CLI not yet on PATH)`
14653
14984
  };
14654
14985
  }
14655
- var import_node_fs41;
14986
+ var import_node_fs42;
14656
14987
  var init_install = __esm({
14657
14988
  "src/agents/install.ts"() {
14658
14989
  "use strict";
14659
- import_node_fs41 = require("fs");
14990
+ import_node_fs42 = require("fs");
14660
14991
  init_run();
14661
14992
  init_app_settings();
14662
14993
  init_path();
@@ -14760,7 +15091,7 @@ function isAgentHostEnvKey(key) {
14760
15091
  }
14761
15092
  function stripHostToolingPath(pathValue) {
14762
15093
  if (!pathValue?.trim()) return "";
14763
- return pathValue.split(import_node_path41.delimiter).filter((part) => part && !HOST_PATH_NOISE.test(part.replace(/\\/g, "/"))).join(import_node_path41.delimiter);
15094
+ return pathValue.split(import_node_path42.delimiter).filter((part) => part && !HOST_PATH_NOISE.test(part.replace(/\\/g, "/"))).join(import_node_path42.delimiter);
14764
15095
  }
14765
15096
  function sanitizeAgentHostEnv(env, cwd) {
14766
15097
  for (const key of Object.keys(env)) {
@@ -14774,11 +15105,11 @@ function sanitizeAgentHostEnv(env, cwd) {
14774
15105
  }
14775
15106
  return env;
14776
15107
  }
14777
- var import_node_path41, DROP_EXACT, DROP_PREFIXES, HOST_PATH_NOISE;
15108
+ var import_node_path42, DROP_EXACT, DROP_PREFIXES, HOST_PATH_NOISE;
14778
15109
  var init_agent_host_env = __esm({
14779
15110
  "src/hook/agent-host-env.ts"() {
14780
15111
  "use strict";
14781
- import_node_path41 = require("path");
15112
+ import_node_path42 = require("path");
14782
15113
  DROP_EXACT = /* @__PURE__ */ new Set([
14783
15114
  "NODE_PATH",
14784
15115
  "NODE_ENV_ELECTRON_VITE",
@@ -14817,15 +15148,15 @@ var init_agent_host_env = __esm({
14817
15148
 
14818
15149
  // src/hook/worktree-pkg-cache.ts
14819
15150
  function worktreePkgCacheRoot(worktreePath) {
14820
- return (0, import_node_path42.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
15151
+ return (0, import_node_path43.join)(worktreePath, WORKTREE_PKG_CACHE_REL);
14821
15152
  }
14822
15153
  function worktreePkgCacheEnv(worktreePath) {
14823
15154
  const root = worktreePkgCacheRoot(worktreePath);
14824
- const store = (0, import_node_path42.join)(root, "pnpm-store");
14825
- const pnpmCache = (0, import_node_path42.join)(root, "pnpm");
14826
- const npmCache = (0, import_node_path42.join)(root, "npm");
14827
- const nodeGyp = (0, import_node_path42.join)(root, "node-gyp");
14828
- const electron = (0, import_node_path42.join)(root, "electron");
15155
+ const store = (0, import_node_path43.join)(root, "pnpm-store");
15156
+ const pnpmCache = (0, import_node_path43.join)(root, "pnpm");
15157
+ const npmCache = (0, import_node_path43.join)(root, "npm");
15158
+ const nodeGyp = (0, import_node_path43.join)(root, "node-gyp");
15159
+ const electron = (0, import_node_path43.join)(root, "electron");
14829
15160
  return {
14830
15161
  npm_config_store_dir: store,
14831
15162
  PNPM_STORE_DIR: store,
@@ -14847,8 +15178,8 @@ function fillGroup(env, keys, values) {
14847
15178
  }
14848
15179
  }
14849
15180
  function ensureWorktreePkgCacheDirs(worktreePath) {
14850
- if (!(0, import_node_fs42.existsSync)(worktreePath)) return;
14851
- (0, import_node_fs42.mkdirSync)(worktreePkgCacheRoot(worktreePath), { recursive: true });
15181
+ if (!(0, import_node_fs43.existsSync)(worktreePath)) return;
15182
+ (0, import_node_fs43.mkdirSync)(worktreePkgCacheRoot(worktreePath), { recursive: true });
14852
15183
  }
14853
15184
  function applyWorktreePkgCacheEnv(env, worktreePath) {
14854
15185
  const cwd = worktreePath.trim();
@@ -14861,12 +15192,12 @@ function applyWorktreePkgCacheEnv(env, worktreePath) {
14861
15192
  fillGroup(env, ["electron_config_cache"], next);
14862
15193
  ensureWorktreePkgCacheDirs(cwd);
14863
15194
  }
14864
- var import_node_fs42, import_node_path42, WORKTREE_PKG_CACHE_REL;
15195
+ var import_node_fs43, import_node_path43, WORKTREE_PKG_CACHE_REL;
14865
15196
  var init_worktree_pkg_cache = __esm({
14866
15197
  "src/hook/worktree-pkg-cache.ts"() {
14867
15198
  "use strict";
14868
- import_node_fs42 = require("fs");
14869
- import_node_path42 = require("path");
15199
+ import_node_fs43 = require("fs");
15200
+ import_node_path43 = require("path");
14870
15201
  WORKTREE_PKG_CACHE_REL = ".context/.sideboard/pkg-cache";
14871
15202
  }
14872
15203
  });
@@ -16229,21 +16560,21 @@ function shouldRefreshReviewRequestTemplate(content) {
16229
16560
  return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
16230
16561
  }
16231
16562
  function readTextIfPresent(abs) {
16232
- if (!(0, import_node_fs43.existsSync)(abs)) return null;
16563
+ if (!(0, import_node_fs44.existsSync)(abs)) return null;
16233
16564
  try {
16234
- const content = (0, import_node_fs43.readFileSync)(abs, "utf8");
16565
+ const content = (0, import_node_fs44.readFileSync)(abs, "utf8");
16235
16566
  return content.trim() ? content : null;
16236
16567
  } catch {
16237
16568
  return null;
16238
16569
  }
16239
16570
  }
16240
16571
  function readLocalGuidelines(worktreePath) {
16241
- const localAbs = (0, import_node_path43.join)(worktreePath, REVIEW_REQUEST_PATH);
16572
+ const localAbs = (0, import_node_path44.join)(worktreePath, REVIEW_REQUEST_PATH);
16242
16573
  const localContent = readTextIfPresent(localAbs);
16243
16574
  if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
16244
16575
  return { path: REVIEW_REQUEST_PATH, content: localContent };
16245
16576
  }
16246
- const legacyAbs = (0, import_node_path43.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
16577
+ const legacyAbs = (0, import_node_path44.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
16247
16578
  const legacyContent = readTextIfPresent(legacyAbs);
16248
16579
  if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
16249
16580
  return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
@@ -16267,27 +16598,27 @@ function contextGuidelines(content, source) {
16267
16598
  };
16268
16599
  }
16269
16600
  function writeContextGuidelines(worktreePath, content) {
16270
- const abs = (0, import_node_path43.join)(worktreePath, CONTEXT_REVIEW_PATH);
16271
- (0, import_node_fs43.mkdirSync)((0, import_node_path43.dirname)(abs), { recursive: true });
16601
+ const abs = (0, import_node_path44.join)(worktreePath, CONTEXT_REVIEW_PATH);
16602
+ (0, import_node_fs44.mkdirSync)((0, import_node_path44.dirname)(abs), { recursive: true });
16272
16603
  const body = content.endsWith("\n") ? content : `${content}
16273
16604
  `;
16274
- (0, import_node_fs43.writeFileSync)(abs, body, "utf8");
16605
+ (0, import_node_fs44.writeFileSync)(abs, body, "utf8");
16275
16606
  return body;
16276
16607
  }
16277
16608
  function readSideboardReview(worktreePath, repoPath) {
16278
- const fromWorktree = readTextIfPresent((0, import_node_path43.join)(worktreePath, REPO_REVIEW_PATH));
16609
+ const fromWorktree = readTextIfPresent((0, import_node_path44.join)(worktreePath, REPO_REVIEW_PATH));
16279
16610
  if (fromWorktree) return fromWorktree;
16280
16611
  const repo = repoPath?.replace(/\/+$/, "");
16281
16612
  const wt = worktreePath.replace(/\/+$/, "");
16282
16613
  if (!repo || repo === wt) return null;
16283
- return readTextIfPresent((0, import_node_path43.join)(repo, REPO_REVIEW_PATH));
16614
+ return readTextIfPresent((0, import_node_path44.join)(repo, REPO_REVIEW_PATH));
16284
16615
  }
16285
16616
  function ensureReviewGuidelinesFile(worktreePath, repoPath) {
16286
- const skillContent = readTextIfPresent((0, import_node_path43.join)(worktreePath, REVIEW_SKILL_PATH));
16617
+ const skillContent = readTextIfPresent((0, import_node_path44.join)(worktreePath, REVIEW_SKILL_PATH));
16287
16618
  if (skillContent) {
16288
16619
  return { ...skillGuidelines(skillContent, "skill"), wrote: false };
16289
16620
  }
16290
- const contextContent = readTextIfPresent((0, import_node_path43.join)(worktreePath, CONTEXT_REVIEW_PATH));
16621
+ const contextContent = readTextIfPresent((0, import_node_path44.join)(worktreePath, CONTEXT_REVIEW_PATH));
16291
16622
  if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
16292
16623
  return { ...contextGuidelines(contextContent, "local"), wrote: false };
16293
16624
  }
@@ -16363,13 +16694,13 @@ async function requestReview(threadRef, send) {
16363
16694
  const started = await send(tab.id, REVIEW_REQUEST_PREFILL);
16364
16695
  return { tab: started, from };
16365
16696
  }
16366
- var import_node_crypto7, import_node_fs43, import_node_path43, REPO_REVIEW_PATH, REPO_REVIEW_NAME, CONTEXT_REVIEW_PATH, REVIEW_REQUEST_PATH, LEGACY_REVIEW_REQUEST_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PREFILL, LEGACY_REVIEW_TEMPLATE_MARKERS;
16697
+ var import_node_crypto7, import_node_fs44, import_node_path44, REPO_REVIEW_PATH, REPO_REVIEW_NAME, CONTEXT_REVIEW_PATH, REVIEW_REQUEST_PATH, LEGACY_REVIEW_REQUEST_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PREFILL, LEGACY_REVIEW_TEMPLATE_MARKERS;
16367
16698
  var init_request_review = __esm({
16368
16699
  "src/review/request-review.ts"() {
16369
16700
  "use strict";
16370
16701
  import_node_crypto7 = require("crypto");
16371
- import_node_fs43 = require("fs");
16372
- import_node_path43 = require("path");
16702
+ import_node_fs44 = require("fs");
16703
+ import_node_path44 = require("path");
16373
16704
  init_global_workspace();
16374
16705
  init_chat_tabs();
16375
16706
  init_thread_store();
@@ -16392,7 +16723,7 @@ var init_request_review = __esm({
16392
16723
 
16393
16724
  // src/hook/worktree-run-ports.ts
16394
16725
  function worktreeRunPortsPath(worktreePath) {
16395
- return (0, import_node_path44.join)(worktreePath, RUN_PORTS_REL);
16726
+ return (0, import_node_path45.join)(worktreePath, RUN_PORTS_REL);
16396
16727
  }
16397
16728
  function isPort(value) {
16398
16729
  return typeof value === "number" && Number.isInteger(value) && value > 0 && value <= 65535;
@@ -16417,7 +16748,7 @@ function parseFile(raw) {
16417
16748
  function readScripts(worktreePath) {
16418
16749
  if (!worktreePath.trim()) return {};
16419
16750
  try {
16420
- const raw = (0, import_node_fs44.readFileSync)(worktreeRunPortsPath(worktreePath), "utf8");
16751
+ const raw = (0, import_node_fs45.readFileSync)(worktreeRunPortsPath(worktreePath), "utf8");
16421
16752
  return parseFile(raw).scripts ?? {};
16422
16753
  } catch {
16423
16754
  return {};
@@ -16444,22 +16775,22 @@ function saveWorktreeRunPorts(worktreePath, scriptName, ports) {
16444
16775
  const path = worktreeRunPortsPath(worktreePath);
16445
16776
  let current = {};
16446
16777
  try {
16447
- current = parseFile((0, import_node_fs44.readFileSync)(path, "utf8"));
16778
+ current = parseFile((0, import_node_fs45.readFileSync)(path, "utf8"));
16448
16779
  } catch {
16449
16780
  current = {};
16450
16781
  }
16451
16782
  const scripts = { ...current.scripts ?? {} };
16452
16783
  scripts[scriptName] = cleaned;
16453
- (0, import_node_fs44.mkdirSync)((0, import_node_path44.dirname)(path), { recursive: true });
16454
- (0, import_node_fs44.writeFileSync)(path, `${JSON.stringify({ scripts }, null, 2)}
16784
+ (0, import_node_fs45.mkdirSync)((0, import_node_path45.dirname)(path), { recursive: true });
16785
+ (0, import_node_fs45.writeFileSync)(path, `${JSON.stringify({ scripts }, null, 2)}
16455
16786
  `, "utf8");
16456
16787
  }
16457
- var import_node_fs44, import_node_path44, RUN_PORTS_REL;
16788
+ var import_node_fs45, import_node_path45, RUN_PORTS_REL;
16458
16789
  var init_worktree_run_ports = __esm({
16459
16790
  "src/hook/worktree-run-ports.ts"() {
16460
16791
  "use strict";
16461
- import_node_fs44 = require("fs");
16462
- import_node_path44 = require("path");
16792
+ import_node_fs45 = require("fs");
16793
+ import_node_path45 = require("path");
16463
16794
  RUN_PORTS_REL = ".context/.sideboard/run-ports.json";
16464
16795
  }
16465
16796
  });
@@ -16506,24 +16837,24 @@ function sanitizeDetachedJobId(id) {
16506
16837
  return s;
16507
16838
  }
16508
16839
  function readIntFile(file) {
16509
- if (!(0, import_node_fs45.existsSync)(file)) return null;
16510
- const n = Number.parseInt((0, import_node_fs45.readFileSync)(file, "utf8").trim(), 10);
16840
+ if (!(0, import_node_fs46.existsSync)(file)) return null;
16841
+ const n = Number.parseInt((0, import_node_fs46.readFileSync)(file, "utf8").trim(), 10);
16511
16842
  return Number.isInteger(n) ? n : null;
16512
16843
  }
16513
16844
  function jobDir(root, id, legacy = false) {
16514
- return (0, import_node_path45.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
16845
+ return (0, import_node_path46.join)(root, legacy ? LEGACY_DETACHED_JOBS_DIR : DETACHED_JOBS_DIR, id);
16515
16846
  }
16516
16847
  function resolveJobDir(root, id) {
16517
16848
  const modern = jobDir(root, id, false);
16518
- if ((0, import_node_fs45.existsSync)(modern)) return modern;
16849
+ if ((0, import_node_fs46.existsSync)(modern)) return modern;
16519
16850
  const legacy = jobDir(root, id, true);
16520
- if ((0, import_node_fs45.existsSync)(legacy)) return legacy;
16851
+ if ((0, import_node_fs46.existsSync)(legacy)) return legacy;
16521
16852
  return modern;
16522
16853
  }
16523
16854
  function listJobIdsIn(root, rel) {
16524
- const dir = (0, import_node_path45.join)(root, rel);
16525
- if (!(0, import_node_fs45.existsSync)(dir)) return [];
16526
- return (0, import_node_fs45.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
16855
+ const dir = (0, import_node_path46.join)(root, rel);
16856
+ if (!(0, import_node_fs46.existsSync)(dir)) return [];
16857
+ return (0, import_node_fs46.readdirSync)(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && JOB_ID_RE.test(e.name)).map((e) => e.name);
16527
16858
  }
16528
16859
  function listRunningDetachedJobs(worktreePath) {
16529
16860
  const root = worktreePath.trim();
@@ -16535,7 +16866,7 @@ function listRunningDetachedJobs(worktreePath) {
16535
16866
  const running = [];
16536
16867
  for (const id of ids) {
16537
16868
  const dir = resolveJobDir(root, id);
16538
- const pid = readIntFile((0, import_node_path45.join)(dir, "pid"));
16869
+ const pid = readIntFile((0, import_node_path46.join)(dir, "pid"));
16539
16870
  if (jobTreeAlive(pid)) running.push(id);
16540
16871
  }
16541
16872
  return running.sort();
@@ -16621,8 +16952,8 @@ function planJobContinue(opts) {
16621
16952
  return { action: "none" };
16622
16953
  }
16623
16954
  function tailProgress(logFile, maxLines = 12) {
16624
- if (!(0, import_node_fs45.existsSync)(logFile)) return "(no log yet)";
16625
- const lines = (0, import_node_fs45.readFileSync)(logFile, "utf8").split("\n");
16955
+ if (!(0, import_node_fs46.existsSync)(logFile)) return "(no log yet)";
16956
+ const lines = (0, import_node_fs46.readFileSync)(logFile, "utf8").split("\n");
16626
16957
  return lines.slice(-maxLines).join("\n");
16627
16958
  }
16628
16959
  function lastProgressLine(progress) {
@@ -16630,8 +16961,8 @@ function lastProgressLine(progress) {
16630
16961
  return last ? last.slice(0, 72) : void 0;
16631
16962
  }
16632
16963
  function readLogLines(file) {
16633
- if (!(0, import_node_fs45.existsSync)(file)) return [];
16634
- const lines = (0, import_node_fs45.readFileSync)(file, "utf8").split("\n");
16964
+ if (!(0, import_node_fs46.existsSync)(file)) return [];
16965
+ const lines = (0, import_node_fs46.readFileSync)(file, "utf8").split("\n");
16635
16966
  if (lines.length && lines[lines.length - 1] === "") lines.pop();
16636
16967
  return lines;
16637
16968
  }
@@ -16642,15 +16973,15 @@ function takeDelta(logFile, cursorFile) {
16642
16973
  return { delta: capJobLogDelta(lines.slice(start).join("\n")), nextCursor: lines.length };
16643
16974
  }
16644
16975
  function snapshotJob(dir) {
16645
- const pid = readIntFile((0, import_node_path45.join)(dir, "pid"));
16976
+ const pid = readIntFile((0, import_node_path46.join)(dir, "pid"));
16646
16977
  const running = jobTreeAlive(pid);
16647
16978
  return {
16648
16979
  pid,
16649
16980
  running,
16650
- exitCode: readIntFile((0, import_node_path45.join)(dir, "exit")),
16651
- log: (0, import_node_path45.join)(dir, "log"),
16652
- cursor: (0, import_node_path45.join)(dir, "present.cursor"),
16653
- progress: tailProgress((0, import_node_path45.join)(dir, "log"))
16981
+ exitCode: readIntFile((0, import_node_path46.join)(dir, "exit")),
16982
+ log: (0, import_node_path46.join)(dir, "log"),
16983
+ cursor: (0, import_node_path46.join)(dir, "present.cursor"),
16984
+ progress: tailProgress((0, import_node_path46.join)(dir, "log"))
16654
16985
  };
16655
16986
  }
16656
16987
  function toResult(id, snap, extra) {
@@ -16659,8 +16990,8 @@ function toResult(id, snap, extra) {
16659
16990
  const stillRunning = snap.running && !ok;
16660
16991
  const { delta, nextCursor } = takeDelta(snap.log, snap.cursor);
16661
16992
  try {
16662
- (0, import_node_fs45.mkdirSync)((0, import_node_path45.dirname)(snap.cursor), { recursive: true });
16663
- (0, import_node_fs45.writeFileSync)(snap.cursor, `${nextCursor}
16993
+ (0, import_node_fs46.mkdirSync)((0, import_node_path46.dirname)(snap.cursor), { recursive: true });
16994
+ (0, import_node_fs46.writeFileSync)(snap.cursor, `${nextCursor}
16664
16995
  `);
16665
16996
  } catch {
16666
16997
  }
@@ -16681,7 +17012,7 @@ function toResult(id, snap, extra) {
16681
17012
  };
16682
17013
  }
16683
17014
  async function sleepMs(ms) {
16684
- await new Promise((resolve2) => setTimeout(resolve2, ms));
17015
+ await new Promise((resolve3) => setTimeout(resolve3, ms));
16685
17016
  }
16686
17017
  async function waitForDetachedJob(cwd, id, opts) {
16687
17018
  const jobId = sanitizeDetachedJobId(id);
@@ -16689,7 +17020,7 @@ async function waitForDetachedJob(cwd, id, opts) {
16689
17020
  const dir = resolveJobDir(root, jobId);
16690
17021
  const timeoutMs = mcpWaitForJobTimeoutMs(opts?.timeoutMs);
16691
17022
  const sleep = opts?.sleep ?? sleepMs;
16692
- if (!(0, import_node_fs45.existsSync)(dir)) {
17023
+ if (!(0, import_node_fs46.existsSync)(dir)) {
16693
17024
  return {
16694
17025
  stillRunning: false,
16695
17026
  ok: false,
@@ -16735,10 +17066,10 @@ function killProcessTree(pid, signal) {
16735
17066
  }
16736
17067
  function appendJobLog(logFile, line) {
16737
17068
  try {
16738
- (0, import_node_fs45.mkdirSync)((0, import_node_path45.dirname)(logFile), { recursive: true });
17069
+ (0, import_node_fs46.mkdirSync)((0, import_node_path46.dirname)(logFile), { recursive: true });
16739
17070
  const body = line.endsWith("\n") ? line : `${line}
16740
17071
  `;
16741
- (0, import_node_fs45.appendFileSync)(logFile, body);
17072
+ (0, import_node_fs46.appendFileSync)(logFile, body);
16742
17073
  } catch {
16743
17074
  }
16744
17075
  }
@@ -16748,7 +17079,7 @@ async function stopDetachedJob(cwd, id, opts) {
16748
17079
  const dir = resolveJobDir(root, jobId);
16749
17080
  const sleep = opts?.sleep ?? sleepMs;
16750
17081
  const why = opts?.reason?.trim() ?? "";
16751
- if (!(0, import_node_fs45.existsSync)(dir)) {
17082
+ if (!(0, import_node_fs46.existsSync)(dir)) {
16752
17083
  return {
16753
17084
  stillRunning: false,
16754
17085
  ok: false,
@@ -16784,10 +17115,10 @@ async function stopDetachedJob(cwd, id, opts) {
16784
17115
  killProcessTree(targetPid, "SIGKILL");
16785
17116
  await sleep(100);
16786
17117
  }
16787
- const exitFile = (0, import_node_path45.join)(dir, "exit");
16788
- if (!(0, import_node_fs45.existsSync)(exitFile)) {
17118
+ const exitFile = (0, import_node_path46.join)(dir, "exit");
17119
+ if (!(0, import_node_fs46.existsSync)(exitFile)) {
16789
17120
  try {
16790
- (0, import_node_fs45.writeFileSync)(exitFile, "1\n");
17121
+ (0, import_node_fs46.writeFileSync)(exitFile, "1\n");
16791
17122
  } catch {
16792
17123
  }
16793
17124
  }
@@ -16807,12 +17138,12 @@ async function stopDetachedJob(cwd, id, opts) {
16807
17138
  hint: stopped ? MCP_STOP_JOB_HINT : MCP_WAIT_JOB_STILL_RUNNING_HINT
16808
17139
  };
16809
17140
  }
16810
- var import_node_fs45, import_node_path45, 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;
17141
+ var import_node_fs46, import_node_path46, 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;
16811
17142
  var init_wait_for_job = __esm({
16812
17143
  "src/mcp/wait-for-job.ts"() {
16813
17144
  "use strict";
16814
- import_node_fs45 = require("fs");
16815
- import_node_path45 = require("path");
17145
+ import_node_fs46 = require("fs");
17146
+ import_node_path46 = require("path");
16816
17147
  init_workspace_scratch();
16817
17148
  init_job_process();
16818
17149
  init_wait_for_turn();
@@ -16834,7 +17165,7 @@ async function killReclaimable(ports, worktreePath, signal) {
16834
17165
  else killListenersOnPorts2(ports);
16835
17166
  }
16836
17167
  async function reservePort() {
16837
- return new Promise((resolve2, reject) => {
17168
+ return new Promise((resolve3, reject) => {
16838
17169
  const server = (0, import_node_net.createServer)();
16839
17170
  let released = false;
16840
17171
  const release = () => new Promise((res) => {
@@ -16851,7 +17182,7 @@ async function reservePort() {
16851
17182
  void release().then(() => reject(new Error("Failed to allocate port")));
16852
17183
  return;
16853
17184
  }
16854
- resolve2({ port: addr.port, release });
17185
+ resolve3({ port: addr.port, release });
16855
17186
  });
16856
17187
  server.on("error", reject);
16857
17188
  });
@@ -16863,7 +17194,7 @@ async function allocatePort() {
16863
17194
  }
16864
17195
  async function tryReservePort(port) {
16865
17196
  if (!Number.isInteger(port) || port <= 0 || port > 65535) return null;
16866
- return new Promise((resolve2) => {
17197
+ return new Promise((resolve3) => {
16867
17198
  const server = (0, import_node_net.createServer)();
16868
17199
  let released = false;
16869
17200
  const release = () => new Promise((res) => {
@@ -16879,10 +17210,10 @@ async function tryReservePort(port) {
16879
17210
  server.close();
16880
17211
  } catch {
16881
17212
  }
16882
- resolve2(null);
17213
+ resolve3(null);
16883
17214
  });
16884
17215
  server.listen(port, "127.0.0.1", () => {
16885
- resolve2({ port, release });
17216
+ resolve3({ port, release });
16886
17217
  });
16887
17218
  });
16888
17219
  }
@@ -16911,7 +17242,7 @@ function normalizePreferredPorts(ports, size) {
16911
17242
  return out;
16912
17243
  }
16913
17244
  function delay(ms) {
16914
- return new Promise((resolve2) => setTimeout(resolve2, ms));
17245
+ return new Promise((resolve3) => setTimeout(resolve3, ms));
16915
17246
  }
16916
17247
  function portSet(ports) {
16917
17248
  const out = /* @__PURE__ */ new Set();
@@ -17059,6 +17390,7 @@ __export(conductor_exports, {
17059
17390
  killListenersOnPorts: () => killListenersOnPorts,
17060
17391
  killStaleWorktreeListeners: () => killStaleWorktreeListeners,
17061
17392
  killableListenerPids: () => killableListenerPids,
17393
+ linkSharedDirectories: () => linkSharedDirectories,
17062
17394
  listRunScripts: () => listRunScripts,
17063
17395
  listenerCwd: () => listenerCwd,
17064
17396
  loadConductorSettings: () => loadConductorSettings,
@@ -17087,9 +17419,9 @@ function matchSimpleGlob(pattern, name) {
17087
17419
  return new RegExp(`^${escaped}$`).test(name);
17088
17420
  }
17089
17421
  function readWorktreeInclude(repoPath) {
17090
- const path = (0, import_node_path46.join)(repoPath, ".worktreeinclude");
17091
- if (!(0, import_node_fs46.existsSync)(path)) return [];
17092
- return (0, import_node_fs46.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
17422
+ const path = (0, import_node_path47.join)(repoPath, ".worktreeinclude");
17423
+ if (!(0, import_node_fs47.existsSync)(path)) return [];
17424
+ return (0, import_node_fs47.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
17093
17425
  }
17094
17426
  function resolveFilesToCopy(repoPath) {
17095
17427
  const fromInclude = readWorktreeInclude(repoPath);
@@ -17099,10 +17431,10 @@ function resolveFilesToCopy(repoPath) {
17099
17431
  if (settings?.fileIncludeGlobs?.length) {
17100
17432
  const matched = [];
17101
17433
  try {
17102
- for (const entry of (0, import_node_fs46.readdirSync)(repoPath, { withFileTypes: true })) {
17434
+ for (const entry of (0, import_node_fs47.readdirSync)(repoPath, { withFileTypes: true })) {
17103
17435
  if (!entry.isFile()) continue;
17104
17436
  for (const glob of settings.fileIncludeGlobs) {
17105
- if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path46.basename)(glob), entry.name)) {
17437
+ if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path47.basename)(glob), entry.name)) {
17106
17438
  matched.push(entry.name);
17107
17439
  break;
17108
17440
  }
@@ -17114,7 +17446,7 @@ function resolveFilesToCopy(repoPath) {
17114
17446
  }
17115
17447
  const defaults = [];
17116
17448
  try {
17117
- for (const entry of (0, import_node_fs46.readdirSync)(repoPath, { withFileTypes: true })) {
17449
+ for (const entry of (0, import_node_fs47.readdirSync)(repoPath, { withFileTypes: true })) {
17118
17450
  if (entry.isFile() && entry.name.startsWith(".env")) {
17119
17451
  defaults.push(entry.name);
17120
17452
  }
@@ -17128,15 +17460,63 @@ function copyConfiguredFiles(repoPath, worktreePath) {
17128
17460
  const patterns = resolveFilesToCopy(repoPath);
17129
17461
  const copied = [];
17130
17462
  for (const rel of patterns) {
17131
- const src = (0, import_node_path46.join)(repoPath, rel);
17132
- if (!(0, import_node_fs46.existsSync)(src)) continue;
17133
- const dest = (0, import_node_path46.join)(worktreePath, rel);
17134
- (0, import_node_fs46.mkdirSync)((0, import_node_path46.dirname)(dest), { recursive: true });
17135
- (0, import_node_fs46.copyFileSync)(src, dest);
17463
+ const src = (0, import_node_path47.join)(repoPath, rel);
17464
+ if (!(0, import_node_fs47.existsSync)(src)) continue;
17465
+ const dest = (0, import_node_path47.join)(worktreePath, rel);
17466
+ (0, import_node_fs47.mkdirSync)((0, import_node_path47.dirname)(dest), { recursive: true });
17467
+ (0, import_node_fs47.copyFileSync)(src, dest);
17136
17468
  copied.push(rel);
17137
17469
  }
17470
+ linkSharedDirectories(repoPath, worktreePath);
17138
17471
  return copied;
17139
17472
  }
17473
+ function linkSharedDirectories(repoPath, worktreePath) {
17474
+ const dirs = loadRepoSettings(repoPath)?.sharedDirectories ?? [];
17475
+ if (!dirs.length || samePath(repoPath, worktreePath)) return [];
17476
+ const linked = [];
17477
+ for (const rel of dirs) {
17478
+ if (!isSafeRelativeDir(rel)) continue;
17479
+ if (!isGitignored(repoPath, rel)) continue;
17480
+ const src = (0, import_node_path47.join)(repoPath, rel);
17481
+ let srcStat;
17482
+ try {
17483
+ srcStat = (0, import_node_fs47.lstatSync)(src);
17484
+ } catch {
17485
+ continue;
17486
+ }
17487
+ if (!srcStat.isDirectory()) continue;
17488
+ const dest = (0, import_node_path47.join)(worktreePath, rel);
17489
+ if ((0, import_node_fs47.existsSync)(dest)) continue;
17490
+ (0, import_node_fs47.mkdirSync)((0, import_node_path47.dirname)(dest), { recursive: true });
17491
+ try {
17492
+ (0, import_node_fs47.symlinkSync)(src, dest);
17493
+ } catch {
17494
+ continue;
17495
+ }
17496
+ linked.push(rel);
17497
+ }
17498
+ return linked;
17499
+ }
17500
+ function samePath(a, b) {
17501
+ try {
17502
+ return (0, import_node_fs47.realpathSync)(a) === (0, import_node_fs47.realpathSync)(b);
17503
+ } catch {
17504
+ return (0, import_node_path47.resolve)(a) === (0, import_node_path47.resolve)(b);
17505
+ }
17506
+ }
17507
+ function isSafeRelativeDir(rel) {
17508
+ if (!rel || (0, import_node_path47.isAbsolute)(rel)) return false;
17509
+ const parts = rel.split(/[\\/]/).filter(Boolean);
17510
+ return parts.length > 0 && parts.every((part) => part !== "." && part !== "..");
17511
+ }
17512
+ function isGitignored(repoPath, rel) {
17513
+ try {
17514
+ (0, import_node_child_process4.execFileSync)("git", ["-C", repoPath, "check-ignore", "-q", "--", rel], { stdio: "ignore" });
17515
+ return true;
17516
+ } catch {
17517
+ return false;
17518
+ }
17519
+ }
17140
17520
  async function captureLoginEnv() {
17141
17521
  if (cachedLoginEnv) return { ...cachedLoginEnv };
17142
17522
  const shell = process.env.SHELL?.trim() || (process.platform === "darwin" ? "/bin/zsh" : "/bin/bash");
@@ -17167,7 +17547,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
17167
17547
  const env = stripNestedElectronEnv({
17168
17548
  ...baseEnv ?? process.env
17169
17549
  });
17170
- const name = opts.workspaceName ?? (0, import_node_path46.basename)(opts.worktreePath);
17550
+ const name = opts.workspaceName ?? (0, import_node_path47.basename)(opts.worktreePath);
17171
17551
  const ports = opts.ports ?? [];
17172
17552
  const primary = ports[0];
17173
17553
  env.SIDEBOARD_WORKSPACE_NAME = name;
@@ -17236,20 +17616,20 @@ function listenerCwd(pid) {
17236
17616
  }
17237
17617
  function realpathOrResolve(path) {
17238
17618
  try {
17239
- return (0, import_node_fs46.realpathSync)(path);
17619
+ return (0, import_node_fs47.realpathSync)(path);
17240
17620
  } catch {
17241
- return (0, import_node_path46.resolve)(path);
17621
+ return (0, import_node_path47.resolve)(path);
17242
17622
  }
17243
17623
  }
17244
17624
  function isOtherWorktreeListenerCwd(cwd, worktreePath) {
17245
17625
  const wt = realpathOrResolve(worktreePath);
17246
17626
  const c = realpathOrResolve(cwd);
17247
- if (c === wt || c.startsWith(wt + import_node_path46.sep)) return false;
17248
- const parent = (0, import_node_path46.dirname)(wt);
17249
- const thisName = (0, import_node_path46.basename)(wt);
17627
+ if (c === wt || c.startsWith(wt + import_node_path47.sep)) return false;
17628
+ const parent = (0, import_node_path47.dirname)(wt);
17629
+ const thisName = (0, import_node_path47.basename)(wt);
17250
17630
  if (!thisName || c === parent) return false;
17251
- if (!c.startsWith(parent + import_node_path46.sep)) return false;
17252
- const first = c.slice(parent.length + 1).split(import_node_path46.sep)[0];
17631
+ if (!c.startsWith(parent + import_node_path47.sep)) return false;
17632
+ const first = c.slice(parent.length + 1).split(import_node_path47.sep)[0];
17253
17633
  return Boolean(first) && first !== thisName;
17254
17634
  }
17255
17635
  function signalPid(pid, signal) {
@@ -17261,7 +17641,7 @@ function signalPid(pid, signal) {
17261
17641
  function isThisWorktreeListenerCwd(cwd, worktreePath) {
17262
17642
  const wt = realpathOrResolve(worktreePath);
17263
17643
  const c = realpathOrResolve(cwd);
17264
- return c === wt || c.startsWith(wt + import_node_path46.sep);
17644
+ return c === wt || c.startsWith(wt + import_node_path47.sep);
17265
17645
  }
17266
17646
  function killDetachedRunTree(pid, worktreePath) {
17267
17647
  if (!Number.isFinite(pid) || pid <= 1 || pid === process.pid) return;
@@ -17513,13 +17893,13 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
17513
17893
  throw err;
17514
17894
  }
17515
17895
  }
17516
- var import_node_fs46, import_node_child_process4, import_node_path46, import_execa4, import_node_readline3, cachedLoginEnv;
17896
+ var import_node_fs47, import_node_child_process4, import_node_path47, import_execa4, import_node_readline3, cachedLoginEnv;
17517
17897
  var init_conductor = __esm({
17518
17898
  "src/hook/conductor.ts"() {
17519
17899
  "use strict";
17520
- import_node_fs46 = require("fs");
17900
+ import_node_fs47 = require("fs");
17521
17901
  import_node_child_process4 = require("child_process");
17522
- import_node_path46 = require("path");
17902
+ import_node_path47 = require("path");
17523
17903
  import_execa4 = require("execa");
17524
17904
  import_node_readline3 = require("readline");
17525
17905
  init_settings();
@@ -17572,7 +17952,7 @@ function materialize(mem) {
17572
17952
  };
17573
17953
  }
17574
17954
  function setupLogPath(threadId) {
17575
- return (0, import_node_path47.join)(threadsDir(), `${threadId}.setup.log.json`);
17955
+ return (0, import_node_path48.join)(threadsDir(), `${threadId}.setup.log.json`);
17576
17956
  }
17577
17957
  function setupLogKeyForWorktree(worktreePath) {
17578
17958
  const norm = normalizeWorktreePath(worktreePath);
@@ -17590,7 +17970,7 @@ function persistNow(threadId) {
17590
17970
  const mem = memory.get(threadId);
17591
17971
  if (!mem) return;
17592
17972
  try {
17593
- (0, import_node_fs47.writeFileSync)(
17973
+ (0, import_node_fs48.writeFileSync)(
17594
17974
  setupLogPath(threadId),
17595
17975
  `${JSON.stringify(materialize(mem))}
17596
17976
  `,
@@ -17611,9 +17991,9 @@ function schedulePersist(threadId) {
17611
17991
  }
17612
17992
  function loadFromDisk(threadId) {
17613
17993
  const path = setupLogPath(threadId);
17614
- if (!(0, import_node_fs47.existsSync)(path)) return null;
17994
+ if (!(0, import_node_fs48.existsSync)(path)) return null;
17615
17995
  try {
17616
- const raw = JSON.parse((0, import_node_fs47.readFileSync)(path, "utf8"));
17996
+ const raw = JSON.parse((0, import_node_fs48.readFileSync)(path, "utf8"));
17617
17997
  return {
17618
17998
  output: typeof raw.output === "string" ? raw.output : "",
17619
17999
  running: Boolean(raw.running),
@@ -17669,13 +18049,13 @@ function finishSetupLog(threadId, exitCode, source) {
17669
18049
  persistNow(threadId);
17670
18050
  return materialize(mem);
17671
18051
  }
17672
- var import_node_crypto8, import_node_fs47, import_node_path47, EMPTY, MAX_SETUP_LOG_CHARS, memory, persistTimers, PERSIST_DEBOUNCE_MS;
18052
+ var import_node_crypto8, import_node_fs48, import_node_path48, EMPTY, MAX_SETUP_LOG_CHARS, memory, persistTimers, PERSIST_DEBOUNCE_MS;
17673
18053
  var init_setup_log = __esm({
17674
18054
  "src/store/setup-log.ts"() {
17675
18055
  "use strict";
17676
18056
  import_node_crypto8 = require("crypto");
17677
- import_node_fs47 = require("fs");
17678
- import_node_path47 = require("path");
18057
+ import_node_fs48 = require("fs");
18058
+ import_node_path48 = require("path");
17679
18059
  init_worktree_labels();
17680
18060
  init_paths();
17681
18061
  EMPTY = {
@@ -17720,7 +18100,7 @@ function safeScriptToken(scriptName) {
17720
18100
  return token || "dev";
17721
18101
  }
17722
18102
  function runLogPath(key) {
17723
- return (0, import_node_path48.join)(threadsDir(), `${key}.run.log.json`);
18103
+ return (0, import_node_path49.join)(threadsDir(), `${key}.run.log.json`);
17724
18104
  }
17725
18105
  function runLogKeyForWorktree(worktreePath, scriptName) {
17726
18106
  const norm = normalizeWorktreePath(worktreePath);
@@ -17748,7 +18128,7 @@ function persistNow2(key) {
17748
18128
  const mem = memory2.get(key);
17749
18129
  if (!mem) return;
17750
18130
  try {
17751
- (0, import_node_fs48.writeFileSync)(runLogPath(key), `${JSON.stringify(materialize2(mem))}
18131
+ (0, import_node_fs49.writeFileSync)(runLogPath(key), `${JSON.stringify(materialize2(mem))}
17752
18132
  `, "utf8");
17753
18133
  } catch {
17754
18134
  }
@@ -17765,9 +18145,9 @@ function schedulePersist2(key) {
17765
18145
  }
17766
18146
  function loadFromDisk2(key) {
17767
18147
  const path = runLogPath(key);
17768
- if (!(0, import_node_fs48.existsSync)(path)) return null;
18148
+ if (!(0, import_node_fs49.existsSync)(path)) return null;
17769
18149
  try {
17770
- const raw = JSON.parse((0, import_node_fs48.readFileSync)(path, "utf8"));
18150
+ const raw = JSON.parse((0, import_node_fs49.readFileSync)(path, "utf8"));
17771
18151
  return {
17772
18152
  output: typeof raw.output === "string" ? raw.output : "",
17773
18153
  running: Boolean(raw.running),
@@ -17825,13 +18205,13 @@ function finishRunLog(key, exitCode) {
17825
18205
  function flushRunLog(key) {
17826
18206
  persistNow2(key);
17827
18207
  }
17828
- var import_node_crypto9, import_node_fs48, import_node_path48, EMPTY2, MAX_RUN_LOG_CHARS, DEFAULT_RUN_LOG_TAIL_CHARS, memory2, persistTimers2, PERSIST_DEBOUNCE_MS2;
18208
+ var import_node_crypto9, import_node_fs49, import_node_path49, EMPTY2, MAX_RUN_LOG_CHARS, DEFAULT_RUN_LOG_TAIL_CHARS, memory2, persistTimers2, PERSIST_DEBOUNCE_MS2;
17829
18209
  var init_run_log = __esm({
17830
18210
  "src/store/run-log.ts"() {
17831
18211
  "use strict";
17832
18212
  import_node_crypto9 = require("crypto");
17833
- import_node_fs48 = require("fs");
17834
- import_node_path48 = require("path");
18213
+ import_node_fs49 = require("fs");
18214
+ import_node_path49 = require("path");
17835
18215
  init_worktree_labels();
17836
18216
  init_setup_log();
17837
18217
  init_paths();
@@ -17860,9 +18240,9 @@ async function findOrphanWorktrees(repoPaths) {
17860
18240
  repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
17861
18241
  );
17862
18242
  const homeRoot = sideboardWorkspacesDir();
17863
- if ((0, import_node_fs49.existsSync)(homeRoot)) {
18243
+ if ((0, import_node_fs50.existsSync)(homeRoot)) {
17864
18244
  try {
17865
- for (const entry of (0, import_node_fs49.readdirSync)(homeRoot, { withFileTypes: true })) {
18245
+ for (const entry of (0, import_node_fs50.readdirSync)(homeRoot, { withFileTypes: true })) {
17866
18246
  if (!entry.isDirectory()) continue;
17867
18247
  void entry;
17868
18248
  }
@@ -17872,7 +18252,7 @@ async function findOrphanWorktrees(repoPaths) {
17872
18252
  const orphans = [];
17873
18253
  const seen = /* @__PURE__ */ new Set();
17874
18254
  for (const repoPath of repos) {
17875
- if (!repoPath || !(0, import_node_fs49.existsSync)(repoPath)) continue;
18255
+ if (!repoPath || !(0, import_node_fs50.existsSync)(repoPath)) continue;
17876
18256
  try {
17877
18257
  const wts = await listWorktrees(repoPath);
17878
18258
  for (const wt of wts) {
@@ -17883,7 +18263,7 @@ async function findOrphanWorktrees(repoPaths) {
17883
18263
  seen.add(path);
17884
18264
  let mtimeMs = 0;
17885
18265
  try {
17886
- mtimeMs = (0, import_node_fs49.statSync)(path).mtimeMs;
18266
+ mtimeMs = (0, import_node_fs50.statSync)(path).mtimeMs;
17887
18267
  } catch {
17888
18268
  mtimeMs = 0;
17889
18269
  }
@@ -17893,16 +18273,16 @@ async function findOrphanWorktrees(repoPaths) {
17893
18273
  }
17894
18274
  try {
17895
18275
  const root = worktreesRoot(repoPath);
17896
- if ((0, import_node_fs49.existsSync)(root)) {
17897
- for (const entry of (0, import_node_fs49.readdirSync)(root, { withFileTypes: true })) {
18276
+ if ((0, import_node_fs50.existsSync)(root)) {
18277
+ for (const entry of (0, import_node_fs50.readdirSync)(root, { withFileTypes: true })) {
17898
18278
  if (!entry.isDirectory()) continue;
17899
- const path = (0, import_node_path49.join)(root, entry.name).replace(/\/$/, "");
18279
+ const path = (0, import_node_path50.join)(root, entry.name).replace(/\/$/, "");
17900
18280
  if (known.has(path) || seen.has(path)) continue;
17901
- if (!(0, import_node_fs49.existsSync)((0, import_node_path49.join)(path, ".git"))) continue;
18281
+ if (!(0, import_node_fs50.existsSync)((0, import_node_path50.join)(path, ".git"))) continue;
17902
18282
  seen.add(path);
17903
18283
  let mtimeMs = 0;
17904
18284
  try {
17905
- mtimeMs = (0, import_node_fs49.statSync)(path).mtimeMs;
18285
+ mtimeMs = (0, import_node_fs50.statSync)(path).mtimeMs;
17906
18286
  } catch {
17907
18287
  mtimeMs = Date.now();
17908
18288
  }
@@ -17954,12 +18334,12 @@ function shouldRunWorktreeCleanup(settings = loadAppSettings()) {
17954
18334
  const elapsed = Date.now() - Date.parse(last);
17955
18335
  return elapsed >= intervalHours * 36e5;
17956
18336
  }
17957
- var import_node_fs49, import_node_path49;
18337
+ var import_node_fs50, import_node_path50;
17958
18338
  var init_orphan_cleanup = __esm({
17959
18339
  "src/git/orphan-cleanup.ts"() {
17960
18340
  "use strict";
17961
- import_node_fs49 = require("fs");
17962
- import_node_path49 = require("path");
18341
+ import_node_fs50 = require("fs");
18342
+ import_node_path50 = require("path");
17963
18343
  init_worktree();
17964
18344
  init_thread_store();
17965
18345
  init_paths();
@@ -18135,12 +18515,12 @@ async function cloneRepoIntoSideboard(opts) {
18135
18515
  if (!url) throw new Error("Clone URL is required");
18136
18516
  let name = opts.name?.trim();
18137
18517
  if (!name) {
18138
- const leaf = (0, import_node_path50.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
18518
+ const leaf = (0, import_node_path51.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
18139
18519
  name = leaf || "repo";
18140
18520
  }
18141
18521
  name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
18142
- const dest = (0, import_node_path50.join)(sideboardReposDir(), name);
18143
- if ((0, import_node_fs50.existsSync)(dest)) {
18522
+ const dest = (0, import_node_path51.join)(sideboardReposDir(), name);
18523
+ if ((0, import_node_fs51.existsSync)(dest)) {
18144
18524
  const repoPath2 = await resolveRepoRoot(dest);
18145
18525
  const workspace2 = await addWorkspace(repoPath2);
18146
18526
  return { repoPath: repoPath2, workspace: workspace2 };
@@ -18155,12 +18535,12 @@ async function cloneRepoIntoSideboard(opts) {
18155
18535
  const workspace = await addWorkspace(repoPath);
18156
18536
  return { repoPath, workspace };
18157
18537
  }
18158
- var import_node_fs50, import_node_path50, import_execa6;
18538
+ var import_node_fs51, import_node_path51, import_execa6;
18159
18539
  var init_clone_repo = __esm({
18160
18540
  "src/git/clone-repo.ts"() {
18161
18541
  "use strict";
18162
- import_node_fs50 = require("fs");
18163
- import_node_path50 = require("path");
18542
+ import_node_fs51 = require("fs");
18543
+ import_node_path51 = require("path");
18164
18544
  import_execa6 = require("execa");
18165
18545
  init_paths();
18166
18546
  init_workspaces();
@@ -18180,11 +18560,11 @@ var init_thread = __esm({
18180
18560
 
18181
18561
  // src/store/desktop-host.ts
18182
18562
  function desktopHostPidPath() {
18183
- return (0, import_node_path51.join)(appDataDir(), "desktop-host.pid");
18563
+ return (0, import_node_path52.join)(appDataDir(), "desktop-host.pid");
18184
18564
  }
18185
18565
  function readDesktopHostPid() {
18186
18566
  try {
18187
- const pid = Number.parseInt((0, import_node_fs51.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
18567
+ const pid = Number.parseInt((0, import_node_fs52.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
18188
18568
  if (!Number.isFinite(pid) || pid <= 0) return null;
18189
18569
  return pid;
18190
18570
  } catch {
@@ -18210,12 +18590,12 @@ function thisProcessShouldDrainAgentQueues() {
18210
18590
  if (isThisProcessDesktopHost()) return true;
18211
18591
  return !isDesktopHostAlive();
18212
18592
  }
18213
- var import_node_fs51, import_node_path51;
18593
+ var import_node_fs52, import_node_path52;
18214
18594
  var init_desktop_host = __esm({
18215
18595
  "src/store/desktop-host.ts"() {
18216
18596
  "use strict";
18217
- import_node_fs51 = require("fs");
18218
- import_node_path51 = require("path");
18597
+ import_node_fs52 = require("fs");
18598
+ import_node_path52 = require("path");
18219
18599
  init_paths();
18220
18600
  }
18221
18601
  });
@@ -18240,20 +18620,63 @@ function denyPendingToolPermissions(threadId) {
18240
18620
  const last = pending[pending.length - 1];
18241
18621
  if (last) clearPrompt(threadId, last.id);
18242
18622
  }
18243
- var import_node_crypto10, import_node_path52, queues, publisher;
18623
+ var import_node_crypto10, import_node_path53, queues, publisher;
18244
18624
  var init_tool_permission = __esm({
18245
18625
  "src/agents/tool-permission.ts"() {
18246
18626
  "use strict";
18247
18627
  import_node_crypto10 = require("crypto");
18248
- import_node_path52 = require("path");
18628
+ import_node_path53 = require("path");
18249
18629
  init_claude_mcp();
18250
18630
  queues = /* @__PURE__ */ new Map();
18251
18631
  publisher = null;
18252
18632
  }
18253
18633
  });
18254
18634
 
18635
+ // src/board/agent-block-view.ts
18636
+ function worktreeBoardStatus(group) {
18637
+ const order = ["running", "queued", "error", "broken"];
18638
+ for (const status of order) {
18639
+ if (group.some((t) => t.status === status)) return status;
18640
+ }
18641
+ return group[0]?.status ?? "idle";
18642
+ }
18643
+ function isDismissedAskUserBlock(block, dismissedQuestionSignature) {
18644
+ if (!block || block.source !== "ask_user") return false;
18645
+ const dismissed = dismissedQuestionSignature?.trim();
18646
+ if (!dismissed) return false;
18647
+ if (!block.questionSignature) return true;
18648
+ return block.questionSignature === dismissed;
18649
+ }
18650
+ function visibleAgentBlock(thread) {
18651
+ if (thread.status === "archived" || thread.status === "error" || thread.status === "broken") {
18652
+ return null;
18653
+ }
18654
+ const block = thread.agentBlock;
18655
+ if (!block?.reason?.trim()) return null;
18656
+ if (isDismissedAskUserBlock(block, thread.dismissedQuestionSignature)) return null;
18657
+ return block;
18658
+ }
18659
+ function worktreeAgentBlock(group) {
18660
+ let best = null;
18661
+ for (const thread of group) {
18662
+ const block = visibleAgentBlock(thread);
18663
+ if (!block) continue;
18664
+ if (!best || block.at > best.at) best = block;
18665
+ }
18666
+ return best;
18667
+ }
18668
+ function threadCardBlockFields(group) {
18669
+ const block = worktreeAgentBlock(group);
18670
+ return block ? { blockedReason: block.reason, blockedSource: block.source } : null;
18671
+ }
18672
+ var init_agent_block_view = __esm({
18673
+ "src/board/agent-block-view.ts"() {
18674
+ "use strict";
18675
+ }
18676
+ });
18677
+
18255
18678
  // src/plan/plan-present.ts
18256
- function asRecord5(v) {
18679
+ function asRecord6(v) {
18257
18680
  return v != null && typeof v === "object" && !Array.isArray(v) ? v : null;
18258
18681
  }
18259
18682
  function isPresentPlanToolName(name) {
@@ -18272,7 +18695,7 @@ function extractPresentedPlan(parts) {
18272
18695
  for (let i = parts.length - 1; i >= 0; i--) {
18273
18696
  const p = parts[i];
18274
18697
  if (p.type !== "tool" || !isPresentPlanToolName(p.name)) continue;
18275
- const input = asRecord5(p.input) ?? {};
18698
+ const input = asRecord6(p.input) ?? {};
18276
18699
  const content = typeof input.content === "string" ? input.content : typeof input.plan === "string" ? input.plan : typeof input.markdown === "string" ? input.markdown : "";
18277
18700
  if (!content.trim()) continue;
18278
18701
  const title = typeof input.title === "string" && input.title.trim() ? input.title.trim() : "Plan";
@@ -18472,7 +18895,10 @@ function decisionBlockFromParts(parts, planMode, at = (/* @__PURE__ */ new Date(
18472
18895
  if (last?.type === "tool" && isAskUserToolName(last.name)) {
18473
18896
  const pending = extractPendingPlanQuestions(parts);
18474
18897
  const reason = pending ? formatAskUserNotifyMessage(pending.questions) : "Waiting for an answer in that chat.";
18475
- return makeAgentBlock("ask_user", reason, at);
18898
+ return {
18899
+ ...makeAgentBlock("ask_user", reason, at),
18900
+ ...pending ? { questionSignature: pending.signature } : {}
18901
+ };
18476
18902
  }
18477
18903
  if (!planMode || last?.type !== "tool") return null;
18478
18904
  const exited = /exitplanmode/i.test(last.name ?? "");
@@ -18489,16 +18915,34 @@ function decisionBlockFromParts(parts, planMode, at = (/* @__PURE__ */ new Date(
18489
18915
  function agentBlockAfterTurn(input) {
18490
18916
  if (input.failed) return null;
18491
18917
  const decision = decisionBlockFromParts(input.parts, input.planMode);
18492
- if (decision) return decision;
18918
+ if (decision) {
18919
+ if (isDismissedAskUserBlock(decision, input.dismissedQuestionSignature)) {
18920
+ return input.existing?.source === "reported" ? input.existing : null;
18921
+ }
18922
+ return decision;
18923
+ }
18493
18924
  if (input.existing && input.existing.source !== "reported" && lastTopLevelTool(input.parts)) {
18494
18925
  return null;
18495
18926
  }
18927
+ if (isDismissedAskUserBlock(input.existing, input.dismissedQuestionSignature)) return null;
18496
18928
  return input.existing ?? null;
18497
18929
  }
18498
18930
  function clearAgentBlock(threadId) {
18499
18931
  const thread = readThread(threadId);
18500
- if (!thread?.agentBlock) return;
18501
- updateThread(threadId, { agentBlock: null });
18932
+ if (!thread?.agentBlock && !thread?.dismissedQuestionSignature) return;
18933
+ updateThread(threadId, { agentBlock: null, dismissedQuestionSignature: null });
18934
+ }
18935
+ function dismissAskUserQuestion(threadId, signature) {
18936
+ const thread = readThread(threadId);
18937
+ if (!thread || thread.status === "archived") return;
18938
+ const sig = signature.trim();
18939
+ if (!sig) return;
18940
+ const clearBlock = thread.agentBlock?.source === "ask_user";
18941
+ if (thread.dismissedQuestionSignature === sig && !clearBlock) return;
18942
+ updateThread(threadId, {
18943
+ dismissedQuestionSignature: sig,
18944
+ ...clearBlock ? { agentBlock: null } : {}
18945
+ });
18502
18946
  }
18503
18947
  function writeAgentBlock(threadId, block) {
18504
18948
  const thread = readThread(threadId);
@@ -18513,11 +18957,12 @@ function settleAgentBlock(threadId, parts, failed) {
18513
18957
  existing: thread.agentBlock,
18514
18958
  parts,
18515
18959
  planMode: Boolean(thread.planMode),
18516
- failed
18960
+ failed,
18961
+ dismissedQuestionSignature: thread.dismissedQuestionSignature
18517
18962
  });
18518
18963
  const prev = thread.agentBlock ?? null;
18519
18964
  if (prev === next) return;
18520
- if (prev && next && prev.source === next.source && prev.reason === next.reason && prev.at === next.at) {
18965
+ if (prev && next && prev.source === next.source && prev.reason === next.reason && prev.at === next.at && prev.questionSignature === next.questionSignature) {
18521
18966
  return;
18522
18967
  }
18523
18968
  updateThread(threadId, { agentBlock: next });
@@ -18535,8 +18980,13 @@ function agentBlockFields(thread) {
18535
18980
  }
18536
18981
  function stampAskUserBlock(resolveCaller, questions) {
18537
18982
  const asked = formatAskUserNotifyMessage(questions);
18983
+ const parsed = parsePlanQuestionsInput({ questions });
18984
+ const block = makeAgentBlock("ask_user", asked);
18538
18985
  try {
18539
- writeAgentBlock(resolveCaller().id, makeAgentBlock("ask_user", asked));
18986
+ writeAgentBlock(
18987
+ resolveCaller().id,
18988
+ parsed.length ? { ...block, questionSignature: planQuestionsSignature(parsed) } : block
18989
+ );
18540
18990
  } catch {
18541
18991
  }
18542
18992
  return asked;
@@ -18559,6 +19009,7 @@ var init_agent_block = __esm({
18559
19009
  "src/orchestrator/agent-block.ts"() {
18560
19010
  "use strict";
18561
19011
  init_tool_permission();
19012
+ init_agent_block_view();
18562
19013
  init_ask_user();
18563
19014
  init_plan_present();
18564
19015
  init_thread_store();
@@ -18770,41 +19221,6 @@ var init_detect = __esm({
18770
19221
  }
18771
19222
  });
18772
19223
 
18773
- // src/board/agent-block-view.ts
18774
- function worktreeBoardStatus(group) {
18775
- const order = ["running", "queued", "error", "broken"];
18776
- for (const status of order) {
18777
- if (group.some((t) => t.status === status)) return status;
18778
- }
18779
- return group[0]?.status ?? "idle";
18780
- }
18781
- function visibleAgentBlock(thread) {
18782
- if (thread.status === "archived" || thread.status === "error" || thread.status === "broken") {
18783
- return null;
18784
- }
18785
- const block = thread.agentBlock;
18786
- if (!block?.reason?.trim()) return null;
18787
- return block;
18788
- }
18789
- function worktreeAgentBlock(group) {
18790
- let best = null;
18791
- for (const thread of group) {
18792
- const block = visibleAgentBlock(thread);
18793
- if (!block) continue;
18794
- if (!best || block.at > best.at) best = block;
18795
- }
18796
- return best;
18797
- }
18798
- function threadCardBlockFields(group) {
18799
- const block = worktreeAgentBlock(group);
18800
- return block ? { blockedReason: block.reason, blockedSource: block.source } : null;
18801
- }
18802
- var init_agent_block_view = __esm({
18803
- "src/board/agent-block-view.ts"() {
18804
- "use strict";
18805
- }
18806
- });
18807
-
18808
19224
  // src/board/pr-state.ts
18809
19225
  function isOpenPrState(prUrl, prState) {
18810
19226
  if (!prUrl?.trim()) return false;
@@ -19582,14 +19998,14 @@ async function startAbleTimeOAuth(opts) {
19582
19998
  const pkce = createAbleTimePkce();
19583
19999
  const authorizeUrl = ableTimeOAuthAuthorizeUrl(clientId, state, pkce.challenge, host);
19584
20000
  const timeoutMs = opts?.timeoutMs ?? 5 * 6e4;
19585
- const code = await new Promise((resolve2, reject) => {
20001
+ const code = await new Promise((resolve3, reject) => {
19586
20002
  let settled = false;
19587
20003
  const finish = (err, value) => {
19588
20004
  if (settled) return;
19589
20005
  settled = true;
19590
20006
  cleanup();
19591
20007
  if (err) reject(err);
19592
- else resolve2(value);
20008
+ else resolve3(value);
19593
20009
  };
19594
20010
  const server = (0, import_node_http.createServer)((req, res) => {
19595
20011
  try {
@@ -19716,7 +20132,7 @@ __export(abletime_rest_exports, {
19716
20132
  looksLikeAbleTimeUlid: () => looksLikeAbleTimeUlid,
19717
20133
  textFromAbleTimeDoc: () => textFromAbleTimeDoc
19718
20134
  });
19719
- function asRecord6(value) {
20135
+ function asRecord7(value) {
19720
20136
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
19721
20137
  }
19722
20138
  function asString(value) {
@@ -19724,7 +20140,7 @@ function asString(value) {
19724
20140
  }
19725
20141
  function asList(value) {
19726
20142
  if (Array.isArray(value)) return value;
19727
- const record = asRecord6(value);
20143
+ const record = asRecord7(value);
19728
20144
  if (!record) return [];
19729
20145
  for (const key of ["data", "tasks", "projects", "users", "items", "results"]) {
19730
20146
  if (Array.isArray(record[key])) return record[key];
@@ -19741,12 +20157,12 @@ function ableTimeDocFromText(text7) {
19741
20157
  }
19742
20158
  function textFromAbleTimeDoc(value) {
19743
20159
  if (typeof value === "string") return value.trim();
19744
- const record = asRecord6(value);
20160
+ const record = asRecord7(value);
19745
20161
  if (!record) return "";
19746
20162
  if (typeof record.text === "string" && record.text.trim()) return record.text.trim();
19747
20163
  const chunks = [];
19748
20164
  const walk = (node) => {
19749
- const rec = asRecord6(node);
20165
+ const rec = asRecord7(node);
19750
20166
  if (!rec) return;
19751
20167
  if (typeof rec.text === "string" && rec.text) chunks.push(rec.text);
19752
20168
  if (Array.isArray(rec.content)) rec.content.forEach(walk);
@@ -19808,7 +20224,7 @@ async function restPages(path, opts, maxPages = 20) {
19808
20224
  query: { ...opts.query, ...cursor ? { cursor } : {} }
19809
20225
  });
19810
20226
  items.push(...asList(raw));
19811
- const page = asRecord6(asRecord6(raw)?.page);
20227
+ const page = asRecord7(asRecord7(raw)?.page);
19812
20228
  const next = page ? asString(page.nextCursor) : "";
19813
20229
  if (!next) break;
19814
20230
  cursor = next;
@@ -19816,7 +20232,7 @@ async function restPages(path, opts, maxPages = 20) {
19816
20232
  return items;
19817
20233
  }
19818
20234
  function userDisplayName(raw) {
19819
- const rec = asRecord6(raw);
20235
+ const rec = asRecord7(raw);
19820
20236
  if (!rec) return null;
19821
20237
  const id = asString(rec.userId) || asString(rec.id);
19822
20238
  const name = [asString(rec.firstName), asString(rec.lastName)].filter(Boolean).join(" ") || asString(rec.username) || asString(rec.email) || asString(rec.name);
@@ -19824,7 +20240,7 @@ function userDisplayName(raw) {
19824
20240
  return { id: id || void 0, name };
19825
20241
  }
19826
20242
  function restTaskToRaw(raw, users) {
19827
- const rec = asRecord6(raw);
20243
+ const rec = asRecord7(raw);
19828
20244
  if (!rec) return null;
19829
20245
  const id = asString(rec.timeflowTaskId) || asString(rec.taskId) || asString(rec.id);
19830
20246
  const identifier = asString(rec.taskRef) || asString(rec.reference) || id;
@@ -19832,7 +20248,7 @@ function restTaskToRaw(raw, users) {
19832
20248
  if (!id && !identifier && !title) return null;
19833
20249
  const assignee = users.get(asString(rec.assignedUserId));
19834
20250
  const comments = asList(rec.comments).map((item) => {
19835
- const comment = asRecord6(item) ?? {};
20251
+ const comment = asRecord7(item) ?? {};
19836
20252
  const user = userDisplayName(comment);
19837
20253
  return {
19838
20254
  id: asString(comment.commentId) || asString(comment.id),
@@ -19862,13 +20278,13 @@ function restTaskToRaw(raw, users) {
19862
20278
  };
19863
20279
  }
19864
20280
  function restProjectToRaw(raw) {
19865
- const rec = asRecord6(raw);
20281
+ const rec = asRecord7(raw);
19866
20282
  if (!rec) return null;
19867
20283
  const id = asString(rec.projectId) || asString(rec.id);
19868
20284
  const name = asString(rec.projectName) || asString(rec.name);
19869
20285
  if (!id && !name) return null;
19870
20286
  const categories = asList(rec.categories).map((item) => {
19871
- const cat = asRecord6(item) ?? {};
20287
+ const cat = asRecord7(item) ?? {};
19872
20288
  return {
19873
20289
  id: asString(cat.projectCategoryId) || asString(cat.categoryId) || asString(cat.id),
19874
20290
  name: asString(cat.categoryName) || asString(cat.name)
@@ -19880,7 +20296,7 @@ async function listUsers(opts) {
19880
20296
  const users = /* @__PURE__ */ new Map();
19881
20297
  for (const item of await restPages("/users", opts).catch(() => [])) {
19882
20298
  const user = userDisplayName(item);
19883
- const rec = asRecord6(item);
20299
+ const rec = asRecord7(item);
19884
20300
  const id = user?.id || (rec ? asString(rec.userId) : "");
19885
20301
  if (user && id) users.set(id, user);
19886
20302
  }
@@ -20006,10 +20422,10 @@ async function callAbleTimeRestTool(name, args = {}, opts) {
20006
20422
  if (!project) throw new Error("AbleTime has no projects to create a task in");
20007
20423
  const categories = asList(project.categories);
20008
20424
  const wantedCategory = firstStringArg(args, ["category_id", "categoryId", "category"]);
20009
- const category = categories.map((item) => asRecord6(item)).find((item) => {
20425
+ const category = categories.map((item) => asRecord7(item)).find((item) => {
20010
20426
  if (!item || !wantedCategory) return false;
20011
20427
  return asString(item.id).toLowerCase() === wantedCategory.toLowerCase() || asString(item.name).toLowerCase() === wantedCategory.toLowerCase();
20012
- }) ?? asRecord6(categories[0]);
20428
+ }) ?? asRecord7(categories[0]);
20013
20429
  const parentArg = firstStringArg(args, ["parent", "parent_id", "parentId", "related_task_id"]);
20014
20430
  const parentTaskId = parentArg ? await resolveRestParentTaskId(parentArg, requestOpts) : void 0;
20015
20431
  const created = await abletimeRestRequest("/tasks", {
@@ -20023,7 +20439,7 @@ async function callAbleTimeRestTool(name, args = {}, opts) {
20023
20439
  }
20024
20440
  });
20025
20441
  const state = firstStringArg(args, ["state"]);
20026
- const createdId = asString(asRecord6(created)?.timeflowTaskId);
20442
+ const createdId = asString(asRecord7(created)?.timeflowTaskId);
20027
20443
  const description = asString(args.description);
20028
20444
  if (createdId && description) {
20029
20445
  await abletimeRestRequest(`/tasks/${encodeURIComponent(createdId)}`, {
@@ -20096,7 +20512,7 @@ async function callAbleTimeRestTool(name, args = {}, opts) {
20096
20512
  method: "POST",
20097
20513
  body: { content: ableTimeDocFromText(body) }
20098
20514
  });
20099
- const rec = asRecord6(created) ?? {};
20515
+ const rec = asRecord7(created) ?? {};
20100
20516
  return {
20101
20517
  id: asString(rec.commentId) || void 0,
20102
20518
  body: textFromAbleTimeDoc(rec.content) || body
@@ -20191,7 +20607,7 @@ function rewriteAbleTimeError(message) {
20191
20607
  }
20192
20608
  return message;
20193
20609
  }
20194
- function asRecord7(value) {
20610
+ function asRecord8(value) {
20195
20611
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
20196
20612
  }
20197
20613
  function parseSseJson(body) {
@@ -20213,12 +20629,12 @@ function parseSseJson(body) {
20213
20629
  }
20214
20630
  }
20215
20631
  function unwrapToolResult(result) {
20216
- const record = asRecord7(result);
20632
+ const record = asRecord8(result);
20217
20633
  if (!record) return result;
20218
20634
  const content = record.content;
20219
20635
  if (Array.isArray(content)) {
20220
20636
  const texts = content.map((part) => {
20221
- const item = asRecord7(part);
20637
+ const item = asRecord8(part);
20222
20638
  if (!item) return "";
20223
20639
  return typeof item.text === "string" ? item.text : "";
20224
20640
  }).filter(Boolean);
@@ -20240,7 +20656,7 @@ function unwrapToolResult(result) {
20240
20656
  return result;
20241
20657
  }
20242
20658
  function textsFromUnknown(value) {
20243
- const record = asRecord7(value);
20659
+ const record = asRecord8(value);
20244
20660
  if (!record) return "";
20245
20661
  if (typeof record.message === "string") return record.message;
20246
20662
  if (typeof record.error === "string") return record.error;
@@ -20287,7 +20703,7 @@ async function abletimeMcpRequest(method, params, opts) {
20287
20703
  return parseSseJson(body);
20288
20704
  }
20289
20705
  })();
20290
- const rpc = asRecord7(parsed);
20706
+ const rpc = asRecord8(parsed);
20291
20707
  if (rpc?.error) {
20292
20708
  const detail = typeof rpc.error.message === "string" && rpc.error.message.trim() ? rpc.error.message : `AbleTime MCP error ${rpc.error.code ?? ""}`.trim();
20293
20709
  throw new Error(rewriteAbleTimeError(detail));
@@ -20379,11 +20795,11 @@ function issueAttachmentWorktreePath(repoPath) {
20379
20795
  return raw || process.cwd();
20380
20796
  }
20381
20797
  function ensureIssueAttachmentsDir(worktreePath) {
20382
- const dir = (0, import_node_path53.join)(worktreePath, ATTACHMENTS_DIR);
20383
- (0, import_node_fs52.mkdirSync)(dir, { recursive: true });
20384
- const gi = (0, import_node_path53.join)(dir, ".gitignore");
20385
- if (!(0, import_node_fs52.existsSync)(gi)) {
20386
- (0, import_node_fs52.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
20798
+ const dir = (0, import_node_path54.join)(worktreePath, ATTACHMENTS_DIR);
20799
+ (0, import_node_fs53.mkdirSync)(dir, { recursive: true });
20800
+ const gi = (0, import_node_path54.join)(dir, ".gitignore");
20801
+ if (!(0, import_node_fs53.existsSync)(gi)) {
20802
+ (0, import_node_fs53.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
20387
20803
  }
20388
20804
  return dir;
20389
20805
  }
@@ -20413,7 +20829,7 @@ function looksLikeFileUrl(url) {
20413
20829
  function filenameFromUrl(url, fallback = "attachment") {
20414
20830
  try {
20415
20831
  const parsed = new URL(url);
20416
- const last = decodeURIComponent((0, import_node_path53.basename)(parsed.pathname)).replace(/[/\\]/g, "_");
20832
+ const last = decodeURIComponent((0, import_node_path54.basename)(parsed.pathname)).replace(/[/\\]/g, "_");
20417
20833
  if (last && last !== "/" && last !== ".") return last;
20418
20834
  } catch {
20419
20835
  }
@@ -20435,12 +20851,12 @@ function filenameFromContentDisposition(header) {
20435
20851
  }
20436
20852
  function uniqueAttachmentFileName(dir, originalName) {
20437
20853
  const safe = originalName.replace(/[/\\]/g, "_").replace(/^\.+/, "") || "file";
20438
- if (!(0, import_node_fs52.existsSync)((0, import_node_path53.join)(dir, safe))) return safe;
20439
- const ext = (0, import_node_path53.extname)(safe);
20854
+ if (!(0, import_node_fs53.existsSync)((0, import_node_path54.join)(dir, safe))) return safe;
20855
+ const ext = (0, import_node_path54.extname)(safe);
20440
20856
  const stem = ext ? safe.slice(0, -ext.length) : safe;
20441
20857
  for (let i = 1; i < 1e4; i++) {
20442
20858
  const candidate = `${stem}-${i}${ext}`;
20443
- if (!(0, import_node_fs52.existsSync)((0, import_node_path53.join)(dir, candidate))) return candidate;
20859
+ if (!(0, import_node_fs53.existsSync)((0, import_node_path54.join)(dir, candidate))) return candidate;
20444
20860
  }
20445
20861
  return `${stem}-${(0, import_node_crypto13.randomUUID)()}${ext}`;
20446
20862
  }
@@ -20488,7 +20904,7 @@ function mergeIssueAttachments(items) {
20488
20904
  return out;
20489
20905
  }
20490
20906
  function extensionForContentType(contentType, name) {
20491
- if ((0, import_node_path53.extname)(name)) return name;
20907
+ if ((0, import_node_path54.extname)(name)) return name;
20492
20908
  const mime = (contentType ?? "").split(";")[0]?.trim().toLowerCase() ?? "";
20493
20909
  const ext = EXT_BY_MIME[mime];
20494
20910
  return ext ? `${name}${ext}` : name;
@@ -20540,7 +20956,7 @@ async function downloadAuthenticatedFile(opts) {
20540
20956
  const dir = ensureIssueAttachmentsDir(opts.worktreePath);
20541
20957
  const hinted = opts.name?.trim() || filenameFromContentDisposition(res.headers.get("content-disposition")) || filenameFromUrl(url);
20542
20958
  const name = uniqueAttachmentFileName(dir, extensionForContentType(contentType, hinted));
20543
- (0, import_node_fs52.writeFileSync)((0, import_node_path53.join)(dir, name), buf);
20959
+ (0, import_node_fs53.writeFileSync)((0, import_node_path54.join)(dir, name), buf);
20544
20960
  return {
20545
20961
  name,
20546
20962
  path: `${ATTACHMENTS_DIR}/${name}`,
@@ -20548,12 +20964,12 @@ async function downloadAuthenticatedFile(opts) {
20548
20964
  ...contentType ? { contentType } : {}
20549
20965
  };
20550
20966
  }
20551
- var import_node_fs52, import_node_path53, import_node_crypto13, ISSUE_ATTACHMENT_MAX_BYTES, MARKDOWN_IMAGE_RE, MARKDOWN_LINK_RE, HTML_SRC_RE, BARE_URL_RE, EXT_BY_MIME;
20967
+ var import_node_fs53, import_node_path54, import_node_crypto13, ISSUE_ATTACHMENT_MAX_BYTES, MARKDOWN_IMAGE_RE, MARKDOWN_LINK_RE, HTML_SRC_RE, BARE_URL_RE, EXT_BY_MIME;
20552
20968
  var init_issue_attachments = __esm({
20553
20969
  "src/integrations/issue-attachments.ts"() {
20554
20970
  "use strict";
20555
- import_node_fs52 = require("fs");
20556
- import_node_path53 = require("path");
20971
+ import_node_fs53 = require("fs");
20972
+ import_node_path54 = require("path");
20557
20973
  import_node_crypto13 = require("crypto");
20558
20974
  init_fetch();
20559
20975
  init_workspace_scratch();
@@ -20579,7 +20995,7 @@ var init_issue_attachments = __esm({
20579
20995
  });
20580
20996
 
20581
20997
  // src/integrations/abletime-attachments.ts
20582
- function asRecord8(value) {
20998
+ function asRecord9(value) {
20583
20999
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
20584
21000
  }
20585
21001
  function asString2(value) {
@@ -20587,7 +21003,7 @@ function asString2(value) {
20587
21003
  }
20588
21004
  function asList2(value) {
20589
21005
  if (Array.isArray(value)) return value;
20590
- const record = asRecord8(value);
21006
+ const record = asRecord9(value);
20591
21007
  if (!record) return [];
20592
21008
  for (const key of ["data", "tasks", "projects", "items", "results", "nodes"]) {
20593
21009
  if (Array.isArray(record[key])) return record[key];
@@ -20606,9 +21022,9 @@ function filesFromAbleTimeDoc(value) {
20606
21022
  const out = [];
20607
21023
  const seen = /* @__PURE__ */ new Set();
20608
21024
  const walk = (node) => {
20609
- const rec = asRecord8(node);
21025
+ const rec = asRecord9(node);
20610
21026
  if (!rec) return;
20611
- const attrs = asRecord8(rec.attrs) ?? rec;
21027
+ const attrs = asRecord9(rec.attrs) ?? rec;
20612
21028
  const url = asString2(attrs.src) || asString2(attrs.href) || asString2(attrs.url) || asString2(attrs.fileUrl) || asString2(attrs.downloadUrl);
20613
21029
  if (url && !seen.has(url)) {
20614
21030
  seen.add(url);
@@ -20626,7 +21042,7 @@ function filesFromAbleTimeDoc(value) {
20626
21042
  function listedAbleTimeFiles(raw) {
20627
21043
  const out = [];
20628
21044
  for (const item of asList2(raw)) {
20629
- const rec = asRecord8(item);
21045
+ const rec = asRecord9(item);
20630
21046
  if (!rec) continue;
20631
21047
  const url = firstString(rec, ["url", "href", "src", "fileUrl", "downloadUrl", "permalink"]);
20632
21048
  if (!url) continue;
@@ -20646,7 +21062,7 @@ function mapAbleTimeAttachments(record) {
20646
21062
  ...filesFromAbleTimeDoc(record.description),
20647
21063
  ...filesFromAbleTimeDoc(record.content),
20648
21064
  ...asList2(record.comments).flatMap((item) => {
20649
- const rec = asRecord8(item);
21065
+ const rec = asRecord9(item);
20650
21066
  return rec ? filesFromAbleTimeDoc(rec.content ?? rec.body) : [];
20651
21067
  })
20652
21068
  ].map((file) => ({
@@ -20688,7 +21104,7 @@ async function resolveAbleTimeAttachmentUrl(id, opts) {
20688
21104
  const json = await res.json().catch(() => null);
20689
21105
  const rec = json && typeof json === "object" && !Array.isArray(json) ? json.data && typeof json.data === "object" ? json.data : json : null;
20690
21106
  if (!rec) continue;
20691
- const url = firstString(rec, ["url", "href", "src", "fileUrl", "downloadUrl"]) || firstString(asRecord8(rec.file), ["url", "href"]);
21107
+ const url = firstString(rec, ["url", "href", "src", "fileUrl", "downloadUrl"]) || firstString(asRecord9(rec.file), ["url", "href"]);
20692
21108
  if (url) {
20693
21109
  return {
20694
21110
  url,
@@ -20730,7 +21146,7 @@ var init_abletime_attachments = __esm({
20730
21146
  });
20731
21147
 
20732
21148
  // src/integrations/abletime-projects.ts
20733
- function asRecord9(value) {
21149
+ function asRecord10(value) {
20734
21150
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
20735
21151
  }
20736
21152
  function firstString2(record, keys) {
@@ -20743,7 +21159,7 @@ function firstString2(record, keys) {
20743
21159
  }
20744
21160
  function asList3(value) {
20745
21161
  if (Array.isArray(value)) return value;
20746
- const record = asRecord9(value);
21162
+ const record = asRecord10(value);
20747
21163
  if (!record) return [];
20748
21164
  for (const key of ["data", "tasks", "projects", "items", "results", "nodes"]) {
20749
21165
  if (Array.isArray(record[key])) return record[key];
@@ -20751,7 +21167,7 @@ function asList3(value) {
20751
21167
  return [];
20752
21168
  }
20753
21169
  function ableTimeProjectFields(nested) {
20754
- const projectRecord = asRecord9(nested.project);
21170
+ const projectRecord = asRecord10(nested.project);
20755
21171
  const projectId = firstString2(nested, ["project_id", "projectId"]) || firstString2(projectRecord, ["id"]) || void 0;
20756
21172
  const projectName = firstString2(nested, ["project_name", "projectName"]) || firstString2(projectRecord, ["name", "title"]) || void 0;
20757
21173
  if (!projectId && !projectName) return {};
@@ -20764,13 +21180,13 @@ function ableTimeProjectFields(nested) {
20764
21180
  };
20765
21181
  }
20766
21182
  function mapAbleTimeProject(raw) {
20767
- const record = asRecord9(raw);
21183
+ const record = asRecord10(raw);
20768
21184
  if (!record) return null;
20769
21185
  const id = firstString2(record, ["id", "project_id", "projectId"]);
20770
21186
  const name = firstString2(record, ["name", "title", "projectName"]);
20771
21187
  if (!id && !name) return null;
20772
21188
  const categories = asList3(record.categories ?? record.category).map((item) => {
20773
- const rec = asRecord9(item);
21189
+ const rec = asRecord10(item);
20774
21190
  if (!rec) return null;
20775
21191
  const categoryId = firstString2(rec, ["id", "category_id", "projectCategoryId", "categoryId"]);
20776
21192
  const categoryName = firstString2(rec, ["name", "title", "categoryName"]);
@@ -20806,7 +21222,7 @@ __export(abletime_exports, {
20806
21222
  updateAbleTimeTask: () => updateAbleTimeTask,
20807
21223
  verifyAbleTimeConnection: () => verifyAbleTimeConnection
20808
21224
  });
20809
- function asRecord10(value) {
21225
+ function asRecord11(value) {
20810
21226
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
20811
21227
  }
20812
21228
  function asString3(value) {
@@ -20823,14 +21239,14 @@ function firstString3(record, keys) {
20823
21239
  function firstRecord(record, keys) {
20824
21240
  if (!record) return null;
20825
21241
  for (const key of keys) {
20826
- const value = asRecord10(record[key]);
21242
+ const value = asRecord11(record[key]);
20827
21243
  if (value) return value;
20828
21244
  }
20829
21245
  return null;
20830
21246
  }
20831
21247
  function asList4(value) {
20832
21248
  if (Array.isArray(value)) return value;
20833
- const record = asRecord10(value);
21249
+ const record = asRecord11(value);
20834
21250
  if (!record) return [];
20835
21251
  for (const key of ["data", "tasks", "projects", "items", "results", "nodes"]) {
20836
21252
  if (Array.isArray(record[key])) return record[key];
@@ -20842,18 +21258,18 @@ function labelsOf(record) {
20842
21258
  if (!Array.isArray(raw)) return [];
20843
21259
  return raw.map((item) => {
20844
21260
  if (typeof item === "string") return item.trim();
20845
- const rec = asRecord10(item);
21261
+ const rec = asRecord11(item);
20846
21262
  return rec ? firstString3(rec, ["name", "title", "label"]) : "";
20847
21263
  }).filter(Boolean);
20848
21264
  }
20849
21265
  function commentsOf(record) {
20850
21266
  const out = [];
20851
21267
  for (const item of asList4(record.comments ?? record.notes ?? record.discussion)) {
20852
- const rec = asRecord10(item);
21268
+ const rec = asRecord11(item);
20853
21269
  if (!rec) continue;
20854
21270
  const body = firstString3(rec, ["body", "text", "comment", "message", "contentSanitized"]) || textFromAbleTimeDoc(rec.content);
20855
21271
  if (!body) continue;
20856
- const user = firstString3(asRecord10(rec.user) ?? asRecord10(rec.author), ["name", "display_name", "username"]) || firstString3(rec, ["user_name", "author", "username"]);
21272
+ const user = firstString3(asRecord11(rec.user) ?? asRecord11(rec.author), ["name", "display_name", "username"]) || firstString3(rec, ["user_name", "author", "username"]);
20857
21273
  const id = firstString3(rec, ["id", "comment_id", "commentId"]);
20858
21274
  const url = firstString3(rec, ["url", "permalink"]);
20859
21275
  const createdAt = firstString3(rec, ["created_at", "createdAt", "created"]);
@@ -20880,7 +21296,7 @@ function taskUrl(task, host) {
20880
21296
  return `${base}/tasks/${slug}`;
20881
21297
  }
20882
21298
  function mapAbleTimeTask(raw, host) {
20883
- const record = asRecord10(raw);
21299
+ const record = asRecord11(raw);
20884
21300
  if (!record) return null;
20885
21301
  const nested = firstRecord(record, ["task", "data"]) ?? record;
20886
21302
  const id = firstString3(nested, ["id", "task_id", "taskId", "timeflowTaskId"]);
@@ -20898,7 +21314,7 @@ function mapAbleTimeTask(raw, host) {
20898
21314
  description: firstString3(nested, ["description", "body", "details", "descriptionSanitized"]) || textFromAbleTimeDoc(nested.description) || void 0,
20899
21315
  state: firstString3(nested, ["state", "board_state", "boardState", "status", "taskState"]) || void 0,
20900
21316
  ...ableTimeProjectFields(nested),
20901
- categoryId: firstString3(nested, ["category_id", "categoryId", "projectCategoryId"]) || firstString3(asRecord10(nested.category), ["id"]) || void 0,
21317
+ categoryId: firstString3(nested, ["category_id", "categoryId", "projectCategoryId"]) || firstString3(asRecord11(nested.category), ["id"]) || void 0,
20902
21318
  assignee: assigneeOf(nested),
20903
21319
  labels: labelsOf(nested),
20904
21320
  comments: commentsOf(nested),
@@ -20948,7 +21364,7 @@ function isOpenTask(task) {
20948
21364
  }
20949
21365
  async function getAbleTimeOrientation(opts) {
20950
21366
  const raw = await callAbleTimeTool("orientation", {}, opts);
20951
- const record = asRecord10(raw);
21367
+ const record = asRecord11(raw);
20952
21368
  const viewerRec = firstRecord(record, ["viewer", "principal", "user", "actor", "me", "person"]) ?? record;
20953
21369
  const viewer = {
20954
21370
  id: firstString3(viewerRec, ["id", "user_id"]) || void 0,
@@ -21027,7 +21443,7 @@ async function commentAbleTimeTask(input, opts) {
21027
21443
  { id, task_id: id, task: id, body, comment: body, text: body },
21028
21444
  opts
21029
21445
  );
21030
- const rec = asRecord10(raw);
21446
+ const rec = asRecord11(raw);
21031
21447
  return {
21032
21448
  id: rec ? firstString3(rec, ["id", "comment_id"]) || void 0 : void 0,
21033
21449
  body: rec ? firstString3(rec, ["body", "text", "comment"]) || body : body
@@ -21282,7 +21698,7 @@ function reuseLiveThread(input, repoPath, match) {
21282
21698
  }
21283
21699
  async function createThread(input, _onSetupLine) {
21284
21700
  const repoPath = await resolveRepoRoot(input.repoPath);
21285
- if (!(0, import_node_fs53.existsSync)(repoPath)) {
21701
+ if (!(0, import_node_fs54.existsSync)(repoPath)) {
21286
21702
  throw new Error(`Repo not found: ${repoPath}`);
21287
21703
  }
21288
21704
  if (isRemovedWorkspace(repoPath)) throw new Error(`Project was removed: ${repoPath}`);
@@ -21469,11 +21885,11 @@ async function createThread(input, _onSetupLine) {
21469
21885
  await ensureWorkspace(repoPath);
21470
21886
  return readThread(thread.id) ?? thread;
21471
21887
  }
21472
- var import_node_fs53;
21888
+ var import_node_fs54;
21473
21889
  var init_create = __esm({
21474
21890
  "src/threads/create.ts"() {
21475
21891
  "use strict";
21476
- import_node_fs53 = require("fs");
21892
+ import_node_fs54 = require("fs");
21477
21893
  init_detect();
21478
21894
  init_worktree();
21479
21895
  init_worktree_labels();
@@ -21532,7 +21948,7 @@ function stampOf(thread) {
21532
21948
  function repoLabel(thread) {
21533
21949
  if (isOrchestratorThread(thread)) return "Orchestration";
21534
21950
  const path = thread.repoPath?.trim() ?? "";
21535
- return path && (0, import_node_path54.basename)(path) || path || "project";
21951
+ return path && (0, import_node_path55.basename)(path) || path || "project";
21536
21952
  }
21537
21953
  function toAgent(thread, flags) {
21538
21954
  const prUrl = thread.prUrl?.trim();
@@ -21731,11 +22147,11 @@ function formatFleetArchive(view) {
21731
22147
  }
21732
22148
  return lines.join("\n");
21733
22149
  }
21734
- var import_node_path54, DEFAULT_LIMIT, MAX_LIMIT;
22150
+ var import_node_path55, DEFAULT_LIMIT, MAX_LIMIT;
21735
22151
  var init_fleet_archive = __esm({
21736
22152
  "src/archive/fleet-archive.ts"() {
21737
22153
  "use strict";
21738
- import_node_path54 = require("path");
22154
+ import_node_path55 = require("path");
21739
22155
  init_global_workspace();
21740
22156
  init_worktree_labels();
21741
22157
  DEFAULT_LIMIT = 40;
@@ -21909,20 +22325,20 @@ function writeTurnLive(threadId, progress) {
21909
22325
  const path = threadLivePath(threadId);
21910
22326
  const tmp = `${path}.${process.pid}.tmp`;
21911
22327
  try {
21912
- (0, import_node_fs54.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
21913
- (0, import_node_fs54.renameSync)(tmp, path);
22328
+ (0, import_node_fs55.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
22329
+ (0, import_node_fs55.renameSync)(tmp, path);
21914
22330
  } catch {
21915
22331
  try {
21916
- (0, import_node_fs54.unlinkSync)(tmp);
22332
+ (0, import_node_fs55.unlinkSync)(tmp);
21917
22333
  } catch {
21918
22334
  }
21919
22335
  }
21920
22336
  }
21921
22337
  function readTurnLive(threadId) {
21922
22338
  const path = threadLivePath(threadId);
21923
- if (!(0, import_node_fs54.existsSync)(path)) return null;
22339
+ if (!(0, import_node_fs55.existsSync)(path)) return null;
21924
22340
  try {
21925
- const raw = JSON.parse((0, import_node_fs54.readFileSync)(path, "utf8"));
22341
+ const raw = JSON.parse((0, import_node_fs55.readFileSync)(path, "utf8"));
21926
22342
  if (!raw || typeof raw.summary !== "string") return null;
21927
22343
  return raw;
21928
22344
  } catch {
@@ -21934,17 +22350,17 @@ function clearTurnLive(threadId) {
21934
22350
  if (buf?.timer) clearTimeout(buf.timer);
21935
22351
  buffers.delete(threadId);
21936
22352
  const path = threadLivePath(threadId);
21937
- if (!(0, import_node_fs54.existsSync)(path)) return;
22353
+ if (!(0, import_node_fs55.existsSync)(path)) return;
21938
22354
  try {
21939
- (0, import_node_fs54.unlinkSync)(path);
22355
+ (0, import_node_fs55.unlinkSync)(path);
21940
22356
  } catch {
21941
22357
  }
21942
22358
  }
21943
- var import_node_fs54, buffers, FLUSH_MS, MAX_PARTS;
22359
+ var import_node_fs55, buffers, FLUSH_MS, MAX_PARTS;
21944
22360
  var init_turn_live = __esm({
21945
22361
  "src/store/turn-live.ts"() {
21946
22362
  "use strict";
21947
- import_node_fs54 = require("fs");
22363
+ import_node_fs55 = require("fs");
21948
22364
  init_message_parts();
21949
22365
  init_paths();
21950
22366
  buffers = /* @__PURE__ */ new Map();
@@ -22221,7 +22637,7 @@ var init_quota_failover = __esm({
22221
22637
  // src/threads/adopt.ts
22222
22638
  function thisModuleFile2() {
22223
22639
  const cjsFile = typeof __filename !== "undefined" ? __filename : "";
22224
- return cjsFile || process.argv[1] || (0, import_node_path55.join)(process.cwd(), "package.json");
22640
+ return cjsFile || process.argv[1] || (0, import_node_path56.join)(process.cwd(), "package.json");
22225
22641
  }
22226
22642
  function openReadonlySqlite(file) {
22227
22643
  const req = (0, import_node_module6.createRequire)(thisModuleFile2());
@@ -22239,21 +22655,21 @@ function mapAgentType(raw) {
22239
22655
  return null;
22240
22656
  }
22241
22657
  function resolveConductorCursorAgentId(workspacePath) {
22242
- if (!workspacePath || !(0, import_node_fs55.existsSync)(CURSOR_SDK_STORE)) return null;
22658
+ if (!workspacePath || !(0, import_node_fs56.existsSync)(CURSOR_SDK_STORE)) return null;
22243
22659
  const normalized = workspacePath.replace(/\/$/, "");
22244
22660
  let best = null;
22245
22661
  let hashes;
22246
22662
  try {
22247
- hashes = (0, import_node_fs55.readdirSync)(CURSOR_SDK_STORE);
22663
+ hashes = (0, import_node_fs56.readdirSync)(CURSOR_SDK_STORE);
22248
22664
  } catch {
22249
22665
  return null;
22250
22666
  }
22251
22667
  for (const hash of hashes) {
22252
- const agentsFile = (0, import_node_path55.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
22253
- if (!(0, import_node_fs55.existsSync)(agentsFile)) continue;
22668
+ const agentsFile = (0, import_node_path56.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
22669
+ if (!(0, import_node_fs56.existsSync)(agentsFile)) continue;
22254
22670
  let text7;
22255
22671
  try {
22256
- text7 = (0, import_node_fs55.readFileSync)(agentsFile, "utf8");
22672
+ text7 = (0, import_node_fs56.readFileSync)(agentsFile, "utf8");
22257
22673
  } catch {
22258
22674
  continue;
22259
22675
  }
@@ -22277,7 +22693,7 @@ function resolveConductorCursorAgentId(workspacePath) {
22277
22693
  return best?.agentId ?? null;
22278
22694
  }
22279
22695
  async function adoptThread(input) {
22280
- if (!(0, import_node_fs55.existsSync)(input.worktreePath)) {
22696
+ if (!(0, import_node_fs56.existsSync)(input.worktreePath)) {
22281
22697
  throw new Error(`Worktree not found: ${input.worktreePath}`);
22282
22698
  }
22283
22699
  const repoPath = await resolveRepoRoot(input.worktreePath);
@@ -22303,18 +22719,18 @@ async function adoptThread(input) {
22303
22719
  return thread;
22304
22720
  }
22305
22721
  function listConductorWorkspaces() {
22306
- if (!(0, import_node_fs55.existsSync)(CONDUCTOR_DB)) {
22722
+ if (!(0, import_node_fs56.existsSync)(CONDUCTOR_DB)) {
22307
22723
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
22308
22724
  }
22309
- const tmp = (0, import_node_fs55.mkdtempSync)((0, import_node_path55.join)((0, import_node_os16.tmpdir)(), "sideboard-conductor-"));
22310
- const snapshot = (0, import_node_path55.join)(tmp, "conductor.db");
22725
+ const tmp = (0, import_node_fs56.mkdtempSync)((0, import_node_path56.join)((0, import_node_os18.tmpdir)(), "sideboard-conductor-"));
22726
+ const snapshot = (0, import_node_path56.join)(tmp, "conductor.db");
22311
22727
  try {
22312
- (0, import_node_fs55.copyFileSync)(CONDUCTOR_DB, snapshot);
22728
+ (0, import_node_fs56.copyFileSync)(CONDUCTOR_DB, snapshot);
22313
22729
  for (const suffix of ["-wal", "-shm"]) {
22314
22730
  const src = `${CONDUCTOR_DB}${suffix}`;
22315
- if ((0, import_node_fs55.existsSync)(src)) {
22731
+ if ((0, import_node_fs56.existsSync)(src)) {
22316
22732
  try {
22317
- (0, import_node_fs55.copyFileSync)(src, `${snapshot}${suffix}`);
22733
+ (0, import_node_fs56.copyFileSync)(src, `${snapshot}${suffix}`);
22318
22734
  } catch {
22319
22735
  }
22320
22736
  }
@@ -22390,22 +22806,22 @@ function listConductorWorkspaces() {
22390
22806
  db.close();
22391
22807
  }
22392
22808
  } finally {
22393
- (0, import_node_fs55.rmSync)(tmp, { recursive: true, force: true });
22809
+ (0, import_node_fs56.rmSync)(tmp, { recursive: true, force: true });
22394
22810
  }
22395
22811
  }
22396
22812
  function importConductorWorkspace(workspaceId) {
22397
- if (!(0, import_node_fs55.existsSync)(CONDUCTOR_DB)) {
22813
+ if (!(0, import_node_fs56.existsSync)(CONDUCTOR_DB)) {
22398
22814
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
22399
22815
  }
22400
- const tmp = (0, import_node_fs55.mkdtempSync)((0, import_node_path55.join)((0, import_node_os16.tmpdir)(), "sideboard-conductor-"));
22401
- const snapshot = (0, import_node_path55.join)(tmp, "conductor.db");
22816
+ const tmp = (0, import_node_fs56.mkdtempSync)((0, import_node_path56.join)((0, import_node_os18.tmpdir)(), "sideboard-conductor-"));
22817
+ const snapshot = (0, import_node_path56.join)(tmp, "conductor.db");
22402
22818
  try {
22403
- (0, import_node_fs55.copyFileSync)(CONDUCTOR_DB, snapshot);
22819
+ (0, import_node_fs56.copyFileSync)(CONDUCTOR_DB, snapshot);
22404
22820
  for (const suffix of ["-wal", "-shm"]) {
22405
22821
  const src = `${CONDUCTOR_DB}${suffix}`;
22406
- if ((0, import_node_fs55.existsSync)(src)) {
22822
+ if ((0, import_node_fs56.existsSync)(src)) {
22407
22823
  try {
22408
- (0, import_node_fs55.copyFileSync)(src, `${snapshot}${suffix}`);
22824
+ (0, import_node_fs56.copyFileSync)(src, `${snapshot}${suffix}`);
22409
22825
  } catch {
22410
22826
  }
22411
22827
  }
@@ -22423,7 +22839,7 @@ function importConductorWorkspace(workspaceId) {
22423
22839
  ).get(workspaceId);
22424
22840
  if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
22425
22841
  const worktreePath = String(row.workspacePath);
22426
- if (!(0, import_node_fs55.existsSync)(worktreePath)) {
22842
+ if (!(0, import_node_fs56.existsSync)(worktreePath)) {
22427
22843
  throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
22428
22844
  }
22429
22845
  let sessionId = null;
@@ -22486,31 +22902,31 @@ function importConductorWorkspace(workspaceId) {
22486
22902
  db.close();
22487
22903
  }
22488
22904
  } finally {
22489
- (0, import_node_fs55.rmSync)(tmp, { recursive: true, force: true });
22905
+ (0, import_node_fs56.rmSync)(tmp, { recursive: true, force: true });
22490
22906
  }
22491
22907
  }
22492
22908
  async function importConductorWorkspaceAsync(workspaceId) {
22493
22909
  return importConductorWorkspace(workspaceId);
22494
22910
  }
22495
- var import_node_child_process5, import_node_fs55, import_node_os16, import_node_path55, import_node_module6, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
22911
+ var import_node_child_process5, import_node_fs56, import_node_os18, import_node_path56, import_node_module6, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
22496
22912
  var init_adopt = __esm({
22497
22913
  "src/threads/adopt.ts"() {
22498
22914
  "use strict";
22499
22915
  import_node_child_process5 = require("child_process");
22500
- import_node_fs55 = require("fs");
22501
- import_node_os16 = require("os");
22502
- import_node_path55 = require("path");
22916
+ import_node_fs56 = require("fs");
22917
+ import_node_os18 = require("os");
22918
+ import_node_path56 = require("path");
22503
22919
  import_node_module6 = require("module");
22504
22920
  init_worktree();
22505
22921
  init_thread_store();
22506
- CONDUCTOR_APP_SUPPORT = (0, import_node_path55.join)(
22922
+ CONDUCTOR_APP_SUPPORT = (0, import_node_path56.join)(
22507
22923
  process.env.HOME ?? "",
22508
22924
  "Library",
22509
22925
  "Application Support",
22510
22926
  "com.conductor.app"
22511
22927
  );
22512
- CONDUCTOR_DB = (0, import_node_path55.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
22513
- CURSOR_SDK_STORE = (0, import_node_path55.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
22928
+ CONDUCTOR_DB = (0, import_node_path56.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
22929
+ CURSOR_SDK_STORE = (0, import_node_path56.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
22514
22930
  }
22515
22931
  });
22516
22932
 
@@ -22577,7 +22993,7 @@ async function openStackLayer(input, _onSetupLine) {
22577
22993
  let createdWorktree = false;
22578
22994
  const trees = await listWorktrees(repoPath);
22579
22995
  const checkedOut = trees.find((w) => w.branch === branchName);
22580
- if (checkedOut?.path && (0, import_node_fs56.existsSync)(checkedOut.path)) {
22996
+ if (checkedOut?.path && (0, import_node_fs57.existsSync)(checkedOut.path)) {
22581
22997
  if (input.reuseExistingWorktree !== false) {
22582
22998
  worktreePath = checkedOut.path;
22583
22999
  } else {
@@ -22719,7 +23135,7 @@ async function initStackFromThread(input, onSetupLine) {
22719
23135
  async function createPrStack(input, onSetupLine) {
22720
23136
  await requireAgent(input.agent);
22721
23137
  const repoPath = await resolveRepoRoot(input.repoPath);
22722
- if (!(0, import_node_fs56.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
23138
+ if (!(0, import_node_fs57.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
22723
23139
  if (!input.branches.length) throw new Error("At least one branch name required");
22724
23140
  const status = await detectGhStack(repoPath);
22725
23141
  if (!status.available) throw new Error(status.reason);
@@ -22786,7 +23202,7 @@ async function createPrStack(input, onSetupLine) {
22786
23202
  }
22787
23203
  }
22788
23204
  const claimed = new Set(threads.map((t) => t.worktreePath));
22789
- if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs56.existsSync)(bootstrap.worktreePath)) {
23205
+ if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs57.existsSync)(bootstrap.worktreePath)) {
22790
23206
  try {
22791
23207
  await removeWorktree(repoPath, bootstrap.worktreePath, {
22792
23208
  deleteBranch: bootstrap.branchName
@@ -22796,11 +23212,11 @@ async function createPrStack(input, onSetupLine) {
22796
23212
  }
22797
23213
  return { stack, threads, createdThreadIds };
22798
23214
  }
22799
- var import_node_fs56;
23215
+ var import_node_fs57;
22800
23216
  var init_stack_layers = __esm({
22801
23217
  "src/threads/stack-layers.ts"() {
22802
23218
  "use strict";
22803
- import_node_fs56 = require("fs");
23219
+ import_node_fs57 = require("fs");
22804
23220
  init_detect();
22805
23221
  init_run();
22806
23222
  init_stack();
@@ -22813,7 +23229,7 @@ var init_stack_layers = __esm({
22813
23229
 
22814
23230
  // src/diff/diff.ts
22815
23231
  async function inspectGitWorktree(worktreePath) {
22816
- if (!worktreePath || !(0, import_node_fs57.existsSync)(worktreePath)) return "missing_worktree";
23232
+ if (!worktreePath || !(0, import_node_fs58.existsSync)(worktreePath)) return "missing_worktree";
22817
23233
  const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
22818
23234
  reject: false
22819
23235
  });
@@ -22821,7 +23237,7 @@ async function inspectGitWorktree(worktreePath) {
22821
23237
  return "ok";
22822
23238
  }
22823
23239
  async function initializeGitRepository(worktreePath) {
22824
- if (!worktreePath || !(0, import_node_fs57.existsSync)(worktreePath)) {
23240
+ if (!worktreePath || !(0, import_node_fs58.existsSync)(worktreePath)) {
22825
23241
  throw new Error("Worktree not found");
22826
23242
  }
22827
23243
  const status = await inspectGitWorktree(worktreePath);
@@ -22955,11 +23371,11 @@ new file mode 100644
22955
23371
  };
22956
23372
  }
22957
23373
  async function untrackedPatch(worktreePath, path, maxHunk) {
22958
- const abs = (0, import_node_path56.join)(worktreePath, path);
23374
+ const abs = (0, import_node_path57.join)(worktreePath, path);
22959
23375
  try {
22960
- const st = (0, import_node_fs57.statSync)(abs);
23376
+ const st = (0, import_node_fs58.statSync)(abs);
22961
23377
  if (st.isFile() && st.size > maxHunk) {
22962
- const buf = (0, import_node_fs57.readFileSync)(abs).subarray(0, maxHunk);
23378
+ const buf = (0, import_node_fs58.readFileSync)(abs).subarray(0, maxHunk);
22963
23379
  return syntheticAddPatch(path, buf.toString("utf8"), maxHunk);
22964
23380
  }
22965
23381
  } catch {
@@ -23426,9 +23842,9 @@ async function getDiff(worktreePath, repoPath, opts) {
23426
23842
  }
23427
23843
  function statWorktreePath(worktreePath, relativePath) {
23428
23844
  assertSafeRelativePath(relativePath);
23429
- const abs = (0, import_node_path56.join)(worktreePath, relativePath);
23430
- if (!(0, import_node_fs57.existsSync)(abs)) return "missing";
23431
- const st = (0, import_node_fs57.statSync)(abs);
23845
+ const abs = (0, import_node_path57.join)(worktreePath, relativePath);
23846
+ if (!(0, import_node_fs58.existsSync)(abs)) return "missing";
23847
+ const st = (0, import_node_fs58.statSync)(abs);
23432
23848
  if (st.isDirectory()) return "dir";
23433
23849
  if (st.isFile()) return "file";
23434
23850
  return "missing";
@@ -23457,8 +23873,8 @@ function isImageRelativePath(relativePath) {
23457
23873
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
23458
23874
  assertSafeRelativePath(relativePath);
23459
23875
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
23460
- const abs = (0, import_node_path56.join)(worktreePath, relativePath);
23461
- const st = (0, import_node_fs57.statSync)(abs);
23876
+ const abs = (0, import_node_path57.join)(worktreePath, relativePath);
23877
+ const st = (0, import_node_fs58.statSync)(abs);
23462
23878
  if (!st.isFile()) {
23463
23879
  throw new Error(`Not a file: ${relativePath}`);
23464
23880
  }
@@ -23467,7 +23883,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
23467
23883
  `File too large to upload (${st.size} bytes; max ${maxBytes})`
23468
23884
  );
23469
23885
  }
23470
- const buf = (0, import_node_fs57.readFileSync)(abs);
23886
+ const buf = (0, import_node_fs58.readFileSync)(abs);
23471
23887
  return {
23472
23888
  path: relativePath,
23473
23889
  contentBase64: buf.toString("base64"),
@@ -23477,12 +23893,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
23477
23893
  function readWorktreeFile(worktreePath, relativePath, opts) {
23478
23894
  assertSafeRelativePath(relativePath);
23479
23895
  const maxBytes = opts?.maxBytes ?? 2e5;
23480
- const abs = (0, import_node_path56.join)(worktreePath, relativePath);
23481
- const st = (0, import_node_fs57.statSync)(abs);
23896
+ const abs = (0, import_node_path57.join)(worktreePath, relativePath);
23897
+ const st = (0, import_node_fs58.statSync)(abs);
23482
23898
  if (!st.isFile()) {
23483
23899
  throw new Error(`Not a file: ${relativePath}`);
23484
23900
  }
23485
- const buf = (0, import_node_fs57.readFileSync)(abs);
23901
+ const buf = (0, import_node_fs58.readFileSync)(abs);
23486
23902
  if (isImageRelativePath(relativePath)) {
23487
23903
  const maxImageBytes = Math.max(maxBytes, 15e6);
23488
23904
  const truncated2 = buf.length > maxImageBytes;
@@ -23525,9 +23941,9 @@ function assertSafeRelativePath(relativePath) {
23525
23941
  }
23526
23942
  function writeWorktreeFile(worktreePath, relativePath, content) {
23527
23943
  assertSafeRelativePath(relativePath);
23528
- const abs = (0, import_node_path56.join)(worktreePath, relativePath);
23529
- (0, import_node_fs57.mkdirSync)((0, import_node_path56.dirname)(abs), { recursive: true });
23530
- (0, import_node_fs57.writeFileSync)(abs, content, "utf8");
23944
+ const abs = (0, import_node_path57.join)(worktreePath, relativePath);
23945
+ (0, import_node_fs58.mkdirSync)((0, import_node_path57.dirname)(abs), { recursive: true });
23946
+ (0, import_node_fs58.writeFileSync)(abs, content, "utf8");
23531
23947
  return { path: relativePath };
23532
23948
  }
23533
23949
  async function getWorktreeDirtyStat(worktreePath) {
@@ -23567,12 +23983,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
23567
23983
  truncated: full.files.length > maxFiles
23568
23984
  };
23569
23985
  }
23570
- var import_node_fs57, import_node_path56, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
23986
+ var import_node_fs58, import_node_path57, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
23571
23987
  var init_diff = __esm({
23572
23988
  "src/diff/diff.ts"() {
23573
23989
  "use strict";
23574
- import_node_fs57 = require("fs");
23575
- import_node_path56 = require("path");
23990
+ import_node_fs58 = require("fs");
23991
+ import_node_path57 = require("path");
23576
23992
  init_run();
23577
23993
  init_worktree();
23578
23994
  mergeBaseCache = /* @__PURE__ */ new Map();
@@ -23794,16 +24210,16 @@ function readWorktreeFileTail(worktreePath, relativePath, maxBytes = WORKTREE_TA
23794
24210
  if (!relativePath || relativePath.includes("..") || relativePath.startsWith("/")) {
23795
24211
  throw new Error("Invalid path");
23796
24212
  }
23797
- const abs = (0, import_node_path57.join)(worktreePath, relativePath);
23798
- const fd = (0, import_node_fs58.openSync)(abs, "r");
24213
+ const abs = (0, import_node_path58.join)(worktreePath, relativePath);
24214
+ const fd = (0, import_node_fs59.openSync)(abs, "r");
23799
24215
  try {
23800
- const st = (0, import_node_fs58.fstatSync)(fd);
24216
+ const st = (0, import_node_fs59.fstatSync)(fd);
23801
24217
  if (!st.isFile()) throw new Error(`Not a file: ${relativePath}`);
23802
24218
  const size = st.size;
23803
24219
  const start = Math.max(0, size - maxBytes);
23804
24220
  const length = size - start;
23805
24221
  const buf = Buffer.alloc(length);
23806
- if (length > 0) (0, import_node_fs58.readSync)(fd, buf, 0, length, start);
24222
+ if (length > 0) (0, import_node_fs59.readSync)(fd, buf, 0, length, start);
23807
24223
  if (buf.subarray(0, Math.min(buf.length, 8e3)).includes(0)) {
23808
24224
  return {
23809
24225
  path: relativePath,
@@ -23821,15 +24237,15 @@ function readWorktreeFileTail(worktreePath, relativePath, maxBytes = WORKTREE_TA
23821
24237
  }
23822
24238
  return { path: relativePath, content, truncated, binary: false, encoding: "utf8" };
23823
24239
  } finally {
23824
- (0, import_node_fs58.closeSync)(fd);
24240
+ (0, import_node_fs59.closeSync)(fd);
23825
24241
  }
23826
24242
  }
23827
- var import_node_fs58, import_node_path57, WORKTREE_TAIL_BYTES;
24243
+ var import_node_fs59, import_node_path58, WORKTREE_TAIL_BYTES;
23828
24244
  var init_read_worktree_tail = __esm({
23829
24245
  "src/diff/read-worktree-tail.ts"() {
23830
24246
  "use strict";
23831
- import_node_fs58 = require("fs");
23832
- import_node_path57 = require("path");
24247
+ import_node_fs59 = require("fs");
24248
+ import_node_path58 = require("path");
23833
24249
  WORKTREE_TAIL_BYTES = 2e5;
23834
24250
  }
23835
24251
  });
@@ -23978,7 +24394,7 @@ function parseFrontmatter(content) {
23978
24394
  }
23979
24395
  function readSkill(skillMd, source) {
23980
24396
  try {
23981
- const content = (0, import_node_fs59.readFileSync)(skillMd, "utf8");
24397
+ const content = (0, import_node_fs60.readFileSync)(skillMd, "utf8");
23982
24398
  const { name: fmName, description } = parseFrontmatter(content);
23983
24399
  const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
23984
24400
  const name = fmName || dirName;
@@ -23997,19 +24413,19 @@ function readSkill(skillMd, source) {
23997
24413
  }
23998
24414
  }
23999
24415
  function scanSkillsDir(dir, source, out) {
24000
- if (!(0, import_node_fs59.existsSync)(dir)) return;
24416
+ if (!(0, import_node_fs60.existsSync)(dir)) return;
24001
24417
  let entries;
24002
24418
  try {
24003
- entries = (0, import_node_fs59.readdirSync)(dir);
24419
+ entries = (0, import_node_fs60.readdirSync)(dir);
24004
24420
  } catch {
24005
24421
  return;
24006
24422
  }
24007
24423
  for (const entry of entries) {
24008
24424
  if (entry.startsWith(".")) continue;
24009
- const skillMd = (0, import_node_path58.join)(dir, entry, "SKILL.md");
24010
- if (!(0, import_node_fs59.existsSync)(skillMd)) continue;
24425
+ const skillMd = (0, import_node_path59.join)(dir, entry, "SKILL.md");
24426
+ if (!(0, import_node_fs60.existsSync)(skillMd)) continue;
24011
24427
  try {
24012
- if (!(0, import_node_fs59.statSync)(skillMd).isFile()) continue;
24428
+ if (!(0, import_node_fs60.statSync)(skillMd).isFile()) continue;
24013
24429
  } catch {
24014
24430
  continue;
24015
24431
  }
@@ -24018,24 +24434,24 @@ function scanSkillsDir(dir, source, out) {
24018
24434
  }
24019
24435
  }
24020
24436
  function scanClaudePluginSkills(pluginsRoot, out) {
24021
- if (!(0, import_node_fs59.existsSync)(pluginsRoot)) return;
24437
+ if (!(0, import_node_fs60.existsSync)(pluginsRoot)) return;
24022
24438
  const walk = (dir, depth, lookingForSkillsDir) => {
24023
24439
  if (depth > 7) return;
24024
24440
  let entries;
24025
24441
  try {
24026
- entries = (0, import_node_fs59.readdirSync)(dir);
24442
+ entries = (0, import_node_fs60.readdirSync)(dir);
24027
24443
  } catch {
24028
24444
  return;
24029
24445
  }
24030
24446
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
24031
- const skill = readSkill((0, import_node_path58.join)(dir, "SKILL.md"), "cli");
24447
+ const skill = readSkill((0, import_node_path59.join)(dir, "SKILL.md"), "cli");
24032
24448
  if (skill) out.push(skill);
24033
24449
  }
24034
24450
  for (const entry of entries) {
24035
24451
  if (entry === "node_modules" || entry === ".git") continue;
24036
- const full = (0, import_node_path58.join)(dir, entry);
24452
+ const full = (0, import_node_path59.join)(dir, entry);
24037
24453
  try {
24038
- if (!(0, import_node_fs59.statSync)(full).isDirectory()) continue;
24454
+ if (!(0, import_node_fs60.statSync)(full).isDirectory()) continue;
24039
24455
  } catch {
24040
24456
  continue;
24041
24457
  }
@@ -24050,20 +24466,20 @@ function scanClaudePluginSkills(pluginsRoot, out) {
24050
24466
  walk(pluginsRoot, 0, false);
24051
24467
  }
24052
24468
  function discoverSkills(worktreePath) {
24053
- const home = (0, import_node_os17.homedir)();
24469
+ const home = (0, import_node_os19.homedir)();
24054
24470
  const collected = [];
24055
24471
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
24056
- scanSkillsDir((0, import_node_path58.join)(worktreePath, rel), "workspace", collected);
24472
+ scanSkillsDir((0, import_node_path59.join)(worktreePath, rel), "workspace", collected);
24057
24473
  }
24058
24474
  for (const abs of [
24059
- (0, import_node_path58.join)(home, ".claude/skills"),
24060
- (0, import_node_path58.join)(home, ".cursor/skills"),
24061
- (0, import_node_path58.join)(home, ".sideboard/skills"),
24062
- (0, import_node_path58.join)(home, ".brightsy/skills")
24475
+ (0, import_node_path59.join)(home, ".claude/skills"),
24476
+ (0, import_node_path59.join)(home, ".cursor/skills"),
24477
+ (0, import_node_path59.join)(home, ".sideboard/skills"),
24478
+ (0, import_node_path59.join)(home, ".brightsy/skills")
24063
24479
  ]) {
24064
24480
  scanSkillsDir(abs, "user", collected);
24065
24481
  }
24066
- scanClaudePluginSkills((0, import_node_path58.join)(home, ".claude/plugins"), collected);
24482
+ scanClaudePluginSkills((0, import_node_path59.join)(home, ".claude/plugins"), collected);
24067
24483
  collected.push(...bundledSkills());
24068
24484
  const rank = {
24069
24485
  workspace: 0,
@@ -24089,7 +24505,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
24089
24505
  \u2026(truncated)` : body;
24090
24506
  }
24091
24507
  }
24092
- const raw = (0, import_node_fs59.readFileSync)(skillPath, "utf8");
24508
+ const raw = (0, import_node_fs60.readFileSync)(skillPath, "utf8");
24093
24509
  if (raw.startsWith("---")) {
24094
24510
  const end = raw.indexOf("\n---", 3);
24095
24511
  if (end >= 0) {
@@ -24103,13 +24519,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
24103
24519
 
24104
24520
  \u2026(truncated)` : raw;
24105
24521
  }
24106
- var import_node_fs59, import_node_os17, import_node_path58, BUNDLED_SKILL_PREFIX;
24522
+ var import_node_fs60, import_node_os19, import_node_path59, BUNDLED_SKILL_PREFIX;
24107
24523
  var init_discover = __esm({
24108
24524
  "src/skills/discover.ts"() {
24109
24525
  "use strict";
24110
- import_node_fs59 = require("fs");
24111
- import_node_os17 = require("os");
24112
- import_node_path58 = require("path");
24526
+ import_node_fs60 = require("fs");
24527
+ import_node_os19 = require("os");
24528
+ import_node_path59 = require("path");
24113
24529
  init_long_running();
24114
24530
  BUNDLED_SKILL_PREFIX = "bundled:";
24115
24531
  }
@@ -24262,9 +24678,9 @@ function compiledModuleDir() {
24262
24678
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
24263
24679
  if (cjsDir) return cjsDir;
24264
24680
  try {
24265
- const url = import_meta5.url;
24681
+ const url = import_meta6.url;
24266
24682
  if (typeof url === "string" && url.length > 0) {
24267
- return (0, import_node_path59.dirname)((0, import_node_url5.fileURLToPath)(url));
24683
+ return (0, import_node_path60.dirname)((0, import_node_url5.fileURLToPath)(url));
24268
24684
  }
24269
24685
  } catch {
24270
24686
  }
@@ -24272,8 +24688,8 @@ function compiledModuleDir() {
24272
24688
  }
24273
24689
  function detachedJobScriptIn(dir) {
24274
24690
  for (const name of DETACHED_JOB_FILENAMES) {
24275
- const script = (0, import_node_path59.join)(dir, "scripts", name);
24276
- if ((0, import_node_fs60.existsSync)(script)) return script;
24691
+ const script = (0, import_node_path60.join)(dir, "scripts", name);
24692
+ if ((0, import_node_fs61.existsSync)(script)) return script;
24277
24693
  }
24278
24694
  return null;
24279
24695
  }
@@ -24290,7 +24706,7 @@ function resolveDetachedJobScript() {
24290
24706
  for (let i = 0; i < 8; i++) {
24291
24707
  const candidate = detachedJobScriptIn(dir);
24292
24708
  if (candidate) return candidate;
24293
- const parent = (0, import_node_path59.dirname)(dir);
24709
+ const parent = (0, import_node_path60.dirname)(dir);
24294
24710
  if (parent === dir) break;
24295
24711
  dir = parent;
24296
24712
  }
@@ -24301,15 +24717,15 @@ function formatDetachedJobInvoke(scriptPath) {
24301
24717
  if (resolved) return `node ${JSON.stringify(resolved)}`;
24302
24718
  return "node scripts/detached-job.cjs";
24303
24719
  }
24304
- var import_node_fs60, import_node_path59, import_node_url5, import_meta5, DETACHED_JOB_FILENAMES;
24720
+ var import_node_fs61, import_node_path60, import_node_url5, import_meta6, DETACHED_JOB_FILENAMES;
24305
24721
  var init_detached_job_path = __esm({
24306
24722
  "src/skills/detached-job-path.ts"() {
24307
24723
  "use strict";
24308
- import_node_fs60 = require("fs");
24309
- import_node_path59 = require("path");
24724
+ import_node_fs61 = require("fs");
24725
+ import_node_path60 = require("path");
24310
24726
  import_node_url5 = require("url");
24311
24727
  init_packaged_runtime();
24312
- import_meta5 = {};
24728
+ import_meta6 = {};
24313
24729
  DETACHED_JOB_FILENAMES = ["detached-job.cjs", "detached-job.js"];
24314
24730
  }
24315
24731
  });
@@ -24407,9 +24823,9 @@ function formatWorktreeDirective(thread, opts) {
24407
24823
  );
24408
24824
  } else {
24409
24825
  const slug = opts?.githubSlug ?? "<origin-owner/name>";
24410
- const resolve2 = opts?.githubSlug ? "" : " Resolve `<origin-owner/name>` with `git remote get-url origin` in this worktree.";
24826
+ const resolve3 = opts?.githubSlug ? "" : " Resolve `<origin-owner/name>` with `git remote get-url origin` in this worktree.";
24411
24827
  lines.push(
24412
- `- Prefer a draft PR first: \`gh pr create --draft --assignee @me -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} Assign to the GitHub-connected user (\`--assignee @me\`) unless the user named someone else. 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\`.`
24828
+ `- Prefer a draft PR first: \`gh pr create --draft --assignee @me -R ${slug}\` (update via \`gh pr edit -R ${slug}\`). Always pass \`-R\` \u2014 bare \`gh pr create\` may target upstream on dual-remote checkouts.${resolve3} Assign to the GitHub-connected user (\`--assignee @me\`) unless the user named someone else. 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\`.`
24413
24829
  );
24414
24830
  }
24415
24831
  lines.push(
@@ -24513,9 +24929,9 @@ function formatPrGateDirective() {
24513
24929
  }
24514
24930
  function formatProcessGuideDirective(opts) {
24515
24931
  const worktree = opts?.worktreePath?.trim();
24516
- const hasGraphSkill = !!worktree && (0, import_node_fs61.existsSync)((0, import_node_path60.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
24517
- const hasReviewSkill = !!worktree && (0, import_node_fs61.existsSync)((0, import_node_path60.join)(worktree, ".claude/skills/review/SKILL.md"));
24518
- const hasInstallSkill = !!worktree && (0, import_node_fs61.existsSync)((0, import_node_path60.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
24932
+ const hasGraphSkill = !!worktree && (0, import_node_fs62.existsSync)((0, import_node_path61.join)(worktree, ".claude/skills/graph-engineering/SKILL.md"));
24933
+ const hasReviewSkill = !!worktree && (0, import_node_fs62.existsSync)((0, import_node_path61.join)(worktree, ".claude/skills/review/SKILL.md"));
24934
+ const hasInstallSkill = !!worktree && (0, import_node_fs62.existsSync)((0, import_node_path61.join)(worktree, ".claude/skills/worktree-install/SKILL.md"));
24519
24935
  return [
24520
24936
  "Process guides (recurring work only):",
24521
24937
  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,
@@ -24555,12 +24971,12 @@ function formatArtifactDirective() {
24555
24971
  function formatUiReminder() {
24556
24972
  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). Chat links: `[name](sideboard://artifact/<id-or-title>)` opens that pane; `[name](sideboard://file/path#L12-L40)` opens a file. 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; pass name \u2014 several scripts can run at once) 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 that script\u2019s Run-tab terminal; stop_dev_script to stop one.";
24557
24973
  }
24558
- var import_node_fs61, import_node_path60, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
24974
+ var import_node_fs62, import_node_path61, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
24559
24975
  var init_instructions = __esm({
24560
24976
  "src/agents/instructions.ts"() {
24561
24977
  "use strict";
24562
- import_node_fs61 = require("fs");
24563
- import_node_path60 = require("path");
24978
+ import_node_fs62 = require("fs");
24979
+ import_node_path61 = require("path");
24564
24980
  init_git_auth_mode();
24565
24981
  init_branch_prefix();
24566
24982
  init_worktree_labels();
@@ -24836,11 +25252,11 @@ function parseIssueSince(input, now = /* @__PURE__ */ new Date()) {
24836
25252
  if (lower === "last week" || lower === "lastweek") {
24837
25253
  return addLocalDays(startOfLocalDay(now), -7).toISOString();
24838
25254
  }
24839
- const relative = lower.match(RELATIVE_RE);
24840
- if (relative) {
24841
- const n = Number(relative[1]);
25255
+ const relative2 = lower.match(RELATIVE_RE);
25256
+ if (relative2) {
25257
+ const n = Number(relative2[1]);
24842
25258
  if (!Number.isInteger(n) || n < 1) throw new Error(ISSUE_SINCE_ERROR);
24843
- const unit = relative[2];
25259
+ const unit = relative2[2];
24844
25260
  if (unit.startsWith("h")) return new Date(now.getTime() - n * 36e5).toISOString();
24845
25261
  if (unit.startsWith("w")) return addLocalDays(startOfLocalDay(now), -7 * n).toISOString();
24846
25262
  return addLocalDays(startOfLocalDay(now), -n).toISOString();
@@ -25301,40 +25717,40 @@ __export(plan_file_exports, {
25301
25717
  writePlanFile: () => writePlanFile
25302
25718
  });
25303
25719
  function ensureAttachmentsGitignore(worktreePath) {
25304
- const gitignoreAbs = (0, import_node_path61.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
25305
- if ((0, import_node_fs62.existsSync)(gitignoreAbs)) return;
25306
- (0, import_node_fs62.mkdirSync)((0, import_node_path61.dirname)(gitignoreAbs), { recursive: true });
25307
- (0, import_node_fs62.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
25720
+ const gitignoreAbs = (0, import_node_path62.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
25721
+ if ((0, import_node_fs63.existsSync)(gitignoreAbs)) return;
25722
+ (0, import_node_fs63.mkdirSync)((0, import_node_path62.dirname)(gitignoreAbs), { recursive: true });
25723
+ (0, import_node_fs63.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
25308
25724
  }
25309
25725
  function planFileAbs(worktreePath) {
25310
- return (0, import_node_path61.join)(worktreePath, PLAN_FILE_REL);
25726
+ return (0, import_node_path62.join)(worktreePath, PLAN_FILE_REL);
25311
25727
  }
25312
25728
  function readTextIfPresent2(abs) {
25313
- if (!(0, import_node_fs62.existsSync)(abs)) return null;
25729
+ if (!(0, import_node_fs63.existsSync)(abs)) return null;
25314
25730
  try {
25315
- const content = (0, import_node_fs62.readFileSync)(abs, "utf8");
25731
+ const content = (0, import_node_fs63.readFileSync)(abs, "utf8");
25316
25732
  return content.trim() ? content : null;
25317
25733
  } catch {
25318
25734
  return null;
25319
25735
  }
25320
25736
  }
25321
25737
  function readPlanFile(worktreePath) {
25322
- return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path61.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path61.join)(worktreePath, LEGACY_PLAN_FILE_REL));
25738
+ return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path62.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path62.join)(worktreePath, LEGACY_PLAN_FILE_REL));
25323
25739
  }
25324
25740
  function writePlanFile(worktreePath, content) {
25325
25741
  ensureAttachmentsGitignore(worktreePath);
25326
25742
  const abs = planFileAbs(worktreePath);
25327
- (0, import_node_fs62.mkdirSync)((0, import_node_path61.dirname)(abs), { recursive: true });
25743
+ (0, import_node_fs63.mkdirSync)((0, import_node_path62.dirname)(abs), { recursive: true });
25328
25744
  const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
25329
- (0, import_node_fs62.writeFileSync)(abs, body, "utf8");
25745
+ (0, import_node_fs63.writeFileSync)(abs, body, "utf8");
25330
25746
  return PLAN_FILE_REL;
25331
25747
  }
25332
- var import_node_fs62, import_node_path61;
25748
+ var import_node_fs63, import_node_path62;
25333
25749
  var init_plan_file = __esm({
25334
25750
  "src/plan/plan-file.ts"() {
25335
25751
  "use strict";
25336
- import_node_fs62 = require("fs");
25337
- import_node_path61 = require("path");
25752
+ import_node_fs63 = require("fs");
25753
+ import_node_path62 = require("path");
25338
25754
  init_workspace_scratch();
25339
25755
  init_plan_present();
25340
25756
  init_plan_present();
@@ -25383,7 +25799,7 @@ function setCaffeinateHoldHooks(next) {
25383
25799
  hooks = next;
25384
25800
  }
25385
25801
  function caffeinateHoldPath() {
25386
- return (0, import_node_path62.join)(appDataDir(), "caffeinate-hold.json");
25802
+ return (0, import_node_path63.join)(appDataDir(), "caffeinate-hold.json");
25387
25803
  }
25388
25804
  function processAlive(pid) {
25389
25805
  if (hooks.processAlive) return hooks.processAlive(pid);
@@ -25417,9 +25833,9 @@ function uniqueIds(ids) {
25417
25833
  }
25418
25834
  function readHold() {
25419
25835
  const path = caffeinateHoldPath();
25420
- if (!(0, import_node_fs63.existsSync)(path)) return null;
25836
+ if (!(0, import_node_fs64.existsSync)(path)) return null;
25421
25837
  try {
25422
- const parsed = JSON.parse((0, import_node_fs63.readFileSync)(path, "utf8"));
25838
+ const parsed = JSON.parse((0, import_node_fs64.readFileSync)(path, "utf8"));
25423
25839
  if (typeof parsed?.pid === "number" && parsed.pid > 0) {
25424
25840
  return {
25425
25841
  pid: parsed.pid,
@@ -25441,7 +25857,7 @@ function writeHold(pid, threadIds) {
25441
25857
  }
25442
25858
  function clearHold() {
25443
25859
  try {
25444
- (0, import_node_fs63.unlinkSync)(caffeinateHoldPath());
25860
+ (0, import_node_fs64.unlinkSync)(caffeinateHoldPath());
25445
25861
  } catch {
25446
25862
  }
25447
25863
  }
@@ -25526,13 +25942,13 @@ function releaseCaffeinateHoldForThread(threadId) {
25526
25942
  }
25527
25943
  return setCaffeinateHold(false, { threadId: id });
25528
25944
  }
25529
- var import_node_child_process6, import_node_fs63, import_node_path62, hooks;
25945
+ var import_node_child_process6, import_node_fs64, import_node_path63, hooks;
25530
25946
  var init_caffeinate_hold = __esm({
25531
25947
  "src/store/caffeinate-hold.ts"() {
25532
25948
  "use strict";
25533
25949
  import_node_child_process6 = require("child_process");
25534
- import_node_fs63 = require("fs");
25535
- import_node_path62 = require("path");
25950
+ import_node_fs64 = require("fs");
25951
+ import_node_path63 = require("path");
25536
25952
  init_paths();
25537
25953
  init_private_file();
25538
25954
  hooks = {};
@@ -25541,7 +25957,7 @@ var init_caffeinate_hold = __esm({
25541
25957
 
25542
25958
  // src/store/schedules.ts
25543
25959
  function schedulesPath() {
25544
- return (0, import_node_path63.join)(appDataDir(), "schedules.json");
25960
+ return (0, import_node_path64.join)(appDataDir(), "schedules.json");
25545
25961
  }
25546
25962
  function parseDurationMs(every) {
25547
25963
  const m = every.trim().match(DURATION_RE);
@@ -25641,9 +26057,9 @@ function normalizeTask(raw) {
25641
26057
  }
25642
26058
  function readAll2() {
25643
26059
  const path = schedulesPath();
25644
- if (!(0, import_node_fs64.existsSync)(path)) return [];
26060
+ if (!(0, import_node_fs65.existsSync)(path)) return [];
25645
26061
  try {
25646
- const parsed = JSON.parse((0, import_node_fs64.readFileSync)(path, "utf8"));
26062
+ const parsed = JSON.parse((0, import_node_fs65.readFileSync)(path, "utf8"));
25647
26063
  if (!Array.isArray(parsed)) return [];
25648
26064
  return parsed.map((row) => {
25649
26065
  try {
@@ -25768,13 +26184,13 @@ function recordScheduleRun(id, result) {
25768
26184
  writeAll2(rows);
25769
26185
  return next;
25770
26186
  }
25771
- var import_node_crypto15, import_node_fs64, import_node_path63, import_croner, DURATION_RE, UNIT_MS;
26187
+ var import_node_crypto15, import_node_fs65, import_node_path64, import_croner, DURATION_RE, UNIT_MS;
25772
26188
  var init_schedules = __esm({
25773
26189
  "src/store/schedules.ts"() {
25774
26190
  "use strict";
25775
26191
  import_node_crypto15 = require("crypto");
25776
- import_node_fs64 = require("fs");
25777
- import_node_path63 = require("path");
26192
+ import_node_fs65 = require("fs");
26193
+ import_node_path64 = require("path");
25778
26194
  import_croner = require("croner");
25779
26195
  init_orchestrator_capable();
25780
26196
  init_paths();
@@ -25923,9 +26339,9 @@ function recoverFinishedCursorRun(opts) {
25923
26339
  return best;
25924
26340
  }
25925
26341
  function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
25926
- if (!(0, import_node_fs65.existsSync)(runsPath)) return null;
26342
+ if (!(0, import_node_fs66.existsSync)(runsPath)) return null;
25927
26343
  try {
25928
- const lines = (0, import_node_fs65.readFileSync)(runsPath, "utf8").split("\n");
26344
+ const lines = (0, import_node_fs66.readFileSync)(runsPath, "utf8").split("\n");
25929
26345
  let best = null;
25930
26346
  for (const line of lines) {
25931
26347
  const trimmed = line.trim();
@@ -25951,11 +26367,11 @@ function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
25951
26367
  return null;
25952
26368
  }
25953
26369
  }
25954
- var import_node_fs65;
26370
+ var import_node_fs66;
25955
26371
  var init_cursor_recover = __esm({
25956
26372
  "src/agents/cursor-recover.ts"() {
25957
26373
  "use strict";
25958
- import_node_fs65 = require("fs");
26374
+ import_node_fs66 = require("fs");
25959
26375
  init_cursor_store();
25960
26376
  }
25961
26377
  });
@@ -26078,7 +26494,7 @@ async function startOrchestration(opts) {
26078
26494
  }
26079
26495
  return updated;
26080
26496
  }
26081
- var import_node_events, import_node_crypto16, import_node_fs66, LIVE_TURN_SPAWN_GRACE_MS, RUN_SCRIPT_DESKTOP_ADOPT_MS, STALE_AGENT_PID_WAIT_MS, LIGHT_RECONCILE_THROTTLE_MS, Orchestrator, singleton;
26497
+ var import_node_events, import_node_crypto16, import_node_fs67, LIVE_TURN_SPAWN_GRACE_MS, RUN_SCRIPT_DESKTOP_ADOPT_MS, STALE_AGENT_PID_WAIT_MS, LIGHT_RECONCILE_THROTTLE_MS, Orchestrator, singleton;
26082
26498
  var init_orchestrator = __esm({
26083
26499
  "src/orchestrator/orchestrator.ts"() {
26084
26500
  "use strict";
@@ -26087,7 +26503,7 @@ var init_orchestrator = __esm({
26087
26503
  init_task_state();
26088
26504
  init_wait_for_turn();
26089
26505
  import_node_crypto16 = require("crypto");
26090
- import_node_fs66 = require("fs");
26506
+ import_node_fs67 = require("fs");
26091
26507
  init_error_detail();
26092
26508
  init_run();
26093
26509
  init_stale_lock();
@@ -26275,7 +26691,7 @@ var init_orchestrator = __esm({
26275
26691
  this.lightReconcileAt.set(repoPath, Date.now());
26276
26692
  for (const thread of listThreads()) {
26277
26693
  if (isGlobalThread(thread) || thread.repoPath !== repoPath) continue;
26278
- if (!(0, import_node_fs66.existsSync)(thread.worktreePath)) {
26694
+ if (!(0, import_node_fs67.existsSync)(thread.worktreePath)) {
26279
26695
  setStatus(thread.id, "broken", "Worktree missing on disk");
26280
26696
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
26281
26697
  }
@@ -26304,7 +26720,7 @@ var init_orchestrator = __esm({
26304
26720
  }
26305
26721
  continue;
26306
26722
  }
26307
- if (!(0, import_node_fs66.existsSync)(thread.worktreePath)) {
26723
+ if (!(0, import_node_fs67.existsSync)(thread.worktreePath)) {
26308
26724
  setStatus(thread.id, "broken", "Worktree missing on disk");
26309
26725
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
26310
26726
  continue;
@@ -28114,7 +28530,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
28114
28530
  return thread;
28115
28531
  }
28116
28532
  const start = Date.now();
28117
- return new Promise((resolve2, reject) => {
28533
+ return new Promise((resolve3, reject) => {
28118
28534
  let settled = false;
28119
28535
  let timer;
28120
28536
  const finish = (fn) => {
@@ -28132,7 +28548,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
28132
28548
  finish(() => reject(new Error(`Thread not found: ${thread.id}`)));
28133
28549
  return;
28134
28550
  }
28135
- finish(() => resolve2(latest));
28551
+ finish(() => resolve3(latest));
28136
28552
  return;
28137
28553
  }
28138
28554
  if (event.type === "status_changed") {
@@ -28142,7 +28558,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
28142
28558
  return;
28143
28559
  }
28144
28560
  if (!["running", "queued"].includes(latest.status)) {
28145
- finish(() => resolve2(latest));
28561
+ finish(() => resolve3(latest));
28146
28562
  }
28147
28563
  }
28148
28564
  });
@@ -28154,12 +28570,12 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
28154
28570
  }
28155
28571
  const current = this.healStaleReportedActivity(raw);
28156
28572
  if (!this.threadLooksLive(current)) {
28157
- finish(() => resolve2(current));
28573
+ finish(() => resolve3(current));
28158
28574
  return;
28159
28575
  }
28160
28576
  if (Date.now() - start > timeoutMs) {
28161
28577
  if (opts?.resolveIfStillRunning) {
28162
- finish(() => resolve2(current));
28578
+ finish(() => resolve3(current));
28163
28579
  } else {
28164
28580
  finish(() => reject(new Error("wait_for_turn timed out")));
28165
28581
  }
@@ -28652,6 +29068,11 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
28652
29068
  if (!next) throw new Error("Title cannot be empty");
28653
29069
  return updateThread(thread.id, { title: next, userSetTitle: true });
28654
29070
  }
29071
+ dismissAskUser(threadRef, signature) {
29072
+ const thread = this.requireThread(threadRef);
29073
+ dismissAskUserQuestion(thread.id, signature);
29074
+ return this.requireThread(thread.id);
29075
+ }
28655
29076
  setWorkspaceTags(threadRef, tags) {
28656
29077
  return applyWorkspaceTags(threadRef, tags, "replace");
28657
29078
  }
@@ -28783,7 +29204,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
28783
29204
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
28784
29205
  return restored2;
28785
29206
  }
28786
- if (!(0, import_node_fs66.existsSync)(thread.worktreePath)) {
29207
+ if (!(0, import_node_fs67.existsSync)(thread.worktreePath)) {
28787
29208
  if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
28788
29209
  throw new Error(
28789
29210
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
@@ -28974,7 +29395,7 @@ function createClippedMcpServer() {
28974
29395
  // src/mcp/server.ts
28975
29396
  var import_zod11 = require("zod");
28976
29397
  var import_node_crypto20 = require("crypto");
28977
- var import_node_path67 = require("path");
29398
+ var import_node_path68 = require("path");
28978
29399
  init_orchestrator();
28979
29400
  init_task_state();
28980
29401
  init_worktree();
@@ -30963,14 +31384,14 @@ function orchCreateThreadAgentNote(input) {
30963
31384
  var MAX_ORCH_THREADS = 5;
30964
31385
  var CREATE_THREAD_TIMEOUT_MS = 9e4;
30965
31386
  function withTimeout2(promise, ms, label) {
30966
- return new Promise((resolve2, reject) => {
31387
+ return new Promise((resolve3, reject) => {
30967
31388
  const timer = setTimeout(() => {
30968
31389
  reject(new Error(`${label} timed out after ${Math.round(ms / 1e3)}s`));
30969
31390
  }, ms);
30970
31391
  promise.then(
30971
31392
  (value) => {
30972
31393
  clearTimeout(timer);
30973
- resolve2(value);
31394
+ resolve3(value);
30974
31395
  },
30975
31396
  (err) => {
30976
31397
  clearTimeout(timer);
@@ -32472,7 +32893,7 @@ function registerScheduleTools(server) {
32472
32893
 
32473
32894
  // src/agent-rpc/handlers.ts
32474
32895
  var import_node_crypto18 = require("crypto");
32475
- var import_node_path64 = require("path");
32896
+ var import_node_path65 = require("path");
32476
32897
  init_wait_for_job();
32477
32898
  init_wait_for_turn();
32478
32899
 
@@ -32516,7 +32937,7 @@ setToolPermissionPublisher({
32516
32937
  });
32517
32938
 
32518
32939
  // src/agent-rpc/handlers.ts
32519
- init_protocol();
32940
+ init_protocol2();
32520
32941
  function presentArtifactResult(input) {
32521
32942
  const id = input.artifact_id?.trim() || `artifact_${Date.now().toString(36)}_${(0, import_node_crypto18.randomUUID)().slice(0, 8)}`;
32522
32943
  return {
@@ -32537,27 +32958,27 @@ init_gh_errors();
32537
32958
  init_git_auth_mode();
32538
32959
 
32539
32960
  // src/board/load-home-board.ts
32540
- var import_node_fs68 = require("fs");
32541
- var import_node_path66 = require("path");
32961
+ var import_node_fs69 = require("fs");
32962
+ var import_node_path67 = require("path");
32542
32963
  init_worktree();
32543
32964
  init_paths();
32544
32965
 
32545
32966
  // src/board/board-pins.ts
32546
32967
  var import_node_crypto19 = require("crypto");
32547
- var import_node_fs67 = require("fs");
32548
- var import_node_path65 = require("path");
32968
+ var import_node_fs68 = require("fs");
32969
+ var import_node_path66 = require("path");
32549
32970
  init_paths();
32550
32971
  init_home_board();
32551
32972
  var FILE = "home-board-pins.json";
32552
32973
  var VERSION = 1;
32553
32974
  function pinsFile() {
32554
- return (0, import_node_path65.join)(appDataDir(), FILE);
32975
+ return (0, import_node_path66.join)(appDataDir(), FILE);
32555
32976
  }
32556
32977
  function readDisk() {
32557
32978
  const path = pinsFile();
32558
- if (!(0, import_node_fs67.existsSync)(path)) return [];
32979
+ if (!(0, import_node_fs68.existsSync)(path)) return [];
32559
32980
  try {
32560
- const raw = JSON.parse((0, import_node_fs67.readFileSync)(path, "utf8"));
32981
+ const raw = JSON.parse((0, import_node_fs68.readFileSync)(path, "utf8"));
32561
32982
  if (raw?.version !== VERSION || !Array.isArray(raw.items)) return [];
32562
32983
  return raw.items.filter((item) => item?.id && item.kind && item.ref);
32563
32984
  } catch {
@@ -32565,8 +32986,8 @@ function readDisk() {
32565
32986
  }
32566
32987
  }
32567
32988
  function writeDisk(items) {
32568
- (0, import_node_fs67.mkdirSync)(appDataDir(), { recursive: true });
32569
- (0, import_node_fs67.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
32989
+ (0, import_node_fs68.mkdirSync)(appDataDir(), { recursive: true });
32990
+ (0, import_node_fs68.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
32570
32991
  }
32571
32992
  function listBoardPins() {
32572
32993
  return readDisk();
@@ -32587,7 +33008,7 @@ function homeBoardWorkspaceKey(workspaces) {
32587
33008
  return workspaces.map((w) => w.path).filter(Boolean).sort().join("\n");
32588
33009
  }
32589
33010
  function cacheFile() {
32590
- return (0, import_node_path66.join)(appDataDir(), "home-board-cache.json");
33011
+ return (0, import_node_path67.join)(appDataDir(), "home-board-cache.json");
32591
33012
  }
32592
33013
  function emptyInputs() {
32593
33014
  return {
@@ -32613,9 +33034,9 @@ function shouldCacheHomeBoardInputs(inputs) {
32613
33034
  }
32614
33035
  function readDiskCache() {
32615
33036
  const path = cacheFile();
32616
- if (!(0, import_node_fs68.existsSync)(path)) return null;
33037
+ if (!(0, import_node_fs69.existsSync)(path)) return null;
32617
33038
  try {
32618
- const raw = JSON.parse((0, import_node_fs68.readFileSync)(path, "utf8"));
33039
+ const raw = JSON.parse((0, import_node_fs69.readFileSync)(path, "utf8"));
32619
33040
  if (raw?.version !== CACHE_VERSION || typeof raw.fetchedAt !== "number") {
32620
33041
  return null;
32621
33042
  }
@@ -32629,8 +33050,8 @@ function readDiskCache() {
32629
33050
  }
32630
33051
  function writeDiskCache(entry) {
32631
33052
  try {
32632
- (0, import_node_fs68.mkdirSync)(appDataDir(), { recursive: true });
32633
- (0, import_node_fs68.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
33053
+ (0, import_node_fs69.mkdirSync)(appDataDir(), { recursive: true });
33054
+ (0, import_node_fs69.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
32634
33055
  } catch {
32635
33056
  }
32636
33057
  }
@@ -32885,7 +33306,7 @@ async function startMcpServer() {
32885
33306
  async () => {
32886
33307
  const threads = orch.getThreads();
32887
33308
  const lines = threads.map((t) => {
32888
- const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path67.basename)(t.repoPath) || t.repoPath;
33309
+ const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path68.basename)(t.repoPath) || t.repoPath;
32889
33310
  const live = orch.threadLooksLive(t) ? readTurnLive(t.id) : null;
32890
33311
  const parent = t.parentThreadId ? ` parent:${t.parentThreadId.slice(0, 8)}` : "";
32891
33312
  const preview = lastMessagePreview(t.messages, 80);