@vtxmacro/cli 2026.8.55 → 2026.8.56

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.
@@ -0,0 +1,1540 @@
1
+ // lib/inference-host/service-bootstrap.ts
2
+ import { spawn as spawn2 } from "node:child_process";
3
+ import { createHash, randomUUID } from "node:crypto";
4
+ import {
5
+ access,
6
+ appendFile,
7
+ mkdir as mkdir2,
8
+ readFile as readFile2,
9
+ readdir,
10
+ rename as rename2,
11
+ rm as rm2
12
+ } from "node:fs/promises";
13
+ import { dirname as dirname2, isAbsolute as isAbsolute2, join as join2, relative as relative2, resolve as resolve2, win32 as windowsPath2 } from "node:path";
14
+ import { fileURLToPath } from "node:url";
15
+
16
+ // agent-cli-release.json
17
+ var agent_cli_release_default = {
18
+ package_name: "@vtxmacro/cli",
19
+ package_version: "2026.8.56",
20
+ codex_package_name: "@openai/codex",
21
+ codex_version: "0.147.0",
22
+ copilot_sdk_package_name: "@github/copilot-sdk",
23
+ copilot_sdk_version: "1.0.0-beta.8",
24
+ copilot_cli_package_name: "@github/copilot",
25
+ copilot_cli_version: "1.0.80",
26
+ deepseek_harness_version: "0.1.1-rc.2",
27
+ deepseek_harness_packages: [
28
+ "@deepseek-ai/dsh-agent",
29
+ "@deepseek-ai/dsh-agent-instructions",
30
+ "@deepseek-ai/dsh-agent-loop",
31
+ "@deepseek-ai/dsh-agent-spine-demo",
32
+ "@deepseek-ai/dsh-anonymous-user-id",
33
+ "@deepseek-ai/dsh-atomic-write",
34
+ "@deepseek-ai/dsh-attachment",
35
+ "@deepseek-ai/dsh-brand",
36
+ "@deepseek-ai/dsh-code-runtime",
37
+ "@deepseek-ai/dsh-credentials",
38
+ "@deepseek-ai/dsh-fs",
39
+ "@deepseek-ai/dsh-goal",
40
+ "@deepseek-ai/dsh-goal-round-driver",
41
+ "@deepseek-ai/dsh-home-paths",
42
+ "@deepseek-ai/dsh-invariants",
43
+ "@deepseek-ai/dsh-jobs",
44
+ "@deepseek-ai/dsh-jobs-local",
45
+ "@deepseek-ai/dsh-launch-environment",
46
+ "@deepseek-ai/dsh-llm",
47
+ "@deepseek-ai/dsh-llm-deepseek",
48
+ "@deepseek-ai/dsh-llm-retry",
49
+ "@deepseek-ai/dsh-output-retention",
50
+ "@deepseek-ai/dsh-sandbox",
51
+ "@deepseek-ai/dsh-sandbox-policy",
52
+ "@deepseek-ai/dsh-scope",
53
+ "@deepseek-ai/dsh-session",
54
+ "@deepseek-ai/dsh-session-checkpoint-policy",
55
+ "@deepseek-ai/dsh-session-persistence",
56
+ "@deepseek-ai/dsh-session-persistence-jsonl",
57
+ "@deepseek-ai/dsh-session-projection",
58
+ "@deepseek-ai/dsh-session-title",
59
+ "@deepseek-ai/dsh-settings",
60
+ "@deepseek-ai/dsh-shell",
61
+ "@deepseek-ai/dsh-shell-env",
62
+ "@deepseek-ai/dsh-skill",
63
+ "@deepseek-ai/dsh-skill-filesystem",
64
+ "@deepseek-ai/dsh-subprocess",
65
+ "@deepseek-ai/dsh-system-prompt",
66
+ "@deepseek-ai/dsh-timeout",
67
+ "@deepseek-ai/dsh-tool-bash",
68
+ "@deepseek-ai/dsh-tool-goal",
69
+ "@deepseek-ai/dsh-tool-jobs",
70
+ "@deepseek-ai/dsh-tool-skill",
71
+ "@deepseek-ai/dsh-tools",
72
+ "@deepseek-ai/dsh-typert-protocol",
73
+ "@deepseek-ai/dsh-user-approval"
74
+ ],
75
+ deepseek_cordis_package_name: "@deepseek-ai/cordis",
76
+ deepseek_cordis_version: "4.0.1",
77
+ deepseek_support_packages: {
78
+ "@deepseek-ai/cordis-plugin-timer": "1.1.3"
79
+ },
80
+ platforms: {
81
+ "linux-x64": {
82
+ package_name: "@openai/codex-linux-x64",
83
+ target: "x86_64-unknown-linux-musl",
84
+ binary_name: "codex",
85
+ sha256: "cb0a15567e9a60a5820d54b0f6ae86d504dc3805c1eab21a47f70e3eb7b73a40"
86
+ },
87
+ "win32-x64": {
88
+ package_name: "@openai/codex-win32-x64",
89
+ target: "x86_64-pc-windows-msvc",
90
+ binary_name: "codex.exe",
91
+ sha256: "935a1911ed2556e4ffcec995f4886ac2ac425863ba26fed264df62e30272ad9d"
92
+ }
93
+ }
94
+ };
95
+
96
+ // lib/inference-host/config.ts
97
+ import { randomBytes } from "node:crypto";
98
+ import { spawn } from "node:child_process";
99
+ import { constants } from "node:fs";
100
+ import { lstat, mkdir, open, readFile, realpath, rename, rm } from "node:fs/promises";
101
+ import { homedir } from "node:os";
102
+ import { dirname, isAbsolute, join, relative, resolve, win32 as windowsPath } from "node:path";
103
+ var MAX_INFERENCE_PRIVATE_FILE_BYTES = 16 * 1024 * 1024;
104
+ var WINDOWS_PRIVATE_ACL_BROKER_SCRIPT = `$ErrorActionPreference='Stop'
105
+ $ProgressPreference='SilentlyContinue'
106
+ while(($line=[Console]::In.ReadLine()) -ne $null) {
107
+ $requestId=$null
108
+ $failureStage='request_validation'
109
+ try {
110
+ if($line.Length -lt 2 -or $line.Length -gt 65536) { throw 'invalid request size' }
111
+ $request=$line | ConvertFrom-Json
112
+ $names=@($request.PSObject.Properties.Name | Sort-Object)
113
+ if(($names -join ',') -ne 'id,kind,mode,path_b64') { throw 'invalid request shape' }
114
+ if($request.id -isnot [long] -and $request.id -isnot [int]) { throw 'invalid request id' }
115
+ $requestId=[long]$request.id
116
+ if($requestId -lt 1) { throw 'invalid request id' }
117
+ $kind=[string]$request.kind
118
+ $mode=[string]$request.mode
119
+ if($kind -ne 'directory' -and $kind -ne 'file') { throw 'invalid path kind' }
120
+ if($mode -ne 'harden' -and $mode -ne 'verify' -and $mode -ne 'verify-owner') { throw 'invalid ACL mode' }
121
+ $path=[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String([string]$request.path_b64))
122
+ if([string]::IsNullOrWhiteSpace($path) -or $path.Length -gt 32767 -or $path.Contains([char]0)) { throw 'invalid path' }
123
+ $failureStage='path_lookup'
124
+ if(-not (Test-Path -LiteralPath $path)) {
125
+ [Console]::Out.WriteLine((@{id=$requestId;status='missing'} | ConvertTo-Json -Compress))
126
+ continue
127
+ }
128
+ $failureStage='principal_resolution'
129
+ $currentIdentity=[Security.Principal.WindowsIdentity]::GetCurrent()
130
+ $current=$currentIdentity.User
131
+ $system=New-Object Security.Principal.SecurityIdentifier('S-1-5-18')
132
+ $admins=New-Object Security.Principal.SecurityIdentifier('S-1-5-32-544')
133
+ $currentIsAdmin=(New-Object Security.Principal.WindowsPrincipal($currentIdentity)).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
134
+ $allowed=@($current.Value,$system.Value,$admins.Value)
135
+ if($mode -eq 'harden') {
136
+ $failureStage='acl_read'
137
+ $acl=Get-Acl -LiteralPath $path
138
+ $failureStage='owner_validation'
139
+ $existingOwner=(New-Object Security.Principal.NTAccount($acl.Owner)).Translate([Security.Principal.SecurityIdentifier]).Value
140
+ if($existingOwner -ne $current.Value -and ($existingOwner -ne $admins.Value -or -not $currentIsAdmin)) { throw 'private ACL owner is invalid' }
141
+ $failureStage='acl_mutation'
142
+ $acl.SetAccessRuleProtection($true,$false)
143
+ foreach($existingRule in @($acl.Access)) { [void]$acl.RemoveAccessRuleSpecific($existingRule) }
144
+ $inherit=if($kind -eq 'directory') {
145
+ [Security.AccessControl.InheritanceFlags]'ContainerInherit,ObjectInherit'
146
+ } else { [Security.AccessControl.InheritanceFlags]::None }
147
+ foreach($sid in @($current,$system,$admins)) {
148
+ $rule=New-Object Security.AccessControl.FileSystemAccessRule(
149
+ $sid,
150
+ [Security.AccessControl.FileSystemRights]::FullControl,
151
+ $inherit,
152
+ [Security.AccessControl.PropagationFlags]::None,
153
+ [Security.AccessControl.AccessControlType]::Allow
154
+ )
155
+ [void]$acl.AddAccessRule($rule)
156
+ }
157
+ $failureStage='acl_write'
158
+ (Get-Item -LiteralPath $path).SetAccessControl($acl)
159
+ }
160
+ $failureStage='acl_readback'
161
+ $actual=Get-Acl -LiteralPath $path
162
+ $failureStage='acl_verification'
163
+ $owner=(New-Object Security.Principal.NTAccount($actual.Owner)).Translate([Security.Principal.SecurityIdentifier]).Value
164
+ if($owner -ne $current.Value -and ($owner -ne $admins.Value -or -not $currentIsAdmin)) { throw 'private ACL owner is invalid' }
165
+ if($mode -ne 'verify-owner') {
166
+ if(-not $actual.AreAccessRulesProtected) { throw 'private ACL inheritance is invalid' }
167
+ $userFull=$false
168
+ foreach($rule in $actual.Access) {
169
+ $sid=$rule.IdentityReference.Translate([Security.Principal.SecurityIdentifier]).Value
170
+ if($rule.IsInherited -or $allowed -notcontains $sid -or $rule.AccessControlType -ne [Security.AccessControl.AccessControlType]::Allow) {
171
+ throw 'private ACL contains an unauthorized access rule'
172
+ }
173
+ if($sid -eq $current.Value -and (($rule.FileSystemRights -band [Security.AccessControl.FileSystemRights]::FullControl) -eq [Security.AccessControl.FileSystemRights]::FullControl)) { $userFull=$true }
174
+ }
175
+ if(-not $userFull) { throw 'private ACL does not grant the current user full control' }
176
+ }
177
+ [Console]::Out.WriteLine((@{id=$requestId;status='ok'} | ConvertTo-Json -Compress))
178
+ } catch {
179
+ [Console]::Out.WriteLine((@{id=$requestId;status='error';error_code=$failureStage} | ConvertTo-Json -Compress))
180
+ }
181
+ }`;
182
+ var WINDOWS_IDENTITY_COMMAND_TIMEOUT_MS = 15e3;
183
+ var WINDOWS_PRIVATE_ACL_BROKER_STARTUP_TIMEOUT_MS = 9e4;
184
+ var SMALL_IDENTITY_COMMAND_TIMEOUT_MS = 5e3;
185
+ var windowsPowerShellEnvironment = (extra = {}) => {
186
+ const sanitizedExtra = { ...extra };
187
+ delete sanitizedExtra.PSModulePath;
188
+ const windowsRoot = process.env.SystemRoot ?? process.env.WINDIR;
189
+ return {
190
+ ...sanitizedExtra,
191
+ NODE_ENV: process.env.NODE_ENV,
192
+ SystemRoot: process.env.SystemRoot,
193
+ WINDIR: process.env.WINDIR,
194
+ ComSpec: process.env.ComSpec,
195
+ PATHEXT: process.env.PATHEXT,
196
+ PSModulePath: windowsRoot ? windowsPath.join(windowsRoot, "System32", "WindowsPowerShell", "v1.0", "Modules") : void 0,
197
+ TEMP: process.env.TEMP,
198
+ TMP: process.env.TMP
199
+ };
200
+ };
201
+ var windowsPrivateAclBrokerInvocation = () => ({
202
+ args: [
203
+ "-NoLogo",
204
+ "-NoProfile",
205
+ "-NonInteractive",
206
+ "-EncodedCommand",
207
+ Buffer.from(WINDOWS_PRIVATE_ACL_BROKER_SCRIPT, "utf16le").toString("base64")
208
+ ],
209
+ env: windowsPowerShellEnvironment()
210
+ });
211
+ var WindowsPrivateAclBroker = class {
212
+ constructor(dependencies = {}) {
213
+ this.child = null;
214
+ this.requestSequence = 0;
215
+ this.queue = Promise.resolve();
216
+ this.pending = null;
217
+ this.outputBuffer = "";
218
+ this.idleTimer = null;
219
+ this.run = async (path, kind, mode) => {
220
+ const operation = this.queue.then(
221
+ () => this.dispatch(path, kind, mode),
222
+ () => this.dispatch(path, kind, mode)
223
+ );
224
+ this.queue = operation.then(() => void 0, () => void 0);
225
+ await operation;
226
+ };
227
+ this.requestTimeoutMs = dependencies.requestTimeoutMs ?? 15e3;
228
+ this.startupRequestTimeoutMs = dependencies.startupRequestTimeoutMs ?? WINDOWS_PRIVATE_ACL_BROKER_STARTUP_TIMEOUT_MS;
229
+ this.idleShutdownMs = dependencies.idleShutdownMs ?? 3e4;
230
+ this.spawnProcess = dependencies.spawnProcess ?? (() => {
231
+ const invocation = windowsPrivateAclBrokerInvocation();
232
+ return spawn("powershell.exe", [...invocation.args], {
233
+ env: invocation.env,
234
+ windowsHide: true,
235
+ stdio: ["pipe", "pipe", "pipe"]
236
+ });
237
+ });
238
+ }
239
+ scheduleIdleShutdown() {
240
+ if (this.idleTimer) clearTimeout(this.idleTimer);
241
+ this.idleTimer = setTimeout(() => {
242
+ this.idleTimer = null;
243
+ const child = this.child;
244
+ if (!child || this.pending) return;
245
+ this.child = null;
246
+ this.outputBuffer = "";
247
+ child.stdin.end();
248
+ const force = setTimeout(() => child.kill("SIGKILL"), 1e3);
249
+ force.unref();
250
+ child.once("exit", () => clearTimeout(force));
251
+ }, this.idleShutdownMs);
252
+ this.idleTimer.unref();
253
+ }
254
+ failChild(child, error) {
255
+ if (this.child !== child) return;
256
+ this.child = null;
257
+ this.outputBuffer = "";
258
+ if (this.idleTimer) {
259
+ clearTimeout(this.idleTimer);
260
+ this.idleTimer = null;
261
+ }
262
+ const pending = this.pending;
263
+ this.pending = null;
264
+ if (pending) {
265
+ clearTimeout(pending.timer);
266
+ pending.reject(error);
267
+ }
268
+ child.kill("SIGKILL");
269
+ }
270
+ acceptLine(child, line) {
271
+ const pending = this.pending;
272
+ if (!pending || !line || line.length > 4096) {
273
+ this.failChild(child, new Error("Windows private ACL broker returned malformed output."));
274
+ return;
275
+ }
276
+ let response;
277
+ try {
278
+ const parsed = JSON.parse(line);
279
+ const status = String(parsed.status);
280
+ const expectedKeys = status === "error" ? "error_code\0id\0status" : "id\0status";
281
+ if (Object.keys(parsed).sort().join("\0") !== expectedKeys || parsed.id !== pending.id || !["ok", "missing", "error"].includes(status) || status === "error" && ![
282
+ "request_validation",
283
+ "path_lookup",
284
+ "principal_resolution",
285
+ "acl_read",
286
+ "owner_validation",
287
+ "acl_mutation",
288
+ "acl_write",
289
+ "acl_readback",
290
+ "acl_verification"
291
+ ].includes(String(parsed.error_code))) throw new Error("invalid response");
292
+ response = parsed;
293
+ } catch {
294
+ this.failChild(child, new Error("Windows private ACL broker returned malformed output."));
295
+ return;
296
+ }
297
+ this.pending = null;
298
+ clearTimeout(pending.timer);
299
+ if (response.status === "ok") {
300
+ pending.resolve();
301
+ } else if (response.status === "missing") {
302
+ const error = new Error("Windows private path no longer exists.");
303
+ error.code = "ENOENT";
304
+ pending.reject(error);
305
+ } else {
306
+ pending.reject(new Error(
307
+ `Windows private ACL ${pending.mode} failed (${response.error_code}).`
308
+ ));
309
+ }
310
+ this.scheduleIdleShutdown();
311
+ }
312
+ ensureChild() {
313
+ if (this.child && this.child.exitCode === null && !this.child.killed) {
314
+ return { child: this.child, startedNow: false };
315
+ }
316
+ const child = this.spawnProcess();
317
+ this.child = child;
318
+ this.outputBuffer = "";
319
+ child.stdout.setEncoding("utf8");
320
+ child.stdout.on("data", (chunk) => {
321
+ if (this.child !== child) return;
322
+ this.outputBuffer += chunk;
323
+ if (this.outputBuffer.length > 65536) {
324
+ this.failChild(child, new Error("Windows private ACL broker exceeded its output limit."));
325
+ return;
326
+ }
327
+ while (this.child === child) {
328
+ const newline = this.outputBuffer.indexOf("\n");
329
+ if (newline < 0) break;
330
+ const line = this.outputBuffer.slice(0, newline).trim();
331
+ this.outputBuffer = this.outputBuffer.slice(newline + 1);
332
+ this.acceptLine(child, line);
333
+ }
334
+ });
335
+ child.stderr.on("data", () => void 0);
336
+ child.once("error", () => {
337
+ this.failChild(child, new Error("Windows private ACL broker failed to start."));
338
+ });
339
+ child.once("exit", () => {
340
+ this.failChild(child, new Error("Windows private ACL broker exited before confirmation."));
341
+ });
342
+ child.unref();
343
+ for (const stream of [child.stdin, child.stdout, child.stderr]) {
344
+ stream.unref?.();
345
+ }
346
+ return { child, startedNow: true };
347
+ }
348
+ async dispatch(path, kind, mode) {
349
+ if (this.idleTimer) {
350
+ clearTimeout(this.idleTimer);
351
+ this.idleTimer = null;
352
+ }
353
+ const id = ++this.requestSequence;
354
+ const request = `${JSON.stringify({
355
+ id,
356
+ kind,
357
+ mode,
358
+ path_b64: Buffer.from(path, "utf8").toString("base64")
359
+ })}
360
+ `;
361
+ if (Buffer.byteLength(request, "utf8") > 65536) {
362
+ throw new Error("Windows private ACL broker request exceeds its input limit.");
363
+ }
364
+ const { child, startedNow } = this.ensureChild();
365
+ const timeoutMs = startedNow ? this.startupRequestTimeoutMs : this.requestTimeoutMs;
366
+ await new Promise((resolvePromise, reject) => {
367
+ const timer = setTimeout(() => {
368
+ this.failChild(child, new Error("Windows private ACL broker request timed out."));
369
+ }, timeoutMs);
370
+ this.pending = { id, mode, resolve: resolvePromise, reject, timer };
371
+ child.stdin.write(request, "utf8", (error) => {
372
+ if (error) {
373
+ this.failChild(child, new Error("Windows private ACL broker request failed."));
374
+ }
375
+ });
376
+ });
377
+ }
378
+ close() {
379
+ if (this.idleTimer) clearTimeout(this.idleTimer);
380
+ this.idleTimer = null;
381
+ const child = this.child;
382
+ this.child = null;
383
+ this.outputBuffer = "";
384
+ if (child) child.stdin.end();
385
+ }
386
+ };
387
+ var defaultWindowsPrivateAclBroker = new WindowsPrivateAclBroker();
388
+ var runWindowsPrivateAcl = async (path, kind, mode) => await defaultWindowsPrivateAclBroker.run(path, kind, mode);
389
+ var windowsAclCache = /* @__PURE__ */ new Map();
390
+ var windowsAclIdentity = async (path) => {
391
+ const metadata = await lstat(path, { bigint: true });
392
+ return {
393
+ dev: metadata.dev,
394
+ ino: metadata.ino,
395
+ ctimeNs: metadata.ctimeNs,
396
+ mtimeNs: metadata.mtimeNs,
397
+ mode: metadata.mode,
398
+ size: metadata.size
399
+ };
400
+ };
401
+ var aclCacheKey = (path, kind, mode) => `${kind}:${mode}:${resolve(path)}`;
402
+ var secureWindowsPrivatePath = async (path, kind, mode, platform = process.platform, runner = runWindowsPrivateAcl) => {
403
+ if (platform !== "win32") return;
404
+ const key = aclCacheKey(path, kind, mode);
405
+ const before = await windowsAclIdentity(path);
406
+ const cached = windowsAclCache.get(key);
407
+ if (cached && cached.dev === before.dev && cached.ino === before.ino && cached.ctimeNs === before.ctimeNs && cached.mtimeNs === before.mtimeNs && cached.mode === before.mode && cached.size === before.size) return;
408
+ await runner(path, kind, mode);
409
+ windowsAclCache.set(key, await windowsAclIdentity(path));
410
+ };
411
+ var invalidateWindowsAclCache = (path) => {
412
+ for (const kind of ["file", "directory"]) {
413
+ for (const mode of ["harden", "verify", "verify-owner"]) {
414
+ windowsAclCache.delete(aclCacheKey(path, kind, mode));
415
+ }
416
+ }
417
+ };
418
+ var rebindHardenedWindowsAclAfterRename = async (source, destination, kind, expected) => {
419
+ const resolvedSource = resolve(source);
420
+ const resolvedDestination = resolve(destination);
421
+ if (resolvedSource === resolvedDestination || dirname(resolvedSource) !== dirname(resolvedDestination)) {
422
+ throw new Error("Windows private ACL cache rename boundary is invalid.");
423
+ }
424
+ const published = await windowsAclIdentity(destination);
425
+ if (published.dev !== expected.dev || published.ino !== expected.ino || published.mode !== expected.mode || published.mtimeNs !== expected.mtimeNs || published.size !== expected.size) {
426
+ invalidateWindowsAclCache(source);
427
+ invalidateWindowsAclCache(destination);
428
+ throw new Error("Windows private file identity changed during atomic publication.");
429
+ }
430
+ invalidateWindowsAclCache(source);
431
+ invalidateWindowsAclCache(destination);
432
+ for (const mode of ["harden", "verify", "verify-owner"]) {
433
+ windowsAclCache.set(aclCacheKey(destination, kind, mode), published);
434
+ }
435
+ };
436
+ var rebindHardenedWindowsDirectoryAfterOwnedMutation = async (path, expected) => {
437
+ const current = await windowsAclIdentity(path);
438
+ if (current.dev !== expected.dev || current.ino !== expected.ino || current.mode !== expected.mode) {
439
+ invalidateWindowsAclCache(path);
440
+ throw new Error("Windows private directory identity changed during atomic publication.");
441
+ }
442
+ invalidateWindowsAclCache(path);
443
+ for (const mode of ["harden", "verify", "verify-owner"]) {
444
+ windowsAclCache.set(aclCacheKey(path, "directory", mode), current);
445
+ }
446
+ };
447
+ var isDefaultWindowsPrivatePath = (path, root = resolve(homedir(), ".vtx", "inference-host")) => {
448
+ const child = relative(root, resolve(path));
449
+ return child === "" || !child.startsWith("..") && !child.includes(":");
450
+ };
451
+ var secureExistingWindowsPath = async (path, kind, platform = process.platform, runner = runWindowsPrivateAcl, defaultRoot = resolve(homedir(), ".vtx", "inference-host")) => {
452
+ if (platform !== "win32") return;
453
+ if (!isDefaultWindowsPrivatePath(path, defaultRoot)) {
454
+ await secureWindowsPrivatePath(path, kind, "verify", platform, runner);
455
+ return;
456
+ }
457
+ await secureWindowsPrivatePath(path, kind, "harden", platform, runner);
458
+ };
459
+ var linuxProcessIdentity = async (pid) => {
460
+ try {
461
+ const [bootId, statLine] = await Promise.all([
462
+ readFile("/proc/sys/kernel/random/boot_id", "utf8"),
463
+ readFile(`/proc/${pid}/stat`, "utf8")
464
+ ]);
465
+ const fields = statLine.slice(statLine.lastIndexOf(")") + 2).trim().split(/\s+/u);
466
+ const startTicks = fields[19];
467
+ return startTicks ? `linux:${bootId.trim()}:${startTicks}` : null;
468
+ } catch {
469
+ return null;
470
+ }
471
+ };
472
+ var windowsProcessIdentityInvocation = (pid) => {
473
+ const script = `$ErrorActionPreference='Stop';$p=[Diagnostics.Process]::GetProcessById([int]$env:VTX_PROCESS_PID);[Console]::Out.Write($p.StartTime.ToUniversalTime().ToFileTimeUtc())`;
474
+ return {
475
+ args: [
476
+ "-NoLogo",
477
+ "-NoProfile",
478
+ "-NonInteractive",
479
+ "-EncodedCommand",
480
+ Buffer.from(script, "utf16le").toString("base64")
481
+ ],
482
+ env: windowsPowerShellEnvironment({ VTX_PROCESS_PID: String(pid) }),
483
+ timeoutMs: WINDOWS_IDENTITY_COMMAND_TIMEOUT_MS
484
+ };
485
+ };
486
+ var windowsBootIdentityInvocation = () => {
487
+ const script = `$ErrorActionPreference='Stop';$s=[System.Management.ManagementObjectSearcher]::new('SELECT LastBootUpTime FROM Win32_OperatingSystem');try{$c=$s.Get();$e=$c.GetEnumerator();if(-not $e.MoveNext()){throw 'boot identity unavailable'};$raw=[string]$e.Current['LastBootUpTime'];$v=[System.Management.ManagementDateTimeConverter]::ToDateTime($raw).ToUniversalTime().ToFileTimeUtc();[Console]::Out.Write($v)}finally{if($c){$c.Dispose()};$s.Dispose()}`;
488
+ return {
489
+ args: [
490
+ "-NoLogo",
491
+ "-NoProfile",
492
+ "-NonInteractive",
493
+ "-EncodedCommand",
494
+ Buffer.from(script, "utf16le").toString("base64")
495
+ ],
496
+ env: windowsPowerShellEnvironment(),
497
+ timeoutMs: WINDOWS_IDENTITY_COMMAND_TIMEOUT_MS
498
+ };
499
+ };
500
+ var windowsProcessIdentity = async (pid) => await new Promise((resolvePromise) => {
501
+ const invocation = windowsProcessIdentityInvocation(pid);
502
+ const child = spawn("powershell.exe", [...invocation.args], {
503
+ windowsHide: true,
504
+ stdio: ["ignore", "pipe", "ignore"],
505
+ env: invocation.env
506
+ });
507
+ const output = [];
508
+ let settled = false;
509
+ const settle = (value) => {
510
+ if (settled) return;
511
+ settled = true;
512
+ clearTimeout(timer);
513
+ resolvePromise(value);
514
+ };
515
+ const timer = setTimeout(() => {
516
+ child.kill("SIGKILL");
517
+ settle(null);
518
+ }, invocation.timeoutMs);
519
+ child.stdout.on("data", (chunk) => {
520
+ if (output.reduce((total, item) => total + item.byteLength, 0) + Buffer.byteLength(chunk) > 1024) {
521
+ child.kill("SIGKILL");
522
+ settle(null);
523
+ return;
524
+ }
525
+ output.push(Buffer.from(chunk));
526
+ });
527
+ child.once("error", () => settle(null));
528
+ child.once("exit", (code) => {
529
+ const started = Buffer.concat(output).toString("utf8").trim();
530
+ settle(code === 0 && /^\d+$/u.test(started) ? `win32:${started}` : null);
531
+ });
532
+ });
533
+ var darwinProcessIdentity = async (pid) => await new Promise((resolvePromise) => {
534
+ const child = spawn("ps", ["-p", String(pid), "-o", "lstart="], {
535
+ stdio: ["ignore", "pipe", "ignore"]
536
+ });
537
+ const output = [];
538
+ let settled = false;
539
+ const settle = (value) => {
540
+ if (settled) return;
541
+ settled = true;
542
+ clearTimeout(timer);
543
+ resolvePromise(value);
544
+ };
545
+ const timer = setTimeout(() => {
546
+ child.kill("SIGKILL");
547
+ settle(null);
548
+ }, 5e3);
549
+ child.stdout.on("data", (chunk) => output.push(Buffer.from(chunk)));
550
+ child.once("error", () => settle(null));
551
+ child.once("exit", (code) => {
552
+ const started = Date.parse(Buffer.concat(output).toString("utf8").trim());
553
+ settle(code === 0 && Number.isFinite(started) ? `darwin:${Math.floor(started / 1e3)}` : null);
554
+ });
555
+ });
556
+ var runSmallIdentityCommand = async (command, args, env, timeoutMs = SMALL_IDENTITY_COMMAND_TIMEOUT_MS) => await new Promise((resolvePromise) => {
557
+ const child = spawn(command, [...args], {
558
+ windowsHide: true,
559
+ stdio: ["ignore", "pipe", "ignore"],
560
+ env
561
+ });
562
+ const output = [];
563
+ let bytes = 0;
564
+ let settled = false;
565
+ const settle = (value) => {
566
+ if (settled) return;
567
+ settled = true;
568
+ clearTimeout(timer);
569
+ resolvePromise(value);
570
+ };
571
+ const timer = setTimeout(() => {
572
+ child.kill("SIGKILL");
573
+ settle(null);
574
+ }, timeoutMs);
575
+ child.stdout.on("data", (chunk) => {
576
+ bytes += Buffer.byteLength(chunk);
577
+ if (bytes > 4096) {
578
+ child.kill("SIGKILL");
579
+ settle(null);
580
+ return;
581
+ }
582
+ output.push(Buffer.from(chunk));
583
+ });
584
+ child.once("error", () => settle(null));
585
+ child.once("exit", (code) => settle(
586
+ code === 0 ? Buffer.concat(output).toString("utf8").trim() || null : null
587
+ ));
588
+ });
589
+ var cachedSystemBootIdentity = null;
590
+ var readInferenceSystemBootIdentity = async (platform = process.platform) => {
591
+ if (platform === process.platform && cachedSystemBootIdentity) {
592
+ return await cachedSystemBootIdentity;
593
+ }
594
+ const read = async () => {
595
+ let identity = null;
596
+ if (platform === "linux") {
597
+ try {
598
+ identity = (await readFile("/proc/sys/kernel/random/boot_id", "utf8")).trim();
599
+ } catch {
600
+ identity = null;
601
+ }
602
+ } else if (platform === "win32") {
603
+ const invocation = windowsBootIdentityInvocation();
604
+ identity = await runSmallIdentityCommand(
605
+ "powershell.exe",
606
+ invocation.args,
607
+ invocation.env,
608
+ invocation.timeoutMs
609
+ );
610
+ } else if (platform === "darwin") {
611
+ identity = await runSmallIdentityCommand("sysctl", ["-n", "kern.boottime"], void 0);
612
+ }
613
+ if (!identity || /[\r\n\0]/u.test(identity)) {
614
+ throw new Error("Inference host could not establish the current system boot identity.");
615
+ }
616
+ return `${platform}:${identity}`;
617
+ };
618
+ const pending = read();
619
+ if (platform === process.platform) cachedSystemBootIdentity = pending;
620
+ try {
621
+ return await pending;
622
+ } catch (error) {
623
+ if (platform === process.platform) cachedSystemBootIdentity = null;
624
+ throw error;
625
+ }
626
+ };
627
+ var defaultProcessIdentity = async (pid) => {
628
+ if (process.platform === "linux") return await linuxProcessIdentity(pid);
629
+ if (process.platform === "win32") return await windowsProcessIdentity(pid);
630
+ if (process.platform === "darwin") return await darwinProcessIdentity(pid);
631
+ return null;
632
+ };
633
+ var defaultCurrentProcessIdentity = async () => {
634
+ const identity = await defaultProcessIdentity(process.pid);
635
+ if (!identity) throw new Error("Inference host could not establish its process-start identity.");
636
+ return identity;
637
+ };
638
+ var processLockObservationCache = /* @__PURE__ */ new Map();
639
+ var inferenceProcessIdentitiesMatch = (stored, observed) => stored === observed;
640
+ async function ensureInferencePrivateDirectory(path, dependencies = {}) {
641
+ const platform = dependencies.platform ?? process.platform;
642
+ const runner = dependencies.runner ?? runWindowsPrivateAcl;
643
+ const defaultRoot = dependencies.defaultRoot ?? resolve(homedir(), ".vtx", "inference-host");
644
+ let created = false;
645
+ try {
646
+ const before = await lstat(path);
647
+ if (before.isSymbolicLink() || !before.isDirectory()) {
648
+ throw new Error("Inference host state directory is unsafe.");
649
+ }
650
+ } catch (error) {
651
+ if (error.code !== "ENOENT") throw error;
652
+ await mkdir(path, { recursive: true, mode: 448 });
653
+ created = true;
654
+ }
655
+ const after = await lstat(path);
656
+ if (after.isSymbolicLink() || !after.isDirectory()) {
657
+ throw new Error("Inference host state directory is unsafe.");
658
+ }
659
+ if (platform === "win32") {
660
+ if (created) {
661
+ await secureWindowsPrivatePath(path, "directory", "harden", platform, runner);
662
+ } else {
663
+ await secureExistingWindowsPath(
664
+ path,
665
+ "directory",
666
+ platform,
667
+ runner,
668
+ defaultRoot
669
+ );
670
+ }
671
+ return;
672
+ }
673
+ if ((after.mode & 63) !== 0) {
674
+ throw new Error("Inference host state directory must have mode 0700.");
675
+ }
676
+ if (typeof process.getuid === "function" && after.uid !== process.getuid()) {
677
+ throw new Error("Inference host state directory must be owned by the current user.");
678
+ }
679
+ const canonical = await realpath(path);
680
+ if (canonical !== resolve(path)) {
681
+ throw new Error("Inference host state directory may not traverse symbolic links.");
682
+ }
683
+ }
684
+ async function syncInferenceDirectory(path, platform = process.platform) {
685
+ if (platform === "win32") return;
686
+ const handle = await open(path, constants.O_RDONLY | constants.O_DIRECTORY);
687
+ try {
688
+ await handle.sync();
689
+ } finally {
690
+ await handle.close();
691
+ }
692
+ }
693
+ var WINDOWS_PRIVATE_FILE_REPLACE_ERROR_CODES = /* @__PURE__ */ new Set([
694
+ "EACCES",
695
+ "EBUSY",
696
+ "EEXIST",
697
+ "ENOTEMPTY",
698
+ "EPERM"
699
+ ]);
700
+ async function replaceAtomicInferencePrivateFile(temporaryPath, destinationPath, options = {}) {
701
+ const platform = options.platform ?? process.platform;
702
+ const renameFile = options.renameFile ?? rename;
703
+ const sleep = options.sleep ?? ((milliseconds) => new Promise((resolve3) => setTimeout(resolve3, milliseconds)));
704
+ const maxAttempts = Math.max(1, options.maxAttempts ?? 40);
705
+ const retryDelayMs = Math.max(0, options.retryDelayMs ?? 25);
706
+ for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
707
+ try {
708
+ await renameFile(temporaryPath, destinationPath);
709
+ return;
710
+ } catch (error) {
711
+ const code = String(error.code ?? "");
712
+ if (platform !== "win32" || !WINDOWS_PRIVATE_FILE_REPLACE_ERROR_CODES.has(code) || attempt === maxAttempts - 1) {
713
+ throw error;
714
+ }
715
+ await sleep(retryDelayMs);
716
+ }
717
+ }
718
+ }
719
+ async function writeAtomicInferencePrivateFile(path, contents, dependencies = {}) {
720
+ const platform = dependencies.platform ?? process.platform;
721
+ const runner = dependencies.runner ?? runWindowsPrivateAcl;
722
+ const defaultRoot = dependencies.defaultRoot ?? resolve(homedir(), ".vtx", "inference-host");
723
+ const directory = dirname(path);
724
+ await ensureInferencePrivateDirectory(directory, dependencies);
725
+ const hardenedDirectoryIdentity = platform === "win32" && isDefaultWindowsPrivatePath(directory, defaultRoot) ? windowsAclCache.get(aclCacheKey(directory, "directory", "harden")) : void 0;
726
+ if (platform === "win32" && isDefaultWindowsPrivatePath(directory, defaultRoot) && !hardenedDirectoryIdentity) {
727
+ throw new Error("Windows private directory ACL hardening was not durably verified.");
728
+ }
729
+ const temporary = join(
730
+ directory,
731
+ `.${process.pid}.${randomBytes(12).toString("hex")}.tmp`
732
+ );
733
+ const handle = await open(
734
+ temporary,
735
+ constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY | constants.O_NOFOLLOW,
736
+ 384
737
+ );
738
+ try {
739
+ await handle.writeFile(contents, "utf8");
740
+ await handle.sync();
741
+ } catch (error) {
742
+ await handle.close().catch(() => void 0);
743
+ await rm(temporary, { force: true }).catch(() => void 0);
744
+ throw error;
745
+ }
746
+ await handle.close();
747
+ await secureWindowsPrivatePath(temporary, "file", "harden", platform, runner);
748
+ const hardenedIdentity = platform === "win32" ? windowsAclCache.get(aclCacheKey(temporary, "file", "harden")) : void 0;
749
+ if (platform === "win32" && !hardenedIdentity) {
750
+ await rm(temporary, { force: true }).catch(() => void 0);
751
+ throw new Error("Windows private ACL hardening was not durably verified.");
752
+ }
753
+ try {
754
+ invalidateWindowsAclCache(path);
755
+ await replaceAtomicInferencePrivateFile(temporary, path, {
756
+ platform,
757
+ renameFile: dependencies.renameFile,
758
+ sleep: dependencies.sleep,
759
+ maxAttempts: dependencies.replaceMaxAttempts,
760
+ retryDelayMs: dependencies.replaceRetryDelayMs
761
+ });
762
+ if (platform === "win32" && hardenedIdentity) {
763
+ await rebindHardenedWindowsAclAfterRename(
764
+ temporary,
765
+ path,
766
+ "file",
767
+ hardenedIdentity
768
+ );
769
+ } else {
770
+ invalidateWindowsAclCache(temporary);
771
+ }
772
+ await syncInferenceDirectory(directory, platform);
773
+ if (platform === "win32" && hardenedDirectoryIdentity) {
774
+ await rebindHardenedWindowsDirectoryAfterOwnedMutation(
775
+ directory,
776
+ hardenedDirectoryIdentity
777
+ );
778
+ }
779
+ } catch (error) {
780
+ await rm(temporary, { force: true }).catch(() => void 0);
781
+ invalidateWindowsAclCache(temporary);
782
+ throw error;
783
+ }
784
+ }
785
+ async function acquireInferenceHostProcessLock(path, dependencies = {}) {
786
+ const directory = dirname(path);
787
+ await ensureInferencePrivateDirectory(directory);
788
+ const ownerToken = randomBytes(24).toString("base64url");
789
+ const observeIdentity = dependencies.processIdentity ?? defaultProcessIdentity;
790
+ const currentBootIdentity = dependencies.currentBootIdentity ?? (() => readInferenceSystemBootIdentity());
791
+ const isProcessAlive = dependencies.processAlive ?? ((pid) => {
792
+ try {
793
+ process.kill(pid, 0);
794
+ return true;
795
+ } catch (error) {
796
+ if (error.code === "ESRCH") return false;
797
+ throw error;
798
+ }
799
+ });
800
+ let handle;
801
+ for (let acquisition = 0; acquisition < 2; acquisition += 1) {
802
+ try {
803
+ handle = await open(
804
+ path,
805
+ constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY | constants.O_NOFOLLOW,
806
+ 384
807
+ );
808
+ break;
809
+ } catch (error) {
810
+ if (error.code !== "EEXIST") throw error;
811
+ if (acquisition > 0) {
812
+ throw new Error("Another inference host process already owns this local host.");
813
+ }
814
+ let before;
815
+ try {
816
+ before = await lstat(path);
817
+ } catch (error2) {
818
+ if (error2.code === "ENOENT") continue;
819
+ throw error2;
820
+ }
821
+ if (before.isSymbolicLink() || !before.isFile() || process.platform !== "win32" && (before.mode & 63) !== 0 || typeof process.getuid === "function" && before.uid !== process.getuid()) {
822
+ throw new Error("Inference host process lock is unsafe.");
823
+ }
824
+ const reclaimPublicationResidue = async () => {
825
+ let current2;
826
+ try {
827
+ current2 = await lstat(path);
828
+ } catch (error2) {
829
+ if (error2.code === "ENOENT") return false;
830
+ throw error2;
831
+ }
832
+ if (current2.isSymbolicLink() || !current2.isFile() || current2.dev !== before.dev || current2.ino !== before.ino || process.platform !== "win32" && (current2.mode & 63) !== 0 || typeof process.getuid === "function" && current2.uid !== process.getuid()) {
833
+ throw new Error("Inference host process lock publication residue changed or is unsafe.");
834
+ }
835
+ try {
836
+ await rm(path);
837
+ } catch (error2) {
838
+ if (error2.code === "ENOENT") return false;
839
+ throw error2;
840
+ }
841
+ processLockObservationCache.delete(resolve(path));
842
+ await syncInferenceDirectory(directory);
843
+ return true;
844
+ };
845
+ try {
846
+ await secureExistingWindowsPath(path, "file");
847
+ } catch (error2) {
848
+ if (error2.code === "ENOENT") continue;
849
+ throw error2;
850
+ }
851
+ let staleOwner;
852
+ try {
853
+ staleOwner = JSON.parse(await readFile(path, "utf8"));
854
+ } catch (error2) {
855
+ if (error2.code === "ENOENT") continue;
856
+ if (Date.now() - before.mtimeMs < 1e4) {
857
+ throw new Error("Another inference host process already owns this local host.");
858
+ }
859
+ await reclaimPublicationResidue();
860
+ continue;
861
+ }
862
+ if (staleOwner.schema_version !== 2 || !Number.isSafeInteger(staleOwner.pid) || Number(staleOwner.pid) < 1 || typeof staleOwner.owner_token !== "string" || !staleOwner.owner_token || typeof staleOwner.process_identity !== "string" || !staleOwner.process_identity || typeof staleOwner.boot_identity !== "string" || !staleOwner.boot_identity) {
863
+ if (Date.now() - before.mtimeMs < 1e4) {
864
+ throw new Error("Another inference host process already owns this local host.");
865
+ }
866
+ await reclaimPublicationResidue();
867
+ continue;
868
+ }
869
+ const stalePid = Number(staleOwner.pid);
870
+ const bootIdentity2 = await currentBootIdentity();
871
+ if (bootIdentity2 === staleOwner.boot_identity && isProcessAlive(stalePid)) {
872
+ const cached = processLockObservationCache.get(resolve(path));
873
+ const observedIdentity = cached && cached.dev === before.dev && cached.ino === before.ino && cached.pid === stalePid && cached.storedIdentity === staleOwner.process_identity && Date.now() - cached.observedAtMs < 5e3 ? cached.observedIdentity : await observeIdentity(stalePid);
874
+ if (!observedIdentity) {
875
+ throw new Error("Inference host could not verify the existing lock owner identity.");
876
+ }
877
+ processLockObservationCache.set(resolve(path), {
878
+ dev: before.dev,
879
+ ino: before.ino,
880
+ pid: stalePid,
881
+ storedIdentity: staleOwner.process_identity,
882
+ observedIdentity,
883
+ observedAtMs: Date.now()
884
+ });
885
+ if (inferenceProcessIdentitiesMatch(staleOwner.process_identity, observedIdentity)) {
886
+ throw new Error("Another inference host process already owns this local host.");
887
+ }
888
+ }
889
+ let current;
890
+ try {
891
+ current = await lstat(path);
892
+ } catch (error2) {
893
+ if (error2.code === "ENOENT") continue;
894
+ throw error2;
895
+ }
896
+ if (current.dev !== before.dev || current.ino !== before.ino) {
897
+ throw new Error("Inference host process lock ownership changed.");
898
+ }
899
+ await rm(path);
900
+ processLockObservationCache.delete(resolve(path));
901
+ await syncInferenceDirectory(directory);
902
+ }
903
+ }
904
+ if (!handle) throw new Error("Inference host process lock could not be acquired.");
905
+ let ownerIdentity;
906
+ let bootIdentity;
907
+ try {
908
+ [ownerIdentity, bootIdentity] = await Promise.all([
909
+ (dependencies.currentProcessIdentity ?? defaultCurrentProcessIdentity)(),
910
+ currentBootIdentity()
911
+ ]);
912
+ } catch (error) {
913
+ await handle.close().catch(() => void 0);
914
+ await rm(path, { force: true }).catch(() => void 0);
915
+ throw error;
916
+ }
917
+ await handle.writeFile(
918
+ `${JSON.stringify({
919
+ schema_version: 2,
920
+ pid: process.pid,
921
+ owner_token: ownerToken,
922
+ process_identity: ownerIdentity,
923
+ boot_identity: bootIdentity
924
+ })}
925
+ `,
926
+ "utf8"
927
+ );
928
+ await handle.sync();
929
+ await handle.close();
930
+ await secureWindowsPrivatePath(path, "file", "harden");
931
+ await syncInferenceDirectory(directory);
932
+ let released = false;
933
+ return {
934
+ path,
935
+ ownerToken,
936
+ release: async () => {
937
+ if (released) return;
938
+ const metadata = await lstat(path);
939
+ if (metadata.isSymbolicLink() || !metadata.isFile()) {
940
+ throw new Error("Inference host process lock is unsafe.");
941
+ }
942
+ const parsed = JSON.parse(await readFile(path, "utf8"));
943
+ if (parsed.owner_token !== ownerToken) {
944
+ throw new Error("Inference host process lock ownership changed.");
945
+ }
946
+ await rm(path);
947
+ processLockObservationCache.delete(resolve(path));
948
+ await syncInferenceDirectory(directory);
949
+ released = true;
950
+ }
951
+ };
952
+ }
953
+
954
+ // lib/inference-host/service-bootstrap.ts
955
+ var OFFICIAL_NPM_REGISTRY = "https://registry.npmjs.org";
956
+ var PACKAGE_NAME = "@vtxmacro/cli";
957
+ var UPDATE_ATTEMPTS = 3;
958
+ var UPDATE_RETRY_MS = 2e3;
959
+ var CANDIDATE_READINESS_TIMEOUT_MS = 10 * 60 * 1e3;
960
+ var SERVICE_DRAIN_COMMAND = "vtx-inference-host-service-drain-v1";
961
+ var safePath = (value, label) => {
962
+ if (typeof value !== "string" || !value || /[\r\n\0]/u.test(value)) {
963
+ throw new Error(`Inference-host bootstrap ${label} is invalid.`);
964
+ }
965
+ return resolve2(value);
966
+ };
967
+ var parseManifest = (value) => {
968
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
969
+ throw new Error("Inference-host bootstrap manifest is invalid.");
970
+ }
971
+ const record = value;
972
+ if (!["vtx_inference_service_v1", "vtx_inference_service_v2", "vtx_inference_service_v3"].includes(String(record.schema_version))) {
973
+ throw new Error("Inference-host bootstrap manifest version is unsupported.");
974
+ }
975
+ return {
976
+ generation: typeof record.generation === "string" && record.generation ? record.generation : `legacy:${String(record.installed_at ?? "")}`,
977
+ executable: safePath(record.executable, "executable"),
978
+ script: safePath(record.script, "script"),
979
+ log_path: safePath(record.log_path, "log path"),
980
+ worker_names: Array.isArray(record.workers) ? record.workers.map((worker) => {
981
+ if (!worker || typeof worker !== "object" || Array.isArray(worker)) {
982
+ throw new Error("Inference-host bootstrap worker is invalid.");
983
+ }
984
+ const instanceName = worker.instance_name;
985
+ if (typeof instanceName !== "string" || !instanceName) {
986
+ throw new Error("Inference-host bootstrap worker is invalid.");
987
+ }
988
+ return instanceName;
989
+ }).sort() : ["default"]
990
+ };
991
+ };
992
+ var serviceSiblingPath = (manifestPath, suffix) => {
993
+ if (!manifestPath.endsWith(".service.json")) {
994
+ throw new Error("Inference-host bootstrap manifest path is invalid.");
995
+ }
996
+ return `${manifestPath.slice(0, -".service.json".length)}${suffix}`;
997
+ };
998
+ var desiredPathFor = (manifestPath) => serviceSiblingPath(manifestPath, ".service-desired.json");
999
+ var selectionPathFor = (manifestPath) => serviceSiblingPath(manifestPath, ".service-release.json");
1000
+ var releasesPathFor = (manifestPath) => serviceSiblingPath(manifestPath, ".service-releases");
1001
+ var rejectionPathFor = (manifestPath) => serviceSiblingPath(manifestPath, ".service-release-rejection.json");
1002
+ var runtimePathFor = (manifestPath) => serviceSiblingPath(manifestPath, ".service-runtime.json");
1003
+ var readDesired = async (manifestPath) => {
1004
+ const value = JSON.parse(await readFile2(desiredPathFor(manifestPath), "utf8"));
1005
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
1006
+ throw new Error("Inference-host bootstrap desired state is invalid.");
1007
+ }
1008
+ const record = value;
1009
+ if (record.schema_version !== "vtx_inference_service_desired_v1" || typeof record.desired_running !== "boolean") {
1010
+ throw new Error("Inference-host bootstrap desired state is invalid.");
1011
+ }
1012
+ return record.desired_running;
1013
+ };
1014
+ var parseVersion = (value) => {
1015
+ const match = /^(\d{4})\.(\d{1,2})\.(\d{1,3})$/u.exec(value);
1016
+ if (!match) return null;
1017
+ const values = match.slice(1).map(Number);
1018
+ if (values.some((entry) => !Number.isSafeInteger(entry) || entry < 0)) return null;
1019
+ return values;
1020
+ };
1021
+ var compareInferenceHostReleaseVersions = (left, right) => {
1022
+ const leftParts = parseVersion(left);
1023
+ const rightParts = parseVersion(right);
1024
+ if (!leftParts || !rightParts) {
1025
+ throw new Error("Inference-host release version is invalid.");
1026
+ }
1027
+ for (let index = 0; index < leftParts.length; index += 1) {
1028
+ const difference = leftParts[index] - rightParts[index];
1029
+ if (difference !== 0) return difference;
1030
+ }
1031
+ return 0;
1032
+ };
1033
+ var isPathWithin = (parent, child) => {
1034
+ const childRelative = relative2(resolve2(parent), resolve2(child));
1035
+ return childRelative !== "" && !childRelative.startsWith("..") && !isAbsolute2(childRelative);
1036
+ };
1037
+ var parseSelection = async (manifestPath) => {
1038
+ try {
1039
+ const value = JSON.parse(await readFile2(selectionPathFor(manifestPath), "utf8"));
1040
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
1041
+ const record = value;
1042
+ const script = safePath(record.script, "selected script");
1043
+ if (record.schema_version !== "vtx_inference_service_release_v1" || record.package_name !== PACKAGE_NAME || typeof record.package_version !== "string" || !parseVersion(record.package_version) || typeof record.integrity !== "string" || typeof record.selected_at !== "string" || !Number.isFinite(Date.parse(record.selected_at)) || !isPathWithin(releasesPathFor(manifestPath), script)) return null;
1044
+ await access(script);
1045
+ return record;
1046
+ } catch (error) {
1047
+ if (error.code === "ENOENT") return null;
1048
+ return null;
1049
+ }
1050
+ };
1051
+ var parseRejection = async (manifestPath) => {
1052
+ try {
1053
+ const value = JSON.parse(await readFile2(rejectionPathFor(manifestPath), "utf8"));
1054
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
1055
+ const record = value;
1056
+ if (record.schema_version !== "vtx_inference_service_release_rejection_v1" || typeof record.package_version !== "string" || !parseVersion(record.package_version) || typeof record.rejected_at !== "string" || !Number.isFinite(Date.parse(record.rejected_at)) || typeof record.reason !== "string" || !/^[a-z0-9_]{1,96}$/u.test(record.reason)) return null;
1057
+ return record;
1058
+ } catch {
1059
+ return null;
1060
+ }
1061
+ };
1062
+ var writeRejection = async (manifestPath, rejection) => {
1063
+ await writeAtomicInferencePrivateFile(
1064
+ rejectionPathFor(manifestPath),
1065
+ `${JSON.stringify(rejection, null, 2)}
1066
+ `
1067
+ );
1068
+ };
1069
+ var defaultRunCommand = async (command, args) => await new Promise((resolvePromise) => {
1070
+ const child = spawn2(command, [...args], {
1071
+ windowsHide: true,
1072
+ stdio: ["ignore", "pipe", "pipe"]
1073
+ });
1074
+ const stdout = [];
1075
+ const stderr = [];
1076
+ let settled = false;
1077
+ const settle = (result) => {
1078
+ if (settled) return;
1079
+ settled = true;
1080
+ resolvePromise(result);
1081
+ };
1082
+ child.stdout.on("data", (chunk) => stdout.push(Buffer.from(chunk)));
1083
+ child.stderr.on("data", (chunk) => stderr.push(Buffer.from(chunk)));
1084
+ child.once("error", (error) => settle({ exitCode: 1, stdout: "", stderr: error.message }));
1085
+ child.once("exit", (code) => settle({
1086
+ exitCode: code ?? 1,
1087
+ stdout: Buffer.concat(stdout).toString("utf8"),
1088
+ stderr: Buffer.concat(stderr).toString("utf8")
1089
+ }));
1090
+ });
1091
+ var encodedPowerShell = (script) => [
1092
+ "-NoLogo",
1093
+ "-NoProfile",
1094
+ "-NonInteractive",
1095
+ "-EncodedCommand",
1096
+ Buffer.from(script, "utf16le").toString("base64")
1097
+ ];
1098
+ var runInferenceHostBootstrapNpmCommand = async (executable, args, platform = process.platform, runCommand = defaultRunCommand) => {
1099
+ const npmPath = platform === "win32" ? windowsPath2.join(windowsPath2.dirname(executable), "npm.cmd") : join2(dirname2(executable), "npm");
1100
+ if (platform !== "win32") return await runCommand(npmPath, args);
1101
+ const payload = Buffer.from(JSON.stringify({ command: npmPath, args }), "utf16le").toString("base64");
1102
+ const script = [
1103
+ "$ErrorActionPreference='Stop'",
1104
+ `$payload='${payload}'`,
1105
+ "$request=[Text.Encoding]::Unicode.GetString([Convert]::FromBase64String($payload)) | ConvertFrom-Json",
1106
+ "& ([string]$request.command) @($request.args | ForEach-Object { [string]$_ })",
1107
+ "$code=$LASTEXITCODE",
1108
+ "if($null -eq $code){$code=1}",
1109
+ "exit $code"
1110
+ ].join(";");
1111
+ return await runCommand("powershell.exe", encodedPowerShell(script));
1112
+ };
1113
+ var defaultRunSupervisor = (executable, args) => {
1114
+ const child = spawn2(executable, [...args], {
1115
+ windowsHide: true,
1116
+ env: { ...process.env, VTX_INFERENCE_HOST_SERVICE_CHILD: "1" },
1117
+ stdio: ["pipe", "inherit", "inherit"]
1118
+ });
1119
+ const completion = new Promise((resolvePromise, reject) => {
1120
+ child.once("error", reject);
1121
+ child.once("exit", (code) => resolvePromise(code ?? 1));
1122
+ });
1123
+ child.stdin.on("error", () => {
1124
+ });
1125
+ return {
1126
+ completion,
1127
+ requestDrain: () => {
1128
+ child.stdin.end(`${SERVICE_DRAIN_COMMAND}
1129
+ `);
1130
+ }
1131
+ };
1132
+ };
1133
+ var appendBootstrapLog = async (path, event, fields = {}) => {
1134
+ await mkdir2(dirname2(path), { recursive: true, mode: 448 });
1135
+ await appendFile(
1136
+ path,
1137
+ `${JSON.stringify({ at: (/* @__PURE__ */ new Date()).toISOString(), event, ...fields })}
1138
+ `,
1139
+ { encoding: "utf8", mode: 384 }
1140
+ );
1141
+ };
1142
+ var fetchLatestRelease = async (fetchImpl) => {
1143
+ const response = await fetchImpl(`${OFFICIAL_NPM_REGISTRY}/%40vtxmacro%2Fcli/latest`, {
1144
+ signal: AbortSignal.timeout(1e4)
1145
+ });
1146
+ if (!response.ok) throw new Error("registry_request_failed");
1147
+ const value = await response.json();
1148
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
1149
+ throw new Error("registry_metadata_invalid");
1150
+ }
1151
+ const record = value;
1152
+ const distribution = record.dist;
1153
+ if (record.name !== PACKAGE_NAME || typeof record.version !== "string" || !parseVersion(record.version) || !distribution || typeof distribution !== "object" || Array.isArray(distribution) || typeof distribution.integrity !== "string") throw new Error("registry_metadata_invalid");
1154
+ return {
1155
+ version: record.version,
1156
+ integrity: distribution.integrity
1157
+ };
1158
+ };
1159
+ var verifyIntegrity = async (tarballPath, integrity) => {
1160
+ const candidates = integrity.split(/\s+/u).map((entry) => {
1161
+ const separator = entry.indexOf("-");
1162
+ return separator > 0 ? { algorithm: entry.slice(0, separator), digest: entry.slice(separator + 1) } : null;
1163
+ }).filter((entry) => entry !== null);
1164
+ const supported = ["sha512", "sha384", "sha256"].map((algorithm) => candidates.find((candidate) => candidate.algorithm === algorithm)).find(Boolean);
1165
+ if (!supported) throw new Error("release_integrity_unsupported");
1166
+ const actual = createHash(supported.algorithm).update(await readFile2(tarballPath)).digest("base64");
1167
+ if (actual !== supported.digest) throw new Error("release_integrity_mismatch");
1168
+ };
1169
+ var atomicWriteSelection = async (manifestPath, selection) => {
1170
+ await writeAtomicInferencePrivateFile(
1171
+ selectionPathFor(manifestPath),
1172
+ `${JSON.stringify(selection, null, 2)}
1173
+ `
1174
+ );
1175
+ };
1176
+ var verifyInstalledRelease = async (prefix, targetVersion, executable, platform, runCommand) => {
1177
+ const rootResult = await runInferenceHostBootstrapNpmCommand(
1178
+ executable,
1179
+ ["root", "--global", "--prefix", prefix],
1180
+ platform,
1181
+ runCommand
1182
+ );
1183
+ if (rootResult.exitCode !== 0 || !rootResult.stdout.trim()) {
1184
+ throw new Error("release_install_invalid");
1185
+ }
1186
+ const packagePath = resolve2(rootResult.stdout.trim(), PACKAGE_NAME);
1187
+ if (!isPathWithin(prefix, packagePath)) throw new Error("release_install_invalid");
1188
+ const packageJson = JSON.parse(await readFile2(join2(packagePath, "package.json"), "utf8"));
1189
+ if (!packageJson || typeof packageJson !== "object" || Array.isArray(packageJson)) {
1190
+ throw new Error("release_install_invalid");
1191
+ }
1192
+ const packageRecord = packageJson;
1193
+ const bin = packageRecord.bin;
1194
+ const binPath = bin && typeof bin === "object" && !Array.isArray(bin) ? bin.vtx : null;
1195
+ if (packageRecord.name !== PACKAGE_NAME || packageRecord.version !== targetVersion || typeof binPath !== "string") throw new Error("release_install_invalid");
1196
+ const script = resolve2(packagePath, binPath);
1197
+ if (!isPathWithin(packagePath, script)) throw new Error("release_install_invalid");
1198
+ await access(script);
1199
+ const verified = await runCommand(executable, [script, "--version"]);
1200
+ if (verified.exitCode !== 0 || verified.stdout.trim() !== targetVersion) {
1201
+ throw new Error("release_version_verification_failed");
1202
+ }
1203
+ return script;
1204
+ };
1205
+ var cleanupInterruptedReleaseStaging = async (releasesPath) => {
1206
+ const entries = await readdir(releasesPath, { withFileTypes: true });
1207
+ for (const entry of entries) {
1208
+ if (entry.isDirectory() && /^\.(?:staging|download)-\d{4}\.\d{1,2}\.\d{1,3}-[0-9a-f-]{36}$/u.test(entry.name)) {
1209
+ await rm2(resolve2(releasesPath, entry.name), { recursive: true, force: true });
1210
+ }
1211
+ }
1212
+ };
1213
+ var stageRelease = async (manifestPath, target, executable, platform, runCommand, now) => {
1214
+ const releasesPath = releasesPathFor(manifestPath);
1215
+ const finalPath = join2(releasesPath, target.version);
1216
+ const stagingPath = join2(releasesPath, `.staging-${target.version}-${randomUUID()}`);
1217
+ const downloadPath = join2(releasesPath, `.download-${target.version}-${randomUUID()}`);
1218
+ await mkdir2(releasesPath, { recursive: true, mode: 448 });
1219
+ await cleanupInterruptedReleaseStaging(releasesPath);
1220
+ try {
1221
+ await access(finalPath);
1222
+ const existingScript = await verifyInstalledRelease(
1223
+ finalPath,
1224
+ target.version,
1225
+ executable,
1226
+ platform,
1227
+ runCommand
1228
+ );
1229
+ const existingSelection = {
1230
+ schema_version: "vtx_inference_service_release_v1",
1231
+ package_name: PACKAGE_NAME,
1232
+ package_version: target.version,
1233
+ integrity: target.integrity,
1234
+ script: existingScript,
1235
+ selected_at: now().toISOString()
1236
+ };
1237
+ return existingSelection;
1238
+ } catch (error) {
1239
+ if (error.code !== "ENOENT") throw error;
1240
+ }
1241
+ await mkdir2(stagingPath, { recursive: true, mode: 448 });
1242
+ await mkdir2(downloadPath, { recursive: true, mode: 448 });
1243
+ try {
1244
+ const packed = await runInferenceHostBootstrapNpmCommand(executable, [
1245
+ "pack",
1246
+ `${PACKAGE_NAME}@${target.version}`,
1247
+ "--pack-destination",
1248
+ downloadPath,
1249
+ "--registry",
1250
+ OFFICIAL_NPM_REGISTRY,
1251
+ "--json"
1252
+ ], platform, runCommand);
1253
+ if (packed.exitCode !== 0) throw new Error("release_download_failed");
1254
+ let filename;
1255
+ try {
1256
+ const parsed = JSON.parse(packed.stdout);
1257
+ filename = String(parsed[0]?.filename ?? "");
1258
+ } catch {
1259
+ throw new Error("release_download_invalid");
1260
+ }
1261
+ const tarballPath = resolve2(downloadPath, filename);
1262
+ if (!filename || !isPathWithin(downloadPath, tarballPath)) {
1263
+ throw new Error("release_download_invalid");
1264
+ }
1265
+ await verifyIntegrity(tarballPath, target.integrity);
1266
+ const installed = await runInferenceHostBootstrapNpmCommand(executable, [
1267
+ "install",
1268
+ "--global",
1269
+ "--prefix",
1270
+ stagingPath,
1271
+ tarballPath,
1272
+ "--no-audit",
1273
+ "--no-fund",
1274
+ "--registry",
1275
+ OFFICIAL_NPM_REGISTRY
1276
+ ], platform, runCommand);
1277
+ if (installed.exitCode !== 0) throw new Error("release_install_failed");
1278
+ const stagedScript = await verifyInstalledRelease(
1279
+ stagingPath,
1280
+ target.version,
1281
+ executable,
1282
+ platform,
1283
+ runCommand
1284
+ );
1285
+ try {
1286
+ await rename2(stagingPath, finalPath);
1287
+ } catch (error) {
1288
+ if (error.code !== "EEXIST") throw error;
1289
+ throw new Error("release_path_already_exists");
1290
+ }
1291
+ const finalScript = resolve2(finalPath, relative2(stagingPath, stagedScript));
1292
+ const selection = {
1293
+ schema_version: "vtx_inference_service_release_v1",
1294
+ package_name: PACKAGE_NAME,
1295
+ package_version: target.version,
1296
+ integrity: target.integrity,
1297
+ script: finalScript,
1298
+ selected_at: now().toISOString()
1299
+ };
1300
+ return selection;
1301
+ } finally {
1302
+ await rm2(stagingPath, { recursive: true, force: true }).catch(() => void 0);
1303
+ await rm2(downloadPath, { recursive: true, force: true }).catch(() => void 0);
1304
+ }
1305
+ };
1306
+ var updateSelection = async (manifestPath, manifest, dependencies) => {
1307
+ const active = await parseSelection(manifestPath);
1308
+ let latest = null;
1309
+ let lastError = null;
1310
+ for (let attempt = 0; attempt < UPDATE_ATTEMPTS; attempt += 1) {
1311
+ try {
1312
+ latest = await fetchLatestRelease(dependencies.fetch);
1313
+ break;
1314
+ } catch (error) {
1315
+ lastError = error;
1316
+ if (attempt + 1 < UPDATE_ATTEMPTS) await dependencies.sleep(UPDATE_RETRY_MS);
1317
+ }
1318
+ }
1319
+ if (!latest) throw lastError ?? new Error("registry_request_failed");
1320
+ const installedVersion = active?.package_version ?? agent_cli_release_default.package_version;
1321
+ if (compareInferenceHostReleaseVersions(latest.version, installedVersion) < 0) {
1322
+ return { active, candidate: null };
1323
+ }
1324
+ if (active && latest.version === active.package_version) {
1325
+ return { active, candidate: null };
1326
+ }
1327
+ const rejection = await parseRejection(manifestPath);
1328
+ if (rejection?.package_version === latest.version) return { active, candidate: null };
1329
+ if (!await readDesired(manifestPath)) return { active, candidate: null };
1330
+ return {
1331
+ active,
1332
+ candidate: await stageRelease(
1333
+ manifestPath,
1334
+ latest,
1335
+ manifest.executable,
1336
+ dependencies.platform,
1337
+ dependencies.runCommand,
1338
+ dependencies.now
1339
+ )
1340
+ };
1341
+ };
1342
+ var waitForCandidateReadiness = async (manifestPath, manifest, candidate, signal, sleep, timeoutMs) => {
1343
+ const deadline = Date.now() + timeoutMs;
1344
+ while (!signal.aborted && Date.now() < deadline) {
1345
+ try {
1346
+ const value = JSON.parse(await readFile2(runtimePathFor(manifestPath), "utf8"));
1347
+ if (value && typeof value === "object" && !Array.isArray(value)) {
1348
+ const runtime = value;
1349
+ const workers = Array.isArray(runtime.workers) ? runtime.workers : [];
1350
+ const workerNames = workers.map((worker) => worker && typeof worker === "object" && !Array.isArray(worker) ? String(worker.instance_name ?? "") : "").sort();
1351
+ const everyWorkerRunning = workers.every((worker) => worker && typeof worker === "object" && !Array.isArray(worker) && worker.state === "running");
1352
+ if (runtime.schema_version === "vtx_inference_service_runtime_v1" && runtime.manifest_generation === manifest.generation && typeof runtime.updated_at === "string" && Date.parse(runtime.updated_at) >= Date.parse(candidate.selected_at) && JSON.stringify(workerNames) === JSON.stringify(manifest.worker_names) && everyWorkerRunning) return "ready";
1353
+ }
1354
+ } catch {
1355
+ }
1356
+ await sleep(250);
1357
+ }
1358
+ return signal.aborted ? "aborted" : "timeout";
1359
+ };
1360
+ var prunePrivateReleases = async (manifestPath, keep) => {
1361
+ const releasesPath = releasesPathFor(manifestPath);
1362
+ const keepPaths = new Set(
1363
+ keep.filter((item) => item !== null).map((item) => resolve2(item.script)).filter((script) => isPathWithin(releasesPath, script)).map((script) => resolve2(releasesPath, relative2(releasesPath, script).split(/[\\/]/u)[0]))
1364
+ );
1365
+ let entries;
1366
+ try {
1367
+ entries = await readdir(releasesPath, { withFileTypes: true });
1368
+ } catch (error) {
1369
+ if (error.code === "ENOENT") return;
1370
+ throw error;
1371
+ }
1372
+ for (const entry of entries) {
1373
+ if (!entry.isDirectory() || !parseVersion(entry.name)) continue;
1374
+ const releasePath = resolve2(releasesPath, entry.name);
1375
+ if (!keepPaths.has(releasePath)) {
1376
+ await rm2(releasePath, { recursive: true, force: true });
1377
+ }
1378
+ }
1379
+ };
1380
+ var supervisorArguments = (script, manifestPath) => [
1381
+ script,
1382
+ "inference-host",
1383
+ "service",
1384
+ "run-internal",
1385
+ "--service-manifest",
1386
+ manifestPath
1387
+ ];
1388
+ var runInferenceHostServiceBootstrap = async (manifestPathValue, dependencies = {}, lockPathValue) => {
1389
+ const manifestPath = resolve2(manifestPathValue);
1390
+ const lockPath = safePath(
1391
+ lockPathValue ?? serviceSiblingPath(manifestPath, ".service-bootstrap.lock"),
1392
+ "lock path"
1393
+ );
1394
+ const lock = await (dependencies.acquireProcessLock ?? acquireInferenceHostProcessLock)(lockPath);
1395
+ try {
1396
+ const manifest = parseManifest(JSON.parse(await readFile2(manifestPath, "utf8")));
1397
+ if (!await readDesired(manifestPath)) {
1398
+ await appendBootstrapLog(manifest.log_path, "service_bootstrap_stopped");
1399
+ return 0;
1400
+ }
1401
+ const now = dependencies.now ?? (() => /* @__PURE__ */ new Date());
1402
+ const sleep = dependencies.sleep ?? (async (milliseconds) => {
1403
+ await new Promise((resolvePromise) => setTimeout(resolvePromise, milliseconds));
1404
+ });
1405
+ const runSupervisor = dependencies.runSupervisor ?? defaultRunSupervisor;
1406
+ const selectedBeforeUpdate = await parseSelection(manifestPath);
1407
+ let updatePlan = { active: selectedBeforeUpdate, candidate: null };
1408
+ try {
1409
+ updatePlan = await updateSelection(manifestPath, manifest, {
1410
+ fetch: dependencies.fetch ?? fetch,
1411
+ now,
1412
+ platform: dependencies.platform ?? process.platform,
1413
+ runCommand: dependencies.runCommand ?? defaultRunCommand,
1414
+ sleep
1415
+ });
1416
+ } catch (error) {
1417
+ await appendBootstrapLog(manifest.log_path, "service_update_deferred", {
1418
+ reason: error instanceof Error ? error.message.slice(0, 160) : "unknown"
1419
+ });
1420
+ }
1421
+ if (!await readDesired(manifestPath)) {
1422
+ await appendBootstrapLog(manifest.log_path, "service_bootstrap_stopped");
1423
+ return 0;
1424
+ }
1425
+ const launch = async (selection) => {
1426
+ const script = selection?.script ?? manifest.script;
1427
+ await access(manifest.executable);
1428
+ await access(script);
1429
+ await appendBootstrapLog(manifest.log_path, "service_bootstrap_launch", {
1430
+ package_version: selection?.package_version ?? agent_cli_release_default.package_version
1431
+ });
1432
+ return await runSupervisor(
1433
+ manifest.executable,
1434
+ supervisorArguments(script, manifestPath)
1435
+ ).completion;
1436
+ };
1437
+ if (!updatePlan.candidate) return await launch(updatePlan.active);
1438
+ const candidate = updatePlan.candidate;
1439
+ await appendBootstrapLog(manifest.log_path, "service_release_candidate_started", {
1440
+ package_version: candidate.package_version
1441
+ });
1442
+ let candidateSupervisor = null;
1443
+ let candidateFailure = "candidate_launch_failed";
1444
+ let candidateExitCode = 1;
1445
+ const readinessController = new AbortController();
1446
+ try {
1447
+ candidateSupervisor = runSupervisor(
1448
+ manifest.executable,
1449
+ supervisorArguments(candidate.script, manifestPath)
1450
+ );
1451
+ const first = await Promise.race([
1452
+ candidateSupervisor.completion.then(
1453
+ (exitCode) => ({ kind: "exit", exitCode }),
1454
+ () => ({ kind: "error", exitCode: 1 })
1455
+ ),
1456
+ waitForCandidateReadiness(
1457
+ manifestPath,
1458
+ manifest,
1459
+ candidate,
1460
+ readinessController.signal,
1461
+ sleep,
1462
+ dependencies.readinessTimeoutMs ?? CANDIDATE_READINESS_TIMEOUT_MS
1463
+ ).then((status) => ({ kind: status, exitCode: 1 }))
1464
+ ]);
1465
+ if (first.kind === "ready") {
1466
+ readinessController.abort();
1467
+ await atomicWriteSelection(manifestPath, candidate);
1468
+ await rm2(rejectionPathFor(manifestPath), { force: true }).catch(() => void 0);
1469
+ await prunePrivateReleases(manifestPath, [candidate, updatePlan.active]).catch(
1470
+ async () => await appendBootstrapLog(
1471
+ manifest.log_path,
1472
+ "service_release_cleanup_deferred",
1473
+ { package_version: candidate.package_version }
1474
+ ).catch(() => void 0)
1475
+ );
1476
+ await appendBootstrapLog(manifest.log_path, "service_release_selected", {
1477
+ package_version: candidate.package_version
1478
+ }).catch(() => void 0);
1479
+ return await candidateSupervisor.completion;
1480
+ }
1481
+ if (first.kind === "timeout") {
1482
+ candidateFailure = "candidate_readiness_timeout";
1483
+ candidateSupervisor.requestDrain();
1484
+ candidateExitCode = await candidateSupervisor.completion.catch(() => 1);
1485
+ } else {
1486
+ candidateFailure = first.kind === "error" ? "candidate_launch_failed" : "candidate_exited_before_readiness";
1487
+ candidateExitCode = first.exitCode;
1488
+ }
1489
+ } catch {
1490
+ candidateFailure = "candidate_launch_failed";
1491
+ candidateExitCode = 1;
1492
+ if (candidateSupervisor) {
1493
+ try {
1494
+ candidateSupervisor.requestDrain();
1495
+ } catch {
1496
+ }
1497
+ candidateExitCode = await candidateSupervisor.completion.catch(() => 1);
1498
+ }
1499
+ } finally {
1500
+ readinessController.abort();
1501
+ }
1502
+ if (!await readDesired(manifestPath)) return candidateExitCode;
1503
+ await writeRejection(manifestPath, {
1504
+ schema_version: "vtx_inference_service_release_rejection_v1",
1505
+ package_version: candidate.package_version,
1506
+ rejected_at: now().toISOString(),
1507
+ reason: candidateFailure
1508
+ });
1509
+ await prunePrivateReleases(manifestPath, [updatePlan.active]);
1510
+ await appendBootstrapLog(manifest.log_path, "service_release_rolled_back", {
1511
+ package_version: candidate.package_version,
1512
+ reason: candidateFailure
1513
+ });
1514
+ return await launch(updatePlan.active);
1515
+ } finally {
1516
+ await lock.release();
1517
+ }
1518
+ };
1519
+ var invokedPath = process.argv[1] ? resolve2(process.argv[1]) : "";
1520
+ if (invokedPath === fileURLToPath(import.meta.url)) {
1521
+ const manifestIndex = process.argv.indexOf("--service-manifest");
1522
+ const lockIndex = process.argv.indexOf("--service-lock");
1523
+ const manifestPath = manifestIndex >= 0 ? process.argv[manifestIndex + 1] : null;
1524
+ const lockPath = lockIndex >= 0 ? process.argv[lockIndex + 1] : null;
1525
+ if (!manifestPath || !lockPath) {
1526
+ process.stderr.write("Internal service manifest and lock paths are required.\n");
1527
+ process.exitCode = 1;
1528
+ } else {
1529
+ process.exitCode = await runInferenceHostServiceBootstrap(manifestPath, {}, lockPath).catch((error) => {
1530
+ process.stderr.write(`${error instanceof Error ? error.message : "Inference-host bootstrap failed."}
1531
+ `);
1532
+ return 1;
1533
+ });
1534
+ }
1535
+ }
1536
+ export {
1537
+ compareInferenceHostReleaseVersions,
1538
+ runInferenceHostBootstrapNpmCommand,
1539
+ runInferenceHostServiceBootstrap
1540
+ };