@farmslot/recipe-harness 0.3.2 → 0.4.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 (49) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +46 -0
  3. package/dist/adapters/app-lifecycle.d.ts +41 -0
  4. package/dist/adapters/app-lifecycle.d.ts.map +1 -0
  5. package/dist/adapters/app-lifecycle.js +203 -0
  6. package/dist/adapters/app-lifecycle.js.map +1 -0
  7. package/dist/cli/flows-command.d.ts +3 -0
  8. package/dist/cli/flows-command.d.ts.map +1 -0
  9. package/dist/cli/flows-command.js +145 -0
  10. package/dist/cli/flows-command.js.map +1 -0
  11. package/dist/cli/index.d.ts.map +1 -1
  12. package/dist/cli/index.js +2 -0
  13. package/dist/cli/index.js.map +1 -1
  14. package/dist/cli/run-command.d.ts.map +1 -1
  15. package/dist/cli/run-command.js +7 -0
  16. package/dist/cli/run-command.js.map +1 -1
  17. package/dist/cli/support.d.ts +4 -2
  18. package/dist/cli/support.d.ts.map +1 -1
  19. package/dist/cli/support.js +7 -3
  20. package/dist/cli/support.js.map +1 -1
  21. package/dist/cli/validate-command.d.ts.map +1 -1
  22. package/dist/cli/validate-command.js +7 -0
  23. package/dist/cli/validate-command.js.map +1 -1
  24. package/dist/core/flows.d.ts +6 -0
  25. package/dist/core/flows.d.ts.map +1 -1
  26. package/dist/core/flows.js +12 -6
  27. package/dist/core/flows.js.map +1 -1
  28. package/dist/core/library.d.ts +72 -0
  29. package/dist/core/library.d.ts.map +1 -0
  30. package/dist/core/library.js +240 -0
  31. package/dist/core/library.js.map +1 -0
  32. package/dist/core/promote.d.ts +41 -0
  33. package/dist/core/promote.d.ts.map +1 -0
  34. package/dist/core/promote.js +249 -0
  35. package/dist/core/promote.js.map +1 -0
  36. package/dist/core/runner.d.ts.map +1 -1
  37. package/dist/core/runner.js +62 -3
  38. package/dist/core/runner.js.map +1 -1
  39. package/dist/core/types.d.ts +46 -0
  40. package/dist/core/types.d.ts.map +1 -1
  41. package/dist/core/validation.d.ts +2 -2
  42. package/dist/core/validation.d.ts.map +1 -1
  43. package/dist/core/validation.js +2 -2
  44. package/dist/core/validation.js.map +1 -1
  45. package/dist/index.d.ts +6 -0
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +3 -0
  48. package/dist/index.js.map +1 -1
  49. package/package.json +6 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,21 @@ All notable changes to `@farmslot/recipe-harness` are tracked here.
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ - Active-development baseline; add user-facing changes here before release or package publication.
8
+
9
+ ## 0.4.0 - 2026-07-07
10
+
11
+ - Add a standard outer `app.lifecycle` adapter for Android and iOS simulator launch/foreground/terminate/restart lifecycle control, with Android background support for performance recipes. Exported as `@farmslot/recipe-harness/adapters/app-lifecycle`.
12
+
13
+ ## 0.3.3 - 2026-07-03
14
+
15
+ - `resolved-flows.json` is emitted whenever a run had any library resolution activity (used, overridden, or shadowed flows) — previously a run that overrode every library flow with recipe-local declarations produced no artifact even though `summary.json` recorded the overrides
16
+ - `flows promote` fails loudly, naming every offending catalog file, when the target library already declares the ref in more than one catalog (pre-existing corruption); `--force` no longer overwrites just one of the duplicates and leaves the library unloadable
17
+ - Multi-source recipe library resolution: `call` refs can resolve from ordered, named library sources (`--library name=path`, `RECIPE_LIBRARY_PATH`, or the personal library at `<farmslot home>/recipe-library`). First source wins; recipe-local flows always win. Nothing resolves silently for any consumer: cross-source shadowing and recipe-local overrides are recorded in `summary.json` `flowResolution` (`shadowed`, `overrides`) and in the `resolved-flows.json` artifact alongside the used definitions, in addition to logging
18
+ - `farmslot-recipe flows list` — list library flows with source, description, required params, and last-verified date across configured sources; exits non-zero when no source is configured
19
+ - `farmslot-recipe validate --library` — validate accepts library-resolved `call` refs with the same source resolution as run
20
+ - `farmslot-recipe flows promote` — promote an inline flow from a per-change recipe into a recipe library (default: the personal library, created on first promote). Enforces the catalog contract (description required, postcondition required for `ensure_*`), stamps `provenance.promotedFrom`/`promotedAt`, and stamps `lastVerified` only from a passing run's artifacts (`--run <dir>`)
21
+
7
22
  ## 0.3.2 - 2026-06-30
8
23
 
9
24
  - Document `orchestrateRuntimeUp` `build` decision as terminal — hosts must call again after native build finishes.
package/README.md CHANGED
@@ -140,6 +140,52 @@ yarn workspace @farmslot/recipe-harness build
140
140
  yarn workspace @farmslot/recipe-harness farmslot-recipe --help
141
141
  ```
142
142
 
143
+ ## Recipe libraries
144
+
145
+ A recipe library is a directory (or repo) of reusable flow catalogs a `call`
146
+ node can resolve without the recipe declaring a `uses` path:
147
+
148
+ ```text
149
+ <library-root>/
150
+ library.json { "kind": "recipe-library", "schema_version": 1, "name": "personal" }
151
+ flows/*.flows.json standard recipe-flow-catalog documents
152
+ ```
153
+
154
+ Sources are named and ordered; the first source that declares a flow ref wins.
155
+ Configure them per run with repeatable `--library name=path` flags or the
156
+ `RECIPE_LIBRARY_PATH` environment variable (colon-separated, same entry
157
+ format). When neither is set, the harness uses the personal library at
158
+ `<farmslot home>/recipe-library` (`FARMSLOT_HOME`, default `~/.farmslot`) if it
159
+ exists. Recipe-local declarations (inline `flows` and explicit `uses`
160
+ catalogs) always win over library sources.
161
+
162
+ Resolution is never silent: shadowed declarations are logged, `summary.json`
163
+ gains a `flowResolution` block naming each used library flow's source, and the
164
+ artifact package includes `resolved-flows.json` with the exact definitions the
165
+ run executed, so evidence stays reviewable without access to the libraries.
166
+
167
+ ```bash
168
+ farmslot-recipe flows list --library personal=~/.farmslot/recipe-library
169
+ farmslot-recipe run recipe.json --artifacts-dir artifacts \
170
+ --action-manifest action-manifest.json \
171
+ --library personal=~/.farmslot/recipe-library --library team=../team-recipes
172
+ ```
173
+
174
+ Per-change recipes stay throwaway; `flows promote` is the explicit keep step
175
+ that moves a proven inline flow into a library as a durable contract:
176
+
177
+ ```bash
178
+ farmslot-recipe flows promote --from recipe.json --flow demo.write-marker \
179
+ --run artifacts # stamps provenance.lastVerified from the passing run
180
+ ```
181
+
182
+ Promotion requires a `description`, requires a `postcondition` for `ensure_*`
183
+ flows, and stamps provenance (origin recipe, promotion date, last-verified
184
+ evidence). The default target is the personal library (created on first
185
+ promote); promote into a team library by configuring it as a source and
186
+ passing `--to <name>` — sharing personal flows with a team is just a PR to the
187
+ team's library repo.
188
+
143
189
  ## Custom adapter
144
190
 
145
191
  ```ts
@@ -0,0 +1,41 @@
1
+ import type { ActionAdapter, ActionExecutionContext } from '../core/types.js';
2
+ export type AppLifecyclePlatform = 'android' | 'ios-simulator';
3
+ export type AppLifecycleCommand = 'launch' | 'foreground' | 'background' | 'terminate' | 'restart';
4
+ export interface AppLifecycleTarget {
5
+ platform: AppLifecyclePlatform;
6
+ /** Android adb serial or iOS simulator UDID/name. */
7
+ deviceId?: string;
8
+ /** Android package name or iOS bundle id. */
9
+ appId: string;
10
+ /** Optional deep link used for Expo/dev-client launch and foreground. */
11
+ launchUrl?: string;
12
+ /** Optional Metro port to reverse on Android before opening Expo/dev-client. */
13
+ metroPort?: string | number;
14
+ /** Optional host-side calls to run immediately before launch/foreground. */
15
+ prelaunchCalls?: AppLifecycleCall[];
16
+ }
17
+ export interface AppLifecycleExecResult {
18
+ stdout?: string;
19
+ stderr?: string;
20
+ }
21
+ export interface AppLifecycleCommandRunner {
22
+ execFile(file: string, args: string[], options?: {
23
+ timeoutMs?: number;
24
+ }): Promise<AppLifecycleExecResult>;
25
+ }
26
+ export interface AppLifecycleCall {
27
+ file: string;
28
+ args: string[];
29
+ ignoreFailureWhenOutputIncludes?: string[];
30
+ }
31
+ export interface AppLifecycleTargetProvider {
32
+ resolveTarget(node: Record<string, unknown>, context: ActionExecutionContext): Promise<AppLifecycleTarget> | AppLifecycleTarget;
33
+ }
34
+ export interface CreateAppLifecycleAdapterOptions {
35
+ actions?: Iterable<string>;
36
+ targetProvider: AppLifecycleTargetProvider;
37
+ commandRunner?: AppLifecycleCommandRunner;
38
+ }
39
+ export declare function createAppLifecycleAdapters(options: CreateAppLifecycleAdapterOptions): ActionAdapter[];
40
+ export declare function createAppLifecycleAdapter(options: CreateAppLifecycleAdapterOptions): ActionAdapter;
41
+ //# sourceMappingURL=app-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-lifecycle.d.ts","sourceRoot":"","sources":["../../src/adapters/app-lifecycle.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAI9E,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,eAAe,CAAC;AAE/D,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,YAAY,GAAG,YAAY,GAAG,WAAW,GAAG,SAAS,CAAC;AAEnG,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,4EAA4E;IAC5E,cAAc,CAAC,EAAE,gBAAgB,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CACN,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAC/B,OAAO,CAAC,sBAAsB,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,+BAA+B,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5C;AAED,MAAM,WAAW,0BAA0B;IACzC,aAAa,CACX,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,kBAAkB,CAAC,GAAG,kBAAkB,CAAC;CACrD;AAED,MAAM,WAAW,gCAAgC;IAC/C,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC3B,cAAc,EAAE,0BAA0B,CAAC;IAC3C,aAAa,CAAC,EAAE,yBAAyB,CAAC;CAC3C;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,gCAAgC,GACxC,aAAa,EAAE,CAGjB;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,gCAAgC,GACxC,aAAa,CA4Cf"}
@@ -0,0 +1,203 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ import { asNumber, asOptionalString } from '../core/json.js';
4
+ const execFileAsync = promisify(execFile);
5
+ export function createAppLifecycleAdapters(options) {
6
+ if (options.actions && !new Set(options.actions).has('app.lifecycle'))
7
+ return [];
8
+ return [createAppLifecycleAdapter(options)];
9
+ }
10
+ export function createAppLifecycleAdapter(options) {
11
+ const commandRunner = options.commandRunner ?? defaultCommandRunner();
12
+ return {
13
+ action: 'app.lifecycle',
14
+ async execute(node, context) {
15
+ // Validate every node input before resolving the target or running any
16
+ // command, so a bad knob can never fail the action after side effects.
17
+ const command = parseLifecycleCommand(node);
18
+ const timeoutMs = optionalIntegerInRange(node.timeout_ms, 'app.lifecycle.timeout_ms', 0, Number.MAX_SAFE_INTEGER);
19
+ const settleMs = optionalIntegerInRange(node.settle_ms, 'app.lifecycle.settle_ms', 0, 60_000);
20
+ const target = await options.targetProvider.resolveTarget(node, context);
21
+ const calls = lifecycleCalls(command, target);
22
+ const results = [];
23
+ for (const call of calls) {
24
+ const result = await execLifecycleCall(commandRunner, call, timeoutMs);
25
+ results.push({
26
+ file: call.file,
27
+ args: call.args,
28
+ stdout: result.stdout ?? '',
29
+ stderr: result.stderr ?? '',
30
+ ignoredFailure: result.ignoredFailure ?? false,
31
+ });
32
+ }
33
+ if (settleMs !== undefined) {
34
+ await new Promise((resolve) => setTimeout(resolve, settleMs));
35
+ }
36
+ return {
37
+ output: {
38
+ command,
39
+ platform: target.platform,
40
+ deviceId: target.deviceId ?? null,
41
+ appId: target.appId,
42
+ launchUrl: target.launchUrl ?? null,
43
+ calls: results,
44
+ settleMs: settleMs ?? 0,
45
+ },
46
+ };
47
+ },
48
+ };
49
+ }
50
+ function parseLifecycleCommand(node) {
51
+ // `event` and `state` are accepted as aliases for `command` so recipes can use
52
+ // the field name that reads best for their flow (e.g. state: background).
53
+ const raw = asOptionalString(node.command, 'app.lifecycle.command') ??
54
+ asOptionalString(node.event, 'app.lifecycle.event') ??
55
+ asOptionalString(node.state, 'app.lifecycle.state');
56
+ if (!raw) {
57
+ throw new Error('app.lifecycle.command must be explicit (aliases: event, state). Supported commands: launch, foreground, background, terminate, restart.');
58
+ }
59
+ const command = raw;
60
+ if (command === 'launch' ||
61
+ command === 'foreground' ||
62
+ command === 'background' ||
63
+ command === 'terminate' ||
64
+ command === 'restart') {
65
+ return command;
66
+ }
67
+ throw new Error(`Unsupported app.lifecycle command: ${command}. Supported commands: launch, foreground, background, terminate, restart.`);
68
+ }
69
+ function lifecycleCalls(command, target) {
70
+ if (!target.appId || !target.appId.trim()) {
71
+ throw new Error('app.lifecycle target requires appId.');
72
+ }
73
+ if (command === 'restart') {
74
+ return [
75
+ ...lifecycleCalls('terminate', target),
76
+ ...(target.prelaunchCalls ?? []),
77
+ ...lifecycleCalls('launch', target),
78
+ ];
79
+ }
80
+ if (command === 'launch' || command === 'foreground') {
81
+ return [...(target.prelaunchCalls ?? []), ...lifecyclePlatformCalls(command, target)];
82
+ }
83
+ return lifecyclePlatformCalls(command, target);
84
+ }
85
+ function lifecyclePlatformCalls(command, target) {
86
+ if (target.platform === 'android')
87
+ return androidLifecycleCalls(command, target);
88
+ if (target.platform === 'ios-simulator')
89
+ return iosSimulatorLifecycleCalls(command, target);
90
+ throw new Error(`Unsupported app.lifecycle platform: ${String(target.platform)}`);
91
+ }
92
+ function androidLifecycleCalls(command, target) {
93
+ const adb = 'adb';
94
+ const serialArgs = target.deviceId ? ['-s', target.deviceId] : [];
95
+ if (command === 'background') {
96
+ return [{ file: adb, args: [...serialArgs, 'shell', 'input', 'keyevent', 'HOME'] }];
97
+ }
98
+ if (command === 'terminate') {
99
+ return [{ file: adb, args: [...serialArgs, 'shell', 'am', 'force-stop', target.appId] }];
100
+ }
101
+ if (target.launchUrl) {
102
+ const calls = [];
103
+ if (target.metroPort !== undefined && target.metroPort !== '') {
104
+ const port = String(target.metroPort);
105
+ calls.push({
106
+ file: adb,
107
+ args: [...serialArgs, 'reverse', `tcp:${port}`, `tcp:${port}`],
108
+ });
109
+ }
110
+ calls.push({
111
+ file: adb,
112
+ args: [
113
+ ...serialArgs,
114
+ 'shell',
115
+ 'am',
116
+ 'start',
117
+ '-a',
118
+ 'android.intent.action.VIEW',
119
+ '-d',
120
+ target.launchUrl,
121
+ ],
122
+ });
123
+ return calls;
124
+ }
125
+ return [
126
+ {
127
+ file: adb,
128
+ args: [
129
+ ...serialArgs,
130
+ 'shell',
131
+ 'monkey',
132
+ '-p',
133
+ target.appId,
134
+ '-c',
135
+ 'android.intent.category.LAUNCHER',
136
+ '1',
137
+ ],
138
+ },
139
+ ];
140
+ }
141
+ function iosSimulatorLifecycleCalls(command, target) {
142
+ const device = target.deviceId ?? 'booted';
143
+ if (command === 'background') {
144
+ // iOS Simulator has no direct HOME equivalent; foreground Settings to background the app under test.
145
+ return [{ file: 'xcrun', args: ['simctl', 'launch', device, 'com.apple.Preferences'] }];
146
+ }
147
+ if (command === 'terminate') {
148
+ return [
149
+ {
150
+ file: 'xcrun',
151
+ args: ['simctl', 'terminate', device, target.appId],
152
+ // simctl terminate exits non-zero when the app is already stopped; restart should remain idempotent.
153
+ ignoreFailureWhenOutputIncludes: ['not running'],
154
+ },
155
+ ];
156
+ }
157
+ if (target.launchUrl) {
158
+ return [{ file: 'xcrun', args: ['simctl', 'openurl', device, target.launchUrl] }];
159
+ }
160
+ return [{ file: 'xcrun', args: ['simctl', 'launch', device, target.appId] }];
161
+ }
162
+ async function execLifecycleCall(commandRunner, call, timeoutMs) {
163
+ try {
164
+ return await commandRunner.execFile(call.file, call.args, { timeoutMs });
165
+ }
166
+ catch (error) {
167
+ const text = error instanceof Error ? error.message : String(error);
168
+ if (call.ignoreFailureWhenOutputIncludes?.some((needle) => text.includes(needle))) {
169
+ return { stderr: text, ignoredFailure: true };
170
+ }
171
+ throw error;
172
+ }
173
+ }
174
+ function optionalIntegerInRange(value, label, min, max) {
175
+ if (value == null)
176
+ return undefined;
177
+ const number = asNumber(value, label);
178
+ if (!Number.isInteger(number) || number < min || number > max) {
179
+ throw new Error(`${label} must be an integer from ${min} through ${max}.`);
180
+ }
181
+ return number;
182
+ }
183
+ function defaultCommandRunner() {
184
+ return {
185
+ async execFile(file, args, options) {
186
+ try {
187
+ return await execFileAsync(file, args, {
188
+ timeout: options?.timeoutMs,
189
+ encoding: 'utf8',
190
+ });
191
+ }
192
+ catch (error) {
193
+ if (error instanceof Error) {
194
+ const output = error;
195
+ const details = [output.message, output.stderr, output.stdout].filter(Boolean).join('\n');
196
+ throw new Error(`${file} ${args.join(' ')} failed: ${details}`);
197
+ }
198
+ throw error;
199
+ }
200
+ },
201
+ };
202
+ }
203
+ //# sourceMappingURL=app-lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-lifecycle.js","sourceRoot":"","sources":["../../src/adapters/app-lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type Command } from 'commander';
2
+ export declare function registerFlowsCommand(program: Command): void;
3
+ //# sourceMappingURL=flows-command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flows-command.d.ts","sourceRoot":"","sources":["../../src/cli/flows-command.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AA6BzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgF3D"}
@@ -0,0 +1,145 @@
1
+ import path from 'node:path';
2
+ import { isRecord, readJsonFile } from '../core/json.js';
3
+ import { loadRecipeLibraries, personalRecipeLibraryRoot, resolveRecipeLibrarySources, } from '../core/library.js';
4
+ import { promoteRecipeFlow } from '../core/promote.js';
5
+ import { resolveRecipeCliPath } from './support.js';
6
+ export function registerFlowsCommand(program) {
7
+ const flows = program
8
+ .command('flows')
9
+ .description('Inspect flows available from configured recipe library sources');
10
+ flows
11
+ .command('list')
12
+ .description('List every library flow with its source, in precedence order')
13
+ .option('--library <entry>', 'Recipe library source as name=path or path (repeatable; order is precedence, first wins). Defaults to RECIPE_LIBRARY_PATH, then the personal library under the farmslot home.', collectRepeatable, [])
14
+ .option('--json', 'Print the flow list as JSON')
15
+ .action(async (options) => {
16
+ const sources = await resolveRecipeLibrarySources({ cliEntries: options.library });
17
+ if (sources.length === 0) {
18
+ const message = 'No recipe library sources configured. Pass --library name=path, set RECIPE_LIBRARY_PATH, or create a personal library under the farmslot home (recipe-library/library.json).';
19
+ if (options.json) {
20
+ console.log(JSON.stringify({ sources: [], flows: [] }, null, 2));
21
+ }
22
+ console.error(message);
23
+ process.exitCode = 1;
24
+ return;
25
+ }
26
+ const resolution = await loadRecipeLibraries(sources, options.json ? undefined : console);
27
+ if (options.json) {
28
+ console.log(JSON.stringify(flowsListDocument(resolution), null, 2));
29
+ return;
30
+ }
31
+ printFlowsList(resolution);
32
+ });
33
+ flows
34
+ .command('promote')
35
+ .description('Promote an inline flow from a per-change recipe into a recipe library (the durable keep behind throwaway proofs)')
36
+ .requiredOption('--from <recipe>', 'Per-change recipe declaring the flow inline')
37
+ .requiredOption('--flow <ref>', 'Flow ref to promote')
38
+ .option('--to <name>', 'Target library source name', 'personal')
39
+ .option('--library <entry>', 'Recipe library source as name=path or path (repeatable; order is precedence, first wins). Defaults to RECIPE_LIBRARY_PATH, then the personal library under the farmslot home.', collectRepeatable, [])
40
+ .option('--domain <stem>', 'Catalog file stem (defaults to the ref minus its last segment)')
41
+ .option('--run <artifactsDir>', 'Artifacts directory of a passing run that exercised the flow; stamps provenance.lastVerified')
42
+ .option('--force', 'Overwrite an existing declaration of the same ref')
43
+ .action(async (options) => {
44
+ const target = await resolvePromoteTarget(options.to, options.library);
45
+ const result = await promoteRecipeFlow({
46
+ recipePath: resolveRecipeCliPath(options.from),
47
+ flowRef: options.flow,
48
+ targetRoot: target.root,
49
+ targetName: target.name ?? options.to,
50
+ domain: options.domain,
51
+ runArtifactsDir: options.run ? resolveRecipeCliPath(options.run) : undefined,
52
+ force: options.force,
53
+ logger: console,
54
+ });
55
+ if (result.createdLibrary) {
56
+ console.log(`Created recipe library ${options.to} at ${target.root}`);
57
+ }
58
+ console.log(`Promoted ${result.ref} to ${result.catalogPath}`);
59
+ console.log(result.lastVerified
60
+ ? `lastVerified stamped from run evidence: ${result.lastVerified}`
61
+ : 'No run evidence provided (--run); the flow carries no lastVerified stamp.');
62
+ if (options.to === 'personal') {
63
+ console.log('Share it with your team by opening a PR to the team recipe library.');
64
+ }
65
+ });
66
+ }
67
+ async function resolvePromoteTarget(to, cliEntries) {
68
+ const sources = await resolveRecipeLibrarySources({ cliEntries });
69
+ const resolved = await Promise.all(sources.map(async (source) => ({
70
+ ...source,
71
+ name: source.name ?? (await libraryManifestName(source.root)),
72
+ })));
73
+ const named = resolved.find((source) => source.name === to);
74
+ if (named)
75
+ return named;
76
+ if (to === 'personal')
77
+ return { name: 'personal', root: personalRecipeLibraryRoot() };
78
+ const available = resolved.map((source) => source.name ?? source.root).join(', ') || 'none';
79
+ throw new Error(`No recipe library source named ${to} is configured (available: ${available}). Pass --library ${to}=path or set RECIPE_LIBRARY_PATH.`);
80
+ }
81
+ // Bare-path sources get their name from library.json, matching how run
82
+ // resolution names them.
83
+ async function libraryManifestName(root) {
84
+ try {
85
+ const manifest = await readJsonFile(path.join(root, 'library.json'));
86
+ if (isRecord(manifest) && typeof manifest.name === 'string' && manifest.name) {
87
+ return manifest.name;
88
+ }
89
+ }
90
+ catch {
91
+ // not a readable library; leave the source unnamed
92
+ }
93
+ return undefined;
94
+ }
95
+ function flowsListDocument(resolution) {
96
+ return {
97
+ sources: resolution.sources,
98
+ flows: [...resolution.flows.values()]
99
+ .sort((a, b) => a.ref.localeCompare(b.ref))
100
+ .map((flow) => ({
101
+ ref: flow.ref,
102
+ source: flow.source,
103
+ file: flow.file,
104
+ ...(flowDescription(flow.raw) ? { description: flowDescription(flow.raw) } : {}),
105
+ ...(requiredParams(flow.raw).length > 0
106
+ ? { requiredParams: requiredParams(flow.raw) }
107
+ : {}),
108
+ ...(flow.shadows.length > 0 ? { shadows: flow.shadows } : {}),
109
+ ...(flow.lastVerified ? { lastVerified: flow.lastVerified } : {}),
110
+ })),
111
+ };
112
+ }
113
+ function printFlowsList(resolution) {
114
+ if (resolution.flows.size === 0) {
115
+ console.log('No flows found in the configured recipe libraries.');
116
+ return;
117
+ }
118
+ for (const flow of [...resolution.flows.values()].sort((a, b) => a.ref.localeCompare(b.ref))) {
119
+ const details = [
120
+ `source=${flow.source}`,
121
+ `file=${flow.file}`,
122
+ ...(flow.lastVerified ? [`lastVerified=${flow.lastVerified}`] : []),
123
+ ...(flow.shadows.length > 0 ? [`shadows=${flow.shadows.join(',')}`] : []),
124
+ ];
125
+ console.log(`${flow.ref} ${details.join(' ')}`);
126
+ const description = flowDescription(flow.raw);
127
+ if (description)
128
+ console.log(` ${description}`);
129
+ const params = requiredParams(flow.raw);
130
+ if (params.length > 0)
131
+ console.log(` params: ${params.join(', ')}`);
132
+ }
133
+ }
134
+ function flowDescription(raw) {
135
+ return typeof raw.description === 'string' && raw.description ? raw.description : undefined;
136
+ }
137
+ function requiredParams(raw) {
138
+ if (!isRecord(raw.paramsSchema) || !Array.isArray(raw.paramsSchema.required))
139
+ return [];
140
+ return raw.paramsSchema.required.filter((entry) => typeof entry === 'string');
141
+ }
142
+ function collectRepeatable(value, previous) {
143
+ return [...previous, value];
144
+ }
145
+ //# sourceMappingURL=flows-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flows-command.js","sourceRoot":"","sources":["../../src/cli/flows-command.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,wBAAgB,0BAA0B,IAAI,OAAO,CAWpD;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAEvE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,wBAAgB,0BAA0B,IAAI,OAAO,CAYpD;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAEvE"}
package/dist/cli/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { pathToFileURL } from 'node:url';
2
2
  import { Command } from 'commander';
3
+ import { registerFlowsCommand } from './flows-command.js';
3
4
  import { registerRunCommand } from './run-command.js';
4
5
  import { registerValidateCommand } from './validate-command.js';
5
6
  const CLI_VERSION = '0.1.0';
@@ -11,6 +12,7 @@ export function createRecipeHarnessProgram() {
11
12
  .version(CLI_VERSION);
12
13
  registerValidateCommand(program);
13
14
  registerRunCommand(program);
15
+ registerFlowsCommand(program);
14
16
  return program;
15
17
  }
16
18
  export async function runRecipeHarnessCli(argv) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,MAAM,WAAW,GAAG,OAAO,CAAC;AAE5B,MAAM,UAAU,0BAA0B;IACxC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAC9B,OAAO;SACJ,IAAI,CAAC,iBAAiB,CAAC;SACvB,WAAW,CAAC,gCAAgC,CAAC;SAC7C,OAAO,CAAC,WAAW,CAAC,CAAC;IAExB,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAE5B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAAc;IACtD,MAAM,0BAA0B,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;AACxE,CAAC;AAED,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/E,IAAI,CAAC;QACH,MAAM,mBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,MAAM,WAAW,GAAG,OAAO,CAAC;AAE5B,MAAM,UAAU,0BAA0B;IACxC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAC9B,OAAO;SACJ,IAAI,CAAC,iBAAiB,CAAC;SACvB,WAAW,CAAC,gCAAgC,CAAC;SAC7C,OAAO,CAAC,WAAW,CAAC,CAAC;IAExB,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC5B,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAE9B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAAc;IACtD,MAAM,0BAA0B,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;AACxE,CAAC;AAED,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/E,IAAI,CAAC;QACH,MAAM,mBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"run-command.d.ts","sourceRoot":"","sources":["../../src/cli/run-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAgCzC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyCzD"}
1
+ {"version":3,"file":"run-command.d.ts","sourceRoot":"","sources":["../../src/cli/run-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAkCzC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiDzD"}
@@ -1,5 +1,6 @@
1
1
  import { getRecipeActionManifestActionNames, } from '@farmslot/protocol';
2
2
  import { createStandardCoreAdapters } from '../adapters/core.js';
3
+ import { resolveRecipeLibrarySources } from '../core/library.js';
3
4
  import { createRecipeRunner } from '../core/runner.js';
4
5
  import { parsePositiveInteger, parseRecordingTarget, readRecipeCliJsonFile, resolveRecipeCliPath, } from './support.js';
5
6
  export function registerRunCommand(program) {
@@ -10,6 +11,7 @@ export function registerRunCommand(program) {
10
11
  .requiredOption('--artifacts-dir <dir>', 'Directory where artifacts are written')
11
12
  .requiredOption('--action-manifest <manifest>', 'Runner action manifest JSON')
12
13
  .option('--project-root <dir>', 'Project root used by command/artifact adapters')
14
+ .option('--library <entry>', 'Recipe library source as name=path or path (repeatable; order is precedence, first wins). Defaults to RECIPE_LIBRARY_PATH, then the personal library under the farmslot home.', collectRepeatable, [])
13
15
  .option('--record-video [mode]', 'Record one whole-recipe MP4 when visual motion proof helps')
14
16
  .option('--record-max-fps <fps>', 'Maximum video frame rate')
15
17
  .option('--record-max-size <px>', 'Maximum recorded video dimension')
@@ -27,6 +29,7 @@ export function registerRunCommand(program) {
27
29
  }),
28
30
  logger: console,
29
31
  });
32
+ const librarySources = await resolveRecipeLibrarySources({ cliEntries: options.library });
30
33
  const result = await runner.run({
31
34
  recipePath: resolveRecipeCliPath(recipePath),
32
35
  artifactsDir: resolveRecipeCliPath(options.artifactsDir),
@@ -34,6 +37,7 @@ export function registerRunCommand(program) {
34
37
  ? resolveRecipeCliPath(options.projectRoot)
35
38
  : resolveRecipeCliPath('.'),
36
39
  recordVideo: parseRecordVideoOptions(options),
40
+ ...(librarySources.length > 0 ? { librarySources } : {}),
37
41
  });
38
42
  if (options.json) {
39
43
  console.log(JSON.stringify(result, null, 2));
@@ -46,6 +50,9 @@ export function registerRunCommand(program) {
46
50
  process.exit(1);
47
51
  });
48
52
  }
53
+ function collectRepeatable(value, previous) {
54
+ return [...previous, value];
55
+ }
49
56
  function parseRecordVideoOptions(options) {
50
57
  if (!options.recordVideo)
51
58
  return false;
@@ -1 +1 @@
1
- {"version":3,"file":"run-command.js","sourceRoot":"","sources":["../../src/cli/run-command.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run-command.js","sourceRoot":"","sources":["../../src/cli/run-command.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,kCAAkC,GAEnC,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAGvD,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,cAAc,CAAC;AAiBtB,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,OAAO;SACJ,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,8CAA8C,CAAC;SAC3D,QAAQ,CAAC,UAAU,EAAE,qBAAqB,CAAC;SAC3C,cAAc,CAAC,uBAAuB,EAAE,uCAAuC,CAAC;SAChF,cAAc,CAAC,8BAA8B,EAAE,6BAA6B,CAAC;SAC7E,MAAM,CAAC,sBAAsB,EAAE,gDAAgD,CAAC;SAChF,MAAM,CACL,mBAAmB,EACnB,+KAA+K,EAC/K,iBAAiB,EACjB,EAAc,CACf;SACA,MAAM,CAAC,uBAAuB,EAAE,4DAA4D,CAAC;SAC7F,MAAM,CAAC,wBAAwB,EAAE,0BAA0B,CAAC;SAC5D,MAAM,CAAC,wBAAwB,EAAE,kCAAkC,CAAC;SACpE,MAAM,CAAC,0BAA0B,EAAE,qCAAqC,CAAC;SACzE,MAAM,CAAC,kCAAkC,EAAE,mDAAmD,CAAC;SAC/F,MAAM,CAAC,yBAAyB,EAAE,mDAAmD,CAAC;SACtF,MAAM,CAAC,oBAAoB,EAAE,uCAAuC,CAAC;SACrE,MAAM,CAAC,QAAQ,EAAE,0BAA0B,CAAC;SAC5C,MAAM,CAAC,KAAK,EAAE,UAAkB,EAAE,OAA0B,EAAE,EAAE;QAC/D,MAAM,QAAQ,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACrE,MAAM,MAAM,GAAG,kBAAkB,CAAC;YAChC,cAAc,EAAE,QAAwC;YACxD,QAAQ,EAAE,0BAA0B,CAAC;gBACnC,OAAO,EAAE,kCAAkC,CAAC,QAAQ,CAAC;aACtD,CAAC;YACF,MAAM,EAAE,OAAO;SAChB,CAAC,CAAC;QACH,MAAM,cAAc,GAAG,MAAM,2BAA2B,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1F,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC;YAC9B,UAAU,EAAE,oBAAoB,CAAC,UAAU,CAAC;YAC5C,YAAY,EAAE,oBAAoB,CAAC,OAAO,CAAC,YAAY,CAAC;YACxD,WAAW,EAAE,OAAO,CAAC,WAAW;gBAC9B,CAAC,CAAC,oBAAoB,CAAC,OAAO,CAAC,WAAW,CAAC;gBAC3C,CAAC,CAAC,oBAAoB,CAAC,GAAG,CAAC;YAC7B,WAAW,EAAE,uBAAuB,CAAC,OAAO,CAAC;YAC7C,GAAG,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACzD,CAAC,CAAC;QACH,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;YAC5C,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,oBAAoB,EAAE,CAAC,CAAC;QAC3D,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM;YAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;AACP,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAa,EAAE,QAAkB;IAC1D,OAAO,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,uBAAuB,CAAC,OAA0B;IACzD,IAAI,CAAC,OAAO,CAAC,WAAW;QAAE,OAAO,KAAK,CAAC;IACvC,MAAM,IAAI,GACR,OAAO,OAAO,CAAC,WAAW,KAAK,QAAQ,IAAI,OAAO,CAAC,WAAW,KAAK,MAAM;QACvE,CAAC,CAAC,OAAO,CAAC,WAAW;QACrB,CAAC,CAAC,UAAU,CAAC;IACjB,IAAI,IAAI,KAAK,cAAc,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CACb,4GAA4G,CAC7G,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,KAAK,UAAU,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,MAAM,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC7C,OAAO;QACL,IAAI;QACJ,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,oBAAoB,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvF,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,oBAAoB,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1F,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9B,CAAC;AACJ,CAAC"}
@@ -1,11 +1,13 @@
1
1
  import { type RecipeValidationResult } from '@farmslot/protocol';
2
- import type { RecordingTarget } from '../core/types.js';
2
+ import type { RecipeLibrarySource, RecordingTarget } from '../core/types.js';
3
3
  interface RecipeValidationInputOptions {
4
4
  recipePath: string;
5
5
  actionManifestPath?: string;
6
6
  artifactManifestPath?: string;
7
7
  artifactDir?: string;
8
8
  baseDir?: string;
9
+ /** Library sources whose flow refs count as resolvable, mirroring run resolution. */
10
+ librarySources?: RecipeLibrarySource[];
9
11
  }
10
12
  interface RecipeCliRecordingTargetOptions {
11
13
  recordAppName?: string;
@@ -18,6 +20,6 @@ export declare function resolveRecipeCliPath(filePath: string, baseDir?: string)
18
20
  export declare function parsePositiveInteger(value: string): number;
19
21
  export declare function parseRecordingTarget(options: RecipeCliRecordingTargetOptions): RecordingTarget | undefined;
20
22
  export declare function readRecipeCliJsonFile(filePath: string, baseDir?: string): Promise<unknown>;
21
- export declare function validateRecipeCliInput({ recipePath, actionManifestPath, artifactManifestPath, artifactDir, baseDir, }: RecipeValidationInputOptions): Promise<RecipeValidationResult>;
23
+ export declare function validateRecipeCliInput({ recipePath, actionManifestPath, artifactManifestPath, artifactDir, baseDir, librarySources, }: RecipeValidationInputOptions): Promise<RecipeValidationResult>;
22
24
  export {};
23
25
  //# sourceMappingURL=support.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"support.d.ts","sourceRoot":"","sources":["../../src/cli/support.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,sBAAsB,EAK5B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,UAAU,4BAA4B;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,+BAA+B;IACvC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,SAAqB,GAAG,MAAM,CAE3F;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,+BAA+B,GACvC,eAAe,GAAG,SAAS,CAc7B;AAED,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,OAAO,SAAqB,GAC3B,OAAO,CAAC,OAAO,CAAC,CAUlB;AA2BD,wBAAsB,sBAAsB,CAAC,EAC3C,UAAU,EACV,kBAAkB,EAClB,oBAAoB,EACpB,WAAW,EACX,OAA4B,GAC7B,EAAE,4BAA4B,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAsChE"}
1
+ {"version":3,"file":"support.d.ts","sourceRoot":"","sources":["../../src/cli/support.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,sBAAsB,EAK5B,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAE7E,UAAU,4BAA4B;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qFAAqF;IACrF,cAAc,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACxC;AAED,UAAU,+BAA+B;IACvC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,SAAqB,GAAG,MAAM,CAE3F;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,+BAA+B,GACvC,eAAe,GAAG,SAAS,CAc7B;AAED,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,OAAO,SAAqB,GAC3B,OAAO,CAAC,OAAO,CAAC,CAUlB;AA2BD,wBAAsB,sBAAsB,CAAC,EAC3C,UAAU,EACV,kBAAkB,EAClB,oBAAoB,EACpB,WAAW,EACX,OAA4B,EAC5B,cAAc,GACf,EAAE,4BAA4B,GAAG,OAAO,CAAC,sBAAsB,CAAC,CA0ChE"}