agent-id-cli 0.1.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

Use `agent-id` to register and look up the permanent human-readable identity for a coding-agent session.

The identity is keyed by the harness session ID. Do not invent a name or register a second name for the same session.

Session discovery, in order:

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

The realm is discovered from `--realm NAME`, `AGENT_REALM` (for tests/overrides), or `$XDG_CONFIG_HOME/agent-id/realm` with `$HOME/.config/agent-id/realm` as the fallback. If no realm configuration exists, one is automatically selected and saved to the realm file.

The registry is durable and defaults to `$XDG_DATA_HOME/agent-id`, or `$HOME/.local/share/agent-id` when `XDG_DATA_HOME` is unset. Set `AGENT_ID_HOME` for tests or an isolated registry.

When you need to understand the identity system or discover other agents, run `agent-id prime`. The extension provides this guidance once per session branch, including tree navigation, without repeating it on every prompt.

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

## Examples

```bash
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 working "$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"
agent-id register --json --family Oak "$AGENT_ID_SESSION_ID"
```

The default 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 the 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 the session ID explicitly\n--json              Print the complete assignment as JSON\n```\n\nFails if the identifier has not been registered.\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--session-id ID     Provide the session ID explicitly\n--json              Print the complete assignment as JSON\n```\n\nSummary, state, and working-directory updates are independent; omitted fields remain unchanged. State timestamps are generated by agent-id and are available in JSON as `state.updated_at`. Working-directory metadata is an optional host-provided path and is not inferred from prompt text.\n\n### `agent-id discover` — List recent identities\n\n```\n--limit N           Maximum records (default 20; zero means all)\n--recent HOURS      Only records updated within this many hours\n--realm NAME        Only records in this realm\n--json              Print the complete assignments as JSON\n```\n\nResults are sorted by `updated_at`, newest first. Human-readable results include summaries, states, and working directories when present; timestamps remain available in JSON.\n\n### `agent-id prune` — Remove old identity assignments\n\n```\n--before TIMESTAMP  Delete records updated before this RFC 3339 timestamp\n--dry-run           Preview matches 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 manual in a JSON object\n```"
    )
}