oh-my-opencode 3.12.3 → 3.13.0

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 (68) hide show
  1. package/README.ja.md +11 -0
  2. package/README.ko.md +11 -0
  3. package/README.md +12 -2
  4. package/README.ru.md +11 -0
  5. package/README.zh-cn.md +11 -0
  6. package/dist/agents/prometheus/system-prompt.d.ts +1 -1
  7. package/dist/cli/index.js +168 -115
  8. package/dist/config/schema/hooks.d.ts +1 -1
  9. package/dist/config/schema/oh-my-opencode-config.d.ts +31 -0
  10. package/dist/config/schema/openclaw.d.ts +64 -0
  11. package/dist/create-hooks.d.ts +1 -1
  12. package/dist/features/background-agent/constants.d.ts +3 -3
  13. package/dist/features/boulder-state/index.d.ts +1 -0
  14. package/dist/features/boulder-state/storage.d.ts +10 -1
  15. package/dist/features/boulder-state/top-level-task.d.ts +2 -0
  16. package/dist/features/boulder-state/types.d.ts +28 -0
  17. package/dist/hooks/atlas/boulder-continuation-injector.d.ts +2 -0
  18. package/dist/hooks/atlas/subagent-session-id.d.ts +7 -1
  19. package/dist/hooks/atlas/tool-execute-after.d.ts +2 -1
  20. package/dist/hooks/atlas/tool-execute-before.d.ts +2 -0
  21. package/dist/hooks/atlas/types.d.ts +13 -1
  22. package/dist/hooks/index.d.ts +1 -1
  23. package/dist/hooks/keyword-detector/constants.d.ts +1 -1
  24. package/dist/hooks/keyword-detector/ultrawork/index.d.ts +1 -1
  25. package/dist/hooks/keyword-detector/ultrawork/source-detector.d.ts +5 -0
  26. package/dist/hooks/openclaw.d.ts +11 -0
  27. package/dist/hooks/preemptive-compaction-degradation-monitor.d.ts +55 -0
  28. package/dist/hooks/preemptive-compaction-no-text-tail.d.ts +18 -0
  29. package/dist/hooks/session-recovery/storage/thinking-prepend.d.ts +27 -2
  30. package/dist/hooks/todo-continuation-enforcer/compaction-guard.d.ts +2 -0
  31. package/dist/hooks/todo-continuation-enforcer/handler.d.ts +0 -1
  32. package/dist/hooks/todo-continuation-enforcer/idle-event.d.ts +0 -1
  33. package/dist/hooks/todo-continuation-enforcer/types.d.ts +2 -1
  34. package/dist/hooks/webfetch-redirect-guard/constants.d.ts +6 -0
  35. package/dist/hooks/webfetch-redirect-guard/hook.d.ts +19 -0
  36. package/dist/hooks/webfetch-redirect-guard/index.d.ts +1 -0
  37. package/dist/hooks/webfetch-redirect-guard/redirect-resolution.d.ts +16 -0
  38. package/dist/index.js +1802 -1055
  39. package/dist/oh-my-opencode.schema.json +141 -0
  40. package/dist/openclaw/config.d.ts +8 -0
  41. package/dist/openclaw/daemon.d.ts +1 -0
  42. package/dist/openclaw/dispatcher.d.ts +16 -0
  43. package/dist/openclaw/index.d.ts +5 -0
  44. package/dist/openclaw/reply-listener.d.ts +31 -0
  45. package/dist/openclaw/session-registry.d.ts +17 -0
  46. package/dist/openclaw/tmux.d.ts +8 -0
  47. package/dist/openclaw/types.d.ts +38 -0
  48. package/dist/plugin/hooks/create-continuation-hooks.d.ts +1 -2
  49. package/dist/plugin/hooks/create-core-hooks.d.ts +1 -0
  50. package/dist/plugin/hooks/create-tool-guard-hooks.d.ts +2 -1
  51. package/dist/plugin/normalize-tool-arg-schemas.d.ts +1 -0
  52. package/dist/plugin-handlers/prometheus-agent-config-builder.d.ts +1 -0
  53. package/dist/shared/jsonc-parser.d.ts +4 -0
  54. package/dist/shared/shell-env.d.ts +1 -1
  55. package/dist/tools/delegate-task/categories.d.ts +1 -0
  56. package/dist/tools/delegate-task/constants.d.ts +2 -2
  57. package/dist/tools/delegate-task/model-selection.d.ts +1 -0
  58. package/dist/tools/delegate-task/subagent-resolver.d.ts +1 -1
  59. package/dist/tools/hashline-edit/formatter-trigger.d.ts +38 -0
  60. package/dist/tools/hashline-edit/hashline-edit-executor.d.ts +2 -1
  61. package/dist/tools/hashline-edit/tools.d.ts +2 -1
  62. package/package.json +12 -12
  63. package/dist/hooks/gpt-permission-continuation/assistant-message.d.ts +0 -23
  64. package/dist/hooks/gpt-permission-continuation/constants.d.ts +0 -4
  65. package/dist/hooks/gpt-permission-continuation/detector.d.ts +0 -1
  66. package/dist/hooks/gpt-permission-continuation/handler.d.ts +0 -12
  67. package/dist/hooks/gpt-permission-continuation/index.d.ts +0 -13
  68. package/dist/hooks/gpt-permission-continuation/session-state.d.ts +0 -15
package/dist/cli/index.js CHANGED
@@ -5942,6 +5942,7 @@ var init_main = __esm(() => {
5942
5942
 
5943
5943
  // src/shared/jsonc-parser.ts
5944
5944
  import { existsSync, readFileSync } from "fs";
5945
+ import { join as join3 } from "path";
5945
5946
  function parseJsonc(content) {
5946
5947
  const errors = [];
5947
5948
  const result = parse2(content, errors, {
@@ -5965,8 +5966,18 @@ function detectConfigFile(basePath) {
5965
5966
  }
5966
5967
  return { format: "none", path: jsonPath };
5967
5968
  }
5969
+ function detectPluginConfigFile(dir) {
5970
+ for (const name of PLUGIN_CONFIG_NAMES) {
5971
+ const result = detectConfigFile(join3(dir, name));
5972
+ if (result.format !== "none")
5973
+ return result;
5974
+ }
5975
+ return { format: "none", path: join3(dir, PLUGIN_CONFIG_NAMES[0] + ".json") };
5976
+ }
5977
+ var PLUGIN_CONFIG_NAMES;
5968
5978
  var init_jsonc_parser = __esm(() => {
5969
5979
  init_main();
5980
+ PLUGIN_CONFIG_NAMES = ["oh-my-opencode", "oh-my-openagent"];
5970
5981
  });
5971
5982
 
5972
5983
  // src/shared/migration/agent-names.ts
@@ -6052,7 +6063,8 @@ var init_hook_names = __esm(() => {
6052
6063
  "sisyphus-orchestrator": "atlas",
6053
6064
  "sisyphus-gpt-hephaestus-reminder": "no-sisyphus-gpt",
6054
6065
  "empty-message-sanitizer": null,
6055
- "delegate-task-english-directive": null
6066
+ "delegate-task-english-directive": null,
6067
+ "gpt-permission-continuation": null
6056
6068
  };
6057
6069
  });
6058
6070
 
@@ -6226,7 +6238,7 @@ var init_migration = __esm(() => {
6226
6238
  // src/shared/opencode-config-dir.ts
6227
6239
  import { existsSync as existsSync2 } from "fs";
6228
6240
  import { homedir as homedir2 } from "os";
6229
- import { join as join3, resolve } from "path";
6241
+ import { join as join4, resolve } from "path";
6230
6242
  function isDevBuild(version) {
6231
6243
  if (!version)
6232
6244
  return false;
@@ -6236,15 +6248,15 @@ function getTauriConfigDir(identifier) {
6236
6248
  const platform = process.platform;
6237
6249
  switch (platform) {
6238
6250
  case "darwin":
6239
- return join3(homedir2(), "Library", "Application Support", identifier);
6251
+ return join4(homedir2(), "Library", "Application Support", identifier);
6240
6252
  case "win32": {
6241
- const appData = process.env.APPDATA || join3(homedir2(), "AppData", "Roaming");
6242
- return join3(appData, identifier);
6253
+ const appData = process.env.APPDATA || join4(homedir2(), "AppData", "Roaming");
6254
+ return join4(appData, identifier);
6243
6255
  }
6244
6256
  case "linux":
6245
6257
  default: {
6246
- const xdgConfig = process.env.XDG_CONFIG_HOME || join3(homedir2(), ".config");
6247
- return join3(xdgConfig, identifier);
6258
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join4(homedir2(), ".config");
6259
+ return join4(xdgConfig, identifier);
6248
6260
  }
6249
6261
  }
6250
6262
  }
@@ -6253,8 +6265,8 @@ function getCliConfigDir() {
6253
6265
  if (envConfigDir) {
6254
6266
  return resolve(envConfigDir);
6255
6267
  }
6256
- const xdgConfig = process.env.XDG_CONFIG_HOME || join3(homedir2(), ".config");
6257
- return join3(xdgConfig, "opencode");
6268
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join4(homedir2(), ".config");
6269
+ return join4(xdgConfig, "opencode");
6258
6270
  }
6259
6271
  function getOpenCodeConfigDir(options) {
6260
6272
  const { binary: binary2, version, checkExisting = true } = options;
@@ -6265,8 +6277,8 @@ function getOpenCodeConfigDir(options) {
6265
6277
  const tauriDir = getTauriConfigDir(identifier);
6266
6278
  if (checkExisting) {
6267
6279
  const legacyDir = getCliConfigDir();
6268
- const legacyConfig = join3(legacyDir, "opencode.json");
6269
- const legacyConfigC = join3(legacyDir, "opencode.jsonc");
6280
+ const legacyConfig = join4(legacyDir, "opencode.json");
6281
+ const legacyConfigC = join4(legacyDir, "opencode.jsonc");
6270
6282
  if (existsSync2(legacyConfig) || existsSync2(legacyConfigC)) {
6271
6283
  return legacyDir;
6272
6284
  }
@@ -6277,10 +6289,10 @@ function getOpenCodeConfigPaths(options) {
6277
6289
  const configDir = getOpenCodeConfigDir(options);
6278
6290
  return {
6279
6291
  configDir,
6280
- configJson: join3(configDir, "opencode.json"),
6281
- configJsonc: join3(configDir, "opencode.jsonc"),
6282
- packageJson: join3(configDir, "package.json"),
6283
- omoConfig: join3(configDir, "oh-my-opencode.json")
6292
+ configJson: join4(configDir, "opencode.json"),
6293
+ configJsonc: join4(configDir, "opencode.jsonc"),
6294
+ packageJson: join4(configDir, "package.json"),
6295
+ omoConfig: join4(configDir, "oh-my-opencode.json")
6284
6296
  };
6285
6297
  }
6286
6298
  var TAURI_APP_IDENTIFIER = "ai.opencode.desktop", TAURI_APP_IDENTIFIER_DEV = "ai.opencode.desktop.dev";
@@ -6555,6 +6567,10 @@ var init_model_requirements = __esm(() => {
6555
6567
  },
6556
6568
  quick: {
6557
6569
  fallbackChain: [
6570
+ {
6571
+ providers: ["openai", "github-copilot", "opencode"],
6572
+ model: "gpt-5.4-mini"
6573
+ },
6558
6574
  {
6559
6575
  providers: ["anthropic", "github-copilot", "opencode"],
6560
6576
  model: "claude-haiku-4-5"
@@ -6647,10 +6663,10 @@ var init_system_directive = () => {};
6647
6663
  var init_agent_tool_restrictions = () => {};
6648
6664
  // src/shared/connected-providers-cache.ts
6649
6665
  import { existsSync as existsSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync } from "fs";
6650
- import { join as join4 } from "path";
6666
+ import { join as join5 } from "path";
6651
6667
  function createConnectedProvidersCacheStore(getCacheDir2 = getOmoOpenCodeCacheDir) {
6652
6668
  function getCacheFilePath(filename) {
6653
- return join4(getCacheDir2(), filename);
6669
+ return join5(getCacheDir2(), filename);
6654
6670
  }
6655
6671
  let memConnected;
6656
6672
  let memProviderModels;
@@ -6806,12 +6822,12 @@ var init_connected_providers_cache = __esm(() => {
6806
6822
 
6807
6823
  // src/shared/model-availability.ts
6808
6824
  import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
6809
- import { join as join5 } from "path";
6825
+ import { join as join6 } from "path";
6810
6826
  function isModelCacheAvailable() {
6811
6827
  if (hasProviderModelsCache()) {
6812
6828
  return true;
6813
6829
  }
6814
- const cacheFile = join5(getOpenCodeCacheDir(), "models.json");
6830
+ const cacheFile = join6(getOpenCodeCacheDir(), "models.json");
6815
6831
  return existsSync4(cacheFile);
6816
6832
  }
6817
6833
  var init_model_availability = __esm(() => {
@@ -6873,14 +6889,14 @@ var init_hook_message_injector = __esm(() => {
6873
6889
  });
6874
6890
 
6875
6891
  // src/shared/opencode-storage-paths.ts
6876
- import { join as join6 } from "path";
6892
+ import { join as join7 } from "path";
6877
6893
  var OPENCODE_STORAGE, MESSAGE_STORAGE, PART_STORAGE, SESSION_STORAGE;
6878
6894
  var init_opencode_storage_paths = __esm(() => {
6879
6895
  init_data_path();
6880
6896
  OPENCODE_STORAGE = getOpenCodeStorageDir();
6881
- MESSAGE_STORAGE = join6(OPENCODE_STORAGE, "message");
6882
- PART_STORAGE = join6(OPENCODE_STORAGE, "part");
6883
- SESSION_STORAGE = join6(OPENCODE_STORAGE, "session");
6897
+ MESSAGE_STORAGE = join7(OPENCODE_STORAGE, "message");
6898
+ PART_STORAGE = join7(OPENCODE_STORAGE, "part");
6899
+ SESSION_STORAGE = join7(OPENCODE_STORAGE, "session");
6884
6900
  });
6885
6901
 
6886
6902
  // src/shared/opencode-message-dir.ts
@@ -7488,7 +7504,7 @@ var init_openai_only_model_catalog = __esm(() => {
7488
7504
  };
7489
7505
  OPENAI_ONLY_CATEGORY_OVERRIDES = {
7490
7506
  artistry: { model: "openai/gpt-5.4", variant: "xhigh" },
7491
- quick: { model: "openai/gpt-5.3-codex", variant: "low" },
7507
+ quick: { model: "openai/gpt-5.4-mini" },
7492
7508
  "visual-engineering": { model: "openai/gpt-5.4", variant: "high" },
7493
7509
  writing: { model: "openai/gpt-5.4", variant: "medium" }
7494
7510
  };
@@ -8625,15 +8641,15 @@ var init_update_toasts = __esm(() => {
8625
8641
 
8626
8642
  // src/hooks/auto-update-checker/hook/background-update-check.ts
8627
8643
  import { existsSync as existsSync20 } from "fs";
8628
- import { join as join17 } from "path";
8644
+ import { join as join18 } from "path";
8629
8645
  function getPinnedVersionToastMessage(latestVersion) {
8630
8646
  return `Update available: ${latestVersion} (version pinned, update manually)`;
8631
8647
  }
8632
8648
  function resolveActiveInstallWorkspace() {
8633
8649
  const configPaths = getOpenCodeConfigPaths({ binary: "opencode" });
8634
8650
  const cacheDir = getOpenCodeCacheDir();
8635
- const configInstallPath = join17(configPaths.configDir, "node_modules", PACKAGE_NAME, "package.json");
8636
- const cacheInstallPath = join17(cacheDir, "node_modules", PACKAGE_NAME, "package.json");
8651
+ const configInstallPath = join18(configPaths.configDir, "node_modules", PACKAGE_NAME, "package.json");
8652
+ const cacheInstallPath = join18(cacheDir, "node_modules", PACKAGE_NAME, "package.json");
8637
8653
  if (existsSync20(configInstallPath)) {
8638
8654
  log(`[auto-update-checker] Active workspace: config-dir (${configPaths.configDir})`);
8639
8655
  return configPaths.configDir;
@@ -8941,7 +8957,7 @@ var {
8941
8957
  // package.json
8942
8958
  var package_default = {
8943
8959
  name: "oh-my-opencode",
8944
- version: "3.12.3",
8960
+ version: "3.13.0",
8945
8961
  description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
8946
8962
  main: "dist/index.js",
8947
8963
  types: "dist/index.d.ts",
@@ -9017,17 +9033,17 @@ var package_default = {
9017
9033
  typescript: "^5.7.3"
9018
9034
  },
9019
9035
  optionalDependencies: {
9020
- "oh-my-opencode-darwin-arm64": "3.12.3",
9021
- "oh-my-opencode-darwin-x64": "3.12.3",
9022
- "oh-my-opencode-darwin-x64-baseline": "3.12.3",
9023
- "oh-my-opencode-linux-arm64": "3.12.3",
9024
- "oh-my-opencode-linux-arm64-musl": "3.12.3",
9025
- "oh-my-opencode-linux-x64": "3.12.3",
9026
- "oh-my-opencode-linux-x64-baseline": "3.12.3",
9027
- "oh-my-opencode-linux-x64-musl": "3.12.3",
9028
- "oh-my-opencode-linux-x64-musl-baseline": "3.12.3",
9029
- "oh-my-opencode-windows-x64": "3.12.3",
9030
- "oh-my-opencode-windows-x64-baseline": "3.12.3"
9036
+ "oh-my-opencode-darwin-arm64": "3.13.0",
9037
+ "oh-my-opencode-darwin-x64": "3.13.0",
9038
+ "oh-my-opencode-darwin-x64-baseline": "3.13.0",
9039
+ "oh-my-opencode-linux-arm64": "3.13.0",
9040
+ "oh-my-opencode-linux-arm64-musl": "3.13.0",
9041
+ "oh-my-opencode-linux-x64": "3.13.0",
9042
+ "oh-my-opencode-linux-x64-baseline": "3.13.0",
9043
+ "oh-my-opencode-linux-x64-musl": "3.13.0",
9044
+ "oh-my-opencode-linux-x64-musl-baseline": "3.13.0",
9045
+ "oh-my-opencode-windows-x64": "3.13.0",
9046
+ "oh-my-opencode-windows-x64-baseline": "3.13.0"
9031
9047
  },
9032
9048
  overrides: {
9033
9049
  "@opencode-ai/sdk": "^1.2.24"
@@ -9898,7 +9914,7 @@ async function promptInstallConfig(detected) {
9898
9914
  message: "Will you integrate Google Gemini?",
9899
9915
  options: [
9900
9916
  { value: "no", label: "No", hint: "Frontend/docs agents will use fallback" },
9901
- { value: "yes", label: "Yes", hint: "Beautiful UI generation with Gemini 3 Pro" }
9917
+ { value: "yes", label: "Yes", hint: "Beautiful UI generation with Gemini 3.1 Pro" }
9902
9918
  ],
9903
9919
  initialValue: initial.gemini
9904
9920
  });
@@ -24551,7 +24567,6 @@ var GitMasterConfigSchema = exports_external.object({
24551
24567
  });
24552
24568
  // src/config/schema/hooks.ts
24553
24569
  var HookNameSchema = exports_external.enum([
24554
- "gpt-permission-continuation",
24555
24570
  "todo-continuation-enforcer",
24556
24571
  "context-window-monitor",
24557
24572
  "session-recovery",
@@ -24599,7 +24614,8 @@ var HookNameSchema = exports_external.enum([
24599
24614
  "anthropic-effort",
24600
24615
  "hashline-read-enhancer",
24601
24616
  "read-image-resizer",
24602
- "todo-description-override"
24617
+ "todo-description-override",
24618
+ "webfetch-redirect-guard"
24603
24619
  ]);
24604
24620
  // src/config/schema/notification.ts
24605
24621
  var NotificationConfigSchema = exports_external.object({
@@ -24609,6 +24625,39 @@ var NotificationConfigSchema = exports_external.object({
24609
24625
  var McpNameSchema = exports_external.enum(["websearch", "context7", "grep_app"]);
24610
24626
  var AnyMcpNameSchema = exports_external.string().min(1);
24611
24627
 
24628
+ // src/config/schema/openclaw.ts
24629
+ var OpenClawGatewaySchema = exports_external.object({
24630
+ type: exports_external.enum(["http", "command"]).default("http"),
24631
+ url: exports_external.string().optional(),
24632
+ method: exports_external.string().default("POST"),
24633
+ headers: exports_external.record(exports_external.string(), exports_external.string()).optional(),
24634
+ command: exports_external.string().optional(),
24635
+ timeout: exports_external.number().optional()
24636
+ });
24637
+ var OpenClawHookSchema = exports_external.object({
24638
+ enabled: exports_external.boolean().default(true),
24639
+ gateway: exports_external.string(),
24640
+ instruction: exports_external.string()
24641
+ });
24642
+ var OpenClawReplyListenerConfigSchema = exports_external.object({
24643
+ discordBotToken: exports_external.string().optional(),
24644
+ discordChannelId: exports_external.string().optional(),
24645
+ discordMention: exports_external.string().optional(),
24646
+ authorizedDiscordUserIds: exports_external.array(exports_external.string()).default([]),
24647
+ telegramBotToken: exports_external.string().optional(),
24648
+ telegramChatId: exports_external.string().optional(),
24649
+ pollIntervalMs: exports_external.number().default(3000),
24650
+ rateLimitPerMinute: exports_external.number().default(10),
24651
+ maxMessageLength: exports_external.number().default(500),
24652
+ includePrefix: exports_external.boolean().default(true)
24653
+ });
24654
+ var OpenClawConfigSchema = exports_external.object({
24655
+ enabled: exports_external.boolean().default(false),
24656
+ gateways: exports_external.record(exports_external.string(), OpenClawGatewaySchema).default({}),
24657
+ hooks: exports_external.record(exports_external.string(), OpenClawHookSchema).default({}),
24658
+ replyListener: OpenClawReplyListenerConfigSchema.optional()
24659
+ });
24660
+
24612
24661
  // src/config/schema/ralph-loop.ts
24613
24662
  var RalphLoopConfigSchema = exports_external.object({
24614
24663
  enabled: exports_external.boolean().default(false),
@@ -24730,6 +24779,7 @@ var OhMyOpenCodeConfigSchema = exports_external.object({
24730
24779
  runtime_fallback: exports_external.union([exports_external.boolean(), RuntimeFallbackConfigSchema]).optional(),
24731
24780
  background_task: BackgroundTaskConfigSchema.optional(),
24732
24781
  notification: NotificationConfigSchema.optional(),
24782
+ openclaw: OpenClawConfigSchema.optional(),
24733
24783
  babysitting: BabysittingConfigSchema.optional(),
24734
24784
  git_master: GitMasterConfigSchema.optional(),
24735
24785
  browser_automation_engine: BrowserAutomationConfigSchema.optional(),
@@ -24860,12 +24910,11 @@ function mergeConfigs(base, override) {
24860
24910
  }
24861
24911
  function loadPluginConfig(directory, ctx) {
24862
24912
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
24863
- const userBasePath = path3.join(configDir, "oh-my-opencode");
24864
- const userDetected = detectConfigFile(userBasePath);
24865
- const userConfigPath = userDetected.format !== "none" ? userDetected.path : userBasePath + ".json";
24866
- const projectBasePath = path3.join(directory, ".opencode", "oh-my-opencode");
24867
- const projectDetected = detectConfigFile(projectBasePath);
24868
- const projectConfigPath = projectDetected.format !== "none" ? projectDetected.path : projectBasePath + ".json";
24913
+ const userDetected = detectPluginConfigFile(configDir);
24914
+ const userConfigPath = userDetected.format !== "none" ? userDetected.path : path3.join(configDir, "oh-my-opencode.json");
24915
+ const projectBasePath = path3.join(directory, ".opencode");
24916
+ const projectDetected = detectPluginConfigFile(projectBasePath);
24917
+ const projectConfigPath = projectDetected.format !== "none" ? projectDetected.path : path3.join(projectBasePath, "oh-my-opencode.json");
24869
24918
  let config2 = loadConfigFromPath(userConfigPath, ctx) ?? {};
24870
24919
  const projectConfig = loadConfigFromPath(projectConfigPath, ctx);
24871
24920
  if (projectConfig) {
@@ -26331,7 +26380,7 @@ var import_picocolors9 = __toESM(require_picocolors(), 1);
26331
26380
 
26332
26381
  // src/cli/run/opencode-binary-resolver.ts
26333
26382
  init_spawn_with_windows_hide();
26334
- import { delimiter, dirname, join as join8 } from "path";
26383
+ import { delimiter, dirname, join as join9 } from "path";
26335
26384
  var OPENCODE_COMMANDS = ["opencode", "opencode-desktop"];
26336
26385
  var WINDOWS_SUFFIXES = ["", ".exe", ".cmd", ".bat", ".ps1"];
26337
26386
  function getCommandCandidates(platform) {
@@ -26354,7 +26403,7 @@ function collectCandidateBinaryPaths(pathEnv, which = Bun.which, platform = proc
26354
26403
  }
26355
26404
  for (const entry of (pathEnv ?? "").split(delimiter).filter(Boolean)) {
26356
26405
  for (const command of commandCandidates) {
26357
- addCandidate(join8(entry, command));
26406
+ addCandidate(join9(entry, command));
26358
26407
  }
26359
26408
  }
26360
26409
  return candidates;
@@ -26721,9 +26770,10 @@ var NOTEPAD_DIR = "notepads";
26721
26770
  var NOTEPAD_BASE_PATH = `${BOULDER_DIR}/${NOTEPAD_DIR}`;
26722
26771
  // src/features/boulder-state/storage.ts
26723
26772
  import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync5, mkdirSync as mkdirSync3, readdirSync } from "fs";
26724
- import { dirname as dirname2, join as join9, basename } from "path";
26773
+ import { dirname as dirname2, join as join10, basename } from "path";
26774
+ var RESERVED_KEYS = new Set(["__proto__", "prototype", "constructor"]);
26725
26775
  function getBoulderFilePath(directory) {
26726
- return join9(directory, BOULDER_DIR, BOULDER_FILE);
26776
+ return join10(directory, BOULDER_DIR, BOULDER_FILE);
26727
26777
  }
26728
26778
  function readBoulderState(directory) {
26729
26779
  const filePath = getBoulderFilePath(directory);
@@ -26739,6 +26789,9 @@ function readBoulderState(directory) {
26739
26789
  if (!Array.isArray(parsed.session_ids)) {
26740
26790
  parsed.session_ids = [];
26741
26791
  }
26792
+ if (!parsed.task_sessions || typeof parsed.task_sessions !== "object" || Array.isArray(parsed.task_sessions)) {
26793
+ parsed.task_sessions = {};
26794
+ }
26742
26795
  return parsed;
26743
26796
  } catch {
26744
26797
  return null;
@@ -26757,7 +26810,7 @@ function getPlanProgress(planPath) {
26757
26810
  return {
26758
26811
  total,
26759
26812
  completed,
26760
- isComplete: total === 0 || completed === total
26813
+ isComplete: total > 0 && completed === total
26761
26814
  };
26762
26815
  } catch {
26763
26816
  return { total: 0, completed: 0, isComplete: true };
@@ -26767,9 +26820,9 @@ function getPlanProgress(planPath) {
26767
26820
  var CONTINUATION_MARKER_DIR = ".sisyphus/run-continuation";
26768
26821
  // src/features/run-continuation-state/storage.ts
26769
26822
  import { existsSync as existsSync12, mkdirSync as mkdirSync4, readFileSync as readFileSync10, rmSync, writeFileSync as writeFileSync6 } from "fs";
26770
- import { join as join10 } from "path";
26823
+ import { join as join11 } from "path";
26771
26824
  function getMarkerPath(directory, sessionID) {
26772
- return join10(directory, CONTINUATION_MARKER_DIR, `${sessionID}.json`);
26825
+ return join11(directory, CONTINUATION_MARKER_DIR, `${sessionID}.json`);
26773
26826
  }
26774
26827
  function readContinuationMarker(directory, sessionID) {
26775
26828
  const markerPath = getMarkerPath(directory, sessionID);
@@ -26802,7 +26855,7 @@ function getActiveContinuationMarkerReason(marker) {
26802
26855
  // src/hooks/ralph-loop/storage.ts
26803
26856
  init_frontmatter();
26804
26857
  import { existsSync as existsSync13, readFileSync as readFileSync11, writeFileSync as writeFileSync7, unlinkSync, mkdirSync as mkdirSync5 } from "fs";
26805
- import { dirname as dirname3, join as join11 } from "path";
26858
+ import { dirname as dirname3, join as join12 } from "path";
26806
26859
 
26807
26860
  // src/hooks/ralph-loop/constants.ts
26808
26861
  var DEFAULT_STATE_FILE = ".sisyphus/ralph-loop.local.md";
@@ -26811,7 +26864,7 @@ var DEFAULT_COMPLETION_PROMISE = "DONE";
26811
26864
 
26812
26865
  // src/hooks/ralph-loop/storage.ts
26813
26866
  function getStateFilePath(directory, customPath) {
26814
- return customPath ? join11(directory, customPath) : join11(directory, DEFAULT_STATE_FILE);
26867
+ return customPath ? join12(directory, customPath) : join12(directory, DEFAULT_STATE_FILE);
26815
26868
  }
26816
26869
  function readState(directory, customPath) {
26817
26870
  const filePath = getStateFilePath(directory, customPath);
@@ -27227,6 +27280,7 @@ async function waitForEventProcessorShutdown(eventProcessor, timeoutMs = EVENT_P
27227
27280
  }
27228
27281
  async function run(options) {
27229
27282
  process.env.OPENCODE_CLI_RUN_MODE = "true";
27283
+ process.env.OPENCODE_CLIENT = "run";
27230
27284
  const startTime = Date.now();
27231
27285
  const {
27232
27286
  message,
@@ -27529,24 +27583,24 @@ import { existsSync as existsSync24, readFileSync as readFileSync21 } from "fs";
27529
27583
  init_spawn_with_windows_hide();
27530
27584
  import { existsSync as existsSync21 } from "fs";
27531
27585
  import { homedir as homedir5 } from "os";
27532
- import { join as join18 } from "path";
27586
+ import { join as join19 } from "path";
27533
27587
  function getDesktopAppPaths(platform) {
27534
27588
  const home = homedir5();
27535
27589
  switch (platform) {
27536
27590
  case "darwin":
27537
27591
  return [
27538
27592
  "/Applications/OpenCode.app/Contents/MacOS/OpenCode",
27539
- join18(home, "Applications", "OpenCode.app", "Contents", "MacOS", "OpenCode")
27593
+ join19(home, "Applications", "OpenCode.app", "Contents", "MacOS", "OpenCode")
27540
27594
  ];
27541
27595
  case "win32": {
27542
27596
  const programFiles = process.env.ProgramFiles;
27543
27597
  const localAppData = process.env.LOCALAPPDATA;
27544
27598
  const paths = [];
27545
27599
  if (programFiles) {
27546
- paths.push(join18(programFiles, "OpenCode", "OpenCode.exe"));
27600
+ paths.push(join19(programFiles, "OpenCode", "OpenCode.exe"));
27547
27601
  }
27548
27602
  if (localAppData) {
27549
- paths.push(join18(localAppData, "OpenCode", "OpenCode.exe"));
27603
+ paths.push(join19(localAppData, "OpenCode", "OpenCode.exe"));
27550
27604
  }
27551
27605
  return paths;
27552
27606
  }
@@ -27554,8 +27608,8 @@ function getDesktopAppPaths(platform) {
27554
27608
  return [
27555
27609
  "/usr/bin/opencode",
27556
27610
  "/usr/lib/opencode/opencode",
27557
- join18(home, "Applications", "opencode-desktop-linux-x86_64.AppImage"),
27558
- join18(home, "Applications", "opencode-desktop-linux-aarch64.AppImage")
27611
+ join19(home, "Applications", "opencode-desktop-linux-x86_64.AppImage"),
27612
+ join19(home, "Applications", "opencode-desktop-linux-aarch64.AppImage")
27559
27613
  ];
27560
27614
  default:
27561
27615
  return [];
@@ -27705,21 +27759,21 @@ init_checker();
27705
27759
  init_auto_update_checker();
27706
27760
  import { existsSync as existsSync23, readFileSync as readFileSync20 } from "fs";
27707
27761
  import { homedir as homedir6 } from "os";
27708
- import { join as join19 } from "path";
27762
+ import { join as join20 } from "path";
27709
27763
  init_shared();
27710
27764
  function getPlatformDefaultCacheDir(platform = process.platform) {
27711
27765
  if (platform === "darwin")
27712
- return join19(homedir6(), "Library", "Caches");
27766
+ return join20(homedir6(), "Library", "Caches");
27713
27767
  if (platform === "win32")
27714
- return process.env.LOCALAPPDATA ?? join19(homedir6(), "AppData", "Local");
27715
- return join19(homedir6(), ".cache");
27768
+ return process.env.LOCALAPPDATA ?? join20(homedir6(), "AppData", "Local");
27769
+ return join20(homedir6(), ".cache");
27716
27770
  }
27717
27771
  function resolveOpenCodeCacheDir() {
27718
27772
  const xdgCacheHome = process.env.XDG_CACHE_HOME;
27719
27773
  if (xdgCacheHome)
27720
- return join19(xdgCacheHome, "opencode");
27774
+ return join20(xdgCacheHome, "opencode");
27721
27775
  const fromShared = getOpenCodeCacheDir();
27722
- const platformDefault = join19(getPlatformDefaultCacheDir(), "opencode");
27776
+ const platformDefault = join20(getPlatformDefaultCacheDir(), "opencode");
27723
27777
  if (existsSync23(fromShared) || !existsSync23(platformDefault))
27724
27778
  return fromShared;
27725
27779
  return platformDefault;
@@ -27747,12 +27801,12 @@ function getLoadedPluginVersion() {
27747
27801
  {
27748
27802
  cacheDir: configPaths.configDir,
27749
27803
  cachePackagePath: configPaths.packageJson,
27750
- installedPackagePath: join19(configPaths.configDir, "node_modules", PACKAGE_NAME2, "package.json")
27804
+ installedPackagePath: join20(configPaths.configDir, "node_modules", PACKAGE_NAME2, "package.json")
27751
27805
  },
27752
27806
  {
27753
27807
  cacheDir,
27754
- cachePackagePath: join19(cacheDir, "package.json"),
27755
- installedPackagePath: join19(cacheDir, "node_modules", PACKAGE_NAME2, "package.json")
27808
+ cachePackagePath: join20(cacheDir, "package.json"),
27809
+ installedPackagePath: join20(cacheDir, "node_modules", PACKAGE_NAME2, "package.json")
27756
27810
  }
27757
27811
  ];
27758
27812
  const selectedCandidate = candidates.find((candidate) => existsSync23(candidate.installedPackagePath)) ?? candidates[0];
@@ -27889,22 +27943,22 @@ async function checkSystem() {
27889
27943
 
27890
27944
  // src/cli/doctor/checks/config.ts
27891
27945
  import { readFileSync as readFileSync24 } from "fs";
27892
- import { join as join23 } from "path";
27946
+ import { join as join24 } from "path";
27893
27947
  init_shared();
27894
27948
 
27895
27949
  // src/cli/doctor/checks/model-resolution-cache.ts
27896
27950
  init_shared();
27897
27951
  import { existsSync as existsSync25, readFileSync as readFileSync22 } from "fs";
27898
27952
  import { homedir as homedir7 } from "os";
27899
- import { join as join20 } from "path";
27953
+ import { join as join21 } from "path";
27900
27954
  function getOpenCodeCacheDir2() {
27901
27955
  const xdgCache = process.env.XDG_CACHE_HOME;
27902
27956
  if (xdgCache)
27903
- return join20(xdgCache, "opencode");
27904
- return join20(homedir7(), ".cache", "opencode");
27957
+ return join21(xdgCache, "opencode");
27958
+ return join21(homedir7(), ".cache", "opencode");
27905
27959
  }
27906
27960
  function loadAvailableModelsFromCache() {
27907
- const cacheFile = join20(getOpenCodeCacheDir2(), "models.json");
27961
+ const cacheFile = join21(getOpenCodeCacheDir2(), "models.json");
27908
27962
  if (!existsSync25(cacheFile)) {
27909
27963
  return { providers: [], modelCount: 0, cacheExists: false };
27910
27964
  }
@@ -27931,12 +27985,11 @@ init_model_requirements();
27931
27985
  // src/cli/doctor/checks/model-resolution-config.ts
27932
27986
  init_shared();
27933
27987
  import { readFileSync as readFileSync23 } from "fs";
27934
- import { join as join21 } from "path";
27935
- var PACKAGE_NAME3 = "oh-my-opencode";
27936
- var USER_CONFIG_BASE = join21(getOpenCodeConfigPaths({ binary: "opencode", version: null }).configDir, PACKAGE_NAME3);
27937
- var PROJECT_CONFIG_BASE = join21(process.cwd(), ".opencode", PACKAGE_NAME3);
27988
+ import { join as join22 } from "path";
27989
+ var USER_CONFIG_DIR2 = getOpenCodeConfigPaths({ binary: "opencode", version: null }).configDir;
27990
+ var PROJECT_CONFIG_DIR = join22(process.cwd(), ".opencode");
27938
27991
  function loadOmoConfig() {
27939
- const projectDetected = detectConfigFile(PROJECT_CONFIG_BASE);
27992
+ const projectDetected = detectPluginConfigFile(PROJECT_CONFIG_DIR);
27940
27993
  if (projectDetected.format !== "none") {
27941
27994
  try {
27942
27995
  const content = readFileSync23(projectDetected.path, "utf-8");
@@ -27945,7 +27998,7 @@ function loadOmoConfig() {
27945
27998
  return null;
27946
27999
  }
27947
28000
  }
27948
- const userDetected = detectConfigFile(USER_CONFIG_BASE);
28001
+ const userDetected = detectPluginConfigFile(USER_CONFIG_DIR2);
27949
28002
  if (userDetected.format !== "none") {
27950
28003
  try {
27951
28004
  const content = readFileSync23(userDetected.path, "utf-8");
@@ -27959,7 +28012,7 @@ function loadOmoConfig() {
27959
28012
 
27960
28013
  // src/cli/doctor/checks/model-resolution-details.ts
27961
28014
  init_shared();
27962
- import { join as join22 } from "path";
28015
+ import { join as join23 } from "path";
27963
28016
 
27964
28017
  // src/cli/doctor/checks/model-resolution-variant.ts
27965
28018
  function formatModelWithVariant(model, variant) {
@@ -27998,7 +28051,7 @@ function getCategoryEffectiveVariant(categoryName, requirement, config2) {
27998
28051
  // src/cli/doctor/checks/model-resolution-details.ts
27999
28052
  function buildModelResolutionDetails(options) {
28000
28053
  const details = [];
28001
- const cacheFile = join22(getOpenCodeCacheDir(), "models.json");
28054
+ const cacheFile = join23(getOpenCodeCacheDir(), "models.json");
28002
28055
  details.push("\u2550\u2550\u2550 Available Models (from cache) \u2550\u2550\u2550");
28003
28056
  details.push("");
28004
28057
  if (options.available.cacheExists) {
@@ -28110,13 +28163,13 @@ async function checkModels() {
28110
28163
  }
28111
28164
 
28112
28165
  // src/cli/doctor/checks/config.ts
28113
- var USER_CONFIG_BASE2 = join23(getOpenCodeConfigDir({ binary: "opencode" }), PACKAGE_NAME2);
28114
- var PROJECT_CONFIG_BASE2 = join23(process.cwd(), ".opencode", PACKAGE_NAME2);
28166
+ var USER_CONFIG_DIR3 = getOpenCodeConfigDir({ binary: "opencode" });
28167
+ var PROJECT_CONFIG_DIR2 = join24(process.cwd(), ".opencode");
28115
28168
  function findConfigPath() {
28116
- const projectConfig = detectConfigFile(PROJECT_CONFIG_BASE2);
28169
+ const projectConfig = detectPluginConfigFile(PROJECT_CONFIG_DIR2);
28117
28170
  if (projectConfig.format !== "none")
28118
28171
  return projectConfig.path;
28119
- const userConfig = detectConfigFile(USER_CONFIG_BASE2);
28172
+ const userConfig = detectPluginConfigFile(USER_CONFIG_DIR3);
28120
28173
  if (userConfig.format !== "none")
28121
28174
  return userConfig.path;
28122
28175
  return null;
@@ -28233,7 +28286,7 @@ async function checkConfig() {
28233
28286
  init_spawn_with_windows_hide();
28234
28287
  import { existsSync as existsSync26 } from "fs";
28235
28288
  import { createRequire } from "module";
28236
- import { dirname as dirname6, join as join24 } from "path";
28289
+ import { dirname as dirname6, join as join25 } from "path";
28237
28290
  async function checkBinaryExists(binary2) {
28238
28291
  try {
28239
28292
  const path10 = Bun.which(binary2);
@@ -28290,11 +28343,11 @@ async function checkAstGrepNapi() {
28290
28343
  };
28291
28344
  } catch {
28292
28345
  const { existsSync: existsSync27 } = await import("fs");
28293
- const { join: join25 } = await import("path");
28346
+ const { join: join26 } = await import("path");
28294
28347
  const { homedir: homedir8 } = await import("os");
28295
28348
  const pathsToCheck = [
28296
- join25(homedir8(), ".config", "opencode", "node_modules", "@ast-grep", "napi"),
28297
- join25(process.cwd(), "node_modules", "@ast-grep", "napi")
28349
+ join26(homedir8(), ".config", "opencode", "node_modules", "@ast-grep", "napi"),
28350
+ join26(process.cwd(), "node_modules", "@ast-grep", "napi")
28298
28351
  ];
28299
28352
  for (const napiPath of pathsToCheck) {
28300
28353
  if (existsSync27(napiPath)) {
@@ -28322,7 +28375,7 @@ function findCommentCheckerPackageBinary() {
28322
28375
  try {
28323
28376
  const require2 = createRequire(import.meta.url);
28324
28377
  const pkgPath = require2.resolve("@code-yeongyu/comment-checker/package.json");
28325
- const binaryPath = join24(dirname6(pkgPath), "bin", binaryName);
28378
+ const binaryPath = join25(dirname6(pkgPath), "bin", binaryName);
28326
28379
  if (existsSync26(binaryPath))
28327
28380
  return binaryPath;
28328
28381
  } catch {}
@@ -28481,7 +28534,7 @@ var BUILTIN_SERVERS = {
28481
28534
  };
28482
28535
  // src/tools/lsp/server-config-loader.ts
28483
28536
  import { existsSync as existsSync27, readFileSync as readFileSync25 } from "fs";
28484
- import { join as join25 } from "path";
28537
+ import { join as join26 } from "path";
28485
28538
  init_shared();
28486
28539
  init_jsonc_parser();
28487
28540
  function loadJsonFile(path10) {
@@ -28497,9 +28550,9 @@ function getConfigPaths2() {
28497
28550
  const cwd = process.cwd();
28498
28551
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
28499
28552
  return {
28500
- project: detectConfigFile(join25(cwd, ".opencode", "oh-my-opencode")).path,
28501
- user: detectConfigFile(join25(configDir, "oh-my-opencode")).path,
28502
- opencode: detectConfigFile(join25(configDir, "opencode")).path
28553
+ project: detectPluginConfigFile(join26(cwd, ".opencode")).path,
28554
+ user: detectPluginConfigFile(configDir).path,
28555
+ opencode: detectConfigFile(join26(configDir, "opencode")).path
28503
28556
  };
28504
28557
  }
28505
28558
  function loadAllConfigs() {
@@ -28569,20 +28622,20 @@ function getMergedServers() {
28569
28622
 
28570
28623
  // src/tools/lsp/server-installation.ts
28571
28624
  import { existsSync as existsSync28 } from "fs";
28572
- import { delimiter as delimiter2, join as join27 } from "path";
28625
+ import { delimiter as delimiter2, join as join28 } from "path";
28573
28626
 
28574
28627
  // src/tools/lsp/server-path-bases.ts
28575
28628
  init_shared();
28576
- import { join as join26 } from "path";
28629
+ import { join as join27 } from "path";
28577
28630
  function getLspServerAdditionalPathBases(workingDirectory) {
28578
28631
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
28579
- const dataDir = join26(getDataDir(), "opencode");
28632
+ const dataDir = join27(getDataDir(), "opencode");
28580
28633
  return [
28581
- join26(workingDirectory, "node_modules", ".bin"),
28582
- join26(configDir, "bin"),
28583
- join26(configDir, "node_modules", ".bin"),
28584
- join26(dataDir, "bin"),
28585
- join26(dataDir, "bin", "node_modules", ".bin")
28634
+ join27(workingDirectory, "node_modules", ".bin"),
28635
+ join27(configDir, "bin"),
28636
+ join27(configDir, "node_modules", ".bin"),
28637
+ join27(dataDir, "bin"),
28638
+ join27(dataDir, "bin", "node_modules", ".bin")
28586
28639
  ];
28587
28640
  }
28588
28641
 
@@ -28613,14 +28666,14 @@ function isServerInstalled(command) {
28613
28666
  const paths = pathEnv.split(delimiter2);
28614
28667
  for (const p2 of paths) {
28615
28668
  for (const suffix of exts) {
28616
- if (existsSync28(join27(p2, cmd + suffix))) {
28669
+ if (existsSync28(join28(p2, cmd + suffix))) {
28617
28670
  return true;
28618
28671
  }
28619
28672
  }
28620
28673
  }
28621
28674
  for (const base of getLspServerAdditionalPathBases(process.cwd())) {
28622
28675
  for (const suffix of exts) {
28623
- if (existsSync28(join27(base, cmd + suffix))) {
28676
+ if (existsSync28(join28(base, cmd + suffix))) {
28624
28677
  return true;
28625
28678
  }
28626
28679
  }
@@ -28684,13 +28737,13 @@ function getInstalledLspServers() {
28684
28737
  init_shared();
28685
28738
  import { existsSync as existsSync29, readFileSync as readFileSync26 } from "fs";
28686
28739
  import { homedir as homedir8 } from "os";
28687
- import { join as join28 } from "path";
28740
+ import { join as join29 } from "path";
28688
28741
  var BUILTIN_MCP_SERVERS = ["context7", "grep_app"];
28689
28742
  function getMcpConfigPaths() {
28690
28743
  return [
28691
- join28(homedir8(), ".claude", ".mcp.json"),
28692
- join28(process.cwd(), ".mcp.json"),
28693
- join28(process.cwd(), ".claude", ".mcp.json")
28744
+ join29(homedir8(), ".claude", ".mcp.json"),
28745
+ join29(process.cwd(), ".mcp.json"),
28746
+ join29(process.cwd(), ".claude", ".mcp.json")
28694
28747
  ];
28695
28748
  }
28696
28749
  function loadUserMcpConfig() {
@@ -29121,10 +29174,10 @@ async function doctor(options = { mode: "default" }) {
29121
29174
  // src/features/mcp-oauth/storage.ts
29122
29175
  init_shared();
29123
29176
  import { chmodSync, existsSync as existsSync30, mkdirSync as mkdirSync6, readFileSync as readFileSync27, unlinkSync as unlinkSync4, writeFileSync as writeFileSync10 } from "fs";
29124
- import { dirname as dirname7, join as join29 } from "path";
29177
+ import { dirname as dirname7, join as join30 } from "path";
29125
29178
  var STORAGE_FILE_NAME = "mcp-oauth.json";
29126
29179
  function getMcpOauthStoragePath() {
29127
- return join29(getOpenCodeConfigDir({ binary: "opencode" }), STORAGE_FILE_NAME);
29180
+ return join30(getOpenCodeConfigDir({ binary: "opencode" }), STORAGE_FILE_NAME);
29128
29181
  }
29129
29182
  function normalizeHost(serverHost) {
29130
29183
  let host = serverHost.trim();
@@ -29753,7 +29806,7 @@ Examples:
29753
29806
  Model Providers (Priority: Native > Copilot > OpenCode Zen > Z.ai > Kimi):
29754
29807
  Claude Native anthropic/ models (Opus, Sonnet, Haiku)
29755
29808
  OpenAI Native openai/ models (GPT-5.4 for Oracle)
29756
- Gemini Native google/ models (Gemini 3 Pro, Flash)
29809
+ Gemini Native google/ models (Gemini 3.1 Pro, Flash)
29757
29810
  Copilot github-copilot/ models (fallback)
29758
29811
  OpenCode Zen opencode/ models (opencode/claude-opus-4-6, etc.)
29759
29812
  Z.ai zai-coding-plan/glm-5 (visual-engineering fallback)