@vtxmacro/cli 2026.8.21 → 2026.8.23

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 +250 -55
  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.21",
41
+ package_version: "2026.8.23",
42
42
  codex_package_name: "@openai/codex",
43
43
  codex_version: "0.147.0",
44
44
  platforms: {
@@ -20047,11 +20047,27 @@ child.once('close', async () => {
20047
20047
  });
20048
20048
  }
20049
20049
  }
20050
- async requireModel(modelName, reasoningEffort, deadlineAtMs, signal) {
20050
+ async readModelCapabilities(deadlineAtMs, signal) {
20051
20051
  let cursor = null;
20052
20052
  const seen = /* @__PURE__ */ new Set();
20053
- let match = null;
20053
+ const capabilities = [];
20054
20054
  do {
20055
+ if (signal?.aborted) {
20056
+ throw new CodexAppServerError({
20057
+ message: "Codex model catalog request was cancelled before dispatch.",
20058
+ category: "cancelled",
20059
+ code: "cancelled",
20060
+ retryable: false
20061
+ });
20062
+ }
20063
+ if (Date.now() >= deadlineAtMs) {
20064
+ throw new CodexAppServerError({
20065
+ message: "Codex model catalog request exceeded the immutable deadline before dispatch.",
20066
+ category: "timeout",
20067
+ code: "deadline_exceeded",
20068
+ retryable: false
20069
+ });
20070
+ }
20055
20071
  const result2 = await this.request("model/list", {
20056
20072
  includeHidden: true,
20057
20073
  ...cursor ? { cursor } : {}
@@ -20062,7 +20078,19 @@ child.once('close', async () => {
20062
20078
  const data = Array.isArray(result2.data) ? result2.data : [];
20063
20079
  for (const raw of data) {
20064
20080
  const candidate = objectOrNull(raw);
20065
- if (candidate && (candidate.model === modelName || candidate.id === modelName)) match = candidate;
20081
+ if (!candidate) continue;
20082
+ const id2 = typeof candidate.id === "string" && candidate.id.trim() ? candidate.id.trim() : null;
20083
+ const model = typeof candidate.model === "string" && candidate.model.trim() ? candidate.model.trim() : null;
20084
+ if (!id2 && !model) continue;
20085
+ const supportedReasoningEfforts = Array.isArray(candidate.supportedReasoningEfforts) ? candidate.supportedReasoningEfforts.flatMap((item) => {
20086
+ const reasoningEffort = objectOrNull(item)?.reasoningEffort;
20087
+ return typeof reasoningEffort === "string" && reasoningEffort.trim() ? [reasoningEffort.trim()] : [];
20088
+ }) : [];
20089
+ capabilities.push(Object.freeze({
20090
+ id: id2,
20091
+ model,
20092
+ supportedReasoningEfforts: Object.freeze(supportedReasoningEfforts)
20093
+ }));
20066
20094
  }
20067
20095
  cursor = typeof result2.nextCursor === "string" && result2.nextCursor ? result2.nextCursor : null;
20068
20096
  if (cursor && seen.has(cursor)) {
@@ -20075,6 +20103,10 @@ child.once('close', async () => {
20075
20103
  }
20076
20104
  if (cursor) seen.add(cursor);
20077
20105
  } while (cursor);
20106
+ return Object.freeze(capabilities);
20107
+ }
20108
+ requireModelCapability(capabilities, modelName, reasoningEffort) {
20109
+ const match = capabilities.find((candidate) => candidate.model === modelName || candidate.id === modelName);
20078
20110
  if (!match) {
20079
20111
  throw new CodexAppServerError({
20080
20112
  message: "The requested Codex model is unavailable.",
@@ -20083,8 +20115,7 @@ child.once('close', async () => {
20083
20115
  retryable: false
20084
20116
  });
20085
20117
  }
20086
- const efforts = Array.isArray(match.supportedReasoningEfforts) ? match.supportedReasoningEfforts.map((item) => objectOrNull(item)?.reasoningEffort) : [];
20087
- if (!efforts.includes(reasoningEffort)) {
20118
+ if (!match.supportedReasoningEfforts.includes(reasoningEffort)) {
20088
20119
  throw new CodexAppServerError({
20089
20120
  message: "The requested Codex reasoning effort is unavailable.",
20090
20121
  category: "model",
@@ -20093,7 +20124,30 @@ child.once('close', async () => {
20093
20124
  });
20094
20125
  }
20095
20126
  }
20127
+ async requireModel(modelName, reasoningEffort, deadlineAtMs, signal) {
20128
+ this.requireModelCapability(
20129
+ await this.readModelCapabilities(deadlineAtMs, signal),
20130
+ modelName,
20131
+ reasoningEffort
20132
+ );
20133
+ }
20096
20134
  async startThread(options) {
20135
+ if (options.signal?.aborted) {
20136
+ throw new CodexAppServerError({
20137
+ message: "Codex thread request was cancelled before dispatch.",
20138
+ category: "cancelled",
20139
+ code: "cancelled",
20140
+ retryable: false
20141
+ });
20142
+ }
20143
+ if (Date.now() >= options.deadlineAtMs) {
20144
+ throw new CodexAppServerError({
20145
+ message: "Codex thread request exceeded the immutable deadline before dispatch.",
20146
+ category: "timeout",
20147
+ code: "deadline_exceeded",
20148
+ retryable: false
20149
+ });
20150
+ }
20097
20151
  const result2 = await this.request("thread/start", {
20098
20152
  model: options.requestedModel,
20099
20153
  modelProvider: "openai",
@@ -20823,7 +20877,7 @@ import {
20823
20877
  import { randomBytes as randomBytes3 } from "node:crypto";
20824
20878
  import { tmpdir as tmpdir2 } from "node:os";
20825
20879
  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;
20880
+ 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
20881
  var init_codex_adapter = __esm({
20828
20882
  "lib/inference-host/codex-adapter.ts"() {
20829
20883
  "use strict";
@@ -20971,6 +21025,24 @@ var init_codex_adapter = __esm({
20971
21025
  }
20972
21026
  };
20973
21027
  utf8Bytes = (value) => Buffer.byteLength(value, "utf8");
21028
+ assertAttemptActive = (deadlineAtMs, signal) => {
21029
+ if (signal?.aborted) {
21030
+ throw new CodexAppServerError({
21031
+ message: "Codex attempt was cancelled before dispatch.",
21032
+ category: "cancelled",
21033
+ code: "cancelled",
21034
+ retryable: false
21035
+ });
21036
+ }
21037
+ if (Date.now() >= deadlineAtMs) {
21038
+ throw new CodexAppServerError({
21039
+ message: "Codex attempt exceeded the immutable deadline before dispatch.",
21040
+ category: "timeout",
21041
+ code: "deadline_exceeded",
21042
+ retryable: false
21043
+ });
21044
+ }
21045
+ };
20974
21046
  tomlString = (value) => JSON.stringify(value);
20975
21047
  permissionConfig = (codexHome) => [
20976
21048
  'forced_login_method = "chatgpt"',
@@ -21308,6 +21380,7 @@ var init_codex_adapter = __esm({
21308
21380
  CodexSubscriptionAdapter = class {
21309
21381
  constructor(dependencies = {}) {
21310
21382
  this.inFlightAttempts = /* @__PURE__ */ new Map();
21383
+ this.attemptCleanups = /* @__PURE__ */ new Map();
21311
21384
  this.durableSession = null;
21312
21385
  this.durableSessionStart = null;
21313
21386
  this.closing = false;
@@ -21334,6 +21407,7 @@ var init_codex_adapter = __esm({
21334
21407
  return {
21335
21408
  session,
21336
21409
  codexHome,
21410
+ capabilityPreflight: null,
21337
21411
  processToken,
21338
21412
  processReceiptPath,
21339
21413
  bootIdentity,
@@ -21416,6 +21490,65 @@ var init_codex_adapter = __esm({
21416
21490
  }
21417
21491
  await session.closePromise;
21418
21492
  }
21493
+ async requireDurableSessionCapability(durableSession, modelName, reasoningEffort, deadlineAtMs, signal) {
21494
+ assertAttemptActive(deadlineAtMs, signal);
21495
+ if (!durableSession.capabilityPreflight) {
21496
+ durableSession.capabilityPreflight = (async () => {
21497
+ try {
21498
+ await durableSession.session.requireManagedChatGptAuth(deadlineAtMs, signal);
21499
+ assertAttemptActive(deadlineAtMs, signal);
21500
+ return await durableSession.session.readModelCapabilities(deadlineAtMs, signal);
21501
+ } catch (error48) {
21502
+ try {
21503
+ await this.invalidateDurableSession(durableSession);
21504
+ } catch (invalidationError) {
21505
+ throw new CodexAppServerError({
21506
+ message: "Codex capability preflight failed and session shutdown was not confirmed.",
21507
+ category: "adapter",
21508
+ code: "capability_preflight_invalidation_unconfirmed",
21509
+ retryable: false,
21510
+ cause: new AggregateError([error48, invalidationError])
21511
+ });
21512
+ }
21513
+ throw error48;
21514
+ }
21515
+ })();
21516
+ }
21517
+ const preflight = durableSession.capabilityPreflight;
21518
+ const capabilities = await new Promise((resolve6, reject) => {
21519
+ let settled = false;
21520
+ const finish = (callback) => {
21521
+ if (settled) return;
21522
+ settled = true;
21523
+ clearTimeout(timer);
21524
+ signal?.removeEventListener("abort", onAbort);
21525
+ callback();
21526
+ };
21527
+ const onAbort = () => finish(() => reject(new CodexAppServerError({
21528
+ message: "Codex capability preflight wait was cancelled.",
21529
+ category: "cancelled",
21530
+ code: "cancelled",
21531
+ retryable: false
21532
+ })));
21533
+ const timer = setTimeout(() => finish(() => reject(new CodexAppServerError({
21534
+ message: "Codex capability preflight wait exceeded the immutable deadline.",
21535
+ category: "timeout",
21536
+ code: "deadline_exceeded",
21537
+ retryable: false
21538
+ }))), Math.max(1, deadlineAtMs - Date.now()));
21539
+ signal?.addEventListener("abort", onAbort, { once: true });
21540
+ if (signal?.aborted) {
21541
+ onAbort();
21542
+ return;
21543
+ }
21544
+ void preflight.then(
21545
+ (value) => finish(() => resolve6(value)),
21546
+ (error48) => finish(() => reject(error48))
21547
+ );
21548
+ });
21549
+ assertAttemptActive(deadlineAtMs, signal);
21550
+ durableSession.session.requireModelCapability(capabilities, modelName, reasoningEffort);
21551
+ }
21419
21552
  runAttempt(input) {
21420
21553
  const active = this.inFlightAttempts.get(input.attemptId);
21421
21554
  if (active) {
@@ -21430,15 +21563,21 @@ var init_codex_adapter = __esm({
21430
21563
  }
21431
21564
  return active.promise;
21432
21565
  }
21433
- const promise2 = this.executeAttempt(input).finally(() => {
21434
- if (this.inFlightAttempts.get(input.attemptId)?.promise === promise2) {
21435
- this.inFlightAttempts.delete(input.attemptId);
21436
- }
21437
- });
21566
+ const promise2 = this.executeAttempt(input);
21438
21567
  this.inFlightAttempts.set(input.attemptId, {
21439
21568
  inputSha256: input.inputSha256,
21440
21569
  promise: promise2
21441
21570
  });
21571
+ void promise2.then(async () => {
21572
+ await this.attemptCleanups.get(input.attemptId)?.catch(() => void 0);
21573
+ if (this.inFlightAttempts.get(input.attemptId)?.promise === promise2) {
21574
+ this.inFlightAttempts.delete(input.attemptId);
21575
+ }
21576
+ }, () => {
21577
+ if (this.inFlightAttempts.get(input.attemptId)?.promise === promise2) {
21578
+ this.inFlightAttempts.delete(input.attemptId);
21579
+ }
21580
+ }).catch(() => void 0);
21442
21581
  return promise2;
21443
21582
  }
21444
21583
  async acknowledgeAttempt(attemptId) {
@@ -21450,8 +21589,27 @@ var init_codex_adapter = __esm({
21450
21589
  retryable: false
21451
21590
  });
21452
21591
  }
21592
+ const activeCleanup = this.attemptCleanups.get(attemptId);
21593
+ if (activeCleanup) {
21594
+ try {
21595
+ await activeCleanup;
21596
+ } catch (error48) {
21597
+ throw new CodexAppServerError({
21598
+ message: "Codex attempt cleanup could not be confirmed.",
21599
+ category: "adapter",
21600
+ code: "attempt_cleanup_unconfirmed",
21601
+ retryable: false,
21602
+ cause: error48
21603
+ });
21604
+ }
21605
+ }
21453
21606
  const recoveryHooks = this.dependencies.recoveryHooks;
21454
- if (!recoveryHooks) return;
21607
+ if (!recoveryHooks) {
21608
+ if (activeCleanup && this.attemptCleanups.get(attemptId) === activeCleanup) {
21609
+ this.attemptCleanups.delete(attemptId);
21610
+ }
21611
+ return;
21612
+ }
21455
21613
  const checkpoint = await recoveryHooks.load(attemptId);
21456
21614
  if (checkpoint && !checkpoint.cleanupConfirmed) {
21457
21615
  throw new CodexAppServerError({
@@ -21479,6 +21637,9 @@ var init_codex_adapter = __esm({
21479
21637
  }
21480
21638
  }
21481
21639
  await recoveryHooks.clear(attemptId);
21640
+ if (activeCleanup && this.attemptCleanups.get(attemptId) === activeCleanup) {
21641
+ this.attemptCleanups.delete(attemptId);
21642
+ }
21482
21643
  }
21483
21644
  async close() {
21484
21645
  if (!this.adapterClosePromise) {
@@ -21497,8 +21658,29 @@ var init_codex_adapter = __esm({
21497
21658
  await Promise.allSettled(
21498
21659
  [...this.inFlightAttempts.values()].map((attempt) => attempt.promise)
21499
21660
  );
21661
+ await Promise.allSettled(
21662
+ [...this.attemptCleanups.values()]
21663
+ );
21664
+ let unconfirmedReceiptPaths = /* @__PURE__ */ new Set();
21665
+ const recoveryHooks = this.dependencies.recoveryHooks;
21666
+ if (recoveryHooks) {
21667
+ if (!recoveryHooks.loadAll) {
21668
+ unconfirmedReceiptPaths = null;
21669
+ } else {
21670
+ try {
21671
+ const checkpoints = await recoveryHooks.loadAll();
21672
+ unconfirmedReceiptPaths = new Set(
21673
+ Object.values(checkpoints).filter((checkpoint) => !checkpoint.cleanupConfirmed && checkpoint.processReceiptPath !== null).map((checkpoint) => resolve3(checkpoint.processReceiptPath))
21674
+ );
21675
+ } catch {
21676
+ unconfirmedReceiptPaths = null;
21677
+ }
21678
+ }
21679
+ }
21500
21680
  for (const session of sessions) {
21501
- if (session.processReceiptPath) await rm3(session.processReceiptPath, { force: true });
21681
+ if (session.processReceiptPath && unconfirmedReceiptPaths !== null && !unconfirmedReceiptPaths.has(resolve3(session.processReceiptPath))) {
21682
+ await rm3(session.processReceiptPath, { force: true });
21683
+ }
21502
21684
  }
21503
21685
  })();
21504
21686
  }
@@ -21597,13 +21779,14 @@ var init_codex_adapter = __esm({
21597
21779
  };
21598
21780
  latestCheckpoint = baseCheckpoint;
21599
21781
  await recoveryHooks?.save(baseCheckpoint);
21600
- await session.requireManagedChatGptAuth(input.deadlineAtMs, input.signal);
21601
- await session.requireModel(
21782
+ await this.requireDurableSessionCapability(
21783
+ sessionLease,
21602
21784
  input.requestedModel,
21603
21785
  input.requestedReasoningEffort,
21604
21786
  input.deadlineAtMs,
21605
21787
  input.signal
21606
21788
  );
21789
+ assertAttemptActive(input.deadlineAtMs, input.signal);
21607
21790
  const thread = await session.startThread({
21608
21791
  workspacePath: resources.workspacePath,
21609
21792
  systemPrompt: input.systemPrompt,
@@ -21651,8 +21834,6 @@ var init_codex_adapter = __esm({
21651
21834
  terminal: { kind: "completed", result: result2 }
21652
21835
  };
21653
21836
  await recoveryHooks?.save(latestCheckpoint);
21654
- await session.deleteThread(thread.threadId);
21655
- threadId = null;
21656
21837
  return result2;
21657
21838
  } catch (error48) {
21658
21839
  caughtError = error48;
@@ -21660,6 +21841,7 @@ var init_codex_adapter = __esm({
21660
21841
  "rpc_rejected",
21661
21842
  "invalid_rpc_result",
21662
21843
  "rpc_timeout",
21844
+ "capability_preflight_invalidation_unconfirmed",
21663
21845
  "invalid_thread_provenance",
21664
21846
  "thread_cleanup_identity_missing",
21665
21847
  "thread_delete_unconfirmed"
@@ -21732,50 +21914,63 @@ var init_codex_adapter = __esm({
21732
21914
  }
21733
21915
  throw classified;
21734
21916
  } finally {
21735
- let cleanupError = sessionInvalidationError;
21736
- if (session && threadId) {
21737
- try {
21738
- await session.deleteThread(threadId);
21739
- } catch (error48) {
21740
- cleanupError = error48;
21917
+ const cleanup = async () => {
21918
+ let cleanupError = sessionInvalidationError;
21919
+ if (session && threadId) {
21920
+ try {
21921
+ await session.deleteThread(threadId);
21922
+ } catch (error48) {
21923
+ cleanupError = error48;
21924
+ }
21741
21925
  }
21742
- }
21743
- if (sessionLease && cleanupError) {
21744
- try {
21745
- await this.invalidateDurableSession(sessionLease);
21746
- } catch (error48) {
21747
- cleanupError ??= error48;
21926
+ if (sessionLease && cleanupError) {
21927
+ try {
21928
+ await this.invalidateDurableSession(sessionLease);
21929
+ } catch (error48) {
21930
+ cleanupError ??= error48;
21931
+ }
21748
21932
  }
21749
- }
21750
- if (resources && cleanupError === null) {
21751
- try {
21752
- await resources.cleanup();
21753
- } catch (error48) {
21754
- cleanupError = error48;
21933
+ if (resources && cleanupError === null) {
21934
+ try {
21935
+ await resources.cleanup();
21936
+ } catch (error48) {
21937
+ cleanupError = error48;
21938
+ }
21755
21939
  }
21756
- }
21757
- if (latestCheckpoint && recoveryHooks && cleanupError === null) {
21758
- latestCheckpoint = {
21759
- ...latestCheckpoint,
21760
- processState: latestCheckpoint.processToken ? sessionLease?.terminated ? "terminated" : "running" : "unmanaged",
21761
- cleanupConfirmed: true
21762
- };
21940
+ if (latestCheckpoint && recoveryHooks && cleanupError === null) {
21941
+ latestCheckpoint = {
21942
+ ...latestCheckpoint,
21943
+ processState: latestCheckpoint.processToken ? sessionLease?.terminated ? "terminated" : "running" : "unmanaged",
21944
+ cleanupConfirmed: true
21945
+ };
21946
+ try {
21947
+ await recoveryHooks.save(latestCheckpoint);
21948
+ } catch (error48) {
21949
+ cleanupError = error48;
21950
+ }
21951
+ }
21952
+ if (cleanupError) {
21953
+ throw new CodexAppServerError({
21954
+ message: "Codex attempt cleanup could not be confirmed.",
21955
+ category: "adapter",
21956
+ code: "attempt_cleanup_unconfirmed",
21957
+ retryable: false,
21958
+ dispatchOutcome: currentDispatchOutcome,
21959
+ cause: cleanupError
21960
+ });
21961
+ }
21962
+ };
21963
+ if (completedResult && caughtError === null) {
21964
+ const cleanupPromise = cleanup();
21965
+ void cleanupPromise.catch(() => void 0);
21966
+ this.attemptCleanups.set(input.attemptId, cleanupPromise);
21967
+ } else {
21763
21968
  try {
21764
- await recoveryHooks.save(latestCheckpoint);
21969
+ await cleanup();
21765
21970
  } catch (error48) {
21766
- cleanupError = error48;
21971
+ if (caughtError === null) throw error48;
21767
21972
  }
21768
21973
  }
21769
- if (cleanupError && caughtError === null) {
21770
- throw new CodexAppServerError({
21771
- message: "Codex attempt cleanup could not be confirmed.",
21772
- category: "adapter",
21773
- code: "attempt_cleanup_unconfirmed",
21774
- retryable: false,
21775
- dispatchOutcome: currentDispatchOutcome,
21776
- cause: cleanupError
21777
- });
21778
- }
21779
21974
  }
21780
21975
  }
21781
21976
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vtxmacro/cli",
3
- "version": "2026.8.21",
3
+ "version": "2026.8.23",
4
4
  "description": "VTX Macro CLI, MCP server, and durable subscription inference host.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",