Skip to content

feat: add a development install that leaves nothing half-done - #6

Merged
pashifika merged 1 commit into
mainfrom
feat/dev-install-script
Aug 28, 2026
Merged

feat: add a development install that leaves nothing half-done#6
pashifika merged 1 commit into
mainfrom
feat/dev-install-script

Conversation

@pashifika

Copy link
Copy Markdown
Owner

Summary

Adds bun run dev:install, a script that brings a development checkout to the state a finished install actually has, and documents it in the README's Development section.

omp plugin link . is one of four things a complete install is, and doing only that is what leaves a checkout half-installed:

  • The committed bundles may be stale against src/, and omp plugin link registers a checkout without building it.
  • This repository's own marketplace catalog is not registered, so omp plugin discover and omp plugin upgrade have nothing to read.
  • The owned MCP entry is not written until whichever session happens to start next.
  • Nothing reports what actually resolved, so the gap between "linked" and "working" is invisible.

Each was a separate command a contributor had to remember. The script is that list, run in order, with a report at the end.

It reimplements nothing

The point of the script is sequencing, not new behaviour, and it is deliberately incapable of disagreeing with the extension:

  • The plugin registry and the marketplace catalog are touched only through OMP's own CLI.
  • The MCP entry is written only through this package's own syncEntry — the same call the extension makes at session start, against the same single owned key.
  • Every path comes from src/paths.ts. The script derives none of its own, so it cannot drift from where the extension looks.
  • Subprocesses go through src/exec.ts's run, so the timeout, output cap, and missing-executable answer are the ones already decided there.

What it refuses to do

  • It never replaces a registration this checkout does not own. A plugin registered from somewhere else is reported and left alone; --force is required to relink over it. A git-spec install is therefore never silently swapped for a link.
  • It never acquires a CBM executable. /cbm install asks for confirmation when a system copy already resolves, and answering that question in a script would decide which executable an account's index belongs to. When nothing resolves, the script reports it and names the command.
  • It never installs from the catalog it registers. That resolves the catalog's source.ref, so it needs a published release. The script says so rather than failing at it.

One trap found while writing it

The script does not quote omp plugin features, and the reason is a real defect rather than a formatting preference. That renderer builds its enabled set from getEnabledFeatures, so the enabledFeatures: null case — no explicit selection recorded, which is exactly what a plain install leaves — yields an empty set and prints the disabled glyph beside every feature. Against this manifest that means it prints graph-augmentation as disabled while resolvePluginManifestEntries does load it (loader.ts:432-441: null selects every feature whose default is true), and while it is demonstrably appending to tool results.

A development install that pasted that output would report the augmentation as off in the one situation it is on. The script reproduces the loader's rule instead and prints which state applies and why:

graph-augmentation on — manifest default on, no explicit selection recorded

Key files changed

File Purpose
scripts/dev-install.ts The script. Six labelled steps: ownership check, build, link, catalog, MCP entry, resolution report
package.json Adds the dev:install script entry
README.md Documents the command in Development, including both things it will not do and the four flags

Test plan

  • bun run typecheck — clean
  • bun run test:unit — 409 pass, 0 fail
  • bun run test:packaging — 10 pass, 0 fail
  • Already-linked checkout: idempotent, reports the existing registration and continues
  • Foreign registration: omp plugin install github:… into a scratch HOME, then dev:install — refused, naming the path and the uninstall command
  • Clean scratch HOME: links, registers the catalog, and reports the unresolved executable with the remedy instead of acquiring one
  • Unknown flag (--nope): rejected rather than ignored
  • omp plugin discover and omp plugin upgrade both answer after the catalog is registered
  • The rebuild left dist/ unchanged, so the committed bundles match source
  • CI ci gate green on this pull request

🤖 Generated with omp

`omp plugin link .` is one of four things a complete install is, and doing
only that is what leaves a checkout half-installed: the bundles may be stale
against `src/`, this repository's own catalog is not registered so
`omp plugin discover` and `omp plugin upgrade` have nothing to read, and the
owned MCP entry waits for whichever session happens to start next. Each was a
separate command to remember, so `bun run dev:install` is the list.

It reimplements none of them. The plugin registry and the catalog are touched
only through OMP's own CLI, and the MCP entry only through this package's own
`syncEntry` -- the same call the extension makes at session start, against the
same single owned key. Every path comes from `src/paths.ts`, so the script
cannot disagree with the extension about where anything lives.

It refuses rather than guessing: a registration from somewhere other than this
checkout is reported and left alone unless `--force` says otherwise, so a
git-spec install is never silently swapped for a link. It never acquires a CBM
executable, because `/cbm install` asks for confirmation when a system copy
already resolves and answering that for you would decide which executable an
account's index belongs to. It never installs from the catalog it registers,
because that resolves the catalog's ref and needs a published release.

One trap found while writing it, and the reason the script does not quote
`omp plugin features`: that renderer builds its enabled set from
`getEnabledFeatures`, so the `enabledFeatures: null` case -- no explicit
selection, which is what a plain install leaves -- yields an empty set and
prints the disabled glyph beside a feature whose manifest default is true and
which `resolvePluginManifestEntries` does load. Pasting it would report
`graph-augmentation` as off while it is demonstrably appending to tool
results. The script reproduces the loader's rule instead and says which state
applies and why.

Verified on four paths: an already-linked checkout (idempotent), a foreign
registration (refused), a clean scratch `HOME` (links, registers, and reports
the unresolved executable without acquiring it), and an unknown flag
(rejected). `omp plugin discover` and `omp plugin upgrade` both answer after
the catalog is registered.
@pashifika
pashifika merged commit 62789b1 into main Aug 28, 2026
5 checks passed
@pashifika
pashifika deleted the feat/dev-install-script branch August 28, 2026 19:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant