@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
package/dist/cli.js ADDED
@@ -0,0 +1,413 @@
1
+ /**
2
+ * @runa-cmd/core — defineCLI() + runCLI()
3
+ *
4
+ * The main CLI orchestrator. Wires together:
5
+ * - Command resolution (including subcommands)
6
+ * - Parsing pipeline (schema-walker → parseArgs-bridge → util.parseArgs → resolve)
7
+ * - Lifecycle hooks (7-hook pipeline)
8
+ * - Plugin loading (topological sort, setup/cleanup)
9
+ * - Middleware execution (Koa/Hono onion model)
10
+ * - Config loading
11
+ * - Error handling
12
+ */
13
+ import { parseArgs } from 'node:util';
14
+ import { loadAndMergeConfig } from './config/merge.js';
15
+ import { CommandNotFoundError, RunaError } from './errors.js';
16
+ import { getSchema } from './introspect.js';
17
+ import { createHookRegistry } from './lifecycle.js';
18
+ import { buildParseArgsConfig } from './parse/parseargs-bridge.js';
19
+ import { resolveValues } from './parse/resolve.js';
20
+ import { walkSchema } from './parse/schema-walker.js';
21
+ import { resolvePlugins, runPluginCleanup, runPluginSetup, topologicalSort } from './plugin.js';
22
+ /**
23
+ * Check if a value is a Command (branded object).
24
+ */
25
+ function isCommand(value) {
26
+ return '_type' in value && value._type === 'runa:command';
27
+ }
28
+ /**
29
+ * Levenshtein distance for "did you mean" suggestions.
30
+ */
31
+ function levenshtein(a, b) {
32
+ const rows = b.length + 1;
33
+ const cols = a.length + 1;
34
+ // Use a flat array for guaranteed index access without non-null assertions
35
+ const matrix = new Array(rows * cols).fill(0);
36
+ const at = (i, j) => matrix[i * cols + j] ?? 0;
37
+ const set = (i, j, v) => {
38
+ matrix[i * cols + j] = v;
39
+ };
40
+ for (let i = 0; i < rows; i++)
41
+ set(i, 0, i);
42
+ for (let j = 0; j < cols; j++)
43
+ set(0, j, j);
44
+ for (let i = 1; i < rows; i++) {
45
+ for (let j = 1; j < cols; j++) {
46
+ if (b[i - 1] === a[j - 1]) {
47
+ set(i, j, at(i - 1, j - 1));
48
+ }
49
+ else {
50
+ set(i, j, Math.min(at(i - 1, j - 1) + 1, // substitution
51
+ at(i, j - 1) + 1, // insertion
52
+ at(i - 1, j) + 1));
53
+ }
54
+ }
55
+ }
56
+ return at(b.length, a.length);
57
+ }
58
+ /**
59
+ * Find the best suggestion for a misspelled command name.
60
+ * Returns undefined if no close match exists (distance > 3).
61
+ */
62
+ function findSuggestion(input, candidates) {
63
+ let best;
64
+ let bestDist = Infinity;
65
+ for (const candidate of candidates) {
66
+ const dist = levenshtein(input, candidate);
67
+ if (dist < bestDist) {
68
+ bestDist = dist;
69
+ best = candidate;
70
+ }
71
+ }
72
+ // Only suggest if reasonably close
73
+ return bestDist <= 3 ? best : undefined;
74
+ }
75
+ /**
76
+ * Resolve a command from the command tree by walking argv tokens.
77
+ * Supports nested subcommands.
78
+ */
79
+ function resolveCommand(commands, tokens) {
80
+ let current = commands;
81
+ let consumed = 0;
82
+ for (let i = 0; i < tokens.length; i++) {
83
+ const token = tokens[i];
84
+ if (token === undefined)
85
+ break;
86
+ // Stop at flags — they're not command names
87
+ if (token.startsWith('-'))
88
+ break;
89
+ const entry = current[token];
90
+ if (!entry)
91
+ break;
92
+ consumed++;
93
+ if (isCommand(entry)) {
94
+ return {
95
+ command: entry,
96
+ remainingArgv: tokens.slice(consumed),
97
+ };
98
+ }
99
+ // It's a subtree — continue walking
100
+ current = entry;
101
+ }
102
+ // If we're in a subtree and haven't found a command, check for a default/index command
103
+ // For now, throw CommandNotFoundError
104
+ const commandName = tokens[consumed] ?? tokens[consumed - 1] ?? '';
105
+ const candidates = Object.keys(current);
106
+ const suggestion = commandName ? findSuggestion(commandName, candidates) : undefined;
107
+ if (!commandName && consumed === 0) {
108
+ throw new CommandNotFoundError('(no command specified)', undefined);
109
+ }
110
+ throw new CommandNotFoundError(tokens.slice(0, consumed + 1).join(' '), suggestion);
111
+ }
112
+ // ─── Middleware Composition ─────────────────────────────────
113
+ /**
114
+ * Compose middleware into a nested chain.
115
+ * Outermost middleware is first in the array.
116
+ * Innermost next() calls the command execution function.
117
+ */
118
+ function composeMiddleware(middlewareList, globalOptions, innerFn) {
119
+ // Build the chain from inside out
120
+ let chain = innerFn;
121
+ for (let i = middlewareList.length - 1; i >= 0; i--) {
122
+ const mw = middlewareList[i];
123
+ if (!mw)
124
+ continue;
125
+ const next = chain;
126
+ chain = () => {
127
+ const ctx = {
128
+ next: async () => {
129
+ await next();
130
+ },
131
+ globalOptions,
132
+ };
133
+ return mw.handler(ctx);
134
+ };
135
+ }
136
+ return chain;
137
+ }
138
+ // ─── CLI Execution Engine ───────────────────────────────────
139
+ /**
140
+ * Run the full CLI lifecycle.
141
+ */
142
+ async function runCLILifecycle(config, argv) {
143
+ // ─── State ─────────────────────────────────────────
144
+ const hookRegistry = createHookRegistry();
145
+ const mutableCommands = { ...config.commands };
146
+ const mutableGlobalOptions = { ...(config.globalOptions ?? {}) };
147
+ const mutableGlobalMeta = {
148
+ options: { ...(config.globalMeta?.options ?? {}) },
149
+ };
150
+ const mutableMiddleware = [...(config.middleware ?? [])];
151
+ let sortedPlugins = [];
152
+ // Hook context that grows as we progress through the lifecycle
153
+ const hookCtx = {
154
+ cli: config.meta,
155
+ rawArgs: argv,
156
+ };
157
+ let lifecycleError;
158
+ let commandResult;
159
+ try {
160
+ // ─── Plugin resolution ────────────────────────────
161
+ if (config.plugins && config.plugins.length > 0) {
162
+ const resolvedPlugins = await resolvePlugins(config.plugins);
163
+ sortedPlugins = topologicalSort(resolvedPlugins);
164
+ // Create plugin host refs
165
+ const pluginRefs = {
166
+ commands: mutableCommands,
167
+ globalOptions: mutableGlobalOptions,
168
+ globalMeta: mutableGlobalMeta,
169
+ middleware: mutableMiddleware,
170
+ hookRegister: (name, handler) => hookRegistry.register(name, handler),
171
+ getSchema: () => getSchema({ ...config, commands: mutableCommands }, mutableGlobalOptions, mutableGlobalMeta.options),
172
+ };
173
+ await runPluginSetup(sortedPlugins, pluginRefs);
174
+ }
175
+ // ─── beforeParse ──────────────────────────────────
176
+ await hookRegistry.emit('beforeParse', hookCtx);
177
+ // Handlers may have mutated hookCtx.rawArgs
178
+ const currentArgv = hookCtx.rawArgs;
179
+ // ─── Parse global options ─────────────────────────
180
+ let parsedGlobalOptions = {};
181
+ if (Object.keys(mutableGlobalOptions).length > 0) {
182
+ const globalMetadata = walkSchema(mutableGlobalOptions);
183
+ const { parseArgsConfig, longAliasMap } = buildParseArgsConfig(globalMetadata, mutableGlobalMeta.options, true);
184
+ // Build lookup maps for global options:
185
+ // longNames: '--verbose' → 'verbose' (canonical name)
186
+ // shortNames: '-V' → 'verbose' (canonical name)
187
+ // booleanGlobals: set of canonical names that are boolean type
188
+ const longNames = new Map();
189
+ const shortNames = new Map();
190
+ const booleanGlobals = new Set();
191
+ const registeredOptions = parseArgsConfig.options ?? {};
192
+ for (const [name, opt] of Object.entries(registeredOptions)) {
193
+ const canonical = longAliasMap[name] ?? name;
194
+ longNames.set(`--${name}`, canonical);
195
+ // --no-* negation for booleans
196
+ if (opt?.type === 'boolean') {
197
+ booleanGlobals.add(canonical);
198
+ longNames.set(`--no-${name}`, canonical);
199
+ }
200
+ if (opt && 'short' in opt && opt.short) {
201
+ shortNames.set(`-${opt.short}`, canonical);
202
+ }
203
+ }
204
+ // Long aliases
205
+ for (const [alias, canonical] of Object.entries(longAliasMap)) {
206
+ longNames.set(`--${alias}`, canonical);
207
+ }
208
+ // Manual argv split: extract global option tokens, leave the rest
209
+ const globalArgv = [];
210
+ const commandArgv = [];
211
+ let i = 0;
212
+ while (i < currentArgv.length) {
213
+ const token = currentArgv[i] ?? '';
214
+ // Handle --opt=val form
215
+ const eqIdx = token.indexOf('=');
216
+ const tokenKey = eqIdx > 0 ? token.slice(0, eqIdx) : token;
217
+ if (longNames.has(tokenKey) || shortNames.has(tokenKey)) {
218
+ const canonical = longNames.get(tokenKey) ?? shortNames.get(tokenKey) ?? '';
219
+ const isBool = booleanGlobals.has(canonical);
220
+ if (eqIdx > 0) {
221
+ // --opt=val — single token, always extract
222
+ globalArgv.push(token);
223
+ i++;
224
+ }
225
+ else if (isBool) {
226
+ // --verbose or --no-verbose — boolean, no value token
227
+ globalArgv.push(token);
228
+ i++;
229
+ }
230
+ else {
231
+ // --opt val — string option, extract both tokens
232
+ globalArgv.push(token);
233
+ i++;
234
+ if (i < currentArgv.length) {
235
+ globalArgv.push(currentArgv[i] ?? '');
236
+ i++;
237
+ }
238
+ }
239
+ }
240
+ else {
241
+ commandArgv.push(token);
242
+ i++;
243
+ }
244
+ }
245
+ // Now parse ONLY the extracted global tokens with parseArgs
246
+ const globalParseResult = parseArgs({
247
+ ...parseArgsConfig,
248
+ args: globalArgv,
249
+ });
250
+ const { parsedOptions } = resolveValues({
251
+ parseArgsResult: {
252
+ values: globalParseResult.values,
253
+ positionals: [],
254
+ },
255
+ longAliasMap,
256
+ schemas: { options: mutableGlobalOptions },
257
+ meta: { options: mutableGlobalMeta.options },
258
+ });
259
+ parsedGlobalOptions = parsedOptions;
260
+ // Pass remaining argv (command tokens only) to command parsing
261
+ hookCtx.rawArgs = commandArgv;
262
+ }
263
+ hookCtx.globalOptions = parsedGlobalOptions;
264
+ // ─── onGlobalFlags ────────────────────────────────
265
+ const globalFlagsResult = await hookRegistry.emit('onGlobalFlags', hookCtx);
266
+ if (globalFlagsResult.shortCircuited) {
267
+ // Short-circuit: skip command resolution and execution, go to cleanup
268
+ return;
269
+ }
270
+ // ─── Resolve command ──────────────────────────────
271
+ const commandArgv = hookCtx.rawArgs;
272
+ const { command, remainingArgv } = resolveCommandFromTree(mutableCommands, commandArgv, config);
273
+ hookCtx.command = command.meta;
274
+ // ─── Parse command args + options ──────────────────
275
+ const optionMetadata = command.options ? walkSchema(command.options) : [];
276
+ const { parseArgsConfig, longAliasMap } = buildParseArgsConfig(optionMetadata, command.meta.options, !!command.args);
277
+ const cmdParseResult = parseArgs({
278
+ ...parseArgsConfig,
279
+ args: remainingArgv,
280
+ });
281
+ // Load config values if configured
282
+ let configValues;
283
+ if (config.config) {
284
+ configValues = await loadAndMergeConfig(config.config);
285
+ }
286
+ const { parsedArgs, parsedOptions } = resolveValues({
287
+ parseArgsResult: {
288
+ values: cmdParseResult.values,
289
+ positionals: cmdParseResult.positionals,
290
+ },
291
+ longAliasMap,
292
+ schemas: {
293
+ args: command.args,
294
+ options: command.options,
295
+ },
296
+ meta: { options: command.meta.options },
297
+ configValues,
298
+ });
299
+ hookCtx.args = parsedArgs;
300
+ hookCtx.options = parsedOptions;
301
+ // ─── afterParse ───────────────────────────────────
302
+ await hookRegistry.emit('afterParse', hookCtx);
303
+ // ─── beforeRun ────────────────────────────────────
304
+ await hookRegistry.emit('beforeRun', hookCtx);
305
+ // ─── Middleware chain + command execution ──────────
306
+ const runContext = {
307
+ args: parsedArgs,
308
+ options: parsedOptions,
309
+ globalOptions: parsedGlobalOptions,
310
+ command: command.meta,
311
+ rawArgs: argv,
312
+ };
313
+ const innerFn = async () => {
314
+ commandResult = await command.run(runContext);
315
+ // Validate output schema if present
316
+ if (command.output) {
317
+ command.output.parse(commandResult);
318
+ }
319
+ };
320
+ const chain = composeMiddleware(mutableMiddleware, parsedGlobalOptions, innerFn);
321
+ await chain();
322
+ // ─── afterRun ─────────────────────────────────────
323
+ await hookRegistry.emit('afterRun', hookCtx);
324
+ }
325
+ catch (err) {
326
+ lifecycleError = err instanceof Error ? err : new Error(String(err));
327
+ // ─── onError ──────────────────────────────────────
328
+ hookCtx.error = lifecycleError;
329
+ try {
330
+ await hookRegistry.emit('onError', hookCtx);
331
+ }
332
+ catch {
333
+ // onError handler threw — swallow it, cleanup still needs to run
334
+ }
335
+ // If error was not handled, fall back to default behavior
336
+ if (!hookCtx.handled) {
337
+ const exitCode = lifecycleError instanceof RunaError ? lifecycleError.exitCode : 1;
338
+ console.error(lifecycleError.message);
339
+ process.exit(exitCode);
340
+ }
341
+ }
342
+ finally {
343
+ // ─── cleanup (ALWAYS runs) ────────────────────────
344
+ try {
345
+ await hookRegistry.emit('cleanup', hookCtx);
346
+ }
347
+ catch {
348
+ // Cleanup hook errors are swallowed
349
+ }
350
+ // Plugin cleanup in reverse topological order
351
+ if (sortedPlugins.length > 0) {
352
+ const cleanupErrors = await runPluginCleanup(sortedPlugins);
353
+ if (cleanupErrors.length > 0) {
354
+ for (const err of cleanupErrors) {
355
+ console.error(`Plugin cleanup error: ${err.message}`);
356
+ }
357
+ }
358
+ }
359
+ }
360
+ }
361
+ /**
362
+ * Resolve command with single-command mode support.
363
+ * If there's exactly one command, route directly without requiring
364
+ * the command name in argv.
365
+ */
366
+ function resolveCommandFromTree(commands, argv, _config) {
367
+ const commandEntries = Object.entries(commands);
368
+ // Single-command mode: if exactly one command and first token doesn't match it,
369
+ // route directly to that command
370
+ if (commandEntries.length === 1) {
371
+ const firstEntry = commandEntries[0];
372
+ if (firstEntry) {
373
+ const [name, entry] = firstEntry;
374
+ if (isCommand(entry)) {
375
+ // If argv is empty or first token doesn't match the command name
376
+ if (argv.length === 0 || argv[0] !== name) {
377
+ return { command: entry, remainingArgv: argv };
378
+ }
379
+ // First token matches — consume it
380
+ return { command: entry, remainingArgv: argv.slice(1) };
381
+ }
382
+ }
383
+ }
384
+ // Multi-command mode: resolve from tree
385
+ return resolveCommand(commands, argv);
386
+ }
387
+ // ─── Public API ─────────────────────────────────────────────
388
+ /**
389
+ * Create a CLI from a configuration.
390
+ * Returns a branded CLI object with a .run() method.
391
+ */
392
+ export function defineCLI(config) {
393
+ return {
394
+ _type: 'runa:cli',
395
+ config,
396
+ async run(argv) {
397
+ const effectiveArgv = argv ?? process.argv.slice(2);
398
+ await runCLILifecycle(config, effectiveArgv);
399
+ },
400
+ };
401
+ }
402
+ /**
403
+ * Single-command shorthand.
404
+ * Wraps a command in defineCLI() and runs it.
405
+ */
406
+ export async function runCLI(command, argv) {
407
+ const cli = defineCLI({
408
+ meta: { name: command.meta.name, description: command.meta.description },
409
+ commands: { [command.meta.name]: command },
410
+ });
411
+ await cli.run(argv);
412
+ }
413
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @runa-cmd/core — defineCommand()
3
+ *
4
+ * Builder function that creates a typed, branded Command object from
5
+ * a CommandConfig. Validates variadic args and meta.options keys at
6
+ * definition time.
7
+ */
8
+ import type { ZodType } from 'zod';
9
+ import type { Command, CommandConfig } from './types.js';
10
+ /**
11
+ * Create a typed Command from a CommandConfig.
12
+ *
13
+ * Validates at definition time:
14
+ * - Variadic args (z.array()) must be the last positional arg
15
+ * - meta.options keys must be a subset of options keys
16
+ *
17
+ * Returns a branded Command object with full generic inference preserved.
18
+ */
19
+ export declare function defineCommand<TArgs extends Record<string, ZodType> = Record<string, ZodType>, TOptions extends Record<string, ZodType> = Record<string, ZodType>, TOutput extends ZodType | undefined = undefined>(config: CommandConfig<TArgs, TOptions, TOutput>): Command;
20
+ //# sourceMappingURL=command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAGnC,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAA2B,MAAM,YAAY,CAAC;AA6BlF;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC5B,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/D,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClE,OAAO,SAAS,OAAO,GAAG,SAAS,GAAG,SAAS,EAC9C,MAAM,EAAE,aAAa,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,GAAG,OAAO,CAkB1D"}
@@ -0,0 +1,46 @@
1
+ import { RunaError } from './errors.js';
2
+ import { validateVariadicArgs } from './parse/variadic.js';
3
+ // ─── Definition-time validation ─────────────────────────────
4
+ /**
5
+ * Validate that keys in meta.options are a subset of the options schema keys.
6
+ * This is a runtime complement to TypeScript's compile-time constraint.
7
+ */
8
+ function validateMetaOptionsKeys(meta, options) {
9
+ if (!meta.options)
10
+ return;
11
+ const optionKeys = options ? new Set(Object.keys(options)) : new Set();
12
+ for (const key of Object.keys(meta.options)) {
13
+ if (!optionKeys.has(key)) {
14
+ throw new RunaError(`meta.options contains key '${key}' that is not defined in options. ` +
15
+ `Available keys: ${optionKeys.size > 0 ? [...optionKeys].map((k) => `'${k}'`).join(', ') : '(none)'}.`, { code: 'INVALID_META_OPTIONS', exitCode: 1 });
16
+ }
17
+ }
18
+ }
19
+ // ─── Public API ─────────────────────────────────────────────
20
+ /**
21
+ * Create a typed Command from a CommandConfig.
22
+ *
23
+ * Validates at definition time:
24
+ * - Variadic args (z.array()) must be the last positional arg
25
+ * - meta.options keys must be a subset of options keys
26
+ *
27
+ * Returns a branded Command object with full generic inference preserved.
28
+ */
29
+ export function defineCommand(config) {
30
+ // Validate variadic args at definition time
31
+ if (config.args) {
32
+ validateVariadicArgs(config.args);
33
+ }
34
+ // Validate meta.options keys match options keys
35
+ validateMetaOptionsKeys(config.meta, config.options);
36
+ // Construct branded Command object
37
+ return {
38
+ _type: 'runa:command',
39
+ meta: config.meta,
40
+ args: config.args,
41
+ options: config.options,
42
+ output: config.output,
43
+ run: config.run,
44
+ };
45
+ }
46
+ //# sourceMappingURL=command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAG3D,+DAA+D;AAE/D;;;GAGG;AACH,SAAS,uBAAuB,CAC/B,IAA2B,EAC3B,OAAkB;IAElB,IAAI,CAAC,IAAI,CAAC,OAAO;QAAE,OAAO;IAE1B,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAU,CAAC;IAE/E,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,SAAS,CAClB,8BAA8B,GAAG,oCAAoC;gBACpE,mBAAmB,UAAU,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,EACvG,EAAE,IAAI,EAAE,sBAAsB,EAAE,QAAQ,EAAE,CAAC,EAAE,CAC7C,CAAC;QACH,CAAC;IACF,CAAC;AACF,CAAC;AAED,+DAA+D;AAE/D;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAI3B,MAA+C;IAChD,4CAA4C;IAC5C,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QACjB,oBAAoB,CAAC,MAAM,CAAC,IAA+B,CAAC,CAAC;IAC9D,CAAC;IAED,gDAAgD;IAChD,uBAAuB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAErD,mCAAmC;IACnC,OAAO;QACN,KAAK,EAAE,cAAuB;QAC9B,IAAI,EAAE,MAAM,CAAC,IAAmB;QAChC,IAAI,EAAE,MAAM,CAAC,IAA2C;QACxD,OAAO,EAAE,MAAM,CAAC,OAA8C;QAC9D,MAAM,EAAE,MAAM,CAAC,MAA6B;QAC5C,GAAG,EAAE,MAAM,CAAC,GAAmC;KAC/C,CAAC;AACH,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { ConfigLoader } from '../types.js';
2
+ export type { ConfigLoader } from '../types.js';
3
+ /**
4
+ * Built-in JSON config file loader.
5
+ * Reads the file and parses it with JSON.parse().
6
+ * Wraps parse errors with a descriptive message including file path.
7
+ */
8
+ export declare function jsonLoader(): ConfigLoader;
9
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIhD;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,YAAY,CAsBzC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * @runa-cmd/core — Config file loader
3
+ *
4
+ * ConfigLoader interface + built-in JSON loader.
5
+ * Uses node:fs/promises for zero runtime dependencies.
6
+ */
7
+ import { readFile } from 'node:fs/promises';
8
+ // ─── Public API ─────────────────────────────────────────────
9
+ /**
10
+ * Built-in JSON config file loader.
11
+ * Reads the file and parses it with JSON.parse().
12
+ * Wraps parse errors with a descriptive message including file path.
13
+ */
14
+ export function jsonLoader() {
15
+ return {
16
+ extensions: ['.json'],
17
+ async load(filePath) {
18
+ let content;
19
+ try {
20
+ content = await readFile(filePath, 'utf-8');
21
+ }
22
+ catch (err) {
23
+ throw new Error(`Failed to read config file '${filePath}': ${err instanceof Error ? err.message : String(err)}`);
24
+ }
25
+ try {
26
+ return JSON.parse(content);
27
+ }
28
+ catch (err) {
29
+ throw new Error(`Invalid JSON in config file '${filePath}': ${err instanceof Error ? err.message : String(err)}`);
30
+ }
31
+ },
32
+ };
33
+ }
34
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAM5C,+DAA+D;AAE/D;;;;GAIG;AACH,MAAM,UAAU,UAAU;IACzB,OAAO;QACN,UAAU,EAAE,CAAC,OAAO,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,QAAgB;YAC1B,IAAI,OAAe,CAAC;YACpB,IAAI,CAAC;gBACJ,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC7C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,MAAM,IAAI,KAAK,CACd,+BAA+B,QAAQ,MAAM,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAC/F,CAAC;YACH,CAAC;YAED,IAAI,CAAC;gBACJ,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAY,CAAC;YACvC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,MAAM,IAAI,KAAK,CACd,gCAAgC,QAAQ,MAAM,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAChG,CAAC;YACH,CAAC;QACF,CAAC;KACD,CAAC;AACH,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @runa-cmd/core — Config loading orchestration
3
+ *
4
+ * Searches for a config file using registered loaders, loads it,
5
+ * and returns the raw config values. The actual merge priority
6
+ * (CLI > env > config > defaults) is handled in resolve.ts.
7
+ */
8
+ import type { CLIConfigOptions } from '../types.js';
9
+ /**
10
+ * Load config values from a config file, if found.
11
+ *
12
+ * 1. Combines built-in JSON loader with any additional loaders
13
+ * 2. Searches configured paths for matching config files
14
+ * 3. Loads and returns the parsed config
15
+ * 4. Returns undefined if no config file found
16
+ */
17
+ export declare function loadAndMergeConfig(configOptions: CLIConfigOptions): Promise<Record<string, unknown> | undefined>;
18
+ //# sourceMappingURL=merge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/config/merge.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAMpD;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACvC,aAAa,EAAE,gBAAgB,GAC7B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CA0B9C"}
@@ -0,0 +1,31 @@
1
+ import { jsonLoader } from './loader.js';
2
+ import { searchConfig } from './search.js';
3
+ // ─── Public API ─────────────────────────────────────────────
4
+ /**
5
+ * Load config values from a config file, if found.
6
+ *
7
+ * 1. Combines built-in JSON loader with any additional loaders
8
+ * 2. Searches configured paths for matching config files
9
+ * 3. Loads and returns the parsed config
10
+ * 4. Returns undefined if no config file found
11
+ */
12
+ export async function loadAndMergeConfig(configOptions) {
13
+ // Combine built-in JSON loader with additional loaders
14
+ const builtInLoader = jsonLoader();
15
+ const allLoaders = [builtInLoader, ...(configOptions.loaders ?? [])];
16
+ // Default search paths: current dir, then home dir
17
+ const searchPaths = configOptions.searchPaths ?? ['.', '~'];
18
+ // Search for config file
19
+ const result = await searchConfig(configOptions.name, allLoaders, searchPaths);
20
+ if (!result) {
21
+ return undefined;
22
+ }
23
+ // Load and return config values
24
+ const config = await result.loader.load(result.filePath);
25
+ // Config files should return plain objects
26
+ if (config === null || typeof config !== 'object' || Array.isArray(config)) {
27
+ throw new Error(`Config file '${result.filePath}' must export a plain object, got ${Array.isArray(config) ? 'array' : typeof config}.`);
28
+ }
29
+ return config;
30
+ }
31
+ //# sourceMappingURL=merge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.js","sourceRoot":"","sources":["../../src/config/merge.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,+DAA+D;AAE/D;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACvC,aAA+B;IAE/B,uDAAuD;IACvD,MAAM,aAAa,GAAG,UAAU,EAAE,CAAC;IACnC,MAAM,UAAU,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,aAAa,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;IAErE,mDAAmD;IACnD,MAAM,WAAW,GAAG,aAAa,CAAC,WAAW,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAE5D,yBAAyB;IACzB,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;IAE/E,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,gCAAgC;IAChC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEzD,2CAA2C;IAC3C,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5E,MAAM,IAAI,KAAK,CACd,gBAAgB,MAAM,CAAC,QAAQ,qCAAqC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,MAAM,GAAG,CACtH,CAAC;IACH,CAAC;IAED,OAAO,MAAiC,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { ConfigLoader } from '../types.js';
2
+ export interface SearchResult {
3
+ filePath: string;
4
+ loader: ConfigLoader;
5
+ }
6
+ /**
7
+ * Search for a config file in the given paths.
8
+ *
9
+ * For each search path, for each loader, checks if
10
+ * `{path}/{name}.config{ext}` exists.
11
+ *
12
+ * Search paths are checked in order; first match wins.
13
+ * '~' is resolved to os.homedir().
14
+ *
15
+ * Returns null if no config file is found (not an error).
16
+ */
17
+ export declare function searchConfig(name: string, loaders: ConfigLoader[], searchPaths: string[]): Promise<SearchResult | null>;
18
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/config/search.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIhD,MAAM,WAAW,YAAY;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,YAAY,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CACjC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,YAAY,EAAE,EACvB,WAAW,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAmB9B"}