@fnndsc/brasa 0.31.5 → 0.32.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.
- package/dist/buildinfo.json +1 -1
- package/dist/builtins/games/bytes.d.ts +21 -0
- package/dist/builtins/games/bytes.js +224 -0
- package/dist/builtins/games/bytes.js.map +1 -0
- package/dist/builtins/games/chimes.d.ts +64 -0
- package/dist/builtins/games/chimes.js +223 -0
- package/dist/builtins/games/chimes.js.map +1 -0
- package/dist/builtins/games/cowsay.d.ts +36 -0
- package/dist/builtins/games/cowsay.js +127 -0
- package/dist/builtins/games/cowsay.js.map +1 -0
- package/dist/builtins/games/figlet.d.ts +25 -0
- package/dist/builtins/games/figlet.js +109 -0
- package/dist/builtins/games/figlet.js.map +1 -0
- package/dist/builtins/games/lab.d.ts +51 -0
- package/dist/builtins/games/lab.js +161 -0
- package/dist/builtins/games/lab.js.map +1 -0
- package/dist/builtins/games/lolcat.d.ts +26 -0
- package/dist/builtins/games/lolcat.js +71 -0
- package/dist/builtins/games/lolcat.js.map +1 -0
- package/dist/builtins/games/morse.d.ts +18 -0
- package/dist/builtins/games/morse.js +46 -0
- package/dist/builtins/games/morse.js.map +1 -0
- package/dist/builtins/games/numbers.d.ts +55 -0
- package/dist/builtins/games/numbers.js +270 -0
- package/dist/builtins/games/numbers.js.map +1 -0
- package/dist/builtins/games/play.d.ts +53 -0
- package/dist/builtins/games/play.js +228 -0
- package/dist/builtins/games/play.js.map +1 -0
- package/dist/builtins/games/qr.d.ts +40 -0
- package/dist/builtins/games/qr.js +336 -0
- package/dist/builtins/games/qr.js.map +1 -0
- package/dist/builtins/games/shelf.d.ts +27 -0
- package/dist/builtins/games/shelf.js +71 -0
- package/dist/builtins/games/shelf.js.map +1 -0
- package/dist/builtins/games/show.d.ts +32 -0
- package/dist/builtins/games/show.js +68 -0
- package/dist/builtins/games/show.js.map +1 -0
- package/dist/builtins/games/sky.d.ts +69 -0
- package/dist/builtins/games/sky.js +190 -0
- package/dist/builtins/games/sky.js.map +1 -0
- package/dist/builtins/games/stdin.d.ts +34 -0
- package/dist/builtins/games/stdin.js +48 -0
- package/dist/builtins/games/stdin.js.map +1 -0
- package/dist/builtins/games/text.d.ts +46 -0
- package/dist/builtins/games/text.js +133 -0
- package/dist/builtins/games/text.js.map +1 -0
- package/dist/builtins/games/wtf.d.ts +13 -0
- package/dist/builtins/games/wtf.data.d.ts +12 -0
- package/dist/builtins/games/wtf.data.js +70 -0
- package/dist/builtins/games/wtf.data.js.map +1 -0
- package/dist/builtins/games/wtf.js +45 -0
- package/dist/builtins/games/wtf.js.map +1 -0
- package/dist/builtins/help.d.ts +8 -0
- package/dist/builtins/help.js +296 -0
- package/dist/builtins/help.js.map +1 -1
- package/dist/core/dispatch.js +125 -9
- package/dist/core/dispatch.js.map +1 -1
- package/dist/core/engine.js +1 -0
- package/dist/core/engine.js.map +1 -1
- package/dist/core/surface.d.ts +14 -0
- package/dist/core/surface.js.map +1 -1
- package/dist/lib/vfs/providers/static.js +15 -1
- package/dist/lib/vfs/providers/static.js.map +1 -1
- package/dist/lib/vfs/providers/static_content.js +2 -2
- package/dist/lib/vfs/providers/static_content.js.map +1 -1
- package/package.json +1 -1
package/dist/buildinfo.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"hash":"
|
|
1
|
+
{"hash":"ff1316"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { CommandEnvelope } from '@fnndsc/cumin';
|
|
2
|
+
/** Bytes `xxd` shows when not told. */
|
|
3
|
+
export declare const XXD_DEFAULT: number;
|
|
4
|
+
/** Strings `strings` shows when not told. */
|
|
5
|
+
export declare const STRINGS_DEFAULT: number;
|
|
6
|
+
/** What a file is, by its first bytes. */
|
|
7
|
+
export declare function magic_of(bytes: Buffer, name?: string): string;
|
|
8
|
+
/** The canonical hex dump of some bytes, offsets from `base`. */
|
|
9
|
+
export declare function hexdump_render(bytes: Buffer, base?: number): string;
|
|
10
|
+
/** The printable runs of at least `min` characters in some bytes. */
|
|
11
|
+
export declare function strings_find(bytes: Buffer, min?: number): string[];
|
|
12
|
+
/** `file <path>...` */
|
|
13
|
+
export declare function builtin_file(args: string[]): Promise<CommandEnvelope>;
|
|
14
|
+
/** `xxd [-s OFFSET] [-l LENGTH] <path>` */
|
|
15
|
+
export declare function builtin_xxd(args: string[]): Promise<CommandEnvelope>;
|
|
16
|
+
/** `strings [-n MIN] [-l LIMIT] <path>` */
|
|
17
|
+
export declare function builtin_strings(args: string[]): Promise<CommandEnvelope>;
|
|
18
|
+
/** `sha256sum <path>...` */
|
|
19
|
+
export declare function builtin_sha256sum(args: string[]): Promise<CommandEnvelope>;
|
|
20
|
+
/** `md5sum <path>...` */
|
|
21
|
+
export declare function builtin_md5sum(args: string[]): Promise<CommandEnvelope>;
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Bytes of a CFS file: `file`, `xxd`, `strings`, `sha256sum`, `md5sum`.
|
|
3
|
+
*
|
|
4
|
+
* The way people learn what a file is: by its magic, in hex, by the words
|
|
5
|
+
* in it, by its digest. Each reads the file the way `cat` does, through
|
|
6
|
+
* the session's filesystem, so a path is a CFS path. `xxd` and `strings`
|
|
7
|
+
* are bounded and say what they showed.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import { createHash } from 'node:crypto';
|
|
12
|
+
import { envelope_ok, envelope_error, errorStack } from '@fnndsc/cumin';
|
|
13
|
+
import { files_cat, files_catBinary } from '@fnndsc/chili/commands/fs/cat.js';
|
|
14
|
+
import chalk from 'chalk';
|
|
15
|
+
import { path_resolve, error_stripDebugPrefix } from '../utils.js';
|
|
16
|
+
/** Bytes `xxd` shows when not told. */
|
|
17
|
+
export const XXD_DEFAULT = 256;
|
|
18
|
+
/** Strings `strings` shows when not told. */
|
|
19
|
+
export const STRINGS_DEFAULT = 200;
|
|
20
|
+
/** What a file is, by its first bytes. */
|
|
21
|
+
export function magic_of(bytes, name = '') {
|
|
22
|
+
const at = (i) => bytes[i] ?? -1;
|
|
23
|
+
const ascii = (from, to) => bytes.subarray(from, to).toString('latin1');
|
|
24
|
+
if (bytes.length === 0)
|
|
25
|
+
return 'empty';
|
|
26
|
+
if (bytes.length > 132 && ascii(128, 132) === 'DICM')
|
|
27
|
+
return 'DICOM medical image (part 10, with preamble)';
|
|
28
|
+
if (at(0) === 0x1f && at(1) === 0x8b)
|
|
29
|
+
return /\.nii\.gz$/i.test(name) ? 'gzip compressed data, a NIfTI volume by its name' : 'gzip compressed data';
|
|
30
|
+
if (bytes.length >= 348 && (ascii(344, 348) === 'n+1\0' || ascii(344, 348) === 'ni1\0'))
|
|
31
|
+
return 'NIfTI-1 neuroimaging volume';
|
|
32
|
+
if (bytes.length >= 8 && ascii(4, 8) === 'n+2\0')
|
|
33
|
+
return 'NIfTI-2 neuroimaging volume';
|
|
34
|
+
if (ascii(0, 4) === '\x89PNG')
|
|
35
|
+
return 'PNG image';
|
|
36
|
+
if (at(0) === 0xff && at(1) === 0xd8)
|
|
37
|
+
return 'JPEG image';
|
|
38
|
+
if (ascii(0, 4) === 'GIF8')
|
|
39
|
+
return 'GIF image';
|
|
40
|
+
if (ascii(0, 4) === '%PDF')
|
|
41
|
+
return 'PDF document';
|
|
42
|
+
if (ascii(0, 2) === 'PK')
|
|
43
|
+
return 'ZIP archive';
|
|
44
|
+
if (ascii(0, 4) === 'MThd')
|
|
45
|
+
return 'MIDI';
|
|
46
|
+
if (ascii(0, 4) === 'RIFF')
|
|
47
|
+
return 'RIFF (WAV or AVI)';
|
|
48
|
+
if (ascii(0, 2) === 'BM')
|
|
49
|
+
return 'BMP image';
|
|
50
|
+
if (ascii(0, 7) === '!<arch>')
|
|
51
|
+
return 'ar archive';
|
|
52
|
+
if (ascii(0, 4) === '\x7fELF')
|
|
53
|
+
return 'ELF executable';
|
|
54
|
+
if (ascii(0, 5) === 'ustar' || ascii(257, 262) === 'ustar')
|
|
55
|
+
return 'tar archive';
|
|
56
|
+
if (at(0) === 0x42 && at(1) === 0x5a && at(2) === 0x68)
|
|
57
|
+
return 'bzip2 compressed data';
|
|
58
|
+
if (ascii(0, 6) === '\xfd7zXZ\0')
|
|
59
|
+
return 'xz compressed data';
|
|
60
|
+
const head = bytes.subarray(0, 4096);
|
|
61
|
+
let printable = 0;
|
|
62
|
+
for (const b of head)
|
|
63
|
+
if (b === 9 || b === 10 || b === 13 || (b >= 32 && b < 127) || b >= 128)
|
|
64
|
+
printable++;
|
|
65
|
+
if (printable / head.length > 0.95) {
|
|
66
|
+
const text = head.toString('utf-8');
|
|
67
|
+
if (/^\s*[{[]/.test(text))
|
|
68
|
+
return 'JSON text';
|
|
69
|
+
if (/^#!/.test(text))
|
|
70
|
+
return `script text (${text.split('\n')[0]?.slice(2).trim() ?? ''})`;
|
|
71
|
+
if (/^\s*<\?xml/i.test(text))
|
|
72
|
+
return 'XML text';
|
|
73
|
+
if (/^\s*<(!doctype html|html)/i.test(text))
|
|
74
|
+
return 'HTML text';
|
|
75
|
+
const lines = text.split('\n').slice(0, 5);
|
|
76
|
+
if (lines.length > 1 && lines.every((l) => l.split(',').length > 1))
|
|
77
|
+
return 'CSV text';
|
|
78
|
+
return head.some((b) => b >= 128) ? 'UTF-8 text' : 'ASCII text';
|
|
79
|
+
}
|
|
80
|
+
return 'data';
|
|
81
|
+
}
|
|
82
|
+
/** The canonical hex dump of some bytes, offsets from `base`. */
|
|
83
|
+
export function hexdump_render(bytes, base = 0) {
|
|
84
|
+
const lines = [];
|
|
85
|
+
for (let off = 0; off < bytes.length; off += 16) {
|
|
86
|
+
const chunk = bytes.subarray(off, off + 16);
|
|
87
|
+
const hex = [];
|
|
88
|
+
for (let i = 0; i < 16; i += 2) {
|
|
89
|
+
const a = chunk[i];
|
|
90
|
+
const b = chunk[i + 1];
|
|
91
|
+
hex.push(a === undefined ? ' ' : b === undefined ? `${a.toString(16).padStart(2, '0')} ` : `${a.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`);
|
|
92
|
+
}
|
|
93
|
+
const text = [...chunk].map((b) => (b >= 32 && b < 127 ? String.fromCharCode(b) : '.')).join('');
|
|
94
|
+
lines.push(`${(base + off).toString(16).padStart(8, '0')}: ${hex.join(' ')} ${text}`);
|
|
95
|
+
}
|
|
96
|
+
return lines.join('\n');
|
|
97
|
+
}
|
|
98
|
+
/** The printable runs of at least `min` characters in some bytes. */
|
|
99
|
+
export function strings_find(bytes, min = 4) {
|
|
100
|
+
const out = [];
|
|
101
|
+
let run = '';
|
|
102
|
+
for (const b of bytes) {
|
|
103
|
+
if (b >= 32 && b < 127) {
|
|
104
|
+
run += String.fromCharCode(b);
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (run.length >= min)
|
|
108
|
+
out.push(run);
|
|
109
|
+
run = '';
|
|
110
|
+
}
|
|
111
|
+
if (run.length >= min)
|
|
112
|
+
out.push(run);
|
|
113
|
+
return out;
|
|
114
|
+
}
|
|
115
|
+
/** Reads a CFS file's bytes, or answers why not. */
|
|
116
|
+
async function bytes_read(pathArg, name) {
|
|
117
|
+
const target = await path_resolve(pathArg);
|
|
118
|
+
const result = await files_catBinary(target);
|
|
119
|
+
if (result.ok)
|
|
120
|
+
return { path: target, bytes: result.value };
|
|
121
|
+
// A projected file (/etc/cube, a /proc log) has words but no bytes of its
|
|
122
|
+
// own: its text is read instead, and the refusal of the first read is
|
|
123
|
+
// dropped — it was a question, not a failure.
|
|
124
|
+
const first = errorStack.stack_pop();
|
|
125
|
+
const text = await files_cat(target);
|
|
126
|
+
if (text.ok)
|
|
127
|
+
return { path: target, bytes: Buffer.from(text.value, 'utf-8') };
|
|
128
|
+
const last = errorStack.stack_pop() ?? first;
|
|
129
|
+
const why = last === undefined ? 'cannot read' : error_stripDebugPrefix(last.message);
|
|
130
|
+
return { error: envelope_error('', undefined, `${name}: ${pathArg}: ${why}\n`) };
|
|
131
|
+
}
|
|
132
|
+
/** Takes `-FLAG N` pairs off the arguments. */
|
|
133
|
+
function numberFlags_take(args, flags) {
|
|
134
|
+
const values = {};
|
|
135
|
+
const rest = [];
|
|
136
|
+
for (let i = 0; i < args.length; i++) {
|
|
137
|
+
const a = args[i];
|
|
138
|
+
if (flags.includes(a)) {
|
|
139
|
+
const n = Number(args[i + 1]);
|
|
140
|
+
if (!Number.isInteger(n) || n < 0)
|
|
141
|
+
return { refusal: `${a} wants a whole number` };
|
|
142
|
+
values[a] = n;
|
|
143
|
+
i++;
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
rest.push(a);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return { values, rest };
|
|
150
|
+
}
|
|
151
|
+
/** `file <path>...` */
|
|
152
|
+
export async function builtin_file(args) {
|
|
153
|
+
if (args.length === 0)
|
|
154
|
+
return envelope_error('', undefined, 'file: usage: file <path>...\n');
|
|
155
|
+
const lines = [];
|
|
156
|
+
const data = [];
|
|
157
|
+
for (const arg of args) {
|
|
158
|
+
const read = await bytes_read(arg, 'file');
|
|
159
|
+
if ('error' in read)
|
|
160
|
+
return read.error;
|
|
161
|
+
const kind = magic_of(read.bytes, read.path);
|
|
162
|
+
lines.push(`${arg}: ${kind}${read.bytes.length > 0 ? chalk.gray(` (${read.bytes.length.toLocaleString('en-US')} bytes)`) : ''}`);
|
|
163
|
+
data.push({ path: read.path, kind, bytes: read.bytes.length });
|
|
164
|
+
}
|
|
165
|
+
return envelope_ok(`${lines.join('\n')}\n`, { kind: 'games.file', data: { files: data } });
|
|
166
|
+
}
|
|
167
|
+
/** `xxd [-s OFFSET] [-l LENGTH] <path>` */
|
|
168
|
+
export async function builtin_xxd(args) {
|
|
169
|
+
const parsed = numberFlags_take(args, ['-s', '-l']);
|
|
170
|
+
if ('refusal' in parsed)
|
|
171
|
+
return envelope_error('', undefined, `xxd: ${parsed.refusal}\n`);
|
|
172
|
+
if (parsed.rest.length !== 1)
|
|
173
|
+
return envelope_error('', undefined, 'xxd: usage: xxd [-s OFFSET] [-l LENGTH] <path>\n');
|
|
174
|
+
const read = await bytes_read(parsed.rest[0], 'xxd');
|
|
175
|
+
if ('error' in read)
|
|
176
|
+
return read.error;
|
|
177
|
+
const offset = parsed.values['-s'] ?? 0;
|
|
178
|
+
const length = parsed.values['-l'] ?? XXD_DEFAULT;
|
|
179
|
+
const shown = read.bytes.subarray(offset, offset + length);
|
|
180
|
+
const more = read.bytes.length - offset - shown.length;
|
|
181
|
+
const note = more > 0 ? chalk.gray(`\nxxd: ${shown.length} of ${read.bytes.length.toLocaleString('en-US')} bytes shown (-l ${length}; -s to start elsewhere)`) : '';
|
|
182
|
+
return envelope_ok(`${hexdump_render(shown, offset)}${note}\n`, { kind: 'games.xxd', data: { path: read.path, offset, shown: shown.length, total: read.bytes.length } });
|
|
183
|
+
}
|
|
184
|
+
/** `strings [-n MIN] [-l LIMIT] <path>` */
|
|
185
|
+
export async function builtin_strings(args) {
|
|
186
|
+
const parsed = numberFlags_take(args, ['-n', '-l']);
|
|
187
|
+
if ('refusal' in parsed)
|
|
188
|
+
return envelope_error('', undefined, `strings: ${parsed.refusal}\n`);
|
|
189
|
+
if (parsed.rest.length !== 1)
|
|
190
|
+
return envelope_error('', undefined, 'strings: usage: strings [-n MIN] [-l LIMIT] <path>\n');
|
|
191
|
+
const read = await bytes_read(parsed.rest[0], 'strings');
|
|
192
|
+
if ('error' in read)
|
|
193
|
+
return read.error;
|
|
194
|
+
const min = Math.max(1, parsed.values['-n'] ?? 4);
|
|
195
|
+
const limit = parsed.values['-l'] ?? STRINGS_DEFAULT;
|
|
196
|
+
const found = strings_find(read.bytes, min);
|
|
197
|
+
const shown = found.slice(0, limit);
|
|
198
|
+
const note = found.length > shown.length ? chalk.gray(`\nstrings: ${shown.length} of ${found.length} shown (-l for more)`) : '';
|
|
199
|
+
return envelope_ok(`${shown.join('\n')}${note}\n`, { kind: 'games.strings', data: { path: read.path, shown: shown.length, total: found.length } });
|
|
200
|
+
}
|
|
201
|
+
async function digest_run(args, algorithm, name) {
|
|
202
|
+
if (args.length === 0)
|
|
203
|
+
return envelope_error('', undefined, `${name}: usage: ${name} <path>...\n`);
|
|
204
|
+
const lines = [];
|
|
205
|
+
const data = [];
|
|
206
|
+
for (const arg of args) {
|
|
207
|
+
const read = await bytes_read(arg, name);
|
|
208
|
+
if ('error' in read)
|
|
209
|
+
return read.error;
|
|
210
|
+
const digest = createHash(algorithm).update(read.bytes).digest('hex');
|
|
211
|
+
lines.push(`${digest} ${arg}`);
|
|
212
|
+
data.push({ path: read.path, digest });
|
|
213
|
+
}
|
|
214
|
+
return envelope_ok(`${lines.join('\n')}\n`, { kind: `games.${name}`, data: { algorithm, files: data } });
|
|
215
|
+
}
|
|
216
|
+
/** `sha256sum <path>...` */
|
|
217
|
+
export async function builtin_sha256sum(args) {
|
|
218
|
+
return digest_run(args, 'sha256', 'sha256sum');
|
|
219
|
+
}
|
|
220
|
+
/** `md5sum <path>...` */
|
|
221
|
+
export async function builtin_md5sum(args) {
|
|
222
|
+
return digest_run(args, 'md5', 'md5sum');
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=bytes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bytes.js","sourceRoot":"","sources":["../../../src/builtins/games/bytes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Chimes: `timer`, `leave` and `stopwatch`.
|
|
3
|
+
*
|
|
4
|
+
* A chime is a word said later. The kernel keeps it on a clock and, when
|
|
5
|
+
* the time comes, publishes it on the ambient channel as an envelope of
|
|
6
|
+
* its own — the same road a refreshed listing takes — so every surface on
|
|
7
|
+
* the session hears it: ARGUS notes it in the console and speaks it, a
|
|
8
|
+
* remote chell prints it. Nothing holds the lane while it waits. A chime
|
|
9
|
+
* lives as long as the process: a session's chimes end with it.
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
import { CommandEnvelope } from '@fnndsc/cumin';
|
|
14
|
+
/** A chime waiting its turn. */
|
|
15
|
+
export interface Chime {
|
|
16
|
+
id: number;
|
|
17
|
+
/** When it sounds, epoch ms. */
|
|
18
|
+
at: number;
|
|
19
|
+
text: string;
|
|
20
|
+
/** What set it. */
|
|
21
|
+
source: 'timer' | 'leave';
|
|
22
|
+
}
|
|
23
|
+
/** The longest a chime may wait. */
|
|
24
|
+
export declare const CHIME_MAX_MS: number;
|
|
25
|
+
/** What sounding a chime does; a test hands in its own ear. */
|
|
26
|
+
export type ChimeSound = (chime: Chime) => void;
|
|
27
|
+
/**
|
|
28
|
+
* Sets a chime.
|
|
29
|
+
*
|
|
30
|
+
* @param delayMs - How long from now.
|
|
31
|
+
* @param text - What it says.
|
|
32
|
+
* @param source - What set it.
|
|
33
|
+
* @param sound - How it sounds (the ambient channel by default).
|
|
34
|
+
* @returns The chime.
|
|
35
|
+
*/
|
|
36
|
+
export declare function chime_set(delayMs: number, text: string, source: Chime['source'], sound?: ChimeSound): Chime;
|
|
37
|
+
/** The chimes still waiting, soonest first. */
|
|
38
|
+
export declare function chimes_list(): Chime[];
|
|
39
|
+
/**
|
|
40
|
+
* Cancels one chime, or every chime of a source, or all of them.
|
|
41
|
+
*
|
|
42
|
+
* @returns How many were cancelled.
|
|
43
|
+
*/
|
|
44
|
+
export declare function chimes_cancel(which: number | Chime['source'] | 'all'): number;
|
|
45
|
+
/**
|
|
46
|
+
* Reads a duration: `90s`, `5m`, `1h30m`, `2:30` (m:ss), `1:00:00`, or a bare number of minutes.
|
|
47
|
+
*
|
|
48
|
+
* @returns Milliseconds, or null when the words are not a duration.
|
|
49
|
+
*/
|
|
50
|
+
export declare function duration_parse(text: string): number | null;
|
|
51
|
+
/** A span in words: `1h 05m`, `4m 30s`, `12s`. */
|
|
52
|
+
export declare function span_words(ms: number): string;
|
|
53
|
+
/** `timer <duration> [words] | timer | timer cancel [id|all]` */
|
|
54
|
+
export declare function builtin_timer(args: string[]): Promise<CommandEnvelope>;
|
|
55
|
+
/** Reads `+hhmm` (from now) or `hhmm` (a clock time, today or tomorrow) as a delay. */
|
|
56
|
+
export declare function leave_delay(text: string, now?: Date): number | null;
|
|
57
|
+
/** `leave [+hhmm | hhmm] | leave cancel` — BSD's leave: a word five minutes before, one at the time, and one after. */
|
|
58
|
+
export declare function builtin_leave(args: string[]): Promise<CommandEnvelope>;
|
|
59
|
+
/** The stopwatch's elapsed time now. */
|
|
60
|
+
export declare function stopwatch_elapsed(now?: number): number;
|
|
61
|
+
/** Resets the stopwatch (a test's seam, and `stopwatch reset`). */
|
|
62
|
+
export declare function stopwatch_reset(): void;
|
|
63
|
+
/** `stopwatch [start|stop|lap|reset]` — bare, it shows the time. */
|
|
64
|
+
export declare function builtin_stopwatch(args: string[]): Promise<CommandEnvelope>;
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Chimes: `timer`, `leave` and `stopwatch`.
|
|
3
|
+
*
|
|
4
|
+
* A chime is a word said later. The kernel keeps it on a clock and, when
|
|
5
|
+
* the time comes, publishes it on the ambient channel as an envelope of
|
|
6
|
+
* its own — the same road a refreshed listing takes — so every surface on
|
|
7
|
+
* the session hears it: ARGUS notes it in the console and speaks it, a
|
|
8
|
+
* remote chell prints it. Nothing holds the lane while it waits. A chime
|
|
9
|
+
* lives as long as the process: a session's chimes end with it.
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
import { envelope_ok, envelope_error } from '@fnndsc/cumin';
|
|
14
|
+
import chalk from 'chalk';
|
|
15
|
+
import { ambient_publish } from '../../core/ambient.js';
|
|
16
|
+
/** The longest a chime may wait. */
|
|
17
|
+
export const CHIME_MAX_MS = 24 * 3600 * 1000;
|
|
18
|
+
const pending = new Map();
|
|
19
|
+
let nextId = 1;
|
|
20
|
+
const chime_sound = (chime) => {
|
|
21
|
+
ambient_publish({
|
|
22
|
+
kind: 'envelope',
|
|
23
|
+
envelope: envelope_ok(`${chalk.yellow('🔔')} ${chime.text}\n`, { kind: 'games.chime', data: { id: chime.id, text: chime.text, source: chime.source, at: new Date(chime.at).toISOString() } }),
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Sets a chime.
|
|
28
|
+
*
|
|
29
|
+
* @param delayMs - How long from now.
|
|
30
|
+
* @param text - What it says.
|
|
31
|
+
* @param source - What set it.
|
|
32
|
+
* @param sound - How it sounds (the ambient channel by default).
|
|
33
|
+
* @returns The chime.
|
|
34
|
+
*/
|
|
35
|
+
export function chime_set(delayMs, text, source, sound = chime_sound) {
|
|
36
|
+
const chime = { id: nextId++, at: Date.now() + delayMs, text, source };
|
|
37
|
+
const handle = setTimeout(() => {
|
|
38
|
+
pending.delete(chime.id);
|
|
39
|
+
sound(chime);
|
|
40
|
+
}, delayMs);
|
|
41
|
+
// A waiting chime must not hold the process open on its own.
|
|
42
|
+
handle.unref();
|
|
43
|
+
pending.set(chime.id, { chime, handle });
|
|
44
|
+
return chime;
|
|
45
|
+
}
|
|
46
|
+
/** The chimes still waiting, soonest first. */
|
|
47
|
+
export function chimes_list() {
|
|
48
|
+
return [...pending.values()].map((p) => p.chime).sort((a, b) => a.at - b.at);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Cancels one chime, or every chime of a source, or all of them.
|
|
52
|
+
*
|
|
53
|
+
* @returns How many were cancelled.
|
|
54
|
+
*/
|
|
55
|
+
export function chimes_cancel(which) {
|
|
56
|
+
let count = 0;
|
|
57
|
+
for (const [id, entry] of pending) {
|
|
58
|
+
if (which === 'all' || which === id || which === entry.chime.source) {
|
|
59
|
+
clearTimeout(entry.handle);
|
|
60
|
+
pending.delete(id);
|
|
61
|
+
count++;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return count;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Reads a duration: `90s`, `5m`, `1h30m`, `2:30` (m:ss), `1:00:00`, or a bare number of minutes.
|
|
68
|
+
*
|
|
69
|
+
* @returns Milliseconds, or null when the words are not a duration.
|
|
70
|
+
*/
|
|
71
|
+
export function duration_parse(text) {
|
|
72
|
+
const t = text.trim().toLowerCase();
|
|
73
|
+
if (/^\d+$/.test(t))
|
|
74
|
+
return Number(t) * 60_000;
|
|
75
|
+
const clock = /^(\d+):(\d{1,2})(?::(\d{1,2}))?$/.exec(t);
|
|
76
|
+
if (clock !== null) {
|
|
77
|
+
const parts = [clock[1], clock[2], clock[3]].filter((p) => p !== undefined).map(Number);
|
|
78
|
+
const seconds = parts.length === 3 ? parts[0] * 3600 + parts[1] * 60 + parts[2] : parts[0] * 60 + parts[1];
|
|
79
|
+
return seconds * 1000;
|
|
80
|
+
}
|
|
81
|
+
const units = /^(?:(\d+(?:\.\d+)?)h)?(?:(\d+(?:\.\d+)?)m)?(?:(\d+(?:\.\d+)?)s)?$/.exec(t);
|
|
82
|
+
if (units === null || units[0] === '')
|
|
83
|
+
return null;
|
|
84
|
+
const [, h, m, s] = units;
|
|
85
|
+
return Math.round(((Number(h ?? 0)) * 3600 + Number(m ?? 0) * 60 + Number(s ?? 0)) * 1000);
|
|
86
|
+
}
|
|
87
|
+
/** A span in words: `1h 05m`, `4m 30s`, `12s`. */
|
|
88
|
+
export function span_words(ms) {
|
|
89
|
+
const total = Math.max(0, Math.round(ms / 1000));
|
|
90
|
+
const h = Math.floor(total / 3600);
|
|
91
|
+
const m = Math.floor((total % 3600) / 60);
|
|
92
|
+
const s = total % 60;
|
|
93
|
+
if (h > 0)
|
|
94
|
+
return `${h}h ${String(m).padStart(2, '0')}m`;
|
|
95
|
+
if (m > 0)
|
|
96
|
+
return `${m}m ${String(s).padStart(2, '0')}s`;
|
|
97
|
+
return `${s}s`;
|
|
98
|
+
}
|
|
99
|
+
function chimes_render() {
|
|
100
|
+
const list = chimes_list();
|
|
101
|
+
if (list.length === 0)
|
|
102
|
+
return `${chalk.gray('no chimes waiting')}\n`;
|
|
103
|
+
return list.map((c) => `${String(c.id).padStart(3)} ${c.source.padEnd(5)} in ${span_words(c.at - Date.now()).padEnd(8)} ${c.text}`).join('\n') + '\n';
|
|
104
|
+
}
|
|
105
|
+
/** `timer <duration> [words] | timer | timer cancel [id|all]` */
|
|
106
|
+
export async function builtin_timer(args) {
|
|
107
|
+
if (args.length === 0)
|
|
108
|
+
return envelope_ok(chimes_render(), { kind: 'games.chimes', data: { chimes: chimes_list() } });
|
|
109
|
+
if (args[0] === 'cancel') {
|
|
110
|
+
const which = args[1] === undefined ? 'timer' : args[1] === 'all' ? 'all' : Number(args[1]);
|
|
111
|
+
if (typeof which === 'number' && !Number.isInteger(which))
|
|
112
|
+
return envelope_error('', undefined, 'timer: cancel wants a chime id, or all\n');
|
|
113
|
+
const n = chimes_cancel(which);
|
|
114
|
+
return envelope_ok(`${n} chime${n === 1 ? '' : 's'} cancelled\n`, { kind: 'games.chimes', data: { cancelled: n } });
|
|
115
|
+
}
|
|
116
|
+
const ms = duration_parse(args[0]);
|
|
117
|
+
if (ms === null || ms <= 0)
|
|
118
|
+
return envelope_error('', undefined, `timer: '${args[0]}' is not a duration (try 90s, 5m, 1h30m, 2:30)\n`);
|
|
119
|
+
if (ms > CHIME_MAX_MS)
|
|
120
|
+
return envelope_error('', undefined, 'timer: a day is the most a timer waits\n');
|
|
121
|
+
const words = args.slice(1).join(' ') || `timer: ${span_words(ms)} is up`;
|
|
122
|
+
const chime = chime_set(ms, words, 'timer');
|
|
123
|
+
return envelope_ok(`timer ${chime.id} set: ${span_words(ms)} from now (${new Date(chime.at).toTimeString().slice(0, 8)}) — ${words}\n`, { kind: 'games.chimes', data: { set: chime } });
|
|
124
|
+
}
|
|
125
|
+
/** Reads `+hhmm` (from now) or `hhmm` (a clock time, today or tomorrow) as a delay. */
|
|
126
|
+
export function leave_delay(text, now = new Date()) {
|
|
127
|
+
const m = /^(\+)?(\d{1,2}):?(\d{2})$/.exec(text.trim());
|
|
128
|
+
if (m === null)
|
|
129
|
+
return null;
|
|
130
|
+
const hours = Number(m[2]);
|
|
131
|
+
const minutes = Number(m[3]);
|
|
132
|
+
if (minutes > 59 || hours > 23 && m[1] === undefined)
|
|
133
|
+
return null;
|
|
134
|
+
if (m[1] === '+')
|
|
135
|
+
return (hours * 60 + minutes) * 60_000;
|
|
136
|
+
const at = new Date(now);
|
|
137
|
+
at.setHours(hours, minutes, 0, 0);
|
|
138
|
+
if (at.getTime() <= now.getTime())
|
|
139
|
+
at.setDate(at.getDate() + 1);
|
|
140
|
+
return at.getTime() - now.getTime();
|
|
141
|
+
}
|
|
142
|
+
/** `leave [+hhmm | hhmm] | leave cancel` — BSD's leave: a word five minutes before, one at the time, and one after. */
|
|
143
|
+
export async function builtin_leave(args) {
|
|
144
|
+
if (args.length === 0) {
|
|
145
|
+
const mine = chimes_list().filter((c) => c.source === 'leave');
|
|
146
|
+
if (mine.length === 0)
|
|
147
|
+
return envelope_ok(`${chalk.gray('no leave set (leave +0030, or leave 1730)')}\n`, { kind: 'games.chimes', data: { chimes: [] } });
|
|
148
|
+
const last = mine[mine.length - 1];
|
|
149
|
+
return envelope_ok(`leaving at ${new Date(last.at - 60_000).toTimeString().slice(0, 5)} — in ${span_words(last.at - 60_000 - Date.now())}\n`, { kind: 'games.chimes', data: { chimes: mine } });
|
|
150
|
+
}
|
|
151
|
+
if (args[0] === 'cancel') {
|
|
152
|
+
const n = chimes_cancel('leave');
|
|
153
|
+
return envelope_ok(`${n === 0 ? 'no leave was set' : 'leave cancelled'}\n`, { kind: 'games.chimes', data: { cancelled: n } });
|
|
154
|
+
}
|
|
155
|
+
const delay = leave_delay(args[0]);
|
|
156
|
+
if (delay === null)
|
|
157
|
+
return envelope_error('', undefined, `leave: '${args[0]}' is not a time (leave +hhmm from now, or leave hhmm)\n`);
|
|
158
|
+
chimes_cancel('leave');
|
|
159
|
+
const at = new Date(Date.now() + delay);
|
|
160
|
+
if (delay > 5 * 60_000)
|
|
161
|
+
chime_set(delay - 5 * 60_000, 'You have to leave in 5 minutes.', 'leave');
|
|
162
|
+
if (delay > 60_000)
|
|
163
|
+
chime_set(delay - 60_000, 'Just one more minute!', 'leave');
|
|
164
|
+
chime_set(delay, 'Time to leave!', 'leave');
|
|
165
|
+
chime_set(delay + 60_000, "You're going to be late!", 'leave');
|
|
166
|
+
return envelope_ok(`Alarm set for ${at.toTimeString().slice(0, 5)} (in ${span_words(delay)}).\n`, { kind: 'games.chimes', data: { at: at.toISOString() } });
|
|
167
|
+
}
|
|
168
|
+
const watch = { startedAt: null, accumulated: 0, laps: [] };
|
|
169
|
+
/** The stopwatch's elapsed time now. */
|
|
170
|
+
export function stopwatch_elapsed(now = Date.now()) {
|
|
171
|
+
return watch.accumulated + (watch.startedAt === null ? 0 : now - watch.startedAt);
|
|
172
|
+
}
|
|
173
|
+
/** Resets the stopwatch (a test's seam, and `stopwatch reset`). */
|
|
174
|
+
export function stopwatch_reset() {
|
|
175
|
+
watch.startedAt = null;
|
|
176
|
+
watch.accumulated = 0;
|
|
177
|
+
watch.laps = [];
|
|
178
|
+
}
|
|
179
|
+
const clock_words = (ms) => {
|
|
180
|
+
const total = Math.floor(ms / 1000);
|
|
181
|
+
const h = Math.floor(total / 3600);
|
|
182
|
+
const m = Math.floor((total % 3600) / 60);
|
|
183
|
+
const s = total % 60;
|
|
184
|
+
const tenths = Math.floor((ms % 1000) / 100);
|
|
185
|
+
return `${h > 0 ? `${h}:` : ''}${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}.${tenths}`;
|
|
186
|
+
};
|
|
187
|
+
/** `stopwatch [start|stop|lap|reset]` — bare, it shows the time. */
|
|
188
|
+
export async function builtin_stopwatch(args) {
|
|
189
|
+
const verb = args[0] ?? 'show';
|
|
190
|
+
const now = Date.now();
|
|
191
|
+
const running = watch.startedAt !== null;
|
|
192
|
+
if (verb === 'start') {
|
|
193
|
+
if (running)
|
|
194
|
+
return envelope_ok(`already running: ${clock_words(stopwatch_elapsed(now))}\n`, { kind: 'games.stopwatch', data: { elapsedMs: stopwatch_elapsed(now), running } });
|
|
195
|
+
watch.startedAt = now;
|
|
196
|
+
return envelope_ok(`stopwatch started${watch.accumulated > 0 ? ` (resuming at ${clock_words(watch.accumulated)})` : ''}\n`, { kind: 'games.stopwatch', data: { elapsedMs: watch.accumulated, running: true } });
|
|
197
|
+
}
|
|
198
|
+
if (verb === 'stop') {
|
|
199
|
+
if (!running)
|
|
200
|
+
return envelope_ok(`stopped at ${clock_words(watch.accumulated)}\n`, { kind: 'games.stopwatch', data: { elapsedMs: watch.accumulated, running: false } });
|
|
201
|
+
watch.accumulated += now - watch.startedAt;
|
|
202
|
+
watch.startedAt = null;
|
|
203
|
+
return envelope_ok(`stopped at ${clock_words(watch.accumulated)}\n`, { kind: 'games.stopwatch', data: { elapsedMs: watch.accumulated, running: false } });
|
|
204
|
+
}
|
|
205
|
+
if (verb === 'lap') {
|
|
206
|
+
if (!running)
|
|
207
|
+
return envelope_error('', undefined, 'stopwatch: not running (stopwatch start)\n');
|
|
208
|
+
const elapsed = stopwatch_elapsed(now);
|
|
209
|
+
watch.laps.push(elapsed);
|
|
210
|
+
const previous = watch.laps.length > 1 ? watch.laps[watch.laps.length - 2] : 0;
|
|
211
|
+
return envelope_ok(`lap ${watch.laps.length}: ${clock_words(elapsed - previous)} (${clock_words(elapsed)} total)\n`, { kind: 'games.stopwatch', data: { elapsedMs: elapsed, laps: watch.laps, running } });
|
|
212
|
+
}
|
|
213
|
+
if (verb === 'reset') {
|
|
214
|
+
stopwatch_reset();
|
|
215
|
+
return envelope_ok('stopwatch reset\n', { kind: 'games.stopwatch', data: { elapsedMs: 0, running: false } });
|
|
216
|
+
}
|
|
217
|
+
if (verb !== 'show')
|
|
218
|
+
return envelope_error('', undefined, `stopwatch: unknown word '${verb}' (start, stop, lap, reset)\n`);
|
|
219
|
+
const elapsed = stopwatch_elapsed(now);
|
|
220
|
+
const laps = watch.laps.map((l, i) => ` lap ${i + 1} ${clock_words(l - (watch.laps[i - 1] ?? 0))}`).join('\n');
|
|
221
|
+
return envelope_ok(`${clock_words(elapsed)}${running ? ' (running)' : watch.accumulated > 0 ? ' (stopped)' : ''}\n${laps ? `${laps}\n` : ''}`, { kind: 'games.stopwatch', data: { elapsedMs: elapsed, laps: watch.laps, running } });
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=chimes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chimes.js","sourceRoot":"","sources":["../../../src/builtins/games/chimes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file `cowsay`, with the ChRIS brain for a cow.
|
|
3
|
+
*
|
|
4
|
+
* The classic: a speech bubble over a creature. Ours thinks rather than
|
|
5
|
+
* lows — the brain is the mascot, and `fortune | cowsay` is what the shelf
|
|
6
|
+
* is for. `-W N` wraps at N columns; `cowthink` is the same with a thought
|
|
7
|
+
* bubble.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import { CommandEnvelope } from '@fnndsc/cumin';
|
|
12
|
+
/** The brain, as ASCII has long drawn it. */
|
|
13
|
+
export declare const BRAIN: ReadonlyArray<string>;
|
|
14
|
+
/** Default wrap width, as cowsay's. */
|
|
15
|
+
export declare const COWSAY_WIDTH: number;
|
|
16
|
+
/** Wraps text at a width, keeping the lines it already had. */
|
|
17
|
+
export declare function text_wrap(text: string, width: number): string[];
|
|
18
|
+
/**
|
|
19
|
+
* Draws the bubble: said (speech) or thought.
|
|
20
|
+
*
|
|
21
|
+
* @param lines - The wrapped lines.
|
|
22
|
+
* @param thought - True for a thought bubble (round sides, `o` trail).
|
|
23
|
+
*/
|
|
24
|
+
export declare function bubble_draw(lines: string[], thought: boolean): string[];
|
|
25
|
+
/**
|
|
26
|
+
* The whole picture: the bubble, its trail, the brain.
|
|
27
|
+
*
|
|
28
|
+
* @param text - What the brain says.
|
|
29
|
+
* @param thought - Thought bubble rather than speech.
|
|
30
|
+
* @param width - Wrap width.
|
|
31
|
+
*/
|
|
32
|
+
export declare function cowsay_render(text: string, thought?: boolean, width?: number): string;
|
|
33
|
+
/** `cowsay [-W N] [text]` */
|
|
34
|
+
export declare function builtin_cowsay(args: string[]): Promise<CommandEnvelope>;
|
|
35
|
+
/** `cowthink [-W N] [text]` */
|
|
36
|
+
export declare function builtin_cowthink(args: string[]): Promise<CommandEnvelope>;
|