@sideboard-ai/core 0.1.235 → 0.1.237

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 (67) hide show
  1. package/dist/{abletime-WZNDTRVL.js → abletime-UX4VUENQ.js} +5 -5
  2. package/dist/{abletime-BGVOCEOU.js → abletime-VSV6AUBV.js} +5 -5
  3. package/dist/{abletime-oauth-ZLU2EYRK.js → abletime-oauth-DKBUZV2C.js} +4 -4
  4. package/dist/{abletime-oauth-6M5GWEPX.js → abletime-oauth-QMDV45JC.js} +4 -4
  5. package/dist/{abletime-rest-F7XG5NGY.js → abletime-rest-NL56UVK5.js} +4 -4
  6. package/dist/{abletime-rest-WNHIATB3.js → abletime-rest-VPBC2XS5.js} +4 -4
  7. package/dist/agents/cursor-runner.cjs +39 -35
  8. package/dist/agents/cursor-runner.js +3 -3
  9. package/dist/{agents-37JCAVSC.js → agents-6NAPLJU2.js} +9 -9
  10. package/dist/{agents-MOMMKSYV.js → agents-HJU23LIF.js} +8 -8
  11. package/dist/{app-settings-KBL2G7M4.js → app-settings-AGDLF75Z.js} +2 -2
  12. package/dist/{app-settings-UXWCPDEA.js → app-settings-I27UBVI4.js} +2 -2
  13. package/dist/{caffeinate-hold-OK4JJ5PP.js → caffeinate-hold-FNKIPXDU.js} +2 -2
  14. package/dist/{caffeinate-hold-22VFDPSO.js → caffeinate-hold-PXHGH7ZN.js} +2 -2
  15. package/dist/{chunk-7J72QJOM.js → chunk-224IXQOM.js} +1 -1
  16. package/dist/{chunk-7366AB7E.js → chunk-32DG3DA2.js} +514 -745
  17. package/dist/{chunk-4VGCG2HV.js → chunk-3AJUH66R.js} +2 -2
  18. package/dist/{chunk-P6ZM5QJW.js → chunk-3PGFAVFL.js} +2 -2
  19. package/dist/{chunk-MVLXDYN5.js → chunk-5ELC3KK3.js} +5 -5
  20. package/dist/{chunk-WPD7BR6C.js → chunk-5SHYLRTU.js} +1 -1
  21. package/dist/{chunk-WFUDY6PC.js → chunk-A4JGXX2F.js} +155 -24
  22. package/dist/{chunk-S2OEFXST.js → chunk-BILEJG3V.js} +20 -7
  23. package/dist/{chunk-TNVJPFHM.js → chunk-CJKL7A4G.js} +5 -5
  24. package/dist/{chunk-SWNEA5OZ.js → chunk-CRAXJAYJ.js} +3 -3
  25. package/dist/{chunk-C774RJJA.js → chunk-CWHMLCLN.js} +3 -3
  26. package/dist/{chunk-YWI3IBP2.js → chunk-DQN5U2VH.js} +1 -1
  27. package/dist/{chunk-RGNPPRZZ.js → chunk-DXY4K5MP.js} +3 -3
  28. package/dist/{chunk-LJWF3VA3.js → chunk-E6UJGLPM.js} +497 -673
  29. package/dist/{chunk-AS4UN7QL.js → chunk-IVXPXYH2.js} +5 -5
  30. package/dist/{chunk-SPAMHHJH.js → chunk-J5GON4SU.js} +1 -1
  31. package/dist/{chunk-D4VKJO5C.js → chunk-K6UTJOE6.js} +326 -20
  32. package/dist/{chunk-EQNRWDLN.js → chunk-KK63BFYN.js} +151 -24
  33. package/dist/{chunk-X5B3OS5I.js → chunk-N6XI5KXL.js} +1 -1
  34. package/dist/{chunk-XJETIO4K.js → chunk-NJ5OXOTN.js} +2 -2
  35. package/dist/{chunk-7H2CVVLF.js → chunk-O3UAQAYA.js} +3 -3
  36. package/dist/{chunk-4TYXWPAJ.js → chunk-OJFEVWZN.js} +1 -1
  37. package/dist/{chunk-TWXSZYR2.js → chunk-OKHOYI53.js} +18 -7
  38. package/dist/{chunk-I5NC7DWO.js → chunk-P3DCZRER.js} +1 -1
  39. package/dist/{chunk-RZTRWN2V.js → chunk-QLWMHQPH.js} +5 -5
  40. package/dist/{chunk-4VFOJZPS.js → chunk-TB6UMHIF.js} +3 -3
  41. package/dist/{chunk-EAYXD2IC.js → chunk-WRUBICEF.js} +302 -18
  42. package/dist/{chunk-GHRZNPBK.js → chunk-YXOOSFAF.js} +2 -2
  43. package/dist/{connected-teams-KQUDU7LZ.js → connected-teams-62AJRDDD.js} +2 -2
  44. package/dist/{connected-teams-JUJAQZZE.js → connected-teams-GXV22ZSF.js} +2 -2
  45. package/dist/{coordinator-prompt-IGDMFKCD.js → coordinator-prompt-5UINTEA6.js} +6 -6
  46. package/dist/{coordinator-prompt-CE7MN6QY.js → coordinator-prompt-ATK73HYU.js} +6 -6
  47. package/dist/{cursor-recover-DTQAUDGO.js → cursor-recover-DFMCTZA4.js} +2 -2
  48. package/dist/{cursor-recover-4PQAADAU.js → cursor-recover-K3EBEM7M.js} +2 -2
  49. package/dist/{global-workspace-7WH24UFO.js → global-workspace-TD5SARNW.js} +6 -6
  50. package/dist/{global-workspace-NCIC2Y2U.js → global-workspace-ZJBBICFJ.js} +6 -6
  51. package/dist/index.cjs +2230 -1164
  52. package/dist/index.d.cts +243 -14
  53. package/dist/index.d.ts +243 -14
  54. package/dist/index.js +903 -70
  55. package/dist/mcp/run-stdio.cjs +4772 -3854
  56. package/dist/mcp/run-stdio.js +723 -49
  57. package/dist/{orchestrator-6NPBOBNA.js → orchestrator-AAYKR4AI.js} +10 -10
  58. package/dist/{orchestrator-RKWRI3PJ.js → orchestrator-HPMDB2SG.js} +11 -11
  59. package/dist/{paths-C2VERLAE.js → paths-LGKOG7MY.js} +1 -1
  60. package/dist/{paths-LOXCISLX.js → paths-O6ZEAEUD.js} +1 -1
  61. package/dist/{thread-store-IKJD4EOK.js → thread-store-AYPBEZT5.js} +3 -3
  62. package/dist/{thread-store-FBK5SZ5P.js → thread-store-YOPKY74K.js} +3 -3
  63. package/dist/{workspaces-NSQZSDQD.js → workspaces-4SFSCYKT.js} +6 -6
  64. package/dist/{workspaces-H2TRFDE2.js → workspaces-JX5R4V24.js} +6 -6
  65. package/dist/{worktree-W7BSI4GU.js → worktree-AGVPKDBH.js} +5 -5
  66. package/dist/{worktree-FMIX4BRV.js → worktree-Y5FES5D6.js} +5 -5
  67. package/package.json +1 -1
@@ -6,7 +6,7 @@ import {
6
6
  import {
7
7
  getAbleTimeHost,
8
8
  isAbleTimeConnected
9
- } from "./chunk-RZTRWN2V.js";
9
+ } from "./chunk-QLWMHQPH.js";
10
10
 
11
11
  // src/integrations/abletime-mcp.ts
12
12
  var DEFAULT_ABLETIME_HOST = "https://track.abletime.com";
@@ -155,7 +155,7 @@ function textsFromUnknown(value) {
155
155
  return "";
156
156
  }
157
157
  async function abletimeMcpRequest(method, params, opts) {
158
- const rawToken = opts?.token ?? await import("./abletime-oauth-ZLU2EYRK.js").then((m) => m.ensureAbleTimeAccessToken());
158
+ const rawToken = opts?.token ?? await import("./abletime-oauth-DKBUZV2C.js").then((m) => m.ensureAbleTimeAccessToken());
159
159
  if (!rawToken?.trim()) {
160
160
  throw new Error("AbleTime is not connected \u2014 paste a personal access token in Account settings");
161
161
  }
@@ -226,9 +226,9 @@ async function callAbleTimeTool(name, args = {}, opts) {
226
226
  if (!opts?.token && !isAbleTimeConnected()) {
227
227
  throw new Error("AbleTime is not connected \u2014 paste a personal access token in Account settings");
228
228
  }
229
- const rawToken = opts?.token ?? await import("./abletime-oauth-ZLU2EYRK.js").then((m) => m.ensureAbleTimeAccessToken());
229
+ const rawToken = opts?.token ?? await import("./abletime-oauth-DKBUZV2C.js").then((m) => m.ensureAbleTimeAccessToken());
230
230
  if (rawToken && ableTimeUsesRest(rawToken)) {
231
- const { callAbleTimeRestTool } = await import("./abletime-rest-WNHIATB3.js");
231
+ const { callAbleTimeRestTool } = await import("./abletime-rest-VPBC2XS5.js");
232
232
  return callAbleTimeRestTool(name, args, { ...opts, token: rawToken });
233
233
  }
234
234
  const requestOpts = { ...opts, pm: opts?.pm ?? abletimeToolUsesPm(name) };
@@ -244,7 +244,7 @@ async function callAbleTimeTool(name, args = {}, opts) {
244
244
  return await call();
245
245
  }
246
246
  if (rawToken && ableTimeUsesRest(rawToken) && isAbleTimeRejectedCredential(message)) {
247
- const { callAbleTimeRestTool } = await import("./abletime-rest-WNHIATB3.js");
247
+ const { callAbleTimeRestTool } = await import("./abletime-rest-VPBC2XS5.js");
248
248
  return callAbleTimeRestTool(name, args, { ...opts, token: rawToken });
249
249
  }
250
250
  throw err instanceof Error ? new Error(rewriteAbleTimeError(err.message)) : err;
@@ -13,7 +13,7 @@ import {
13
13
  } from "./chunk-2UG25RMK.js";
14
14
  import {
15
15
  appDataDir
16
- } from "./chunk-EQNRWDLN.js";
16
+ } from "./chunk-KK63BFYN.js";
17
17
 
18
18
  // src/brightsy/connected-teams.ts
19
19
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
@@ -1,18 +1,18 @@
1
1
  import {
2
2
  isOrchestratorThread
3
- } from "./chunk-S2OEFXST.js";
3
+ } from "./chunk-BILEJG3V.js";
4
4
  import {
5
5
  codexUnattendedGitConfigArgs,
6
6
  mergeAgentGitAuthEnv,
7
7
  resolveAgentGitAuthEnv,
8
8
  resolveCodexGitWritableRoots
9
- } from "./chunk-7H2CVVLF.js";
9
+ } from "./chunk-O3UAQAYA.js";
10
10
  import {
11
11
  applyConnectedTeamToCli,
12
12
  brightsyMcpServerName,
13
13
  ensureCliTeamTracked,
14
14
  ensureConnectedBrightsyTeamTokens
15
- } from "./chunk-TNVJPFHM.js";
15
+ } from "./chunk-CJKL7A4G.js";
16
16
  import {
17
17
  loadBrightsyConfig
18
18
  } from "./chunk-ROPGQRPU.js";
@@ -36,7 +36,7 @@ import {
36
36
  packagedMcpStdioPath,
37
37
  parseCursorRunnerLine,
38
38
  resolveNodeLaunch
39
- } from "./chunk-WPD7BR6C.js";
39
+ } from "./chunk-5SHYLRTU.js";
40
40
  import {
41
41
  claudeChromeEnabled,
42
42
  fromInclusiveInputUsage,
@@ -45,10 +45,10 @@ import {
45
45
  loadAppSettings,
46
46
  resolveAgentExecutable,
47
47
  resolveClaudeExecutable
48
- } from "./chunk-I5NC7DWO.js";
48
+ } from "./chunk-P3DCZRER.js";
49
49
  import {
50
50
  appDataDir
51
- } from "./chunk-WFUDY6PC.js";
51
+ } from "./chunk-A4JGXX2F.js";
52
52
  import {
53
53
  enrichPathWithNpmGlobalBin,
54
54
  isConductorBundledCli,
@@ -557,6 +557,7 @@ import { fileURLToPath } from "url";
557
557
 
558
558
  // src/mcp/profile.ts
559
559
  var SIDEBOARD_MCP_PROFILE_ENV = "SIDEBOARD_MCP_PROFILE";
560
+ var SIDEBOARD_THREAD_ID_ENV = "SIDEBOARD_THREAD_ID";
560
561
  var WORKTREE_MCP_TOOLS = [
561
562
  "present_artifact",
562
563
  "ask_user",
@@ -568,6 +569,8 @@ var WORKTREE_MCP_TOOLS = [
568
569
  "list_run_scripts",
569
570
  "run_dev_script",
570
571
  "stop_dev_script",
572
+ "get_run_log",
573
+ "notify_orchestrator",
571
574
  "get_viewer_context",
572
575
  "update_viewer_context"
573
576
  ];
@@ -617,6 +620,8 @@ var SIDEBOARD_ARTIFACT_MCP_ALLOWED_TOOLS = [
617
620
  "mcp__sideboard__list_run_scripts",
618
621
  "mcp__sideboard__run_dev_script",
619
622
  "mcp__sideboard__stop_dev_script",
623
+ "mcp__sideboard__get_run_log",
624
+ "mcp__sideboard__notify_orchestrator",
620
625
  "mcp__sideboard__get_viewer_context",
621
626
  "mcp__sideboard__update_viewer_context"
622
627
  ];
@@ -783,6 +788,7 @@ async function buildInjectedMcpServers(opts) {
783
788
  const sideboard = await resolveSideboardMcpServer();
784
789
  const orchId = opts.orchestratorThreadId?.trim();
785
790
  const profile = orchId ? "orchestration" : "worktree";
791
+ const threadId = opts.threadId?.trim() || orchId;
786
792
  sideboard.env = {
787
793
  ...sideboard.env ?? {},
788
794
  SIDEBOARD_APP_DATA: appDataDir(),
@@ -791,6 +797,9 @@ async function buildInjectedMcpServers(opts) {
791
797
  if (orchId) {
792
798
  sideboard.env.SIDEBOARD_ORCHESTRATOR_THREAD_ID = orchId;
793
799
  }
800
+ if (threadId) {
801
+ sideboard.env[SIDEBOARD_THREAD_ID_ENV] = threadId;
802
+ }
794
803
  try {
795
804
  mergeAgentGitAuthEnv(
796
805
  sideboard.env,
@@ -1154,7 +1163,76 @@ function visibleToolRowDetail(detail, description, worktreePath) {
1154
1163
  if (parts.length >= 2) return `\u2026/${parts.slice(-2).join("/")}`;
1155
1164
  return base;
1156
1165
  }
1166
+ function isSkillToolName(name) {
1167
+ const n = (name ?? "").trim();
1168
+ if (/^(Skill|SlashCommand)$/i.test(n)) return true;
1169
+ return /(?:^|__)Skill$/i.test(n);
1170
+ }
1171
+ function skillCommandFromInput(input) {
1172
+ const raw = str(input?.skill) ?? str(input?.command) ?? str(input?.name) ?? str(input?.skill_name) ?? str(input?.skillName);
1173
+ if (raw) return raw.replace(/^\//, "").trim() || void 0;
1174
+ const path = str(input?.file_path) ?? str(input?.path);
1175
+ if (path && /SKILL\.md$/i.test(path)) {
1176
+ const parts = path.replace(/\\/g, "/").split("/");
1177
+ const dir = parts[parts.length - 2];
1178
+ if (dir && dir !== "skills") return dir;
1179
+ }
1180
+ return void 0;
1181
+ }
1182
+ function looksLikeSkillBody(text) {
1183
+ const t = text.trim();
1184
+ if (!t) return false;
1185
+ if (/^## Skill: \//m.test(t) && /Follow this skill for the request above:/i.test(t)) {
1186
+ return true;
1187
+ }
1188
+ return skillNameFromFrontmatter(t) != null;
1189
+ }
1190
+ function skillNameFromFrontmatter(text) {
1191
+ const t = text.trim();
1192
+ if (!t.startsWith("---")) return void 0;
1193
+ const close = t.indexOf("\n---", 3);
1194
+ if (close < 0) return void 0;
1195
+ const fm = t.slice(3, close);
1196
+ const m = fm.match(/^\s*name\s*:\s*['"]?([A-Za-z0-9][A-Za-z0-9._-]*)['"]?\s*$/m);
1197
+ return m?.[1];
1198
+ }
1199
+ function skillCommandFromBody(text) {
1200
+ return skillNameFromFrontmatter(text) ?? text.match(/^## Skill: \/([A-Za-z0-9][A-Za-z0-9._-]*)/m)?.[1];
1201
+ }
1202
+ function isCompactToolName(name) {
1203
+ const short = (name ?? "").replace(/^mcp__[^_]+__/, "").trim();
1204
+ return /^(Compact|ConversationCompact|summarize_context|SummarizeContext|SummarizeConversation)$/i.test(
1205
+ short
1206
+ );
1207
+ }
1208
+ function isContextCompactInProgress(text) {
1209
+ return /^Compressing context/i.test(text.trim());
1210
+ }
1211
+ function isContextCompactDone(text) {
1212
+ return /^Context compressed\b/i.test(text.trim());
1213
+ }
1214
+ function looksLikeConversationSummary(text) {
1215
+ const t = text.trim();
1216
+ if (t.length < 80) return false;
1217
+ if (/<summarized_conversation\b/i.test(t) || /<conversation_summary\b/i.test(t)) {
1218
+ return true;
1219
+ }
1220
+ if (/this session is being continued from a previous conversation/i.test(t)) {
1221
+ return true;
1222
+ }
1223
+ if (/conversation compacted|replaced with a summary/i.test(t)) return true;
1224
+ if (/^## Prior summary\b/m.test(t)) return true;
1225
+ if (/_Automatic extractive summary/i.test(t)) return true;
1226
+ if (/"context_summary"\s*:/.test(t)) return true;
1227
+ if (/^(?:#+\s*)?(?:conversation summary|summary of (?:the )?conversation|compacted (?:conversation|context))\b/im.test(
1228
+ t
1229
+ )) {
1230
+ return true;
1231
+ }
1232
+ return false;
1233
+ }
1157
1234
  function toolDetail(name, input) {
1235
+ if (isSkillToolName(name) || isCompactToolName(name)) return void 0;
1158
1236
  if (!input) return void 0;
1159
1237
  const command = str(input.command) ?? str(input.cmd);
1160
1238
  if (command) return clipChatLine(command);
@@ -1206,6 +1284,21 @@ function toolDescription(name, input) {
1206
1284
  if (/stop_dev_script$/i.test(name)) {
1207
1285
  return str(input?.name) ? `Stop ${str(input?.name)}` : "Stop Dev script";
1208
1286
  }
1287
+ if (/get_run_log$/i.test(name)) {
1288
+ return str(input?.name) ? `Read ${str(input?.name)} log` : "Read Dev log";
1289
+ }
1290
+ if (/notify_orchestrator$/i.test(name)) return "Notify orchestrator";
1291
+ if (isSkillToolName(name)) {
1292
+ const cmd = skillCommandFromInput(input);
1293
+ return cmd ? `Using /${cmd}` : "Using skill";
1294
+ }
1295
+ if (isCompactToolName(name)) {
1296
+ const trigger = str(input?.trigger);
1297
+ if (trigger && !/^auto$/i.test(trigger) && trigger !== "injected") {
1298
+ return `Summarized conversation (${trigger})`;
1299
+ }
1300
+ return "Summarized conversation";
1301
+ }
1209
1302
  if (isSubagentToolName(name)) {
1210
1303
  const desc = str(input?.description);
1211
1304
  const sub = asRecord(input?.subagentType);
@@ -1325,6 +1418,8 @@ function toolActivityLine(parts) {
1325
1418
  });
1326
1419
  if (tools.length === 0) return null;
1327
1420
  const edited = [];
1421
+ const skillNames = [];
1422
+ let compacts = 0;
1328
1423
  let reads = 0;
1329
1424
  let searches = 0;
1330
1425
  let shells = 0;
@@ -1333,7 +1428,12 @@ function toolActivityLine(parts) {
1333
1428
  let deletions = 0;
1334
1429
  for (const tool of tools) {
1335
1430
  const kind = classifyTool(tool.name);
1336
- if (kind === "edit") {
1431
+ if (isSkillToolName(tool.name)) {
1432
+ const cmd = skillCommandFromInput(tool.input);
1433
+ skillNames.push(cmd ? `/${cmd}` : "skill");
1434
+ } else if (isCompactToolName(tool.name)) {
1435
+ compacts += 1;
1436
+ } else if (kind === "edit") {
1337
1437
  const path = tool.filePath ?? toolFilePath(tool.input);
1338
1438
  edited.push({
1339
1439
  name: path ? fileBasename(path) : tool.name,
@@ -1361,6 +1461,10 @@ function toolActivityLine(parts) {
1361
1461
  else if (searches > 1) bits.push(`${searches} searches`);
1362
1462
  if (shells === 1) bits.push("ran 1 command");
1363
1463
  else if (shells > 1) bits.push(`ran ${shells} commands`);
1464
+ if (skillNames.length === 1) bits.push(`used ${skillNames[0]}`);
1465
+ else if (skillNames.length > 1) bits.push(`used ${skillNames.length} skills`);
1466
+ if (compacts === 1) bits.push("summarized conversation");
1467
+ else if (compacts > 1) bits.push(`summarized conversation \xD7${compacts}`);
1364
1468
  if (others === 1) bits.push("1 tool");
1365
1469
  else if (others > 1) bits.push(`${others} tools`);
1366
1470
  if (bits.length === 0) return null;
@@ -1493,10 +1597,107 @@ function withPartTimes(next, prev) {
1493
1597
  const startedAt = prev && typeof prev.startedAt === "number" ? prev.startedAt : now;
1494
1598
  return { ...next, startedAt, updatedAt: now };
1495
1599
  }
1600
+ function skillToolFromTextPart(part, id) {
1601
+ const command = skillCommandFromBody(part.text);
1602
+ const input = command ? { skill: command } : void 0;
1603
+ return {
1604
+ type: "tool",
1605
+ id,
1606
+ name: "Skill",
1607
+ input,
1608
+ description: toolDescription("Skill", input),
1609
+ status: "done",
1610
+ result: clipToolResultForStore(part.text),
1611
+ ...part.parentId ? { parentId: part.parentId } : {},
1612
+ startedAt: part.startedAt,
1613
+ updatedAt: Date.now()
1614
+ };
1615
+ }
1616
+ function compactToolPart(text, id, opts) {
1617
+ const input = { trigger: opts?.trigger ?? "auto" };
1618
+ return withPartTimes(
1619
+ {
1620
+ type: "tool",
1621
+ id,
1622
+ name: "Compact",
1623
+ input,
1624
+ description: toolDescription("Compact", input),
1625
+ status: opts?.status ?? "done",
1626
+ result: clipToolResultForStore(text) ?? "",
1627
+ ...opts?.parentId ? { parentId: opts.parentId } : {}
1628
+ },
1629
+ opts?.prev
1630
+ );
1631
+ }
1632
+ function contextCompactInProgress(parts, parentId) {
1633
+ let compressing = false;
1634
+ for (const p of parts) {
1635
+ if (!sameParentId(p.parentId, parentId)) continue;
1636
+ if (p.type === "thinking" && isContextCompactInProgress(p.text)) compressing = true;
1637
+ if (p.type === "thinking" && isContextCompactDone(p.text)) compressing = false;
1638
+ }
1639
+ return compressing;
1640
+ }
1641
+ function lastRunningCompactIndex(parts, parentId) {
1642
+ for (let i = parts.length - 1; i >= 0; i--) {
1643
+ const p = parts[i];
1644
+ if (p.type === "tool" && isCompactToolName(p.name) && p.status === "running" && sameParentId(p.parentId, parentId)) {
1645
+ return i;
1646
+ }
1647
+ }
1648
+ return -1;
1649
+ }
1650
+ function markRunningCompactDone(parts, parentId) {
1651
+ return parts.map((p) => {
1652
+ if (p.type === "tool" && isCompactToolName(p.name) && p.status === "running" && sameParentId(p.parentId, parentId)) {
1653
+ return withPartTimes({ ...p, status: "done" }, p);
1654
+ }
1655
+ return p;
1656
+ });
1657
+ }
1658
+ function ensureCompactTool(parts, parentId) {
1659
+ const hasCompact = parts.some(
1660
+ (p) => p.type === "tool" && isCompactToolName(p.name) && sameParentId(p.parentId, parentId)
1661
+ );
1662
+ if (hasCompact) return parts;
1663
+ return [
1664
+ ...parts,
1665
+ compactToolPart("Context compressed", `compact-${parts.length}`, {
1666
+ parentId,
1667
+ status: "done"
1668
+ })
1669
+ ];
1670
+ }
1671
+ function withCompactFinish(parts, thinking, parentId) {
1672
+ if (!isContextCompactDone(thinking)) return parts;
1673
+ return ensureCompactTool(markRunningCompactDone(parts, parentId), parentId);
1674
+ }
1496
1675
  function applyAgentEvent(parts, event) {
1497
1676
  if (event.type === "stdout") {
1498
1677
  const data = event.data;
1499
1678
  if (!data) return parts;
1679
+ const runningIdx = lastRunningCompactIndex(parts, event.parentId);
1680
+ if (runningIdx >= 0) {
1681
+ const prev = parts[runningIdx];
1682
+ const next2 = [...parts];
1683
+ next2[runningIdx] = withPartTimes(
1684
+ {
1685
+ ...prev,
1686
+ result: clipToolResultForStore(`${prev.result ?? ""}${data}`)
1687
+ },
1688
+ prev
1689
+ );
1690
+ return next2;
1691
+ }
1692
+ if (contextCompactInProgress(parts, event.parentId)) {
1693
+ return [
1694
+ ...parts,
1695
+ compactToolPart(data, `compact-${parts.length}`, {
1696
+ parentId: event.parentId,
1697
+ status: "running"
1698
+ })
1699
+ ];
1700
+ }
1500
1701
  const next = [...parts];
1501
1702
  const last = next[next.length - 1];
1502
1703
  if (last?.type === "text" && sameParentId(last.parentId, event.parentId)) {
@@ -1517,6 +1718,16 @@ function applyAgentEvent(parts, event) {
1517
1718
  })
1518
1719
  );
1519
1720
  }
1721
+ const acc = next[next.length - 1];
1722
+ if (acc?.type === "text" && looksLikeSkillBody(acc.text)) {
1723
+ next[next.length - 1] = skillToolFromTextPart(acc, `skill-${next.length}`);
1724
+ } else if (acc?.type === "text" && looksLikeConversationSummary(acc.text)) {
1725
+ next[next.length - 1] = compactToolPart(acc.text, `compact-${next.length}`, {
1726
+ parentId: acc.parentId,
1727
+ status: "done",
1728
+ prev: acc
1729
+ });
1730
+ }
1520
1731
  return next;
1521
1732
  }
1522
1733
  if (event.type === "thinking") {
@@ -1535,7 +1746,7 @@ function applyAgentEvent(parts, event) {
1535
1746
  },
1536
1747
  prev
1537
1748
  );
1538
- return next;
1749
+ return withCompactFinish(next, data, event.parentId);
1539
1750
  }
1540
1751
  }
1541
1752
  next.push(
@@ -1545,7 +1756,7 @@ function applyAgentEvent(parts, event) {
1545
1756
  ...event.parentId ? { parentId: event.parentId } : {}
1546
1757
  })
1547
1758
  );
1548
- return next;
1759
+ return withCompactFinish(next, data, event.parentId);
1549
1760
  }
1550
1761
  const last = next[next.length - 1];
1551
1762
  if (last?.type === "thinking" && sameParentId(last.parentId, event.parentId)) {
@@ -1566,7 +1777,7 @@ function applyAgentEvent(parts, event) {
1566
1777
  })
1567
1778
  );
1568
1779
  }
1569
- return next;
1780
+ return withCompactFinish(next, data, event.parentId);
1570
1781
  }
1571
1782
  if (event.type === "tool_use") {
1572
1783
  const input = asRecord(event.input);
@@ -1845,6 +2056,87 @@ function claudeResultErrorDetail(obj) {
1845
2056
  }
1846
2057
  return "Claude turn failed";
1847
2058
  }
2059
+ function toolResultContent(block) {
2060
+ if (typeof block.content === "string") return block.content;
2061
+ if (Array.isArray(block.content)) {
2062
+ return block.content.map(
2063
+ (c) => typeof c === "string" ? c : c && typeof c === "object" && "text" in c ? String(c.text ?? "") : ""
2064
+ ).join("");
2065
+ }
2066
+ if (block.content != null) return JSON.stringify(block.content);
2067
+ return void 0;
2068
+ }
2069
+ function skillToolEventsFromBody(text, parentId) {
2070
+ const command = skillCommandFromBody(text) ?? "skill";
2071
+ const id = `skill-${command}`;
2072
+ return [
2073
+ withEventParentId(
2074
+ { type: "tool_use", id, name: "Skill", input: { skill: command } },
2075
+ parentId
2076
+ ),
2077
+ withEventParentId({ type: "tool_result", id, content: text }, parentId)
2078
+ ];
2079
+ }
2080
+ function compactToolEventsFromBody(text, parentId) {
2081
+ const id = "compact-summary";
2082
+ return [
2083
+ withEventParentId(
2084
+ { type: "tool_use", id, name: "Compact", input: { trigger: "injected" } },
2085
+ parentId
2086
+ ),
2087
+ withEventParentId({ type: "tool_result", id, content: text }, parentId)
2088
+ ];
2089
+ }
2090
+ function eventsFromInjectedUserText(text, parentId) {
2091
+ if (looksLikeSkillBody(text)) return skillToolEventsFromBody(text, parentId);
2092
+ if (looksLikeConversationSummary(text)) return compactToolEventsFromBody(text, parentId);
2093
+ return [];
2094
+ }
2095
+ function eventsFromUserContent(content, parentId) {
2096
+ if (typeof content === "string" && content.trim()) {
2097
+ return eventsFromInjectedUserText(content, parentId);
2098
+ }
2099
+ if (!Array.isArray(content) || content.length === 0) return [];
2100
+ const out = [];
2101
+ const textBlocks = [];
2102
+ for (const block of content) {
2103
+ if (!block?.type) continue;
2104
+ if (block.type === "tool_use" && block.id && block.name) {
2105
+ out.push(
2106
+ withEventParentId(
2107
+ {
2108
+ type: "tool_use",
2109
+ id: block.id,
2110
+ name: block.name,
2111
+ input: block.input
2112
+ },
2113
+ parentId
2114
+ )
2115
+ );
2116
+ continue;
2117
+ }
2118
+ if (block.type === "tool_result" && block.tool_use_id) {
2119
+ out.push(
2120
+ withEventParentId(
2121
+ {
2122
+ type: "tool_result",
2123
+ id: block.tool_use_id,
2124
+ content: toolResultContent(block),
2125
+ isError: Boolean(block.is_error)
2126
+ },
2127
+ parentId
2128
+ )
2129
+ );
2130
+ continue;
2131
+ }
2132
+ if (block.type === "text" && block.text) textBlocks.push(block.text);
2133
+ }
2134
+ if (out.length > 0) return out;
2135
+ for (const text of textBlocks) {
2136
+ out.push(...eventsFromInjectedUserText(text, parentId));
2137
+ }
2138
+ return out;
2139
+ }
1848
2140
  function eventsFromContentBlocks(blocks, parentId) {
1849
2141
  if (!blocks?.length) return [];
1850
2142
  const out = [];
@@ -1873,15 +2165,12 @@ function eventsFromContentBlocks(blocks, parentId) {
1873
2165
  continue;
1874
2166
  }
1875
2167
  if (block.type === "tool_result" && block.tool_use_id) {
1876
- const content = typeof block.content === "string" ? block.content : Array.isArray(block.content) ? block.content.map(
1877
- (c) => typeof c === "string" ? c : c && typeof c === "object" && "text" in c ? String(c.text ?? "") : ""
1878
- ).join("") : block.content != null ? JSON.stringify(block.content) : void 0;
1879
2168
  out.push(
1880
2169
  withEventParentId(
1881
2170
  {
1882
2171
  type: "tool_result",
1883
2172
  id: block.tool_use_id,
1884
- content,
2173
+ content: toolResultContent(block),
1885
2174
  isError: Boolean(block.is_error)
1886
2175
  },
1887
2176
  parentId
@@ -2120,14 +2409,15 @@ var claudeAdapter = {
2120
2409
  );
2121
2410
  }
2122
2411
  const mode = permissionMode(thread);
2123
- const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-NCIC2Y2U.js");
2412
+ const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-ZJBBICFJ.js");
2124
2413
  const isOrchestrator = isOrchestratorThread2(thread);
2125
2414
  const injectedServers = await buildInjectedMcpServers({
2126
2415
  includeSideboard: true,
2127
2416
  includeBrightsy: shouldInjectBrightsyMcp(thread, {
2128
2417
  orchestrator: isOrchestrator
2129
2418
  }),
2130
- orchestratorThreadId: isOrchestrator ? thread.id : null
2419
+ orchestratorThreadId: isOrchestrator ? thread.id : null,
2420
+ threadId: thread.id
2131
2421
  });
2132
2422
  const injectedBrightsyNames = injectedServers.filter((s) => s.name === "brightsy" || s.name.startsWith("brightsy_")).map((s) => s.name);
2133
2423
  const chromeOn = claudeChromeEnabled();
@@ -2220,7 +2510,10 @@ var claudeAdapter = {
2220
2510
  if (obj.type === "assistant" || obj.type === "user") {
2221
2511
  const parentId = claudeParentToolUseId(obj);
2222
2512
  const message = obj.message;
2223
- const events = eventsFromContentBlocks(message?.content, parentId);
2513
+ const events = obj.type === "user" ? eventsFromUserContent(message?.content, parentId) : eventsFromContentBlocks(
2514
+ Array.isArray(message?.content) ? message.content : void 0,
2515
+ parentId
2516
+ );
2224
2517
  if (obj.type === "assistant") {
2225
2518
  const usage = usageFromClaude(message?.usage);
2226
2519
  if (usage) events.push({ type: "usage", data: usage, scope: "request" });
@@ -2518,7 +2811,8 @@ var codexAdapter = {
2518
2811
  includeBrightsy: shouldInjectBrightsyMcp(thread, {
2519
2812
  orchestrator: isOrchestrator
2520
2813
  }),
2521
- orchestratorThreadId: isOrchestrator ? thread.id : null
2814
+ orchestratorThreadId: isOrchestrator ? thread.id : null,
2815
+ threadId: thread.id
2522
2816
  });
2523
2817
  const isolatePlugins = isOrchestrator || Boolean(thread.isolateCodexPlugins) || Boolean(normalizeTurnInput(input).isolateCodexPlugins);
2524
2818
  const mcpOverrides = [
@@ -2858,7 +3152,8 @@ var cursorAdapter = {
2858
3152
  includeBrightsy: shouldInjectBrightsyMcp(thread, {
2859
3153
  orchestrator: isOrchestrator
2860
3154
  }),
2861
- orchestratorThreadId: isOrchestrator ? thread.id : null
3155
+ orchestratorThreadId: isOrchestrator ? thread.id : null,
3156
+ threadId: thread.id
2862
3157
  });
2863
3158
  const mcpServers = toCursorMcpServers(injected);
2864
3159
  const req = {
@@ -3064,7 +3359,8 @@ var opencodeAdapter = {
3064
3359
  includeBrightsy: shouldInjectBrightsyMcp(thread, {
3065
3360
  orchestrator: isOrchestrator
3066
3361
  }),
3067
- orchestratorThreadId: isOrchestrator ? thread.id : null
3362
+ orchestratorThreadId: isOrchestrator ? thread.id : null,
3363
+ threadId: thread.id
3068
3364
  });
3069
3365
  const disableNames = isOrchestrator ? userMcpNamesToDisable({
3070
3366
  injectedNames: injected.map((s) => s.name),
@@ -4096,6 +4392,15 @@ function allAdapters() {
4096
4392
 
4097
4393
  export {
4098
4394
  visibleToolRowDetail,
4395
+ isSkillToolName,
4396
+ skillCommandFromInput,
4397
+ looksLikeSkillBody,
4398
+ skillNameFromFrontmatter,
4399
+ skillCommandFromBody,
4400
+ isCompactToolName,
4401
+ isContextCompactInProgress,
4402
+ isContextCompactDone,
4403
+ looksLikeConversationSummary,
4099
4404
  toolDetail,
4100
4405
  toolDescription,
4101
4406
  isSubagentToolName,
@@ -4141,6 +4446,7 @@ export {
4141
4446
  mcpAllowToolsFromNames,
4142
4447
  mcpAuthWarnings,
4143
4448
  SIDEBOARD_MCP_PROFILE_ENV,
4449
+ SIDEBOARD_THREAD_ID_ENV,
4144
4450
  WORKTREE_MCP_TOOLS,
4145
4451
  WORKTREE_GITHUB_MCP_TOOLS,
4146
4452
  WORKTREE_LINEAR_MCP_TOOLS,