Help us shape the future of Go! Take the 2026 Go Developer Survey

o-cmds

command module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 31, 2026 License: MIT Imports: 26 Imported by: 0

README

o-cmds
Latest release Go Reference Go version License

Agents leave small scripts; you list, inspect and run them, with the newest at the bottom.

List saved commands, run one by number, then preview and run one in the TUI

o-cmds keeps shell scripts for the owner to inspect and run by name or number. Agents can add them through the CLI or MCP. Commands list in creation order: the newest is closest to the bottom. Adding a duplicate name records another command with a suffix (hello-2, etc.). Empty scripts and missing descriptions or working directories are accepted.

o-cmds is an o-family extension: oden dispatches the CLI, ochazuke supplies the TUI, settings, bindings, and catalog. An o-cmds executable on PATH is discoverable by the family's o and mtm commands, just like o-gh or o-git.

Install with the Go version in go.mod or newer:

go install github.com/unixsuperhero/o-cmds@latest

With the installed binary on PATH:

printf 'printf "hello %%s\\n" "$1"\n' | o-cmds cmd add --name hello --desc 'Say hello'
printf 'pwd\n' | o-cmds cmd add --name where --desc 'Show the current directory'
o-cmds cmd list
o-cmds cmd show hello
o-cmds cmd run hello -- 'Ada Lovelace'
o-cmds cmd run 2                 # names or displayed numbers: NAME|N
o-cmds                           # standalone TUI, selected on newest
o-cmds pick hello                # print a script without running it
o-cmds pick                      # choose a script in the TUI
o-cmds shell-init zsh            # print an optional current-shell helper
o-cmds mcp                       # serve add/list/show over stdio JSON-RPC

Use cmd add --file ./some-script.sh --name inspect --cwd /path/to/project to record a file and its working directory. o-cmds catalog prints the JSON catalog for mtm/nabe; o-cmds view --smoke renders one frame without a terminal. The demo tape records the header animation.

cmd list prints numbered columns: name, description, age, author. Numbers are positions in the current order; filtering preserves the unfiltered numbers. Names take precedence over numeric positions. Stable cmd/ID targets from JSON rows remain usable across renames and changes to the list.

Every command-targeting verb and MCP cmd_show also accepts a unique name prefix: cmd show play can select play-o-json-tutorials. Matching reuses oden's resolver, including its descendant rule: a prefix matching both play and play-tutorials selects play. Exact names and valid numbered positions take precedence. Ambiguous input prints the matching commands with their current list numbers and returns a failure; it never runs or changes a command.

The pinned oden v0.1.1 supports exact/prefix matching only. Dash-segment forms (p-o-j-t, pojt) and last-resort word fragments require a shared oden matcher extension; they are not implemented by a separate app matcher.

o-cmds cmd show 1
o-cmds cmd copy hello            # print the exact script bytes
o-cmds cmd copy hello --yank     # also copy to the clipboard
EDITOR='code --wait' o-cmds cmd edit hello
o-cmds cmd rename hello greeting
o-cmds cmd pin greeting          # show a star, keep chronological position
o-cmds cmd star greeting         # toggle the pin
o-cmds cmd unpin greeting
o-cmds cmd delete greeting       # hide; keep script and history
o-cmds cmd undo                  # restore the most recent change
o-cmds cmd path greeting         # script path
o-cmds cmd path                  # storage directory
o-cmds cmd list --filter deploy
o-cmds cmd list --json '{}'      # catalog rows, including script/metadata
o-cmds cmd list --format table   # framework table output
o-cmds cmd add --name report --script 'pwd' --tags '["work","daily"]'

Runs use sh SCRIPT ARG..., with the recorded cwd if present. Otherwise they inherit the caller's directory. Stdin, stdout and stderr stream directly, and the CLI returns the script's exit status. A missing recorded directory does not prevent saving; running reports the directory error. Script bytes are preserved, including when the script is empty or has no trailing newline.

The script itself is an ordinary editable file. edit checkpoints it before opening $EDITOR (default vi); the selected editor controls its own writing. Metadata changes commit immediately. undo restores the last rename, delete, edit checkpoint, or pin change, including the saved script bytes. It does not undo execution. If a restored name is occupied, restoration uses a suffix.

Storage is $XDG_DATA_HOME/o-cmds, default ~/.local/share/o-cmds. --data DIR overrides it; put global flags before the command. Each command has a <created-ts>-<slug>-<random-id>.sh and JSON sidecar with name, description, created time, author, optional cwd, tags and pin status. Script and metadata permissions are 0600; newly created storage/history directories are 0700. A file lock coordinates concurrent writers. .history holds undo snapshots. Deletion is a metadata flag; scripts are retained. An interrupted add that leaves only a script is still listed as unassociated. Failed atomic writes retain hidden .pending-* recovery files.

Author names default to owner. Agent additions use O_CMDS_AUTHOR, TUIOS_AGENT_NAME or AGENT_NAME; harness and pane/session fields come from TUIOS_HARNESS/AGENT_HARNESS, Codex/Claude markers and TUIOS identifiers. --author overrides the name. No environment file or credentials are read.

The TUI uses binding rows, with hints generated from the effective bindings. Default actions are Enter run, v view inside the TUI, y copy, e edit, d d delete, u undo, s star. / filters using ochazuke's list/search bindings; ? shows help; q quits standalone. Rebind or unbind these through ochazuke's bindings/config verbs. No keys are switched on in application code.

The right pane shows a compact name/description/author/age/cwd/tags header, then the script with line numbers. Indentation, spaces and blank lines remain visible; long lines wrap without removing spaces, and tabs display as four spaces. The stored script and copy/pick output keep their original bytes. ctrl+d / ctrl+u scroll the script eight display lines while the metadata stays put. Moving the list cursor updates the preview.

v opens a large read-only modal without leaving the TUI. Scroll with j / k, ctrl+d / ctrl+u, or g / G for the beginning/end; q or Escape returns to the list (also in pick mode). Scripts use plain terminal monospace. The view.detail=false setting hides the right pane; the viewer still works.

o cycles the existing list.order setting between oldest-first and newest-first, keeping the cursor on the same command. This uses ochazuke's setting-cycle verb and applies to the current session; persist your preferred default through the settings command. Default order is oldest-first, with the newest command at the bottom.

Optional shell convenience: o-cmds pick opens the same Commands page, with Enter choosing the script and exiting instead of running it. Escape cancels with non-zero status and no stdout. The UI renders on stderr, so stdout holds only the selected script. o-cmds pick NAME|NUMBER prints that script directly, using the same name/number resolver. Picking does not execute the script.

To evaluate selected commands in your current Zsh session, add this optional line to ~/.zshrc yourself:

eval "$(o-cmds shell-init zsh)"

For Bash, use eval "$(o-cmds shell-init bash)" in your shell startup file. This defines oc; --name changes the function name:

oc                          # pick, record in history, and evaluate here
oc hello                    # evaluate a named command directly
oc 2                        # evaluate a numbered command directly
eval "$(o-cmds shell-init zsh --name choose_command)"
choose_command hello        # use a different function name

The generated function calls o-cmds pick, records the chosen script in shell history, and evaluates it in the current shell, so cd and export persist. Cancellation returns the picker's status without evaluating or adding a history entry. Evaluation returns the script's status. The function preserves script text and trailing newlines; the shell's normal history settings control saving history to disk. It evaluates in the current directory; the stored cwd metadata applies to cmd run. Use a function name containing letters, digits and underscores, starting with a letter or underscore.

Shell initialization is entirely optional. o-cmds, cmd run, the standalone TUI and MCP work without it. shell-init only prints the function; it edits no dotfiles, installs no hooks, and needs o-cmds on PATH when the function runs.

o-cmds settings set list.order newest-first --yes
o-cmds settings set list.start-newest false --yes
o-cmds settings set view.detail false --yes
o-cmds settings set list.refresh 0s --yes

Defaults: list.order=oldest-first, list.start-newest=true, view.detail=true, list.refresh=2s. Zero refresh disables standalone polling for commands left by agents. Existing selection is preserved on reload. Settings use $XDG_CONFIG_HOME/o-cmds/settings.json; framework state uses $XDG_STATE_HOME/o-cmds. Restart the page after changing detail visibility or startup selection. Host page layout, refresh and initial selection are owned by the host; see integration limits.

MCP lets agents leave commands for the owner:

{
  "mcpServers": {
    "o-cmds": {"command": "/path/to/o-cmds", "args": ["mcp"]}
  }
}

The stdio server exposes exactly cmd_add, cmd_list, cmd_show. It has no cmd_run tool. cmd_add requires script (empty is valid), and accepts name, desc, cwd, tags and author. cmd_list takes optional filter; cmd_show takes target (a name, number as a string, or stable ID). MCP additions also stamp the initializing client's name when agent environment metadata is unavailable. Notifications receive no response; tool failures use MCP error content. Stdio uses newline-delimited JSON-RPC with initialize, ping, tools/list and tools/call.

Compared with Vim: / searches/filters and d d deletes the current item; u restores a change. Script view, execution and copy operate on whole command records. The detailed Vim comparison records differences.

Checks: make check runs gofmt validation, vet and the new app's Go tests; make test runs tests; make build builds locally. Builds set GOWORK=off, GOFLAGS='-trimpath -p=2' and GOMAXPROCS=3, under nice -n 15. Test temporary HOME/XDG paths are isolated; TEST_TMP defaults to /tmp/o-cmds-lane/tests.

Licensed under the MIT License.

Documentation

Overview

Command o-cmds records small scripts for the owner to inspect and run.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL