@sideboard-ai/core 0.1.264 → 0.1.267

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 (68) hide show
  1. package/dist/{abletime-6AOJI2YZ.js → abletime-4ZSDI4YP.js} +9 -6
  2. package/dist/{abletime-U75ZGDIX.js → abletime-JNQAHLHH.js} +7 -4
  3. package/dist/{abletime-oauth-TA2YDCYX.js → abletime-oauth-4RXZH2KU.js} +3 -3
  4. package/dist/{abletime-oauth-LOAHGG4X.js → abletime-oauth-DCEIINYT.js} +5 -5
  5. package/dist/{abletime-rest-CTA5WV26.js → abletime-rest-KVBJFVFD.js} +3 -3
  6. package/dist/{abletime-rest-YZPFM6IY.js → abletime-rest-VN6PZ6P2.js} +5 -5
  7. package/dist/agents/cursor-runner.js +7 -5
  8. package/dist/{agents-3TUMFSMH.js → agents-G3JTULM2.js} +7 -5
  9. package/dist/{agents-6FWDRVA2.js → agents-XRXJCAWJ.js} +11 -10
  10. package/dist/{app-settings-RKFFUIFQ.js → app-settings-L5HGYXWJ.js} +1 -3
  11. package/dist/{app-settings-MVZPM6WW.js → app-settings-RAC4PSSP.js} +3 -5
  12. package/dist/{caffeinate-hold-UAGLSGMM.js → caffeinate-hold-7JM5H5P3.js} +2 -2
  13. package/dist/{chunk-F5MFNUAA.js → chunk-27Z4MEQ5.js} +1 -1
  14. package/dist/{chunk-EK3KVT7I.js → chunk-2XIRV7FS.js} +53 -1254
  15. package/dist/{chunk-3H7O27X2.js → chunk-3VBS6MES.js} +39 -1017
  16. package/dist/chunk-4ECDIKAS.js +2273 -0
  17. package/dist/{chunk-H547WSSZ.js → chunk-4RZRHTSZ.js} +1 -1
  18. package/dist/{chunk-QN5DL2QO.js → chunk-5DZUWGKV.js} +1 -1
  19. package/dist/chunk-5N4Q46SG.js +392 -0
  20. package/dist/{chunk-YKYEHDMX.js → chunk-AGXZAMOF.js} +5 -5
  21. package/dist/{chunk-RKPBIB2U.js → chunk-DB7MVDYS.js} +33 -7
  22. package/dist/{chunk-BOMSJUXW.js → chunk-DBFAFI5A.js} +5 -5
  23. package/dist/chunk-FAGK33E2.js +994 -0
  24. package/dist/{chunk-A5SAYFJ4.js → chunk-FIBZEFKA.js} +4 -390
  25. package/dist/{chunk-5PK53SAP.js → chunk-GONPMH36.js} +5 -5
  26. package/dist/{chunk-L5WGAIL2.js → chunk-GZXKUUJO.js} +35 -9
  27. package/dist/{chunk-Z2LGMV6C.js → chunk-H5XL4KUS.js} +21 -0
  28. package/dist/{chunk-T3AYRQJZ.js → chunk-HSRN2CSL.js} +473 -2487
  29. package/dist/{chunk-TJ673EZT.js → chunk-JANCPF7Z.js} +2 -2
  30. package/dist/chunk-KZ2CDZBZ.js +828 -0
  31. package/dist/{chunk-6YY7XPPL.js → chunk-L6CYOON4.js} +5 -5
  32. package/dist/{chunk-6YOXQVJ7.js → chunk-LAIBYKZS.js} +3 -3
  33. package/dist/{chunk-4ALDX5IO.js → chunk-NWE3NOWQ.js} +3 -3
  34. package/dist/{chunk-36FOBJBF.js → chunk-OIENQEGG.js} +63 -38
  35. package/dist/{chunk-2QUQH2SZ.js → chunk-PAH7KDL2.js} +68 -24
  36. package/dist/{chunk-XAISOBBG.js → chunk-TQRSVE7D.js} +1 -1
  37. package/dist/chunk-UKSJO36E.js +1224 -0
  38. package/dist/{chunk-CEMNIGQH.js → chunk-UN5Q7POQ.js} +1 -1
  39. package/dist/{chunk-5ZPT5YAV.js → chunk-USBZ7PH4.js} +1 -1
  40. package/dist/chunk-UXI52MLJ.js +826 -0
  41. package/dist/chunk-X7RP3TQB.js +2385 -0
  42. package/dist/{chunk-QX6QUZVD.js → chunk-ZSGSVFWD.js} +424 -2611
  43. package/dist/conductor-MLM5NGTP.js +104 -0
  44. package/dist/conductor-NRKTEN5X.js +105 -0
  45. package/dist/{connected-teams-7CENZDWU.js → connected-teams-JIUOSZ6C.js} +2 -2
  46. package/dist/{coordinator-prompt-J7DKHOCH.js → coordinator-prompt-4GHKCVRH.js} +7 -7
  47. package/dist/{coordinator-prompt-HZCQZ6C5.js → coordinator-prompt-BKRQDZFT.js} +3 -3
  48. package/dist/{cursor-recover-FALSNEZN.js → cursor-recover-MB3T2K5T.js} +2 -2
  49. package/dist/{global-workspace-TI26K25J.js → global-workspace-EEWJOMED.js} +9 -3
  50. package/dist/{global-workspace-6LDUZ2NF.js → global-workspace-EWFL4HPW.js} +13 -7
  51. package/dist/index.cjs +3918 -2592
  52. package/dist/index.d.cts +363 -68
  53. package/dist/index.d.ts +363 -68
  54. package/dist/index.js +4181 -3462
  55. package/dist/{managed-accounts-4BLTJKAN.js → managed-accounts-46A4KRUE.js} +2 -2
  56. package/dist/mcp/run-stdio.cjs +1894 -2012
  57. package/dist/mcp/run-stdio.js +719 -1445
  58. package/dist/{orchestrator-5YU46YNS.js → orchestrator-6ZQ2CYS4.js} +9 -6
  59. package/dist/{orchestrator-4JSG7BWC.js → orchestrator-MA3MHYIM.js} +15 -13
  60. package/dist/{paths-IUR3ABNG.js → paths-HYT5WOOX.js} +1 -1
  61. package/dist/{thread-store-FJ5CDX2M.js → thread-store-B3ZM4QEZ.js} +3 -3
  62. package/dist/{workspaces-QJ3XIPUJ.js → workspaces-F33Z4CEY.js} +3 -3
  63. package/dist/{workspaces-WOQHJFRQ.js → workspaces-SLP24Z3S.js} +7 -7
  64. package/dist/{worktree-6U2FA5LO.js → worktree-ACW23KJ5.js} +6 -6
  65. package/dist/{worktree-KQA4ON2G.js → worktree-C7RPVHZ7.js} +2 -2
  66. package/package.json +1 -1
  67. package/dist/chunk-CEOTK5GZ.js +0 -479
  68. package/dist/chunk-K7B25HO4.js +0 -477
@@ -4,15 +4,21 @@ import {
4
4
  ensureCliTeamTracked,
5
5
  ensureConnectedBrightsyTeamTokens
6
6
  } from "./chunk-GWFVCCJZ.js";
7
+ import {
8
+ looksLikeConversationSummary,
9
+ looksLikeSkillBody,
10
+ skillCommandFromBody,
11
+ withEventParentId
12
+ } from "./chunk-FAGK33E2.js";
7
13
  import {
8
14
  isOrchestratorThread
9
- } from "./chunk-RKPBIB2U.js";
15
+ } from "./chunk-DB7MVDYS.js";
10
16
  import {
11
17
  codexUnattendedGitConfigArgs,
12
18
  mergeAgentGitAuthEnv,
13
19
  resolveAgentGitAuthEnv,
14
20
  resolveCodexGitWritableRoots
15
- } from "./chunk-5ZPT5YAV.js";
21
+ } from "./chunk-USBZ7PH4.js";
16
22
  import {
17
23
  loadBrightsyConfig
18
24
  } from "./chunk-ROPGQRPU.js";
@@ -23,21 +29,22 @@ import {
23
29
  CURSOR_SDK_INSTALL_HINT,
24
30
  applyAgentRunnerHeapEnv,
25
31
  applyNodeLaunch,
26
- clipToolResultForStore,
27
32
  cursorRipgrepEnv,
28
- extractJsonErrorMessage,
29
- formatUnknownDetail,
30
33
  importCursorSdk,
31
34
  isAsarPath,
32
35
  isCursorSdkInstalled,
33
- looksLikeAgentFailureMessage,
34
- looksLikeBrightsyEmptyCompletion,
35
36
  packagedCursorRunnerPath,
36
37
  packagedCursorRuntimeDir,
37
38
  packagedMcpStdioPath,
38
39
  parseCursorRunnerLine,
39
40
  resolveNodeLaunch
40
- } from "./chunk-A5SAYFJ4.js";
41
+ } from "./chunk-FIBZEFKA.js";
42
+ import {
43
+ extractJsonErrorMessage,
44
+ formatUnknownDetail,
45
+ looksLikeAgentFailureMessage,
46
+ looksLikeBrightsyEmptyCompletion
47
+ } from "./chunk-5N4Q46SG.js";
41
48
  import {
42
49
  enrichPathWithNpmGlobalBin,
43
50
  isConductorBundledCli,
@@ -64,7 +71,7 @@ import {
64
71
  loadAppSettings,
65
72
  resolveAgentExecutable,
66
73
  resolveClaudeExecutable
67
- } from "./chunk-2QUQH2SZ.js";
74
+ } from "./chunk-PAH7KDL2.js";
68
75
  import {
69
76
  isElectronLikeCommand,
70
77
  unwrapStrippedElectronLaunch
@@ -645,6 +652,7 @@ var WORKTREE_MCP_TOOLS = [
645
652
  var WORKTREE_GITHUB_MCP_TOOLS = [
646
653
  "github_search_issues",
647
654
  "github_get_issue",
655
+ "github_download_attachment",
648
656
  "github_comment",
649
657
  "github_update_issue",
650
658
  "github_create_issue"
@@ -653,6 +661,7 @@ var WORKTREE_LINEAR_MCP_TOOLS = [
653
661
  "linear_list_teams",
654
662
  "linear_search_issues",
655
663
  "linear_get_issue",
664
+ "linear_download_attachment",
656
665
  "linear_create_issue",
657
666
  "linear_update_issue",
658
667
  "linear_comment"
@@ -663,6 +672,7 @@ var WORKTREE_ABLETIME_MCP_TOOLS = [
663
672
  "abletime_list_tasks",
664
673
  "abletime_search_tasks",
665
674
  "abletime_get_task",
675
+ "abletime_download_attachment",
666
676
  "abletime_comment",
667
677
  "abletime_update_task",
668
678
  "abletime_create_task",
@@ -1179,954 +1189,6 @@ function toCodexUnattendedAppsArgs() {
1179
1189
  ];
1180
1190
  }
1181
1191
 
1182
- // src/agents/message-parts.ts
1183
- function asRecord(input) {
1184
- if (input && typeof input === "object" && !Array.isArray(input)) {
1185
- return input;
1186
- }
1187
- return void 0;
1188
- }
1189
- function str(v) {
1190
- return typeof v === "string" && v.trim() ? v : void 0;
1191
- }
1192
- var CHAT_DETAIL_MAX = 72;
1193
- function clipChatLine(value, max = CHAT_DETAIL_MAX) {
1194
- const line = value.trim().split(/\r?\n/, 1)[0] ?? "";
1195
- if (line.length <= max) return line;
1196
- return `${line.slice(0, Math.max(1, max - 1))}\u2026`;
1197
- }
1198
- var SHELL_BIN_DIR = /^(?:\/usr\/local\/bin|\/usr\/bin|\/bin|\/opt\/homebrew\/bin|\/sbin|\/usr\/sbin)\//;
1199
- function rootedPathWithSpaces(trimmed) {
1200
- const [head = "", ...rest] = trimmed.split(/\s+/);
1201
- if (SHELL_BIN_DIR.test(head)) return false;
1202
- return rest.every((tok) => !/^[-/~$]/.test(tok) && !tok.includes("="));
1203
- }
1204
- function looksLikeFilePath(value) {
1205
- const trimmed = value.trim();
1206
- if (!trimmed || /[\r\n;|&<>]/.test(trimmed)) return false;
1207
- const rooted = trimmed.startsWith("/") || trimmed.startsWith("~/") || /^[A-Za-z]:[\\/]/.test(trimmed);
1208
- if (/\s/.test(trimmed)) return rooted && rootedPathWithSpaces(trimmed);
1209
- if (rooted) return true;
1210
- return trimmed.includes("/") || trimmed.includes("\\");
1211
- }
1212
- function stripWorktreePrefix(path, worktreePath) {
1213
- if (!worktreePath) return path;
1214
- const prefix = worktreePath.replace(/[/\\]+$/, "");
1215
- if (path === prefix || path === `${prefix}/`) return "";
1216
- if (path.startsWith(`${prefix}/`)) return path.slice(prefix.length + 1);
1217
- return path;
1218
- }
1219
- function visibleToolRowDetail(detail, description, worktreePath) {
1220
- if (!detail?.trim()) return void 0;
1221
- const raw = detail.trim();
1222
- const desc = (description ?? "").trim();
1223
- if (!looksLikeFilePath(raw)) {
1224
- const clipped = clipChatLine(raw);
1225
- if (!clipped || desc === clipped || desc === raw) return void 0;
1226
- return clipped;
1227
- }
1228
- const rel = stripWorktreePrefix(raw, worktreePath);
1229
- if (!rel) return void 0;
1230
- const base = fileBasename(rel);
1231
- if (desc && (desc === base || desc.endsWith(` ${base}`))) return void 0;
1232
- if (rel.length <= 42) return rel;
1233
- const parts = rel.split(/[/\\]/).filter(Boolean);
1234
- if (parts.length >= 2) return `\u2026/${parts.slice(-2).join("/")}`;
1235
- return base;
1236
- }
1237
- function isSkillToolName(name) {
1238
- const n = (name ?? "").trim();
1239
- if (/^(Skill|SlashCommand)$/i.test(n)) return true;
1240
- return /(?:^|__)Skill$/i.test(n);
1241
- }
1242
- function skillCommandFromInput(input) {
1243
- const raw = str(input?.skill) ?? str(input?.command) ?? str(input?.name) ?? str(input?.skill_name) ?? str(input?.skillName);
1244
- if (raw) return raw.replace(/^\//, "").trim() || void 0;
1245
- const path = str(input?.file_path) ?? str(input?.path);
1246
- if (path && /SKILL\.md$/i.test(path)) {
1247
- const parts = path.replace(/\\/g, "/").split("/");
1248
- const dir = parts[parts.length - 2];
1249
- if (dir && dir !== "skills") return dir;
1250
- }
1251
- return void 0;
1252
- }
1253
- function looksLikeComposerSkillExpansion(text) {
1254
- const t = text.trim();
1255
- return /^## Skill: \//m.test(t) && /Follow this skill for the request above:/i.test(t);
1256
- }
1257
- var SKILL_FRONTMATTER_NAME = /^\s*name\s*:\s*['"]?([A-Za-z0-9][A-Za-z0-9._-]*)['"]?\s*$/m;
1258
- function skillNameFromFrontmatter(text) {
1259
- const t = text.trim();
1260
- if (!t) return void 0;
1261
- let yaml = t;
1262
- if (!yaml.startsWith("---")) {
1263
- const at = t.search(/(?:^|\n)---(?:\r?\n)/);
1264
- if (at < 0 || at > 800) return void 0;
1265
- yaml = t.slice(at).replace(/^\n/, "");
1266
- }
1267
- if (!yaml.startsWith("---")) return void 0;
1268
- const close = yaml.indexOf("\n---", 3);
1269
- if (close < 0) return void 0;
1270
- return yaml.slice(3, close).match(SKILL_FRONTMATTER_NAME)?.[1];
1271
- }
1272
- function skillCommandFromBody(text) {
1273
- return skillNameFromFrontmatter(text) ?? text.match(/^## Skill: \/([A-Za-z0-9][A-Za-z0-9._-]*)/m)?.[1] ?? text.match(/^Launching skill:\s*\/?([A-Za-z0-9][A-Za-z0-9._-]*)/im)?.[1];
1274
- }
1275
- function looksLikeSkillBody(text) {
1276
- const t = text.trim();
1277
- if (!t) return false;
1278
- if (looksLikeComposerSkillExpansion(t)) return true;
1279
- if (skillNameFromFrontmatter(t) != null) return true;
1280
- return /^Launching skill:/im.test(t) && /Base directory for this skill:/i.test(t);
1281
- }
1282
- function looksLikeIncompleteSkillDump(text) {
1283
- const t = text.trim();
1284
- if (!t || looksLikeSkillBody(t)) return false;
1285
- if (/^## Skill: \//m.test(t)) return true;
1286
- if (/^Launching skill:/im.test(t)) return true;
1287
- if (/Base directory for this skill:/i.test(t)) return true;
1288
- return t.startsWith("---") && SKILL_FRONTMATTER_NAME.test(t);
1289
- }
1290
- function isCompactToolName(name) {
1291
- const short = (name ?? "").replace(/^mcp__[^_]+__/, "").trim();
1292
- return /^(Compact|ConversationCompact|summarize_context|SummarizeContext|SummarizeConversation)$/i.test(
1293
- short
1294
- );
1295
- }
1296
- function isContextCompactDone(text) {
1297
- return /\bContext compressed\b/i.test(text.trim());
1298
- }
1299
- function isContextCompactInProgress(text) {
1300
- const t = text.trim();
1301
- if (isContextCompactDone(t)) return false;
1302
- return /^Compressing context/i.test(t);
1303
- }
1304
- function isSystemStatusThinking(event) {
1305
- if (event.replace) return true;
1306
- const t = (event.data ?? "").trim();
1307
- if (!t) return true;
1308
- if (/^API retry\b/i.test(t)) return true;
1309
- if (/^MCP:/i.test(t)) return true;
1310
- if (isContextCompactInProgress(t) || isContextCompactDone(t)) return true;
1311
- return false;
1312
- }
1313
- function looksLikeConversationSummary(text) {
1314
- const t = text.trim();
1315
- if (t.length < 80) return false;
1316
- if (/<summarized_conversation\b/i.test(t) || /<conversation_summary\b/i.test(t)) {
1317
- return true;
1318
- }
1319
- if (/this session is being continued from a previous conversation/i.test(t)) {
1320
- return true;
1321
- }
1322
- if (/conversation compacted|replaced with a summary/i.test(t)) return true;
1323
- if (/^## Prior summary\b/m.test(t)) return true;
1324
- if (/_Automatic extractive summary/i.test(t)) return true;
1325
- if (/"context_summary"\s*:/.test(t)) return true;
1326
- if (/^(?:#+\s*)?(?:conversation summary|summary of (?:the )?conversation|compacted (?:conversation|context))\b/im.test(
1327
- t
1328
- )) {
1329
- return true;
1330
- }
1331
- return false;
1332
- }
1333
- function toolDetail(name, input) {
1334
- if (isSkillToolName(name) || isCompactToolName(name)) return void 0;
1335
- if (!input) return void 0;
1336
- const command = str(input.command) ?? str(input.cmd);
1337
- if (command) return clipChatLine(command);
1338
- const pattern = str(input.pattern) ?? str(input.glob) ?? str(input.glob_pattern);
1339
- const isSearch = /grep|glob|search|ripgrep|findfiles|semsearch/i.test(name);
1340
- if (isSearch && pattern) {
1341
- return pattern.length > 80 ? `${pattern.slice(0, 77)}\u2026` : pattern;
1342
- }
1343
- const path = str(input.file_path) ?? str(input.path) ?? str(input.filePath) ?? str(input.filename);
1344
- if (path) return path;
1345
- if (pattern) return pattern.length > 80 ? `${pattern.slice(0, 77)}\u2026` : pattern;
1346
- const query = str(input.query) ?? str(input.prompt);
1347
- if (query) return query.length > 80 ? `${query.slice(0, 77)}\u2026` : query;
1348
- try {
1349
- const raw = JSON.stringify(input);
1350
- return raw.length > 80 ? `${raw.slice(0, 77)}\u2026` : raw;
1351
- } catch {
1352
- return name;
1353
- }
1354
- }
1355
- function toolDescription(name, input) {
1356
- const n = name.replace(/^mcp__/, "").replace(/__/g, " \xB7 ");
1357
- if (/^get_record_types$|recordTypes/i.test(name)) return "List record types";
1358
- if (/connectedAgentRequest/i.test(name)) {
1359
- return str(input?.agent_id) ? `Ask connected agent` : "Ask connected agent";
1360
- }
1361
- if (/present_artifact$/i.test(name)) {
1362
- return str(input?.title) ? `Present ${str(input?.title)}` : "Present artifact";
1363
- }
1364
- if (/present_plan$/i.test(name)) {
1365
- return str(input?.title) ? `Plan ${str(input?.title)}` : "Present plan";
1366
- }
1367
- if (/present_schema$/i.test(name)) {
1368
- return str(input?.title) ? `Schema ${str(input?.title)}` : "Present schema";
1369
- }
1370
- if (/present_files$/i.test(name)) {
1371
- return str(input?.title) ? `Files ${str(input?.title)}` : "Present files";
1372
- }
1373
- if (/wait_for_job$/i.test(name)) {
1374
- return str(input?.id) ? `Wait for ${str(input?.id)}` : "Wait for job";
1375
- }
1376
- if (/stop_job$/i.test(name)) {
1377
- return str(input?.id) ? `Stop ${str(input?.id)}` : "Stop job";
1378
- }
1379
- if (/list_run_scripts$/i.test(name)) return "List run scripts";
1380
- if (/run_dev_script$/i.test(name)) {
1381
- return str(input?.name) ? `Start ${str(input?.name)}` : "Start Dev script";
1382
- }
1383
- if (/stop_dev_script$/i.test(name)) {
1384
- return str(input?.name) ? `Stop ${str(input?.name)}` : "Stop Dev script";
1385
- }
1386
- if (/get_run_log$/i.test(name)) {
1387
- return str(input?.name) ? `Read ${str(input?.name)} log` : "Read Dev log";
1388
- }
1389
- if (/notify_orchestrator$/i.test(name)) return "Notify orchestrator";
1390
- if (/list_schedules$/i.test(name)) return "List schedules";
1391
- if (/create_schedule$/i.test(name)) {
1392
- return str(input?.name) ? `Schedule ${str(input?.name)}` : "Create schedule";
1393
- }
1394
- if (/update_schedule$/i.test(name)) return "Update schedule";
1395
- if (/delete_schedule$/i.test(name)) return "Delete schedule";
1396
- if (/run_schedule$/i.test(name)) return "Run schedule";
1397
- if (isSkillToolName(name)) {
1398
- const cmd = skillCommandFromInput(input);
1399
- return cmd ? `Using /${cmd}` : "Using skill";
1400
- }
1401
- if (isCompactToolName(name)) {
1402
- const trigger = str(input?.trigger);
1403
- if (trigger && !/^auto$/i.test(trigger) && trigger !== "injected") {
1404
- return `Summarized conversation (${trigger})`;
1405
- }
1406
- return "Summarized conversation";
1407
- }
1408
- if (isSubagentToolName(name)) {
1409
- const desc = str(input?.description);
1410
- const sub = asRecord(input?.subagentType);
1411
- const kind = str(sub?.name) ?? str(sub?.kind) ?? str(input?.subagent_type) ?? str(input?.subagentType);
1412
- if (/^spawn_agent$/i.test(name)) {
1413
- return str(input?.prompt) ?? desc ?? "Subagent";
1414
- }
1415
- if (/connectedAgentRequest/i.test(name)) {
1416
- return str(input?.agent_id) ? `Ask connected agent` : "Ask connected agent";
1417
- }
1418
- if (desc && kind) return `${kind}: ${desc}${subagentLiveSuffix(input)}`;
1419
- if (desc) return `${desc}${subagentLiveSuffix(input)}`;
1420
- return `Subagent${subagentLiveSuffix(input)}`;
1421
- }
1422
- if (/^(create|update)_artifact$/i.test(name.replace(/^mcp__[^_]+__/, ""))) {
1423
- return str(input?.title) ? `Artifact ${str(input?.title)}` : "Artifact";
1424
- }
1425
- if (!input) return n;
1426
- if (/bash|shell|terminal/i.test(name) && str(input.command)) {
1427
- const cmd = str(input.command);
1428
- if (/git\s+fetch/i.test(cmd)) return "Fetch latest from origin and check status";
1429
- if (/git\s+status/i.test(cmd)) return "Check git status";
1430
- if (/git\s+log/i.test(cmd)) return "Inspect recent commits";
1431
- if (/git\s+branch/i.test(cmd)) return "List branches";
1432
- if (/grep|rg\b/i.test(cmd)) return "Search repository";
1433
- return "Run shell command";
1434
- }
1435
- if (/edit|write|apply/i.test(name)) {
1436
- const path = str(input.file_path) ?? str(input.path);
1437
- return path ? `Edit ${path.split("/").pop()}` : "Edit file";
1438
- }
1439
- if (/read/i.test(name)) {
1440
- const path = str(input.file_path) ?? str(input.path);
1441
- return path ? `Read ${path.split("/").pop()}` : "Read file";
1442
- }
1443
- if (/grep/i.test(name)) return "Search files";
1444
- if (/glob/i.test(name)) return "Find files";
1445
- const compact = n.replace(/[_-]/g, "");
1446
- if (/^taskoutput$/i.test(compact)) {
1447
- return str(input.task_id) ? `Wait for ${str(input.task_id)}` : "Wait for background task";
1448
- }
1449
- if (/^taskstop$/i.test(compact)) {
1450
- return str(input.task_id) ? `Stop ${str(input.task_id)}` : "Stop background task";
1451
- }
1452
- if (/^monitor$/i.test(compact)) {
1453
- const command = str(input.command);
1454
- return command ? `Watch ${command.length > 48 ? `${command.slice(0, 45)}\u2026` : command}` : "Watch command";
1455
- }
1456
- return n;
1457
- }
1458
- function subagentLiveSuffix(input) {
1459
- if (!input) return "";
1460
- const bits = [];
1461
- const status = str(input.live_status);
1462
- if (status && !/^runn(ing)?$|^working$/i.test(status)) bits.push(status);
1463
- if (typeof input.live_tool_uses === "number") bits.push(`${input.live_tool_uses} tools`);
1464
- if (typeof input.live_duration_ms === "number") {
1465
- bits.push(`${Math.max(0, Math.round(Number(input.live_duration_ms) / 1e3))}s`);
1466
- }
1467
- const last = str(input.live_last_tool);
1468
- if (last) bits.push(last);
1469
- return bits.length ? ` \xB7 ${bits.join(" \xB7 ")}` : "";
1470
- }
1471
- function isSubagentToolName(name) {
1472
- const n = (name ?? "").trim();
1473
- if (/^(task|agent|spawn_agent)$/i.test(n)) return true;
1474
- return /connectedAgentRequest/i.test(n);
1475
- }
1476
- function isInternalAgentStatusText(text) {
1477
- const t = text.trim();
1478
- if (!t) return false;
1479
- if (/waiting for gate to pass/i.test(t)) return true;
1480
- if (/^agent is running\b/i.test(t) && t.length < 160) return true;
1481
- return false;
1482
- }
1483
- function isPollWrapperToolName(name) {
1484
- const n = (name ?? "").replace(/[_-]/g, "");
1485
- return /^(taskoutput|taskstop|sleep)$/i.test(n);
1486
- }
1487
- function lastTextPart(parts, type) {
1488
- for (let i = parts.length - 1; i >= 0; i--) {
1489
- const p = parts[i];
1490
- if (p.type !== type) continue;
1491
- const text = p.text.trim();
1492
- if (!text || isInternalAgentStatusText(text)) continue;
1493
- return text;
1494
- }
1495
- return "";
1496
- }
1497
- function toolLabel(tool) {
1498
- return tool.description || toolDescription(tool.name, tool.input) || tool.name;
1499
- }
1500
- function fileBasename(path) {
1501
- const parts = path.replace(/\/$/, "").split(/[/\\]/);
1502
- return parts[parts.length - 1] || path;
1503
- }
1504
- function classifyTool(name) {
1505
- const compact = name.replace(/^mcp__[^_]+__/, "").replace(/[_-]/g, "");
1506
- if (/bash|shell|terminal|^zsh$|^sh$/i.test(compact)) return "shell";
1507
- if (/grep|glob|search|ripgrep|findfiles|semsearch/i.test(compact)) return "search";
1508
- if (/^(read|cat)$/i.test(compact) || /^read/i.test(compact)) return "read";
1509
- if (/edit|write|apply|strreplace|multiedit|updatefile|createfile/i.test(compact)) {
1510
- return "edit";
1511
- }
1512
- return "other";
1513
- }
1514
- function isShellToolName(name) {
1515
- return classifyTool(name ?? "") === "shell";
1516
- }
1517
- function toolActivityLine(parts) {
1518
- const tools = parts.filter((p) => {
1519
- if (p.type !== "tool" || p.parentId) return false;
1520
- if (isPollWrapperToolName(p.name)) return false;
1521
- if (/present_plan$/i.test(p.name ?? "")) return false;
1522
- if (/ask_user|AskUserQuestion/i.test(p.name ?? "")) return false;
1523
- return true;
1524
- });
1525
- if (tools.length === 0) return null;
1526
- const edited = [];
1527
- const skillNames = [];
1528
- let compacts = 0;
1529
- let reads = 0;
1530
- let searches = 0;
1531
- let shells = 0;
1532
- let others = 0;
1533
- let additions = 0;
1534
- let deletions = 0;
1535
- for (const tool of tools) {
1536
- const kind = classifyTool(tool.name);
1537
- if (isSkillToolName(tool.name)) {
1538
- const cmd = skillCommandFromInput(tool.input);
1539
- skillNames.push(cmd ? `/${cmd}` : "skill");
1540
- } else if (isCompactToolName(tool.name)) {
1541
- compacts += 1;
1542
- } else if (kind === "edit") {
1543
- const path = tool.filePath ?? toolFilePath(tool.input);
1544
- edited.push({
1545
- name: path ? fileBasename(path) : tool.name,
1546
- running: tool.status === "running"
1547
- });
1548
- } else if (kind === "read") reads += 1;
1549
- else if (kind === "search") searches += 1;
1550
- else if (kind === "shell") shells += 1;
1551
- else others += 1;
1552
- if (typeof tool.additions === "number") additions += tool.additions;
1553
- if (typeof tool.deletions === "number") deletions += tool.deletions;
1554
- }
1555
- const bits = [];
1556
- const editing = edited.filter((e) => e.running);
1557
- const editedDone = edited.filter((e) => !e.running);
1558
- if (editing.length === 1) bits.push(`Editing ${editing[0].name}`);
1559
- else if (editing.length > 1) bits.push(`Editing ${editing.length} files`);
1560
- if (editedDone.length === 1) bits.push(`${editing.length ? "edited" : "Edited"} ${editedDone[0].name}`);
1561
- else if (editedDone.length > 1) {
1562
- bits.push(`${editing.length ? "edited" : "Edited"} ${editedDone.length} files`);
1563
- }
1564
- if (reads === 1) bits.push("explored 1 file");
1565
- else if (reads > 1) bits.push(`explored ${reads} files`);
1566
- if (searches === 1) bits.push("1 search");
1567
- else if (searches > 1) bits.push(`${searches} searches`);
1568
- if (shells === 1) bits.push("ran 1 command");
1569
- else if (shells > 1) bits.push(`ran ${shells} commands`);
1570
- if (skillNames.length === 1) bits.push(`used ${skillNames[0]}`);
1571
- else if (skillNames.length > 1) bits.push(`used ${skillNames.length} skills`);
1572
- if (compacts === 1) bits.push("summarized conversation");
1573
- else if (compacts > 1) bits.push(`summarized conversation \xD7${compacts}`);
1574
- if (others === 1) bits.push("1 tool");
1575
- else if (others > 1) bits.push(`${others} tools`);
1576
- if (bits.length === 0) return null;
1577
- return { text: bits.join(", "), additions, deletions };
1578
- }
1579
- function liveActivitySummary(parts, opts) {
1580
- if (opts?.queued && parts.length === 0) {
1581
- return "Queued \u2014 waiting for a slot";
1582
- }
1583
- const tools = parts.filter((p) => p.type === "tool");
1584
- const runningSubs = tools.filter(
1585
- (t) => t.status === "running" && !t.parentId && isSubagentToolName(t.name)
1586
- );
1587
- const runningNested = [...tools].reverse().find((t) => t.status === "running" && t.parentId && !isPollWrapperToolName(t.name));
1588
- const runningTop = [...tools].reverse().find(
1589
- (t) => t.status === "running" && !t.parentId && !isPollWrapperToolName(t.name) && !isSubagentToolName(t.name)
1590
- );
1591
- const runningPoll = [...tools].reverse().find((t) => t.status === "running" && isPollWrapperToolName(t.name));
1592
- const thinking = lastTextPart(parts, "thinking");
1593
- const text = lastTextPart(parts, "text");
1594
- if (runningSubs.length > 0) {
1595
- const heads = runningSubs.map(toolLabel);
1596
- const head = runningSubs.length === 1 ? heads[0] : `${runningSubs.length} subagents \xB7 ${heads.slice(0, 2).join(" \xB7 ")}`;
1597
- if (runningNested) return `${head} \xB7 ${toolLabel(runningNested)}`;
1598
- return head;
1599
- }
1600
- if (runningTop) return toolLabel(runningTop);
1601
- if (runningPoll) return toolLabel(runningPoll);
1602
- if (thinking) return thinking.length > 96 ? `\u2026${thinking.slice(-96)}` : thinking;
1603
- if (text) return "Writing reply\u2026";
1604
- const last = [...tools].reverse().find((t) => !isPollWrapperToolName(t.name)) ?? tools.at(-1);
1605
- if (last) {
1606
- const label = toolLabel(last);
1607
- return last.status === "running" ? label : `Finished ${label}`;
1608
- }
1609
- return "Working\u2026";
1610
- }
1611
- function messagePartParentId(part) {
1612
- if ("parentId" in part && typeof part.parentId === "string" && part.parentId.trim()) {
1613
- return part.parentId;
1614
- }
1615
- return void 0;
1616
- }
1617
- function sameParentId(a, b) {
1618
- return (a ?? "") === (b ?? "");
1619
- }
1620
- function withEventParentId(event, parentId) {
1621
- if (!parentId) return event;
1622
- if (event.type === "stdout" || event.type === "thinking" || event.type === "tool_use" || event.type === "tool_result") {
1623
- return { ...event, parentId: event.parentId ?? parentId };
1624
- }
1625
- return event;
1626
- }
1627
- function withEventsParentId(events, parentId) {
1628
- if (!parentId) return events;
1629
- return events.map((event) => withEventParentId(event, parentId));
1630
- }
1631
- function toolFilePath(input) {
1632
- if (!input) return void 0;
1633
- return str(input.file_path) ?? str(input.path) ?? str(input.filePath) ?? str(input.filename);
1634
- }
1635
- function countLines(text) {
1636
- if (!text) return 0;
1637
- return text.split("\n").length;
1638
- }
1639
- function diffFromInput(input) {
1640
- if (!input) return {};
1641
- const oldS = str(input.old_string) ?? str(input.oldString);
1642
- const newS = str(input.new_string) ?? str(input.newString) ?? str(input.content);
1643
- if (oldS != null || newS != null) {
1644
- return {
1645
- additions: countLines(newS),
1646
- deletions: countLines(oldS)
1647
- };
1648
- }
1649
- return {};
1650
- }
1651
- function parseDiffStat(result) {
1652
- if (!result) return {};
1653
- const paired = result.match(/\+(\d+)\s+-(\d+)/);
1654
- if (paired) {
1655
- return {
1656
- additions: Number(paired[1]),
1657
- deletions: Number(paired[2])
1658
- };
1659
- }
1660
- const verbose = result.match(
1661
- /(\d+)\s+insertions?(?:,\s*(\d+)\s+deletions?)?/i
1662
- );
1663
- if (verbose) {
1664
- return {
1665
- additions: Number(verbose[1]),
1666
- deletions: verbose[2] != null ? Number(verbose[2]) : void 0
1667
- };
1668
- }
1669
- return {};
1670
- }
1671
- var THINKING_PART_MAX_CHARS = 64e3;
1672
- function clipThinkingForStore(text, max = THINKING_PART_MAX_CHARS) {
1673
- if (text.length <= max) return text;
1674
- const marker = "\u2026(earlier thinking trimmed)\n";
1675
- return marker + text.slice(text.length - Math.max(1, max - marker.length));
1676
- }
1677
- var STDOUT_EVENT_MAX_CHARS = 16e3;
1678
- var STDERR_EVENT_MAX_CHARS = 4e3;
1679
- function clipEventTail(text, max) {
1680
- if (text.length <= max) return text;
1681
- const marker = "\u2026(truncated)\n";
1682
- return marker + text.slice(text.length - Math.max(1, max - marker.length));
1683
- }
1684
- function clipAgentEventForPaint(event) {
1685
- if (event.type === "tool_result" && event.content) {
1686
- const content = clipToolResultForStore(event.content);
1687
- if (content === event.content) return event;
1688
- return { ...event, content };
1689
- }
1690
- if (event.type === "thinking" && event.data.length > THINKING_PART_MAX_CHARS) {
1691
- return { ...event, data: clipThinkingForStore(event.data) };
1692
- }
1693
- if (event.type === "stdout" && event.data.length > STDOUT_EVENT_MAX_CHARS) {
1694
- return { ...event, data: clipEventTail(event.data, STDOUT_EVENT_MAX_CHARS) };
1695
- }
1696
- if (event.type === "stderr" && event.data.length > STDERR_EVENT_MAX_CHARS) {
1697
- return { ...event, data: clipEventTail(event.data, STDERR_EVENT_MAX_CHARS) };
1698
- }
1699
- return event;
1700
- }
1701
- function withPartTimes(next, prev) {
1702
- const now = Date.now();
1703
- const startedAt = prev && typeof prev.startedAt === "number" ? prev.startedAt : now;
1704
- return { ...next, startedAt, updatedAt: now };
1705
- }
1706
- function skillToolFromTextPart(part, id, status = "done") {
1707
- const command = skillCommandFromBody(part.text);
1708
- const input = command ? { skill: command } : void 0;
1709
- return {
1710
- type: "tool",
1711
- id: command ? `skill-${command}` : id,
1712
- name: "Skill",
1713
- input,
1714
- description: toolDescription("Skill", input),
1715
- status,
1716
- result: clipToolResultForStore(part.text),
1717
- ...part.parentId ? { parentId: part.parentId } : {},
1718
- startedAt: part.startedAt,
1719
- updatedAt: Date.now()
1720
- };
1721
- }
1722
- function lastSkillToolIndex(parts, parentId) {
1723
- for (let i = parts.length - 1; i >= 0; i--) {
1724
- const p = parts[i];
1725
- if (p.type === "tool" && isSkillToolName(p.name) && sameParentId(p.parentId, parentId)) {
1726
- return i;
1727
- }
1728
- }
1729
- return -1;
1730
- }
1731
- function lastRunningSkillIndex(parts, parentId) {
1732
- for (let i = parts.length - 1; i >= 0; i--) {
1733
- const p = parts[i];
1734
- if (p.type === "tool" && isSkillToolName(p.name) && p.status === "running" && sameParentId(p.parentId, parentId)) {
1735
- return i;
1736
- }
1737
- }
1738
- return -1;
1739
- }
1740
- function markRunningSkillsDone(parts, parentId) {
1741
- return parts.map((p) => {
1742
- if (p.type === "tool" && isSkillToolName(p.name) && p.status === "running" && sameParentId(p.parentId, parentId)) {
1743
- return withPartTimes({ ...p, status: "done" }, p);
1744
- }
1745
- return p;
1746
- });
1747
- }
1748
- function promoteOrFoldSkillText(parts, textIdx) {
1749
- const acc = parts[textIdx];
1750
- if (acc?.type !== "text") return parts;
1751
- const complete = looksLikeSkillBody(acc.text);
1752
- const incomplete = looksLikeIncompleteSkillDump(acc.text);
1753
- if (!complete && !incomplete) return parts;
1754
- const existing = lastSkillToolIndex(parts, acc.parentId);
1755
- if (existing >= 0 && existing !== textIdx) {
1756
- const prev = parts[existing];
1757
- const next2 = parts.filter((_, i) => i !== textIdx);
1758
- const existingIdx = lastSkillToolIndex(next2, acc.parentId);
1759
- if (existingIdx < 0) return parts;
1760
- next2[existingIdx] = withPartTimes(
1761
- {
1762
- ...prev,
1763
- status: complete ? "done" : prev.status,
1764
- result: clipToolResultForStore(acc.text) ?? prev.result
1765
- },
1766
- prev
1767
- );
1768
- return next2;
1769
- }
1770
- const next = [...parts];
1771
- next[textIdx] = skillToolFromTextPart(
1772
- acc,
1773
- `skill-${next.length}`,
1774
- complete ? "done" : "running"
1775
- );
1776
- return next;
1777
- }
1778
- function compactSummaryPart(text, id = "compact-summary") {
1779
- return compactToolPart(text, id, { status: "done" });
1780
- }
1781
- function compactPartsForSummaryMessage(message) {
1782
- const existing = (message.parts ?? []).filter(
1783
- (p) => p.type === "tool" && isCompactToolName(p.name)
1784
- );
1785
- if (existing.length) return existing;
1786
- return [compactSummaryPart(message.text ?? "")];
1787
- }
1788
- function compactToolPart(text, id, opts) {
1789
- const input = { trigger: opts?.trigger ?? "auto" };
1790
- return withPartTimes(
1791
- {
1792
- type: "tool",
1793
- id,
1794
- name: "Compact",
1795
- input,
1796
- description: toolDescription("Compact", input),
1797
- status: opts?.status ?? "done",
1798
- result: clipToolResultForStore(text) ?? "",
1799
- ...opts?.parentId ? { parentId: opts.parentId } : {}
1800
- },
1801
- opts?.prev
1802
- );
1803
- }
1804
- function contextCompactInProgress(parts, parentId) {
1805
- let compressing = false;
1806
- for (const p of parts) {
1807
- if (!sameParentId(p.parentId, parentId)) continue;
1808
- if (p.type === "thinking" && isContextCompactInProgress(p.text)) compressing = true;
1809
- if (p.type === "thinking" && isContextCompactDone(p.text)) compressing = false;
1810
- }
1811
- return compressing;
1812
- }
1813
- function lastRunningCompactIndex(parts, parentId) {
1814
- for (let i = parts.length - 1; i >= 0; i--) {
1815
- const p = parts[i];
1816
- if (p.type === "tool" && isCompactToolName(p.name) && p.status === "running" && sameParentId(p.parentId, parentId)) {
1817
- return i;
1818
- }
1819
- }
1820
- return -1;
1821
- }
1822
- function markRunningCompactDone(parts, parentId) {
1823
- return parts.map((p) => {
1824
- if (p.type === "tool" && isCompactToolName(p.name) && p.status === "running" && sameParentId(p.parentId, parentId)) {
1825
- return withPartTimes({ ...p, status: "done" }, p);
1826
- }
1827
- return p;
1828
- });
1829
- }
1830
- function ensureCompactTool(parts, parentId) {
1831
- const hasCompact = parts.some(
1832
- (p) => p.type === "tool" && isCompactToolName(p.name) && sameParentId(p.parentId, parentId)
1833
- );
1834
- if (hasCompact) return parts;
1835
- return [
1836
- ...parts,
1837
- compactToolPart("Context compressed", `compact-${parts.length}`, {
1838
- parentId,
1839
- status: "done"
1840
- })
1841
- ];
1842
- }
1843
- function withCompactFinish(parts, thinking, parentId) {
1844
- if (!isContextCompactDone(thinking)) return parts;
1845
- return ensureCompactTool(markRunningCompactDone(parts, parentId), parentId);
1846
- }
1847
- function applyAgentEvent(parts, event) {
1848
- if (event.type === "stdout") {
1849
- const data = event.data;
1850
- if (!data) return parts;
1851
- const runningIdx = lastRunningCompactIndex(parts, event.parentId);
1852
- if (runningIdx >= 0) {
1853
- const prev = parts[runningIdx];
1854
- const next2 = [...parts];
1855
- next2[runningIdx] = withPartTimes(
1856
- {
1857
- ...prev,
1858
- result: clipToolResultForStore(`${prev.result ?? ""}${data}`)
1859
- },
1860
- prev
1861
- );
1862
- return next2;
1863
- }
1864
- const runningSkillIdx = lastRunningSkillIndex(parts, event.parentId);
1865
- if (runningSkillIdx >= 0) {
1866
- const prev = parts[runningSkillIdx];
1867
- const result = `${prev.result ?? ""}${data}`;
1868
- const next2 = [...parts];
1869
- next2[runningSkillIdx] = withPartTimes(
1870
- {
1871
- ...prev,
1872
- result: clipToolResultForStore(result),
1873
- // Stay running after the YAML `name:` fence so later content_block_delta
1874
- // tokens of SKILL.md stay on this row. thinking / tool_use / finalizeParts
1875
- // mark the row done so the real reply can be chat.
1876
- status: "running"
1877
- },
1878
- prev
1879
- );
1880
- return next2;
1881
- }
1882
- if (contextCompactInProgress(parts, event.parentId)) {
1883
- return [
1884
- ...parts,
1885
- compactToolPart(data, `compact-${parts.length}`, {
1886
- parentId: event.parentId,
1887
- status: "running"
1888
- })
1889
- ];
1890
- }
1891
- const next = [...parts];
1892
- const last = next[next.length - 1];
1893
- if (last?.type === "text" && sameParentId(last.parentId, event.parentId)) {
1894
- next[next.length - 1] = withPartTimes(
1895
- {
1896
- type: "text",
1897
- text: last.text + data,
1898
- ...event.parentId ? { parentId: event.parentId } : {}
1899
- },
1900
- last
1901
- );
1902
- } else {
1903
- next.push(
1904
- withPartTimes({
1905
- type: "text",
1906
- text: data,
1907
- ...event.parentId ? { parentId: event.parentId } : {}
1908
- })
1909
- );
1910
- }
1911
- const acc = next[next.length - 1];
1912
- if (acc?.type === "text" && (looksLikeSkillBody(acc.text) || looksLikeIncompleteSkillDump(acc.text))) {
1913
- return promoteOrFoldSkillText(next, next.length - 1);
1914
- }
1915
- if (acc?.type === "text" && looksLikeConversationSummary(acc.text)) {
1916
- next[next.length - 1] = compactToolPart(acc.text, `compact-${next.length}`, {
1917
- parentId: acc.parentId,
1918
- status: "done",
1919
- prev: acc
1920
- });
1921
- }
1922
- return next;
1923
- }
1924
- if (event.type === "thinking") {
1925
- const data = event.data;
1926
- if (!data) return parts;
1927
- if (!isSystemStatusThinking(event)) {
1928
- parts = markRunningSkillsDone(parts, event.parentId);
1929
- }
1930
- const next = [...parts];
1931
- if (event.replace) {
1932
- for (let i = next.length - 1; i >= 0; i--) {
1933
- const prev = next[i];
1934
- if (prev?.type === "thinking" && sameParentId(prev.parentId, event.parentId)) {
1935
- next[i] = withPartTimes(
1936
- {
1937
- type: "thinking",
1938
- text: clipThinkingForStore(data),
1939
- ...event.parentId ? { parentId: event.parentId } : {}
1940
- },
1941
- prev
1942
- );
1943
- return withCompactFinish(next, data, event.parentId);
1944
- }
1945
- }
1946
- next.push(
1947
- withPartTimes({
1948
- type: "thinking",
1949
- text: clipThinkingForStore(data),
1950
- ...event.parentId ? { parentId: event.parentId } : {}
1951
- })
1952
- );
1953
- return withCompactFinish(next, data, event.parentId);
1954
- }
1955
- const last = next[next.length - 1];
1956
- if (last?.type === "thinking" && sameParentId(last.parentId, event.parentId)) {
1957
- next[next.length - 1] = withPartTimes(
1958
- {
1959
- type: "thinking",
1960
- text: clipThinkingForStore(last.text + data),
1961
- ...event.parentId ? { parentId: event.parentId } : {}
1962
- },
1963
- last
1964
- );
1965
- } else {
1966
- next.push(
1967
- withPartTimes({
1968
- type: "thinking",
1969
- text: clipThinkingForStore(data),
1970
- ...event.parentId ? { parentId: event.parentId } : {}
1971
- })
1972
- );
1973
- }
1974
- return withCompactFinish(next, data, event.parentId);
1975
- }
1976
- if (event.type === "tool_use") {
1977
- parts = markRunningSkillsDone(parts, event.parentId);
1978
- const input = asRecord(event.input);
1979
- const diff = diffFromInput(input);
1980
- const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
1981
- if (existing >= 0) {
1982
- const prev = parts[existing];
1983
- const next = [...parts];
1984
- const mergedInput = {
1985
- ...prev.input ?? {},
1986
- ...input ?? {}
1987
- };
1988
- const mergedRecord = Object.keys(mergedInput).length > 0 ? mergedInput : void 0;
1989
- next[existing] = withPartTimes(
1990
- {
1991
- ...prev,
1992
- name: event.name || prev.name,
1993
- input: mergedRecord,
1994
- description: toolDescription(event.name || prev.name, mergedRecord),
1995
- detail: toolDetail(event.name || prev.name, mergedRecord) ?? prev.detail,
1996
- filePath: toolFilePath(mergedRecord) ?? prev.filePath,
1997
- additions: diff.additions ?? prev.additions,
1998
- deletions: diff.deletions ?? prev.deletions,
1999
- parentId: event.parentId ?? prev.parentId
2000
- },
2001
- prev
2002
- );
2003
- return next;
2004
- }
2005
- return [
2006
- ...parts,
2007
- withPartTimes({
2008
- type: "tool",
2009
- id: event.id,
2010
- name: event.name,
2011
- input,
2012
- description: toolDescription(event.name, input),
2013
- detail: toolDetail(event.name, input),
2014
- status: "running",
2015
- filePath: toolFilePath(input),
2016
- ...event.parentId ? { parentId: event.parentId } : {},
2017
- ...diff
2018
- })
2019
- ];
2020
- }
2021
- if (event.type === "tool_result") {
2022
- const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
2023
- const fromResult = parseDiffStat(event.content);
2024
- if (event.partial) {
2025
- if (existing < 0) {
2026
- return [
2027
- ...parts,
2028
- withPartTimes({
2029
- type: "tool",
2030
- id: event.id,
2031
- name: "tool",
2032
- description: "tool",
2033
- status: event.isError ? "error" : "running",
2034
- result: clipToolResultForStore(event.content),
2035
- ...event.parentId ? { parentId: event.parentId } : {}
2036
- })
2037
- ];
2038
- }
2039
- return parts.map((p, i) => {
2040
- if (i !== existing || p.type !== "tool") return p;
2041
- if (p.status === "done" || p.status === "error") return p;
2042
- return withPartTimes(
2043
- {
2044
- ...p,
2045
- result: clipToolResultForStore(event.content) ?? p.result
2046
- },
2047
- p
2048
- );
2049
- });
2050
- }
2051
- if (existing < 0) {
2052
- return [
2053
- ...parts,
2054
- withPartTimes({
2055
- type: "tool",
2056
- id: event.id,
2057
- name: "tool",
2058
- description: "tool",
2059
- status: event.isError ? "error" : "done",
2060
- result: clipToolResultForStore(event.content),
2061
- ...event.parentId ? { parentId: event.parentId } : {},
2062
- ...fromResult.additions != null ? { additions: fromResult.additions } : {},
2063
- ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
2064
- })
2065
- ];
2066
- }
2067
- return parts.map((p, i) => {
2068
- if (i !== existing || p.type !== "tool") return p;
2069
- return withPartTimes(
2070
- {
2071
- ...p,
2072
- status: event.isError ? "error" : "done",
2073
- result: clipToolResultForStore(event.content),
2074
- ...fromResult.additions != null ? { additions: fromResult.additions } : {},
2075
- ...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
2076
- },
2077
- p
2078
- );
2079
- });
2080
- }
2081
- return parts;
2082
- }
2083
- function partsToAssistantText(parts) {
2084
- return parts.filter(
2085
- (p) => p.type === "text" && !messagePartParentId(p)
2086
- ).map((p) => p.text).join("").trim();
2087
- }
2088
- function visibleAssistantText(text, parts) {
2089
- const fromParts = partsToAssistantText(parts ?? []);
2090
- if (fromParts) return fromParts;
2091
- if (parts?.some((p) => p.type === "tool" || p.type === "thinking")) return "";
2092
- return (text ?? "").trim();
2093
- }
2094
- function lastAssistantMessageText(parts) {
2095
- if (!parts?.length) return "";
2096
- for (let i = parts.length - 1; i >= 0; i--) {
2097
- const p = parts[i];
2098
- if (!p || p.type !== "text" || messagePartParentId(p)) continue;
2099
- const text = p.text.trim();
2100
- if (!text || isInternalAgentStatusText(text)) continue;
2101
- return text;
2102
- }
2103
- return "";
2104
- }
2105
- function stripBrightsyNdjsonNoise(text) {
2106
- if (!text || !text.includes('"type"')) return text;
2107
- let out = text;
2108
- out = out.replace(
2109
- /\{"type":"(?:tool_use|tool_result|tool|thinking|usage|done|error)"[\s\S]*?\}\s*(?=\{"type":"|$|(?=[A-Za-z*#]))/g,
2110
- ""
2111
- );
2112
- out = out.replace(/\{"type":"(?:tool_use|tool_result|tool)"[\s\S]*$/g, "");
2113
- return out.trim();
2114
- }
2115
- function isBrightsyNdjsonLine(line) {
2116
- const t = line.trim();
2117
- if (!t.startsWith("{")) return false;
2118
- return /"type"\s*:\s*"(tool_use|tool_result|tool|thinking|usage|done|error|text)"/.test(t);
2119
- }
2120
- function finalizeParts(parts) {
2121
- return parts.map(
2122
- (p) => p.type === "tool" && p.status === "running" ? { ...p, status: "done" } : p
2123
- );
2124
- }
2125
- function normalizeParseResult(parsed) {
2126
- if (!parsed) return [];
2127
- return Array.isArray(parsed) ? parsed : [parsed];
2128
- }
2129
-
2130
1192
  // src/agents/types.ts
2131
1193
  var PLAN_MODE_INSTRUCTION = "Plan mode is active and must remain active until the user turns Plan mode off in the UI (or Approves / Hands off the plan). Analyze the codebase, search and read files as needed, and produce or refine a clear implementation plan. Do not modify, create, or delete any project files except via Sideboard MCP present_plan (writes .context/attachments/plan.md). When you need a clarifying decision (approach forks, auth choice, scope) \u2014 not greetings, check-ins, or an invented task menu: (1) first write a short chat message that explains the decision and what each option means (tradeoffs, when to pick it) \u2014 do not leave the user staring at bare labels; (2) then call Sideboard MCP ask_user with the same options, including a description on every option. If one option is the obvious default, proceed without asking. Sideboard shows questions in the composer and mirrors them in chat. After ask_user, wait for the user's next message with their answers before finalizing the plan. When the plan is ready for approval: (1) call present_plan with the full markdown plan (title + content) so Sideboard saves .context/attachments/plan.md and shows it in chat for Approve / Hand off / Copy; (2) Claude should also call ExitPlanMode after present_plan. Do not skip present_plan \u2014 the plan must be a markdown file, not only chat prose.";
2132
1194
  var PLAN_MODE_OFF_INSTRUCTION = "Plan mode is off. Do not call present_plan or ExitPlanMode \u2014 those only work when the user turns Plan on in the composer. If you need to propose an approach, write it in chat.";
@@ -2683,7 +1745,7 @@ var claudeAdapter = {
2683
1745
  );
2684
1746
  }
2685
1747
  const mode = permissionMode(thread);
2686
- const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-TI26K25J.js");
1748
+ const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-EEWJOMED.js");
2687
1749
  const isOrchestrator = isOrchestratorThread2(thread);
2688
1750
  const rpc = worktreeAgentRpc(isOrchestrator);
2689
1751
  const injectedServers = await buildInjectedMcpServers({
@@ -3031,7 +2093,7 @@ function unwrapCodexMcpResult(result) {
3031
2093
  return String(result);
3032
2094
  }
3033
2095
  }
3034
- function asRecord2(value) {
2096
+ function asRecord(value) {
3035
2097
  if (value && typeof value === "object" && !Array.isArray(value)) {
3036
2098
  return value;
3037
2099
  }
@@ -3184,7 +2246,7 @@ var codexAdapter = {
3184
2246
  }
3185
2247
  if (itemType === "mcp_tool_call" && item.id && item.server && item.tool) {
3186
2248
  const name = `mcp__${item.server}__${item.tool}`;
3187
- const input = asRecord2(item.arguments);
2249
+ const input = asRecord(item.arguments);
3188
2250
  const events = [
3189
2251
  { type: "tool_use", id: item.id, name, input }
3190
2252
  ];
@@ -3669,17 +2731,17 @@ var FALLBACK_OPENCODE_MODELS = [
3669
2731
  ];
3670
2732
  var cachedOpencodeModels = null;
3671
2733
  var OPENCODE_MODEL_CACHE_MS = 5 * 60 * 1e3;
3672
- function asRecord3(value) {
2734
+ function asRecord2(value) {
3673
2735
  if (value && typeof value === "object" && !Array.isArray(value)) {
3674
2736
  return value;
3675
2737
  }
3676
2738
  return void 0;
3677
2739
  }
3678
- function str2(v) {
2740
+ function str(v) {
3679
2741
  return typeof v === "string" && v.trim() ? v.trim() : void 0;
3680
2742
  }
3681
2743
  function opencodeToolId(name, callId, metadata) {
3682
- const sessionId = str2(metadata?.sessionId) ?? str2(metadata?.sessionID);
2744
+ const sessionId = str(metadata?.sessionId) ?? str(metadata?.sessionID);
3683
2745
  if (name === "task" && sessionId) return sessionId;
3684
2746
  return callId || `tool-${Date.now()}`;
3685
2747
  }
@@ -3827,7 +2889,7 @@ var opencodeAdapter = {
3827
2889
  return { type: "stderr", data: detail };
3828
2890
  }
3829
2891
  const sid = typeof obj.sessionID === "string" && obj.sessionID || typeof obj.sessionId === "string" && obj.sessionId || typeof obj.session_id === "string" && obj.session_id;
3830
- const childSid = str2(obj.childSessionID) ?? str2(obj.childSessionId) ?? str2(obj.parentID) ?? str2(obj.parentId);
2892
+ const childSid = str(obj.childSessionID) ?? str(obj.childSessionId) ?? str(obj.parentID) ?? str(obj.parentId);
3831
2893
  if (sid && !childSid && (!obj.type || obj.type === "step_start" || obj.type === "session")) {
3832
2894
  return { type: "session_id", data: sid };
3833
2895
  }
@@ -3840,7 +2902,7 @@ var opencodeAdapter = {
3840
2902
  const name = part?.tool ?? part?.name ?? obj.tool ?? obj.name ?? "tool";
3841
2903
  const state = part?.state;
3842
2904
  const input = (state?.input && typeof state.input === "object" ? state.input : void 0) ?? part?.input ?? obj.input;
3843
- const metadata = asRecord3(state?.metadata);
2905
+ const metadata = asRecord2(state?.metadata);
3844
2906
  const id = opencodeToolId(
3845
2907
  name,
3846
2908
  part?.callID ?? part?.id ?? obj.id,
@@ -3863,8 +2925,8 @@ var opencodeAdapter = {
3863
2925
  return events.length === 1 ? events[0] : events;
3864
2926
  }
3865
2927
  if (obj.type === "subtask_delta") {
3866
- const parentId = str2(obj.childSessionID) ?? str2(obj.childSessionId);
3867
- const delta = str2(obj.delta);
2928
+ const parentId = str(obj.childSessionID) ?? str(obj.childSessionId);
2929
+ const delta = str(obj.delta);
3868
2930
  if (parentId && delta) {
3869
2931
  return withTaskParent(
3870
2932
  parentId,
@@ -3874,20 +2936,20 @@ var opencodeAdapter = {
3874
2936
  return null;
3875
2937
  }
3876
2938
  if (obj.type === "subtask_event") {
3877
- const parentId = str2(obj.childSessionID) ?? str2(obj.childSessionId);
3878
- const part = asRecord3(obj.part);
2939
+ const parentId = str(obj.childSessionID) ?? str(obj.childSessionId);
2940
+ const part = asRecord2(obj.part);
3879
2941
  if (!parentId || !part) return null;
3880
- if (part.type === "text" && str2(part.text)) {
2942
+ if (part.type === "text" && str(part.text)) {
3881
2943
  return withTaskParent(
3882
2944
  parentId,
3883
- withEventParentId({ type: "stdout", data: str2(part.text) }, parentId)
2945
+ withEventParentId({ type: "stdout", data: str(part.text) }, parentId)
3884
2946
  );
3885
2947
  }
3886
- if (part.type === "tool" || str2(part.tool)) {
3887
- const name = str2(part.tool) ?? str2(part.name) ?? "tool";
3888
- const id = str2(part.callID) ?? str2(part.id) ?? `${parentId}-${name}`;
3889
- const state = asRecord3(part.state);
3890
- const input = asRecord3(state?.input) ?? asRecord3(part.input);
2948
+ if (part.type === "tool" || str(part.tool)) {
2949
+ const name = str(part.tool) ?? str(part.name) ?? "tool";
2950
+ const id = str(part.callID) ?? str(part.id) ?? `${parentId}-${name}`;
2951
+ const state = asRecord2(part.state);
2952
+ const input = asRecord2(state?.input) ?? asRecord2(part.input);
3891
2953
  const nested = [
3892
2954
  withEventParentId({ type: "tool_use", id, name, input }, parentId)
3893
2955
  ];
@@ -4831,7 +3893,7 @@ async function loginAgent(agent) {
4831
3893
  };
4832
3894
  }
4833
3895
  async function loginManagedAccount(accountId) {
4834
- const { loadAppSettings: loadAppSettings2 } = await import("./app-settings-RKFFUIFQ.js");
3896
+ const { loadAppSettings: loadAppSettings2 } = await import("./app-settings-L5HGYXWJ.js");
4835
3897
  const { loginEnvPrefix } = await import("./managed-accounts-2AK5RIAF.js");
4836
3898
  const account = loadAppSettings2().accounts.accounts.find((a) => a.id === accountId);
4837
3899
  if (!account) {
@@ -4868,46 +3930,6 @@ function allAdapters() {
4868
3930
  }
4869
3931
 
4870
3932
  export {
4871
- visibleToolRowDetail,
4872
- isSkillToolName,
4873
- skillCommandFromInput,
4874
- looksLikeComposerSkillExpansion,
4875
- skillNameFromFrontmatter,
4876
- skillCommandFromBody,
4877
- looksLikeSkillBody,
4878
- looksLikeIncompleteSkillDump,
4879
- isCompactToolName,
4880
- isContextCompactDone,
4881
- isContextCompactInProgress,
4882
- isSystemStatusThinking,
4883
- looksLikeConversationSummary,
4884
- toolDetail,
4885
- toolDescription,
4886
- isSubagentToolName,
4887
- isInternalAgentStatusText,
4888
- isPollWrapperToolName,
4889
- isShellToolName,
4890
- toolActivityLine,
4891
- liveActivitySummary,
4892
- messagePartParentId,
4893
- withEventParentId,
4894
- withEventsParentId,
4895
- toolFilePath,
4896
- THINKING_PART_MAX_CHARS,
4897
- clipThinkingForStore,
4898
- STDOUT_EVENT_MAX_CHARS,
4899
- STDERR_EVENT_MAX_CHARS,
4900
- clipAgentEventForPaint,
4901
- compactSummaryPart,
4902
- compactPartsForSummaryMessage,
4903
- applyAgentEvent,
4904
- partsToAssistantText,
4905
- visibleAssistantText,
4906
- lastAssistantMessageText,
4907
- stripBrightsyNdjsonNoise,
4908
- isBrightsyNdjsonLine,
4909
- finalizeParts,
4910
- normalizeParseResult,
4911
3933
  encodeBrightsyTarget,
4912
3934
  decodeBrightsyTarget,
4913
3935
  normalizeTurnInput,