icore 1.0.15 → 1.0.16

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.
Files changed (50) hide show
  1. package/CHANGELOG.md +220 -0
  2. package/dist/{argv.d.ts → argv/parser.d.ts} +3 -1
  3. package/dist/{argv.js → argv/parser.js} +5 -5
  4. package/dist/{commands.d.ts → command/mechanics.d.ts} +73 -6
  5. package/dist/{commands.js → command/mechanics.js} +53 -15
  6. package/dist/{errors.d.ts → errors/icore-error.d.ts} +2 -0
  7. package/dist/{errors.js → errors/icore-error.js} +2 -0
  8. package/dist/index.d.ts +28 -1
  9. package/dist/index.js +61 -17
  10. package/dist/options/parser.d.ts +43 -0
  11. package/dist/{options.js → options/parser.js} +27 -17
  12. package/dist/{options.d.ts → options/schema.d.ts} +16 -23
  13. package/dist/options/schema.js +23 -0
  14. package/dist/output/facade.d.ts +28 -0
  15. package/dist/output/facade.js +32 -0
  16. package/dist/output/node-writer.d.ts +17 -0
  17. package/dist/output/node-writer.js +25 -0
  18. package/dist/output/text-writer.d.ts +29 -0
  19. package/dist/output/text-writer.js +49 -0
  20. package/dist/presentation/facade.d.ts +39 -0
  21. package/dist/presentation/facade.js +47 -0
  22. package/dist/presentation/format-options.d.ts +31 -0
  23. package/dist/presentation/format-options.js +37 -0
  24. package/dist/presentation/renderers/csv.d.ts +18 -0
  25. package/dist/presentation/renderers/csv.js +35 -0
  26. package/dist/presentation/renderers/json.d.ts +13 -0
  27. package/dist/presentation/renderers/json.js +18 -0
  28. package/dist/presentation/renderers/table.d.ts +14 -0
  29. package/dist/presentation/renderers/table.js +29 -0
  30. package/dist/presentation/result-renderer.d.ts +25 -0
  31. package/dist/presentation/result-renderer.js +184 -0
  32. package/dist/presentation/view.d.ts +58 -0
  33. package/dist/presentation/view.js +56 -0
  34. package/dist/terminal/app.d.ts +51 -0
  35. package/dist/terminal/app.js +100 -0
  36. package/examples/cli-argument-syntax.md +218 -0
  37. package/examples/command-resolution.md +174 -0
  38. package/examples/custom-command-flow.md +109 -0
  39. package/examples/option-schemas.md +206 -0
  40. package/examples/output-writers.md +128 -0
  41. package/examples/practical-cli-patterns.md +385 -0
  42. package/examples/presentation-output.md +66 -0
  43. package/examples/presentation-primitives.md +190 -0
  44. package/examples/readme.md +48 -0
  45. package/examples/terminal-app.md +118 -0
  46. package/examples/two-phase-primitives.md +282 -0
  47. package/package.json +9 -4
  48. package/readme.md +278 -299
  49. package/dist/cli.d.ts +0 -14
  50. package/dist/cli.js +0 -32
package/CHANGELOG.md ADDED
@@ -0,0 +1,220 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ Historical entries before this file was introduced were reconstructed from npm
9
+ publish metadata and local git history. Older entries are intentionally
10
+ conservative.
11
+
12
+ ## [Unreleased]
13
+
14
+ ### Added
15
+
16
+ - Added `createCommand` as a semantic command mechanics facade.
17
+ - Added `createCommands` as a high-level command mechanics facade.
18
+ - Added `createPresentation` and `PresentationResult` for terminal view-model rendering.
19
+ - Added semantic `Presentation` view factory methods such as `presentation.records(...)`.
20
+ - Added `createOutput` as a stdout/stderr output boundary facade.
21
+ - Added semantic `Output.write()` and `Output.error()` methods.
22
+ - Added `createTerminalApp` to compose command, presentation, and output mechanics.
23
+ - Added generic terminal presentation renderers for JSON, CSV, and text tables.
24
+ - Added reusable stdout/stderr text writers with backpressure handling.
25
+ - Added shared `presentationFormatOptions` for common `--format` command options.
26
+ - Added machine-readable `IcoreError` codes and details.
27
+ - Added `parseOptionsSubsetDetailed` for validating known option subsets while preserving unknown raw options.
28
+ - Added opt-in `strict: true` command resolution for rejecting options before command paths.
29
+ - Added `strict: true` support to direct `runCommand` execution.
30
+ - Added typed prepared command `payload` returned from `prepare` and passed to `handle`.
31
+ - Added public `CommandPayload`, `CommandContext`, and `CommandResult` helper types.
32
+ - Added `isPreparedCommandName` for narrowing prepared command unions by name.
33
+ - Added this changelog.
34
+
35
+ ### Changed
36
+
37
+ - Changed `PreparedCommand` typing to preserve payload correlation when narrowing registry unions by command name.
38
+ - Changed output writers to await promise-returning custom sinks.
39
+ - Reorganized internal source files by CLI framework responsibility without changing the root public API.
40
+ - Split option schema contracts from option value parsing internals.
41
+ - Changed npm package contents to include `CHANGELOG.md`.
42
+ - Removed the redundant `cli` barrel so `index` is the only package entrypoint.
43
+
44
+ ### Removed
45
+
46
+ - Removed explicit boolean values such as `--flag=true` and `--flag=false`; use `--flag` and `--no-flag`.
47
+
48
+ ## [1.0.12] - 2026-07-02
49
+
50
+ ### Changed
51
+
52
+ - Replaced the preliminary flag-only boolean option naming with `syntax: 'flag'`.
53
+ - Documented flag-only boolean option behavior.
54
+
55
+ ## [1.0.11] - 2026-07-02
56
+
57
+ ### Added
58
+
59
+ - Added preliminary flag-only boolean option support.
60
+
61
+ ## [1.0.10] - 2026-07-02
62
+
63
+ ### Added
64
+
65
+ - Added two-phase command execution.
66
+ - Added `PreparedCommandInput`.
67
+ - Added `PreparedCommand`.
68
+ - Added `prepareCommandFromArgs`.
69
+ - Added `runPreparedCommand`.
70
+ - Added command `metadata`.
71
+ - Added command `prepare` hook.
72
+ - Added focused tests for prepare-time validation and handler safety.
73
+
74
+ ### Changed
75
+
76
+ - Changed `runCommand` and `runCommandFromRegistry` to use the prepare-and-run flow internally.
77
+
78
+ ## [1.0.9] - 2026-07-02
79
+
80
+ ### Changed
81
+
82
+ - Refined npm package metadata.
83
+ - Updated repository metadata for npm.
84
+ - Simplified published package contents.
85
+
86
+ ## [1.0.8] - 2026-07-02
87
+
88
+ ### Changed
89
+
90
+ - Updated package author metadata.
91
+ - Normalized README heading structure.
92
+
93
+ ## [1.0.7] - 2026-07-02
94
+
95
+ ### Changed
96
+
97
+ - Renamed README examples from `upper` to `uppercase`.
98
+ - Cleaned duplicated command test coverage without changing public behavior.
99
+
100
+ ## [1.0.6] - 2026-07-02
101
+
102
+ ### Added
103
+
104
+ - Added explicit long boolean values such as `--flag=true` and `--flag=false`.
105
+ - Added schema-known boolean negation such as `--no-flag`.
106
+ - Added short option aliases such as `-f` and `-n value`.
107
+ - Added alias validation and duplicate detection between short and long option forms.
108
+ - Documented supported option syntax.
109
+
110
+ ## [1.0.5] - 2026-07-01
111
+
112
+ ### Changed
113
+
114
+ - Rebuilt README as the main public documentation entry point.
115
+
116
+ ### Removed
117
+
118
+ - Removed separate generated reference docs from the published documentation flow.
119
+
120
+ ## [1.0.4] - 2026-07-01
121
+
122
+ ### Changed
123
+
124
+ - Reorganized README and documentation references.
125
+
126
+ ## [1.0.3] - 2026-07-01
127
+
128
+ ### Added
129
+
130
+ - Added README table of contents.
131
+
132
+ ### Changed
133
+
134
+ - Polished README formatting and emphasis.
135
+
136
+ ## [1.0.2] - 2026-06-30
137
+
138
+ ### Added
139
+
140
+ - Added module boundary comments to production source files.
141
+
142
+ ### Changed
143
+
144
+ - Clarified CLI scope and supported syntax in README.
145
+ - Updated package description and keywords.
146
+
147
+ ## [1.0.1] - 2026-06-30
148
+
149
+ ### Changed
150
+
151
+ - Published documentation updates after the first stable release.
152
+ - No dedicated version commit is present in local git history for this patch.
153
+
154
+ ## [1.0.0] - 2026-06-30
155
+
156
+ ### Added
157
+
158
+ - First stable release of the new `icore` CLI mechanics package.
159
+ - Added declarative option parsing and validation.
160
+ - Added schema-aware argv parsing.
161
+ - Added option presence metadata through `parseOptionsDetailed`.
162
+ - Added option schema composition through `mergeOptionsSchema`.
163
+ - Added command registry routing.
164
+ - Added typed command handler input.
165
+ - Added CommonJS package entry points and TypeScript declarations.
166
+
167
+ ### Changed
168
+
169
+ - Lowered the runtime Node.js engine to `>=16.9.0`.
170
+
171
+ ## [1.0.0-alpha] - 2026-06-28
172
+
173
+ ### Added
174
+
175
+ - Started the new CLI mechanics codebase after pruning the legacy package code.
176
+ - Added the initial TypeScript build, test, and lint setup for the new package.
177
+
178
+ ## [0.1.38] - 2019-06-12
179
+
180
+ ### Added
181
+
182
+ - Added legacy tests and documentation.
183
+
184
+ ### Changed
185
+
186
+ - Final legacy web-framework line release.
187
+ - Updated the legacy package description.
188
+
189
+ ### Removed
190
+
191
+ - Trimmed legacy runtime dependencies.
192
+
193
+ ## [0.0.37 and earlier]
194
+
195
+ ### Added
196
+
197
+ - Original legacy npm package line published between 2017 and 2019.
198
+ - Legacy history is preserved for package provenance.
199
+
200
+ ### Changed
201
+
202
+ - Detailed changelog entries were not maintained for these releases.
203
+
204
+ [Unreleased]: https://github.com/woodger/icore/commits/develop
205
+ [1.0.12]: https://www.npmjs.com/package/icore/v/1.0.12
206
+ [1.0.11]: https://www.npmjs.com/package/icore/v/1.0.11
207
+ [1.0.10]: https://www.npmjs.com/package/icore/v/1.0.10
208
+ [1.0.9]: https://www.npmjs.com/package/icore/v/1.0.9
209
+ [1.0.8]: https://www.npmjs.com/package/icore/v/1.0.8
210
+ [1.0.7]: https://www.npmjs.com/package/icore/v/1.0.7
211
+ [1.0.6]: https://www.npmjs.com/package/icore/v/1.0.6
212
+ [1.0.5]: https://www.npmjs.com/package/icore/v/1.0.5
213
+ [1.0.4]: https://www.npmjs.com/package/icore/v/1.0.4
214
+ [1.0.3]: https://www.npmjs.com/package/icore/v/1.0.3
215
+ [1.0.2]: https://www.npmjs.com/package/icore/v/1.0.2
216
+ [1.0.1]: https://www.npmjs.com/package/icore/v/1.0.1
217
+ [1.0.0]: https://www.npmjs.com/package/icore/v/1.0.0
218
+ [1.0.0-alpha]: https://www.npmjs.com/package/icore/v/1.0.0-alpha
219
+ [0.1.38]: https://www.npmjs.com/package/icore/v/0.1.38
220
+ [0.0.37 and earlier]: https://www.npmjs.com/package/icore?activeTab=versions
@@ -9,13 +9,15 @@
9
9
  *
10
10
  * This file must not contain typed option validation or command resolution.
11
11
  */
12
- import type { OptionsSchema, RawOptionValue } from './options';
12
+ import type { OptionsSchema, RawOptionValue } from '../options/schema';
13
13
  /**
14
14
  * Parsed CLI arguments split into positional command path segments and raw
15
15
  * named options.
16
16
  */
17
17
  export type ParsedArgv = {
18
+ /** Non-option tokens. */
18
19
  positionals: string[];
20
+ /** Unvalidated option values. */
19
21
  options: Record<string, RawOptionValue>;
20
22
  };
21
23
  /**
@@ -12,7 +12,7 @@
12
12
  */
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
14
  exports.parseArgv = parseArgv;
15
- const errors_1 = require("./errors");
15
+ const icore_error_1 = require("../errors/icore-error");
16
16
  /**
17
17
  * Parses raw CLI arguments into positionals and raw long-option values.
18
18
  */
@@ -140,24 +140,24 @@ function isShortOptionToken(arg) {
140
140
  return arg.length === 2 && arg.startsWith('-') && !arg.startsWith('--');
141
141
  }
142
142
  function createDuplicateArgumentError(name) {
143
- return new errors_1.IcoreError('DUPLICATE_ARGUMENT', `Unexpected duplicate argument '--${name}'`, {
143
+ return new icore_error_1.IcoreError('DUPLICATE_ARGUMENT', `Unexpected duplicate argument '--${name}'`, {
144
144
  argument: `--${name}`,
145
145
  option: name
146
146
  });
147
147
  }
148
148
  function createUnexpectedArgumentError(argument) {
149
- return new errors_1.IcoreError('UNEXPECTED_ARGUMENT', `Unexpected argument '${argument}'`, {
149
+ return new icore_error_1.IcoreError('UNEXPECTED_ARGUMENT', `Unexpected argument '${argument}'`, {
150
150
  argument
151
151
  });
152
152
  }
153
153
  function createDuplicateAliasError(alias) {
154
- return new errors_1.IcoreError('DUPLICATE_ALIAS', `Unexpected duplicate alias '-${alias}'`, {
154
+ return new icore_error_1.IcoreError('DUPLICATE_ALIAS', `Unexpected duplicate alias '-${alias}'`, {
155
155
  alias,
156
156
  argument: `-${alias}`
157
157
  });
158
158
  }
159
159
  function createInvalidOptionAliasError(name, alias) {
160
- return new errors_1.IcoreError('INVALID_OPTION_ALIAS', `Expected alias for '--${name}' as single ASCII letter`, {
160
+ return new icore_error_1.IcoreError('INVALID_OPTION_ALIAS', `Expected alias for '--${name}' as single ASCII letter`, {
161
161
  argument: `--${name}`,
162
162
  option: name,
163
163
  alias
@@ -10,26 +10,32 @@
10
10
  * This file must not contain raw token parsing, option schema validation,
11
11
  * domain behavior, SDK calls, or output formatting.
12
12
  */
13
- import { type InferOptions, type InferProvidedOptions, type OptionsSchema } from './options';
13
+ import type { InferOptions, InferProvidedOptions, OptionsSchema } from '../options/schema';
14
14
  /**
15
15
  * Input produced after command path and option validation, before runtime
16
16
  * context is attached.
17
17
  */
18
18
  export type PreparedCommandInput<TSchema extends OptionsSchema> = {
19
+ /** Parsed option values. */
19
20
  options: InferOptions<TSchema>;
21
+ /** Explicit option presence metadata. */
20
22
  provided: InferProvidedOptions<TSchema>;
23
+ /** Positionals after the command path. */
21
24
  positionals: string[];
22
25
  };
23
26
  /**
24
27
  * Input passed to a command handler after command path and option validation.
25
28
  */
26
29
  export type CommandInput<TSchema extends OptionsSchema, TContext, TPayload = void> = PreparedCommandInput<TSchema> & {
30
+ /** Application runtime context. */
27
31
  context: TContext;
28
32
  } & ([
29
33
  TPayload
30
34
  ] extends [void] ? {
35
+ /** Optional prepared payload. */
31
36
  payload?: TPayload;
32
37
  } : {
38
+ /** Prepared payload. */
33
39
  payload: TPayload;
34
40
  });
35
41
  /**
@@ -40,11 +46,17 @@ export type CommandInput<TSchema extends OptionsSchema, TContext, TPayload = voi
40
46
  * formatting.
41
47
  */
42
48
  export type CommandDefinition<TSchema extends OptionsSchema, TContext, TResult, TPath extends readonly [string, ...string[]] = readonly [string, ...string[]], TMetadata = unknown, TPayload = void> = {
49
+ /** Command path segments. */
43
50
  path: TPath;
51
+ /** Command option schema. */
44
52
  options: TSchema;
53
+ /** Caller-owned static metadata. */
45
54
  metadata?: TMetadata;
55
+ /** Allows extra positionals. */
46
56
  allowExtraPositionals?: boolean;
57
+ /** Prepares payload before runtime context. */
47
58
  prepare?(input: PreparedCommandInput<TSchema>): TPayload | Promise<TPayload>;
59
+ /** Runs application command behavior. */
48
60
  handle(input: CommandInput<TSchema, TContext, TPayload>): TResult | Promise<TResult>;
49
61
  };
50
62
  type AnyCommandInput = PreparedCommandInput<OptionsSchema> & {
@@ -78,9 +90,18 @@ type CommandDefinitionParts<TCommand extends AnyCommandDefinition> = TCommand ex
78
90
  metadata: TCommand['metadata'];
79
91
  payload: unknown;
80
92
  };
93
+ /**
94
+ * Infers the runtime context type required by a command.
95
+ */
81
96
  export type CommandContext<TCommand extends AnyCommandDefinition> = CommandDefinitionParts<TCommand>['context'];
97
+ /**
98
+ * Infers the awaited command handler result type.
99
+ */
82
100
  export type CommandResult<TCommand extends AnyCommandDefinition> = Awaited<CommandDefinitionParts<TCommand>['result']>;
83
101
  type CommandSchema<TCommand extends AnyCommandDefinition> = CommandDefinitionParts<TCommand>['schema'];
102
+ /**
103
+ * Infers the payload type produced by a command prepare hook.
104
+ */
84
105
  export type CommandPayload<TCommand extends AnyCommandDefinition> = CommandDefinitionParts<TCommand>['payload'];
85
106
  /**
86
107
  * Infers the public command name from a command path.
@@ -90,39 +111,77 @@ export type CommandName<TCommand extends AnyCommandDefinition> = CommandPathName
90
111
  * Declarative command registry used to resolve command paths.
91
112
  */
92
113
  export type CommandRegistry<TCommands extends readonly AnyCommandDefinition[]> = {
114
+ /** Registered command definitions. */
93
115
  commands: TCommands;
116
+ /** Derived public command names. */
94
117
  commandNames: readonly CommandName<TCommands[number]>[];
95
118
  };
119
+ /**
120
+ * High-level command mechanics facade for terminal applications.
121
+ */
122
+ export type Commands<TCommands extends readonly AnyCommandDefinition[]> = {
123
+ /** Original command definitions. */
124
+ definitions: TCommands;
125
+ /** Public command names. */
126
+ names: readonly CommandName<TCommands[number]>[];
127
+ /** Lower-level command registry. */
128
+ registry: CommandRegistry<TCommands>;
129
+ /** Resolves from positionals. */
130
+ resolve(positionals: readonly string[]): ResolvedCommand<TCommands[number]>;
131
+ /** Resolves from raw argv. */
132
+ resolveFromArgs(args: readonly string[]): ResolvedCommand<TCommands[number]>;
133
+ /** Prepares without runtime context. */
134
+ prepare(args: readonly string[], options?: CommandResolutionOptions): Promise<PreparedCommand<TCommands[number]>>;
135
+ /** Runs a prepared command. */
136
+ run(prepared: PreparedCommand<TCommands[number]>, context: CommandContext<TCommands[number]>): Promise<CommandResult<TCommands[number]>>;
137
+ /** Resolves, prepares, and runs. */
138
+ runFromArgs(args: readonly string[], context: CommandContext<TCommands[number]>, options?: CommandResolutionOptions): Promise<CommandResult<TCommands[number]>>;
139
+ };
140
+ /**
141
+ * Semantic facade for command mechanics.
142
+ */
143
+ export type Command = {
144
+ define: typeof defineCommand;
145
+ registry: typeof createCommands;
146
+ run: typeof runCommand;
147
+ };
96
148
  /**
97
149
  * Options for command resolution from raw CLI arguments.
98
150
  */
99
151
  export type CommandResolutionOptions = {
100
- /**
101
- * When enabled, command path must appear before options. Options before the
102
- * command path are rejected instead of participating in legacy candidate
103
- * schema parsing.
104
- */
152
+ /** Rejects options before command path. */
105
153
  strict?: boolean;
106
154
  };
107
155
  /**
108
156
  * Result of resolving a command from user positionals.
109
157
  */
110
158
  export type ResolvedCommand<TCommand extends AnyCommandDefinition> = {
159
+ /** Space-joined command name. */
111
160
  name: CommandName<TCommand>;
161
+ /** Literal command path. */
112
162
  path: TCommand['path'];
163
+ /** Selected command definition. */
113
164
  command: TCommand;
165
+ /** Positionals after the command path. */
114
166
  positionals: string[];
115
167
  };
116
168
  /**
117
169
  * Command resolved and validated without runtime context.
118
170
  */
119
171
  export type PreparedCommand<TCommand extends AnyCommandDefinition> = TCommand extends AnyCommandDefinition ? {
172
+ /** Space-joined command name. */
120
173
  name: CommandName<TCommand>;
174
+ /** Literal command path. */
121
175
  path: TCommand['path'];
176
+ /** Selected command definition. */
122
177
  command: TCommand;
178
+ /** Parsed option values. */
123
179
  options: InferOptions<CommandSchema<TCommand>>;
180
+ /** Explicit option presence metadata. */
124
181
  provided: InferProvidedOptions<CommandSchema<TCommand>>;
182
+ /** Positionals after the command path. */
125
183
  positionals: string[];
184
+ /** Prepared payload. */
126
185
  payload: CommandPayload<TCommand>;
127
186
  } : never;
128
187
  /**
@@ -133,6 +192,14 @@ export declare function defineCommand<const TSchema extends OptionsSchema, const
133
192
  * Defines a command registry while preserving literal command path types.
134
193
  */
135
194
  export declare function defineCommandRegistry<const TCommands extends readonly AnyCommandDefinition[]>(commands: TCommands): CommandRegistry<TCommands>;
195
+ /**
196
+ * Creates a command mechanics facade from declarative command definitions.
197
+ */
198
+ export declare function createCommands<const TCommands extends readonly AnyCommandDefinition[]>(definitions: TCommands): Commands<TCommands>;
199
+ /**
200
+ * Creates a semantic command mechanics facade.
201
+ */
202
+ export declare function createCommand(): Command;
136
203
  /**
137
204
  * Checks whether a value is a command name registered in the given registry.
138
205
  */
@@ -14,6 +14,8 @@
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.defineCommand = defineCommand;
16
16
  exports.defineCommandRegistry = defineCommandRegistry;
17
+ exports.createCommands = createCommands;
18
+ exports.createCommand = createCommand;
17
19
  exports.isCommandName = isCommandName;
18
20
  exports.isPreparedCommandName = isPreparedCommandName;
19
21
  exports.resolveCommand = resolveCommand;
@@ -22,9 +24,9 @@ exports.prepareCommandFromArgs = prepareCommandFromArgs;
22
24
  exports.runPreparedCommand = runPreparedCommand;
23
25
  exports.runCommandFromRegistry = runCommandFromRegistry;
24
26
  exports.runCommand = runCommand;
25
- const argv_1 = require("./argv");
26
- const errors_1 = require("./errors");
27
- const options_1 = require("./options");
27
+ const parser_1 = require("../argv/parser");
28
+ const icore_error_1 = require("../errors/icore-error");
29
+ const parser_2 = require("../options/parser");
28
30
  /**
29
31
  * Defines a command while preserving literal option schema types.
30
32
  */
@@ -42,6 +44,42 @@ function defineCommandRegistry(commands) {
42
44
  commandNames: commandNames
43
45
  };
44
46
  }
47
+ /**
48
+ * Creates a command mechanics facade from declarative command definitions.
49
+ */
50
+ function createCommands(definitions) {
51
+ const registry = defineCommandRegistry(definitions);
52
+ return {
53
+ definitions,
54
+ names: registry.commandNames,
55
+ registry,
56
+ resolve(positionals) {
57
+ return resolveCommand(registry, positionals);
58
+ },
59
+ resolveFromArgs(args) {
60
+ return resolveCommandFromArgs(registry, args);
61
+ },
62
+ prepare(args, options) {
63
+ return prepareCommandFromArgs(registry, args, options);
64
+ },
65
+ run(prepared, context) {
66
+ return runPreparedCommand(prepared, context);
67
+ },
68
+ runFromArgs(args, context, options) {
69
+ return runCommandFromRegistry(registry, args, context, options);
70
+ }
71
+ };
72
+ }
73
+ /**
74
+ * Creates a semantic command mechanics facade.
75
+ */
76
+ function createCommand() {
77
+ return {
78
+ define: defineCommand,
79
+ registry: createCommands,
80
+ run: runCommand
81
+ };
82
+ }
45
83
  /**
46
84
  * Checks whether a value is a command name registered in the given registry.
47
85
  */
@@ -72,13 +110,13 @@ function resolveCommand(registry, positionals) {
72
110
  */
73
111
  function resolveCommandFromArgs(registry, args) {
74
112
  for (const command of commandsBySpecificity(registry.commands)) {
75
- const argv = (0, argv_1.parseArgv)(args, command.options);
113
+ const argv = (0, parser_1.parseArgv)(args, command.options);
76
114
  const resolved = resolveCommandCandidate(command, argv.positionals);
77
115
  if (resolved !== undefined) {
78
116
  return resolved;
79
117
  }
80
118
  }
81
- throw createUnknownCommandError((0, argv_1.parseArgv)(args).positionals);
119
+ throw createUnknownCommandError((0, parser_1.parseArgv)(args).positionals);
82
120
  }
83
121
  /**
84
122
  * Resolves and validates a command without requiring runtime context.
@@ -88,13 +126,13 @@ async function prepareCommandFromArgs(registry, args, options = {}) {
88
126
  return prepareCommandFromArgsStrict(registry, args);
89
127
  }
90
128
  for (const command of commandsBySpecificity(registry.commands)) {
91
- const argv = (0, argv_1.parseArgv)(args, command.options);
129
+ const argv = (0, parser_1.parseArgv)(args, command.options);
92
130
  const resolved = resolveCommandCandidate(command, argv.positionals);
93
131
  if (resolved !== undefined) {
94
132
  return prepareResolvedCommand(resolved, argv.options);
95
133
  }
96
134
  }
97
- throw createUnknownCommandError((0, argv_1.parseArgv)(args).positionals);
135
+ throw createUnknownCommandError((0, parser_1.parseArgv)(args).positionals);
98
136
  }
99
137
  /**
100
138
  * Runs a prepared command with caller-provided runtime context.
@@ -128,7 +166,7 @@ async function prepareCommand(command, args, options = {}) {
128
166
  if (options.strict === true) {
129
167
  assertNoOptionBeforeCommand(args);
130
168
  }
131
- const argv = (0, argv_1.parseArgv)(args, command.options);
169
+ const argv = (0, parser_1.parseArgv)(args, command.options);
132
170
  const extraPositionals = resolveCommandPositionals(command.path, argv.positionals);
133
171
  const resolved = {
134
172
  name: commandPathToName(command.path),
@@ -143,7 +181,7 @@ async function prepareCommandFromArgsStrict(registry, args) {
143
181
  if (command === undefined) {
144
182
  throw createUnknownCommandError(commandPositionalsBeforeOptions(args));
145
183
  }
146
- const argv = (0, argv_1.parseArgv)(args, command.options);
184
+ const argv = (0, parser_1.parseArgv)(args, command.options);
147
185
  const resolved = resolveCommandCandidate(command, argv.positionals);
148
186
  if (resolved === undefined) {
149
187
  throw createUnknownCommandError(argv.positionals);
@@ -154,13 +192,13 @@ async function prepareResolvedCommand(resolved, rawOptions) {
154
192
  const { command } = resolved;
155
193
  if (resolved.positionals.length > 0 && command.allowExtraPositionals !== true) {
156
194
  const positional = resolved.positionals[0] ?? '';
157
- throw new errors_1.IcoreError('UNEXPECTED_POSITIONAL', `Unexpected positional argument for '${command.path.join(' ')}': ${positional}`, {
195
+ throw new icore_error_1.IcoreError('UNEXPECTED_POSITIONAL', `Unexpected positional argument for '${command.path.join(' ')}': ${positional}`, {
158
196
  command: command.path.join(' '),
159
197
  positional,
160
198
  positionals: [...resolved.positionals]
161
199
  });
162
200
  }
163
- const parsed = (0, options_1.parseOptionsDetailed)(command.options, rawOptions);
201
+ const parsed = (0, parser_2.parseOptionsDetailed)(command.options, rawOptions);
164
202
  const input = {
165
203
  options: parsed.options,
166
204
  provided: parsed.provided,
@@ -181,7 +219,7 @@ function resolveCommandPositionals(path, positionals) {
181
219
  for (let index = 0; index < path.length; index += 1) {
182
220
  if (positionals[index] !== path[index]) {
183
221
  const command = path.join(' ');
184
- throw new errors_1.IcoreError('UNKNOWN_COMMAND', `Expected command '${command}'`, {
222
+ throw new icore_error_1.IcoreError('UNKNOWN_COMMAND', `Expected command '${command}'`, {
185
223
  command,
186
224
  path: [...path],
187
225
  positionals: [...positionals]
@@ -266,18 +304,18 @@ function isOptionBeforeCommand(arg) {
266
304
  }
267
305
  function createUnknownCommandError(positionals) {
268
306
  const command = formatCommandPositionals(positionals);
269
- return new errors_1.IcoreError('UNKNOWN_COMMAND', `Unknown command: ${command}`, {
307
+ return new icore_error_1.IcoreError('UNKNOWN_COMMAND', `Unknown command: ${command}`, {
270
308
  command,
271
309
  positionals: [...positionals]
272
310
  });
273
311
  }
274
312
  function createUnexpectedArgumentError(argument) {
275
- return new errors_1.IcoreError('UNEXPECTED_ARGUMENT', `Unexpected argument '${argument}'`, {
313
+ return new icore_error_1.IcoreError('UNEXPECTED_ARGUMENT', `Unexpected argument '${argument}'`, {
276
314
  argument
277
315
  });
278
316
  }
279
317
  function createDuplicateCommandError(command) {
280
- return new errors_1.IcoreError('DUPLICATE_COMMAND', `Unexpected duplicate command '${command}'`, {
318
+ return new icore_error_1.IcoreError('DUPLICATE_COMMAND', `Unexpected duplicate command '${command}'`, {
281
319
  command
282
320
  });
283
321
  }
@@ -21,7 +21,9 @@ export type IcoreErrorDetails = Readonly<Record<string, unknown>>;
21
21
  * resolution, and schema configuration failures.
22
22
  */
23
23
  export declare class IcoreError extends Error {
24
+ /** Stable machine-readable code. */
24
25
  readonly code: IcoreErrorCode;
26
+ /** Structured error context. */
25
27
  readonly details: IcoreErrorDetails;
26
28
  constructor(code: IcoreErrorCode, message: string, details?: IcoreErrorDetails);
27
29
  }
@@ -16,7 +16,9 @@ exports.IcoreError = void 0;
16
16
  * resolution, and schema configuration failures.
17
17
  */
18
18
  class IcoreError extends Error {
19
+ /** Stable machine-readable code. */
19
20
  code;
21
+ /** Structured error context. */
20
22
  details;
21
23
  constructor(code, message, details = {}) {
22
24
  super(message);
package/dist/index.d.ts CHANGED
@@ -1 +1,28 @@
1
- export { defineCommand, defineCommandRegistry, IcoreError, isCommandName, isPreparedCommandName, mergeOptionsSchema, parseArgv, parseOptions, parseOptionsDetailed, prepareCommandFromArgs, resolveCommand, resolveCommandFromArgs, runCommand, runPreparedCommand, runCommandFromRegistry, type BooleanOption, type CommandDefinition, type CommandContext, type CommandInput, type CommandName, type CommandPayload, type CommandRegistry, type CommandResolutionOptions, type CommandResult, type InferOptions, type InferProvidedOptions, type IcoreErrorCode, type IcoreErrorDetails, type MergeOptionsSchemas, type NumberOption, type OptionDefinition, type OptionsSchema, type ParseOptionsResult, type ParsedArgv, type PreparedCommand, type PreparedCommandInput, type RawOptionValue, type ResolvedCommand, type StringOption } from './cli';
1
+ /**
2
+ * The package entrypoint exposes the supported command mechanics API.
3
+ *
4
+ * Allowed here:
5
+ * - re-exporting public argv parser contracts;
6
+ * - re-exporting public option schema contracts;
7
+ * - re-exporting public command registry contracts;
8
+ * - re-exporting public presentation and output contracts;
9
+ * - re-exporting public terminal app composition contracts;
10
+ *
11
+ * This file must not contain parser, validator, or command runtime logic.
12
+ */
13
+ export { parseArgv, type ParsedArgv } from './argv/parser';
14
+ export { createCommand, createCommands, defineCommand, defineCommandRegistry, isCommandName, isPreparedCommandName, prepareCommandFromArgs, resolveCommand, resolveCommandFromArgs, runCommand, runPreparedCommand, runCommandFromRegistry, type Command, type CommandDefinition, type CommandContext, type CommandInput, type CommandName, type CommandPayload, type CommandRegistry, type CommandResolutionOptions, type CommandResult, type Commands, type PreparedCommand, type PreparedCommandInput, type ResolvedCommand } from './command/mechanics';
15
+ export { IcoreError, type IcoreErrorCode, type IcoreErrorDetails } from './errors/icore-error';
16
+ export { parseOptions, parseOptionsDetailed, parseOptionsSubsetDetailed, type ParseOptionsResult, type ParseOptionsSubsetResult } from './options/parser';
17
+ export { mergeOptionsSchema, type BooleanOption, type InferOptions, type InferProvidedOptions, type MergeOptionsSchemas, type NumberOption, type OptionDefinition, type OptionsSchema, type RawOptionValue, type StringOption } from './options/schema';
18
+ export { createPresentation, type Presentation, type PresentationRenderers } from './presentation/facade';
19
+ export { isPresentationFormat, presentationFormatOptions, presentationFormats, type PresentationFormat } from './presentation/format-options';
20
+ export { renderCsv, renderCsvRow } from './presentation/renderers/csv';
21
+ export { renderJson } from './presentation/renderers/json';
22
+ export { renderTextTable } from './presentation/renderers/table';
23
+ export { isPresentationResult, renderPresentationResult } from './presentation/result-renderer';
24
+ export { type CsvCell, type CsvRow, type CsvPresentationView, type EmptyPresentationView, type PresentationRecord, type PresentationResult, type PresentationView, type PresentationViewFactory, type RecordPresentationView, type RecordsPresentationView, type TablePresentationView, type TextPresentationView, type TextTableRow } from './presentation/view';
25
+ export { createOutput, type Output, type OutputOptions } from './output/facade';
26
+ export { createStderrWriter, createStdoutWriter } from './output/node-writer';
27
+ export { createBackpressureTextWriter, type BackpressureTextSink, type TextWriter } from './output/text-writer';
28
+ export { createTerminalApp, type TerminalApp, type TerminalAppOptions, type TerminalCommandOutput } from './terminal/app';