@vybestack/llxprt-code 0.1.23 → 0.2.2-nightly.250908.7b895396

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 (164) hide show
  1. package/README.md +21 -17
  2. package/dist/package.json +4 -3
  3. package/dist/src/auth/anthropic-oauth-provider.d.ts +50 -3
  4. package/dist/src/auth/anthropic-oauth-provider.js +287 -63
  5. package/dist/src/auth/anthropic-oauth-provider.js.map +1 -1
  6. package/dist/src/auth/gemini-oauth-provider.d.ts +34 -3
  7. package/dist/src/auth/gemini-oauth-provider.js +308 -14
  8. package/dist/src/auth/gemini-oauth-provider.js.map +1 -1
  9. package/dist/src/auth/migration.d.ts +26 -0
  10. package/dist/src/auth/migration.js +54 -0
  11. package/dist/src/auth/migration.js.map +1 -0
  12. package/dist/src/auth/oauth-manager.d.ts +24 -0
  13. package/dist/src/auth/oauth-manager.js +179 -14
  14. package/dist/src/auth/oauth-manager.js.map +1 -1
  15. package/dist/src/auth/oauth-manager.spec.js +10 -8
  16. package/dist/src/auth/oauth-manager.spec.js.map +1 -1
  17. package/dist/src/auth/qwen-oauth-provider.d.ts +59 -3
  18. package/dist/src/auth/qwen-oauth-provider.js +263 -41
  19. package/dist/src/auth/qwen-oauth-provider.js.map +1 -1
  20. package/dist/src/config/config.js +11 -10
  21. package/dist/src/config/config.js.map +1 -1
  22. package/dist/src/config/extension.d.ts +1 -1
  23. package/dist/src/config/extension.js +1 -1
  24. package/dist/src/gemini.js +33 -11
  25. package/dist/src/gemini.js.map +1 -1
  26. package/dist/src/generated/git-commit.d.ts +1 -1
  27. package/dist/src/generated/git-commit.js +1 -1
  28. package/dist/src/integration-tests/base-url-behavior.integration.test.js +4 -1
  29. package/dist/src/integration-tests/base-url-behavior.integration.test.js.map +1 -1
  30. package/dist/src/integration-tests/compression-settings-apply.integration.test.js +85 -332
  31. package/dist/src/integration-tests/compression-settings-apply.integration.test.js.map +1 -1
  32. package/dist/src/integration-tests/ephemeral-settings.integration.test.js +5 -16
  33. package/dist/src/integration-tests/ephemeral-settings.integration.test.js.map +1 -1
  34. package/dist/src/integration-tests/model-params-isolation.integration.test.js +8 -2
  35. package/dist/src/integration-tests/model-params-isolation.integration.test.js.map +1 -1
  36. package/dist/src/integration-tests/modelParams.integration.test.js +4 -1
  37. package/dist/src/integration-tests/modelParams.integration.test.js.map +1 -1
  38. package/dist/src/integration-tests/provider-switching.integration.test.js +4 -1
  39. package/dist/src/integration-tests/provider-switching.integration.test.js.map +1 -1
  40. package/dist/src/integration-tests/retry-settings.integration.test.d.ts +6 -0
  41. package/dist/src/integration-tests/retry-settings.integration.test.js +56 -0
  42. package/dist/src/integration-tests/retry-settings.integration.test.js.map +1 -0
  43. package/dist/src/providers/index.d.ts +1 -1
  44. package/dist/src/providers/logging/LoggingProviderWrapper.test.js +58 -47
  45. package/dist/src/providers/logging/LoggingProviderWrapper.test.js.map +1 -1
  46. package/dist/src/providers/logging/multi-provider-logging.integration.test.js +130 -68
  47. package/dist/src/providers/logging/multi-provider-logging.integration.test.js.map +1 -1
  48. package/dist/src/providers/logging/performance.test.js +39 -16
  49. package/dist/src/providers/logging/performance.test.js.map +1 -1
  50. package/dist/src/providers/provider-gemini-switching.test.js +4 -1
  51. package/dist/src/providers/provider-gemini-switching.test.js.map +1 -1
  52. package/dist/src/providers/provider-switching.integration.test.js +12 -3
  53. package/dist/src/providers/provider-switching.integration.test.js.map +1 -1
  54. package/dist/src/providers/providerConfigUtils.js +2 -4
  55. package/dist/src/providers/providerConfigUtils.js.map +1 -1
  56. package/dist/src/providers/providerManagerInstance.js +24 -49
  57. package/dist/src/providers/providerManagerInstance.js.map +1 -1
  58. package/dist/src/services/BuiltinCommandLoader.js +4 -0
  59. package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
  60. package/dist/src/storage/ConversationStorage.test.js +10 -7
  61. package/dist/src/storage/ConversationStorage.test.js.map +1 -1
  62. package/dist/src/test-utils/mockCommandContext.js +2 -0
  63. package/dist/src/test-utils/mockCommandContext.js.map +1 -1
  64. package/dist/src/ui/App.e2e.test.d.ts +6 -0
  65. package/dist/src/ui/App.e2e.test.js +37 -0
  66. package/dist/src/ui/App.e2e.test.js.map +1 -0
  67. package/dist/src/ui/App.js +51 -4
  68. package/dist/src/ui/App.js.map +1 -1
  69. package/dist/src/ui/commands/authCommand.d.ts +9 -1
  70. package/dist/src/ui/commands/authCommand.js +109 -31
  71. package/dist/src/ui/commands/authCommand.js.map +1 -1
  72. package/dist/src/ui/commands/clearCommand.js +2 -0
  73. package/dist/src/ui/commands/clearCommand.js.map +1 -1
  74. package/dist/src/ui/commands/ideCommand.js +26 -0
  75. package/dist/src/ui/commands/ideCommand.js.map +1 -1
  76. package/dist/src/ui/commands/keyCommand.js +16 -54
  77. package/dist/src/ui/commands/keyCommand.js.map +1 -1
  78. package/dist/src/ui/commands/keyCommand.test.js +3 -3
  79. package/dist/src/ui/commands/keyCommand.test.js.map +1 -1
  80. package/dist/src/ui/commands/keyfileCommand.js +42 -32
  81. package/dist/src/ui/commands/keyfileCommand.js.map +1 -1
  82. package/dist/src/ui/commands/logoutCommand.d.ts +7 -0
  83. package/dist/src/ui/commands/logoutCommand.js +70 -0
  84. package/dist/src/ui/commands/logoutCommand.js.map +1 -0
  85. package/dist/src/ui/commands/modelCommand.js +16 -0
  86. package/dist/src/ui/commands/modelCommand.js.map +1 -1
  87. package/dist/src/ui/commands/profileCommand.js +31 -25
  88. package/dist/src/ui/commands/profileCommand.js.map +1 -1
  89. package/dist/src/ui/commands/profileCommand.test.js +15 -16
  90. package/dist/src/ui/commands/profileCommand.test.js.map +1 -1
  91. package/dist/src/ui/commands/providerCommand.js +10 -7
  92. package/dist/src/ui/commands/providerCommand.js.map +1 -1
  93. package/dist/src/ui/commands/setCommand.js +43 -19
  94. package/dist/src/ui/commands/setCommand.js.map +1 -1
  95. package/dist/src/ui/commands/setCommand.test.js +5 -7
  96. package/dist/src/ui/commands/setCommand.test.js.map +1 -1
  97. package/dist/src/ui/commands/setupGithubCommand.d.ts +2 -0
  98. package/dist/src/ui/commands/setupGithubCommand.js +123 -23
  99. package/dist/src/ui/commands/setupGithubCommand.js.map +1 -1
  100. package/dist/src/ui/commands/setupGithubCommand.test.js +94 -1
  101. package/dist/src/ui/commands/setupGithubCommand.test.js.map +1 -1
  102. package/dist/src/ui/commands/statusCommand.d.ts +7 -0
  103. package/dist/src/ui/commands/statusCommand.js +71 -0
  104. package/dist/src/ui/commands/statusCommand.js.map +1 -0
  105. package/dist/src/ui/commands/types.d.ts +1 -0
  106. package/dist/src/ui/commands/types.js.map +1 -1
  107. package/dist/src/ui/components/ContextIndicator.ui.test.js +19 -46
  108. package/dist/src/ui/components/ContextIndicator.ui.test.js.map +1 -1
  109. package/dist/src/ui/components/Footer.d.ts +1 -1
  110. package/dist/src/ui/components/Footer.js +7 -7
  111. package/dist/src/ui/components/Footer.js.map +1 -1
  112. package/dist/src/ui/components/Footer.responsive.test.js +28 -25
  113. package/dist/src/ui/components/Footer.responsive.test.js.map +1 -1
  114. package/dist/src/ui/components/OAuthCodeDialog.d.ts +5 -0
  115. package/dist/src/ui/components/OAuthCodeDialog.js +31 -1
  116. package/dist/src/ui/components/OAuthCodeDialog.js.map +1 -1
  117. package/dist/src/ui/components/OAuthCodeDialog.test.d.ts +6 -0
  118. package/dist/src/ui/components/OAuthCodeDialog.test.js +60 -0
  119. package/dist/src/ui/components/OAuthCodeDialog.test.js.map +1 -0
  120. package/dist/src/ui/contexts/KeypressContext.js +23 -1
  121. package/dist/src/ui/contexts/KeypressContext.js.map +1 -1
  122. package/dist/src/ui/contexts/KeypressContext.test.js +58 -2
  123. package/dist/src/ui/contexts/KeypressContext.test.js.map +1 -1
  124. package/dist/src/ui/contexts/SessionContext.d.ts +2 -0
  125. package/dist/src/ui/contexts/SessionContext.js +9 -1
  126. package/dist/src/ui/contexts/SessionContext.js.map +1 -1
  127. package/dist/src/ui/contexts/TodoContext.js +2 -2
  128. package/dist/src/ui/contexts/TodoContext.js.map +1 -1
  129. package/dist/src/ui/hooks/atCommandProcessor.js +0 -2
  130. package/dist/src/ui/hooks/atCommandProcessor.js.map +1 -1
  131. package/dist/src/ui/hooks/atCommandProcessor.test.js +21 -6
  132. package/dist/src/ui/hooks/atCommandProcessor.test.js.map +1 -1
  133. package/dist/src/ui/hooks/slashCommandProcessor.js +2 -0
  134. package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
  135. package/dist/src/ui/hooks/useAuthCommand.js +6 -5
  136. package/dist/src/ui/hooks/useAuthCommand.js.map +1 -1
  137. package/dist/src/ui/hooks/useGeminiStream.js +47 -63
  138. package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
  139. package/dist/src/ui/hooks/useProviderDialog.js +2 -5
  140. package/dist/src/ui/hooks/useProviderDialog.js.map +1 -1
  141. package/dist/src/ui/hooks/useToolScheduler.test.js +60 -24
  142. package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
  143. package/dist/src/ui/utils/platformConstants.d.ts +2 -0
  144. package/dist/src/ui/utils/platformConstants.js +2 -0
  145. package/dist/src/ui/utils/platformConstants.js.map +1 -1
  146. package/dist/src/ui/utils/secureInputHandler.js +18 -7
  147. package/dist/src/ui/utils/secureInputHandler.js.map +1 -1
  148. package/dist/src/ui/utils/secureInputHandler.test.js +20 -0
  149. package/dist/src/ui/utils/secureInputHandler.test.js.map +1 -1
  150. package/dist/src/utils/privacy/ConversationDataRedactor.d.ts +3 -3
  151. package/dist/src/utils/privacy/ConversationDataRedactor.js +16 -12
  152. package/dist/src/utils/privacy/ConversationDataRedactor.js.map +1 -1
  153. package/dist/src/utils/privacy/ConversationDataRedactor.test.js +115 -72
  154. package/dist/src/utils/privacy/ConversationDataRedactor.test.js.map +1 -1
  155. package/dist/src/validateNonInterActiveAuth.js +8 -17
  156. package/dist/src/validateNonInterActiveAuth.js.map +1 -1
  157. package/dist/src/zed-integration/schema.d.ts +194 -91
  158. package/dist/src/zed-integration/schema.js +7 -1
  159. package/dist/src/zed-integration/schema.js.map +1 -1
  160. package/dist/src/zed-integration/zedIntegration.d.ts +1 -3
  161. package/dist/src/zed-integration/zedIntegration.js +454 -198
  162. package/dist/src/zed-integration/zedIntegration.js.map +1 -1
  163. package/dist/tsconfig.tsbuildinfo +1 -1
  164. package/package.json +4 -3
@@ -4,7 +4,8 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  // These imports will be needed when the command is re-enabled
7
- // import path from 'path';
7
+ import path from 'path';
8
+ import fs from 'fs';
8
9
  // import { CommandContext } from '../../ui/commands/types.js';
9
10
  // import {
10
11
  // getGitRepoRoot,
@@ -15,8 +16,69 @@ import { CommandKind, } from './types.js';
15
16
  // TODO: Re-add imports when the setup-github command is re-enabled
16
17
  // import { getUrlOpenCommand } from '../../ui/utils/commandUtils.js';
17
18
  // import { getGitHubRepoInfo } from '../../utils/gitUtils.js';
18
- // TODO: Reimplement _getOpenUrlsCommands when the setup-github command is re-enabled
19
- // This function was removed because it's currently unused
19
+ export const GITHUB_WORKFLOW_PATHS = [
20
+ 'gemini-dispatch/gemini-dispatch.yml',
21
+ 'gemini-assistant/gemini-invoke.yml',
22
+ 'issue-triage/gemini-triage.yml',
23
+ 'issue-triage/gemini-scheduled-triage.yml',
24
+ 'pr-review/gemini-review.yml',
25
+ ];
26
+ // TODO: Reimplement getOpenUrlsCommands when the setup-github command is re-enabled
27
+ // This function was removed because it's currently unused but kept for reference
28
+ // function getOpenUrlsCommands(readmeUrl: string): string[] {
29
+ // // Determine the OS-specific command to open URLs, ex: 'open', 'xdg-open', etc
30
+ // const openCmd = getUrlOpenCommand();
31
+ //
32
+ // // Build a list of URLs to open
33
+ // const urlsToOpen = [readmeUrl];
34
+ //
35
+ // const repoInfo = getGitHubRepoInfo();
36
+ // if (repoInfo) {
37
+ // urlsToOpen.push(
38
+ // `https://github.com/${repoInfo.owner}/${repoInfo.repo}/settings/secrets/actions`,
39
+ // );
40
+ // }
41
+ //
42
+ // // Create and join the individual commands
43
+ // const commands = urlsToOpen.map((url) => `${openCmd} "${url}"`);
44
+ // return commands;
45
+ // }
46
+ // Add Gemini CLI specific entries to .gitignore file
47
+ export async function updateGitignore(gitRepoRoot) {
48
+ const gitignoreEntries = ['.gemini/', 'gha-creds-*.json'];
49
+ const gitignorePath = path.join(gitRepoRoot, '.gitignore');
50
+ try {
51
+ // Check if .gitignore exists and read its content
52
+ let existingContent = '';
53
+ let fileExists = true;
54
+ try {
55
+ existingContent = await fs.promises.readFile(gitignorePath, 'utf8');
56
+ }
57
+ catch (_error) {
58
+ // File doesn't exist
59
+ fileExists = false;
60
+ }
61
+ if (!fileExists) {
62
+ // Create new .gitignore file with the entries
63
+ const contentToWrite = gitignoreEntries.join('\n') + '\n';
64
+ await fs.promises.writeFile(gitignorePath, contentToWrite);
65
+ }
66
+ else {
67
+ // Check which entries are missing
68
+ const missingEntries = gitignoreEntries.filter((entry) => !existingContent
69
+ .split(/\r?\n/)
70
+ .some((line) => line.split('#')[0].trim() === entry));
71
+ if (missingEntries.length > 0) {
72
+ const contentToAdd = '\n' + missingEntries.join('\n') + '\n';
73
+ await fs.promises.appendFile(gitignorePath, contentToAdd);
74
+ }
75
+ }
76
+ }
77
+ catch (error) {
78
+ console.debug('Failed to update .gitignore:', error);
79
+ // Continue without failing the whole command
80
+ }
81
+ }
20
82
  export const setupGithubCommand = {
21
83
  name: 'setup-github',
22
84
  description: 'Set up GitHub Actions (currently disabled - needs adaptation for llxprt)',
@@ -74,36 +136,74 @@ For now, you can manually set up GitHub Actions by creating workflows that use l
74
136
  const proxy = context?.services?.config?.getProxy();
75
137
  const releaseTag = await getLatestGitHubRelease(proxy);
76
138
 
77
- // TODO: Update these workflow paths for llxprt
78
- const workflows = [
79
- 'llxprt-cli/llxprt-cli.yml',
80
- 'issue-triage/llxprt-issue-automated-triage.yml',
81
- 'issue-triage/llxprt-issue-scheduled-triage.yml',
82
- 'pr-review/llxprt-pr-review.yml',
83
- ];
139
+ // Create the .github/workflows directory to download the files into
140
+ const githubWorkflowsDir = path.join(gitRepoRoot, '.github', 'workflows');
141
+ try {
142
+ await fs.promises.mkdir(githubWorkflowsDir, { recursive: true });
143
+ } catch (_error) {
144
+ console.debug(
145
+ `Failed to create ${githubWorkflowsDir} directory:`,
146
+ _error,
147
+ );
148
+ throw new Error(
149
+ `Unable to create ${githubWorkflowsDir} directory. Do you have file permissions in the current directory?`,
150
+ );
151
+ }
84
152
 
85
- const commands = [];
153
+ // Download each workflow in parallel - there aren't enough files to warrant
154
+ // a full workerpool model here.
155
+ const downloads = [];
156
+ for (const workflow of GITHUB_WORKFLOW_PATHS) {
157
+ downloads.push(
158
+ (async () => {
159
+ const endpoint = `https://raw.githubusercontent.com/google-github-actions/run-gemini-cli/refs/tags/${releaseTag}/examples/workflows/${workflow}`;
160
+ const response = await fetch(endpoint, {
161
+ method: 'GET',
162
+ dispatcher: proxy ? new ProxyAgent(proxy) : undefined,
163
+ signal: AbortSignal.any([
164
+ AbortSignal.timeout(30_000),
165
+ abortController.signal,
166
+ ]),
167
+ } as RequestInit);
86
168
 
87
- // Ensure fast exit
88
- commands.push(`set -eEuo pipefail`);
169
+ if (!response.ok) {
170
+ throw new Error(
171
+ `Invalid response code downloading ${endpoint}: ${response.status} - ${response.statusText}`,
172
+ );
173
+ }
174
+ const body = response.body;
175
+ if (!body) {
176
+ throw new Error(
177
+ `Empty body while downloading ${endpoint}: ${response.status} - ${response.statusText}`,
178
+ );
179
+ }
89
180
 
90
- // Make the directory if it doesn't exist
91
- commands.push(`mkdir -p "${gitRepoRoot}/.github/workflows"`);
181
+ const destination = path.resolve(
182
+ githubWorkflowsDir,
183
+ path.basename(workflow),
184
+ );
92
185
 
93
- for (const workflow of workflows) {
94
- const fileName = path.basename(workflow);
95
- // TODO: Update to use acoliver/run-llxprt-code repository
96
- const curlCommand = buildCurlCommand(
97
- `https://raw.githubusercontent.com/acoliver/run-llxprt-code/refs/tags/${releaseTag}/examples/workflows/${workflow}`,
98
- [`--output "${gitRepoRoot}/.github/workflows/${fileName}"`],
186
+ const fileStream = fs.createWriteStream(destination, {
187
+ mode: 0o644, // -rw-r--r--, user(rw), group(r), other(r)
188
+ flags: 'w', // write and overwrite
189
+ flush: true,
190
+ });
191
+
192
+ await body.pipeTo(Writable.toWeb(fileStream));
193
+ })(),
99
194
  );
100
- commands.push(curlCommand);
101
195
  }
102
196
 
103
197
  const readmeUrl = `https://github.com/google-github-actions/run-gemini-cli/blob/${releaseTag}/README.md#quick-start`;
104
198
 
199
+ // Add entries to .gitignore file
200
+ await updateGitignore(gitRepoRoot);
201
+
202
+ // Print out a message
203
+ const commands = [];
204
+ commands.push('set -eEuo pipefail');
105
205
  commands.push(
106
- `echo "Successfully downloaded ${workflows.length} workflows. Follow the steps in ${readmeUrl} (skipping the /setup-github step) to complete setup."`
206
+ `echo "Successfully downloaded ${GITHUB_WORKFLOW_PATHS.length} workflows and updated .gitignore. Follow the steps in ${readmeUrl} (skipping the /setup-github step) to complete setup."`,
107
207
  );
108
208
 
109
209
  commands.push(...getOpenUrlsCommands(readmeUrl));
@@ -1 +1 @@
1
- {"version":3,"file":"setupGithubCommand.js","sourceRoot":"","sources":["../../../../src/ui/commands/setupGithubCommand.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,8DAA8D;AAC9D,2BAA2B;AAC3B,+DAA+D;AAC/D,WAAW;AACX,oBAAoB;AACpB,4BAA4B;AAC5B,wBAAwB;AACxB,oCAAoC;AAEpC,OAAO,EACL,WAAW,GAGZ,MAAM,YAAY,CAAC;AACpB,mEAAmE;AACnE,sEAAsE;AACtE,+DAA+D;AAE/D,qFAAqF;AACrF,0DAA0D;AAE1D,MAAM,CAAC,MAAM,kBAAkB,GAAiB;IAC9C,IAAI,EAAE,cAAc;IACpB,WAAW,EACT,0EAA0E;IAC5E,IAAI,EAAE,WAAW,CAAC,QAAQ;IAC1B,MAAM,EAAE,GAA6B,EAAE;IACrC,2CAA2C;IAC3C,WAAW;IACX,4GAA4G;IAC5G,yDAAyD;IACzD,2DAA2D;IAC3D,sDAAsD;IACtD,wEAAwE;IAExE,yCAAyC;IACzC,CAAC;QACC,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,MAAM;QACnB,OAAO,EAAE;;;;;;;;;;;;;4FAa6E;KACvF,CAAC;IAEJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAuEE;CACH,CAAC;AAEF,2EAA2E;AAC3E,gDAAgD;AAChD,4EAA4E;AAC5E,qBAAqB;AACrB,yBAAyB;AACzB,6BAA6B;AAC7B,+BAA+B;AAC/B,2BAA2B;AAC3B,EAAE;AACF,8CAA8C;AAC9C,sBAAsB;AACtB,MAAM;AACN,EAAE;AACF,iBAAiB;AACjB,EAAE;AACF,4CAA4C;AAC5C,IAAI"}
1
+ {"version":3,"file":"setupGithubCommand.js","sourceRoot":"","sources":["../../../../src/ui/commands/setupGithubCommand.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,8DAA8D;AAC9D,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,+DAA+D;AAC/D,WAAW;AACX,oBAAoB;AACpB,4BAA4B;AAC5B,wBAAwB;AACxB,oCAAoC;AAEpC,OAAO,EACL,WAAW,GAGZ,MAAM,YAAY,CAAC;AACpB,mEAAmE;AACnE,sEAAsE;AACtE,+DAA+D;AAE/D,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,qCAAqC;IACrC,oCAAoC;IACpC,gCAAgC;IAChC,0CAA0C;IAC1C,6BAA6B;CAC9B,CAAC;AAEF,oFAAoF;AACpF,iFAAiF;AACjF,8DAA8D;AAC9D,mFAAmF;AACnF,yCAAyC;AACzC,EAAE;AACF,oCAAoC;AACpC,oCAAoC;AACpC,EAAE;AACF,0CAA0C;AAC1C,oBAAoB;AACpB,uBAAuB;AACvB,0FAA0F;AAC1F,SAAS;AACT,MAAM;AACN,EAAE;AACF,+CAA+C;AAC/C,qEAAqE;AACrE,qBAAqB;AACrB,IAAI;AAEJ,qDAAqD;AACrD,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,WAAmB;IACvD,MAAM,gBAAgB,GAAG,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;IAE1D,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAC3D,IAAI,CAAC;QACH,kDAAkD;QAClD,IAAI,eAAe,GAAG,EAAE,CAAC;QACzB,IAAI,UAAU,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC;YACH,eAAe,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QACtE,CAAC;QAAC,OAAO,MAAM,EAAE,CAAC;YAChB,qBAAqB;YACrB,UAAU,GAAG,KAAK,CAAC;QACrB,CAAC;QAED,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,8CAA8C;YAC9C,MAAM,cAAc,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;YAC1D,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;QAC7D,CAAC;aAAM,CAAC;YACN,kCAAkC;YAClC,MAAM,cAAc,GAAG,gBAAgB,CAAC,MAAM,CAC5C,CAAC,KAAK,EAAE,EAAE,CACR,CAAC,eAAe;iBACb,KAAK,CAAC,OAAO,CAAC;iBACd,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,KAAK,CAAC,CACzD,CAAC;YAEF,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9B,MAAM,YAAY,GAAG,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;gBAC7D,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;QACrD,6CAA6C;IAC/C,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAiB;IAC9C,IAAI,EAAE,cAAc;IACpB,WAAW,EACT,0EAA0E;IAC5E,IAAI,EAAE,WAAW,CAAC,QAAQ;IAC1B,MAAM,EAAE,GAA6B,EAAE;IACrC,2CAA2C;IAC3C,WAAW;IACX,4GAA4G;IAC5G,yDAAyD;IACzD,2DAA2D;IAC3D,sDAAsD;IACtD,wEAAwE;IAExE,yCAAyC;IACzC,CAAC;QACC,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,MAAM;QACnB,OAAO,EAAE;;;;;;;;;;;;;4FAa6E;KACvF,CAAC;IAEJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA6GE;CACH,CAAC;AAEF,2EAA2E;AAC3E,gDAAgD;AAChD,4EAA4E;AAC5E,qBAAqB;AACrB,yBAAyB;AACzB,6BAA6B;AAC7B,+BAA+B;AAC/B,2BAA2B;AAC3B,EAAE;AACF,8CAA8C;AAC9C,sBAAsB;AACtB,MAAM;AACN,EAAE;AACF,iBAAiB;AACjB,EAAE;AACF,4CAA4C;AAC5C,IAAI"}
@@ -4,8 +4,11 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import { vi, describe, expect, it, afterEach, beforeEach } from 'vitest';
7
+ import path from 'path';
8
+ import fs from 'fs/promises';
9
+ import os from 'os';
7
10
  import * as gitUtils from '../../utils/gitUtils.js';
8
- import { setupGithubCommand } from './setupGithubCommand.js';
11
+ import { setupGithubCommand, updateGitignore, GITHUB_WORKFLOW_PATHS, } from './setupGithubCommand.js';
9
12
  vi.mock('child_process');
10
13
  // Mock fetch globally
11
14
  global.fetch = vi.fn();
@@ -36,6 +39,10 @@ describe('setupGithubCommand', async () => {
36
39
  const fakeRepoName = 'repo';
37
40
  const fakeRepoRoot = `/github.com/${fakeRepoOwner}/${fakeRepoName}/root`;
38
41
  const fakeReleaseVersion = 'v1.2.3';
42
+ const workflows = GITHUB_WORKFLOW_PATHS.map((p) => path.basename(p));
43
+ for (const workflow of workflows) {
44
+ vi.mocked(global.fetch).mockReturnValueOnce(Promise.resolve(new Response(workflow)));
45
+ }
39
46
  vi.mocked(gitUtils.isGitHubRepository).mockReturnValueOnce(true);
40
47
  vi.mocked(gitUtils.getGitRepoRoot).mockReturnValueOnce(fakeRepoRoot);
41
48
  vi.mocked(gitUtils.getLatestGitHubRelease).mockResolvedValueOnce(fakeReleaseVersion);
@@ -66,4 +73,90 @@ describe('setupGithubCommand', async () => {
66
73
  }).toThrow('Unable to determine the GitHub repository. /setup-github must be run from a git repository.');
67
74
  });
68
75
  });
76
+ describe('updateGitignore', () => {
77
+ let scratchDir = '';
78
+ beforeEach(async () => {
79
+ scratchDir = await fs.mkdtemp(path.join(os.tmpdir(), 'update-gitignore-'));
80
+ });
81
+ afterEach(async () => {
82
+ if (scratchDir)
83
+ await fs.rm(scratchDir, { recursive: true });
84
+ });
85
+ it('creates a new .gitignore file when none exists', async () => {
86
+ await updateGitignore(scratchDir);
87
+ const gitignorePath = path.join(scratchDir, '.gitignore');
88
+ const content = await fs.readFile(gitignorePath, 'utf8');
89
+ expect(content).toBe('.gemini/\ngha-creds-*.json\n');
90
+ });
91
+ it('appends entries to existing .gitignore file', async () => {
92
+ const gitignorePath = path.join(scratchDir, '.gitignore');
93
+ const existingContent = '# Existing content\nnode_modules/\n';
94
+ await fs.writeFile(gitignorePath, existingContent);
95
+ await updateGitignore(scratchDir);
96
+ const content = await fs.readFile(gitignorePath, 'utf8');
97
+ expect(content).toBe('# Existing content\nnode_modules/\n\n.gemini/\ngha-creds-*.json\n');
98
+ });
99
+ it('does not add duplicate entries', async () => {
100
+ const gitignorePath = path.join(scratchDir, '.gitignore');
101
+ const existingContent = '.gemini/\nsome-other-file\ngha-creds-*.json\n';
102
+ await fs.writeFile(gitignorePath, existingContent);
103
+ await updateGitignore(scratchDir);
104
+ const content = await fs.readFile(gitignorePath, 'utf8');
105
+ expect(content).toBe(existingContent);
106
+ });
107
+ it('adds only missing entries when some already exist', async () => {
108
+ const gitignorePath = path.join(scratchDir, '.gitignore');
109
+ const existingContent = '.gemini/\nsome-other-file\n';
110
+ await fs.writeFile(gitignorePath, existingContent);
111
+ await updateGitignore(scratchDir);
112
+ const content = await fs.readFile(gitignorePath, 'utf8');
113
+ // Should add only the missing gha-creds-*.json entry
114
+ expect(content).toBe('.gemini/\nsome-other-file\n\ngha-creds-*.json\n');
115
+ expect(content).toContain('gha-creds-*.json');
116
+ // Should not duplicate .gemini/ entry
117
+ expect((content.match(/\.gemini\//g) || []).length).toBe(1);
118
+ });
119
+ it('does not get confused by entries in comments or as substrings', async () => {
120
+ const gitignorePath = path.join(scratchDir, '.gitignore');
121
+ const existingContent = [
122
+ '# This is a comment mentioning .gemini/ folder',
123
+ 'my-app.gemini/config',
124
+ '# Another comment with gha-creds-*.json pattern',
125
+ 'some-other-gha-creds-file.json',
126
+ '',
127
+ ].join('\n');
128
+ await fs.writeFile(gitignorePath, existingContent);
129
+ await updateGitignore(scratchDir);
130
+ const content = await fs.readFile(gitignorePath, 'utf8');
131
+ // Should add both entries since they don't actually exist as gitignore rules
132
+ expect(content).toContain('.gemini/');
133
+ expect(content).toContain('gha-creds-*.json');
134
+ // Verify the entries were added (not just mentioned in comments)
135
+ const lines = content
136
+ .split('\n')
137
+ .map((line) => line.split('#')[0].trim())
138
+ .filter((line) => line);
139
+ expect(lines).toContain('.gemini/');
140
+ expect(lines).toContain('gha-creds-*.json');
141
+ expect(lines).toContain('my-app.gemini/config');
142
+ expect(lines).toContain('some-other-gha-creds-file.json');
143
+ });
144
+ it('handles file system errors gracefully', async () => {
145
+ // Try to update gitignore in a non-existent directory
146
+ const nonExistentDir = path.join(scratchDir, 'non-existent');
147
+ // This should not throw an error
148
+ await expect(updateGitignore(nonExistentDir)).resolves.toBeUndefined();
149
+ });
150
+ it('handles permission errors gracefully', async () => {
151
+ const consoleSpy = vi.spyOn(console, 'debug').mockImplementation(() => { });
152
+ const fsModule = await import('node:fs');
153
+ const writeFileSpy = vi
154
+ .spyOn(fsModule.promises, 'writeFile')
155
+ .mockRejectedValue(new Error('Permission denied'));
156
+ await expect(updateGitignore(scratchDir)).resolves.toBeUndefined();
157
+ expect(consoleSpy).toHaveBeenCalledWith('Failed to update .gitignore:', expect.any(Error));
158
+ writeFileSpy.mockRestore();
159
+ consoleSpy.mockRestore();
160
+ });
161
+ });
69
162
  //# sourceMappingURL=setupGithubCommand.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"setupGithubCommand.test.js","sourceRoot":"","sources":["../../../../src/ui/commands/setupGithubCommand.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"setupGithubCommand.test.js","sourceRoot":"","sources":["../../../../src/ui/commands/setupGithubCommand.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { SlashCommand } from './types.js';
7
+ export declare const statusCommand: SlashCommand;
@@ -0,0 +1,71 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { CommandKind, } from './types.js';
7
+ import { getOAuthManager } from '../../providers/providerManagerInstance.js';
8
+ export const statusCommand = {
9
+ name: 'status',
10
+ description: 'show authentication status for all providers',
11
+ kind: CommandKind.BUILT_IN,
12
+ action: async (_context, _args) => {
13
+ try {
14
+ const oauthManager = getOAuthManager();
15
+ if (!oauthManager) {
16
+ return {
17
+ type: 'message',
18
+ messageType: 'error',
19
+ content: 'OAuth manager not available. Please try again.',
20
+ };
21
+ }
22
+ // Get authentication status for all providers
23
+ const statuses = await oauthManager.getAuthStatus();
24
+ if (statuses.length === 0) {
25
+ return {
26
+ type: 'message',
27
+ messageType: 'info',
28
+ content: 'No OAuth providers are registered.',
29
+ };
30
+ }
31
+ // Format status display
32
+ let statusMessage = 'Authentication Status:\n';
33
+ statusMessage += '─'.repeat(50) + '\n';
34
+ for (const status of statuses) {
35
+ const indicator = status.authenticated ? '✓' : '✗';
36
+ let line = `${indicator} ${status.provider}: `;
37
+ if (status.authenticated) {
38
+ line += `authenticated (${status.authType})`;
39
+ if (status.expiresIn && status.expiresIn > 0) {
40
+ const hours = Math.floor(status.expiresIn / 3600);
41
+ const minutes = Math.floor((status.expiresIn % 3600) / 60);
42
+ line += ` - expires in ${hours}h ${minutes}m`;
43
+ }
44
+ }
45
+ else {
46
+ line += 'not authenticated';
47
+ }
48
+ if (status.oauthEnabled !== undefined) {
49
+ line += ` [OAuth ${status.oauthEnabled ? 'enabled' : 'disabled'}]`;
50
+ }
51
+ statusMessage += line + '\n';
52
+ }
53
+ statusMessage += '\nUse /auth <provider> to configure OAuth settings';
54
+ statusMessage += '\nUse /logout <provider> to sign out';
55
+ return {
56
+ type: 'message',
57
+ messageType: 'info',
58
+ content: statusMessage,
59
+ };
60
+ }
61
+ catch (error) {
62
+ const errorMessage = error instanceof Error ? error.message : String(error);
63
+ return {
64
+ type: 'message',
65
+ messageType: 'error',
66
+ content: `Failed to get authentication status: ${errorMessage}`,
67
+ };
68
+ }
69
+ },
70
+ };
71
+ //# sourceMappingURL=statusCommand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statusCommand.js","sourceRoot":"","sources":["../../../../src/ui/commands/statusCommand.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAIL,WAAW,GACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAC;AAE7E,MAAM,CAAC,MAAM,aAAa,GAAiB;IACzC,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,8CAA8C;IAC3D,IAAI,EAAE,WAAW,CAAC,QAAQ;IAC1B,MAAM,EAAE,KAAK,EACX,QAAwB,EACxB,KAAa,EACiB,EAAE;QAChC,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;YACvC,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,OAAO;oBACL,IAAI,EAAE,SAAS;oBACf,WAAW,EAAE,OAAO;oBACpB,OAAO,EAAE,gDAAgD;iBAC1D,CAAC;YACJ,CAAC;YAED,8CAA8C;YAC9C,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,aAAa,EAAE,CAAC;YAEpD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1B,OAAO;oBACL,IAAI,EAAE,SAAS;oBACf,WAAW,EAAE,MAAM;oBACnB,OAAO,EAAE,oCAAoC;iBAC9C,CAAC;YACJ,CAAC;YAED,wBAAwB;YACxB,IAAI,aAAa,GAAG,0BAA0B,CAAC;YAC/C,aAAa,IAAI,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;YAEvC,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;gBAC9B,MAAM,SAAS,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;gBACnD,IAAI,IAAI,GAAG,GAAG,SAAS,IAAI,MAAM,CAAC,QAAQ,IAAI,CAAC;gBAE/C,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;oBACzB,IAAI,IAAI,kBAAkB,MAAM,CAAC,QAAQ,GAAG,CAAC;oBAC7C,IAAI,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;wBAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;wBAClD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;wBAC3D,IAAI,IAAI,iBAAiB,KAAK,KAAK,OAAO,GAAG,CAAC;oBAChD,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,IAAI,IAAI,mBAAmB,CAAC;gBAC9B,CAAC;gBAED,IAAI,MAAM,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;oBACtC,IAAI,IAAI,WAAW,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC;gBACrE,CAAC;gBAED,aAAa,IAAI,IAAI,GAAG,IAAI,CAAC;YAC/B,CAAC;YAED,aAAa,IAAI,oDAAoD,CAAC;YACtE,aAAa,IAAI,sCAAsC,CAAC;YAExD,OAAO;gBACL,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,MAAM;gBACnB,OAAO,EAAE,aAAa;aACvB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,YAAY,GAChB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACzD,OAAO;gBACL,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,OAAO;gBACpB,OAAO,EAAE,wCAAwC,YAAY,EAAE;aAChE,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -59,6 +59,7 @@ export interface CommandContext {
59
59
  */
60
60
  toggleVimEnabled: () => Promise<boolean>;
61
61
  setLlxprtMdFileCount: (count: number) => void;
62
+ updateHistoryTokenCount: (count: number) => void;
62
63
  reloadCommands: () => void;
63
64
  };
64
65
  session: {
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/ui/commands/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA8KH,MAAM,CAAN,IAAY,WAIX;AAJD,WAAY,WAAW;IACrB,oCAAqB,CAAA;IACrB,4BAAa,CAAA;IACb,wCAAyB,CAAA;AAC3B,CAAC,EAJW,WAAW,KAAX,WAAW,QAItB"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/ui/commands/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA+KH,MAAM,CAAN,IAAY,WAIX;AAJD,WAAY,WAAW;IACrB,oCAAqB,CAAA;IACrB,4BAAa,CAAA;IACb,wCAAyB,CAAA;AAC3B,CAAC,EAJW,WAAW,KAAX,WAAW,QAItB"}
@@ -3,87 +3,60 @@ import { render } from 'ink-testing-library';
3
3
  import { describe, it, expect, vi, beforeEach } from 'vitest';
4
4
  import { Footer } from './Footer.js';
5
5
  import { getProviderManager } from '../../providers/providerManagerInstance.js';
6
- import { OpenAIProvider, ProviderManager, } from '@vybestack/llxprt-code-core';
6
+ import { ProviderManager } from '@vybestack/llxprt-code-core';
7
+ // Mock the hooks
8
+ vi.mock('../hooks/useResponsive.js', () => ({
9
+ useResponsive: vi.fn(() => ({ breakpoint: 'NARROW' })),
10
+ }));
7
11
  // Mock the provider manager
8
12
  vi.mock('../../providers/providerManagerInstance.js', () => ({
9
13
  getProviderManager: vi.fn(),
10
14
  }));
11
15
  describe('ContextIndicator UI', () => {
12
- let mockProvider;
13
16
  let mockProviderManager;
14
17
  beforeEach(() => {
15
- // Create mock OpenAI provider
16
- mockProvider = {
17
- estimateContextUsage: vi.fn(),
18
- };
19
- // Make it an instance of OpenAIProvider for instanceof check
20
- Object.setPrototypeOf(mockProvider, OpenAIProvider.prototype);
21
18
  // Create a real ProviderManager instance and mock its methods
22
19
  mockProviderManager = new ProviderManager();
23
20
  // Mock the methods we need
24
21
  vi.spyOn(mockProviderManager, 'hasActiveProvider').mockReturnValue(true);
25
- vi.spyOn(mockProviderManager, 'getActiveProvider').mockReturnValue(mockProvider);
22
+ vi.spyOn(mockProviderManager, 'getActiveProvider').mockReturnValue({
23
+ name: 'openai',
24
+ });
26
25
  vi.mocked(getProviderManager).mockReturnValue(mockProviderManager);
27
26
  });
28
27
  it('should display context percentage without remote tokens', () => {
29
- const { lastFrame } = render(_jsx(Footer, { model: "gpt-4o", targetDir: "/test/dir", debugMode: false, debugMessage: "", errorCount: 0, showErrorDetails: false, promptTokenCount: 1000, nightly: false }));
28
+ const { lastFrame } = render(_jsx(Footer, { model: "gpt-4o", targetDir: "/test/dir", debugMode: false, debugMessage: "", errorCount: 0, showErrorDetails: false, historyTokenCount: 1000, nightly: false }));
30
29
  // Should show context in new format: Ctx: 1.0k/128k
31
30
  expect(lastFrame()).toContain('Ctx: 1.0k/128k');
32
31
  });
33
32
  it('should display context percentage when using OpenAI', () => {
34
- // Mock the context estimation
35
- mockProvider.estimateContextUsage.mockReturnValue({
36
- totalTokens: 52000,
37
- remoteTokens: 50000,
38
- promptTokens: 2000,
39
- maxTokens: 128000,
40
- contextUsedPercent: 40.625,
41
- tokensRemaining: 76000,
42
- });
43
- const { lastFrame } = render(_jsx(Footer, { model: "gpt-4o", targetDir: "/test/dir", debugMode: false, debugMessage: "", errorCount: 0, showErrorDetails: false, promptTokenCount: 1000, nightly: false }));
33
+ const { lastFrame } = render(_jsx(Footer, { model: "gpt-4o", targetDir: "/test/dir", debugMode: false, debugMessage: "", errorCount: 0, showErrorDetails: false, historyTokenCount: 1000, nightly: false }));
44
34
  // Should show context in new format: Ctx: 1.0k/128k
45
35
  expect(lastFrame()).toContain('Ctx: 1.0k/128k');
46
36
  });
47
37
  it('should handle high token usage', () => {
48
- // Mock near-limit context usage
49
- mockProvider.estimateContextUsage.mockReturnValue({
50
- totalTokens: 120000,
51
- remoteTokens: 115000,
52
- promptTokens: 5000,
53
- maxTokens: 128000,
54
- contextUsedPercent: 93.75,
55
- tokensRemaining: 8000,
56
- });
57
- const { lastFrame } = render(_jsx(Footer, { model: "gpt-4o", targetDir: "/test/dir", debugMode: false, debugMessage: "", errorCount: 0, showErrorDetails: false, promptTokenCount: 1000, nightly: false }));
58
- // Should show context in new format: Ctx: 1.0k/128k
59
- expect(lastFrame()).toContain('Ctx: 1.0k/128k');
38
+ const { lastFrame } = render(_jsx(Footer, { model: "gpt-4o", targetDir: "/test/dir", debugMode: false, debugMessage: "", errorCount: 0, showErrorDetails: false, historyTokenCount: 120000, nightly: false }));
39
+ // Should show context with high usage: Ctx: 120.0k/128k
40
+ expect(lastFrame()).toContain('Ctx: 120.0k/128k');
60
41
  });
61
- it('should fallback to local calculation on error', () => {
62
- // Make estimateContextUsage throw an error
63
- mockProvider.estimateContextUsage.mockImplementation(() => {
64
- throw new Error('API error');
65
- });
66
- const { lastFrame } = render(_jsx(Footer, { model: "gpt-4o", targetDir: "/test/dir", debugMode: false, debugMessage: "", errorCount: 0, showErrorDetails: false, promptTokenCount: 1000, nightly: false }));
67
- // Should fallback to local calculation in new format
42
+ it('should fallback to local calculation', () => {
43
+ const { lastFrame } = render(_jsx(Footer, { model: "gpt-4o", targetDir: "/test/dir", debugMode: false, debugMessage: "", errorCount: 0, showErrorDetails: false, historyTokenCount: 1000, nightly: false }));
44
+ // Should show local calculation in new format
68
45
  expect(lastFrame()).toContain('Ctx: 1.0k/128k');
69
- expect(lastFrame()).not.toContain('remote');
70
46
  });
71
47
  it('should handle non-OpenAI providers', () => {
72
48
  // Mock a non-OpenAI provider
73
49
  vi.mocked(mockProviderManager.getActiveProvider).mockReturnValue({
74
50
  name: 'anthropic',
75
51
  });
76
- const { lastFrame } = render(_jsx(Footer, { model: "claude-3-opus", targetDir: "/test/dir", debugMode: false, debugMessage: "", errorCount: 0, showErrorDetails: false, promptTokenCount: 1000, nightly: false }));
52
+ const { lastFrame } = render(_jsx(Footer, { model: "claude-3-opus", targetDir: "/test/dir", debugMode: false, debugMessage: "", errorCount: 0, showErrorDetails: false, historyTokenCount: 1000, nightly: false }));
77
53
  // Should use local calculation for non-OpenAI providers in new format
78
54
  expect(lastFrame()).toContain('Ctx: 1.0k/1049k');
79
- expect(lastFrame()).not.toContain('remote');
80
55
  });
81
56
  it('should handle missing conversation context', () => {
82
- const { lastFrame } = render(_jsx(Footer, { model: "gpt-4o", targetDir: "/test/dir", debugMode: false, debugMessage: "", errorCount: 0, showErrorDetails: false, promptTokenCount: 1000, nightly: false }));
83
- // Should not attempt to get remote context
84
- expect(mockProvider.estimateContextUsage).not.toHaveBeenCalled();
57
+ const { lastFrame } = render(_jsx(Footer, { model: "gpt-4o", targetDir: "/test/dir", debugMode: false, debugMessage: "", errorCount: 0, showErrorDetails: false, historyTokenCount: 1000, nightly: false }));
58
+ // Should display context normally
85
59
  expect(lastFrame()).toContain('Ctx: 1.0k/128k');
86
- expect(lastFrame()).not.toContain('remote');
87
60
  });
88
61
  });
89
62
  //# sourceMappingURL=ContextIndicator.ui.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ContextIndicator.ui.test.js","sourceRoot":"","sources":["../../../../src/ui/components/ContextIndicator.ui.test.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ContextIndicator.ui.test.js","sourceRoot":"","sources":["../../../../src/ui/components/ContextIndicator.ui.test.tsx"],"names":[],"mappings":"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"}
@@ -13,7 +13,7 @@ interface FooterProps {
13
13
  errorCount: number;
14
14
  showErrorDetails: boolean;
15
15
  showMemoryUsage?: boolean;
16
- promptTokenCount: number;
16
+ historyTokenCount: number;
17
17
  isPaidMode?: boolean;
18
18
  nightly: boolean;
19
19
  vimMode?: string;
@@ -62,9 +62,9 @@ const ResponsiveMemoryDisplay = ({ compact, detailed }) => {
62
62
  return _jsx(Text, { color: memoryUsageColor, children: memoryUsage });
63
63
  };
64
64
  // Responsive Context Usage Display
65
- const ResponsiveContextDisplay = ({ promptTokenCount, model, contextLimit, compact, detailed }) => {
65
+ const ResponsiveContextDisplay = ({ historyTokenCount, model, contextLimit, compact, detailed }) => {
66
66
  const limit = tokenLimit(model, contextLimit);
67
- const percentage = promptTokenCount / limit;
67
+ const percentage = historyTokenCount / limit;
68
68
  const remainingPercentage = (1 - percentage) * 100;
69
69
  // Use semantic colors based on how much context is left
70
70
  let color;
@@ -79,13 +79,13 @@ const ResponsiveContextDisplay = ({ promptTokenCount, model, contextLimit, compa
79
79
  }
80
80
  let displayText;
81
81
  if (detailed) {
82
- displayText = `Context: ${promptTokenCount.toLocaleString()}/${limit.toLocaleString()} tokens`;
82
+ displayText = `Context: ${historyTokenCount.toLocaleString()}/${limit.toLocaleString()} tokens`;
83
83
  }
84
84
  else if (compact) {
85
- displayText = `Ctx: ${(promptTokenCount / 1000).toFixed(1)}k/${(limit / 1000).toFixed(0)}k`;
85
+ displayText = `Ctx: ${(historyTokenCount / 1000).toFixed(1)}k/${(limit / 1000).toFixed(0)}k`;
86
86
  }
87
87
  else {
88
- displayText = `Context: ${(promptTokenCount / 1000).toFixed(1)}k/${(limit / 1000).toFixed(0)}k`;
88
+ displayText = `Context: ${(historyTokenCount / 1000).toFixed(1)}k/${(limit / 1000).toFixed(0)}k`;
89
89
  }
90
90
  return _jsx(Text, { color: color, children: displayText });
91
91
  };
@@ -105,7 +105,7 @@ const ResponsiveTimestamp = () => {
105
105
  }, []);
106
106
  return _jsx(Text, { color: SemanticColors.text.secondary, children: time });
107
107
  };
108
- export const Footer = ({ model, targetDir, branchName, debugMode, debugMessage, errorCount, showErrorDetails, showMemoryUsage, promptTokenCount, isPaidMode, nightly, vimMode, contextLimit, isTrustedFolder, }) => {
108
+ export const Footer = ({ model, targetDir, branchName, debugMode, debugMessage, errorCount, showErrorDetails, showMemoryUsage, historyTokenCount, isPaidMode, nightly, vimMode, contextLimit, isTrustedFolder, }) => {
109
109
  const { breakpoint } = useResponsive();
110
110
  // Define what to show at each breakpoint
111
111
  const showTimestamp = breakpoint === 'WIDE';
@@ -127,7 +127,7 @@ export const Footer = ({ model, targetDir, branchName, debugMode, debugMessage,
127
127
  ? truncateMiddle(branchName, maxBranchLength)
128
128
  : branchName, "*)"] }) })) : (_jsxs(Text, { color: SemanticColors.text.accent, children: ["(", branchName.length > maxBranchLength
129
129
  ? truncateMiddle(branchName, maxBranchLength)
130
- : branchName, "*)"] })) })), isTrustedFolder === false && (_jsx(Text, { color: SemanticColors.status.warning, children: " (untrusted)" })), debugMode && (_jsxs(_Fragment, { children: [_jsx(DebugProfiler, {}), _jsx(Text, { color: SemanticColors.status.error, children: ' ' + (debugMessage || '--debug') })] })), vimMode && (_jsxs(Text, { color: SemanticColors.text.secondary, children: ["[", vimMode, "] "] }))] }), _jsxs(Box, { flexDirection: "row", alignItems: "center", children: [showMemoryUsage && (_jsxs(_Fragment, { children: [_jsx(ResponsiveMemoryDisplay, { compact: isCompact, detailed: isDetailed }), _jsx(Text, { color: SemanticColors.text.secondary, children: " | " })] })), _jsx(ResponsiveContextDisplay, { promptTokenCount: promptTokenCount, model: model, contextLimit: contextLimit, compact: isCompact, detailed: isDetailed }), showTimestamp && (_jsxs(_Fragment, { children: [_jsx(Text, { color: SemanticColors.text.secondary, children: " | " }), _jsx(ResponsiveTimestamp, {})] }))] })] }), _jsxs(Box, { justifyContent: "space-between", width: "100%", alignItems: "center", children: [_jsxs(Box, { flexDirection: "row", alignItems: "center", children: [nightly ? (_jsx(Gradient, { colors: Colors.GradientColors, children: _jsx(Text, { children: shortenPath(tildeifyPath(targetDir), isCompact ? 30 : 70) }) })) : (_jsx(Text, { color: SemanticColors.text.secondary, children: shortenPath(tildeifyPath(targetDir), isCompact ? 30 : 70) })), !isCompact && (_jsx(Box, { marginLeft: 2, children: process.env.SANDBOX && process.env.SANDBOX !== 'sandbox-exec' ? (_jsxs(Text, { color: SemanticColors.status.success, children: ["[", process.env.SANDBOX.replace(/^gemini-(?:cli-)?/, ''), "]"] })) : process.env.SANDBOX === 'sandbox-exec' ? (_jsxs(Text, { color: SemanticColors.status.warning, children: ["[macOS Seatbelt", ' ', _jsxs(Text, { color: SemanticColors.text.secondary, children: ["(", process.env.SEATBELT_PROFILE, ")"] }), "]"] })) : (_jsxs(Text, { color: SemanticColors.status.error, children: ["[no sandbox", ' ', _jsx(Text, { color: SemanticColors.text.secondary, children: "(see /docs)" }), "]"] })) }))] }), _jsxs(Box, { flexDirection: "row", alignItems: "center", children: [showModelName && (_jsx(Text, { color: SemanticColors.text.accent, children: model })), isPaidMode !== undefined &&
130
+ : branchName, "*)"] })) })), isTrustedFolder === false && (_jsx(Text, { color: SemanticColors.status.warning, children: " (untrusted)" })), debugMode && (_jsxs(_Fragment, { children: [_jsx(DebugProfiler, {}), _jsx(Text, { color: SemanticColors.status.error, children: ' ' + (debugMessage || '--debug') })] })), vimMode && (_jsxs(Text, { color: SemanticColors.text.secondary, children: ["[", vimMode, "] "] }))] }), _jsxs(Box, { flexDirection: "row", alignItems: "center", children: [showMemoryUsage && (_jsxs(_Fragment, { children: [_jsx(ResponsiveMemoryDisplay, { compact: isCompact, detailed: isDetailed }), _jsx(Text, { color: SemanticColors.text.secondary, children: " | " })] })), _jsx(ResponsiveContextDisplay, { historyTokenCount: historyTokenCount, model: model, contextLimit: contextLimit, compact: isCompact, detailed: isDetailed }), showTimestamp && (_jsxs(_Fragment, { children: [_jsx(Text, { color: SemanticColors.text.secondary, children: " | " }), _jsx(ResponsiveTimestamp, {})] }))] })] }), _jsxs(Box, { justifyContent: "space-between", width: "100%", alignItems: "center", children: [_jsxs(Box, { flexDirection: "row", alignItems: "center", children: [nightly ? (_jsx(Gradient, { colors: Colors.GradientColors, children: _jsx(Text, { children: shortenPath(tildeifyPath(targetDir), isCompact ? 30 : 70) }) })) : (_jsx(Text, { color: SemanticColors.text.secondary, children: shortenPath(tildeifyPath(targetDir), isCompact ? 30 : 70) })), !isCompact && (_jsx(Box, { marginLeft: 2, children: process.env.SANDBOX && process.env.SANDBOX !== 'sandbox-exec' ? (_jsxs(Text, { color: SemanticColors.status.success, children: ["[", process.env.SANDBOX.replace(/^gemini-(?:cli-)?/, ''), "]"] })) : process.env.SANDBOX === 'sandbox-exec' ? (_jsxs(Text, { color: SemanticColors.status.warning, children: ["[macOS Seatbelt", ' ', _jsxs(Text, { color: SemanticColors.text.secondary, children: ["(", process.env.SEATBELT_PROFILE, ")"] }), "]"] })) : (_jsxs(Text, { color: SemanticColors.status.error, children: ["[no sandbox", ' ', _jsx(Text, { color: SemanticColors.text.secondary, children: "(see /docs)" }), "]"] })) }))] }), _jsxs(Box, { flexDirection: "row", alignItems: "center", children: [showModelName && (_jsx(Text, { color: SemanticColors.text.accent, children: model })), isPaidMode !== undefined &&
131
131
  (() => {
132
132
  const providerManager = getProviderManager();
133
133
  const activeProvider = providerManager?.getActiveProvider?.();