@jun133/kitty 0.0.12 → 0.0.14

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.
@@ -1034,6 +1034,7 @@ function buildToolBlock() {
1034
1034
  function buildCommunicationBlock() {
1035
1035
  return [
1036
1036
  "Always reply in Simplified Chinese.",
1037
+ "No Markdown in user-facing conversational replies; prefer plain text whenever possible.",
1037
1038
  "Provide concise progress updates during multi-step work.",
1038
1039
  "Make every sentence carry decision, execution, evidence, or understanding.",
1039
1040
  "Claim changed files, passed commands, and successful tools only when tool evidence supports them.",
@@ -3557,14 +3558,21 @@ async function launchCommand(command, cwd, timeoutMs, abortSignal) {
3557
3558
  function encodePowerShellCommand(command) {
3558
3559
  const wrapped = [
3559
3560
  "$ProgressPreference = 'SilentlyContinue'",
3561
+ "$ErrorActionPreference = 'Stop'",
3560
3562
  "[Console]::InputEncoding = [System.Text.Encoding]::UTF8",
3561
3563
  "[Console]::OutputEncoding = [System.Text.Encoding]::UTF8",
3562
3564
  "$OutputEncoding = [System.Text.Encoding]::UTF8",
3563
3565
  "try { chcp 65001 > $null } catch { }",
3566
+ "$code = 0",
3567
+ "try {",
3564
3568
  `& { ${command} }`,
3565
3569
  "$code = if ($null -ne $LASTEXITCODE) { [int]$LASTEXITCODE } elseif ($?) { 0 } else { 1 }",
3570
+ "} catch {",
3571
+ "[Console]::Error.WriteLine($_.Exception.Message)",
3572
+ "$code = 1",
3573
+ "}",
3566
3574
  "exit $code"
3567
- ].join("; ");
3575
+ ].join("\n");
3568
3576
  return Buffer.from(wrapped, "utf16le").toString("base64");
3569
3577
  }
3570
3578
  function buildCommandEnvironment() {
@@ -3576,422 +3584,33 @@ function buildCommandEnvironment() {
3576
3584
  };
3577
3585
  }
3578
3586
 
3579
- // src/utils/commandRunner/platformArgs.ts
3580
- function splitByAndAnd(command) {
3581
- const segments = [];
3582
- let current = "";
3583
- let inSingle = false;
3584
- let inDouble = false;
3585
- for (let index = 0; index < command.length; index += 1) {
3586
- const char = command.charAt(index);
3587
- if (char === "'" && !inDouble) {
3588
- inSingle = !inSingle;
3589
- current += char;
3590
- continue;
3591
- }
3592
- if (char === '"' && !inSingle) {
3593
- inDouble = !inDouble;
3594
- current += char;
3595
- continue;
3596
- }
3597
- if (!inSingle && !inDouble && char === "&" && command.charAt(index + 1) === "&") {
3598
- if (current.trim()) {
3599
- segments.push(current.trim());
3600
- }
3601
- current = "";
3602
- index += 1;
3603
- continue;
3604
- }
3605
- current += char;
3606
- }
3607
- if (current.trim()) {
3608
- segments.push(current.trim());
3609
- }
3610
- return segments.length > 0 ? segments : [command];
3611
- }
3612
- function joinWithAndSemantics(segments) {
3613
- if (segments.length <= 1) {
3614
- return segments[0] ?? "";
3615
- }
3616
- let script = segments[0] ?? "";
3617
- for (let index = 1; index < segments.length; index += 1) {
3618
- const segment = segments[index];
3619
- script += `; if ($?) { ${segment} }`;
3620
- }
3621
- return script;
3622
- }
3623
- function splitArgs(command) {
3624
- const args = [];
3625
- let current = "";
3626
- let inSingle = false;
3627
- let inDouble = false;
3628
- for (let index = 0; index < command.length; index += 1) {
3629
- const char = command.charAt(index);
3630
- if (char === "'" && !inDouble) {
3631
- inSingle = !inSingle;
3632
- continue;
3633
- }
3634
- if (char === '"' && !inSingle) {
3635
- inDouble = !inDouble;
3636
- continue;
3637
- }
3638
- if (!inSingle && !inDouble && /\s/.test(char)) {
3639
- if (current) {
3640
- args.push(current);
3641
- current = "";
3642
- }
3643
- continue;
3644
- }
3645
- current += char;
3646
- }
3647
- if (current) {
3648
- args.push(current);
3649
- }
3650
- return args;
3651
- }
3652
- function expandPaths(paths) {
3653
- return paths.flatMap((targetPath) => expandBraces(targetPath));
3654
- }
3655
- function normalizeWindowsPath(value) {
3656
- if (value.includes("://")) {
3657
- return value;
3658
- }
3659
- return value.replace(/\//g, "\\");
3660
- }
3661
- function quotePowerShell(value) {
3662
- const escaped = value.replace(/'/g, "''");
3663
- return `'${escaped}'`;
3664
- }
3665
- function expandBraces(input) {
3666
- const start = findBraceStart(input);
3667
- if (start === -1) {
3668
- return [input];
3669
- }
3670
- const end = findMatchingBrace(input, start);
3671
- if (end === -1) {
3672
- return [input];
3673
- }
3674
- const prefix = input.slice(0, start);
3675
- const suffix = input.slice(end + 1);
3676
- const body = input.slice(start + 1, end);
3677
- const parts = splitBraceParts(body);
3678
- const expandedSuffix = expandBraces(suffix);
3679
- const results = [];
3680
- for (const part of parts) {
3681
- for (const expandedPart of expandBraces(part)) {
3682
- for (const tail of expandedSuffix) {
3683
- results.push(`${prefix}${expandedPart}${tail}`);
3684
- }
3685
- }
3686
- }
3687
- return results;
3688
- }
3689
- function findBraceStart(input) {
3690
- let inSingle = false;
3691
- let inDouble = false;
3692
- for (let index = 0; index < input.length; index += 1) {
3693
- const char = input.charAt(index);
3694
- if (char === "'" && !inDouble) {
3695
- inSingle = !inSingle;
3696
- continue;
3697
- }
3698
- if (char === '"' && !inSingle) {
3699
- inDouble = !inDouble;
3700
- continue;
3701
- }
3702
- if (!inSingle && !inDouble && char === "{") {
3703
- return index;
3704
- }
3705
- }
3706
- return -1;
3707
- }
3708
- function findMatchingBrace(input, start) {
3709
- let depth = 0;
3710
- let inSingle = false;
3711
- let inDouble = false;
3712
- for (let index = start; index < input.length; index += 1) {
3713
- const char = input.charAt(index);
3714
- if (char === "'" && !inDouble) {
3715
- inSingle = !inSingle;
3716
- continue;
3717
- }
3718
- if (char === '"' && !inSingle) {
3719
- inDouble = !inDouble;
3720
- continue;
3721
- }
3722
- if (inSingle || inDouble) {
3723
- continue;
3724
- }
3725
- if (char === "{") {
3726
- depth += 1;
3727
- } else if (char === "}") {
3728
- depth -= 1;
3729
- if (depth === 0) {
3730
- return index;
3731
- }
3732
- }
3733
- }
3734
- return -1;
3735
- }
3736
- function splitBraceParts(input) {
3737
- const parts = [];
3738
- let current = "";
3739
- let depth = 0;
3740
- for (let index = 0; index < input.length; index += 1) {
3741
- const char = input.charAt(index);
3742
- if (char === "{") {
3743
- depth += 1;
3744
- current += char;
3745
- continue;
3746
- }
3747
- if (char === "}") {
3748
- depth -= 1;
3749
- current += char;
3750
- continue;
3751
- }
3752
- if (char === "," && depth === 0) {
3753
- parts.push(current);
3754
- current = "";
3755
- continue;
3756
- }
3757
- current += char;
3758
- }
3759
- if (current) {
3760
- parts.push(current);
3761
- }
3762
- return parts.length > 0 ? parts : [input];
3763
- }
3764
-
3765
- // src/utils/commandRunner/platformTransforms.ts
3766
- function startsWithExplicitShell(command) {
3767
- return /^\s*(cmd(?:\.exe)?\s+\/c|powershell(?:\.exe)?\b|pwsh\b|bash\b)/i.test(command);
3768
- }
3769
- function normalizeWindowsSegment(segment) {
3770
- const trimmed = segment.trim();
3771
- if (!trimmed) {
3772
- return segment;
3773
- }
3774
- const lowered = trimmed.toLowerCase();
3775
- if (lowered.startsWith("get-childitem") || lowered.startsWith("new-item")) {
3776
- return segment;
3777
- }
3778
- if (lowered.startsWith("ls")) {
3779
- return normalizeLsSegment(trimmed);
3780
- }
3781
- if (lowered.startsWith("mkdir") || lowered.startsWith("md ")) {
3782
- return normalizeMkdirSegment(trimmed);
3783
- }
3784
- if (lowered.startsWith("rm ")) {
3785
- return normalizeRemoveSegment(trimmed);
3786
- }
3787
- if (lowered.startsWith("cp ")) {
3788
- return normalizeCopySegment(trimmed);
3789
- }
3790
- if (lowered.startsWith("mv ")) {
3791
- return normalizeMoveSegment(trimmed);
3792
- }
3793
- if (lowered.startsWith("touch ")) {
3794
- return normalizeTouchSegment(trimmed);
3587
+ // src/utils/commandRunner/output.ts
3588
+ function normalizeCommandOutput(output) {
3589
+ if (!output.includes("#< CLIXML")) {
3590
+ return output;
3795
3591
  }
3796
- if (lowered.startsWith("cat ")) {
3797
- return normalizeCatSegment(trimmed);
3592
+ const errors = [...output.matchAll(/<S\s+S="Error">([\s\S]*?)<\/S>/g)].map((match) => decodePowerShellText(match[1] ?? "")).map((line) => line.trimEnd()).filter(Boolean);
3593
+ if (errors.length === 0) {
3594
+ return output;
3798
3595
  }
3799
- return segment;
3596
+ return errors.join("\n").replace(/\n{3,}/g, "\n\n").trim();
3800
3597
  }
3801
- function normalizeLsSegment(segment) {
3802
- const args = splitArgs(segment).slice(1);
3803
- const flags = args.filter((arg) => arg.startsWith("-"));
3804
- const paths = args.filter((arg) => !arg.startsWith("-"));
3805
- const force = flags.some((flag) => flag.includes("a"));
3806
- const targetPath = paths[0];
3807
- let command = "Get-ChildItem";
3808
- if (force) {
3809
- command += " -Force";
3810
- }
3811
- if (targetPath) {
3812
- command += ` -LiteralPath ${quotePowerShell(normalizeWindowsPath(targetPath))}`;
3813
- }
3814
- return command;
3815
- }
3816
- function normalizeMkdirSegment(segment) {
3817
- const args = splitArgs(segment);
3818
- if (args.length <= 1) {
3819
- return segment;
3820
- }
3821
- const rest = args.slice(1);
3822
- let hasParents = false;
3823
- const paths = rest.filter((arg) => {
3824
- const lowered = arg.toLowerCase();
3825
- if (lowered === "-p" || lowered === "--parents") {
3826
- hasParents = true;
3827
- return false;
3828
- }
3829
- return true;
3830
- });
3831
- const needsNormalization = hasParents || paths.some((targetPath) => targetPath.includes("{"));
3832
- if (!needsNormalization) {
3833
- return segment;
3834
- }
3835
- const expanded = expandPaths(paths);
3836
- if (expanded.length === 0) {
3837
- return segment;
3838
- }
3839
- const normalizedPaths = expanded.map((targetPath) => quotePowerShell(normalizeWindowsPath(targetPath)));
3840
- return `New-Item -ItemType Directory -Force -Path ${normalizedPaths.join(", ")}`;
3841
- }
3842
- function normalizeRemoveSegment(segment) {
3843
- const args = splitArgs(segment);
3844
- if (args.length <= 1) {
3845
- return segment;
3846
- }
3847
- const flags = args.slice(1).filter((arg) => arg.startsWith("-"));
3848
- const paths = args.slice(1).filter((arg) => !arg.startsWith("-"));
3849
- if (paths.length === 0) {
3850
- return segment;
3851
- }
3852
- const recurse = flags.some((flag) => /r/i.test(flag));
3853
- const force = flags.some((flag) => /f/i.test(flag));
3854
- let command = "Remove-Item";
3855
- if (recurse) {
3856
- command += " -Recurse";
3857
- }
3858
- if (force) {
3859
- command += " -Force";
3860
- }
3861
- command += ` -LiteralPath ${paths.map((targetPath) => quotePowerShell(normalizeWindowsPath(targetPath))).join(", ")}`;
3862
- return command;
3863
- }
3864
- function normalizeCopySegment(segment) {
3865
- const args = splitArgs(segment);
3866
- if (args.length < 3) {
3867
- return segment;
3868
- }
3869
- const flags = args.slice(1).filter((arg) => arg.startsWith("-"));
3870
- const paths = args.slice(1).filter((arg) => !arg.startsWith("-"));
3871
- if (paths.length < 2) {
3872
- return segment;
3873
- }
3874
- const recurse = flags.some((flag) => /r/i.test(flag));
3875
- const force = flags.some((flag) => /f/i.test(flag));
3876
- const destination = paths[paths.length - 1];
3877
- if (!destination) {
3878
- return segment;
3879
- }
3880
- const sources = paths.slice(0, -1);
3881
- let command = "Copy-Item";
3882
- if (recurse) {
3883
- command += " -Recurse";
3884
- }
3885
- if (force) {
3886
- command += " -Force";
3887
- }
3888
- command += ` -Path ${sources.map((targetPath) => quotePowerShell(normalizeWindowsPath(targetPath))).join(", ")}`;
3889
- command += ` -Destination ${quotePowerShell(normalizeWindowsPath(destination))}`;
3890
- return command;
3891
- }
3892
- function normalizeMoveSegment(segment) {
3893
- const args = splitArgs(segment);
3894
- if (args.length < 3) {
3895
- return segment;
3896
- }
3897
- const flags = args.slice(1).filter((arg) => arg.startsWith("-"));
3898
- const paths = args.slice(1).filter((arg) => !arg.startsWith("-"));
3899
- if (paths.length < 2) {
3900
- return segment;
3901
- }
3902
- const force = flags.some((flag) => /f/i.test(flag));
3903
- const destination = paths[paths.length - 1];
3904
- if (!destination) {
3905
- return segment;
3906
- }
3907
- const sources = paths.slice(0, -1);
3908
- let command = "Move-Item";
3909
- if (force) {
3910
- command += " -Force";
3911
- }
3912
- command += ` -Path ${sources.map((targetPath) => quotePowerShell(normalizeWindowsPath(targetPath))).join(", ")}`;
3913
- command += ` -Destination ${quotePowerShell(normalizeWindowsPath(destination))}`;
3914
- return command;
3915
- }
3916
- function normalizeTouchSegment(segment) {
3917
- const args = splitArgs(segment).slice(1);
3918
- if (args.length === 0) {
3919
- return segment;
3920
- }
3921
- const expanded = expandPaths(args);
3922
- if (expanded.length === 0) {
3923
- return segment;
3924
- }
3925
- const paths = expanded.map((targetPath) => quotePowerShell(normalizeWindowsPath(targetPath)));
3926
- return `New-Item -ItemType File -Force -Path ${paths.join(", ")}`;
3927
- }
3928
- function normalizeCatSegment(segment) {
3929
- const args = splitArgs(segment).slice(1);
3930
- if (args.length === 0) {
3931
- return segment;
3932
- }
3933
- const targetPath = args[0];
3934
- if (!targetPath) {
3935
- return segment;
3936
- }
3937
- return `Get-Content -LiteralPath ${quotePowerShell(normalizeWindowsPath(targetPath))}`;
3938
- }
3939
-
3940
- // src/utils/commandRunner/platform.ts
3941
- function normalizeCommandForPlatform(command) {
3942
- if (process.platform !== "win32") {
3943
- return command;
3944
- }
3945
- const trimmed = command.trim();
3946
- if (!trimmed) {
3947
- return command;
3948
- }
3949
- const normalized = normalizeWindowsCommand(trimmed);
3950
- return normalizeNpmCommandNames(normalized);
3951
- }
3952
- function normalizeWindowsCommand(command) {
3953
- if (startsWithExplicitShell(command)) {
3954
- return command;
3955
- }
3956
- const segments = splitByAndAnd(command);
3957
- const normalizedSegments = segments.map((segment) => normalizeWindowsSegment(segment));
3958
- return joinWithAndSemantics(normalizedSegments);
3959
- }
3960
- function normalizeNpmCommandNames(command) {
3961
- const commandNames = {
3962
- npm: "npm.cmd",
3963
- npx: "npx.cmd",
3964
- pnpm: "pnpm.cmd",
3965
- yarn: "yarn.cmd"
3966
- };
3967
- const pattern = /(^|[;&|]|\&\&)\s*(npm|npx|pnpm|yarn)(?=\s|$)/gi;
3968
- return command.replace(pattern, (match, prefix, tool) => {
3969
- const replacement = commandNames[String(tool).toLowerCase()];
3970
- if (!replacement) {
3971
- return match;
3972
- }
3973
- if (!prefix) {
3974
- return replacement;
3975
- }
3976
- return `${prefix} ${replacement}`;
3977
- });
3598
+ function decodePowerShellText(value) {
3599
+ return value.replace(/_x000D__x000A_/g, "\n").replace(/_x000D_/g, "\r").replace(/_x000A_/g, "\n").replace(/_x0009_/g, " ").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&apos;/g, "'").replace(/&amp;/g, "&");
3978
3600
  }
3979
3601
 
3980
3602
  // src/utils/commandRunner/run.ts
3981
3603
  var STALL_KILL_TIMEOUT_MS = 5e3;
3982
3604
  async function runCommandWithPolicy(options) {
3983
- const normalizedCommand = normalizeCommandForPlatform(options.command);
3984
- return runCommandOnce({
3985
- ...options,
3986
- command: normalizedCommand
3987
- });
3605
+ return runCommandOnce(options);
3988
3606
  }
3989
3607
  async function runCommandOnce(options) {
3990
3608
  const start = Date.now();
3991
3609
  let stalled = false;
3992
3610
  let stallTimer = null;
3993
3611
  let forceKillTimer = null;
3994
- const { subprocess } = await launchCommand(options.command, options.cwd, options.timeoutMs, options.abortSignal);
3612
+ const launched = await launchCommand(options.command, options.cwd, options.timeoutMs, options.abortSignal);
3613
+ const { subprocess } = launched;
3995
3614
  const outputCapture = await createBashOutputCapture(options.outputCapture ?? {});
3996
3615
  const clearTimers = () => {
3997
3616
  if (stallTimer) {
@@ -4044,9 +3663,11 @@ async function runCommandOnce(options) {
4044
3663
  const result = await subprocess;
4045
3664
  clearTimers();
4046
3665
  const shellOutput = await outputCapture.finalize();
3666
+ const output = normalizeCommandOutput(shellOutput.outputPreview);
4047
3667
  return {
3668
+ command: options.command,
4048
3669
  exitCode: typeof result.exitCode === "number" ? result.exitCode : null,
4049
- output: shellOutput.outputPreview,
3670
+ output,
4050
3671
  outputPath: shellOutput.outputPath,
4051
3672
  truncated: shellOutput.truncated,
4052
3673
  outputChars: shellOutput.outputChars,
@@ -4061,9 +3682,12 @@ async function runCommandOnce(options) {
4061
3682
  const timedOut = isTimedOutError(error);
4062
3683
  clearTimers();
4063
3684
  const shellOutput = await outputCapture.finalize();
3685
+ const fallbackOutput = shellOutput.outputChars > 0 ? shellOutput.outputPreview : readProcessOutput(error);
3686
+ const output = normalizeCommandOutput(fallbackOutput);
4064
3687
  return {
3688
+ command: options.command,
4065
3689
  exitCode: readExitCode(error),
4066
- output: shellOutput.outputChars > 0 ? shellOutput.outputPreview : readProcessOutput(error),
3690
+ output,
4067
3691
  outputPath: shellOutput.outputPath,
4068
3692
  truncated: shellOutput.truncated,
4069
3693
  outputChars: shellOutput.outputChars,
@@ -4624,7 +4248,7 @@ var bashToolDefinition = {
4624
4248
  const status = result.aborted ? "aborted" : result.stalled ? "stalled" : result.timedOut ? "timed_out" : result.exitCode === 0 ? "completed" : "failed";
4625
4249
  const outputGovernance = governToolOutput({
4626
4250
  toolName: "bash",
4627
- command,
4251
+ command: result.command,
4628
4252
  status,
4629
4253
  exitCode: result.exitCode,
4630
4254
  durationMs: result.durationMs,
@@ -4652,7 +4276,7 @@ var bashToolDefinition = {
4652
4276
  return okResult(
4653
4277
  JSON.stringify(
4654
4278
  {
4655
- command,
4279
+ command: result.command,
4656
4280
  cwd: resolvedCwd,
4657
4281
  exitCode: result.exitCode,
4658
4282
  status,
@@ -6099,6 +5723,53 @@ async function executeToolBatch(params) {
6099
5723
  };
6100
5724
  }
6101
5725
 
5726
+ // src/session/events.ts
5727
+ import fs15 from "fs/promises";
5728
+ import path15 from "path";
5729
+ var SessionEventStore = class {
5730
+ constructor(eventsDir) {
5731
+ this.eventsDir = eventsDir;
5732
+ }
5733
+ async append(event) {
5734
+ const record = {
5735
+ id: createEventId(),
5736
+ createdAt: event.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
5737
+ type: event.type,
5738
+ sessionId: event.sessionId,
5739
+ cwd: event.cwd,
5740
+ host: event.host,
5741
+ message: event.message,
5742
+ details: event.details
5743
+ };
5744
+ await fs15.mkdir(this.eventsDir, { recursive: true });
5745
+ await fs15.appendFile(this.getSessionEventPath(event.sessionId), `${JSON.stringify(record)}
5746
+ `, "utf8");
5747
+ return record;
5748
+ }
5749
+ async list(sessionId, limit = 100) {
5750
+ const filePath = this.getSessionEventPath(sessionId);
5751
+ let raw = "";
5752
+ try {
5753
+ raw = await fs15.readFile(filePath, "utf8");
5754
+ } catch (error) {
5755
+ if (error.code === "ENOENT") {
5756
+ return [];
5757
+ }
5758
+ throw error;
5759
+ }
5760
+ return raw.split(/\r?\n/).filter(Boolean).map((line) => JSON.parse(line)).slice(-limit);
5761
+ }
5762
+ getSessionEventPath(sessionId) {
5763
+ return path15.join(this.eventsDir, `${sanitizeSessionId(sessionId)}.jsonl`);
5764
+ }
5765
+ };
5766
+ function createEventId() {
5767
+ return `${(/* @__PURE__ */ new Date()).toISOString().replace(/[-:.TZ]/g, "").slice(0, 14)}-${Math.random().toString(16).slice(2, 10)}`;
5768
+ }
5769
+ function sanitizeSessionId(sessionId) {
5770
+ return sessionId.replace(/[^a-zA-Z0-9_.-]/g, "_");
5771
+ }
5772
+
6102
5773
  // src/agent/turn/toolFailure.ts
6103
5774
  function readToolFailureError(output) {
6104
5775
  try {
@@ -6134,9 +5805,16 @@ async function processToolCallBatch(input) {
6134
5805
  const batchToolMessages = [];
6135
5806
  const batchModelOutputs = [];
6136
5807
  const batchChangedPaths = /* @__PURE__ */ new Set();
5808
+ const sessionEvents = new SessionEventStore(options.config.paths.eventsDir);
6137
5809
  const leadWaitExecutionsBefore = identity.kind === "lead" ? listLeadWaitExecutions(projectContext.stateRootDir) : [];
6138
5810
  for (const toolCall of response.toolCalls) {
6139
5811
  throwIfAborted(options.abortSignal, "Turn aborted by user.");
5812
+ await sessionEvents.append({
5813
+ type: "tool.started",
5814
+ sessionId: session.id,
5815
+ cwd: options.cwd,
5816
+ details: buildToolStartedEventDetails(toolCall, identity)
5817
+ });
6140
5818
  options.callbacks?.onToolCall?.(toolCall.function.name, toolCall.function.arguments);
6141
5819
  await recordObservabilityEvent(projectContext.stateRootDir, {
6142
5820
  event: "tool.execution",
@@ -6170,6 +5848,7 @@ async function processToolCallBatch(input) {
6170
5848
  } else if (metadata?.sessionDiff) {
6171
5849
  session = await options.sessionStore.save(noteSessionDiff(session, metadata.sessionDiff));
6172
5850
  }
5851
+ const failureError = result.ok ? void 0 : readToolFailureError(result.output);
6173
5852
  await recordObservabilityEvent(projectContext.stateRootDir, {
6174
5853
  event: "tool.execution",
6175
5854
  status: result.ok ? "completed" : "failed",
@@ -6178,11 +5857,23 @@ async function processToolCallBatch(input) {
6178
5857
  identityName: identity.name,
6179
5858
  toolName: toolCall.function.name,
6180
5859
  durationMs,
6181
- error: result.ok ? void 0 : readToolFailureError(result.output),
5860
+ error: failureError,
6182
5861
  details: {
6183
5862
  changedPathCount: metadata?.changedPaths?.length ?? 0
6184
5863
  }
6185
5864
  });
5865
+ await sessionEvents.append({
5866
+ type: result.ok ? "tool.completed" : "tool.failed",
5867
+ sessionId: session.id,
5868
+ cwd: options.cwd,
5869
+ details: buildToolFinishedEventDetails({
5870
+ toolCall,
5871
+ identity,
5872
+ durationMs,
5873
+ changedPathCount: metadata?.changedPaths?.length ?? 0,
5874
+ error: failureError ? formatToolFailureError(failureError) : void 0
5875
+ })
5876
+ });
6186
5877
  if (metadata?.outputGovernance) {
6187
5878
  await recordObservabilityEvent(projectContext.stateRootDir, {
6188
5879
  event: "tool.output",
@@ -6276,6 +5967,33 @@ async function processToolCallBatch(input) {
6276
5967
  }
6277
5968
  };
6278
5969
  }
5970
+ function buildToolStartedEventDetails(toolCall, identity) {
5971
+ return {
5972
+ toolName: toolCall.function.name,
5973
+ toolCallId: toolCall.id,
5974
+ identityKind: identity.kind,
5975
+ identityName: identity.name,
5976
+ argumentsPreview: previewToolArguments(toolCall.function.arguments)
5977
+ };
5978
+ }
5979
+ function buildToolFinishedEventDetails(input) {
5980
+ return {
5981
+ toolName: input.toolCall.function.name,
5982
+ toolCallId: input.toolCall.id,
5983
+ identityKind: input.identity.kind,
5984
+ identityName: input.identity.name,
5985
+ durationMs: input.durationMs,
5986
+ changedPathCount: input.changedPathCount,
5987
+ error: input.error
5988
+ };
5989
+ }
5990
+ function previewToolArguments(rawArgs) {
5991
+ const normalized = rawArgs.replace(/\s+/g, " ").trim();
5992
+ return normalized.length > 240 ? `${normalized.slice(0, 237)}...` : normalized;
5993
+ }
5994
+ function formatToolFailureError(error) {
5995
+ return error.code ? `${error.code}: ${error.message}` : error.message;
5996
+ }
6279
5997
 
6280
5998
  // src/agent/turn/toolless.ts
6281
5999
  async function resolveToollessTurn(params) {
@@ -6362,8 +6080,8 @@ function normalizeToolArguments(raw) {
6362
6080
 
6363
6081
  // src/agent/changes/store.ts
6364
6082
  import crypto2 from "crypto";
6365
- import fs15 from "fs/promises";
6366
- import path15 from "path";
6083
+ import fs16 from "fs/promises";
6084
+ import path16 from "path";
6367
6085
  var ChangeStore = class {
6368
6086
  constructor(changesDir) {
6369
6087
  this.changesDir = changesDir;
@@ -6371,8 +6089,8 @@ var ChangeStore = class {
6371
6089
  async record(input) {
6372
6090
  const id = createChangeId();
6373
6091
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
6374
- const blobDir = path15.join(this.changesDir, id);
6375
- await fs15.mkdir(blobDir, { recursive: true });
6092
+ const blobDir = path16.join(this.changesDir, id);
6093
+ await fs16.mkdir(blobDir, { recursive: true });
6376
6094
  const operations = await Promise.all(
6377
6095
  input.operations.map(async (operation, index) => {
6378
6096
  const beforeSnapshotPath = await this.writeSnapshot(
@@ -6412,21 +6130,21 @@ var ChangeStore = class {
6412
6130
  preview: input.preview,
6413
6131
  operations
6414
6132
  };
6415
- await fs15.mkdir(this.changesDir, { recursive: true });
6416
- await fs15.writeFile(this.getMetadataPath(id), `${JSON.stringify(record, null, 2)}
6133
+ await fs16.mkdir(this.changesDir, { recursive: true });
6134
+ await fs16.writeFile(this.getMetadataPath(id), `${JSON.stringify(record, null, 2)}
6417
6135
  `, "utf8");
6418
6136
  return record;
6419
6137
  }
6420
6138
  async list(limit = 20) {
6421
- await fs15.mkdir(this.changesDir, { recursive: true });
6422
- const entries = await fs15.readdir(this.changesDir, { withFileTypes: true });
6139
+ await fs16.mkdir(this.changesDir, { recursive: true });
6140
+ const entries = await fs16.readdir(this.changesDir, { withFileTypes: true });
6423
6141
  const changes = await Promise.all(
6424
- entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map(async (entry) => this.load(path15.basename(entry.name, ".json")))
6142
+ entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map(async (entry) => this.load(path16.basename(entry.name, ".json")))
6425
6143
  );
6426
6144
  return changes.sort((left, right) => right.createdAt.localeCompare(left.createdAt)).slice(0, limit);
6427
6145
  }
6428
6146
  async load(id) {
6429
- const raw = await fs15.readFile(this.getMetadataPath(id), "utf8");
6147
+ const raw = await fs16.readFile(this.getMetadataPath(id), "utf8");
6430
6148
  return JSON.parse(raw);
6431
6149
  }
6432
6150
  async loadLatestUndoable() {
@@ -6450,17 +6168,17 @@ var ChangeStore = class {
6450
6168
  restoredPaths.push(operation.path);
6451
6169
  if (operation.beforeSnapshotPath) {
6452
6170
  const buffer = await this.readSnapshot(operation.beforeSnapshotPath);
6453
- await fs15.mkdir(path15.dirname(operation.path), { recursive: true });
6454
- await fs15.writeFile(operation.path, buffer);
6171
+ await fs16.mkdir(path16.dirname(operation.path), { recursive: true });
6172
+ await fs16.writeFile(operation.path, buffer);
6455
6173
  continue;
6456
6174
  }
6457
- await fs15.rm(operation.path, { force: true });
6175
+ await fs16.rm(operation.path, { force: true });
6458
6176
  }
6459
6177
  const updated = {
6460
6178
  ...record,
6461
6179
  undoneAt: (/* @__PURE__ */ new Date()).toISOString()
6462
6180
  };
6463
- await fs15.writeFile(this.getMetadataPath(updated.id), `${JSON.stringify(updated, null, 2)}
6181
+ await fs16.writeFile(this.getMetadataPath(updated.id), `${JSON.stringify(updated, null, 2)}
6464
6182
  `, "utf8");
6465
6183
  return {
6466
6184
  record: updated,
@@ -6468,19 +6186,19 @@ var ChangeStore = class {
6468
6186
  };
6469
6187
  }
6470
6188
  getMetadataPath(id) {
6471
- return path15.join(this.changesDir, `${id}.json`);
6189
+ return path16.join(this.changesDir, `${id}.json`);
6472
6190
  }
6473
6191
  async writeSnapshot(blobDir, label, buffer) {
6474
6192
  if (!buffer) {
6475
6193
  return void 0;
6476
6194
  }
6477
6195
  const fileName = `${label}.bin`;
6478
- const absolutePath = path15.join(blobDir, fileName);
6479
- await fs15.writeFile(absolutePath, buffer);
6480
- return path15.relative(this.changesDir, absolutePath);
6196
+ const absolutePath = path16.join(blobDir, fileName);
6197
+ await fs16.writeFile(absolutePath, buffer);
6198
+ return path16.relative(this.changesDir, absolutePath);
6481
6199
  }
6482
6200
  async readSnapshot(relativePath) {
6483
- return fs15.readFile(path15.join(this.changesDir, relativePath));
6201
+ return fs16.readFile(path16.join(this.changesDir, relativePath));
6484
6202
  }
6485
6203
  };
6486
6204
  function createChangeId() {
@@ -6866,9 +6584,10 @@ var backgroundRunTool = {
6866
6584
  registerBackgroundProcess(job.id, subprocess);
6867
6585
  store.markRunning(job.id, { pid: subprocess.pid ?? 0 });
6868
6586
  const outputTracker = createBackgroundOutputTracker((output) => {
6587
+ const normalizedOutput = normalizeCommandOutput(output);
6869
6588
  store.updateRunningOutput(job.id, {
6870
- output,
6871
- summary: summarizeBackgroundOutput(output),
6589
+ output: normalizedOutput,
6590
+ summary: summarizeBackgroundOutput(normalizedOutput),
6872
6591
  lastOutputAt: (/* @__PURE__ */ new Date()).toISOString()
6873
6592
  });
6874
6593
  });
@@ -6878,7 +6597,7 @@ var backgroundRunTool = {
6878
6597
  void subprocess.then(async (result) => {
6879
6598
  outputTracker.flush();
6880
6599
  const running2 = store.load(job.id);
6881
- const resultOutput = typeof result.all === "string" ? result.all : "";
6600
+ const resultOutput = normalizeCommandOutput(typeof result.all === "string" ? result.all : "");
6882
6601
  const output = resultOutput || running2?.output || "";
6883
6602
  store.close(job.id, {
6884
6603
  status: result.exitCode === 0 ? "completed" : "failed",
@@ -6890,7 +6609,7 @@ var backgroundRunTool = {
6890
6609
  }, async (error) => {
6891
6610
  outputTracker.flush();
6892
6611
  const running2 = store.load(job.id);
6893
- const errorOutput = typeof error.all === "string" ? error.all : "";
6612
+ const errorOutput = normalizeCommandOutput(typeof error.all === "string" ? error.all : "");
6894
6613
  const output = errorOutput || running2?.output || String(error.message);
6895
6614
  store.close(job.id, {
6896
6615
  status: "failed",
@@ -7058,20 +6777,20 @@ function createBackgroundTools() {
7058
6777
  }
7059
6778
 
7060
6779
  // src/extensions/tools/network/tools/downloadUrl.ts
7061
- import fs17 from "fs/promises";
6780
+ import fs18 from "fs/promises";
7062
6781
 
7063
6782
  // src/extensions/shared.ts
7064
- import fs16 from "fs/promises";
7065
- import path16 from "path";
6783
+ import fs17 from "fs/promises";
6784
+ import path17 from "path";
7066
6785
  async function ensureExtensionDir(rootDir, extensionId) {
7067
6786
  const paths = await ensureProjectStateDirectories(rootDir);
7068
- const dir = path16.join(paths.extensionsDir, extensionId);
7069
- await fs16.mkdir(dir, { recursive: true });
6787
+ const dir = path17.join(paths.extensionsDir, extensionId);
6788
+ await fs17.mkdir(dir, { recursive: true });
7070
6789
  return dir;
7071
6790
  }
7072
6791
  async function readJsonFile(filePath, fallback) {
7073
6792
  try {
7074
- return JSON.parse(await fs16.readFile(filePath, "utf8"));
6793
+ return JSON.parse(await fs17.readFile(filePath, "utf8"));
7075
6794
  } catch (error) {
7076
6795
  if (error.code === "ENOENT") {
7077
6796
  return fallback;
@@ -7080,8 +6799,8 @@ async function readJsonFile(filePath, fallback) {
7080
6799
  }
7081
6800
  }
7082
6801
  async function writeJsonFile(filePath, value) {
7083
- await fs16.mkdir(path16.dirname(filePath), { recursive: true });
7084
- await fs16.writeFile(filePath, `${JSON.stringify(value, null, 2)}
6802
+ await fs17.mkdir(path17.dirname(filePath), { recursive: true });
6803
+ await fs17.writeFile(filePath, `${JSON.stringify(value, null, 2)}
7085
6804
  `, "utf8");
7086
6805
  }
7087
6806
  function jsonResult(value) {
@@ -7097,7 +6816,7 @@ function sanitizeStateSegment(value) {
7097
6816
  }
7098
6817
 
7099
6818
  // src/extensions/tools/network/session.ts
7100
- import path17 from "path";
6819
+ import path18 from "path";
7101
6820
  async function listHttpSessions(rootDir) {
7102
6821
  const state = await readJsonFile(await sessionFile(rootDir), { sessions: [] });
7103
6822
  return Array.isArray(state.sessions) ? state.sessions.map(normalizeSession) : [];
@@ -7122,7 +6841,7 @@ async function getHttpSessionStateFile(rootDir) {
7122
6841
  return sessionFile(rootDir);
7123
6842
  }
7124
6843
  async function sessionFile(rootDir) {
7125
- return path17.join(await ensureExtensionDir(rootDir, "network"), "http-sessions.json");
6844
+ return path18.join(await ensureExtensionDir(rootDir, "network"), "http-sessions.json");
7126
6845
  }
7127
6846
  function normalizeSession(value) {
7128
6847
  return {
@@ -7351,7 +7070,7 @@ var downloadUrlTool = {
7351
7070
  }
7352
7071
  const bytes = Buffer.from(await response.arrayBuffer());
7353
7072
  await ensureParentDirectory(targetPath);
7354
- await fs17.writeFile(targetPath, bytes);
7073
+ await fs18.writeFile(targetPath, bytes);
7355
7074
  return changedJsonResult({
7356
7075
  ok: response.ok,
7357
7076
  url,
@@ -7416,17 +7135,17 @@ var httpProbeTool = {
7416
7135
  };
7417
7136
 
7418
7137
  // src/extensions/tools/network/traceStore.ts
7419
- import fs18 from "fs/promises";
7420
- import path18 from "path";
7138
+ import fs19 from "fs/promises";
7139
+ import path19 from "path";
7421
7140
  async function writeNetworkTrace(rootDir, traceId, record) {
7422
7141
  const filePath = await networkTraceFilePath(rootDir, traceId);
7423
- await fs18.mkdir(path18.dirname(filePath), { recursive: true });
7424
- await fs18.writeFile(filePath, `${JSON.stringify(record, null, 2)}
7142
+ await fs19.mkdir(path19.dirname(filePath), { recursive: true });
7143
+ await fs19.writeFile(filePath, `${JSON.stringify(record, null, 2)}
7425
7144
  `, "utf8");
7426
7145
  return filePath;
7427
7146
  }
7428
7147
  async function networkTraceFilePath(rootDir, traceId) {
7429
- return path18.join(await ensureExtensionDir(rootDir, "network"), "traces", `${sanitizeStateSegment(traceId)}.json`);
7148
+ return path19.join(await ensureExtensionDir(rootDir, "network"), "traces", `${sanitizeStateSegment(traceId)}.json`);
7430
7149
  }
7431
7150
 
7432
7151
  // src/extensions/tools/network/tools/httpRequest.ts
@@ -7826,14 +7545,14 @@ function readStringMap2(value) {
7826
7545
  }
7827
7546
 
7828
7547
  // src/extensions/tools/network/openapi.ts
7829
- import fs19 from "fs/promises";
7548
+ import fs20 from "fs/promises";
7830
7549
  async function loadOpenApiDocument(source, context) {
7831
7550
  const normalizedSource = source.trim();
7832
7551
  if (!normalizedSource) {
7833
7552
  throw new ToolExecutionError("OpenAPI source is required.", { code: "OPENAPI_SOURCE_INVALID" });
7834
7553
  }
7835
7554
  const resolvedSource = /^https?:\/\//i.test(normalizedSource) ? normalizedSource : resolveUserPath(normalizedSource, context.cwd);
7836
- const raw = /^https?:\/\//i.test(normalizedSource) ? await (await fetchWithTimeout(normalizedSource, { method: "GET" }, 2e4, context.abortSignal)).text() : stripBom(await fs19.readFile(resolvedSource, "utf8"));
7555
+ const raw = /^https?:\/\//i.test(normalizedSource) ? await (await fetchWithTimeout(normalizedSource, { method: "GET" }, 2e4, context.abortSignal)).text() : stripBom(await fs20.readFile(resolvedSource, "utf8"));
7837
7556
  const parsed = parseOpenApiDocument(raw, normalizedSource);
7838
7557
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
7839
7558
  throw new ToolExecutionError("OpenAPI document root must be an object.", { code: "OPENAPI_ROOT_INVALID" });
@@ -8181,8 +7900,8 @@ async function recordSkillUse(rootDir, input) {
8181
7900
  }
8182
7901
 
8183
7902
  // src/extensions/tools/skills/tools/skillReadResource.ts
8184
- import fs20 from "fs/promises";
8185
- import path19 from "path";
7903
+ import fs21 from "fs/promises";
7904
+ import path20 from "path";
8186
7905
  var MAX_RESOURCE_CHARS = 24e3;
8187
7906
  var skillReadResourceTool = {
8188
7907
  definition: {
@@ -8219,8 +7938,8 @@ var skillReadResourceTool = {
8219
7938
  if (!resource) {
8220
7939
  throw new Error(`Skill "${name}" does not declare resource: ${requestedPath}`);
8221
7940
  }
8222
- const absolutePath = path19.resolve(context.projectContext.rootDir, resource.path);
8223
- const content = await fs20.readFile(absolutePath, "utf8");
7941
+ const absolutePath = path20.resolve(context.projectContext.rootDir, resource.path);
7942
+ const content = await fs21.readFile(absolutePath, "utf8");
8224
7943
  return jsonResult({
8225
7944
  ok: true,
8226
7945
  skill: {
@@ -8238,7 +7957,7 @@ function normalizeResourcePath(value) {
8238
7957
  }
8239
7958
 
8240
7959
  // src/extensions/tools/skills/tools/skillRunScript.ts
8241
- import path20 from "path";
7960
+ import path21 from "path";
8242
7961
  var skillRunScriptTool = {
8243
7962
  definition: {
8244
7963
  type: "function",
@@ -8282,12 +8001,12 @@ var skillRunScriptTool = {
8282
8001
  if (!resource) {
8283
8002
  throw new Error(`Skill "${name}" does not declare script resource: ${requestedPath}`);
8284
8003
  }
8285
- const skillDir = path20.dirname(skill.path);
8286
- const relativeToSkill = normalizeResourcePath2(path20.relative(skillDir, resource.path));
8004
+ const skillDir = path21.dirname(skill.path);
8005
+ const relativeToSkill = normalizeResourcePath2(path21.relative(skillDir, resource.path));
8287
8006
  if (!relativeToSkill.startsWith("scripts/")) {
8288
8007
  throw new Error(`Skill "${name}" resource is not executable because it is outside scripts/: ${requestedPath}`);
8289
8008
  }
8290
- const scriptPath = path20.resolve(context.projectContext.rootDir, resource.path);
8009
+ const scriptPath = path21.resolve(context.projectContext.rootDir, resource.path);
8291
8010
  const argumentText = typeof args.args === "string" ? args.args.trim() : "";
8292
8011
  const command = buildScriptCommand(scriptPath, argumentText);
8293
8012
  const result = await runCommandWithPolicy({
@@ -8362,7 +8081,7 @@ function quotePath(value) {
8362
8081
  return `"${value.replace(/"/g, '\\"')}"`;
8363
8082
  }
8364
8083
  function buildScriptCommand(scriptPath, argumentText) {
8365
- const extension = path20.extname(scriptPath).toLowerCase();
8084
+ const extension = path21.extname(scriptPath).toLowerCase();
8366
8085
  const quoted = quotePath(scriptPath);
8367
8086
  const suffix = argumentText ? ` ${argumentText}` : "";
8368
8087
  if (extension === ".js" || extension === ".mjs" || extension === ".cjs") {
@@ -8416,12 +8135,12 @@ var subagentCheckTool = {
8416
8135
 
8417
8136
  // src/execution/launch.ts
8418
8137
  import { spawn } from "child_process";
8419
- import path21 from "path";
8138
+ import path22 from "path";
8420
8139
  function spawnExecutionWorker(input) {
8421
8140
  if (process.env.KITTY_TEST_WORKER_MODE === "stub") {
8422
8141
  return process.pid;
8423
8142
  }
8424
- const cliEntry = path21.resolve(process.argv[1] ?? "");
8143
+ const cliEntry = path22.resolve(process.argv[1] ?? "");
8425
8144
  if (!cliEntry) {
8426
8145
  throw new Error("Unable to locate Kitty CLI entrypoint for execution worker.");
8427
8146
  }
@@ -8627,7 +8346,7 @@ function parseWorktreeBlock(block) {
8627
8346
  }
8628
8347
 
8629
8348
  // src/extensions/tools/worktree/state.ts
8630
- import path22 from "path";
8349
+ import path23 from "path";
8631
8350
  async function readWorktreeState(rootDir) {
8632
8351
  return normalizeWorktreeState(await readJsonFile(await stateFile(rootDir), {
8633
8352
  schemaVersion: 1,
@@ -8650,7 +8369,7 @@ async function recordWorktreeEvent(rootDir, event) {
8650
8369
  return writeWorktreeState(rootDir, state);
8651
8370
  }
8652
8371
  async function stateFile(rootDir) {
8653
- return path22.join(await ensureExtensionDir(rootDir, "worktree"), "state.json");
8372
+ return path23.join(await ensureExtensionDir(rootDir, "worktree"), "state.json");
8654
8373
  }
8655
8374
  function normalizeWorktreeState(value) {
8656
8375
  return {
@@ -9273,8 +8992,8 @@ function looksLikeToolProtocolText(content) {
9273
8992
  }
9274
8993
 
9275
8994
  // src/observability/crashRecorder.ts
9276
- import fs21 from "fs";
9277
- import path23 from "path";
8995
+ import fs22 from "fs";
8996
+ import path24 from "path";
9278
8997
  var activeCrashContexts = /* @__PURE__ */ new Map();
9279
8998
  var nextCrashContextId = 0;
9280
8999
  function enterCrashContext(context) {
@@ -9286,7 +9005,7 @@ function enterCrashContext(context) {
9286
9005
  }
9287
9006
 
9288
9007
  // src/observability/hostEvents.ts
9289
- import path24 from "path";
9008
+ import path25 from "path";
9290
9009
  async function recordHostTurnStarted(rootDir, input) {
9291
9010
  await recordObservabilityEvent(rootDir, {
9292
9011
  event: "host.turn",
@@ -9317,53 +9036,6 @@ async function recordHostTurnFinished(rootDir, input) {
9317
9036
  });
9318
9037
  }
9319
9038
 
9320
- // src/session/events.ts
9321
- import fs22 from "fs/promises";
9322
- import path25 from "path";
9323
- var SessionEventStore = class {
9324
- constructor(eventsDir) {
9325
- this.eventsDir = eventsDir;
9326
- }
9327
- async append(event) {
9328
- const record = {
9329
- id: createEventId(),
9330
- createdAt: event.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
9331
- type: event.type,
9332
- sessionId: event.sessionId,
9333
- cwd: event.cwd,
9334
- host: event.host,
9335
- message: event.message,
9336
- details: event.details
9337
- };
9338
- await fs22.mkdir(this.eventsDir, { recursive: true });
9339
- await fs22.appendFile(this.getSessionEventPath(event.sessionId), `${JSON.stringify(record)}
9340
- `, "utf8");
9341
- return record;
9342
- }
9343
- async list(sessionId, limit = 100) {
9344
- const filePath = this.getSessionEventPath(sessionId);
9345
- let raw = "";
9346
- try {
9347
- raw = await fs22.readFile(filePath, "utf8");
9348
- } catch (error) {
9349
- if (error.code === "ENOENT") {
9350
- return [];
9351
- }
9352
- throw error;
9353
- }
9354
- return raw.split(/\r?\n/).filter(Boolean).map((line) => JSON.parse(line)).slice(-limit);
9355
- }
9356
- getSessionEventPath(sessionId) {
9357
- return path25.join(this.eventsDir, `${sanitizeSessionId(sessionId)}.jsonl`);
9358
- }
9359
- };
9360
- function createEventId() {
9361
- return `${(/* @__PURE__ */ new Date()).toISOString().replace(/[-:.TZ]/g, "").slice(0, 14)}-${Math.random().toString(16).slice(2, 10)}`;
9362
- }
9363
- function sanitizeSessionId(sessionId) {
9364
- return sessionId.replace(/[^a-zA-Z0-9_.-]/g, "_");
9365
- }
9366
-
9367
9039
  // src/host/toolRegistry.ts
9368
9040
  async function createHostToolRegistry(config, options = {}) {
9369
9041
  const extraTools = options.extraTools ?? [];
@@ -10292,6 +9964,7 @@ export {
10292
9964
  getErrorMessage,
10293
9965
  ControlPlaneLedger,
10294
9966
  ExecutionStore,
9967
+ SessionEventStore,
10295
9968
  isProcessAlive,
10296
9969
  terminatePid,
10297
9970
  BackgroundExecutionStore,
@@ -10300,12 +9973,14 @@ export {
10300
9973
  summarizeExecution,
10301
9974
  summarizeExecutionSet,
10302
9975
  EXTENSION_ENV_KEYS,
10303
- SessionEventStore,
10304
9976
  runHostTurn,
10305
9977
  writeStdout,
10306
9978
  writeStdoutLine,
10307
9979
  writeStderrLine,
10308
9980
  createRuntimeUiEvent,
9981
+ tryParseJson,
9982
+ buildToolCallDisplay,
9983
+ buildToolResultDisplay,
10309
9984
  colorRuntimeUiText,
10310
9985
  createRuntimeUiTerminalRenderer,
10311
9986
  formatRuntimeUiEventLine