@farmslot/protocol 0.11.0 → 0.12.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.
@@ -1,7 +1,7 @@
1
- import { addFinding, createContext, finishResult, hasOwn, isNonEmptyString, isRecord, RECIPE_PROTOCOL_SCHEMA_URL, requireStringField, validateOptionalStringField, } from './common.js';
1
+ import { addFinding, createContext, finishResult, hasOwn, isNonEmptyString, isRecord, RECIPE_PROTOCOL_SCHEMA_URL, validateOptionalStringField, } from './common.js';
2
2
  import { getRecipeActionManifestActionNames, validateRecipeActionManifestDocument, } from './manifest.js';
3
3
  import { validateRecipeParams, validateRecipeParamsSchema } from './params.js';
4
- import { extractWorkflow, getRecipeActionParams, getRecipeWorkflowActionEntries, validateRecipeCalls, validateWorkflowGraph, } from './workflow.js';
4
+ import { extractWorkflow, getRecipeActionParams, getRecipeWorkflowActionEntries, validateRecipeActionCases, validateRecipeCalls, validateWorkflowGraph, } from './workflow.js';
5
5
  const RECIPE_FIELDS = new Set([
6
6
  '$schema',
7
7
  'title',
@@ -49,19 +49,7 @@ export function validateRecipeWithManifest(recipe, manifest, options) {
49
49
  });
50
50
  ctx.findings.push(...paramsResult.findings.map((finding) => rebaseFinding(finding, path)));
51
51
  }
52
- if (isRecord(node.cases)) {
53
- if (!contract?.resultCases?.length) {
54
- addFinding(ctx, 'error', 'recipe.action_cases_not_declared', `${path}.cases`, `Action ${action} uses result cases but its manifest declares none.`);
55
- }
56
- else {
57
- const allowed = new Set(contract.resultCases);
58
- for (const caseName of Object.keys(node.cases)) {
59
- if (!allowed.has(caseName)) {
60
- addFinding(ctx, 'error', 'recipe.action_case_not_declared', `${path}.cases.${caseName}`, `Case ${caseName} is not declared by action ${action}.`);
61
- }
62
- }
63
- }
64
- }
52
+ ctx.findings.push(...validateRecipeActionCases(node, action, contract?.resultCases, path).findings);
65
53
  }
66
54
  return finishResult(ctx);
67
55
  }
@@ -82,12 +70,14 @@ export function validateRecipeDocument(recipe, options) {
82
70
  else if (recipe.$schema !== RECIPE_PROTOCOL_SCHEMA_URL) {
83
71
  addFinding(ctx, 'error', 'recipe.unsupported_schema_ref', '$schema', `Recipe $schema must equal ${RECIPE_PROTOCOL_SCHEMA_URL}.`);
84
72
  }
85
- requireStringField(ctx, recipe, 'description', 'description');
73
+ validateOptionalStringField(ctx, recipe, 'description', 'description');
86
74
  validateOptionalStringField(ctx, recipe, 'title', 'title');
87
75
  if (hasOwn(recipe, 'paramsSchema')) {
88
76
  ctx.findings.push(...validateRecipeParamsSchema(recipe.paramsSchema).findings);
89
77
  }
90
- const proofTargetIds = validateProofTargets(ctx, recipe.proofTargets);
78
+ const proofTargetIds = hasOwn(recipe, 'proofTargets')
79
+ ? validateProofTargets(ctx, recipe.proofTargets)
80
+ : new Set();
91
81
  const workflow = extractWorkflow(ctx, recipe);
92
82
  if (workflow) {
93
83
  validateWorkflowGraph(ctx, workflow);
@@ -101,8 +91,6 @@ export function validateRecipeDocument(recipe, options) {
101
91
  }
102
92
  function validateProofTargets(ctx, value) {
103
93
  const ids = new Set();
104
- if (value == null)
105
- return ids;
106
94
  if (!Array.isArray(value)) {
107
95
  addFinding(ctx, 'error', 'recipe.invalid_proof_targets', 'proofTargets', 'proofTargets must be an array.');
108
96
  return ids;
@@ -155,21 +143,12 @@ function validateProofLinks(ctx, nodes, declared) {
155
143
  }
156
144
  function manifestActionContracts(manifest) {
157
145
  const contracts = new Map();
158
- if (!isRecord(manifest))
146
+ if (!isRecord(manifest) || !isRecord(manifest.actions))
159
147
  return contracts;
160
- if (isRecord(manifest.action_metadata)) {
161
- for (const [name, entry] of Object.entries(manifest.action_metadata)) {
162
- if (!isRecord(entry))
163
- continue;
164
- contracts.set(name, actionContract(entry));
165
- }
166
- }
167
- if (Array.isArray(manifest.custom_actions)) {
168
- for (const entry of manifest.custom_actions) {
169
- if (isRecord(entry) && isNonEmptyString(entry.name)) {
170
- contracts.set(entry.name, actionContract(entry));
171
- }
172
- }
148
+ for (const [name, entry] of Object.entries(manifest.actions)) {
149
+ if (!isRecord(entry))
150
+ continue;
151
+ contracts.set(name, actionContract(entry));
173
152
  }
174
153
  return contracts;
175
154
  }
@@ -1 +1 @@
1
- {"version":3,"file":"document.js","sourceRoot":"","sources":["../../src/recipe/document.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"document.js","sourceRoot":"","sources":["../../src/recipe/document.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  export { mergeRecipeValidationResults, validateArtifactManifestDocument, validateRecipeArtifactPackage, } from './artifact.js';
2
- export { BUILT_IN_UI_OBSERVERS, type BuiltInUiObserverRef, isRecord, OFFICIAL_RECIPE_ACTIONS, type OfficialActionName, RECIPE_PROTOCOL_SCHEMA_URL, RECIPE_PROTOCOL_SCHEMA_URLS, RECIPE_PROTOCOL_SCHEMA_VERSION, type RecipeActionCatalogEntry, type RecipeActionCatalogExample, type RecipeActionManifestDocument, type RecipeActionName, type RecipeArtifactPackageInput, type RecipeCustomActionDeclaration, type RecipeNativeBindingDeclaration, type RecipeObserverDeclaration, type RecipeResolutionDependency, type RecipeResolutionDocument, type RecipeResolutionEdge, type RecipeRuntimeCapabilityDeclaration, type RecipeValidationFinding, type RecipeValidationResult, type RecipeValidationSeverity, type RecipeValidationStatus, type UiObserverRef, } from './common.js';
2
+ export { BUILT_IN_UI_OBSERVERS, type BuiltInUiObserverRef, isRecord, OFFICIAL_RECIPE_ACTIONS, type OfficialActionName, RECIPE_ACTION_MANIFEST_SCHEMA_URL, RECIPE_PROTOCOL_SCHEMA_URL, RECIPE_PROTOCOL_SCHEMA_URLS, RECIPE_PROTOCOL_SCHEMA_VERSION, type RecipeActionCatalogEntry, type RecipeActionManifestDocument, type RecipeActionName, type RecipeArtifactPackageInput, type RecipeObserverDeclaration, type RecipeResolutionDependency, type RecipeResolutionDocument, type RecipeResolutionEdge, type RecipeRuntimeCapabilityDeclaration, type RecipeValidationFinding, type RecipeValidationResult, type RecipeValidationSeverity, type RecipeValidationStatus, type UiObserverRef, } from './common.js';
3
3
  export { recipeProtocolSchemaUrlForVersion } from './common.js';
4
4
  export { canonicalRecipeJson, digestRecipeDocument, resolvedRecipeArtifactPath } from './digest.js';
5
5
  export { type RecipeDocumentValidationOptions, validateRecipeDocument, validateRecipeWithManifest, validateResolvedRecipeActionNode, } from './document.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/recipe/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,gCAAgC,EAChC,6BAA6B,GAC9B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,qBAAqB,EACrB,KAAK,oBAAoB,EACzB,QAAQ,EACR,uBAAuB,EACvB,KAAK,kBAAkB,EACvB,0BAA0B,EAC1B,2BAA2B,EAC3B,8BAA8B,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAC/B,KAAK,4BAA4B,EACjC,KAAK,gBAAgB,EACrB,KAAK,0BAA0B,EAC/B,KAAK,6BAA6B,EAClC,KAAK,8BAA8B,EACnC,KAAK,yBAAyB,EAC9B,KAAK,0BAA0B,EAC/B,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,kCAAkC,EACvC,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,aAAa,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,iCAAiC,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACpG,OAAO,EACL,KAAK,+BAA+B,EACpC,sBAAsB,EACtB,0BAA0B,EAC1B,gCAAgC,GACjC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,kCAAkC,EAClC,oCAAoC,GACrC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,6CAA6C,EAC7C,gCAAgC,EAChC,6BAA6B,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,GACxB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/recipe/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,gCAAgC,EAChC,6BAA6B,GAC9B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,qBAAqB,EACrB,KAAK,oBAAoB,EACzB,QAAQ,EACR,uBAAuB,EACvB,KAAK,kBAAkB,EACvB,iCAAiC,EACjC,0BAA0B,EAC1B,2BAA2B,EAC3B,8BAA8B,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,4BAA4B,EACjC,KAAK,gBAAgB,EACrB,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,EAC9B,KAAK,0BAA0B,EAC/B,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,kCAAkC,EACvC,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,aAAa,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,iCAAiC,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACpG,OAAO,EACL,KAAK,+BAA+B,EACpC,sBAAsB,EACtB,0BAA0B,EAC1B,gCAAgC,GACjC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,kCAAkC,EAClC,oCAAoC,GACrC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,6CAA6C,EAC7C,gCAAgC,EAChC,6BAA6B,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,GACxB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,eAAe,CAAC"}
@@ -1,5 +1,5 @@
1
1
  export { mergeRecipeValidationResults, validateArtifactManifestDocument, validateRecipeArtifactPackage, } from './artifact.js';
2
- export { BUILT_IN_UI_OBSERVERS, isRecord, OFFICIAL_RECIPE_ACTIONS, RECIPE_PROTOCOL_SCHEMA_URL, RECIPE_PROTOCOL_SCHEMA_URLS, RECIPE_PROTOCOL_SCHEMA_VERSION, } from './common.js';
2
+ export { BUILT_IN_UI_OBSERVERS, isRecord, OFFICIAL_RECIPE_ACTIONS, RECIPE_ACTION_MANIFEST_SCHEMA_URL, RECIPE_PROTOCOL_SCHEMA_URL, RECIPE_PROTOCOL_SCHEMA_URLS, RECIPE_PROTOCOL_SCHEMA_VERSION, } from './common.js';
3
3
  export { recipeProtocolSchemaUrlForVersion } from './common.js';
4
4
  export { canonicalRecipeJson, digestRecipeDocument, resolvedRecipeArtifactPath } from './digest.js';
5
5
  export { validateRecipeDocument, validateRecipeWithManifest, validateResolvedRecipeActionNode, } from './document.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/recipe/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,gCAAgC,EAChC,6BAA6B,GAC9B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,qBAAqB,EAErB,QAAQ,EACR,uBAAuB,EAEvB,0BAA0B,EAC1B,2BAA2B,EAC3B,8BAA8B,GAkB/B,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,iCAAiC,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACpG,OAAO,EAEL,sBAAsB,EACtB,0BAA0B,EAC1B,gCAAgC,GACjC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,kCAAkC,EAClC,oCAAoC,GACrC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,6CAA6C,EAC7C,gCAAgC,EAChC,6BAA6B,GAS9B,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/recipe/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,gCAAgC,EAChC,6BAA6B,GAC9B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,qBAAqB,EAErB,QAAQ,EACR,uBAAuB,EAEvB,iCAAiC,EACjC,0BAA0B,EAC1B,2BAA2B,EAC3B,8BAA8B,GAe/B,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,iCAAiC,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACpG,OAAO,EAEL,sBAAsB,EACtB,0BAA0B,EAC1B,gCAAgC,GACjC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,kCAAkC,EAClC,oCAAoC,GACrC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,6CAA6C,EAC7C,gCAAgC,EAChC,6BAA6B,GAS9B,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,eAAe,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/recipe/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAUL,KAAK,sBAAsB,EAC5B,MAAM,aAAa,CAAC;AAiBrB,wBAAgB,kCAAkC,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,EAAE,CAc9E;AAsLD,wBAAgB,oCAAoC,CAAC,QAAQ,EAAE,OAAO,GAAG,sBAAsB,CAsc9F"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/recipe/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAUL,KAAK,sBAAsB,EAC5B,MAAM,aAAa,CAAC;AAqBrB,wBAAgB,kCAAkC,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,EAAE,CAG9E;AA4QD,wBAAgB,oCAAoC,CAAC,QAAQ,EAAE,OAAO,GAAG,sBAAsB,CAoF9F"}
@@ -1,54 +1,40 @@
1
- import { addFinding, BUILT_IN_UI_OBSERVER_SET, createContext, finishResult, isNonEmptyString, isRecord, OFFICIAL_ACTION_SET, RECIPE_PROTOCOL_SCHEMA_VERSION, } from './common.js';
1
+ import { addFinding, BUILT_IN_UI_OBSERVER_SET, createContext, finishResult, isNonEmptyString, isRecord, OFFICIAL_ACTION_SET, RECIPE_ACTION_MANIFEST_SCHEMA_URL, } from './common.js';
2
2
  import { validateRecipeParams, validateRecipeParamsSchema } from './params.js';
3
3
  import { RECIPE_EXECUTION_CAPABILITIES } from './trust.js';
4
- import { getRecipeActionParams } from './workflow.js';
4
+ import { getRecipeActionParams, isDynamicRecipeRef, validateRecipeActionCases, validateRecipeWorkflowNode, } from './workflow.js';
5
5
  const recipeExecutionCapabilitySet = new Set(RECIPE_EXECUTION_CAPABILITIES);
6
- const ACTION_MANIFEST_FIELDS = new Set([
7
- 'runner_protocol_version',
8
- 'action_registry_version',
9
- 'supported_official_actions',
10
- 'action_metadata',
11
- 'custom_actions',
12
- 'native_bindings',
13
- 'capabilities',
14
- 'observers',
6
+ const ACTION_MANIFEST_FIELDS = new Set(['$schema', 'actions', 'observers']);
7
+ const ACTION_ENTRY_FIELDS = new Set([
8
+ 'description',
9
+ 'schema',
10
+ 'result_cases',
11
+ 'examples',
12
+ 'execution_capabilities',
15
13
  ]);
14
+ const OBSERVER_FIELDS = new Set(['ref', 'default_for']);
16
15
  export function getRecipeActionManifestActionNames(manifest) {
17
- if (!isRecord(manifest))
16
+ if (!isRecord(manifest) || !isRecord(manifest.actions))
18
17
  return [];
19
- const actionNames = new Set();
20
- if (Array.isArray(manifest.supported_official_actions)) {
21
- for (const action of manifest.supported_official_actions) {
22
- if (isNonEmptyString(action))
23
- actionNames.add(action);
24
- }
25
- }
26
- if (Array.isArray(manifest.custom_actions)) {
27
- for (const action of manifest.custom_actions) {
28
- if (isRecord(action) && isNonEmptyString(action.name))
29
- actionNames.add(action.name);
30
- }
18
+ return Object.keys(manifest.actions).sort();
19
+ }
20
+ function rejectUnknownFields(ctx, value, allowed, path, code) {
21
+ for (const field of Object.keys(value)) {
22
+ if (allowed.has(field))
23
+ continue;
24
+ addFinding(ctx, 'error', code, `${path}.${field}`, `${path} does not support ${field}.`);
31
25
  }
32
- return [...actionNames].sort();
33
26
  }
34
- function validateActionCatalogEntry(ctx, entry, path, expectedAction, schemaRequired = true) {
27
+ function validateActionCatalogEntry(ctx, action, entry, path) {
35
28
  if (!isRecord(entry)) {
36
- addFinding(ctx, 'error', 'action_manifest.invalid_action_metadata', path, `${path} must be an object.`);
29
+ addFinding(ctx, 'error', 'action_manifest.invalid_action', path, `${path} must be an object.`);
37
30
  return;
38
31
  }
39
- for (const stringField of [
40
- 'description',
41
- 'when_to_use',
42
- 'avoid_when',
43
- 'proof_effect',
44
- 'safety_notes',
45
- ]) {
46
- const value = entry[stringField];
47
- if (value != null && typeof value !== 'string') {
48
- addFinding(ctx, 'error', 'action_manifest.invalid_metadata_field', `${path}.${stringField}`, `${path}.${stringField} must be a string when present.`);
49
- }
32
+ rejectUnknownFields(ctx, entry, ACTION_ENTRY_FIELDS, path, 'action_manifest.unsupported_action_field');
33
+ if (!isNonEmptyString(entry.description)) {
34
+ addFinding(ctx, 'error', 'action_manifest.missing_description', `${path}.description`, `${path}.description must be a non-empty string.`);
50
35
  }
51
- if (entry.schema == null) {
36
+ const schemaRequired = action !== 'call' && action !== 'end';
37
+ if (!Object.hasOwn(entry, 'schema')) {
52
38
  if (schemaRequired) {
53
39
  addFinding(ctx, 'error', 'action_manifest.missing_schema', `${path}.schema`, `${path}.schema is required so action parameters can be validated before execution.`);
54
40
  }
@@ -57,13 +43,13 @@ function validateActionCatalogEntry(ctx, entry, path, expectedAction, schemaRequ
57
43
  addFinding(ctx, 'error', 'action_manifest.invalid_schema', `${path}.schema`, `${path}.schema must be a JSON Schema object when present.`);
58
44
  }
59
45
  else {
60
- const schemaResult = validateRecipeParamsSchema(entry.schema, { requireClosedRoot: false });
46
+ const schemaResult = validateRecipeParamsSchema(entry.schema);
61
47
  ctx.findings.push(...schemaResult.findings.map((finding) => ({
62
48
  ...finding,
63
49
  path: `${path}.schema${finding.path === 'paramsSchema' ? '' : finding.path.replace(/^paramsSchema/u, '')}`,
64
50
  })));
65
51
  }
66
- if (entry.result_cases != null) {
52
+ if (Object.hasOwn(entry, 'result_cases')) {
67
53
  if (!Array.isArray(entry.result_cases) ||
68
54
  entry.result_cases.length === 0 ||
69
55
  entry.result_cases.some((value) => !isNonEmptyString(value)) ||
@@ -71,9 +57,10 @@ function validateActionCatalogEntry(ctx, entry, path, expectedAction, schemaRequ
71
57
  addFinding(ctx, 'error', 'action_manifest.invalid_result_cases', `${path}.result_cases`, `${path}.result_cases must be a non-empty array of unique case names.`);
72
58
  }
73
59
  }
74
- if (entry.execution_capabilities != null) {
75
- if (!Array.isArray(entry.execution_capabilities)) {
76
- addFinding(ctx, 'error', 'action_manifest.invalid_execution_capabilities', `${path}.execution_capabilities`, `${path}.execution_capabilities must be an array when present.`);
60
+ if (Object.hasOwn(entry, 'execution_capabilities')) {
61
+ if (!Array.isArray(entry.execution_capabilities) ||
62
+ new Set(entry.execution_capabilities).size !== entry.execution_capabilities.length) {
63
+ addFinding(ctx, 'error', 'action_manifest.invalid_execution_capabilities', `${path}.execution_capabilities`, `${path}.execution_capabilities must be an array of unique capabilities.`);
77
64
  }
78
65
  else {
79
66
  entry.execution_capabilities.forEach((capability, index) => {
@@ -83,249 +70,111 @@ function validateActionCatalogEntry(ctx, entry, path, expectedAction, schemaRequ
83
70
  });
84
71
  }
85
72
  }
86
- if (entry.examples == null)
87
- return;
88
- if (!Array.isArray(entry.examples)) {
89
- addFinding(ctx, 'error', 'action_manifest.invalid_examples', `${path}.examples`, `${path}.examples must be an array when present.`);
73
+ if (!Array.isArray(entry.examples) || entry.examples.length === 0) {
74
+ addFinding(ctx, 'error', 'action_manifest.missing_examples', `${path}.examples`, `${path}.examples must contain at least one copyable recipe node.`);
90
75
  return;
91
76
  }
92
77
  entry.examples.forEach((example, index) => {
93
78
  const examplePath = `${path}.examples[${index}]`;
94
79
  if (!isRecord(example)) {
95
- addFinding(ctx, 'error', 'action_manifest.invalid_example', examplePath, `${examplePath} must be an object.`);
96
- return;
97
- }
98
- if (example.description != null && typeof example.description !== 'string') {
99
- addFinding(ctx, 'error', 'action_manifest.invalid_example_description', `${examplePath}.description`, `${examplePath}.description must be a string when present.`);
100
- }
101
- if (!isRecord(example.node)) {
102
- addFinding(ctx, 'error', 'action_manifest.invalid_example_node', `${examplePath}.node`, `${examplePath}.node must be an object.`);
80
+ addFinding(ctx, 'error', 'action_manifest.invalid_example', examplePath, `${examplePath} must be a recipe node object.`);
103
81
  return;
104
82
  }
105
- if (!isNonEmptyString(example.node.action)) {
106
- addFinding(ctx, 'error', 'action_manifest.invalid_example_action', `${examplePath}.node.action`, `${examplePath}.node.action must be a non-empty string.`);
107
- }
108
- else if (expectedAction && example.node.action !== expectedAction) {
109
- addFinding(ctx, 'error', 'action_manifest.example_action_mismatch', `${examplePath}.node.action`, `Example action ${example.node.action} must match declared action ${expectedAction}.`);
83
+ if (example.action !== action) {
84
+ addFinding(ctx, 'error', 'action_manifest.example_action_mismatch', `${examplePath}.action`, `${examplePath}.action must equal ${action}.`);
110
85
  }
86
+ const nodeResult = validateRecipeWorkflowNode('example', example);
87
+ ctx.findings.push(...nodeResult.findings.map((finding) => ({
88
+ ...finding,
89
+ path: finding.path.replace(/^workflow\.nodes\.example/u, examplePath),
90
+ })));
91
+ if (action === 'call' && isNonEmptyString(example.ref) && isDynamicRecipeRef(example.ref)) {
92
+ addFinding(ctx, 'error', 'workflow.dynamic_call_ref', `${examplePath}.ref`, 'call.ref must be static so dependencies can be resolved and trusted before execution.');
93
+ }
94
+ const resultCases = Array.isArray(entry.result_cases)
95
+ ? entry.result_cases.filter(isNonEmptyString)
96
+ : undefined;
97
+ const casesResult = validateRecipeActionCases(example, action, resultCases, examplePath);
98
+ ctx.findings.push(...casesResult.findings);
111
99
  if (isRecord(entry.schema)) {
112
- const paramsResult = validateRecipeParams(getRecipeActionParams(example.node), entry.schema, {
100
+ const paramsResult = validateRecipeParams(getRecipeActionParams(example), entry.schema, {
113
101
  allowTemplates: true,
114
102
  });
115
103
  ctx.findings.push(...paramsResult.findings.map((finding) => ({
116
104
  ...finding,
117
- path: `${examplePath}.node${finding.path === 'params' ? '' : finding.path.replace(/^params/u, '')}`,
105
+ path: `${examplePath}${finding.path === 'params' ? '' : finding.path.replace(/^params/u, '')}`,
118
106
  })));
119
107
  }
120
108
  });
121
109
  }
122
- export function validateRecipeActionManifestDocument(manifest) {
123
- const ctx = createContext();
124
- if (!isRecord(manifest)) {
125
- addFinding(ctx, 'error', 'action_manifest.invalid_document', '$', 'Recipe action manifest must be a JSON object.');
126
- return finishResult(ctx);
127
- }
128
- for (const field of Object.keys(manifest)) {
129
- if (!ACTION_MANIFEST_FIELDS.has(field)) {
130
- addFinding(ctx, 'error', 'action_manifest.unsupported_field', field, `Recipe action manifests do not support ${field}.`);
131
- }
132
- }
133
- if (manifest.runner_protocol_version !== RECIPE_PROTOCOL_SCHEMA_VERSION) {
134
- addFinding(ctx, 'error', 'action_manifest.invalid_runner_protocol_version', 'runner_protocol_version', `runner_protocol_version must equal ${RECIPE_PROTOCOL_SCHEMA_VERSION}.`);
110
+ function validateObserver(ctx, observer, index, declaredActions, declaredObservers) {
111
+ const path = `observers[${index}]`;
112
+ if (!isRecord(observer)) {
113
+ addFinding(ctx, 'error', 'action_manifest.invalid_observer', path, `${path} must be an object.`);
114
+ return;
135
115
  }
136
- if (manifest.action_registry_version !== RECIPE_PROTOCOL_SCHEMA_VERSION) {
137
- addFinding(ctx, 'error', 'action_manifest.invalid_action_registry_version', 'action_registry_version', `action_registry_version must equal ${RECIPE_PROTOCOL_SCHEMA_VERSION}.`);
138
- }
139
- const declaredActions = new Set();
140
- const officialActions = manifest.supported_official_actions;
141
- if (!Array.isArray(officialActions) || officialActions.length === 0) {
142
- addFinding(ctx, 'error', 'action_manifest.invalid_supported_official_actions', 'supported_official_actions', 'supported_official_actions must be a non-empty array.');
116
+ rejectUnknownFields(ctx, observer, OBSERVER_FIELDS, path, 'action_manifest.unsupported_observer_field');
117
+ if (!isNonEmptyString(observer.ref)) {
118
+ addFinding(ctx, 'error', 'action_manifest.invalid_observer_ref', `${path}.ref`, `${path}.ref must be a non-empty string.`);
143
119
  }
144
120
  else {
145
- officialActions.forEach((action, index) => {
146
- const path = `supported_official_actions[${index}]`;
147
- if (!isNonEmptyString(action)) {
148
- addFinding(ctx, 'error', 'action_manifest.invalid_supported_action', path, `${path} must be a non-empty string.`);
149
- return;
150
- }
151
- if (!OFFICIAL_ACTION_SET.has(action)) {
152
- addFinding(ctx, 'error', 'action_manifest.unknown_official_action', path, `${action} is not in the Farmslot v1 official action registry.`);
153
- }
154
- if (declaredActions.has(action)) {
155
- addFinding(ctx, 'error', 'action_manifest.duplicate_action', path, `${action} is declared more than once.`);
156
- }
157
- declaredActions.add(action);
158
- });
159
- }
160
- const customActions = manifest.custom_actions;
161
- if (customActions != null) {
162
- if (!Array.isArray(customActions)) {
163
- addFinding(ctx, 'error', 'action_manifest.invalid_custom_actions', 'custom_actions', 'custom_actions must be an array when present.');
121
+ if (!BUILT_IN_UI_OBSERVER_SET.has(observer.ref) && !observer.ref.includes('.')) {
122
+ addFinding(ctx, 'error', 'action_manifest.invalid_observer_ref', `${path}.ref`, `${observer.ref} must be a built-in UI observer ref or a namespaced custom ref.`);
164
123
  }
165
- else {
166
- customActions.forEach((action, index) => {
167
- const path = `custom_actions[${index}]`;
168
- if (!isRecord(action)) {
169
- addFinding(ctx, 'error', 'action_manifest.invalid_custom_action', path, `${path} must be an object.`);
170
- return;
171
- }
172
- if (!isNonEmptyString(action.name)) {
173
- addFinding(ctx, 'error', 'action_manifest.invalid_custom_action_name', `${path}.name`, `${path}.name must be a non-empty string.`);
174
- }
175
- else {
176
- if (!/^[a-z0-9]+(?:[._-][a-z0-9]+)+$/u.test(action.name)) {
177
- addFinding(ctx, 'error', 'action_manifest.custom_action_not_namespaced', `${path}.name`, `${action.name} must be a lowercase namespaced action such as wallet.unlock.`);
178
- }
179
- if (OFFICIAL_ACTION_SET.has(action.name)) {
180
- addFinding(ctx, 'error', 'action_manifest.custom_action_overlaps_official', `${path}.name`, `${action.name} is official and must be declared in supported_official_actions.`);
181
- }
182
- if (declaredActions.has(action.name)) {
183
- addFinding(ctx, 'error', 'action_manifest.duplicate_action', `${path}.name`, `${action.name} is declared more than once.`);
184
- }
185
- declaredActions.add(action.name);
186
- }
187
- validateActionCatalogEntry(ctx, action, path, isNonEmptyString(action.name) ? action.name : undefined);
188
- if (!Object.hasOwn(action, 'execution_capabilities')) {
189
- addFinding(ctx, 'error', 'action_manifest.missing_execution_capabilities', `${path}.execution_capabilities`, 'Custom actions must explicitly declare execution_capabilities, including an empty array for read-only actions.');
190
- }
191
- });
124
+ if (declaredObservers.has(observer.ref)) {
125
+ addFinding(ctx, 'error', 'action_manifest.duplicate_observer', `${path}.ref`, `${observer.ref} is declared more than once.`);
192
126
  }
127
+ declaredObservers.add(observer.ref);
193
128
  }
194
- if (manifest.action_metadata != null) {
195
- if (!isRecord(manifest.action_metadata)) {
196
- addFinding(ctx, 'error', 'action_manifest.invalid_action_metadata', 'action_metadata', 'action_metadata must be an object when present.');
197
- }
198
- else {
199
- const declaredOfficialActions = new Set(Array.isArray(officialActions)
200
- ? officialActions.filter((action) => isNonEmptyString(action))
201
- : []);
202
- for (const [action, metadata] of Object.entries(manifest.action_metadata)) {
203
- if (!declaredOfficialActions.has(action)) {
204
- addFinding(ctx, 'error', 'action_manifest.metadata_for_undeclared_action', `action_metadata.${action}`, `action_metadata may describe only supported_official_actions; declare ${action} once in custom_actions instead.`);
205
- }
206
- validateActionCatalogEntry(ctx, metadata, `action_metadata.${action}`, action, action !== 'call' && action !== 'end');
207
- }
208
- }
129
+ if (!Array.isArray(observer.default_for) ||
130
+ observer.default_for.length === 0 ||
131
+ new Set(observer.default_for).size !== observer.default_for.length) {
132
+ addFinding(ctx, 'error', 'action_manifest.invalid_observer_default_for', `${path}.default_for`, `${path}.default_for must be a non-empty array of unique declared actions.`);
133
+ return;
209
134
  }
210
- for (const action of declaredActions) {
211
- if (action === 'call' || action === 'end')
212
- continue;
213
- const isCustom = Array.isArray(customActions)
214
- ? customActions.some((entry) => isRecord(entry) && entry.name === action)
215
- : false;
216
- if (isCustom)
217
- continue;
218
- if (!isRecord(manifest.action_metadata) || !isRecord(manifest.action_metadata[action])) {
219
- addFinding(ctx, 'error', 'action_manifest.missing_action_metadata', `action_metadata.${action}`, `Official action ${action} must declare metadata and a parameter schema.`);
135
+ observer.default_for.forEach((action, actionIndex) => {
136
+ if (!isNonEmptyString(action) ||
137
+ !declaredActions.has(action) ||
138
+ action === 'call' ||
139
+ action === 'end') {
140
+ addFinding(ctx, 'error', 'action_manifest.invalid_observer_default_for', `${path}.default_for[${actionIndex}]`, `${path}.default_for[${actionIndex}] must reference a declared executable action.`);
220
141
  }
142
+ });
143
+ }
144
+ export function validateRecipeActionManifestDocument(manifest) {
145
+ const ctx = createContext();
146
+ if (!isRecord(manifest)) {
147
+ addFinding(ctx, 'error', 'action_manifest.invalid_document', '$', 'Recipe action manifest must be a JSON object.');
148
+ return finishResult(ctx);
221
149
  }
222
- const nativeBindings = manifest.native_bindings;
223
- if (nativeBindings != null) {
224
- if (!Array.isArray(nativeBindings)) {
225
- addFinding(ctx, 'error', 'action_manifest.invalid_native_bindings', 'native_bindings', 'native_bindings must be an array when present.');
226
- }
227
- else {
228
- nativeBindings.forEach((binding, index) => {
229
- const path = `native_bindings[${index}]`;
230
- if (!isRecord(binding)) {
231
- addFinding(ctx, 'error', 'action_manifest.invalid_native_binding', path, `${path} must be an object.`);
232
- return;
233
- }
234
- if (!isNonEmptyString(binding.action)) {
235
- addFinding(ctx, 'error', 'action_manifest.invalid_native_binding_action', `${path}.action`, `${path}.action must be a non-empty string.`);
236
- }
237
- else if (!declaredActions.has(binding.action)) {
238
- addFinding(ctx, 'error', 'action_manifest.native_binding_for_undeclared_action', `${path}.action`, `Native binding action ${binding.action} is not declared by the manifest.`);
239
- }
240
- if (!isNonEmptyString(binding.implementation)) {
241
- addFinding(ctx, 'error', 'action_manifest.invalid_native_binding_implementation', `${path}.implementation`, `${path}.implementation must be a non-empty string.`);
242
- }
243
- });
244
- }
150
+ rejectUnknownFields(ctx, manifest, ACTION_MANIFEST_FIELDS, '$', 'action_manifest.unsupported_field');
151
+ if (manifest.$schema !== RECIPE_ACTION_MANIFEST_SCHEMA_URL) {
152
+ addFinding(ctx, 'error', 'action_manifest.invalid_schema_ref', '$schema', `$schema must equal ${RECIPE_ACTION_MANIFEST_SCHEMA_URL}.`);
245
153
  }
246
- const capabilities = manifest.capabilities;
247
- if (capabilities != null) {
248
- if (!Array.isArray(capabilities)) {
249
- addFinding(ctx, 'error', 'action_manifest.invalid_capabilities', 'capabilities', 'capabilities must be an array when present.');
154
+ if (!isRecord(manifest.actions) || Object.keys(manifest.actions).length === 0) {
155
+ addFinding(ctx, 'error', 'action_manifest.invalid_actions', 'actions', 'actions must be a non-empty object keyed by action name.');
156
+ return finishResult(ctx);
157
+ }
158
+ const declaredActions = new Set();
159
+ for (const [action, entry] of Object.entries(manifest.actions)) {
160
+ const path = `actions.${action}`;
161
+ if (!OFFICIAL_ACTION_SET.has(action) && !/^[a-z0-9]+(?:[._-][a-z0-9]+)+$/u.test(action)) {
162
+ addFinding(ctx, 'error', 'action_manifest.custom_action_not_namespaced', path, `${action} must be an official action or a lowercase namespaced custom action.`);
250
163
  }
251
- else {
252
- capabilities.forEach((capability, index) => {
253
- const path = `capabilities[${index}]`;
254
- if (!isRecord(capability)) {
255
- addFinding(ctx, 'error', 'action_manifest.invalid_capability', path, `${path} must be an object.`);
256
- return;
257
- }
258
- if (!isNonEmptyString(capability.capability)) {
259
- addFinding(ctx, 'error', 'action_manifest.invalid_capability_name', `${path}.capability`, `${path}.capability must be a non-empty string.`);
260
- }
261
- if (capability.status !== 'supported' &&
262
- capability.status !== 'unsupported' &&
263
- capability.status !== 'partial' &&
264
- capability.status !== 'planned') {
265
- addFinding(ctx, 'error', 'action_manifest.invalid_capability_status', `${path}.status`, `${path}.status must be supported, unsupported, partial, or planned.`);
266
- }
267
- for (const stringField of ['provider', 'reason']) {
268
- const value = capability[stringField];
269
- if (value != null && typeof value !== 'string') {
270
- addFinding(ctx, 'error', 'action_manifest.invalid_capability_field', `${path}.${stringField}`, `${path}.${stringField} must be a string when present.`);
271
- }
272
- }
273
- for (const arrayField of ['platforms', 'modes', 'artifactTypes']) {
274
- const value = capability[arrayField];
275
- if (value != null &&
276
- (!Array.isArray(value) || value.some((entry) => !isNonEmptyString(entry)))) {
277
- addFinding(ctx, 'error', 'action_manifest.invalid_capability_field', `${path}.${arrayField}`, `${path}.${arrayField} must be an array of non-empty strings when present.`);
278
- }
279
- }
280
- });
164
+ declaredActions.add(action);
165
+ validateActionCatalogEntry(ctx, action, entry, path);
166
+ if (!OFFICIAL_ACTION_SET.has(action) &&
167
+ (!isRecord(entry) || !Object.hasOwn(entry, 'execution_capabilities'))) {
168
+ addFinding(ctx, 'error', 'action_manifest.missing_execution_capabilities', `${path}.execution_capabilities`, 'Custom actions must explicitly declare execution_capabilities, including an empty array for read-only actions.');
281
169
  }
282
170
  }
283
- const observers = manifest.observers;
284
- if (observers != null) {
285
- if (!Array.isArray(observers)) {
171
+ if (Object.hasOwn(manifest, 'observers')) {
172
+ if (!Array.isArray(manifest.observers)) {
286
173
  addFinding(ctx, 'error', 'action_manifest.invalid_observers', 'observers', 'observers must be an array when present.');
287
174
  }
288
175
  else {
289
176
  const declaredObservers = new Set();
290
- observers.forEach((observer, index) => {
291
- const path = `observers[${index}]`;
292
- if (!isRecord(observer)) {
293
- addFinding(ctx, 'error', 'action_manifest.invalid_observer', path, `${path} must be an object.`);
294
- return;
295
- }
296
- if (!isNonEmptyString(observer.ref)) {
297
- addFinding(ctx, 'error', 'action_manifest.invalid_observer_ref', `${path}.ref`, `${path}.ref must be a non-empty string.`);
298
- }
299
- else {
300
- if (!BUILT_IN_UI_OBSERVER_SET.has(observer.ref) && !observer.ref.includes('.')) {
301
- addFinding(ctx, 'error', 'action_manifest.invalid_observer_ref', `${path}.ref`, `${observer.ref} must be a built-in UI observer ref or a namespaced custom ref.`);
302
- }
303
- if (declaredObservers.has(observer.ref)) {
304
- addFinding(ctx, 'error', 'action_manifest.duplicate_observer', `${path}.ref`, `${observer.ref} is declared more than once.`);
305
- }
306
- declaredObservers.add(observer.ref);
307
- }
308
- if (!isNonEmptyString(observer.description)) {
309
- addFinding(ctx, 'error', 'action_manifest.invalid_observer_description', `${path}.description`, `${path}.description must be a non-empty string.`);
310
- }
311
- if (observer.default_for != null) {
312
- if (!Array.isArray(observer.default_for)) {
313
- addFinding(ctx, 'error', 'action_manifest.invalid_observer_default_for', `${path}.default_for`, `${path}.default_for must be an array when present.`);
314
- }
315
- else {
316
- observer.default_for.forEach((action, actionIndex) => {
317
- if (!isNonEmptyString(action) || !declaredActions.has(action)) {
318
- addFinding(ctx, 'error', 'action_manifest.invalid_observer_default_for', `${path}.default_for[${actionIndex}]`, `${path}.default_for[${actionIndex}] must reference a declared action.`);
319
- }
320
- });
321
- }
322
- }
323
- for (const field of ['cost', 'redaction']) {
324
- if (observer[field] != null && typeof observer[field] !== 'string') {
325
- addFinding(ctx, 'error', 'action_manifest.invalid_observer_field', `${path}.${field}`, `${path}.${field} must be a string when present.`);
326
- }
327
- }
328
- });
177
+ manifest.observers.forEach((observer, index) => validateObserver(ctx, observer, index, declaredActions, declaredObservers));
329
178
  }
330
179
  }
331
180
  return finishResult(ctx);