lazycodex-ai 5.0.0-beta.50 → 5.0.0-beta.52

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 (79) hide show
  1. package/dist/cli/doctor/checks/index.d.ts +2 -0
  2. package/dist/cli/doctor/checks/latest-version.d.ts +11 -0
  3. package/dist/cli/doctor/framework/constants.d.ts +5 -0
  4. package/dist/cli/doctor/framework/types.d.ts +2 -0
  5. package/dist/cli/index.js +110 -44
  6. package/dist/cli-node/index.js +110 -44
  7. package/package.json +1 -1
  8. package/packages/lsp-daemon/dist/cli.js +1 -2
  9. package/packages/lsp-daemon/dist/ownership.js +2 -2
  10. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  11. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +5 -1
  12. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  13. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  14. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  15. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  16. package/packages/omo-codex/plugin/components/git-bash/dist/cli.js +1 -1
  17. package/packages/omo-codex/plugin/components/git-bash/dist/codex-hook.js +2 -1
  18. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  19. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  20. package/packages/omo-codex/plugin/components/git-bash/src/codex-hook.ts +2 -1
  21. package/packages/omo-codex/plugin/components/git-bash/test/codex-hook.test.ts +6 -7
  22. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  23. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  24. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
  25. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  26. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  27. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  28. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  29. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  30. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  31. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  32. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  33. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  34. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  35. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
  36. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
  37. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +11 -5
  38. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +11 -5
  39. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
  40. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  41. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +10 -5
  42. package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +21 -1
  43. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  44. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  45. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  46. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  47. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  48. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  49. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  50. package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
  51. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  52. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  53. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  54. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  55. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  56. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  57. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  58. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
  59. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  60. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  61. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  62. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  63. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  64. package/packages/omo-codex/plugin/package-lock.json +12 -12
  65. package/packages/omo-codex/plugin/package.json +1 -1
  66. package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +1 -0
  67. package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +10 -0
  68. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +3 -0
  69. package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +10 -2
  70. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +1 -0
  71. package/packages/omo-codex/plugin/skills/frontend/references/design/ambience-skill.md +145 -0
  72. package/packages/omo-codex/plugin/skills/frontend/references/design/interaction-skill.md +2 -0
  73. package/packages/omo-codex/scripts/install-dist/install-local.mjs +9 -5
  74. package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +10 -0
  75. package/packages/shared-skills/skills/frontend/SKILL.md +3 -0
  76. package/packages/shared-skills/skills/frontend/references/design/README.md +10 -2
  77. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +1 -0
  78. package/packages/shared-skills/skills/frontend/references/design/ambience-skill.md +145 -0
  79. package/packages/shared-skills/skills/frontend/references/design/interaction-skill.md +2 -0
@@ -65,7 +65,7 @@ var package_default;
65
65
  var init_package = __esm(() => {
66
66
  package_default = {
67
67
  name: "oh-my-opencode",
68
- version: "5.0.0-beta.50",
68
+ version: "5.0.0-beta.52",
69
69
  description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
70
70
  main: "./dist/index.js",
71
71
  types: "dist/index.d.ts",
@@ -249,7 +249,7 @@ var init_package = __esm(() => {
249
249
  zod: "^4.4.3"
250
250
  },
251
251
  devDependencies: {
252
- "@code-yeongyu/senpi": "2026.9.9",
252
+ "@code-yeongyu/senpi": "2026.9.10",
253
253
  "@oh-my-opencode/agents-md-core": "workspace:*",
254
254
  "@oh-my-opencode/ast-grep-mcp": "workspace:*",
255
255
  "@oh-my-opencode/boulder-state": "workspace:*",
@@ -290,18 +290,18 @@ var init_package = __esm(() => {
290
290
  typescript: "^7.0.2"
291
291
  },
292
292
  optionalDependencies: {
293
- "oh-my-opencode-darwin-arm64": "5.0.0-beta.50",
294
- "oh-my-opencode-darwin-x64": "5.0.0-beta.50",
295
- "oh-my-opencode-darwin-x64-baseline": "5.0.0-beta.50",
296
- "oh-my-opencode-linux-arm64": "5.0.0-beta.50",
297
- "oh-my-opencode-linux-arm64-musl": "5.0.0-beta.50",
298
- "oh-my-opencode-linux-x64": "5.0.0-beta.50",
299
- "oh-my-opencode-linux-x64-baseline": "5.0.0-beta.50",
300
- "oh-my-opencode-linux-x64-musl": "5.0.0-beta.50",
301
- "oh-my-opencode-linux-x64-musl-baseline": "5.0.0-beta.50",
302
- "oh-my-opencode-windows-arm64": "5.0.0-beta.50",
303
- "oh-my-opencode-windows-x64": "5.0.0-beta.50",
304
- "oh-my-opencode-windows-x64-baseline": "5.0.0-beta.50"
293
+ "oh-my-opencode-darwin-arm64": "5.0.0-beta.52",
294
+ "oh-my-opencode-darwin-x64": "5.0.0-beta.52",
295
+ "oh-my-opencode-darwin-x64-baseline": "5.0.0-beta.52",
296
+ "oh-my-opencode-linux-arm64": "5.0.0-beta.52",
297
+ "oh-my-opencode-linux-arm64-musl": "5.0.0-beta.52",
298
+ "oh-my-opencode-linux-x64": "5.0.0-beta.52",
299
+ "oh-my-opencode-linux-x64-baseline": "5.0.0-beta.52",
300
+ "oh-my-opencode-linux-x64-musl": "5.0.0-beta.52",
301
+ "oh-my-opencode-linux-x64-musl-baseline": "5.0.0-beta.52",
302
+ "oh-my-opencode-windows-arm64": "5.0.0-beta.52",
303
+ "oh-my-opencode-windows-x64": "5.0.0-beta.52",
304
+ "oh-my-opencode-windows-x64-baseline": "5.0.0-beta.52"
305
305
  },
306
306
  overrides: {
307
307
  "@earendil-works/pi-agent-core": "0.84.2",
@@ -64425,6 +64425,7 @@ var init_injector = __esm(() => {
64425
64425
  var init_hook_message_injector = __esm(() => {
64426
64426
  init_injector();
64427
64427
  init_constants2();
64428
+ init_id_generation();
64428
64429
  });
64429
64430
 
64430
64431
  // packages/omo-opencode/src/shared/opencode-message-dir.ts
@@ -73438,10 +73439,8 @@ function validationDiagnostic(path, issues) {
73438
73439
  function unrecognizedKeyIssues(issues) {
73439
73440
  return issues.flatMap((issue) => issue.code === "unrecognized_keys" ? [{ keys: issue.keys, path: issue.path.map((segment) => String(segment)) }] : []);
73440
73441
  }
73441
- function hasUnsafeUnrecognizedKey(parsed, issues) {
73442
- if (issues.some((issue) => issue.keys.some((key) => isUnsafeObjectKey2(key))))
73443
- return true;
73444
- return hasTamperedPrototype(parsed);
73442
+ function hasUnsafeUnrecognizedKey(issues) {
73443
+ return issues.some((issue) => issue.keys.some((key) => isUnsafeObjectKey2(key)));
73445
73444
  }
73446
73445
  function hasTamperedPrototype(value) {
73447
73446
  if (Array.isArray(value))
@@ -73514,11 +73513,17 @@ function readConfigSource(path, scope, fileSystem) {
73514
73513
  source: { exists: true, loaded: false, path, scope }
73515
73514
  };
73516
73515
  }
73516
+ if (hasTamperedPrototype(parsed.data)) {
73517
+ return {
73518
+ diagnostic: { kind: "validation", message: `Invalid omo config at ${path}: "__proto__" member is not allowed`, path },
73519
+ source: { exists: true, loaded: false, path, scope }
73520
+ };
73521
+ }
73517
73522
  const parsedRecord = toRecord2(parsed.data);
73518
73523
  const validation = OmoConfigLayerSchema.safeParse(parsed.data);
73519
73524
  if (!validation.success) {
73520
73525
  const unrecognized = unrecognizedKeyIssues(validation.error.issues);
73521
- if (unrecognized.length > 0 && hasUnsafeUnrecognizedKey(parsed.data, unrecognized)) {
73526
+ if (hasUnsafeUnrecognizedKey(unrecognized)) {
73522
73527
  return {
73523
73528
  diagnostic: validationDiagnostic(path, validation.error.issues),
73524
73529
  source: { exists: true, loaded: false, path, scope }
@@ -84518,7 +84523,7 @@ var package_default2;
84518
84523
  var init_package2 = __esm(() => {
84519
84524
  package_default2 = {
84520
84525
  name: "@oh-my-opencode/omo-codex",
84521
- version: "5.0.0-beta.50",
84526
+ version: "5.0.0-beta.52",
84522
84527
  type: "module",
84523
84528
  private: true,
84524
84529
  description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
@@ -87939,6 +87944,19 @@ var EXIT_CODES = {
87939
87944
  var MIN_OPENCODE_VERSION = "1.4.0";
87940
87945
  var PACKAGE_NAME = PUBLISHED_PACKAGE_NAME;
87941
87946
  var OPENCODE_BINARIES2 = ["opencode", "opencode-desktop"];
87947
+ var EDITION_LABELS = {
87948
+ opencode: "OpenCode",
87949
+ codex: "Codex"
87950
+ };
87951
+ var EDITION_PACKAGE_NAMES = {
87952
+ opencode: PUBLISHED_PACKAGE_NAME,
87953
+ codex: "lazycodex-ai"
87954
+ };
87955
+ var UPDATE_COMMANDS = {
87956
+ opencode: `bunx ${PUBLISHED_PACKAGE_NAME} install`,
87957
+ codex: "npx lazycodex-ai install --no-tui --codex-autonomous"
87958
+ };
87959
+ var LATEST_UNAVAILABLE_TEXT = "could not check";
87942
87960
 
87943
87961
  // packages/omo-opencode/src/cli/minimum-opencode-version.ts
87944
87962
  init_opencode_version();
@@ -90515,7 +90533,7 @@ var CODEX_AGENTS_HEADER = "agents";
90515
90533
  var CODEX_MULTI_AGENT_V2_HEADER = "features.multi_agent_v2";
90516
90534
  function ensureCodexMultiAgentV2Config(config, options = {}) {
90517
90535
  const featureFlag = removeFeatureFlagSetting(config, "multi_agent_v2");
90518
- const v2Preferred = options.multiAgentVersion === "v2";
90536
+ const v2Preferred = options.multiAgentVersion === "v2" || isMultiAgentV2Enabled(featureFlag.config);
90519
90537
  const agentsConfig = removeAgentsMaxThreads(featureFlag.config, v2Preferred);
90520
90538
  const preserveDisable = featureFlag.value === false && !v2Preferred;
90521
90539
  const featureConfig = preserveDisable ? setMultiAgentV2Disable(agentsConfig) : v2Preferred ? removeMultiAgentV2Disable(agentsConfig) : agentsConfig;
@@ -90594,6 +90612,10 @@ function removeFeatureFlagSetting(config, featureName) {
90594
90612
  value: readBooleanSetting(section.text, featureName)
90595
90613
  };
90596
90614
  }
90615
+ function isMultiAgentV2Enabled(config) {
90616
+ const section = findTomlSection(config, CODEX_MULTI_AGENT_V2_HEADER);
90617
+ return section !== null && /^\s*enabled\s*=\s*true[ \t]*(?:#.*)?$/m.test(section.text);
90618
+ }
90597
90619
  function removeAgentsMaxThreads(config, v2Preferred) {
90598
90620
  const section = findTomlSection(config, CODEX_AGENTS_HEADER);
90599
90621
  if (!section)
@@ -91756,7 +91778,7 @@ function lastValue(values) {
91756
91778
  return values.length > 0 ? values[values.length - 1] ?? null : null;
91757
91779
  }
91758
91780
  function repairProjectLocalCodexConfigText(config) {
91759
- if (!isMultiAgentV2Enabled(config))
91781
+ if (!isMultiAgentV2Enabled2(config))
91760
91782
  return { config, changed: false, removedKeys: [] };
91761
91783
  let nextConfig = config;
91762
91784
  const removedKeys = [];
@@ -91846,7 +91868,7 @@ async function collectProjectLocalArtifacts(projectRoots) {
91846
91868
  }
91847
91869
  return artifacts;
91848
91870
  }
91849
- function isMultiAgentV2Enabled(config) {
91871
+ function isMultiAgentV2Enabled2(config) {
91850
91872
  const featuresSection = findTomlSection(config, "features");
91851
91873
  if (featuresSection !== null && settingIsBooleanTrue(featuresSection.text, "multi_agent_v2"))
91852
91874
  return true;
@@ -93277,6 +93299,20 @@ import { constants as constants9 } from "node:fs";
93277
93299
  import { access as access2, readFile as readFile26, stat as stat6 } from "node:fs/promises";
93278
93300
  import { dirname as dirname23, join as join59 } from "node:path";
93279
93301
 
93302
+ // packages/memory-core/src/personas/manifest.ts
93303
+ var PERSONA_ASSET_FILENAMES = {
93304
+ reflection: "reflection-persona.md",
93305
+ dream: "dream-persona.md",
93306
+ facts: "facts-persona.md",
93307
+ kibitzer: "kibitzer-persona.md"
93308
+ };
93309
+ var PERSONA_ASSET_FILES = [
93310
+ PERSONA_ASSET_FILENAMES.reflection,
93311
+ PERSONA_ASSET_FILENAMES.dream,
93312
+ PERSONA_ASSET_FILENAMES.facts,
93313
+ PERSONA_ASSET_FILENAMES.kibitzer
93314
+ ];
93315
+
93280
93316
  // packages/omo-senpi/src/install/senpi-settings.ts
93281
93317
  import { constants as constants8 } from "node:fs";
93282
93318
  import { access, copyFile as copyFile3, mkdir as mkdir9, readFile as readFile25, rename as rename5, writeFile as writeFile14 } from "node:fs/promises";
@@ -93400,10 +93436,7 @@ var REQUIRED_PLUGIN_ARTIFACTS = [
93400
93436
  join59("extensions", "omo-task.js"),
93401
93437
  join59("extensions", "omo-member.js"),
93402
93438
  join59("extensions", "memory-run-supervisor.mjs"),
93403
- join59("extensions", "reflection-persona.md"),
93404
- join59("extensions", "dream-persona.md"),
93405
- join59("extensions", "facts-persona.md"),
93406
- join59("extensions", "kibitzer-persona.md"),
93439
+ ...PERSONA_ASSET_FILES.map((filename) => join59("extensions", filename)),
93407
93440
  join59("skills", "ast-grep", "SKILL.md"),
93408
93441
  join59("skills", "coding-agent-sessions", "SKILL.md"),
93409
93442
  join59("skills", "debugging", "SKILL.md"),
@@ -100723,7 +100756,9 @@ async function checkConfig() {
100723
100756
  }
100724
100757
 
100725
100758
  // packages/omo-opencode/src/cli/doctor/checks/deprecated-reasoning-keys.ts
100759
+ init_src4();
100726
100760
  init_main();
100761
+ init_config_migration();
100727
100762
  import { existsSync as existsSync52, readFileSync as readFileSync33 } from "node:fs";
100728
100763
  import { join as join78 } from "node:path";
100729
100764
  var CANONICAL_REPLACEMENT = new Map([
@@ -100731,8 +100766,9 @@ var CANONICAL_REPLACEMENT = new Map([
100731
100766
  ["reasoningEffort", "reasoning"],
100732
100767
  ["thinking", 'reasoning: "off" or provider_options.thinking'],
100733
100768
  ["textVerbosity", "provider_options.textVerbosity"],
100734
- ["fallback_models", "models"]
100769
+ ["fallback_models", "models: [<primary>, ...fallbacks] (the first entry becomes the primary model)"]
100735
100770
  ]);
100771
+ var MIGRATE_SUFFIX = ", or run: oh-my-openagent config migrate";
100736
100772
  var TUNING_CONTAINERS = new Set(["agents", "categories", "models"]);
100737
100773
  var PASSTHROUGH_CONTAINERS = new Set(["provider_options", "providerOptions"]);
100738
100774
  function isRecord13(value) {
@@ -100741,7 +100777,7 @@ function isRecord13(value) {
100741
100777
  function isHarnessBlock(key) {
100742
100778
  return key.startsWith("[") && key.endsWith("]");
100743
100779
  }
100744
- function collectIssues(configPath, value, prefix) {
100780
+ function collectIssues(configPath, value, prefix, fixSuffix) {
100745
100781
  if (!isRecord13(value))
100746
100782
  return [];
100747
100783
  const issues = [];
@@ -100752,7 +100788,7 @@ function collectIssues(configPath, value, prefix) {
100752
100788
  issues.push({
100753
100789
  title: "Deprecated config key",
100754
100790
  description: `${configPath}: ${path}`,
100755
- fix: `Replace ${key} with ${replacement}, or run: oh-my-openagent config migrate`,
100791
+ fix: `Replace ${key} with ${replacement}${fixSuffix}`,
100756
100792
  severity: "warning",
100757
100793
  affects: [path]
100758
100794
  });
@@ -100764,18 +100800,23 @@ function collectIssues(configPath, value, prefix) {
100764
100800
  continue;
100765
100801
  if (prefix.length === 0 && key === "profiles") {
100766
100802
  for (const profile of Object.values(child)) {
100767
- issues.push(...collectIssues(configPath, profile, ""));
100803
+ issues.push(...collectIssues(configPath, profile, "", fixSuffix));
100768
100804
  }
100769
100805
  continue;
100770
100806
  }
100771
100807
  if (key === "[opencode]")
100772
100808
  continue;
100773
100809
  if (TUNING_CONTAINERS.has(key) || isHarnessBlock(key) || prefix.length > 0) {
100774
- issues.push(...collectIssues(configPath, child, path));
100810
+ issues.push(...collectIssues(configPath, child, path, fixSuffix));
100775
100811
  }
100776
100812
  }
100777
100813
  return issues;
100778
100814
  }
100815
+ function migrateFixSuffix(parsed) {
100816
+ if (isRecord13(parsed) && hasMigrationMarker(parsed, REASONING_UNIFICATION_MIGRATION_ID))
100817
+ return "";
100818
+ return MIGRATE_SUFFIX;
100819
+ }
100779
100820
  function userConfigPaths() {
100780
100821
  const home = process.env.HOME ?? process.env.USERPROFILE;
100781
100822
  if (home === undefined || home.length === 0)
@@ -100790,7 +100831,7 @@ async function checkDeprecatedReasoningKeys() {
100790
100831
  continue;
100791
100832
  scanned.push(configPath);
100792
100833
  const parsed = parse2(readFileSync33(configPath, "utf-8"));
100793
- issues.push(...collectIssues(configPath, parsed, ""));
100834
+ issues.push(...collectIssues(configPath, parsed, "", migrateFixSuffix(parsed)));
100794
100835
  }
100795
100836
  return {
100796
100837
  name: CHECK_NAMES[CHECK_IDS.CONFIG],
@@ -101916,6 +101957,24 @@ async function pathExists2(path) {
101916
101957
  }
101917
101958
  }
101918
101959
 
101960
+ // packages/omo-opencode/src/cli/doctor/checks/latest-version.ts
101961
+ init_auto_update_checker();
101962
+ function gatherEditionDistTags(target, fetchDistTags = fetchNpmDistTags) {
101963
+ return fetchDistTags(EDITION_PACKAGE_NAMES[target]);
101964
+ }
101965
+ function resolveInstalledVersion(input) {
101966
+ if (input.target === "codex" && input.codex) {
101967
+ return input.codex.packageVersion ?? input.codex.installerVersion;
101968
+ }
101969
+ return input.systemInfo.pluginVersion;
101970
+ }
101971
+ function resolveLatestVersion(input) {
101972
+ if (!input.distTags)
101973
+ return null;
101974
+ const channel = extractChannel(resolveInstalledVersion(input));
101975
+ return input.distTags[channel] ?? input.distTags.latest ?? null;
101976
+ }
101977
+
101919
101978
  // packages/omo-opencode/src/cli/doctor/checks/codex-components.ts
101920
101979
  init_src();
101921
101980
  import { readdir as readdir15, readFile as readFile28, stat as stat7 } from "node:fs/promises";
@@ -102326,7 +102385,6 @@ function getCodexCheckDefinitions() {
102326
102385
  }
102327
102386
 
102328
102387
  // packages/omo-opencode/src/cli/doctor/framework/format-default.ts
102329
- init_shared();
102330
102388
  var import_picocolors19 = __toESM(require_picocolors(), 1);
102331
102389
 
102332
102390
  // packages/omo-opencode/src/cli/doctor/framework/format-shared.ts
@@ -102368,23 +102426,27 @@ function formatIssue(issue, index) {
102368
102426
  }
102369
102427
 
102370
102428
  // packages/omo-opencode/src/cli/doctor/framework/format-default.ts
102429
+ function formatOkSummary(result, headline, installedVersion) {
102430
+ const target = result.target ?? "opencode";
102431
+ const latest = result.latestVersion ?? LATEST_UNAVAILABLE_TEXT;
102432
+ return [
102433
+ ` ${import_picocolors19.default.green(SYMBOLS2.check)} ${import_picocolors19.default.green(`${headline} · Edition: ${EDITION_LABELS[target]} · Installed: ${installedVersion} · Latest: ${latest}`)}`,
102434
+ ` Update: ${UPDATE_COMMANDS[target]}`
102435
+ ];
102436
+ }
102371
102437
  function formatDefault(result) {
102372
102438
  const lines = [];
102373
102439
  lines.push(formatHeader());
102374
102440
  const allIssues = result.results.flatMap((r) => r.issues);
102375
102441
  if (allIssues.length === 0) {
102376
102442
  if (result.target === "codex" && result.codex) {
102377
- const codex = result.codex.codexPath ?? result.codex.codexAppId ?? "unknown";
102378
- const pluginVer = result.codex.pluginVersion ?? "unknown";
102379
- const packageName = result.codex.packageName ?? "lazycodex-ai";
102380
102443
  const packageVer = result.codex.packageVersion ?? result.codex.installerVersion;
102381
- lines.push(` ${import_picocolors19.default.green(SYMBOLS2.check)} ${import_picocolors19.default.green(`LazyCodex OK (codex ${codex} · omo ${pluginVer} · ${packageName} ${packageVer})`)}`);
102444
+ lines.push(...formatOkSummary(result, "LazyCodex OK", packageVer));
102382
102445
  return lines.join(`
102383
102446
  `);
102384
102447
  }
102385
- const opencodeVer = result.systemInfo.opencodeVersion ?? "unknown";
102386
102448
  const pluginVer = result.systemInfo.pluginVersion ?? "unknown";
102387
- lines.push(` ${import_picocolors19.default.green(SYMBOLS2.check)} ${import_picocolors19.default.green(`System OK (opencode ${opencodeVer} · oh-my-opencode ${pluginVer})`.replace("oh-my-opencode", PLUGIN_NAME))}`);
102449
+ lines.push(...formatOkSummary(result, "System OK", pluginVer));
102388
102450
  } else {
102389
102451
  const issueCount = allIssues.filter((i) => i.severity === "error").length;
102390
102452
  const warnCount = allIssues.filter((i) => i.severity === "warning").length;
@@ -102631,7 +102693,8 @@ function buildTimeoutResult(start, options) {
102631
102693
  systemInfo: { opencodeVersion: null, opencodePath: null, pluginVersion: null, loadedVersion: null, bunVersion: null, configPath: null, configValid: false, isLocalDev: false },
102632
102694
  tools: { lspServers: [], astGrepCli: false, commentChecker: false, ghCli: { installed: false, authenticated: false, username: null }, mcpBuiltin: [], mcpUser: [] },
102633
102695
  summary: { total: 1, passed: 0, failed: 1, warnings: 0, skipped: 0, duration: Math.round(performance.now() - start) },
102634
- exitCode: EXIT_CODES.FAILURE
102696
+ exitCode: EXIT_CODES.FAILURE,
102697
+ latestVersion: null
102635
102698
  };
102636
102699
  if (options.json) {
102637
102700
  console.log(formatJsonOutput2(timeoutResult));
@@ -102651,7 +102714,8 @@ async function runDoctor(options) {
102651
102714
  Promise.all(allChecks.map(runCheck)),
102652
102715
  gatherSystemInfo(),
102653
102716
  gatherToolsSummary(),
102654
- target === "codex" ? gatherCodexSummary() : Promise.resolve(undefined)
102717
+ target === "codex" ? gatherCodexSummary() : Promise.resolve(undefined),
102718
+ gatherEditionDistTags(target)
102655
102719
  ]);
102656
102720
  let timer;
102657
102721
  const timeoutPromise = new Promise((_, reject) => {
@@ -102661,8 +102725,9 @@ async function runDoctor(options) {
102661
102725
  let systemInfo;
102662
102726
  let tools;
102663
102727
  let codex;
102728
+ let distTags;
102664
102729
  try {
102665
- [results, systemInfo, tools, codex] = await Promise.race([checksPromise, timeoutPromise]);
102730
+ [results, systemInfo, tools, codex, distTags] = await Promise.race([checksPromise, timeoutPromise]);
102666
102731
  } catch (error) {
102667
102732
  clearTimeout(timer);
102668
102733
  if (error instanceof DoctorTimeoutError) {
@@ -102681,7 +102746,8 @@ async function runDoctor(options) {
102681
102746
  summary,
102682
102747
  exitCode,
102683
102748
  target,
102684
- codex
102749
+ codex,
102750
+ latestVersion: resolveLatestVersion({ target, systemInfo, codex, distTags })
102685
102751
  };
102686
102752
  if (options.json) {
102687
102753
  console.log(formatJsonOutput2(doctorResult));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lazycodex-ai",
3
- "version": "5.0.0-beta.50",
3
+ "version": "5.0.0-beta.52",
4
4
  "description": "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
5
5
  "main": "./dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -6833,8 +6833,7 @@ async function validateExistingOwner(paths, pingOwner) {
6833
6833
  if (isProcessAlive2(owner.pid))
6834
6834
  throw new DaemonStartupDeferredError("owner_pid_live_unreachable");
6835
6835
  const reread = readDaemonOwner(paths);
6836
- const endpoint = endpointIdentity(owner.endpoint.path);
6837
- if (!reread || reread.nonce !== owner.nonce || !sameEndpoint(endpoint, owner.endpoint)) {
6836
+ if (!reread || !sameOwner(reread, owner)) {
6838
6837
  throw new DaemonStartupDeferredError("owner_changed_during_cleanup");
6839
6838
  }
6840
6839
  cleanupDeadOwner(paths, owner);
@@ -107,9 +107,9 @@ async function validateExistingOwner(paths, pingOwner) {
107
107
  continue;
108
108
  if (isProcessAlive(owner.pid))
109
109
  throw new DaemonStartupDeferredError("owner_pid_live_unreachable");
110
+ // Compare the two file reads only: a live socket stat drifts across reboots (st_dev, tmpfs) while the pid is dead.
110
111
  const reread = readDaemonOwner(paths);
111
- const endpoint = endpointIdentity(owner.endpoint.path);
112
- if (!reread || reread.nonce !== owner.nonce || !sameEndpoint(endpoint, owner.endpoint)) {
112
+ if (!reread || !sameOwner(reread, owner)) {
113
113
  throw new DaemonStartupDeferredError("owner_changed_during_cleanup");
114
114
  }
115
115
  cleanupDeadOwner(paths, owner);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omo",
3
- "version": "5.0.0-beta.50",
3
+ "version": "5.0.0-beta.52",
4
4
  "description": "One Codex plugin namespace for Yeongyu's local Codex components.",
5
5
  "author": {
6
6
  "name": "Yeongyu Kim",
@@ -3260,7 +3260,7 @@ var CODEX_AGENTS_HEADER = "agents";
3260
3260
  var CODEX_MULTI_AGENT_V2_HEADER = "features.multi_agent_v2";
3261
3261
  function ensureCodexMultiAgentV2Config(config, options = {}) {
3262
3262
  const featureFlag = removeFeatureFlagSetting(config, "multi_agent_v2");
3263
- const v2Preferred = options.multiAgentVersion === "v2";
3263
+ const v2Preferred = options.multiAgentVersion === "v2" || isMultiAgentV2Enabled(featureFlag.config);
3264
3264
  const agentsConfig = removeAgentsMaxThreads(featureFlag.config, v2Preferred);
3265
3265
  const preserveDisable = featureFlag.value === false && !v2Preferred;
3266
3266
  const featureConfig = preserveDisable ? setMultiAgentV2Disable(agentsConfig) : v2Preferred ? removeMultiAgentV2Disable(agentsConfig) : agentsConfig;
@@ -3339,6 +3339,10 @@ function removeFeatureFlagSetting(config, featureName) {
3339
3339
  value: readBooleanSetting(section.text, featureName)
3340
3340
  };
3341
3341
  }
3342
+ function isMultiAgentV2Enabled(config) {
3343
+ const section = findTomlSection(config, CODEX_MULTI_AGENT_V2_HEADER);
3344
+ return section !== null && /^\s*enabled\s*=\s*true[ \t]*(?:#.*)?$/m.test(section.text);
3345
+ }
3342
3346
  function removeAgentsMaxThreads(config, v2Preferred) {
3343
3347
  const section = findTomlSection(config, CODEX_AGENTS_HEADER);
3344
3348
  if (!section)
@@ -8,7 +8,7 @@
8
8
  "command": "node \"${PLUGIN_ROOT}/components/bootstrap/dist/cli.js\" hook session-start",
9
9
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\bootstrap.ps1\"",
10
10
  "timeout": 30,
11
- "statusMessage": "(OmO 5.0.0-beta.50) Checking Bootstrap Provisioning"
11
+ "statusMessage": "(OmO 5.0.0-beta.52) Checking Bootstrap Provisioning"
12
12
  }
13
13
  ]
14
14
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sisyphuslabs/codex-bootstrap",
3
- "version": "5.0.0-beta.50",
3
+ "version": "5.0.0-beta.52",
4
4
  "description": "Codex SessionStart bootstrap component that provisions LazyCodex runtime dependencies from a detached worker.",
5
5
  "type": "module",
6
6
  "private": true,
@@ -8,7 +8,7 @@
8
8
  "type": "command",
9
9
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-tool-use",
10
10
  "timeout": 30,
11
- "statusMessage": "(OmO 5.0.0-beta.50) Checking Comments"
11
+ "statusMessage": "(OmO 5.0.0-beta.52) Checking Comments"
12
12
  }
13
13
  ]
14
14
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-comment-checker",
3
- "version": "5.0.0-beta.50",
3
+ "version": "5.0.0-beta.52",
4
4
  "description": "Codex plugin that runs comment-checker after edit-like PostToolUse hooks.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -5,7 +5,7 @@ import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
5
5
  import { homedir } from "node:os";
6
6
  import { dirname, join } from "node:path";
7
7
  var BASH_TOOL_NAME = "Bash";
8
- var REMINDER = "On Windows, prefer the OMO git_bash MCP for shell commands before using built-in exec_command. Use exec_command only when git_bash is unavailable or for non-shell operations.";
8
+ var REMINDER = "On Windows, prefer the OMO git_bash MCP for shell commands before using built-in exec_command. Use exec_command only when git_bash is unavailable or for non-shell operations. " + "In code mode, these tools may be deferred: inspect ALL_TOOLS with exec to discover the actual git_bash run, diagnose, and which_bash tool names, then invoke the matching entries through the tools object inside exec before treating git_bash as unavailable. Do not issue deferred names as top-level tool calls.";
9
9
  function parsePreToolUsePayload(raw) {
10
10
  if (raw.trim().length === 0)
11
11
  return null;
@@ -2,7 +2,8 @@ import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
3
  import { dirname, join } from "node:path";
4
4
  const BASH_TOOL_NAME = "Bash";
5
- const REMINDER = "On Windows, prefer the OMO git_bash MCP for shell commands before using built-in exec_command. Use exec_command only when git_bash is unavailable or for non-shell operations.";
5
+ const REMINDER = "On Windows, prefer the OMO git_bash MCP for shell commands before using built-in exec_command. Use exec_command only when git_bash is unavailable or for non-shell operations. " +
6
+ "In code mode, these tools may be deferred: inspect ALL_TOOLS with exec to discover the actual git_bash run, diagnose, and which_bash tool names, then invoke the matching entries through the tools object inside exec before treating git_bash as unavailable. Do not issue deferred names as top-level tool calls.";
6
7
  export function parsePreToolUsePayload(raw) {
7
8
  if (raw.trim().length === 0)
8
9
  return null;
@@ -8,7 +8,7 @@
8
8
  "type": "command",
9
9
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook pre-tool-use",
10
10
  "timeout": 5,
11
- "statusMessage": "(OmO 5.0.0-beta.50) Recommending Git Bash MCP"
11
+ "statusMessage": "(OmO 5.0.0-beta.52) Recommending Git Bash MCP"
12
12
  }
13
13
  ]
14
14
  }
@@ -20,7 +20,7 @@
20
20
  "type": "command",
21
21
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-compact",
22
22
  "timeout": 5,
23
- "statusMessage": "(OmO 5.0.0-beta.50) Resetting Git Bash MCP Reminder"
23
+ "statusMessage": "(OmO 5.0.0-beta.52) Resetting Git Bash MCP Reminder"
24
24
  }
25
25
  ]
26
26
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sisyphuslabs/codex-git-bash-hook",
3
- "version": "5.0.0-beta.50",
3
+ "version": "5.0.0-beta.52",
4
4
  "description": "Codex hook component that reminds Windows sessions to prefer the OMO git_bash MCP.",
5
5
  "type": "module",
6
6
  "private": true,
@@ -37,7 +37,8 @@ interface PreToolUseHookOutput {
37
37
 
38
38
  const BASH_TOOL_NAME = "Bash";
39
39
  const REMINDER =
40
- "On Windows, prefer the OMO git_bash MCP for shell commands before using built-in exec_command. Use exec_command only when git_bash is unavailable or for non-shell operations.";
40
+ "On Windows, prefer the OMO git_bash MCP for shell commands before using built-in exec_command. Use exec_command only when git_bash is unavailable or for non-shell operations. " +
41
+ "In code mode, these tools may be deferred: inspect ALL_TOOLS with exec to discover the actual git_bash run, diagnose, and which_bash tool names, then invoke the matching entries through the tools object inside exec before treating git_bash as unavailable. Do not issue deferred names as top-level tool calls.";
41
42
 
42
43
  export function parsePreToolUsePayload(raw: string): PreToolUsePayload | null {
43
44
  if (raw.trim().length === 0) return null;
@@ -81,8 +81,7 @@ describe("applyGitBashPreToolUseReminder", () => {
81
81
  const parsed = JSON.parse(output);
82
82
  expect(parsed.hookSpecificOutput).toEqual({
83
83
  hookEventName: "PreToolUse",
84
- additionalContext:
85
- "On Windows, prefer the OMO git_bash MCP for shell commands before using built-in exec_command. Use exec_command only when git_bash is unavailable or for non-shell operations.",
84
+ additionalContext: expect.any(String),
86
85
  });
87
86
  });
88
87
 
@@ -96,7 +95,7 @@ describe("applyGitBashPreToolUseReminder", () => {
96
95
  const second = applyGitBashPreToolUseReminder(payload, { env: windowsEnv(), platform: "linux", pluginDataRoot });
97
96
 
98
97
  // then
99
- expect(first).toContain("git_bash");
98
+ expect(JSON.parse(first).hookSpecificOutput.hookEventName).toBe("PreToolUse");
100
99
  expect(second).toBe("");
101
100
  });
102
101
 
@@ -148,9 +147,9 @@ describe("applyGitBashPostCompactReset", () => {
148
147
  });
149
148
 
150
149
  // then
151
- expect(first).toContain("git_bash");
150
+ expect(JSON.parse(first).hookSpecificOutput.hookEventName).toBe("PreToolUse");
152
151
  expect(second).toBe("");
153
- expect(afterCompact).toContain("git_bash");
152
+ expect(JSON.parse(afterCompact).hookSpecificOutput.hookEventName).toBe("PreToolUse");
154
153
  });
155
154
  });
156
155
 
@@ -169,7 +168,7 @@ describe("runGitBashHookCli", () => {
169
168
  });
170
169
 
171
170
  // then
172
- expect(capture.read()).toContain("git_bash MCP");
171
+ expect(JSON.parse(capture.read()).hookSpecificOutput.hookEventName).toBe("PreToolUse");
173
172
  });
174
173
 
175
174
  it("#given PostCompact stdin #when CLI hook runs #then it resets the one-shot reminder", async () => {
@@ -190,6 +189,6 @@ describe("runGitBashHookCli", () => {
190
189
 
191
190
  // then
192
191
  expect(capture.read()).toBe("");
193
- expect(afterCompact).toContain("git_bash");
192
+ expect(JSON.parse(afterCompact).hookSpecificOutput.hookEventName).toBe("PreToolUse");
194
193
  });
195
194
  });
@@ -8,7 +8,7 @@
8
8
  "type": "command",
9
9
  "command": "node \"${PLUGIN_ROOT}/components/lazycodex-executor-verify/dist/cli.js\" hook subagent-stop",
10
10
  "timeout": 10,
11
- "statusMessage": "(OmO 5.0.0-beta.50) Verifying LazyCodex Executor Evidence"
11
+ "statusMessage": "(OmO 5.0.0-beta.52) Verifying LazyCodex Executor Evidence"
12
12
  }
13
13
  ]
14
14
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-lazycodex-executor-verify",
3
- "version": "5.0.0-beta.50",
3
+ "version": "5.0.0-beta.52",
4
4
  "description": "Codex SubagentStop evidence verifier for LazyCodex executor completions.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "version": "5.0.0-beta.50",
4
- "inputDigest": "sha256:27672c2cd34eb3b44fc226b7e4e9137af0d0acedbb729fe92cdd663602ae6846",
3
+ "version": "5.0.0-beta.52",
4
+ "inputDigest": "sha256:8674d4fcd17586aabee0cf663798fa9c40792359db3eca9bb5f99c88594f89df",
5
5
  "outputs": [
6
6
  {
7
7
  "path": "cli.d.ts",
@@ -8,7 +8,7 @@
8
8
  "type": "command",
9
9
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-tool-use",
10
10
  "timeout": 60,
11
- "statusMessage": "(OmO 5.0.0-beta.50) Checking LSP Diagnostics"
11
+ "statusMessage": "(OmO 5.0.0-beta.52) Checking LSP Diagnostics"
12
12
  }
13
13
  ]
14
14
  }
@@ -21,7 +21,7 @@
21
21
  "type": "command",
22
22
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-compact",
23
23
  "timeout": 5,
24
- "statusMessage": "(OmO 5.0.0-beta.50) Resetting LSP Diagnostics Cache"
24
+ "statusMessage": "(OmO 5.0.0-beta.52) Resetting LSP Diagnostics Cache"
25
25
  }
26
26
  ]
27
27
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-lsp",
3
- "version": "5.0.0-beta.50",
3
+ "version": "5.0.0-beta.52",
4
4
  "description": "Codex plugin that exposes Language Server Protocol tools and post-edit diagnostics.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",