oh-my-opencode 5.0.0-beta.82 → 5.0.0-beta.83

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 (133) hide show
  1. package/README.ja.md +2 -2
  2. package/README.ko.md +2 -2
  3. package/README.md +4 -4
  4. package/README.ru.md +2 -2
  5. package/README.zh-cn.md +2 -2
  6. package/dist/cli/index.js +392 -112
  7. package/dist/cli/install-native/index.d.ts +4 -0
  8. package/dist/cli/install-native/plan.d.ts +11 -0
  9. package/dist/cli/install-native/run-native-install.d.ts +23 -0
  10. package/dist/cli/install-native-dev/index.d.ts +4 -0
  11. package/dist/cli/native-dev-platform-flag.d.ts +5 -0
  12. package/dist/cli/native-edition-hint.d.ts +10 -0
  13. package/dist/cli/types.d.ts +3 -2
  14. package/dist/cli-node/index.js +392 -112
  15. package/dist/config/schema/hooks.d.ts +1 -0
  16. package/dist/config-migration/harness-native-rename.d.ts +3 -0
  17. package/dist/create-hooks.d.ts +1 -0
  18. package/dist/features/native-edition-nudge/index.d.ts +2 -0
  19. package/dist/features/native-edition-nudge/tui.d.ts +33 -0
  20. package/dist/hooks/index.d.ts +1 -0
  21. package/dist/hooks/native-edition-nudge/decide.d.ts +4 -0
  22. package/dist/hooks/native-edition-nudge/hook.d.ts +26 -0
  23. package/dist/hooks/native-edition-nudge/index.d.ts +5 -0
  24. package/dist/hooks/native-edition-nudge/state.d.ts +9 -0
  25. package/dist/hooks/native-edition-nudge/types.d.ts +38 -0
  26. package/dist/index.js +723 -351
  27. package/dist/plugin/hooks/create-core-hooks.d.ts +1 -0
  28. package/dist/plugin/hooks/create-session-hooks.d.ts +2 -1
  29. package/dist/skills/browser/ATTRIBUTION.md +25 -0
  30. package/dist/skills/browser/SKILL.md +89 -0
  31. package/dist/skills/browser/references/commands.md +90 -0
  32. package/dist/skills/browser/references/install.md +71 -0
  33. package/dist/skills/browser/references/owned-engine/README.md +42 -0
  34. package/dist/skills/browser/references/owned-engine/frames-and-humans.md +39 -0
  35. package/dist/skills/browser/references/owned-engine/ladder.md +59 -0
  36. package/dist/skills/browser/references/owned-engine/network.md +42 -0
  37. package/dist/skills/browser/references/recipes/1password.md +59 -0
  38. package/dist/skills/browser/references/remote.md +24 -0
  39. package/dist/skills/browser/scripts/browser-doctor.mjs +41 -0
  40. package/dist/skills/browser/scripts/browser-env.mjs +41 -0
  41. package/dist/skills/browser/scripts/browser-install.mjs +51 -0
  42. package/dist/tui.js +517 -66
  43. package/package.json +14 -14
  44. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  45. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +84 -11
  46. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  47. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  48. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  49. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  50. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  51. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  52. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  53. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  54. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
  55. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  56. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  57. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  58. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  59. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  60. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  61. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  62. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  63. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  64. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  65. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
  66. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
  67. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +24 -10
  68. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +8 -6
  69. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.d.ts +2 -0
  70. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.js +21 -4
  71. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
  72. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  73. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +10 -5
  74. package/packages/omo-codex/plugin/components/ulw-loop/src/surface.ts +24 -6
  75. package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard-native-reviewer.test.ts +207 -0
  76. package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +6 -4
  77. package/packages/omo-codex/plugin/components/ulw-loop/test/surface.test.ts +43 -4
  78. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  79. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  80. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  81. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  82. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  83. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  84. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  85. package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
  86. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  87. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  88. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  89. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  90. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  91. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  92. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  93. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
  94. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  95. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  96. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  97. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  98. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  99. package/packages/omo-codex/plugin/package-lock.json +12 -12
  100. package/packages/omo-codex/plugin/package.json +1 -1
  101. package/packages/omo-codex/plugin/skills/browser/ATTRIBUTION.md +25 -0
  102. package/packages/omo-codex/plugin/skills/browser/SKILL.md +89 -0
  103. package/packages/omo-codex/plugin/skills/browser/agents/openai.yaml +2 -0
  104. package/packages/omo-codex/plugin/skills/browser/references/commands.md +90 -0
  105. package/packages/omo-codex/plugin/skills/browser/references/install.md +71 -0
  106. package/packages/omo-codex/plugin/skills/browser/references/owned-engine/README.md +42 -0
  107. package/packages/omo-codex/plugin/skills/browser/references/owned-engine/frames-and-humans.md +39 -0
  108. package/packages/omo-codex/plugin/skills/browser/references/owned-engine/ladder.md +59 -0
  109. package/packages/omo-codex/plugin/skills/browser/references/owned-engine/network.md +42 -0
  110. package/packages/omo-codex/plugin/skills/browser/references/recipes/1password.md +59 -0
  111. package/packages/omo-codex/plugin/skills/browser/references/remote.md +24 -0
  112. package/packages/omo-codex/plugin/skills/browser/scripts/browser-doctor.mjs +41 -0
  113. package/packages/omo-codex/plugin/skills/browser/scripts/browser-env.mjs +41 -0
  114. package/packages/omo-codex/plugin/skills/browser/scripts/browser-install.mjs +51 -0
  115. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +1 -0
  116. package/packages/omo-codex/scripts/install-dist/install-local.mjs +90 -17
  117. package/packages/shared-skills/skills/browser/ATTRIBUTION.md +25 -0
  118. package/packages/shared-skills/skills/browser/SKILL.md +89 -0
  119. package/packages/shared-skills/skills/browser/references/commands.md +90 -0
  120. package/packages/shared-skills/skills/browser/references/install.md +71 -0
  121. package/packages/shared-skills/skills/browser/references/owned-engine/README.md +42 -0
  122. package/packages/shared-skills/skills/browser/references/owned-engine/frames-and-humans.md +39 -0
  123. package/packages/shared-skills/skills/browser/references/owned-engine/ladder.md +59 -0
  124. package/packages/shared-skills/skills/browser/references/owned-engine/network.md +42 -0
  125. package/packages/shared-skills/skills/browser/references/recipes/1password.md +59 -0
  126. package/packages/shared-skills/skills/browser/references/remote.md +24 -0
  127. package/packages/shared-skills/skills/browser/scripts/browser-doctor.mjs +41 -0
  128. package/packages/shared-skills/skills/browser/scripts/browser-env.mjs +41 -0
  129. package/packages/shared-skills/skills/browser/scripts/browser-install.mjs +51 -0
  130. package/postinstall.mjs +3 -3
  131. package/dist/cli/install-senpi/index.d.ts +0 -1
  132. package/dist/cli/senpi-edition-hint.d.ts +0 -10
  133. package/dist/cli/senpi-platform-flag.d.ts +0 -4
package/dist/tui.js CHANGED
@@ -3268,8 +3268,10 @@ var init_command_executor2 = __esm(() => {
3268
3268
  var init_contains_path2 = () => {};
3269
3269
 
3270
3270
  // packages/omo-opencode/src/shared/plugin-identity.ts
3271
- var PUBLISHED_PACKAGE_NAME = "oh-my-openagent", LOG_FILENAME = "oh-my-opencode.log", CACHE_DIR_NAME = "oh-my-opencode";
3272
- var init_plugin_identity = () => {};
3271
+ var PUBLISHED_PACKAGE_NAME = "oh-my-openagent", ACCEPTED_PACKAGE_NAMES, LOG_FILENAME = "oh-my-opencode.log", CACHE_DIR_NAME = "oh-my-opencode";
3272
+ var init_plugin_identity = __esm(() => {
3273
+ ACCEPTED_PACKAGE_NAMES = ["oh-my-openagent", "oh-my-opencode"];
3274
+ });
3273
3275
 
3274
3276
  // packages/omo-opencode/src/shared/logger.ts
3275
3277
  var logger3, log2, getLogFilePath;
@@ -3343,6 +3345,7 @@ var init_agent_model_requirements = __esm(() => {
3343
3345
  },
3344
3346
  librarian: {
3345
3347
  fallbackChain: [
3348
+ { providers: ["kimi-for-coding"], model: "kimi-for-coding-highspeed", variant: "off" },
3346
3349
  { providers: ["openai", "openai-codex"], model: "gpt-5.6-luna-fast", variant: "low" },
3347
3350
  { providers: ["deepseek"], model: "deepseek-v4-flash", variant: "max" },
3348
3351
  { providers: ["opencode-go", "bailian-coding-plan"], model: "qwen3.7-plus" },
@@ -3355,6 +3358,7 @@ var init_agent_model_requirements = __esm(() => {
3355
3358
  },
3356
3359
  explore: {
3357
3360
  fallbackChain: [
3361
+ { providers: ["kimi-for-coding"], model: "kimi-for-coding-highspeed", variant: "off" },
3358
3362
  { providers: ["openai", "openai-codex"], model: "gpt-5.6-luna-fast", variant: "low" },
3359
3363
  { providers: ["deepseek"], model: "deepseek-v4-flash", variant: "max" },
3360
3364
  { providers: ["opencode-go", "bailian-coding-plan"], model: "qwen3.7-plus" },
@@ -3528,7 +3532,6 @@ var init_category_model_requirements = __esm(() => {
3528
3532
  },
3529
3533
  quick: {
3530
3534
  fallbackChain: [
3531
- { providers: ["kimi-for-coding"], model: "kimi-for-coding-highspeed" },
3532
3535
  { providers: ["openai-codex"], model: "gpt-5.6-luna-fast", variant: "low" },
3533
3536
  { providers: ["deepseek"], model: "deepseek-v4-flash", variant: "off" },
3534
3537
  {
@@ -3548,7 +3551,8 @@ var init_category_model_requirements = __esm(() => {
3548
3551
  },
3549
3552
  "unspecified-low": {
3550
3553
  fallbackChain: [
3551
- { providers: ["xai", "github-copilot", "opencode"], model: "grok-4.6", variant: "xhigh" },
3554
+ { providers: ["xiaomi", "opencode-go"], model: "mimo-v2.6-pro", variant: "max" },
3555
+ { providers: ["xai", "github-copilot", "opencode-go"], model: "grok-4.7", variant: "xhigh" },
3552
3556
  {
3553
3557
  providers: ["openai", "openai-codex", "github-copilot", "opencode"],
3554
3558
  model: "gpt-5.6-terra",
@@ -3570,11 +3574,6 @@ var init_category_model_requirements = __esm(() => {
3570
3574
  },
3571
3575
  "unspecified-high": {
3572
3576
  fallbackChain: [
3573
- {
3574
- providers: ["openai", "openai-codex", "github-copilot", "opencode"],
3575
- model: "gpt-6-astra",
3576
- variant: "high"
3577
- },
3578
3577
  {
3579
3578
  providers: ["anthropic", "anthropic-api", "github-copilot", "opencode"],
3580
3579
  model: "claude-opus-5",
@@ -4188,6 +4187,36 @@ var init_supplemental_entries = __esm(() => {
4188
4187
  output: 32768
4189
4188
  }
4190
4189
  },
4190
+ "grok-4.7": {
4191
+ id: "grok-4.7",
4192
+ family: "grok",
4193
+ reasoning: false,
4194
+ temperature: true,
4195
+ toolCall: true,
4196
+ modalities: {
4197
+ input: ["text", "image"],
4198
+ output: ["text"]
4199
+ },
4200
+ limit: {
4201
+ context: 500000,
4202
+ output: 32768
4203
+ }
4204
+ },
4205
+ "xai/grok-4.7": {
4206
+ id: "xai/grok-4.7",
4207
+ family: "grok",
4208
+ reasoning: false,
4209
+ temperature: true,
4210
+ toolCall: true,
4211
+ modalities: {
4212
+ input: ["text", "image"],
4213
+ output: ["text"]
4214
+ },
4215
+ limit: {
4216
+ context: 500000,
4217
+ output: 32768
4218
+ }
4219
+ },
4191
4220
  "xai/grok-build-0.1": {
4192
4221
  id: "xai/grok-build-0.1",
4193
4222
  family: "grok",
@@ -4217,6 +4246,36 @@ var init_supplemental_entries = __esm(() => {
4217
4246
  context: 256000,
4218
4247
  output: 32768
4219
4248
  }
4249
+ },
4250
+ "mimo-v2.6-pro": {
4251
+ id: "mimo-v2.6-pro",
4252
+ family: "mimo",
4253
+ reasoning: true,
4254
+ temperature: true,
4255
+ toolCall: true,
4256
+ modalities: {
4257
+ input: ["text", "image"],
4258
+ output: ["text"]
4259
+ },
4260
+ limit: {
4261
+ context: 1048576,
4262
+ output: 131072
4263
+ }
4264
+ },
4265
+ "xiaomi/mimo-v2.6-pro": {
4266
+ id: "xiaomi/mimo-v2.6-pro",
4267
+ family: "mimo",
4268
+ reasoning: true,
4269
+ temperature: true,
4270
+ toolCall: true,
4271
+ modalities: {
4272
+ input: ["text", "image"],
4273
+ output: ["text"]
4274
+ },
4275
+ limit: {
4276
+ context: 1048576,
4277
+ output: 131072
4278
+ }
4220
4279
  }
4221
4280
  };
4222
4281
  });
@@ -4740,6 +4799,9 @@ function getCacheDir() {
4740
4799
  function getOmoOpenCodeCacheDir() {
4741
4800
  return path3.join(getCacheDir(), CACHE_DIR_NAME);
4742
4801
  }
4802
+ function getOpenCodeCacheDir() {
4803
+ return path3.join(getCacheDir(), "opencode");
4804
+ }
4743
4805
  var init_data_path = __esm(() => {
4744
4806
  init_src();
4745
4807
  init_plugin_identity();
@@ -5102,21 +5164,21 @@ var init_openai_categories = __esm(() => {
5102
5164
  },
5103
5165
  {
5104
5166
  name: "quick",
5105
- config: { model: "kimi-for-coding/kimi-for-coding-highspeed" },
5167
+ config: { model: "openai/gpt-5.6-luna-fast", variant: "low" },
5106
5168
  description: "Trivial tasks - single file changes, typo fixes, simple modifications",
5107
5169
  callerGuidance: QUICK_CATEGORY_CALLER_GUIDANCE,
5108
5170
  promptAppend: QUICK_CATEGORY_PROMPT_APPEND
5109
5171
  },
5110
5172
  {
5111
5173
  name: "unspecified-low",
5112
- config: { model: "xai/grok-4.6", variant: "xhigh" },
5174
+ config: { model: "xiaomi/mimo-v2.6-pro", variant: "max" },
5113
5175
  description: "Tasks that don't fit other categories, low effort required",
5114
5176
  callerGuidance: UNSPECIFIED_LOW_CATEGORY_CALLER_GUIDANCE,
5115
5177
  promptAppend: UNSPECIFIED_LOW_CATEGORY_PROMPT_APPEND
5116
5178
  },
5117
5179
  {
5118
5180
  name: "unspecified-high",
5119
- config: { model: "openai/gpt-6-astra", variant: "high" },
5181
+ config: { model: "anthropic/claude-opus-5", variant: "xhigh" },
5120
5182
  description: "Tasks that don't fit other categories, high effort required",
5121
5183
  callerGuidance: UNSPECIFIED_HIGH_CATEGORY_CALLER_GUIDANCE,
5122
5184
  promptAppend: UNSPECIFIED_HIGH_CATEGORY_PROMPT_APPEND,
@@ -5164,6 +5226,102 @@ var init_migration2 = __esm(() => {
5164
5226
  });
5165
5227
 
5166
5228
  // packages/omo-opencode/src/shared/opencode-config-dir.ts
5229
+ import { existsSync as existsSync2, realpathSync } from "fs";
5230
+ import { homedir as homedir2 } from "os";
5231
+ import { join as join3, posix, resolve, win32 } from "path";
5232
+ function isDevBuild(version) {
5233
+ if (!version)
5234
+ return false;
5235
+ return version.includes("-dev") || version.includes(".dev");
5236
+ }
5237
+ function getTauriConfigDir(identifier) {
5238
+ const platform = process.platform;
5239
+ switch (platform) {
5240
+ case "darwin":
5241
+ return join3(homedir2(), "Library", "Application Support", identifier);
5242
+ case "win32": {
5243
+ const appData = process.env.APPDATA || join3(homedir2(), "AppData", "Roaming");
5244
+ return win32.join(appData, identifier);
5245
+ }
5246
+ case "linux":
5247
+ default: {
5248
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join3(homedir2(), ".config");
5249
+ return join3(xdgConfig, identifier);
5250
+ }
5251
+ }
5252
+ }
5253
+ function resolveConfigPath(pathValue) {
5254
+ if (isWslEnvironment() && pathValue.startsWith("/")) {
5255
+ return posix.normalize(pathValue);
5256
+ }
5257
+ const resolvedPath = resolve(pathValue);
5258
+ if (!existsSync2(resolvedPath))
5259
+ return resolvedPath;
5260
+ try {
5261
+ return realpathSync(resolvedPath);
5262
+ } catch (error) {
5263
+ if (error instanceof Error) {
5264
+ return resolvedPath;
5265
+ }
5266
+ return resolvedPath;
5267
+ }
5268
+ }
5269
+ function isWslEnvironment() {
5270
+ return process.platform === "linux" && (Boolean(process.env.WSL_DISTRO_NAME?.trim()) || Boolean(process.env.WSL_INTEROP?.trim()));
5271
+ }
5272
+ function isWindowsUserConfigRoot(pathValue) {
5273
+ const normalizedPath = pathValue.replaceAll("\\", "/").toLowerCase();
5274
+ return /^[a-z]:\/users\//.test(normalizedPath) || /^\/mnt\/[a-z]\/users\//.test(normalizedPath);
5275
+ }
5276
+ function getWindowsUserFromConfigRoot(pathValue) {
5277
+ const normalizedPath = pathValue.replaceAll("\\", "/");
5278
+ const match = /^(?:[a-z]:|\/mnt\/[a-z])\/Users\/([^/]+)/i.exec(normalizedPath);
5279
+ return match?.[1] ?? null;
5280
+ }
5281
+ function getWslLinuxHomeDir(windowsConfigRoot) {
5282
+ const envHome = process.env.HOME?.trim();
5283
+ if (envHome && envHome.startsWith("/") && !isWindowsUserConfigRoot(envHome)) {
5284
+ return envHome;
5285
+ }
5286
+ const user = process.env.USER?.trim() || process.env.LOGNAME?.trim() || process.env.SUDO_USER?.trim() || (windowsConfigRoot ? getWindowsUserFromConfigRoot(windowsConfigRoot) : undefined);
5287
+ return user ? posix.join("/home", user) : null;
5288
+ }
5289
+ function getCliDefaultConfigDir() {
5290
+ const envXdgConfig = process.env.XDG_CONFIG_HOME?.trim();
5291
+ const shouldIgnoreWindowsXdg = envXdgConfig !== undefined && envXdgConfig.length > 0 && isWslEnvironment() && isWindowsUserConfigRoot(envXdgConfig);
5292
+ const xdgConfig = shouldIgnoreWindowsXdg ? posix.join(getWslLinuxHomeDir(envXdgConfig) ?? "/home", ".config") : envXdgConfig || join3(homedir2(), ".config");
5293
+ const configDir = isWslEnvironment() ? posix.join(xdgConfig, "opencode") : join3(xdgConfig, "opencode");
5294
+ return resolveConfigPath(configDir);
5295
+ }
5296
+ function getCliCustomConfigDir() {
5297
+ const envConfigDir = process.env.OPENCODE_CONFIG_DIR?.trim();
5298
+ if (!envConfigDir) {
5299
+ return null;
5300
+ }
5301
+ return resolveConfigPath(envConfigDir);
5302
+ }
5303
+ function getCliConfigDir() {
5304
+ return getCliCustomConfigDir() ?? getCliDefaultConfigDir();
5305
+ }
5306
+ function getOpenCodeConfigDir(options) {
5307
+ const { binary, version, checkExisting = true } = options;
5308
+ if (binary === "opencode") {
5309
+ return getCliConfigDir();
5310
+ }
5311
+ const identifier = isDevBuild(version) ? TAURI_APP_IDENTIFIER_DEV : TAURI_APP_IDENTIFIER;
5312
+ const tauriDirBase = getTauriConfigDir(identifier);
5313
+ const tauriDir = process.platform === "win32" ? win32.isAbsolute(tauriDirBase) ? win32.normalize(tauriDirBase) : win32.resolve(tauriDirBase) : resolveConfigPath(tauriDirBase);
5314
+ if (checkExisting) {
5315
+ const legacyDir = getCliConfigDir();
5316
+ const legacyConfig = join3(legacyDir, "opencode.json");
5317
+ const legacyConfigC = join3(legacyDir, "opencode.jsonc");
5318
+ if (existsSync2(legacyConfig) || existsSync2(legacyConfigC)) {
5319
+ return legacyDir;
5320
+ }
5321
+ }
5322
+ return tauriDir;
5323
+ }
5324
+ var TAURI_APP_IDENTIFIER = "ai.opencode.desktop", TAURI_APP_IDENTIFIER_DEV = "ai.opencode.desktop.dev";
5167
5325
  var init_opencode_config_dir = () => {};
5168
5326
 
5169
5327
  // packages/omo-opencode/src/shared/resolve-agent-definition-paths.ts
@@ -5265,8 +5423,8 @@ var init_write_file_atomically = __esm(() => {
5265
5423
  });
5266
5424
 
5267
5425
  // packages/omo-opencode/src/shared/json-file-cache-store.ts
5268
- import { existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync, writeFileSync } from "fs";
5269
- import { join as join3 } from "path";
5426
+ import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync, writeFileSync } from "fs";
5427
+ import { join as join4 } from "path";
5270
5428
  function toLogLabel(cacheLabel) {
5271
5429
  return cacheLabel.toLowerCase();
5272
5430
  }
@@ -5274,11 +5432,11 @@ function createJsonFileCacheStore(options) {
5274
5432
  let memoryValue;
5275
5433
  let writtenInCurrentProcess = false;
5276
5434
  function getCacheFilePath() {
5277
- return join3(options.getCacheDir(), options.filename);
5435
+ return join4(options.getCacheDir(), options.filename);
5278
5436
  }
5279
5437
  function ensureCacheDir() {
5280
5438
  const cacheDir = options.getCacheDir();
5281
- if (!existsSync2(cacheDir)) {
5439
+ if (!existsSync3(cacheDir)) {
5282
5440
  mkdirSync3(cacheDir, { recursive: true });
5283
5441
  }
5284
5442
  }
@@ -5287,7 +5445,7 @@ function createJsonFileCacheStore(options) {
5287
5445
  return memoryValue;
5288
5446
  }
5289
5447
  const cacheFile = getCacheFilePath();
5290
- if (!existsSync2(cacheFile)) {
5448
+ if (!existsSync3(cacheFile)) {
5291
5449
  memoryValue = null;
5292
5450
  log2(`[${options.logPrefix}] ${options.cacheLabel} file not found`, { cacheFile });
5293
5451
  return null;
@@ -5313,7 +5471,7 @@ function createJsonFileCacheStore(options) {
5313
5471
  if (writtenInCurrentProcess) {
5314
5472
  return true;
5315
5473
  }
5316
- return existsSync2(getCacheFilePath());
5474
+ return existsSync3(getCacheFilePath());
5317
5475
  }
5318
5476
  function write(value) {
5319
5477
  ensureCacheDir();
@@ -59882,14 +60040,14 @@ var init_fallback_model_availability = __esm(() => {
59882
60040
  });
59883
60041
 
59884
60042
  // packages/omo-opencode/src/shared/opencode-storage-paths.ts
59885
- import { join as join4 } from "path";
60043
+ import { join as join5 } from "path";
59886
60044
  var OPENCODE_STORAGE, MESSAGE_STORAGE, PART_STORAGE, SESSION_STORAGE;
59887
60045
  var init_opencode_storage_paths = __esm(() => {
59888
60046
  init_data_path();
59889
60047
  OPENCODE_STORAGE = getOpenCodeStorageDir();
59890
- MESSAGE_STORAGE = join4(OPENCODE_STORAGE, "message");
59891
- PART_STORAGE = join4(OPENCODE_STORAGE, "part");
59892
- SESSION_STORAGE = join4(OPENCODE_STORAGE, "session");
60048
+ MESSAGE_STORAGE = join5(OPENCODE_STORAGE, "message");
60049
+ PART_STORAGE = join5(OPENCODE_STORAGE, "part");
60050
+ SESSION_STORAGE = join5(OPENCODE_STORAGE, "session");
59893
60051
  });
59894
60052
 
59895
60053
  // packages/omo-opencode/src/shared/compaction-marker.ts
@@ -69224,12 +69382,14 @@ var init_git_master = __esm(() => {
69224
69382
  });
69225
69383
 
69226
69384
  // packages/omo-config-core/src/schema/harness.ts
69227
- var HARNESS_IDS, OMO_CONFIG_HARNESS_IDS, OmoHarnessIdSchema;
69385
+ var HARNESS_IDS, OMO_CONFIG_HARNESS_IDS, OmoHarnessIdSchema, OMO_CONFIG_LEGACY_HARNESS_ALIASES, OMO_CONFIG_LEGACY_HARNESS_IDS;
69228
69386
  var init_harness = __esm(() => {
69229
69387
  init_zod();
69230
69388
  HARNESS_IDS = ["codex", "opencode", "omo"];
69231
- OMO_CONFIG_HARNESS_IDS = ["opencode", "senpi", "codex"];
69389
+ OMO_CONFIG_HARNESS_IDS = ["opencode", "native", "codex"];
69232
69390
  OmoHarnessIdSchema = _enum(OMO_CONFIG_HARNESS_IDS);
69391
+ OMO_CONFIG_LEGACY_HARNESS_ALIASES = { senpi: "native" };
69392
+ OMO_CONFIG_LEGACY_HARNESS_IDS = Object.keys(OMO_CONFIG_LEGACY_HARNESS_ALIASES);
69233
69393
  });
69234
69394
 
69235
69395
  // packages/omo-config-core/src/schema/memory.ts
@@ -69732,6 +69892,7 @@ var init_config = __esm(() => {
69732
69892
  telemetry: OmoTelemetrySettingsLayerSchema.optional(),
69733
69893
  disabled_skills: OmoDisabledSkillsSchema.optional(),
69734
69894
  "[opencode]": OmoOpenCodeHarnessConfigSchema.optional(),
69895
+ "[native]": OmoTypedHarnessConfigSchema.optional(),
69735
69896
  "[senpi]": OmoTypedHarnessConfigSchema.optional(),
69736
69897
  "[codex]": OmoTypedHarnessConfigSchema.optional()
69737
69898
  }).strict();
@@ -69750,6 +69911,7 @@ var init_config = __esm(() => {
69750
69911
  telemetry: OmoTelemetrySettingsSchema.optional(),
69751
69912
  disabled_skills: OmoDisabledSkillsSchema.optional(),
69752
69913
  "[opencode]": OmoOpenCodeHarnessConfigSchema.optional(),
69914
+ "[native]": OmoTypedHarnessConfigSchema.optional(),
69753
69915
  "[senpi]": OmoTypedHarnessConfigSchema.optional(),
69754
69916
  "[codex]": OmoTypedHarnessConfigSchema.optional(),
69755
69917
  profiles: record(string2(), OmoConfigProfileSchema).default({}),
@@ -69771,6 +69933,7 @@ var init_config = __esm(() => {
69771
69933
  telemetry: OmoTelemetrySettingsLayerSchema.optional(),
69772
69934
  disabled_skills: OmoDisabledSkillsSchema.optional(),
69773
69935
  "[opencode]": OmoOpenCodeHarnessConfigSchema.optional(),
69936
+ "[native]": OmoTypedHarnessConfigSchema.optional(),
69774
69937
  "[senpi]": OmoTypedHarnessConfigSchema.optional(),
69775
69938
  "[codex]": OmoTypedHarnessConfigSchema.optional(),
69776
69939
  profiles: record(string2(), OmoConfigProfileSchema).optional(),
@@ -69838,6 +70001,57 @@ var init_legacy_category_names = __esm(() => {
69838
70001
  LEGACY_CATEGORY_NAME_ALIASES = { deep: "deep-low" };
69839
70002
  });
69840
70003
 
70004
+ // packages/omo-config-core/src/schema/legacy-harness-names.ts
70005
+ function canonicalHarnessName(name) {
70006
+ return Object.hasOwn(OMO_CONFIG_LEGACY_HARNESS_ALIASES, name) ? OMO_CONFIG_LEGACY_HARNESS_ALIASES[name] : name;
70007
+ }
70008
+ function harnessBlockKey(harness) {
70009
+ return `[${harness}]`;
70010
+ }
70011
+ function legacyHarnessOfBlockKey(key) {
70012
+ if (!key.startsWith("[") || !key.endsWith("]"))
70013
+ return;
70014
+ const harness = key.slice(1, -1);
70015
+ return Object.hasOwn(OMO_CONFIG_LEGACY_HARNESS_ALIASES, harness) ? harness : undefined;
70016
+ }
70017
+ function isRecord10(value) {
70018
+ return typeof value === "object" && value !== null && !Array.isArray(value);
70019
+ }
70020
+ function canonicalizeBlocksIn(container, path, renames) {
70021
+ const result = {};
70022
+ for (const [key, value] of Object.entries(container)) {
70023
+ const legacyHarness = legacyHarnessOfBlockKey(key);
70024
+ if (legacyHarness === undefined) {
70025
+ result[key] = value;
70026
+ continue;
70027
+ }
70028
+ const canonical = harnessBlockKey(canonicalHarnessName(legacyHarness));
70029
+ const dropped = Object.hasOwn(container, canonical);
70030
+ renames.push({ canonical, dropped, legacy: key, path: [...path, key].join(".") });
70031
+ if (!dropped)
70032
+ result[canonical] = value;
70033
+ }
70034
+ return result;
70035
+ }
70036
+ function canonicalizeLegacyHarnessBlocks(document) {
70037
+ if (!isRecord10(document))
70038
+ return { document: {}, renames: [] };
70039
+ const renames = [];
70040
+ const canonicalized = canonicalizeBlocksIn(document, [], renames);
70041
+ const profiles = canonicalized["profiles"];
70042
+ if (isRecord10(profiles)) {
70043
+ const canonicalProfiles = {};
70044
+ for (const [name, profile] of Object.entries(profiles)) {
70045
+ canonicalProfiles[name] = isRecord10(profile) ? canonicalizeBlocksIn(profile, ["profiles", name], renames) : profile;
70046
+ }
70047
+ canonicalized["profiles"] = canonicalProfiles;
70048
+ }
70049
+ return { document: canonicalized, renames };
70050
+ }
70051
+ var init_legacy_harness_names = __esm(() => {
70052
+ init_harness();
70053
+ });
70054
+
69841
70055
  // packages/omo-config-core/src/schema/index.ts
69842
70056
  var init_schema = __esm(() => {
69843
70057
  init_agent();
@@ -69848,6 +70062,7 @@ var init_schema = __esm(() => {
69848
70062
  init_git_master();
69849
70063
  init_harness();
69850
70064
  init_legacy_category_names();
70065
+ init_legacy_harness_names();
69851
70066
  init_memory();
69852
70067
  init_model_catalog();
69853
70068
  init_model_profile();
@@ -69857,6 +70072,9 @@ var init_schema = __esm(() => {
69857
70072
  init_telemetry();
69858
70073
  });
69859
70074
 
70075
+ // packages/omo-config-core/src/loader/disabled-skills.ts
70076
+ var init_disabled_skills = () => {};
70077
+
69860
70078
  // packages/omo-config-core/src/loader/merge.ts
69861
70079
  function isUnsafeObjectKey2(key) {
69862
70080
  return DANGEROUS_KEYS2.has(key);
@@ -69900,33 +70118,33 @@ function toPosixPath(path) {
69900
70118
  var init_posix_path = () => {};
69901
70119
 
69902
70120
  // packages/omo-config-core/src/loader/types.ts
69903
- import { existsSync as existsSync3, lstatSync, readFileSync as readFileSync3, realpathSync as realpathSync2 } from "fs";
70121
+ import { existsSync as existsSync4, lstatSync, readFileSync as readFileSync4, realpathSync as realpathSync3 } from "fs";
69904
70122
  var DEFAULT_READ_FILE_SYSTEM;
69905
70123
  var init_types3 = __esm(() => {
69906
70124
  DEFAULT_READ_FILE_SYSTEM = {
69907
- existsSync: existsSync3,
70125
+ existsSync: existsSync4,
69908
70126
  lstatSync,
69909
- readFileSync: readFileSync3,
69910
- realpathSync: realpathSync2
70127
+ readFileSync: readFileSync4,
70128
+ realpathSync: realpathSync3
69911
70129
  };
69912
70130
  });
69913
70131
 
69914
70132
  // packages/omo-config-core/src/loader/paths.ts
69915
70133
  import { userInfo } from "os";
69916
- import { dirname, join as join6, posix, resolve as resolve2 } from "path";
70134
+ import { dirname, join as join10, posix as posix2, resolve as resolve3 } from "path";
69917
70135
  function resolveHomeDir(env = process.env) {
69918
70136
  const homeDir = env.HOME ?? env.USERPROFILE ?? process.cwd();
69919
- return homeDir.startsWith("/") ? posix.resolve(homeDir) : toPosixPath(resolve2(homeDir));
70137
+ return homeDir.startsWith("/") ? posix2.resolve(homeDir) : toPosixPath(resolve3(homeDir));
69920
70138
  }
69921
70139
  function resolveUserOmoConfigDirectory(env = process.env) {
69922
- return join6(resolveHomeDir(env), ".omo");
70140
+ return join10(resolveHomeDir(env), ".omo");
69923
70141
  }
69924
70142
  function detectUserOmoJsonPath(env, fileSystem) {
69925
70143
  const configDir = resolveUserOmoConfigDirectory(env);
69926
- const jsoncPath = join6(configDir, "omo.jsonc");
70144
+ const jsoncPath = join10(configDir, "omo.jsonc");
69927
70145
  if (fileSystem.existsSync(jsoncPath))
69928
70146
  return jsoncPath;
69929
- const jsonPath = join6(configDir, "omo.json");
70147
+ const jsonPath = join10(configDir, "omo.json");
69930
70148
  return fileSystem.existsSync(jsonPath) ? jsonPath : jsoncPath;
69931
70149
  }
69932
70150
  function isSymlinkedProjectPath(path, fileSystem) {
@@ -69944,13 +70162,13 @@ function isLoadableProjectConfigFile(path, fileSystem) {
69944
70162
  return fileSystem.existsSync(path) && !isSymlinkedProjectPath(path, fileSystem);
69945
70163
  }
69946
70164
  function detectOmoJsonPath(dir, fileSystem) {
69947
- const omoDir = join6(dir, ".omo");
70165
+ const omoDir = join10(dir, ".omo");
69948
70166
  if (isSymlinkedProjectPath(omoDir, fileSystem))
69949
70167
  return null;
69950
- const jsoncPath = join6(omoDir, "omo.jsonc");
70168
+ const jsoncPath = join10(omoDir, "omo.jsonc");
69951
70169
  if (isLoadableProjectConfigFile(jsoncPath, fileSystem))
69952
70170
  return jsoncPath;
69953
- const jsonPath = join6(omoDir, "omo.json");
70171
+ const jsonPath = join10(omoDir, "omo.json");
69954
70172
  return isLoadableProjectConfigFile(jsonPath, fileSystem) ? jsonPath : null;
69955
70173
  }
69956
70174
  function realpathOrSelf(path, fileSystem) {
@@ -69963,8 +70181,8 @@ function realpathOrSelf(path, fileSystem) {
69963
70181
  }
69964
70182
  }
69965
70183
  function findProjectConfigPathsFarthestFirst(cwd, homeDir, fileSystem, accountHomeDir = homeDir) {
69966
- const startDir = resolve2(cwd);
69967
- const boundaryDirs = [...new Set([resolve2(homeDir), resolve2(accountHomeDir)])];
70184
+ const startDir = resolve3(cwd);
70185
+ const boundaryDirs = [...new Set([resolve3(homeDir), resolve3(accountHomeDir)])];
69968
70186
  const realBoundaryDirs = new Set(boundaryDirs.map((path) => realpathOrSelf(path, fileSystem)));
69969
70187
  const nearestFirst = [];
69970
70188
  let currentDir = startDir;
@@ -70028,7 +70246,13 @@ function withoutControlKeys(config) {
70028
70246
  function harnessLayer(config, harness) {
70029
70247
  if (harness === undefined)
70030
70248
  return {};
70031
- return toRecord(config[`[${harness}]`]) ?? {};
70249
+ const canonical = canonicalHarnessName(harness);
70250
+ const legacyKeys = Object.entries(OMO_CONFIG_LEGACY_HARNESS_ALIASES).filter(([, target]) => target === canonical).map(([legacy]) => harnessBlockKey(legacy));
70251
+ let layer = {};
70252
+ for (const key of [...legacyKeys, harnessBlockKey(canonical)]) {
70253
+ layer = mergeOmoConfigRecords(layer, toRecord(config[key]) ?? {});
70254
+ }
70255
+ return layer;
70032
70256
  }
70033
70257
  function resolveOmoConfigView(options) {
70034
70258
  const profiles = toRecord(options.config["profiles"]);
@@ -70058,7 +70282,7 @@ var HARNESS_KEYS;
70058
70282
  var init_resolution = __esm(() => {
70059
70283
  init_schema();
70060
70284
  init_merge();
70061
- HARNESS_KEYS = [...new Set([...HARNESS_IDS, ...OMO_CONFIG_HARNESS_IDS])].map((harness) => `[${harness}]`);
70285
+ HARNESS_KEYS = [...new Set([...HARNESS_IDS, ...OMO_CONFIG_HARNESS_IDS, ...OMO_CONFIG_LEGACY_HARNESS_IDS])].map((harness) => harnessBlockKey(harness));
70062
70286
  });
70063
70287
 
70064
70288
  // packages/omo-config-core/src/loader/loader.ts
@@ -70079,6 +70303,7 @@ function parseJsoncSafe2(content) {
70079
70303
  function stripResolutionControlKeys(config) {
70080
70304
  const {
70081
70305
  "[codex]": _codex,
70306
+ "[native]": _native,
70082
70307
  "[opencode]": _opencode,
70083
70308
  "[senpi]": _senpi,
70084
70309
  profiles: _profiles,
@@ -70104,21 +70329,21 @@ function hasUnsafeUnrecognizedKey(issues) {
70104
70329
  function hasTamperedPrototype(value) {
70105
70330
  if (Array.isArray(value))
70106
70331
  return value.some((entry) => hasTamperedPrototype(entry));
70107
- if (!isRecord10(value))
70332
+ if (!isRecord11(value))
70108
70333
  return false;
70109
70334
  const prototype = Object.getPrototypeOf(value);
70110
70335
  if (prototype !== Object.prototype && prototype !== null)
70111
70336
  return true;
70112
70337
  return Object.values(value).some((entry) => hasTamperedPrototype(entry));
70113
70338
  }
70114
- function isRecord10(value) {
70339
+ function isRecord11(value) {
70115
70340
  return typeof value === "object" && value !== null && !Array.isArray(value);
70116
70341
  }
70117
70342
  function containerAt(record, path) {
70118
70343
  let container = record;
70119
70344
  for (const segment of path) {
70120
70345
  const next = container[segment];
70121
- if (!isRecord10(next))
70346
+ if (!isRecord11(next))
70122
70347
  return null;
70123
70348
  container = next;
70124
70349
  }
@@ -70229,6 +70454,15 @@ function legacyCategoryDiagnostic(path, renames) {
70229
70454
  issuePaths: renames.map((rename) => rename.path)
70230
70455
  };
70231
70456
  }
70457
+ function legacyHarnessDiagnostic(path, renames) {
70458
+ const detail = renames.map((rename) => rename.dropped ? `${rename.path} ignored because ${rename.canonical} is also configured` : `${rename.path} renamed to ${rename.canonical}`).join(", ");
70459
+ return {
70460
+ kind: "deprecated-keys",
70461
+ message: `Deprecated harness block in ${path}: ${detail}. Rename it; the alias is removed in a future release.`,
70462
+ path,
70463
+ issuePaths: renames.map((rename) => rename.path)
70464
+ };
70465
+ }
70232
70466
  function loadOmoConfig(options = {}) {
70233
70467
  const fileSystem = options.fileSystem ?? DEFAULT_READ_FILE_SYSTEM;
70234
70468
  const cwd = options.cwd ?? process.cwd();
@@ -70251,8 +70485,12 @@ function loadOmoConfig(options = {}) {
70251
70485
  if (canonicalized.renames.length > 0) {
70252
70486
  diagnostics.push(legacyCategoryDiagnostic(candidate.path, canonicalized.renames));
70253
70487
  }
70254
- layers.push({ config: canonicalized.document, source: loaded.source });
70255
- merged = mergeOmoConfigRecords(merged, canonicalized.document);
70488
+ const harnessCanonicalized = canonicalizeLegacyHarnessBlocks(canonicalized.document);
70489
+ if (harnessCanonicalized.renames.length > 0) {
70490
+ diagnostics.push(legacyHarnessDiagnostic(candidate.path, harnessCanonicalized.renames));
70491
+ }
70492
+ layers.push({ config: harnessCanonicalized.document, source: loaded.source });
70493
+ merged = mergeOmoConfigRecords(merged, harnessCanonicalized.document);
70256
70494
  }
70257
70495
  }
70258
70496
  const requestedProfile = resolveOmoProfileName({
@@ -70300,6 +70538,7 @@ var init_loader2 = __esm(() => {
70300
70538
 
70301
70539
  // packages/omo-config-core/src/loader/index.ts
70302
70540
  var init_loader3 = __esm(() => {
70541
+ init_disabled_skills();
70303
70542
  init_loader2();
70304
70543
  init_merge();
70305
70544
  init_paths();
@@ -70475,30 +70714,30 @@ var init_models = __esm(() => {
70475
70714
  // packages/omo-config-core/src/writer/types.ts
70476
70715
  import {
70477
70716
  copyFileSync,
70478
- existsSync as existsSync4,
70717
+ existsSync as existsSync5,
70479
70718
  lstatSync as lstatSync2,
70480
- mkdirSync as mkdirSync5,
70481
- readFileSync as readFileSync4,
70719
+ mkdirSync as mkdirSync6,
70720
+ readFileSync as readFileSync5,
70482
70721
  readdirSync,
70483
70722
  renameSync as renameSync2,
70484
- unlinkSync as unlinkSync2,
70485
- writeFileSync as writeFileSync2
70723
+ unlinkSync as unlinkSync3,
70724
+ writeFileSync as writeFileSync3
70486
70725
  } from "fs";
70487
70726
  var DEFAULT_WRITE_FILE_SYSTEM;
70488
70727
  var init_types4 = __esm(() => {
70489
70728
  DEFAULT_WRITE_FILE_SYSTEM = {
70490
70729
  copyFileSync,
70491
- existsSync: existsSync4,
70730
+ existsSync: existsSync5,
70492
70731
  lstatSync: lstatSync2,
70493
- mkdirSync: mkdirSync5,
70494
- readFileSync: readFileSync4,
70732
+ mkdirSync: mkdirSync6,
70733
+ readFileSync: readFileSync5,
70495
70734
  readdirSync,
70496
70735
  renameSync: renameSync2,
70497
- unlinkSync: unlinkSync2,
70736
+ unlinkSync: unlinkSync3,
70498
70737
  writeFileExclusiveSync: (path, content) => {
70499
- writeFileSync2(path, content, { encoding: "utf-8", flag: "wx" });
70738
+ writeFileSync3(path, content, { encoding: "utf-8", flag: "wx" });
70500
70739
  },
70501
- writeFileSync: writeFileSync2
70740
+ writeFileSync: writeFileSync3
70502
70741
  };
70503
70742
  });
70504
70743
 
@@ -71277,7 +71516,8 @@ var init_hooks = __esm(() => {
71277
71516
  "webfetch-redirect-guard",
71278
71517
  "fsync-skip-warning",
71279
71518
  "plan-format-validator",
71280
- "legacy-plugin-toast"
71519
+ "legacy-plugin-toast",
71520
+ "native-edition-nudge"
71281
71521
  ]);
71282
71522
  });
71283
71523
 
@@ -73515,6 +73755,212 @@ async function registerBtwSideTui(api, solid) {
73515
73755
  });
73516
73756
  log2("[btw-side] TUI controls registered");
73517
73757
  }
73758
+ // packages/omo-opencode/src/cli/native-edition-hint.ts
73759
+ var NATIVE_EDITION_INSTALL_COMMAND = "bun add -g omo-ai@beta";
73760
+ var NATIVE_EDITION_GUIDE_URL = "https://github.com/code-yeongyu/oh-my-openagent/blob/dev/docs/guide/installation.md#omo-native-beta-omo-via-omo-ai";
73761
+
73762
+ // packages/omo-opencode/src/cli/install-native/plan.ts
73763
+ var NATIVE_PACKAGE_SPEC = "omo-ai@beta";
73764
+ var NATIVE_SETUP_COMMAND = "omo setup";
73765
+ var PLANS = {
73766
+ bun: { packageManager: "bun", command: "bun", args: ["add", "-g", NATIVE_PACKAGE_SPEC] },
73767
+ npm: { packageManager: "npm", command: "npm", args: ["i", "-g", NATIVE_PACKAGE_SPEC] }
73768
+ };
73769
+ function resolveNativeInstallPlan(bunAvailable) {
73770
+ return bunAvailable ? PLANS.bun : PLANS.npm;
73771
+ }
73772
+ function formatNativeInstallCommand(plan) {
73773
+ return [plan.command, ...plan.args].join(" ");
73774
+ }
73775
+ // packages/omo-opencode/src/cli/install-native/run-native-install.ts
73776
+ init_bun_which_shim();
73777
+
73778
+ // packages/omo-opencode/src/shared/spawn-with-windows-hide.ts
73779
+ init_bun_spawn_shim();
73780
+ // packages/omo-opencode/src/hooks/native-edition-nudge/types.ts
73781
+ var NUDGE_STATE_VERSION = 1;
73782
+ var NUDGE_INTERVALS_MS = [3, 7, 14].map((days) => days * 24 * 60 * 60 * 1000);
73783
+ var NUDGE_SNOOZE_MS = 7 * 24 * 60 * 60 * 1000;
73784
+ var NUDGE_CORRUPT_RECOVERY_MS = 3 * 24 * 60 * 60 * 1000;
73785
+ // packages/omo-opencode/src/hooks/native-edition-nudge/hook.ts
73786
+ import { join as join8 } from "path";
73787
+ init_logger2();
73788
+
73789
+ // packages/omo-opencode/src/hooks/auto-update-checker/constants.ts
73790
+ import * as path4 from "path";
73791
+ init_data_path();
73792
+ init_opencode_config_dir();
73793
+ init_plugin_identity();
73794
+ var PACKAGE_NAME = PUBLISHED_PACKAGE_NAME;
73795
+ var ACCEPTED_PACKAGE_NAMES2 = ACCEPTED_PACKAGE_NAMES;
73796
+ var NPM_REGISTRY_URL = `https://registry.npmjs.org/-/package/${PACKAGE_NAME}/dist-tags`;
73797
+ var CACHE_ROOT_DIR = getOpenCodeCacheDir();
73798
+ var CACHE_DIR = path4.join(CACHE_ROOT_DIR, "packages");
73799
+ var VERSION_FILE = path4.join(CACHE_ROOT_DIR, "version");
73800
+ function getUserConfigDir() {
73801
+ return getOpenCodeConfigDir({ binary: "opencode" });
73802
+ }
73803
+ var INSTALLED_PACKAGE_JSON = path4.join(CACHE_DIR, "node_modules", PACKAGE_NAME, "package.json");
73804
+ var INSTALLED_PACKAGE_JSON_CANDIDATES = ACCEPTED_PACKAGE_NAMES2.map((name) => path4.join(CACHE_DIR, "node_modules", name, "package.json"));
73805
+
73806
+ // packages/omo-opencode/src/hooks/native-edition-nudge/state.ts
73807
+ import { mkdirSync as mkdirSync4, readFileSync as readFileSync2, unlinkSync as unlinkSync2, writeFileSync as writeFileSync2 } from "fs";
73808
+ import { join as join7 } from "path";
73809
+ var NUDGE_STATE_FILE = "native-nudge.json";
73810
+ function isDecision(value) {
73811
+ return value === "none" || value === "snoozed" || value === "never" || value === "migrated";
73812
+ }
73813
+ function isEpoch(value) {
73814
+ return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
73815
+ }
73816
+ function parseNudgeState(raw) {
73817
+ let parsed;
73818
+ try {
73819
+ parsed = JSON.parse(raw);
73820
+ } catch {
73821
+ return "corrupt";
73822
+ }
73823
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed))
73824
+ return "corrupt";
73825
+ const record = parsed;
73826
+ if (!isDecision(record["decision"]))
73827
+ return "corrupt";
73828
+ if (!isEpoch(record["nextEligibleAt"]))
73829
+ return "corrupt";
73830
+ const autoShows = record["autoShows"];
73831
+ return {
73832
+ schemaVersion: typeof record["schemaVersion"] === "number" ? record["schemaVersion"] : NUDGE_STATE_VERSION,
73833
+ autoShows: typeof autoShows === "number" && Number.isSafeInteger(autoShows) && autoShows >= 0 ? autoShows : 0,
73834
+ lastShownAt: isEpoch(record["lastShownAt"]) ? record["lastShownAt"] : null,
73835
+ nextEligibleAt: record["nextEligibleAt"],
73836
+ decision: record["decision"],
73837
+ decidedAt: isEpoch(record["decidedAt"]) ? record["decidedAt"] : null,
73838
+ writtenBy: typeof record["writtenBy"] === "string" ? record["writtenBy"] : "unknown"
73839
+ };
73840
+ }
73841
+ function createNudgeStateStore(stateDir) {
73842
+ const path = join7(stateDir, NUDGE_STATE_FILE);
73843
+ return {
73844
+ read: () => {
73845
+ let raw;
73846
+ try {
73847
+ raw = readFileSync2(path, "utf8");
73848
+ } catch {
73849
+ return "missing";
73850
+ }
73851
+ return parseNudgeState(raw);
73852
+ },
73853
+ write: (state) => {
73854
+ try {
73855
+ mkdirSync4(stateDir, { recursive: true });
73856
+ writeFileSync2(path, `${JSON.stringify(state, null, 2)}
73857
+ `, { mode: 384 });
73858
+ return true;
73859
+ } catch {
73860
+ return false;
73861
+ }
73862
+ },
73863
+ probeWritable: () => {
73864
+ const probe = join7(stateDir, `.${NUDGE_STATE_FILE}.probe`);
73865
+ try {
73866
+ mkdirSync4(stateDir, { recursive: true });
73867
+ writeFileSync2(probe, "", { mode: 384 });
73868
+ } catch {
73869
+ return false;
73870
+ }
73871
+ try {
73872
+ unlinkSync2(probe);
73873
+ } catch {}
73874
+ return true;
73875
+ }
73876
+ };
73877
+ }
73878
+
73879
+ // packages/omo-opencode/src/hooks/native-edition-nudge/hook.ts
73880
+ var NATIVE_NUDGE_TOAST_MESSAGE = `Same agent, one binary, nothing else to keep updated.
73881
+ Install: ${NATIVE_EDITION_INSTALL_COMMAND}`;
73882
+ function nativeEditionStateDir() {
73883
+ return join8(getUserConfigDir(), "oh-my-openagent");
73884
+ }
73885
+ // packages/omo-opencode/src/features/native-edition-nudge/tui.ts
73886
+ var NATIVE_NUDGE_DIALOG_TITLE = "OmO Native";
73887
+ var NATIVE_NUDGE_OPTIONS = [
73888
+ { value: "install", title: "Install OmO Native" },
73889
+ { value: "guide", title: "Open the guide" },
73890
+ { value: "later", title: "Remind me in a week" },
73891
+ { value: "never", title: "Don't ask again" }
73892
+ ];
73893
+ function baseState(now) {
73894
+ return {
73895
+ schemaVersion: NUDGE_STATE_VERSION,
73896
+ autoShows: 0,
73897
+ lastShownAt: null,
73898
+ nextEligibleAt: now,
73899
+ decision: "none",
73900
+ decidedAt: null,
73901
+ writtenBy: "tui"
73902
+ };
73903
+ }
73904
+ function currentState(store, now) {
73905
+ const read = store.read();
73906
+ return read === "missing" || read === "corrupt" ? baseState(now) : read;
73907
+ }
73908
+ function applyNativeEditionNudgeAction(action, options) {
73909
+ const state = currentState(options.store, options.now);
73910
+ if (action === "install") {
73911
+ const command = formatNativeInstallCommand(resolveNativeInstallPlan(options.bunAvailable));
73912
+ return { toast: `Run: ${command}
73913
+ Then: ${NATIVE_SETUP_COMMAND}` };
73914
+ }
73915
+ if (action === "guide") {
73916
+ options.store.write({ ...state, nextEligibleAt: options.now + NUDGE_SNOOZE_MS, writtenBy: "tui" });
73917
+ return { toast: "Opening the OmO Native guide.", url: NATIVE_EDITION_GUIDE_URL };
73918
+ }
73919
+ if (action === "later") {
73920
+ options.store.write({
73921
+ ...state,
73922
+ nextEligibleAt: options.now + NUDGE_SNOOZE_MS,
73923
+ decision: "snoozed",
73924
+ decidedAt: options.now,
73925
+ writtenBy: "tui"
73926
+ });
73927
+ return { toast: "I'll mention OmO Native again in a week." };
73928
+ }
73929
+ options.store.write({ ...state, decision: "never", decidedAt: options.now, writtenBy: "tui" });
73930
+ return { toast: "I won't bring up OmO Native again. The command palette entry stays available." };
73931
+ }
73932
+ function registerNativeEditionNudgeTui(api, deps = {}) {
73933
+ const store = deps.store ?? createNudgeStateStore(nativeEditionStateDir());
73934
+ const open = () => {
73935
+ api.ui.dialog.replace(() => api.ui.DialogSelect({
73936
+ title: NATIVE_NUDGE_DIALOG_TITLE,
73937
+ placeholder: "The same omo as one command, with no host app",
73938
+ options: NATIVE_NUDGE_OPTIONS.map((option) => ({ title: option.title, value: option.value })),
73939
+ onSelect: (option) => {
73940
+ const result = applyNativeEditionNudgeAction(option.value, {
73941
+ store,
73942
+ now: Date.now(),
73943
+ bunAvailable: true
73944
+ });
73945
+ api.ui.dialog.clear();
73946
+ api.ui.toast?.({ message: result.toast });
73947
+ }
73948
+ }));
73949
+ };
73950
+ return api.command?.register(() => [
73951
+ {
73952
+ title: "OmO Native",
73953
+ value: "omo.native.nudge",
73954
+ description: "Install the standalone OmO Native edition, or stop being reminded about it",
73955
+ category: "Session",
73956
+ enabled: true,
73957
+ slash: { name: "native", aliases: ["omo-native"] },
73958
+ onSelect: open
73959
+ }
73960
+ ]) ?? (() => {
73961
+ return;
73962
+ });
73963
+ }
73518
73964
  // packages/omo-opencode/src/features/tui-sidebar/state-types.ts
73519
73965
  function assertNever(value) {
73520
73966
  throw new Error(`Unexpected variant: ${JSON.stringify(value)}`);
@@ -73682,30 +74128,30 @@ function compareJobs(left, right) {
73682
74128
  }
73683
74129
 
73684
74130
  // packages/omo-opencode/src/features/tui-sidebar/mirror-io.ts
73685
- import { mkdirSync as mkdirSync4, readFileSync as readFileSync2 } from "fs";
74131
+ import { mkdirSync as mkdirSync5, readFileSync as readFileSync3 } from "fs";
73686
74132
  init_write_file_atomically();
73687
74133
 
73688
74134
  // packages/omo-opencode/src/features/tui-sidebar/mirror-path.ts
73689
74135
  import { createHash } from "crypto";
73690
- import { realpathSync } from "fs";
73691
- import { homedir as homedir2 } from "os";
73692
- import { join as join5, resolve } from "path";
74136
+ import { realpathSync as realpathSync2 } from "fs";
74137
+ import { homedir as homedir3 } from "os";
74138
+ import { join as join9, resolve as resolve2 } from "path";
73693
74139
  function mirrorStorageDir() {
73694
- return join5(process.env.XDG_DATA_HOME ?? join5(homedir2(), ".local", "share"), "opencode", "storage", "oh-my-openagent", MIRROR_DIR_NAME);
74140
+ return join9(process.env.XDG_DATA_HOME ?? join9(homedir3(), ".local", "share"), "opencode", "storage", "oh-my-openagent", MIRROR_DIR_NAME);
73695
74141
  }
73696
74142
  function canonicalProjectDir(projectDir) {
73697
74143
  try {
73698
- return realpathSync.native(projectDir);
74144
+ return realpathSync2.native(projectDir);
73699
74145
  } catch (error) {
73700
74146
  if (error instanceof Error) {
73701
- return resolve(projectDir);
74147
+ return resolve2(projectDir);
73702
74148
  }
73703
74149
  throw error;
73704
74150
  }
73705
74151
  }
73706
74152
  function mirrorFilePath(projectDir) {
73707
74153
  const projectHash = createHash("sha1").update(canonicalProjectDir(projectDir)).digest("hex").slice(0, 16);
73708
- return join5(mirrorStorageDir(), `${projectHash}.json`);
74154
+ return join9(mirrorStorageDir(), `${projectHash}.json`);
73709
74155
  }
73710
74156
 
73711
74157
  // packages/omo-opencode/src/features/tui-sidebar/snapshot-schema.ts
@@ -73765,7 +74211,7 @@ function parseSnapshot(raw) {
73765
74211
  function readMirror(projectDir) {
73766
74212
  let raw;
73767
74213
  try {
73768
- raw = JSON.parse(readFileSync2(mirrorFilePath(projectDir), "utf-8"));
74214
+ raw = JSON.parse(readFileSync3(mirrorFilePath(projectDir), "utf-8"));
73769
74215
  } catch (error) {
73770
74216
  if (error instanceof Error) {
73771
74217
  return null;
@@ -73975,6 +74421,11 @@ var module = {
73975
74421
  } catch (error) {
73976
74422
  log2("[btw-side] TUI registration failed", { error });
73977
74423
  }
74424
+ try {
74425
+ registerNativeEditionNudgeTui(api);
74426
+ } catch (error) {
74427
+ log2("[native-edition-nudge] TUI registration failed", { error });
74428
+ }
73978
74429
  const directory = api.state.path.directory;
73979
74430
  if ((await loadPluginValidation(directory)).config.tui?.sidebar?.enabled === false) {
73980
74431
  return;