@kubbisec/ai-linux-arm64 0.1.21 → 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 (130) hide show
  1. package/bundled/clarify/clarify-gate-state.d.ts +1 -1
  2. package/bundled/clarify/clarify-gate-state.js +3 -3
  3. package/bundled/clarify/clarify-gate.d.ts +21 -14
  4. package/bundled/clarify/clarify-gate.js +118 -111
  5. package/bundled/clarify/clarify-select-panel.d.ts +16 -9
  6. package/bundled/clarify/clarify-select-panel.js +65 -67
  7. package/bundled/clarify/clarify-ui-state.d.ts +12 -10
  8. package/bundled/clarify/clarify-ui-state.js +26 -26
  9. package/bundled/clarify/parse-clarify-answer.d.ts +29 -18
  10. package/bundled/clarify/parse-clarify-answer.js +39 -45
  11. package/bundled/clarify/question-format.d.ts +34 -23
  12. package/bundled/clarify/question-format.js +112 -119
  13. package/bundled/clarify/questionnaire-tool.d.ts +28 -17
  14. package/bundled/clarify/questionnaire-tool.js +180 -144
  15. package/bundled/clarify/scope-discovery.d.ts +8 -5
  16. package/bundled/clarify/scope-discovery.js +102 -110
  17. package/bundled/clarify/session-questionnaire.d.ts +48 -13
  18. package/bundled/clarify/session-questionnaire.js +304 -312
  19. package/bundled/clarify/session-questionnaire.types.d.ts +29 -27
  20. package/bundled/clarify/session-questionnaire.types.js +10 -10
  21. package/bundled/components/kubbisec-model-selector.d.ts +47 -34
  22. package/bundled/components/kubbisec-model-selector.js +187 -177
  23. package/bundled/config/config.d.ts +6 -6
  24. package/bundled/config/config.js +55 -55
  25. package/bundled/config/detect-local-llm-providers.d.ts +26 -16
  26. package/bundled/config/detect-local-llm-providers.js +130 -142
  27. package/bundled/config/ensure-kubbisec-project-settings.d.ts +9 -9
  28. package/bundled/config/ensure-kubbisec-project-settings.js +44 -48
  29. package/bundled/config/extended-context.d.ts +5 -6
  30. package/bundled/config/extended-context.js +23 -22
  31. package/bundled/config/feature-flags.d.ts +10 -2
  32. package/bundled/config/feature-flags.js +8 -2
  33. package/bundled/config/format-kubbisec-footer-status.d.ts +1 -1
  34. package/bundled/config/format-kubbisec-footer-status.js +26 -31
  35. package/bundled/config/kubbisec-extension-manifest.d.ts +22 -2
  36. package/bundled/config/kubbisec-extension-manifest.js +20 -20
  37. package/bundled/config/llm-config-mutations.d.ts +51 -25
  38. package/bundled/config/llm-config-mutations.js +173 -182
  39. package/bundled/config/llm-config.d.ts +54 -41
  40. package/bundled/config/llm-config.js +199 -199
  41. package/bundled/config/llm-provider-catalog.d.ts +18 -15
  42. package/bundled/config/llm-provider-catalog.js +45 -46
  43. package/bundled/config/materialize-kubbisec-pi-resources.d.ts +1 -1
  44. package/bundled/config/materialize-kubbisec-pi-resources.js +174 -183
  45. package/bundled/config/register-custom-llm-providers.d.ts +11 -5
  46. package/bundled/config/register-custom-llm-providers.js +17 -15
  47. package/bundled/config/register-kubbisec-llm-provider.d.ts +14 -10
  48. package/bundled/config/register-kubbisec-llm-provider.js +50 -42
  49. package/bundled/config/resolve-agents-context-file.d.ts +1 -1
  50. package/bundled/config/resolve-agents-context-file.js +33 -34
  51. package/bundled/config/resource-budget.d.ts +12 -12
  52. package/bundled/config/resource-budget.js +28 -28
  53. package/bundled/config/sync-kubbisec-pi-models.d.ts +6 -3
  54. package/bundled/config/sync-kubbisec-pi-models.js +58 -58
  55. package/bundled/copy/cli-reference-index.d.ts +3 -2
  56. package/bundled/copy/cli-reference-index.js +1 -1
  57. package/bundled/copy/kubbisec-shell-copy.d.ts +11 -6
  58. package/bundled/copy/kubbisec-shell-copy.js +1 -1
  59. package/bundled/extensions/cli-local-shared.d.ts +45 -26
  60. package/bundled/extensions/cli-local-shared.js +128 -118
  61. package/bundled/extensions/kubbisec-aspm-local.extension.d.ts +18 -15
  62. package/bundled/extensions/kubbisec-aspm-local.extension.js +118 -114
  63. package/bundled/extensions/kubbisec-brand.extension.d.ts +1 -1
  64. package/bundled/extensions/kubbisec-brand.extension.js +25 -25
  65. package/bundled/extensions/kubbisec-byok-provider.extension.d.ts +1 -1
  66. package/bundled/extensions/kubbisec-byok-provider.extension.js +2 -2
  67. package/bundled/extensions/kubbisec-clarify.extension.d.ts +64 -35
  68. package/bundled/extensions/kubbisec-clarify.extension.js +323 -305
  69. package/bundled/extensions/kubbisec-exit.extension.d.ts +1 -1
  70. package/bundled/extensions/kubbisec-exit.extension.js +29 -32
  71. package/bundled/extensions/kubbisec-extended-context.extension.d.ts +1 -1
  72. package/bundled/extensions/kubbisec-extended-context.extension.js +56 -43
  73. package/bundled/extensions/kubbisec-footer.extension.d.ts +14 -14
  74. package/bundled/extensions/kubbisec-footer.extension.js +205 -215
  75. package/bundled/extensions/kubbisec-github-local.extension.d.ts +26 -18
  76. package/bundled/extensions/kubbisec-github-local.extension.js +123 -116
  77. package/bundled/extensions/kubbisec-llm-config.extension.d.ts +1 -1
  78. package/bundled/extensions/kubbisec-llm-config.extension.js +200 -181
  79. package/bundled/extensions/kubbisec-memory.extension.d.ts +9 -7
  80. package/bundled/extensions/kubbisec-memory.extension.js +88 -95
  81. package/bundled/extensions/kubbisec-naus-local.extension.d.ts +18 -15
  82. package/bundled/extensions/kubbisec-naus-local.extension.js +132 -111
  83. package/bundled/extensions/kubbisec-platform-tools.extension.d.ts +31 -21
  84. package/bundled/extensions/kubbisec-platform-tools.extension.js +152 -152
  85. package/bundled/extensions/kubbisec-runtime-status.extension.d.ts +10 -8
  86. package/bundled/extensions/kubbisec-runtime-status.extension.js +15 -13
  87. package/bundled/extensions/kubbisec-scope.extension.d.ts +12 -7
  88. package/bundled/extensions/kubbisec-scope.extension.js +13 -13
  89. package/bundled/extensions/kubbisec-skill-mentions.extension.d.ts +27 -16
  90. package/bundled/extensions/kubbisec-skill-mentions.extension.js +73 -63
  91. package/bundled/extensions/kubbisec-skill-telemetry.extension.d.ts +2 -3
  92. package/bundled/extensions/kubbisec-skill-telemetry.extension.js +59 -64
  93. package/bundled/extensions/kubbisec-theme-lock.extension.d.ts +1 -1
  94. package/bundled/extensions/kubbisec-theme-lock.extension.js +33 -34
  95. package/bundled/extensions/kubbisec-ui.extension.d.ts +1 -1
  96. package/bundled/extensions/kubbisec-ui.extension.js +114 -109
  97. package/bundled/extensions/kubbisec-workflow.extension.d.ts +20 -18
  98. package/bundled/extensions/kubbisec-workflow.extension.js +138 -140
  99. package/bundled/node_modules/@aspm/shared/dist/redaction.test.d.ts +2 -0
  100. package/bundled/node_modules/@aspm/shared/dist/redaction.test.d.ts.map +1 -0
  101. package/bundled/node_modules/@aspm/shared/dist/redaction.test.js +626 -0
  102. package/bundled/node_modules/@aspm/shared/dist/redaction.test.js.map +1 -0
  103. package/bundled/resolve-bundled-dist-root.js +122 -131
  104. package/bundled/skills/at-path-mentions.d.ts +1 -1
  105. package/bundled/skills/at-path-mentions.js +146 -153
  106. package/bundled/skills/chat-mention-render.d.ts +2 -2
  107. package/bundled/skills/chat-mention-render.js +121 -126
  108. package/bundled/skills/chat-mentions.d.ts +17 -8
  109. package/bundled/skills/chat-mentions.js +76 -76
  110. package/bundled/skills/list-bundled-skills.d.ts +3 -3
  111. package/bundled/skills/list-bundled-skills.js +33 -35
  112. package/bundled/skills/skill-mention.d.ts +10 -2
  113. package/bundled/skills/skill-mention.js +10 -2
  114. package/bundled/theme/clear-terminal.d.ts +1 -1
  115. package/bundled/theme/clear-terminal.js +3 -4
  116. package/bundled/theme/footer-render-hook.d.ts +1 -1
  117. package/bundled/theme/footer-render-hook.js +3 -3
  118. package/bundled/theme/kubbisec-brand-fg.d.ts +1 -1
  119. package/bundled/theme/kubbisec-brand-fg.js +2 -2
  120. package/bundled/theme/kubbisec-menu-themes.d.ts +7 -7
  121. package/bundled/theme/kubbisec-menu-themes.js +30 -31
  122. package/bundled/theme/kubbisec-theme-name.d.ts +1 -1
  123. package/bundled/theme/kubbisec-theme-name.js +1 -1
  124. package/bundled/theme/patch-pi-settings-theme.runtime.d.ts +1 -1
  125. package/bundled/theme/patch-pi-settings-theme.runtime.js +11 -10
  126. package/bundled/theme/render-compact-header.d.ts +13 -5
  127. package/bundled/theme/render-compact-header.js +127 -129
  128. package/bundled/workflow/session-workflow-mode.d.ts +1 -1
  129. package/bundled/workflow/session-workflow-mode.js +33 -33
  130. 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