@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.
- package/README.md +21 -17
- package/dist/package.json +4 -3
- package/dist/src/auth/anthropic-oauth-provider.d.ts +50 -3
- package/dist/src/auth/anthropic-oauth-provider.js +287 -63
- package/dist/src/auth/anthropic-oauth-provider.js.map +1 -1
- package/dist/src/auth/gemini-oauth-provider.d.ts +34 -3
- package/dist/src/auth/gemini-oauth-provider.js +308 -14
- package/dist/src/auth/gemini-oauth-provider.js.map +1 -1
- package/dist/src/auth/migration.d.ts +26 -0
- package/dist/src/auth/migration.js +54 -0
- package/dist/src/auth/migration.js.map +1 -0
- package/dist/src/auth/oauth-manager.d.ts +24 -0
- package/dist/src/auth/oauth-manager.js +179 -14
- package/dist/src/auth/oauth-manager.js.map +1 -1
- package/dist/src/auth/oauth-manager.spec.js +10 -8
- package/dist/src/auth/oauth-manager.spec.js.map +1 -1
- package/dist/src/auth/qwen-oauth-provider.d.ts +59 -3
- package/dist/src/auth/qwen-oauth-provider.js +263 -41
- package/dist/src/auth/qwen-oauth-provider.js.map +1 -1
- package/dist/src/config/config.js +11 -10
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/extension.d.ts +1 -1
- package/dist/src/config/extension.js +1 -1
- package/dist/src/gemini.js +33 -11
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +1 -1
- package/dist/src/generated/git-commit.js +1 -1
- package/dist/src/integration-tests/base-url-behavior.integration.test.js +4 -1
- package/dist/src/integration-tests/base-url-behavior.integration.test.js.map +1 -1
- package/dist/src/integration-tests/compression-settings-apply.integration.test.js +85 -332
- package/dist/src/integration-tests/compression-settings-apply.integration.test.js.map +1 -1
- package/dist/src/integration-tests/ephemeral-settings.integration.test.js +5 -16
- package/dist/src/integration-tests/ephemeral-settings.integration.test.js.map +1 -1
- package/dist/src/integration-tests/model-params-isolation.integration.test.js +8 -2
- package/dist/src/integration-tests/model-params-isolation.integration.test.js.map +1 -1
- package/dist/src/integration-tests/modelParams.integration.test.js +4 -1
- package/dist/src/integration-tests/modelParams.integration.test.js.map +1 -1
- package/dist/src/integration-tests/provider-switching.integration.test.js +4 -1
- package/dist/src/integration-tests/provider-switching.integration.test.js.map +1 -1
- package/dist/src/integration-tests/retry-settings.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/retry-settings.integration.test.js +56 -0
- package/dist/src/integration-tests/retry-settings.integration.test.js.map +1 -0
- package/dist/src/providers/index.d.ts +1 -1
- package/dist/src/providers/logging/LoggingProviderWrapper.test.js +58 -47
- package/dist/src/providers/logging/LoggingProviderWrapper.test.js.map +1 -1
- package/dist/src/providers/logging/multi-provider-logging.integration.test.js +130 -68
- package/dist/src/providers/logging/multi-provider-logging.integration.test.js.map +1 -1
- package/dist/src/providers/logging/performance.test.js +39 -16
- package/dist/src/providers/logging/performance.test.js.map +1 -1
- package/dist/src/providers/provider-gemini-switching.test.js +4 -1
- package/dist/src/providers/provider-gemini-switching.test.js.map +1 -1
- package/dist/src/providers/provider-switching.integration.test.js +12 -3
- package/dist/src/providers/provider-switching.integration.test.js.map +1 -1
- package/dist/src/providers/providerConfigUtils.js +2 -4
- package/dist/src/providers/providerConfigUtils.js.map +1 -1
- package/dist/src/providers/providerManagerInstance.js +24 -49
- package/dist/src/providers/providerManagerInstance.js.map +1 -1
- package/dist/src/services/BuiltinCommandLoader.js +4 -0
- package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
- package/dist/src/storage/ConversationStorage.test.js +10 -7
- package/dist/src/storage/ConversationStorage.test.js.map +1 -1
- package/dist/src/test-utils/mockCommandContext.js +2 -0
- package/dist/src/test-utils/mockCommandContext.js.map +1 -1
- package/dist/src/ui/App.e2e.test.d.ts +6 -0
- package/dist/src/ui/App.e2e.test.js +37 -0
- package/dist/src/ui/App.e2e.test.js.map +1 -0
- package/dist/src/ui/App.js +51 -4
- package/dist/src/ui/App.js.map +1 -1
- package/dist/src/ui/commands/authCommand.d.ts +9 -1
- package/dist/src/ui/commands/authCommand.js +109 -31
- package/dist/src/ui/commands/authCommand.js.map +1 -1
- package/dist/src/ui/commands/clearCommand.js +2 -0
- package/dist/src/ui/commands/clearCommand.js.map +1 -1
- package/dist/src/ui/commands/ideCommand.js +26 -0
- package/dist/src/ui/commands/ideCommand.js.map +1 -1
- package/dist/src/ui/commands/keyCommand.js +16 -54
- package/dist/src/ui/commands/keyCommand.js.map +1 -1
- package/dist/src/ui/commands/keyCommand.test.js +3 -3
- package/dist/src/ui/commands/keyCommand.test.js.map +1 -1
- package/dist/src/ui/commands/keyfileCommand.js +42 -32
- package/dist/src/ui/commands/keyfileCommand.js.map +1 -1
- package/dist/src/ui/commands/logoutCommand.d.ts +7 -0
- package/dist/src/ui/commands/logoutCommand.js +70 -0
- package/dist/src/ui/commands/logoutCommand.js.map +1 -0
- package/dist/src/ui/commands/modelCommand.js +16 -0
- package/dist/src/ui/commands/modelCommand.js.map +1 -1
- package/dist/src/ui/commands/profileCommand.js +31 -25
- package/dist/src/ui/commands/profileCommand.js.map +1 -1
- package/dist/src/ui/commands/profileCommand.test.js +15 -16
- package/dist/src/ui/commands/profileCommand.test.js.map +1 -1
- package/dist/src/ui/commands/providerCommand.js +10 -7
- package/dist/src/ui/commands/providerCommand.js.map +1 -1
- package/dist/src/ui/commands/setCommand.js +43 -19
- package/dist/src/ui/commands/setCommand.js.map +1 -1
- package/dist/src/ui/commands/setCommand.test.js +5 -7
- package/dist/src/ui/commands/setCommand.test.js.map +1 -1
- package/dist/src/ui/commands/setupGithubCommand.d.ts +2 -0
- package/dist/src/ui/commands/setupGithubCommand.js +123 -23
- package/dist/src/ui/commands/setupGithubCommand.js.map +1 -1
- package/dist/src/ui/commands/setupGithubCommand.test.js +94 -1
- package/dist/src/ui/commands/setupGithubCommand.test.js.map +1 -1
- package/dist/src/ui/commands/statusCommand.d.ts +7 -0
- package/dist/src/ui/commands/statusCommand.js +71 -0
- package/dist/src/ui/commands/statusCommand.js.map +1 -0
- package/dist/src/ui/commands/types.d.ts +1 -0
- package/dist/src/ui/commands/types.js.map +1 -1
- package/dist/src/ui/components/ContextIndicator.ui.test.js +19 -46
- package/dist/src/ui/components/ContextIndicator.ui.test.js.map +1 -1
- package/dist/src/ui/components/Footer.d.ts +1 -1
- package/dist/src/ui/components/Footer.js +7 -7
- package/dist/src/ui/components/Footer.js.map +1 -1
- package/dist/src/ui/components/Footer.responsive.test.js +28 -25
- package/dist/src/ui/components/Footer.responsive.test.js.map +1 -1
- package/dist/src/ui/components/OAuthCodeDialog.d.ts +5 -0
- package/dist/src/ui/components/OAuthCodeDialog.js +31 -1
- package/dist/src/ui/components/OAuthCodeDialog.js.map +1 -1
- package/dist/src/ui/components/OAuthCodeDialog.test.d.ts +6 -0
- package/dist/src/ui/components/OAuthCodeDialog.test.js +60 -0
- package/dist/src/ui/components/OAuthCodeDialog.test.js.map +1 -0
- package/dist/src/ui/contexts/KeypressContext.js +23 -1
- package/dist/src/ui/contexts/KeypressContext.js.map +1 -1
- package/dist/src/ui/contexts/KeypressContext.test.js +58 -2
- package/dist/src/ui/contexts/KeypressContext.test.js.map +1 -1
- package/dist/src/ui/contexts/SessionContext.d.ts +2 -0
- package/dist/src/ui/contexts/SessionContext.js +9 -1
- package/dist/src/ui/contexts/SessionContext.js.map +1 -1
- package/dist/src/ui/contexts/TodoContext.js +2 -2
- package/dist/src/ui/contexts/TodoContext.js.map +1 -1
- package/dist/src/ui/hooks/atCommandProcessor.js +0 -2
- package/dist/src/ui/hooks/atCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/atCommandProcessor.test.js +21 -6
- package/dist/src/ui/hooks/atCommandProcessor.test.js.map +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.js +2 -0
- package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/useAuthCommand.js +6 -5
- package/dist/src/ui/hooks/useAuthCommand.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.js +47 -63
- package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
- package/dist/src/ui/hooks/useProviderDialog.js +2 -5
- package/dist/src/ui/hooks/useProviderDialog.js.map +1 -1
- package/dist/src/ui/hooks/useToolScheduler.test.js +60 -24
- package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
- package/dist/src/ui/utils/platformConstants.d.ts +2 -0
- package/dist/src/ui/utils/platformConstants.js +2 -0
- package/dist/src/ui/utils/platformConstants.js.map +1 -1
- package/dist/src/ui/utils/secureInputHandler.js +18 -7
- package/dist/src/ui/utils/secureInputHandler.js.map +1 -1
- package/dist/src/ui/utils/secureInputHandler.test.js +20 -0
- package/dist/src/ui/utils/secureInputHandler.test.js.map +1 -1
- package/dist/src/utils/privacy/ConversationDataRedactor.d.ts +3 -3
- package/dist/src/utils/privacy/ConversationDataRedactor.js +16 -12
- package/dist/src/utils/privacy/ConversationDataRedactor.js.map +1 -1
- package/dist/src/utils/privacy/ConversationDataRedactor.test.js +115 -72
- package/dist/src/utils/privacy/ConversationDataRedactor.test.js.map +1 -1
- package/dist/src/validateNonInterActiveAuth.js +8 -17
- package/dist/src/validateNonInterActiveAuth.js.map +1 -1
- package/dist/src/zed-integration/schema.d.ts +194 -91
- package/dist/src/zed-integration/schema.js +7 -1
- package/dist/src/zed-integration/schema.js.map +1 -1
- package/dist/src/zed-integration/zedIntegration.d.ts +1 -3
- package/dist/src/zed-integration/zedIntegration.js +454 -198
- package/dist/src/zed-integration/zedIntegration.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- 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
|
-
|
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
|
-
|
19
|
-
|
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
|
-
//
|
78
|
-
const
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
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
|
-
|
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
|
-
|
88
|
-
|
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
|
-
|
91
|
-
|
181
|
+
const destination = path.resolve(
|
182
|
+
githubWorkflowsDir,
|
183
|
+
path.basename(workflow),
|
184
|
+
);
|
92
185
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
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 ${
|
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,
|
1
|
+
{"version":3,"file":"setupGithubCommand.js","sourceRoot":"","sources":["../../../../src/ui/commands/setupGithubCommand.ts"],"names":[],"mappings":"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"}
|
@@ -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":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,KAAK,QAAQ,MAAM,yBAAyB,CAAC;AACpD,OAAO,
|
1
|
+
{"version":3,"file":"setupGithubCommand.test.js","sourceRoot":"","sources":["../../../../src/ui/commands/setupGithubCommand.test.ts"],"names":[],"mappings":"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"}
|
@@ -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"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/ui/commands/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
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 {
|
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(
|
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,
|
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
|
-
|
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
|
-
|
49
|
-
|
50
|
-
|
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
|
62
|
-
|
63
|
-
|
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,
|
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,
|
83
|
-
// Should
|
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":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAkB,MAAM,QAAQ,CAAC;AAC9E,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,kBAAkB,EAAE,MAAM,4CAA4C,CAAC;AAChF,OAAO,
|
1
|
+
{"version":3,"file":"ContextIndicator.ui.test.js","sourceRoot":"","sources":["../../../../src/ui/components/ContextIndicator.ui.test.tsx"],"names":[],"mappings":"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"}
|
@@ -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 = ({
|
65
|
+
const ResponsiveContextDisplay = ({ historyTokenCount, model, contextLimit, compact, detailed }) => {
|
66
66
|
const limit = tokenLimit(model, contextLimit);
|
67
|
-
const percentage =
|
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: ${
|
82
|
+
displayText = `Context: ${historyTokenCount.toLocaleString()}/${limit.toLocaleString()} tokens`;
|
83
83
|
}
|
84
84
|
else if (compact) {
|
85
|
-
displayText = `Ctx: ${(
|
85
|
+
displayText = `Ctx: ${(historyTokenCount / 1000).toFixed(1)}k/${(limit / 1000).toFixed(0)}k`;
|
86
86
|
}
|
87
87
|
else {
|
88
|
-
displayText = `Context: ${(
|
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,
|
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, {
|
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?.();
|