@sideboard-ai/core 0.1.244 → 0.1.245

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.
package/dist/index.js CHANGED
@@ -336,7 +336,7 @@ import {
336
336
  worktreeRunPortsPath,
337
337
  wrapReviewSkillMarkdown,
338
338
  writeWorktreeFile
339
- } from "./chunk-YJJ2A5CI.js";
339
+ } from "./chunk-NT6MCFSB.js";
340
340
  import {
341
341
  LEGACY_PLAN_FILE_REL,
342
342
  PLAN_FILE_NAME,
@@ -428,6 +428,7 @@ import {
428
428
  loginAgent,
429
429
  looksLikeComposerSkillExpansion,
430
430
  looksLikeConversationSummary,
431
+ looksLikeIncompleteSkillDump,
431
432
  looksLikeSkillBody,
432
433
  mcpAllowTools,
433
434
  mcpAllowToolsFromNames,
@@ -467,12 +468,13 @@ import {
467
468
  userClaudeMcpConfigPath,
468
469
  userCursorMcpConfigPath,
469
470
  userMcpNamesToDisable,
471
+ visibleAssistantText,
470
472
  visibleToolRowDetail,
471
473
  whichOnPath,
472
474
  withEventParentId,
473
475
  withEventsParentId,
474
476
  writeInjectedMcpConfig
475
- } from "./chunk-CYYQ6577.js";
477
+ } from "./chunk-QRWVKBGP.js";
476
478
  import {
477
479
  CLOUD_COORDINATOR_BUSY_REPLY,
478
480
  CLOUD_COORDINATOR_CANCELED_REPLY,
@@ -3960,7 +3962,7 @@ async function continueSourceThread(threadId, prompt) {
3960
3962
  await continueOnReply(threadId, prompt);
3961
3963
  return;
3962
3964
  }
3963
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-ABF6QFE6.js");
3965
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-7YCQ7V5S.js");
3964
3966
  await getOrchestrator2().send(threadId, prompt);
3965
3967
  } catch {
3966
3968
  }
@@ -10182,6 +10184,7 @@ export {
10182
10184
  loginAgent,
10183
10185
  looksLikeComposerSkillExpansion,
10184
10186
  looksLikeConversationSummary,
10187
+ looksLikeIncompleteSkillDump,
10185
10188
  looksLikeSkillBody,
10186
10189
  lookupSoccerTeam,
10187
10190
  mapAbleTimeTask,
@@ -10490,6 +10493,7 @@ export {
10490
10493
  validateLinearApiKey,
10491
10494
  verifyAbleTimeConnection,
10492
10495
  verifyOptionalService,
10496
+ visibleAssistantText,
10493
10497
  visibleToolRowDetail,
10494
10498
  waitForPidExit,
10495
10499
  warmGithubAgentAuth,
@@ -10230,23 +10230,37 @@ function looksLikeComposerSkillExpansion(text7) {
10230
10230
  const t = text7.trim();
10231
10231
  return /^## Skill: \//m.test(t) && /Follow this skill for the request above:/i.test(t);
10232
10232
  }
10233
+ function skillNameFromFrontmatter(text7) {
10234
+ const t = text7.trim();
10235
+ if (!t) return void 0;
10236
+ let yaml = t;
10237
+ if (!yaml.startsWith("---")) {
10238
+ const at = t.search(/(?:^|\n)---(?:\r?\n)/);
10239
+ if (at < 0 || at > 800) return void 0;
10240
+ yaml = t.slice(at).replace(/^\n/, "");
10241
+ }
10242
+ if (!yaml.startsWith("---")) return void 0;
10243
+ const close = yaml.indexOf("\n---", 3);
10244
+ if (close < 0) return void 0;
10245
+ return yaml.slice(3, close).match(SKILL_FRONTMATTER_NAME)?.[1];
10246
+ }
10247
+ function skillCommandFromBody(text7) {
10248
+ return skillNameFromFrontmatter(text7) ?? text7.match(/^## Skill: \/([A-Za-z0-9][A-Za-z0-9._-]*)/m)?.[1] ?? text7.match(/^Launching skill:\s*\/?([A-Za-z0-9][A-Za-z0-9._-]*)/im)?.[1];
10249
+ }
10233
10250
  function looksLikeSkillBody(text7) {
10234
10251
  const t = text7.trim();
10235
10252
  if (!t) return false;
10236
10253
  if (looksLikeComposerSkillExpansion(t)) return true;
10237
- return skillNameFromFrontmatter(t) != null;
10254
+ if (skillNameFromFrontmatter(t) != null) return true;
10255
+ return /^Launching skill:/im.test(t) && /Base directory for this skill:/i.test(t);
10238
10256
  }
10239
- function skillNameFromFrontmatter(text7) {
10257
+ function looksLikeIncompleteSkillDump(text7) {
10240
10258
  const t = text7.trim();
10241
- if (!t.startsWith("---")) return void 0;
10242
- const close = t.indexOf("\n---", 3);
10243
- if (close < 0) return void 0;
10244
- const fm = t.slice(3, close);
10245
- const m = fm.match(/^\s*name\s*:\s*['"]?([A-Za-z0-9][A-Za-z0-9._-]*)['"]?\s*$/m);
10246
- return m?.[1];
10247
- }
10248
- function skillCommandFromBody(text7) {
10249
- return skillNameFromFrontmatter(text7) ?? text7.match(/^## Skill: \/([A-Za-z0-9][A-Za-z0-9._-]*)/m)?.[1];
10259
+ if (!t || looksLikeSkillBody(t)) return false;
10260
+ if (/^## Skill: \//m.test(t)) return true;
10261
+ if (/^Launching skill:/im.test(t)) return true;
10262
+ if (/Base directory for this skill:/i.test(t)) return true;
10263
+ return t.startsWith("---") && SKILL_FRONTMATTER_NAME.test(t);
10250
10264
  }
10251
10265
  function isCompactToolName(name) {
10252
10266
  const short = (name ?? "").replace(/^mcp__[^_]+__/, "").trim();
@@ -10562,22 +10576,70 @@ function withPartTimes(next, prev) {
10562
10576
  const startedAt = prev && typeof prev.startedAt === "number" ? prev.startedAt : now;
10563
10577
  return { ...next, startedAt, updatedAt: now };
10564
10578
  }
10565
- function skillToolFromTextPart(part, id) {
10579
+ function skillToolFromTextPart(part, id, status = "done") {
10566
10580
  const command = skillCommandFromBody(part.text);
10567
10581
  const input = command ? { skill: command } : void 0;
10568
10582
  return {
10569
10583
  type: "tool",
10570
- id,
10584
+ id: command ? `skill-${command}` : id,
10571
10585
  name: "Skill",
10572
10586
  input,
10573
10587
  description: toolDescription("Skill", input),
10574
- status: "done",
10588
+ status,
10575
10589
  result: clipToolResultForStore(part.text),
10576
10590
  ...part.parentId ? { parentId: part.parentId } : {},
10577
10591
  startedAt: part.startedAt,
10578
10592
  updatedAt: Date.now()
10579
10593
  };
10580
10594
  }
10595
+ function lastSkillToolIndex(parts, parentId) {
10596
+ for (let i = parts.length - 1; i >= 0; i--) {
10597
+ const p = parts[i];
10598
+ if (p.type === "tool" && isSkillToolName(p.name) && sameParentId(p.parentId, parentId)) {
10599
+ return i;
10600
+ }
10601
+ }
10602
+ return -1;
10603
+ }
10604
+ function lastRunningSkillIndex(parts, parentId) {
10605
+ for (let i = parts.length - 1; i >= 0; i--) {
10606
+ const p = parts[i];
10607
+ if (p.type === "tool" && isSkillToolName(p.name) && p.status === "running" && sameParentId(p.parentId, parentId)) {
10608
+ return i;
10609
+ }
10610
+ }
10611
+ return -1;
10612
+ }
10613
+ function promoteOrFoldSkillText(parts, textIdx) {
10614
+ const acc = parts[textIdx];
10615
+ if (acc?.type !== "text") return parts;
10616
+ const complete = looksLikeSkillBody(acc.text);
10617
+ const incomplete = looksLikeIncompleteSkillDump(acc.text);
10618
+ if (!complete && !incomplete) return parts;
10619
+ const existing = lastSkillToolIndex(parts, acc.parentId);
10620
+ if (existing >= 0 && existing !== textIdx) {
10621
+ const prev = parts[existing];
10622
+ const next2 = parts.filter((_, i) => i !== textIdx);
10623
+ const existingIdx = lastSkillToolIndex(next2, acc.parentId);
10624
+ if (existingIdx < 0) return parts;
10625
+ next2[existingIdx] = withPartTimes(
10626
+ {
10627
+ ...prev,
10628
+ status: complete ? "done" : prev.status,
10629
+ result: clipToolResultForStore(acc.text) ?? prev.result
10630
+ },
10631
+ prev
10632
+ );
10633
+ return next2;
10634
+ }
10635
+ const next = [...parts];
10636
+ next[textIdx] = skillToolFromTextPart(
10637
+ acc,
10638
+ `skill-${next.length}`,
10639
+ complete ? "done" : "running"
10640
+ );
10641
+ return next;
10642
+ }
10581
10643
  function compactSummaryPart(text7, id = "compact-summary") {
10582
10644
  return compactToolPart(text7, id, { status: "done" });
10583
10645
  }
@@ -10666,6 +10728,21 @@ function applyAgentEvent(parts, event) {
10666
10728
  })
10667
10729
  ];
10668
10730
  }
10731
+ const runningSkillIdx = lastRunningSkillIndex(parts, event.parentId);
10732
+ if (runningSkillIdx >= 0) {
10733
+ const prev = parts[runningSkillIdx];
10734
+ const result = `${prev.result ?? ""}${data}`;
10735
+ const next2 = [...parts];
10736
+ next2[runningSkillIdx] = withPartTimes(
10737
+ {
10738
+ ...prev,
10739
+ result: clipToolResultForStore(result),
10740
+ status: looksLikeSkillBody(result) ? "done" : prev.status
10741
+ },
10742
+ prev
10743
+ );
10744
+ return next2;
10745
+ }
10669
10746
  const next = [...parts];
10670
10747
  const last = next[next.length - 1];
10671
10748
  if (last?.type === "text" && sameParentId(last.parentId, event.parentId)) {
@@ -10687,9 +10764,10 @@ function applyAgentEvent(parts, event) {
10687
10764
  );
10688
10765
  }
10689
10766
  const acc = next[next.length - 1];
10690
- if (acc?.type === "text" && looksLikeComposerSkillExpansion(acc.text)) {
10691
- next[next.length - 1] = skillToolFromTextPart(acc, `skill-${next.length}`);
10692
- } else if (acc?.type === "text" && looksLikeConversationSummary(acc.text)) {
10767
+ if (acc?.type === "text" && (looksLikeSkillBody(acc.text) || looksLikeIncompleteSkillDump(acc.text))) {
10768
+ return promoteOrFoldSkillText(next, next.length - 1);
10769
+ }
10770
+ if (acc?.type === "text" && looksLikeConversationSummary(acc.text)) {
10693
10771
  next[next.length - 1] = compactToolPart(acc.text, `compact-${next.length}`, {
10694
10772
  parentId: acc.parentId,
10695
10773
  status: "done",
@@ -10893,12 +10971,13 @@ function normalizeParseResult(parsed) {
10893
10971
  if (!parsed) return [];
10894
10972
  return Array.isArray(parsed) ? parsed : [parsed];
10895
10973
  }
10896
- var CHAT_DETAIL_MAX, THINKING_PART_MAX_CHARS, STDOUT_EVENT_MAX_CHARS, STDERR_EVENT_MAX_CHARS;
10974
+ var CHAT_DETAIL_MAX, SKILL_FRONTMATTER_NAME, THINKING_PART_MAX_CHARS, STDOUT_EVENT_MAX_CHARS, STDERR_EVENT_MAX_CHARS;
10897
10975
  var init_message_parts = __esm({
10898
10976
  "src/agents/message-parts.ts"() {
10899
10977
  "use strict";
10900
10978
  init_error_detail();
10901
10979
  CHAT_DETAIL_MAX = 72;
10980
+ SKILL_FRONTMATTER_NAME = /^\s*name\s*:\s*['"]?([A-Za-z0-9][A-Za-z0-9._-]*)['"]?\s*$/m;
10902
10981
  THINKING_PART_MAX_CHARS = 64e3;
10903
10982
  STDOUT_EVENT_MAX_CHARS = 16e3;
10904
10983
  STDERR_EVENT_MAX_CHARS = 4e3;
@@ -11056,13 +11135,17 @@ function eventsFromInjectedUserText(text7, parentId) {
11056
11135
  if (looksLikeConversationSummary(text7)) return compactToolEventsFromBody(text7, parentId);
11057
11136
  return [];
11058
11137
  }
11138
+ function eventsFromAssistantText(text7, parentId) {
11139
+ if (looksLikeSkillBody(text7)) return skillToolEventsFromBody(text7, parentId);
11140
+ return [withEventParentId({ type: "stdout", data: text7 }, parentId)];
11141
+ }
11059
11142
  function eventsFromUserContent(content, parentId) {
11060
11143
  if (typeof content === "string" && content.trim()) {
11061
11144
  return eventsFromInjectedUserText(content, parentId);
11062
11145
  }
11063
11146
  if (!Array.isArray(content) || content.length === 0) return [];
11064
11147
  const out = [];
11065
- const textBlocks = [];
11148
+ const injected2 = [];
11066
11149
  for (const block of content) {
11067
11150
  if (!block?.type) continue;
11068
11151
  if (block.type === "tool_use" && block.id && block.name) {
@@ -11093,13 +11176,12 @@ function eventsFromUserContent(content, parentId) {
11093
11176
  );
11094
11177
  continue;
11095
11178
  }
11096
- if (block.type === "text" && block.text) textBlocks.push(block.text);
11097
- }
11098
- if (out.length > 0) return out;
11099
- for (const text7 of textBlocks) {
11100
- out.push(...eventsFromInjectedUserText(text7, parentId));
11179
+ if (block.type === "text" && block.text) {
11180
+ injected2.push(...eventsFromInjectedUserText(block.text, parentId));
11181
+ }
11101
11182
  }
11102
- return out;
11183
+ if (out.length === 0 && injected2.length === 0) return [];
11184
+ return [...out, ...injected2];
11103
11185
  }
11104
11186
  function eventsFromContentBlocks(blocks, parentId) {
11105
11187
  if (!blocks?.length) return [];
@@ -11107,7 +11189,7 @@ function eventsFromContentBlocks(blocks, parentId) {
11107
11189
  for (const block of blocks) {
11108
11190
  if (!block?.type) continue;
11109
11191
  if (block.type === "text" && block.text) {
11110
- out.push(withEventParentId({ type: "stdout", data: block.text }, parentId));
11192
+ out.push(...eventsFromAssistantText(block.text, parentId));
11111
11193
  continue;
11112
11194
  }
11113
11195
  if ((block.type === "thinking" || block.type === "redacted_thinking") && block.thinking) {
@@ -11600,7 +11682,9 @@ var init_claude = __esm({
11600
11682
  events.push({ type: "stderr", data: errorDetail });
11601
11683
  } else {
11602
11684
  const text7 = obj.result;
11603
- if (typeof text7 === "string" && text7) events.push({ type: "stdout", data: text7 });
11685
+ if (typeof text7 === "string" && text7) {
11686
+ events.push(...eventsFromAssistantText(text7));
11687
+ }
11604
11688
  }
11605
11689
  const usage = usageFromClaude(obj.usage);
11606
11690
  if (usage) {
@@ -13429,9 +13513,11 @@ async function spawnAgentTurn(thread, input, onEvent) {
13429
13513
  if (assistantText && (parsed.data === assistantText || assistantText.endsWith(parsed.data))) {
13430
13514
  continue;
13431
13515
  }
13432
- assistantText += parsed.data;
13433
13516
  }
13434
13517
  parts = applyAgentEvent(parts, parsed);
13518
+ if (parsed.type === "stdout") {
13519
+ assistantText = partsToAssistantText(parts);
13520
+ }
13435
13521
  outbound.push(parsed);
13436
13522
  }
13437
13523
  });
@@ -49,7 +49,7 @@ import {
49
49
  threadsSharingWorktree,
50
50
  updateSchedule,
51
51
  waitForDetachedJob
52
- } from "../chunk-4HMV53AB.js";
52
+ } from "../chunk-J5IZXFLD.js";
53
53
  import {
54
54
  PRESENT_PLAN_REQUIRES_PLAN_MODE,
55
55
  PRESENT_PLAN_TOOL_DESCRIPTION,
@@ -66,7 +66,7 @@ import {
66
66
  materializeSystemCaBundle,
67
67
  sideboardMcpProfile,
68
68
  trustSystemCertificates
69
- } from "../chunk-2QRU4IFI.js";
69
+ } from "../chunk-3ZEBUVUI.js";
70
70
  import {
71
71
  GLOBAL_WORKSPACE_ID,
72
72
  isCloudCoordinatorThread,
@@ -2366,7 +2366,7 @@ async function continueSourceThread(threadId, prompt) {
2366
2366
  await continueOnReply(threadId, prompt);
2367
2367
  return;
2368
2368
  }
2369
- const { getOrchestrator: getOrchestrator2 } = await import("../orchestrator-ZJ6SYGW7.js");
2369
+ const { getOrchestrator: getOrchestrator2 } = await import("../orchestrator-5ROSTGGH.js");
2370
2370
  await getOrchestrator2().send(threadId, prompt);
2371
2371
  } catch {
2372
2372
  }
@@ -11,10 +11,10 @@ import {
11
11
  resolveSendFollowUp,
12
12
  startOrchestration,
13
13
  waitForPidExit
14
- } from "./chunk-4HMV53AB.js";
14
+ } from "./chunk-J5IZXFLD.js";
15
15
  import "./chunk-WDDUIGFK.js";
16
16
  import "./chunk-DQN5U2VH.js";
17
- import "./chunk-2QRU4IFI.js";
17
+ import "./chunk-3ZEBUVUI.js";
18
18
  import "./chunk-576S3HJ7.js";
19
19
  import "./chunk-J5GON4SU.js";
20
20
  import "./chunk-P2BSMNHB.js";
@@ -9,9 +9,9 @@ import {
9
9
  resolveSendFollowUp,
10
10
  startOrchestration,
11
11
  waitForPidExit
12
- } from "./chunk-YJJ2A5CI.js";
12
+ } from "./chunk-NT6MCFSB.js";
13
13
  import "./chunk-PGPSIEMW.js";
14
- import "./chunk-CYYQ6577.js";
14
+ import "./chunk-QRWVKBGP.js";
15
15
  import "./chunk-GFRC6JQN.js";
16
16
  import "./chunk-E6C5NR46.js";
17
17
  import "./chunk-6K64FJDD.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sideboard-ai/core",
3
- "version": "0.1.244",
3
+ "version": "0.1.245",
4
4
  "description": "Sideboard core — orchestration, agents, git worktrees, MCP server",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",