incur 0.4.0 → 0.4.2
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 +83 -22
- package/SKILL.md +6 -6
- package/dist/Cli.d.ts +46 -26
- package/dist/Cli.d.ts.map +1 -1
- package/dist/Cli.js +728 -441
- package/dist/Cli.js.map +1 -1
- package/dist/Completions.d.ts +4 -3
- package/dist/Completions.d.ts.map +1 -1
- package/dist/Completions.js +17 -10
- package/dist/Completions.js.map +1 -1
- package/dist/Fetch.d.ts.map +1 -1
- package/dist/Fetch.js +10 -9
- package/dist/Fetch.js.map +1 -1
- package/dist/Filter.js +0 -18
- package/dist/Filter.js.map +1 -1
- package/dist/Formatter.d.ts.map +1 -1
- package/dist/Formatter.js +6 -1
- package/dist/Formatter.js.map +1 -1
- package/dist/Help.d.ts +7 -1
- package/dist/Help.d.ts.map +1 -1
- package/dist/Help.js +44 -27
- package/dist/Help.js.map +1 -1
- package/dist/Mcp.d.ts +37 -5
- package/dist/Mcp.d.ts.map +1 -1
- package/dist/Mcp.js +71 -72
- package/dist/Mcp.js.map +1 -1
- package/dist/Openapi.d.ts.map +1 -1
- package/dist/Openapi.js +22 -14
- package/dist/Openapi.js.map +1 -1
- package/dist/Parser.d.ts +4 -0
- package/dist/Parser.d.ts.map +1 -1
- package/dist/Parser.js +70 -38
- package/dist/Parser.js.map +1 -1
- package/dist/Schema.d.ts +5 -1
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +13 -2
- package/dist/Schema.js.map +1 -1
- package/dist/Skill.d.ts +2 -1
- package/dist/Skill.d.ts.map +1 -1
- package/dist/Skill.js +33 -19
- package/dist/Skill.js.map +1 -1
- package/dist/Skillgen.js +1 -1
- package/dist/Skillgen.js.map +1 -1
- package/dist/SyncSkills.d.ts +48 -0
- package/dist/SyncSkills.d.ts.map +1 -1
- package/dist/SyncSkills.js +108 -10
- package/dist/SyncSkills.js.map +1 -1
- package/dist/Typegen.js +4 -2
- package/dist/Typegen.js.map +1 -1
- package/dist/bin.d.ts +2 -1
- package/dist/bin.d.ts.map +1 -1
- package/dist/bin.js +17 -2
- package/dist/bin.js.map +1 -1
- package/dist/internal/command.d.ts +170 -0
- package/dist/internal/command.d.ts.map +1 -0
- package/dist/internal/command.js +292 -0
- package/dist/internal/command.js.map +1 -0
- package/dist/internal/configSchema.d.ts +8 -0
- package/dist/internal/configSchema.d.ts.map +1 -0
- package/dist/internal/configSchema.js +57 -0
- package/dist/internal/configSchema.js.map +1 -0
- package/dist/internal/dereference.d.ts +12 -0
- package/dist/internal/dereference.d.ts.map +1 -0
- package/dist/internal/dereference.js +71 -0
- package/dist/internal/dereference.js.map +1 -0
- package/dist/internal/helpers.d.ts +9 -0
- package/dist/internal/helpers.d.ts.map +1 -0
- package/dist/internal/helpers.js +54 -0
- package/dist/internal/helpers.js.map +1 -0
- package/dist/middleware.d.ts +6 -8
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +1 -1
- package/dist/middleware.js.map +1 -1
- package/examples/npm/.npmrc.json +21 -0
- package/examples/npm/config.schema.json +134 -0
- package/package.json +6 -29
- package/src/Cli.test-d.ts +44 -33
- package/src/Cli.test.ts +1231 -101
- package/src/Cli.ts +877 -569
- package/src/Completions.test.ts +136 -12
- package/src/Completions.ts +18 -13
- package/src/Fetch.test.ts +21 -0
- package/src/Fetch.ts +8 -10
- package/src/Filter.ts +0 -17
- package/src/Formatter.test.ts +15 -2
- package/src/Formatter.ts +5 -1
- package/src/Help.test.ts +184 -20
- package/src/Help.ts +52 -28
- package/src/Mcp.test.ts +159 -0
- package/src/Mcp.ts +108 -86
- package/src/Openapi.test.ts +17 -5
- package/src/Openapi.ts +21 -15
- package/src/Parser.test-d.ts +22 -0
- package/src/Parser.test.ts +89 -0
- package/src/Parser.ts +87 -36
- package/src/Schema.test.ts +29 -0
- package/src/Schema.ts +12 -2
- package/src/Skill.test.ts +87 -6
- package/src/Skill.ts +38 -21
- package/src/Skillgen.ts +1 -1
- package/src/SyncMcp.test.ts +6 -8
- package/src/SyncSkills.test.ts +146 -3
- package/src/SyncSkills.ts +191 -10
- package/src/Typegen.test.ts +15 -0
- package/src/Typegen.ts +4 -2
- package/src/bin.ts +21 -2
- package/src/e2e.test.ts +188 -98
- package/src/internal/command.ts +449 -0
- package/src/internal/configSchema.test.ts +193 -0
- package/src/internal/configSchema.ts +66 -0
- package/src/internal/dereference.test.ts +695 -0
- package/src/internal/dereference.ts +75 -0
- package/src/internal/helpers.test.ts +75 -0
- package/src/internal/helpers.ts +59 -0
- package/src/middleware.ts +5 -12
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { FieldError } from '../Errors.js';
|
|
3
|
+
import type { Handler as MiddlewareHandler } from '../middleware.js';
|
|
4
|
+
/** @internal CTA block for command output. */
|
|
5
|
+
export type CtaBlock = {
|
|
6
|
+
commands: unknown[];
|
|
7
|
+
description?: string | undefined;
|
|
8
|
+
};
|
|
9
|
+
/** @internal Unified command execution used by CLI, HTTP, and MCP transports. */
|
|
10
|
+
export declare function execute(command: any, options: execute.Options): Promise<execute.Result>;
|
|
11
|
+
export declare namespace execute {
|
|
12
|
+
/** Options for the unified execute function. */
|
|
13
|
+
type Options = {
|
|
14
|
+
/** Whether the consumer is an agent. */
|
|
15
|
+
agent: boolean;
|
|
16
|
+
/** Raw positional tokens (already separated from flags). For HTTP/MCP, pass `[]`. */
|
|
17
|
+
argv: string[];
|
|
18
|
+
/** Default option values from config file. */
|
|
19
|
+
defaults?: Record<string, unknown> | undefined;
|
|
20
|
+
/** The resolved binary name the user invoked (e.g. an alias). Falls back to `name`. */
|
|
21
|
+
displayName?: string | undefined;
|
|
22
|
+
/** CLI-level env schema. */
|
|
23
|
+
env?: z.ZodObject<any> | undefined;
|
|
24
|
+
/** Source for environment variables. Defaults to `process.env`. */
|
|
25
|
+
envSource?: Record<string, string | undefined> | undefined;
|
|
26
|
+
/** The resolved output format. */
|
|
27
|
+
format: string;
|
|
28
|
+
/** Whether the format was explicitly requested. */
|
|
29
|
+
formatExplicit: boolean;
|
|
30
|
+
/** Raw parsed options (from query params, JSON body, or MCP params). For CLI, pass `{}`. */
|
|
31
|
+
inputOptions: Record<string, unknown>;
|
|
32
|
+
/** Middleware handlers (root + group + command, already collected). */
|
|
33
|
+
middlewares?: MiddlewareHandler[] | undefined;
|
|
34
|
+
/** The CLI name. */
|
|
35
|
+
name: string;
|
|
36
|
+
/**
|
|
37
|
+
* How to parse input:
|
|
38
|
+
* - `'argv'` (default): parse both args and options from argv tokens (CLI mode)
|
|
39
|
+
* - `'split'`: args from argv, options from inputOptions (HTTP mode)
|
|
40
|
+
* - `'flat'`: all params from inputOptions, split by schema shapes (MCP mode)
|
|
41
|
+
*/
|
|
42
|
+
parseMode?: 'argv' | 'split' | 'flat' | undefined;
|
|
43
|
+
/** The resolved command path. */
|
|
44
|
+
path: string;
|
|
45
|
+
/** Vars schema for middleware variables. */
|
|
46
|
+
vars?: z.ZodObject<any> | undefined;
|
|
47
|
+
/** CLI version string. */
|
|
48
|
+
version: string | undefined;
|
|
49
|
+
};
|
|
50
|
+
/** Result of executing a command. */
|
|
51
|
+
type Result = {
|
|
52
|
+
ok: true;
|
|
53
|
+
data: unknown;
|
|
54
|
+
cta?: CtaBlock | undefined;
|
|
55
|
+
} | {
|
|
56
|
+
ok: false;
|
|
57
|
+
error: {
|
|
58
|
+
code: string;
|
|
59
|
+
message: string;
|
|
60
|
+
retryable?: boolean | undefined;
|
|
61
|
+
fieldErrors?: FieldError[] | undefined;
|
|
62
|
+
};
|
|
63
|
+
cta?: CtaBlock | undefined;
|
|
64
|
+
exitCode?: number | undefined;
|
|
65
|
+
} | {
|
|
66
|
+
stream: AsyncGenerator<unknown, unknown, unknown>;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/** Common metadata shared by command definitions and built-in commands. */
|
|
70
|
+
export type CommandMeta<options extends z.ZodObject<any> | undefined = undefined> = {
|
|
71
|
+
/** Map of option names to single-char aliases. */
|
|
72
|
+
alias?: options extends z.ZodObject<any> ? Partial<Record<keyof z.output<options>, string>> : Record<string, string> | undefined;
|
|
73
|
+
/** A short description of what the command does. */
|
|
74
|
+
description?: string | undefined;
|
|
75
|
+
/** Zod schema for named options/flags. */
|
|
76
|
+
options?: options | undefined;
|
|
77
|
+
};
|
|
78
|
+
/** Supported shell names for completions. */
|
|
79
|
+
export declare const shells: readonly ["bash", "fish", "nushell", "zsh"];
|
|
80
|
+
/** A supported shell name. */
|
|
81
|
+
export type Shell = (typeof shells)[number];
|
|
82
|
+
/** Built-in command metadata shared by help, completions, and handler logic. */
|
|
83
|
+
export declare const builtinCommands: ({
|
|
84
|
+
name: string;
|
|
85
|
+
description: string;
|
|
86
|
+
args: z.ZodObject<{
|
|
87
|
+
shell: z.ZodEnum<{
|
|
88
|
+
bash: "bash";
|
|
89
|
+
fish: "fish";
|
|
90
|
+
nushell: "nushell";
|
|
91
|
+
zsh: "zsh";
|
|
92
|
+
}>;
|
|
93
|
+
}, z.core.$strip>;
|
|
94
|
+
hint(name: string): string;
|
|
95
|
+
subcommands?: undefined;
|
|
96
|
+
aliases?: undefined;
|
|
97
|
+
} | {
|
|
98
|
+
name: string;
|
|
99
|
+
description: string;
|
|
100
|
+
subcommands: (CommandMeta<z.ZodObject<{
|
|
101
|
+
agent: z.ZodOptional<z.ZodString>;
|
|
102
|
+
command: z.ZodOptional<z.ZodString>;
|
|
103
|
+
noGlobal: z.ZodOptional<z.ZodBoolean>;
|
|
104
|
+
}, z.core.$strip>> & {
|
|
105
|
+
name: string;
|
|
106
|
+
})[];
|
|
107
|
+
args?: undefined;
|
|
108
|
+
hint?: undefined;
|
|
109
|
+
aliases?: undefined;
|
|
110
|
+
} | {
|
|
111
|
+
name: string;
|
|
112
|
+
aliases: string[];
|
|
113
|
+
description: string;
|
|
114
|
+
subcommands: ((CommandMeta<z.ZodObject<{
|
|
115
|
+
depth: z.ZodOptional<z.ZodNumber>;
|
|
116
|
+
noGlobal: z.ZodOptional<z.ZodBoolean>;
|
|
117
|
+
}, z.core.$strip>> & {
|
|
118
|
+
name: string;
|
|
119
|
+
}) | (CommandMeta<z.ZodObject<any, z.core.$strip>> & {
|
|
120
|
+
name: string;
|
|
121
|
+
}))[];
|
|
122
|
+
args?: undefined;
|
|
123
|
+
hint?: undefined;
|
|
124
|
+
})[];
|
|
125
|
+
/** @internal Finds a builtin command by its name or alias. */
|
|
126
|
+
export declare function findBuiltin(token: string): {
|
|
127
|
+
name: string;
|
|
128
|
+
description: string;
|
|
129
|
+
args: z.ZodObject<{
|
|
130
|
+
shell: z.ZodEnum<{
|
|
131
|
+
bash: "bash";
|
|
132
|
+
fish: "fish";
|
|
133
|
+
nushell: "nushell";
|
|
134
|
+
zsh: "zsh";
|
|
135
|
+
}>;
|
|
136
|
+
}, z.core.$strip>;
|
|
137
|
+
hint(name: string): string;
|
|
138
|
+
subcommands?: undefined;
|
|
139
|
+
aliases?: undefined;
|
|
140
|
+
} | {
|
|
141
|
+
name: string;
|
|
142
|
+
description: string;
|
|
143
|
+
subcommands: (CommandMeta<z.ZodObject<{
|
|
144
|
+
agent: z.ZodOptional<z.ZodString>;
|
|
145
|
+
command: z.ZodOptional<z.ZodString>;
|
|
146
|
+
noGlobal: z.ZodOptional<z.ZodBoolean>;
|
|
147
|
+
}, z.core.$strip>> & {
|
|
148
|
+
name: string;
|
|
149
|
+
})[];
|
|
150
|
+
args?: undefined;
|
|
151
|
+
hint?: undefined;
|
|
152
|
+
aliases?: undefined;
|
|
153
|
+
} | {
|
|
154
|
+
name: string;
|
|
155
|
+
aliases: string[];
|
|
156
|
+
description: string;
|
|
157
|
+
subcommands: ((CommandMeta<z.ZodObject<{
|
|
158
|
+
depth: z.ZodOptional<z.ZodNumber>;
|
|
159
|
+
noGlobal: z.ZodOptional<z.ZodBoolean>;
|
|
160
|
+
}, z.core.$strip>> & {
|
|
161
|
+
name: string;
|
|
162
|
+
}) | (CommandMeta<z.ZodObject<any, z.core.$strip>> & {
|
|
163
|
+
name: string;
|
|
164
|
+
}))[];
|
|
165
|
+
args?: undefined;
|
|
166
|
+
hint?: undefined;
|
|
167
|
+
} | undefined;
|
|
168
|
+
/** @internal Checks if a token matches a builtin command by name or alias. */
|
|
169
|
+
export declare function isBuiltin(token: string): boolean;
|
|
170
|
+
//# sourceMappingURL=command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/internal/command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { IncurError, ValidationError } from '../Errors.js';
|
|
3
|
+
import * as Parser from '../Parser.js';
|
|
4
|
+
/** @internal Sentinel symbol for `ok()` and `error()` return values. */
|
|
5
|
+
const sentinel = Symbol.for('incur.sentinel');
|
|
6
|
+
/** @internal Unified command execution used by CLI, HTTP, and MCP transports. */
|
|
7
|
+
export async function execute(command, options) {
|
|
8
|
+
const { argv, inputOptions, agent, format, formatExplicit, name, path, version, envSource = process.env, env: envSchema, vars: varsSchema, middlewares = [], } = options;
|
|
9
|
+
const displayName = options.displayName ?? name;
|
|
10
|
+
const parseMode = options.parseMode ?? 'argv';
|
|
11
|
+
const varsMap = varsSchema ? varsSchema.parse({}) : {};
|
|
12
|
+
let result;
|
|
13
|
+
// For streaming with middleware: runCommand suspends on streamConsumed so middleware "after"
|
|
14
|
+
// runs after the stream is consumed. The wrapped generator resolves it in its finally block.
|
|
15
|
+
// resultReady signals that result has been set (for streams, before the chain finishes).
|
|
16
|
+
let streamConsumed;
|
|
17
|
+
let resolveStreamConsumed;
|
|
18
|
+
let resolveResultReady;
|
|
19
|
+
const resultReady = new Promise((r) => {
|
|
20
|
+
resolveResultReady = r;
|
|
21
|
+
});
|
|
22
|
+
const runCommand = async () => {
|
|
23
|
+
// Parse args and options
|
|
24
|
+
let args;
|
|
25
|
+
let parsedOptions;
|
|
26
|
+
if (parseMode === 'argv') {
|
|
27
|
+
// CLI mode: parse both args and options from argv tokens
|
|
28
|
+
const parsed = Parser.parse(argv, {
|
|
29
|
+
alias: command.alias,
|
|
30
|
+
args: command.args,
|
|
31
|
+
defaults: options.defaults,
|
|
32
|
+
options: command.options,
|
|
33
|
+
});
|
|
34
|
+
args = parsed.args;
|
|
35
|
+
parsedOptions = parsed.options;
|
|
36
|
+
}
|
|
37
|
+
else if (parseMode === 'split') {
|
|
38
|
+
// HTTP mode: positional args from URL path segments, options from body/query
|
|
39
|
+
const parsed = Parser.parse(argv, { args: command.args });
|
|
40
|
+
args = parsed.args;
|
|
41
|
+
parsedOptions = command.options ? command.options.parse(inputOptions) : {};
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
// MCP mode: all params come from inputOptions, split into args vs options
|
|
45
|
+
const split = splitParams(inputOptions, command);
|
|
46
|
+
args = command.args ? command.args.parse(split.args) : {};
|
|
47
|
+
parsedOptions = command.options ? command.options.parse(split.options) : {};
|
|
48
|
+
}
|
|
49
|
+
// Parse env
|
|
50
|
+
const commandEnv = command.env ? Parser.parseEnv(command.env, envSource) : {};
|
|
51
|
+
// Build sentinel helpers
|
|
52
|
+
const okFn = (data, meta = {}) => ({ [sentinel]: 'ok', data, cta: meta.cta });
|
|
53
|
+
const errorFn = (opts) => ({ [sentinel]: 'error', ...opts });
|
|
54
|
+
const raw = command.run({
|
|
55
|
+
agent,
|
|
56
|
+
args,
|
|
57
|
+
displayName,
|
|
58
|
+
env: commandEnv,
|
|
59
|
+
error: errorFn,
|
|
60
|
+
format,
|
|
61
|
+
formatExplicit,
|
|
62
|
+
name,
|
|
63
|
+
ok: okFn,
|
|
64
|
+
options: parsedOptions,
|
|
65
|
+
var: varsMap,
|
|
66
|
+
version,
|
|
67
|
+
});
|
|
68
|
+
// Streaming: wrap the generator so middleware "after" runs after consumption.
|
|
69
|
+
// When middleware is active, runCommand suspends until the stream is fully consumed,
|
|
70
|
+
// keeping the middleware chain alive around the stream's lifetime.
|
|
71
|
+
if (isAsyncGenerator(raw)) {
|
|
72
|
+
if (middlewares.length > 0) {
|
|
73
|
+
streamConsumed = new Promise((r) => {
|
|
74
|
+
resolveStreamConsumed = r;
|
|
75
|
+
});
|
|
76
|
+
async function* wrapped() {
|
|
77
|
+
try {
|
|
78
|
+
yield* raw;
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
resolveStreamConsumed();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
result = { stream: wrapped() };
|
|
85
|
+
resolveResultReady();
|
|
86
|
+
await streamConsumed;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
result = { stream: raw };
|
|
90
|
+
}
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const awaited = await raw;
|
|
94
|
+
if (isSentinel(awaited)) {
|
|
95
|
+
if (awaited[sentinel] === 'ok') {
|
|
96
|
+
const ok = awaited;
|
|
97
|
+
result = { ok: true, data: ok.data, ...(ok.cta ? { cta: ok.cta } : undefined) };
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
const err = awaited;
|
|
101
|
+
result = {
|
|
102
|
+
ok: false,
|
|
103
|
+
error: {
|
|
104
|
+
code: err.code,
|
|
105
|
+
message: err.message,
|
|
106
|
+
...(err.retryable !== undefined ? { retryable: err.retryable } : undefined),
|
|
107
|
+
},
|
|
108
|
+
...(err.cta ? { cta: err.cta } : undefined),
|
|
109
|
+
...(err.exitCode !== undefined ? { exitCode: err.exitCode } : undefined),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
result = { ok: true, data: awaited };
|
|
115
|
+
};
|
|
116
|
+
try {
|
|
117
|
+
// Parse CLI-level env
|
|
118
|
+
const cliEnv = envSchema ? Parser.parseEnv(envSchema, envSource) : {};
|
|
119
|
+
if (middlewares.length > 0) {
|
|
120
|
+
const errorFn = (opts) => {
|
|
121
|
+
// Side-effect: set result directly (handles both `return c.error()` and bare `c.error()`)
|
|
122
|
+
result = {
|
|
123
|
+
ok: false,
|
|
124
|
+
error: {
|
|
125
|
+
code: opts.code,
|
|
126
|
+
message: opts.message,
|
|
127
|
+
...(opts.retryable !== undefined ? { retryable: opts.retryable } : undefined),
|
|
128
|
+
},
|
|
129
|
+
...(opts.cta ? { cta: opts.cta } : undefined),
|
|
130
|
+
...(opts.exitCode !== undefined ? { exitCode: opts.exitCode } : undefined),
|
|
131
|
+
};
|
|
132
|
+
return undefined;
|
|
133
|
+
};
|
|
134
|
+
const mwCtx = {
|
|
135
|
+
agent,
|
|
136
|
+
command: path,
|
|
137
|
+
displayName,
|
|
138
|
+
env: cliEnv,
|
|
139
|
+
error: errorFn,
|
|
140
|
+
format: format,
|
|
141
|
+
formatExplicit,
|
|
142
|
+
name,
|
|
143
|
+
set(key, value) {
|
|
144
|
+
varsMap[key] = value;
|
|
145
|
+
},
|
|
146
|
+
var: varsMap,
|
|
147
|
+
version,
|
|
148
|
+
};
|
|
149
|
+
const composed = middlewares.reduceRight((next, mw) => async () => {
|
|
150
|
+
await mw(mwCtx, next);
|
|
151
|
+
}, runCommand);
|
|
152
|
+
// Start the chain and race against resultReady. For streams with middleware,
|
|
153
|
+
// runCommand suspends on streamConsumed (keeping middleware "after" deferred)
|
|
154
|
+
// but signals resultReady so we can return the stream immediately. The transport
|
|
155
|
+
// consumes the stream, which resolves streamConsumed, letting middleware "after" run.
|
|
156
|
+
const chainPromise = composed();
|
|
157
|
+
await Promise.race([chainPromise, resultReady]);
|
|
158
|
+
if (streamConsumed)
|
|
159
|
+
return result;
|
|
160
|
+
await chainPromise;
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
await runCommand();
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
if (error instanceof ValidationError)
|
|
168
|
+
return {
|
|
169
|
+
ok: false,
|
|
170
|
+
error: {
|
|
171
|
+
code: 'VALIDATION_ERROR',
|
|
172
|
+
message: error.message,
|
|
173
|
+
fieldErrors: error.fieldErrors,
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
return {
|
|
177
|
+
ok: false,
|
|
178
|
+
error: {
|
|
179
|
+
code: error instanceof IncurError ? error.code : 'UNKNOWN',
|
|
180
|
+
message: error instanceof Error ? error.message : String(error),
|
|
181
|
+
...(error instanceof IncurError ? { retryable: error.retryable } : undefined),
|
|
182
|
+
},
|
|
183
|
+
...(error instanceof IncurError && error.exitCode !== undefined
|
|
184
|
+
? { exitCode: error.exitCode }
|
|
185
|
+
: undefined),
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
return result ?? { ok: true, data: undefined };
|
|
189
|
+
}
|
|
190
|
+
/** @internal Splits flat params into args vs options using schema shapes. */
|
|
191
|
+
function splitParams(params, command) {
|
|
192
|
+
const argKeys = new Set(command.args ? Object.keys(command.args.shape) : []);
|
|
193
|
+
const a = {};
|
|
194
|
+
const o = {};
|
|
195
|
+
for (const [key, value] of Object.entries(params))
|
|
196
|
+
if (argKeys.has(key))
|
|
197
|
+
a[key] = value;
|
|
198
|
+
else
|
|
199
|
+
o[key] = value;
|
|
200
|
+
return { args: a, options: o };
|
|
201
|
+
}
|
|
202
|
+
/** @internal Type guard for sentinel results. */
|
|
203
|
+
function isSentinel(value) {
|
|
204
|
+
return typeof value === 'object' && value !== null && sentinel in value;
|
|
205
|
+
}
|
|
206
|
+
/** @internal Type guard for async generators. */
|
|
207
|
+
function isAsyncGenerator(value) {
|
|
208
|
+
return (typeof value === 'object' &&
|
|
209
|
+
value !== null &&
|
|
210
|
+
Symbol.asyncIterator in value &&
|
|
211
|
+
typeof value.next === 'function');
|
|
212
|
+
}
|
|
213
|
+
/** @internal Creates a builtin subcommand with typesafe alias inference. */
|
|
214
|
+
function subcommand(def) {
|
|
215
|
+
return def;
|
|
216
|
+
}
|
|
217
|
+
/** Supported shell names for completions. */
|
|
218
|
+
export const shells = ['bash', 'fish', 'nushell', 'zsh'];
|
|
219
|
+
/** Built-in command metadata shared by help, completions, and handler logic. */
|
|
220
|
+
export const builtinCommands = [
|
|
221
|
+
{
|
|
222
|
+
name: 'completions',
|
|
223
|
+
description: 'Generate shell completion script',
|
|
224
|
+
args: z.object({
|
|
225
|
+
shell: z.enum(shells).describe('Shell to generate completions for'),
|
|
226
|
+
}),
|
|
227
|
+
hint(name) {
|
|
228
|
+
const rows = [
|
|
229
|
+
['bash', `eval "$(${name} completions bash)"`, '# add to ~/.bashrc'],
|
|
230
|
+
['fish', `${name} completions fish | source`, '# add to ~/.config/fish/config.fish'],
|
|
231
|
+
['nushell', `see \`${name} completions nushell\``, '# add to config.nu'],
|
|
232
|
+
['zsh', `eval "$(${name} completions zsh)"`, '# add to ~/.zshrc'],
|
|
233
|
+
];
|
|
234
|
+
const shellW = Math.max(...rows.map((r) => r[0].length));
|
|
235
|
+
const cmdW = Math.max(...rows.map((r) => r[1].length));
|
|
236
|
+
return ('Setup:\n' +
|
|
237
|
+
rows
|
|
238
|
+
.map(([s, cmd, comment]) => ` ${s.padEnd(shellW)} ${cmd.padEnd(cmdW)} ${comment}`)
|
|
239
|
+
.join('\n'));
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
name: 'mcp',
|
|
244
|
+
description: 'Register as MCP server',
|
|
245
|
+
subcommands: [
|
|
246
|
+
subcommand({
|
|
247
|
+
name: 'add',
|
|
248
|
+
description: 'Register as MCP server',
|
|
249
|
+
alias: { command: 'c' },
|
|
250
|
+
options: z.object({
|
|
251
|
+
agent: z
|
|
252
|
+
.string()
|
|
253
|
+
.optional()
|
|
254
|
+
.describe('Target a specific agent (e.g. claude-code, cursor)'),
|
|
255
|
+
command: z
|
|
256
|
+
.string()
|
|
257
|
+
.optional()
|
|
258
|
+
.describe('Override the command agents will run (e.g. "pnpm my-cli --mcp")'),
|
|
259
|
+
noGlobal: z.boolean().optional().describe('Install to project instead of globally'),
|
|
260
|
+
}),
|
|
261
|
+
}),
|
|
262
|
+
],
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
name: 'skills',
|
|
266
|
+
aliases: ['skill'],
|
|
267
|
+
description: 'Sync skill files to agents',
|
|
268
|
+
subcommands: [
|
|
269
|
+
subcommand({
|
|
270
|
+
name: 'add',
|
|
271
|
+
description: 'Sync skill files to agents',
|
|
272
|
+
options: z.object({
|
|
273
|
+
depth: z.number().optional().describe('Grouping depth for skill files (default: 1)'),
|
|
274
|
+
noGlobal: z.boolean().optional().describe('Install to project instead of globally'),
|
|
275
|
+
}),
|
|
276
|
+
}),
|
|
277
|
+
subcommand({
|
|
278
|
+
name: 'list',
|
|
279
|
+
description: 'List skills',
|
|
280
|
+
}),
|
|
281
|
+
],
|
|
282
|
+
},
|
|
283
|
+
];
|
|
284
|
+
/** @internal Finds a builtin command by its name or alias. */
|
|
285
|
+
export function findBuiltin(token) {
|
|
286
|
+
return builtinCommands.find((b) => b.name === token || b.aliases?.includes(token));
|
|
287
|
+
}
|
|
288
|
+
/** @internal Checks if a token matches a builtin command by name or alias. */
|
|
289
|
+
export function isBuiltin(token) {
|
|
290
|
+
return builtinCommands.some((b) => b.name === token || b.aliases?.includes(token));
|
|
291
|
+
}
|
|
292
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/internal/command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as Cli from '../Cli.js';
|
|
2
|
+
/** Returns `true` if the CLI has `config` enabled on `Cli.create()`. */
|
|
3
|
+
export declare function hasConfig(cli: Cli.Cli): boolean;
|
|
4
|
+
/** Imports a CLI from `input` (must `export default` a `Cli`), generates the JSON Schema, and writes it to `output`. */
|
|
5
|
+
export declare function generate(input: string, output: string): Promise<void>;
|
|
6
|
+
/** Generates a JSON Schema describing the config file structure for a CLI. */
|
|
7
|
+
export declare function fromCli(cli: Cli.Cli): Record<string, unknown>;
|
|
8
|
+
//# sourceMappingURL=configSchema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configSchema.d.ts","sourceRoot":"","sources":["../../src/internal/configSchema.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,GAAG,MAAM,WAAW,CAAA;AAIhC,wEAAwE;AACxE,wBAAgB,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,GAAG,OAAO,CAE/C;AAED,wHAAwH;AACxH,wBAAsB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG3E;AAED,8EAA8E;AAC9E,wBAAgB,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAU7D"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import * as Cli from '../Cli.js';
|
|
3
|
+
import * as Schema from '../Schema.js';
|
|
4
|
+
import { importCli } from './utils.js';
|
|
5
|
+
/** Returns `true` if the CLI has `config` enabled on `Cli.create()`. */
|
|
6
|
+
export function hasConfig(cli) {
|
|
7
|
+
return Cli.toConfigEnabled.get(cli) === true;
|
|
8
|
+
}
|
|
9
|
+
/** Imports a CLI from `input` (must `export default` a `Cli`), generates the JSON Schema, and writes it to `output`. */
|
|
10
|
+
export async function generate(input, output) {
|
|
11
|
+
const cli = await importCli(input);
|
|
12
|
+
await fs.writeFile(output, JSON.stringify(fromCli(cli), null, 2) + '\n');
|
|
13
|
+
}
|
|
14
|
+
/** Generates a JSON Schema describing the config file structure for a CLI. */
|
|
15
|
+
export function fromCli(cli) {
|
|
16
|
+
const commands = Cli.toCommands.get(cli);
|
|
17
|
+
if (!commands)
|
|
18
|
+
return { type: 'object' };
|
|
19
|
+
const rootOptions = Cli.toRootOptions.get(cli);
|
|
20
|
+
const node = buildNode(commands, rootOptions);
|
|
21
|
+
const properties = (node.properties ?? {});
|
|
22
|
+
properties.$schema = { type: 'string' };
|
|
23
|
+
node.properties = properties;
|
|
24
|
+
return node;
|
|
25
|
+
}
|
|
26
|
+
/** Builds a JSON Schema node for a command level. */
|
|
27
|
+
function buildNode(commands, options) {
|
|
28
|
+
const properties = {};
|
|
29
|
+
// Add `options` property from the options schema
|
|
30
|
+
if (options) {
|
|
31
|
+
const optSchema = Schema.toJsonSchema(options);
|
|
32
|
+
const props = optSchema.properties;
|
|
33
|
+
if (props && Object.keys(props).length > 0)
|
|
34
|
+
properties.options = { type: 'object', additionalProperties: false, properties: props };
|
|
35
|
+
}
|
|
36
|
+
// Add `commands` property with subcommand namespaces
|
|
37
|
+
const commandProps = {};
|
|
38
|
+
for (const [name, entry] of commands) {
|
|
39
|
+
if ('_group' in entry && entry._group) {
|
|
40
|
+
commandProps[name] = buildNode(entry.commands, undefined);
|
|
41
|
+
}
|
|
42
|
+
else if (!('_fetch' in entry)) {
|
|
43
|
+
const cmd = entry;
|
|
44
|
+
commandProps[name] = buildNode(new Map(), cmd.options);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (Object.keys(commandProps).length > 0)
|
|
48
|
+
properties.commands = { type: 'object', additionalProperties: false, properties: commandProps };
|
|
49
|
+
const node = {
|
|
50
|
+
type: 'object',
|
|
51
|
+
additionalProperties: false,
|
|
52
|
+
};
|
|
53
|
+
if (Object.keys(properties).length > 0)
|
|
54
|
+
node.properties = properties;
|
|
55
|
+
return node;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=configSchema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configSchema.js","sourceRoot":"","sources":["../../src/internal/configSchema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dereferences all local `$ref` pointers in a JSON object (e.g. `{"$ref": "#/components/schemas/User"}`),
|
|
3
|
+
* replacing them inline with the resolved values. Only handles local (`#/...`) references.
|
|
4
|
+
*
|
|
5
|
+
* Handles circular references by caching a mutable placeholder before recursing.
|
|
6
|
+
*
|
|
7
|
+
* Minimal reimplementation of the dereferencing behavior from `@apidevtools/json-schema-ref-parser`
|
|
8
|
+
* (https://github.com/APIDevTools/json-schema-ref-parser). Only supports in-memory, local-pointer
|
|
9
|
+
* resolution — no file/URL resolution, no `$id` scoping.
|
|
10
|
+
*/
|
|
11
|
+
export declare function dereference<value>(root: value): value;
|
|
12
|
+
//# sourceMappingURL=dereference.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dereference.d.ts","sourceRoot":"","sources":["../../src/internal/dereference.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,GAAG,KAAK,CAGrD"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dereferences all local `$ref` pointers in a JSON object (e.g. `{"$ref": "#/components/schemas/User"}`),
|
|
3
|
+
* replacing them inline with the resolved values. Only handles local (`#/...`) references.
|
|
4
|
+
*
|
|
5
|
+
* Handles circular references by caching a mutable placeholder before recursing.
|
|
6
|
+
*
|
|
7
|
+
* Minimal reimplementation of the dereferencing behavior from `@apidevtools/json-schema-ref-parser`
|
|
8
|
+
* (https://github.com/APIDevTools/json-schema-ref-parser). Only supports in-memory, local-pointer
|
|
9
|
+
* resolution — no file/URL resolution, no `$id` scoping.
|
|
10
|
+
*/
|
|
11
|
+
export function dereference(root) {
|
|
12
|
+
const cache = new Map();
|
|
13
|
+
return walk(root, root, cache);
|
|
14
|
+
}
|
|
15
|
+
function walk(node, root, cache) {
|
|
16
|
+
if (Array.isArray(node))
|
|
17
|
+
return node.map((item) => walk(item, root, cache));
|
|
18
|
+
if (typeof node !== 'object' || node === null)
|
|
19
|
+
return node;
|
|
20
|
+
const obj = node;
|
|
21
|
+
// Resolve $ref pointer
|
|
22
|
+
if (typeof obj.$ref === 'string' && obj.$ref.startsWith('#')) {
|
|
23
|
+
const ref = obj.$ref;
|
|
24
|
+
if (cache.has(ref))
|
|
25
|
+
return cache.get(ref);
|
|
26
|
+
const resolved = resolvePointer(root, ref);
|
|
27
|
+
// Non-object targets (primitives, arrays) can't be circular — resolve directly
|
|
28
|
+
if (typeof resolved !== 'object' || resolved === null || Array.isArray(resolved)) {
|
|
29
|
+
const dereferenced = walk(resolved, root, cache);
|
|
30
|
+
cache.set(ref, dereferenced);
|
|
31
|
+
return dereferenced;
|
|
32
|
+
}
|
|
33
|
+
// Use a mutable placeholder so circular refs resolve to the same object.
|
|
34
|
+
// If the walked result is not a plain object (e.g. chained ref to primitive/array),
|
|
35
|
+
// skip the placeholder and cache directly.
|
|
36
|
+
const placeholder = {};
|
|
37
|
+
cache.set(ref, placeholder);
|
|
38
|
+
const dereferenced = walk(resolved, root, cache);
|
|
39
|
+
if (typeof dereferenced !== 'object' || dereferenced === null || Array.isArray(dereferenced)) {
|
|
40
|
+
cache.set(ref, dereferenced);
|
|
41
|
+
return dereferenced;
|
|
42
|
+
}
|
|
43
|
+
Object.assign(placeholder, dereferenced);
|
|
44
|
+
return placeholder;
|
|
45
|
+
}
|
|
46
|
+
const result = {};
|
|
47
|
+
for (const key of Object.keys(obj))
|
|
48
|
+
result[key] = walk(obj[key], root, cache);
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
/** Resolves a JSON Pointer (e.g. `#/components/schemas/User`) against a root object. */
|
|
52
|
+
function resolvePointer(root, pointer) {
|
|
53
|
+
// "#" or "#/" → root
|
|
54
|
+
const fragment = pointer.slice(1);
|
|
55
|
+
if (fragment === '' || fragment === '/')
|
|
56
|
+
return root;
|
|
57
|
+
const parts = fragment
|
|
58
|
+
.slice(1)
|
|
59
|
+
.split('/')
|
|
60
|
+
.map((p) => p.replace(/~1/g, '/').replace(/~0/g, '~'));
|
|
61
|
+
let current = root;
|
|
62
|
+
for (const part of parts) {
|
|
63
|
+
if (typeof current !== 'object' || current === null)
|
|
64
|
+
throw new Error(`Cannot resolve $ref "${pointer}": path segment "${part}" not found`);
|
|
65
|
+
current = current[part];
|
|
66
|
+
if (current === undefined)
|
|
67
|
+
throw new Error(`Cannot resolve $ref "${pointer}": "${part}" not found`);
|
|
68
|
+
}
|
|
69
|
+
return current;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=dereference.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dereference.js","sourceRoot":"","sources":["../../src/internal/dereference.ts"],"names":[],"mappings":"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"}
|