nexrall-code 0.5.126 → 0.5.127
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/index.js +728 -35
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -105415,6 +105415,490 @@ var require_modePolicy = __commonJS({
|
|
|
105415
105415
|
}
|
|
105416
105416
|
});
|
|
105417
105417
|
|
|
105418
|
+
// ../../../../../Users/henry/Documents/nexrall-code/packages/core/dist/permissions/destructiveTokens.js
|
|
105419
|
+
var require_destructiveTokens = __commonJS({
|
|
105420
|
+
"../../../../../Users/henry/Documents/nexrall-code/packages/core/dist/permissions/destructiveTokens.js"(exports2) {
|
|
105421
|
+
"use strict";
|
|
105422
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
105423
|
+
exports2.tokenize = tokenize3;
|
|
105424
|
+
exports2.classifyTokens = classifyTokens;
|
|
105425
|
+
var hit = (category, reason) => ({ category, reason });
|
|
105426
|
+
function tokenize3(src) {
|
|
105427
|
+
const cmds = [];
|
|
105428
|
+
let cur = [];
|
|
105429
|
+
let word = "";
|
|
105430
|
+
let has2 = false;
|
|
105431
|
+
let q = null;
|
|
105432
|
+
const pushWord = () => {
|
|
105433
|
+
if (has2)
|
|
105434
|
+
cur.push(word);
|
|
105435
|
+
word = "";
|
|
105436
|
+
has2 = false;
|
|
105437
|
+
};
|
|
105438
|
+
const pushCmd = () => {
|
|
105439
|
+
pushWord();
|
|
105440
|
+
if (cur.length)
|
|
105441
|
+
cmds.push(cur);
|
|
105442
|
+
cur = [];
|
|
105443
|
+
};
|
|
105444
|
+
for (let i2 = 0; i2 < src.length; i2++) {
|
|
105445
|
+
const ch = src[i2];
|
|
105446
|
+
if (q === "'") {
|
|
105447
|
+
if (ch === "'")
|
|
105448
|
+
q = null;
|
|
105449
|
+
else
|
|
105450
|
+
word += ch;
|
|
105451
|
+
continue;
|
|
105452
|
+
}
|
|
105453
|
+
if (q === '"') {
|
|
105454
|
+
if (ch === "\\" && i2 + 1 < src.length) {
|
|
105455
|
+
word += src[++i2];
|
|
105456
|
+
continue;
|
|
105457
|
+
}
|
|
105458
|
+
if (ch === '"') {
|
|
105459
|
+
q = null;
|
|
105460
|
+
continue;
|
|
105461
|
+
}
|
|
105462
|
+
word += ch;
|
|
105463
|
+
continue;
|
|
105464
|
+
}
|
|
105465
|
+
if (ch === "'" || ch === '"') {
|
|
105466
|
+
q = ch;
|
|
105467
|
+
has2 = true;
|
|
105468
|
+
continue;
|
|
105469
|
+
}
|
|
105470
|
+
if (ch === "\\") {
|
|
105471
|
+
if (i2 + 1 < src.length) {
|
|
105472
|
+
word += src[++i2];
|
|
105473
|
+
has2 = true;
|
|
105474
|
+
}
|
|
105475
|
+
continue;
|
|
105476
|
+
}
|
|
105477
|
+
if (ch === ";" || ch === "&" || ch === "|" || ch === "\n" || ch === "(" || ch === ")" || ch === "`") {
|
|
105478
|
+
pushCmd();
|
|
105479
|
+
continue;
|
|
105480
|
+
}
|
|
105481
|
+
if (ch === " " || ch === " ") {
|
|
105482
|
+
pushWord();
|
|
105483
|
+
continue;
|
|
105484
|
+
}
|
|
105485
|
+
word += ch;
|
|
105486
|
+
has2 = true;
|
|
105487
|
+
}
|
|
105488
|
+
pushCmd();
|
|
105489
|
+
return cmds;
|
|
105490
|
+
}
|
|
105491
|
+
var ENV_ASSIGN = /^[A-Za-z_][A-Za-z0-9_]*=/;
|
|
105492
|
+
var CONTROL_WORDS = /* @__PURE__ */ new Set(["{", "}", "!", "if", "then", "else", "elif", "do", "while", "until", "fi", "done"]);
|
|
105493
|
+
var SHELLS = /* @__PURE__ */ new Set(["bash", "sh", "zsh", "dash", "ksh"]);
|
|
105494
|
+
var base = (w) => {
|
|
105495
|
+
const b = w.includes("/") ? w.slice(w.lastIndexOf("/") + 1) : w;
|
|
105496
|
+
return b;
|
|
105497
|
+
};
|
|
105498
|
+
function dropOpts(args, withArg = /* @__PURE__ */ new Set()) {
|
|
105499
|
+
let i2 = 0;
|
|
105500
|
+
while (i2 < args.length && args[i2].startsWith("-") && args[i2] !== "--") {
|
|
105501
|
+
i2 += withArg.has(args[i2]) ? 2 : 1;
|
|
105502
|
+
}
|
|
105503
|
+
if (args[i2] === "--")
|
|
105504
|
+
i2++;
|
|
105505
|
+
return args.slice(i2);
|
|
105506
|
+
}
|
|
105507
|
+
function has(args, long, short) {
|
|
105508
|
+
return args.some((a) => long !== null && (a === long || a.startsWith(long + "=")) || short !== null && /^-[A-Za-z]+$/.test(a) && a.includes(short));
|
|
105509
|
+
}
|
|
105510
|
+
var BROAD = /* @__PURE__ */ new Set([".", "./", "*", "./*", ":/", ":/", "..", "../", "/", "~", "~/", "$HOME", "${HOME}", ".*"]);
|
|
105511
|
+
var DISPOSABLE = /* @__PURE__ */ new Set([
|
|
105512
|
+
"node_modules",
|
|
105513
|
+
"dist",
|
|
105514
|
+
"build",
|
|
105515
|
+
"out",
|
|
105516
|
+
".next",
|
|
105517
|
+
".nuxt",
|
|
105518
|
+
".svelte-kit",
|
|
105519
|
+
".turbo",
|
|
105520
|
+
".cache",
|
|
105521
|
+
".parcel-cache",
|
|
105522
|
+
"coverage",
|
|
105523
|
+
".nyc_output",
|
|
105524
|
+
"target",
|
|
105525
|
+
"__pycache__",
|
|
105526
|
+
".pytest_cache",
|
|
105527
|
+
".mypy_cache",
|
|
105528
|
+
".ruff_cache",
|
|
105529
|
+
".tox",
|
|
105530
|
+
"venv",
|
|
105531
|
+
".venv",
|
|
105532
|
+
".gradle",
|
|
105533
|
+
".dart_tool",
|
|
105534
|
+
"tmp",
|
|
105535
|
+
".tmp",
|
|
105536
|
+
".vite",
|
|
105537
|
+
".angular",
|
|
105538
|
+
".expo",
|
|
105539
|
+
"DerivedData"
|
|
105540
|
+
]);
|
|
105541
|
+
var SCRATCH_PREFIXES = ["/tmp/", "/private/tmp/", "/var/folders/", "/private/var/folders/"];
|
|
105542
|
+
function isDisposableTarget(raw) {
|
|
105543
|
+
let t2 = raw;
|
|
105544
|
+
if (t2 === "")
|
|
105545
|
+
return false;
|
|
105546
|
+
if (/[$~`]/.test(t2) || t2.includes(".."))
|
|
105547
|
+
return false;
|
|
105548
|
+
if (t2.startsWith("/"))
|
|
105549
|
+
return SCRATCH_PREFIXES.some((p) => t2.startsWith(p) && t2.length > p.length);
|
|
105550
|
+
t2 = t2.replace(/^(?:\.\/)+/, "").replace(/\/+$/, "");
|
|
105551
|
+
if (t2 === "" || t2 === ".")
|
|
105552
|
+
return false;
|
|
105553
|
+
const segs = t2.split("/").filter(Boolean);
|
|
105554
|
+
if (segs.length === 0)
|
|
105555
|
+
return false;
|
|
105556
|
+
return DISPOSABLE.has(segs[0]) || DISPOSABLE.has(segs[segs.length - 1]);
|
|
105557
|
+
}
|
|
105558
|
+
function checkGit(argsIn) {
|
|
105559
|
+
let i2 = 0;
|
|
105560
|
+
while (i2 < argsIn.length && argsIn[i2].startsWith("-")) {
|
|
105561
|
+
const a = argsIn[i2];
|
|
105562
|
+
i2 += ["-C", "-c", "--git-dir", "--work-tree", "--namespace", "--exec-path"].includes(a) ? 2 : 1;
|
|
105563
|
+
}
|
|
105564
|
+
const sub = argsIn[i2];
|
|
105565
|
+
const args = argsIn.slice(i2 + 1);
|
|
105566
|
+
const operands = args.filter((a) => !a.startsWith("-"));
|
|
105567
|
+
switch (sub) {
|
|
105568
|
+
case "push": {
|
|
105569
|
+
if (has(args, "--force", "f") || operands.some((a) => a.startsWith("+"))) {
|
|
105570
|
+
return hit("git-history", "force-pushes (can overwrite/destroy remote history)");
|
|
105571
|
+
}
|
|
105572
|
+
if (has(args, "--delete", "d") || operands.some((a) => a.startsWith(":"))) {
|
|
105573
|
+
return hit("git-history", "deletes a remote branch or tag");
|
|
105574
|
+
}
|
|
105575
|
+
if (has(args, "--mirror", null)) {
|
|
105576
|
+
return hit("git-history", "mirror-pushes (overwrites and deletes remote refs to match local)");
|
|
105577
|
+
}
|
|
105578
|
+
return null;
|
|
105579
|
+
}
|
|
105580
|
+
case "reset":
|
|
105581
|
+
if (has(args, "--hard", null) || has(args, "--keep", null) || has(args, "--merge", null)) {
|
|
105582
|
+
return hit("git-history", "hard-resets the working tree (discards uncommitted work)");
|
|
105583
|
+
}
|
|
105584
|
+
return null;
|
|
105585
|
+
case "clean":
|
|
105586
|
+
if (has(args, "--force", "f") && !has(args, "--dry-run", "n")) {
|
|
105587
|
+
return hit("git-history", "deletes untracked files (git clean)");
|
|
105588
|
+
}
|
|
105589
|
+
return null;
|
|
105590
|
+
case "branch":
|
|
105591
|
+
if (args.some((a) => /^-[A-Za-z]*D/.test(a)) || has(args, "--delete", "d") && has(args, "--force", "f")) {
|
|
105592
|
+
return hit("git-history", "force-deletes a git branch");
|
|
105593
|
+
}
|
|
105594
|
+
return null;
|
|
105595
|
+
case "checkout":
|
|
105596
|
+
if (has(args, "--force", "f"))
|
|
105597
|
+
return hit("git-history", "git checkout --force discards local changes");
|
|
105598
|
+
if (args.some((a) => BROAD.has(a)))
|
|
105599
|
+
return hit("git-history", "discards every uncommitted change in the working tree");
|
|
105600
|
+
return null;
|
|
105601
|
+
case "restore": {
|
|
105602
|
+
const stagedOnly = has(args, "--staged", "S") && !has(args, "--worktree", "W");
|
|
105603
|
+
if (!stagedOnly && args.some((a) => BROAD.has(a))) {
|
|
105604
|
+
return hit("git-history", "discards every uncommitted change in the working tree");
|
|
105605
|
+
}
|
|
105606
|
+
return null;
|
|
105607
|
+
}
|
|
105608
|
+
case "stash":
|
|
105609
|
+
if (args[0] === "drop" || args[0] === "clear")
|
|
105610
|
+
return hit("git-history", "drops stashed work (not recoverable without the commit hash)");
|
|
105611
|
+
return null;
|
|
105612
|
+
case "update-ref":
|
|
105613
|
+
if (has(args, "-d", "d") || has(args, "--delete", null))
|
|
105614
|
+
return hit("git-history", "deletes a git ref");
|
|
105615
|
+
return null;
|
|
105616
|
+
case "reflog":
|
|
105617
|
+
if (args[0] === "delete" || args[0] === "expire")
|
|
105618
|
+
return hit("git-history", "reflog expire / gc prune (permanently drops recoverable commits)");
|
|
105619
|
+
return null;
|
|
105620
|
+
case "gc":
|
|
105621
|
+
if (args.some((a) => /^--prune=(?:now|all)$/.test(a)))
|
|
105622
|
+
return hit("git-history", "reflog expire / gc prune (permanently drops recoverable commits)");
|
|
105623
|
+
return null;
|
|
105624
|
+
case "worktree":
|
|
105625
|
+
if (args[0] === "remove" && has(args, "--force", "f"))
|
|
105626
|
+
return hit("git-history", "force-removes a worktree (discards its uncommitted work)");
|
|
105627
|
+
return null;
|
|
105628
|
+
case "filter-branch":
|
|
105629
|
+
case "filter-repo":
|
|
105630
|
+
return hit("git-history", "rewrites git history (filter-branch/filter-repo)");
|
|
105631
|
+
case "rm":
|
|
105632
|
+
if (operands.some((a) => BROAD.has(a))) {
|
|
105633
|
+
return hit("git-history", "removes every tracked file from the working tree and index");
|
|
105634
|
+
}
|
|
105635
|
+
return null;
|
|
105636
|
+
default:
|
|
105637
|
+
return null;
|
|
105638
|
+
}
|
|
105639
|
+
}
|
|
105640
|
+
function checkRm(args) {
|
|
105641
|
+
const targets = [];
|
|
105642
|
+
let recursive = false;
|
|
105643
|
+
let endOpts = false;
|
|
105644
|
+
for (const a of args) {
|
|
105645
|
+
if (!endOpts && a === "--") {
|
|
105646
|
+
endOpts = true;
|
|
105647
|
+
continue;
|
|
105648
|
+
}
|
|
105649
|
+
if (!endOpts && a.startsWith("-")) {
|
|
105650
|
+
if (a === "--recursive" || /^-[A-Za-z]*[rR]/.test(a))
|
|
105651
|
+
recursive = true;
|
|
105652
|
+
continue;
|
|
105653
|
+
}
|
|
105654
|
+
targets.push(a);
|
|
105655
|
+
}
|
|
105656
|
+
if (targets.some((t2) => BROAD.has(t2)))
|
|
105657
|
+
return hit("filesystem", "deletes the current directory, home, or everything matching a bare glob");
|
|
105658
|
+
if (recursive && targets.some((t2) => !isDisposableTarget(t2))) {
|
|
105659
|
+
return hit("filesystem", "recursively deletes files or directories that are not a known build artefact");
|
|
105660
|
+
}
|
|
105661
|
+
return null;
|
|
105662
|
+
}
|
|
105663
|
+
function checkFind(args) {
|
|
105664
|
+
if (args.includes("-delete"))
|
|
105665
|
+
return hit("filesystem", "find -delete removes every match");
|
|
105666
|
+
for (let i2 = 0; i2 < args.length - 1; i2++) {
|
|
105667
|
+
if ((args[i2] === "-exec" || args[i2] === "-execdir" || args[i2] === "-ok") && ["rm", "shred", "unlink"].includes(base(args[i2 + 1]))) {
|
|
105668
|
+
return hit("filesystem", "find -exec rm removes every match");
|
|
105669
|
+
}
|
|
105670
|
+
}
|
|
105671
|
+
return null;
|
|
105672
|
+
}
|
|
105673
|
+
function judge(bin, args) {
|
|
105674
|
+
switch (bin) {
|
|
105675
|
+
case "git":
|
|
105676
|
+
return checkGit(args);
|
|
105677
|
+
case "rm":
|
|
105678
|
+
case "unlink":
|
|
105679
|
+
return checkRm(args);
|
|
105680
|
+
case "find":
|
|
105681
|
+
return checkFind(args);
|
|
105682
|
+
case "rsync":
|
|
105683
|
+
if (args.some((a) => a === "--del" || /^--delete(?:-[a-z]+)?$/.test(a)))
|
|
105684
|
+
return hit("filesystem", "rsync --delete removes destination files that are absent from the source");
|
|
105685
|
+
return null;
|
|
105686
|
+
case "truncate":
|
|
105687
|
+
return hit("filesystem", "truncate cuts a file (contents lost)");
|
|
105688
|
+
case "shred":
|
|
105689
|
+
return hit("filesystem", "shred irrecoverably overwrites a file");
|
|
105690
|
+
case "dd":
|
|
105691
|
+
if (args.some((a) => /^of=\/dev\//.test(a)))
|
|
105692
|
+
return hit("filesystem", "dd writing to a device (overwrites the disk)");
|
|
105693
|
+
return null;
|
|
105694
|
+
case "diskutil":
|
|
105695
|
+
if (/^(?:erase|secureErase|zeroDisk|randomDisk|partitionDisk|reformat)/i.test(args[0] ?? ""))
|
|
105696
|
+
return hit("filesystem", "diskutil erases or repartitions a disk");
|
|
105697
|
+
return null;
|
|
105698
|
+
case "chmod": {
|
|
105699
|
+
if (!has(args, "--recursive", "R"))
|
|
105700
|
+
return null;
|
|
105701
|
+
const operands = args.filter((a) => !a.startsWith("-"));
|
|
105702
|
+
if (operands.slice(1).some((t2) => BROAD.has(t2)))
|
|
105703
|
+
return hit("filesystem", "recursive chmod over the current directory / home / root");
|
|
105704
|
+
return null;
|
|
105705
|
+
}
|
|
105706
|
+
case "terraform":
|
|
105707
|
+
case "tofu":
|
|
105708
|
+
case "terragrunt":
|
|
105709
|
+
if (args.includes("destroy") || args.includes("apply") && (args.includes("-destroy") || args.includes("-auto-approve"))) {
|
|
105710
|
+
return hit("infra", "destroys or applies Terraform-managed infrastructure without a plan review");
|
|
105711
|
+
}
|
|
105712
|
+
return null;
|
|
105713
|
+
case "kubectl":
|
|
105714
|
+
case "oc": {
|
|
105715
|
+
const a = dropOpts(args, /* @__PURE__ */ new Set(["-n", "--namespace", "--context", "--cluster", "--kubeconfig", "-s", "--server", "--user"]));
|
|
105716
|
+
if (a[0] === "delete")
|
|
105717
|
+
return hit("infra", "deletes Kubernetes resources");
|
|
105718
|
+
if (a[0] === "drain")
|
|
105719
|
+
return hit("infra", "drains a node (evicts every pod)");
|
|
105720
|
+
if (a[0] === "replace" && has(a, "--force", null))
|
|
105721
|
+
return hit("infra", "kubectl replace --force deletes and recreates the resource");
|
|
105722
|
+
return null;
|
|
105723
|
+
}
|
|
105724
|
+
case "helm": {
|
|
105725
|
+
const a = dropOpts(args, /* @__PURE__ */ new Set(["-n", "--namespace", "--kube-context", "--kubeconfig"]));
|
|
105726
|
+
if (a[0] === "uninstall" || a[0] === "delete")
|
|
105727
|
+
return hit("infra", "helm uninstall / delete (removes a release)");
|
|
105728
|
+
return null;
|
|
105729
|
+
}
|
|
105730
|
+
case "aws":
|
|
105731
|
+
if (args[0] === "s3" && args[1] === "sync" && has(args, "--delete", null))
|
|
105732
|
+
return hit("cloud", "aws s3 sync --delete removes bucket objects missing locally");
|
|
105733
|
+
return null;
|
|
105734
|
+
case "vercel":
|
|
105735
|
+
if (args[0] === "remove" || args[0] === "rm")
|
|
105736
|
+
return hit("cloud", "removes a Vercel project or deployment");
|
|
105737
|
+
return null;
|
|
105738
|
+
case "fly":
|
|
105739
|
+
case "flyctl":
|
|
105740
|
+
if (args.includes("destroy"))
|
|
105741
|
+
return hit("cloud", "destroys a Fly.io app, volume or machine");
|
|
105742
|
+
return null;
|
|
105743
|
+
case "heroku":
|
|
105744
|
+
if (args.some((a) => /:destroy$/.test(a) || a === "pg:reset"))
|
|
105745
|
+
return hit("cloud", "destroys a Heroku app or resets its database");
|
|
105746
|
+
return null;
|
|
105747
|
+
case "supabase":
|
|
105748
|
+
if (args[0] === "db" && args[1] === "reset" || args[0] === "projects" && args[1] === "delete")
|
|
105749
|
+
return hit("cloud", "resets a Supabase database or deletes a project");
|
|
105750
|
+
return null;
|
|
105751
|
+
case "firebase":
|
|
105752
|
+
if (args.some((a) => /:delete$/.test(a)))
|
|
105753
|
+
return hit("cloud", "deletes Firebase data or a project");
|
|
105754
|
+
return null;
|
|
105755
|
+
case "netlify":
|
|
105756
|
+
if (args.some((a) => /:delete$/.test(a)))
|
|
105757
|
+
return hit("cloud", "deletes a Netlify site");
|
|
105758
|
+
return null;
|
|
105759
|
+
case "npm":
|
|
105760
|
+
case "pnpm":
|
|
105761
|
+
case "yarn":
|
|
105762
|
+
if (args[0] === "unpublish")
|
|
105763
|
+
return hit("publish", "unpublishes a package version");
|
|
105764
|
+
if (args[0] === "dist-tag" && (args[1] === "rm" || args[1] === "remove"))
|
|
105765
|
+
return hit("publish", "removes an npm dist-tag (can break `npm i pkg@latest`)");
|
|
105766
|
+
return null;
|
|
105767
|
+
case "gh": {
|
|
105768
|
+
if ((args[0] === "repo" || args[0] === "release") && args[1] === "delete")
|
|
105769
|
+
return hit("cloud", "deletes a GitHub repository or release");
|
|
105770
|
+
if (args[0] === "api") {
|
|
105771
|
+
const m2 = args.findIndex((a) => a === "-X" || a === "--method");
|
|
105772
|
+
const inline = args.find((a) => /^(?:-X|--method=)DELETE$/i.test(a));
|
|
105773
|
+
if (m2 >= 0 && /^delete$/i.test(args[m2 + 1] ?? "") || inline)
|
|
105774
|
+
return hit("cloud", "sends an HTTP DELETE to the GitHub API");
|
|
105775
|
+
}
|
|
105776
|
+
return null;
|
|
105777
|
+
}
|
|
105778
|
+
case "docker":
|
|
105779
|
+
case "docker-compose":
|
|
105780
|
+
case "podman": {
|
|
105781
|
+
const a = bin === "docker-compose" ? ["compose", ...args] : dropOpts(args, /* @__PURE__ */ new Set(["-H", "--host", "--context", "-c"]));
|
|
105782
|
+
const verb = a[0] === "container" ? a[1] : a[0];
|
|
105783
|
+
const rest = a.slice(a[0] === "container" ? 2 : 1);
|
|
105784
|
+
if (verb === "rm" && has(rest, "--force", "f") && rest.some((x2) => x2.startsWith("$")))
|
|
105785
|
+
return hit("container", "force-removes many containers at once");
|
|
105786
|
+
if (a[0] === "compose" && rest.includes("down") && has(rest, "--volumes", "v"))
|
|
105787
|
+
return hit("container", "docker compose down with -v (deletes named volumes)");
|
|
105788
|
+
return null;
|
|
105789
|
+
}
|
|
105790
|
+
case "dropdb":
|
|
105791
|
+
case "dropuser":
|
|
105792
|
+
return hit("database", "drops a Postgres database or role");
|
|
105793
|
+
default:
|
|
105794
|
+
if (bin.startsWith("mkfs"))
|
|
105795
|
+
return hit("filesystem", "mkfs formats a filesystem (destroys its contents)");
|
|
105796
|
+
return null;
|
|
105797
|
+
}
|
|
105798
|
+
}
|
|
105799
|
+
var DB_BINS = /* @__PURE__ */ new Set([
|
|
105800
|
+
"psql",
|
|
105801
|
+
"mysql",
|
|
105802
|
+
"mariadb",
|
|
105803
|
+
"mongo",
|
|
105804
|
+
"mongosh",
|
|
105805
|
+
"sqlite3",
|
|
105806
|
+
"cockroach",
|
|
105807
|
+
"clickhouse-client",
|
|
105808
|
+
"pgcli",
|
|
105809
|
+
"mycli",
|
|
105810
|
+
"usql",
|
|
105811
|
+
"sqlcmd",
|
|
105812
|
+
"redis-cli"
|
|
105813
|
+
]);
|
|
105814
|
+
function classifyTokens(tokens, recurse, rawSql) {
|
|
105815
|
+
let t2 = tokens.slice();
|
|
105816
|
+
for (let guard = 0; guard < 12; guard++) {
|
|
105817
|
+
while (t2.length && (ENV_ASSIGN.test(t2[0]) || CONTROL_WORDS.has(t2[0])))
|
|
105818
|
+
t2 = t2.slice(1);
|
|
105819
|
+
if (t2.length === 0)
|
|
105820
|
+
return null;
|
|
105821
|
+
{
|
|
105822
|
+
const r2 = /^>(?![>&])/.test(t2[0]) ? t2 : (t2[0] === ":" || t2[0] === "true") && /^>(?![>&])/.test(t2[1] ?? "") ? t2.slice(1) : null;
|
|
105823
|
+
if (r2) {
|
|
105824
|
+
const target = r2[0].length > 1 ? r2[0].slice(1) : r2[1] ?? "";
|
|
105825
|
+
if (!target.startsWith("/dev/"))
|
|
105826
|
+
return hit("filesystem", "a bare `>` redirect truncates the file (contents lost)");
|
|
105827
|
+
return null;
|
|
105828
|
+
}
|
|
105829
|
+
}
|
|
105830
|
+
const bin = base(t2[0]);
|
|
105831
|
+
const args = t2.slice(1);
|
|
105832
|
+
if (DB_BINS.has(bin)) {
|
|
105833
|
+
return rawSql(bin + " " + args.map((a) => JSON.stringify(a)).join(" "));
|
|
105834
|
+
}
|
|
105835
|
+
if (bin === "sudo" || bin === "doas") {
|
|
105836
|
+
t2 = dropOpts(args, /* @__PURE__ */ new Set(["-u", "-g", "-h", "-p", "-C", "-D", "-R", "-T", "-U"]));
|
|
105837
|
+
continue;
|
|
105838
|
+
}
|
|
105839
|
+
if (bin === "env") {
|
|
105840
|
+
t2 = dropOpts(args, /* @__PURE__ */ new Set(["-u", "-C", "-S"]));
|
|
105841
|
+
continue;
|
|
105842
|
+
}
|
|
105843
|
+
if (bin === "nice") {
|
|
105844
|
+
t2 = dropOpts(args, /* @__PURE__ */ new Set(["-n"]));
|
|
105845
|
+
continue;
|
|
105846
|
+
}
|
|
105847
|
+
if (bin === "ionice") {
|
|
105848
|
+
t2 = dropOpts(args, /* @__PURE__ */ new Set(["-c", "-n", "-p"]));
|
|
105849
|
+
continue;
|
|
105850
|
+
}
|
|
105851
|
+
if (bin === "timeout") {
|
|
105852
|
+
t2 = dropOpts(args, /* @__PURE__ */ new Set(["-s", "-k"])).slice(1);
|
|
105853
|
+
continue;
|
|
105854
|
+
}
|
|
105855
|
+
if (bin === "xargs") {
|
|
105856
|
+
t2 = dropOpts(args, /* @__PURE__ */ new Set(["-I", "-n", "-P", "-L", "-s", "-d", "-E", "-a", "-J"]));
|
|
105857
|
+
continue;
|
|
105858
|
+
}
|
|
105859
|
+
if (["command", "builtin", "nohup", "exec", "time", "setsid", "caffeinate", "stdbuf", "unbuffer"].includes(bin)) {
|
|
105860
|
+
t2 = dropOpts(args);
|
|
105861
|
+
continue;
|
|
105862
|
+
}
|
|
105863
|
+
if (SHELLS.has(bin)) {
|
|
105864
|
+
const i2 = args.findIndex((a) => /^-[A-Za-z]*c[A-Za-z]*$/.test(a));
|
|
105865
|
+
if (i2 >= 0 && args[i2 + 1] !== void 0)
|
|
105866
|
+
return recurse(args[i2 + 1]);
|
|
105867
|
+
return null;
|
|
105868
|
+
}
|
|
105869
|
+
if (bin === "eval")
|
|
105870
|
+
return recurse(args.join(" "));
|
|
105871
|
+
if (bin === "ssh") {
|
|
105872
|
+
const a = dropOpts(args, /* @__PURE__ */ new Set(["-p", "-i", "-l", "-o", "-F", "-J", "-L", "-R", "-D", "-b", "-c", "-E", "-e", "-I", "-m", "-O", "-Q", "-S", "-w", "-W"]));
|
|
105873
|
+
return a.length > 1 ? recurse(a.slice(1).join(" ")) : null;
|
|
105874
|
+
}
|
|
105875
|
+
if (bin === "docker" || bin === "podman" || bin === "docker-compose") {
|
|
105876
|
+
const a0 = bin === "docker-compose" ? ["compose", ...args] : dropOpts(args, /* @__PURE__ */ new Set(["-H", "--host", "--context", "-c"]));
|
|
105877
|
+
const isExec = a0[0] === "exec" || a0[0] === "compose" && dropOpts(a0.slice(1), /* @__PURE__ */ new Set(["-f", "-p", "--project-name", "--file", "--profile"]))[0] === "exec";
|
|
105878
|
+
if (isExec) {
|
|
105879
|
+
const afterVerb = a0[0] === "exec" ? a0.slice(1) : dropOpts(a0.slice(1), /* @__PURE__ */ new Set(["-f", "-p", "--project-name", "--file", "--profile"])).slice(1);
|
|
105880
|
+
const inner = dropOpts(afterVerb, /* @__PURE__ */ new Set(["-e", "-u", "-w", "--env", "--user", "--workdir", "--env-file", "--detach-keys", "--index"]));
|
|
105881
|
+
if (inner.length > 1) {
|
|
105882
|
+
t2 = inner.slice(1);
|
|
105883
|
+
continue;
|
|
105884
|
+
}
|
|
105885
|
+
return null;
|
|
105886
|
+
}
|
|
105887
|
+
}
|
|
105888
|
+
if (bin === "kubectl" || bin === "oc") {
|
|
105889
|
+
const i2 = args.indexOf("--");
|
|
105890
|
+
if (i2 >= 0 && args.includes("exec") && i2 + 1 < args.length) {
|
|
105891
|
+
t2 = args.slice(i2 + 1);
|
|
105892
|
+
continue;
|
|
105893
|
+
}
|
|
105894
|
+
}
|
|
105895
|
+
return judge(bin, args);
|
|
105896
|
+
}
|
|
105897
|
+
return null;
|
|
105898
|
+
}
|
|
105899
|
+
}
|
|
105900
|
+
});
|
|
105901
|
+
|
|
105418
105902
|
// ../../../../../Users/henry/Documents/nexrall-code/packages/core/dist/permissions/destructive.js
|
|
105419
105903
|
var require_destructive = __commonJS({
|
|
105420
105904
|
"../../../../../Users/henry/Documents/nexrall-code/packages/core/dist/permissions/destructive.js"(exports2) {
|
|
@@ -105422,6 +105906,7 @@ var require_destructive = __commonJS({
|
|
|
105422
105906
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
105423
105907
|
exports2.classifyDestructiveCommand = classifyDestructiveCommand;
|
|
105424
105908
|
exports2.isDestructiveBash = isDestructiveBash3;
|
|
105909
|
+
var destructiveTokens_1 = require_destructiveTokens();
|
|
105425
105910
|
function stripHeredocs(command) {
|
|
105426
105911
|
return command.replace(/<<-?\s*(['"]?)(\w+)\1[\s\S]*?\n\2(?=\s|;|&|$)/g, " ");
|
|
105427
105912
|
}
|
|
@@ -105451,6 +105936,16 @@ var require_destructive = __commonJS({
|
|
|
105451
105936
|
reason: "drops a Postgres/MySQL role or user",
|
|
105452
105937
|
re: new RegExp(CMD_POS + DB_CLIENT + String.raw`\b[\s\S]*?\bdrop\s+(?:role|user)\b`, "i")
|
|
105453
105938
|
},
|
|
105939
|
+
{
|
|
105940
|
+
category: "database",
|
|
105941
|
+
reason: "UPDATE without a WHERE clause (rewrites every row)",
|
|
105942
|
+
re: new RegExp(CMD_POS + DB_CLIENT + String.raw`\b[\s\S]*?\bupdate\s+[\w.` + "`" + String.raw`"]+\s+set\b(?![\s\S]*\bwhere\b)`, "i")
|
|
105943
|
+
},
|
|
105944
|
+
{
|
|
105945
|
+
category: "database",
|
|
105946
|
+
reason: "DELETE with a WHERE clause that is always true (deletes every row)",
|
|
105947
|
+
re: new RegExp(CMD_POS + DB_CLIENT + String.raw`\b[\s\S]*?\bdelete\s+from\b[\s\S]*?\bwhere\s+(?:1\s*=\s*1|true)\b`, "i")
|
|
105948
|
+
},
|
|
105454
105949
|
{
|
|
105455
105950
|
category: "database",
|
|
105456
105951
|
reason: "drops a MongoDB database or collection",
|
|
@@ -105490,11 +105985,6 @@ var require_destructive = __commonJS({
|
|
|
105490
105985
|
reason: "deletes untracked files (git clean)",
|
|
105491
105986
|
re: /\bgit\s+clean\s+-[a-z]*f/i
|
|
105492
105987
|
},
|
|
105493
|
-
{
|
|
105494
|
-
category: "git-history",
|
|
105495
|
-
reason: "force-deletes a git branch",
|
|
105496
|
-
re: /\bgit\s+branch\s+-[a-z]*D/i
|
|
105497
|
-
},
|
|
105498
105988
|
{
|
|
105499
105989
|
category: "git-history",
|
|
105500
105990
|
reason: "rewrites git history (filter-branch/filter-repo)",
|
|
@@ -105585,9 +106075,7 @@ var require_destructive = __commonJS({
|
|
|
105585
106075
|
re: new RegExp(CMD_POS + String.raw`(?:npm\s+publish|yarn\s+publish|pnpm\s+publish|cargo\s+publish|twine\s+upload|gem\s+push)\b`, "i")
|
|
105586
106076
|
}
|
|
105587
106077
|
];
|
|
105588
|
-
function
|
|
105589
|
-
if (!command || typeof command !== "string")
|
|
105590
|
-
return null;
|
|
106078
|
+
function classifyRegex(command) {
|
|
105591
106079
|
const raw = stripHeredocs(command);
|
|
105592
106080
|
for (const rule of RAW_RULES) {
|
|
105593
106081
|
if (rule.re.test(raw)) {
|
|
@@ -105602,6 +106090,33 @@ var require_destructive = __commonJS({
|
|
|
105602
106090
|
}
|
|
105603
106091
|
return null;
|
|
105604
106092
|
}
|
|
106093
|
+
function classifyRawSql(command) {
|
|
106094
|
+
const raw = stripHeredocs(command);
|
|
106095
|
+
for (const rule of RAW_RULES) {
|
|
106096
|
+
if (rule.re.test(raw))
|
|
106097
|
+
return { category: rule.category, reason: rule.reason };
|
|
106098
|
+
}
|
|
106099
|
+
return null;
|
|
106100
|
+
}
|
|
106101
|
+
var MAX_DEPTH = 4;
|
|
106102
|
+
function classify(command, depth) {
|
|
106103
|
+
if (depth > MAX_DEPTH)
|
|
106104
|
+
return null;
|
|
106105
|
+
const viaRegex = classifyRegex(command);
|
|
106106
|
+
if (viaRegex)
|
|
106107
|
+
return viaRegex;
|
|
106108
|
+
for (const tokens of (0, destructiveTokens_1.tokenize)(stripHeredocs(command))) {
|
|
106109
|
+
const m2 = (0, destructiveTokens_1.classifyTokens)(tokens, (inner) => classify(inner, depth + 1), classifyRawSql);
|
|
106110
|
+
if (m2)
|
|
106111
|
+
return m2;
|
|
106112
|
+
}
|
|
106113
|
+
return null;
|
|
106114
|
+
}
|
|
106115
|
+
function classifyDestructiveCommand(command) {
|
|
106116
|
+
if (!command || typeof command !== "string")
|
|
106117
|
+
return null;
|
|
106118
|
+
return classify(command, 0);
|
|
106119
|
+
}
|
|
105605
106120
|
function isDestructiveBash3(tool, input) {
|
|
105606
106121
|
if (tool !== "bash" && tool !== "run_command" && tool !== "execute_command")
|
|
105607
106122
|
return null;
|
|
@@ -145676,6 +146191,67 @@ function padVis(s2, n) {
|
|
|
145676
146191
|
const pad = n - visibleLen(s2);
|
|
145677
146192
|
return pad > 0 ? s2 + " ".repeat(pad) : s2;
|
|
145678
146193
|
}
|
|
146194
|
+
var graphemeSegmenter = typeof Intl.Segmenter === "function" ? new Intl.Segmenter(void 0, { granularity: "grapheme" }) : null;
|
|
146195
|
+
function graphemes(s2) {
|
|
146196
|
+
return graphemeSegmenter ? Array.from(graphemeSegmenter.segment(s2), (x2) => x2.segment) : Array.from(s2);
|
|
146197
|
+
}
|
|
146198
|
+
function truncateCells(s2, max) {
|
|
146199
|
+
if (max <= 0)
|
|
146200
|
+
return "";
|
|
146201
|
+
if (visibleLen(s2) <= max)
|
|
146202
|
+
return s2;
|
|
146203
|
+
let out = "";
|
|
146204
|
+
for (const g of graphemes(s2)) {
|
|
146205
|
+
if (visibleLen(out + g) > max - 1)
|
|
146206
|
+
break;
|
|
146207
|
+
out += g;
|
|
146208
|
+
}
|
|
146209
|
+
return out + "\u2026";
|
|
146210
|
+
}
|
|
146211
|
+
function wrapCells(text, width) {
|
|
146212
|
+
if (width < 1)
|
|
146213
|
+
return [];
|
|
146214
|
+
const rows = [];
|
|
146215
|
+
let cur = "";
|
|
146216
|
+
for (const w of text.split(/\s+/)) {
|
|
146217
|
+
if (!w)
|
|
146218
|
+
continue;
|
|
146219
|
+
let word = w;
|
|
146220
|
+
while (visibleLen(word) > width) {
|
|
146221
|
+
if (cur) {
|
|
146222
|
+
rows.push(cur);
|
|
146223
|
+
cur = "";
|
|
146224
|
+
}
|
|
146225
|
+
const g = graphemes(word);
|
|
146226
|
+
let chunk = "";
|
|
146227
|
+
let i2 = 0;
|
|
146228
|
+
for (; i2 < g.length; i2++) {
|
|
146229
|
+
if (visibleLen(chunk + g[i2]) > width)
|
|
146230
|
+
break;
|
|
146231
|
+
chunk += g[i2];
|
|
146232
|
+
}
|
|
146233
|
+
if (!chunk) {
|
|
146234
|
+
chunk = g[0];
|
|
146235
|
+
i2 = 1;
|
|
146236
|
+
}
|
|
146237
|
+
rows.push(chunk);
|
|
146238
|
+
word = g.slice(i2).join("");
|
|
146239
|
+
}
|
|
146240
|
+
if (!word)
|
|
146241
|
+
continue;
|
|
146242
|
+
if (!cur)
|
|
146243
|
+
cur = word;
|
|
146244
|
+
else if (visibleLen(cur) + 1 + visibleLen(word) <= width)
|
|
146245
|
+
cur += " " + word;
|
|
146246
|
+
else {
|
|
146247
|
+
rows.push(cur);
|
|
146248
|
+
cur = word;
|
|
146249
|
+
}
|
|
146250
|
+
}
|
|
146251
|
+
if (cur)
|
|
146252
|
+
rows.push(cur);
|
|
146253
|
+
return rows;
|
|
146254
|
+
}
|
|
145679
146255
|
function ruleWidth(max = 50, columns = process.stdout.columns || 80) {
|
|
145680
146256
|
const MIN = 20;
|
|
145681
146257
|
const indent = 2;
|
|
@@ -145904,11 +146480,9 @@ function formatToolResult(name, result, durationMs) {
|
|
|
145904
146480
|
const sizeHint = lines > 1 ? `${lines} lines` : `${out.length} chars`;
|
|
145905
146481
|
return source_default.green(icons.check) + " " + source_default.dim(name) + source_default.dim(` \xB7 ${sizeHint}`) + source_default.dim(` \xB7 ${durationMs}ms`);
|
|
145906
146482
|
}
|
|
145907
|
-
function formatThinking(
|
|
146483
|
+
function formatThinking(tokens) {
|
|
145908
146484
|
const tokStr = tokens >= 1e3 ? `~${(tokens / 1e3).toFixed(1)}k tokens` : tokens > 0 ? `~${tokens} tokens` : "";
|
|
145909
|
-
|
|
145910
|
-
const preview = text.trim().split("\n").filter(Boolean).slice(0, 3).map((l2) => source_default.dim(" " + l2.slice(0, 100))).join("\n");
|
|
145911
|
-
return "\n" + header + (preview ? "\n" + preview : "") + "\n";
|
|
146485
|
+
return source_default.dim(`${icons.thinking} Thought`) + (tokStr ? source_default.dim(` \xB7 ${tokStr}`) : "");
|
|
145912
146486
|
}
|
|
145913
146487
|
function formatUsage(outputTokens) {
|
|
145914
146488
|
const tok = outputTokens >= 1e3 ? `${(outputTokens / 1e3).toFixed(1)}k` : String(outputTokens);
|
|
@@ -157661,11 +158235,11 @@ function fillerContent(rows) {
|
|
|
157661
158235
|
return "\n".repeat(rows - 1);
|
|
157662
158236
|
}
|
|
157663
158237
|
var IntlWithSegmenter2 = Intl;
|
|
157664
|
-
var
|
|
158238
|
+
var graphemeSegmenter2 = typeof IntlWithSegmenter2.Segmenter === "function" ? new IntlWithSegmenter2.Segmenter(void 0, { granularity: "grapheme" }) : null;
|
|
157665
158239
|
function graphemeBoundaries(text) {
|
|
157666
|
-
if (
|
|
158240
|
+
if (graphemeSegmenter2) {
|
|
157667
158241
|
const bounds2 = [0];
|
|
157668
|
-
for (const { index } of
|
|
158242
|
+
for (const { index } of graphemeSegmenter2.segment(text)) {
|
|
157669
158243
|
if (index > 0)
|
|
157670
158244
|
bounds2.push(index);
|
|
157671
158245
|
}
|
|
@@ -158965,7 +159539,95 @@ ${content}`);
|
|
|
158965
159539
|
}
|
|
158966
159540
|
return parts.length > 0 ? parts.join("\n\n---\n\n") : void 0;
|
|
158967
159541
|
}
|
|
158968
|
-
var
|
|
159542
|
+
var THINK_PREVIEW_ROWS = 3;
|
|
159543
|
+
var THINK_BUFFER_CHARS = 1200;
|
|
159544
|
+
var VERB_ROTATE_SEC = 3;
|
|
159545
|
+
var WORKING_VERBS = [
|
|
159546
|
+
"Accomplishing",
|
|
159547
|
+
"Actualizing",
|
|
159548
|
+
"Baking",
|
|
159549
|
+
"Brewing",
|
|
159550
|
+
"Calculating",
|
|
159551
|
+
"Cerebrating",
|
|
159552
|
+
"Churning",
|
|
159553
|
+
"Coalescing",
|
|
159554
|
+
"Cogitating",
|
|
159555
|
+
"Computing",
|
|
159556
|
+
"Concocting",
|
|
159557
|
+
"Conjuring",
|
|
159558
|
+
"Considering",
|
|
159559
|
+
"Contemplating",
|
|
159560
|
+
"Cooking",
|
|
159561
|
+
"Crafting",
|
|
159562
|
+
"Creating",
|
|
159563
|
+
"Crunching",
|
|
159564
|
+
"Deliberating",
|
|
159565
|
+
"Determining",
|
|
159566
|
+
"Digesting",
|
|
159567
|
+
"Distilling",
|
|
159568
|
+
"Divining",
|
|
159569
|
+
"Effecting",
|
|
159570
|
+
"Elaborating",
|
|
159571
|
+
"Envisioning",
|
|
159572
|
+
"Fabricating",
|
|
159573
|
+
"Fermenting",
|
|
159574
|
+
"Finagling",
|
|
159575
|
+
"Forging",
|
|
159576
|
+
"Formulating",
|
|
159577
|
+
"Generating",
|
|
159578
|
+
"Germinating",
|
|
159579
|
+
"Hatching",
|
|
159580
|
+
"Herding",
|
|
159581
|
+
"Hustling",
|
|
159582
|
+
"Ideating",
|
|
159583
|
+
"Imagining",
|
|
159584
|
+
"Incubating",
|
|
159585
|
+
"Inferring",
|
|
159586
|
+
"Manifesting",
|
|
159587
|
+
"Marinating",
|
|
159588
|
+
"Meandering",
|
|
159589
|
+
"Mulling",
|
|
159590
|
+
"Musing",
|
|
159591
|
+
"Noodling",
|
|
159592
|
+
"Percolating",
|
|
159593
|
+
"Pondering",
|
|
159594
|
+
"Processing",
|
|
159595
|
+
"Puzzling",
|
|
159596
|
+
"Reticulating",
|
|
159597
|
+
"Ruminating",
|
|
159598
|
+
"Simmering",
|
|
159599
|
+
"Smelting",
|
|
159600
|
+
"Spinning",
|
|
159601
|
+
"Stewing",
|
|
159602
|
+
"Sussing",
|
|
159603
|
+
"Synthesizing",
|
|
159604
|
+
"Thinking",
|
|
159605
|
+
"Tinkering",
|
|
159606
|
+
"Transmuting",
|
|
159607
|
+
"Unfurling",
|
|
159608
|
+
"Vibing",
|
|
159609
|
+
"Wandering",
|
|
159610
|
+
"Weaving",
|
|
159611
|
+
"Whirring",
|
|
159612
|
+
"Working"
|
|
159613
|
+
];
|
|
159614
|
+
function composeThinkingBlock(opts) {
|
|
159615
|
+
const tok = formatProgressTokens(opts.tokens);
|
|
159616
|
+
const flat = opts.text.replace(/\s+/g, " ").trim();
|
|
159617
|
+
if (!tok && !flat)
|
|
159618
|
+
return [];
|
|
159619
|
+
const columns = Math.max(20, opts.columns | 0 || 80);
|
|
159620
|
+
const termRows = opts.rows && opts.rows > 0 ? opts.rows : 24;
|
|
159621
|
+
const maxRows = Math.max(0, Math.min(opts.maxRows ?? THINK_PREVIEW_ROWS, termRows - 12));
|
|
159622
|
+
const lines = [source_default.dim(truncateCells(`${icons.thinking} Thinking\u2026${tok ? " " + tok : ""}`, columns - 1))];
|
|
159623
|
+
if (flat && maxRows > 0) {
|
|
159624
|
+
const indent = " ";
|
|
159625
|
+
const wrapped = wrapCells(flat, columns - 1 - indent.length);
|
|
159626
|
+
for (const row of wrapped.slice(-maxRows))
|
|
159627
|
+
lines.push(source_default.dim.italic(indent + row));
|
|
159628
|
+
}
|
|
159629
|
+
return lines;
|
|
159630
|
+
}
|
|
158969
159631
|
function composeStatusLine(opts) {
|
|
158970
159632
|
const timer = source_default.dim(` (${opts.elapsedSec}s)`);
|
|
158971
159633
|
const hint = opts.hint !== false && !opts.detail && opts.elapsedSec >= 15 ? source_default.dim(" \xB7 still running, no output yet is normal for quiet commands") : "";
|
|
@@ -158994,10 +159656,21 @@ var Spinner = class {
|
|
|
158994
159656
|
// already explained by the detail text (e.g. a live token counter is itself
|
|
158995
159657
|
// proof of life, so "no output yet is normal" would be noise).
|
|
158996
159658
|
hintEnabled = true;
|
|
159659
|
+
// Model-working phases (before the first token, and between tool rounds) show a rotating
|
|
159660
|
+
// verb instead of a fixed label, plus the live reasoning block above it. Tool phases
|
|
159661
|
+
// ("running bash…") keep their literal label: a verb there would hide what is running.
|
|
159662
|
+
verbs = false;
|
|
159663
|
+
verbIdx = 0;
|
|
159664
|
+
thinkTokens = 0;
|
|
159665
|
+
thinkText = "";
|
|
158997
159666
|
start(text, opts) {
|
|
158998
159667
|
this.stop();
|
|
158999
159668
|
this.baseText = text;
|
|
159000
159669
|
this.detail = "";
|
|
159670
|
+
this.thinkTokens = 0;
|
|
159671
|
+
this.thinkText = "";
|
|
159672
|
+
this.verbs = opts?.verbs === true;
|
|
159673
|
+
this.verbIdx = Math.floor(Math.random() * WORKING_VERBS.length);
|
|
159001
159674
|
this.hintEnabled = opts?.hint !== false;
|
|
159002
159675
|
this.startedAt = Date.now();
|
|
159003
159676
|
this.render();
|
|
@@ -159027,6 +159700,17 @@ var Spinner = class {
|
|
|
159027
159700
|
return;
|
|
159028
159701
|
this.detail = detail;
|
|
159029
159702
|
}
|
|
159703
|
+
/**
|
|
159704
|
+
* Feed the live reasoning block (token count + streamed text). Like setDetail, this only
|
|
159705
|
+
* records state — the 100 ms tick renders it, so a burst of deltas cannot add redraws.
|
|
159706
|
+
* The text is capped to THINK_BUFFER_CHARS: only its last rows are ever displayed.
|
|
159707
|
+
*/
|
|
159708
|
+
setThinking(tokens, text) {
|
|
159709
|
+
if (this.interval === null)
|
|
159710
|
+
return;
|
|
159711
|
+
this.thinkTokens = tokens;
|
|
159712
|
+
this.thinkText = text.slice(-THINK_BUFFER_CHARS);
|
|
159713
|
+
}
|
|
159030
159714
|
/** Swap the label without resetting the elapsed timer (phase change within one turn). Same reasoning as setDetail() above: no immediate render, the interval tick picks it up. */
|
|
159031
159715
|
setText(text) {
|
|
159032
159716
|
if (this.interval === null)
|
|
@@ -159034,20 +159718,36 @@ var Spinner = class {
|
|
|
159034
159718
|
this.baseText = text;
|
|
159035
159719
|
}
|
|
159036
159720
|
render() {
|
|
159037
|
-
|
|
159721
|
+
const elapsedSec = Math.floor((Date.now() - this.startedAt) / 1e3);
|
|
159722
|
+
if (this.verbs && elapsedSec > 0 && elapsedSec % VERB_ROTATE_SEC === 0 && this.lastRotateSec !== elapsedSec) {
|
|
159723
|
+
this.lastRotateSec = elapsedSec;
|
|
159724
|
+
this.verbIdx++;
|
|
159725
|
+
}
|
|
159726
|
+
const label = this.verbs ? `${WORKING_VERBS[this.verbIdx % WORKING_VERBS.length]}\u2026` : this.baseText;
|
|
159727
|
+
const status = composeStatusLine({
|
|
159038
159728
|
frame: this.frames[this.i % this.frames.length],
|
|
159039
|
-
text:
|
|
159040
|
-
elapsedSec
|
|
159729
|
+
text: label,
|
|
159730
|
+
elapsedSec,
|
|
159041
159731
|
detail: this.detail,
|
|
159042
159732
|
hint: this.hintEnabled
|
|
159043
|
-
})
|
|
159733
|
+
});
|
|
159734
|
+
const block = this.verbs ? composeThinkingBlock({
|
|
159735
|
+
tokens: this.thinkTokens,
|
|
159736
|
+
text: this.thinkText,
|
|
159737
|
+
columns: process.stdout.columns || 80,
|
|
159738
|
+
rows: process.stdout.rows || 24
|
|
159739
|
+
}) : [];
|
|
159740
|
+
getInkTerminal()?.setLive(block.length ? block.join("\n") + "\n" + status : status);
|
|
159044
159741
|
this.i++;
|
|
159045
159742
|
}
|
|
159743
|
+
lastRotateSec = -1;
|
|
159046
159744
|
stop() {
|
|
159047
159745
|
if (this.interval !== null) {
|
|
159048
159746
|
clearInterval(this.interval);
|
|
159049
159747
|
this.interval = null;
|
|
159050
159748
|
this.detail = "";
|
|
159749
|
+
this.thinkTokens = 0;
|
|
159750
|
+
this.thinkText = "";
|
|
159051
159751
|
getInkTerminal()?.setLive("");
|
|
159052
159752
|
}
|
|
159053
159753
|
}
|
|
@@ -159142,26 +159842,20 @@ async function runTurn(messages, modelAlias, workDir, abortSignal, env4, nexrall
|
|
|
159142
159842
|
const toolCalls = /* @__PURE__ */ new Map();
|
|
159143
159843
|
const subPrefix = (meta) => source_default.dim(` \u21B3 ${meta?.agentName ?? "sub-agent"} `);
|
|
159144
159844
|
let thinkingTokens = 0;
|
|
159145
|
-
let
|
|
159845
|
+
let liveThinkText = "";
|
|
159146
159846
|
const pushStatus = () => {
|
|
159147
|
-
|
|
159148
|
-
const tok = formatProgressTokens(thinkingTokens);
|
|
159149
|
-
if (tok)
|
|
159150
|
-
parts.push(tok);
|
|
159151
|
-
if (liveThinkTail)
|
|
159152
|
-
parts.push(liveThinkTail);
|
|
159153
|
-
spinner.setDetail(parts.join(" \xB7 "));
|
|
159847
|
+
spinner.setThinking(thinkingTokens, liveThinkText);
|
|
159154
159848
|
};
|
|
159155
159849
|
const resumeWorking = (label = "working\u2026") => {
|
|
159156
159850
|
if (abortSignal.aborted)
|
|
159157
159851
|
return;
|
|
159158
159852
|
thinkingTokens = 0;
|
|
159159
|
-
|
|
159160
|
-
spinner.start(label, { hint: false });
|
|
159853
|
+
liveThinkText = "";
|
|
159854
|
+
spinner.start(label, { hint: false, verbs: true });
|
|
159161
159855
|
};
|
|
159162
159856
|
setMode(mode);
|
|
159163
159857
|
console.log();
|
|
159164
|
-
spinner.start("thinking\u2026", { hint: false });
|
|
159858
|
+
spinner.start("thinking\u2026", { hint: false, verbs: true });
|
|
159165
159859
|
const result = await (0, import_code_core7.runAgentLoop)(messages, {
|
|
159166
159860
|
workDir,
|
|
159167
159861
|
model: modelAlias,
|
|
@@ -159213,17 +159907,16 @@ async function runTurn(messages, modelAlias, workDir, abortSignal, env4, nexrall
|
|
|
159213
159907
|
onThinkingDelta: (text) => {
|
|
159214
159908
|
if (abortSignal.aborted)
|
|
159215
159909
|
return;
|
|
159216
|
-
|
|
159217
|
-
liveThinkTail = (liveThinkTail + flat).slice(-THINK_TAIL_CHARS);
|
|
159910
|
+
liveThinkText = (liveThinkText + text).slice(-THINK_BUFFER_CHARS);
|
|
159218
159911
|
pushStatus();
|
|
159219
159912
|
},
|
|
159220
159913
|
onThinking: (text) => {
|
|
159221
159914
|
if (abortSignal.aborted)
|
|
159222
159915
|
return;
|
|
159223
159916
|
spinner.stop();
|
|
159224
|
-
console.log(formatThinking(
|
|
159917
|
+
console.log(formatThinking(thinkingTokens));
|
|
159225
159918
|
thinkingTokens = 0;
|
|
159226
|
-
|
|
159919
|
+
liveThinkText = "";
|
|
159227
159920
|
resumeWorking();
|
|
159228
159921
|
},
|
|
159229
159922
|
onText: (text) => {
|