@sma1lboy/kobe 0.5.18 → 0.5.19

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.
Files changed (2) hide show
  1. package/dist/cli/index.js +273 -95
  2. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -15511,7 +15511,7 @@ var init_package = __esm(() => {
15511
15511
  package_default = {
15512
15512
  $schema: "https://json.schemastore.org/package.json",
15513
15513
  name: "@sma1lboy/kobe",
15514
- version: "0.5.18",
15514
+ version: "0.5.19",
15515
15515
  description: "TUI orchestrator for Claude Code (codename)",
15516
15516
  type: "module",
15517
15517
  packageManager: "bun@1.3.13",
@@ -30801,23 +30801,46 @@ var init_MessageList = __esm(() => {
30801
30801
  });
30802
30802
 
30803
30803
  // src/tui/panes/chat/composer/model-picker-row.ts
30804
- function modelPickerRowParts(choice) {
30805
- const caps = getCapabilities(choice.vendor);
30806
- return {
30807
- level: choice.level ?? "level1",
30808
- vendor: choice.vendor,
30809
- engine: caps.label,
30810
- from: "catalog",
30811
- model: choice.label,
30812
- hint: choice.hint
30813
- };
30804
+ function modelPickerModelOptions(choices) {
30805
+ const byKey = new Map;
30806
+ for (const choice of choices) {
30807
+ const key = `${choice.vendor}:${choice.id}`;
30808
+ const bucket = byKey.get(key);
30809
+ if (bucket)
30810
+ bucket.push(choice);
30811
+ else
30812
+ byKey.set(key, [choice]);
30813
+ }
30814
+ return [...byKey.values()].map((bucket) => {
30815
+ const base = bucket.find((choice) => choice.effort === undefined) ?? bucket[0];
30816
+ if (!base) {
30817
+ throw new Error("model picker option bucket unexpectedly empty");
30818
+ }
30819
+ return {
30820
+ vendor: base.vendor,
30821
+ id: base.id,
30822
+ label: stripEffortSuffix(base.label, base.effort),
30823
+ hint: base.hint,
30824
+ choices: bucket
30825
+ };
30826
+ });
30814
30827
  }
30815
- function modelPickerMetaLabel(parts) {
30816
- return `${parts.level} ${parts.vendor} ${parts.engine} from ${parts.from}`;
30828
+ function modelPickerEffortOptions(model) {
30829
+ return model.choices.map((choice) => ({
30830
+ id: choice.id,
30831
+ effort: choice.effort,
30832
+ label: choice.effort ?? "default",
30833
+ hint: choice.effort ? choice.hint : choice.hint ?? "use the model default"
30834
+ }));
30835
+ }
30836
+ function stripEffortSuffix(label, effort) {
30837
+ if (!effort)
30838
+ return label;
30839
+ return label.replace(new RegExp(`\\s+\xB7\\s+${escapeRegExp3(effort)}$`), "");
30840
+ }
30841
+ function escapeRegExp3(value) {
30842
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
30817
30843
  }
30818
- var init_model_picker_row = __esm(() => {
30819
- init_registry2();
30820
- });
30821
30844
 
30822
30845
  // src/tui/panes/chat/composer/ModelPicker.tsx
30823
30846
  import { TextAttributes as TextAttributes24 } from "@opentui/core";
@@ -30826,137 +30849,293 @@ function ModelPicker(props) {
30826
30849
  const {
30827
30850
  theme
30828
30851
  } = useTheme();
30829
- const choices = createMemo(() => allModels());
30852
+ const models = createMemo(() => modelPickerModelOptions(allModels()));
30853
+ const [selectedModel, setSelectedModel] = createSignal();
30854
+ const effortChoices = createMemo(() => {
30855
+ const model = selectedModel();
30856
+ return model ? modelPickerEffortOptions(model) : [];
30857
+ });
30830
30858
  const seed = props.current ?? defaultCapabilities.defaultModelId();
30831
- const initial = choices().findIndex((m2) => m2.id === seed && m2.effort === props.currentEffort);
30859
+ const initial = models().findIndex((m2) => m2.id === seed);
30832
30860
  const [cursor, setCursor] = createSignal(initial >= 0 ? initial : 0);
30861
+ const [effortCursor, setEffortCursor] = createSignal(0);
30862
+ const inEffortStep = () => selectedModel() !== undefined;
30863
+ function setInitialEffortCursor(model) {
30864
+ const efforts = modelPickerEffortOptions(model);
30865
+ const idx = efforts.findIndex((choice) => choice.effort === props.currentEffort);
30866
+ setEffortCursor(idx >= 0 ? idx : 0);
30867
+ }
30833
30868
  function commit() {
30834
- const choice = choices()[cursor()];
30869
+ if (inEffortStep()) {
30870
+ commitEffort();
30871
+ return;
30872
+ }
30873
+ const model = models()[cursor()];
30874
+ if (!model)
30875
+ return;
30876
+ const efforts = modelPickerEffortOptions(model);
30877
+ if (efforts.length <= 1 && efforts[0]?.effort === undefined) {
30878
+ props.onPick({
30879
+ id: model.id,
30880
+ effort: undefined
30881
+ });
30882
+ dialog.clear();
30883
+ return;
30884
+ }
30885
+ setSelectedModel(model);
30886
+ setInitialEffortCursor(model);
30887
+ }
30888
+ function commitEffort() {
30889
+ const model = selectedModel();
30890
+ if (!model)
30891
+ return;
30892
+ const choice = effortChoices()[effortCursor()];
30835
30893
  if (!choice)
30836
30894
  return;
30837
30895
  props.onPick({
30838
- id: choice.id,
30896
+ id: model.id,
30839
30897
  effort: choice.effort
30840
30898
  });
30841
30899
  dialog.clear();
30842
30900
  }
30901
+ function backToModels() {
30902
+ setSelectedModel(undefined);
30903
+ }
30843
30904
  useBindings(() => ({
30844
30905
  bindings: [{
30845
30906
  key: "up",
30846
30907
  cmd: () => {
30847
- const n2 = choices().length;
30908
+ const n2 = inEffortStep() ? effortChoices().length : models().length;
30848
30909
  if (n2 === 0)
30849
30910
  return;
30850
- setCursor((c2) => (c2 - 1 + n2) % n2);
30911
+ if (inEffortStep())
30912
+ setEffortCursor((c2) => (c2 - 1 + n2) % n2);
30913
+ else
30914
+ setCursor((c2) => (c2 - 1 + n2) % n2);
30851
30915
  }
30852
30916
  }, {
30853
30917
  key: "down",
30854
30918
  cmd: () => {
30855
- const n2 = choices().length;
30919
+ const n2 = inEffortStep() ? effortChoices().length : models().length;
30856
30920
  if (n2 === 0)
30857
30921
  return;
30858
- setCursor((c2) => (c2 + 1) % n2);
30922
+ if (inEffortStep())
30923
+ setEffortCursor((c2) => (c2 + 1) % n2);
30924
+ else
30925
+ setCursor((c2) => (c2 + 1) % n2);
30859
30926
  }
30860
30927
  }, {
30861
30928
  key: "k",
30862
30929
  cmd: () => {
30863
- const n2 = choices().length;
30930
+ const n2 = inEffortStep() ? effortChoices().length : models().length;
30864
30931
  if (n2 === 0)
30865
30932
  return;
30866
- setCursor((c2) => (c2 - 1 + n2) % n2);
30933
+ if (inEffortStep())
30934
+ setEffortCursor((c2) => (c2 - 1 + n2) % n2);
30935
+ else
30936
+ setCursor((c2) => (c2 - 1 + n2) % n2);
30867
30937
  }
30868
30938
  }, {
30869
30939
  key: "j",
30870
30940
  cmd: () => {
30871
- const n2 = choices().length;
30941
+ const n2 = inEffortStep() ? effortChoices().length : models().length;
30872
30942
  if (n2 === 0)
30873
30943
  return;
30874
- setCursor((c2) => (c2 + 1) % n2);
30944
+ if (inEffortStep())
30945
+ setEffortCursor((c2) => (c2 + 1) % n2);
30946
+ else
30947
+ setCursor((c2) => (c2 + 1) % n2);
30875
30948
  }
30949
+ }, {
30950
+ key: "left",
30951
+ cmd: backToModels
30952
+ }, {
30953
+ key: "h",
30954
+ cmd: backToModels
30876
30955
  }, {
30877
30956
  key: "return",
30878
30957
  cmd: commit
30879
30958
  }]
30880
30959
  }));
30881
30960
  return (() => {
30882
- var _el$ = createElement("box"), _el$2 = createElement("box"), _el$3 = createElement("text"), _el$5 = createElement("text"), _el$7 = createElement("box"), _el$8 = createElement("box"), _el$9 = createElement("text");
30961
+ var _el$ = createElement("box"), _el$2 = createElement("box"), _el$3 = createElement("text"), _el$4 = createElement("text"), _el$6 = createElement("box"), _el$7 = createElement("text");
30883
30962
  insertNode(_el$, _el$2);
30884
- insertNode(_el$, _el$7);
30885
- insertNode(_el$, _el$8);
30963
+ insertNode(_el$, _el$6);
30886
30964
  setProp(_el$, "paddingLeft", 2);
30887
30965
  setProp(_el$, "paddingRight", 2);
30888
30966
  setProp(_el$, "gap", 1);
30889
30967
  insertNode(_el$2, _el$3);
30890
- insertNode(_el$2, _el$5);
30968
+ insertNode(_el$2, _el$4);
30891
30969
  setProp(_el$2, "flexDirection", "row");
30892
30970
  setProp(_el$2, "justifyContent", "space-between");
30893
- insertNode(_el$3, createTextNode(`Pick a model`));
30894
- insertNode(_el$5, createTextNode(`esc`));
30895
- setProp(_el$5, "onMouseUp", () => props.onCancel());
30896
- setProp(_el$7, "flexDirection", "column");
30897
- setProp(_el$7, "paddingBottom", 1);
30898
- insert(_el$7, createComponent2(For, {
30899
- get each() {
30900
- return choices();
30901
- },
30902
- children: (choice, i2) => {
30903
- const active = () => i2() === cursor();
30904
- const parts = () => modelPickerRowParts(choice);
30905
- return (() => {
30906
- var _el$1 = createElement("box"), _el$10 = createElement("text"), _el$11 = createElement("text");
30907
- insertNode(_el$1, _el$10);
30908
- insertNode(_el$1, _el$11);
30909
- setProp(_el$1, "flexDirection", "row");
30910
- setProp(_el$1, "gap", 2);
30911
- setProp(_el$1, "paddingLeft", 1);
30912
- setProp(_el$1, "paddingRight", 1);
30913
- setProp(_el$1, "onMouseUp", () => {
30914
- setCursor(i2());
30915
- commit();
30916
- });
30917
- setProp(_el$10, "wrapMode", "none");
30918
- insert(_el$10, () => active() ? "\u25B8 " : " ", null);
30919
- insert(_el$10, () => modelPickerMetaLabel(parts()), null);
30920
- setProp(_el$11, "wrapMode", "none");
30921
- insert(_el$11, () => parts().model);
30922
- insert(_el$1, (() => {
30923
- var _c$ = memo2(() => !!parts().hint);
30924
- return () => _c$() ? (() => {
30925
- var _el$12 = createElement("text");
30971
+ insert(_el$3, () => inEffortStep() ? "Pick effort" : "Pick a model");
30972
+ insertNode(_el$4, createTextNode(`esc`));
30973
+ setProp(_el$4, "onMouseUp", () => props.onCancel());
30974
+ insert(_el$, (() => {
30975
+ var _c$ = memo2(() => !!inEffortStep());
30976
+ return () => _c$() ? (() => {
30977
+ var _el$8 = createElement("box"), _el$9 = createElement("box"), _el$0 = createElement("text"), _el$10 = createElement("text");
30978
+ insertNode(_el$8, _el$9);
30979
+ setProp(_el$8, "flexDirection", "column");
30980
+ setProp(_el$8, "paddingBottom", 1);
30981
+ insertNode(_el$9, _el$0);
30982
+ insertNode(_el$9, _el$10);
30983
+ setProp(_el$9, "flexDirection", "row");
30984
+ setProp(_el$9, "gap", 2);
30985
+ setProp(_el$9, "paddingLeft", 1);
30986
+ setProp(_el$9, "paddingRight", 1);
30987
+ insertNode(_el$0, createTextNode(`model`));
30988
+ setProp(_el$0, "wrapMode", "none");
30989
+ setProp(_el$10, "wrapMode", "none");
30990
+ insert(_el$10, () => selectedModel()?.label);
30991
+ insert(_el$8, createComponent2(For, {
30992
+ get each() {
30993
+ return effortChoices();
30994
+ },
30995
+ children: (choice, i2) => {
30996
+ const active = () => i2() === effortCursor();
30997
+ return (() => {
30998
+ var _el$11 = createElement("box"), _el$12 = createElement("text");
30999
+ insertNode(_el$11, _el$12);
31000
+ setProp(_el$11, "flexDirection", "row");
31001
+ setProp(_el$11, "gap", 2);
31002
+ setProp(_el$11, "paddingLeft", 1);
31003
+ setProp(_el$11, "paddingRight", 1);
31004
+ setProp(_el$11, "onMouseUp", () => {
31005
+ setEffortCursor(i2());
31006
+ props.onPick({
31007
+ id: choice.id,
31008
+ effort: choice.effort
31009
+ });
31010
+ dialog.clear();
31011
+ });
30926
31012
  setProp(_el$12, "wrapMode", "none");
30927
- insert(_el$12, () => parts().hint);
30928
- effect((_$p) => setProp(_el$12, "fg", active() ? theme.selectedListItemText : theme.textMuted, _$p));
30929
- return _el$12;
30930
- })() : null;
30931
- })(), null);
30932
- effect((_p$) => {
30933
- var _v$5 = active() ? theme.primary : undefined, _v$6 = active() ? theme.selectedListItemText : theme.text, _v$7 = active() ? TextAttributes24.BOLD : undefined, _v$8 = active() ? theme.selectedListItemText : theme.text, _v$9 = active() ? TextAttributes24.BOLD : undefined;
30934
- _v$5 !== _p$.e && (_p$.e = setProp(_el$1, "backgroundColor", _v$5, _p$.e));
30935
- _v$6 !== _p$.t && (_p$.t = setProp(_el$10, "fg", _v$6, _p$.t));
30936
- _v$7 !== _p$.a && (_p$.a = setProp(_el$10, "attributes", _v$7, _p$.a));
30937
- _v$8 !== _p$.o && (_p$.o = setProp(_el$11, "fg", _v$8, _p$.o));
30938
- _v$9 !== _p$.i && (_p$.i = setProp(_el$11, "attributes", _v$9, _p$.i));
30939
- return _p$;
30940
- }, {
30941
- e: undefined,
30942
- t: undefined,
30943
- a: undefined,
30944
- o: undefined,
30945
- i: undefined
30946
- });
30947
- return _el$1;
30948
- })();
30949
- }
30950
- }));
30951
- insertNode(_el$8, _el$9);
30952
- setProp(_el$8, "paddingBottom", 1);
30953
- insertNode(_el$9, createTextNode(`\u2191\u2193 pick \xB7 enter select \xB7 esc cancel`));
31013
+ insert(_el$12, () => active() ? "\u25B8 " : " ", null);
31014
+ insert(_el$12, () => choice.label, null);
31015
+ insert(_el$11, (() => {
31016
+ var _c$2 = memo2(() => !!choice.hint);
31017
+ return () => _c$2() ? (() => {
31018
+ var _el$13 = createElement("text");
31019
+ setProp(_el$13, "wrapMode", "none");
31020
+ insert(_el$13, () => choice.hint);
31021
+ effect((_$p) => setProp(_el$13, "fg", active() ? theme.selectedListItemText : theme.textMuted, _$p));
31022
+ return _el$13;
31023
+ })() : null;
31024
+ })(), null);
31025
+ effect((_p$) => {
31026
+ var _v$8 = active() ? theme.primary : undefined, _v$9 = active() ? theme.selectedListItemText : theme.text, _v$0 = active() ? TextAttributes24.BOLD : undefined;
31027
+ _v$8 !== _p$.e && (_p$.e = setProp(_el$11, "backgroundColor", _v$8, _p$.e));
31028
+ _v$9 !== _p$.t && (_p$.t = setProp(_el$12, "fg", _v$9, _p$.t));
31029
+ _v$0 !== _p$.a && (_p$.a = setProp(_el$12, "attributes", _v$0, _p$.a));
31030
+ return _p$;
31031
+ }, {
31032
+ e: undefined,
31033
+ t: undefined,
31034
+ a: undefined
31035
+ });
31036
+ return _el$11;
31037
+ })();
31038
+ }
31039
+ }), null);
31040
+ effect((_p$) => {
31041
+ var { textMuted: _v$5, text: _v$6 } = theme, _v$7 = TextAttributes24.BOLD;
31042
+ _v$5 !== _p$.e && (_p$.e = setProp(_el$0, "fg", _v$5, _p$.e));
31043
+ _v$6 !== _p$.t && (_p$.t = setProp(_el$10, "fg", _v$6, _p$.t));
31044
+ _v$7 !== _p$.a && (_p$.a = setProp(_el$10, "attributes", _v$7, _p$.a));
31045
+ return _p$;
31046
+ }, {
31047
+ e: undefined,
31048
+ t: undefined,
31049
+ a: undefined
31050
+ });
31051
+ return _el$8;
31052
+ })() : (() => {
31053
+ var _el$14 = createElement("box");
31054
+ setProp(_el$14, "flexDirection", "column");
31055
+ setProp(_el$14, "paddingBottom", 1);
31056
+ insert(_el$14, createComponent2(For, {
31057
+ get each() {
31058
+ return models();
31059
+ },
31060
+ children: (model, i2) => {
31061
+ const active = () => i2() === cursor();
31062
+ const hasEfforts = () => modelPickerEffortOptions(model).some((choice) => choice.effort !== undefined);
31063
+ return (() => {
31064
+ var _el$15 = createElement("box"), _el$16 = createElement("text"), _el$17 = createElement("text");
31065
+ insertNode(_el$15, _el$16);
31066
+ insertNode(_el$15, _el$17);
31067
+ setProp(_el$15, "flexDirection", "row");
31068
+ setProp(_el$15, "gap", 2);
31069
+ setProp(_el$15, "paddingLeft", 1);
31070
+ setProp(_el$15, "paddingRight", 1);
31071
+ setProp(_el$15, "onMouseUp", () => {
31072
+ const efforts = modelPickerEffortOptions(model);
31073
+ if (efforts.length <= 1 && efforts[0]?.effort === undefined) {
31074
+ props.onPick({
31075
+ id: model.id,
31076
+ effort: undefined
31077
+ });
31078
+ dialog.clear();
31079
+ return;
31080
+ }
31081
+ setCursor(i2());
31082
+ setSelectedModel(model);
31083
+ setInitialEffortCursor(model);
31084
+ });
31085
+ setProp(_el$16, "wrapMode", "none");
31086
+ insert(_el$16, () => active() ? "\u25B8 " : " ", null);
31087
+ insert(_el$16, () => model.label, null);
31088
+ setProp(_el$17, "wrapMode", "none");
31089
+ insert(_el$17, () => model.vendor);
31090
+ insert(_el$15, (() => {
31091
+ var _c$3 = memo2(() => !!hasEfforts());
31092
+ return () => _c$3() ? (() => {
31093
+ var _el$18 = createElement("text");
31094
+ insertNode(_el$18, createTextNode(`effort\u2026`));
31095
+ setProp(_el$18, "wrapMode", "none");
31096
+ effect((_$p) => setProp(_el$18, "fg", active() ? theme.selectedListItemText : theme.textMuted, _$p));
31097
+ return _el$18;
31098
+ })() : null;
31099
+ })(), null);
31100
+ insert(_el$15, (() => {
31101
+ var _c$4 = memo2(() => !!model.hint);
31102
+ return () => _c$4() ? (() => {
31103
+ var _el$20 = createElement("text");
31104
+ setProp(_el$20, "wrapMode", "none");
31105
+ insert(_el$20, () => model.hint);
31106
+ effect((_$p) => setProp(_el$20, "fg", active() ? theme.selectedListItemText : theme.textMuted, _$p));
31107
+ return _el$20;
31108
+ })() : null;
31109
+ })(), null);
31110
+ effect((_p$) => {
31111
+ var _v$1 = active() ? theme.primary : undefined, _v$10 = active() ? theme.selectedListItemText : theme.text, _v$11 = active() ? TextAttributes24.BOLD : undefined, _v$12 = active() ? theme.selectedListItemText : theme.textMuted;
31112
+ _v$1 !== _p$.e && (_p$.e = setProp(_el$15, "backgroundColor", _v$1, _p$.e));
31113
+ _v$10 !== _p$.t && (_p$.t = setProp(_el$16, "fg", _v$10, _p$.t));
31114
+ _v$11 !== _p$.a && (_p$.a = setProp(_el$16, "attributes", _v$11, _p$.a));
31115
+ _v$12 !== _p$.o && (_p$.o = setProp(_el$17, "fg", _v$12, _p$.o));
31116
+ return _p$;
31117
+ }, {
31118
+ e: undefined,
31119
+ t: undefined,
31120
+ a: undefined,
31121
+ o: undefined
31122
+ });
31123
+ return _el$15;
31124
+ })();
31125
+ }
31126
+ }));
31127
+ return _el$14;
31128
+ })();
31129
+ })(), _el$6);
31130
+ insertNode(_el$6, _el$7);
31131
+ setProp(_el$6, "paddingBottom", 1);
31132
+ insert(_el$7, () => inEffortStep() ? "\u2191\u2193 pick \xB7 enter select \xB7 h back \xB7 esc cancel" : "\u2191\u2193 pick \xB7 enter select \xB7 esc cancel");
30954
31133
  effect((_p$) => {
30955
31134
  var _v$ = TextAttributes24.BOLD, _v$2 = theme.text, _v$3 = theme.textMuted, _v$4 = theme.textMuted;
30956
31135
  _v$ !== _p$.e && (_p$.e = setProp(_el$3, "attributes", _v$, _p$.e));
30957
31136
  _v$2 !== _p$.t && (_p$.t = setProp(_el$3, "fg", _v$2, _p$.t));
30958
- _v$3 !== _p$.a && (_p$.a = setProp(_el$5, "fg", _v$3, _p$.a));
30959
- _v$4 !== _p$.o && (_p$.o = setProp(_el$9, "fg", _v$4, _p$.o));
31137
+ _v$3 !== _p$.a && (_p$.a = setProp(_el$4, "fg", _v$3, _p$.a));
31138
+ _v$4 !== _p$.o && (_p$.o = setProp(_el$7, "fg", _v$4, _p$.o));
30960
31139
  return _p$;
30961
31140
  }, {
30962
31141
  e: undefined,
@@ -30981,7 +31160,6 @@ var init_ModelPicker = __esm(() => {
30981
31160
  init_theme();
30982
31161
  init_keymap();
30983
31162
  init_dialog();
30984
- init_model_picker_row();
30985
31163
  ModelPicker.show = (dialog, current, currentEffort) => {
30986
31164
  return new Promise((resolve4) => {
30987
31165
  dialog.replace(() => createComponent2(ModelPicker, {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@sma1lboy/kobe",
4
- "version": "0.5.18",
4
+ "version": "0.5.19",
5
5
  "description": "TUI orchestrator for Claude Code (codename)",
6
6
  "type": "module",
7
7
  "packageManager": "bun@1.3.13",