@mudah-cli/mudah 0.8.0 → 0.9.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/LICENSE +21 -0
- package/README.md +70 -0
- package/dist/autocomplete.d.ts +8 -0
- package/dist/autocomplete.js +38 -0
- package/dist/autocomplete.js.map +1 -0
- package/dist/built-ins.d.ts +9 -0
- package/dist/built-ins.js +144 -0
- package/dist/built-ins.js.map +1 -0
- package/dist/commands/autocomplete.command.d.ts +11 -0
- package/dist/commands/autocomplete.command.js +16 -0
- package/dist/commands/autocomplete.command.js.map +1 -0
- package/dist/commands/build.command.d.ts +1 -0
- package/dist/commands/build.command.js +2 -1
- package/dist/commands/build.command.js.map +1 -1
- package/dist/commands/cache.command.d.ts +11 -0
- package/dist/commands/cache.command.js +47 -0
- package/dist/commands/cache.command.js.map +1 -0
- package/dist/commands/complete.command.d.ts +13 -0
- package/dist/commands/complete.command.js +23 -0
- package/dist/commands/complete.command.js.map +1 -0
- package/dist/commands/config.diff.command.d.ts +8 -0
- package/dist/commands/config.diff.command.js +96 -0
- package/dist/commands/config.diff.command.js.map +1 -0
- package/dist/commands/config.set.command.d.ts +8 -0
- package/dist/commands/config.set.command.js +66 -0
- package/dist/commands/config.set.command.js.map +1 -0
- package/dist/commands/config.show.command.d.ts +8 -0
- package/dist/commands/config.show.command.js +38 -0
- package/dist/commands/config.show.command.js.map +1 -0
- package/dist/commands/config.source.command.d.ts +8 -0
- package/dist/commands/config.source.command.js +42 -0
- package/dist/commands/config.source.command.js.map +1 -0
- package/dist/commands/config.validate.command.d.ts +14 -0
- package/dist/commands/config.validate.command.js +63 -0
- package/dist/commands/config.validate.command.js.map +1 -0
- package/dist/commands/dev.command.d.ts +1 -0
- package/dist/commands/dev.command.js +1 -0
- package/dist/commands/dev.command.js.map +1 -1
- package/dist/commands/docs.widgets.command.d.ts +11 -0
- package/dist/commands/docs.widgets.command.js +17 -0
- package/dist/commands/docs.widgets.command.js.map +1 -0
- package/dist/commands/doctor.command.d.ts +1 -0
- package/dist/commands/doctor.command.js +36 -6
- package/dist/commands/doctor.command.js.map +1 -1
- package/dist/commands/graph.command.d.ts +10 -0
- package/dist/commands/graph.command.js +21 -0
- package/dist/commands/graph.command.js.map +1 -0
- package/dist/commands/help.command.d.ts +1 -0
- package/dist/commands/help.command.js +2 -2
- package/dist/commands/help.command.js.map +1 -1
- package/dist/commands/info.command.d.ts +8 -0
- package/dist/commands/info.command.js +61 -0
- package/dist/commands/info.command.js.map +1 -0
- package/dist/commands/lsp.command.d.ts +12 -0
- package/dist/commands/lsp.command.js +57 -0
- package/dist/commands/lsp.command.js.map +1 -0
- package/dist/commands/make.command.d.ts +2 -0
- package/dist/commands/make.command.js +75 -4
- package/dist/commands/make.command.js.map +1 -1
- package/dist/commands/plugins.list.command.d.ts +12 -0
- package/dist/commands/plugins.list.command.js +29 -0
- package/dist/commands/plugins.list.command.js.map +1 -0
- package/dist/commands/plugins.update.command.d.ts +29 -0
- package/dist/commands/plugins.update.command.js +78 -0
- package/dist/commands/plugins.update.command.js.map +1 -0
- package/dist/commands/plugins.watch.command.d.ts +10 -0
- package/dist/commands/plugins.watch.command.js +37 -0
- package/dist/commands/plugins.watch.command.js.map +1 -0
- package/dist/commands/replay.command.d.ts +10 -0
- package/dist/commands/replay.command.js +50 -0
- package/dist/commands/replay.command.js.map +1 -0
- package/dist/commands/storybook.command.d.ts +11 -0
- package/dist/commands/storybook.command.js +84 -0
- package/dist/commands/storybook.command.js.map +1 -0
- package/dist/commands/telemetry.command.d.ts +12 -0
- package/dist/commands/telemetry.command.js +55 -0
- package/dist/commands/telemetry.command.js.map +1 -0
- package/dist/commands/test.command.d.ts +13 -0
- package/dist/commands/test.command.js +83 -0
- package/dist/commands/test.command.js.map +1 -0
- package/dist/commands/tutorial.command.d.ts +12 -0
- package/dist/commands/tutorial.command.js +57 -0
- package/dist/commands/tutorial.command.js.map +1 -0
- package/dist/commands/version.command.d.ts +1 -0
- package/dist/commands/version.command.js +1 -0
- package/dist/commands/version.command.js.map +1 -1
- package/dist/commands/watch.command.d.ts +13 -0
- package/dist/commands/watch.command.js +62 -0
- package/dist/commands/watch.command.js.map +1 -0
- package/dist/index.d.ts +8 -5
- package/dist/index.js +8 -5
- package/dist/index.js.map +1 -1
- package/dist/lsp.d.ts +147 -0
- package/dist/lsp.js +497 -0
- package/dist/lsp.js.map +1 -0
- package/dist/run.d.ts +4 -2
- package/dist/run.js +372 -37
- package/dist/run.js.map +1 -1
- package/dist/watcher.d.ts +20 -1
- package/dist/watcher.js +41 -4
- package/dist/watcher.js.map +1 -1
- package/package.json +27 -10
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Command } from '@mudah-cli/console';
|
|
2
|
+
import { decodeLspFrames, encodeLspFrame, handleLspMessage, initializeResult, publishDiagnostics, uriOf, } from '../lsp.js';
|
|
3
|
+
/**
|
|
4
|
+
* Built-in `lsp` command: stdio JSON-RPC (Content-Length framed, with a
|
|
5
|
+
* newline-delimited fallback for probes).
|
|
6
|
+
*/
|
|
7
|
+
export default class LspCommand extends Command {
|
|
8
|
+
signature = 'lsp [--stdio] [--probe]';
|
|
9
|
+
description = 'Language server for mudah.json keys and command signatures';
|
|
10
|
+
descriptionKey = 'cmd.lsp.description';
|
|
11
|
+
async handle() {
|
|
12
|
+
if (this.option('probe') === true) {
|
|
13
|
+
const ready = initializeResult();
|
|
14
|
+
this.output.raw(`${JSON.stringify({ jsonrpc: '2.0', id: 1, result: ready })}\n`);
|
|
15
|
+
return 0;
|
|
16
|
+
}
|
|
17
|
+
if (this.option('stdio') === true) {
|
|
18
|
+
return this.serveStdio();
|
|
19
|
+
}
|
|
20
|
+
this.output.success('mudah-lsp ready');
|
|
21
|
+
this.output.muted('Pass --stdio to speak JSON-RPC on stdin/stdout, or --probe to print initialize.');
|
|
22
|
+
return 0;
|
|
23
|
+
}
|
|
24
|
+
serveStdio() {
|
|
25
|
+
return new Promise((resolve) => {
|
|
26
|
+
let buffer = '';
|
|
27
|
+
const write = (msg) => {
|
|
28
|
+
process.stdout.write(encodeLspFrame(msg));
|
|
29
|
+
};
|
|
30
|
+
process.stdin.setEncoding('utf8');
|
|
31
|
+
process.stdin.on('data', (chunk) => {
|
|
32
|
+
buffer += chunk;
|
|
33
|
+
const decoded = decodeLspFrames(buffer);
|
|
34
|
+
buffer = decoded.rest;
|
|
35
|
+
for (const msg of decoded.messages) {
|
|
36
|
+
if (msg.method === 'exit') {
|
|
37
|
+
resolve(0);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const reply = handleLspMessage(msg);
|
|
41
|
+
if (reply !== undefined)
|
|
42
|
+
write(reply);
|
|
43
|
+
if (msg.method === 'textDocument/didOpen' || msg.method === 'textDocument/didChange') {
|
|
44
|
+
const notice = publishDiagnostics(uriOf(msg.params));
|
|
45
|
+
if (notice !== undefined)
|
|
46
|
+
write(notice);
|
|
47
|
+
}
|
|
48
|
+
if (msg.method === 'shutdown') {
|
|
49
|
+
resolve(0);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
process.stdin.on('end', () => resolve(0));
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=lsp.command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lsp.command.js","sourceRoot":"","sources":["../../src/commands/lsp.command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EACL,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAEhB,kBAAkB,EAClB,KAAK,GACN,MAAM,WAAW,CAAC;AAEnB;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,OAAO;IAC7C,SAAS,GAAG,yBAAyB,CAAC;IACtC,WAAW,GAAG,4DAA4D,CAAC;IAC3E,cAAc,GAAG,qBAAqB,CAAC;IAEvC,KAAK,CAAC,MAAM;QACV,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;YACjC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC;YACjF,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;YAClC,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iFAAiF,CAAC,CAAC;QACrG,OAAO,CAAC,CAAC;IACX,CAAC;IAEO,UAAU;QAChB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,MAAM,KAAK,GAAG,CAAC,GAAe,EAAQ,EAAE;gBACtC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;YAC5C,CAAC,CAAC;YACF,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YAClC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;gBACzC,MAAM,IAAI,KAAK,CAAC;gBAChB,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;gBACxC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;gBACtB,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;oBACnC,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;wBAC1B,OAAO,CAAC,CAAC,CAAC,CAAC;wBACX,OAAO;oBACT,CAAC;oBACD,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;oBACpC,IAAI,KAAK,KAAK,SAAS;wBAAE,KAAK,CAAC,KAAK,CAAC,CAAC;oBACtC,IAAI,GAAG,CAAC,MAAM,KAAK,sBAAsB,IAAI,GAAG,CAAC,MAAM,KAAK,wBAAwB,EAAE,CAAC;wBACrF,MAAM,MAAM,GAAG,kBAAkB,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;wBACrD,IAAI,MAAM,KAAK,SAAS;4BAAE,KAAK,CAAC,MAAM,CAAC,CAAC;oBAC1C,CAAC;oBACD,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;wBAC9B,OAAO,CAAC,CAAC,CAAC,CAAC;oBACb,CAAC;gBACH,CAAC;YACH,CAAC,CAAC,CAAC;YACH,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
1
2
|
import { mkdir, writeFile } from 'node:fs/promises';
|
|
2
3
|
import { isAbsolute, join, relative } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
3
5
|
import { Command } from '@mudah-cli/console';
|
|
6
|
+
/** Peer range for a generated plugin, matching the installed framework version. */
|
|
7
|
+
function mudahRange() {
|
|
8
|
+
const pkg = JSON.parse(readFileSync(fileURLToPath(new URL('../../package.json', import.meta.url)), 'utf8'));
|
|
9
|
+
return `^${pkg.version}`;
|
|
10
|
+
}
|
|
4
11
|
function kebab(name) {
|
|
5
12
|
return name.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
|
|
6
13
|
}
|
|
@@ -35,7 +42,41 @@ export default defineConfig({
|
|
|
35
42
|
// Add configuration for this component.
|
|
36
43
|
});
|
|
37
44
|
`;
|
|
38
|
-
const TUI_HINT = 'Use: make {command|provider|config|tui} {name}';
|
|
45
|
+
const TUI_HINT = 'Use: make {command|provider|config|tui|plugin} {name}';
|
|
46
|
+
const PLUGIN_PACKAGE = (name) => `${JSON.stringify({
|
|
47
|
+
name,
|
|
48
|
+
version: '0.1.0',
|
|
49
|
+
private: true,
|
|
50
|
+
description: `${name} — a Mudah plugin`,
|
|
51
|
+
type: 'module',
|
|
52
|
+
license: 'MIT',
|
|
53
|
+
keywords: ['mudah-plugin', 'cli'],
|
|
54
|
+
exports: { '.': './src/index.ts' },
|
|
55
|
+
dependencies: { '@mudah-cli/mudah': mudahRange() },
|
|
56
|
+
}, null, 2)}\n`;
|
|
57
|
+
const PLUGIN_INDEX = (name, className) => `import { Command, ServiceProvider } from '@mudah-cli/mudah';
|
|
58
|
+
|
|
59
|
+
/** Binds services this plugin contributes. */
|
|
60
|
+
export class ${className}Provider extends ServiceProvider {
|
|
61
|
+
register(): void {}
|
|
62
|
+
|
|
63
|
+
boot(): void {}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export class ${className}HelloCommand extends Command {
|
|
67
|
+
signature = '${name}:hello';
|
|
68
|
+
description = 'Hello from the ${name} plugin';
|
|
69
|
+
groupDescription = '${className} plugin';
|
|
70
|
+
|
|
71
|
+
async handle(): Promise<number> {
|
|
72
|
+
this.output.success('Hello from ${name}');
|
|
73
|
+
return 0;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export const providers = [${className}Provider];
|
|
78
|
+
export const commands = [${className}HelloCommand];
|
|
79
|
+
`;
|
|
39
80
|
const TUI_PICKER = (command, className) => `import { Command } from '@mudah-cli/mudah';
|
|
40
81
|
import { Program, Screen } from '@mudah-cli/mudah/tui';
|
|
41
82
|
|
|
@@ -115,11 +156,12 @@ export default class ${className} extends Command {
|
|
|
115
156
|
*/
|
|
116
157
|
export default class MakeCommand extends Command {
|
|
117
158
|
signature = 'make {type} {name}';
|
|
118
|
-
description = 'Scaffold a command, provider, config file,
|
|
159
|
+
description = 'Scaffold a command, provider, config file, TUI screen, or plugin';
|
|
160
|
+
descriptionKey = 'cmd.make.description';
|
|
119
161
|
async handle() {
|
|
120
162
|
const type = this.arg('type');
|
|
121
163
|
const name = this.arg('name');
|
|
122
|
-
if (!['command', 'provider', 'config', 'tui'].includes(type)) {
|
|
164
|
+
if (!['command', 'provider', 'config', 'tui', 'plugin'].includes(type)) {
|
|
123
165
|
throw this.usageError(`Unknown make type "${type}".`, TUI_HINT);
|
|
124
166
|
}
|
|
125
167
|
if (!/^[a-zA-Z][a-zA-Z0-9-]*$/.test(name)) {
|
|
@@ -127,6 +169,10 @@ export default class MakeCommand extends Command {
|
|
|
127
169
|
}
|
|
128
170
|
const k = kebab(name);
|
|
129
171
|
const className = pascal(name);
|
|
172
|
+
if (type === 'plugin') {
|
|
173
|
+
await this.writePlugin(k, className);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
130
176
|
let filePath;
|
|
131
177
|
let content;
|
|
132
178
|
if (type === 'command') {
|
|
@@ -142,7 +188,12 @@ export default class MakeCommand extends Command {
|
|
|
142
188
|
throw this.usageError(`Unknown TUI recipe "${name}".`, 'Use: make tui {picker|wizard|dashboard}');
|
|
143
189
|
}
|
|
144
190
|
filePath = join(this.app.basePath, 'src', 'commands', `${k}.command.ts`);
|
|
145
|
-
content =
|
|
191
|
+
content =
|
|
192
|
+
k === 'wizard'
|
|
193
|
+
? TUI_WIZARD(k, className)
|
|
194
|
+
: k === 'dashboard'
|
|
195
|
+
? TUI_DASHBOARD(k, className)
|
|
196
|
+
: TUI_PICKER(k, className);
|
|
146
197
|
}
|
|
147
198
|
else {
|
|
148
199
|
filePath = join(this.app.basePath, 'config', `${k}.ts`);
|
|
@@ -163,5 +214,25 @@ export default class MakeCommand extends Command {
|
|
|
163
214
|
}
|
|
164
215
|
this.output.success(`Created ${relative(this.app.basePath, filePath)}`);
|
|
165
216
|
}
|
|
217
|
+
async writePlugin(k, className) {
|
|
218
|
+
const dir = join(this.app.basePath, `${k}-plugin`);
|
|
219
|
+
if (isAbsolute(dir) === false || !dir.startsWith(this.app.basePath)) {
|
|
220
|
+
throw this.usageError('Refusing to write outside the app directory.');
|
|
221
|
+
}
|
|
222
|
+
const pkgPath = join(dir, 'package.json');
|
|
223
|
+
const srcPath = join(dir, 'src', 'index.ts');
|
|
224
|
+
try {
|
|
225
|
+
await mkdir(join(dir, 'src'), { recursive: true });
|
|
226
|
+
await writeFile(pkgPath, PLUGIN_PACKAGE(k), { flag: 'wx' });
|
|
227
|
+
await writeFile(srcPath, PLUGIN_INDEX(k, className), { flag: 'wx' });
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
if (error.code === 'EEXIST') {
|
|
231
|
+
throw this.usageError(`${relative(this.app.basePath, dir)} already exists.`);
|
|
232
|
+
}
|
|
233
|
+
throw error;
|
|
234
|
+
}
|
|
235
|
+
this.output.success(`Created ${relative(this.app.basePath, srcPath)}`);
|
|
236
|
+
}
|
|
166
237
|
}
|
|
167
238
|
//# sourceMappingURL=make.command.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"make.command.js","sourceRoot":"","sources":["../../src/commands/make.command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,SAAS,KAAK,CAAC,IAAY;IACzB,OAAO,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;AACnE,CAAC;AAED,SAAS,MAAM,CAAC,IAAY;IAC1B,OAAO,KAAK,CAAC,IAAI,CAAC;SACf,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAC3D,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED,MAAM,gBAAgB,GAAG,
|
|
1
|
+
{"version":3,"file":"make.command.js","sourceRoot":"","sources":["../../src/commands/make.command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Command } from '@mudah-cli/console';
|
|
2
|
+
/**
|
|
3
|
+
* Built-in `plugins:list` — discovered plugins and how many providers each
|
|
4
|
+
* registered. Alias: `plugins`.
|
|
5
|
+
*/
|
|
6
|
+
export default class PluginsListCommand extends Command {
|
|
7
|
+
signature: string;
|
|
8
|
+
description: string;
|
|
9
|
+
descriptionKey: string;
|
|
10
|
+
aliases: string[];
|
|
11
|
+
handle(): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Command } from '@mudah-cli/console';
|
|
2
|
+
import { t } from '@mudah-cli/core';
|
|
3
|
+
/**
|
|
4
|
+
* Built-in `plugins:list` — discovered plugins and how many providers each
|
|
5
|
+
* registered. Alias: `plugins`.
|
|
6
|
+
*/
|
|
7
|
+
export default class PluginsListCommand extends Command {
|
|
8
|
+
signature = 'plugins:list';
|
|
9
|
+
description = 'List discovered plugins';
|
|
10
|
+
descriptionKey = 'cmd.plugins.list.description';
|
|
11
|
+
aliases = ['plugins'];
|
|
12
|
+
async handle() {
|
|
13
|
+
const plugins = pluginsOf(this.app);
|
|
14
|
+
if (plugins.length === 0) {
|
|
15
|
+
this.output.info(t('plugins.none'));
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
this.output.section('Plugins');
|
|
19
|
+
for (const plugin of plugins) {
|
|
20
|
+
this.output.keyValue(plugin.name, `${plugin.providers.length} provider(s)`);
|
|
21
|
+
}
|
|
22
|
+
this.output.line();
|
|
23
|
+
this.output.success(t('plugins.listed', { count: plugins.length }));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function pluginsOf(app) {
|
|
27
|
+
return typeof app.plugins === 'function' ? app.plugins() : [];
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=plugins.list.command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugins.list.command.js","sourceRoot":"","sources":["../../src/commands/plugins.list.command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAmB,CAAC,EAAE,MAAM,iBAAiB,CAAC;AAErD;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,OAAO;IACrD,SAAS,GAAG,cAAc,CAAC;IAC3B,WAAW,GAAG,yBAAyB,CAAC;IACxC,cAAc,GAAG,8BAA8B,CAAC;IAChD,OAAO,GAAG,CAAC,SAAS,CAAC,CAAC;IAEtB,KAAK,CAAC,MAAM;QACV,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC;YACpC,OAAO;QACT,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC/B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,cAAc,CAAC,CAAC;QAC9E,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACnB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACtE,CAAC;CACF;AAED,SAAS,SAAS,CAAC,GAA8C;IAC/D,OAAO,OAAO,GAAG,CAAC,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAChE,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Command } from '@mudah-cli/console';
|
|
2
|
+
export interface RegistryLatest {
|
|
3
|
+
readonly name: string;
|
|
4
|
+
readonly version: string;
|
|
5
|
+
}
|
|
6
|
+
export type PluginUpdateSpawn = (command: string, args: readonly string[], options: {
|
|
7
|
+
cwd: string;
|
|
8
|
+
encoding: 'utf8';
|
|
9
|
+
}) => {
|
|
10
|
+
status: number | null;
|
|
11
|
+
stdout: string;
|
|
12
|
+
stderr: string;
|
|
13
|
+
error?: Error;
|
|
14
|
+
};
|
|
15
|
+
export declare function fetchLatestVersion(name: string, doFetch?: typeof fetch): Promise<string | undefined>;
|
|
16
|
+
export declare function applyPluginUpdate(name: string, cwd: string, spawn?: PluginUpdateSpawn): {
|
|
17
|
+
ok: boolean;
|
|
18
|
+
detail: string;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Built-in `plugins:update` — compare installed plugin versions to the npm
|
|
22
|
+
* registry. `--apply` runs `npm install name@latest` for each outdated plugin.
|
|
23
|
+
*/
|
|
24
|
+
export default class PluginsUpdateCommand extends Command {
|
|
25
|
+
signature: string;
|
|
26
|
+
description: string;
|
|
27
|
+
descriptionKey: string;
|
|
28
|
+
handle(): Promise<0 | 1>;
|
|
29
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { Command } from '@mudah-cli/console';
|
|
3
|
+
import { t } from '@mudah-cli/core';
|
|
4
|
+
export async function fetchLatestVersion(name, doFetch = fetch) {
|
|
5
|
+
const url = `https://registry.npmjs.org/${encodeURIComponent(name)}/latest`;
|
|
6
|
+
try {
|
|
7
|
+
const response = await doFetch(url, { headers: { accept: 'application/json' } });
|
|
8
|
+
if (!response.ok)
|
|
9
|
+
return undefined;
|
|
10
|
+
const body = (await response.json());
|
|
11
|
+
return typeof body.version === 'string' ? body.version : undefined;
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export function applyPluginUpdate(name, cwd, spawn = (command, args, options) => spawnSync(command, [...args], options)) {
|
|
18
|
+
const result = spawn('npm', ['install', `${name}@latest`], { cwd, encoding: 'utf8' });
|
|
19
|
+
if (result.error)
|
|
20
|
+
return { ok: false, detail: result.error.message };
|
|
21
|
+
if (result.status !== 0) {
|
|
22
|
+
return {
|
|
23
|
+
ok: false,
|
|
24
|
+
detail: (result.stderr || result.stdout || `npm exit ${String(result.status)}`).trim(),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
return { ok: true, detail: 'installed' };
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Built-in `plugins:update` — compare installed plugin versions to the npm
|
|
31
|
+
* registry. `--apply` runs `npm install name@latest` for each outdated plugin.
|
|
32
|
+
*/
|
|
33
|
+
export default class PluginsUpdateCommand extends Command {
|
|
34
|
+
signature = 'plugins:update [--apply]';
|
|
35
|
+
description = 'Check the npm registry for plugin updates and optionally install them';
|
|
36
|
+
descriptionKey = 'cmd.plugins.update.description';
|
|
37
|
+
async handle() {
|
|
38
|
+
const plugins = await this.app.reloadPlugins();
|
|
39
|
+
const doFetch = this.app.has('plugins.fetch') ? this.app.make('plugins.fetch') : fetch;
|
|
40
|
+
const spawn = this.app.has('plugins.spawn')
|
|
41
|
+
? this.app.make('plugins.spawn')
|
|
42
|
+
: (command, args, options) => spawnSync(command, [...args], options);
|
|
43
|
+
const apply = this.option('apply') === true;
|
|
44
|
+
let outdated = 0;
|
|
45
|
+
let failed = 0;
|
|
46
|
+
this.output.section('Plugins');
|
|
47
|
+
for (const plugin of plugins) {
|
|
48
|
+
const latest = await fetchLatestVersion(plugin.name, doFetch);
|
|
49
|
+
const current = plugin.version ?? 'unknown';
|
|
50
|
+
if (latest !== undefined && current !== 'unknown' && latest !== current) {
|
|
51
|
+
this.output.warn(`${plugin.name} ${current} → ${latest}`);
|
|
52
|
+
outdated += 1;
|
|
53
|
+
if (apply) {
|
|
54
|
+
const result = applyPluginUpdate(plugin.name, this.app.basePath, spawn);
|
|
55
|
+
if (result.ok)
|
|
56
|
+
this.output.success(`${plugin.name} installed ${latest}`);
|
|
57
|
+
else {
|
|
58
|
+
this.output.error(`${plugin.name} ${result.detail}`);
|
|
59
|
+
failed += 1;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
this.output.keyValue(plugin.name, latest ?? current);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (outdated === 0)
|
|
68
|
+
this.output.success(t('plugins.upToDate'));
|
|
69
|
+
else if (!apply)
|
|
70
|
+
this.output.warn(`${outdated} plugin(s) have a newer version on npm. Pass --apply to install.`);
|
|
71
|
+
this.output.keyValue('plugins', String(plugins.length));
|
|
72
|
+
for (const warning of this.app.pluginWarnings()) {
|
|
73
|
+
this.output.warn(warning);
|
|
74
|
+
}
|
|
75
|
+
return failed > 0 ? 1 : 0;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=plugins.update.command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugins.update.command.js","sourceRoot":"","sources":["../../src/commands/plugins.update.command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Command } from '@mudah-cli/console';
|
|
2
|
+
/**
|
|
3
|
+
* Built-in `plugins:watch` — re-import providers when `node_modules` changes.
|
|
4
|
+
*/
|
|
5
|
+
export default class PluginsWatchCommand extends Command {
|
|
6
|
+
signature: string;
|
|
7
|
+
description: string;
|
|
8
|
+
descriptionKey: string;
|
|
9
|
+
handle(): Promise<number>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { Command } from '@mudah-cli/console';
|
|
3
|
+
import { t } from '@mudah-cli/core';
|
|
4
|
+
import { hotReloadPlugins } from '../watcher.js';
|
|
5
|
+
/**
|
|
6
|
+
* Built-in `plugins:watch` — re-import providers when `node_modules` changes.
|
|
7
|
+
*/
|
|
8
|
+
export default class PluginsWatchCommand extends Command {
|
|
9
|
+
signature = 'plugins:watch [--debounce=] [--once]';
|
|
10
|
+
description = 'Watch node_modules and reload plugin providers';
|
|
11
|
+
descriptionKey = 'cmd.plugins.watch.description';
|
|
12
|
+
async handle() {
|
|
13
|
+
const debounce = Number(this.option('debounce') ?? 200) || 200;
|
|
14
|
+
const dir = join(this.app.basePath, 'node_modules');
|
|
15
|
+
this.output.section('Plugin watch');
|
|
16
|
+
this.output.keyValue('dir', dir);
|
|
17
|
+
this.output.keyValue('debounce', `${debounce}ms`);
|
|
18
|
+
const plugins = await this.app.reloadPlugins();
|
|
19
|
+
this.output.muted(`reloaded ${plugins.length} plugin(s)`);
|
|
20
|
+
if (this.option('once') === true || process.stdin.isTTY !== true) {
|
|
21
|
+
this.output.success(t('plugins.reloaded'));
|
|
22
|
+
return 0;
|
|
23
|
+
}
|
|
24
|
+
const stop = hotReloadPlugins(this.app, () => {
|
|
25
|
+
this.output.muted('change detected — reloading plugins…');
|
|
26
|
+
}, { debounceMs: debounce, dir });
|
|
27
|
+
this.output.muted('watching for plugin changes (ctrl+c to stop)');
|
|
28
|
+
await new Promise((resolve) => {
|
|
29
|
+
process.once('SIGINT', () => {
|
|
30
|
+
stop();
|
|
31
|
+
resolve();
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
return 0;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=plugins.watch.command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugins.watch.command.js","sourceRoot":"","sources":["../../src/commands/plugins.watch.command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,CAAC,EAAE,MAAM,iBAAiB,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,mBAAoB,SAAQ,OAAO;IACtD,SAAS,GAAG,sCAAsC,CAAC;IACnD,WAAW,GAAG,gDAAgD,CAAC;IAC/D,cAAc,GAAG,+BAA+B,CAAC;IAEjD,KAAK,CAAC,MAAM;QACV,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC;QAC/D,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QACpD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACpC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,GAAG,QAAQ,IAAI,CAAC,CAAC;QAElD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC/C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,OAAO,CAAC,MAAM,YAAY,CAAC,CAAC;QAE1D,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;YACjE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC;YAC3C,OAAO,CAAC,CAAC;QACX,CAAC;QAED,MAAM,IAAI,GAAG,gBAAgB,CAC3B,IAAI,CAAC,GAAG,EACR,GAAG,EAAE;YACH,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC5D,CAAC,EACD,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,CAC9B,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAClE,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAClC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE;gBAC1B,IAAI,EAAE,CAAC;gBACP,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,CAAC;IACX,CAAC;CACF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Command } from '@mudah-cli/console';
|
|
2
|
+
/**
|
|
3
|
+
* Built-in `replay` command: print or apply a structured session tape.
|
|
4
|
+
*/
|
|
5
|
+
export default class ReplayCommand extends Command {
|
|
6
|
+
signature: string;
|
|
7
|
+
description: string;
|
|
8
|
+
descriptionKey: string;
|
|
9
|
+
handle(): Promise<number>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { Command } from '@mudah-cli/console';
|
|
3
|
+
/**
|
|
4
|
+
* Built-in `replay` command: print or apply a structured session tape.
|
|
5
|
+
*/
|
|
6
|
+
export default class ReplayCommand extends Command {
|
|
7
|
+
signature = 'replay {file?} [--play] [--speed=]';
|
|
8
|
+
description = 'Replay a structured TUI session JSON file';
|
|
9
|
+
descriptionKey = 'cmd.replay.description';
|
|
10
|
+
async handle() {
|
|
11
|
+
const file = this.arg('file');
|
|
12
|
+
if (file === undefined) {
|
|
13
|
+
this.output.info('Usage: replay {file} [--play]');
|
|
14
|
+
this.output.muted('JSON { version, events: [{ type, t?, key?, text? }] } or a bare event array');
|
|
15
|
+
return 0;
|
|
16
|
+
}
|
|
17
|
+
const { parseSessionTape, replayTapeAsync, Column, Label } = await import('@mudah-cli/tui');
|
|
18
|
+
let tape;
|
|
19
|
+
try {
|
|
20
|
+
tape = parseSessionTape(JSON.parse(await readFile(file, 'utf8')));
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
24
|
+
throw this.usageError(`Cannot read session file "${file}".`, message);
|
|
25
|
+
}
|
|
26
|
+
this.output.section(`Replay ${file}`);
|
|
27
|
+
this.output.keyValue('events', String(tape.events.length));
|
|
28
|
+
this.output.keyValue('recorded', tape.recordedAt);
|
|
29
|
+
for (const [i, event] of tape.events.entries()) {
|
|
30
|
+
const extra = event.key ?? event.text ?? `${event.x ?? 0},${event.y ?? 0}`;
|
|
31
|
+
this.output.raw(` ${i + 1}. +${event.t ?? 0}ms ${event.type} ${extra}\n`);
|
|
32
|
+
}
|
|
33
|
+
if (this.option('play') === true) {
|
|
34
|
+
const { TestTui } = await import('@mudah-cli/testing');
|
|
35
|
+
const target = this.app.has('replay.target')
|
|
36
|
+
? this.app.make('replay.target')
|
|
37
|
+
: TestTui.mount(new Column().add(new Label('replay')), {
|
|
38
|
+
cols: tape.cols ?? 80,
|
|
39
|
+
rows: tape.rows ?? 24,
|
|
40
|
+
});
|
|
41
|
+
await replayTapeAsync(target, tape, { speed: Number(this.option('speed') ?? 1) || 1 });
|
|
42
|
+
if ('snapshot' in target && typeof target.snapshot === 'function') {
|
|
43
|
+
this.output.raw(`${target.snapshot()}\n`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
this.output.success('replay complete');
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=replay.command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replay.command.js","sourceRoot":"","sources":["../../src/commands/replay.command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Command } from '@mudah-cli/console';
|
|
2
|
+
/**
|
|
3
|
+
* Built-in `storybook` command: widget gallery. Prints snapshots when not a
|
|
4
|
+
* TTY. On a TTY, opens a Program: left/right pick a widget, +/− resize.
|
|
5
|
+
*/
|
|
6
|
+
export default class StorybookCommand extends Command {
|
|
7
|
+
signature: string;
|
|
8
|
+
description: string;
|
|
9
|
+
descriptionKey: string;
|
|
10
|
+
handle(): Promise<number>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { Command } from '@mudah-cli/console';
|
|
2
|
+
async function stories() {
|
|
3
|
+
const { Calendar, Chart, Checkbox, Column, DatePicker, Label, List, Pager, ProgressBar, Table, Toolbar } = await import('@mudah-cli/tui');
|
|
4
|
+
return [
|
|
5
|
+
{ name: 'label', build: () => new Column().add(new Label('Label story')) },
|
|
6
|
+
{ name: 'list', build: () => new Column().add(new Label('List story'), new List(['alpha', 'beta'])) },
|
|
7
|
+
{
|
|
8
|
+
name: 'toolbar',
|
|
9
|
+
build: () => new Column().add(new Label('Toolbar story'), new Toolbar({
|
|
10
|
+
items: [
|
|
11
|
+
{ id: 'run', label: 'Run' },
|
|
12
|
+
{ id: 'stop', label: 'Stop' },
|
|
13
|
+
],
|
|
14
|
+
})),
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: 'checkbox',
|
|
18
|
+
build: () => new Column().add(new Label('Checkbox story'), new Checkbox({ label: 'enabled', checked: true })),
|
|
19
|
+
},
|
|
20
|
+
{ name: 'progress', build: () => new Column().add(new Label('Progress story'), new ProgressBar(0.42)) },
|
|
21
|
+
{
|
|
22
|
+
name: 'table',
|
|
23
|
+
build: () => new Column().add(new Label('Table story'), new Table([{ header: 'Host' }, { header: 'State' }], [['db', 'up']])),
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: 'pager',
|
|
27
|
+
build: () => new Column().add(new Pager({ title: 'Pager story', lines: ['alpha', 'beta', 'gamma'] })),
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'calendar',
|
|
31
|
+
build: () => new Column().add(new Label('Calendar story'), new Calendar({ date: new Date('2026-09-01T00:00:00Z') })),
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: 'datepicker',
|
|
35
|
+
build: () => new Column().add(new Label('DatePicker story'), new DatePicker({ date: new Date('2026-09-01T00:00:00Z') })),
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'chart',
|
|
39
|
+
build: () => new Column().add(new Label('Chart story'), new Chart({
|
|
40
|
+
kind: 'bar',
|
|
41
|
+
entries: [
|
|
42
|
+
{ label: 'a', value: 3 },
|
|
43
|
+
{ label: 'b', value: 1 },
|
|
44
|
+
],
|
|
45
|
+
})),
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Built-in `storybook` command: widget gallery. Prints snapshots when not a
|
|
51
|
+
* TTY. On a TTY, opens a Program: left/right pick a widget, +/− resize.
|
|
52
|
+
*/
|
|
53
|
+
export default class StorybookCommand extends Command {
|
|
54
|
+
signature = 'storybook {widget?} [--cols=] [--rows=]';
|
|
55
|
+
description = 'Open a TUI widget gallery with live resize';
|
|
56
|
+
descriptionKey = 'cmd.storybook.description';
|
|
57
|
+
async handle() {
|
|
58
|
+
const cols = Number(this.option('cols') ?? 40) || 40;
|
|
59
|
+
const rows = Number(this.option('rows') ?? 8) || 8;
|
|
60
|
+
const filter = this.arg('widget');
|
|
61
|
+
const all = await stories();
|
|
62
|
+
const shown = filter ? all.filter((entry) => entry.name === filter) : all;
|
|
63
|
+
if (shown.length === 0) {
|
|
64
|
+
throw this.usageError(`Unknown widget "${filter}".`, `Known: ${all.map((s) => s.name).join(', ')}`);
|
|
65
|
+
}
|
|
66
|
+
const tty = process.stdin.isTTY === true && process.stdout.isTTY === true;
|
|
67
|
+
if (tty && process.env['VITEST'] === undefined) {
|
|
68
|
+
const { Program, StorybookGallery } = await import('@mudah-cli/tui');
|
|
69
|
+
const gallery = new StorybookGallery(shown, cols, rows);
|
|
70
|
+
const program = new Program();
|
|
71
|
+
program.mount(gallery);
|
|
72
|
+
return program.run();
|
|
73
|
+
}
|
|
74
|
+
const { TestTui } = await import('@mudah-cli/testing');
|
|
75
|
+
const snapshot = (root, width, height) => TestTui.mount(root, { cols: width, rows: height }).snapshot();
|
|
76
|
+
this.output.section(`Storybook ${cols}x${rows}`);
|
|
77
|
+
for (const entry of shown) {
|
|
78
|
+
this.output.raw(`${snapshot(entry.build(cols, rows), cols, rows)}\n\n`);
|
|
79
|
+
}
|
|
80
|
+
this.output.success('storybook complete');
|
|
81
|
+
return 0;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=storybook.command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storybook.command.js","sourceRoot":"","sources":["../../src/commands/storybook.command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Command } from '@mudah-cli/console';
|
|
2
|
+
/**
|
|
3
|
+
* Built-in `telemetry` — summarize the events written to
|
|
4
|
+
* `.mudah/telemetry.jsonl` (see `telemetry: true` in `mudah.json`), or clear
|
|
5
|
+
* the log. Under `--json` the summary is emitted as a data payload.
|
|
6
|
+
*/
|
|
7
|
+
export default class TelemetryCommand extends Command {
|
|
8
|
+
signature: string;
|
|
9
|
+
description: string;
|
|
10
|
+
descriptionKey: string;
|
|
11
|
+
handle(): Promise<void>;
|
|
12
|
+
}
|