feat(pit): /alias — name the lines you keep retyping - #359
Merged
Conversation
The pit is a prompt people sit at all day, and the things they retype are
their own: `git status`, `pnpm -r test`, `/agents claude --resume`. Shell
aliases cannot help, because the pit is not a shell — and `!git status` is
exactly the keystrokes an alias is supposed to save.
/alias set gs "git status" → /gs, and /gs -sb appends
/alias set cx "/agents codex" → a pit command, not a shell one
/alias → what is defined
/alias rm gs
A value runs in $SHELL unless it starts with `/`, in which case it is a pit
command. Shell-by-default because that is what the prompt is mostly asked
for, and the leading slash is already how the pit spells its own verbs, so
the rule reads the same way the rest of the pit does.
An alias expands into a line that goes back through the top of the dispatch
loop rather than through a second copy of the dispatcher, which is what makes
`/gs -sb` append the way a shell alias does and lets one alias name another.
Expansion is bounded, so two aliases naming each other report a loop instead
of spinning the prompt.
Aliases are dispatched last, so they can never shadow a built-in — and
`/alias set` refuses a name the pit already owns (commands, engines and their
aliases, tools) rather than accepting a shortcut that would be silently dead.
The store is ~/.moshcode/aliases.json, owner-only for the same reason the
history file is: values are whatever was typed, and people alias commands
that carry tokens. A corrupt or hand-broken file reads as no aliases rather
than taking the prompt down.
Also teaches renderPitCommand the synopsis/examples/note shapes renderCommand
already reads, so a pit-only verb with sub-verbs can document itself; `/quit`
and friends are unchanged.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ThreatCrush Security Scan93 finding(s) HIGH/CRITICAL: 2 | MEDIUM: 43 | LOW: 48
…and 43 more. Full results in the Security tab. Snippets are redacted; ThreatCrush never prints matched credential material. |
Merged
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
/aliasin the pit: name a line you keep retyping, run it as/<name>.A value runs in
$SHELLunless it starts with/, in which case it is a pit command. Shell-by-default because that is what the prompt is mostly asked for, and the leading slash is already how the pit spells its own verbs.How
src/aliases.mjs— the store:~/.moshcode/aliases.json, owner-only for the same reason the history file is (values are whatever was typed, and people alias commands that carry tokens). A corrupt or hand-edited file reads as no aliases rather than taking the prompt down./gs -sbappend the way a shell alias does, and lets one alias name another. Expansion is bounded, so two aliases naming each other report a loop instead of spinning the prompt./alias setrefuses a name the pit already owns (pit commands, engines and their aliases —/ccis claude — and tools) rather than accepting a shortcut that would be silently dead.renderPitCommandlearned thesynopsis/examples/noteshapesrenderCommandalready reads, so a pit-only verb with sub-verbs documents itself./quitand friends render unchanged.Tests
test/aliases.test.mjs— 13 tests: set/run, argument append with quoting intact, pit-command values, persistence across sessions, all three reservation classes, unusable names, expansion loops, 0600 permissions, corrupt-file tolerance, list/get/rm, and the/help aliastext.Its harness feeds one command per prompt. That is not cosmetic: readline in non-terminal mode emits every buffered line at once and only the one a pending
questioncatches survives, so the existingstdin.end("/a\n/b\n/quit\n")style silently runs only the first command. Pre-existing behaviour, unchanged here — but it is why these tests could not be written the old way.Full suite: 1534 tests, 0 failures.
🤖 Generated with Claude Code