@wrongstack/tools 1.0.0 → 1.0.1
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/auto-proceed-loop-guard.d.ts +1 -1
- package/dist/auto-proceed-loop-guard.js +1 -1
- package/dist/bash.js +1 -1
- package/dist/builtin.js +3 -3
- package/dist/{chunk-NN2SNP2R.js → chunk-6H4ERJP7.js} +137 -21
- package/dist/{chunk-YULVUTK5.js → chunk-7LQCT3LT.js} +3 -3
- package/dist/{chunk-M6UV67BH.js → chunk-E7JE3UEX.js} +2 -2
- package/dist/{chunk-AB2CAUOP.js → chunk-IAYMTTR2.js} +175 -29
- package/dist/{chunk-KDEXUQY7.js → chunk-MGPR7VG3.js} +261 -258
- package/dist/{chunk-37QKUQ2Z.js → chunk-NL2S2CXD.js} +1 -1
- package/dist/exec.js +1 -1
- package/dist/index.js +6 -6
- package/dist/pack.js +4 -4
- package/dist/tool-tier.js +5 -5
- package/package.json +5 -5
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* on every reply — which happens whenever the model's output is stable but
|
|
10
10
|
* autonomy treats the next step as "still actionable" — the loop self-feeds
|
|
11
11
|
* the same instruction 2–3 times in a row before the longer
|
|
12
|
-
* `autoProceedMaxIterations` cap (default
|
|
12
|
+
* `autoProceedMaxIterations` cap (default 0 = unlimited) trips.
|
|
13
13
|
*
|
|
14
14
|
* The user reports the visible symptom: the same response, including the same
|
|
15
15
|
* `<nextsteps>` block, repeats. Manual input from the user is the only thing
|
package/dist/bash.js
CHANGED
package/dist/builtin.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
TIER2_TOOLS,
|
|
7
7
|
TIER3_TOOLS,
|
|
8
8
|
builtinTools
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-IAYMTTR2.js";
|
|
10
10
|
import "./chunk-RV7BVTDG.js";
|
|
11
11
|
import "./chunk-YEISRT4S.js";
|
|
12
12
|
import "./chunk-XRNN44QY.js";
|
|
@@ -40,8 +40,8 @@ import "./chunk-ASEXQRA7.js";
|
|
|
40
40
|
import "./chunk-4ERMPDHV.js";
|
|
41
41
|
import "./chunk-YJTXRH5Y.js";
|
|
42
42
|
import "./chunk-ZBMANLYH.js";
|
|
43
|
-
import "./chunk-
|
|
44
|
-
import "./chunk-
|
|
43
|
+
import "./chunk-6H4ERJP7.js";
|
|
44
|
+
import "./chunk-MGPR7VG3.js";
|
|
45
45
|
import "./chunk-BTSFTGIL.js";
|
|
46
46
|
import "./chunk-PVCB7RUZ.js";
|
|
47
47
|
import "./chunk-SCMRM6NL.js";
|
|
@@ -627,17 +627,51 @@ var bashTool = {
|
|
|
627
627
|
const detached = !isWin2;
|
|
628
628
|
const startedAt = Date.now();
|
|
629
629
|
if (input.background) {
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
630
|
+
let child2;
|
|
631
|
+
try {
|
|
632
|
+
child2 = spawn(shell, args, {
|
|
633
|
+
cwd: spawnCwd,
|
|
634
|
+
env,
|
|
635
|
+
stdio: ["ignore", "ignore", "ignore"],
|
|
636
|
+
detached: !isWin2,
|
|
637
|
+
windowsHide: true
|
|
638
|
+
});
|
|
639
|
+
} catch (err) {
|
|
640
|
+
registry.afterCall(Date.now() - startedAt, true, bypassBreaker);
|
|
641
|
+
emitProcessStarted({
|
|
642
|
+
parentPid: process.pid,
|
|
643
|
+
command: redactCommand(`${shell} ${args.join(" ")}`),
|
|
644
|
+
args: redactCommand(args.join(" ")).split(" ").filter(Boolean),
|
|
645
|
+
cwd: spawnCwd,
|
|
646
|
+
background: true,
|
|
647
|
+
startedAt: new Date(startedAt).toISOString()
|
|
648
|
+
});
|
|
649
|
+
emitProcessCompleted({
|
|
650
|
+
exitCode: 1,
|
|
651
|
+
durationMs: Date.now() - startedAt,
|
|
652
|
+
stdoutBytes: 0,
|
|
653
|
+
stderrBytes: 0,
|
|
654
|
+
timedOut: false,
|
|
655
|
+
endedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
656
|
+
});
|
|
657
|
+
yield {
|
|
658
|
+
type: "final",
|
|
659
|
+
output: {
|
|
660
|
+
output: "",
|
|
661
|
+
exit_code: 1,
|
|
662
|
+
timed_out: false,
|
|
663
|
+
pid: null,
|
|
664
|
+
error: `spawn failed: ${err instanceof Error ? err.message : String(err)}`
|
|
665
|
+
}
|
|
666
|
+
};
|
|
667
|
+
return;
|
|
668
|
+
}
|
|
637
669
|
const pid2 = child2.pid;
|
|
638
670
|
const stdoutBytes2 = 0;
|
|
639
671
|
const stderrBytes2 = 0;
|
|
640
672
|
let telemetryCompleted2 = false;
|
|
673
|
+
let bgErrorOccurred = false;
|
|
674
|
+
let bgSettled = false;
|
|
641
675
|
emitProcessStarted({
|
|
642
676
|
...pid2 !== void 0 ? { pid: pid2 } : {},
|
|
643
677
|
parentPid: process.pid,
|
|
@@ -675,15 +709,33 @@ var bashTool = {
|
|
|
675
709
|
child2.on("close", () => registry.unregister(pid2));
|
|
676
710
|
}
|
|
677
711
|
child2.on("error", () => {
|
|
678
|
-
if (
|
|
712
|
+
if (bgSettled) return;
|
|
713
|
+
bgErrorOccurred = true;
|
|
679
714
|
registry.afterCall(Date.now() - startedAt, true, bypassBreaker);
|
|
680
715
|
completeBackground(1);
|
|
681
716
|
});
|
|
682
717
|
child2.on("close", (code, signal) => {
|
|
683
|
-
|
|
718
|
+
bgSettled = true;
|
|
719
|
+
if (bgErrorOccurred) return;
|
|
720
|
+
const failed = code !== 0 && code !== null || !!signal;
|
|
721
|
+
registry.afterCall(Date.now() - startedAt, failed, bypassBreaker);
|
|
684
722
|
completeBackground(code ?? (signal ? 1 : 0), signal ?? void 0);
|
|
685
723
|
});
|
|
686
|
-
if (typeof pid2
|
|
724
|
+
if (typeof pid2 !== "number") {
|
|
725
|
+
completeBackground(1);
|
|
726
|
+
yield {
|
|
727
|
+
type: "final",
|
|
728
|
+
output: {
|
|
729
|
+
output: "",
|
|
730
|
+
exit_code: 1,
|
|
731
|
+
timed_out: false,
|
|
732
|
+
pid: null,
|
|
733
|
+
error: "Failed to launch background process: invalid PID"
|
|
734
|
+
}
|
|
735
|
+
};
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
738
|
+
child2.unref();
|
|
687
739
|
yield {
|
|
688
740
|
type: "final",
|
|
689
741
|
output: {
|
|
@@ -705,14 +757,46 @@ var bashTool = {
|
|
|
705
757
|
});
|
|
706
758
|
return;
|
|
707
759
|
}
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
760
|
+
let child;
|
|
761
|
+
try {
|
|
762
|
+
child = spawn(shell, args, {
|
|
763
|
+
cwd: spawnCwd,
|
|
764
|
+
env,
|
|
765
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
766
|
+
detached,
|
|
767
|
+
windowsHide: true,
|
|
768
|
+
...isWin2 ? {} : { signal: callerSignal }
|
|
769
|
+
});
|
|
770
|
+
} catch (err) {
|
|
771
|
+
registry.afterCall(Date.now() - startedAt, true, bypassBreaker);
|
|
772
|
+
emitProcessStarted({
|
|
773
|
+
parentPid: process.pid,
|
|
774
|
+
command: redactCommand(`${shell} ${args.join(" ")}`),
|
|
775
|
+
args: redactCommand(args.join(" ")).split(" ").filter(Boolean),
|
|
776
|
+
cwd: spawnCwd,
|
|
777
|
+
background: false,
|
|
778
|
+
startedAt: new Date(startedAt).toISOString()
|
|
779
|
+
});
|
|
780
|
+
emitProcessCompleted({
|
|
781
|
+
exitCode: 1,
|
|
782
|
+
durationMs: Date.now() - startedAt,
|
|
783
|
+
stdoutBytes: 0,
|
|
784
|
+
stderrBytes: 0,
|
|
785
|
+
timedOut: false,
|
|
786
|
+
endedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
787
|
+
});
|
|
788
|
+
yield {
|
|
789
|
+
type: "final",
|
|
790
|
+
output: {
|
|
791
|
+
output: "",
|
|
792
|
+
exit_code: 1,
|
|
793
|
+
timed_out: false,
|
|
794
|
+
pid: null,
|
|
795
|
+
error: `spawn failed: ${err instanceof Error ? err.message : String(err)}`
|
|
796
|
+
}
|
|
797
|
+
};
|
|
798
|
+
return;
|
|
799
|
+
}
|
|
716
800
|
const pid = child.pid;
|
|
717
801
|
let stdoutBytes = 0;
|
|
718
802
|
let stderrBytes = 0;
|
|
@@ -862,15 +946,21 @@ var bashTool = {
|
|
|
862
946
|
const onStderrData = (chunk) => onData(chunk, "stderr");
|
|
863
947
|
child.stdout?.on("data", onStdoutData);
|
|
864
948
|
child.stderr?.on("data", onStderrData);
|
|
949
|
+
let fgErrorOccurred = false;
|
|
950
|
+
let sawClose = false;
|
|
865
951
|
child.on("error", (err) => {
|
|
952
|
+
if (sawClose) return;
|
|
953
|
+
fgErrorOccurred = true;
|
|
866
954
|
for (const t of timers) clearTimeout(t);
|
|
867
955
|
registry.afterCall(Date.now() - startedAt, true);
|
|
868
956
|
completeForeground(1);
|
|
869
957
|
push({ kind: "error", err });
|
|
870
958
|
});
|
|
871
959
|
child.on("close", (code, signal) => {
|
|
960
|
+
sawClose = true;
|
|
872
961
|
for (const t of timers) clearTimeout(t);
|
|
873
962
|
if (typeof pid === "number") registry.unregister(pid);
|
|
963
|
+
if (fgErrorOccurred) return;
|
|
874
964
|
registry.afterCall(Date.now() - startedAt, code !== 0 && code !== null);
|
|
875
965
|
completeForeground(timedOut ? 124 : code ?? (signal ? 1 : 0), signal ?? void 0);
|
|
876
966
|
const tail = stdoutDecoder.end() + stderrDecoder.end();
|
|
@@ -885,7 +975,33 @@ var bashTool = {
|
|
|
885
975
|
while (true) {
|
|
886
976
|
const c = await next();
|
|
887
977
|
resumeIfDrained();
|
|
888
|
-
if (c.kind === "error")
|
|
978
|
+
if (c.kind === "error") {
|
|
979
|
+
const isAbort = c.err?.code === "ABORT_ERR" || callerSignal.aborted;
|
|
980
|
+
const remainder = flush();
|
|
981
|
+
if (remainder !== null) {
|
|
982
|
+
yield { type: "partial_output", text: remainder };
|
|
983
|
+
}
|
|
984
|
+
const spooled = spool.finalize();
|
|
985
|
+
yield {
|
|
986
|
+
type: "final",
|
|
987
|
+
output: {
|
|
988
|
+
output: normalizeCommandOutput(buf) + (spooled ? spoolNote(spooled) : "") + pipeToShellNote,
|
|
989
|
+
exit_code: isAbort ? 124 : 1,
|
|
990
|
+
timed_out: isAbort,
|
|
991
|
+
pid: pid ?? null,
|
|
992
|
+
error: isAbort ? "Command aborted by user or signal" : c.err.message
|
|
993
|
+
}
|
|
994
|
+
};
|
|
995
|
+
ctx.recordSideEffect?.({
|
|
996
|
+
toolUseId: `bash-${Date.now()}`,
|
|
997
|
+
toolName: "bash",
|
|
998
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
999
|
+
input: { command: redactCommand(input.command) },
|
|
1000
|
+
outcome: isAbort ? "aborted" : `error (${c.err.message})`,
|
|
1001
|
+
risk: "shell"
|
|
1002
|
+
});
|
|
1003
|
+
return;
|
|
1004
|
+
}
|
|
889
1005
|
if (c.kind === "end") {
|
|
890
1006
|
const remainder = flush();
|
|
891
1007
|
if (remainder !== null) {
|
|
@@ -930,7 +1046,7 @@ ${hint}` : "") + pipeToShellNote,
|
|
|
930
1046
|
child.stderr?.off("data", onStderrData);
|
|
931
1047
|
child.stdout?.destroy();
|
|
932
1048
|
child.stderr?.destroy();
|
|
933
|
-
if (child.exitCode === null && !child.killed) {
|
|
1049
|
+
if (!sawClose && child.exitCode === null && !child.killed) {
|
|
934
1050
|
if (typeof pid === "number") registry.kill(pid, { force: true });
|
|
935
1051
|
else killWithTimeout(child, 2e3);
|
|
936
1052
|
}
|
|
@@ -977,4 +1093,4 @@ export {
|
|
|
977
1093
|
checkAndBlockKillCommand,
|
|
978
1094
|
bashTool
|
|
979
1095
|
};
|
|
980
|
-
//# sourceMappingURL=chunk-
|
|
1096
|
+
//# sourceMappingURL=chunk-6H4ERJP7.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
builtinToolsPack
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-E7JE3UEX.js";
|
|
4
4
|
import {
|
|
5
5
|
TIER1_TOOLS,
|
|
6
6
|
TIER2_TOOLS
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-IAYMTTR2.js";
|
|
8
8
|
|
|
9
9
|
// src/tool-tier.ts
|
|
10
10
|
function toolNameSet(tools) {
|
|
@@ -54,4 +54,4 @@ export {
|
|
|
54
54
|
selectBuiltinToolsForTier,
|
|
55
55
|
registerBuiltinToolTier
|
|
56
56
|
};
|
|
57
|
-
//# sourceMappingURL=chunk-
|
|
57
|
+
//# sourceMappingURL=chunk-7LQCT3LT.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
builtinTools
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-IAYMTTR2.js";
|
|
4
4
|
|
|
5
5
|
// src/pack.ts
|
|
6
6
|
var builtinToolsPack = {
|
|
@@ -12,4 +12,4 @@ var builtinToolsPack = {
|
|
|
12
12
|
export {
|
|
13
13
|
builtinToolsPack
|
|
14
14
|
};
|
|
15
|
-
//# sourceMappingURL=chunk-
|
|
15
|
+
//# sourceMappingURL=chunk-E7JE3UEX.js.map
|
|
@@ -100,11 +100,11 @@ import {
|
|
|
100
100
|
checkAndBlockKillCommand,
|
|
101
101
|
diagnoseBashism,
|
|
102
102
|
shellArgs
|
|
103
|
-
} from "./chunk-
|
|
103
|
+
} from "./chunk-6H4ERJP7.js";
|
|
104
104
|
import {
|
|
105
105
|
detectDanger,
|
|
106
106
|
execTool
|
|
107
|
-
} from "./chunk-
|
|
107
|
+
} from "./chunk-MGPR7VG3.js";
|
|
108
108
|
import {
|
|
109
109
|
buildChildEnv
|
|
110
110
|
} from "./chunk-BTSFTGIL.js";
|
|
@@ -474,14 +474,72 @@ var pwshTool = {
|
|
|
474
474
|
const startedAt = Date.now();
|
|
475
475
|
const detached = !isWin;
|
|
476
476
|
if (isBackground) {
|
|
477
|
-
|
|
477
|
+
let child2;
|
|
478
|
+
try {
|
|
479
|
+
child2 = spawn(bin, args, {
|
|
480
|
+
cwd: targetCwd,
|
|
481
|
+
env,
|
|
482
|
+
detached,
|
|
483
|
+
stdio: ["ignore", "ignore", "ignore"],
|
|
484
|
+
windowsHide: true
|
|
485
|
+
});
|
|
486
|
+
} catch (err) {
|
|
487
|
+
registry.afterCall(Date.now() - startedAt, true, isBackground);
|
|
488
|
+
emitProcessStarted({
|
|
489
|
+
parentPid: process.pid,
|
|
490
|
+
command: redactCommand(`${bin} ${args.join(" ")}`),
|
|
491
|
+
args: redactCommand(args.join(" ")).split(" ").filter(Boolean),
|
|
492
|
+
cwd: targetCwd,
|
|
493
|
+
background: true,
|
|
494
|
+
startedAt: new Date(startedAt).toISOString()
|
|
495
|
+
});
|
|
496
|
+
emitProcessCompleted({
|
|
497
|
+
exitCode: 1,
|
|
498
|
+
durationMs: Date.now() - startedAt,
|
|
499
|
+
stdoutBytes: 0,
|
|
500
|
+
stderrBytes: 0,
|
|
501
|
+
timedOut: false,
|
|
502
|
+
endedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
503
|
+
});
|
|
504
|
+
yield {
|
|
505
|
+
type: "final",
|
|
506
|
+
output: {
|
|
507
|
+
output: "",
|
|
508
|
+
exit_code: 1,
|
|
509
|
+
timed_out: false,
|
|
510
|
+
pid: null,
|
|
511
|
+
error: `pwsh: spawn failed: ${err instanceof Error ? err.message : String(err)}`
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
const pid2 = child2.pid;
|
|
517
|
+
let bgTelemetryCompleted = false;
|
|
518
|
+
let bgErrorOccurred = false;
|
|
519
|
+
let bgSettled = false;
|
|
520
|
+
emitProcessStarted({
|
|
521
|
+
...pid2 !== void 0 ? { pid: pid2 } : {},
|
|
522
|
+
parentPid: process.pid,
|
|
523
|
+
command: redactCommand(`${bin} ${args.join(" ")}`),
|
|
524
|
+
args: redactCommand(args.join(" ")).split(" ").filter(Boolean),
|
|
478
525
|
cwd: targetCwd,
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
stdio: ["ignore", "ignore", "ignore"],
|
|
482
|
-
windowsHide: true
|
|
526
|
+
background: true,
|
|
527
|
+
startedAt: new Date(startedAt).toISOString()
|
|
483
528
|
});
|
|
484
|
-
const
|
|
529
|
+
const completeBackground = (exitCode, sig) => {
|
|
530
|
+
if (bgTelemetryCompleted) return;
|
|
531
|
+
bgTelemetryCompleted = true;
|
|
532
|
+
emitProcessCompleted({
|
|
533
|
+
...pid2 !== void 0 ? { pid: pid2 } : {},
|
|
534
|
+
exitCode,
|
|
535
|
+
...sig ? { signal: sig } : {},
|
|
536
|
+
durationMs: Date.now() - startedAt,
|
|
537
|
+
stdoutBytes: 0,
|
|
538
|
+
stderrBytes: 0,
|
|
539
|
+
timedOut: false,
|
|
540
|
+
endedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
541
|
+
});
|
|
542
|
+
};
|
|
485
543
|
if (typeof pid2 === "number") {
|
|
486
544
|
registry.register({
|
|
487
545
|
pid: pid2,
|
|
@@ -493,10 +551,19 @@ var pwshTool = {
|
|
|
493
551
|
processGroupLeader: detached && child2.pid === pid2,
|
|
494
552
|
background: true
|
|
495
553
|
});
|
|
496
|
-
child2.on("close", () =>
|
|
497
|
-
|
|
554
|
+
child2.on("close", (code, signal) => {
|
|
555
|
+
bgSettled = true;
|
|
498
556
|
registry.unregister(pid2);
|
|
557
|
+
if (bgErrorOccurred) return;
|
|
558
|
+
const failed = code !== 0 && code !== null || !!signal;
|
|
559
|
+
registry.afterCall(Date.now() - startedAt, failed, isBackground);
|
|
560
|
+
completeBackground(code ?? (signal ? 1 : 0), signal ?? void 0);
|
|
561
|
+
});
|
|
562
|
+
child2.on("error", () => {
|
|
563
|
+
if (bgSettled) return;
|
|
564
|
+
bgErrorOccurred = true;
|
|
499
565
|
registry.afterCall(Date.now() - startedAt, true, isBackground);
|
|
566
|
+
completeBackground(1);
|
|
500
567
|
});
|
|
501
568
|
child2.unref();
|
|
502
569
|
const jobId = `job_${pid2}`;
|
|
@@ -521,6 +588,7 @@ Working directory: ${targetCwd}`,
|
|
|
521
588
|
};
|
|
522
589
|
return;
|
|
523
590
|
}
|
|
591
|
+
completeBackground(1);
|
|
524
592
|
yield {
|
|
525
593
|
type: "final",
|
|
526
594
|
output: {
|
|
@@ -534,13 +602,46 @@ Working directory: ${targetCwd}`,
|
|
|
534
602
|
return;
|
|
535
603
|
}
|
|
536
604
|
const spool = createOutputSpool({ tool: "pwsh", thresholdBytes: MAX_OUTPUT });
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
605
|
+
let child;
|
|
606
|
+
try {
|
|
607
|
+
child = spawn(bin, args, {
|
|
608
|
+
cwd: targetCwd,
|
|
609
|
+
env,
|
|
610
|
+
detached,
|
|
611
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
612
|
+
windowsHide: true
|
|
613
|
+
});
|
|
614
|
+
} catch (err) {
|
|
615
|
+
registry.afterCall(Date.now() - startedAt, true, isBackground);
|
|
616
|
+
spool.finalize();
|
|
617
|
+
emitProcessStarted({
|
|
618
|
+
parentPid: process.pid,
|
|
619
|
+
command: redactCommand(`${bin} ${args.join(" ")}`),
|
|
620
|
+
args: redactCommand(args.join(" ")).split(" ").filter(Boolean),
|
|
621
|
+
cwd: targetCwd,
|
|
622
|
+
background: false,
|
|
623
|
+
startedAt: new Date(startedAt).toISOString()
|
|
624
|
+
});
|
|
625
|
+
emitProcessCompleted({
|
|
626
|
+
exitCode: 1,
|
|
627
|
+
durationMs: Date.now() - startedAt,
|
|
628
|
+
stdoutBytes: 0,
|
|
629
|
+
stderrBytes: 0,
|
|
630
|
+
timedOut: false,
|
|
631
|
+
endedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
632
|
+
});
|
|
633
|
+
yield {
|
|
634
|
+
type: "final",
|
|
635
|
+
output: {
|
|
636
|
+
output: "",
|
|
637
|
+
exit_code: 1,
|
|
638
|
+
timed_out: false,
|
|
639
|
+
pid: null,
|
|
640
|
+
error: `pwsh: spawn failed: ${err instanceof Error ? err.message : String(err)}`
|
|
641
|
+
}
|
|
642
|
+
};
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
544
645
|
const pid = child.pid;
|
|
545
646
|
let stdoutBytes = 0;
|
|
546
647
|
let stderrBytes = 0;
|
|
@@ -688,17 +789,25 @@ Working directory: ${targetCwd}`,
|
|
|
688
789
|
push({ kind: "data", text });
|
|
689
790
|
pauseIfFlooded();
|
|
690
791
|
};
|
|
691
|
-
|
|
692
|
-
|
|
792
|
+
const onStdoutData = (chunk) => onData(chunk, "stdout");
|
|
793
|
+
const onStderrData = (chunk) => onData(chunk, "stderr");
|
|
794
|
+
child.stdout?.on("data", onStdoutData);
|
|
795
|
+
child.stderr?.on("data", onStderrData);
|
|
796
|
+
let fgErrorOccurred = false;
|
|
797
|
+
let sawClose = false;
|
|
693
798
|
child.on("error", (err) => {
|
|
799
|
+
if (sawClose) return;
|
|
800
|
+
fgErrorOccurred = true;
|
|
694
801
|
for (const t of timers) clearTimeout(t);
|
|
695
802
|
registry.afterCall(Date.now() - startedAt, true);
|
|
696
803
|
completeForeground(1);
|
|
697
804
|
push({ kind: "error", err });
|
|
698
805
|
});
|
|
699
806
|
child.on("close", (code, signal) => {
|
|
807
|
+
sawClose = true;
|
|
700
808
|
for (const t of timers) clearTimeout(t);
|
|
701
809
|
if (typeof pid === "number") registry.unregister(pid);
|
|
810
|
+
if (fgErrorOccurred) return;
|
|
702
811
|
registry.afterCall(Date.now() - startedAt, code !== 0 && code !== null);
|
|
703
812
|
completeForeground(timedOut ? 124 : code ?? (signal ? 1 : 0), signal ?? void 0);
|
|
704
813
|
const tail = stdoutDecoder.end() + stderrDecoder.end();
|
|
@@ -713,7 +822,33 @@ Working directory: ${targetCwd}`,
|
|
|
713
822
|
while (true) {
|
|
714
823
|
const c = await next();
|
|
715
824
|
resumeIfDrained();
|
|
716
|
-
if (c.kind === "error")
|
|
825
|
+
if (c.kind === "error") {
|
|
826
|
+
const isAbort = c.err?.code === "ABORT_ERR" || callerSignal.aborted;
|
|
827
|
+
const remainder = flush();
|
|
828
|
+
if (remainder !== null) {
|
|
829
|
+
yield { type: "partial_output", text: remainder };
|
|
830
|
+
}
|
|
831
|
+
const spooled = spool.finalize();
|
|
832
|
+
yield {
|
|
833
|
+
type: "final",
|
|
834
|
+
output: {
|
|
835
|
+
output: normalizeCommandOutput(buf) + (spooled ? spoolNote(spooled) : ""),
|
|
836
|
+
exit_code: isAbort ? 124 : 1,
|
|
837
|
+
timed_out: isAbort,
|
|
838
|
+
pid: pid ?? null,
|
|
839
|
+
error: isAbort ? "Command aborted by user or signal" : c.err.message
|
|
840
|
+
}
|
|
841
|
+
};
|
|
842
|
+
ctx.recordSideEffect?.({
|
|
843
|
+
toolUseId: `pwsh-${Date.now()}`,
|
|
844
|
+
toolName: "pwsh",
|
|
845
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
846
|
+
input: { command: redactCommand(input.command) },
|
|
847
|
+
outcome: isAbort ? "aborted" : `error (${c.err.message})`,
|
|
848
|
+
risk: "shell"
|
|
849
|
+
});
|
|
850
|
+
return;
|
|
851
|
+
}
|
|
717
852
|
if (c.kind === "end") {
|
|
718
853
|
const remainder = flush();
|
|
719
854
|
if (remainder !== null) {
|
|
@@ -739,14 +874,16 @@ Working directory: ${targetCwd}`,
|
|
|
739
874
|
const finalResultText = formattedOutput + (spooled ? spoolNote(spooled) : "") + (hint ? `
|
|
740
875
|
|
|
741
876
|
${hint}` : "") + cautionText;
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
877
|
+
if (!fgErrorOccurred) {
|
|
878
|
+
ctx.recordSideEffect?.({
|
|
879
|
+
toolUseId: `pwsh-${Date.now()}`,
|
|
880
|
+
toolName: "pwsh",
|
|
881
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
882
|
+
input: { command: redactCommand(input.command) },
|
|
883
|
+
outcome: timedOut ? `timed out (exit ${c.code})` : `exit ${c.code}`,
|
|
884
|
+
risk: "shell"
|
|
885
|
+
});
|
|
886
|
+
}
|
|
750
887
|
const isAborted = callerSignal.aborted;
|
|
751
888
|
yield {
|
|
752
889
|
type: "final",
|
|
@@ -768,7 +905,16 @@ ${hint}` : "") + cautionText;
|
|
|
768
905
|
}
|
|
769
906
|
} finally {
|
|
770
907
|
for (const t of timers) clearTimeout(t);
|
|
908
|
+
spool.finalize();
|
|
771
909
|
callerSignal.removeEventListener("abort", onAbort);
|
|
910
|
+
child.stdout?.off("data", onStdoutData);
|
|
911
|
+
child.stderr?.off("data", onStderrData);
|
|
912
|
+
child.stdout?.destroy();
|
|
913
|
+
child.stderr?.destroy();
|
|
914
|
+
if (!sawClose && child.exitCode === null && !child.killed) {
|
|
915
|
+
if (typeof pid === "number") registry.kill(pid, { force: true });
|
|
916
|
+
else killWithTimeout(2e3);
|
|
917
|
+
}
|
|
772
918
|
}
|
|
773
919
|
}
|
|
774
920
|
};
|
|
@@ -1288,4 +1434,4 @@ export {
|
|
|
1288
1434
|
TIER3_TOOLS,
|
|
1289
1435
|
builtinTools
|
|
1290
1436
|
};
|
|
1291
|
-
//# sourceMappingURL=chunk-
|
|
1437
|
+
//# sourceMappingURL=chunk-IAYMTTR2.js.map
|
|
@@ -471,245 +471,6 @@ function levelRank(level) {
|
|
|
471
471
|
}
|
|
472
472
|
}
|
|
473
473
|
|
|
474
|
-
// src/exec-kill-guard.ts
|
|
475
|
-
import * as os from "node:os";
|
|
476
|
-
import * as path from "node:path";
|
|
477
|
-
var isWin = os.platform() === "win32";
|
|
478
|
-
async function checkExecKillCommand(cmd, args) {
|
|
479
|
-
if (!cmd) return { blocked: false };
|
|
480
|
-
const cmdLower = cmd.toLowerCase().trim();
|
|
481
|
-
const fullCommand = [cmdLower, ...args].join(" ").replace(/\s+/g, " ").trim();
|
|
482
|
-
if (isWin) {
|
|
483
|
-
if (cmdLower === "taskkill" || cmdLower === "taskkill.exe") {
|
|
484
|
-
const hasForce = args.some((a) => a.toUpperCase() === "/F" || a.toUpperCase() === "-F");
|
|
485
|
-
const signal = hasForce ? "FORCE" : "TERM";
|
|
486
|
-
for (let i = 0; i < args.length; i++) {
|
|
487
|
-
const a = args[i];
|
|
488
|
-
if (a.toUpperCase() === "/IM" || a.toUpperCase() === "-IM") {
|
|
489
|
-
const nameArg = args[i + 1];
|
|
490
|
-
if (nameArg) {
|
|
491
|
-
const result = await checkKillTarget({ name: nameArg, signal, cmd: fullCommand });
|
|
492
|
-
if (result.blocked) return result;
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
for (let i = 0; i < args.length; i++) {
|
|
497
|
-
const a = args[i];
|
|
498
|
-
if (a.toUpperCase() === "/PID" || a.toUpperCase() === "-PID") {
|
|
499
|
-
const pidArg = args[i + 1];
|
|
500
|
-
if (pidArg && /^\d+$/.test(pidArg)) {
|
|
501
|
-
const result = await checkKillTarget({
|
|
502
|
-
pid: parseInt(pidArg, 10),
|
|
503
|
-
signal,
|
|
504
|
-
cmd: fullCommand
|
|
505
|
-
});
|
|
506
|
-
if (result.blocked) return result;
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
for (let i = 0; i < args.length; i++) {
|
|
511
|
-
const a = args[i];
|
|
512
|
-
if (a.toUpperCase() === "/FI" || a.toUpperCase() === "-FI") {
|
|
513
|
-
const filterArg = args[i + 1];
|
|
514
|
-
if (filterArg) {
|
|
515
|
-
const nameMatch = filterArg.match(/IMAGENAME\s+eq\s+"?([^"\s]+)/i);
|
|
516
|
-
if (nameMatch?.[1]) {
|
|
517
|
-
const result = await checkKillTarget({
|
|
518
|
-
name: nameMatch[1],
|
|
519
|
-
signal,
|
|
520
|
-
cmd: fullCommand
|
|
521
|
-
});
|
|
522
|
-
if (result.blocked) return result;
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
return { blocked: false };
|
|
528
|
-
}
|
|
529
|
-
if (cmdLower === "powershell" || cmdLower === "powershell.exe" || cmdLower === "pwsh" || cmdLower === "pwsh.exe" || cmdLower === "cmd" || cmdLower === "cmd.exe") {
|
|
530
|
-
const shellFlagIndex = args.findIndex((arg) => {
|
|
531
|
-
const lower = arg.toLowerCase();
|
|
532
|
-
return lower === "-c" || lower === "-command" || lower === "/c";
|
|
533
|
-
});
|
|
534
|
-
if (shellFlagIndex >= 0) {
|
|
535
|
-
const innerTokens = tokenizeShellCommand(args.slice(shellFlagIndex + 1).join(" "));
|
|
536
|
-
const innerCommand = innerTokens[0];
|
|
537
|
-
if (innerCommand) {
|
|
538
|
-
const result = await checkExecKillCommand(innerCommand, innerTokens.slice(1));
|
|
539
|
-
if (result.blocked) return result;
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
if (cmdLower === "stop-process" || cmdLower === "kill") {
|
|
544
|
-
for (let i = 0; i < args.length; i++) {
|
|
545
|
-
const a = args[i];
|
|
546
|
-
if (a === "-Name" || a === "-n") {
|
|
547
|
-
const nameArg = args[i + 1]?.replace(/^['"]|['"]$/g, "");
|
|
548
|
-
if (nameArg) {
|
|
549
|
-
const result = await checkKillTarget({
|
|
550
|
-
name: nameArg,
|
|
551
|
-
signal: "FORCE",
|
|
552
|
-
cmd: fullCommand
|
|
553
|
-
});
|
|
554
|
-
if (result.blocked) return result;
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
if (a === "-Id" || a === "-PID" || a === "-pid") {
|
|
558
|
-
const pidArg = args[i + 1];
|
|
559
|
-
if (pidArg && /^\d+$/.test(pidArg)) {
|
|
560
|
-
const result = await checkKillTarget({
|
|
561
|
-
pid: parseInt(pidArg, 10),
|
|
562
|
-
signal: "FORCE",
|
|
563
|
-
cmd: fullCommand
|
|
564
|
-
});
|
|
565
|
-
if (result.blocked) return result;
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
const firstNonFlag = args.find((a) => !a.startsWith("-"));
|
|
570
|
-
if (firstNonFlag) {
|
|
571
|
-
const name = firstNonFlag.replace(/^['"]|['"]$/g, "");
|
|
572
|
-
const result = await checkKillTarget({ name, signal: "TERM", cmd: fullCommand });
|
|
573
|
-
if (result.blocked) return result;
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
if (cmdLower === "wmic" || cmdLower === "wmic.exe") {
|
|
577
|
-
const joined = args.join(" ").toLowerCase();
|
|
578
|
-
if (/\bprocess\b/.test(joined) && /\bdelete\b/.test(joined)) {
|
|
579
|
-
const nameMatch = joined.match(/name\s*=\s*['"]?([^'"]+)/);
|
|
580
|
-
if (nameMatch?.[1]) {
|
|
581
|
-
const result = await checkKillTarget({
|
|
582
|
-
name: nameMatch[1].trim(),
|
|
583
|
-
signal: "FORCE",
|
|
584
|
-
cmd: fullCommand
|
|
585
|
-
});
|
|
586
|
-
if (result.blocked) return result;
|
|
587
|
-
}
|
|
588
|
-
return {
|
|
589
|
-
blocked: true,
|
|
590
|
-
reason: "Blocked: wmic process delete targets all matched processes \u2014 would include protected WrongStack processes."
|
|
591
|
-
};
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
if (cmdLower === "node" || cmdLower === "node.exe") {
|
|
595
|
-
if (args.includes("-e") || args.includes("--eval")) {
|
|
596
|
-
const evalIdx = args.indexOf("-e") !== -1 ? args.indexOf("-e") : args.indexOf("--eval");
|
|
597
|
-
const evalCode = args[evalIdx + 1] ?? "";
|
|
598
|
-
if (/\bprocess\.kill\s*\(/.test(evalCode)) {
|
|
599
|
-
const pidMatch = evalCode.match(/process\.kill\s*\(\s*(\d+)/);
|
|
600
|
-
if (pidMatch?.[1]) {
|
|
601
|
-
const pid = parseInt(pidMatch[1], 10);
|
|
602
|
-
const result = await checkKillTarget({ pid, signal: "SIGTERM", cmd: fullCommand });
|
|
603
|
-
if (result.blocked) return result;
|
|
604
|
-
}
|
|
605
|
-
return {
|
|
606
|
-
blocked: true,
|
|
607
|
-
reason: "Blocked: node -e with process.kill() \u2014 would target protected WrongStack process(es)."
|
|
608
|
-
};
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
} else {
|
|
613
|
-
if (cmdLower === "kill") {
|
|
614
|
-
for (const a of args) {
|
|
615
|
-
const num = a.replace(/^-/, "");
|
|
616
|
-
if (/^\d+$/.test(num)) {
|
|
617
|
-
const pid = parseInt(num, 10);
|
|
618
|
-
const result = await checkKillTarget({ pid, signal: "SIGTERM", cmd: fullCommand });
|
|
619
|
-
if (result.blocked) return result;
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
if (cmdLower === "pkill" || cmdLower === "killall") {
|
|
624
|
-
const firstNonFlag = args.find((a) => !a.startsWith("-"));
|
|
625
|
-
if (firstNonFlag) {
|
|
626
|
-
const result = await checkKillTarget({
|
|
627
|
-
name: firstNonFlag,
|
|
628
|
-
signal: "SIGTERM",
|
|
629
|
-
cmd: fullCommand
|
|
630
|
-
});
|
|
631
|
-
if (result.blocked) return result;
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
return { blocked: false };
|
|
636
|
-
}
|
|
637
|
-
function tokenizeShellCommand(command) {
|
|
638
|
-
const tokens = [];
|
|
639
|
-
let current = "";
|
|
640
|
-
let quote = null;
|
|
641
|
-
for (const char of command.trim()) {
|
|
642
|
-
if (quote) {
|
|
643
|
-
if (char === quote) quote = null;
|
|
644
|
-
else current += char;
|
|
645
|
-
continue;
|
|
646
|
-
}
|
|
647
|
-
if (char === '"' || char === "'") {
|
|
648
|
-
quote = char;
|
|
649
|
-
} else if (/\s/.test(char)) {
|
|
650
|
-
if (current) {
|
|
651
|
-
tokens.push(current);
|
|
652
|
-
current = "";
|
|
653
|
-
}
|
|
654
|
-
} else {
|
|
655
|
-
current += char;
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
if (current) tokens.push(current);
|
|
659
|
-
return tokens;
|
|
660
|
-
}
|
|
661
|
-
async function checkKillTarget(target) {
|
|
662
|
-
const registry = getPersistentProcessRegistry();
|
|
663
|
-
if (target.pid !== void 0) {
|
|
664
|
-
const blocked = await registry.shouldBlockKill(target.pid);
|
|
665
|
-
if (blocked) {
|
|
666
|
-
return {
|
|
667
|
-
blocked: true,
|
|
668
|
-
reason: `Blocked: kill ${target.signal} PID ${target.pid} targets a protected WrongStack process (${target.cmd.slice(0, 80)}).`
|
|
669
|
-
};
|
|
670
|
-
}
|
|
671
|
-
if (target.pid === process.pid) {
|
|
672
|
-
return {
|
|
673
|
-
blocked: true,
|
|
674
|
-
reason: "Blocked: cannot kill the current WrongStack process."
|
|
675
|
-
};
|
|
676
|
-
}
|
|
677
|
-
if (target.pid === process.ppid) {
|
|
678
|
-
return {
|
|
679
|
-
blocked: true,
|
|
680
|
-
reason: "Blocked: cannot kill the parent terminal hosting WrongStack."
|
|
681
|
-
};
|
|
682
|
-
}
|
|
683
|
-
return { blocked: false };
|
|
684
|
-
}
|
|
685
|
-
if (target.name) {
|
|
686
|
-
const nameLower = target.name.toLowerCase().replace(/\.exe$/, "");
|
|
687
|
-
if (nameLower.includes("wrongstack")) {
|
|
688
|
-
return {
|
|
689
|
-
blocked: true,
|
|
690
|
-
reason: `Blocked: kill ${target.signal} '${target.name}' targets a WrongStack process name.`
|
|
691
|
-
};
|
|
692
|
-
}
|
|
693
|
-
const currentImage = path.basename(process.execPath).toLowerCase().replace(/\.exe$/, "");
|
|
694
|
-
const targetsNodeRuntime = nameLower === "node" || nameLower.startsWith("node");
|
|
695
|
-
if (targetsNodeRuntime && currentImage === "node") {
|
|
696
|
-
return {
|
|
697
|
-
blocked: true,
|
|
698
|
-
reason: `Blocked: kill ${target.signal} '${target.name}' would kill the active WrongStack node.exe runtime.`
|
|
699
|
-
};
|
|
700
|
-
}
|
|
701
|
-
const protectedPids = await registry.getAllProtectedPids();
|
|
702
|
-
if (protectedPids.length > 0 && targetsNodeRuntime) {
|
|
703
|
-
return {
|
|
704
|
-
blocked: true,
|
|
705
|
-
reason: `Blocked: kill ${target.signal} '${target.name}' would kill all node.exe processes including active WrongStack instance(s).`
|
|
706
|
-
};
|
|
707
|
-
}
|
|
708
|
-
return { blocked: false };
|
|
709
|
-
}
|
|
710
|
-
return { blocked: false };
|
|
711
|
-
}
|
|
712
|
-
|
|
713
474
|
// src/exec-allowlist.ts
|
|
714
475
|
var DEFAULT_ALLOWED_COMMANDS = /* @__PURE__ */ new Set([
|
|
715
476
|
// JS / TS toolchain
|
|
@@ -1300,6 +1061,245 @@ var DEFAULT_ALLOWED_COMMANDS = /* @__PURE__ */ new Set([
|
|
|
1300
1061
|
"chaos"
|
|
1301
1062
|
]);
|
|
1302
1063
|
|
|
1064
|
+
// src/exec-kill-guard.ts
|
|
1065
|
+
import * as os from "node:os";
|
|
1066
|
+
import * as path from "node:path";
|
|
1067
|
+
var isWin = os.platform() === "win32";
|
|
1068
|
+
async function checkExecKillCommand(cmd, args) {
|
|
1069
|
+
if (!cmd) return { blocked: false };
|
|
1070
|
+
const cmdLower = cmd.toLowerCase().trim();
|
|
1071
|
+
const fullCommand = [cmdLower, ...args].join(" ").replace(/\s+/g, " ").trim();
|
|
1072
|
+
if (isWin) {
|
|
1073
|
+
if (cmdLower === "taskkill" || cmdLower === "taskkill.exe") {
|
|
1074
|
+
const hasForce = args.some((a) => a.toUpperCase() === "/F" || a.toUpperCase() === "-F");
|
|
1075
|
+
const signal = hasForce ? "FORCE" : "TERM";
|
|
1076
|
+
for (let i = 0; i < args.length; i++) {
|
|
1077
|
+
const a = args[i];
|
|
1078
|
+
if (a.toUpperCase() === "/IM" || a.toUpperCase() === "-IM") {
|
|
1079
|
+
const nameArg = args[i + 1];
|
|
1080
|
+
if (nameArg) {
|
|
1081
|
+
const result = await checkKillTarget({ name: nameArg, signal, cmd: fullCommand });
|
|
1082
|
+
if (result.blocked) return result;
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
for (let i = 0; i < args.length; i++) {
|
|
1087
|
+
const a = args[i];
|
|
1088
|
+
if (a.toUpperCase() === "/PID" || a.toUpperCase() === "-PID") {
|
|
1089
|
+
const pidArg = args[i + 1];
|
|
1090
|
+
if (pidArg && /^\d+$/.test(pidArg)) {
|
|
1091
|
+
const result = await checkKillTarget({
|
|
1092
|
+
pid: parseInt(pidArg, 10),
|
|
1093
|
+
signal,
|
|
1094
|
+
cmd: fullCommand
|
|
1095
|
+
});
|
|
1096
|
+
if (result.blocked) return result;
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
for (let i = 0; i < args.length; i++) {
|
|
1101
|
+
const a = args[i];
|
|
1102
|
+
if (a.toUpperCase() === "/FI" || a.toUpperCase() === "-FI") {
|
|
1103
|
+
const filterArg = args[i + 1];
|
|
1104
|
+
if (filterArg) {
|
|
1105
|
+
const nameMatch = filterArg.match(/IMAGENAME\s+eq\s+"?([^"\s]+)/i);
|
|
1106
|
+
if (nameMatch?.[1]) {
|
|
1107
|
+
const result = await checkKillTarget({
|
|
1108
|
+
name: nameMatch[1],
|
|
1109
|
+
signal,
|
|
1110
|
+
cmd: fullCommand
|
|
1111
|
+
});
|
|
1112
|
+
if (result.blocked) return result;
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
return { blocked: false };
|
|
1118
|
+
}
|
|
1119
|
+
if (cmdLower === "powershell" || cmdLower === "powershell.exe" || cmdLower === "pwsh" || cmdLower === "pwsh.exe" || cmdLower === "cmd" || cmdLower === "cmd.exe") {
|
|
1120
|
+
const shellFlagIndex = args.findIndex((arg) => {
|
|
1121
|
+
const lower = arg.toLowerCase();
|
|
1122
|
+
return lower === "-c" || lower === "-command" || lower === "/c";
|
|
1123
|
+
});
|
|
1124
|
+
if (shellFlagIndex >= 0) {
|
|
1125
|
+
const innerTokens = tokenizeShellCommand(args.slice(shellFlagIndex + 1).join(" "));
|
|
1126
|
+
const innerCommand = innerTokens[0];
|
|
1127
|
+
if (innerCommand) {
|
|
1128
|
+
const result = await checkExecKillCommand(innerCommand, innerTokens.slice(1));
|
|
1129
|
+
if (result.blocked) return result;
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
if (cmdLower === "stop-process" || cmdLower === "kill") {
|
|
1134
|
+
for (let i = 0; i < args.length; i++) {
|
|
1135
|
+
const a = args[i];
|
|
1136
|
+
if (a === "-Name" || a === "-n") {
|
|
1137
|
+
const nameArg = args[i + 1]?.replace(/^['"]|['"]$/g, "");
|
|
1138
|
+
if (nameArg) {
|
|
1139
|
+
const result = await checkKillTarget({
|
|
1140
|
+
name: nameArg,
|
|
1141
|
+
signal: "FORCE",
|
|
1142
|
+
cmd: fullCommand
|
|
1143
|
+
});
|
|
1144
|
+
if (result.blocked) return result;
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
if (a === "-Id" || a === "-PID" || a === "-pid") {
|
|
1148
|
+
const pidArg = args[i + 1];
|
|
1149
|
+
if (pidArg && /^\d+$/.test(pidArg)) {
|
|
1150
|
+
const result = await checkKillTarget({
|
|
1151
|
+
pid: parseInt(pidArg, 10),
|
|
1152
|
+
signal: "FORCE",
|
|
1153
|
+
cmd: fullCommand
|
|
1154
|
+
});
|
|
1155
|
+
if (result.blocked) return result;
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
const firstNonFlag = args.find((a) => !a.startsWith("-"));
|
|
1160
|
+
if (firstNonFlag) {
|
|
1161
|
+
const name = firstNonFlag.replace(/^['"]|['"]$/g, "");
|
|
1162
|
+
const result = await checkKillTarget({ name, signal: "TERM", cmd: fullCommand });
|
|
1163
|
+
if (result.blocked) return result;
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
if (cmdLower === "wmic" || cmdLower === "wmic.exe") {
|
|
1167
|
+
const joined = args.join(" ").toLowerCase();
|
|
1168
|
+
if (/\bprocess\b/.test(joined) && /\bdelete\b/.test(joined)) {
|
|
1169
|
+
const nameMatch = joined.match(/name\s*=\s*['"]?([^'"]+)/);
|
|
1170
|
+
if (nameMatch?.[1]) {
|
|
1171
|
+
const result = await checkKillTarget({
|
|
1172
|
+
name: nameMatch[1].trim(),
|
|
1173
|
+
signal: "FORCE",
|
|
1174
|
+
cmd: fullCommand
|
|
1175
|
+
});
|
|
1176
|
+
if (result.blocked) return result;
|
|
1177
|
+
}
|
|
1178
|
+
return {
|
|
1179
|
+
blocked: true,
|
|
1180
|
+
reason: "Blocked: wmic process delete targets all matched processes \u2014 would include protected WrongStack processes."
|
|
1181
|
+
};
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
if (cmdLower === "node" || cmdLower === "node.exe") {
|
|
1185
|
+
if (args.includes("-e") || args.includes("--eval")) {
|
|
1186
|
+
const evalIdx = args.indexOf("-e") !== -1 ? args.indexOf("-e") : args.indexOf("--eval");
|
|
1187
|
+
const evalCode = args[evalIdx + 1] ?? "";
|
|
1188
|
+
if (/\bprocess\.kill\s*\(/.test(evalCode)) {
|
|
1189
|
+
const pidMatch = evalCode.match(/process\.kill\s*\(\s*(\d+)/);
|
|
1190
|
+
if (pidMatch?.[1]) {
|
|
1191
|
+
const pid = parseInt(pidMatch[1], 10);
|
|
1192
|
+
const result = await checkKillTarget({ pid, signal: "SIGTERM", cmd: fullCommand });
|
|
1193
|
+
if (result.blocked) return result;
|
|
1194
|
+
}
|
|
1195
|
+
return {
|
|
1196
|
+
blocked: true,
|
|
1197
|
+
reason: "Blocked: node -e with process.kill() \u2014 would target protected WrongStack process(es)."
|
|
1198
|
+
};
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
} else {
|
|
1203
|
+
if (cmdLower === "kill") {
|
|
1204
|
+
for (const a of args) {
|
|
1205
|
+
const num = a.replace(/^-/, "");
|
|
1206
|
+
if (/^\d+$/.test(num)) {
|
|
1207
|
+
const pid = parseInt(num, 10);
|
|
1208
|
+
const result = await checkKillTarget({ pid, signal: "SIGTERM", cmd: fullCommand });
|
|
1209
|
+
if (result.blocked) return result;
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
if (cmdLower === "pkill" || cmdLower === "killall") {
|
|
1214
|
+
const firstNonFlag = args.find((a) => !a.startsWith("-"));
|
|
1215
|
+
if (firstNonFlag) {
|
|
1216
|
+
const result = await checkKillTarget({
|
|
1217
|
+
name: firstNonFlag,
|
|
1218
|
+
signal: "SIGTERM",
|
|
1219
|
+
cmd: fullCommand
|
|
1220
|
+
});
|
|
1221
|
+
if (result.blocked) return result;
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
return { blocked: false };
|
|
1226
|
+
}
|
|
1227
|
+
function tokenizeShellCommand(command) {
|
|
1228
|
+
const tokens = [];
|
|
1229
|
+
let current = "";
|
|
1230
|
+
let quote = null;
|
|
1231
|
+
for (const char of command.trim()) {
|
|
1232
|
+
if (quote) {
|
|
1233
|
+
if (char === quote) quote = null;
|
|
1234
|
+
else current += char;
|
|
1235
|
+
continue;
|
|
1236
|
+
}
|
|
1237
|
+
if (char === '"' || char === "'") {
|
|
1238
|
+
quote = char;
|
|
1239
|
+
} else if (/\s/.test(char)) {
|
|
1240
|
+
if (current) {
|
|
1241
|
+
tokens.push(current);
|
|
1242
|
+
current = "";
|
|
1243
|
+
}
|
|
1244
|
+
} else {
|
|
1245
|
+
current += char;
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
if (current) tokens.push(current);
|
|
1249
|
+
return tokens;
|
|
1250
|
+
}
|
|
1251
|
+
async function checkKillTarget(target) {
|
|
1252
|
+
const registry = getPersistentProcessRegistry();
|
|
1253
|
+
if (target.pid !== void 0) {
|
|
1254
|
+
const blocked = await registry.shouldBlockKill(target.pid);
|
|
1255
|
+
if (blocked) {
|
|
1256
|
+
return {
|
|
1257
|
+
blocked: true,
|
|
1258
|
+
reason: `Blocked: kill ${target.signal} PID ${target.pid} targets a protected WrongStack process (${target.cmd.slice(0, 80)}).`
|
|
1259
|
+
};
|
|
1260
|
+
}
|
|
1261
|
+
if (target.pid === process.pid) {
|
|
1262
|
+
return {
|
|
1263
|
+
blocked: true,
|
|
1264
|
+
reason: "Blocked: cannot kill the current WrongStack process."
|
|
1265
|
+
};
|
|
1266
|
+
}
|
|
1267
|
+
if (target.pid === process.ppid) {
|
|
1268
|
+
return {
|
|
1269
|
+
blocked: true,
|
|
1270
|
+
reason: "Blocked: cannot kill the parent terminal hosting WrongStack."
|
|
1271
|
+
};
|
|
1272
|
+
}
|
|
1273
|
+
return { blocked: false };
|
|
1274
|
+
}
|
|
1275
|
+
if (target.name) {
|
|
1276
|
+
const nameLower = target.name.toLowerCase().replace(/\.exe$/, "");
|
|
1277
|
+
if (nameLower.includes("wrongstack")) {
|
|
1278
|
+
return {
|
|
1279
|
+
blocked: true,
|
|
1280
|
+
reason: `Blocked: kill ${target.signal} '${target.name}' targets a WrongStack process name.`
|
|
1281
|
+
};
|
|
1282
|
+
}
|
|
1283
|
+
const currentImage = path.basename(process.execPath).toLowerCase().replace(/\.exe$/, "");
|
|
1284
|
+
const targetsNodeRuntime = nameLower === "node" || nameLower.startsWith("node");
|
|
1285
|
+
if (targetsNodeRuntime && currentImage === "node") {
|
|
1286
|
+
return {
|
|
1287
|
+
blocked: true,
|
|
1288
|
+
reason: `Blocked: kill ${target.signal} '${target.name}' would kill the active WrongStack node.exe runtime.`
|
|
1289
|
+
};
|
|
1290
|
+
}
|
|
1291
|
+
const protectedPids = await registry.getAllProtectedPids();
|
|
1292
|
+
if (protectedPids.length > 0 && targetsNodeRuntime) {
|
|
1293
|
+
return {
|
|
1294
|
+
blocked: true,
|
|
1295
|
+
reason: `Blocked: kill ${target.signal} '${target.name}' would kill all node.exe processes including active WrongStack instance(s).`
|
|
1296
|
+
};
|
|
1297
|
+
}
|
|
1298
|
+
return { blocked: false };
|
|
1299
|
+
}
|
|
1300
|
+
return { blocked: false };
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
1303
|
// src/exec.ts
|
|
1304
1304
|
var isWin2 = process.platform === "win32";
|
|
1305
1305
|
var allowedCommands = new Set(DEFAULT_ALLOWED_COMMANDS);
|
|
@@ -1351,10 +1351,9 @@ var BLOCKED_ARG_PATTERNS = {
|
|
|
1351
1351
|
/^--exec=/,
|
|
1352
1352
|
/^--upload-pack=/,
|
|
1353
1353
|
/^--receive-pack=/,
|
|
1354
|
-
/^-C
|
|
1355
|
-
/^-c
|
|
1354
|
+
/^-C/,
|
|
1355
|
+
/^-c/,
|
|
1356
1356
|
/^--config$/,
|
|
1357
|
-
/^-c=/,
|
|
1358
1357
|
/^--config=/,
|
|
1359
1358
|
/^--config-env=/
|
|
1360
1359
|
],
|
|
@@ -1454,6 +1453,7 @@ function validateArgs(cmd, args) {
|
|
|
1454
1453
|
const blocked = BLOCKED_ARG_PATTERNS[cmd];
|
|
1455
1454
|
if (!blocked) return null;
|
|
1456
1455
|
for (const arg of args) {
|
|
1456
|
+
if (arg === "--") break;
|
|
1457
1457
|
for (const pattern of blocked) {
|
|
1458
1458
|
if (pattern.test(arg)) {
|
|
1459
1459
|
return `Blocked argument "${arg}" for command "${cmd}" (matches security pattern ${pattern})`;
|
|
@@ -1657,11 +1657,6 @@ function runCommand(cmd, args, cwd, timeout, signal, sessionId, danger) {
|
|
|
1657
1657
|
});
|
|
1658
1658
|
return;
|
|
1659
1659
|
}
|
|
1660
|
-
const resolved = resolveWin32Command(cmd);
|
|
1661
|
-
const needsShell = isWin2 && (resolved.endsWith(".cmd") || resolved.endsWith(".bat"));
|
|
1662
|
-
const shim = needsShell ? buildWin32CmdShimInvocation(resolved, args) : null;
|
|
1663
|
-
const spawnCmd = shim?.command ?? resolved;
|
|
1664
|
-
const spawnArgs = shim?.args ?? args;
|
|
1665
1660
|
const emitCompletedOnce = (exitCode, pid2, signal2) => {
|
|
1666
1661
|
if (telemetryCompleted) return;
|
|
1667
1662
|
telemetryCompleted = true;
|
|
@@ -1678,6 +1673,11 @@ function runCommand(cmd, args, cwd, timeout, signal, sessionId, danger) {
|
|
|
1678
1673
|
};
|
|
1679
1674
|
let child;
|
|
1680
1675
|
try {
|
|
1676
|
+
const resolved = resolveWin32Command(cmd);
|
|
1677
|
+
const needsShell = isWin2 && (resolved.endsWith(".cmd") || resolved.endsWith(".bat"));
|
|
1678
|
+
const shim = needsShell ? buildWin32CmdShimInvocation(resolved, args) : null;
|
|
1679
|
+
const spawnCmd = shim?.command ?? resolved;
|
|
1680
|
+
const spawnArgs = shim?.args ?? args;
|
|
1681
1681
|
child = spawn(spawnCmd, spawnArgs, {
|
|
1682
1682
|
cwd,
|
|
1683
1683
|
env: buildChildEnv(sessionId),
|
|
@@ -1687,6 +1687,7 @@ function runCommand(cmd, args, cwd, timeout, signal, sessionId, danger) {
|
|
|
1687
1687
|
...shim ? { windowsVerbatimArguments: shim.windowsVerbatimArguments } : {}
|
|
1688
1688
|
});
|
|
1689
1689
|
} catch (err) {
|
|
1690
|
+
getProcessRegistry().afterCall(Date.now() - startedAt, true);
|
|
1690
1691
|
spool.finalize();
|
|
1691
1692
|
emitProcessStarted({
|
|
1692
1693
|
parentPid: process.pid,
|
|
@@ -1718,10 +1719,18 @@ function runCommand(cmd, args, cwd, timeout, signal, sessionId, danger) {
|
|
|
1718
1719
|
background: false,
|
|
1719
1720
|
startedAt: new Date(startedAt).toISOString()
|
|
1720
1721
|
});
|
|
1722
|
+
const registry = getProcessRegistry();
|
|
1723
|
+
const pid = child.pid;
|
|
1724
|
+
let timer;
|
|
1725
|
+
const onAbort = () => {
|
|
1726
|
+
killed = true;
|
|
1727
|
+
if (typeof pid === "number") registry.kill(pid, { force: true });
|
|
1728
|
+
else child.kill("SIGTERM");
|
|
1729
|
+
};
|
|
1721
1730
|
child.on("error", (err) => {
|
|
1722
1731
|
const isAbort = err && err.code === "ABORT_ERR";
|
|
1723
1732
|
const stderrText = isAbort ? `Aborted: ${err.message}` : err.message;
|
|
1724
|
-
clearTimeout(timer);
|
|
1733
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
1725
1734
|
if (isWin2) signal.removeEventListener("abort", onAbort);
|
|
1726
1735
|
if (typeof pid === "number") registry.unregister(pid);
|
|
1727
1736
|
registry.afterCall(Date.now() - startedAt, true);
|
|
@@ -1738,8 +1747,6 @@ function runCommand(cmd, args, cwd, timeout, signal, sessionId, danger) {
|
|
|
1738
1747
|
danger
|
|
1739
1748
|
});
|
|
1740
1749
|
});
|
|
1741
|
-
const registry = getProcessRegistry();
|
|
1742
|
-
const pid = child.pid;
|
|
1743
1750
|
if (typeof pid === "number") {
|
|
1744
1751
|
const fullCommand = `${cmd} ${args.join(" ")}`;
|
|
1745
1752
|
registry.register({
|
|
@@ -1751,17 +1758,12 @@ function runCommand(cmd, args, cwd, timeout, signal, sessionId, danger) {
|
|
|
1751
1758
|
child
|
|
1752
1759
|
});
|
|
1753
1760
|
}
|
|
1754
|
-
|
|
1761
|
+
timer = setTimeout(() => {
|
|
1755
1762
|
killed = true;
|
|
1756
1763
|
timedOut = true;
|
|
1757
1764
|
if (typeof pid === "number") registry.kill(pid);
|
|
1758
1765
|
else child.kill("SIGTERM");
|
|
1759
1766
|
}, timeout);
|
|
1760
|
-
const onAbort = () => {
|
|
1761
|
-
killed = true;
|
|
1762
|
-
if (typeof pid === "number") registry.kill(pid, { force: true });
|
|
1763
|
-
else child.kill("SIGTERM");
|
|
1764
|
-
};
|
|
1765
1767
|
if (isWin2) {
|
|
1766
1768
|
if (signal.aborted) onAbort();
|
|
1767
1769
|
else signal.addEventListener("abort", onAbort, { once: true });
|
|
@@ -1787,9 +1789,10 @@ function runCommand(cmd, args, cwd, timeout, signal, sessionId, danger) {
|
|
|
1787
1789
|
}
|
|
1788
1790
|
});
|
|
1789
1791
|
child.on("close", (code) => {
|
|
1790
|
-
clearTimeout(timer);
|
|
1792
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
1791
1793
|
if (isWin2) signal.removeEventListener("abort", onAbort);
|
|
1792
1794
|
if (typeof pid === "number") registry.unregister(pid);
|
|
1795
|
+
if (resolvedOnce.value) return;
|
|
1793
1796
|
const durationMs = Date.now() - startedAt;
|
|
1794
1797
|
const exitCode = killed ? 124 : code ?? 1;
|
|
1795
1798
|
emitCompletedOnce(exitCode, pid);
|
|
@@ -1832,4 +1835,4 @@ export {
|
|
|
1832
1835
|
getExecAllowlist,
|
|
1833
1836
|
execTool
|
|
1834
1837
|
};
|
|
1835
|
-
//# sourceMappingURL=chunk-
|
|
1838
|
+
//# sourceMappingURL=chunk-MGPR7VG3.js.map
|
package/dist/exec.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
GROUNDED_NO_PROGRESS_STEER,
|
|
17
17
|
createAutoProceedLoopGuard,
|
|
18
18
|
normalizeForRepetition
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-NL2S2CXD.js";
|
|
20
20
|
import {
|
|
21
21
|
createGlobalPsSlashCommand,
|
|
22
22
|
formatGlobalStatus,
|
|
@@ -41,10 +41,10 @@ import "./chunk-Z6DAKQ3U.js";
|
|
|
41
41
|
import {
|
|
42
42
|
registerBuiltinToolTier,
|
|
43
43
|
selectBuiltinToolsForTier
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-7LQCT3LT.js";
|
|
45
45
|
import {
|
|
46
46
|
builtinToolsPack
|
|
47
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-E7JE3UEX.js";
|
|
48
48
|
import {
|
|
49
49
|
OFF_ONLY_TOOLS,
|
|
50
50
|
OPTIONAL_TOOLS,
|
|
@@ -59,7 +59,7 @@ import {
|
|
|
59
59
|
pwshTool,
|
|
60
60
|
securityAstScanTool,
|
|
61
61
|
setWorkingDirTool
|
|
62
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-IAYMTTR2.js";
|
|
63
63
|
import {
|
|
64
64
|
discoverE2EProjects,
|
|
65
65
|
e2ePlanTool
|
|
@@ -193,7 +193,7 @@ import {
|
|
|
193
193
|
import {
|
|
194
194
|
bashTool,
|
|
195
195
|
checkAndBlockKillCommand
|
|
196
|
-
} from "./chunk-
|
|
196
|
+
} from "./chunk-6H4ERJP7.js";
|
|
197
197
|
import {
|
|
198
198
|
checkExecKillCommand,
|
|
199
199
|
configureDangerBypass,
|
|
@@ -205,7 +205,7 @@ import {
|
|
|
205
205
|
isExecCommandAllowed,
|
|
206
206
|
resetDangerBypass,
|
|
207
207
|
resetExecPolicy
|
|
208
|
-
} from "./chunk-
|
|
208
|
+
} from "./chunk-MGPR7VG3.js";
|
|
209
209
|
import "./chunk-BTSFTGIL.js";
|
|
210
210
|
import {
|
|
211
211
|
getPersistentProcessRegistry,
|
package/dist/pack.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
builtinToolsPack
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-E7JE3UEX.js";
|
|
4
|
+
import "./chunk-IAYMTTR2.js";
|
|
5
5
|
import "./chunk-RV7BVTDG.js";
|
|
6
6
|
import "./chunk-YEISRT4S.js";
|
|
7
7
|
import "./chunk-XRNN44QY.js";
|
|
@@ -35,8 +35,8 @@ import "./chunk-ASEXQRA7.js";
|
|
|
35
35
|
import "./chunk-4ERMPDHV.js";
|
|
36
36
|
import "./chunk-YJTXRH5Y.js";
|
|
37
37
|
import "./chunk-ZBMANLYH.js";
|
|
38
|
-
import "./chunk-
|
|
39
|
-
import "./chunk-
|
|
38
|
+
import "./chunk-6H4ERJP7.js";
|
|
39
|
+
import "./chunk-MGPR7VG3.js";
|
|
40
40
|
import "./chunk-BTSFTGIL.js";
|
|
41
41
|
import "./chunk-PVCB7RUZ.js";
|
|
42
42
|
import "./chunk-SCMRM6NL.js";
|
package/dist/tool-tier.js
CHANGED
|
@@ -2,9 +2,9 @@ import {
|
|
|
2
2
|
BUILTIN_TIER_COUNTS,
|
|
3
3
|
registerBuiltinToolTier,
|
|
4
4
|
selectBuiltinToolsForTier
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-7LQCT3LT.js";
|
|
6
|
+
import "./chunk-E7JE3UEX.js";
|
|
7
|
+
import "./chunk-IAYMTTR2.js";
|
|
8
8
|
import "./chunk-RV7BVTDG.js";
|
|
9
9
|
import "./chunk-YEISRT4S.js";
|
|
10
10
|
import "./chunk-XRNN44QY.js";
|
|
@@ -38,8 +38,8 @@ import "./chunk-ASEXQRA7.js";
|
|
|
38
38
|
import "./chunk-4ERMPDHV.js";
|
|
39
39
|
import "./chunk-YJTXRH5Y.js";
|
|
40
40
|
import "./chunk-ZBMANLYH.js";
|
|
41
|
-
import "./chunk-
|
|
42
|
-
import "./chunk-
|
|
41
|
+
import "./chunk-6H4ERJP7.js";
|
|
42
|
+
import "./chunk-MGPR7VG3.js";
|
|
43
43
|
import "./chunk-BTSFTGIL.js";
|
|
44
44
|
import "./chunk-PVCB7RUZ.js";
|
|
45
45
|
import "./chunk-SCMRM6NL.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrongstack/tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "WrongStack built-in tools: read/write/edit, bash/exec, grep/glob, git, fetch, test, lint, and more.",
|
|
6
6
|
"repository": {
|
|
@@ -249,10 +249,10 @@
|
|
|
249
249
|
"@msgpack/msgpack": "^3.1.3",
|
|
250
250
|
"@playwright/test": "^1.62.1",
|
|
251
251
|
"@typescript/typescript6": "^6.0.2",
|
|
252
|
-
"@wrongstack/core": "1.0.
|
|
253
|
-
"@wrongstack/kanban": "1.0.
|
|
254
|
-
"@wrongstack/persistence": "1.0.
|
|
255
|
-
"@wrongstack/primitives": "1.0.
|
|
252
|
+
"@wrongstack/core": "1.0.1",
|
|
253
|
+
"@wrongstack/kanban": "1.0.1",
|
|
254
|
+
"@wrongstack/persistence": "1.0.1",
|
|
255
|
+
"@wrongstack/primitives": "1.0.1",
|
|
256
256
|
"tree-sitter-wasm": "1.1.4",
|
|
257
257
|
"turndown": "^7.2.4",
|
|
258
258
|
"undici": "^8.10.0",
|