Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 164 additions & 0 deletions docs/ai/design/feature-agent-detail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
---
phase: design
title: Agent Detail Command - System Design
description: Technical design for the agent detail CLI command
---

# System Design & Architecture

## Architecture Overview

The `agent detail` command follows the existing adapter pattern. It reuses `AgentManager` for agent discovery and resolution, then adds a conversation-reading layer.

```mermaid
graph TD
CLI["CLI: agent detail --id abc"]
AM["AgentManager"]
CCA["ClaudeCodeAdapter"]
CA["CodexAdapter"]
SR["Session Reader"]
SF["Session JSONL Files"]

CLI -->|resolve agent| AM
AM --> CCA
AM --> CA
CLI -->|read conversation| SR
SR -->|parse JSONL| SF
CCA -->|AgentInfo + sessionFilePath| CLI
CA -->|AgentInfo + sessionFilePath| CLI
```

**Key insight:** The existing adapters already read session files to extract status/summary. For `detail`, we need the full conversation, which requires a second pass that reads and parses all JSONL entries (not just the last few lines).

## Data Models

### AgentDetail (extends AgentInfo conceptually)

```typescript
interface AgentDetail {
sessionId: string;
cwd: string;
startTime: Date;
status: AgentStatus;
type: AgentType;
name: string;
slug?: string;
conversation: ConversationMessage[];
}

interface ConversationMessage {
role: 'user' | 'assistant' | 'system';
content: string;
timestamp?: string;
}
```

### Conversation parsing rules

**Claude Code JSONL:**
- Each line is `{ type, timestamp, message, ... }`
- `type: "user"` → role=user, extract text from `message.content`
- `type: "assistant"` → role=assistant, extract text from `message.content`
- `type: "system"` → role=system
- Skip metadata types: `file-history-snapshot`, `last-prompt`, `progress`, `thinking`
- **Default mode:** Extract only text blocks from `message.content` arrays
- **Verbose mode:** Also include tool_use blocks (name + input summary) and tool_result blocks

**Codex JSONL:**
- First line: `session_meta` → skip (metadata only)
- Subsequent lines have `type`, `timestamp`, and `payload` with `payload.message` (plain string) and `payload.type`
- Map `payload.type` to roles: `user_message` → user, `agent_message` → assistant, others → system
- Default mode: extract `payload.message` strings
- Verbose mode: include additional payload details if present

## API Design

### CLI Interface

```
ai-devkit agent detail --id <name> [--json] [--full] [--tail <n>] [--verbose]
```

**Options:**
- `--id <name>` (required): Agent name (as shown in `agent list` output)
- `--json` (optional): Output as JSON
- `--full` (optional): Show entire conversation history (default: last 20 messages)
- `--tail <n>` (optional): Show last N messages (default: 20)
- `--verbose` (optional): Include tool call/result details in messages

**Default output format (human-readable, text only, last 20 messages):**
```
Agent Detail
────────────────────────────────
Session ID: a6ce7023-6ac4-40b7-a8a5-dde50645bed5
CWD: ~/Code/ai-devkit
Start Time: 2026-03-27 10:30:00
Status: 🟢 run
Type: Claude Code

Conversation (last 20 messages)
────────────────────────────────
[10:30:05] user:
Fix the login bug in auth.ts

[10:30:12] assistant:
I'll look at the auth.ts file...
...
```

**Verbose mode adds tool details:**
```
[10:30:12] assistant:
I'll look at the auth.ts file...
[Tool: Read] auth.ts
[Tool: Edit] auth.ts (lines 15-20)
```

### Internal API

Add `getConversation()` as a **required** method on the `AgentAdapter` interface:

```typescript
interface AgentAdapter {
// existing...
getConversation(sessionFilePath: string, options?: { verbose?: boolean }): ConversationMessage[];
}
```

Each adapter implements its own parsing logic (Claude: structured content blocks, Codex: `payload.message` strings) but all return the same `ConversationMessage[]` output.

## Component Breakdown

1. **CLI command handler** (`packages/cli/src/commands/agent.ts`):
- New `detail` subcommand under the existing `agent` command
- Uses `AgentManager` to list + resolve agent
- Calls conversation reader
- Formats and displays output

2. **Conversation reader** (`packages/agent-manager/src/`):
- New method or utility to parse full conversation from JSONL
- Claude-specific parsing in `ClaudeCodeAdapter`
- Codex-specific parsing in `CodexAdapter`
- Returns `ConversationMessage[]`

3. **AgentInfo extension**:
- Add `sessionFilePath?: string` to `AgentInfo` — already known at detection time, avoids re-discovery

## Design Decisions

| Decision | Choice | Rationale |
|----------|--------|-----------|
| Where to add conversation parsing | Required method on `AgentAdapter` interface | Each adapter has its own JSONL format but unified output |
| How to pass session file path | Add to `AgentInfo` | Already known at detection, avoids re-discovery |
| Output format | Table header + message list | Consistent with `agent list` style |
| Message filtering | Skip progress/thinking/metadata | Show only meaningful conversation turns |
| Default message count | Last 20 | Practical default; `--full`/`--tail` for overrides |
| Tool display | Text-only default, `--verbose` for tools | Keeps output clean; tools are verbose |
| Identifier type | Name only | Consistent, simple; users copy from `agent list` |
| Non-running agents | Not supported | Scoped to running processes only |

## Non-Functional Requirements

- **Performance:** Session files can be large. Read the file once, parse line-by-line. No concern for very large files since we're already reading them in `readSession()`.
- **Reliability:** Graceful handling of corrupted JSONL lines (skip and continue).
- **Compatibility:** Works on macOS and Linux (same as existing commands).
50 changes: 50 additions & 0 deletions docs/ai/implementation/feature-agent-detail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
phase: implementation
title: Agent Detail Command - Implementation Guide
description: Technical implementation notes for the agent detail command
---

# Implementation Guide

## Development Setup

- Worktree: `.worktrees/feature-agent-detail`
- Branch: `feature-agent-detail`
- Dependencies: already bootstrapped via `npm ci`

## Code Structure

**Files to modify:**
- `packages/agent-manager/src/adapters/AgentAdapter.ts` — add `sessionFilePath` to `AgentInfo`, add `ConversationMessage` type
- `packages/agent-manager/src/adapters/ClaudeCodeAdapter.ts` — populate `sessionFilePath`, add `getConversation()`
- `packages/agent-manager/src/adapters/CodexAdapter.ts` — populate `sessionFilePath`, add `getConversation()`
- `packages/agent-manager/src/index.ts` — export new types
- `packages/cli/src/commands/agent.ts` — add `detail` subcommand

## Implementation Notes

### ConversationMessage type
```typescript
export interface ConversationMessage {
role: 'user' | 'assistant' | 'system';
content: string;
timestamp?: string;
}
```

### Claude conversation parsing
- Read file once, split by newlines
- For each line: parse JSON, check `type` field
- Include `user`, `assistant`, `system` types
- Skip `progress`, `thinking`, `file-history-snapshot`, `last-prompt`
- Extract text content using existing `extractUserMessageText` logic for user messages
- For assistant messages, concatenate text blocks from `message.content` array

### Codex conversation parsing
- Skip `session_meta` first line
- Map event types to roles based on Codex format

### CLI output formatting
- Use `ui.text()` for section headers
- Use chalk for coloring roles
- Truncate very long messages with `--full` flag (future consideration)
54 changes: 54 additions & 0 deletions docs/ai/planning/feature-agent-detail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
phase: planning
title: Agent Detail Command - Planning
description: Task breakdown and implementation plan for the agent detail command
---

# Project Planning & Task Breakdown

## Milestones

- [x] Milestone 1: Core infrastructure (AgentInfo extension + conversation reader)
- [x] Milestone 2: CLI command implementation
- [x] Milestone 3: Tests and polish

## Task Breakdown

### Phase 1: Core Infrastructure

- [x] Task 1.1: Add `sessionFilePath` field to `AgentInfo` interface in `AgentAdapter.ts`
- [x] Task 1.2: Populate `sessionFilePath` in `ClaudeCodeAdapter.mapSessionToAgent()` and `CodexAdapter`
- [x] Task 1.3: Add `ConversationMessage` type and `getConversation(filePath: string): ConversationMessage[]` method to `ClaudeCodeAdapter`
- [x] Task 1.4: Add `getConversation(filePath: string): ConversationMessage[]` method to `CodexAdapter`
- [x] Task 1.5: Export new types and methods from `@ai-devkit/agent-manager` package index

### Phase 2: CLI Command

- [x] Task 2.1: Add `agent detail` subcommand in `agent.ts` with `--id`, `--json`, `--full`, `--tail`, `--verbose` options
- [x] Task 2.2: Implement agent resolution logic (reuse `resolveAgent` by name + handle ambiguity)
- [x] Task 2.3: Implement human-readable output formatting (metadata header + tail-limited conversation, text-only default)
- [x] Task 2.4: Implement `--verbose` mode (include tool call/result details)
- [x] Task 2.5: Implement JSON output mode

### Phase 3: Testing & Polish

- [x] Task 3.1: Unit tests for `ClaudeCodeAdapter.getConversation()` — 11 tests
- [x] Task 3.2: Unit tests for `CodexAdapter.getConversation()` — 9 tests
- [ ] Task 3.3: Integration test for `agent detail` CLI command (deferred — requires running agents)
- [ ] Task 3.4: Manual testing with real running agents (deferred — requires running agents)

## Dependencies

- Task 1.1 must complete before Task 1.2
- Task 1.3/1.4 can run in parallel
- Task 1.5 depends on 1.1–1.4
- Phase 2 depends on Phase 1 completion
- Phase 3 depends on Phase 2 completion

## Risks & Mitigation

| Risk | Impact | Mitigation |
|------|--------|------------|
| Large session files slow down detail display | Medium | Stream/parse line by line (already done in readSession) |
| Codex JSONL format has undocumented fields | Low | Graceful fallback for unknown entry types |
| Adding field to AgentInfo breaks existing consumers | Low | Field is optional (`sessionFilePath?: string`) |
83 changes: 83 additions & 0 deletions docs/ai/requirements/feature-agent-detail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
---
phase: requirements
title: Agent Detail Command
description: CLI command to fetch detailed information about a running agent including session data and conversation history
---

# Requirements & Problem Understanding

## Problem Statement

Users of `ai-devkit` can list running agents via `agent list`, but there is no way to inspect the full details of a specific agent. When debugging, monitoring, or reviewing an agent's work, users need to see:

- The session ID and metadata (cwd, start time)
- Current status
- The full conversation history (all messages)

Currently, users must manually navigate to `~/.claude/projects/` or `~/.codex/sessions/`, find the correct JSONL file, and parse it themselves.

## Goals & Objectives

**Primary goals:**
- Provide a `ai-devkit agent detail --id <identifier>` command that displays comprehensive agent information
- Show session metadata: session ID, cwd, start time, current status
- Show the last N conversation messages by default, with `--full` to show all and `--tail <n>` to control count
- Show text content by default; `--verbose` to include tool call/result details

**Non-goals:**
- Editing or modifying session data
- Real-time streaming/tailing of the conversation
- Exporting conversation to external formats (PDF, HTML, etc.)
- Supporting terminated/non-running agents (only agents visible in `agent list`)

## User Stories & Use Cases

- **As a developer**, I want to run `ai-devkit agent detail --id "abc"` so that I can see what a specific agent has been doing, including its recent conversation.
- **As a team lead**, I want to inspect an agent's session details (start time, status, cwd) to understand its context and current state.
- **As a developer**, I want JSON output (`--json` flag) so I can pipe agent details into other tools for analysis.
- **As a developer**, I want `--verbose` to see tool call details when debugging what an agent actually executed.
- **As a developer**, I want `--full` or `--tail <n>` to control how much conversation history is shown.

**Key workflows:**
1. User runs `agent list` to see all running agents
2. User picks an agent name from the list
3. User runs `agent detail --id <name>` to see details + recent conversation
4. Output shows metadata header + last N conversation messages (text only by default)

**Edge cases:**
- Agent name matches multiple agents → show error with available matches
- Agent name matches no agent → show error with available agents
- Session file is missing or corrupted → graceful error message
- Agent is from Codex (not just Claude) → adapter-agnostic detail fetching

## Success Criteria

- `ai-devkit agent detail --id <name>` resolves the agent by name and displays:
- Session ID
- CWD (working directory)
- Start time
- Current status
- Last 20 conversation messages (text only) by default
- `--full` shows entire conversation history
- `--tail <n>` shows last N messages
- `--verbose` includes tool call/result details in messages
- `--json` flag outputs structured JSON
- Works for both Claude Code and Codex agents
- Only works for running agents (those visible in `agent list`)
- Handles ambiguous/missing names gracefully with helpful messages
- Uses existing `AgentManager.resolveAgent()` for name resolution

## Constraints & Assumptions

- Reuses the existing adapter architecture (`AgentManager`, `ClaudeCodeAdapter`, `CodexAdapter`)
- Session data is read from JSONL files already discovered during agent detection
- The conversation reader needs access to the session file path, which is available via the matched `SessionFile`
- Conversation parsing must handle both Claude and Codex JSONL formats
- Must not break existing `agent list`, `agent open`, or `agent send` commands

## Resolved Questions

- **Identifier type:** Accept agent name only (from `agent list` output), not session IDs or slugs
- **Conversation length:** Show last 20 messages by default; `--full` for all, `--tail <n>` for custom count
- **Tool use display:** Text-only by default; `--verbose` includes tool call/result details
- **Non-running agents:** Not supported — only agents with a running process (visible in `agent list`)
Loading
Loading