icore 1.0.19 → 2.0.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/CHANGELOG.md CHANGED
@@ -9,42 +9,81 @@ Historical entries before this file was introduced were reconstructed from npm
9
9
  publish metadata and local git history. Older entries are intentionally
10
10
  conservative.
11
11
 
12
- Version boundaries between `1.0.12` and `1.0.15` are draft-level and should be
13
- verified against git tags.
12
+ Version boundaries from `1.0.12` through `1.0.19` were checked against npm
13
+ `gitHead` metadata and local git history.
14
14
 
15
15
  ## [Unreleased]
16
16
 
17
+ ## [2.0.0] - 2026-07-14
18
+
19
+ ### Added
20
+
21
+ - Added reusable terminal error rendering and exit-code policy with prepare,
22
+ execute, render, write, and external phase context.
23
+ - Added `TerminalApp.reportError(...)` for caller-owned lifecycle flows that
24
+ need the same stderr and exit-code behavior as `run(...)` and
25
+ `runPrepared(...)`.
26
+ - Added `IcoreError.category` to distinguish usage failures from invalid
27
+ command and option definitions.
28
+ - Added the public `IcoreErrorDetailsMap`, generic `IcoreErrorDetails<TCode>`,
29
+ and distributed `AnyIcoreError` contracts for code-specific error details.
30
+ - Added `isIcoreError(...)` overloads for narrowing any `IcoreError` or one
31
+ exact error code while preserving its details type.
32
+
33
+ ### Changed
34
+
35
+ - Clarified that extra positionals after a matched command path are rejected
36
+ during prepare unless the command declares `allowExtraPositionals: true`.
37
+ - Changed `TerminalApp.run(...)` and `TerminalApp.runPrepared(...)` to share the
38
+ configured terminal error policy while preserving the default error text and
39
+ exit code.
40
+ - **Breaking:** changed the `IcoreError` constructor to require code-specific
41
+ `details`; direct callers must now provide the third argument.
42
+ - Added explicit variant discriminators to `UNKNOWN_COMMAND`,
43
+ `UNEXPECTED_ARGUMENT`, `EXPECTED_REQUIRED_ARGUMENT`, and
44
+ `INVALID_OPTION_DEFAULT` details.
45
+
46
+ ## [1.0.19]
47
+
17
48
  ### Added
18
49
 
19
- - Added `TerminalApp.runPrepared(...)` for running prepared commands through terminal rendering and output.
20
50
  - Added `TerminalApp.writePreparedOutput(...)` for rendering and writing already obtained terminal output.
51
+ - Added `docs/roadmap.md` for directional project decisions that are not release history.
21
52
 
22
53
  ### Changed
23
54
 
24
- - Changed `createTerminalApp` typing to accept command registries with void and prepared payloads.
25
55
  - Changed `createTerminalApp` typing to allow custom command results when consumers run prepared commands themselves.
26
- - Updated testing instructions to use `yarn build` and `yarn test`.
56
+ - Documented the caller-owned flow for command execution results that may be
57
+ lifecycle handles before terminal output is written.
58
+ - Documented that terminal string output is written exactly as provided.
27
59
 
28
- ## [1.0.16]
60
+ ## [1.0.18]
29
61
 
30
62
  ### Added
31
63
 
32
- - Added `createTerminalApp()` as the top-level terminal application composition API.
33
- - Added semantic presentation facade: `createPresentation()`.
34
- - Added semantic output facade: `createOutput()` with `output.write(...)` and `output.error(...)`.
35
- - Added terminal-ready command output support: text, async text streams, presentation results, and empty output.
36
- - Added guide-style examples for terminal app, command flow, option schemas, presentation, output, and lower-level mechanics.
64
+ - Added `TerminalApp.runPrepared(...)` for running prepared commands through terminal rendering and output.
37
65
 
38
66
  ### Changed
39
67
 
40
- - Documentation was reorganized around `command`, `presentation`, and `output`.
41
- - Examples were grouped by usage level: Terminal Application, Layer Toolkit, Primitive Mechanics.
42
- - Public README now positions `icore` as terminal application mechanics, not only argv parsing.
68
+ - Documented the `app.prepare(...)` and `app.runPrepared(...)` flow for applications
69
+ that create and clean up runtime context themselves.
43
70
 
44
- ## [1.0.15]
71
+ ## [1.0.17]
72
+
73
+ ### Changed
74
+
75
+ - Relaxed `createTerminalApp` typing so command registries with commands
76
+ without `prepare()` hooks and with void payloads compile without adapter casts.
77
+
78
+ ## [1.0.16]
45
79
 
46
80
  ### Added
47
81
 
82
+ - Added `createTerminalApp()` as the top-level terminal application composition API.
83
+ - Added command mechanics facade: `createCommand()`.
84
+ - Added semantic presentation facade: `createPresentation()`.
85
+ - Added semantic output facade: `createOutput()` with `output.write(...)` and `output.error(...)`.
86
+ - Added terminal-ready command output support: text, async text streams, presentation results, and empty output.
48
87
  - Added presentation primitives and renderers:
49
88
  - `renderJson`
50
89
  - `renderCsv`
@@ -56,67 +95,62 @@ verified against git tags.
56
95
  - `createStdoutWriter`
57
96
  - `createStderrWriter`
58
97
  - `createBackpressureTextWriter`
98
+ - Added typed option subset parsing with `parseOptionsSubsetDetailed`.
99
+ - Added guide-style examples for terminal app, command flow, option schemas, presentation, output, and lower-level mechanics.
59
100
 
60
101
  ### Changed
61
102
 
62
- - Extracted generic JSON/CSV/table rendering mechanics from project-specific CLI code.
103
+ - Documentation was reorganized around `command`, `presentation`, and `output`.
104
+ - Examples were grouped by usage level: Terminal Application, Layer Toolkit, Primitive Mechanics.
105
+ - Public README now positions `icore` as terminal application mechanics, not only argv parsing.
106
+ - Source files were reorganized by framework area: argv, command, options,
107
+ presentation, output, and terminal app.
108
+ - Updated tests to run with `fwa --prune`.
109
+ - Restored `CHANGELOG.md` to published package contents.
63
110
 
64
- ## [1.0.14]
111
+ ### Removed
112
+
113
+ - Removed the redundant CLI barrel module.
114
+ - Removed the legacy `git-flow.md` document.
115
+ - Removed the `prepare` package script.
116
+
117
+ ## [1.0.15]
65
118
 
66
119
  ### Added
67
120
 
68
- - Added command mechanics facade: `createCommand()`.
69
- - Added command registry flow:
70
- - `command.define(...)`
71
- - `command.registry(...)`
72
- - `commands.prepare(...)`
73
- - `commands.run(...)`
74
- - `commands.runFromArgs(...)`
75
- - Added lower-level command primitives:
76
- - `defineCommand`
77
- - `defineCommandRegistry`
78
- - `createCommands`
79
- - `resolveCommand`
80
- - `prepareCommandFromArgs`
81
- - `runPreparedCommand`
82
- - `runCommandFromRegistry`
83
- - `runCommand`
121
+ - Added `isPreparedCommandName` for narrowing prepared command unions by command name.
84
122
 
85
123
  ### Changed
86
124
 
87
- - CLI command execution became explicitly two-phase: prepare without runtime context, then run with context.
125
+ - Temporarily excluded `CHANGELOG.md` from published package contents.
126
+
127
+ ## [1.0.14]
128
+
129
+ ### Changed
130
+
131
+ - Preserved prepared command payload correlation when narrowing registry unions.
132
+ - Reformatted `CHANGELOG.md` according to Keep a Changelog.
88
133
 
89
134
  ## [1.0.13]
90
135
 
91
136
  ### Added
92
137
 
93
- - Added typed option schema composition with `mergeOptionsSchema`.
94
- - Added option inference helpers for parsed values and provided metadata.
95
- - Added command-name guards:
96
- - `isCommandName`
97
- - `isPreparedCommandName`
98
- - Added detailed option parsing contracts for cases where caller needs explicit provided/not-provided metadata.
138
+ - Added machine-readable `IcoreError` codes and details.
139
+ - Added strict command resolution mode with `strict: true`.
140
+ - Added strict mode support to direct `runCommand(...)` calls.
141
+ - Added typed prepared command payloads.
142
+ - Added `CHANGELOG.md`.
99
143
 
100
144
  ### Changed
101
145
 
102
- - Boolean option handling was tightened around flag syntax: `--flag` and `--no-flag`.
146
+ - Boolean option handling was tightened to flag syntax only.
103
147
 
104
148
  ## [1.0.12]
105
149
 
106
- ### Added
150
+ ### Changed
107
151
 
108
- - Added core typed CLI option mechanics based on literal schemas:
109
- - `type: 'string'`
110
- - `type: 'boolean'`
111
- - `type: 'number'`
112
- - Added GNU-style argv parsing:
113
- - `--name value`
114
- - `--name=value`
115
- - `--flag`
116
- - short aliases
117
- - `--` terminator
118
- - Added machine-readable `IcoreError`.
119
- - Added initial TypeScript-first public API for command-line mechanics.
152
+ - Replaced the preliminary `flagOnly` boolean option setting with typed
153
+ `syntax: 'flag'`.
120
154
 
121
155
  ## [1.0.11] - 2026-07-02
122
156
 
@@ -268,6 +302,9 @@ verified against git tags.
268
302
  - Detailed changelog entries were not maintained for these releases.
269
303
 
270
304
  [Unreleased]: https://github.com/woodger/icore/commits/develop
305
+ [1.0.19]: https://www.npmjs.com/package/icore/v/1.0.19
306
+ [1.0.18]: https://www.npmjs.com/package/icore/v/1.0.18
307
+ [1.0.17]: https://www.npmjs.com/package/icore/v/1.0.17
271
308
  [1.0.16]: https://www.npmjs.com/package/icore/v/1.0.16
272
309
  [1.0.15]: https://www.npmjs.com/package/icore/v/1.0.15
273
310
  [1.0.14]: https://www.npmjs.com/package/icore/v/1.0.14
@@ -147,6 +147,7 @@ function createDuplicateArgumentError(name) {
147
147
  }
148
148
  function createUnexpectedArgumentError(argument) {
149
149
  return new icore_error_1.IcoreError('UNEXPECTED_ARGUMENT', `Unexpected argument '${argument}'`, {
150
+ reason: 'malformed-option',
150
151
  argument
151
152
  });
152
153
  }
@@ -220,6 +220,7 @@ function resolveCommandPositionals(path, positionals) {
220
220
  if (positionals[index] !== path[index]) {
221
221
  const command = path.join(' ');
222
222
  throw new icore_error_1.IcoreError('UNKNOWN_COMMAND', `Expected command '${command}'`, {
223
+ reason: 'path-mismatch',
223
224
  command,
224
225
  path: [...path],
225
226
  positionals: [...positionals]
@@ -305,12 +306,14 @@ function isOptionBeforeCommand(arg) {
305
306
  function createUnknownCommandError(positionals) {
306
307
  const command = formatCommandPositionals(positionals);
307
308
  return new icore_error_1.IcoreError('UNKNOWN_COMMAND', `Unknown command: ${command}`, {
309
+ reason: 'unresolved',
308
310
  command,
309
311
  positionals: [...positionals]
310
312
  });
311
313
  }
312
314
  function createUnexpectedArgumentError(argument) {
313
315
  return new icore_error_1.IcoreError('UNEXPECTED_ARGUMENT', `Unexpected argument '${argument}'`, {
316
+ reason: 'option-before-command',
314
317
  argument
315
318
  });
316
319
  }
@@ -3,27 +3,150 @@
3
3
  *
4
4
  * Allowed here:
5
5
  * - defining stable error codes;
6
+ * - correlating error codes with structured details;
6
7
  * - preserving human-readable messages on Error instances;
7
8
  * - carrying structured details for application-level handling;
9
+ * - narrowing unknown errors by their stable codes;
8
10
  *
9
11
  * This file must not contain parser, validator, or command resolution logic.
10
12
  */
13
+ type OptionIdentityDetails = {
14
+ argument: string;
15
+ option: string;
16
+ };
17
+ type UnknownCommandDetails = {
18
+ reason: 'unresolved';
19
+ command: string;
20
+ positionals: readonly string[];
21
+ } | {
22
+ reason: 'path-mismatch';
23
+ command: string;
24
+ path: readonly string[];
25
+ positionals: readonly string[];
26
+ };
27
+ type UnexpectedArgumentDetails = {
28
+ reason: 'malformed-option';
29
+ argument: string;
30
+ } | {
31
+ reason: 'unknown-option';
32
+ argument: string;
33
+ option: string;
34
+ } | {
35
+ reason: 'option-before-command';
36
+ argument: string;
37
+ };
38
+ type ExpectedRequiredArgumentDetails = {
39
+ reason: 'option';
40
+ argument: string;
41
+ option: string;
42
+ } | {
43
+ reason: 'positional';
44
+ argument: string;
45
+ positional: string;
46
+ };
47
+ type InvalidOptionTypeDetails = OptionIdentityDetails & ({
48
+ expected: 'string' | 'boolean flag' | 'number';
49
+ value: unknown;
50
+ } | {
51
+ expected: 'integer';
52
+ value: number;
53
+ } | {
54
+ expected: 'minimum';
55
+ min: number;
56
+ value: number;
57
+ } | {
58
+ expected: 'maximum';
59
+ max: number;
60
+ value: number;
61
+ });
62
+ type InvalidOptionDefaultDetails = OptionIdentityDetails & ({
63
+ expected: 'string' | 'boolean' | 'number';
64
+ value: unknown;
65
+ } | {
66
+ expected: 'integer';
67
+ value: number;
68
+ } | {
69
+ expected: 'minimum';
70
+ min: number;
71
+ value: number;
72
+ } | {
73
+ expected: 'maximum';
74
+ max: number;
75
+ value: number;
76
+ } | {
77
+ expected: 'choice';
78
+ choices: readonly (string | number)[];
79
+ value: string | number;
80
+ });
81
+ /** Structured details protocol keyed by every stable `IcoreError` code. */
82
+ export type IcoreErrorDetailsMap = {
83
+ UNKNOWN_COMMAND: UnknownCommandDetails;
84
+ UNEXPECTED_ARGUMENT: UnexpectedArgumentDetails;
85
+ DUPLICATE_ARGUMENT: OptionIdentityDetails;
86
+ EXPECTED_REQUIRED_ARGUMENT: ExpectedRequiredArgumentDetails;
87
+ INVALID_OPTION_TYPE: InvalidOptionTypeDetails;
88
+ INVALID_OPTION_CHOICE: OptionIdentityDetails & {
89
+ choices: readonly (string | number)[];
90
+ value: string | number;
91
+ };
92
+ UNEXPECTED_POSITIONAL: {
93
+ command: string;
94
+ positional: string;
95
+ positionals: readonly string[];
96
+ };
97
+ INVALID_OPTION_ALIAS: OptionIdentityDetails & {
98
+ alias: unknown;
99
+ };
100
+ DUPLICATE_ALIAS: {
101
+ argument: string;
102
+ alias: string;
103
+ };
104
+ INVALID_OPTION_DEFAULT: InvalidOptionDefaultDetails;
105
+ DUPLICATE_COMMAND: {
106
+ command: string;
107
+ };
108
+ };
109
+ /** Stable machine-readable error code for `icore` CLI mechanics errors. */
110
+ export type IcoreErrorCode = keyof IcoreErrorDetailsMap;
111
+ /** Structured details for one exact `IcoreError` code. */
112
+ export type IcoreErrorDetails<TCode extends IcoreErrorCode> = Readonly<IcoreErrorDetailsMap[TCode]>;
11
113
  /**
12
- * Stable machine-readable error code for `icore` CLI mechanics errors.
114
+ * Stable category for distinguishing user input failures from invalid command
115
+ * or option definitions.
13
116
  */
14
- export type IcoreErrorCode = 'UNKNOWN_COMMAND' | 'UNEXPECTED_ARGUMENT' | 'DUPLICATE_ARGUMENT' | 'EXPECTED_REQUIRED_ARGUMENT' | 'INVALID_OPTION_TYPE' | 'INVALID_OPTION_CHOICE' | 'UNEXPECTED_POSITIONAL' | 'INVALID_OPTION_ALIAS' | 'DUPLICATE_ALIAS' | 'INVALID_OPTION_DEFAULT' | 'DUPLICATE_COMMAND';
15
- /**
16
- * Structured context for application-level error handling.
17
- */
18
- export type IcoreErrorDetails = Readonly<Record<string, unknown>>;
117
+ export type IcoreErrorCategory = 'usage' | 'definition';
118
+ declare const icoreErrorCategoryByCode: {
119
+ readonly UNKNOWN_COMMAND: "usage";
120
+ readonly UNEXPECTED_ARGUMENT: "usage";
121
+ readonly DUPLICATE_ARGUMENT: "usage";
122
+ readonly EXPECTED_REQUIRED_ARGUMENT: "usage";
123
+ readonly INVALID_OPTION_TYPE: "usage";
124
+ readonly INVALID_OPTION_CHOICE: "usage";
125
+ readonly UNEXPECTED_POSITIONAL: "usage";
126
+ readonly INVALID_OPTION_ALIAS: "definition";
127
+ readonly DUPLICATE_ALIAS: "definition";
128
+ readonly INVALID_OPTION_DEFAULT: "definition";
129
+ readonly DUPLICATE_COMMAND: "definition";
130
+ };
19
131
  /**
20
132
  * Error thrown by `icore` for CLI parsing, option validation, command
21
133
  * resolution, and schema configuration failures.
22
134
  */
23
- export declare class IcoreError extends Error {
135
+ export declare class IcoreError<TCode extends IcoreErrorCode = IcoreErrorCode> extends Error {
24
136
  /** Stable machine-readable code. */
25
- readonly code: IcoreErrorCode;
137
+ readonly code: TCode;
138
+ /** Stable high-level error category. */
139
+ readonly category: typeof icoreErrorCategoryByCode[TCode];
26
140
  /** Structured error context. */
27
- readonly details: IcoreErrorDetails;
28
- constructor(code: IcoreErrorCode, message: string, details?: IcoreErrorDetails);
141
+ readonly details: IcoreErrorDetails<TCode>;
142
+ constructor(code: TCode, message: string, details: IcoreErrorDetails<TCode>);
29
143
  }
144
+ /** Distributed union preserving the correlation between code and details. */
145
+ export type AnyIcoreError = {
146
+ [TCode in IcoreErrorCode]: IcoreError<TCode>;
147
+ }[IcoreErrorCode];
148
+ /** Checks whether an unknown value is any supported `IcoreError`. */
149
+ export declare function isIcoreError(error: unknown): error is AnyIcoreError;
150
+ /** Checks and narrows an unknown value to one exact `IcoreError` code. */
151
+ export declare function isIcoreError<TCode extends IcoreErrorCode>(error: unknown, code: TCode): error is IcoreError<TCode>;
152
+ export {};
@@ -4,13 +4,29 @@
4
4
  *
5
5
  * Allowed here:
6
6
  * - defining stable error codes;
7
+ * - correlating error codes with structured details;
7
8
  * - preserving human-readable messages on Error instances;
8
9
  * - carrying structured details for application-level handling;
10
+ * - narrowing unknown errors by their stable codes;
9
11
  *
10
12
  * This file must not contain parser, validator, or command resolution logic.
11
13
  */
12
14
  Object.defineProperty(exports, "__esModule", { value: true });
13
15
  exports.IcoreError = void 0;
16
+ exports.isIcoreError = isIcoreError;
17
+ const icoreErrorCategoryByCode = {
18
+ UNKNOWN_COMMAND: 'usage',
19
+ UNEXPECTED_ARGUMENT: 'usage',
20
+ DUPLICATE_ARGUMENT: 'usage',
21
+ EXPECTED_REQUIRED_ARGUMENT: 'usage',
22
+ INVALID_OPTION_TYPE: 'usage',
23
+ INVALID_OPTION_CHOICE: 'usage',
24
+ UNEXPECTED_POSITIONAL: 'usage',
25
+ INVALID_OPTION_ALIAS: 'definition',
26
+ DUPLICATE_ALIAS: 'definition',
27
+ INVALID_OPTION_DEFAULT: 'definition',
28
+ DUPLICATE_COMMAND: 'definition'
29
+ };
14
30
  /**
15
31
  * Error thrown by `icore` for CLI parsing, option validation, command
16
32
  * resolution, and schema configuration failures.
@@ -18,14 +34,21 @@ exports.IcoreError = void 0;
18
34
  class IcoreError extends Error {
19
35
  /** Stable machine-readable code. */
20
36
  code;
37
+ /** Stable high-level error category. */
38
+ category;
21
39
  /** Structured error context. */
22
40
  details;
23
- constructor(code, message, details = {}) {
41
+ constructor(code, message, details) {
24
42
  super(message);
25
43
  this.name = 'IcoreError';
26
44
  this.code = code;
45
+ this.category = icoreErrorCategoryByCode[code];
27
46
  this.details = details;
28
47
  Object.setPrototypeOf(this, new.target.prototype);
29
48
  }
30
49
  }
31
50
  exports.IcoreError = IcoreError;
51
+ function isIcoreError(error, code) {
52
+ return error instanceof IcoreError
53
+ && (code === undefined || error.code === code);
54
+ }
package/dist/index.d.ts CHANGED
@@ -12,7 +12,7 @@
12
12
  */
13
13
  export { parseArgv, type ParsedArgv } from './argv/parser';
14
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';
15
+ export { IcoreError, isIcoreError, type AnyIcoreError, type IcoreErrorCategory, type IcoreErrorCode, type IcoreErrorDetails, type IcoreErrorDetailsMap } from './errors/icore-error';
16
16
  export { parseOptions, parseOptionsDetailed, parseOptionsSubsetDetailed, type ParseOptionsResult, type ParseOptionsSubsetResult } from './options/parser';
17
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
18
  export { createPresentation, type Presentation, type PresentationRenderers } from './presentation/facade';
@@ -25,4 +25,4 @@ export { type CsvCell, type CsvRow, type CsvPresentationView, type EmptyPresenta
25
25
  export { createOutput, type Output, type OutputOptions } from './output/facade';
26
26
  export { createStderrWriter, createStdoutWriter } from './output/node-writer';
27
27
  export { createBackpressureTextWriter, type BackpressureTextSink, type TextWriter } from './output/text-writer';
28
- export { createTerminalApp, type TerminalApp, type TerminalAppOptions, type TerminalCommandOutput } from './terminal/app';
28
+ export { createTerminalApp, type TerminalApp, type TerminalAppOptions, type TerminalCommandOutput, type TerminalErrorContext, type TerminalErrorPhase, type TerminalErrorPolicy } from './terminal/app';
package/dist/index.js CHANGED
@@ -12,7 +12,7 @@
12
12
  * This file must not contain parser, validator, or command runtime logic.
13
13
  */
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.createTerminalApp = exports.createBackpressureTextWriter = exports.createStdoutWriter = exports.createStderrWriter = exports.createOutput = exports.renderPresentationResult = exports.isPresentationResult = exports.renderTextTable = exports.renderJson = exports.renderCsvRow = exports.renderCsv = exports.presentationFormats = exports.presentationFormatOptions = exports.isPresentationFormat = exports.createPresentation = exports.mergeOptionsSchema = exports.parseOptionsSubsetDetailed = exports.parseOptionsDetailed = exports.parseOptions = exports.IcoreError = exports.runCommandFromRegistry = exports.runPreparedCommand = exports.runCommand = exports.resolveCommandFromArgs = exports.resolveCommand = exports.prepareCommandFromArgs = exports.isPreparedCommandName = exports.isCommandName = exports.defineCommandRegistry = exports.defineCommand = exports.createCommands = exports.createCommand = exports.parseArgv = void 0;
15
+ exports.createTerminalApp = exports.createBackpressureTextWriter = exports.createStdoutWriter = exports.createStderrWriter = exports.createOutput = exports.renderPresentationResult = exports.isPresentationResult = exports.renderTextTable = exports.renderJson = exports.renderCsvRow = exports.renderCsv = exports.presentationFormats = exports.presentationFormatOptions = exports.isPresentationFormat = exports.createPresentation = exports.mergeOptionsSchema = exports.parseOptionsSubsetDetailed = exports.parseOptionsDetailed = exports.parseOptions = exports.isIcoreError = exports.IcoreError = exports.runCommandFromRegistry = exports.runPreparedCommand = exports.runCommand = exports.resolveCommandFromArgs = exports.resolveCommand = exports.prepareCommandFromArgs = exports.isPreparedCommandName = exports.isCommandName = exports.defineCommandRegistry = exports.defineCommand = exports.createCommands = exports.createCommand = exports.parseArgv = void 0;
16
16
  var parser_1 = require("./argv/parser");
17
17
  Object.defineProperty(exports, "parseArgv", { enumerable: true, get: function () { return parser_1.parseArgv; } });
18
18
  var mechanics_1 = require("./command/mechanics");
@@ -30,6 +30,7 @@ Object.defineProperty(exports, "runPreparedCommand", { enumerable: true, get: fu
30
30
  Object.defineProperty(exports, "runCommandFromRegistry", { enumerable: true, get: function () { return mechanics_1.runCommandFromRegistry; } });
31
31
  var icore_error_1 = require("./errors/icore-error");
32
32
  Object.defineProperty(exports, "IcoreError", { enumerable: true, get: function () { return icore_error_1.IcoreError; } });
33
+ Object.defineProperty(exports, "isIcoreError", { enumerable: true, get: function () { return icore_error_1.isIcoreError; } });
33
34
  var parser_2 = require("./options/parser");
34
35
  Object.defineProperty(exports, "parseOptions", { enumerable: true, get: function () { return parser_2.parseOptions; } });
35
36
  Object.defineProperty(exports, "parseOptionsDetailed", { enumerable: true, get: function () { return parser_2.parseOptionsDetailed; } });
@@ -151,7 +151,10 @@ function validateNumberConstraints(name, definition, parsed, source = 'value') {
151
151
  value: parsed
152
152
  });
153
153
  }
154
- throw createExpectedOptionTypeError(name, 'integer', parsed);
154
+ throw createInvalidOptionTypeError(name, `Expected '--${name}' as integer`, {
155
+ expected: 'integer',
156
+ value: parsed
157
+ });
155
158
  }
156
159
  if (definition.min !== undefined && parsed < definition.min) {
157
160
  const message = `Expected '--${name}' to be greater than or equal to ${String(definition.min)}`;
@@ -192,6 +195,7 @@ function assertChoice(name, choices, value, source = 'value') {
192
195
  const message = `Expected '--${name}' as one of: ${choices.join(', ')}`;
193
196
  if (source === 'default') {
194
197
  throw createInvalidOptionDefaultError(name, message, {
198
+ expected: 'choice',
195
199
  choices: [...choices],
196
200
  value
197
201
  });
@@ -200,12 +204,14 @@ function assertChoice(name, choices, value, source = 'value') {
200
204
  }
201
205
  function createUnexpectedArgumentError(name) {
202
206
  return new icore_error_1.IcoreError('UNEXPECTED_ARGUMENT', `Unexpected argument '--${name}'`, {
207
+ reason: 'unknown-option',
203
208
  argument: `--${name}`,
204
209
  option: name
205
210
  });
206
211
  }
207
212
  function createExpectedRequiredArgumentError(name) {
208
213
  return new icore_error_1.IcoreError('EXPECTED_REQUIRED_ARGUMENT', `Expected required argument '--${name}'`, {
214
+ reason: 'option',
209
215
  argument: `--${name}`,
210
216
  option: name
211
217
  });
@@ -5,6 +5,7 @@
5
5
  * - preparing and running command facades;
6
6
  * - rendering presentation results;
7
7
  * - writing command output through the output facade;
8
+ * - reporting terminal errors through caller-configured policy;
8
9
  *
9
10
  * This file must not contain argv tokenization, option validation internals,
10
11
  * domain behavior, or application-specific report mapping.
@@ -21,6 +22,32 @@ import { type Output } from '../output/facade';
21
22
  * no output. Other result shapes are rejected before writing to stdout.
22
23
  */
23
24
  export type TerminalCommandOutput = string | AsyncIterable<string> | PresentationResult | undefined;
25
+ /** Terminal operation in which an error was observed. */
26
+ export type TerminalErrorPhase = 'prepare' | 'execute' | 'render' | 'write' | 'external';
27
+ /**
28
+ * Context supplied to terminal error policy callbacks.
29
+ *
30
+ * Prepared command data is guaranteed for command execution and terminal
31
+ * output phases. Errors outside terminal app operations may provide either
32
+ * arguments, prepared command data, or neither.
33
+ */
34
+ export type TerminalErrorContext<TPrepared> = {
35
+ phase: 'prepare';
36
+ args: readonly string[];
37
+ } | {
38
+ phase: 'execute' | 'render' | 'write';
39
+ prepared: TPrepared;
40
+ args?: readonly string[];
41
+ } | {
42
+ phase: 'external';
43
+ args?: readonly string[];
44
+ prepared?: TPrepared;
45
+ };
46
+ /** Caller-owned terminal error rendering and process exit-code policy. */
47
+ export type TerminalErrorPolicy<TPrepared> = {
48
+ renderError?(error: unknown, context: TerminalErrorContext<TPrepared>): string;
49
+ resolveExitCode?(error: unknown, context: TerminalErrorContext<TPrepared>): number;
50
+ };
24
51
  type BivariantCallback<TInput, TOutput> = {
25
52
  bivarianceHack(input: TInput): TOutput;
26
53
  }['bivarianceHack'];
@@ -47,6 +74,8 @@ export type TerminalAppOptions<TCommands extends readonly TerminalCommandDefinit
47
74
  presentation?: Presentation;
48
75
  /** Custom output facade. */
49
76
  output?: Output;
77
+ /** Custom terminal error rendering and exit-code policy. */
78
+ errorPolicy?: TerminalErrorPolicy<PreparedCommand<TCommands[number]>>;
50
79
  /** Resolves output format. */
51
80
  resolveFormat?(prepared: PreparedCommand<TCommands[number]>): PresentationFormat | undefined;
52
81
  };
@@ -54,6 +83,8 @@ export type TerminalApp<TCommands extends readonly TerminalCommandDefinition[]>
54
83
  commands: Commands<TCommands>;
55
84
  presentation: Presentation;
56
85
  output: Output;
86
+ /** Renders an error to stderr and returns its process-style exit code. */
87
+ reportError(error: unknown, context?: TerminalErrorContext<PreparedCommand<TCommands[number]>>): Promise<number>;
57
88
  /** No application context required. */
58
89
  prepare(args: readonly string[], options?: CommandResolutionOptions): Promise<PreparedCommand<TCommands[number]>>;
59
90
  /** Runs an already prepared command through terminal rendering and output. */