@fnndsc/brasa 0.38.2 → 0.40.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"hash":"86ecd2"}
1
+ {"hash":"bd5de9"}
@@ -0,0 +1,70 @@
1
+ import { type CommandEnvelope } from '@fnndsc/menu';
2
+ /** One entry the walk visits. */
3
+ export interface FindNode {
4
+ /** The path as printed (relative to how its starting point was typed). */
5
+ shown: string;
6
+ /** The entry's own name. */
7
+ name: string;
8
+ /** `d` a folder (any kind the namespace lists into), `l` a link, `f` anything else. */
9
+ type: 'f' | 'd' | 'l';
10
+ /** ISO date, when the listing carries one. */
11
+ date?: string;
12
+ /** Levels below its starting point. */
13
+ depth: number;
14
+ }
15
+ /** A parsed expression. */
16
+ export type FindExpr = {
17
+ kind: 'and' | 'or';
18
+ left: FindExpr;
19
+ right: FindExpr;
20
+ } | {
21
+ kind: 'not';
22
+ operand: FindExpr;
23
+ } | {
24
+ kind: 'test';
25
+ test: (node: FindNode) => boolean;
26
+ } | {
27
+ kind: 'print';
28
+ separator: string;
29
+ };
30
+ /** What the command line asks for. */
31
+ export interface FindQuery {
32
+ starts: string[];
33
+ expr: FindExpr;
34
+ maxdepth: number;
35
+ mindepth: number;
36
+ /** Whether the expression names an action; without one, every match is printed. */
37
+ acts: boolean;
38
+ }
39
+ /**
40
+ * A shell pattern as a regular expression, the way `find` matches it: `*`
41
+ * any run of characters (a `/` included), `?` one, `[...]` a class.
42
+ *
43
+ * @param pattern - The pattern.
44
+ * @param ignoreCase - Whether case is ignored.
45
+ * @returns The expression, anchored at both ends.
46
+ */
47
+ export declare function pattern_toRegExp(pattern: string, ignoreCase?: boolean): RegExp;
48
+ /**
49
+ * Parses `find`'s arguments.
50
+ *
51
+ * @param args - The words after `find`.
52
+ * @returns The query, or the refusal to say.
53
+ */
54
+ export declare function find_parse(args: string[]): FindQuery | string;
55
+ /**
56
+ * Evaluates an expression on one entry, printing as its actions say.
57
+ *
58
+ * @param expr - The expression.
59
+ * @param node - The entry.
60
+ * @param out - Where printed paths go.
61
+ * @returns Whether the expression is true for the entry.
62
+ */
63
+ export declare function find_evaluate(expr: FindExpr, node: FindNode, out: string[]): boolean;
64
+ /**
65
+ * `find [path...] [expression]`.
66
+ *
67
+ * @param args - The words after `find`.
68
+ * @returns The selected paths, and why any part of the walk failed.
69
+ */
70
+ export declare function builtin_find(args: string[]): Promise<CommandEnvelope>;
@@ -0,0 +1,323 @@
1
+ /**
2
+ * @file `find`: walk the namespace and print the paths an expression selects.
3
+ *
4
+ * POSIX's form: starting points first (`.` when none), then an expression of
5
+ * tests and actions joined by implicit AND, `-o`, `!`/`-not` and parentheses.
6
+ * The walk reads every folder through the listing cache (`vfs.listing_get`),
7
+ * the same listings `ls` reads, so a tree already seen is walked without a
8
+ * word to CUBE; only a folder never listed, or one whose listing expired, is
9
+ * fetched. Links are not followed (POSIX's default). A long walk says how far
10
+ * it has got, and Ctrl-C stops it, saying where; a folder that cannot be read
11
+ * is named and the command fails, as POSIX `find` does, without stopping the
12
+ * walk.
13
+ *
14
+ * Tests: `-name`, `-iname`, `-path`, `-ipath` (shell patterns, `*` crossing `/`
15
+ * in a path), `-type f|d|l`, `-newermt DATE`; options `-maxdepth N`,
16
+ * `-mindepth N`; actions `-print` (the default) and `-print0`. Anything else
17
+ * is refused by name.
18
+ *
19
+ * @module
20
+ */
21
+ import chalk from 'chalk';
22
+ import path from 'path';
23
+ import { path_resolve } from '../utils.js';
24
+ import { vfs } from '../../lib/vfs/vfs.js';
25
+ import { spinner } from '../../lib/spinner.js';
26
+ import { commandCancellation_enable, commandCancellation_signalGet } from '../../core/cancellation.js';
27
+ import { errorStack } from '@fnndsc/fond';
28
+ import { envelope_error } from '@fnndsc/menu';
29
+ /** How long a walk runs before it says how far it has got. */
30
+ const PROGRESS_AFTER_MS = 1500;
31
+ /** Listing types the namespace descends into. */
32
+ const FOLDER_TYPES = new Set(['dir', 'vfs', 'job']);
33
+ /**
34
+ * A shell pattern as a regular expression, the way `find` matches it: `*`
35
+ * any run of characters (a `/` included), `?` one, `[...]` a class.
36
+ *
37
+ * @param pattern - The pattern.
38
+ * @param ignoreCase - Whether case is ignored.
39
+ * @returns The expression, anchored at both ends.
40
+ */
41
+ export function pattern_toRegExp(pattern, ignoreCase = false) {
42
+ let source = '';
43
+ for (let i = 0; i < pattern.length; i++) {
44
+ const ch = pattern[i];
45
+ if (ch === '*')
46
+ source += '.*';
47
+ else if (ch === '?')
48
+ source += '.';
49
+ else if (ch === '[') {
50
+ const close = pattern.indexOf(']', i + 2);
51
+ if (close === -1) {
52
+ source += '\\[';
53
+ continue;
54
+ }
55
+ const body = pattern.slice(i + 1, close).replace(/^!/, '^').replace(/\\/g, '\\\\');
56
+ source += `[${body}]`;
57
+ i = close;
58
+ }
59
+ else if (ch === '\\' && i + 1 < pattern.length) {
60
+ source += pattern[++i].replace(/[.*+?^${}()|[\]\\/]/g, '\\$&');
61
+ }
62
+ else
63
+ source += ch.replace(/[.*+?^${}()|[\]\\/]/g, '\\$&');
64
+ }
65
+ return new RegExp(`^${source}$`, ignoreCase ? 'i' : '');
66
+ }
67
+ /**
68
+ * Parses `find`'s arguments.
69
+ *
70
+ * @param args - The words after `find`.
71
+ * @returns The query, or the refusal to say.
72
+ */
73
+ export function find_parse(args) {
74
+ const starts = [];
75
+ let i = 0;
76
+ while (i < args.length && !/^[-!(]/.test(args[i]))
77
+ starts.push(args[i++]);
78
+ if (starts.length === 0)
79
+ starts.push('.');
80
+ const words = args.slice(i);
81
+ let at = 0;
82
+ let maxdepth = Number.POSITIVE_INFINITY;
83
+ let mindepth = 0;
84
+ let acts = false;
85
+ const argument = (predicate) => {
86
+ const value = words[++at];
87
+ if (value === undefined)
88
+ throw new Error(`find: ${predicate} needs an argument`);
89
+ return value;
90
+ };
91
+ const depth = (predicate) => {
92
+ const value = argument(predicate);
93
+ if (!/^\d+$/.test(value))
94
+ throw new Error(`find: ${predicate} takes a number, not '${value}'`);
95
+ return Number(value);
96
+ };
97
+ const primary = () => {
98
+ const word = words[at];
99
+ if (word === undefined)
100
+ throw new Error('find: an expression ends where a test was expected');
101
+ if (word === '(') {
102
+ at++;
103
+ const inner = or();
104
+ if (words[at] !== ')')
105
+ throw new Error("find: a '(' is not closed");
106
+ at++;
107
+ return inner;
108
+ }
109
+ let expr;
110
+ switch (word) {
111
+ case '-name':
112
+ case '-iname': {
113
+ const re = pattern_toRegExp(argument(word), word === '-iname');
114
+ expr = { kind: 'test', test: (node) => re.test(node.name) };
115
+ break;
116
+ }
117
+ case '-path':
118
+ case '-ipath':
119
+ case '-wholename': {
120
+ const re = pattern_toRegExp(argument(word), word === '-ipath');
121
+ expr = { kind: 'test', test: (node) => re.test(node.shown) };
122
+ break;
123
+ }
124
+ case '-type': {
125
+ const kind = argument(word);
126
+ if (!['f', 'd', 'l'].includes(kind))
127
+ throw new Error(`find: -type takes f, d or l, not '${kind}'`);
128
+ expr = { kind: 'test', test: (node) => node.type === kind };
129
+ break;
130
+ }
131
+ case '-newermt': {
132
+ const when = argument(word);
133
+ const time = Date.parse(when);
134
+ if (Number.isNaN(time))
135
+ throw new Error(`find: -newermt takes a date, not '${when}'`);
136
+ expr = { kind: 'test', test: (node) => node.date !== undefined && Date.parse(node.date) > time };
137
+ break;
138
+ }
139
+ case '-maxdepth':
140
+ maxdepth = depth(word);
141
+ expr = { kind: 'test', test: () => true };
142
+ break;
143
+ case '-mindepth':
144
+ mindepth = depth(word);
145
+ expr = { kind: 'test', test: () => true };
146
+ break;
147
+ case '-true':
148
+ expr = { kind: 'test', test: () => true };
149
+ break;
150
+ case '-false':
151
+ expr = { kind: 'test', test: () => false };
152
+ break;
153
+ case '-print':
154
+ acts = true;
155
+ expr = { kind: 'print', separator: '\n' };
156
+ break;
157
+ case '-print0':
158
+ acts = true;
159
+ expr = { kind: 'print', separator: '\0' };
160
+ break;
161
+ default: throw new Error(`find: unknown predicate '${word}'`);
162
+ }
163
+ at++;
164
+ return expr;
165
+ };
166
+ const not = () => {
167
+ if (words[at] === '!' || words[at] === '-not') {
168
+ at++;
169
+ return { kind: 'not', operand: not() };
170
+ }
171
+ return primary();
172
+ };
173
+ const and = () => {
174
+ let left = not();
175
+ while (at < words.length && words[at] !== '-o' && words[at] !== '-or' && words[at] !== ')') {
176
+ if (words[at] === '-a' || words[at] === '-and')
177
+ at++;
178
+ left = { kind: 'and', left, right: not() };
179
+ }
180
+ return left;
181
+ };
182
+ const or = () => {
183
+ let left = and();
184
+ while (words[at] === '-o' || words[at] === '-or') {
185
+ at++;
186
+ left = { kind: 'or', left, right: and() };
187
+ }
188
+ return left;
189
+ };
190
+ try {
191
+ const expr = words.length === 0 ? { kind: 'test', test: () => true } : or();
192
+ if (at < words.length)
193
+ return `find: unexpected '${words[at]}'`;
194
+ return { starts, expr, maxdepth, mindepth, acts };
195
+ }
196
+ catch (error) {
197
+ return error instanceof Error ? error.message : String(error);
198
+ }
199
+ }
200
+ /**
201
+ * Evaluates an expression on one entry, printing as its actions say.
202
+ *
203
+ * @param expr - The expression.
204
+ * @param node - The entry.
205
+ * @param out - Where printed paths go.
206
+ * @returns Whether the expression is true for the entry.
207
+ */
208
+ export function find_evaluate(expr, node, out) {
209
+ switch (expr.kind) {
210
+ case 'and': return find_evaluate(expr.left, node, out) && find_evaluate(expr.right, node, out);
211
+ case 'or': return find_evaluate(expr.left, node, out) || find_evaluate(expr.right, node, out);
212
+ case 'not': return !find_evaluate(expr.operand, node, out);
213
+ case 'test': return expr.test(node);
214
+ case 'print':
215
+ out.push(node.shown + expr.separator);
216
+ return true;
217
+ }
218
+ }
219
+ /** An entry's kind, as `-type` names it. */
220
+ function type_of(item) {
221
+ if (item.type === 'link')
222
+ return 'l';
223
+ return FOLDER_TYPES.has(item.type) ? 'd' : 'f';
224
+ }
225
+ /**
226
+ * `find [path...] [expression]`.
227
+ *
228
+ * @param args - The words after `find`.
229
+ * @returns The selected paths, and why any part of the walk failed.
230
+ */
231
+ export async function builtin_find(args) {
232
+ const query = find_parse(args);
233
+ if (typeof query === 'string') {
234
+ process.exitCode = 1;
235
+ return envelope_error('', undefined, `${chalk.red(query)}\n`);
236
+ }
237
+ commandCancellation_enable();
238
+ const signal = commandCancellation_signalGet();
239
+ const out = [];
240
+ let failures = '';
241
+ let folders = 0;
242
+ let found = 0;
243
+ const startedAt = Date.now();
244
+ let announced = false;
245
+ const progress = () => {
246
+ if (Date.now() - startedAt < PROGRESS_AFTER_MS)
247
+ return;
248
+ const words = `find: ${folders} folder${folders === 1 ? '' : 's'} walked, ${found} found`;
249
+ if (announced)
250
+ spinner.updateMessage(words);
251
+ else {
252
+ spinner.start(words);
253
+ announced = true;
254
+ }
255
+ };
256
+ const visit = (node) => {
257
+ if (node.depth < query.mindepth)
258
+ return;
259
+ const before = out.length;
260
+ const matched = find_evaluate(query.expr, node, out);
261
+ if (!query.acts && matched)
262
+ out.push(`${node.shown}\n`);
263
+ if (out.length > before)
264
+ found++;
265
+ };
266
+ try {
267
+ for (const start of query.starts) {
268
+ const resolved = await path_resolve(start);
269
+ const shownRoot = start.startsWith('~') ? resolved : start;
270
+ const self = await vfs.listing_get(resolved, { directory: true });
271
+ const entry = self.ok ? self.value.items[0] : undefined;
272
+ if (entry === undefined) {
273
+ errorStack.stack_pop();
274
+ failures += `find: '${start}': No such file or directory\n`;
275
+ continue;
276
+ }
277
+ const rootType = type_of(entry);
278
+ visit({ shown: shownRoot, name: path.posix.basename(resolved) || resolved, type: rootType, date: entry.date || undefined, depth: 0 });
279
+ if (rootType !== 'd')
280
+ continue;
281
+ // Depth first, in listing order: an entry, then everything beneath it.
282
+ const walk = async (real, shown, depth) => {
283
+ if (signal?.aborted)
284
+ return false;
285
+ if (depth >= query.maxdepth)
286
+ return true;
287
+ const listed = await vfs.listing_get(real);
288
+ folders++;
289
+ progress();
290
+ if (!listed.ok) {
291
+ const why = errorStack.stack_pop()?.message ?? 'cannot be read';
292
+ failures += `find: '${shown}': ${why}\n`;
293
+ return true;
294
+ }
295
+ for (const item of listed.value.items) {
296
+ const node = {
297
+ shown: shown === '/' ? `/${item.name}` : `${shown}/${item.name}`,
298
+ name: item.name,
299
+ type: type_of(item),
300
+ date: item.date || undefined,
301
+ depth: depth + 1,
302
+ };
303
+ visit(node);
304
+ if (node.type === 'd' && !(await walk(path.posix.join(real, item.name), node.shown, node.depth)))
305
+ return false;
306
+ }
307
+ return true;
308
+ };
309
+ if (!(await walk(resolved, shownRoot, 0))) {
310
+ failures += `find: stopped (Ctrl-C) after ${folders} folders; ${found} found so far\n`;
311
+ break;
312
+ }
313
+ }
314
+ }
315
+ finally {
316
+ if (announced)
317
+ spinner.stop();
318
+ }
319
+ if (failures !== '')
320
+ process.exitCode = 1;
321
+ return { status: failures === '' ? 'ok' : 'error', rendered: out.join(''), renderedErr: failures === '' ? undefined : chalk.red(failures) };
322
+ }
323
+ //# sourceMappingURL=find.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find.js","sourceRoot":"","sources":["../../../src/builtins/fs/find.ts"],"names":[],"mappings":"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"}
@@ -21,7 +21,7 @@ export declare function builtin_cmatrix(args: string[]): Promise<CommandEnvelope
21
21
  export declare function builtin_rain(args: string[]): Promise<CommandEnvelope>;
22
22
  /** `asciiquarium`: fish. */
23
23
  export declare function builtin_asciiquarium(args: string[]): Promise<CommandEnvelope>;
24
- /** `tetris`: falling blocks, in ARGUS. */
24
+ /** `tetris`: falling blocks. */
25
25
  export declare function builtin_tetris(args: string[]): Promise<CommandEnvelope>;
26
- /** `snake`: the snake, in ARGUS. */
26
+ /** `snake`: the snake. */
27
27
  export declare function builtin_snake(args: string[]): Promise<CommandEnvelope>;
@@ -2,15 +2,16 @@
2
2
  * @file The showpieces — `sl`, `cmatrix`, `rain`, `asciiquarium` — and the
3
3
  * arcade: `tetris`, `snake`.
4
4
  *
5
- * Each is a program a surface with a canvas runs: ARGUS opens its GAMES
6
- * pane on the `games.show` model and draws. The console gets the text: a
7
- * still of the show, or the words that there is nothing to play here and
8
- * where there is.
5
+ * Each is a program on a cell grid (`@fnndsc/menu/games`). A terminal
6
+ * plays it in place: chell takes the screen on the `games.show` model, and
7
+ * gives it back on q, Esc or Ctrl-C. `--pane` asks ARGUS to draw it in its
8
+ * GAMES pane instead, as the deprecated transcript console always does.
9
+ * Every surface also gets the text: a still of the show, and how to play it.
9
10
  *
10
11
  * @module
11
12
  */
12
13
  import chalk from 'chalk';
13
- import { envelope_ok } from '@fnndsc/menu';
14
+ import { envelope_ok, envelope_error } from '@fnndsc/menu';
14
15
  /**
15
16
  * The starship `sl` sends across the screen (a typo's punishment, as the
16
17
  * train was): the Constitution-class refit, side view, from the Star Trek
@@ -50,15 +51,20 @@ export function still_of(program, random = Math.random) {
50
51
  case 'snake': return [' . . . . . . . .', ' . @ o o o . . .', ' . . . . o . . .', ' . . * . . . . .'];
51
52
  }
52
53
  }
53
- /** What the console says beside a still: where the moving one is. */
54
- function note_of(program, arcade) {
55
- return arcade
56
- ? chalk.gray(`${program} plays in ARGUS: type it there and the GAMES pane opens with the keys live (arrows; Esc gives the keyboard back).`)
57
- : chalk.gray(`a still; ARGUS draws ${program} moving in its GAMES pane.`);
54
+ /** What the console says beside a still: how the moving one is played. */
55
+ function note_of(program, arcade, pane) {
56
+ if (pane)
57
+ return chalk.gray(`${program}: ARGUS draws it in its GAMES pane${arcade ? ' with the keys live (arrows; Esc gives the keyboard back)' : ''}.`);
58
+ return chalk.gray(`${program}: a terminal plays it in place${arcade ? ' (arrows steer)' : ''}; q, Esc or Ctrl-C leaves. --pane draws it in ARGUS's GAMES pane.`);
58
59
  }
59
60
  function show_run(program, args, arcade) {
61
+ const unknown = args.find((arg) => arg.startsWith('-') && arg !== '--pane');
62
+ if (unknown !== undefined)
63
+ return envelope_error(`${program}: unknown option '${unknown}' (--pane)\n`);
64
+ const pane = args.includes('--pane');
65
+ const rest = args.filter((arg) => arg !== '--pane');
60
66
  const still = still_of(program);
61
- return envelope_ok(`${still.join('\n')}\n${note_of(program, arcade)}\n`, { kind: 'games.show', data: { program, args, arcade } });
67
+ return envelope_ok(`${still.join('\n')}\n${note_of(program, arcade, pane)}\n`, { kind: 'games.show', data: { program, args: rest, arcade, pane } });
62
68
  }
63
69
  /** `sl`: a starship crosses the screen. */
64
70
  export async function builtin_sl(args) { return show_run('sl', args, false); }
@@ -68,8 +74,8 @@ export async function builtin_cmatrix(args) { return show_run('cmatrix', args, f
68
74
  export async function builtin_rain(args) { return show_run('rain', args, false); }
69
75
  /** `asciiquarium`: fish. */
70
76
  export async function builtin_asciiquarium(args) { return show_run('aquarium', args, false); }
71
- /** `tetris`: falling blocks, in ARGUS. */
77
+ /** `tetris`: falling blocks. */
72
78
  export async function builtin_tetris(args) { return show_run('tetris', args, true); }
73
- /** `snake`: the snake, in ARGUS. */
79
+ /** `snake`: the snake. */
74
80
  export async function builtin_snake(args) { return show_run('snake', args, true); }
75
81
  //# sourceMappingURL=show.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"show.js","sourceRoot":"","sources":["../../../src/builtins/games/show.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"show.js","sourceRoot":"","sources":["../../../src/builtins/games/show.ts"],"names":[],"mappings":"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"}
@@ -162,6 +162,21 @@ export const helpText = {
162
162
  '# /home/chris/feeds/Brain MRI Analysis/dircopy v2.1.1/data',
163
163
  ],
164
164
  },
165
+ find: {
166
+ posix: { group: 'Files', differs: 'walks the namespace through the listing cache; links are not followed' },
167
+ category: 'Navigation',
168
+ usage: 'find [path...] [expression]',
169
+ description: 'Walk from each path (. when none) and print the paths the expression selects. Tests and actions join by implicit AND, -o, ! (or -not) and parentheses. Folders are read from the listing cache, so a tree already seen is walked without asking CUBE. A long walk says how far it has got; Ctrl-C stops it and says where.',
170
+ options: [
171
+ '-name PATTERN, -iname PATTERN The entry\'s name matches a shell pattern (-iname ignores case)',
172
+ '-path PATTERN, -ipath PATTERN The printed path matches; * crosses /',
173
+ '-type f|d|l A file, a folder, a link',
174
+ '-newermt DATE Changed after DATE (2026-10-10, or an ISO time)',
175
+ '-maxdepth N, -mindepth N Descend at most N levels; test only from level N',
176
+ '-print, -print0 Print the path (the default), or end it with NUL',
177
+ ],
178
+ examples: ["find ~ -name '*.nii'", 'find ~/feeds -maxdepth 2 -type d', "find . -name '*.json' -o -name '*.csv'", "find /proc/jobs -maxdepth 1 -newermt 2026-10-10"],
179
+ },
165
180
  cat: {
166
181
  posix: { group: 'Files', differs: 'reads CFS files (and a pipe)' },
167
182
  category: 'Files',
@@ -502,39 +517,39 @@ export const helpText = {
502
517
  examples: ['stopwatch start', 'stopwatch lap', 'stopwatch', 'stopwatch stop'],
503
518
  },
504
519
  sl: {
505
- usage: 'sl',
520
+ usage: 'sl [--pane]',
506
521
  summary: 'A starship crosses the screen (the punishment for mistyping ls)',
507
- description: 'The train of old, refitted: in ARGUS the GAMES pane opens and a starship glides across it; a console with no canvas gets a still of it.',
508
- examples: ['sl'],
522
+ description: 'The train of old, refitted: a starship glides across the terminal. q, Esc or Ctrl-C gives the screen back. --pane draws it in ARGUS\'s GAMES pane instead (the transcript console always does).',
523
+ examples: ['sl', 'sl --pane'],
509
524
  },
510
525
  cmatrix: {
511
- usage: 'cmatrix',
526
+ usage: 'cmatrix [--pane]',
512
527
  summary: 'The glyph rain',
513
- description: 'Columns of glyphs falling in ARGUS\'s GAMES pane; a console with no canvas gets one frame of it.',
514
- examples: ['cmatrix'],
528
+ description: 'Columns of glyphs falling down the terminal. q, Esc or Ctrl-C gives the screen back. --pane draws it in ARGUS\'s GAMES pane instead (the transcript console always does).',
529
+ examples: ['cmatrix', 'cmatrix --pane'],
515
530
  },
516
531
  rain: {
517
- usage: 'rain',
532
+ usage: 'rain [--pane]',
518
533
  summary: 'Rain',
519
- description: 'Drops falling and ringing out on the floor in ARGUS\'s GAMES pane; a console with no canvas gets one frame of it.',
534
+ description: 'Drops falling and ringing out on the floor of the terminal. q, Esc or Ctrl-C gives the screen back. --pane draws it in ARGUS\'s GAMES pane instead (the transcript console always does).',
520
535
  examples: ['rain'],
521
536
  },
522
537
  asciiquarium: {
523
- usage: 'asciiquarium',
538
+ usage: 'asciiquarium [--pane]',
524
539
  summary: 'An aquarium: fish, weed, bubbles',
525
- description: 'Fish swimming both ways, weed swaying, bubbles rising, in ARGUS\'s GAMES pane; a console with no canvas gets a still.',
540
+ description: 'Fish swimming both ways, weed swaying, bubbles rising, in the terminal. q, Esc or Ctrl-C gives the screen back. --pane draws it in ARGUS\'s GAMES pane instead (the transcript console always does).',
526
541
  examples: ['asciiquarium'],
527
542
  },
528
543
  tetris: {
529
- usage: 'tetris',
530
- summary: 'Falling blocks (in ARGUS)',
531
- description: 'Played in ARGUS\'s GAMES pane: left/right move, up rotates, down drops, Esc gives the keyboard back. A terminal gets a still and the words that the game lives in ARGUS.',
532
- examples: ['tetris'],
544
+ usage: 'tetris [--pane]',
545
+ summary: 'Falling blocks',
546
+ description: 'Played in the terminal: left/right move, up rotates, down drops. q, Esc or Ctrl-C gives the screen back. --pane draws it in ARGUS\'s GAMES pane instead (the transcript console always does).',
547
+ examples: ['tetris', 'tetris --pane'],
533
548
  },
534
549
  snake: {
535
- usage: 'snake',
536
- summary: 'The snake (in ARGUS)',
537
- description: 'Played in ARGUS\'s GAMES pane: arrows steer, eat the food, do not eat yourself. A terminal gets a still and the words that the game lives in ARGUS.',
550
+ usage: 'snake [--pane]',
551
+ summary: 'The snake',
552
+ description: 'Played in the terminal: arrows (or hjkl, wasd) steer; eat the food, do not eat yourself. q, Esc or Ctrl-C gives the screen back. --pane draws it in ARGUS\'s GAMES pane instead (the transcript console always does).',
538
553
  examples: ['snake'],
539
554
  },
540
555
  quiz: {
@@ -599,6 +614,12 @@ export const helpText = {
599
614
  description: 'Prints a month or year calendar with today highlighted, in the spirit of UNIX cal.',
600
615
  examples: ['cal', 'cal 2026', 'cal 7 2026'],
601
616
  },
617
+ clear: {
618
+ category: 'Settings',
619
+ usage: 'clear',
620
+ description: 'Empty the console: the screen and its scrollback in a terminal, the record in the transcript. Ctrl-L clears the screen alone.',
621
+ examples: ['clear'],
622
+ },
602
623
  prompt: {
603
624
  category: 'Settings',
604
625
  usage: 'prompt [list | <theme>]',