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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ One `.ai-devkit.json` configures all of them. Add a new agent to your team witho
| [Gemini CLI](https://github.com/google-gemini/gemini-cli) | yes | yes |
| [Codex CLI](https://github.com/openai/codex) | yes | yes |
| [opencode](https://opencode.ai/) | yes | testing |
| Pi | — | yes |
| [Cursor](https://cursor.sh/) | yes | — |
| [GitHub Copilot](https://code.visualstudio.com/) | yes | — |
| [Antigravity](https://antigravity.google/) | yes | — |
Expand Down
103 changes: 103 additions & 0 deletions docs/ai/design/2026-06-10-feature-pi-adapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
---
phase: design
title: "Pi Adapter in @ai-devkit/agent-manager - Design"
feature: pi-adapter
description: Design for Pi process detection, tracker matching, fallback session matching, and session parsing
---

# Design: Pi Adapter in @ai-devkit/agent-manager

## Architecture Overview

```mermaid
graph TD
AgentManager --> PiAdapter
PiAdapter --> ProcessUtils[listAgentProcesses + enrichProcesses]
PiAdapter --> Registry[AgentRegistry cache]
PiAdapter --> Tracker[~/.pi/agent/sessions.json]
PiAdapter --> Sessions[~/.pi/agent/sessions/**/*.jsonl]
PiAdapter --> Matching[matchProcessesToSessions fallback]
Sessions --> Parser[Pi JSONL parser]
Parser --> AgentInfo
Parser --> ConversationMessage
Parser --> SessionSummary
```

`PiAdapter` follows the existing adapter shape:
- Discover candidate Pi processes.
- Return registry-cached session matches when valid.
- Prefer tracker-based PID matching for remaining processes.
- Discover session files and apply shared legacy matching for anything not matched by tracker data.
- Map parsed sessions into `AgentInfo`.
- Fall back to process-only agents when session parsing is unavailable.

## Data Models

### Agent Type

`AgentType` adds:

```ts
'pi'
```

### Tracker Metadata

The tracker schema is a plain PID-to-session-path map:

```json
{
"12345": "/Users/me/.pi/agent/sessions/project/session.jsonl"
}
```

The adapter only trusts entries whose PID matches a live process and whose path exists under the Pi sessions directory.

### Pi Session

Pi JSONL is parsed permissively. Entries may expose timestamps, roles, content, cwd/project path, session id, and event type under common top-level or nested fields. The adapter derives:
- `sessionId`: explicit id when available, otherwise filename UUID/timestamp fallback.
- `projectPath`: explicit cwd/project path when available, otherwise process cwd for running agents. For fallback matching, encoded Pi project directory names are compared against live process CWDs instead of decoded, because path segments may contain hyphens.
- `summary`: latest user message.
- `sessionStart`: earliest timestamp or file birthtime/mtime.
- `lastActive`: latest timestamp or file mtime.

## API Design

- Public adapter contract remains `AgentAdapter`.
- CLI and channel agent-manager wiring register `new PiAdapter()` with the existing adapters.
- Package exports expose `PiAdapter`.
- No external network APIs or authentication are introduced.

## Component Breakdown

### `PiAdapter`
- `canHandle(processInfo)`: identifies Pi executable/script tokens.
- `detectAgents()`: combines registry cache, tracker matching, fallback matching, and process-only fallback.
- `getConversation(sessionFilePath)`: reads JSONL and normalizes message entries.
- `listSessions(opts)`: enumerates historical Pi session files and applies optional strict `cwd`.

### Tracker Matching
- Reads `~/.pi/agent/sessions.json` with `safeReadFile`.
- Extracts numeric object keys whose values are string session paths.
- Validates the session path exists and is inside `~/.pi/agent/sessions`.
- Parses the matched session directly.

### Fallback Matching
- Recursively discovers `*.jsonl` session files under `~/.pi/agent/sessions`.
- Uses shared `matchProcessesToSessions()` with session birth/mtime and resolved CWD when available.

## Design Decisions

- Use exact tracker matching first because PID metadata is more reliable than file timestamp heuristics.
- Keep legacy fallback because tracker installation is optional.
- Parse Pi JSONL permissively because the adapter should tolerate minor schema drift.
- Do not add a shared tracker abstraction yet; Pi is the first adapter with this specific extension file.
- Validate tracker paths under the Pi sessions directory to avoid arbitrary file reads from compromised metadata.

## Non-Functional Requirements

- Detection must avoid throwing on malformed JSON, missing directories, or unreadable files.
- Recursive session discovery should be bounded to `.jsonl` files under the Pi sessions root.
- Tracker path validation must prevent escaping the Pi sessions root.
- Existing adapter behavior and exports must remain source-compatible.
93 changes: 93 additions & 0 deletions docs/ai/implementation/2026-06-10-feature-pi-adapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
---
phase: implementation
title: "Pi Adapter Implementation Notes"
feature: pi-adapter
description: Implementation details and verification evidence for Pi adapter support
---

# Implementation: Pi Adapter

## Development Setup

- Feature worktree: `.worktrees/feature-pi-adapter`
- Branch: `feature-pi-adapter`
- Dependency bootstrap: `npm ci` completed; Husky prepare could not write `.git/config` in the sandbox, but npm exited 0.

## Code Structure

- `packages/agent-manager/src/adapters/PiAdapter.ts`: Pi process detection, tracker matching, fallback matching, JSONL parsing, conversations, and historical session listing.
- `packages/agent-manager/src/adapters/AgentAdapter.ts`: `AgentType` now includes `pi`.
- `packages/agent-manager/src/index.ts` and `packages/agent-manager/src/adapters/index.ts`: export `PiAdapter`.
- `packages/cli/src/commands/agent.ts`: registers `PiAdapter` and labels `pi` as `Pi`.
- `packages/cli/src/services/channel/channel-runner.ts`: registers `PiAdapter` for channel bridge agent resolution.
- `packages/cli/src/util/sessions.ts`: accepts `--type pi`.

## Implementation Notes

### Core Features
- Exact matching: reads `~/.pi/agent/sessions.json` as a plain PID-to-session-path map.
- Path safety: tracker paths are used only when they resolve inside `~/.pi/agent/sessions`.
- Fallback matching: recursively discovers Pi `.jsonl` files and reuses `matchProcessesToSessions()`.
- Encoded project directories: fallback matching builds Pi's encoded directory form from each live process CWD, then compares that value to session parent directory names. It does not decode directory names because real path segments can contain hyphens.
- Parsing: JSONL lines are parsed permissively; malformed lines are skipped.
- Summaries: latest user message becomes the `AgentInfo.summary`; process-only fallback uses `Pi process running`.
- Detail parsing: Pi `type: "message"` records are parsed from nested `message.role` and `message.content` fields, including text-part arrays like `[{ type: "text", text: "hello" }]`.
- Simplification pass: detection is split into tracker and fallback mapping stages; JSONL entries are parsed once for session summaries; message parsing now uses explicit nested-message helpers instead of treating every `type` value as a possible role.

### Patterns & Best Practices
- Matches existing adapter structure: process discovery, registry cache, direct matching, fallback matching, process-only fallback.
- Uses shared utilities for safe file reads/stats and agent naming.
- Keeps tracker support local to Pi instead of introducing a premature shared abstraction.

## Integration Points

- Optional extension: `@ai-devkit/pi-session-tracker` writes `~/.pi/agent/sessions.json`.
- CLI: `ai-devkit agent sessions --type pi` and session detail filtering now validate `pi`.
- Channel bridge: Pi agents can be resolved by the shared `AgentManager` used by channel runner.

## Error Handling

- Missing or malformed `sessions.json` returns an empty tracker map and continues to fallback matching.
- Trusted tracker entries whose session files cannot be parsed re-enter fallback matching before returning process-only agents.
- Missing session root returns process-only agents for running Pi processes.
- Bad JSONL lines are ignored.
- Unparseable sessions that remain unmatched after fallback return process-only agents.

## Performance Considerations

- Tracker matching avoids session scans for exact PID matches.
- Recursive discovery is limited to `.jsonl` files under the Pi sessions root.
- No network calls or external process calls are added.

## Security Notes

- Tracker paths are constrained to the Pi sessions root before reading.
- Session parsing treats all file contents as untrusted and skips malformed records.
- No secrets are read or emitted.

## Verification Evidence

- Red step: `npx nx test agent-manager --runInBand --testPathPattern=PiAdapter.test.ts` failed with missing `PiAdapter.js`.
- Focused adapter: `npx vitest run src/__tests__/adapters/PiAdapter.test.ts` exited 0 with 9 tests passed.
- Package tests: `npx nx run agent-manager:test` exited 0 with 14 files and 394 tests passed.
- Builds: `npx nx run agent-manager:build` and `npx nx run channel-connector:build` exited 0.
- Focused CLI: `npx vitest run src/__tests__/util/sessions.test.ts src/__tests__/commands/agent.test.ts src/__tests__/commands/channel.test.ts` exited 0 with 3 files and 87 tests passed.
- CLI package: `npx nx run cli:test` exited 0 with 54 files and 697 tests passed.
- CLI build: `npx nx run cli:build` exited 0 and built `cli` plus dependent packages.
- Detail regression: `npm run dev -- agent detail --id ai-devkit-25877 --json` exited 0 and returned two Pi conversation messages after rebuilding `agent-manager`.
- Simplification verification: `npx vitest run src/__tests__/adapters/PiAdapter.test.ts`, `npx nx run agent-manager:test`, `npx nx run cli:test`, `npx nx run cli:build`, and live `agent detail --id ai-devkit-25877 --json` all exited 0 after the refactor.

## Phase 6 Implementation Check

- Alignment: implementation matches the requirements and design for `pi` type support, tracker-first matching, legacy fallback, package exports, CLI/channel registration, conversation parsing, and historical sessions.
- Design clarification applied: fallback CWD matching uses encoded Pi project directory names generated from live process CWDs, avoiding lossy decoding of hyphenated path segments.
- No blocking implementation deviations found.
- Remaining validation gap: no live Pi process with `@ai-devkit/pi-session-tracker` was available for manual end-to-end verification.
- Update (2026-06-10): live Pi detail was verified for `ai-devkit-25877` after adding nested Pi message parsing.

## Phase 8 Code Review

- Finding fixed: a trusted tracker entry with an unparseable session file previously returned a process-only agent without attempting legacy matching. `PiAdapter` now sends that process through fallback matching before returning process-only.
- Scope cleanup: README changes are limited to adding Pi support; unrelated Copilot support-table changes were removed.
- Holistic review outcome: no remaining blocking issues found across adapter exports, `AgentType`, CLI registration, session type validation, channel runner registration, docs, and tests.
- Final verification: `npx vitest run src/__tests__/adapters/PiAdapter.test.ts`, `npm run test:coverage --workspace packages/agent-manager`, `npx nx run agent-manager:test`, `npx nx run cli:test`, `npx nx run cli:build`, and `npx ai-devkit@latest lint --feature pi-adapter` all exited 0 after the Phase 8 fix.
61 changes: 61 additions & 0 deletions docs/ai/planning/2026-06-10-feature-pi-adapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
phase: planning
title: "Pi Adapter Implementation Plan"
feature: pi-adapter
description: Task breakdown for implementing and validating Pi adapter support
---

# Planning: Pi Adapter

## Milestones

- [x] Milestone 1: Requirements, design, testing, and planning docs are complete.
- [x] Milestone 2: Pi adapter behavior is covered by failing tests.
- [x] Milestone 3: Pi adapter implementation passes focused and package tests.

## Task Breakdown

### Phase 1: Docs and Setup
- [x] Task 1.1: Initialize feature worktree and docs.
- [x] Task 1.2: Document requirements, design, testing strategy, and implementation plan.

### Phase 2: Red Tests
- [x] Task 2.1: Add Pi adapter tests for tracker matching and fallback matching.
- [x] Task 2.2: Add Pi parsing, conversation, listSessions, export, and registration tests.

### Phase 3: Implementation
- [x] Task 3.1: Add `pi` to `AgentType`.
- [x] Task 3.2: Implement `PiAdapter`.
- [x] Task 3.3: Export `PiAdapter` and register it in CLI/channel agent-manager wiring.
- [x] Task 3.4: Update README support matrix if present.

### Phase 4: Verification
- [x] Task 4.1: Run focused Pi adapter tests.
- [x] Task 4.2: Run `npx nx run agent-manager:test`.
- [x] Task 4.3: Update implementation/testing docs with evidence.

## Dependencies

- Existing shared utilities: `process`, `session`, `matching`, `AgentRegistry`.
- Optional external extension: `@ai-devkit/pi-session-tracker`; adapter must work without it.
- User-confirmed type string: `pi`.

## Timeline & Estimates

- Docs/setup: small.
- Tests: medium, because process and filesystem setup must mirror existing adapter patterns.
- Implementation: medium, due defensive tracker/schema parsing.
- Verification: small to medium, depending on suite runtime.

## Risks & Mitigation

- Risk: Tracker metadata is malformed or points at a stale file. Mitigation: accept only the documented PID-to-session-path map and fall back safely when entries are unusable.
- Risk: Pi JSONL schema differs from parser assumptions. Mitigation: parse common message fields permissively and never throw on unknown lines.
- Risk: Process command detection is too broad. Mitigation: match executable/script path tokens rather than arbitrary prose when possible.
- Risk: Real Pi is unavailable for manual verification. Mitigation: automated tests cover filesystem/process behavior; call out manual gap.

## Resources Needed

- Local test filesystem via temporary HOME.
- Vitest mocking for process utilities.
- Existing adapter tests as implementation examples.
80 changes: 80 additions & 0 deletions docs/ai/requirements/2026-06-10-feature-pi-adapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
phase: requirements
title: "Pi Adapter in @ai-devkit/agent-manager - Requirements"
feature: pi-adapter
description: Add a Pi adapter that detects running Pi sessions from local session files and tracker metadata
---

# Requirements: Add Pi Adapter to @ai-devkit/agent-manager

## Problem Statement

`@ai-devkit/agent-manager` supports multiple local AI agents through adapters, but Pi sessions are not surfaced by `agent list`, `agent detail`, or related flows. Pi persists local sessions under `~/.pi/agent/sessions`, and the companion extension `@ai-devkit/pi-session-tracker` can write `~/.pi/agent/sessions.json` to map running PIDs to exact session files.

Who is affected:
- Users running Pi who expect active sessions to appear alongside Claude, Codex, Gemini CLI, OpenCode, and Copilot.
- Maintainers adding adapter support who need Pi to follow existing agent-manager patterns.
- Users without the tracker extension, who still need a best-effort fallback instead of an empty result.

## Goals & Objectives

### Primary Goals
- Add `pi` as a first-class `AgentType`.
- Implement `PiAdapter` in `packages/agent-manager`.
- Detect running Pi processes and map them to session files.
- Prefer exact PID-to-session matching from `~/.pi/agent/sessions.json`.
- Fall back to legacy process/session matching when `sessions.json` is missing or unusable.
- Export and register the adapter so existing manager flows include Pi.

### Secondary Goals
- Reuse shared process, session, matching, and registry utilities.
- Parse Pi JSONL sessions enough to expose summary, timestamps, project path, conversation messages, and historical session summaries.
- Cover tracker matching, fallback matching, malformed data, and conversation extraction with unit tests.

### Non-Goals
- Implementing or installing `@ai-devkit/pi-session-tracker`.
- Changing Pi's session file format.
- Redesigning the agent list/detail/open UX.
- Removing existing legacy matching behavior for other adapters.

## User Stories & Use Cases

1. As a Pi user with `@ai-devkit/pi-session-tracker` installed, I want active Pi sessions to be matched by PID so the correct session is shown even when timestamp heuristics are ambiguous.
2. As a Pi user without the tracker file, I want `agent list` to fall back to existing matching heuristics so Pi still appears when session timing and CWD are enough.
3. As a user inspecting an agent, I want Pi conversation messages to be readable from the stored JSONL session.
4. As a maintainer, I want Pi support to reuse the adapter contract and exports used by the other adapters.

## Success Criteria

- `AgentType` includes `pi`.
- `PiAdapter` exists and implements `AgentAdapter`.
- `PiAdapter` is exported from adapter and package entry points.
- CLI and channel agent-manager wiring register `PiAdapter` with the existing adapters.
- When `~/.pi/agent/sessions.json` maps a running PID to a session path, `detectAgents()` returns the mapped session.
- When `sessions.json` is absent, `detectAgents()` uses session discovery plus shared legacy matching.
- Invalid or missing tracker/session files do not break other detection paths.
- `getConversation()` returns user and assistant messages from Pi JSONL entries.
- `listSessions()` returns historical Pi sessions and honors strict `cwd` filtering.
- Focused adapter tests and package tests pass.

## Constraints & Assumptions

### Technical Constraints
- Follow existing TypeScript, Nx, Vitest, and adapter conventions.
- Keep JSON/table output shape compatible with existing `AgentInfo`.
- Do not require tracker installation for fallback support.
- Isolate file parsing failures so one bad Pi session does not abort detection.

### Assumptions
- Pi process commands can be identified by executable/script tokens containing `pi`.
- Pi sessions live below `~/.pi/agent/sessions`.
- Project-scoped Pi sessions may live in encoded project directories such as `--Users-hoangnguyen-Codeaholicguy-Code-ai-devkit--`.
- Session filenames can include an ISO-like timestamp and UUID, for example `2026-06-10T08-58-20-754Z_019eb0c1-06d2-71ed-90ee-7acbf4b21c5b.jsonl`.
- `~/.pi/agent/sessions.json` is created by `@ai-devkit/pi-session-tracker` and maps PIDs directly to session file paths.
- `pi` is the public adapter type string.

## Questions & Open Items

- Resolved (2026-06-10): Public adapter type is `pi`.
- Resolved (2026-06-10): `sessions.json` is optional. Missing tracker metadata falls back to legacy matching.
- Resolved (2026-06-10): Tracker JSON schema is a plain PID-to-session-path map, for example `{ "12345": "/path/to/session.jsonl" }`.
Loading
Loading