@travetto/cli 8.0.0-alpha.20 → 8.0.0-alpha.22

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/README.md CHANGED
@@ -22,34 +22,38 @@ $ trv --help
22
22
  Usage: [options] [command]
23
23
 
24
24
  Commands:
25
- doc Command line support for generating module docs.
26
- doc:angular Generate documentation into the angular webapp under related/travetto.github.io
27
- doc:mapping Generate module mapping for
28
- email:compile CLI Entry point for running the email server
29
- email:editor The email editor compilation service and output serving
30
- email:test CLI Entry point for running the email server
31
- eslint Command line support for eslint
32
- eslint:register Writes the eslint configuration file
33
- model:export Exports model schemas
34
- model:install Installing models
35
- openapi:client CLI for generating the cli client
36
- openapi:spec CLI for outputting the open api spec to a local file
37
- pack Standard pack support
38
- pack:docker Standard docker support for pack
39
- pack:lambda Standard lambda support for pack
40
- pack:zip Standard zip support for pack
41
- repo:exec Repo execution
42
- repo:list Allows for listing of modules
43
- repo:publish Publish all pending modules
44
- repo:version Version all changed dependencies
45
- repo:version-sync Enforces all packages to write out their versions and dependencies
46
- run:double Doubles a number
47
- scaffold Command to run scaffolding
48
- service Allows for running services
49
- test Launch test framework and execute tests
50
- test:watch Invoke the test watcher
51
- web:http Run a web server
52
- web:rpc-client Generate the web-rpc client
25
+ doc Generate documentation outputs from a module `DOC.tsx` entry file.
26
+ doc:angular Generate documentation into the angular webapp under related/travetto.github.io
27
+ doc:mapping Generate module mapping for
28
+ email:compile Compile all email templates into generated runtime artifacts.
29
+ email:editor Start the email template editor service for interactive preview and testing.
30
+ email:test Render and send a template file to a target recipient for quick validation.
31
+ eslint Run ESLint for the workspace or changed files.
32
+ eslint:register Generate the workspace ESLint configuration entry file.
33
+ llm:support:execute Execute llm-support operations with dry-run by default.
34
+ llm:support:mcp Minimal MCP stdio server for llm-support tools.
35
+ llm:support:plan Build plan-first execution details for llm-support operations.
36
+ llm:support:recommend Recommend llm-support bundles, workflows, and operations.
37
+ llm:support:status Show llm-support execution coverage status.
38
+ model:export Export model definitions for a selected provider and model set.
39
+ model:install Install or update model definitions for a selected provider.
40
+ openapi:client Generate API clients from an OpenAPI specification using the generator image.
41
+ openapi:spec Generate the OpenAPI specification for the selected module.
42
+ pack Build a standard module package artifact.
43
+ pack:docker Build container-ready artifacts and optionally publish Docker images.
44
+ pack:lambda Build an AWS Lambda-ready zip package using the pack pipeline.
45
+ pack:zip Build a deployable zip artifact using the standard pack pipeline.
46
+ repo:exec Execute a shell command across workspace modules.
47
+ repo:list List workspace modules and their relationships.
48
+ repo:publish Publish unpublished workspace modules to the package registry.
49
+ repo:version Bump workspace module versions and optionally commit/tag release metadata.
50
+ repo:version-sync Synchronize package versions and dependency ranges across the monorepo.
51
+ run:double Doubles a number
52
+ service Manage development services (start/stop/restart/status) across the workspace.
53
+ test Execute the test framework for targeted files, suites, or methods.
54
+ test:watch Start the test watcher for continuous test execution.
55
+ web:http Start the configured web HTTP server for a module.
56
+ web:rpc-client Generate web-rpc client artifacts from a specified provider or leveraging local config.
53
57
  ```
54
58
 
55
59
  This listing is from the [Travetto](https://travetto.dev) monorepo, and represents the majority of tools that can be invoked from the command line.
@@ -259,7 +263,7 @@ import { CliCommand } from '@travetto/cli';
259
263
  import { Max, Min } from '@travetto/schema';
260
264
 
261
265
  /**
262
- * Custom Argument Command
266
+ * Example command with a custom argument
263
267
  */
264
268
  @CliCommand()
265
269
  export class CustomCommand {
@@ -283,6 +287,8 @@ $ trv custom:arg --help
283
287
 
284
288
  Usage: custom:arg [options] [volume:number]
285
289
 
290
+ Example command with a custom argument
291
+
286
292
  Options:
287
293
  -m, --message <string> The message to send back to the user (default: "hello")
288
294
  --help display help for command
@@ -311,7 +317,7 @@ import { CliCommand } from '@travetto/cli';
311
317
  import { Max, Min } from '@travetto/schema';
312
318
 
313
319
  /**
314
- * Custom Argument Command
320
+ * Example of a command with a custom environment variable argument
315
321
  */
316
322
  @CliCommand()
317
323
  export class CustomCommand {
@@ -334,6 +340,8 @@ $ trv custom:env-arg --help
334
340
 
335
341
  Usage: custom:env-arg [options] [volume:number]
336
342
 
343
+ Example of a command with a custom environment variable argument
344
+
337
345
  Options:
338
346
  -t, --text <string> The message to send back to the user (default: "hello")
339
347
  --help display help for command
@@ -442,7 +450,12 @@ import { Registry } from '@travetto/registry';
442
450
  import type { WebHttpServer } from '../src/types.ts';
443
451
 
444
452
  /**
445
- * Run a web server
453
+ * Start the configured web HTTP server for a module.
454
+ *
455
+ * Initializes registry and server bindings, supports restart-aware development
456
+ * flags, and can attempt to clear conflicting port owners in local workflows.
457
+ *
458
+ * @example trv web:http -m <MODULE> -p 3000
446
459
  */
447
460
  @CliCommand()
448
461
  export class WebHttpCommand implements CliCommandShape {
@@ -551,12 +564,17 @@ A simple example of the validation can be found in the `doc` command:
551
564
  ## CLI - service
552
565
  The module provides the ability to start/stop/restart services as [docker](https://www.docker.com/community-edition) containers. This is meant to be used for development purposes, to minimize the effort of getting an application up and running. Services can be targeted individually or handled as a group.
553
566
 
554
- **Terminal: Command Service**
567
+ **Terminal: Help for service**
555
568
  ```bash
556
569
  $ trv service --help
557
570
 
558
571
  Usage: service [options] <action:restart|start|status|stop> [services...:string]
559
572
 
573
+ Manage development services (start/stop/restart/status) across the workspace.
574
+
575
+ Services are discovered from registered descriptors and executed with streamed
576
+ terminal feedback, including optional quiet mode.
577
+
560
578
  Options:
561
579
  -q, --quiet (default: false)
562
580
  --help display help for command
@@ -566,7 +584,7 @@ Available Services
566
584
  * dynamodb@3.3.0
567
585
  * elasticsearch@9.2.8
568
586
  * firestore@latest
569
- * mongodb@8.2
587
+ * mongodb@8.3
570
588
  * mysql@9.6
571
589
  * postgresql@18.3
572
590
  * redis@8.4
@@ -584,7 +602,7 @@ Service Version Status
584
602
  dynamodb 3.3.0 Running 93af422e793a
585
603
  elasticsearch 9.2.8 Running ed76ee063d13
586
604
  firestore latest Running feec2e5e95b4
587
- mongodb 8.2 Running 5513eba6734e
605
+ mongodb 8.3 Running 5513eba6734e
588
606
  mysql 9.6 Running 307bc66d442a
589
607
  postgresql 18.3 Running e78291e71040
590
608
  redis 8.4 Running 77ba279b4e30
@@ -598,12 +616,16 @@ The services are defined as plain typescript files within the framework and can
598
616
  ```typescript
599
617
  import type { ServiceDescriptor } from '@travetto/cli';
600
618
 
601
- const version = process.env.MONGO_VERSION || '8.2';
619
+ const version = process.env.MONGO_VERSION || '8.3';
602
620
 
603
621
  export const service: ServiceDescriptor = {
604
622
  name: 'mongodb',
605
623
  version,
606
624
  port: 27017,
607
- image: `mongo:${version}`
625
+ image: `mongo:${version}`,
626
+ env: {
627
+ // Temp until mongo image fixes orbstack issue
628
+ GLIBC_TUNABLES: 'glibc.pthread.rseq=1'
629
+ }
608
630
  };
609
631
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/cli",
3
- "version": "8.0.0-alpha.20",
3
+ "version": "8.0.0-alpha.22",
4
4
  "type": "module",
5
5
  "description": "CLI infrastructure for Travetto framework",
6
6
  "keywords": [
@@ -29,8 +29,8 @@
29
29
  "directory": "module/cli"
30
30
  },
31
31
  "dependencies": {
32
- "@travetto/schema": "^8.0.0-alpha.15",
33
- "@travetto/terminal": "^8.0.0-alpha.14"
32
+ "@travetto/schema": "^8.0.0-alpha.17",
33
+ "@travetto/terminal": "^8.0.0-alpha.16"
34
34
  },
35
35
  "travetto": {
36
36
  "displayName": "Command Line Interface",
package/src/help.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import util from 'node:util';
2
2
 
3
- import { castKey, getClass, JSONUtil, Runtime } from '@travetto/runtime';
3
+ import { castKey, CodecUtil, getClass, JSONUtil, Runtime } from '@travetto/runtime';
4
4
  import { SchemaRegistryIndex, ValidationResultError } from '@travetto/schema';
5
5
 
6
6
  import { cliTpl } from './color.ts';
@@ -33,38 +33,43 @@ const COMMAND_TO_MODULE = Object.fromEntries(Object.entries(MODULE_TO_COMMAND).f
33
33
  */
34
34
  export class HelpUtil {
35
35
 
36
- /** Render the unknown command message */
37
- static renderUnknownCommandMessage(command: string): string {
38
- const module = COMMAND_TO_MODULE[command];
39
- if (module) {
40
- return cliTpl`
41
- ${{ title: 'Missing Package' }}\n${'-'.repeat(20)}\nTo use ${{ input: command }} please run:\n
42
- ${{ identifier: Runtime.getInstallCommand(module) }}
43
- `;
44
- } else {
45
- return cliTpl`${{ subtitle: 'Unknown command' }}: ${{ input: command }}`;
46
- }
47
- }
48
-
49
- /**
50
- * Render command-specific help
51
- * @param command
52
- */
53
- static async renderCommandHelp(command: CliCommandShape): Promise<string> {
36
+ /** Get usage help for a command */
37
+ static getUsageMessage(command: CliCommandShape): string[] {
54
38
  const schema = SchemaRegistryIndex.getConfig(getClass(command));
55
39
  const { name: commandName } = CliCommandRegistryIndex.get(getClass(command));
56
- const args = schema.methods.main?.parameters ?? [];
57
40
 
58
- const usage = [cliTpl`${{ title: 'Usage:' }} ${{ param: commandName }} ${{ input: '[options]' }}`,];
59
- const params: string[] = [];
60
- const descriptions: string[] = [];
41
+ const usage: string[] = [];
42
+
43
+ usage.push(
44
+ cliTpl`${{ title: 'Usage:' }} ${{ param: commandName }} ${{ input: '[options]' }}`
45
+ );
61
46
 
62
47
  // Ensure finalized
63
- for (const field of args) {
48
+ for (const field of schema.methods.main?.parameters ?? []) {
64
49
  const type = field.type === String && field.enum && field.enum?.values.length <= 7 ? field.enum?.values?.join('|') : field.type.name.toLowerCase();
65
50
  const arg = `${field.name}${field.array ? '...' : ''}:${type}`;
66
51
  usage.push(cliTpl`${{ input: field.required?.active !== false ? `<${arg}>` : `[${arg}]` }}`);
67
52
  }
53
+ usage.push('');
54
+ return usage;
55
+ }
56
+
57
+ /** Get description help for a command */
58
+ static getDescriptionMessage(command: CliCommandShape): string[] {
59
+ const schema = SchemaRegistryIndex.getConfig(getClass(command));
60
+ const description: string[] = [];
61
+
62
+ if (schema.description) {
63
+ description.push(cliTpl`${{ title: 'Description:' }}`, ...schema.description.split('\n').map(line => ` ${line}`), '');
64
+ }
65
+ return description;
66
+ }
67
+
68
+ /** Get options help for a command */
69
+ static getOptionsMessage(command: CliCommandShape): string[] {
70
+ const schema = SchemaRegistryIndex.getConfig(getClass(command));
71
+ const params: string[] = [];
72
+ const descriptions: string[] = [];
68
73
 
69
74
  for (const field of Object.values(schema.fields)) {
70
75
  const key = castKey<CliCommandShape>(field.name);
@@ -106,20 +111,68 @@ ${{ identifier: Runtime.getInstallCommand(module) }}
106
111
  const paramWidth = Math.max(...paramWidths);
107
112
  const descWidth = Math.max(...descWidths);
108
113
 
114
+ const options: string[] = [
115
+ cliTpl`${{ title: 'Options:' }}`,
116
+ ...params.map((_, i) =>
117
+ ` ${params[i]}${' '.repeat((paramWidth - paramWidths[i]))} ${descriptions[i].padEnd(descWidth)}${' '.repeat((descWidth - descWidths[i]))}`
118
+ ),
119
+ ''
120
+ ];
121
+ return options;
122
+ }
123
+
124
+ /** Get extended help for a command */
125
+ static async getExtendedHelpMessage(command: CliCommandShape): Promise<string[]> {
109
126
  const extendedHelpText = await (command.help?.() ?? []);
110
127
  if (extendedHelpText.length && extendedHelpText.at(-1) !== '') {
111
128
  extendedHelpText.push('');
112
129
  }
130
+ return extendedHelpText;
131
+ }
132
+
133
+ /** Get examples for a command */
134
+ static getExamplesMessage(command: CliCommandShape): string[] {
135
+ const schema = SchemaRegistryIndex.getConfig(getClass(command));
136
+ const examples: string[] = [];
137
+ if (schema.examples) {
138
+ examples.push(cliTpl`${{ title: 'Examples:' }}`);
139
+ for (const example of schema.examples) {
140
+ for (const line of example.split('\n')) {
141
+ examples.push(
142
+ line.trim().startsWith('>') ?
143
+ cliTpl` ${{ input: line.substring(line.indexOf('> ') + 2).trim() }}` :
144
+ cliTpl` ${{ subtitle: line.trim() }}`);
145
+ }
146
+ }
147
+ examples.push('');
148
+ }
149
+ return examples;
150
+ }
151
+
152
+ /** Render the unknown command message */
153
+ static renderUnknownCommandMessage(command: string): string {
154
+ const module = COMMAND_TO_MODULE[command];
155
+ if (module) {
156
+ return cliTpl`
157
+ ${{ title: 'Missing Package' }}\n${'-'.repeat(20)}\nTo use ${{ input: command }} please run:\n
158
+ ${{ identifier: Runtime.getInstallCommand(module) }}
159
+ `;
160
+ } else {
161
+ return cliTpl`${{ subtitle: 'Unknown command' }}: ${{ input: command }}`;
162
+ }
163
+ }
113
164
 
165
+ /**
166
+ * Render command-specific help
167
+ * @param command
168
+ */
169
+ static async renderCommandHelp(command: CliCommandShape): Promise<string> {
114
170
  return [
115
- usage.join(' '),
116
- '',
117
- cliTpl`${{ title: 'Options:' }}`,
118
- ...params.map((_, i) =>
119
- ` ${params[i]}${' '.repeat((paramWidth - paramWidths[i]))} ${descriptions[i].padEnd(descWidth)}${' '.repeat((descWidth - descWidths[i]))}`
120
- ),
121
- '',
122
- ...extendedHelpText
171
+ ...this.getUsageMessage(command),
172
+ ...this.getDescriptionMessage(command),
173
+ ...this.getOptionsMessage(command),
174
+ ...await this.getExtendedHelpMessage(command),
175
+ ...this.getExamplesMessage(command)
123
176
  ].map(line => line.trimEnd()).join('\n');
124
177
  }
125
178
 
@@ -136,11 +189,13 @@ ${{ identifier: Runtime.getInstallCommand(module) }}
136
189
  for (const { command: cmd, schema } of resolved) {
137
190
  try {
138
191
  if (schema && !schema.private) {
139
- rows.push(cliTpl` ${{ param: cmd.padEnd(maxWidth, ' ') }} ${{ title: schema.description || '' }}`);
192
+ const description = CodecUtil.readFirstLine(schema.description, '');
193
+ rows.push(cliTpl` ${{ param: cmd.padEnd(maxWidth, ' ') }} ${{ title: description }}`);
140
194
  }
141
195
  } catch (error) {
142
196
  if (error instanceof Error) {
143
- rows.push(cliTpl` ${{ param: cmd.padEnd(maxWidth, ' ') }} ${{ failure: error.message.split(/\n/)[0] }}`);
197
+ const failure = CodecUtil.readFirstLine(error.message);
198
+ rows.push(cliTpl` ${{ param: cmd.padEnd(maxWidth, ' ') }} ${{ failure }}`);
144
199
  } else {
145
200
  throw error;
146
201
  }
@@ -84,7 +84,7 @@ export function CliModuleFlag(config: CliFlagOptions & { scope?: 'current' | 'co
84
84
  ...CliParseUtil.buildAliases(config, Env.TRV_MODULE.key),
85
85
  description: 'Module to run for',
86
86
  specifiers: ['module'],
87
- required: { active: Runtime.monoRoot },
87
+ required: { active: Runtime.monoRoot && config.scope !== 'command' },
88
88
  });
89
89
 
90
90
  SchemaRegistryIndex.getForRegister(cls).register({
@@ -147,7 +147,7 @@ export function CliDebugIpcFlag(config: CliFlagOptions = {}) {
147
147
  const cls = getClass(instance);
148
148
  SchemaRegistryIndex.getForRegister(cls).registerField(property, {
149
149
  ...CliParseUtil.buildAliases(config, Env.TRV_DEBUG_IPC.key),
150
- description: 'Should the invocation automatically restart on source changes'
150
+ description: 'Should the invocation support debugging via IPC (e.g. from VSCode)'
151
151
  });
152
152
 
153
153
  CliCommandRegistryIndex.getForRegister(cls).register({ runTarget: true });
@@ -1,7 +1,7 @@
1
1
  import { castTo, type Class, describeFunction } from '@travetto/runtime';
2
2
  import { type SchemaInputConfig, SchemaRegistryIndex } from '@travetto/schema';
3
3
 
4
- import { CliCommandRegistryIndex } from '../src/registry/registry-index.ts';
4
+ import { CliCommandRegistryIndex } from './registry/registry-index.ts';
5
5
 
6
6
  /**
7
7
  * CLI Command argument/flag shape
@@ -25,7 +25,10 @@ async function nameValidator(names?: string[]): Promise<ValidationError | undefi
25
25
  }
26
26
 
27
27
  /**
28
- * Generates the schema for all CLI operations
28
+ * Exports machine-readable command metadata for automation and tooling.
29
+ *
30
+ * Used by editor integrations to discover runnable commands and inputs.
31
+ * Used by guidance workflows to validate command signatures.
29
32
  */
30
33
  @CliCommand()
31
34
  @IsPrivate()
@@ -11,7 +11,10 @@ async function validateMain(fileOrImport: string): Promise<ValidationError | und
11
11
  };
12
12
 
13
13
  /**
14
- * Allows for running of main entry points
14
+ * Execute a module `main()` entrypoint directly.
15
+ *
16
+ * This internal command resolves an import/source target, invokes its exported
17
+ * `main` function, and forwards unknown CLI args to that function.
15
18
  */
16
19
  @CliCommand()
17
20
  @IsPrivate()
@@ -16,7 +16,10 @@ async function validateService(_: ServiceAction, services: string[]): Promise<Va
16
16
  }
17
17
 
18
18
  /**
19
- * Allows for running services
19
+ * Manage development services (start/stop/restart/status) across the workspace.
20
+ *
21
+ * Services are discovered from registered descriptors and executed with streamed
22
+ * terminal feedback, including optional quiet mode.
20
23
  */
21
24
  @CliCommand()
22
25
  export class CliServiceCommand implements CliCommandShape {