@ganglion/xacpx 0.24.2-beta.0 → 0.24.3-beta.0

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.
@@ -3567,12 +3567,218 @@ var init_tool_kind_emoji = __esm(() => {
3567
3567
  search: "\uD83D\uDD0D",
3568
3568
  execute: "\uD83D\uDCBB",
3569
3569
  edit: "✏️",
3570
+ delete: "\uD83D\uDDD1️",
3571
+ move: "\uD83D\uDCE6",
3572
+ fetch: "\uD83C\uDF10",
3570
3573
  think: "\uD83E\uDDE0",
3571
3574
  other: "\uD83D\uDD27"
3572
3575
  };
3573
3576
  DEFAULT_TOOL_EMOJI = TOOL_KIND_EMOJI.other;
3574
3577
  });
3575
3578
 
3579
+ // src/transport/tool-summary.ts
3580
+ function isRecord2(value) {
3581
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3582
+ }
3583
+ function isEmptyToolField(v) {
3584
+ if (v === undefined || v === null)
3585
+ return true;
3586
+ if (typeof v === "string")
3587
+ return v.trim().length === 0;
3588
+ if (Array.isArray(v))
3589
+ return v.length === 0;
3590
+ if (typeof v === "object")
3591
+ return Object.keys(v).length === 0;
3592
+ return false;
3593
+ }
3594
+ function cursorToolInput(rawInput) {
3595
+ if (!isRecord2(rawInput))
3596
+ return;
3597
+ if (isRecord2(rawInput.args))
3598
+ return rawInput.args;
3599
+ return rawInput;
3600
+ }
3601
+ function readFirstString(record, keys) {
3602
+ for (const key of keys) {
3603
+ const value = record[key];
3604
+ if (typeof value === "string" && value.trim().length > 0) {
3605
+ return value.trim();
3606
+ }
3607
+ }
3608
+ return;
3609
+ }
3610
+ function readFirstStringArray(record, keys) {
3611
+ for (const key of keys) {
3612
+ const value = record[key];
3613
+ if (!Array.isArray(value))
3614
+ continue;
3615
+ const entries = value.map((entry) => typeof entry === "string" && entry.trim().length > 0 ? entry.trim() : undefined).filter((entry) => entry !== undefined);
3616
+ if (entries.length > 0) {
3617
+ return entries;
3618
+ }
3619
+ }
3620
+ return;
3621
+ }
3622
+ function summarizeTaskInput(rawInput, title) {
3623
+ const subagentType = readFirstString(rawInput, ["subagent_type", "subagentType", "agent", "agentType"]);
3624
+ const description = readFirstString(rawInput, ["description", "task", "summary"]);
3625
+ if (subagentType && description) {
3626
+ return description === title ? subagentType : `${subagentType}: ${description}`;
3627
+ }
3628
+ if (subagentType)
3629
+ return subagentType;
3630
+ return;
3631
+ }
3632
+ function summarizeToolInput(rawInput, title = "") {
3633
+ if (rawInput == null)
3634
+ return;
3635
+ if (typeof rawInput === "string" || typeof rawInput === "number" || typeof rawInput === "boolean") {
3636
+ return String(rawInput);
3637
+ }
3638
+ if (!isRecord2(rawInput))
3639
+ return;
3640
+ const nestedInput = cursorToolInput(rawInput);
3641
+ if (nestedInput !== rawInput) {
3642
+ const nestedSummary = summarizeToolInput(nestedInput, title);
3643
+ if (nestedSummary)
3644
+ return nestedSummary;
3645
+ }
3646
+ const taskSummary = summarizeTaskInput(rawInput, title);
3647
+ if (taskSummary)
3648
+ return taskSummary;
3649
+ const command = readFirstString(rawInput, ["command", "cmd", "program"]);
3650
+ const args = readFirstStringArray(rawInput, ["args", "arguments"]);
3651
+ if (command) {
3652
+ return [command, ...args ?? []].join(" ");
3653
+ }
3654
+ const parsedCmd = rawInput.parsed_cmd;
3655
+ if (Array.isArray(parsedCmd) && parsedCmd.length > 0) {
3656
+ const parts = [];
3657
+ for (const entry of parsedCmd) {
3658
+ if (isRecord2(entry) && typeof entry.cmd === "string" && entry.cmd.length > 0) {
3659
+ parts.push(entry.cmd);
3660
+ }
3661
+ }
3662
+ if (parts.length > 0) {
3663
+ return parts.join(" ");
3664
+ }
3665
+ }
3666
+ const globPattern = readFirstString(rawInput, ["glob_pattern"]);
3667
+ if (globPattern) {
3668
+ const targetDirectory = readFirstString(rawInput, ["target_directory"]);
3669
+ return targetDirectory ? `${globPattern} in ${targetDirectory}` : globPattern;
3670
+ }
3671
+ const mode = readFirstString(rawInput, ["target_mode_id", "mode_id"]);
3672
+ const explanation = readFirstString(rawInput, ["explanation"]);
3673
+ if (mode || explanation) {
3674
+ return mode && explanation ? `${mode}: ${explanation}` : mode ?? explanation;
3675
+ }
3676
+ return readFirstString(rawInput, [
3677
+ "path",
3678
+ "file",
3679
+ "filePath",
3680
+ "filepath",
3681
+ "file_path",
3682
+ "target",
3683
+ "uri",
3684
+ "url",
3685
+ "query",
3686
+ "pattern",
3687
+ "text",
3688
+ "search",
3689
+ "working_directory",
3690
+ "name",
3691
+ "description"
3692
+ ]);
3693
+ }
3694
+ function summarizeToolOutput(rawOutput) {
3695
+ if (rawOutput == null)
3696
+ return;
3697
+ if (typeof rawOutput === "string" || typeof rawOutput === "number" || typeof rawOutput === "boolean") {
3698
+ const text = String(rawOutput).trim();
3699
+ if (!text)
3700
+ return;
3701
+ return text.length > TOOL_OUTPUT_SUMMARY_MAX_CHARS ? text.slice(0, TOOL_OUTPUT_SUMMARY_MAX_CHARS) : text;
3702
+ }
3703
+ if (!isRecord2(rawOutput))
3704
+ return;
3705
+ const direct = readFirstString(rawOutput, ["text", "message", "error", "stdout", "stderr", "content"]);
3706
+ if (direct) {
3707
+ return direct.length > TOOL_OUTPUT_SUMMARY_MAX_CHARS ? direct.slice(0, TOOL_OUTPUT_SUMMARY_MAX_CHARS) : direct;
3708
+ }
3709
+ if (Array.isArray(rawOutput.content)) {
3710
+ const parts = [];
3711
+ for (const item of rawOutput.content) {
3712
+ if (typeof item === "string" && item.trim().length > 0) {
3713
+ parts.push(item.trim());
3714
+ } else if (isRecord2(item)) {
3715
+ const itemText = readFirstString(item, ["text", "content"]);
3716
+ if (itemText)
3717
+ parts.push(itemText);
3718
+ }
3719
+ }
3720
+ if (parts.length > 0) {
3721
+ const text = parts.join(`
3722
+ `);
3723
+ return text.length > TOOL_OUTPUT_SUMMARY_MAX_CHARS ? text.slice(0, TOOL_OUTPUT_SUMMARY_MAX_CHARS) : text;
3724
+ }
3725
+ }
3726
+ return;
3727
+ }
3728
+ var TOOL_OUTPUT_SUMMARY_MAX_CHARS = 500;
3729
+
3730
+ // src/transport/transcript-text-boundary.ts
3731
+ function createTranscriptTextBoundaryState() {
3732
+ return {
3733
+ hasAgentMessage: false,
3734
+ lastMessageId: undefined,
3735
+ lastTextTail: "",
3736
+ activitySinceLastText: false
3737
+ };
3738
+ }
3739
+ function markTranscriptActivity(state) {
3740
+ state.activitySinceLastText = state.hasAgentMessage;
3741
+ }
3742
+ function endsWithSentenceTerminal(text) {
3743
+ return SENTENCE_TERMINAL_AT_END.test(text.trimEnd());
3744
+ }
3745
+ function hasParagraphBoundaryAtJoin(left, right) {
3746
+ const leftHasBoundary = PARAGRAPH_BOUNDARY_AT_END.test(left);
3747
+ const rightHasBoundary = PARAGRAPH_BOUNDARY_AT_START.test(right);
3748
+ const boundarySpansJoin = LINE_BREAK_AT_END.test(left) && LINE_BREAK_AT_START.test(right);
3749
+ const crlfBoundarySpansJoin = PARTIAL_CRLF_PARAGRAPH_BOUNDARY_AT_END.test(left) && right.startsWith(`
3750
+ `);
3751
+ return leftHasBoundary || rightHasBoundary || boundarySpansJoin || crlfBoundarySpansJoin;
3752
+ }
3753
+ function normalizeTranscriptTextChunk(state, input) {
3754
+ state.hasAgentMessage = true;
3755
+ let chunk = input.text;
3756
+ if (chunk.length === 0)
3757
+ return chunk;
3758
+ const messageId = typeof input.messageId === "string" && input.messageId.length > 0 ? input.messageId : undefined;
3759
+ const messageIdChanged = state.lastMessageId !== undefined && messageId !== undefined && state.lastMessageId !== messageId;
3760
+ const fallbackBoundary = state.activitySinceLastText && (state.lastMessageId === undefined || messageId === undefined) && endsWithSentenceTerminal(state.lastTextTail);
3761
+ if ((messageIdChanged || fallbackBoundary) && !hasParagraphBoundaryAtJoin(state.lastTextTail, chunk)) {
3762
+ chunk = `
3763
+
3764
+ ${chunk}`;
3765
+ state.lastTextTail = "";
3766
+ }
3767
+ state.lastMessageId = messageId;
3768
+ state.activitySinceLastText = false;
3769
+ state.lastTextTail = `${state.lastTextTail}${chunk}`.slice(-256);
3770
+ return chunk;
3771
+ }
3772
+ var SENTENCE_TERMINAL_AT_END, PARAGRAPH_BOUNDARY_AT_END, PARAGRAPH_BOUNDARY_AT_START, LINE_BREAK_AT_END, LINE_BREAK_AT_START, PARTIAL_CRLF_PARAGRAPH_BOUNDARY_AT_END;
3773
+ var init_transcript_text_boundary = __esm(() => {
3774
+ SENTENCE_TERMINAL_AT_END = /(?:\p{Sentence_Terminal}|…|⋯)[\p{Close_Punctuation}\p{Final_Punctuation}"“”‘’*_~`]*$/u;
3775
+ PARAGRAPH_BOUNDARY_AT_END = /\r?\n[\t ]*\r?\n[\t ]*$/;
3776
+ PARAGRAPH_BOUNDARY_AT_START = /^[\t ]*\r?\n[\t ]*\r?\n/;
3777
+ LINE_BREAK_AT_END = /\r?\n[\t ]*$/;
3778
+ LINE_BREAK_AT_START = /^[\t ]*\r?\n/;
3779
+ PARTIAL_CRLF_PARAGRAPH_BOUNDARY_AT_END = /\r?\n[\t ]*\r$/;
3780
+ });
3781
+
3576
3782
  // src/transport/streaming-prompt.ts
3577
3783
  function createStreamingPromptState(formatToolCalls = false, options) {
3578
3784
  let toolEventMode;
@@ -3605,9 +3811,9 @@ function createStreamingPromptState(formatToolCalls = false, options) {
3605
3811
  });
3606
3812
  }
3607
3813
  return {
3814
+ ...createTranscriptTextBoundaryState(),
3608
3815
  buffer: "",
3609
3816
  segments: [],
3610
- hasAgentMessage: false,
3611
3817
  pendingLine: "",
3612
3818
  formatToolCalls,
3613
3819
  emittedToolCallIds: new Set,
@@ -3617,8 +3823,6 @@ function createStreamingPromptState(formatToolCalls = false, options) {
3617
3823
  toolEventMode,
3618
3824
  driver,
3619
3825
  rawStream,
3620
- lastTextTail: "",
3621
- activitySinceLastText: false,
3622
3826
  onBeforeActivityEvent,
3623
3827
  onToolEvent,
3624
3828
  onThought,
@@ -3730,23 +3934,14 @@ function parseStreamingChunks(state, line) {
3730
3934
  const isMessageChunk = update.sessionUpdate === "agent_message_chunk" && update.content?.type === "text" && typeof update.content.text === "string";
3731
3935
  if (!isMessageChunk)
3732
3936
  return;
3733
- state.hasAgentMessage = true;
3734
- let chunk = update.content.text ?? "";
3735
- if (chunk.length === 0)
3937
+ const rawChunk = update.content.text ?? "";
3938
+ if (rawChunk.length === 0)
3736
3939
  return;
3737
- const messageId = typeof update.messageId === "string" && update.messageId.length > 0 ? update.messageId : undefined;
3738
- const messageIdChanged = state.lastMessageId !== undefined && messageId !== undefined && state.lastMessageId !== messageId;
3739
- const fallbackBoundary = state.activitySinceLastText && (state.lastMessageId === undefined || messageId === undefined) && endsWithSentenceTerminal(state.lastTextTail);
3740
- if ((messageIdChanged || fallbackBoundary) && !hasParagraphBoundaryAtJoin(state.lastTextTail, chunk)) {
3741
- chunk = `
3742
-
3743
- ${chunk}`;
3744
- state.lastTextTail = "";
3745
- }
3940
+ const chunk = normalizeTranscriptTextChunk(state, {
3941
+ text: rawChunk,
3942
+ messageId: update.messageId
3943
+ });
3746
3944
  state.buffer += chunk;
3747
- state.lastMessageId = messageId;
3748
- state.activitySinceLastText = false;
3749
- state.lastTextTail = `${state.lastTextTail}${chunk}`.slice(-256);
3750
3945
  if (state.rawStream)
3751
3946
  return;
3752
3947
  let boundary;
@@ -3760,20 +3955,9 @@ ${chunk}`;
3760
3955
  }
3761
3956
  }
3762
3957
  }
3763
- function endsWithSentenceTerminal(text) {
3764
- return SENTENCE_TERMINAL_AT_END.test(text.trimEnd());
3765
- }
3766
- function hasParagraphBoundaryAtJoin(left, right) {
3767
- const leftHasBoundary = PARAGRAPH_BOUNDARY_AT_END.test(left);
3768
- const rightHasBoundary = PARAGRAPH_BOUNDARY_AT_START.test(right);
3769
- const boundarySpansJoin = LINE_BREAK_AT_END.test(left) && LINE_BREAK_AT_START.test(right);
3770
- const crlfBoundarySpansJoin = PARTIAL_CRLF_PARAGRAPH_BOUNDARY_AT_END.test(left) && right.startsWith(`
3771
- `);
3772
- return leftHasBoundary || rightHasBoundary || boundarySpansJoin || crlfBoundarySpansJoin;
3773
- }
3774
3958
  function markActivityBoundary(state) {
3775
3959
  flushBeforeActivityEvent(state);
3776
- state.activitySinceLastText = state.hasAgentMessage;
3960
+ markTranscriptActivity(state);
3777
3961
  }
3778
3962
  function flushBeforeActivityEvent(state) {
3779
3963
  state.onBeforeActivityEvent?.();
@@ -3796,17 +3980,6 @@ function formatToolCallEvent(update, sessionUpdate) {
3796
3980
  const statusText = status ? ` (${status})` : "";
3797
3981
  return `${emoji} ${title}${statusText}${summaryText}`;
3798
3982
  }
3799
- function isEmptyToolField(v) {
3800
- if (v === undefined || v === null)
3801
- return true;
3802
- if (typeof v === "string")
3803
- return v.trim().length === 0;
3804
- if (Array.isArray(v))
3805
- return v.length === 0;
3806
- if (typeof v === "object")
3807
- return Object.keys(v).length === 0;
3808
- return false;
3809
- }
3810
3983
  function mergeToolCallUpdate(state, toolCallId, update) {
3811
3984
  const prev = state.toolCalls.get(toolCallId) ?? { toolCallId };
3812
3985
  const merged = { ...prev };
@@ -4004,13 +4177,6 @@ function normalizePlanPriority(value) {
4004
4177
  return;
4005
4178
  return value;
4006
4179
  }
4007
- function cursorToolInput(rawInput) {
4008
- if (!isRecord2(rawInput))
4009
- return;
4010
- if (isRecord2(rawInput.args))
4011
- return rawInput.args;
4012
- return rawInput;
4013
- }
4014
4180
  function normalizeCursorToolName(title) {
4015
4181
  return (title ?? "").trim().toLowerCase().replace(/[\s_-]+/g, "");
4016
4182
  }
@@ -4026,6 +4192,9 @@ function normalizeToolKind(update, driver) {
4026
4192
  case "search":
4027
4193
  case "execute":
4028
4194
  case "edit":
4195
+ case "delete":
4196
+ case "move":
4197
+ case "fetch":
4029
4198
  case "think":
4030
4199
  return kindRaw;
4031
4200
  }
@@ -4078,99 +4247,6 @@ function isKimiSubagentInput(rawInput) {
4078
4247
  function isCodexSubagentMeta(meta) {
4079
4248
  return typeof meta?.threadId === "string" && meta.threadId.trim().length > 0 && typeof meta.activity === "string" && meta.activity.trim().length > 0;
4080
4249
  }
4081
- function summarizeToolInput(rawInput, title = "") {
4082
- if (rawInput == null)
4083
- return;
4084
- if (typeof rawInput === "string" || typeof rawInput === "number" || typeof rawInput === "boolean") {
4085
- return String(rawInput);
4086
- }
4087
- if (!isRecord2(rawInput))
4088
- return;
4089
- const nestedInput = cursorToolInput(rawInput);
4090
- if (nestedInput !== rawInput) {
4091
- const nestedSummary = summarizeToolInput(nestedInput, title);
4092
- if (nestedSummary)
4093
- return nestedSummary;
4094
- }
4095
- const taskSummary = summarizeTaskInput(rawInput, title);
4096
- if (taskSummary)
4097
- return taskSummary;
4098
- const command = readFirstString(rawInput, ["command", "cmd", "program"]);
4099
- const args = readFirstStringArray(rawInput, ["args", "arguments"]);
4100
- if (command) {
4101
- return [command, ...args ?? []].join(" ");
4102
- }
4103
- const parsedCmd = rawInput.parsed_cmd;
4104
- if (Array.isArray(parsedCmd) && parsedCmd.length > 0) {
4105
- const parts = [];
4106
- for (const entry of parsedCmd) {
4107
- if (isRecord2(entry) && typeof entry.cmd === "string" && entry.cmd.length > 0) {
4108
- parts.push(entry.cmd);
4109
- }
4110
- }
4111
- if (parts.length > 0) {
4112
- return parts.join(" ");
4113
- }
4114
- }
4115
- const globPattern = readFirstString(rawInput, ["glob_pattern"]);
4116
- if (globPattern) {
4117
- const targetDirectory = readFirstString(rawInput, ["target_directory"]);
4118
- return targetDirectory ? `${globPattern} in ${targetDirectory}` : globPattern;
4119
- }
4120
- const mode = readFirstString(rawInput, ["target_mode_id", "mode_id"]);
4121
- const explanation = readFirstString(rawInput, ["explanation"]);
4122
- if (mode || explanation) {
4123
- return mode && explanation ? `${mode}: ${explanation}` : mode ?? explanation;
4124
- }
4125
- return readFirstString(rawInput, [
4126
- "path",
4127
- "file",
4128
- "filePath",
4129
- "filepath",
4130
- "file_path",
4131
- "target",
4132
- "uri",
4133
- "url",
4134
- "query",
4135
- "pattern",
4136
- "text",
4137
- "search",
4138
- "working_directory",
4139
- "name",
4140
- "description"
4141
- ]);
4142
- }
4143
- function summarizeTaskInput(rawInput, title) {
4144
- const subagentType = readFirstString(rawInput, ["subagent_type", "subagentType", "agent", "agentType"]);
4145
- const description = readFirstString(rawInput, ["description", "task", "summary"]);
4146
- if (subagentType && description) {
4147
- return description === title ? subagentType : `${subagentType}: ${description}`;
4148
- }
4149
- if (subagentType)
4150
- return subagentType;
4151
- return;
4152
- }
4153
- function readFirstString(record, keys) {
4154
- for (const key of keys) {
4155
- const value = record[key];
4156
- if (typeof value === "string" && value.trim().length > 0) {
4157
- return value.trim();
4158
- }
4159
- }
4160
- return;
4161
- }
4162
- function readFirstStringArray(record, keys) {
4163
- for (const key of keys) {
4164
- const value = record[key];
4165
- if (!Array.isArray(value))
4166
- continue;
4167
- const entries = value.map((entry) => typeof entry === "string" && entry.trim().length > 0 ? entry.trim() : undefined).filter((entry) => entry !== undefined);
4168
- if (entries.length > 0) {
4169
- return entries;
4170
- }
4171
- }
4172
- return;
4173
- }
4174
4250
  function asFiniteNumber(value) {
4175
4251
  return typeof value === "number" && Number.isFinite(value) ? value : undefined;
4176
4252
  }
@@ -4217,9 +4293,6 @@ function normalizeAgentCommands(value) {
4217
4293
  }
4218
4294
  return out;
4219
4295
  }
4220
- function isRecord2(value) {
4221
- return typeof value === "object" && value !== null && !Array.isArray(value);
4222
- }
4223
4296
  function readString2(rawInput, key) {
4224
4297
  if (!isRecord2(rawInput))
4225
4298
  return;
@@ -4242,16 +4315,11 @@ function isGenericToolTitle(kind, title) {
4242
4315
  }
4243
4316
  return false;
4244
4317
  }
4245
- var SENTENCE_TERMINAL_AT_END, PARAGRAPH_BOUNDARY_AT_END, PARAGRAPH_BOUNDARY_AT_START, LINE_BREAK_AT_END, LINE_BREAK_AT_START, PARTIAL_CRLF_PARAGRAPH_BOUNDARY_AT_END, CURSOR_TOOL_NAME_KEY = "_toolName", CURSOR_PLAN_TOOL_NAMES, CURSOR_SUBAGENT_TOOL_NAMES, USAGE_BREAKDOWN_FIELDS;
4318
+ var CURSOR_TOOL_NAME_KEY = "_toolName", CURSOR_PLAN_TOOL_NAMES, CURSOR_SUBAGENT_TOOL_NAMES, USAGE_BREAKDOWN_FIELDS;
4246
4319
  var init_streaming_prompt = __esm(() => {
4247
4320
  init_background_followup();
4248
4321
  init_tool_kind_emoji();
4249
- SENTENCE_TERMINAL_AT_END = /(?:\p{Sentence_Terminal}|…|⋯)[\p{Close_Punctuation}\p{Final_Punctuation}"“”‘’*_~`]*$/u;
4250
- PARAGRAPH_BOUNDARY_AT_END = /\r?\n[\t ]*\r?\n[\t ]*$/;
4251
- PARAGRAPH_BOUNDARY_AT_START = /^[\t ]*\r?\n[\t ]*\r?\n/;
4252
- LINE_BREAK_AT_END = /\r?\n[\t ]*$/;
4253
- LINE_BREAK_AT_START = /^[\t ]*\r?\n/;
4254
- PARTIAL_CRLF_PARAGRAPH_BOUNDARY_AT_END = /\r?\n[\t ]*\r$/;
4322
+ init_transcript_text_boundary();
4255
4323
  CURSOR_PLAN_TOOL_NAMES = new Set([
4256
4324
  "todowrite",
4257
4325
  "createplan",
@@ -15944,15 +16012,18 @@ function mapRuntimeToolEvent(event) {
15944
16012
  const toolCallId = event.toolCallId || `tc-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
15945
16013
  const title = (event.title ?? "").trim();
15946
16014
  const toolName = title || "Tool";
16015
+ const summaryRaw = event.summary || summarizeToolInput(event.rawInput, title) || summarizeToolOutput(event.rawOutput);
16016
+ const summary = summaryRaw && summaryRaw !== title ? summaryRaw : undefined;
15947
16017
  const statusRaw = (event.status ?? "").toLowerCase();
15948
16018
  const status = statusRaw === "completed" || statusRaw === "success" ? "success" : statusRaw === "failed" || statusRaw === "error" ? "error" : "running";
15949
- const validKinds = new Set(["read", "search", "execute", "edit", "think", "other"]);
16019
+ const validKinds = new Set(["read", "search", "execute", "edit", "delete", "move", "fetch", "think", "other"]);
15950
16020
  const kind = typeof event.kind === "string" && validKinds.has(event.kind.toLowerCase()) ? event.kind.toLowerCase() : "other";
15951
16021
  return {
15952
16022
  toolCallId,
15953
16023
  toolName,
15954
16024
  kind,
15955
16025
  status,
16026
+ ...summary ? { summary } : {},
15956
16027
  ...event.rawInput !== undefined ? { rawInput: event.rawInput } : {},
15957
16028
  ...event.rawOutput !== undefined ? { rawOutput: event.rawOutput } : {},
15958
16029
  ...event.content !== undefined ? { content: event.content } : {},
@@ -2441,6 +2441,209 @@ var init_orphan_registry = __esm(() => {
2441
2441
  SAFE_KEY = /^[A-Za-z0-9._-]+$/;
2442
2442
  });
2443
2443
 
2444
+ // src/transport/tool-summary.ts
2445
+ function isRecord(value) {
2446
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2447
+ }
2448
+ function isEmptyToolField(v) {
2449
+ if (v === undefined || v === null)
2450
+ return true;
2451
+ if (typeof v === "string")
2452
+ return v.trim().length === 0;
2453
+ if (Array.isArray(v))
2454
+ return v.length === 0;
2455
+ if (typeof v === "object")
2456
+ return Object.keys(v).length === 0;
2457
+ return false;
2458
+ }
2459
+ function cursorToolInput(rawInput) {
2460
+ if (!isRecord(rawInput))
2461
+ return;
2462
+ if (isRecord(rawInput.args))
2463
+ return rawInput.args;
2464
+ return rawInput;
2465
+ }
2466
+ function readFirstString(record, keys) {
2467
+ for (const key of keys) {
2468
+ const value = record[key];
2469
+ if (typeof value === "string" && value.trim().length > 0) {
2470
+ return value.trim();
2471
+ }
2472
+ }
2473
+ return;
2474
+ }
2475
+ function readFirstStringArray(record, keys) {
2476
+ for (const key of keys) {
2477
+ const value = record[key];
2478
+ if (!Array.isArray(value))
2479
+ continue;
2480
+ const entries = value.map((entry) => typeof entry === "string" && entry.trim().length > 0 ? entry.trim() : undefined).filter((entry) => entry !== undefined);
2481
+ if (entries.length > 0) {
2482
+ return entries;
2483
+ }
2484
+ }
2485
+ return;
2486
+ }
2487
+ function summarizeTaskInput(rawInput, title) {
2488
+ const subagentType = readFirstString(rawInput, ["subagent_type", "subagentType", "agent", "agentType"]);
2489
+ const description = readFirstString(rawInput, ["description", "task", "summary"]);
2490
+ if (subagentType && description) {
2491
+ return description === title ? subagentType : `${subagentType}: ${description}`;
2492
+ }
2493
+ if (subagentType)
2494
+ return subagentType;
2495
+ return;
2496
+ }
2497
+ function summarizeToolInput(rawInput, title = "") {
2498
+ if (rawInput == null)
2499
+ return;
2500
+ if (typeof rawInput === "string" || typeof rawInput === "number" || typeof rawInput === "boolean") {
2501
+ return String(rawInput);
2502
+ }
2503
+ if (!isRecord(rawInput))
2504
+ return;
2505
+ const nestedInput = cursorToolInput(rawInput);
2506
+ if (nestedInput !== rawInput) {
2507
+ const nestedSummary = summarizeToolInput(nestedInput, title);
2508
+ if (nestedSummary)
2509
+ return nestedSummary;
2510
+ }
2511
+ const taskSummary = summarizeTaskInput(rawInput, title);
2512
+ if (taskSummary)
2513
+ return taskSummary;
2514
+ const command = readFirstString(rawInput, ["command", "cmd", "program"]);
2515
+ const args = readFirstStringArray(rawInput, ["args", "arguments"]);
2516
+ if (command) {
2517
+ return [command, ...args ?? []].join(" ");
2518
+ }
2519
+ const parsedCmd = rawInput.parsed_cmd;
2520
+ if (Array.isArray(parsedCmd) && parsedCmd.length > 0) {
2521
+ const parts = [];
2522
+ for (const entry of parsedCmd) {
2523
+ if (isRecord(entry) && typeof entry.cmd === "string" && entry.cmd.length > 0) {
2524
+ parts.push(entry.cmd);
2525
+ }
2526
+ }
2527
+ if (parts.length > 0) {
2528
+ return parts.join(" ");
2529
+ }
2530
+ }
2531
+ const globPattern = readFirstString(rawInput, ["glob_pattern"]);
2532
+ if (globPattern) {
2533
+ const targetDirectory = readFirstString(rawInput, ["target_directory"]);
2534
+ return targetDirectory ? `${globPattern} in ${targetDirectory}` : globPattern;
2535
+ }
2536
+ const mode = readFirstString(rawInput, ["target_mode_id", "mode_id"]);
2537
+ const explanation = readFirstString(rawInput, ["explanation"]);
2538
+ if (mode || explanation) {
2539
+ return mode && explanation ? `${mode}: ${explanation}` : mode ?? explanation;
2540
+ }
2541
+ return readFirstString(rawInput, [
2542
+ "path",
2543
+ "file",
2544
+ "filePath",
2545
+ "filepath",
2546
+ "file_path",
2547
+ "target",
2548
+ "uri",
2549
+ "url",
2550
+ "query",
2551
+ "pattern",
2552
+ "text",
2553
+ "search",
2554
+ "working_directory",
2555
+ "name",
2556
+ "description"
2557
+ ]);
2558
+ }
2559
+ function summarizeToolOutput(rawOutput) {
2560
+ if (rawOutput == null)
2561
+ return;
2562
+ if (typeof rawOutput === "string" || typeof rawOutput === "number" || typeof rawOutput === "boolean") {
2563
+ const text = String(rawOutput).trim();
2564
+ if (!text)
2565
+ return;
2566
+ return text.length > TOOL_OUTPUT_SUMMARY_MAX_CHARS ? text.slice(0, TOOL_OUTPUT_SUMMARY_MAX_CHARS) : text;
2567
+ }
2568
+ if (!isRecord(rawOutput))
2569
+ return;
2570
+ const direct = readFirstString(rawOutput, ["text", "message", "error", "stdout", "stderr", "content"]);
2571
+ if (direct) {
2572
+ return direct.length > TOOL_OUTPUT_SUMMARY_MAX_CHARS ? direct.slice(0, TOOL_OUTPUT_SUMMARY_MAX_CHARS) : direct;
2573
+ }
2574
+ if (Array.isArray(rawOutput.content)) {
2575
+ const parts = [];
2576
+ for (const item of rawOutput.content) {
2577
+ if (typeof item === "string" && item.trim().length > 0) {
2578
+ parts.push(item.trim());
2579
+ } else if (isRecord(item)) {
2580
+ const itemText = readFirstString(item, ["text", "content"]);
2581
+ if (itemText)
2582
+ parts.push(itemText);
2583
+ }
2584
+ }
2585
+ if (parts.length > 0) {
2586
+ const text = parts.join(`
2587
+ `);
2588
+ return text.length > TOOL_OUTPUT_SUMMARY_MAX_CHARS ? text.slice(0, TOOL_OUTPUT_SUMMARY_MAX_CHARS) : text;
2589
+ }
2590
+ }
2591
+ return;
2592
+ }
2593
+ var TOOL_OUTPUT_SUMMARY_MAX_CHARS = 500;
2594
+
2595
+ // src/transport/transcript-text-boundary.ts
2596
+ function createTranscriptTextBoundaryState() {
2597
+ return {
2598
+ hasAgentMessage: false,
2599
+ lastMessageId: undefined,
2600
+ lastTextTail: "",
2601
+ activitySinceLastText: false
2602
+ };
2603
+ }
2604
+ function markTranscriptActivity(state) {
2605
+ state.activitySinceLastText = state.hasAgentMessage;
2606
+ }
2607
+ function endsWithSentenceTerminal(text) {
2608
+ return SENTENCE_TERMINAL_AT_END.test(text.trimEnd());
2609
+ }
2610
+ function hasParagraphBoundaryAtJoin(left, right) {
2611
+ const leftHasBoundary = PARAGRAPH_BOUNDARY_AT_END.test(left);
2612
+ const rightHasBoundary = PARAGRAPH_BOUNDARY_AT_START.test(right);
2613
+ const boundarySpansJoin = LINE_BREAK_AT_END.test(left) && LINE_BREAK_AT_START.test(right);
2614
+ const crlfBoundarySpansJoin = PARTIAL_CRLF_PARAGRAPH_BOUNDARY_AT_END.test(left) && right.startsWith(`
2615
+ `);
2616
+ return leftHasBoundary || rightHasBoundary || boundarySpansJoin || crlfBoundarySpansJoin;
2617
+ }
2618
+ function normalizeTranscriptTextChunk(state, input) {
2619
+ state.hasAgentMessage = true;
2620
+ let chunk = input.text;
2621
+ if (chunk.length === 0)
2622
+ return chunk;
2623
+ const messageId = typeof input.messageId === "string" && input.messageId.length > 0 ? input.messageId : undefined;
2624
+ const messageIdChanged = state.lastMessageId !== undefined && messageId !== undefined && state.lastMessageId !== messageId;
2625
+ const fallbackBoundary = state.activitySinceLastText && (state.lastMessageId === undefined || messageId === undefined) && endsWithSentenceTerminal(state.lastTextTail);
2626
+ if ((messageIdChanged || fallbackBoundary) && !hasParagraphBoundaryAtJoin(state.lastTextTail, chunk)) {
2627
+ chunk = `
2628
+
2629
+ ${chunk}`;
2630
+ state.lastTextTail = "";
2631
+ }
2632
+ state.lastMessageId = messageId;
2633
+ state.activitySinceLastText = false;
2634
+ state.lastTextTail = `${state.lastTextTail}${chunk}`.slice(-256);
2635
+ return chunk;
2636
+ }
2637
+ var SENTENCE_TERMINAL_AT_END, PARAGRAPH_BOUNDARY_AT_END, PARAGRAPH_BOUNDARY_AT_START, LINE_BREAK_AT_END, LINE_BREAK_AT_START, PARTIAL_CRLF_PARAGRAPH_BOUNDARY_AT_END;
2638
+ var init_transcript_text_boundary = __esm(() => {
2639
+ SENTENCE_TERMINAL_AT_END = /(?:\p{Sentence_Terminal}|…|⋯)[\p{Close_Punctuation}\p{Final_Punctuation}"“”‘’*_~`]*$/u;
2640
+ PARAGRAPH_BOUNDARY_AT_END = /\r?\n[\t ]*\r?\n[\t ]*$/;
2641
+ PARAGRAPH_BOUNDARY_AT_START = /^[\t ]*\r?\n[\t ]*\r?\n/;
2642
+ LINE_BREAK_AT_END = /\r?\n[\t ]*$/;
2643
+ LINE_BREAK_AT_START = /^[\t ]*\r?\n/;
2644
+ PARTIAL_CRLF_PARAGRAPH_BOUNDARY_AT_END = /\r?\n[\t ]*\r$/;
2645
+ });
2646
+
2444
2647
  // src/transport/session-effort.ts
2445
2648
  function sessionEffortToReapply(input) {
2446
2649
  const effort = input.persisted?.trim();
@@ -2469,11 +2672,11 @@ function parseSessionEffortRecord(raw) {
2469
2672
  } catch {
2470
2673
  return;
2471
2674
  }
2472
- if (!isRecord(record) || !isRecord(record.acpx) || !Array.isArray(record.acpx.config_options)) {
2675
+ if (!isRecord2(record) || !isRecord2(record.acpx) || !Array.isArray(record.acpx.config_options)) {
2473
2676
  return;
2474
2677
  }
2475
2678
  for (const candidate of record.acpx.config_options) {
2476
- if (!isRecord(candidate) || typeof candidate.id !== "string")
2679
+ if (!isRecord2(candidate) || typeof candidate.id !== "string")
2477
2680
  continue;
2478
2681
  if (candidate.category !== "thought_level" && !EFFORT_CONFIG_IDS.has(candidate.id))
2479
2682
  continue;
@@ -2487,13 +2690,13 @@ function parseSessionEffortRecord(raw) {
2487
2690
  return;
2488
2691
  }
2489
2692
  function effortOptionValues(option) {
2490
- if (!isRecord(option))
2693
+ if (!isRecord2(option))
2491
2694
  return [];
2492
2695
  if (typeof option.value === "string")
2493
2696
  return [option.value];
2494
2697
  return Array.isArray(option.options) ? option.options.flatMap(effortOptionValues) : [];
2495
2698
  }
2496
- function isRecord(value) {
2699
+ function isRecord2(value) {
2497
2700
  return typeof value === "object" && value !== null;
2498
2701
  }
2499
2702
  var EFFORT_CONFIG_IDS;
@@ -6660,6 +6863,72 @@ import {
6660
6863
  createAgentRegistry,
6661
6864
  createRuntimeStore
6662
6865
  } from "acpx/runtime";
6866
+
6867
+ // src/bridge/engine/runtime/runtime-tool-call-merge.ts
6868
+ function isMeaningfulTitle(title) {
6869
+ if (typeof title !== "string")
6870
+ return false;
6871
+ const trimmed = title.trim();
6872
+ return trimmed.length > 0 && trimmed.toLowerCase() !== "tool call";
6873
+ }
6874
+ function mergeTitle(prevTitle, nextTitle) {
6875
+ if (nextTitle === undefined || nextTitle === null || nextTitle.trim().length === 0) {
6876
+ return prevTitle;
6877
+ }
6878
+ const nextTrimmed = nextTitle.trim();
6879
+ if (isMeaningfulTitle(nextTrimmed)) {
6880
+ return nextTrimmed;
6881
+ }
6882
+ if (isMeaningfulTitle(prevTitle)) {
6883
+ return prevTitle;
6884
+ }
6885
+ return nextTrimmed;
6886
+ }
6887
+ function normalizeRuntimeToolCallEvent(toolCalls, event) {
6888
+ const toolCallId = event.toolCallId;
6889
+ if (!toolCallId) {
6890
+ return {
6891
+ type: "tool_call",
6892
+ text: event.text,
6893
+ ...event.tag ? { tag: event.tag } : {},
6894
+ ...event.status ? { status: event.status } : {},
6895
+ ...event.title ? { title: event.title } : {},
6896
+ ...event.kind ? { kind: event.kind } : {},
6897
+ ...event.locations !== undefined ? { locations: event.locations } : {},
6898
+ ...event.rawInput !== undefined ? { rawInput: event.rawInput } : {},
6899
+ ...event.rawOutput !== undefined ? { rawOutput: event.rawOutput } : {},
6900
+ ...event.content !== undefined ? { content: event.content } : {}
6901
+ };
6902
+ }
6903
+ const prev = toolCalls.get(toolCallId);
6904
+ const title = mergeTitle(prev?.title, event.title);
6905
+ const text = typeof event.text === "string" && event.text.trim().length > 0 ? event.text : prev?.text ?? event.text ?? "";
6906
+ const tag = event.tag ?? prev?.tag;
6907
+ const kind = !isEmptyToolField(event.kind) ? event.kind : prev?.kind;
6908
+ const status = !isEmptyToolField(event.status) ? event.status : prev?.status;
6909
+ const rawInput = !isEmptyToolField(event.rawInput) ? event.rawInput : prev?.rawInput;
6910
+ const rawOutput = !isEmptyToolField(event.rawOutput) ? event.rawOutput : prev?.rawOutput;
6911
+ const content = !isEmptyToolField(event.content) ? event.content : prev?.content;
6912
+ const locations = !isEmptyToolField(event.locations) ? event.locations : prev?.locations;
6913
+ const snapshot = {
6914
+ type: "tool_call",
6915
+ toolCallId,
6916
+ text,
6917
+ ...tag ? { tag } : {},
6918
+ ...title !== undefined ? { title } : {},
6919
+ ...kind !== undefined ? { kind } : {},
6920
+ ...status !== undefined ? { status } : {},
6921
+ ...rawInput !== undefined ? { rawInput } : {},
6922
+ ...rawOutput !== undefined ? { rawOutput } : {},
6923
+ ...content !== undefined ? { content } : {},
6924
+ ...locations !== undefined ? { locations } : {}
6925
+ };
6926
+ toolCalls.set(toolCallId, snapshot);
6927
+ return snapshot;
6928
+ }
6929
+
6930
+ // src/bridge/engine/runtime/runtime-adapter.ts
6931
+ init_transcript_text_boundary();
6663
6932
  function createXacpxRuntimeAdapter(options) {
6664
6933
  const runtime = createAcpRuntime({
6665
6934
  cwd: process.cwd(),
@@ -6727,10 +6996,51 @@ function createXacpxRuntimeAdapter(options) {
6727
6996
  }
6728
6997
  };
6729
6998
  }
6999
+ function normalizeTextDeltaMeta(meta) {
7000
+ if (!meta || typeof meta !== "object")
7001
+ return;
7002
+ const raw = meta;
7003
+ const result = {};
7004
+ if (typeof raw.origin === "string" && raw.origin.length > 0)
7005
+ result.origin = raw.origin;
7006
+ if (typeof raw.kind === "string" && raw.kind.length > 0)
7007
+ result.kind = raw.kind;
7008
+ if (typeof raw.source === "string" && raw.source.length > 0)
7009
+ result.source = raw.source;
7010
+ return Object.keys(result).length > 0 ? result : undefined;
7011
+ }
6730
7012
  async function* mapEvents(events) {
7013
+ const toolCalls = new Map;
7014
+ const textBoundary = createTranscriptTextBoundaryState();
6731
7015
  for await (const event of events) {
6732
7016
  if (event.type === "text_delta") {
6733
- yield { type: "text_delta", text: event.text, ...event.stream ? { stream: event.stream } : {} };
7017
+ const isThought = event.stream === "thought";
7018
+ if (isThought) {
7019
+ markTranscriptActivity(textBoundary);
7020
+ const meta = normalizeTextDeltaMeta(event.meta);
7021
+ yield {
7022
+ type: "text_delta",
7023
+ text: event.text,
7024
+ stream: "thought",
7025
+ ...event.tag ? { tag: event.tag } : {},
7026
+ ...event.messageId ? { messageId: event.messageId } : {},
7027
+ ...meta ? { meta } : {}
7028
+ };
7029
+ } else {
7030
+ const text = normalizeTranscriptTextChunk(textBoundary, {
7031
+ text: event.text,
7032
+ messageId: event.messageId
7033
+ });
7034
+ const meta = normalizeTextDeltaMeta(event.meta);
7035
+ yield {
7036
+ type: "text_delta",
7037
+ text,
7038
+ ...event.stream ? { stream: event.stream } : {},
7039
+ ...event.tag ? { tag: event.tag } : {},
7040
+ ...event.messageId ? { messageId: event.messageId } : {},
7041
+ ...meta ? { meta } : {}
7042
+ };
7043
+ }
6734
7044
  } else if (event.type === "status") {
6735
7045
  yield {
6736
7046
  type: "status",
@@ -6743,9 +7053,14 @@ async function* mapEvents(events) {
6743
7053
  ...event.availableCommands ? { availableCommands: event.availableCommands } : {}
6744
7054
  };
6745
7055
  } else if (event.type === "tool_call") {
6746
- yield {
7056
+ const isInitialToolEvent = typeof event.toolCallId === "string" ? !toolCalls.has(event.toolCallId) : event.tag !== "tool_call_update";
7057
+ if (isInitialToolEvent) {
7058
+ markTranscriptActivity(textBoundary);
7059
+ }
7060
+ yield normalizeRuntimeToolCallEvent(toolCalls, {
6747
7061
  type: "tool_call",
6748
7062
  text: event.text,
7063
+ ...event.tag ? { tag: event.tag } : {},
6749
7064
  ...event.toolCallId ? { toolCallId: event.toolCallId } : {},
6750
7065
  ...event.status ? { status: event.status } : {},
6751
7066
  ...event.title ? { title: event.title } : {},
@@ -6754,7 +7069,7 @@ async function* mapEvents(events) {
6754
7069
  ...event.rawInput !== undefined ? { rawInput: event.rawInput } : {},
6755
7070
  ...event.rawOutput !== undefined ? { rawOutput: event.rawOutput } : {},
6756
7071
  ...event.content !== undefined ? { content: event.content } : {}
6757
- };
7072
+ });
6758
7073
  }
6759
7074
  }
6760
7075
  }
@@ -201,7 +201,7 @@ export interface MessageChannelRuntime {
201
201
  syncAgentEndpoints?(endpoints: unknown[]): void;
202
202
  }
203
203
  export type ToolUseStatus = "running" | "success" | "error";
204
- export type ToolUseKind = "read" | "search" | "execute" | "edit" | "think" | "other";
204
+ export type ToolUseKind = "read" | "search" | "execute" | "edit" | "delete" | "move" | "fetch" | "think" | "other";
205
205
  export interface ToolUseEvent {
206
206
  toolCallId: string;
207
207
  /** Parent ACP tool call when this tool runs inside a delegated subagent. */
package/dist/cli.js CHANGED
@@ -58128,12 +58128,218 @@ var init_tool_kind_emoji = __esm(() => {
58128
58128
  search: "\uD83D\uDD0D",
58129
58129
  execute: "\uD83D\uDCBB",
58130
58130
  edit: "✏️",
58131
+ delete: "\uD83D\uDDD1️",
58132
+ move: "\uD83D\uDCE6",
58133
+ fetch: "\uD83C\uDF10",
58131
58134
  think: "\uD83E\uDDE0",
58132
58135
  other: "\uD83D\uDD27"
58133
58136
  };
58134
58137
  DEFAULT_TOOL_EMOJI = TOOL_KIND_EMOJI.other;
58135
58138
  });
58136
58139
 
58140
+ // src/transport/tool-summary.ts
58141
+ function isRecord5(value) {
58142
+ return typeof value === "object" && value !== null && !Array.isArray(value);
58143
+ }
58144
+ function isEmptyToolField(v) {
58145
+ if (v === undefined || v === null)
58146
+ return true;
58147
+ if (typeof v === "string")
58148
+ return v.trim().length === 0;
58149
+ if (Array.isArray(v))
58150
+ return v.length === 0;
58151
+ if (typeof v === "object")
58152
+ return Object.keys(v).length === 0;
58153
+ return false;
58154
+ }
58155
+ function cursorToolInput(rawInput) {
58156
+ if (!isRecord5(rawInput))
58157
+ return;
58158
+ if (isRecord5(rawInput.args))
58159
+ return rawInput.args;
58160
+ return rawInput;
58161
+ }
58162
+ function readFirstString(record3, keys) {
58163
+ for (const key of keys) {
58164
+ const value = record3[key];
58165
+ if (typeof value === "string" && value.trim().length > 0) {
58166
+ return value.trim();
58167
+ }
58168
+ }
58169
+ return;
58170
+ }
58171
+ function readFirstStringArray(record3, keys) {
58172
+ for (const key of keys) {
58173
+ const value = record3[key];
58174
+ if (!Array.isArray(value))
58175
+ continue;
58176
+ const entries = value.map((entry) => typeof entry === "string" && entry.trim().length > 0 ? entry.trim() : undefined).filter((entry) => entry !== undefined);
58177
+ if (entries.length > 0) {
58178
+ return entries;
58179
+ }
58180
+ }
58181
+ return;
58182
+ }
58183
+ function summarizeTaskInput(rawInput, title) {
58184
+ const subagentType = readFirstString(rawInput, ["subagent_type", "subagentType", "agent", "agentType"]);
58185
+ const description = readFirstString(rawInput, ["description", "task", "summary"]);
58186
+ if (subagentType && description) {
58187
+ return description === title ? subagentType : `${subagentType}: ${description}`;
58188
+ }
58189
+ if (subagentType)
58190
+ return subagentType;
58191
+ return;
58192
+ }
58193
+ function summarizeToolInput(rawInput, title = "") {
58194
+ if (rawInput == null)
58195
+ return;
58196
+ if (typeof rawInput === "string" || typeof rawInput === "number" || typeof rawInput === "boolean") {
58197
+ return String(rawInput);
58198
+ }
58199
+ if (!isRecord5(rawInput))
58200
+ return;
58201
+ const nestedInput = cursorToolInput(rawInput);
58202
+ if (nestedInput !== rawInput) {
58203
+ const nestedSummary = summarizeToolInput(nestedInput, title);
58204
+ if (nestedSummary)
58205
+ return nestedSummary;
58206
+ }
58207
+ const taskSummary = summarizeTaskInput(rawInput, title);
58208
+ if (taskSummary)
58209
+ return taskSummary;
58210
+ const command = readFirstString(rawInput, ["command", "cmd", "program"]);
58211
+ const args = readFirstStringArray(rawInput, ["args", "arguments"]);
58212
+ if (command) {
58213
+ return [command, ...args ?? []].join(" ");
58214
+ }
58215
+ const parsedCmd = rawInput.parsed_cmd;
58216
+ if (Array.isArray(parsedCmd) && parsedCmd.length > 0) {
58217
+ const parts = [];
58218
+ for (const entry of parsedCmd) {
58219
+ if (isRecord5(entry) && typeof entry.cmd === "string" && entry.cmd.length > 0) {
58220
+ parts.push(entry.cmd);
58221
+ }
58222
+ }
58223
+ if (parts.length > 0) {
58224
+ return parts.join(" ");
58225
+ }
58226
+ }
58227
+ const globPattern = readFirstString(rawInput, ["glob_pattern"]);
58228
+ if (globPattern) {
58229
+ const targetDirectory = readFirstString(rawInput, ["target_directory"]);
58230
+ return targetDirectory ? `${globPattern} in ${targetDirectory}` : globPattern;
58231
+ }
58232
+ const mode = readFirstString(rawInput, ["target_mode_id", "mode_id"]);
58233
+ const explanation = readFirstString(rawInput, ["explanation"]);
58234
+ if (mode || explanation) {
58235
+ return mode && explanation ? `${mode}: ${explanation}` : mode ?? explanation;
58236
+ }
58237
+ return readFirstString(rawInput, [
58238
+ "path",
58239
+ "file",
58240
+ "filePath",
58241
+ "filepath",
58242
+ "file_path",
58243
+ "target",
58244
+ "uri",
58245
+ "url",
58246
+ "query",
58247
+ "pattern",
58248
+ "text",
58249
+ "search",
58250
+ "working_directory",
58251
+ "name",
58252
+ "description"
58253
+ ]);
58254
+ }
58255
+ function summarizeToolOutput(rawOutput) {
58256
+ if (rawOutput == null)
58257
+ return;
58258
+ if (typeof rawOutput === "string" || typeof rawOutput === "number" || typeof rawOutput === "boolean") {
58259
+ const text = String(rawOutput).trim();
58260
+ if (!text)
58261
+ return;
58262
+ return text.length > TOOL_OUTPUT_SUMMARY_MAX_CHARS ? text.slice(0, TOOL_OUTPUT_SUMMARY_MAX_CHARS) : text;
58263
+ }
58264
+ if (!isRecord5(rawOutput))
58265
+ return;
58266
+ const direct = readFirstString(rawOutput, ["text", "message", "error", "stdout", "stderr", "content"]);
58267
+ if (direct) {
58268
+ return direct.length > TOOL_OUTPUT_SUMMARY_MAX_CHARS ? direct.slice(0, TOOL_OUTPUT_SUMMARY_MAX_CHARS) : direct;
58269
+ }
58270
+ if (Array.isArray(rawOutput.content)) {
58271
+ const parts = [];
58272
+ for (const item of rawOutput.content) {
58273
+ if (typeof item === "string" && item.trim().length > 0) {
58274
+ parts.push(item.trim());
58275
+ } else if (isRecord5(item)) {
58276
+ const itemText = readFirstString(item, ["text", "content"]);
58277
+ if (itemText)
58278
+ parts.push(itemText);
58279
+ }
58280
+ }
58281
+ if (parts.length > 0) {
58282
+ const text = parts.join(`
58283
+ `);
58284
+ return text.length > TOOL_OUTPUT_SUMMARY_MAX_CHARS ? text.slice(0, TOOL_OUTPUT_SUMMARY_MAX_CHARS) : text;
58285
+ }
58286
+ }
58287
+ return;
58288
+ }
58289
+ var TOOL_OUTPUT_SUMMARY_MAX_CHARS = 500;
58290
+
58291
+ // src/transport/transcript-text-boundary.ts
58292
+ function createTranscriptTextBoundaryState() {
58293
+ return {
58294
+ hasAgentMessage: false,
58295
+ lastMessageId: undefined,
58296
+ lastTextTail: "",
58297
+ activitySinceLastText: false
58298
+ };
58299
+ }
58300
+ function markTranscriptActivity(state) {
58301
+ state.activitySinceLastText = state.hasAgentMessage;
58302
+ }
58303
+ function endsWithSentenceTerminal(text) {
58304
+ return SENTENCE_TERMINAL_AT_END.test(text.trimEnd());
58305
+ }
58306
+ function hasParagraphBoundaryAtJoin(left, right) {
58307
+ const leftHasBoundary = PARAGRAPH_BOUNDARY_AT_END.test(left);
58308
+ const rightHasBoundary = PARAGRAPH_BOUNDARY_AT_START.test(right);
58309
+ const boundarySpansJoin = LINE_BREAK_AT_END.test(left) && LINE_BREAK_AT_START.test(right);
58310
+ const crlfBoundarySpansJoin = PARTIAL_CRLF_PARAGRAPH_BOUNDARY_AT_END.test(left) && right.startsWith(`
58311
+ `);
58312
+ return leftHasBoundary || rightHasBoundary || boundarySpansJoin || crlfBoundarySpansJoin;
58313
+ }
58314
+ function normalizeTranscriptTextChunk(state, input) {
58315
+ state.hasAgentMessage = true;
58316
+ let chunk = input.text;
58317
+ if (chunk.length === 0)
58318
+ return chunk;
58319
+ const messageId = typeof input.messageId === "string" && input.messageId.length > 0 ? input.messageId : undefined;
58320
+ const messageIdChanged = state.lastMessageId !== undefined && messageId !== undefined && state.lastMessageId !== messageId;
58321
+ const fallbackBoundary = state.activitySinceLastText && (state.lastMessageId === undefined || messageId === undefined) && endsWithSentenceTerminal(state.lastTextTail);
58322
+ if ((messageIdChanged || fallbackBoundary) && !hasParagraphBoundaryAtJoin(state.lastTextTail, chunk)) {
58323
+ chunk = `
58324
+
58325
+ ${chunk}`;
58326
+ state.lastTextTail = "";
58327
+ }
58328
+ state.lastMessageId = messageId;
58329
+ state.activitySinceLastText = false;
58330
+ state.lastTextTail = `${state.lastTextTail}${chunk}`.slice(-256);
58331
+ return chunk;
58332
+ }
58333
+ var SENTENCE_TERMINAL_AT_END, PARAGRAPH_BOUNDARY_AT_END, PARAGRAPH_BOUNDARY_AT_START, LINE_BREAK_AT_END, LINE_BREAK_AT_START, PARTIAL_CRLF_PARAGRAPH_BOUNDARY_AT_END;
58334
+ var init_transcript_text_boundary = __esm(() => {
58335
+ SENTENCE_TERMINAL_AT_END = /(?:\p{Sentence_Terminal}|…|⋯)[\p{Close_Punctuation}\p{Final_Punctuation}"“”‘’*_~`]*$/u;
58336
+ PARAGRAPH_BOUNDARY_AT_END = /\r?\n[\t ]*\r?\n[\t ]*$/;
58337
+ PARAGRAPH_BOUNDARY_AT_START = /^[\t ]*\r?\n[\t ]*\r?\n/;
58338
+ LINE_BREAK_AT_END = /\r?\n[\t ]*$/;
58339
+ LINE_BREAK_AT_START = /^[\t ]*\r?\n/;
58340
+ PARTIAL_CRLF_PARAGRAPH_BOUNDARY_AT_END = /\r?\n[\t ]*\r$/;
58341
+ });
58342
+
58137
58343
  // src/transport/streaming-prompt.ts
58138
58344
  function createStreamingPromptState(formatToolCalls = false, options) {
58139
58345
  let toolEventMode;
@@ -58166,9 +58372,9 @@ function createStreamingPromptState(formatToolCalls = false, options) {
58166
58372
  });
58167
58373
  }
58168
58374
  return {
58375
+ ...createTranscriptTextBoundaryState(),
58169
58376
  buffer: "",
58170
58377
  segments: [],
58171
- hasAgentMessage: false,
58172
58378
  pendingLine: "",
58173
58379
  formatToolCalls,
58174
58380
  emittedToolCallIds: new Set,
@@ -58178,8 +58384,6 @@ function createStreamingPromptState(formatToolCalls = false, options) {
58178
58384
  toolEventMode,
58179
58385
  driver,
58180
58386
  rawStream,
58181
- lastTextTail: "",
58182
- activitySinceLastText: false,
58183
58387
  onBeforeActivityEvent,
58184
58388
  onToolEvent,
58185
58389
  onThought,
@@ -58291,23 +58495,14 @@ function parseStreamingChunks(state, line) {
58291
58495
  const isMessageChunk = update.sessionUpdate === "agent_message_chunk" && update.content?.type === "text" && typeof update.content.text === "string";
58292
58496
  if (!isMessageChunk)
58293
58497
  return;
58294
- state.hasAgentMessage = true;
58295
- let chunk = update.content.text ?? "";
58296
- if (chunk.length === 0)
58498
+ const rawChunk = update.content.text ?? "";
58499
+ if (rawChunk.length === 0)
58297
58500
  return;
58298
- const messageId = typeof update.messageId === "string" && update.messageId.length > 0 ? update.messageId : undefined;
58299
- const messageIdChanged = state.lastMessageId !== undefined && messageId !== undefined && state.lastMessageId !== messageId;
58300
- const fallbackBoundary = state.activitySinceLastText && (state.lastMessageId === undefined || messageId === undefined) && endsWithSentenceTerminal(state.lastTextTail);
58301
- if ((messageIdChanged || fallbackBoundary) && !hasParagraphBoundaryAtJoin(state.lastTextTail, chunk)) {
58302
- chunk = `
58303
-
58304
- ${chunk}`;
58305
- state.lastTextTail = "";
58306
- }
58501
+ const chunk = normalizeTranscriptTextChunk(state, {
58502
+ text: rawChunk,
58503
+ messageId: update.messageId
58504
+ });
58307
58505
  state.buffer += chunk;
58308
- state.lastMessageId = messageId;
58309
- state.activitySinceLastText = false;
58310
- state.lastTextTail = `${state.lastTextTail}${chunk}`.slice(-256);
58311
58506
  if (state.rawStream)
58312
58507
  return;
58313
58508
  let boundary;
@@ -58321,20 +58516,9 @@ ${chunk}`;
58321
58516
  }
58322
58517
  }
58323
58518
  }
58324
- function endsWithSentenceTerminal(text) {
58325
- return SENTENCE_TERMINAL_AT_END.test(text.trimEnd());
58326
- }
58327
- function hasParagraphBoundaryAtJoin(left, right) {
58328
- const leftHasBoundary = PARAGRAPH_BOUNDARY_AT_END.test(left);
58329
- const rightHasBoundary = PARAGRAPH_BOUNDARY_AT_START.test(right);
58330
- const boundarySpansJoin = LINE_BREAK_AT_END.test(left) && LINE_BREAK_AT_START.test(right);
58331
- const crlfBoundarySpansJoin = PARTIAL_CRLF_PARAGRAPH_BOUNDARY_AT_END.test(left) && right.startsWith(`
58332
- `);
58333
- return leftHasBoundary || rightHasBoundary || boundarySpansJoin || crlfBoundarySpansJoin;
58334
- }
58335
58519
  function markActivityBoundary(state) {
58336
58520
  flushBeforeActivityEvent(state);
58337
- state.activitySinceLastText = state.hasAgentMessage;
58521
+ markTranscriptActivity(state);
58338
58522
  }
58339
58523
  function flushBeforeActivityEvent(state) {
58340
58524
  state.onBeforeActivityEvent?.();
@@ -58357,17 +58541,6 @@ function formatToolCallEvent(update, sessionUpdate) {
58357
58541
  const statusText = status ? ` (${status})` : "";
58358
58542
  return `${emoji2} ${title}${statusText}${summaryText}`;
58359
58543
  }
58360
- function isEmptyToolField(v) {
58361
- if (v === undefined || v === null)
58362
- return true;
58363
- if (typeof v === "string")
58364
- return v.trim().length === 0;
58365
- if (Array.isArray(v))
58366
- return v.length === 0;
58367
- if (typeof v === "object")
58368
- return Object.keys(v).length === 0;
58369
- return false;
58370
- }
58371
58544
  function mergeToolCallUpdate(state, toolCallId, update) {
58372
58545
  const prev = state.toolCalls.get(toolCallId) ?? { toolCallId };
58373
58546
  const merged = { ...prev };
@@ -58565,13 +58738,6 @@ function normalizePlanPriority(value) {
58565
58738
  return;
58566
58739
  return value;
58567
58740
  }
58568
- function cursorToolInput(rawInput) {
58569
- if (!isRecord5(rawInput))
58570
- return;
58571
- if (isRecord5(rawInput.args))
58572
- return rawInput.args;
58573
- return rawInput;
58574
- }
58575
58741
  function normalizeCursorToolName(title) {
58576
58742
  return (title ?? "").trim().toLowerCase().replace(/[\s_-]+/g, "");
58577
58743
  }
@@ -58587,6 +58753,9 @@ function normalizeToolKind(update, driver) {
58587
58753
  case "search":
58588
58754
  case "execute":
58589
58755
  case "edit":
58756
+ case "delete":
58757
+ case "move":
58758
+ case "fetch":
58590
58759
  case "think":
58591
58760
  return kindRaw;
58592
58761
  }
@@ -58639,99 +58808,6 @@ function isKimiSubagentInput(rawInput) {
58639
58808
  function isCodexSubagentMeta(meta2) {
58640
58809
  return typeof meta2?.threadId === "string" && meta2.threadId.trim().length > 0 && typeof meta2.activity === "string" && meta2.activity.trim().length > 0;
58641
58810
  }
58642
- function summarizeToolInput(rawInput, title = "") {
58643
- if (rawInput == null)
58644
- return;
58645
- if (typeof rawInput === "string" || typeof rawInput === "number" || typeof rawInput === "boolean") {
58646
- return String(rawInput);
58647
- }
58648
- if (!isRecord5(rawInput))
58649
- return;
58650
- const nestedInput = cursorToolInput(rawInput);
58651
- if (nestedInput !== rawInput) {
58652
- const nestedSummary = summarizeToolInput(nestedInput, title);
58653
- if (nestedSummary)
58654
- return nestedSummary;
58655
- }
58656
- const taskSummary = summarizeTaskInput(rawInput, title);
58657
- if (taskSummary)
58658
- return taskSummary;
58659
- const command = readFirstString(rawInput, ["command", "cmd", "program"]);
58660
- const args = readFirstStringArray(rawInput, ["args", "arguments"]);
58661
- if (command) {
58662
- return [command, ...args ?? []].join(" ");
58663
- }
58664
- const parsedCmd = rawInput.parsed_cmd;
58665
- if (Array.isArray(parsedCmd) && parsedCmd.length > 0) {
58666
- const parts = [];
58667
- for (const entry of parsedCmd) {
58668
- if (isRecord5(entry) && typeof entry.cmd === "string" && entry.cmd.length > 0) {
58669
- parts.push(entry.cmd);
58670
- }
58671
- }
58672
- if (parts.length > 0) {
58673
- return parts.join(" ");
58674
- }
58675
- }
58676
- const globPattern = readFirstString(rawInput, ["glob_pattern"]);
58677
- if (globPattern) {
58678
- const targetDirectory = readFirstString(rawInput, ["target_directory"]);
58679
- return targetDirectory ? `${globPattern} in ${targetDirectory}` : globPattern;
58680
- }
58681
- const mode = readFirstString(rawInput, ["target_mode_id", "mode_id"]);
58682
- const explanation = readFirstString(rawInput, ["explanation"]);
58683
- if (mode || explanation) {
58684
- return mode && explanation ? `${mode}: ${explanation}` : mode ?? explanation;
58685
- }
58686
- return readFirstString(rawInput, [
58687
- "path",
58688
- "file",
58689
- "filePath",
58690
- "filepath",
58691
- "file_path",
58692
- "target",
58693
- "uri",
58694
- "url",
58695
- "query",
58696
- "pattern",
58697
- "text",
58698
- "search",
58699
- "working_directory",
58700
- "name",
58701
- "description"
58702
- ]);
58703
- }
58704
- function summarizeTaskInput(rawInput, title) {
58705
- const subagentType = readFirstString(rawInput, ["subagent_type", "subagentType", "agent", "agentType"]);
58706
- const description = readFirstString(rawInput, ["description", "task", "summary"]);
58707
- if (subagentType && description) {
58708
- return description === title ? subagentType : `${subagentType}: ${description}`;
58709
- }
58710
- if (subagentType)
58711
- return subagentType;
58712
- return;
58713
- }
58714
- function readFirstString(record3, keys) {
58715
- for (const key of keys) {
58716
- const value = record3[key];
58717
- if (typeof value === "string" && value.trim().length > 0) {
58718
- return value.trim();
58719
- }
58720
- }
58721
- return;
58722
- }
58723
- function readFirstStringArray(record3, keys) {
58724
- for (const key of keys) {
58725
- const value = record3[key];
58726
- if (!Array.isArray(value))
58727
- continue;
58728
- const entries = value.map((entry) => typeof entry === "string" && entry.trim().length > 0 ? entry.trim() : undefined).filter((entry) => entry !== undefined);
58729
- if (entries.length > 0) {
58730
- return entries;
58731
- }
58732
- }
58733
- return;
58734
- }
58735
58811
  function asFiniteNumber(value) {
58736
58812
  return typeof value === "number" && Number.isFinite(value) ? value : undefined;
58737
58813
  }
@@ -58778,9 +58854,6 @@ function normalizeAgentCommands(value) {
58778
58854
  }
58779
58855
  return out;
58780
58856
  }
58781
- function isRecord5(value) {
58782
- return typeof value === "object" && value !== null && !Array.isArray(value);
58783
- }
58784
58857
  function readString2(rawInput, key) {
58785
58858
  if (!isRecord5(rawInput))
58786
58859
  return;
@@ -58803,16 +58876,11 @@ function isGenericToolTitle(kind, title) {
58803
58876
  }
58804
58877
  return false;
58805
58878
  }
58806
- var SENTENCE_TERMINAL_AT_END, PARAGRAPH_BOUNDARY_AT_END, PARAGRAPH_BOUNDARY_AT_START, LINE_BREAK_AT_END, LINE_BREAK_AT_START, PARTIAL_CRLF_PARAGRAPH_BOUNDARY_AT_END, CURSOR_TOOL_NAME_KEY = "_toolName", CURSOR_PLAN_TOOL_NAMES, CURSOR_SUBAGENT_TOOL_NAMES, USAGE_BREAKDOWN_FIELDS;
58879
+ var CURSOR_TOOL_NAME_KEY = "_toolName", CURSOR_PLAN_TOOL_NAMES, CURSOR_SUBAGENT_TOOL_NAMES, USAGE_BREAKDOWN_FIELDS;
58807
58880
  var init_streaming_prompt = __esm(() => {
58808
58881
  init_background_followup();
58809
58882
  init_tool_kind_emoji();
58810
- SENTENCE_TERMINAL_AT_END = /(?:\p{Sentence_Terminal}|…|⋯)[\p{Close_Punctuation}\p{Final_Punctuation}"“”‘’*_~`]*$/u;
58811
- PARAGRAPH_BOUNDARY_AT_END = /\r?\n[\t ]*\r?\n[\t ]*$/;
58812
- PARAGRAPH_BOUNDARY_AT_START = /^[\t ]*\r?\n[\t ]*\r?\n/;
58813
- LINE_BREAK_AT_END = /\r?\n[\t ]*$/;
58814
- LINE_BREAK_AT_START = /^[\t ]*\r?\n/;
58815
- PARTIAL_CRLF_PARAGRAPH_BOUNDARY_AT_END = /\r?\n[\t ]*\r$/;
58883
+ init_transcript_text_boundary();
58816
58884
  CURSOR_PLAN_TOOL_NAMES = new Set([
58817
58885
  "todowrite",
58818
58886
  "createplan",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ganglion/xacpx",
3
- "version": "0.24.2-beta.0",
3
+ "version": "0.24.3-beta.0",
4
4
  "description": "随时随地通过聊天频道(微信 / 飞书 / 元宝等)远程控制 `acpx` 上的 Claude Code、Codex 等 Agents。",
5
5
  "keywords": [
6
6
  "acpx",