@ckanner/flywheel 0.32.1 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/CHANGELOG.md +10 -1
  2. package/README.md +7 -0
  3. package/README.zh-CN.md +5 -0
  4. package/THIRD_PARTY_NOTICES.md +42 -0
  5. package/bin/runtime.js +25 -31
  6. package/cordis.patch.yml +5 -0
  7. package/dist/bridge.mjs +421 -0
  8. package/dist/claude-code-pro-bridge.mjs +82 -0
  9. package/dist/claude-code-pro-worker.mjs +5 -0
  10. package/dist/client.js +4078 -0
  11. package/dist/codex-pro-bridge.mjs +75 -0
  12. package/dist/codex-pro-worker.mjs +5 -0
  13. package/dist/console-read.mjs +51 -0
  14. package/dist/control.mjs +218 -0
  15. package/dist/index.mjs +185 -0
  16. package/dist/installation.mjs +56 -0
  17. package/dist/machine-worker.mjs +241 -0
  18. package/dist/policy.mjs +91 -0
  19. package/dist/prewarm.mjs +136 -0
  20. package/dist/protocol.mjs +260 -0
  21. package/dist/task-association.mjs +127 -0
  22. package/dist/worker.mjs +52 -0
  23. package/dist/workspaces.mjs +42 -0
  24. package/docs/README.md +1 -1
  25. package/docs/README.zh-CN.md +1 -1
  26. package/docs/design.md +7 -4
  27. package/docs/en/configuration.md +1 -1
  28. package/docs/en/contributing.md +5 -6
  29. package/docs/en/flow-console.md +1 -1
  30. package/docs/en/getting-started.md +9 -2
  31. package/docs/en/releasing.md +132 -174
  32. package/docs/validation/2026-11-13-release-0.32.1.md +83 -0
  33. package/docs/validation/2026-11-14-single-package.md +60 -0
  34. package/docs/validation/README.md +2 -0
  35. package/docs/zh-CN/configuration.md +1 -1
  36. package/docs/zh-CN/contributing.md +4 -5
  37. package/docs/zh-CN/flow-console.md +1 -1
  38. package/docs/zh-CN/getting-started.md +7 -3
  39. package/docs/zh-CN/releasing.md +97 -81
  40. package/native/darwin-amd64/flywheel +0 -0
  41. package/native/darwin-arm64/flywheel +0 -0
  42. package/native/linux-amd64/flywheel +0 -0
  43. package/native/linux-arm64/flywheel +0 -0
  44. package/native/manifest.json +22 -0
  45. package/node_modules/dsh-subagent-codex-pro/CHANGELOG.md +403 -0
  46. package/node_modules/dsh-subagent-codex-pro/LICENSE +21 -0
  47. package/node_modules/dsh-subagent-codex-pro/README.md +557 -0
  48. package/node_modules/dsh-subagent-codex-pro/cordis.patch.yml +30 -0
  49. package/node_modules/dsh-subagent-codex-pro/docs/README.zh.md +355 -0
  50. package/node_modules/dsh-subagent-codex-pro/docs/machine-lifecycle-validation.md +65 -0
  51. package/node_modules/dsh-subagent-codex-pro/docs/machine-lifecycle.md +144 -0
  52. package/node_modules/dsh-subagent-codex-pro/docs/machine-lifecycle.zh.md +98 -0
  53. package/node_modules/dsh-subagent-codex-pro/docs/machine.md +194 -0
  54. package/node_modules/dsh-subagent-codex-pro/docs/orchestration.zh.md +86 -0
  55. package/node_modules/dsh-subagent-codex-pro/lib/codex-exec.js +68 -0
  56. package/node_modules/dsh-subagent-codex-pro/lib/codex-exec.js.map +1 -0
  57. package/node_modules/dsh-subagent-codex-pro/lib/dsh-types.js +15 -0
  58. package/node_modules/dsh-subagent-codex-pro/lib/dsh-types.js.map +1 -0
  59. package/node_modules/dsh-subagent-codex-pro/lib/index.js +830 -0
  60. package/node_modules/dsh-subagent-codex-pro/lib/index.js.map +1 -0
  61. package/node_modules/dsh-subagent-codex-pro/lib/jobs.js +35 -0
  62. package/node_modules/dsh-subagent-codex-pro/lib/jobs.js.map +1 -0
  63. package/node_modules/dsh-subagent-codex-pro/lib/jsonrpc.js +229 -0
  64. package/node_modules/dsh-subagent-codex-pro/lib/jsonrpc.js.map +1 -0
  65. package/node_modules/dsh-subagent-codex-pro/lib/machine-cli.js +101 -0
  66. package/node_modules/dsh-subagent-codex-pro/lib/machine-cli.js.map +1 -0
  67. package/node_modules/dsh-subagent-codex-pro/lib/machine-local.js +122 -0
  68. package/node_modules/dsh-subagent-codex-pro/lib/machine-local.js.map +1 -0
  69. package/node_modules/dsh-subagent-codex-pro/lib/machine-recovery.js +167 -0
  70. package/node_modules/dsh-subagent-codex-pro/lib/machine-recovery.js.map +1 -0
  71. package/node_modules/dsh-subagent-codex-pro/lib/machine-supervision.js +141 -0
  72. package/node_modules/dsh-subagent-codex-pro/lib/machine-supervision.js.map +1 -0
  73. package/node_modules/dsh-subagent-codex-pro/lib/machine-supervisor.js +128 -0
  74. package/node_modules/dsh-subagent-codex-pro/lib/machine-supervisor.js.map +1 -0
  75. package/node_modules/dsh-subagent-codex-pro/lib/machine.js +104 -0
  76. package/node_modules/dsh-subagent-codex-pro/lib/machine.js.map +1 -0
  77. package/node_modules/dsh-subagent-codex-pro/lib/process-guardian.js +156 -0
  78. package/node_modules/dsh-subagent-codex-pro/lib/process-guardian.js.map +1 -0
  79. package/node_modules/dsh-subagent-codex-pro/lib/run.js +842 -0
  80. package/node_modules/dsh-subagent-codex-pro/lib/run.js.map +1 -0
  81. package/node_modules/dsh-subagent-codex-pro/lib/structured.js +329 -0
  82. package/node_modules/dsh-subagent-codex-pro/lib/structured.js.map +1 -0
  83. package/node_modules/dsh-subagent-codex-pro/lib/tool.js +295 -0
  84. package/node_modules/dsh-subagent-codex-pro/lib/tool.js.map +1 -0
  85. package/node_modules/dsh-subagent-codex-pro/lib/types/codex-exec.d.ts +88 -0
  86. package/node_modules/dsh-subagent-codex-pro/lib/types/codex-exec.d.ts.map +1 -0
  87. package/node_modules/dsh-subagent-codex-pro/lib/types/dsh-types.d.ts +179 -0
  88. package/node_modules/dsh-subagent-codex-pro/lib/types/dsh-types.d.ts.map +1 -0
  89. package/node_modules/dsh-subagent-codex-pro/lib/types/index.d.ts +266 -0
  90. package/node_modules/dsh-subagent-codex-pro/lib/types/index.d.ts.map +1 -0
  91. package/node_modules/dsh-subagent-codex-pro/lib/types/jobs.d.ts +34 -0
  92. package/node_modules/dsh-subagent-codex-pro/lib/types/jobs.d.ts.map +1 -0
  93. package/node_modules/dsh-subagent-codex-pro/lib/types/jsonrpc.d.ts +113 -0
  94. package/node_modules/dsh-subagent-codex-pro/lib/types/jsonrpc.d.ts.map +1 -0
  95. package/node_modules/dsh-subagent-codex-pro/lib/types/machine-cli.d.ts +3 -0
  96. package/node_modules/dsh-subagent-codex-pro/lib/types/machine-cli.d.ts.map +1 -0
  97. package/node_modules/dsh-subagent-codex-pro/lib/types/machine-local.d.ts +4 -0
  98. package/node_modules/dsh-subagent-codex-pro/lib/types/machine-local.d.ts.map +1 -0
  99. package/node_modules/dsh-subagent-codex-pro/lib/types/machine-recovery.d.ts +53 -0
  100. package/node_modules/dsh-subagent-codex-pro/lib/types/machine-recovery.d.ts.map +1 -0
  101. package/node_modules/dsh-subagent-codex-pro/lib/types/machine-supervision.d.ts +8 -0
  102. package/node_modules/dsh-subagent-codex-pro/lib/types/machine-supervision.d.ts.map +1 -0
  103. package/node_modules/dsh-subagent-codex-pro/lib/types/machine-supervisor.d.ts +2 -0
  104. package/node_modules/dsh-subagent-codex-pro/lib/types/machine-supervisor.d.ts.map +1 -0
  105. package/node_modules/dsh-subagent-codex-pro/lib/types/machine.d.ts +70 -0
  106. package/node_modules/dsh-subagent-codex-pro/lib/types/machine.d.ts.map +1 -0
  107. package/node_modules/dsh-subagent-codex-pro/lib/types/process-guardian.d.ts +22 -0
  108. package/node_modules/dsh-subagent-codex-pro/lib/types/process-guardian.d.ts.map +1 -0
  109. package/node_modules/dsh-subagent-codex-pro/lib/types/run.d.ts +386 -0
  110. package/node_modules/dsh-subagent-codex-pro/lib/types/run.d.ts.map +1 -0
  111. package/node_modules/dsh-subagent-codex-pro/lib/types/structured.d.ts +35 -0
  112. package/node_modules/dsh-subagent-codex-pro/lib/types/structured.d.ts.map +1 -0
  113. package/node_modules/dsh-subagent-codex-pro/lib/types/tool.d.ts +107 -0
  114. package/node_modules/dsh-subagent-codex-pro/lib/types/tool.d.ts.map +1 -0
  115. package/node_modules/dsh-subagent-codex-pro/lib/types/usage.d.ts +131 -0
  116. package/node_modules/dsh-subagent-codex-pro/lib/types/usage.d.ts.map +1 -0
  117. package/node_modules/dsh-subagent-codex-pro/lib/types/wire.d.ts +321 -0
  118. package/node_modules/dsh-subagent-codex-pro/lib/types/wire.d.ts.map +1 -0
  119. package/node_modules/dsh-subagent-codex-pro/lib/usage.js +356 -0
  120. package/node_modules/dsh-subagent-codex-pro/lib/usage.js.map +1 -0
  121. package/node_modules/dsh-subagent-codex-pro/lib/wire.js +986 -0
  122. package/node_modules/dsh-subagent-codex-pro/lib/wire.js.map +1 -0
  123. package/node_modules/dsh-subagent-codex-pro/package.json +76 -0
  124. package/npm/install.js +59 -6
  125. package/package.json +74 -12
  126. package/plugins/dsh/LICENSE +21 -0
  127. package/plugins/dsh/PROTOCOL.md +607 -0
  128. package/plugins/dsh/README.en.md +4 -0
  129. package/plugins/dsh/README.md +342 -0
  130. package/plugins/dsh/README.zh-CN.md +279 -0
  131. package/plugins/dsh/THIRD_PARTY_NOTICES.md +42 -0
  132. package/plugins/dsh/vendor/README.md +17 -0
  133. package/plugins/dsh/vendor/codex-pro.json +16 -0
@@ -0,0 +1,167 @@
1
+ /** Private, durable evidence for one explicitly identified machine invocation. */
2
+ import { closeSync, constants, fstatSync, fsyncSync, lstatSync, mkdirSync, openSync, readFileSync, realpathSync, renameSync, unlinkSync, writeFileSync, } from 'node:fs';
3
+ import { createHash, randomUUID } from 'node:crypto';
4
+ import { dirname, isAbsolute, join, normalize } from 'node:path';
5
+ export const MACHINE_LIFECYCLE_VERSION = 1;
6
+ export const MACHINE_LIFECYCLE_CAPABILITIES = Object.freeze({
7
+ version: 1, durableJournal: true, readOnlyRecovery: true, threadReadyBeforeDispatch: true,
8
+ });
9
+ const MAX_JOURNAL_BYTES = 64 * 1024 * 1024;
10
+ const RECORD_NAME = 'machine-journal.json';
11
+ const EVENTS = new Set(['thread-ready', 'dispatch-intent', 'dispatch-possible', 'turn-accepted', 'terminal', 'cleanup-confirmed']);
12
+ function object(value) {
13
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
14
+ }
15
+ function identity(value) {
16
+ return typeof value === 'string' && value.trim() !== '' && !value.includes('\0') && Buffer.byteLength(value) <= 4096;
17
+ }
18
+ /** A recovery path is deliberately not a search root, an alias or a symlink. */
19
+ export function validateRecoveryDirectory(value, existing = false) {
20
+ if (typeof value !== 'string' || !isAbsolute(value) || value.includes('\0') || normalize(value) !== value
21
+ || value === dirname(value) || realpathSync(dirname(value)) !== dirname(value)) {
22
+ throw new Error('recoveryDirectory must be a canonical absolute path with an existing physical parent');
23
+ }
24
+ if (existing) {
25
+ const stat = lstatSync(value);
26
+ if (!stat.isDirectory() || stat.isSymbolicLink() || (stat.mode & 0o077) !== 0
27
+ || (process.getuid !== undefined && stat.uid !== process.getuid())) {
28
+ throw new Error('recoveryDirectory must be a private owned directory, not a symlink');
29
+ }
30
+ }
31
+ }
32
+ export function validLifecycle(value, requestId, runId) {
33
+ if (!object(value) || value.lifecycleVersion !== 1 || value.type !== 'lifecycle'
34
+ || value.requestId !== requestId || value.runId !== runId || !Number.isSafeInteger(value.sequence)
35
+ || value.sequence < 1 || !EVENTS.has(value.event)
36
+ || (value.threadId !== null && !identity(value.threadId)) || (value.turnId !== null && !identity(value.turnId))
37
+ || typeof value.persistent !== 'boolean' || (value.configuration !== null && !object(value.configuration))
38
+ || !['not-dispatched', 'possible', 'accepted'].includes(value.dispatch)
39
+ || !['unknown', 'completed', 'failed', 'cancelled'].includes(value.outcome)
40
+ || typeof value.cleanupConfirmed !== 'boolean')
41
+ return false;
42
+ if (value.event === 'thread-ready' && (value.dispatch !== 'not-dispatched' || value.threadId === null
43
+ || !object(value.configuration) || value.configuration.matched !== true))
44
+ return false;
45
+ if (value.event === 'dispatch-intent' && value.dispatch !== 'not-dispatched')
46
+ return false;
47
+ if (value.event === 'dispatch-possible' && value.dispatch !== 'possible')
48
+ return false;
49
+ if (value.event === 'turn-accepted' && value.dispatch !== 'accepted')
50
+ return false;
51
+ return value.event !== 'cleanup-confirmed' || value.cleanupConfirmed === true;
52
+ }
53
+ function checksum(body) {
54
+ return createHash('sha256').update(JSON.stringify(body)).digest('hex');
55
+ }
56
+ /** One writer, exclusive directory admission, atomic replacement and directory fsync. */
57
+ export class MachineJournal {
58
+ #directory;
59
+ #body;
60
+ constructor(directory, requestId, runId) {
61
+ validateRecoveryDirectory(directory);
62
+ // EEXIST is a refusal, never an invitation to rerun or replace old evidence.
63
+ mkdirSync(directory, { mode: 0o700 });
64
+ const parent = openSync(dirname(directory), constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
65
+ try {
66
+ fsyncSync(parent);
67
+ }
68
+ finally {
69
+ closeSync(parent);
70
+ }
71
+ this.#directory = directory;
72
+ this.#body = { protocol: 1, type: 'machine-journal', requestId, runId, lifecycle: null, receipt: null };
73
+ this.#write();
74
+ }
75
+ lifecycle(event) {
76
+ if (!validLifecycle(event, this.#body.requestId, this.#body.runId)
77
+ || event.sequence !== (this.#body.lifecycle?.sequence ?? 0) + 1)
78
+ throw new Error('invalid lifecycle journal sequence');
79
+ this.#body = { ...this.#body, lifecycle: event };
80
+ this.#write();
81
+ }
82
+ receipt(receipt) {
83
+ if (receipt.protocol !== 1 || receipt.type !== 'result' || receipt.requestId !== this.#body.requestId
84
+ || receipt.runId !== this.#body.runId || this.#body.receipt !== null)
85
+ throw new Error('invalid terminal journal identity');
86
+ this.#body = { ...this.#body, receipt };
87
+ this.#write();
88
+ }
89
+ #write() {
90
+ validateRecoveryDirectory(this.#directory, true);
91
+ const data = JSON.stringify({ body: this.#body, sha256: checksum(this.#body) }) + '\n';
92
+ if (Buffer.byteLength(data) > MAX_JOURNAL_BYTES)
93
+ throw new Error('machine journal exceeds its bounded size');
94
+ const temporary = join(this.#directory, '.pending-' + randomUUID());
95
+ const fd = openSync(temporary, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY | constants.O_NOFOLLOW, 0o600);
96
+ try {
97
+ writeFileSync(fd, data);
98
+ fsyncSync(fd);
99
+ }
100
+ finally {
101
+ closeSync(fd);
102
+ }
103
+ try {
104
+ renameSync(temporary, join(this.#directory, RECORD_NAME));
105
+ const directory = openSync(this.#directory, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
106
+ try {
107
+ fsyncSync(directory);
108
+ }
109
+ finally {
110
+ closeSync(directory);
111
+ }
112
+ }
113
+ finally {
114
+ try {
115
+ unlinkSync(temporary);
116
+ }
117
+ catch { /* already renamed or retained evidence */ }
118
+ }
119
+ }
120
+ }
121
+ /** Read exactly one owned journal. Never starts a process, contacts a model or changes files. */
122
+ export async function recoverMachine(value) {
123
+ if (!object(value) || Object.keys(value).some(key => !['protocol', 'requestId', 'runId', 'recoveryDirectory'].includes(key))
124
+ || value.protocol !== 1 || !identity(value.requestId) || !identity(value.runId)
125
+ || typeof value.recoveryDirectory !== 'string' || !isAbsolute(value.recoveryDirectory)
126
+ || value.recoveryDirectory.includes('\0'))
127
+ throw new Error('invalid machine recovery request');
128
+ const base = { protocol: 1, type: 'recovery', requestId: value.requestId, runId: value.runId };
129
+ const unknown = (reason) => ({ ...base, status: 'unknown', receipt: null, lifecycle: null, reason });
130
+ try {
131
+ validateRecoveryDirectory(value.recoveryDirectory, true);
132
+ const file = join(value.recoveryDirectory, RECORD_NAME);
133
+ const fd = openSync(file, constants.O_RDONLY | constants.O_NOFOLLOW);
134
+ let data;
135
+ try {
136
+ const stat = fstatSync(fd);
137
+ if (!stat.isFile() || stat.size > MAX_JOURNAL_BYTES || (stat.mode & 0o077) !== 0
138
+ || (process.getuid !== undefined && stat.uid !== process.getuid()))
139
+ return unknown('untrusted journal file');
140
+ data = JSON.parse(readFileSync(fd, 'utf8'));
141
+ }
142
+ finally {
143
+ closeSync(fd);
144
+ }
145
+ if (!object(data) || !object(data.body) || data.sha256 !== checksum(data.body))
146
+ return unknown('invalid journal integrity');
147
+ const body = data.body;
148
+ if (body.protocol !== 1 || body.type !== 'machine-journal' || body.requestId !== value.requestId || body.runId !== value.runId
149
+ || (body.lifecycle !== null && !validLifecycle(body.lifecycle, value.requestId, value.runId)))
150
+ return unknown('journal identity does not match');
151
+ const lifecycle = body.lifecycle;
152
+ if (body.receipt === null)
153
+ return { ...base, status: 'pending', receipt: null, lifecycle,
154
+ reason: 'no durable terminal receipt; owner liveness, execution outcome and replay safety remain unproven' };
155
+ const receipt = body.receipt;
156
+ if (!object(receipt) || receipt.protocol !== 1 || receipt.type !== 'result'
157
+ || receipt.requestId !== value.requestId || receipt.runId !== value.runId || typeof receipt.ok !== 'boolean') {
158
+ return unknown('invalid terminal receipt identity');
159
+ }
160
+ return { ...base, status: 'terminal', receipt: receipt, lifecycle,
161
+ reason: 'original durable receipt; caller must validate its configuration, outcome and independent cleanup facts' };
162
+ }
163
+ catch {
164
+ return unknown('journal absent, inaccessible or malformed; no replay is authorized');
165
+ }
166
+ }
167
+ //# sourceMappingURL=machine-recovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine-recovery.js","sourceRoot":"","sources":["../src/machine-recovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,141 @@
1
+ /** A machine supervisor owns terminal persistence even after its API caller dies. */
2
+ import { fork } from 'node:child_process';
3
+ import { randomUUID } from 'node:crypto';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { validLifecycle } from "./machine-recovery.js";
6
+ /** This promise rejects on incomplete evidence; it never fabricates a successful receipt. */
7
+ export async function superviseMachine(request, options) {
8
+ const runId = randomUUID();
9
+ const host = fork(fileURLToPath(new URL(import.meta.url.endsWith('.ts') ? './machine-supervisor.ts' : './machine-supervisor.js', import.meta.url)), [], {
10
+ execPath: process.execPath, execArgv: [], detached: true,
11
+ stdio: ['ignore', 'ignore', 'pipe', 'ipc'], env: {},
12
+ });
13
+ let settled = false, ready = false, receipt, failure;
14
+ let lastSequence = 0;
15
+ let exitDrain;
16
+ let resolveClosed;
17
+ const closed = new Promise(resolve => { resolveClosed = resolve; });
18
+ const send = (message) => {
19
+ if (!host.connected)
20
+ return;
21
+ try {
22
+ host.send({ protocol: 1, runId, ...message }, error => { if (error !== null)
23
+ disconnect(); });
24
+ }
25
+ catch {
26
+ disconnect();
27
+ }
28
+ };
29
+ const disconnect = () => {
30
+ try {
31
+ if (host.connected)
32
+ host.disconnect();
33
+ }
34
+ catch { /* The inherited lease is already closed. */ }
35
+ };
36
+ const invalid = (reason) => {
37
+ failure ??= new Error(reason);
38
+ send({ type: 'cancel' });
39
+ disconnect();
40
+ };
41
+ const cancel = () => { send({ type: 'cancel' }); };
42
+ options.signal?.addEventListener('abort', cancel, { once: true });
43
+ const admissionTimer = setTimeout(() => { invalid('machine supervisor admission timed out'); }, 10_000);
44
+ host.stderr?.on('data', () => { });
45
+ const settleExit = (code, signal) => {
46
+ if (settled)
47
+ return;
48
+ settled = true;
49
+ clearTimeout(admissionTimer);
50
+ if (exitDrain !== undefined)
51
+ clearTimeout(exitDrain);
52
+ options.signal?.removeEventListener('abort', cancel);
53
+ if (code !== 0 || signal !== null)
54
+ failure ??= new Error('machine supervisor exited without a complete normal handoff');
55
+ resolveClosed();
56
+ };
57
+ host.once('error', () => { invalid('machine supervisor could not start'); if (host.pid === undefined)
58
+ settleExit(null, null); });
59
+ host.once('close', settleExit);
60
+ host.once('exit', (code, signal) => {
61
+ // A simultaneous IPC disconnect can suppress ChildProcess 'close' on some
62
+ // Node versions. The OS exit is authoritative for this supervisor; allow a
63
+ // bounded IPC drain, then stop waiting on an already-dead process.
64
+ exitDrain = setTimeout(() => { host.stderr?.destroy(); settleExit(code, signal); }, 250);
65
+ });
66
+ host.on('message', (raw) => {
67
+ if (settled || failure !== undefined)
68
+ return;
69
+ if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {
70
+ invalid('invalid machine supervisor message');
71
+ return;
72
+ }
73
+ const message = raw;
74
+ if (message.protocol !== 1 || (message.type !== 'ready' && message.runId !== runId)) {
75
+ invalid('machine supervisor identity mismatch');
76
+ return;
77
+ }
78
+ if (message.type === 'ready') {
79
+ if (ready) {
80
+ invalid('duplicate machine supervisor admission');
81
+ return;
82
+ }
83
+ ready = true;
84
+ clearTimeout(admissionTimer);
85
+ const env = { ...process.env, ...options.env };
86
+ send({ type: 'start', request, options: { env,
87
+ ...(options.recoveryDirectory === undefined ? {} : { recoveryDirectory: options.recoveryDirectory }) } });
88
+ if (options.signal?.aborted === true)
89
+ cancel();
90
+ return;
91
+ }
92
+ if (!ready || receipt !== undefined) {
93
+ invalid('machine supervisor message out of order');
94
+ return;
95
+ }
96
+ if (message.type === 'lifecycle') {
97
+ const event = message.event;
98
+ if (!validLifecycle(event, request.requestId, runId) || event.sequence !== lastSequence + 1) {
99
+ invalid('machine supervisor lifecycle mismatch');
100
+ return;
101
+ }
102
+ lastSequence = event.sequence;
103
+ // Rejection is an explicit negative ACK. The host aborts before a turn can
104
+ // cross a pre-dispatch barrier; a final receipt remains intact after cleanup.
105
+ void Promise.resolve().then(() => options.onLifecycle?.(event)).then(() => { send({ type: 'ack', sequence: event.sequence, ok: true }); }, () => { send({ type: 'ack', sequence: event.sequence, ok: false }); });
106
+ }
107
+ else if (message.type === 'progress' && typeof message.text === 'string') {
108
+ try {
109
+ options.onProgress?.(message.text);
110
+ }
111
+ catch { /* Progress is display-only. */ }
112
+ }
113
+ else if (message.type === 'result') {
114
+ const value = message.receipt;
115
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) {
116
+ invalid('invalid machine supervisor receipt');
117
+ return;
118
+ }
119
+ const result = value;
120
+ if (result.protocol !== 1 || result.type !== 'result' || result.requestId !== request.requestId
121
+ || result.runId !== runId || typeof result.ok !== 'boolean') {
122
+ invalid('machine supervisor terminal identity mismatch');
123
+ return;
124
+ }
125
+ receipt = result;
126
+ }
127
+ else if (message.type === 'failure') {
128
+ failure = new Error('machine supervisor could not persist or deliver complete invocation evidence');
129
+ disconnect();
130
+ }
131
+ else
132
+ invalid('unsupported machine supervisor message');
133
+ });
134
+ await closed;
135
+ if (failure !== undefined)
136
+ throw failure;
137
+ if (receipt === undefined)
138
+ throw new Error('machine supervisor closed without a terminal receipt; recover the known journal before replay');
139
+ return receipt;
140
+ }
141
+ //# sourceMappingURL=machine-supervision.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine-supervision.js","sourceRoot":"","sources":["../src/machine-supervision.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,128 @@
1
+ /** Private supervised machine host. Native cleanup and journal completion outlive the caller. */
2
+ import { runMachineLocal } from "./machine-local.js";
3
+ import { MachineJournal } from "./machine-recovery.js";
4
+ const abort = new AbortController();
5
+ let started = false, finished = false, runId;
6
+ let acknowledgement;
7
+ const cancel = () => {
8
+ abort.abort();
9
+ acknowledgement?.reject(new Error('machine caller disconnected or cancelled'));
10
+ acknowledgement = undefined;
11
+ };
12
+ for (const event of ['SIGTERM', 'SIGINT', 'SIGHUP'])
13
+ process.on(event, cancel);
14
+ process.on('disconnect', cancel);
15
+ function send(message) {
16
+ return new Promise(resolve => {
17
+ if (!process.connected || process.send === undefined) {
18
+ resolve(false);
19
+ return;
20
+ }
21
+ try {
22
+ process.send({ protocol: 1, runId, ...message }, error => {
23
+ if (error !== null)
24
+ cancel();
25
+ resolve(error === null);
26
+ });
27
+ }
28
+ catch {
29
+ cancel();
30
+ resolve(false);
31
+ }
32
+ });
33
+ }
34
+ const admissionTimer = setTimeout(() => {
35
+ if (!started) {
36
+ cancel();
37
+ if (process.connected)
38
+ process.disconnect();
39
+ process.exitCode = 1;
40
+ }
41
+ }, 10_000);
42
+ process.on('disconnect', () => { if (!started) {
43
+ clearTimeout(admissionTimer);
44
+ process.exitCode = 0;
45
+ } });
46
+ process.on('message', (raw) => {
47
+ if (finished)
48
+ return;
49
+ if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {
50
+ cancel();
51
+ return;
52
+ }
53
+ const message = raw;
54
+ if (message.protocol !== 1 || (started && message.runId !== runId)) {
55
+ cancel();
56
+ return;
57
+ }
58
+ if (message.type === 'cancel') {
59
+ cancel();
60
+ return;
61
+ }
62
+ if (message.type === 'ack') {
63
+ if (acknowledgement === undefined || message.sequence !== acknowledgement.sequence || typeof message.ok !== 'boolean') {
64
+ cancel();
65
+ return;
66
+ }
67
+ const pending = acknowledgement;
68
+ acknowledgement = undefined;
69
+ if (message.ok)
70
+ pending.resolve();
71
+ else {
72
+ pending.reject(new Error('machine lifecycle checkpoint was rejected'));
73
+ abort.abort();
74
+ }
75
+ return;
76
+ }
77
+ if (started || message.type !== 'start' || typeof message.runId !== 'string') {
78
+ cancel();
79
+ return;
80
+ }
81
+ started = true;
82
+ runId = message.runId;
83
+ clearTimeout(admissionTimer);
84
+ void execute(message.request, message.options);
85
+ });
86
+ async function execute(request, options) {
87
+ try {
88
+ if (!process.connected)
89
+ cancel();
90
+ const journal = options.recoveryDirectory === undefined ? undefined : new MachineJournal(options.recoveryDirectory, request.requestId, runId);
91
+ const onLifecycle = async (event) => {
92
+ journal?.lifecycle(event);
93
+ if (!process.connected || abort.signal.aborted)
94
+ throw new Error('machine caller is no longer awaiting this checkpoint');
95
+ const ack = new Promise((resolve, reject) => { acknowledgement = { sequence: event.sequence, resolve, reject }; });
96
+ // Attach the handler before a send can synchronously trigger disconnect.
97
+ const waiting = ack.catch((error) => { throw error; });
98
+ waiting.catch(() => { });
99
+ const timeout = setTimeout(cancel, 10_000);
100
+ try {
101
+ if (!await send({ type: 'lifecycle', event }))
102
+ cancel();
103
+ await waiting;
104
+ }
105
+ finally {
106
+ clearTimeout(timeout);
107
+ }
108
+ };
109
+ const receipt = await runMachineLocal(request, {
110
+ signal: abort.signal, env: options.env, onLifecycle,
111
+ onProgress: text => { void send({ type: 'progress', text: text.slice(0, 16_384) }); },
112
+ }, runId, value => { journal?.receipt(value); });
113
+ await send({ type: 'result', receipt });
114
+ }
115
+ catch {
116
+ await send({ type: 'failure' });
117
+ }
118
+ finally {
119
+ finished = true;
120
+ acknowledgement?.reject(new Error('machine supervisor completed'));
121
+ acknowledgement = undefined;
122
+ if (process.connected)
123
+ process.disconnect();
124
+ process.exitCode = 0;
125
+ }
126
+ }
127
+ await send({ type: 'ready' });
128
+ //# sourceMappingURL=machine-supervisor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine-supervisor.js","sourceRoot":"","sources":["../src/machine-supervisor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,104 @@
1
+ /** Versioned, host-independent entry point for deterministic orchestrators. */
2
+ import { isAbsolute } from 'node:path';
3
+ import { runMachineLocal } from "./machine-local.js";
4
+ import { superviseMachine } from "./machine-supervision.js";
5
+ import { validateRecoveryDirectory } from "./machine-recovery.js";
6
+ export { MACHINE_LIFECYCLE_VERSION, MACHINE_LIFECYCLE_CAPABILITIES, recoverMachine } from "./machine-recovery.js";
7
+ export const MACHINE_PROTOCOL_VERSION = 1;
8
+ export class MachineInputError extends Error {
9
+ code = 'INVALID_REQUEST';
10
+ constructor(message) { super(message); this.name = 'MachineInputError'; }
11
+ }
12
+ const INPUT_KEYS = new Set([
13
+ 'protocol', 'requestId', 'prompt', 'cwd', 'model', 'effort', 'permissionMode',
14
+ 'command', 'timeoutMs', 'maxOutputBytes', 'threadMode', 'threadId', 'images', 'outputSchema',
15
+ ]);
16
+ function textField(input, key, optional = false) {
17
+ const value = input[key];
18
+ if (optional && value === undefined)
19
+ return;
20
+ if (typeof value !== 'string' || value.trim() === '' || value.includes('\0')) {
21
+ throw new MachineInputError(key + ' must be a nonempty string without NUL');
22
+ }
23
+ if (key === 'requestId' && Buffer.byteLength(value) > 4096)
24
+ throw new MachineInputError('requestId exceeds 4096 bytes');
25
+ }
26
+ /** Validate before starting any process; unknown options never silently disappear. */
27
+ export function parseMachineRequest(value) {
28
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) {
29
+ throw new MachineInputError('request must be a JSON object');
30
+ }
31
+ const input = value;
32
+ if (Object.keys(input).some((key) => !INPUT_KEYS.has(key)))
33
+ throw new MachineInputError('request contains an unsupported field');
34
+ if (input.protocol !== MACHINE_PROTOCOL_VERSION)
35
+ throw new MachineInputError('unsupported machine protocol version');
36
+ for (const key of ['requestId', 'prompt', 'cwd', 'model', 'effort'])
37
+ textField(input, key);
38
+ for (const key of ['command', 'threadId'])
39
+ textField(input, key, true);
40
+ if (!isAbsolute(input.cwd))
41
+ throw new MachineInputError('cwd must be absolute');
42
+ if (typeof input.permissionMode !== 'string'
43
+ || !['read-only', 'workspace-write', 'dangerously-bypass-approvals-and-sandbox'].includes(input.permissionMode)) {
44
+ throw new MachineInputError('permissionMode must explicitly select a supported sandbox');
45
+ }
46
+ for (const key of ['timeoutMs', 'maxOutputBytes']) {
47
+ const number = input[key];
48
+ if (number !== undefined && (!Number.isSafeInteger(number) || number < (key === 'timeoutMs' ? 0 : 1)
49
+ || (key === 'timeoutMs' && number > 2_147_483_647))) {
50
+ throw new MachineInputError(key + ' must be a safe integer in its allowed range');
51
+ }
52
+ }
53
+ if (input.threadMode !== undefined && (typeof input.threadMode !== 'string'
54
+ || !['ephemeral', 'persistent'].includes(input.threadMode))) {
55
+ throw new MachineInputError('unsupported threadMode');
56
+ }
57
+ if (input.threadId !== undefined && input.threadMode === 'ephemeral') {
58
+ throw new MachineInputError('resuming a thread requires persistent mode');
59
+ }
60
+ if (input.images !== undefined && (!Array.isArray(input.images)
61
+ || input.images.some((path) => typeof path !== 'string' || !isAbsolute(path) || path.includes('\0')))) {
62
+ throw new MachineInputError('images must contain absolute paths');
63
+ }
64
+ if (input.outputSchema !== undefined) {
65
+ const schema = input.outputSchema;
66
+ if (schema === null || typeof schema !== 'object' || Array.isArray(schema)
67
+ || schema.type !== 'object') {
68
+ throw new MachineInputError('outputSchema must be an object-rooted JSON Schema');
69
+ }
70
+ }
71
+ return input;
72
+ }
73
+ /** A machine run never invents an exit code, usage, effective effort, or dollar cost. */
74
+ export async function runMachine(value, options = {}) {
75
+ const request = parseMachineRequest(value);
76
+ if (process.platform === 'win32')
77
+ throw new MachineInputError('machine execution requires POSIX process-group supervision');
78
+ if (options === null || typeof options !== 'object' || Array.isArray(options)
79
+ || Object.keys(options).some(key => !['signal', 'env', 'onProgress', 'onLifecycle', 'recoveryDirectory'].includes(key))) {
80
+ throw new MachineInputError('machine options contain unsupported fields');
81
+ }
82
+ if (options.signal !== undefined && !(options.signal instanceof AbortSignal))
83
+ throw new MachineInputError('signal must be an AbortSignal');
84
+ if (options.onProgress !== undefined && typeof options.onProgress !== 'function')
85
+ throw new MachineInputError('onProgress must be a function');
86
+ if (options.env !== undefined && (options.env === null || typeof options.env !== 'object' || Array.isArray(options.env)
87
+ || Object.values(options.env).some(value => value !== undefined && (typeof value !== 'string' || value.includes('\0'))))) {
88
+ throw new MachineInputError('env must contain only string environment values');
89
+ }
90
+ if (options.onLifecycle !== undefined && typeof options.onLifecycle !== 'function')
91
+ throw new MachineInputError('onLifecycle must be a function');
92
+ if (options.recoveryDirectory !== undefined) {
93
+ try {
94
+ validateRecoveryDirectory(options.recoveryDirectory);
95
+ }
96
+ catch {
97
+ throw new MachineInputError('invalid recoveryDirectory');
98
+ }
99
+ }
100
+ if (options.onLifecycle !== undefined || options.recoveryDirectory !== undefined)
101
+ return superviseMachine(request, options);
102
+ return runMachineLocal(request, options);
103
+ }
104
+ //# sourceMappingURL=machine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine.js","sourceRoot":"","sources":["../src/machine.ts"],"names":[],"mappings":"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"}