@wrongstack/tools 0.308.0 → 0.308.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/bash-kill-guard.d.ts +1 -0
- package/dist/bash.js +15 -1
- package/dist/builtin.js +612 -143
- package/dist/exec.js +34 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +644 -171
- package/dist/pack.js +611 -143
- package/dist/pwsh.d.ts +22 -0
- package/dist/tool-tier.js +612 -143
- package/package.json +5 -4
package/dist/index.js
CHANGED
|
@@ -1034,8 +1034,8 @@ async function* spawnStream(opts) {
|
|
|
1034
1034
|
try {
|
|
1035
1035
|
for (; ; ) {
|
|
1036
1036
|
while (queue.length === 0) {
|
|
1037
|
-
await new Promise((
|
|
1038
|
-
waiter =
|
|
1037
|
+
await new Promise((resolve25) => {
|
|
1038
|
+
waiter = resolve25;
|
|
1039
1039
|
});
|
|
1040
1040
|
}
|
|
1041
1041
|
const chunk = queue.shift();
|
|
@@ -1138,9 +1138,9 @@ async function detectPackageManager(cwd, stopAt) {
|
|
|
1138
1138
|
return "npm";
|
|
1139
1139
|
}
|
|
1140
1140
|
async function detectPackageManagerInDir(dir) {
|
|
1141
|
-
const
|
|
1141
|
+
const fs45 = await import("node:fs/promises");
|
|
1142
1142
|
try {
|
|
1143
|
-
const raw = await
|
|
1143
|
+
const raw = await fs45.readFile(path3.join(dir, "package.json"), "utf8");
|
|
1144
1144
|
const declared = JSON.parse(raw).packageManager;
|
|
1145
1145
|
if (typeof declared === "string") {
|
|
1146
1146
|
const name = declared.split("@")[0] ?? "";
|
|
@@ -1159,7 +1159,7 @@ async function detectPackageManagerInDir(dir) {
|
|
|
1159
1159
|
];
|
|
1160
1160
|
for (const [file, manager] of lockfiles) {
|
|
1161
1161
|
try {
|
|
1162
|
-
await
|
|
1162
|
+
await fs45.stat(`${dir}/${file}`);
|
|
1163
1163
|
return manager;
|
|
1164
1164
|
} catch {
|
|
1165
1165
|
}
|
|
@@ -4140,15 +4140,15 @@ async function changedPaths(before, after, beforeSizes, afterSizes) {
|
|
|
4140
4140
|
const beforeSet = new Set(before);
|
|
4141
4141
|
const afterSet = new Set(after);
|
|
4142
4142
|
const changed = /* @__PURE__ */ new Set();
|
|
4143
|
-
for (const
|
|
4144
|
-
if (!beforeSet.has(
|
|
4143
|
+
for (const path51 of after) {
|
|
4144
|
+
if (!beforeSet.has(path51)) changed.add(path51);
|
|
4145
4145
|
}
|
|
4146
|
-
for (const
|
|
4147
|
-
if (!afterSet.has(
|
|
4146
|
+
for (const path51 of before) {
|
|
4147
|
+
if (!afterSet.has(path51)) changed.add(path51);
|
|
4148
4148
|
}
|
|
4149
4149
|
if (beforeSizes && afterSizes) {
|
|
4150
|
-
for (const
|
|
4151
|
-
if (beforeSizes.get(
|
|
4150
|
+
for (const path51 of after) {
|
|
4151
|
+
if (beforeSizes.get(path51) !== afterSizes.get(path51)) changed.add(path51);
|
|
4152
4152
|
}
|
|
4153
4153
|
}
|
|
4154
4154
|
return [...changed].sort();
|
|
@@ -5643,7 +5643,7 @@ async function syncGoParse(filePath, content, lang) {
|
|
|
5643
5643
|
}
|
|
5644
5644
|
const goBinary = resolveWin32Command("go");
|
|
5645
5645
|
const goResult = await new Promise(
|
|
5646
|
-
(
|
|
5646
|
+
(resolve25, reject) => {
|
|
5647
5647
|
let settled = false;
|
|
5648
5648
|
const proc = spawn5(goBinary, ["run", scriptPath], {
|
|
5649
5649
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -5672,7 +5672,7 @@ async function syncGoParse(filePath, content, lang) {
|
|
|
5672
5672
|
if (settled) return;
|
|
5673
5673
|
settled = true;
|
|
5674
5674
|
clearTimeout(timer);
|
|
5675
|
-
|
|
5675
|
+
resolve25({ code: code2, stdout: stdout2 });
|
|
5676
5676
|
});
|
|
5677
5677
|
}
|
|
5678
5678
|
);
|
|
@@ -6348,7 +6348,7 @@ async function resolvePython() {
|
|
|
6348
6348
|
return null;
|
|
6349
6349
|
}
|
|
6350
6350
|
function commandIsAvailable(command) {
|
|
6351
|
-
return new Promise((
|
|
6351
|
+
return new Promise((resolve25) => {
|
|
6352
6352
|
let settled = false;
|
|
6353
6353
|
const proc = spawn6(command, ["--version"], {
|
|
6354
6354
|
stdio: "ignore",
|
|
@@ -6358,7 +6358,7 @@ function commandIsAvailable(command) {
|
|
|
6358
6358
|
if (settled) return;
|
|
6359
6359
|
settled = true;
|
|
6360
6360
|
clearTimeout(timer);
|
|
6361
|
-
|
|
6361
|
+
resolve25(available);
|
|
6362
6362
|
};
|
|
6363
6363
|
const timer = setTimeout(() => {
|
|
6364
6364
|
proc.kill("SIGKILL");
|
|
@@ -6370,7 +6370,7 @@ function commandIsAvailable(command) {
|
|
|
6370
6370
|
});
|
|
6371
6371
|
}
|
|
6372
6372
|
function spawnPyParser(pyBinary, scriptPath, filePath, content) {
|
|
6373
|
-
return new Promise((
|
|
6373
|
+
return new Promise((resolve25, reject) => {
|
|
6374
6374
|
let settled = false;
|
|
6375
6375
|
const proc = spawn6(pyBinary, [scriptPath, filePath], {
|
|
6376
6376
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -6399,7 +6399,7 @@ function spawnPyParser(pyBinary, scriptPath, filePath, content) {
|
|
|
6399
6399
|
if (settled) return;
|
|
6400
6400
|
settled = true;
|
|
6401
6401
|
clearTimeout(timer);
|
|
6402
|
-
|
|
6402
|
+
resolve25({ code, stdout });
|
|
6403
6403
|
});
|
|
6404
6404
|
});
|
|
6405
6405
|
}
|
|
@@ -7788,6 +7788,40 @@ var RULES = [
|
|
|
7788
7788
|
},
|
|
7789
7789
|
reason: "Remove-Item with -Recurse -Force"
|
|
7790
7790
|
},
|
|
7791
|
+
// ----- Windows PowerShell Disk & Volume destruction -----
|
|
7792
|
+
{
|
|
7793
|
+
id: "powershell-disk-volume-destroy",
|
|
7794
|
+
level: "destructive",
|
|
7795
|
+
test: (cmd, args) => {
|
|
7796
|
+
if (cmd !== "powershell" && cmd !== "pwsh") return false;
|
|
7797
|
+
return args.some(
|
|
7798
|
+
(a) => /^(?:Format-Volume|Clear-Disk|Initialize-Disk|Remove-Partition|Clear-Volume)(?:\s|$)/i.test(a)
|
|
7799
|
+
);
|
|
7800
|
+
},
|
|
7801
|
+
reason: "PowerShell disk/volume partition destruction"
|
|
7802
|
+
},
|
|
7803
|
+
// ----- Windows PowerShell System Restart / Shutdown -----
|
|
7804
|
+
{
|
|
7805
|
+
id: "powershell-stop-restart-computer",
|
|
7806
|
+
level: "destructive",
|
|
7807
|
+
test: (cmd, args) => {
|
|
7808
|
+
if (cmd !== "powershell" && cmd !== "pwsh") return false;
|
|
7809
|
+
return args.some((a) => /^(?:Stop-Computer|Restart-Computer)(?:\s|$)/i.test(a));
|
|
7810
|
+
},
|
|
7811
|
+
reason: "PowerShell system shutdown or restart"
|
|
7812
|
+
},
|
|
7813
|
+
// ----- Windows PowerShell ExecutionPolicy / Payload evasion -----
|
|
7814
|
+
{
|
|
7815
|
+
id: "powershell-execution-policy-bypass",
|
|
7816
|
+
level: "caution",
|
|
7817
|
+
test: (cmd, args) => {
|
|
7818
|
+
if (cmd !== "powershell" && cmd !== "pwsh") return false;
|
|
7819
|
+
return args.some(
|
|
7820
|
+
(a) => /Set-ExecutionPolicy\s+(?:Bypass|Unrestricted)|-(?:EncodedCommand|enc)\b/i.test(a)
|
|
7821
|
+
);
|
|
7822
|
+
},
|
|
7823
|
+
reason: "PowerShell execution policy bypass or encoded command"
|
|
7824
|
+
},
|
|
7791
7825
|
// ----- find -exec / -ok / -execdir -----
|
|
7792
7826
|
{
|
|
7793
7827
|
id: "find-exec",
|
|
@@ -8108,8 +8142,8 @@ function normalizeShell(value) {
|
|
|
8108
8142
|
if (v === "pwsh" || v === "pwsh.exe") return "pwsh";
|
|
8109
8143
|
return void 0;
|
|
8110
8144
|
}
|
|
8111
|
-
function resolveSessionShell(
|
|
8112
|
-
if (
|
|
8145
|
+
function resolveSessionShell(platform7, env, deps = {}) {
|
|
8146
|
+
if (platform7 !== "win32") return void 0;
|
|
8113
8147
|
const override = normalizeShell(env.get("WRONGSTACK_SHELL"));
|
|
8114
8148
|
if (override) return override;
|
|
8115
8149
|
const hasBinary = deps.hasBinary ?? ((bin) => resolveWin32Command(bin) !== bin);
|
|
@@ -8119,11 +8153,11 @@ function resolveSessionShell(platform6, env, deps = {}) {
|
|
|
8119
8153
|
}
|
|
8120
8154
|
function ensureSessionShell(opts = {}) {
|
|
8121
8155
|
const env = opts.env ?? process.env;
|
|
8122
|
-
const
|
|
8123
|
-
if (
|
|
8156
|
+
const platform7 = opts.platform ?? process.platform;
|
|
8157
|
+
if (platform7 !== "win32") return void 0;
|
|
8124
8158
|
const existing = normalizeShell(env["WRONGSTACK_SHELL"]);
|
|
8125
8159
|
if (existing) return existing;
|
|
8126
|
-
const chosen = resolveSessionShell(
|
|
8160
|
+
const chosen = resolveSessionShell(platform7, { get: (k) => env[k] }, { hasBinary: opts.hasBinary }) ?? "cmd";
|
|
8127
8161
|
env["WRONGSTACK_SHELL"] = chosen;
|
|
8128
8162
|
return chosen;
|
|
8129
8163
|
}
|
|
@@ -8989,6 +9023,18 @@ function parseKillCommand(command) {
|
|
|
8989
9023
|
originalCommand: command
|
|
8990
9024
|
};
|
|
8991
9025
|
}
|
|
9026
|
+
const wmicPidMatch = normalized.match(
|
|
9027
|
+
/^wmic\s+process\s+where\s+['"]?processid\s*=\s*['"]?(\d+)/i
|
|
9028
|
+
);
|
|
9029
|
+
if (wmicPidMatch?.[1]) {
|
|
9030
|
+
return {
|
|
9031
|
+
pid: parseInt(wmicPidMatch[1], 10),
|
|
9032
|
+
signal: "FORCE",
|
|
9033
|
+
isGroupKill: false,
|
|
9034
|
+
isAllKill: false,
|
|
9035
|
+
originalCommand: command
|
|
9036
|
+
};
|
|
9037
|
+
}
|
|
8992
9038
|
const killScriptMatch = normalized.match(SCRIPT_KILL_RE);
|
|
8993
9039
|
if (killScriptMatch) {
|
|
8994
9040
|
return {
|
|
@@ -9108,7 +9154,9 @@ async function isKillProtected(kill) {
|
|
|
9108
9154
|
return protectedPids.length > 0;
|
|
9109
9155
|
}
|
|
9110
9156
|
if (kill.pid !== void 0) {
|
|
9111
|
-
|
|
9157
|
+
if (await registry.shouldBlockKill(kill.pid)) return true;
|
|
9158
|
+
if (kill.pid === process.pid || kill.pid === process.ppid) return true;
|
|
9159
|
+
return false;
|
|
9112
9160
|
}
|
|
9113
9161
|
return false;
|
|
9114
9162
|
}
|
|
@@ -9155,8 +9203,8 @@ async function checkAndBlockKillCommand(command) {
|
|
|
9155
9203
|
|
|
9156
9204
|
// src/_shell-pick.ts
|
|
9157
9205
|
var POSIX_DEFAULT = "cmd";
|
|
9158
|
-
function pickShell(
|
|
9159
|
-
if (
|
|
9206
|
+
function pickShell(platform7, command, env) {
|
|
9207
|
+
if (platform7 !== "win32") return POSIX_DEFAULT;
|
|
9160
9208
|
const override = env.get("WRONGSTACK_SHELL")?.trim().toLowerCase();
|
|
9161
9209
|
if (override === "cmd" || override === "cmd.exe") return "cmd";
|
|
9162
9210
|
if (override === "powershell" || override === "powershell.exe") return "powershell";
|
|
@@ -9615,10 +9663,10 @@ var bashTool = {
|
|
|
9615
9663
|
queue.push(c);
|
|
9616
9664
|
}
|
|
9617
9665
|
};
|
|
9618
|
-
const next = () => new Promise((
|
|
9666
|
+
const next = () => new Promise((resolve25) => {
|
|
9619
9667
|
const c = queue.shift();
|
|
9620
|
-
if (c)
|
|
9621
|
-
else resolveNext =
|
|
9668
|
+
if (c) resolve25(c);
|
|
9669
|
+
else resolveNext = resolve25;
|
|
9622
9670
|
});
|
|
9623
9671
|
let lastFlush = Date.now();
|
|
9624
9672
|
const flush = () => {
|
|
@@ -10071,11 +10119,11 @@ var BrowserArtifactStore = class {
|
|
|
10071
10119
|
};
|
|
10072
10120
|
async function hashFile(target) {
|
|
10073
10121
|
const hash = createHash3("sha256");
|
|
10074
|
-
await new Promise((
|
|
10122
|
+
await new Promise((resolve25, reject) => {
|
|
10075
10123
|
const stream = createReadStream(target);
|
|
10076
10124
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
10077
10125
|
stream.once("error", reject);
|
|
10078
|
-
stream.once("end",
|
|
10126
|
+
stream.once("end", resolve25);
|
|
10079
10127
|
});
|
|
10080
10128
|
return hash.digest("hex");
|
|
10081
10129
|
}
|
|
@@ -10230,7 +10278,7 @@ var BrowserNetworkGuardProxy = class {
|
|
|
10230
10278
|
async start() {
|
|
10231
10279
|
if (this.url) return this.url;
|
|
10232
10280
|
if (this.startPromise) return this.startPromise;
|
|
10233
|
-
this.startPromise = new Promise((
|
|
10281
|
+
this.startPromise = new Promise((resolve25, reject) => {
|
|
10234
10282
|
const onError = (error) => {
|
|
10235
10283
|
this.server.off("listening", onListening);
|
|
10236
10284
|
reject(error);
|
|
@@ -10243,7 +10291,7 @@ var BrowserNetworkGuardProxy = class {
|
|
|
10243
10291
|
return;
|
|
10244
10292
|
}
|
|
10245
10293
|
this.url = `http://127.0.0.1:${address.port}`;
|
|
10246
|
-
|
|
10294
|
+
resolve25(this.url);
|
|
10247
10295
|
};
|
|
10248
10296
|
this.server.once("error", onError);
|
|
10249
10297
|
this.server.once("listening", onListening);
|
|
@@ -10258,7 +10306,7 @@ var BrowserNetworkGuardProxy = class {
|
|
|
10258
10306
|
for (const socket of this.sockets) socket.destroy();
|
|
10259
10307
|
this.sockets.clear();
|
|
10260
10308
|
if (!this.server.listening) return;
|
|
10261
|
-
await new Promise((
|
|
10309
|
+
await new Promise((resolve25) => this.server.close(() => resolve25()));
|
|
10262
10310
|
}
|
|
10263
10311
|
async forwardHttp(request2, response) {
|
|
10264
10312
|
try {
|
|
@@ -10831,7 +10879,7 @@ function pushBounded(target, value, limit) {
|
|
|
10831
10879
|
}
|
|
10832
10880
|
async function abortable(signal, operation, onAbort) {
|
|
10833
10881
|
signal.throwIfAborted();
|
|
10834
|
-
return new Promise((
|
|
10882
|
+
return new Promise((resolve25, reject) => {
|
|
10835
10883
|
let settled = false;
|
|
10836
10884
|
let aborting = false;
|
|
10837
10885
|
const finish = (fn) => {
|
|
@@ -10849,7 +10897,7 @@ async function abortable(signal, operation, onAbort) {
|
|
|
10849
10897
|
signal.addEventListener("abort", abort, { once: true });
|
|
10850
10898
|
operation().then(
|
|
10851
10899
|
(value) => {
|
|
10852
|
-
if (!aborting) finish(() =>
|
|
10900
|
+
if (!aborting) finish(() => resolve25(value));
|
|
10853
10901
|
},
|
|
10854
10902
|
(err) => {
|
|
10855
10903
|
if (!aborting) finish(() => reject(err));
|
|
@@ -14387,8 +14435,8 @@ function isProjectIndexServerHealth(value) {
|
|
|
14387
14435
|
return typeof health.checkedAt === "number" && typeof health.uptimeMs === "number" && typeof memory?.rss === "number" && typeof memory.heapUsed === "number" && typeof memory.heapTotal === "number" && typeof memory.external === "number" && typeof health.clients === "number" && typeof health.activeRequests === "number" && typeof health.activeWrites === "number" && typeof health.queuedWrites === "number" && typeof health.pendingExternalFiles === "number" && typeof health.watchingExternal === "boolean" && typeof activity?.indexing === "boolean" && typeof activity.currentFile === "number" && typeof activity.totalFiles === "number" && typeof activity.generation === "number";
|
|
14388
14436
|
}
|
|
14389
14437
|
function delay(ms) {
|
|
14390
|
-
return new Promise((
|
|
14391
|
-
const timer = setTimeout(
|
|
14438
|
+
return new Promise((resolve25) => {
|
|
14439
|
+
const timer = setTimeout(resolve25, ms);
|
|
14392
14440
|
timer.unref?.();
|
|
14393
14441
|
});
|
|
14394
14442
|
}
|
|
@@ -14594,7 +14642,7 @@ var ProjectServerConnection = class {
|
|
|
14594
14642
|
return Promise.reject(new Error("codebase-index server connection is not available"));
|
|
14595
14643
|
}
|
|
14596
14644
|
const id = this.nextId++;
|
|
14597
|
-
return new Promise((
|
|
14645
|
+
return new Promise((resolve25, reject) => {
|
|
14598
14646
|
const timer = setTimeout(() => {
|
|
14599
14647
|
const entry = this.pending.get(id);
|
|
14600
14648
|
if (!entry) return;
|
|
@@ -14617,7 +14665,7 @@ var ProjectServerConnection = class {
|
|
|
14617
14665
|
entry.reject(cancellationError(signal));
|
|
14618
14666
|
} : void 0;
|
|
14619
14667
|
this.pending.set(id, {
|
|
14620
|
-
resolve:
|
|
14668
|
+
resolve: resolve25,
|
|
14621
14669
|
reject,
|
|
14622
14670
|
timer,
|
|
14623
14671
|
signal,
|
|
@@ -14686,7 +14734,7 @@ var ProjectServerConnection = class {
|
|
|
14686
14734
|
this.binaryBuffer = [];
|
|
14687
14735
|
this.useBinary = false;
|
|
14688
14736
|
this.textDecoder = null;
|
|
14689
|
-
return new Promise((
|
|
14737
|
+
return new Promise((resolve25, reject) => {
|
|
14690
14738
|
const socket = net3.createConnection(this.endpoint);
|
|
14691
14739
|
this.socket = socket;
|
|
14692
14740
|
const timer = setTimeout(() => {
|
|
@@ -14698,7 +14746,7 @@ var ProjectServerConnection = class {
|
|
|
14698
14746
|
clearTimeout(timer);
|
|
14699
14747
|
this.connectResolve = null;
|
|
14700
14748
|
this.connectReject = null;
|
|
14701
|
-
|
|
14749
|
+
resolve25();
|
|
14702
14750
|
};
|
|
14703
14751
|
const finishReject = (error) => {
|
|
14704
14752
|
clearTimeout(timer);
|
|
@@ -15747,9 +15795,9 @@ var ParserWorkerPool = class {
|
|
|
15747
15795
|
for (let i = 0; i < files.length; i++) {
|
|
15748
15796
|
chunks[i % workerCount].push(files[i]);
|
|
15749
15797
|
}
|
|
15750
|
-
return new Promise((
|
|
15798
|
+
return new Promise((resolve25, reject) => {
|
|
15751
15799
|
this.pending.set(batchId, {
|
|
15752
|
-
resolve:
|
|
15800
|
+
resolve: resolve25,
|
|
15753
15801
|
reject,
|
|
15754
15802
|
accumulated: [],
|
|
15755
15803
|
expectedWorkers: workerCount,
|
|
@@ -15780,10 +15828,10 @@ var ParserWorkerPool = class {
|
|
|
15780
15828
|
await Promise.allSettled(
|
|
15781
15829
|
workers.map(
|
|
15782
15830
|
(w) => Promise.race([
|
|
15783
|
-
new Promise((
|
|
15784
|
-
w.once("exit", () =>
|
|
15831
|
+
new Promise((resolve25) => {
|
|
15832
|
+
w.once("exit", () => resolve25());
|
|
15785
15833
|
}),
|
|
15786
|
-
new Promise((
|
|
15834
|
+
new Promise((resolve25) => setTimeout(() => resolve25(), 2e3))
|
|
15787
15835
|
]).then(() => {
|
|
15788
15836
|
if (!w.threadId) return;
|
|
15789
15837
|
return w.terminate().catch(() => {
|
|
@@ -15844,7 +15892,7 @@ function shouldUseParserWorkerPool(candidateFileCount, parseBatchCount) {
|
|
|
15844
15892
|
return !isFrugalPerf() && candidateFileCount >= WORKER_POOL_THRESHOLD && parseBatchCount > 1;
|
|
15845
15893
|
}
|
|
15846
15894
|
function yieldEventLoop() {
|
|
15847
|
-
return new Promise((
|
|
15895
|
+
return new Promise((resolve25) => setImmediate(resolve25));
|
|
15848
15896
|
}
|
|
15849
15897
|
function throwIfAborted(signal) {
|
|
15850
15898
|
if (!signal?.aborted) return;
|
|
@@ -15876,7 +15924,7 @@ function normalizeComparablePath(value) {
|
|
|
15876
15924
|
return process.platform === "win32" ? resolved.toLowerCase() : resolved;
|
|
15877
15925
|
}
|
|
15878
15926
|
function gitOutput(projectRoot, args) {
|
|
15879
|
-
return new Promise((
|
|
15927
|
+
return new Promise((resolve25, reject) => {
|
|
15880
15928
|
execFile(
|
|
15881
15929
|
"git",
|
|
15882
15930
|
["-C", projectRoot, ...args],
|
|
@@ -15887,7 +15935,7 @@ function gitOutput(projectRoot, args) {
|
|
|
15887
15935
|
},
|
|
15888
15936
|
(error, stdout) => {
|
|
15889
15937
|
if (error) reject(error);
|
|
15890
|
-
else
|
|
15938
|
+
else resolve25(Buffer.isBuffer(stdout) ? stdout : Buffer.from(stdout));
|
|
15891
15939
|
}
|
|
15892
15940
|
);
|
|
15893
15941
|
});
|
|
@@ -16687,7 +16735,7 @@ function callIndexOp(op, args, opts) {
|
|
|
16687
16735
|
opts.signal.reason instanceof Error ? opts.signal.reason : new Error("Indexing cancelled")
|
|
16688
16736
|
);
|
|
16689
16737
|
}
|
|
16690
|
-
return new Promise((
|
|
16738
|
+
return new Promise((resolve25, reject) => {
|
|
16691
16739
|
const id = nextRpcId++;
|
|
16692
16740
|
const timer = setTimeout(() => {
|
|
16693
16741
|
pending.delete(id);
|
|
@@ -16709,7 +16757,7 @@ function callIndexOp(op, args, opts) {
|
|
|
16709
16757
|
pending.set(id, {
|
|
16710
16758
|
resolve: (v) => {
|
|
16711
16759
|
cleanup();
|
|
16712
|
-
|
|
16760
|
+
resolve25(v);
|
|
16713
16761
|
},
|
|
16714
16762
|
reject: (e) => {
|
|
16715
16763
|
cleanup();
|
|
@@ -20279,7 +20327,7 @@ function findGitDir(cwd) {
|
|
|
20279
20327
|
return null;
|
|
20280
20328
|
}
|
|
20281
20329
|
function runGit(args, cwd, signal) {
|
|
20282
|
-
return new Promise((
|
|
20330
|
+
return new Promise((resolve25) => {
|
|
20283
20331
|
let stdout = "";
|
|
20284
20332
|
let stderr = "";
|
|
20285
20333
|
const child = spawn7("git", args, {
|
|
@@ -20295,8 +20343,8 @@ function runGit(args, cwd, signal) {
|
|
|
20295
20343
|
child.stderr?.on("data", (c) => {
|
|
20296
20344
|
stderr += c.toString();
|
|
20297
20345
|
});
|
|
20298
|
-
child.on("close", (code) =>
|
|
20299
|
-
child.on("error", (e) =>
|
|
20346
|
+
child.on("close", (code) => resolve25({ stdout, stderr, exitCode: code ?? 0 }));
|
|
20347
|
+
child.on("error", (e) => resolve25({ stdout: "", stderr: e.message, exitCode: 1 }));
|
|
20300
20348
|
});
|
|
20301
20349
|
}
|
|
20302
20350
|
async function fileDiff(input, ctx, _signal) {
|
|
@@ -22611,7 +22659,7 @@ var execTool = {
|
|
|
22611
22659
|
}
|
|
22612
22660
|
};
|
|
22613
22661
|
function runCommand(cmd, args, cwd, timeout, signal, sessionId, danger) {
|
|
22614
|
-
return new Promise((
|
|
22662
|
+
return new Promise((resolve25) => {
|
|
22615
22663
|
let stdout = "";
|
|
22616
22664
|
let stderr = "";
|
|
22617
22665
|
let killed = false;
|
|
@@ -22619,7 +22667,7 @@ function runCommand(cmd, args, cwd, timeout, signal, sessionId, danger) {
|
|
|
22619
22667
|
const finish = (result) => {
|
|
22620
22668
|
if (resolvedOnce.value) return;
|
|
22621
22669
|
resolvedOnce.value = true;
|
|
22622
|
-
|
|
22670
|
+
resolve25(result);
|
|
22623
22671
|
};
|
|
22624
22672
|
const startedAt = Date.now();
|
|
22625
22673
|
let stdoutBytes = 0;
|
|
@@ -23295,10 +23343,10 @@ function parseFormatterCounts(fixer, output) {
|
|
|
23295
23343
|
};
|
|
23296
23344
|
}
|
|
23297
23345
|
async function detectFixer(cwd) {
|
|
23298
|
-
const
|
|
23346
|
+
const fs45 = await import("node:fs/promises");
|
|
23299
23347
|
const exists = async (file) => {
|
|
23300
23348
|
try {
|
|
23301
|
-
await
|
|
23349
|
+
await fs45.stat(`${cwd}/${file}`);
|
|
23302
23350
|
return true;
|
|
23303
23351
|
} catch {
|
|
23304
23352
|
return false;
|
|
@@ -23321,7 +23369,7 @@ async function detectFixer(cwd) {
|
|
|
23321
23369
|
if (await exists(cfg)) return "prettier";
|
|
23322
23370
|
}
|
|
23323
23371
|
try {
|
|
23324
|
-
const raw = await
|
|
23372
|
+
const raw = await fs45.readFile(`${cwd}/package.json`, "utf8");
|
|
23325
23373
|
const pkg = JSON.parse(raw);
|
|
23326
23374
|
if (pkg["prettier"] !== void 0) return "prettier";
|
|
23327
23375
|
} catch {
|
|
@@ -23589,7 +23637,7 @@ function buildArgs(input) {
|
|
|
23589
23637
|
}
|
|
23590
23638
|
}
|
|
23591
23639
|
function runGit2(args, cwd, signal) {
|
|
23592
|
-
return new Promise((
|
|
23640
|
+
return new Promise((resolve25) => {
|
|
23593
23641
|
let stdout = "";
|
|
23594
23642
|
let stderr = "";
|
|
23595
23643
|
const child = spawn9("git", args, {
|
|
@@ -23610,7 +23658,7 @@ function runGit2(args, cwd, signal) {
|
|
|
23610
23658
|
}
|
|
23611
23659
|
});
|
|
23612
23660
|
child.on("error", (err) => {
|
|
23613
|
-
|
|
23661
|
+
resolve25({
|
|
23614
23662
|
command: args[0],
|
|
23615
23663
|
stdout: normalizeCommandOutput(stdout),
|
|
23616
23664
|
stderr: err.message,
|
|
@@ -23619,7 +23667,7 @@ function runGit2(args, cwd, signal) {
|
|
|
23619
23667
|
});
|
|
23620
23668
|
});
|
|
23621
23669
|
child.on("close", (code) => {
|
|
23622
|
-
|
|
23670
|
+
resolve25({
|
|
23623
23671
|
command: args[0],
|
|
23624
23672
|
stdout: normalizeCommandOutput(stdout),
|
|
23625
23673
|
stderr: normalizeCommandOutput(stderr),
|
|
@@ -24032,7 +24080,7 @@ var grepTool = {
|
|
|
24032
24080
|
};
|
|
24033
24081
|
var rgAvailabilityCache;
|
|
24034
24082
|
function detectRg() {
|
|
24035
|
-
rgAvailabilityCache ??= new Promise((
|
|
24083
|
+
rgAvailabilityCache ??= new Promise((resolve25) => {
|
|
24036
24084
|
try {
|
|
24037
24085
|
const p = spawn10("rg", ["--version"], {
|
|
24038
24086
|
env: buildChildEnv5(),
|
|
@@ -24040,10 +24088,10 @@ function detectRg() {
|
|
|
24040
24088
|
signal: AbortSignal.timeout(1e4),
|
|
24041
24089
|
windowsHide: true
|
|
24042
24090
|
});
|
|
24043
|
-
p.on("error", () =>
|
|
24044
|
-
p.on("close", (code) =>
|
|
24091
|
+
p.on("error", () => resolve25(false));
|
|
24092
|
+
p.on("close", (code) => resolve25(code === 0));
|
|
24045
24093
|
} catch {
|
|
24046
|
-
|
|
24094
|
+
resolve25(false);
|
|
24047
24095
|
}
|
|
24048
24096
|
});
|
|
24049
24097
|
return rgAvailabilityCache;
|
|
@@ -25085,60 +25133,60 @@ function jmespathSearch(data, query) {
|
|
|
25085
25133
|
}
|
|
25086
25134
|
function validateJsonSchema(data, schema) {
|
|
25087
25135
|
const errors = [];
|
|
25088
|
-
function check(value, s,
|
|
25136
|
+
function check(value, s, path51) {
|
|
25089
25137
|
if (s["type"]) {
|
|
25090
25138
|
const expectedType = s["type"];
|
|
25091
25139
|
const actualType = Array.isArray(value) ? "array" : value === null ? "null" : typeof value;
|
|
25092
25140
|
if (expectedType === "integer") {
|
|
25093
|
-
if (!Number.isInteger(value)) errors.push(`${
|
|
25141
|
+
if (!Number.isInteger(value)) errors.push(`${path51}: expected integer, got ${actualType}`);
|
|
25094
25142
|
} else if (expectedType !== actualType) {
|
|
25095
|
-
errors.push(`${
|
|
25143
|
+
errors.push(`${path51}: expected ${expectedType}, got ${actualType}`);
|
|
25096
25144
|
}
|
|
25097
25145
|
}
|
|
25098
25146
|
if (typeof value === "string" && s["format"] === "uri" && value) {
|
|
25099
25147
|
try {
|
|
25100
25148
|
new URL(value);
|
|
25101
25149
|
} catch {
|
|
25102
|
-
errors.push(`${
|
|
25150
|
+
errors.push(`${path51}: not a valid URI`);
|
|
25103
25151
|
}
|
|
25104
25152
|
}
|
|
25105
25153
|
if (typeof value === "string" && s["pattern"]) {
|
|
25106
25154
|
const compiled = compileUserRegex(s["pattern"], "");
|
|
25107
25155
|
if (!compiled.ok) {
|
|
25108
|
-
errors.push(`${
|
|
25156
|
+
errors.push(`${path51}: invalid schema pattern \u2014 ${compiled.reason}`);
|
|
25109
25157
|
} else if (!compiled.regex.test(capSubject(value))) {
|
|
25110
|
-
errors.push(`${
|
|
25158
|
+
errors.push(`${path51}: does not match pattern ${s["pattern"]}`);
|
|
25111
25159
|
}
|
|
25112
25160
|
}
|
|
25113
25161
|
if (typeof value === "string" && s["minLength"] !== void 0 && value.length < s["minLength"]) {
|
|
25114
|
-
errors.push(`${
|
|
25162
|
+
errors.push(`${path51}: string too short (min ${s["minLength"]})`);
|
|
25115
25163
|
}
|
|
25116
25164
|
if (typeof value === "string" && s["maxLength"] !== void 0 && value.length > s["maxLength"]) {
|
|
25117
|
-
errors.push(`${
|
|
25165
|
+
errors.push(`${path51}: string too long (max ${s["maxLength"]})`);
|
|
25118
25166
|
}
|
|
25119
25167
|
if (typeof value === "number" && s["minimum"] !== void 0 && value < s["minimum"]) {
|
|
25120
|
-
errors.push(`${
|
|
25168
|
+
errors.push(`${path51}: below minimum ${s["minimum"]}`);
|
|
25121
25169
|
}
|
|
25122
25170
|
if (typeof value === "number" && s["maximum"] !== void 0 && value > s["maximum"]) {
|
|
25123
|
-
errors.push(`${
|
|
25171
|
+
errors.push(`${path51}: above maximum ${s["maximum"]}`);
|
|
25124
25172
|
}
|
|
25125
25173
|
if (Array.isArray(value) && s["items"] && Array.isArray(s["items"])) {
|
|
25126
25174
|
for (let i = 0; i < value.length; i++) {
|
|
25127
|
-
check(value[i], s["items"], `${
|
|
25175
|
+
check(value[i], s["items"], `${path51}[${i}]`);
|
|
25128
25176
|
}
|
|
25129
25177
|
}
|
|
25130
25178
|
if (typeof value === "object" && value !== null && !Array.isArray(value) && s["properties"]) {
|
|
25131
25179
|
const props = s["properties"];
|
|
25132
25180
|
for (const [k, propSchema] of Object.entries(props)) {
|
|
25133
|
-
check(value[k], propSchema, `${
|
|
25181
|
+
check(value[k], propSchema, `${path51}.${k}`);
|
|
25134
25182
|
}
|
|
25135
25183
|
}
|
|
25136
25184
|
}
|
|
25137
25185
|
check(data, schema, "$");
|
|
25138
25186
|
return { valid: errors.length === 0, errors };
|
|
25139
25187
|
}
|
|
25140
|
-
function simpleQuery(data,
|
|
25141
|
-
const parts =
|
|
25188
|
+
function simpleQuery(data, path51) {
|
|
25189
|
+
const parts = path51.replace(/\[(\d+)\]/g, ".$1").split(".").filter(Boolean);
|
|
25142
25190
|
let current = data;
|
|
25143
25191
|
for (const part of parts) {
|
|
25144
25192
|
if (current === null || current === void 0) return void 0;
|
|
@@ -28250,7 +28298,7 @@ async function dockerLogs(service, lines, filterRe, cwd, signal, since) {
|
|
|
28250
28298
|
};
|
|
28251
28299
|
}
|
|
28252
28300
|
args.push("--timestamps", service);
|
|
28253
|
-
return new Promise((
|
|
28301
|
+
return new Promise((resolve25) => {
|
|
28254
28302
|
let stdout = "";
|
|
28255
28303
|
let stderr = "";
|
|
28256
28304
|
const MAX = 2e5;
|
|
@@ -28266,7 +28314,7 @@ async function dockerLogs(service, lines, filterRe, cwd, signal, since) {
|
|
|
28266
28314
|
if (settled) return;
|
|
28267
28315
|
settled = true;
|
|
28268
28316
|
clearTimeout(timer);
|
|
28269
|
-
|
|
28317
|
+
resolve25(result);
|
|
28270
28318
|
};
|
|
28271
28319
|
const child = spawn11("docker", args, {
|
|
28272
28320
|
cwd,
|
|
@@ -28311,7 +28359,7 @@ async function dockerLogs(service, lines, filterRe, cwd, signal, since) {
|
|
|
28311
28359
|
}
|
|
28312
28360
|
var DOCKER_LOGS_TIMEOUT_MS = 3e3;
|
|
28313
28361
|
var MAX_TAIL_LINES = 1e5;
|
|
28314
|
-
async function fileLogs(
|
|
28362
|
+
async function fileLogs(path51, lines, filterRe) {
|
|
28315
28363
|
const { createInterface } = await import("node:readline");
|
|
28316
28364
|
const { createReadStream: createReadStream2 } = await import("node:fs");
|
|
28317
28365
|
const entries = [];
|
|
@@ -28320,7 +28368,7 @@ async function fileLogs(path50, lines, filterRe) {
|
|
|
28320
28368
|
let writeIdx = 0;
|
|
28321
28369
|
let totalLines = 0;
|
|
28322
28370
|
const rl = createInterface({
|
|
28323
|
-
input: createReadStream2(
|
|
28371
|
+
input: createReadStream2(path51),
|
|
28324
28372
|
crlfDelay: Number.POSITIVE_INFINITY
|
|
28325
28373
|
});
|
|
28326
28374
|
for await (const line of rl) {
|
|
@@ -28341,7 +28389,7 @@ async function fileLogs(path50, lines, filterRe) {
|
|
|
28341
28389
|
if (parsed) entries.push(parsed);
|
|
28342
28390
|
}
|
|
28343
28391
|
return {
|
|
28344
|
-
source:
|
|
28392
|
+
source: path51,
|
|
28345
28393
|
entries,
|
|
28346
28394
|
total: entries.length,
|
|
28347
28395
|
truncated: totalLines > effLines,
|
|
@@ -28483,7 +28531,7 @@ var outdatedTool = {
|
|
|
28483
28531
|
}
|
|
28484
28532
|
};
|
|
28485
28533
|
function runOutdated(manager, args, cwd, signal) {
|
|
28486
|
-
return new Promise((
|
|
28534
|
+
return new Promise((resolve25) => {
|
|
28487
28535
|
let stdout = "";
|
|
28488
28536
|
let stderr = "";
|
|
28489
28537
|
const MAX = 1e5;
|
|
@@ -28508,10 +28556,10 @@ function runOutdated(manager, args, cwd, signal) {
|
|
|
28508
28556
|
});
|
|
28509
28557
|
child.on("close", (code) => {
|
|
28510
28558
|
const result = parseOutdatedOutput(stdout, code ?? 0);
|
|
28511
|
-
|
|
28559
|
+
resolve25(result);
|
|
28512
28560
|
});
|
|
28513
28561
|
child.on("error", (e) => {
|
|
28514
|
-
|
|
28562
|
+
resolve25({
|
|
28515
28563
|
exit_code: 1,
|
|
28516
28564
|
packages: [],
|
|
28517
28565
|
total: 0,
|
|
@@ -28830,7 +28878,7 @@ function runPatch(args, cwd, signal, fallback) {
|
|
|
28830
28878
|
});
|
|
28831
28879
|
}
|
|
28832
28880
|
function runPatchProcess(command, args, cwd, signal) {
|
|
28833
|
-
return new Promise((
|
|
28881
|
+
return new Promise((resolve25) => {
|
|
28834
28882
|
let stdout = "";
|
|
28835
28883
|
let stderr = "";
|
|
28836
28884
|
const env = { ...buildChildEnv8(), LANG: "C", LC_ALL: "C" };
|
|
@@ -28849,11 +28897,11 @@ function runPatchProcess(command, args, cwd, signal) {
|
|
|
28849
28897
|
});
|
|
28850
28898
|
child.on(
|
|
28851
28899
|
"close",
|
|
28852
|
-
(code) =>
|
|
28900
|
+
(code) => resolve25({ exitCode: code ?? 1, stdout, stderr, unavailable: false })
|
|
28853
28901
|
);
|
|
28854
28902
|
child.on(
|
|
28855
28903
|
"error",
|
|
28856
|
-
(e) =>
|
|
28904
|
+
(e) => resolve25({
|
|
28857
28905
|
exitCode: 1,
|
|
28858
28906
|
stdout: "",
|
|
28859
28907
|
stderr: e.message,
|
|
@@ -29642,9 +29690,428 @@ function mkResult(plan, ok, message, todos) {
|
|
|
29642
29690
|
return result;
|
|
29643
29691
|
}
|
|
29644
29692
|
|
|
29693
|
+
// src/pwsh.ts
|
|
29694
|
+
import { spawn as spawn14 } from "node:child_process";
|
|
29695
|
+
import * as fs36 from "node:fs";
|
|
29696
|
+
import * as os10 from "node:os";
|
|
29697
|
+
import * as path43 from "node:path";
|
|
29698
|
+
import { StringDecoder as StringDecoder3 } from "node:string_decoder";
|
|
29699
|
+
import {
|
|
29700
|
+
emitProcessCompleted as emitProcessCompleted4,
|
|
29701
|
+
emitProcessOutput as emitProcessOutput4,
|
|
29702
|
+
emitProcessStarted as emitProcessStarted4
|
|
29703
|
+
} from "@wrongstack/core/observability";
|
|
29704
|
+
init_output_spool();
|
|
29705
|
+
init_util();
|
|
29706
|
+
init_process_registry();
|
|
29707
|
+
init_win32_resolve();
|
|
29708
|
+
var MAX_OUTPUT4 = 32768;
|
|
29709
|
+
var DEFAULT_TIMEOUT_MS4 = 3e5;
|
|
29710
|
+
var STREAM_FLUSH_INTERVAL_MS2 = 200;
|
|
29711
|
+
var STREAM_FLUSH_BYTES2 = 4 * 1024;
|
|
29712
|
+
var MAX_QUEUE_CHUNKS2 = 500;
|
|
29713
|
+
var PWSH_TOOL_DESCRIPTION = "Execute a PowerShell command (`pwsh -Command`) in a fresh process on Windows and return its stdout/stderr. Stateless per call: pass `workdir` instead of using `cd`.";
|
|
29714
|
+
var PWSH_TOOL_USAGE_HINT = "Best practices & sandbox protocol for pwsh:\n- **Stateless**: No cwd, variables, or functions persist between calls. Use `workdir` to set the directory.\n- **Paths & Environs**: Use native Windows paths (`C:\\...`) and read env vars via `$env:NAME` (and `$env:DSH_*`).\n- **Exit Codes**: Non-zero exits are reported as `[exit code: N]`. On Windows, a force-killed command settles as exit code 1 (interruption).\n- **Background**: Set `run_in_background: true` for long-running processes (returns job id; manage via job_output/job_kill).\n- **Sandboxing**: Under read-only sandbox, pwsh runs in `ConstrainedLanguage` mode (prefer cmdlets, basic types; .NET reflection and COM fail). Workspace-write runs in `FullLanguage`.\n- **Escalation**: If denied by policy (`[sandbox: file access denied]`), retry once with `sandbox_permissions` plus a one-sentence `justification`.";
|
|
29715
|
+
function wrapPwshCommand(command) {
|
|
29716
|
+
const bootstrap = "[Console]::OutputEncoding = [System.Text.Encoding]::UTF8;$ProgressPreference = 'SilentlyContinue';$ConfirmPreference = 'None';$WhatIfPreference = $false";
|
|
29717
|
+
return `${bootstrap}
|
|
29718
|
+
$ErrorActionPreference = 'Stop'
|
|
29719
|
+
${command}
|
|
29720
|
+
if ($LASTEXITCODE -is [int]) { exit $LASTEXITCODE }`;
|
|
29721
|
+
}
|
|
29722
|
+
var pwshTool = {
|
|
29723
|
+
name: "pwsh",
|
|
29724
|
+
category: "Shell",
|
|
29725
|
+
description: PWSH_TOOL_DESCRIPTION,
|
|
29726
|
+
usageHint: PWSH_TOOL_USAGE_HINT,
|
|
29727
|
+
selection: {
|
|
29728
|
+
doNotUseWhen: "the command is an allowlisted single binary (node, git, pnpm, tsc) needing no shell expansion or pipelines.",
|
|
29729
|
+
useInstead: ["exec"]
|
|
29730
|
+
},
|
|
29731
|
+
permission: "confirm",
|
|
29732
|
+
mutating: true,
|
|
29733
|
+
riskTier: "destructive",
|
|
29734
|
+
icon: "terminal",
|
|
29735
|
+
subjectKey: "command",
|
|
29736
|
+
capabilities: ["shell.arbitrary"],
|
|
29737
|
+
timeoutMs: 61e4,
|
|
29738
|
+
maxOutputBytes: MAX_OUTPUT4,
|
|
29739
|
+
estimatedDurationMs: 3e4,
|
|
29740
|
+
inputSchema: {
|
|
29741
|
+
type: "object",
|
|
29742
|
+
properties: {
|
|
29743
|
+
command: {
|
|
29744
|
+
type: "string",
|
|
29745
|
+
description: "The exact PowerShell command or script block to run."
|
|
29746
|
+
},
|
|
29747
|
+
workdir: {
|
|
29748
|
+
type: "string",
|
|
29749
|
+
description: "Absolute or project-relative path to the working directory for this command. Defaults to session working directory."
|
|
29750
|
+
},
|
|
29751
|
+
timeout_ms: {
|
|
29752
|
+
type: "integer",
|
|
29753
|
+
description: "Optional timeout for this specific command in milliseconds (default 300000, max 600000)."
|
|
29754
|
+
},
|
|
29755
|
+
run_in_background: {
|
|
29756
|
+
type: "boolean",
|
|
29757
|
+
description: "If true, launch the process in the background and return the job ID / PID immediately."
|
|
29758
|
+
},
|
|
29759
|
+
background: {
|
|
29760
|
+
type: "boolean",
|
|
29761
|
+
description: "Alias for run_in_background."
|
|
29762
|
+
},
|
|
29763
|
+
sandbox_permissions: {
|
|
29764
|
+
type: "string",
|
|
29765
|
+
description: "Escalation mode if retrying a sandbox-denied command (e.g., workspace-write)."
|
|
29766
|
+
},
|
|
29767
|
+
justification: {
|
|
29768
|
+
type: "string",
|
|
29769
|
+
description: "One-sentence justification when retrying a denied command with sandbox_permissions."
|
|
29770
|
+
}
|
|
29771
|
+
},
|
|
29772
|
+
required: ["command"]
|
|
29773
|
+
},
|
|
29774
|
+
async execute(input, ctx, opts) {
|
|
29775
|
+
let final;
|
|
29776
|
+
const executeStream = pwshTool.executeStream;
|
|
29777
|
+
if (!executeStream) throw new Error("pwshTool: stream execution unavailable");
|
|
29778
|
+
for await (const ev of executeStream(input, ctx, opts)) {
|
|
29779
|
+
if (ev.type === "final") final = ev.output;
|
|
29780
|
+
}
|
|
29781
|
+
if (!final) throw new Error("pwsh: stream ended without final event");
|
|
29782
|
+
return final;
|
|
29783
|
+
},
|
|
29784
|
+
async *executeStream(input, ctx, opts) {
|
|
29785
|
+
if (!input?.command) throw new Error("pwsh: command is required");
|
|
29786
|
+
const isBackground = !!(input.run_in_background || input.background);
|
|
29787
|
+
const registry = getProcessRegistry();
|
|
29788
|
+
if (!registry.beforeCall(isBackground)) {
|
|
29789
|
+
yield {
|
|
29790
|
+
type: "final",
|
|
29791
|
+
output: {
|
|
29792
|
+
output: "",
|
|
29793
|
+
exit_code: 1,
|
|
29794
|
+
timed_out: false,
|
|
29795
|
+
pid: null,
|
|
29796
|
+
error: "pwsh: circuit breaker open \u2014 too many consecutive failures or slow calls. Use /kill to inspect or /kill reset to recover."
|
|
29797
|
+
}
|
|
29798
|
+
};
|
|
29799
|
+
return;
|
|
29800
|
+
}
|
|
29801
|
+
const killCheck = await checkAndBlockKillCommand(input.command);
|
|
29802
|
+
if (killCheck.blocked) {
|
|
29803
|
+
yield {
|
|
29804
|
+
type: "final",
|
|
29805
|
+
output: {
|
|
29806
|
+
output: "",
|
|
29807
|
+
exit_code: 1,
|
|
29808
|
+
timed_out: false,
|
|
29809
|
+
pid: null,
|
|
29810
|
+
error: `pwsh: ${killCheck.reason}`
|
|
29811
|
+
}
|
|
29812
|
+
};
|
|
29813
|
+
return;
|
|
29814
|
+
}
|
|
29815
|
+
const isWin5 = os10.platform() === "win32";
|
|
29816
|
+
const bin = isWin5 ? resolvePowerShell("pwsh.exe") : "pwsh";
|
|
29817
|
+
const args = shellArgs("pwsh");
|
|
29818
|
+
const stdinBody = wrapPwshCommand(input.command);
|
|
29819
|
+
const env = buildChildEnv2(ctx.session?.id);
|
|
29820
|
+
let targetCwd = ctx.workingDir ?? ctx.projectRoot;
|
|
29821
|
+
if (input.workdir) {
|
|
29822
|
+
const resolved = path43.isAbsolute(input.workdir) ? input.workdir : path43.resolve(ctx.projectRoot, input.workdir);
|
|
29823
|
+
if (fs36.existsSync(resolved)) {
|
|
29824
|
+
targetCwd = resolved;
|
|
29825
|
+
}
|
|
29826
|
+
}
|
|
29827
|
+
const startedAt = Date.now();
|
|
29828
|
+
const detached = !isWin5;
|
|
29829
|
+
if (isBackground) {
|
|
29830
|
+
const child2 = spawn14(bin, args, {
|
|
29831
|
+
cwd: targetCwd,
|
|
29832
|
+
env,
|
|
29833
|
+
detached,
|
|
29834
|
+
stdio: ["pipe", "ignore", "ignore"],
|
|
29835
|
+
windowsHide: true
|
|
29836
|
+
});
|
|
29837
|
+
if (child2.stdin) {
|
|
29838
|
+
child2.stdin.write(stdinBody);
|
|
29839
|
+
child2.stdin.end();
|
|
29840
|
+
}
|
|
29841
|
+
const pid2 = child2.pid;
|
|
29842
|
+
if (typeof pid2 === "number") {
|
|
29843
|
+
registry.register({
|
|
29844
|
+
pid: pid2,
|
|
29845
|
+
name: "pwsh",
|
|
29846
|
+
command: redactCommand(input.command),
|
|
29847
|
+
startedAt: Date.now(),
|
|
29848
|
+
sessionId: ctx.session?.id,
|
|
29849
|
+
child: child2,
|
|
29850
|
+
processGroupLeader: detached && child2.pid === pid2,
|
|
29851
|
+
background: true
|
|
29852
|
+
});
|
|
29853
|
+
child2.on("close", () => registry.unregister(pid2));
|
|
29854
|
+
child2.on("error", () => {
|
|
29855
|
+
registry.unregister(pid2);
|
|
29856
|
+
registry.afterCall(Date.now() - startedAt, true, isBackground);
|
|
29857
|
+
});
|
|
29858
|
+
child2.unref();
|
|
29859
|
+
const jobId = `job_${pid2}`;
|
|
29860
|
+
ctx.recordSideEffect?.({
|
|
29861
|
+
toolUseId: `pwsh-bg-${Date.now()}`,
|
|
29862
|
+
toolName: "pwsh",
|
|
29863
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
29864
|
+
input: { command: redactCommand(input.command), background: true },
|
|
29865
|
+
outcome: `started background job ${jobId} (PID: ${pid2})`,
|
|
29866
|
+
risk: "shell"
|
|
29867
|
+
});
|
|
29868
|
+
yield {
|
|
29869
|
+
type: "final",
|
|
29870
|
+
output: {
|
|
29871
|
+
output: `Background job started: ${jobId} (PID: ${pid2})
|
|
29872
|
+
Working directory: ${targetCwd}`,
|
|
29873
|
+
exit_code: null,
|
|
29874
|
+
timed_out: false,
|
|
29875
|
+
pid: pid2,
|
|
29876
|
+
job_id: jobId
|
|
29877
|
+
}
|
|
29878
|
+
};
|
|
29879
|
+
return;
|
|
29880
|
+
}
|
|
29881
|
+
yield {
|
|
29882
|
+
type: "final",
|
|
29883
|
+
output: {
|
|
29884
|
+
output: "",
|
|
29885
|
+
exit_code: 1,
|
|
29886
|
+
timed_out: false,
|
|
29887
|
+
pid: null,
|
|
29888
|
+
error: "pwsh: failed to obtain PID for background process"
|
|
29889
|
+
}
|
|
29890
|
+
};
|
|
29891
|
+
return;
|
|
29892
|
+
}
|
|
29893
|
+
const spool = createOutputSpool({ tool: "pwsh", thresholdBytes: MAX_OUTPUT4 });
|
|
29894
|
+
const child = spawn14(bin, args, {
|
|
29895
|
+
cwd: targetCwd,
|
|
29896
|
+
env,
|
|
29897
|
+
detached,
|
|
29898
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
29899
|
+
windowsHide: true
|
|
29900
|
+
});
|
|
29901
|
+
const pid = child.pid;
|
|
29902
|
+
let stdoutBytes = 0;
|
|
29903
|
+
let stderrBytes = 0;
|
|
29904
|
+
let telemetryCompleted = false;
|
|
29905
|
+
emitProcessStarted4({
|
|
29906
|
+
...pid !== void 0 ? { pid } : {},
|
|
29907
|
+
parentPid: process.pid,
|
|
29908
|
+
command: redactCommand(`${bin} ${args.join(" ")}`),
|
|
29909
|
+
args: redactCommand(args.join(" ")).split(" ").filter(Boolean),
|
|
29910
|
+
cwd: targetCwd,
|
|
29911
|
+
background: false,
|
|
29912
|
+
startedAt: new Date(startedAt).toISOString()
|
|
29913
|
+
});
|
|
29914
|
+
const completeForeground = (exitCode, sig) => {
|
|
29915
|
+
if (telemetryCompleted) return;
|
|
29916
|
+
telemetryCompleted = true;
|
|
29917
|
+
emitProcessCompleted4({
|
|
29918
|
+
...pid !== void 0 ? { pid } : {},
|
|
29919
|
+
exitCode,
|
|
29920
|
+
...sig ? { signal: sig } : {},
|
|
29921
|
+
durationMs: Date.now() - startedAt,
|
|
29922
|
+
stdoutBytes,
|
|
29923
|
+
stderrBytes,
|
|
29924
|
+
timedOut,
|
|
29925
|
+
endedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
29926
|
+
});
|
|
29927
|
+
};
|
|
29928
|
+
if (typeof pid === "number") {
|
|
29929
|
+
registry.register({
|
|
29930
|
+
pid,
|
|
29931
|
+
name: "pwsh",
|
|
29932
|
+
command: redactCommand(input.command),
|
|
29933
|
+
startedAt: Date.now(),
|
|
29934
|
+
sessionId: ctx.session?.id,
|
|
29935
|
+
child,
|
|
29936
|
+
processGroupLeader: detached && child.pid === pid
|
|
29937
|
+
});
|
|
29938
|
+
}
|
|
29939
|
+
if (child.stdin) {
|
|
29940
|
+
child.stdin.write(stdinBody);
|
|
29941
|
+
child.stdin.end();
|
|
29942
|
+
}
|
|
29943
|
+
const timeoutMs = Math.min(
|
|
29944
|
+
Math.max(1e3, input.timeout_ms ?? DEFAULT_TIMEOUT_MS4),
|
|
29945
|
+
6e5
|
|
29946
|
+
);
|
|
29947
|
+
let timedOut = false;
|
|
29948
|
+
const timers = [];
|
|
29949
|
+
const killWithTimeout = (timeout) => {
|
|
29950
|
+
if (isWin5) {
|
|
29951
|
+
if (typeof child.pid === "number" && child.exitCode === null) {
|
|
29952
|
+
const attempted = registry.kill(child.pid, { force: true, graceMs: timeout });
|
|
29953
|
+
if (!attempted) {
|
|
29954
|
+
try {
|
|
29955
|
+
child.kill();
|
|
29956
|
+
} catch {
|
|
29957
|
+
}
|
|
29958
|
+
}
|
|
29959
|
+
}
|
|
29960
|
+
return;
|
|
29961
|
+
}
|
|
29962
|
+
if (typeof child.pid === "number") {
|
|
29963
|
+
registry.kill(child.pid, { graceMs: timeout });
|
|
29964
|
+
} else {
|
|
29965
|
+
try {
|
|
29966
|
+
child.kill("SIGTERM");
|
|
29967
|
+
} catch {
|
|
29968
|
+
}
|
|
29969
|
+
}
|
|
29970
|
+
};
|
|
29971
|
+
const timer = setTimeout(() => {
|
|
29972
|
+
timedOut = true;
|
|
29973
|
+
killWithTimeout(2e3);
|
|
29974
|
+
}, timeoutMs);
|
|
29975
|
+
timers.push(timer);
|
|
29976
|
+
const onAbort = () => killWithTimeout(2e3);
|
|
29977
|
+
if (opts.signal.aborted) onAbort();
|
|
29978
|
+
else opts.signal.addEventListener("abort", onAbort, { once: true });
|
|
29979
|
+
const queue = [];
|
|
29980
|
+
let resolveNext = null;
|
|
29981
|
+
const push = (c) => {
|
|
29982
|
+
if (resolveNext) {
|
|
29983
|
+
const r = resolveNext;
|
|
29984
|
+
resolveNext = null;
|
|
29985
|
+
r(c);
|
|
29986
|
+
} else {
|
|
29987
|
+
queue.push(c);
|
|
29988
|
+
}
|
|
29989
|
+
};
|
|
29990
|
+
const next = () => new Promise((resolve25) => {
|
|
29991
|
+
const c = queue.shift();
|
|
29992
|
+
if (c) resolve25(c);
|
|
29993
|
+
else resolveNext = resolve25;
|
|
29994
|
+
});
|
|
29995
|
+
let buf = "";
|
|
29996
|
+
let pending2 = "";
|
|
29997
|
+
let lastFlush = Date.now();
|
|
29998
|
+
const flush = () => {
|
|
29999
|
+
if (pending2.length === 0) return null;
|
|
30000
|
+
const text = pending2;
|
|
30001
|
+
pending2 = "";
|
|
30002
|
+
lastFlush = Date.now();
|
|
30003
|
+
return text;
|
|
30004
|
+
};
|
|
30005
|
+
let paused = false;
|
|
30006
|
+
const pauseIfFlooded = () => {
|
|
30007
|
+
if (!paused && queue.length >= MAX_QUEUE_CHUNKS2) {
|
|
30008
|
+
paused = true;
|
|
30009
|
+
child.stdout?.pause();
|
|
30010
|
+
child.stderr?.pause();
|
|
30011
|
+
}
|
|
30012
|
+
};
|
|
30013
|
+
const resumeIfDrained = () => {
|
|
30014
|
+
if (paused && queue.length < MAX_QUEUE_CHUNKS2) {
|
|
30015
|
+
paused = false;
|
|
30016
|
+
child.stdout?.resume();
|
|
30017
|
+
child.stderr?.resume();
|
|
30018
|
+
}
|
|
30019
|
+
};
|
|
30020
|
+
const stdoutDecoder = new StringDecoder3("utf8");
|
|
30021
|
+
const stderrDecoder = new StringDecoder3("utf8");
|
|
30022
|
+
const onData = (chunk, stream) => {
|
|
30023
|
+
const text = (stream === "stdout" ? stdoutDecoder : stderrDecoder).write(chunk);
|
|
30024
|
+
if (stream === "stdout") stdoutBytes += chunk.byteLength;
|
|
30025
|
+
else stderrBytes += chunk.byteLength;
|
|
30026
|
+
emitProcessOutput4({ pid: pid ?? 0, stream, chunk });
|
|
30027
|
+
if (buf.length < MAX_OUTPUT4) {
|
|
30028
|
+
buf += text.slice(0, MAX_OUTPUT4 - buf.length);
|
|
30029
|
+
}
|
|
30030
|
+
spool.write(text);
|
|
30031
|
+
pending2 += text;
|
|
30032
|
+
push({ kind: "data", text });
|
|
30033
|
+
pauseIfFlooded();
|
|
30034
|
+
};
|
|
30035
|
+
child.stdout?.on("data", (chunk) => onData(chunk, "stdout"));
|
|
30036
|
+
child.stderr?.on("data", (chunk) => onData(chunk, "stderr"));
|
|
30037
|
+
child.on("error", (err) => {
|
|
30038
|
+
for (const t of timers) clearTimeout(t);
|
|
30039
|
+
registry.afterCall(Date.now() - startedAt, true);
|
|
30040
|
+
completeForeground(1);
|
|
30041
|
+
push({ kind: "error", err });
|
|
30042
|
+
});
|
|
30043
|
+
child.on("close", (code, signal) => {
|
|
30044
|
+
for (const t of timers) clearTimeout(t);
|
|
30045
|
+
if (typeof pid === "number") registry.unregister(pid);
|
|
30046
|
+
registry.afterCall(Date.now() - startedAt, code !== 0 && code !== null);
|
|
30047
|
+
completeForeground(timedOut ? 124 : code ?? (signal ? 1 : 0), signal ?? void 0);
|
|
30048
|
+
const tail = stdoutDecoder.end() + stderrDecoder.end();
|
|
30049
|
+
if (tail) {
|
|
30050
|
+
if (buf.length < MAX_OUTPUT4) buf += tail.slice(0, MAX_OUTPUT4 - buf.length);
|
|
30051
|
+
spool.write(tail);
|
|
30052
|
+
pending2 += tail;
|
|
30053
|
+
}
|
|
30054
|
+
push({ kind: "end", code });
|
|
30055
|
+
});
|
|
30056
|
+
try {
|
|
30057
|
+
while (true) {
|
|
30058
|
+
const c = await next();
|
|
30059
|
+
resumeIfDrained();
|
|
30060
|
+
if (c.kind === "error") throw c.err;
|
|
30061
|
+
if (c.kind === "end") {
|
|
30062
|
+
const remainder = flush();
|
|
30063
|
+
if (remainder !== null) {
|
|
30064
|
+
yield { type: "partial_output", text: remainder };
|
|
30065
|
+
}
|
|
30066
|
+
const spooled = spool.finalize();
|
|
30067
|
+
let formattedOutput = normalizeCommandOutput(buf);
|
|
30068
|
+
if (c.code !== null && c.code !== 0 && !timedOut) {
|
|
30069
|
+
if (!formattedOutput.includes(`[exit code: ${c.code}]`)) {
|
|
30070
|
+
formattedOutput = formattedOutput ? `${formattedOutput}
|
|
30071
|
+
[exit code: ${c.code}]` : `[exit code: ${c.code}]`;
|
|
30072
|
+
}
|
|
30073
|
+
}
|
|
30074
|
+
const hint = !timedOut && typeof c.code === "number" && c.code !== 0 ? diagnoseBashism(input.command, "pwsh") : void 0;
|
|
30075
|
+
const danger = detectDanger("pwsh", [input.command]);
|
|
30076
|
+
const cautionText = danger.level === "caution" && danger.reasons.length > 0 ? `
|
|
30077
|
+
[caution: ${danger.reasons.join("; ")}]` : "";
|
|
30078
|
+
const finalResultText = formattedOutput + (spooled ? spoolNote(spooled) : "") + (hint ? `
|
|
30079
|
+
|
|
30080
|
+
${hint}` : "") + cautionText;
|
|
30081
|
+
ctx.recordSideEffect?.({
|
|
30082
|
+
toolUseId: `pwsh-${Date.now()}`,
|
|
30083
|
+
toolName: "pwsh",
|
|
30084
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
30085
|
+
input: { command: redactCommand(input.command) },
|
|
30086
|
+
outcome: timedOut ? `timed out (exit ${c.code})` : `exit ${c.code}`,
|
|
30087
|
+
risk: "shell"
|
|
30088
|
+
});
|
|
30089
|
+
yield {
|
|
30090
|
+
type: "final",
|
|
30091
|
+
output: {
|
|
30092
|
+
output: finalResultText,
|
|
30093
|
+
exit_code: timedOut ? 1 : c.code,
|
|
30094
|
+
timed_out: timedOut,
|
|
30095
|
+
pid
|
|
30096
|
+
}
|
|
30097
|
+
};
|
|
30098
|
+
return;
|
|
30099
|
+
}
|
|
30100
|
+
const now2 = Date.now();
|
|
30101
|
+
if (pending2.length >= STREAM_FLUSH_BYTES2 || now2 - lastFlush >= STREAM_FLUSH_INTERVAL_MS2) {
|
|
30102
|
+
const text = flush();
|
|
30103
|
+
if (text) yield { type: "partial_output", text };
|
|
30104
|
+
}
|
|
30105
|
+
}
|
|
30106
|
+
} finally {
|
|
30107
|
+
for (const t of timers) clearTimeout(t);
|
|
30108
|
+
}
|
|
30109
|
+
}
|
|
30110
|
+
};
|
|
30111
|
+
|
|
29645
30112
|
// src/read.ts
|
|
29646
30113
|
init_util();
|
|
29647
|
-
import * as
|
|
30114
|
+
import * as fs37 from "node:fs/promises";
|
|
29648
30115
|
import { FsError, ToolValidationError as ToolValidationError8 } from "@wrongstack/core/types";
|
|
29649
30116
|
import { toErrorMessage as toErrorMessage15 } from "@wrongstack/core/utils";
|
|
29650
30117
|
var ADVANCED_MODE_META_KEY = "tools.read.advancedMode";
|
|
@@ -29704,7 +30171,7 @@ var readTool = {
|
|
|
29704
30171
|
const shouldIncludeSymbols = input.includeSymbols === true || input.includeSymbols !== false && ctx.meta[ADVANCED_MODE_META_KEY] === true;
|
|
29705
30172
|
let stat22;
|
|
29706
30173
|
try {
|
|
29707
|
-
stat22 = await
|
|
30174
|
+
stat22 = await fs37.stat(absPath);
|
|
29708
30175
|
} catch (err) {
|
|
29709
30176
|
const code = err.code;
|
|
29710
30177
|
if (code === "ENOENT") {
|
|
@@ -29756,7 +30223,7 @@ var readTool = {
|
|
|
29756
30223
|
...symResult2?.symbols ? { symbols: symResult2.symbols } : {}
|
|
29757
30224
|
};
|
|
29758
30225
|
}
|
|
29759
|
-
const buf = await
|
|
30226
|
+
const buf = await fs37.readFile(absPath);
|
|
29760
30227
|
if (isBinaryBuffer(buf)) {
|
|
29761
30228
|
throw new FsError({
|
|
29762
30229
|
message: `read: "${input.path}" appears to be binary`,
|
|
@@ -29922,9 +30389,9 @@ ${interesting.join("\n")}` : "symbols/imports: (none detected)"
|
|
|
29922
30389
|
}
|
|
29923
30390
|
|
|
29924
30391
|
// src/replace.ts
|
|
29925
|
-
import { spawn as
|
|
29926
|
-
import * as
|
|
29927
|
-
import * as
|
|
30392
|
+
import { spawn as spawn15 } from "node:child_process";
|
|
30393
|
+
import * as fs38 from "node:fs/promises";
|
|
30394
|
+
import * as path44 from "node:path";
|
|
29928
30395
|
import { ToolValidationError as ToolValidationError9 } from "@wrongstack/core/types";
|
|
29929
30396
|
import {
|
|
29930
30397
|
atomicWrite as atomicWrite4,
|
|
@@ -30007,14 +30474,14 @@ var replaceTool = {
|
|
|
30007
30474
|
const dryRun = input.dry_run ?? true;
|
|
30008
30475
|
const filesInput = Array.isArray(input.files) ? input.files.join(",") : input.files;
|
|
30009
30476
|
const fileList = await resolveFiles2(filesInput, ctx, globRe);
|
|
30010
|
-
const realRoot = await
|
|
30477
|
+
const realRoot = await fs38.realpath(ctx.projectRoot).catch(() => ctx.projectRoot);
|
|
30011
30478
|
const results = [];
|
|
30012
30479
|
let totalReplacements = 0;
|
|
30013
30480
|
let diffBytesUsed = 0;
|
|
30014
30481
|
let diffsOmitted = 0;
|
|
30015
30482
|
let diffsTruncated = 0;
|
|
30016
30483
|
for (const absPath of fileList) {
|
|
30017
|
-
const lstat2 = await
|
|
30484
|
+
const lstat2 = await fs38.lstat(absPath).catch((err) => {
|
|
30018
30485
|
if (err.code === "ENOENT") return null;
|
|
30019
30486
|
throw err;
|
|
30020
30487
|
});
|
|
@@ -30022,17 +30489,17 @@ var replaceTool = {
|
|
|
30022
30489
|
if (lstat2.isSymbolicLink()) continue;
|
|
30023
30490
|
let realPath;
|
|
30024
30491
|
try {
|
|
30025
|
-
realPath = await
|
|
30492
|
+
realPath = await fs38.realpath(absPath);
|
|
30026
30493
|
} catch {
|
|
30027
30494
|
continue;
|
|
30028
30495
|
}
|
|
30029
|
-
const rel =
|
|
30030
|
-
if (rel.startsWith("..") ||
|
|
30031
|
-
const stat22 = await
|
|
30496
|
+
const rel = path44.relative(realRoot, realPath);
|
|
30497
|
+
if (rel.startsWith("..") || path44.isAbsolute(rel)) continue;
|
|
30498
|
+
const stat22 = await fs38.stat(realPath).catch(() => null);
|
|
30032
30499
|
if (!stat22?.isFile()) continue;
|
|
30033
30500
|
let content;
|
|
30034
30501
|
try {
|
|
30035
|
-
const buf = await
|
|
30502
|
+
const buf = await fs38.readFile(realPath);
|
|
30036
30503
|
if (isBinaryBuffer(buf)) continue;
|
|
30037
30504
|
content = buf.toString("utf8");
|
|
30038
30505
|
} catch {
|
|
@@ -30055,7 +30522,7 @@ var replaceTool = {
|
|
|
30055
30522
|
if (!dryRun) {
|
|
30056
30523
|
const newContent = toStyle2(newContentLf, style);
|
|
30057
30524
|
await atomicWrite4(realPath, newContent, { mode: stat22.mode & 511 });
|
|
30058
|
-
const written = await
|
|
30525
|
+
const written = await fs38.stat(realPath).catch(() => null);
|
|
30059
30526
|
if (written) {
|
|
30060
30527
|
ctx.recordRead?.(realPath, written.mtimeMs, "write", sha256hex(newContent));
|
|
30061
30528
|
}
|
|
@@ -30155,8 +30622,8 @@ async function resolveFiles2(filesInput, ctx, extraGlob) {
|
|
|
30155
30622
|
const resolved = [];
|
|
30156
30623
|
for (const p of parts) {
|
|
30157
30624
|
const absPath = await safeResolveReal(p, ctx);
|
|
30158
|
-
if (extraGlob && !passesExtraGlob(extraGlob,
|
|
30159
|
-
const stat22 = await
|
|
30625
|
+
if (extraGlob && !passesExtraGlob(extraGlob, path44.basename(absPath), absPath)) continue;
|
|
30626
|
+
const stat22 = await fs38.stat(absPath).catch(() => null);
|
|
30160
30627
|
if (stat22?.isFile()) {
|
|
30161
30628
|
resolved.push(absPath);
|
|
30162
30629
|
}
|
|
@@ -30170,7 +30637,7 @@ async function globFiles(pattern, base, extraGlob) {
|
|
|
30170
30637
|
const { promise } = spawnRgFind(pattern, base);
|
|
30171
30638
|
const files = await promise;
|
|
30172
30639
|
if (extraGlob) {
|
|
30173
|
-
return files.filter((f) => passesExtraGlob(extraGlob,
|
|
30640
|
+
return files.filter((f) => passesExtraGlob(extraGlob, path44.basename(f), f));
|
|
30174
30641
|
}
|
|
30175
30642
|
return files;
|
|
30176
30643
|
} catch {
|
|
@@ -30180,24 +30647,24 @@ async function globFiles(pattern, base, extraGlob) {
|
|
|
30180
30647
|
}
|
|
30181
30648
|
var rgAvailabilityCache2;
|
|
30182
30649
|
function checkRg() {
|
|
30183
|
-
rgAvailabilityCache2 ??= new Promise((
|
|
30650
|
+
rgAvailabilityCache2 ??= new Promise((resolve25) => {
|
|
30184
30651
|
try {
|
|
30185
|
-
const p =
|
|
30652
|
+
const p = spawn15("rg", ["--version"], {
|
|
30186
30653
|
env: buildChildEnv9(),
|
|
30187
30654
|
stdio: "ignore",
|
|
30188
30655
|
windowsHide: true
|
|
30189
30656
|
});
|
|
30190
|
-
p.on("error", () =>
|
|
30191
|
-
p.on("close", (code) =>
|
|
30657
|
+
p.on("error", () => resolve25(false));
|
|
30658
|
+
p.on("close", (code) => resolve25(code === 0));
|
|
30192
30659
|
} catch {
|
|
30193
|
-
|
|
30660
|
+
resolve25(false);
|
|
30194
30661
|
}
|
|
30195
30662
|
});
|
|
30196
30663
|
return rgAvailabilityCache2;
|
|
30197
30664
|
}
|
|
30198
30665
|
function spawnRgFind(pattern, base) {
|
|
30199
30666
|
const args = ["--files", "--glob", pattern, base];
|
|
30200
|
-
const child =
|
|
30667
|
+
const child = spawn15("rg", args, {
|
|
30201
30668
|
signal: AbortSignal.timeout(3e4),
|
|
30202
30669
|
env: buildChildEnv9(),
|
|
30203
30670
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -30216,10 +30683,10 @@ function spawnRgFind(pattern, base) {
|
|
|
30216
30683
|
}
|
|
30217
30684
|
});
|
|
30218
30685
|
return {
|
|
30219
|
-
promise: new Promise((
|
|
30686
|
+
promise: new Promise((resolve25, reject) => {
|
|
30220
30687
|
child.on("error", reject);
|
|
30221
30688
|
child.on("close", () => {
|
|
30222
|
-
|
|
30689
|
+
resolve25(buf.split("\n").filter(Boolean));
|
|
30223
30690
|
});
|
|
30224
30691
|
})
|
|
30225
30692
|
};
|
|
@@ -30230,15 +30697,15 @@ async function globNative(pattern, base, extraGlob) {
|
|
|
30230
30697
|
const walk2 = async (dir) => {
|
|
30231
30698
|
let entries;
|
|
30232
30699
|
try {
|
|
30233
|
-
entries = await
|
|
30700
|
+
entries = await fs38.readdir(dir, { withFileTypes: true });
|
|
30234
30701
|
} catch {
|
|
30235
30702
|
return;
|
|
30236
30703
|
}
|
|
30237
30704
|
for (const e of entries) {
|
|
30238
30705
|
if (DEFAULT_IGNORE4.includes(e.name)) continue;
|
|
30239
|
-
const full =
|
|
30706
|
+
const full = path44.join(dir, e.name);
|
|
30240
30707
|
try {
|
|
30241
|
-
const stat22 = await
|
|
30708
|
+
const stat22 = await fs38.lstat(full);
|
|
30242
30709
|
if (stat22.isSymbolicLink()) continue;
|
|
30243
30710
|
} catch {
|
|
30244
30711
|
continue;
|
|
@@ -30262,8 +30729,8 @@ async function globNative(pattern, base, extraGlob) {
|
|
|
30262
30729
|
|
|
30263
30730
|
// src/scaffold.ts
|
|
30264
30731
|
init_util();
|
|
30265
|
-
import * as
|
|
30266
|
-
import * as
|
|
30732
|
+
import * as fs39 from "node:fs/promises";
|
|
30733
|
+
import * as path45 from "node:path";
|
|
30267
30734
|
import { atomicWrite as atomicWrite5 } from "@wrongstack/core/utils";
|
|
30268
30735
|
var BUILT_IN_TEMPLATES = {
|
|
30269
30736
|
"npm-package": {
|
|
@@ -30414,16 +30881,16 @@ async function handleBuiltIn(name, templateFiles, cwd, ctx, dryRun, vars) {
|
|
|
30414
30881
|
let filesCreated = 0;
|
|
30415
30882
|
for (const [filePath, content] of Object.entries(templateFiles)) {
|
|
30416
30883
|
const resolvedPath = substituteVars(filePath, name, vars);
|
|
30417
|
-
const joinedPath =
|
|
30418
|
-
const root =
|
|
30419
|
-
const target =
|
|
30420
|
-
const rel =
|
|
30421
|
-
if (rel.startsWith("..") ||
|
|
30884
|
+
const joinedPath = path45.join(cwd, resolvedPath);
|
|
30885
|
+
const root = path45.resolve(ctx.projectRoot);
|
|
30886
|
+
const target = path45.resolve(joinedPath);
|
|
30887
|
+
const rel = path45.relative(root, target);
|
|
30888
|
+
if (rel.startsWith("..") || path45.isAbsolute(rel)) {
|
|
30422
30889
|
throw new Error(`scaffold: generated path "${resolvedPath}" would escape project root`);
|
|
30423
30890
|
}
|
|
30424
30891
|
const fullPath = target;
|
|
30425
30892
|
if (!dryRun) {
|
|
30426
|
-
await
|
|
30893
|
+
await fs39.mkdir(path45.dirname(fullPath), { recursive: true });
|
|
30427
30894
|
await atomicWrite5(fullPath, substituteVars(content, name, vars));
|
|
30428
30895
|
}
|
|
30429
30896
|
files.push(resolvedPath);
|
|
@@ -30869,8 +31336,8 @@ function decodeHtmlEntities(text) {
|
|
|
30869
31336
|
}
|
|
30870
31337
|
|
|
30871
31338
|
// src/security-ast-scan-tool.ts
|
|
30872
|
-
import * as
|
|
30873
|
-
import * as
|
|
31339
|
+
import * as fs40 from "node:fs/promises";
|
|
31340
|
+
import * as path46 from "node:path";
|
|
30874
31341
|
import { toErrorMessage as toErrorMessage17 } from "@wrongstack/core/utils";
|
|
30875
31342
|
var SECRET_PATTERNS = [
|
|
30876
31343
|
{ name: "AWS Access Key", regex: /\b(AKIA[0-9A-Z]{16})\b/ },
|
|
@@ -31037,9 +31504,9 @@ var securityAstScanTool = {
|
|
|
31037
31504
|
let targetFile = input.file ?? "inline-code.ts";
|
|
31038
31505
|
let content = input.content;
|
|
31039
31506
|
if (!content && input.file) {
|
|
31040
|
-
const absPath =
|
|
31041
|
-
targetFile =
|
|
31042
|
-
content = await
|
|
31507
|
+
const absPath = path46.isAbsolute(input.file) ? input.file : path46.resolve(projectRoot, input.file);
|
|
31508
|
+
targetFile = path46.relative(projectRoot, absPath).replace(/\\/g, "/");
|
|
31509
|
+
content = await fs40.readFile(absPath, "utf8");
|
|
31043
31510
|
}
|
|
31044
31511
|
if (!content) {
|
|
31045
31512
|
return {
|
|
@@ -31087,7 +31554,7 @@ var securityAstScanTool = {
|
|
|
31087
31554
|
};
|
|
31088
31555
|
|
|
31089
31556
|
// src/set-working-dir.ts
|
|
31090
|
-
import * as
|
|
31557
|
+
import * as fs41 from "node:fs/promises";
|
|
31091
31558
|
import { toErrorMessage as toErrorMessage18 } from "@wrongstack/core/utils";
|
|
31092
31559
|
var setWorkingDirTool = {
|
|
31093
31560
|
name: "set_working_dir",
|
|
@@ -31127,7 +31594,7 @@ var setWorkingDirTool = {
|
|
|
31127
31594
|
}
|
|
31128
31595
|
let isDirectory = false;
|
|
31129
31596
|
try {
|
|
31130
|
-
isDirectory = (await
|
|
31597
|
+
isDirectory = (await fs41.stat(resolved)).isDirectory();
|
|
31131
31598
|
} catch {
|
|
31132
31599
|
isDirectory = false;
|
|
31133
31600
|
}
|
|
@@ -31662,7 +32129,7 @@ ${formatTaskList2(file.tasks)}` : file.tasks.length > 0 ? formatTaskList2(file.t
|
|
|
31662
32129
|
init_spawn_stream();
|
|
31663
32130
|
init_util();
|
|
31664
32131
|
init_legacy_bridge();
|
|
31665
|
-
import * as
|
|
32132
|
+
import * as path47 from "node:path";
|
|
31666
32133
|
var testTool = {
|
|
31667
32134
|
name: "test",
|
|
31668
32135
|
category: "Code Quality",
|
|
@@ -31769,7 +32236,7 @@ async function detectRunner(cwd) {
|
|
|
31769
32236
|
const candidates = ["vitest.config.ts", "jest.config.js", ".mocharc.json"];
|
|
31770
32237
|
for (const f of candidates) {
|
|
31771
32238
|
try {
|
|
31772
|
-
await stat22(
|
|
32239
|
+
await stat22(path47.join(cwd, f));
|
|
31773
32240
|
if (f.includes("vitest")) return "vitest";
|
|
31774
32241
|
if (f.includes("jest")) return "jest";
|
|
31775
32242
|
if (f.includes("mocha")) return "mocha";
|
|
@@ -32146,8 +32613,8 @@ var toolUseTool = {
|
|
|
32146
32613
|
|
|
32147
32614
|
// src/tree.ts
|
|
32148
32615
|
init_util();
|
|
32149
|
-
import * as
|
|
32150
|
-
import * as
|
|
32616
|
+
import * as fs42 from "node:fs/promises";
|
|
32617
|
+
import * as path48 from "node:path";
|
|
32151
32618
|
import { DEFAULT_WALK_IGNORE_DIRS as DEFAULT_WALK_IGNORE_DIRS4, expectDefined as expectDefined10 } from "@wrongstack/core/utils";
|
|
32152
32619
|
var DEFAULT_IGNORE5 = /* @__PURE__ */ new Set([
|
|
32153
32620
|
...DEFAULT_WALK_IGNORE_DIRS4,
|
|
@@ -32310,7 +32777,7 @@ var treeTool = {
|
|
|
32310
32777
|
async function walkDir(dir, depth, opts) {
|
|
32311
32778
|
opts.signal.throwIfAborted();
|
|
32312
32779
|
if (opts.retention.truncated) return;
|
|
32313
|
-
const entries = await
|
|
32780
|
+
const entries = await fs42.readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
32314
32781
|
const filtered = entries.filter((e) => {
|
|
32315
32782
|
if (!opts.showHidden && e.name.startsWith(".")) return false;
|
|
32316
32783
|
if (opts.exclude.has(e.name)) return false;
|
|
@@ -32352,7 +32819,7 @@ async function walkDir(dir, depth, opts) {
|
|
|
32352
32819
|
opts.retention.outputBytes += lineBytes;
|
|
32353
32820
|
if (entry.isDirectory() && (opts.maxDepth === 0 || depth < opts.maxDepth)) {
|
|
32354
32821
|
const childPrefix = opts.prefix + connector;
|
|
32355
|
-
await walkDir(
|
|
32822
|
+
await walkDir(path48.join(dir, entry.name), depth + 1, {
|
|
32356
32823
|
...opts,
|
|
32357
32824
|
prefix: childPrefix,
|
|
32358
32825
|
isLast
|
|
@@ -32365,7 +32832,7 @@ async function walkDir(dir, depth, opts) {
|
|
|
32365
32832
|
init_spawn_stream();
|
|
32366
32833
|
init_util();
|
|
32367
32834
|
init_legacy_bridge();
|
|
32368
|
-
import * as
|
|
32835
|
+
import * as path49 from "node:path";
|
|
32369
32836
|
var typecheckTool = {
|
|
32370
32837
|
name: "typecheck",
|
|
32371
32838
|
category: "Code Quality",
|
|
@@ -32477,8 +32944,8 @@ async function findTsConfig(cwd) {
|
|
|
32477
32944
|
const candidates = ["tsconfig.json", "tsconfig.base.json"];
|
|
32478
32945
|
for (const f of candidates) {
|
|
32479
32946
|
try {
|
|
32480
|
-
const s = await stat22(
|
|
32481
|
-
if (s.isFile()) return
|
|
32947
|
+
const s = await stat22(path49.join(cwd, f));
|
|
32948
|
+
if (s.isFile()) return path49.join(cwd, f);
|
|
32482
32949
|
} catch {
|
|
32483
32950
|
}
|
|
32484
32951
|
}
|
|
@@ -32486,7 +32953,7 @@ async function findTsConfig(cwd) {
|
|
|
32486
32953
|
}
|
|
32487
32954
|
|
|
32488
32955
|
// src/write.ts
|
|
32489
|
-
import * as
|
|
32956
|
+
import * as fs43 from "node:fs/promises";
|
|
32490
32957
|
import { ToolValidationError as ToolValidationError11 } from "@wrongstack/core/types";
|
|
32491
32958
|
import {
|
|
32492
32959
|
atomicWrite as atomicWrite6,
|
|
@@ -32563,14 +33030,14 @@ async function prepareWrite(input, ctx) {
|
|
|
32563
33030
|
let existed = false;
|
|
32564
33031
|
let prev = "";
|
|
32565
33032
|
try {
|
|
32566
|
-
const stat22 = await
|
|
33033
|
+
const stat22 = await fs43.stat(absPath);
|
|
32567
33034
|
existed = stat22.isFile();
|
|
32568
33035
|
if (existed) {
|
|
32569
33036
|
if (!ctx.hasRead(absPath)) {
|
|
32570
|
-
prev = await
|
|
33037
|
+
prev = await fs43.readFile(absPath, "utf8");
|
|
32571
33038
|
ctx.recordRead(absPath, stat22.mtimeMs, "write", sha256hex(prev));
|
|
32572
33039
|
} else {
|
|
32573
|
-
prev = await
|
|
33040
|
+
prev = await fs43.readFile(absPath, "utf8");
|
|
32574
33041
|
}
|
|
32575
33042
|
}
|
|
32576
33043
|
} catch (err) {
|
|
@@ -32591,7 +33058,7 @@ async function finishWrite(input, ctx, prepared, signal) {
|
|
|
32591
33058
|
const rawDiff = prepared.existed ? unifiedDiff3(prepared.prev, content, { fromFile: input.path, toFile: input.path }) : `+++ ${input.path}
|
|
32592
33059
|
+ (new file, ${content.split("\n").length} lines)`;
|
|
32593
33060
|
const { text: diff, truncated: diffTruncated } = truncateDiffPayload(rawDiff, MAX_DIFF_BYTES3);
|
|
32594
|
-
const stat22 = await
|
|
33061
|
+
const stat22 = await fs43.stat(prepared.absPath);
|
|
32595
33062
|
ctx.recordRead(prepared.absPath, stat22.mtimeMs, "write", sha256hex(content));
|
|
32596
33063
|
ctx.session.recordFileChange({
|
|
32597
33064
|
path: prepared.absPath,
|
|
@@ -32669,6 +33136,7 @@ var TIER1_TOOLS = [
|
|
|
32669
33136
|
var TIER2_TOOLS = [
|
|
32670
33137
|
replaceTool,
|
|
32671
33138
|
execTool,
|
|
33139
|
+
pwshTool,
|
|
32672
33140
|
fetchTool,
|
|
32673
33141
|
gitTool,
|
|
32674
33142
|
treeTool,
|
|
@@ -32724,6 +33192,7 @@ var builtinTools = [
|
|
|
32724
33192
|
grepTool,
|
|
32725
33193
|
bashTool,
|
|
32726
33194
|
execTool,
|
|
33195
|
+
pwshTool,
|
|
32727
33196
|
fetchTool,
|
|
32728
33197
|
searchTool,
|
|
32729
33198
|
todoTool,
|
|
@@ -33140,7 +33609,7 @@ var builtinToolsPack = {
|
|
|
33140
33609
|
};
|
|
33141
33610
|
|
|
33142
33611
|
// src/process-guardian.ts
|
|
33143
|
-
import * as
|
|
33612
|
+
import * as os11 from "node:os";
|
|
33144
33613
|
var ProcessGuardian = class {
|
|
33145
33614
|
registry;
|
|
33146
33615
|
config;
|
|
@@ -33276,7 +33745,7 @@ var ProcessGuardian = class {
|
|
|
33276
33745
|
event: "process_guardian.started",
|
|
33277
33746
|
instanceId: this.instanceId,
|
|
33278
33747
|
mainPid: process.pid,
|
|
33279
|
-
hostname:
|
|
33748
|
+
hostname: os11.hostname(),
|
|
33280
33749
|
platform: process.platform
|
|
33281
33750
|
})
|
|
33282
33751
|
);
|
|
@@ -33410,8 +33879,8 @@ var ProcessGuardian = class {
|
|
|
33410
33879
|
instanceId: this.instanceId,
|
|
33411
33880
|
mainPid: process.pid,
|
|
33412
33881
|
protectedCount: this.protectedProcesses.size,
|
|
33413
|
-
platform:
|
|
33414
|
-
hostname:
|
|
33882
|
+
platform: os11.platform(),
|
|
33883
|
+
hostname: os11.hostname(),
|
|
33415
33884
|
uptime: process.uptime()
|
|
33416
33885
|
};
|
|
33417
33886
|
}
|
|
@@ -33441,7 +33910,7 @@ function stopProcessGuardian() {
|
|
|
33441
33910
|
init_process_registry();
|
|
33442
33911
|
|
|
33443
33912
|
// src/ps-slash.ts
|
|
33444
|
-
import * as
|
|
33913
|
+
import * as os12 from "node:os";
|
|
33445
33914
|
var IDLE_THRESHOLD_MS = 2 * 6e4;
|
|
33446
33915
|
var STALE_THRESHOLD_MS2 = 5 * 6e4;
|
|
33447
33916
|
function now() {
|
|
@@ -33482,7 +33951,7 @@ async function listInstances(options = {}) {
|
|
|
33482
33951
|
const mainProc = processes.find((p) => p.spawnMode === "main");
|
|
33483
33952
|
const firstProc = processes.at(0);
|
|
33484
33953
|
const mainPid = mainProc?.pid ?? firstProc?.pid ?? 0;
|
|
33485
|
-
const hostname_ = firstProc?.hostname ??
|
|
33954
|
+
const hostname_ = firstProc?.hostname ?? os12.hostname();
|
|
33486
33955
|
const startedAt = Math.min(...processes.map((p) => p.startedAt));
|
|
33487
33956
|
const lastActivity = Math.max(...processes.map((p) => p.lastHeartbeat));
|
|
33488
33957
|
const age = timestamp - lastActivity;
|
|
@@ -33570,7 +34039,7 @@ async function getGlobalProcessStatus() {
|
|
|
33570
34039
|
mainPid: process.pid,
|
|
33571
34040
|
protectedCount: 0,
|
|
33572
34041
|
platform: process.platform,
|
|
33573
|
-
hostname:
|
|
34042
|
+
hostname: os12.hostname(),
|
|
33574
34043
|
uptime: 0
|
|
33575
34044
|
},
|
|
33576
34045
|
allInstances: instances.map((inst) => ({
|
|
@@ -33764,8 +34233,8 @@ function createGlobalPsSlashCommand() {
|
|
|
33764
34233
|
}
|
|
33765
34234
|
|
|
33766
34235
|
// src/skill.ts
|
|
33767
|
-
import * as
|
|
33768
|
-
import * as
|
|
34236
|
+
import * as fs44 from "node:fs/promises";
|
|
34237
|
+
import * as path50 from "node:path";
|
|
33769
34238
|
import {
|
|
33770
34239
|
missingRequiredRuntimeTools,
|
|
33771
34240
|
missingRuntimeCapabilities,
|
|
@@ -33829,7 +34298,7 @@ function makeSkillTool(skillLoader) {
|
|
|
33829
34298
|
field: "name"
|
|
33830
34299
|
});
|
|
33831
34300
|
}
|
|
33832
|
-
const dir =
|
|
34301
|
+
const dir = path50.dirname(manifest.path);
|
|
33833
34302
|
let loadedResource;
|
|
33834
34303
|
if (input.resource?.trim()) {
|
|
33835
34304
|
loadedResource = await loadResource(dir, input.resource.trim());
|
|
@@ -33888,15 +34357,15 @@ ${listing}${warningLine}`;
|
|
|
33888
34357
|
}
|
|
33889
34358
|
async function loadResource(skillDir, rel) {
|
|
33890
34359
|
const norm = rel.replace(/\\/g, "/");
|
|
33891
|
-
if (
|
|
34360
|
+
if (path50.isAbsolute(rel) || norm.split("/").some((seg) => seg === "..")) {
|
|
33892
34361
|
throw new ToolValidationError13({
|
|
33893
34362
|
message: `skill: invalid resource path "${rel}"`,
|
|
33894
34363
|
field: "resource"
|
|
33895
34364
|
});
|
|
33896
34365
|
}
|
|
33897
|
-
const absPath =
|
|
33898
|
-
const root =
|
|
33899
|
-
if (absPath !== root && !absPath.startsWith(root +
|
|
34366
|
+
const absPath = path50.resolve(skillDir, rel);
|
|
34367
|
+
const root = path50.resolve(skillDir);
|
|
34368
|
+
if (absPath !== root && !absPath.startsWith(root + path50.sep)) {
|
|
33900
34369
|
throw new ToolValidationError13({
|
|
33901
34370
|
message: `skill: resource "${rel}" escapes the skill directory`,
|
|
33902
34371
|
field: "resource"
|
|
@@ -33905,15 +34374,15 @@ async function loadResource(skillDir, rel) {
|
|
|
33905
34374
|
let realPath;
|
|
33906
34375
|
let realRoot;
|
|
33907
34376
|
try {
|
|
33908
|
-
realRoot = await
|
|
33909
|
-
realPath = await
|
|
34377
|
+
realRoot = await fs44.realpath(root);
|
|
34378
|
+
realPath = await fs44.realpath(absPath);
|
|
33910
34379
|
} catch {
|
|
33911
34380
|
throw new ToolValidationError13({
|
|
33912
34381
|
message: `skill: resource "${rel}" not readable`,
|
|
33913
34382
|
field: "resource"
|
|
33914
34383
|
});
|
|
33915
34384
|
}
|
|
33916
|
-
if (realPath !== realRoot && !realPath.startsWith(realRoot +
|
|
34385
|
+
if (realPath !== realRoot && !realPath.startsWith(realRoot + path50.sep)) {
|
|
33917
34386
|
throw new ToolValidationError13({
|
|
33918
34387
|
message: `skill: resource "${rel}" resolves outside the skill directory`,
|
|
33919
34388
|
field: "resource"
|
|
@@ -33921,7 +34390,7 @@ async function loadResource(skillDir, rel) {
|
|
|
33921
34390
|
}
|
|
33922
34391
|
let buf;
|
|
33923
34392
|
try {
|
|
33924
|
-
buf = await
|
|
34393
|
+
buf = await fs44.readFile(realPath);
|
|
33925
34394
|
} catch {
|
|
33926
34395
|
throw new ToolValidationError13({
|
|
33927
34396
|
message: `skill: resource "${rel}" not readable`,
|
|
@@ -33950,17 +34419,17 @@ async function walk(root, dir, out) {
|
|
|
33950
34419
|
if (out.length >= MAX_LISTED_RESOURCES) return;
|
|
33951
34420
|
let entries;
|
|
33952
34421
|
try {
|
|
33953
|
-
entries = await
|
|
34422
|
+
entries = await fs44.readdir(dir, { withFileTypes: true });
|
|
33954
34423
|
} catch {
|
|
33955
34424
|
return;
|
|
33956
34425
|
}
|
|
33957
34426
|
for (const e of entries) {
|
|
33958
34427
|
if (out.length >= MAX_LISTED_RESOURCES) return;
|
|
33959
|
-
const fullPath =
|
|
34428
|
+
const fullPath = path50.join(dir, e.name);
|
|
33960
34429
|
let isDir = e.isDirectory();
|
|
33961
34430
|
if (e.isSymbolicLink()) {
|
|
33962
34431
|
try {
|
|
33963
|
-
isDir = (await
|
|
34432
|
+
isDir = (await fs44.stat(fullPath)).isDirectory();
|
|
33964
34433
|
} catch {
|
|
33965
34434
|
continue;
|
|
33966
34435
|
}
|
|
@@ -33971,8 +34440,8 @@ async function walk(root, dir, out) {
|
|
|
33971
34440
|
} else if (e.isFile()) {
|
|
33972
34441
|
if (e.name === "SKILL.md" || e.name === "SKILL.save.md") continue;
|
|
33973
34442
|
try {
|
|
33974
|
-
const stat22 = await
|
|
33975
|
-
const rel =
|
|
34443
|
+
const stat22 = await fs44.stat(fullPath);
|
|
34444
|
+
const rel = path50.relative(root, fullPath).split(path50.sep).join("/");
|
|
33976
34445
|
out.push({ path: rel, bytes: stat22.size });
|
|
33977
34446
|
} catch {
|
|
33978
34447
|
}
|
|
@@ -33998,6 +34467,8 @@ var TOOL_ICON_MAP = {
|
|
|
33998
34467
|
// Shell/command execution
|
|
33999
34468
|
bash: "terminal",
|
|
34000
34469
|
exec: "terminal",
|
|
34470
|
+
pwsh: "terminal",
|
|
34471
|
+
powershell: "terminal",
|
|
34001
34472
|
run: "terminal",
|
|
34002
34473
|
command: "terminal",
|
|
34003
34474
|
shell: "terminal",
|
|
@@ -34205,6 +34676,7 @@ export {
|
|
|
34205
34676
|
OFF_ONLY_TOOLS,
|
|
34206
34677
|
OPTIONAL_TOOLS,
|
|
34207
34678
|
PRIMARY_LANGUAGE_PROFILES,
|
|
34679
|
+
PWSH_TOOL_DESCRIPTION,
|
|
34208
34680
|
SESSION_KANBAN_COLUMNS,
|
|
34209
34681
|
TIER1_TOOLS,
|
|
34210
34682
|
TIER2_TOOLS,
|
|
@@ -34332,6 +34804,7 @@ export {
|
|
|
34332
34804
|
projectSessionPlanToKanban,
|
|
34333
34805
|
projectSessionTasksToKanban,
|
|
34334
34806
|
projectSessionTodosToKanban,
|
|
34807
|
+
pwshTool,
|
|
34335
34808
|
readTool,
|
|
34336
34809
|
rebindSessionKanbanTask,
|
|
34337
34810
|
recordKanbanVerificationEvidence,
|