@vtxmacro/cli 2026.9.48 → 2026.9.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -62,11 +62,20 @@ Both paths use a separate least-privilege `insights:inference` OAuth grant.
62
62
  VTX never receives an agent vendor password, OAuth token, or subscription
63
63
  credential.
64
64
 
65
+ - **Background services:** OpenAI Codex, GitHub Copilot, DeepSeek Harness, Grok Build, Pi. These integrations can keep serving VTX after the setup chat ends. Keep the host computer on and its service running.
66
+ - **Automatic foreground bridge:** Exo. The bridge serves VTX automatically while its process stays open.
67
+ - **Foreground agent integrations:** Amp, Auggie, Claude Code, Cursor, Gemini CLI, Google Antigravity, Hermes Agent, JetBrains Junie, Kiro CLI, OpenClaw, OpenCode, Qwen Code, Warp Oz. Keep the harness session and its VTX foreground host loop open. Available modes depend on the connected model’s advertised capabilities.
68
+
69
+ These groups describe how an integration runs, not a test grade. Limitations are
70
+ listed in the [Insights harness guide](https://vtxmacro.com/insights#subscription-inference).
71
+ Any recorded acceptance applies only to its tested mode and date; it does not
72
+ prove current provider availability.
73
+
65
74
  ### Durable inference hosts
66
75
 
67
76
  Codex remains the reference implementation and its existing App Server,
68
77
  authentication, quota, recovery, and provider-mode path are unchanged. GitHub
69
- Copilot is an additive preview adapter that uses the official SDK and validates
78
+ Copilot uses the official SDK and validates
70
79
  final text against VTX's immutable schema. An uncertain interrupted Copilot call
71
80
  is quarantined as `outcome_unknown` and is never blindly repeated. A different
72
81
  adapter cannot replace an installed Codex instance; it needs a distinct instance
@@ -76,15 +85,15 @@ effective model.
76
85
 
77
86
  Grok Build is a durable adapter using its package-owned official runtime and an
78
87
  isolated local Grok OAuth session. Run `vtx inference-host grok-login --instance grok-1`
79
- after the normal VTX host login, then `vtx inference-host service install --adapter grok-build --instance grok-1`.
88
+ after `vtx inference-host login --instance grok-1`, then `vtx inference-host service install --adapter grok-build --instance grok-1`.
80
89
  Provider mode has no tools; Main Agent mode exposes only assignment-scoped VTX tools.
81
90
  Structured decisions, model identity, and usage are validated. Interrupted requests
82
91
  with an uncertain outcome are fenced; same-attempt recovery is not supported.
83
92
 
84
- An explicitly capable durable Codex, Grok Build, Copilot, DeepSeek Harness, or Pi model can also
93
+ An explicitly capable model from a background service listed above can also
85
94
  control Main in **Agent** mode using the same VTX OAuth grant and its own local
86
- adapter-specific vendor credential: ChatGPT or Copilot login, or a DeepSeek or
87
- Pi provider API key. VTX assigns the running bot but does not send a VTX-authored prompt or set
95
+ adapter-specific vendor credential: ChatGPT, Copilot, or Grok login, or a DeepSeek
96
+ or Pi provider API key. VTX assigns the running bot but does not send a VTX-authored prompt or set
88
97
  the analysis cadence. The assigned runtime keeps a durable Agent thread,
89
98
  chooses when to wake, requests only the assignment-scoped VTX data it needs (or
90
99
  none), and submits the normal structured decision for VTX to validate and
@@ -242,9 +251,8 @@ confirmation page was blocked; the grant succeeded.
242
251
 
243
252
  ### Any compatible agent harness
244
253
 
245
- Codex, DeepSeek Harness, Claude Code, Cursor, GitHub Copilot, Antigravity, and other agents that can
246
- run shell commands can use their existing first-party session without a
247
- VTX-owned vendor adapter:
254
+ Compatible agents that can run shell commands can use their existing first-party
255
+ session without a VTX-owned vendor adapter:
248
256
 
249
257
  ```bash
250
258
  vtx inference-host login
@@ -348,12 +356,9 @@ self-modification, installed tools, or ambient conversation context. Interrupted
348
356
  work with an unknown outcome is fenced rather than repeated. After stopping and
349
357
  resolving pending work, remove the vendor key with `exo-logout --instance exo-1`.
350
358
 
351
- Claude Code, Antigravity, Gemini CLI, Kiro, Grok Build, Cursor, Amp, Auggie,
352
- Junie, Warp/Oz, Qwen Code, and OpenCode remain on the explicit foreground host
353
- path. Their current subscription routing,
354
- effective-model identity, schema, usage, or crash-recovery contracts do not yet
355
- meet every durable VTX acceptance fence. The public Insights matrix records the
356
- specific limitation instead of treating headless support alone as durability.
359
+ Amp, Auggie, Claude Code, Cursor, Gemini CLI, Google Antigravity, Hermes Agent, JetBrains Junie, Kiro CLI, OpenClaw, OpenCode, Qwen Code, Warp Oz use the explicit foreground agent path.
360
+ Their setup and specific limitations are listed in the public Insights matrix.
361
+ A successful foreground test does not establish background-service support.
357
362
 
358
363
  Keep `agent-run` open in a separate terminal while the foreground host should
359
364
  remain available. Use the Provider job loop for Main, Review, or Screener, or the
@@ -16,7 +16,7 @@ import { fileURLToPath } from "node:url";
16
16
  // agent-cli-release.json
17
17
  var agent_cli_release_default = {
18
18
  package_name: "@vtxmacro/cli",
19
- package_version: "2026.9.48",
19
+ package_version: "2026.9.50",
20
20
  codex_package_name: "@openai/codex",
21
21
  codex_version: "0.153.3",
22
22
  copilot_sdk_package_name: "@github/copilot-sdk",
@@ -296,6 +296,11 @@ import { constants } from "node:fs";
296
296
  import { lstat, mkdir, open, readFile, realpath, rename, rm } from "node:fs/promises";
297
297
  import { homedir } from "node:os";
298
298
  import { dirname, isAbsolute, join, relative, resolve, win32 as windowsPath } from "node:path";
299
+
300
+ // lib/inference-host/mcp-transport.ts
301
+ import { Agent, fetch as undiciFetch } from "undici";
302
+
303
+ // lib/inference-host/config.ts
299
304
  var MAX_INFERENCE_PRIVATE_FILE_BYTES = 16 * 1024 * 1024;
300
305
  var WINDOWS_PRIVATE_ACL_BROKER_SCRIPT = `$ErrorActionPreference='Stop'
301
306
  $ProgressPreference='SilentlyContinue'
package/bin/vtx.js CHANGED
@@ -77,7 +77,7 @@ var init_agent_cli_release = __esm({
77
77
  "agent-cli-release.json"() {
78
78
  agent_cli_release_default = {
79
79
  package_name: "@vtxmacro/cli",
80
- package_version: "2026.9.48",
80
+ package_version: "2026.9.50",
81
81
  codex_package_name: "@openai/codex",
82
82
  codex_version: "0.153.3",
83
83
  copilot_sdk_package_name: "@github/copilot-sdk",
@@ -17580,13 +17580,69 @@ var init_dist = __esm({
17580
17580
  }
17581
17581
  });
17582
17582
 
17583
+ // lib/inference-host/mcp-transport.ts
17584
+ import { readFileSync } from "node:fs";
17585
+ import { X509Certificate } from "node:crypto";
17586
+ import { isIP } from "node:net";
17587
+ import { isAbsolute, win32 } from "node:path";
17588
+ import { Agent, fetch as undiciFetch } from "undici";
17589
+ function resolveInferenceMcpDirectTransport(env) {
17590
+ const address = String(env.VTX_INFERENCE_HOST_MCP_CONNECT_ADDRESS || "").trim();
17591
+ const caFile = String(env.VTX_INFERENCE_HOST_MCP_CA_FILE || "").trim();
17592
+ if (!address && !caFile) return void 0;
17593
+ if (!isIP(address) || !caFile || /[\r\n\0]/u.test(caFile) || !isAbsolute(caFile) && !win32.isAbsolute(caFile)) {
17594
+ throw new Error("Direct inference MCP transport requires an IP address and an absolute CA file path.");
17595
+ }
17596
+ return { address, caFile };
17597
+ }
17598
+ function createInferenceMcpTransport(endpoint, direct, fetchImpl = fetch) {
17599
+ if (!direct) return { fetch: fetchImpl, route: "public", close: async () => void 0 };
17600
+ const canonical = new URL(endpoint);
17601
+ if (canonical.protocol !== "https:" || canonical.username || canonical.password || canonical.pathname !== "/insights/mcp" || canonical.search || canonical.hash || isIP(canonical.hostname) || !isIP(direct.address)) {
17602
+ throw new Error("Direct inference MCP transport requires a canonical HTTPS MCP hostname.");
17603
+ }
17604
+ const ca = readFileSync(direct.caFile, "utf8");
17605
+ new X509Certificate(ca);
17606
+ const agent = new Agent({
17607
+ connect: {
17608
+ ca,
17609
+ rejectUnauthorized: true,
17610
+ servername: canonical.hostname,
17611
+ lookup: (_hostname, options, callback) => {
17612
+ const address = { address: direct.address, family: isIP(direct.address) };
17613
+ if (options.all) callback(null, [address]);
17614
+ else callback(null, address.address, address.family);
17615
+ }
17616
+ }
17617
+ });
17618
+ const dispatchFetch = fetchImpl === fetch ? undiciFetch : fetchImpl;
17619
+ const routedFetch = (input, init2) => {
17620
+ const url2 = new URL(input instanceof Request ? input.url : String(input));
17621
+ if (url2.href !== canonical.href) {
17622
+ return Promise.reject(new Error("Direct inference transport cannot send requests outside its MCP endpoint."));
17623
+ }
17624
+ return dispatchFetch(input, { ...init2, redirect: "error", dispatcher: agent });
17625
+ };
17626
+ return { fetch: routedFetch, route: "direct", close: async () => {
17627
+ await agent.destroy();
17628
+ } };
17629
+ }
17630
+ var init_mcp_transport = __esm({
17631
+ "lib/inference-host/mcp-transport.ts"() {
17632
+ "use strict";
17633
+ init_define_VTX_EXO_POLICY();
17634
+ init_define_VTX_GROK_POLICY();
17635
+ init_define_VTX_PI_MODEL_POLICY();
17636
+ }
17637
+ });
17638
+
17583
17639
  // lib/inference-host/config.ts
17584
17640
  import { randomBytes } from "node:crypto";
17585
17641
  import { spawn } from "node:child_process";
17586
17642
  import { constants } from "node:fs";
17587
17643
  import { lstat, mkdir, open, readFile, realpath, rename, rm } from "node:fs/promises";
17588
17644
  import { homedir } from "node:os";
17589
- import { dirname, isAbsolute, join, relative, resolve, win32 as windowsPath } from "node:path";
17645
+ import { dirname, isAbsolute as isAbsolute2, join, relative, resolve, win32 as windowsPath } from "node:path";
17590
17646
  function inferenceBaseDir(env) {
17591
17647
  const configured = String(env.VTX_INFERENCE_HOST_HOME || "").trim();
17592
17648
  return configured || join(homedir(), ".vtx", "inference-host");
@@ -17638,6 +17694,7 @@ function resolveInferenceHostConfig(env = process.env) {
17638
17694
  );
17639
17695
  return {
17640
17696
  apiUrl: String(env.VTX_API_URL || "https://api.vtxmacro.com").replace(/\/+$/, ""),
17697
+ mcpDirectTransport: resolveInferenceMcpDirectTransport(env),
17641
17698
  baseDir,
17642
17699
  instanceName,
17643
17700
  credentialStoreMode: rawMode,
@@ -18160,6 +18217,7 @@ var init_config = __esm({
18160
18217
  init_define_VTX_GROK_POLICY();
18161
18218
  init_define_VTX_PI_MODEL_POLICY();
18162
18219
  init_dist();
18220
+ init_mcp_transport();
18163
18221
  loadInferenceReceiptDurabilityTimeoutMs = async () => {
18164
18222
  let configured;
18165
18223
  if (true) {
@@ -18734,7 +18792,7 @@ while(($line=[Console]::In.ReadLine()) -ne $null) {
18734
18792
  requireNamedInstancePath = (instanceName, instanceDir, rawPath, label) => {
18735
18793
  if (!rawPath || instanceName === DEFAULT_INFERENCE_HOST_INSTANCE) return rawPath;
18736
18794
  const relativePath = relative(resolve(instanceDir), resolve(rawPath));
18737
- if (relativePath === ".." || relativePath.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) || isAbsolute(relativePath)) {
18795
+ if (relativePath === ".." || relativePath.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) || isAbsolute2(relativePath)) {
18738
18796
  throw new Error(`${label} for a named instance must stay inside its isolated instance directory.`);
18739
18797
  }
18740
18798
  return rawPath;
@@ -20619,6 +20677,7 @@ var init_mcp_client = __esm({
20619
20677
  init_define_VTX_PI_MODEL_POLICY();
20620
20678
  init_zod();
20621
20679
  init_runtime_policy_generated();
20680
+ init_mcp_transport();
20622
20681
  init_external_inference_contract();
20623
20682
  EXTERNAL_INFERENCE_MCP_PROTOCOL_VERSION = "2026-07-28";
20624
20683
  EXTERNAL_INFERENCE_AUTOMATED_HOST_TOOLS = [
@@ -21282,6 +21341,7 @@ var init_mcp_client = __esm({
21282
21341
  #endpoint;
21283
21342
  #tokenSource;
21284
21343
  #fetch;
21344
+ #transport;
21285
21345
  #clientVersion;
21286
21346
  #clientName;
21287
21347
  #expectedTools;
@@ -21293,6 +21353,9 @@ var init_mcp_client = __esm({
21293
21353
  #providerHttpStatusTools = /* @__PURE__ */ new Set();
21294
21354
  #grokToolValidationTools = /* @__PURE__ */ new Set();
21295
21355
  #grokResponseIdentityTools = /* @__PURE__ */ new Set();
21356
+ async close() {
21357
+ await this.#transport.close();
21358
+ }
21296
21359
  supportsProviderHttpStatusDiagnostics(tool) {
21297
21360
  return this.#providerHttpStatusTools.has(tool);
21298
21361
  }
@@ -21345,7 +21408,8 @@ var init_mcp_client = __esm({
21345
21408
  }
21346
21409
  this.#endpoint = endpoint;
21347
21410
  this.#tokenSource = options.tokenSource;
21348
- this.#fetch = options.fetchImpl ?? fetch;
21411
+ this.#transport = createInferenceMcpTransport(endpoint, options.directTransport, options.fetchImpl);
21412
+ this.#fetch = this.#transport.fetch;
21349
21413
  this.#clientVersion = String(options.clientVersion || "development").trim() || "development";
21350
21414
  this.#clientName = String(
21351
21415
  options.clientName || "@vtxmacro/cli external inference host"
@@ -21508,7 +21572,7 @@ var init_mcp_client = __esm({
21508
21572
  return result2;
21509
21573
  } finally {
21510
21574
  if (timing) {
21511
- const receipt = timing.finish(outcome);
21575
+ const receipt = Object.freeze({ ...timing.finish(outcome), transport_route: this.#transport.route });
21512
21576
  try {
21513
21577
  void Promise.resolve(options.onClaimTiming?.(receipt)).catch(() => void 0);
21514
21578
  } catch {
@@ -28103,7 +28167,7 @@ var require_ajv = __commonJS({
28103
28167
  import { spawn as spawn3 } from "node:child_process";
28104
28168
  import { chmod, lstat as lstat2, open as open2, readFile as readFile2, rename as rename2, rm as rm2, writeFile } from "node:fs/promises";
28105
28169
  import { tmpdir } from "node:os";
28106
- import { dirname as dirname2, isAbsolute as isAbsolute2, join as join2, resolve as resolve2, sep } from "node:path";
28170
+ import { dirname as dirname2, isAbsolute as isAbsolute3, join as join2, resolve as resolve2, sep } from "node:path";
28107
28171
  import { createInterface } from "node:readline";
28108
28172
  async function loginCodexSubscription(options) {
28109
28173
  const session = await CodexAppServerSession.start(options);
@@ -29732,7 +29796,7 @@ child.once('close', async (code, signal) => {
29732
29796
  const resolvedHome = resolve2(this.codexHome);
29733
29797
  const resolvedThreadPath = resolve2(threadPath);
29734
29798
  const resolvedSessionsRoot = join2(resolvedHome, "sessions");
29735
- if (!threadId || !threadPath || !isAbsolute2(threadPath) || !resolvedThreadPath.startsWith(`${resolvedSessionsRoot}${sep}`) || !resolvedThreadPath.endsWith(".jsonl") || thread?.ephemeral !== false || thread?.modelProvider !== "openai" || !Array.isArray(thread?.turns) || thread.turns.length !== 0 || result2.model !== options.requestedModel || result2.modelProvider !== "openai" || result2.serviceTier !== "default" || result2.reasoningEffort !== options.requestedReasoningEffort || String(result2.cwd || "") !== options.workspacePath || !Array.isArray(result2.runtimeWorkspaceRoots) || result2.runtimeWorkspaceRoots.length !== 0 || !Array.isArray(result2.instructionSources) || result2.instructionSources.length !== 0 || result2.approvalPolicy !== "never" || result2.approvalsReviewer !== "user" || sandbox?.type !== "readOnly" || sandbox.networkAccess !== false || permission?.id !== CODEX_INFERENCE_PERMISSION_PROFILE || permission.extends !== null) {
29799
+ if (!threadId || !threadPath || !isAbsolute3(threadPath) || !resolvedThreadPath.startsWith(`${resolvedSessionsRoot}${sep}`) || !resolvedThreadPath.endsWith(".jsonl") || thread?.ephemeral !== false || thread?.modelProvider !== "openai" || !Array.isArray(thread?.turns) || thread.turns.length !== 0 || result2.model !== options.requestedModel || result2.modelProvider !== "openai" || result2.serviceTier !== "default" || result2.reasoningEffort !== options.requestedReasoningEffort || String(result2.cwd || "") !== options.workspacePath || !Array.isArray(result2.runtimeWorkspaceRoots) || result2.runtimeWorkspaceRoots.length !== 0 || !Array.isArray(result2.instructionSources) || result2.instructionSources.length !== 0 || result2.approvalPolicy !== "never" || result2.approvalsReviewer !== "user" || sandbox?.type !== "readOnly" || sandbox.networkAccess !== false || permission?.id !== CODEX_INFERENCE_PERMISSION_PROFILE || permission.extends !== null) {
29736
29800
  throw new CodexAppServerError({
29737
29801
  message: "Codex thread isolation or effective settings were invalid.",
29738
29802
  category: "adapter",
@@ -29818,7 +29882,7 @@ child.once('close', async (code, signal) => {
29818
29882
  async resumeAgentThread(options) {
29819
29883
  const expectedPath = resolve2(options.threadPath);
29820
29884
  const sessionsRoot = join2(resolve2(this.codexHome), "sessions");
29821
- if (!options.threadId.trim() || !isAbsolute2(options.threadPath) || !expectedPath.startsWith(`${sessionsRoot}${sep}`) || !expectedPath.endsWith(".jsonl")) {
29885
+ if (!options.threadId.trim() || !isAbsolute3(options.threadPath) || !expectedPath.startsWith(`${sessionsRoot}${sep}`) || !expectedPath.endsWith(".jsonl")) {
29822
29886
  throw new CodexAppServerError({
29823
29887
  message: "Codex Agent durable thread receipt was invalid.",
29824
29888
  category: "adapter",
@@ -29863,7 +29927,7 @@ child.once('close', async (code, signal) => {
29863
29927
  const threadPath = String(thread?.path || "");
29864
29928
  const resolvedThreadPath = resolve2(threadPath);
29865
29929
  const sessionsRoot = join2(resolve2(this.codexHome), "sessions");
29866
- if (!threadId || !threadPath || !isAbsolute2(threadPath) || !resolvedThreadPath.startsWith(`${sessionsRoot}${sep}`) || !resolvedThreadPath.endsWith(".jsonl") || thread?.ephemeral !== false || thread?.modelProvider !== "openai" || !Array.isArray(thread?.turns) || !resumed && thread.turns.length !== 0 || result2.model !== options.requestedModel || result2.modelProvider !== "openai" || result2.serviceTier !== "default" || result2.reasoningEffort !== options.requestedReasoningEffort || String(result2.cwd || "") !== options.workspacePath || !Array.isArray(result2.instructionSources) || result2.instructionSources.length !== 0 || result2.approvalPolicy !== "never" || result2.approvalsReviewer !== "user" || sandbox?.type !== "readOnly" || sandbox.networkAccess !== false || permission?.id !== CODEX_AGENT_PERMISSION_PROFILE || permission.extends !== null) {
29930
+ if (!threadId || !threadPath || !isAbsolute3(threadPath) || !resolvedThreadPath.startsWith(`${sessionsRoot}${sep}`) || !resolvedThreadPath.endsWith(".jsonl") || thread?.ephemeral !== false || thread?.modelProvider !== "openai" || !Array.isArray(thread?.turns) || !resumed && thread.turns.length !== 0 || result2.model !== options.requestedModel || result2.modelProvider !== "openai" || result2.serviceTier !== "default" || result2.reasoningEffort !== options.requestedReasoningEffort || String(result2.cwd || "") !== options.workspacePath || !Array.isArray(result2.instructionSources) || result2.instructionSources.length !== 0 || result2.approvalPolicy !== "never" || result2.approvalsReviewer !== "user" || sandbox?.type !== "readOnly" || sandbox.networkAccess !== false || permission?.id !== CODEX_AGENT_PERMISSION_PROFILE || permission.extends !== null) {
29867
29931
  throw new CodexAppServerError({
29868
29932
  message: "Codex Agent thread isolation or effective settings were invalid.",
29869
29933
  category: "adapter",
@@ -30959,6 +31023,7 @@ function createDefaultInferenceHostRunnerDependencies(options) {
30959
31023
  }),
30960
31024
  createMcpClient: (tokenSource) => new ExternalInferenceMcpClient({
30961
31025
  endpoint: `${options.apiUrl.replace(/\/+$/u, "")}/insights/mcp`,
31026
+ directTransport: options.directTransport,
30962
31027
  tokenSource,
30963
31028
  fetchImpl,
30964
31029
  clientVersion: options.clientVersion,
@@ -33382,7 +33447,11 @@ var init_runner = __esm({
33382
33447
  try {
33383
33448
  await this.dependencies.codexAdapter.close?.();
33384
33449
  } finally {
33385
- await lock2.release();
33450
+ try {
33451
+ await mcp?.close?.();
33452
+ } finally {
33453
+ await lock2.release();
33454
+ }
33386
33455
  }
33387
33456
  }
33388
33457
  }
@@ -35627,7 +35696,7 @@ import {
35627
35696
  } from "node:fs/promises";
35628
35697
  import { createHash as createHash6, randomBytes as randomBytes4 } from "node:crypto";
35629
35698
  import { tmpdir as tmpdir2 } from "node:os";
35630
- import { isAbsolute as isAbsolute3, join as join4, relative as relative2, resolve as resolve3, sep as sep2 } from "node:path";
35699
+ import { isAbsolute as isAbsolute4, join as join4, relative as relative2, resolve as resolve3, sep as sep2 } from "node:path";
35631
35700
  var MAX_PROMPT_BYTES2, CODEX_MODEL_NAME_PATTERN, CODEX_REASONING_EFFORT_PATTERN, codexRecoveryCheckpointProcessFingerprint, proveCodexSameBootQuiescence, tokenUsageReceiptSchema, turnResultReceiptSchema, terminalReceiptSchema, recoveryCheckpointSchema, recoveryFileSchema, FileCodexAttemptRecoveryStore, utf8Bytes, assertAttemptActive, tomlString, permissionConfig, ensureDedicatedCodexHome, createIsolatedCodexAttemptResources, createIsolatedCodexHostResources, validateAttemptInput, isStrictDescendant, assertRecoveryResourceScope, removeRecoveredThread, confirmGuardianTerminatedForRecovery, recoveredCodexProcessExit, reconcileCodexAttemptRecovery, CodexSubscriptionAdapter, CodexAgentSubscriptionAdapter;
35632
35701
  var init_codex_adapter = __esm({
35633
35702
  "lib/inference-host/codex-adapter.ts"() {
@@ -36010,7 +36079,7 @@ var init_codex_adapter = __esm({
36010
36079
  const parentPath = resolve3(parent);
36011
36080
  const candidatePath = resolve3(candidate);
36012
36081
  const scoped = relative2(parentPath, candidatePath);
36013
- return scoped.length > 0 && !scoped.startsWith(`..${sep2}`) && scoped !== ".." && !isAbsolute3(scoped);
36082
+ return scoped.length > 0 && !scoped.startsWith(`..${sep2}`) && scoped !== ".." && !isAbsolute4(scoped);
36014
36083
  };
36015
36084
  assertRecoveryResourceScope = (checkpoint) => {
36016
36085
  const temporaryRoot = resolve3(tmpdir2());
@@ -36100,7 +36169,7 @@ var init_codex_adapter = __esm({
36100
36169
  }
36101
36170
  }
36102
36171
  if (checkpoint.threadPath !== null) {
36103
- if (!isAbsolute3(checkpoint.threadPath) || !isStrictDescendant(
36172
+ if (!isAbsolute4(checkpoint.threadPath) || !isStrictDescendant(
36104
36173
  checkpoint.threadPath,
36105
36174
  sessionsRoot
36106
36175
  ) || !checkpoint.threadPath.endsWith(".jsonl")) {
@@ -42462,7 +42531,7 @@ var init_runtime_policy_generated2 = __esm({
42462
42531
  // lib/inference-host/service.ts
42463
42532
  import { spawn as spawn10 } from "node:child_process";
42464
42533
  import { randomUUID as randomUUID9 } from "node:crypto";
42465
- import { createWriteStream, readFileSync } from "node:fs";
42534
+ import { createWriteStream, readFileSync as readFileSync2 } from "node:fs";
42466
42535
  import { access as access4, chmod as chmod3, mkdir as mkdir3, readFile as readFile9, rm as rm10, writeFile as writeFile4 } from "node:fs/promises";
42467
42536
  import { homedir as homedir2 } from "node:os";
42468
42537
  import { dirname as dirname12, join as join13, resolve as resolve10 } from "node:path";
@@ -42505,7 +42574,7 @@ var init_service = __esm({
42505
42574
  isWindowsSubsystemForLinux = (env = process.env, kernelRelease) => Boolean(
42506
42575
  String(env.WSL_INTEROP || "").trim() || String(env.WSL_DISTRO_NAME || "").trim() || /microsoft/iu.test(kernelRelease ?? (() => {
42507
42576
  try {
42508
- return readFileSync("/proc/sys/kernel/osrelease", "utf8");
42577
+ return readFileSync2("/proc/sys/kernel/osrelease", "utf8");
42509
42578
  } catch {
42510
42579
  return "";
42511
42580
  }
@@ -42790,6 +42859,10 @@ var init_service = __esm({
42790
42859
  if (config2.credentialFilePath) {
42791
42860
  result2.VTX_INFERENCE_HOST_CREDENTIAL_FILE = config2.credentialFilePath;
42792
42861
  }
42862
+ if (config2.mcpDirectTransport) {
42863
+ result2.VTX_INFERENCE_HOST_MCP_CONNECT_ADDRESS = config2.mcpDirectTransport.address;
42864
+ result2.VTX_INFERENCE_HOST_MCP_CA_FILE = config2.mcpDirectTransport.caFile;
42865
+ }
42793
42866
  return result2;
42794
42867
  };
42795
42868
  serviceBootstrapArguments = (bootstrapScript, manifestPath, lockPath) => [
@@ -44725,6 +44798,7 @@ Durable service:
44725
44798
  });
44726
44799
  const dependencies = createDefaultInferenceHostRunnerDependencies({
44727
44800
  apiUrl: options.config.apiUrl,
44801
+ directTransport: options.config.mcpDirectTransport,
44728
44802
  statePath: options.config.statePath,
44729
44803
  processLockPath: options.config.processLockPath,
44730
44804
  credentialStore: options.credentialStore,
@@ -44792,6 +44866,7 @@ Durable service:
44792
44866
  }
44793
44867
  const dependencies = createDefaultInferenceHostRunnerDependencies({
44794
44868
  apiUrl: options.config.apiUrl,
44869
+ directTransport: options.config.mcpDirectTransport,
44795
44870
  statePath: options.config.statePath,
44796
44871
  processLockPath: options.config.processLockPath,
44797
44872
  credentialStore: options.credentialStore,
@@ -47821,7 +47896,7 @@ var init_client = __esm({
47821
47896
  import {
47822
47897
  chmodSync,
47823
47898
  mkdirSync,
47824
- readFileSync as readFileSync2,
47899
+ readFileSync as readFileSync3,
47825
47900
  renameSync,
47826
47901
  unlinkSync,
47827
47902
  writeFileSync
@@ -47876,7 +47951,7 @@ var init_protection_storage = __esm({
47876
47951
  }
47877
47952
  readValues() {
47878
47953
  try {
47879
- return parseStoredValues(readFileSync2(this.path, "utf8"), this.path);
47954
+ return parseStoredValues(readFileSync3(this.path, "utf8"), this.path);
47880
47955
  } catch (error48) {
47881
47956
  if (error48.code === "ENOENT") return {};
47882
47957
  throw error48;
@@ -47896,7 +47971,7 @@ var init_protection_storage = __esm({
47896
47971
  chmodSync(temporaryPath, 384);
47897
47972
  renameSync(temporaryPath, this.path);
47898
47973
  chmodSync(this.path, 384);
47899
- if (readFileSync2(this.path, "utf8") !== serialized) {
47974
+ if (readFileSync3(this.path, "utf8") !== serialized) {
47900
47975
  throw new Error("Headless protection state readback did not match the durable write.");
47901
47976
  }
47902
47977
  } catch (error48) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vtxmacro/cli",
3
- "version": "2026.9.48",
3
+ "version": "2026.9.50",
4
4
  "description": "VTX Macro CLI, MCP server, and durable external inference host.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",
@@ -20,6 +20,7 @@
20
20
  "node": "^22.19.0 || >=24.0.0"
21
21
  },
22
22
  "dependencies": {
23
+ "undici": "8.10.0",
23
24
  "@openai/codex": "0.153.3",
24
25
  "@earendil-works/pi-coding-agent": "0.85.1",
25
26
  "@earendil-works/pi-ai": "0.85.1",