@sideboard-ai/core 0.1.295 → 0.1.296

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 (40) hide show
  1. package/dist/agents/claude-runner.cjs +55 -0
  2. package/dist/agents/claude-runner.js +57 -1
  3. package/dist/agents/cursor-runner.js +2 -2
  4. package/dist/{agents-S55DBAVO.js → agents-DZTPUKVF.js} +4 -4
  5. package/dist/{agents-EFHYZUZT.js → agents-ICHYDSCD.js} +5 -5
  6. package/dist/{chunk-ABLHTRRG.js → chunk-2O3ICR77.js} +3 -3
  7. package/dist/{chunk-KCP6IVRI.js → chunk-67BWWLEB.js} +4 -4
  8. package/dist/{chunk-RWIYYFID.js → chunk-6GTABVNG.js} +4 -4
  9. package/dist/{chunk-YEIPPZ5W.js → chunk-BGEECLKH.js} +2 -2
  10. package/dist/{chunk-ER6BGGME.js → chunk-J54UPHXZ.js} +1 -1
  11. package/dist/{chunk-ZEP6JIRF.js → chunk-JWXJXEA3.js} +1 -1
  12. package/dist/{chunk-NYBFYFK7.js → chunk-QDA6NXRA.js} +1 -0
  13. package/dist/{chunk-YFKAC4LB.js → chunk-QT36F4TD.js} +54 -25
  14. package/dist/{chunk-YRXV3E7J.js → chunk-TVN4TDFB.js} +9 -0
  15. package/dist/{chunk-6SGYGYH7.js → chunk-VXNZG4J6.js} +1 -1
  16. package/dist/{chunk-XXT3C2EF.js → chunk-W2A63ZOK.js} +176 -39
  17. package/dist/{chunk-E7G7RY6T.js → chunk-WQREAX35.js} +2 -2
  18. package/dist/{chunk-QB5MDOHL.js → chunk-WZLV4WNS.js} +9 -0
  19. package/dist/{chunk-HWIIRVYE.js → chunk-ZXWRNA4G.js} +4 -4
  20. package/dist/{conductor-GURU5XD7.js → conductor-HJFDYIZD.js} +4 -4
  21. package/dist/{conductor-HT2UANDY.js → conductor-ZXDIA6OF.js} +4 -4
  22. package/dist/{coordinator-prompt-AROMFCP2.js → coordinator-prompt-ILHSVPOG.js} +3 -3
  23. package/dist/{coordinator-prompt-K6XHUG3N.js → coordinator-prompt-L3V2CMWX.js} +3 -3
  24. package/dist/{global-workspace-4WAU4PAL.js → global-workspace-47G453ZU.js} +3 -3
  25. package/dist/{global-workspace-PX4GUVLW.js → global-workspace-NMRUGGFF.js} +3 -3
  26. package/dist/index.cjs +1014 -698
  27. package/dist/index.d.cts +25 -4
  28. package/dist/index.d.ts +25 -4
  29. package/dist/index.js +282 -119
  30. package/dist/mcp/run-stdio.cjs +201 -118
  31. package/dist/mcp/run-stdio.js +46 -8
  32. package/dist/{orchestrator-VNSEXL62.js → orchestrator-MR7TCIPP.js} +6 -6
  33. package/dist/{orchestrator-VDYZSZWY.js → orchestrator-ZQU62CES.js} +7 -7
  34. package/dist/{thread-store-DPKESDFR.js → thread-store-H6D6MDUM.js} +1 -1
  35. package/dist/{thread-store-X6S2GIR5.js → thread-store-SADLLKRE.js} +1 -1
  36. package/dist/{workspaces-MFU3IGAP.js → workspaces-PGY4UWZ3.js} +3 -3
  37. package/dist/{workspaces-U7SSD27C.js → workspaces-WGZPRQJX.js} +3 -3
  38. package/dist/{worktree-TQKASYPZ.js → worktree-3MF5J5XZ.js} +2 -2
  39. package/dist/{worktree-2VSHRI72.js → worktree-JZXDAKQF.js} +2 -2
  40. package/package.json +1 -1
@@ -14,7 +14,7 @@ import {
14
14
  parseSessionQuotaResetAt,
15
15
  planModeTurnInstruction,
16
16
  resolveQuotaFallbackAgent
17
- } from "./chunk-RWIYYFID.js";
17
+ } from "./chunk-6GTABVNG.js";
18
18
  import {
19
19
  REVIEW_TAB_TITLE,
20
20
  applyWorktreePkgCacheEnv,
@@ -53,7 +53,7 @@ import {
53
53
  worktreeDevProcessKey,
54
54
  worktreeRunProcessKey,
55
55
  worktreeSetupProcessKey
56
- } from "./chunk-KCP6IVRI.js";
56
+ } from "./chunk-67BWWLEB.js";
57
57
  import {
58
58
  applyAgentEvent,
59
59
  clipAgentEventForPaint,
@@ -100,7 +100,7 @@ import {
100
100
  stageAbsolutePathsAsAttachments,
101
101
  stageBuffersAsAttachments,
102
102
  syncWorkspacesFromThreads
103
- } from "./chunk-YEIPPZ5W.js";
103
+ } from "./chunk-BGEECLKH.js";
104
104
  import {
105
105
  addPrStackLayer,
106
106
  allocateTeamSlug,
@@ -142,7 +142,7 @@ import {
142
142
  resolveRepoRoot,
143
143
  switchWorktreeBranch,
144
144
  withRepoGitLock
145
- } from "./chunk-ZEP6JIRF.js";
145
+ } from "./chunk-JWXJXEA3.js";
146
146
  import {
147
147
  agentNicknameFromWorktreePath,
148
148
  appendMessage,
@@ -166,7 +166,7 @@ import {
166
166
  worktreeNameFromPath,
167
167
  worktreeSlugForTicket,
168
168
  writeThread
169
- } from "./chunk-QB5MDOHL.js";
169
+ } from "./chunk-WZLV4WNS.js";
170
170
  import {
171
171
  createAgentStreamCoalescer
172
172
  } from "./chunk-AXQ4ZWHK.js";
@@ -299,7 +299,7 @@ function formatInjectedNoticesForTurn(notices) {
299
299
  }
300
300
 
301
301
  // src/orchestrator/orchestrator.ts
302
- import { randomUUID as randomUUID4 } from "crypto";
302
+ import { randomUUID as randomUUID5 } from "crypto";
303
303
  import { existsSync as existsSync14 } from "fs";
304
304
 
305
305
  // src/agents/spawn.ts
@@ -451,9 +451,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
451
451
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
452
452
  );
453
453
  }
454
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-4WAU4PAL.js");
454
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-47G453ZU.js");
455
455
  if (isGlobalThread2(thread)) {
456
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-AROMFCP2.js");
456
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-ILHSVPOG.js");
457
457
  ensureGlobalCoordinatorCwd2(
458
458
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
459
459
  );
@@ -493,6 +493,7 @@ async function spawnAgentTurn(thread, input, onEvent) {
493
493
  }
494
494
  applyManagedAccountEnv(env, thread.agent, resolveAccountForThread(thread, accounts));
495
495
  sanitizeAgentHostEnv(env, cmd.cwd);
496
+ env[SIDEBOARD_THREAD_ID_ENV] = thread.id;
496
497
  ensureAgentPath(env);
497
498
  applyPromptCacheTtlEnv(thread.agent, env);
498
499
  applyAgentRunnerHeapEnv(env);
@@ -1475,6 +1476,137 @@ function thisProcessShouldDrainAgentQueues() {
1475
1476
  return !isDesktopHostAlive();
1476
1477
  }
1477
1478
 
1479
+ // src/agents/tool-permission.ts
1480
+ import { randomUUID } from "crypto";
1481
+ import { dirname } from "path";
1482
+ var queues = /* @__PURE__ */ new Map();
1483
+ var publisher = null;
1484
+ function setToolPermissionPublisher(next) {
1485
+ publisher = next;
1486
+ }
1487
+ function clean(value) {
1488
+ return typeof value === "string" ? value.trim() : "";
1489
+ }
1490
+ function pathFromToolInput(input) {
1491
+ if (!input) return "";
1492
+ for (const key of ["file_path", "filePath", "path", "notebook_path", "target_file"]) {
1493
+ const value = clean(input[key]);
1494
+ if (value) return value;
1495
+ }
1496
+ return "";
1497
+ }
1498
+ function describeToolPermission(ask) {
1499
+ const path = clean(ask.blockedPath) || pathFromToolInput(ask.input);
1500
+ const action = clean(ask.displayName) || clean(ask.toolName) || "this action";
1501
+ const title = clean(ask.title) || (path ? `Allow ${action} on ${path}?` : `Allow ${action}?`);
1502
+ return { title, detail: clean(ask.description), path };
1503
+ }
1504
+ function denied(message) {
1505
+ return { behavior: "deny", message, decisionClassification: "user_reject" };
1506
+ }
1507
+ function sessionGrants(item) {
1508
+ if (Array.isArray(item.suggestions) && item.suggestions.length > 0) {
1509
+ return item.suggestions;
1510
+ }
1511
+ const dir = directoryGrant(item);
1512
+ if (!dir) return void 0;
1513
+ return [{ type: "addDirectories", directories: [dir], destination: "session" }];
1514
+ }
1515
+ function directoryGrant(item) {
1516
+ const stored = item.prompt;
1517
+ const path = stored.path ?? "";
1518
+ if (!path) return "";
1519
+ if (path.endsWith("/") || path.endsWith("\\")) return path;
1520
+ const dir = dirname(path);
1521
+ return dir && dir !== "." ? dir : path;
1522
+ }
1523
+ function toAnswer(item, decision) {
1524
+ if (decision === "deny") {
1525
+ return denied("The user denied this action.");
1526
+ }
1527
+ if (decision === "allow_session" && item.prompt.allowSession) {
1528
+ return {
1529
+ behavior: "allow",
1530
+ updatedPermissions: sessionGrants(item),
1531
+ decisionClassification: "user_permanent"
1532
+ };
1533
+ }
1534
+ return { behavior: "allow", decisionClassification: "user_temporary" };
1535
+ }
1536
+ function showPrompt(item) {
1537
+ if (!publisher) return false;
1538
+ return publisher.show({ threadId: item.threadId, prompt: item.prompt });
1539
+ }
1540
+ function clearPrompt(threadId, id) {
1541
+ publisher?.clear(threadId, id);
1542
+ }
1543
+ function finish(item, answer) {
1544
+ const q = queues.get(item.threadId) ?? [];
1545
+ const idx = q.findIndex((row) => row.id === item.id);
1546
+ if (idx >= 0) q.splice(idx, 1);
1547
+ if (q.length === 0) queues.delete(item.threadId);
1548
+ else queues.set(item.threadId, q);
1549
+ item.resolve(answer);
1550
+ const next = idx === 0 ? q[0] : void 0;
1551
+ if (next) activate(next);
1552
+ else if (q.length === 0) clearPrompt(item.threadId, item.id);
1553
+ }
1554
+ function activate(item) {
1555
+ if (!publisher) {
1556
+ finish(item, denied("Sideboard could not show a permission prompt."));
1557
+ return;
1558
+ }
1559
+ if (!showPrompt(item)) finish(item, denied("That chat is not on this Mac."));
1560
+ }
1561
+ function askToolPermission(ask) {
1562
+ const threadId = clean(ask.threadId);
1563
+ const toolName = clean(ask.toolName);
1564
+ if (!threadId || !toolName) return Promise.resolve(denied("Missing chat or tool."));
1565
+ const described = describeToolPermission({ ...ask, threadId, toolName });
1566
+ const prompt = {
1567
+ id: randomUUID(),
1568
+ title: described.title,
1569
+ detail: described.detail,
1570
+ path: described.path || void 0,
1571
+ allowSession: !ask.suppressAlwaysAllow,
1572
+ defaultToNo: Boolean(ask.defaultToNo)
1573
+ };
1574
+ return new Promise((resolve) => {
1575
+ const item = {
1576
+ id: prompt.id,
1577
+ threadId,
1578
+ prompt,
1579
+ suggestions: ask.suggestions,
1580
+ resolve
1581
+ };
1582
+ const q = queues.get(threadId) ?? [];
1583
+ q.push(item);
1584
+ queues.set(threadId, q);
1585
+ if (q.length === 1) activate(item);
1586
+ });
1587
+ }
1588
+ function answerToolPermission(id, decision) {
1589
+ const key = clean(id);
1590
+ if (!key) return false;
1591
+ for (const q of queues.values()) {
1592
+ const item = q.find((row) => row.id === key);
1593
+ if (!item) continue;
1594
+ finish(item, toAnswer(item, decision));
1595
+ return true;
1596
+ }
1597
+ return false;
1598
+ }
1599
+ function denyPendingToolPermissions(threadId) {
1600
+ const q = queues.get(threadId);
1601
+ if (!q?.length) return;
1602
+ const pending = q.splice(0, q.length);
1603
+ queues.delete(threadId);
1604
+ const answer = denied("The turn ended before this was allowed.");
1605
+ for (const item of pending) item.resolve(answer);
1606
+ const last = pending[pending.length - 1];
1607
+ if (last) clearPrompt(threadId, last.id);
1608
+ }
1609
+
1478
1610
  // src/orchestrator/notify-orchestrator.ts
1479
1611
  var MAX_NOTIFY_ORCHESTRATOR_MESSAGE_CHARS = 1500;
1480
1612
  var inputRequiredNotified = /* @__PURE__ */ new Set();
@@ -1628,6 +1760,7 @@ function writeAgentBlock(threadId, block) {
1628
1760
  updateThread(threadId, { agentBlock: block });
1629
1761
  }
1630
1762
  function settleAgentBlock(threadId, parts, failed) {
1763
+ denyPendingToolPermissions(threadId);
1631
1764
  const thread = readThread(threadId);
1632
1765
  if (!thread || thread.status === "archived") return;
1633
1766
  const next = agentBlockAfterTurn({
@@ -1741,13 +1874,13 @@ function writeStoppedStatus(threadId, reason) {
1741
1874
  }
1742
1875
 
1743
1876
  // src/orchestrator/steer-request.ts
1744
- import { randomUUID } from "crypto";
1877
+ import { randomUUID as randomUUID2 } from "crypto";
1745
1878
  function isUnclaimedSteerRequest(req) {
1746
1879
  return Boolean(req?.requestId && !req.claimedAt);
1747
1880
  }
1748
1881
  function nextSteerRequest(existing) {
1749
1882
  if (existing?.requestId && !existing.claimedAt) return existing;
1750
- return { requestId: randomUUID(), requestedAt: (/* @__PURE__ */ new Date()).toISOString() };
1883
+ return { requestId: randomUUID2(), requestedAt: (/* @__PURE__ */ new Date()).toISOString() };
1751
1884
  }
1752
1885
  function claimSteerRequest(threadId) {
1753
1886
  const pending = readThread(threadId)?.steerRequest;
@@ -1760,7 +1893,6 @@ function claimSteerRequest(threadId) {
1760
1893
  // src/threads/agent-purpose-title.ts
1761
1894
  function agentPurposeStamp(input) {
1762
1895
  if (input.autoContinue) return null;
1763
- if (input.thread.sourceType === "orchestration") return null;
1764
1896
  if (input.thread.title.trim() === REVIEW_TAB_TITLE) return null;
1765
1897
  const identities = worktreeIdentityTitles(input.thread);
1766
1898
  const titled = input.thread.title?.trim() || "";
@@ -2740,7 +2872,7 @@ async function createThread(input, _onSetupLine) {
2740
2872
  return readThread(thread.id) ?? thread;
2741
2873
  }
2742
2874
  async function listLinearIssues(agent, repoPath) {
2743
- const { getAdapter: getAdapter2 } = await import("./agents-EFHYZUZT.js");
2875
+ const { getAdapter: getAdapter2 } = await import("./agents-ICHYDSCD.js");
2744
2876
  await requireAgent(agent, { requireLinear: true });
2745
2877
  const adapter = getAdapter2(agent);
2746
2878
  if (!adapter.listLinearIssues) {
@@ -2991,7 +3123,7 @@ async function forkThreadWorktree(input, onSetupLine) {
2991
3123
  }
2992
3124
 
2993
3125
  // src/orchestrator/quota-failover.ts
2994
- import { randomUUID as randomUUID2 } from "crypto";
3126
+ import { randomUUID as randomUUID3 } from "crypto";
2995
3127
  function managedKindForAgent(agent) {
2996
3128
  return agent === "claude" || agent === "codex" ? agent : null;
2997
3129
  }
@@ -3111,7 +3243,7 @@ function buildQuotaHandoffAttachment(from, limitText, fallbackAgent) {
3111
3243
  ...instructions
3112
3244
  ].join("\n");
3113
3245
  return {
3114
- id: randomUUID2(),
3246
+ id: randomUUID3(),
3115
3247
  name: orch ? "Orchestration quota handoff.md" : "Quota handoff.md",
3116
3248
  kind: "transcript",
3117
3249
  content: body
@@ -3251,7 +3383,7 @@ async function adoptThread(input) {
3251
3383
  messages: input.messages ?? []
3252
3384
  });
3253
3385
  writeThread(thread);
3254
- const { addWorkspace: addWorkspace2 } = await import("./workspaces-U7SSD27C.js");
3386
+ const { addWorkspace: addWorkspace2 } = await import("./workspaces-WGZPRQJX.js");
3255
3387
  await addWorkspace2(repoPath);
3256
3388
  const { ensureWorktreeSideboardIgnored } = await import("./worktree-exclude-RXZPTCNH.js");
3257
3389
  await ensureWorktreeSideboardIgnored(input.worktreePath);
@@ -3747,7 +3879,7 @@ function stackAgentDefaultsFrom(input) {
3747
3879
 
3748
3880
  // src/diff/diff.ts
3749
3881
  import { existsSync as existsSync9, mkdirSync, readFileSync as readFileSync6, statSync as statSync2, writeFileSync as writeFileSync5 } from "fs";
3750
- import { dirname, join as join8 } from "path";
3882
+ import { dirname as dirname2, join as join8 } from "path";
3751
3883
  async function inspectGitWorktree(worktreePath) {
3752
3884
  if (!worktreePath || !existsSync9(worktreePath)) return "missing_worktree";
3753
3885
  const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
@@ -4476,7 +4608,7 @@ function assertSafeRelativePath(relativePath) {
4476
4608
  function writeWorktreeFile(worktreePath, relativePath, content) {
4477
4609
  assertSafeRelativePath(relativePath);
4478
4610
  const abs = join8(worktreePath, relativePath);
4479
- mkdirSync(dirname(abs), { recursive: true });
4611
+ mkdirSync(dirname2(abs), { recursive: true });
4480
4612
  writeFileSync5(abs, content, "utf8");
4481
4613
  return { path: relativePath };
4482
4614
  }
@@ -5142,7 +5274,7 @@ import { join as join12 } from "path";
5142
5274
 
5143
5275
  // src/skills/detached-job-path.ts
5144
5276
  import { existsSync as existsSync11 } from "fs";
5145
- import { dirname as dirname2, join as join11 } from "path";
5277
+ import { dirname as dirname3, join as join11 } from "path";
5146
5278
  import { fileURLToPath } from "url";
5147
5279
  var DETACHED_JOB_FILENAMES = ["detached-job.cjs", "detached-job.js"];
5148
5280
  function compiledModuleDir() {
@@ -5151,7 +5283,7 @@ function compiledModuleDir() {
5151
5283
  try {
5152
5284
  const url = import.meta.url;
5153
5285
  if (typeof url === "string" && url.length > 0) {
5154
- return dirname2(fileURLToPath(url));
5286
+ return dirname3(fileURLToPath(url));
5155
5287
  }
5156
5288
  } catch {
5157
5289
  }
@@ -5177,7 +5309,7 @@ function resolveDetachedJobScript() {
5177
5309
  for (let i = 0; i < 8; i++) {
5178
5310
  const candidate = detachedJobScriptIn(dir);
5179
5311
  if (candidate) return candidate;
5180
- const parent = dirname2(dir);
5312
+ const parent = dirname3(dir);
5181
5313
  if (parent === dir) break;
5182
5314
  dir = parent;
5183
5315
  }
@@ -5911,7 +6043,7 @@ async function syncThreadBranchFromGit(threadId) {
5911
6043
  }
5912
6044
 
5913
6045
  // src/store/schedules.ts
5914
- import { randomUUID as randomUUID3 } from "crypto";
6046
+ import { randomUUID as randomUUID4 } from "crypto";
5915
6047
  import { existsSync as existsSync13, readFileSync as readFileSync8 } from "fs";
5916
6048
  import { join as join13 } from "path";
5917
6049
  import { Cron } from "croner";
@@ -6056,7 +6188,7 @@ function buildTask(input, now) {
6056
6188
  const ts = nowIso(now);
6057
6189
  const agent = input.agent ? coerceOrchestratorAgent(input.agent) : null;
6058
6190
  return {
6059
- id: randomUUID3(),
6191
+ id: randomUUID4(),
6060
6192
  name: input.name?.trim() || defaultScheduleName(prompt),
6061
6193
  prompt,
6062
6194
  enabled: input.enabled !== false,
@@ -6170,7 +6302,7 @@ function formatScheduledPrompt(name, prompt) {
6170
6302
  ${prompt}`;
6171
6303
  }
6172
6304
  async function defaultDeps() {
6173
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-VDYZSZWY.js");
6305
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-ZQU62CES.js");
6174
6306
  const orch = getOrchestrator2();
6175
6307
  return {
6176
6308
  findThread: (id) => findThreadByRef(id),
@@ -7883,7 +8015,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
7883
8015
  const request = sameIntent ? pending : {
7884
8016
  op,
7885
8017
  scriptName: scriptName ?? null,
7886
- requestId: randomUUID4(),
8018
+ requestId: randomUUID5(),
7887
8019
  requestedAt: (/* @__PURE__ */ new Date()).toISOString()
7888
8020
  };
7889
8021
  if (!sameIntent) {
@@ -8144,7 +8276,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
8144
8276
  this.emit({ type: "setup_output", threadId: thread.id, line: chunk });
8145
8277
  });
8146
8278
  let finished = false;
8147
- const finish = (exitCode, source) => {
8279
+ const finish2 = (exitCode, source) => {
8148
8280
  if (finished) return;
8149
8281
  finished = true;
8150
8282
  output.flush();
@@ -8164,7 +8296,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
8164
8296
  if (!setup.ran) {
8165
8297
  const line = "No setup script in .sideboard/settings.toml, .conductor/settings.toml, .cursor/worktrees.json, or script/setup (bin/setup, scripts/setup)";
8166
8298
  output.push(line);
8167
- finish(null, null);
8299
+ finish2(null, null);
8168
8300
  throw new Error(line);
8169
8301
  }
8170
8302
  if (setup.exitCode !== 0 && setup.exitCode !== null) {
@@ -8179,10 +8311,10 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
8179
8311
  });
8180
8312
  }
8181
8313
  }
8182
- finish(setup.exitCode, setup.source);
8314
+ finish2(setup.exitCode, setup.source);
8183
8315
  return { exitCode: setup.exitCode, source: setup.source };
8184
8316
  } catch (err) {
8185
- finish(null, null);
8317
+ finish2(null, null);
8186
8318
  throw err;
8187
8319
  } finally {
8188
8320
  this.processes.delete(key);
@@ -8263,7 +8395,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
8263
8395
  return new Promise((resolve, reject) => {
8264
8396
  let settled = false;
8265
8397
  let timer;
8266
- const finish = (fn) => {
8398
+ const finish2 = (fn) => {
8267
8399
  if (settled) return;
8268
8400
  settled = true;
8269
8401
  if (timer) clearInterval(timer);
@@ -8275,39 +8407,39 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
8275
8407
  if (event.type === "turn_finished" || event.type === "error") {
8276
8408
  const latest = readThread(thread.id);
8277
8409
  if (!latest) {
8278
- finish(() => reject(new Error(`Thread not found: ${thread.id}`)));
8410
+ finish2(() => reject(new Error(`Thread not found: ${thread.id}`)));
8279
8411
  return;
8280
8412
  }
8281
- finish(() => resolve(latest));
8413
+ finish2(() => resolve(latest));
8282
8414
  return;
8283
8415
  }
8284
8416
  if (event.type === "status_changed") {
8285
8417
  const latest = readThread(thread.id);
8286
8418
  if (!latest) {
8287
- finish(() => reject(new Error(`Thread not found: ${thread.id}`)));
8419
+ finish2(() => reject(new Error(`Thread not found: ${thread.id}`)));
8288
8420
  return;
8289
8421
  }
8290
8422
  if (!["running", "queued"].includes(latest.status)) {
8291
- finish(() => resolve(latest));
8423
+ finish2(() => resolve(latest));
8292
8424
  }
8293
8425
  }
8294
8426
  });
8295
8427
  timer = setInterval(() => {
8296
8428
  const raw = readThread(thread.id);
8297
8429
  if (!raw) {
8298
- finish(() => reject(new Error(`Thread not found: ${thread.id}`)));
8430
+ finish2(() => reject(new Error(`Thread not found: ${thread.id}`)));
8299
8431
  return;
8300
8432
  }
8301
8433
  const current = this.healStaleReportedActivity(raw);
8302
8434
  if (!this.threadLooksLive(current)) {
8303
- finish(() => resolve(current));
8435
+ finish2(() => resolve(current));
8304
8436
  return;
8305
8437
  }
8306
8438
  if (Date.now() - start > timeoutMs) {
8307
8439
  if (opts?.resolveIfStillRunning) {
8308
- finish(() => resolve(current));
8440
+ finish2(() => resolve(current));
8309
8441
  } else {
8310
- finish(() => reject(new Error("wait_for_turn timed out")));
8442
+ finish2(() => reject(new Error("wait_for_turn timed out")));
8311
8443
  }
8312
8444
  }
8313
8445
  }, 200);
@@ -9042,7 +9174,7 @@ async function startOrchestration(opts) {
9042
9174
  sourceRef: "default",
9043
9175
  ...createOpts
9044
9176
  }).catch(async () => {
9045
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-TQKASYPZ.js");
9177
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-3MF5J5XZ.js");
9046
9178
  const repo = await resolveRepoRoot2(repoPath);
9047
9179
  const def = await resolveDefaultBranch2(repo);
9048
9180
  return orch.createThread({
@@ -9052,7 +9184,7 @@ async function startOrchestration(opts) {
9052
9184
  repoPath: repo
9053
9185
  });
9054
9186
  });
9055
- const { updateThread: upd } = await import("./thread-store-X6S2GIR5.js");
9187
+ const { updateThread: upd } = await import("./thread-store-SADLLKRE.js");
9056
9188
  const updated = upd(thread.id, {
9057
9189
  sourceType: "orchestration",
9058
9190
  sourceRef: goal
@@ -9066,6 +9198,9 @@ async function startOrchestration(opts) {
9066
9198
  export {
9067
9199
  isUnclaimedRunScriptRequest,
9068
9200
  isAdoptableRunScriptRequest,
9201
+ setToolPermissionPublisher,
9202
+ askToolPermission,
9203
+ answerToolPermission,
9069
9204
  worktreeBoardStatus,
9070
9205
  visibleAgentBlock,
9071
9206
  worktreeAgentBlock,
@@ -9143,6 +9278,8 @@ export {
9143
9278
  shouldNotifyOrchestrator,
9144
9279
  resolveNotifyCallerThread,
9145
9280
  notifyOrchestrator,
9281
+ clampBlockReason,
9282
+ writeAgentBlock,
9146
9283
  chatBlockedSuffix,
9147
9284
  agentBlockFields,
9148
9285
  stampAskUserBlock,
@@ -5,7 +5,7 @@ import {
5
5
  ensureGhPreferOrigin,
6
6
  resolveGithubRepoSlug,
7
7
  resolveRepoRoot
8
- } from "./chunk-6SGYGYH7.js";
8
+ } from "./chunk-VXNZG4J6.js";
9
9
  import {
10
10
  ATTACHMENTS_DIR,
11
11
  attachmentsGitignoreBody
@@ -31,7 +31,7 @@ import {
31
31
  teamSlugFromName,
32
32
  updateThread,
33
33
  writeThread
34
- } from "./chunk-YRXV3E7J.js";
34
+ } from "./chunk-TVN4TDFB.js";
35
35
  import {
36
36
  appDataDir,
37
37
  globalAgentCwd,
@@ -871,9 +871,18 @@ function branchDisplayLabel(branchName, worktreePath) {
871
871
  }
872
872
  return branchName.trim();
873
873
  }
874
+ function taskPurposeTitle(title) {
875
+ const trimmed = title?.trim() ?? "";
876
+ if (!trimmed || teamSlugFromName(trimmed)) return null;
877
+ return trimmed;
878
+ }
874
879
  function threadDisplayLabel(thread) {
875
880
  if (thread.userSetTitle && thread.title?.trim()) return thread.title.trim();
876
881
  if (thread.prTitle?.trim()) return thread.prTitle.trim();
882
+ if (isPlaceholderBranch(thread.branchName, thread.worktreePath)) {
883
+ const purpose = taskPurposeTitle(thread.title);
884
+ if (purpose) return purpose;
885
+ }
877
886
  return branchDisplayLabel(thread.branchName, thread.worktreePath);
878
887
  }
879
888
  function worktreeDisplayLabel(thread) {
@@ -11,11 +11,11 @@ import {
11
11
  isGlobalThread,
12
12
  isOrchestratorThread,
13
13
  isSlackCoordinatorThread
14
- } from "./chunk-E7G7RY6T.js";
14
+ } from "./chunk-WQREAX35.js";
15
15
  import {
16
16
  mergeAgentGitAuthEnv,
17
17
  resolveAgentGitAuthEnv
18
- } from "./chunk-6SGYGYH7.js";
18
+ } from "./chunk-VXNZG4J6.js";
19
19
  import {
20
20
  ATTACHMENTS_DIR,
21
21
  DETACHED_JOBS_DIR,
@@ -46,7 +46,7 @@ import {
46
46
  updateThread,
47
47
  worktreeNameFromPath,
48
48
  writeThread
49
- } from "./chunk-YRXV3E7J.js";
49
+ } from "./chunk-TVN4TDFB.js";
50
50
  import {
51
51
  findConventionSetup,
52
52
  loadRepoSettings,
@@ -1674,7 +1674,7 @@ var PORT_RANGE_SIZE = 10;
1674
1674
  var RECLAIM_RETRY_DELAY_MS = 40;
1675
1675
  var RECLAIM_TRIES = 8;
1676
1676
  async function killReclaimable(ports, worktreePath, signal) {
1677
- const { killListenersOnPorts: killListenersOnPorts2, killStaleWorktreeListeners: killStaleWorktreeListeners2 } = await import("./conductor-GURU5XD7.js");
1677
+ const { killListenersOnPorts: killListenersOnPorts2, killStaleWorktreeListeners: killStaleWorktreeListeners2 } = await import("./conductor-HJFDYIZD.js");
1678
1678
  if (worktreePath) killStaleWorktreeListeners2(ports, worktreePath, signal);
1679
1679
  else killListenersOnPorts2(ports);
1680
1680
  }
@@ -33,10 +33,10 @@ import {
33
33
  tryReservePort,
34
34
  tryReservePorts,
35
35
  worktreeRunPortsPath
36
- } from "./chunk-HWIIRVYE.js";
36
+ } from "./chunk-ZXWRNA4G.js";
37
37
  import "./chunk-ED4ZXQVO.js";
38
- import "./chunk-E7G7RY6T.js";
39
- import "./chunk-6SGYGYH7.js";
38
+ import "./chunk-WQREAX35.js";
39
+ import "./chunk-VXNZG4J6.js";
40
40
  import "./chunk-N2WW62LF.js";
41
41
  import "./chunk-DD67JWTN.js";
42
42
  import "./chunk-2UG25RMK.js";
@@ -47,7 +47,7 @@ import {
47
47
  } from "./chunk-WWUABK6B.js";
48
48
  import "./chunk-FJZWM2ON.js";
49
49
  import "./chunk-UN5Q7POQ.js";
50
- import "./chunk-YRXV3E7J.js";
50
+ import "./chunk-TVN4TDFB.js";
51
51
  import "./chunk-4RZRHTSZ.js";
52
52
  import "./chunk-KGZBYWZ3.js";
53
53
  import {
@@ -31,11 +31,11 @@ import {
31
31
  tryReservePort,
32
32
  tryReservePorts,
33
33
  worktreeRunPortsPath
34
- } from "./chunk-KCP6IVRI.js";
34
+ } from "./chunk-67BWWLEB.js";
35
35
  import "./chunk-Q3DPZ4DE.js";
36
- import "./chunk-YEIPPZ5W.js";
37
- import "./chunk-ZEP6JIRF.js";
38
- import "./chunk-QB5MDOHL.js";
36
+ import "./chunk-BGEECLKH.js";
37
+ import "./chunk-JWXJXEA3.js";
38
+ import "./chunk-WZLV4WNS.js";
39
39
  import "./chunk-2P4XKWV2.js";
40
40
  import "./chunk-HO5R3ZRH.js";
41
41
  import "./chunk-6K64FJDD.js";
@@ -7,9 +7,9 @@ import {
7
7
  enrichWorkspacesWithGithub,
8
8
  ensureGlobalCoordinatorCwd,
9
9
  formatWorkspaceInventory
10
- } from "./chunk-YEIPPZ5W.js";
11
- import "./chunk-ZEP6JIRF.js";
12
- import "./chunk-QB5MDOHL.js";
10
+ } from "./chunk-BGEECLKH.js";
11
+ import "./chunk-JWXJXEA3.js";
12
+ import "./chunk-WZLV4WNS.js";
13
13
  import "./chunk-2P4XKWV2.js";
14
14
  import "./chunk-6K64FJDD.js";
15
15
  import "./chunk-UWQ6UCIB.js";
@@ -9,8 +9,8 @@ import {
9
9
  enrichWorkspacesWithGithub,
10
10
  ensureGlobalCoordinatorCwd,
11
11
  formatWorkspaceInventory
12
- } from "./chunk-E7G7RY6T.js";
13
- import "./chunk-6SGYGYH7.js";
12
+ } from "./chunk-WQREAX35.js";
13
+ import "./chunk-VXNZG4J6.js";
14
14
  import "./chunk-N2WW62LF.js";
15
15
  import "./chunk-DD67JWTN.js";
16
16
  import "./chunk-2UG25RMK.js";
@@ -19,7 +19,7 @@ import "./chunk-NSTQ6QKD.js";
19
19
  import "./chunk-WWUABK6B.js";
20
20
  import "./chunk-FJZWM2ON.js";
21
21
  import "./chunk-UN5Q7POQ.js";
22
- import "./chunk-YRXV3E7J.js";
22
+ import "./chunk-TVN4TDFB.js";
23
23
  import "./chunk-4RZRHTSZ.js";
24
24
  import "./chunk-KGZBYWZ3.js";
25
25
  import "./chunk-H5XL4KUS.js";
@@ -18,9 +18,9 @@ import {
18
18
  remoteCoordinatorSourceRef,
19
19
  slackCoordinatorSourceRef,
20
20
  takenTeamSlugsForOrchestration
21
- } from "./chunk-YEIPPZ5W.js";
22
- import "./chunk-ZEP6JIRF.js";
23
- import "./chunk-QB5MDOHL.js";
21
+ } from "./chunk-BGEECLKH.js";
22
+ import "./chunk-JWXJXEA3.js";
23
+ import "./chunk-WZLV4WNS.js";
24
24
  import "./chunk-2P4XKWV2.js";
25
25
  import "./chunk-6K64FJDD.js";
26
26
  import "./chunk-UWQ6UCIB.js";
@@ -20,8 +20,8 @@ import {
20
20
  remoteCoordinatorSourceRef,
21
21
  slackCoordinatorSourceRef,
22
22
  takenTeamSlugsForOrchestration
23
- } from "./chunk-E7G7RY6T.js";
24
- import "./chunk-6SGYGYH7.js";
23
+ } from "./chunk-WQREAX35.js";
24
+ import "./chunk-VXNZG4J6.js";
25
25
  import "./chunk-N2WW62LF.js";
26
26
  import "./chunk-DD67JWTN.js";
27
27
  import "./chunk-2UG25RMK.js";
@@ -30,7 +30,7 @@ import "./chunk-NSTQ6QKD.js";
30
30
  import "./chunk-WWUABK6B.js";
31
31
  import "./chunk-FJZWM2ON.js";
32
32
  import "./chunk-UN5Q7POQ.js";
33
- import "./chunk-YRXV3E7J.js";
33
+ import "./chunk-TVN4TDFB.js";
34
34
  import "./chunk-4RZRHTSZ.js";
35
35
  import "./chunk-KGZBYWZ3.js";
36
36
  import {