@wrongstack/tools 0.276.3 → 0.277.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/audit.js +21 -8
- package/dist/audit.js.map +1 -1
- package/dist/bash.js.map +1 -1
- package/dist/builtin.js +648 -57
- package/dist/builtin.js.map +1 -1
- package/dist/exec.js +521 -9
- package/dist/exec.js.map +1 -1
- package/dist/fetch.js +7 -3
- package/dist/fetch.js.map +1 -1
- package/dist/format.js +22 -9
- package/dist/format.js.map +1 -1
- package/dist/index.js +649 -58
- package/dist/index.js.map +1 -1
- package/dist/install.js +21 -8
- package/dist/install.js.map +1 -1
- package/dist/lint.js +21 -8
- package/dist/lint.js.map +1 -1
- package/dist/memory.js +1 -1
- package/dist/memory.js.map +1 -1
- package/dist/outdated.js +20 -7
- package/dist/outdated.js.map +1 -1
- package/dist/pack.js +648 -57
- package/dist/pack.js.map +1 -1
- package/dist/search.js +113 -36
- package/dist/search.js.map +1 -1
- package/dist/test.js +21 -8
- package/dist/test.js.map +1 -1
- package/dist/typecheck.js +21 -8
- package/dist/typecheck.js.map +1 -1
- package/package.json +9 -5
package/dist/pack.js
CHANGED
|
@@ -15,7 +15,7 @@ import * as ts from 'typescript';
|
|
|
15
15
|
import { toErrorMessage as toErrorMessage$1 } from '@wrongstack/core/utils/error';
|
|
16
16
|
import * as dns from 'node:dns/promises';
|
|
17
17
|
import * as net from 'node:net';
|
|
18
|
-
import { Agent } from 'undici';
|
|
18
|
+
import { Agent, fetch } from 'undici';
|
|
19
19
|
import TurndownService from 'turndown';
|
|
20
20
|
import { randomUUID } from 'node:crypto';
|
|
21
21
|
|
|
@@ -714,16 +714,28 @@ function resolvePowerShell(cmd) {
|
|
|
714
714
|
}
|
|
715
715
|
return resolved;
|
|
716
716
|
}
|
|
717
|
-
var WIN32_SHELL_META = /[
|
|
717
|
+
var WIN32_SHELL_META = /[&|<>"\r\n\0]/;
|
|
718
718
|
function assertSafeWin32ShellArgs(args) {
|
|
719
|
-
for (const
|
|
720
|
-
if (typeof
|
|
719
|
+
for (const arg of args) {
|
|
720
|
+
if (typeof arg === "string" && WIN32_SHELL_META.test(arg)) {
|
|
721
721
|
throw new Error(
|
|
722
|
-
|
|
722
|
+
'win32 cmd shim spawn: argument contains a shell metacharacter (one of & | < > ", or a newline) that could enable command injection through the .cmd/.bat wrapper - refusing to run. Offending argument: ' + JSON.stringify(arg)
|
|
723
723
|
);
|
|
724
724
|
}
|
|
725
725
|
}
|
|
726
726
|
}
|
|
727
|
+
function buildWin32CmdShimInvocation(command, args = []) {
|
|
728
|
+
assertSafeWin32ShellArgs([command, ...args]);
|
|
729
|
+
const line = ["call", quoteWin32CmdArg(command), ...args.map(quoteWin32CmdArg)].join(" ");
|
|
730
|
+
return {
|
|
731
|
+
command: process.env["COMSPEC"] ?? "cmd.exe",
|
|
732
|
+
args: ["/d", "/c", line],
|
|
733
|
+
windowsVerbatimArguments: true
|
|
734
|
+
};
|
|
735
|
+
}
|
|
736
|
+
function quoteWin32CmdArg(arg) {
|
|
737
|
+
return `"${arg}"`;
|
|
738
|
+
}
|
|
727
739
|
|
|
728
740
|
// src/_spawn-stream.ts
|
|
729
741
|
var isWin = process.platform === "win32";
|
|
@@ -738,15 +750,16 @@ async function* spawnStream(opts) {
|
|
|
738
750
|
const spool = createOutputSpool({ tool: opts.cmd, thresholdBytes: max });
|
|
739
751
|
const resolved = resolveWin32Command(opts.cmd);
|
|
740
752
|
const needsShell = isWin && (resolved.endsWith(".cmd") || resolved.endsWith(".bat"));
|
|
741
|
-
const
|
|
742
|
-
|
|
743
|
-
const
|
|
753
|
+
const shim = needsShell ? buildWin32CmdShimInvocation(resolved, opts.args) : null;
|
|
754
|
+
const cmd = shim?.command ?? resolved;
|
|
755
|
+
const args = shim?.args ?? opts.args;
|
|
756
|
+
const child = spawn(cmd, args, {
|
|
744
757
|
cwd: opts.cwd,
|
|
745
758
|
env: buildChildEnv(),
|
|
746
759
|
stdio: ["ignore", "pipe", "pipe"],
|
|
747
760
|
windowsHide: true,
|
|
748
761
|
...isWin ? {} : { signal: opts.signal },
|
|
749
|
-
...
|
|
762
|
+
...shim ? { windowsVerbatimArguments: shim.windowsVerbatimArguments } : {}
|
|
750
763
|
});
|
|
751
764
|
const registry = getProcessRegistry();
|
|
752
765
|
const pid = child.pid;
|
|
@@ -5408,9 +5421,9 @@ var designTool = {
|
|
|
5408
5421
|
category: "Design",
|
|
5409
5422
|
description: 'Browse, load, customize, and enforce curated frontend/mobile UI design kits. Use BEFORE writing UI code to commit to one coherent, modern, responsive, dark/light, accessible design. Actions: "list" (menu), "use" (load+pin a kit for a stack), "foundations" (baseline), "set" (override kit colors/tokens), "materialize" (write the tokens to a real theme file \u2014 CSS @theme/OKLCH or native), "verify" (scan UI files for off-palette colors).',
|
|
5410
5423
|
usageHint: 'Flow: `design {action:"use", kit:"minimal-clarity", stack:"web"}` \u2192 optionally `design {action:"set", set:{primary:"oklch(62% 0.2 25)"}}` \u2192 `design {action:"materialize"}` to write tokens to disk \u2192 implement against them \u2192 `design {action:"verify"}`.',
|
|
5411
|
-
permission: "
|
|
5412
|
-
mutating:
|
|
5413
|
-
capabilities: [],
|
|
5424
|
+
permission: "confirm",
|
|
5425
|
+
mutating: true,
|
|
5426
|
+
capabilities: ["fs.write"],
|
|
5414
5427
|
timeoutMs: 15e3,
|
|
5415
5428
|
inputSchema: {
|
|
5416
5429
|
type: "object",
|
|
@@ -6146,10 +6159,20 @@ var DEFAULT_ALLOWED_COMMANDS = /* @__PURE__ */ new Set([
|
|
|
6146
6159
|
// C / C++ / native build
|
|
6147
6160
|
"make",
|
|
6148
6161
|
"cmake",
|
|
6162
|
+
"ninja",
|
|
6163
|
+
"clang",
|
|
6164
|
+
"clang-cl",
|
|
6165
|
+
"gcc",
|
|
6166
|
+
"g++",
|
|
6167
|
+
"link",
|
|
6168
|
+
"msbuild",
|
|
6149
6169
|
// containers / orchestration
|
|
6150
6170
|
"docker",
|
|
6151
6171
|
"podman",
|
|
6152
6172
|
"kubectl",
|
|
6173
|
+
// network (read-only intent; destructive ops still blocked by BLOCKED_ARG_PATTERNS)
|
|
6174
|
+
"curl",
|
|
6175
|
+
"wget",
|
|
6153
6176
|
// common POSIX file/text utilities
|
|
6154
6177
|
"pwd",
|
|
6155
6178
|
"ls",
|
|
@@ -6169,7 +6192,496 @@ var DEFAULT_ALLOWED_COMMANDS = /* @__PURE__ */ new Set([
|
|
|
6169
6192
|
"cp",
|
|
6170
6193
|
"mv",
|
|
6171
6194
|
"rm",
|
|
6172
|
-
"touch"
|
|
6195
|
+
"touch",
|
|
6196
|
+
"tar",
|
|
6197
|
+
// Windows-native tooling (win32). All non-destructive binaries; per-arg
|
|
6198
|
+
// safety is still enforced by BLOCKED_ARG_PATTERNS + the destructive-ops
|
|
6199
|
+
// gate in bash-kill-guard.ts. `gh` is included even though it lives at
|
|
6200
|
+
// "C:\Program Files\GitHub CLI\gh.exe" — resolveWin32Command handles the
|
|
6201
|
+
// space in the path.
|
|
6202
|
+
"gh",
|
|
6203
|
+
"where",
|
|
6204
|
+
"tasklist",
|
|
6205
|
+
"systeminfo",
|
|
6206
|
+
"wmic",
|
|
6207
|
+
"sc",
|
|
6208
|
+
"netstat",
|
|
6209
|
+
"ipconfig",
|
|
6210
|
+
"nslookup",
|
|
6211
|
+
"tracert",
|
|
6212
|
+
"pathping",
|
|
6213
|
+
// [core] Extended default allowlist (added 4b3d18d1 + this commit). All
|
|
6214
|
+
// non-destructive, broadly-used dev binaries. Per-arg safety is still
|
|
6215
|
+
// enforced by BLOCKED_ARG_PATTERNS + bash-kill-guard.ts.
|
|
6216
|
+
// --- Archives & compression ---
|
|
6217
|
+
"7z",
|
|
6218
|
+
"7za",
|
|
6219
|
+
"bzip2",
|
|
6220
|
+
"gzip",
|
|
6221
|
+
"xz",
|
|
6222
|
+
"unzip",
|
|
6223
|
+
"zip",
|
|
6224
|
+
"gtar",
|
|
6225
|
+
"bsdtar",
|
|
6226
|
+
"star",
|
|
6227
|
+
"pax",
|
|
6228
|
+
"cpio",
|
|
6229
|
+
// --- Android / mobile dev ---
|
|
6230
|
+
"adb",
|
|
6231
|
+
"fastboot",
|
|
6232
|
+
"sdkmanager",
|
|
6233
|
+
// --- DevOps / config mgmt ---
|
|
6234
|
+
"ansible",
|
|
6235
|
+
"ansible-playbook",
|
|
6236
|
+
"ansible-vault",
|
|
6237
|
+
"ansible-lint",
|
|
6238
|
+
"ansible-galaxy",
|
|
6239
|
+
"molecule",
|
|
6240
|
+
// --- Cloud CLIs ---
|
|
6241
|
+
"aws",
|
|
6242
|
+
"aws-vault",
|
|
6243
|
+
"awslocal",
|
|
6244
|
+
"az",
|
|
6245
|
+
"azcopy",
|
|
6246
|
+
"gcloud",
|
|
6247
|
+
"gsutil",
|
|
6248
|
+
"doctl",
|
|
6249
|
+
"linode-cli",
|
|
6250
|
+
// --- Native / C / C++ / linker tools ---
|
|
6251
|
+
"clang++",
|
|
6252
|
+
"clang-format",
|
|
6253
|
+
"clang-tidy",
|
|
6254
|
+
"clangd",
|
|
6255
|
+
"lld",
|
|
6256
|
+
"lldb",
|
|
6257
|
+
"ctest",
|
|
6258
|
+
"gmake",
|
|
6259
|
+
"meson",
|
|
6260
|
+
"conan",
|
|
6261
|
+
"vcpkg",
|
|
6262
|
+
"cl",
|
|
6263
|
+
"rc",
|
|
6264
|
+
"mt",
|
|
6265
|
+
"dumpbin",
|
|
6266
|
+
"dotnet-format",
|
|
6267
|
+
// --- Image / media / binary tools ---
|
|
6268
|
+
"convert",
|
|
6269
|
+
"ffmpeg",
|
|
6270
|
+
"ffprobe",
|
|
6271
|
+
"magick",
|
|
6272
|
+
"gs",
|
|
6273
|
+
"exiftool",
|
|
6274
|
+
// --- HTTP / fetch ---
|
|
6275
|
+
"wget2",
|
|
6276
|
+
"aria2c",
|
|
6277
|
+
"axel",
|
|
6278
|
+
"httpie",
|
|
6279
|
+
"hey",
|
|
6280
|
+
"ab",
|
|
6281
|
+
"wrk",
|
|
6282
|
+
"http",
|
|
6283
|
+
// --- Diff / patch / merge ---
|
|
6284
|
+
"diff",
|
|
6285
|
+
"diff3",
|
|
6286
|
+
"patch",
|
|
6287
|
+
"meld",
|
|
6288
|
+
"kdiff3",
|
|
6289
|
+
"kompare",
|
|
6290
|
+
// --- Encoding / file inspection ---
|
|
6291
|
+
"dos2unix",
|
|
6292
|
+
"unix2dos",
|
|
6293
|
+
"iconv",
|
|
6294
|
+
"file",
|
|
6295
|
+
"stat",
|
|
6296
|
+
"xxd",
|
|
6297
|
+
"hexdump",
|
|
6298
|
+
"od",
|
|
6299
|
+
"base64",
|
|
6300
|
+
// --- SSH / crypto / signing ---
|
|
6301
|
+
"ssh",
|
|
6302
|
+
"ssh-add",
|
|
6303
|
+
"ssh-keygen",
|
|
6304
|
+
"ssh-keyscan",
|
|
6305
|
+
"scp",
|
|
6306
|
+
"sftp",
|
|
6307
|
+
"rsync",
|
|
6308
|
+
"gpg",
|
|
6309
|
+
"gpg2",
|
|
6310
|
+
"gpg-agent",
|
|
6311
|
+
"openssl",
|
|
6312
|
+
"step",
|
|
6313
|
+
"keytool",
|
|
6314
|
+
// --- Search ---
|
|
6315
|
+
"egrep",
|
|
6316
|
+
"fgrep",
|
|
6317
|
+
"ag",
|
|
6318
|
+
"ack",
|
|
6319
|
+
"sift",
|
|
6320
|
+
"ugrep",
|
|
6321
|
+
"fd",
|
|
6322
|
+
"fdfind",
|
|
6323
|
+
"jq",
|
|
6324
|
+
"yq",
|
|
6325
|
+
"xq",
|
|
6326
|
+
"fx",
|
|
6327
|
+
"gron",
|
|
6328
|
+
// --- K8s / container ecosystem ---
|
|
6329
|
+
"kubectl.exe",
|
|
6330
|
+
"kubeadm",
|
|
6331
|
+
"kubelet",
|
|
6332
|
+
"helm",
|
|
6333
|
+
"k9s",
|
|
6334
|
+
"kustomize",
|
|
6335
|
+
"skaffold",
|
|
6336
|
+
"tilt",
|
|
6337
|
+
"minikube",
|
|
6338
|
+
"kind",
|
|
6339
|
+
"k3d",
|
|
6340
|
+
"k3s",
|
|
6341
|
+
"docker-compose",
|
|
6342
|
+
"buildah",
|
|
6343
|
+
"skopeo",
|
|
6344
|
+
"nerdctl",
|
|
6345
|
+
"ctr",
|
|
6346
|
+
"ctr.exe",
|
|
6347
|
+
// --- Databases ---
|
|
6348
|
+
"sqlite3",
|
|
6349
|
+
"sqlite",
|
|
6350
|
+
"psql",
|
|
6351
|
+
"pg_dump",
|
|
6352
|
+
"pg_restore",
|
|
6353
|
+
"mysql",
|
|
6354
|
+
"mysqladmin",
|
|
6355
|
+
"mysqldump",
|
|
6356
|
+
"mariadb",
|
|
6357
|
+
"mariadb-dump",
|
|
6358
|
+
"redis-cli",
|
|
6359
|
+
"redis-server",
|
|
6360
|
+
"memcached",
|
|
6361
|
+
"etcdctl",
|
|
6362
|
+
"consul",
|
|
6363
|
+
"vault",
|
|
6364
|
+
"nomad",
|
|
6365
|
+
"mongosh",
|
|
6366
|
+
"mongo",
|
|
6367
|
+
"mongoexport",
|
|
6368
|
+
"mongoimport",
|
|
6369
|
+
"mongodump",
|
|
6370
|
+
"mongorestore",
|
|
6371
|
+
// --- Windows extended (read-mostly ops) ---
|
|
6372
|
+
"taskkill",
|
|
6373
|
+
"gpupdate",
|
|
6374
|
+
"gpresult",
|
|
6375
|
+
"hostname",
|
|
6376
|
+
"whoami",
|
|
6377
|
+
"who",
|
|
6378
|
+
"net",
|
|
6379
|
+
"net1",
|
|
6380
|
+
// --- VCS ecosystem ---
|
|
6381
|
+
"glab",
|
|
6382
|
+
"hub",
|
|
6383
|
+
"tea",
|
|
6384
|
+
"git-lfs",
|
|
6385
|
+
"tig",
|
|
6386
|
+
"lazygit",
|
|
6387
|
+
// --- POSIX text utilities (extended; duplicates of pwd/ls/cat/head/tail/wc/
|
|
6388
|
+
// grep/find/echo/awk/mkdir/cp/mv/rm/touch from the base list above are
|
|
6389
|
+
// omitted — the Set is de-duplicated at runtime but a clean literal is
|
|
6390
|
+
// easier to maintain) ---
|
|
6391
|
+
"gawk",
|
|
6392
|
+
"tr",
|
|
6393
|
+
"cut",
|
|
6394
|
+
"paste",
|
|
6395
|
+
"join",
|
|
6396
|
+
"comm",
|
|
6397
|
+
"expand",
|
|
6398
|
+
"unexpand",
|
|
6399
|
+
"fold",
|
|
6400
|
+
"fmt",
|
|
6401
|
+
"nl",
|
|
6402
|
+
"pr",
|
|
6403
|
+
"column",
|
|
6404
|
+
"tsort",
|
|
6405
|
+
"tty",
|
|
6406
|
+
"ul",
|
|
6407
|
+
"units",
|
|
6408
|
+
"factor",
|
|
6409
|
+
"seq",
|
|
6410
|
+
"shuf",
|
|
6411
|
+
"look",
|
|
6412
|
+
"yes",
|
|
6413
|
+
"true",
|
|
6414
|
+
"false",
|
|
6415
|
+
"test",
|
|
6416
|
+
"[",
|
|
6417
|
+
"printf",
|
|
6418
|
+
"env",
|
|
6419
|
+
"tree",
|
|
6420
|
+
"locate",
|
|
6421
|
+
"which",
|
|
6422
|
+
"whereis",
|
|
6423
|
+
"type",
|
|
6424
|
+
"hash",
|
|
6425
|
+
"pushd",
|
|
6426
|
+
"popd",
|
|
6427
|
+
"dirs",
|
|
6428
|
+
"history",
|
|
6429
|
+
"fc",
|
|
6430
|
+
"jobs",
|
|
6431
|
+
"bg",
|
|
6432
|
+
"fg",
|
|
6433
|
+
"wait",
|
|
6434
|
+
"ulimit",
|
|
6435
|
+
"umask",
|
|
6436
|
+
"nice",
|
|
6437
|
+
"nohup",
|
|
6438
|
+
"timeout",
|
|
6439
|
+
"time",
|
|
6440
|
+
"trap",
|
|
6441
|
+
"exit",
|
|
6442
|
+
"return",
|
|
6443
|
+
"source",
|
|
6444
|
+
".",
|
|
6445
|
+
"alias",
|
|
6446
|
+
"unalias",
|
|
6447
|
+
"set",
|
|
6448
|
+
"unset",
|
|
6449
|
+
"export",
|
|
6450
|
+
"readonly",
|
|
6451
|
+
"typeset",
|
|
6452
|
+
"declare",
|
|
6453
|
+
"local",
|
|
6454
|
+
"eval",
|
|
6455
|
+
"exec",
|
|
6456
|
+
// --- Process / system inspection ---
|
|
6457
|
+
"htop",
|
|
6458
|
+
"top",
|
|
6459
|
+
"atop",
|
|
6460
|
+
"glances",
|
|
6461
|
+
"iotop",
|
|
6462
|
+
"nethogs",
|
|
6463
|
+
"iftop",
|
|
6464
|
+
"lsof",
|
|
6465
|
+
"strace",
|
|
6466
|
+
"ltrace",
|
|
6467
|
+
"sysstat",
|
|
6468
|
+
"vmstat",
|
|
6469
|
+
"iostat",
|
|
6470
|
+
"mpstat",
|
|
6471
|
+
"sar",
|
|
6472
|
+
"free",
|
|
6473
|
+
"df",
|
|
6474
|
+
"du",
|
|
6475
|
+
"mount",
|
|
6476
|
+
"umount",
|
|
6477
|
+
"lsblk",
|
|
6478
|
+
"blkid",
|
|
6479
|
+
"kill",
|
|
6480
|
+
"killall",
|
|
6481
|
+
"pkill",
|
|
6482
|
+
"pgrep",
|
|
6483
|
+
"pidof",
|
|
6484
|
+
"ps",
|
|
6485
|
+
"ps.exe",
|
|
6486
|
+
// --- Network inspection ---
|
|
6487
|
+
"ip",
|
|
6488
|
+
"ss",
|
|
6489
|
+
"route",
|
|
6490
|
+
"arp",
|
|
6491
|
+
"arping",
|
|
6492
|
+
"ping",
|
|
6493
|
+
"ping6",
|
|
6494
|
+
"hping3",
|
|
6495
|
+
"mtr",
|
|
6496
|
+
"tracepath",
|
|
6497
|
+
"tcpdump",
|
|
6498
|
+
"nmap",
|
|
6499
|
+
"netcat",
|
|
6500
|
+
"nc",
|
|
6501
|
+
"ncat",
|
|
6502
|
+
"socat",
|
|
6503
|
+
// --- Sync / backup ---
|
|
6504
|
+
"rclone",
|
|
6505
|
+
"restic",
|
|
6506
|
+
"borg",
|
|
6507
|
+
"duplicati",
|
|
6508
|
+
"duplicacy",
|
|
6509
|
+
"syncthing",
|
|
6510
|
+
"syncthing-cli",
|
|
6511
|
+
// --- Permissions / users / ACLs (POSIX) ---
|
|
6512
|
+
"useradd",
|
|
6513
|
+
"userdel",
|
|
6514
|
+
"usermod",
|
|
6515
|
+
"groupadd",
|
|
6516
|
+
"groupdel",
|
|
6517
|
+
"groupmod",
|
|
6518
|
+
"chown",
|
|
6519
|
+
"chmod",
|
|
6520
|
+
"chgrp",
|
|
6521
|
+
"getfacl",
|
|
6522
|
+
"setfacl",
|
|
6523
|
+
"setcap",
|
|
6524
|
+
"getcap",
|
|
6525
|
+
// --- Crypto / cert mgmt (extended) ---
|
|
6526
|
+
"certbot",
|
|
6527
|
+
"mkcert",
|
|
6528
|
+
"jarsigner",
|
|
6529
|
+
// --- Editors ---
|
|
6530
|
+
"subl",
|
|
6531
|
+
"code",
|
|
6532
|
+
"code-insiders",
|
|
6533
|
+
"cursor",
|
|
6534
|
+
"atom",
|
|
6535
|
+
"nano",
|
|
6536
|
+
"vim",
|
|
6537
|
+
"nvim",
|
|
6538
|
+
"vi",
|
|
6539
|
+
"emacs",
|
|
6540
|
+
"helix",
|
|
6541
|
+
"hx",
|
|
6542
|
+
"micro",
|
|
6543
|
+
"jed",
|
|
6544
|
+
"ed",
|
|
6545
|
+
"ex",
|
|
6546
|
+
"mg",
|
|
6547
|
+
// --- Terminal multiplexers ---
|
|
6548
|
+
"asciinema",
|
|
6549
|
+
"script",
|
|
6550
|
+
"scriptreplay",
|
|
6551
|
+
"expect",
|
|
6552
|
+
"screen",
|
|
6553
|
+
"tmux",
|
|
6554
|
+
"byobu",
|
|
6555
|
+
"dtach",
|
|
6556
|
+
"abduco",
|
|
6557
|
+
// --- Calculators / REPLs / scientific ---
|
|
6558
|
+
"bc",
|
|
6559
|
+
"dc",
|
|
6560
|
+
"calc",
|
|
6561
|
+
"qalc",
|
|
6562
|
+
"genius",
|
|
6563
|
+
"octave",
|
|
6564
|
+
"R",
|
|
6565
|
+
"Rscript",
|
|
6566
|
+
"julia",
|
|
6567
|
+
"irb",
|
|
6568
|
+
"pry",
|
|
6569
|
+
"ghci",
|
|
6570
|
+
"stack",
|
|
6571
|
+
"cabal",
|
|
6572
|
+
"ghc",
|
|
6573
|
+
// --- PHP / Lua / Perl / Ruby ecosystem (extended) ---
|
|
6574
|
+
"php8",
|
|
6575
|
+
"php7",
|
|
6576
|
+
"phpcs",
|
|
6577
|
+
"phpcbf",
|
|
6578
|
+
"phpmd",
|
|
6579
|
+
"phpstan",
|
|
6580
|
+
"psalm",
|
|
6581
|
+
"lua",
|
|
6582
|
+
"lua5.1",
|
|
6583
|
+
"lua5.2",
|
|
6584
|
+
"lua5.3",
|
|
6585
|
+
"lua5.4",
|
|
6586
|
+
"luarocks",
|
|
6587
|
+
"perl",
|
|
6588
|
+
"cpan",
|
|
6589
|
+
"prove",
|
|
6590
|
+
"plackup",
|
|
6591
|
+
"rake",
|
|
6592
|
+
"rspec",
|
|
6593
|
+
"jekyll",
|
|
6594
|
+
"node-gyp",
|
|
6595
|
+
"node-pre-gyp",
|
|
6596
|
+
// --- JS / TS toolchain (extended) ---
|
|
6597
|
+
"electron",
|
|
6598
|
+
"electron-builder",
|
|
6599
|
+
"electron-forge",
|
|
6600
|
+
"vite-preview",
|
|
6601
|
+
"swc",
|
|
6602
|
+
"swc-cli",
|
|
6603
|
+
"swcpack",
|
|
6604
|
+
"mocha",
|
|
6605
|
+
"chai",
|
|
6606
|
+
"jasmine",
|
|
6607
|
+
"puppeteer",
|
|
6608
|
+
"lighthouse",
|
|
6609
|
+
// --- Linters / formatters (extended) ---
|
|
6610
|
+
"tslint",
|
|
6611
|
+
"stylelint",
|
|
6612
|
+
"htmlhint",
|
|
6613
|
+
"jshint",
|
|
6614
|
+
"jslint",
|
|
6615
|
+
"jscs",
|
|
6616
|
+
// --- Document conversion ---
|
|
6617
|
+
"pandoc",
|
|
6618
|
+
"weasyprint",
|
|
6619
|
+
"wkhtmltopdf",
|
|
6620
|
+
"wkhtmltoimage",
|
|
6621
|
+
"prince",
|
|
6622
|
+
"mdp",
|
|
6623
|
+
"markdown",
|
|
6624
|
+
"multimarkdown",
|
|
6625
|
+
"cmark",
|
|
6626
|
+
"cmark-gfm",
|
|
6627
|
+
// --- Office / spreadsheet ---
|
|
6628
|
+
"soffice",
|
|
6629
|
+
"libreoffice",
|
|
6630
|
+
"unoconv",
|
|
6631
|
+
"abiword",
|
|
6632
|
+
"gnumeric",
|
|
6633
|
+
// --- Spell / grammar ---
|
|
6634
|
+
"aspell",
|
|
6635
|
+
"hunspell",
|
|
6636
|
+
"enchant",
|
|
6637
|
+
"languagetool",
|
|
6638
|
+
// --- Source-highlight / diff tools ---
|
|
6639
|
+
"delta",
|
|
6640
|
+
"bat",
|
|
6641
|
+
"ccat",
|
|
6642
|
+
"hl",
|
|
6643
|
+
"highlight",
|
|
6644
|
+
"source-highlight",
|
|
6645
|
+
"ansifilter",
|
|
6646
|
+
// --- Job schedulers ---
|
|
6647
|
+
"pueue",
|
|
6648
|
+
"task-spooler",
|
|
6649
|
+
"ts",
|
|
6650
|
+
"at",
|
|
6651
|
+
"atd",
|
|
6652
|
+
"anacron",
|
|
6653
|
+
"fcron",
|
|
6654
|
+
"cronie",
|
|
6655
|
+
"systemd-run",
|
|
6656
|
+
"systemd-cat",
|
|
6657
|
+
// --- Plotting / visualization ---
|
|
6658
|
+
"gnuplot",
|
|
6659
|
+
"gnuplot-nox",
|
|
6660
|
+
"veusz",
|
|
6661
|
+
"scidavis",
|
|
6662
|
+
"grace",
|
|
6663
|
+
"xmgrace",
|
|
6664
|
+
"labplot",
|
|
6665
|
+
// --- Security / recon (network + web) ---
|
|
6666
|
+
"masscan",
|
|
6667
|
+
"zmap",
|
|
6668
|
+
"rustscan",
|
|
6669
|
+
"amass",
|
|
6670
|
+
"subfinder",
|
|
6671
|
+
"httpx",
|
|
6672
|
+
"nuclei",
|
|
6673
|
+
"naabu",
|
|
6674
|
+
"katana",
|
|
6675
|
+
"dnsx",
|
|
6676
|
+
"assetfinder",
|
|
6677
|
+
"findomain",
|
|
6678
|
+
"gau",
|
|
6679
|
+
"waybackurls",
|
|
6680
|
+
"httprobe",
|
|
6681
|
+
"meg",
|
|
6682
|
+
"subjack",
|
|
6683
|
+
"sublert",
|
|
6684
|
+
"chaos"
|
|
6173
6685
|
]);
|
|
6174
6686
|
var allowedCommands = new Set(DEFAULT_ALLOWED_COMMANDS);
|
|
6175
6687
|
var normalizeCmd = (c) => c.trim();
|
|
@@ -6377,17 +6889,18 @@ function runCommand(cmd, args, cwd, timeout, signal, sessionId) {
|
|
|
6377
6889
|
const spool = createOutputSpool({ tool: `exec-${cmd}`, thresholdBytes: MAX_OUTPUT2 });
|
|
6378
6890
|
const resolved = resolveWin32Command(cmd);
|
|
6379
6891
|
const needsShell = isWin3 && (resolved.endsWith(".cmd") || resolved.endsWith(".bat"));
|
|
6380
|
-
const
|
|
6381
|
-
|
|
6892
|
+
const shim = needsShell ? buildWin32CmdShimInvocation(resolved, args) : null;
|
|
6893
|
+
const spawnCmd = shim?.command ?? resolved;
|
|
6894
|
+
const spawnArgs = shim?.args ?? args;
|
|
6382
6895
|
let child;
|
|
6383
6896
|
try {
|
|
6384
|
-
child = spawn(spawnCmd,
|
|
6897
|
+
child = spawn(spawnCmd, spawnArgs, {
|
|
6385
6898
|
cwd,
|
|
6386
6899
|
env: buildChildEnv(sessionId),
|
|
6387
6900
|
stdio: ["ignore", "pipe", "pipe"],
|
|
6388
6901
|
windowsHide: true,
|
|
6389
6902
|
...isWin3 ? {} : { signal },
|
|
6390
|
-
...
|
|
6903
|
+
...shim ? { windowsVerbatimArguments: shim.windowsVerbatimArguments } : {}
|
|
6391
6904
|
});
|
|
6392
6905
|
} catch (err) {
|
|
6393
6906
|
spool.finalize();
|
|
@@ -6482,6 +6995,7 @@ TD.addRule("stripDangerousElements", {
|
|
|
6482
6995
|
});
|
|
6483
6996
|
var MAX_BYTES = 131072;
|
|
6484
6997
|
var TIMEOUT_MS = 2e4;
|
|
6998
|
+
var nativeGlobalFetch = globalThis.fetch;
|
|
6485
6999
|
var ALLOW_PRIVATE = process.env["WRONGSTACK_FETCH_ALLOW_PRIVATE"] === "1";
|
|
6486
7000
|
if (ALLOW_PRIVATE && !process.env["CI"]) {
|
|
6487
7001
|
console.warn(
|
|
@@ -6531,6 +7045,9 @@ function getPinnedDispatcher() {
|
|
|
6531
7045
|
}
|
|
6532
7046
|
return pinnedAgent;
|
|
6533
7047
|
}
|
|
7048
|
+
function dispatcherFetch() {
|
|
7049
|
+
return globalThis.fetch === nativeGlobalFetch ? fetch : globalThis.fetch;
|
|
7050
|
+
}
|
|
6534
7051
|
var _beforeExitRegistered = false;
|
|
6535
7052
|
if (!_beforeExitRegistered) {
|
|
6536
7053
|
_beforeExitRegistered = true;
|
|
@@ -6566,7 +7083,7 @@ async function guardedFetch(url, maxRedirects, signal, headers = {
|
|
|
6566
7083
|
headers,
|
|
6567
7084
|
dispatcher: getPinnedDispatcher()
|
|
6568
7085
|
};
|
|
6569
|
-
const res = await
|
|
7086
|
+
const res = await dispatcherFetch()(currentUrl, init);
|
|
6570
7087
|
if (res.status < 300 || res.status > 399) {
|
|
6571
7088
|
return res;
|
|
6572
7089
|
}
|
|
@@ -6594,7 +7111,7 @@ var fetchTool = {
|
|
|
6594
7111
|
category: "Network",
|
|
6595
7112
|
description: "Fetch a URL and return its content. HTML pages are automatically converted to clean markdown. This tool has strong SSRF protections (private IPs, localhost, and cloud metadata endpoints are blocked by default).",
|
|
6596
7113
|
usageHint: "Use this when you need external information (documentation, API responses, web pages, etc.).\n\nSecurity notes:\n- Only HTTPS is allowed by default.\n- Internal/private networks are blocked unless explicitly enabled via environment variable.\n- Redirects are followed but re-validated at each hop.\n- Output is capped (128KB by default) to avoid flooding context.\nPrefer this over raw `bash curl` or `bash wget`.",
|
|
6597
|
-
permission: "
|
|
7114
|
+
permission: "auto",
|
|
6598
7115
|
mutating: false,
|
|
6599
7116
|
capabilities: ["net.outbound"],
|
|
6600
7117
|
icon: "web",
|
|
@@ -6834,7 +7351,7 @@ var formatTool = {
|
|
|
6834
7351
|
usageHint: "RUN REGULARLY:\n\n- Use on changed files before committing.\n- `check: true` verifies formatting without making changes (useful in CI-like flows).\nThis project has very consistent formatting expectations. Always ensure your changes are formatted.",
|
|
6835
7352
|
permission: "confirm",
|
|
6836
7353
|
mutating: true,
|
|
6837
|
-
capabilities: ["fs.write", "shell.
|
|
7354
|
+
capabilities: ["fs.write", "shell.restricted"],
|
|
6838
7355
|
icon: "code",
|
|
6839
7356
|
timeoutMs: 6e4,
|
|
6840
7357
|
inputSchema: {
|
|
@@ -8739,9 +9256,10 @@ function runOutdated(manager, args, cwd, signal) {
|
|
|
8739
9256
|
const MAX = 1e5;
|
|
8740
9257
|
const resolved = resolveWin32Command(manager);
|
|
8741
9258
|
const needsShell = process.platform === "win32" && (resolved.endsWith(".cmd") || resolved.endsWith(".bat"));
|
|
8742
|
-
const
|
|
8743
|
-
|
|
8744
|
-
const
|
|
9259
|
+
const shim = needsShell ? buildWin32CmdShimInvocation(resolved, args) : null;
|
|
9260
|
+
const spawnCmd = shim?.command ?? resolved;
|
|
9261
|
+
const spawnArgs = shim?.args ?? args;
|
|
9262
|
+
const child = spawn(spawnCmd, spawnArgs, { cwd, signal, env: buildChildEnv(), stdio: ["ignore", "pipe", "pipe"], windowsHide: true, ...shim ? { windowsVerbatimArguments: shim.windowsVerbatimArguments } : {} });
|
|
8745
9263
|
child.stdout?.on("data", (c) => {
|
|
8746
9264
|
if (stdout.length < MAX) stdout += c.toString();
|
|
8747
9265
|
});
|
|
@@ -9782,7 +10300,7 @@ var searchTool = {
|
|
|
9782
10300
|
category: "Search",
|
|
9783
10301
|
description: "Perform a web search and return results with title, URL, and snippet. Use this when you need up-to-date external information that is not in the local codebase. Results are cached (5 min TTL) and deduplicated by URL.",
|
|
9784
10302
|
usageHint: "Good for: API documentation, error messages, library usage examples, current best practices.\n\n- Prefer specific queries over very broad ones.\n- Results go through the guarded fetch system (same protections as the `fetch` tool).\n- Supports duckduckgo (default), google, and bing sources.\n- Set `skip_cache: true` to force a fresh search.\n- This is often better than the model trying to recall outdated knowledge.",
|
|
9785
|
-
permission: "
|
|
10303
|
+
permission: "auto",
|
|
9786
10304
|
mutating: false,
|
|
9787
10305
|
capabilities: ["net.outbound"],
|
|
9788
10306
|
icon: "search",
|
|
@@ -9845,15 +10363,15 @@ var searchTool = {
|
|
|
9845
10363
|
};
|
|
9846
10364
|
yield {
|
|
9847
10365
|
type: "partial_output",
|
|
9848
|
-
text: `${results.length} cached results from ${source}`,
|
|
9849
|
-
data: { count: results.length, cached: true }
|
|
10366
|
+
text: `${results.length} cached results from ${entry.source}`,
|
|
10367
|
+
data: { count: results.length, cached: true, source: entry.source }
|
|
9850
10368
|
};
|
|
9851
10369
|
yield {
|
|
9852
10370
|
type: "final",
|
|
9853
10371
|
output: {
|
|
9854
10372
|
query: input.query,
|
|
9855
10373
|
results: results.slice(0, num),
|
|
9856
|
-
source,
|
|
10374
|
+
source: entry.source,
|
|
9857
10375
|
truncated: results.length >= num,
|
|
9858
10376
|
cached: true
|
|
9859
10377
|
}
|
|
@@ -9867,6 +10385,7 @@ var searchTool = {
|
|
|
9867
10385
|
data: { source, query: input.query, cached: false }
|
|
9868
10386
|
};
|
|
9869
10387
|
let rawResults;
|
|
10388
|
+
let effectiveSource = source;
|
|
9870
10389
|
switch (source) {
|
|
9871
10390
|
case "duckduckgo":
|
|
9872
10391
|
rawResults = await duckduckgoSearch(input.query, num, opts.signal);
|
|
@@ -9883,24 +10402,24 @@ var searchTool = {
|
|
|
9883
10402
|
field: "source"
|
|
9884
10403
|
});
|
|
9885
10404
|
}
|
|
9886
|
-
|
|
9887
|
-
|
|
9888
|
-
|
|
9889
|
-
|
|
9890
|
-
|
|
9891
|
-
|
|
9892
|
-
|
|
9893
|
-
|
|
9894
|
-
|
|
10405
|
+
let ranked = rankSearchResults(rawResults, input.query);
|
|
10406
|
+
if (source !== "duckduckgo" && shouldFallbackToDuckDuckGo(ranked, input.query)) {
|
|
10407
|
+
yield {
|
|
10408
|
+
type: "log",
|
|
10409
|
+
text: `${source} returned no relevant static results; falling back to duckduckgo`,
|
|
10410
|
+
data: { source, fallback: "duckduckgo", query: input.query }
|
|
10411
|
+
};
|
|
10412
|
+
rawResults = await duckduckgoSearch(input.query, num, opts.signal);
|
|
10413
|
+
ranked = rankSearchResults(rawResults, input.query);
|
|
10414
|
+
effectiveSource = "duckduckgo";
|
|
9895
10415
|
}
|
|
9896
|
-
const ranked = scoreResults(deduped, input.query);
|
|
9897
10416
|
const finalResults = ranked.slice(0, num);
|
|
9898
|
-
cache.set(cacheKey, { results: ranked, timestamp: Date.now() });
|
|
10417
|
+
cache.set(cacheKey, { results: ranked, source: effectiveSource, timestamp: Date.now() });
|
|
9899
10418
|
pruneStaleCacheEntries();
|
|
9900
10419
|
yield {
|
|
9901
10420
|
type: "partial_output",
|
|
9902
|
-
text: `${finalResults.length} results from ${
|
|
9903
|
-
data: { count: finalResults.length, cached: false }
|
|
10421
|
+
text: `${finalResults.length} results from ${effectiveSource}`,
|
|
10422
|
+
data: { count: finalResults.length, cached: false, source: effectiveSource }
|
|
9904
10423
|
};
|
|
9905
10424
|
yield {
|
|
9906
10425
|
type: "final",
|
|
@@ -9911,7 +10430,7 @@ var searchTool = {
|
|
|
9911
10430
|
url: r.url,
|
|
9912
10431
|
snippet: r.snippet
|
|
9913
10432
|
})),
|
|
9914
|
-
source,
|
|
10433
|
+
source: effectiveSource,
|
|
9915
10434
|
truncated: finalResults.length >= num,
|
|
9916
10435
|
cached: false
|
|
9917
10436
|
}
|
|
@@ -9924,6 +10443,19 @@ function pruneStaleCacheEntries() {
|
|
|
9924
10443
|
if (entry.timestamp < cutoff) cache.delete(key);
|
|
9925
10444
|
}
|
|
9926
10445
|
}
|
|
10446
|
+
function rankSearchResults(results, query) {
|
|
10447
|
+
const seenUrls = /* @__PURE__ */ new Set();
|
|
10448
|
+
const deduped = [];
|
|
10449
|
+
for (const r of results) {
|
|
10450
|
+
const noQuery = r.url.split("?")[0] ?? r.url;
|
|
10451
|
+
const normalized = noQuery.split("#")[0] ?? r.url;
|
|
10452
|
+
if (!seenUrls.has(normalized) && r.url.startsWith("http")) {
|
|
10453
|
+
seenUrls.add(normalized);
|
|
10454
|
+
deduped.push(r);
|
|
10455
|
+
}
|
|
10456
|
+
}
|
|
10457
|
+
return scoreResults(deduped, query);
|
|
10458
|
+
}
|
|
9927
10459
|
function scoreResults(results, query) {
|
|
9928
10460
|
const terms = query.toLowerCase().split(/\s+/).filter((t) => t.length > 0);
|
|
9929
10461
|
return results.map((r) => {
|
|
@@ -9937,6 +10469,15 @@ function scoreResults(results, query) {
|
|
|
9937
10469
|
return { ...r, score };
|
|
9938
10470
|
}).sort((a, b) => b.score - a.score);
|
|
9939
10471
|
}
|
|
10472
|
+
function shouldFallbackToDuckDuckGo(results, query) {
|
|
10473
|
+
if (results.length === 0) return true;
|
|
10474
|
+
const terms = query.toLowerCase().split(/\s+/).filter((t) => t.length >= 3);
|
|
10475
|
+
if (terms.length === 0) return false;
|
|
10476
|
+
return !results.some((r) => {
|
|
10477
|
+
const haystack = `${r.title} ${r.url} ${r.snippet}`.toLowerCase();
|
|
10478
|
+
return terms.some((term) => haystack.includes(term));
|
|
10479
|
+
});
|
|
10480
|
+
}
|
|
9940
10481
|
async function duckduckgoSearch(query, num, signal) {
|
|
9941
10482
|
const encoded = encodeURIComponent(query);
|
|
9942
10483
|
const url = `https://lite.duckduckgo.com/lite/?q=${encoded}&kd=-1&kl=wt-wt`;
|
|
@@ -9961,14 +10502,19 @@ function takeFrom(iter, max) {
|
|
|
9961
10502
|
}
|
|
9962
10503
|
function parseDuckDuckGo(html, num) {
|
|
9963
10504
|
const results = [];
|
|
9964
|
-
const
|
|
9965
|
-
const
|
|
10505
|
+
const linkRegex = /<a\b([^>]*\bclass=(["'])[^"']*\bresult-link\b[^"']*\2[^>]*)>([\s\S]*?)<\/a>/gi;
|
|
10506
|
+
const snippetRegex = /<([a-z0-9]+)\b([^>]*\bclass=(["'])[^"']*\bresult-snippet\b[^"']*\3[^>]*)>([\s\S]*?)<\/\1>/gi;
|
|
9966
10507
|
const linkMatches = takeFrom(
|
|
9967
|
-
[...html.matchAll(
|
|
10508
|
+
[...html.matchAll(linkRegex)].map((m) => {
|
|
10509
|
+
const attrs = expectDefined(m[1]);
|
|
10510
|
+
const href = getHtmlAttr(attrs, "href");
|
|
10511
|
+
const title = stripTags(expectDefined(m[3]));
|
|
10512
|
+
return href && title ? { url: normalizeDuckDuckGoUrl(href), title } : void 0;
|
|
10513
|
+
}).filter((m) => m !== void 0),
|
|
9968
10514
|
num
|
|
9969
10515
|
);
|
|
9970
10516
|
const snippetMatches = takeFrom(
|
|
9971
|
-
[...html.matchAll(
|
|
10517
|
+
[...html.matchAll(snippetRegex)].filter((m) => m[4]).map((m) => stripTags(expectDefined(m[4]))),
|
|
9972
10518
|
num
|
|
9973
10519
|
);
|
|
9974
10520
|
for (let i = 0; i < linkMatches.length && i < num; i++) {
|
|
@@ -9984,6 +10530,24 @@ function parseDuckDuckGo(html, num) {
|
|
|
9984
10530
|
}
|
|
9985
10531
|
return results;
|
|
9986
10532
|
}
|
|
10533
|
+
function getHtmlAttr(attrs, name) {
|
|
10534
|
+
const quoted = new RegExp(`\\b${name}\\s*=\\s*(["'])(.*?)\\1`, "i").exec(attrs);
|
|
10535
|
+
if (quoted?.[2]) return decodeHtmlEntities(quoted[2]);
|
|
10536
|
+
const unquoted = new RegExp(`\\b${name}\\s*=\\s*([^\\s>]+)`, "i").exec(attrs);
|
|
10537
|
+
return unquoted?.[1] ? decodeHtmlEntities(unquoted[1]) : void 0;
|
|
10538
|
+
}
|
|
10539
|
+
function normalizeDuckDuckGoUrl(raw) {
|
|
10540
|
+
if (raw.startsWith("//")) return `https:${raw}`;
|
|
10541
|
+
if (!raw.startsWith("/")) return raw;
|
|
10542
|
+
if (!raw.startsWith("/l/")) return raw;
|
|
10543
|
+
try {
|
|
10544
|
+
const url = new URL(raw, "https://duckduckgo.com");
|
|
10545
|
+
const uddg = url.searchParams.get("uddg");
|
|
10546
|
+
return uddg?.startsWith("http") ? uddg : url.toString();
|
|
10547
|
+
} catch {
|
|
10548
|
+
return raw;
|
|
10549
|
+
}
|
|
10550
|
+
}
|
|
9987
10551
|
async function googleSearch(query, num, signal) {
|
|
9988
10552
|
const encoded = encodeURIComponent(query);
|
|
9989
10553
|
const url = `https://www.google.com/search?q=${encoded}&hl=en`;
|
|
@@ -10025,29 +10589,53 @@ async function bingSearch(query, num, signal) {
|
|
|
10025
10589
|
}
|
|
10026
10590
|
function parseBingResults(html, num) {
|
|
10027
10591
|
const results = [];
|
|
10028
|
-
const
|
|
10029
|
-
const
|
|
10030
|
-
const entries = takeFrom(
|
|
10031
|
-
|
|
10032
|
-
|
|
10033
|
-
|
|
10034
|
-
|
|
10035
|
-
|
|
10036
|
-
|
|
10037
|
-
|
|
10592
|
+
const blocks = [...html.matchAll(/<li\b[^>]*class=(["'])[^"']*\bb_algo\b[^"']*\1[^>]*>([\s\S]*?)(?=<li\b[^>]*class=(["'])[^"']*\bb_algo\b[^"']*\3|<\/ol>)/gi)].map((m) => expectDefined(m[2]));
|
|
10593
|
+
const candidates = blocks.length > 0 ? blocks : [html];
|
|
10594
|
+
const entries = takeFrom(candidates.flatMap((block) => {
|
|
10595
|
+
const titleMatch = /<h2[^>]*>\s*<a\b([^>]*)>([\s\S]*?)<\/a>\s*<\/h2>/i.exec(block);
|
|
10596
|
+
if (!titleMatch) return [];
|
|
10597
|
+
const href = getHtmlAttr(expectDefined(titleMatch[1]), "href");
|
|
10598
|
+
const title = stripTags(expectDefined(titleMatch[2]));
|
|
10599
|
+
if (!href || !title) return [];
|
|
10600
|
+
const snippetMatch = /<p\b[^>]*class=(["'])[^"']*\b(?:b_paractl|b_lineclamp\d*)\b[^"']*\1[^>]*>([\s\S]*?)<\/p>/i.exec(block) ?? /<p\b[^>]*>([\s\S]*?)<\/p>/i.exec(block);
|
|
10601
|
+
const snippet = snippetMatch ? stripTags(expectDefined(snippetMatch.at(-1))) : "";
|
|
10602
|
+
return [{ url: normalizeBingUrl(href), title, snippet, score: 1 }];
|
|
10603
|
+
}), num);
|
|
10038
10604
|
for (let i = 0; i < entries.length; i++) {
|
|
10039
10605
|
const entry = entries[i];
|
|
10040
10606
|
if (entry) {
|
|
10041
10607
|
results.push({
|
|
10042
10608
|
title: entry.title ?? "",
|
|
10043
10609
|
url: entry.url ?? "",
|
|
10044
|
-
snippet:
|
|
10610
|
+
snippet: entry.snippet ?? "",
|
|
10045
10611
|
score: 1
|
|
10046
10612
|
});
|
|
10047
10613
|
}
|
|
10048
10614
|
}
|
|
10049
10615
|
return results;
|
|
10050
10616
|
}
|
|
10617
|
+
function normalizeBingUrl(raw) {
|
|
10618
|
+
try {
|
|
10619
|
+
const url = new URL(raw);
|
|
10620
|
+
if (url.hostname.endsWith("bing.com") && url.pathname.startsWith("/ck/")) {
|
|
10621
|
+
const encoded = url.searchParams.get("u");
|
|
10622
|
+
const decoded = decodeBingTarget(encoded);
|
|
10623
|
+
if (decoded?.startsWith("http")) return decoded;
|
|
10624
|
+
}
|
|
10625
|
+
} catch {
|
|
10626
|
+
}
|
|
10627
|
+
return raw;
|
|
10628
|
+
}
|
|
10629
|
+
function decodeBingTarget(encoded) {
|
|
10630
|
+
if (!encoded) return void 0;
|
|
10631
|
+
const payload = encoded.startsWith("a1") ? encoded.slice(2) : encoded;
|
|
10632
|
+
try {
|
|
10633
|
+
const padded = payload.replace(/-/g, "+").replace(/_/g, "/").padEnd(Math.ceil(payload.length / 4) * 4, "=");
|
|
10634
|
+
return Buffer.from(padded, "base64").toString("utf8");
|
|
10635
|
+
} catch {
|
|
10636
|
+
return void 0;
|
|
10637
|
+
}
|
|
10638
|
+
}
|
|
10051
10639
|
async function fetchWithTimeout(url, signal, timeoutMs) {
|
|
10052
10640
|
const controller = new AbortController();
|
|
10053
10641
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
@@ -10075,7 +10663,10 @@ function anySignal(...signals) {
|
|
|
10075
10663
|
return AbortSignal.any(signals);
|
|
10076
10664
|
}
|
|
10077
10665
|
function stripTags(html) {
|
|
10078
|
-
return html.replace(/<[^>]+>/g, "")
|
|
10666
|
+
return decodeHtmlEntities(html.replace(/<[^>]+>/g, "")).trim();
|
|
10667
|
+
}
|
|
10668
|
+
function decodeHtmlEntities(text) {
|
|
10669
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'");
|
|
10079
10670
|
}
|
|
10080
10671
|
var setWorkingDirTool = {
|
|
10081
10672
|
name: "set_working_dir",
|