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/agents/hephaestus/gpt-5-4.d.ts +22 -1
- package/dist/cli/index.js +477 -206
- package/dist/cli/run/continuation-state.d.ts +2 -1
- package/dist/create-runtime-tmux-config.d.ts +1 -0
- package/dist/features/background-agent/spawner.d.ts +3 -0
- package/dist/features/boulder-state/storage.d.ts +1 -1
- package/dist/features/boulder-state/types.d.ts +1 -0
- package/dist/features/claude-code-plugin-loader/discovery.d.ts +2 -1
- package/dist/features/claude-code-plugin-loader/loader.d.ts +1 -0
- package/dist/features/claude-code-plugin-loader/types.d.ts +10 -0
- package/dist/hooks/atlas/background-launch-session-tracking.d.ts +11 -0
- package/dist/hooks/atlas/boulder-continuation-injector.d.ts +2 -1
- package/dist/hooks/atlas/task-context.d.ts +7 -0
- package/dist/hooks/atlas/types.d.ts +1 -0
- package/dist/hooks/auto-update-checker/constants.d.ts +3 -3
- package/dist/index.js +1026 -681
- package/dist/plugin/tool-registry.d.ts +1 -0
- package/dist/shared/agent-display-names.d.ts +1 -0
- package/dist/tools/delegate-task/resolve-call-id.d.ts +2 -0
- package/package.json +12 -12
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
6797
|
-
import { join as
|
|
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
|
|
6874
|
+
return join6(options.getCacheDir(), options.filename);
|
|
6805
6875
|
}
|
|
6806
6876
|
function ensureCacheDir() {
|
|
6807
6877
|
const cacheDir = options.getCacheDir();
|
|
6808
|
-
if (!
|
|
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 (!
|
|
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
|
|
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
|
|
7007
|
-
import { join as
|
|
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 =
|
|
7013
|
-
return
|
|
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
|
|
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 =
|
|
48332
|
-
PART_STORAGE =
|
|
48333
|
-
SESSION_STORAGE =
|
|
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
|
|
48920
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync3 } from "fs";
|
|
48819
48921
|
function ensureConfigDirectoryExists() {
|
|
48820
48922
|
const configDir = getConfigDir();
|
|
48821
|
-
if (!
|
|
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
|
|
48961
|
+
import { existsSync as existsSync8 } from "fs";
|
|
48860
48962
|
function detectConfigFormat() {
|
|
48861
48963
|
const configJsonc = getConfigJsonc();
|
|
48862
48964
|
const configJson = getConfigJson();
|
|
48863
|
-
if (
|
|
48965
|
+
if (existsSync8(configJsonc)) {
|
|
48864
48966
|
return { format: "jsonc", path: configJsonc };
|
|
48865
48967
|
}
|
|
48866
|
-
if (
|
|
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
|
|
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 (
|
|
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
|
|
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
|
|
49479
|
+
import { existsSync as existsSync10, readFileSync as readFileSync7 } from "fs";
|
|
49378
49480
|
function detectProvidersFromOmoConfig() {
|
|
49379
49481
|
const omoConfigPath = getOmoConfigPath();
|
|
49380
|
-
if (!
|
|
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
|
|
49467
|
-
import { join as
|
|
49568
|
+
import { existsSync as existsSync11 } from "fs";
|
|
49569
|
+
import { join as join10 } from "path";
|
|
49468
49570
|
function getDefaultWorkspaceDir() {
|
|
49469
|
-
return
|
|
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 (!
|
|
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
|
-
|
|
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
|
-
|
|
49661
|
-
|
|
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 =
|
|
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(
|
|
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
|
|
50187
|
-
import { join as
|
|
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
|
|
50245
|
-
const currentVersion =
|
|
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:
|
|
50306
|
-
join:
|
|
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
|
|
50625
|
+
const cachedVersion2 = getCachedVersion();
|
|
50516
50626
|
const localDevVersion = getLocalDevVersion(ctx.directory);
|
|
50517
|
-
const displayVersion = localDevVersion ??
|
|
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.
|
|
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.
|
|
50665
|
-
"oh-my-opencode-darwin-x64": "3.15.
|
|
50666
|
-
"oh-my-opencode-darwin-x64-baseline": "3.15.
|
|
50667
|
-
"oh-my-opencode-linux-arm64": "3.15.
|
|
50668
|
-
"oh-my-opencode-linux-arm64-musl": "3.15.
|
|
50669
|
-
"oh-my-opencode-linux-x64": "3.15.
|
|
50670
|
-
"oh-my-opencode-linux-x64-baseline": "3.15.
|
|
50671
|
-
"oh-my-opencode-linux-x64-musl": "3.15.
|
|
50672
|
-
"oh-my-opencode-linux-x64-musl-baseline": "3.15.
|
|
50673
|
-
"oh-my-opencode-windows-x64": "3.15.
|
|
50674
|
-
"oh-my-opencode-windows-x64-baseline": "3.15.
|
|
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
|
|
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
|
|
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
|
|
66478
|
-
import { join as
|
|
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
|
|
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 (!
|
|
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 (
|
|
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,
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
|
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(
|
|
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
|
|
68563
|
-
import { dirname as dirname4, join as
|
|
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
|
|
68682
|
+
return join14(directory, BOULDER_DIR, BOULDER_FILE);
|
|
68567
68683
|
}
|
|
68568
68684
|
function readBoulderState(directory) {
|
|
68569
68685
|
const filePath = getBoulderFilePath(directory);
|
|
68570
|
-
if (!
|
|
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 (!
|
|
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
|
|
68613
|
-
import { join as
|
|
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
|
|
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 (!
|
|
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
|
|
68648
|
-
import { dirname as dirname5, join as
|
|
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 ?
|
|
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 (!
|
|
68898
|
+
if (!existsSync16(filePath)) {
|
|
68662
68899
|
return null;
|
|
68663
68900
|
}
|
|
68664
68901
|
try {
|
|
68665
|
-
const content =
|
|
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
|
-
|
|
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
|
|
68727
|
-
if (!
|
|
68997
|
+
const state2 = readState(directory);
|
|
68998
|
+
if (!state2 || !state2.active)
|
|
68728
68999
|
return false;
|
|
68729
|
-
if (
|
|
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
|
|
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
|
|
69646
|
+
import { existsSync as existsSync24 } from "fs";
|
|
69376
69647
|
import { homedir as homedir5 } from "os";
|
|
69377
|
-
import { join as
|
|
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
|
-
|
|
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(
|
|
69662
|
+
paths.push(join24(programFiles, "OpenCode", "OpenCode.exe"));
|
|
69392
69663
|
}
|
|
69393
69664
|
if (localAppData) {
|
|
69394
|
-
paths.push(
|
|
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
|
-
|
|
69403
|
-
|
|
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 =
|
|
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
|
|
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
|
|
69446
|
-
const
|
|
69447
|
-
const currentParts =
|
|
69448
|
-
const minimumParts =
|
|
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
|
|
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 (
|
|
69737
|
+
if (existsSync25(paths.configJsonc))
|
|
69467
69738
|
return paths.configJsonc;
|
|
69468
|
-
if (
|
|
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 =
|
|
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
|
|
69823
|
+
import { existsSync as existsSync26, readFileSync as readFileSync22 } from "fs";
|
|
69553
69824
|
import { homedir as homedir6 } from "os";
|
|
69554
|
-
import { join as
|
|
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
|
|
69829
|
+
return join25(homedir6(), "Library", "Caches");
|
|
69559
69830
|
if (platform === "win32")
|
|
69560
|
-
return process.env.LOCALAPPDATA ??
|
|
69561
|
-
return
|
|
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
|
|
69837
|
+
return join25(xdgCacheHome, "opencode");
|
|
69567
69838
|
const fromShared = getOpenCodeCacheDir();
|
|
69568
|
-
const platformDefault =
|
|
69569
|
-
if (
|
|
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 (!
|
|
69845
|
+
if (!existsSync26(dirPath))
|
|
69575
69846
|
return dirPath;
|
|
69576
69847
|
return resolveSymlink(dirPath);
|
|
69577
69848
|
}
|
|
69578
69849
|
function readPackageJson(filePath) {
|
|
69579
|
-
if (!
|
|
69850
|
+
if (!existsSync26(filePath))
|
|
69580
69851
|
return null;
|
|
69581
69852
|
try {
|
|
69582
|
-
const content =
|
|
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:
|
|
69602
|
-
installedPackagePath:
|
|
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:
|
|
69607
|
-
installedPackagePath:
|
|
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) =>
|
|
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 (!
|
|
69908
|
+
if (!existsSync27(configPath))
|
|
69638
69909
|
return false;
|
|
69639
69910
|
try {
|
|
69640
|
-
parseJsonc(
|
|
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
|
|
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 && !
|
|
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 && !
|
|
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
|
|
69757
|
-
import { join as
|
|
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
|
|
70033
|
+
import { existsSync as existsSync28, readFileSync as readFileSync24 } from "fs";
|
|
69763
70034
|
import { homedir as homedir7 } from "os";
|
|
69764
|
-
import { join as
|
|
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
|
|
69769
|
-
return
|
|
70039
|
+
return join26(xdgCache, "opencode");
|
|
70040
|
+
return join26(homedir7(), ".cache", "opencode");
|
|
69770
70041
|
}
|
|
69771
70042
|
function loadAvailableModelsFromCache() {
|
|
69772
|
-
const cacheFile =
|
|
69773
|
-
if (!
|
|
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 =
|
|
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
|
|
69800
|
-
import { join as
|
|
69801
|
-
var
|
|
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 =
|
|
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
|
|
70083
|
+
const userConfigDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
70084
|
+
const userDetected = detectPluginConfigFile(userConfigDir);
|
|
69814
70085
|
if (userDetected.format !== "none") {
|
|
69815
70086
|
try {
|
|
69816
|
-
const content =
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
70416
|
+
import { existsSync as existsSync29 } from "fs";
|
|
70146
70417
|
import { createRequire } from "module";
|
|
70147
|
-
import { dirname as dirname9, join as
|
|
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:
|
|
70204
|
-
const { join:
|
|
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
|
-
|
|
70208
|
-
|
|
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 (
|
|
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 =
|
|
70237
|
-
if (
|
|
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
|
|
70395
|
-
import { join as
|
|
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 (!
|
|
70670
|
+
if (!existsSync30(path10))
|
|
70400
70671
|
return null;
|
|
70401
70672
|
try {
|
|
70402
|
-
return parseJsonc(
|
|
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(
|
|
70682
|
+
project: detectPluginConfigFile(join31(cwd, ".opencode")).path,
|
|
70412
70683
|
user: detectPluginConfigFile(configDir).path,
|
|
70413
|
-
opencode: detectConfigFile(
|
|
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
|
|
70483
|
-
import { delimiter as delimiter2, join as
|
|
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
|
|
70758
|
+
import { join as join32 } from "path";
|
|
70488
70759
|
function getLspServerAdditionalPathBases(workingDirectory) {
|
|
70489
70760
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
70490
|
-
const dataDir =
|
|
70761
|
+
const dataDir = join32(getDataDir(), "opencode");
|
|
70491
70762
|
return [
|
|
70492
|
-
|
|
70493
|
-
|
|
70494
|
-
|
|
70495
|
-
|
|
70496
|
-
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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
|
|
70867
|
+
import { existsSync as existsSync32, readFileSync as readFileSync28 } from "fs";
|
|
70597
70868
|
import { homedir as homedir8 } from "os";
|
|
70598
|
-
import { join as
|
|
70869
|
+
import { join as join34 } from "path";
|
|
70599
70870
|
var BUILTIN_MCP_SERVERS = ["context7", "grep_app"];
|
|
70600
70871
|
function getMcpConfigPaths() {
|
|
70601
70872
|
return [
|
|
70602
|
-
|
|
70603
|
-
|
|
70604
|
-
|
|
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 (!
|
|
70881
|
+
if (!existsSync32(configPath))
|
|
70611
70882
|
continue;
|
|
70612
70883
|
try {
|
|
70613
|
-
const content =
|
|
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
|
|
71067
|
-
import { dirname as dirname10, join as
|
|
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
|
|
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 (!
|
|
71378
|
+
if (!existsSync33(filePath)) {
|
|
71108
71379
|
return null;
|
|
71109
71380
|
}
|
|
71110
71381
|
try {
|
|
71111
|
-
const content =
|
|
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 (!
|
|
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 (
|
|
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
|
|
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 || !
|
|
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
|
|
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 !==
|
|
71718
|
+
if (result.state !== state2) {
|
|
71448
71719
|
throw new Error("OAuth state mismatch");
|
|
71449
71720
|
}
|
|
71450
71721
|
return { code: result.code, verifier };
|