learned.md: noctalia v5 bar layering + hot-reload loop; secret-gate self-match convention (quoted literals redacted per the convention the line itself states); niri 26.04 event-stream has no hotplug event. New managed skills: git-repo-secret-audit, omp-system-prompt-retrieval.
3.7 KiB
name, description
| name | description |
|---|---|
| omp-system-prompt-retrieval | 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:
jq -r '.system[] | strings // .system' <file> # anthropic shape
jq -r '.messages[] | select(.role=="system") | .content' <file> # 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:
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_chunkframes: key onchunkId, require allcountindices,base64.b64decodeand concatenate inindexorder, thenjson.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<project-context>+<critical>+ the cwd'sAGENTS.md. --no-extensionschanges nothing in the blocks; tool count rides indumpTools, not the prompt.cwdmatters: 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) | <pkg>/src/prompts/system/system-prompt.md |
| Footer | <pkg>/src/prompts/system/project-prompt.md |
| Plain-custom template | <pkg>/src/prompts/system/custom-system-prompt.md |
| Repo rules (into footer) | the cwd's AGENTS.md |
| Overrides | --system-prompt, --system-prompt-template <path>, --append-system-prompt; discovered SYSTEM.md, SYSTEM_TEMPLATE.md, APPEND_SYSTEM.md, PERSONALITY.md, TITLE_SYSTEM.md |
<pkg> = ~/.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.