Skip to content

Commit 3f472b8

Browse files
committed
feat(cli): add DevTools integration with gemini-cli-devtools
1 parent d45a45d commit 3f472b8

13 files changed

Lines changed: 312 additions & 96 deletions

.gemini/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,8 @@
33
"toolOutputMasking": {
44
"enabled": true
55
}
6+
},
7+
"general": {
8+
"devtools": true
69
}
710
}

docs/get-started/configuration.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ their corresponding top-level category object in your `settings.json` file.
106106
- **Description:** Enable Vim keybindings
107107
- **Default:** `false`
108108

109+
- **`general.devtools`** (boolean):
110+
- **Description:** Enable DevTools inspector on launch.
111+
- **Default:** `false`
112+
109113
- **`general.enableAutoUpdate`** (boolean):
110114
- **Description:** Enable automatic updates.
111115
- **Default:** `true`
@@ -855,6 +859,11 @@ their corresponding top-level category object in your `settings.json` file.
855859
- **Default:** `true`
856860
- **Requires restart:** Yes
857861

862+
- **`experimental.enableEventDrivenScheduler`** (boolean):
863+
- **Description:** Enables event-driven scheduler within the CLI session.
864+
- **Default:** `true`
865+
- **Requires restart:** Yes
866+
858867
- **`experimental.extensionReloading`** (boolean):
859868
- **Description:** Enables extension loading/unloading within the CLI session.
860869
- **Default:** `false`

esbuild.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ const external = [
6363
'@lydell/node-pty-win32-arm64',
6464
'@lydell/node-pty-win32-x64',
6565
'keytar',
66+
'gemini-cli-devtools',
6667
];
6768

6869
const baseConfig = {

package-lock.json

Lines changed: 13 additions & 27 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@
137137
"@lydell/node-pty-linux-x64": "1.1.0",
138138
"@lydell/node-pty-win32-arm64": "1.1.0",
139139
"@lydell/node-pty-win32-x64": "1.1.0",
140+
"gemini-cli-devtools": "^0.2.1",
140141
"keytar": "^7.9.0",
141142
"node-pty": "^1.0.0"
142143
},

packages/cli/src/config/settingsSchema.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,15 @@ const SETTINGS_SCHEMA = {
179179
description: 'Enable Vim keybindings',
180180
showInDialog: true,
181181
},
182+
devtools: {
183+
type: 'boolean',
184+
label: 'DevTools',
185+
category: 'General',
186+
requiresRestart: false,
187+
default: false,
188+
description: 'Enable DevTools inspector on launch.',
189+
showInDialog: false,
190+
},
182191
enableAutoUpdate: {
183192
type: 'boolean',
184193
label: 'Enable Auto Update',
@@ -1514,6 +1523,15 @@ const SETTINGS_SCHEMA = {
15141523
description: 'Enable requesting and fetching of extension settings.',
15151524
showInDialog: false,
15161525
},
1526+
enableEventDrivenScheduler: {
1527+
type: 'boolean',
1528+
label: 'Event Driven Scheduler',
1529+
category: 'Experimental',
1530+
requiresRestart: true,
1531+
default: true,
1532+
description: 'Enables event-driven scheduler within the CLI session.',
1533+
showInDialog: false,
1534+
},
15171535
extensionReloading: {
15181536
type: 'boolean',
15191537
label: 'Extension Reloading',

packages/cli/src/gemini.tsx

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -351,11 +351,12 @@ export async function main() {
351351
}
352352

353353
const isDebugMode = cliConfig.isDebugMode(argv);
354+
const earlyConsoleLogs: Array<{ type: string; content: string }> = [];
354355
const consolePatcher = new ConsolePatcher({
355356
stderr: true,
356357
debugMode: isDebugMode,
357358
onNewMessage: (msg) => {
358-
coreEvents.emitConsoleLog(msg.type, msg.content);
359+
earlyConsoleLogs.push({ type: msg.type, content: msg.content });
359360
},
360361
});
361362
consolePatcher.patch();
@@ -518,11 +519,19 @@ export async function main() {
518519

519520
adminControlsListner.setConfig(config);
520521

521-
if (config.isInteractive() && config.getDebugMode()) {
522+
if (config.isInteractive() && settings.merged.general.devtools) {
522523
const { registerActivityLogger } = await import(
523-
'./utils/activityLogger.js'
524+
'./utils/devtoolsService.js'
524525
);
525-
registerActivityLogger(config);
526+
await registerActivityLogger(config);
527+
// Replay early console logs directly to ActivityLogger (bypasses
528+
// coreEvents so they only appear in DevTools, not the TUI debug console).
529+
const { ActivityLogger } = await import('./utils/activityLogger.js');
530+
const capture = ActivityLogger.getInstance();
531+
for (const log of earlyConsoleLogs) {
532+
capture.logConsole(log);
533+
}
534+
earlyConsoleLogs.length = 0;
526535
}
527536

528537
// Register config for telemetry shutdown

packages/cli/src/nonInteractiveCli.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ import type { LoadedSettings } from './config/settings.js';
3939
vi.mock('./ui/hooks/atCommandProcessor.js');
4040

4141
const mockRegisterActivityLogger = vi.hoisted(() => vi.fn());
42-
vi.mock('./utils/activityLogger.js', () => ({
42+
vi.mock('./utils/devtoolsService.js', () => ({
4343
registerActivityLogger: mockRegisterActivityLogger,
4444
}));
4545

packages/cli/src/nonInteractiveCli.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,9 @@ export async function runNonInteractive({
7373

7474
if (process.env['GEMINI_CLI_ACTIVITY_LOG_TARGET']) {
7575
const { registerActivityLogger } = await import(
76-
'./utils/activityLogger.js'
76+
'./utils/devtoolsService.js'
7777
);
78-
registerActivityLogger(config);
78+
await registerActivityLogger(config);
7979
}
8080

8181
const { stdout: workingStdout } = createWorkingStdio();

packages/cli/src/ui/utils/ConsolePatcher.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,16 @@ export class ConsolePatcher {
4949
private patchConsoleMethod =
5050
(type: 'log' | 'warn' | 'error' | 'debug' | 'info') =>
5151
(...args: unknown[]) => {
52+
if (type === 'debug' && !this.params.debugMode) return;
53+
5254
if (this.params.stderr) {
53-
if (type !== 'debug' || this.params.debugMode) {
54-
this.originalConsoleError(this.formatArgs(args));
55-
}
56-
} else {
57-
if (type !== 'debug' || this.params.debugMode) {
58-
this.params.onNewMessage?.({
59-
type,
60-
content: this.formatArgs(args),
61-
count: 1,
62-
});
63-
}
55+
this.originalConsoleError(this.formatArgs(args));
6456
}
57+
58+
this.params.onNewMessage?.({
59+
type,
60+
content: this.formatArgs(args),
61+
count: 1,
62+
});
6563
};
6664
}

0 commit comments

Comments
 (0)