agent: add `pm agent serve` daemon for live session tracking
A headless daemon (stdlib threaded HTTP + SSE, ephemeral WAL SQLite) that
ingests best-effort hook events from Claude/Codex/Cursor and broadcasts live
session state to observers (the Emacs sidebar, curl).
- serve/{server,store,status,fallback}: HTTP+SSE server, WAL store, pure
status-derivation, and a Tier-2 transcript fallback poller. Status vocab:
working / waiting_response / waiting_permission / idle / unknown, with
openui-style activity-gating and a pid-liveness cleanup backstop.
- install-hooks: a shared stdlib reporter installed for Claude (settings.json),
Codex (a --profile pm config, since isaac regenerates ~/.codex/hooks.json),
and Cursor (~/.cursor/hooks.json, incl. shell/MCP approval). Skips the
Claude-hook double-report Cursor triggers.
- transcript: shared title library (custom-title > ai-title > synthetic >
first prompt) that also parses Codex rollouts natively; the fallback fills
source-reader titles (e.g. Cursor) for sessions it cannot parse.
- config [serve], opt-in WAL in sqlite_db, systemd unit, tests.
pm project: `wt` first-class, CLI cleanup, per-project multi-worktree
- Schema: `repos(name, slot_uuid, branch)` → `worktrees(name, repo, slot_uuid, branch)`.
A worktree has its own name (the symlink under projects/<p>/) and a `repo` column
that's the pool key, so a project can hold multiple worktrees of the same repo.
Legacy dbs migrate in place on first open (copies name into both columns).
- CLI reshape under `pm project`:
create <project> [--wt <spec>] — create-only; `--wt` optional
delete <project> [--dry-run] — whole-project only
wt create [-p P] <spec> — add worktrees to an existing project
wt attach [-p P] (--wt <names>|--all) [--no-branch]
wt detach [-p P] (--wt <names>|--all) [--dry-run]
wt delete [-p P] (--wt <names>|--all) [--dry-run]
`-p/--project` defaults to the current project (via cwd detection).
- Spec syntax: `foo,bar:baz,qux` → wt `foo`/repo `foo`, wt `bar`/repo `baz`,
wt `qux`/repo `qux`. Rejects duplicates, empty sides of colon, extra colons.
- Impl: `project/new.py` → `create.py`; attach/detach/delete/discovery/ls/status
thread (wt, repo) pairs; forward symlinks keyed on wt, pool claims keyed on
repo. check.Finding gains `wt`; ORPHAN_OWNER/OPS_OWNED now populate `repo`
from the pool key.
- Tests: full rewrite of test_project/test_check/test_current/test_status/test_pool
for the new signatures, plus new coverage for two wts of the same repo, spec
parsing, and legacy schema migration.
agent: add `pm agent serve` daemon for live session tracking
A headless daemon (stdlib threaded HTTP + SSE, ephemeral WAL SQLite) that
ingests best-effort hook events from Claude/Codex/Cursor and broadcasts live
session state to observers (the Emacs sidebar, curl).
- serve/{server,store,status,fallback}: HTTP+SSE server, WAL store, pure
status-derivation, and a Tier-2 transcript fallback poller. Status vocab:
working / waiting_response / waiting_permission / idle / unknown, with
openui-style activity-gating and a pid-liveness cleanup backstop.
- install-hooks: a shared stdlib reporter installed for Claude (settings.json),
Codex (a --profile pm config, since isaac regenerates ~/.codex/hooks.json),
and Cursor (~/.cursor/hooks.json, incl. shell/MCP approval). Skips the
Claude-hook double-report Cursor triggers.
- transcript: shared title library (custom-title > ai-title > synthetic >
first prompt) that also parses Codex rollouts natively; the fallback fills
source-reader titles (e.g. Cursor) for sessions it cannot parse.
- config [serve], opt-in WAL in sqlite_db, systemd unit, tests.