@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
@@ -2,254 +2,244 @@
2
2
  * KubbiSec AI footer: centered cwd, branch, model, and usage stats.
3
3
  */
4
4
  import { basename, isAbsolute, relative, resolve, sep } from "node:path";
5
- import { formatModelFooterLabel, formatModelFooterWithInferenceSettings, getRuntimeTemperature, readLlmConfig, } from "../config/llm-config.js";
5
+ import {
6
+ formatModelFooterLabel,
7
+ formatModelFooterWithInferenceSettings,
8
+ getRuntimeTemperature,
9
+ readLlmConfig,
10
+ } from "../config/llm-config.js";
6
11
  import { setKubbisecFooterRequestRender } from "../theme/footer-render-hook.js";
7
12
  import { kubbisecBrandFg } from "../theme/kubbisec-brand-fg.js";
8
13
  import { centerLine } from "../theme/render-compact-header.js";
9
- import { getSessionWorkflowFooterBadge, onSessionWorkflowStatusChange, } from "../workflow/session-workflow-mode.js";
14
+ import {
15
+ getSessionWorkflowFooterBadge,
16
+ onSessionWorkflowStatusChange,
17
+ } from "../workflow/session-workflow-mode.js";
18
+
10
19
  function visibleWidth(text) {
11
- return text.replace(/\x1b\[[0-9;]*m/g, "").length;
20
+ return text.replace(/\x1b\[[0-9;]*m/g, "").length;
12
21
  }
13
22
  function truncateToWidth(text, width, ellipsis) {
14
- if (visibleWidth(text) <= width)
15
- return text;
16
- const target = Math.max(0, width - visibleWidth(ellipsis));
17
- let out = "";
18
- let w = 0;
19
- let i = 0;
20
- while (i < text.length && w < target) {
21
- if (text[i] === "\x1b") {
22
- const end = text.indexOf("m", i);
23
- if (end === -1)
24
- break;
25
- out += text.slice(i, end + 1);
26
- i = end + 1;
27
- continue;
28
- }
29
- out += text[i];
30
- w += 1;
31
- i += 1;
23
+ if (visibleWidth(text) <= width) return text;
24
+ const target = Math.max(0, width - visibleWidth(ellipsis));
25
+ let out = "";
26
+ let w = 0;
27
+ let i = 0;
28
+ while (i < text.length && w < target) {
29
+ if (text[i] === "\x1b") {
30
+ const end = text.indexOf("m", i);
31
+ if (end === -1) break;
32
+ out += text.slice(i, end + 1);
33
+ i = end + 1;
34
+ continue;
32
35
  }
33
- return out + ellipsis;
36
+ out += text[i];
37
+ w += 1;
38
+ i += 1;
39
+ }
40
+ return out + ellipsis;
34
41
  }
35
42
  function formatTokens(count) {
36
- if (count < 1000)
37
- return count.toString();
38
- if (count < 10000)
39
- return `${(count / 1000).toFixed(1)}k`;
40
- if (count < 1000000)
41
- return `${Math.round(count / 1000)}k`;
42
- if (count < 10000000)
43
- return `${(count / 1000000).toFixed(1)}M`;
44
- return `${Math.round(count / 1000000)}M`;
43
+ if (count < 1000) return count.toString();
44
+ if (count < 10000) return `${(count / 1000).toFixed(1)}k`;
45
+ if (count < 1000000) return `${Math.round(count / 1000)}k`;
46
+ if (count < 10000000) return `${(count / 1000000).toFixed(1)}M`;
47
+ return `${Math.round(count / 1000000)}M`;
45
48
  }
46
49
  function truncatePathMiddle(text, maxWidth) {
47
- if (visibleWidth(text) <= maxWidth)
48
- return text;
49
- const branchMatch = text.match(/(\s\([^)]+\))$/);
50
- const branch = branchMatch?.[1] ?? "";
51
- const base = branch ? text.slice(0, -branch.length) : text;
52
- const ellipsis = "…";
53
- const room = maxWidth - visibleWidth(branch) - visibleWidth(ellipsis);
54
- if (room < 4)
55
- return truncateToWidth(text, maxWidth, ellipsis);
56
- const head = Math.max(2, Math.ceil(room * 0.45));
57
- const tail = Math.max(2, room - head);
58
- return base.slice(0, head) + ellipsis + base.slice(-tail) + branch;
50
+ if (visibleWidth(text) <= maxWidth) return text;
51
+ const branchMatch = text.match(/(\s\([^)]+\))$/);
52
+ const branch = branchMatch?.[1] ?? "";
53
+ const base = branch ? text.slice(0, -branch.length) : text;
54
+ const ellipsis = "…";
55
+ const room = maxWidth - visibleWidth(branch) - visibleWidth(ellipsis);
56
+ if (room < 4) return truncateToWidth(text, maxWidth, ellipsis);
57
+ const head = Math.max(2, Math.ceil(room * 0.45));
58
+ const tail = Math.max(2, room - head);
59
+ return base.slice(0, head) + ellipsis + base.slice(-tail) + branch;
59
60
  }
60
61
  function formatCwdForFooter(cwd, home) {
61
- if (!home)
62
- return cwd;
63
- const resolvedCwd = resolve(cwd);
64
- const resolvedHome = resolve(home);
65
- const relativeToHome = relative(resolvedHome, resolvedCwd);
66
- const isInsideHome = relativeToHome === "" ||
67
- (relativeToHome !== ".." &&
68
- !relativeToHome.startsWith(`..${sep}`) &&
69
- !isAbsolute(relativeToHome));
70
- if (!isInsideHome)
71
- return cwd;
72
- return relativeToHome === "" ? "~" : `~${sep}${relativeToHome}`;
62
+ if (!home) return cwd;
63
+ const resolvedCwd = resolve(cwd);
64
+ const resolvedHome = resolve(home);
65
+ const relativeToHome = relative(resolvedHome, resolvedCwd);
66
+ const isInsideHome =
67
+ relativeToHome === "" ||
68
+ (relativeToHome !== ".." &&
69
+ !relativeToHome.startsWith(`..${sep}`) &&
70
+ !isAbsolute(relativeToHome));
71
+ if (!isInsideHome) return cwd;
72
+ return relativeToHome === "" ? "~" : `~${sep}${relativeToHome}`;
73
73
  }
74
74
  /** Short folder label when git branch is shown separately; otherwise tilde path. */
75
75
  function formatLocationLabel(cwd, home, gitBranch) {
76
- const folder = basename(cwd) || cwd;
77
- if (gitBranch && folder)
78
- return folder;
79
- return formatCwdForFooter(cwd, home);
76
+ const folder = basename(cwd) || cwd;
77
+ if (gitBranch && folder) return folder;
78
+ return formatCwdForFooter(cwd, home);
80
79
  }
81
80
  const FOOTER_SEP = " · ";
82
81
  function joinFooterSegments(segments) {
83
- return segments.filter((s) => s.length > 0).join(FOOTER_SEP);
82
+ return segments.filter((s) => s.length > 0).join(FOOTER_SEP);
84
83
  }
85
84
  function resolveKubbisecFooterModelRef(ctx) {
86
- const model = ctx.model;
87
- if (model?.provider && model.id) {
88
- return formatModelFooterLabel(model.provider, model.id);
89
- }
90
- return (process.env.KUBBISEC_AI_MODEL_ID?.trim() ||
91
- process.env.KUBBISEC_AI_MODEL?.trim() ||
92
- process.env.KUBBISEC_PI_MODEL?.trim() ||
93
- process.env.NAUS_PI_MODEL?.trim() ||
94
- model?.id?.trim() ||
95
- "no-model");
85
+ const model = ctx.model;
86
+ if (model?.provider && model.id) {
87
+ return formatModelFooterLabel(model.provider, model.id);
88
+ }
89
+ return (
90
+ process.env.KUBBISEC_AI_MODEL_ID?.trim() ||
91
+ process.env.KUBBISEC_AI_MODEL?.trim() ||
92
+ process.env.KUBBISEC_PI_MODEL?.trim() ||
93
+ process.env.NAUS_PI_MODEL?.trim() ||
94
+ model?.id?.trim() ||
95
+ "no-model"
96
+ );
96
97
  }
97
98
  function resolveKubbisecFooterModelLabel(ctx, api) {
98
- const modelRef = resolveKubbisecFooterModelRef(ctx);
99
- const config = readLlmConfig(ctx.cwd);
100
- const thinkingLevel = api.getThinkingLevel() || config.defaultThinkingLevel;
101
- const temperature = getRuntimeTemperature(config);
102
- return formatModelFooterWithInferenceSettings(modelRef, thinkingLevel, temperature);
99
+ const modelRef = resolveKubbisecFooterModelRef(ctx);
100
+ const config = readLlmConfig(ctx.cwd);
101
+ const thinkingLevel = api.getThinkingLevel() || config.defaultThinkingLevel;
102
+ const temperature = getRuntimeTemperature(config);
103
+ return formatModelFooterWithInferenceSettings(modelRef, thinkingLevel, temperature);
103
104
  }
104
105
  function buildFooterPlainSegments(input) {
105
- const folder = basename(input.cwd);
106
- const location = formatLocationLabel(input.cwd, input.home, input.gitBranch);
107
- const segments = [location];
108
- if (input.gitBranch && folder) {
109
- segments.push(input.gitBranch);
110
- }
111
- else if (input.gitBranch) {
112
- segments[0] = `${location} (${input.gitBranch})`;
113
- }
114
- if (input.sessionName)
115
- segments.push(input.sessionName);
116
- if (input.workflowBadge)
117
- segments.push(input.workflowBadge);
118
- segments.push(input.modelLabel);
119
- const hasTokenUsage = input.totalInput > 0 ||
120
- input.totalOutput > 0 ||
121
- input.totalCacheRead > 0 ||
122
- input.totalCacheWrite > 0 ||
123
- input.totalCost > 0;
124
- if (hasTokenUsage) {
125
- const stats = [];
126
- if (input.totalInput)
127
- stats.push(`↑${formatTokens(input.totalInput)}`);
128
- if (input.totalOutput)
129
- stats.push(`↓${formatTokens(input.totalOutput)}`);
130
- if (input.totalCacheRead)
131
- stats.push(`R${formatTokens(input.totalCacheRead)}`);
132
- if (input.totalCacheWrite)
133
- stats.push(`W${formatTokens(input.totalCacheWrite)}`);
134
- if (input.totalCost)
135
- stats.push(`$${input.totalCost.toFixed(3)}`);
136
- if (stats.length)
137
- segments.push(stats.join(" "));
138
- }
139
- const contextPercentValue = input.contextPercent ?? 0;
140
- if (hasTokenUsage && contextPercentValue > 0 && input.contextWindow > 0) {
141
- segments.push(`${contextPercentValue.toFixed(1)}% ctx`);
142
- }
143
- return segments;
106
+ const folder = basename(input.cwd);
107
+ const location = formatLocationLabel(input.cwd, input.home, input.gitBranch);
108
+ const segments = [location];
109
+ if (input.gitBranch && folder) {
110
+ segments.push(input.gitBranch);
111
+ } else if (input.gitBranch) {
112
+ segments[0] = `${location} (${input.gitBranch})`;
113
+ }
114
+ if (input.sessionName) segments.push(input.sessionName);
115
+ if (input.workflowBadge) segments.push(input.workflowBadge);
116
+ segments.push(input.modelLabel);
117
+ const hasTokenUsage =
118
+ input.totalInput > 0 ||
119
+ input.totalOutput > 0 ||
120
+ input.totalCacheRead > 0 ||
121
+ input.totalCacheWrite > 0 ||
122
+ input.totalCost > 0;
123
+ if (hasTokenUsage) {
124
+ const stats = [];
125
+ if (input.totalInput) stats.push(`↑${formatTokens(input.totalInput)}`);
126
+ if (input.totalOutput) stats.push(`↓${formatTokens(input.totalOutput)}`);
127
+ if (input.totalCacheRead) stats.push(`R${formatTokens(input.totalCacheRead)}`);
128
+ if (input.totalCacheWrite) stats.push(`W${formatTokens(input.totalCacheWrite)}`);
129
+ if (input.totalCost) stats.push(`$${input.totalCost.toFixed(3)}`);
130
+ if (stats.length) segments.push(stats.join(" "));
131
+ }
132
+ const contextPercentValue = input.contextPercent ?? 0;
133
+ if (hasTokenUsage && contextPercentValue > 0 && input.contextWindow > 0) {
134
+ segments.push(`${contextPercentValue.toFixed(1)}% ctx`);
135
+ }
136
+ return segments;
144
137
  }
145
138
  export function buildKubbisecFooterPlainLine(input) {
146
- return joinFooterSegments(buildFooterPlainSegments(input));
139
+ return joinFooterSegments(buildFooterPlainSegments(input));
147
140
  }
148
141
  function buildKubbisecFooterThemedLine(theme, input) {
149
- const folder = basename(input.cwd);
150
- const plainSegments = buildFooterPlainSegments(input);
151
- const themed = [];
152
- const sep = theme.fg("dim", FOOTER_SEP);
153
- for (let i = 0; i < plainSegments.length; i += 1) {
154
- const text = plainSegments[i] ?? "";
155
- if (i > 0)
156
- themed.push(sep);
157
- const isBranch = i === 1 && Boolean(input.gitBranch && folder);
158
- const isWorkflowBadge = text === input.workflowBadge;
159
- const isModel = text === input.modelLabel;
160
- const isStats = text.includes("↑") || text.includes("↓") || text.includes("% ctx") || text.startsWith("$");
161
- if (isWorkflowBadge) {
162
- themed.push(theme.fg("planAccent", text));
163
- }
164
- else if (isBranch || isModel) {
165
- themed.push(kubbisecBrandFg(text));
166
- }
167
- else if (isStats) {
168
- themed.push(theme.fg("dim", text));
169
- }
170
- else {
171
- themed.push(theme.fg("dim", text));
172
- }
142
+ const folder = basename(input.cwd);
143
+ const plainSegments = buildFooterPlainSegments(input);
144
+ const themed = [];
145
+ const sep = theme.fg("dim", FOOTER_SEP);
146
+ for (let i = 0; i < plainSegments.length; i += 1) {
147
+ const text = plainSegments[i] ?? "";
148
+ if (i > 0) themed.push(sep);
149
+ const isBranch = i === 1 && Boolean(input.gitBranch && folder);
150
+ const isWorkflowBadge = text === input.workflowBadge;
151
+ const isModel = text === input.modelLabel;
152
+ const isStats =
153
+ text.includes("↑") || text.includes("↓") || text.includes("% ctx") || text.startsWith("$");
154
+ if (isWorkflowBadge) {
155
+ themed.push(theme.fg("planAccent", text));
156
+ } else if (isBranch || isModel) {
157
+ themed.push(kubbisecBrandFg(text));
158
+ } else if (isStats) {
159
+ themed.push(theme.fg("dim", text));
160
+ } else {
161
+ themed.push(theme.fg("dim", text));
173
162
  }
174
- return themed.join("");
163
+ }
164
+ return themed.join("");
175
165
  }
176
166
  function buildFooterComponent(ctx, theme, footerData, api) {
177
- return {
178
- invalidate() { },
179
- render(width) {
180
- let totalInput = 0;
181
- let totalOutput = 0;
182
- let totalCacheRead = 0;
183
- let totalCacheWrite = 0;
184
- let totalCost = 0;
185
- for (const entry of ctx.sessionManager.getBranch()) {
186
- if (entry.type !== "message" || !entry.message || entry.message.role !== "assistant") {
187
- continue;
188
- }
189
- const m = entry.message;
190
- totalInput += m.usage.input;
191
- totalOutput += m.usage.output;
192
- totalCacheRead += m.usage.cacheRead;
193
- totalCacheWrite += m.usage.cacheWrite;
194
- totalCost += m.usage.cost.total;
195
- }
196
- const contextUsage = ctx.getContextUsage();
197
- const contextWindow = contextUsage?.contextWindow ?? ctx.model?.contextWindow ?? 0;
198
- const contextPercent = contextUsage?.percent ?? null;
199
- const input = {
200
- cwd: ctx.sessionManager.getCwd(),
201
- home: process.env.HOME || process.env.USERPROFILE,
202
- gitBranch: footerData.getGitBranch() ?? undefined,
203
- sessionName: ctx.sessionManager.getSessionName(),
204
- workflowBadge: getSessionWorkflowFooterBadge(),
205
- modelLabel: resolveKubbisecFooterModelLabel(ctx, api),
206
- totalInput,
207
- totalOutput,
208
- totalCacheRead,
209
- totalCacheWrite,
210
- totalCost,
211
- contextPercent,
212
- contextWindow,
213
- };
214
- const plain = buildKubbisecFooterPlainLine(input);
215
- const truncatedPlain = truncatePathMiddle(plain, width);
216
- const line = truncatedPlain === plain
217
- ? buildKubbisecFooterThemedLine(theme, input)
218
- : theme.fg("dim", truncatedPlain);
219
- const centered = centerLine(truncateToWidth(line, width, theme.fg("dim", "…")), width);
220
- return [centered];
221
- },
222
- };
167
+ return {
168
+ invalidate() {},
169
+ render(width) {
170
+ let totalInput = 0;
171
+ let totalOutput = 0;
172
+ let totalCacheRead = 0;
173
+ let totalCacheWrite = 0;
174
+ let totalCost = 0;
175
+ for (const entry of ctx.sessionManager.getBranch()) {
176
+ if (entry.type !== "message" || !entry.message || entry.message.role !== "assistant") {
177
+ continue;
178
+ }
179
+ const m = entry.message;
180
+ totalInput += m.usage.input;
181
+ totalOutput += m.usage.output;
182
+ totalCacheRead += m.usage.cacheRead;
183
+ totalCacheWrite += m.usage.cacheWrite;
184
+ totalCost += m.usage.cost.total;
185
+ }
186
+ const contextUsage = ctx.getContextUsage();
187
+ const contextWindow = contextUsage?.contextWindow ?? ctx.model?.contextWindow ?? 0;
188
+ const contextPercent = contextUsage?.percent ?? null;
189
+ const input = {
190
+ cwd: ctx.sessionManager.getCwd(),
191
+ home: process.env.HOME || process.env.USERPROFILE,
192
+ gitBranch: footerData.getGitBranch() ?? undefined,
193
+ sessionName: ctx.sessionManager.getSessionName(),
194
+ workflowBadge: getSessionWorkflowFooterBadge(),
195
+ modelLabel: resolveKubbisecFooterModelLabel(ctx, api),
196
+ totalInput,
197
+ totalOutput,
198
+ totalCacheRead,
199
+ totalCacheWrite,
200
+ totalCost,
201
+ contextPercent,
202
+ contextWindow,
203
+ };
204
+ const plain = buildKubbisecFooterPlainLine(input);
205
+ const truncatedPlain = truncatePathMiddle(plain, width);
206
+ const line =
207
+ truncatedPlain === plain
208
+ ? buildKubbisecFooterThemedLine(theme, input)
209
+ : theme.fg("dim", truncatedPlain);
210
+ const centered = centerLine(truncateToWidth(line, width, theme.fg("dim", "…")), width);
211
+ return [centered];
212
+ },
213
+ };
223
214
  }
224
215
  export default function kubbisecFooter(api) {
225
- let requestRender;
226
- const scheduleRender = () => {
227
- requestRender?.();
228
- };
229
- api.on("model_select", scheduleRender);
230
- api.on("thinking_level_select", scheduleRender);
231
- api.on("turn_end", scheduleRender);
232
- api.on("message_end", scheduleRender);
233
- api.on("session_compact", scheduleRender);
234
- api.on("session_start", async (_event, ctx) => {
235
- if (!ctx.hasUI)
236
- return;
237
- ctx.ui.setFooter((tui, theme, footerData) => {
238
- requestRender = () => tui.requestRender();
239
- setKubbisecFooterRequestRender(requestRender);
240
- const unsubBranch = footerData.onBranchChange(() => tui.requestRender());
241
- const unsubWorkflow = onSessionWorkflowStatusChange(() => tui.requestRender());
242
- const component = buildFooterComponent(ctx, theme, footerData, api);
243
- return {
244
- ...component,
245
- dispose() {
246
- unsubBranch();
247
- unsubWorkflow();
248
- requestRender = undefined;
249
- setKubbisecFooterRequestRender(undefined);
250
- },
251
- };
252
- });
216
+ let requestRender;
217
+ const scheduleRender = () => {
218
+ requestRender?.();
219
+ };
220
+ api.on("model_select", scheduleRender);
221
+ api.on("thinking_level_select", scheduleRender);
222
+ api.on("turn_end", scheduleRender);
223
+ api.on("message_end", scheduleRender);
224
+ api.on("session_compact", scheduleRender);
225
+ api.on("session_start", async (_event, ctx) => {
226
+ if (!ctx.hasUI) return;
227
+ ctx.ui.setFooter((tui, theme, footerData) => {
228
+ requestRender = () => tui.requestRender();
229
+ setKubbisecFooterRequestRender(requestRender);
230
+ const unsubBranch = footerData.onBranchChange(() => tui.requestRender());
231
+ const unsubWorkflow = onSessionWorkflowStatusChange(() => tui.requestRender());
232
+ const component = buildFooterComponent(ctx, theme, footerData, api);
233
+ return {
234
+ ...component,
235
+ dispose() {
236
+ unsubBranch();
237
+ unsubWorkflow();
238
+ requestRender = undefined;
239
+ setKubbisecFooterRequestRender(undefined);
240
+ },
241
+ };
253
242
  });
243
+ });
254
244
  }
255
- //# sourceMappingURL=kubbisec-footer.extension.js.map
245
+ //# sourceMappingURL=kubbisec-footer.extension.js.map
@@ -2,25 +2,33 @@
2
2
  * Local GitHub/gh tools — only when user opted in: KUBBISEC_CHAT_EXTENDED_CONTEXT=1
3
3
  */
4
4
  type ExtensionApi = {
5
- on: (event: string, handler: (event: unknown, ctx: ExtensionContext) => void | Promise<void>) => void;
6
- registerTool: (def: {
7
- name: string;
8
- label: string;
9
- description: string;
10
- parameters: unknown;
11
- execute: (toolCallId: string, params: Record<string, unknown>, signal: AbortSignal, onUpdate: unknown, ctx: ExtensionContext) => Promise<{
12
- content: Array<{
13
- type: "text";
14
- text: string;
15
- }>;
16
- }>;
17
- }) => void;
5
+ on: (
6
+ event: string,
7
+ handler: (event: unknown, ctx: ExtensionContext) => void | Promise<void>,
8
+ ) => void;
9
+ registerTool: (def: {
10
+ name: string;
11
+ label: string;
12
+ description: string;
13
+ parameters: unknown;
14
+ execute: (
15
+ toolCallId: string,
16
+ params: Record<string, unknown>,
17
+ signal: AbortSignal,
18
+ onUpdate: unknown,
19
+ ctx: ExtensionContext,
20
+ ) => Promise<{
21
+ content: Array<{
22
+ type: "text";
23
+ text: string;
24
+ }>;
25
+ }>;
26
+ }) => void;
18
27
  };
19
28
  type ExtensionContext = {
20
- ui?: {
21
- notify: (message: string, level: string) => void;
22
- };
29
+ ui?: {
30
+ notify: (message: string, level: string) => void;
31
+ };
23
32
  };
24
33
  export default function kubbisecGithubLocal(api: ExtensionApi): void;
25
- export {};
26
- //# sourceMappingURL=kubbisec-github-local.extension.d.ts.map
34
+ //# sourceMappingURL=kubbisec-github-local.extension.d.ts.map