@sideboard-ai/core 0.1.147 → 0.1.149

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 (30) hide show
  1. package/dist/agents/cursor-runner.cjs +45 -10
  2. package/dist/agents/cursor-runner.js +46 -11
  3. package/dist/{agents-YVETHB2R.js → agents-HSVQ2Z6Y.js} +4 -4
  4. package/dist/{agents-N3KMRQUZ.js → agents-V4MTDWXS.js} +3 -3
  5. package/dist/{chunk-JHZ6HGRI.js → chunk-3QRGCKYL.js} +1 -1
  6. package/dist/{chunk-SXPTL222.js → chunk-EGDRPA4B.js} +1 -1
  7. package/dist/{chunk-ZZBN2MR7.js → chunk-JDYKQ6OI.js} +12 -12
  8. package/dist/{chunk-WT5HSFOU.js → chunk-LAFA56WD.js} +4 -1
  9. package/dist/{chunk-KNE3FZ46.js → chunk-N3VNOFXQ.js} +1 -1
  10. package/dist/{chunk-WWH4NNBH.js → chunk-PTI5H3RK.js} +3 -3
  11. package/dist/{chunk-4RYRNJPN.js → chunk-Q5DHVMXB.js} +6 -3
  12. package/dist/{chunk-JW436RTA.js → chunk-Q62SDB53.js} +1 -1
  13. package/dist/{chunk-IHSR7EVK.js → chunk-R4JP32P5.js} +1 -1
  14. package/dist/{chunk-KZG47SZP.js → chunk-TZWO7J4W.js} +11 -11
  15. package/dist/{chunk-67K3FRKR.js → chunk-ZVYLEF72.js} +1 -1
  16. package/dist/{coordinator-prompt-2EOR35TP.js → coordinator-prompt-5GXGBGEZ.js} +1 -1
  17. package/dist/{coordinator-prompt-6EPVHVGJ.js → coordinator-prompt-ZWBMAIWA.js} +1 -1
  18. package/dist/{global-workspace-PANZGRUS.js → global-workspace-2SIPM4PW.js} +2 -2
  19. package/dist/{global-workspace-EZVQPMWT.js → global-workspace-OJRXWXEA.js} +2 -2
  20. package/dist/index.cjs +151 -7
  21. package/dist/index.d.cts +50 -1
  22. package/dist/index.d.ts +50 -1
  23. package/dist/index.js +151 -11
  24. package/dist/mcp/run-stdio.cjs +149 -7
  25. package/dist/mcp/run-stdio.js +149 -10
  26. package/dist/{orchestrator-T35BJZWY.js → orchestrator-6TXQWBXN.js} +5 -5
  27. package/dist/{orchestrator-KWV2PPML.js → orchestrator-Z2O5OVJA.js} +6 -6
  28. package/dist/{workspaces-ZJATBC4A.js → workspaces-3NUUZTQK.js} +3 -3
  29. package/dist/{workspaces-DWERPUQJ.js → workspaces-UUJNOO4T.js} +3 -3
  30. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -212,7 +212,7 @@ import {
212
212
  worktreeCleanupSettings,
213
213
  wrapReviewSkillMarkdown,
214
214
  writeWorktreeFile
215
- } from "./chunk-ZZBN2MR7.js";
215
+ } from "./chunk-JDYKQ6OI.js";
216
216
  import {
217
217
  BRIGHTSY_MCP_ALLOWED_TOOLS,
218
218
  CLAUDE_MODEL_CATALOG,
@@ -294,7 +294,7 @@ import {
294
294
  withEventParentId,
295
295
  withEventsParentId,
296
296
  writeInjectedMcpConfig
297
- } from "./chunk-WWH4NNBH.js";
297
+ } from "./chunk-PTI5H3RK.js";
298
298
  import {
299
299
  brightsyMcpServerName,
300
300
  connectBrightsyTeam,
@@ -319,7 +319,7 @@ import {
319
319
  listWorkspaces,
320
320
  removeWorkspace,
321
321
  syncWorkspacesFromThreads
322
- } from "./chunk-JHZ6HGRI.js";
322
+ } from "./chunk-3QRGCKYL.js";
323
323
  import {
324
324
  CLOUD_COORDINATOR_BUSY_REPLY,
325
325
  CLOUD_COORDINATOR_STOPPED_REPLY,
@@ -354,7 +354,7 @@ import {
354
354
  stageAbsolutePathsAsAttachments,
355
355
  stageBuffersAsAttachments,
356
356
  takenTeamSlugsForOrchestration
357
- } from "./chunk-IHSR7EVK.js";
357
+ } from "./chunk-R4JP32P5.js";
358
358
  import {
359
359
  COORDINATOR_TOOL_PLAYBOOK,
360
360
  SLACK_REPLY_FORMATTING,
@@ -363,7 +363,7 @@ import {
363
363
  enrichWorkspacesWithGithub,
364
364
  ensureGlobalCoordinatorCwd,
365
365
  formatWorkspaceInventory
366
- } from "./chunk-SXPTL222.js";
366
+ } from "./chunk-EGDRPA4B.js";
367
367
  import {
368
368
  ABLETIME_MCP_PATH,
369
369
  DEFAULT_ABLETIME_HOST,
@@ -411,7 +411,7 @@ import {
411
411
  preferredCursorCostCents,
412
412
  turnCostUsdFromCursorUsage,
413
413
  withMaxOldSpaceSize
414
- } from "./chunk-WT5HSFOU.js";
414
+ } from "./chunk-LAFA56WD.js";
415
415
  import {
416
416
  caffeinateHoldPath,
417
417
  getCaffeinateHold,
@@ -984,6 +984,12 @@ var LIST_ISSUE_FIELDS = `
984
984
  labels(first: 10) { nodes { name } }
985
985
  cycle { name number startsAt endsAt completedAt }
986
986
  `;
987
+ var ISSUE_REF_FIELDS = `
988
+ id
989
+ identifier
990
+ title
991
+ url
992
+ `;
987
993
  var ISSUE_FIELDS = `
988
994
  id
989
995
  identifier
@@ -991,11 +997,46 @@ var ISSUE_FIELDS = `
991
997
  description
992
998
  url
993
999
  priority
1000
+ estimate
1001
+ dueDate
1002
+ branchName
1003
+ createdAt
1004
+ updatedAt
1005
+ completedAt
994
1006
  state { id name type }
995
1007
  assignee { id name }
1008
+ creator { id name }
996
1009
  team { id key name states(first: 50) { nodes { id name type } } }
997
1010
  labels(first: 50) { nodes { name } }
998
1011
  cycle { name number startsAt endsAt completedAt }
1012
+ project { id name }
1013
+ parent { ${ISSUE_REF_FIELDS} }
1014
+ children(first: 25) { nodes { ${ISSUE_REF_FIELDS} } }
1015
+ relations(first: 25) {
1016
+ nodes {
1017
+ type
1018
+ relatedIssue { ${ISSUE_REF_FIELDS} }
1019
+ }
1020
+ }
1021
+ inverseRelations(first: 25) {
1022
+ nodes {
1023
+ type
1024
+ issue { ${ISSUE_REF_FIELDS} }
1025
+ }
1026
+ }
1027
+ comments(first: 50) {
1028
+ nodes {
1029
+ id
1030
+ body
1031
+ url
1032
+ createdAt
1033
+ updatedAt
1034
+ user { id name }
1035
+ }
1036
+ }
1037
+ attachments(first: 20) {
1038
+ nodes { id title url subtitle }
1039
+ }
999
1040
  `;
1000
1041
  var ASSIGNED_ISSUES_QUERY = `
1001
1042
  query SideboardAssignedIssues($first: Int!) {
@@ -1123,6 +1164,82 @@ function mapCycle(node) {
1123
1164
  isActive: linearCycleIsActive(node)
1124
1165
  };
1125
1166
  }
1167
+ function mapUser(node) {
1168
+ if (!node?.id && !node?.name) return void 0;
1169
+ return {
1170
+ id: String(node.id ?? ""),
1171
+ name: String(node.name ?? "")
1172
+ };
1173
+ }
1174
+ function mapIssueRef(node) {
1175
+ if (!node?.id && !node?.identifier) return void 0;
1176
+ return {
1177
+ id: String(node.id ?? node.identifier ?? ""),
1178
+ identifier: String(node.identifier ?? node.id ?? ""),
1179
+ title: String(node.title ?? ""),
1180
+ url: String(node.url ?? "")
1181
+ };
1182
+ }
1183
+ function flipLinearRelationType(type) {
1184
+ switch (type) {
1185
+ case "blocks":
1186
+ return "blockedBy";
1187
+ case "blockedBy":
1188
+ return "blocks";
1189
+ case "duplicate":
1190
+ return "duplicateOf";
1191
+ case "duplicateOf":
1192
+ return "duplicate";
1193
+ default:
1194
+ return type;
1195
+ }
1196
+ }
1197
+ function mapRelations(node) {
1198
+ const out = [];
1199
+ for (const rel of node.relations?.nodes ?? []) {
1200
+ const issue = mapIssueRef(rel.relatedIssue);
1201
+ if (!issue) continue;
1202
+ out.push({ type: String(rel.type ?? "related"), issue });
1203
+ }
1204
+ for (const rel of node.inverseRelations?.nodes ?? []) {
1205
+ const issue = mapIssueRef(rel.issue);
1206
+ if (!issue) continue;
1207
+ out.push({ type: flipLinearRelationType(String(rel.type ?? "related")), issue });
1208
+ }
1209
+ return out;
1210
+ }
1211
+ function mapComments(node) {
1212
+ const out = [];
1213
+ for (const comment of node.comments?.nodes ?? []) {
1214
+ const id = String(comment.id ?? "");
1215
+ const body = String(comment.body ?? "");
1216
+ if (!id && !body) continue;
1217
+ out.push({
1218
+ id,
1219
+ body,
1220
+ url: comment.url?.trim() || void 0,
1221
+ createdAt: comment.createdAt?.trim() || void 0,
1222
+ updatedAt: comment.updatedAt?.trim() || void 0,
1223
+ user: mapUser(comment.user)
1224
+ });
1225
+ }
1226
+ return out;
1227
+ }
1228
+ function mapAttachments(node) {
1229
+ const out = [];
1230
+ for (const attachment of node.attachments?.nodes ?? []) {
1231
+ const id = String(attachment.id ?? "");
1232
+ const url = String(attachment.url ?? "").trim();
1233
+ if (!id && !url) continue;
1234
+ out.push({
1235
+ id,
1236
+ title: String(attachment.title ?? ""),
1237
+ url,
1238
+ subtitle: attachment.subtitle?.trim() || void 0
1239
+ });
1240
+ }
1241
+ return out;
1242
+ }
1126
1243
  function mapIssue(node) {
1127
1244
  const team = node.team;
1128
1245
  return {
@@ -1132,16 +1249,35 @@ function mapIssue(node) {
1132
1249
  url: String(node.url ?? ""),
1133
1250
  description: node.description?.trim() || void 0,
1134
1251
  priority: typeof node.priority === "number" ? node.priority : void 0,
1252
+ estimate: typeof node.estimate === "number" ? node.estimate : void 0,
1253
+ dueDate: node.dueDate?.trim() || void 0,
1254
+ branchName: node.branchName?.trim() || void 0,
1255
+ createdAt: node.createdAt?.trim() || void 0,
1256
+ updatedAt: node.updatedAt?.trim() || void 0,
1257
+ completedAt: node.completedAt?.trim() || void 0,
1135
1258
  state: mapState(node.state),
1136
- assignee: node.assignee?.id ? { id: String(node.assignee.id), name: String(node.assignee.name ?? "") } : void 0,
1259
+ assignee: mapUser(node.assignee),
1260
+ creator: mapUser(node.creator),
1137
1261
  team: team?.id ? {
1138
1262
  id: String(team.id),
1139
1263
  key: String(team.key ?? ""),
1140
1264
  name: String(team.name ?? ""),
1141
- states: (team.states?.nodes ?? []).map((s) => mapState(s)).filter((s) => Boolean(s))
1265
+ states: (team.states?.nodes ?? []).flatMap((s) => {
1266
+ const state = mapState(s);
1267
+ return state ? [state] : [];
1268
+ })
1142
1269
  } : void 0,
1143
1270
  labels: (node.labels?.nodes ?? []).map((l) => l.name).filter((n) => Boolean(n)),
1144
- cycle: mapCycle(node.cycle)
1271
+ cycle: mapCycle(node.cycle),
1272
+ project: node.project?.id ? { id: String(node.project.id), name: String(node.project.name ?? "") } : void 0,
1273
+ parent: mapIssueRef(node.parent),
1274
+ children: (node.children?.nodes ?? []).flatMap((child) => {
1275
+ const ref = mapIssueRef(child);
1276
+ return ref ? [ref] : [];
1277
+ }),
1278
+ relations: mapRelations(node),
1279
+ comments: mapComments(node),
1280
+ attachments: mapAttachments(node)
1145
1281
  };
1146
1282
  }
1147
1283
  function toIssueInfo(issue) {
@@ -1163,7 +1299,10 @@ function mapTeam(node) {
1163
1299
  id: String(node.id ?? ""),
1164
1300
  key: String(node.key ?? ""),
1165
1301
  name: String(node.name ?? ""),
1166
- states: (node.states?.nodes ?? []).map((s) => mapState(s)).filter((s) => Boolean(s))
1302
+ states: (node.states?.nodes ?? []).flatMap((s) => {
1303
+ const state = mapState(s);
1304
+ return state ? [state] : [];
1305
+ })
1167
1306
  };
1168
1307
  }
1169
1308
  function resolveLinearTeam(teams, team) {
@@ -2467,7 +2606,7 @@ function registerLinearTools(server) {
2467
2606
  );
2468
2607
  server.tool(
2469
2608
  "linear_get_issue",
2470
- "Get a Linear issue by uuid or identifier (ENG-123).",
2609
+ "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.",
2471
2610
  { id: z3.string() },
2472
2611
  async ({ id }) => {
2473
2612
  try {
@@ -6738,6 +6877,7 @@ export {
6738
6877
  findThreadForStackLayer,
6739
6878
  fireSchedule,
6740
6879
  flattenTurnInput,
6880
+ flipLinearRelationType,
6741
6881
  forkChatTab,
6742
6882
  forkMessageSlice,
6743
6883
  forkThreadWorktree,
@@ -1527,7 +1527,7 @@ function looksLikeRetryableRunnerCrash(text5) {
1527
1527
  const lower = text5.trim().toLowerCase();
1528
1528
  if (/cannot find (?:package|module)|err_module_not_found/.test(lower)) return false;
1529
1529
  if (!lower) return true;
1530
- return /uv_run|spineventloopinternal|libuv|homebrew node \+ shared libuv|cursor runner crashed in node|hascustomhostobject|electroninitializeicuandstartnode|nested chromium|truncated crash dump|connection stalled|sig(?:segv|abrt|ill)|segmentation fault|illegal instruction|fatal error/.test(
1530
+ return /uv_run|spineventloopinternal|libuv|homebrew node \+ shared libuv|cursor runner crashed in node|hascustomhostobject|electroninitializeicuandstartnode|nested chromium|truncated crash dump|connection stalled|network request failed|cursor startup failed:.+\(retryable\)|sig(?:segv|abrt|ill)|segmentation fault|illegal instruction|fatal error/.test(
1531
1531
  lower
1532
1532
  );
1533
1533
  }
@@ -1595,6 +1595,9 @@ function humanizeAgentFailDetail(detail) {
1595
1595
  if (/connection stalled/.test(lower)) {
1596
1596
  return /retry the turn/i.test(raw) ? raw : `${raw} \u2014 retry the turn (Sideboard will start a fresh Cursor session).`;
1597
1597
  }
1598
+ if (/network request failed|cursor startup failed:.+\(retryable\)/.test(lower)) {
1599
+ return /retry the turn/i.test(raw) ? raw : `${raw} \u2014 retry the turn (a transient Cursor SDK network error).`;
1600
+ }
1598
1601
  return raw;
1599
1602
  }
1600
1603
  function turnFailChatText(opts) {
@@ -6615,7 +6618,7 @@ var init_coordinator_prompt = __esm({
6615
6618
  "- list_workspaces \u2014 registered repos (path + github slug when known)",
6616
6619
  "- list_board \u2014 Home Kanban of worktrees (New / Draft / Review / Merged; one card per checkout). Path to merge: no PR \u2192 draft PR \u2192 open PR \u2192 merged. Archive removes the card to Settings \u2192 History. Queued/running are activity on the card, not columns. Orchestration chats are not on the board. Filters: query, repoPath, kind, column, limit.",
6617
6620
  "- list_branches / list_prs / list_issues \u2014 pass repoPath from list_workspaces (issues: Linear, AbleTime MCP, or GitHub Issues)",
6618
- "- linear_list_teams / linear_get_issue / linear_create_issue / linear_update_issue / linear_comment \u2014 Linear Account connection; call linear_list_teams for team key and workflow states; pass ENG-123 or uuid. If mutations fail with a scope error, Disconnect and Connect Linear in Account settings.",
6621
+ "- linear_list_teams / linear_get_issue / linear_create_issue / linear_update_issue / linear_comment \u2014 Linear Account connection; call linear_list_teams for team key and workflow states; pass ENG-123 or uuid. linear_get_issue returns comments, relations, parent/children, and the rest of the issue metadata. If mutations fail with a scope error, Disconnect and Connect Linear in Account settings.",
6619
6622
  "- abletime_orientation / abletime_list_projects / abletime_list_tasks / abletime_search_tasks / abletime_get_task / abletime_create_task / abletime_ensure_task \u2014 AbleTime Account personal access token (hosted MCP). Call orientation first. If work has no task yet, abletime_ensure_task creates one to track against (or create_thread from the default branch does that automatically when AbleTime is the preferred issue source).",
6620
6623
  "- list_teams / slack_list_channels / slack_list_users / slack_search / slack_read / slack_post / slack_replies \u2014 Slack workspaces from Settings \u2192 Remote; pass team_id from list_teams",
6621
6624
  "- Optional connectors (Vercel, Supabase, PostHog, Sentry) in Settings \u2192 Connectors inject tokens into worktree agent env when connected. Prefer official CLIs (`vercel`, `supabase`, `sentry-cli`) with those env vars. PostHog has no first-class CLI \u2014 use the HTTP API (`POSTHOG_PERSONAL_API_KEY`). If a CLI is missing, the user can Install CLI on that row (not auto-installed on Connect). Do not add vendor MCPs or ask the user to paste tokens again. Git (`gh`) stays Settings \u2192 Git; issue tracking stays Settings \u2192 Issues; Slack stays Settings \u2192 Remote (Sideboard MCP).",
@@ -19611,6 +19614,12 @@ var LIST_ISSUE_FIELDS = `
19611
19614
  labels(first: 10) { nodes { name } }
19612
19615
  cycle { name number startsAt endsAt completedAt }
19613
19616
  `;
19617
+ var ISSUE_REF_FIELDS = `
19618
+ id
19619
+ identifier
19620
+ title
19621
+ url
19622
+ `;
19614
19623
  var ISSUE_FIELDS = `
19615
19624
  id
19616
19625
  identifier
@@ -19618,11 +19627,46 @@ var ISSUE_FIELDS = `
19618
19627
  description
19619
19628
  url
19620
19629
  priority
19630
+ estimate
19631
+ dueDate
19632
+ branchName
19633
+ createdAt
19634
+ updatedAt
19635
+ completedAt
19621
19636
  state { id name type }
19622
19637
  assignee { id name }
19638
+ creator { id name }
19623
19639
  team { id key name states(first: 50) { nodes { id name type } } }
19624
19640
  labels(first: 50) { nodes { name } }
19625
19641
  cycle { name number startsAt endsAt completedAt }
19642
+ project { id name }
19643
+ parent { ${ISSUE_REF_FIELDS} }
19644
+ children(first: 25) { nodes { ${ISSUE_REF_FIELDS} } }
19645
+ relations(first: 25) {
19646
+ nodes {
19647
+ type
19648
+ relatedIssue { ${ISSUE_REF_FIELDS} }
19649
+ }
19650
+ }
19651
+ inverseRelations(first: 25) {
19652
+ nodes {
19653
+ type
19654
+ issue { ${ISSUE_REF_FIELDS} }
19655
+ }
19656
+ }
19657
+ comments(first: 50) {
19658
+ nodes {
19659
+ id
19660
+ body
19661
+ url
19662
+ createdAt
19663
+ updatedAt
19664
+ user { id name }
19665
+ }
19666
+ }
19667
+ attachments(first: 20) {
19668
+ nodes { id title url subtitle }
19669
+ }
19626
19670
  `;
19627
19671
  var ASSIGNED_ISSUES_QUERY = `
19628
19672
  query SideboardAssignedIssues($first: Int!) {
@@ -19750,6 +19794,82 @@ function mapCycle(node) {
19750
19794
  isActive: linearCycleIsActive(node)
19751
19795
  };
19752
19796
  }
19797
+ function mapUser(node) {
19798
+ if (!node?.id && !node?.name) return void 0;
19799
+ return {
19800
+ id: String(node.id ?? ""),
19801
+ name: String(node.name ?? "")
19802
+ };
19803
+ }
19804
+ function mapIssueRef(node) {
19805
+ if (!node?.id && !node?.identifier) return void 0;
19806
+ return {
19807
+ id: String(node.id ?? node.identifier ?? ""),
19808
+ identifier: String(node.identifier ?? node.id ?? ""),
19809
+ title: String(node.title ?? ""),
19810
+ url: String(node.url ?? "")
19811
+ };
19812
+ }
19813
+ function flipLinearRelationType(type) {
19814
+ switch (type) {
19815
+ case "blocks":
19816
+ return "blockedBy";
19817
+ case "blockedBy":
19818
+ return "blocks";
19819
+ case "duplicate":
19820
+ return "duplicateOf";
19821
+ case "duplicateOf":
19822
+ return "duplicate";
19823
+ default:
19824
+ return type;
19825
+ }
19826
+ }
19827
+ function mapRelations(node) {
19828
+ const out = [];
19829
+ for (const rel of node.relations?.nodes ?? []) {
19830
+ const issue = mapIssueRef(rel.relatedIssue);
19831
+ if (!issue) continue;
19832
+ out.push({ type: String(rel.type ?? "related"), issue });
19833
+ }
19834
+ for (const rel of node.inverseRelations?.nodes ?? []) {
19835
+ const issue = mapIssueRef(rel.issue);
19836
+ if (!issue) continue;
19837
+ out.push({ type: flipLinearRelationType(String(rel.type ?? "related")), issue });
19838
+ }
19839
+ return out;
19840
+ }
19841
+ function mapComments(node) {
19842
+ const out = [];
19843
+ for (const comment of node.comments?.nodes ?? []) {
19844
+ const id = String(comment.id ?? "");
19845
+ const body = String(comment.body ?? "");
19846
+ if (!id && !body) continue;
19847
+ out.push({
19848
+ id,
19849
+ body,
19850
+ url: comment.url?.trim() || void 0,
19851
+ createdAt: comment.createdAt?.trim() || void 0,
19852
+ updatedAt: comment.updatedAt?.trim() || void 0,
19853
+ user: mapUser(comment.user)
19854
+ });
19855
+ }
19856
+ return out;
19857
+ }
19858
+ function mapAttachments(node) {
19859
+ const out = [];
19860
+ for (const attachment of node.attachments?.nodes ?? []) {
19861
+ const id = String(attachment.id ?? "");
19862
+ const url = String(attachment.url ?? "").trim();
19863
+ if (!id && !url) continue;
19864
+ out.push({
19865
+ id,
19866
+ title: String(attachment.title ?? ""),
19867
+ url,
19868
+ subtitle: attachment.subtitle?.trim() || void 0
19869
+ });
19870
+ }
19871
+ return out;
19872
+ }
19753
19873
  function mapIssue(node) {
19754
19874
  const team = node.team;
19755
19875
  return {
@@ -19759,16 +19879,35 @@ function mapIssue(node) {
19759
19879
  url: String(node.url ?? ""),
19760
19880
  description: node.description?.trim() || void 0,
19761
19881
  priority: typeof node.priority === "number" ? node.priority : void 0,
19882
+ estimate: typeof node.estimate === "number" ? node.estimate : void 0,
19883
+ dueDate: node.dueDate?.trim() || void 0,
19884
+ branchName: node.branchName?.trim() || void 0,
19885
+ createdAt: node.createdAt?.trim() || void 0,
19886
+ updatedAt: node.updatedAt?.trim() || void 0,
19887
+ completedAt: node.completedAt?.trim() || void 0,
19762
19888
  state: mapState(node.state),
19763
- assignee: node.assignee?.id ? { id: String(node.assignee.id), name: String(node.assignee.name ?? "") } : void 0,
19889
+ assignee: mapUser(node.assignee),
19890
+ creator: mapUser(node.creator),
19764
19891
  team: team?.id ? {
19765
19892
  id: String(team.id),
19766
19893
  key: String(team.key ?? ""),
19767
19894
  name: String(team.name ?? ""),
19768
- states: (team.states?.nodes ?? []).map((s) => mapState(s)).filter((s) => Boolean(s))
19895
+ states: (team.states?.nodes ?? []).flatMap((s) => {
19896
+ const state = mapState(s);
19897
+ return state ? [state] : [];
19898
+ })
19769
19899
  } : void 0,
19770
19900
  labels: (node.labels?.nodes ?? []).map((l) => l.name).filter((n) => Boolean(n)),
19771
- cycle: mapCycle(node.cycle)
19901
+ cycle: mapCycle(node.cycle),
19902
+ project: node.project?.id ? { id: String(node.project.id), name: String(node.project.name ?? "") } : void 0,
19903
+ parent: mapIssueRef(node.parent),
19904
+ children: (node.children?.nodes ?? []).flatMap((child) => {
19905
+ const ref = mapIssueRef(child);
19906
+ return ref ? [ref] : [];
19907
+ }),
19908
+ relations: mapRelations(node),
19909
+ comments: mapComments(node),
19910
+ attachments: mapAttachments(node)
19772
19911
  };
19773
19912
  }
19774
19913
  function toIssueInfo(issue) {
@@ -19790,7 +19929,10 @@ function mapTeam(node) {
19790
19929
  id: String(node.id ?? ""),
19791
19930
  key: String(node.key ?? ""),
19792
19931
  name: String(node.name ?? ""),
19793
- states: (node.states?.nodes ?? []).map((s) => mapState(s)).filter((s) => Boolean(s))
19932
+ states: (node.states?.nodes ?? []).flatMap((s) => {
19933
+ const state = mapState(s);
19934
+ return state ? [state] : [];
19935
+ })
19794
19936
  };
19795
19937
  }
19796
19938
  function resolveLinearTeam(teams, team) {
@@ -20760,7 +20902,7 @@ function registerLinearTools(server) {
20760
20902
  );
20761
20903
  server.tool(
20762
20904
  "linear_get_issue",
20763
- "Get a Linear issue by uuid or identifier (ENG-123).",
20905
+ "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.",
20764
20906
  { id: import_zod3.z.string() },
20765
20907
  async ({ id }) => {
20766
20908
  try {