@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.
- package/CHANGELOG.md +26 -0
- package/LICENSE +178 -0
- package/README.md +170 -0
- package/dist/ast/types.d.ts +34 -0
- package/dist/ast/types.js +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +122 -0
- package/dist/compile.d.ts +14 -0
- package/dist/compile.js +219 -0
- package/dist/contracts.d.ts +12610 -0
- package/dist/contracts.js +401 -0
- package/dist/diagnostics/types.d.ts +17 -0
- package/dist/diagnostics/types.js +1 -0
- package/dist/execute/localRuntime.d.ts +5 -0
- package/dist/execute/localRuntime.js +165 -0
- package/dist/execute/moduleRuntime.d.ts +25 -0
- package/dist/execute/moduleRuntime.js +352 -0
- package/dist/execute/types.d.ts +113 -0
- package/dist/execute/types.js +1 -0
- package/dist/execute-cli.d.ts +2 -0
- package/dist/execute-cli.js +112 -0
- package/dist/execute.d.ts +6 -0
- package/dist/execute.js +46 -0
- package/dist/graph/buildExecutionGraph.d.ts +8 -0
- package/dist/graph/buildExecutionGraph.js +69 -0
- package/dist/graph/types.d.ts +24 -0
- package/dist/graph/types.js +1 -0
- package/dist/handoff-store-cli.d.ts +2 -0
- package/dist/handoff-store-cli.js +139 -0
- package/dist/handoff-store.d.ts +103 -0
- package/dist/handoff-store.js +78 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +21 -0
- package/dist/ir/types.d.ts +92 -0
- package/dist/ir/types.js +1 -0
- package/dist/parser/parseAst.d.ts +3 -0
- package/dist/parser/parseAst.js +207 -0
- package/dist/parser/payload.d.ts +6 -0
- package/dist/parser/payload.js +211 -0
- package/dist/plan/buildExecutionPlan.d.ts +9 -0
- package/dist/plan/buildExecutionPlan.js +98 -0
- package/dist/plan/types.d.ts +44 -0
- package/dist/plan/types.js +1 -0
- package/dist/publish-cli.d.ts +2 -0
- package/dist/publish-cli.js +249 -0
- package/dist/publish.d.ts +148 -0
- package/dist/publish.js +190 -0
- package/dist/recover-cli.d.ts +2 -0
- package/dist/recover-cli.js +258 -0
- package/dist/recover.d.ts +489 -0
- package/dist/recover.js +290 -0
- package/dist/refs/resolveRefs.d.ts +13 -0
- package/dist/refs/resolveRefs.js +104 -0
- package/dist/registry/loadModuleRegistry.d.ts +28 -0
- package/dist/registry/loadModuleRegistry.js +97 -0
- package/dist/registry/types.d.ts +20 -0
- package/dist/registry/types.js +2 -0
- package/dist/resume-cli.d.ts +2 -0
- package/dist/resume-cli.js +379 -0
- package/dist/resume.d.ts +2076 -0
- package/dist/resume.js +452 -0
- package/dist/run-cli.d.ts +2 -0
- package/dist/run-cli.js +119 -0
- package/dist/run.d.ts +9 -0
- package/dist/run.js +43 -0
- package/dist/runtime-handoff-cli.d.ts +2 -0
- package/dist/runtime-handoff-cli.js +179 -0
- package/dist/runtime-handoff.d.ts +914 -0
- package/dist/runtime-handoff.js +383 -0
- package/dist/scanner/scanSource.d.ts +9 -0
- package/dist/scanner/scanSource.js +43 -0
- package/dist/schema/validateIrSchemas.d.ts +3 -0
- package/dist/schema/validateIrSchemas.js +64 -0
- package/dist/validate-module-cli.d.ts +2 -0
- package/dist/validate-module-cli.js +93 -0
- package/dist/validate-registry-cli.d.ts +2 -0
- package/dist/validate-registry-cli.js +82 -0
- package/dist/validate.d.ts +52 -0
- package/dist/validate.js +91 -0
- package/fixtures/duplicate-doc.aionis.md +19 -0
- package/fixtures/fenced-example.aionis.md +27 -0
- package/fixtures/malformed-payload.aionis.md +9 -0
- package/fixtures/npm-installed-module-registry.json +17 -0
- package/fixtures/standalone-module-registry.json +13 -0
- package/fixtures/standalone-runner-plan.json +51 -0
- package/fixtures/standalone-runner.aionis.md +29 -0
- package/fixtures/unresolved-ref.aionis.md +14 -0
- package/fixtures/valid-minimal.aionis.md +24 -0
- package/fixtures/valid-workflow.aionis.md +29 -0
- package/official-modules/copy-summary/CHANGELOG.md +6 -0
- package/official-modules/copy-summary/README.md +43 -0
- package/official-modules/copy-summary/index.mjs +41 -0
- package/official-modules/copy-summary/package.json +31 -0
- package/official-modules/json-transform/CHANGELOG.md +6 -0
- package/official-modules/json-transform/README.md +51 -0
- package/official-modules/json-transform/index.mjs +53 -0
- package/official-modules/json-transform/package.json +31 -0
- package/official-modules/research-claims/CHANGELOG.md +6 -0
- package/official-modules/research-claims/README.md +47 -0
- package/official-modules/research-claims/index.mjs +44 -0
- package/official-modules/research-claims/package.json +31 -0
- package/package.json +74 -0
package/dist/resume.js
ADDED
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { RecoverInputKindSchema, RecoverResultSchema, recoverAionisManifestSource, recoverHandoffStoreRequest, recoverPublishedAionisManifest, recoverRuntimeHandoff, } from "./recover.js";
|
|
4
|
+
export const AIONIS_MANIFEST_RESUME_RESULT_VERSION = "aionis_manifest_resume_result_v2";
|
|
5
|
+
export const AIONIS_MANIFEST_RESUME_PRODUCT_PATHS = {
|
|
6
|
+
guide: "/v1/guide",
|
|
7
|
+
feedback: "/v1/feedback",
|
|
8
|
+
};
|
|
9
|
+
export const ResumeInputKindSchema = z.enum([
|
|
10
|
+
...RecoverInputKindSchema.options,
|
|
11
|
+
"recover-result",
|
|
12
|
+
]);
|
|
13
|
+
const LowercaseSha256Schema = z.string().regex(/^[a-f0-9]{64}$/);
|
|
14
|
+
export const ProductToolSelectionReceiptSchema = z.object({
|
|
15
|
+
contract_version: z.literal("aionis_tool_selection_receipt_v1"),
|
|
16
|
+
decision_id: z.string().min(1),
|
|
17
|
+
decision_uri: z.string().min(1),
|
|
18
|
+
run_id: z.string().min(1),
|
|
19
|
+
selected_tool: z.string().min(1).nullable(),
|
|
20
|
+
candidates: z.array(z.string().min(1)).min(1),
|
|
21
|
+
policy_sha256: LowercaseSha256Schema,
|
|
22
|
+
context_sha256: LowercaseSha256Schema.optional(),
|
|
23
|
+
rule_evaluation_sha256: LowercaseSha256Schema.optional(),
|
|
24
|
+
source_rule_ids: z.array(z.string().min(1)),
|
|
25
|
+
created_at: z.string().min(1),
|
|
26
|
+
}).strict();
|
|
27
|
+
export const ProductGuideResumeRequestSchema = z.object({
|
|
28
|
+
tenant_id: z.string().min(1).optional(),
|
|
29
|
+
scope: z.string().min(1).optional(),
|
|
30
|
+
query_text: z.string().min(1),
|
|
31
|
+
mode: z.literal("full_power").default("full_power"),
|
|
32
|
+
run_id: z.string().min(1),
|
|
33
|
+
context: z.record(z.unknown()),
|
|
34
|
+
execution_state_v1: z.record(z.unknown()).optional(),
|
|
35
|
+
execution_packet_v1: z.record(z.unknown()).optional(),
|
|
36
|
+
tool_candidates: z.array(z.string().min(1)).min(1),
|
|
37
|
+
tool_strict: z.boolean().default(true),
|
|
38
|
+
include_shadow: z.boolean().default(false),
|
|
39
|
+
rules_limit: z.number().int().positive().max(200).default(50),
|
|
40
|
+
include_packets: z.literal(true).default(true),
|
|
41
|
+
}).strict();
|
|
42
|
+
export const ProductGuideResumePayloadSchema = z.object({
|
|
43
|
+
contract_version: z.literal("aionis_guide_result_v1"),
|
|
44
|
+
tenant_id: z.string().min(1),
|
|
45
|
+
scope: z.string().min(1),
|
|
46
|
+
consumer_agent_id: z.string().min(1).optional(),
|
|
47
|
+
guide_trace_id: z.string().min(1),
|
|
48
|
+
agent_context: z.record(z.unknown()),
|
|
49
|
+
tool_selection: ProductToolSelectionReceiptSchema.optional(),
|
|
50
|
+
memory_packet: z.record(z.unknown()).nullable().optional(),
|
|
51
|
+
guide_packet: z.record(z.unknown()).nullable().optional(),
|
|
52
|
+
source_map: z.record(z.unknown()),
|
|
53
|
+
}).passthrough();
|
|
54
|
+
export const ProductToolFeedbackResumeRequestSchema = z.object({
|
|
55
|
+
feedback_kind: z.literal("tool_selection"),
|
|
56
|
+
tenant_id: z.string().min(1),
|
|
57
|
+
scope: z.string().min(1),
|
|
58
|
+
actor: z.string().min(1).optional(),
|
|
59
|
+
guide_trace_id: z.string().min(1),
|
|
60
|
+
decision_id: z.string().min(1),
|
|
61
|
+
run_id: z.string().min(1),
|
|
62
|
+
selected_tool: z.string().min(1),
|
|
63
|
+
candidates: z.array(z.string().min(1)).min(1),
|
|
64
|
+
outcome: z.enum(["positive", "negative", "neutral"]),
|
|
65
|
+
context: z.record(z.unknown()),
|
|
66
|
+
include_shadow: z.boolean().default(false),
|
|
67
|
+
rules_limit: z.number().int().positive().max(200).default(50),
|
|
68
|
+
target: z.enum(["tool", "all"]).default("tool"),
|
|
69
|
+
note: z.string().min(1).optional(),
|
|
70
|
+
input_text: z.string().min(1),
|
|
71
|
+
}).strict();
|
|
72
|
+
export const ProductToolFeedbackResumePayloadSchema = z.object({
|
|
73
|
+
contract_version: z.literal("aionis_feedback_result_v1"),
|
|
74
|
+
tenant_id: z.string().min(1),
|
|
75
|
+
scope: z.string().min(1),
|
|
76
|
+
product_action: z.literal("feedback"),
|
|
77
|
+
feedback_kind: z.literal("tool_selection"),
|
|
78
|
+
tool_selection: ProductToolSelectionReceiptSchema,
|
|
79
|
+
feedback_result: z.object({
|
|
80
|
+
updated_rules: z.number().int().nonnegative(),
|
|
81
|
+
decision_id: z.string().min(1),
|
|
82
|
+
}).passthrough(),
|
|
83
|
+
run_lifecycle: z.object({
|
|
84
|
+
run_id: z.string().min(1),
|
|
85
|
+
lifecycle: z.object({
|
|
86
|
+
status: z.string().min(1),
|
|
87
|
+
}).passthrough(),
|
|
88
|
+
}).passthrough(),
|
|
89
|
+
source_map: z.record(z.unknown()),
|
|
90
|
+
}).passthrough();
|
|
91
|
+
export const ResumeSummarySchema = z.object({
|
|
92
|
+
selected_tool: z.string().nullable(),
|
|
93
|
+
decision_id: z.string().nullable(),
|
|
94
|
+
run_id: z.string().min(1),
|
|
95
|
+
resume_state: z.enum(["inspection_only", "feedback_applied", "lifecycle_advanced"]),
|
|
96
|
+
feedback_written: z.boolean(),
|
|
97
|
+
feedback_outcome: z.enum(["positive", "negative", "neutral"]).nullable(),
|
|
98
|
+
pre_feedback_run_status: z.string().nullable(),
|
|
99
|
+
post_feedback_run_status: z.string().nullable(),
|
|
100
|
+
lifecycle_transition: z.string().nullable(),
|
|
101
|
+
lifecycle_advanced: z.boolean(),
|
|
102
|
+
feedback_updated_rules: z.number().int().nonnegative().nullable(),
|
|
103
|
+
});
|
|
104
|
+
export const ResumeResultSchema = z.object({
|
|
105
|
+
resume_result_version: z.literal(AIONIS_MANIFEST_RESUME_RESULT_VERSION),
|
|
106
|
+
resumed_at: z.string().min(1),
|
|
107
|
+
base_url: z.string().min(1),
|
|
108
|
+
input_kind: ResumeInputKindSchema,
|
|
109
|
+
source_doc_id: z.string().min(1).nullable(),
|
|
110
|
+
source_doc_version: z.string().min(1).nullable(),
|
|
111
|
+
run_id: z.string().min(1),
|
|
112
|
+
resume_summary: ResumeSummarySchema,
|
|
113
|
+
recover_result: RecoverResultSchema.nullable(),
|
|
114
|
+
guide_request: ProductGuideResumeRequestSchema,
|
|
115
|
+
guide_response: z.object({
|
|
116
|
+
status: z.number().int().nonnegative(),
|
|
117
|
+
request_id: z.string().nullable(),
|
|
118
|
+
data: ProductGuideResumePayloadSchema,
|
|
119
|
+
}),
|
|
120
|
+
tool_feedback_request: ProductToolFeedbackResumeRequestSchema.nullable(),
|
|
121
|
+
tool_feedback_response: z.object({
|
|
122
|
+
status: z.number().int().nonnegative(),
|
|
123
|
+
request_id: z.string().nullable(),
|
|
124
|
+
data: ProductToolFeedbackResumePayloadSchema,
|
|
125
|
+
}).nullable(),
|
|
126
|
+
});
|
|
127
|
+
function joinUrl(baseUrl, path) {
|
|
128
|
+
return `${baseUrl.replace(/\/+$/, "")}/${path.replace(/^\/+/, "")}`;
|
|
129
|
+
}
|
|
130
|
+
function withTimeout(timeoutMs) {
|
|
131
|
+
const controller = new AbortController();
|
|
132
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
133
|
+
return {
|
|
134
|
+
signal: controller.signal,
|
|
135
|
+
cancel: () => clearTimeout(timer),
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
async function parseResponseBody(res) {
|
|
139
|
+
const contentType = (res.headers.get("content-type") ?? "").toLowerCase();
|
|
140
|
+
if (contentType.includes("application/json"))
|
|
141
|
+
return res.json();
|
|
142
|
+
const text = await res.text();
|
|
143
|
+
return text.length > 0 ? text : null;
|
|
144
|
+
}
|
|
145
|
+
function buildHeaders(args) {
|
|
146
|
+
const headers = { "content-type": "application/json" };
|
|
147
|
+
if (args.apiKey)
|
|
148
|
+
headers["x-api-key"] = args.apiKey;
|
|
149
|
+
if (args.adminToken)
|
|
150
|
+
headers["x-admin-token"] = args.adminToken;
|
|
151
|
+
if (args.authBearer) {
|
|
152
|
+
headers.authorization = args.authBearer.toLowerCase().startsWith("bearer ")
|
|
153
|
+
? args.authBearer
|
|
154
|
+
: `Bearer ${args.authBearer}`;
|
|
155
|
+
}
|
|
156
|
+
if (args.requestId)
|
|
157
|
+
headers["x-request-id"] = args.requestId;
|
|
158
|
+
return headers;
|
|
159
|
+
}
|
|
160
|
+
function extractRequestId(headers) {
|
|
161
|
+
return headers.get("x-request-id") ?? headers.get("request-id") ?? null;
|
|
162
|
+
}
|
|
163
|
+
function firstString(...values) {
|
|
164
|
+
for (const value of values) {
|
|
165
|
+
if (typeof value === "string" && value.trim().length > 0)
|
|
166
|
+
return value;
|
|
167
|
+
}
|
|
168
|
+
return undefined;
|
|
169
|
+
}
|
|
170
|
+
function maybeRecord(value) {
|
|
171
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
172
|
+
}
|
|
173
|
+
function maybeRecords(value) {
|
|
174
|
+
if (!Array.isArray(value))
|
|
175
|
+
return undefined;
|
|
176
|
+
return value.filter((entry) => !!entry && typeof entry === "object" && !Array.isArray(entry));
|
|
177
|
+
}
|
|
178
|
+
function readString(record, key) {
|
|
179
|
+
const value = record?.[key];
|
|
180
|
+
return typeof value === "string" && value.trim().length > 0 ? value : null;
|
|
181
|
+
}
|
|
182
|
+
function readNonNegativeInt(record, key) {
|
|
183
|
+
const value = record?.[key];
|
|
184
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : null;
|
|
185
|
+
}
|
|
186
|
+
function buildResumeContext(recoverResult) {
|
|
187
|
+
const recovered = recoverResult.recover_response.data;
|
|
188
|
+
return {
|
|
189
|
+
intent: "doc_resume",
|
|
190
|
+
workflow_kind: "aionis_manifest",
|
|
191
|
+
handoff_anchor: recovered.anchor,
|
|
192
|
+
...(recovered.control_profile_v1 ? { control_profile_v1: recovered.control_profile_v1 } : {}),
|
|
193
|
+
...(recovered.execution_result_summary
|
|
194
|
+
? { execution_result_summary: recovered.execution_result_summary }
|
|
195
|
+
: {}),
|
|
196
|
+
...(maybeRecords(recovered.execution_artifacts)
|
|
197
|
+
? { execution_artifacts: maybeRecords(recovered.execution_artifacts) }
|
|
198
|
+
: {}),
|
|
199
|
+
...(maybeRecords(recovered.execution_evidence)
|
|
200
|
+
? { execution_evidence: maybeRecords(recovered.execution_evidence) }
|
|
201
|
+
: {}),
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
export function buildProductGuideResumeRequest(args) {
|
|
205
|
+
const recovered = args.recoverResult.recover_response.data;
|
|
206
|
+
const executionReady = maybeRecord(recovered.execution_ready_handoff);
|
|
207
|
+
const handoff = maybeRecord(recovered.handoff);
|
|
208
|
+
const executionState = maybeRecord(recovered.execution_state_v1);
|
|
209
|
+
return ProductGuideResumeRequestSchema.parse({
|
|
210
|
+
tenant_id: args.tenantId ?? recovered.tenant_id,
|
|
211
|
+
scope: args.scope ?? recovered.scope,
|
|
212
|
+
query_text: args.queryText ?? firstString(executionReady?.next_action, executionState?.task_brief, handoff?.summary, recovered.anchor) ?? "resume recovered handoff",
|
|
213
|
+
mode: "full_power",
|
|
214
|
+
run_id: args.runId ?? randomUUID(),
|
|
215
|
+
context: buildResumeContext(args.recoverResult),
|
|
216
|
+
execution_state_v1: executionState ?? undefined,
|
|
217
|
+
execution_packet_v1: maybeRecord(recovered.execution_packet_v1) ?? undefined,
|
|
218
|
+
tool_candidates: args.candidates,
|
|
219
|
+
tool_strict: args.strict ?? true,
|
|
220
|
+
include_shadow: args.includeShadow ?? false,
|
|
221
|
+
rules_limit: args.rulesLimit ?? 50,
|
|
222
|
+
include_packets: true,
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
export function buildProductToolFeedbackResumeRequest(args) {
|
|
226
|
+
const receipt = args.guideResponse.tool_selection;
|
|
227
|
+
if (!receipt)
|
|
228
|
+
throw new Error("Guide did not expose a tool-selection receipt for feedback.");
|
|
229
|
+
const selectedTool = args.selectedTool ?? receipt.selected_tool;
|
|
230
|
+
if (!selectedTool)
|
|
231
|
+
throw new Error("Guide tool-selection receipt did not select a tool.");
|
|
232
|
+
return ProductToolFeedbackResumeRequestSchema.parse({
|
|
233
|
+
feedback_kind: "tool_selection",
|
|
234
|
+
tenant_id: args.guideResponse.tenant_id,
|
|
235
|
+
scope: args.guideResponse.scope,
|
|
236
|
+
actor: args.actor,
|
|
237
|
+
guide_trace_id: args.guideResponse.guide_trace_id,
|
|
238
|
+
decision_id: receipt.decision_id,
|
|
239
|
+
run_id: receipt.run_id,
|
|
240
|
+
selected_tool: selectedTool,
|
|
241
|
+
candidates: receipt.candidates,
|
|
242
|
+
outcome: args.outcome,
|
|
243
|
+
context: args.guideRequest.context,
|
|
244
|
+
include_shadow: args.guideRequest.include_shadow,
|
|
245
|
+
rules_limit: args.guideRequest.rules_limit,
|
|
246
|
+
target: args.target ?? "tool",
|
|
247
|
+
note: args.note,
|
|
248
|
+
input_text: args.inputText ?? args.note ?? args.guideRequest.query_text,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
async function postJson(args) {
|
|
252
|
+
const timeout = withTimeout(args.timeoutMs ?? 10_000);
|
|
253
|
+
try {
|
|
254
|
+
const res = await fetch(joinUrl(args.baseUrl, args.path), {
|
|
255
|
+
method: "POST",
|
|
256
|
+
headers: buildHeaders(args),
|
|
257
|
+
body: JSON.stringify(args.body),
|
|
258
|
+
signal: timeout.signal,
|
|
259
|
+
});
|
|
260
|
+
const body = await parseResponseBody(res);
|
|
261
|
+
if (!res.ok) {
|
|
262
|
+
const message = body && typeof body === "object" && "message" in body && typeof body.message === "string"
|
|
263
|
+
? String(body.message)
|
|
264
|
+
: `${args.path} failed with status ${res.status}`;
|
|
265
|
+
throw new Error(message);
|
|
266
|
+
}
|
|
267
|
+
return { status: res.status, request_id: extractRequestId(res.headers), body };
|
|
268
|
+
}
|
|
269
|
+
finally {
|
|
270
|
+
timeout.cancel();
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
export async function resumeRecoveredAionisManifest(args) {
|
|
274
|
+
const recoverResult = RecoverResultSchema.parse(args.recoverResult);
|
|
275
|
+
const guideRequest = buildProductGuideResumeRequest({
|
|
276
|
+
recoverResult,
|
|
277
|
+
queryText: args.queryText,
|
|
278
|
+
runId: args.runId,
|
|
279
|
+
tenantId: args.tenantId,
|
|
280
|
+
scope: args.scope,
|
|
281
|
+
candidates: args.candidates,
|
|
282
|
+
strict: args.strict,
|
|
283
|
+
includeShadow: args.includeShadow,
|
|
284
|
+
rulesLimit: args.rulesLimit,
|
|
285
|
+
});
|
|
286
|
+
const guideWrite = await postJson({
|
|
287
|
+
baseUrl: args.baseUrl,
|
|
288
|
+
path: AIONIS_MANIFEST_RESUME_PRODUCT_PATHS.guide,
|
|
289
|
+
body: guideRequest,
|
|
290
|
+
timeoutMs: args.timeoutMs,
|
|
291
|
+
apiKey: args.apiKey,
|
|
292
|
+
authBearer: args.authBearer,
|
|
293
|
+
adminToken: args.adminToken,
|
|
294
|
+
requestId: args.requestId,
|
|
295
|
+
});
|
|
296
|
+
const guideResponse = ProductGuideResumePayloadSchema.parse(guideWrite.body);
|
|
297
|
+
let toolFeedbackRequest = null;
|
|
298
|
+
let toolFeedbackResponse = null;
|
|
299
|
+
if (args.feedbackOutcome) {
|
|
300
|
+
toolFeedbackRequest = buildProductToolFeedbackResumeRequest({
|
|
301
|
+
guideRequest,
|
|
302
|
+
guideResponse,
|
|
303
|
+
outcome: args.feedbackOutcome,
|
|
304
|
+
actor: args.feedbackActor,
|
|
305
|
+
note: args.feedbackNote,
|
|
306
|
+
inputText: args.feedbackInputText,
|
|
307
|
+
target: args.feedbackTarget,
|
|
308
|
+
selectedTool: args.feedbackSelectedTool,
|
|
309
|
+
});
|
|
310
|
+
const feedbackWrite = await postJson({
|
|
311
|
+
baseUrl: args.baseUrl,
|
|
312
|
+
path: AIONIS_MANIFEST_RESUME_PRODUCT_PATHS.feedback,
|
|
313
|
+
body: toolFeedbackRequest,
|
|
314
|
+
timeoutMs: args.timeoutMs,
|
|
315
|
+
apiKey: args.apiKey,
|
|
316
|
+
authBearer: args.authBearer,
|
|
317
|
+
adminToken: args.adminToken,
|
|
318
|
+
requestId: args.requestId,
|
|
319
|
+
});
|
|
320
|
+
toolFeedbackResponse = {
|
|
321
|
+
status: feedbackWrite.status,
|
|
322
|
+
request_id: feedbackWrite.request_id,
|
|
323
|
+
data: ProductToolFeedbackResumePayloadSchema.parse(feedbackWrite.body),
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
const receipt = guideResponse.tool_selection ?? null;
|
|
327
|
+
const preStatus = receipt ? "decision_recorded" : null;
|
|
328
|
+
const runLifecycle = maybeRecord(toolFeedbackResponse?.data.run_lifecycle);
|
|
329
|
+
const postStatus = readString(maybeRecord(runLifecycle?.lifecycle), "status");
|
|
330
|
+
const lifecycleTransition = preStatus && postStatus && preStatus !== postStatus
|
|
331
|
+
? `${preStatus} -> ${postStatus}`
|
|
332
|
+
: null;
|
|
333
|
+
const feedbackWritten = toolFeedbackResponse !== null;
|
|
334
|
+
const lifecycleAdvanced = lifecycleTransition !== null;
|
|
335
|
+
const feedbackResult = maybeRecord(toolFeedbackResponse?.data.feedback_result);
|
|
336
|
+
const resumeSummary = ResumeSummarySchema.parse({
|
|
337
|
+
selected_tool: receipt?.selected_tool ?? null,
|
|
338
|
+
decision_id: receipt?.decision_id ?? null,
|
|
339
|
+
run_id: receipt?.run_id ?? guideRequest.run_id,
|
|
340
|
+
resume_state: !feedbackWritten ? "inspection_only" : lifecycleAdvanced ? "lifecycle_advanced" : "feedback_applied",
|
|
341
|
+
feedback_written: feedbackWritten,
|
|
342
|
+
feedback_outcome: args.feedbackOutcome ?? null,
|
|
343
|
+
pre_feedback_run_status: preStatus,
|
|
344
|
+
post_feedback_run_status: postStatus,
|
|
345
|
+
lifecycle_transition: lifecycleTransition,
|
|
346
|
+
lifecycle_advanced: lifecycleAdvanced,
|
|
347
|
+
feedback_updated_rules: readNonNegativeInt(feedbackResult, "updated_rules"),
|
|
348
|
+
});
|
|
349
|
+
return ResumeResultSchema.parse({
|
|
350
|
+
resume_result_version: AIONIS_MANIFEST_RESUME_RESULT_VERSION,
|
|
351
|
+
resumed_at: args.resumedAt ?? new Date().toISOString(),
|
|
352
|
+
base_url: args.baseUrl,
|
|
353
|
+
input_kind: args.inputKind ?? "recover-result",
|
|
354
|
+
source_doc_id: recoverResult.source_doc_id,
|
|
355
|
+
source_doc_version: recoverResult.source_doc_version,
|
|
356
|
+
run_id: resumeSummary.run_id,
|
|
357
|
+
resume_summary: resumeSummary,
|
|
358
|
+
recover_result: recoverResult,
|
|
359
|
+
guide_request: guideRequest,
|
|
360
|
+
guide_response: {
|
|
361
|
+
status: guideWrite.status,
|
|
362
|
+
request_id: guideWrite.request_id,
|
|
363
|
+
data: guideResponse,
|
|
364
|
+
},
|
|
365
|
+
tool_feedback_request: toolFeedbackRequest,
|
|
366
|
+
tool_feedback_response: toolFeedbackResponse,
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
export async function resumePublishedAionisManifest(args) {
|
|
370
|
+
const recoverResult = await recoverPublishedAionisManifest({
|
|
371
|
+
publishResult: args.publishResult,
|
|
372
|
+
inputKind: "publish-result",
|
|
373
|
+
baseUrl: args.baseUrl,
|
|
374
|
+
timeoutMs: args.timeoutMs,
|
|
375
|
+
apiKey: args.apiKey,
|
|
376
|
+
authBearer: args.authBearer,
|
|
377
|
+
adminToken: args.adminToken,
|
|
378
|
+
requestId: args.requestId,
|
|
379
|
+
scope: args.scope,
|
|
380
|
+
tenantId: args.tenantId,
|
|
381
|
+
});
|
|
382
|
+
return resumeRecoveredAionisManifest({ ...args, recoverResult, inputKind: "publish-result" });
|
|
383
|
+
}
|
|
384
|
+
export async function resumeRuntimeHandoff(args) {
|
|
385
|
+
const recoverResult = await recoverRuntimeHandoff({
|
|
386
|
+
runtimeHandoff: args.runtimeHandoff,
|
|
387
|
+
baseUrl: args.baseUrl,
|
|
388
|
+
timeoutMs: args.timeoutMs,
|
|
389
|
+
apiKey: args.apiKey,
|
|
390
|
+
authBearer: args.authBearer,
|
|
391
|
+
adminToken: args.adminToken,
|
|
392
|
+
requestId: args.requestId,
|
|
393
|
+
scope: args.scope,
|
|
394
|
+
tenantId: args.tenantId,
|
|
395
|
+
actor: args.actor,
|
|
396
|
+
memoryLane: args.memoryLane,
|
|
397
|
+
title: args.title,
|
|
398
|
+
tags: args.tags,
|
|
399
|
+
repoRoot: args.repoRoot,
|
|
400
|
+
filePath: args.filePath,
|
|
401
|
+
symbol: args.symbol,
|
|
402
|
+
handoffKind: args.handoffKind,
|
|
403
|
+
limit: args.limit,
|
|
404
|
+
});
|
|
405
|
+
return resumeRecoveredAionisManifest({ ...args, recoverResult, inputKind: "runtime-handoff" });
|
|
406
|
+
}
|
|
407
|
+
export async function resumeHandoffStoreRequest(args) {
|
|
408
|
+
const recoverResult = await recoverHandoffStoreRequest({
|
|
409
|
+
handoffStoreRequest: args.handoffStoreRequest,
|
|
410
|
+
baseUrl: args.baseUrl,
|
|
411
|
+
timeoutMs: args.timeoutMs,
|
|
412
|
+
apiKey: args.apiKey,
|
|
413
|
+
authBearer: args.authBearer,
|
|
414
|
+
adminToken: args.adminToken,
|
|
415
|
+
requestId: args.requestId,
|
|
416
|
+
scope: args.scope,
|
|
417
|
+
tenantId: args.tenantId,
|
|
418
|
+
repoRoot: args.repoRoot,
|
|
419
|
+
filePath: args.filePath,
|
|
420
|
+
symbol: args.symbol,
|
|
421
|
+
handoffKind: args.handoffKind,
|
|
422
|
+
limit: args.limit,
|
|
423
|
+
});
|
|
424
|
+
return resumeRecoveredAionisManifest({ ...args, recoverResult, inputKind: "handoff-store-request" });
|
|
425
|
+
}
|
|
426
|
+
export async function resumeAionisManifestSource(args) {
|
|
427
|
+
const recoverResult = await recoverAionisManifestSource({
|
|
428
|
+
source: args.source,
|
|
429
|
+
inputPath: args.inputPath,
|
|
430
|
+
baseUrl: args.baseUrl,
|
|
431
|
+
timeoutMs: args.timeoutMs,
|
|
432
|
+
apiKey: args.apiKey,
|
|
433
|
+
authBearer: args.authBearer,
|
|
434
|
+
adminToken: args.adminToken,
|
|
435
|
+
requestId: args.requestId,
|
|
436
|
+
scope: args.scope,
|
|
437
|
+
tenantId: args.tenantId,
|
|
438
|
+
actor: args.actor,
|
|
439
|
+
memoryLane: args.memoryLane,
|
|
440
|
+
title: args.title,
|
|
441
|
+
tags: args.tags,
|
|
442
|
+
repoRoot: args.repoRoot,
|
|
443
|
+
filePath: args.filePath,
|
|
444
|
+
symbol: args.symbol,
|
|
445
|
+
currentStage: args.currentStage,
|
|
446
|
+
activeRole: args.activeRole,
|
|
447
|
+
handoffKind: args.handoffKind,
|
|
448
|
+
limit: args.limit,
|
|
449
|
+
allowCompileErrors: args.allowCompileErrors,
|
|
450
|
+
});
|
|
451
|
+
return resumeRecoveredAionisManifest({ ...args, recoverResult, inputKind: "source" });
|
|
452
|
+
}
|
package/dist/run-cli.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
|
+
import process from "node:process";
|
|
5
|
+
import { AionisManifestExecutionResultSchema, AionisManifestRunInputKindSchema } from "./contracts.js";
|
|
6
|
+
import { AionisManifestRunError, runAionisManifest } from "./run.js";
|
|
7
|
+
class CliUsageError extends Error {
|
|
8
|
+
}
|
|
9
|
+
function printHelp() {
|
|
10
|
+
process.stdout.write([
|
|
11
|
+
"run-aionis-manifest",
|
|
12
|
+
"",
|
|
13
|
+
"Usage:",
|
|
14
|
+
" run-aionis-manifest <input-file> [--input-kind source|compile-envelope|plan] --registry <path> [--out <path>] [--compact]",
|
|
15
|
+
"",
|
|
16
|
+
"Options:",
|
|
17
|
+
" --input-kind <kind> Select source, compile-envelope, or plan input. Default: source",
|
|
18
|
+
" --registry <path> Path to a module registry JSON file",
|
|
19
|
+
" --out <path> Write output JSON to a file instead of stdout",
|
|
20
|
+
" --compact Print compact JSON instead of pretty JSON",
|
|
21
|
+
" --help Show this message",
|
|
22
|
+
"",
|
|
23
|
+
].join("\n"));
|
|
24
|
+
}
|
|
25
|
+
function parseArgs(argv) {
|
|
26
|
+
let inputPath = null;
|
|
27
|
+
const flags = {
|
|
28
|
+
inputKind: "source",
|
|
29
|
+
registry: null,
|
|
30
|
+
out: null,
|
|
31
|
+
compact: false,
|
|
32
|
+
help: false,
|
|
33
|
+
};
|
|
34
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
35
|
+
const token = argv[i];
|
|
36
|
+
if (token === "--help" || token === "-h") {
|
|
37
|
+
flags.help = true;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (token === "--compact") {
|
|
41
|
+
flags.compact = true;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (token === "--input-kind") {
|
|
45
|
+
const next = argv[i + 1];
|
|
46
|
+
if (!next)
|
|
47
|
+
throw new CliUsageError("Missing value for --input-kind.");
|
|
48
|
+
flags.inputKind = AionisManifestRunInputKindSchema.parse(next);
|
|
49
|
+
i += 1;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (token === "--registry") {
|
|
53
|
+
const next = argv[i + 1];
|
|
54
|
+
if (!next)
|
|
55
|
+
throw new CliUsageError("Missing value for --registry.");
|
|
56
|
+
flags.registry = next;
|
|
57
|
+
i += 1;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (token === "--out") {
|
|
61
|
+
const next = argv[i + 1];
|
|
62
|
+
if (!next)
|
|
63
|
+
throw new CliUsageError("Missing value for --out.");
|
|
64
|
+
flags.out = next;
|
|
65
|
+
i += 1;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (token.startsWith("--")) {
|
|
69
|
+
throw new CliUsageError(`Unknown flag '${token}'.`);
|
|
70
|
+
}
|
|
71
|
+
if (inputPath)
|
|
72
|
+
throw new CliUsageError("Only one input file may be provided.");
|
|
73
|
+
inputPath = token;
|
|
74
|
+
}
|
|
75
|
+
return { inputPath, flags };
|
|
76
|
+
}
|
|
77
|
+
async function writeOutput(pathname, contents) {
|
|
78
|
+
await mkdir(dirname(pathname), { recursive: true });
|
|
79
|
+
await writeFile(pathname, contents, "utf8");
|
|
80
|
+
}
|
|
81
|
+
async function main() {
|
|
82
|
+
const { inputPath, flags } = parseArgs(process.argv.slice(2));
|
|
83
|
+
if (flags.help) {
|
|
84
|
+
printHelp();
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (!inputPath)
|
|
88
|
+
throw new CliUsageError("An input file path is required.");
|
|
89
|
+
if (!flags.registry)
|
|
90
|
+
throw new CliUsageError("A --registry path is required.");
|
|
91
|
+
const result = await runAionisManifest({
|
|
92
|
+
inputPath,
|
|
93
|
+
inputKind: flags.inputKind,
|
|
94
|
+
registryPath: flags.registry,
|
|
95
|
+
});
|
|
96
|
+
const parsed = AionisManifestExecutionResultSchema.parse(result);
|
|
97
|
+
const rendered = flags.compact ? JSON.stringify(parsed) : `${JSON.stringify(parsed, null, 2)}\n`;
|
|
98
|
+
if (flags.out) {
|
|
99
|
+
await writeOutput(resolve(process.cwd(), flags.out), rendered);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
process.stdout.write(rendered);
|
|
103
|
+
}
|
|
104
|
+
if (parsed.status === "failed") {
|
|
105
|
+
process.exitCode = 1;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
main().catch((error) => {
|
|
109
|
+
if (error instanceof CliUsageError || error instanceof AionisManifestRunError) {
|
|
110
|
+
process.stderr.write(`${error.message}\n`);
|
|
111
|
+
if (error instanceof CliUsageError)
|
|
112
|
+
printHelp();
|
|
113
|
+
process.exitCode = error instanceof CliUsageError ? 2 : 1;
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
117
|
+
process.stderr.write(`${message}\n`);
|
|
118
|
+
process.exitCode = 1;
|
|
119
|
+
});
|
package/dist/run.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AionisManifestRunInputKind, ExecutionResultV1 } from "./execute/types.js";
|
|
2
|
+
export declare class AionisManifestRunError extends Error {
|
|
3
|
+
}
|
|
4
|
+
export declare function runAionisManifest(args: {
|
|
5
|
+
inputPath: string;
|
|
6
|
+
inputKind?: AionisManifestRunInputKind;
|
|
7
|
+
registryPath: string;
|
|
8
|
+
cwd?: string;
|
|
9
|
+
}): Promise<ExecutionResultV1>;
|
package/dist/run.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { compileAionisManifest } from "./compile.js";
|
|
4
|
+
import { validateCompileEnvelope, ExecutionPlanSchema } from "./contracts.js";
|
|
5
|
+
import { executeExecutionPlan } from "./execute.js";
|
|
6
|
+
import { createModuleRegistryRuntimeFromFile } from "./registry/loadModuleRegistry.js";
|
|
7
|
+
export class AionisManifestRunError extends Error {
|
|
8
|
+
}
|
|
9
|
+
function resolvePath(cwd, targetPath) {
|
|
10
|
+
return path.resolve(cwd ?? process.cwd(), targetPath);
|
|
11
|
+
}
|
|
12
|
+
async function loadJsonFile(resolvedPath) {
|
|
13
|
+
return JSON.parse(await readFile(resolvedPath, "utf8"));
|
|
14
|
+
}
|
|
15
|
+
function resolveInputKind(inputKind) {
|
|
16
|
+
return inputKind ?? "source";
|
|
17
|
+
}
|
|
18
|
+
export async function runAionisManifest(args) {
|
|
19
|
+
const inputKind = resolveInputKind(args.inputKind);
|
|
20
|
+
const resolvedInputPath = resolvePath(args.cwd, args.inputPath);
|
|
21
|
+
const resolvedRegistryPath = resolvePath(args.cwd, args.registryPath);
|
|
22
|
+
const runtime = await createModuleRegistryRuntimeFromFile({
|
|
23
|
+
registryPath: resolvedRegistryPath,
|
|
24
|
+
});
|
|
25
|
+
switch (inputKind) {
|
|
26
|
+
case "source": {
|
|
27
|
+
const source = await readFile(resolvedInputPath, "utf8");
|
|
28
|
+
const result = compileAionisManifest(source);
|
|
29
|
+
return executeExecutionPlan(result.plan, { runtime });
|
|
30
|
+
}
|
|
31
|
+
case "compile-envelope": {
|
|
32
|
+
const envelope = validateCompileEnvelope(await loadJsonFile(resolvedInputPath));
|
|
33
|
+
if (!envelope.artifacts.plan) {
|
|
34
|
+
throw new AionisManifestRunError(`Compile envelope '${resolvedInputPath}' does not contain a plan artifact. Re-run compile-aionis-manifest with --emit all or --emit plan.`);
|
|
35
|
+
}
|
|
36
|
+
return executeExecutionPlan(envelope.artifacts.plan, { runtime });
|
|
37
|
+
}
|
|
38
|
+
case "plan": {
|
|
39
|
+
const plan = ExecutionPlanSchema.parse(await loadJsonFile(resolvedInputPath));
|
|
40
|
+
return executeExecutionPlan(plan, { runtime });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|