@pablozaiden/terminatui 0.6.0 → 0.6.3
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/package.json +1 -1
- package/src/builtins/help.ts +13 -0
- package/src/core/application.ts +24 -34
- package/src/core/help.ts +8 -2
- package/src/types/execution.ts +0 -11
package/package.json
CHANGED
package/src/builtins/help.ts
CHANGED
|
@@ -21,6 +21,7 @@ export class HelpCommand extends Command<OptionSchema> {
|
|
|
21
21
|
private allCommands: AnyCommand[] = [];
|
|
22
22
|
private appName: string;
|
|
23
23
|
private appVersion: string;
|
|
24
|
+
private commandPath: string[] = [];
|
|
24
25
|
|
|
25
26
|
constructor(config: {
|
|
26
27
|
parentCommand?: AnyCommand;
|
|
@@ -35,6 +36,14 @@ export class HelpCommand extends Command<OptionSchema> {
|
|
|
35
36
|
this.appVersion = config.appVersion;
|
|
36
37
|
}
|
|
37
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Set the command path for this help command.
|
|
41
|
+
* Called by the Application before executing help.
|
|
42
|
+
*/
|
|
43
|
+
setCommandPath(path: string[]): void {
|
|
44
|
+
this.commandPath = path;
|
|
45
|
+
}
|
|
46
|
+
|
|
38
47
|
/**
|
|
39
48
|
* Help command is CLI-only (auto-injected for CLI use, not shown in TUI).
|
|
40
49
|
*/
|
|
@@ -45,11 +54,15 @@ export class HelpCommand extends Command<OptionSchema> {
|
|
|
45
54
|
override async execute(): Promise<CommandResult> {
|
|
46
55
|
let helpText: string;
|
|
47
56
|
|
|
57
|
+
// Get the parent command path (exclude "help" from the end if present)
|
|
58
|
+
const parentPath = this.commandPath.filter(p => p !== KNOWN_COMMANDS.help);
|
|
59
|
+
|
|
48
60
|
if (this.parentCommand) {
|
|
49
61
|
// Show help for the parent command
|
|
50
62
|
helpText = generateCommandHelp(this.parentCommand, {
|
|
51
63
|
appName: this.appName,
|
|
52
64
|
version: this.appVersion,
|
|
65
|
+
commandPath: parentPath,
|
|
53
66
|
globalOptionsSchema: GLOBAL_OPTIONS_SCHEMA,
|
|
54
67
|
});
|
|
55
68
|
} else {
|
package/src/core/application.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { AppContext, type AppConfig } from "./context.ts";
|
|
2
2
|
import { Command, type AnyCommand, ConfigValidationError, type CommandExecutionContext } from "./command.ts";
|
|
3
3
|
import { CommandRegistry } from "./registry.ts";
|
|
4
|
-
import { ExecutionMode } from "../types/execution.ts";
|
|
5
4
|
import { LogLevel, type LoggerConfig } from "./logger.ts";
|
|
6
5
|
import {
|
|
7
6
|
extractCommandChain,
|
|
@@ -341,8 +340,10 @@ export class Application {
|
|
|
341
340
|
return;
|
|
342
341
|
}
|
|
343
342
|
|
|
344
|
-
//
|
|
345
|
-
|
|
343
|
+
// If this is a help command being executed directly, set its command path
|
|
344
|
+
if ('setCommandPath' in command && typeof command.setCommandPath === 'function') {
|
|
345
|
+
(command as { setCommandPath: (path: string[]) => void }).setCommandPath(commandPath);
|
|
346
|
+
}
|
|
346
347
|
|
|
347
348
|
// Parse options
|
|
348
349
|
const schema = command.options ?? {};
|
|
@@ -364,13 +365,13 @@ export class Application {
|
|
|
364
365
|
let options;
|
|
365
366
|
try {
|
|
366
367
|
options = parseOptionValues(schema, parsedValues);
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
368
|
+
} catch (err) {
|
|
369
|
+
// Enum validation error from parseOptionValues
|
|
370
|
+
AppContext.current.logger.error(`Error: ${(err as Error).message}\n`);
|
|
371
|
+
await this.printHelpForCommand(command, commandPath);
|
|
372
|
+
process.exitCode = 1;
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
374
375
|
|
|
375
376
|
|
|
376
377
|
// Validate options (required, min/max, etc.)
|
|
@@ -409,17 +410,14 @@ export class Application {
|
|
|
409
410
|
const ctx: CommandExecutionContext = { signal: new AbortController().signal };
|
|
410
411
|
const commandResult = await command.execute(config, ctx);
|
|
411
412
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
if (commandResult.
|
|
415
|
-
|
|
416
|
-
if (commandResult.data !== undefined) {
|
|
417
|
-
console.log(JSON.stringify(commandResult.data, null, 2));
|
|
418
|
-
}
|
|
419
|
-
} else {
|
|
420
|
-
// Set exit code for failures
|
|
421
|
-
process.exitCode = 1;
|
|
413
|
+
if (commandResult.success) {
|
|
414
|
+
// Output data as JSON to stdout if present
|
|
415
|
+
if (commandResult.data !== undefined) {
|
|
416
|
+
console.log(JSON.stringify(commandResult.data, null, 2));
|
|
422
417
|
}
|
|
418
|
+
} else {
|
|
419
|
+
// Set exit code for failures
|
|
420
|
+
process.exitCode = 1;
|
|
423
421
|
}
|
|
424
422
|
} catch (e) {
|
|
425
423
|
error = e as Error;
|
|
@@ -456,6 +454,11 @@ export class Application {
|
|
|
456
454
|
throw new Error(`Help command not injected for '${resolvedCommandPath.join(" ")}'`);
|
|
457
455
|
}
|
|
458
456
|
|
|
457
|
+
// Set the command path on the help command so it can generate correct usage
|
|
458
|
+
if ('setCommandPath' in helpCommand && typeof helpCommand.setCommandPath === 'function') {
|
|
459
|
+
(helpCommand as { setCommandPath: (path: string[]) => void }).setCommandPath(resolvedCommandPath);
|
|
460
|
+
}
|
|
461
|
+
|
|
459
462
|
await this.executeCommand(helpCommand, [], [...resolvedCommandPath, KNOWN_COMMANDS.help]);
|
|
460
463
|
}
|
|
461
464
|
|
|
@@ -479,19 +482,6 @@ export class Application {
|
|
|
479
482
|
return !hasCustomExecute;
|
|
480
483
|
}
|
|
481
484
|
|
|
482
|
-
/**
|
|
483
|
-
* Detect the execution mode based on command and args.
|
|
484
|
-
*/
|
|
485
|
-
private detectExecutionMode(command: AnyCommand, args: string[]): ExecutionMode {
|
|
486
|
-
// If no args and command supports TUI, use TUI mode
|
|
487
|
-
if (args.length === 0 && command.supportsTui()) {
|
|
488
|
-
return ExecutionMode.Tui;
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
// Otherwise use CLI mode
|
|
492
|
-
return ExecutionMode.Cli;
|
|
493
|
-
}
|
|
494
|
-
|
|
495
485
|
/**
|
|
496
486
|
* Parse global options from argv.
|
|
497
487
|
* Returns the parsed global options and remaining args.
|
|
@@ -514,7 +504,7 @@ export class Application {
|
|
|
514
504
|
const rawGlobalOptions = parseOptionValues(GLOBAL_OPTIONS_SCHEMA, result.values) as GlobalOptions;
|
|
515
505
|
|
|
516
506
|
const globalOptions: GlobalOptions = { ...rawGlobalOptions };
|
|
517
|
-
|
|
507
|
+
|
|
518
508
|
const remainingArgs: string[] = [];
|
|
519
509
|
for (const token of result.tokens ?? []) {
|
|
520
510
|
if (token.kind === "positional") {
|
package/src/core/help.ts
CHANGED
|
@@ -112,7 +112,7 @@ export function formatExamples(command: AnyCommand): string {
|
|
|
112
112
|
* @returns Formatted help text
|
|
113
113
|
*/
|
|
114
114
|
export function generateCommandHelp(command: AnyCommand, options: HelpOptions = {}): string {
|
|
115
|
-
const { appName = "cli", version } = options;
|
|
115
|
+
const { appName = "cli", version, commandPath = [] } = options;
|
|
116
116
|
const sections: string[] = [];
|
|
117
117
|
|
|
118
118
|
// Header with version
|
|
@@ -164,8 +164,14 @@ export function generateCommandHelp(command: AnyCommand, options: HelpOptions =
|
|
|
164
164
|
|
|
165
165
|
// Help hint
|
|
166
166
|
if (command.hasSubCommands()) {
|
|
167
|
+
// Build the full command path for the hint
|
|
168
|
+
const fullPath = [appName, ...commandPath];
|
|
169
|
+
// Add command name if not already in path
|
|
170
|
+
if (commandPath.length === 0 || commandPath[commandPath.length - 1] !== command.name) {
|
|
171
|
+
fullPath.push(command.name);
|
|
172
|
+
}
|
|
167
173
|
sections.push(
|
|
168
|
-
`\n${colors.dim(`Run '${
|
|
174
|
+
`\n${colors.dim(`Run '${fullPath.join(" ")} <command> help' for more information on a command.`)}`
|
|
169
175
|
);
|
|
170
176
|
}
|
|
171
177
|
|
package/src/types/execution.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Execution mode determines how a command runs.
|
|
3
|
-
* - Cli: Command-line mode with arguments, executes and exits
|
|
4
|
-
* - Tui: Terminal UI mode with interactive rendering
|
|
5
|
-
*/
|
|
6
|
-
export enum ExecutionMode {
|
|
7
|
-
/** Command-line mode: parse args, execute, exit */
|
|
8
|
-
Cli = "cli",
|
|
9
|
-
/** Terminal UI mode: interactive render loop */
|
|
10
|
-
Tui = "tui",
|
|
11
|
-
}
|