Skip to content

feat(analytics): add Gemini CLI session discovery to analytics report - #467

Open
alex-budanov wants to merge 6 commits into
codemie-ai:mainfrom
alex-budanov:EPMCDME-13909
Open

feat(analytics): add Gemini CLI session discovery to analytics report#467
alex-budanov wants to merge 6 commits into
codemie-ai:mainfrom
alex-budanov:EPMCDME-13909

Conversation

@alex-budanov

Copy link
Copy Markdown
Contributor

Summary

The codemie analytics report was silently omitting Gemini CLI sessions because GeminiSessionAdapter lacked a discoverSessions() implementation and 'gemini' was absent from the NATIVE_AGENTS list. This PR adds Gemini session discovery to the native analytics pipeline, following the established Claude/Copilot-CLI adapter pattern.

Changes

  • gemini.paths.ts (new): path helpers with GEMINI_HOME env var override for test isolation
  • gemini.session-adapter.ts: discoverSessions() iterates ~/.gemini/tmp/{hash}/chats/*.json, applies maxAgeDays filter, returns newest-first; never throws
  • native-loader.ts: added 'gemini' to NATIVE_AGENTS to wire session discovery and ownership/dedup
  • agent-labels.ts + app.js: added 'gemini' → 'Gemini CLI' display label

Testing

  • Tests added/updated: 18 new unit tests (12 for discoverSessions(), 3 for Gemini CLI label, 3 for native-loader ownership/dedup gate)
  • Manual testing: typecheck PASS, lint PASS, full test suite exit 0

Checklist

  • Code follows project standards (architecture.md boundaries respected: Plugin → Core → Utils)
  • CI is green (npm run ci)
  • No merge conflicts with main

Fixes EPMCDME-13909

Aleksandr Budanov and others added 6 commits August 5, 2026 12:04
Implements discoverSessions() on GeminiSessionAdapter so the analytics
layer can find ~/.gemini/tmp/{hash}/chats/*.json sessions. Adds
gemini.paths.ts for GEMINI_HOME env-var override (test isolation) and
12 unit tests covering empty dirs, maxAgeDays filtering, newest-first
sorting, limit, malformed JSON, and multi-hash discovery.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds 'gemini': 'Gemini CLI' to agent-labels.ts and the inline AGENT_LABELS
map in app.js so the report renders 'Gemini CLI' instead of 'gemini'.
AGENT_COLORS in app.js already had the gemini entry; no change needed there.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds 'gemini' to the NATIVE_AGENTS array so the native-loader calls
GeminiSessionAdapter.discoverSessions() when building the analytics
report. Gemini sessions at ~/.gemini/tmp/{hash}/chats/*.json are now
discovered and synthesized alongside claude, codex, and copilot-cli.
Adds ownership-gate and dedup tests to native-loader.test.ts.

Also raises per-test timeouts to 120s on two WSL2-sensitive tests
(sync-plugin.test.ts and usage-readers.test.ts) that use vi.resetModules()
+ dynamic imports and race-condition fail when the global 30s expires mid-run.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ytics fix

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@alex-budanov

Copy link
Copy Markdown
Contributor Author

📋 Local Test Guide

local-test-guide.md

Local test guide — EPMCDME-13909 Gemini analytics fix

Step-by-step walkthrough for verifying the fix in WSL. Every command shows the exact folder you run it from.


What we are testing

codemie analytics was silently ignoring Gemini CLI sessions. The fix adds:

  1. discoverSessions() on GeminiSessionAdapter — reads ~/.gemini/tmp/{hash}/chats/*.json
  2. 'gemini' added to NATIVE_AGENTS — wires discovery into the analytics pipeline
  3. 'Gemini CLI' display label — shows the agent's friendly name in output and reports

Folder reference

Purpose Path
Repo root /mnt/c/Users/AleksandrBudanov/Projects/EPMCDME-13909/codemie-code
CLI entry point bin/codemie.js (inside repo root)
Fake Gemini home /tmp/test-gemini-home (you create this; see Step 2)

Step 1 — Checkout the fix branch and build

Open a WSL terminal and run:

cd /mnt/c/Users/AleksandrBudanov/Projects/EPMCDME-13909/codemie-code

git checkout EPMCDME-13909

npm install        # only needed if you haven't done it yet
npm run build      # compiles TypeScript → dist/ and copies plugins

Verify the build succeeded and the CLI responds:

node bin/codemie.js --version
# expected: a semver string, e.g. 0.11.0

Why npm run build? The CLI at bin/codemie.js imports from dist/. The TypeScript source
files in src/ are not executed directly.


Step 2 — Create a fake Gemini session directory

Using the GEMINI_HOME environment variable you can redirect the adapter away from
~/.gemini so you do not need Gemini CLI installed and do not touch real data.

Still in the repo root (codemie-code/), run:

export GEMINI_HOME=/tmp/test-gemini-home

HASH="abc123def456"   # any string; represents a project hash directory

mkdir -p $GEMINI_HOME/tmp/$HASH/chats

The directory tree the adapter expects is:

/tmp/test-gemini-home/
└── tmp/
    └── abc123def456/       ← project hash (any name)
        └── chats/
            └── *.json      ← one file per session

Step 3 — Create a mock session file

Run this from anywhere (it writes to the path you just created):

cat > $GEMINI_HOME/tmp/$HASH/chats/session-001.json << 'EOF'
{
  "sessionId": "session-001",
  "projectHash": "abc123def456",
  "startTime": "2026-08-05T10:00:00.000Z",
  "lastUpdated": "2026-08-05T10:05:00.000Z",
  "messages": [
    {
      "id": "msg-1",
      "timestamp": "2026-08-05T10:00:01.000Z",
      "type": "user",
      "content": "List files in src/"
    },
    {
      "id": "msg-2",
      "timestamp": "2026-08-05T10:00:03.000Z",
      "type": "gemini",
      "content": "Here are the files in src/",
      "tokens": {
        "input": 120,
        "output": 80,
        "cached": 0,
        "thoughts": 20,
        "tool": 15,
        "total": 235
      },
      "toolCalls": [
        {
          "id": "tc-1",
          "name": "list_directory",
          "args": { "path": "src/" },
          "status": "success",
          "timestamp": "2026-08-05T10:00:02.000Z",
          "result": [
            {
              "functionResponse": {
                "id": "tc-1",
                "name": "list_directory",
                "response": { "output": "analytics/\nagents/\nutils/" }
              }
            }
          ]
        }
      ]
    }
  ]
}
EOF

Key fields the adapter reads:

Field Type Purpose
sessionId string Unique ID for the session; used as dedup key
startTime ISO 8601 string Sets createdAt; sessions older than 30 days are skipped
lastUpdated ISO 8601 string Sets updatedAt
messages[].type "user" or "gemini" Role; "gemini" messages carry token counts
messages[].tokens object Input/output/cached/total; drives the analytics metrics
messages[].toolCalls array Tool invocations; counted in the tools.view metric

Timestamps must be recent (within 30 days) or the session is filtered out by maxAgeDays.


Step 4 — Run codemie analytics

From the repo root (codemie-code/):

cd /mnt/c/Users/AleksandrBudanov/Projects/EPMCDME-13909/codemie-code

GEMINI_HOME=/tmp/test-gemini-home node bin/codemie.js analytics --include-external

Why --include-external?
Gemini sessions that are not owned by a running CodeMie agent are tagged native-external.
Without this flag the CLI hides them (opt-in behaviour added to avoid polluting reports with
untracked data). If you already use CodeMie to manage a Gemini CLI session the flag is not
needed for those sessions, but it is needed for sessions discovered from the filesystem alone.

Actual terminal output structure — the CLI groups by PROJECT, not by agent. With one
discovered session the output looks like this:

============================================================
ANALYTICS SUMMARY
============================================================
Sessions: 1
Duration: 5m 0s
Turns: 1
File Operations: 0
Lines: +0 -0 ~0 (0)
Tool Calls: 1 (✓1, ✗0, 100.0%)

------------------------------------------------------------
PROJECTS
------------------------------------------------------------

============================================================
PROJECT: Unknown
============================================================
  Sessions: 1
  Duration: 5m 0s
  Turns: 1
  ...
  Tool Calls: 1 (✓1, ✗0, 100.0%)

The agent label "Gemini CLI" and the provider tag "native [external ⚠ not CodeMie-managed]"
only appear in the per-session block, which requires --verbose:

GEMINI_HOME=/tmp/test-gemini-home \
  node bin/codemie.js analytics --include-external --verbose

Look for this block nested under PROJECT → BRANCH:

      Session: session-001
      Agent:     Gemini CLI (gemini)
      Provider:  native [external ⚠ not CodeMie-managed]
      Duration:  5m 0s
      Turns:     1

Token totals are not in the terminal output. The displayStats method shows Sessions,
Duration, Turns, File Operations, Lines, and Tool Calls — no token breakdown. Token data
(input/output/cached/total) is visible only in the HTML report (Step 6). This affects all
native agents, not just Gemini, and is a pre-existing gap in synthesizeRawSession.

If you see No analytics data available. instead of any project block, go to the debug step
below.


Step 5 — Debug with verbose discovery logs

CODEMIE_DEBUG=true (or =1) enables logger.debug() output. The discovery method emits
[gemini-discovery] lines that show exactly what it found:

cd /mnt/c/Users/AleksandrBudanov/Projects/EPMCDME-13909/codemie-code

GEMINI_HOME=/tmp/test-gemini-home CODEMIE_DEBUG=true \
  node bin/codemie.js analytics --include-external 2>&1 | grep -i gemini

Successful discovery looks like:

[gemini-discovery] found 1 session(s)

If the directory does not exist:

[gemini-discovery] no tmp dir at /tmp/test-gemini-home/tmp

If a file has a bad timestamp or is malformed:

[gemini-discovery] skipping malformed file: /tmp/test-gemini-home/tmp/abc123def456/chats/session-001.json

Step 6 — Generate the HTML report

cd /mnt/c/Users/AleksandrBudanov/Projects/EPMCDME-13909/codemie-code

GEMINI_HOME=/tmp/test-gemini-home \
  node bin/codemie.js analytics --include-external --report --open

This writes codemie-analytics-YYYY-MM-DD.html in the current directory and tries to open
it in the default browser. In WSL open it manually in Windows if the auto-open does not work:

# copy the generated path from the output, e.g.:
explorer.exe /mnt/c/Users/AleksandrBudanov/Projects/EPMCDME-13909/codemie-code/codemie-analytics-2026-08-05.html

In the browser, verify:

  • "Gemini CLI" appears in the agent breakdown (label added by agent-labels.ts)
  • Tool invocations and token totals match the values in the session file
  • The agent icon/colour is orange-gold #F5A534 (pre-existing in app.js)

Step 7 — Run the unit tests for the changed files

This is faster than the full suite and avoids the WSL concurrent-load timeouts:

cd /mnt/c/Users/AleksandrBudanov/Projects/EPMCDME-13909/codemie-code

npx vitest run \
  src/agents/plugins/gemini/__tests__/gemini.discovery.test.ts \
  src/cli/commands/analytics/__tests__/agent-labels.test.ts \
  src/cli/commands/analytics/__tests__/native-loader.test.ts

Expected: 37 tests pass across the three files:

File Tests New in this PR
gemini.discovery.test.ts 12 12 (new file)
agent-labels.test.ts 3 3 (new file)
native-loader.test.ts 22 3 (Gemini ownership/dedup; 19 were pre-existing)
Total 37 18

Step 8 — Before/after comparison (sanity check)

To prove the fix is what makes Gemini sessions appear, temporarily revert the wire and re-build:

cd /mnt/c/Users/AleksandrBudanov/Projects/EPMCDME-13909/codemie-code

# --- BEFORE (revert the one-line wire, do NOT commit) ---
git diff HEAD src/cli/commands/analytics/native-loader.ts   # shows the +1 line
sed -i "s/'gemini', //" src/cli/commands/analytics/native-loader.ts
npm run build

GEMINI_HOME=/tmp/test-gemini-home node bin/codemie.js analytics --include-external
# ↑ Gemini CLI section should NOT appear

# --- AFTER (restore) ---
git restore src/cli/commands/analytics/native-loader.ts
npm run build

GEMINI_HOME=/tmp/test-gemini-home node bin/codemie.js analytics --include-external
# ↑ Gemini CLI section IS present

Optional — filter to Gemini sessions only

Use --agent gemini to show only Gemini CLI rows regardless of other agents on the machine:

GEMINI_HOME=/tmp/test-gemini-home \
  node bin/codemie.js analytics --include-external --agent gemini

Use --last 7d to scope to the past week (useful when you have real Gemini sessions mixed with old ones):

GEMINI_HOME=/tmp/test-gemini-home \
  node bin/codemie.js analytics --include-external --agent gemini --last 7d

Known limitation

Turn count in the report will show 1 regardless of how many exchanges the session has.
synthesizeRawSession checks m.type === 'assistant' for turn counting, but Gemini messages
use type: 'gemini'. Tool metrics and token totals are accurate. A dedicated
synthesizeGeminiRawSession branch (like the existing Codex path) would fix turn counting in a
follow-up.


Cleanup

When you are done testing, remove the fake data:

rm -rf /tmp/test-gemini-home
unset GEMINI_HOME

@alex-budanov

Copy link
Copy Markdown
Contributor Author

✅ Local Test Results

local-test-results.md

Local Test Results — EPMCDME-13909 Gemini Analytics Fix

Executed: 2026-08-05
Branch: EPMCDME-13909
CLI version: 0.11.0


Summary

Step Result Notes
1 — Build ✅ PASS Clean build, node bin/codemie.js --version0.11.0
2 & 3 — Fake session setup ✅ PASS Directory structure created, session file written
4 — codemie analytics ⚠️ PARTIAL Session IS discovered, but guide's expected output format does not match reality
5 — Verbose discovery debug ✅ PASS [gemini-discovery] found 1 session(s) confirmed
6 — HTML report ✅ PASS "Gemini CLI" label + #F5A534 color + correct tokens in payload
7 — Unit tests ✅ PASS 37/37 pass (guide predicted 18 — count wrong)
8 — Before/after comparison ✅ PASS Without wire → no sessions; with wire → 1 session

Overall verdict: the fix is functionally correct. Two discrepancies exist between the guide's descriptions and the actual CLI behavior. Neither represents a code bug — they are inaccuracies in the guide itself.


Step 1 — Checkout and Build

Command run:

git checkout EPMCDME-13909   # already on this branch
npm run build
node bin/codemie.js --version

Actual output:

> @codemieai/code@0.11.0 build
> tsc && tsc-alias && npm run copy-plugin
...
✓ Gemini extension copied successfully
Plugin assets copied successfully!

0.11.0

Result: ✅ PASS — Build clean, CLI responds, version confirmed.


Step 2 & 3 — Create Fake Gemini Session

Commands run:

export GEMINI_HOME=/tmp/test-gemini-home
HASH="abc123def456"
mkdir -p $GEMINI_HOME/tmp/$HASH/chats
cat > $GEMINI_HOME/tmp/$HASH/chats/session-001.json << 'EOF'
{ ... }
EOF

Actual output:

total 4
-rw-r--r-- 1 aleksandrbudanov 1111 Aug  5 19:45 session-001.json

Result: ✅ PASS — File written with correct structure.


Step 4 — Run codemie analytics

Command run:

GEMINI_HOME=/tmp/test-gemini-home node bin/codemie.js analytics --include-external

Guide's expected output:

Gemini CLI
  Sessions : 1
  Turns    : 1
  Tools    : 1
  Tokens   : 235  (in: 120, out: 80, cached: 0)

Actual terminal output (relevant section):

============================================================
PROJECT: Unknown
============================================================
  Sessions: 1
  Duration: 2s
  Turns: 1
  File Operations: 0
  Tool Calls: 1 (✓1, ✗0, 100.0%)

  Tool Usage:
    ┌────────────────┬───────────────────────────┬──────────────┐
    │ Tool           │   Calls (Success, Failed) │ Success Rate │
    ├────────────────┼───────────────────────────┼──────────────┤
    │ list_directory │                1 (✓1, ✗0) │       100.0% │
    └────────────────┴───────────────────────────┴──────────────┘

Result: ⚠️ PARTIAL — two discrepancies from the guide:

Discrepancy A — expected output format does not exist in the CLI:

The guide describes a per-agent summary block (Gemini CLI / Sessions / Turns / Tools / Tokens). This format does not exist in the terminal analytics output. The CLI organises output by PROJECT, not by AGENT. There is no agent-named section header in the terminal output.

What actually happens when you filter to --agent gemini: you get the standard ANALYTICS SUMMARY + PROJECTS format with all counts correct (Sessions: 1, Turns: 1, Tool Calls: 1) but no "Gemini CLI" heading.

The "Gemini CLI" agent label DOES appear — but only with --verbose, as:

Agent:     Gemini CLI (gemini)

Discrepancy B — tokens do not appear in terminal output:

The synthesizeRawSession function in native-loader.ts does not propagate the Gemini token fields (input, output, cached, total) from the ParsedSession into the RawSessionData deltas. As a result, the terminal analytics display has no token counts for native Gemini sessions.

Tokens ARE extracted correctly in the HTML report (via the cost enricher re-reading the session file, see Step 6 below). This is not a regression — Claude and other native agents also have no terminal-level token display.

What IS working:

  • Session is discovered and included in the pipeline ✅
  • Session count, turn count, and tool count are correct ✅
  • Tool name (list_directory) is correctly extracted ✅
  • provider is set to native-external (correct for untracked Gemini sessions) ✅

Step 5 — Verbose Discovery Debug

Command run:

GEMINI_HOME=/tmp/test-gemini-home CODEMIE_DEBUG=true \
  node bin/codemie.js analytics --include-external 2>&1 | grep -i gemini

Actual output:

[DEBUG] [system] [] [gemini-adapter] Registered processor: gemini-metrics (priority: 1)
[DEBUG] [system] [] [gemini-adapter] Registered processor: gemini-conversations (priority: 2)
[DEBUG] [system] [] [gemini-adapter] Initialized 2 processors
[DEBUG] [system] [] [gemini-discovery] found 1 session(s)
[DEBUG] [system] [] [gemini-adapter] Parsed session session-001: 2 messages, 1 tool types

Result: ✅ PASS — Discovery found 1 session exactly as documented. The expected success line [gemini-discovery] found 1 session(s) matches the guide exactly.


Step 6 — HTML Report

Command run:

GEMINI_HOME=/tmp/test-gemini-home node bin/codemie.js analytics --include-external --report

Actual output:

✓ HTML report written to: codemie-analytics-aleksandr-budanov-epam-com-2026-08-05.html
  Cost priced for 84/161 sessions (native agent logs required for the rest.)

Verified in HTML payload (extracted from embedded JSON):

{
  "sessionId": "session-001",
  "agentName": "gemini",
  "provider": "native-external",
  "turns": 1,
  "toolCallsTotal": 1,
  "tools": [
    { "toolName": "list_directory", "totalCalls": 1, "successCount": 1, "failureCount": 0 }
  ],
  "tokens": {
    "input": 120,
    "output": 80,
    "cacheRead": 0,
    "cacheCreation": 0,
    "total": 235
  }
}

Label lookup (AGENT_LABELS in report JS):

var AGENT_LABELS = { 'copilot-cli': 'GitHub Copilot CLI', 'gemini': 'Gemini CLI' };

Color: #F5A534 present — 20 occurrences of F5A534 found in the report file.

Result: ✅ PASS — "Gemini CLI" label present, orange-gold #F5A534 color present, token values match session file exactly (input: 120, output: 80, total: 235). The report cannot be opened in a headless WSL environment, but the payload content is verified.


Step 7 — Unit Tests

Command run:

npx vitest run \
  src/agents/plugins/gemini/__tests__/gemini.discovery.test.ts \
  src/cli/commands/analytics/__tests__/agent-labels.test.ts \
  src/cli/commands/analytics/__tests__/native-loader.test.ts

Actual result:

 Test Files  3 passed (3)
      Tests  37 passed (37)
   Start at  20:06:01
   Duration  26.34s

Breakdown by file:

File Tests Result
gemini.discovery.test.ts 12 ✅ All pass
agent-labels.test.ts 3 ✅ All pass
native-loader.test.ts 22 ✅ All pass
Total 37 ✅ All pass

Discrepancy from guide: Guide predicted 18 tests (12 + 3 + 3). Actual is 37. The native-loader test file has 22 tests, not 3. The guide undercounted — likely written when fewer native-loader tests existed, or counting only the 3 gemini-specific ownership tests while ignoring the pre-existing ones in that file.

Result: ✅ PASS — All 37 tests pass. The discrepancy in count does not indicate a problem; all tests pass cleanly.

Notable gemini-specific tests that pass:

  • returns "Gemini CLI" for the gemini agent key
  • honors GEMINI_HOME and sets correct filePath
  • skips malformed JSON files and includes valid ones
  • honors maxAgeDays and excludes old sessions
  • synthesizes a native gemini session into RawSessionData
  • tags an unowned gemini session native-external (gemini is a managed agent)
  • deduplicates a gemini session already tracked by CodeMie

Step 8 — Before/After Comparison

BEFORE (gemini removed from NATIVE_AGENTS):

sed -i "s/, 'gemini'//" src/cli/commands/analytics/native-loader.ts
# native-loader.ts line 31: const NATIVE_AGENTS = ['claude', 'codex', 'copilot-cli'] as const;
npm run build && GEMINI_HOME=/tmp/test-gemini-home node bin/codemie.js analytics --include-external --agent gemini

Output:

No sessions found matching the specified criteria.
Run with different filters or check that metrics are being collected.

AFTER (gemini restored):

git restore src/cli/commands/analytics/native-loader.ts
# native-loader.ts line 31: const NATIVE_AGENTS = ['claude', 'codex', 'copilot-cli', 'gemini'] as const;
npm run build && GEMINI_HOME=/tmp/test-gemini-home node bin/codemie.js analytics --include-external --agent gemini

Output:

ANALYTICS SUMMARY
Sessions: 1
...
Tool Calls: 1 (✓1, ✗0, 100.0%)

Result: ✅ PASS — The one-line wire ('gemini' in NATIVE_AGENTS) is the exact and sole cause of discovery working or not working. The fix is minimal and causal.


Issues Found

Issue 1 — Guide's Step 4 expected output format is incorrect

Severity: Documentation bug (not a code bug)

The guide shows:

Gemini CLI
  Sessions : 1
  Turns    : 1
  Tools    : 1
  Tokens   : 235  (in: 120, out: 80, cached: 0)

This block does not exist in the CLI. The CLI has no per-agent summary section in terminal output. The guide's expected output describes a format that was either planned but not implemented, or taken from a different/mock version of the CLI.

What to do: Update the guide. The correct way to verify terminal-level Gemini detection is:

  1. --agent gemini → see Sessions: 1 in the summary
  2. --agent gemini --verbose → see Agent: Gemini CLI (gemini) in the session detail

Issue 2 — Tokens do not appear in terminal analytics output

Severity: Out-of-scope gap (not introduced by this fix)

Token data is not shown in the terminal output for any native (untracked) agent session, including Gemini. The synthesizeRawSession function only propagates tool counts and model names, not token data. Token extraction for the terminal output would require a parallel pathway to the cost enricher used by the HTML report.

This is consistent with the behavior of other native agents (Claude, Codex, Copilot CLI). Fixing it would be a separate follow-up, not part of this ticket.

Tokens ARE correct in the HTML report (verified: input 120, output 80, total 235).

Issue 3 — Unit test count in guide is wrong (18 vs 37)

Severity: Documentation bug only

The guide says "18 tests pass — 12 discovery, 3 label, 3 native-loader ownership/dedup". The actual count is 37 (12 + 3 + 22). The native-loader test file has significantly more tests than the guide states. All tests pass; this is only a count mismatch in documentation.

Known Limitation (documented in guide, confirmed)

Turn count shows 1 for all Gemini sessions because synthesizeRawSession counts turns via messages.filter(isAssistant), which filters for type === 'assistant'. Gemini messages use type === 'gemini', so no assistant messages are found and turns = Math.max(0, 1) = 1. Confirmed: turns shows 1 in both terminal output and HTML report payload. Guide documents this and flags it for a follow-up.


Cleanup

rm -rf /tmp/test-gemini-home
unset GEMINI_HOME

Cleanup executed. GEMINI_HOME environment variable is cleared for this session.


Appendix — main branch (pre-fix) run

Executed: 2026-08-05, immediately after the fix-branch run above.
Branch: main (up to date with origin/main)
CLI version: 0.11.0

This run answers: "what does the user actually see without the fix?"

What is absent on main

Component Fix branch main
'gemini' in NATIVE_AGENTS ✅ present ❌ absent
discoverSessions() on Gemini adapter ✅ implemented ❌ not implemented
'gemini': 'Gemini CLI' in agent-labels.ts ✅ present ❌ absent
gemini.discovery.test.ts ✅ 12 tests ❌ file does not exist
agent-labels.test.ts ✅ 3 tests ❌ file does not exist
Gemini tests in native-loader.test.ts ✅ 22 tests (3 new) 19 tests (pre-existing only)

codemie analytics --agent gemini on main

No sessions found matching the specified criteria.
Run with different filters or check that metrics are being collected.

Debug log (CODEMIE_DEBUG=true) on main

Key difference in the debug output:

Fix branch:

[gemini-adapter] Initialized 2 processors
[gemini-discovery] found 1 session(s)
[gemini-adapter] Parsed session session-001: 2 messages, 1 tool types

main branch:

[gemini-adapter] Initialized 2 processors
(no [gemini-discovery] line — the method does not exist)

The Gemini adapter IS loaded in both branches (it exists for the managed agent flow), but on main it has no discoverSessions() method and 'gemini' is not in NATIVE_AGENTS, so the discovery loop never touches it.

Unit tests on main

npx vitest run \
  src/agents/plugins/gemini/__tests__/gemini.discovery.test.ts \  # does not exist
  src/cli/commands/analytics/__tests__/agent-labels.test.ts \     # does not exist
  src/cli/commands/analytics/__tests__/native-loader.test.ts

Actual result:

Test Files  1 passed (1)   ← vitest silently skipped the two missing files
     Tests  19 passed (19)

Vitest reported no error for the missing files — it simply ran the one that existed. The 19 passing tests are all pre-existing synthesizeRawSession / loadNativeSessions tests that have nothing to do with Gemini. The 3 gemini-specific tests added to native-loader.test.ts on the fix branch are absent on main.

Conclusion

On main, a real Gemini CLI session sitting in ~/.gemini/tmp/*/chats/ is silently ignored by codemie analytics. No error, no warning — the session simply does not exist from analytics' perspective. The fix branch changes exactly three lines/files to wire it in:

  1. native-loader.ts:31 — adds 'gemini' to NATIVE_AGENTS
  2. gemini.session-adapter.ts — adds discoverSessions() reading GEMINI_HOME/tmp/*/chats/*.json
  3. agent-labels.ts — adds 'gemini': 'Gemini CLI'

Each change is independently verifiable and the before/after is unambiguous.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant