reasonix 0.33.2 → 0.34.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dashboard/dist/app.js +1 -21
- package/dashboard/dist/app.js.map +1 -1
- package/dist/cli/{chat-ZMSAXE77.js → chat-TD6GR3QK.js} +14 -13
- package/dist/cli/chunk-2EBODRRO.js +149 -0
- package/dist/cli/chunk-2EBODRRO.js.map +1 -0
- package/dist/cli/{chunk-DULSP7JH.js → chunk-5JXXEPDM.js} +34 -1
- package/dist/cli/chunk-5JXXEPDM.js.map +1 -0
- package/dist/cli/{chunk-OW7IHE6M.js → chunk-EINEIIIW.js} +693 -364
- package/dist/cli/chunk-EINEIIIW.js.map +1 -0
- package/dist/cli/{chunk-WVJL7ZO2.js → chunk-F3ILWP2L.js} +4 -4
- package/dist/cli/{chunk-SDE5U32Z.js → chunk-KZHMKOJH.js} +13 -8
- package/dist/cli/{chunk-SDE5U32Z.js.map → chunk-KZHMKOJH.js.map} +1 -1
- package/dist/cli/{chunk-G7M3QWEN.js → chunk-LNTORE5K.js} +225 -132
- package/dist/cli/chunk-LNTORE5K.js.map +1 -0
- package/dist/cli/chunk-MRLXEMZ7.js +26 -0
- package/dist/cli/chunk-MRLXEMZ7.js.map +1 -0
- package/dist/cli/{chunk-WBDE4IRI.js → chunk-OERAGRJX.js} +2 -2
- package/dist/cli/{chunk-QGE6AF76.js → chunk-Q36KBLSU.js} +207 -8
- package/dist/cli/chunk-Q36KBLSU.js.map +1 -0
- package/dist/cli/{chunk-RZILUXUC.js → chunk-RXGEGA7K.js} +2 -2
- package/dist/cli/{chunk-FXGQ5NHE.js → chunk-SA4UGZPG.js} +21 -1
- package/dist/cli/chunk-SA4UGZPG.js.map +1 -0
- package/dist/cli/{chunk-J5VLP23S.js → chunk-SW3CCXEV.js} +2 -2
- package/dist/cli/{chunk-W4LDFAZ6.js → chunk-SX6L4HZZ.js} +2 -2
- package/dist/cli/chunk-WUI3P4RA.js +319 -0
- package/dist/cli/chunk-WUI3P4RA.js.map +1 -0
- package/dist/cli/{code-R4TXQQEE.js → code-TGUOQBRJ.js} +15 -14
- package/dist/cli/{code-R4TXQQEE.js.map → code-TGUOQBRJ.js.map} +1 -1
- package/dist/cli/{commands-JWT2MWVH.js → commands-MEZPSEHV.js} +4 -3
- package/dist/cli/{commands-JWT2MWVH.js.map → commands-MEZPSEHV.js.map} +1 -1
- package/dist/cli/{commit-RPZBOZS2.js → commit-CE4EFTUQ.js} +3 -2
- package/dist/cli/{commit-RPZBOZS2.js.map → commit-CE4EFTUQ.js.map} +1 -1
- package/dist/cli/{doctor-V5HLCMSQ.js → doctor-YASM64X6.js} +7 -6
- package/dist/cli/index.js +22 -21
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/{mcp-ARTNQ24O.js → mcp-LDFK5QJI.js} +3 -2
- package/dist/cli/{mcp-ARTNQ24O.js.map → mcp-LDFK5QJI.js.map} +1 -1
- package/dist/cli/{mcp-browse-HLO2ENDL.js → mcp-browse-FYHEITCM.js} +3 -2
- package/dist/cli/{mcp-browse-HLO2ENDL.js.map → mcp-browse-FYHEITCM.js.map} +1 -1
- package/dist/cli/{replay-Q43DSMG6.js → replay-JEDLU7F2.js} +8 -6
- package/dist/cli/{replay-Q43DSMG6.js.map → replay-JEDLU7F2.js.map} +1 -1
- package/dist/cli/{run-HK3FP266.js → run-NHD2RSTD.js} +7 -6
- package/dist/cli/{run-HK3FP266.js.map → run-NHD2RSTD.js.map} +1 -1
- package/dist/cli/{server-SYC3OVOP.js → server-MC4A4WAJ.js} +9 -8
- package/dist/cli/{server-SYC3OVOP.js.map → server-MC4A4WAJ.js.map} +1 -1
- package/dist/cli/{sessions-3XU2GGHX.js → sessions-ZHWJEW4L.js} +7 -6
- package/dist/cli/{sessions-3XU2GGHX.js.map → sessions-ZHWJEW4L.js.map} +1 -1
- package/dist/cli/{setup-CCJZAWTY.js → setup-DK43MT47.js} +6 -5
- package/dist/cli/{setup-CCJZAWTY.js.map → setup-DK43MT47.js.map} +1 -1
- package/dist/cli/{version-5SGI2SEE.js → version-O362UKPM.js} +7 -6
- package/dist/cli/{version-5SGI2SEE.js.map → version-O362UKPM.js.map} +1 -1
- package/dist/index.d.ts +45 -1
- package/dist/index.js +569 -27
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/cli/chunk-63KAV5DX.js +0 -106
- package/dist/cli/chunk-63KAV5DX.js.map +0 -1
- package/dist/cli/chunk-DULSP7JH.js.map +0 -1
- package/dist/cli/chunk-FXGQ5NHE.js.map +0 -1
- package/dist/cli/chunk-G7M3QWEN.js.map +0 -1
- package/dist/cli/chunk-OW7IHE6M.js.map +0 -1
- package/dist/cli/chunk-QGE6AF76.js.map +0 -1
- package/dist/cli/chunk-ZPTSJGX5.js +0 -88
- package/dist/cli/chunk-ZPTSJGX5.js.map +0 -1
- /package/dist/cli/{chat-ZMSAXE77.js.map → chat-TD6GR3QK.js.map} +0 -0
- /package/dist/cli/{chunk-WVJL7ZO2.js.map → chunk-F3ILWP2L.js.map} +0 -0
- /package/dist/cli/{chunk-WBDE4IRI.js.map → chunk-OERAGRJX.js.map} +0 -0
- /package/dist/cli/{chunk-RZILUXUC.js.map → chunk-RXGEGA7K.js.map} +0 -0
- /package/dist/cli/{chunk-J5VLP23S.js.map → chunk-SW3CCXEV.js.map} +0 -0
- /package/dist/cli/{chunk-W4LDFAZ6.js.map → chunk-SX6L4HZZ.js.map} +0 -0
- /package/dist/cli/{doctor-V5HLCMSQ.js.map → doctor-YASM64X6.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -395,6 +395,264 @@ import { chmodSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
|
395
395
|
import { homedir } from "os";
|
|
396
396
|
import { dirname, join } from "path";
|
|
397
397
|
|
|
398
|
+
// src/cli/ui/theme/tokens.ts
|
|
399
|
+
function card(fg, tone) {
|
|
400
|
+
return {
|
|
401
|
+
user: { color: fg.meta, glyph: "\u25C7" },
|
|
402
|
+
reasoning: { color: tone.accent, glyph: "\u25C6" },
|
|
403
|
+
streaming: { color: tone.brand, glyph: "\u25C8" },
|
|
404
|
+
task: { color: tone.warn, glyph: "\u25B6" },
|
|
405
|
+
tool: { color: tone.info, glyph: "\u25A3" },
|
|
406
|
+
plan: { color: tone.accent, glyph: "\u229E" },
|
|
407
|
+
diff: { color: tone.ok, glyph: "\xB1" },
|
|
408
|
+
error: { color: tone.err, glyph: "\u2716" },
|
|
409
|
+
warn: { color: tone.warn, glyph: "\u26A0" },
|
|
410
|
+
usage: { color: fg.meta, glyph: "\u03A3" },
|
|
411
|
+
subagent: { color: tone.violet, glyph: "\u232C" },
|
|
412
|
+
approval: { color: tone.warn, glyph: "?" },
|
|
413
|
+
search: { color: tone.info, glyph: "\u2299" },
|
|
414
|
+
memory: { color: fg.meta, glyph: "\u2311" },
|
|
415
|
+
ctx: { color: tone.brand, glyph: "\u25D4" },
|
|
416
|
+
doctor: { color: fg.meta, glyph: "\u2695" },
|
|
417
|
+
branch: { color: tone.violet, glyph: "\u2387" }
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
function defineTheme(base) {
|
|
421
|
+
return { ...base, card: card(base.fg, base.tone) };
|
|
422
|
+
}
|
|
423
|
+
var githubDark = defineTheme({
|
|
424
|
+
fg: {
|
|
425
|
+
strong: "#e6edf3",
|
|
426
|
+
body: "#c9d1d9",
|
|
427
|
+
sub: "#8b949e",
|
|
428
|
+
meta: "#6e7681",
|
|
429
|
+
faint: "#484f58"
|
|
430
|
+
},
|
|
431
|
+
tone: {
|
|
432
|
+
brand: "#79c0ff",
|
|
433
|
+
accent: "#d2a8ff",
|
|
434
|
+
violet: "#b395f5",
|
|
435
|
+
ok: "#7ee787",
|
|
436
|
+
warn: "#f0b07d",
|
|
437
|
+
err: "#ff8b81",
|
|
438
|
+
info: "#79c0ff"
|
|
439
|
+
},
|
|
440
|
+
toneActive: {
|
|
441
|
+
brand: "#a5d6ff",
|
|
442
|
+
accent: "#e2c5ff",
|
|
443
|
+
violet: "#c8aaff",
|
|
444
|
+
ok: "#a8f5ad",
|
|
445
|
+
warn: "#ffc99e",
|
|
446
|
+
err: "#ffaba3",
|
|
447
|
+
info: "#a5d6ff"
|
|
448
|
+
},
|
|
449
|
+
surface: {
|
|
450
|
+
bg: "#0a0c10",
|
|
451
|
+
bgInput: "#0d1015",
|
|
452
|
+
bgCode: "#06080c",
|
|
453
|
+
bgElev: "#11141a"
|
|
454
|
+
}
|
|
455
|
+
});
|
|
456
|
+
var dark = defineTheme({
|
|
457
|
+
fg: {
|
|
458
|
+
strong: "#f4f7fb",
|
|
459
|
+
body: "#d8dee9",
|
|
460
|
+
sub: "#a7b1c2",
|
|
461
|
+
meta: "#778294",
|
|
462
|
+
faint: "#4d5666"
|
|
463
|
+
},
|
|
464
|
+
tone: {
|
|
465
|
+
brand: "#7dd3fc",
|
|
466
|
+
accent: "#c084fc",
|
|
467
|
+
violet: "#a78bfa",
|
|
468
|
+
ok: "#86efac",
|
|
469
|
+
warn: "#fbbf24",
|
|
470
|
+
err: "#f87171",
|
|
471
|
+
info: "#60a5fa"
|
|
472
|
+
},
|
|
473
|
+
toneActive: {
|
|
474
|
+
brand: "#bae6fd",
|
|
475
|
+
accent: "#e9d5ff",
|
|
476
|
+
violet: "#ddd6fe",
|
|
477
|
+
ok: "#bbf7d0",
|
|
478
|
+
warn: "#fde68a",
|
|
479
|
+
err: "#fecaca",
|
|
480
|
+
info: "#bfdbfe"
|
|
481
|
+
},
|
|
482
|
+
surface: {
|
|
483
|
+
bg: "#0b1020",
|
|
484
|
+
bgInput: "#111827",
|
|
485
|
+
bgCode: "#080c16",
|
|
486
|
+
bgElev: "#151d2f"
|
|
487
|
+
}
|
|
488
|
+
});
|
|
489
|
+
var light = defineTheme({
|
|
490
|
+
fg: {
|
|
491
|
+
strong: "#111827",
|
|
492
|
+
body: "#1f2937",
|
|
493
|
+
sub: "#4b5563",
|
|
494
|
+
meta: "#6b7280",
|
|
495
|
+
faint: "#9ca3af"
|
|
496
|
+
},
|
|
497
|
+
tone: {
|
|
498
|
+
brand: "#2563eb",
|
|
499
|
+
accent: "#7c3aed",
|
|
500
|
+
violet: "#6d28d9",
|
|
501
|
+
ok: "#15803d",
|
|
502
|
+
warn: "#b45309",
|
|
503
|
+
err: "#dc2626",
|
|
504
|
+
info: "#0369a1"
|
|
505
|
+
},
|
|
506
|
+
toneActive: {
|
|
507
|
+
brand: "#1d4ed8",
|
|
508
|
+
accent: "#6d28d9",
|
|
509
|
+
violet: "#5b21b6",
|
|
510
|
+
ok: "#166534",
|
|
511
|
+
warn: "#92400e",
|
|
512
|
+
err: "#b91c1c",
|
|
513
|
+
info: "#075985"
|
|
514
|
+
},
|
|
515
|
+
surface: {
|
|
516
|
+
bg: "#ffffff",
|
|
517
|
+
bgInput: "#f8fafc",
|
|
518
|
+
bgCode: "#f3f4f6",
|
|
519
|
+
bgElev: "#eef2f7"
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
var tokyoNight = defineTheme({
|
|
523
|
+
fg: {
|
|
524
|
+
strong: "#c0caf5",
|
|
525
|
+
body: "#a9b1d6",
|
|
526
|
+
sub: "#9aa5ce",
|
|
527
|
+
meta: "#565f89",
|
|
528
|
+
faint: "#414868"
|
|
529
|
+
},
|
|
530
|
+
tone: {
|
|
531
|
+
brand: "#7aa2f7",
|
|
532
|
+
accent: "#bb9af7",
|
|
533
|
+
violet: "#9d7cd8",
|
|
534
|
+
ok: "#9ece6a",
|
|
535
|
+
warn: "#e0af68",
|
|
536
|
+
err: "#f7768e",
|
|
537
|
+
info: "#2ac3de"
|
|
538
|
+
},
|
|
539
|
+
toneActive: {
|
|
540
|
+
brand: "#a9c7ff",
|
|
541
|
+
accent: "#d7b9ff",
|
|
542
|
+
violet: "#c6a0f6",
|
|
543
|
+
ok: "#b9f27c",
|
|
544
|
+
warn: "#ffd089",
|
|
545
|
+
err: "#ff9cac",
|
|
546
|
+
info: "#7dcfff"
|
|
547
|
+
},
|
|
548
|
+
surface: {
|
|
549
|
+
bg: "#1a1b26",
|
|
550
|
+
bgInput: "#1f2335",
|
|
551
|
+
bgCode: "#16161e",
|
|
552
|
+
bgElev: "#24283b"
|
|
553
|
+
}
|
|
554
|
+
});
|
|
555
|
+
var githubLight = defineTheme({
|
|
556
|
+
fg: {
|
|
557
|
+
strong: "#1f2328",
|
|
558
|
+
body: "#24292f",
|
|
559
|
+
sub: "#57606a",
|
|
560
|
+
meta: "#6e7781",
|
|
561
|
+
faint: "#8c959f"
|
|
562
|
+
},
|
|
563
|
+
tone: {
|
|
564
|
+
brand: "#0969da",
|
|
565
|
+
accent: "#8250df",
|
|
566
|
+
violet: "#6639ba",
|
|
567
|
+
ok: "#1a7f37",
|
|
568
|
+
warn: "#9a6700",
|
|
569
|
+
err: "#cf222e",
|
|
570
|
+
info: "#0969da"
|
|
571
|
+
},
|
|
572
|
+
toneActive: {
|
|
573
|
+
brand: "#0550ae",
|
|
574
|
+
accent: "#6639ba",
|
|
575
|
+
violet: "#512a97",
|
|
576
|
+
ok: "#116329",
|
|
577
|
+
warn: "#7d4e00",
|
|
578
|
+
err: "#a40e26",
|
|
579
|
+
info: "#0550ae"
|
|
580
|
+
},
|
|
581
|
+
surface: {
|
|
582
|
+
bg: "#ffffff",
|
|
583
|
+
bgInput: "#f6f8fa",
|
|
584
|
+
bgCode: "#f6f8fa",
|
|
585
|
+
bgElev: "#eaeef2"
|
|
586
|
+
}
|
|
587
|
+
});
|
|
588
|
+
var highContrast = defineTheme({
|
|
589
|
+
fg: {
|
|
590
|
+
strong: "#ffffff",
|
|
591
|
+
body: "#f5f5f5",
|
|
592
|
+
sub: "#d4d4d4",
|
|
593
|
+
meta: "#bdbdbd",
|
|
594
|
+
faint: "#8a8a8a"
|
|
595
|
+
},
|
|
596
|
+
tone: {
|
|
597
|
+
brand: "#00e5ff",
|
|
598
|
+
accent: "#ff4dff",
|
|
599
|
+
violet: "#b388ff",
|
|
600
|
+
ok: "#00ff66",
|
|
601
|
+
warn: "#ffdd00",
|
|
602
|
+
err: "#ff4d4d",
|
|
603
|
+
info: "#4da3ff"
|
|
604
|
+
},
|
|
605
|
+
toneActive: {
|
|
606
|
+
brand: "#80f2ff",
|
|
607
|
+
accent: "#ff99ff",
|
|
608
|
+
violet: "#d0b3ff",
|
|
609
|
+
ok: "#80ffb3",
|
|
610
|
+
warn: "#ffee80",
|
|
611
|
+
err: "#ff9999",
|
|
612
|
+
info: "#99c9ff"
|
|
613
|
+
},
|
|
614
|
+
surface: {
|
|
615
|
+
bg: "#000000",
|
|
616
|
+
bgInput: "#0a0a0a",
|
|
617
|
+
bgCode: "#050505",
|
|
618
|
+
bgElev: "#141414"
|
|
619
|
+
}
|
|
620
|
+
});
|
|
621
|
+
var THEMES = {
|
|
622
|
+
default: githubDark,
|
|
623
|
+
dark,
|
|
624
|
+
light,
|
|
625
|
+
"tokyo-night": tokyoNight,
|
|
626
|
+
"github-dark": githubDark,
|
|
627
|
+
"github-light": githubLight,
|
|
628
|
+
"high-contrast": highContrast
|
|
629
|
+
};
|
|
630
|
+
var DEFAULT_THEME_NAME = "default";
|
|
631
|
+
var DEFAULT_THEME = THEMES[DEFAULT_THEME_NAME];
|
|
632
|
+
var activeTheme = DEFAULT_THEME;
|
|
633
|
+
function proxyTokens(select) {
|
|
634
|
+
const target = select(DEFAULT_THEME);
|
|
635
|
+
return new Proxy(target, {
|
|
636
|
+
get(_target, prop) {
|
|
637
|
+
return select(activeTheme)[prop];
|
|
638
|
+
},
|
|
639
|
+
getOwnPropertyDescriptor(_target, prop) {
|
|
640
|
+
return Reflect.getOwnPropertyDescriptor(select(activeTheme), prop);
|
|
641
|
+
},
|
|
642
|
+
has(_target, prop) {
|
|
643
|
+
return prop in select(activeTheme);
|
|
644
|
+
},
|
|
645
|
+
ownKeys() {
|
|
646
|
+
return Reflect.ownKeys(select(activeTheme));
|
|
647
|
+
}
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
var FG = proxyTokens((theme) => theme.fg);
|
|
651
|
+
var TONE = proxyTokens((theme) => theme.tone);
|
|
652
|
+
var TONE_ACTIVE = proxyTokens((theme) => theme.toneActive);
|
|
653
|
+
var SURFACE = proxyTokens((theme) => theme.surface);
|
|
654
|
+
var CARD = proxyTokens((theme) => theme.card);
|
|
655
|
+
|
|
398
656
|
// src/index/config.ts
|
|
399
657
|
import picomatch from "picomatch";
|
|
400
658
|
var DEFAULT_INDEX_EXCLUDES = {
|
|
@@ -610,7 +868,100 @@ var EN = {
|
|
|
610
868
|
ephemeralSession: "\u25B8 ephemeral chat (no session persistence) \u2014 drop --no-session to enable",
|
|
611
869
|
restoredEdits: "\u25B8 restored {count} pending edit block(s) from an interrupted prior run \u2014 /apply to commit or /discard to drop.",
|
|
612
870
|
resumedPlan: "Resumed plan \xB7 {when}{summary}",
|
|
613
|
-
tipEditBindings:
|
|
871
|
+
tipEditBindings: {
|
|
872
|
+
topic: "edit-gate keybindings",
|
|
873
|
+
sections: [
|
|
874
|
+
{
|
|
875
|
+
rows: [
|
|
876
|
+
{ key: "y / n", text: "accept or drop pending edits" },
|
|
877
|
+
{
|
|
878
|
+
key: "Shift+Tab",
|
|
879
|
+
text: "switch review \u2194 AUTO (persisted; AUTO applies instantly)"
|
|
880
|
+
},
|
|
881
|
+
{ key: "u", text: "undo the last auto-applied batch (within the 5s banner)" }
|
|
882
|
+
]
|
|
883
|
+
}
|
|
884
|
+
],
|
|
885
|
+
footer: "Current mode shown in the bottom status bar \xB7 /keys for the full reference"
|
|
886
|
+
},
|
|
887
|
+
tipMouseClipboard: {
|
|
888
|
+
topic: "mouse + clipboard",
|
|
889
|
+
sections: [
|
|
890
|
+
{
|
|
891
|
+
rows: [
|
|
892
|
+
{ key: "wheel", text: "scrolls the chat history above" },
|
|
893
|
+
{
|
|
894
|
+
key: "right-click",
|
|
895
|
+
text: "captured by the app \u2014 use Ctrl+V (Win/Linux) or Cmd+V (macOS) to paste"
|
|
896
|
+
},
|
|
897
|
+
{
|
|
898
|
+
key: "Shift + drag",
|
|
899
|
+
text: "selects text natively (Option on iTerm2, Shift on Win Term / Alacritty / WezTerm)"
|
|
900
|
+
}
|
|
901
|
+
]
|
|
902
|
+
}
|
|
903
|
+
],
|
|
904
|
+
footer: "Run /keys for the full keyboard + mouse reference"
|
|
905
|
+
},
|
|
906
|
+
keysReference: {
|
|
907
|
+
topic: "Reasonix keys + mouse reference",
|
|
908
|
+
sections: [
|
|
909
|
+
{
|
|
910
|
+
title: "keyboard",
|
|
911
|
+
rows: [
|
|
912
|
+
{ key: "Enter", text: "submit the prompt" },
|
|
913
|
+
{ key: "Shift+Enter", text: "insert a newline in the prompt" },
|
|
914
|
+
{ key: "Ctrl+P / Ctrl+N", text: "recall previous / next prompt from history" },
|
|
915
|
+
{ key: "Ctrl+A / Ctrl+E", text: "jump to start / end of the current line" },
|
|
916
|
+
{ key: "Ctrl+W", text: "delete the word before the cursor" },
|
|
917
|
+
{ key: "Ctrl+U", text: "clear the entire prompt buffer" },
|
|
918
|
+
{ key: "Tab", text: "complete @-mention \xB7 drill folder \xB7 accept slash command" },
|
|
919
|
+
{ key: "Shift+Tab", text: "edit-gate: toggle review \u2194 AUTO mode" },
|
|
920
|
+
{ key: "Esc", text: "dismiss picker \xB7 abort the running model turn" },
|
|
921
|
+
{ key: "Ctrl+C", text: "abort the running model turn (NOT copy \u2014 see clipboard)" },
|
|
922
|
+
{
|
|
923
|
+
key: "\u2191 / \u2193",
|
|
924
|
+
text: "scroll chat history (PromptInput cursor when buffer non-empty)"
|
|
925
|
+
},
|
|
926
|
+
{ key: "PgUp / PgDn", text: "scroll chat history a page at a time" },
|
|
927
|
+
{ key: "End", text: "jump chat to the most recent line" }
|
|
928
|
+
]
|
|
929
|
+
},
|
|
930
|
+
{
|
|
931
|
+
title: "mouse",
|
|
932
|
+
rows: [
|
|
933
|
+
{ key: "wheel", text: "scrolls the chat history" },
|
|
934
|
+
{ key: "right-click", text: "captured by the app \u2014 use Ctrl+V / Cmd+V to paste" },
|
|
935
|
+
{ key: "left-click", text: "captured (no action yet \u2014 reserved for future use)" }
|
|
936
|
+
]
|
|
937
|
+
},
|
|
938
|
+
{
|
|
939
|
+
title: "copy / paste",
|
|
940
|
+
rows: [
|
|
941
|
+
{ key: "select text", text: "hold Shift while dragging (Option on iTerm2)" },
|
|
942
|
+
{
|
|
943
|
+
key: "copy",
|
|
944
|
+
text: "Ctrl+Shift+C (Win/Linux) \xB7 Cmd+C (macOS) \u2014 terminal-native after selection"
|
|
945
|
+
},
|
|
946
|
+
{ key: "paste", text: "Ctrl+V or Ctrl+Shift+V (Win/Linux) \xB7 Cmd+V (macOS)" },
|
|
947
|
+
{
|
|
948
|
+
key: "bracketed paste",
|
|
949
|
+
text: "multi-line pastes stay one block \u2014 no auto-submit on intermediate newlines"
|
|
950
|
+
}
|
|
951
|
+
]
|
|
952
|
+
},
|
|
953
|
+
{
|
|
954
|
+
title: "edit-gate (code mode)",
|
|
955
|
+
rows: [
|
|
956
|
+
{ key: "y / n", text: "accept or drop pending edits in the review modal" },
|
|
957
|
+
{ key: "Shift+Tab", text: "toggle review \u2194 AUTO (persisted across sessions)" },
|
|
958
|
+
{ key: "u", text: "undo the last auto-applied batch (within the 5s banner)" }
|
|
959
|
+
]
|
|
960
|
+
}
|
|
961
|
+
],
|
|
962
|
+
footer: "Mouse tracking is on so the wheel scrolls chat instead of moving the cursor \u2014 that's why right-click no longer does the terminal's native paste."
|
|
963
|
+
},
|
|
964
|
+
tipShownOnce: "shown once",
|
|
614
965
|
modelOverride: "override the default model",
|
|
615
966
|
noSession: "disable session persistence for this run",
|
|
616
967
|
resumeHint: "force-resume the named session (even if idle)",
|
|
@@ -735,7 +1086,7 @@ var EN = {
|
|
|
735
1086
|
description: "shrink oversized tool results AND tool-call args (edit_file search/replace) in the log; cap in tokens, default 4000",
|
|
736
1087
|
argsHint: "[tokens]"
|
|
737
1088
|
},
|
|
738
|
-
keys: { description: "
|
|
1089
|
+
keys: { description: "keyboard + mouse + copy/paste reference" },
|
|
739
1090
|
plans: { description: "list this session's active + archived plans, newest first" },
|
|
740
1091
|
replay: {
|
|
741
1092
|
description: "load an archived plan as a read-only Time Travel snapshot (default: newest)",
|
|
@@ -964,7 +1315,8 @@ var EN = {
|
|
|
964
1315
|
loopStopped: "\u25B8 loop stopped.",
|
|
965
1316
|
loopNoActive: "no active loop to stop.",
|
|
966
1317
|
loopNoActiveHint: "no active loop. Start one with `/loop <interval> <prompt>` (e.g. /loop 30s npm test).\nCancels on: /loop stop \xB7 Esc \xB7 /clear /new \xB7 any user-typed prompt.",
|
|
967
|
-
loopStarted: '\u25B8 loop started \u2014 re-submitting "{prompt}" every {duration}. Type anything (or /loop stop) to cancel.'
|
|
1318
|
+
loopStarted: '\u25B8 loop started \u2014 re-submitting "{prompt}" every {duration}. Type anything (or /loop stop) to cancel.',
|
|
1319
|
+
keysNeedsTui: "/keys needs a TUI context (postKeys wired)."
|
|
968
1320
|
},
|
|
969
1321
|
admin: {
|
|
970
1322
|
doctorNeedsTui: "/doctor needs a TUI context (postDoctor wired).",
|
|
@@ -1303,7 +1655,94 @@ var zhCN = {
|
|
|
1303
1655
|
ephemeralSession: "\u25B8 \u4E34\u65F6\u804A\u5929 (\u4E0D\u4FDD\u5B58\u4F1A\u8BDD) \u2014 \u53BB\u6389 --no-session \u4EE5\u542F\u7528\u4FDD\u5B58",
|
|
1304
1656
|
restoredEdits: "\u25B8 \u4ECE\u4E2D\u65AD\u7684\u8FD0\u884C\u4E2D\u6062\u590D\u4E86 {count} \u4E2A\u5F85\u5904\u7406\u7684\u7F16\u8F91\u5757 \u2014 /apply \u63D0\u4EA4\u6216 /discard \u653E\u5F03\u3002",
|
|
1305
1657
|
resumedPlan: "\u5DF2\u6062\u590D\u8BA1\u5212 \xB7 {when}{summary}",
|
|
1306
|
-
tipEditBindings:
|
|
1658
|
+
tipEditBindings: {
|
|
1659
|
+
topic: "\u7F16\u8F91\u95E8\u63A7\u5FEB\u6377\u952E",
|
|
1660
|
+
sections: [
|
|
1661
|
+
{
|
|
1662
|
+
rows: [
|
|
1663
|
+
{ key: "y / n", text: "\u63A5\u53D7\u6216\u653E\u5F03\u5F85\u5904\u7406\u7684\u7F16\u8F91" },
|
|
1664
|
+
{ key: "Shift+Tab", text: "\u5207\u6362 \u9884\u89C8 \u2194 \u81EA\u52A8\uFF08\u6301\u4E45\u5316\uFF1B\u81EA\u52A8\u6A21\u5F0F\u7ACB\u5373\u5E94\u7528\uFF09" },
|
|
1665
|
+
{ key: "u", text: "\u64A4\u9500\u4E0A\u6B21\u81EA\u52A8\u5E94\u7528\u7684\u6279\u5904\u7406\uFF085 \u79D2\u6A2A\u5E45\u5185\uFF09" }
|
|
1666
|
+
]
|
|
1667
|
+
}
|
|
1668
|
+
],
|
|
1669
|
+
footer: "\u5F53\u524D\u6A21\u5F0F\u663E\u793A\u5728\u5E95\u90E8\u72B6\u6001\u680F \xB7 /keys \u67E5\u770B\u5B8C\u6574\u5FEB\u6377\u952E\u53C2\u8003"
|
|
1670
|
+
},
|
|
1671
|
+
tipMouseClipboard: {
|
|
1672
|
+
topic: "\u9F20\u6807 + \u526A\u8D34\u677F",
|
|
1673
|
+
sections: [
|
|
1674
|
+
{
|
|
1675
|
+
rows: [
|
|
1676
|
+
{ key: "\u6EDA\u8F6E", text: "\u6EDA\u52A8\u4E0A\u65B9\u7684\u804A\u5929\u8BB0\u5F55" },
|
|
1677
|
+
{
|
|
1678
|
+
key: "\u53F3\u952E",
|
|
1679
|
+
text: "\u5DF2\u88AB\u5E94\u7528\u63A5\u7BA1 \u2014 \u7528 Ctrl+V\uFF08Win/Linux\uFF09\u6216 Cmd+V\uFF08macOS\uFF09\u7C98\u8D34"
|
|
1680
|
+
},
|
|
1681
|
+
{
|
|
1682
|
+
key: "Shift + \u62D6\u52A8",
|
|
1683
|
+
text: "\u539F\u751F\u9009\u4E2D\u6587\u672C\uFF08iTerm2 \u7528 Option\uFF0CWin Term / Alacritty / WezTerm \u7528 Shift\uFF09"
|
|
1684
|
+
}
|
|
1685
|
+
]
|
|
1686
|
+
}
|
|
1687
|
+
],
|
|
1688
|
+
footer: "\u8FD0\u884C /keys \u67E5\u770B\u5B8C\u6574\u952E\u76D8 + \u9F20\u6807\u53C2\u8003"
|
|
1689
|
+
},
|
|
1690
|
+
keysReference: {
|
|
1691
|
+
topic: "Reasonix \u952E\u76D8 + \u9F20\u6807\u53C2\u8003",
|
|
1692
|
+
sections: [
|
|
1693
|
+
{
|
|
1694
|
+
title: "\u952E\u76D8",
|
|
1695
|
+
rows: [
|
|
1696
|
+
{ key: "Enter", text: "\u63D0\u4EA4\u8F93\u5165" },
|
|
1697
|
+
{ key: "Shift+Enter", text: "\u5728\u8F93\u5165\u6846\u4E2D\u63D2\u5165\u6362\u884C" },
|
|
1698
|
+
{ key: "Ctrl+P / Ctrl+N", text: "\u8C03\u51FA\u4E0A\u4E00\u6761 / \u4E0B\u4E00\u6761\u5386\u53F2\u63D0\u793A" },
|
|
1699
|
+
{ key: "Ctrl+A / Ctrl+E", text: "\u8DF3\u5230\u5F53\u524D\u884C\u7684\u5F00\u5934 / \u7ED3\u5C3E" },
|
|
1700
|
+
{ key: "Ctrl+W", text: "\u5220\u9664\u5149\u6807\u524D\u7684\u4E00\u4E2A\u8BCD" },
|
|
1701
|
+
{ key: "Ctrl+U", text: "\u6E05\u7A7A\u6574\u4E2A\u8F93\u5165\u7F13\u51B2\u533A" },
|
|
1702
|
+
{ key: "Tab", text: "\u8865\u5168 @-mention \xB7 \u8FDB\u5165\u6587\u4EF6\u5939 \xB7 \u63A5\u53D7 slash \u547D\u4EE4" },
|
|
1703
|
+
{ key: "Shift+Tab", text: "\u7F16\u8F91\u95E8\u63A7\uFF1A\u5207\u6362 \u9884\u89C8 \u2194 \u81EA\u52A8 \u6A21\u5F0F" },
|
|
1704
|
+
{ key: "Esc", text: "\u5173\u95ED\u5F39\u51FA\u9009\u62E9\u5668 \xB7 \u4E2D\u6B62\u5F53\u524D\u6A21\u578B\u56DE\u5408" },
|
|
1705
|
+
{ key: "Ctrl+C", text: "\u4E2D\u6B62\u5F53\u524D\u6A21\u578B\u56DE\u5408\uFF08\u4E0D\u662F\u590D\u5236 \u2014 \u89C1\u526A\u8D34\u677F\u6BB5\uFF09" },
|
|
1706
|
+
{ key: "\u2191 / \u2193", text: "\u6EDA\u52A8\u804A\u5929\u8BB0\u5F55\uFF08\u7F13\u51B2\u533A\u975E\u7A7A\u65F6\u4E3A\u5149\u6807\u79FB\u52A8\uFF09" },
|
|
1707
|
+
{ key: "PgUp / PgDn", text: "\u6574\u9875\u6EDA\u52A8\u804A\u5929\u8BB0\u5F55" },
|
|
1708
|
+
{ key: "End", text: "\u8DF3\u5230\u804A\u5929\u7684\u6700\u65B0\u4E00\u884C" }
|
|
1709
|
+
]
|
|
1710
|
+
},
|
|
1711
|
+
{
|
|
1712
|
+
title: "\u9F20\u6807",
|
|
1713
|
+
rows: [
|
|
1714
|
+
{ key: "\u6EDA\u8F6E", text: "\u6EDA\u52A8\u804A\u5929\u8BB0\u5F55" },
|
|
1715
|
+
{ key: "\u53F3\u952E", text: "\u88AB\u5E94\u7528\u63A5\u7BA1 \u2014 \u7528 Ctrl+V / Cmd+V \u7C98\u8D34" },
|
|
1716
|
+
{ key: "\u5DE6\u952E", text: "\u88AB\u63A5\u7BA1\uFF08\u6682\u65E0\u52A8\u4F5C \u2014 \u9884\u7559\u7ED9\u540E\u7EED\u529F\u80FD\uFF09" }
|
|
1717
|
+
]
|
|
1718
|
+
},
|
|
1719
|
+
{
|
|
1720
|
+
title: "\u590D\u5236 / \u7C98\u8D34",
|
|
1721
|
+
rows: [
|
|
1722
|
+
{ key: "\u9009\u4E2D\u6587\u5B57", text: "\u62D6\u52A8\u65F6\u6309\u4F4F Shift\uFF08iTerm2 \u7528 Option\uFF09" },
|
|
1723
|
+
{
|
|
1724
|
+
key: "\u590D\u5236",
|
|
1725
|
+
text: "Ctrl+Shift+C\uFF08Win/Linux\uFF09\xB7 Cmd+C\uFF08macOS\uFF09\u2014 \u9009\u4E2D\u540E\u7531\u7EC8\u7AEF\u539F\u751F\u5904\u7406"
|
|
1726
|
+
},
|
|
1727
|
+
{ key: "\u7C98\u8D34", text: "Ctrl+V \u6216 Ctrl+Shift+V\uFF08Win/Linux\uFF09\xB7 Cmd+V\uFF08macOS\uFF09" },
|
|
1728
|
+
{
|
|
1729
|
+
key: "bracketed paste",
|
|
1730
|
+
text: "\u591A\u884C\u7C98\u8D34\u6574\u4F53\u8FDB\u5165 \u2014 \u4E2D\u95F4\u6362\u884C\u4E0D\u4F1A\u89E6\u53D1\u63D0\u4EA4"
|
|
1731
|
+
}
|
|
1732
|
+
]
|
|
1733
|
+
},
|
|
1734
|
+
{
|
|
1735
|
+
title: "\u7F16\u8F91\u95E8\u63A7\uFF08\u4EC5 code \u6A21\u5F0F\uFF09",
|
|
1736
|
+
rows: [
|
|
1737
|
+
{ key: "y / n", text: "\u5728\u9884\u89C8\u6A21\u6001\u4E2D\u63A5\u53D7\u6216\u653E\u5F03\u5F85\u5904\u7406\u7684\u7F16\u8F91" },
|
|
1738
|
+
{ key: "Shift+Tab", text: "\u5207\u6362 \u9884\u89C8 \u2194 \u81EA\u52A8\uFF08\u6301\u4E45\u5316\uFF09" },
|
|
1739
|
+
{ key: "u", text: "\u64A4\u9500\u4E0A\u6B21\u81EA\u52A8\u5E94\u7528\u7684\u6279\u5904\u7406\uFF085 \u79D2\u6A2A\u5E45\u5185\uFF09" }
|
|
1740
|
+
]
|
|
1741
|
+
}
|
|
1742
|
+
],
|
|
1743
|
+
footer: "\u9F20\u6807\u8FFD\u8E2A\u5DF2\u5F00\u542F\uFF0C\u6EDA\u8F6E\u7528\u6765\u6EDA\u52A8\u804A\u5929\u800C\u4E0D\u662F\u79FB\u52A8\u5149\u6807 \u2014 \u8FD9\u4E5F\u662F\u53F3\u952E\u4E0D\u518D\u89E6\u53D1\u7EC8\u7AEF\u539F\u751F\u7C98\u8D34\u7684\u539F\u56E0\u3002"
|
|
1744
|
+
},
|
|
1745
|
+
tipShownOnce: "\u4EC5\u663E\u793A\u4E00\u6B21",
|
|
1307
1746
|
modelOverride: "\u8986\u76D6\u9ED8\u8BA4\u6A21\u578B",
|
|
1308
1747
|
noSession: "\u7981\u7528\u672C\u6B21\u8FD0\u884C\u7684\u4F1A\u8BDD\u6301\u4E45\u5316",
|
|
1309
1748
|
resumeHint: "\u5F3A\u5236\u6062\u590D\u6307\u5B9A\u4F1A\u8BDD\uFF08\u5373\u4F7F\u7A7A\u95F2\uFF09",
|
|
@@ -1430,7 +1869,7 @@ var zhCN = {
|
|
|
1430
1869
|
description: "\u7F29\u5C0F\u65E5\u5FD7\u4E2D\u8FC7\u5927\u7684\u5DE5\u5177\u7ED3\u679C\u548C\u5DE5\u5177\u8C03\u7528\u53C2\u6570\uFF1B\u4E0A\u9650\u4E3A tokens\uFF0C\u9ED8\u8BA4 4000",
|
|
1431
1870
|
argsHint: "[tokens]"
|
|
1432
1871
|
},
|
|
1433
|
-
keys: { description: "\
|
|
1872
|
+
keys: { description: "\u952E\u76D8 + \u9F20\u6807 + \u590D\u5236\u7C98\u8D34\u53C2\u8003" },
|
|
1434
1873
|
plans: { description: "\u5217\u51FA\u6B64\u4F1A\u8BDD\u7684\u6D3B\u8DC3 + \u5F52\u6863\u8BA1\u5212\uFF08\u6700\u65B0\u5728\u524D\uFF09" },
|
|
1435
1874
|
replay: {
|
|
1436
1875
|
description: "\u52A0\u8F7D\u5F52\u6863\u8BA1\u5212\u4E3A\u53EA\u8BFB\u7684\u65F6\u95F4\u65C5\u884C\u5FEB\u7167\uFF08\u9ED8\u8BA4\uFF1A\u6700\u65B0\uFF09",
|
|
@@ -1661,7 +2100,8 @@ var zhCN = {
|
|
|
1661
2100
|
loopStopped: "\u25B8 \u5FAA\u73AF\u5DF2\u505C\u6B62\u3002",
|
|
1662
2101
|
loopNoActive: "\u6CA1\u6709\u6D3B\u52A8\u7684\u5FAA\u73AF\u53EF\u505C\u6B62\u3002",
|
|
1663
2102
|
loopNoActiveHint: "\u6CA1\u6709\u6D3B\u52A8\u7684\u5FAA\u73AF\u3002\u4F7F\u7528 `/loop <interval> <prompt>` \u542F\u52A8\u4E00\u4E2A\uFF08\u4F8B\u5982 /loop 30s npm test\uFF09\u3002\n\u53D6\u6D88\u65B9\u5F0F\uFF1A/loop stop \xB7 Esc \xB7 /clear /new \xB7 \u4EFB\u4F55\u7528\u6237\u8F93\u5165\u7684\u63D0\u793A\u3002",
|
|
1664
|
-
loopStarted: '\u25B8 \u5FAA\u73AF\u5DF2\u542F\u52A8 \u2014 \u6BCF {duration} \u91CD\u65B0\u63D0\u4EA4 "{prompt}"\u3002\u8F93\u5165\u4EFB\u4F55\u5185\u5BB9\uFF08\u6216 /loop stop\uFF09\u53D6\u6D88\u3002'
|
|
2103
|
+
loopStarted: '\u25B8 \u5FAA\u73AF\u5DF2\u542F\u52A8 \u2014 \u6BCF {duration} \u91CD\u65B0\u63D0\u4EA4 "{prompt}"\u3002\u8F93\u5165\u4EFB\u4F55\u5185\u5BB9\uFF08\u6216 /loop stop\uFF09\u53D6\u6D88\u3002',
|
|
2104
|
+
keysNeedsTui: "/keys \u9700\u8981 TUI \u4E0A\u4E0B\u6587\uFF08postKeys \u5DF2\u8FDE\u63A5\uFF09\u3002"
|
|
1665
2105
|
},
|
|
1666
2106
|
admin: {
|
|
1667
2107
|
doctorNeedsTui: "/doctor \u9700\u8981 TUI \u4E0A\u4E0B\u6587\uFF08postDoctor \u5DF2\u8FDE\u63A5\uFF09\u3002",
|
|
@@ -4777,13 +5217,41 @@ function listFilesWithStatsSync(root, opts = {}) {
|
|
|
4777
5217
|
return out;
|
|
4778
5218
|
}
|
|
4779
5219
|
async function listFilesWithStatsAsync(root, opts = {}) {
|
|
5220
|
+
const out = [];
|
|
4780
5221
|
const maxResults = Math.max(1, opts.maxResults ?? 2e3);
|
|
5222
|
+
await walkFilesStream(root, {
|
|
5223
|
+
...opts,
|
|
5224
|
+
onEntry: (e) => {
|
|
5225
|
+
out.push(e);
|
|
5226
|
+
return out.length < maxResults;
|
|
5227
|
+
}
|
|
5228
|
+
});
|
|
5229
|
+
return out;
|
|
5230
|
+
}
|
|
5231
|
+
async function walkFilesStream(root, opts) {
|
|
4781
5232
|
const ignoreDirs = new Set(opts.ignoreDirs ?? DEFAULT_PICKER_IGNORE_DIRS);
|
|
4782
|
-
const rootAbs = resolve(root);
|
|
4783
5233
|
const respectGi = opts.respectGitignore !== false;
|
|
4784
|
-
const
|
|
5234
|
+
const rootAbs = resolve(root);
|
|
5235
|
+
const progressGap = Math.max(0, opts.progressIntervalMs ?? 100);
|
|
5236
|
+
let scanned = 0;
|
|
5237
|
+
let halted = false;
|
|
5238
|
+
let lastProgress = 0;
|
|
5239
|
+
const reportProgress = (force) => {
|
|
5240
|
+
if (!opts.onProgress) return;
|
|
5241
|
+
const now = Date.now();
|
|
5242
|
+
if (force || now - lastProgress >= progressGap) {
|
|
5243
|
+
lastProgress = now;
|
|
5244
|
+
opts.onProgress(scanned);
|
|
5245
|
+
}
|
|
5246
|
+
};
|
|
5247
|
+
const emit = (entry) => {
|
|
5248
|
+
scanned++;
|
|
5249
|
+
if (halted) return;
|
|
5250
|
+
if (opts.onEntry(entry) === false) halted = true;
|
|
5251
|
+
reportProgress(false);
|
|
5252
|
+
};
|
|
4785
5253
|
const walk2 = async (dirAbs, dirRel, layers) => {
|
|
4786
|
-
if (
|
|
5254
|
+
if (halted || opts.signal?.aborted) return;
|
|
4787
5255
|
let effectiveLayers = layers;
|
|
4788
5256
|
if (respectGi) {
|
|
4789
5257
|
const ig = await loadGitignoreAt(dirAbs);
|
|
@@ -4798,36 +5266,31 @@ async function listFilesWithStatsAsync(root, opts = {}) {
|
|
|
4798
5266
|
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
4799
5267
|
const fileEnts = [];
|
|
4800
5268
|
for (const ent of entries) {
|
|
4801
|
-
if (
|
|
4802
|
-
const relPath = dirRel ? `${dirRel}/${ent.name}` : ent.name;
|
|
5269
|
+
if (halted || opts.signal?.aborted) break;
|
|
4803
5270
|
const absPath = join5(dirAbs, ent.name);
|
|
4804
5271
|
if (ent.isDirectory()) {
|
|
4805
5272
|
if (ent.name.startsWith(".") || ignoreDirs.has(ent.name)) continue;
|
|
4806
5273
|
if (ignoredByLayers(effectiveLayers, absPath, true)) continue;
|
|
4807
5274
|
if (fileEnts.length > 0) {
|
|
4808
|
-
await
|
|
5275
|
+
await flushFiles(fileEnts, dirAbs, dirRel, effectiveLayers, emit);
|
|
4809
5276
|
fileEnts.length = 0;
|
|
4810
|
-
if (
|
|
5277
|
+
if (halted || opts.signal?.aborted) return;
|
|
4811
5278
|
}
|
|
4812
|
-
await walk2(absPath,
|
|
5279
|
+
await walk2(absPath, dirRel ? `${dirRel}/${ent.name}` : ent.name, effectiveLayers);
|
|
4813
5280
|
} else if (ent.isFile() || ent.isSymbolicLink()) {
|
|
4814
5281
|
fileEnts.push(ent);
|
|
4815
5282
|
}
|
|
4816
5283
|
}
|
|
4817
|
-
if (fileEnts.length > 0 &&
|
|
4818
|
-
await
|
|
5284
|
+
if (fileEnts.length > 0 && !halted && !opts.signal?.aborted) {
|
|
5285
|
+
await flushFiles(fileEnts, dirAbs, dirRel, effectiveLayers, emit);
|
|
4819
5286
|
}
|
|
4820
5287
|
};
|
|
4821
5288
|
await walk2(rootAbs, "", []);
|
|
4822
|
-
|
|
5289
|
+
reportProgress(true);
|
|
5290
|
+
return { scanned, cancelled: !!opts.signal?.aborted };
|
|
4823
5291
|
}
|
|
4824
|
-
async function
|
|
4825
|
-
const accepted =
|
|
4826
|
-
for (const e of ents) {
|
|
4827
|
-
if (out.length + accepted.length >= maxResults) break;
|
|
4828
|
-
if (ignoredByLayers(layers, join5(dirAbs, e.name), false)) continue;
|
|
4829
|
-
accepted.push(e);
|
|
4830
|
-
}
|
|
5292
|
+
async function flushFiles(ents, dirAbs, dirRel, layers, emit) {
|
|
5293
|
+
const accepted = ents.filter((e) => !ignoredByLayers(layers, join5(dirAbs, e.name), false));
|
|
4831
5294
|
const stats = await Promise.all(
|
|
4832
5295
|
accepted.map(
|
|
4833
5296
|
(e) => stat(join5(dirAbs, e.name)).then((s) => ({ mtimeMs: s.mtimeMs, isFile: s.isFile() })).catch(() => null)
|
|
@@ -4836,14 +5299,90 @@ async function statBatch(ents, dirAbs, dirRel, out, maxResults, layers) {
|
|
|
4836
5299
|
for (let i = 0; i < accepted.length; i++) {
|
|
4837
5300
|
const ent = accepted[i];
|
|
4838
5301
|
const s = stats[i];
|
|
4839
|
-
if (ent.isSymbolicLink())
|
|
4840
|
-
|
|
5302
|
+
if (ent.isSymbolicLink() && (!s || !s.isFile)) continue;
|
|
5303
|
+
emit({
|
|
5304
|
+
path: dirRel ? `${dirRel}/${ent.name}` : ent.name,
|
|
5305
|
+
mtimeMs: s?.mtimeMs ?? 0
|
|
5306
|
+
});
|
|
5307
|
+
}
|
|
5308
|
+
}
|
|
5309
|
+
async function listDirectory(root, relDir, opts = {}) {
|
|
5310
|
+
const ignoreDirs = new Set(opts.ignoreDirs ?? DEFAULT_PICKER_IGNORE_DIRS);
|
|
5311
|
+
const respectGi = opts.respectGitignore !== false;
|
|
5312
|
+
const rootAbs = resolve(root);
|
|
5313
|
+
const dirAbs = resolve(rootAbs, relDir);
|
|
5314
|
+
const rel = relative(rootAbs, dirAbs);
|
|
5315
|
+
if (rel.startsWith("..") || isAbsolute(rel)) return [];
|
|
5316
|
+
const layers = [];
|
|
5317
|
+
if (respectGi) {
|
|
5318
|
+
const segs = rel ? rel.split(/[\\/]/) : [];
|
|
5319
|
+
let cursor = rootAbs;
|
|
5320
|
+
const ig = await loadGitignoreAt(cursor);
|
|
5321
|
+
if (ig) layers.push({ dirAbs: cursor, ig });
|
|
5322
|
+
for (const seg of segs) {
|
|
5323
|
+
cursor = join5(cursor, seg);
|
|
5324
|
+
const igSeg = await loadGitignoreAt(cursor);
|
|
5325
|
+
if (igSeg) layers.push({ dirAbs: cursor, ig: igSeg });
|
|
4841
5326
|
}
|
|
4842
|
-
|
|
5327
|
+
}
|
|
5328
|
+
let raw;
|
|
5329
|
+
try {
|
|
5330
|
+
raw = await readdir(dirAbs, { withFileTypes: true });
|
|
5331
|
+
} catch {
|
|
5332
|
+
return [];
|
|
5333
|
+
}
|
|
5334
|
+
const dirRel = rel.split(/[\\/]/).join("/");
|
|
5335
|
+
const dirs = [];
|
|
5336
|
+
const files = [];
|
|
5337
|
+
for (const ent of raw) {
|
|
5338
|
+
const absPath = join5(dirAbs, ent.name);
|
|
5339
|
+
if (ent.isDirectory()) {
|
|
5340
|
+
if (ent.name.startsWith(".") || ignoreDirs.has(ent.name)) continue;
|
|
5341
|
+
if (ignoredByLayers(layers, absPath, true)) continue;
|
|
5342
|
+
dirs.push({
|
|
5343
|
+
name: ent.name,
|
|
5344
|
+
path: dirRel ? `${dirRel}/${ent.name}` : ent.name,
|
|
5345
|
+
isDir: true,
|
|
5346
|
+
mtimeMs: 0
|
|
5347
|
+
});
|
|
5348
|
+
} else if (ent.isFile() || ent.isSymbolicLink()) {
|
|
5349
|
+
if (ignoredByLayers(layers, absPath, false)) continue;
|
|
5350
|
+
files.push(ent);
|
|
5351
|
+
}
|
|
5352
|
+
}
|
|
5353
|
+
const stats = await Promise.all(
|
|
5354
|
+
files.map(
|
|
5355
|
+
(e) => stat(join5(dirAbs, e.name)).then((s) => ({ mtimeMs: s.mtimeMs, isFile: s.isFile() })).catch(() => null)
|
|
5356
|
+
)
|
|
5357
|
+
);
|
|
5358
|
+
const fileEntries = [];
|
|
5359
|
+
for (let i = 0; i < files.length; i++) {
|
|
5360
|
+
const ent = files[i];
|
|
5361
|
+
const s = stats[i];
|
|
5362
|
+
if (ent.isSymbolicLink() && (!s || !s.isFile)) continue;
|
|
5363
|
+
fileEntries.push({
|
|
5364
|
+
name: ent.name,
|
|
4843
5365
|
path: dirRel ? `${dirRel}/${ent.name}` : ent.name,
|
|
5366
|
+
isDir: false,
|
|
4844
5367
|
mtimeMs: s?.mtimeMs ?? 0
|
|
4845
5368
|
});
|
|
4846
5369
|
}
|
|
5370
|
+
dirs.sort((a, b) => a.name.localeCompare(b.name));
|
|
5371
|
+
fileEntries.sort((a, b) => a.name.localeCompare(b.name));
|
|
5372
|
+
return [...dirs, ...fileEntries];
|
|
5373
|
+
}
|
|
5374
|
+
function parseAtQuery(query) {
|
|
5375
|
+
const normalized = query.replace(/\\/g, "/");
|
|
5376
|
+
const trailingSlash = normalized.endsWith("/");
|
|
5377
|
+
const trimmed = trailingSlash ? normalized.slice(0, -1) : normalized;
|
|
5378
|
+
const lastSlash = trimmed.lastIndexOf("/");
|
|
5379
|
+
if (trailingSlash) return { dir: trimmed, filter: "", trailingSlash: true };
|
|
5380
|
+
if (lastSlash < 0) return { dir: "", filter: trimmed, trailingSlash: false };
|
|
5381
|
+
return {
|
|
5382
|
+
dir: trimmed.slice(0, lastSlash),
|
|
5383
|
+
filter: trimmed.slice(lastSlash + 1),
|
|
5384
|
+
trailingSlash: false
|
|
5385
|
+
};
|
|
4847
5386
|
}
|
|
4848
5387
|
var AT_PICKER_PREFIX = /(?:^|\s)@([a-zA-Z0-9_./\\-]*)$/;
|
|
4849
5388
|
function detectAtPicker(input) {
|
|
@@ -11480,6 +12019,7 @@ export {
|
|
|
11480
12019
|
isJsonRpcError,
|
|
11481
12020
|
isNpxInstall,
|
|
11482
12021
|
isPlausibleKey,
|
|
12022
|
+
listDirectory,
|
|
11483
12023
|
listFilesSync,
|
|
11484
12024
|
listFilesWithStatsAsync,
|
|
11485
12025
|
listFilesWithStatsSync,
|
|
@@ -11493,6 +12033,7 @@ export {
|
|
|
11493
12033
|
nestArguments,
|
|
11494
12034
|
openTranscriptFile,
|
|
11495
12035
|
outputCostUsd,
|
|
12036
|
+
parseAtQuery,
|
|
11496
12037
|
parseEditBlocks,
|
|
11497
12038
|
parseMcpSpec,
|
|
11498
12039
|
parseMojeekResults,
|
|
@@ -11537,6 +12078,7 @@ export {
|
|
|
11537
12078
|
tokenizeCommand,
|
|
11538
12079
|
truncateForModel,
|
|
11539
12080
|
truncateForModelByTokens,
|
|
12081
|
+
walkFilesStream,
|
|
11540
12082
|
webFetch,
|
|
11541
12083
|
webSearch,
|
|
11542
12084
|
withUtf8Codepage,
|