install: wire a tool's pit aliases into installing it - #431
Merged
Conversation
Several tools in the roster ship a set of commands rather than one binary, and propose short words for them at the pit prompt. Until now the only way to get those words was to let the tool write ~/.moshcode/aliases.json itself — a config it does not own, and the same objection that keeps `railway setup agent` out of /install. So the tool proposes and the pit disposes. A tool declares an `aliases` spec in TOOLS; `/alias install <tool>` runs it, reads the JSON, and merges it. Declared rather than probed: `aliases --json` guessed at every installed CLI would eventually hit one where those words mean something else. A name the operator bound themselves always wins and is named in the report rather than silently kept — theirs and the tool's suggestion are both plausible, and the pit's own aliases carry flags (--orgs, --apply) that a generic suggestion knows nothing about. Names that collide with a pit command, engine, or tool are refused for the reason /alias set refuses them: built-ins resolve first, so such an alias would be dead on arrival. Its own verb rather than a step inside /install, because writing the operator's aliases is a side effect an install command has no business having — and a roster is worth adopting long after the day a tool was installed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ThreatCrush Security Scan3 finding(s) in the 6 file(s) this pull request changes. MEDIUM: 3
52 pre-existing finding(s) elsewhere in the repository — **HIGH/CRITICAL**: 5 | **MEDIUM**: 41 | **LOW**: 6Not introduced by this pull request. The full set is in the Security tab.
…and 32 more. Full results in the Security tab. Snippets are redacted; ThreatCrush never prints matched credential material. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Installing a workflow tool now configures it.
cli-toolsships seven commands behind one dispatcher, and none of them are reachable from the pit until the words that reach them exist — so/installsets those up:/upgradedoes the same, because an upgrade is where a tool gains commands. That is exactly how cli-tools' owngenerate-namesshipped in their #11 and never reached anybody's prompt.moshcode install <tool>from the CLI does it too, in plain text./alias install <tool> | --allre-runs it on demand, for tools installed before this existed./tools install <name>also routes to the installer now, instead of answeringunknown tool "install"— it's the obvious spelling right after/toolsprints the roster.How
aliasesspec inTOOLS(cli-tools→cli-tools aliases --json). Declared, not probed —aliases --jsonguessed at every installed CLI would eventually hit one where those words mean something else.readToolAliasescaptures and validates. Every failure (not installed, non-zero exit, not JSON, not an object) is a returned reason, never a throw.stdinisignoreso a tool that decides to ask a question can't hang the pit on an invisible prompt.mergeAliasesdoes the write. A name you bound yourself always wins — your/prsmay carry--orgsflags a generic suggestion knows nothing about. Names colliding with a pit command/engine/tool are refused for the reasonsetAliasrefuses them: built-ins resolve first, so such an alias would be dead on arrival. Capped at 64.Tests
20 in
test/alias-install.test.mjs: parse/failure modes with an injected runner, the undeclared-tool path asserting nothing is executed on a guess, merge semantics (existing wins, reserved refused, unusable values refused, cap + drop), the post-install line builder including a real binary reached overPATH,/tools installrouting, and six end-to-end pit runs.Two pre-existing problems in
test/tools.test.mjsthat this surfaced, both fixed:$HOME, so a successful install in the suite could write the aliases of whoever ran it.Full suite green: 2324 tests, 0 fail.
🤖 Generated with Claude Code