google-gemini/gemini-cli
An open-source AI agent that brings the power of Gemini directly into your terminal.
TypeScript★ 108,192+44 that day#6 on trending
E37.3/100
Duplication40
11.2% in typescript, tsx, javascript, python, bash, csharp, docker, makefileDead code29
13.5%Complexity45
58% The score is jscpd's own --health model: markup, data and text left out, tests kept. The numbers below are the trending scan's.
2.97%duplicated code · 9,243 of 311,591 lines
525clones in code
1,248code files of 2,730 scanned
11.18%duplicated over all files · 5,809 clones
Most complex files
- packages/cli/src/ui/components/shared/text-buffer.ts811 cx
- packages/cli/src/ui/hooks/useGeminiStream.test.tsx733 cx
- packages/cli/src/ui/components/InputPrompt.test.tsx673 cx
- packages/cli/src/ui/AppContainer.test.tsx573 cx
- packages/cli/src/ui/components/shared/text-buffer.test.ts541 cx
- packages/core/src/core/geminiChat.test.ts530 cx
- packages/cli/src/ui/AppContainer.tsx523 cx
- packages/core/src/config/config.ts477 cx
- packages/cli/src/config/settings.test.ts423 cx
- packages/cli/src/ui/hooks/useGeminiStream.ts422 cx
Dead code 13.48% unused · 573 findings
- packages/cli/src/ui/AppContainer.tsxunused-file
- packages/cli/src/ui/hooks/useGeminiStream.tsunused-file
- packages/cli/src/ui/components/InputPrompt.tsxunused-file
- packages/cli/src/ui/hooks/vim.tsunused-file
- packages/cli/src/acp/acpSession.tsunused-file
- packages/cli/src/utils/sandbox.tsunused-file
- packages/cli/src/ui/components/InboxDialog.tsxunused-file
- packages/cli/src/ui/components/AskUserDialog.tsxunused-file
- packages/cli/src/config/config.tsunused-file
- packages/cli/src/ui/components/messages/ToolConfirmationMessage.tsxunused-file
The code number leaves out tests, fixtures, docs, examples, data files, styles, translations and vendored code.
Largest clones in the code
- 13 lines in 21 placestypescript58 tokenspackages/core/src/telemetry/loggers.ts:127–139packages/core/src/telemetry/loggers.ts:186–197packages/core/src/telemetry/loggers.ts:201–212packages/core/src/telemetry/loggers.ts:248–259packages/core/src/telemetry/loggers.ts:352–363and 16 more
127ClearcutLogger.getInstance(config)?.logNewPromptEvent(event); 128bufferTelemetryEvent(() => { 129 const logger = logs.getLogger(SERVICE_NAME); 130 131 const logRecord: LogRecord = { 132 body: event.toLogBody(), 133 attributes: event.toOpenTelemetryAttributes(config), 134 }; 135 logger.emit(logRecord); 136});186 ClearcutLogger.getInstance(config)?.logToolOutputTruncatedEvent(event); 187 bufferTelemetryEvent(() => { 188 const logger = logs.getLogger(SERVICE_NAME); 189 const logRecord: LogRecord = { 190 body: event.toLogBody(), 191 attributes: event.toOpenTelemetryAttributes(config), 192 }; 193 logger.emit(logRecord); 194 }); 195}First 10 of 13 lines, the second copy on the right.
- 9 lines in 16 placestypescript52 tokenspackages/core/src/telemetry/loggers.ts:127–135packages/core/src/telemetry/loggers.ts:148–155packages/core/src/telemetry/loggers.ts:216–223packages/core/src/telemetry/loggers.ts:496–503packages/core/src/telemetry/loggers.ts:512–519and 11 more
127ClearcutLogger.getInstance(config)?.logNewPromptEvent(event); 128bufferTelemetryEvent(() => { 129 const logger = logs.getLogger(SERVICE_NAME); 130 131 const logRecord: LogRecord = { 132 body: event.toLogBody(), 133 attributes: event.toOpenTelemetryAttributes(config), 134 }; 135 logger.emit(logRecord);148ClearcutLogger.getInstance(config)?.logToolCallEvent(event); 149bufferTelemetryEvent(() => { 150 const logger = logs.getLogger(SERVICE_NAME); 151 const logRecord: LogRecord = { 152 body: event.toLogBody(), 153 attributes: event.toOpenTelemetryAttributes(config), 154 }; 155 logger.emit(logRecord); - 149 lines in 2 placestypescript693 tokenspackages/cli/src/nonInteractiveCli.ts:88–236packages/cli/src/nonInteractiveCliAgentSession.ts:88–234
88return promptIdContext.run(prompt_id, async () => { 89 const consolePatcher = new ConsolePatcher({ 90 stderr: true, 91 interactive: false, 92 debugMode: config.getDebugMode(), 93 onNewMessage: (msg) => { 94 coreEvents.emitConsoleLog(msg.type, msg.content); 95 }, 96 }); 97First 10 of 149 lines.
7 more
- 169 lines in 2 placestypescript498 tokens
- 200 lines in 2 placestypescript383 tokens
- 99 lines in 2 placestypescript368 tokens
- 66 lines in 2 placestypescript329 tokens
- 93 lines in 2 placestypescript286 tokens
- 37 lines in 2 placestypescript235 tokens
- 48 lines in 2 placestypescript229 tokens
Largest clones over all files, tests and data included
- 143 lines in 4 placesmarkuptests3,668 tokenspackages/cli/src/ui/components/__snapshots__/SettingsDialog-SettingsDialog-Initial-Rendering-should-render-settings-list-with-visual-indicators.snap.svg:3–145packages/cli/src/ui/components/__snapshots__/SettingsDialog-SettingsDialog-Snapshot-Tests-should-render-default-state-correctly.snap.svg:3–145packages/cli/src/ui/components/__snapshots__/SettingsDialog-SettingsDialog-Snapshot-Tests-should-render-file-filtering-settings-configured-correctly.snap.svg:3–145packages/cli/src/ui/components/__snapshots__/SettingsDialog-SettingsDialog-Snapshot-Tests-should-render-tools-and-security-settings-correctly.snap.svg:3–145
3 text { font-family: Consolas, "Courier New", monospace; font-size: 14px; dominant-baseline: text-before-edge; white-space: pre; } 4</style> 5<rect width="920" height="751" fill="#000000" /> 6<g transform="translate(10, 10)"> 7 <text x="0" y="2" fill="#878787" textLength="900" lengthAdjust="spacingAndGlyphs">╭──────────────────────────────────────────────────────────────────────────… 8 <text x="0" y="19" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs">│</text> 9 <text x="891" y="19" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs">│</text> 10 <text x="0" y="36" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs">│</text> 11 <text x="27" y="36" fill="#ffffff" textLength="99" lengthAdjust="spacingAndGlyphs" font-weight="bold">> Settings </text> 12 <text x="891" y="36" fill="#878787" textLength="9" lengthAdjust="spacingAndGlyphs">│</text>First 10 of 143 lines.
- 20 lines in 15 placestxtdocs and examples251 tokenspackages/vscode-ide-companion/NOTICES.txt:11–30packages/vscode-ide-companion/NOTICES.txt:38–58packages/vscode-ide-companion/NOTICES.txt:94–112packages/vscode-ide-companion/NOTICES.txt:273–292packages/vscode-ide-companion/NOTICES.txt:482–502and 10 more
11Permission is hereby granted, free of charge, to any person obtaining a copy 12of this software and associated documentation files (the "Software"), to deal 13in the Software without restriction, including without limitation the rights 14to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15copies of the Software, and to permit persons to whom the Software is 16furnished to do so, subject to the following conditions: 17 18The above copyright notice and this permission notice shall be included in all 19copies or substantial portions of the Software. 20First 10 of 20 lines.
- 573 lines in 2 placestypescripttests2,723 tokenspackages/cli/src/nonInteractiveCli.test.ts:1488–2060packages/cli/src/nonInteractiveCliAgentSession.test.ts:1454–2026
1488}); 1489 1490it('should throw FatalInputError if a command requires confirmation', async () => { 1491 const mockCommand = { 1492 name: 'confirm', 1493 description: 'a command that needs confirmation', 1494 action: vi.fn().mockResolvedValue({ 1495 type: 'confirm_shell_commands', 1496 commands: ['rm -rf /'], 1497 }),First 10 of 573 lines.
- 105 lines in 2 placesmarkuptests2,552 tokenspackages/cli/src/ui/components/__snapshots__/SettingsDialog-SettingsDialog-Initial-Rendering-should-render-settings-list-with-visual-indicators.snap.svg:41–145packages/cli/src/ui/components/__snapshots__/SettingsDialog-SettingsDialog-Snapshot-Tests-should-render-accessibility-settings-enabled-correctly.snap.svg:41–145
- 39 lines in 3 placesmarkuptests1,115 tokenspackages/cli/src/ui/components/__snapshots__/SettingsDialog-SettingsDialog-Initial-Rendering-should-render-settings-list-with-visual-indicators.snap.svg:3–41packages/cli/src/ui/components/__snapshots__/SettingsDialog-SettingsDialog-Snapshot-Tests-should-render-accessibility-settings-enabled-correctly.snap.svg:3–41packages/cli/src/ui/components/__snapshots__/SettingsDialog-SettingsDialog-Snapshot-Tests-should-render-various-boolean-settings-enabled-correctly.snap.svg:3–41
By format, code only
| Format | Files | Lines | Clones | Duplicated lines | Duplication |
|---|---|---|---|---|---|
| typescript | 940 | 246,959 | 457 | 8,198 | 3.32% |
| tsx | 203 | 47,192 | 60 | 925 | 1.96% |
| javascript | 65 | 11,573 | 8 | 120 | 1.04% |
| python | 29 | 4,225 | 0 | 0 | 0% |
| bash | 10 | 1,074 | 0 | 0 | 0% |
| csharp | 1 | 568 | 0 | 0 | 0% |
By format, all files
| Format | Files | Lines | Clones | Duplicated lines | Duplication |
|---|---|---|---|---|---|
| typescript | 1,732 | 579,315 | 4,162 | 62,587 | 10.8% |
| tsx | 419 | 125,329 | 1,282 | 17,914 | 14.29% |
| markup | 106 | 6,582 | 183 | 2,593 | 39.4% |
| txt | 3 | 2,408 | 84 | 1,832 | 76.08% |
| javascript | 75 | 13,273 | 36 | 664 | 5% |
| yaml | 73 | 9,042 | 23 | 448 | 4.95% |
| json | 54 | 9,991 | 17 | 1,647 | 16.48% |
| markdown | 154 | 31,120 | 15 | 244 | 0.78% |
| python | 41 | 5,836 | 3 | 45 | 0.77% |
| bash | 29 | 1,606 | 3 | 27 | 1.68% |
Trending appearances
| Day | Rank | Stars | Files | Lines | Clones | All files | Code | Health | Commit |
|---|---|---|---|---|---|---|---|---|---|
| Oct 25, 2026 | #6 | 108,192 (+44) | 2,730 | 787,054 | 5,809 | 11.18% | 2.97% | E 37.3 | cd1b45c |
Want this for your own project? Install jscpd and run jscpd ., or measure it the way the baselines were measured.