--- name: omp-system-prompt-retrieval description: "Retrieve the exact system prompt an omp session is running: /dump while live, RPC get_state re-render, and the shipped template/override source paths." --- # Retrieve omp's live system prompt Three routes, in fidelity order. Verified on omp 18.4.10 (linux/x64). ## 1. `/dump` — the only exact capture of a LIVE session TUI slash command: "Copy session transcript to clipboard (and write LLM request JSON to tmp)". The request JSON is the wire-true payload (system blocks + tool schemas). Path is printed in the `/dump` output; then: ```bash jq -r '.system[] | strings // .system' # anthropic shape jq -r '.messages[] | select(.role=="system") | .content' # openai shape ``` **The prompt is never persisted in the session JSONL.** Session entries are only `title, session, model_change, thinking_level_change, message, custom(tool_execution_start), model_usage`. So a past session's prompt is unrecoverable from disk — capture live, or re-render. ## 2. RPC `get_state` — re-render without a model call `omp --mode rpc` answers `{"type":"get_state"}` with `data.systemPrompt: [blocks]` and `data.dumpTools` (spec: `omp://rpc.md` "get_state payload"). Drive it over stdio: ```python cmds = json.dumps({"id":"p1","type":"negotiate_protocol","protocolVersion":2}) + "\n" \ + json.dumps({"id":"s1","type":"get_state"}) + "\n" p = subprocess.run(["omp","--mode","rpc","--no-session","--no-pty"], cwd=TARGET_CWD, input=cmds, capture_output=True, text=True, timeout=280) ``` Closing stdin shuts it down cleanly (exit 0), no model call, no session file written. - Parse stdout line-by-line. Protocol v2 wraps logical frames >1 MiB in `rpc_chunk` frames: key on `chunkId`, require all `count` indices, `base64.b64decode` and concatenate in `index` order, then `json.loads` — otherwise a large prompt is silently lost. - Shape measured on a dotfiles repo cwd: 2 blocks, ~45 KB / ~391 lines — block 0 = static instruction block (RFC 2119 line, `§ Role`, Engineering/Tone/Escalation, tool inventory, `xd://` catalog), block 1 = footer opening `` + `` + the cwd's `AGENTS.md`. - `--no-extensions` changes nothing in the blocks; tool count rides in `dumpTools`, not the prompt. - `cwd` matters: the footer is cwd-derived (workstation block, context files, skills, rules). ## 3. Sources (edit here, not in a dump) | Layer | Path | |---|---| | Default instruction template (Handlebars, block 0) | `/src/prompts/system/system-prompt.md` | | Footer | `/src/prompts/system/project-prompt.md` | | Plain-custom template | `/src/prompts/system/custom-system-prompt.md` | | Repo rules (into footer) | the cwd's `AGENTS.md` | | Overrides | `--system-prompt`, `--system-prompt-template `, `--append-system-prompt`; discovered `SYSTEM.md`, `SYSTEM_TEMPLATE.md`, `APPEND_SYSTEM.md`, `PERSONALITY.md`, `TITLE_SYSTEM.md` | `` = `~/.bun/install/global/node_modules/@oh-my-pi/pi-coding-agent` (resolve via `readlink -f $(command -v omp)`). Docs: `omp://system-prompt-customization.md`. Precedence: explicit CLI flag > project `SYSTEM.md` > project `SYSTEM_TEMPLATE.md` > user `SYSTEM.md` > user `SYSTEM_TEMPLATE.md`. A same-scope literal always beats a discovered template, so a `SYSTEM_TEMPLATE.md` is inert while a `SYSTEM.md` sits beside it. ## Trap NEVER paste a rendered `/dump` into `SYSTEM_TEMPLATE.md`: a render freezes settings, tool catalogs, and mounted-device data. Copy the Handlebars **source** and diff against the shipped path after every omp upgrade. Plain files (`SYSTEM.md`, `APPEND_SYSTEM.md`) are inserted verbatim — `{{cwd}}` and friends stay literal there; only the template route compiles Handlebars.