5.0 KiB
name, description
| name | description |
|---|---|
| plugin-git-install-committed-artifact | Use when shipping or landing an omp/pi plugin (omp plugin install/upgrade git): install validation fails on a missing build artifact, a stale bun git-mirror cache is reused, the live bundle needs proof it is the merged build, or upgrade says "not installed". |
Plugin install from git: committed artifact + fresh mirror
omp plugin install git:<url> (and pi install git:) clone the repo and validate the manifest's declared extension entry WITHOUT running a build step. Two failure classes seen live (dank/dankvoice, 2026-10-19):
1. Declared entry missing from the clone
Symptom: Plugin <name> extension validation failed: ./dist/index.js: declared extension entry not found on disk.
Cause: build output (dist/) is gitignored; the manifest points at it; the clone has only src/.
Fix — ship the artifact:
- Remove
dist/from.gitignore,bun run build, commitdist/. - Prove build determinism first: build twice,
cmpthe outputs (bun esm builds are byte-reproducible without sourcemaps). - Pin the contract in a small bats suite so it can't rot:
- the manifest's declared entry is tracked in git (
git ls-files -- "${entry#./}"non-empty — this is the installer's exact contract, not a config assertion); - committed bytes equal a fresh build (
bun run buildthengit diff --name-only -- distis empty → red on drift).
- the manifest's declared entry is tracked in git (
2. Stale bun git-mirror cache
Symptom: fix pushed, retry still fails identically, and the retry is suspiciously fast (seconds).
Cause: bun keeps bare mirrors in ~/.bun/install/cache/<hash>.git and may reuse them at an old commit — even after the fix is pushed and the default branch is correct.
Diagnose + fix:
find ~/.bun/install/cache -maxdepth 2 -iname "*<repo>*"
git --git-dir ~/.bun/install/cache/<hash>.git log --oneline -3 --all # stale HEAD?
rm -rf ~/.bun/install/cache/<hash>.git # it is a cache; safe
Prove the fetch path independently first (also validates credentials for private Gitea repos):
GIT_TERMINAL_PROMPT=0 git clone -q <url> /tmp/x && git -C /tmp/x log --oneline -1 && ls /tmp/x/dist
Order of investigation (don't skip)
- Gitea default branch correct? (
GET /api/v1/repos/<o>/<r>with token — private repos 404/None unauthenticated.) - Plain unattended clone contains the entry? If yes, the installer's view is cached → purge mirror.
- Only then suspect the installer itself (validation code lives in the minified bundle;
grep -oE '.{600}<error string>' "$bunfile"onreadlink -f $(which omp)shows the exact check).
Landing a merged PR on the live box
After the merge and the --ff-only on the dev checkout (ls -ld node_modules after landing anything that could have touched it):
omp plugin upgrade <name>takes the PACKAGE name, not the install alias.omp plugin upgrade dankvoicefailsdankvoice is not installedwhile the live copy sits in~/.omp/plugins/node_modules/omp-dankvoice/. Read the directory name (orpackage.json"name") and upgrade that.- Then close the chain of custody with one command — the deployed bytes are the merged bytes:
If only docs/tests changed,
cmp ~/Projects/<repo>/dist/index.js ~/.omp/plugins/node_modules/<pkg>/dist/index.jsdist/is untouched and this should already match; ifsrc/changed, the plugin must be upgraded first or this fails withchar <n>— which is a real finding (stale live bundle), not a test bug. - The session that did the merge keeps the OLD bundle in memory: it is still running pre-merge code. Never conclude "the change does not work" from the merging session.
After install — proof without a TUI
omp plugin doctor→ per-plugin ✔ line.- Audible/behavioral chain when TUI input is unusable (update-banner modal freezes pty submits): run
omp --mode=rpc --no-sessionwith the feature env armed (dankvoice:DANKVOICE_AUTO=1, gate is print/json-only) and watch for objective side effects, e.g. PipeWire:pw-dump | grep -q "say-<ms>.wav"proves synth+playback end-to-end. - When pty submits DO work (no modal), the strongest instrument is a stub player plus a clip count, not ears or pixels:
DANKVOICE_PLAYER=/tmp/stub.shwhere the stub appends$1to a log and exits 0. Launch the DEPLOYED bundle by path (omp --no-extensions --no-session -e ~/.omp/plugins/node_modules/<pkg>/dist/index.js) in a neutral cwd withDANKVOICE_CONFIGpointed at a scratch file so the operator's settings are untouched. - Count clips per narration EVENT, not per turn. One turn can fire several narrations (dankvoice:
message_endcarries prose+thinking,agent_endthe settled answer; the dedupe only skips byte-identical text, so thinking-on means both speak). A "too many clips" result is usually correct behaviour — check the harness transcript for the turn count before believing a bug. The player deletes each temp wav, so the log line count is the only surviving evidence: park it in~/.AGENTTRASH/<date>-<topic>/if it becomes evidence for an issue.