@aiwayds/dsh-opentui 0.4.2 → 0.5.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.
@@ -1,5 +1,8 @@
1
+ import { createRequire } from "node:module";
2
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
3
+
1
4
  // src/host-entry.tsx
2
- import { createComponent as _$createComponent16 } from "@opentui/solid";
5
+ import { createComponent as _$createComponent18 } from "@opentui/solid";
3
6
  import { spawn } from "node:child_process";
4
7
  import { render } from "@opentui/solid";
5
8
 
@@ -148,16 +151,16 @@ function createI18n(locale = "zh-CN") {
148
151
  }
149
152
 
150
153
  // src/ShellHost.tsx
151
- import { effect as _$effect16 } from "@opentui/solid";
154
+ import { effect as _$effect18 } from "@opentui/solid";
152
155
  import { createTextNode as _$createTextNode11 } from "@opentui/solid";
153
156
  import { insertNode as _$insertNode13 } from "@opentui/solid";
154
157
  import { mergeProps as _$mergeProps } from "@opentui/solid";
155
- import { insert as _$insert16 } from "@opentui/solid";
156
- import { createComponent as _$createComponent15 } from "@opentui/solid";
158
+ import { insert as _$insert18 } from "@opentui/solid";
159
+ import { createComponent as _$createComponent17 } from "@opentui/solid";
157
160
  import { memo as _$memo9 } from "@opentui/solid";
158
- import { setProp as _$setProp16 } from "@opentui/solid";
159
- import { createElement as _$createElement16 } from "@opentui/solid";
160
- import { For as For12, createMemo, createSignal as createSignal4, onCleanup, onMount } from "solid-js";
161
+ import { setProp as _$setProp18 } from "@opentui/solid";
162
+ import { createElement as _$createElement18 } from "@opentui/solid";
163
+ import { For as For14, createMemo, createSignal as createSignal6, onCleanup as onCleanup3, onMount } from "solid-js";
161
164
  import { SyntaxStyle } from "@opentui/core";
162
165
  import { useKeyboard as useKeyboard2, useRenderer } from "@opentui/solid";
163
166
  // ../kit/src/themes-data.ts
@@ -564,6 +567,620 @@ var generatedThemes = {
564
567
  "tokyo-night": tokyoNight
565
568
  };
566
569
 
570
+ // ../kit/src/themes-opencode.ts
571
+ var oc_amoled = {
572
+ name: "amoled",
573
+ dark: true,
574
+ tokens: {
575
+ accent: "#b388ff",
576
+ dim: "#000000",
577
+ danger: "#ff1744",
578
+ ok: "#00ff88",
579
+ warn: "#ffea00",
580
+ text: "#ffffff",
581
+ border: "#000000",
582
+ selection: "#000000",
583
+ thinking: "#ff4081",
584
+ toolOk: "#00ff88",
585
+ toolFail: "#ff1744"
586
+ }
587
+ };
588
+ var oc_aura = {
589
+ name: "aura",
590
+ dark: true,
591
+ tokens: {
592
+ accent: "#a277ff",
593
+ dim: "#15141b",
594
+ danger: "#ff6767",
595
+ ok: "#61ffca",
596
+ warn: "#ffca85",
597
+ text: "#edecee",
598
+ border: "#15141b",
599
+ selection: "#15141b",
600
+ thinking: "#ff6767",
601
+ toolOk: "#61ffca",
602
+ toolFail: "#ff6767"
603
+ }
604
+ };
605
+ var oc_ayu = {
606
+ name: "ayu",
607
+ dark: true,
608
+ tokens: {
609
+ accent: "#3fb7e3",
610
+ dim: "#0f1419",
611
+ danger: "#f58572",
612
+ ok: "#78d05c",
613
+ warn: "#e4a75c",
614
+ text: "#d6dae0",
615
+ border: "#0f1419",
616
+ selection: "#0f1419",
617
+ thinking: "#f2856f",
618
+ toolOk: "#78d05c",
619
+ toolFail: "#f58572"
620
+ }
621
+ };
622
+ var oc_carbonfox = {
623
+ name: "carbonfox",
624
+ dark: true,
625
+ tokens: {
626
+ accent: "#33b1ff",
627
+ dim: "#393939",
628
+ danger: "#ff8389",
629
+ ok: "#42be65",
630
+ warn: "#f1c21b",
631
+ text: "#f2f4f8",
632
+ border: "#393939",
633
+ selection: "#393939",
634
+ thinking: "#ff8389",
635
+ toolOk: "#42be65",
636
+ toolFail: "#ff8389"
637
+ }
638
+ };
639
+ var oc_catppuccin_frappe = {
640
+ name: "catppuccin-frappe",
641
+ dark: true,
642
+ tokens: {
643
+ accent: "#8caaee",
644
+ dim: "#303446",
645
+ danger: "#e78284",
646
+ ok: "#a6d189",
647
+ warn: "#e5c890",
648
+ text: "#c6d0f5",
649
+ border: "#303446",
650
+ selection: "#303446",
651
+ thinking: "#f4b8e4",
652
+ toolOk: "#a6d189",
653
+ toolFail: "#e78284"
654
+ }
655
+ };
656
+ var oc_catppuccin_macchiato = {
657
+ name: "catppuccin-macchiato",
658
+ dark: true,
659
+ tokens: {
660
+ accent: "#8aadf4",
661
+ dim: "#24273a",
662
+ danger: "#ed8796",
663
+ ok: "#a6da95",
664
+ warn: "#eed49f",
665
+ text: "#cad3f5",
666
+ border: "#24273a",
667
+ selection: "#24273a",
668
+ thinking: "#f5bde6",
669
+ toolOk: "#a6da95",
670
+ toolFail: "#ed8796"
671
+ }
672
+ };
673
+ var oc_catppuccin = {
674
+ name: "catppuccin",
675
+ dark: true,
676
+ tokens: {
677
+ accent: "#b4befe",
678
+ dim: "#1e1e2e",
679
+ danger: "#f38ba8",
680
+ ok: "#a6e3a1",
681
+ warn: "#f9e2af",
682
+ text: "#cdd6f4",
683
+ border: "#1e1e2e",
684
+ selection: "#1e1e2e",
685
+ thinking: "#f38ba8",
686
+ toolOk: "#a6e3a1",
687
+ toolFail: "#f38ba8"
688
+ }
689
+ };
690
+ var oc_cobalt2 = {
691
+ name: "cobalt2",
692
+ dark: true,
693
+ tokens: {
694
+ accent: "#0088ff",
695
+ dim: "#193549",
696
+ danger: "#ff0088",
697
+ ok: "#9eff80",
698
+ warn: "#ffc600",
699
+ text: "#ffffff",
700
+ border: "#193549",
701
+ selection: "#193549",
702
+ thinking: "#2affdf",
703
+ toolOk: "#9eff80",
704
+ toolFail: "#ff0088"
705
+ }
706
+ };
707
+ var oc_cursor = {
708
+ name: "cursor",
709
+ dark: true,
710
+ tokens: {
711
+ accent: "#88c0d0",
712
+ dim: "#181818",
713
+ danger: "#e34671",
714
+ ok: "#3fa266",
715
+ warn: "#f1b467",
716
+ text: "#e4e4e4",
717
+ border: "#181818",
718
+ selection: "#181818",
719
+ thinking: "#88c0d0",
720
+ toolOk: "#3fa266",
721
+ toolFail: "#e34671"
722
+ }
723
+ };
724
+ var oc_dracula = {
725
+ name: "dracula",
726
+ dark: true,
727
+ tokens: {
728
+ accent: "#bd93f9",
729
+ dim: "#1d1e28",
730
+ danger: "#ff5555",
731
+ ok: "#50fa7b",
732
+ warn: "#ffb86c",
733
+ text: "#f8f8f2",
734
+ border: "#1d1e28",
735
+ selection: "#1d1e28",
736
+ thinking: "#ff79c6",
737
+ toolOk: "#50fa7b",
738
+ toolFail: "#ff5555"
739
+ }
740
+ };
741
+ var oc_everforest = {
742
+ name: "everforest",
743
+ dark: true,
744
+ tokens: {
745
+ accent: "#a7c080",
746
+ dim: "#2d353b",
747
+ danger: "#e67e80",
748
+ ok: "#a7c080",
749
+ warn: "#e69875",
750
+ text: "#d3c6aa",
751
+ border: "#2d353b",
752
+ selection: "#2d353b",
753
+ thinking: "#d699b6",
754
+ toolOk: "#a7c080",
755
+ toolFail: "#e67e80"
756
+ }
757
+ };
758
+ var oc_flexoki = {
759
+ name: "flexoki",
760
+ dark: true,
761
+ tokens: {
762
+ accent: "#DA702C",
763
+ dim: "#100F0F",
764
+ danger: "#D14D41",
765
+ ok: "#879A39",
766
+ warn: "#DA702C",
767
+ text: "#CECDC3",
768
+ border: "#100F0F",
769
+ selection: "#100F0F",
770
+ thinking: "#8B7EC8",
771
+ toolOk: "#879A39",
772
+ toolFail: "#D14D41"
773
+ }
774
+ };
775
+ var oc_github = {
776
+ name: "github",
777
+ dark: true,
778
+ tokens: {
779
+ accent: "#58a6ff",
780
+ dim: "#0d1117",
781
+ danger: "#f85149",
782
+ ok: "#3fb950",
783
+ warn: "#e3b341",
784
+ text: "#c9d1d9",
785
+ border: "#0d1117",
786
+ selection: "#0d1117",
787
+ thinking: "#39c5cf",
788
+ toolOk: "#3fb950",
789
+ toolFail: "#f85149"
790
+ }
791
+ };
792
+ var oc_gruvbox = {
793
+ name: "gruvbox",
794
+ dark: true,
795
+ tokens: {
796
+ accent: "#83a598",
797
+ dim: "#282828",
798
+ danger: "#fb4934",
799
+ ok: "#b8bb26",
800
+ warn: "#fabd2f",
801
+ text: "#ebdbb2",
802
+ border: "#282828",
803
+ selection: "#282828",
804
+ thinking: "#fb4934",
805
+ toolOk: "#b8bb26",
806
+ toolFail: "#fb4934"
807
+ }
808
+ };
809
+ var oc_kanagawa = {
810
+ name: "kanagawa",
811
+ dark: true,
812
+ tokens: {
813
+ accent: "#7E9CD8",
814
+ dim: "#1F1F28",
815
+ danger: "#E82424",
816
+ ok: "#98BB6C",
817
+ warn: "#D7A657",
818
+ text: "#DCD7BA",
819
+ border: "#1F1F28",
820
+ selection: "#1F1F28",
821
+ thinking: "#D27E99",
822
+ toolOk: "#98BB6C",
823
+ toolFail: "#E82424"
824
+ }
825
+ };
826
+ var oc_lucent_orng = {
827
+ name: "lucent-orng",
828
+ dark: true,
829
+ tokens: {
830
+ accent: "#EC5B2B",
831
+ dim: "#2a1a15",
832
+ danger: "#e06c75",
833
+ ok: "#6ba1e6",
834
+ warn: "#EC5B2B",
835
+ text: "#eeeeee",
836
+ border: "#2a1a15",
837
+ selection: "#2a1a15",
838
+ thinking: "#FFF7F1",
839
+ toolOk: "#6ba1e6",
840
+ toolFail: "#e06c75"
841
+ }
842
+ };
843
+ var oc_material = {
844
+ name: "material",
845
+ dark: true,
846
+ tokens: {
847
+ accent: "#82aaff",
848
+ dim: "#263238",
849
+ danger: "#f07178",
850
+ ok: "#c3e88d",
851
+ warn: "#ffcb6b",
852
+ text: "#eeffff",
853
+ border: "#263238",
854
+ selection: "#263238",
855
+ thinking: "#89ddff",
856
+ toolOk: "#c3e88d",
857
+ toolFail: "#f07178"
858
+ }
859
+ };
860
+ var oc_matrix = {
861
+ name: "matrix",
862
+ dark: true,
863
+ tokens: {
864
+ accent: "#2eff6a",
865
+ dim: "#0a0e0a",
866
+ danger: "#ff4b4b",
867
+ ok: "#62ff94",
868
+ warn: "#e6ff57",
869
+ text: "#62ff94",
870
+ border: "#0a0e0a",
871
+ selection: "#0a0e0a",
872
+ thinking: "#c770ff",
873
+ toolOk: "#62ff94",
874
+ toolFail: "#ff4b4b"
875
+ }
876
+ };
877
+ var oc_mercury = {
878
+ name: "mercury",
879
+ dark: true,
880
+ tokens: {
881
+ accent: "#8da4f5",
882
+ dim: "#171721",
883
+ danger: "#fc92b4",
884
+ ok: "#77c599",
885
+ warn: "#fc9b6f",
886
+ text: "#dddde5",
887
+ border: "#171721",
888
+ selection: "#171721",
889
+ thinking: "#8da4f5",
890
+ toolOk: "#77c599",
891
+ toolFail: "#fc92b4"
892
+ }
893
+ };
894
+ var oc_monokai = {
895
+ name: "monokai",
896
+ dark: true,
897
+ tokens: {
898
+ accent: "#ae81ff",
899
+ dim: "#272822",
900
+ danger: "#f92672",
901
+ ok: "#a6e22e",
902
+ warn: "#fd971f",
903
+ text: "#f8f8f2",
904
+ border: "#272822",
905
+ selection: "#272822",
906
+ thinking: "#f92672",
907
+ toolOk: "#a6e22e",
908
+ toolFail: "#f92672"
909
+ }
910
+ };
911
+ var oc_nightowl = {
912
+ name: "nightowl",
913
+ dark: true,
914
+ tokens: {
915
+ accent: "#82aaff",
916
+ dim: "#011627",
917
+ danger: "#ef5350",
918
+ ok: "#c5e478",
919
+ warn: "#ecc48d",
920
+ text: "#d6deeb",
921
+ border: "#011627",
922
+ selection: "#011627",
923
+ thinking: "#f78c6c",
924
+ toolOk: "#c5e478",
925
+ toolFail: "#ef5350"
926
+ }
927
+ };
928
+ var oc_nord = {
929
+ name: "nord",
930
+ dark: true,
931
+ tokens: {
932
+ accent: "#88c0d0",
933
+ dim: "#2e3440",
934
+ danger: "#bf616a",
935
+ ok: "#a3be8c",
936
+ warn: "#d08770",
937
+ text: "#e5e9f0",
938
+ border: "#2e3440",
939
+ selection: "#2e3440",
940
+ thinking: "#d57780",
941
+ toolOk: "#a3be8c",
942
+ toolFail: "#bf616a"
943
+ }
944
+ };
945
+ var oc_oc_2 = {
946
+ name: "oc-2",
947
+ dark: true,
948
+ tokens: {
949
+ accent: "#fab283",
950
+ dim: "#1f1f1f",
951
+ danger: "#fc533a",
952
+ ok: "#12c905",
953
+ warn: "#fcd53a",
954
+ text: "#f1ece8",
955
+ border: "#1f1f1f",
956
+ selection: "#1f1f1f",
957
+ toolOk: "#12c905",
958
+ toolFail: "#fc533a"
959
+ }
960
+ };
961
+ var oc_one_dark = {
962
+ name: "one-dark",
963
+ dark: true,
964
+ tokens: {
965
+ accent: "#61afef",
966
+ dim: "#282c34",
967
+ danger: "#e06c75",
968
+ ok: "#98c379",
969
+ warn: "#e5c07b",
970
+ text: "#abb2bf",
971
+ border: "#282c34",
972
+ selection: "#282c34",
973
+ thinking: "#56b6c2",
974
+ toolOk: "#98c379",
975
+ toolFail: "#e06c75"
976
+ }
977
+ };
978
+ var oc_onedarkpro = {
979
+ name: "onedarkpro",
980
+ dark: true,
981
+ tokens: {
982
+ accent: "#61afef",
983
+ dim: "#1e222a",
984
+ danger: "#e06c75",
985
+ ok: "#98c379",
986
+ warn: "#e5c07b",
987
+ text: "#abb2bf",
988
+ border: "#1e222a",
989
+ selection: "#1e222a",
990
+ thinking: "#e06c75",
991
+ toolOk: "#98c379",
992
+ toolFail: "#e06c75"
993
+ }
994
+ };
995
+ var oc_orng = {
996
+ name: "orng",
997
+ dark: true,
998
+ tokens: {
999
+ accent: "#EC5B2B",
1000
+ dim: "#0a0a0a",
1001
+ danger: "#e06c75",
1002
+ ok: "#6ba1e6",
1003
+ warn: "#EC5B2B",
1004
+ text: "#eeeeee",
1005
+ border: "#0a0a0a",
1006
+ selection: "#0a0a0a",
1007
+ thinking: "#FFF7F1",
1008
+ toolOk: "#6ba1e6",
1009
+ toolFail: "#e06c75"
1010
+ }
1011
+ };
1012
+ var oc_osaka_jade = {
1013
+ name: "osaka-jade",
1014
+ dark: true,
1015
+ tokens: {
1016
+ accent: "#2DD5B7",
1017
+ dim: "#111c18",
1018
+ danger: "#FF5345",
1019
+ ok: "#549e6a",
1020
+ warn: "#E5C736",
1021
+ text: "#C1C497",
1022
+ border: "#111c18",
1023
+ selection: "#111c18",
1024
+ thinking: "#549e6a",
1025
+ toolOk: "#549e6a",
1026
+ toolFail: "#FF5345"
1027
+ }
1028
+ };
1029
+ var oc_palenight = {
1030
+ name: "palenight",
1031
+ dark: true,
1032
+ tokens: {
1033
+ accent: "#82aaff",
1034
+ dim: "#292d3e",
1035
+ danger: "#f07178",
1036
+ ok: "#c3e88d",
1037
+ warn: "#ffcb6b",
1038
+ text: "#a6accd",
1039
+ border: "#292d3e",
1040
+ selection: "#292d3e",
1041
+ thinking: "#89ddff",
1042
+ toolOk: "#c3e88d",
1043
+ toolFail: "#f07178"
1044
+ }
1045
+ };
1046
+ var oc_rosepine = {
1047
+ name: "rosepine",
1048
+ dark: true,
1049
+ tokens: {
1050
+ accent: "#9ccfd8",
1051
+ dim: "#191724",
1052
+ danger: "#eb6f92",
1053
+ ok: "#31748f",
1054
+ warn: "#f6c177",
1055
+ text: "#e0def4",
1056
+ border: "#191724",
1057
+ selection: "#191724",
1058
+ thinking: "#ebbcba",
1059
+ toolOk: "#31748f",
1060
+ toolFail: "#eb6f92"
1061
+ }
1062
+ };
1063
+ var oc_shadesofpurple = {
1064
+ name: "shadesofpurple",
1065
+ dark: true,
1066
+ tokens: {
1067
+ accent: "#c792ff",
1068
+ dim: "#1a102b",
1069
+ danger: "#ff7ac6",
1070
+ ok: "#7be0b0",
1071
+ warn: "#ffd580",
1072
+ text: "#f5f0ff",
1073
+ border: "#1a102b",
1074
+ selection: "#1a102b",
1075
+ thinking: "#ff7ac6",
1076
+ toolOk: "#7be0b0",
1077
+ toolFail: "#ff7ac6"
1078
+ }
1079
+ };
1080
+ var oc_solarized = {
1081
+ name: "solarized",
1082
+ dark: true,
1083
+ tokens: {
1084
+ accent: "#6c71c4",
1085
+ dim: "#002b36",
1086
+ danger: "#dc322f",
1087
+ ok: "#859900",
1088
+ warn: "#b58900",
1089
+ text: "#93a1a1",
1090
+ border: "#002b36",
1091
+ selection: "#002b36",
1092
+ thinking: "#d33682",
1093
+ toolOk: "#859900",
1094
+ toolFail: "#dc322f"
1095
+ }
1096
+ };
1097
+ var oc_synthwave84 = {
1098
+ name: "synthwave84",
1099
+ dark: true,
1100
+ tokens: {
1101
+ accent: "#36f9f6",
1102
+ dim: "#262335",
1103
+ danger: "#fe4450",
1104
+ ok: "#72f1b8",
1105
+ warn: "#fede5d",
1106
+ text: "#ffffff",
1107
+ border: "#262335",
1108
+ selection: "#262335",
1109
+ thinking: "#b084eb",
1110
+ toolOk: "#72f1b8",
1111
+ toolFail: "#fe4450"
1112
+ }
1113
+ };
1114
+ var oc_tokyonight = {
1115
+ name: "tokyonight",
1116
+ dark: true,
1117
+ tokens: {
1118
+ accent: "#7aa2f7",
1119
+ dim: "#1a1b26",
1120
+ danger: "#f7768e",
1121
+ ok: "#9ece6a",
1122
+ warn: "#e0af68",
1123
+ text: "#c0caf5",
1124
+ border: "#1a1b26",
1125
+ selection: "#1a1b26",
1126
+ thinking: "#ff9e64",
1127
+ toolOk: "#9ece6a",
1128
+ toolFail: "#f7768e"
1129
+ }
1130
+ };
1131
+ var oc_vercel = {
1132
+ name: "vercel",
1133
+ dark: true,
1134
+ tokens: {
1135
+ accent: "#0070F3",
1136
+ dim: "#000000",
1137
+ danger: "#E5484D",
1138
+ ok: "#46A758",
1139
+ warn: "#FFB224",
1140
+ text: "#EDEDED",
1141
+ border: "#000000",
1142
+ selection: "#000000",
1143
+ thinking: "#8E4EC6",
1144
+ toolOk: "#46A758",
1145
+ toolFail: "#E5484D"
1146
+ }
1147
+ };
1148
+ var oc_vesper = {
1149
+ name: "vesper",
1150
+ dark: true,
1151
+ tokens: {
1152
+ accent: "#FFC799",
1153
+ dim: "#101010",
1154
+ danger: "#FF8080",
1155
+ ok: "#99FFE4",
1156
+ warn: "#FFC799",
1157
+ text: "#FFF",
1158
+ border: "#101010",
1159
+ selection: "#101010",
1160
+ thinking: "#FF8080",
1161
+ toolOk: "#99FFE4",
1162
+ toolFail: "#FF8080"
1163
+ }
1164
+ };
1165
+ var oc_zenburn = {
1166
+ name: "zenburn",
1167
+ dark: true,
1168
+ tokens: {
1169
+ accent: "#8cd0d3",
1170
+ dim: "#3f3f3f",
1171
+ danger: "#cc9393",
1172
+ ok: "#7f9f7f",
1173
+ warn: "#f0dfaf",
1174
+ text: "#dcdccc",
1175
+ border: "#3f3f3f",
1176
+ selection: "#3f3f3f",
1177
+ thinking: "#93e0e3",
1178
+ toolOk: "#7f9f7f",
1179
+ toolFail: "#cc9393"
1180
+ }
1181
+ };
1182
+ var opencodeThemes = [oc_amoled, oc_aura, oc_ayu, oc_carbonfox, oc_catppuccin_frappe, oc_catppuccin_macchiato, oc_catppuccin, oc_cobalt2, oc_cursor, oc_dracula, oc_everforest, oc_flexoki, oc_github, oc_gruvbox, oc_kanagawa, oc_lucent_orng, oc_material, oc_matrix, oc_mercury, oc_monokai, oc_nightowl, oc_nord, oc_oc_2, oc_one_dark, oc_onedarkpro, oc_orng, oc_osaka_jade, oc_palenight, oc_rosepine, oc_shadesofpurple, oc_solarized, oc_synthwave84, oc_tokyonight, oc_vercel, oc_vesper, oc_zenburn];
1183
+
567
1184
  // ../kit/src/theme.ts
568
1185
  var defaultTheme = {
569
1186
  name: "default",
@@ -599,6 +1216,7 @@ var catppuccinMocha2 = {
599
1216
  var themes = {
600
1217
  default: defaultTheme,
601
1218
  ...generatedThemes,
1219
+ ...Object.fromEntries(opencodeThemes.map((t) => [t.name, t])),
602
1220
  "catppuccin-mocha": catppuccinMocha2
603
1221
  };
604
1222
  function getTheme(name) {
@@ -621,12 +1239,12 @@ import { For } from "solid-js";
621
1239
  // ../kit/src/shell-parts.tsx
622
1240
  import { use as _$use } from "@opentui/solid";
623
1241
  import { memo as _$memo } from "@opentui/solid";
624
- import { createComponent as _$createComponent2 } from "@opentui/solid";
625
- import { setProp as _$setProp2 } from "@opentui/solid";
626
- import { effect as _$effect2 } from "@opentui/solid";
627
- import { insert as _$insert2 } from "@opentui/solid";
628
1242
  import { createTextNode as _$createTextNode2 } from "@opentui/solid";
629
1243
  import { insertNode as _$insertNode2 } from "@opentui/solid";
1244
+ import { effect as _$effect2 } from "@opentui/solid";
1245
+ import { insert as _$insert2 } from "@opentui/solid";
1246
+ import { createComponent as _$createComponent2 } from "@opentui/solid";
1247
+ import { setProp as _$setProp2 } from "@opentui/solid";
630
1248
  import { createElement as _$createElement2 } from "@opentui/solid";
631
1249
  import { createEffect, For as For2, on, Show } from "solid-js";
632
1250
  import { defaultTextareaKeyBindings } from "@opentui/core";
@@ -723,6 +1341,115 @@ function itemsToLines(items, theme, t, spinnerFrame, _mdStyle) {
723
1341
  }
724
1342
  return out;
725
1343
  }
1344
+ var itemNode = (it, theme, t, mdStyle, spinnerFrame = "") => {
1345
+ const th = theme;
1346
+ if (it.kind === "user") {
1347
+ return (() => {
1348
+ var _el$3 = _$createElement2("text"), _el$4 = _$createTextNode2(`❯ `);
1349
+ _$insertNode2(_el$3, _el$4);
1350
+ _$insert2(_el$3, () => it.text, null);
1351
+ _$effect2((_$p) => _$setProp2(_el$3, "style", {
1352
+ fg: th.tokens.userMark ?? th.tokens.accent
1353
+ }, _$p));
1354
+ return _el$3;
1355
+ })();
1356
+ }
1357
+ if (it.kind === "assistant") {
1358
+ if (it.final) {
1359
+ return (() => {
1360
+ var _el$5 = _$createElement2("box"), _el$6 = _$createElement2("markdown"), _el$7 = _$createElement2("text");
1361
+ _$insertNode2(_el$5, _el$6);
1362
+ _$insertNode2(_el$5, _el$7);
1363
+ _$setProp2(_el$5, "style", {
1364
+ flexDirection: "column"
1365
+ });
1366
+ _$setProp2(_el$6, "streaming", false);
1367
+ _$setProp2(_el$6, "syntaxStyle", mdStyle);
1368
+ _$insertNode2(_el$7, _$createTextNode2(` `));
1369
+ _$effect2((_$p) => _$setProp2(_el$6, "content", it.text, _$p));
1370
+ return _el$5;
1371
+ })();
1372
+ }
1373
+ return (() => {
1374
+ var _el$9 = _$createElement2("box");
1375
+ _$setProp2(_el$9, "style", {
1376
+ flexDirection: "column"
1377
+ });
1378
+ _$insert2(_el$9, _$createComponent2(For2, {
1379
+ get each() {
1380
+ return renderAssistant(it.text, th);
1381
+ },
1382
+ children: (l) => (() => {
1383
+ var _el$0 = _$createElement2("text");
1384
+ _$insert2(_el$0, () => `┃ ${l.text || " "}`);
1385
+ _$effect2((_$p) => _$setProp2(_el$0, "style", l.fg ? {
1386
+ fg: l.fg
1387
+ } : {}, _$p));
1388
+ return _el$0;
1389
+ })()
1390
+ }));
1391
+ return _el$9;
1392
+ })();
1393
+ }
1394
+ if (it.kind === "thinking") {
1395
+ return (() => {
1396
+ var _el$1 = _$createElement2("text");
1397
+ _$insert2(_el$1, () => `${spinnerFrame} ${t("agent.thinking")} (${it.chars}) ${it.tail.slice(-120)}`);
1398
+ _$effect2((_$p) => _$setProp2(_el$1, "style", {
1399
+ fg: th.tokens.dim
1400
+ }, _$p));
1401
+ return _el$1;
1402
+ })();
1403
+ }
1404
+ if (it.kind === "tool") {
1405
+ return (() => {
1406
+ var _el$10 = _$createElement2("box"), _el$11 = _$createElement2("text"), _el$12 = _$createElement2("text");
1407
+ _$insertNode2(_el$10, _el$11);
1408
+ _$insertNode2(_el$10, _el$12);
1409
+ _$setProp2(_el$10, "style", {
1410
+ flexDirection: "column"
1411
+ });
1412
+ _$insert2(_el$11, () => ` ⚒ ${it.name} ${it.args.slice(0, 90)}`);
1413
+ _$insert2(_el$12, () => ` ⎿ ${it.ok ? t("agent.tool.ok") : t("agent.tool.fail")}: ${it.brief.slice(0, 110)}`);
1414
+ _$effect2((_p$) => {
1415
+ var _v$ = {
1416
+ fg: th.tokens.toolOk ?? th.tokens.warn
1417
+ }, _v$2 = {
1418
+ fg: it.ok ? th.tokens.dim : th.tokens.toolFail ?? th.tokens.danger
1419
+ };
1420
+ _v$ !== _p$.e && (_p$.e = _$setProp2(_el$11, "style", _v$, _p$.e));
1421
+ _v$2 !== _p$.t && (_p$.t = _$setProp2(_el$12, "style", _v$2, _p$.t));
1422
+ return _p$;
1423
+ }, {
1424
+ e: undefined,
1425
+ t: undefined
1426
+ });
1427
+ return _el$10;
1428
+ })();
1429
+ }
1430
+ if (it.kind === "error") {
1431
+ return (() => {
1432
+ var _el$13 = _$createElement2("text"), _el$14 = _$createTextNode2(`✗ `), _el$15 = _$createTextNode2(`: `);
1433
+ _$insertNode2(_el$13, _el$14);
1434
+ _$insertNode2(_el$13, _el$15);
1435
+ _$insert2(_el$13, () => t("agent.error"), _el$15);
1436
+ _$insert2(_el$13, () => it.text, null);
1437
+ _$effect2((_$p) => _$setProp2(_el$13, "style", {
1438
+ fg: th.tokens.danger
1439
+ }, _$p));
1440
+ return _el$13;
1441
+ })();
1442
+ }
1443
+ return (() => {
1444
+ var _el$16 = _$createElement2("text"), _el$17 = _$createTextNode2(`· `);
1445
+ _$insertNode2(_el$16, _el$17);
1446
+ _$insert2(_el$16, () => it.text, null);
1447
+ _$effect2((_$p) => _$setProp2(_el$16, "style", {
1448
+ fg: th.tokens.dim
1449
+ }, _$p));
1450
+ return _el$16;
1451
+ })();
1452
+ };
726
1453
  function TranscriptWindow(props) {
727
1454
  const offset = () => props.offset ?? 0;
728
1455
  const windowLines = () => {
@@ -738,41 +1465,68 @@ function TranscriptWindow(props) {
738
1465
  const end = Math.max(1, all.length - offset());
739
1466
  return all.slice(start, end);
740
1467
  };
1468
+ if (props.startIndex === undefined && (props.offset ?? 0) === 0) {
1469
+ return (() => {
1470
+ var _el$18 = _$createElement2("box");
1471
+ _$setProp2(_el$18, "style", {
1472
+ flexDirection: "column",
1473
+ flexGrow: 1,
1474
+ justifyContent: "flex-end",
1475
+ padding: 1
1476
+ });
1477
+ _$insert2(_el$18, _$createComponent2(For2, {
1478
+ get each() {
1479
+ return props.items.slice(-(props.maxItems ?? MAX_VISIBLE_ITEMS));
1480
+ },
1481
+ children: (it) => (() => {
1482
+ var _el$19 = _$createElement2("box"), _el$20 = _$createElement2("text");
1483
+ _$insertNode2(_el$19, _el$20);
1484
+ _$setProp2(_el$19, "style", {
1485
+ flexDirection: "column"
1486
+ });
1487
+ _$insert2(_el$19, () => itemNode(it, props.theme, props.t, props.mdStyle, props.spinnerFrame), _el$20);
1488
+ _$insertNode2(_el$20, _$createTextNode2(` `));
1489
+ return _el$19;
1490
+ })()
1491
+ }));
1492
+ return _el$18;
1493
+ })();
1494
+ }
741
1495
  return (() => {
742
- var _el$18 = _$createElement2("box");
743
- _$setProp2(_el$18, "style", {
1496
+ var _el$22 = _$createElement2("box");
1497
+ _$setProp2(_el$22, "style", {
744
1498
  flexDirection: "column",
745
1499
  flexGrow: 1,
746
1500
  justifyContent: "flex-end",
747
1501
  padding: 1
748
1502
  });
749
- _$insert2(_el$18, _$createComponent2(For2, {
1503
+ _$insert2(_el$22, _$createComponent2(For2, {
750
1504
  get each() {
751
1505
  return windowLines();
752
1506
  },
753
1507
  children: (l) => (() => {
754
- var _el$21 = _$createElement2("text");
755
- _$insert2(_el$21, () => l.text || " ");
756
- _$effect2((_$p) => _$setProp2(_el$21, "style", l.fg ? {
1508
+ var _el$25 = _$createElement2("text");
1509
+ _$insert2(_el$25, () => l.text || " ");
1510
+ _$effect2((_$p) => _$setProp2(_el$25, "style", l.fg ? {
757
1511
  fg: l.fg
758
1512
  } : {}, _$p));
759
- return _el$21;
1513
+ return _el$25;
760
1514
  })()
761
1515
  }), null);
762
- _$insert2(_el$18, _$createComponent2(Show, {
1516
+ _$insert2(_el$22, _$createComponent2(Show, {
763
1517
  get when() {
764
1518
  return (props.offset ?? 0) > 0 || props.startIndex !== undefined;
765
1519
  },
766
1520
  get children() {
767
- var _el$19 = _$createElement2("text");
768
- _$insertNode2(_el$19, _$createTextNode2(`↑ scrolled (PgDn = follow latest)`));
769
- _$effect2((_$p) => _$setProp2(_el$19, "style", {
1521
+ var _el$23 = _$createElement2("text");
1522
+ _$insertNode2(_el$23, _$createTextNode2(`↑ scrolled (PgDn = follow latest)`));
1523
+ _$effect2((_$p) => _$setProp2(_el$23, "style", {
770
1524
  fg: props.theme.tokens.dim
771
1525
  }, _$p));
772
- return _el$19;
1526
+ return _el$23;
773
1527
  }
774
1528
  }), null);
775
- return _el$18;
1529
+ return _el$22;
776
1530
  })();
777
1531
  }
778
1532
  var INPUT_KEY_BINDINGS = [...defaultTextareaKeyBindings, {
@@ -836,53 +1590,53 @@ function InputLine(props) {
836
1590
  }
837
1591
  };
838
1592
  return (() => {
839
- var _el$22 = _$createElement2("box"), _el$23 = _$createElement2("box"), _el$24 = _$createElement2("text"), _el$26 = _$createElement2("textarea");
840
- _$insertNode2(_el$22, _el$23);
841
- _$insertNode2(_el$23, _el$24);
842
- _$insertNode2(_el$23, _el$26);
843
- _$setProp2(_el$23, "style", {
1593
+ var _el$26 = _$createElement2("box"), _el$27 = _$createElement2("box"), _el$28 = _$createElement2("text"), _el$30 = _$createElement2("textarea");
1594
+ _$insertNode2(_el$26, _el$27);
1595
+ _$insertNode2(_el$27, _el$28);
1596
+ _$insertNode2(_el$27, _el$30);
1597
+ _$setProp2(_el$27, "style", {
844
1598
  flexDirection: "row"
845
1599
  });
846
- _$insertNode2(_el$24, _$createTextNode2(`❯ `));
847
- _$use((el) => ta = el, _el$26);
848
- _$setProp2(_el$26, "keyBindings", INPUT_KEY_BINDINGS);
849
- _$setProp2(_el$26, "onContentChange", () => props.onContentChange?.(ta?.plainText ?? ""));
850
- _$setProp2(_el$26, "onSubmit", () => props.onSubmit?.());
851
- _$setProp2(_el$26, "onKeyDown", onKeyDown);
852
- _$insert2(_el$22, _$createComponent2(Show, {
1600
+ _$insertNode2(_el$28, _$createTextNode2(`❯ `));
1601
+ _$use((el) => ta = el, _el$30);
1602
+ _$setProp2(_el$30, "keyBindings", INPUT_KEY_BINDINGS);
1603
+ _$setProp2(_el$30, "onContentChange", () => props.onContentChange?.(ta?.plainText ?? ""));
1604
+ _$setProp2(_el$30, "onSubmit", () => props.onSubmit?.());
1605
+ _$setProp2(_el$30, "onKeyDown", onKeyDown);
1606
+ _$insert2(_el$26, _$createComponent2(Show, {
853
1607
  get when() {
854
1608
  return props.busy;
855
1609
  },
856
1610
  get children() {
857
- var _el$27 = _$createElement2("text");
858
- _$insert2(_el$27, () => `${props.spinnerFrame ? `${props.spinnerFrame} ` : ""}${props.busyLabel}`);
859
- _$effect2((_$p) => _$setProp2(_el$27, "style", {
1611
+ var _el$31 = _$createElement2("text");
1612
+ _$insert2(_el$31, () => `${props.spinnerFrame ? `${props.spinnerFrame} ` : ""}${props.busyLabel}`);
1613
+ _$effect2((_$p) => _$setProp2(_el$31, "style", {
860
1614
  fg: props.theme.tokens.dim
861
1615
  }, _$p));
862
- return _el$27;
1616
+ return _el$31;
863
1617
  }
864
1618
  }), null);
865
1619
  _$effect2((_p$) => {
866
- var _v$5 = {
1620
+ var _v$3 = {
867
1621
  border: true,
868
1622
  borderStyle: "rounded",
869
1623
  borderColor: props.theme.tokens.border,
870
1624
  flexDirection: "column"
871
- }, _v$6 = {
1625
+ }, _v$4 = {
872
1626
  fg: props.theme.tokens.accent
873
- }, _v$7 = !props.busy && (props.focused ?? true), _v$8 = props.placeholder, _v$9 = props.theme.tokens.text, _v$0 = props.theme.tokens.text, _v$1 = props.theme.tokens.dim, _v$10 = {
1627
+ }, _v$5 = !props.busy && (props.focused ?? true), _v$6 = props.placeholder, _v$7 = props.theme.tokens.text, _v$8 = props.theme.tokens.text, _v$9 = props.theme.tokens.dim, _v$0 = {
874
1628
  flexGrow: 1,
875
1629
  height: props.height ?? 1,
876
1630
  wrapMode: "char"
877
1631
  };
878
- _v$5 !== _p$.e && (_p$.e = _$setProp2(_el$22, "style", _v$5, _p$.e));
879
- _v$6 !== _p$.t && (_p$.t = _$setProp2(_el$24, "style", _v$6, _p$.t));
880
- _v$7 !== _p$.a && (_p$.a = _$setProp2(_el$26, "focused", _v$7, _p$.a));
881
- _v$8 !== _p$.o && (_p$.o = _$setProp2(_el$26, "placeholder", _v$8, _p$.o));
882
- _v$9 !== _p$.i && (_p$.i = _$setProp2(_el$26, "textColor", _v$9, _p$.i));
883
- _v$0 !== _p$.n && (_p$.n = _$setProp2(_el$26, "focusedTextColor", _v$0, _p$.n));
884
- _v$1 !== _p$.s && (_p$.s = _$setProp2(_el$26, "placeholderColor", _v$1, _p$.s));
885
- _v$10 !== _p$.h && (_p$.h = _$setProp2(_el$26, "style", _v$10, _p$.h));
1632
+ _v$3 !== _p$.e && (_p$.e = _$setProp2(_el$26, "style", _v$3, _p$.e));
1633
+ _v$4 !== _p$.t && (_p$.t = _$setProp2(_el$28, "style", _v$4, _p$.t));
1634
+ _v$5 !== _p$.a && (_p$.a = _$setProp2(_el$30, "focused", _v$5, _p$.a));
1635
+ _v$6 !== _p$.o && (_p$.o = _$setProp2(_el$30, "placeholder", _v$6, _p$.o));
1636
+ _v$7 !== _p$.i && (_p$.i = _$setProp2(_el$30, "textColor", _v$7, _p$.i));
1637
+ _v$8 !== _p$.n && (_p$.n = _$setProp2(_el$30, "focusedTextColor", _v$8, _p$.n));
1638
+ _v$9 !== _p$.s && (_p$.s = _$setProp2(_el$30, "placeholderColor", _v$9, _p$.s));
1639
+ _v$0 !== _p$.h && (_p$.h = _$setProp2(_el$30, "style", _v$0, _p$.h));
886
1640
  return _p$;
887
1641
  }, {
888
1642
  e: undefined,
@@ -894,32 +1648,32 @@ function InputLine(props) {
894
1648
  s: undefined,
895
1649
  h: undefined
896
1650
  });
897
- return _el$22;
1651
+ return _el$26;
898
1652
  })();
899
1653
  }
900
1654
  function FooterHints(props) {
901
1655
  return (() => {
902
- var _el$28 = _$createElement2("box");
903
- _$setProp2(_el$28, "style", {
1656
+ var _el$32 = _$createElement2("box");
1657
+ _$setProp2(_el$32, "style", {
904
1658
  flexDirection: "row",
905
1659
  paddingLeft: 2,
906
1660
  paddingRight: 2
907
1661
  });
908
- _$insert2(_el$28, _$createComponent2(For2, {
1662
+ _$insert2(_el$32, _$createComponent2(For2, {
909
1663
  each: footerHints,
910
1664
  children: (h, i) => (() => {
911
- var _el$29 = _$createElement2("text"), _el$30 = _$createTextNode2(` `);
912
- _$insertNode2(_el$29, _el$30);
913
- _$insert2(_el$29, () => i() > 0 ? " · " : "", _el$30);
914
- _$insert2(_el$29, () => h.key, _el$30);
915
- _$insert2(_el$29, () => h.label, null);
916
- _$effect2((_$p) => _$setProp2(_el$29, "style", {
1665
+ var _el$33 = _$createElement2("text"), _el$34 = _$createTextNode2(` `);
1666
+ _$insertNode2(_el$33, _el$34);
1667
+ _$insert2(_el$33, () => i() > 0 ? " · " : "", _el$34);
1668
+ _$insert2(_el$33, () => h.key, _el$34);
1669
+ _$insert2(_el$33, () => h.label, null);
1670
+ _$effect2((_$p) => _$setProp2(_el$33, "style", {
917
1671
  fg: props.theme.tokens.dim
918
1672
  }, _$p));
919
- return _el$29;
1673
+ return _el$33;
920
1674
  })()
921
1675
  }));
922
- return _el$28;
1676
+ return _el$32;
923
1677
  })();
924
1678
  }
925
1679
  // ../kit/src/overlays.tsx
@@ -1357,35 +2111,23 @@ function SubagentWidget(props) {
1357
2111
  },
1358
2112
  get fallback() {
1359
2113
  return (() => {
1360
- var _el$3 = _$createElement9("text");
1361
- _$insert9(_el$3, () => `${branch()} ${glyph()} ${name()}${meta()}`);
1362
- _$effect9((_$p) => _$setProp9(_el$3, "style", {
2114
+ var _el$2 = _$createElement9("text");
2115
+ _$insert9(_el$2, () => `${branch()} ${glyph()} ${name()}${meta()}`);
2116
+ _$effect9((_$p) => _$setProp9(_el$2, "style", {
1363
2117
  fg: th().tokens.dim
1364
2118
  }, _$p));
1365
- return _el$3;
2119
+ return _el$2;
1366
2120
  })();
1367
2121
  },
1368
2122
  get children() {
1369
- return [(() => {
1370
- var _el$ = _$createElement9("text");
1371
- _$insert9(_el$, () => `${branch()} ${spinnerFrame(e.elapsed)} ${name()}${meta()}`);
1372
- _$effect9((_$p) => _$setProp9(_el$, "style", {
1373
- fg: th().tokens.accent
1374
- }, _$p));
1375
- return _el$;
1376
- })(), _$createComponent9(Show5, {
1377
- get when() {
1378
- return tailLine(e).length > 0;
1379
- },
1380
- get children() {
1381
- var _el$2 = _$createElement9("text");
1382
- _$insert9(_el$2, () => `│ ${tailLine(e)}`);
1383
- _$effect9((_$p) => _$setProp9(_el$2, "style", {
1384
- fg: th().tokens.dim
1385
- }, _$p));
1386
- return _el$2;
1387
- }
1388
- })];
2123
+ var _el$ = _$createElement9("text");
2124
+ _$insert9(_el$, () => `${branch()} ${spinnerFrame(e.elapsed)} ${name()}${meta()} ${tailLine(e)}`.trimEnd());
2125
+ _$effect9((_$p) => _$setProp9(_el$, "style", {
2126
+ fg: th().tokens.accent,
2127
+ wrapMode: "none",
2128
+ truncate: true
2129
+ }, _$p));
2130
+ return _el$;
1389
2131
  }
1390
2132
  });
1391
2133
  }
@@ -1433,14 +2175,14 @@ function Select(props) {
1433
2175
  }
1434
2176
  if (n === 0)
1435
2177
  return;
1436
- if (key.name === "up") {
2178
+ if (key.name === "up" || key.name === "left") {
1437
2179
  key.preventDefault?.();
1438
2180
  const v = (index() - 1 + n) % n;
1439
2181
  setIndex(v);
1440
2182
  props.onPreview?.(props.items[v]?.value ?? "");
1441
2183
  return;
1442
2184
  }
1443
- if (key.name === "down") {
2185
+ if (key.name === "down" || key.name === "right") {
1444
2186
  key.preventDefault?.();
1445
2187
  const v = (index() + 1) % n;
1446
2188
  setIndex(v);
@@ -1666,6 +2408,148 @@ function WidgetFrame(props) {
1666
2408
  }
1667
2409
  });
1668
2410
  }
2411
+ // ../kit/src/status-bar.tsx
2412
+ import { effect as _$effect14 } from "@opentui/solid";
2413
+ import { insert as _$insert14 } from "@opentui/solid";
2414
+ import { createComponent as _$createComponent13 } from "@opentui/solid";
2415
+ import { setProp as _$setProp14 } from "@opentui/solid";
2416
+ import { createElement as _$createElement14 } from "@opentui/solid";
2417
+ import { createSignal as createSignal2, onCleanup, For as For11, Show as Show8 } from "solid-js";
2418
+ var DEFAULT_VERBS = {
2419
+ think: ["Thinking", "Pondering", "Reasoning", "Reflecting", "Deliberating", "Mulling"],
2420
+ tool: ["Executing", "Running", "Processing", "Building"],
2421
+ stream: ["Writing", "Composing", "Typing", "Drafting"],
2422
+ approve: ["Waiting"]
2423
+ };
2424
+ var VERB_MS = 2500;
2425
+ var PHASE_ICON = {
2426
+ think: "\uD83E\uDDE0",
2427
+ tool: "\uD83D\uDEE0",
2428
+ stream: "\uD83D\uDCDD",
2429
+ approve: "⏳"
2430
+ };
2431
+ var TAIL = 5;
2432
+ var RAMP = ["█", "▓", "▒", "░"];
2433
+ var BAR_MS = 80;
2434
+ function StatusBar(props) {
2435
+ const [tick, setTick] = createSignal2(0);
2436
+ const timer = setInterval(() => setTick((t) => t + 1), BAR_MS);
2437
+ onCleanup(() => clearInterval(timer));
2438
+ const pools = () => ({
2439
+ think: props.verbs?.think ?? DEFAULT_VERBS.think,
2440
+ tool: props.verbs?.tool ?? DEFAULT_VERBS.tool,
2441
+ stream: props.verbs?.stream ?? DEFAULT_VERBS.stream,
2442
+ approve: props.verbs?.approve ?? DEFAULT_VERBS.approve
2443
+ });
2444
+ const fg = () => {
2445
+ const th = props.theme.tokens;
2446
+ if (props.phase === "think")
2447
+ return th.thinking ?? th.accent;
2448
+ if (props.phase === "tool")
2449
+ return th.toolOk ?? th.ok;
2450
+ if (props.phase === "approve")
2451
+ return th.warn;
2452
+ return th.accent;
2453
+ };
2454
+ const TRACK_COLS = 15;
2455
+ const ASSEMBLY = 2;
2456
+ const row = () => {
2457
+ const phase = props.phase;
2458
+ if (phase === null)
2459
+ return [];
2460
+ const pool = pools()[phase];
2461
+ const verb = pool[Math.floor(tick() * BAR_MS / VERB_MS) % pool.length];
2462
+ const detail = props.detail?.() ?? "";
2463
+ const label = `${PHASE_ICON[phase]} ${verb}... ${props.elapsed()}s${detail ? ` · ${detail}` : ""}`;
2464
+ const trackFg = props.theme.tokens.border;
2465
+ const headFg = fg();
2466
+ const span = TRACK_COLS - ASSEMBLY;
2467
+ const step = Math.floor(tick() % (span * 2));
2468
+ const start = step < span ? step : span * 2 - step;
2469
+ const dirRight = step < span;
2470
+ const stern = dirRight ? start : start + ASSEMBLY;
2471
+ const tailEnd = dirRight ? stern - TAIL : stern + TAIL;
2472
+ const runs = [];
2473
+ let buf = "";
2474
+ let bufFg = trackFg;
2475
+ const flush = (f) => {
2476
+ if (buf)
2477
+ runs.push({
2478
+ text: buf,
2479
+ fg: bufFg
2480
+ });
2481
+ buf = "";
2482
+ bufFg = f;
2483
+ };
2484
+ for (let c = 0;c < TRACK_COLS; c++) {
2485
+ if (c === start) {
2486
+ flush(headFg);
2487
+ runs.push({
2488
+ text: "\uD83D\uDC33",
2489
+ fg: headFg
2490
+ });
2491
+ bufFg = trackFg;
2492
+ c += 1;
2493
+ continue;
2494
+ }
2495
+ const behind = dirRight ? stern - c : c - stern;
2496
+ const inTail = dirRight ? c < stern && c > tailEnd : c > stern && c < tailEnd;
2497
+ if (inTail && behind >= 0) {
2498
+ const ch = RAMP[Math.min(RAMP.length - 1, Math.floor(behind / 2) + 1)];
2499
+ if (headFg !== bufFg)
2500
+ flush(headFg);
2501
+ buf += ch;
2502
+ } else {
2503
+ if (trackFg !== bufFg)
2504
+ flush(trackFg);
2505
+ buf += "░";
2506
+ }
2507
+ }
2508
+ flush(trackFg);
2509
+ runs.push({
2510
+ text: ` ${label}`,
2511
+ fg: headFg
2512
+ });
2513
+ return runs;
2514
+ };
2515
+ return _$createComponent13(Show8, {
2516
+ get when() {
2517
+ return props.phase !== null;
2518
+ },
2519
+ get children() {
2520
+ var _el$ = _$createElement14("box");
2521
+ _$setProp14(_el$, "style", {
2522
+ flexDirection: "row",
2523
+ paddingLeft: 1,
2524
+ paddingRight: 1,
2525
+ height: 1,
2526
+ flexGrow: 0
2527
+ });
2528
+ _$insert14(_el$, _$createComponent13(For11, {
2529
+ get each() {
2530
+ return row();
2531
+ },
2532
+ children: (r) => (() => {
2533
+ var _el$2 = _$createElement14("text");
2534
+ _$setProp14(_el$2, "wrapMode", "none");
2535
+ _$insert14(_el$2, () => r.text);
2536
+ _$effect14((_$p) => _$setProp14(_el$2, "style", {
2537
+ fg: r.fg
2538
+ }, _$p));
2539
+ return _el$2;
2540
+ })()
2541
+ }));
2542
+ return _el$;
2543
+ }
2544
+ });
2545
+ }
2546
+ // ../kit/src/flow-bar.tsx
2547
+ import { effect as _$effect15 } from "@opentui/solid";
2548
+ import { insert as _$insert15 } from "@opentui/solid";
2549
+ import { createComponent as _$createComponent14 } from "@opentui/solid";
2550
+ import { setProp as _$setProp15 } from "@opentui/solid";
2551
+ import { createElement as _$createElement15 } from "@opentui/solid";
2552
+ import { createSignal as createSignal3, onCleanup as onCleanup2, For as For12, Show as Show9 } from "solid-js";
1669
2553
  // src/features/model-select.tsx
1670
2554
  function createModelSelectFeature(deps) {
1671
2555
  let catalog = [];
@@ -1813,15 +2697,15 @@ function createHistoryForkFeature(deps) {
1813
2697
  }
1814
2698
 
1815
2699
  // src/features/login.tsx
1816
- import { setProp as _$setProp14 } from "@opentui/solid";
1817
- import { effect as _$effect14 } from "@opentui/solid";
2700
+ import { setProp as _$setProp16 } from "@opentui/solid";
2701
+ import { effect as _$effect16 } from "@opentui/solid";
1818
2702
  import { createTextNode as _$createTextNode9 } from "@opentui/solid";
1819
2703
  import { insertNode as _$insertNode11 } from "@opentui/solid";
1820
2704
  import { memo as _$memo7 } from "@opentui/solid";
1821
- import { insert as _$insert14 } from "@opentui/solid";
1822
- import { createElement as _$createElement14 } from "@opentui/solid";
1823
- import { createComponent as _$createComponent13 } from "@opentui/solid";
1824
- import { createSignal as createSignal2 } from "solid-js";
2705
+ import { insert as _$insert16 } from "@opentui/solid";
2706
+ import { createElement as _$createElement16 } from "@opentui/solid";
2707
+ import { createComponent as _$createComponent15 } from "@opentui/solid";
2708
+ import { createSignal as createSignal4 } from "solid-js";
1825
2709
  var PROVIDER_CATALOG = [{
1826
2710
  id: "amazon-bedrock",
1827
2711
  name: "Amazon Bedrock",
@@ -2029,7 +2913,7 @@ function providerProfileFor(entry) {
2029
2913
  return profile;
2030
2914
  }
2031
2915
  function createLoginFeature(deps) {
2032
- const [stage, setStage] = createSignal2({
2916
+ const [stage, setStage] = createSignal4({
2033
2917
  kind: "closed"
2034
2918
  });
2035
2919
  const settings = () => deps.session.settingsSeam;
@@ -2210,7 +3094,7 @@ function createLoginFeature(deps) {
2210
3094
  const st = stage();
2211
3095
  const th = deps.theme();
2212
3096
  if (st.kind === "menu") {
2213
- return _$createComponent13(Select, {
3097
+ return _$createComponent15(Select, {
2214
3098
  get title() {
2215
3099
  return st.title;
2216
3100
  },
@@ -2231,17 +3115,17 @@ function createLoginFeature(deps) {
2231
3115
  }
2232
3116
  if (st.kind === "entry") {
2233
3117
  return (() => {
2234
- var _el$ = _$createElement14("box"), _el$2 = _$createElement14("text"), _el$3 = _$createElement14("text"), _el$4 = _$createElement14("text");
3118
+ var _el$ = _$createElement16("box"), _el$2 = _$createElement16("text"), _el$3 = _$createElement16("text"), _el$4 = _$createElement16("text");
2235
3119
  _$insertNode11(_el$, _el$2);
2236
3120
  _$insertNode11(_el$, _el$3);
2237
3121
  _$insertNode11(_el$, _el$4);
2238
- _$insert14(_el$2, () => st.title);
2239
- _$insert14(_el$3, (() => {
3122
+ _$insert16(_el$2, () => st.title);
3123
+ _$insert16(_el$3, (() => {
2240
3124
  var _c$ = _$memo7(() => !!st.mask);
2241
3125
  return () => _c$() ? st.buffer.replace(/./g, "*") || " " : st.buffer || " ";
2242
3126
  })());
2243
3127
  _$insertNode11(_el$4, _$createTextNode9(`type · enter saves · esc cancels`));
2244
- _$effect14((_p$) => {
3128
+ _$effect16((_p$) => {
2245
3129
  var _v$ = {
2246
3130
  border: true,
2247
3131
  borderStyle: "rounded",
@@ -2255,10 +3139,10 @@ function createLoginFeature(deps) {
2255
3139
  }, _v$4 = {
2256
3140
  fg: th.tokens.dim
2257
3141
  };
2258
- _v$ !== _p$.e && (_p$.e = _$setProp14(_el$, "style", _v$, _p$.e));
2259
- _v$2 !== _p$.t && (_p$.t = _$setProp14(_el$2, "style", _v$2, _p$.t));
2260
- _v$3 !== _p$.a && (_p$.a = _$setProp14(_el$3, "style", _v$3, _p$.a));
2261
- _v$4 !== _p$.o && (_p$.o = _$setProp14(_el$4, "style", _v$4, _p$.o));
3142
+ _v$ !== _p$.e && (_p$.e = _$setProp16(_el$, "style", _v$, _p$.e));
3143
+ _v$2 !== _p$.t && (_p$.t = _$setProp16(_el$2, "style", _v$2, _p$.t));
3144
+ _v$3 !== _p$.a && (_p$.a = _$setProp16(_el$3, "style", _v$3, _p$.a));
3145
+ _v$4 !== _p$.o && (_p$.o = _$setProp16(_el$4, "style", _v$4, _p$.o));
2262
3146
  return _p$;
2263
3147
  }, {
2264
3148
  e: undefined,
@@ -2271,12 +3155,12 @@ function createLoginFeature(deps) {
2271
3155
  }
2272
3156
  if (st.kind === "confirm") {
2273
3157
  return (() => {
2274
- var _el$6 = _$createElement14("box"), _el$7 = _$createElement14("text"), _el$8 = _$createElement14("text");
3158
+ var _el$6 = _$createElement16("box"), _el$7 = _$createElement16("text"), _el$8 = _$createElement16("text");
2275
3159
  _$insertNode11(_el$6, _el$7);
2276
3160
  _$insertNode11(_el$6, _el$8);
2277
- _$insert14(_el$7, () => st.text);
3161
+ _$insert16(_el$7, () => st.text);
2278
3162
  _$insertNode11(_el$8, _$createTextNode9(`y confirm · n/esc cancels`));
2279
- _$effect14((_p$) => {
3163
+ _$effect16((_p$) => {
2280
3164
  var _v$5 = {
2281
3165
  border: true,
2282
3166
  borderStyle: "rounded",
@@ -2288,9 +3172,9 @@ function createLoginFeature(deps) {
2288
3172
  }, _v$7 = {
2289
3173
  fg: th.tokens.dim
2290
3174
  };
2291
- _v$5 !== _p$.e && (_p$.e = _$setProp14(_el$6, "style", _v$5, _p$.e));
2292
- _v$6 !== _p$.t && (_p$.t = _$setProp14(_el$7, "style", _v$6, _p$.t));
2293
- _v$7 !== _p$.a && (_p$.a = _$setProp14(_el$8, "style", _v$7, _p$.a));
3175
+ _v$5 !== _p$.e && (_p$.e = _$setProp16(_el$6, "style", _v$5, _p$.e));
3176
+ _v$6 !== _p$.t && (_p$.t = _$setProp16(_el$7, "style", _v$6, _p$.t));
3177
+ _v$7 !== _p$.a && (_p$.a = _$setProp16(_el$8, "style", _v$7, _p$.a));
2294
3178
  return _p$;
2295
3179
  }, {
2296
3180
  e: undefined,
@@ -2302,10 +3186,10 @@ function createLoginFeature(deps) {
2302
3186
  }
2303
3187
  if (st.kind === "notice") {
2304
3188
  return (() => {
2305
- var _el$0 = _$createElement14("box"), _el$1 = _$createElement14("text");
3189
+ var _el$0 = _$createElement16("box"), _el$1 = _$createElement16("text");
2306
3190
  _$insertNode11(_el$0, _el$1);
2307
- _$insert14(_el$1, () => st.text);
2308
- _$effect14((_p$) => {
3191
+ _$insert16(_el$1, () => st.text);
3192
+ _$effect16((_p$) => {
2309
3193
  var _v$8 = {
2310
3194
  border: true,
2311
3195
  borderStyle: "rounded",
@@ -2315,8 +3199,8 @@ function createLoginFeature(deps) {
2315
3199
  }, _v$9 = {
2316
3200
  fg: th.tokens.dim
2317
3201
  };
2318
- _v$8 !== _p$.e && (_p$.e = _$setProp14(_el$0, "style", _v$8, _p$.e));
2319
- _v$9 !== _p$.t && (_p$.t = _$setProp14(_el$1, "style", _v$9, _p$.t));
3202
+ _v$8 !== _p$.e && (_p$.e = _$setProp16(_el$0, "style", _v$8, _p$.e));
3203
+ _v$9 !== _p$.t && (_p$.t = _$setProp16(_el$1, "style", _v$9, _p$.t));
2320
3204
  return _p$;
2321
3205
  }, {
2322
3206
  e: undefined,
@@ -2391,15 +3275,15 @@ function createLoginFeature(deps) {
2391
3275
  }
2392
3276
 
2393
3277
  // src/features/dock.tsx
2394
- import { setProp as _$setProp15 } from "@opentui/solid";
2395
- import { effect as _$effect15 } from "@opentui/solid";
2396
- import { insert as _$insert15 } from "@opentui/solid";
3278
+ import { setProp as _$setProp17 } from "@opentui/solid";
3279
+ import { effect as _$effect17 } from "@opentui/solid";
3280
+ import { insert as _$insert17 } from "@opentui/solid";
2397
3281
  import { createTextNode as _$createTextNode10 } from "@opentui/solid";
2398
3282
  import { insertNode as _$insertNode12 } from "@opentui/solid";
2399
- import { createElement as _$createElement15 } from "@opentui/solid";
2400
- import { createComponent as _$createComponent14 } from "@opentui/solid";
3283
+ import { createElement as _$createElement17 } from "@opentui/solid";
3284
+ import { createComponent as _$createComponent16 } from "@opentui/solid";
2401
3285
  import { memo as _$memo8 } from "@opentui/solid";
2402
- import { createSignal as createSignal3, For as For11, Show as Show8 } from "solid-js";
3286
+ import { createSignal as createSignal5, For as For13, Show as Show10 } from "solid-js";
2403
3287
  var FLUSH_MS = 60;
2404
3288
  var FADE_STEP_MS = 130;
2405
3289
  var FADE_STEPS = 5;
@@ -2409,7 +3293,7 @@ function createDockFeature(deps) {
2409
3293
  const thinkFg = () => th().tokens.thinking ?? th().tokens.accent;
2410
3294
  const toolFg = () => th().tokens.toolOk ?? th().tokens.ok;
2411
3295
  const dim = (fg) => dimColor(fg, 0.45);
2412
- const [think, setThink] = createSignal3({
3296
+ const [think, setThink] = createSignal5({
2413
3297
  visible: false,
2414
3298
  expanded: false,
2415
3299
  fading: false,
@@ -2421,11 +3305,11 @@ function createDockFeature(deps) {
2421
3305
  let thinkBuf = "";
2422
3306
  let lastFlush = 0;
2423
3307
  let thinkOpen = false;
2424
- const [tools, setTools] = createSignal3([]);
2425
- const [toolVisible, setToolVisible] = createSignal3(false);
2426
- const [toolFading, setToolFading] = createSignal3(false);
2427
- const [toolFade, setToolFade] = createSignal3(0);
2428
- const [toolExpanded, setToolExpanded] = createSignal3(false);
3308
+ const [tools, setTools] = createSignal5([]);
3309
+ const [toolVisible, setToolVisible] = createSignal5(false);
3310
+ const [toolFading, setToolFading] = createSignal5(false);
3311
+ const [toolFade, setToolFade] = createSignal5(0);
3312
+ const [toolExpanded, setToolExpanded] = createSignal5(false);
2429
3313
  let lastToolAt = 0;
2430
3314
  let thinkHideTimer;
2431
3315
  const cancelThinkHide = () => {
@@ -2504,12 +3388,12 @@ function createDockFeature(deps) {
2504
3388
  const border = t.visible ? thinkFg() : toolFg();
2505
3389
  return dimColor(border, 0.82);
2506
3390
  };
2507
- return [_$createComponent14(Show8, {
3391
+ return [_$createComponent16(Show10, {
2508
3392
  get when() {
2509
3393
  return t.visible;
2510
3394
  },
2511
3395
  get children() {
2512
- return _$createComponent14(WidgetFrame, {
3396
+ return _$createComponent16(WidgetFrame, {
2513
3397
  get bg() {
2514
3398
  return bgTint();
2515
3399
  },
@@ -2527,20 +3411,20 @@ function createDockFeature(deps) {
2527
3411
  return hints.think;
2528
3412
  },
2529
3413
  get children() {
2530
- return [_$createComponent14(Show8, {
3414
+ return [_$createComponent16(Show10, {
2531
3415
  get when() {
2532
3416
  return t.expanded;
2533
3417
  },
2534
3418
  get children() {
2535
- return _$createComponent14(For11, {
3419
+ return _$createComponent16(For13, {
2536
3420
  get each() {
2537
3421
  return t.text.split(`
2538
3422
  `).slice(-Math.max(1, (typeof rowsT === "number" ? rowsT : 7) - 2));
2539
3423
  },
2540
3424
  children: (line) => (() => {
2541
- var _el$6 = _$createElement15("text");
2542
- _$insert15(_el$6, line || " ");
2543
- _$effect15((_$p) => _$setProp15(_el$6, "style", {
3425
+ var _el$6 = _$createElement17("text");
3426
+ _$insert17(_el$6, line || " ");
3427
+ _$effect17((_$p) => _$setProp17(_el$6, "style", {
2544
3428
  fg: dimColor(thinkFg(), 0.2),
2545
3429
  wrapMode: "none",
2546
3430
  truncate: true
@@ -2549,18 +3433,18 @@ function createDockFeature(deps) {
2549
3433
  })()
2550
3434
  });
2551
3435
  }
2552
- }), _$createComponent14(Show8, {
3436
+ }), _$createComponent16(Show10, {
2553
3437
  get when() {
2554
3438
  return !t.expanded;
2555
3439
  },
2556
3440
  get children() {
2557
- var _el$ = _$createElement15("text"), _el$2 = _$createTextNode10(`\uD83D\uDCAD `), _el$3 = _$createTextNode10(`s `);
3441
+ var _el$ = _$createElement17("text"), _el$2 = _$createTextNode10(`\uD83D\uDCAD `), _el$3 = _$createTextNode10(`s `);
2558
3442
  _$insertNode12(_el$, _el$2);
2559
3443
  _$insertNode12(_el$, _el$3);
2560
- _$insert15(_el$, elapsed, _el$3);
2561
- _$insert15(_el$, () => thinkBuf.split(`
3444
+ _$insert17(_el$, elapsed, _el$3);
3445
+ _$insert17(_el$, () => thinkBuf.split(`
2562
3446
  `).pop() || " ", null);
2563
- _$effect15((_$p) => _$setProp15(_el$, "style", {
3447
+ _$effect17((_$p) => _$setProp17(_el$, "style", {
2564
3448
  fg: dimColor(thinkFg(), 0.2),
2565
3449
  wrapMode: "none",
2566
3450
  truncate: true
@@ -2571,12 +3455,12 @@ function createDockFeature(deps) {
2571
3455
  }
2572
3456
  });
2573
3457
  }
2574
- }), _$createComponent14(Show8, {
3458
+ }), _$createComponent16(Show10, {
2575
3459
  get when() {
2576
3460
  return toolVisible() || list.length > 0;
2577
3461
  },
2578
3462
  get children() {
2579
- return _$createComponent14(WidgetFrame, {
3463
+ return _$createComponent16(WidgetFrame, {
2580
3464
  get bg() {
2581
3465
  return bgTint();
2582
3466
  },
@@ -2596,22 +3480,22 @@ function createDockFeature(deps) {
2596
3480
  return hints.tool;
2597
3481
  },
2598
3482
  get children() {
2599
- return [_$createComponent14(Show8, {
3483
+ return [_$createComponent16(Show10, {
2600
3484
  get when() {
2601
3485
  return toolExpanded();
2602
3486
  },
2603
3487
  get children() {
2604
- return _$createComponent14(For11, {
3488
+ return _$createComponent16(For13, {
2605
3489
  get each() {
2606
3490
  return list.slice(-Math.max(1, (typeof rowsTool === "number" ? rowsTool : 7) - 2));
2607
3491
  },
2608
3492
  children: (e) => (() => {
2609
- var _el$7 = _$createElement15("text");
2610
- _$insert15(_el$7, (() => {
3493
+ var _el$7 = _$createElement17("text");
3494
+ _$insert17(_el$7, (() => {
2611
3495
  var _c$2 = _$memo8(() => e.status === "running");
2612
3496
  return () => _c$2() ? `⚙ ${e.name} ${e.args}` : `${e.status === "ok" ? "✔" : "✘"} ${e.name} ${e.args}`;
2613
3497
  })());
2614
- _$effect15((_$p) => _$setProp15(_el$7, "style", {
3498
+ _$effect17((_$p) => _$setProp17(_el$7, "style", {
2615
3499
  fg: e.status === "running" ? toolFg() : e.status === "fail" ? th().tokens.toolFail ?? th().tokens.danger : th().tokens.toolOk ?? th().tokens.ok,
2616
3500
  wrapMode: "none",
2617
3501
  truncate: true
@@ -2620,18 +3504,18 @@ function createDockFeature(deps) {
2620
3504
  })()
2621
3505
  });
2622
3506
  }
2623
- }), _$createComponent14(Show8, {
3507
+ }), _$createComponent16(Show10, {
2624
3508
  get when() {
2625
3509
  return !toolExpanded();
2626
3510
  },
2627
3511
  get children() {
2628
- var _el$4 = _$createElement15("text"), _el$5 = _$createTextNode10(`\uD83D\uDD27 `);
3512
+ var _el$4 = _$createElement17("text"), _el$5 = _$createTextNode10(`\uD83D\uDD27 `);
2629
3513
  _$insertNode12(_el$4, _el$5);
2630
- _$insert15(_el$4, (() => {
3514
+ _$insert17(_el$4, (() => {
2631
3515
  var _c$ = _$memo8(() => running.length > 0);
2632
3516
  return () => _c$() ? `⚙ ${running[0].name} ${running[0].args}` : `${list[0]?.name ?? ""} ${list[0]?.args ?? ""}`;
2633
3517
  })(), null);
2634
- _$effect15((_$p) => _$setProp15(_el$4, "style", {
3518
+ _$effect17((_$p) => _$setProp17(_el$4, "style", {
2635
3519
  fg: dimColor(toolFg(), 0.2),
2636
3520
  wrapMode: "none",
2637
3521
  truncate: true
@@ -2758,6 +3642,7 @@ function createDockFeature(deps) {
2758
3642
  setToolExpanded((v) => !v);
2759
3643
  },
2760
3644
  toolCount: () => tools().length,
3645
+ runningToolName: () => tools().find((e) => e.status === "running")?.name ?? null,
2761
3646
  toolActive: () => tools().some((e) => e.status === "running")
2762
3647
  };
2763
3648
  function hideAll() {
@@ -2805,6 +3690,30 @@ var COMMANDS = [{
2805
3690
  }, {
2806
3691
  name: "/preset",
2807
3692
  desc: "switch agent preset"
3693
+ }, {
3694
+ name: "/think",
3695
+ desc: "cycle reasoning effort of the current model"
3696
+ }, {
3697
+ name: "/subagents",
3698
+ desc: "pick a subagent to view its transcript"
3699
+ }, {
3700
+ name: "/resume",
3701
+ desc: "resume a stored session (picker)"
3702
+ }, {
3703
+ name: "/hotkeys",
3704
+ desc: "show the key bindings"
3705
+ }, {
3706
+ name: "/session",
3707
+ desc: "show current session info (/session rename …)"
3708
+ }, {
3709
+ name: "/plugins",
3710
+ desc: "list installed plugins"
3711
+ }, {
3712
+ name: "/skills",
3713
+ desc: "list registered skills"
3714
+ }, {
3715
+ name: "/reload",
3716
+ desc: "hot-reload plugins"
2808
3717
  }, {
2809
3718
  name: "/search",
2810
3719
  desc: "full-text search sessions (/search text)"
@@ -2820,12 +3729,21 @@ var COMMANDS = [{
2820
3729
  }, {
2821
3730
  name: "/config",
2822
3731
  desc: "plugin settings (/config or /config key value)"
3732
+ }, {
3733
+ name: "/settings",
3734
+ desc: "browse host settings namespaces"
2823
3735
  }, {
2824
3736
  name: "/queue",
2825
3737
  desc: "queue a message (/queue msg, bare toggles panel)"
2826
3738
  }, {
2827
3739
  name: "/repair",
2828
3740
  desc: "scan session logs for broken files"
3741
+ }, {
3742
+ name: "/tail",
3743
+ desc: "watch a session log live (/tail sessionId)"
3744
+ }, {
3745
+ name: "/agents",
3746
+ desc: "list agent definitions (~/.dsh/agents)"
2829
3747
  }, {
2830
3748
  name: "/theme",
2831
3749
  desc: "pick theme"
@@ -2852,53 +3770,73 @@ var fmtClock = () => {
2852
3770
  };
2853
3771
  function ShellHost(props) {
2854
3772
  const t = props.deps.t;
2855
- const [input, setInput] = createSignal4("");
2856
- const [history, setHistory] = createSignal4([]);
2857
- const [historyIdx, setHistoryIdx] = createSignal4(0);
2858
- const [resetKey, setResetKey] = createSignal4(0);
2859
- const [setKey, setSetKey] = createSignal4(0);
2860
- const [setValueText, setSetValueText] = createSignal4("");
2861
- const [items, setItems] = createSignal4([]);
2862
- const [busy, setBusy] = createSignal4(false);
2863
- const [approval, setApproval] = createSignal4(null);
2864
- const [usage, setUsage] = createSignal4({
3773
+ const [input, setInput] = createSignal6("");
3774
+ const [history, setHistory] = createSignal6([]);
3775
+ const [historyIdx, setHistoryIdx] = createSignal6(0);
3776
+ const [resetKey, setResetKey] = createSignal6(0);
3777
+ const [setKey, setSetKey] = createSignal6(0);
3778
+ const [setValueText, setSetValueText] = createSignal6("");
3779
+ const [items, setItems] = createSignal6([]);
3780
+ const [busy, setBusy] = createSignal6(false);
3781
+ const [approval, setApproval] = createSignal6(null);
3782
+ const [usage, setUsage] = createSignal6({
2865
3783
  prompt: 0,
2866
3784
  completion: 0,
2867
3785
  turns: 0
2868
3786
  });
2869
- const [label, setLabel] = createSignal4(props.deps.session.label);
2870
- const [showWelcome, setShowWelcome] = createSignal4(true);
2871
- const [todos, setTodos] = createSignal4([]);
2872
- const [subagents, setSubagents] = createSignal4([]);
2873
- const [viewerId, setViewerId] = createSignal4(null);
2874
- const [viewerLines, setViewerLines] = createSignal4([]);
2875
- const [steerFor, setSteerFor] = createSignal4(null);
2876
- const [steerBuffer, setSteerBuffer] = createSignal4("");
2877
- const [hintsVisible, setHintsVisible] = createSignal4(true);
2878
- const [gitBranch, setGitBranch] = createSignal4("");
2879
- const [queueMsgs, setQueueMsgs] = createSignal4([]);
2880
- const [queueOpen, setQueueOpen] = createSignal4(false);
2881
- const [btwPairs, setBtwPairs] = createSignal4([]);
2882
- const [btwLive, setBtwLive] = createSignal4(null);
2883
- const [btwOpen, setBtwOpen] = createSignal4(false);
2884
- const [kb] = createSignal4(props.deps.session.keybindingsLoad?.() ?? {});
3787
+ const [label, setLabel] = createSignal6(props.deps.session.label);
3788
+ const [showWelcome, setShowWelcome] = createSignal6(true);
3789
+ const [todos, setTodos] = createSignal6([]);
3790
+ const [subagents, setSubagents] = createSignal6([]);
3791
+ let subagentClearTimer;
3792
+ const scheduleSubagentClear = () => {
3793
+ if (subagentClearTimer !== undefined)
3794
+ clearTimeout(subagentClearTimer);
3795
+ subagentClearTimer = setTimeout(() => {
3796
+ subagentClearTimer = undefined;
3797
+ setSubagents([]);
3798
+ }, 1000);
3799
+ };
3800
+ const [viewerId, setViewerId] = createSignal6(null);
3801
+ const [viewerLines, setViewerLines] = createSignal6([]);
3802
+ const [steerFor, setSteerFor] = createSignal6(null);
3803
+ const [steerBuffer, setSteerBuffer] = createSignal6("");
3804
+ const [hintsVisible, setHintsVisible] = createSignal6(true);
3805
+ const [gitBranch, setGitBranch] = createSignal6("");
3806
+ const [queueMsgs, setQueueMsgs] = createSignal6([]);
3807
+ const [queueOpen, setQueueOpen] = createSignal6(false);
3808
+ const [btwPairs, setBtwPairs] = createSignal6([]);
3809
+ const [btwLive, setBtwLive] = createSignal6(null);
3810
+ const [btwOpen, setBtwOpen] = createSignal6(false);
3811
+ const [kb] = createSignal6(props.deps.session.keybindingsLoad?.() ?? {});
2885
3812
  const hot = (action, fallback) => kb()[action] ?? fallback;
2886
- const [pluginConfig, setPluginConfig] = createSignal4(props.deps.session.configLoad());
3813
+ props.deps.session.remoteTailSink = (rows) => {
3814
+ setItems(rows.map((r) => ({
3815
+ kind: r.kind,
3816
+ text: r.text,
3817
+ final: r.final
3818
+ })));
3819
+ setScrollTopLine(null);
3820
+ };
3821
+ const [pluginConfig, setPluginConfig] = createSignal6(props.deps.session.configLoad());
2887
3822
  const openViewer = (id) => {
2888
3823
  setViewerId(id);
2889
3824
  setViewerLines(props.deps.session.childTranscript(id));
2890
3825
  };
2891
- const [overlay, setOverlay] = createSignal4(null);
3826
+ const [overlay, setOverlay] = createSignal6(null);
2892
3827
  const initialTheme = process.env.DSH_OPENTUI_THEME ?? props.deps.themeName ?? "catppuccin-mocha";
2893
- const [themeName, setThemeName] = createSignal4(themes[initialTheme] ? initialTheme : "catppuccin-mocha");
3828
+ const [themeName, setThemeName] = createSignal6(themes[initialTheme] ? initialTheme : "catppuccin-mocha");
2894
3829
  const theme = () => getTheme(themeName());
2895
- const [menuOpen, setMenuOpen] = createSignal4(true);
2896
- const [menuSel, setMenuSel] = createSignal4(0);
2897
- const [clock, setClock] = createSignal4(fmtClock());
2898
- const [liveTps, setLiveTps] = createSignal4(null);
3830
+ const [menuOpen, setMenuOpen] = createSignal6(true);
3831
+ const [menuSel, setMenuSel] = createSignal6(0);
3832
+ const [clock, setClock] = createSignal6(fmtClock());
3833
+ const [turnElapsed, setTurnElapsed] = createSignal6(0);
3834
+ const [streaming, setStreaming] = createSignal6(false);
3835
+ const [termCols, setTermCols] = createSignal6(process.stdout.columns ?? 100);
3836
+ const [liveTps, setLiveTps] = createSignal6(null);
2899
3837
  let turnStartAt = 0;
2900
3838
  let approveResolve = null;
2901
- const [scrollTopLine, setScrollTopLine] = createSignal4(null);
3839
+ const [scrollTopLine, setScrollTopLine] = createSignal6(null);
2902
3840
  let totalLines = 0;
2903
3841
  const VIEWPORT_ROWS = 18;
2904
3842
  const scrollUp = () => {
@@ -2917,19 +3855,23 @@ function ShellHost(props) {
2917
3855
  };
2918
3856
  const pinIfFollowing = () => {};
2919
3857
  let replayGen = 0;
2920
- const [stopConfirm, setStopConfirm] = createSignal4(false);
2921
- const [plugins] = createSignal4(props.deps.session.listPlugins());
2922
- const execMode = props.deps.session.executionMode();
2923
- const [hostCommands, setHostCommands] = createSignal4([]);
3858
+ const [stopConfirm, setStopConfirm] = createSignal6(false);
3859
+ const [plugins] = createSignal6(props.deps.session.listPlugins());
3860
+ const [execMode, setExecMode] = createSignal6(props.deps.session.executionMode());
3861
+ const refreshExecMode = () => setExecMode(props.deps.session.executionMode());
3862
+ const [hostCommands, setHostCommands] = createSignal6([]);
2924
3863
  onMount(async () => {
2925
3864
  try {
2926
3865
  setHostCommands(await props.deps.session.listHostCommands());
2927
3866
  } catch {}
2928
3867
  });
2929
- const [focusKey, setFocusKey] = createSignal4(0);
3868
+ const [focusKey, setFocusKey] = createSignal6(0);
2930
3869
  onMount(() => {
2931
3870
  const tick = setInterval(() => {
2932
3871
  setClock(fmtClock());
3872
+ setTermCols(process.stdout.columns ?? 100);
3873
+ if (busy())
3874
+ setTurnElapsed((s) => s + 1);
2933
3875
  dock.tick();
2934
3876
  setSubagents((arr) => arr.some((r) => r.status === "running") ? arr.map((r) => r.status === "running" ? {
2935
3877
  ...r,
@@ -2966,11 +3908,11 @@ function ShellHost(props) {
2966
3908
  });
2967
3909
  });
2968
3910
  }, 1200);
2969
- onCleanup(() => {
3911
+ onCleanup3(() => {
2970
3912
  clearInterval(gitTick);
2971
3913
  clearTimeout(gitOnce);
2972
3914
  });
2973
- onCleanup(() => clearInterval(tick));
3915
+ onCleanup3(() => clearInterval(tick));
2974
3916
  if (!process.env.DSH_OPENTUI_NO_ASK)
2975
3917
  props.deps.session.registerAskProvider(async (questions) => {
2976
3918
  const answer = await new Promise((resolve) => {
@@ -3324,6 +4266,99 @@ function ShellHost(props) {
3324
4266
  });
3325
4267
  }
3326
4268
  }
4269
+ } else if (cmd === "think") {
4270
+ const ladder = ["keep", "low", "medium", "high", "xhigh", "max"];
4271
+ const m = /^([^/]+)\/([^/]+?)(?:\s*\(([^)]+)\))?$/.exec(label());
4272
+ if (!m) {
4273
+ push({
4274
+ kind: "error",
4275
+ text: "no live model route to cycle"
4276
+ });
4277
+ return;
4278
+ }
4279
+ const [, provider, model, cur] = m;
4280
+ const next = cur === undefined || cur === "off" ? "low" : ladder[(ladder.indexOf(cur) + 1) % ladder.length];
4281
+ props.deps.session.switchModel(provider, model, next === "keep" ? undefined : next);
4282
+ setLabel(props.deps.session.label);
4283
+ push({
4284
+ kind: "system",
4285
+ text: `${provider}/${model} ◕ ${next}`
4286
+ });
4287
+ } else if (cmd === "subagents") {
4288
+ const list = subagents();
4289
+ if (list.length === 0) {
4290
+ push({
4291
+ kind: "system",
4292
+ text: "no subagents yet (ctrl+G works once children exist too)"
4293
+ });
4294
+ return;
4295
+ }
4296
+ openOverlay({
4297
+ title: "subagents — pick to view transcript",
4298
+ items: list.map((e) => ({
4299
+ label: `${e.label}${e.model ? ` · ${e.model}` : ""}`,
4300
+ value: e.id,
4301
+ description: `${e.status} · ↻${e.rounds}`
4302
+ })),
4303
+ onSelect: (value) => openViewer(value)
4304
+ });
4305
+ } else if (cmd === "resume") {
4306
+ const hits = await props.deps.session.listSessions();
4307
+ if (hits.length === 0) {
4308
+ push({
4309
+ kind: "system",
4310
+ text: "no sessions to resume"
4311
+ });
4312
+ return;
4313
+ }
4314
+ openOverlay({
4315
+ title: t("picker.sessions.title"),
4316
+ items: hits.map((h) => ({
4317
+ label: h.title || h.id.slice(0, 8),
4318
+ value: h.id,
4319
+ description: h.updatedAt?.slice(0, 19)
4320
+ })),
4321
+ onSelect: async (value) => {
4322
+ props.deps.session.resumeSession(value);
4323
+ setBusy(false);
4324
+ setShowWelcome(false);
4325
+ const gen = ++replayGen;
4326
+ try {
4327
+ const rows = await props.deps.session.storedTranscript(value);
4328
+ if (gen !== replayGen)
4329
+ return;
4330
+ await new Promise((r) => setTimeout(r, 50));
4331
+ if (gen !== replayGen)
4332
+ return;
4333
+ setItems(rows.map((it) => it.kind === "assistant" ? {
4334
+ kind: "assistant",
4335
+ text: it.text,
4336
+ final: true
4337
+ } : {
4338
+ kind: "user",
4339
+ text: it.text
4340
+ }));
4341
+ setScrollTopLine(null);
4342
+ } catch {}
4343
+ push({
4344
+ kind: "system",
4345
+ text: `${t("cmd.sessions.resumed")}: ${value.slice(0, 8)}`
4346
+ });
4347
+ }
4348
+ });
4349
+ } else if (cmd === "hotkeys") {
4350
+ const rows = [["viewer", "ctrl+g"], ["think", "ctrl+t"], ["tools", "ctrl+o"], ["scrollUp", "pageup"], ["scrollDown", "pagedown"], ["model", "ctrl+l"], ["search", "ctrl+alt+f"], ["escape", "escape"], ["ctrlC", "ctrl+c"], ["ctrlD", "ctrl+d"]];
4351
+ push({
4352
+ kind: "system",
4353
+ text: "keybindings (keybindings.json overrides *):"
4354
+ });
4355
+ for (const [action, def] of rows) {
4356
+ const mark = kb()[action] ? " *" : "";
4357
+ push({
4358
+ kind: "system",
4359
+ text: ` ${action.padEnd(10)} ${kb()[action] ?? def}${mark}`
4360
+ });
4361
+ }
3327
4362
  } else if (cmd === "preset") {
3328
4363
  const presets = await props.deps.session.listPresets();
3329
4364
  if (presets.length === 0) {
@@ -3345,6 +4380,7 @@ function ShellHost(props) {
3345
4380
  onSelect: (value) => {
3346
4381
  const picked = presets.find((p) => p.id === value);
3347
4382
  props.deps.session.switchPreset(value);
4383
+ refreshExecMode();
3348
4384
  push({
3349
4385
  kind: "system",
3350
4386
  text: `preset → ${picked?.name ?? value} (fresh session on next message)`
@@ -3357,10 +4393,12 @@ function ShellHost(props) {
3357
4393
  } else if (cmd === "new") {
3358
4394
  replayGen++;
3359
4395
  props.deps.session.newSession();
4396
+ refreshExecMode();
3360
4397
  setItems([]);
3361
4398
  setBtwPairs([]);
3362
4399
  setBtwLive(null);
3363
4400
  setBtwOpen(false);
4401
+ props.deps.session.stopRemoteTail();
3364
4402
  push({
3365
4403
  kind: "system",
3366
4404
  text: t("cmd.new.done")
@@ -3494,6 +4532,129 @@ function ShellHost(props) {
3494
4532
  text: "language switching unavailable"
3495
4533
  });
3496
4534
  }
4535
+ } else if (cmd === "agents") {
4536
+ const agents = props.deps.session.listAgents();
4537
+ if (agents.length === 0) {
4538
+ push({
4539
+ kind: "system",
4540
+ text: "no agent definitions (~/.dsh/agents/*.md)"
4541
+ });
4542
+ return;
4543
+ }
4544
+ const openFields = (agentName) => {
4545
+ const a = props.deps.session.listAgents().find((x) => x.name === agentName);
4546
+ if (!a)
4547
+ return;
4548
+ openOverlay({
4549
+ title: `${a.displayName ?? a.name} — fields`,
4550
+ items: [{
4551
+ label: `model: ${a.model ?? "(inherit)"}`,
4552
+ value: "model",
4553
+ description: "pick a model route"
4554
+ }, {
4555
+ label: `thinking: ${a.thinking ?? "(inherit)"}`,
4556
+ value: "thinking",
4557
+ description: "pick a reasoning effort"
4558
+ }, {
4559
+ label: `deep: ${a.deep ?? "0"}`,
4560
+ value: "deep",
4561
+ description: "spawn depth"
4562
+ }],
4563
+ onSelect: (field) => {
4564
+ if (field === "model") {
4565
+ props.deps.session.listProviders().then((catalog) => {
4566
+ openOverlay({
4567
+ title: `${a.name} — pick model`,
4568
+ items: catalog.flatMap((p) => p.models.map((m) => ({
4569
+ label: m,
4570
+ group: p.provider,
4571
+ value: `${p.provider}/${m}`
4572
+ }))),
4573
+ onSelect: (v) => {
4574
+ props.deps.session.agentSet(a.name, "model", v);
4575
+ push({
4576
+ kind: "system",
4577
+ text: `${a.name}: model → ${v}`
4578
+ });
4579
+ openFields(a.name);
4580
+ }
4581
+ });
4582
+ });
4583
+ } else if (field === "thinking") {
4584
+ openOverlay({
4585
+ title: `${a.name} — thinking`,
4586
+ items: ["keep", "low", "medium", "high", "xhigh", "max"].map((e) => ({
4587
+ label: e,
4588
+ value: e,
4589
+ description: t(`picker.effort.${e}.desc`)
4590
+ })),
4591
+ onSelect: (v) => {
4592
+ props.deps.session.agentSet(a.name, "thinking", v === "keep" ? "" : v);
4593
+ push({
4594
+ kind: "system",
4595
+ text: `${a.name}: thinking → ${v}`
4596
+ });
4597
+ openFields(a.name);
4598
+ }
4599
+ });
4600
+ } else {
4601
+ openOverlay({
4602
+ title: `${a.name} — deep`,
4603
+ items: ["0", "1", "2", "3"].map((d) => ({
4604
+ label: d,
4605
+ value: d,
4606
+ description: d === "0" ? "no delegation" : `depth ${d}`
4607
+ })),
4608
+ onSelect: (v) => {
4609
+ props.deps.session.agentSet(a.name, "deep", v);
4610
+ push({
4611
+ kind: "system",
4612
+ text: `${a.name}: deep → ${v}`
4613
+ });
4614
+ openFields(a.name);
4615
+ }
4616
+ });
4617
+ }
4618
+ }
4619
+ });
4620
+ };
4621
+ const broken = agents.filter((a) => a.broken);
4622
+ openOverlay({
4623
+ title: `agents (${agents.length})`,
4624
+ items: agents.map((a) => ({
4625
+ label: a.broken ? `✗ ${a.name}` : a.displayName ?? a.name,
4626
+ value: a.name,
4627
+ description: [a.model ? `⚙ ${a.model}` : null, a.thinking ? `◕ ${a.thinking}` : null, a.deep ? `deep ${a.deep}` : null, a.broken ? `broken: ${a.broken}` : null].filter(Boolean).join(" · ")
4628
+ })),
4629
+ onSelect: (value) => {
4630
+ const a = agents.find((x) => x.name === value);
4631
+ if (!a || a.broken)
4632
+ return;
4633
+ openFields(a.name);
4634
+ }
4635
+ });
4636
+ } else if (cmd === "tail") {
4637
+ const target = parts[1] ?? "";
4638
+ if (!target) {
4639
+ push({
4640
+ kind: "error",
4641
+ text: "usage: /tail <sessionId or prefix>"
4642
+ });
4643
+ return;
4644
+ }
4645
+ setShowWelcome(false);
4646
+ setBusy(false);
4647
+ const err = await props.deps.session.startRemoteTail(target);
4648
+ if (err)
4649
+ push({
4650
+ kind: "error",
4651
+ text: `tail: ${err}`
4652
+ });
4653
+ else
4654
+ push({
4655
+ kind: "system",
4656
+ text: `watching ${target.slice(0, 8)} (read-only, 2s poll) — /new stops`
4657
+ });
3497
4658
  } else if (cmd === "repair") {
3498
4659
  for (const line of props.deps.session.repairScan())
3499
4660
  push({
@@ -3511,6 +4672,108 @@ function ShellHost(props) {
3511
4672
  kind: "system",
3512
4673
  text: `queued (${queueMsgs().length} waiting) — sends after the current turn`
3513
4674
  });
4675
+ } else if (cmd === "session") {
4676
+ push({
4677
+ kind: "system",
4678
+ text: `session: ${label()} · \uD83D\uDCAC ${msgCount()} · ⚒ ${toolCount()} · up ${turnElapsed()}s`
4679
+ });
4680
+ if (parts[1])
4681
+ push({
4682
+ kind: "system",
4683
+ text: `rename: ${parts.slice(1).join(" ")} (needs session-title plugin)`
4684
+ });
4685
+ } else if (cmd === "plugins") {
4686
+ const list = props.deps.session.listPlugins();
4687
+ if (list.length === 0)
4688
+ push({
4689
+ kind: "system",
4690
+ text: "no plugins installed"
4691
+ });
4692
+ else {
4693
+ push({
4694
+ kind: "system",
4695
+ text: `plugins (${list.length}):`
4696
+ });
4697
+ for (const p of list)
4698
+ push({
4699
+ kind: "system",
4700
+ text: ` ● ${p.name}@${p.version}`
4701
+ });
4702
+ }
4703
+ } else if (cmd === "skills") {
4704
+ const skills = props.deps.session.listSkills();
4705
+ if (skills.length === 0)
4706
+ push({
4707
+ kind: "system",
4708
+ text: "no skills registered"
4709
+ });
4710
+ else {
4711
+ push({
4712
+ kind: "system",
4713
+ text: `skills (${skills.length}):`
4714
+ });
4715
+ for (const k of skills)
4716
+ push({
4717
+ kind: "system",
4718
+ text: ` ● ${k.name} — ${k.description}`
4719
+ });
4720
+ }
4721
+ } else if (cmd === "reload") {
4722
+ const err = await props.deps.session.reloadPlugins();
4723
+ if (err)
4724
+ push({
4725
+ kind: "error",
4726
+ text: `reload failed: ${err}`
4727
+ });
4728
+ else
4729
+ push({
4730
+ kind: "system",
4731
+ text: "plugins reloaded"
4732
+ });
4733
+ } else if (cmd === "settings") {
4734
+ const descs = await props.deps.session.settingsDescribe();
4735
+ if (descs.length === 0) {
4736
+ push({
4737
+ kind: "system",
4738
+ text: "settings service unavailable"
4739
+ });
4740
+ return;
4741
+ }
4742
+ openOverlay({
4743
+ title: `settings (${descs.length} namespaces)`,
4744
+ items: descs.map((d) => ({
4745
+ label: d.ns,
4746
+ value: d.ns,
4747
+ description: `revision ${d.revision ?? "?"}`
4748
+ })),
4749
+ onSelect: (ns) => {
4750
+ const desc = descs.find((d) => d.ns === ns);
4751
+ const value = desc?.value ?? {};
4752
+ const keys = Object.keys(value ?? {});
4753
+ if (keys.length === 0) {
4754
+ push({
4755
+ kind: "system",
4756
+ text: `${ns}: no top-level keys`
4757
+ });
4758
+ return;
4759
+ }
4760
+ openOverlay({
4761
+ title: `settings: ${ns}`,
4762
+ items: keys.map((k) => ({
4763
+ label: k,
4764
+ value: k,
4765
+ description: JSON.stringify(value[k]).slice(0, 70)
4766
+ })),
4767
+ onSelect: (key) => {
4768
+ const cur = value[key];
4769
+ push({
4770
+ kind: "system",
4771
+ text: `${ns}.${key} = ${JSON.stringify(cur)} — edit via /settings-edit ${ns} ${key} <json>`
4772
+ });
4773
+ }
4774
+ });
4775
+ }
4776
+ });
3514
4777
  } else if (cmd === "config") {
3515
4778
  const KEYS = [{
3516
4779
  key: "retentionDays",
@@ -3645,6 +4908,12 @@ function ShellHost(props) {
3645
4908
  });
3646
4909
  setBusy(true);
3647
4910
  dock.onTurnStart();
4911
+ setTurnElapsed(0);
4912
+ setStreaming(false);
4913
+ if (subagentClearTimer !== undefined) {
4914
+ clearTimeout(subagentClearTimer);
4915
+ subagentClearTimer = undefined;
4916
+ }
3648
4917
  setLiveTps(null);
3649
4918
  turnStartAt = Date.now();
3650
4919
  streamingReply = null;
@@ -3656,6 +4925,7 @@ function ShellHost(props) {
3656
4925
  },
3657
4926
  onContentDelta: (s) => {
3658
4927
  dock.onContentDelta(s);
4928
+ setStreaming(true);
3659
4929
  if (!streamingReply) {
3660
4930
  streamingReply = {
3661
4931
  kind: "assistant",
@@ -3676,6 +4946,7 @@ function ShellHost(props) {
3676
4946
  setItems((arr) => arr.map((x) => x === cur ? final : x));
3677
4947
  }
3678
4948
  setLabel(props.deps.session.label);
4949
+ refreshExecMode();
3679
4950
  setUsage((v) => ({
3680
4951
  prompt: v.prompt + u.prompt,
3681
4952
  completion: v.completion + u.completion,
@@ -3691,7 +4962,11 @@ function ShellHost(props) {
3691
4962
  setLiveTps(Math.round(chars / 4 / sec));
3692
4963
  },
3693
4964
  onTodos: (list) => setTodos(list),
3694
- onSubagentUpdate: (entries) => setSubagents(entries),
4965
+ onSubagentUpdate: (entries) => {
4966
+ setSubagents(entries);
4967
+ if (entries.length > 0 && entries.every((e) => e.status !== "running"))
4968
+ scheduleSubagentClear();
4969
+ },
3695
4970
  onApprove: (name, args) => {
3696
4971
  if (SPAWN_TOOLS.includes(name)) {
3697
4972
  const cap = Number(pluginConfig().maxAgents ?? 0);
@@ -3747,6 +5022,7 @@ function ShellHost(props) {
3747
5022
  });
3748
5023
  } finally {
3749
5024
  dock.onTurnEnd();
5025
+ setStreaming(false);
3750
5026
  setApproval(null);
3751
5027
  approveResolve = null;
3752
5028
  setBusy(false);
@@ -3887,6 +5163,16 @@ function ShellHost(props) {
3887
5163
  dock.toggleExpand("tool");
3888
5164
  return;
3889
5165
  }
5166
+ const modelKey = hot("model", "ctrl+l");
5167
+ if (key.ctrl && !key.meta && key.name === modelKey.replace("ctrl+", "")) {
5168
+ runCommand("/model");
5169
+ return;
5170
+ }
5171
+ const searchKey = hot("search", "ctrl+alt+f");
5172
+ if (key.ctrl && key.option && key.name === searchKey.replace("ctrl+alt+", "")) {
5173
+ runCommand("/search");
5174
+ return;
5175
+ }
3890
5176
  const upKey = hot("scrollUp", "pageup");
3891
5177
  const dnKey = hot("scrollDown", "pagedown");
3892
5178
  if (key.name === upKey || upKey.startsWith("ctrl+") && key.ctrl && key.name === upKey.slice(5)) {
@@ -3921,7 +5207,7 @@ function ShellHost(props) {
3921
5207
  const r = route();
3922
5208
  const pct = contextPct();
3923
5209
  const segs = [{
3924
- text: `dsh(${execMode})`,
5210
+ text: `dsh(${execMode()})`,
3925
5211
  bg: POWERLINE_COLORS.brand
3926
5212
  }, {
3927
5213
  text: r.provider,
@@ -3959,16 +5245,27 @@ function ShellHost(props) {
3959
5245
  segs.push(speed);
3960
5246
  return segs;
3961
5247
  };
5248
+ const statusPhase = createMemo(() => {
5249
+ if (!busy())
5250
+ return null;
5251
+ if (approval())
5252
+ return "approve";
5253
+ if (dock.toolActive())
5254
+ return "tool";
5255
+ if (streaming())
5256
+ return "stream";
5257
+ return "think";
5258
+ });
3962
5259
  const th = () => theme();
3963
5260
  return (() => {
3964
- var _el$ = _$createElement16("box");
3965
- _$setProp16(_el$, "style", {
5261
+ var _el$ = _$createElement18("box");
5262
+ _$setProp18(_el$, "style", {
3966
5263
  flexDirection: "column",
3967
5264
  flexGrow: 1
3968
5265
  });
3969
- _$insert16(_el$, (() => {
5266
+ _$insert18(_el$, (() => {
3970
5267
  var _c$ = _$memo9(() => !!showWelcome());
3971
- return () => _c$() ? _$createComponent15(WelcomeBanner, {
5268
+ return () => _c$() ? _$createComponent17(WelcomeBanner, {
3972
5269
  get theme() {
3973
5270
  return th();
3974
5271
  },
@@ -3981,7 +5278,7 @@ function ShellHost(props) {
3981
5278
  get plugins() {
3982
5279
  return plugins();
3983
5280
  }
3984
- }) : _$createComponent15(TranscriptWindow, _$mergeProps({
5281
+ }) : _$createComponent17(TranscriptWindow, _$mergeProps({
3985
5282
  get items() {
3986
5283
  return items();
3987
5284
  },
@@ -4000,26 +5297,10 @@ function ShellHost(props) {
4000
5297
  onLayout: (total, rows) => totalLines = total
4001
5298
  }));
4002
5299
  })(), null);
4003
- _$insert16(_el$, _$createComponent15(TodosWidget, {
4004
- get todos() {
4005
- return todos();
4006
- },
4007
- get theme() {
4008
- return th();
4009
- }
4010
- }), null);
4011
- _$insert16(_el$, _$createComponent15(SubagentWidget, {
4012
- get entries() {
4013
- return subagents();
4014
- },
4015
- get theme() {
4016
- return th();
4017
- }
4018
- }), null);
4019
- _$insert16(_el$, () => dock.dockView(), null);
4020
- _$insert16(_el$, (() => {
5300
+ _$insert18(_el$, () => dock.dockView(), null);
5301
+ _$insert18(_el$, (() => {
4021
5302
  var _c$2 = _$memo9(() => !!approval());
4022
- return () => _c$2() ? _$createComponent15(ApprovalCard, {
5303
+ return () => _c$2() ? _$createComponent17(ApprovalCard, {
4023
5304
  get toolName() {
4024
5305
  return approval().name;
4025
5306
  },
@@ -4034,15 +5315,15 @@ function ShellHost(props) {
4034
5315
  }
4035
5316
  }) : null;
4036
5317
  })(), null);
4037
- _$insert16(_el$, (() => {
5318
+ _$insert18(_el$, (() => {
4038
5319
  var _c$3 = _$memo9(() => !!stopConfirm());
4039
5320
  return () => _c$3() ? (() => {
4040
- var _el$2 = _$createElement16("box"), _el$3 = _$createElement16("text"), _el$5 = _$createElement16("text");
5321
+ var _el$2 = _$createElement18("box"), _el$3 = _$createElement18("text"), _el$5 = _$createElement18("text");
4041
5322
  _$insertNode13(_el$2, _el$3);
4042
5323
  _$insertNode13(_el$2, _el$5);
4043
5324
  _$insertNode13(_el$3, _$createTextNode11(`abort this turn?`));
4044
5325
  _$insertNode13(_el$5, _$createTextNode11(`y aborts · n/esc resumes`));
4045
- _$effect16((_p$) => {
5326
+ _$effect18((_p$) => {
4046
5327
  var _v$ = {
4047
5328
  border: true,
4048
5329
  borderStyle: "rounded",
@@ -4054,9 +5335,9 @@ function ShellHost(props) {
4054
5335
  }, _v$3 = {
4055
5336
  fg: th().tokens.dim
4056
5337
  };
4057
- _v$ !== _p$.e && (_p$.e = _$setProp16(_el$2, "style", _v$, _p$.e));
4058
- _v$2 !== _p$.t && (_p$.t = _$setProp16(_el$3, "style", _v$2, _p$.t));
4059
- _v$3 !== _p$.a && (_p$.a = _$setProp16(_el$5, "style", _v$3, _p$.a));
5338
+ _v$ !== _p$.e && (_p$.e = _$setProp18(_el$2, "style", _v$, _p$.e));
5339
+ _v$2 !== _p$.t && (_p$.t = _$setProp18(_el$3, "style", _v$2, _p$.t));
5340
+ _v$3 !== _p$.a && (_p$.a = _$setProp18(_el$5, "style", _v$3, _p$.a));
4060
5341
  return _p$;
4061
5342
  }, {
4062
5343
  e: undefined,
@@ -4066,26 +5347,26 @@ function ShellHost(props) {
4066
5347
  return _el$2;
4067
5348
  })() : null;
4068
5349
  })(), null);
4069
- _$insert16(_el$, (() => {
5350
+ _$insert18(_el$, (() => {
4070
5351
  var _c$4 = _$memo9(() => !!viewerId());
4071
5352
  return () => _c$4() ? (() => {
4072
- var _el$7 = _$createElement16("box"), _el$8 = _$createElement16("text");
5353
+ var _el$7 = _$createElement18("box"), _el$8 = _$createElement18("text");
4073
5354
  _$insertNode13(_el$7, _el$8);
4074
- _$insert16(_el$8, () => `child ${viewerId().slice(0, 8)} · s steer · esc back`);
4075
- _$insert16(_el$7, _$createComponent15(For12, {
5355
+ _$insert18(_el$8, () => `child ${viewerId().slice(0, 8)} · s steer · esc back`);
5356
+ _$insert18(_el$7, _$createComponent17(For14, {
4076
5357
  get each() {
4077
5358
  return viewerLines().slice(-7);
4078
5359
  },
4079
5360
  children: (l) => (() => {
4080
- var _el$9 = _$createElement16("text");
4081
- _$insert16(_el$9, l);
4082
- _$effect16((_$p) => _$setProp16(_el$9, "style", {
5361
+ var _el$9 = _$createElement18("text");
5362
+ _$insert18(_el$9, l);
5363
+ _$effect18((_$p) => _$setProp18(_el$9, "style", {
4083
5364
  fg: th().tokens.dim
4084
5365
  }, _$p));
4085
5366
  return _el$9;
4086
5367
  })()
4087
5368
  }), null);
4088
- _$effect16((_p$) => {
5369
+ _$effect18((_p$) => {
4089
5370
  var _v$4 = {
4090
5371
  border: true,
4091
5372
  borderStyle: "rounded",
@@ -4096,8 +5377,8 @@ function ShellHost(props) {
4096
5377
  }, _v$5 = {
4097
5378
  fg: th().tokens.accent
4098
5379
  };
4099
- _v$4 !== _p$.e && (_p$.e = _$setProp16(_el$7, "style", _v$4, _p$.e));
4100
- _v$5 !== _p$.t && (_p$.t = _$setProp16(_el$8, "style", _v$5, _p$.t));
5380
+ _v$4 !== _p$.e && (_p$.e = _$setProp18(_el$7, "style", _v$4, _p$.e));
5381
+ _v$5 !== _p$.t && (_p$.t = _$setProp18(_el$8, "style", _v$5, _p$.t));
4101
5382
  return _p$;
4102
5383
  }, {
4103
5384
  e: undefined,
@@ -4106,15 +5387,15 @@ function ShellHost(props) {
4106
5387
  return _el$7;
4107
5388
  })() : null;
4108
5389
  })(), null);
4109
- _$insert16(_el$, (() => {
5390
+ _$insert18(_el$, (() => {
4110
5391
  var _c$5 = _$memo9(() => !!steerFor());
4111
5392
  return () => _c$5() ? (() => {
4112
- var _el$0 = _$createElement16("box"), _el$1 = _$createElement16("text"), _el$11 = _$createElement16("text");
5393
+ var _el$0 = _$createElement18("box"), _el$1 = _$createElement18("text"), _el$11 = _$createElement18("text");
4113
5394
  _$insertNode13(_el$0, _el$1);
4114
5395
  _$insertNode13(_el$0, _el$11);
4115
5396
  _$insertNode13(_el$1, _$createTextNode11(`⚡ steer: `));
4116
- _$insert16(_el$11, () => steerBuffer() || " ");
4117
- _$effect16((_p$) => {
5397
+ _$insert18(_el$11, () => steerBuffer() || " ");
5398
+ _$effect18((_p$) => {
4118
5399
  var _v$6 = {
4119
5400
  border: true,
4120
5401
  borderStyle: "rounded",
@@ -4126,9 +5407,9 @@ function ShellHost(props) {
4126
5407
  }, _v$8 = {
4127
5408
  fg: th().tokens.text
4128
5409
  };
4129
- _v$6 !== _p$.e && (_p$.e = _$setProp16(_el$0, "style", _v$6, _p$.e));
4130
- _v$7 !== _p$.t && (_p$.t = _$setProp16(_el$1, "style", _v$7, _p$.t));
4131
- _v$8 !== _p$.a && (_p$.a = _$setProp16(_el$11, "style", _v$8, _p$.a));
5410
+ _v$6 !== _p$.e && (_p$.e = _$setProp18(_el$0, "style", _v$6, _p$.e));
5411
+ _v$7 !== _p$.t && (_p$.t = _$setProp18(_el$1, "style", _v$7, _p$.t));
5412
+ _v$8 !== _p$.a && (_p$.a = _$setProp18(_el$11, "style", _v$8, _p$.a));
4132
5413
  return _p$;
4133
5414
  }, {
4134
5415
  e: undefined,
@@ -4138,54 +5419,54 @@ function ShellHost(props) {
4138
5419
  return _el$0;
4139
5420
  })() : null;
4140
5421
  })(), null);
4141
- _$insert16(_el$, (() => {
5422
+ _$insert18(_el$, (() => {
4142
5423
  var _c$6 = _$memo9(() => !!(btwOpen() || btwLive()));
4143
5424
  return () => _c$6() ? (() => {
4144
- var _el$12 = _$createElement16("box"), _el$13 = _$createElement16("box"), _el$14 = _$createElement16("text"), _el$16 = _$createElement16("box"), _el$17 = _$createElement16("text");
5425
+ var _el$12 = _$createElement18("box"), _el$13 = _$createElement18("box"), _el$14 = _$createElement18("text"), _el$16 = _$createElement18("box"), _el$17 = _$createElement18("text");
4145
5426
  _$insertNode13(_el$12, _el$13);
4146
5427
  _$insertNode13(_el$13, _el$14);
4147
5428
  _$insertNode13(_el$13, _el$16);
4148
5429
  _$insertNode13(_el$13, _el$17);
4149
- _$setProp16(_el$13, "style", {
5430
+ _$setProp18(_el$13, "style", {
4150
5431
  flexDirection: "row"
4151
5432
  });
4152
5433
  _$insertNode13(_el$14, _$createTextNode11(`btw`));
4153
- _$setProp16(_el$16, "style", {
5434
+ _$setProp18(_el$16, "style", {
4154
5435
  flexGrow: 1
4155
5436
  });
4156
5437
  _$insertNode13(_el$17, _$createTextNode11(`/btw close`));
4157
- _$insert16(_el$12, _$createComponent15(For12, {
5438
+ _$insert18(_el$12, _$createComponent17(For14, {
4158
5439
  get each() {
4159
5440
  return _$memo9(() => !!btwLive())() ? [btwLive()] : btwPairs().slice(-2);
4160
5441
  },
4161
5442
  children: (pair) => (() => {
4162
- var _el$19 = _$createElement16("box"), _el$20 = _$createElement16("text");
5443
+ var _el$19 = _$createElement18("box"), _el$20 = _$createElement18("text");
4163
5444
  _$insertNode13(_el$19, _el$20);
4164
- _$setProp16(_el$19, "style", {
5445
+ _$setProp18(_el$19, "style", {
4165
5446
  flexDirection: "column"
4166
5447
  });
4167
- _$insert16(_el$20, () => `Q: ${pair.q.slice(0, 90)}`);
4168
- _$insert16(_el$19, _$createComponent15(For12, {
5448
+ _$insert18(_el$20, () => `Q: ${pair.q.slice(0, 90)}`);
5449
+ _$insert18(_el$19, _$createComponent17(For14, {
4169
5450
  get each() {
4170
5451
  return pair.a.split(`
4171
5452
  `).slice(0, 4);
4172
5453
  },
4173
5454
  children: (l) => (() => {
4174
- var _el$21 = _$createElement16("text");
4175
- _$insert16(_el$21, () => `A: ${l.slice(0, 100)}`);
4176
- _$effect16((_$p) => _$setProp16(_el$21, "style", {
5455
+ var _el$21 = _$createElement18("text");
5456
+ _$insert18(_el$21, () => `A: ${l.slice(0, 100)}`);
5457
+ _$effect18((_$p) => _$setProp18(_el$21, "style", {
4177
5458
  fg: th().tokens.text
4178
5459
  }, _$p));
4179
5460
  return _el$21;
4180
5461
  })()
4181
5462
  }), null);
4182
- _$effect16((_$p) => _$setProp16(_el$20, "style", {
5463
+ _$effect18((_$p) => _$setProp18(_el$20, "style", {
4183
5464
  fg: th().tokens.dim
4184
5465
  }, _$p));
4185
5466
  return _el$19;
4186
5467
  })()
4187
5468
  }), null);
4188
- _$effect16((_p$) => {
5469
+ _$effect18((_p$) => {
4189
5470
  var _v$9 = {
4190
5471
  border: true,
4191
5472
  borderStyle: "rounded",
@@ -4198,9 +5479,9 @@ function ShellHost(props) {
4198
5479
  }, _v$1 = {
4199
5480
  fg: th().tokens.dim
4200
5481
  };
4201
- _v$9 !== _p$.e && (_p$.e = _$setProp16(_el$12, "style", _v$9, _p$.e));
4202
- _v$0 !== _p$.t && (_p$.t = _$setProp16(_el$14, "style", _v$0, _p$.t));
4203
- _v$1 !== _p$.a && (_p$.a = _$setProp16(_el$17, "style", _v$1, _p$.a));
5482
+ _v$9 !== _p$.e && (_p$.e = _$setProp18(_el$12, "style", _v$9, _p$.e));
5483
+ _v$0 !== _p$.t && (_p$.t = _$setProp18(_el$14, "style", _v$0, _p$.t));
5484
+ _v$1 !== _p$.a && (_p$.a = _$setProp18(_el$17, "style", _v$1, _p$.a));
4204
5485
  return _p$;
4205
5486
  }, {
4206
5487
  e: undefined,
@@ -4210,36 +5491,36 @@ function ShellHost(props) {
4210
5491
  return _el$12;
4211
5492
  })() : null;
4212
5493
  })(), null);
4213
- _$insert16(_el$, (() => {
5494
+ _$insert18(_el$, (() => {
4214
5495
  var _c$7 = _$memo9(() => !!(queueOpen() || queueMsgs().length > 0));
4215
5496
  return () => _c$7() ? (() => {
4216
- var _el$22 = _$createElement16("box"), _el$23 = _$createElement16("box"), _el$24 = _$createElement16("text"), _el$26 = _$createElement16("box"), _el$27 = _$createElement16("text");
5497
+ var _el$22 = _$createElement18("box"), _el$23 = _$createElement18("box"), _el$24 = _$createElement18("text"), _el$26 = _$createElement18("box"), _el$27 = _$createElement18("text");
4217
5498
  _$insertNode13(_el$22, _el$23);
4218
5499
  _$insertNode13(_el$23, _el$24);
4219
5500
  _$insertNode13(_el$23, _el$26);
4220
5501
  _$insertNode13(_el$23, _el$27);
4221
- _$setProp16(_el$23, "style", {
5502
+ _$setProp18(_el$23, "style", {
4222
5503
  flexDirection: "row"
4223
5504
  });
4224
5505
  _$insertNode13(_el$24, _$createTextNode11(`queue`));
4225
- _$setProp16(_el$26, "style", {
5506
+ _$setProp18(_el$26, "style", {
4226
5507
  flexGrow: 1
4227
5508
  });
4228
5509
  _$insertNode13(_el$27, _$createTextNode11(`/queue &lt;msg&gt; enqueue · bare toggle`));
4229
- _$insert16(_el$22, _$createComponent15(For12, {
5510
+ _$insert18(_el$22, _$createComponent17(For14, {
4230
5511
  get each() {
4231
5512
  return queueMsgs();
4232
5513
  },
4233
5514
  children: (m, i) => (() => {
4234
- var _el$29 = _$createElement16("text");
4235
- _$insert16(_el$29, () => `${i() + 1}. ${m.slice(0, 80)}`);
4236
- _$effect16((_$p) => _$setProp16(_el$29, "style", {
5515
+ var _el$29 = _$createElement18("text");
5516
+ _$insert18(_el$29, () => `${i() + 1}. ${m.slice(0, 80)}`);
5517
+ _$effect18((_$p) => _$setProp18(_el$29, "style", {
4237
5518
  fg: th().tokens.text
4238
5519
  }, _$p));
4239
5520
  return _el$29;
4240
5521
  })()
4241
5522
  }), null);
4242
- _$effect16((_p$) => {
5523
+ _$effect18((_p$) => {
4243
5524
  var _v$10 = {
4244
5525
  border: true,
4245
5526
  borderStyle: "rounded",
@@ -4252,9 +5533,9 @@ function ShellHost(props) {
4252
5533
  }, _v$12 = {
4253
5534
  fg: th().tokens.dim
4254
5535
  };
4255
- _v$10 !== _p$.e && (_p$.e = _$setProp16(_el$22, "style", _v$10, _p$.e));
4256
- _v$11 !== _p$.t && (_p$.t = _$setProp16(_el$24, "style", _v$11, _p$.t));
4257
- _v$12 !== _p$.a && (_p$.a = _$setProp16(_el$27, "style", _v$12, _p$.a));
5536
+ _v$10 !== _p$.e && (_p$.e = _$setProp18(_el$22, "style", _v$10, _p$.e));
5537
+ _v$11 !== _p$.t && (_p$.t = _$setProp18(_el$24, "style", _v$11, _p$.t));
5538
+ _v$12 !== _p$.a && (_p$.a = _$setProp18(_el$27, "style", _v$12, _p$.a));
4258
5539
  return _p$;
4259
5540
  }, {
4260
5541
  e: undefined,
@@ -4264,10 +5545,10 @@ function ShellHost(props) {
4264
5545
  return _el$22;
4265
5546
  })() : null;
4266
5547
  })(), null);
4267
- _$insert16(_el$, () => loginFeature.view(), null);
4268
- _$insert16(_el$, (() => {
5548
+ _$insert18(_el$, () => loginFeature.view(), null);
5549
+ _$insert18(_el$, (() => {
4269
5550
  var _c$8 = _$memo9(() => !!overlay());
4270
- return () => _c$8() ? _$createComponent15(Select, {
5551
+ return () => _c$8() ? _$createComponent17(Select, {
4271
5552
  get title() {
4272
5553
  return overlay()?.title ?? "";
4273
5554
  },
@@ -4284,27 +5565,27 @@ function ShellHost(props) {
4284
5565
  onCancel: onOverlayCancel
4285
5566
  }) : null;
4286
5567
  })(), null);
4287
- _$insert16(_el$, (() => {
5568
+ _$insert18(_el$, (() => {
4288
5569
  var _c$9 = _$memo9(() => !!menuVisible());
4289
5570
  return () => _c$9() ? (() => {
4290
- var _el$30 = _$createElement16("box");
4291
- _$insert16(_el$30, _$createComponent15(For12, {
5571
+ var _el$30 = _$createElement18("box");
5572
+ _$insert18(_el$30, _$createComponent17(For14, {
4292
5573
  get each() {
4293
5574
  return filteredCommands();
4294
5575
  },
4295
5576
  children: (c, i) => (() => {
4296
- var _el$31 = _$createElement16("text"), _el$32 = _$createTextNode11(` `);
5577
+ var _el$31 = _$createElement18("text"), _el$32 = _$createTextNode11(` `);
4297
5578
  _$insertNode13(_el$31, _el$32);
4298
- _$insert16(_el$31, () => i() === clampedSel() ? "› " : " ", _el$32);
4299
- _$insert16(_el$31, () => c.name, _el$32);
4300
- _$insert16(_el$31, () => c.desc, null);
4301
- _$effect16((_$p) => _$setProp16(_el$31, "style", {
5579
+ _$insert18(_el$31, () => i() === clampedSel() ? "› " : " ", _el$32);
5580
+ _$insert18(_el$31, () => c.name, _el$32);
5581
+ _$insert18(_el$31, () => c.desc, null);
5582
+ _$effect18((_$p) => _$setProp18(_el$31, "style", {
4302
5583
  fg: i() === clampedSel() ? th().tokens.accent : undefined
4303
5584
  }, _$p));
4304
5585
  return _el$31;
4305
5586
  })()
4306
5587
  }));
4307
- _$effect16((_$p) => _$setProp16(_el$30, "style", {
5588
+ _$effect18((_$p) => _$setProp18(_el$30, "style", {
4308
5589
  border: true,
4309
5590
  borderColor: th().tokens.border,
4310
5591
  flexDirection: "column",
@@ -4313,7 +5594,23 @@ function ShellHost(props) {
4313
5594
  return _el$30;
4314
5595
  })() : null;
4315
5596
  })(), null);
4316
- _$insert16(_el$, _$createComponent15(InputLine, {
5597
+ _$insert18(_el$, _$createComponent17(StatusBar, {
5598
+ get theme() {
5599
+ return th();
5600
+ },
5601
+ get phase() {
5602
+ return statusPhase();
5603
+ },
5604
+ elapsed: turnElapsed,
5605
+ detail: () => dock.runningToolName() ?? "",
5606
+ get verbs() {
5607
+ return pluginConfig().statusVerbs;
5608
+ },
5609
+ get width() {
5610
+ return termCols();
5611
+ }
5612
+ }), null);
5613
+ _$insert18(_el$, _$createComponent17(InputLine, {
4317
5614
  get focused() {
4318
5615
  return !(approval() || overlay() || loginFeature.panelOpen() || viewerId() !== null);
4319
5616
  },
@@ -4352,15 +5649,31 @@ function ShellHost(props) {
4352
5649
  return setValueText();
4353
5650
  }
4354
5651
  }), null);
4355
- _$insert16(_el$, (() => {
5652
+ _$insert18(_el$, _$createComponent17(TodosWidget, {
5653
+ get todos() {
5654
+ return todos();
5655
+ },
5656
+ get theme() {
5657
+ return th();
5658
+ }
5659
+ }), null);
5660
+ _$insert18(_el$, _$createComponent17(SubagentWidget, {
5661
+ get entries() {
5662
+ return subagents();
5663
+ },
5664
+ get theme() {
5665
+ return th();
5666
+ }
5667
+ }), null);
5668
+ _$insert18(_el$, (() => {
4356
5669
  var _c$0 = _$memo9(() => !!hintsVisible());
4357
- return () => _c$0() ? _$createComponent15(FooterHints, {
5670
+ return () => _c$0() ? _$createComponent17(FooterHints, {
4358
5671
  get theme() {
4359
5672
  return th();
4360
5673
  }
4361
5674
  }) : null;
4362
5675
  })(), null);
4363
- _$insert16(_el$, _$createComponent15(PowerlineFooter, {
5676
+ _$insert18(_el$, _$createComponent17(PowerlineFooter, {
4364
5677
  get left() {
4365
5678
  return powerlineSegments();
4366
5679
  },
@@ -4525,6 +5838,7 @@ class HostSession {
4525
5838
  resumeSession(id) {
4526
5839
  this.newSession();
4527
5840
  this.#resumeId = id;
5841
+ return "ok";
4528
5842
  }
4529
5843
  async storedTranscript(id, skip = 0) {
4530
5844
  const persistence = this.#ctx.get?.("sessionPersistence");
@@ -4769,6 +6083,136 @@ ${snapshot.join(`
4769
6083
  const st = this.#ctx.get?.("settings");
4770
6084
  return st ? { describe: () => st.describe(), mutate: (ns, ops, rev) => st.mutate(ns, ops, rev) } : undefined;
4771
6085
  }
6086
+ listAgents() {
6087
+ const out = [];
6088
+ try {
6089
+ const home = process.env.DSH_HOME || join(process.env.HOME || "", ".dsh");
6090
+ const dir = join(home, "agents");
6091
+ if (!existsSync(dir))
6092
+ return [];
6093
+ for (const f of readdirSync(dir)) {
6094
+ if (!f.endsWith(".md"))
6095
+ continue;
6096
+ const full = join(dir, f);
6097
+ try {
6098
+ const text = readFileSync(full, "utf8");
6099
+ const m = /^---\n([\s\S]*?)\n---/.exec(text);
6100
+ const fm = {};
6101
+ if (m) {
6102
+ for (const line of m[1].split(`
6103
+ `)) {
6104
+ const kv = /^([a-zA-Z_]+):\s*(.*)$/.exec(line.trim());
6105
+ if (kv)
6106
+ fm[kv[1]] = kv[2].replace(/^"|"$|'"$/g, "").trim();
6107
+ }
6108
+ }
6109
+ out.push({
6110
+ name: fm.name ?? f.replace(/\.md$/, ""),
6111
+ displayName: fm.display_name,
6112
+ description: fm.description,
6113
+ model: fm.model,
6114
+ thinking: fm.thinking,
6115
+ deep: fm.deep,
6116
+ file: full
6117
+ });
6118
+ } catch (e) {
6119
+ out.push({ name: f, file: full, broken: String(e instanceof Error ? e.message : e).slice(0, 100) });
6120
+ }
6121
+ }
6122
+ } catch {}
6123
+ return out;
6124
+ }
6125
+ agentSet(name, field, value) {
6126
+ const home = process.env.DSH_HOME || join(process.env.HOME || "", ".dsh");
6127
+ const file = join(home, "agents", `${name}.md`);
6128
+ const text = readFileSync(file, "utf8");
6129
+ const lineRe = new RegExp(`^(${field}):\\s*.*$`, "m");
6130
+ let next;
6131
+ if (lineRe.test(text)) {
6132
+ next = text.replace(lineRe, `$1: ${value}`);
6133
+ } else if (/^---\\n[\\s\\S]*?\\n---/.test(text)) {
6134
+ next = text.replace(/^---\n/, `---
6135
+ ${field}: ${value}
6136
+ `);
6137
+ } else {
6138
+ next = `---
6139
+ ${field}: ${value}
6140
+ ---
6141
+
6142
+ ` + text;
6143
+ }
6144
+ writeFileSync(file, next);
6145
+ }
6146
+ remoteTailActive = false;
6147
+ remoteTailSink = null;
6148
+ async startRemoteTail(sessionId) {
6149
+ try {
6150
+ const home = process.env.DSH_HOME || join(process.env.HOME || "", ".dsh");
6151
+ const root = join(home, "sessions");
6152
+ let file;
6153
+ for (let depth = 0;depth < 4 && !file; depth++) {}
6154
+ const walk = (dir, depth) => {
6155
+ if (depth > 3)
6156
+ return;
6157
+ for (const name of readdirSync(dir)) {
6158
+ const full = join(dir, name);
6159
+ if (statSync(full).isDirectory()) {
6160
+ const found = walk(full, depth + 1);
6161
+ if (found)
6162
+ return found;
6163
+ } else if (name.includes(sessionId) && name.endsWith(".zstd")) {
6164
+ return full;
6165
+ }
6166
+ }
6167
+ return;
6168
+ };
6169
+ file = walk(root, 0);
6170
+ if (!file)
6171
+ return "log file not found for this session";
6172
+ this.remoteTailActive = true;
6173
+ const poll = async () => {
6174
+ if (!this.remoteTailActive)
6175
+ return;
6176
+ try {
6177
+ const r = await new Promise((res) => {
6178
+ const { execFile } = __require("node:child_process");
6179
+ execFile("zstd", ["-dc", file], { maxBuffer: 1 << 30 }, (error, stdout) => res({ error, stdout }));
6180
+ });
6181
+ if (r.error)
6182
+ return;
6183
+ const rows = [];
6184
+ for (const line of r.stdout.split(`
6185
+ `)) {
6186
+ if (!line.trim())
6187
+ continue;
6188
+ try {
6189
+ const ev = JSON.parse(line);
6190
+ const type = ev.type ?? "";
6191
+ if (!["user/message", "assistant/message", "tool/call", "tool/result"].includes(type))
6192
+ continue;
6193
+ const text = type === "assistant/message" ? (ev.data?.message?.content ?? []).filter((b) => b?.type === "text").map((b) => b.text).join(`
6194
+ `) : type === "user/message" ? (ev.data?.content ?? []).filter((b) => b?.type === "text").map((b) => b.text).join(`
6195
+ `) : `${ev.data?.name ?? "tool"}`;
6196
+ if (text.trim())
6197
+ rows.push({ kind: type === "user/message" ? "user" : "assistant", text: `${type === "tool/call" || type === "tool/result" ? "⚙ " : ""}${text}` });
6198
+ } catch {}
6199
+ }
6200
+ if (rows.length > 0 && this.remoteTailSink) {
6201
+ this.remoteTailSink(rows.map((r2) => ({ kind: r2.kind, text: r2.text, final: true })));
6202
+ }
6203
+ } catch {}
6204
+ if (this.remoteTailActive)
6205
+ setTimeout(poll, 2000);
6206
+ };
6207
+ poll();
6208
+ return;
6209
+ } catch (e) {
6210
+ return String(e instanceof Error ? e.message : e).slice(0, 150);
6211
+ }
6212
+ }
6213
+ stopRemoteTail() {
6214
+ this.remoteTailActive = false;
6215
+ }
4772
6216
  async searchSessions(query) {
4773
6217
  try {
4774
6218
  const q = this.#ctx.get?.("sessionQuery");
@@ -4783,6 +6227,23 @@ ${snapshot.join(`
4783
6227
  return [];
4784
6228
  }
4785
6229
  }
6230
+ async settingsDescribe() {
6231
+ try {
6232
+ const st = this.#ctx.get?.("settings");
6233
+ if (!st?.describe)
6234
+ return [];
6235
+ const out = await st.describe();
6236
+ return (Array.isArray(out) ? out : []).map((e) => ({ ns: String(e?.ns ?? ""), revision: e?.revision, value: e?.value }));
6237
+ } catch {
6238
+ return [];
6239
+ }
6240
+ }
6241
+ async settingsMutate(ns, ops, revision) {
6242
+ const st = this.#ctx.get?.("settings");
6243
+ if (!st?.mutate)
6244
+ throw new Error("settings service unavailable");
6245
+ await st.mutate(ns, ops, revision);
6246
+ }
4786
6247
  configPath(name = "config.json") {
4787
6248
  let dir = new URL(".", import.meta.url).pathname;
4788
6249
  for (let i = 0;i < 8; i++) {
@@ -4873,6 +6334,32 @@ ${snapshot.join(`
4873
6334
  }
4874
6335
  return out;
4875
6336
  }
6337
+ listSkills() {
6338
+ try {
6339
+ const reg = this.#ctx.get?.("skills");
6340
+ if (!reg?.list)
6341
+ return [];
6342
+ const list = reg.list() ?? [];
6343
+ return list.map((x) => ({
6344
+ name: String(x?.name ?? ""),
6345
+ description: String(x?.description ?? "").slice(0, 90),
6346
+ invocation: String(x?.invocation ?? "")
6347
+ })).filter((x) => x.name);
6348
+ } catch {
6349
+ return [];
6350
+ }
6351
+ }
6352
+ async reloadPlugins() {
6353
+ try {
6354
+ const loader = this.#ctx.get?.("loader");
6355
+ if (!loader)
6356
+ return "loader service unavailable";
6357
+ await loader.reload?.(new URL("../dist-host/index.js", import.meta.url).href);
6358
+ return;
6359
+ } catch (e) {
6360
+ return String(e instanceof Error ? e.message : e).slice(0, 200);
6361
+ }
6362
+ }
4876
6363
  listPlugins() {
4877
6364
  try {
4878
6365
  const root = new URL("../../../../package.json", import.meta.url).pathname;
@@ -4893,7 +6380,15 @@ ${snapshot.join(`
4893
6380
  }
4894
6381
  }
4895
6382
  executionMode() {
4896
- return this.listPlugins().some((p) => /ptc|codemode/i.test(p.name)) ? "ptc" : "native";
6383
+ try {
6384
+ const tools = this.#ctx.get?.("tools");
6385
+ if (typeof tools?.schemas !== "function")
6386
+ return "native";
6387
+ const schemas = tools.schemas(this.#handle?.agent) ?? [];
6388
+ return schemas.some((schema) => schema?.name === "run_code") ? "ptc" : "native";
6389
+ } catch {
6390
+ return "native";
6391
+ }
4897
6392
  }
4898
6393
  usageSummary() {
4899
6394
  const fmt = (n) => n >= 1000 ? `${(n / 1000).toFixed(1)}k` : `${n}`;
@@ -5105,6 +6600,7 @@ ${snapshot.join(`
5105
6600
  const cb = this.#cb;
5106
6601
  if (!cb?.onSubagentUpdate)
5107
6602
  return;
6603
+ const clamp = (v) => v && v.length > 240 ? v.slice(-240) : v;
5108
6604
  cb.onSubagentUpdate([...this.#children.entries()].map(([id, v]) => ({
5109
6605
  id,
5110
6606
  label: v.label,
@@ -5113,7 +6609,7 @@ ${snapshot.join(`
5113
6609
  rounds: v.rounds,
5114
6610
  ...v.tokens !== undefined ? { tokens: v.tokens } : {},
5115
6611
  elapsed: Math.max(0, Math.floor((Date.now() - v.startedAt) / 1000)),
5116
- ...v.lastLine ? { lastLine: v.lastLine } : {}
6612
+ ...v.lastLine ? { lastLine: clamp(v.lastLine) } : {}
5117
6613
  })));
5118
6614
  }
5119
6615
  historyTurns() {
@@ -5260,6 +6756,13 @@ ${snapshot.join(`
5260
6756
  #wire() {
5261
6757
  const ctx = this.#ctx;
5262
6758
  ctx.on("agent/assistant-stream", ({ agent, frame }) => {
6759
+ if (frame.type === "chunk" && frame.chunk?.type === "text-delta" && frame.chunk.text && agent.id !== this.#agentId) {
6760
+ const view = this.#children.get(agent.id);
6761
+ if (view && view.status === "running") {
6762
+ this.#children.set(agent.id, { ...view, lastLine: (view.lastLine ?? "") + frame.chunk.text });
6763
+ this.#emitChildren();
6764
+ }
6765
+ }
5263
6766
  if (this.#agentId === undefined || agent.id !== this.#agentId)
5264
6767
  return;
5265
6768
  const cb = this.#cb;
@@ -5432,7 +6935,7 @@ function apply(ctx, config) {
5432
6935
  mountEngine({}).then(({
5433
6936
  renderer
5434
6937
  }) => {
5435
- render(() => _$createComponent16(ShellHost, {
6938
+ render(() => _$createComponent18(ShellHost, {
5436
6939
  get deps() {
5437
6940
  return {
5438
6941
  store,