@farmslot/recipe-cli 0.4.0 → 0.5.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.
- package/CHANGELOG.md +17 -0
- package/README.md +11 -11
- package/dist/harness/catalog.d.ts +71 -0
- package/dist/harness/catalog.d.ts.map +1 -0
- package/dist/harness/catalog.js +280 -0
- package/dist/harness/catalog.js.map +1 -0
- package/dist/harness/commands/call.d.ts +18 -0
- package/dist/harness/commands/call.d.ts.map +1 -0
- package/dist/harness/commands/call.js +663 -0
- package/dist/harness/commands/call.js.map +1 -0
- package/dist/harness/commands/discover.d.ts +29 -0
- package/dist/harness/commands/discover.d.ts.map +1 -0
- package/dist/harness/commands/discover.js +563 -0
- package/dist/harness/commands/discover.js.map +1 -0
- package/dist/harness/commands/run.d.ts +40 -0
- package/dist/harness/commands/run.d.ts.map +1 -0
- package/dist/harness/commands/run.js +727 -0
- package/dist/harness/commands/run.js.map +1 -0
- package/dist/harness/heal-bounds.d.ts +8 -0
- package/dist/harness/heal-bounds.d.ts.map +1 -1
- package/dist/harness/heal-bounds.js +10 -0
- package/dist/harness/heal-bounds.js.map +1 -1
- package/dist/harness/host.d.ts +5 -0
- package/dist/harness/host.d.ts.map +1 -1
- package/dist/harness/host.js +7 -0
- package/dist/harness/host.js.map +1 -1
- package/dist/harness/index.d.ts +8 -0
- package/dist/harness/index.d.ts.map +1 -1
- package/dist/harness/index.js +8 -0
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/network-observation.d.ts +19 -0
- package/dist/harness/network-observation.d.ts.map +1 -0
- package/dist/harness/network-observation.js +202 -0
- package/dist/harness/network-observation.js.map +1 -0
- package/dist/harness/recipe-library.d.ts +65 -0
- package/dist/harness/recipe-library.d.ts.map +1 -0
- package/dist/harness/recipe-library.js +182 -0
- package/dist/harness/recipe-library.js.map +1 -0
- package/dist/harness/recipe-validation.d.ts +27 -0
- package/dist/harness/recipe-validation.d.ts.map +1 -0
- package/dist/harness/recipe-validation.js +249 -0
- package/dist/harness/recipe-validation.js.map +1 -0
- package/dist/harness/run-engine.d.ts +79 -0
- package/dist/harness/run-engine.d.ts.map +1 -0
- package/dist/harness/run-engine.js +632 -0
- package/dist/harness/run-engine.js.map +1 -0
- package/dist/harness/run-observers.d.ts +13 -0
- package/dist/harness/run-observers.d.ts.map +1 -0
- package/dist/harness/run-observers.js +21 -0
- package/dist/harness/run-observers.js.map +1 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,23 @@ All notable changes to `@farmslot/recipe-cli` are tracked here.
|
|
|
6
6
|
|
|
7
7
|
- Active-development baseline; add user-facing changes here before release or package publication.
|
|
8
8
|
|
|
9
|
+
## 0.5.0 - 2026-10-05
|
|
10
|
+
|
|
11
|
+
- Add `run` and `call` to `@farmslot/recipe-cli/harness`, moved from mm-harness: `handleRun(argv, options)`, `handleCall(argv, options)` and `handleCallHelp(argv, genericHelp, { catalog })`. The host passes a `RecipeEngine` (`RecipeCatalog`: its bundled library, action manifest resolver and validator, and bundled action risk; plus `createRunner`, an optional `trustedMutation` loaded from the command line and bound to the run's plan, the `console` classifier and `runnerIncludes`), and per command `targetDevice`, the `run --plan` host steps and launch wording, and `exampleAction`. `run --list`, `run <recipe> --describe` and `call --list` read the catalog themselves. Messages name the host (`<name> call`, `<product>-checkout`).
|
|
12
|
+
- the engine door: `runRecipe`, `preflightRecipe`, `activateRecipeRuntimeEnvironment` (sets every registered adapter's `devServer.portEnv` from `--watcher-port`), bounded healing and heal-bound envelopes;
|
|
13
|
+
- the recipe library: `resolveLibrarySources`, `listRunnableRecipes`, `describeRunnableRecipe`, `runnableLibraryRecipes`;
|
|
14
|
+
- static validation: `validateRunRecipeStatic`, `validateActionInputs` (each adapter's `actions.inputFindings` on every node), `resolveRecipeParamValue`;
|
|
15
|
+
- `describeManifestActions`, the action catalog entries a host reads for its own action views;
|
|
16
|
+
- network observation through the adapter's `observation.network`: the automatic whole-run capture (off with the host's `AUTO_NETWORK_CAPTURE=0`) and `runNetworkCaptureAction` for `app.network_capture`.
|
|
17
|
+
- Add `actions` to `@farmslot/recipe-cli/harness`, moved from mm-harness: `handleActions(parsed, { catalog })` lists, searches (`[query]`), filters (`--category`, `--categories`), describes (`--action`) and dumps (`--raw`) the adapter's actions, and `--matrix` compares them across the registered adapters. `actions`, `run --list`, `call --list` and `run <recipe> --describe` share one discovery module and one catalog renderer.
|
|
18
|
+
- The matrix has one column per registered adapter, in registration order (its JSON `adapters`, the human header and column widths), and a capability no adapter declares reads `across <Adapter>, …, or <Adapter>` from the registry instead of a fixed list.
|
|
19
|
+
- `actions --action <name>` (one match, human output) and `call <action> --help` print the same action detail: the call form, description, source and adapter, risk, result cases, typed fields, up to two example calls, and the first example as a runnable call with its recipe node. The example calls carry only the action's fields (no `next`, `cases` or other graph keys), shell-quoted, under the short name when it is unambiguous. JSON output is unchanged.
|
|
20
|
+
- Publish with adapter-sdk 0.4.0, agent-runtime 0.17.0, protocol 0.34.0 and recipe-runner 0.24.0.
|
|
21
|
+
|
|
22
|
+
## 0.4.1 - 2026-10-05
|
|
23
|
+
|
|
24
|
+
- Publish with adapter-sdk 0.3.1, agent-runtime 0.17.0, protocol 0.34.0 and recipe-runner 0.24.0 so consumers share one recipe-runner copy.
|
|
25
|
+
|
|
9
26
|
## 0.4.0 - 2026-10-05
|
|
10
27
|
|
|
11
28
|
- Add run evidence to `@farmslot/recipe-cli/harness`, moved from mm-harness and driven through the registered adapters and the host identity:
|
package/README.md
CHANGED
|
@@ -29,17 +29,17 @@ Docs: https://farmslot.io/docs/reference/recipe-discovery
|
|
|
29
29
|
|
|
30
30
|
## Source layout
|
|
31
31
|
|
|
32
|
-
| path | owns
|
|
33
|
-
| --------------------------------------------------- |
|
|
34
|
-
| `src/cli.ts` | the `farmslot-recipe` program: the runner's `run`/`validate` plus discovery
|
|
35
|
-
| `src/commands.ts` | discovery command registration, JSON envelopes and errors
|
|
36
|
-
| `src/libraries.ts` | library resolution: precedence, overrides, digests, `requires` checks
|
|
37
|
-
| `src/discovery-index.ts` | the recipe and action index for one platform view
|
|
38
|
-
| `src/composition.ts` | composition, callers and `explain`
|
|
39
|
-
| `src/search.ts`, `src/template.ts`, `src/render.ts` | search ranking, skeletons, text output
|
|
40
|
-
| `src/types.ts` | the documented `--json` schema
|
|
41
|
-
| `src/harness/` | generic harness support (`@farmslot/recipe-cli/harness`): host identity, adapter registry, runtime paths, journal, checkout lock, JSON stream, colour, option parsing, leaf spawning, bounded healing,
|
|
42
|
-
| `src/harness/commands/` |
|
|
32
|
+
| path | owns |
|
|
33
|
+
| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
34
|
+
| `src/cli.ts` | the `farmslot-recipe` program: the runner's `run`/`validate` plus discovery |
|
|
35
|
+
| `src/commands.ts` | discovery command registration, JSON envelopes and errors |
|
|
36
|
+
| `src/libraries.ts` | library resolution: precedence, overrides, digests, `requires` checks |
|
|
37
|
+
| `src/discovery-index.ts` | the recipe and action index for one platform view |
|
|
38
|
+
| `src/composition.ts` | composition, callers and `explain` |
|
|
39
|
+
| `src/search.ts`, `src/template.ts`, `src/render.ts` | search ranking, skeletons, text output |
|
|
40
|
+
| `src/types.ts` | the documented `--json` schema |
|
|
41
|
+
| `src/harness/` | generic harness support (`@farmslot/recipe-cli/harness`): host identity, adapter registry, runtime paths, journal, checkout lock, JSON stream, colour, option parsing, leaf spawning, bounded healing, run evidence (execution provenance, framed recording, run diagnostics, run report, live adapter scripts, run options, trust input, behavioral proof), and the run engine (`RecipeEngine`, recipe library, static validation, action catalog, network observation) |
|
|
42
|
+
| `src/harness/commands/` | commands a host CLI dispatches to: `run`, `call`, the lifecycle (`launch`, `reload`, `stop`, `last`), and discovery (`discover.ts`: `actions`, `run --list`, `run --describe`, `call --list`); `overlay.ts` is `install`/`verify`/`cleanup` |
|
|
43
43
|
|
|
44
44
|
## Maintenance rules
|
|
45
45
|
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { type RecipeActionManifestDocument, type RecipeExecutionCapability, type RecipeSourceProvenance } from '@farmslot/protocol';
|
|
2
|
+
import type { RecipeLibrarySource } from '@farmslot/recipe-runner';
|
|
3
|
+
import { type ActionMatrixRow } from '../action-catalog.js';
|
|
4
|
+
/** Where one resolved action came from. */
|
|
5
|
+
export interface ActionCapabilitySource {
|
|
6
|
+
name: string;
|
|
7
|
+
tier: 'official' | 'personal' | 'team' | 'canonical' | 'task';
|
|
8
|
+
manifestPath: string;
|
|
9
|
+
shadows?: string[];
|
|
10
|
+
trust?: RecipeSourceProvenance['trust'];
|
|
11
|
+
implementationRoot?: string;
|
|
12
|
+
digest?: string;
|
|
13
|
+
resolveDigest?: () => Promise<string>;
|
|
14
|
+
}
|
|
15
|
+
export interface ResolvedActionManifest {
|
|
16
|
+
manifest: RecipeActionManifestDocument;
|
|
17
|
+
actionSources: Map<string, ActionCapabilitySource>;
|
|
18
|
+
}
|
|
19
|
+
export interface RecipeCatalog {
|
|
20
|
+
/** The library the host ships: its source name, root, and the namespace of its action names. */
|
|
21
|
+
bundledLibrary: {
|
|
22
|
+
name: string;
|
|
23
|
+
root: string;
|
|
24
|
+
actionNamespace: string;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* The adapter's action manifest merged across the library sources (the
|
|
28
|
+
* bundled one last), or the override manifest with its task action root.
|
|
29
|
+
*/
|
|
30
|
+
resolveActionManifest(adapter: string, overridePath?: string, sources?: readonly RecipeLibrarySource[], taskActionRoot?: string): Promise<ResolvedActionManifest>;
|
|
31
|
+
/** Throws when the manifest document is invalid. */
|
|
32
|
+
validateManifest(manifest: RecipeActionManifestDocument): Promise<unknown>;
|
|
33
|
+
/** The execution capabilities the host enforces for a bundled action. */
|
|
34
|
+
actionCapabilities(action: string): readonly RecipeExecutionCapability[];
|
|
35
|
+
}
|
|
36
|
+
export interface DescribedAction {
|
|
37
|
+
name: string;
|
|
38
|
+
kind: 'official' | 'custom';
|
|
39
|
+
category: string;
|
|
40
|
+
description: string;
|
|
41
|
+
fields: string[];
|
|
42
|
+
schema?: unknown;
|
|
43
|
+
examples?: unknown;
|
|
44
|
+
result_cases?: string[];
|
|
45
|
+
source: string;
|
|
46
|
+
sourceTier: ActionCapabilitySource['tier'];
|
|
47
|
+
sourceManifest: string;
|
|
48
|
+
shadows: string[];
|
|
49
|
+
capabilities: RecipeExecutionCapability[];
|
|
50
|
+
}
|
|
51
|
+
/** `--library` arguments that reproduce the non-bundled sources of a lookup. */
|
|
52
|
+
export declare function actionLibraryContextArgs(catalog: RecipeCatalog, librarySources?: readonly RecipeLibrarySource[]): string;
|
|
53
|
+
/** Every action across the registered adapters, with the adapters that declare it. */
|
|
54
|
+
export declare function resolveActionCapabilityMatrix(catalog: RecipeCatalog, librarySources?: readonly RecipeLibrarySource[]): Promise<ActionMatrixRow[]>;
|
|
55
|
+
export declare function describeManifestActions(catalog: RecipeCatalog, manifest: unknown, actionSources?: ReadonlyMap<string, ActionCapabilitySource>): DescribedAction[];
|
|
56
|
+
/**
|
|
57
|
+
* One action in full, as `actions --action <name>` and `call <action> --help`
|
|
58
|
+
* print it: the call form, description, source and adapter, risk, result
|
|
59
|
+
* cases, fields with their types, up to two authored examples, and the first
|
|
60
|
+
* one as a runnable call with its recipe node. `actionNames` is the adapter's
|
|
61
|
+
* vocabulary, which decides whether the short name is unambiguous.
|
|
62
|
+
*/
|
|
63
|
+
export declare function renderActionDetail(entry: DescribedAction, adapter: string, target: string, executable: string, actionNames: readonly string[]): string;
|
|
64
|
+
/** The authored example as a human block: the call that runs it and its recipe node. */
|
|
65
|
+
export declare function renderHumanActionExample(entry: DescribedAction, adapter: string, target: string, executable: string): string | undefined;
|
|
66
|
+
/**
|
|
67
|
+
* A runnable `call` for the action's authored example; `preferredValues` pick
|
|
68
|
+
* the closest example and override its values.
|
|
69
|
+
*/
|
|
70
|
+
export declare function actionExampleCommand(entry: DescribedAction, adapter: string, target: string, executable: string, preferredValues?: Record<string, unknown>): string | undefined;
|
|
71
|
+
//# sourceMappingURL=catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/harness/catalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
// The host's action catalog: where its bundled library lives, how an adapter's
|
|
2
|
+
// action manifest resolves across library sources, and the risk each bundled
|
|
3
|
+
// action carries. `run`, `call` and the discovery helpers below read actions
|
|
4
|
+
// only through it.
|
|
5
|
+
import { OFFICIAL_RECIPE_ACTIONS, officialRecipeActionCapabilities, } from '@farmslot/protocol';
|
|
6
|
+
import { actionCapabilityMatrix, actionCategory, shortActionNames, } from '../action-catalog.js';
|
|
7
|
+
import { harnessAdapters } from './adapters.js';
|
|
8
|
+
import { color } from './cli-color.js';
|
|
9
|
+
import { isSensitiveKey, redactStructuredValue } from './command-journal.js';
|
|
10
|
+
import { harnessHost } from './host.js';
|
|
11
|
+
import { isRecord, shellQuoteArg } from './parse-args.js';
|
|
12
|
+
import { closest } from './suggest.js';
|
|
13
|
+
const OFFICIAL_ACTIONS = new Set(OFFICIAL_RECIPE_ACTIONS);
|
|
14
|
+
/** `--library` arguments that reproduce the non-bundled sources of a lookup. */
|
|
15
|
+
export function actionLibraryContextArgs(catalog, librarySources) {
|
|
16
|
+
return (librarySources ?? [])
|
|
17
|
+
.filter((source) => source.name !== catalog.bundledLibrary.name)
|
|
18
|
+
.map((source) => {
|
|
19
|
+
const entry = source.name ? `${source.name}=${source.root}` : source.root;
|
|
20
|
+
return ` --library ${shellQuoteArg(entry)}`;
|
|
21
|
+
})
|
|
22
|
+
.join('');
|
|
23
|
+
}
|
|
24
|
+
/** Every action across the registered adapters, with the adapters that declare it. */
|
|
25
|
+
export async function resolveActionCapabilityMatrix(catalog, librarySources) {
|
|
26
|
+
const catalogs = await Promise.all(harnessAdapters()
|
|
27
|
+
.list()
|
|
28
|
+
.map(async (adapter) => {
|
|
29
|
+
const { manifest, actionSources } = await catalog.resolveActionManifest(adapter, undefined, librarySources);
|
|
30
|
+
return { adapter, actions: describeManifestActions(catalog, manifest, actionSources) };
|
|
31
|
+
}));
|
|
32
|
+
return actionCapabilityMatrix(catalogs);
|
|
33
|
+
}
|
|
34
|
+
export function describeManifestActions(catalog, manifest, actionSources = new Map()) {
|
|
35
|
+
const manifestRecord = isRecord(manifest) ? manifest : {};
|
|
36
|
+
const actions = isRecord(manifestRecord.actions) ? manifestRecord.actions : {};
|
|
37
|
+
return Object.entries(actions).map(([name, metadata]) => describeManifestAction(catalog, name, OFFICIAL_ACTIONS.has(name) ? 'official' : 'custom', metadata, actionSources.get(name)));
|
|
38
|
+
}
|
|
39
|
+
function describeManifestAction(catalog, name, kind, metadata, source) {
|
|
40
|
+
const record = isRecord(metadata) ? metadata : {};
|
|
41
|
+
const schema = record.schema;
|
|
42
|
+
const schemaRecord = isRecord(schema) ? schema : {};
|
|
43
|
+
const properties = isRecord(schemaRecord.properties)
|
|
44
|
+
? Object.keys(schemaRecord.properties)
|
|
45
|
+
.filter((field) => field !== 'action' && field !== 'next')
|
|
46
|
+
.sort()
|
|
47
|
+
: [];
|
|
48
|
+
return {
|
|
49
|
+
name,
|
|
50
|
+
kind,
|
|
51
|
+
category: actionCategory(name, [catalog.bundledLibrary.actionNamespace]),
|
|
52
|
+
description: typeof record.description === 'string' ? record.description : '',
|
|
53
|
+
fields: properties,
|
|
54
|
+
schema,
|
|
55
|
+
examples: record.examples,
|
|
56
|
+
...(Array.isArray(record.result_cases)
|
|
57
|
+
? {
|
|
58
|
+
result_cases: record.result_cases.filter((value) => typeof value === 'string'),
|
|
59
|
+
}
|
|
60
|
+
: {}),
|
|
61
|
+
source: source?.name ?? (kind === 'official' ? 'official' : catalog.bundledLibrary.name),
|
|
62
|
+
sourceTier: source?.tier ?? (kind === 'official' ? 'official' : 'canonical'),
|
|
63
|
+
sourceManifest: source?.manifestPath ?? '',
|
|
64
|
+
shadows: source?.shadows ?? [],
|
|
65
|
+
capabilities: [
|
|
66
|
+
...new Set([
|
|
67
|
+
...(Array.isArray(record.execution_capabilities)
|
|
68
|
+
? record.execution_capabilities.filter((value) => typeof value === 'string')
|
|
69
|
+
: []),
|
|
70
|
+
...(kind === 'official'
|
|
71
|
+
? officialRecipeActionCapabilities(name)
|
|
72
|
+
: catalog.actionCapabilities(name)),
|
|
73
|
+
]),
|
|
74
|
+
],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* One action in full, as `actions --action <name>` and `call <action> --help`
|
|
79
|
+
* print it: the call form, description, source and adapter, risk, result
|
|
80
|
+
* cases, fields with their types, up to two authored examples, and the first
|
|
81
|
+
* one as a runnable call with its recipe node. `actionNames` is the adapter's
|
|
82
|
+
* vocabulary, which decides whether the short name is unambiguous.
|
|
83
|
+
*/
|
|
84
|
+
export function renderActionDetail(entry, adapter, target, executable, actionNames) {
|
|
85
|
+
const host = harnessHost().name;
|
|
86
|
+
const schema = isRecord(entry.schema) ? entry.schema : {};
|
|
87
|
+
const properties = isRecord(schema.properties) ? schema.properties : {};
|
|
88
|
+
const required = new Set(Array.isArray(schema.required)
|
|
89
|
+
? schema.required.filter((r) => typeof r === 'string')
|
|
90
|
+
: []);
|
|
91
|
+
const lines = [
|
|
92
|
+
`${host} call ${entry.name} [key=value ...] [--arg k=v ...] [flags]`,
|
|
93
|
+
'',
|
|
94
|
+
];
|
|
95
|
+
if (entry.description)
|
|
96
|
+
lines.push(` ${entry.description}`, '');
|
|
97
|
+
lines.push(` Source: ${entry.source}${entry.sourceManifest ? ` (${entry.sourceManifest})` : ''} · adapter ${adapter}`);
|
|
98
|
+
if (entry.capabilities.length > 0)
|
|
99
|
+
lines.push(` Risk: ${entry.capabilities.join(', ')}`);
|
|
100
|
+
if (entry.result_cases?.length)
|
|
101
|
+
lines.push(` Result cases: ${entry.result_cases.join(', ')}`);
|
|
102
|
+
lines.push('');
|
|
103
|
+
if (entry.fields.length === 0) {
|
|
104
|
+
lines.push(' Fields: (none)');
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
lines.push(' Fields (pass as <name>=<value> or --arg <name>=<value>):');
|
|
108
|
+
const width = Math.max(...entry.fields.map((name) => name.length));
|
|
109
|
+
for (const name of entry.fields) {
|
|
110
|
+
const prop = isRecord(properties[name]) ? properties[name] : {};
|
|
111
|
+
const type = typeof prop.type === 'string' ? prop.type : 'any';
|
|
112
|
+
const req = required.has(name) ? ' (required)' : '';
|
|
113
|
+
const desc = typeof prop.description === 'string' ? ` — ${prop.description}` : '';
|
|
114
|
+
const enumVals = Array.isArray(prop.enum) ? ` [one of: ${prop.enum.join(', ')}]` : '';
|
|
115
|
+
const defaultValue = Object.hasOwn(prop, 'default')
|
|
116
|
+
? ` [default: ${JSON.stringify(prop.default)}]`
|
|
117
|
+
: '';
|
|
118
|
+
lines.push(` ${name.padEnd(width)} ${type}${req}${defaultValue}${desc}${enumVals}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const examples = shortExampleCalls(entry, actionNames);
|
|
122
|
+
if (examples.length > 0) {
|
|
123
|
+
lines.push('', ' Examples:');
|
|
124
|
+
for (const example of examples)
|
|
125
|
+
lines.push(` ${example}`);
|
|
126
|
+
}
|
|
127
|
+
const runnable = renderHumanActionExample(entry, adapter, target, executable);
|
|
128
|
+
if (runnable)
|
|
129
|
+
lines.push('', runnable);
|
|
130
|
+
return lines.join('\n');
|
|
131
|
+
}
|
|
132
|
+
// Up to two authored examples as `call` lines: the short name where it is
|
|
133
|
+
// unambiguous, and only the action's fields, quoted, as actionExampleCommand
|
|
134
|
+
// renders them.
|
|
135
|
+
function shortExampleCalls(entry, actionNames) {
|
|
136
|
+
if (!Array.isArray(entry.examples))
|
|
137
|
+
return [];
|
|
138
|
+
const name = shortActionNames(actionNames).get(entry.name) ?? entry.name;
|
|
139
|
+
const out = [];
|
|
140
|
+
for (const example of entry.examples.slice(0, 2)) {
|
|
141
|
+
const node = isRecord(example) ? example : undefined;
|
|
142
|
+
if (!node)
|
|
143
|
+
continue;
|
|
144
|
+
const tokens = entry.fields.flatMap((field) => Object.hasOwn(node, field)
|
|
145
|
+
? [shellQuoteArg(`${field}=${safeActionCallValue(field, node[field])}`)]
|
|
146
|
+
: []);
|
|
147
|
+
out.push([harnessHost().name, 'call', shellQuoteArg(name), ...tokens].join(' '));
|
|
148
|
+
}
|
|
149
|
+
return out;
|
|
150
|
+
}
|
|
151
|
+
/** The authored example as a human block: the call that runs it and its recipe node. */
|
|
152
|
+
export function renderHumanActionExample(entry, adapter, target, executable) {
|
|
153
|
+
const node = authoredExampleNode(entry.examples, undefined, entry.schema);
|
|
154
|
+
if (!node)
|
|
155
|
+
return undefined;
|
|
156
|
+
const out = (style, text) => color(style, text, { stream: process.stdout });
|
|
157
|
+
const command = actionExampleCommand(entry, adapter, target, executable);
|
|
158
|
+
if (!command)
|
|
159
|
+
return undefined;
|
|
160
|
+
const lines = [
|
|
161
|
+
out('label', 'Example call:'),
|
|
162
|
+
` ${out('cmd', command)}`,
|
|
163
|
+
out('label', 'Recipe node:'),
|
|
164
|
+
...JSON.stringify(node, null, 2)
|
|
165
|
+
.split('\n')
|
|
166
|
+
.map((line) => ` ${line}`),
|
|
167
|
+
];
|
|
168
|
+
return lines.join('\n');
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* A runnable `call` for the action's authored example; `preferredValues` pick
|
|
172
|
+
* the closest example and override its values.
|
|
173
|
+
*/
|
|
174
|
+
export function actionExampleCommand(entry, adapter, target, executable, preferredValues) {
|
|
175
|
+
const node = authoredExampleNode(entry.examples, preferredValues, entry.schema);
|
|
176
|
+
if (!node)
|
|
177
|
+
return undefined;
|
|
178
|
+
const host = harnessHost().name;
|
|
179
|
+
const commandName = executable.endsWith(`/${host}`) ? host : executable;
|
|
180
|
+
const args = entry.fields.flatMap((field) => Object.hasOwn(node, field)
|
|
181
|
+
? [shellQuoteArg(`${field}=${safeActionCallValue(field, node[field])}`)]
|
|
182
|
+
: []);
|
|
183
|
+
return [
|
|
184
|
+
shellQuoteArg(commandName),
|
|
185
|
+
'call',
|
|
186
|
+
shellQuoteArg(entry.name),
|
|
187
|
+
...args,
|
|
188
|
+
'--adapter',
|
|
189
|
+
adapter,
|
|
190
|
+
'--target',
|
|
191
|
+
shellQuoteArg(target),
|
|
192
|
+
].join(' ');
|
|
193
|
+
}
|
|
194
|
+
function authoredExampleNode(examples, preferredValues, schema) {
|
|
195
|
+
if (!Array.isArray(examples))
|
|
196
|
+
return undefined;
|
|
197
|
+
if (preferredValues && Object.keys(preferredValues).length > 0) {
|
|
198
|
+
const normalizedValues = normalizePreferredValues(preferredValues, schema);
|
|
199
|
+
const nodes = examples.filter(isRecord);
|
|
200
|
+
if (nodes.length === 0)
|
|
201
|
+
return undefined;
|
|
202
|
+
const ranked = nodes
|
|
203
|
+
.map((node) => ({
|
|
204
|
+
node,
|
|
205
|
+
completeness: Object.keys(node).filter((name) => !['action', 'intent', 'next'].includes(name)).length,
|
|
206
|
+
score: Object.entries(normalizedValues).reduce((score, [name, value]) => {
|
|
207
|
+
if (!Object.hasOwn(node, name))
|
|
208
|
+
return score;
|
|
209
|
+
return score + (sameActionValue(name, node[name], value) ? 3 : -1);
|
|
210
|
+
}, 0),
|
|
211
|
+
}))
|
|
212
|
+
.sort((left, right) => right.score - left.score || right.completeness - left.completeness);
|
|
213
|
+
return { ...ranked[0].node, ...normalizedValues };
|
|
214
|
+
}
|
|
215
|
+
for (const example of examples) {
|
|
216
|
+
if (isRecord(example))
|
|
217
|
+
return example;
|
|
218
|
+
}
|
|
219
|
+
return undefined;
|
|
220
|
+
}
|
|
221
|
+
function normalizePreferredValues(preferredValues, schema) {
|
|
222
|
+
const properties = isRecord(schema) && isRecord(schema.properties) ? schema.properties : {};
|
|
223
|
+
return Object.fromEntries(Object.entries(preferredValues).flatMap(([name, value]) => {
|
|
224
|
+
const property = isRecord(properties[name]) ? properties[name] : undefined;
|
|
225
|
+
if (property && !matchesSchemaType(property.type, value))
|
|
226
|
+
return [];
|
|
227
|
+
const values = property && Array.isArray(property.enum) ? property.enum : undefined;
|
|
228
|
+
if (!values) {
|
|
229
|
+
return [[name, value]];
|
|
230
|
+
}
|
|
231
|
+
const compatibleValue = values.find((candidate) => sameActionValue(name, candidate, value));
|
|
232
|
+
if (compatibleValue !== undefined)
|
|
233
|
+
return [[name, compatibleValue]];
|
|
234
|
+
const strings = values.filter((candidate) => typeof candidate === 'string');
|
|
235
|
+
const suggestion = typeof value === 'string' ? closest(value, strings) : undefined;
|
|
236
|
+
return suggestion === undefined ? [] : [[name, suggestion]];
|
|
237
|
+
}));
|
|
238
|
+
}
|
|
239
|
+
function matchesSchemaType(type, value) {
|
|
240
|
+
const types = Array.isArray(type) ? type : [type];
|
|
241
|
+
if (types.every((candidate) => typeof candidate !== 'string'))
|
|
242
|
+
return true;
|
|
243
|
+
return types.some((candidate) => {
|
|
244
|
+
if (candidate === 'null')
|
|
245
|
+
return value === null;
|
|
246
|
+
if (candidate === 'array')
|
|
247
|
+
return Array.isArray(value);
|
|
248
|
+
if (candidate === 'object')
|
|
249
|
+
return isRecord(value);
|
|
250
|
+
if (candidate === 'integer')
|
|
251
|
+
return typeof value === 'number' && Number.isInteger(value);
|
|
252
|
+
return typeof value === candidate;
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
function sameActionValue(name, left, right) {
|
|
256
|
+
if (name === 'state') {
|
|
257
|
+
const canonicalState = (value) => {
|
|
258
|
+
if (value === 'present')
|
|
259
|
+
return 'open';
|
|
260
|
+
if (value === 'absent')
|
|
261
|
+
return 'none';
|
|
262
|
+
return value;
|
|
263
|
+
};
|
|
264
|
+
left = canonicalState(left);
|
|
265
|
+
right = canonicalState(right);
|
|
266
|
+
}
|
|
267
|
+
const scalar = (value) => typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean';
|
|
268
|
+
if (scalar(left) && scalar(right))
|
|
269
|
+
return String(left) === String(right);
|
|
270
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
271
|
+
}
|
|
272
|
+
function actionCallValue(value) {
|
|
273
|
+
return typeof value === 'string' ? value : JSON.stringify(value);
|
|
274
|
+
}
|
|
275
|
+
function safeActionCallValue(field, value) {
|
|
276
|
+
if (isSensitiveKey(field))
|
|
277
|
+
return `<${field}>`;
|
|
278
|
+
return actionCallValue(redactStructuredValue(value));
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/harness/catalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type RecipeCatalog } from '../catalog.js';
|
|
2
|
+
import { type ConsoleAllowlist } from '../run-diagnostics.js';
|
|
3
|
+
import { type RecipeEngine } from '../run-engine.js';
|
|
4
|
+
import { type DeviceTargeting } from './run.js';
|
|
5
|
+
export interface CallCommandOptions<TMutation, TAllowlist extends ConsoleAllowlist> {
|
|
6
|
+
engine: RecipeEngine<TMutation, TAllowlist>;
|
|
7
|
+
targetDevice?: DeviceTargeting;
|
|
8
|
+
exampleAction?(names: readonly string[]): string | undefined;
|
|
9
|
+
}
|
|
10
|
+
export declare function handleCall<TMutation, TAllowlist extends ConsoleAllowlist>(argv: string[], commandOptions: CallCommandOptions<TMutation, TAllowlist>): Promise<number>;
|
|
11
|
+
/** A fresh artifacts directory per call, under the checkout's recipe calls. */
|
|
12
|
+
export declare function defaultCallArtifactsDir(target: string, action: string): string;
|
|
13
|
+
/** Call inputs and output with every sensitive-keyed value redacted. */
|
|
14
|
+
export declare function redactCallValue(value: unknown, key?: string): unknown;
|
|
15
|
+
export declare function handleCallHelp(argv: string[], genericHelp: string, commandOptions: {
|
|
16
|
+
catalog: RecipeCatalog;
|
|
17
|
+
}): Promise<number>;
|
|
18
|
+
//# sourceMappingURL=call.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call.d.ts","sourceRoot":"","sources":["../../../src/harness/commands/call.ts"],"names":[],"mappings":"AAaA,OAAO,EAKL,KAAK,aAAa,EAGnB,MAAM,eAAe,CAAC;AAsBvB,OAAO,EACL,KAAK,gBAAgB,EAGtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAOL,KAAK,YAAY,EAIlB,MAAM,kBAAkB,CAAC;AAQ1B,OAAO,EAAE,KAAK,eAAe,EAAyC,MAAM,UAAU,CAAC;AAEvF,MAAM,WAAW,kBAAkB,CAAC,SAAS,EAAE,UAAU,SAAS,gBAAgB;IAChF,MAAM,EAAE,YAAY,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAC5C,YAAY,CAAC,EAAE,eAAe,CAAC;IAG/B,aAAa,CAAC,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAAC;CAC9D;AAED,wBAAsB,UAAU,CAAC,SAAS,EAAE,UAAU,SAAS,gBAAgB,EAC7E,IAAI,EAAE,MAAM,EAAE,EACd,cAAc,EAAE,kBAAkB,CAAC,SAAS,EAAE,UAAU,CAAC,GACxD,OAAO,CAAC,MAAM,CAAC,CAmfjB;AAoGD,+EAA+E;AAC/E,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAG9E;AA0BD,wEAAwE;AACxE,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,SAAK,GAAG,OAAO,CAKjE;AAOD,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EAAE,EACd,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE;IAAE,OAAO,EAAE,aAAa,CAAA;CAAE,GACzC,OAAO,CAAC,MAAM,CAAC,CA+CjB"}
|