intentdna 1.9.0 → 1.9.3
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +227 -87
- package/dist/cli/commands/run-lifecycle.d.ts +61 -11
- package/dist/cli/commands/run-lifecycle.js +184 -50
- package/dist/cli/commands/run-observer.d.ts +15 -0
- package/dist/cli/commands/run-observer.js +210 -0
- package/dist/cli/commands/run.d.ts +16 -20
- package/dist/cli/commands/run.js +461 -659
- package/dist/cli/commands/sync.js +16 -12
- package/dist/cli/index.js +14 -5
- package/dist/compiler/compile.d.ts +1 -0
- package/dist/compiler/compile.js +1 -1
- package/dist/compiler/controller.d.ts +16 -0
- package/dist/compiler/controller.js +693 -0
- package/dist/compiler/input-resolver.d.ts +2 -0
- package/dist/compiler/input-resolver.js +22 -6
- package/dist/hooks/cli.d.ts +45 -0
- package/dist/hooks/cli.js +263 -31
- package/dist/hooks/host-event.d.ts +57 -0
- package/dist/hooks/host-event.js +187 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/protocol.d.ts +7 -0
- package/dist/hooks/schema.d.ts +1 -0
- package/dist/hooks/schema.js +89 -1
- package/dist/hooks/state.d.ts +23 -1
- package/dist/hooks/state.js +9 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/mcp/index.js +2 -0
- package/dist/mcp/tools-run.d.ts +4 -0
- package/dist/mcp/tools-run.js +419 -0
- package/dist/mcp/tools-state.d.ts +1 -1
- package/dist/mcp/tools-state.js +13 -241
- package/dist/runtime/artifact-store.d.ts +146 -0
- package/dist/runtime/artifact-store.js +1436 -0
- package/dist/runtime/canonical-attempt-outcome.d.ts +12 -0
- package/dist/runtime/canonical-attempt-outcome.js +195 -0
- package/dist/runtime/canonical-json.d.ts +10 -0
- package/dist/runtime/canonical-json.js +105 -0
- package/dist/runtime/canonical-run-application.d.ts +93 -0
- package/dist/runtime/canonical-run-application.js +229 -0
- package/dist/runtime/canonical-run-service.d.ts +454 -0
- package/dist/runtime/canonical-run-service.js +4760 -0
- package/dist/runtime/canonical-runtime-composition.d.ts +22 -0
- package/dist/runtime/canonical-runtime-composition.js +34 -0
- package/dist/runtime/canonical-runtime-projection.d.ts +3 -0
- package/dist/runtime/canonical-runtime-projection.js +4 -0
- package/dist/runtime/canonical-target-compiler.d.ts +46 -0
- package/dist/runtime/canonical-target-compiler.js +514 -0
- package/dist/runtime/claude-agent-identity.d.ts +2 -0
- package/dist/runtime/claude-agent-identity.js +21 -0
- package/dist/runtime/executable-run-plan.d.ts +328 -0
- package/dist/runtime/executable-run-plan.js +1485 -0
- package/dist/runtime/execution-authority.d.ts +83 -0
- package/dist/runtime/execution-authority.js +98 -0
- package/dist/runtime/handoff-resolver.js +4 -1
- package/dist/runtime/harness-pull-adapter.d.ts +146 -0
- package/dist/runtime/harness-pull-adapter.js +315 -0
- package/dist/runtime/index.d.ts +39 -14
- package/dist/runtime/index.js +29 -7
- package/dist/runtime/local-execution-authority.d.ts +194 -0
- package/dist/runtime/local-execution-authority.js +2897 -0
- package/dist/runtime/local-execution-reconciliation.d.ts +20 -0
- package/dist/runtime/local-execution-reconciliation.js +107 -0
- package/dist/runtime/local-execution-supervisor-script.d.ts +7 -0
- package/dist/runtime/local-execution-supervisor-script.js +793 -0
- package/dist/runtime/local-provider-sandbox.d.ts +42 -0
- package/dist/runtime/local-provider-sandbox.js +154 -0
- package/dist/runtime/local-verifier-execution.d.ts +24 -0
- package/dist/runtime/local-verifier-execution.js +290 -0
- package/dist/runtime/local-windows-execution-supervisor-script.d.ts +6 -0
- package/dist/runtime/local-windows-execution-supervisor-script.js +788 -0
- package/dist/runtime/plan-store.d.ts +30 -0
- package/dist/runtime/plan-store.js +231 -0
- package/dist/runtime/process-tree.d.ts +9 -0
- package/dist/runtime/process-tree.js +97 -24
- package/dist/runtime/providers/codex.js +2 -2
- package/dist/runtime/push-driver.d.ts +184 -0
- package/dist/runtime/push-driver.js +1002 -0
- package/dist/runtime/result-store.d.ts +34 -3
- package/dist/runtime/result-store.js +1073 -2
- package/dist/runtime/run-binding.d.ts +68 -0
- package/dist/runtime/run-binding.js +278 -0
- package/dist/runtime/run-contracts.d.ts +575 -0
- package/dist/runtime/run-contracts.js +58 -7
- package/dist/runtime/run-controller.d.ts +1 -6
- package/dist/runtime/run-controller.js +0 -41
- package/dist/runtime/run-store.d.ts +85 -7
- package/dist/runtime/run-store.js +2528 -186
- package/dist/runtime/skill-adapter.d.ts +18 -7
- package/dist/runtime/skill-adapter.js +100 -742
- package/dist/runtime/structured-output-validator.d.ts +44 -0
- package/dist/runtime/structured-output-validator.js +171 -0
- package/dist/runtime/verifier-command-binding.d.ts +22 -0
- package/dist/runtime/verifier-command-binding.js +162 -0
- package/dist/runtime/verifier.d.ts +46 -6
- package/dist/runtime/verifier.js +355 -53
- package/dist/runtime/windows-job-keeper.d.ts +47 -0
- package/dist/runtime/windows-job-keeper.js +231 -0
- package/dist/runtime/worker-executor.d.ts +17 -1
- package/dist/runtime/worker-executor.js +26 -5
- package/dist/runtime/workflow-plan-adapter.d.ts +19 -0
- package/dist/runtime/workflow-plan-adapter.js +502 -6
- package/dist/runtime/workflow-runtime-manifest.d.ts +1 -0
- package/dist/runtime/workflow-runtime-manifest.js +5 -0
- package/dist/runtime/workspace-isolation.d.ts +29 -2
- package/dist/runtime/workspace-isolation.js +488 -11
- package/dist/runtime/workspace-observation.d.ts +44 -0
- package/dist/runtime/workspace-observation.js +216 -0
- package/dist/schema/controller-registry.d.ts +0 -7
- package/dist/schema/controller-registry.js +0 -8
- package/dist/schema/types.d.ts +84 -10
- package/dist/schema/types.js +2 -0
- package/dist/schema/validate.js +151 -1
- package/dist/schema/validators/controllers.d.ts +1 -1
- package/dist/schema/validators/controllers.js +126 -41
- package/dist/schema/workflow-authoring-contract.js +2 -0
- package/dist/schema/yaml-parser.js +1 -1
- package/dist/templates/flutter-rewrite-new.dna.yaml +1 -0
- package/dist/templates/flutter-rewrite.dna.yaml +87 -60
- package/dist/templates/safe-refactoring.dna.yaml +1 -0
- package/native/windows-job-keeper/README.md +80 -0
- package/native/windows-job-keeper/bin/aarch64/intentdna-windows-job-keeper.exe +0 -0
- package/native/windows-job-keeper/bin/x86_64/intentdna-windows-job-keeper.exe +0 -0
- package/native/windows-job-keeper/keeper.c +979 -0
- package/native/windows-job-keeper/manifest.json +33 -0
- package/package.json +6 -2
- package/scripts/build-windows-job-keeper.mjs +172 -0
- package/scripts/verify-windows-job-keeper.mjs +184 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { existsSync, lstatSync, readFileSync, realpathSync, } from "node:fs";
|
|
3
|
+
import { dirname, isAbsolute, relative, resolve } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
export const WINDOWS_JOB_KEEPER_PROTOCOL_VERSION = "IDNA_WINDOWS_JOB_KEEPER_V1";
|
|
6
|
+
export const WINDOWS_JOB_KEEPER_MANIFEST_SCHEMA = "intentdna.windows_job_keeper_manifest.v1";
|
|
7
|
+
export class WindowsJobKeeperArtifactError extends Error {
|
|
8
|
+
constructor(message, options) {
|
|
9
|
+
super(message, options);
|
|
10
|
+
this.name = "WindowsJobKeeperArtifactError";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function canonicalDigest(value) {
|
|
14
|
+
return typeof value === "string" && /^sha256:[0-9a-f]{64}$/.test(value);
|
|
15
|
+
}
|
|
16
|
+
function exactKeys(value, expected) {
|
|
17
|
+
const actual = Object.keys(value).sort();
|
|
18
|
+
const sortedExpected = [...expected].sort();
|
|
19
|
+
return actual.length === sortedExpected.length
|
|
20
|
+
&& actual.every((key, index) => key === sortedExpected[index]);
|
|
21
|
+
}
|
|
22
|
+
function record(value) {
|
|
23
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24
|
+
}
|
|
25
|
+
function architecture(value) {
|
|
26
|
+
if (value === "x64")
|
|
27
|
+
return "x86_64";
|
|
28
|
+
if (value === "arm64")
|
|
29
|
+
return "aarch64";
|
|
30
|
+
throw new WindowsJobKeeperArtifactError(`Windows Job keeper does not support architecture '${value}'`);
|
|
31
|
+
}
|
|
32
|
+
function fileDigest(path) {
|
|
33
|
+
return `sha256:${createHash("sha256").update(readFileSync(path)).digest("hex")}`;
|
|
34
|
+
}
|
|
35
|
+
function trustedRegularFile(path, label) {
|
|
36
|
+
let metadata;
|
|
37
|
+
try {
|
|
38
|
+
metadata = lstatSync(path);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
throw new WindowsJobKeeperArtifactError(`${label} is unavailable: ${path}`, { cause: error });
|
|
42
|
+
}
|
|
43
|
+
if (!metadata.isFile() || metadata.isSymbolicLink()) {
|
|
44
|
+
throw new WindowsJobKeeperArtifactError(`${label} is not a regular non-symlink file: ${path}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function resolveManifestMember(manifestPath, member, label) {
|
|
48
|
+
if (member.length === 0 || isAbsolute(member) || member.includes("\0")) {
|
|
49
|
+
throw new WindowsJobKeeperArtifactError(`${label} path is not a safe relative path`);
|
|
50
|
+
}
|
|
51
|
+
const root = realpathSync(dirname(manifestPath));
|
|
52
|
+
const path = resolve(root, member);
|
|
53
|
+
trustedRegularFile(path, label);
|
|
54
|
+
const actual = realpathSync(path);
|
|
55
|
+
const memberRelative = relative(root, actual);
|
|
56
|
+
if (memberRelative === "" || memberRelative === ".." || memberRelative.startsWith("../") || memberRelative.startsWith("..\\") || isAbsolute(memberRelative)) {
|
|
57
|
+
throw new WindowsJobKeeperArtifactError(`${label} escapes the manifest directory`);
|
|
58
|
+
}
|
|
59
|
+
return actual;
|
|
60
|
+
}
|
|
61
|
+
function parseManifestFile(value, label) {
|
|
62
|
+
if (!record(value) || !exactKeys(value, ["path", "sha256"])) {
|
|
63
|
+
throw new WindowsJobKeeperArtifactError(`${label} has an invalid schema`);
|
|
64
|
+
}
|
|
65
|
+
if (typeof value.path !== "string" || !canonicalDigest(value.sha256)) {
|
|
66
|
+
throw new WindowsJobKeeperArtifactError(`${label} has invalid path or digest fields`);
|
|
67
|
+
}
|
|
68
|
+
return value;
|
|
69
|
+
}
|
|
70
|
+
function parseManifestBinary(value, expectedMachine, label) {
|
|
71
|
+
if (!record(value) || !exactKeys(value, ["path", "sha256", "pe_machine"])) {
|
|
72
|
+
throw new WindowsJobKeeperArtifactError(`${label} has an invalid schema`);
|
|
73
|
+
}
|
|
74
|
+
if (typeof value.path !== "string"
|
|
75
|
+
|| !canonicalDigest(value.sha256)
|
|
76
|
+
|| value.pe_machine !== expectedMachine) {
|
|
77
|
+
throw new WindowsJobKeeperArtifactError(`${label} has invalid artifact identity fields`);
|
|
78
|
+
}
|
|
79
|
+
return value;
|
|
80
|
+
}
|
|
81
|
+
export function parseWindowsJobKeeperManifest(value) {
|
|
82
|
+
if (!record(value) || !exactKeys(value, [
|
|
83
|
+
"schema_version",
|
|
84
|
+
"protocol_version",
|
|
85
|
+
"source",
|
|
86
|
+
"toolchain",
|
|
87
|
+
"binaries",
|
|
88
|
+
])) {
|
|
89
|
+
throw new WindowsJobKeeperArtifactError("Windows Job keeper manifest has an invalid schema");
|
|
90
|
+
}
|
|
91
|
+
if (value.schema_version !== WINDOWS_JOB_KEEPER_MANIFEST_SCHEMA
|
|
92
|
+
|| value.protocol_version !== WINDOWS_JOB_KEEPER_PROTOCOL_VERSION
|
|
93
|
+
|| !record(value.toolchain)
|
|
94
|
+
|| !exactKeys(value.toolchain, [
|
|
95
|
+
"name",
|
|
96
|
+
"version",
|
|
97
|
+
"build_script",
|
|
98
|
+
"source_date_epoch",
|
|
99
|
+
"targets",
|
|
100
|
+
])
|
|
101
|
+
|| value.toolchain.name !== "zig"
|
|
102
|
+
|| value.toolchain.version !== "0.16.0"
|
|
103
|
+
|| !record(value.toolchain.build_script)
|
|
104
|
+
|| !exactKeys(value.toolchain.build_script, ["path", "sha256"])
|
|
105
|
+
|| value.toolchain.build_script.path !== "../../scripts/build-windows-job-keeper.mjs"
|
|
106
|
+
|| !canonicalDigest(value.toolchain.build_script.sha256)
|
|
107
|
+
|| value.toolchain.source_date_epoch !== 0
|
|
108
|
+
|| !record(value.toolchain.targets)
|
|
109
|
+
|| !exactKeys(value.toolchain.targets, ["x86_64", "aarch64"])
|
|
110
|
+
|| value.toolchain.targets.x86_64 !== "x86_64-windows-gnu"
|
|
111
|
+
|| value.toolchain.targets.aarch64 !== "aarch64-windows-gnu"
|
|
112
|
+
|| !record(value.binaries)
|
|
113
|
+
|| !exactKeys(value.binaries, ["x86_64", "aarch64"])) {
|
|
114
|
+
throw new WindowsJobKeeperArtifactError("Windows Job keeper manifest has an unsupported identity");
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
schema_version: WINDOWS_JOB_KEEPER_MANIFEST_SCHEMA,
|
|
118
|
+
protocol_version: WINDOWS_JOB_KEEPER_PROTOCOL_VERSION,
|
|
119
|
+
source: parseManifestFile(value.source, "Windows Job keeper source"),
|
|
120
|
+
toolchain: {
|
|
121
|
+
name: "zig",
|
|
122
|
+
version: "0.16.0",
|
|
123
|
+
build_script: {
|
|
124
|
+
path: "../../scripts/build-windows-job-keeper.mjs",
|
|
125
|
+
sha256: value.toolchain.build_script.sha256,
|
|
126
|
+
},
|
|
127
|
+
source_date_epoch: 0,
|
|
128
|
+
targets: {
|
|
129
|
+
x86_64: "x86_64-windows-gnu",
|
|
130
|
+
aarch64: "aarch64-windows-gnu",
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
binaries: {
|
|
134
|
+
x86_64: parseManifestBinary(value.binaries.x86_64, "0x8664", "Windows Job keeper x86_64 binary"),
|
|
135
|
+
aarch64: parseManifestBinary(value.binaries.aarch64, "0xaa64", "Windows Job keeper aarch64 binary"),
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
export function readPeMachine(path) {
|
|
140
|
+
const bytes = readFileSync(path);
|
|
141
|
+
if (bytes.length < 0x40 || bytes[0] !== 0x4d || bytes[1] !== 0x5a) {
|
|
142
|
+
throw new WindowsJobKeeperArtifactError("Windows Job keeper does not have an MZ header");
|
|
143
|
+
}
|
|
144
|
+
const peOffset = bytes.readUInt32LE(0x3c);
|
|
145
|
+
if (peOffset > bytes.length - 6
|
|
146
|
+
|| bytes.toString("ascii", peOffset, peOffset + 4) !== "PE\0\0") {
|
|
147
|
+
throw new WindowsJobKeeperArtifactError("Windows Job keeper does not have a valid PE header");
|
|
148
|
+
}
|
|
149
|
+
return bytes.readUInt16LE(peOffset + 4);
|
|
150
|
+
}
|
|
151
|
+
function verifyBinary(path, expectedDigest, target) {
|
|
152
|
+
trustedRegularFile(path, "Windows Job keeper binary");
|
|
153
|
+
const actualDigest = fileDigest(path);
|
|
154
|
+
if (actualDigest !== expectedDigest) {
|
|
155
|
+
throw new WindowsJobKeeperArtifactError(`Windows Job keeper digest mismatch: expected ${expectedDigest}, received ${actualDigest}`);
|
|
156
|
+
}
|
|
157
|
+
const expectedMachine = target === "x86_64" ? 0x8664 : 0xaa64;
|
|
158
|
+
const actualMachine = readPeMachine(path);
|
|
159
|
+
if (actualMachine !== expectedMachine) {
|
|
160
|
+
throw new WindowsJobKeeperArtifactError(`Windows Job keeper PE machine mismatch: expected 0x${expectedMachine.toString(16)}, received 0x${actualMachine.toString(16)}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
function repositoryRoot() {
|
|
164
|
+
return resolve(dirname(fileURLToPath(import.meta.url)), "../..");
|
|
165
|
+
}
|
|
166
|
+
function defaultManifestPaths() {
|
|
167
|
+
const root = repositoryRoot();
|
|
168
|
+
return [
|
|
169
|
+
resolve(root, "dist/native/windows-job-keeper/manifest.json"),
|
|
170
|
+
resolve(root, "native/windows-job-keeper/manifest.json"),
|
|
171
|
+
];
|
|
172
|
+
}
|
|
173
|
+
export function resolveWindowsJobKeeperArtifact(options) {
|
|
174
|
+
if (options.platform !== "win32")
|
|
175
|
+
return null;
|
|
176
|
+
const target = architecture(options.architecture ?? process.arch);
|
|
177
|
+
const hasOverride = options.helper_path !== undefined || options.expected_digest !== undefined;
|
|
178
|
+
if (hasOverride) {
|
|
179
|
+
if (process.platform === "win32") {
|
|
180
|
+
throw new WindowsJobKeeperArtifactError("production Windows execution cannot override the packaged Job keeper trust anchor");
|
|
181
|
+
}
|
|
182
|
+
if (options.helper_path === undefined || !canonicalDigest(options.expected_digest)) {
|
|
183
|
+
throw new WindowsJobKeeperArtifactError("simulated Windows execution requires helper_path and a canonical expected_digest");
|
|
184
|
+
}
|
|
185
|
+
const path = resolve(options.helper_path);
|
|
186
|
+
verifyBinary(path, options.expected_digest, target);
|
|
187
|
+
return {
|
|
188
|
+
architecture: target,
|
|
189
|
+
path,
|
|
190
|
+
digest: options.expected_digest,
|
|
191
|
+
source_digest: options.expected_digest,
|
|
192
|
+
protocol_version: WINDOWS_JOB_KEEPER_PROTOCOL_VERSION,
|
|
193
|
+
manifest_path: null,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
const manifestPath = defaultManifestPaths().find(existsSync);
|
|
197
|
+
if (manifestPath === undefined) {
|
|
198
|
+
throw new WindowsJobKeeperArtifactError("packaged Windows Job keeper manifest is unavailable");
|
|
199
|
+
}
|
|
200
|
+
trustedRegularFile(manifestPath, "Windows Job keeper manifest");
|
|
201
|
+
let parsed;
|
|
202
|
+
try {
|
|
203
|
+
parsed = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
throw new WindowsJobKeeperArtifactError("Windows Job keeper manifest is not valid JSON", {
|
|
207
|
+
cause: error,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
const manifest = parseWindowsJobKeeperManifest(parsed);
|
|
211
|
+
const sourcePath = resolveManifestMember(manifestPath, manifest.source.path, "Windows Job keeper source");
|
|
212
|
+
if (fileDigest(sourcePath) !== manifest.source.sha256) {
|
|
213
|
+
throw new WindowsJobKeeperArtifactError("Windows Job keeper source digest mismatch");
|
|
214
|
+
}
|
|
215
|
+
const buildScriptPath = resolve(dirname(manifestPath), manifest.toolchain.build_script.path);
|
|
216
|
+
trustedRegularFile(buildScriptPath, "Windows Job keeper build script");
|
|
217
|
+
if (fileDigest(realpathSync(buildScriptPath)) !== manifest.toolchain.build_script.sha256) {
|
|
218
|
+
throw new WindowsJobKeeperArtifactError("Windows Job keeper build script digest mismatch");
|
|
219
|
+
}
|
|
220
|
+
const binary = manifest.binaries[target];
|
|
221
|
+
const binaryPath = resolveManifestMember(manifestPath, binary.path, "Windows Job keeper binary");
|
|
222
|
+
verifyBinary(binaryPath, binary.sha256, target);
|
|
223
|
+
return {
|
|
224
|
+
architecture: target,
|
|
225
|
+
path: binaryPath,
|
|
226
|
+
digest: binary.sha256,
|
|
227
|
+
source_digest: manifest.source.sha256,
|
|
228
|
+
protocol_version: manifest.protocol_version,
|
|
229
|
+
manifest_path: realpathSync(manifestPath),
|
|
230
|
+
};
|
|
231
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { ProviderEvent, StepPacket } from "./run-contracts.js";
|
|
1
|
+
import type { ProviderEvent, StepPacket, TerminalOutcome } from "./run-contracts.js";
|
|
2
2
|
import type { ExecutionProvider, WorkerExecution } from "./execution-provider.js";
|
|
3
|
+
import { type ProcessTreeRunOptions, type ProcessTreeRunResult } from "./process-tree.js";
|
|
3
4
|
export interface WorkerExecutorOptions {
|
|
4
5
|
readonly cancellationSignal?: AbortSignal;
|
|
5
6
|
readonly cancellationReason?: string | null;
|
|
@@ -7,8 +8,23 @@ export interface WorkerExecutorOptions {
|
|
|
7
8
|
readonly maxProcessCount?: number;
|
|
8
9
|
readonly processLimitPollMs?: number;
|
|
9
10
|
readonly onProcessStart?: (processId: number) => void | Promise<void>;
|
|
11
|
+
readonly execution_authority?: WorkerExecutionAuthorityBinding;
|
|
12
|
+
readonly startedAt?: string;
|
|
10
13
|
readonly now?: () => Date;
|
|
11
14
|
}
|
|
15
|
+
export interface WorkerExecutionAuthorityBinding {
|
|
16
|
+
readonly cancellation_signal: AbortSignal;
|
|
17
|
+
readonly launch_environment?: Readonly<Record<string, string>>;
|
|
18
|
+
executeProcessTree?(command: string, args: readonly string[], options: ProcessTreeRunOptions): Promise<ProcessTreeRunResult>;
|
|
19
|
+
processStarted(processId: number): void | Promise<void>;
|
|
20
|
+
processTreeCompleted(observation: {
|
|
21
|
+
readonly started_at: string;
|
|
22
|
+
readonly completed_at: string;
|
|
23
|
+
readonly outcome: TerminalOutcome;
|
|
24
|
+
readonly process_id: number | null;
|
|
25
|
+
readonly process_tree_drained: boolean;
|
|
26
|
+
}): void | Promise<void>;
|
|
27
|
+
}
|
|
12
28
|
export interface WorkerExecutionWithEvents extends WorkerExecution {
|
|
13
29
|
readonly events: readonly ProviderEvent[];
|
|
14
30
|
}
|
|
@@ -88,17 +88,31 @@ export async function executeWorkerAttempt(packet, provider, options = {}) {
|
|
|
88
88
|
});
|
|
89
89
|
};
|
|
90
90
|
const launch = provider.createLaunch(packet);
|
|
91
|
-
const startedAt = now().toISOString();
|
|
91
|
+
const startedAt = options.startedAt ?? now().toISOString();
|
|
92
92
|
pushEvent({ type: "launch_started", provider: provider.name });
|
|
93
93
|
let processStartObservation = Promise.resolve();
|
|
94
94
|
let processStartFailed = false;
|
|
95
95
|
let processStartError;
|
|
96
|
-
const
|
|
96
|
+
const cancellationSignals = [
|
|
97
|
+
options.cancellationSignal,
|
|
98
|
+
options.execution_authority?.cancellation_signal,
|
|
99
|
+
].filter((signal) => signal !== undefined);
|
|
100
|
+
const cancellationSignal = cancellationSignals.length > 1
|
|
101
|
+
? AbortSignal.any(cancellationSignals)
|
|
102
|
+
: cancellationSignals[0];
|
|
103
|
+
const executeProcessTree = options.execution_authority?.executeProcessTree
|
|
104
|
+
?? runProcessTree;
|
|
105
|
+
const processResult = await executeProcessTree(launch.command, launch.args, {
|
|
97
106
|
cwd: launch.cwd,
|
|
98
|
-
env:
|
|
107
|
+
env: options.execution_authority?.launch_environment === undefined
|
|
108
|
+
? launch.env
|
|
109
|
+
: {
|
|
110
|
+
...(launch.env ?? process.env),
|
|
111
|
+
...options.execution_authority.launch_environment,
|
|
112
|
+
},
|
|
99
113
|
stdin: launch.stdin ?? undefined,
|
|
100
114
|
timeoutMs: packet.execution.timeout_ms ?? undefined,
|
|
101
|
-
cancellationSignal
|
|
115
|
+
cancellationSignal,
|
|
102
116
|
cancellationReason: options.cancellationReason,
|
|
103
117
|
cancellationGraceMs: packet.execution.cancellation_grace_ms,
|
|
104
118
|
maxOutputBytes: options.maxOutputBytes,
|
|
@@ -107,7 +121,7 @@ export async function executeWorkerAttempt(packet, provider, options = {}) {
|
|
|
107
121
|
cleanupOnParentExit: true,
|
|
108
122
|
onProcessStart: (processId) => {
|
|
109
123
|
pushEvent({ type: "process_started", process_id: processId });
|
|
110
|
-
processStartObservation = Promise.resolve(options.onProcessStart?.(processId)).catch((error) => {
|
|
124
|
+
processStartObservation = Promise.resolve(options.execution_authority?.processStarted(processId)).then(() => options.onProcessStart?.(processId)).then(() => undefined).catch((error) => {
|
|
111
125
|
processStartFailed = true;
|
|
112
126
|
processStartError = error;
|
|
113
127
|
});
|
|
@@ -172,6 +186,13 @@ export async function executeWorkerAttempt(packet, provider, options = {}) {
|
|
|
172
186
|
signal: processResult.signal,
|
|
173
187
|
});
|
|
174
188
|
const completedAt = now().toISOString();
|
|
189
|
+
await options.execution_authority?.processTreeCompleted({
|
|
190
|
+
started_at: startedAt,
|
|
191
|
+
completed_at: completedAt,
|
|
192
|
+
outcome,
|
|
193
|
+
process_id: processResult.processId,
|
|
194
|
+
process_tree_drained: processResult.processTreeDrained,
|
|
195
|
+
});
|
|
175
196
|
const result = {
|
|
176
197
|
run_id: packet.run_id,
|
|
177
198
|
step_id: packet.step_id,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { RoleDef, WorkflowPlan, WorkflowStep } from "../schema/types.js";
|
|
2
2
|
import type { ControllerStepDefinition, MaterializeStepPacketInput, WorkflowRetryLoopPolicy } from "./run-controller.js";
|
|
3
3
|
import type { TerminalOutcomeKind } from "./run-contracts.js";
|
|
4
|
+
import { type ExecutableRunPlanPayload, type PlanSourceProvenance, type RunInputContract } from "./executable-run-plan.js";
|
|
4
5
|
export type WorkflowPlanAdapterErrorCode = "invalid_plan" | "missing_role" | "invalid_handoff" | "unsupported_routing";
|
|
5
6
|
export declare class WorkflowPlanAdapterError extends Error {
|
|
6
7
|
readonly code: WorkflowPlanAdapterErrorCode;
|
|
@@ -18,6 +19,19 @@ export interface WorkflowPlanAdapterOptions {
|
|
|
18
19
|
readonly retry_max_delay_ms?: number | null;
|
|
19
20
|
readonly retryable_outcomes?: readonly TerminalOutcomeKind[];
|
|
20
21
|
}
|
|
22
|
+
export interface WorkflowExecutablePlanAdapterOptions {
|
|
23
|
+
readonly roles: Readonly<Record<string, RoleDef>>;
|
|
24
|
+
readonly target_key: string;
|
|
25
|
+
readonly input_contract: RunInputContract;
|
|
26
|
+
readonly source_provenance: PlanSourceProvenance;
|
|
27
|
+
readonly global_constraints?: readonly string[];
|
|
28
|
+
readonly allow_network?: boolean;
|
|
29
|
+
readonly timeout_ms?: number | null;
|
|
30
|
+
readonly cancellation_grace_ms?: number;
|
|
31
|
+
readonly retry_initial_delay_ms?: number;
|
|
32
|
+
readonly retry_max_delay_ms?: number | null;
|
|
33
|
+
readonly retryable_outcomes?: readonly TerminalOutcomeKind[];
|
|
34
|
+
}
|
|
21
35
|
export declare function adaptWorkflowRetryLoop(plan: WorkflowPlan, options?: Pick<WorkflowPlanAdapterOptions, "retry_initial_delay_ms" | "retry_max_delay_ms">): WorkflowRetryLoopPolicy | null;
|
|
22
36
|
/**
|
|
23
37
|
* Adapt one compiled workflow plan into Controller definitions. Every
|
|
@@ -25,3 +39,8 @@ export declare function adaptWorkflowRetryLoop(plan: WorkflowPlan, options?: Pic
|
|
|
25
39
|
* no provider transcript or prior-session state is accepted by this API.
|
|
26
40
|
*/
|
|
27
41
|
export declare function adaptWorkflowPlan(plan: WorkflowPlan, options: WorkflowPlanAdapterOptions): readonly ControllerStepDefinition[];
|
|
42
|
+
/**
|
|
43
|
+
* Compile a WorkflowPlan into the immutable, provider-neutral plan payload.
|
|
44
|
+
* The legacy closure-based adapter above remains unchanged until the S8 cutover.
|
|
45
|
+
*/
|
|
46
|
+
export declare function adaptWorkflowPlanToExecutableRunPlan(plan: WorkflowPlan, options: WorkflowExecutablePlanAdapterOptions): ExecutableRunPlanPayload;
|