oh-my-opencode 3.15.1 → 3.15.3

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.
package/dist/cli/index.js CHANGED
@@ -6360,25 +6360,95 @@ function getOpenCodeConfigPaths(options) {
6360
6360
  configJson: join4(configDir, "opencode.json"),
6361
6361
  configJsonc: join4(configDir, "opencode.jsonc"),
6362
6362
  packageJson: join4(configDir, "package.json"),
6363
- omoConfig: join4(configDir, "oh-my-opencode.json")
6363
+ omoConfig: join4(configDir, `${CONFIG_BASENAME}.json`)
6364
6364
  };
6365
6365
  }
6366
6366
  var TAURI_APP_IDENTIFIER = "ai.opencode.desktop", TAURI_APP_IDENTIFIER_DEV = "ai.opencode.desktop.dev";
6367
6367
  var init_opencode_config_dir = () => {};
6368
6368
 
6369
6369
  // src/shared/opencode-version.ts
6370
- var NOT_CACHED;
6370
+ import { execSync } from "child_process";
6371
+ function parseVersion(version) {
6372
+ const cleaned = version.replace(/^v/, "").split("-")[0];
6373
+ return cleaned.split(".").map((n) => parseInt(n, 10) || 0);
6374
+ }
6375
+ function compareVersions(a, b) {
6376
+ const partsA = parseVersion(a);
6377
+ const partsB = parseVersion(b);
6378
+ const maxLen = Math.max(partsA.length, partsB.length);
6379
+ for (let i2 = 0;i2 < maxLen; i2++) {
6380
+ const numA = partsA[i2] ?? 0;
6381
+ const numB = partsB[i2] ?? 0;
6382
+ if (numA < numB)
6383
+ return -1;
6384
+ if (numA > numB)
6385
+ return 1;
6386
+ }
6387
+ return 0;
6388
+ }
6389
+ function getOpenCodeVersion() {
6390
+ if (cachedVersion !== NOT_CACHED) {
6391
+ return cachedVersion;
6392
+ }
6393
+ try {
6394
+ const result = execSync("opencode --version", {
6395
+ encoding: "utf-8",
6396
+ timeout: 5000,
6397
+ stdio: ["pipe", "pipe", "pipe"]
6398
+ }).trim();
6399
+ const versionMatch = result.match(/(\d+\.\d+\.\d+(?:-[\w.]+)?)/);
6400
+ cachedVersion = versionMatch?.[1] ?? null;
6401
+ return cachedVersion;
6402
+ } catch {
6403
+ cachedVersion = null;
6404
+ return null;
6405
+ }
6406
+ }
6407
+ function isOpenCodeVersionAtLeast(version) {
6408
+ const current = getOpenCodeVersion();
6409
+ if (!current)
6410
+ return true;
6411
+ return compareVersions(current, version) >= 0;
6412
+ }
6413
+ var OPENCODE_SQLITE_VERSION = "1.1.53", NOT_CACHED, cachedVersion;
6371
6414
  var init_opencode_version = __esm(() => {
6372
6415
  NOT_CACHED = Symbol("NOT_CACHED");
6416
+ cachedVersion = NOT_CACHED;
6373
6417
  });
6374
6418
 
6375
6419
  // src/shared/opencode-storage-detection.ts
6376
- var NOT_CACHED2, FALSE_PENDING_RETRY;
6420
+ import { existsSync as existsSync3 } from "fs";
6421
+ import { join as join5 } from "path";
6422
+ function isSqliteBackend() {
6423
+ if (cachedResult === true)
6424
+ return true;
6425
+ if (cachedResult === false)
6426
+ return false;
6427
+ const check = () => {
6428
+ const versionOk = isOpenCodeVersionAtLeast(OPENCODE_SQLITE_VERSION);
6429
+ const dbPath = join5(getDataDir(), "opencode", "opencode.db");
6430
+ return versionOk && existsSync3(dbPath);
6431
+ };
6432
+ if (cachedResult === FALSE_PENDING_RETRY) {
6433
+ const result2 = check();
6434
+ cachedResult = result2;
6435
+ return result2;
6436
+ }
6437
+ const result = check();
6438
+ if (result) {
6439
+ cachedResult = true;
6440
+ } else {
6441
+ cachedResult = FALSE_PENDING_RETRY;
6442
+ }
6443
+ return result;
6444
+ }
6445
+ var NOT_CACHED2, FALSE_PENDING_RETRY, cachedResult;
6377
6446
  var init_opencode_storage_detection = __esm(() => {
6378
6447
  init_data_path();
6379
6448
  init_opencode_version();
6380
6449
  NOT_CACHED2 = Symbol("NOT_CACHED");
6381
6450
  FALSE_PENDING_RETRY = Symbol("FALSE_PENDING_RETRY");
6451
+ cachedResult = NOT_CACHED2;
6382
6452
  });
6383
6453
  // src/shared/load-opencode-plugins.ts
6384
6454
  var init_load_opencode_plugins = __esm(() => {
@@ -6793,19 +6863,19 @@ function normalizeModelID(modelID) {
6793
6863
  }
6794
6864
 
6795
6865
  // src/shared/json-file-cache-store.ts
6796
- import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
6797
- import { join as join5 } from "path";
6866
+ import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
6867
+ import { join as join6 } from "path";
6798
6868
  function toLogLabel(cacheLabel) {
6799
6869
  return cacheLabel.toLowerCase();
6800
6870
  }
6801
6871
  function createJsonFileCacheStore(options) {
6802
6872
  let memoryValue;
6803
6873
  function getCacheFilePath() {
6804
- return join5(options.getCacheDir(), options.filename);
6874
+ return join6(options.getCacheDir(), options.filename);
6805
6875
  }
6806
6876
  function ensureCacheDir() {
6807
6877
  const cacheDir = options.getCacheDir();
6808
- if (!existsSync3(cacheDir)) {
6878
+ if (!existsSync4(cacheDir)) {
6809
6879
  mkdirSync2(cacheDir, { recursive: true });
6810
6880
  }
6811
6881
  }
@@ -6814,7 +6884,7 @@ function createJsonFileCacheStore(options) {
6814
6884
  return memoryValue;
6815
6885
  }
6816
6886
  const cacheFile = getCacheFilePath();
6817
- if (!existsSync3(cacheFile)) {
6887
+ if (!existsSync4(cacheFile)) {
6818
6888
  memoryValue = null;
6819
6889
  log(`[${options.logPrefix}] ${options.cacheLabel} file not found`, { cacheFile });
6820
6890
  return null;
@@ -6834,7 +6904,7 @@ function createJsonFileCacheStore(options) {
6834
6904
  }
6835
6905
  }
6836
6906
  function has() {
6837
- return existsSync3(getCacheFilePath());
6907
+ return existsSync4(getCacheFilePath());
6838
6908
  }
6839
6909
  function write(value) {
6840
6910
  ensureCacheDir();
@@ -7003,14 +7073,14 @@ var init_connected_providers_cache = __esm(() => {
7003
7073
  });
7004
7074
 
7005
7075
  // src/shared/model-availability.ts
7006
- import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
7007
- import { join as join6 } from "path";
7076
+ import { existsSync as existsSync5, readFileSync as readFileSync3 } from "fs";
7077
+ import { join as join7 } from "path";
7008
7078
  function isModelCacheAvailable() {
7009
7079
  if (hasProviderModelsCache()) {
7010
7080
  return true;
7011
7081
  }
7012
- const cacheFile = join6(getOpenCodeCacheDir(), "models.json");
7013
- return existsSync4(cacheFile);
7082
+ const cacheFile = join7(getOpenCodeCacheDir(), "models.json");
7083
+ return existsSync5(cacheFile);
7014
7084
  }
7015
7085
  var init_model_availability = __esm(() => {
7016
7086
  init_logger();
@@ -48323,17 +48393,43 @@ var init_hook_message_injector = __esm(() => {
48323
48393
  });
48324
48394
 
48325
48395
  // src/shared/opencode-storage-paths.ts
48326
- import { join as join7 } from "path";
48396
+ import { join as join8 } from "path";
48327
48397
  var OPENCODE_STORAGE, MESSAGE_STORAGE, PART_STORAGE, SESSION_STORAGE;
48328
48398
  var init_opencode_storage_paths = __esm(() => {
48329
48399
  init_data_path();
48330
48400
  OPENCODE_STORAGE = getOpenCodeStorageDir();
48331
- MESSAGE_STORAGE = join7(OPENCODE_STORAGE, "message");
48332
- PART_STORAGE = join7(OPENCODE_STORAGE, "part");
48333
- SESSION_STORAGE = join7(OPENCODE_STORAGE, "session");
48401
+ MESSAGE_STORAGE = join8(OPENCODE_STORAGE, "message");
48402
+ PART_STORAGE = join8(OPENCODE_STORAGE, "part");
48403
+ SESSION_STORAGE = join8(OPENCODE_STORAGE, "session");
48334
48404
  });
48335
48405
 
48336
48406
  // src/shared/opencode-message-dir.ts
48407
+ import { existsSync as existsSync6, readdirSync } from "fs";
48408
+ import { join as join9 } from "path";
48409
+ function getMessageDir(sessionID) {
48410
+ if (!sessionID.startsWith("ses_"))
48411
+ return null;
48412
+ if (/[/\\]|\.\./.test(sessionID))
48413
+ return null;
48414
+ if (!existsSync6(MESSAGE_STORAGE))
48415
+ return null;
48416
+ const directPath = join9(MESSAGE_STORAGE, sessionID);
48417
+ if (existsSync6(directPath)) {
48418
+ return directPath;
48419
+ }
48420
+ try {
48421
+ for (const dir of readdirSync(MESSAGE_STORAGE)) {
48422
+ const sessionPath = join9(MESSAGE_STORAGE, dir, sessionID);
48423
+ if (existsSync6(sessionPath)) {
48424
+ return sessionPath;
48425
+ }
48426
+ }
48427
+ } catch (error) {
48428
+ log("[opencode-message-dir] Failed to scan message directories", { sessionID, error: String(error) });
48429
+ return null;
48430
+ }
48431
+ return null;
48432
+ }
48337
48433
  var init_opencode_message_dir = __esm(() => {
48338
48434
  init_opencode_storage_paths();
48339
48435
  init_logger();
@@ -48620,6 +48716,7 @@ var init_hook_loader = __esm(() => {
48620
48716
  });
48621
48717
 
48622
48718
  // src/features/claude-code-plugin-loader/loader.ts
48719
+ var cachedPluginComponentsByKey;
48623
48720
  var init_loader = __esm(() => {
48624
48721
  init_logger();
48625
48722
  init_discovery();
@@ -48634,6 +48731,7 @@ var init_loader = __esm(() => {
48634
48731
  init_agent_loader();
48635
48732
  init_mcp_server_loader();
48636
48733
  init_hook_loader();
48734
+ cachedPluginComponentsByKey = new Map;
48637
48735
  });
48638
48736
 
48639
48737
  // src/features/claude-code-plugin-loader/index.ts
@@ -48764,6 +48862,10 @@ function getConfigJsonc() {
48764
48862
  return getConfigContext().paths.configJsonc;
48765
48863
  }
48766
48864
  function getOmoConfigPath() {
48865
+ const configDir = getConfigContext().paths.configDir;
48866
+ const detected = detectPluginConfigFile(configDir);
48867
+ if (detected.format !== "none")
48868
+ return detected.path;
48767
48869
  return getConfigContext().paths.omoConfig;
48768
48870
  }
48769
48871
  var configContext = null;
@@ -48815,10 +48917,10 @@ var init_plugin_name_with_version = __esm(() => {
48815
48917
  });
48816
48918
 
48817
48919
  // src/cli/config-manager/ensure-config-directory-exists.ts
48818
- import { existsSync as existsSync5, mkdirSync as mkdirSync3 } from "fs";
48920
+ import { existsSync as existsSync7, mkdirSync as mkdirSync3 } from "fs";
48819
48921
  function ensureConfigDirectoryExists() {
48820
48922
  const configDir = getConfigDir();
48821
- if (!existsSync5(configDir)) {
48923
+ if (!existsSync7(configDir)) {
48822
48924
  mkdirSync3(configDir, { recursive: true });
48823
48925
  }
48824
48926
  }
@@ -48856,14 +48958,14 @@ function formatErrorWithSuggestion(err, context) {
48856
48958
  }
48857
48959
 
48858
48960
  // src/cli/config-manager/opencode-config-format.ts
48859
- import { existsSync as existsSync6 } from "fs";
48961
+ import { existsSync as existsSync8 } from "fs";
48860
48962
  function detectConfigFormat() {
48861
48963
  const configJsonc = getConfigJsonc();
48862
48964
  const configJson = getConfigJson();
48863
- if (existsSync6(configJsonc)) {
48965
+ if (existsSync8(configJsonc)) {
48864
48966
  return { format: "jsonc", path: configJsonc };
48865
48967
  }
48866
- if (existsSync6(configJson)) {
48968
+ if (existsSync8(configJson)) {
48867
48969
  return { format: "json", path: configJson };
48868
48970
  }
48869
48971
  return { format: "none", path: configJson };
@@ -49214,7 +49316,7 @@ function deepMergeRecord(target, source) {
49214
49316
  }
49215
49317
 
49216
49318
  // src/cli/config-manager/write-omo-config.ts
49217
- import { existsSync as existsSync7, readFileSync as readFileSync6, statSync as statSync2, writeFileSync as writeFileSync4 } from "fs";
49319
+ import { existsSync as existsSync9, readFileSync as readFileSync6, statSync as statSync2, writeFileSync as writeFileSync4 } from "fs";
49218
49320
  function isEmptyOrWhitespace2(content) {
49219
49321
  return content.trim().length === 0;
49220
49322
  }
@@ -49231,7 +49333,7 @@ function writeOmoConfig(installConfig) {
49231
49333
  const omoConfigPath = getOmoConfigPath();
49232
49334
  try {
49233
49335
  const newConfig = generateOmoConfig(installConfig);
49234
- if (existsSync7(omoConfigPath)) {
49336
+ if (existsSync9(omoConfigPath)) {
49235
49337
  try {
49236
49338
  const stat = statSync2(omoConfigPath);
49237
49339
  const content = readFileSync6(omoConfigPath, "utf-8");
@@ -49362,7 +49464,7 @@ async function isOpenCodeInstalled() {
49362
49464
  const result = await findOpenCodeBinaryWithVersion();
49363
49465
  return result !== null;
49364
49466
  }
49365
- async function getOpenCodeVersion() {
49467
+ async function getOpenCodeVersion2() {
49366
49468
  const result = await findOpenCodeBinaryWithVersion();
49367
49469
  return result?.version ?? null;
49368
49470
  }
@@ -49374,10 +49476,10 @@ var init_opencode_binary = __esm(() => {
49374
49476
  });
49375
49477
 
49376
49478
  // src/cli/config-manager/detect-current-config.ts
49377
- import { existsSync as existsSync8, readFileSync as readFileSync7 } from "fs";
49479
+ import { existsSync as existsSync10, readFileSync as readFileSync7 } from "fs";
49378
49480
  function detectProvidersFromOmoConfig() {
49379
49481
  const omoConfigPath = getOmoConfigPath();
49380
- if (!existsSync8(omoConfigPath)) {
49482
+ if (!existsSync10(omoConfigPath)) {
49381
49483
  return {
49382
49484
  hasOpenAI: true,
49383
49485
  hasOpencodeZen: true,
@@ -49463,10 +49565,10 @@ var init_detect_current_config = __esm(() => {
49463
49565
  });
49464
49566
 
49465
49567
  // src/cli/config-manager/bun-install.ts
49466
- import { existsSync as existsSync9 } from "fs";
49467
- import { join as join8 } from "path";
49568
+ import { existsSync as existsSync11 } from "fs";
49569
+ import { join as join10 } from "path";
49468
49570
  function getDefaultWorkspaceDir() {
49469
- return join8(getOpenCodeCacheDir(), "packages");
49571
+ return join10(getOpenCodeCacheDir(), "packages");
49470
49572
  }
49471
49573
  function readProcessOutput(stream) {
49472
49574
  if (!stream) {
@@ -49492,7 +49594,7 @@ async function runBunInstallWithDetails(options) {
49492
49594
  const outputMode = options?.outputMode ?? "pipe";
49493
49595
  const cacheDir = options?.workspaceDir ?? getDefaultWorkspaceDir();
49494
49596
  const packageJsonPath = `${cacheDir}/package.json`;
49495
- if (!existsSync9(packageJsonPath)) {
49597
+ if (!existsSync11(packageJsonPath)) {
49496
49598
  return {
49497
49599
  success: false,
49498
49600
  error: `Workspace not initialized: ${packageJsonPath} not found. OpenCode should create this on first run.`
@@ -49636,7 +49738,16 @@ function getWindowsAppdataDir() {
49636
49738
  return null;
49637
49739
  return process.env.APPDATA ?? path4.join(os3.homedir(), "AppData", "Roaming");
49638
49740
  }
49639
- var PACKAGE_NAME = "oh-my-openagent", NPM_REGISTRY_URL, NPM_FETCH_TIMEOUT = 5000, CACHE_ROOT_DIR, CACHE_DIR, VERSION_FILE, USER_CONFIG_DIR, USER_OPENCODE_CONFIG, USER_OPENCODE_CONFIG_JSONC, INSTALLED_PACKAGE_JSON;
49741
+ function getUserConfigDir() {
49742
+ return getOpenCodeConfigDir({ binary: "opencode" });
49743
+ }
49744
+ function getUserOpencodeConfig() {
49745
+ return path4.join(getUserConfigDir(), "opencode.json");
49746
+ }
49747
+ function getUserOpencodeConfigJsonc() {
49748
+ return path4.join(getUserConfigDir(), "opencode.jsonc");
49749
+ }
49750
+ var PACKAGE_NAME = "oh-my-openagent", NPM_REGISTRY_URL, NPM_FETCH_TIMEOUT = 5000, CACHE_ROOT_DIR, CACHE_DIR, VERSION_FILE, INSTALLED_PACKAGE_JSON;
49640
49751
  var init_constants3 = __esm(() => {
49641
49752
  init_data_path();
49642
49753
  init_opencode_config_dir();
@@ -49644,9 +49755,6 @@ var init_constants3 = __esm(() => {
49644
49755
  CACHE_ROOT_DIR = getOpenCodeCacheDir();
49645
49756
  CACHE_DIR = path4.join(CACHE_ROOT_DIR, "packages");
49646
49757
  VERSION_FILE = path4.join(CACHE_ROOT_DIR, "version");
49647
- USER_CONFIG_DIR = getOpenCodeConfigDir({ binary: "opencode" });
49648
- USER_OPENCODE_CONFIG = path4.join(USER_CONFIG_DIR, "opencode.json");
49649
- USER_OPENCODE_CONFIG_JSONC = path4.join(USER_CONFIG_DIR, "opencode.jsonc");
49650
49758
  INSTALLED_PACKAGE_JSON = path4.join(CACHE_DIR, "node_modules", PACKAGE_NAME, "package.json");
49651
49759
  });
49652
49760
 
@@ -49654,17 +49762,18 @@ var init_constants3 = __esm(() => {
49654
49762
  import * as os4 from "os";
49655
49763
  import * as path5 from "path";
49656
49764
  function getConfigPaths(directory) {
49765
+ const userConfigDir = getUserConfigDir();
49657
49766
  const paths = [
49658
49767
  path5.join(directory, ".opencode", "opencode.json"),
49659
49768
  path5.join(directory, ".opencode", "opencode.jsonc"),
49660
- USER_OPENCODE_CONFIG,
49661
- USER_OPENCODE_CONFIG_JSONC
49769
+ getUserOpencodeConfig(),
49770
+ getUserOpencodeConfigJsonc()
49662
49771
  ];
49663
49772
  if (process.platform === "win32") {
49664
49773
  const crossPlatformDir = path5.join(os4.homedir(), ".config");
49665
49774
  const appdataDir = getWindowsAppdataDir();
49666
49775
  if (appdataDir) {
49667
- const alternateDir = USER_CONFIG_DIR === crossPlatformDir ? appdataDir : crossPlatformDir;
49776
+ const alternateDir = userConfigDir === crossPlatformDir ? appdataDir : crossPlatformDir;
49668
49777
  const alternateConfig = path5.join(alternateDir, "opencode", "opencode.json");
49669
49778
  const alternateConfigJsonc = path5.join(alternateDir, "opencode", "opencode.jsonc");
49670
49779
  if (!paths.includes(alternateConfig)) {
@@ -50121,8 +50230,9 @@ function removeFromBunLock(packageName) {
50121
50230
  }
50122
50231
  function invalidatePackage(packageName = PACKAGE_NAME) {
50123
50232
  try {
50233
+ const userConfigDir = getUserConfigDir();
50124
50234
  const pkgDirs = [
50125
- path9.join(USER_CONFIG_DIR, "node_modules", packageName),
50235
+ path9.join(userConfigDir, "node_modules", packageName),
50126
50236
  path9.join(CACHE_DIR, "node_modules", packageName)
50127
50237
  ];
50128
50238
  let packageRemoved = false;
@@ -50183,8 +50293,8 @@ var init_update_toasts = __esm(() => {
50183
50293
  });
50184
50294
 
50185
50295
  // src/hooks/auto-update-checker/hook/background-update-check.ts
50186
- import { existsSync as existsSync21 } from "fs";
50187
- import { join as join20 } from "path";
50296
+ import { existsSync as existsSync23 } from "fs";
50297
+ import { join as join23 } from "path";
50188
50298
  function getCacheWorkspaceDir(deps) {
50189
50299
  return deps.join(deps.getOpenCodeCacheDir(), "packages");
50190
50300
  }
@@ -50241,8 +50351,8 @@ function createBackgroundUpdateCheckRunner(overrides = {}) {
50241
50351
  deps.log("[auto-update-checker] Plugin not found in config");
50242
50352
  return;
50243
50353
  }
50244
- const cachedVersion = deps.getCachedVersion();
50245
- const currentVersion = cachedVersion ?? pluginInfo.pinnedVersion;
50354
+ const cachedVersion2 = deps.getCachedVersion();
50355
+ const currentVersion = cachedVersion2 ?? pluginInfo.pinnedVersion;
50246
50356
  if (!currentVersion) {
50247
50357
  deps.log("[auto-update-checker] No version found (cached or pinned)");
50248
50358
  return;
@@ -50302,8 +50412,8 @@ var init_background_update_check = __esm(() => {
50302
50412
  init_checker();
50303
50413
  init_update_toasts();
50304
50414
  defaultDeps = {
50305
- existsSync: existsSync21,
50306
- join: join20,
50415
+ existsSync: existsSync23,
50416
+ join: join23,
50307
50417
  runBunInstallWithDetails,
50308
50418
  log,
50309
50419
  getOpenCodeCacheDir,
@@ -50512,9 +50622,9 @@ v${latestVersion} available. Restart OpenCode to apply.` : "OpenCode is now on S
50512
50622
  return;
50513
50623
  hasChecked = true;
50514
50624
  setTimeout(async () => {
50515
- const cachedVersion = getCachedVersion();
50625
+ const cachedVersion2 = getCachedVersion();
50516
50626
  const localDevVersion = getLocalDevVersion(ctx.directory);
50517
- const displayVersion = localDevVersion ?? cachedVersion;
50627
+ const displayVersion = localDevVersion ?? cachedVersion2;
50518
50628
  await showConfigErrorsIfAny(ctx);
50519
50629
  await updateAndShowConnectedProvidersCacheStatus(ctx);
50520
50630
  await refreshModelCapabilitiesOnStartup(modelCapabilities);
@@ -50583,7 +50693,7 @@ var {
50583
50693
  // package.json
50584
50694
  var package_default = {
50585
50695
  name: "oh-my-opencode",
50586
- version: "3.15.1",
50696
+ version: "3.15.3",
50587
50697
  description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
50588
50698
  main: "./dist/index.js",
50589
50699
  types: "dist/index.d.ts",
@@ -50661,17 +50771,17 @@ var package_default = {
50661
50771
  typescript: "^5.7.3"
50662
50772
  },
50663
50773
  optionalDependencies: {
50664
- "oh-my-opencode-darwin-arm64": "3.15.1",
50665
- "oh-my-opencode-darwin-x64": "3.15.1",
50666
- "oh-my-opencode-darwin-x64-baseline": "3.15.1",
50667
- "oh-my-opencode-linux-arm64": "3.15.1",
50668
- "oh-my-opencode-linux-arm64-musl": "3.15.1",
50669
- "oh-my-opencode-linux-x64": "3.15.1",
50670
- "oh-my-opencode-linux-x64-baseline": "3.15.1",
50671
- "oh-my-opencode-linux-x64-musl": "3.15.1",
50672
- "oh-my-opencode-linux-x64-musl-baseline": "3.15.1",
50673
- "oh-my-opencode-windows-x64": "3.15.1",
50674
- "oh-my-opencode-windows-x64-baseline": "3.15.1"
50774
+ "oh-my-opencode-darwin-arm64": "3.15.3",
50775
+ "oh-my-opencode-darwin-x64": "3.15.3",
50776
+ "oh-my-opencode-darwin-x64-baseline": "3.15.3",
50777
+ "oh-my-opencode-linux-arm64": "3.15.3",
50778
+ "oh-my-opencode-linux-arm64-musl": "3.15.3",
50779
+ "oh-my-opencode-linux-x64": "3.15.3",
50780
+ "oh-my-opencode-linux-x64-baseline": "3.15.3",
50781
+ "oh-my-opencode-linux-x64-musl": "3.15.3",
50782
+ "oh-my-opencode-linux-x64-musl-baseline": "3.15.3",
50783
+ "oh-my-opencode-windows-x64": "3.15.3",
50784
+ "oh-my-opencode-windows-x64-baseline": "3.15.3"
50675
50785
  },
50676
50786
  overrides: {
50677
50787
  "@opencode-ai/sdk": "^1.2.24"
@@ -50854,7 +50964,7 @@ async function runCliInstaller(args, version) {
50854
50964
  let step = 1;
50855
50965
  printStep(step++, totalSteps, "Checking OpenCode installation...");
50856
50966
  const installed = await isOpenCodeInstalled();
50857
- const openCodeVersion = await getOpenCodeVersion();
50967
+ const openCodeVersion = await getOpenCodeVersion2();
50858
50968
  if (!installed) {
50859
50969
  printWarning("OpenCode binary not found. Plugin will be configured, but you'll need to install OpenCode to use it.");
50860
50970
  printInfo("Visit https://opencode.ai/docs for installation instructions");
@@ -51629,7 +51739,7 @@ async function runTuiInstaller(args, version) {
51629
51739
  const spinner = Y2();
51630
51740
  spinner.start("Checking OpenCode installation");
51631
51741
  const installed = await isOpenCodeInstalled();
51632
- const openCodeVersion = await getOpenCodeVersion();
51742
+ const openCodeVersion = await getOpenCodeVersion2();
51633
51743
  if (!installed) {
51634
51744
  spinner.stop(`OpenCode binary not found ${import_picocolors4.default.yellow("[!]")}`);
51635
51745
  M2.warn("OpenCode binary not found. Plugin will be configured, but you'll need to install OpenCode to use it.");
@@ -66474,12 +66584,12 @@ init_shared();
66474
66584
  // src/shared/migrate-legacy-config-file.ts
66475
66585
  init_logger();
66476
66586
  init_write_file_atomically();
66477
- import { existsSync as existsSync10, readFileSync as readFileSync8, renameSync as renameSync2, rmSync } from "fs";
66478
- import { join as join9, dirname, basename } from "path";
66587
+ import { existsSync as existsSync12, readFileSync as readFileSync8, renameSync as renameSync2, rmSync } from "fs";
66588
+ import { join as join11, dirname, basename } from "path";
66479
66589
  function buildCanonicalPath(legacyPath) {
66480
66590
  const dir = dirname(legacyPath);
66481
66591
  const ext = basename(legacyPath).includes(".jsonc") ? ".jsonc" : ".json";
66482
- return join9(dir, `${CONFIG_BASENAME}${ext}`);
66592
+ return join11(dir, `${CONFIG_BASENAME}${ext}`);
66483
66593
  }
66484
66594
  function archiveLegacyConfigFile(legacyPath) {
66485
66595
  const backupPath = `${legacyPath}.bak`;
@@ -66511,12 +66621,12 @@ function archiveLegacyConfigFile(legacyPath) {
66511
66621
  }
66512
66622
  }
66513
66623
  function migrateLegacyConfigFile(legacyPath) {
66514
- if (!existsSync10(legacyPath))
66624
+ if (!existsSync12(legacyPath))
66515
66625
  return false;
66516
66626
  if (!basename(legacyPath).startsWith(LEGACY_CONFIG_BASENAME))
66517
66627
  return false;
66518
66628
  const canonicalPath = buildCanonicalPath(legacyPath);
66519
- if (existsSync10(canonicalPath))
66629
+ if (existsSync12(canonicalPath))
66520
66630
  return false;
66521
66631
  try {
66522
66632
  const content = readFileSync8(legacyPath, "utf-8");
@@ -66662,7 +66772,7 @@ function mergeConfigs(base, override) {
66662
66772
  function loadPluginConfig(directory, ctx) {
66663
66773
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
66664
66774
  const userDetected = detectPluginConfigFile(configDir);
66665
- let userConfigPath = userDetected.format !== "none" ? userDetected.path : path3.join(configDir, "oh-my-opencode.json");
66775
+ let userConfigPath = userDetected.format !== "none" ? userDetected.path : path3.join(configDir, `${CONFIG_BASENAME}.json`);
66666
66776
  if (userDetected.legacyPath) {
66667
66777
  log("Canonical plugin config detected alongside legacy config. Remove the legacy file to avoid confusion.", {
66668
66778
  canonicalPath: userDetected.path,
@@ -66670,12 +66780,15 @@ function loadPluginConfig(directory, ctx) {
66670
66780
  });
66671
66781
  }
66672
66782
  if (userDetected.format !== "none" && path3.basename(userDetected.path).startsWith(LEGACY_CONFIG_BASENAME)) {
66673
- migrateLegacyConfigFile(userDetected.path);
66674
- userConfigPath = path3.join(path3.dirname(userDetected.path), `${CONFIG_BASENAME}${path3.extname(userDetected.path)}`);
66783
+ const migrated = migrateLegacyConfigFile(userDetected.path);
66784
+ const canonicalPath = path3.join(path3.dirname(userDetected.path), `${CONFIG_BASENAME}${path3.extname(userDetected.path)}`);
66785
+ if (migrated || fs3.existsSync(canonicalPath)) {
66786
+ userConfigPath = canonicalPath;
66787
+ }
66675
66788
  }
66676
66789
  const projectBasePath = path3.join(directory, ".opencode");
66677
66790
  const projectDetected = detectPluginConfigFile(projectBasePath);
66678
- let projectConfigPath = projectDetected.format !== "none" ? projectDetected.path : path3.join(projectBasePath, "oh-my-opencode.json");
66791
+ let projectConfigPath = projectDetected.format !== "none" ? projectDetected.path : path3.join(projectBasePath, `${CONFIG_BASENAME}.json`);
66679
66792
  if (projectDetected.legacyPath) {
66680
66793
  log("Canonical plugin config detected alongside legacy config. Remove the legacy file to avoid confusion.", {
66681
66794
  canonicalPath: projectDetected.path,
@@ -66683,8 +66796,11 @@ function loadPluginConfig(directory, ctx) {
66683
66796
  });
66684
66797
  }
66685
66798
  if (projectDetected.format !== "none" && path3.basename(projectDetected.path).startsWith(LEGACY_CONFIG_BASENAME)) {
66686
- migrateLegacyConfigFile(projectDetected.path);
66687
- projectConfigPath = path3.join(path3.dirname(projectDetected.path), `${CONFIG_BASENAME}${path3.extname(projectDetected.path)}`);
66799
+ const projectMigrated = migrateLegacyConfigFile(projectDetected.path);
66800
+ const canonicalProjectPath = path3.join(path3.dirname(projectDetected.path), `${CONFIG_BASENAME}${path3.extname(projectDetected.path)}`);
66801
+ if (projectMigrated || fs3.existsSync(canonicalProjectPath)) {
66802
+ projectConfigPath = canonicalProjectPath;
66803
+ }
66688
66804
  }
66689
66805
  const userConfig = loadConfigFromPath(userConfigPath, ctx);
66690
66806
  let config2 = userConfig ?? OhMyOpenCodeConfigSchema.parse({});
@@ -68153,7 +68269,7 @@ var import_picocolors9 = __toESM(require_picocolors(), 1);
68153
68269
 
68154
68270
  // src/cli/run/opencode-binary-resolver.ts
68155
68271
  init_spawn_with_windows_hide();
68156
- import { delimiter, dirname as dirname3, join as join11 } from "path";
68272
+ import { delimiter, dirname as dirname3, join as join13 } from "path";
68157
68273
  var OPENCODE_COMMANDS = ["opencode", "opencode-desktop"];
68158
68274
  var WINDOWS_SUFFIXES = ["", ".exe", ".cmd", ".bat", ".ps1"];
68159
68275
  function getCommandCandidates(platform) {
@@ -68176,7 +68292,7 @@ function collectCandidateBinaryPaths(pathEnv, which = Bun.which, platform = proc
68176
68292
  }
68177
68293
  for (const entry of (pathEnv ?? "").split(delimiter).filter(Boolean)) {
68178
68294
  for (const command of commandCandidates) {
68179
- addCandidate(join11(entry, command));
68295
+ addCandidate(join13(entry, command));
68180
68296
  }
68181
68297
  }
68182
68298
  return candidates;
@@ -68559,15 +68675,15 @@ var BOULDER_STATE_PATH = `${BOULDER_DIR}/${BOULDER_FILE}`;
68559
68675
  var NOTEPAD_DIR = "notepads";
68560
68676
  var NOTEPAD_BASE_PATH = `${BOULDER_DIR}/${NOTEPAD_DIR}`;
68561
68677
  // src/features/boulder-state/storage.ts
68562
- import { existsSync as existsSync12, readFileSync as readFileSync10, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, readdirSync } from "fs";
68563
- import { dirname as dirname4, join as join12, basename as basename3 } from "path";
68678
+ import { existsSync as existsSync14, readFileSync as readFileSync10, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, readdirSync as readdirSync2 } from "fs";
68679
+ import { dirname as dirname4, join as join14, basename as basename3 } from "path";
68564
68680
  var RESERVED_KEYS = new Set(["__proto__", "prototype", "constructor"]);
68565
68681
  function getBoulderFilePath(directory) {
68566
- return join12(directory, BOULDER_DIR, BOULDER_FILE);
68682
+ return join14(directory, BOULDER_DIR, BOULDER_FILE);
68567
68683
  }
68568
68684
  function readBoulderState(directory) {
68569
68685
  const filePath = getBoulderFilePath(directory);
68570
- if (!existsSync12(filePath)) {
68686
+ if (!existsSync14(filePath)) {
68571
68687
  return null;
68572
68688
  }
68573
68689
  try {
@@ -68579,6 +68695,15 @@ function readBoulderState(directory) {
68579
68695
  if (!Array.isArray(parsed.session_ids)) {
68580
68696
  parsed.session_ids = [];
68581
68697
  }
68698
+ if (!parsed.session_origins || typeof parsed.session_origins !== "object" || Array.isArray(parsed.session_origins)) {
68699
+ parsed.session_origins = {};
68700
+ }
68701
+ if (parsed.session_ids.length === 1) {
68702
+ const soleSessionId = parsed.session_ids[0];
68703
+ if (typeof soleSessionId === "string" && parsed.session_origins[soleSessionId] !== "appended" && parsed.session_origins[soleSessionId] !== "direct") {
68704
+ parsed.session_origins[soleSessionId] = "direct";
68705
+ }
68706
+ }
68582
68707
  if (!parsed.task_sessions || typeof parsed.task_sessions !== "object" || Array.isArray(parsed.task_sessions)) {
68583
68708
  parsed.task_sessions = {};
68584
68709
  }
@@ -68588,7 +68713,7 @@ function readBoulderState(directory) {
68588
68713
  }
68589
68714
  }
68590
68715
  function getPlanProgress(planPath) {
68591
- if (!existsSync12(planPath)) {
68716
+ if (!existsSync14(planPath)) {
68592
68717
  return { total: 0, completed: 0, isComplete: true };
68593
68718
  }
68594
68719
  try {
@@ -68606,17 +68731,26 @@ function getPlanProgress(planPath) {
68606
68731
  return { total: 0, completed: 0, isComplete: true };
68607
68732
  }
68608
68733
  }
68734
+ // src/features/claude-code-session-state/state.ts
68735
+ init_agent_display_names();
68736
+ var subagentSessions = new Set;
68737
+ var syncSubagentSessions = new Set;
68738
+ var registeredAgentNames = new Set;
68739
+ var sessionAgentMap = new Map;
68740
+ function getSessionAgent(sessionID) {
68741
+ return sessionAgentMap.get(sessionID);
68742
+ }
68609
68743
  // src/features/run-continuation-state/constants.ts
68610
68744
  var CONTINUATION_MARKER_DIR = ".sisyphus/run-continuation";
68611
68745
  // src/features/run-continuation-state/storage.ts
68612
- import { existsSync as existsSync13, mkdirSync as mkdirSync5, readFileSync as readFileSync11, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "fs";
68613
- import { join as join13 } from "path";
68746
+ import { existsSync as existsSync15, mkdirSync as mkdirSync5, readFileSync as readFileSync11, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "fs";
68747
+ import { join as join15 } from "path";
68614
68748
  function getMarkerPath(directory, sessionID) {
68615
- return join13(directory, CONTINUATION_MARKER_DIR, `${sessionID}.json`);
68749
+ return join15(directory, CONTINUATION_MARKER_DIR, `${sessionID}.json`);
68616
68750
  }
68617
68751
  function readContinuationMarker(directory, sessionID) {
68618
68752
  const markerPath = getMarkerPath(directory, sessionID);
68619
- if (!existsSync13(markerPath))
68753
+ if (!existsSync15(markerPath))
68620
68754
  return null;
68621
68755
  try {
68622
68756
  const raw = readFileSync11(markerPath, "utf-8");
@@ -68642,10 +68776,113 @@ function getActiveContinuationMarkerReason(marker) {
68642
68776
  const [source, entry] = active;
68643
68777
  return entry.reason ?? `${source} continuation is active`;
68644
68778
  }
68779
+ // src/hooks/atlas/boulder-session-lineage.ts
68780
+ init_logger();
68781
+
68782
+ // src/hooks/atlas/hook-name.ts
68783
+ var HOOK_NAME = "atlas";
68784
+
68785
+ // src/hooks/atlas/boulder-session-lineage.ts
68786
+ async function isSessionInBoulderLineage(input) {
68787
+ const visitedSessionIDs = new Set;
68788
+ let currentSessionID = input.sessionID;
68789
+ while (!visitedSessionIDs.has(currentSessionID)) {
68790
+ visitedSessionIDs.add(currentSessionID);
68791
+ const sessionResult = await input.client.session.get({ path: { id: currentSessionID } }).catch((error48) => {
68792
+ log(`[${HOOK_NAME}] Failed to resolve session lineage`, {
68793
+ sessionID: input.sessionID,
68794
+ currentSessionID,
68795
+ error: error48
68796
+ });
68797
+ return null;
68798
+ });
68799
+ if (!sessionResult || sessionResult.error) {
68800
+ return false;
68801
+ }
68802
+ const parentSessionID = sessionResult.data?.parentID;
68803
+ if (!parentSessionID) {
68804
+ return false;
68805
+ }
68806
+ if (input.boulderSessionIDs.includes(parentSessionID)) {
68807
+ return true;
68808
+ }
68809
+ currentSessionID = parentSessionID;
68810
+ }
68811
+ return false;
68812
+ }
68813
+
68814
+ // src/hooks/atlas/session-last-agent.ts
68815
+ init_shared();
68816
+ import { readFileSync as readFileSync12, readdirSync as readdirSync3 } from "fs";
68817
+ import { join as join16 } from "path";
68818
+ function isCompactionAgent(agent) {
68819
+ return typeof agent === "string" && agent.toLowerCase() === "compaction";
68820
+ }
68821
+ function getLastAgentFromMessageDir(messageDir) {
68822
+ try {
68823
+ const messages = readdirSync3(messageDir).filter((fileName) => fileName.endsWith(".json")).map((fileName) => {
68824
+ try {
68825
+ const content = readFileSync12(join16(messageDir, fileName), "utf-8");
68826
+ const parsed = JSON.parse(content);
68827
+ return {
68828
+ fileName,
68829
+ agent: parsed.agent,
68830
+ createdAt: typeof parsed.time?.created === "number" ? parsed.time.created : Number.NEGATIVE_INFINITY
68831
+ };
68832
+ } catch {
68833
+ return null;
68834
+ }
68835
+ }).filter((message) => message !== null).sort((left, right) => right.createdAt - left.createdAt || right.fileName.localeCompare(left.fileName));
68836
+ for (const message of messages) {
68837
+ if (typeof message.agent === "string" && !isCompactionAgent(message.agent)) {
68838
+ return message.agent.toLowerCase();
68839
+ }
68840
+ }
68841
+ } catch {
68842
+ return null;
68843
+ }
68844
+ return null;
68845
+ }
68846
+ async function getLastAgentFromSession(sessionID, client3) {
68847
+ if (isSqliteBackend() && client3) {
68848
+ try {
68849
+ const response = await client3.session.messages({ path: { id: sessionID } });
68850
+ const messages = normalizeSDKResponse(response, [], {
68851
+ preferResponseOnMissingData: true
68852
+ }).sort((left, right) => {
68853
+ const leftTime = left.info?.time?.created ?? Number.NEGATIVE_INFINITY;
68854
+ const rightTime = right.info?.time?.created ?? Number.NEGATIVE_INFINITY;
68855
+ if (leftTime !== rightTime) {
68856
+ return rightTime - leftTime;
68857
+ }
68858
+ const leftId = typeof left.id === "string" ? left.id : "";
68859
+ const rightId = typeof right.id === "string" ? right.id : "";
68860
+ return rightId.localeCompare(leftId);
68861
+ });
68862
+ for (const message of messages) {
68863
+ const agent = message.info?.agent;
68864
+ if (typeof agent === "string" && !isCompactionAgent(agent)) {
68865
+ return agent.toLowerCase();
68866
+ }
68867
+ }
68868
+ } catch {
68869
+ return null;
68870
+ }
68871
+ return null;
68872
+ }
68873
+ const messageDir = getMessageDir(sessionID);
68874
+ if (!messageDir)
68875
+ return null;
68876
+ return getLastAgentFromMessageDir(messageDir);
68877
+ }
68878
+
68879
+ // src/cli/run/continuation-state.ts
68880
+ init_agent_display_names();
68881
+
68645
68882
  // src/hooks/ralph-loop/storage.ts
68646
68883
  init_frontmatter();
68647
- import { existsSync as existsSync14, readFileSync as readFileSync12, writeFileSync as writeFileSync7, unlinkSync, mkdirSync as mkdirSync6 } from "fs";
68648
- import { dirname as dirname5, join as join14 } from "path";
68884
+ import { existsSync as existsSync16, readFileSync as readFileSync13, writeFileSync as writeFileSync7, unlinkSync, mkdirSync as mkdirSync6 } from "fs";
68885
+ import { dirname as dirname5, join as join17 } from "path";
68649
68886
 
68650
68887
  // src/hooks/ralph-loop/constants.ts
68651
68888
  var DEFAULT_STATE_FILE = ".sisyphus/ralph-loop.local.md";
@@ -68654,15 +68891,15 @@ var DEFAULT_COMPLETION_PROMISE = "DONE";
68654
68891
 
68655
68892
  // src/hooks/ralph-loop/storage.ts
68656
68893
  function getStateFilePath(directory, customPath) {
68657
- return customPath ? join14(directory, customPath) : join14(directory, DEFAULT_STATE_FILE);
68894
+ return customPath ? join17(directory, customPath) : join17(directory, DEFAULT_STATE_FILE);
68658
68895
  }
68659
68896
  function readState(directory, customPath) {
68660
68897
  const filePath = getStateFilePath(directory, customPath);
68661
- if (!existsSync14(filePath)) {
68898
+ if (!existsSync16(filePath)) {
68662
68899
  return null;
68663
68900
  }
68664
68901
  try {
68665
- const content = readFileSync12(filePath, "utf-8");
68902
+ const content = readFileSync13(filePath, "utf-8");
68666
68903
  const { data, body } = parseFrontmatter(content);
68667
68904
  const active = data.active;
68668
68905
  const iteration = data.iteration;
@@ -68702,10 +68939,10 @@ function readState(directory, customPath) {
68702
68939
  }
68703
68940
 
68704
68941
  // src/cli/run/continuation-state.ts
68705
- function getContinuationState(directory, sessionID) {
68942
+ async function getContinuationState(directory, sessionID, client3) {
68706
68943
  const marker = readContinuationMarker(directory, sessionID);
68707
68944
  return {
68708
- hasActiveBoulder: hasActiveBoulderContinuation(directory, sessionID),
68945
+ hasActiveBoulder: await hasActiveBoulderContinuation(directory, sessionID, client3),
68709
68946
  hasActiveRalphLoop: hasActiveRalphLoopContinuation(directory, sessionID),
68710
68947
  hasHookMarker: marker !== null,
68711
68948
  hasTodoHookMarker: marker?.sources.todo !== undefined,
@@ -68713,20 +68950,54 @@ function getContinuationState(directory, sessionID) {
68713
68950
  activeHookMarkerReason: getActiveContinuationMarkerReason(marker)
68714
68951
  };
68715
68952
  }
68716
- function hasActiveBoulderContinuation(directory, sessionID) {
68953
+ async function hasActiveBoulderContinuation(directory, sessionID, client3) {
68717
68954
  const boulder = readBoulderState(directory);
68718
68955
  if (!boulder)
68719
68956
  return false;
68720
- if (!boulder.session_ids.includes(sessionID))
68721
- return false;
68722
68957
  const progress = getPlanProgress(boulder.active_plan);
68723
- return !progress.isComplete;
68958
+ if (progress.isComplete)
68959
+ return false;
68960
+ if (!client3)
68961
+ return false;
68962
+ const isTrackedSession = boulder.session_ids.includes(sessionID);
68963
+ const sessionOrigin = boulder.session_origins?.[sessionID];
68964
+ if (!isTrackedSession) {
68965
+ return false;
68966
+ }
68967
+ const isTrackedDescendant = await isTrackedDescendantSession(client3, sessionID, boulder.session_ids);
68968
+ if (isTrackedSession && sessionOrigin === "direct") {
68969
+ return true;
68970
+ }
68971
+ if (isTrackedSession && sessionOrigin !== "direct" && !isTrackedDescendant) {
68972
+ return false;
68973
+ }
68974
+ const sessionAgent = await getLastAgentFromSession(sessionID, client3) ?? getSessionAgent(sessionID);
68975
+ if (!sessionAgent) {
68976
+ return false;
68977
+ }
68978
+ const requiredAgentKey = getAgentConfigKey(boulder.agent ?? "atlas");
68979
+ const sessionAgentKey = getAgentConfigKey(sessionAgent);
68980
+ if (sessionAgentKey !== requiredAgentKey && !(requiredAgentKey === getAgentConfigKey("atlas") && sessionAgentKey === getAgentConfigKey("sisyphus"))) {
68981
+ return false;
68982
+ }
68983
+ return isTrackedSession || isTrackedDescendant;
68984
+ }
68985
+ async function isTrackedDescendantSession(client3, sessionID, trackedSessionIDs) {
68986
+ const ancestorSessionIDs = trackedSessionIDs.filter((trackedSessionID) => trackedSessionID !== sessionID);
68987
+ if (ancestorSessionIDs.length === 0) {
68988
+ return false;
68989
+ }
68990
+ return isSessionInBoulderLineage({
68991
+ client: client3,
68992
+ sessionID,
68993
+ boulderSessionIDs: ancestorSessionIDs
68994
+ });
68724
68995
  }
68725
68996
  function hasActiveRalphLoopContinuation(directory, sessionID) {
68726
- const state = readState(directory);
68727
- if (!state || !state.active)
68997
+ const state2 = readState(directory);
68998
+ if (!state2 || !state2.active)
68728
68999
  return false;
68729
- if (state.session_id && state.session_id !== sessionID) {
69000
+ if (state2.session_id && state2.session_id !== sessionID) {
68730
69001
  return false;
68731
69002
  }
68732
69003
  return true;
@@ -68735,7 +69006,7 @@ function hasActiveRalphLoopContinuation(directory, sessionID) {
68735
69006
  // src/cli/run/completion.ts
68736
69007
  async function checkCompletionConditions(ctx) {
68737
69008
  try {
68738
- const continuationState = getContinuationState(ctx.directory, ctx.sessionID);
69009
+ const continuationState = await getContinuationState(ctx.directory, ctx.sessionID, ctx.client);
68739
69010
  if (continuationState.hasActiveHookMarker) {
68740
69011
  const reason = continuationState.activeHookMarkerReason ?? "continuation hook is active";
68741
69012
  logWaiting(ctx, reason);
@@ -69368,30 +69639,30 @@ var PACKAGE_NAME2 = PLUGIN_NAME;
69368
69639
  var OPENCODE_BINARIES2 = ["opencode", "opencode-desktop"];
69369
69640
 
69370
69641
  // src/cli/doctor/checks/system.ts
69371
- import { existsSync as existsSync25, readFileSync as readFileSync22 } from "fs";
69642
+ import { existsSync as existsSync27, readFileSync as readFileSync23 } from "fs";
69372
69643
 
69373
69644
  // src/cli/doctor/checks/system-binary.ts
69374
69645
  init_spawn_with_windows_hide();
69375
- import { existsSync as existsSync22 } from "fs";
69646
+ import { existsSync as existsSync24 } from "fs";
69376
69647
  import { homedir as homedir5 } from "os";
69377
- import { join as join21 } from "path";
69648
+ import { join as join24 } from "path";
69378
69649
  function getDesktopAppPaths(platform) {
69379
69650
  const home = homedir5();
69380
69651
  switch (platform) {
69381
69652
  case "darwin":
69382
69653
  return [
69383
69654
  "/Applications/OpenCode.app/Contents/MacOS/OpenCode",
69384
- join21(home, "Applications", "OpenCode.app", "Contents", "MacOS", "OpenCode")
69655
+ join24(home, "Applications", "OpenCode.app", "Contents", "MacOS", "OpenCode")
69385
69656
  ];
69386
69657
  case "win32": {
69387
69658
  const programFiles = process.env.ProgramFiles;
69388
69659
  const localAppData = process.env.LOCALAPPDATA;
69389
69660
  const paths = [];
69390
69661
  if (programFiles) {
69391
- paths.push(join21(programFiles, "OpenCode", "OpenCode.exe"));
69662
+ paths.push(join24(programFiles, "OpenCode", "OpenCode.exe"));
69392
69663
  }
69393
69664
  if (localAppData) {
69394
- paths.push(join21(localAppData, "OpenCode", "OpenCode.exe"));
69665
+ paths.push(join24(localAppData, "OpenCode", "OpenCode.exe"));
69395
69666
  }
69396
69667
  return paths;
69397
69668
  }
@@ -69399,8 +69670,8 @@ function getDesktopAppPaths(platform) {
69399
69670
  return [
69400
69671
  "/usr/bin/opencode",
69401
69672
  "/usr/lib/opencode/opencode",
69402
- join21(home, "Applications", "opencode-desktop-linux-x86_64.AppImage"),
69403
- join21(home, "Applications", "opencode-desktop-linux-aarch64.AppImage")
69673
+ join24(home, "Applications", "opencode-desktop-linux-x86_64.AppImage"),
69674
+ join24(home, "Applications", "opencode-desktop-linux-aarch64.AppImage")
69404
69675
  ];
69405
69676
  default:
69406
69677
  return [];
@@ -69412,7 +69683,7 @@ function buildVersionCommand(binaryPath, platform) {
69412
69683
  }
69413
69684
  return [binaryPath, "--version"];
69414
69685
  }
69415
- function findDesktopBinary(platform = process.platform, checkExists = existsSync22) {
69686
+ function findDesktopBinary(platform = process.platform, checkExists = existsSync24) {
69416
69687
  for (const desktopPath of getDesktopAppPaths(platform)) {
69417
69688
  if (checkExists(desktopPath)) {
69418
69689
  return { binary: "opencode", path: desktopPath };
@@ -69429,7 +69700,7 @@ async function findOpenCodeBinary() {
69429
69700
  }
69430
69701
  return findDesktopBinary();
69431
69702
  }
69432
- async function getOpenCodeVersion2(binaryPath, platform = process.platform) {
69703
+ async function getOpenCodeVersion3(binaryPath, platform = process.platform) {
69433
69704
  try {
69434
69705
  const command = buildVersionCommand(binaryPath, platform);
69435
69706
  const processResult = spawnWithWindowsHide(command, { stdout: "pipe", stderr: "pipe" });
@@ -69442,10 +69713,10 @@ async function getOpenCodeVersion2(binaryPath, platform = process.platform) {
69442
69713
  return null;
69443
69714
  }
69444
69715
  }
69445
- function compareVersions(current, minimum) {
69446
- const parseVersion = (version2) => version2.replace(/^v/, "").split("-")[0].split(".").map((part) => Number.parseInt(part, 10) || 0);
69447
- const currentParts = parseVersion(current);
69448
- const minimumParts = parseVersion(minimum);
69716
+ function compareVersions2(current, minimum) {
69717
+ const parseVersion2 = (version2) => version2.replace(/^v/, "").split("-")[0].split(".").map((part) => Number.parseInt(part, 10) || 0);
69718
+ const currentParts = parseVersion2(current);
69719
+ const minimumParts = parseVersion2(minimum);
69449
69720
  const length = Math.max(currentParts.length, minimumParts.length);
69450
69721
  for (let index = 0;index < length; index++) {
69451
69722
  const currentPart = currentParts[index] ?? 0;
@@ -69460,12 +69731,12 @@ function compareVersions(current, minimum) {
69460
69731
 
69461
69732
  // src/cli/doctor/checks/system-plugin.ts
69462
69733
  init_shared();
69463
- import { existsSync as existsSync23, readFileSync as readFileSync20 } from "fs";
69734
+ import { existsSync as existsSync25, readFileSync as readFileSync21 } from "fs";
69464
69735
  function detectConfigPath() {
69465
69736
  const paths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
69466
- if (existsSync23(paths.configJsonc))
69737
+ if (existsSync25(paths.configJsonc))
69467
69738
  return paths.configJsonc;
69468
- if (existsSync23(paths.configJson))
69739
+ if (existsSync25(paths.configJson))
69469
69740
  return paths.configJson;
69470
69741
  return null;
69471
69742
  }
@@ -69511,7 +69782,7 @@ function getPluginInfo() {
69511
69782
  };
69512
69783
  }
69513
69784
  try {
69514
- const content = readFileSync20(configPath, "utf-8");
69785
+ const content = readFileSync21(configPath, "utf-8");
69515
69786
  const parsedConfig = parseJsonc(content);
69516
69787
  const pluginEntry = findPluginEntry2(parsedConfig.plugin ?? []);
69517
69788
  if (!pluginEntry) {
@@ -69549,37 +69820,37 @@ function getPluginInfo() {
69549
69820
  init_file_utils();
69550
69821
  init_checker();
69551
69822
  init_auto_update_checker();
69552
- import { existsSync as existsSync24, readFileSync as readFileSync21 } from "fs";
69823
+ import { existsSync as existsSync26, readFileSync as readFileSync22 } from "fs";
69553
69824
  import { homedir as homedir6 } from "os";
69554
- import { join as join22 } from "path";
69825
+ import { join as join25 } from "path";
69555
69826
  init_shared();
69556
69827
  function getPlatformDefaultCacheDir(platform = process.platform) {
69557
69828
  if (platform === "darwin")
69558
- return join22(homedir6(), "Library", "Caches");
69829
+ return join25(homedir6(), "Library", "Caches");
69559
69830
  if (platform === "win32")
69560
- return process.env.LOCALAPPDATA ?? join22(homedir6(), "AppData", "Local");
69561
- return join22(homedir6(), ".cache");
69831
+ return process.env.LOCALAPPDATA ?? join25(homedir6(), "AppData", "Local");
69832
+ return join25(homedir6(), ".cache");
69562
69833
  }
69563
69834
  function resolveOpenCodeCacheDir() {
69564
69835
  const xdgCacheHome = process.env.XDG_CACHE_HOME;
69565
69836
  if (xdgCacheHome)
69566
- return join22(xdgCacheHome, "opencode");
69837
+ return join25(xdgCacheHome, "opencode");
69567
69838
  const fromShared = getOpenCodeCacheDir();
69568
- const platformDefault = join22(getPlatformDefaultCacheDir(), "opencode");
69569
- if (existsSync24(fromShared) || !existsSync24(platformDefault))
69839
+ const platformDefault = join25(getPlatformDefaultCacheDir(), "opencode");
69840
+ if (existsSync26(fromShared) || !existsSync26(platformDefault))
69570
69841
  return fromShared;
69571
69842
  return platformDefault;
69572
69843
  }
69573
69844
  function resolveExistingDir(dirPath) {
69574
- if (!existsSync24(dirPath))
69845
+ if (!existsSync26(dirPath))
69575
69846
  return dirPath;
69576
69847
  return resolveSymlink(dirPath);
69577
69848
  }
69578
69849
  function readPackageJson(filePath) {
69579
- if (!existsSync24(filePath))
69850
+ if (!existsSync26(filePath))
69580
69851
  return null;
69581
69852
  try {
69582
- const content = readFileSync21(filePath, "utf-8");
69853
+ const content = readFileSync22(filePath, "utf-8");
69583
69854
  return parseJsonc(content);
69584
69855
  } catch {
69585
69856
  return null;
@@ -69598,16 +69869,16 @@ function getLoadedPluginVersion() {
69598
69869
  const candidates = [
69599
69870
  {
69600
69871
  cacheDir: configDir,
69601
- cachePackagePath: join22(configDir, "package.json"),
69602
- installedPackagePath: join22(configDir, "node_modules", PACKAGE_NAME2, "package.json")
69872
+ cachePackagePath: join25(configDir, "package.json"),
69873
+ installedPackagePath: join25(configDir, "node_modules", PACKAGE_NAME2, "package.json")
69603
69874
  },
69604
69875
  {
69605
69876
  cacheDir,
69606
- cachePackagePath: join22(cacheDir, "package.json"),
69607
- installedPackagePath: join22(cacheDir, "node_modules", PACKAGE_NAME2, "package.json")
69877
+ cachePackagePath: join25(cacheDir, "package.json"),
69878
+ installedPackagePath: join25(cacheDir, "node_modules", PACKAGE_NAME2, "package.json")
69608
69879
  }
69609
69880
  ];
69610
- const selectedCandidate = candidates.find((candidate) => existsSync24(candidate.installedPackagePath)) ?? candidates[0];
69881
+ const selectedCandidate = candidates.find((candidate) => existsSync26(candidate.installedPackagePath)) ?? candidates[0];
69611
69882
  const { cacheDir: selectedDir, cachePackagePath, installedPackagePath } = selectedCandidate;
69612
69883
  const cachePackage = readPackageJson(cachePackagePath);
69613
69884
  const installedPackage = readPackageJson(installedPackagePath);
@@ -69634,10 +69905,10 @@ init_shared();
69634
69905
  function isConfigValid(configPath) {
69635
69906
  if (!configPath)
69636
69907
  return true;
69637
- if (!existsSync25(configPath))
69908
+ if (!existsSync27(configPath))
69638
69909
  return false;
69639
69910
  try {
69640
- parseJsonc(readFileSync22(configPath, "utf-8"));
69911
+ parseJsonc(readFileSync23(configPath, "utf-8"));
69641
69912
  return true;
69642
69913
  } catch {
69643
69914
  return false;
@@ -69660,7 +69931,7 @@ function buildMessage(status, issues) {
69660
69931
  async function gatherSystemInfo() {
69661
69932
  const [binaryInfo, pluginInfo] = await Promise.all([findOpenCodeBinary(), Promise.resolve(getPluginInfo())]);
69662
69933
  const loadedInfo = getLoadedPluginVersion();
69663
- const opencodeVersion = binaryInfo ? await getOpenCodeVersion2(binaryInfo.path) : null;
69934
+ const opencodeVersion = binaryInfo ? await getOpenCodeVersion3(binaryInfo.path) : null;
69664
69935
  const pluginVersion = pluginInfo.pinnedVersion ?? loadedInfo.expectedVersion ?? loadedInfo.loadedVersion;
69665
69936
  return {
69666
69937
  opencodeVersion,
@@ -69688,7 +69959,7 @@ async function checkSystem() {
69688
69959
  affects: ["doctor", "run"]
69689
69960
  });
69690
69961
  }
69691
- if (systemInfo.opencodeVersion && !compareVersions(systemInfo.opencodeVersion, MIN_OPENCODE_VERSION)) {
69962
+ if (systemInfo.opencodeVersion && !compareVersions2(systemInfo.opencodeVersion, MIN_OPENCODE_VERSION)) {
69692
69963
  issues.push({
69693
69964
  title: "OpenCode version below minimum",
69694
69965
  description: `Detected ${systemInfo.opencodeVersion}; required >= ${MIN_OPENCODE_VERSION}.`,
@@ -69728,7 +69999,7 @@ async function checkSystem() {
69728
69999
  affects: ["plugin loading"]
69729
70000
  });
69730
70001
  }
69731
- if (systemInfo.loadedVersion && latestVersion && !compareVersions(systemInfo.loadedVersion, latestVersion)) {
70002
+ if (systemInfo.loadedVersion && latestVersion && !compareVersions2(systemInfo.loadedVersion, latestVersion)) {
69732
70003
  issues.push({
69733
70004
  title: "Loaded plugin is outdated",
69734
70005
  description: `Loaded ${systemInfo.loadedVersion}, latest ${latestVersion}.`,
@@ -69753,28 +70024,28 @@ async function checkSystem() {
69753
70024
  }
69754
70025
 
69755
70026
  // src/cli/doctor/checks/config.ts
69756
- import { readFileSync as readFileSync25 } from "fs";
69757
- import { join as join26 } from "path";
70027
+ import { readFileSync as readFileSync26 } from "fs";
70028
+ import { join as join29 } from "path";
69758
70029
  init_shared();
69759
70030
 
69760
70031
  // src/cli/doctor/checks/model-resolution-cache.ts
69761
70032
  init_shared();
69762
- import { existsSync as existsSync26, readFileSync as readFileSync23 } from "fs";
70033
+ import { existsSync as existsSync28, readFileSync as readFileSync24 } from "fs";
69763
70034
  import { homedir as homedir7 } from "os";
69764
- import { join as join23 } from "path";
70035
+ import { join as join26 } from "path";
69765
70036
  function getOpenCodeCacheDir2() {
69766
70037
  const xdgCache = process.env.XDG_CACHE_HOME;
69767
70038
  if (xdgCache)
69768
- return join23(xdgCache, "opencode");
69769
- return join23(homedir7(), ".cache", "opencode");
70039
+ return join26(xdgCache, "opencode");
70040
+ return join26(homedir7(), ".cache", "opencode");
69770
70041
  }
69771
70042
  function loadAvailableModelsFromCache() {
69772
- const cacheFile = join23(getOpenCodeCacheDir2(), "models.json");
69773
- if (!existsSync26(cacheFile)) {
70043
+ const cacheFile = join26(getOpenCodeCacheDir2(), "models.json");
70044
+ if (!existsSync28(cacheFile)) {
69774
70045
  return { providers: [], modelCount: 0, cacheExists: false };
69775
70046
  }
69776
70047
  try {
69777
- const content = readFileSync23(cacheFile, "utf-8");
70048
+ const content = readFileSync24(cacheFile, "utf-8");
69778
70049
  const data = parseJsonc(content);
69779
70050
  const providers = Object.keys(data);
69780
70051
  let modelCount = 0;
@@ -69796,24 +70067,24 @@ init_model_capabilities();
69796
70067
 
69797
70068
  // src/cli/doctor/checks/model-resolution-config.ts
69798
70069
  init_shared();
69799
- import { readFileSync as readFileSync24 } from "fs";
69800
- import { join as join24 } from "path";
69801
- var USER_CONFIG_DIR2 = getOpenCodeConfigPaths({ binary: "opencode", version: null }).configDir;
69802
- var PROJECT_CONFIG_DIR = join24(process.cwd(), ".opencode");
70070
+ import { readFileSync as readFileSync25 } from "fs";
70071
+ import { join as join27 } from "path";
70072
+ var PROJECT_CONFIG_DIR = join27(process.cwd(), ".opencode");
69803
70073
  function loadOmoConfig() {
69804
70074
  const projectDetected = detectPluginConfigFile(PROJECT_CONFIG_DIR);
69805
70075
  if (projectDetected.format !== "none") {
69806
70076
  try {
69807
- const content = readFileSync24(projectDetected.path, "utf-8");
70077
+ const content = readFileSync25(projectDetected.path, "utf-8");
69808
70078
  return parseJsonc(content);
69809
70079
  } catch {
69810
70080
  return null;
69811
70081
  }
69812
70082
  }
69813
- const userDetected = detectPluginConfigFile(USER_CONFIG_DIR2);
70083
+ const userConfigDir = getOpenCodeConfigDir({ binary: "opencode" });
70084
+ const userDetected = detectPluginConfigFile(userConfigDir);
69814
70085
  if (userDetected.format !== "none") {
69815
70086
  try {
69816
- const content = readFileSync24(userDetected.path, "utf-8");
70087
+ const content = readFileSync25(userDetected.path, "utf-8");
69817
70088
  return parseJsonc(content);
69818
70089
  } catch {
69819
70090
  return null;
@@ -69824,7 +70095,7 @@ function loadOmoConfig() {
69824
70095
 
69825
70096
  // src/cli/doctor/checks/model-resolution-details.ts
69826
70097
  init_shared();
69827
- import { join as join25 } from "path";
70098
+ import { join as join28 } from "path";
69828
70099
 
69829
70100
  // src/cli/doctor/checks/model-resolution-variant.ts
69830
70101
  function formatModelWithVariant(model, variant) {
@@ -69866,7 +70137,7 @@ function formatCapabilityResolutionLabel(mode) {
69866
70137
  }
69867
70138
  function buildModelResolutionDetails(options) {
69868
70139
  const details = [];
69869
- const cacheFile = join25(getOpenCodeCacheDir(), "models.json");
70140
+ const cacheFile = join28(getOpenCodeCacheDir(), "models.json");
69870
70141
  details.push("\u2550\u2550\u2550 Available Models (from cache) \u2550\u2550\u2550");
69871
70142
  details.push("");
69872
70143
  if (options.available.cacheExists) {
@@ -70021,13 +70292,13 @@ async function checkModels() {
70021
70292
  }
70022
70293
 
70023
70294
  // src/cli/doctor/checks/config.ts
70024
- var USER_CONFIG_DIR3 = getOpenCodeConfigDir({ binary: "opencode" });
70025
- var PROJECT_CONFIG_DIR2 = join26(process.cwd(), ".opencode");
70295
+ var PROJECT_CONFIG_DIR2 = join29(process.cwd(), ".opencode");
70026
70296
  function findConfigPath() {
70027
70297
  const projectConfig = detectPluginConfigFile(PROJECT_CONFIG_DIR2);
70028
70298
  if (projectConfig.format !== "none")
70029
70299
  return projectConfig.path;
70030
- const userConfig = detectPluginConfigFile(USER_CONFIG_DIR3);
70300
+ const userConfigDir = getOpenCodeConfigDir({ binary: "opencode" });
70301
+ const userConfig = detectPluginConfigFile(userConfigDir);
70031
70302
  if (userConfig.format !== "none")
70032
70303
  return userConfig.path;
70033
70304
  return null;
@@ -70038,7 +70309,7 @@ function validateConfig() {
70038
70309
  return { exists: false, path: null, valid: true, config: null, errors: [] };
70039
70310
  }
70040
70311
  try {
70041
- const content = readFileSync25(configPath, "utf-8");
70312
+ const content = readFileSync26(configPath, "utf-8");
70042
70313
  const rawConfig = parseJsonc(content);
70043
70314
  const schemaResult = OhMyOpenCodeConfigSchema.safeParse(rawConfig);
70044
70315
  if (!schemaResult.success) {
@@ -70142,9 +70413,9 @@ async function checkConfig() {
70142
70413
 
70143
70414
  // src/cli/doctor/checks/dependencies.ts
70144
70415
  init_spawn_with_windows_hide();
70145
- import { existsSync as existsSync27 } from "fs";
70416
+ import { existsSync as existsSync29 } from "fs";
70146
70417
  import { createRequire } from "module";
70147
- import { dirname as dirname9, join as join27 } from "path";
70418
+ import { dirname as dirname9, join as join30 } from "path";
70148
70419
  async function checkBinaryExists(binary2) {
70149
70420
  try {
70150
70421
  const path10 = Bun.which(binary2);
@@ -70200,15 +70471,15 @@ async function checkAstGrepNapi() {
70200
70471
  path: null
70201
70472
  };
70202
70473
  } catch {
70203
- const { existsSync: existsSync28 } = await import("fs");
70204
- const { join: join28 } = await import("path");
70474
+ const { existsSync: existsSync30 } = await import("fs");
70475
+ const { join: join31 } = await import("path");
70205
70476
  const { homedir: homedir8 } = await import("os");
70206
70477
  const pathsToCheck = [
70207
- join28(homedir8(), ".config", "opencode", "node_modules", "@ast-grep", "napi"),
70208
- join28(process.cwd(), "node_modules", "@ast-grep", "napi")
70478
+ join31(homedir8(), ".config", "opencode", "node_modules", "@ast-grep", "napi"),
70479
+ join31(process.cwd(), "node_modules", "@ast-grep", "napi")
70209
70480
  ];
70210
70481
  for (const napiPath of pathsToCheck) {
70211
- if (existsSync28(napiPath)) {
70482
+ if (existsSync30(napiPath)) {
70212
70483
  return {
70213
70484
  name: "AST-Grep NAPI",
70214
70485
  required: false,
@@ -70233,8 +70504,8 @@ function findCommentCheckerPackageBinary() {
70233
70504
  try {
70234
70505
  const require2 = createRequire(import.meta.url);
70235
70506
  const pkgPath = require2.resolve("@code-yeongyu/comment-checker/package.json");
70236
- const binaryPath = join27(dirname9(pkgPath), "bin", binaryName);
70237
- if (existsSync27(binaryPath))
70507
+ const binaryPath = join30(dirname9(pkgPath), "bin", binaryName);
70508
+ if (existsSync29(binaryPath))
70238
70509
  return binaryPath;
70239
70510
  } catch {}
70240
70511
  return null;
@@ -70391,15 +70662,15 @@ var BUILTIN_SERVERS = {
70391
70662
  "kotlin-ls": { command: ["kotlin-lsp"], extensions: [".kt", ".kts"] }
70392
70663
  };
70393
70664
  // src/tools/lsp/server-config-loader.ts
70394
- import { existsSync as existsSync28, readFileSync as readFileSync26 } from "fs";
70395
- import { join as join28 } from "path";
70665
+ import { existsSync as existsSync30, readFileSync as readFileSync27 } from "fs";
70666
+ import { join as join31 } from "path";
70396
70667
  init_shared();
70397
70668
  init_jsonc_parser();
70398
70669
  function loadJsonFile(path10) {
70399
- if (!existsSync28(path10))
70670
+ if (!existsSync30(path10))
70400
70671
  return null;
70401
70672
  try {
70402
- return parseJsonc(readFileSync26(path10, "utf-8"));
70673
+ return parseJsonc(readFileSync27(path10, "utf-8"));
70403
70674
  } catch {
70404
70675
  return null;
70405
70676
  }
@@ -70408,9 +70679,9 @@ function getConfigPaths2() {
70408
70679
  const cwd = process.cwd();
70409
70680
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
70410
70681
  return {
70411
- project: detectPluginConfigFile(join28(cwd, ".opencode")).path,
70682
+ project: detectPluginConfigFile(join31(cwd, ".opencode")).path,
70412
70683
  user: detectPluginConfigFile(configDir).path,
70413
- opencode: detectConfigFile(join28(configDir, "opencode")).path
70684
+ opencode: detectConfigFile(join31(configDir, "opencode")).path
70414
70685
  };
70415
70686
  }
70416
70687
  function loadAllConfigs() {
@@ -70479,21 +70750,21 @@ function getMergedServers() {
70479
70750
  }
70480
70751
 
70481
70752
  // src/tools/lsp/server-installation.ts
70482
- import { existsSync as existsSync29 } from "fs";
70483
- import { delimiter as delimiter2, join as join30 } from "path";
70753
+ import { existsSync as existsSync31 } from "fs";
70754
+ import { delimiter as delimiter2, join as join33 } from "path";
70484
70755
 
70485
70756
  // src/tools/lsp/server-path-bases.ts
70486
70757
  init_shared();
70487
- import { join as join29 } from "path";
70758
+ import { join as join32 } from "path";
70488
70759
  function getLspServerAdditionalPathBases(workingDirectory) {
70489
70760
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
70490
- const dataDir = join29(getDataDir(), "opencode");
70761
+ const dataDir = join32(getDataDir(), "opencode");
70491
70762
  return [
70492
- join29(workingDirectory, "node_modules", ".bin"),
70493
- join29(configDir, "bin"),
70494
- join29(configDir, "node_modules", ".bin"),
70495
- join29(dataDir, "bin"),
70496
- join29(dataDir, "bin", "node_modules", ".bin")
70763
+ join32(workingDirectory, "node_modules", ".bin"),
70764
+ join32(configDir, "bin"),
70765
+ join32(configDir, "node_modules", ".bin"),
70766
+ join32(dataDir, "bin"),
70767
+ join32(dataDir, "bin", "node_modules", ".bin")
70497
70768
  ];
70498
70769
  }
70499
70770
 
@@ -70503,7 +70774,7 @@ function isServerInstalled(command) {
70503
70774
  return false;
70504
70775
  const cmd = command[0];
70505
70776
  if (cmd.includes("/") || cmd.includes("\\")) {
70506
- if (existsSync29(cmd))
70777
+ if (existsSync31(cmd))
70507
70778
  return true;
70508
70779
  }
70509
70780
  const isWindows = process.platform === "win32";
@@ -70524,14 +70795,14 @@ function isServerInstalled(command) {
70524
70795
  const paths = pathEnv.split(delimiter2);
70525
70796
  for (const p2 of paths) {
70526
70797
  for (const suffix of exts) {
70527
- if (existsSync29(join30(p2, cmd + suffix))) {
70798
+ if (existsSync31(join33(p2, cmd + suffix))) {
70528
70799
  return true;
70529
70800
  }
70530
70801
  }
70531
70802
  }
70532
70803
  for (const base of getLspServerAdditionalPathBases(process.cwd())) {
70533
70804
  for (const suffix of exts) {
70534
- if (existsSync29(join30(base, cmd + suffix))) {
70805
+ if (existsSync31(join33(base, cmd + suffix))) {
70535
70806
  return true;
70536
70807
  }
70537
70808
  }
@@ -70593,24 +70864,24 @@ function getInstalledLspServers() {
70593
70864
 
70594
70865
  // src/cli/doctor/checks/tools-mcp.ts
70595
70866
  init_shared();
70596
- import { existsSync as existsSync30, readFileSync as readFileSync27 } from "fs";
70867
+ import { existsSync as existsSync32, readFileSync as readFileSync28 } from "fs";
70597
70868
  import { homedir as homedir8 } from "os";
70598
- import { join as join31 } from "path";
70869
+ import { join as join34 } from "path";
70599
70870
  var BUILTIN_MCP_SERVERS = ["context7", "grep_app"];
70600
70871
  function getMcpConfigPaths() {
70601
70872
  return [
70602
- join31(homedir8(), ".claude", ".mcp.json"),
70603
- join31(process.cwd(), ".mcp.json"),
70604
- join31(process.cwd(), ".claude", ".mcp.json")
70873
+ join34(homedir8(), ".claude", ".mcp.json"),
70874
+ join34(process.cwd(), ".mcp.json"),
70875
+ join34(process.cwd(), ".claude", ".mcp.json")
70605
70876
  ];
70606
70877
  }
70607
70878
  function loadUserMcpConfig() {
70608
70879
  const servers = {};
70609
70880
  for (const configPath of getMcpConfigPaths()) {
70610
- if (!existsSync30(configPath))
70881
+ if (!existsSync32(configPath))
70611
70882
  continue;
70612
70883
  try {
70613
- const content = readFileSync27(configPath, "utf-8");
70884
+ const content = readFileSync28(configPath, "utf-8");
70614
70885
  const config2 = parseJsonc(content);
70615
70886
  if (config2.mcpServers) {
70616
70887
  Object.assign(servers, config2.mcpServers);
@@ -71063,11 +71334,11 @@ async function refreshModelCapabilities(options, deps = {}) {
71063
71334
 
71064
71335
  // src/features/mcp-oauth/storage.ts
71065
71336
  init_shared();
71066
- import { chmodSync, existsSync as existsSync31, mkdirSync as mkdirSync8, readFileSync as readFileSync28, unlinkSync as unlinkSync4, writeFileSync as writeFileSync10 } from "fs";
71067
- import { dirname as dirname10, join as join32 } from "path";
71337
+ import { chmodSync, existsSync as existsSync33, mkdirSync as mkdirSync8, readFileSync as readFileSync29, unlinkSync as unlinkSync4, writeFileSync as writeFileSync10 } from "fs";
71338
+ import { dirname as dirname10, join as join35 } from "path";
71068
71339
  var STORAGE_FILE_NAME = "mcp-oauth.json";
71069
71340
  function getMcpOauthStoragePath() {
71070
- return join32(getOpenCodeConfigDir({ binary: "opencode" }), STORAGE_FILE_NAME);
71341
+ return join35(getOpenCodeConfigDir({ binary: "opencode" }), STORAGE_FILE_NAME);
71071
71342
  }
71072
71343
  function normalizeHost(serverHost) {
71073
71344
  let host = serverHost.trim();
@@ -71104,11 +71375,11 @@ function buildKey(serverHost, resource) {
71104
71375
  }
71105
71376
  function readStore() {
71106
71377
  const filePath = getMcpOauthStoragePath();
71107
- if (!existsSync31(filePath)) {
71378
+ if (!existsSync33(filePath)) {
71108
71379
  return null;
71109
71380
  }
71110
71381
  try {
71111
- const content = readFileSync28(filePath, "utf-8");
71382
+ const content = readFileSync29(filePath, "utf-8");
71112
71383
  return JSON.parse(content);
71113
71384
  } catch {
71114
71385
  return null;
@@ -71118,7 +71389,7 @@ function writeStore(store2) {
71118
71389
  const filePath = getMcpOauthStoragePath();
71119
71390
  try {
71120
71391
  const dir = dirname10(filePath);
71121
- if (!existsSync31(dir)) {
71392
+ if (!existsSync33(dir)) {
71122
71393
  mkdirSync8(dir, { recursive: true });
71123
71394
  }
71124
71395
  writeFileSync10(filePath, JSON.stringify(store2, null, 2), { encoding: "utf-8", mode: 384 });
@@ -71153,7 +71424,7 @@ function deleteToken(serverHost, resource) {
71153
71424
  if (Object.keys(store2).length === 0) {
71154
71425
  try {
71155
71426
  const filePath = getMcpOauthStoragePath();
71156
- if (existsSync31(filePath)) {
71427
+ if (existsSync33(filePath)) {
71157
71428
  unlinkSync4(filePath);
71158
71429
  }
71159
71430
  return true;
@@ -71376,7 +71647,7 @@ function startCallbackServer(port) {
71376
71647
  clearTimeout(timeoutId);
71377
71648
  const requestUrl = new URL(request.url ?? "/", `http://localhost:${port}`);
71378
71649
  const code = requestUrl.searchParams.get("code");
71379
- const state = requestUrl.searchParams.get("state");
71650
+ const state2 = requestUrl.searchParams.get("state");
71380
71651
  const error48 = requestUrl.searchParams.get("error");
71381
71652
  if (error48) {
71382
71653
  const errorDescription = requestUrl.searchParams.get("error_description") ?? error48;
@@ -71386,7 +71657,7 @@ function startCallbackServer(port) {
71386
71657
  reject(new Error(`OAuth authorization error: ${errorDescription}`));
71387
71658
  return;
71388
71659
  }
71389
- if (!code || !state) {
71660
+ if (!code || !state2) {
71390
71661
  response.writeHead(400, { "content-type": "text/html" });
71391
71662
  response.end("<html><body><h1>Missing code or state</h1></body></html>");
71392
71663
  server2.close();
@@ -71396,7 +71667,7 @@ function startCallbackServer(port) {
71396
71667
  response.writeHead(200, { "content-type": "text/html" });
71397
71668
  response.end("<html><body><h1>Authorization successful. You can close this tab.</h1></body></html>");
71398
71669
  server2.close();
71399
- resolve2({ code, state });
71670
+ resolve2({ code, state: state2 });
71400
71671
  });
71401
71672
  timeoutId = setTimeout(() => {
71402
71673
  server2.close();
@@ -71432,19 +71703,19 @@ function openBrowser(url2) {
71432
71703
  async function runAuthorizationCodeRedirect(options) {
71433
71704
  const verifier = generateCodeVerifier();
71434
71705
  const challenge = generateCodeChallenge(verifier);
71435
- const state = randomBytes2(16).toString("hex");
71706
+ const state2 = randomBytes2(16).toString("hex");
71436
71707
  const authorizationUrl = buildAuthorizationUrl(options.authorizationEndpoint, {
71437
71708
  clientId: options.clientId,
71438
71709
  redirectUri: options.redirectUri,
71439
71710
  codeChallenge: challenge,
71440
- state,
71711
+ state: state2,
71441
71712
  scopes: options.scopes,
71442
71713
  resource: options.resource
71443
71714
  });
71444
71715
  const callbackPromise = startCallbackServer(options.callbackPort);
71445
71716
  openBrowser(authorizationUrl);
71446
71717
  const result = await callbackPromise;
71447
- if (result.state !== state) {
71718
+ if (result.state !== state2) {
71448
71719
  throw new Error("OAuth state mismatch");
71449
71720
  }
71450
71721
  return { code: result.code, verifier };