Skip to content
Open
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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased
- Added the OMP (`omp`) harness to agent-manager, CLI start, Tmux runtimes, and the Rust daemon; profile aliases are represented as repeatable structured `--arg` values rather than shell-evaluated aliases.

- [3f90d45](https://github.com/codeaholicguy/ai-devkit/commit/3f90d45) Added the built-in `dev-retro` skill: an evidence-based retrospective that turns friction into durable fixes, automation first. `dev-lifecycle` and `dev-debug` offer it and run it only if the user agrees.
- [fdbfb3a](https://github.com/codeaholicguy/ai-devkit/commit/fdbfb3a) Wired `dev-smoke` into other skills: `verify` requires it for "feature works" claims on user-facing changes, `dev-refactor` and `dev-simplify` compare runs before and after, `dev-debug` uses it as the repro, and `dev-lifecycle` runs it before code review.
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ ai-devkit agent send "review this branch for release risk" --group reviewers

# Pipe a session through Telegram — operate your agent from your phone
ai-devkit channel start telegram --agent <agent-name> --daemon
# Start an OMP profile with structured arguments (no shell alias evaluation)
ai-devkit agent start --type omp --arg --profile --arg work
```

Use this when work spans long-running agents, multiple providers, scheduled checks, review loops, or remote control from another channel.
Expand Down Expand Up @@ -213,6 +215,7 @@ One `.ai-devkit.json` configures all of them. Add a new agent to your team witho
| [Grok Build CLI](https://x.ai/cli) | yes | yes (`grok_cli`) |
| [opencode](https://opencode.ai/) | yes | yes (`opencode`) |
| [Pi](https://pi.dev) | yes | yes (`pi`) |
| [oh-my-pi](https://github.com/can1357/oh-my-pi) | yes | yes (`omp`) |
| [GitHub Copilot](https://github.com/features/copilot) | yes | yes (`copilot`) |
| [Kiro CLI](https://kiro.dev/cli/) | yes | yes (`kiro`) |
| [Devin](https://devin.ai/) | yes | yes (`devin`) |
Expand Down
83 changes: 83 additions & 0 deletions docs/ai/design/feature-omp-adapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
---
phase: design
title: "OMP Agent Harness Support - Design"
feature: omp-adapter
description: Architecture for OMP process detection, session mapping, profile arguments, and daemon parity
---

# Design: OMP Agent Harness Support

## Architecture Overview

```mermaid
graph TD
CLI[agent start --type omp --arg ...] --> Runtime[local or devkitd runtime]
Runtime --> Tmux[Tmux command: omp --profile name]
AgentManager --> OmpAdapter[OmpAdapter]
Devkitd --> RustOmp[Rust OMP adapter]
OmpAdapter --> Sessions[~/.omp/agent/sessions/**/*.jsonl]
RustOmp --> Sessions
Sessions --> SharedParser[Pi-compatible JSONL parser]
SharedParser --> AgentInfo
```

OMP uses the Pi-compatible JSONL message envelope but has an independent storage root and project-directory encoding. The adapter reuses the existing parser/matching primitives where their contracts fit, while keeping `type: "omp"` and OMP paths explicit.

## Data Model

- Add `"omp"` to `AGENT_TYPES` and `AgentType`.
- OMP session root: `~/.omp/agent/sessions` by default.
- OMP project bucket: the observed form is `-<cwd relative to $HOME, separators replaced by ->` (for example with `$HOME=/home/me`, `/home/me/repo` → `-repo`). Matching compares encoded live CWD values; it does not lossy-decode bucket names.
- `AgentInfo.type` is `"omp"`; `sessionFilePath` points to the JSONL file; `sessionId`, project path, summary, status, and timestamps follow the shared Pi-compatible record semantics.

## TypeScript Components

- `OmpAdapter`: precise OMP process matching, live session matching, process-only fallback, historical listing, and conversation access.
- Reuse `PiSessionLocator` with injected OMP root/encoder and reuse the Pi parser; this avoids duplicating schema and incremental-scan logic while keeping OMP paths explicit.
- `runtimeProfiles.ts`: add the OMP command, runtime kind, discovery aliases, and Bun/CLI matcher.
- `ManagedAgentRuntime`: pass structured args to the runtime and compose a quoted Tmux command.
- CLI: add repeatable `--arg <value>` and forward it through daemon and local paths.

## Rust Components

- `devkit-harness::omp`: mirror process matching, session root, locator, parser mapping, and process-only fallback.
- Register OMP in `default_registry`.
- Add an OMP `StartProfile` with a matcher that recognizes the OMP Bun CLI path.
- `devkitd` Tmux runtime composes profile command plus validated argv arguments using the same deterministic shell quoting contract as TypeScript.

## Profile Launch Contract

An alias such as:

```bash
alias omp-work='omp --profile work'
```

is represented as:

```text
--type omp --arg --profile --arg work
```

AI DevKit MUST NOT invoke `bash -ic` or evaluate alias text. This avoids dependence on interactive shell startup files and avoids arbitrary shell injection through the vendor configuration.

## Matching Contract

- Accept the direct `omp` executable.
- Accept Bun commands whose argv contains the OMP CLI entry path and `omp`/`pi-coding-agent` package marker.
- Reject unrelated `bun`, `node`, and arbitrary scripts.
- Start-profile matching and discovery matching use the same OMP identity rule.

## Design Decisions

- OMP is a first-class built-in type, not a generic arbitrary-vendor registry.
- Structured arguments are additive and generic enough for OMP profiles; shell aliases are documentation-only conveniences.
- Durable mode is explicitly excluded until OMP print/resume semantics are verified.
- The Rust daemon mirrors the TypeScript adapter because daemon results suppress local adapter discovery when non-empty.

## Security and Performance

- Session files are read only below the configured/default OMP root.
- JSONL parsing skips malformed records and bounds head reads using existing utilities.
- Tmux arguments are quoted as argv values; no user-provided shell fragment is evaluated.
- Discovery remains bounded to OMP `*.jsonl` files and uses existing incremental summaries.
38 changes: 38 additions & 0 deletions docs/ai/implementation/feature-omp-adapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
phase: implementation
title: "OMP Agent Harness Support - Implementation"
feature: omp-adapter
description: Implementation notes, decisions, deviations, and verification evidence for OMP support
---

# Implementation: OMP Agent Harness Support

- Phase: Check Implementation
- Branch: `feature-omp-adapter`
- Worktree: `/tmp/ai-devkit-omp-worktree`
- Current task: align implementation records with the completed TypeScript/Rust changes and verification queue.

## Changed Files

- Agent-manager: OMP adapter, Pi locator parameterization, type/registry/runtime/readiness integration, Tmux argument quoting, Bun `/bin/omp` launcher detection, and focused tests.
- CLI: `agent start --arg`, TUI structured argument forwarding, labels, status/session/start tests.
- Rust: OMP adapter/registry/start profile, Bun `/bin/omp` launcher detection, and daemon Tmux argument quoting/tests.
- Project docs: README, CHANGELOG, and readiness fixtures.

## Decisions

- Structured OMP profile arguments replace shell alias execution.
- Rust `devkitd` support is required because non-empty daemon discovery is authoritative.

- OMP project buckets use the observed home-relative encoding; the default root is `~/.omp/agent/sessions`.
- Registry session paths are accepted only when they remain below the OMP sessions root.
- OMP durable mode remains out of scope; arbitrary shell aliases are never evaluated.

## Verification Evidence

- Preflight: `npx ai-devkit@latest lint` and `npx ai-devkit@latest lint --feature omp-adapter` passed.
- Setup/build: `npm ci`, `npm run build`, `npm run lint`, and TypeScript formatting passed; the local rustup toolchain lacked an applicable `rustfmt` component for the final Rust format check.
- Tests: full Nx test targets and `cargo test --workspace` passed after the launcher-shape fix.
- Smoke: installed OMP 18.12.6 launches as `bun .../bin/omp`; the cockpit now recognizes that real process shape.
- Cockpit smoke: daemon-backed `agent start --type omp` succeeded with a configured model, `agent list --json` reported `type: "omp"`, and `agent kill` stopped the OMP PID. `agent detail` is unavailable for a sessionless OMP process, and kill leaves the empty tmux shell until the daemon refreshes/cleanup path handles it.
- Initial baseline before the build had one Pi live-discovery failure; the final full suite passed after the launcher-shape fix.
54 changes: 54 additions & 0 deletions docs/ai/planning/feature-omp-adapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
phase: planning
title: "OMP Agent Harness Support - Plan"
feature: omp-adapter
description: Ordered implementation plan for OMP support
---

# Plan: OMP Agent Harness Support

## Milestones

- [x] M1: OMP requirements/design and red tests established.
- [x] M2: TypeScript and Rust OMP discovery implemented.
- [x] M3: Structured profile arguments work through CLI, local Tmux, and devkitd.
- [x] M4: Verification complete and upstream pull request opened.

## Task Breakdown

### Foundation

- [x] Add failing TypeScript tests for type registration, process matching, session mapping, and start arguments.
- [x] Add failing Rust tests for registry/start-profile parity.

### Core Features

- [x] Add TypeScript OMP adapter and exports/registration.
- [x] Add OMP runtime profile and labels/type filters.
- [x] Implement structured `--arg` propagation and deterministic Tmux quoting.
- [x] Add Rust OMP adapter, registry registration, and start profile.

### Integration and Polish

- [x] Update tests for CLI, console action forwarding, daemon wire arguments, and Rust runtime behavior.
- [x] Update README/CHANGELOG and implementation/testing records.
- [x] Run targeted tests, environment smoke tests, full relevant checks, review, commit, push, and open PR.

## Dependencies

- OMP executable is installed for environment smoke testing; CI uses fixtures.
- Rust daemon must be rebuilt before daemon smoke testing.
- Existing Pi parser behavior must remain green.

## Risks and Mitigations

- Bun command ambiguity: require OMP CLI path/package marker, not basename `bun` alone.
- Alias availability: model aliases as executable plus argv, never shell-evaluate aliases.
- TS/Rust drift: add matching fixtures and parity assertions in both test suites.
- Existing flaky Pi live-discovery test: record separately; do not widen OMP scope to fix it.

- Queue update 2: production implementation and focused regression fixes complete; broad verification and PR remain.
- Current queue: Foundation `done`; Core Features `done`; Integration `in-progress`.
- Baseline: preflight lint/build passed; baseline full tests had one existing Pi live-discovery failure.
- Queue update 3: targeted/full verification, formatting, lint, and OMP smoke checks complete; commit and PR submission are the remaining actions.
- Queue update 4: commit `f95df21` pushed; PR #422 opened against `codeaholicguy/ai-devkit:main`.
53 changes: 53 additions & 0 deletions docs/ai/requirements/feature-omp-adapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
phase: requirements
title: "OMP Agent Harness Support - Requirements"
feature: omp-adapter
description: Requirements for managing oh-my-pi (OMP) sessions and structured profile launches in AI DevKit
---

# Requirements: OMP Agent Harness Support

## Problem Statement

AI DevKit can manage Pi-compatible agents, but oh-my-pi (OMP) is a separate executable with a different session root and Bun-launched process shape. OMP profile aliases such as `omp-work='omp --profile work'` are also not reliable launch identities inside non-interactive Tmux or daemon shells.

## Goals

- Detect and manage OMP interactive processes through the same agent-manager surface as other harnesses.
- Discover OMP JSONL sessions from the default `~/.omp/agent/sessions` tree.
- Support profile launches as structured executable arguments, without evaluating shell aliases.
- Keep TypeScript local discovery and Rust `devkitd` discovery behavior aligned.
- Preserve existing Pi behavior and public APIs except for additive OMP/type support.

## Non-goals

- Executing arbitrary shell aliases or shell command strings.
- OMP durable/print-mode support in this change.
- OMP protocol changes or modifying the OMP package.
- A general third-party vendor plugin registry.

## User Stories

- As a user, I can list running OMP sessions with `agent list`.
- As a user, I can inspect OMP conversation history and historical sessions.
- As a user, I can send a prompt, wait for completion, focus, and stop an OMP agent.
- As a user, I can start a profile using `agent start --type omp --arg --profile --arg work` or the console's structured arguments field.
- As a user, OMP agents remain visible when `devkitd` is authoritative.

## Acceptance Criteria

1. `AgentType` and all exhaustive built-in type tables include `omp`.
2. OMP matching accepts the OMP CLI/Bun process shape and rejects unrelated Bun/Node processes.
3. OMP sessions are read only below the resolved OMP sessions root; malformed records do not fail discovery.
4. OMP summaries, status, conversation detail, and historical listing work for the installed session format.
5. Local and daemon discovery produce the same OMP agent type and session mapping.
6. Structured arguments reach both local Tmux and daemon Tmux launches without shell alias evaluation.
7. Tests cover positive/negative process matching, session mapping, argument propagation, and Rust/TypeScript parity.
8. Existing supported harness behavior remains unchanged.

## Constraints and Risks

- OMP is Bun-launched, so matching must identify the OMP CLI path rather than every Bun process.
- OMP's default storage root is `~/.omp/agent`; `PI_CODING_AGENT_DIR` may override it. This change supports the default root and documents the environment-root limitation if the existing adapter contract cannot safely inject it.
- Tmux receives a shell command string; arguments must be quoted deterministically.
- The daemon's authoritative result means Rust support is required, not optional.
48 changes: 48 additions & 0 deletions docs/ai/testing/feature-omp-adapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
phase: testing
title: "OMP Agent Harness Support - Testing"
feature: omp-adapter
description: Test strategy and evidence for OMP detection, sessions, profile args, and daemon parity
---

# Testing: OMP Agent Harness Support

## Coverage Goals

- Cover all new OMP branches that affect process ownership, path safety, session mapping, and status.
- Cover structured arguments from CLI/console to both local and daemon Tmux runtimes.
- Keep TypeScript and Rust process matching behavior equivalent.
- Use fixtures for CI; use the installed OMP binary only for no-model smoke checks.

## Unit Tests

- [x] `omp` is present in exhaustive agent type lists, labels, adapters, and session filters.
- [x] OMP matcher accepts direct CLI, Bun-launched `dist/cli.js`, and the installed Bun `/bin/omp` shim.
- [x] OMP matcher rejects unrelated Bun/Node processes and paths containing only incidental `omp` text.
- [x] OMP session locator maps the observed project bucket and strict CWD.
- [x] OMP parser maps user/assistant messages, summaries, timestamps, and status through the Pi-compatible parser.
- [x] OMP adapter returns process-only agents when sessions are unavailable.
- [x] Tmux command quoting preserves each structured argument.
- [x] Rust registry/start profile agrees with TypeScript OMP identity rules.

## Integration and E2E

- [x] Agent-manager focused/package tests pass.
- [x] CLI focused/package tests pass, including daemon and local start argument forwarding.
- [x] Rust workspace and daemon tests pass.
- [x] Isolated HOME smoke lists a fixture OMP session.
- [x] Installed `omp --version`/`omp --help` smoke confirms the environment's executable and profile flag without invoking a model.
- [x] Live cockpit smoke starts a model-configured OMP in tmux, discovers it as `type: "omp"`, and stops its process through `agent kill`.

## Known Baseline

- Sessionless OMP processes are intentionally process-only; `agent detail` requires an OMP JSONL session file.
- Daemon-backed `agent kill` terminates the OMP PID, but the managed tmux shell remains until explicit cleanup. This is runtime lifecycle behavior shared by the daemon start path, not OMP process detection.
- After building workspace packages, the baseline test suite had one existing failure in `PiDiscoveryIO.test.ts` where a newly added Pi session was not rechecked. This is tracked separately from OMP work.

- Focused TypeScript: agent-manager OMP/readiness/runtime/Tmux tests and CLI command/status/TUI/session tests passed.
- Full Nx test run: all 8 project test targets passed after the installed-launcher matcher fix; agent-manager reported 93 files/1380 tests and CLI reported 111 files/1350 tests.
- Rust: `cargo test --workspace` passed after the installed-launcher matcher fix; the repository's `cargo fmt` check was unavailable because the local rustup toolchain lacks an applicable `rustfmt` component.
- Smoke: built CLI `agent list --json` returned an OMP entry; installed `omp/18.12.6` exposes `--profile`; managed cockpit start/list/kill passed for a configured OMP process.

## Evidence Log
33 changes: 33 additions & 0 deletions fixtures/readiness/degraded.json
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,39 @@
]
},
"status": "fail"
},
"omp": {
"type": "omp",
"executable": {
"command": "omp",
"path": null,
"status": "fail",
"errors": [
"omp was not found on PATH"
]
},
"globalConfig": {
"path": "~/.omp",
"present": false,
"readable": false,
"status": "fail",
"errors": [
"global configuration directory is unavailable"
]
},
"builtInSkills": {
"path": null,
"required": 3,
"present": 0,
"missing": [
"agent-management",
"memory",
"verify"
],
"status": "info",
"errors": []
},
"status": "fail"
}
}
}
33 changes: 33 additions & 0 deletions fixtures/readiness/healthy.json
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,39 @@
"errors": []
},
"status": "pass"
},
"omp": {
"type": "omp",
"executable": {
"command": "omp",
"path": null,
"status": "fail",
"errors": [
"omp was not found on PATH"
]
},
"globalConfig": {
"path": "~/.omp",
"present": false,
"readable": false,
"status": "fail",
"errors": [
"global configuration directory is unavailable"
]
},
"builtInSkills": {
"path": null,
"required": 3,
"present": 0,
"missing": [
"agent-management",
"memory",
"verify"
],
"status": "info",
"errors": []
},
"status": "fail"
}
}
}
Loading