@aionis/manifest 0.1.1

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 (102) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/LICENSE +178 -0
  3. package/README.md +170 -0
  4. package/dist/ast/types.d.ts +34 -0
  5. package/dist/ast/types.js +1 -0
  6. package/dist/cli.d.ts +2 -0
  7. package/dist/cli.js +122 -0
  8. package/dist/compile.d.ts +14 -0
  9. package/dist/compile.js +219 -0
  10. package/dist/contracts.d.ts +12610 -0
  11. package/dist/contracts.js +401 -0
  12. package/dist/diagnostics/types.d.ts +17 -0
  13. package/dist/diagnostics/types.js +1 -0
  14. package/dist/execute/localRuntime.d.ts +5 -0
  15. package/dist/execute/localRuntime.js +165 -0
  16. package/dist/execute/moduleRuntime.d.ts +25 -0
  17. package/dist/execute/moduleRuntime.js +352 -0
  18. package/dist/execute/types.d.ts +113 -0
  19. package/dist/execute/types.js +1 -0
  20. package/dist/execute-cli.d.ts +2 -0
  21. package/dist/execute-cli.js +112 -0
  22. package/dist/execute.d.ts +6 -0
  23. package/dist/execute.js +46 -0
  24. package/dist/graph/buildExecutionGraph.d.ts +8 -0
  25. package/dist/graph/buildExecutionGraph.js +69 -0
  26. package/dist/graph/types.d.ts +24 -0
  27. package/dist/graph/types.js +1 -0
  28. package/dist/handoff-store-cli.d.ts +2 -0
  29. package/dist/handoff-store-cli.js +139 -0
  30. package/dist/handoff-store.d.ts +103 -0
  31. package/dist/handoff-store.js +78 -0
  32. package/dist/index.d.ts +22 -0
  33. package/dist/index.js +21 -0
  34. package/dist/ir/types.d.ts +92 -0
  35. package/dist/ir/types.js +1 -0
  36. package/dist/parser/parseAst.d.ts +3 -0
  37. package/dist/parser/parseAst.js +207 -0
  38. package/dist/parser/payload.d.ts +6 -0
  39. package/dist/parser/payload.js +211 -0
  40. package/dist/plan/buildExecutionPlan.d.ts +9 -0
  41. package/dist/plan/buildExecutionPlan.js +98 -0
  42. package/dist/plan/types.d.ts +44 -0
  43. package/dist/plan/types.js +1 -0
  44. package/dist/publish-cli.d.ts +2 -0
  45. package/dist/publish-cli.js +249 -0
  46. package/dist/publish.d.ts +148 -0
  47. package/dist/publish.js +190 -0
  48. package/dist/recover-cli.d.ts +2 -0
  49. package/dist/recover-cli.js +258 -0
  50. package/dist/recover.d.ts +489 -0
  51. package/dist/recover.js +290 -0
  52. package/dist/refs/resolveRefs.d.ts +13 -0
  53. package/dist/refs/resolveRefs.js +104 -0
  54. package/dist/registry/loadModuleRegistry.d.ts +28 -0
  55. package/dist/registry/loadModuleRegistry.js +97 -0
  56. package/dist/registry/types.d.ts +20 -0
  57. package/dist/registry/types.js +2 -0
  58. package/dist/resume-cli.d.ts +2 -0
  59. package/dist/resume-cli.js +379 -0
  60. package/dist/resume.d.ts +2076 -0
  61. package/dist/resume.js +452 -0
  62. package/dist/run-cli.d.ts +2 -0
  63. package/dist/run-cli.js +119 -0
  64. package/dist/run.d.ts +9 -0
  65. package/dist/run.js +43 -0
  66. package/dist/runtime-handoff-cli.d.ts +2 -0
  67. package/dist/runtime-handoff-cli.js +179 -0
  68. package/dist/runtime-handoff.d.ts +914 -0
  69. package/dist/runtime-handoff.js +383 -0
  70. package/dist/scanner/scanSource.d.ts +9 -0
  71. package/dist/scanner/scanSource.js +43 -0
  72. package/dist/schema/validateIrSchemas.d.ts +3 -0
  73. package/dist/schema/validateIrSchemas.js +64 -0
  74. package/dist/validate-module-cli.d.ts +2 -0
  75. package/dist/validate-module-cli.js +93 -0
  76. package/dist/validate-registry-cli.d.ts +2 -0
  77. package/dist/validate-registry-cli.js +82 -0
  78. package/dist/validate.d.ts +52 -0
  79. package/dist/validate.js +91 -0
  80. package/fixtures/duplicate-doc.aionis.md +19 -0
  81. package/fixtures/fenced-example.aionis.md +27 -0
  82. package/fixtures/malformed-payload.aionis.md +9 -0
  83. package/fixtures/npm-installed-module-registry.json +17 -0
  84. package/fixtures/standalone-module-registry.json +13 -0
  85. package/fixtures/standalone-runner-plan.json +51 -0
  86. package/fixtures/standalone-runner.aionis.md +29 -0
  87. package/fixtures/unresolved-ref.aionis.md +14 -0
  88. package/fixtures/valid-minimal.aionis.md +24 -0
  89. package/fixtures/valid-workflow.aionis.md +29 -0
  90. package/official-modules/copy-summary/CHANGELOG.md +6 -0
  91. package/official-modules/copy-summary/README.md +43 -0
  92. package/official-modules/copy-summary/index.mjs +41 -0
  93. package/official-modules/copy-summary/package.json +31 -0
  94. package/official-modules/json-transform/CHANGELOG.md +6 -0
  95. package/official-modules/json-transform/README.md +51 -0
  96. package/official-modules/json-transform/index.mjs +53 -0
  97. package/official-modules/json-transform/package.json +31 -0
  98. package/official-modules/research-claims/CHANGELOG.md +6 -0
  99. package/official-modules/research-claims/README.md +47 -0
  100. package/official-modules/research-claims/index.mjs +44 -0
  101. package/official-modules/research-claims/package.json +31 -0
  102. package/package.json +74 -0
@@ -0,0 +1,352 @@
1
+ import { validateExecutionModuleManifest } from "../contracts.js";
2
+ import { AIONIS_MANIFEST_EXECUTION_RESULT_VERSION, } from "./types.js";
3
+ function isObject(value) {
4
+ return typeof value === "object" && value !== null && !Array.isArray(value);
5
+ }
6
+ function getPathValue(root, path) {
7
+ let current = root;
8
+ for (const segment of path) {
9
+ if (!isObject(current))
10
+ return undefined;
11
+ current = current[segment];
12
+ }
13
+ return current;
14
+ }
15
+ export function resolveExecutionInput(plan, outputs, step) {
16
+ if (step.input)
17
+ return step.input;
18
+ if (!step.input_ref)
19
+ return {};
20
+ if (step.input_ref === "ctx")
21
+ return plan.context.merged;
22
+ if (step.input_ref.startsWith("ctx.")) {
23
+ return getPathValue(plan.context.merged, step.input_ref.slice(4).split(".")) ?? null;
24
+ }
25
+ if (step.input_ref in outputs)
26
+ return outputs[step.input_ref];
27
+ const [rootRef, ...rest] = step.input_ref.split(".");
28
+ if ((rootRef === "run" || rootRef === "out") && rest.length > 1) {
29
+ const candidate = `${rootRef}.${rest[0]}`;
30
+ if (candidate in outputs) {
31
+ return getPathValue(outputs[candidate], rest.slice(1)) ?? null;
32
+ }
33
+ }
34
+ return null;
35
+ }
36
+ function missingDependency(step, outputs) {
37
+ for (const dependency of step.depends_on) {
38
+ if (!(dependency in outputs))
39
+ return dependency;
40
+ }
41
+ return null;
42
+ }
43
+ function contractPath(path, segment) {
44
+ return path === "$" ? `$.${segment}` : `${path}.${segment}`;
45
+ }
46
+ function validateValueAgainstContract(value, contract, path = "$") {
47
+ switch (contract.kind) {
48
+ case "any":
49
+ return [];
50
+ case "string":
51
+ return typeof value === "string" ? [] : [`Expected string at '${path}'.`];
52
+ case "number":
53
+ return typeof value === "number" ? [] : [`Expected number at '${path}'.`];
54
+ case "boolean":
55
+ return typeof value === "boolean" ? [] : [`Expected boolean at '${path}'.`];
56
+ case "null":
57
+ return value === null ? [] : [`Expected null at '${path}'.`];
58
+ case "array": {
59
+ if (!Array.isArray(value))
60
+ return [`Expected array at '${path}'.`];
61
+ if (!contract.items)
62
+ return [];
63
+ return value.flatMap((item, index) => validateValueAgainstContract(item, contract.items, `${path}[${index}]`));
64
+ }
65
+ case "object": {
66
+ if (!isObject(value))
67
+ return [`Expected object at '${path}'.`];
68
+ const errors = [];
69
+ const properties = contract.properties ?? {};
70
+ const required = new Set(contract.required ?? []);
71
+ for (const key of required) {
72
+ if (!(key in value))
73
+ errors.push(`Missing required property '${key}' at '${path}'.`);
74
+ }
75
+ for (const [key, propertyContract] of Object.entries(properties)) {
76
+ if (!(key in value))
77
+ continue;
78
+ errors.push(...validateValueAgainstContract(value[key], propertyContract, contractPath(path, key)));
79
+ }
80
+ if (contract.additional_properties === false) {
81
+ for (const key of Object.keys(value)) {
82
+ if (!(key in properties))
83
+ errors.push(`Unexpected property '${key}' at '${path}'.`);
84
+ }
85
+ }
86
+ return errors;
87
+ }
88
+ }
89
+ }
90
+ function missingModuleCapabilities(manifest, capabilities) {
91
+ return (manifest.required_capabilities ?? []).filter((capability) => !capabilities[capability]);
92
+ }
93
+ function isModuleOutcome(value) {
94
+ return (typeof value === "object" &&
95
+ value !== null &&
96
+ !Array.isArray(value) &&
97
+ "kind" in value &&
98
+ value.kind === "module_result" &&
99
+ "output" in value);
100
+ }
101
+ export function createExecutionRuntimeCapabilities(overrides = {}) {
102
+ return {
103
+ direct_execution: true,
104
+ deterministic_replay: false,
105
+ state_persistence: false,
106
+ memory_publish: false,
107
+ handoff_recover: false,
108
+ module_registry: true,
109
+ evidence_capture: false,
110
+ ...overrides,
111
+ };
112
+ }
113
+ export class StaticModuleRegistry {
114
+ #modules;
115
+ constructor(modules) {
116
+ this.#modules = new Map(modules.map((definition) => {
117
+ validateExecutionModuleManifest(definition.manifest);
118
+ return [definition.manifest.module, definition];
119
+ }));
120
+ }
121
+ has(moduleName) {
122
+ return this.#modules.has(moduleName);
123
+ }
124
+ get(moduleName) {
125
+ return this.#modules.get(moduleName);
126
+ }
127
+ getManifest(moduleName) {
128
+ return this.#modules.get(moduleName)?.manifest;
129
+ }
130
+ list() {
131
+ return [...this.#modules.values()];
132
+ }
133
+ listManifests() {
134
+ return this.list().map((definition) => definition.manifest);
135
+ }
136
+ }
137
+ export class ModuleRegistryExecutionRuntime {
138
+ runtime_id;
139
+ #registry;
140
+ #capabilities;
141
+ constructor(args) {
142
+ this.runtime_id = args.runtime_id;
143
+ this.#registry = args.registry;
144
+ this.#capabilities = createExecutionRuntimeCapabilities(args.capabilities);
145
+ }
146
+ capabilities() {
147
+ return this.#capabilities;
148
+ }
149
+ async execute(plan) {
150
+ const outputs = {};
151
+ const artifacts = [];
152
+ const evidence = [];
153
+ const nodeResults = [];
154
+ const errors = [];
155
+ for (const step of plan.executions) {
156
+ const unmetDependency = missingDependency(step, outputs);
157
+ if (unmetDependency) {
158
+ const message = `Execution '${step.execution_id}' is blocked on missing dependency '${unmetDependency}'.`;
159
+ nodeResults.push({
160
+ execution_id: step.execution_id,
161
+ module: step.module,
162
+ tool: step.tool,
163
+ agent: step.agent,
164
+ status: "failed",
165
+ input_ref: step.input_ref,
166
+ output_ref: step.output_ref,
167
+ error: message,
168
+ });
169
+ errors.push(message);
170
+ continue;
171
+ }
172
+ if (!step.module) {
173
+ const message = `Execution '${step.execution_id}' has no module and cannot run on runtime '${this.runtime_id}'.`;
174
+ nodeResults.push({
175
+ execution_id: step.execution_id,
176
+ module: step.module,
177
+ tool: step.tool,
178
+ agent: step.agent,
179
+ status: "failed",
180
+ input_ref: step.input_ref,
181
+ output_ref: step.output_ref,
182
+ error: message,
183
+ });
184
+ errors.push(message);
185
+ continue;
186
+ }
187
+ const definition = this.#registry.get(step.module);
188
+ if (!definition) {
189
+ const message = `Module '${step.module}' is not supported by runtime '${this.runtime_id}'.`;
190
+ nodeResults.push({
191
+ execution_id: step.execution_id,
192
+ module: step.module,
193
+ tool: step.tool,
194
+ agent: step.agent,
195
+ status: "failed",
196
+ input_ref: step.input_ref,
197
+ output_ref: step.output_ref,
198
+ error: message,
199
+ });
200
+ errors.push(message);
201
+ continue;
202
+ }
203
+ const missingCapabilities = missingModuleCapabilities(definition.manifest, this.#capabilities);
204
+ if (missingCapabilities.length > 0) {
205
+ const message = `Module '${step.module}' requires unsupported runtime capabilities: ${missingCapabilities.join(", ")}.`;
206
+ nodeResults.push({
207
+ execution_id: step.execution_id,
208
+ module: step.module,
209
+ tool: step.tool,
210
+ agent: step.agent,
211
+ status: "failed",
212
+ input_ref: step.input_ref,
213
+ output_ref: step.output_ref,
214
+ error: message,
215
+ });
216
+ errors.push(message);
217
+ continue;
218
+ }
219
+ const input = resolveExecutionInput(plan, outputs, step);
220
+ if (definition.manifest.input_contract) {
221
+ const inputErrors = validateValueAgainstContract(input, definition.manifest.input_contract);
222
+ if (inputErrors.length > 0) {
223
+ const message = `Input contract validation failed for module '${step.module}': ${inputErrors.join(" ")}`;
224
+ nodeResults.push({
225
+ execution_id: step.execution_id,
226
+ module: step.module,
227
+ tool: step.tool,
228
+ agent: step.agent,
229
+ status: "failed",
230
+ input_ref: step.input_ref,
231
+ output_ref: step.output_ref,
232
+ error: message,
233
+ });
234
+ errors.push(message);
235
+ continue;
236
+ }
237
+ }
238
+ const context = {
239
+ plan,
240
+ step,
241
+ outputs,
242
+ runtime_id: this.runtime_id,
243
+ };
244
+ const rawResult = await definition.handler(input, context);
245
+ const normalized = isModuleOutcome(rawResult)
246
+ ? rawResult
247
+ : {
248
+ kind: "module_result",
249
+ output: rawResult,
250
+ artifacts: [],
251
+ evidence: [],
252
+ };
253
+ const output = normalized.output;
254
+ const producedArtifacts = normalized.artifacts ?? [];
255
+ const producedEvidence = normalized.evidence ?? [];
256
+ if (definition.manifest.output_contract) {
257
+ const outputErrors = validateValueAgainstContract(output, definition.manifest.output_contract);
258
+ if (outputErrors.length > 0) {
259
+ const message = `Output contract validation failed for module '${step.module}': ${outputErrors.join(" ")}`;
260
+ nodeResults.push({
261
+ execution_id: step.execution_id,
262
+ module: step.module,
263
+ tool: step.tool,
264
+ agent: step.agent,
265
+ status: "failed",
266
+ input_ref: step.input_ref,
267
+ output_ref: step.output_ref,
268
+ error: message,
269
+ });
270
+ errors.push(message);
271
+ continue;
272
+ }
273
+ }
274
+ if (definition.manifest.artifact_contract) {
275
+ const artifactErrors = producedArtifacts.flatMap((value, index) => validateValueAgainstContract(value, definition.manifest.artifact_contract, `artifacts[${index}]`));
276
+ if (artifactErrors.length > 0) {
277
+ const message = `Artifact contract validation failed for module '${step.module}': ${artifactErrors.join(" ")}`;
278
+ nodeResults.push({
279
+ execution_id: step.execution_id,
280
+ module: step.module,
281
+ tool: step.tool,
282
+ agent: step.agent,
283
+ status: "failed",
284
+ input_ref: step.input_ref,
285
+ output_ref: step.output_ref,
286
+ error: message,
287
+ });
288
+ errors.push(message);
289
+ continue;
290
+ }
291
+ }
292
+ if (definition.manifest.evidence_contract) {
293
+ const evidenceErrors = producedEvidence.flatMap((value, index) => validateValueAgainstContract(value, definition.manifest.evidence_contract, `evidence[${index}]`));
294
+ if (evidenceErrors.length > 0) {
295
+ const message = `Evidence contract validation failed for module '${step.module}': ${evidenceErrors.join(" ")}`;
296
+ nodeResults.push({
297
+ execution_id: step.execution_id,
298
+ module: step.module,
299
+ tool: step.tool,
300
+ agent: step.agent,
301
+ status: "failed",
302
+ input_ref: step.input_ref,
303
+ output_ref: step.output_ref,
304
+ error: message,
305
+ });
306
+ errors.push(message);
307
+ continue;
308
+ }
309
+ }
310
+ if (step.output_ref)
311
+ outputs[step.output_ref] = output;
312
+ artifacts.push(...producedArtifacts.map((value) => ({
313
+ execution_id: step.execution_id,
314
+ module: step.module,
315
+ value,
316
+ })));
317
+ evidence.push(...producedEvidence.map((value) => ({
318
+ execution_id: step.execution_id,
319
+ module: step.module,
320
+ value,
321
+ })));
322
+ nodeResults.push({
323
+ execution_id: step.execution_id,
324
+ module: step.module,
325
+ tool: step.tool,
326
+ agent: step.agent,
327
+ status: "success",
328
+ input_ref: step.input_ref,
329
+ output_ref: step.output_ref,
330
+ output,
331
+ artifacts: producedArtifacts,
332
+ evidence: producedEvidence,
333
+ });
334
+ }
335
+ return {
336
+ execution_result_version: AIONIS_MANIFEST_EXECUTION_RESULT_VERSION,
337
+ runtime_id: this.runtime_id,
338
+ executed_at: new Date().toISOString(),
339
+ plan_version: plan.plan_version,
340
+ doc_id: plan.doc?.id ?? null,
341
+ status: errors.length > 0 ? "failed" : "success",
342
+ outputs,
343
+ artifacts,
344
+ evidence,
345
+ node_results: nodeResults,
346
+ expected_outputs: plan.expected_outputs,
347
+ warnings: [],
348
+ errors,
349
+ diagnostics: plan.diagnostics,
350
+ };
351
+ }
352
+ }
@@ -0,0 +1,113 @@
1
+ import type { Diagnostic } from "../diagnostics/types.js";
2
+ import type { AionisValue } from "../ir/types.js";
3
+ import type { ExecutionPlanStep, ExecutionPlanV1 } from "../plan/types.js";
4
+ export declare const AIONIS_MANIFEST_EXECUTION_RESULT_VERSION: "aionis_manifest_execution_result_v1";
5
+ export type AionisManifestRunInputKind = "source" | "compile-envelope" | "plan";
6
+ export interface ExecutionNodeResult {
7
+ execution_id: string;
8
+ module?: string;
9
+ tool?: string;
10
+ agent?: string;
11
+ status: "success" | "failed" | "skipped";
12
+ input_ref?: string;
13
+ output_ref?: string;
14
+ output?: AionisValue;
15
+ artifacts?: AionisValue[];
16
+ evidence?: AionisValue[];
17
+ error?: string;
18
+ }
19
+ export interface ExecutionArtifactRecord {
20
+ execution_id: string;
21
+ module?: string;
22
+ value: AionisValue;
23
+ }
24
+ export interface ExecutionEvidenceRecord {
25
+ execution_id: string;
26
+ module?: string;
27
+ value: AionisValue;
28
+ }
29
+ export type ExecutionRuntimeCapability = "direct_execution" | "deterministic_replay" | "state_persistence" | "memory_publish" | "handoff_recover" | "module_registry" | "evidence_capture";
30
+ export interface ExecutionRuntimeCapabilities {
31
+ direct_execution: boolean;
32
+ deterministic_replay: boolean;
33
+ state_persistence: boolean;
34
+ memory_publish: boolean;
35
+ handoff_recover: boolean;
36
+ module_registry: boolean;
37
+ evidence_capture: boolean;
38
+ }
39
+ export interface ExecutionModuleContext {
40
+ plan: ExecutionPlanV1;
41
+ step: ExecutionPlanStep;
42
+ outputs: Record<string, AionisValue>;
43
+ runtime_id: string;
44
+ }
45
+ export type ExecutionModuleValueContractKind = "any" | "string" | "number" | "boolean" | "null" | "array" | "object";
46
+ export interface ExecutionModuleValueContract {
47
+ kind: ExecutionModuleValueContractKind;
48
+ description?: string;
49
+ properties?: Record<string, ExecutionModuleValueContract>;
50
+ required?: string[];
51
+ items?: ExecutionModuleValueContract;
52
+ additional_properties?: boolean;
53
+ }
54
+ export interface ExecutionModuleManifest {
55
+ module: string;
56
+ version: string;
57
+ title?: string;
58
+ description?: string;
59
+ deterministic?: boolean;
60
+ required_capabilities?: ExecutionRuntimeCapability[];
61
+ input_contract?: ExecutionModuleValueContract;
62
+ output_contract?: ExecutionModuleValueContract;
63
+ artifact_contract?: ExecutionModuleValueContract;
64
+ evidence_contract?: ExecutionModuleValueContract;
65
+ }
66
+ export interface ExecutionModuleOutcome {
67
+ kind: "module_result";
68
+ output: AionisValue;
69
+ artifacts?: AionisValue[];
70
+ evidence?: AionisValue[];
71
+ }
72
+ export type ExecutionModuleHandler = (input: AionisValue, context: ExecutionModuleContext) => Promise<AionisValue | ExecutionModuleOutcome> | AionisValue | ExecutionModuleOutcome;
73
+ export interface ExecutionModuleDefinition {
74
+ manifest: ExecutionModuleManifest;
75
+ handler: ExecutionModuleHandler;
76
+ }
77
+ export interface ExecutionModuleRegistry {
78
+ has(moduleName: string): boolean;
79
+ get(moduleName: string): ExecutionModuleDefinition | undefined;
80
+ getManifest(moduleName: string): ExecutionModuleManifest | undefined;
81
+ list(): ExecutionModuleDefinition[];
82
+ listManifests(): ExecutionModuleManifest[];
83
+ }
84
+ export interface ExecutionResultV1 {
85
+ execution_result_version: typeof AIONIS_MANIFEST_EXECUTION_RESULT_VERSION;
86
+ runtime_id: string;
87
+ executed_at: string;
88
+ plan_version: ExecutionPlanV1["plan_version"];
89
+ doc_id: string | null;
90
+ status: "success" | "failed";
91
+ outputs: Record<string, AionisValue>;
92
+ artifacts: ExecutionArtifactRecord[];
93
+ evidence: ExecutionEvidenceRecord[];
94
+ node_results: ExecutionNodeResult[];
95
+ expected_outputs: string[];
96
+ warnings: string[];
97
+ errors: string[];
98
+ diagnostics: Diagnostic[];
99
+ }
100
+ export interface ExecutionRuntime {
101
+ runtime_id: string;
102
+ capabilities(): ExecutionRuntimeCapabilities;
103
+ execute(plan: ExecutionPlanV1): Promise<ExecutionResultV1>;
104
+ }
105
+ export interface ExecuteAionisManifestOptions {
106
+ runtime?: ExecutionRuntime;
107
+ }
108
+ export interface AionisManifestRunRequest {
109
+ inputKind: AionisManifestRunInputKind;
110
+ registryPath: string;
111
+ cwd?: string;
112
+ compact?: boolean;
113
+ }
@@ -0,0 +1 @@
1
+ export const AIONIS_MANIFEST_EXECUTION_RESULT_VERSION = "aionis_manifest_execution_result_v1";
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,112 @@
1
+ #!/usr/bin/env node
2
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
3
+ import { dirname, resolve } from "node:path";
4
+ import process from "node:process";
5
+ import { AionisManifestExecutionResultSchema } from "./contracts.js";
6
+ import { AionisManifestExecutionError, compileAndExecuteAionisManifest, executeCompileEnvelope, executeExecutionPlan, } from "./execute.js";
7
+ class CliUsageError extends Error {
8
+ }
9
+ function printHelp() {
10
+ process.stdout.write([
11
+ "execute-aionis-manifest",
12
+ "",
13
+ "Usage:",
14
+ " execute-aionis-manifest <input-file> [--input-kind source|compile-envelope|plan] [--out <path>] [--compact]",
15
+ "",
16
+ "Options:",
17
+ " --input-kind <kind> Select source, compile-envelope, or plan input. Default: source",
18
+ " --out <path> Write output JSON to a file instead of stdout",
19
+ " --compact Print compact JSON instead of pretty JSON",
20
+ " --help Show this message",
21
+ "",
22
+ ].join("\n"));
23
+ }
24
+ function parseArgs(argv) {
25
+ let inputPath = null;
26
+ const flags = {
27
+ inputKind: "source",
28
+ out: null,
29
+ compact: false,
30
+ help: false,
31
+ };
32
+ for (let i = 0; i < argv.length; i += 1) {
33
+ const token = argv[i];
34
+ if (token === "--help" || token === "-h") {
35
+ flags.help = true;
36
+ continue;
37
+ }
38
+ if (token === "--compact") {
39
+ flags.compact = true;
40
+ continue;
41
+ }
42
+ if (token === "--input-kind") {
43
+ const next = argv[i + 1];
44
+ if (!next)
45
+ throw new CliUsageError("Missing value for --input-kind.");
46
+ if (!["source", "compile-envelope", "plan"].includes(next)) {
47
+ throw new CliUsageError(`Unsupported input kind '${next}'.`);
48
+ }
49
+ flags.inputKind = next;
50
+ i += 1;
51
+ continue;
52
+ }
53
+ if (token === "--out") {
54
+ const next = argv[i + 1];
55
+ if (!next)
56
+ throw new CliUsageError("Missing value for --out.");
57
+ flags.out = next;
58
+ i += 1;
59
+ continue;
60
+ }
61
+ if (token.startsWith("--")) {
62
+ throw new CliUsageError(`Unknown flag '${token}'.`);
63
+ }
64
+ if (inputPath)
65
+ throw new CliUsageError("Only one input file may be provided.");
66
+ inputPath = token;
67
+ }
68
+ return { inputPath, flags };
69
+ }
70
+ async function writeOutput(pathname, contents) {
71
+ await mkdir(dirname(pathname), { recursive: true });
72
+ await writeFile(pathname, contents, "utf8");
73
+ }
74
+ async function main() {
75
+ const { inputPath, flags } = parseArgs(process.argv.slice(2));
76
+ if (flags.help) {
77
+ printHelp();
78
+ return;
79
+ }
80
+ if (!inputPath)
81
+ throw new CliUsageError("An input file path is required.");
82
+ const resolvedInput = resolve(process.cwd(), inputPath);
83
+ const source = await readFile(resolvedInput, "utf8");
84
+ const result = flags.inputKind === "source"
85
+ ? await compileAndExecuteAionisManifest(source)
86
+ : flags.inputKind === "compile-envelope"
87
+ ? await executeCompileEnvelope(JSON.parse(source))
88
+ : await executeExecutionPlan(JSON.parse(source));
89
+ const parsed = AionisManifestExecutionResultSchema.parse(result);
90
+ const rendered = flags.compact ? JSON.stringify(parsed) : `${JSON.stringify(parsed, null, 2)}\n`;
91
+ if (flags.out) {
92
+ await writeOutput(resolve(process.cwd(), flags.out), rendered);
93
+ }
94
+ else {
95
+ process.stdout.write(rendered);
96
+ }
97
+ if (parsed.status === "failed") {
98
+ process.exitCode = 1;
99
+ }
100
+ }
101
+ main().catch((error) => {
102
+ if (error instanceof CliUsageError || error instanceof AionisManifestExecutionError) {
103
+ process.stderr.write(`${error.message}\n`);
104
+ if (error instanceof CliUsageError)
105
+ printHelp();
106
+ process.exitCode = error instanceof CliUsageError ? 2 : 1;
107
+ return;
108
+ }
109
+ const message = error instanceof Error ? error.message : String(error);
110
+ process.stderr.write(`${message}\n`);
111
+ process.exitCode = 1;
112
+ });
@@ -0,0 +1,6 @@
1
+ import type { ExecuteAionisManifestOptions, ExecutionResultV1 } from "./execute/types.js";
2
+ export declare class AionisManifestExecutionError extends Error {
3
+ }
4
+ export declare function compileAndExecuteAionisManifest(source: string, options?: ExecuteAionisManifestOptions): Promise<ExecutionResultV1>;
5
+ export declare function executeCompileEnvelope(value: unknown, options?: ExecuteAionisManifestOptions): Promise<ExecutionResultV1>;
6
+ export declare function executeExecutionPlan(value: unknown, options?: ExecuteAionisManifestOptions): Promise<ExecutionResultV1>;
@@ -0,0 +1,46 @@
1
+ import { validateCompileEnvelope, ExecutionPlanSchema } from "./contracts.js";
2
+ import { compileAionisManifest } from "./compile.js";
3
+ import { LocalExecutionRuntime } from "./execute/localRuntime.js";
4
+ import { buildExecutionPlanV1 } from "./plan/buildExecutionPlan.js";
5
+ export class AionisManifestExecutionError extends Error {
6
+ }
7
+ function resolveRuntime(options) {
8
+ return options?.runtime ?? new LocalExecutionRuntime();
9
+ }
10
+ function planFromCompileResult(result) {
11
+ return result.plan;
12
+ }
13
+ function asExecutionPlan(value) {
14
+ return value;
15
+ }
16
+ function asAionisManifestIr(value) {
17
+ return value;
18
+ }
19
+ function asExecutionGraph(value) {
20
+ return value ?? null;
21
+ }
22
+ function planFromEnvelope(value) {
23
+ const envelope = validateCompileEnvelope(value);
24
+ if (envelope.artifacts.plan)
25
+ return asExecutionPlan(envelope.artifacts.plan);
26
+ if (!envelope.artifacts.ir) {
27
+ throw new AionisManifestExecutionError(`Execution requires a plan or IR artifact. Re-run compile-aionis-manifest with --emit all, --emit ir, or --emit plan; current selected_artifact is '${envelope.selected_artifact}'.`);
28
+ }
29
+ return buildExecutionPlanV1({
30
+ ir: asAionisManifestIr(envelope.artifacts.ir),
31
+ graph: asExecutionGraph(envelope.artifacts.graph),
32
+ diagnostics: envelope.diagnostics,
33
+ });
34
+ }
35
+ export function compileAndExecuteAionisManifest(source, options = {}) {
36
+ const result = compileAionisManifest(source);
37
+ return executeExecutionPlan(planFromCompileResult(result), options);
38
+ }
39
+ export function executeCompileEnvelope(value, options = {}) {
40
+ return executeExecutionPlan(planFromEnvelope(value), options);
41
+ }
42
+ export function executeExecutionPlan(value, options = {}) {
43
+ const plan = asExecutionPlan(ExecutionPlanSchema.parse(value));
44
+ const runtime = resolveRuntime(options);
45
+ return runtime.execute(plan);
46
+ }
@@ -0,0 +1,8 @@
1
+ import type { Diagnostic } from "../diagnostics/types.js";
2
+ import type { ExecutionGraph } from "./types.js";
3
+ import type { AionisManifestIR } from "../ir/types.js";
4
+ export interface GraphBuildResult {
5
+ value: ExecutionGraph | null;
6
+ diagnostics: Diagnostic[];
7
+ }
8
+ export declare function buildExecutionGraph(ir: AionisManifestIR): GraphBuildResult;