@wrongstack/tui 0.51.3 → 0.54.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3769,12 +3769,28 @@ var LiveActivityStrip = React4.memo(function LiveActivityStrip2({
3769
3769
  ] }) }) : null
3770
3770
  ] });
3771
3771
  });
3772
+ var MAX_VISIBLE = 10;
3773
+ function getVisibleWindow(selected, total) {
3774
+ const half = Math.floor(MAX_VISIBLE / 2);
3775
+ let start = selected - half;
3776
+ let end = start + MAX_VISIBLE;
3777
+ if (start < 0) {
3778
+ start = 0;
3779
+ end = Math.min(total, MAX_VISIBLE);
3780
+ }
3781
+ if (end > total) {
3782
+ end = total;
3783
+ start = Math.max(0, end - MAX_VISIBLE);
3784
+ }
3785
+ return { start, end };
3786
+ }
3772
3787
  function ModelPicker({
3773
3788
  step,
3774
3789
  providerOptions,
3775
- modelOptions,
3790
+ filteredOptions,
3776
3791
  selected,
3777
3792
  pickedProviderId,
3793
+ searchQuery,
3778
3794
  hint
3779
3795
  }) {
3780
3796
  if (step === "provider") {
@@ -3799,17 +3815,47 @@ function ModelPicker({
3799
3815
  hint ? /* @__PURE__ */ jsx(Text, { color: "yellow", children: hint }) : null
3800
3816
  ] });
3801
3817
  }
3818
+ const total = filteredOptions.length;
3819
+ const { start, end } = getVisibleWindow(selected, total);
3820
+ const visibleItems = filteredOptions.slice(start, end);
3821
+ const searchHint = searchQuery ? ` | filter:"${searchQuery}" \u2192 ${total} match${total === 1 ? "" : "es"}` : total > MAX_VISIBLE ? ` (${total} models \u2014 type to filter)` : "";
3802
3822
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingX: 1, children: [
3803
3823
  /* @__PURE__ */ jsxs(Text, { color: "cyan", bold: true, children: [
3804
- "\u2501\u2501 Switch model \u2014 Step 2/2: Pick model (",
3824
+ "\u2501\u2501 Switch model \u2014 Step 2/2: Pick model ",
3825
+ "(",
3805
3826
  pickedProviderId,
3806
- ") \u2501\u2501"
3827
+ searchHint,
3828
+ ")",
3829
+ " \u2501\u2501"
3830
+ ] }),
3831
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191/\u2193 navigate \xB7 Enter select \xB7 Esc back \xB7 Ctrl+C exit \xB7 type to filter" }),
3832
+ total === 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: searchQuery ? `(no models match "${searchQuery}")` : "(no models known for this provider)" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
3833
+ start > 0 && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
3834
+ "\u25B2 ",
3835
+ start,
3836
+ " above"
3837
+ ] }),
3838
+ visibleItems.map((id, vi) => {
3839
+ const absoluteIndex = start + vi;
3840
+ return /* @__PURE__ */ jsxs(
3841
+ Text,
3842
+ {
3843
+ color: absoluteIndex === selected ? "cyan" : void 0,
3844
+ inverse: absoluteIndex === selected,
3845
+ children: [
3846
+ absoluteIndex === selected ? "\u203A " : " ",
3847
+ id
3848
+ ]
3849
+ },
3850
+ id
3851
+ );
3852
+ }),
3853
+ end < total && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
3854
+ "\u25BC ",
3855
+ total - end,
3856
+ " below"
3857
+ ] })
3807
3858
  ] }),
3808
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191/\u2193 navigate \xB7 Enter select \xB7 Esc back \xB7 Ctrl+C exit" }),
3809
- modelOptions.length === 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "(no models known for this provider)" }) : modelOptions.map((id, i) => /* @__PURE__ */ jsxs(Text, { color: i === selected ? "cyan" : void 0, inverse: i === selected, children: [
3810
- i === selected ? "\u203A " : " ",
3811
- id
3812
- ] }, id)),
3813
3859
  hint ? /* @__PURE__ */ jsx(Text, { color: "yellow", children: hint }) : null
3814
3860
  ] });
3815
3861
  }
@@ -4911,8 +4957,10 @@ function reducer(state, action) {
4911
4957
  step: "provider",
4912
4958
  providerOptions: action.providers,
4913
4959
  modelOptions: [],
4960
+ filteredOptions: [],
4914
4961
  selected: 0,
4915
- hint: void 0
4962
+ hint: void 0,
4963
+ searchQuery: ""
4916
4964
  }
4917
4965
  };
4918
4966
  case "modelPickerClose":
@@ -4923,12 +4971,15 @@ function reducer(state, action) {
4923
4971
  step: "provider",
4924
4972
  providerOptions: [],
4925
4973
  modelOptions: [],
4926
- selected: 0
4974
+ filteredOptions: [],
4975
+ selected: 0,
4976
+ searchQuery: ""
4927
4977
  }
4928
4978
  };
4929
4979
  case "modelPickerMove": {
4930
4980
  if (!state.modelPicker.open) return state;
4931
- const len = state.modelPicker.step === "provider" ? state.modelPicker.providerOptions.length : state.modelPicker.modelOptions.length;
4981
+ const list = state.modelPicker.step === "provider" ? state.modelPicker.providerOptions : state.modelPicker.filteredOptions;
4982
+ const len = list.length;
4932
4983
  if (len === 0) return state;
4933
4984
  const next = (state.modelPicker.selected + action.delta + len) % len;
4934
4985
  return {
@@ -4943,9 +4994,11 @@ function reducer(state, action) {
4943
4994
  ...state.modelPicker,
4944
4995
  step: "model",
4945
4996
  modelOptions: action.models,
4997
+ filteredOptions: action.models,
4946
4998
  selected: 0,
4947
4999
  pickedProviderId: action.providerId,
4948
- hint: void 0
5000
+ hint: void 0,
5001
+ searchQuery: ""
4949
5002
  }
4950
5003
  };
4951
5004
  case "modelPickerBack":
@@ -4955,11 +5008,29 @@ function reducer(state, action) {
4955
5008
  ...state.modelPicker,
4956
5009
  step: "provider",
4957
5010
  modelOptions: [],
5011
+ filteredOptions: [],
4958
5012
  selected: 0,
4959
5013
  pickedProviderId: void 0,
5014
+ hint: void 0,
5015
+ searchQuery: ""
5016
+ }
5017
+ };
5018
+ case "modelPickerSearch": {
5019
+ if (!state.modelPicker.open || state.modelPicker.step !== "model") return state;
5020
+ const q = action.query.toLowerCase();
5021
+ const filtered = q ? state.modelPicker.modelOptions.filter((id) => id.toLowerCase().includes(q)) : state.modelPicker.modelOptions;
5022
+ const selected = filtered.length > 0 ? Math.min(state.modelPicker.selected, filtered.length - 1) : 0;
5023
+ return {
5024
+ ...state,
5025
+ modelPicker: {
5026
+ ...state.modelPicker,
5027
+ filteredOptions: filtered,
5028
+ selected,
5029
+ searchQuery: action.query,
4960
5030
  hint: void 0
4961
5031
  }
4962
5032
  };
5033
+ }
4963
5034
  case "modelPickerHint":
4964
5035
  return {
4965
5036
  ...state,
@@ -5819,7 +5890,9 @@ function App({
5819
5890
  step: "provider",
5820
5891
  providerOptions: [],
5821
5892
  modelOptions: [],
5822
- selected: 0
5893
+ filteredOptions: [],
5894
+ selected: 0,
5895
+ searchQuery: ""
5823
5896
  },
5824
5897
  autonomyPicker: { open: false, options: [], selected: 0 },
5825
5898
  settingsPicker: { open: false, field: 0, mode: "off", delayMs: 0 },
@@ -7864,6 +7937,19 @@ function App({
7864
7937
  dispatch({ type: "modelPickerMove", delta: 1 });
7865
7938
  return;
7866
7939
  }
7940
+ if (state.modelPicker.step === "model" && input && !key.return && !key.backspace) {
7941
+ dispatch({ type: "modelPickerSearch", query: state.modelPicker.searchQuery + input });
7942
+ return;
7943
+ }
7944
+ if (state.modelPicker.step === "model" && key.backspace) {
7945
+ const q = state.modelPicker.searchQuery;
7946
+ if (q.length > 0) {
7947
+ dispatch({ type: "modelPickerSearch", query: q.slice(0, -1) });
7948
+ } else {
7949
+ dispatch({ type: "modelPickerBack" });
7950
+ }
7951
+ return;
7952
+ }
7867
7953
  if (isEnter) {
7868
7954
  inputGateRef.current = true;
7869
7955
  try {
@@ -7878,7 +7964,7 @@ function App({
7878
7964
  return;
7879
7965
  }
7880
7966
  const providerId = state.modelPicker.pickedProviderId;
7881
- const modelId = state.modelPicker.modelOptions[state.modelPicker.selected];
7967
+ const modelId = state.modelPicker.filteredOptions[state.modelPicker.selected];
7882
7968
  if (!providerId || !modelId) return;
7883
7969
  const err = switchProviderAndModel?.(providerId, modelId);
7884
7970
  if (err) {
@@ -8684,8 +8770,10 @@ User message:
8684
8770
  step: state.modelPicker.step,
8685
8771
  providerOptions: state.modelPicker.providerOptions,
8686
8772
  modelOptions: state.modelPicker.modelOptions,
8773
+ filteredOptions: state.modelPicker.filteredOptions,
8687
8774
  selected: state.modelPicker.selected,
8688
8775
  pickedProviderId: state.modelPicker.pickedProviderId,
8776
+ searchQuery: state.modelPicker.searchQuery,
8689
8777
  hint: state.modelPicker.hint
8690
8778
  }
8691
8779
  ) : null,