opi
Operations Interface — a project control center for your terminal.
Go into any repository, type opi, and get a usable interface for that
project — without configuring anything first.
Status:
0.6.0. Scripts are the main thing; health, security, updates, clean and the commit/release workflows are built on top of them.
What it does
Its primary job is to be a better npm run. The start screen shows the
project's scripts — grouped by prefix, labelled from scripts-info, with the
package manager detected rather than typed:
astro-v7-workspace pnpm
12 entries · 4 groups
Development
› dev Startet die Starter-App im Dev-Modus
dev:blog Startet die Blog-App im Dev-Modus
Build
build Baut Starter- und Blog-App
build:blog Baut die Blog-App
Preview
preview Vorschau des Starter-Builds
Quality
check Prüft das Repo mit Biome
check:fix Behebt Lint- und Formatfehler
Enter runs the highlighted script. That is the shortest path, and nothing is
placed in front of it. A list taller than the terminal scrolls, and / filters
it as you type — in a monorepo that is the difference between scrolling past
thirty entries and typing three letters.
Past 15 entries or 5 groups the groups move into a row of tabs and only the active one's entries are listed, because a heading per group over thirty-odd scripts is taller than the terminal:
casoon-web pnpm
43 entries · 10 groups · 3 packages
1 Development 2 Build 3 Preview 4 Quality 5 Deploy …
─────────────
› dev Startet die Homepage
dev:homepage Startet die Homepage
dev:insights Startet Insights
dev:webcheck Startet Webcheck
←→ group / search H Health C Clean S Security U Updates
The first group is preselected and the cursor is on its first entry, so opi ↵
still starts dev — the tabs hide what is not needed rather than asking for a
choice first. ← →, Tab and the digits switch groups; / searches all
of them, which is the case the tabs are worst at. opi | cat lists every group
as before: nothing on the other end of a pipe can press a key.
Three speeds, all backed by the same task model:
Arguments after the name go to the script: opi build --verbose.
In a monorepo each workspace member's scripts appear under the member's name —
only those the root does not already define, since the root's script usually
wraps them and wins the name anyway. Where both exist, a bare name runs the
root's and blog/dev runs the member's:
opi also works from anywhere inside a project, not only from the directory
holding package.json.
The script replaces the opi process, so Ctrl-C reaches your dev server
rather than killing a wrapper, and the script's exit code is what your shell
sees — opi build && … works.
More than one kind of project
A repository can be several things at once, and opi does not make it choose.
package.json and Cargo.toml are both read, and their commands share one
list:
llmux-dashboard npm · cargo
Development
cargo run Build and run the binary
dev
Build
build
cargo build Build in release mode
cargo check Type-check without building
Health and clean follow: cargo fmt --check, cargo clippy and cargo test
run alongside the npm checks, and target/ is listed with the build artefacts.
Saying more about a script
Optional, and only ever refinement — a project with neither opi nor
scripts-info still gets a usable list, which is the whole point.
description |
Wins over scripts-info, which stays valid for nr |
group |
Replaces the group the script's name implies |
favorite |
Lifts it out of its group, to the top |
confirm |
Asks before running it; opi --yes <script> answers in advance |
A confirm script refuses to run without a terminal rather than assuming yes —
otherwise the protection would vanish in exactly the case it exists for.
The other areas
Each is a hotkey in the list and a flag on the command line. Never a bare word:
health, clean and release are script names in real projects, and the bare
word stays theirs.
H |
opi --health |
Runs every check the project's tools can answer, concurrently |
S |
opi --security |
Secret scan and a parsed dependency audit |
U |
opi --updates |
What is outdated, split into safe and major |
C |
opi --clean |
Removable artefacts, with what each one costs |
opi --check commit |
The fast checks, before you commit | |
opi --check release |
Everything, plus a clean tree and an untagged version |
astro-v7-workspace health
✓ Lint & format 0.2s biome
✗ Secrets 1.0s nosecrets
✓ TypeScript (@astro-v7/starter) 5.2s astro
✓ TypeScript (@astro-v7/blog) 5.4s astro
opi reimplements none of this. It detects which tool a project depends on —
Biome, ESLint, Prettier, tsc, astro check, Vitest, Jest, fallow, Knip, a
secret scanner, cargo — runs it, and relays what came back. In a workspace the
checks run per member, in the member, because that is where the tools and their
config live.
Output is parsed only where the format is documented (audit --json,
outdated --json). Everything else is relayed whole and capped at twenty lines,
with the command to see the rest: a parser that guesses at a tool's output
breaks on that tool's next release.
There is no health score. A composite number stops meaning anything within weeks; what a failing tool actually said does not.
Design rules
- Zero configuration.
opimust be useful in an unmodified repository. A tool you have to configure first never gets started in someone else's project. - The project's own files are the only interface.
package.jsonandCargo.toml— noopi.toml, no second source of truth ofopi's own making.scripts, optionallyscripts-info, optionally anopikey for refinement. - No task system of its own.
opidoes not define tasks with their own commands — that would put it in competition with npm scripts,just,makeand Taskfile for no gain. - Orchestration, not reimplementation.
opiis a UX layer over proven tooling.
Install
Unix only. opi runs a script by replacing its own process with exec, so
Ctrl-C reaches the dev server rather than killing a wrapper, and its
interactive list drives termios directly. Windows offers neither, and a second
execution model that nothing exercises would be worse than an honest boundary.
Building on Windows fails with that message rather than producing a degraded
binary.
Documentation
- docs/project-state.md — what this is and where it stands
- docs/architecture.md — the modules and how they fit
- docs/constraints.md — the boundaries the implementation respects
- docs/conventions.md — the rules future changes follow
- docs/decisions.md — the decisions in force, and why
Terminal presentation comes from runemark, the shared presentation layer for these CLI tools.
Name
opi is unrelated to OdradekAI/opi, which
owns the opi-* crate namespace on crates.io. Installing both puts two opi
binaries in ~/.cargo/bin.
License
MIT (LICENSE).