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