@wrongstack/tools 0.276.4 → 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/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import { statSync, mkdirSync, createWriteStream } from 'node:fs';
|
|
|
10
10
|
import { toErrorMessage as toErrorMessage$1 } from '@wrongstack/core/utils/error';
|
|
11
11
|
import * as dns from 'node:dns/promises';
|
|
12
12
|
import * as net from 'node:net';
|
|
13
|
-
import { Agent } from 'undici';
|
|
13
|
+
import { Agent, fetch } from 'undici';
|
|
14
14
|
import TurndownService from 'turndown';
|
|
15
15
|
import { toErrorMessage as toErrorMessage$2 } from '@wrongstack/core/utils';
|
|
16
16
|
import { randomUUID } from 'node:crypto';
|
|
@@ -2762,16 +2762,28 @@ function resolvePowerShell(cmd) {
|
|
|
2762
2762
|
}
|
|
2763
2763
|
return resolved;
|
|
2764
2764
|
}
|
|
2765
|
-
var WIN32_SHELL_META = /[
|
|
2765
|
+
var WIN32_SHELL_META = /[&|<>"\r\n\0]/;
|
|
2766
2766
|
function assertSafeWin32ShellArgs(args) {
|
|
2767
|
-
for (const
|
|
2768
|
-
if (typeof
|
|
2767
|
+
for (const arg of args) {
|
|
2768
|
+
if (typeof arg === "string" && WIN32_SHELL_META.test(arg)) {
|
|
2769
2769
|
throw new Error(
|
|
2770
|
-
|
|
2770
|
+
'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)
|
|
2771
2771
|
);
|
|
2772
2772
|
}
|
|
2773
2773
|
}
|
|
2774
2774
|
}
|
|
2775
|
+
function buildWin32CmdShimInvocation(command, args = []) {
|
|
2776
|
+
assertSafeWin32ShellArgs([command, ...args]);
|
|
2777
|
+
const line = ["call", quoteWin32CmdArg(command), ...args.map(quoteWin32CmdArg)].join(" ");
|
|
2778
|
+
return {
|
|
2779
|
+
command: process.env["COMSPEC"] ?? "cmd.exe",
|
|
2780
|
+
args: ["/d", "/c", line],
|
|
2781
|
+
windowsVerbatimArguments: true
|
|
2782
|
+
};
|
|
2783
|
+
}
|
|
2784
|
+
function quoteWin32CmdArg(arg) {
|
|
2785
|
+
return `"${arg}"`;
|
|
2786
|
+
}
|
|
2775
2787
|
|
|
2776
2788
|
// src/bash.ts
|
|
2777
2789
|
var MAX_OUTPUT = 32768;
|
|
@@ -3313,10 +3325,20 @@ var DEFAULT_ALLOWED_COMMANDS = /* @__PURE__ */ new Set([
|
|
|
3313
3325
|
// C / C++ / native build
|
|
3314
3326
|
"make",
|
|
3315
3327
|
"cmake",
|
|
3328
|
+
"ninja",
|
|
3329
|
+
"clang",
|
|
3330
|
+
"clang-cl",
|
|
3331
|
+
"gcc",
|
|
3332
|
+
"g++",
|
|
3333
|
+
"link",
|
|
3334
|
+
"msbuild",
|
|
3316
3335
|
// containers / orchestration
|
|
3317
3336
|
"docker",
|
|
3318
3337
|
"podman",
|
|
3319
3338
|
"kubectl",
|
|
3339
|
+
// network (read-only intent; destructive ops still blocked by BLOCKED_ARG_PATTERNS)
|
|
3340
|
+
"curl",
|
|
3341
|
+
"wget",
|
|
3320
3342
|
// common POSIX file/text utilities
|
|
3321
3343
|
"pwd",
|
|
3322
3344
|
"ls",
|
|
@@ -3336,7 +3358,496 @@ var DEFAULT_ALLOWED_COMMANDS = /* @__PURE__ */ new Set([
|
|
|
3336
3358
|
"cp",
|
|
3337
3359
|
"mv",
|
|
3338
3360
|
"rm",
|
|
3339
|
-
"touch"
|
|
3361
|
+
"touch",
|
|
3362
|
+
"tar",
|
|
3363
|
+
// Windows-native tooling (win32). All non-destructive binaries; per-arg
|
|
3364
|
+
// safety is still enforced by BLOCKED_ARG_PATTERNS + the destructive-ops
|
|
3365
|
+
// gate in bash-kill-guard.ts. `gh` is included even though it lives at
|
|
3366
|
+
// "C:\Program Files\GitHub CLI\gh.exe" — resolveWin32Command handles the
|
|
3367
|
+
// space in the path.
|
|
3368
|
+
"gh",
|
|
3369
|
+
"where",
|
|
3370
|
+
"tasklist",
|
|
3371
|
+
"systeminfo",
|
|
3372
|
+
"wmic",
|
|
3373
|
+
"sc",
|
|
3374
|
+
"netstat",
|
|
3375
|
+
"ipconfig",
|
|
3376
|
+
"nslookup",
|
|
3377
|
+
"tracert",
|
|
3378
|
+
"pathping",
|
|
3379
|
+
// [core] Extended default allowlist (added 4b3d18d1 + this commit). All
|
|
3380
|
+
// non-destructive, broadly-used dev binaries. Per-arg safety is still
|
|
3381
|
+
// enforced by BLOCKED_ARG_PATTERNS + bash-kill-guard.ts.
|
|
3382
|
+
// --- Archives & compression ---
|
|
3383
|
+
"7z",
|
|
3384
|
+
"7za",
|
|
3385
|
+
"bzip2",
|
|
3386
|
+
"gzip",
|
|
3387
|
+
"xz",
|
|
3388
|
+
"unzip",
|
|
3389
|
+
"zip",
|
|
3390
|
+
"gtar",
|
|
3391
|
+
"bsdtar",
|
|
3392
|
+
"star",
|
|
3393
|
+
"pax",
|
|
3394
|
+
"cpio",
|
|
3395
|
+
// --- Android / mobile dev ---
|
|
3396
|
+
"adb",
|
|
3397
|
+
"fastboot",
|
|
3398
|
+
"sdkmanager",
|
|
3399
|
+
// --- DevOps / config mgmt ---
|
|
3400
|
+
"ansible",
|
|
3401
|
+
"ansible-playbook",
|
|
3402
|
+
"ansible-vault",
|
|
3403
|
+
"ansible-lint",
|
|
3404
|
+
"ansible-galaxy",
|
|
3405
|
+
"molecule",
|
|
3406
|
+
// --- Cloud CLIs ---
|
|
3407
|
+
"aws",
|
|
3408
|
+
"aws-vault",
|
|
3409
|
+
"awslocal",
|
|
3410
|
+
"az",
|
|
3411
|
+
"azcopy",
|
|
3412
|
+
"gcloud",
|
|
3413
|
+
"gsutil",
|
|
3414
|
+
"doctl",
|
|
3415
|
+
"linode-cli",
|
|
3416
|
+
// --- Native / C / C++ / linker tools ---
|
|
3417
|
+
"clang++",
|
|
3418
|
+
"clang-format",
|
|
3419
|
+
"clang-tidy",
|
|
3420
|
+
"clangd",
|
|
3421
|
+
"lld",
|
|
3422
|
+
"lldb",
|
|
3423
|
+
"ctest",
|
|
3424
|
+
"gmake",
|
|
3425
|
+
"meson",
|
|
3426
|
+
"conan",
|
|
3427
|
+
"vcpkg",
|
|
3428
|
+
"cl",
|
|
3429
|
+
"rc",
|
|
3430
|
+
"mt",
|
|
3431
|
+
"dumpbin",
|
|
3432
|
+
"dotnet-format",
|
|
3433
|
+
// --- Image / media / binary tools ---
|
|
3434
|
+
"convert",
|
|
3435
|
+
"ffmpeg",
|
|
3436
|
+
"ffprobe",
|
|
3437
|
+
"magick",
|
|
3438
|
+
"gs",
|
|
3439
|
+
"exiftool",
|
|
3440
|
+
// --- HTTP / fetch ---
|
|
3441
|
+
"wget2",
|
|
3442
|
+
"aria2c",
|
|
3443
|
+
"axel",
|
|
3444
|
+
"httpie",
|
|
3445
|
+
"hey",
|
|
3446
|
+
"ab",
|
|
3447
|
+
"wrk",
|
|
3448
|
+
"http",
|
|
3449
|
+
// --- Diff / patch / merge ---
|
|
3450
|
+
"diff",
|
|
3451
|
+
"diff3",
|
|
3452
|
+
"patch",
|
|
3453
|
+
"meld",
|
|
3454
|
+
"kdiff3",
|
|
3455
|
+
"kompare",
|
|
3456
|
+
// --- Encoding / file inspection ---
|
|
3457
|
+
"dos2unix",
|
|
3458
|
+
"unix2dos",
|
|
3459
|
+
"iconv",
|
|
3460
|
+
"file",
|
|
3461
|
+
"stat",
|
|
3462
|
+
"xxd",
|
|
3463
|
+
"hexdump",
|
|
3464
|
+
"od",
|
|
3465
|
+
"base64",
|
|
3466
|
+
// --- SSH / crypto / signing ---
|
|
3467
|
+
"ssh",
|
|
3468
|
+
"ssh-add",
|
|
3469
|
+
"ssh-keygen",
|
|
3470
|
+
"ssh-keyscan",
|
|
3471
|
+
"scp",
|
|
3472
|
+
"sftp",
|
|
3473
|
+
"rsync",
|
|
3474
|
+
"gpg",
|
|
3475
|
+
"gpg2",
|
|
3476
|
+
"gpg-agent",
|
|
3477
|
+
"openssl",
|
|
3478
|
+
"step",
|
|
3479
|
+
"keytool",
|
|
3480
|
+
// --- Search ---
|
|
3481
|
+
"egrep",
|
|
3482
|
+
"fgrep",
|
|
3483
|
+
"ag",
|
|
3484
|
+
"ack",
|
|
3485
|
+
"sift",
|
|
3486
|
+
"ugrep",
|
|
3487
|
+
"fd",
|
|
3488
|
+
"fdfind",
|
|
3489
|
+
"jq",
|
|
3490
|
+
"yq",
|
|
3491
|
+
"xq",
|
|
3492
|
+
"fx",
|
|
3493
|
+
"gron",
|
|
3494
|
+
// --- K8s / container ecosystem ---
|
|
3495
|
+
"kubectl.exe",
|
|
3496
|
+
"kubeadm",
|
|
3497
|
+
"kubelet",
|
|
3498
|
+
"helm",
|
|
3499
|
+
"k9s",
|
|
3500
|
+
"kustomize",
|
|
3501
|
+
"skaffold",
|
|
3502
|
+
"tilt",
|
|
3503
|
+
"minikube",
|
|
3504
|
+
"kind",
|
|
3505
|
+
"k3d",
|
|
3506
|
+
"k3s",
|
|
3507
|
+
"docker-compose",
|
|
3508
|
+
"buildah",
|
|
3509
|
+
"skopeo",
|
|
3510
|
+
"nerdctl",
|
|
3511
|
+
"ctr",
|
|
3512
|
+
"ctr.exe",
|
|
3513
|
+
// --- Databases ---
|
|
3514
|
+
"sqlite3",
|
|
3515
|
+
"sqlite",
|
|
3516
|
+
"psql",
|
|
3517
|
+
"pg_dump",
|
|
3518
|
+
"pg_restore",
|
|
3519
|
+
"mysql",
|
|
3520
|
+
"mysqladmin",
|
|
3521
|
+
"mysqldump",
|
|
3522
|
+
"mariadb",
|
|
3523
|
+
"mariadb-dump",
|
|
3524
|
+
"redis-cli",
|
|
3525
|
+
"redis-server",
|
|
3526
|
+
"memcached",
|
|
3527
|
+
"etcdctl",
|
|
3528
|
+
"consul",
|
|
3529
|
+
"vault",
|
|
3530
|
+
"nomad",
|
|
3531
|
+
"mongosh",
|
|
3532
|
+
"mongo",
|
|
3533
|
+
"mongoexport",
|
|
3534
|
+
"mongoimport",
|
|
3535
|
+
"mongodump",
|
|
3536
|
+
"mongorestore",
|
|
3537
|
+
// --- Windows extended (read-mostly ops) ---
|
|
3538
|
+
"taskkill",
|
|
3539
|
+
"gpupdate",
|
|
3540
|
+
"gpresult",
|
|
3541
|
+
"hostname",
|
|
3542
|
+
"whoami",
|
|
3543
|
+
"who",
|
|
3544
|
+
"net",
|
|
3545
|
+
"net1",
|
|
3546
|
+
// --- VCS ecosystem ---
|
|
3547
|
+
"glab",
|
|
3548
|
+
"hub",
|
|
3549
|
+
"tea",
|
|
3550
|
+
"git-lfs",
|
|
3551
|
+
"tig",
|
|
3552
|
+
"lazygit",
|
|
3553
|
+
// --- POSIX text utilities (extended; duplicates of pwd/ls/cat/head/tail/wc/
|
|
3554
|
+
// grep/find/echo/awk/mkdir/cp/mv/rm/touch from the base list above are
|
|
3555
|
+
// omitted — the Set is de-duplicated at runtime but a clean literal is
|
|
3556
|
+
// easier to maintain) ---
|
|
3557
|
+
"gawk",
|
|
3558
|
+
"tr",
|
|
3559
|
+
"cut",
|
|
3560
|
+
"paste",
|
|
3561
|
+
"join",
|
|
3562
|
+
"comm",
|
|
3563
|
+
"expand",
|
|
3564
|
+
"unexpand",
|
|
3565
|
+
"fold",
|
|
3566
|
+
"fmt",
|
|
3567
|
+
"nl",
|
|
3568
|
+
"pr",
|
|
3569
|
+
"column",
|
|
3570
|
+
"tsort",
|
|
3571
|
+
"tty",
|
|
3572
|
+
"ul",
|
|
3573
|
+
"units",
|
|
3574
|
+
"factor",
|
|
3575
|
+
"seq",
|
|
3576
|
+
"shuf",
|
|
3577
|
+
"look",
|
|
3578
|
+
"yes",
|
|
3579
|
+
"true",
|
|
3580
|
+
"false",
|
|
3581
|
+
"test",
|
|
3582
|
+
"[",
|
|
3583
|
+
"printf",
|
|
3584
|
+
"env",
|
|
3585
|
+
"tree",
|
|
3586
|
+
"locate",
|
|
3587
|
+
"which",
|
|
3588
|
+
"whereis",
|
|
3589
|
+
"type",
|
|
3590
|
+
"hash",
|
|
3591
|
+
"pushd",
|
|
3592
|
+
"popd",
|
|
3593
|
+
"dirs",
|
|
3594
|
+
"history",
|
|
3595
|
+
"fc",
|
|
3596
|
+
"jobs",
|
|
3597
|
+
"bg",
|
|
3598
|
+
"fg",
|
|
3599
|
+
"wait",
|
|
3600
|
+
"ulimit",
|
|
3601
|
+
"umask",
|
|
3602
|
+
"nice",
|
|
3603
|
+
"nohup",
|
|
3604
|
+
"timeout",
|
|
3605
|
+
"time",
|
|
3606
|
+
"trap",
|
|
3607
|
+
"exit",
|
|
3608
|
+
"return",
|
|
3609
|
+
"source",
|
|
3610
|
+
".",
|
|
3611
|
+
"alias",
|
|
3612
|
+
"unalias",
|
|
3613
|
+
"set",
|
|
3614
|
+
"unset",
|
|
3615
|
+
"export",
|
|
3616
|
+
"readonly",
|
|
3617
|
+
"typeset",
|
|
3618
|
+
"declare",
|
|
3619
|
+
"local",
|
|
3620
|
+
"eval",
|
|
3621
|
+
"exec",
|
|
3622
|
+
// --- Process / system inspection ---
|
|
3623
|
+
"htop",
|
|
3624
|
+
"top",
|
|
3625
|
+
"atop",
|
|
3626
|
+
"glances",
|
|
3627
|
+
"iotop",
|
|
3628
|
+
"nethogs",
|
|
3629
|
+
"iftop",
|
|
3630
|
+
"lsof",
|
|
3631
|
+
"strace",
|
|
3632
|
+
"ltrace",
|
|
3633
|
+
"sysstat",
|
|
3634
|
+
"vmstat",
|
|
3635
|
+
"iostat",
|
|
3636
|
+
"mpstat",
|
|
3637
|
+
"sar",
|
|
3638
|
+
"free",
|
|
3639
|
+
"df",
|
|
3640
|
+
"du",
|
|
3641
|
+
"mount",
|
|
3642
|
+
"umount",
|
|
3643
|
+
"lsblk",
|
|
3644
|
+
"blkid",
|
|
3645
|
+
"kill",
|
|
3646
|
+
"killall",
|
|
3647
|
+
"pkill",
|
|
3648
|
+
"pgrep",
|
|
3649
|
+
"pidof",
|
|
3650
|
+
"ps",
|
|
3651
|
+
"ps.exe",
|
|
3652
|
+
// --- Network inspection ---
|
|
3653
|
+
"ip",
|
|
3654
|
+
"ss",
|
|
3655
|
+
"route",
|
|
3656
|
+
"arp",
|
|
3657
|
+
"arping",
|
|
3658
|
+
"ping",
|
|
3659
|
+
"ping6",
|
|
3660
|
+
"hping3",
|
|
3661
|
+
"mtr",
|
|
3662
|
+
"tracepath",
|
|
3663
|
+
"tcpdump",
|
|
3664
|
+
"nmap",
|
|
3665
|
+
"netcat",
|
|
3666
|
+
"nc",
|
|
3667
|
+
"ncat",
|
|
3668
|
+
"socat",
|
|
3669
|
+
// --- Sync / backup ---
|
|
3670
|
+
"rclone",
|
|
3671
|
+
"restic",
|
|
3672
|
+
"borg",
|
|
3673
|
+
"duplicati",
|
|
3674
|
+
"duplicacy",
|
|
3675
|
+
"syncthing",
|
|
3676
|
+
"syncthing-cli",
|
|
3677
|
+
// --- Permissions / users / ACLs (POSIX) ---
|
|
3678
|
+
"useradd",
|
|
3679
|
+
"userdel",
|
|
3680
|
+
"usermod",
|
|
3681
|
+
"groupadd",
|
|
3682
|
+
"groupdel",
|
|
3683
|
+
"groupmod",
|
|
3684
|
+
"chown",
|
|
3685
|
+
"chmod",
|
|
3686
|
+
"chgrp",
|
|
3687
|
+
"getfacl",
|
|
3688
|
+
"setfacl",
|
|
3689
|
+
"setcap",
|
|
3690
|
+
"getcap",
|
|
3691
|
+
// --- Crypto / cert mgmt (extended) ---
|
|
3692
|
+
"certbot",
|
|
3693
|
+
"mkcert",
|
|
3694
|
+
"jarsigner",
|
|
3695
|
+
// --- Editors ---
|
|
3696
|
+
"subl",
|
|
3697
|
+
"code",
|
|
3698
|
+
"code-insiders",
|
|
3699
|
+
"cursor",
|
|
3700
|
+
"atom",
|
|
3701
|
+
"nano",
|
|
3702
|
+
"vim",
|
|
3703
|
+
"nvim",
|
|
3704
|
+
"vi",
|
|
3705
|
+
"emacs",
|
|
3706
|
+
"helix",
|
|
3707
|
+
"hx",
|
|
3708
|
+
"micro",
|
|
3709
|
+
"jed",
|
|
3710
|
+
"ed",
|
|
3711
|
+
"ex",
|
|
3712
|
+
"mg",
|
|
3713
|
+
// --- Terminal multiplexers ---
|
|
3714
|
+
"asciinema",
|
|
3715
|
+
"script",
|
|
3716
|
+
"scriptreplay",
|
|
3717
|
+
"expect",
|
|
3718
|
+
"screen",
|
|
3719
|
+
"tmux",
|
|
3720
|
+
"byobu",
|
|
3721
|
+
"dtach",
|
|
3722
|
+
"abduco",
|
|
3723
|
+
// --- Calculators / REPLs / scientific ---
|
|
3724
|
+
"bc",
|
|
3725
|
+
"dc",
|
|
3726
|
+
"calc",
|
|
3727
|
+
"qalc",
|
|
3728
|
+
"genius",
|
|
3729
|
+
"octave",
|
|
3730
|
+
"R",
|
|
3731
|
+
"Rscript",
|
|
3732
|
+
"julia",
|
|
3733
|
+
"irb",
|
|
3734
|
+
"pry",
|
|
3735
|
+
"ghci",
|
|
3736
|
+
"stack",
|
|
3737
|
+
"cabal",
|
|
3738
|
+
"ghc",
|
|
3739
|
+
// --- PHP / Lua / Perl / Ruby ecosystem (extended) ---
|
|
3740
|
+
"php8",
|
|
3741
|
+
"php7",
|
|
3742
|
+
"phpcs",
|
|
3743
|
+
"phpcbf",
|
|
3744
|
+
"phpmd",
|
|
3745
|
+
"phpstan",
|
|
3746
|
+
"psalm",
|
|
3747
|
+
"lua",
|
|
3748
|
+
"lua5.1",
|
|
3749
|
+
"lua5.2",
|
|
3750
|
+
"lua5.3",
|
|
3751
|
+
"lua5.4",
|
|
3752
|
+
"luarocks",
|
|
3753
|
+
"perl",
|
|
3754
|
+
"cpan",
|
|
3755
|
+
"prove",
|
|
3756
|
+
"plackup",
|
|
3757
|
+
"rake",
|
|
3758
|
+
"rspec",
|
|
3759
|
+
"jekyll",
|
|
3760
|
+
"node-gyp",
|
|
3761
|
+
"node-pre-gyp",
|
|
3762
|
+
// --- JS / TS toolchain (extended) ---
|
|
3763
|
+
"electron",
|
|
3764
|
+
"electron-builder",
|
|
3765
|
+
"electron-forge",
|
|
3766
|
+
"vite-preview",
|
|
3767
|
+
"swc",
|
|
3768
|
+
"swc-cli",
|
|
3769
|
+
"swcpack",
|
|
3770
|
+
"mocha",
|
|
3771
|
+
"chai",
|
|
3772
|
+
"jasmine",
|
|
3773
|
+
"puppeteer",
|
|
3774
|
+
"lighthouse",
|
|
3775
|
+
// --- Linters / formatters (extended) ---
|
|
3776
|
+
"tslint",
|
|
3777
|
+
"stylelint",
|
|
3778
|
+
"htmlhint",
|
|
3779
|
+
"jshint",
|
|
3780
|
+
"jslint",
|
|
3781
|
+
"jscs",
|
|
3782
|
+
// --- Document conversion ---
|
|
3783
|
+
"pandoc",
|
|
3784
|
+
"weasyprint",
|
|
3785
|
+
"wkhtmltopdf",
|
|
3786
|
+
"wkhtmltoimage",
|
|
3787
|
+
"prince",
|
|
3788
|
+
"mdp",
|
|
3789
|
+
"markdown",
|
|
3790
|
+
"multimarkdown",
|
|
3791
|
+
"cmark",
|
|
3792
|
+
"cmark-gfm",
|
|
3793
|
+
// --- Office / spreadsheet ---
|
|
3794
|
+
"soffice",
|
|
3795
|
+
"libreoffice",
|
|
3796
|
+
"unoconv",
|
|
3797
|
+
"abiword",
|
|
3798
|
+
"gnumeric",
|
|
3799
|
+
// --- Spell / grammar ---
|
|
3800
|
+
"aspell",
|
|
3801
|
+
"hunspell",
|
|
3802
|
+
"enchant",
|
|
3803
|
+
"languagetool",
|
|
3804
|
+
// --- Source-highlight / diff tools ---
|
|
3805
|
+
"delta",
|
|
3806
|
+
"bat",
|
|
3807
|
+
"ccat",
|
|
3808
|
+
"hl",
|
|
3809
|
+
"highlight",
|
|
3810
|
+
"source-highlight",
|
|
3811
|
+
"ansifilter",
|
|
3812
|
+
// --- Job schedulers ---
|
|
3813
|
+
"pueue",
|
|
3814
|
+
"task-spooler",
|
|
3815
|
+
"ts",
|
|
3816
|
+
"at",
|
|
3817
|
+
"atd",
|
|
3818
|
+
"anacron",
|
|
3819
|
+
"fcron",
|
|
3820
|
+
"cronie",
|
|
3821
|
+
"systemd-run",
|
|
3822
|
+
"systemd-cat",
|
|
3823
|
+
// --- Plotting / visualization ---
|
|
3824
|
+
"gnuplot",
|
|
3825
|
+
"gnuplot-nox",
|
|
3826
|
+
"veusz",
|
|
3827
|
+
"scidavis",
|
|
3828
|
+
"grace",
|
|
3829
|
+
"xmgrace",
|
|
3830
|
+
"labplot",
|
|
3831
|
+
// --- Security / recon (network + web) ---
|
|
3832
|
+
"masscan",
|
|
3833
|
+
"zmap",
|
|
3834
|
+
"rustscan",
|
|
3835
|
+
"amass",
|
|
3836
|
+
"subfinder",
|
|
3837
|
+
"httpx",
|
|
3838
|
+
"nuclei",
|
|
3839
|
+
"naabu",
|
|
3840
|
+
"katana",
|
|
3841
|
+
"dnsx",
|
|
3842
|
+
"assetfinder",
|
|
3843
|
+
"findomain",
|
|
3844
|
+
"gau",
|
|
3845
|
+
"waybackurls",
|
|
3846
|
+
"httprobe",
|
|
3847
|
+
"meg",
|
|
3848
|
+
"subjack",
|
|
3849
|
+
"sublert",
|
|
3850
|
+
"chaos"
|
|
3340
3851
|
]);
|
|
3341
3852
|
var allowedCommands = new Set(DEFAULT_ALLOWED_COMMANDS);
|
|
3342
3853
|
var normalizeCmd = (c) => c.trim();
|
|
@@ -3559,17 +4070,18 @@ function runCommand(cmd, args, cwd, timeout, signal, sessionId) {
|
|
|
3559
4070
|
const spool = createOutputSpool({ tool: `exec-${cmd}`, thresholdBytes: MAX_OUTPUT2 });
|
|
3560
4071
|
const resolved = resolveWin32Command(cmd);
|
|
3561
4072
|
const needsShell = isWin2 && (resolved.endsWith(".cmd") || resolved.endsWith(".bat"));
|
|
3562
|
-
const
|
|
3563
|
-
|
|
4073
|
+
const shim = needsShell ? buildWin32CmdShimInvocation(resolved, args) : null;
|
|
4074
|
+
const spawnCmd = shim?.command ?? resolved;
|
|
4075
|
+
const spawnArgs = shim?.args ?? args;
|
|
3564
4076
|
let child;
|
|
3565
4077
|
try {
|
|
3566
|
-
child = spawn(spawnCmd,
|
|
4078
|
+
child = spawn(spawnCmd, spawnArgs, {
|
|
3567
4079
|
cwd,
|
|
3568
4080
|
env: buildChildEnv(sessionId),
|
|
3569
4081
|
stdio: ["ignore", "pipe", "pipe"],
|
|
3570
4082
|
windowsHide: true,
|
|
3571
4083
|
...isWin2 ? {} : { signal },
|
|
3572
|
-
...
|
|
4084
|
+
...shim ? { windowsVerbatimArguments: shim.windowsVerbatimArguments } : {}
|
|
3573
4085
|
});
|
|
3574
4086
|
} catch (err) {
|
|
3575
4087
|
spool.finalize();
|
|
@@ -3664,6 +4176,7 @@ TD.addRule("stripDangerousElements", {
|
|
|
3664
4176
|
});
|
|
3665
4177
|
var MAX_BYTES2 = 131072;
|
|
3666
4178
|
var TIMEOUT_MS = 2e4;
|
|
4179
|
+
var nativeGlobalFetch = globalThis.fetch;
|
|
3667
4180
|
var ALLOW_PRIVATE = process.env["WRONGSTACK_FETCH_ALLOW_PRIVATE"] === "1";
|
|
3668
4181
|
if (ALLOW_PRIVATE && !process.env["CI"]) {
|
|
3669
4182
|
console.warn(
|
|
@@ -3713,6 +4226,9 @@ function getPinnedDispatcher() {
|
|
|
3713
4226
|
}
|
|
3714
4227
|
return pinnedAgent;
|
|
3715
4228
|
}
|
|
4229
|
+
function dispatcherFetch() {
|
|
4230
|
+
return globalThis.fetch === nativeGlobalFetch ? fetch : globalThis.fetch;
|
|
4231
|
+
}
|
|
3716
4232
|
var _beforeExitRegistered = false;
|
|
3717
4233
|
if (!_beforeExitRegistered) {
|
|
3718
4234
|
_beforeExitRegistered = true;
|
|
@@ -3748,7 +4264,7 @@ async function guardedFetch(url, maxRedirects, signal, headers = {
|
|
|
3748
4264
|
headers,
|
|
3749
4265
|
dispatcher: getPinnedDispatcher()
|
|
3750
4266
|
};
|
|
3751
|
-
const res = await
|
|
4267
|
+
const res = await dispatcherFetch()(currentUrl, init);
|
|
3752
4268
|
if (res.status < 300 || res.status > 399) {
|
|
3753
4269
|
return res;
|
|
3754
4270
|
}
|
|
@@ -3776,7 +4292,7 @@ var fetchTool = {
|
|
|
3776
4292
|
category: "Network",
|
|
3777
4293
|
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).",
|
|
3778
4294
|
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`.",
|
|
3779
|
-
permission: "
|
|
4295
|
+
permission: "auto",
|
|
3780
4296
|
mutating: false,
|
|
3781
4297
|
capabilities: ["net.outbound"],
|
|
3782
4298
|
icon: "web",
|
|
@@ -4017,7 +4533,7 @@ var searchTool = {
|
|
|
4017
4533
|
category: "Search",
|
|
4018
4534
|
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.",
|
|
4019
4535
|
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.",
|
|
4020
|
-
permission: "
|
|
4536
|
+
permission: "auto",
|
|
4021
4537
|
mutating: false,
|
|
4022
4538
|
capabilities: ["net.outbound"],
|
|
4023
4539
|
icon: "search",
|
|
@@ -4080,15 +4596,15 @@ var searchTool = {
|
|
|
4080
4596
|
};
|
|
4081
4597
|
yield {
|
|
4082
4598
|
type: "partial_output",
|
|
4083
|
-
text: `${results.length} cached results from ${source}`,
|
|
4084
|
-
data: { count: results.length, cached: true }
|
|
4599
|
+
text: `${results.length} cached results from ${entry.source}`,
|
|
4600
|
+
data: { count: results.length, cached: true, source: entry.source }
|
|
4085
4601
|
};
|
|
4086
4602
|
yield {
|
|
4087
4603
|
type: "final",
|
|
4088
4604
|
output: {
|
|
4089
4605
|
query: input.query,
|
|
4090
4606
|
results: results.slice(0, num),
|
|
4091
|
-
source,
|
|
4607
|
+
source: entry.source,
|
|
4092
4608
|
truncated: results.length >= num,
|
|
4093
4609
|
cached: true
|
|
4094
4610
|
}
|
|
@@ -4102,6 +4618,7 @@ var searchTool = {
|
|
|
4102
4618
|
data: { source, query: input.query, cached: false }
|
|
4103
4619
|
};
|
|
4104
4620
|
let rawResults;
|
|
4621
|
+
let effectiveSource = source;
|
|
4105
4622
|
switch (source) {
|
|
4106
4623
|
case "duckduckgo":
|
|
4107
4624
|
rawResults = await duckduckgoSearch(input.query, num, opts.signal);
|
|
@@ -4118,24 +4635,24 @@ var searchTool = {
|
|
|
4118
4635
|
field: "source"
|
|
4119
4636
|
});
|
|
4120
4637
|
}
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4638
|
+
let ranked = rankSearchResults(rawResults, input.query);
|
|
4639
|
+
if (source !== "duckduckgo" && shouldFallbackToDuckDuckGo(ranked, input.query)) {
|
|
4640
|
+
yield {
|
|
4641
|
+
type: "log",
|
|
4642
|
+
text: `${source} returned no relevant static results; falling back to duckduckgo`,
|
|
4643
|
+
data: { source, fallback: "duckduckgo", query: input.query }
|
|
4644
|
+
};
|
|
4645
|
+
rawResults = await duckduckgoSearch(input.query, num, opts.signal);
|
|
4646
|
+
ranked = rankSearchResults(rawResults, input.query);
|
|
4647
|
+
effectiveSource = "duckduckgo";
|
|
4130
4648
|
}
|
|
4131
|
-
const ranked = scoreResults(deduped, input.query);
|
|
4132
4649
|
const finalResults = ranked.slice(0, num);
|
|
4133
|
-
cache.set(cacheKey, { results: ranked, timestamp: Date.now() });
|
|
4650
|
+
cache.set(cacheKey, { results: ranked, source: effectiveSource, timestamp: Date.now() });
|
|
4134
4651
|
pruneStaleCacheEntries();
|
|
4135
4652
|
yield {
|
|
4136
4653
|
type: "partial_output",
|
|
4137
|
-
text: `${finalResults.length} results from ${
|
|
4138
|
-
data: { count: finalResults.length, cached: false }
|
|
4654
|
+
text: `${finalResults.length} results from ${effectiveSource}`,
|
|
4655
|
+
data: { count: finalResults.length, cached: false, source: effectiveSource }
|
|
4139
4656
|
};
|
|
4140
4657
|
yield {
|
|
4141
4658
|
type: "final",
|
|
@@ -4146,7 +4663,7 @@ var searchTool = {
|
|
|
4146
4663
|
url: r.url,
|
|
4147
4664
|
snippet: r.snippet
|
|
4148
4665
|
})),
|
|
4149
|
-
source,
|
|
4666
|
+
source: effectiveSource,
|
|
4150
4667
|
truncated: finalResults.length >= num,
|
|
4151
4668
|
cached: false
|
|
4152
4669
|
}
|
|
@@ -4159,6 +4676,19 @@ function pruneStaleCacheEntries() {
|
|
|
4159
4676
|
if (entry.timestamp < cutoff) cache.delete(key);
|
|
4160
4677
|
}
|
|
4161
4678
|
}
|
|
4679
|
+
function rankSearchResults(results, query) {
|
|
4680
|
+
const seenUrls = /* @__PURE__ */ new Set();
|
|
4681
|
+
const deduped = [];
|
|
4682
|
+
for (const r of results) {
|
|
4683
|
+
const noQuery = r.url.split("?")[0] ?? r.url;
|
|
4684
|
+
const normalized = noQuery.split("#")[0] ?? r.url;
|
|
4685
|
+
if (!seenUrls.has(normalized) && r.url.startsWith("http")) {
|
|
4686
|
+
seenUrls.add(normalized);
|
|
4687
|
+
deduped.push(r);
|
|
4688
|
+
}
|
|
4689
|
+
}
|
|
4690
|
+
return scoreResults(deduped, query);
|
|
4691
|
+
}
|
|
4162
4692
|
function scoreResults(results, query) {
|
|
4163
4693
|
const terms = query.toLowerCase().split(/\s+/).filter((t) => t.length > 0);
|
|
4164
4694
|
return results.map((r) => {
|
|
@@ -4172,6 +4702,15 @@ function scoreResults(results, query) {
|
|
|
4172
4702
|
return { ...r, score };
|
|
4173
4703
|
}).sort((a, b) => b.score - a.score);
|
|
4174
4704
|
}
|
|
4705
|
+
function shouldFallbackToDuckDuckGo(results, query) {
|
|
4706
|
+
if (results.length === 0) return true;
|
|
4707
|
+
const terms = query.toLowerCase().split(/\s+/).filter((t) => t.length >= 3);
|
|
4708
|
+
if (terms.length === 0) return false;
|
|
4709
|
+
return !results.some((r) => {
|
|
4710
|
+
const haystack = `${r.title} ${r.url} ${r.snippet}`.toLowerCase();
|
|
4711
|
+
return terms.some((term) => haystack.includes(term));
|
|
4712
|
+
});
|
|
4713
|
+
}
|
|
4175
4714
|
async function duckduckgoSearch(query, num, signal) {
|
|
4176
4715
|
const encoded = encodeURIComponent(query);
|
|
4177
4716
|
const url = `https://lite.duckduckgo.com/lite/?q=${encoded}&kd=-1&kl=wt-wt`;
|
|
@@ -4196,14 +4735,19 @@ function takeFrom(iter, max) {
|
|
|
4196
4735
|
}
|
|
4197
4736
|
function parseDuckDuckGo(html, num) {
|
|
4198
4737
|
const results = [];
|
|
4199
|
-
const
|
|
4200
|
-
const
|
|
4738
|
+
const linkRegex = /<a\b([^>]*\bclass=(["'])[^"']*\bresult-link\b[^"']*\2[^>]*)>([\s\S]*?)<\/a>/gi;
|
|
4739
|
+
const snippetRegex = /<([a-z0-9]+)\b([^>]*\bclass=(["'])[^"']*\bresult-snippet\b[^"']*\3[^>]*)>([\s\S]*?)<\/\1>/gi;
|
|
4201
4740
|
const linkMatches = takeFrom(
|
|
4202
|
-
[...html.matchAll(
|
|
4741
|
+
[...html.matchAll(linkRegex)].map((m) => {
|
|
4742
|
+
const attrs = expectDefined(m[1]);
|
|
4743
|
+
const href = getHtmlAttr(attrs, "href");
|
|
4744
|
+
const title = stripTags(expectDefined(m[3]));
|
|
4745
|
+
return href && title ? { url: normalizeDuckDuckGoUrl(href), title } : void 0;
|
|
4746
|
+
}).filter((m) => m !== void 0),
|
|
4203
4747
|
num
|
|
4204
4748
|
);
|
|
4205
4749
|
const snippetMatches = takeFrom(
|
|
4206
|
-
[...html.matchAll(
|
|
4750
|
+
[...html.matchAll(snippetRegex)].filter((m) => m[4]).map((m) => stripTags(expectDefined(m[4]))),
|
|
4207
4751
|
num
|
|
4208
4752
|
);
|
|
4209
4753
|
for (let i = 0; i < linkMatches.length && i < num; i++) {
|
|
@@ -4219,6 +4763,24 @@ function parseDuckDuckGo(html, num) {
|
|
|
4219
4763
|
}
|
|
4220
4764
|
return results;
|
|
4221
4765
|
}
|
|
4766
|
+
function getHtmlAttr(attrs, name) {
|
|
4767
|
+
const quoted = new RegExp(`\\b${name}\\s*=\\s*(["'])(.*?)\\1`, "i").exec(attrs);
|
|
4768
|
+
if (quoted?.[2]) return decodeHtmlEntities(quoted[2]);
|
|
4769
|
+
const unquoted = new RegExp(`\\b${name}\\s*=\\s*([^\\s>]+)`, "i").exec(attrs);
|
|
4770
|
+
return unquoted?.[1] ? decodeHtmlEntities(unquoted[1]) : void 0;
|
|
4771
|
+
}
|
|
4772
|
+
function normalizeDuckDuckGoUrl(raw) {
|
|
4773
|
+
if (raw.startsWith("//")) return `https:${raw}`;
|
|
4774
|
+
if (!raw.startsWith("/")) return raw;
|
|
4775
|
+
if (!raw.startsWith("/l/")) return raw;
|
|
4776
|
+
try {
|
|
4777
|
+
const url = new URL(raw, "https://duckduckgo.com");
|
|
4778
|
+
const uddg = url.searchParams.get("uddg");
|
|
4779
|
+
return uddg?.startsWith("http") ? uddg : url.toString();
|
|
4780
|
+
} catch {
|
|
4781
|
+
return raw;
|
|
4782
|
+
}
|
|
4783
|
+
}
|
|
4222
4784
|
async function googleSearch(query, num, signal) {
|
|
4223
4785
|
const encoded = encodeURIComponent(query);
|
|
4224
4786
|
const url = `https://www.google.com/search?q=${encoded}&hl=en`;
|
|
@@ -4260,29 +4822,53 @@ async function bingSearch(query, num, signal) {
|
|
|
4260
4822
|
}
|
|
4261
4823
|
function parseBingResults(html, num) {
|
|
4262
4824
|
const results = [];
|
|
4263
|
-
const
|
|
4264
|
-
const
|
|
4265
|
-
const entries = takeFrom(
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4825
|
+
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]));
|
|
4826
|
+
const candidates = blocks.length > 0 ? blocks : [html];
|
|
4827
|
+
const entries = takeFrom(candidates.flatMap((block) => {
|
|
4828
|
+
const titleMatch = /<h2[^>]*>\s*<a\b([^>]*)>([\s\S]*?)<\/a>\s*<\/h2>/i.exec(block);
|
|
4829
|
+
if (!titleMatch) return [];
|
|
4830
|
+
const href = getHtmlAttr(expectDefined(titleMatch[1]), "href");
|
|
4831
|
+
const title = stripTags(expectDefined(titleMatch[2]));
|
|
4832
|
+
if (!href || !title) return [];
|
|
4833
|
+
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);
|
|
4834
|
+
const snippet = snippetMatch ? stripTags(expectDefined(snippetMatch.at(-1))) : "";
|
|
4835
|
+
return [{ url: normalizeBingUrl(href), title, snippet, score: 1 }];
|
|
4836
|
+
}), num);
|
|
4273
4837
|
for (let i = 0; i < entries.length; i++) {
|
|
4274
4838
|
const entry = entries[i];
|
|
4275
4839
|
if (entry) {
|
|
4276
4840
|
results.push({
|
|
4277
4841
|
title: entry.title ?? "",
|
|
4278
4842
|
url: entry.url ?? "",
|
|
4279
|
-
snippet:
|
|
4843
|
+
snippet: entry.snippet ?? "",
|
|
4280
4844
|
score: 1
|
|
4281
4845
|
});
|
|
4282
4846
|
}
|
|
4283
4847
|
}
|
|
4284
4848
|
return results;
|
|
4285
4849
|
}
|
|
4850
|
+
function normalizeBingUrl(raw) {
|
|
4851
|
+
try {
|
|
4852
|
+
const url = new URL(raw);
|
|
4853
|
+
if (url.hostname.endsWith("bing.com") && url.pathname.startsWith("/ck/")) {
|
|
4854
|
+
const encoded = url.searchParams.get("u");
|
|
4855
|
+
const decoded = decodeBingTarget(encoded);
|
|
4856
|
+
if (decoded?.startsWith("http")) return decoded;
|
|
4857
|
+
}
|
|
4858
|
+
} catch {
|
|
4859
|
+
}
|
|
4860
|
+
return raw;
|
|
4861
|
+
}
|
|
4862
|
+
function decodeBingTarget(encoded) {
|
|
4863
|
+
if (!encoded) return void 0;
|
|
4864
|
+
const payload = encoded.startsWith("a1") ? encoded.slice(2) : encoded;
|
|
4865
|
+
try {
|
|
4866
|
+
const padded = payload.replace(/-/g, "+").replace(/_/g, "/").padEnd(Math.ceil(payload.length / 4) * 4, "=");
|
|
4867
|
+
return Buffer.from(padded, "base64").toString("utf8");
|
|
4868
|
+
} catch {
|
|
4869
|
+
return void 0;
|
|
4870
|
+
}
|
|
4871
|
+
}
|
|
4286
4872
|
async function fetchWithTimeout(url, signal, timeoutMs) {
|
|
4287
4873
|
const controller = new AbortController();
|
|
4288
4874
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
@@ -4310,7 +4896,10 @@ function anySignal(...signals) {
|
|
|
4310
4896
|
return AbortSignal.any(signals);
|
|
4311
4897
|
}
|
|
4312
4898
|
function stripTags(html) {
|
|
4313
|
-
return html.replace(/<[^>]+>/g, "")
|
|
4899
|
+
return decodeHtmlEntities(html.replace(/<[^>]+>/g, "")).trim();
|
|
4900
|
+
}
|
|
4901
|
+
function decodeHtmlEntities(text) {
|
|
4902
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'");
|
|
4314
4903
|
}
|
|
4315
4904
|
var todoTool = {
|
|
4316
4905
|
name: "todo",
|
|
@@ -5880,15 +6469,16 @@ async function* spawnStream(opts) {
|
|
|
5880
6469
|
const spool = createOutputSpool({ tool: opts.cmd, thresholdBytes: max });
|
|
5881
6470
|
const resolved = resolveWin32Command(opts.cmd);
|
|
5882
6471
|
const needsShell = isWin3 && (resolved.endsWith(".cmd") || resolved.endsWith(".bat"));
|
|
5883
|
-
const
|
|
5884
|
-
|
|
5885
|
-
const
|
|
6472
|
+
const shim = needsShell ? buildWin32CmdShimInvocation(resolved, opts.args) : null;
|
|
6473
|
+
const cmd = shim?.command ?? resolved;
|
|
6474
|
+
const args = shim?.args ?? opts.args;
|
|
6475
|
+
const child = spawn(cmd, args, {
|
|
5886
6476
|
cwd: opts.cwd,
|
|
5887
6477
|
env: buildChildEnv(),
|
|
5888
6478
|
stdio: ["ignore", "pipe", "pipe"],
|
|
5889
6479
|
windowsHide: true,
|
|
5890
6480
|
...isWin3 ? {} : { signal: opts.signal },
|
|
5891
|
-
...
|
|
6481
|
+
...shim ? { windowsVerbatimArguments: shim.windowsVerbatimArguments } : {}
|
|
5892
6482
|
});
|
|
5893
6483
|
const registry = getProcessRegistry();
|
|
5894
6484
|
const pid = child.pid;
|
|
@@ -6135,7 +6725,7 @@ var formatTool = {
|
|
|
6135
6725
|
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.",
|
|
6136
6726
|
permission: "confirm",
|
|
6137
6727
|
mutating: true,
|
|
6138
|
-
capabilities: ["fs.write", "shell.
|
|
6728
|
+
capabilities: ["fs.write", "shell.restricted"],
|
|
6139
6729
|
icon: "code",
|
|
6140
6730
|
timeoutMs: 6e4,
|
|
6141
6731
|
inputSchema: {
|
|
@@ -6788,9 +7378,10 @@ function runOutdated(manager, args, cwd, signal) {
|
|
|
6788
7378
|
const MAX = 1e5;
|
|
6789
7379
|
const resolved = resolveWin32Command(manager);
|
|
6790
7380
|
const needsShell = process.platform === "win32" && (resolved.endsWith(".cmd") || resolved.endsWith(".bat"));
|
|
6791
|
-
const
|
|
6792
|
-
|
|
6793
|
-
const
|
|
7381
|
+
const shim = needsShell ? buildWin32CmdShimInvocation(resolved, args) : null;
|
|
7382
|
+
const spawnCmd = shim?.command ?? resolved;
|
|
7383
|
+
const spawnArgs = shim?.args ?? args;
|
|
7384
|
+
const child = spawn(spawnCmd, spawnArgs, { cwd, signal, env: buildChildEnv(), stdio: ["ignore", "pipe", "pipe"], windowsHide: true, ...shim ? { windowsVerbatimArguments: shim.windowsVerbatimArguments } : {} });
|
|
6794
7385
|
child.stdout?.on("data", (c) => {
|
|
6795
7386
|
if (stdout.length < MAX) stdout += c.toString();
|
|
6796
7387
|
});
|
|
@@ -7395,9 +7986,9 @@ var designTool = {
|
|
|
7395
7986
|
category: "Design",
|
|
7396
7987
|
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).',
|
|
7397
7988
|
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"}`.',
|
|
7398
|
-
permission: "
|
|
7399
|
-
mutating:
|
|
7400
|
-
capabilities: [],
|
|
7989
|
+
permission: "confirm",
|
|
7990
|
+
mutating: true,
|
|
7991
|
+
capabilities: ["fs.write"],
|
|
7401
7992
|
timeoutMs: 15e3,
|
|
7402
7993
|
inputSchema: {
|
|
7403
7994
|
type: "object",
|
|
@@ -7998,7 +8589,7 @@ function rememberTool(memory) {
|
|
|
7998
8589
|
category: "Session",
|
|
7999
8590
|
description: "Persist facts, conventions, decisions, and preferences into long-term memory. Memories survive restarts and are scored for relevance in future sessions.",
|
|
8000
8591
|
usageHint: "Persist facts, conventions, decisions, and preferences into long-term memory.\n\nWHEN TO USE:\n- Project conventions discovered during a task (build tool, lint rules, code style)\n- Architecture decisions made (chose X over Y, decided to use pattern Z)\n- User preferences expressed (prefers short names, always uses pnpm)\n- Anti-patterns identified (never do X, avoid pattern Y)\n- File/location references useful across sessions\n\nWHEN NOT TO USE:\n- Temporary task state or progress \u2192 use `todo`\n- One-off debugging notes\n- Information already obvious from the codebase\n\nAlways include `type` and `priority`. Use 1-3 `tags` for grouping.\nBetter to remember a fact now than rediscover it next session.",
|
|
8001
|
-
permission: "
|
|
8592
|
+
permission: "confirm",
|
|
8002
8593
|
mutating: true,
|
|
8003
8594
|
timeoutMs: 2e3,
|
|
8004
8595
|
capabilities: ["memory.write"],
|