Help: consume CommandNode.help_id — REGISTRY-driven in-app help

Every CommandNode declared a help_id that nothing read; the in-app
`help` body was a single hand-kept catalog block that drifted from
the command set (handoff-12 §2.1).

note_help now iterates the command REGISTRY and translates each
CommandNode's help_id (`help.<id>`), framed by help.intro /
help.dsl_section / help.types_reference. A newly-registered command
appears in `help` automatically — no edit to note_help or a hand-kept
list. Added 20 per-command help entries plus the 3 framing entries;
removed help.in_app_body.

Per-command entries use block scalars: a libyml 0.0.5 scanner bug
panics on long internal space runs in double-quoted scalars, and the
entries are space-aligned.
This commit is contained in:
claude@clouddev1
2026-05-15 22:45:18 +00:00
parent f46606b12e
commit 03dd9003df
4 changed files with 139 additions and 56 deletions
+71 -40
View File
@@ -208,46 +208,77 @@ help:
import <zip> [as <t>] Unpack <zip> into a new project and
switch to it. <t> overrides the target
name (else taken from the zip).
# In-app `help` command output. Same shape as
# `cli_banner` — multi-line block, consumers iterate
# lines and emit each as its own output row so scroll
# math stays accurate.
in_app_body: |
Supported commands:
quit — exit
help — this list
mode simple|advanced — switch input mode
messages — show current verbosity
messages short|verbose— switch error wording (verbose is the default)
rebuild — rebuild .db from project.yaml + data/ (with confirmation)
save — save current temp project under a name
save as — copy current project to a new name/path
new — close current, start a fresh temp project
load — open the project picker
export [<path>] — write a zip of project.yaml + data/ (excludes .db, history.log)
import <zip> [as <t>] — unpack a zip and switch to the new project
DSL data commands (in simple mode):
create table <T> with pk [<col>:<type>...]
drop table <T>
add column [to] [table] <T>: <col> (<type>)
(for serial/shortid on a non-empty table: existing rows auto-filled)
drop column [from] [table] <T>: <col>
rename column [in] [table] <T>: <old> to <new>
change column [in] [table] <T>: <col> (<newtype>)
[--force-conversion | --dont-convert]
(to serial/shortid: null cells auto-filled with generated values)
add 1:n relationship [as <name>] from <P>.<col> to <C>.<col>
[on delete <action>] [on update <action>] [--create-fk]
drop relationship <name>
insert into <T> [(cols)] [values] (vals)
update <T> set <c>=<v>... where <c>=<v> | --all-rows
delete from <T> where <c>=<v> | --all-rows
show table <T>
show data <T>
replay <path> — run each non-blank, non-`#`-comment line
of <path> as a command. Stops at the first
error (no rollback). Relative paths resolve
under the current project's directory.
# In-app `help` command output (ADR-0024 §help_id). The
# renderer iterates the command REGISTRY and translates each
# CommandNode's `help_id` — so a newly-registered command
# appears in `help` automatically, with no edit here. `intro`
# and `dsl_section` frame the two command groups; each
# `app.*` / `ddl.*` / `data.*` entry is keyed by a command's
# `help_id`; `types_reference` closes the block. All entries
# are multi-line-capable — the renderer emits one output row
# per line so scroll math stays accurate.
intro: "Supported commands:"
dsl_section: "DSL data commands (in simple mode):"
# Per-command help, keyed by `CommandNode.help_id`. Block
# scalars (`|-`) so the column alignment survives — the
# double-quoted form trips a libyml scanner bug on long
# internal space runs. The renderer emits one output row per
# line, so multi-form commands list each form on its own line.
app:
quit: |-
quit — exit the app
help: |-
help — show this command list
rebuild: |-
rebuild — rebuild the project database from project.yaml + data/ (with confirmation)
save: |-
save — save the current temp project under a name
save as — copy the current project to a new name/path
new: |-
new — close the current project, start a fresh temp project
load: |-
load — open the project picker
export: |-
export [<path>] — write a zip of project.yaml + data/ (excludes the database file and history.log)
import: |-
import <zip> [as <target>] — unpack a zip into a new project and switch to it
mode: |-
mode simple|advanced — switch input mode
messages: |-
messages [short|verbose] — show or switch error-message verbosity (verbose is the default)
ddl:
create: |-
create table <T> with pk [<col>:<type>, ...] — create a table
drop: |-
drop table <T> — remove a table
drop column [from] [table] <T>: <col> — remove a column
drop relationship <name> — remove a relationship
add: |-
add column [to] [table] <T>: <col> (<type>) — add a column
(for serial/shortid on a non-empty table: existing rows auto-filled)
add 1:n relationship [as <name>] from <P>.<col> to <C>.<col>
[on delete <action>] [on update <action>] [--create-fk] — declare a relationship
rename: |-
rename column [in] [table] <T>: <old> to <new> — rename a column
change: |-
change column [in] [table] <T>: <col> (<newtype>) [--force-conversion | --dont-convert]
— change a column's type (to serial/shortid: null cells auto-filled with generated values)
data:
show: |-
show table <T> — show a table's structure
show data <T> — show a table's rows
insert: |-
insert into <T> [(cols)] [values] (vals) — add a row
update: |-
update <T> set <c>=<v>, ... where <c>=<v> | --all-rows — change matching rows
delete: |-
delete from <T> where <c>=<v> | --all-rows — remove matching rows
replay: |-
replay <path> — run each non-blank, non-`#`-comment line of <path>
as a command. Stops at the first error (no rollback);
relative paths resolve under the project directory.
# Type reference, appended after the command list.
types_reference: |
Types: text, int, real, decimal, bool, date, datetime, blob, serial, shortid
Auto-generated types (serial, shortid):
serial — integer that auto-fills with the next sequence value