@vtxmacro/cli 2026.8.22 → 2026.8.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/vtx.js +235 -26
  2. package/package.json +1 -1
package/bin/vtx.js CHANGED
@@ -38,7 +38,7 @@ var init_agent_cli_release = __esm({
38
38
  "agent-cli-release.json"() {
39
39
  agent_cli_release_default = {
40
40
  package_name: "@vtxmacro/cli",
41
- package_version: "2026.8.22",
41
+ package_version: "2026.8.24",
42
42
  codex_package_name: "@openai/codex",
43
43
  codex_version: "0.147.0",
44
44
  platforms: {
@@ -16132,7 +16132,10 @@ function assertLocalState(value) {
16132
16132
  }
16133
16133
  return record2;
16134
16134
  }
16135
- async function ensureInferencePrivateDirectory(path) {
16135
+ async function ensureInferencePrivateDirectory(path, dependencies = {}) {
16136
+ const platform = dependencies.platform ?? process.platform;
16137
+ const runner = dependencies.runner ?? runWindowsPrivateAcl;
16138
+ const defaultRoot = dependencies.defaultRoot ?? resolve(homedir(), ".vtx", "inference-host");
16136
16139
  let created = false;
16137
16140
  try {
16138
16141
  const before = await lstat(path);
@@ -16148,9 +16151,18 @@ async function ensureInferencePrivateDirectory(path) {
16148
16151
  if (after.isSymbolicLink() || !after.isDirectory()) {
16149
16152
  throw new Error("Inference host state directory is unsafe.");
16150
16153
  }
16151
- if (process.platform === "win32") {
16152
- if (created) await secureWindowsPrivatePath(path, "directory", "harden");
16153
- else await secureExistingWindowsPath(path, "directory");
16154
+ if (platform === "win32") {
16155
+ if (created) {
16156
+ await secureWindowsPrivatePath(path, "directory", "harden", platform, runner);
16157
+ } else {
16158
+ await secureExistingWindowsPath(
16159
+ path,
16160
+ "directory",
16161
+ platform,
16162
+ runner,
16163
+ defaultRoot
16164
+ );
16165
+ }
16154
16166
  return;
16155
16167
  }
16156
16168
  if ((after.mode & 63) !== 0) {
@@ -16173,9 +16185,16 @@ async function syncInferenceDirectory(path, platform = process.platform) {
16173
16185
  await handle.close();
16174
16186
  }
16175
16187
  }
16176
- async function writeAtomicInferencePrivateFile(path, contents) {
16188
+ async function writeAtomicInferencePrivateFile(path, contents, dependencies = {}) {
16189
+ const platform = dependencies.platform ?? process.platform;
16190
+ const runner = dependencies.runner ?? runWindowsPrivateAcl;
16191
+ const defaultRoot = dependencies.defaultRoot ?? resolve(homedir(), ".vtx", "inference-host");
16177
16192
  const directory = dirname(path);
16178
- await ensureInferencePrivateDirectory(directory);
16193
+ await ensureInferencePrivateDirectory(directory, dependencies);
16194
+ const hardenedDirectoryIdentity = platform === "win32" && isDefaultWindowsPrivatePath(directory, defaultRoot) ? windowsAclCache.get(aclCacheKey(directory, "directory", "harden")) : void 0;
16195
+ if (platform === "win32" && isDefaultWindowsPrivatePath(directory, defaultRoot) && !hardenedDirectoryIdentity) {
16196
+ throw new Error("Windows private directory ACL hardening was not durably verified.");
16197
+ }
16179
16198
  const temporary = join(
16180
16199
  directory,
16181
16200
  `.${process.pid}.${randomBytes(12).toString("hex")}.tmp`
@@ -16194,19 +16213,42 @@ async function writeAtomicInferencePrivateFile(path, contents) {
16194
16213
  throw error48;
16195
16214
  }
16196
16215
  await handle.close();
16197
- await secureWindowsPrivatePath(temporary, "file", "harden");
16216
+ await secureWindowsPrivatePath(temporary, "file", "harden", platform, runner);
16217
+ const hardenedIdentity = platform === "win32" ? windowsAclCache.get(aclCacheKey(temporary, "file", "harden")) : void 0;
16218
+ if (platform === "win32" && !hardenedIdentity) {
16219
+ await rm(temporary, { force: true }).catch(() => void 0);
16220
+ throw new Error("Windows private ACL hardening was not durably verified.");
16221
+ }
16198
16222
  try {
16199
16223
  invalidateWindowsAclCache(path);
16200
16224
  await rename(temporary, path);
16201
- invalidateWindowsAclCache(temporary);
16202
- await secureWindowsPrivatePath(path, "file", "verify");
16203
- await syncInferenceDirectory(directory);
16225
+ if (platform === "win32" && hardenedIdentity) {
16226
+ await rebindHardenedWindowsAclAfterRename(
16227
+ temporary,
16228
+ path,
16229
+ "file",
16230
+ hardenedIdentity
16231
+ );
16232
+ } else {
16233
+ invalidateWindowsAclCache(temporary);
16234
+ }
16235
+ await syncInferenceDirectory(directory, platform);
16236
+ if (platform === "win32" && hardenedDirectoryIdentity) {
16237
+ await rebindHardenedWindowsDirectoryAfterOwnedMutation(
16238
+ directory,
16239
+ hardenedDirectoryIdentity
16240
+ );
16241
+ }
16204
16242
  } catch (error48) {
16205
16243
  await rm(temporary, { force: true }).catch(() => void 0);
16244
+ invalidateWindowsAclCache(temporary);
16206
16245
  throw error48;
16207
16246
  }
16208
16247
  }
16209
- async function readInferencePrivateFile(path, label) {
16248
+ async function readInferencePrivateFile(path, label, dependencies = {}) {
16249
+ const platform = dependencies.platform ?? process.platform;
16250
+ const runner = dependencies.runner ?? runWindowsPrivateAcl;
16251
+ const defaultRoot = dependencies.defaultRoot ?? resolve(homedir(), ".vtx", "inference-host");
16210
16252
  let before;
16211
16253
  try {
16212
16254
  before = await lstat(path);
@@ -16217,15 +16259,21 @@ async function readInferencePrivateFile(path, label) {
16217
16259
  if (before.isSymbolicLink() || !before.isFile()) {
16218
16260
  throw new Error(`${label} is unsafe.`);
16219
16261
  }
16220
- await secureExistingWindowsPath(dirname(path), "directory");
16221
- await secureExistingWindowsPath(path, "file");
16262
+ await secureExistingWindowsPath(
16263
+ dirname(path),
16264
+ "directory",
16265
+ platform,
16266
+ runner,
16267
+ defaultRoot
16268
+ );
16269
+ await secureExistingWindowsPath(path, "file", platform, runner, defaultRoot);
16222
16270
  const handle = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW);
16223
16271
  try {
16224
16272
  const opened = await handle.stat();
16225
16273
  if (!opened.isFile() || opened.dev !== before.dev || opened.ino !== before.ino || opened.size > MAX_INFERENCE_PRIVATE_FILE_BYTES || typeof process.getuid === "function" && opened.uid !== process.getuid()) {
16226
16274
  throw new Error(`${label} changed while it was opened.`);
16227
16275
  }
16228
- if (process.platform !== "win32" && (opened.mode & 63) !== 0) {
16276
+ if (platform !== "win32" && (opened.mode & 63) !== 0) {
16229
16277
  throw new Error(`${label} must have mode 0600.`);
16230
16278
  }
16231
16279
  return await handle.readFile("utf8");
@@ -16440,7 +16488,7 @@ async function acquireInferenceHostProcessLock(path, dependencies = {}) {
16440
16488
  }
16441
16489
  };
16442
16490
  }
16443
- var INFERENCE_CREDENTIAL_NAMESPACE, MAX_INFERENCE_PRIVATE_FILE_BYTES, WINDOWS_PRIVATE_ACL_SCRIPT, windowsPrivateAclInvocation, runWindowsPrivateAcl, windowsAclCache, windowsAclIdentity, aclCacheKey, secureWindowsPrivatePath, invalidateWindowsAclCache, isDefaultWindowsPrivatePath, secureExistingWindowsPath, linuxProcessIdentity, windowsProcessIdentity, darwinProcessIdentity, runSmallIdentityCommand, cachedSystemBootIdentity, readInferenceSystemBootIdentity, defaultProcessIdentity, defaultCurrentProcessIdentity, processLockObservationCache, inferenceProcessIdentitiesMatch, credentialStoreIdentity;
16491
+ var INFERENCE_CREDENTIAL_NAMESPACE, MAX_INFERENCE_PRIVATE_FILE_BYTES, WINDOWS_PRIVATE_ACL_SCRIPT, windowsPrivateAclInvocation, runWindowsPrivateAcl, windowsAclCache, windowsAclIdentity, aclCacheKey, secureWindowsPrivatePath, invalidateWindowsAclCache, rebindHardenedWindowsAclAfterRename, rebindHardenedWindowsDirectoryAfterOwnedMutation, isDefaultWindowsPrivatePath, secureExistingWindowsPath, linuxProcessIdentity, windowsProcessIdentity, darwinProcessIdentity, runSmallIdentityCommand, cachedSystemBootIdentity, readInferenceSystemBootIdentity, defaultProcessIdentity, defaultCurrentProcessIdentity, processLockObservationCache, inferenceProcessIdentitiesMatch, credentialStoreIdentity;
16444
16492
  var init_config = __esm({
16445
16493
  "lib/inference-host/config.ts"() {
16446
16494
  "use strict";
@@ -16581,6 +16629,35 @@ if(-not $userFull) { throw 'private ACL does not grant the current user full con
16581
16629
  }
16582
16630
  }
16583
16631
  };
16632
+ rebindHardenedWindowsAclAfterRename = async (source, destination, kind, expected) => {
16633
+ const resolvedSource = resolve(source);
16634
+ const resolvedDestination = resolve(destination);
16635
+ if (resolvedSource === resolvedDestination || dirname(resolvedSource) !== dirname(resolvedDestination)) {
16636
+ throw new Error("Windows private ACL cache rename boundary is invalid.");
16637
+ }
16638
+ const published = await windowsAclIdentity(destination);
16639
+ if (published.dev !== expected.dev || published.ino !== expected.ino || published.mode !== expected.mode || published.mtimeNs !== expected.mtimeNs || published.size !== expected.size) {
16640
+ invalidateWindowsAclCache(source);
16641
+ invalidateWindowsAclCache(destination);
16642
+ throw new Error("Windows private file identity changed during atomic publication.");
16643
+ }
16644
+ invalidateWindowsAclCache(source);
16645
+ invalidateWindowsAclCache(destination);
16646
+ for (const mode of ["harden", "verify", "verify-owner"]) {
16647
+ windowsAclCache.set(aclCacheKey(destination, kind, mode), published);
16648
+ }
16649
+ };
16650
+ rebindHardenedWindowsDirectoryAfterOwnedMutation = async (path, expected) => {
16651
+ const current = await windowsAclIdentity(path);
16652
+ if (current.dev !== expected.dev || current.ino !== expected.ino || current.mode !== expected.mode) {
16653
+ invalidateWindowsAclCache(path);
16654
+ throw new Error("Windows private directory identity changed during atomic publication.");
16655
+ }
16656
+ invalidateWindowsAclCache(path);
16657
+ for (const mode of ["harden", "verify", "verify-owner"]) {
16658
+ windowsAclCache.set(aclCacheKey(path, "directory", mode), current);
16659
+ }
16660
+ };
16584
16661
  isDefaultWindowsPrivatePath = (path, root = resolve(homedir(), ".vtx", "inference-host")) => {
16585
16662
  const child = relative(root, resolve(path));
16586
16663
  return child === "" || !child.startsWith("..") && !child.includes(":");
@@ -16591,8 +16668,6 @@ if(-not $userFull) { throw 'private ACL does not grant the current user full con
16591
16668
  await secureWindowsPrivatePath(path, kind, "verify", platform, runner);
16592
16669
  return;
16593
16670
  }
16594
- await secureWindowsPrivatePath(path, kind, "verify-owner", platform, runner);
16595
- invalidateWindowsAclCache(path);
16596
16671
  await secureWindowsPrivatePath(path, kind, "harden", platform, runner);
16597
16672
  };
16598
16673
  linuxProcessIdentity = async (pid) => {
@@ -20047,11 +20122,27 @@ child.once('close', async () => {
20047
20122
  });
20048
20123
  }
20049
20124
  }
20050
- async requireModel(modelName, reasoningEffort, deadlineAtMs, signal) {
20125
+ async readModelCapabilities(deadlineAtMs, signal) {
20051
20126
  let cursor = null;
20052
20127
  const seen = /* @__PURE__ */ new Set();
20053
- let match = null;
20128
+ const capabilities = [];
20054
20129
  do {
20130
+ if (signal?.aborted) {
20131
+ throw new CodexAppServerError({
20132
+ message: "Codex model catalog request was cancelled before dispatch.",
20133
+ category: "cancelled",
20134
+ code: "cancelled",
20135
+ retryable: false
20136
+ });
20137
+ }
20138
+ if (Date.now() >= deadlineAtMs) {
20139
+ throw new CodexAppServerError({
20140
+ message: "Codex model catalog request exceeded the immutable deadline before dispatch.",
20141
+ category: "timeout",
20142
+ code: "deadline_exceeded",
20143
+ retryable: false
20144
+ });
20145
+ }
20055
20146
  const result2 = await this.request("model/list", {
20056
20147
  includeHidden: true,
20057
20148
  ...cursor ? { cursor } : {}
@@ -20062,7 +20153,19 @@ child.once('close', async () => {
20062
20153
  const data = Array.isArray(result2.data) ? result2.data : [];
20063
20154
  for (const raw of data) {
20064
20155
  const candidate = objectOrNull(raw);
20065
- if (candidate && (candidate.model === modelName || candidate.id === modelName)) match = candidate;
20156
+ if (!candidate) continue;
20157
+ const id2 = typeof candidate.id === "string" && candidate.id.trim() ? candidate.id.trim() : null;
20158
+ const model = typeof candidate.model === "string" && candidate.model.trim() ? candidate.model.trim() : null;
20159
+ if (!id2 && !model) continue;
20160
+ const supportedReasoningEfforts = Array.isArray(candidate.supportedReasoningEfforts) ? candidate.supportedReasoningEfforts.flatMap((item) => {
20161
+ const reasoningEffort = objectOrNull(item)?.reasoningEffort;
20162
+ return typeof reasoningEffort === "string" && reasoningEffort.trim() ? [reasoningEffort.trim()] : [];
20163
+ }) : [];
20164
+ capabilities.push(Object.freeze({
20165
+ id: id2,
20166
+ model,
20167
+ supportedReasoningEfforts: Object.freeze(supportedReasoningEfforts)
20168
+ }));
20066
20169
  }
20067
20170
  cursor = typeof result2.nextCursor === "string" && result2.nextCursor ? result2.nextCursor : null;
20068
20171
  if (cursor && seen.has(cursor)) {
@@ -20075,6 +20178,10 @@ child.once('close', async () => {
20075
20178
  }
20076
20179
  if (cursor) seen.add(cursor);
20077
20180
  } while (cursor);
20181
+ return Object.freeze(capabilities);
20182
+ }
20183
+ requireModelCapability(capabilities, modelName, reasoningEffort) {
20184
+ const match = capabilities.find((candidate) => candidate.model === modelName || candidate.id === modelName);
20078
20185
  if (!match) {
20079
20186
  throw new CodexAppServerError({
20080
20187
  message: "The requested Codex model is unavailable.",
@@ -20083,8 +20190,7 @@ child.once('close', async () => {
20083
20190
  retryable: false
20084
20191
  });
20085
20192
  }
20086
- const efforts = Array.isArray(match.supportedReasoningEfforts) ? match.supportedReasoningEfforts.map((item) => objectOrNull(item)?.reasoningEffort) : [];
20087
- if (!efforts.includes(reasoningEffort)) {
20193
+ if (!match.supportedReasoningEfforts.includes(reasoningEffort)) {
20088
20194
  throw new CodexAppServerError({
20089
20195
  message: "The requested Codex reasoning effort is unavailable.",
20090
20196
  category: "model",
@@ -20093,7 +20199,30 @@ child.once('close', async () => {
20093
20199
  });
20094
20200
  }
20095
20201
  }
20202
+ async requireModel(modelName, reasoningEffort, deadlineAtMs, signal) {
20203
+ this.requireModelCapability(
20204
+ await this.readModelCapabilities(deadlineAtMs, signal),
20205
+ modelName,
20206
+ reasoningEffort
20207
+ );
20208
+ }
20096
20209
  async startThread(options) {
20210
+ if (options.signal?.aborted) {
20211
+ throw new CodexAppServerError({
20212
+ message: "Codex thread request was cancelled before dispatch.",
20213
+ category: "cancelled",
20214
+ code: "cancelled",
20215
+ retryable: false
20216
+ });
20217
+ }
20218
+ if (Date.now() >= options.deadlineAtMs) {
20219
+ throw new CodexAppServerError({
20220
+ message: "Codex thread request exceeded the immutable deadline before dispatch.",
20221
+ category: "timeout",
20222
+ code: "deadline_exceeded",
20223
+ retryable: false
20224
+ });
20225
+ }
20097
20226
  const result2 = await this.request("thread/start", {
20098
20227
  model: options.requestedModel,
20099
20228
  modelProvider: "openai",
@@ -20823,7 +20952,7 @@ import {
20823
20952
  import { randomBytes as randomBytes3 } from "node:crypto";
20824
20953
  import { tmpdir as tmpdir2 } from "node:os";
20825
20954
  import { isAbsolute as isAbsolute2, join as join4, relative as relative2, resolve as resolve3, sep as sep2 } from "node:path";
20826
- var INITIAL_CODEX_INFERENCE_MODEL, SUPPORTED_CODEX_REASONING_EFFORTS, MAX_PROMPT_BYTES2, tokenUsageReceiptSchema, turnResultReceiptSchema, terminalReceiptSchema, recoveryCheckpointSchema, recoveryFileSchema, FileCodexAttemptRecoveryStore, utf8Bytes, tomlString, permissionConfig, ensureDedicatedCodexHome, createIsolatedCodexAttemptResources, createIsolatedCodexHostResources, validateAttemptInput, isStrictDescendant, assertRecoveryResourceScope, removeRecoveredThread, confirmGuardianTerminatedForRecovery, reconcileCodexAttemptRecovery, CodexSubscriptionAdapter;
20955
+ var INITIAL_CODEX_INFERENCE_MODEL, SUPPORTED_CODEX_REASONING_EFFORTS, MAX_PROMPT_BYTES2, tokenUsageReceiptSchema, turnResultReceiptSchema, terminalReceiptSchema, recoveryCheckpointSchema, recoveryFileSchema, FileCodexAttemptRecoveryStore, utf8Bytes, assertAttemptActive, tomlString, permissionConfig, ensureDedicatedCodexHome, createIsolatedCodexAttemptResources, createIsolatedCodexHostResources, validateAttemptInput, isStrictDescendant, assertRecoveryResourceScope, removeRecoveredThread, confirmGuardianTerminatedForRecovery, reconcileCodexAttemptRecovery, CodexSubscriptionAdapter;
20827
20956
  var init_codex_adapter = __esm({
20828
20957
  "lib/inference-host/codex-adapter.ts"() {
20829
20958
  "use strict";
@@ -20971,6 +21100,24 @@ var init_codex_adapter = __esm({
20971
21100
  }
20972
21101
  };
20973
21102
  utf8Bytes = (value) => Buffer.byteLength(value, "utf8");
21103
+ assertAttemptActive = (deadlineAtMs, signal) => {
21104
+ if (signal?.aborted) {
21105
+ throw new CodexAppServerError({
21106
+ message: "Codex attempt was cancelled before dispatch.",
21107
+ category: "cancelled",
21108
+ code: "cancelled",
21109
+ retryable: false
21110
+ });
21111
+ }
21112
+ if (Date.now() >= deadlineAtMs) {
21113
+ throw new CodexAppServerError({
21114
+ message: "Codex attempt exceeded the immutable deadline before dispatch.",
21115
+ category: "timeout",
21116
+ code: "deadline_exceeded",
21117
+ retryable: false
21118
+ });
21119
+ }
21120
+ };
20974
21121
  tomlString = (value) => JSON.stringify(value);
20975
21122
  permissionConfig = (codexHome) => [
20976
21123
  'forced_login_method = "chatgpt"',
@@ -21335,6 +21482,7 @@ var init_codex_adapter = __esm({
21335
21482
  return {
21336
21483
  session,
21337
21484
  codexHome,
21485
+ capabilityPreflight: null,
21338
21486
  processToken,
21339
21487
  processReceiptPath,
21340
21488
  bootIdentity,
@@ -21417,6 +21565,65 @@ var init_codex_adapter = __esm({
21417
21565
  }
21418
21566
  await session.closePromise;
21419
21567
  }
21568
+ async requireDurableSessionCapability(durableSession, modelName, reasoningEffort, deadlineAtMs, signal) {
21569
+ assertAttemptActive(deadlineAtMs, signal);
21570
+ if (!durableSession.capabilityPreflight) {
21571
+ durableSession.capabilityPreflight = (async () => {
21572
+ try {
21573
+ await durableSession.session.requireManagedChatGptAuth(deadlineAtMs, signal);
21574
+ assertAttemptActive(deadlineAtMs, signal);
21575
+ return await durableSession.session.readModelCapabilities(deadlineAtMs, signal);
21576
+ } catch (error48) {
21577
+ try {
21578
+ await this.invalidateDurableSession(durableSession);
21579
+ } catch (invalidationError) {
21580
+ throw new CodexAppServerError({
21581
+ message: "Codex capability preflight failed and session shutdown was not confirmed.",
21582
+ category: "adapter",
21583
+ code: "capability_preflight_invalidation_unconfirmed",
21584
+ retryable: false,
21585
+ cause: new AggregateError([error48, invalidationError])
21586
+ });
21587
+ }
21588
+ throw error48;
21589
+ }
21590
+ })();
21591
+ }
21592
+ const preflight = durableSession.capabilityPreflight;
21593
+ const capabilities = await new Promise((resolve6, reject) => {
21594
+ let settled = false;
21595
+ const finish = (callback) => {
21596
+ if (settled) return;
21597
+ settled = true;
21598
+ clearTimeout(timer);
21599
+ signal?.removeEventListener("abort", onAbort);
21600
+ callback();
21601
+ };
21602
+ const onAbort = () => finish(() => reject(new CodexAppServerError({
21603
+ message: "Codex capability preflight wait was cancelled.",
21604
+ category: "cancelled",
21605
+ code: "cancelled",
21606
+ retryable: false
21607
+ })));
21608
+ const timer = setTimeout(() => finish(() => reject(new CodexAppServerError({
21609
+ message: "Codex capability preflight wait exceeded the immutable deadline.",
21610
+ category: "timeout",
21611
+ code: "deadline_exceeded",
21612
+ retryable: false
21613
+ }))), Math.max(1, deadlineAtMs - Date.now()));
21614
+ signal?.addEventListener("abort", onAbort, { once: true });
21615
+ if (signal?.aborted) {
21616
+ onAbort();
21617
+ return;
21618
+ }
21619
+ void preflight.then(
21620
+ (value) => finish(() => resolve6(value)),
21621
+ (error48) => finish(() => reject(error48))
21622
+ );
21623
+ });
21624
+ assertAttemptActive(deadlineAtMs, signal);
21625
+ durableSession.session.requireModelCapability(capabilities, modelName, reasoningEffort);
21626
+ }
21420
21627
  runAttempt(input) {
21421
21628
  const active = this.inFlightAttempts.get(input.attemptId);
21422
21629
  if (active) {
@@ -21647,13 +21854,14 @@ var init_codex_adapter = __esm({
21647
21854
  };
21648
21855
  latestCheckpoint = baseCheckpoint;
21649
21856
  await recoveryHooks?.save(baseCheckpoint);
21650
- await session.requireManagedChatGptAuth(input.deadlineAtMs, input.signal);
21651
- await session.requireModel(
21857
+ await this.requireDurableSessionCapability(
21858
+ sessionLease,
21652
21859
  input.requestedModel,
21653
21860
  input.requestedReasoningEffort,
21654
21861
  input.deadlineAtMs,
21655
21862
  input.signal
21656
21863
  );
21864
+ assertAttemptActive(input.deadlineAtMs, input.signal);
21657
21865
  const thread = await session.startThread({
21658
21866
  workspacePath: resources.workspacePath,
21659
21867
  systemPrompt: input.systemPrompt,
@@ -21708,6 +21916,7 @@ var init_codex_adapter = __esm({
21708
21916
  "rpc_rejected",
21709
21917
  "invalid_rpc_result",
21710
21918
  "rpc_timeout",
21919
+ "capability_preflight_invalidation_unconfirmed",
21711
21920
  "invalid_thread_provenance",
21712
21921
  "thread_cleanup_identity_missing",
21713
21922
  "thread_delete_unconfirmed"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vtxmacro/cli",
3
- "version": "2026.8.22",
3
+ "version": "2026.8.24",
4
4
  "description": "VTX Macro CLI, MCP server, and durable subscription inference host.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",