@sideboard-ai/core 0.1.149 → 0.1.151

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 (60) hide show
  1. package/dist/{abletime-QEVAE67D.js → abletime-223A3LY6.js} +2 -2
  2. package/dist/{abletime-DI55AJX3.js → abletime-CLC5UJC2.js} +2 -2
  3. package/dist/agents/cursor-runner.cjs +40 -35
  4. package/dist/agents/cursor-runner.js +2 -2
  5. package/dist/{agents-V4MTDWXS.js → agents-JAOMXDXN.js} +10 -9
  6. package/dist/{agents-HSVQ2Z6Y.js → agents-U2JCFXW4.js} +10 -9
  7. package/dist/{app-settings-WJDCJFSY.js → app-settings-3CHCNIMD.js} +5 -1
  8. package/dist/{app-settings-ZCN632OJ.js → app-settings-J3JBCUOT.js} +5 -1
  9. package/dist/{chunk-N5PM7HGQ.js → chunk-2SDMENAL.js} +1 -1
  10. package/dist/{chunk-JTPDWTWJ.js → chunk-3JBMACYX.js} +137 -114
  11. package/dist/{chunk-I77RYPOH.js → chunk-4XNSGDXE.js} +12 -0
  12. package/dist/{chunk-JDYKQ6OI.js → chunk-6H4TJ5TA.js} +136 -75
  13. package/dist/{chunk-EGDRPA4B.js → chunk-77MP647F.js} +6 -6
  14. package/dist/{chunk-KBWND62T.js → chunk-7F4XE6UG.js} +5 -5
  15. package/dist/{chunk-R4JP32P5.js → chunk-ADCEGG4A.js} +4 -4
  16. package/dist/{chunk-BOD5V52W.js → chunk-B7XK37WZ.js} +1 -1
  17. package/dist/{chunk-BGQBELGJ.js → chunk-CZD4NRDZ.js} +12 -0
  18. package/dist/{chunk-KPIYENTF.js → chunk-FNQNJOHY.js} +89 -5
  19. package/dist/{chunk-ED4UPEJX.js → chunk-G7SIQFBQ.js} +1 -1
  20. package/dist/{chunk-TZWO7J4W.js → chunk-GCWAAPJ5.js} +115 -54
  21. package/dist/{chunk-YP3CSOZ6.js → chunk-GE7M3QTE.js} +142 -114
  22. package/dist/{chunk-LAFA56WD.js → chunk-HEII7W3Q.js} +1 -1
  23. package/dist/{chunk-3QRGCKYL.js → chunk-HWZWBJWL.js} +2 -2
  24. package/dist/{chunk-FKOIHGKV.js → chunk-JRH62XC4.js} +5 -1
  25. package/dist/{chunk-Q5DHVMXB.js → chunk-LZAOX76N.js} +18 -7
  26. package/dist/{chunk-B3SJXYIJ.js → chunk-NVXVEGGM.js} +1 -1
  27. package/dist/{chunk-ZVYLEF72.js → chunk-OXOU2FRS.js} +6 -6
  28. package/dist/chunk-QQKDGPUI.js +63 -0
  29. package/dist/{chunk-QTUESPAW.js → chunk-RFMQY56R.js} +1 -1
  30. package/dist/chunk-SYFVUF2C.js +65 -0
  31. package/dist/{chunk-Q62SDB53.js → chunk-TSCWSAQL.js} +2 -2
  32. package/dist/{chunk-DVM4ID64.js → chunk-UFHNSFAS.js} +89 -5
  33. package/dist/{chunk-PTI5H3RK.js → chunk-UIS7BVCX.js} +24 -13
  34. package/dist/{chunk-VZJVKQHH.js → chunk-WLV7TRMR.js} +1 -1
  35. package/dist/{chunk-N3VNOFXQ.js → chunk-Y2FNDKHF.js} +4 -4
  36. package/dist/{connected-teams-IJUJQ7R6.js → connected-teams-I2WZZZFA.js} +2 -2
  37. package/dist/{connected-teams-4A2AXDNN.js → connected-teams-XO766HB4.js} +2 -2
  38. package/dist/{coordinator-prompt-ZWBMAIWA.js → coordinator-prompt-LWYUZAXR.js} +6 -5
  39. package/dist/{coordinator-prompt-5GXGBGEZ.js → coordinator-prompt-ZK5MII7W.js} +6 -5
  40. package/dist/{global-workspace-OJRXWXEA.js → global-workspace-IB2CCEJF.js} +7 -6
  41. package/dist/{global-workspace-2SIPM4PW.js → global-workspace-T7RL3XEC.js} +7 -6
  42. package/dist/index.cjs +1010 -577
  43. package/dist/index.d.cts +96 -11
  44. package/dist/index.d.ts +96 -11
  45. package/dist/index.js +272 -93
  46. package/dist/mcp/run-stdio.cjs +981 -581
  47. package/dist/mcp/run-stdio.js +196 -43
  48. package/dist/{orchestrator-Z2O5OVJA.js → orchestrator-DPTRBKEH.js} +16 -13
  49. package/dist/{orchestrator-6TXQWBXN.js → orchestrator-Y5MWUU7C.js} +14 -11
  50. package/dist/{plan-file-6O7G4VPQ.js → plan-file-LSSSQGTQ.js} +2 -2
  51. package/dist/{plan-file-PHVKUAEE.js → plan-file-OZEBFSGQ.js} +2 -2
  52. package/dist/{run-XQKGHQZ2.js → run-CAGKZLHA.js} +1 -1
  53. package/dist/{run-USF6FRKV.js → run-EBWL2Q4N.js} +1 -1
  54. package/dist/{workspaces-UUJNOO4T.js → workspaces-VICQYI2N.js} +8 -7
  55. package/dist/{workspaces-3NUUZTQK.js → workspaces-ZXCUVCZC.js} +8 -7
  56. package/dist/{worktree-RZRJNHYL.js → worktree-DPIREDFR.js} +5 -4
  57. package/dist/{worktree-UCWWTVLS.js → worktree-HTUM35NT.js} +5 -4
  58. package/dist/worktree-exclude-N5X5I422.js +13 -0
  59. package/dist/worktree-exclude-X54WSOXM.js +11 -0
  60. package/package.json +1 -1
@@ -32,14 +32,19 @@ import {
32
32
  slackTokenFor,
33
33
  syncBoardPins,
34
34
  updateSchedule
35
- } from "../chunk-TZWO7J4W.js";
35
+ } from "../chunk-GCWAAPJ5.js";
36
36
  import {
37
+ isInternalAgentStatusText,
37
38
  listModelsForAgent,
38
39
  sideboardMcpProfile
39
- } from "../chunk-Q5DHVMXB.js";
40
- import "../chunk-ED4UPEJX.js";
40
+ } from "../chunk-LZAOX76N.js";
41
+ import "../chunk-G7SIQFBQ.js";
41
42
  import "../chunk-S42XV45P.js";
42
- import "../chunk-Q62SDB53.js";
43
+ import "../chunk-TSCWSAQL.js";
44
+ import {
45
+ GLOBAL_WORKSPACE_ID,
46
+ isCloudCoordinatorThread
47
+ } from "../chunk-Y2FNDKHF.js";
43
48
  import {
44
49
  createAbleTimeTask,
45
50
  ensureAbleTimeTask,
@@ -50,30 +55,28 @@ import {
50
55
  listAbleTimeTasks,
51
56
  searchAbleTimeTasks,
52
57
  toAbleTimeIssueInfo
53
- } from "../chunk-BOD5V52W.js";
58
+ } from "../chunk-B7XK37WZ.js";
54
59
  import {
55
60
  httpFetch
56
61
  } from "../chunk-6GN5WPYZ.js";
57
- import "../chunk-N5PM7HGQ.js";
62
+ import "../chunk-2SDMENAL.js";
58
63
  import "../chunk-KLBOWJ74.js";
59
- import {
60
- GLOBAL_WORKSPACE_ID,
61
- isCloudCoordinatorThread
62
- } from "../chunk-N3VNOFXQ.js";
63
- import "../chunk-ZVYLEF72.js";
64
+ import "../chunk-OXOU2FRS.js";
64
65
  import {
65
66
  canonicalizeRepoPath,
67
+ formatGhLandError,
66
68
  listBranches,
67
69
  listPrs,
68
70
  resolveGithubRepoSlug,
69
71
  resolveRepoRoot,
70
72
  warmGithubAgentAuth
71
- } from "../chunk-JTPDWTWJ.js";
72
- import "../chunk-B3SJXYIJ.js";
73
+ } from "../chunk-3JBMACYX.js";
74
+ import "../chunk-NVXVEGGM.js";
73
75
  import "../chunk-EUXOHTUK.js";
76
+ import "../chunk-SYFVUF2C.js";
74
77
  import {
75
78
  gh
76
- } from "../chunk-KPIYENTF.js";
79
+ } from "../chunk-FNQNJOHY.js";
77
80
  import {
78
81
  disconnectLinearConnection,
79
82
  dropNestedElectronEnvFromProcess,
@@ -82,7 +85,7 @@ import {
82
85
  loadAppSettings,
83
86
  resolveEffectiveIssueSource,
84
87
  saveLinearOAuth
85
- } from "../chunk-BGQBELGJ.js";
88
+ } from "../chunk-CZD4NRDZ.js";
86
89
  import "../chunk-NSTQ6QKD.js";
87
90
  import "../chunk-KGZBYWZ3.js";
88
91
  import {
@@ -273,6 +276,22 @@ query SideboardAssignedIssues($first: Int!) {
273
276
  }
274
277
  }
275
278
  `;
279
+ var ISSUES_QUERY = `
280
+ query SideboardIssues($first: Int!, $filter: IssueFilter) {
281
+ viewer { id name }
282
+ issues(first: $first, orderBy: updatedAt, filter: $filter) {
283
+ nodes { ${LIST_ISSUE_FIELDS} }
284
+ }
285
+ }
286
+ `;
287
+ var SEARCH_ISSUES_QUERY = `
288
+ query SideboardSearchIssues($term: String!, $first: Int!, $filter: IssueFilter) {
289
+ viewer { id name }
290
+ searchIssues(term: $term, first: $first, includeArchived: false, filter: $filter) {
291
+ nodes { ${LIST_ISSUE_FIELDS} }
292
+ }
293
+ }
294
+ `;
276
295
  var TEAMS_QUERY = `
277
296
  query SideboardTeams {
278
297
  viewer { id name }
@@ -556,19 +575,73 @@ function normalizePriority(priority) {
556
575
  }
557
576
  return priority;
558
577
  }
559
- async function listLinearAssignedIssues(opts) {
560
- const first = Math.max(1, Math.min(250, opts?.limit ?? 200));
561
- const json = await linearGraphql(ASSIGNED_ISSUES_QUERY, { first }, opts);
578
+ var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
579
+ function assigneeFilterKey(assignee) {
580
+ return (assignee ?? "").trim();
581
+ }
582
+ function buildLinearIssueFilter(input) {
583
+ const filter = {
584
+ state: { type: { nin: ["completed", "canceled"] } }
585
+ };
586
+ const raw = assigneeFilterKey(input?.assignee) || "me";
587
+ const key = raw.toLowerCase();
588
+ if (key === "all" || key === "*") return filter;
589
+ if (key === "unassigned" || key === "none" || key === "null") {
590
+ filter.assignee = { null: true };
591
+ return filter;
592
+ }
593
+ if (key === "me" || key === "@me") {
594
+ filter.assignee = { isMe: true };
595
+ return filter;
596
+ }
597
+ if (UUID_RE.test(raw)) {
598
+ filter.assignee = { id: { eq: raw } };
599
+ return filter;
600
+ }
601
+ filter.assignee = { name: { eqIgnoreCase: raw } };
602
+ return filter;
603
+ }
604
+ function isAssignedToMe(assignee) {
605
+ const key = assignee.toLowerCase();
606
+ return key === "me" || key === "@me";
607
+ }
608
+ function listedLinearIssues(json, nodes) {
562
609
  return {
563
610
  viewer: {
564
611
  id: String(json.viewer?.id ?? ""),
565
612
  name: String(json.viewer?.name ?? "")
566
613
  },
567
- issues: (json.viewer?.assignedIssues?.nodes ?? []).map(
568
- (node) => toIssueInfo(mapIssue(node))
569
- )
614
+ issues: (nodes ?? []).map((node) => toIssueInfo(mapIssue(node)))
570
615
  };
571
616
  }
617
+ async function listLinearIssuesFiltered(opts) {
618
+ const first = Math.max(1, Math.min(250, opts?.limit ?? 200));
619
+ const query = opts?.query?.trim() ?? "";
620
+ const assignee = assigneeFilterKey(opts?.assignee) || (query ? "all" : "me");
621
+ const filter = buildLinearIssueFilter({ assignee });
622
+ if (query) {
623
+ const json2 = await linearGraphql(
624
+ SEARCH_ISSUES_QUERY,
625
+ { term: query, first, filter },
626
+ opts
627
+ );
628
+ return listedLinearIssues(json2, json2.searchIssues?.nodes);
629
+ }
630
+ if (isAssignedToMe(assignee)) {
631
+ const json2 = await linearGraphql(
632
+ ASSIGNED_ISSUES_QUERY,
633
+ { first },
634
+ opts
635
+ );
636
+ return listedLinearIssues(json2, json2.viewer?.assignedIssues?.nodes);
637
+ }
638
+ const json = await linearGraphql(
639
+ ISSUES_QUERY,
640
+ { first, filter },
641
+ opts
642
+ );
643
+ return listedLinearIssues(json, json.issues?.nodes);
644
+ }
572
645
  async function listLinearTeams(opts) {
573
646
  const json = await linearGraphql(TEAMS_QUERY, void 0, opts);
574
647
  return {
@@ -675,6 +748,22 @@ async function commentLinearIssue(input, opts) {
675
748
  }
676
749
 
677
750
  // src/integrations/issues.ts
751
+ function assigneeKey(assignee) {
752
+ return (assignee ?? "").trim().toLowerCase();
753
+ }
754
+ function issueMatchesAssignee(issue, assignee, viewerName = "") {
755
+ const key = assigneeKey(assignee);
756
+ if (!key || key === "all" || key === "*") return true;
757
+ const names = [...issue.assignees ?? [], issue.assignee ?? ""].map((name) => name.trim().toLowerCase()).filter(Boolean);
758
+ if (key === "unassigned" || key === "none" || key === "null") {
759
+ return names.length === 0;
760
+ }
761
+ if (key === "me" || key === "@me") {
762
+ const me = viewerName.trim().toLowerCase();
763
+ return Boolean(me && names.includes(me));
764
+ }
765
+ return names.includes(key);
766
+ }
678
767
  async function listGitHubIssues(repoPath, opts) {
679
768
  const limit = Math.max(1, Math.min(1e3, opts?.limit ?? 200));
680
769
  const slug = await resolveGithubRepoSlug(repoPath);
@@ -688,6 +777,17 @@ async function listGitHubIssues(repoPath, opts) {
688
777
  "--state",
689
778
  "open"
690
779
  ];
780
+ const query = opts?.query?.trim() ?? "";
781
+ const assignee = opts?.assignee?.trim() ?? "";
782
+ const key = assignee.toLowerCase();
783
+ const searchParts = [];
784
+ if (query) searchParts.push(query);
785
+ if (key === "unassigned" || key === "none" || key === "null") {
786
+ searchParts.push("no:assignee");
787
+ } else if (key && key !== "all" && key !== "*") {
788
+ args.push("--assignee", key === "me" || key === "@me" ? "@me" : assignee);
789
+ }
790
+ if (searchParts.length) args.push("--search", searchParts.join(" "));
691
791
  if (slug) args.push("--repo", slug);
692
792
  const { stdout, exitCode } = await gh(args, repoPath, { reject: false });
693
793
  if (exitCode !== 0 || !stdout.trim()) return [];
@@ -725,14 +825,20 @@ async function githubViewerLogin(repoPath) {
725
825
  if (exitCode !== 0) return "";
726
826
  return stdout.trim();
727
827
  }
728
- async function listIssues(repoPath) {
828
+ async function listIssues(repoPath, opts) {
729
829
  const settings = loadAppSettings();
730
830
  const preferredSource = settings.integrations.issueSource ?? "github";
731
831
  const linearConnected = isLinearConnected(settings);
732
832
  const abletimeConnected = isAbleTimeConnected(settings);
733
833
  const source = resolveEffectiveIssueSource(settings);
834
+ const query = opts?.query?.trim() || void 0;
835
+ const assignee = opts?.assignee?.trim() || void 0;
734
836
  if (source === "linear") {
735
- const listed = await listLinearAssignedIssues();
837
+ const listed = await listLinearIssuesFiltered({
838
+ assignee,
839
+ query,
840
+ limit: opts?.limit
841
+ });
736
842
  return {
737
843
  source,
738
844
  preferredSource,
@@ -746,13 +852,20 @@ async function listIssues(repoPath) {
746
852
  };
747
853
  }
748
854
  if (source === "abletime") {
749
- const listed = await listAbleTimeAssignedIssues();
855
+ const [listed, searched] = await Promise.all([
856
+ listAbleTimeAssignedIssues(),
857
+ query ? searchAbleTimeTasks(query) : Promise.resolve(null)
858
+ ]);
859
+ const viewerName = listed.viewer.name ?? listed.viewer.id ?? "";
860
+ const issues2 = (searched ? searched.map(toAbleTimeIssueInfo) : listed.issues).filter(
861
+ (issue) => issueMatchesAssignee(issue, assignee, viewerName)
862
+ );
750
863
  return {
751
864
  source,
752
865
  preferredSource,
753
866
  linearConnected,
754
867
  abletimeConnected,
755
- issues: listed.issues,
868
+ issues: issues2,
756
869
  viewer: {
757
870
  login: listed.viewer.name,
758
871
  name: listed.viewer.name
@@ -760,7 +873,7 @@ async function listIssues(repoPath) {
760
873
  };
761
874
  }
762
875
  const [issues, login] = await Promise.all([
763
- listGitHubIssues(repoPath),
876
+ listGitHubIssues(repoPath, { assignee, query, limit: opts?.limit }),
764
877
  githubViewerLogin(repoPath)
765
878
  ]);
766
879
  return {
@@ -808,7 +921,7 @@ function lastMessagePreview(messages, max = 160) {
808
921
  if (!messages?.length) return null;
809
922
  for (let i = messages.length - 1; i >= 0; i--) {
810
923
  const text5 = messages[i]?.text?.trim();
811
- if (!text5) continue;
924
+ if (!text5 || isInternalAgentStatusText(text5)) continue;
812
925
  const flat = text5.replace(/\s+/g, " ");
813
926
  return flat.length > max ? `${flat.slice(0, max)}\u2026` : flat;
814
927
  }
@@ -1473,6 +1586,22 @@ function registerLinearTools(server) {
1473
1586
  }
1474
1587
  }
1475
1588
  );
1589
+ server.tool(
1590
+ "linear_search_issues",
1591
+ "Search or list open Linear issues. Not limited to the current user \u2014 pass assignee=unassigned for issues with no owner, assignee=all (default when query is set) for anyone including unassigned, assignee=me for yours, or a user id / name. Optional query uses Linear search (title, identifier, description).",
1592
+ {
1593
+ query: z3.string().optional().describe("Search text (identifier, title, description). Omit to list by assignee only."),
1594
+ assignee: z3.string().optional().describe("me, unassigned, all, a Linear user id, or a display name. Default: all when query is set, otherwise me."),
1595
+ limit: z3.number().int().positive().max(250).optional()
1596
+ },
1597
+ async ({ query, assignee, limit }) => {
1598
+ try {
1599
+ return text3(await listLinearIssuesFiltered({ query, assignee, limit }));
1600
+ } catch (err) {
1601
+ return fail3(err);
1602
+ }
1603
+ }
1604
+ );
1476
1605
  server.tool(
1477
1606
  "linear_get_issue",
1478
1607
  "Get a Linear issue by uuid or identifier (ENG-123). Returns description, comments, relations (blocks/blockedBy/related/duplicate), parent/children, project, cycle, labels, and other metadata.",
@@ -2036,7 +2165,7 @@ async function startMcpServer() {
2036
2165
  );
2037
2166
  }
2038
2167
  try {
2039
- const { maxConcurrentAgents } = await import("../app-settings-ZCN632OJ.js");
2168
+ const { maxConcurrentAgents } = await import("../app-settings-J3JBCUOT.js");
2040
2169
  orch.setMaxConcurrent(maxConcurrentAgents());
2041
2170
  } catch {
2042
2171
  }
@@ -2081,12 +2210,12 @@ async function startMcpServer() {
2081
2210
  const threads = orch.getThreads(true);
2082
2211
  const lines = threads.map((t) => {
2083
2212
  const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : basename(t.repoPath) || t.repoPath;
2084
- const live = t.status === "running" || t.status === "queued" ? readTurnLive(t.id) : null;
2213
+ const live = orch.threadLooksLive(t) ? readTurnLive(t.id) : null;
2085
2214
  const parent = t.parentThreadId ? ` parent:${t.parentThreadId.slice(0, 8)}` : "";
2086
2215
  const preview = lastMessagePreview(t.messages, 80);
2087
2216
  const previewBit = preview ? ` ${preview}` : "";
2088
2217
  const err = t.lastError ? ` error:${t.lastError.replace(/\s+/g, " ").slice(0, 60)}` : "";
2089
- const progress = live?.summary ? ` ${live.summary}` : "";
2218
+ const progress = live?.summary && !isInternalAgentStatusText(live.summary) ? ` ${live.summary}` : "";
2090
2219
  return `${t.id.slice(0, 8)} ${t.status.padEnd(9)} ${t.agent.padEnd(8)} ${repo} ${t.sourceType}:${t.sourceRef} ${t.title}${parent}${previewBit}${err} sideboard://thread/${t.id}${t.devPort ? ` http://localhost:${t.devPort}` : ""}${progress}`;
2091
2220
  });
2092
2221
  return {
@@ -2148,7 +2277,9 @@ async function startMcpServer() {
2148
2277
  if (!t) {
2149
2278
  return { content: [{ type: "text", text: `Thread not found: ${ref}` }], isError: true };
2150
2279
  }
2151
- const live = t.status === "running" || t.status === "queued" ? readTurnLive(t.id) : null;
2280
+ const stillRunning = orch.threadLooksLive(t);
2281
+ const live = stillRunning ? readTurnLive(t.id) : null;
2282
+ const liveSummary = live?.summary && !isInternalAgentStatusText(live.summary) ? live.summary : null;
2152
2283
  const spend = orch.getThreadUsage(t.id);
2153
2284
  const summary = {
2154
2285
  id: t.id,
@@ -2168,8 +2299,8 @@ async function startMcpServer() {
2168
2299
  devPort: t.devPort,
2169
2300
  prUrl: t.prUrl,
2170
2301
  lastError: t.lastError ?? null,
2171
- stillRunning: t.status === "running" || t.status === "queued",
2172
- progress: live?.summary ?? (t.status === "queued" ? "Queued \u2014 waiting for a concurrency slot" : null),
2302
+ stillRunning,
2303
+ progress: liveSummary ?? (stillRunning && t.status === "queued" ? "Queued \u2014 waiting for a concurrency slot" : null),
2173
2304
  lastActivityAt: live?.updatedAt ?? null,
2174
2305
  usage: spend.usage,
2175
2306
  lastTurnUsage: spend.lastTurnUsage
@@ -2245,7 +2376,7 @@ async function startMcpServer() {
2245
2376
  thread_id: z5.string().optional().describe("Sideboard thread id when cwd is not the worktree")
2246
2377
  },
2247
2378
  async ({ title, content, thread_id }) => {
2248
- const { writePlanFile } = await import("../plan-file-PHVKUAEE.js");
2379
+ const { writePlanFile } = await import("../plan-file-OZEBFSGQ.js");
2249
2380
  let root = process.cwd();
2250
2381
  if (thread_id?.trim()) {
2251
2382
  const t = orch.getThread(thread_id.trim());
@@ -2318,7 +2449,7 @@ async function startMcpServer() {
2318
2449
  registerAbleTimeTools(server);
2319
2450
  registerScheduleTools(server);
2320
2451
  const { getCaffeinateHold, setCaffeinateHold } = await import("../caffeinate-hold-NBRUWYXO.js");
2321
- const { resolveNewThreadOptions, resolveThreadDefaults } = await import("../app-settings-ZCN632OJ.js");
2452
+ const { resolveNewThreadOptions, resolveThreadDefaults } = await import("../app-settings-J3JBCUOT.js");
2322
2453
  const accountDefaults = resolveThreadDefaults();
2323
2454
  const accountDefaultsHint = `Account defaults: agent=${accountDefaults.agent}, model=${accountDefaults.model?.trim() || "Auto"}, effort=${accountDefaults.effort}`;
2324
2455
  server.tool(
@@ -2526,7 +2657,7 @@ async function startMcpServer() {
2526
2657
  );
2527
2658
  server.tool(
2528
2659
  "wait_for_turn",
2529
- "Wait until the thread finishes its current/queued turn, or return early with a live progress snapshot. MCP clients often kill tools around 60s, so this returns within 45s even while the child is still working. If stillRunning is true, progress is tools/thinking (or \u201Cqueued, waiting for a concurrency slot\u201D if it has not started). Call wait_for_turn again. Do not send a check-in prompt, force_stop, or assume a hang. On status error, lastError/text is the failure. On status stopped or broken, the child did not finish \u2014 resume with send_to_thread or tell the user; do not treat that as success. When finished, usage is the last agent turn\u2019s tokens + costUsd (when the provider reported cost).",
2660
+ "Wait until the thread finishes its current/queued turn, or return early with a live progress snapshot. MCP clients often kill tools around 60s, so this returns within 45s even while the child is still working. stillRunning is the source of truth \u2014 if false, the child is not working (do not say it is waiting for a gate). If stillRunning is true, progress is tools/thinking (or \u201Cqueued, waiting for a concurrency slot\u201D if it has not started). Call wait_for_turn again. Do not send a check-in prompt, force_stop, or assume a hang. On status error, lastError/text is the failure. On status stopped or broken, the child did not finish \u2014 resume with send_to_thread or tell the user; do not treat that as success. When finished, usage is the last agent turn\u2019s tokens + costUsd (when the provider reported cost).",
2530
2661
  {
2531
2662
  ref: z5.string(),
2532
2663
  timeoutMs: z5.number().optional()
@@ -2718,7 +2849,7 @@ async function startMcpServer() {
2718
2849
  );
2719
2850
  server.tool(
2720
2851
  "ask_git",
2721
- "Commit & push, open a draft PR, resolve conflicts, or merge \u2014 same actions as the desktop git buttons. When the worktree is clean, Sideboard pushes / opens the PR itself (HTTPS via `gh` if SSH is missing). When dirty, queues the worktree agent to commit; then wait_for_turn (loop while stillRunning). Pass a worktree thread ref (not the orchestrator). action=merge only when the user explicitly asked to merge that PR. Do not run git or gh from the orchestration cwd.",
2852
+ "Commit & push, open a draft PR, resolve conflicts, or merge \u2014 same actions as the desktop git buttons. When the worktree is clean, Sideboard pushes / opens the PR itself (HTTPS via `gh` even when origin is SSH / Settings \u2192 Git is SSH). When dirty, queues the worktree agent to commit; then wait_for_turn (loop while stillRunning). Pass a worktree thread ref (not the orchestrator). action=merge only when the user explicitly asked to merge that PR. Do not run git or gh from the orchestration cwd. If this tool errors that the GraphQL/PR body is too long, the branch is already pushed \u2014 have the worktree agent retry `gh pr create --body-file` with a short description (GitHub limit 65,536 characters). Do not invent SSH/auth failures from that error.",
2722
2853
  {
2723
2854
  ref: z5.string().describe("Worktree thread id/ref"),
2724
2855
  action: z5.enum(AGENT_GIT_ACTIONS).describe(
@@ -2743,8 +2874,26 @@ async function startMcpServer() {
2743
2874
  ]
2744
2875
  };
2745
2876
  } catch (err) {
2746
- const message = err instanceof Error ? err.message : String(err);
2747
- return { content: [{ type: "text", text: message }], isError: true };
2877
+ const raw = err instanceof Error ? err.message : String(err);
2878
+ const message = formatGhLandError(raw);
2879
+ return {
2880
+ content: [
2881
+ {
2882
+ type: "text",
2883
+ text: JSON.stringify(
2884
+ {
2885
+ error: true,
2886
+ action,
2887
+ lastError: message,
2888
+ hint: /body is too long/i.test(message) ? "Branch is already pushed. send_to_thread so the worktree agent runs gh pr create --draft -R <origin> --body-file <short.md>. Keep the description short." : void 0
2889
+ },
2890
+ null,
2891
+ 2
2892
+ )
2893
+ }
2894
+ ],
2895
+ isError: true
2896
+ };
2748
2897
  }
2749
2898
  }
2750
2899
  );
@@ -3139,11 +3288,15 @@ async function startMcpServer() {
3139
3288
  );
3140
3289
  server.tool(
3141
3290
  "list_issues",
3142
- "List issues from Sideboard Account connections (Linear, AbleTime MCP, or GitHub Issues; falls back to GitHub when the preferred tracker is not connected). Linear/AbleTime are account-wide; GitHub Issues are scoped to repoPath from list_workspaces. When AbleTime is the issue source and work has no ticket, call abletime_ensure_task (or create_thread from the default branch \u2014 Sideboard auto-creates a task to track against). Prefer list_board for Home columns. Then create_thread with sourceType=ticket.",
3143
- { repoPath: z5.string() },
3144
- async ({ repoPath }) => {
3291
+ "List or search issues from Sideboard Account connections (Linear, AbleTime MCP, or GitHub Issues; falls back to GitHub when the preferred tracker is not connected). Linear defaults to issues assigned to you; pass assignee=unassigned for no owner, assignee=all for everyone (including unassigned), or a user id / GitHub login. Optional query searches title/identifier. Linear/AbleTime are account-wide; GitHub Issues are scoped to repoPath from list_workspaces. Prefer linear_search_issues when Linear is connected and you need unassigned or other people's tickets. When AbleTime is the issue source and work has no ticket, call abletime_ensure_task (or create_thread from the default branch \u2014 Sideboard auto-creates a task to track against). Prefer list_board for Home columns. Then create_thread with sourceType=ticket.",
3292
+ {
3293
+ repoPath: z5.string(),
3294
+ query: z5.string().optional().describe("Search title, identifier, or description"),
3295
+ assignee: z5.string().optional().describe("me (Linear default), unassigned, all, a user id, or a GitHub login")
3296
+ },
3297
+ async ({ repoPath, query, assignee }) => {
3145
3298
  const root = await resolveRepoRoot(repoPath);
3146
- const result = await listIssues(root);
3299
+ const result = await listIssues(root, { query, assignee });
3147
3300
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
3148
3301
  }
3149
3302
  );
@@ -1,31 +1,34 @@
1
1
  import {
2
+ LIVE_TURN_SPAWN_GRACE_MS,
2
3
  Orchestrator,
3
4
  getOrchestrator,
4
5
  isPidAlive,
5
6
  startOrchestration,
6
7
  waitForPidExit
7
- } from "./chunk-JDYKQ6OI.js";
8
- import "./chunk-PTI5H3RK.js";
9
- import "./chunk-KBWND62T.js";
8
+ } from "./chunk-6H4TJ5TA.js";
9
+ import "./chunk-RFMQY56R.js";
10
+ import "./chunk-UIS7BVCX.js";
11
+ import "./chunk-7F4XE6UG.js";
10
12
  import "./chunk-M267JPEA.js";
11
- import "./chunk-3QRGCKYL.js";
12
- import "./chunk-R4JP32P5.js";
13
- import "./chunk-EGDRPA4B.js";
13
+ import "./chunk-HWZWBJWL.js";
14
+ import "./chunk-ADCEGG4A.js";
15
+ import "./chunk-77MP647F.js";
16
+ import "./chunk-GE7M3QTE.js";
17
+ import "./chunk-JRH62XC4.js";
14
18
  import "./chunk-ELBYOGVA.js";
15
- import "./chunk-QTUESPAW.js";
16
19
  import "./chunk-AXQ4ZWHK.js";
17
- import "./chunk-LAFA56WD.js";
18
- import "./chunk-DCOZABNT.js";
19
- import "./chunk-YP3CSOZ6.js";
20
- import "./chunk-FKOIHGKV.js";
21
- import "./chunk-I77RYPOH.js";
20
+ import "./chunk-HEII7W3Q.js";
21
+ import "./chunk-4XNSGDXE.js";
22
22
  import "./chunk-4TR3HZFT.js";
23
+ import "./chunk-DCOZABNT.js";
23
24
  import "./chunk-JT7R45JB.js";
24
25
  import "./chunk-TUGKX5BD.js";
25
26
  import "./chunk-77WWLBCI.js";
26
27
  import "./chunk-QZQEXME2.js";
27
- import "./chunk-DVM4ID64.js";
28
+ import "./chunk-QQKDGPUI.js";
29
+ import "./chunk-UFHNSFAS.js";
28
30
  export {
31
+ LIVE_TURN_SPAWN_GRACE_MS,
29
32
  Orchestrator,
30
33
  getOrchestrator,
31
34
  isPidAlive,
@@ -1,30 +1,33 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import {
4
+ LIVE_TURN_SPAWN_GRACE_MS,
4
5
  Orchestrator,
5
6
  getOrchestrator,
6
7
  isPidAlive,
7
8
  startOrchestration,
8
9
  waitForPidExit
9
- } from "./chunk-TZWO7J4W.js";
10
- import "./chunk-Q5DHVMXB.js";
11
- import "./chunk-ED4UPEJX.js";
10
+ } from "./chunk-GCWAAPJ5.js";
11
+ import "./chunk-LZAOX76N.js";
12
+ import "./chunk-G7SIQFBQ.js";
12
13
  import "./chunk-S42XV45P.js";
13
- import "./chunk-Q62SDB53.js";
14
+ import "./chunk-TSCWSAQL.js";
15
+ import "./chunk-Y2FNDKHF.js";
14
16
  import "./chunk-6GN5WPYZ.js";
15
- import "./chunk-N5PM7HGQ.js";
17
+ import "./chunk-2SDMENAL.js";
16
18
  import "./chunk-KLBOWJ74.js";
17
- import "./chunk-N3VNOFXQ.js";
18
- import "./chunk-ZVYLEF72.js";
19
- import "./chunk-JTPDWTWJ.js";
20
- import "./chunk-B3SJXYIJ.js";
19
+ import "./chunk-OXOU2FRS.js";
20
+ import "./chunk-3JBMACYX.js";
21
+ import "./chunk-NVXVEGGM.js";
21
22
  import "./chunk-EUXOHTUK.js";
22
- import "./chunk-KPIYENTF.js";
23
- import "./chunk-BGQBELGJ.js";
23
+ import "./chunk-SYFVUF2C.js";
24
+ import "./chunk-FNQNJOHY.js";
25
+ import "./chunk-CZD4NRDZ.js";
24
26
  import "./chunk-NSTQ6QKD.js";
25
27
  import "./chunk-KGZBYWZ3.js";
26
28
  import "./chunk-BD2ICC4D.js";
27
29
  export {
30
+ LIVE_TURN_SPAWN_GRACE_MS,
28
31
  Orchestrator,
29
32
  getOrchestrator,
30
33
  isPidAlive,
@@ -8,8 +8,8 @@ import {
8
8
  readPlanFile,
9
9
  resolvePlanMarkdown,
10
10
  writePlanFile
11
- } from "./chunk-QTUESPAW.js";
12
- import "./chunk-FKOIHGKV.js";
11
+ } from "./chunk-RFMQY56R.js";
12
+ import "./chunk-JRH62XC4.js";
13
13
  export {
14
14
  LEGACY_PLAN_FILE_REL,
15
15
  PLAN_FILE_NAME,
@@ -10,8 +10,8 @@ import {
10
10
  readPlanFile,
11
11
  resolvePlanMarkdown,
12
12
  writePlanFile
13
- } from "./chunk-N5PM7HGQ.js";
14
- import "./chunk-B3SJXYIJ.js";
13
+ } from "./chunk-2SDMENAL.js";
14
+ import "./chunk-NVXVEGGM.js";
15
15
  export {
16
16
  LEGACY_PLAN_FILE_REL,
17
17
  PLAN_FILE_NAME,
@@ -4,7 +4,7 @@ import {
4
4
  resolveGhAuthToken,
5
5
  resolveGitDirsForLockRecovery,
6
6
  run
7
- } from "./chunk-DVM4ID64.js";
7
+ } from "./chunk-UFHNSFAS.js";
8
8
  export {
9
9
  gh,
10
10
  git,
@@ -6,7 +6,7 @@ import {
6
6
  resolveGhAuthToken,
7
7
  resolveGitDirsForLockRecovery,
8
8
  run
9
- } from "./chunk-KPIYENTF.js";
9
+ } from "./chunk-FNQNJOHY.js";
10
10
  export {
11
11
  gh,
12
12
  git,
@@ -6,14 +6,15 @@ import {
6
6
  listWorkspaces,
7
7
  removeWorkspace,
8
8
  syncWorkspacesFromThreads
9
- } from "./chunk-Q62SDB53.js";
10
- import "./chunk-N3VNOFXQ.js";
11
- import "./chunk-ZVYLEF72.js";
12
- import "./chunk-JTPDWTWJ.js";
13
- import "./chunk-B3SJXYIJ.js";
9
+ } from "./chunk-TSCWSAQL.js";
10
+ import "./chunk-Y2FNDKHF.js";
11
+ import "./chunk-OXOU2FRS.js";
12
+ import "./chunk-3JBMACYX.js";
13
+ import "./chunk-NVXVEGGM.js";
14
14
  import "./chunk-EUXOHTUK.js";
15
- import "./chunk-KPIYENTF.js";
16
- import "./chunk-BGQBELGJ.js";
15
+ import "./chunk-SYFVUF2C.js";
16
+ import "./chunk-FNQNJOHY.js";
17
+ import "./chunk-CZD4NRDZ.js";
17
18
  import "./chunk-NSTQ6QKD.js";
18
19
  import "./chunk-KGZBYWZ3.js";
19
20
  import "./chunk-BD2ICC4D.js";
@@ -4,18 +4,19 @@ import {
4
4
  listWorkspaces,
5
5
  removeWorkspace,
6
6
  syncWorkspacesFromThreads
7
- } from "./chunk-3QRGCKYL.js";
8
- import "./chunk-R4JP32P5.js";
9
- import "./chunk-EGDRPA4B.js";
10
- import "./chunk-YP3CSOZ6.js";
11
- import "./chunk-FKOIHGKV.js";
12
- import "./chunk-I77RYPOH.js";
7
+ } from "./chunk-HWZWBJWL.js";
8
+ import "./chunk-ADCEGG4A.js";
9
+ import "./chunk-77MP647F.js";
10
+ import "./chunk-GE7M3QTE.js";
11
+ import "./chunk-JRH62XC4.js";
12
+ import "./chunk-4XNSGDXE.js";
13
13
  import "./chunk-4TR3HZFT.js";
14
14
  import "./chunk-JT7R45JB.js";
15
15
  import "./chunk-TUGKX5BD.js";
16
16
  import "./chunk-77WWLBCI.js";
17
17
  import "./chunk-QZQEXME2.js";
18
- import "./chunk-DVM4ID64.js";
18
+ import "./chunk-QQKDGPUI.js";
19
+ import "./chunk-UFHNSFAS.js";
19
20
  export {
20
21
  addWorkspace,
21
22
  ensureWorkspace,
@@ -53,15 +53,16 @@ import {
53
53
  worktreeDisplayLabel,
54
54
  worktreeDisplayLabelForGroup,
55
55
  worktreeNameFromPath
56
- } from "./chunk-YP3CSOZ6.js";
57
- import "./chunk-FKOIHGKV.js";
58
- import "./chunk-I77RYPOH.js";
56
+ } from "./chunk-GE7M3QTE.js";
57
+ import "./chunk-JRH62XC4.js";
58
+ import "./chunk-4XNSGDXE.js";
59
59
  import "./chunk-4TR3HZFT.js";
60
60
  import "./chunk-JT7R45JB.js";
61
61
  import "./chunk-TUGKX5BD.js";
62
62
  import "./chunk-77WWLBCI.js";
63
63
  import "./chunk-QZQEXME2.js";
64
- import "./chunk-DVM4ID64.js";
64
+ import "./chunk-QQKDGPUI.js";
65
+ import "./chunk-UFHNSFAS.js";
65
66
  export {
66
67
  FAMOUS_SOCCER_TEAMS,
67
68
  allocateTeamName,
@@ -55,11 +55,12 @@ import {
55
55
  worktreeDisplayLabel,
56
56
  worktreeDisplayLabelForGroup,
57
57
  worktreeNameFromPath
58
- } from "./chunk-JTPDWTWJ.js";
59
- import "./chunk-B3SJXYIJ.js";
58
+ } from "./chunk-3JBMACYX.js";
59
+ import "./chunk-NVXVEGGM.js";
60
60
  import "./chunk-EUXOHTUK.js";
61
- import "./chunk-KPIYENTF.js";
62
- import "./chunk-BGQBELGJ.js";
61
+ import "./chunk-SYFVUF2C.js";
62
+ import "./chunk-FNQNJOHY.js";
63
+ import "./chunk-CZD4NRDZ.js";
63
64
  import "./chunk-NSTQ6QKD.js";
64
65
  import "./chunk-KGZBYWZ3.js";
65
66
  import "./chunk-BD2ICC4D.js";