@farmslot/recipe-harness 0.3.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -1
- package/README.md +73 -27
- package/dist/cli/flows-command.d.ts +3 -0
- package/dist/cli/flows-command.d.ts.map +1 -0
- package/dist/cli/flows-command.js +145 -0
- package/dist/cli/flows-command.js.map +1 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/run-command.d.ts.map +1 -1
- package/dist/cli/run-command.js +7 -0
- package/dist/cli/run-command.js.map +1 -1
- package/dist/cli/support.d.ts +4 -2
- package/dist/cli/support.d.ts.map +1 -1
- package/dist/cli/support.js +7 -3
- package/dist/cli/support.js.map +1 -1
- package/dist/cli/validate-command.d.ts.map +1 -1
- package/dist/cli/validate-command.js +7 -0
- package/dist/cli/validate-command.js.map +1 -1
- package/dist/core/flows.d.ts +6 -0
- package/dist/core/flows.d.ts.map +1 -1
- package/dist/core/flows.js +12 -6
- package/dist/core/flows.js.map +1 -1
- package/dist/core/library.d.ts +72 -0
- package/dist/core/library.d.ts.map +1 -0
- package/dist/core/library.js +240 -0
- package/dist/core/library.js.map +1 -0
- package/dist/core/promote.d.ts +41 -0
- package/dist/core/promote.d.ts.map +1 -0
- package/dist/core/promote.js +249 -0
- package/dist/core/promote.js.map +1 -0
- package/dist/core/runner.d.ts.map +1 -1
- package/dist/core/runner.js +62 -3
- package/dist/core/runner.js.map +1 -1
- package/dist/core/types.d.ts +49 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/validation.d.ts +2 -2
- package/dist/core/validation.d.ts.map +1 -1
- package/dist/core/validation.js +2 -2
- package/dist/core/validation.js.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/recording/capture-helper.d.ts.map +1 -1
- package/dist/recording/capture-helper.js +8 -2
- package/dist/recording/capture-helper.js.map +1 -1
- package/dist/recording/cdp-video-recorder.d.ts +9 -0
- package/dist/recording/cdp-video-recorder.d.ts.map +1 -0
- package/dist/recording/cdp-video-recorder.js +226 -0
- package/dist/recording/cdp-video-recorder.js.map +1 -0
- package/dist/runtime/cdp.d.ts +2 -0
- package/dist/runtime/cdp.d.ts.map +1 -1
- package/dist/runtime/cdp.js +19 -0
- package/dist/runtime/cdp.js.map +1 -1
- package/dist/runtime/decision-types.d.ts.map +1 -1
- package/dist/runtime/deps-readiness.d.ts.map +1 -1
- package/dist/runtime/deps-readiness.js.map +1 -1
- package/dist/runtime/log-analysis.d.ts.map +1 -1
- package/dist/runtime/log-analysis.js +4 -1
- package/dist/runtime/log-analysis.js.map +1 -1
- package/dist/runtime/metro-probe.d.ts.map +1 -1
- package/dist/runtime/metro-probe.js +4 -2
- package/dist/runtime/metro-probe.js.map +1 -1
- package/dist/runtime/orchestrate-up.d.ts.map +1 -1
- package/dist/runtime/orchestrate-up.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,21 @@ All notable changes to `@farmslot/recipe-harness` are tracked here.
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- Active-development baseline; add user-facing changes here before release or package publication.
|
|
8
|
+
|
|
9
|
+
## 0.3.3 - 2026-07-03
|
|
10
|
+
|
|
11
|
+
- `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
|
|
12
|
+
- `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
|
|
13
|
+
- 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
|
|
14
|
+
- `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
|
|
15
|
+
- `farmslot-recipe validate --library` — validate accepts library-resolved `call` refs with the same source resolution as run
|
|
16
|
+
- `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>`)
|
|
17
|
+
|
|
18
|
+
## 0.3.2 - 2026-06-30
|
|
19
|
+
|
|
20
|
+
- Document `orchestrateRuntimeUp` `build` decision as terminal — hosts must call again after native build finishes.
|
|
21
|
+
- Use the installed `capture-helper` package for capture runs.
|
|
8
22
|
|
|
9
23
|
## 0.3.1 - 2026-06-26
|
|
10
24
|
|
package/README.md
CHANGED
|
@@ -33,16 +33,16 @@ npm install @farmslot/recipe-harness @farmslot/protocol
|
|
|
33
33
|
|
|
34
34
|
## Source layout
|
|
35
35
|
|
|
36
|
-
| Path | Owns
|
|
37
|
-
| --------------- |
|
|
38
|
-
| `bin/` | Published `farmslot-recipe` executable shim.
|
|
39
|
-
| `src/index.ts` | Public package export surface.
|
|
40
|
-
| `src/core/` | Manifest-aware recipe graph execution, flow calls, predicates, HUD node shaping, and harness-local types.
|
|
41
|
-
| `src/adapters/` | Standard core and UI adapter factories.
|
|
36
|
+
| Path | Owns |
|
|
37
|
+
| --------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
|
38
|
+
| `bin/` | Published `farmslot-recipe` executable shim. |
|
|
39
|
+
| `src/index.ts` | Public package export surface. |
|
|
40
|
+
| `src/core/` | Manifest-aware recipe graph execution, flow calls, predicates, HUD node shaping, and harness-local types. |
|
|
41
|
+
| `src/adapters/` | Standard core and UI adapter factories. |
|
|
42
42
|
| `src/runtime/` | Runtime transports (CDP, browser extensions, RN bridge) and shared readiness helpers (deps, log analysis, Metro probe). |
|
|
43
|
-
| `src/node/` | Node-only artifact, trace, and summary writers.
|
|
44
|
-
| `src/cli/` | CLI entrypoint, commands, and shared CLI validation helpers.
|
|
45
|
-
| `test/` | Harness package and export-boundary tests mirroring public behavior.
|
|
43
|
+
| `src/node/` | Node-only artifact, trace, and summary writers. |
|
|
44
|
+
| `src/cli/` | CLI entrypoint, commands, and shared CLI validation helpers. |
|
|
45
|
+
| `test/` | Harness package and export-boundary tests mirroring public behavior. |
|
|
46
46
|
|
|
47
47
|
## Public import paths
|
|
48
48
|
|
|
@@ -50,24 +50,24 @@ The package exports explicit public subpaths only. Internal modules under
|
|
|
50
50
|
`src/core/`, `src/node/`, and `test/` are implementation details unless
|
|
51
51
|
listed here.
|
|
52
52
|
|
|
53
|
-
| Import path | Use for
|
|
54
|
-
| ------------------------------------------------------ |
|
|
55
|
-
| `@farmslot/recipe-harness` | Preferred root import for runner/adapters.
|
|
56
|
-
| `@farmslot/recipe-harness/runner` | Runner construction helpers.
|
|
57
|
-
| `@farmslot/recipe-harness/types` | Harness-local runtime types.
|
|
58
|
-
| `@farmslot/recipe-harness/adapters/core` | Standard backend/headless action adapters.
|
|
59
|
-
| `@farmslot/recipe-harness/adapters/ui` | Standard `ui.*` adapter shell.
|
|
60
|
-
| `@farmslot/recipe-harness/runtime/cdp` | CDP browser transport helpers.
|
|
61
|
-
| `@farmslot/recipe-harness/runtime/react-native-bridge` | React Native bridge transport helpers.
|
|
62
|
-
| `@farmslot/recipe-harness/runtime/browser-extension` | Browser-extension target helpers.
|
|
63
|
-
| `@farmslot/recipe-harness/runtime/deps-readiness` | Install fingerprint, baseline, product-marker partial checks.
|
|
64
|
-
| `@farmslot/recipe-harness/runtime/log-analysis` | Bundle-log boundaries, unresolved-module scoping, persistent bundle-error state.
|
|
65
|
-
| `@farmslot/recipe-harness/runtime/metro-probe` | Metro packager `/status` reachability probe.
|
|
66
|
-
| `@farmslot/recipe-harness/runtime/decision-types` | Portable `RuntimeDecisionReport` / action shapes for product adapters.
|
|
67
|
-
| `@farmslot/recipe-harness/runtime/orchestrate-up` | Generic install → relaunch orchestration loop for `recipe up` hosts. |
|
|
68
|
-
| `@farmslot/recipe-harness/cli` | Programmatic CLI entrypoint.
|
|
69
|
-
| `@farmslot/recipe-harness/cli/support` | Shared CLI input validation helpers.
|
|
70
|
-
| `@farmslot/recipe-harness/writers` | Node-only JSON artifact writers.
|
|
53
|
+
| Import path | Use for |
|
|
54
|
+
| ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
55
|
+
| `@farmslot/recipe-harness` | Preferred root import for runner/adapters. |
|
|
56
|
+
| `@farmslot/recipe-harness/runner` | Runner construction helpers. |
|
|
57
|
+
| `@farmslot/recipe-harness/types` | Harness-local runtime types. |
|
|
58
|
+
| `@farmslot/recipe-harness/adapters/core` | Standard backend/headless action adapters. |
|
|
59
|
+
| `@farmslot/recipe-harness/adapters/ui` | Standard `ui.*` adapter shell. |
|
|
60
|
+
| `@farmslot/recipe-harness/runtime/cdp` | CDP browser transport helpers. |
|
|
61
|
+
| `@farmslot/recipe-harness/runtime/react-native-bridge` | React Native bridge transport helpers. |
|
|
62
|
+
| `@farmslot/recipe-harness/runtime/browser-extension` | Browser-extension target helpers. |
|
|
63
|
+
| `@farmslot/recipe-harness/runtime/deps-readiness` | Install fingerprint, baseline, product-marker partial checks. |
|
|
64
|
+
| `@farmslot/recipe-harness/runtime/log-analysis` | Bundle-log boundaries, unresolved-module scoping, persistent bundle-error state. |
|
|
65
|
+
| `@farmslot/recipe-harness/runtime/metro-probe` | Metro packager `/status` reachability probe. |
|
|
66
|
+
| `@farmslot/recipe-harness/runtime/decision-types` | Portable `RuntimeDecisionReport` / action shapes for product adapters. |
|
|
67
|
+
| `@farmslot/recipe-harness/runtime/orchestrate-up` | Generic install → relaunch orchestration loop for `recipe up` hosts. `build` exits after `onLaunch` — callers re-invoke after native build completes. |
|
|
68
|
+
| `@farmslot/recipe-harness/cli` | Programmatic CLI entrypoint. |
|
|
69
|
+
| `@farmslot/recipe-harness/cli/support` | Shared CLI input validation helpers. |
|
|
70
|
+
| `@farmslot/recipe-harness/writers` | Node-only JSON artifact writers. |
|
|
71
71
|
|
|
72
72
|
## What belongs here
|
|
73
73
|
|
|
@@ -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 @@
|
|
|
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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"}
|
package/dist/cli/index.d.ts.map
CHANGED
|
@@ -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;
|
|
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) {
|
package/dist/cli/index.js.map
CHANGED
|
@@ -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;
|
|
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;
|
|
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"}
|
package/dist/cli/run-command.js
CHANGED
|
@@ -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":"AAEA,OAAO,EACL,kCAAkC,GAEnC,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAGvD,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"run-command.js","sourceRoot":"","sources":["../../src/cli/run-command.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/support.d.ts
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/cli/support.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readdir, readFile } from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { mergeRecipeValidationResults, validateArtifactManifestDocument, validateRecipeArtifactPackage, validateRecipeDocument, validateRecipeWithManifest, } from '@farmslot/protocol';
|
|
4
|
+
import { loadRecipeLibraries } from '../core/library.js';
|
|
4
5
|
export function recipeCliBaseDir() {
|
|
5
6
|
return process.env.INIT_CWD ?? process.cwd();
|
|
6
7
|
}
|
|
@@ -66,15 +67,18 @@ function parseRecipeCliJsonText(filePath, text) {
|
|
|
66
67
|
throw new Error(`Failed to parse JSON from ${filePath}: ${message}`);
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
|
-
export async function validateRecipeCliInput({ recipePath, actionManifestPath, artifactManifestPath, artifactDir, baseDir = recipeCliBaseDir(), }) {
|
|
70
|
+
export async function validateRecipeCliInput({ recipePath, actionManifestPath, artifactManifestPath, artifactDir, baseDir = recipeCliBaseDir(), librarySources, }) {
|
|
70
71
|
const recipe = await readRecipeCliJsonFile(recipePath, baseDir);
|
|
71
72
|
const results = [];
|
|
73
|
+
const validationOptions = librarySources && librarySources.length > 0
|
|
74
|
+
? { externalFlowIds: new Set((await loadRecipeLibraries(librarySources)).flows.keys()) }
|
|
75
|
+
: undefined;
|
|
72
76
|
if (actionManifestPath) {
|
|
73
77
|
const actionManifest = await readRecipeCliJsonFile(actionManifestPath, baseDir);
|
|
74
|
-
results.push(validateRecipeWithManifest(recipe, actionManifest));
|
|
78
|
+
results.push(validateRecipeWithManifest(recipe, actionManifest, validationOptions));
|
|
75
79
|
}
|
|
76
80
|
else {
|
|
77
|
-
results.push(validateRecipeDocument(recipe));
|
|
81
|
+
results.push(validateRecipeDocument(recipe, validationOptions));
|
|
78
82
|
}
|
|
79
83
|
const artifactPaths = artifactDir
|
|
80
84
|
? await listRelativeRecipeCliFiles(resolveRecipeCliPath(artifactDir, baseDir))
|
package/dist/cli/support.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"support.js","sourceRoot":"","sources":["../../src/cli/support.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EACL,4BAA4B,EAE5B,gCAAgC,EAChC,6BAA6B,EAC7B,sBAAsB,EACtB,0BAA0B,GAC3B,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"support.js","sourceRoot":"","sources":["../../src/cli/support.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EACL,4BAA4B,EAE5B,gCAAgC,EAChC,6BAA6B,EAC7B,sBAAsB,EACtB,0BAA0B,GAC3B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAoBzD,MAAM,UAAU,gBAAgB;IAC9B,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,QAAgB,EAAE,OAAO,GAAG,gBAAgB,EAAE;IACjF,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAa;IAChD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,oCAAoC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,OAAwC;IAExC,IAAI,OAAO,CAAC,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,oBAAoB,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;IAC5F,IAAI,OAAO,CAAC,cAAc;QAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC;IAC3F,IAAI,OAAO,CAAC,aAAa,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;QACtD,IAAI,CAAC,OAAO,CAAC,aAAa,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC;YACxD,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAC;QAC3F,CAAC;QACD,OAAO;YACL,IAAI,EAAE,YAAY;YAClB,OAAO,EAAE,OAAO,CAAC,aAAa;YAC9B,UAAU,EAAE,OAAO,CAAC,gBAAgB;SACrC,CAAC;IACJ,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,QAAgB,EAChB,OAAO,GAAG,gBAAgB,EAAE;IAE5B,MAAM,YAAY,GAAG,oBAAoB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC7D,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC/C,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,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,KAAK,OAAO,EAAE,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,sBAAsB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AAChD,CAAC;AAED,KAAK,UAAU,6BAA6B,CAC1C,QAAgB,EAChB,OAAO,GAAG,gBAAgB,EAAE;IAE5B,MAAM,YAAY,GAAG,oBAAoB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC7D,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,EAAE,IAAI,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAC;QAC1E,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,KAAK,OAAO,EAAE,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,sBAAsB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,sBAAsB,CAAC,QAAgB,EAAE,IAAY;IAC5D,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,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,MAAM,IAAI,KAAK,CAAC,6BAA6B,QAAQ,KAAK,OAAO,EAAE,CAAC,CAAC;IACvE,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,EAC3C,UAAU,EACV,kBAAkB,EAClB,oBAAoB,EACpB,WAAW,EACX,OAAO,GAAG,gBAAgB,EAAE,EAC5B,cAAc,GACe;IAC7B,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAChE,MAAM,OAAO,GAA6B,EAAE,CAAC;IAE7C,MAAM,iBAAiB,GACrB,cAAc,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC;QACzC,CAAC,CAAC,EAAE,eAAe,EAAE,IAAI,GAAG,CAAC,CAAC,MAAM,mBAAmB,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE;QACxF,CAAC,CAAC,SAAS,CAAC;IAChB,IAAI,kBAAkB,EAAE,CAAC;QACvB,MAAM,cAAc,GAAG,MAAM,qBAAqB,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC;QAChF,OAAO,CAAC,IAAI,CAAC,0BAA0B,CAAC,MAAM,EAAE,cAAc,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACtF,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,IAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,aAAa,GAAG,WAAW;QAC/B,CAAC,CAAC,MAAM,0BAA0B,CAAC,oBAAoB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAC9E,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,YAAY,GAChB,oBAAoB;QACpB,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,wBAAwB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAE/E,IAAI,QAAiB,CAAC;IACtB,IAAI,YAAY,EAAE,CAAC;QACjB,QAAQ,GAAG,oBAAoB;YAC7B,CAAC,CAAC,MAAM,qBAAqB,CAAC,YAAY,EAAE,OAAO,CAAC;YACpD,CAAC,CAAC,MAAM,6BAA6B,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAC/D,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,WAAW,EAAE,CAAC;YAC3C,OAAO,CAAC,IAAI,CACV,gCAAgC,CAAC,QAAQ,EAAE;gBACzC,MAAM;gBACN,aAAa;aACd,CAAC,CACH,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,CAAC,IAAI,CAAC,6BAA6B,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC;IACnF,CAAC;IAED,OAAO,4BAA4B,CAAC,OAAO,CAAC,CAAC;AAC/C,CAAC;AAED,KAAK,UAAU,0BAA0B,CAAC,IAAY;IACpD,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,KAAK,UAAU,KAAK,CAAC,WAAmB;QACtC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACrF,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YACxD,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,MAAM,KAAK,CAAC,YAAY,CAAC,CAAC;YAC5B,CAAC;iBAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC1B,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,KAAK,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;AACvB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate-command.d.ts","sourceRoot":"","sources":["../../src/cli/validate-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"validate-command.d.ts","sourceRoot":"","sources":["../../src/cli/validate-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAczC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAoC9D"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveRecipeLibrarySources } from '../core/library.js';
|
|
1
2
|
import { validateRecipeCliInput } from './support.js';
|
|
2
3
|
export function registerValidateCommand(program) {
|
|
3
4
|
program
|
|
@@ -7,13 +8,16 @@ export function registerValidateCommand(program) {
|
|
|
7
8
|
.option('--action-manifest <manifest>', 'Runner action manifest JSON')
|
|
8
9
|
.option('--artifact-manifest <manifest>', 'Artifact manifest JSON')
|
|
9
10
|
.option('--artifact-dir <dir>', 'Artifact package directory')
|
|
11
|
+
.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 — same resolution as run.', collectRepeatable, [])
|
|
10
12
|
.option('--json', 'Print validation result as JSON')
|
|
11
13
|
.action(async (recipePath, options) => {
|
|
14
|
+
const librarySources = await resolveRecipeLibrarySources({ cliEntries: options.library });
|
|
12
15
|
const result = await validateRecipeCliInput({
|
|
13
16
|
recipePath,
|
|
14
17
|
actionManifestPath: options.actionManifest,
|
|
15
18
|
artifactManifestPath: options.artifactManifest,
|
|
16
19
|
artifactDir: options.artifactDir,
|
|
20
|
+
...(librarySources.length > 0 ? { librarySources } : {}),
|
|
17
21
|
});
|
|
18
22
|
if (options.json) {
|
|
19
23
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -28,4 +32,7 @@ export function registerValidateCommand(program) {
|
|
|
28
32
|
process.exit(1);
|
|
29
33
|
});
|
|
30
34
|
}
|
|
35
|
+
function collectRepeatable(value, previous) {
|
|
36
|
+
return [...previous, value];
|
|
37
|
+
}
|
|
31
38
|
//# sourceMappingURL=validate-command.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate-command.js","sourceRoot":"","sources":["../../src/cli/validate-command.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"validate-command.js","sourceRoot":"","sources":["../../src/cli/validate-command.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAEjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAUtD,MAAM,UAAU,uBAAuB,CAAC,OAAgB;IACtD,OAAO;SACJ,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CAAC,oDAAoD,CAAC;SACjE,QAAQ,CAAC,UAAU,EAAE,qBAAqB,CAAC;SAC3C,MAAM,CAAC,8BAA8B,EAAE,6BAA6B,CAAC;SACrE,MAAM,CAAC,gCAAgC,EAAE,wBAAwB,CAAC;SAClE,MAAM,CAAC,sBAAsB,EAAE,4BAA4B,CAAC;SAC5D,MAAM,CACL,mBAAmB,EACnB,wMAAwM,EACxM,iBAAiB,EACjB,EAAc,CACf;SACA,MAAM,CAAC,QAAQ,EAAE,iCAAiC,CAAC;SACnD,MAAM,CAAC,KAAK,EAAE,UAAkB,EAAE,OAA+B,EAAE,EAAE;QACpE,MAAM,cAAc,GAAG,MAAM,2BAA2B,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1F,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC;YAC1C,UAAU;YACV,kBAAkB,EAAE,OAAO,CAAC,cAAc;YAC1C,oBAAoB,EAAE,OAAO,CAAC,gBAAgB;YAC9C,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,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,CACT,sBAAsB,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,OAAO,CAAC,MAAM,YAAY,MAAM,CAAC,OAAO,CAAC,QAAQ,YAAY,CAC7G,CAAC;YACF,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACtC,OAAO,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;YAC3F,CAAC;QACH,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS;YAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;AACP,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAa,EAAE,QAAkB;IAC1D,OAAO,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,CAAC;AAC9B,CAAC"}
|
package/dist/core/flows.d.ts
CHANGED
|
@@ -19,6 +19,12 @@ export declare function collectFlows(recipe: unknown, options: {
|
|
|
19
19
|
projectRoot: string;
|
|
20
20
|
recipeDir: string;
|
|
21
21
|
}): Promise<ReadonlyMap<string, InlineFlow>>;
|
|
22
|
+
export interface CatalogFlowEntry {
|
|
23
|
+
ref: string;
|
|
24
|
+
flow: InlineFlow;
|
|
25
|
+
raw: Record<string, unknown>;
|
|
26
|
+
}
|
|
27
|
+
export declare function readCatalogFlows(catalog: unknown, source: string): CatalogFlowEntry[];
|
|
22
28
|
export declare function executeInlineFlowCall({ callNodeId, node, context, flowCatalog, adapters, traceWriter, callStack, maxCallDepth, publishHudProgress, }: {
|
|
23
29
|
callNodeId: string;
|
|
24
30
|
node: Record<string, unknown>;
|
package/dist/core/flows.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flows.d.ts","sourceRoot":"","sources":["../../src/core/flows.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAMrD,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE9D,KAAK,gBAAgB,GAAG,CACtB,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,EACnC,KAAK,EAAE;IACL,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,UAAU,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,KACE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC/C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,OAAO,EACf,OAAO,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAClD,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAa1C;
|
|
1
|
+
{"version":3,"file":"flows.d.ts","sourceRoot":"","sources":["../../src/core/flows.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAMrD,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE9D,KAAK,gBAAgB,GAAG,CACtB,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,EACnC,KAAK,EAAE;IACL,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,UAAU,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,KACE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC/C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,OAAO,EACf,OAAO,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAClD,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAa1C;AAoCD,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,UAAU,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC9B;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAQrF;AAuBD,wBAAsB,qBAAqB,CAAC,EAC1C,UAAU,EACV,IAAI,EACJ,OAAO,EACP,WAAW,EACX,QAAQ,EACR,WAAW,EACX,SAAS,EACT,YAAY,EACZ,kBAAkB,GACnB,EAAE;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,EAAE,UAAU,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC7C,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC7C,WAAW,EAAE,eAAe,CAAC;IAC7B,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,gBAAgB,CAAC;CACvC,GAAG,OAAO,CAAC,YAAY,CAAC,CA+BxB"}
|
package/dist/core/flows.js
CHANGED
|
@@ -42,15 +42,21 @@ function resolveUsePath(catalogPath, options) {
|
|
|
42
42
|
return path.join(options.projectRoot, normalized);
|
|
43
43
|
}
|
|
44
44
|
function addCatalogFlows(flows, catalog, source) {
|
|
45
|
+
for (const entry of readCatalogFlows(catalog, source)) {
|
|
46
|
+
if (flows.has(entry.ref))
|
|
47
|
+
throw new Error(`Flow ${entry.ref} is declared more than once.`);
|
|
48
|
+
flows.set(entry.ref, entry.flow);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export function readCatalogFlows(catalog, source) {
|
|
45
52
|
if (!isRecord(catalog) || !isRecord(catalog.flows)) {
|
|
46
53
|
throw new Error(`Flow catalog ${source} must contain a flows object.`);
|
|
47
54
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
55
|
+
return Object.entries(catalog.flows).map(([ref, flow]) => {
|
|
56
|
+
if (!isRecord(flow))
|
|
57
|
+
throw new Error(`Flow ${ref} in ${source} must be an object.`);
|
|
58
|
+
return { ref, flow: normalizeFlow(ref, flow, source), raw: flow };
|
|
59
|
+
});
|
|
54
60
|
}
|
|
55
61
|
function normalizeFlow(ref, flow, source) {
|
|
56
62
|
if (!isRecord(flow))
|