oh-my-opencode 4.16.1 → 4.16.3

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 (151) hide show
  1. package/.agents/skills/pre-publish-review/SKILL.md +3 -0
  2. package/README.md +2 -2
  3. package/dist/agents/hephaestus/agent.d.ts +1 -1
  4. package/dist/agents/hephaestus/gpt-5-6.d.ts +2 -0
  5. package/dist/agents/momus-gpt-5-6.d.ts +1 -0
  6. package/dist/agents/types.d.ts +2 -0
  7. package/dist/cli/index.js +800 -536
  8. package/dist/cli-node/index.js +800 -536
  9. package/dist/features/background-agent/error-classifier.d.ts +5 -0
  10. package/dist/features/background-agent/parent-wake-dedupe.d.ts +1 -0
  11. package/dist/features/background-agent/parent-wake-flush-runner.d.ts +2 -0
  12. package/dist/features/background-agent/parent-wake-prompt-dispatch.d.ts +1 -0
  13. package/dist/features/builtin-commands/templates/refactor-sections/intro-and-analysis.d.ts +1 -1
  14. package/dist/features/builtin-commands/templates/remove-ai-slops.d.ts +1 -1
  15. package/dist/index.js +464 -54
  16. package/dist/shared/live-server-route.d.ts +1 -1
  17. package/dist/skills/review-work/SKILL.md +4 -2
  18. package/dist/skills/start-work/SKILL.md +2 -0
  19. package/dist/skills/ulw-plan/references/full-workflow.md +1 -1
  20. package/dist/skills/ulw-research/SKILL.md +5 -3
  21. package/dist/skills/visual-qa/SKILL.md +1 -1
  22. package/dist/tui.js +125 -13
  23. package/package.json +13 -13
  24. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  25. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +398 -246
  26. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  27. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  28. package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
  29. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  30. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  31. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  32. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  33. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  34. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  35. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  36. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  37. package/packages/omo-codex/plugin/components/rules/bundled-rules/{hephaestus.md → hephaestus/gpt-5.5.md} +1 -1
  38. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-5.6.md +93 -0
  39. package/packages/omo-codex/plugin/components/rules/dist/cli.js +43 -24
  40. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  41. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  42. package/packages/omo-codex/plugin/components/rules/src/codex-hook.ts +2 -1
  43. package/packages/omo-codex/plugin/components/rules/src/dynamic-target-fingerprints.ts +15 -6
  44. package/packages/omo-codex/plugin/components/rules/src/rules-engine-factory.ts +7 -2
  45. package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +2 -2
  46. package/packages/omo-codex/plugin/components/rules/test/codex-hook.test.ts +32 -0
  47. package/packages/omo-codex/plugin/components/rules/test/hephaestus-model-variant.test.ts +106 -0
  48. package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +1 -1
  49. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
  50. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  51. package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +1 -1
  52. package/packages/omo-codex/plugin/components/teammode/AGENTS.md +12 -9
  53. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  54. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  55. package/packages/omo-codex/plugin/components/teammode/skills/teammode/SKILL.md +136 -76
  56. package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-guide.mjs +94 -23
  57. package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-state.mjs +94 -14
  58. package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-transport.mjs +55 -0
  59. package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team.mjs +72 -18
  60. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +23 -0
  61. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  62. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  63. package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +24 -41
  64. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-clone-fidelity-reviewer.toml +1 -1
  65. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-code-reviewer.toml +1 -1
  66. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-executor.toml +2 -2
  67. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-gate-reviewer.toml +1 -1
  68. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-qa-executor.toml +1 -1
  69. package/packages/omo-codex/plugin/components/ultrawork/agents/librarian.toml +21 -49
  70. package/packages/omo-codex/plugin/components/ultrawork/agents/metis.toml +17 -29
  71. package/packages/omo-codex/plugin/components/ultrawork/agents/momus.toml +20 -50
  72. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +18 -39
  73. package/packages/omo-codex/plugin/components/ultrawork/directive.md +1 -0
  74. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  75. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  76. package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +1 -0
  77. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +2 -0
  78. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +3 -1
  79. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +1 -0
  80. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +2 -2
  81. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  82. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +2 -0
  83. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +1 -1
  84. package/packages/omo-codex/plugin/components/ulw-loop/test/skill-contract.test.ts +1 -1
  85. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  86. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  87. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  88. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  89. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  90. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  91. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  92. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  93. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  94. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  95. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  96. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  97. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  98. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  99. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  100. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
  101. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +1 -1
  102. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  103. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  104. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  105. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  106. package/packages/omo-codex/plugin/package-lock.json +13 -13
  107. package/packages/omo-codex/plugin/package.json +1 -1
  108. package/packages/omo-codex/plugin/scripts/auto-update.mjs +73 -19
  109. package/packages/omo-codex/plugin/scripts/entry-guard.mjs +26 -0
  110. package/packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs +3 -1
  111. package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +221 -20
  112. package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +71 -3
  113. package/packages/omo-codex/plugin/scripts/migrate-codex-config.mjs +35 -7
  114. package/packages/omo-codex/plugin/scripts/migrate-omo-sot.mjs +2 -2
  115. package/packages/omo-codex/plugin/scripts/sync-hook-status-messages.mjs +2 -2
  116. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +7 -5
  117. package/packages/omo-codex/plugin/scripts/sync-version.mjs +4 -2
  118. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +2 -2
  119. package/packages/omo-codex/plugin/skills/refactor/SKILL.md +2 -2
  120. package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +2 -2
  121. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +2 -2
  122. package/packages/omo-codex/plugin/skills/start-work/SKILL.md +2 -2
  123. package/packages/omo-codex/plugin/skills/teammode/SKILL.md +136 -76
  124. package/packages/omo-codex/plugin/skills/teammode/scripts/team-guide.mjs +94 -23
  125. package/packages/omo-codex/plugin/skills/teammode/scripts/team-state.mjs +94 -14
  126. package/packages/omo-codex/plugin/skills/teammode/scripts/team-transport.mjs +55 -0
  127. package/packages/omo-codex/plugin/skills/teammode/scripts/team.mjs +72 -18
  128. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +1 -0
  129. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +2 -0
  130. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +1 -1
  131. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +2 -0
  132. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +3 -1
  133. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +3 -3
  134. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +3 -3
  135. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +47 -1
  136. package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +1 -1
  137. package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +4 -2
  138. package/packages/omo-codex/plugin/test/auto-update-restart-notice.test.mjs +33 -0
  139. package/packages/omo-codex/plugin/test/auto-update.test.mjs +35 -1
  140. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +412 -19
  141. package/packages/omo-codex/plugin/test/multi-agent-v2-regression.test.mjs +71 -0
  142. package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +65 -0
  143. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +13 -4
  144. package/packages/omo-codex/plugin/test/teammode-transport.test.mjs +345 -0
  145. package/packages/omo-codex/scripts/install-dist/install-local.mjs +436 -284
  146. package/packages/omo-codex/scripts/install-generated-bundle.test.mjs +111 -1
  147. package/packages/shared-skills/skills/review-work/SKILL.md +4 -2
  148. package/packages/shared-skills/skills/start-work/SKILL.md +2 -0
  149. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +1 -1
  150. package/packages/shared-skills/skills/ulw-research/SKILL.md +5 -3
  151. package/packages/shared-skills/skills/visual-qa/SKILL.md +1 -1
@@ -95,21 +95,21 @@ var init_atomic_write = __esm(() => {
95
95
  });
96
96
 
97
97
  // packages/telemetry-core/src/activity-state.ts
98
- import { existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync } from "node:fs";
99
- import { basename as basename6, join as join31 } from "node:path";
98
+ import { existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync as readFileSync2 } from "node:fs";
99
+ import { basename as basename6, join as join33 } from "node:path";
100
100
  function resolveTelemetryStateDir(product, options = {}) {
101
101
  const dataDir = resolveXdgDataDir(product.cacheDirName, {
102
102
  env: options.env,
103
103
  osProvider: options.osProvider
104
104
  });
105
- const xdgStateDir = options.env?.XDG_DATA_HOME === undefined ? undefined : join31(options.env.XDG_DATA_HOME, product.cacheDirName);
105
+ const xdgStateDir = options.env?.XDG_DATA_HOME === undefined ? undefined : join33(options.env.XDG_DATA_HOME, product.cacheDirName);
106
106
  if (dataDir === xdgStateDir || xdgStateDir === undefined && basename6(dataDir) === product.cacheDirName) {
107
107
  return dataDir;
108
108
  }
109
- return join31(dataDir, product.cacheDirName);
109
+ return join33(dataDir, product.cacheDirName);
110
110
  }
111
111
  function getTelemetryActivityStateFilePath(stateDir) {
112
- return join31(stateDir, POSTHOG_ACTIVITY_STATE_FILE);
112
+ return join33(stateDir, POSTHOG_ACTIVITY_STATE_FILE);
113
113
  }
114
114
  function getDailyActiveCaptureState(input) {
115
115
  const state = readPostHogActivityState(input.stateDir, input.diagnostics);
@@ -138,7 +138,7 @@ function readPostHogActivityState(stateDir, diagnostics) {
138
138
  return {};
139
139
  }
140
140
  try {
141
- const stateContent = readFileSync(stateFilePath, "utf-8");
141
+ const stateContent = readFileSync2(stateFilePath, "utf-8");
142
142
  const stateJson = JSON.parse(stateContent);
143
143
  if (!isPostHogActivityState(stateJson)) {
144
144
  return {};
@@ -179,10 +179,10 @@ var init_activity_state = __esm(() => {
179
179
  var DEFAULT_POSTHOG_HOST = "https://us.i.posthog.com", DEFAULT_POSTHOG_API_KEY = "phc_CFJhj5HyvA62QPhvyaUCtaq23aUfznnijg5VaaGkNk74";
180
180
 
181
181
  // packages/telemetry-core/src/diagnostics.ts
182
- import { appendFileSync, existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync2 } from "node:fs";
183
- import { join as join32 } from "node:path";
182
+ import { appendFileSync, existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync3 } from "node:fs";
183
+ import { join as join34 } from "node:path";
184
184
  function getTelemetryDiagnosticsFilePath(diagnosticsDir) {
185
- return join32(diagnosticsDir, DIAGNOSTICS_FILE_NAME);
185
+ return join34(diagnosticsDir, DIAGNOSTICS_FILE_NAME);
186
186
  }
187
187
  function writeTelemetryDiagnostic(input, options) {
188
188
  const now = options.now ?? new Date;
@@ -205,7 +205,7 @@ function cleanupTelemetryDiagnostics(options) {
205
205
  }
206
206
  try {
207
207
  const cutoffMs = (options.now ?? new Date).getTime() - DIAGNOSTICS_RETENTION_MS;
208
- const retainedLines = trimToMaxBytes(readFileSync2(diagnosticsFilePath, "utf-8").split(`
208
+ const retainedLines = trimToMaxBytes(readFileSync3(diagnosticsFilePath, "utf-8").split(`
209
209
  `).filter((line) => shouldRetainLine(line, cutoffMs)));
210
210
  writeFileAtomically(diagnosticsFilePath, retainedLines.length === 0 ? "" : `${retainedLines.join(`
211
211
  `)}
@@ -257,7 +257,7 @@ function shouldRetainLine(line, cutoffMs) {
257
257
  function parseDiagnosticLine(line) {
258
258
  try {
259
259
  const parsed = JSON.parse(line);
260
- if (!isRecord(parsed)) {
260
+ if (!isRecord2(parsed)) {
261
261
  return null;
262
262
  }
263
263
  return parsed;
@@ -268,7 +268,7 @@ function parseDiagnosticLine(line) {
268
268
  throw error;
269
269
  }
270
270
  }
271
- function isRecord(value) {
271
+ function isRecord2(value) {
272
272
  return value !== null && typeof value === "object" && !Array.isArray(value);
273
273
  }
274
274
  function trimToMaxBytes(lines) {
@@ -348,7 +348,7 @@ function getTelemetryDistinctId(machineIdPrefix, osProvider = getDefaultTelemetr
348
348
  var init_machine_id = () => {};
349
349
 
350
350
  // node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
351
- import { dirname as dirname9, posix, sep as sep7 } from "node:path";
351
+ import { dirname as dirname10, posix, sep as sep7 } from "node:path";
352
352
  function createModulerModifier() {
353
353
  const getModuleFromFileName = createGetModuleFromFilename();
354
354
  return async (frames) => {
@@ -357,7 +357,7 @@ function createModulerModifier() {
357
357
  return frames;
358
358
  };
359
359
  }
360
- function createGetModuleFromFilename(basePath = process.argv[1] ? dirname9(process.argv[1]) : process.cwd(), isWindows = sep7 === "\\") {
360
+ function createGetModuleFromFilename(basePath = process.argv[1] ? dirname10(process.argv[1]) : process.cwd(), isWindows = sep7 === "\\") {
361
361
  const normalizedBase = isWindows ? normalizeWindowsPath(basePath) : basePath;
362
362
  return (filename) => {
363
363
  if (!filename)
@@ -3378,7 +3378,7 @@ var init_context_lines_node = __esm(() => {
3378
3378
  });
3379
3379
 
3380
3380
  // node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/relative-path.node.mjs
3381
- import { isAbsolute as isAbsolute6, relative as relative4, sep as sep8 } from "node:path";
3381
+ import { isAbsolute as isAbsolute7, relative as relative4, sep as sep8 } from "node:path";
3382
3382
  function createRelativePathModifier(basePath = process.cwd()) {
3383
3383
  const isWindows = sep8 === "\\";
3384
3384
  const toUnix = (p) => isWindows ? p.replace(/\\/g, "/") : p;
@@ -3386,7 +3386,7 @@ function createRelativePathModifier(basePath = process.cwd()) {
3386
3386
  return async (frames) => {
3387
3387
  for (const frame of frames)
3388
3388
  if (!(!frame.filename || frame.filename.startsWith("node:") || frame.filename.startsWith("data:"))) {
3389
- if (isAbsolute6(frame.filename))
3389
+ if (isAbsolute7(frame.filename))
3390
3390
  frame.filename = toUnix(relative4(normalizedBase, toUnix(frame.filename)));
3391
3391
  }
3392
3392
  return frames;
@@ -5903,7 +5903,7 @@ var package_default;
5903
5903
  var init_package = __esm(() => {
5904
5904
  package_default = {
5905
5905
  name: "@oh-my-opencode/omo-codex",
5906
- version: "4.16.1",
5906
+ version: "4.16.2",
5907
5907
  type: "module",
5908
5908
  private: true,
5909
5909
  description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
@@ -6123,7 +6123,7 @@ var init_telemetry = __esm(() => {
6123
6123
 
6124
6124
  // packages/omo-codex/src/install/install-local-cli.ts
6125
6125
  import { readFile as readFile21 } from "node:fs/promises";
6126
- import { dirname as dirname11, join as join37, resolve as resolve10 } from "node:path";
6126
+ import { dirname as dirname12, join as join39, resolve as resolve10 } from "node:path";
6127
6127
  import { fileURLToPath as fileURLToPath2 } from "node:url";
6128
6128
 
6129
6129
  // packages/utils/src/runtime/spawn.ts
@@ -6456,7 +6456,7 @@ var defaultRunCommand = async (command, args, options) => {
6456
6456
  };
6457
6457
 
6458
6458
  // packages/omo-codex/src/install/install-codex.ts
6459
- import { join as join33, resolve as resolve9 } from "node:path";
6459
+ import { join as join35, resolve as resolve9 } from "node:path";
6460
6460
  import { existsSync as existsSync7 } from "node:fs";
6461
6461
  import { homedir as homedir2 } from "node:os";
6462
6462
 
@@ -7818,7 +7818,7 @@ async function shouldBuildSourcePackages(repoRoot) {
7818
7818
 
7819
7819
  // packages/omo-codex/src/install/codex-config-toml.ts
7820
7820
  import { mkdir as mkdir5, readFile as readFile11 } from "node:fs/promises";
7821
- import { dirname as dirname7 } from "node:path";
7821
+ import { dirname as dirname8 } from "node:path";
7822
7822
 
7823
7823
  // packages/omo-codex/src/install/toml-section-editor.ts
7824
7824
  function findTomlSection(config, header) {
@@ -8655,30 +8655,87 @@ function isRootSetting2(line, key) {
8655
8655
  }
8656
8656
 
8657
8657
  // packages/omo-codex/src/install/codex-multi-agent-v2-config.ts
8658
+ import { readFileSync } from "node:fs";
8659
+ import { dirname as dirname7, isAbsolute as isAbsolute6, join as join18 } from "node:path";
8658
8660
  var CODEX_AGENTS_HEADER = "agents";
8659
8661
  var CODEX_MULTI_AGENT_V2_HEADER = "features.multi_agent_v2";
8660
8662
  var CODEX_SUBAGENT_THREAD_LIMIT = 1000;
8661
- function ensureCodexMultiAgentV2Config(config) {
8663
+ function ensureCodexMultiAgentV2Config(config, options = {}) {
8662
8664
  const featureFlag = removeFeatureFlagSetting(config, "multi_agent_v2");
8663
- const agentsConfig = ensureAgentsMaxThreads(featureFlag.config);
8664
- const section = findTomlSection(agentsConfig, CODEX_MULTI_AGENT_V2_HEADER);
8665
+ const v2Preferred = options.multiAgentVersion === "v2";
8666
+ const modelKnown = options.multiAgentVersion != null || readRootModel(featureFlag.config) !== null;
8667
+ const agentsConfig = v2Preferred ? removeAgentsMaxThreads(featureFlag.config) : modelKnown ? ensureAgentsMaxThreads(featureFlag.config) : raiseExistingAgentsMaxThreads(featureFlag.config);
8665
8668
  const maxThreadsValue = CODEX_SUBAGENT_THREAD_LIMIT.toString();
8669
+ const preserveDisable = featureFlag.value === false && !v2Preferred;
8670
+ const featureConfig = preserveDisable ? setMultiAgentV2Disable(agentsConfig) : v2Preferred ? removeMultiAgentV2Disable(agentsConfig) : agentsConfig;
8671
+ const section = findTomlSection(featureConfig, CODEX_MULTI_AGENT_V2_HEADER);
8666
8672
  if (!section) {
8667
- const enabledSetting = featureFlag.value === false ? `enabled = false
8673
+ const enabledSetting = preserveDisable ? `enabled = false
8668
8674
  ` : "";
8669
- return appendBlock(agentsConfig, `[${CODEX_MULTI_AGENT_V2_HEADER}]
8675
+ return appendBlock(featureConfig, `[${CODEX_MULTI_AGENT_V2_HEADER}]
8670
8676
  ${enabledSetting}max_concurrent_threads_per_session = ${maxThreadsValue}
8671
8677
  `);
8672
8678
  }
8673
- const withPreservedDisable = featureFlag.value === false ? replaceOrInsertSetting(agentsConfig, section, "enabled", "false") : agentsConfig;
8674
- const updatedSection = featureFlag.value === false ? findTomlSection(withPreservedDisable, CODEX_MULTI_AGENT_V2_HEADER) : section;
8675
- if (!updatedSection) {
8676
- return appendBlock(withPreservedDisable, `[${CODEX_MULTI_AGENT_V2_HEADER}]
8677
- enabled = false
8678
- max_concurrent_threads_per_session = ${maxThreadsValue}
8679
- `);
8679
+ return replaceOrInsertSetting(featureConfig, section, "max_concurrent_threads_per_session", maxThreadsValue);
8680
+ }
8681
+ function resolveCodexMultiAgentVersion(config, configPath) {
8682
+ const model = readRootModel(config);
8683
+ if (model === null)
8684
+ return null;
8685
+ const catalogPath = resolveCatalogPath(readRootModelCatalogPath(config), configPath);
8686
+ const catalogVersion = readCatalogMultiAgentVersion(model, catalogPath);
8687
+ if (catalogVersion !== null)
8688
+ return catalogVersion;
8689
+ return /^gpt-5\.6\b/i.test(model) ? "v2" : null;
8690
+ }
8691
+ function resolveCatalogPath(configuredPath, configPath) {
8692
+ if (configuredPath === null)
8693
+ return join18(dirname7(configPath), "models_cache.json");
8694
+ return isAbsolute6(configuredPath) ? configuredPath : join18(dirname7(configPath), configuredPath);
8695
+ }
8696
+ function readCatalogMultiAgentVersion(model, cachePath) {
8697
+ let raw;
8698
+ try {
8699
+ raw = readFileSync(cachePath, "utf8");
8700
+ } catch {
8701
+ return null;
8702
+ }
8703
+ let cache;
8704
+ try {
8705
+ cache = JSON.parse(raw);
8706
+ } catch {
8707
+ return null;
8680
8708
  }
8681
- return replaceOrInsertSetting(withPreservedDisable, updatedSection, "max_concurrent_threads_per_session", maxThreadsValue);
8709
+ if (!isRecord(cache) || !Array.isArray(cache.models))
8710
+ return null;
8711
+ for (const entry of cache.models) {
8712
+ if (!isRecord(entry))
8713
+ continue;
8714
+ if (entry.slug !== model && entry.id !== model)
8715
+ continue;
8716
+ const version = entry.multi_agent_version;
8717
+ if (version === "v1" || version === "v2")
8718
+ return version;
8719
+ return null;
8720
+ }
8721
+ return null;
8722
+ }
8723
+ function readRootModel(config) {
8724
+ const double = config.match(/^\s*model\s*=\s*"([^"]+)"/m);
8725
+ if (double !== null)
8726
+ return double[1] ?? null;
8727
+ const single = config.match(/^\s*model\s*=\s*'([^']+)'/m);
8728
+ return single?.[1] ?? null;
8729
+ }
8730
+ function readRootModelCatalogPath(config) {
8731
+ const double = config.match(/^\s*model_catalog_json\s*=\s*"([^"]+)"/m);
8732
+ if (double !== null)
8733
+ return double[1] ?? null;
8734
+ const single = config.match(/^\s*model_catalog_json\s*=\s*'([^']+)'/m);
8735
+ return single?.[1] ?? null;
8736
+ }
8737
+ function isRecord(value) {
8738
+ return typeof value === "object" && value !== null && !Array.isArray(value);
8682
8739
  }
8683
8740
  function removeFeatureFlagSetting(config, featureName) {
8684
8741
  const section = findTomlSection(config, "features");
@@ -8699,6 +8756,36 @@ max_threads = ${maxThreadsValue}
8699
8756
  }
8700
8757
  return replaceOrInsertSetting(config, section, "max_threads", maxThreadsValue);
8701
8758
  }
8759
+ function removeAgentsMaxThreads(config) {
8760
+ const section = findTomlSection(config, CODEX_AGENTS_HEADER);
8761
+ if (!section)
8762
+ return config;
8763
+ if (!/^\s*max_threads\s*=/m.test(section.text))
8764
+ return config;
8765
+ return removeSetting(config, section, "max_threads");
8766
+ }
8767
+ function removeMultiAgentV2Disable(config) {
8768
+ const section = findTomlSection(config, CODEX_MULTI_AGENT_V2_HEADER);
8769
+ if (!section)
8770
+ return config;
8771
+ if (!/^\s*enabled\s*=\s*false(?:\s*#.*)?$/m.test(section.text))
8772
+ return config;
8773
+ return removeSetting(config, section, "enabled");
8774
+ }
8775
+ function setMultiAgentV2Disable(config) {
8776
+ const section = findTomlSection(config, CODEX_MULTI_AGENT_V2_HEADER);
8777
+ if (!section)
8778
+ return config;
8779
+ return replaceOrInsertSetting(config, section, "enabled", "false");
8780
+ }
8781
+ function raiseExistingAgentsMaxThreads(config) {
8782
+ const section = findTomlSection(config, CODEX_AGENTS_HEADER);
8783
+ if (!section)
8784
+ return config;
8785
+ if (!/^\s*max_threads\s*=/m.test(section.text))
8786
+ return config;
8787
+ return replaceOrInsertSetting(config, section, "max_threads", CODEX_SUBAGENT_THREAD_LIMIT.toString());
8788
+ }
8702
8789
  function readBooleanSetting(sectionText, key) {
8703
8790
  const match = new RegExp(`^\\s*${escapeRegExp(key)}\\s*=\\s*(true|false)\\s*(?:#.*)?$`, "m").exec(sectionText);
8704
8791
  if (!match)
@@ -8708,7 +8795,7 @@ function readBooleanSetting(sectionText, key) {
8708
8795
 
8709
8796
  // packages/omo-codex/src/install/codex-config-toml.ts
8710
8797
  async function updateCodexConfig(input) {
8711
- await mkdir5(dirname7(input.configPath), { recursive: true });
8798
+ await mkdir5(dirname8(input.configPath), { recursive: true });
8712
8799
  let config;
8713
8800
  try {
8714
8801
  config = await readFile11(input.configPath, "utf8");
@@ -8731,7 +8818,9 @@ async function updateCodexConfig(input) {
8731
8818
  config = ensureFeatureEnabled(config, "multi_agent");
8732
8819
  config = removeUnsupportedCodexMultiAgentModeConfig(config);
8733
8820
  config = ensureCodexReasoningConfig(config, await readCodexModelCatalog(input.repoRoot));
8734
- config = ensureCodexMultiAgentV2Config(config);
8821
+ config = ensureCodexMultiAgentV2Config(config, {
8822
+ multiAgentVersion: resolveCodexMultiAgentVersion(config, input.configPath)
8823
+ });
8735
8824
  if (input.autonomousPermissions === true)
8736
8825
  config = ensureAutonomousPermissions(config);
8737
8826
  if (!(input.preserveMarketplaceSource === true && hasMarketplaceBlock(config, input.marketplaceName))) {
@@ -8757,7 +8846,7 @@ function isMissingFileError(error) {
8757
8846
  // packages/omo-codex/src/install/codex-hook-trust.ts
8758
8847
  import { createHash } from "node:crypto";
8759
8848
  import { readFile as readFile12 } from "node:fs/promises";
8760
- import { join as join18 } from "node:path";
8849
+ import { join as join19 } from "node:path";
8761
8850
  var EVENT_LABELS = new Map([
8762
8851
  ["PreToolUse", "pre_tool_use"],
8763
8852
  ["PermissionRequest", "permission_request"],
@@ -8771,7 +8860,7 @@ var EVENT_LABELS = new Map([
8771
8860
  ["Stop", "stop"]
8772
8861
  ]);
8773
8862
  async function trustedHookStatesForPlugin(input) {
8774
- const manifestPath = join18(input.pluginRoot, ".codex-plugin", "plugin.json");
8863
+ const manifestPath = join19(input.pluginRoot, ".codex-plugin", "plugin.json");
8775
8864
  if (!await exists(manifestPath))
8776
8865
  return [];
8777
8866
  const manifest = JSON.parse(await readFile12(manifestPath, "utf8"));
@@ -8779,7 +8868,7 @@ async function trustedHookStatesForPlugin(input) {
8779
8868
  return [];
8780
8869
  const states = [];
8781
8870
  for (const hookPath of hookManifestPaths2(manifest.hooks)) {
8782
- const hooksPath = join18(input.pluginRoot, hookPath);
8871
+ const hooksPath = join19(input.pluginRoot, hookPath);
8783
8872
  if (!await exists(hooksPath))
8784
8873
  continue;
8785
8874
  const parsed = JSON.parse(await readFile12(hooksPath, "utf8"));
@@ -8904,207 +8993,125 @@ function toCodexResolution(resolution) {
8904
8993
  }
8905
8994
 
8906
8995
  // packages/omo-codex/src/install/link-cached-plugin-agents.ts
8907
- import { copyFile, lstat as lstat8, mkdir as mkdir6, readFile as readFile14, readdir as readdir6, rm as rm8, writeFile as writeFile6 } from "node:fs/promises";
8908
- import { basename as basename5, join as join20 } from "node:path";
8996
+ import { copyFile, lstat as lstat9, mkdir as mkdir6, readdir as readdir7, rm as rm8, writeFile as writeFile7 } from "node:fs/promises";
8997
+ import { basename as basename5, join as join22 } from "node:path";
8909
8998
 
8910
- // packages/omo-codex/src/install/retired-managed-agent-purge.ts
8911
- import { lstat as lstat7, readFile as readFile13, rm as rm7 } from "node:fs/promises";
8912
- import { join as join19 } from "node:path";
8913
- var RETIRED_MANAGED_AGENT_FILES = [
8914
- {
8915
- fileName: "codex-ultrawork-reviewer.toml",
8916
- requiredMarkers: [
8917
- 'name = "codex-ultrawork-reviewer"',
8918
- 'description = "Strict ultrawork verification reviewer.',
8919
- 'developer_instructions = """You are the ultrawork verification reviewer.'
8920
- ]
8921
- }
8922
- ];
8923
- async function purgeRetiredManagedAgentFiles(input) {
8924
- const agentsDir = join19(input.codexHome, "agents");
8925
- if (!await exists2(agentsDir))
8926
- return;
8927
- for (const retiredAgent of RETIRED_MANAGED_AGENT_FILES) {
8928
- const agentPath = join19(agentsDir, retiredAgent.fileName);
8929
- if (!await exists2(agentPath))
8930
- continue;
8931
- const agentStat = await lstat7(agentPath);
8932
- if (agentStat.isDirectory() && !agentStat.isSymbolicLink())
8933
- continue;
8934
- const content = await readTextIfExists(agentPath);
8935
- if (content === null || !hasRequiredMarkers(content, retiredAgent.requiredMarkers))
8936
- continue;
8937
- await rm7(agentPath, { force: true });
8938
- }
8939
- }
8940
- function hasRequiredMarkers(content, markers) {
8941
- return markers.every((marker) => content.includes(marker));
8942
- }
8943
- async function readTextIfExists(path) {
8944
- try {
8945
- return await readFile13(path, "utf8");
8946
- } catch (error) {
8947
- if (nodeErrorCode(error) === "ENOENT")
8948
- return null;
8949
- throw error;
8950
- }
8951
- }
8952
- async function exists2(path) {
8953
- try {
8954
- await lstat7(path);
8955
- return true;
8956
- } catch (error) {
8957
- if (nodeErrorCode(error) !== "ENOENT")
8958
- throw error;
8959
- return false;
8999
+ // packages/omo-codex/src/install/preserved-agent-settings.ts
9000
+ import { lstat as lstat7, readFile as readFile13, readdir as readdir6, writeFile as writeFile6 } from "node:fs/promises";
9001
+ import { join as join20 } from "node:path";
9002
+
9003
+ // packages/omo-codex/src/install/managed-agent-reasoning-defaults.ts
9004
+ var MANAGED_REASONING_DEFAULT_UPGRADES = new Map([
9005
+ [
9006
+ "explorer",
9007
+ {
9008
+ previous: { model: "gpt-5.4-mini", effort: "low" },
9009
+ current: { model: "gpt-5.6-terra", effort: "medium" }
9010
+ }
9011
+ ],
9012
+ [
9013
+ "librarian",
9014
+ {
9015
+ previous: { model: "gpt-5.4-mini", effort: "low" },
9016
+ current: { model: "gpt-5.6-terra", effort: "medium" }
9017
+ }
9018
+ ],
9019
+ [
9020
+ "momus",
9021
+ {
9022
+ previous: { model: "gpt-5.5", effort: "xhigh" },
9023
+ current: { model: "gpt-5.6-sol", effort: "ultra" }
9024
+ }
9025
+ ]
9026
+ ]);
9027
+ function resolveManagedAgentReasoning(input) {
9028
+ const upgrade = MANAGED_REASONING_DEFAULT_UPGRADES.get(input.agentName);
9029
+ if (upgrade !== undefined && input.preserved.model === upgrade.previous.model && input.preserved.effort === upgrade.previous.effort && input.bundledModel === upgrade.current.model && input.bundledEffort === upgrade.current.effort) {
9030
+ return upgrade.current.effort;
8960
9031
  }
8961
- }
8962
- function nodeErrorCode(error) {
8963
- if (!(error instanceof Error) || !("code" in error))
8964
- return null;
8965
- return typeof error.code === "string" ? error.code : null;
9032
+ return input.preserved.effort;
8966
9033
  }
8967
9034
 
8968
- // packages/omo-codex/src/install/link-cached-plugin-agents.ts
8969
- var MANIFEST_FILE = ".installed-agents.json";
9035
+ // packages/omo-codex/src/install/preserved-agent-settings.ts
8970
9036
  async function capturePreservedAgentReasoning(input) {
8971
9037
  const agentsDir = join20(input.codexHome, "agents");
8972
- if (!await exists3(agentsDir))
9038
+ if (!await exists2(agentsDir))
8973
9039
  return new Map;
8974
9040
  const preserved = new Map;
8975
9041
  const agentEntries = await readdir6(agentsDir, { withFileTypes: true });
8976
9042
  for (const entry of agentEntries) {
8977
9043
  if (!entry.name.endsWith(".toml"))
8978
9044
  continue;
8979
- const content = await readTextIfExists2(join20(agentsDir, entry.name));
9045
+ const content = await readTextIfExists(join20(agentsDir, entry.name));
8980
9046
  if (content === null)
8981
9047
  continue;
8982
9048
  const effort = extractReasoningEffort(content);
8983
- if (effort !== null)
8984
- preserved.set(agentNameFromToml(entry.name), effort);
9049
+ if (effort !== null) {
9050
+ preserved.set(agentNameFromToml(entry.name), {
9051
+ model: extractModel(content),
9052
+ effort
9053
+ });
9054
+ }
8985
9055
  }
8986
9056
  return preserved;
8987
9057
  }
8988
9058
  async function capturePreservedAgentServiceTier(input) {
8989
9059
  const agentsDir = join20(input.codexHome, "agents");
8990
- if (!await exists3(agentsDir))
9060
+ if (!await exists2(agentsDir))
8991
9061
  return new Map;
8992
9062
  const preserved = new Map;
8993
9063
  const agentEntries = await readdir6(agentsDir, { withFileTypes: true });
8994
9064
  for (const entry of agentEntries) {
8995
9065
  if (!entry.name.endsWith(".toml"))
8996
9066
  continue;
8997
- const content = await readTextIfExists2(join20(agentsDir, entry.name));
9067
+ const content = await readTextIfExists(join20(agentsDir, entry.name));
8998
9068
  if (content === null)
8999
9069
  continue;
9000
9070
  preserved.set(agentNameFromToml(entry.name), extractServiceTier(content));
9001
9071
  }
9002
9072
  return preserved;
9003
9073
  }
9004
- async function linkCachedPluginAgents(input) {
9005
- const bundledAgents = await discoverBundledAgents(input.pluginRoot);
9006
- await purgeRetiredManagedAgentFiles({ codexHome: input.codexHome });
9007
- if (bundledAgents.length === 0) {
9008
- await writeManifest(input.pluginRoot, []);
9009
- return [];
9010
- }
9011
- const agentsDir = join20(input.codexHome, "agents");
9012
- await mkdir6(agentsDir, { recursive: true });
9013
- const linked = [];
9014
- for (const agentPath of bundledAgents) {
9015
- const agentFileName = basename5(agentPath);
9016
- const agentName = agentNameFromToml(agentFileName);
9017
- const linkPath = join20(agentsDir, agentFileName);
9018
- await replaceWithCopy(linkPath, agentPath);
9019
- await restorePreservedReasoning({
9020
- agentName,
9021
- linkPath,
9022
- target: agentPath,
9023
- value: input.preservedReasoning?.get(agentName)
9024
- });
9025
- await restorePreservedServiceTier({
9026
- linkPath,
9027
- preserved: input.preservedServiceTier?.has(agentName) ?? false,
9028
- value: input.preservedServiceTier?.get(agentName) ?? null
9029
- });
9030
- linked.push({ name: agentFileName, path: linkPath, target: agentPath });
9031
- }
9032
- await writeManifest(input.pluginRoot, linked.map((entry) => entry.path));
9033
- return linked;
9034
- }
9035
- async function restorePreservedServiceTier(input) {
9036
- if (!input.preserved)
9074
+ async function restorePreservedReasoning(input) {
9075
+ if (input.value === undefined)
9037
9076
  return;
9038
- const content = await readFile14(input.linkPath, "utf8");
9039
- if (extractServiceTier(content) === input.value)
9077
+ const content = await readFile13(input.target, "utf8");
9078
+ const bundledEffort = extractReasoningEffort(content);
9079
+ const effort = resolveManagedAgentReasoning({
9080
+ agentName: input.agentName,
9081
+ bundledModel: extractModel(content),
9082
+ bundledEffort,
9083
+ preserved: input.value
9084
+ });
9085
+ if (bundledEffort === effort)
9040
9086
  return;
9041
- const replacement = replaceServiceTier(content, input.value);
9087
+ const replacement = replaceTopLevelStringSetting(content, "model_reasoning_effort", effort, { insertIfMissing: false });
9042
9088
  if (!replacement.replaced)
9043
9089
  return;
9044
9090
  await writeFile6(input.linkPath, replacement.content);
9045
9091
  }
9046
- async function discoverBundledAgents(pluginRoot) {
9047
- const componentsRoot = join20(pluginRoot, "components");
9048
- if (!await exists3(componentsRoot))
9049
- return [];
9050
- const componentEntries = await readdir6(componentsRoot, { withFileTypes: true });
9051
- const agents = [];
9052
- for (const entry of componentEntries) {
9053
- if (!entry.isDirectory())
9054
- continue;
9055
- const agentsRoot = join20(componentsRoot, entry.name, "agents");
9056
- if (!await exists3(agentsRoot))
9057
- continue;
9058
- const agentEntries = await readdir6(agentsRoot, { withFileTypes: true });
9059
- for (const file of agentEntries) {
9060
- if (!file.isFile() || !file.name.endsWith(".toml"))
9061
- continue;
9062
- agents.push(join20(agentsRoot, file.name));
9063
- }
9064
- }
9065
- agents.sort();
9066
- return agents;
9067
- }
9068
- async function replaceWithCopy(linkPath, target) {
9069
- await prepareReplacement(linkPath);
9070
- await copyFile(target, linkPath);
9071
- }
9072
- async function prepareReplacement(linkPath) {
9073
- if (!await exists3(linkPath))
9074
- return;
9075
- const entryStat = await lstat8(linkPath);
9076
- if (entryStat.isDirectory() && !entryStat.isSymbolicLink()) {
9077
- throw new Error(`${linkPath} already exists and is a directory; refusing to replace`);
9078
- }
9079
- await rm8(linkPath, { force: true });
9080
- }
9081
- async function writeManifest(pluginRoot, agentPaths) {
9082
- const manifestPath = join20(pluginRoot, MANIFEST_FILE);
9083
- const payload = { agents: [...agentPaths].sort() };
9084
- await writeFile6(manifestPath, `${JSON.stringify(payload, null, "\t")}
9085
- `);
9086
- }
9087
- async function restorePreservedReasoning(input) {
9088
- if (input.value === undefined)
9092
+ async function restorePreservedServiceTier(input) {
9093
+ if (!input.preserved)
9089
9094
  return;
9090
- const content = await readFile14(input.target, "utf8");
9091
- const bundledEffort = extractReasoningEffort(content);
9092
- if (bundledEffort === input.value)
9095
+ const content = await readFile13(input.linkPath, "utf8");
9096
+ if (extractServiceTier(content) === input.value)
9093
9097
  return;
9094
- const replacement = replaceReasoningEffort(content, input.value);
9098
+ const replacement = replaceTopLevelStringSetting(content, "service_tier", input.value, { insertIfMissing: true });
9095
9099
  if (!replacement.replaced)
9096
9100
  return;
9097
9101
  await writeFile6(input.linkPath, replacement.content);
9098
9102
  }
9099
- async function readTextIfExists2(path) {
9103
+ async function readTextIfExists(path) {
9100
9104
  try {
9101
- return await readFile14(path, "utf8");
9105
+ return await readFile13(path, "utf8");
9102
9106
  } catch (error) {
9103
- if (nodeErrorCode2(error) === "ENOENT")
9107
+ if (nodeErrorCode(error) === "ENOENT")
9104
9108
  return null;
9105
9109
  throw error;
9106
9110
  }
9107
9111
  }
9112
+ function extractModel(content) {
9113
+ return extractTopLevelStringSetting(content, "model");
9114
+ }
9108
9115
  function extractReasoningEffort(content) {
9109
9116
  return extractTopLevelStringSetting(content, "model_reasoning_effort");
9110
9117
  }
@@ -9124,12 +9131,6 @@ function extractTopLevelStringSetting(content, key) {
9124
9131
  }
9125
9132
  return null;
9126
9133
  }
9127
- function replaceReasoningEffort(content, value) {
9128
- return replaceTopLevelStringSetting(content, "model_reasoning_effort", value, { insertIfMissing: false });
9129
- }
9130
- function replaceServiceTier(content, value) {
9131
- return replaceTopLevelStringSetting(content, "service_tier", value, { insertIfMissing: true });
9132
- }
9133
9134
  function replaceTopLevelStringSetting(content, key, value, options) {
9134
9135
  const lines = content.split(/\n/);
9135
9136
  for (let index = 0;index < lines.length; index += 1) {
@@ -9189,6 +9190,64 @@ function parseJsonString(value) {
9189
9190
  return null;
9190
9191
  }
9191
9192
  }
9193
+ async function exists2(path) {
9194
+ try {
9195
+ await lstat7(path);
9196
+ return true;
9197
+ } catch (error) {
9198
+ if (nodeErrorCode(error) !== "ENOENT")
9199
+ throw error;
9200
+ return false;
9201
+ }
9202
+ }
9203
+ function nodeErrorCode(error) {
9204
+ if (!(error instanceof Error) || !("code" in error))
9205
+ return null;
9206
+ return typeof error.code === "string" ? error.code : null;
9207
+ }
9208
+
9209
+ // packages/omo-codex/src/install/retired-managed-agent-purge.ts
9210
+ import { lstat as lstat8, readFile as readFile14, rm as rm7 } from "node:fs/promises";
9211
+ import { join as join21 } from "node:path";
9212
+ var RETIRED_MANAGED_AGENT_FILES = [
9213
+ {
9214
+ fileName: "codex-ultrawork-reviewer.toml",
9215
+ requiredMarkers: [
9216
+ 'name = "codex-ultrawork-reviewer"',
9217
+ 'description = "Strict ultrawork verification reviewer.',
9218
+ 'developer_instructions = """You are the ultrawork verification reviewer.'
9219
+ ]
9220
+ }
9221
+ ];
9222
+ async function purgeRetiredManagedAgentFiles(input) {
9223
+ const agentsDir = join21(input.codexHome, "agents");
9224
+ if (!await exists3(agentsDir))
9225
+ return;
9226
+ for (const retiredAgent of RETIRED_MANAGED_AGENT_FILES) {
9227
+ const agentPath = join21(agentsDir, retiredAgent.fileName);
9228
+ if (!await exists3(agentPath))
9229
+ continue;
9230
+ const agentStat = await lstat8(agentPath);
9231
+ if (agentStat.isDirectory() && !agentStat.isSymbolicLink())
9232
+ continue;
9233
+ const content = await readTextIfExists2(agentPath);
9234
+ if (content === null || !hasRequiredMarkers(content, retiredAgent.requiredMarkers))
9235
+ continue;
9236
+ await rm7(agentPath, { force: true });
9237
+ }
9238
+ }
9239
+ function hasRequiredMarkers(content, markers) {
9240
+ return markers.every((marker) => content.includes(marker));
9241
+ }
9242
+ async function readTextIfExists2(path) {
9243
+ try {
9244
+ return await readFile14(path, "utf8");
9245
+ } catch (error) {
9246
+ if (nodeErrorCode2(error) === "ENOENT")
9247
+ return null;
9248
+ throw error;
9249
+ }
9250
+ }
9192
9251
  async function exists3(path) {
9193
9252
  try {
9194
9253
  await lstat8(path);
@@ -9205,12 +9264,105 @@ function nodeErrorCode2(error) {
9205
9264
  return typeof error.code === "string" ? error.code : null;
9206
9265
  }
9207
9266
 
9267
+ // packages/omo-codex/src/install/link-cached-plugin-agents.ts
9268
+ var MANIFEST_FILE = ".installed-agents.json";
9269
+ async function linkCachedPluginAgents(input) {
9270
+ const bundledAgents = await discoverBundledAgents(input.pluginRoot);
9271
+ await purgeRetiredManagedAgentFiles({ codexHome: input.codexHome });
9272
+ if (bundledAgents.length === 0) {
9273
+ await writeManifest(input.pluginRoot, []);
9274
+ return [];
9275
+ }
9276
+ const agentsDir = join22(input.codexHome, "agents");
9277
+ await mkdir6(agentsDir, { recursive: true });
9278
+ const linked = [];
9279
+ for (const agentPath of bundledAgents) {
9280
+ const agentFileName = basename5(agentPath);
9281
+ const agentName = agentNameFromToml2(agentFileName);
9282
+ const linkPath = join22(agentsDir, agentFileName);
9283
+ await replaceWithCopy(linkPath, agentPath);
9284
+ await restorePreservedReasoning({
9285
+ agentName,
9286
+ linkPath,
9287
+ target: agentPath,
9288
+ value: input.preservedReasoning?.get(agentName)
9289
+ });
9290
+ await restorePreservedServiceTier({
9291
+ linkPath,
9292
+ preserved: input.preservedServiceTier?.has(agentName) ?? false,
9293
+ value: input.preservedServiceTier?.get(agentName) ?? null
9294
+ });
9295
+ linked.push({ name: agentFileName, path: linkPath, target: agentPath });
9296
+ }
9297
+ await writeManifest(input.pluginRoot, linked.map((entry) => entry.path));
9298
+ return linked;
9299
+ }
9300
+ async function discoverBundledAgents(pluginRoot) {
9301
+ const componentsRoot = join22(pluginRoot, "components");
9302
+ if (!await exists4(componentsRoot))
9303
+ return [];
9304
+ const componentEntries = await readdir7(componentsRoot, { withFileTypes: true });
9305
+ const agents = [];
9306
+ for (const entry of componentEntries) {
9307
+ if (!entry.isDirectory())
9308
+ continue;
9309
+ const agentsRoot = join22(componentsRoot, entry.name, "agents");
9310
+ if (!await exists4(agentsRoot))
9311
+ continue;
9312
+ const agentEntries = await readdir7(agentsRoot, { withFileTypes: true });
9313
+ for (const file of agentEntries) {
9314
+ if (!file.isFile() || !file.name.endsWith(".toml"))
9315
+ continue;
9316
+ agents.push(join22(agentsRoot, file.name));
9317
+ }
9318
+ }
9319
+ agents.sort();
9320
+ return agents;
9321
+ }
9322
+ async function replaceWithCopy(linkPath, target) {
9323
+ await prepareReplacement(linkPath);
9324
+ await copyFile(target, linkPath);
9325
+ }
9326
+ async function prepareReplacement(linkPath) {
9327
+ if (!await exists4(linkPath))
9328
+ return;
9329
+ const entryStat = await lstat9(linkPath);
9330
+ if (entryStat.isDirectory() && !entryStat.isSymbolicLink()) {
9331
+ throw new Error(`${linkPath} already exists and is a directory; refusing to replace`);
9332
+ }
9333
+ await rm8(linkPath, { force: true });
9334
+ }
9335
+ async function writeManifest(pluginRoot, agentPaths) {
9336
+ const manifestPath = join22(pluginRoot, MANIFEST_FILE);
9337
+ const payload = { agents: [...agentPaths].sort() };
9338
+ await writeFile7(manifestPath, `${JSON.stringify(payload, null, "\t")}
9339
+ `);
9340
+ }
9341
+ function agentNameFromToml2(fileName) {
9342
+ return fileName.endsWith(".toml") ? fileName.slice(0, -".toml".length) : fileName;
9343
+ }
9344
+ async function exists4(path) {
9345
+ try {
9346
+ await lstat9(path);
9347
+ return true;
9348
+ } catch (error) {
9349
+ if (nodeErrorCode3(error) !== "ENOENT")
9350
+ throw error;
9351
+ return false;
9352
+ }
9353
+ }
9354
+ function nodeErrorCode3(error) {
9355
+ if (!(error instanceof Error) || !("code" in error))
9356
+ return null;
9357
+ return typeof error.code === "string" ? error.code : null;
9358
+ }
9359
+
9208
9360
  // packages/omo-codex/src/install/codex-marketplace.ts
9209
9361
  import { readFile as readFile15 } from "node:fs/promises";
9210
- import { join as join21 } from "node:path";
9362
+ import { join as join23 } from "node:path";
9211
9363
  var DEFAULT_MARKETPLACE_PATH = "packages/omo-codex/marketplace.json";
9212
9364
  async function readMarketplace(repoRoot, options) {
9213
- const marketplacePath = options?.marketplacePath ?? join21(repoRoot, DEFAULT_MARKETPLACE_PATH);
9365
+ const marketplacePath = options?.marketplacePath ?? join23(repoRoot, DEFAULT_MARKETPLACE_PATH);
9214
9366
  const raw = await readFile15(marketplacePath, "utf8");
9215
9367
  const parsed = JSON.parse(raw);
9216
9368
  if (!isPlainRecord(parsed))
@@ -9229,10 +9381,10 @@ async function readMarketplace(repoRoot, options) {
9229
9381
  function resolvePluginSource(repoRoot, plugin, options) {
9230
9382
  const sourcePath = localSourcePath(options?.pathOverride ?? plugin.source);
9231
9383
  const relativePath = sourcePath.slice(2);
9232
- return join21(repoRoot, ...relativePath.split(/[\\/]/));
9384
+ return join23(repoRoot, ...relativePath.split(/[\\/]/));
9233
9385
  }
9234
9386
  async function readPluginManifest(pluginRoot) {
9235
- const raw = await readFile15(join21(pluginRoot, ".codex-plugin", "plugin.json"), "utf8");
9387
+ const raw = await readFile15(join23(pluginRoot, ".codex-plugin", "plugin.json"), "utf8");
9236
9388
  const parsed = JSON.parse(raw);
9237
9389
  if (!isPlainRecord(parsed))
9238
9390
  throw new Error(`${pluginRoot} plugin.json must be an object`);
@@ -9313,8 +9465,8 @@ function validateLocalSourcePath(path) {
9313
9465
  }
9314
9466
 
9315
9467
  // packages/omo-codex/src/install/codex-marketplace-snapshot.ts
9316
- import { cp as cp3, mkdir as mkdir7, rename as rename4, rm as rm9, writeFile as writeFile7 } from "node:fs/promises";
9317
- import { join as join22, sep as sep6 } from "node:path";
9468
+ import { cp as cp3, mkdir as mkdir7, rename as rename4, rm as rm9, writeFile as writeFile8 } from "node:fs/promises";
9469
+ import { join as join24, sep as sep6 } from "node:path";
9318
9470
  var INSTALLED_MARKETPLACES_DIR = ".tmp/marketplaces";
9319
9471
  async function writeInstalledMarketplaceSnapshot(input) {
9320
9472
  const marketplaceRoot = installedMarketplaceRoot(input.codexHome, input.marketplace.name);
@@ -9327,21 +9479,21 @@ async function writeInstalledMarketplaceSnapshot(input) {
9327
9479
  return snapshotPlugins;
9328
9480
  }
9329
9481
  function installedMarketplaceRoot(codexHome, marketplaceName) {
9330
- return join22(codexHome, INSTALLED_MARKETPLACES_DIR, marketplaceName);
9482
+ return join24(codexHome, INSTALLED_MARKETPLACES_DIR, marketplaceName);
9331
9483
  }
9332
9484
  async function writeMarketplaceManifest(marketplaceRoot, marketplace) {
9333
- const manifestDir = join22(marketplaceRoot, ".agents", "plugins");
9485
+ const manifestDir = join24(marketplaceRoot, ".agents", "plugins");
9334
9486
  await mkdir7(manifestDir, { recursive: true });
9335
- const tempPath = join22(manifestDir, `.marketplace-${process.pid}-${Date.now()}.json.tmp`);
9336
- await writeFile7(tempPath, `${JSON.stringify(marketplace, null, "\t")}
9487
+ const tempPath = join24(manifestDir, `.marketplace-${process.pid}-${Date.now()}.json.tmp`);
9488
+ await writeFile8(tempPath, `${JSON.stringify(marketplace, null, "\t")}
9337
9489
  `);
9338
- await rename4(tempPath, join22(manifestDir, "marketplace.json"));
9490
+ await rename4(tempPath, join24(manifestDir, "marketplace.json"));
9339
9491
  }
9340
9492
  async function writeSnapshotPlugin(marketplaceRoot, plugin) {
9341
- const pluginsDir = join22(marketplaceRoot, "plugins");
9493
+ const pluginsDir = join24(marketplaceRoot, "plugins");
9342
9494
  await mkdir7(pluginsDir, { recursive: true });
9343
- const targetPath = join22(pluginsDir, plugin.name);
9344
- const tempPath = join22(pluginsDir, `.tmp-${plugin.name}-${process.pid}-${Date.now()}`);
9495
+ const targetPath = join24(pluginsDir, plugin.name);
9496
+ const tempPath = join24(pluginsDir, `.tmp-${plugin.name}-${process.pid}-${Date.now()}`);
9345
9497
  await rm9(tempPath, { recursive: true, force: true });
9346
9498
  await cp3(plugin.sourcePath, tempPath, {
9347
9499
  recursive: true,
@@ -9362,11 +9514,11 @@ function shouldCopyMarketplaceSourcePath(path, root) {
9362
9514
  }
9363
9515
 
9364
9516
  // packages/omo-codex/src/install/lazycodex-version-stamp.ts
9365
- import { readdir as readdir7, readFile as readFile16, writeFile as writeFile8 } from "node:fs/promises";
9366
- import { join as join23 } from "node:path";
9517
+ import { readdir as readdir8, readFile as readFile16, writeFile as writeFile9 } from "node:fs/promises";
9518
+ import { join as join25 } from "node:path";
9367
9519
  async function readDistributionManifest(repoRoot) {
9368
9520
  try {
9369
- const parsed = JSON.parse(await readFile16(join23(repoRoot, "package.json"), "utf8"));
9521
+ const parsed = JSON.parse(await readFile16(join25(repoRoot, "package.json"), "utf8"));
9370
9522
  if (!isPlainRecord(parsed) || typeof parsed.version !== "string" || parsed.version.trim().length === 0)
9371
9523
  return;
9372
9524
  return {
@@ -9386,19 +9538,19 @@ function resolveLazyCodexPluginVersion(input) {
9386
9538
  return input.manifestVersion ?? "local";
9387
9539
  }
9388
9540
  async function stampLazyCodexPluginVersion(input) {
9389
- const manifestPath = join23(input.pluginRoot, ".codex-plugin", "plugin.json");
9541
+ const manifestPath = join25(input.pluginRoot, ".codex-plugin", "plugin.json");
9390
9542
  const hookPaths = await readPluginHookPaths(manifestPath);
9391
9543
  await stampJsonVersion(manifestPath, input.version);
9392
- await stampJsonVersion(join23(input.pluginRoot, "package.json"), input.version);
9544
+ await stampJsonVersion(join25(input.pluginRoot, "package.json"), input.version);
9393
9545
  for (const hookPath of hookPaths) {
9394
- await stampHookStatusMessages(join23(input.pluginRoot, hookPath), input.version);
9546
+ await stampHookStatusMessages(join25(input.pluginRoot, hookPath), input.version);
9395
9547
  }
9396
9548
  await stampComponentVersions(input);
9397
9549
  }
9398
9550
  async function writeLazyCodexInstallSnapshot(input) {
9399
9551
  if (input.distributionManifest === undefined)
9400
9552
  return;
9401
- await writeFile8(join23(input.pluginRoot, "lazycodex-install.json"), `${JSON.stringify({
9553
+ await writeFile9(join25(input.pluginRoot, "lazycodex-install.json"), `${JSON.stringify({
9402
9554
  packageName: input.distributionManifest.name,
9403
9555
  version: input.distributionManifest.version
9404
9556
  }, null, "\t")}
@@ -9410,7 +9562,7 @@ async function stampJsonVersion(path, version) {
9410
9562
  if (!isPlainRecord(parsed))
9411
9563
  return;
9412
9564
  parsed.version = version;
9413
- await writeFile8(path, `${JSON.stringify(parsed, null, "\t")}
9565
+ await writeFile9(path, `${JSON.stringify(parsed, null, "\t")}
9414
9566
  `);
9415
9567
  } catch (error) {
9416
9568
  if (error instanceof Error)
@@ -9444,7 +9596,7 @@ async function stampHookStatusMessages(path, version) {
9444
9596
  if (!isPlainRecord(parsed))
9445
9597
  return;
9446
9598
  stampHookGroups(parsed.hooks, version);
9447
- await writeFile8(path, `${JSON.stringify(parsed, null, "\t")}
9599
+ await writeFile9(path, `${JSON.stringify(parsed, null, "\t")}
9448
9600
  `);
9449
9601
  } catch (error) {
9450
9602
  if (error instanceof Error)
@@ -9455,16 +9607,16 @@ async function stampHookStatusMessages(path, version) {
9455
9607
  async function stampComponentVersions(input) {
9456
9608
  let entries;
9457
9609
  try {
9458
- entries = await readdir7(join23(input.pluginRoot, "components"));
9610
+ entries = await readdir8(join25(input.pluginRoot, "components"));
9459
9611
  } catch (error) {
9460
9612
  if (error instanceof Error)
9461
9613
  return;
9462
9614
  throw error;
9463
9615
  }
9464
9616
  for (const entry of entries) {
9465
- const componentRoot = join23(input.pluginRoot, "components", entry);
9466
- await stampJsonVersion(join23(componentRoot, "package.json"), input.version);
9467
- await stampHookStatusMessages(join23(componentRoot, "hooks", "hooks.json"), input.version);
9617
+ const componentRoot = join25(input.pluginRoot, "components", entry);
9618
+ await stampJsonVersion(join25(componentRoot, "package.json"), input.version);
9619
+ await stampHookStatusMessages(join25(componentRoot, "hooks", "hooks.json"), input.version);
9468
9620
  }
9469
9621
  }
9470
9622
  function stampHookGroups(hooks, version) {
@@ -9493,8 +9645,8 @@ function normalizeHookStatusVersion(version) {
9493
9645
  }
9494
9646
 
9495
9647
  // packages/omo-codex/src/install/codex-project-local-cleanup.ts
9496
- import { copyFile as copyFile2, lstat as lstat9, readFile as readFile17, writeFile as writeFile9 } from "node:fs/promises";
9497
- import { dirname as dirname8, join as join24, resolve as resolve7 } from "node:path";
9648
+ import { copyFile as copyFile2, lstat as lstat10, readFile as readFile17, writeFile as writeFile10 } from "node:fs/promises";
9649
+ import { dirname as dirname9, join as join26, resolve as resolve7 } from "node:path";
9498
9650
  var LEGACY_AGENT_CONFLICT_KEYS = ["max_threads"];
9499
9651
  var PROJECT_LOCAL_ARTIFACT_PATHS = [
9500
9652
  ".codex/hooks.json",
@@ -9526,7 +9678,7 @@ async function repairNearestProjectLocalCodexArtifacts(input) {
9526
9678
  }
9527
9679
  const backupPath = `${configPath}.backup-${formatBackupTimestamp(input.now?.() ?? new Date)}`;
9528
9680
  await copyFile2(configPath, backupPath);
9529
- await writeFile9(configPath, `${repair.config.trimEnd()}
9681
+ await writeFile10(configPath, `${repair.config.trimEnd()}
9530
9682
  `);
9531
9683
  configs.push({
9532
9684
  projectRoot: project.projectRoot,
@@ -9597,37 +9749,37 @@ async function findProjectLocalCodexConfigs(startDirectory, codexHome) {
9597
9749
  if (startDirectoryStat !== null && !startDirectoryStat.isDirectory()) {
9598
9750
  throw new ProjectLocalCleanupStartDirectoryError(startDirectory);
9599
9751
  }
9600
- const codexHomeConfigPath = codexHome === undefined ? null : join24(resolve7(codexHome), "config.toml");
9752
+ const codexHomeConfigPath = codexHome === undefined ? null : join26(resolve7(codexHome), "config.toml");
9601
9753
  let current = resolve7(startDirectory);
9602
9754
  const configPathsFromCwd = [];
9603
9755
  while (true) {
9604
- const configPath = join24(current, ".codex", "config.toml");
9756
+ const configPath = join26(current, ".codex", "config.toml");
9605
9757
  if (await isRegularProjectLocalConfig(current, configPath)) {
9606
9758
  if (codexHomeConfigPath === null || resolve7(configPath) !== codexHomeConfigPath) {
9607
9759
  configPathsFromCwd.push(configPath);
9608
9760
  }
9609
9761
  }
9610
- if (await exists4(join24(current, ".git"))) {
9762
+ if (await exists5(join26(current, ".git"))) {
9611
9763
  return configPathsFromCwd.length === 0 ? null : {
9612
9764
  projectRoot: current,
9613
9765
  configPaths: [...configPathsFromCwd].reverse(),
9614
9766
  artifactRoots: artifactRootsForConfigPaths(configPathsFromCwd)
9615
9767
  };
9616
9768
  }
9617
- const parent = dirname8(current);
9769
+ const parent = dirname9(current);
9618
9770
  if (parent === current) {
9619
9771
  const nearestConfigPath = configPathsFromCwd[0];
9620
9772
  return nearestConfigPath === undefined ? null : {
9621
- projectRoot: dirname8(dirname8(nearestConfigPath)),
9773
+ projectRoot: dirname9(dirname9(nearestConfigPath)),
9622
9774
  configPaths: [nearestConfigPath],
9623
- artifactRoots: [dirname8(dirname8(nearestConfigPath))]
9775
+ artifactRoots: [dirname9(dirname9(nearestConfigPath))]
9624
9776
  };
9625
9777
  }
9626
9778
  current = parent;
9627
9779
  }
9628
9780
  }
9629
9781
  async function isRegularProjectLocalConfig(directory, configPath) {
9630
- const codexDirStat = await maybeLstat(join24(directory, ".codex"));
9782
+ const codexDirStat = await maybeLstat(join26(directory, ".codex"));
9631
9783
  if (codexDirStat === null || !codexDirStat.isDirectory() || codexDirStat.isSymbolicLink())
9632
9784
  return false;
9633
9785
  const configStat = await maybeLstat(configPath);
@@ -9636,7 +9788,7 @@ async function isRegularProjectLocalConfig(directory, configPath) {
9636
9788
  function artifactRootsForConfigPaths(configPaths) {
9637
9789
  const roots = [];
9638
9790
  for (const configPath of configPaths) {
9639
- const root = dirname8(dirname8(configPath));
9791
+ const root = dirname9(dirname9(configPath));
9640
9792
  if (!roots.includes(root))
9641
9793
  roots.push(root);
9642
9794
  }
@@ -9647,7 +9799,7 @@ async function collectProjectLocalArtifacts(projectRoots) {
9647
9799
  const seenPaths = new Set;
9648
9800
  for (const projectRoot of projectRoots) {
9649
9801
  for (const relativePath of PROJECT_LOCAL_ARTIFACT_PATHS) {
9650
- const artifactPath = join24(projectRoot, relativePath);
9802
+ const artifactPath = join26(projectRoot, relativePath);
9651
9803
  if (seenPaths.has(artifactPath))
9652
9804
  continue;
9653
9805
  const entryStat = await maybeLstat(artifactPath);
@@ -9681,17 +9833,17 @@ function formatBackupTimestamp(date) {
9681
9833
  }
9682
9834
  async function maybeLstat(path) {
9683
9835
  try {
9684
- return await lstat9(path);
9836
+ return await lstat10(path);
9685
9837
  } catch (error) {
9686
- if (nodeErrorCode3(error) === "ENOENT")
9838
+ if (nodeErrorCode4(error) === "ENOENT")
9687
9839
  return null;
9688
9840
  throw error;
9689
9841
  }
9690
9842
  }
9691
- async function exists4(path) {
9843
+ async function exists5(path) {
9692
9844
  return await maybeLstat(path) !== null;
9693
9845
  }
9694
- function nodeErrorCode3(error) {
9846
+ function nodeErrorCode4(error) {
9695
9847
  if (!(error instanceof Error) || !("code" in error))
9696
9848
  return null;
9697
9849
  return typeof error.code === "string" ? error.code : null;
@@ -9722,24 +9874,24 @@ function formatUnknownError(error) {
9722
9874
  }
9723
9875
 
9724
9876
  // packages/omo-codex/src/install/lsp-daemon-reaper.ts
9725
- import { readFile as readFile18, readdir as readdir8, rm as rm10 } from "node:fs/promises";
9877
+ import { readFile as readFile18, readdir as readdir9, rm as rm10 } from "node:fs/promises";
9726
9878
  import { connect } from "node:net";
9727
- import { join as join25 } from "node:path";
9879
+ import { join as join27 } from "node:path";
9728
9880
  async function reapLspDaemons(codexHome, deps = {}) {
9729
9881
  const killProcess = deps.killProcess ?? sendSigterm;
9730
9882
  const isDaemonLive = deps.isDaemonLive ?? probeSocketLive;
9731
- const daemonRoot = join25(codexHome, "codex-lsp", "daemon");
9883
+ const daemonRoot = join27(codexHome, "codex-lsp", "daemon");
9732
9884
  const reaped = [];
9733
9885
  let entries;
9734
9886
  try {
9735
- entries = await readdir8(daemonRoot);
9887
+ entries = await readdir9(daemonRoot);
9736
9888
  } catch {
9737
9889
  return reaped;
9738
9890
  }
9739
9891
  for (const entry of entries) {
9740
- const versionDir = join25(daemonRoot, entry);
9741
- const pid = await readPidFile(join25(versionDir, "daemon.pid"));
9742
- const socketPath = await readEndpointFile(join25(versionDir, "daemon.endpoint"));
9892
+ const versionDir = join27(daemonRoot, entry);
9893
+ const pid = await readPidFile(join27(versionDir, "daemon.pid"));
9894
+ const socketPath = await readEndpointFile(join27(versionDir, "daemon.endpoint"));
9743
9895
  if (pid !== null && socketPath !== null && await isDaemonLive(socketPath) && killProcess(pid)) {
9744
9896
  reaped.push(pid);
9745
9897
  }
@@ -9793,7 +9945,7 @@ function sendSigterm(pid) {
9793
9945
 
9794
9946
  // packages/omo-codex/src/install/codex-installer-bin-dir.ts
9795
9947
  import { homedir } from "node:os";
9796
- import { join as join26, resolve as resolve8 } from "node:path";
9948
+ import { join as join28, resolve as resolve8 } from "node:path";
9797
9949
  function resolveCodexInstallerBinDir(input) {
9798
9950
  const explicitBinDir = input.binDir ?? input.env?.CODEX_LOCAL_BIN_DIR;
9799
9951
  if (explicitBinDir !== undefined && explicitBinDir.trim().length > 0)
@@ -9802,13 +9954,13 @@ function resolveCodexInstallerBinDir(input) {
9802
9954
  const defaultCodexHome = resolve8(homeDir, ".codex");
9803
9955
  const resolvedCodexHome = resolve8(input.codexHome);
9804
9956
  if (resolvedCodexHome !== defaultCodexHome)
9805
- return join26(resolvedCodexHome, "bin");
9957
+ return join28(resolvedCodexHome, "bin");
9806
9958
  return resolve8(homeDir, ".local", "bin");
9807
9959
  }
9808
9960
 
9809
9961
  // packages/omo-codex/src/install/codex-git-bash-hooks.ts
9810
- import { readFile as readFile19, writeFile as writeFile10 } from "node:fs/promises";
9811
- import { join as join27 } from "node:path";
9962
+ import { readFile as readFile19, writeFile as writeFile11 } from "node:fs/promises";
9963
+ import { join as join29 } from "node:path";
9812
9964
  var WINDOWS_ONLY_GIT_BASH_HOOKS = new Set([
9813
9965
  "./hooks/pre-tool-use-recommending-git-bash-mcp.json",
9814
9966
  "./hooks/post-compact-resetting-git-bash-mcp-reminder.json"
@@ -9816,22 +9968,22 @@ var WINDOWS_ONLY_GIT_BASH_HOOKS = new Set([
9816
9968
  async function removeGitBashHooksOffWindows(input) {
9817
9969
  if (input.platform === "win32")
9818
9970
  return;
9819
- const manifestPath = join27(input.pluginRoot, ".codex-plugin", "plugin.json");
9971
+ const manifestPath = join29(input.pluginRoot, ".codex-plugin", "plugin.json");
9820
9972
  const parsed = JSON.parse(await readFile19(manifestPath, "utf8"));
9821
9973
  if (!isPlainRecord(parsed) || !Array.isArray(parsed.hooks))
9822
9974
  return;
9823
9975
  const hooks = parsed.hooks.filter((hook) => typeof hook !== "string" || !WINDOWS_ONLY_GIT_BASH_HOOKS.has(hook));
9824
9976
  if (hooks.length === parsed.hooks.length)
9825
9977
  return;
9826
- await writeFile10(manifestPath, `${JSON.stringify({ ...parsed, hooks }, null, "\t")}
9978
+ await writeFile11(manifestPath, `${JSON.stringify({ ...parsed, hooks }, null, "\t")}
9827
9979
  `);
9828
9980
  }
9829
9981
 
9830
9982
  // packages/omo-codex/src/install/omo-sot-migration.ts
9831
- import { join as join28 } from "node:path";
9983
+ import { join as join30 } from "node:path";
9832
9984
  async function seedAndMigrateOmoSot(input) {
9833
9985
  const commandEnv = { ...input.env };
9834
- const scriptPath = join28(input.repoRoot, "packages", "omo-codex", "plugin", "scripts", "migrate-omo-sot.mjs");
9986
+ const scriptPath = join30(input.repoRoot, "packages", "omo-codex", "plugin", "scripts", "migrate-omo-sot.mjs");
9835
9987
  try {
9836
9988
  await input.runCommand(process.execPath, [scriptPath, "--seed"], {
9837
9989
  cwd: input.repoRoot,
@@ -9845,7 +9997,7 @@ async function seedAndMigrateOmoSot(input) {
9845
9997
  }
9846
9998
 
9847
9999
  // packages/omo-codex/src/install/install-ast-grep-sg.ts
9848
- import { join as join30 } from "node:path";
10000
+ import { join as join32 } from "node:path";
9849
10001
 
9850
10002
  // packages/utils/src/ast-grep/sg-manifest.ts
9851
10003
  function normalizeRuntimePlatform(platform = process.platform) {
@@ -9865,11 +10017,11 @@ function runtimeSlug(platform = process.platform, arch = process.arch) {
9865
10017
  // packages/utils/src/ast-grep/install-script.ts
9866
10018
  import { spawn as spawn2 } from "node:child_process";
9867
10019
  import { existsSync as existsSync4 } from "node:fs";
9868
- import { join as join29 } from "node:path";
10020
+ import { join as join31 } from "node:path";
9869
10021
  var AST_GREP_BIN_DIR_ENV_KEY = "OMO_AST_GREP_BIN_DIR";
9870
10022
  var AST_GREP_INSTALL_TIMEOUT_MS = 30000;
9871
10023
  function astGrepRuntimeDir(baseDir, platform = process.platform, arch = process.arch) {
9872
- return join29(baseDir, "runtime", "ast-grep", runtimeSlug(platform, arch));
10024
+ return join31(baseDir, "runtime", "ast-grep", runtimeSlug(platform, arch));
9873
10025
  }
9874
10026
  function isMissingExecutable(error) {
9875
10027
  if (!("code" in error))
@@ -9907,7 +10059,7 @@ function defaultSpawnProcess(command, args, options) {
9907
10059
  };
9908
10060
  }
9909
10061
  function scriptPathForPlatform(skillDir, platform) {
9910
- return join29(skillDir, platform === "win32" ? "install.ps1" : "install.sh");
10062
+ return join31(skillDir, platform === "win32" ? "install.ps1" : "install.sh");
9911
10063
  }
9912
10064
  function invocationsForPlatform(scriptPath, platform) {
9913
10065
  if (platform !== "win32")
@@ -9979,7 +10131,7 @@ async function installAstGrepForCodex(options) {
9979
10131
  return;
9980
10132
  const platform = options.platform ?? process.platform;
9981
10133
  const targetDir = astGrepRuntimeDir(options.codexHome, platform, options.arch ?? process.arch);
9982
- const skillDir = join30(plugin.path, "skills", "ast-grep");
10134
+ const skillDir = join32(plugin.path, "skills", "ast-grep");
9983
10135
  const installer = options.installer ?? runAstGrepSkillInstall;
9984
10136
  try {
9985
10137
  const result = await installer({ platform, skillDir, targetDir });
@@ -10012,7 +10164,7 @@ async function runCodexInstaller(options = {}) {
10012
10164
  const env2 = options.env ?? process.env;
10013
10165
  const platform = options.platform ?? process.platform;
10014
10166
  const repoRoot = resolve9(options.repoRoot ?? findRepoRoot({ importerDir: import.meta.dir, env: env2 }));
10015
- const codexHome = resolve9(options.codexHome ?? env2.CODEX_HOME ?? join33(homedir2(), ".codex"));
10167
+ const codexHome = resolve9(options.codexHome ?? env2.CODEX_HOME ?? join35(homedir2(), ".codex"));
10016
10168
  const projectDirectory = resolve9(options.projectDirectory ?? env2.OMO_CODEX_PROJECT ?? process.cwd());
10017
10169
  const binDir = resolveCodexInstallerBinDir({ binDir: options.binDir, codexHome, env: env2 });
10018
10170
  const runCommand = options.runCommand ?? defaultRunCommand;
@@ -10028,9 +10180,9 @@ async function runCodexInstaller(options = {}) {
10028
10180
  if (!gitBashResolution.found) {
10029
10181
  throw new Error(gitBashResolution.installHint);
10030
10182
  }
10031
- const codexPackageRoot = join33(repoRoot, "packages", "omo-codex");
10183
+ const codexPackageRoot = join35(repoRoot, "packages", "omo-codex");
10032
10184
  const marketplace = await readMarketplace(repoRoot, {
10033
- marketplacePath: join33(codexPackageRoot, "marketplace.json")
10185
+ marketplacePath: join35(codexPackageRoot, "marketplace.json")
10034
10186
  });
10035
10187
  const distributionManifest = await readDistributionManifest(repoRoot);
10036
10188
  const installed = [];
@@ -10073,7 +10225,7 @@ async function runCodexInstaller(options = {}) {
10073
10225
  if (runtimeLink !== null)
10074
10226
  log(`Linked ${runtimeLink.name} -> ${runtimeLink.target}`);
10075
10227
  else
10076
- log(`Warning: skipped the omo runtime wrapper because ${join33(repoRoot, "dist", "cli", "index.js")} is missing; omo ulw-loop commands will be unavailable until a package shipping dist/cli is installed`);
10228
+ log(`Warning: skipped the omo runtime wrapper because ${join35(repoRoot, "dist", "cli", "index.js")} is missing; omo ulw-loop commands will be unavailable until a package shipping dist/cli is installed`);
10077
10229
  }
10078
10230
  pluginSources.push({ name: entry.name, sourcePath });
10079
10231
  installed.push(plugin);
@@ -10104,7 +10256,7 @@ async function runCodexInstaller(options = {}) {
10104
10256
  });
10105
10257
  for (const link of agentLinks) {
10106
10258
  log(`Linked agent ${link.name} -> ${link.target}`);
10107
- const agentName = agentNameFromToml2(link.name);
10259
+ const agentName = agentNameFromToml3(link.name);
10108
10260
  agentConfigs.set(agentName, { name: agentName, configFile: `./agents/${link.name}` });
10109
10261
  }
10110
10262
  }
@@ -10127,13 +10279,13 @@ async function runCodexInstaller(options = {}) {
10127
10279
  });
10128
10280
  }
10129
10281
  await reapLspDaemons(codexHome).catch(() => []);
10130
- const marketplaceRoot = join33(codexHome, "plugins", "cache", marketplace.name);
10282
+ const marketplaceRoot = join35(codexHome, "plugins", "cache", marketplace.name);
10131
10283
  await writeCachedMarketplaceManifest({
10132
10284
  marketplaceName: marketplace.name,
10133
10285
  marketplaceRoot,
10134
10286
  plugins: installed
10135
10287
  });
10136
- const configPath = join33(codexHome, "config.toml");
10288
+ const configPath = join35(codexHome, "config.toml");
10137
10289
  await updateCodexConfig({
10138
10290
  configPath,
10139
10291
  repoRoot: codexPackageRoot,
@@ -10171,7 +10323,7 @@ async function runCodexInstaller(options = {}) {
10171
10323
  projectCleanup
10172
10324
  };
10173
10325
  }
10174
- function agentNameFromToml2(fileName) {
10326
+ function agentNameFromToml3(fileName) {
10175
10327
  return fileName.endsWith(".toml") ? fileName.slice(0, -".toml".length) : fileName;
10176
10328
  }
10177
10329
  async function agentSourceRootsForInstall(input) {
@@ -10193,7 +10345,7 @@ function findRepoRootFromImporter(importerDir) {
10193
10345
  for (let depth = 0;depth <= 7; depth += 1) {
10194
10346
  if (isRepoRootWithCodexPlugin(current))
10195
10347
  return current;
10196
- for (const wrapperPackageRoot of [join33(current, "node_modules", "oh-my-openagent"), join33(current, "oh-my-openagent")]) {
10348
+ for (const wrapperPackageRoot of [join35(current, "node_modules", "oh-my-openagent"), join35(current, "oh-my-openagent")]) {
10197
10349
  if (isRepoRootWithCodexPlugin(wrapperPackageRoot))
10198
10350
  return wrapperPackageRoot;
10199
10351
  }
@@ -10211,7 +10363,7 @@ function findRepoRoot(input) {
10211
10363
  return findRepoRootFromImporter(input.importerDir);
10212
10364
  }
10213
10365
  function isRepoRootWithCodexPlugin(repoRoot) {
10214
- return existsSync7(join33(repoRoot, "packages", "omo-codex", "plugin", ".codex-plugin", "plugin.json"));
10366
+ return existsSync7(join35(repoRoot, "packages", "omo-codex", "plugin", ".codex-plugin", "plugin.json"));
10215
10367
  }
10216
10368
  function codexMarketplaceSource(marketplaceRoot) {
10217
10369
  return { sourceType: "local", source: marketplaceRoot };
@@ -10523,13 +10675,13 @@ function shellQuote(value) {
10523
10675
 
10524
10676
  // packages/omo-codex/src/install/lazycodex-manual-update.ts
10525
10677
  import { spawn as spawn3, spawnSync as spawnSync3 } from "node:child_process";
10526
- import { readFileSync as readFileSync3 } from "node:fs";
10527
- import { dirname as dirname10, join as join35 } from "node:path";
10678
+ import { readFileSync as readFileSync4 } from "node:fs";
10679
+ import { dirname as dirname11, join as join37 } from "node:path";
10528
10680
  import { createInterface as createInterface2 } from "node:readline/promises";
10529
10681
  import { fileURLToPath } from "node:url";
10530
10682
 
10531
10683
  // packages/omo-codex/src/install/lazycodex-bun-global-paths.ts
10532
- import { join as join34 } from "node:path";
10684
+ import { join as join36 } from "node:path";
10533
10685
  function isBunGlobalEntrypointPath(invokedPath, env2) {
10534
10686
  if (typeof invokedPath !== "string" || invokedPath.trim().length === 0)
10535
10687
  return false;
@@ -10540,8 +10692,8 @@ function resolveBunGlobalRoots(env2) {
10540
10692
  const bunInstallRoot = env2.BUN_INSTALL?.trim();
10541
10693
  const homeRoot = env2.HOME?.trim();
10542
10694
  return [
10543
- ...bunInstallRoot ? [join34(bunInstallRoot, "bin"), join34(bunInstallRoot, "install", "global", "node_modules")] : [],
10544
- ...homeRoot ? [join34(homeRoot, ".bun", "bin"), join34(homeRoot, ".bun", "install", "global", "node_modules")] : []
10695
+ ...bunInstallRoot ? [join36(bunInstallRoot, "bin"), join36(bunInstallRoot, "install", "global", "node_modules")] : [],
10696
+ ...homeRoot ? [join36(homeRoot, ".bun", "bin"), join36(homeRoot, ".bun", "install", "global", "node_modules")] : []
10545
10697
  ].map(normalizePathForPrefix);
10546
10698
  }
10547
10699
  function normalizePathForPrefix(path2) {
@@ -10633,8 +10785,8 @@ function resolveArgs(env2) {
10633
10785
  function resolveCurrentVersion(env2) {
10634
10786
  if (env2.LAZYCODEX_CURRENT_VERSION?.trim())
10635
10787
  return env2.LAZYCODEX_CURRENT_VERSION.trim();
10636
- const pluginRoot = dirname10(dirname10(fileURLToPath(import.meta.url)));
10637
- return readVersionManifest(resolveInstalledVersionPath(env2, pluginRoot)) ?? readVersionManifest(join35(pluginRoot, "..", "..", "..", "package.json")) ?? readVersionManifest(join35(pluginRoot, ".codex-plugin", "plugin.json"));
10788
+ const pluginRoot = dirname11(dirname11(fileURLToPath(import.meta.url)));
10789
+ return readVersionManifest(resolveInstalledVersionPath(env2, pluginRoot)) ?? readVersionManifest(join37(pluginRoot, "..", "..", "..", "package.json")) ?? readVersionManifest(join37(pluginRoot, ".codex-plugin", "plugin.json"));
10638
10790
  }
10639
10791
  function resolveLatestVersion(env2) {
10640
10792
  if (env2.LAZYCODEX_LATEST_VERSION?.trim())
@@ -10750,11 +10902,11 @@ function compareVersions(left, right) {
10750
10902
  function resolveInstalledVersionPath(env2, pluginRoot) {
10751
10903
  if (env2.LAZYCODEX_INSTALLED_VERSION_FILE?.trim())
10752
10904
  return env2.LAZYCODEX_INSTALLED_VERSION_FILE.trim();
10753
- return join35(pluginRoot, INSTALLED_VERSION_FILE);
10905
+ return join37(pluginRoot, INSTALLED_VERSION_FILE);
10754
10906
  }
10755
10907
  function readVersionManifest(path2) {
10756
10908
  try {
10757
- const parsed = JSON.parse(readFileSync3(path2, "utf8"));
10909
+ const parsed = JSON.parse(readFileSync4(path2, "utf8"));
10758
10910
  if (typeof parsed === "object" && parsed !== null && "version" in parsed && typeof parsed.version === "string") {
10759
10911
  return parsed.version;
10760
10912
  }
@@ -10766,12 +10918,12 @@ function readVersionManifest(path2) {
10766
10918
  }
10767
10919
  }
10768
10920
  // packages/omo-codex/src/install/codex-git-bash-mcp-env.ts
10769
- import { readFile as readFile20, writeFile as writeFile11 } from "node:fs/promises";
10770
- import { join as join36 } from "node:path";
10921
+ import { readFile as readFile20, writeFile as writeFile12 } from "node:fs/promises";
10922
+ import { join as join38 } from "node:path";
10771
10923
  var GIT_BASH_ENV_KEY2 = "OMO_CODEX_GIT_BASH_PATH";
10772
10924
  var CODEGRAPH_RELATIVE_ARGS2 = new Set(["components/codegraph/dist/serve.js", "./components/codegraph/dist/serve.js"]);
10773
10925
  async function stampGitBashMcpEnv(input) {
10774
- const manifestPath = join36(input.pluginRoot, ".mcp.json");
10926
+ const manifestPath = join38(input.pluginRoot, ".mcp.json");
10775
10927
  if (!await fileExistsStrict(manifestPath))
10776
10928
  return false;
10777
10929
  const parsed = JSON.parse(await readFile20(manifestPath, "utf8"));
@@ -10792,7 +10944,7 @@ async function stampGitBashMcpEnv(input) {
10792
10944
  }
10793
10945
  if (!changed)
10794
10946
  return false;
10795
- await writeFile11(manifestPath, `${JSON.stringify(parsed, null, "\t")}
10947
+ await writeFile12(manifestPath, `${JSON.stringify(parsed, null, "\t")}
10796
10948
  `);
10797
10949
  return true;
10798
10950
  }
@@ -10804,7 +10956,7 @@ function stampCodegraphMcpPath(mcpServers, pluginRoot) {
10804
10956
  const entrypoint = args[0];
10805
10957
  if (typeof entrypoint !== "string" || !CODEGRAPH_RELATIVE_ARGS2.has(entrypoint))
10806
10958
  return false;
10807
- codegraphServer["args"] = [join36(pluginRoot, "components", "codegraph", "dist", "serve.js"), ...args.slice(1)];
10959
+ codegraphServer["args"] = [join38(pluginRoot, "components", "codegraph", "dist", "serve.js"), ...args.slice(1)];
10808
10960
  return true;
10809
10961
  }
10810
10962
 
@@ -10813,7 +10965,7 @@ async function installMarketplaceLocally(options = {}) {
10813
10965
  return runCodexInstaller(options);
10814
10966
  }
10815
10967
  function resolveDefaultRepoRootForEntrypoint(entrypointPath) {
10816
- return resolve10(dirname11(entrypointPath), "..", "..", "..");
10968
+ return resolve10(dirname12(entrypointPath), "..", "..", "..");
10817
10969
  }
10818
10970
  function resolveDefaultRepoRoot() {
10819
10971
  return resolveDefaultRepoRootForEntrypoint(fileURLToPath2(import.meta.url));
@@ -10825,7 +10977,7 @@ async function runLazyCodexInstallLocalCli(input) {
10825
10977
  return 0;
10826
10978
  }
10827
10979
  if (parsed.kind === "version") {
10828
- const packageJson = JSON.parse(await readFile21(join37(input.defaultRepoRoot, "package.json"), "utf8"));
10980
+ const packageJson = JSON.parse(await readFile21(join39(input.defaultRepoRoot, "package.json"), "utf8"));
10829
10981
  const version2 = typeof packageJson.version === "string" ? packageJson.version : "unknown";
10830
10982
  input.log(`lazycodex-ai ${version2}`);
10831
10983
  return 0;