@outfitter/cli 0.5.1 → 0.5.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/README.md CHANGED
@@ -56,11 +56,11 @@ output(errors, { stream: process.stderr });
56
56
 
57
57
  **Options:**
58
58
 
59
- | Option | Type | Default | Description |
60
- |--------|------|---------|-------------|
61
- | `mode` | `OutputMode` | auto | Force a specific output mode |
62
- | `stream` | `WritableStream` | `stdout` | Stream to write to |
63
- | `pretty` | `boolean` | `false` | Pretty-print JSON output |
59
+ | Option | Type | Default | Description |
60
+ | -------- | ---------------- | -------- | ---------------------------- |
61
+ | `mode` | `OutputMode` | auto | Force a specific output mode |
62
+ | `stream` | `WritableStream` | `stdout` | Stream to write to |
63
+ | `pretty` | `boolean` | `false` | Pretty-print JSON output |
64
64
 
65
65
  **Output Modes:**
66
66
 
@@ -108,10 +108,10 @@ const ids = await collectIds(args.ids, {
108
108
 
109
109
  **Options:**
110
110
 
111
- | Option | Type | Default | Description |
112
- |--------|------|---------|-------------|
113
- | `allowFile` | `boolean` | `true` | Allow `@file` expansion |
114
- | `allowStdin` | `boolean` | `true` | Allow `@-` for stdin |
111
+ | Option | Type | Default | Description |
112
+ | ------------ | --------- | ------- | ----------------------- |
113
+ | `allowFile` | `boolean` | `true` | Allow `@file` expansion |
114
+ | `allowStdin` | `boolean` | `true` | Allow `@-` for stdin |
115
115
 
116
116
  #### `expandFileArg(input, options?)`
117
117
 
@@ -132,11 +132,11 @@ const content = await expandFileArg(args.content, {
132
132
 
133
133
  **Options:**
134
134
 
135
- | Option | Type | Default | Description |
136
- |--------|------|---------|-------------|
137
- | `encoding` | `BufferEncoding` | `utf-8` | File encoding |
138
- | `maxSize` | `number` | - | Maximum file size in bytes |
139
- | `trim` | `boolean` | `false` | Trim whitespace |
135
+ | Option | Type | Default | Description |
136
+ | ---------- | ---------------- | ------- | -------------------------- |
137
+ | `encoding` | `BufferEncoding` | `utf-8` | File encoding |
138
+ | `maxSize` | `number` | - | Maximum file size in bytes |
139
+ | `trim` | `boolean` | `false` | Trim whitespace |
140
140
 
141
141
  #### `parseGlob(pattern, options?)`
142
142
 
@@ -154,13 +154,13 @@ const files = await parseGlob("src/**/*.ts", {
154
154
 
155
155
  **Options:**
156
156
 
157
- | Option | Type | Default | Description |
158
- |--------|------|---------|-------------|
159
- | `cwd` | `string` | `process.cwd()` | Working directory |
160
- | `ignore` | `string[]` | `[]` | Patterns to exclude |
161
- | `onlyFiles` | `boolean` | `false` | Only match files |
162
- | `onlyDirectories` | `boolean` | `false` | Only match directories |
163
- | `followSymlinks` | `boolean` | `false` | Follow symbolic links |
157
+ | Option | Type | Default | Description |
158
+ | ----------------- | ---------- | --------------- | ---------------------- |
159
+ | `cwd` | `string` | `process.cwd()` | Working directory |
160
+ | `ignore` | `string[]` | `[]` | Patterns to exclude |
161
+ | `onlyFiles` | `boolean` | `false` | Only match files |
162
+ | `onlyDirectories` | `boolean` | `false` | Only match directories |
163
+ | `followSymlinks` | `boolean` | `false` | Follow symbolic links |
164
164
 
165
165
  #### `parseKeyValue(input)`
166
166
 
@@ -219,15 +219,15 @@ if (result.isOk()) {
219
219
 
220
220
  **Filter Operators:**
221
221
 
222
- | Prefix | Operator | Description |
223
- |--------|----------|-------------|
224
- | (none) | `eq` | Equals (default) |
225
- | `!` | `ne` | Not equals |
226
- | `>` | `gt` | Greater than |
227
- | `<` | `lt` | Less than |
228
- | `>=` | `gte` | Greater than or equal |
229
- | `<=` | `lte` | Less than or equal |
230
- | `~` | `contains` | Contains substring |
222
+ | Prefix | Operator | Description |
223
+ | ------ | ---------- | --------------------- |
224
+ | (none) | `eq` | Equals (default) |
225
+ | `!` | `ne` | Not equals |
226
+ | `>` | `gt` | Greater than |
227
+ | `<` | `lt` | Less than |
228
+ | `>=` | `gte` | Greater than or equal |
229
+ | `<=` | `lte` | Less than or equal |
230
+ | `~` | `contains` | Contains substring |
231
231
 
232
232
  #### `parseSortSpec(input)`
233
233
 
@@ -268,13 +268,13 @@ if (result.isOk()) {
268
268
 
269
269
  **Options:**
270
270
 
271
- | Option | Type | Default | Description |
272
- |--------|------|---------|-------------|
273
- | `trim` | `boolean` | `false` | Trim whitespace |
271
+ | Option | Type | Default | Description |
272
+ | ----------- | --------- | ------- | -------------------- |
273
+ | `trim` | `boolean` | `false` | Trim whitespace |
274
274
  | `lowercase` | `boolean` | `false` | Convert to lowercase |
275
- | `minLength` | `number` | - | Minimum length |
276
- | `maxLength` | `number` | - | Maximum length |
277
- | `pattern` | `RegExp` | - | Required pattern |
275
+ | `minLength` | `number` | - | Minimum length |
276
+ | `maxLength` | `number` | - | Maximum length |
277
+ | `pattern` | `RegExp` | - | Required pattern |
278
278
 
279
279
  #### `confirmDestructive(options)`
280
280
 
@@ -363,10 +363,15 @@ if (flags.reset) {
363
363
 
364
364
  ## Conventions
365
365
 
366
- Composable flag presets provide typed, reusable CLI flag definitions. See the [full conventions guide](../../docs/CLI-CONVENTIONS.md) for the complete catalog.
366
+ Composable flag presets provide typed, reusable CLI flag definitions. See the [full conventions guide](../../docs/cli/conventions.md) for the complete catalog.
367
367
 
368
368
  ```typescript
369
- import { composePresets, verbosePreset, cwdPreset, forcePreset } from "@outfitter/cli/flags";
369
+ import {
370
+ composePresets,
371
+ verbosePreset,
372
+ cwdPreset,
373
+ forcePreset,
374
+ } from "@outfitter/cli/flags";
370
375
  import { outputModePreset } from "@outfitter/cli/query";
371
376
 
372
377
  const preset = composePresets(verbosePreset(), cwdPreset(), forcePreset());
@@ -382,6 +387,7 @@ command("deploy")
382
387
  **Available presets:** `verbosePreset`, `cwdPreset`, `dryRunPreset`, `forcePreset`, `interactionPreset`, `strictPreset`, `colorPreset`, `projectionPreset`, `paginationPreset`, `timeWindowPreset`, `executionPreset`, `outputModePreset`, `jqPreset`
383
388
 
384
389
  **Additional modules:**
390
+
385
391
  - `@outfitter/cli/verbs` — Standard verb families (`create`, `modify`, `remove`, `list`, `show`)
386
392
  - `@outfitter/cli/query` — Output mode and jq expression presets
387
393
  - `@outfitter/cli/completion` — Shell completion script generation
@@ -390,19 +396,20 @@ command("deploy")
390
396
 
391
397
  ### Environment Variables
392
398
 
393
- | Variable | Description | Default |
394
- |----------|-------------|---------|
395
- | `OUTFITTER_ENV` | Environment profile (`development`, `production`, `test`) | `production` |
396
- | `OUTFITTER_VERBOSE` | Override verbose mode (`1` or `0`) | - |
397
- | `OUTFITTER_JSON` | Set to `1` to force JSON output | - |
398
- | `OUTFITTER_JSONL` | Set to `1` to force JSONL output (takes priority over JSON) | - |
399
- | `XDG_STATE_HOME` | State directory for pagination | Platform-specific |
399
+ | Variable | Description | Default |
400
+ | ------------------- | ----------------------------------------------------------- | ----------------- |
401
+ | `OUTFITTER_ENV` | Environment profile (`development`, `production`, `test`) | `production` |
402
+ | `OUTFITTER_VERBOSE` | Override verbose mode (`1` or `0`) | - |
403
+ | `OUTFITTER_JSON` | Set to `1` to force JSON output | - |
404
+ | `OUTFITTER_JSONL` | Set to `1` to force JSONL output (takes priority over JSON) | - |
405
+ | `XDG_STATE_HOME` | State directory for pagination | Platform-specific |
400
406
 
401
407
  ### `resolveVerbose(verbose?)`
402
408
 
403
409
  Resolve verbose mode from environment configuration. Use this instead of hardcoding verbosity so your CLI responds to `OUTFITTER_ENV` and `OUTFITTER_VERBOSE` automatically.
404
410
 
405
411
  **Precedence** (highest wins):
412
+
406
413
  1. `OUTFITTER_VERBOSE` environment variable (`"1"` or `"0"`)
407
414
  2. Explicit `verbose` parameter (from `--verbose` CLI flag)
408
415
  3. `OUTFITTER_ENV` profile defaults (`true` in development)
@@ -449,18 +456,18 @@ The bridge uses `optsWithGlobals()` so global and subcommand `--json` flags both
449
456
 
450
457
  Exit codes are automatically determined from error categories:
451
458
 
452
- | Category | Exit Code |
453
- |----------|-----------|
454
- | `validation` | 1 |
455
- | `not_found` | 2 |
456
- | `conflict` | 3 |
457
- | `permission` | 4 |
458
- | `timeout` | 5 |
459
- | `rate_limit` | 6 |
460
- | `network` | 7 |
461
- | `internal` | 8 |
462
- | `auth` | 9 |
463
- | `cancelled` | 130 |
459
+ | Category | Exit Code |
460
+ | ------------ | --------- |
461
+ | `validation` | 1 |
462
+ | `not_found` | 2 |
463
+ | `conflict` | 3 |
464
+ | `permission` | 4 |
465
+ | `timeout` | 5 |
466
+ | `rate_limit` | 6 |
467
+ | `network` | 7 |
468
+ | `internal` | 8 |
469
+ | `auth` | 9 |
470
+ | `cancelled` | 130 |
464
471
 
465
472
  ### Tagged Errors
466
473
 
@@ -478,9 +485,18 @@ exitWithError(error); // Exits with code 2
478
485
  All types are exported for TypeScript consumers:
479
486
 
480
487
  ```typescript
481
- import type { CLIConfig, CommandConfig, CommandAction, CommandFlags } from "@outfitter/cli/command";
488
+ import type {
489
+ CLIConfig,
490
+ CommandConfig,
491
+ CommandAction,
492
+ CommandFlags,
493
+ } from "@outfitter/cli/command";
482
494
  import type { OutputMode, OutputOptions } from "@outfitter/cli/output";
483
- import type { CollectIdsOptions, ExpandFileOptions, ParseGlobOptions } from "@outfitter/cli/input";
495
+ import type {
496
+ CollectIdsOptions,
497
+ ExpandFileOptions,
498
+ ParseGlobOptions,
499
+ } from "@outfitter/cli/input";
484
500
  import type { PaginationState, CursorOptions } from "@outfitter/cli/pagination";
485
501
  ```
486
502
 
package/dist/actions.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { SchemaCommandOptions } from "./shared/@outfitter/cli-n1k0d23k";
2
- import { FlagPreset } from "./shared/@outfitter/cli-7n5zmndx";
1
+ import { SchemaCommandOptions } from "./shared/@outfitter/cli-n1k0d23k.js";
2
+ import { FlagPreset } from "./shared/@outfitter/cli-98aa9104.js";
3
3
  import { ActionCliInputContext, ActionCliOption, ActionRegistry, ActionSurface, AnyActionSpec, HandlerContext } from "@outfitter/contracts";
4
4
  import { Command } from "commander";
5
5
  interface BuildCliCommandsOptions {
package/dist/actions.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  createSchemaCommand
4
- } from "./shared/@outfitter/cli-g0sn0r0b.js";
4
+ } from "./shared/@outfitter/cli-5vtr4bdt.js";
5
5
  import {
6
6
  composePresets
7
7
  } from "./shared/@outfitter/cli-pdb7znbq.js";
package/dist/cli.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { CLI, CLIConfig } from "./shared/@outfitter/cli-7n5zmndx";
1
+ import { CLI, CLIConfig } from "./shared/@outfitter/cli-98aa9104.js";
2
2
  /**
3
3
  * Create a new CLI instance with the given configuration.
4
4
  *
@@ -1,2 +1,2 @@
1
- import { ANSI, ColorName, Theme, TokenOptions, Tokens, applyColor, createTheme, createTokens, resolveTokenColorEnabled } from "../shared/@outfitter/cli-xppg982q";
1
+ import { ANSI, ColorName, Theme, TokenOptions, Tokens, applyColor, createTheme, createTokens, resolveTokenColorEnabled } from "../shared/@outfitter/cli-j2x88att.js";
2
2
  export { resolveTokenColorEnabled, createTokens, createTheme, applyColor, Tokens, TokenOptions, Theme, ColorName, ANSI };
@@ -1,3 +1,3 @@
1
- import "../shared/@outfitter/cli-qz47jk6d";
2
- import { ANSI, ColorName, Theme, TokenOptions, Tokens, applyColor, createTheme, createTokens, resolveTokenColorEnabled } from "../shared/@outfitter/cli-xppg982q";
1
+ import "../shared/@outfitter/cli-qz47jk6d.js";
2
+ import { ANSI, ColorName, Theme, TokenOptions, Tokens, applyColor, createTheme, createTokens, resolveTokenColorEnabled } from "../shared/@outfitter/cli-j2x88att.js";
3
3
  export { resolveTokenColorEnabled, createTokens, createTheme, applyColor, Tokens, TokenOptions, Theme, ColorName, ANSI };
@@ -1,17 +1 @@
1
- // @bun
2
- import"../shared/@outfitter/cli-zw75pdk8.js";
3
- import {
4
- ANSI,
5
- applyColor,
6
- createTheme,
7
- createTokens,
8
- resolveTokenColorEnabled
9
- } from "../shared/@outfitter/cli-rk9zagkm.js";
10
- import"../shared/@outfitter/cli-jbj78ac5.js";
11
- export {
12
- resolveTokenColorEnabled,
13
- createTokens,
14
- createTheme,
15
- applyColor,
16
- ANSI
17
- };
1
+ export { ANSI, applyColor, createTheme, createTokens, resolveTokenColorEnabled } from "./colors.js";
package/dist/command.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { CLI, CLIConfig, CommandAction, CommandBuilder, CommandConfig, CommandFlags, FlagPreset } from "./shared/@outfitter/cli-7n5zmndx";
1
+ import { CLI, CLIConfig, CommandAction, CommandBuilder, CommandConfig, CommandFlags, FlagPreset } from "./shared/@outfitter/cli-98aa9104.js";
2
2
  /**
3
3
  * Create a CLI instance with a portable return type from this module.
4
4
  */
@@ -3,10 +3,10 @@ import { Command } from "commander";
3
3
  * Configuration for the completion command.
4
4
  */
5
5
  interface CompletionConfig {
6
- /** Supported shells (default: bash, zsh, fish) */
7
- readonly shells?: readonly ("bash" | "zsh" | "fish")[];
8
6
  /** Program name for completion scripts (inferred from CLI name if not provided) */
9
7
  readonly programName?: string;
8
+ /** Supported shells (default: bash, zsh, fish) */
9
+ readonly shells?: readonly ("bash" | "zsh" | "fish")[];
10
10
  }
11
11
  /**
12
12
  * Generate a completion script for the given shell.
package/dist/flags.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { BooleanFlagPresetConfig, ColorFlags, ColorMode, ComposedPreset, EnumFlagPresetConfig, ExecutionFlags, ExecutionPresetConfig, FlagPreset, FlagPresetConfig, InteractionFlags, NumberFlagPresetConfig, PaginationFlags, PaginationPresetConfig, ProjectionFlags, StrictFlags, StringListFlagPresetConfig, TimeWindowFlags, TimeWindowPresetConfig } from "./shared/@outfitter/cli-7n5zmndx";
1
+ import { BooleanFlagPresetConfig, ColorFlags, ColorMode, ComposedPreset, EnumFlagPresetConfig, ExecutionFlags, ExecutionPresetConfig, FlagPreset, FlagPresetConfig, InteractionFlags, NumberFlagPresetConfig, PaginationFlags, PaginationPresetConfig, ProjectionFlags, StrictFlags, StringListFlagPresetConfig, TimeWindowFlags, TimeWindowPresetConfig } from "./shared/@outfitter/cli-98aa9104.js";
2
2
  /**
3
3
  * Create a typed flag preset.
4
4
  *
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import "./shared/@outfitter/cli-qz47jk6d";
2
- import { ANSI, Theme, Tokens, createTheme } from "./shared/@outfitter/cli-xppg982q";
3
- import { exitWithError, output } from "./shared/@outfitter/cli-z7mgapx5";
4
- import { OutputMode } from "./shared/@outfitter/cli-7n5zmndx";
1
+ import "./shared/@outfitter/cli-qz47jk6d.js";
2
+ import { ANSI, Theme, Tokens, createTheme } from "./shared/@outfitter/cli-j2x88att.js";
3
+ import { exitWithError, output } from "./shared/@outfitter/cli-xy3gs50c.js";
4
+ import { OutputMode } from "./shared/@outfitter/cli-98aa9104.js";
5
5
  export { output, exitWithError, createTheme, Tokens, Theme, OutputMode, ANSI };
package/dist/index.js CHANGED
@@ -1,17 +1,2 @@
1
- // @bun
2
- import"./shared/@outfitter/cli-zw75pdk8.js";
3
- import {
4
- ANSI,
5
- createTheme
6
- } from "./shared/@outfitter/cli-rk9zagkm.js";
7
- import"./shared/@outfitter/cli-jbj78ac5.js";
8
- import {
9
- exitWithError,
10
- output
11
- } from "./shared/@outfitter/cli-7wp5nj0s.js";
12
- export {
13
- output,
14
- exitWithError,
15
- createTheme,
16
- ANSI
17
- };
1
+ export { ANSI, createTheme } from "./colors/index.js";
2
+ export { exitWithError, output } from "./output.js";
package/dist/input.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { CollectIdsOptions, ExpandFileOptions, FilterExpression, KeyValuePair, NormalizeIdOptions, ParseGlobOptions, Range, SortCriteria } from "./shared/@outfitter/cli-7n5zmndx";
1
+ import { CollectIdsOptions, ExpandFileOptions, FilterExpression, KeyValuePair, NormalizeIdOptions, ParseGlobOptions, Range, SortCriteria } from "./shared/@outfitter/cli-98aa9104.js";
2
2
  import { ValidationError } from "@outfitter/contracts";
3
3
  import { Result } from "better-result";
4
4
  /**
package/dist/output.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import { exitWithError, output, resolveVerbose } from "./shared/@outfitter/cli-z7mgapx5";
2
- import "./shared/@outfitter/cli-7n5zmndx";
1
+ import { exitWithError, output, resolveVerbose } from "./shared/@outfitter/cli-xy3gs50c.js";
2
+ import "./shared/@outfitter/cli-98aa9104.js";
3
3
  export { resolveVerbose, output, exitWithError };
package/dist/output.js CHANGED
@@ -1,9 +1,170 @@
1
1
  // @bun
2
+ // packages/cli/src/output.ts
3
+ import { getEnvironment, getEnvironmentDefaults } from "@outfitter/config";
2
4
  import {
3
- exitWithError,
4
- output,
5
- resolveVerbose
6
- } from "./shared/@outfitter/cli-7wp5nj0s.js";
5
+ safeStringify as contractsSafeStringify,
6
+ exitCodeMap
7
+ } from "@outfitter/contracts";
8
+ var DEFAULT_EXIT_CODE = 1;
9
+ function writeWithBackpressure(stream, data) {
10
+ return new Promise((resolve, reject) => {
11
+ const canContinue = stream.write(data, (error) => {
12
+ if (error)
13
+ reject(error);
14
+ });
15
+ if (canContinue) {
16
+ resolve();
17
+ } else {
18
+ stream.once("drain", () => resolve());
19
+ stream.once("error", reject);
20
+ }
21
+ });
22
+ }
23
+ function detectMode(options) {
24
+ if (options?.mode) {
25
+ return options.mode;
26
+ }
27
+ const envJsonl = process.env["OUTFITTER_JSONL"];
28
+ const envJson = process.env["OUTFITTER_JSON"];
29
+ if (envJsonl === "1")
30
+ return "jsonl";
31
+ if (envJson === "1")
32
+ return "json";
33
+ if (envJsonl === "0" || envJson === "0")
34
+ return "human";
35
+ return "human";
36
+ }
37
+ function isValidCategory(category) {
38
+ return category in exitCodeMap;
39
+ }
40
+ function safeStringify(value, pretty) {
41
+ const wrappedValue = value === undefined ? null : value;
42
+ return contractsSafeStringify(wrappedValue, pretty ? 2 : undefined);
43
+ }
44
+ function formatHuman(data) {
45
+ if (data === null || data === undefined) {
46
+ return "";
47
+ }
48
+ if (typeof data === "string") {
49
+ return data;
50
+ }
51
+ if (typeof data === "number" || typeof data === "boolean") {
52
+ return String(data);
53
+ }
54
+ if (Array.isArray(data)) {
55
+ return data.map((item) => formatHuman(item)).join(`
56
+ `);
57
+ }
58
+ if (typeof data === "object") {
59
+ const lines = [];
60
+ for (const [key, value] of Object.entries(data)) {
61
+ lines.push(`${key}: ${formatHuman(value)}`);
62
+ }
63
+ return lines.join(`
64
+ `);
65
+ }
66
+ return String(data);
67
+ }
68
+ function getErrorProperties(error) {
69
+ const errorObj = error;
70
+ return {
71
+ _tag: errorObj._tag,
72
+ category: errorObj.category,
73
+ context: errorObj.context
74
+ };
75
+ }
76
+ function getExitCode(error) {
77
+ const { category } = getErrorProperties(error);
78
+ if (category !== undefined && isValidCategory(category)) {
79
+ return exitCodeMap[category];
80
+ }
81
+ return DEFAULT_EXIT_CODE;
82
+ }
83
+ function serializeErrorToJson(error) {
84
+ const { _tag, category, context } = getErrorProperties(error);
85
+ const result = {
86
+ message: error.message
87
+ };
88
+ if (_tag !== undefined) {
89
+ result._tag = _tag;
90
+ }
91
+ if (category !== undefined) {
92
+ result.category = category;
93
+ }
94
+ if (context !== undefined) {
95
+ result.context = context;
96
+ }
97
+ return JSON.stringify(result);
98
+ }
99
+ function formatErrorHuman(error) {
100
+ const { _tag } = getErrorProperties(error);
101
+ if (_tag) {
102
+ return `${_tag}: ${error.message}`;
103
+ }
104
+ return error.message;
105
+ }
106
+ async function output(data, options) {
107
+ const mode = detectMode(options);
108
+ const stream = options?.stream ?? process.stdout;
109
+ let outputText;
110
+ switch (mode) {
111
+ case "json": {
112
+ const jsonData = data === undefined ? null : data;
113
+ outputText = safeStringify(jsonData, options?.pretty);
114
+ break;
115
+ }
116
+ case "jsonl": {
117
+ if (Array.isArray(data)) {
118
+ if (data.length === 0) {
119
+ outputText = "";
120
+ } else {
121
+ outputText = data.map((item) => safeStringify(item)).join(`
122
+ `);
123
+ }
124
+ } else {
125
+ outputText = safeStringify(data);
126
+ }
127
+ break;
128
+ }
129
+ default: {
130
+ outputText = formatHuman(data);
131
+ break;
132
+ }
133
+ }
134
+ if (outputText) {
135
+ await writeWithBackpressure(stream, `${outputText}
136
+ `);
137
+ }
138
+ }
139
+ function exitWithError(error, options) {
140
+ const exitCode = getExitCode(error);
141
+ const mode = detectMode({
142
+ ...options,
143
+ stream: options?.stream ?? process.stderr
144
+ });
145
+ const isJsonMode = mode === "json" || mode === "jsonl";
146
+ if (isJsonMode) {
147
+ process.stderr.write(`${serializeErrorToJson(error)}
148
+ `);
149
+ } else {
150
+ process.stderr.write(`${formatErrorHuman(error)}
151
+ `);
152
+ }
153
+ process.exit(exitCode);
154
+ }
155
+ function resolveVerbose(verbose) {
156
+ const envVerbose = process.env["OUTFITTER_VERBOSE"];
157
+ if (envVerbose === "1")
158
+ return true;
159
+ if (envVerbose === "0")
160
+ return false;
161
+ if (verbose !== undefined) {
162
+ return verbose;
163
+ }
164
+ const env = getEnvironment();
165
+ const defaults = getEnvironmentDefaults(env);
166
+ return defaults.verbose;
167
+ }
7
168
  export {
8
169
  resolveVerbose,
9
170
  output,
@@ -1,4 +1,4 @@
1
- import { CursorOptions, PaginationState } from "./shared/@outfitter/cli-7n5zmndx";
1
+ import { CursorOptions, PaginationState } from "./shared/@outfitter/cli-98aa9104.js";
2
2
  /**
3
3
  * Load persisted pagination state for a command.
4
4
  *
package/dist/query.d.ts CHANGED
@@ -1,14 +1,14 @@
1
- import { FlagPreset, OutputMode } from "./shared/@outfitter/cli-7n5zmndx";
1
+ import { FlagPreset, OutputMode } from "./shared/@outfitter/cli-98aa9104.js";
2
2
  /**
3
3
  * Configuration for the output mode preset.
4
4
  */
5
5
  interface OutputModePresetConfig {
6
- /** Allowed output modes (default: ["human", "json"]) */
7
- readonly modes?: readonly OutputMode[];
8
6
  /** Default mode when not specified (default: "human") */
9
7
  readonly defaultMode?: OutputMode;
10
8
  /** Whether to include "jsonl" in allowed modes (default: false) */
11
9
  readonly includeJsonl?: boolean;
10
+ /** Allowed output modes (default: ["human", "json"]) */
11
+ readonly modes?: readonly OutputMode[];
12
12
  }
13
13
  /**
14
14
  * Resolved output mode from CLI input.
package/dist/schema.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { ActionManifest, ActionManifestEntry, ActionSource, GenerateManifestOptions, SchemaCommandOptions, SurfaceCommandOptions, createSchemaCommand, formatManifestHuman, generateManifest } from "./shared/@outfitter/cli-n1k0d23k";
1
+ import { ActionManifest, ActionManifestEntry, ActionSource, GenerateManifestOptions, SchemaCommandOptions, SurfaceCommandOptions, createSchemaCommand, formatManifestHuman, generateManifest } from "./shared/@outfitter/cli-n1k0d23k.js";
2
2
  export { generateManifest, formatManifestHuman, createSchemaCommand, SurfaceCommandOptions, SchemaCommandOptions, GenerateManifestOptions, ActionSource, ActionManifestEntry, ActionManifest };
package/dist/schema.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  createSchemaCommand,
4
4
  formatManifestHuman,
5
5
  generateManifest
6
- } from "./shared/@outfitter/cli-g0sn0r0b.js";
6
+ } from "./shared/@outfitter/cli-5vtr4bdt.js";
7
7
  export {
8
8
  generateManifest,
9
9
  formatManifestHuman,
@@ -42,9 +42,9 @@ function formatSummary(manifest, programName) {
42
42
  for (const [groupName, groupActions] of grouped.entries()) {
43
43
  lines.push(groupName);
44
44
  for (const action of groupActions) {
45
- const commandPart = action.cli?.command ?? action.id;
45
+ const commandPart = action.cli?.command ?? "";
46
46
  const isBase = !commandPart || commandPart.startsWith("[") || commandPart.startsWith("<");
47
- const displayCommand = isBase ? ` ${groupName} ${commandPart ?? ""}`.trimEnd() : ` ${groupName} ${commandPart}`;
47
+ const displayCommand = isBase ? ` ${groupName} ${commandPart}`.trimEnd() : ` ${groupName} ${commandPart}`;
48
48
  const desc = action.cli?.description ?? action.description ?? "";
49
49
  lines.push(padCommand(displayCommand, desc));
50
50
  }
@@ -76,8 +76,8 @@ function formatActionDetail(manifest, actionId) {
76
76
  lines.push("");
77
77
  if (entry.cli) {
78
78
  const group = entry.cli.group;
79
- const commandPart = entry.cli.command ?? entry.id;
80
- const fullCommand = group ? `${group} ${commandPart}` : commandPart;
79
+ const commandPart = entry.cli.command ?? (group ? "" : entry.id);
80
+ const fullCommand = group ? `${group} ${commandPart}`.trimEnd() : commandPart;
81
81
  lines.push(` Command: ${fullCommand}`);
82
82
  }
83
83
  lines.push(` Surfaces: ${entry.surfaces.join(", ")}`);
@@ -174,6 +174,7 @@ function createSchemaCommand(source, options) {
174
174
  const diffCmd = new Command("diff").description("Compare runtime schema against committed surface map").option("--output <mode>", "Output mode (human, json)", "human").option("--against <version>", "Compare runtime against a named snapshot").option("--from <version>", "Base snapshot for snapshot-to-snapshot diff").option("--to <version>", "Target snapshot for snapshot-to-snapshot diff").action(async (diffOptions) => {
175
175
  let left;
176
176
  let right;
177
+ let diffMode = "committed-to-runtime";
177
178
  if (diffOptions.from && !diffOptions.to || !diffOptions.from && diffOptions.to) {
178
179
  process.stderr.write(`Both --from and --to are required for snapshot-to-snapshot diff.
179
180
  `);
@@ -181,6 +182,7 @@ function createSchemaCommand(source, options) {
181
182
  return;
182
183
  }
183
184
  if (diffOptions.from && diffOptions.to) {
185
+ diffMode = "snapshot-to-snapshot";
184
186
  const fromPath = resolveSnapshotPath(cwd, outputDir, diffOptions.from);
185
187
  const toPath = resolveSnapshotPath(cwd, outputDir, diffOptions.to);
186
188
  try {
@@ -210,6 +212,7 @@ function createSchemaCommand(source, options) {
210
212
  return;
211
213
  }
212
214
  } else if (diffOptions.against) {
215
+ diffMode = "snapshot-to-runtime";
213
216
  const snapshotPath = resolveSnapshotPath(cwd, outputDir, diffOptions.against);
214
217
  try {
215
218
  left = await readSurfaceMap(snapshotPath);
@@ -244,7 +247,7 @@ function createSchemaCommand(source, options) {
244
247
  }
245
248
  right = generateSurfaceMap(source, { generator: "runtime" });
246
249
  }
247
- const result = diffSurfaceMaps(left, right);
250
+ const result = diffSurfaceMaps(left, right, { mode: diffMode });
248
251
  if (diffOptions.output === "json") {
249
252
  process.stdout.write(`${JSON.stringify(result, null, 2)}
250
253
  `);
@@ -1,4 +1,4 @@
1
- import { OutputOptions } from "./cli-7n5zmndx";
1
+ import { OutputOptions } from "./cli-98aa9104.js";
2
2
  /**
3
3
  * Output data to the console with automatic mode selection.
4
4
  *
@@ -1,2 +1,2 @@
1
- import { TerminalOptions, getEnvValue, getTerminalWidth, hasNoColorEnv, isInteractive, resolveColorEnv, resolveForceColorEnv, supportsColor } from "../shared/@outfitter/cli-8aa1vhdn";
1
+ import { TerminalOptions, getEnvValue, getTerminalWidth, hasNoColorEnv, isInteractive, resolveColorEnv, resolveForceColorEnv, supportsColor } from "../shared/@outfitter/cli-rr1sq5s4.js";
2
2
  export { supportsColor, resolveForceColorEnv, resolveColorEnv, isInteractive, hasNoColorEnv, getTerminalWidth, getEnvValue, TerminalOptions };
@@ -1,2 +1,2 @@
1
- import { TerminalOptions, getEnvValue, getTerminalWidth, hasNoColorEnv, isInteractive, resolveColorEnv, resolveForceColorEnv, supportsColor } from "../shared/@outfitter/cli-8aa1vhdn";
1
+ import { TerminalOptions, getEnvValue, getTerminalWidth, hasNoColorEnv, isInteractive, resolveColorEnv, resolveForceColorEnv, supportsColor } from "../shared/@outfitter/cli-rr1sq5s4.js";
2
2
  export { supportsColor, resolveForceColorEnv, resolveColorEnv, isInteractive, hasNoColorEnv, getTerminalWidth, getEnvValue, TerminalOptions };