diff --git a/apps/cli/src/commands/import/claude.ts b/apps/cli/src/commands/import/claude.ts index 4e75c2f1b..633cbd49a 100644 --- a/apps/cli/src/commands/import/claude.ts +++ b/apps/cli/src/commands/import/claude.ts @@ -17,11 +17,6 @@ export const importClaudeCommand = command({ long: 'session-id', description: 'UUID of the Claude Code session to import', }), - discover: option({ - type: optional(string), - long: 'discover', - description: 'Discovery mode: "latest" to import the most recent session', - }), projectPath: option({ type: optional(string), long: 'project-path', @@ -44,7 +39,7 @@ export const importClaudeCommand = command({ description: 'List available sessions instead of importing', }), }, - handler: async ({ sessionId, discover, projectPath, output, projectsDir, list }) => { + handler: async ({ sessionId, projectPath, output, projectsDir, list }) => { if (list) { const sessions = await discoverClaudeSessions({ projectPath, @@ -81,22 +76,10 @@ export const importClaudeCommand = command({ process.exit(1); } sessionFilePath = sessions[0].filePath; - } else if (discover === 'latest') { - const sessions = await discoverClaudeSessions({ - projectPath, - projectsDir, - latest: true, - }); - - if (sessions.length === 0) { - console.error('Error: no Claude Code sessions found.'); - process.exit(1); - } - sessionFilePath = sessions[0].filePath; - sessionId = sessions[0].sessionId; - console.log(`Discovered latest session: ${sessionId}`); } else { - console.error('Error: specify --session-id or --discover latest to select a session.'); + console.error( + 'Error: specify --session-id to select a session. Use --list to see available sessions.', + ); process.exit(1); } diff --git a/apps/cli/src/commands/import/codex.ts b/apps/cli/src/commands/import/codex.ts index a99035b1d..a7d3cd888 100644 --- a/apps/cli/src/commands/import/codex.ts +++ b/apps/cli/src/commands/import/codex.ts @@ -12,10 +12,10 @@ export const importCodexCommand = command({ name: 'codex', description: 'Import a Codex CLI session transcript for offline grading', args: { - discover: option({ + sessionId: option({ type: optional(string), - long: 'discover', - description: 'Discovery mode: "latest" to import the most recent session', + long: 'session-id', + description: 'UUID of the Codex CLI session to import', }), date: option({ type: optional(string), @@ -38,7 +38,7 @@ export const importCodexCommand = command({ description: 'List available sessions instead of importing', }), }, - handler: async ({ discover, date, output, sessionsDir, list }) => { + handler: async ({ sessionId, date, output, sessionsDir, list }) => { if (list) { const sessions = await discoverCodexSessions({ date, @@ -59,25 +59,27 @@ export const importCodexCommand = command({ return; } - if (discover !== 'latest') { - console.error('Error: specify --discover latest to select a session.'); - process.exit(1); - } - - const sessions = await discoverCodexSessions({ - date, - sessionsDir, - latest: true, - }); + let session: Awaited>[number]; - if (sessions.length === 0) { - console.error('Error: no Codex CLI sessions found.'); + if (sessionId) { + const sessions = await discoverCodexSessions({ + date, + sessionsDir, + limit: 100, + }); + const match = sessions.find((s) => s.sessionId === sessionId); + if (!match) { + console.error(`Error: session ${sessionId} not found.`); + process.exit(1); + } + session = match; + } else { + console.error( + 'Error: specify --session-id to select a session. Use --list to see available sessions.', + ); process.exit(1); } - const session = sessions[0]; - console.log(`Discovered latest session: ${session.filename}`); - // Parse the session const rawJsonl = await readTranscriptFile(session.filePath); const transcript = parseCodexSession(rawJsonl); diff --git a/apps/cli/src/commands/import/copilot.ts b/apps/cli/src/commands/import/copilot.ts index dab154120..7377181c7 100644 --- a/apps/cli/src/commands/import/copilot.ts +++ b/apps/cli/src/commands/import/copilot.ts @@ -12,11 +12,6 @@ export const importCopilotCommand = command({ long: 'session-id', description: 'UUID of the Copilot CLI session to import', }), - discover: option({ - type: optional(string), - long: 'discover', - description: 'Discovery mode: "latest" to import the most recent session', - }), output: option({ type: optional(string), long: 'output', @@ -34,7 +29,7 @@ export const importCopilotCommand = command({ description: 'List available sessions instead of importing', }), }, - handler: async ({ sessionId, discover, output, sessionStateDir, list }) => { + handler: async ({ sessionId, output, sessionStateDir, list }) => { if (list) { const sessions = await discoverCopilotSessions({ sessionStateDir, @@ -70,21 +65,10 @@ export const importCopilotCommand = command({ } sessionDir = match.sessionDir; resolvedSessionId = sessionId; - } else if (discover === 'latest') { - const sessions = await discoverCopilotSessions({ - sessionStateDir, - limit: 1, - }); - - if (sessions.length === 0) { - console.error('Error: no Copilot CLI sessions found.'); - process.exit(1); - } - sessionDir = sessions[0].sessionDir; - resolvedSessionId = sessions[0].sessionId; - console.log(`Discovered latest session: ${resolvedSessionId}`); } else { - console.error('Error: specify --session-id or --discover latest to select a session.'); + console.error( + 'Error: specify --session-id to select a session. Use --list to see available sessions.', + ); process.exit(1); } diff --git a/apps/web/src/content/docs/docs/evaluation/running-evals.mdx b/apps/web/src/content/docs/docs/evaluation/running-evals.mdx index 5d94ed245..58035377d 100644 --- a/apps/web/src/content/docs/docs/evaluation/running-evals.mdx +++ b/apps/web/src/content/docs/docs/evaluation/running-evals.mdx @@ -306,8 +306,9 @@ This is the same interface that agent-orchestrated evals use — the EVAL.yaml t Grade existing agent sessions without re-running them. Import a transcript, then run deterministic evaluators: ```bash -# Import a Claude Code session -agentv import claude --discover latest +# List sessions and import one +agentv import claude --list +agentv import claude --session-id # Run evaluators against the imported transcript agentv eval evals/my-eval.yaml --transcript .agentv/transcripts/claude-.jsonl diff --git a/apps/web/src/content/docs/docs/guides/agent-skills-evals.mdx b/apps/web/src/content/docs/docs/guides/agent-skills-evals.mdx index f5a1d1ac1..04bebd443 100644 --- a/apps/web/src/content/docs/docs/guides/agent-skills-evals.mdx +++ b/apps/web/src/content/docs/docs/guides/agent-skills-evals.mdx @@ -85,7 +85,8 @@ Grade existing agent sessions offline using `agentv import` to convert transcrip ```bash # Import a Claude Code session transcript -agentv import claude --discover latest +agentv import claude --list +agentv import claude --session-id # Run deterministic evaluators against the imported transcript agentv eval evals.json --target copilot-log diff --git a/apps/web/src/content/docs/docs/guides/skill-improvement-workflow.mdx b/apps/web/src/content/docs/docs/guides/skill-improvement-workflow.mdx index 40db69514..42496afbe 100644 --- a/apps/web/src/content/docs/docs/guides/skill-improvement-workflow.mdx +++ b/apps/web/src/content/docs/docs/guides/skill-improvement-workflow.mdx @@ -123,7 +123,8 @@ Or grade existing sessions offline (no API keys required): ```bash # Import a Claude Code session transcript -agentv import claude --discover latest +agentv import claude --list +agentv import claude --session-id # Run deterministic evaluators against the imported transcript agentv eval evals.json --target copilot-log diff --git a/apps/web/src/content/docs/docs/tools/import.mdx b/apps/web/src/content/docs/docs/tools/import.mdx index bc5029fca..2521a6d26 100644 --- a/apps/web/src/content/docs/docs/tools/import.mdx +++ b/apps/web/src/content/docs/docs/tools/import.mdx @@ -12,14 +12,14 @@ The `import` command converts agent session transcripts into AgentV's `Message[] | Provider | Command | Source | |----------|---------|--------| | Claude Code | `agentv import claude` | `~/.claude/projects//.jsonl` | - -Codex and Copilot importers are planned for future releases. +| Codex CLI | `agentv import codex` | `~/.codex/sessions///
/rollout-*.jsonl` | +| Copilot CLI | `agentv import copilot` | `~/.copilot/session-state//events.jsonl` | ## `import claude` Import a Claude Code session transcript. -### Discover available sessions +### List available sessions ```bash agentv import claude --list @@ -35,12 +35,6 @@ Found 5 session(s): ed8b8c62-4414-49fb-8739-006d809c8588 3h ago -home-user-other-project ``` -### Import latest session - -```bash -agentv import claude --discover latest -``` - ### Import a specific session ```bash @@ -50,27 +44,68 @@ agentv import claude --session-id 4c4f9e4e-e6f1-490b-a1b1-9aef543ebf22 ### Filter by project path ```bash -agentv import claude --discover latest --project-path /home/user/myproject +agentv import claude --list --project-path /home/user/myproject ``` ### Custom output path ```bash -agentv import claude --discover latest -o transcripts/my-session.jsonl +agentv import claude --session-id -o transcripts/my-session.jsonl ``` Default output: `.agentv/transcripts/claude-.jsonl` +## `import codex` + +Import a Codex CLI session transcript. + +### List available sessions + +```bash +agentv import codex --list +``` + +### Import a specific session + +```bash +agentv import codex --session-id 019d5cff-9f02-7bc3-8f98-2071ba17ef0e +``` + +## `import copilot` + +Import a Copilot CLI session transcript. + +### List available sessions + +```bash +agentv import copilot --list +``` + +### Import a specific session + +```bash +agentv import copilot --session-id 9ca6d90c-1d80-40d1-b805-c59ee31fc007 +``` + ## Options +All three providers share the same core flags: + | Flag | Description | |------|-------------| | `--session-id ` | Import a specific session by UUID | -| `--discover latest` | Import the most recent session | -| `--project-path ` | Filter sessions by project path | -| `--output, -o ` | Custom output file path | -| `--projects-dir ` | Override `~/.claude/projects` directory | | `--list` | List available sessions instead of importing | +| `--output, -o ` | Custom output file path | + +Provider-specific flags: + +| Flag | Provider | Description | +|------|----------|-------------| +| `--project-path ` | Claude | Filter sessions by project path | +| `--projects-dir ` | Claude | Override `~/.claude/projects` directory | +| `--date ` | Codex | Filter sessions by date | +| `--sessions-dir ` | Codex | Override `~/.codex/sessions` directory | +| `--session-state-dir ` | Copilot | Override `~/.copilot/session-state` directory | ## Output Format @@ -101,10 +136,13 @@ Token usage is aggregated from the final cumulative value per LLM request. Durat Import a session, then run evaluators against it: ```bash -# 1. Import the latest Claude Code session -agentv import claude --discover latest +# 1. List sessions and pick one +agentv import claude --list + +# 2. Import a session by ID +agentv import claude --session-id 4c4f9e4e-e6f1-490b-a1b1-9aef543ebf22 -# 2. Run evaluators against the imported transcript +# 3. Run evaluators against the imported transcript agentv eval evals/my-eval.yaml --transcript .agentv/transcripts/claude-4c4f9e4e.jsonl ``` diff --git a/examples/features/import-claude/README.md b/examples/features/import-claude/README.md index ed4dba683..11bbca308 100644 --- a/examples/features/import-claude/README.md +++ b/examples/features/import-claude/README.md @@ -18,12 +18,6 @@ claude -p "List all TypeScript files in this project" ### 2. Import the session transcript -```bash -agentv import claude --discover latest -o transcripts/session.jsonl -``` - -Or import a specific session: - ```bash # List available sessions agentv import claude --list diff --git a/plugins/agentv-dev/skills/agentv-eval-writer/SKILL.md b/plugins/agentv-dev/skills/agentv-eval-writer/SKILL.md index 86d724022..4ee55f41a 100644 --- a/plugins/agentv-dev/skills/agentv-eval-writer/SKILL.md +++ b/plugins/agentv-dev/skills/agentv-eval-writer/SKILL.md @@ -539,7 +539,7 @@ agentv eval --otel-file traces/eval.otlp.json agentv eval assert --agent-output "..." --agent-input "..." # Import agent transcripts for offline grading -agentv import claude --discover latest +agentv import claude --session-id # Re-run only execution errors from a previous run agentv eval --retry-errors .agentv/results/runs//index.jsonl