Token-optimization suite for oh-my-pi — a local port of =@xynogen/pix-optimizer= off the upstream pi.dev coding agent. Five tools wired into one extension via src/index.ts, fronted by a single /optimizer command and one shared status-bar cell:
- Caveman (
Cv) — terse-output system prompt - RTK (
Rk) — prefixes shell commands withrtk+ injects RTK prompt - Ponytail (
Pt) — lazy-senior-dev system prompt (minimal code, YAGNI) - Engram (
En) — automatic memory recall onsession_startand retain on compaction, via the local Engram HTTP server (:7437, requires Engram ≥ 3.0.0: compact context,project_owned+resumesession registration; replay-safe retain viaoperation_id+GET /observations/save-resulton Engram ≥ 3.3.0); on/off toggle - Title (
Tt) — background session titles from the first user prompts; on/off toggle
All five persist to ~/.omp/agent/optimizer.json and toggle through the same /optimizer command. Since v2.0.0 this package also absorbs a third formerly standalone plugin:
- omp-skills — 41 workflow skills under
skills/(auto-discovered by omp’s skill provider) + live!`cmd`directive interpolation onskill://reads
One command opens an interactive overlay that fronts every tool:
/optimizer → pick a tool, then pick its value (native select dialogs)
/optimizer status → plain-text summary of all five tools
/optimizer <tool> → current value + valid values for that tool
/optimizer <tool> <value> → set directly (headless-safe)
v1 used a custom overlay widget (ui.custom) — under omp it rendered but never received keystrokes, so it was replaced. omp exposes no extension-contributed settings section (its ExtensionDashboard is enable/disable toggles only), so the interactive path uses omp’s native ctx.ui.select dialogs. Every path ends in the tool’s run() handler, which persists the new value and repaints the shared status cell.
State persists to ~/.omp/agent/optimizer.json, keyed by tool name. Each tool reads its saved value on session_start and writes it on every /optimizer change.
A single cell always shows all five tool icons in a fixed left-to-right order, color-coded by state: accent when the tool is enabled, dim when disabled. The cell is never empty. Engram’s icon is accent only when BOTH enabled and memory was actually loaded this session (dim if disabled or the Engram server is unreachable).
Icons come from three presets in src/status.ts (TOOL_ICON_ASCII Cv/Rk/Pt/En/Tt, TOOL_ICON_UNICODE emoji, TOOL_ICON_NERD), selected by the active omp symbol preset. The Nerd set is chosen for equal visual weight (glyph ink area 0.33–0.48 of the cell, measured on Symbols Nerd Font Mono): caveman \uf066, rtk \uf489 (oct-terminal; fa-terminal \uf120 was too thin, 0.18), ponytail \uf0c4, engram \uf472 (oct-database; fa-brain \uee9c was too heavy, 0.68), title \uf044 (\uf040 pencil too thin; Material Design \u{f090c} renders smaller in the terminal — stay in the Font Awesome/Octicons ranges). Re-measure with fontTools AreaPen before swapping a glyph.
Cuts output tokens while keeping full technical accuracy — savings are workload-dependent, not a fixed percentage: heaviest on prose-style explanations (fluff/hedging/filler removed), much smaller on agentic coding turns where code blocks, diffs, and tool output already stay verbatim and uncompressed. No independent measurement has been run for this fork.
| Level | Description |
|---|---|
| lite | Professional, no fluff |
| full | Classic caveman |
| ultra | Maximum compression |
| micro | Experimental prompt-minimized |
Toggle from the /optimizer overlay. Default level for new sessions is restored from ~/.omp/agent/optimizer.json.
Execute layer only — rewrites bash tool calls, prefixing known commands (git, gh, cargo, npm, pnpm, docker, kubectl, ls, grep, …) with rtk when the model forgets. Command chains are split on =&&=, =||=, =;= and =|=, and every known segment is prefixed — e.g. git add . && git push becomes rtk git add . && rtk git push. Operators inside quotes are ignored, and unparseable commands are left untouched. Falls back gracefully when the rtk binary is missing (warns once). No system-prompt injection — the rewrite alone is zero always-on context cost (matches upstream 1.1.28; see sync note below).
Also blocks sudo segments in bash chains before rewriting — redirects the model to a sudo_run tool when active tools include one, otherwise explains the restriction. This intercept is unconditional (independent of the RTK on/off toggle would be more correct upstream behavior, but currently ships inside the same tool_call hook — see src/rtk.ts).
Requirement: the rtk binary must be on PATH.
cargo install rtk-ai“Lazy senior dev” mode. Governs what the agent builds (smallest complete change), orthogonal to Caveman which governs how it talks — they pair. Before writing code the agent maps every place the change must reach (callers, tests, fixtures, config) and what it could break, then takes the first option that fully works: skip it → reuse in-repo → stdlib/platform → installed dep → one line → minimum code. Every reply ends with what was skipped or not checked. Validation, error handling, security, and accessibility are never cut. Known shortcuts are marked shortcut: <limit>, <when to upgrade>. Bundled ponytail-review / ponytail-audit skills give a numbered, plain-English quality review of a change / whole repo.
| Level | Description |
|---|---|
| lite | Build as asked, name the smaller option |
| full | The rules enforced (default) |
| ultra | YAGNI extremist, also questions the request |
No install required — pure prompt injection, no external binary or PATH dependency (unlike RTK and TOON).
Not published to npm. Install straight from git (no manual download; omp plugin install accepts git sources, see https://omp.sh/docs/plugins):
omp plugin install 'github:arkhan/omp-optimizer'
# pinned to a tag/commit:
omp plugin install 'github:arkhan/omp-optimizer#<ref>'Start a new omp session afterwards. Alternatively, with a local checkout, point omp at it with an explicit extension path or the extensions: setting:
omp --extension /path/to/omp-optimizer/src/index.ts# ~/.omp/agent/config.yml or <repo>/.omp/config.yml
extensions:
- /path/to/omp-optimizer/src/index.tsLoading through extensions:=/–extension= also makes the omp-plugins capability provider pick up skills/toon-json/ automatically — no separate skill registration needed.
| File | Role |
|---|---|
src/index.ts | Wires all five tools + shared status, registers /optimizer |
src/opt.ts | The /optimizer command (native select dialogs + text args) |
src/caveman.ts | Caveman logic, levels, prompt |
src/mode.ts | Shared level-resolution + createMode() factory (caveman/ponytail) |
src/rtk.ts | RTK prompt + bash command rewriting + sudo intercept |
src/ponytail.ts | Ponytail logic, levels, prompt |
src/engram.js | Engram memory recall + on/off toggle handle |
title.bundle.js | Prebuilt omp-title bundle, gated on/off in index.ts |
src/persist.ts | Disk-backed ~/.omp/agent/optimizer.json persistence |
src/tool-result-filter.ts | Strips model-guidance warnings from tool_result |
skills/toon-json/SKILL.md | jq+TOON JSON workflow — standalone skill, no optimizer state |
Each tool registers its own lifecycle hooks and exposes an OptimizerHandle that /optimizer dispatches to. All five share one OptimizerStatus.
Sync state: feature-parity with upstream 1.2.0 (forked at 1.1.14). Upstream 1.1.15–1.1.18 reviewed 2026-07-24 (see prior note, unchanged). 1.1.19–1.1.24 reviewed 2026-08-11: the only functional delta is 1.1.22’s refactor(pix-optimizer): move toon guidance to skills — upstream deleted json.ts, the toon tool/icon/state, and the pix.json toon config key entirely, since the bundled toon-json skill (auto-discovered, on-demand) made the heuristic-triggered system-prompt injection redundant. Ported here: src/json.ts=/=json.test.ts deleted, toon=/=Tn removed from OptimizerTool=/=TOOL_ORDER=/both icon catalogs/=/optimizer’s tool list/ optimizer.json schema — this port carries the exact same redundancy upstream identified (the toon-json skill was already bundled and auto-discovered here too), so the same deletion applies verbatim. The rest of 1.1.19–1.1.24 (UI menu spacing, pix-pretty height-aware modal overlays with pagination/diff-tints, Kitty keyboard-protocol support in the custom overlay, cross-package dedup, theme unification, a dependency-pin sync) is opt.ts’s original custom-overlay/raw-keyboard-handling infrastructure and the external pix-pretty theming package — this port replaced the overlay with omp’s native ctx.ui.select dialogs (no raw key parsing) and dropped pix-pretty entirely (see below), so none of it has an equivalent surface here.
1.1.25–1.1.29 reviewed 2026-09-03: one real functional delta, 1.1.28’s fix(pix-pretty): dim gate-overlay values; drop RTK always-on prompt — upstream deleted RTK_SYSTEM_PROMPT from rtk.ts entirely, since the tool_call rewrite hook already adds the rtk prefix on its own, making the always-on prompt injection redundant baseline context (manual rtk err=/=summary=/=log=/=json=/=test=/=gain subcommands are no longer advertised — same tradeoff upstream made for toon in 1.1.22). Ported here: RTK_SYSTEM_PROMPT deleted, before_agent_start now only detects sudo_run availability and injects nothing — this port’s own copy of the constant was already leaner than upstream’s pre-1.1.28 version (upstream’s had a full “prefix with rtk” preamble + chain example; this port’s only advertised the manual filtering subcommands), but the same redundancy argument applies verbatim once the execute layer is the sole rewriter. The rest of 1.1.25–1.1.29 (a dim=→=muted theme-color-tier rename across every pix-pretty-consuming package’s status/overlay rendering, a pix-sec design-doc addition, and two release-chore/bun.lock-dedup commits) is pix-pretty theme-token surface this port never carried (status icons are static ASCII, the /optimizer overlay is native ctx.ui.select, neither calls theme.fg()) or unrelated new-package planning — no equivalent surface here.
1.2.0 reviewed 2026-09-26 (package.json version bump from the 1.1.29 line above; no CHANGELOG.md in the upstream repo, diffed by file). Four real deltas:
- =mode.ts= (new file) — upstream extracted the level-resolution + session-restore + status-sync boilerplate shared by
caveman.ts=/ =ponytail.tsinto a genericcreateMode<L>()factory + genericresolveLevel=/=toggleLevel. Ported here verbatim as a DRY refactor, with one adaptation: upstream’sbefore_agent_starthook treatsevent.systemPromptas a plain string and concatenates (`${prompt}\n\n${existing}`) — that’s the@earendil-works/ pi-coding-agentSDK’s contract. This port’s hook still returns{ systemPromptAppend: prompt }, matching every other hook in this package (see theExtensionAPIdivergence note below) — no behavior change,caveman.test.ts=/=ponytail.test.tsunchanged and green. - =persist.ts= hardening — upstream’s
readFile()now iterates an explicit tool whitelist instead of trusting whatever keys are in the parsed JSON, rejecting a corrupt/hand-editedoptimizer.json(stray keys, non-string values) instead of propagating garbage into tool state. Ported here asOPTIMIZER_TOOLS(all five local tools, vs upstream’s three). Upstream also dropped thetry/catcharoundsaveOptValue’s write in favor of ashowTransientErrorUI call frompix-prettyat each call-site — NOT ported: this port’ssaveOptValuealready swallows andconsole.warn=s its own write failures (pre-dates this sync), so callers never needed their own try/catch; adding =pix-pretty’s external dep for a UI toast this port doesn’t have would be a regression, not a fix. - =opt.ts= full rewrite to a =ui.custom= keyboard-nav overlay (arrow-key cycling,
ModalPager, Kitty-protocol key matching) — NOT portable, confirmed dead end: this is the exact overlay mechanism v1 of this port already tried and abandoned (see Command section above —ui.customrenders under omp but never receives keystrokes). No change. - =caveman.ts= full redesign to ASD-STE100 Simplified Technical English (keeps articles, active voice, numbered reply-shape rules) — reviewed and deliberately NOT ported. Two independent reasons: (1) wrong lineage — this port’s
caveman.tshas trackedJuliusBrussee/caveman’s SKILL.md since the fork point, notpix-optimizer’s own evolving caveman text (see the lineage note below); (2) upstream’s redesign explicitly keeps articles (“unlike the old article-dropping caveman prompt” — their words), which is the opposite of this harness’s own globalRULES.mdcaveman mandate (“Sin artículos (el/la/un/una)”) — porting it would silently break every other project on this machine that relies on that mandate.status.ts’s parallel move to the external@xynogen/pix-prettyicon catalog + a global/pixicon-mode command is the same already-declined external-dep tradeoff documented below, unchanged.
Two of those four (mode.ts, persist.ts) landed in this sync; the other two are confirmed non-applicable, not oversights.
Caveman prompt text (src/caveman.ts BASE=/=SAFETY) separately tracks =JuliusBrussee/caveman= (the original Claude Code skill this mode’s wording is modeled on — distinct lineage from pix-optimizer=/=pi-caveman above). Synced through commit a010997 (2026-08-11), then again against main HEAD post-v2.2.0 (2026-08-20, repo tags v2.1.0/v2.2.0 — both releases are CLI/installer/ hooks-infra work, no SKILL.md wording changes of their own; the delta below was a separate main-branch drift found by diffing current HEAD). On top of the prior v1.10.0 sync: added only=/=except to the never-drop-negation list plus an explicit numbers/units-exact rule, widened tool-call silence to cover narration between calls with an explicit clarify/warn/ambiguity exception, added a “never recap normal-then-Caveman:” self-reference guard with an explicit exception for direct questions about the active mode, a guard against classical (wenyan) characters leaking into non-wenyan levels, and widened the persisted-text boundary to explicitly cover code comments and messages to other agents/peers (this port’s hub messaging). 2026-08-20 delta: ported a “never add words to sound caveman” anti-mangling rule (no inserted pronoun/copula to fake broken grammar, keep the correct verb form when it costs the same token count — mangling buys nothing, reads worse; same “shorter-or-plain” test already applied to abbreviations/arrows). Reviewed PR JuliusBrussee/caveman#782 (“feat(install): add native OMP support”, open, unmerged as of 2026-08-20): installer-only, no prompt-text surface — it wires ~/.omp/caveman-plugin as a managed plugin whose only extension code is a session_start status-bar setter, with the actual guidance delivered via a copied rules/caveman.md (raw src/rules/ caveman-activate.md, no frontmatter/glob, no Precedence: clause) and skill/command/agent dirs — no before_agent_start-equivalent hook, so it cannot guarantee same-tier system-prompt injection every turn the way this port’s caveman.ts does, and it ships none of the harness-specific Precedence: fix documented above (upstream has no visibility into omp’s own Evidence/Completeness/Reasoning-Format system-prompt contract this port patches against). Not a reason to change this port’s own hook-based design. Upstream shipped Caveman 2.0.0 (82864c8, “engine, proxy, SDKs, unified CLI”) between the a010997 sync and this one — a Go proxy/engine, CCR recovery store, and @caveman-ai/cli=/SDK surface that shrinks /input/ tokens ahead of the provider call. Reviewed and confirmed inapplicable: this port only ever carried the pure system-prompt-injection skill (output-side), no proxy, no CLI, no engine --- there is no equivalent surface here to extend. Re-diffed =skills/caveman/SKILL.md at main HEAD 2026-09-03: no wording drift since the 2026-08-20 sync above — every current paragraph already has a ported equivalent in BASE=/=SAFETY (the only unported bits remain the previously-reviewed-and-skipped /caveman-compress-exempt clause and “open a defect = open issue” wording, neither mapping to anything here). Re-diffed again 2026-09-26 against ~/.agents/skills/caveman/SKILL.md (installed fresh that day via npx skills add JuliusBrussee/caveman -g, pinned to main HEAD — byte-identical to the GitHub main fetch used for this review): one new paragraph, a “Clarity register” hybrid rule — mixes ASD-STE100 clarity principles (one idea per sentence, ≤20-word target, active voice, present tense, one-term-per-concept, imperative mood, 3-word noun-cluster cap, single-referent pronouns) into caveman’s existing article-dropping/terse identity rather than replacing it, with an explicit “conflict → clarity wins” tiebreaker. Unlike pix-optimizer’s ASD-STE100 rewrite above, this is additive, not a replacement — still drops articles, still compatible with the global RULES.md mandate. Ported verbatim into BASE, positioned (matching upstream) right after the anti-mangling rule and before the tool-call-silence rule.
Ponytail prompt text (src/ponytail.ts BASE=/=SAFETY) separately tracks =DietrichGebert/ponytail=’s .openclaw/skills/ponytail/SKILL.md. First version-pinned sync: 2026-08-11, main HEAD. Added a Persistence: line (drift-back-to-over-building guard, mirroring Caveman’s own) that was missing from this port entirely; widened the never-simplify-away rule with an explicit “user insists on full version → build it, no re-arguing” override; widened the self-check rule with “no fixtures, no per-function suites unless asked” (guards against test bloat under this harness’s own verification mandate); and expanded the terse-output rule with an explicit essay/feature-tour/design-note ban plus the converse — explanation the user explicitly asked for (a report, a walkthrough, phase notes) is not debt and prints in full — plus the upstream Pattern: line, all missing from this port before. Upstream’s mode-filtering/hook-infra fixes (filterSkillBodyForMode, the ponytail: marker scanner, rejecting review as a default mode) belong to the 20-agent plugin/hook surface this port never carried (no modes beyond lite/full/ultra, no hook-side marker scanning) — no equivalent surface exists here to update. Re-diffed at main HEAD 2026-09-03: two more concrete deltas ported — the ponytail: comment bullet now names example ceiling categories (global lock/O(n²) scan/naive heuristic) plus a concrete # ponytail: global lock, per-account locks if throughput matters example (previously generic, “names the ceiling and upgrade path” with no example); and the self-check rule now closes with “YAGNI applies to tests too”, making explicit that the trivial-one-liners- need-no-test exemption is the same laziness principle as the rest of the skill, not a separate carve-out.
Synced 2026-10-08 against caveman v3.2.0 / ponytail v5.1.0 / pix-optimizer 1.3.2 (live files at main HEAD, not changelogs):
- caveman (
skills/caveman/SKILL.md; 3.2.0 “refine voice rules”): ported switch-off-in-one-line, diff-first answers (changed lines + 1-2 context lines), existing-comments-are-payload, question-to-user → full sentences, harness status line → give it, a pre-send check, and theultracaveskill’s copula/connective drop + no-summary-after-list intoultra. Themegacaveskill’s floor (payload in original script, 不/非/勿/未/毋 kept, Arabic numerals, ambiguous clause → 白話, never claim savings) is appended to allwenyan-*levels; the old “80-90% character reduction” claim is gone. Deliberately NOT ported: upstream’s relaxed “bounded status” tool-call rule (this port keeps full tool-call silence) and the hook-reported/caveman statuswording (this port tracks level itself). Everything else in 3.2.0 is proxy/engine/installer/browser-extension infrastructure — no equivalent surface. - pix-optimizer 1.3.2 lineage:
63b2ded“lite ships the short rule set” ported asLITE_BASE(also fixes lite’s old contradiction: BASE said “drop articles”, lite intensity said “keep articles”);Precedence:kept in it. Not ported:09c2e9e(pix’s caveman reduced to a length-only preference because its separate SOP package owns style — no such package here),79d4cfcrtk auto-install via@xynogen/pix-runtimebinary catalog (external dep, same ceiling aspix-pretty), the asyncsaveOptValuerefactor (this port’spersist.tsis sync/local), and Windows path/home/theme refactors. - ponytail v5.0.0/v5.1.0:
BASE=/=SAFETYrewritten to the new ruleset (scope-mapping before writing, “lazy about the solution, never the change”, move/merge keeps validation, one-line why-only comments, closing skipped/unchecked lines, test trigger list, ultra questions the request) and theponytail:marker becameshortcut:(old marker still recognized). Dropped as superseded: the fixed[code] → skippedpattern line and the “complex request? ship lazy version” rule.ponytail-reviewandponytail-auditskills copied verbatim from upstream. Not ported: the session-start codebase map (hook infrastructure),ponytail-debt=/-gain=/-help(CLI/hook-state dependent). - engram (gentle-engram pi-v0.2.0 → pi-v0.4.1):
src/engram.jsretains the compaction summary withproject_owned+resume:truesession registration (effective<id>:resume:Ncached per runtime id), recalls with/context?compact=true, and since pi-v0.4.0 saves viasaveObservation(): frozenoperation_id,GET /observations/save-resulton ambiguous acks, one replay only after the typed 404observation_save_result_not_found. pi-v0.4.1 (session summaries only on explicit closure) is amem_*prompt change and does not apply. Not ported:mem_*tools,pi-engram init, installer pins, self-heal server launcher (MCP/pi-engram own those).
Synced 2026-10-19 against caveman v4.0.1 / ponytail v5.3.2 / pix-optimizer 1.3.3 (live files at main HEAD):
- caveman v4.0.0/v4.0.1: both releases are Go CLI / proxy / hook / Windows / OpenCode / Pi-extension work (
@caveman-ai/pi0.3.1: thinking-level preservation, custom-message turns, proxy config — none apply to a purebefore_agent_startprompt port).skills/caveman/SKILL.mdis byte-identical atv4.0.1andmainand last changed 2026-10-06 (already covered by the 2026-10-08 sync). Two small leftovers ported: explicit reply-language instruction wins and quoted text never switches language (BASE+LITE_BASE), and the persisted-text boundary now names tickets, code comments and messages to third parties. Still NOT ported: bounded-status tool-call rule, hook-reported/caveman status,/caveman-compressexemption. - ponytail v5.2.x–v5.3.2:
.openclaw/skills/ponytail/SKILL.mdandskills/ponytail-review=/-audit= unchanged since 2026-10-08 (2a1fe84); 5.3.2 is the/ponytail band importboard feature (CLI/hook state). Nothing to port;ponytail-review=/-audit= verified byte-identical to local copies. - pix-optimizer 1.3.3 (
597cc9a“preserve piped and redirected command output”):rewriteChainno longer prefixes pipe producers (only the final consumer of a pipe getsrtk) and leaves any command containing<or>untouched, sortk’s filtered output cannot corrupt data piped into another program or written to a file. Ported with the upstream test matrix (adapted: nortkCommandresolved-path parameter, that arrived with the unported binary-catalog commit79d4cfc). Other commits in the range (088ac75render snapshot tests, version bumps) needpix-prettyor carry no code.
Ported to omp’s ExtensionAPI (@oh-my-pi/pi-coding-agent), which differs from upstream pi-coding-agent in ways that required real code changes, not just an import-scope rename:
BeforeAgentStartEventResult.systemPrompt(array-return, old omp API) is gone from the currently installed SDK — the old{ systemPrompt: [prompt] }return from every hook was silently dropped (checked, wasn’t a bug on the config/rules side:optimizer.jsonvalues were correct, the hook return just no longer matched the SDK contract). Fixed: every hook now returns{ systemPromptAppend: prompt }— a plain string, auto-concatenated across hooks by the runner (seepi-coding-agent’sexamples/extensions/pirate.ts- its
CHANGELOG.md). No manualevent.systemPrompt ?? ""merging needed.
- its
event.systemPromptOptions?.selectedToolsdoes not exist on omp’sBeforeAgentStartEvent.rtk.tsdetectssudo_runavailability viapi.getActiveTools()instead.- Dropped the
@xynogen/pix-prettyicon catalog and@xynogen/pix-dataconfig-seeding dependencies (external to omp, not installable). Icons are static ASCII;~/.omp/agent/pix.jsoninitial-value seeding was removed —optimizer.jsonis now the only source of truth. - The
/optimizercommand’s original overlay widget (ui.custom, with a local plain-ASCIIframeLinesport) rendered but never received keyboard input under omp — replaced with nativectx.ui.selectdialogs + a text-arg form (see Command section above).
bun testThis package was built by merging two upstream Pi community packages (via @xynogen/pix-optimizer, see its own README for full lineage):
- Caveman mode — originally from
npm:pi-caveman. - RTK rewriting — originally from
npm:pi-rtk-optimizer. - Ponytail mode — ruleset adapted from =git:github.com/DietrichGebert/ponytail=.
All upstreams are MIT licensed.
MIT