lazycodex-ai 5.0.0-beta.51 → 5.0.0-beta.53

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 (83) hide show
  1. package/README.ja.md +11 -18
  2. package/README.ko.md +10 -17
  3. package/README.md +11 -18
  4. package/README.ru.md +11 -18
  5. package/README.zh-cn.md +11 -18
  6. package/dist/cli/doctor/checks/index.d.ts +2 -0
  7. package/dist/cli/doctor/checks/latest-version.d.ts +11 -0
  8. package/dist/cli/doctor/framework/constants.d.ts +5 -0
  9. package/dist/cli/doctor/framework/types.d.ts +2 -0
  10. package/dist/cli/index.js +181 -63
  11. package/dist/cli-node/index.js +181 -63
  12. package/package.json +1 -1
  13. package/packages/lsp-daemon/dist/cli.js +1 -2
  14. package/packages/lsp-daemon/dist/ownership.js +2 -2
  15. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  16. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  17. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  18. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  19. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  20. package/packages/omo-codex/plugin/components/git-bash/dist/cli.js +1 -1
  21. package/packages/omo-codex/plugin/components/git-bash/dist/codex-hook.js +2 -1
  22. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  23. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  24. package/packages/omo-codex/plugin/components/git-bash/src/codex-hook.ts +2 -1
  25. package/packages/omo-codex/plugin/components/git-bash/test/codex-hook.test.ts +6 -7
  26. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  27. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  28. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
  29. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  30. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  31. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  32. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  33. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  34. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  35. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  36. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  37. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  38. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  39. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
  40. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
  41. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
  42. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -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/skills/frontend/ATTRIBUTION.md +10 -0
  67. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +3 -0
  68. package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +10 -2
  69. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +1 -0
  70. package/packages/omo-codex/plugin/skills/frontend/references/design/ambience-skill.md +145 -0
  71. package/packages/omo-codex/plugin/skills/frontend/references/design/interaction-skill.md +2 -0
  72. package/packages/omo-codex/plugin/skills/refactor/SKILL.md +3 -3
  73. package/packages/omo-codex/plugin/skills/ulw-execute/SKILL.md +5 -5
  74. package/packages/omo-codex/scripts/install-dist/install-local.mjs +2 -2
  75. package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +10 -0
  76. package/packages/shared-skills/skills/frontend/SKILL.md +3 -0
  77. package/packages/shared-skills/skills/frontend/references/design/README.md +10 -2
  78. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +1 -0
  79. package/packages/shared-skills/skills/frontend/references/design/ambience-skill.md +145 -0
  80. package/packages/shared-skills/skills/frontend/references/design/interaction-skill.md +2 -0
  81. package/packages/shared-skills/skills/refactor/SKILL.md +3 -3
  82. package/packages/shared-skills/skills/review-work/SKILL.md +1 -1
  83. package/packages/shared-skills/skills/ulw-execute/SKILL.md +5 -5
package/dist/cli/index.js CHANGED
@@ -64,7 +64,7 @@ var package_default;
64
64
  var init_package = __esm(() => {
65
65
  package_default = {
66
66
  name: "oh-my-opencode",
67
- version: "5.0.0-beta.51",
67
+ version: "5.0.0-beta.53",
68
68
  description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
69
69
  main: "./dist/index.js",
70
70
  types: "dist/index.d.ts",
@@ -248,7 +248,7 @@ var init_package = __esm(() => {
248
248
  zod: "^4.4.3"
249
249
  },
250
250
  devDependencies: {
251
- "@code-yeongyu/senpi": "2026.9.9-2",
251
+ "@code-yeongyu/senpi": "2026.9.10-2",
252
252
  "@oh-my-opencode/agents-md-core": "workspace:*",
253
253
  "@oh-my-opencode/ast-grep-mcp": "workspace:*",
254
254
  "@oh-my-opencode/boulder-state": "workspace:*",
@@ -289,18 +289,18 @@ var init_package = __esm(() => {
289
289
  typescript: "^7.0.2"
290
290
  },
291
291
  optionalDependencies: {
292
- "oh-my-opencode-darwin-arm64": "5.0.0-beta.51",
293
- "oh-my-opencode-darwin-x64": "5.0.0-beta.51",
294
- "oh-my-opencode-darwin-x64-baseline": "5.0.0-beta.51",
295
- "oh-my-opencode-linux-arm64": "5.0.0-beta.51",
296
- "oh-my-opencode-linux-arm64-musl": "5.0.0-beta.51",
297
- "oh-my-opencode-linux-x64": "5.0.0-beta.51",
298
- "oh-my-opencode-linux-x64-baseline": "5.0.0-beta.51",
299
- "oh-my-opencode-linux-x64-musl": "5.0.0-beta.51",
300
- "oh-my-opencode-linux-x64-musl-baseline": "5.0.0-beta.51",
301
- "oh-my-opencode-windows-arm64": "5.0.0-beta.51",
302
- "oh-my-opencode-windows-x64": "5.0.0-beta.51",
303
- "oh-my-opencode-windows-x64-baseline": "5.0.0-beta.51"
292
+ "oh-my-opencode-darwin-arm64": "5.0.0-beta.53",
293
+ "oh-my-opencode-darwin-x64": "5.0.0-beta.53",
294
+ "oh-my-opencode-darwin-x64-baseline": "5.0.0-beta.53",
295
+ "oh-my-opencode-linux-arm64": "5.0.0-beta.53",
296
+ "oh-my-opencode-linux-arm64-musl": "5.0.0-beta.53",
297
+ "oh-my-opencode-linux-x64": "5.0.0-beta.53",
298
+ "oh-my-opencode-linux-x64-baseline": "5.0.0-beta.53",
299
+ "oh-my-opencode-linux-x64-musl": "5.0.0-beta.53",
300
+ "oh-my-opencode-linux-x64-musl-baseline": "5.0.0-beta.53",
301
+ "oh-my-opencode-windows-arm64": "5.0.0-beta.53",
302
+ "oh-my-opencode-windows-x64": "5.0.0-beta.53",
303
+ "oh-my-opencode-windows-x64-baseline": "5.0.0-beta.53"
304
304
  },
305
305
  overrides: {
306
306
  "@earendil-works/pi-agent-core": "0.84.2",
@@ -64424,6 +64424,7 @@ var init_injector = __esm(() => {
64424
64424
  var init_hook_message_injector = __esm(() => {
64425
64425
  init_injector();
64426
64426
  init_constants2();
64427
+ init_id_generation();
64427
64428
  });
64428
64429
 
64429
64430
  // packages/omo-opencode/src/shared/opencode-message-dir.ts
@@ -72838,6 +72839,25 @@ var init_model_catalog = __esm(() => {
72838
72839
  OmoModelCatalogLayerSchema = record(string2(), OmoModelCatalogEntryLayerSchema);
72839
72840
  });
72840
72841
 
72842
+ // packages/omo-config-core/src/schema/model-profile.ts
72843
+ function isRecord8(value) {
72844
+ return typeof value === "object" && value !== null && !Array.isArray(value);
72845
+ }
72846
+ var OmoModelProfileInputSchema, OmoModelProfileSchema, OmoModelProfilesSchema, OmoModelProfileLayerInputSchema, OmoModelProfileLayerSchema, OmoModelProfilesLayerSchema;
72847
+ var init_model_profile = __esm(() => {
72848
+ init_zod();
72849
+ init_fallback_models();
72850
+ OmoModelProfileInputSchema = object({
72851
+ display_name: string2().optional(),
72852
+ models: array(union([string2(), OmoFallbackModelObjectSchema])).optional()
72853
+ }).strict();
72854
+ OmoModelProfileSchema = preprocess((value) => isRecord8(value) ? normalizeLegacyModelFields(value) : value, OmoModelProfileInputSchema);
72855
+ OmoModelProfilesSchema = record(string2(), OmoModelProfileSchema);
72856
+ OmoModelProfileLayerInputSchema = OmoModelProfileInputSchema.partial();
72857
+ OmoModelProfileLayerSchema = preprocess((value) => isRecord8(value) ? normalizeLegacyModelFields(value) : value, OmoModelProfileLayerInputSchema);
72858
+ OmoModelProfilesLayerSchema = record(string2(), OmoModelProfileLayerSchema);
72859
+ });
72860
+
72841
72861
  // packages/omo-config-core/src/schema/task.ts
72842
72862
  import { availableParallelism } from "os";
72843
72863
  function resolveOmoTaskSettings(input, resolveParallelism = availableParallelism) {
@@ -73030,6 +73050,7 @@ var init_config = __esm(() => {
73030
73050
  init_git_master();
73031
73051
  init_memory();
73032
73052
  init_model_catalog();
73053
+ init_model_profile();
73033
73054
  init_task();
73034
73055
  init_team();
73035
73056
  init_telemetry();
@@ -73043,6 +73064,8 @@ var init_config = __esm(() => {
73043
73064
  task: OmoTaskSettingsLayerSchema.optional(),
73044
73065
  teams: OmoTeamsConfigLayerSchema.optional(),
73045
73066
  models: OmoModelCatalogLayerSchema.optional(),
73067
+ model_profiles: OmoModelProfilesLayerSchema.optional(),
73068
+ model_profile: string2().optional(),
73046
73069
  memory: OmoMemorySettingsLayerSchema.optional(),
73047
73070
  telemetry: OmoTelemetrySettingsLayerSchema.optional()
73048
73071
  }).strict();
@@ -73054,6 +73077,8 @@ var init_config = __esm(() => {
73054
73077
  task: OmoTaskSettingsLayerSchema.optional(),
73055
73078
  teams: OmoTeamsConfigLayerSchema.optional(),
73056
73079
  models: OmoModelCatalogLayerSchema.optional(),
73080
+ model_profiles: OmoModelProfilesLayerSchema.optional(),
73081
+ model_profile: string2().optional(),
73057
73082
  memory: OmoMemorySettingsLayerSchema.optional(),
73058
73083
  telemetry: OmoTelemetrySettingsLayerSchema.optional(),
73059
73084
  "[opencode]": OmoOpenCodeHarnessConfigSchema.optional(),
@@ -73069,6 +73094,8 @@ var init_config = __esm(() => {
73069
73094
  task: OmoTaskSettingsSchema.optional(),
73070
73095
  teams: OmoTeamsConfigSchema.optional(),
73071
73096
  models: OmoModelCatalogSchema.optional(),
73097
+ model_profiles: OmoModelProfilesSchema.optional(),
73098
+ model_profile: string2().optional(),
73072
73099
  memory: OmoMemorySettingsSchema.optional(),
73073
73100
  telemetry: OmoTelemetrySettingsSchema.optional(),
73074
73101
  "[opencode]": OmoOpenCodeHarnessConfigSchema.optional(),
@@ -73087,6 +73114,8 @@ var init_config = __esm(() => {
73087
73114
  task: OmoTaskSettingsLayerSchema.optional(),
73088
73115
  teams: OmoTeamsConfigLayerSchema.optional(),
73089
73116
  models: OmoModelCatalogLayerSchema.optional(),
73117
+ model_profiles: OmoModelProfilesLayerSchema.optional(),
73118
+ model_profile: string2().optional(),
73090
73119
  memory: OmoMemorySettingsLayerSchema.optional(),
73091
73120
  telemetry: OmoTelemetrySettingsLayerSchema.optional(),
73092
73121
  "[opencode]": OmoOpenCodeHarnessConfigSchema.optional(),
@@ -73109,6 +73138,7 @@ var init_schema = __esm(() => {
73109
73138
  init_harness();
73110
73139
  init_memory();
73111
73140
  init_model_catalog();
73141
+ init_model_profile();
73112
73142
  init_model_ref();
73113
73143
  init_task();
73114
73144
  init_team();
@@ -73359,29 +73389,27 @@ function validationDiagnostic(path, issues) {
73359
73389
  function unrecognizedKeyIssues(issues) {
73360
73390
  return issues.flatMap((issue) => issue.code === "unrecognized_keys" ? [{ keys: issue.keys, path: issue.path.map((segment) => String(segment)) }] : []);
73361
73391
  }
73362
- function hasUnsafeUnrecognizedKey(parsed, issues) {
73363
- if (issues.some((issue) => issue.keys.some((key) => isUnsafeObjectKey2(key))))
73364
- return true;
73365
- return hasTamperedPrototype(parsed);
73392
+ function hasUnsafeUnrecognizedKey(issues) {
73393
+ return issues.some((issue) => issue.keys.some((key) => isUnsafeObjectKey2(key)));
73366
73394
  }
73367
73395
  function hasTamperedPrototype(value) {
73368
73396
  if (Array.isArray(value))
73369
73397
  return value.some((entry) => hasTamperedPrototype(entry));
73370
- if (!isRecord8(value))
73398
+ if (!isRecord9(value))
73371
73399
  return false;
73372
73400
  const prototype = Object.getPrototypeOf(value);
73373
73401
  if (prototype !== Object.prototype && prototype !== null)
73374
73402
  return true;
73375
73403
  return Object.values(value).some((entry) => hasTamperedPrototype(entry));
73376
73404
  }
73377
- function isRecord8(value) {
73405
+ function isRecord9(value) {
73378
73406
  return typeof value === "object" && value !== null && !Array.isArray(value);
73379
73407
  }
73380
73408
  function containerAt(record, path) {
73381
73409
  let container = record;
73382
73410
  for (const segment of path) {
73383
73411
  const next = container[segment];
73384
- if (!isRecord8(next))
73412
+ if (!isRecord9(next))
73385
73413
  return null;
73386
73414
  container = next;
73387
73415
  }
@@ -73435,11 +73463,17 @@ function readConfigSource(path, scope, fileSystem) {
73435
73463
  source: { exists: true, loaded: false, path, scope }
73436
73464
  };
73437
73465
  }
73466
+ if (hasTamperedPrototype(parsed.data)) {
73467
+ return {
73468
+ diagnostic: { kind: "validation", message: `Invalid omo config at ${path}: "__proto__" member is not allowed`, path },
73469
+ source: { exists: true, loaded: false, path, scope }
73470
+ };
73471
+ }
73438
73472
  const parsedRecord = toRecord2(parsed.data);
73439
73473
  const validation = OmoConfigLayerSchema.safeParse(parsed.data);
73440
73474
  if (!validation.success) {
73441
73475
  const unrecognized = unrecognizedKeyIssues(validation.error.issues);
73442
- if (unrecognized.length > 0 && hasUnsafeUnrecognizedKey(parsed.data, unrecognized)) {
73476
+ if (hasUnsafeUnrecognizedKey(unrecognized)) {
73443
73477
  return {
73444
73478
  diagnostic: validationDiagnostic(path, validation.error.issues),
73445
73479
  source: { exists: true, loaded: false, path, scope }
@@ -73637,6 +73671,38 @@ function resolveCategoryDefinition(definition, catalog, cycleNames) {
73637
73671
  ...definition.fallback_models === undefined ? {} : { fallback_models: resolveFallbackModels(definition.fallback_models, catalog, cycleNames) }
73638
73672
  };
73639
73673
  }
73674
+ function resolveModelProfile(definition, catalog, cycleNames) {
73675
+ return {
73676
+ ...definition,
73677
+ ...definition.models === undefined ? {} : { models: definition.models.map((entry) => resolveModelEntry(entry, catalog, cycleNames)) }
73678
+ };
73679
+ }
73680
+ function profileShadowDiagnostics(view) {
73681
+ if (view.model_profiles === undefined || view.models === undefined)
73682
+ return [];
73683
+ return Object.keys(view.model_profiles).flatMap((name) => view.models?.[name] === undefined ? [] : [{
73684
+ kind: "validation",
73685
+ message: `Model profile "${name}" shadows a model catalog entry of the same name`,
73686
+ path: `model_profiles.${name}`
73687
+ }]);
73688
+ }
73689
+ function profileSpliceDiagnostics(section, definitions, profileNames) {
73690
+ if (definitions === undefined || profileNames.size === 0)
73691
+ return [];
73692
+ return Object.entries(definitions).flatMap(([name, definition]) => (definition.models ?? []).flatMap((entry, index) => typeof entry !== "string" || !profileNames.has(entry) ? [] : [{
73693
+ kind: "validation",
73694
+ message: `"${entry}" is a model profile; splicing a profile into a category chain is not supported yet`,
73695
+ path: `${section}.${name}.models.${index}`
73696
+ }]));
73697
+ }
73698
+ function modelProfileDiagnostics(view) {
73699
+ const profileNames = new Set(Object.keys(view.model_profiles ?? {}));
73700
+ return [
73701
+ ...profileShadowDiagnostics(view),
73702
+ ...profileSpliceDiagnostics("categories", view.categories, profileNames),
73703
+ ...profileSpliceDiagnostics("agents", view.agents, profileNames)
73704
+ ];
73705
+ }
73640
73706
  function cycleDiagnostics(catalog) {
73641
73707
  if (catalog === undefined)
73642
73708
  return [];
@@ -73647,9 +73713,10 @@ function cycleDiagnostics(catalog) {
73647
73713
  }));
73648
73714
  }
73649
73715
  function resolveModelReferences(view) {
73650
- const diagnostics = cycleDiagnostics(view.models);
73716
+ const cycles = cycleDiagnostics(view.models);
73717
+ const diagnostics = [...cycles, ...modelProfileDiagnostics(view)];
73651
73718
  const cycleNames = new Set;
73652
- for (const diagnostic of diagnostics) {
73719
+ for (const diagnostic of cycles) {
73653
73720
  const name = diagnostic.path.split(".")[1];
73654
73721
  if (name !== undefined)
73655
73722
  cycleNames.add(name);
@@ -73662,12 +73729,17 @@ function resolveModelReferences(view) {
73662
73729
  name,
73663
73730
  resolveCategoryDefinition(definition, view.models, cycleNames)
73664
73731
  ]));
73732
+ const modelProfiles = view.model_profiles === undefined ? undefined : Object.fromEntries(Object.entries(view.model_profiles).map(([name, definition]) => [
73733
+ name,
73734
+ resolveModelProfile(definition, view.models, cycleNames)
73735
+ ]));
73665
73736
  return {
73666
73737
  diagnostics,
73667
73738
  view: {
73668
73739
  ...view,
73669
73740
  ...agents === undefined ? {} : { agents },
73670
- ...categories === undefined ? {} : { categories }
73741
+ ...categories === undefined ? {} : { categories },
73742
+ ...modelProfiles === undefined ? {} : { model_profiles: modelProfiles }
73671
73743
  }
73672
73744
  };
73673
73745
  }
@@ -77002,7 +77074,7 @@ function shouldRetainLine(line, cutoffMs) {
77002
77074
  function parseDiagnosticLine(line) {
77003
77075
  try {
77004
77076
  const parsed = JSON.parse(line);
77005
- if (!isRecord10(parsed)) {
77077
+ if (!isRecord11(parsed)) {
77006
77078
  return null;
77007
77079
  }
77008
77080
  return parsed;
@@ -77013,7 +77085,7 @@ function parseDiagnosticLine(line) {
77013
77085
  throw error;
77014
77086
  }
77015
77087
  }
77016
- function isRecord10(value) {
77088
+ function isRecord11(value) {
77017
77089
  return value !== null && typeof value === "object" && !Array.isArray(value);
77018
77090
  }
77019
77091
  function trimToMaxBytes(lines) {
@@ -82387,7 +82459,7 @@ function coerceBool(value) {
82387
82459
  function coerceString(value) {
82388
82460
  return typeof value == "string" ? value : undefined;
82389
82461
  }
82390
- function isRecord11(value) {
82462
+ function isRecord12(value) {
82391
82463
  return typeof value == "object" && value !== null && !Array.isArray(value);
82392
82464
  }
82393
82465
  function toRfc3339(timestamp) {
@@ -82409,7 +82481,7 @@ function relocateInto(properties, key, value) {
82409
82481
  properties[key] = value;
82410
82482
  }
82411
82483
  function buildV1Event(message) {
82412
- const sourceProperties = isRecord11(message.properties) ? message.properties : {};
82484
+ const sourceProperties = isRecord12(message.properties) ? message.properties : {};
82413
82485
  const properties = {
82414
82486
  ...sourceProperties
82415
82487
  };
@@ -84439,7 +84511,7 @@ var package_default2;
84439
84511
  var init_package2 = __esm(() => {
84440
84512
  package_default2 = {
84441
84513
  name: "@oh-my-opencode/omo-codex",
84442
- version: "5.0.0-beta.51",
84514
+ version: "5.0.0-beta.53",
84443
84515
  type: "module",
84444
84516
  private: true,
84445
84517
  description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
@@ -87860,6 +87932,19 @@ var EXIT_CODES = {
87860
87932
  var MIN_OPENCODE_VERSION = "1.4.0";
87861
87933
  var PACKAGE_NAME = PUBLISHED_PACKAGE_NAME;
87862
87934
  var OPENCODE_BINARIES2 = ["opencode", "opencode-desktop"];
87935
+ var EDITION_LABELS = {
87936
+ opencode: "OpenCode",
87937
+ codex: "Codex"
87938
+ };
87939
+ var EDITION_PACKAGE_NAMES = {
87940
+ opencode: PUBLISHED_PACKAGE_NAME,
87941
+ codex: "lazycodex-ai"
87942
+ };
87943
+ var UPDATE_COMMANDS = {
87944
+ opencode: `bunx ${PUBLISHED_PACKAGE_NAME} install`,
87945
+ codex: "npx lazycodex-ai install --no-tui --codex-autonomous"
87946
+ };
87947
+ var LATEST_UNAVAILABLE_TEXT = "could not check";
87863
87948
 
87864
87949
  // packages/omo-opencode/src/cli/minimum-opencode-version.ts
87865
87950
  init_opencode_version();
@@ -90475,10 +90560,10 @@ function readCatalogMultiAgentVersion(model, cachePath) {
90475
90560
  } catch {
90476
90561
  return null;
90477
90562
  }
90478
- if (!isRecord9(cache) || !Array.isArray(cache.models))
90563
+ if (!isRecord10(cache) || !Array.isArray(cache.models))
90479
90564
  return null;
90480
90565
  for (const entry of cache.models) {
90481
- if (!isRecord9(entry))
90566
+ if (!isRecord10(entry))
90482
90567
  continue;
90483
90568
  if (entry.slug !== model && entry.id !== model)
90484
90569
  continue;
@@ -90503,7 +90588,7 @@ function readRootModelCatalogPath(config) {
90503
90588
  const single = config.match(/^\s*model_catalog_json\s*=\s*'([^']+)'/m);
90504
90589
  return single?.[1] ?? null;
90505
90590
  }
90506
- function isRecord9(value) {
90591
+ function isRecord10(value) {
90507
90592
  return typeof value === "object" && value !== null && !Array.isArray(value);
90508
90593
  }
90509
90594
  function removeFeatureFlagSetting(config, featureName) {
@@ -93236,7 +93321,7 @@ async function readSettings(settingsPath) {
93236
93321
  throw error;
93237
93322
  }
93238
93323
  const parsed = JSON.parse(raw);
93239
- if (!isRecord12(parsed))
93324
+ if (!isRecord13(parsed))
93240
93325
  throw new Error(`${settingsPath} must contain a JSON object`);
93241
93326
  return parsed;
93242
93327
  }
@@ -93297,7 +93382,7 @@ async function nextBackupPath(settingsPath) {
93297
93382
  function timestampForBackup() {
93298
93383
  return new Date().toISOString().replace(/[-:.]/g, "");
93299
93384
  }
93300
- function isRecord12(value) {
93385
+ function isRecord13(value) {
93301
93386
  return typeof value === "object" && value !== null && !Array.isArray(value);
93302
93387
  }
93303
93388
  async function readPackageName(packagePath) {
@@ -93317,7 +93402,7 @@ async function readPackageName(packagePath) {
93317
93402
  return;
93318
93403
  throw error;
93319
93404
  }
93320
- return isRecord12(parsed) && typeof parsed.name === "string" ? parsed.name : undefined;
93405
+ return isRecord13(parsed) && typeof parsed.name === "string" ? parsed.name : undefined;
93321
93406
  }
93322
93407
  async function fileExists(path) {
93323
93408
  try {
@@ -93435,7 +93520,7 @@ async function verifyAstGrepRuntimeIntegrity(pluginPath, platform) {
93435
93520
  }
93436
93521
  }
93437
93522
  function isAstGrepRuntimeManifest(value) {
93438
- if (!isRecord12(value))
93523
+ if (!isRecord13(value))
93439
93524
  return false;
93440
93525
  return typeof value.sha256 === "string" && /^[a-f0-9]{64}$/.test(value.sha256) && typeof value.mode === "number" && Number.isInteger(value.mode) && typeof value.stagedAtUtc === "string" && !Number.isNaN(Date.parse(value.stagedAtUtc));
93441
93526
  }
@@ -100659,7 +100744,9 @@ async function checkConfig() {
100659
100744
  }
100660
100745
 
100661
100746
  // packages/omo-opencode/src/cli/doctor/checks/deprecated-reasoning-keys.ts
100747
+ init_src4();
100662
100748
  init_main();
100749
+ init_config_migration();
100663
100750
  import { existsSync as existsSync52, readFileSync as readFileSync33 } from "fs";
100664
100751
  import { join as join78 } from "path";
100665
100752
  var CANONICAL_REPLACEMENT = new Map([
@@ -100667,18 +100754,19 @@ var CANONICAL_REPLACEMENT = new Map([
100667
100754
  ["reasoningEffort", "reasoning"],
100668
100755
  ["thinking", 'reasoning: "off" or provider_options.thinking'],
100669
100756
  ["textVerbosity", "provider_options.textVerbosity"],
100670
- ["fallback_models", "models"]
100757
+ ["fallback_models", "models: [<primary>, ...fallbacks] (the first entry becomes the primary model)"]
100671
100758
  ]);
100759
+ var MIGRATE_SUFFIX = ", or run: oh-my-openagent config migrate";
100672
100760
  var TUNING_CONTAINERS = new Set(["agents", "categories", "models"]);
100673
100761
  var PASSTHROUGH_CONTAINERS = new Set(["provider_options", "providerOptions"]);
100674
- function isRecord13(value) {
100762
+ function isRecord14(value) {
100675
100763
  return value !== null && typeof value === "object" && !Array.isArray(value);
100676
100764
  }
100677
100765
  function isHarnessBlock(key) {
100678
100766
  return key.startsWith("[") && key.endsWith("]");
100679
100767
  }
100680
- function collectIssues(configPath, value, prefix) {
100681
- if (!isRecord13(value))
100768
+ function collectIssues(configPath, value, prefix, fixSuffix) {
100769
+ if (!isRecord14(value))
100682
100770
  return [];
100683
100771
  const issues = [];
100684
100772
  for (const [key, child] of Object.entries(value)) {
@@ -100688,30 +100776,35 @@ function collectIssues(configPath, value, prefix) {
100688
100776
  issues.push({
100689
100777
  title: "Deprecated config key",
100690
100778
  description: `${configPath}: ${path}`,
100691
- fix: `Replace ${key} with ${replacement}, or run: oh-my-openagent config migrate`,
100779
+ fix: `Replace ${key} with ${replacement}${fixSuffix}`,
100692
100780
  severity: "warning",
100693
100781
  affects: [path]
100694
100782
  });
100695
100783
  continue;
100696
100784
  }
100697
- if (!isRecord13(child))
100785
+ if (!isRecord14(child))
100698
100786
  continue;
100699
100787
  if (PASSTHROUGH_CONTAINERS.has(key))
100700
100788
  continue;
100701
100789
  if (prefix.length === 0 && key === "profiles") {
100702
100790
  for (const profile of Object.values(child)) {
100703
- issues.push(...collectIssues(configPath, profile, ""));
100791
+ issues.push(...collectIssues(configPath, profile, "", fixSuffix));
100704
100792
  }
100705
100793
  continue;
100706
100794
  }
100707
100795
  if (key === "[opencode]")
100708
100796
  continue;
100709
100797
  if (TUNING_CONTAINERS.has(key) || isHarnessBlock(key) || prefix.length > 0) {
100710
- issues.push(...collectIssues(configPath, child, path));
100798
+ issues.push(...collectIssues(configPath, child, path, fixSuffix));
100711
100799
  }
100712
100800
  }
100713
100801
  return issues;
100714
100802
  }
100803
+ function migrateFixSuffix(parsed) {
100804
+ if (isRecord14(parsed) && hasMigrationMarker(parsed, REASONING_UNIFICATION_MIGRATION_ID))
100805
+ return "";
100806
+ return MIGRATE_SUFFIX;
100807
+ }
100715
100808
  function userConfigPaths() {
100716
100809
  const home = process.env.HOME ?? process.env.USERPROFILE;
100717
100810
  if (home === undefined || home.length === 0)
@@ -100726,7 +100819,7 @@ async function checkDeprecatedReasoningKeys() {
100726
100819
  continue;
100727
100820
  scanned.push(configPath);
100728
100821
  const parsed = parse2(readFileSync33(configPath, "utf-8"));
100729
- issues.push(...collectIssues(configPath, parsed, ""));
100822
+ issues.push(...collectIssues(configPath, parsed, "", migrateFixSuffix(parsed)));
100730
100823
  }
100731
100824
  return {
100732
100825
  name: CHECK_NAMES[CHECK_IDS.CONFIG],
@@ -101852,6 +101945,24 @@ async function pathExists2(path) {
101852
101945
  }
101853
101946
  }
101854
101947
 
101948
+ // packages/omo-opencode/src/cli/doctor/checks/latest-version.ts
101949
+ init_auto_update_checker();
101950
+ function gatherEditionDistTags(target, fetchDistTags = fetchNpmDistTags) {
101951
+ return fetchDistTags(EDITION_PACKAGE_NAMES[target]);
101952
+ }
101953
+ function resolveInstalledVersion(input) {
101954
+ if (input.target === "codex" && input.codex) {
101955
+ return input.codex.packageVersion ?? input.codex.installerVersion;
101956
+ }
101957
+ return input.systemInfo.pluginVersion;
101958
+ }
101959
+ function resolveLatestVersion(input) {
101960
+ if (!input.distTags)
101961
+ return null;
101962
+ const channel = extractChannel(resolveInstalledVersion(input));
101963
+ return input.distTags[channel] ?? input.distTags.latest ?? null;
101964
+ }
101965
+
101855
101966
  // packages/omo-opencode/src/cli/doctor/checks/codex-components.ts
101856
101967
  init_src();
101857
101968
  import { readdir as readdir15, readFile as readFile28, stat as stat7 } from "fs/promises";
@@ -101928,12 +102039,12 @@ async function auditBundleTargets(pluginRoot) {
101928
102039
  let referencedCount = 0;
101929
102040
  for (const manifestPath of await findManifestPaths(pluginRoot, ".mcp.json")) {
101930
102041
  const manifest = await readJson2(manifestPath);
101931
- if (manifest === null || !isRecord14(manifest["mcpServers"]))
102042
+ if (manifest === null || !isRecord15(manifest["mcpServers"]))
101932
102043
  continue;
101933
102044
  const manifestRoot = dirname33(manifestPath);
101934
102045
  const isRootManifest = resolve24(manifestRoot) === resolve24(pluginRoot);
101935
102046
  for (const server of Object.values(manifest["mcpServers"])) {
101936
- if (!isRecord14(server) || !Array.isArray(server["args"]))
102047
+ if (!isRecord15(server) || !Array.isArray(server["args"]))
101937
102048
  continue;
101938
102049
  for (const arg of server["args"]) {
101939
102050
  if (typeof arg !== "string" || !isPluginRuntimePathArg(arg))
@@ -102019,7 +102130,7 @@ function collectHookCommands(value, commands) {
102019
102130
  collectHookCommands(item, commands);
102020
102131
  return;
102021
102132
  }
102022
- if (!isRecord14(value))
102133
+ if (!isRecord15(value))
102023
102134
  return;
102024
102135
  if (value["type"] === "command") {
102025
102136
  if (typeof value["command"] === "string")
@@ -102074,7 +102185,7 @@ function parseDegradedEntries(value) {
102074
102185
  return [];
102075
102186
  const entries = [];
102076
102187
  for (const item of value) {
102077
- if (!isRecord14(item))
102188
+ if (!isRecord15(item))
102078
102189
  continue;
102079
102190
  if (typeof item["component"] !== "string" || typeof item["reason"] !== "string")
102080
102191
  continue;
@@ -102108,7 +102219,7 @@ function degradedDetailLines(entries) {
102108
102219
  async function readJson2(path) {
102109
102220
  try {
102110
102221
  const parsed = JSON.parse(await readFile28(path, "utf8"));
102111
- return isRecord14(parsed) ? parsed : null;
102222
+ return isRecord15(parsed) ? parsed : null;
102112
102223
  } catch (error) {
102113
102224
  if (error instanceof Error)
102114
102225
  return null;
@@ -102129,7 +102240,7 @@ function normalizeRelative(root, target) {
102129
102240
  function normalizePathSeparators(path) {
102130
102241
  return path.split("\\").join("/");
102131
102242
  }
102132
- function isRecord14(value) {
102243
+ function isRecord15(value) {
102133
102244
  return typeof value === "object" && value !== null && !Array.isArray(value);
102134
102245
  }
102135
102246
 
@@ -102262,7 +102373,6 @@ function getCodexCheckDefinitions() {
102262
102373
  }
102263
102374
 
102264
102375
  // packages/omo-opencode/src/cli/doctor/framework/format-default.ts
102265
- init_shared();
102266
102376
  var import_picocolors19 = __toESM(require_picocolors(), 1);
102267
102377
 
102268
102378
  // packages/omo-opencode/src/cli/doctor/framework/format-shared.ts
@@ -102304,23 +102414,27 @@ function formatIssue(issue, index) {
102304
102414
  }
102305
102415
 
102306
102416
  // packages/omo-opencode/src/cli/doctor/framework/format-default.ts
102417
+ function formatOkSummary(result, headline, installedVersion) {
102418
+ const target = result.target ?? "opencode";
102419
+ const latest = result.latestVersion ?? LATEST_UNAVAILABLE_TEXT;
102420
+ return [
102421
+ ` ${import_picocolors19.default.green(SYMBOLS2.check)} ${import_picocolors19.default.green(`${headline} \xB7 Edition: ${EDITION_LABELS[target]} \xB7 Installed: ${installedVersion} \xB7 Latest: ${latest}`)}`,
102422
+ ` Update: ${UPDATE_COMMANDS[target]}`
102423
+ ];
102424
+ }
102307
102425
  function formatDefault(result) {
102308
102426
  const lines = [];
102309
102427
  lines.push(formatHeader());
102310
102428
  const allIssues = result.results.flatMap((r) => r.issues);
102311
102429
  if (allIssues.length === 0) {
102312
102430
  if (result.target === "codex" && result.codex) {
102313
- const codex = result.codex.codexPath ?? result.codex.codexAppId ?? "unknown";
102314
- const pluginVer = result.codex.pluginVersion ?? "unknown";
102315
- const packageName = result.codex.packageName ?? "lazycodex-ai";
102316
102431
  const packageVer = result.codex.packageVersion ?? result.codex.installerVersion;
102317
- lines.push(` ${import_picocolors19.default.green(SYMBOLS2.check)} ${import_picocolors19.default.green(`LazyCodex OK (codex ${codex} \xB7 omo ${pluginVer} \xB7 ${packageName} ${packageVer})`)}`);
102432
+ lines.push(...formatOkSummary(result, "LazyCodex OK", packageVer));
102318
102433
  return lines.join(`
102319
102434
  `);
102320
102435
  }
102321
- const opencodeVer = result.systemInfo.opencodeVersion ?? "unknown";
102322
102436
  const pluginVer = result.systemInfo.pluginVersion ?? "unknown";
102323
- lines.push(` ${import_picocolors19.default.green(SYMBOLS2.check)} ${import_picocolors19.default.green(`System OK (opencode ${opencodeVer} \xB7 oh-my-opencode ${pluginVer})`.replace("oh-my-opencode", PLUGIN_NAME))}`);
102437
+ lines.push(...formatOkSummary(result, "System OK", pluginVer));
102324
102438
  } else {
102325
102439
  const issueCount = allIssues.filter((i) => i.severity === "error").length;
102326
102440
  const warnCount = allIssues.filter((i) => i.severity === "warning").length;
@@ -102567,7 +102681,8 @@ function buildTimeoutResult(start, options) {
102567
102681
  systemInfo: { opencodeVersion: null, opencodePath: null, pluginVersion: null, loadedVersion: null, bunVersion: null, configPath: null, configValid: false, isLocalDev: false },
102568
102682
  tools: { lspServers: [], astGrepCli: false, commentChecker: false, ghCli: { installed: false, authenticated: false, username: null }, mcpBuiltin: [], mcpUser: [] },
102569
102683
  summary: { total: 1, passed: 0, failed: 1, warnings: 0, skipped: 0, duration: Math.round(performance.now() - start) },
102570
- exitCode: EXIT_CODES.FAILURE
102684
+ exitCode: EXIT_CODES.FAILURE,
102685
+ latestVersion: null
102571
102686
  };
102572
102687
  if (options.json) {
102573
102688
  console.log(formatJsonOutput2(timeoutResult));
@@ -102587,7 +102702,8 @@ async function runDoctor(options) {
102587
102702
  Promise.all(allChecks.map(runCheck)),
102588
102703
  gatherSystemInfo(),
102589
102704
  gatherToolsSummary(),
102590
- target === "codex" ? gatherCodexSummary() : Promise.resolve(undefined)
102705
+ target === "codex" ? gatherCodexSummary() : Promise.resolve(undefined),
102706
+ gatherEditionDistTags(target)
102591
102707
  ]);
102592
102708
  let timer;
102593
102709
  const timeoutPromise = new Promise((_, reject) => {
@@ -102597,8 +102713,9 @@ async function runDoctor(options) {
102597
102713
  let systemInfo;
102598
102714
  let tools;
102599
102715
  let codex;
102716
+ let distTags;
102600
102717
  try {
102601
- [results, systemInfo, tools, codex] = await Promise.race([checksPromise, timeoutPromise]);
102718
+ [results, systemInfo, tools, codex, distTags] = await Promise.race([checksPromise, timeoutPromise]);
102602
102719
  } catch (error) {
102603
102720
  clearTimeout(timer);
102604
102721
  if (error instanceof DoctorTimeoutError) {
@@ -102617,7 +102734,8 @@ async function runDoctor(options) {
102617
102734
  summary,
102618
102735
  exitCode,
102619
102736
  target,
102620
- codex
102737
+ codex,
102738
+ latestVersion: resolveLatestVersion({ target, systemInfo, codex, distTags })
102621
102739
  };
102622
102740
  if (options.json) {
102623
102741
  console.log(formatJsonOutput2(doctorResult));