Skip to content

feat(claude): scan ~/.claude-internal and subagent sessions#11

Merged
Miss-you merged 2 commits into
mainfrom
feat/claude-internal-and-subagents-support
Mar 10, 2026
Merged

feat(claude): scan ~/.claude-internal and subagent sessions#11
Miss-you merged 2 commits into
mainfrom
feat/claude-internal-and-subagents-support

Conversation

@Miss-you

Copy link
Copy Markdown
Owner

Summary

  • Enhance Claude provider to scan both ~/.claude/projects/ and ~/.claude-internal/projects/ by default (previously only ~/.claude/projects/)
  • Add recursive scanning of <session-uuid>/subagents/agent-*.jsonl files in both directories, treating each subagent as an independent session
  • Extract collectPaths() helper for reusable directory walking with graceful handling of missing directories

Details

  • --claude-dir flag override continues to work (backward compatible)
  • Subagent messageIds do not overlap with parent sessions — no dedup changes needed
  • Non-existent directories are silently skipped (important since ~/.claude-internal/ may not exist for all users)

Test plan

  • Unit tests: subagent discovery, multi-dir scanning, missing dir graceful handling, flag override, multi-base-dir merge
  • E2E tests: Claude subagent sessions appear in session --json and daily --json output
  • make test passes with -race -cover
  • go vet passes
  • Real-world validation: 227 Claude sessions / 291.54m tokens detected (vs fewer before)

🤖 Generated with Claude Code

The Claude provider previously only scanned ~/.claude/projects/ for
top-level JSONL files, missing two sources of token usage data:

1. ~/.claude-internal/projects/ was completely ignored
2. <session-uuid>/subagents/agent-*.jsonl files in both directories
   were skipped

Extract collectPaths() helper from CollectSessions() to walk a single
base directory. When no --claude-dir override is set, scan both default
directories and merge results. During the walk, probe subdirectories
for subagents/ children and collect their JSONL files as independent
sessions.

Subagent messageIds do not overlap with parent sessions (verified on
real data), so no dedup changes are needed. The existing --claude-dir
flag continues to work as a single-directory override.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Copilot AI review requested due to automatic review settings March 10, 2026 06:59

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the Claude provider’s session discovery so it can scan both the standard Claude projects directory and the ~/.claude-internal projects directory, and it adds support for treating subagent JSONL files as independent sessions (including E2E coverage via new testdata).

Changes:

  • Update Claude provider session collection to scan multiple default base directories and discover subagent JSONL sessions under <session>/subagents/.
  • Add unit + E2E tests and new E2E Claude session fixtures to validate subagent discovery and JSON outputs.
  • Add an openspec/config.yaml file (not referenced elsewhere in the repo).

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
provider/claude/parser.go Scan both ~/.claude/projects and ~/.claude-internal/projects, and collect subagent JSONL session paths via collectPaths.
provider/claude/parser_test.go Add unit tests for multi-base-dir scanning, subagent discovery, and missing directory handling.
e2e/e2e_test.go Add E2E tests asserting subagent sessions appear in session --json and daily --json output.
e2e/testdata/claude-sessions/project-test/session-main.jsonl New Claude main session fixture for E2E.
e2e/testdata/claude-sessions/project-test/session-main/subagents/agent-sub1.jsonl New Claude subagent fixture for E2E.
openspec/config.yaml New OpenSpec config template file added.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread provider/claude/parser.go
Comment on lines 91 to 94
projectDirs, err := os.ReadDir(baseDir)
if err != nil {
return nil, err
return // skip non-existent or unreadable directories
}

Copilot AI Mar 10, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

collectPaths currently returns on any ReadDir error (including permission/IO errors), which changes CollectSessions behavior from returning an error to silently producing no sessions. Consider only skipping os.IsNotExist(err) (to handle ~/.claude-internal missing) and propagating other errors back to CollectSessions so misconfigurations/permission issues are visible.

Copilot uses AI. Check for mistakes.
Comment thread provider/claude/parser_test.go Outdated
Comment on lines +347 to +358
func TestCollectClaudeSessions_MissingDirectoryGraceful(t *testing.T) {
// Point to a non-existent directory — collectPaths should skip it
baseDir := filepath.Join(t.TempDir(), "nonexistent")

prov := &Provider{}
result, err := prov.CollectSessions(baseDir)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if len(result) != 0 {
t.Errorf("got %d sessions, want 0", len(result))
}

Copilot AI Mar 10, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test asserts that an explicitly provided baseDir that does not exist should be silently skipped. That’s a behavioral change from the previous implementation (which returned an error) and could hide a mistyped --claude-dir. If the silent-skip behavior is only meant for the default ~/.claude-internal path, consider updating the test to expect an error when the user explicitly passes a missing directory.

Copilot uses AI. Check for mistakes.
Comment thread openspec/config.yaml Outdated
Comment on lines +1 to +3
schema: spec-driven

# Project context (optional)

Copilot AI Mar 10, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

openspec/config.yaml is introduced in this PR but isn't mentioned in the PR description. If this file is required for tooling, consider documenting that in the PR summary; otherwise it may be accidental/unrelated and should be split into a separate PR or removed.

Copilot uses AI. Check for mistakes.
…pec/config.yaml

Address PR review feedback:
- collectPaths now returns error; only os.ErrNotExist is silently
  skipped for default directories. Permission/IO errors are propagated.
- Explicit --claude-dir pointing to a non-existent path returns an
  error instead of silently producing empty results.
- Remove accidentally included openspec/config.yaml from this PR.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@Miss-you
Miss-you merged commit 20c3620 into main Mar 10, 2026
7 checks passed
@Miss-you
Miss-you deleted the feat/claude-internal-and-subagents-support branch March 10, 2026 07:28
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.

2 participants