lazycodex-ai 5.0.0-beta.51 → 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 (73) 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 +88 -37
  6. package/dist/cli-node/index.js +88 -37
  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/hooks/hooks.json +1 -1
  12. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  13. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  14. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  15. package/packages/omo-codex/plugin/components/git-bash/dist/cli.js +1 -1
  16. package/packages/omo-codex/plugin/components/git-bash/dist/codex-hook.js +2 -1
  17. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  18. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  19. package/packages/omo-codex/plugin/components/git-bash/src/codex-hook.ts +2 -1
  20. package/packages/omo-codex/plugin/components/git-bash/test/codex-hook.test.ts +6 -7
  21. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  22. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  23. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
  24. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  25. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  26. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  27. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  28. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  29. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  30. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  31. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  32. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  33. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  34. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
  35. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
  36. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
  37. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  38. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  39. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  40. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  41. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  42. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  43. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  44. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  45. package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
  46. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  47. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  48. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  49. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  50. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  51. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  52. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  53. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
  54. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  55. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  56. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  57. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  58. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  59. package/packages/omo-codex/plugin/package-lock.json +12 -12
  60. package/packages/omo-codex/plugin/package.json +1 -1
  61. package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +10 -0
  62. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +3 -0
  63. package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +10 -2
  64. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +1 -0
  65. package/packages/omo-codex/plugin/skills/frontend/references/design/ambience-skill.md +145 -0
  66. package/packages/omo-codex/plugin/skills/frontend/references/design/interaction-skill.md +2 -0
  67. package/packages/omo-codex/scripts/install-dist/install-local.mjs +2 -2
  68. package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +10 -0
  69. package/packages/shared-skills/skills/frontend/SKILL.md +3 -0
  70. package/packages/shared-skills/skills/frontend/references/design/README.md +10 -2
  71. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +1 -0
  72. package/packages/shared-skills/skills/frontend/references/design/ambience-skill.md +145 -0
  73. package/packages/shared-skills/skills/frontend/references/design/interaction-skill.md +2 -0
@@ -2,9 +2,11 @@ import type { CheckDefinition } from "../framework/types";
2
2
  import { gatherSystemInfo } from "./system";
3
3
  import { gatherToolsSummary } from "./tools";
4
4
  import { gatherCodexSummary } from "./codex";
5
+ import { gatherEditionDistTags, resolveLatestVersion } from "./latest-version";
5
6
  export type { CheckDefinition };
6
7
  export * from "./model-resolution-types";
7
8
  export { gatherSystemInfo, gatherToolsSummary };
8
9
  export { gatherCodexSummary };
10
+ export { gatherEditionDistTags, resolveLatestVersion };
9
11
  export declare function getAllCheckDefinitions(): CheckDefinition[];
10
12
  export declare function getCodexCheckDefinitions(): CheckDefinition[];
@@ -0,0 +1,11 @@
1
+ import { type NpmDistTags } from "../../config-manager/npm-dist-tags";
2
+ import type { CodexDoctorSummary, DoctorTarget, SystemInfo } from "../framework/types";
3
+ export type FetchDistTags = (packageName: string) => Promise<NpmDistTags | null>;
4
+ export interface LatestVersionInput {
5
+ target: DoctorTarget;
6
+ systemInfo: SystemInfo;
7
+ codex: CodexDoctorSummary | undefined;
8
+ distTags: NpmDistTags | null;
9
+ }
10
+ export declare function gatherEditionDistTags(target: DoctorTarget, fetchDistTags?: FetchDistTags): Promise<NpmDistTags | null>;
11
+ export declare function resolveLatestVersion(input: LatestVersionInput): string | null;
@@ -1,3 +1,4 @@
1
+ import type { DoctorTarget } from "./types";
1
2
  export declare const SYMBOLS: {
2
3
  readonly check: string;
3
4
  readonly cross: string;
@@ -31,3 +32,7 @@ export declare const EXIT_CODES: {
31
32
  export declare const MIN_OPENCODE_VERSION = "1.4.0";
32
33
  export declare const PACKAGE_NAME = "oh-my-openagent";
33
34
  export declare const OPENCODE_BINARIES: readonly ["opencode", "opencode-desktop"];
35
+ export declare const EDITION_LABELS: Record<DoctorTarget, string>;
36
+ export declare const EDITION_PACKAGE_NAMES: Record<DoctorTarget, string>;
37
+ export declare const UPDATE_COMMANDS: Record<DoctorTarget, string>;
38
+ export declare const LATEST_UNAVAILABLE_TEXT = "could not check";
@@ -69,6 +69,8 @@ export interface DoctorResult {
69
69
  exitCode: number;
70
70
  target?: DoctorTarget;
71
71
  codex?: CodexDoctorSummary;
72
+ /** Latest published version on the installed channel; null when the registry lookup failed. */
73
+ latestVersion: string | null;
72
74
  }
73
75
  export interface CodexConfigSummary {
74
76
  readonly exists: boolean;
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.52",
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",
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.52",
293
+ "oh-my-opencode-darwin-x64": "5.0.0-beta.52",
294
+ "oh-my-opencode-darwin-x64-baseline": "5.0.0-beta.52",
295
+ "oh-my-opencode-linux-arm64": "5.0.0-beta.52",
296
+ "oh-my-opencode-linux-arm64-musl": "5.0.0-beta.52",
297
+ "oh-my-opencode-linux-x64": "5.0.0-beta.52",
298
+ "oh-my-opencode-linux-x64-baseline": "5.0.0-beta.52",
299
+ "oh-my-opencode-linux-x64-musl": "5.0.0-beta.52",
300
+ "oh-my-opencode-linux-x64-musl-baseline": "5.0.0-beta.52",
301
+ "oh-my-opencode-windows-arm64": "5.0.0-beta.52",
302
+ "oh-my-opencode-windows-x64": "5.0.0-beta.52",
303
+ "oh-my-opencode-windows-x64-baseline": "5.0.0-beta.52"
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
@@ -73359,10 +73360,8 @@ function validationDiagnostic(path, issues) {
73359
73360
  function unrecognizedKeyIssues(issues) {
73360
73361
  return issues.flatMap((issue) => issue.code === "unrecognized_keys" ? [{ keys: issue.keys, path: issue.path.map((segment) => String(segment)) }] : []);
73361
73362
  }
73362
- function hasUnsafeUnrecognizedKey(parsed, issues) {
73363
- if (issues.some((issue) => issue.keys.some((key) => isUnsafeObjectKey2(key))))
73364
- return true;
73365
- return hasTamperedPrototype(parsed);
73363
+ function hasUnsafeUnrecognizedKey(issues) {
73364
+ return issues.some((issue) => issue.keys.some((key) => isUnsafeObjectKey2(key)));
73366
73365
  }
73367
73366
  function hasTamperedPrototype(value) {
73368
73367
  if (Array.isArray(value))
@@ -73435,11 +73434,17 @@ function readConfigSource(path, scope, fileSystem) {
73435
73434
  source: { exists: true, loaded: false, path, scope }
73436
73435
  };
73437
73436
  }
73437
+ if (hasTamperedPrototype(parsed.data)) {
73438
+ return {
73439
+ diagnostic: { kind: "validation", message: `Invalid omo config at ${path}: "__proto__" member is not allowed`, path },
73440
+ source: { exists: true, loaded: false, path, scope }
73441
+ };
73442
+ }
73438
73443
  const parsedRecord = toRecord2(parsed.data);
73439
73444
  const validation = OmoConfigLayerSchema.safeParse(parsed.data);
73440
73445
  if (!validation.success) {
73441
73446
  const unrecognized = unrecognizedKeyIssues(validation.error.issues);
73442
- if (unrecognized.length > 0 && hasUnsafeUnrecognizedKey(parsed.data, unrecognized)) {
73447
+ if (hasUnsafeUnrecognizedKey(unrecognized)) {
73443
73448
  return {
73444
73449
  diagnostic: validationDiagnostic(path, validation.error.issues),
73445
73450
  source: { exists: true, loaded: false, path, scope }
@@ -84439,7 +84444,7 @@ var package_default2;
84439
84444
  var init_package2 = __esm(() => {
84440
84445
  package_default2 = {
84441
84446
  name: "@oh-my-opencode/omo-codex",
84442
- version: "5.0.0-beta.51",
84447
+ version: "5.0.0-beta.52",
84443
84448
  type: "module",
84444
84449
  private: true,
84445
84450
  description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
@@ -87860,6 +87865,19 @@ var EXIT_CODES = {
87860
87865
  var MIN_OPENCODE_VERSION = "1.4.0";
87861
87866
  var PACKAGE_NAME = PUBLISHED_PACKAGE_NAME;
87862
87867
  var OPENCODE_BINARIES2 = ["opencode", "opencode-desktop"];
87868
+ var EDITION_LABELS = {
87869
+ opencode: "OpenCode",
87870
+ codex: "Codex"
87871
+ };
87872
+ var EDITION_PACKAGE_NAMES = {
87873
+ opencode: PUBLISHED_PACKAGE_NAME,
87874
+ codex: "lazycodex-ai"
87875
+ };
87876
+ var UPDATE_COMMANDS = {
87877
+ opencode: `bunx ${PUBLISHED_PACKAGE_NAME} install`,
87878
+ codex: "npx lazycodex-ai install --no-tui --codex-autonomous"
87879
+ };
87880
+ var LATEST_UNAVAILABLE_TEXT = "could not check";
87863
87881
 
87864
87882
  // packages/omo-opencode/src/cli/minimum-opencode-version.ts
87865
87883
  init_opencode_version();
@@ -100659,7 +100677,9 @@ async function checkConfig() {
100659
100677
  }
100660
100678
 
100661
100679
  // packages/omo-opencode/src/cli/doctor/checks/deprecated-reasoning-keys.ts
100680
+ init_src4();
100662
100681
  init_main();
100682
+ init_config_migration();
100663
100683
  import { existsSync as existsSync52, readFileSync as readFileSync33 } from "fs";
100664
100684
  import { join as join78 } from "path";
100665
100685
  var CANONICAL_REPLACEMENT = new Map([
@@ -100667,8 +100687,9 @@ var CANONICAL_REPLACEMENT = new Map([
100667
100687
  ["reasoningEffort", "reasoning"],
100668
100688
  ["thinking", 'reasoning: "off" or provider_options.thinking'],
100669
100689
  ["textVerbosity", "provider_options.textVerbosity"],
100670
- ["fallback_models", "models"]
100690
+ ["fallback_models", "models: [<primary>, ...fallbacks] (the first entry becomes the primary model)"]
100671
100691
  ]);
100692
+ var MIGRATE_SUFFIX = ", or run: oh-my-openagent config migrate";
100672
100693
  var TUNING_CONTAINERS = new Set(["agents", "categories", "models"]);
100673
100694
  var PASSTHROUGH_CONTAINERS = new Set(["provider_options", "providerOptions"]);
100674
100695
  function isRecord13(value) {
@@ -100677,7 +100698,7 @@ function isRecord13(value) {
100677
100698
  function isHarnessBlock(key) {
100678
100699
  return key.startsWith("[") && key.endsWith("]");
100679
100700
  }
100680
- function collectIssues(configPath, value, prefix) {
100701
+ function collectIssues(configPath, value, prefix, fixSuffix) {
100681
100702
  if (!isRecord13(value))
100682
100703
  return [];
100683
100704
  const issues = [];
@@ -100688,7 +100709,7 @@ function collectIssues(configPath, value, prefix) {
100688
100709
  issues.push({
100689
100710
  title: "Deprecated config key",
100690
100711
  description: `${configPath}: ${path}`,
100691
- fix: `Replace ${key} with ${replacement}, or run: oh-my-openagent config migrate`,
100712
+ fix: `Replace ${key} with ${replacement}${fixSuffix}`,
100692
100713
  severity: "warning",
100693
100714
  affects: [path]
100694
100715
  });
@@ -100700,18 +100721,23 @@ function collectIssues(configPath, value, prefix) {
100700
100721
  continue;
100701
100722
  if (prefix.length === 0 && key === "profiles") {
100702
100723
  for (const profile of Object.values(child)) {
100703
- issues.push(...collectIssues(configPath, profile, ""));
100724
+ issues.push(...collectIssues(configPath, profile, "", fixSuffix));
100704
100725
  }
100705
100726
  continue;
100706
100727
  }
100707
100728
  if (key === "[opencode]")
100708
100729
  continue;
100709
100730
  if (TUNING_CONTAINERS.has(key) || isHarnessBlock(key) || prefix.length > 0) {
100710
- issues.push(...collectIssues(configPath, child, path));
100731
+ issues.push(...collectIssues(configPath, child, path, fixSuffix));
100711
100732
  }
100712
100733
  }
100713
100734
  return issues;
100714
100735
  }
100736
+ function migrateFixSuffix(parsed) {
100737
+ if (isRecord13(parsed) && hasMigrationMarker(parsed, REASONING_UNIFICATION_MIGRATION_ID))
100738
+ return "";
100739
+ return MIGRATE_SUFFIX;
100740
+ }
100715
100741
  function userConfigPaths() {
100716
100742
  const home = process.env.HOME ?? process.env.USERPROFILE;
100717
100743
  if (home === undefined || home.length === 0)
@@ -100726,7 +100752,7 @@ async function checkDeprecatedReasoningKeys() {
100726
100752
  continue;
100727
100753
  scanned.push(configPath);
100728
100754
  const parsed = parse2(readFileSync33(configPath, "utf-8"));
100729
- issues.push(...collectIssues(configPath, parsed, ""));
100755
+ issues.push(...collectIssues(configPath, parsed, "", migrateFixSuffix(parsed)));
100730
100756
  }
100731
100757
  return {
100732
100758
  name: CHECK_NAMES[CHECK_IDS.CONFIG],
@@ -101852,6 +101878,24 @@ async function pathExists2(path) {
101852
101878
  }
101853
101879
  }
101854
101880
 
101881
+ // packages/omo-opencode/src/cli/doctor/checks/latest-version.ts
101882
+ init_auto_update_checker();
101883
+ function gatherEditionDistTags(target, fetchDistTags = fetchNpmDistTags) {
101884
+ return fetchDistTags(EDITION_PACKAGE_NAMES[target]);
101885
+ }
101886
+ function resolveInstalledVersion(input) {
101887
+ if (input.target === "codex" && input.codex) {
101888
+ return input.codex.packageVersion ?? input.codex.installerVersion;
101889
+ }
101890
+ return input.systemInfo.pluginVersion;
101891
+ }
101892
+ function resolveLatestVersion(input) {
101893
+ if (!input.distTags)
101894
+ return null;
101895
+ const channel = extractChannel(resolveInstalledVersion(input));
101896
+ return input.distTags[channel] ?? input.distTags.latest ?? null;
101897
+ }
101898
+
101855
101899
  // packages/omo-opencode/src/cli/doctor/checks/codex-components.ts
101856
101900
  init_src();
101857
101901
  import { readdir as readdir15, readFile as readFile28, stat as stat7 } from "fs/promises";
@@ -102262,7 +102306,6 @@ function getCodexCheckDefinitions() {
102262
102306
  }
102263
102307
 
102264
102308
  // packages/omo-opencode/src/cli/doctor/framework/format-default.ts
102265
- init_shared();
102266
102309
  var import_picocolors19 = __toESM(require_picocolors(), 1);
102267
102310
 
102268
102311
  // packages/omo-opencode/src/cli/doctor/framework/format-shared.ts
@@ -102304,23 +102347,27 @@ function formatIssue(issue, index) {
102304
102347
  }
102305
102348
 
102306
102349
  // packages/omo-opencode/src/cli/doctor/framework/format-default.ts
102350
+ function formatOkSummary(result, headline, installedVersion) {
102351
+ const target = result.target ?? "opencode";
102352
+ const latest = result.latestVersion ?? LATEST_UNAVAILABLE_TEXT;
102353
+ return [
102354
+ ` ${import_picocolors19.default.green(SYMBOLS2.check)} ${import_picocolors19.default.green(`${headline} \xB7 Edition: ${EDITION_LABELS[target]} \xB7 Installed: ${installedVersion} \xB7 Latest: ${latest}`)}`,
102355
+ ` Update: ${UPDATE_COMMANDS[target]}`
102356
+ ];
102357
+ }
102307
102358
  function formatDefault(result) {
102308
102359
  const lines = [];
102309
102360
  lines.push(formatHeader());
102310
102361
  const allIssues = result.results.flatMap((r) => r.issues);
102311
102362
  if (allIssues.length === 0) {
102312
102363
  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
102364
  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})`)}`);
102365
+ lines.push(...formatOkSummary(result, "LazyCodex OK", packageVer));
102318
102366
  return lines.join(`
102319
102367
  `);
102320
102368
  }
102321
- const opencodeVer = result.systemInfo.opencodeVersion ?? "unknown";
102322
102369
  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))}`);
102370
+ lines.push(...formatOkSummary(result, "System OK", pluginVer));
102324
102371
  } else {
102325
102372
  const issueCount = allIssues.filter((i) => i.severity === "error").length;
102326
102373
  const warnCount = allIssues.filter((i) => i.severity === "warning").length;
@@ -102567,7 +102614,8 @@ function buildTimeoutResult(start, options) {
102567
102614
  systemInfo: { opencodeVersion: null, opencodePath: null, pluginVersion: null, loadedVersion: null, bunVersion: null, configPath: null, configValid: false, isLocalDev: false },
102568
102615
  tools: { lspServers: [], astGrepCli: false, commentChecker: false, ghCli: { installed: false, authenticated: false, username: null }, mcpBuiltin: [], mcpUser: [] },
102569
102616
  summary: { total: 1, passed: 0, failed: 1, warnings: 0, skipped: 0, duration: Math.round(performance.now() - start) },
102570
- exitCode: EXIT_CODES.FAILURE
102617
+ exitCode: EXIT_CODES.FAILURE,
102618
+ latestVersion: null
102571
102619
  };
102572
102620
  if (options.json) {
102573
102621
  console.log(formatJsonOutput2(timeoutResult));
@@ -102587,7 +102635,8 @@ async function runDoctor(options) {
102587
102635
  Promise.all(allChecks.map(runCheck)),
102588
102636
  gatherSystemInfo(),
102589
102637
  gatherToolsSummary(),
102590
- target === "codex" ? gatherCodexSummary() : Promise.resolve(undefined)
102638
+ target === "codex" ? gatherCodexSummary() : Promise.resolve(undefined),
102639
+ gatherEditionDistTags(target)
102591
102640
  ]);
102592
102641
  let timer;
102593
102642
  const timeoutPromise = new Promise((_, reject) => {
@@ -102597,8 +102646,9 @@ async function runDoctor(options) {
102597
102646
  let systemInfo;
102598
102647
  let tools;
102599
102648
  let codex;
102649
+ let distTags;
102600
102650
  try {
102601
- [results, systemInfo, tools, codex] = await Promise.race([checksPromise, timeoutPromise]);
102651
+ [results, systemInfo, tools, codex, distTags] = await Promise.race([checksPromise, timeoutPromise]);
102602
102652
  } catch (error) {
102603
102653
  clearTimeout(timer);
102604
102654
  if (error instanceof DoctorTimeoutError) {
@@ -102617,7 +102667,8 @@ async function runDoctor(options) {
102617
102667
  summary,
102618
102668
  exitCode,
102619
102669
  target,
102620
- codex
102670
+ codex,
102671
+ latestVersion: resolveLatestVersion({ target, systemInfo, codex, distTags })
102621
102672
  };
102622
102673
  if (options.json) {
102623
102674
  console.log(formatJsonOutput2(doctorResult));
@@ -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.51",
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-2",
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.51",
294
- "oh-my-opencode-darwin-x64": "5.0.0-beta.51",
295
- "oh-my-opencode-darwin-x64-baseline": "5.0.0-beta.51",
296
- "oh-my-opencode-linux-arm64": "5.0.0-beta.51",
297
- "oh-my-opencode-linux-arm64-musl": "5.0.0-beta.51",
298
- "oh-my-opencode-linux-x64": "5.0.0-beta.51",
299
- "oh-my-opencode-linux-x64-baseline": "5.0.0-beta.51",
300
- "oh-my-opencode-linux-x64-musl": "5.0.0-beta.51",
301
- "oh-my-opencode-linux-x64-musl-baseline": "5.0.0-beta.51",
302
- "oh-my-opencode-windows-arm64": "5.0.0-beta.51",
303
- "oh-my-opencode-windows-x64": "5.0.0-beta.51",
304
- "oh-my-opencode-windows-x64-baseline": "5.0.0-beta.51"
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.51",
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();
@@ -100738,7 +100756,9 @@ async function checkConfig() {
100738
100756
  }
100739
100757
 
100740
100758
  // packages/omo-opencode/src/cli/doctor/checks/deprecated-reasoning-keys.ts
100759
+ init_src4();
100741
100760
  init_main();
100761
+ init_config_migration();
100742
100762
  import { existsSync as existsSync52, readFileSync as readFileSync33 } from "node:fs";
100743
100763
  import { join as join78 } from "node:path";
100744
100764
  var CANONICAL_REPLACEMENT = new Map([
@@ -100746,8 +100766,9 @@ var CANONICAL_REPLACEMENT = new Map([
100746
100766
  ["reasoningEffort", "reasoning"],
100747
100767
  ["thinking", 'reasoning: "off" or provider_options.thinking'],
100748
100768
  ["textVerbosity", "provider_options.textVerbosity"],
100749
- ["fallback_models", "models"]
100769
+ ["fallback_models", "models: [<primary>, ...fallbacks] (the first entry becomes the primary model)"]
100750
100770
  ]);
100771
+ var MIGRATE_SUFFIX = ", or run: oh-my-openagent config migrate";
100751
100772
  var TUNING_CONTAINERS = new Set(["agents", "categories", "models"]);
100752
100773
  var PASSTHROUGH_CONTAINERS = new Set(["provider_options", "providerOptions"]);
100753
100774
  function isRecord13(value) {
@@ -100756,7 +100777,7 @@ function isRecord13(value) {
100756
100777
  function isHarnessBlock(key) {
100757
100778
  return key.startsWith("[") && key.endsWith("]");
100758
100779
  }
100759
- function collectIssues(configPath, value, prefix) {
100780
+ function collectIssues(configPath, value, prefix, fixSuffix) {
100760
100781
  if (!isRecord13(value))
100761
100782
  return [];
100762
100783
  const issues = [];
@@ -100767,7 +100788,7 @@ function collectIssues(configPath, value, prefix) {
100767
100788
  issues.push({
100768
100789
  title: "Deprecated config key",
100769
100790
  description: `${configPath}: ${path}`,
100770
- fix: `Replace ${key} with ${replacement}, or run: oh-my-openagent config migrate`,
100791
+ fix: `Replace ${key} with ${replacement}${fixSuffix}`,
100771
100792
  severity: "warning",
100772
100793
  affects: [path]
100773
100794
  });
@@ -100779,18 +100800,23 @@ function collectIssues(configPath, value, prefix) {
100779
100800
  continue;
100780
100801
  if (prefix.length === 0 && key === "profiles") {
100781
100802
  for (const profile of Object.values(child)) {
100782
- issues.push(...collectIssues(configPath, profile, ""));
100803
+ issues.push(...collectIssues(configPath, profile, "", fixSuffix));
100783
100804
  }
100784
100805
  continue;
100785
100806
  }
100786
100807
  if (key === "[opencode]")
100787
100808
  continue;
100788
100809
  if (TUNING_CONTAINERS.has(key) || isHarnessBlock(key) || prefix.length > 0) {
100789
- issues.push(...collectIssues(configPath, child, path));
100810
+ issues.push(...collectIssues(configPath, child, path, fixSuffix));
100790
100811
  }
100791
100812
  }
100792
100813
  return issues;
100793
100814
  }
100815
+ function migrateFixSuffix(parsed) {
100816
+ if (isRecord13(parsed) && hasMigrationMarker(parsed, REASONING_UNIFICATION_MIGRATION_ID))
100817
+ return "";
100818
+ return MIGRATE_SUFFIX;
100819
+ }
100794
100820
  function userConfigPaths() {
100795
100821
  const home = process.env.HOME ?? process.env.USERPROFILE;
100796
100822
  if (home === undefined || home.length === 0)
@@ -100805,7 +100831,7 @@ async function checkDeprecatedReasoningKeys() {
100805
100831
  continue;
100806
100832
  scanned.push(configPath);
100807
100833
  const parsed = parse2(readFileSync33(configPath, "utf-8"));
100808
- issues.push(...collectIssues(configPath, parsed, ""));
100834
+ issues.push(...collectIssues(configPath, parsed, "", migrateFixSuffix(parsed)));
100809
100835
  }
100810
100836
  return {
100811
100837
  name: CHECK_NAMES[CHECK_IDS.CONFIG],
@@ -101931,6 +101957,24 @@ async function pathExists2(path) {
101931
101957
  }
101932
101958
  }
101933
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
+
101934
101978
  // packages/omo-opencode/src/cli/doctor/checks/codex-components.ts
101935
101979
  init_src();
101936
101980
  import { readdir as readdir15, readFile as readFile28, stat as stat7 } from "node:fs/promises";
@@ -102341,7 +102385,6 @@ function getCodexCheckDefinitions() {
102341
102385
  }
102342
102386
 
102343
102387
  // packages/omo-opencode/src/cli/doctor/framework/format-default.ts
102344
- init_shared();
102345
102388
  var import_picocolors19 = __toESM(require_picocolors(), 1);
102346
102389
 
102347
102390
  // packages/omo-opencode/src/cli/doctor/framework/format-shared.ts
@@ -102383,23 +102426,27 @@ function formatIssue(issue, index) {
102383
102426
  }
102384
102427
 
102385
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
+ }
102386
102437
  function formatDefault(result) {
102387
102438
  const lines = [];
102388
102439
  lines.push(formatHeader());
102389
102440
  const allIssues = result.results.flatMap((r) => r.issues);
102390
102441
  if (allIssues.length === 0) {
102391
102442
  if (result.target === "codex" && result.codex) {
102392
- const codex = result.codex.codexPath ?? result.codex.codexAppId ?? "unknown";
102393
- const pluginVer = result.codex.pluginVersion ?? "unknown";
102394
- const packageName = result.codex.packageName ?? "lazycodex-ai";
102395
102443
  const packageVer = result.codex.packageVersion ?? result.codex.installerVersion;
102396
- 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));
102397
102445
  return lines.join(`
102398
102446
  `);
102399
102447
  }
102400
- const opencodeVer = result.systemInfo.opencodeVersion ?? "unknown";
102401
102448
  const pluginVer = result.systemInfo.pluginVersion ?? "unknown";
102402
- 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));
102403
102450
  } else {
102404
102451
  const issueCount = allIssues.filter((i) => i.severity === "error").length;
102405
102452
  const warnCount = allIssues.filter((i) => i.severity === "warning").length;
@@ -102646,7 +102693,8 @@ function buildTimeoutResult(start, options) {
102646
102693
  systemInfo: { opencodeVersion: null, opencodePath: null, pluginVersion: null, loadedVersion: null, bunVersion: null, configPath: null, configValid: false, isLocalDev: false },
102647
102694
  tools: { lspServers: [], astGrepCli: false, commentChecker: false, ghCli: { installed: false, authenticated: false, username: null }, mcpBuiltin: [], mcpUser: [] },
102648
102695
  summary: { total: 1, passed: 0, failed: 1, warnings: 0, skipped: 0, duration: Math.round(performance.now() - start) },
102649
- exitCode: EXIT_CODES.FAILURE
102696
+ exitCode: EXIT_CODES.FAILURE,
102697
+ latestVersion: null
102650
102698
  };
102651
102699
  if (options.json) {
102652
102700
  console.log(formatJsonOutput2(timeoutResult));
@@ -102666,7 +102714,8 @@ async function runDoctor(options) {
102666
102714
  Promise.all(allChecks.map(runCheck)),
102667
102715
  gatherSystemInfo(),
102668
102716
  gatherToolsSummary(),
102669
- target === "codex" ? gatherCodexSummary() : Promise.resolve(undefined)
102717
+ target === "codex" ? gatherCodexSummary() : Promise.resolve(undefined),
102718
+ gatherEditionDistTags(target)
102670
102719
  ]);
102671
102720
  let timer;
102672
102721
  const timeoutPromise = new Promise((_, reject) => {
@@ -102676,8 +102725,9 @@ async function runDoctor(options) {
102676
102725
  let systemInfo;
102677
102726
  let tools;
102678
102727
  let codex;
102728
+ let distTags;
102679
102729
  try {
102680
- [results, systemInfo, tools, codex] = await Promise.race([checksPromise, timeoutPromise]);
102730
+ [results, systemInfo, tools, codex, distTags] = await Promise.race([checksPromise, timeoutPromise]);
102681
102731
  } catch (error) {
102682
102732
  clearTimeout(timer);
102683
102733
  if (error instanceof DoctorTimeoutError) {
@@ -102696,7 +102746,8 @@ async function runDoctor(options) {
102696
102746
  summary,
102697
102747
  exitCode,
102698
102748
  target,
102699
- codex
102749
+ codex,
102750
+ latestVersion: resolveLatestVersion({ target, systemInfo, codex, distTags })
102700
102751
  };
102701
102752
  if (options.json) {
102702
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.51",
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);