oh-my-opencode 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 (98) 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/dist/features/background-agent/manager.d.ts +7 -0
  8. package/dist/features/background-agent/types.d.ts +4 -0
  9. package/dist/features/claude-tasks/storage.d.ts +7 -2
  10. package/dist/features/hook-message-injector/index.d.ts +1 -0
  11. package/dist/features/hook-message-injector/sdk-message-lookup.d.ts +1 -0
  12. package/dist/hooks/keyword-detector/hook.d.ts +2 -0
  13. package/dist/hooks/keyword-detector/ultrawork/index.d.ts +2 -0
  14. package/dist/hooks/unstable-agent-babysitter/task-message-analyzer.d.ts +1 -0
  15. package/dist/index.js +286 -109
  16. package/dist/plugin/chat-message/types.d.ts +3 -1
  17. package/dist/plugin/stop-continuation.d.ts +3 -0
  18. package/dist/plugin/system-transform.d.ts +5 -1
  19. package/dist/skills/frontend/ATTRIBUTION.md +10 -0
  20. package/dist/skills/frontend/SKILL.md +3 -0
  21. package/dist/skills/frontend/references/design/README.md +10 -2
  22. package/dist/skills/frontend/references/design/_INDEX.md +1 -0
  23. package/dist/skills/frontend/references/design/ambience-skill.md +145 -0
  24. package/dist/skills/frontend/references/design/interaction-skill.md +2 -0
  25. package/dist/tui.js +16 -7
  26. package/package.json +14 -14
  27. package/packages/lsp-daemon/dist/cli.js +1 -2
  28. package/packages/lsp-daemon/dist/ownership.js +2 -2
  29. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  30. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +5 -1
  31. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  32. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  33. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  34. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  35. package/packages/omo-codex/plugin/components/git-bash/dist/cli.js +1 -1
  36. package/packages/omo-codex/plugin/components/git-bash/dist/codex-hook.js +2 -1
  37. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  38. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  39. package/packages/omo-codex/plugin/components/git-bash/src/codex-hook.ts +2 -1
  40. package/packages/omo-codex/plugin/components/git-bash/test/codex-hook.test.ts +6 -7
  41. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  42. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  43. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
  44. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  45. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  46. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  47. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  48. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  49. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  50. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  51. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  52. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  53. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  54. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
  55. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
  56. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +11 -5
  57. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +11 -5
  58. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
  59. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  60. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +10 -5
  61. package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +21 -1
  62. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  63. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  64. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  65. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  66. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  67. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  68. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  69. package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
  70. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  71. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  72. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  73. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  74. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  75. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  76. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  77. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
  78. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  79. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  80. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  81. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  82. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  83. package/packages/omo-codex/plugin/package-lock.json +12 -12
  84. package/packages/omo-codex/plugin/package.json +1 -1
  85. package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +1 -0
  86. package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +10 -0
  87. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +3 -0
  88. package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +10 -2
  89. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +1 -0
  90. package/packages/omo-codex/plugin/skills/frontend/references/design/ambience-skill.md +145 -0
  91. package/packages/omo-codex/plugin/skills/frontend/references/design/interaction-skill.md +2 -0
  92. package/packages/omo-codex/scripts/install-dist/install-local.mjs +9 -5
  93. package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +10 -0
  94. package/packages/shared-skills/skills/frontend/SKILL.md +3 -0
  95. package/packages/shared-skills/skills/frontend/references/design/README.md +10 -2
  96. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +1 -0
  97. package/packages/shared-skills/skills/frontend/references/design/ambience-skill.md +145 -0
  98. 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));
@@ -61,6 +61,7 @@ export declare class BackgroundManager {
61
61
  private queuesByKey;
62
62
  private processingKeys;
63
63
  private completionTimers;
64
+ private readonly syncAttachedSessions;
64
65
  private completedTaskArchive;
65
66
  private completedTaskSummaries;
66
67
  private idleDeferralTimers;
@@ -140,6 +141,12 @@ export declare class BackgroundManager {
140
141
  private updateBackgroundTaskMarker;
141
142
  getAllDescendantTasks(sessionID: string): BackgroundTask[];
142
143
  findBySession(sessionID: string): BackgroundTask | undefined;
144
+ /**
145
+ * Marks a session as being polled by a run_in_background=false continuation so the
146
+ * completion cleanup timer neither drops the task nor deletes the session underneath it.
147
+ * The returned detach restarts the cleanup grace window once the waiter leaves.
148
+ */
149
+ attachSyncContinuation(sessionID: string): () => void;
143
150
  private resolveTaskAttemptBySession;
144
151
  private getConcurrencyKeyFromInput;
145
152
  private getRawConcurrencyKeyFromInput;
@@ -70,6 +70,8 @@ export interface BackgroundTask {
70
70
  isUnstableAgent?: boolean;
71
71
  /** Category used for this task (e.g., 'quick', 'visual-engineering') */
72
72
  category?: string;
73
+ /** Directory the child session is created and prompted in; defaults to the parent session directory */
74
+ cwd?: string;
73
75
  onSessionCreated?: (sessionId: string) => void | Promise<void>;
74
76
  /** Pending retry notification details for the next spawned retry session */
75
77
  retryNotification?: {
@@ -118,6 +120,8 @@ export interface LaunchInput {
118
120
  skillContent?: string;
119
121
  category?: string;
120
122
  sessionPermission?: SessionPermissionRule[];
123
+ /** Directory the child session is created and prompted in; defaults to the parent session directory */
124
+ cwd?: string;
121
125
  onSessionCreated?: (sessionId: string) => void | Promise<void>;
122
126
  /** User tool overrides (ask/allow/deny) from category or agent config. Merged into launchTools before hardcoded restrictions. */
123
127
  userPermission?: Record<string, "ask" | "allow" | "deny">;
@@ -6,9 +6,14 @@ export declare function resolveTaskListId(config?: Partial<OhMyOpenCodeConfig>):
6
6
  export declare function ensureDir(dirPath: string): void;
7
7
  export declare function readJsonSafe<T>(filePath: string, schema: z.ZodType<T>): T | null;
8
8
  export declare function writeJsonAtomic(filePath: string, data: unknown): void;
9
+ export interface AcquireLockOptions {
10
+ waitTimeoutMs?: number;
11
+ retryDelayMs?: number;
12
+ }
13
+ export declare function resolveLockWaitTimeoutMs(): number;
9
14
  export declare function generateTaskId(): string;
10
15
  export declare function listTaskFiles(config?: Partial<OhMyOpenCodeConfig>): string[];
11
- export declare function acquireLock(dirPath: string): {
16
+ export declare function acquireLock(dirPath: string, options?: AcquireLockOptions): Promise<{
12
17
  acquired: boolean;
13
18
  release: () => void;
14
- };
19
+ }>;
@@ -2,3 +2,4 @@ export { injectHookMessage, findNearestMessageWithFields, findFirstMessageWithAg
2
2
  export type { StoredMessage } from "./injector";
3
3
  export type { MessageMeta, OriginalMessageContext, TextPart, ToolPermission } from "./types";
4
4
  export { MESSAGE_STORAGE } from "./constants";
5
+ export { generatePartId } from "./id-generation";
@@ -19,6 +19,7 @@ export interface SDKMessage {
19
19
  };
20
20
  readonly providerID?: string;
21
21
  readonly modelID?: string;
22
+ readonly variant?: string;
22
23
  readonly tools?: Record<string, ToolPermission>;
23
24
  readonly time?: {
24
25
  readonly created?: number;
@@ -20,6 +20,8 @@ export declare function createKeywordDetectorHook(ctx: PluginInput, _collector?:
20
20
  [key: string]: unknown;
21
21
  }>;
22
22
  }) => Promise<void>;
23
+ clearSession: (sessionID: string) => void;
24
+ getSystemTransformGuidance: (sessionID: string, modelID?: string) => string | undefined;
23
25
  event: ({ event }: {
24
26
  event: {
25
27
  type: string;
@@ -15,6 +15,8 @@ export { ULTRAWORK_GPT_MESSAGE, getGptUltraworkMessage } from "./gpt";
15
15
  export { ULTRAWORK_GEMINI_MESSAGE, getGeminiUltraworkMessage } from "./gemini";
16
16
  export { ULTRAWORK_GLM_MESSAGE, getGlmUltraworkMessage } from "./glm";
17
17
  export { ULTRAWORK_DEFAULT_MESSAGE, getDefaultUltraworkMessage, } from "./default";
18
+ import { type UltraworkSource } from "./source-detector";
19
+ export declare function getUltraworkMessageForSource(source: UltraworkSource): string;
18
20
  /**
19
21
  * Gets the appropriate ultrawork message based on agent and model context.
20
22
  */
@@ -10,6 +10,7 @@ type MessageInfo = {
10
10
  };
11
11
  providerID?: string;
12
12
  modelID?: string;
13
+ variant?: string;
13
14
  tools?: Record<string, boolean | "allow" | "deny" | "ask">;
14
15
  };
15
16
  type MessagePart = {