@runa-cmd/core 0.1.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.
Files changed (71) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +351 -0
  3. package/dist/cli.d.ts +12 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +413 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/command.d.ts +20 -0
  8. package/dist/command.d.ts.map +1 -0
  9. package/dist/command.js +46 -0
  10. package/dist/command.js.map +1 -0
  11. package/dist/config/loader.d.ts +9 -0
  12. package/dist/config/loader.d.ts.map +1 -0
  13. package/dist/config/loader.js +34 -0
  14. package/dist/config/loader.js.map +1 -0
  15. package/dist/config/merge.d.ts +18 -0
  16. package/dist/config/merge.d.ts.map +1 -0
  17. package/dist/config/merge.js +31 -0
  18. package/dist/config/merge.js.map +1 -0
  19. package/dist/config/search.d.ts +18 -0
  20. package/dist/config/search.d.ts.map +1 -0
  21. package/dist/config/search.js +40 -0
  22. package/dist/config/search.js.map +1 -0
  23. package/dist/errors.d.ts +32 -0
  24. package/dist/errors.d.ts.map +1 -0
  25. package/dist/errors.js +65 -0
  26. package/dist/errors.js.map +1 -0
  27. package/dist/index.d.ts +16 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +20 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/introspect.d.ts +16 -0
  32. package/dist/introspect.d.ts.map +1 -0
  33. package/dist/introspect.js +128 -0
  34. package/dist/introspect.js.map +1 -0
  35. package/dist/lifecycle.d.ts +27 -0
  36. package/dist/lifecycle.d.ts.map +1 -0
  37. package/dist/lifecycle.js +62 -0
  38. package/dist/lifecycle.js.map +1 -0
  39. package/dist/middleware.d.ts +16 -0
  40. package/dist/middleware.d.ts.map +1 -0
  41. package/dist/middleware.js +15 -0
  42. package/dist/middleware.js.map +1 -0
  43. package/dist/parse/parseargs-bridge.d.ts +22 -0
  44. package/dist/parse/parseargs-bridge.d.ts.map +1 -0
  45. package/dist/parse/parseargs-bridge.js +54 -0
  46. package/dist/parse/parseargs-bridge.js.map +1 -0
  47. package/dist/parse/resolve.d.ts +48 -0
  48. package/dist/parse/resolve.d.ts.map +1 -0
  49. package/dist/parse/resolve.js +240 -0
  50. package/dist/parse/resolve.js.map +1 -0
  51. package/dist/parse/schema-walker.d.ts +21 -0
  52. package/dist/parse/schema-walker.d.ts.map +1 -0
  53. package/dist/parse/schema-walker.js +121 -0
  54. package/dist/parse/schema-walker.js.map +1 -0
  55. package/dist/parse/variadic.d.ts +22 -0
  56. package/dist/parse/variadic.d.ts.map +1 -0
  57. package/dist/parse/variadic.js +71 -0
  58. package/dist/parse/variadic.js.map +1 -0
  59. package/dist/plugin.d.ts +53 -0
  60. package/dist/plugin.d.ts.map +1 -0
  61. package/dist/plugin.js +194 -0
  62. package/dist/plugin.js.map +1 -0
  63. package/dist/types.d.ts +225 -0
  64. package/dist/types.d.ts.map +1 -0
  65. package/dist/types.js +19 -0
  66. package/dist/types.js.map +1 -0
  67. package/dist/zod.d.ts +8 -0
  68. package/dist/zod.d.ts.map +1 -0
  69. package/dist/zod.js +8 -0
  70. package/dist/zod.js.map +1 -0
  71. package/package.json +66 -0
@@ -0,0 +1,240 @@
1
+ /**
2
+ * @runa-cmd/core — Value resolution pipeline
3
+ *
4
+ * Merge priority: CLI args > env vars > config file > Zod defaults.
5
+ * Maps positionals to args by insertion order.
6
+ * Pre-coerces number strings before Zod .parse().
7
+ */
8
+ import { ZodError, z } from 'zod';
9
+ import { ValidationError } from '../errors.js';
10
+ import { walkSchema } from './schema-walker.js';
11
+ import { isVariadic } from './variadic.js';
12
+ // ─── Positional Mapping ─────────────────────────────────────
13
+ function mapPositionals(positionals, argsSchemas) {
14
+ const keys = Object.keys(argsSchemas);
15
+ const result = {};
16
+ if (keys.length === 0) {
17
+ // No args defined but positionals provided
18
+ if (positionals.length > 0) {
19
+ throw new ValidationError([
20
+ {
21
+ code: 'custom',
22
+ message: `Unexpected positional argument: '${positionals[0]}'`,
23
+ path: [],
24
+ },
25
+ ]);
26
+ }
27
+ return result;
28
+ }
29
+ // Check if last arg is variadic
30
+ const lastKey = keys[keys.length - 1];
31
+ if (!lastKey)
32
+ return result;
33
+ const lastSchema = argsSchemas[lastKey];
34
+ const lastIsVariadic = lastSchema ? isVariadic(lastSchema) : false;
35
+ const fixedCount = lastIsVariadic ? keys.length - 1 : keys.length;
36
+ // Check for extra positionals without variadic
37
+ if (!lastIsVariadic && positionals.length > keys.length) {
38
+ throw new ValidationError([
39
+ {
40
+ code: 'custom',
41
+ message: `Unexpected positional argument: '${positionals[keys.length]}'`,
42
+ path: [],
43
+ },
44
+ ]);
45
+ }
46
+ // Map fixed positionals
47
+ for (let i = 0; i < fixedCount; i++) {
48
+ const key = keys[i];
49
+ if (!key)
50
+ continue;
51
+ if (i < positionals.length) {
52
+ result[key] = positionals[i];
53
+ }
54
+ // If not provided, omit — let Zod handle required/optional validation
55
+ }
56
+ // Map variadic (remaining positionals go to last key as array)
57
+ if (lastIsVariadic) {
58
+ result[lastKey] = positionals.slice(fixedCount);
59
+ }
60
+ return result;
61
+ }
62
+ // ─── Value Resolution ───────────────────────────────────────
63
+ function resolveOptionValues(parseArgsValues, longAliasMap, optionsSchemas, optionsMeta, configValues, env, optionsMetadata) {
64
+ const resolved = {};
65
+ // Build a set of number fields for pre-coercion
66
+ const numberFields = new Set();
67
+ for (const meta of optionsMetadata) {
68
+ if (meta.zodType === 'number') {
69
+ numberFields.add(meta.name);
70
+ }
71
+ }
72
+ // First, apply long alias mappings to parseArgs values
73
+ const normalizedValues = { ...parseArgsValues };
74
+ for (const [alias, canonical] of Object.entries(longAliasMap)) {
75
+ if (alias in normalizedValues && !(canonical in normalizedValues)) {
76
+ normalizedValues[canonical] = normalizedValues[alias];
77
+ delete normalizedValues[alias];
78
+ }
79
+ }
80
+ for (const key of Object.keys(optionsSchemas)) {
81
+ // Priority 1: CLI arg
82
+ if (key in normalizedValues && normalizedValues[key] !== undefined) {
83
+ let value = normalizedValues[key];
84
+ // Pre-coerce numbers from string
85
+ if (numberFields.has(key) && typeof value === 'string') {
86
+ const num = Number(value);
87
+ if (!Number.isNaN(num)) {
88
+ value = num;
89
+ }
90
+ }
91
+ resolved[key] = value;
92
+ continue;
93
+ }
94
+ // Priority 2: Environment variable
95
+ const envName = optionsMeta?.[key]?.env;
96
+ if (envName && envName in env && env[envName] !== undefined) {
97
+ let value = env[envName];
98
+ // Pre-coerce numbers from string
99
+ if (numberFields.has(key) && typeof value === 'string') {
100
+ const num = Number(value);
101
+ if (!Number.isNaN(num)) {
102
+ value = num;
103
+ }
104
+ }
105
+ resolved[key] = value;
106
+ continue;
107
+ }
108
+ // Priority 3: Config file value
109
+ if (configValues && key in configValues && configValues[key] !== undefined) {
110
+ let value = configValues[key];
111
+ // Pre-coerce numbers from string (config values are usually already typed,
112
+ // but defensive handling)
113
+ if (numberFields.has(key) && typeof value === 'string') {
114
+ const num = Number(value);
115
+ if (!Number.isNaN(num)) {
116
+ value = num;
117
+ }
118
+ }
119
+ resolved[key] = value;
120
+ }
121
+ // Priority 4: Omit — let Zod .default() handle it
122
+ }
123
+ return resolved;
124
+ }
125
+ /**
126
+ * Rewrite Zod issues into user-friendly CLI error messages.
127
+ * Handles common cases: missing required args/options, invalid enums, wrong types.
128
+ */
129
+ function humanizeArgIssues(issues, argsSchemas) {
130
+ const metadata = walkSchema(argsSchemas);
131
+ const metaByName = new Map(metadata.map((m) => [m.name, m]));
132
+ return issues.map((issue) => {
133
+ const name = issue.path[0];
134
+ if (typeof name !== 'string')
135
+ return issue;
136
+ const param = metaByName.get(name);
137
+ // Missing required arg: Zod v4 produces "Invalid input: expected X, received undefined"
138
+ if (issue.code === 'invalid_type' && issue.message.includes('received undefined')) {
139
+ return {
140
+ code: 'custom',
141
+ message: `Missing required argument: <${name}>${param?.description ? ` — ${param.description}` : ''}`,
142
+ path: issue.path,
143
+ };
144
+ }
145
+ // Invalid enum value (Zod v4 uses 'invalid_value' for enums)
146
+ if (issue.code === 'invalid_value' && param?.enumValues) {
147
+ return {
148
+ code: 'custom',
149
+ message: `Invalid value for <${name}>. Expected one of: ${param.enumValues.join(', ')}`,
150
+ path: issue.path,
151
+ };
152
+ }
153
+ return issue;
154
+ });
155
+ }
156
+ function humanizeOptionIssues(issues, optionsSchemas) {
157
+ const metadata = walkSchema(optionsSchemas);
158
+ const metaByName = new Map(metadata.map((m) => [m.name, m]));
159
+ return issues.map((issue) => {
160
+ const name = issue.path[0];
161
+ if (typeof name !== 'string')
162
+ return issue;
163
+ const param = metaByName.get(name);
164
+ // Missing required option
165
+ if (issue.code === 'invalid_type' && issue.message.includes('received undefined')) {
166
+ return {
167
+ code: 'custom',
168
+ message: `Missing required option: --${name}${param?.description ? ` — ${param.description}` : ''}`,
169
+ path: issue.path,
170
+ };
171
+ }
172
+ // Invalid enum value
173
+ if (issue.code === 'invalid_value' && param?.enumValues) {
174
+ return {
175
+ code: 'custom',
176
+ message: `Invalid value for --${name}. Expected one of: ${param.enumValues.join(', ')}`,
177
+ path: issue.path,
178
+ };
179
+ }
180
+ // Wrong type (e.g. expected number, got string)
181
+ if (issue.code === 'invalid_type') {
182
+ const expected = issue.expected;
183
+ return {
184
+ code: 'custom',
185
+ message: `Invalid value for --${name}: expected ${String(expected)}`,
186
+ path: issue.path,
187
+ };
188
+ }
189
+ return issue;
190
+ });
191
+ }
192
+ // ─── Public API ─────────────────────────────────────────────
193
+ /**
194
+ * Resolve values from all sources and validate through Zod.
195
+ *
196
+ * Pipeline:
197
+ * 1. Map positionals to args by insertion order
198
+ * 2. Merge option values (CLI > env > config)
199
+ * 3. Pre-coerce number strings
200
+ * 4. Validate through Zod schemas
201
+ * 5. Return typed results or throw ValidationError
202
+ */
203
+ export function resolveValues(input) {
204
+ const { parseArgsResult, longAliasMap = {}, schemas, meta, configValues, env = process.env, } = input;
205
+ // ─── Args resolution ─────────────────────────────────
206
+ let parsedArgs = {};
207
+ if (schemas.args && Object.keys(schemas.args).length > 0) {
208
+ const rawArgs = mapPositionals(parseArgsResult.positionals, schemas.args);
209
+ // Build Zod object schema for args and validate
210
+ const argsZodSchema = z.object(schemas.args);
211
+ try {
212
+ parsedArgs = argsZodSchema.parse(rawArgs);
213
+ }
214
+ catch (err) {
215
+ if (err instanceof ZodError) {
216
+ throw new ValidationError(humanizeArgIssues(err.issues, schemas.args));
217
+ }
218
+ throw err;
219
+ }
220
+ }
221
+ // ─── Options resolution ──────────────────────────────
222
+ let parsedOptions = {};
223
+ if (schemas.options && Object.keys(schemas.options).length > 0) {
224
+ const optionsMetadata = walkSchema(schemas.options);
225
+ const rawOptions = resolveOptionValues(parseArgsResult.values, longAliasMap, schemas.options, meta?.options, configValues, env, optionsMetadata);
226
+ // Build Zod object schema for options and validate
227
+ const optionsZodSchema = z.object(schemas.options);
228
+ try {
229
+ parsedOptions = optionsZodSchema.parse(rawOptions);
230
+ }
231
+ catch (err) {
232
+ if (err instanceof ZodError) {
233
+ throw new ValidationError(humanizeOptionIssues(err.issues, schemas.options));
234
+ }
235
+ throw err;
236
+ }
237
+ }
238
+ return { parsedArgs, parsedOptions };
239
+ }
240
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/parse/resolve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @runa-cmd/core — Zod Schema Walker
3
+ *
4
+ * Walks Zod schemas to extract parameter metadata (type, default, required,
5
+ * description, enum values, variadic). This is the ONLY module that accesses
6
+ * Zod v4 internal `._zod.def` — if Zod changes internals, only this file
7
+ * needs updating.
8
+ */
9
+ import type { ZodType } from 'zod';
10
+ import type { ParamMetadata } from '../types.js';
11
+ /**
12
+ * Walk a record of Zod schemas and extract parameter metadata for each key.
13
+ * Keys are returned in insertion order (Object.entries preserves it).
14
+ */
15
+ export declare function walkSchema(schemas: Record<string, ZodType>): ParamMetadata[];
16
+ /**
17
+ * Walk a single Zod schema and extract its metadata.
18
+ * Used by other modules that need to inspect individual schemas.
19
+ */
20
+ export declare function walkSingleSchema(name: string, schema: ZodType): ParamMetadata;
21
+ //# sourceMappingURL=schema-walker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-walker.d.ts","sourceRoot":"","sources":["../../src/parse/schema-walker.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AACnC,OAAO,KAAK,EAAE,aAAa,EAAa,MAAM,aAAa,CAAC;AA6I5D;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,aAAa,EAAE,CAmB5E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,aAAa,CAa7E"}
@@ -0,0 +1,121 @@
1
+ // ─── Helper: access ._zod.def safely ───────────────────────
2
+ function getZodDef(schema) {
3
+ const s = schema;
4
+ if (!s._zod?.def) {
5
+ throw new Error('Cannot introspect Zod schema: ._zod.def is missing. Ensure you are using Zod v4.');
6
+ }
7
+ return s._zod.def;
8
+ }
9
+ function getDescription(schema) {
10
+ const s = schema;
11
+ return s.description;
12
+ }
13
+ function unwrapSchema(schema) {
14
+ let isOptional = false;
15
+ let defaultValue;
16
+ let hasDefault = false;
17
+ let description = getDescription(schema);
18
+ let current = schema;
19
+ // Iteratively unwrap layers
20
+ const maxDepth = 10; // safety limit
21
+ for (let i = 0; i < maxDepth; i++) {
22
+ const def = getZodDef(current);
23
+ if (def.type === 'optional') {
24
+ isOptional = true;
25
+ current = def.innerType;
26
+ if (!description)
27
+ description = getDescription(current);
28
+ continue;
29
+ }
30
+ if (def.type === 'default') {
31
+ isOptional = true; // defaults make the field optional from the user's perspective
32
+ hasDefault = true;
33
+ defaultValue = def.defaultValue;
34
+ current = def.innerType;
35
+ if (!description)
36
+ description = getDescription(current);
37
+ continue;
38
+ }
39
+ if (def.type === 'nullable') {
40
+ current = def.innerType;
41
+ if (!description)
42
+ description = getDescription(current);
43
+ continue;
44
+ }
45
+ // Base type reached
46
+ break;
47
+ }
48
+ // If we found a default via the wrapper, keep it.
49
+ // If not, defaultValue stays undefined.
50
+ return {
51
+ baseSchema: current,
52
+ baseDef: getZodDef(current),
53
+ isOptional,
54
+ defaultValue: hasDefault ? defaultValue : undefined,
55
+ description,
56
+ };
57
+ }
58
+ // ─── Detect base type ───────────────────────────────────────
59
+ function detectParamType(def) {
60
+ switch (def.type) {
61
+ case 'string':
62
+ return { zodType: 'string' };
63
+ case 'number':
64
+ case 'int':
65
+ return { zodType: 'number' };
66
+ case 'boolean':
67
+ return { zodType: 'boolean' };
68
+ case 'enum': {
69
+ // Zod v4 uses `entries` (object { staging: 'staging', prod: 'prod' })
70
+ // not `values` (array). Extract the values from the entries object.
71
+ const entries = def.entries;
72
+ const values = entries ? Object.values(entries) : undefined;
73
+ return { zodType: 'enum', enumValues: values };
74
+ }
75
+ case 'array':
76
+ return { zodType: 'array' };
77
+ default:
78
+ // Fallback: treat unknown types as string
79
+ return { zodType: 'string' };
80
+ }
81
+ }
82
+ // ─── Public API ─────────────────────────────────────────────
83
+ /**
84
+ * Walk a record of Zod schemas and extract parameter metadata for each key.
85
+ * Keys are returned in insertion order (Object.entries preserves it).
86
+ */
87
+ export function walkSchema(schemas) {
88
+ const result = [];
89
+ for (const [name, schema] of Object.entries(schemas)) {
90
+ const { baseDef, isOptional, defaultValue, description } = unwrapSchema(schema);
91
+ const { zodType, enumValues } = detectParamType(baseDef);
92
+ result.push({
93
+ name,
94
+ zodType,
95
+ isOptional,
96
+ defaultValue,
97
+ isArray: zodType === 'array',
98
+ enumValues,
99
+ description,
100
+ });
101
+ }
102
+ return result;
103
+ }
104
+ /**
105
+ * Walk a single Zod schema and extract its metadata.
106
+ * Used by other modules that need to inspect individual schemas.
107
+ */
108
+ export function walkSingleSchema(name, schema) {
109
+ const { baseDef, isOptional, defaultValue, description } = unwrapSchema(schema);
110
+ const { zodType, enumValues } = detectParamType(baseDef);
111
+ return {
112
+ name,
113
+ zodType,
114
+ isOptional,
115
+ defaultValue,
116
+ isArray: zodType === 'array',
117
+ enumValues,
118
+ description,
119
+ };
120
+ }
121
+ //# sourceMappingURL=schema-walker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-walker.js","sourceRoot":"","sources":["../../src/parse/schema-walker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @runa-cmd/core — Variadic arg validation
3
+ *
4
+ * Validates that z.array() positional args appear only as the last arg
5
+ * and that at most one variadic arg exists per command.
6
+ * These checks run at definition time (when defineCommand() is called).
7
+ */
8
+ import type { ZodType } from 'zod';
9
+ /**
10
+ * Check if a Zod schema is a z.array() type.
11
+ * Unwraps optional/default/nullable wrappers to find the base type.
12
+ */
13
+ export declare function isVariadic(schema: ZodType): boolean;
14
+ /**
15
+ * Validate variadic arg constraints:
16
+ * 1. z.array() is only allowed as the LAST positional arg
17
+ * 2. At most one z.array() per command
18
+ *
19
+ * Throws RunaError at definition time if constraints are violated.
20
+ */
21
+ export declare function validateVariadicArgs(args: Record<string, ZodType>): void;
22
+ //# sourceMappingURL=variadic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"variadic.d.ts","sourceRoot":"","sources":["../../src/parse/variadic.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAsBnC;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAyBnD;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAsCxE"}
@@ -0,0 +1,71 @@
1
+ import { RunaError } from '../errors.js';
2
+ function getDefType(schema) {
3
+ const s = schema;
4
+ return s._zod?.def?.type ?? 'unknown';
5
+ }
6
+ // ─── Public API ─────────────────────────────────────────────
7
+ /**
8
+ * Check if a Zod schema is a z.array() type.
9
+ * Unwraps optional/default/nullable wrappers to find the base type.
10
+ */
11
+ export function isVariadic(schema) {
12
+ let current = schema;
13
+ const maxDepth = 10;
14
+ for (let i = 0; i < maxDepth; i++) {
15
+ const defType = getDefType(current);
16
+ if (defType === 'array') {
17
+ return true;
18
+ }
19
+ // Unwrap wrappers
20
+ if (defType === 'optional' || defType === 'default' || defType === 'nullable') {
21
+ const s = current;
22
+ const inner = s._zod?.def?.innerType;
23
+ if (inner) {
24
+ current = inner;
25
+ continue;
26
+ }
27
+ }
28
+ return false;
29
+ }
30
+ return false;
31
+ }
32
+ /**
33
+ * Validate variadic arg constraints:
34
+ * 1. z.array() is only allowed as the LAST positional arg
35
+ * 2. At most one z.array() per command
36
+ *
37
+ * Throws RunaError at definition time if constraints are violated.
38
+ */
39
+ export function validateVariadicArgs(args) {
40
+ const keys = Object.keys(args);
41
+ const arrayIndices = [];
42
+ for (let i = 0; i < keys.length; i++) {
43
+ const key = keys[i];
44
+ if (!key)
45
+ continue;
46
+ const schema = args[key];
47
+ if (schema && isVariadic(schema)) {
48
+ arrayIndices.push({ name: key, index: i });
49
+ }
50
+ }
51
+ // No arrays → valid
52
+ if (arrayIndices.length === 0) {
53
+ return;
54
+ }
55
+ // Multiple arrays → invalid
56
+ if (arrayIndices.length > 1) {
57
+ const names = arrayIndices.map((a) => `'${a.name}'`).join(', ');
58
+ throw new RunaError(`Only one variadic arg is allowed per command. Found: ${names}.`, {
59
+ code: 'INVALID_VARIADIC_ARGS',
60
+ exitCode: 1,
61
+ });
62
+ }
63
+ // Single array but not in last position → invalid
64
+ const arrayEntry = arrayIndices[0];
65
+ if (arrayEntry && arrayEntry.index !== keys.length - 1) {
66
+ throw new RunaError(`Variadic arg '${arrayEntry.name}' must be the last positional argument. ` +
67
+ `Found at position ${arrayEntry.index} of ${keys.length}.`, { code: 'INVALID_VARIADIC_POSITION', exitCode: 1 });
68
+ }
69
+ // Single array in last position → valid
70
+ }
71
+ //# sourceMappingURL=variadic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"variadic.js","sourceRoot":"","sources":["../../src/parse/variadic.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAczC,SAAS,UAAU,CAAC,MAAe;IAClC,MAAM,CAAC,GAAG,MAA2C,CAAC;IACtD,OAAO,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AACvC,CAAC;AAED,+DAA+D;AAE/D;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,MAAe;IACzC,IAAI,OAAO,GAAG,MAAM,CAAC;IACrB,MAAM,QAAQ,GAAG,EAAE,CAAC;IAEpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;QAEpC,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC;QACb,CAAC;QAED,kBAAkB;QAClB,IAAI,OAAO,KAAK,UAAU,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;YAC/E,MAAM,CAAC,GAAG,OAA4C,CAAC;YACvD,MAAM,KAAK,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,CAAC;YACrC,IAAI,KAAK,EAAE,CAAC;gBACX,OAAO,GAAG,KAAK,CAAC;gBAChB,SAAS;YACV,CAAC;QACF,CAAC;QAED,OAAO,KAAK,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAA6B;IACjE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,YAAY,GAA2C,EAAE,CAAC;IAEhE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,CAAC,GAAG;YAAE,SAAS;QACnB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,MAAM,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAClC,YAAY,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QAC5C,CAAC;IACF,CAAC;IAED,oBAAoB;IACpB,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO;IACR,CAAC;IAED,4BAA4B;IAC5B,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChE,MAAM,IAAI,SAAS,CAAC,wDAAwD,KAAK,GAAG,EAAE;YACrF,IAAI,EAAE,uBAAuB;YAC7B,QAAQ,EAAE,CAAC;SACX,CAAC,CAAC;IACJ,CAAC;IAED,kDAAkD;IAClD,MAAM,UAAU,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,UAAU,IAAI,UAAU,CAAC,KAAK,KAAK,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,SAAS,CAClB,iBAAiB,UAAU,CAAC,IAAI,0CAA0C;YACzE,qBAAqB,UAAU,CAAC,KAAK,OAAO,IAAI,CAAC,MAAM,GAAG,EAC3D,EAAE,IAAI,EAAE,2BAA2B,EAAE,QAAQ,EAAE,CAAC,EAAE,CAClD,CAAC;IACH,CAAC;IAED,wCAAwC;AACzC,CAAC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @runa-cmd/core — Plugin system
3
+ *
4
+ * definePlugin() — validate and return plugin config
5
+ * Plugin host — resolve lazy imports, topological sort, setup/cleanup orchestration
6
+ * Capability validation via PluginAPI proxy
7
+ */
8
+ import type { ZodType } from 'zod';
9
+ import type { CLISchema, CommandTree, HookHandler, HookName, Middleware, OptionMeta, PluginAPI, PluginCapabilities, PluginConfig } from './types.js';
10
+ /**
11
+ * Validate and return a PluginConfig.
12
+ * Passthrough with shape validation — ensures required fields exist.
13
+ */
14
+ export declare function definePlugin(config: PluginConfig): PluginConfig;
15
+ type PluginInput = PluginConfig | (() => Promise<{
16
+ default: PluginConfig;
17
+ }>);
18
+ /**
19
+ * Resolve a list of plugin inputs (direct configs or lazy imports)
20
+ * into resolved PluginConfig objects.
21
+ */
22
+ export declare function resolvePlugins(plugins: PluginInput[]): Promise<PluginConfig[]>;
23
+ /**
24
+ * Sort plugins in dependency order using Kahn's algorithm.
25
+ * Detects circular dependencies and missing dependencies.
26
+ */
27
+ export declare function topologicalSort(plugins: PluginConfig[]): PluginConfig[];
28
+ export interface PluginHostRefs {
29
+ commands: CommandTree;
30
+ globalOptions: Record<string, ZodType>;
31
+ globalMeta: {
32
+ options: Record<string, OptionMeta>;
33
+ };
34
+ middleware: Middleware[];
35
+ hookRegister: (name: HookName, handler: HookHandler) => void;
36
+ getSchema: () => CLISchema;
37
+ }
38
+ /**
39
+ * Create a PluginAPI for a specific plugin, enforcing capability checks.
40
+ */
41
+ export declare function createPluginAPI(pluginName: string, capabilities: PluginCapabilities | undefined, refs: PluginHostRefs): PluginAPI;
42
+ /**
43
+ * Call setup(api) for each plugin in topological order.
44
+ */
45
+ export declare function runPluginSetup(plugins: PluginConfig[], refs: PluginHostRefs): Promise<void>;
46
+ /**
47
+ * Call cleanup() for each plugin in REVERSE topological order.
48
+ * Each cleanup is wrapped in try/catch — failures don't prevent others from running.
49
+ * Returns collected errors.
50
+ */
51
+ export declare function runPluginCleanup(plugins: PluginConfig[]): Promise<Error[]>;
52
+ export {};
53
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAEnC,OAAO,KAAK,EACX,SAAS,EAET,WAAW,EACX,WAAW,EACX,QAAQ,EACR,UAAU,EACV,UAAU,EACV,SAAS,EACT,kBAAkB,EAClB,YAAY,EACZ,MAAM,YAAY,CAAC;AAIpB;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CAc/D;AAID,KAAK,WAAW,GAAG,YAAY,GAAG,CAAC,MAAM,OAAO,CAAC;IAAE,OAAO,EAAE,YAAY,CAAA;CAAE,CAAC,CAAC,CAAC;AAE7E;;;GAGG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CA2BpF;AAID;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,YAAY,EAAE,CAmEvE;AAID,MAAM,WAAW,cAAc;IAC9B,QAAQ,EAAE,WAAW,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,UAAU,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;KAAE,CAAC;IACpD,UAAU,EAAE,UAAU,EAAE,CAAC;IACzB,YAAY,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IAC7D,SAAS,EAAE,MAAM,SAAS,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC9B,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,kBAAkB,GAAG,SAAS,EAC5C,IAAI,EAAE,cAAc,GAClB,SAAS,CAkDX;AAID;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAKjG;AAID;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CAiBhF"}