agent-id-cli 0.3.0

Portable identity registry for coding-agent sessions
Documentation
use anyhow::Result;
use serde_json::json;

use crate::cli::PrimeArgs;

pub fn execute(args: &PrimeArgs) -> Result<()> {
    let documentation = generate(args.prelude);
    if args.json {
        println!(
            "{}",
            serde_json::to_string_pretty(&json!({"documentation": documentation}))?
        );
    } else {
        println!("{documentation}");
    }
    Ok(())
}

pub fn generate(prelude_only: bool) -> String {
    let prelude = r#"# agent-id — Portable agent identity registry

Agent ID provides the permanent human-readable identity for a coding-agent session. The identity is keyed by the harness session ID; never invent a name or register a second name for the same session.

## OMP workflow

The OMP extension automatically looks up or registers the current session, records its working directory and session file, and manages its lifecycle state.

Call `agent-id current --json` to inspect the complete current assignment. The command uses `AGENT_ID_SESSION_ID` and never registers a missing identity. Call `agent-id discover` directly when you need to find other identities. Discover omits only identities in the `stopped` state by default; use `agent-id discover --all` to include them. Inside Herdr, discover adds live pane, workspace, status, and worktree context when the reported OMP session file matches an assignment.

Lifecycle hooks publish `working`, `idle`, and `stopped` automatically. Use `agent-id annotate` to publish `waiting` or `blocked`, or to set or clear a summary or namespaced extension value when an explicit update is needed. Automatic summaries use completed agent turns; explicit updates remain authoritative.

## CLI fallback

Direct CLI use is normally unnecessary under OMP. If the extension is unavailable, the CLI resolves a session from:

1. An explicit `SESSION_ID` argument or `--session-id ID`.
2. `AGENT_ID_SESSION_ID`.

A missing session ID is an error. A missing lookup is an error; register the session first.

## Examples

```bash
agent-id discover
agent-id discover --recent 24 --json
agent-id discover --all
agent-id register "$AGENT_ID_SESSION_ID"
agent-id register --family Oak "$AGENT_ID_SESSION_ID"
agent-id lookup "$AGENT_ID_SESSION_ID"
agent-id annotate --summary "Implementing checkout retries" "$AGENT_ID_SESSION_ID"
agent-id annotate --clear-summary "$AGENT_ID_SESSION_ID"
agent-id annotate --state waiting "$AGENT_ID_SESSION_ID"
agent-id annotate --state blocked "$AGENT_ID_SESSION_ID"
agent-id annotate --clear-state "$AGENT_ID_SESSION_ID"
agent-id annotate --cwd "$PWD" "$AGENT_ID_SESSION_ID"
agent-id annotate --clear-cwd "$AGENT_ID_SESSION_ID"
```

The default CLI output is the full name. Use `--json` when a tool needs the session ID, name parts, realm, slug, optional timestamped summary, typed activity state, working directory, and created/updated timestamps."#;

    if prelude_only {
        return prelude.to_string();
    }
    format!(
        "{prelude}\n\n## Commands\n\n### `agent-id register [SESSION_ID]` — Allocate a permanent identity\n\n```\n--family NAME       Prefer a family name, useful for child agents\n--realm NAME        Select a computer realm\n--session-id ID     Provide the session ID explicitly\n--json              Print the complete assignment as JSON\n```\n\nRegistration is idempotent: an existing session keeps its identity and receives a new `updated_at`.\n\n### `agent-id lookup [IDENTIFIER]` — Read an existing identity\n\nIDENTIFIER may be a session ID, canonical name, or slug. Without an explicit identifier, lookup uses the session environment.\n\n```\n--session-id ID     Provide an explicit session ID\n--json              Print the complete assignment as JSON\n```\n\nFails if the identifier has not been registered.\n\n### `agent-id current` — Read the current session identity\n\n```\n--json              Print the complete assignment as JSON\n```\n\nUses `AGENT_ID_SESSION_ID` to identify the current session and never registers a missing identity.\n\n### `agent-id annotate [SESSION_ID]` — Update activity metadata\n\n```\n--summary TEXT         Set a concise summary (maximum 240 characters)\n--clear-summary        Remove the summary\n--state VALUE          Set working, idle, waiting, blocked, or stopped\n--clear-state          Remove the activity state\n--cwd PATH             Set the current working directory\n--clear-cwd            Remove the current working directory\n--extension OWNER=JSON Set namespaced unstructured JSON metadata; repeatable\n--clear-extension NAME Remove one extension namespace; repeatable\n--session-id ID        Provide the session ID explicitly\n--json                 Print the complete assignment as JSON\n```\n\nSummary, state, working-directory, and extension metadata updates are independent; omitted fields remain unchanged. Agent ID timestamps mutable fields. Extension updates atomically replace one owner's JSON value.\n\n### `agent-id discover` — List identities\n\n```\n--limit N           Maximum records (default 20; zero means all)\n--recent HOURS      Only include records updated within this many hours\n--realm NAME        Only include records in this realm\n--all               Include stopped assignments\n--json              Print assignments and available runtime projections as JSON\n```\n\nStopped assignments are excluded by default. Use `--all` to include them. Results are sorted by `updated_at`, newest first. Inside Herdr, matching OMP session-file metadata adds a non-persistent live runtime projection.\n\n### `agent-id prune` — Remove old identity assignments\n\n```\n--before TIMESTAMP  Delete records updated before this timestamp\n--dry-run           Preview matching records without deleting\n--json              Print the prune report as JSON\n```\n\nPruning applies by default and removes both session records and matching name claims.\n\n### `agent-id prime` — Print this workflow manual\n\n```\n--prelude           Omit the command reference\n--json              Wrap the documentation in a JSON object\n```"
    )
}