@wrongstack/tui 0.305.0 → 0.306.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/index.js CHANGED
@@ -293,7 +293,7 @@ var init_connections_health = __esm({
293
293
  // src/app.tsx
294
294
  import * as path7 from "node:path";
295
295
  import { applyRewindToConversation, DefaultSessionRewinder } from "@wrongstack/core/storage";
296
- import React9, { useCallback as useCallback25, useEffect as useEffect66, useRef as useRef38 } from "react";
296
+ import React9, { useCallback as useCallback25, useEffect as useEffect67, useRef as useRef38 } from "react";
297
297
 
298
298
  // src/ink.tsx
299
299
  import { Box as InkBox, Text as InkText } from "ink";
@@ -315,6 +315,12 @@ var pastel = Object.freeze({
315
315
  // Greys
316
316
  gray: "#7f849c",
317
317
  grey: "#7f849c",
318
+ // Lifted grey used for comment tokens sitting on a diff wash. `gray` falls
319
+ // below WCAG AA on `diffAddBg`/`diffDelBg`; this clears both. MUST exist in
320
+ // this map — `softColor` passes unknown names through untouched and Ink /
321
+ // chalk then silently drop them, rendering the token with no color at all.
322
+ grayBright: "#a6adc8",
323
+ greyBright: "#a6adc8",
318
324
  // Bright variants — a touch lighter / shifted within the same family
319
325
  blackBright: "#585b70",
320
326
  redBright: "#eba0ac",
@@ -334,8 +340,32 @@ var pastel = Object.freeze({
334
340
  flamingo: "#f2cdcd"
335
341
  });
336
342
  var catppuccin = pastel;
343
+ var SYNTAX_TOKEN = Object.freeze({
344
+ keyword: "brand",
345
+ string: "success",
346
+ comment: "textMuted",
347
+ commentOnWash: "textSecondary",
348
+ number: "warn",
349
+ literal: "warn",
350
+ property: "accent",
351
+ variable: "accent",
352
+ command: "accent",
353
+ flag: "warn",
354
+ decorator: "brand",
355
+ diffAdd: "success",
356
+ diffDel: "error",
357
+ diffMeta: "accent"
358
+ });
359
+ var SYNTAX_PREFIX = "syntax.";
360
+ function resolveSyntaxColor(role, palette = theme) {
361
+ return palette.syntax?.[role] ?? palette[SYNTAX_TOKEN[role]];
362
+ }
337
363
  function softColor(color) {
338
364
  if (!color) return color;
365
+ if (color.startsWith(SYNTAX_PREFIX)) {
366
+ const role = color.slice(SYNTAX_PREFIX.length);
367
+ return role in SYNTAX_TOKEN ? resolveSyntaxColor(role) : color;
368
+ }
339
369
  return pastel[color] ?? color;
340
370
  }
341
371
  function detectSupportsBackground(env = process.env, isTTY = process.stdout.isTTY ?? false) {
@@ -408,6 +438,9 @@ function setActiveTheme(name) {
408
438
  }
409
439
  const t = theme;
410
440
  const p = preset;
441
+ for (const k of Object.keys(t)) {
442
+ if (!(k in p)) delete t[k];
443
+ }
411
444
  for (const k of Object.keys(p)) {
412
445
  t[k] = p[k];
413
446
  }
@@ -459,7 +492,9 @@ var themePresets = Object.freeze({
459
492
  brand: "#bb9af7",
460
493
  surface: "#16161e",
461
494
  surfaceRaised: "#1a1b26",
462
- monitor: { ...baseTheme.monitor, fleet: "#7dcfff", agents: "#bb9af7", goal: "#9ece6a" }
495
+ diffAddBg: "#1c3326",
496
+ diffDelBg: "#37202b",
497
+ monitor: { fleet: "#7dcfff", agents: "#bb9af7", worktree: "#9ece6a", phase: "#7dcfff" }
463
498
  }),
464
499
  nord: Object.freeze({
465
500
  ...baseTheme,
@@ -478,7 +513,9 @@ var themePresets = Object.freeze({
478
513
  brand: "#b48ead",
479
514
  surface: "#2e3440",
480
515
  surfaceRaised: "#3b4252",
481
- monitor: { ...baseTheme.monitor, fleet: "#88c0d0", agents: "#b48ead", goal: "#a3be8c" }
516
+ diffAddBg: "#2f4034",
517
+ diffDelBg: "#442f35",
518
+ monitor: { fleet: "#88c0d0", agents: "#b48ead", worktree: "#a3be8c", phase: "#88c0d0" }
482
519
  }),
483
520
  cyberpunk: Object.freeze({
484
521
  ...baseTheme,
@@ -497,7 +534,9 @@ var themePresets = Object.freeze({
497
534
  brand: "#ff00aa",
498
535
  surface: "#0d0d1a",
499
536
  surfaceRaised: "#16162a",
500
- monitor: { ...baseTheme.monitor, fleet: "#00f0ff", agents: "#ff00aa", goal: "#00ff66" }
537
+ diffAddBg: "#0d2e1f",
538
+ diffDelBg: "#2e0d1c",
539
+ monitor: { fleet: "#00f0ff", agents: "#ff00aa", worktree: "#00ff66", phase: "#00f0ff" }
501
540
  }),
502
541
  dracula: Object.freeze({
503
542
  ...baseTheme,
@@ -516,7 +555,9 @@ var themePresets = Object.freeze({
516
555
  brand: "#ff79c6",
517
556
  surface: "#282a36",
518
557
  surfaceRaised: "#44475a",
519
- monitor: { ...baseTheme.monitor, fleet: "#8be9fd", agents: "#ff79c6", goal: "#50fa7b" }
558
+ diffAddBg: "#26402e",
559
+ diffDelBg: "#43262e",
560
+ monitor: { fleet: "#8be9fd", agents: "#ff79c6", worktree: "#50fa7b", phase: "#8be9fd" }
520
561
  }),
521
562
  "gruvbox-dark": Object.freeze({
522
563
  ...baseTheme,
@@ -537,7 +578,7 @@ var themePresets = Object.freeze({
537
578
  surfaceRaised: "#3c3836",
538
579
  diffAddBg: "#1f3a1f",
539
580
  diffDelBg: "#3a1f1f",
540
- monitor: { ...baseTheme.monitor, fleet: "#83a598", agents: "#d3869b", goal: "#b8bb26" }
581
+ monitor: { fleet: "#83a598", agents: "#d3869b", worktree: "#b8bb26", phase: "#83a598" }
541
582
  }),
542
583
  "solarized-dark": Object.freeze({
543
584
  ...baseTheme,
@@ -558,7 +599,7 @@ var themePresets = Object.freeze({
558
599
  surfaceRaised: "#073642",
559
600
  diffAddBg: "#0e3a30",
560
601
  diffDelBg: "#3a1a1a",
561
- monitor: { ...baseTheme.monitor, fleet: "#268bd2", agents: "#d33682", goal: "#859900" }
602
+ monitor: { fleet: "#268bd2", agents: "#d33682", worktree: "#859900", phase: "#268bd2" }
562
603
  }),
563
604
  "one-dark": Object.freeze({
564
605
  ...baseTheme,
@@ -579,7 +620,7 @@ var themePresets = Object.freeze({
579
620
  surfaceRaised: "#282c34",
580
621
  diffAddBg: "#1f3a26",
581
622
  diffDelBg: "#3a2226",
582
- monitor: { ...baseTheme.monitor, fleet: "#61afef", agents: "#c678dd", goal: "#98c379" }
623
+ monitor: { fleet: "#61afef", agents: "#c678dd", worktree: "#98c379", phase: "#61afef" }
583
624
  }),
584
625
  monokai: Object.freeze({
585
626
  ...baseTheme,
@@ -600,7 +641,7 @@ var themePresets = Object.freeze({
600
641
  surfaceRaised: "#272822",
601
642
  diffAddBg: "#1f3318",
602
643
  diffDelBg: "#3a1f25",
603
- monitor: { ...baseTheme.monitor, fleet: "#66d9ef", agents: "#ae81ff", goal: "#a6e22e" }
644
+ monitor: { fleet: "#66d9ef", agents: "#ae81ff", worktree: "#a6e22e", phase: "#66d9ef" }
604
645
  }),
605
646
  "rose-pine": Object.freeze({
606
647
  ...baseTheme,
@@ -621,7 +662,7 @@ var themePresets = Object.freeze({
621
662
  surfaceRaised: "#1f1d2e",
622
663
  diffAddBg: "#1f3538",
623
664
  diffDelBg: "#3a2530",
624
- monitor: { ...baseTheme.monitor, fleet: "#9ccfd8", agents: "#c4a7e7", goal: "#31748f" }
665
+ monitor: { fleet: "#9ccfd8", agents: "#c4a7e7", worktree: "#31748f", phase: "#9ccfd8" }
625
666
  }),
626
667
  kanagawa: Object.freeze({
627
668
  ...baseTheme,
@@ -642,7 +683,7 @@ var themePresets = Object.freeze({
642
683
  surfaceRaised: "#1f1f28",
643
684
  diffAddBg: "#1f2d1f",
644
685
  diffDelBg: "#321e22",
645
- monitor: { ...baseTheme.monitor, fleet: "#7fb4ca", agents: "#957fb8", goal: "#98bb6e" }
686
+ monitor: { fleet: "#7fb4ca", agents: "#957fb8", worktree: "#98bb6e", phase: "#7fb4ca" }
646
687
  }),
647
688
  "ayu-dark": Object.freeze({
648
689
  ...baseTheme,
@@ -663,7 +704,7 @@ var themePresets = Object.freeze({
663
704
  surfaceRaised: "#14181f",
664
705
  diffAddBg: "#1c2a1f",
665
706
  diffDelBg: "#2e1c20",
666
- monitor: { ...baseTheme.monitor, fleet: "#59c2ff", agents: "#d4b5ff", goal: "#aad94c" }
707
+ monitor: { fleet: "#59c2ff", agents: "#d4b5ff", worktree: "#aad94c", phase: "#59c2ff" }
667
708
  }),
668
709
  everforest: Object.freeze({
669
710
  ...baseTheme,
@@ -684,7 +725,7 @@ var themePresets = Object.freeze({
684
725
  surfaceRaised: "#343f44",
685
726
  diffAddBg: "#1f3326",
686
727
  diffDelBg: "#331f25",
687
- monitor: { ...baseTheme.monitor, fleet: "#7fbbb3", agents: "#d699b6", goal: "#a7c080" }
728
+ monitor: { fleet: "#7fbbb3", agents: "#d699b6", worktree: "#a7c080", phase: "#7fbbb3" }
688
729
  }),
689
730
  "night-owl": Object.freeze({
690
731
  ...baseTheme,
@@ -705,7 +746,7 @@ var themePresets = Object.freeze({
705
746
  surfaceRaised: "#0b253a",
706
747
  diffAddBg: "#0e2e26",
707
748
  diffDelBg: "#2e1722",
708
- monitor: { ...baseTheme.monitor, fleet: "#82aaff", agents: "#c792ea", goal: "#c3e88d" }
749
+ monitor: { fleet: "#82aaff", agents: "#c792ea", worktree: "#c3e88d", phase: "#82aaff" }
709
750
  }),
710
751
  synthwave: Object.freeze({
711
752
  ...baseTheme,
@@ -726,7 +767,508 @@ var themePresets = Object.freeze({
726
767
  surfaceRaised: "#241b46",
727
768
  diffAddBg: "#1f3530",
728
769
  diffDelBg: "#3a1f30",
729
- monitor: { ...baseTheme.monitor, fleet: "#36f9f6", agents: "#b56cff", goal: "#72f1b8" }
770
+ monitor: { fleet: "#36f9f6", agents: "#b56cff", worktree: "#72f1b8", phase: "#36f9f6" }
771
+ }),
772
+ "github-dark": Object.freeze({
773
+ ...baseTheme,
774
+ textPrimary: "#c9d1d9",
775
+ textSecondary: "#b1bac4",
776
+ textMuted: "#8b949e",
777
+ brandPrimary: "#d29922",
778
+ brandAccent: "#bc8cff",
779
+ accent: "#58a6ff",
780
+ user: "#d29922",
781
+ assistant: "#58a6ff",
782
+ tool: "#39c5cf",
783
+ success: "#3fb950",
784
+ warn: "#d29922",
785
+ error: "#f85149",
786
+ borderDefault: "#30363d",
787
+ borderSubtle: "#21262d",
788
+ borderActive: "#58a6ff",
789
+ brand: "#bc8cff",
790
+ surface: "#0d1117",
791
+ surfaceRaised: "#161b22",
792
+ diffAddBg: "#0d2f18",
793
+ diffDelBg: "#3d1418",
794
+ monitor: { fleet: "#58a6ff", agents: "#bc8cff", worktree: "#3fb950", phase: "#39c5cf" }
795
+ }),
796
+ "material-ocean": Object.freeze({
797
+ ...baseTheme,
798
+ textPrimary: "#a6accd",
799
+ textSecondary: "#8f93a2",
800
+ textMuted: "#4b526d",
801
+ brandPrimary: "#f78c6c",
802
+ brandAccent: "#c792ea",
803
+ accent: "#89ddff",
804
+ user: "#ffcb6b",
805
+ assistant: "#89ddff",
806
+ tool: "#82aaff",
807
+ success: "#c3e88d",
808
+ warn: "#ffcb6b",
809
+ error: "#f07178",
810
+ borderDefault: "#3b3f51",
811
+ borderSubtle: "#1f2233",
812
+ borderActive: "#89ddff",
813
+ brand: "#c792ea",
814
+ surface: "#0f111a",
815
+ surfaceRaised: "#1a1c25",
816
+ diffAddBg: "#17301f",
817
+ diffDelBg: "#331b21",
818
+ monitor: { fleet: "#89ddff", agents: "#c792ea", worktree: "#c3e88d", phase: "#82aaff" }
819
+ }),
820
+ nightfox: Object.freeze({
821
+ ...baseTheme,
822
+ textPrimary: "#cdcecf",
823
+ textSecondary: "#aeafb0",
824
+ textMuted: "#71839b",
825
+ brandPrimary: "#f4a261",
826
+ brandAccent: "#9d79d6",
827
+ accent: "#719cd6",
828
+ user: "#dbc074",
829
+ assistant: "#63cdcf",
830
+ tool: "#719cd6",
831
+ success: "#81b29a",
832
+ warn: "#dbc074",
833
+ error: "#c94f6d",
834
+ borderDefault: "#39506d",
835
+ borderSubtle: "#29394f",
836
+ borderActive: "#719cd6",
837
+ brand: "#9d79d6",
838
+ surface: "#192330",
839
+ surfaceRaised: "#212e3f",
840
+ diffAddBg: "#1d3025",
841
+ diffDelBg: "#33202a",
842
+ monitor: { fleet: "#719cd6", agents: "#9d79d6", worktree: "#81b29a", phase: "#63cdcf" }
843
+ }),
844
+ oxocarbon: Object.freeze({
845
+ ...baseTheme,
846
+ textPrimary: "#f2f4f8",
847
+ textSecondary: "#dde1e6",
848
+ textMuted: "#82868b",
849
+ brandPrimary: "#ff7eb6",
850
+ brandAccent: "#be95ff",
851
+ accent: "#78a9ff",
852
+ user: "#3ddbd9",
853
+ assistant: "#78a9ff",
854
+ tool: "#3ddbd9",
855
+ success: "#42be65",
856
+ warn: "#ff7eb6",
857
+ error: "#ee5396",
858
+ borderDefault: "#393939",
859
+ borderSubtle: "#262626",
860
+ borderActive: "#be95ff",
861
+ brand: "#be95ff",
862
+ surface: "#161616",
863
+ surfaceRaised: "#262626",
864
+ diffAddBg: "#17301f",
865
+ diffDelBg: "#33182a",
866
+ monitor: { fleet: "#78a9ff", agents: "#be95ff", worktree: "#42be65", phase: "#3ddbd9" }
867
+ }),
868
+ "catppuccin-macchiato": Object.freeze({
869
+ ...baseTheme,
870
+ textPrimary: "#cad3f5",
871
+ textSecondary: "#b8c0e0",
872
+ textMuted: "#6e738d",
873
+ brandPrimary: "#f5a97f",
874
+ brandAccent: "#f5bde6",
875
+ accent: "#8bd5ca",
876
+ user: "#eed49f",
877
+ assistant: "#8aadf4",
878
+ tool: "#8bd5ca",
879
+ success: "#a6da95",
880
+ warn: "#eed49f",
881
+ error: "#ed8796",
882
+ borderDefault: "#5b6078",
883
+ borderSubtle: "#363a4f",
884
+ borderActive: "#eed49f",
885
+ brand: "#c6a0f6",
886
+ surface: "#1e2030",
887
+ surfaceRaised: "#24273a",
888
+ diffAddBg: "#26402f",
889
+ diffDelBg: "#3f242c",
890
+ monitor: { fleet: "#8bd5ca", agents: "#c6a0f6", worktree: "#a6da95", phase: "#8aadf4" }
891
+ }),
892
+ "catppuccin-frappe": Object.freeze({
893
+ ...baseTheme,
894
+ textPrimary: "#c6d0f5",
895
+ textSecondary: "#b5bfe2",
896
+ textMuted: "#737994",
897
+ brandPrimary: "#ef9f76",
898
+ brandAccent: "#f4b8e4",
899
+ accent: "#81c8be",
900
+ user: "#e5c890",
901
+ assistant: "#8caaee",
902
+ tool: "#81c8be",
903
+ success: "#a6d189",
904
+ warn: "#e5c890",
905
+ error: "#e78284",
906
+ borderDefault: "#626880",
907
+ borderSubtle: "#414559",
908
+ borderActive: "#e5c890",
909
+ brand: "#ca9ee6",
910
+ surface: "#292c3c",
911
+ surfaceRaised: "#303446",
912
+ diffAddBg: "#2c4034",
913
+ diffDelBg: "#422a32",
914
+ monitor: { fleet: "#81c8be", agents: "#ca9ee6", worktree: "#a6d189", phase: "#8caaee" }
915
+ }),
916
+ "gruvbox-material": Object.freeze({
917
+ ...baseTheme,
918
+ textPrimary: "#d4be98",
919
+ textSecondary: "#c5b18d",
920
+ textMuted: "#928374",
921
+ brandPrimary: "#e78a4e",
922
+ brandAccent: "#d3869b",
923
+ accent: "#7daea3",
924
+ user: "#d8a657",
925
+ assistant: "#89b482",
926
+ tool: "#7daea3",
927
+ success: "#a9b665",
928
+ warn: "#d8a657",
929
+ error: "#ea6962",
930
+ borderDefault: "#45403d",
931
+ borderSubtle: "#3c3836",
932
+ borderActive: "#e78a4e",
933
+ brand: "#d3869b",
934
+ surface: "#282828",
935
+ surfaceRaised: "#32302f",
936
+ diffAddBg: "#26332a",
937
+ diffDelBg: "#3a2426",
938
+ monitor: { fleet: "#7daea3", agents: "#d3869b", worktree: "#a9b665", phase: "#89b482" }
939
+ }),
940
+ "tokyo-night-storm": Object.freeze({
941
+ ...baseTheme,
942
+ textPrimary: "#c0caf5",
943
+ textSecondary: "#a9b1d6",
944
+ textMuted: "#565f89",
945
+ brandPrimary: "#ff9e64",
946
+ brandAccent: "#bb9af7",
947
+ accent: "#7aa2f7",
948
+ user: "#e0af68",
949
+ assistant: "#7dcfff",
950
+ tool: "#73daca",
951
+ success: "#9ece6a",
952
+ warn: "#e0af68",
953
+ error: "#f7768e",
954
+ borderDefault: "#3b4261",
955
+ borderSubtle: "#292e42",
956
+ borderActive: "#7aa2f7",
957
+ brand: "#bb9af7",
958
+ surface: "#1f2335",
959
+ surfaceRaised: "#24283b",
960
+ diffAddBg: "#20372c",
961
+ diffDelBg: "#3b2331",
962
+ monitor: { fleet: "#7aa2f7", agents: "#bb9af7", worktree: "#9ece6a", phase: "#7dcfff" }
963
+ }),
964
+ "rose-pine-moon": Object.freeze({
965
+ ...baseTheme,
966
+ textPrimary: "#e0def4",
967
+ // Between Rosé Pine's `text` and `subtle` — `subtle` (#908caa) alone falls
968
+ // under WCAG AA once a comment is lifted onto a diff wash.
969
+ textSecondary: "#c4c1d8",
970
+ textMuted: "#6e6a86",
971
+ brandPrimary: "#f6c177",
972
+ brandAccent: "#ea9a97",
973
+ accent: "#9ccfd8",
974
+ user: "#f6c177",
975
+ assistant: "#c4a7e7",
976
+ tool: "#3e8fb0",
977
+ success: "#3e8fb0",
978
+ warn: "#f6c177",
979
+ error: "#eb6f92",
980
+ borderDefault: "#44415a",
981
+ borderSubtle: "#393552",
982
+ borderActive: "#ea9a97",
983
+ brand: "#c4a7e7",
984
+ surface: "#232136",
985
+ surfaceRaised: "#2a273f",
986
+ diffAddBg: "#22403e",
987
+ diffDelBg: "#3a2836",
988
+ monitor: { fleet: "#9ccfd8", agents: "#c4a7e7", worktree: "#3e8fb0", phase: "#9ccfd8" }
989
+ }),
990
+ zenburn: Object.freeze({
991
+ ...baseTheme,
992
+ textPrimary: "#dcdccc",
993
+ textSecondary: "#c0c0a8",
994
+ textMuted: "#8f8f7f",
995
+ brandPrimary: "#dfaf8f",
996
+ brandAccent: "#dc8cc3",
997
+ accent: "#8cd0d3",
998
+ user: "#f0dfaf",
999
+ assistant: "#93e0e3",
1000
+ tool: "#8cd0d3",
1001
+ success: "#7f9f7f",
1002
+ warn: "#f0dfaf",
1003
+ error: "#cc9393",
1004
+ borderDefault: "#5f5f5f",
1005
+ borderSubtle: "#4a4a4a",
1006
+ borderActive: "#f0dfaf",
1007
+ brand: "#dc8cc3",
1008
+ surface: "#3f3f3f",
1009
+ surfaceRaised: "#4f4f4f",
1010
+ // Zenburn's base (#3f3f3f) is the lightest of any preset here, so a wash
1011
+ // blended toward it leaves the muted green/red markers under 3:1. These
1012
+ // sit well below the base on purpose.
1013
+ diffAddBg: "#2b3a2a",
1014
+ diffDelBg: "#42292a",
1015
+ monitor: { fleet: "#8cd0d3", agents: "#dc8cc3", worktree: "#7f9f7f", phase: "#93e0e3" }
1016
+ }),
1017
+ palenight: Object.freeze({
1018
+ ...baseTheme,
1019
+ // Palenight's canonical fg (#a6accd) is dim enough that using it as the
1020
+ // PRIMARY leaves no headroom for a readable secondary; shift both up one
1021
+ // step and keep #a6accd as the secondary.
1022
+ textPrimary: "#babed8",
1023
+ textSecondary: "#a6accd",
1024
+ textMuted: "#676e95",
1025
+ brandPrimary: "#f78c6c",
1026
+ brandAccent: "#c792ea",
1027
+ accent: "#82aaff",
1028
+ user: "#ffcb6b",
1029
+ assistant: "#89ddff",
1030
+ tool: "#82aaff",
1031
+ success: "#c3e88d",
1032
+ warn: "#ffcb6b",
1033
+ error: "#f07178",
1034
+ borderDefault: "#4a4f6a",
1035
+ borderSubtle: "#3a3f58",
1036
+ borderActive: "#82aaff",
1037
+ brand: "#c792ea",
1038
+ surface: "#292d3e",
1039
+ surfaceRaised: "#34324a",
1040
+ diffAddBg: "#2b4033",
1041
+ diffDelBg: "#43293a",
1042
+ monitor: { fleet: "#82aaff", agents: "#c792ea", worktree: "#c3e88d", phase: "#89ddff" }
1043
+ }),
1044
+ horizon: Object.freeze({
1045
+ ...baseTheme,
1046
+ textPrimary: "#d5d8da",
1047
+ textSecondary: "#bbbdbf",
1048
+ textMuted: "#6c6f93",
1049
+ brandPrimary: "#f09383",
1050
+ brandAccent: "#ee64ac",
1051
+ accent: "#26bbd9",
1052
+ user: "#fab795",
1053
+ assistant: "#59e1e3",
1054
+ tool: "#26bbd9",
1055
+ success: "#29d398",
1056
+ warn: "#fab795",
1057
+ error: "#e95678",
1058
+ borderDefault: "#3d3f4c",
1059
+ borderSubtle: "#2e303e",
1060
+ borderActive: "#e95678",
1061
+ brand: "#ee64ac",
1062
+ surface: "#1c1e26",
1063
+ surfaceRaised: "#232530",
1064
+ diffAddBg: "#16362e",
1065
+ diffDelBg: "#3a1f2a",
1066
+ monitor: { fleet: "#26bbd9", agents: "#ee64ac", worktree: "#29d398", phase: "#59e1e3" }
1067
+ }),
1068
+ sonokai: Object.freeze({
1069
+ ...baseTheme,
1070
+ textPrimary: "#e3e1e4",
1071
+ textSecondary: "#c9c6cb",
1072
+ textMuted: "#848089",
1073
+ brandPrimary: "#ef9062",
1074
+ brandAccent: "#ab9df2",
1075
+ accent: "#7accd7",
1076
+ user: "#e5c463",
1077
+ assistant: "#7accd7",
1078
+ tool: "#9ecd6f",
1079
+ success: "#9ecd6f",
1080
+ warn: "#e5c463",
1081
+ error: "#f85e84",
1082
+ borderDefault: "#4b484d",
1083
+ borderSubtle: "#3b383e",
1084
+ borderActive: "#ef9062",
1085
+ brand: "#ab9df2",
1086
+ surface: "#2d2a2e",
1087
+ surfaceRaised: "#37343a",
1088
+ diffAddBg: "#2c3a2b",
1089
+ diffDelBg: "#43262f",
1090
+ monitor: { fleet: "#7accd7", agents: "#ab9df2", worktree: "#9ecd6f", phase: "#7accd7" }
1091
+ }),
1092
+ "edge-dark": Object.freeze({
1093
+ ...baseTheme,
1094
+ textPrimary: "#c5cdd9",
1095
+ textSecondary: "#adb6c2",
1096
+ textMuted: "#7f8490",
1097
+ brandPrimary: "#deb974",
1098
+ brandAccent: "#d38aea",
1099
+ accent: "#6cb6eb",
1100
+ user: "#deb974",
1101
+ assistant: "#5dbbc1",
1102
+ tool: "#6cb6eb",
1103
+ success: "#a0c980",
1104
+ warn: "#deb974",
1105
+ error: "#ec7279",
1106
+ borderDefault: "#464957",
1107
+ borderSubtle: "#363a4d",
1108
+ borderActive: "#6cb6eb",
1109
+ brand: "#d38aea",
1110
+ surface: "#2b2d3a",
1111
+ surfaceRaised: "#333648",
1112
+ diffAddBg: "#29392c",
1113
+ diffDelBg: "#3d2830",
1114
+ monitor: { fleet: "#6cb6eb", agents: "#d38aea", worktree: "#a0c980", phase: "#5dbbc1" }
1115
+ }),
1116
+ moonfly: Object.freeze({
1117
+ ...baseTheme,
1118
+ textPrimary: "#bdbdbd",
1119
+ textSecondary: "#a8a8a8",
1120
+ textMuted: "#767676",
1121
+ brandPrimary: "#de935f",
1122
+ brandAccent: "#cf87e8",
1123
+ accent: "#80a0ff",
1124
+ user: "#e3c78a",
1125
+ assistant: "#79dac8",
1126
+ tool: "#80a0ff",
1127
+ success: "#8cc85f",
1128
+ warn: "#e3c78a",
1129
+ error: "#ff5454",
1130
+ borderDefault: "#3a3a3a",
1131
+ borderSubtle: "#262626",
1132
+ borderActive: "#80a0ff",
1133
+ brand: "#cf87e8",
1134
+ surface: "#080808",
1135
+ surfaceRaised: "#1c1c1c",
1136
+ diffAddBg: "#10301d",
1137
+ diffDelBg: "#331414",
1138
+ monitor: { fleet: "#80a0ff", agents: "#cf87e8", worktree: "#8cc85f", phase: "#79dac8" }
1139
+ }),
1140
+ melange: Object.freeze({
1141
+ ...baseTheme,
1142
+ textPrimary: "#ece1d7",
1143
+ textSecondary: "#c1a78e",
1144
+ textMuted: "#867462",
1145
+ brandPrimary: "#e49b5d",
1146
+ brandAccent: "#cf9bc2",
1147
+ accent: "#a3a9ce",
1148
+ user: "#ebc06d",
1149
+ assistant: "#89b3b6",
1150
+ tool: "#a3a9ce",
1151
+ success: "#85b695",
1152
+ warn: "#ebc06d",
1153
+ error: "#d47766",
1154
+ borderDefault: "#4d4640",
1155
+ borderSubtle: "#3a352f",
1156
+ borderActive: "#e49b5d",
1157
+ brand: "#cf9bc2",
1158
+ surface: "#292522",
1159
+ surfaceRaised: "#34302c",
1160
+ diffAddBg: "#2f3a30",
1161
+ diffDelBg: "#3f2b28",
1162
+ monitor: { fleet: "#a3a9ce", agents: "#cf9bc2", worktree: "#85b695", phase: "#89b3b6" }
1163
+ }),
1164
+ poimandres: Object.freeze({
1165
+ ...baseTheme,
1166
+ // Same shift as palenight — #a6accd becomes the secondary so the lifted
1167
+ // on-wash comment clears AA.
1168
+ textPrimary: "#c4cbe0",
1169
+ textSecondary: "#a6accd",
1170
+ textMuted: "#506477",
1171
+ brandPrimary: "#f087bd",
1172
+ brandAccent: "#a684ff",
1173
+ accent: "#5de4c7",
1174
+ user: "#fffac2",
1175
+ assistant: "#89ddff",
1176
+ tool: "#5de4c7",
1177
+ success: "#5fb3a1",
1178
+ warn: "#fffac2",
1179
+ error: "#d0679d",
1180
+ borderDefault: "#3b4056",
1181
+ borderSubtle: "#252b37",
1182
+ borderActive: "#5de4c7",
1183
+ brand: "#a684ff",
1184
+ surface: "#1b1e28",
1185
+ surfaceRaised: "#252b37",
1186
+ diffAddBg: "#14352f",
1187
+ diffDelBg: "#35202c",
1188
+ monitor: { fleet: "#5de4c7", agents: "#a684ff", worktree: "#5fb3a1", phase: "#89ddff" }
1189
+ }),
1190
+ "vitesse-dark": Object.freeze({
1191
+ ...baseTheme,
1192
+ textPrimary: "#dbd7ca",
1193
+ textSecondary: "#bfbaaa",
1194
+ textMuted: "#758575",
1195
+ brandPrimary: "#dfab5c",
1196
+ brandAccent: "#d3869b",
1197
+ accent: "#6394bf",
1198
+ user: "#e6cc77",
1199
+ assistant: "#5eaab5",
1200
+ tool: "#6394bf",
1201
+ success: "#4d9375",
1202
+ warn: "#e6cc77",
1203
+ error: "#cb7676",
1204
+ borderDefault: "#333333",
1205
+ borderSubtle: "#222222",
1206
+ borderActive: "#dfab5c",
1207
+ brand: "#d3869b",
1208
+ surface: "#121212",
1209
+ surfaceRaised: "#1c1c1c",
1210
+ diffAddBg: "#16301f",
1211
+ diffDelBg: "#331d1d",
1212
+ monitor: { fleet: "#6394bf", agents: "#d3869b", worktree: "#4d9375", phase: "#5eaab5" }
1213
+ }),
1214
+ aura: Object.freeze({
1215
+ ...baseTheme,
1216
+ textPrimary: "#edecee",
1217
+ textSecondary: "#cdccce",
1218
+ textMuted: "#6d6d6d",
1219
+ brandPrimary: "#ffca85",
1220
+ brandAccent: "#f694ff",
1221
+ accent: "#82e2ff",
1222
+ user: "#ffca85",
1223
+ assistant: "#82e2ff",
1224
+ tool: "#a277ff",
1225
+ success: "#61ffca",
1226
+ warn: "#ffca85",
1227
+ error: "#ff6767",
1228
+ borderDefault: "#3b334b",
1229
+ borderSubtle: "#262433",
1230
+ borderActive: "#a277ff",
1231
+ brand: "#f694ff",
1232
+ surface: "#15141b",
1233
+ surfaceRaised: "#1c1b22",
1234
+ diffAddBg: "#14382c",
1235
+ diffDelBg: "#351d23",
1236
+ monitor: { fleet: "#82e2ff", agents: "#a277ff", worktree: "#61ffca", phase: "#f694ff" }
1237
+ }),
1238
+ "dark-plus": Object.freeze({
1239
+ ...baseTheme,
1240
+ textPrimary: "#d4d4d4",
1241
+ textSecondary: "#cccccc",
1242
+ textMuted: "#858585",
1243
+ brandPrimary: "#ce9178",
1244
+ brandAccent: "#c586c0",
1245
+ accent: "#569cd6",
1246
+ user: "#dcdcaa",
1247
+ assistant: "#9cdcfe",
1248
+ tool: "#4ec9b0",
1249
+ success: "#89d185",
1250
+ warn: "#cca700",
1251
+ error: "#f44747",
1252
+ borderDefault: "#3c3c3c",
1253
+ borderSubtle: "#2d2d30",
1254
+ borderActive: "#569cd6",
1255
+ brand: "#c586c0",
1256
+ surface: "#1e1e1e",
1257
+ surfaceRaised: "#252526",
1258
+ diffAddBg: "#16351f",
1259
+ diffDelBg: "#3a1d20",
1260
+ monitor: { fleet: "#569cd6", agents: "#c586c0", worktree: "#89d185", phase: "#4ec9b0" },
1261
+ // The one preset that genuinely disagrees with the derived defaults:
1262
+ // VS Code colors strings orange and comments green, the inverse of the
1263
+ // usual green-string / grey-comment convention the defaults assume.
1264
+ // `commentOnWash` is a lifted green rather than the default
1265
+ // `textSecondary`, so the comment stays green on a diff wash instead of
1266
+ // switching to grey mid-file.
1267
+ syntax: {
1268
+ string: "#ce9178",
1269
+ comment: "#6a9955",
1270
+ commentOnWash: "#9fc98b"
1271
+ }
730
1272
  })
731
1273
  });
732
1274
  var THEME_OPTIONS = [
@@ -796,6 +1338,106 @@ var THEME_OPTIONS = [
796
1338
  id: "synthwave",
797
1339
  name: "Synthwave '84",
798
1340
  description: "Hot pink + neon cyan on deep purple \u2014 80s retro glow"
1341
+ },
1342
+ {
1343
+ id: "github-dark",
1344
+ name: "GitHub Dark",
1345
+ description: "GitHub's default dark \u2014 crisp blue on near-black"
1346
+ },
1347
+ {
1348
+ id: "material-ocean",
1349
+ name: "Material Ocean",
1350
+ description: "Deepest Material variant \u2014 ink blue with pastel accents"
1351
+ },
1352
+ {
1353
+ id: "nightfox",
1354
+ name: "Nightfox",
1355
+ description: "Balanced slate blue with muted sage and rose"
1356
+ },
1357
+ {
1358
+ id: "oxocarbon",
1359
+ name: "Oxocarbon",
1360
+ description: "IBM Carbon-derived \u2014 neutral greys, electric blue & pink"
1361
+ },
1362
+ {
1363
+ id: "catppuccin-macchiato",
1364
+ name: "Catppuccin Macchiato",
1365
+ description: "Warmer, one shade lighter than Mocha"
1366
+ },
1367
+ {
1368
+ id: "catppuccin-frappe",
1369
+ name: "Catppuccin Frapp\xE9",
1370
+ description: "The lightest Catppuccin dark \u2014 gentle midday contrast"
1371
+ },
1372
+ {
1373
+ id: "gruvbox-material",
1374
+ name: "Gruvbox Material",
1375
+ description: "Softened Gruvbox \u2014 same warmth, lower eye strain"
1376
+ },
1377
+ {
1378
+ id: "tokyo-night-storm",
1379
+ name: "Tokyo Night Storm",
1380
+ description: "Tokyo Night on a lifted blue-grey base"
1381
+ },
1382
+ {
1383
+ id: "rose-pine-moon",
1384
+ name: "Ros\xE9 Pine Moon",
1385
+ description: "Ros\xE9 Pine at dusk \u2014 deeper base, same soft accents"
1386
+ },
1387
+ {
1388
+ id: "zenburn",
1389
+ name: "Zenburn",
1390
+ description: "The classic low-contrast grey \u2014 desaturated and calm"
1391
+ },
1392
+ {
1393
+ id: "palenight",
1394
+ name: "Palenight",
1395
+ description: "Material Palenight \u2014 indigo base, candy accents"
1396
+ },
1397
+ {
1398
+ id: "horizon",
1399
+ name: "Horizon",
1400
+ description: "Warm coral and mint on charcoal \u2014 sunset gradient"
1401
+ },
1402
+ {
1403
+ id: "sonokai",
1404
+ name: "Sonokai",
1405
+ description: "Monokai Pro descendant \u2014 punchy on warm graphite"
1406
+ },
1407
+ {
1408
+ id: "edge-dark",
1409
+ name: "Edge Dark",
1410
+ description: "Clean, evenly-weighted palette on desaturated navy"
1411
+ },
1412
+ {
1413
+ id: "moonfly",
1414
+ name: "Moonfly",
1415
+ description: "Near-black base with high-chroma accents \u2014 maximum contrast"
1416
+ },
1417
+ {
1418
+ id: "melange",
1419
+ name: "Melange",
1420
+ description: "Warm sepia and clay \u2014 the least blue dark theme here"
1421
+ },
1422
+ {
1423
+ id: "poimandres",
1424
+ name: "Poimandres",
1425
+ description: "Teal-forward, low-saturation \u2014 mint on deep indigo"
1426
+ },
1427
+ {
1428
+ id: "vitesse-dark",
1429
+ name: "Vitesse Dark",
1430
+ description: "Anthony Fu's minimal palette \u2014 muted, print-like"
1431
+ },
1432
+ {
1433
+ id: "aura",
1434
+ name: "Aura Dark",
1435
+ description: "Vivid purple and spring green on near-black violet"
1436
+ },
1437
+ {
1438
+ id: "dark-plus",
1439
+ name: "VS Code Dark+",
1440
+ description: "Visual Studio Code's default \u2014 familiar blue/orange/teal"
799
1441
  }
800
1442
  ];
801
1443
 
@@ -10649,20 +11291,20 @@ import React2 from "react";
10649
11291
 
10650
11292
  // src/highlight.ts
10651
11293
  var C = {
10652
- keyword: "magenta",
10653
- string: "green",
10654
- comment: "gray",
10655
- number: "yellow",
10656
- literal: "yellow",
11294
+ keyword: "syntax.keyword",
11295
+ string: "syntax.string",
11296
+ comment: "syntax.comment",
11297
+ number: "syntax.number",
11298
+ literal: "syntax.literal",
10657
11299
  // true/false/null
10658
- property: "cyan",
10659
- variable: "cyan",
10660
- command: "cyan",
10661
- flag: "yellow",
10662
- decorator: "magenta",
10663
- diffAdd: "green",
10664
- diffDel: "red",
10665
- diffMeta: "cyan"
11300
+ property: "syntax.property",
11301
+ variable: "syntax.variable",
11302
+ command: "syntax.command",
11303
+ flag: "syntax.flag",
11304
+ decorator: "syntax.decorator",
11305
+ diffAdd: "syntax.diffAdd",
11306
+ diffDel: "syntax.diffDel",
11307
+ diffMeta: "syntax.diffMeta"
10666
11308
  };
10667
11309
  var TS_KEYWORDS = /* @__PURE__ */ new Set([
10668
11310
  "const",
@@ -13407,8 +14049,8 @@ function formatDiffStats(added, removed) {
13407
14049
  function applyWashTokens(tokens, onWash) {
13408
14050
  if (!onWash) return tokens;
13409
14051
  return tokens.map((t) => {
13410
- if (t.color !== "gray") return t;
13411
- return { ...t, color: "grayBright", dim: false };
14052
+ if (t.color !== "syntax.comment") return t;
14053
+ return { ...t, color: "syntax.commentOnWash", dim: false };
13412
14054
  });
13413
14055
  }
13414
14056
  function renderTokens(tokens, onWash = false) {
@@ -20092,6 +20734,9 @@ function SendModePicker({
20092
20734
  ] });
20093
20735
  }
20094
20736
 
20737
+ // src/components/settings-picker.tsx
20738
+ import { useEffect as useEffect24 } from "react";
20739
+
20095
20740
  // src/components/settings-picker-filter.ts
20096
20741
  function fuzzyMatch(haystack, needle) {
20097
20742
  const lower = haystack.toLowerCase();
@@ -20988,27 +21633,30 @@ function renderPickerRow(row, fieldIdx, selected, filterActive, highlightSegment
20988
21633
  ] }) : /* @__PURE__ */ jsx73(Text, { bold: true, children: labelStr.padEnd(26) }),
20989
21634
  /* @__PURE__ */ jsx73(Text, { color: "cyan", children: String(row.value ?? "").padEnd(12) }),
20990
21635
  /* @__PURE__ */ jsx73(Text, { dimColor: true, children: row.detail ?? "" })
20991
- ] }, `row-${row.label ?? fieldIdx}`);
21636
+ ] }, `row-${fieldIdx}`);
20992
21637
  }
20993
- function buildVisibleSectionHeaders(rows, fieldRowIndex, windowStart, windowEnd) {
20994
- const sectionFields = [];
20995
- let curHeader = -1;
20996
- for (let i = 0; i < rows.length; i++) {
20997
- if (rows[i]?.section) curHeader = i;
20998
- else if (curHeader >= 0) {
20999
- const fieldIdx = fieldRowIndex.indexOf(i);
21000
- if (fieldIdx === -1) continue;
21001
- const entry = sectionFields.find((s2) => s2.headerIdx === curHeader);
21002
- if (entry) {
21003
- entry.fieldEnd = fieldIdx + 1;
21004
- } else {
21005
- sectionFields.push({ headerIdx: curHeader, fieldStart: fieldIdx, fieldEnd: fieldIdx + 1 });
21006
- }
21007
- }
21638
+ function deriveSettingsSectionFieldStarts(fieldRowIndex) {
21639
+ const starts = [];
21640
+ for (let fieldIdx = 0; fieldIdx < fieldRowIndex.length; fieldIdx++) {
21641
+ const rowIdx = fieldRowIndex[fieldIdx] ?? 0;
21642
+ const previousRowIdx = fieldIdx > 0 ? fieldRowIndex[fieldIdx - 1] ?? 0 : -1;
21643
+ if (fieldIdx === 0 || rowIdx - previousRowIdx > 1) starts.push(fieldIdx);
21008
21644
  }
21009
- return new Set(
21010
- sectionFields.filter((section) => section.fieldStart < windowEnd && section.fieldEnd > windowStart).map((section) => section.headerIdx)
21011
- );
21645
+ return starts;
21646
+ }
21647
+ function buildVisibleSectionHeaders(rows, fieldRowIndex, windowStart, windowEnd) {
21648
+ const sectionStarts = deriveSettingsSectionFieldStarts(fieldRowIndex);
21649
+ const visibleHeaders = /* @__PURE__ */ new Set();
21650
+ for (let i = 0; i < sectionStarts.length; i++) {
21651
+ const fieldStart = sectionStarts[i] ?? 0;
21652
+ const fieldEnd = sectionStarts[i + 1] ?? fieldRowIndex.length;
21653
+ if (fieldStart >= windowEnd || fieldEnd <= windowStart) continue;
21654
+ const firstFieldRow = fieldRowIndex[fieldStart];
21655
+ if (firstFieldRow === void 0) continue;
21656
+ const headerIdx = firstFieldRow - 1;
21657
+ if (rows[headerIdx]?.section) visibleHeaders.add(headerIdx);
21658
+ }
21659
+ return visibleHeaders;
21012
21660
  }
21013
21661
  function SettingsPickerRowList({
21014
21662
  rows,
@@ -21018,10 +21666,12 @@ function SettingsPickerRowList({
21018
21666
  rankedResults,
21019
21667
  highlightSegments,
21020
21668
  windowStart,
21021
- windowEnd
21669
+ windowEnd,
21670
+ filterWindowStart,
21671
+ filterWindowEnd
21022
21672
  }) {
21023
21673
  if (filterActive) {
21024
- return /* @__PURE__ */ jsx73(Fragment27, { children: rankedResults.map((result) => {
21674
+ return /* @__PURE__ */ jsx73(Fragment27, { children: rankedResults.slice(filterWindowStart, filterWindowEnd).map((result) => {
21025
21675
  const fieldIdx = result.chord.field;
21026
21676
  const rowIdx = fieldRowIndex[fieldIdx] ?? -1;
21027
21677
  const row = rows[rowIdx];
@@ -21100,7 +21750,9 @@ function SettingsPicker({
21100
21750
  nextStepsTool,
21101
21751
  readSymbols,
21102
21752
  panelPositions,
21103
- hint
21753
+ inputHeight,
21754
+ hint,
21755
+ onLayoutComputed
21104
21756
  }) {
21105
21757
  const boolVal = (v) => v ? "on" : "off";
21106
21758
  const rows = [
@@ -21373,50 +22025,134 @@ function SettingsPicker({
21373
22025
  for (let i = 0; i < rows.length; i++) {
21374
22026
  if (!rows[i]?.section) fieldRowIndex.push(i);
21375
22027
  }
22028
+ useEffect24(() => {
22029
+ onLayoutComputed?.({ rows, fieldRowIndex });
22030
+ });
21376
22031
  const { filterActive, rankedResults, filteredFieldIndices, highlightSegments } = buildSettingsFilterState(filter, SETTINGS_PICKER_JUMP_CHORDS);
21377
22032
  const { stdout } = useStdout();
21378
22033
  const termRows = stdout?.rows ?? 24;
21379
- const VISIBLE_FIELDS = Math.max(8, termRows - 26);
22034
+ const termCols = stdout?.columns ?? 80;
22035
+ const contentWidth = Math.max(10, termCols - 4);
22036
+ const fieldLineCount = (fieldIdx) => {
22037
+ const rowIdx = fieldRowIndex[fieldIdx];
22038
+ const row = rowIdx === void 0 ? void 0 : rows[rowIdx];
22039
+ const printableWidth = 2 + Math.max(26, (row?.label ?? "").length) + Math.max(12, String(row?.value ?? "").length) + (row?.detail ?? "").length;
22040
+ return Math.max(1, Math.ceil(printableWidth / contentWidth));
22041
+ };
22042
+ const INPUT_ROWS = inputHeight ?? 3;
22043
+ const bottomChromeRows = statuslineMode === "detailed" ? 5 : 2;
22044
+ const BORDER_ROWS = 2;
22045
+ const BASE_CHROME_ROWS = contentWidth < 64 ? 4 : 3;
22046
+ const pickerHeight = Math.max(8, termRows - INPUT_ROWS - bottomChromeRows);
22047
+ const innerHeight = pickerHeight - BORDER_ROWS;
21380
22048
  const totalFields = fieldRowIndex.length;
21381
- const windowStart = totalFields <= VISIBLE_FIELDS ? 0 : Math.max(0, Math.min(field - Math.floor(VISIBLE_FIELDS / 2), totalFields - VISIBLE_FIELDS));
22049
+ const sectionFieldStarts = deriveSettingsSectionFieldStarts(fieldRowIndex);
22050
+ const countWindowLines = (start, end) => {
22051
+ let lines = 0;
22052
+ for (let fieldIdx = start; fieldIdx < end; fieldIdx++) {
22053
+ lines += fieldLineCount(fieldIdx);
22054
+ }
22055
+ for (const secStart of sectionFieldStarts) {
22056
+ if (secStart >= start && secStart < end) lines++;
22057
+ }
22058
+ if (start > 0 && !sectionFieldStarts.includes(start)) lines++;
22059
+ return lines;
22060
+ };
22061
+ const windowStartFor = (n) => totalFields <= n ? 0 : Math.max(0, Math.min(field - Math.floor(n / 2), totalFields - n));
22062
+ const windowFits = (fieldCount) => {
22063
+ const start = windowStartFor(fieldCount);
22064
+ const end = Math.min(start + fieldCount, totalFields);
22065
+ const scrollIndicatorRows = (start > 0 ? 1 : 0) + (end < totalFields ? 1 : 0);
22066
+ const chromeRows = BASE_CHROME_ROWS + scrollIndicatorRows + (hint ? 1 : 0);
22067
+ return countWindowLines(start, end) + chromeRows <= innerHeight;
22068
+ };
22069
+ let lo = 3;
22070
+ let hi = totalFields;
22071
+ let VISIBLE_FIELDS = Math.min(3, totalFields);
22072
+ while (lo <= hi) {
22073
+ const mid = Math.floor((lo + hi) / 2);
22074
+ if (windowFits(mid)) {
22075
+ VISIBLE_FIELDS = mid;
22076
+ lo = mid + 1;
22077
+ } else {
22078
+ hi = mid - 1;
22079
+ }
22080
+ }
22081
+ const windowStart = windowStartFor(VISIBLE_FIELDS);
21382
22082
  const windowEnd = Math.min(windowStart + VISIBLE_FIELDS, totalFields);
21383
22083
  const hasAbove = windowStart > 0;
21384
22084
  const hasBelow = windowEnd < totalFields;
21385
- return /* @__PURE__ */ jsxs71(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
21386
- /* @__PURE__ */ jsx74(Text, { color: "cyan", bold: true, children: "\u2501\u2501 Settings \u2501\u2501" }),
21387
- filterActive ? /* @__PURE__ */ jsx74(
21388
- Text,
21389
- {
21390
- color: "yellow",
21391
- bold: true,
21392
- children: `Filter: ${filter} (${filteredFieldIndices.length} match${filteredFieldIndices.length === 1 ? "" : "es"})`
21393
- }
21394
- ) : /* @__PURE__ */ jsx74(Text, { dimColor: true, children: "\u2191/\u2193 field \xB7 \u2190/\u2192 change + autosave \xB7 `/` to search \xB7 F5 to close" }),
21395
- hasAbove && !filterActive ? /* @__PURE__ */ jsx74(Text, { dimColor: true, children: ` \u2191 ${windowStart} field${windowStart === 1 ? "" : "s"} above` }) : null,
21396
- filterActive && filteredFieldIndices.length === 0 ? /* @__PURE__ */ jsx74(Text, { dimColor: true, italic: true, children: "No matching settings rows." }) : null,
21397
- /* @__PURE__ */ jsx74(
21398
- SettingsPickerRowList,
21399
- {
21400
- rows,
21401
- field,
21402
- fieldRowIndex,
21403
- filterActive,
21404
- rankedResults,
21405
- highlightSegments,
21406
- windowStart,
21407
- windowEnd
21408
- }
21409
- ),
21410
- hasBelow && !filterActive ? /* @__PURE__ */ jsx74(
21411
- Text,
21412
- {
21413
- dimColor: true,
21414
- children: ` \u2193 ${totalFields - windowEnd} field${totalFields - windowEnd === 1 ? "" : "s"} below`
21415
- }
21416
- ) : null,
21417
- /* @__PURE__ */ jsx74(Text, { dimColor: true, children: configScope === "project" ? "Persisted to <project>/.wrongstack/config.json" : `Persisted to ${profileConfigPath}` }),
21418
- hint ? /* @__PURE__ */ jsx74(Text, { color: "yellow", children: hint }) : null
21419
- ] });
22085
+ const maxFilteredFieldLines = Math.max(
22086
+ 1,
22087
+ ...rankedResults.map((result) => fieldLineCount(result.chord.field))
22088
+ );
22089
+ const FILTER_CHROME_ROWS = BASE_CHROME_ROWS + 2;
22090
+ const FILTER_VISIBLE_FIELDS = Math.max(
22091
+ 3,
22092
+ Math.floor((innerHeight - FILTER_CHROME_ROWS - (hint ? 1 : 0)) / maxFilteredFieldLines)
22093
+ );
22094
+ const filterMatchCount = rankedResults.length;
22095
+ const filterSelectedIdx = filterActive ? rankedResults.findIndex((r) => r.chord.field === field) : -1;
22096
+ const filterWindowStart = !filterActive || filterMatchCount <= FILTER_VISIBLE_FIELDS || filterSelectedIdx < 0 ? 0 : Math.max(
22097
+ 0,
22098
+ Math.min(
22099
+ filterSelectedIdx - Math.floor(FILTER_VISIBLE_FIELDS / 2),
22100
+ filterMatchCount - FILTER_VISIBLE_FIELDS
22101
+ )
22102
+ );
22103
+ const filterWindowEnd = Math.min(filterWindowStart + FILTER_VISIBLE_FIELDS, filterMatchCount);
22104
+ const filterHasAbove = filterActive && filterWindowStart > 0;
22105
+ const filterHasBelow = filterActive && filterWindowEnd < filterMatchCount;
22106
+ return /* @__PURE__ */ jsxs71(
22107
+ Box,
22108
+ {
22109
+ flexDirection: "column",
22110
+ borderStyle: "round",
22111
+ borderColor: "yellow",
22112
+ paddingX: 1,
22113
+ height: pickerHeight,
22114
+ overflowY: "hidden",
22115
+ children: [
22116
+ /* @__PURE__ */ jsx74(Text, { color: "cyan", bold: true, children: "\u2501\u2501 Settings \u2501\u2501" }),
22117
+ filterActive ? /* @__PURE__ */ jsx74(
22118
+ Text,
22119
+ {
22120
+ color: "yellow",
22121
+ bold: true,
22122
+ children: `Filter: ${filter} (${filteredFieldIndices.length} match${filteredFieldIndices.length === 1 ? "" : "es"})`
22123
+ }
22124
+ ) : /* @__PURE__ */ jsx74(Text, { dimColor: true, children: "\u2191/\u2193 field \xB7 \u2190/\u2192 change + autosave \xB7 `/` to search \xB7 F5 to close" }),
22125
+ filterActive && filterHasAbove ? /* @__PURE__ */ jsx74(Text, { dimColor: true, children: ` \u2191 ${filterWindowStart} match${filterWindowStart === 1 ? "" : "es"} above` }) : null,
22126
+ !filterActive && hasAbove ? /* @__PURE__ */ jsx74(Text, { dimColor: true, children: ` \u2191 ${windowStart} field${windowStart === 1 ? "" : "s"} above` }) : null,
22127
+ filterActive && filteredFieldIndices.length === 0 ? /* @__PURE__ */ jsx74(Text, { dimColor: true, italic: true, children: "No matching settings rows." }) : null,
22128
+ /* @__PURE__ */ jsx74(
22129
+ SettingsPickerRowList,
22130
+ {
22131
+ rows,
22132
+ field,
22133
+ fieldRowIndex,
22134
+ filterActive,
22135
+ rankedResults,
22136
+ highlightSegments,
22137
+ windowStart,
22138
+ windowEnd,
22139
+ filterWindowStart,
22140
+ filterWindowEnd
22141
+ }
22142
+ ),
22143
+ filterActive && filterHasBelow ? /* @__PURE__ */ jsx74(Text, { dimColor: true, children: ` \u2193 ${filterMatchCount - filterWindowEnd} match${filterMatchCount - filterWindowEnd === 1 ? "" : "es"} below` }) : null,
22144
+ !filterActive && hasBelow ? /* @__PURE__ */ jsx74(
22145
+ Text,
22146
+ {
22147
+ dimColor: true,
22148
+ children: ` \u2193 ${totalFields - windowEnd} field${totalFields - windowEnd === 1 ? "" : "s"} below`
22149
+ }
22150
+ ) : null,
22151
+ /* @__PURE__ */ jsx74(Text, { dimColor: true, children: configScope === "project" ? "Persisted to <project>/.wrongstack/config.json" : `Persisted to ${profileConfigPath}` }),
22152
+ hint ? /* @__PURE__ */ jsx74(Text, { color: "yellow", children: hint }) : null
22153
+ ]
22154
+ }
22155
+ );
21420
22156
  }
21421
22157
 
21422
22158
  // src/components/shadow-panel.tsx
@@ -23557,7 +24293,7 @@ function ThemePicker({
23557
24293
  const isSelected = i === selected;
23558
24294
  return /* @__PURE__ */ jsxs80(Text, { inverse: isSelected, ...isSelected ? { color: "cyan" } : {}, children: [
23559
24295
  isSelected ? "\u203A " : " ",
23560
- /* @__PURE__ */ jsx83(Text, { bold: true, children: opt.name.padEnd(18) }),
24296
+ /* @__PURE__ */ jsx83(Text, { bold: true, children: opt.name.padEnd(21) }),
23561
24297
  /* @__PURE__ */ jsx83(Text, { dimColor: true, children: opt.description }),
23562
24298
  isActive ? /* @__PURE__ */ jsx83(Text, { color: "green", children: " [active]" }) : null
23563
24299
  ] }, opt.id);
@@ -23770,10 +24506,10 @@ function TopicCheckPanel({ prompt }) {
23770
24506
 
23771
24507
  // src/hooks/use-sidebar-panel-data.ts
23772
24508
  import { getProcessRegistry as getProcessRegistry3 } from "@wrongstack/tools";
23773
- import { useEffect as useEffect24, useState as useState24 } from "react";
24509
+ import { useEffect as useEffect25, useState as useState24 } from "react";
23774
24510
  function useSidebarProcessList(enabled = true) {
23775
24511
  const [data, setData] = useState24({ activeCount: 0, totalCount: 0, processes: [] });
23776
- useEffect24(() => {
24512
+ useEffect25(() => {
23777
24513
  if (!enabled) return;
23778
24514
  const read = () => {
23779
24515
  const registry = getProcessRegistry3();
@@ -23794,7 +24530,7 @@ function useSidebarProcessList(enabled = true) {
23794
24530
  }
23795
24531
  function useSidebarConnections(projectRoot, enabled = true) {
23796
24532
  const [connections, setConnections] = useState24([]);
23797
- useEffect24(() => {
24533
+ useEffect25(() => {
23798
24534
  if (!enabled) return;
23799
24535
  let cancelled = false;
23800
24536
  const poll = async () => {
@@ -23823,7 +24559,7 @@ function useSidebarConnections(projectRoot, enabled = true) {
23823
24559
  }
23824
24560
  function useSidebarKanban(projectRoot, enabled = true) {
23825
24561
  const [data, setData] = useState24({ columns: [], totalActive: 0, activeCardTitles: [] });
23826
- useEffect24(() => {
24562
+ useEffect25(() => {
23827
24563
  if (!enabled) return;
23828
24564
  let cancelled = false;
23829
24565
  const poll = async () => {
@@ -24156,6 +24892,7 @@ function AppView({ host, runtime }) {
24156
24892
  nextStepsTool: state.settingsPicker.nextStepsTool,
24157
24893
  readSymbols: state.settingsPicker.readSymbols,
24158
24894
  panelPositions: state.settingsPicker.panelPositions,
24895
+ inputHeight,
24159
24896
  filter: state.settingsPicker.filter,
24160
24897
  hint: state.settingsPicker.hint
24161
24898
  }
@@ -25994,7 +26731,7 @@ function useAppPickerKeys({
25994
26731
 
25995
26732
  // src/hooks/use-app-runtime-refs.ts
25996
26733
  import { InputBuilder } from "@wrongstack/core/agent";
25997
- import { useEffect as useEffect25, useRef as useRef10 } from "react";
26734
+ import { useEffect as useEffect26, useRef as useRef10 } from "react";
25998
26735
 
25999
26736
  // src/token-previews.ts
26000
26737
  var TOKEN_PREVIEWS_MAX_ENTRIES = 64;
@@ -26134,7 +26871,7 @@ function useAppRuntimeRefs(attachments, state) {
26134
26871
  builderRef.current = new InputBuilder({ store: attachments });
26135
26872
  }
26136
26873
  const activeCtrlRef = useRef10(null);
26137
- useEffect25(
26874
+ useEffect26(
26138
26875
  () => () => {
26139
26876
  activeCtrlRef.current?.abort("TUI unmounted");
26140
26877
  activeCtrlRef.current = null;
@@ -26192,7 +26929,7 @@ function useAppRuntimeRefs(attachments, state) {
26192
26929
  }
26193
26930
 
26194
26931
  // src/hooks/use-app-session-state.ts
26195
- import { useEffect as useEffect26, useMemo as useMemo9, useReducer } from "react";
26932
+ import { useEffect as useEffect27, useMemo as useMemo9, useReducer } from "react";
26196
26933
 
26197
26934
  // src/checkpoint-retention.ts
26198
26935
  var TUI_CHECKPOINTS_MAX_ENTRIES = 200;
@@ -30482,7 +31219,7 @@ function useAppSessionState(options) {
30482
31219
  }),
30483
31220
  [options.sessionsDir]
30484
31221
  );
30485
- useEffect26(() => {
31222
+ useEffect27(() => {
30486
31223
  void layoutStore.load();
30487
31224
  return () => {
30488
31225
  void layoutStore.flushNow();
@@ -30492,7 +31229,7 @@ function useAppSessionState(options) {
30492
31229
  }
30493
31230
 
30494
31231
  // src/hooks/use-auth-panel.ts
30495
- import { useCallback as useCallback7, useEffect as useEffect27, useRef as useRef11 } from "react";
31232
+ import { useCallback as useCallback7, useEffect as useEffect28, useRef as useRef11 } from "react";
30496
31233
  function abortError() {
30497
31234
  return Object.assign(new Error("Cancelled"), { name: "AbortError" });
30498
31235
  }
@@ -30518,14 +31255,14 @@ function useAuthPanel(opts) {
30518
31255
  promptRef.current = null;
30519
31256
  pending?.reject(abortError());
30520
31257
  }, []);
30521
- useEffect27(() => {
31258
+ useEffect28(() => {
30522
31259
  mountedRef.current = true;
30523
31260
  return () => {
30524
31261
  mountedRef.current = false;
30525
31262
  abortLiveFlow();
30526
31263
  };
30527
31264
  }, [abortLiveFlow]);
30528
- useEffect27(() => {
31265
+ useEffect28(() => {
30529
31266
  if (!open) abortLiveFlow();
30530
31267
  }, [open, abortLiveFlow]);
30531
31268
  const reloadProviders = useCallback7(async () => {
@@ -30879,7 +31616,7 @@ function useAuthPanel(opts) {
30879
31616
  }
30880
31617
 
30881
31618
  // src/hooks/use-autonomous-coordinator.ts
30882
- import { useCallback as useCallback8, useEffect as useEffect28, useRef as useRef12 } from "react";
31619
+ import { useCallback as useCallback8, useEffect as useEffect29, useRef as useRef12 } from "react";
30883
31620
  function useAutonomousCoordinator(subscribeCoordinatorEvents, dispatch) {
30884
31621
  const dispatchRef = useRef12(dispatch);
30885
31622
  dispatchRef.current = dispatch;
@@ -30889,7 +31626,7 @@ function useAutonomousCoordinator(subscribeCoordinatorEvents, dispatch) {
30889
31626
  event
30890
31627
  });
30891
31628
  }, []);
30892
- useEffect28(() => {
31629
+ useEffect29(() => {
30893
31630
  if (!subscribeCoordinatorEvents) return;
30894
31631
  const unsubscribe = subscribeCoordinatorEvents(handler);
30895
31632
  return unsubscribe;
@@ -30899,7 +31636,7 @@ function useAutonomousCoordinator(subscribeCoordinatorEvents, dispatch) {
30899
31636
  // src/hooks/use-autonomy-drivers.ts
30900
31637
  import { toErrorMessage as toErrorMessage3 } from "@wrongstack/core/utils";
30901
31638
  import {
30902
- useEffect as useEffect29,
31639
+ useEffect as useEffect30,
30903
31640
  useRef as useRef13
30904
31641
  } from "react";
30905
31642
  function useAutonomyDrivers({
@@ -30917,7 +31654,7 @@ function useAutonomyDrivers({
30917
31654
  parallelLoopRunningRef
30918
31655
  }) {
30919
31656
  const mountedRef = useRef13(true);
30920
- useEffect29(() => {
31657
+ useEffect30(() => {
30921
31658
  mountedRef.current = true;
30922
31659
  return () => {
30923
31660
  mountedRef.current = false;
@@ -31009,7 +31746,7 @@ function useAutonomyDrivers({
31009
31746
  };
31010
31747
  const runParallelLoopRef = useRef13(runParallelLoop);
31011
31748
  runParallelLoopRef.current = runParallelLoop;
31012
- useEffect29(() => {
31749
+ useEffect30(() => {
31013
31750
  if (!subscribeEternalIteration) return;
31014
31751
  const unsub = subscribeEternalIteration((entry) => {
31015
31752
  const mark = entry.status === "success" ? "\u2713" : entry.status === "failure" ? "\u2717" : entry.status === "aborted" ? "\u2298" : "\xB7";
@@ -31020,7 +31757,7 @@ function useAutonomyDrivers({
31020
31757
  });
31021
31758
  return unsub;
31022
31759
  }, [subscribeEternalIteration]);
31023
- useEffect29(() => {
31760
+ useEffect30(() => {
31024
31761
  if (!subscribeEternalStage) return;
31025
31762
  const unsub = subscribeEternalStage((stage) => {
31026
31763
  dispatch({ type: "eternalStage", stage });
@@ -31356,7 +32093,7 @@ function useBrainPanel(opts) {
31356
32093
  }
31357
32094
 
31358
32095
  // src/hooks/use-brain-risk-sync.ts
31359
- import { useCallback as useCallback9, useEffect as useEffect30, useRef as useRef14 } from "react";
32096
+ import { useCallback as useCallback9, useEffect as useEffect31, useRef as useRef14 } from "react";
31360
32097
  function useBrainRiskSync({
31361
32098
  dispatch,
31362
32099
  riskLevel,
@@ -31370,7 +32107,7 @@ function useBrainRiskSync({
31370
32107
  [dispatch]
31371
32108
  );
31372
32109
  const prevRiskRef = useRef14(riskLevel);
31373
- useEffect30(() => {
32110
+ useEffect31(() => {
31374
32111
  if (!brainPanelOpen) return;
31375
32112
  if (riskLevel !== prevRiskRef.current && onBrainRiskLevel) {
31376
32113
  prevRiskRef.current = riskLevel;
@@ -31384,7 +32121,7 @@ function useBrainRiskSync({
31384
32121
 
31385
32122
  // src/hooks/use-client-telemetry.ts
31386
32123
  import { projectSlug } from "@wrongstack/core/utils";
31387
- import { useEffect as useEffect31 } from "react";
32124
+ import { useEffect as useEffect32 } from "react";
31388
32125
  function useClientTelemetry({
31389
32126
  events,
31390
32127
  clientId,
@@ -31395,7 +32132,7 @@ function useClientTelemetry({
31395
32132
  restoreDebugStreamCallback,
31396
32133
  dispatch
31397
32134
  }) {
31398
- useEffect31(() => {
32135
+ useEffect32(() => {
31399
32136
  if (!clientId || !events) return;
31400
32137
  let toolCalls = 0;
31401
32138
  const emitStatus = () => {
@@ -31437,7 +32174,7 @@ function useClientTelemetry({
31437
32174
  offIterCompleted();
31438
32175
  };
31439
32176
  }, [events, clientId, tokenCounter, getAutonomy, agent.ctx.model, agent.ctx.projectRoot]);
31440
- useEffect31(() => {
32177
+ useEffect32(() => {
31441
32178
  if (!registerDebugStreamCallback) return;
31442
32179
  let cancelled = false;
31443
32180
  registerDebugStreamCallback((stats) => {
@@ -31471,7 +32208,7 @@ import { toErrorMessage as toErrorMessage4 } from "@wrongstack/core/utils";
31471
32208
  import { getProcessRegistry as getProcessRegistry6 } from "@wrongstack/tools";
31472
32209
  import {
31473
32210
  useCallback as useCallback10,
31474
- useEffect as useEffect32,
32211
+ useEffect as useEffect33,
31475
32212
  useMemo as useMemo10
31476
32213
  } from "react";
31477
32214
 
@@ -33280,7 +34017,7 @@ function useCoreTuiCommands({
33280
34017
  }) {
33281
34018
  const stdout = { columns: terminalWidth };
33282
34019
  const getCronJobs = useMemo10(() => createCronJobsGetter(agent), [agent]);
33283
- useEffect32(() => {
34020
+ useEffect33(() => {
33284
34021
  slashRegistry.register(createKillSlashCommand());
33285
34022
  slashRegistry.register(createPsSlashCommand());
33286
34023
  slashRegistry.register(createCronSlashCommand({ getCronJobs }));
@@ -33353,7 +34090,7 @@ function useCoreTuiCommands({
33353
34090
  getModeLabel,
33354
34091
  getCronJobs
33355
34092
  ]);
33356
- useEffect32(() => {
34093
+ useEffect33(() => {
33357
34094
  return () => {
33358
34095
  getProcessRegistry6().killAll({ preserveBackground: true });
33359
34096
  };
@@ -33385,7 +34122,7 @@ function useCoreTuiCommands({
33385
34122
  },
33386
34123
  [liveDirector, clearPendingConfirms, dispatch]
33387
34124
  );
33388
- useEffect32(() => {
34125
+ useEffect33(() => {
33389
34126
  const cmd = {
33390
34127
  name: "steer",
33391
34128
  description: "Interrupt the running agent (incl. fleet) and redirect: /steer <new direction>",
@@ -33417,7 +34154,7 @@ function useCoreTuiCommands({
33417
34154
  slashRegistry.unregister("steer");
33418
34155
  };
33419
34156
  }, [slashRegistry, director, runSteerSequence]);
33420
- useEffect32(() => {
34157
+ useEffect33(() => {
33421
34158
  const cmd = {
33422
34159
  name: "rewind",
33423
34160
  description: "Open checkpoint timeline to rewind session: /rewind [checkpoint-index]",
@@ -33454,7 +34191,7 @@ function useCoreTuiCommands({
33454
34191
  slashRegistry.unregister("rewind");
33455
34192
  };
33456
34193
  }, [slashRegistry, handleRewindTo]);
33457
- useEffect32(() => {
34194
+ useEffect33(() => {
33458
34195
  const cmd = {
33459
34196
  name: "agents",
33460
34197
  description: "Toggle the agents monitor overlay.",
@@ -33476,7 +34213,7 @@ function useCoreTuiCommands({
33476
34213
  }
33477
34214
 
33478
34215
  // src/hooks/use-director-fleet-bridge.ts
33479
- import { useEffect as useEffect33, useRef as useRef16 } from "react";
34216
+ import { useEffect as useEffect34, useRef as useRef16 } from "react";
33480
34217
  import { stripNextStepsBlock } from "@wrongstack/tools/next-steps";
33481
34218
 
33482
34219
  // src/hooks/fleet-chat-coalescer.ts
@@ -33564,10 +34301,10 @@ function useDirectorFleetBridge({
33564
34301
  const labelsRef = useRef16(/* @__PURE__ */ new Map());
33565
34302
  const chatModeRef = useRef16(chatMode);
33566
34303
  const gate = useFleetGenerationGate(sessionGenerationRef);
33567
- useEffect33(() => {
34304
+ useEffect34(() => {
33568
34305
  chatModeRef.current = chatMode;
33569
34306
  }, [chatMode]);
33570
- useEffect33(() => {
34307
+ useEffect34(() => {
33571
34308
  const d = director;
33572
34309
  if (!d) return;
33573
34310
  const batch = [];
@@ -34002,13 +34739,13 @@ function handleCollabDone(event, dispatch, stateRef) {
34002
34739
  }
34003
34740
 
34004
34741
  // src/hooks/use-enhance-runtime-state.ts
34005
- import { useEffect as useEffect34, useRef as useRef17, useState as useState25 } from "react";
34742
+ import { useEffect as useEffect35, useRef as useRef17, useState as useState25 } from "react";
34006
34743
  function useEnhanceRuntimeState({
34007
34744
  enhanceEnabled,
34008
34745
  midRunSendPicker
34009
34746
  }) {
34010
34747
  const enhanceEnabledRef = useRef17(enhanceEnabled);
34011
- useEffect34(() => {
34748
+ useEffect35(() => {
34012
34749
  enhanceEnabledRef.current = enhanceEnabled;
34013
34750
  }, [enhanceEnabled]);
34014
34751
  const midRunSendPickerRef = useRef17(midRunSendPicker);
@@ -34041,7 +34778,7 @@ function useEnhanceRuntimeState({
34041
34778
 
34042
34779
  // src/hooks/use-exit-command.ts
34043
34780
  import { getProcessRegistry as getProcessRegistry7 } from "@wrongstack/tools";
34044
- import { useCallback as useCallback12, useEffect as useEffect35, useRef as useRef18 } from "react";
34781
+ import { useCallback as useCallback12, useEffect as useEffect36, useRef as useRef18 } from "react";
34045
34782
 
34046
34783
  // src/exit-slash.ts
34047
34784
  var DESCRIPTION = "Exit the TUI. While a leader run or any subagent is still active, asks for an explicit Enter/Esc confirmation before terminating them.";
@@ -34147,7 +34884,7 @@ function useExitCommand({
34147
34884
  },
34148
34885
  [dispatch, terminateWork]
34149
34886
  );
34150
- useEffect35(() => {
34887
+ useEffect36(() => {
34151
34888
  const cmd = createExitSlashCommand({
34152
34889
  isLeaderActive: () => interruptController?.isRunning?.() ?? stateRef.current.status !== "idle",
34153
34890
  countRunningSubagents: () => Object.values(stateRef.current.fleet).filter((e) => e.status === "running").length,
@@ -34167,7 +34904,7 @@ function useExitCommand({
34167
34904
  import * as fs3 from "node:fs/promises";
34168
34905
  import * as path4 from "node:path";
34169
34906
  import { toErrorMessage as toErrorMessage5 } from "@wrongstack/core/utils";
34170
- import { useEffect as useEffect36 } from "react";
34907
+ import { useEffect as useEffect37 } from "react";
34171
34908
 
34172
34909
  // src/file-search.ts
34173
34910
  import * as fs2 from "node:fs/promises";
@@ -34269,7 +35006,7 @@ function detectAtToken(buffer, cursor) {
34269
35006
  }
34270
35007
  function useFileSearch(options) {
34271
35008
  const { state, dispatch, projectRoot, builderRef, draftRef, setDraft, tokenPreviewsRef } = options;
34272
- useEffect36(() => {
35009
+ useEffect37(() => {
34273
35010
  const detected = detectAtToken(state.buffer, state.cursor);
34274
35011
  if (!detected) {
34275
35012
  if (state.picker.open) dispatch({ type: "pickerClose" });
@@ -34346,7 +35083,7 @@ function fileReadContract(filePath, bytes) {
34346
35083
  }
34347
35084
 
34348
35085
  // src/hooks/use-git-session-status.ts
34349
- import { useEffect as useEffect37, useRef as useRef19, useState as useState26 } from "react";
35086
+ import { useEffect as useEffect38, useRef as useRef19, useState as useState26 } from "react";
34350
35087
 
34351
35088
  // src/git-info.ts
34352
35089
  import { spawn } from "node:child_process";
@@ -34450,10 +35187,10 @@ function useGitSessionStatus({
34450
35187
  const [gitInfo, setGitInfo] = useState26(null);
34451
35188
  const previousBranchRef = useRef19(null);
34452
35189
  const gitHidden = hiddenItems.includes("git");
34453
- useEffect37(() => {
35190
+ useEffect38(() => {
34454
35191
  if (gitHidden) previousBranchRef.current = null;
34455
35192
  }, [gitHidden]);
34456
- useEffect37(() => {
35193
+ useEffect38(() => {
34457
35194
  if (gitHidden) return;
34458
35195
  let cancelled = false;
34459
35196
  const refresh = () => {
@@ -34487,7 +35224,7 @@ function useGitSessionStatus({
34487
35224
  clearInterval(timer);
34488
35225
  };
34489
35226
  }, [agent.ctx, gitHidden]);
34490
- useEffect37(() => {
35227
+ useEffect38(() => {
34491
35228
  if (!getLiveSessions) return;
34492
35229
  let cancelled = false;
34493
35230
  const poll = async () => {
@@ -34525,7 +35262,7 @@ function useHelpPanel(dispatch, slashRegistry) {
34525
35262
  }
34526
35263
 
34527
35264
  // src/hooks/use-history-copy-notice.ts
34528
- import { useCallback as useCallback14, useEffect as useEffect38, useRef as useRef20 } from "react";
35265
+ import { useCallback as useCallback14, useEffect as useEffect39, useRef as useRef20 } from "react";
34529
35266
  function useHistoryCopyNotice(dispatch) {
34530
35267
  const copiedHintTimerRef = useRef20(null);
34531
35268
  const onHistoryCopy = useCallback14(
@@ -34539,7 +35276,7 @@ function useHistoryCopyNotice(dispatch) {
34539
35276
  },
34540
35277
  [dispatch]
34541
35278
  );
34542
- useEffect38(
35279
+ useEffect39(
34543
35280
  () => () => {
34544
35281
  if (copiedHintTimerRef.current) clearTimeout(copiedHintTimerRef.current);
34545
35282
  },
@@ -34549,14 +35286,14 @@ function useHistoryCopyNotice(dispatch) {
34549
35286
  }
34550
35287
 
34551
35288
  // src/hooks/use-history-viewport-sync.ts
34552
- import { useEffect as useEffect39, useLayoutEffect as useLayoutEffect2, useRef as useRef21, useState as useState27 } from "react";
35289
+ import { useEffect as useEffect40, useLayoutEffect as useLayoutEffect2, useRef as useRef21, useState as useState27 } from "react";
34553
35290
  function useHistoryViewportSync(input) {
34554
35291
  const { stdoutRows, viewportRows, setViewportRows } = input;
34555
35292
  const bottomRegionRef = useRef21(null);
34556
35293
  const statusBarWrapRef = useRef21(null);
34557
35294
  const belowStatusBarRef = useRef21(null);
34558
35295
  const [termRows, setTermRows] = useState27(stdoutRows ?? 24);
34559
- useEffect39(() => {
35296
+ useEffect40(() => {
34560
35297
  const handleResize = () => setTermRows(process.stdout.rows ?? 24);
34561
35298
  process.stdout.prependListener("resize", handleResize);
34562
35299
  return () => {
@@ -34576,7 +35313,7 @@ function useHistoryViewportSync(input) {
34576
35313
 
34577
35314
  // src/hooks/use-initial-prompt.ts
34578
35315
  import { buildGoalPreamble } from "@wrongstack/core/execution";
34579
- import { useEffect as useEffect40, useRef as useRef22 } from "react";
35316
+ import { useEffect as useEffect41, useRef as useRef22 } from "react";
34580
35317
  function useInitialPrompt({
34581
35318
  initialGoal,
34582
35319
  initialAsk,
@@ -34585,7 +35322,7 @@ function useInitialPrompt({
34585
35322
  dispatch
34586
35323
  }) {
34587
35324
  const bootInjectedRef = useRef22(false);
34588
- useEffect40(() => {
35325
+ useEffect41(() => {
34589
35326
  if (bootInjectedRef.current) return;
34590
35327
  const goal = initialGoal?.trim();
34591
35328
  const ask = initialAsk?.trim();
@@ -34632,7 +35369,7 @@ function useInitialPrompt({
34632
35369
  import { DefaultSecretScrubber } from "@wrongstack/core/security";
34633
35370
  import { INPUT_HISTORY_DEFAULT_MAX, InputHistoryStore } from "@wrongstack/core/storage";
34634
35371
  import { resolveWstackPaths as resolveWstackPaths3 } from "@wrongstack/core/utils";
34635
- import { useEffect as useEffect41, useMemo as useMemo12, useRef as useRef23 } from "react";
35372
+ import { useEffect as useEffect42, useMemo as useMemo12, useRef as useRef23 } from "react";
34636
35373
  function useInputHistoryPersistence({
34637
35374
  projectRoot,
34638
35375
  inputHistory,
@@ -34646,7 +35383,7 @@ function useInputHistoryPersistence({
34646
35383
  const inputHistoryLoadedRef = useRef23(false);
34647
35384
  const inputHistorySaveTimerRef = useRef23(void 0);
34648
35385
  const inputHistoryLastSavedRef = useRef23("");
34649
- useEffect41(() => {
35386
+ useEffect42(() => {
34650
35387
  if (!inputHistoryStore) return;
34651
35388
  let cancelled = false;
34652
35389
  inputHistoryStore.load().then((entries) => {
@@ -34662,7 +35399,7 @@ function useInputHistoryPersistence({
34662
35399
  cancelled = true;
34663
35400
  };
34664
35401
  }, [inputHistoryStore, dispatch]);
34665
- useEffect41(() => {
35402
+ useEffect42(() => {
34666
35403
  if (!inputHistoryStore || !inputHistoryLoadedRef.current) return;
34667
35404
  const snapshot = JSON.stringify(inputHistory);
34668
35405
  if (snapshot === inputHistoryLastSavedRef.current) return;
@@ -34682,7 +35419,7 @@ function useInputHistoryPersistence({
34682
35419
  import { getProcessRegistry as getProcessRegistry8 } from "@wrongstack/tools";
34683
35420
  import {
34684
35421
  useCallback as useCallback15,
34685
- useEffect as useEffect42,
35422
+ useEffect as useEffect43,
34686
35423
  useRef as useRef24
34687
35424
  } from "react";
34688
35425
  var INTERRUPT_PRESS_WINDOW_MS = 2e3;
@@ -34881,7 +35618,7 @@ function useInterruptLadder({
34881
35618
  onExit,
34882
35619
  exit
34883
35620
  ]);
34884
- useEffect42(() => {
35621
+ useEffect43(() => {
34885
35622
  process.on("SIGINT", runInterruptLadder);
34886
35623
  return () => {
34887
35624
  process.off("SIGINT", runInterruptLadder);
@@ -34907,7 +35644,7 @@ function useKanbanBoardFocus() {
34907
35644
  }
34908
35645
 
34909
35646
  // src/hooks/use-live-settings-state.ts
34910
- import { useEffect as useEffect43, useRef as useRef26 } from "react";
35647
+ import { useEffect as useEffect44, useRef as useRef26 } from "react";
34911
35648
  function useLiveSettingsState({
34912
35649
  getSettings,
34913
35650
  titleController,
@@ -34923,7 +35660,7 @@ function useLiveSettingsState({
34923
35660
  const confirmExitRef = useRef26(confirmExit);
34924
35661
  confirmExitRef.current = liveSettings?.confirmExit ?? confirmExit;
34925
35662
  const liveTitleAnimation = liveSettings?.titleAnimation;
34926
- useEffect43(() => {
35663
+ useEffect44(() => {
34927
35664
  if (!titleController) return;
34928
35665
  titleController.setEnabled(liveTitleAnimation !== false);
34929
35666
  }, [titleController, liveTitleAnimation]);
@@ -34938,10 +35675,10 @@ function useLiveSettingsState({
34938
35675
  }
34939
35676
 
34940
35677
  // src/hooks/use-live-todos.ts
34941
- import { useEffect as useEffect44, useState as useState29 } from "react";
35678
+ import { useEffect as useEffect45, useState as useState29 } from "react";
34942
35679
  function useLiveTodos(context) {
34943
35680
  const [todos, setTodos] = useState29(() => [...context.todos]);
34944
- useEffect44(() => {
35681
+ useEffect45(() => {
34945
35682
  setTodos([...context.todos]);
34946
35683
  return context.state.onChange((change) => {
34947
35684
  if (change.kind === "todos_replaced") setTodos([...change.todos]);
@@ -34951,7 +35688,7 @@ function useLiveTodos(context) {
34951
35688
  }
34952
35689
 
34953
35690
  // src/hooks/use-mailbox-view-model.ts
34954
- import { useEffect as useEffect45, useState as useState30 } from "react";
35691
+ import { useEffect as useEffect46, useState as useState30 } from "react";
34955
35692
  function useMailboxViewModel(events) {
34956
35693
  const [mailboxStatus, setMailboxStatus] = useState30({
34957
35694
  unread: 0,
@@ -34961,7 +35698,7 @@ function useMailboxViewModel(events) {
34961
35698
  const [mailboxPanelOpen, setMailboxPanelOpen] = useState30(false);
34962
35699
  const [mailboxMessages, setMailboxMessages] = useState30([]);
34963
35700
  const [mailboxAgents, setMailboxAgents] = useState30([]);
34964
- useEffect45(() => {
35701
+ useEffect46(() => {
34965
35702
  const AGENT_ONLINE_TTL_MS = 12e4;
34966
35703
  const lastSeen = /* @__PURE__ */ new Map();
34967
35704
  const unsubUnread = events.onPattern("mailbox.unread_count", (_event, payload) => {
@@ -35023,7 +35760,7 @@ function useMailboxViewModel(events) {
35023
35760
  unsubSnapshot();
35024
35761
  };
35025
35762
  }, [events]);
35026
- useEffect45(() => {
35763
+ useEffect46(() => {
35027
35764
  const unsubMessage = events.onPattern("mailbox.received", (_event, payload) => {
35028
35765
  const data = payload;
35029
35766
  if (!data?.messageId) return;
@@ -35174,7 +35911,7 @@ function useModelPickRequest(opts) {
35174
35911
  }
35175
35912
 
35176
35913
  // src/hooks/use-mouse-tracking.ts
35177
- import { useEffect as useEffect46, useRef as useRef27, useState as useState31 } from "react";
35914
+ import { useEffect as useEffect47, useRef as useRef27, useState as useState31 } from "react";
35178
35915
  function useMouseTracking(input) {
35179
35916
  const { initialMouseMode, overlayOpen, protocol, stdout } = input;
35180
35917
  const [mouseMode, setMouseMode] = useState31(initialMouseMode);
@@ -35186,7 +35923,7 @@ function useMouseTracking(input) {
35186
35923
  });
35187
35924
  const mouseTrackingSequence = mouseTrackingOn ? mouseMode ? MOUSE_DRAG_ON : MOUSE_CLICK_ON : MOUSE_OFF;
35188
35925
  const mouseWrittenRef = useRef27(null);
35189
- useEffect46(() => {
35926
+ useEffect47(() => {
35190
35927
  if (mouseWrittenRef.current === mouseTrackingSequence) return;
35191
35928
  mouseWrittenRef.current = mouseTrackingSequence;
35192
35929
  try {
@@ -35194,7 +35931,7 @@ function useMouseTracking(input) {
35194
35931
  } catch {
35195
35932
  }
35196
35933
  }, [mouseTrackingSequence, stdout]);
35197
- useEffect46(
35934
+ useEffect47(
35198
35935
  () => () => {
35199
35936
  const wasTracking = mouseWrittenRef.current !== null && mouseWrittenRef.current !== MOUSE_OFF;
35200
35937
  mouseWrittenRef.current = null;
@@ -35222,7 +35959,7 @@ import {
35222
35959
  import { todoTool } from "@wrongstack/tools/todo";
35223
35960
  import {
35224
35961
  useCallback as useCallback17,
35225
- useEffect as useEffect47,
35962
+ useEffect as useEffect48,
35226
35963
  useRef as useRef28,
35227
35964
  useState as useState32
35228
35965
  } from "react";
@@ -35283,13 +36020,13 @@ function useNextStepsAutoSubmit({
35283
36020
  const autoSubmitLoopGuardRef = useRef28(createAutoProceedLoopGuard());
35284
36021
  const continuationAttemptTrackerRef = useRef28(createContinuationAttemptTracker());
35285
36022
  const [nextStepsRecheck, setNextStepsRecheck] = useState32(0);
35286
- useEffect47(() => {
36023
+ useEffect48(() => {
35287
36024
  autoSubmitStreakRef.current = 0;
35288
36025
  autoSubmitCapWarnedRef.current = false;
35289
36026
  autoSubmitLoopGuardRef.current.reset();
35290
36027
  continuationAttemptTrackerRef.current.reset();
35291
36028
  }, [autonomyLive]);
35292
- useEffect47(() => {
36029
+ useEffect48(() => {
35293
36030
  const liveAutonomy = getAutonomy?.() ?? autonomyLive;
35294
36031
  if (state.status !== "idle" || liveAutonomy !== "auto") {
35295
36032
  clearInterval(nextStepsAutoSubmitTimerRef.current);
@@ -35549,7 +36286,7 @@ ${GROUNDED_NO_PROGRESS_STEER}` : suggestion;
35549
36286
 
35550
36287
  // src/hooks/use-panel-controllers.ts
35551
36288
  import { toErrorMessage as toErrorMessage6 } from "@wrongstack/core/utils";
35552
- import React8, { useEffect as useEffect48 } from "react";
36289
+ import React8, { useEffect as useEffect49 } from "react";
35553
36290
 
35554
36291
  // src/on-panel-open.ts
35555
36292
  function createPanelOpenDispatcher(deps) {
@@ -35683,7 +36420,7 @@ function usePanelControllers({
35683
36420
  dispatch({ type: "sessionsPanelBusy", on: false });
35684
36421
  }
35685
36422
  }, [getLiveSessions]);
35686
- useEffect48(() => {
36423
+ useEffect49(() => {
35687
36424
  if (!onPanelOpen) return;
35688
36425
  const dispatcher = createPanelOpenDispatcher({
35689
36426
  dispatch,
@@ -35710,7 +36447,7 @@ function usePanelControllers({
35710
36447
  openShadowPanel,
35711
36448
  openHelpPanel
35712
36449
  ]);
35713
- useEffect48(() => {
36450
+ useEffect49(() => {
35714
36451
  if (!state.sessionsPanelOpen || !getLiveSessions) return void 0;
35715
36452
  const t = setInterval(() => {
35716
36453
  void loadLiveSessions();
@@ -35790,7 +36527,7 @@ function usePanelControllers({
35790
36527
  if (!getPluginItems) return;
35791
36528
  dispatch({ type: "pluginPickerSetItems", items: getPluginItems() });
35792
36529
  }, [getPluginItems]);
35793
- useEffect48(() => {
36530
+ useEffect49(() => {
35794
36531
  if (!state.pluginPicker.open) return;
35795
36532
  refreshPluginPicker();
35796
36533
  }, [state.pluginPicker.open, refreshPluginPicker]);
@@ -35822,7 +36559,7 @@ function usePanelControllers({
35822
36559
  if (!getMcpServers) return;
35823
36560
  dispatch({ type: "mcpPickerSetItems", items: getMcpServers() });
35824
36561
  }, [getMcpServers]);
35825
- useEffect48(() => {
36562
+ useEffect49(() => {
35826
36563
  if (!state.mcpPicker.open) return;
35827
36564
  refreshMcpPicker();
35828
36565
  }, [state.mcpPicker.open, refreshMcpPicker]);
@@ -35866,7 +36603,7 @@ function usePanelControllers({
35866
36603
  dispatch({ type: "toolsPickerSetItems", items });
35867
36604
  setLiveToolCount(items.filter((item) => item.enabled).length);
35868
36605
  }, [getToolsItems]);
35869
- useEffect48(() => {
36606
+ useEffect49(() => {
35870
36607
  if (!state.toolsPicker.open) return;
35871
36608
  refreshToolsPicker();
35872
36609
  }, [state.toolsPicker.open, refreshToolsPicker]);
@@ -36104,7 +36841,7 @@ function usePromptPicker({
36104
36841
  import { tuiStreamFlushMs } from "@wrongstack/core/utils";
36105
36842
  import { DEFAULT_MIN_IMPORTANCE as DEFAULT_MIN_IMPORTANCE2, DEFAULT_MIN_SCORE as DEFAULT_MIN_SCORE2, MIN_RELATION_STRENGTH as MIN_RELATION_STRENGTH2 } from "@wrongstack/sage";
36106
36843
  import { isFinalTurnStopReason as isFinalTurnStopReason2 } from "@wrongstack/tools/next-steps";
36107
- import { useEffect as useEffect49 } from "react";
36844
+ import { useEffect as useEffect50 } from "react";
36108
36845
 
36109
36846
  // src/memory-lifecycle-entry.ts
36110
36847
  function memoryLifecycleEntry(event, payload) {
@@ -36304,7 +37041,7 @@ function useProviderEventBridge({
36304
37041
  assistantCommittedThisRunRef,
36305
37042
  setMemoryContextMonitor
36306
37043
  }) {
36307
- useEffect49(() => {
37044
+ useEffect50(() => {
36308
37045
  const FLUSH_MS2 = tuiStreamFlushMs();
36309
37046
  let pendingToolStream = null;
36310
37047
  const pendingSageStats = /* @__PURE__ */ new Map();
@@ -36678,7 +37415,7 @@ function useProviderEventBridge({
36678
37415
  }
36679
37416
 
36680
37417
  // src/hooks/use-queue-manager.ts
36681
- import { useEffect as useEffect50, useRef as useRef31 } from "react";
37418
+ import { useEffect as useEffect51, useRef as useRef31 } from "react";
36682
37419
 
36683
37420
  // src/queue-slash.ts
36684
37421
  var USAGE5 = "Usage:\n /queue \u2014 list pending messages\n /queue list \u2014 same as /queue\n /queue clear \u2014 drop all pending messages\n /queue delete N M\u2026 \u2014 drop messages at 1-based positions\n /queue picker on|off \u2014 toggle the mid-run send-mode picker (queue/btw/steer)\n /queue picker \u2014 show whether the picker is on";
@@ -36786,7 +37523,7 @@ function useQueueManager({
36786
37523
  midRunSendPickerRef
36787
37524
  }) {
36788
37525
  const persistState = useRef31({ running: false, pending: null });
36789
- useEffect50(() => {
37526
+ useEffect51(() => {
36790
37527
  if (!queueStore) return;
36791
37528
  let cancelled = false;
36792
37529
  queueStore.read().then((items) => {
@@ -36813,7 +37550,7 @@ function useQueueManager({
36813
37550
  cancelled = true;
36814
37551
  };
36815
37552
  }, [queueStore]);
36816
- useEffect50(() => {
37553
+ useEffect51(() => {
36817
37554
  if (!queueStore) return;
36818
37555
  const raw = stateRef.current.queue.map(
36819
37556
  ({
@@ -36842,10 +37579,10 @@ function useQueueManager({
36842
37579
  }
36843
37580
  })();
36844
37581
  }, [stateRef.current.queue, queueStore, stateRef]);
36845
- useEffect50(() => {
37582
+ useEffect51(() => {
36846
37583
  onQueueChange?.(stateRef.current.queue.map((q) => q.displayText));
36847
37584
  }, [stateRef.current.queue, onQueueChange, stateRef]);
36848
- useEffect50(() => {
37585
+ useEffect51(() => {
36849
37586
  const cmd = createQueueSlashCommand({
36850
37587
  getQueue: () => stateRef.current.queue,
36851
37588
  clear: () => dispatch({ type: "queueClear" }),
@@ -36868,7 +37605,7 @@ function useQueueManager({
36868
37605
  }
36869
37606
 
36870
37607
  // src/hooks/use-session-interrupt-controller.ts
36871
- import { useEffect as useEffect51 } from "react";
37608
+ import { useEffect as useEffect52 } from "react";
36872
37609
  function useSessionInterruptController({
36873
37610
  interruptController,
36874
37611
  dispatch,
@@ -36890,7 +37627,7 @@ function useSessionInterruptController({
36890
37627
  getSddRun,
36891
37628
  switchAutonomy
36892
37629
  }) {
36893
- useEffect51(() => {
37630
+ useEffect52(() => {
36894
37631
  if (!interruptController) return;
36895
37632
  let pendingClearResolve = null;
36896
37633
  let pendingSlashResolve = null;
@@ -37017,15 +37754,15 @@ function useSessionInterruptController({
37017
37754
  }
37018
37755
 
37019
37756
  // src/hooks/use-settings-auto-save.ts
37020
- import { useEffect as useEffect52, useRef as useRef32 } from "react";
37757
+ import { useEffect as useEffect53, useRef as useRef32 } from "react";
37021
37758
  function useSettingsAutoSave(state, saveSettings, dispatch) {
37022
37759
  const settingsAutoSaveGateRef = useRef32(true);
37023
- useEffect52(() => {
37760
+ useEffect53(() => {
37024
37761
  if (state.settingsPicker.open) {
37025
37762
  settingsAutoSaveGateRef.current = true;
37026
37763
  }
37027
37764
  }, [state.settingsPicker.open]);
37028
- useEffect52(() => {
37765
+ useEffect53(() => {
37029
37766
  const sp = state.settingsPicker;
37030
37767
  const save = saveSettings;
37031
37768
  if (!sp.open || !save) return;
@@ -37181,14 +37918,14 @@ function useShadowPanel(dispatch, host) {
37181
37918
  }
37182
37919
 
37183
37920
  // src/hooks/use-slash-picker.ts
37184
- import { useCallback as useCallback20, useEffect as useEffect53 } from "react";
37921
+ import { useCallback as useCallback20, useEffect as useEffect54 } from "react";
37185
37922
  function useSlashPicker({
37186
37923
  state,
37187
37924
  slashRegistry,
37188
37925
  dispatch,
37189
37926
  setDraft
37190
37927
  }) {
37191
- useEffect53(() => {
37928
+ useEffect54(() => {
37192
37929
  const trimmed = state.buffer.trimStart();
37193
37930
  if (!trimmed.startsWith("/") || /\s/.test(trimmed)) {
37194
37931
  if (state.slashPicker.open) dispatch({ type: "slashPickerClose" });
@@ -37226,7 +37963,7 @@ function useStableKeyHandler(handleKey) {
37226
37963
  // src/hooks/use-statusbar-view-model.ts
37227
37964
  import * as fs4 from "node:fs/promises";
37228
37965
  import { getContextBreakdown } from "@wrongstack/core/utils";
37229
- import { useEffect as useEffect54, useMemo as useMemo13, useState as useState33 } from "react";
37966
+ import { useEffect as useEffect55, useMemo as useMemo13, useState as useState33 } from "react";
37230
37967
 
37231
37968
  // src/context-fill.ts
37232
37969
  function resolveContextFill(inputs) {
@@ -37360,7 +38097,7 @@ function useStatusbarViewModel({
37360
38097
  const taskHidden = hiddenItems.includes("tasks");
37361
38098
  const planPath = agent.ctx.meta["plan.path"];
37362
38099
  const [planCounts, setPlanCounts] = useState33(null);
37363
- useEffect54(() => {
38100
+ useEffect55(() => {
37364
38101
  if (planHidden) return;
37365
38102
  if (typeof planPath !== "string" || !planPath) {
37366
38103
  setPlanCounts(null);
@@ -37407,7 +38144,7 @@ function useStatusbarViewModel({
37407
38144
  }, [planPath, planHidden]);
37408
38145
  const taskPath = agent.ctx.meta["task.path"];
37409
38146
  const [taskCounts, setTaskCounts] = useState33(null);
37410
- useEffect54(() => {
38147
+ useEffect55(() => {
37411
38148
  if (taskHidden) return;
37412
38149
  if (typeof taskPath !== "string" || !taskPath) {
37413
38150
  setTaskCounts(null);
@@ -37477,7 +38214,7 @@ function useStatusbarViewModel({
37477
38214
  }
37478
38215
 
37479
38216
  // src/hooks/use-statusline-hidden-sync.ts
37480
- import { useEffect as useEffect55 } from "react";
38217
+ import { useEffect as useEffect56 } from "react";
37481
38218
  function statuslineHiddenDiffers(hookHidden, pickerHidden) {
37482
38219
  const currentHidden = new Set(hookHidden);
37483
38220
  const pickerHiddenSet = new Set(pickerHidden);
@@ -37489,7 +38226,7 @@ function useStatuslineHiddenSync({
37489
38226
  hiddenItems,
37490
38227
  setHiddenItems
37491
38228
  }) {
37492
- useEffect55(() => {
38229
+ useEffect56(() => {
37493
38230
  if (!pickerOpen) return;
37494
38231
  if (statuslineHiddenDiffers(hiddenItems, pickerHidden)) {
37495
38232
  setHiddenItems([...pickerHidden]);
@@ -37498,7 +38235,7 @@ function useStatuslineHiddenSync({
37498
38235
  }
37499
38236
 
37500
38237
  // src/hooks/use-stream-chip-expiration.ts
37501
- import { useEffect as useEffect56, useRef as useRef34 } from "react";
38238
+ import { useEffect as useEffect57, useRef as useRef34 } from "react";
37502
38239
  function computeStreamChipActions(input) {
37503
38240
  const actions = [];
37504
38241
  const visible = new Set(input.visibleChipKeys);
@@ -37525,7 +38262,7 @@ function useStreamChipExpiration({
37525
38262
  }) {
37526
38263
  const prevBrainPromptRef = useRef34(brainPrompt);
37527
38264
  const prevEnhanceRef = useRef34(enhance);
37528
- useEffect56(() => {
38265
+ useEffect57(() => {
37529
38266
  const actions = computeStreamChipActions({
37530
38267
  brainPromptNow: !!brainPrompt,
37531
38268
  brainPromptPrev: !!prevBrainPromptRef.current,
@@ -37537,7 +38274,7 @@ function useStreamChipExpiration({
37537
38274
  prevBrainPromptRef.current = brainPrompt;
37538
38275
  prevEnhanceRef.current = enhance;
37539
38276
  }, [brainPrompt, enhance, visibleChips, dispatch]);
37540
- useEffect56(() => {
38277
+ useEffect57(() => {
37541
38278
  const interval = setInterval(() => {
37542
38279
  const expired = computeExpiredChipKeys(visibleChips, Date.now());
37543
38280
  for (const key of expired) {
@@ -37549,9 +38286,9 @@ function useStreamChipExpiration({
37549
38286
  }
37550
38287
 
37551
38288
  // src/hooks/use-theme-state.ts
37552
- import { useEffect as useEffect57 } from "react";
38289
+ import { useEffect as useEffect58 } from "react";
37553
38290
  function useThemeState({ configStore }) {
37554
- useEffect57(() => {
38291
+ useEffect58(() => {
37555
38292
  if (!configStore) return;
37556
38293
  const initial = configStore.get().themePreset;
37557
38294
  if (initial && initial !== getActiveThemeName()) {
@@ -37573,7 +38310,7 @@ function useThemeState({ configStore }) {
37573
38310
  import * as os from "node:os";
37574
38311
  import { loadGoal } from "@wrongstack/core/storage";
37575
38312
  import { resolveWstackPaths as resolveWstackPaths5 } from "@wrongstack/core/utils";
37576
- import { useCallback as useCallback22, useEffect as useEffect58, useMemo as useMemo14, useRef as useRef35, useState as useState34 } from "react";
38313
+ import { useCallback as useCallback22, useEffect as useEffect59, useMemo as useMemo14, useRef as useRef35, useState as useState34 } from "react";
37577
38314
 
37578
38315
  // src/heap-watchdog.ts
37579
38316
  import {
@@ -37620,7 +38357,7 @@ function useTuiActivity({
37620
38357
  const [rolledThinkingWord, setRolledThinkingWord] = useState34(() => pickRandomTuiThinkingWord());
37621
38358
  const thinkingWorking = status === "running" || status === "streaming";
37622
38359
  const prevThinkingWorkingRef = useRef35(false);
37623
- useEffect58(() => {
38360
+ useEffect59(() => {
37624
38361
  if (thinkingWorking && !prevThinkingWorkingRef.current) {
37625
38362
  setRolledThinkingWord((previous) => pickRandomTuiThinkingWord(previous));
37626
38363
  }
@@ -37633,14 +38370,14 @@ function useTuiActivity({
37633
38370
  );
37634
38371
  const startedAtRef = useRef35(Date.now());
37635
38372
  const [nowTick, setNowTick] = useState34(Date.now());
37636
- useEffect58(() => {
38373
+ useEffect59(() => {
37637
38374
  const timer = setInterval(() => setNowTick(Date.now()), 1e4);
37638
38375
  return () => clearInterval(timer);
37639
38376
  }, []);
37640
38377
  const [workingTimeBase, setWorkingTimeBase] = useState34(0);
37641
38378
  const workingStartRef = useRef35(null);
37642
38379
  const prevStatusRef = useRef35(status);
37643
- useEffect58(() => {
38380
+ useEffect59(() => {
37644
38381
  if (prevStatusRef.current === status) return;
37645
38382
  const wasWorking = prevStatusRef.current === "running" || prevStatusRef.current === "streaming";
37646
38383
  const isWorking = status === "running" || status === "streaming";
@@ -37656,7 +38393,7 @@ function useTuiActivity({
37656
38393
  const [fleetWorkingBase, setFleetWorkingBase] = useState34(0);
37657
38394
  const fleetWorkingStartRef = useRef35(null);
37658
38395
  const prevFleetRunningRef = useRef35(0);
37659
- useEffect58(() => {
38396
+ useEffect59(() => {
37660
38397
  const running = fleetRunningCount;
37661
38398
  if (prevFleetRunningRef.current === running) return;
37662
38399
  const wasRunning = prevFleetRunningRef.current > 0;
@@ -37702,7 +38439,7 @@ function useTuiActivity({
37702
38439
  pushMetricHistory(cpuHistoryRef.current, pct / 100);
37703
38440
  return pct;
37704
38441
  }, [nowTick]);
37705
- useEffect58(() => {
38442
+ useEffect59(() => {
37706
38443
  const stopHeapWatchdog = startSharedHeapWatchdog({
37707
38444
  collectStats: () => {
37708
38445
  const currentState = stateRef.current;
@@ -37783,7 +38520,7 @@ function useTuiActivity({
37783
38520
  }).catch(() => {
37784
38521
  });
37785
38522
  }, [dispatch, projectRoot]);
37786
- useEffect58(() => {
38523
+ useEffect59(() => {
37787
38524
  refreshGoalSummary();
37788
38525
  }, [nowTick, refreshGoalSummary]);
37789
38526
  const enhanceDots = enhanceBusy ? timingFrame % 36 : 0;
@@ -37806,7 +38543,7 @@ function useTuiActivity({
37806
38543
  }
37807
38544
 
37808
38545
  // src/hooks/use-tui-controllers.ts
37809
- import { useEffect as useEffect59 } from "react";
38546
+ import { useEffect as useEffect60 } from "react";
37810
38547
  function useTuiControllers({
37811
38548
  dispatch,
37812
38549
  fleetChat,
@@ -37816,7 +38553,7 @@ function useTuiControllers({
37816
38553
  enhanceController,
37817
38554
  agentsMonitorController
37818
38555
  }) {
37819
- useEffect59(() => {
38556
+ useEffect60(() => {
37820
38557
  if (!fleetStreamController) return;
37821
38558
  fleetStreamController.mode = fleetChat;
37822
38559
  fleetStreamController.setMode = (mode) => {
@@ -37828,12 +38565,12 @@ function useTuiControllers({
37828
38565
  };
37829
38566
  };
37830
38567
  }, [dispatch, fleetStreamController, fleetChat]);
37831
- useEffect59(() => {
38568
+ useEffect60(() => {
37832
38569
  if (fleetStreamController) {
37833
38570
  fleetStreamController.mode = fleetChat;
37834
38571
  }
37835
38572
  }, [fleetStreamController, fleetChat]);
37836
- useEffect59(() => {
38573
+ useEffect60(() => {
37837
38574
  if (!enhanceController) return;
37838
38575
  enhanceController.enabled = enhanceEnabled;
37839
38576
  enhanceController.setEnabled = (enabled) => {
@@ -37845,7 +38582,7 @@ function useTuiControllers({
37845
38582
  };
37846
38583
  };
37847
38584
  }, [dispatch, enhanceController, enhanceEnabled]);
37848
- useEffect59(() => {
38585
+ useEffect60(() => {
37849
38586
  if (!agentsMonitorController) return;
37850
38587
  agentsMonitorController.visible = agentsMonitorOpen;
37851
38588
  agentsMonitorController.setVisible = (visible) => {
@@ -37859,14 +38596,14 @@ function useTuiControllers({
37859
38596
  };
37860
38597
  };
37861
38598
  }, [agentsMonitorController, agentsMonitorOpen, dispatch]);
37862
- useEffect59(() => {
38599
+ useEffect60(() => {
37863
38600
  if (agentsMonitorController) agentsMonitorController.visible = agentsMonitorOpen;
37864
38601
  }, [agentsMonitorController, agentsMonitorOpen]);
37865
38602
  }
37866
38603
 
37867
38604
  // src/hooks/use-tui-environment-state.ts
37868
38605
  import { getIndexState as getIndexState2, getProcessRegistry as getProcessRegistry9, onIndexStateChange } from "@wrongstack/tools";
37869
- import { useEffect as useEffect60, useRef as useRef36, useState as useState36 } from "react";
38606
+ import { useEffect as useEffect61, useRef as useRef36, useState as useState36 } from "react";
37870
38607
 
37871
38608
  // src/hooks/use-statusline-state.ts
37872
38609
  import { useState as useState35 } from "react";
@@ -37924,7 +38661,7 @@ function useTuiEnvironmentState({
37924
38661
  const memoryRecordTotalRef = useRef36(memoryRecordTotal);
37925
38662
  memoryRecordTotalRef.current = memoryRecordTotal;
37926
38663
  const activeMemoryInContext = activeMemoryContextCount(memoryContextMonitor);
37927
- useEffect60(() => {
38664
+ useEffect61(() => {
37928
38665
  let cancelled = false;
37929
38666
  const refreshTotal = async () => {
37930
38667
  try {
@@ -37953,16 +38690,16 @@ function useTuiEnvironmentState({
37953
38690
  const hiddenItemsRef = useRef36(statusline.hiddenItems);
37954
38691
  hiddenItemsRef.current = statusline.hiddenItems;
37955
38692
  const [liveToolCount, setLiveToolCount] = useState36(toolCount);
37956
- useEffect60(() => setLiveToolCount(toolCount), [toolCount]);
38693
+ useEffect61(() => setLiveToolCount(toolCount), [toolCount]);
37957
38694
  const [indexState, setIndexState] = useState36(() => getIndexState2());
37958
- useEffect60(() => {
38695
+ useEffect61(() => {
37959
38696
  setIndexState(getIndexState2());
37960
38697
  return onIndexStateChange(setIndexState);
37961
38698
  }, []);
37962
38699
  const [breakerCountdown, setBreakerCountdown] = useState36(
37963
38700
  () => getProcessRegistry9().getBreakerCountdown()
37964
38701
  );
37965
- useEffect60(() => {
38702
+ useEffect61(() => {
37966
38703
  const settings = getSettings?.();
37967
38704
  if (settings) {
37968
38705
  getProcessRegistry9().setBreakerConfig({
@@ -37973,7 +38710,7 @@ function useTuiEnvironmentState({
37973
38710
  return getProcessRegistry9().onBreakerCountdownChange(setBreakerCountdown);
37974
38711
  }, [getSettings]);
37975
38712
  const breakerArmed = breakerCountdown !== null;
37976
- useEffect60(() => {
38713
+ useEffect61(() => {
37977
38714
  if (!breakerArmed) return;
37978
38715
  const timer = setInterval(
37979
38716
  () => setBreakerCountdown(getProcessRegistry9().getBreakerCountdown()),
@@ -37981,10 +38718,10 @@ function useTuiEnvironmentState({
37981
38718
  );
37982
38719
  return () => clearInterval(timer);
37983
38720
  }, [breakerArmed]);
37984
- useEffect60(() => {
38721
+ useEffect61(() => {
37985
38722
  statusline.setHiddenItems([...statuslineHiddenItems]);
37986
38723
  }, [statuslineHiddenItems, statusline.setHiddenItems]);
37987
- useEffect60(() => {
38724
+ useEffect61(() => {
37988
38725
  setStatuslineHiddenItems(statusline.hiddenItems);
37989
38726
  saveStatuslineHiddenItems(statusline.hiddenItems).catch?.((error) => {
37990
38727
  console.error(
@@ -38014,13 +38751,13 @@ function useTuiEnvironmentState({
38014
38751
  }
38015
38752
 
38016
38753
  // src/hooks/use-tui-event-bridge.ts
38017
- import { useCallback as useCallback24, useEffect as useEffect63 } from "react";
38754
+ import { useCallback as useCallback24, useEffect as useEffect64 } from "react";
38018
38755
 
38019
38756
  // src/hooks/use-brain-events.ts
38020
- import { useEffect as useEffect61 } from "react";
38757
+ import { useEffect as useEffect62 } from "react";
38021
38758
  var MONITOR_INTERVENTION_GRACE_MS = 5e3;
38022
38759
  function useBrainEvents(events, dispatch, getSessionId) {
38023
- useEffect61(() => {
38760
+ useEffect62(() => {
38024
38761
  const isCurrentSession2 = (sessionId) => {
38025
38762
  const current = getSessionId?.();
38026
38763
  return !sessionId || !current || sessionId === current;
@@ -38190,7 +38927,7 @@ function useBrainEvents(events, dispatch, getSessionId) {
38190
38927
 
38191
38928
  // src/hooks/use-subagent-events.ts
38192
38929
  import { expectDefined as expectDefined5 } from "@wrongstack/core/utils";
38193
- import { useCallback as useCallback23, useEffect as useEffect62, useRef as useRef37 } from "react";
38930
+ import { useCallback as useCallback23, useEffect as useEffect63, useRef as useRef37 } from "react";
38194
38931
  var STREAM_COLORS2 = ["cyan", "magenta", "yellow", "green", "blue"];
38195
38932
  function providerContextLimitHistoryEntry(event) {
38196
38933
  if (event.source !== "provider" || event.decreased !== true || typeof event.previousMaxContext !== "number" || event.previousMaxContext <= event.maxContext) {
@@ -38247,7 +38984,7 @@ function useSubagentEvents(events, dispatch, setActiveMaxContext, getSessionId,
38247
38984
  []
38248
38985
  // labelsRef is a stable ref
38249
38986
  );
38250
- useEffect62(() => {
38987
+ useEffect63(() => {
38251
38988
  const seen = /* @__PURE__ */ new Set();
38252
38989
  const isCurrentSession2 = (sessionId) => {
38253
38990
  const current = getSessionId?.();
@@ -38592,7 +39329,7 @@ function useTuiEventBridge({
38592
39329
  useGoalEvents(subscribeGoal, dispatch, stateRef, getSessionId);
38593
39330
  }
38594
39331
  function useSessionEvents(events, dispatch, onClearHistory, getSessionId) {
38595
- useEffect63(() => {
39332
+ useEffect64(() => {
38596
39333
  const isCurrentSession2 = (sessionId) => {
38597
39334
  const current = getSessionId?.();
38598
39335
  return !sessionId || !current || sessionId === current;
@@ -38623,7 +39360,7 @@ function useSessionEvents(events, dispatch, onClearHistory, getSessionId) {
38623
39360
  }, [events, dispatch, onClearHistory, getSessionId]);
38624
39361
  }
38625
39362
  function useGoalEvents(subscribeGoal, dispatch, stateRef, getSessionId) {
38626
- useEffect63(() => {
39363
+ useEffect64(() => {
38627
39364
  if (!subscribeGoal) return;
38628
39365
  const isCurrentSession2 = (sessionId) => {
38629
39366
  const current = getSessionId?.();
@@ -38845,7 +39582,7 @@ import {
38845
39582
  setDesignOverrides
38846
39583
  } from "@wrongstack/core/design";
38847
39584
  import { toErrorMessage as toErrorMessage9 } from "@wrongstack/core/utils";
38848
- import { useEffect as useEffect64 } from "react";
39585
+ import { useEffect as useEffect65 } from "react";
38849
39586
  function useTuiSlashCommands({
38850
39587
  slashRegistry,
38851
39588
  getPickableProviders,
@@ -38866,7 +39603,7 @@ function useTuiSlashCommands({
38866
39603
  switchAutonomy,
38867
39604
  listSessions
38868
39605
  }) {
38869
- useEffect64(() => {
39606
+ useEffect65(() => {
38870
39607
  if (!getPickableProviders || !switchProviderAndModel) return;
38871
39608
  const cmd = {
38872
39609
  name: "model",
@@ -38882,7 +39619,7 @@ function useTuiSlashCommands({
38882
39619
  slashRegistry.unregister("model");
38883
39620
  };
38884
39621
  }, [slashRegistry, getPickableProviders, switchProviderAndModel, openModelPicker]);
38885
- useEffect64(() => {
39622
+ useEffect65(() => {
38886
39623
  const cmd = {
38887
39624
  name: "f",
38888
39625
  description: "Open F-key panel picker. Arrow keys to navigate, Enter to open, Esc to close.",
@@ -38896,7 +39633,7 @@ function useTuiSlashCommands({
38896
39633
  slashRegistry.unregister("f");
38897
39634
  };
38898
39635
  }, [slashRegistry, openFKeyPicker]);
38899
- useEffect64(() => {
39636
+ useEffect65(() => {
38900
39637
  const cmd = {
38901
39638
  name: "design",
38902
39639
  description: "Design Studio: /design (picker) | <kit> [stack] | off | foundations | set <k=v> | tune <k=v> | swap <kit> | materialize [stack] [path] | verify.",
@@ -39028,7 +39765,7 @@ ${menu}` };
39028
39765
  slashRegistry.unregister("design");
39029
39766
  };
39030
39767
  }, [slashRegistry, projectRoot, agent]);
39031
- useEffect64(() => {
39768
+ useEffect65(() => {
39032
39769
  if (!getSettings || !saveSettings) return;
39033
39770
  const cmd = {
39034
39771
  name: "settings",
@@ -39135,7 +39872,7 @@ Available chords:
39135
39872
  slashRegistry.unregister("settings");
39136
39873
  };
39137
39874
  }, [slashRegistry, getSettings, saveSettings, openSettings, dispatch]);
39138
- useEffect64(() => {
39875
+ useEffect65(() => {
39139
39876
  const cmd = {
39140
39877
  name: "settings-get",
39141
39878
  aliases: ["config-get", "get"],
@@ -39167,7 +39904,7 @@ Available chords:
39167
39904
  slashRegistry.unregister("settings-get");
39168
39905
  };
39169
39906
  }, [slashRegistry, state.settingsPicker]);
39170
- useEffect64(() => {
39907
+ useEffect65(() => {
39171
39908
  const cmd = {
39172
39909
  name: "statusline",
39173
39910
  aliases: ["sl"],
@@ -39220,7 +39957,7 @@ Available chords:
39220
39957
  slashRegistry.unregister("statusline");
39221
39958
  };
39222
39959
  }, [slashRegistry, openStatuslinePicker, setHiddenItems]);
39223
- useEffect64(() => {
39960
+ useEffect65(() => {
39224
39961
  const cmd = {
39225
39962
  name: "mailbox",
39226
39963
  aliases: ["inbox", "mail"],
@@ -39235,7 +39972,7 @@ Available chords:
39235
39972
  slashRegistry.unregister("mailbox");
39236
39973
  };
39237
39974
  }, [slashRegistry]);
39238
- useEffect64(() => {
39975
+ useEffect65(() => {
39239
39976
  if (!switchAutonomy) return;
39240
39977
  const cmd = {
39241
39978
  name: "autonomy",
@@ -39251,7 +39988,7 @@ Available chords:
39251
39988
  slashRegistry.unregister("autonomy");
39252
39989
  };
39253
39990
  }, [slashRegistry, switchAutonomy]);
39254
- useEffect64(() => {
39991
+ useEffect65(() => {
39255
39992
  const cmd = {
39256
39993
  name: "theme",
39257
39994
  description: "Pick a TUI color theme preset interactively (picker).",
@@ -39283,7 +40020,7 @@ Available chords:
39283
40020
  slashRegistry.unregister("theme");
39284
40021
  };
39285
40022
  }, [slashRegistry, dispatch]);
39286
- useEffect64(() => {
40023
+ useEffect65(() => {
39287
40024
  const cmd = {
39288
40025
  name: "resume",
39289
40026
  aliases: ["load"],
@@ -39315,7 +40052,7 @@ Available chords:
39315
40052
 
39316
40053
  // src/hooks/use-working-dir-chip.ts
39317
40054
  import * as path6 from "node:path";
39318
- import { useEffect as useEffect65, useState as useState37 } from "react";
40055
+ import { useEffect as useEffect66, useState as useState37 } from "react";
39319
40056
  function formatWorkingDirChip(workingDir, projectRoot) {
39320
40057
  if (!workingDir || workingDir === projectRoot) return void 0;
39321
40058
  const impl = workingDir.includes("\\") || projectRoot.includes("\\") ? path6.win32 : path6;
@@ -39327,7 +40064,7 @@ function useWorkingDirChip(ctx, projectRoot) {
39327
40064
  const [workingDirChip, setWorkingDirChip] = useState37(
39328
40065
  () => formatWorkingDirChip(ctx.workingDir, projectRoot)
39329
40066
  );
39330
- useEffect65(() => {
40067
+ useEffect66(() => {
39331
40068
  setWorkingDirChip(formatWorkingDirChip(ctx.workingDir, projectRoot));
39332
40069
  return ctx.onWorkingDirChanged((newDir) => {
39333
40070
  setWorkingDirChip(formatWorkingDirChip(newDir, projectRoot));
@@ -41741,7 +42478,7 @@ function App(props) {
41741
42478
  liveSettings,
41742
42479
  mailbox.mailboxPanelOpen
41743
42480
  );
41744
- useEffect66(() => {
42481
+ useEffect67(() => {
41745
42482
  titleController?.setModel(liveModel);
41746
42483
  }, [titleController, liveModel]);
41747
42484
  const activity = useTuiActivity({
@@ -41778,7 +42515,7 @@ function App(props) {
41778
42515
  dispatch,
41779
42516
  open: state.authPanel.open
41780
42517
  });
41781
- useEffect66(() => {
42518
+ useEffect67(() => {
41782
42519
  if (!secretInputController) return;
41783
42520
  const previousSecret = secretInputController.readSecret;
41784
42521
  const previousText = secretInputController.readText;
@@ -41875,7 +42612,7 @@ function App(props) {
41875
42612
  dispatch({ type: "clearInput" });
41876
42613
  };
41877
42614
  const staleGuardRef = useRef38(JSON.stringify({ a: "", y: false, m: "", model: "", provider: "" }));
41878
- useEffect66(() => {
42615
+ useEffect67(() => {
41879
42616
  const poll = () => {
41880
42617
  const a = getAutonomy?.() ?? "off";
41881
42618
  const y = getYolo?.() ?? false;