Conversation
Asking moshcode how it works could change your repo. `moshcode prd --help`
parsed `--help` as the PRD's idea, so it published prd/NNNN---help.md,
committed it, and handed it to an engine to author — which is how PRD 0006
got its own filename. Four other commands answered --help with exit 1, two
wrote usage to stdout, and `moshcode bogus` dumped 127 lines to *stdout*,
polluting any pipe with a typo in it.
Underneath was one cause: nothing recognised --help, so every command's own
argument parser met it and improvised.
- Help is recognised before dispatch, at every depth, wherever the flag
sits among that level's arguments. No parser ever sees it, so no parser
can act on it. `prd --help` now prints usage and writes nothing; the
test spawns the real binary against a temp directory and asserts the
directory is untouched.
- Two boundaries it does not cross. `moshcode gh --help` still reaches
gh byte-for-byte, and `moshcode help gh` answers the wrapper question
instead. `moshcode run --help` is the runner's; after the filename it
belongs to the script's argv (PRD 0004 R13).
- One stream, one code: asked for → stdout, exit 0. A usage error → that
command's own block on stderr, exit 1, never the top-level wall.
- The 87-line template literal is deleted, not supplemented. It had
already drifted: `dns` and `version` were dispatchable, completable and
absent from it, as were every alias and most flags. Help now renders
from CORE_CLI_COMMANDS, which the dispatcher and shell completion
already share, so a verb that exists is documented by construction.
- A drift test scrapes `cmd === "…"` out of the dispatcher and fails when
a dispatched command has no schema entry — the same shape as the
existing completion drift test.
- The overview is 21 lines and wraps at 80 columns (was 127 lines, 28 of
them over-length). `--all` keeps the full text for people who grep it,
and `--json` is the better grep target: the whole model, for the
consumer that is now an agent shelling back in to learn the interface.
- A typo gets one line and a suggestion — `moshcode instal` → did you
mean install? — drawn from the same command set completion uses.
test/help-stream.test.mjs asserted the old contract (the full banner on
stderr for an unknown verb). Updated to the new one: the pointer to
`moshcode help` is what has to survive a typo, not the wall.
Deferred, and marked P1/P2 in the PRD: the pit's own /help (R12), the
README drift test (R13), moshscript verb help (R14), NO_COLOR (R15), and
completing help topics (R16).
1073 tests, 861 pass, 0 fail.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
vu1nz Security ReviewNOT RUN — Add |
This was referenced Aug 3, 2026
Merged
ralyodio
added a commit
that referenced
this pull request
Aug 3, 2026
#263) The tail of PRD 0006 — R14, R15, R16. R14. `moshcode help ask` answered "no help for ask". `ask()` is as much part of the interface as `moshcode prd`, but the vocabulary lives in a registry help had never been introduced to. Verbs now carry an optional `usage` — `ai(prompt, { engine })`, `ask(...prompt)` — and help renders it with the summary and a note that this one is called from a .mosh file, not a shell. `usage` stays optional, so a verb registered by a host that has not declared one still renders as `name(…)`. cliVerb() derives its own signature rather than repeating it twenty times: every CLI verb forwards its arguments to `moshcode <name>`, so adding a line to the vocabulary documents it. R15 turned out to be already true and is now nailed down. src/ui.mjs gates colour on `NO_COLOR == null && process.stdout.isTTY`, so both the CLI and the pit already emit plain text to a pipe. Three tests keep it that way, including one for the pit — which needs spawnSync rather than the execFile helper the rest of the file uses, because the pit reads stdin and execFile has no way to supply it. Nothing paginates. R16. `moshcode help <tab>` now completes topics, in all four shells. The list is what help itself accepts — commands, engines, tools and moshscript verbs — so tab-completion and help cannot disagree about what is answerable. A test asserts exactly that: every offered topic resolves. 1099 tests, 887 pass, 0 fail. That closes PRD 0006. R1–R16 are implemented across #257, #258, #260 and this. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
ralyodio
added a commit
that referenced
this pull request
Aug 3, 2026
…260) * docs: generate README's command table from the schema (PRD 0006 R13) The README described the CLI from memory. Nothing connected its command listings to the table the dispatcher actually reads, so a renamed verb stayed documented and a new one stayed invisible — the same drift that had already happened inside `moshcode help` itself. Generated rather than checked, which R13 offers as the alternative and is the better half of it: a checker tells you the README is wrong, a generator makes it right. `moshcode help --markdown` emits the table, and it goes between markers in README.md exactly like the PRD index this repo already maintains, so the convention is one people here already know. Three tests, in both directions: - the table is regenerated and compared, so adding a verb without regenerating fails with the command that fixes it; - every command named in the table resolves in the schema; - every `moshcode <verb>` invoked in a fenced code block anywhere in the README is a real command, engine or tool. Scoped to fenced blocks because the prose also contains sentences like "moshcode warns you", and a grep that cannot tell those apart is a test nobody trusts. Verified the guard bites: adding a command to the schema without regenerating fails the suite, and the failure names `moshcode help --markdown` as the fix. 1089 tests, 877 pass, 0 fail. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat(help): moshscript verbs, terminal manners, and completable topics (#263) The tail of PRD 0006 — R14, R15, R16. R14. `moshcode help ask` answered "no help for ask". `ask()` is as much part of the interface as `moshcode prd`, but the vocabulary lives in a registry help had never been introduced to. Verbs now carry an optional `usage` — `ai(prompt, { engine })`, `ask(...prompt)` — and help renders it with the summary and a note that this one is called from a .mosh file, not a shell. `usage` stays optional, so a verb registered by a host that has not declared one still renders as `name(…)`. cliVerb() derives its own signature rather than repeating it twenty times: every CLI verb forwards its arguments to `moshcode <name>`, so adding a line to the vocabulary documents it. R15 turned out to be already true and is now nailed down. src/ui.mjs gates colour on `NO_COLOR == null && process.stdout.isTTY`, so both the CLI and the pit already emit plain text to a pipe. Three tests keep it that way, including one for the pit — which needs spawnSync rather than the execFile helper the rest of the file uses, because the pit reads stdin and execFile has no way to supply it. Nothing paginates. R16. `moshcode help <tab>` now completes topics, in all four shells. The list is what help itself accepts — commands, engines, tools and moshscript verbs — so tab-completion and help cannot disagree about what is answerable. A test asserts exactly that: every offered topic resolves. 1099 tests, 887 pass, 0 fail. That closes PRD 0006. R1–R16 are implemented across #257, #258, #260 and this. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Implements PRD 0006 (included in this PR as
prd/0006-help.md— it was sitting untracked in the working copy, and its0005collided with the hosted-resolver PRD that landed meanwhile).The bug worth leading with
moshcode prd --helppublished a document.--helpwas parsed as the PRD's idea, so asking how the command worked ran it: wroteprd/NNNN---help.md, committed it, and handed it to an engine to author. That is literally how PRD 0006's own file got its name.It wasn't alone.
run/mcp/skill/completionanswered--helpwith exit 1;consoleandinstallwrote usage to stderr;commandsignored the flag;moshcode bogusdumped 127 lines to stdout, polluting any pipe with a typo in it.One cause underneath all of it: nothing recognised
--help, so every command's own argument parser met it and improvised.What changed
Help is recognised before dispatch, at every depth, wherever the flag sits among that level's args. No parser ever sees it, so none of them can act on it.
Two boundaries it deliberately doesn't cross:
moshcode gh --helpstill reachesghbyte-for-byte;moshcode help ghanswers the wrapper question instead.moshcode run --helpis the runner's. After the filename,--helpis the script'sargv(PRD 0004 R13).One stream, one code. Asked for → stdout, exit 0. Usage error → that command's own block on stderr, exit 1, never the top-level wall.
The 87-line template literal is deleted, not supplemented. It had already drifted —
dnsandversionwere dispatchable, completable, and absent from it, as were every alias and most flags. Help now renders fromCORE_CLI_COMMANDS, which the dispatcher and shell completion already share, so a verb that exists is documented by construction. A drift test scrapescmd === "…"out of the dispatcher and fails when a dispatched command has no schema entry — same shape as the existing completion drift test.Fits a screen. 21 lines, wrapped at 80 columns (was 127 lines, 28 over-length).
--allkeeps the full text for people who grep it.--jsonis the better grep target and the real point: the whole model, for the consumer that is now an agent shelling back in to learn the interface.Typos get one line:
moshcode instal→did you mean install?, drawn from the same command set completion uses so the two can't disagree.Before / after
One deliberate contract change
test/help-stream.test.mjsasserted the old behaviour — the full banner on stderr for an unknown verb. R11 replaces that with one line and a pointer, so I updated the assertion: what has to survive a typo is the way forward, not the wall. The test still enforces exit≠0, clean stdout, and now a ≤3-line stderr.Deferred
Marked P1/P2 in the PRD and not attempted here: the pit's own
/help(R12), the README drift test (R13), moshscript verb help (R14),NO_COLOR(R15), completing help topics (R16).Tests
22 new in
test/help.test.mjs, including the no-side-effect ones that spawn the real binary against a temp directory — the bug was in dispatch, so dispatch is what gets exercised.Full suite: 1073 tests, 861 pass, 0 fail (212 skipped — the pre-existing environment-dependent ones).
🤖 Generated with Claude Code