Skip to content

feat(analytics): attribute Claude Desktop sessions by repository and branch - #447

Open
mykolanehrych wants to merge 3 commits into
codemie-ai:mainfrom
mykolanehrych:EPMCDME-12687
Open

feat(analytics): attribute Claude Desktop sessions by repository and branch#447
mykolanehrych wants to merge 3 commits into
codemie-ai:mainfrom
mykolanehrych:EPMCDME-12687

Conversation

@mykolanehrych

@mykolanehrych mykolanehrych commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds accurate repository/branch attribution for Claude Desktop sessions in CodeMie Analytics, and adds api-key based auth support for local Code/Desktop proxy integrations.

Before

before

After

after

Changes

  • Resolve and attribute the correct repository per Claude Desktop session (TCP process lookup, per-request X-CodeMie-Repository header, session-to-repository map with await-poll)
  • Inject X-CodeMie-Branch header for Claude Desktop session attribution
  • Fix Cowork vs Code tab session attribution and branch fallback logic
  • Add api-key auth support for local dev / Code integration sessions; remove local-dev apiKey auth bypass
  • Rename Desktop sandbox repository label from Claude Desktop/Default to Cowork
  • Harden --add-dir path handling (reject non-absolute paths, lazy regex) and consolidate lsof/repo-resolution logic
  • Dedupe concurrent Desktop session resolution
  • Update analytics/proxy specs and docs to reflect the implementation

Impact

Claude Desktop sessions are now attributed to the correct repository and branch in analytics instead of falling back to defaults, and local dev/Code integrations can authenticate via api key.

Checklist

  • Self-reviewed
  • Manual testing performed
  • Documentation updated (if needed)
  • No breaking changes (or clearly documented)

Ref: EPMCDME-12687

…branch

Resolve and attribute the correct repository/branch per Claude Desktop
session (TCP process lookup, per-request X-CodeMie-Repository header,
session-to-repository map with await-poll, X-CodeMie-Branch header
injection), fix Cowork vs Code tab session attribution and branch
fallback, add api-key auth support for local dev/Code integration
sessions, rename Desktop sandbox repository label to 'Cowork', and
harden --add-dir path handling and lsof/repo-resolution logic.

Ref: EPMCDME-12687
@codemie-ai

Copy link
Copy Markdown
Owner

[AUTO_CLOSE_WARNING] ⏰ This pull request is older than 14 days and will be automatically closed in 16 more days (when it reaches 30 days old)! To maintain this PR, either convert it to Draft or complete your changes and merge.

@8nevil8

8nevil8 commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Automated review — blockers

Focused on architecture, patterns, correctness, DRY, YAGNI. Minor issues intentionally omitted.

0. Policy blocker — user-header manipulation is a strictly secured operation

This PR extends header-injection.plugin.ts with +309 lines of new logic that decides what to inject into user-facing request headers (repository, branch attribution derived from OS-level process introspection). Any change to headers that carry user-attributable identity is a strictly secured operation in this repo and requires explicit, security-reviewed authorization before it lands. The current diff introduces new derivation paths and new injected fields without that gate.

Fix direction: Split the header-injection changes out of this PR and route them through the security-review process; keep the analytics attribution work in the telemetry runtime, where header injection is not the surface.

1. Fix4B debug label still present despite self-review CR-004 marking it fixed

header-injection.plugin.ts — findWorkingDirForDesktopDirectRequest

The committed self-review JSON in this same PR marks CR-004 as "outcome": "fixed" with the directive to strip all external numbering scheme references. The surviving logger.debug('[header-injection] Fix4B subprocess cwd candidate', ...) directly contradicts that approval decision and will mislead any future maintainer grepping for the spec.

Fix direction: Remove the Fix4B label from the debug statement.

2. .git/HEAD direct read silently breaks worktrees and submodules

header-injection.plugin.ts — readGitBranchLocal

readGitBranchLocal reads .git/HEAD as a plain file — silently returns null for all git worktree and submodule sessions.

In a worktree, .git is a file containing gitdir: /path/to/.git/worktrees/name. readFile(join(dir, '.git', 'HEAD')) reads the gitdir pointer, the branch regex never matches, and branch is stored as empty for the entire session — silent wrong attribution. The shared detectGitBranch() in src/utils/processes.ts already handles this correctly via git rev-parse --abbrev-ref HEAD.

Fix direction: Replace readGitBranchLocal with a call to the existing detectGitBranch() utility (or resolve the gitdir indirection before reading HEAD).

3. Process introspection lives in the wrong architectural layer (+309 lines in a proxy plugin)

header-injection.plugin.ts — lines 152–461

OS-level process introspection (lsof, ps -axww, BFS process tree walk) and git file reads placed inside a proxy plugin whose declared responsibility is header injection.

The architecture layer for repository discovery is the telemetry runtime (DesktopTelemetryRuntime), not the proxy plugin layer. The resulting dual-resolution path (header-injection + DesktopTelemetryRuntime.ensureSession) is what caused the dual-write overwrite (self-review CR-002), and the two paths remain independently maintained with no shared contract.

Fix direction: Move resolveDesktopSessionRepository and all helper functions into DesktopTelemetryRuntime (or a DesktopRepositoryResolver service). The proxy plugin reads only from the shared sessionRepositoryMap.

4. 30s TTL fallback permanently caches cross-project misattribution

header-injection.plugin.ts — lastDesktopRepo fallback, ~line 128

30-second TTL heuristic caches a guessed repository into sessionRepositoryMap on cache miss, permanently misattributing rapid project switches.

A user opening a second Desktop project within 30 seconds of the first will have their new orchestrator request permanently attributed to the previous project — sessionRepositoryMap.set(cliSessionId, last.repo) is irreversible; subsequent retries are skipped because the key is now present in the map.

Fix direction: Store fallback entries as tentative (e.g. a separate sessionRepositoryFallbackSet) so the next successful resolution from any strategy can overwrite them.

@codemie-ai

Copy link
Copy Markdown
Owner

[AUTO_CLOSE_WARNING] 🔒 This pull request was automatically closed after being older than 30 days with no activity. Contact maintainers to reopen if needed.

@codemie-ai codemie-ai closed this Aug 28, 2026
@m-golovchin m-golovchin reopened this Aug 31, 2026
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.

4 participants