@kubbisec/ai-linux-arm64 0.1.20 → 0.1.22

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 (131) hide show
  1. package/bin/kubbisec +0 -0
  2. package/bundled/clarify/clarify-gate-state.d.ts +1 -1
  3. package/bundled/clarify/clarify-gate-state.js +3 -3
  4. package/bundled/clarify/clarify-gate.d.ts +21 -14
  5. package/bundled/clarify/clarify-gate.js +118 -111
  6. package/bundled/clarify/clarify-select-panel.d.ts +16 -9
  7. package/bundled/clarify/clarify-select-panel.js +65 -67
  8. package/bundled/clarify/clarify-ui-state.d.ts +12 -10
  9. package/bundled/clarify/clarify-ui-state.js +26 -26
  10. package/bundled/clarify/parse-clarify-answer.d.ts +29 -18
  11. package/bundled/clarify/parse-clarify-answer.js +39 -45
  12. package/bundled/clarify/question-format.d.ts +34 -23
  13. package/bundled/clarify/question-format.js +112 -119
  14. package/bundled/clarify/questionnaire-tool.d.ts +28 -17
  15. package/bundled/clarify/questionnaire-tool.js +180 -144
  16. package/bundled/clarify/scope-discovery.d.ts +8 -5
  17. package/bundled/clarify/scope-discovery.js +102 -110
  18. package/bundled/clarify/session-questionnaire.d.ts +48 -13
  19. package/bundled/clarify/session-questionnaire.js +304 -312
  20. package/bundled/clarify/session-questionnaire.types.d.ts +29 -27
  21. package/bundled/clarify/session-questionnaire.types.js +10 -10
  22. package/bundled/components/kubbisec-model-selector.d.ts +47 -34
  23. package/bundled/components/kubbisec-model-selector.js +187 -177
  24. package/bundled/config/config.d.ts +6 -6
  25. package/bundled/config/config.js +55 -55
  26. package/bundled/config/detect-local-llm-providers.d.ts +26 -16
  27. package/bundled/config/detect-local-llm-providers.js +130 -142
  28. package/bundled/config/ensure-kubbisec-project-settings.d.ts +9 -9
  29. package/bundled/config/ensure-kubbisec-project-settings.js +44 -48
  30. package/bundled/config/extended-context.d.ts +5 -6
  31. package/bundled/config/extended-context.js +23 -22
  32. package/bundled/config/feature-flags.d.ts +10 -2
  33. package/bundled/config/feature-flags.js +8 -2
  34. package/bundled/config/format-kubbisec-footer-status.d.ts +1 -1
  35. package/bundled/config/format-kubbisec-footer-status.js +26 -31
  36. package/bundled/config/kubbisec-extension-manifest.d.ts +22 -2
  37. package/bundled/config/kubbisec-extension-manifest.js +20 -20
  38. package/bundled/config/llm-config-mutations.d.ts +51 -25
  39. package/bundled/config/llm-config-mutations.js +173 -182
  40. package/bundled/config/llm-config.d.ts +54 -41
  41. package/bundled/config/llm-config.js +199 -199
  42. package/bundled/config/llm-provider-catalog.d.ts +18 -15
  43. package/bundled/config/llm-provider-catalog.js +45 -46
  44. package/bundled/config/materialize-kubbisec-pi-resources.d.ts +1 -1
  45. package/bundled/config/materialize-kubbisec-pi-resources.js +174 -183
  46. package/bundled/config/register-custom-llm-providers.d.ts +11 -5
  47. package/bundled/config/register-custom-llm-providers.js +17 -15
  48. package/bundled/config/register-kubbisec-llm-provider.d.ts +14 -10
  49. package/bundled/config/register-kubbisec-llm-provider.js +50 -42
  50. package/bundled/config/resolve-agents-context-file.d.ts +1 -1
  51. package/bundled/config/resolve-agents-context-file.js +33 -34
  52. package/bundled/config/resource-budget.d.ts +12 -12
  53. package/bundled/config/resource-budget.js +28 -28
  54. package/bundled/config/sync-kubbisec-pi-models.d.ts +6 -3
  55. package/bundled/config/sync-kubbisec-pi-models.js +58 -58
  56. package/bundled/copy/cli-reference-index.d.ts +3 -2
  57. package/bundled/copy/cli-reference-index.js +1 -1
  58. package/bundled/copy/kubbisec-shell-copy.d.ts +11 -6
  59. package/bundled/copy/kubbisec-shell-copy.js +1 -1
  60. package/bundled/extensions/cli-local-shared.d.ts +45 -26
  61. package/bundled/extensions/cli-local-shared.js +128 -118
  62. package/bundled/extensions/kubbisec-aspm-local.extension.d.ts +18 -15
  63. package/bundled/extensions/kubbisec-aspm-local.extension.js +118 -114
  64. package/bundled/extensions/kubbisec-brand.extension.d.ts +1 -1
  65. package/bundled/extensions/kubbisec-brand.extension.js +25 -25
  66. package/bundled/extensions/kubbisec-byok-provider.extension.d.ts +1 -1
  67. package/bundled/extensions/kubbisec-byok-provider.extension.js +2 -2
  68. package/bundled/extensions/kubbisec-clarify.extension.d.ts +64 -35
  69. package/bundled/extensions/kubbisec-clarify.extension.js +323 -305
  70. package/bundled/extensions/kubbisec-exit.extension.d.ts +1 -1
  71. package/bundled/extensions/kubbisec-exit.extension.js +29 -32
  72. package/bundled/extensions/kubbisec-extended-context.extension.d.ts +1 -1
  73. package/bundled/extensions/kubbisec-extended-context.extension.js +56 -43
  74. package/bundled/extensions/kubbisec-footer.extension.d.ts +14 -14
  75. package/bundled/extensions/kubbisec-footer.extension.js +205 -215
  76. package/bundled/extensions/kubbisec-github-local.extension.d.ts +26 -18
  77. package/bundled/extensions/kubbisec-github-local.extension.js +123 -116
  78. package/bundled/extensions/kubbisec-llm-config.extension.d.ts +1 -1
  79. package/bundled/extensions/kubbisec-llm-config.extension.js +200 -181
  80. package/bundled/extensions/kubbisec-memory.extension.d.ts +9 -7
  81. package/bundled/extensions/kubbisec-memory.extension.js +88 -95
  82. package/bundled/extensions/kubbisec-naus-local.extension.d.ts +18 -15
  83. package/bundled/extensions/kubbisec-naus-local.extension.js +132 -111
  84. package/bundled/extensions/kubbisec-platform-tools.extension.d.ts +31 -21
  85. package/bundled/extensions/kubbisec-platform-tools.extension.js +152 -152
  86. package/bundled/extensions/kubbisec-runtime-status.extension.d.ts +10 -8
  87. package/bundled/extensions/kubbisec-runtime-status.extension.js +15 -13
  88. package/bundled/extensions/kubbisec-scope.extension.d.ts +12 -7
  89. package/bundled/extensions/kubbisec-scope.extension.js +13 -13
  90. package/bundled/extensions/kubbisec-skill-mentions.extension.d.ts +27 -16
  91. package/bundled/extensions/kubbisec-skill-mentions.extension.js +73 -63
  92. package/bundled/extensions/kubbisec-skill-telemetry.extension.d.ts +2 -3
  93. package/bundled/extensions/kubbisec-skill-telemetry.extension.js +59 -64
  94. package/bundled/extensions/kubbisec-theme-lock.extension.d.ts +1 -1
  95. package/bundled/extensions/kubbisec-theme-lock.extension.js +33 -34
  96. package/bundled/extensions/kubbisec-ui.extension.d.ts +1 -1
  97. package/bundled/extensions/kubbisec-ui.extension.js +114 -109
  98. package/bundled/extensions/kubbisec-workflow.extension.d.ts +20 -18
  99. package/bundled/extensions/kubbisec-workflow.extension.js +138 -140
  100. package/bundled/node_modules/@aspm/shared/dist/redaction.test.d.ts +2 -0
  101. package/bundled/node_modules/@aspm/shared/dist/redaction.test.d.ts.map +1 -0
  102. package/bundled/node_modules/@aspm/shared/dist/redaction.test.js +626 -0
  103. package/bundled/node_modules/@aspm/shared/dist/redaction.test.js.map +1 -0
  104. package/bundled/resolve-bundled-dist-root.js +122 -131
  105. package/bundled/skills/at-path-mentions.d.ts +1 -1
  106. package/bundled/skills/at-path-mentions.js +146 -153
  107. package/bundled/skills/chat-mention-render.d.ts +2 -2
  108. package/bundled/skills/chat-mention-render.js +121 -126
  109. package/bundled/skills/chat-mentions.d.ts +17 -8
  110. package/bundled/skills/chat-mentions.js +76 -76
  111. package/bundled/skills/list-bundled-skills.d.ts +3 -3
  112. package/bundled/skills/list-bundled-skills.js +33 -35
  113. package/bundled/skills/skill-mention.d.ts +10 -2
  114. package/bundled/skills/skill-mention.js +10 -2
  115. package/bundled/theme/clear-terminal.d.ts +1 -1
  116. package/bundled/theme/clear-terminal.js +3 -4
  117. package/bundled/theme/footer-render-hook.d.ts +1 -1
  118. package/bundled/theme/footer-render-hook.js +3 -3
  119. package/bundled/theme/kubbisec-brand-fg.d.ts +1 -1
  120. package/bundled/theme/kubbisec-brand-fg.js +2 -2
  121. package/bundled/theme/kubbisec-menu-themes.d.ts +7 -7
  122. package/bundled/theme/kubbisec-menu-themes.js +30 -31
  123. package/bundled/theme/kubbisec-theme-name.d.ts +1 -1
  124. package/bundled/theme/kubbisec-theme-name.js +1 -1
  125. package/bundled/theme/patch-pi-settings-theme.runtime.d.ts +1 -1
  126. package/bundled/theme/patch-pi-settings-theme.runtime.js +11 -10
  127. package/bundled/theme/render-compact-header.d.ts +13 -5
  128. package/bundled/theme/render-compact-header.js +127 -129
  129. package/bundled/workflow/session-workflow-mode.d.ts +1 -1
  130. package/bundled/workflow/session-workflow-mode.js +33 -33
  131. package/package.json +1 -1
@@ -3,45 +3,47 @@ export type SessionQuestionnaireStatus = "collecting" | "ready";
3
3
  export type ClarifyOptionId = "A" | "B" | "C" | "D" | "E";
4
4
  export type QuestionnaireScenario = "remediation" | "plan" | "explore" | "review";
5
5
  export type SessionQuestionnaireFields = {
6
- projectIds: string[];
7
- severityMin: string | null;
8
- remediationMode: "auto" | "suggestion" | null;
9
- nausConstraints: string | null;
10
- extendedContext: boolean | null;
11
- customNotes: string | null;
12
- extras: Record<string, string>;
6
+ projectIds: string[];
7
+ severityMin: string | null;
8
+ remediationMode: "auto" | "suggestion" | null;
9
+ nausConstraints: string | null;
10
+ extendedContext: boolean | null;
11
+ customNotes: string | null;
12
+ extras: Record<string, string>;
13
13
  };
14
14
  export type QuestionnaireHistoryEntry = {
15
- field: string;
16
- question: string;
17
- askedAt: string;
18
- answer: {
15
+ field: string;
16
+ question: string;
17
+ askedAt: string;
18
+ answer:
19
+ | {
19
20
  kind: "option";
20
21
  optionId: ClarifyOptionId;
21
22
  detail?: string;
22
23
  label?: string;
23
- } | {
24
+ }
25
+ | {
24
26
  kind: "custom";
25
27
  text: string;
26
- };
28
+ };
27
29
  };
28
30
  export type ClarifySelectionMode = "single" | "multi";
29
31
  export type PendingQuestion = {
30
- field: string;
31
- questionMarkdown: string;
32
- optionLabels: string[];
33
- selectionMode?: ClarifySelectionMode;
32
+ field: string;
33
+ questionMarkdown: string;
34
+ optionLabels: string[];
35
+ selectionMode?: ClarifySelectionMode;
34
36
  };
35
37
  export type SessionQuestionnaire = {
36
- $schema: typeof SESSION_QUESTIONNAIRE_SCHEMA;
37
- sessionId: string;
38
- status: SessionQuestionnaireStatus;
39
- scenario: QuestionnaireScenario | null;
40
- updatedAt: string;
41
- fields: SessionQuestionnaireFields;
42
- history: QuestionnaireHistoryEntry[];
43
- awaitingUserAnswer: boolean;
44
- pending: PendingQuestion | null;
38
+ $schema: typeof SESSION_QUESTIONNAIRE_SCHEMA;
39
+ sessionId: string;
40
+ status: SessionQuestionnaireStatus;
41
+ scenario: QuestionnaireScenario | null;
42
+ updatedAt: string;
43
+ fields: SessionQuestionnaireFields;
44
+ history: QuestionnaireHistoryEntry[];
45
+ awaitingUserAnswer: boolean;
46
+ pending: PendingQuestion | null;
45
47
  };
46
48
  export declare function createEmptyFields(): SessionQuestionnaireFields;
47
- //# sourceMappingURL=session-questionnaire.types.d.ts.map
49
+ //# sourceMappingURL=session-questionnaire.types.d.ts.map
@@ -1,13 +1,13 @@
1
1
  export const SESSION_QUESTIONNAIRE_SCHEMA = "kubbisec.sessionQuestionnaire.v2";
2
2
  export function createEmptyFields() {
3
- return {
4
- projectIds: [],
5
- severityMin: null,
6
- remediationMode: null,
7
- nausConstraints: null,
8
- extendedContext: null,
9
- customNotes: null,
10
- extras: {},
11
- };
3
+ return {
4
+ projectIds: [],
5
+ severityMin: null,
6
+ remediationMode: null,
7
+ nausConstraints: null,
8
+ extendedContext: null,
9
+ customNotes: null,
10
+ extras: {},
11
+ };
12
12
  }
13
- //# sourceMappingURL=session-questionnaire.types.js.map
13
+ //# sourceMappingURL=session-questionnaire.types.js.map
@@ -1,44 +1,57 @@
1
1
  import type { Api, Model } from "@earendil-works/pi-ai";
2
2
  import { Container, Input, type TUI } from "@earendil-works/pi-tui";
3
+
3
4
  type KubbisecModel = Model<Api>;
4
5
  type KubbisecTheme = {
5
- fg: (role: string, text: string) => string;
6
+ fg: (role: string, text: string) => string;
6
7
  };
7
8
  export type KubbisecModelGroup = {
8
- provider: string;
9
- displayName: string;
10
- models: KubbisecModel[];
9
+ provider: string;
10
+ displayName: string;
11
+ models: KubbisecModel[];
11
12
  };
12
- export type KubbisecModelListItem = {
13
- kind: "header";
14
- provider: string;
15
- label: string;
16
- } | {
17
- kind: "model";
18
- provider: string;
19
- model: KubbisecModel;
20
- };
21
- export declare function groupModelsForSelector(models: KubbisecModel[], getProviderDisplayName: (provider: string) => string): KubbisecModelGroup[];
13
+ export type KubbisecModelListItem =
14
+ | {
15
+ kind: "header";
16
+ provider: string;
17
+ label: string;
18
+ }
19
+ | {
20
+ kind: "model";
21
+ provider: string;
22
+ model: KubbisecModel;
23
+ };
24
+ export declare function groupModelsForSelector(
25
+ models: KubbisecModel[],
26
+ getProviderDisplayName: (provider: string) => string,
27
+ ): KubbisecModelGroup[];
22
28
  export declare function flattenGroupedModels(groups: KubbisecModelGroup[]): KubbisecModelListItem[];
23
29
  export declare class KubbisecModelSelectorComponent extends Container {
24
- private theme;
25
- private onSelect;
26
- private onCancel;
27
- private searchInput;
28
- private listContainer;
29
- private allItems;
30
- private filteredItems;
31
- private selectableIndexes;
32
- private selectedIndex;
33
- private currentModel?;
34
- private _focused;
35
- get focused(): boolean;
36
- set focused(value: boolean);
37
- constructor(_tui: TUI, currentModel: KubbisecModel | undefined, groups: KubbisecModelGroup[], theme: KubbisecTheme, onSelect: (model: KubbisecModel) => void, onCancel: () => void, initialSearch?: string);
38
- getSearchInput(): Input;
39
- private filterModels;
40
- private renderList;
41
- handleInput(keyData: string): void;
30
+ private theme;
31
+ private onSelect;
32
+ private onCancel;
33
+ private searchInput;
34
+ private listContainer;
35
+ private allItems;
36
+ private filteredItems;
37
+ private selectableIndexes;
38
+ private selectedIndex;
39
+ private currentModel?;
40
+ private _focused;
41
+ get focused(): boolean;
42
+ set focused(value: boolean);
43
+ constructor(
44
+ _tui: TUI,
45
+ currentModel: KubbisecModel | undefined,
46
+ groups: KubbisecModelGroup[],
47
+ theme: KubbisecTheme,
48
+ onSelect: (model: KubbisecModel) => void,
49
+ onCancel: () => void,
50
+ initialSearch?: string,
51
+ );
52
+ getSearchInput(): Input;
53
+ private filterModels;
54
+ private renderList;
55
+ handleInput(keyData: string): void;
42
56
  }
43
- export {};
44
- //# sourceMappingURL=kubbisec-model-selector.d.ts.map
57
+ //# sourceMappingURL=kubbisec-model-selector.d.ts.map
@@ -2,197 +2,207 @@ import { DynamicBorder } from "@earendil-works/pi-coding-agent";
2
2
  import { Container, getKeybindings, Input, Spacer, Text } from "@earendil-works/pi-tui";
3
3
  import { kubbisecBrandFg } from "../theme/kubbisec-brand-fg.js";
4
4
  export function groupModelsForSelector(models, getProviderDisplayName) {
5
- const byProvider = new Map();
6
- for (const model of models) {
7
- const list = byProvider.get(model.provider) ?? [];
8
- list.push(model);
9
- byProvider.set(model.provider, list);
10
- }
11
- const providerRank = (provider) => {
12
- if (provider === "kubbisec")
13
- return 0;
14
- if (provider === "ollama")
15
- return 1;
16
- if (provider === "lmstudio")
17
- return 2;
18
- return 10;
19
- };
20
- const providers = [...byProvider.keys()].sort((a, b) => {
21
- const rankDiff = providerRank(a) - providerRank(b);
22
- if (rankDiff !== 0)
23
- return rankDiff;
24
- return getProviderDisplayName(a).localeCompare(getProviderDisplayName(b));
25
- });
26
- return providers.map((provider) => ({
27
- provider,
28
- displayName: getProviderDisplayName(provider),
29
- models: (byProvider.get(provider) ?? []).sort((a, b) => a.name.localeCompare(b.name)),
30
- }));
5
+ const byProvider = new Map();
6
+ for (const model of models) {
7
+ const list = byProvider.get(model.provider) ?? [];
8
+ list.push(model);
9
+ byProvider.set(model.provider, list);
10
+ }
11
+ const providerRank = (provider) => {
12
+ if (provider === "kubbisec") return 0;
13
+ if (provider === "ollama") return 1;
14
+ if (provider === "lmstudio") return 2;
15
+ return 10;
16
+ };
17
+ const providers = [...byProvider.keys()].sort((a, b) => {
18
+ const rankDiff = providerRank(a) - providerRank(b);
19
+ if (rankDiff !== 0) return rankDiff;
20
+ return getProviderDisplayName(a).localeCompare(getProviderDisplayName(b));
21
+ });
22
+ return providers.map((provider) => ({
23
+ provider,
24
+ displayName: getProviderDisplayName(provider),
25
+ models: (byProvider.get(provider) ?? []).sort((a, b) => a.name.localeCompare(b.name)),
26
+ }));
31
27
  }
32
28
  export function flattenGroupedModels(groups) {
33
- const items = [];
34
- for (const group of groups) {
35
- items.push({ kind: "header", provider: group.provider, label: group.displayName });
36
- for (const model of group.models) {
37
- items.push({ kind: "model", provider: group.provider, model });
38
- }
29
+ const items = [];
30
+ for (const group of groups) {
31
+ items.push({ kind: "header", provider: group.provider, label: group.displayName });
32
+ for (const model of group.models) {
33
+ items.push({ kind: "model", provider: group.provider, model });
39
34
  }
40
- return items;
35
+ }
36
+ return items;
41
37
  }
42
38
  function fuzzyMatch(query, model, providerLabel) {
43
- const haystack = `${model.id} ${model.name} ${model.provider} ${providerLabel}`.toLowerCase();
44
- const tokens = query.toLowerCase().split(/\s+/).filter(Boolean);
45
- return tokens.every((token) => haystack.includes(token));
39
+ const haystack = `${model.id} ${model.name} ${model.provider} ${providerLabel}`.toLowerCase();
40
+ const tokens = query.toLowerCase().split(/\s+/).filter(Boolean);
41
+ return tokens.every((token) => haystack.includes(token));
46
42
  }
47
43
  export class KubbisecModelSelectorComponent extends Container {
48
- theme;
49
- onSelect;
50
- onCancel;
51
- searchInput;
52
- listContainer = new Container();
53
- allItems = [];
54
- filteredItems = [];
55
- selectableIndexes = [];
56
- selectedIndex = 0;
57
- currentModel;
58
- _focused = false;
59
- get focused() {
60
- return this._focused;
44
+ theme;
45
+ onSelect;
46
+ onCancel;
47
+ searchInput;
48
+ listContainer = new Container();
49
+ allItems = [];
50
+ filteredItems = [];
51
+ selectableIndexes = [];
52
+ selectedIndex = 0;
53
+ currentModel;
54
+ _focused = false;
55
+ get focused() {
56
+ return this._focused;
57
+ }
58
+ set focused(value) {
59
+ this._focused = value;
60
+ this.searchInput.focused = value;
61
+ }
62
+ constructor(_tui, currentModel, groups, theme, onSelect, onCancel, initialSearch = "") {
63
+ super();
64
+ this.theme = theme;
65
+ this.onSelect = onSelect;
66
+ this.onCancel = onCancel;
67
+ this.currentModel = currentModel;
68
+ this.allItems = flattenGroupedModels(groups);
69
+ const borderColor = (text) => this.theme.fg("borderAccent", text);
70
+ this.addChild(new DynamicBorder(borderColor));
71
+ this.addChild(new Spacer(1));
72
+ this.addChild(new Text(kubbisecBrandFg("Selecionar modelo"), 0, 0));
73
+ this.addChild(new Spacer(1));
74
+ this.searchInput = new Input();
75
+ if (initialSearch) this.searchInput.setValue(initialSearch);
76
+ this.searchInput.onSubmit = () => {
77
+ const listIndex = this.selectableIndexes[this.selectedIndex];
78
+ const item = listIndex == null ? undefined : this.filteredItems[listIndex];
79
+ if (item?.kind === "model") {
80
+ this.onSelect(item.model);
81
+ }
82
+ };
83
+ this.addChild(this.searchInput);
84
+ this.addChild(new Spacer(1));
85
+ this.addChild(this.listContainer);
86
+ this.addChild(new Spacer(1));
87
+ this.addChild(new DynamicBorder(borderColor));
88
+ this.filterModels(initialSearch);
89
+ }
90
+ getSearchInput() {
91
+ return this.searchInput;
92
+ }
93
+ filterModels(query) {
94
+ const trimmed = query.trim();
95
+ if (!trimmed) {
96
+ this.filteredItems = this.allItems;
97
+ } else {
98
+ const visibleProviders = new Set();
99
+ const filtered = [];
100
+ for (const item of this.allItems) {
101
+ if (item.kind === "header") continue;
102
+ const header = this.allItems.find(
103
+ (entry) => entry.kind === "header" && entry.provider === item.provider,
104
+ );
105
+ const providerLabel = header?.kind === "header" ? header.label : item.provider;
106
+ if (fuzzyMatch(trimmed, item.model, providerLabel)) {
107
+ if (!visibleProviders.has(item.provider)) {
108
+ visibleProviders.add(item.provider);
109
+ if (header?.kind === "header") filtered.push(header);
110
+ }
111
+ filtered.push(item);
112
+ }
113
+ }
114
+ this.filteredItems = filtered;
61
115
  }
62
- set focused(value) {
63
- this._focused = value;
64
- this.searchInput.focused = value;
116
+ this.selectableIndexes = this.filteredItems
117
+ .map((item, index) => (item.kind === "model" ? index : -1))
118
+ .filter((index) => index >= 0);
119
+ const currentSelectable = this.selectableIndexes.findIndex((index) => {
120
+ const item = this.filteredItems[index];
121
+ return item?.kind === "model" && modelsEqual(this.currentModel, item.model);
122
+ });
123
+ this.selectedIndex = currentSelectable >= 0 ? currentSelectable : 0;
124
+ this.renderList();
125
+ }
126
+ renderList() {
127
+ this.listContainer.clear();
128
+ const maxVisible = 12;
129
+ const start = Math.max(
130
+ 0,
131
+ Math.min(
132
+ this.selectedIndex - Math.floor(maxVisible / 2),
133
+ Math.max(0, this.selectableIndexes.length - maxVisible),
134
+ ),
135
+ );
136
+ const end = Math.min(start + maxVisible, this.selectableIndexes.length);
137
+ for (let i = start; i < end; i += 1) {
138
+ const listIndex = this.selectableIndexes[i];
139
+ const item = this.filteredItems[listIndex];
140
+ if (item?.kind !== "model") continue;
141
+ const header = this.filteredItems.find(
142
+ (entry, idx) =>
143
+ idx < listIndex && entry.kind === "header" && entry.provider === item.provider,
144
+ );
145
+ if (
146
+ header?.kind === "header" &&
147
+ (i === start || this.selectableIndexes[i - 1] === undefined)
148
+ ) {
149
+ this.listContainer.addChild(
150
+ new Text(this.theme.fg("muted", `── ${header.label} ──`), 0, 0),
151
+ );
152
+ } else if (
153
+ header?.kind === "header" &&
154
+ i > start &&
155
+ this.filteredItems[this.selectableIndexes[i - 1]]?.kind === "model" &&
156
+ this.filteredItems[this.selectableIndexes[i - 1]]?.provider !== item.provider
157
+ ) {
158
+ this.listContainer.addChild(
159
+ new Text(this.theme.fg("muted", `── ${header.label} ──`), 0, 0),
160
+ );
161
+ }
162
+ const isSelected = i === this.selectedIndex;
163
+ const isCurrent = modelsEqual(this.currentModel, item.model);
164
+ const prefix = isSelected ? kubbisecBrandFg("→ ") : " ";
165
+ const name = isSelected ? kubbisecBrandFg(item.model.name) : item.model.name;
166
+ const id = this.theme.fg("muted", ` (${item.model.id})`);
167
+ const check = isCurrent ? kubbisecBrandFg(" ✓") : "";
168
+ this.listContainer.addChild(new Text(`${prefix}${name}${id}${check}`, 0, 0));
65
169
  }
66
- constructor(_tui, currentModel, groups, theme, onSelect, onCancel, initialSearch = "") {
67
- super();
68
- this.theme = theme;
69
- this.onSelect = onSelect;
70
- this.onCancel = onCancel;
71
- this.currentModel = currentModel;
72
- this.allItems = flattenGroupedModels(groups);
73
- const borderColor = (text) => this.theme.fg("borderAccent", text);
74
- this.addChild(new DynamicBorder(borderColor));
75
- this.addChild(new Spacer(1));
76
- this.addChild(new Text(kubbisecBrandFg("Selecionar modelo"), 0, 0));
77
- this.addChild(new Spacer(1));
78
- this.searchInput = new Input();
79
- if (initialSearch)
80
- this.searchInput.setValue(initialSearch);
81
- this.searchInput.onSubmit = () => {
82
- const listIndex = this.selectableIndexes[this.selectedIndex];
83
- const item = listIndex == null ? undefined : this.filteredItems[listIndex];
84
- if (item?.kind === "model") {
85
- this.onSelect(item.model);
86
- }
87
- };
88
- this.addChild(this.searchInput);
89
- this.addChild(new Spacer(1));
90
- this.addChild(this.listContainer);
91
- this.addChild(new Spacer(1));
92
- this.addChild(new DynamicBorder(borderColor));
93
- this.filterModels(initialSearch);
170
+ if (this.selectableIndexes.length === 0) {
171
+ this.listContainer.addChild(
172
+ new Text(this.theme.fg("muted", " Nenhum modelo encontrado"), 0, 0),
173
+ );
94
174
  }
95
- getSearchInput() {
96
- return this.searchInput;
175
+ }
176
+ handleInput(keyData) {
177
+ const kb = getKeybindings();
178
+ if (kb.matches(keyData, "tui.select.up")) {
179
+ this.selectedIndex = Math.max(0, this.selectedIndex - 1);
180
+ this.renderList();
181
+ return;
97
182
  }
98
- filterModels(query) {
99
- const trimmed = query.trim();
100
- if (!trimmed) {
101
- this.filteredItems = this.allItems;
102
- }
103
- else {
104
- const visibleProviders = new Set();
105
- const filtered = [];
106
- for (const item of this.allItems) {
107
- if (item.kind === "header")
108
- continue;
109
- const header = this.allItems.find((entry) => entry.kind === "header" && entry.provider === item.provider);
110
- const providerLabel = header?.kind === "header" ? header.label : item.provider;
111
- if (fuzzyMatch(trimmed, item.model, providerLabel)) {
112
- if (!visibleProviders.has(item.provider)) {
113
- visibleProviders.add(item.provider);
114
- if (header?.kind === "header")
115
- filtered.push(header);
116
- }
117
- filtered.push(item);
118
- }
119
- }
120
- this.filteredItems = filtered;
121
- }
122
- this.selectableIndexes = this.filteredItems
123
- .map((item, index) => (item.kind === "model" ? index : -1))
124
- .filter((index) => index >= 0);
125
- const currentSelectable = this.selectableIndexes.findIndex((index) => {
126
- const item = this.filteredItems[index];
127
- return item?.kind === "model" && modelsEqual(this.currentModel, item.model);
128
- });
129
- this.selectedIndex = currentSelectable >= 0 ? currentSelectable : 0;
130
- this.renderList();
183
+ if (kb.matches(keyData, "tui.select.down")) {
184
+ this.selectedIndex = Math.min(this.selectableIndexes.length - 1, this.selectedIndex + 1);
185
+ this.renderList();
186
+ return;
131
187
  }
132
- renderList() {
133
- this.listContainer.clear();
134
- const maxVisible = 12;
135
- const start = Math.max(0, Math.min(this.selectedIndex - Math.floor(maxVisible / 2), Math.max(0, this.selectableIndexes.length - maxVisible)));
136
- const end = Math.min(start + maxVisible, this.selectableIndexes.length);
137
- for (let i = start; i < end; i += 1) {
138
- const listIndex = this.selectableIndexes[i];
139
- const item = this.filteredItems[listIndex];
140
- if (!item || item.kind !== "model")
141
- continue;
142
- const header = this.filteredItems.find((entry, idx) => idx < listIndex && entry.kind === "header" && entry.provider === item.provider);
143
- if (header?.kind === "header" &&
144
- (i === start || this.selectableIndexes[i - 1] === undefined)) {
145
- this.listContainer.addChild(new Text(this.theme.fg("muted", `── ${header.label} ──`), 0, 0));
146
- }
147
- else if (header?.kind === "header" &&
148
- i > start &&
149
- this.filteredItems[this.selectableIndexes[i - 1]]?.kind === "model" &&
150
- this.filteredItems[this.selectableIndexes[i - 1]]?.provider !== item.provider) {
151
- this.listContainer.addChild(new Text(this.theme.fg("muted", `── ${header.label} ──`), 0, 0));
152
- }
153
- const isSelected = i === this.selectedIndex;
154
- const isCurrent = modelsEqual(this.currentModel, item.model);
155
- const prefix = isSelected ? kubbisecBrandFg("→ ") : " ";
156
- const name = isSelected ? kubbisecBrandFg(item.model.name) : item.model.name;
157
- const id = this.theme.fg("muted", ` (${item.model.id})`);
158
- const check = isCurrent ? kubbisecBrandFg(" ✓") : "";
159
- this.listContainer.addChild(new Text(`${prefix}${name}${id}${check}`, 0, 0));
160
- }
161
- if (this.selectableIndexes.length === 0) {
162
- this.listContainer.addChild(new Text(this.theme.fg("muted", " Nenhum modelo encontrado"), 0, 0));
163
- }
188
+ if (kb.matches(keyData, "tui.select.confirm")) {
189
+ const listIndex = this.selectableIndexes[this.selectedIndex];
190
+ const item = listIndex == null ? undefined : this.filteredItems[listIndex];
191
+ if (item?.kind === "model") {
192
+ this.onSelect(item.model);
193
+ }
194
+ return;
164
195
  }
165
- handleInput(keyData) {
166
- const kb = getKeybindings();
167
- if (kb.matches(keyData, "tui.select.up")) {
168
- this.selectedIndex = Math.max(0, this.selectedIndex - 1);
169
- this.renderList();
170
- return;
171
- }
172
- if (kb.matches(keyData, "tui.select.down")) {
173
- this.selectedIndex = Math.min(this.selectableIndexes.length - 1, this.selectedIndex + 1);
174
- this.renderList();
175
- return;
176
- }
177
- if (kb.matches(keyData, "tui.select.confirm")) {
178
- const listIndex = this.selectableIndexes[this.selectedIndex];
179
- const item = listIndex == null ? undefined : this.filteredItems[listIndex];
180
- if (item?.kind === "model") {
181
- this.onSelect(item.model);
182
- }
183
- return;
184
- }
185
- if (kb.matches(keyData, "tui.select.cancel")) {
186
- this.onCancel();
187
- return;
188
- }
189
- this.searchInput.handleInput(keyData);
190
- this.filterModels(this.searchInput.getValue());
196
+ if (kb.matches(keyData, "tui.select.cancel")) {
197
+ this.onCancel();
198
+ return;
191
199
  }
200
+ this.searchInput.handleInput(keyData);
201
+ this.filterModels(this.searchInput.getValue());
202
+ }
192
203
  }
193
204
  function modelsEqual(a, b) {
194
- if (!a || !b)
195
- return false;
196
- return a.provider === b.provider && a.id === b.id;
205
+ if (!a || !b) return false;
206
+ return a.provider === b.provider && a.id === b.id;
197
207
  }
198
- //# sourceMappingURL=kubbisec-model-selector.js.map
208
+ //# sourceMappingURL=kubbisec-model-selector.js.map
@@ -1,9 +1,9 @@
1
1
  export type KubbisecConfig = {
2
- apiUrl: string;
3
- apiKey: string;
4
- orgId?: string;
5
- defaultProject?: string;
6
- clientId?: string;
2
+ apiUrl: string;
3
+ apiKey: string;
4
+ orgId?: string;
5
+ defaultProject?: string;
6
+ clientId?: string;
7
7
  };
8
8
  export declare function getKubbisecStateDir(): string;
9
9
  export declare function getConfigPath(): string;
@@ -11,4 +11,4 @@ export declare function loadConfig(): Partial<KubbisecConfig>;
11
11
  export declare function saveConfig(partial: Partial<KubbisecConfig>): KubbisecConfig;
12
12
  export declare function clearConfig(): void;
13
13
  export declare function requireConfig(): KubbisecConfig;
14
- //# sourceMappingURL=config.d.ts.map
14
+ //# sourceMappingURL=config.d.ts.map