@outfitter/cli 0.5.3 → 1.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/README.md +105 -2
- package/dist/actions.d.ts +5 -2
- package/dist/actions.js +2 -2
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +8 -1
- package/dist/command.d.ts +3 -43
- package/dist/command.js +241 -13
- package/dist/envelope.d.ts +5 -0
- package/dist/envelope.js +160 -0
- package/dist/flags.d.ts +5 -189
- package/dist/flags.js +5 -1
- package/dist/hints.d.ts +34 -0
- package/dist/hints.js +26 -0
- package/dist/index.d.ts +3 -2
- package/dist/input.d.ts +3 -124
- package/dist/input.js +14 -359
- package/dist/internal/envelope-helpers.d.ts +4 -0
- package/dist/internal/envelope-helpers.js +24 -0
- package/dist/internal/envelope-types.d.ts +3 -0
- package/dist/internal/envelope-types.js +1 -0
- package/dist/internal/flag-builders.d.ts +3 -0
- package/dist/internal/flag-builders.js +155 -0
- package/dist/internal/flag-types.d.ts +3 -0
- package/dist/internal/flag-types.js +13 -0
- package/dist/internal/hint-action-graph.d.ts +5 -0
- package/dist/internal/hint-action-graph.js +11 -0
- package/dist/internal/hint-command-tree.d.ts +5 -0
- package/dist/internal/hint-command-tree.js +9 -0
- package/dist/internal/hint-error-recovery.d.ts +2 -0
- package/dist/internal/hint-error-recovery.js +7 -0
- package/dist/internal/hint-types.d.ts +4 -0
- package/dist/internal/hint-types.js +1 -0
- package/dist/internal/input-helpers.d.ts +18 -0
- package/dist/internal/input-helpers.js +11 -0
- package/dist/internal/input-normalization.d.ts +3 -0
- package/dist/internal/input-normalization.js +9 -0
- package/dist/internal/input-parsers.d.ts +3 -0
- package/dist/internal/input-parsers.js +19 -0
- package/dist/internal/input-security.d.ts +22 -0
- package/dist/internal/input-security.js +11 -0
- package/dist/internal/output-formatting.d.ts +3 -0
- package/dist/internal/output-formatting.js +21 -0
- package/dist/internal/presets.d.ts +3 -0
- package/dist/{shared/@outfitter/cli-pdb7znbq.js → internal/presets.js} +49 -223
- package/dist/internal/schema-commands.d.ts +3 -0
- package/dist/{shared/@outfitter/cli-5vtr4bdt.js → internal/schema-commands.js} +8 -99
- package/dist/internal/schema-formatting.d.ts +2 -0
- package/dist/internal/schema-formatting.js +7 -0
- package/dist/internal/schema-types.d.ts +2 -0
- package/dist/internal/schema-types.js +1 -0
- package/dist/output.d.ts +4 -3
- package/dist/output.js +13 -166
- package/dist/pagination.d.ts +1 -1
- package/dist/query.d.ts +84 -2
- package/dist/query.js +8 -45
- package/dist/schema-input.d.ts +80 -0
- package/dist/schema-input.js +15 -0
- package/dist/schema.d.ts +4 -1
- package/dist/schema.js +1 -1
- package/dist/shared/@outfitter/cli-10wxfc78.d.ts +45 -0
- package/dist/shared/@outfitter/cli-16wg5mka.d.ts +71 -0
- package/dist/shared/@outfitter/cli-1q5redaj.js +267 -0
- package/dist/shared/@outfitter/cli-2dfxs239.js +98 -0
- package/dist/shared/@outfitter/cli-30mt7c5w.d.ts +112 -0
- package/dist/shared/@outfitter/cli-3jta1h1h.js +134 -0
- package/dist/shared/@outfitter/cli-4h85mpth.js +76 -0
- package/dist/shared/@outfitter/cli-6shkwxdc.js +28 -0
- package/dist/shared/@outfitter/cli-89335n9a.js +16 -0
- package/dist/shared/@outfitter/cli-8999qjdd.js +3 -0
- package/dist/shared/@outfitter/cli-8cfxdady.js +60 -0
- package/dist/shared/@outfitter/cli-bcajqy33.d.ts +25 -0
- package/dist/shared/@outfitter/cli-c09332vm.d.ts +39 -0
- package/dist/shared/@outfitter/cli-cgha038c.d.ts +3 -0
- package/dist/shared/@outfitter/{cli-zahqsaby.js → cli-d40m2x1d.js} +19 -3
- package/dist/shared/@outfitter/cli-dg0cz7rw.js +127 -0
- package/dist/shared/@outfitter/cli-dv8kk4jw.d.ts +24 -0
- package/dist/shared/@outfitter/cli-g43887b7.js +20 -0
- package/dist/shared/@outfitter/cli-gqtkhgw4.js +52 -0
- package/dist/shared/@outfitter/cli-h4ejpmjs.d.ts +104 -0
- package/dist/shared/@outfitter/cli-htzez8v2.js +70 -0
- package/dist/shared/@outfitter/cli-hvg2m5gf.js +79 -0
- package/dist/shared/@outfitter/cli-n54zs151.d.ts +78 -0
- package/dist/shared/@outfitter/cli-nbpgw7z7.d.ts +15 -0
- package/dist/shared/@outfitter/cli-nkt399zf.d.ts +94 -0
- package/dist/shared/@outfitter/cli-pmd04gtv.d.ts +60 -0
- package/dist/shared/@outfitter/{cli-xy3gs50c.d.ts → cli-q6csxmeh.d.ts} +19 -12
- package/dist/shared/@outfitter/cli-qcskd96y.d.ts +11 -0
- package/dist/shared/@outfitter/cli-ry7btmy4.js +118 -0
- package/dist/shared/@outfitter/cli-sy99pjyj.js +32 -0
- package/dist/shared/@outfitter/cli-tm2fzngs.d.ts +23 -0
- package/dist/shared/@outfitter/cli-vvvhjwks.js +106 -0
- package/dist/shared/@outfitter/cli-wjv7g1aq.d.ts +16 -0
- package/dist/shared/@outfitter/{cli-98aa9104.d.ts → cli-x6qr7bnd.d.ts} +338 -16
- package/dist/shared/@outfitter/cli-xde45xcc.d.ts +53 -0
- package/dist/shared/@outfitter/cli-xw8ys1je.d.ts +123 -0
- package/dist/shared/@outfitter/cli-yfewnyc2.d.ts +43 -0
- package/dist/shared/@outfitter/cli-zkzj0q4q.js +99 -0
- package/dist/shared/@outfitter/cli-zv3ah6f0.js +3 -0
- package/dist/streaming.d.ts +47 -0
- package/dist/streaming.js +13 -0
- package/dist/truncation.d.ts +104 -0
- package/dist/truncation.js +111 -0
- package/dist/types.d.ts +2 -2
- package/dist/verbs.d.ts +1 -1
- package/package.json +55 -25
- package/dist/shared/@outfitter/cli-n1k0d23k.d.ts +0 -33
package/dist/output.js
CHANGED
|
@@ -1,172 +1,19 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
// packages/cli/src/output.ts
|
|
3
|
-
import { getEnvironment, getEnvironmentDefaults } from "@outfitter/config";
|
|
4
2
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
}
|
|
3
|
+
exitWithError,
|
|
4
|
+
output,
|
|
5
|
+
resolveVerbose
|
|
6
|
+
} from "./shared/@outfitter/cli-4h85mpth.js";
|
|
7
|
+
import {
|
|
8
|
+
cliStringify,
|
|
9
|
+
detectMode,
|
|
10
|
+
formatHuman
|
|
11
|
+
} from "./shared/@outfitter/cli-dg0cz7rw.js";
|
|
168
12
|
export {
|
|
169
13
|
resolveVerbose,
|
|
170
14
|
output,
|
|
171
|
-
|
|
15
|
+
formatHuman,
|
|
16
|
+
exitWithError,
|
|
17
|
+
detectMode,
|
|
18
|
+
cliStringify
|
|
172
19
|
};
|
package/dist/pagination.d.ts
CHANGED
package/dist/query.d.ts
CHANGED
|
@@ -1,4 +1,66 @@
|
|
|
1
|
-
import { FlagPreset, OutputMode } from "./shared/@outfitter/cli-
|
|
1
|
+
import { FlagPreset, OutputMode } from "./shared/@outfitter/cli-x6qr7bnd.js";
|
|
2
|
+
/**
|
|
3
|
+
* Source of the resolved output mode, indicating how the mode was determined.
|
|
4
|
+
*
|
|
5
|
+
* - `"flag"` — User explicitly passed `--output`, `-o`, `--json`, or `--jsonl`
|
|
6
|
+
* - `"env"` — Mode set via `OUTFITTER_JSON=1` or `OUTFITTER_JSONL=1`
|
|
7
|
+
* - `"default"` — No explicit input; using the configured default (typically `"human"`)
|
|
8
|
+
*/
|
|
9
|
+
type OutputModeSource = "flag" | "env" | "default";
|
|
10
|
+
/**
|
|
11
|
+
* Result of resolving output mode with source/explicitness tracking.
|
|
12
|
+
*/
|
|
13
|
+
interface ResolvedOutputMode {
|
|
14
|
+
/** The resolved output mode */
|
|
15
|
+
readonly mode: "human" | "json" | "jsonl";
|
|
16
|
+
/** How the mode was determined */
|
|
17
|
+
readonly source: OutputModeSource;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Configuration for the centralized output mode resolver.
|
|
21
|
+
*/
|
|
22
|
+
interface ResolveOutputModeConfig {
|
|
23
|
+
/** Custom argv for explicit-flag detection (defaults to `process.argv.slice(2)`) */
|
|
24
|
+
readonly argv?: readonly string[];
|
|
25
|
+
/** Default mode when not specified (default: `"human"`) */
|
|
26
|
+
readonly defaultMode?: "human" | "json" | "jsonl";
|
|
27
|
+
/**
|
|
28
|
+
* When `true`, skip env-var fallback and return the default for implicit
|
|
29
|
+
* modes. Useful for orchestrator modes (e.g., `check --pre-commit`) where
|
|
30
|
+
* structured output should require an explicit flag.
|
|
31
|
+
*/
|
|
32
|
+
readonly forceHumanWhenImplicit?: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Centralized output-mode resolver with source/explicitness tracking.
|
|
36
|
+
*
|
|
37
|
+
* Resolves the output mode from CLI flags, environment variables, or defaults.
|
|
38
|
+
* Returns both the resolved mode and its source so callers can make decisions
|
|
39
|
+
* based on how the mode was determined.
|
|
40
|
+
*
|
|
41
|
+
* **Resolution order (highest wins):**
|
|
42
|
+
* 1. Explicit `--output` / `-o` flag (source: `"flag"`)
|
|
43
|
+
* 2. Legacy `--json` / `--jsonl` boolean flags (source: `"flag"`)
|
|
44
|
+
* 3. `OUTFITTER_JSONL=1` / `OUTFITTER_JSON=1` env vars (source: `"env"`)
|
|
45
|
+
* 4. Configured default — typically `"human"` (source: `"default"`)
|
|
46
|
+
*
|
|
47
|
+
* When `forceHumanWhenImplicit` is set, steps 3–4 collapse to `"human"`.
|
|
48
|
+
*
|
|
49
|
+
* @param flags - Raw Commander flags (from `context.flags`)
|
|
50
|
+
* @param config - Optional configuration
|
|
51
|
+
* @returns The resolved mode and its source
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```typescript
|
|
55
|
+
* import { resolveOutputMode } from "@outfitter/cli/query";
|
|
56
|
+
*
|
|
57
|
+
* // In a mapInput function:
|
|
58
|
+
* const { mode, source } = resolveOutputMode(context.flags);
|
|
59
|
+
* // mode: "human" | "json" | "jsonl"
|
|
60
|
+
* // source: "flag" | "env" | "default"
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
declare function resolveOutputMode(flags: Record<string, unknown>, config?: ResolveOutputModeConfig): ResolvedOutputMode;
|
|
2
64
|
/**
|
|
3
65
|
* Configuration for the output mode preset.
|
|
4
66
|
*/
|
|
@@ -38,6 +100,26 @@ type JqFlags = {
|
|
|
38
100
|
readonly jq: string | undefined;
|
|
39
101
|
};
|
|
40
102
|
/**
|
|
103
|
+
* Resolved stream flags from CLI input.
|
|
104
|
+
*/
|
|
105
|
+
type StreamFlags = {
|
|
106
|
+
/** Whether NDJSON streaming mode is enabled */
|
|
107
|
+
readonly stream: boolean;
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* NDJSON streaming flag preset.
|
|
111
|
+
*
|
|
112
|
+
* Adds: `--stream`
|
|
113
|
+
* Resolves: `{ stream: boolean }`
|
|
114
|
+
*
|
|
115
|
+
* When enabled, the CLI writes progress events as newline-delimited JSON
|
|
116
|
+
* (NDJSON) to stdout. The final line is the standard command envelope.
|
|
117
|
+
*
|
|
118
|
+
* `--stream` is orthogonal to output mode — it controls delivery, not
|
|
119
|
+
* serialization. Works alongside `--output human|json|jsonl` and env vars.
|
|
120
|
+
*/
|
|
121
|
+
declare function streamPreset(): FlagPreset<StreamFlags>;
|
|
122
|
+
/**
|
|
41
123
|
* JQ expression flag preset.
|
|
42
124
|
*
|
|
43
125
|
* Adds: `--jq <expr>`
|
|
@@ -47,4 +129,4 @@ type JqFlags = {
|
|
|
47
129
|
* Actual jq execution is a consumer concern.
|
|
48
130
|
*/
|
|
49
131
|
declare function jqPreset(): FlagPreset<JqFlags>;
|
|
50
|
-
export { outputModePreset, jqPreset, OutputModePresetConfig, OutputModeFlags, JqFlags };
|
|
132
|
+
export { streamPreset, resolveOutputMode, outputModePreset, jqPreset, StreamFlags, ResolvedOutputMode, ResolveOutputModeConfig, OutputModeSource, OutputModePresetConfig, OutputModeFlags, JqFlags };
|
package/dist/query.js
CHANGED
|
@@ -1,51 +1,14 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const baseModes = config?.modes ?? ["human", "json"];
|
|
10
|
-
const modes = new Set(config?.includeJsonl ? [...baseModes, "jsonl"] : baseModes);
|
|
11
|
-
modes.add(defaultMode);
|
|
12
|
-
return createPreset({
|
|
13
|
-
id: "outputMode",
|
|
14
|
-
options: [
|
|
15
|
-
{
|
|
16
|
-
flags: "-o, --output <mode>",
|
|
17
|
-
description: `Output mode (${[...modes].join(", ")})`,
|
|
18
|
-
defaultValue: defaultMode
|
|
19
|
-
}
|
|
20
|
-
],
|
|
21
|
-
resolve: (flags) => {
|
|
22
|
-
const raw = flags["output"];
|
|
23
|
-
if (typeof raw === "string" && modes.has(raw)) {
|
|
24
|
-
return { outputMode: raw };
|
|
25
|
-
}
|
|
26
|
-
return { outputMode: defaultMode };
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
function jqPreset() {
|
|
31
|
-
return createPreset({
|
|
32
|
-
id: "jq",
|
|
33
|
-
options: [
|
|
34
|
-
{
|
|
35
|
-
flags: "--jq <expr>",
|
|
36
|
-
description: "Filter JSON output with a jq expression"
|
|
37
|
-
}
|
|
38
|
-
],
|
|
39
|
-
resolve: (flags) => {
|
|
40
|
-
const raw = flags["jq"];
|
|
41
|
-
if (typeof raw === "string" && raw.length > 0) {
|
|
42
|
-
return { jq: raw };
|
|
43
|
-
}
|
|
44
|
-
return { jq: undefined };
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
}
|
|
3
|
+
jqPreset,
|
|
4
|
+
outputModePreset,
|
|
5
|
+
resolveOutputMode,
|
|
6
|
+
streamPreset
|
|
7
|
+
} from "./shared/@outfitter/cli-vvvhjwks.js";
|
|
8
|
+
import"./shared/@outfitter/cli-8999qjdd.js";
|
|
48
9
|
export {
|
|
10
|
+
streamPreset,
|
|
11
|
+
resolveOutputMode,
|
|
49
12
|
outputModePreset,
|
|
50
13
|
jqPreset
|
|
51
14
|
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Option } from "commander";
|
|
2
|
+
/** Result of unwrapping a Zod field's type chain. */
|
|
3
|
+
interface ZodFieldInfo {
|
|
4
|
+
/** The base Zod type name (string, number, boolean, enum). */
|
|
5
|
+
readonly baseType: string;
|
|
6
|
+
/** Default value if .default() was used. */
|
|
7
|
+
readonly defaultValue: unknown;
|
|
8
|
+
/** Description from .describe(). */
|
|
9
|
+
readonly description: string | undefined;
|
|
10
|
+
/** Enum values if baseType is 'enum'. */
|
|
11
|
+
readonly enumValues: readonly string[] | undefined;
|
|
12
|
+
/** Whether .default() was used. */
|
|
13
|
+
readonly hasDefault: boolean;
|
|
14
|
+
/** Whether the field is optional. */
|
|
15
|
+
readonly isOptional: boolean;
|
|
16
|
+
}
|
|
17
|
+
/** Derived Commander flag definition from a Zod field. */
|
|
18
|
+
interface DerivedFlag {
|
|
19
|
+
/** Commander default value. */
|
|
20
|
+
readonly defaultValue: unknown;
|
|
21
|
+
/** Commander option description. */
|
|
22
|
+
readonly description: string;
|
|
23
|
+
/** Commander flag string (e.g., "--output-dir <value>"). */
|
|
24
|
+
readonly flagString: string;
|
|
25
|
+
/** Whether this is a boolean flag (no value). */
|
|
26
|
+
readonly isBoolean: boolean;
|
|
27
|
+
/** Whether the field is required (no default, not optional). */
|
|
28
|
+
readonly isRequired: boolean;
|
|
29
|
+
/** Long flag name including dashes (e.g., "--output-dir"). */
|
|
30
|
+
readonly longFlag: string;
|
|
31
|
+
/** Original camelCase field name from the Zod schema. */
|
|
32
|
+
readonly name: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Convert a camelCase string to kebab-case.
|
|
36
|
+
*/
|
|
37
|
+
declare function camelToKebab(str: string): string;
|
|
38
|
+
/**
|
|
39
|
+
* Unwrap a Zod field to extract its base type, description, default, and optionality.
|
|
40
|
+
*
|
|
41
|
+
* Handles chains like: z.string().optional().default('hi').describe('desc')
|
|
42
|
+
*/
|
|
43
|
+
declare function unwrapZodField(field: unknown): ZodFieldInfo;
|
|
44
|
+
/**
|
|
45
|
+
* Derive Commander flag definitions from a Zod object schema.
|
|
46
|
+
*
|
|
47
|
+
* Handles:
|
|
48
|
+
* - z.string() → `--name <value>` (string option)
|
|
49
|
+
* - z.number() → `--count <n>` (number option with coercion)
|
|
50
|
+
* - z.boolean() → `--verbose` (boolean flag)
|
|
51
|
+
* - z.enum(['a','b']) → `--format <value>` with choices
|
|
52
|
+
* - .describe() → option description
|
|
53
|
+
* - .default() → option default
|
|
54
|
+
* - .optional() → not required
|
|
55
|
+
*/
|
|
56
|
+
declare function deriveFlags(schema: {
|
|
57
|
+
shape: Record<string, unknown>;
|
|
58
|
+
}, explicitLongFlags: ReadonlySet<string>): DerivedFlag[];
|
|
59
|
+
/**
|
|
60
|
+
* Create a Commander Option from a derived flag definition,
|
|
61
|
+
* including choices for enum types and argParser for number types.
|
|
62
|
+
*/
|
|
63
|
+
declare function createCommanderOption(flag: DerivedFlag, schema: {
|
|
64
|
+
shape: Record<string, unknown>;
|
|
65
|
+
}): Option;
|
|
66
|
+
/**
|
|
67
|
+
* Extract validated input from parsed Commander flags using a Zod schema.
|
|
68
|
+
*
|
|
69
|
+
* Maps Commander flag values (which use camelCase keys) to the schema
|
|
70
|
+
* field names, then runs Zod validation to apply defaults and coercion.
|
|
71
|
+
*/
|
|
72
|
+
declare function validateInput(flags: Record<string, unknown>, schema: {
|
|
73
|
+
shape: Record<string, unknown>;
|
|
74
|
+
safeParse: (data: unknown) => {
|
|
75
|
+
success: boolean;
|
|
76
|
+
data?: unknown;
|
|
77
|
+
error?: unknown;
|
|
78
|
+
};
|
|
79
|
+
}): Record<string, unknown>;
|
|
80
|
+
export { validateInput, unwrapZodField, deriveFlags, createCommanderOption, camelToKebab, ZodFieldInfo, DerivedFlag };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
camelToKebab,
|
|
4
|
+
createCommanderOption,
|
|
5
|
+
deriveFlags,
|
|
6
|
+
unwrapZodField,
|
|
7
|
+
validateInput
|
|
8
|
+
} from "./shared/@outfitter/cli-3jta1h1h.js";
|
|
9
|
+
export {
|
|
10
|
+
validateInput,
|
|
11
|
+
unwrapZodField,
|
|
12
|
+
deriveFlags,
|
|
13
|
+
createCommanderOption,
|
|
14
|
+
camelToKebab
|
|
15
|
+
};
|
package/dist/schema.d.ts
CHANGED
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
import { ActionManifest, ActionManifestEntry, ActionSource, GenerateManifestOptions,
|
|
1
|
+
import { ActionManifest, ActionManifestEntry, ActionSource, GenerateManifestOptions, generateManifest } from "./shared/@outfitter/cli-cgha038c.js";
|
|
2
|
+
import { createSchemaCommand } from "./shared/@outfitter/cli-nbpgw7z7.js";
|
|
3
|
+
import { SchemaCommandOptions, SurfaceCommandOptions } from "./shared/@outfitter/cli-wjv7g1aq.js";
|
|
4
|
+
import { formatManifestHuman } from "./shared/@outfitter/cli-qcskd96y.js";
|
|
2
5
|
export { generateManifest, formatManifestHuman, createSchemaCommand, SurfaceCommandOptions, SchemaCommandOptions, GenerateManifestOptions, ActionSource, ActionManifestEntry, ActionManifest };
|
package/dist/schema.js
CHANGED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { OutputMode, OutputOptions } from "./cli-x6qr7bnd.js";
|
|
2
|
+
/**
|
|
3
|
+
* Detects output mode based on explicit format, environment, and options.
|
|
4
|
+
*
|
|
5
|
+
* Priority: explicit format > env var > default (human)
|
|
6
|
+
*
|
|
7
|
+
* Per CLI conventions (clig.dev), human output is the default.
|
|
8
|
+
* Machine-readable output requires explicit opt-in via --json flag
|
|
9
|
+
* or OUTFITTER_JSON=1 environment variable.
|
|
10
|
+
*/
|
|
11
|
+
declare function detectMode(format?: OutputMode): OutputMode;
|
|
12
|
+
/**
|
|
13
|
+
* Safe JSON stringify that handles circular references and undefined values.
|
|
14
|
+
* Wraps contracts' safeStringify with undefined -> null conversion for CLI JSON output.
|
|
15
|
+
*/
|
|
16
|
+
declare function cliStringify(value: unknown, pretty?: boolean): string;
|
|
17
|
+
/**
|
|
18
|
+
* Formats data for human-readable output.
|
|
19
|
+
*/
|
|
20
|
+
declare function formatHuman(data: unknown): string;
|
|
21
|
+
/**
|
|
22
|
+
* Gets the exit code for an error based on its category.
|
|
23
|
+
* Uses exitCodeMap from @outfitter/contracts for known categories.
|
|
24
|
+
*/
|
|
25
|
+
declare function getExitCode(error: Error): number;
|
|
26
|
+
/**
|
|
27
|
+
* Serializes an error to JSON format for CLI output.
|
|
28
|
+
* Handles both OutfitterError instances and plain Error objects.
|
|
29
|
+
*/
|
|
30
|
+
declare function serializeErrorToJson(error: Error): string;
|
|
31
|
+
/**
|
|
32
|
+
* Formats an error for human-readable output.
|
|
33
|
+
*/
|
|
34
|
+
declare function formatErrorHuman(error: Error): string;
|
|
35
|
+
type OutputSliceTruncation = Pick<NonNullable<OutputOptions["truncation"]>, "limit" | "offset">;
|
|
36
|
+
/**
|
|
37
|
+
* Applies array truncation (limit/offset) to output data.
|
|
38
|
+
*/
|
|
39
|
+
declare function applyOutputTruncation(data: unknown, truncation: OutputSliceTruncation | undefined): unknown;
|
|
40
|
+
/**
|
|
41
|
+
* Writes to a stream with proper backpressure handling.
|
|
42
|
+
* Returns a promise that resolves when the write is complete.
|
|
43
|
+
*/
|
|
44
|
+
declare function writeWithBackpressure(stream: NodeJS.WritableStream, data: string): Promise<void>;
|
|
45
|
+
export { detectMode, cliStringify, formatHuman, getExitCode, serializeErrorToJson, formatErrorHuman, applyOutputTruncation, writeWithBackpressure };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { CommandMetadata } from "./cli-xde45xcc.js";
|
|
2
|
+
/**
|
|
3
|
+
* Option metadata in the command tree.
|
|
4
|
+
*/
|
|
5
|
+
interface CommandTreeOption {
|
|
6
|
+
/** Commander flag string (e.g., "--limit <n>") */
|
|
7
|
+
readonly flags: string;
|
|
8
|
+
/** Option description */
|
|
9
|
+
readonly description: string;
|
|
10
|
+
/** Default value (absent when no default) */
|
|
11
|
+
readonly defaultValue?: unknown;
|
|
12
|
+
/** Whether the option is required */
|
|
13
|
+
readonly required?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* A node in the command tree representing a single command or subcommand.
|
|
17
|
+
*/
|
|
18
|
+
interface CommandTreeNode {
|
|
19
|
+
/** Command name */
|
|
20
|
+
readonly name: string;
|
|
21
|
+
/** Command description */
|
|
22
|
+
readonly description?: string;
|
|
23
|
+
/** Safety metadata signals (readOnly, idempotent) */
|
|
24
|
+
readonly metadata?: CommandMetadata;
|
|
25
|
+
/** Available options/flags */
|
|
26
|
+
readonly options?: readonly CommandTreeOption[];
|
|
27
|
+
/** Nested subcommands */
|
|
28
|
+
readonly subcommands?: readonly CommandTreeNode[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Full command tree for a CLI application.
|
|
32
|
+
*
|
|
33
|
+
* Used for self-documenting root command output in JSON mode.
|
|
34
|
+
*/
|
|
35
|
+
interface CommandTree {
|
|
36
|
+
/** CLI name */
|
|
37
|
+
readonly name: string;
|
|
38
|
+
/** CLI version */
|
|
39
|
+
readonly version: string;
|
|
40
|
+
/** CLI description */
|
|
41
|
+
readonly description?: string;
|
|
42
|
+
/** Top-level commands */
|
|
43
|
+
readonly commands: readonly CommandTreeNode[];
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* An edge in the action graph representing a relationship between commands.
|
|
47
|
+
*/
|
|
48
|
+
interface ActionGraphEdge {
|
|
49
|
+
/** Source command name */
|
|
50
|
+
readonly from: string;
|
|
51
|
+
/** Target command name */
|
|
52
|
+
readonly to: string;
|
|
53
|
+
/** Relationship description (if provided) */
|
|
54
|
+
readonly description?: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* An action graph built from `.relatedTo()` declarations on registered commands.
|
|
58
|
+
*
|
|
59
|
+
* Nodes are command names, edges are relationship declarations.
|
|
60
|
+
* Used for tier-4 hint generation — success hints include next-actions
|
|
61
|
+
* from graph neighbors, error hints include remediation paths.
|
|
62
|
+
*/
|
|
63
|
+
interface ActionGraph {
|
|
64
|
+
/** All registered command names */
|
|
65
|
+
readonly nodes: readonly string[];
|
|
66
|
+
/** Relationship edges between commands */
|
|
67
|
+
readonly edges: readonly ActionGraphEdge[];
|
|
68
|
+
/** Warnings for invalid references (e.g., unknown targets) */
|
|
69
|
+
readonly warnings?: readonly string[];
|
|
70
|
+
}
|
|
71
|
+
export { CommandTreeOption, CommandTreeNode, CommandTree, ActionGraphEdge, ActionGraph };
|