@xemahq/dsl 0.8.1 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/package.json +2 -3
  2. package/src/deliverable-spec/index.ts +0 -19
  3. package/src/deliverable-spec/lib/schema.ts +0 -270
  4. package/src/deliverable-spec/lib/types.ts +0 -26
  5. package/src/payload-codec/index.ts +0 -44
  6. package/src/payload-codec/lib/blob-store.ts +0 -176
  7. package/src/payload-codec/lib/codec-context.ts +0 -38
  8. package/src/payload-codec/lib/codec.ts +0 -605
  9. package/src/payload-codec/lib/enums.ts +0 -58
  10. package/src/payload-codec/lib/errors.ts +0 -54
  11. package/src/payload-codec/lib/http-blob-store.ts +0 -267
  12. package/src/payload-codec/lib/lru-cache.ts +0 -81
  13. package/src/payload-codec/lib/payload.ts +0 -26
  14. package/src/payload-codec/temporal/index.ts +0 -36
  15. package/src/workflow/index.ts +0 -108
  16. package/src/workflow/lib/action-input-validator.ts +0 -160
  17. package/src/workflow/lib/compiler/action-shape.ts +0 -71
  18. package/src/workflow/lib/compiler/canonical-json.ts +0 -66
  19. package/src/workflow/lib/compiler/compile.ts +0 -1742
  20. package/src/workflow/lib/compiler/concurrency.ts +0 -223
  21. package/src/workflow/lib/compiler/dag.ts +0 -108
  22. package/src/workflow/lib/compiler/gate-defaults.ts +0 -153
  23. package/src/workflow/lib/compiler/index.ts +0 -11
  24. package/src/workflow/lib/compiler/inputs.ts +0 -254
  25. package/src/workflow/lib/compiler/installation-resource-validator.ts +0 -114
  26. package/src/workflow/lib/compiler/manifest-source.ts +0 -71
  27. package/src/workflow/lib/compiler/matrix.ts +0 -135
  28. package/src/workflow/lib/compiler/mount-plan.ts +0 -190
  29. package/src/workflow/lib/compiler/payload-reach-in.ts +0 -497
  30. package/src/workflow/lib/compiler/permissions.ts +0 -64
  31. package/src/workflow/lib/compiler/retry-timeout.ts +0 -105
  32. package/src/workflow/lib/compiler/review-step.ts +0 -548
  33. package/src/workflow/lib/compiler/types.ts +0 -172
  34. package/src/workflow/lib/compiler/variable-requirements.ts +0 -208
  35. package/src/workflow/lib/deliverable-spec-introspection-error.ts +0 -63
  36. package/src/workflow/lib/deliverable-spec-keys.ts +0 -147
  37. package/src/workflow/lib/deliverable-spec-source-scan.ts +0 -280
  38. package/src/workflow/lib/dispatch-inputs/index.ts +0 -160
  39. package/src/workflow/lib/dispatch-inputs/to-json-schema.ts +0 -60
  40. package/src/workflow/lib/duration.ts +0 -43
  41. package/src/workflow/lib/errors.ts +0 -37
  42. package/src/workflow/lib/expression/ast.ts +0 -108
  43. package/src/workflow/lib/expression/context.ts +0 -148
  44. package/src/workflow/lib/expression/evaluator.ts +0 -492
  45. package/src/workflow/lib/expression/index.ts +0 -28
  46. package/src/workflow/lib/expression/interpolation.ts +0 -84
  47. package/src/workflow/lib/expression/parser.ts +0 -264
  48. package/src/workflow/lib/expression/template.ts +0 -117
  49. package/src/workflow/lib/expression/tokenizer.ts +0 -200
  50. package/src/workflow/lib/expression/tokens.ts +0 -30
  51. package/src/workflow/lib/expression/walk-artifact-refs.ts +0 -232
  52. package/src/workflow/lib/installation-resource-kind.ts +0 -107
  53. package/src/workflow/lib/schemas-loader.ts +0 -64
  54. package/src/workflow/lib/serializer.ts +0 -30
  55. package/src/workflow/lib/types.ts +0 -417
  56. package/src/workflow/lib/validate.ts +0 -199
  57. package/src/workspace-manifest/index.ts +0 -27
  58. package/src/workspace-manifest/lib/compile.ts +0 -619
  59. package/src/workspace-manifest/lib/interpolate.ts +0 -166
  60. package/src/workspace-manifest/lib/resolve-extends.ts +0 -260
  61. package/src/workspace-manifest/lib/schema.ts +0 -692
  62. package/src/workspace-manifest/lib/types.ts +0 -446
@@ -1,160 +0,0 @@
1
- /**
2
- * Runtime validator for an action's `with:` payload against the JSON Schema
3
- * declared in its manifest's `spec.inputs`.
4
- *
5
- * The DSL compiler pins `spec.inputs` into `ActionRef.inputsSchema` so the
6
- * worker validates against the schema that was in effect when the run was
7
- * compiled — not whatever's currently published. The worker calls
8
- * {@link validateActionInputs} from the activity-registry wrapper just before
9
- * dispatching the underlying activity; failures throw fast with a precise
10
- * `inputs.<path>: <message>` pointer instead of letting bad payloads ride
11
- * through to the downstream service.
12
- *
13
- * Implementation choices:
14
- * - A dedicated Ajv instance (separate from the strict one used to validate
15
- * manifests themselves) so user-authored schemas with looser conventions
16
- * still compile. We turn off `strict` because action authors aren't
17
- * schema-spec lawyers — `additionalProperties: false` plus `required`
18
- * already catches typos.
19
- * - Validators are memoized by schema reference identity. CompiledRun
20
- * schemas are frozen objects whose identity is stable for the lifetime of
21
- * the worker process, so a `WeakMap` cache means each schema compiles at
22
- * most once per worker — even across concurrent dispatches.
23
- * - We refuse to compile an empty / non-object schema. If a manifest didn't
24
- * declare `inputs:`, the compiler emits `inputsSchema: null` and the
25
- * caller skips validation entirely.
26
- */
27
- import Ajv2020, { type ErrorObject, type ValidateFunction } from 'ajv/dist/2020';
28
- import addFormats from 'ajv-formats';
29
-
30
- const ajv = new Ajv2020({
31
- // Author-friendly: action manifests use plain JSON Schema, not Ajv-strict
32
- // dialect. We still get type-safety from `additionalProperties: false`
33
- // (every action schema declares it) plus `required:`.
34
- strict: false,
35
- allErrors: true,
36
- useDefaults: false,
37
- validateFormats: true,
38
- });
39
- addFormats(ajv);
40
-
41
- /**
42
- * Custom JSON Schema keyword `x-installation-resource` — marks a string
43
- * field as referencing a resource bound to the calling biome
44
- * installation. The compiler's installation-resource validator
45
- * (workflow-engine `CompilerService`) reads the keyword + queries the
46
- * installation's bound resources of the declared `kind`; if the value
47
- * isn't in the bound set, the dispatch fails BEFORE the workflow
48
- * starts.
49
- *
50
- * At the worker layer (here, AJV runtime) the keyword is a no-op
51
- * accepted metadata — the compiler is the authoritative gate and runs
52
- * with installation scope; by the time the worker validates `with:`
53
- * the compile-time check has already confirmed the reference is bound.
54
- *
55
- * Declaration shape on an action manifest field:
56
- * walletId:
57
- * type: string
58
- * x-installation-resource: { kind: 'wallet' }
59
- *
60
- * Closed `kind` set lives in `installation-resource-kind.ts` to keep
61
- * the wire stable across the SDK, the engine, and biome-host-api.
62
- */
63
- ajv.addKeyword({
64
- keyword: 'x-installation-resource',
65
- metaSchema: {
66
- type: 'object',
67
- additionalProperties: false,
68
- required: ['kind'],
69
- properties: {
70
- kind: { type: 'string', enum: ['wallet', 'repo', 'project', 'channel', 'space'] },
71
- },
72
- },
73
- });
74
-
75
- const validatorCache = new WeakMap<
76
- Readonly<Record<string, unknown>>,
77
- ValidateFunction
78
- >();
79
-
80
- export interface ActionInputValidationFailure {
81
- readonly path: string;
82
- readonly message: string;
83
- }
84
-
85
- export interface ActionInputValidationResult {
86
- readonly valid: boolean;
87
- readonly failures: readonly ActionInputValidationFailure[];
88
- }
89
-
90
- /**
91
- * Validate `value` against the JSON Schema attached to a compiled
92
- * ActionRef. Returns `{ valid: true, failures: [] }` on success.
93
- *
94
- * On failure, returns up to N failures (Ajv `allErrors: true`) each with a
95
- * dotted `inputs.<path>` pointer so callers can compose
96
- * `<actionId>: inputs.slug must match pattern …`-style messages.
97
- *
98
- * Throws synchronously only if the schema itself is unparseable (a bug in
99
- * the compiler or a malformed manifest that slipped past `ACTION_SCHEMA`).
100
- */
101
- export function validateActionInputs(
102
- schema: Readonly<Record<string, unknown>>,
103
- value: unknown,
104
- ): ActionInputValidationResult {
105
- const validate = compileOrGet(schema);
106
- if (validate(value)) {
107
- return { valid: true, failures: [] };
108
- }
109
- const errors = validate.errors ?? [];
110
- return {
111
- valid: false,
112
- failures: errors.map(formatError),
113
- };
114
- }
115
-
116
- function compileOrGet(
117
- schema: Readonly<Record<string, unknown>>,
118
- ): ValidateFunction {
119
- const cached = validatorCache.get(schema);
120
- if (cached) return cached;
121
- const compiled = ajv.compile(schema);
122
- validatorCache.set(schema, compiled);
123
- return compiled;
124
- }
125
-
126
- /**
127
- * Translate an Ajv error object into a deterministic
128
- * `inputs.<path>: <message>` shape.
129
- *
130
- * `instancePath` is JSON-pointer syntax (`/slug`, `/labels/foo`); we
131
- * convert to dotted form and prepend `inputs.` so the pointer matches the
132
- * call-site phrase the workflow author authored (`with.slug`, `with.labels.foo`).
133
- */
134
- function formatError(err: ErrorObject): ActionInputValidationFailure {
135
- const dotted = err.instancePath
136
- .replace(/^\//, '')
137
- .split('/')
138
- .filter((seg) => seg.length > 0)
139
- .join('.');
140
- const path = dotted.length > 0 ? `inputs.${dotted}` : 'inputs';
141
- // For `required` violations Ajv puts the missing key in `params.missingProperty`
142
- // and emits `instancePath: ''` — splice the key into the path so the message
143
- // points at the offending field, not at the parent.
144
- if (err.keyword === 'required' && typeof err.params?.['missingProperty'] === 'string') {
145
- const missing = err.params['missingProperty'] as string;
146
- const subPath = path === 'inputs' ? `inputs.${missing}` : `${path}.${missing}`;
147
- return { path: subPath, message: 'is required but missing' };
148
- }
149
- // additionalProperties: name the unexpected key in the path so the
150
- // workflow author can see exactly which `with:` field the schema refused.
151
- if (err.keyword === 'additionalProperties' && typeof err.params?.['additionalProperty'] === 'string') {
152
- const extra = err.params['additionalProperty'] as string;
153
- const subPath = path === 'inputs' ? `inputs.${extra}` : `${path}.${extra}`;
154
- return { path: subPath, message: 'is not declared on this action — remove it from the with-block' };
155
- }
156
- return {
157
- path,
158
- message: err.message ?? `failed ${err.keyword} check`,
159
- };
160
- }
@@ -1,71 +0,0 @@
1
- import type {
2
- ActionManifest,
3
- AgentActionContract,
4
- WorkspaceManifestActionContract,
5
- } from '../types';
6
-
7
- /**
8
- * Returns the action's `workspace-manifest@v1` contract entry when the
9
- * manifest declares one explicitly. This is the source of truth for the
10
- * manifest-source triplet check in `manifest-source.ts` — biomes ship
11
- * an action by adding `consumes: [{ kind: workspace-manifest, version: v1, ... }]`
12
- * to its manifest and inherit the manifest picker, the canvas
13
- * Inspector, and the runtime resolver lane for free.
14
- */
15
- export function getWorkspaceManifestContract(
16
- actionManifest: ActionManifest | null,
17
- ): WorkspaceManifestActionContract | null {
18
- if (!actionManifest) return null;
19
- const contracts = actionManifest.spec.consumes;
20
- if (!contracts || contracts.length === 0) return null;
21
- for (const c of contracts) {
22
- if (c.kind === 'workspace-manifest' && c.version === 'v1') {
23
- return c;
24
- }
25
- }
26
- return null;
27
- }
28
-
29
- /**
30
- * Returns true when an action manifest opts into the workspace-manifest
31
- * contract (preferred, declarative) OR matches the `inputs:` shape
32
- * heuristic (declares an `agentRef` property). `agentRef` is the sole
33
- * way a workflow names its agent, so its presence on the action's input
34
- * schema is the heuristic. The heuristic remains a fallback so action
35
- * manifests authored before the explicit `consumes` contract still
36
- * compile.
37
- */
38
- export function isAgentShapedAction(
39
- actionManifest: ActionManifest | null,
40
- ): actionManifest is ActionManifest {
41
- if (!actionManifest) return false;
42
- if (getWorkspaceManifestContract(actionManifest) !== null) return true;
43
- const inputs = actionManifest.spec.inputs as
44
- | { properties?: Readonly<Record<string, unknown>> }
45
- | undefined;
46
- const properties = inputs?.properties;
47
- if (!properties) return false;
48
- return 'agentRef' in properties;
49
- }
50
-
51
- /**
52
- * Returns the action's `agent-composition@v1` contract entry when the
53
- * manifest declares one. An action that opts into this contract accepts
54
- * `with.composition` — a `slug@version` reference to an Agent
55
- * in the llm-registry-api composition registry. The runtime resolves the
56
- * composition at dispatch time; the composition is the source of truth
57
- * for the step's agent + sub-agents + skill/tool selection.
58
- */
59
- export function getAgentContract(
60
- actionManifest: ActionManifest | null,
61
- ): AgentActionContract | null {
62
- if (!actionManifest) return null;
63
- const contracts = actionManifest.spec.consumes;
64
- if (!contracts || contracts.length === 0) return null;
65
- for (const c of contracts) {
66
- if (c.kind === 'agent' && c.version === 'v1') {
67
- return c;
68
- }
69
- }
70
- return null;
71
- }
@@ -1,66 +0,0 @@
1
- import { createHash } from 'node:crypto';
2
-
3
- /**
4
- * Canonical JSON serialization used to compute the CompiledRun's sha256.
5
- * Determinism is the whole point: two compilations of the same workflow +
6
- * trigger MUST produce byte-identical output, so every replica derives the
7
- * same hash.
8
- *
9
- * Rules:
10
- * - Object keys are emitted in lexicographic (UTF-16) order.
11
- * - No whitespace.
12
- * - Numbers use JSON.stringify's representation.
13
- * - undefined is forbidden (throws); callers must use explicit null.
14
- * - Symbols / functions are forbidden (throws).
15
- */
16
- export function canonicalJsonStringify(value: unknown): string {
17
- return stringify(value, new Set());
18
- }
19
-
20
- /** Convenience: canonical stringify + sha256 hex. */
21
- export function canonicalJsonSha256(value: unknown): string {
22
- return createHash('sha256').update(canonicalJsonStringify(value), 'utf8').digest('hex');
23
- }
24
-
25
- function stringify(value: unknown, seen: Set<object>): string {
26
- if (value === null) return 'null';
27
- if (value === undefined) {
28
- throw new Error('canonicalJsonStringify: undefined is not serializable');
29
- }
30
- if (typeof value === 'string') return JSON.stringify(value);
31
- if (typeof value === 'number') {
32
- if (!Number.isFinite(value)) {
33
- throw new Error(`canonicalJsonStringify: non-finite number ${value}`);
34
- }
35
- return JSON.stringify(value);
36
- }
37
- if (typeof value === 'boolean') return value ? 'true' : 'false';
38
- if (Array.isArray(value)) {
39
- // Guard against circular references (e.g. cyclic YAML anchors) so a
40
- // self-referential input yields a clear error instead of a stack overflow.
41
- if (seen.has(value)) {
42
- throw new Error('canonicalJsonStringify: circular reference is not serializable');
43
- }
44
- seen.add(value);
45
- const out = `[${value.map((child) => stringify(child, seen)).join(',')}]`;
46
- seen.delete(value);
47
- return out;
48
- }
49
- if (typeof value === 'object') {
50
- if (seen.has(value)) {
51
- throw new Error('canonicalJsonStringify: circular reference is not serializable');
52
- }
53
- seen.add(value);
54
- const record = value as Record<string, unknown>;
55
- const keys = Object.keys(record).sort();
56
- const entries: string[] = [];
57
- for (const key of keys) {
58
- const child = record[key];
59
- if (child === undefined) continue; // drop undefined; do not emit
60
- entries.push(`${JSON.stringify(key)}:${stringify(child, seen)}`);
61
- }
62
- seen.delete(value);
63
- return `{${entries.join(',')}}`;
64
- }
65
- throw new Error(`canonicalJsonStringify: unsupported type ${typeof value}`);
66
- }