oh-my-opencode 3.15.2 → 3.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/dynamic-agent-core-sections.d.ts +7 -0
- package/dist/agents/dynamic-agent-prompt-builder.d.ts +1 -1
- package/dist/cli/config-manager/backup-config.d.ts +6 -0
- package/dist/cli/config-manager/version-compatibility.d.ts +9 -0
- package/dist/cli/config-manager.d.ts +4 -0
- package/dist/cli/doctor/constants.d.ts +1 -1
- package/dist/cli/index.js +1691 -552
- package/dist/cli/minimum-opencode-version.d.ts +1 -0
- package/dist/cli/model-fallback-types.d.ts +3 -0
- package/dist/cli/run/continuation-state.d.ts +2 -1
- package/dist/cli/types.d.ts +1 -0
- package/dist/create-managers.d.ts +14 -0
- package/dist/features/background-agent/compaction-aware-message-resolver.d.ts +5 -2
- package/dist/features/boulder-state/storage.d.ts +8 -1
- package/dist/features/boulder-state/types.d.ts +1 -0
- package/dist/features/builtin-commands/templates/ralph-loop.d.ts +1 -1
- package/dist/features/claude-code-mcp-loader/env-expander.d.ts +5 -2
- package/dist/features/claude-code-plugin-loader/loader.d.ts +15 -0
- package/dist/features/claude-code-plugin-loader/scope-filter.d.ts +2 -0
- package/dist/features/claude-code-plugin-loader/types.d.ts +11 -0
- package/dist/features/claude-code-session-state/state.d.ts +1 -0
- package/dist/features/mcp-oauth/provider.d.ts +1 -0
- package/dist/features/mcp-oauth/refresh-mutex.d.ts +26 -0
- package/dist/features/skill-mcp-manager/error-redaction.d.ts +10 -0
- package/dist/features/skill-mcp-manager/oauth-handler.d.ts +7 -0
- package/dist/features/skill-mcp-manager/types.d.ts +3 -1
- 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 +2 -0
- package/dist/hooks/auto-update-checker/constants.d.ts +2 -2
- package/dist/hooks/keyword-detector/hook.d.ts +2 -1
- package/dist/hooks/ralph-loop/constants.d.ts +1 -0
- package/dist/hooks/ralph-loop/oracle-verification-detector.d.ts +8 -0
- package/dist/hooks/read-image-resizer/png-fallback-resizer.d.ts +2 -0
- package/dist/hooks/runtime-fallback/auto-retry-signal.d.ts +4 -0
- package/dist/hooks/runtime-fallback/error-classifier.d.ts +1 -5
- package/dist/hooks/session-recovery/types.d.ts +2 -0
- package/dist/hooks/todo-continuation-enforcer/pending-question-detection.d.ts +1 -1
- package/dist/hooks/todo-continuation-enforcer/token-limit-detection.d.ts +4 -0
- package/dist/hooks/todo-continuation-enforcer/types.d.ts +7 -0
- package/dist/hooks/unstable-agent-babysitter/task-message-analyzer.d.ts +1 -0
- package/dist/hooks/unstable-agent-babysitter/unstable-agent-babysitter-hook.d.ts +2 -0
- package/dist/index.js +2439 -1222
- package/dist/plugin/chat-params.d.ts +1 -0
- package/dist/plugin/hooks/create-transform-hooks.d.ts +2 -0
- package/dist/shared/agent-display-names.d.ts +10 -2
- package/dist/shared/compaction-marker.d.ts +12 -0
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/internal-initiator-marker.d.ts +1 -0
- package/dist/shared/session-prompt-params-state.d.ts +1 -0
- package/dist/tools/background-task/constants.d.ts +1 -1
- package/dist/tools/delegate-task/resolve-call-id.d.ts +2 -0
- package/package.json +16 -18
- package/postinstall.mjs +63 -1
package/dist/cli/index.js
CHANGED
|
@@ -5977,9 +5977,13 @@ var PLUGIN_NAME = "oh-my-openagent", LEGACY_PLUGIN_NAME = "oh-my-opencode", CONF
|
|
|
5977
5977
|
// src/shared/jsonc-parser.ts
|
|
5978
5978
|
import { existsSync, readFileSync } from "fs";
|
|
5979
5979
|
import { join as join3 } from "path";
|
|
5980
|
+
function stripBom(content) {
|
|
5981
|
+
return content.charCodeAt(0) === 65279 ? content.slice(1) : content;
|
|
5982
|
+
}
|
|
5980
5983
|
function parseJsonc(content) {
|
|
5984
|
+
content = content.replace(/^\uFEFF/, "");
|
|
5981
5985
|
const errors = [];
|
|
5982
|
-
const result = parse2(content, errors, {
|
|
5986
|
+
const result = parse2(stripBom(content), errors, {
|
|
5983
5987
|
allowTrailingComma: true,
|
|
5984
5988
|
disallowComments: false
|
|
5985
5989
|
});
|
|
@@ -6042,15 +6046,15 @@ var init_agent_names = __esm(() => {
|
|
|
6042
6046
|
"omo-plan": "prometheus",
|
|
6043
6047
|
"Planner-Sisyphus": "prometheus",
|
|
6044
6048
|
"planner-sisyphus": "prometheus",
|
|
6045
|
-
"Prometheus
|
|
6049
|
+
"Prometheus - Plan Builder": "prometheus",
|
|
6046
6050
|
prometheus: "prometheus",
|
|
6047
6051
|
"orchestrator-sisyphus": "atlas",
|
|
6048
6052
|
Atlas: "atlas",
|
|
6049
6053
|
atlas: "atlas",
|
|
6050
6054
|
"plan-consultant": "metis",
|
|
6051
|
-
"Metis
|
|
6055
|
+
"Metis - Plan Consultant": "metis",
|
|
6052
6056
|
metis: "metis",
|
|
6053
|
-
"Momus
|
|
6057
|
+
"Momus - Plan Critic": "momus",
|
|
6054
6058
|
momus: "momus",
|
|
6055
6059
|
"Sisyphus-Junior": "sisyphus-junior",
|
|
6056
6060
|
"sisyphus-junior": "sisyphus-junior",
|
|
@@ -6367,18 +6371,88 @@ var TAURI_APP_IDENTIFIER = "ai.opencode.desktop", TAURI_APP_IDENTIFIER_DEV = "ai
|
|
|
6367
6371
|
var init_opencode_config_dir = () => {};
|
|
6368
6372
|
|
|
6369
6373
|
// src/shared/opencode-version.ts
|
|
6370
|
-
|
|
6374
|
+
import { execSync } from "child_process";
|
|
6375
|
+
function parseVersion(version) {
|
|
6376
|
+
const cleaned = version.replace(/^v/, "").split("-")[0];
|
|
6377
|
+
return cleaned.split(".").map((n) => parseInt(n, 10) || 0);
|
|
6378
|
+
}
|
|
6379
|
+
function compareVersions(a, b) {
|
|
6380
|
+
const partsA = parseVersion(a);
|
|
6381
|
+
const partsB = parseVersion(b);
|
|
6382
|
+
const maxLen = Math.max(partsA.length, partsB.length);
|
|
6383
|
+
for (let i2 = 0;i2 < maxLen; i2++) {
|
|
6384
|
+
const numA = partsA[i2] ?? 0;
|
|
6385
|
+
const numB = partsB[i2] ?? 0;
|
|
6386
|
+
if (numA < numB)
|
|
6387
|
+
return -1;
|
|
6388
|
+
if (numA > numB)
|
|
6389
|
+
return 1;
|
|
6390
|
+
}
|
|
6391
|
+
return 0;
|
|
6392
|
+
}
|
|
6393
|
+
function getOpenCodeVersion() {
|
|
6394
|
+
if (cachedVersion !== NOT_CACHED) {
|
|
6395
|
+
return cachedVersion;
|
|
6396
|
+
}
|
|
6397
|
+
try {
|
|
6398
|
+
const result = execSync("opencode --version", {
|
|
6399
|
+
encoding: "utf-8",
|
|
6400
|
+
timeout: 5000,
|
|
6401
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
6402
|
+
}).trim();
|
|
6403
|
+
const versionMatch = result.match(/(\d+\.\d+\.\d+(?:-[\w.]+)?)/);
|
|
6404
|
+
cachedVersion = versionMatch?.[1] ?? null;
|
|
6405
|
+
return cachedVersion;
|
|
6406
|
+
} catch {
|
|
6407
|
+
cachedVersion = null;
|
|
6408
|
+
return null;
|
|
6409
|
+
}
|
|
6410
|
+
}
|
|
6411
|
+
function isOpenCodeVersionAtLeast(version) {
|
|
6412
|
+
const current = getOpenCodeVersion();
|
|
6413
|
+
if (!current)
|
|
6414
|
+
return true;
|
|
6415
|
+
return compareVersions(current, version) >= 0;
|
|
6416
|
+
}
|
|
6417
|
+
var OPENCODE_SQLITE_VERSION = "1.1.53", NOT_CACHED, cachedVersion;
|
|
6371
6418
|
var init_opencode_version = __esm(() => {
|
|
6372
6419
|
NOT_CACHED = Symbol("NOT_CACHED");
|
|
6420
|
+
cachedVersion = NOT_CACHED;
|
|
6373
6421
|
});
|
|
6374
6422
|
|
|
6375
6423
|
// src/shared/opencode-storage-detection.ts
|
|
6376
|
-
|
|
6424
|
+
import { existsSync as existsSync3 } from "fs";
|
|
6425
|
+
import { join as join5 } from "path";
|
|
6426
|
+
function isSqliteBackend() {
|
|
6427
|
+
if (cachedResult === true)
|
|
6428
|
+
return true;
|
|
6429
|
+
if (cachedResult === false)
|
|
6430
|
+
return false;
|
|
6431
|
+
const check = () => {
|
|
6432
|
+
const versionOk = isOpenCodeVersionAtLeast(OPENCODE_SQLITE_VERSION);
|
|
6433
|
+
const dbPath = join5(getDataDir(), "opencode", "opencode.db");
|
|
6434
|
+
return versionOk && existsSync3(dbPath);
|
|
6435
|
+
};
|
|
6436
|
+
if (cachedResult === FALSE_PENDING_RETRY) {
|
|
6437
|
+
const result2 = check();
|
|
6438
|
+
cachedResult = result2;
|
|
6439
|
+
return result2;
|
|
6440
|
+
}
|
|
6441
|
+
const result = check();
|
|
6442
|
+
if (result) {
|
|
6443
|
+
cachedResult = true;
|
|
6444
|
+
} else {
|
|
6445
|
+
cachedResult = FALSE_PENDING_RETRY;
|
|
6446
|
+
}
|
|
6447
|
+
return result;
|
|
6448
|
+
}
|
|
6449
|
+
var NOT_CACHED2, FALSE_PENDING_RETRY, cachedResult;
|
|
6377
6450
|
var init_opencode_storage_detection = __esm(() => {
|
|
6378
6451
|
init_data_path();
|
|
6379
6452
|
init_opencode_version();
|
|
6380
6453
|
NOT_CACHED2 = Symbol("NOT_CACHED");
|
|
6381
6454
|
FALSE_PENDING_RETRY = Symbol("FALSE_PENDING_RETRY");
|
|
6455
|
+
cachedResult = NOT_CACHED2;
|
|
6382
6456
|
});
|
|
6383
6457
|
// src/shared/load-opencode-plugins.ts
|
|
6384
6458
|
var init_load_opencode_plugins = __esm(() => {
|
|
@@ -6793,19 +6867,19 @@ function normalizeModelID(modelID) {
|
|
|
6793
6867
|
}
|
|
6794
6868
|
|
|
6795
6869
|
// src/shared/json-file-cache-store.ts
|
|
6796
|
-
import { existsSync as
|
|
6797
|
-
import { join as
|
|
6870
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
6871
|
+
import { join as join6 } from "path";
|
|
6798
6872
|
function toLogLabel(cacheLabel) {
|
|
6799
6873
|
return cacheLabel.toLowerCase();
|
|
6800
6874
|
}
|
|
6801
6875
|
function createJsonFileCacheStore(options) {
|
|
6802
6876
|
let memoryValue;
|
|
6803
6877
|
function getCacheFilePath() {
|
|
6804
|
-
return
|
|
6878
|
+
return join6(options.getCacheDir(), options.filename);
|
|
6805
6879
|
}
|
|
6806
6880
|
function ensureCacheDir() {
|
|
6807
6881
|
const cacheDir = options.getCacheDir();
|
|
6808
|
-
if (!
|
|
6882
|
+
if (!existsSync4(cacheDir)) {
|
|
6809
6883
|
mkdirSync2(cacheDir, { recursive: true });
|
|
6810
6884
|
}
|
|
6811
6885
|
}
|
|
@@ -6814,7 +6888,7 @@ function createJsonFileCacheStore(options) {
|
|
|
6814
6888
|
return memoryValue;
|
|
6815
6889
|
}
|
|
6816
6890
|
const cacheFile = getCacheFilePath();
|
|
6817
|
-
if (!
|
|
6891
|
+
if (!existsSync4(cacheFile)) {
|
|
6818
6892
|
memoryValue = null;
|
|
6819
6893
|
log(`[${options.logPrefix}] ${options.cacheLabel} file not found`, { cacheFile });
|
|
6820
6894
|
return null;
|
|
@@ -6834,7 +6908,7 @@ function createJsonFileCacheStore(options) {
|
|
|
6834
6908
|
}
|
|
6835
6909
|
}
|
|
6836
6910
|
function has() {
|
|
6837
|
-
return
|
|
6911
|
+
return existsSync4(getCacheFilePath());
|
|
6838
6912
|
}
|
|
6839
6913
|
function write(value) {
|
|
6840
6914
|
ensureCacheDir();
|
|
@@ -7003,14 +7077,14 @@ var init_connected_providers_cache = __esm(() => {
|
|
|
7003
7077
|
});
|
|
7004
7078
|
|
|
7005
7079
|
// src/shared/model-availability.ts
|
|
7006
|
-
import { existsSync as
|
|
7007
|
-
import { join as
|
|
7080
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3 } from "fs";
|
|
7081
|
+
import { join as join7 } from "path";
|
|
7008
7082
|
function isModelCacheAvailable() {
|
|
7009
7083
|
if (hasProviderModelsCache()) {
|
|
7010
7084
|
return true;
|
|
7011
7085
|
}
|
|
7012
|
-
const cacheFile =
|
|
7013
|
-
return
|
|
7086
|
+
const cacheFile = join7(getOpenCodeCacheDir(), "models.json");
|
|
7087
|
+
return existsSync5(cacheFile);
|
|
7014
7088
|
}
|
|
7015
7089
|
var init_model_availability = __esm(() => {
|
|
7016
7090
|
init_logger();
|
|
@@ -48305,6 +48379,57 @@ var init_constants = __esm(() => {
|
|
|
48305
48379
|
init_shared();
|
|
48306
48380
|
});
|
|
48307
48381
|
|
|
48382
|
+
// src/shared/opencode-storage-paths.ts
|
|
48383
|
+
import { join as join8 } from "path";
|
|
48384
|
+
var OPENCODE_STORAGE, MESSAGE_STORAGE, PART_STORAGE, SESSION_STORAGE;
|
|
48385
|
+
var init_opencode_storage_paths = __esm(() => {
|
|
48386
|
+
init_data_path();
|
|
48387
|
+
OPENCODE_STORAGE = getOpenCodeStorageDir();
|
|
48388
|
+
MESSAGE_STORAGE = join8(OPENCODE_STORAGE, "message");
|
|
48389
|
+
PART_STORAGE = join8(OPENCODE_STORAGE, "part");
|
|
48390
|
+
SESSION_STORAGE = join8(OPENCODE_STORAGE, "session");
|
|
48391
|
+
});
|
|
48392
|
+
|
|
48393
|
+
// src/shared/compaction-marker.ts
|
|
48394
|
+
import { existsSync as existsSync6, readdirSync, readFileSync as readFileSync4 } from "fs";
|
|
48395
|
+
import { join as join9 } from "path";
|
|
48396
|
+
function isCompactionPart(part) {
|
|
48397
|
+
return typeof part === "object" && part !== null && part.type === "compaction";
|
|
48398
|
+
}
|
|
48399
|
+
function isCompactionAgent(agent) {
|
|
48400
|
+
return typeof agent === "string" && agent.trim().toLowerCase() === "compaction";
|
|
48401
|
+
}
|
|
48402
|
+
function hasCompactionPart(parts) {
|
|
48403
|
+
return Array.isArray(parts) && parts.some((part) => isCompactionPart(part));
|
|
48404
|
+
}
|
|
48405
|
+
function isCompactionMessage(message) {
|
|
48406
|
+
return isCompactionAgent(message.info?.agent ?? message.agent) || hasCompactionPart(message.parts);
|
|
48407
|
+
}
|
|
48408
|
+
function hasCompactionPartInStorage(messageID) {
|
|
48409
|
+
if (!messageID) {
|
|
48410
|
+
return false;
|
|
48411
|
+
}
|
|
48412
|
+
const partDir = join9(PART_STORAGE, messageID);
|
|
48413
|
+
if (!existsSync6(partDir)) {
|
|
48414
|
+
return false;
|
|
48415
|
+
}
|
|
48416
|
+
try {
|
|
48417
|
+
return readdirSync(partDir).filter((fileName) => fileName.endsWith(".json")).some((fileName) => {
|
|
48418
|
+
try {
|
|
48419
|
+
const content = readFileSync4(join9(partDir, fileName), "utf-8");
|
|
48420
|
+
return isCompactionPart(JSON.parse(content));
|
|
48421
|
+
} catch {
|
|
48422
|
+
return false;
|
|
48423
|
+
}
|
|
48424
|
+
});
|
|
48425
|
+
} catch {
|
|
48426
|
+
return false;
|
|
48427
|
+
}
|
|
48428
|
+
}
|
|
48429
|
+
var init_compaction_marker = __esm(() => {
|
|
48430
|
+
init_opencode_storage_paths();
|
|
48431
|
+
});
|
|
48432
|
+
|
|
48308
48433
|
// src/features/hook-message-injector/injector.ts
|
|
48309
48434
|
import { randomBytes } from "crypto";
|
|
48310
48435
|
var processPrefix;
|
|
@@ -48313,6 +48438,7 @@ var init_injector = __esm(() => {
|
|
|
48313
48438
|
init_logger();
|
|
48314
48439
|
init_opencode_storage_detection();
|
|
48315
48440
|
init_shared();
|
|
48441
|
+
init_compaction_marker();
|
|
48316
48442
|
processPrefix = randomBytes(4).toString("hex");
|
|
48317
48443
|
});
|
|
48318
48444
|
|
|
@@ -48322,18 +48448,33 @@ var init_hook_message_injector = __esm(() => {
|
|
|
48322
48448
|
init_constants();
|
|
48323
48449
|
});
|
|
48324
48450
|
|
|
48325
|
-
// src/shared/opencode-storage-paths.ts
|
|
48326
|
-
import { join as join7 } from "path";
|
|
48327
|
-
var OPENCODE_STORAGE, MESSAGE_STORAGE, PART_STORAGE, SESSION_STORAGE;
|
|
48328
|
-
var init_opencode_storage_paths = __esm(() => {
|
|
48329
|
-
init_data_path();
|
|
48330
|
-
OPENCODE_STORAGE = getOpenCodeStorageDir();
|
|
48331
|
-
MESSAGE_STORAGE = join7(OPENCODE_STORAGE, "message");
|
|
48332
|
-
PART_STORAGE = join7(OPENCODE_STORAGE, "part");
|
|
48333
|
-
SESSION_STORAGE = join7(OPENCODE_STORAGE, "session");
|
|
48334
|
-
});
|
|
48335
|
-
|
|
48336
48451
|
// src/shared/opencode-message-dir.ts
|
|
48452
|
+
import { existsSync as existsSync7, readdirSync as readdirSync2 } from "fs";
|
|
48453
|
+
import { join as join10 } from "path";
|
|
48454
|
+
function getMessageDir(sessionID) {
|
|
48455
|
+
if (!sessionID.startsWith("ses_"))
|
|
48456
|
+
return null;
|
|
48457
|
+
if (/[/\\]|\.\./.test(sessionID))
|
|
48458
|
+
return null;
|
|
48459
|
+
if (!existsSync7(MESSAGE_STORAGE))
|
|
48460
|
+
return null;
|
|
48461
|
+
const directPath = join10(MESSAGE_STORAGE, sessionID);
|
|
48462
|
+
if (existsSync7(directPath)) {
|
|
48463
|
+
return directPath;
|
|
48464
|
+
}
|
|
48465
|
+
try {
|
|
48466
|
+
for (const dir of readdirSync2(MESSAGE_STORAGE)) {
|
|
48467
|
+
const sessionPath = join10(MESSAGE_STORAGE, dir, sessionID);
|
|
48468
|
+
if (existsSync7(sessionPath)) {
|
|
48469
|
+
return sessionPath;
|
|
48470
|
+
}
|
|
48471
|
+
}
|
|
48472
|
+
} catch (error) {
|
|
48473
|
+
log("[opencode-message-dir] Failed to scan message directories", { sessionID, error: String(error) });
|
|
48474
|
+
return null;
|
|
48475
|
+
}
|
|
48476
|
+
return null;
|
|
48477
|
+
}
|
|
48337
48478
|
var init_opencode_message_dir = __esm(() => {
|
|
48338
48479
|
init_opencode_storage_paths();
|
|
48339
48480
|
init_logger();
|
|
@@ -48359,22 +48500,25 @@ function getAgentConfigKey(agentName) {
|
|
|
48359
48500
|
const reversed = REVERSE_DISPLAY_NAMES[lower];
|
|
48360
48501
|
if (reversed !== undefined)
|
|
48361
48502
|
return reversed;
|
|
48503
|
+
const legacy = LEGACY_DISPLAY_NAMES[lower];
|
|
48504
|
+
if (legacy !== undefined)
|
|
48505
|
+
return legacy;
|
|
48362
48506
|
if (AGENT_DISPLAY_NAMES[lower] !== undefined)
|
|
48363
48507
|
return lower;
|
|
48364
48508
|
return lower;
|
|
48365
48509
|
}
|
|
48366
|
-
var AGENT_DISPLAY_NAMES, REVERSE_DISPLAY_NAMES;
|
|
48510
|
+
var AGENT_DISPLAY_NAMES, REVERSE_DISPLAY_NAMES, LEGACY_DISPLAY_NAMES;
|
|
48367
48511
|
var init_agent_display_names = __esm(() => {
|
|
48368
48512
|
AGENT_DISPLAY_NAMES = {
|
|
48369
|
-
sisyphus: "Sisyphus
|
|
48370
|
-
hephaestus: "Hephaestus
|
|
48371
|
-
prometheus: "Prometheus
|
|
48372
|
-
atlas: "Atlas
|
|
48513
|
+
sisyphus: "Sisyphus - Ultraworker",
|
|
48514
|
+
hephaestus: "Hephaestus - Deep Agent",
|
|
48515
|
+
prometheus: "Prometheus - Plan Builder",
|
|
48516
|
+
atlas: "Atlas - Plan Executor",
|
|
48373
48517
|
"sisyphus-junior": "Sisyphus-Junior",
|
|
48374
|
-
metis: "Metis
|
|
48375
|
-
momus: "Momus
|
|
48376
|
-
athena: "Athena
|
|
48377
|
-
"athena-junior": "Athena-Junior
|
|
48518
|
+
metis: "Metis - Plan Consultant",
|
|
48519
|
+
momus: "Momus - Plan Critic",
|
|
48520
|
+
athena: "Athena - Council",
|
|
48521
|
+
"athena-junior": "Athena-Junior - Council",
|
|
48378
48522
|
oracle: "oracle",
|
|
48379
48523
|
librarian: "librarian",
|
|
48380
48524
|
explore: "explore",
|
|
@@ -48382,6 +48526,16 @@ var init_agent_display_names = __esm(() => {
|
|
|
48382
48526
|
"council-member": "council-member"
|
|
48383
48527
|
};
|
|
48384
48528
|
REVERSE_DISPLAY_NAMES = Object.fromEntries(Object.entries(AGENT_DISPLAY_NAMES).map(([key, displayName]) => [displayName.toLowerCase(), key]));
|
|
48529
|
+
LEGACY_DISPLAY_NAMES = {
|
|
48530
|
+
"sisyphus (ultraworker)": "sisyphus",
|
|
48531
|
+
"hephaestus (deep agent)": "hephaestus",
|
|
48532
|
+
"prometheus (plan builder)": "prometheus",
|
|
48533
|
+
"atlas (plan executor)": "atlas",
|
|
48534
|
+
"metis (plan consultant)": "metis",
|
|
48535
|
+
"momus (plan critic)": "momus",
|
|
48536
|
+
"athena (council)": "athena",
|
|
48537
|
+
"athena-junior (council)": "athena-junior"
|
|
48538
|
+
};
|
|
48385
48539
|
});
|
|
48386
48540
|
|
|
48387
48541
|
// src/shared/session-utils.ts
|
|
@@ -48545,9 +48699,18 @@ var init_session_tools_store = __esm(() => {
|
|
|
48545
48699
|
var init_prompt_tools = __esm(() => {
|
|
48546
48700
|
init_session_tools_store();
|
|
48547
48701
|
});
|
|
48702
|
+
|
|
48703
|
+
// src/shared/internal-initiator-marker.ts
|
|
48704
|
+
var init_internal_initiator_marker = () => {};
|
|
48705
|
+
// src/features/claude-code-plugin-loader/scope-filter.ts
|
|
48706
|
+
var init_scope_filter = __esm(() => {
|
|
48707
|
+
init_contains_path();
|
|
48708
|
+
});
|
|
48709
|
+
|
|
48548
48710
|
// src/features/claude-code-plugin-loader/discovery.ts
|
|
48549
48711
|
var init_discovery = __esm(() => {
|
|
48550
48712
|
init_logger();
|
|
48713
|
+
init_scope_filter();
|
|
48551
48714
|
});
|
|
48552
48715
|
|
|
48553
48716
|
// src/features/claude-code-plugin-loader/command-loader.ts
|
|
@@ -48598,7 +48761,7 @@ var init_env_expander = __esm(() => {
|
|
|
48598
48761
|
});
|
|
48599
48762
|
|
|
48600
48763
|
// src/features/claude-code-mcp-loader/scope-filter.ts
|
|
48601
|
-
var
|
|
48764
|
+
var init_scope_filter2 = __esm(() => {
|
|
48602
48765
|
init_contains_path();
|
|
48603
48766
|
});
|
|
48604
48767
|
|
|
@@ -48609,7 +48772,7 @@ var init_transformer = __esm(() => {
|
|
|
48609
48772
|
// src/features/claude-code-plugin-loader/mcp-server-loader.ts
|
|
48610
48773
|
var init_mcp_server_loader = __esm(() => {
|
|
48611
48774
|
init_env_expander();
|
|
48612
|
-
|
|
48775
|
+
init_scope_filter2();
|
|
48613
48776
|
init_transformer();
|
|
48614
48777
|
init_logger();
|
|
48615
48778
|
});
|
|
@@ -48740,6 +48903,8 @@ var init_shared = __esm(() => {
|
|
|
48740
48903
|
init_project_discovery_dirs();
|
|
48741
48904
|
init_session_directory_resolver();
|
|
48742
48905
|
init_prompt_tools();
|
|
48906
|
+
init_compaction_marker();
|
|
48907
|
+
init_internal_initiator_marker();
|
|
48743
48908
|
init_plugin_command_discovery();
|
|
48744
48909
|
init_log_legacy_plugin_startup_warning();
|
|
48745
48910
|
});
|
|
@@ -48820,12 +48985,37 @@ var init_plugin_name_with_version = __esm(() => {
|
|
|
48820
48985
|
PRIORITIZED_TAGS = ["latest", "beta", "next"];
|
|
48821
48986
|
});
|
|
48822
48987
|
|
|
48988
|
+
// src/cli/config-manager/backup-config.ts
|
|
48989
|
+
import { copyFileSync as copyFileSync2, existsSync as existsSync8, mkdirSync as mkdirSync3 } from "fs";
|
|
48990
|
+
import { dirname } from "path";
|
|
48991
|
+
function backupConfigFile(configPath) {
|
|
48992
|
+
if (!existsSync8(configPath)) {
|
|
48993
|
+
return { success: true };
|
|
48994
|
+
}
|
|
48995
|
+
const timestamp2 = new Date().toISOString().replace(/[:.]/g, "-");
|
|
48996
|
+
const backupPath = `${configPath}.backup-${timestamp2}`;
|
|
48997
|
+
try {
|
|
48998
|
+
const dir = dirname(backupPath);
|
|
48999
|
+
if (!existsSync8(dir)) {
|
|
49000
|
+
mkdirSync3(dir, { recursive: true });
|
|
49001
|
+
}
|
|
49002
|
+
copyFileSync2(configPath, backupPath);
|
|
49003
|
+
return { success: true, backupPath };
|
|
49004
|
+
} catch (err) {
|
|
49005
|
+
return {
|
|
49006
|
+
success: false,
|
|
49007
|
+
error: err instanceof Error ? err.message : "Failed to create backup"
|
|
49008
|
+
};
|
|
49009
|
+
}
|
|
49010
|
+
}
|
|
49011
|
+
var init_backup_config = () => {};
|
|
49012
|
+
|
|
48823
49013
|
// src/cli/config-manager/ensure-config-directory-exists.ts
|
|
48824
|
-
import { existsSync as
|
|
49014
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync4 } from "fs";
|
|
48825
49015
|
function ensureConfigDirectoryExists() {
|
|
48826
49016
|
const configDir = getConfigDir();
|
|
48827
|
-
if (!
|
|
48828
|
-
|
|
49017
|
+
if (!existsSync9(configDir)) {
|
|
49018
|
+
mkdirSync4(configDir, { recursive: true });
|
|
48829
49019
|
}
|
|
48830
49020
|
}
|
|
48831
49021
|
var init_ensure_config_directory_exists = __esm(() => {
|
|
@@ -48862,14 +49052,14 @@ function formatErrorWithSuggestion(err, context) {
|
|
|
48862
49052
|
}
|
|
48863
49053
|
|
|
48864
49054
|
// src/cli/config-manager/opencode-config-format.ts
|
|
48865
|
-
import { existsSync as
|
|
49055
|
+
import { existsSync as existsSync10 } from "fs";
|
|
48866
49056
|
function detectConfigFormat() {
|
|
48867
49057
|
const configJsonc = getConfigJsonc();
|
|
48868
49058
|
const configJson = getConfigJson();
|
|
48869
|
-
if (
|
|
49059
|
+
if (existsSync10(configJsonc)) {
|
|
48870
49060
|
return { format: "jsonc", path: configJsonc };
|
|
48871
49061
|
}
|
|
48872
|
-
if (
|
|
49062
|
+
if (existsSync10(configJson)) {
|
|
48873
49063
|
return { format: "json", path: configJson };
|
|
48874
49064
|
}
|
|
48875
49065
|
return { format: "none", path: configJson };
|
|
@@ -48879,7 +49069,7 @@ var init_opencode_config_format = __esm(() => {
|
|
|
48879
49069
|
});
|
|
48880
49070
|
|
|
48881
49071
|
// src/cli/config-manager/parse-opencode-config-file.ts
|
|
48882
|
-
import { readFileSync as
|
|
49072
|
+
import { readFileSync as readFileSync5, statSync } from "fs";
|
|
48883
49073
|
function isEmptyOrWhitespace(content) {
|
|
48884
49074
|
return content.trim().length === 0;
|
|
48885
49075
|
}
|
|
@@ -48889,7 +49079,7 @@ function parseOpenCodeConfigFileWithError(path3) {
|
|
|
48889
49079
|
if (stat.size === 0) {
|
|
48890
49080
|
return { config: null, error: `Config file is empty: ${path3}. Delete it or add valid JSON content.` };
|
|
48891
49081
|
}
|
|
48892
|
-
const content =
|
|
49082
|
+
const content = readFileSync5(path3, "utf-8");
|
|
48893
49083
|
if (isEmptyOrWhitespace(content)) {
|
|
48894
49084
|
return { config: null, error: `Config file contains only whitespace: ${path3}. Delete it or add valid JSON content.` };
|
|
48895
49085
|
}
|
|
@@ -48912,8 +49102,90 @@ var init_parse_opencode_config_file = __esm(() => {
|
|
|
48912
49102
|
init_shared();
|
|
48913
49103
|
});
|
|
48914
49104
|
|
|
49105
|
+
// src/cli/config-manager/version-compatibility.ts
|
|
49106
|
+
function parseVersion2(version) {
|
|
49107
|
+
const clean = version.replace(/^v/, "").split("-")[0];
|
|
49108
|
+
return clean.split(".").map(Number);
|
|
49109
|
+
}
|
|
49110
|
+
function compareVersions2(a, b) {
|
|
49111
|
+
const partsA = parseVersion2(a);
|
|
49112
|
+
const partsB = parseVersion2(b);
|
|
49113
|
+
const maxLen = Math.max(partsA.length, partsB.length);
|
|
49114
|
+
for (let i2 = 0;i2 < maxLen; i2++) {
|
|
49115
|
+
const numA = partsA[i2] ?? 0;
|
|
49116
|
+
const numB = partsB[i2] ?? 0;
|
|
49117
|
+
if (numA !== numB) {
|
|
49118
|
+
return numA - numB;
|
|
49119
|
+
}
|
|
49120
|
+
}
|
|
49121
|
+
return 0;
|
|
49122
|
+
}
|
|
49123
|
+
function checkVersionCompatibility(currentVersion, newVersion) {
|
|
49124
|
+
if (!currentVersion) {
|
|
49125
|
+
return {
|
|
49126
|
+
canUpgrade: true,
|
|
49127
|
+
isDowngrade: false,
|
|
49128
|
+
isMajorBump: false,
|
|
49129
|
+
requiresMigration: false
|
|
49130
|
+
};
|
|
49131
|
+
}
|
|
49132
|
+
const cleanCurrent = currentVersion.replace(/^v/, "");
|
|
49133
|
+
const cleanNew = newVersion.replace(/^v/, "");
|
|
49134
|
+
try {
|
|
49135
|
+
const comparison = compareVersions2(cleanNew, cleanCurrent);
|
|
49136
|
+
if (comparison < 0) {
|
|
49137
|
+
return {
|
|
49138
|
+
canUpgrade: false,
|
|
49139
|
+
reason: `Downgrade from ${currentVersion} to ${newVersion} is not allowed`,
|
|
49140
|
+
isDowngrade: true,
|
|
49141
|
+
isMajorBump: false,
|
|
49142
|
+
requiresMigration: false
|
|
49143
|
+
};
|
|
49144
|
+
}
|
|
49145
|
+
if (comparison === 0) {
|
|
49146
|
+
return {
|
|
49147
|
+
canUpgrade: true,
|
|
49148
|
+
reason: `Version ${newVersion} is already installed`,
|
|
49149
|
+
isDowngrade: false,
|
|
49150
|
+
isMajorBump: false,
|
|
49151
|
+
requiresMigration: false
|
|
49152
|
+
};
|
|
49153
|
+
}
|
|
49154
|
+
const currentMajor = cleanCurrent.split(".")[0];
|
|
49155
|
+
const newMajor = cleanNew.split(".")[0];
|
|
49156
|
+
const isMajorBump = currentMajor !== newMajor;
|
|
49157
|
+
if (isMajorBump) {
|
|
49158
|
+
return {
|
|
49159
|
+
canUpgrade: true,
|
|
49160
|
+
reason: `Major version upgrade from ${currentVersion} to ${newVersion} - configuration migration may be required`,
|
|
49161
|
+
isDowngrade: false,
|
|
49162
|
+
isMajorBump: true,
|
|
49163
|
+
requiresMigration: true
|
|
49164
|
+
};
|
|
49165
|
+
}
|
|
49166
|
+
return {
|
|
49167
|
+
canUpgrade: true,
|
|
49168
|
+
isDowngrade: false,
|
|
49169
|
+
isMajorBump: false,
|
|
49170
|
+
requiresMigration: false
|
|
49171
|
+
};
|
|
49172
|
+
} catch {
|
|
49173
|
+
return {
|
|
49174
|
+
canUpgrade: true,
|
|
49175
|
+
reason: `Unable to compare versions ${currentVersion} and ${newVersion} - proceeding with caution`,
|
|
49176
|
+
isDowngrade: false,
|
|
49177
|
+
isMajorBump: false,
|
|
49178
|
+
requiresMigration: false
|
|
49179
|
+
};
|
|
49180
|
+
}
|
|
49181
|
+
}
|
|
49182
|
+
function extractVersionFromPluginEntry(entry) {
|
|
49183
|
+
const match = entry.match(/@(.+)$/);
|
|
49184
|
+
return match ? match[1] : null;
|
|
49185
|
+
}
|
|
49186
|
+
|
|
48915
49187
|
// src/cli/config-manager/add-plugin-to-opencode-config.ts
|
|
48916
|
-
import { readFileSync as
|
|
49188
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync3 } from "fs";
|
|
48917
49189
|
async function addPluginToOpenCodeConfig(currentVersion) {
|
|
48918
49190
|
try {
|
|
48919
49191
|
ensureConfigDirectoryExists();
|
|
@@ -48946,19 +49218,35 @@ async function addPluginToOpenCodeConfig(currentVersion) {
|
|
|
48946
49218
|
const canonicalEntries = plugins.filter((plugin) => plugin === PLUGIN_NAME || plugin.startsWith(`${PLUGIN_NAME}@`));
|
|
48947
49219
|
const legacyEntries = plugins.filter((plugin) => plugin === LEGACY_PLUGIN_NAME || plugin.startsWith(`${LEGACY_PLUGIN_NAME}@`));
|
|
48948
49220
|
const otherPlugins = plugins.filter((plugin) => !(plugin === PLUGIN_NAME || plugin.startsWith(`${PLUGIN_NAME}@`)) && !(plugin === LEGACY_PLUGIN_NAME || plugin.startsWith(`${LEGACY_PLUGIN_NAME}@`)));
|
|
49221
|
+
const existingEntry = canonicalEntries[0] ?? legacyEntries[0];
|
|
49222
|
+
if (existingEntry) {
|
|
49223
|
+
const installedVersion = extractVersionFromPluginEntry(existingEntry);
|
|
49224
|
+
const compatibility = checkVersionCompatibility(installedVersion, currentVersion);
|
|
49225
|
+
if (!compatibility.canUpgrade) {
|
|
49226
|
+
return {
|
|
49227
|
+
success: false,
|
|
49228
|
+
configPath: path3,
|
|
49229
|
+
error: compatibility.reason ?? "Version compatibility check failed"
|
|
49230
|
+
};
|
|
49231
|
+
}
|
|
49232
|
+
const backupResult = backupConfigFile(path3);
|
|
49233
|
+
if (!backupResult.success) {
|
|
49234
|
+
return {
|
|
49235
|
+
success: false,
|
|
49236
|
+
configPath: path3,
|
|
49237
|
+
error: `Failed to create backup: ${backupResult.error}`
|
|
49238
|
+
};
|
|
49239
|
+
}
|
|
49240
|
+
}
|
|
48949
49241
|
const normalizedPlugins = [...otherPlugins];
|
|
48950
|
-
if (canonicalEntries.length > 0) {
|
|
48951
|
-
normalizedPlugins.push(
|
|
48952
|
-
} else if (legacyEntries.length > 0) {
|
|
48953
|
-
const versionMatch = legacyEntries[0].match(/@(.+)$/);
|
|
48954
|
-
const preservedVersion = versionMatch ? versionMatch[1] : null;
|
|
48955
|
-
normalizedPlugins.push(preservedVersion ? `${PLUGIN_NAME}@${preservedVersion}` : pluginEntry);
|
|
49242
|
+
if (canonicalEntries.length > 0 || legacyEntries.length > 0) {
|
|
49243
|
+
normalizedPlugins.push(pluginEntry);
|
|
48956
49244
|
} else {
|
|
48957
49245
|
normalizedPlugins.push(pluginEntry);
|
|
48958
49246
|
}
|
|
48959
49247
|
config.plugin = normalizedPlugins;
|
|
48960
49248
|
if (format2 === "jsonc") {
|
|
48961
|
-
const content =
|
|
49249
|
+
const content = readFileSync6(path3, "utf-8");
|
|
48962
49250
|
const pluginArrayRegex = /((?:"plugin"|plugin)\s*:\s*)\[([\s\S]*?)\]/;
|
|
48963
49251
|
const match = content.match(pluginArrayRegex);
|
|
48964
49252
|
if (match) {
|
|
@@ -48988,6 +49276,7 @@ async function addPluginToOpenCodeConfig(currentVersion) {
|
|
|
48988
49276
|
}
|
|
48989
49277
|
var init_add_plugin_to_opencode_config = __esm(() => {
|
|
48990
49278
|
init_shared();
|
|
49279
|
+
init_backup_config();
|
|
48991
49280
|
init_config_context();
|
|
48992
49281
|
init_ensure_config_directory_exists();
|
|
48993
49282
|
init_opencode_config_format();
|
|
@@ -49103,6 +49392,47 @@ var init_fallback_chain_resolution = __esm(() => {
|
|
|
49103
49392
|
});
|
|
49104
49393
|
|
|
49105
49394
|
// src/cli/model-fallback.ts
|
|
49395
|
+
function toFallbackModelObject(entry, provider) {
|
|
49396
|
+
return {
|
|
49397
|
+
model: `${provider}/${transformModelForProvider(provider, entry.model)}`,
|
|
49398
|
+
...entry.variant ? { variant: entry.variant } : {},
|
|
49399
|
+
...entry.reasoningEffort ? { reasoningEffort: entry.reasoningEffort } : {},
|
|
49400
|
+
...entry.temperature !== undefined ? { temperature: entry.temperature } : {},
|
|
49401
|
+
...entry.top_p !== undefined ? { top_p: entry.top_p } : {},
|
|
49402
|
+
...entry.maxTokens !== undefined ? { maxTokens: entry.maxTokens } : {},
|
|
49403
|
+
...entry.thinking ? { thinking: entry.thinking } : {}
|
|
49404
|
+
};
|
|
49405
|
+
}
|
|
49406
|
+
function collectAvailableFallbacks(fallbackChain, availability) {
|
|
49407
|
+
const expandedFallbacks = fallbackChain.flatMap((entry) => entry.providers.filter((provider) => isProviderAvailable(provider, availability)).map((provider) => toFallbackModelObject(entry, provider)));
|
|
49408
|
+
return expandedFallbacks.filter((entry, index, allEntries) => allEntries.findIndex((candidate) => candidate.model === entry.model && candidate.variant === entry.variant) === index);
|
|
49409
|
+
}
|
|
49410
|
+
function attachFallbackModels(config, fallbackChain, availability) {
|
|
49411
|
+
const uniqueFallbacks = collectAvailableFallbacks(fallbackChain, availability);
|
|
49412
|
+
const primaryIndex = uniqueFallbacks.findIndex((entry) => entry.model === config.model);
|
|
49413
|
+
if (primaryIndex === -1) {
|
|
49414
|
+
return config;
|
|
49415
|
+
}
|
|
49416
|
+
const fallbackModels = uniqueFallbacks.slice(primaryIndex + 1);
|
|
49417
|
+
if (fallbackModels.length === 0) {
|
|
49418
|
+
return config;
|
|
49419
|
+
}
|
|
49420
|
+
return {
|
|
49421
|
+
...config,
|
|
49422
|
+
fallback_models: fallbackModels
|
|
49423
|
+
};
|
|
49424
|
+
}
|
|
49425
|
+
function attachAllFallbackModels(config, fallbackChain, availability) {
|
|
49426
|
+
const uniqueFallbacks = collectAvailableFallbacks(fallbackChain, availability);
|
|
49427
|
+
const fallbackModels = uniqueFallbacks.filter((entry) => entry.model !== config.model);
|
|
49428
|
+
if (fallbackModels.length === 0) {
|
|
49429
|
+
return config;
|
|
49430
|
+
}
|
|
49431
|
+
return {
|
|
49432
|
+
...config,
|
|
49433
|
+
fallback_models: fallbackModels
|
|
49434
|
+
};
|
|
49435
|
+
}
|
|
49106
49436
|
function generateModelConfig(config) {
|
|
49107
49437
|
const avail = toProviderAvailability(config);
|
|
49108
49438
|
const hasAnyProvider = avail.native.claude || avail.native.openai || avail.native.gemini || avail.opencodeZen || avail.copilot || avail.zai || avail.kimiForCoding || avail.opencodeGo;
|
|
@@ -49117,25 +49447,31 @@ function generateModelConfig(config) {
|
|
|
49117
49447
|
const categories = {};
|
|
49118
49448
|
for (const [role, req] of Object.entries(CLI_AGENT_MODEL_REQUIREMENTS)) {
|
|
49119
49449
|
if (role === "librarian") {
|
|
49450
|
+
let agentConfig;
|
|
49120
49451
|
if (avail.opencodeGo) {
|
|
49121
|
-
|
|
49452
|
+
agentConfig = { model: "opencode-go/minimax-m2.7" };
|
|
49122
49453
|
} else if (avail.zai) {
|
|
49123
|
-
|
|
49454
|
+
agentConfig = { model: ZAI_MODEL };
|
|
49455
|
+
}
|
|
49456
|
+
if (agentConfig) {
|
|
49457
|
+
agents[role] = attachAllFallbackModels(agentConfig, req.fallbackChain, avail);
|
|
49124
49458
|
}
|
|
49125
49459
|
continue;
|
|
49126
49460
|
}
|
|
49127
49461
|
if (role === "explore") {
|
|
49462
|
+
let agentConfig;
|
|
49128
49463
|
if (avail.native.claude) {
|
|
49129
|
-
|
|
49464
|
+
agentConfig = { model: "anthropic/claude-haiku-4-5" };
|
|
49130
49465
|
} else if (avail.opencodeZen) {
|
|
49131
|
-
|
|
49466
|
+
agentConfig = { model: "opencode/claude-haiku-4-5" };
|
|
49132
49467
|
} else if (avail.opencodeGo) {
|
|
49133
|
-
|
|
49468
|
+
agentConfig = { model: "opencode-go/minimax-m2.7" };
|
|
49134
49469
|
} else if (avail.copilot) {
|
|
49135
|
-
|
|
49470
|
+
agentConfig = { model: "github-copilot/gpt-5-mini" };
|
|
49136
49471
|
} else {
|
|
49137
|
-
|
|
49472
|
+
agentConfig = { model: "opencode/gpt-5-nano" };
|
|
49138
49473
|
}
|
|
49474
|
+
agents[role] = attachAllFallbackModels(agentConfig, req.fallbackChain, avail);
|
|
49139
49475
|
continue;
|
|
49140
49476
|
}
|
|
49141
49477
|
if (role === "sisyphus") {
|
|
@@ -49146,7 +49482,8 @@ function generateModelConfig(config) {
|
|
|
49146
49482
|
const resolved2 = resolveModelFromChain(fallbackChain, avail);
|
|
49147
49483
|
if (resolved2) {
|
|
49148
49484
|
const variant = resolved2.variant ?? req.variant;
|
|
49149
|
-
|
|
49485
|
+
const agentConfig = variant ? { model: resolved2.model, variant } : { model: resolved2.model };
|
|
49486
|
+
agents[role] = attachFallbackModels(agentConfig, fallbackChain, avail);
|
|
49150
49487
|
}
|
|
49151
49488
|
continue;
|
|
49152
49489
|
}
|
|
@@ -49159,7 +49496,8 @@ function generateModelConfig(config) {
|
|
|
49159
49496
|
const resolved = resolveModelFromChain(req.fallbackChain, avail);
|
|
49160
49497
|
if (resolved) {
|
|
49161
49498
|
const variant = resolved.variant ?? req.variant;
|
|
49162
|
-
|
|
49499
|
+
const agentConfig = variant ? { model: resolved.model, variant } : { model: resolved.model };
|
|
49500
|
+
agents[role] = attachFallbackModels(agentConfig, req.fallbackChain, avail);
|
|
49163
49501
|
} else {
|
|
49164
49502
|
agents[role] = { model: ULTIMATE_FALLBACK };
|
|
49165
49503
|
}
|
|
@@ -49175,7 +49513,8 @@ function generateModelConfig(config) {
|
|
|
49175
49513
|
const resolved = resolveModelFromChain(fallbackChain, avail);
|
|
49176
49514
|
if (resolved) {
|
|
49177
49515
|
const variant = resolved.variant ?? req.variant;
|
|
49178
|
-
|
|
49516
|
+
const categoryConfig = variant ? { model: resolved.model, variant } : { model: resolved.model };
|
|
49517
|
+
categories[cat] = attachFallbackModels(categoryConfig, fallbackChain, avail);
|
|
49179
49518
|
} else {
|
|
49180
49519
|
categories[cat] = { model: ULTIMATE_FALLBACK };
|
|
49181
49520
|
}
|
|
@@ -49192,6 +49531,7 @@ var init_model_fallback = __esm(() => {
|
|
|
49192
49531
|
init_model_fallback_requirements();
|
|
49193
49532
|
init_openai_only_model_catalog();
|
|
49194
49533
|
init_fallback_chain_resolution();
|
|
49534
|
+
init_provider_model_id_transform();
|
|
49195
49535
|
});
|
|
49196
49536
|
|
|
49197
49537
|
// src/cli/config-manager/generate-omo-config.ts
|
|
@@ -49220,7 +49560,7 @@ function deepMergeRecord(target, source) {
|
|
|
49220
49560
|
}
|
|
49221
49561
|
|
|
49222
49562
|
// src/cli/config-manager/write-omo-config.ts
|
|
49223
|
-
import { existsSync as
|
|
49563
|
+
import { existsSync as existsSync11, readFileSync as readFileSync7, statSync as statSync2, writeFileSync as writeFileSync4 } from "fs";
|
|
49224
49564
|
function isEmptyOrWhitespace2(content) {
|
|
49225
49565
|
return content.trim().length === 0;
|
|
49226
49566
|
}
|
|
@@ -49237,10 +49577,18 @@ function writeOmoConfig(installConfig) {
|
|
|
49237
49577
|
const omoConfigPath = getOmoConfigPath();
|
|
49238
49578
|
try {
|
|
49239
49579
|
const newConfig = generateOmoConfig(installConfig);
|
|
49240
|
-
if (
|
|
49580
|
+
if (existsSync11(omoConfigPath)) {
|
|
49581
|
+
const backupResult = backupConfigFile(omoConfigPath);
|
|
49582
|
+
if (!backupResult.success) {
|
|
49583
|
+
return {
|
|
49584
|
+
success: false,
|
|
49585
|
+
configPath: omoConfigPath,
|
|
49586
|
+
error: `Failed to create backup: ${backupResult.error}`
|
|
49587
|
+
};
|
|
49588
|
+
}
|
|
49241
49589
|
try {
|
|
49242
49590
|
const stat = statSync2(omoConfigPath);
|
|
49243
|
-
const content =
|
|
49591
|
+
const content = readFileSync7(omoConfigPath, "utf-8");
|
|
49244
49592
|
if (stat.size === 0 || isEmptyOrWhitespace2(content)) {
|
|
49245
49593
|
writeFileSync4(omoConfigPath, JSON.stringify(newConfig, null, 2) + `
|
|
49246
49594
|
`);
|
|
@@ -49278,6 +49626,7 @@ function writeOmoConfig(installConfig) {
|
|
|
49278
49626
|
}
|
|
49279
49627
|
var init_write_omo_config = __esm(() => {
|
|
49280
49628
|
init_shared();
|
|
49629
|
+
init_backup_config();
|
|
49281
49630
|
init_config_context();
|
|
49282
49631
|
init_ensure_config_directory_exists();
|
|
49283
49632
|
init_generate_omo_config();
|
|
@@ -49368,7 +49717,7 @@ async function isOpenCodeInstalled() {
|
|
|
49368
49717
|
const result = await findOpenCodeBinaryWithVersion();
|
|
49369
49718
|
return result !== null;
|
|
49370
49719
|
}
|
|
49371
|
-
async function
|
|
49720
|
+
async function getOpenCodeVersion2() {
|
|
49372
49721
|
const result = await findOpenCodeBinaryWithVersion();
|
|
49373
49722
|
return result?.version ?? null;
|
|
49374
49723
|
}
|
|
@@ -49380,10 +49729,10 @@ var init_opencode_binary = __esm(() => {
|
|
|
49380
49729
|
});
|
|
49381
49730
|
|
|
49382
49731
|
// src/cli/config-manager/detect-current-config.ts
|
|
49383
|
-
import { existsSync as
|
|
49732
|
+
import { existsSync as existsSync12, readFileSync as readFileSync8 } from "fs";
|
|
49384
49733
|
function detectProvidersFromOmoConfig() {
|
|
49385
49734
|
const omoConfigPath = getOmoConfigPath();
|
|
49386
|
-
if (!
|
|
49735
|
+
if (!existsSync12(omoConfigPath)) {
|
|
49387
49736
|
return {
|
|
49388
49737
|
hasOpenAI: true,
|
|
49389
49738
|
hasOpencodeZen: true,
|
|
@@ -49393,7 +49742,7 @@ function detectProvidersFromOmoConfig() {
|
|
|
49393
49742
|
};
|
|
49394
49743
|
}
|
|
49395
49744
|
try {
|
|
49396
|
-
const content =
|
|
49745
|
+
const content = readFileSync8(omoConfigPath, "utf-8");
|
|
49397
49746
|
const omoConfig = parseJsonc(content);
|
|
49398
49747
|
if (!omoConfig || typeof omoConfig !== "object") {
|
|
49399
49748
|
return {
|
|
@@ -49424,9 +49773,13 @@ function detectProvidersFromOmoConfig() {
|
|
|
49424
49773
|
function isOurPlugin(plugin) {
|
|
49425
49774
|
return plugin === PLUGIN_NAME || plugin.startsWith(`${PLUGIN_NAME}@`) || plugin === LEGACY_PLUGIN_NAME || plugin.startsWith(`${LEGACY_PLUGIN_NAME}@`);
|
|
49426
49775
|
}
|
|
49776
|
+
function findOurPluginEntry(plugins) {
|
|
49777
|
+
return plugins.find(isOurPlugin) ?? null;
|
|
49778
|
+
}
|
|
49427
49779
|
function detectCurrentConfig() {
|
|
49428
49780
|
const result = {
|
|
49429
49781
|
isInstalled: false,
|
|
49782
|
+
installedVersion: null,
|
|
49430
49783
|
hasClaude: true,
|
|
49431
49784
|
isMax20: true,
|
|
49432
49785
|
hasOpenAI: true,
|
|
@@ -49447,7 +49800,11 @@ function detectCurrentConfig() {
|
|
|
49447
49800
|
}
|
|
49448
49801
|
const openCodeConfig = parseResult.config;
|
|
49449
49802
|
const plugins = openCodeConfig.plugin ?? [];
|
|
49450
|
-
|
|
49803
|
+
const ourPluginEntry = findOurPluginEntry(plugins);
|
|
49804
|
+
result.isInstalled = !!ourPluginEntry;
|
|
49805
|
+
if (ourPluginEntry) {
|
|
49806
|
+
result.installedVersion = extractVersionFromPluginEntry(ourPluginEntry);
|
|
49807
|
+
}
|
|
49451
49808
|
if (!result.isInstalled) {
|
|
49452
49809
|
return result;
|
|
49453
49810
|
}
|
|
@@ -49469,10 +49826,10 @@ var init_detect_current_config = __esm(() => {
|
|
|
49469
49826
|
});
|
|
49470
49827
|
|
|
49471
49828
|
// src/cli/config-manager/bun-install.ts
|
|
49472
|
-
import { existsSync as
|
|
49473
|
-
import { join as
|
|
49829
|
+
import { existsSync as existsSync13 } from "fs";
|
|
49830
|
+
import { join as join11 } from "path";
|
|
49474
49831
|
function getDefaultWorkspaceDir() {
|
|
49475
|
-
return
|
|
49832
|
+
return join11(getOpenCodeCacheDir(), "packages");
|
|
49476
49833
|
}
|
|
49477
49834
|
function readProcessOutput(stream) {
|
|
49478
49835
|
if (!stream) {
|
|
@@ -49498,7 +49855,7 @@ async function runBunInstallWithDetails(options) {
|
|
|
49498
49855
|
const outputMode = options?.outputMode ?? "pipe";
|
|
49499
49856
|
const cacheDir = options?.workspaceDir ?? getDefaultWorkspaceDir();
|
|
49500
49857
|
const packageJsonPath = `${cacheDir}/package.json`;
|
|
49501
|
-
if (!
|
|
49858
|
+
if (!existsSync13(packageJsonPath)) {
|
|
49502
49859
|
return {
|
|
49503
49860
|
success: false,
|
|
49504
49861
|
error: `Workspace not initialized: ${packageJsonPath} not found. OpenCode should create this on first run.`
|
|
@@ -49574,6 +49931,7 @@ var init_config_manager = __esm(() => {
|
|
|
49574
49931
|
init_opencode_binary();
|
|
49575
49932
|
init_detect_current_config();
|
|
49576
49933
|
init_bun_install();
|
|
49934
|
+
init_backup_config();
|
|
49577
49935
|
});
|
|
49578
49936
|
|
|
49579
49937
|
// node_modules/sisteransi/src/index.js
|
|
@@ -49634,6 +49992,462 @@ var require_src = __commonJS((exports, module) => {
|
|
|
49634
49992
|
module.exports = { cursor, scroll, erase, beep };
|
|
49635
49993
|
});
|
|
49636
49994
|
|
|
49995
|
+
// node_modules/isexe/windows.js
|
|
49996
|
+
var require_windows = __commonJS((exports, module) => {
|
|
49997
|
+
module.exports = isexe;
|
|
49998
|
+
isexe.sync = sync;
|
|
49999
|
+
var fs4 = __require("fs");
|
|
50000
|
+
function checkPathExt(path4, options) {
|
|
50001
|
+
var pathext = options.pathExt !== undefined ? options.pathExt : process.env.PATHEXT;
|
|
50002
|
+
if (!pathext) {
|
|
50003
|
+
return true;
|
|
50004
|
+
}
|
|
50005
|
+
pathext = pathext.split(";");
|
|
50006
|
+
if (pathext.indexOf("") !== -1) {
|
|
50007
|
+
return true;
|
|
50008
|
+
}
|
|
50009
|
+
for (var i2 = 0;i2 < pathext.length; i2++) {
|
|
50010
|
+
var p2 = pathext[i2].toLowerCase();
|
|
50011
|
+
if (p2 && path4.substr(-p2.length).toLowerCase() === p2) {
|
|
50012
|
+
return true;
|
|
50013
|
+
}
|
|
50014
|
+
}
|
|
50015
|
+
return false;
|
|
50016
|
+
}
|
|
50017
|
+
function checkStat(stat, path4, options) {
|
|
50018
|
+
if (!stat.isSymbolicLink() && !stat.isFile()) {
|
|
50019
|
+
return false;
|
|
50020
|
+
}
|
|
50021
|
+
return checkPathExt(path4, options);
|
|
50022
|
+
}
|
|
50023
|
+
function isexe(path4, options, cb) {
|
|
50024
|
+
fs4.stat(path4, function(er, stat) {
|
|
50025
|
+
cb(er, er ? false : checkStat(stat, path4, options));
|
|
50026
|
+
});
|
|
50027
|
+
}
|
|
50028
|
+
function sync(path4, options) {
|
|
50029
|
+
return checkStat(fs4.statSync(path4), path4, options);
|
|
50030
|
+
}
|
|
50031
|
+
});
|
|
50032
|
+
|
|
50033
|
+
// node_modules/isexe/mode.js
|
|
50034
|
+
var require_mode = __commonJS((exports, module) => {
|
|
50035
|
+
module.exports = isexe;
|
|
50036
|
+
isexe.sync = sync;
|
|
50037
|
+
var fs4 = __require("fs");
|
|
50038
|
+
function isexe(path4, options, cb) {
|
|
50039
|
+
fs4.stat(path4, function(er, stat) {
|
|
50040
|
+
cb(er, er ? false : checkStat(stat, options));
|
|
50041
|
+
});
|
|
50042
|
+
}
|
|
50043
|
+
function sync(path4, options) {
|
|
50044
|
+
return checkStat(fs4.statSync(path4), options);
|
|
50045
|
+
}
|
|
50046
|
+
function checkStat(stat, options) {
|
|
50047
|
+
return stat.isFile() && checkMode(stat, options);
|
|
50048
|
+
}
|
|
50049
|
+
function checkMode(stat, options) {
|
|
50050
|
+
var mod = stat.mode;
|
|
50051
|
+
var uid = stat.uid;
|
|
50052
|
+
var gid = stat.gid;
|
|
50053
|
+
var myUid = options.uid !== undefined ? options.uid : process.getuid && process.getuid();
|
|
50054
|
+
var myGid = options.gid !== undefined ? options.gid : process.getgid && process.getgid();
|
|
50055
|
+
var u2 = parseInt("100", 8);
|
|
50056
|
+
var g2 = parseInt("010", 8);
|
|
50057
|
+
var o2 = parseInt("001", 8);
|
|
50058
|
+
var ug = u2 | g2;
|
|
50059
|
+
var ret = mod & o2 || mod & g2 && gid === myGid || mod & u2 && uid === myUid || mod & ug && myUid === 0;
|
|
50060
|
+
return ret;
|
|
50061
|
+
}
|
|
50062
|
+
});
|
|
50063
|
+
|
|
50064
|
+
// node_modules/isexe/index.js
|
|
50065
|
+
var require_isexe = __commonJS((exports, module) => {
|
|
50066
|
+
var fs4 = __require("fs");
|
|
50067
|
+
var core3;
|
|
50068
|
+
if (process.platform === "win32" || global.TESTING_WINDOWS) {
|
|
50069
|
+
core3 = require_windows();
|
|
50070
|
+
} else {
|
|
50071
|
+
core3 = require_mode();
|
|
50072
|
+
}
|
|
50073
|
+
module.exports = isexe;
|
|
50074
|
+
isexe.sync = sync;
|
|
50075
|
+
function isexe(path4, options, cb) {
|
|
50076
|
+
if (typeof options === "function") {
|
|
50077
|
+
cb = options;
|
|
50078
|
+
options = {};
|
|
50079
|
+
}
|
|
50080
|
+
if (!cb) {
|
|
50081
|
+
if (typeof Promise !== "function") {
|
|
50082
|
+
throw new TypeError("callback not provided");
|
|
50083
|
+
}
|
|
50084
|
+
return new Promise(function(resolve2, reject) {
|
|
50085
|
+
isexe(path4, options || {}, function(er, is) {
|
|
50086
|
+
if (er) {
|
|
50087
|
+
reject(er);
|
|
50088
|
+
} else {
|
|
50089
|
+
resolve2(is);
|
|
50090
|
+
}
|
|
50091
|
+
});
|
|
50092
|
+
});
|
|
50093
|
+
}
|
|
50094
|
+
core3(path4, options || {}, function(er, is) {
|
|
50095
|
+
if (er) {
|
|
50096
|
+
if (er.code === "EACCES" || options && options.ignoreErrors) {
|
|
50097
|
+
er = null;
|
|
50098
|
+
is = false;
|
|
50099
|
+
}
|
|
50100
|
+
}
|
|
50101
|
+
cb(er, is);
|
|
50102
|
+
});
|
|
50103
|
+
}
|
|
50104
|
+
function sync(path4, options) {
|
|
50105
|
+
try {
|
|
50106
|
+
return core3.sync(path4, options || {});
|
|
50107
|
+
} catch (er) {
|
|
50108
|
+
if (options && options.ignoreErrors || er.code === "EACCES") {
|
|
50109
|
+
return false;
|
|
50110
|
+
} else {
|
|
50111
|
+
throw er;
|
|
50112
|
+
}
|
|
50113
|
+
}
|
|
50114
|
+
}
|
|
50115
|
+
});
|
|
50116
|
+
|
|
50117
|
+
// node_modules/which/which.js
|
|
50118
|
+
var require_which = __commonJS((exports, module) => {
|
|
50119
|
+
var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
|
|
50120
|
+
var path4 = __require("path");
|
|
50121
|
+
var COLON = isWindows ? ";" : ":";
|
|
50122
|
+
var isexe = require_isexe();
|
|
50123
|
+
var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
|
|
50124
|
+
var getPathInfo = (cmd, opt) => {
|
|
50125
|
+
const colon = opt.colon || COLON;
|
|
50126
|
+
const pathEnv = cmd.match(/\//) || isWindows && cmd.match(/\\/) ? [""] : [
|
|
50127
|
+
...isWindows ? [process.cwd()] : [],
|
|
50128
|
+
...(opt.path || process.env.PATH || "").split(colon)
|
|
50129
|
+
];
|
|
50130
|
+
const pathExtExe = isWindows ? opt.pathExt || process.env.PATHEXT || ".EXE;.CMD;.BAT;.COM" : "";
|
|
50131
|
+
const pathExt = isWindows ? pathExtExe.split(colon) : [""];
|
|
50132
|
+
if (isWindows) {
|
|
50133
|
+
if (cmd.indexOf(".") !== -1 && pathExt[0] !== "")
|
|
50134
|
+
pathExt.unshift("");
|
|
50135
|
+
}
|
|
50136
|
+
return {
|
|
50137
|
+
pathEnv,
|
|
50138
|
+
pathExt,
|
|
50139
|
+
pathExtExe
|
|
50140
|
+
};
|
|
50141
|
+
};
|
|
50142
|
+
var which = (cmd, opt, cb) => {
|
|
50143
|
+
if (typeof opt === "function") {
|
|
50144
|
+
cb = opt;
|
|
50145
|
+
opt = {};
|
|
50146
|
+
}
|
|
50147
|
+
if (!opt)
|
|
50148
|
+
opt = {};
|
|
50149
|
+
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
50150
|
+
const found = [];
|
|
50151
|
+
const step = (i2) => new Promise((resolve2, reject) => {
|
|
50152
|
+
if (i2 === pathEnv.length)
|
|
50153
|
+
return opt.all && found.length ? resolve2(found) : reject(getNotFoundError(cmd));
|
|
50154
|
+
const ppRaw = pathEnv[i2];
|
|
50155
|
+
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
50156
|
+
const pCmd = path4.join(pathPart, cmd);
|
|
50157
|
+
const p2 = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
50158
|
+
resolve2(subStep(p2, i2, 0));
|
|
50159
|
+
});
|
|
50160
|
+
const subStep = (p2, i2, ii) => new Promise((resolve2, reject) => {
|
|
50161
|
+
if (ii === pathExt.length)
|
|
50162
|
+
return resolve2(step(i2 + 1));
|
|
50163
|
+
const ext = pathExt[ii];
|
|
50164
|
+
isexe(p2 + ext, { pathExt: pathExtExe }, (er, is) => {
|
|
50165
|
+
if (!er && is) {
|
|
50166
|
+
if (opt.all)
|
|
50167
|
+
found.push(p2 + ext);
|
|
50168
|
+
else
|
|
50169
|
+
return resolve2(p2 + ext);
|
|
50170
|
+
}
|
|
50171
|
+
return resolve2(subStep(p2, i2, ii + 1));
|
|
50172
|
+
});
|
|
50173
|
+
});
|
|
50174
|
+
return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
|
|
50175
|
+
};
|
|
50176
|
+
var whichSync = (cmd, opt) => {
|
|
50177
|
+
opt = opt || {};
|
|
50178
|
+
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
50179
|
+
const found = [];
|
|
50180
|
+
for (let i2 = 0;i2 < pathEnv.length; i2++) {
|
|
50181
|
+
const ppRaw = pathEnv[i2];
|
|
50182
|
+
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
50183
|
+
const pCmd = path4.join(pathPart, cmd);
|
|
50184
|
+
const p2 = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
50185
|
+
for (let j2 = 0;j2 < pathExt.length; j2++) {
|
|
50186
|
+
const cur = p2 + pathExt[j2];
|
|
50187
|
+
try {
|
|
50188
|
+
const is = isexe.sync(cur, { pathExt: pathExtExe });
|
|
50189
|
+
if (is) {
|
|
50190
|
+
if (opt.all)
|
|
50191
|
+
found.push(cur);
|
|
50192
|
+
else
|
|
50193
|
+
return cur;
|
|
50194
|
+
}
|
|
50195
|
+
} catch (ex) {}
|
|
50196
|
+
}
|
|
50197
|
+
}
|
|
50198
|
+
if (opt.all && found.length)
|
|
50199
|
+
return found;
|
|
50200
|
+
if (opt.nothrow)
|
|
50201
|
+
return null;
|
|
50202
|
+
throw getNotFoundError(cmd);
|
|
50203
|
+
};
|
|
50204
|
+
module.exports = which;
|
|
50205
|
+
which.sync = whichSync;
|
|
50206
|
+
});
|
|
50207
|
+
|
|
50208
|
+
// node_modules/path-key/index.js
|
|
50209
|
+
var require_path_key = __commonJS((exports, module) => {
|
|
50210
|
+
var pathKey = (options = {}) => {
|
|
50211
|
+
const environment = options.env || process.env;
|
|
50212
|
+
const platform = options.platform || process.platform;
|
|
50213
|
+
if (platform !== "win32") {
|
|
50214
|
+
return "PATH";
|
|
50215
|
+
}
|
|
50216
|
+
return Object.keys(environment).reverse().find((key) => key.toUpperCase() === "PATH") || "Path";
|
|
50217
|
+
};
|
|
50218
|
+
module.exports = pathKey;
|
|
50219
|
+
module.exports.default = pathKey;
|
|
50220
|
+
});
|
|
50221
|
+
|
|
50222
|
+
// node_modules/cross-spawn/lib/util/resolveCommand.js
|
|
50223
|
+
var require_resolveCommand = __commonJS((exports, module) => {
|
|
50224
|
+
var path4 = __require("path");
|
|
50225
|
+
var which = require_which();
|
|
50226
|
+
var getPathKey = require_path_key();
|
|
50227
|
+
function resolveCommandAttempt(parsed, withoutPathExt) {
|
|
50228
|
+
const env = parsed.options.env || process.env;
|
|
50229
|
+
const cwd = process.cwd();
|
|
50230
|
+
const hasCustomCwd = parsed.options.cwd != null;
|
|
50231
|
+
const shouldSwitchCwd = hasCustomCwd && process.chdir !== undefined && !process.chdir.disabled;
|
|
50232
|
+
if (shouldSwitchCwd) {
|
|
50233
|
+
try {
|
|
50234
|
+
process.chdir(parsed.options.cwd);
|
|
50235
|
+
} catch (err) {}
|
|
50236
|
+
}
|
|
50237
|
+
let resolved;
|
|
50238
|
+
try {
|
|
50239
|
+
resolved = which.sync(parsed.command, {
|
|
50240
|
+
path: env[getPathKey({ env })],
|
|
50241
|
+
pathExt: withoutPathExt ? path4.delimiter : undefined
|
|
50242
|
+
});
|
|
50243
|
+
} catch (e2) {} finally {
|
|
50244
|
+
if (shouldSwitchCwd) {
|
|
50245
|
+
process.chdir(cwd);
|
|
50246
|
+
}
|
|
50247
|
+
}
|
|
50248
|
+
if (resolved) {
|
|
50249
|
+
resolved = path4.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
|
|
50250
|
+
}
|
|
50251
|
+
return resolved;
|
|
50252
|
+
}
|
|
50253
|
+
function resolveCommand(parsed) {
|
|
50254
|
+
return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true);
|
|
50255
|
+
}
|
|
50256
|
+
module.exports = resolveCommand;
|
|
50257
|
+
});
|
|
50258
|
+
|
|
50259
|
+
// node_modules/cross-spawn/lib/util/escape.js
|
|
50260
|
+
var require_escape = __commonJS((exports, module) => {
|
|
50261
|
+
var metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g;
|
|
50262
|
+
function escapeCommand(arg) {
|
|
50263
|
+
arg = arg.replace(metaCharsRegExp, "^$1");
|
|
50264
|
+
return arg;
|
|
50265
|
+
}
|
|
50266
|
+
function escapeArgument(arg, doubleEscapeMetaChars) {
|
|
50267
|
+
arg = `${arg}`;
|
|
50268
|
+
arg = arg.replace(/(?=(\\+?)?)\1"/g, "$1$1\\\"");
|
|
50269
|
+
arg = arg.replace(/(?=(\\+?)?)\1$/, "$1$1");
|
|
50270
|
+
arg = `"${arg}"`;
|
|
50271
|
+
arg = arg.replace(metaCharsRegExp, "^$1");
|
|
50272
|
+
if (doubleEscapeMetaChars) {
|
|
50273
|
+
arg = arg.replace(metaCharsRegExp, "^$1");
|
|
50274
|
+
}
|
|
50275
|
+
return arg;
|
|
50276
|
+
}
|
|
50277
|
+
exports.command = escapeCommand;
|
|
50278
|
+
exports.argument = escapeArgument;
|
|
50279
|
+
});
|
|
50280
|
+
|
|
50281
|
+
// node_modules/shebang-regex/index.js
|
|
50282
|
+
var require_shebang_regex = __commonJS((exports, module) => {
|
|
50283
|
+
module.exports = /^#!(.*)/;
|
|
50284
|
+
});
|
|
50285
|
+
|
|
50286
|
+
// node_modules/shebang-command/index.js
|
|
50287
|
+
var require_shebang_command = __commonJS((exports, module) => {
|
|
50288
|
+
var shebangRegex = require_shebang_regex();
|
|
50289
|
+
module.exports = (string4 = "") => {
|
|
50290
|
+
const match = string4.match(shebangRegex);
|
|
50291
|
+
if (!match) {
|
|
50292
|
+
return null;
|
|
50293
|
+
}
|
|
50294
|
+
const [path4, argument] = match[0].replace(/#! ?/, "").split(" ");
|
|
50295
|
+
const binary2 = path4.split("/").pop();
|
|
50296
|
+
if (binary2 === "env") {
|
|
50297
|
+
return argument;
|
|
50298
|
+
}
|
|
50299
|
+
return argument ? `${binary2} ${argument}` : binary2;
|
|
50300
|
+
};
|
|
50301
|
+
});
|
|
50302
|
+
|
|
50303
|
+
// node_modules/cross-spawn/lib/util/readShebang.js
|
|
50304
|
+
var require_readShebang = __commonJS((exports, module) => {
|
|
50305
|
+
var fs4 = __require("fs");
|
|
50306
|
+
var shebangCommand = require_shebang_command();
|
|
50307
|
+
function readShebang(command) {
|
|
50308
|
+
const size = 150;
|
|
50309
|
+
const buffer2 = Buffer.alloc(size);
|
|
50310
|
+
let fd;
|
|
50311
|
+
try {
|
|
50312
|
+
fd = fs4.openSync(command, "r");
|
|
50313
|
+
fs4.readSync(fd, buffer2, 0, size, 0);
|
|
50314
|
+
fs4.closeSync(fd);
|
|
50315
|
+
} catch (e2) {}
|
|
50316
|
+
return shebangCommand(buffer2.toString());
|
|
50317
|
+
}
|
|
50318
|
+
module.exports = readShebang;
|
|
50319
|
+
});
|
|
50320
|
+
|
|
50321
|
+
// node_modules/cross-spawn/lib/parse.js
|
|
50322
|
+
var require_parse = __commonJS((exports, module) => {
|
|
50323
|
+
var path4 = __require("path");
|
|
50324
|
+
var resolveCommand = require_resolveCommand();
|
|
50325
|
+
var escape = require_escape();
|
|
50326
|
+
var readShebang = require_readShebang();
|
|
50327
|
+
var isWin = process.platform === "win32";
|
|
50328
|
+
var isExecutableRegExp = /\.(?:com|exe)$/i;
|
|
50329
|
+
var isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;
|
|
50330
|
+
function detectShebang(parsed) {
|
|
50331
|
+
parsed.file = resolveCommand(parsed);
|
|
50332
|
+
const shebang = parsed.file && readShebang(parsed.file);
|
|
50333
|
+
if (shebang) {
|
|
50334
|
+
parsed.args.unshift(parsed.file);
|
|
50335
|
+
parsed.command = shebang;
|
|
50336
|
+
return resolveCommand(parsed);
|
|
50337
|
+
}
|
|
50338
|
+
return parsed.file;
|
|
50339
|
+
}
|
|
50340
|
+
function parseNonShell(parsed) {
|
|
50341
|
+
if (!isWin) {
|
|
50342
|
+
return parsed;
|
|
50343
|
+
}
|
|
50344
|
+
const commandFile = detectShebang(parsed);
|
|
50345
|
+
const needsShell = !isExecutableRegExp.test(commandFile);
|
|
50346
|
+
if (parsed.options.forceShell || needsShell) {
|
|
50347
|
+
const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
|
|
50348
|
+
parsed.command = path4.normalize(parsed.command);
|
|
50349
|
+
parsed.command = escape.command(parsed.command);
|
|
50350
|
+
parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars));
|
|
50351
|
+
const shellCommand = [parsed.command].concat(parsed.args).join(" ");
|
|
50352
|
+
parsed.args = ["/d", "/s", "/c", `"${shellCommand}"`];
|
|
50353
|
+
parsed.command = process.env.comspec || "cmd.exe";
|
|
50354
|
+
parsed.options.windowsVerbatimArguments = true;
|
|
50355
|
+
}
|
|
50356
|
+
return parsed;
|
|
50357
|
+
}
|
|
50358
|
+
function parse7(command, args, options) {
|
|
50359
|
+
if (args && !Array.isArray(args)) {
|
|
50360
|
+
options = args;
|
|
50361
|
+
args = null;
|
|
50362
|
+
}
|
|
50363
|
+
args = args ? args.slice(0) : [];
|
|
50364
|
+
options = Object.assign({}, options);
|
|
50365
|
+
const parsed = {
|
|
50366
|
+
command,
|
|
50367
|
+
args,
|
|
50368
|
+
options,
|
|
50369
|
+
file: undefined,
|
|
50370
|
+
original: {
|
|
50371
|
+
command,
|
|
50372
|
+
args
|
|
50373
|
+
}
|
|
50374
|
+
};
|
|
50375
|
+
return options.shell ? parsed : parseNonShell(parsed);
|
|
50376
|
+
}
|
|
50377
|
+
module.exports = parse7;
|
|
50378
|
+
});
|
|
50379
|
+
|
|
50380
|
+
// node_modules/cross-spawn/lib/enoent.js
|
|
50381
|
+
var require_enoent = __commonJS((exports, module) => {
|
|
50382
|
+
var isWin = process.platform === "win32";
|
|
50383
|
+
function notFoundError(original, syscall) {
|
|
50384
|
+
return Object.assign(new Error(`${syscall} ${original.command} ENOENT`), {
|
|
50385
|
+
code: "ENOENT",
|
|
50386
|
+
errno: "ENOENT",
|
|
50387
|
+
syscall: `${syscall} ${original.command}`,
|
|
50388
|
+
path: original.command,
|
|
50389
|
+
spawnargs: original.args
|
|
50390
|
+
});
|
|
50391
|
+
}
|
|
50392
|
+
function hookChildProcess(cp, parsed) {
|
|
50393
|
+
if (!isWin) {
|
|
50394
|
+
return;
|
|
50395
|
+
}
|
|
50396
|
+
const originalEmit = cp.emit;
|
|
50397
|
+
cp.emit = function(name, arg1) {
|
|
50398
|
+
if (name === "exit") {
|
|
50399
|
+
const err = verifyENOENT(arg1, parsed);
|
|
50400
|
+
if (err) {
|
|
50401
|
+
return originalEmit.call(cp, "error", err);
|
|
50402
|
+
}
|
|
50403
|
+
}
|
|
50404
|
+
return originalEmit.apply(cp, arguments);
|
|
50405
|
+
};
|
|
50406
|
+
}
|
|
50407
|
+
function verifyENOENT(status, parsed) {
|
|
50408
|
+
if (isWin && status === 1 && !parsed.file) {
|
|
50409
|
+
return notFoundError(parsed.original, "spawn");
|
|
50410
|
+
}
|
|
50411
|
+
return null;
|
|
50412
|
+
}
|
|
50413
|
+
function verifyENOENTSync(status, parsed) {
|
|
50414
|
+
if (isWin && status === 1 && !parsed.file) {
|
|
50415
|
+
return notFoundError(parsed.original, "spawnSync");
|
|
50416
|
+
}
|
|
50417
|
+
return null;
|
|
50418
|
+
}
|
|
50419
|
+
module.exports = {
|
|
50420
|
+
hookChildProcess,
|
|
50421
|
+
verifyENOENT,
|
|
50422
|
+
verifyENOENTSync,
|
|
50423
|
+
notFoundError
|
|
50424
|
+
};
|
|
50425
|
+
});
|
|
50426
|
+
|
|
50427
|
+
// node_modules/cross-spawn/index.js
|
|
50428
|
+
var require_cross_spawn = __commonJS((exports, module) => {
|
|
50429
|
+
var cp = __require("child_process");
|
|
50430
|
+
var parse7 = require_parse();
|
|
50431
|
+
var enoent = require_enoent();
|
|
50432
|
+
function spawn(command, args, options) {
|
|
50433
|
+
const parsed = parse7(command, args, options);
|
|
50434
|
+
const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);
|
|
50435
|
+
enoent.hookChildProcess(spawned, parsed);
|
|
50436
|
+
return spawned;
|
|
50437
|
+
}
|
|
50438
|
+
function spawnSync(command, args, options) {
|
|
50439
|
+
const parsed = parse7(command, args, options);
|
|
50440
|
+
const result = cp.spawnSync(parsed.command, parsed.args, parsed.options);
|
|
50441
|
+
result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
|
|
50442
|
+
return result;
|
|
50443
|
+
}
|
|
50444
|
+
module.exports = spawn;
|
|
50445
|
+
module.exports.spawn = spawn;
|
|
50446
|
+
module.exports.sync = spawnSync;
|
|
50447
|
+
module.exports._parse = parse7;
|
|
50448
|
+
module.exports._enoent = enoent;
|
|
50449
|
+
});
|
|
50450
|
+
|
|
49637
50451
|
// src/hooks/auto-update-checker/constants.ts
|
|
49638
50452
|
import * as path4 from "path";
|
|
49639
50453
|
import * as os3 from "os";
|
|
@@ -49651,15 +50465,15 @@ function getUserOpencodeConfig() {
|
|
|
49651
50465
|
function getUserOpencodeConfigJsonc() {
|
|
49652
50466
|
return path4.join(getUserConfigDir(), "opencode.jsonc");
|
|
49653
50467
|
}
|
|
49654
|
-
var
|
|
50468
|
+
var PACKAGE_NAME2 = "oh-my-opencode", NPM_REGISTRY_URL, NPM_FETCH_TIMEOUT = 5000, CACHE_ROOT_DIR, CACHE_DIR, VERSION_FILE, INSTALLED_PACKAGE_JSON;
|
|
49655
50469
|
var init_constants3 = __esm(() => {
|
|
49656
50470
|
init_data_path();
|
|
49657
50471
|
init_opencode_config_dir();
|
|
49658
|
-
NPM_REGISTRY_URL = `https://registry.npmjs.org/-/package/${
|
|
50472
|
+
NPM_REGISTRY_URL = `https://registry.npmjs.org/-/package/${PACKAGE_NAME2}/dist-tags`;
|
|
49659
50473
|
CACHE_ROOT_DIR = getOpenCodeCacheDir();
|
|
49660
50474
|
CACHE_DIR = path4.join(CACHE_ROOT_DIR, "packages");
|
|
49661
50475
|
VERSION_FILE = path4.join(CACHE_ROOT_DIR, "version");
|
|
49662
|
-
INSTALLED_PACKAGE_JSON = path4.join(CACHE_DIR, "node_modules",
|
|
50476
|
+
INSTALLED_PACKAGE_JSON = path4.join(CACHE_DIR, "node_modules", PACKAGE_NAME2, "package.json");
|
|
49663
50477
|
});
|
|
49664
50478
|
|
|
49665
50479
|
// src/hooks/auto-update-checker/checker/config-paths.ts
|
|
@@ -49714,7 +50528,7 @@ function getLocalDevPath(directory) {
|
|
|
49714
50528
|
const config2 = JSON.parse(stripJsonComments(content));
|
|
49715
50529
|
const plugins = config2.plugin ?? [];
|
|
49716
50530
|
for (const entry of plugins) {
|
|
49717
|
-
if (entry.startsWith("file://") && entry.includes(
|
|
50531
|
+
if (entry.startsWith("file://") && entry.includes(PACKAGE_NAME2)) {
|
|
49718
50532
|
try {
|
|
49719
50533
|
return fileURLToPath(entry);
|
|
49720
50534
|
} catch {
|
|
@@ -49746,7 +50560,7 @@ function findPackageJsonUp(startPath) {
|
|
|
49746
50560
|
try {
|
|
49747
50561
|
const content = fs5.readFileSync(pkgPath, "utf-8");
|
|
49748
50562
|
const pkg = JSON.parse(content);
|
|
49749
|
-
if (pkg.name ===
|
|
50563
|
+
if (pkg.name === PACKAGE_NAME2)
|
|
49750
50564
|
return pkgPath;
|
|
49751
50565
|
} catch {}
|
|
49752
50566
|
}
|
|
@@ -49795,13 +50609,15 @@ function findPluginEntry(directory) {
|
|
|
49795
50609
|
const config2 = JSON.parse(stripJsonComments(content));
|
|
49796
50610
|
const plugins = config2.plugin ?? [];
|
|
49797
50611
|
for (const entry of plugins) {
|
|
49798
|
-
|
|
49799
|
-
|
|
49800
|
-
|
|
49801
|
-
|
|
49802
|
-
|
|
49803
|
-
|
|
49804
|
-
|
|
50612
|
+
for (const pluginName of MATCH_PLUGIN_NAMES) {
|
|
50613
|
+
if (entry === pluginName) {
|
|
50614
|
+
return { entry, isPinned: false, pinnedVersion: null, configPath };
|
|
50615
|
+
}
|
|
50616
|
+
if (entry.startsWith(`${pluginName}@`)) {
|
|
50617
|
+
const pinnedVersion = entry.slice(pluginName.length + 1);
|
|
50618
|
+
const isPinned = EXACT_SEMVER_REGEX.test(pinnedVersion.trim());
|
|
50619
|
+
return { entry, isPinned, pinnedVersion, configPath };
|
|
50620
|
+
}
|
|
49805
50621
|
}
|
|
49806
50622
|
}
|
|
49807
50623
|
} catch {
|
|
@@ -49810,11 +50626,12 @@ function findPluginEntry(directory) {
|
|
|
49810
50626
|
}
|
|
49811
50627
|
return null;
|
|
49812
50628
|
}
|
|
49813
|
-
var EXACT_SEMVER_REGEX;
|
|
50629
|
+
var EXACT_SEMVER_REGEX, MATCH_PLUGIN_NAMES;
|
|
49814
50630
|
var init_plugin_entry = __esm(() => {
|
|
49815
50631
|
init_constants3();
|
|
49816
50632
|
init_config_paths();
|
|
49817
50633
|
EXACT_SEMVER_REGEX = /^\d+\.\d+\.\d+(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$/;
|
|
50634
|
+
MATCH_PLUGIN_NAMES = [PACKAGE_NAME2, PLUGIN_NAME, LEGACY_PLUGIN_NAME];
|
|
49818
50635
|
});
|
|
49819
50636
|
|
|
49820
50637
|
// src/hooks/auto-update-checker/checker/cached-version.ts
|
|
@@ -50022,7 +50839,7 @@ function syncCachePackageJsonToIntent(pluginInfo) {
|
|
|
50022
50839
|
if (!fs9.existsSync(cachePackageJsonPath)) {
|
|
50023
50840
|
log("[auto-update-checker] Cache package.json missing, creating workspace package.json", { intentVersion });
|
|
50024
50841
|
return {
|
|
50025
|
-
...writeCachePackageJson(cachePackageJsonPath, { dependencies: { [
|
|
50842
|
+
...writeCachePackageJson(cachePackageJsonPath, { dependencies: { [PACKAGE_NAME2]: intentVersion } }),
|
|
50026
50843
|
message: `Created cache package.json with: ${intentVersion}`
|
|
50027
50844
|
};
|
|
50028
50845
|
}
|
|
@@ -50040,21 +50857,21 @@ function syncCachePackageJsonToIntent(pluginInfo) {
|
|
|
50040
50857
|
log("[auto-update-checker] Failed to parse cache package.json:", err);
|
|
50041
50858
|
return { synced: false, error: "parse_error", message: "Failed to parse cache package.json (malformed JSON)" };
|
|
50042
50859
|
}
|
|
50043
|
-
if (!pkgJson || !pkgJson.dependencies?.[
|
|
50860
|
+
if (!pkgJson || !pkgJson.dependencies?.[PACKAGE_NAME2]) {
|
|
50044
50861
|
log("[auto-update-checker] Plugin missing from cache package.json dependencies, adding dependency", { intentVersion });
|
|
50045
50862
|
const nextPkgJson = {
|
|
50046
50863
|
...pkgJson ?? {},
|
|
50047
50864
|
dependencies: {
|
|
50048
50865
|
...pkgJson?.dependencies ?? {},
|
|
50049
|
-
[
|
|
50866
|
+
[PACKAGE_NAME2]: intentVersion
|
|
50050
50867
|
}
|
|
50051
50868
|
};
|
|
50052
50869
|
return {
|
|
50053
50870
|
...writeCachePackageJson(cachePackageJsonPath, nextPkgJson),
|
|
50054
|
-
message: `Added ${
|
|
50871
|
+
message: `Added ${PACKAGE_NAME2}: ${intentVersion}`
|
|
50055
50872
|
};
|
|
50056
50873
|
}
|
|
50057
|
-
const currentVersion = pkgJson.dependencies[
|
|
50874
|
+
const currentVersion = pkgJson.dependencies[PACKAGE_NAME2];
|
|
50058
50875
|
if (currentVersion === intentVersion) {
|
|
50059
50876
|
log("[auto-update-checker] Cache package.json already matches intent:", intentVersion);
|
|
50060
50877
|
return { synced: false, error: null, message: `Already matches intent: ${intentVersion}` };
|
|
@@ -50066,7 +50883,7 @@ function syncCachePackageJsonToIntent(pluginInfo) {
|
|
|
50066
50883
|
} else {
|
|
50067
50884
|
log(`[auto-update-checker] Updating cache package.json: "${currentVersion}" \u2192 "${intentVersion}"`);
|
|
50068
50885
|
}
|
|
50069
|
-
pkgJson.dependencies[
|
|
50886
|
+
pkgJson.dependencies[PACKAGE_NAME2] = intentVersion;
|
|
50070
50887
|
return {
|
|
50071
50888
|
...writeCachePackageJson(cachePackageJsonPath, pkgJson),
|
|
50072
50889
|
message: `Updated: "${currentVersion}" \u2192 "${intentVersion}"`
|
|
@@ -50132,7 +50949,7 @@ function removeFromBunLock(packageName) {
|
|
|
50132
50949
|
}
|
|
50133
50950
|
return false;
|
|
50134
50951
|
}
|
|
50135
|
-
function invalidatePackage(packageName =
|
|
50952
|
+
function invalidatePackage(packageName = PACKAGE_NAME2) {
|
|
50136
50953
|
try {
|
|
50137
50954
|
const userConfigDir = getUserConfigDir();
|
|
50138
50955
|
const pkgDirs = [
|
|
@@ -50197,8 +51014,8 @@ var init_update_toasts = __esm(() => {
|
|
|
50197
51014
|
});
|
|
50198
51015
|
|
|
50199
51016
|
// src/hooks/auto-update-checker/hook/background-update-check.ts
|
|
50200
|
-
import { existsSync as
|
|
50201
|
-
import { join as
|
|
51017
|
+
import { existsSync as existsSync25 } from "fs";
|
|
51018
|
+
import { join as join24 } from "path";
|
|
50202
51019
|
function getCacheWorkspaceDir(deps) {
|
|
50203
51020
|
return deps.join(deps.getOpenCodeCacheDir(), "packages");
|
|
50204
51021
|
}
|
|
@@ -50208,8 +51025,8 @@ function getPinnedVersionToastMessage(latestVersion) {
|
|
|
50208
51025
|
function resolveActiveInstallWorkspace(deps) {
|
|
50209
51026
|
const configPaths = deps.getOpenCodeConfigPaths({ binary: "opencode" });
|
|
50210
51027
|
const cacheDir = getCacheWorkspaceDir(deps);
|
|
50211
|
-
const configInstallPath = deps.join(configPaths.configDir, "node_modules",
|
|
50212
|
-
const cacheInstallPath = deps.join(cacheDir, "node_modules",
|
|
51028
|
+
const configInstallPath = deps.join(configPaths.configDir, "node_modules", PACKAGE_NAME2, "package.json");
|
|
51029
|
+
const cacheInstallPath = deps.join(cacheDir, "node_modules", PACKAGE_NAME2, "package.json");
|
|
50213
51030
|
if (deps.existsSync(configInstallPath)) {
|
|
50214
51031
|
deps.log(`[auto-update-checker] Active workspace: config-dir (${configPaths.configDir})`);
|
|
50215
51032
|
return configPaths.configDir;
|
|
@@ -50255,8 +51072,8 @@ function createBackgroundUpdateCheckRunner(overrides = {}) {
|
|
|
50255
51072
|
deps.log("[auto-update-checker] Plugin not found in config");
|
|
50256
51073
|
return;
|
|
50257
51074
|
}
|
|
50258
|
-
const
|
|
50259
|
-
const currentVersion =
|
|
51075
|
+
const cachedVersion2 = deps.getCachedVersion();
|
|
51076
|
+
const currentVersion = cachedVersion2 ?? pluginInfo.pinnedVersion;
|
|
50260
51077
|
if (!currentVersion) {
|
|
50261
51078
|
deps.log("[auto-update-checker] No version found (cached or pinned)");
|
|
50262
51079
|
return;
|
|
@@ -50288,7 +51105,7 @@ function createBackgroundUpdateCheckRunner(overrides = {}) {
|
|
|
50288
51105
|
await deps.showUpdateAvailableToast(ctx, latestVersion, getToastMessage);
|
|
50289
51106
|
return;
|
|
50290
51107
|
}
|
|
50291
|
-
deps.invalidatePackage(
|
|
51108
|
+
deps.invalidatePackage(PACKAGE_NAME2);
|
|
50292
51109
|
const activeWorkspace = resolveActiveInstallWorkspace(deps);
|
|
50293
51110
|
const installSuccess = await runBunInstallSafe(activeWorkspace, deps);
|
|
50294
51111
|
if (installSuccess) {
|
|
@@ -50316,8 +51133,8 @@ var init_background_update_check = __esm(() => {
|
|
|
50316
51133
|
init_checker();
|
|
50317
51134
|
init_update_toasts();
|
|
50318
51135
|
defaultDeps = {
|
|
50319
|
-
existsSync:
|
|
50320
|
-
join:
|
|
51136
|
+
existsSync: existsSync25,
|
|
51137
|
+
join: join24,
|
|
50321
51138
|
runBunInstallWithDetails,
|
|
50322
51139
|
log,
|
|
50323
51140
|
getOpenCodeCacheDir,
|
|
@@ -50526,9 +51343,9 @@ v${latestVersion} available. Restart OpenCode to apply.` : "OpenCode is now on S
|
|
|
50526
51343
|
return;
|
|
50527
51344
|
hasChecked = true;
|
|
50528
51345
|
setTimeout(async () => {
|
|
50529
|
-
const
|
|
51346
|
+
const cachedVersion2 = getCachedVersion();
|
|
50530
51347
|
const localDevVersion = getLocalDevVersion(ctx.directory);
|
|
50531
|
-
const displayVersion = localDevVersion ??
|
|
51348
|
+
const displayVersion = localDevVersion ?? cachedVersion2;
|
|
50532
51349
|
await showConfigErrorsIfAny(ctx);
|
|
50533
51350
|
await updateAndShowConnectedProvidersCacheStatus(ctx);
|
|
50534
51351
|
await refreshModelCapabilitiesOnStartup(modelCapabilities);
|
|
@@ -50597,7 +51414,7 @@ var {
|
|
|
50597
51414
|
// package.json
|
|
50598
51415
|
var package_default = {
|
|
50599
51416
|
name: "oh-my-opencode",
|
|
50600
|
-
version: "3.
|
|
51417
|
+
version: "3.16.0",
|
|
50601
51418
|
description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
50602
51419
|
main: "./dist/index.js",
|
|
50603
51420
|
types: "dist/index.d.ts",
|
|
@@ -50656,8 +51473,8 @@ var package_default = {
|
|
|
50656
51473
|
"@clack/prompts": "^0.11.0",
|
|
50657
51474
|
"@code-yeongyu/comment-checker": "^0.7.0",
|
|
50658
51475
|
"@modelcontextprotocol/sdk": "^1.25.2",
|
|
50659
|
-
"@opencode-ai/plugin": "^1.
|
|
50660
|
-
"@opencode-ai/sdk": "^1.
|
|
51476
|
+
"@opencode-ai/plugin": "^1.4.0",
|
|
51477
|
+
"@opencode-ai/sdk": "^1.4.0",
|
|
50661
51478
|
commander: "^14.0.2",
|
|
50662
51479
|
"detect-libc": "^2.0.0",
|
|
50663
51480
|
diff: "^8.0.3",
|
|
@@ -50666,7 +51483,7 @@ var package_default = {
|
|
|
50666
51483
|
picocolors: "^1.1.1",
|
|
50667
51484
|
picomatch: "^4.0.2",
|
|
50668
51485
|
"vscode-jsonrpc": "^8.2.0",
|
|
50669
|
-
zod: "^4.
|
|
51486
|
+
zod: "^4.3.0"
|
|
50670
51487
|
},
|
|
50671
51488
|
devDependencies: {
|
|
50672
51489
|
"@types/js-yaml": "^4.0.9",
|
|
@@ -50675,21 +51492,19 @@ var package_default = {
|
|
|
50675
51492
|
typescript: "^5.7.3"
|
|
50676
51493
|
},
|
|
50677
51494
|
optionalDependencies: {
|
|
50678
|
-
"oh-my-opencode-darwin-arm64": "3.
|
|
50679
|
-
"oh-my-opencode-darwin-x64": "3.
|
|
50680
|
-
"oh-my-opencode-darwin-x64-baseline": "3.
|
|
50681
|
-
"oh-my-opencode-linux-arm64": "3.
|
|
50682
|
-
"oh-my-opencode-linux-arm64-musl": "3.
|
|
50683
|
-
"oh-my-opencode-linux-x64": "3.
|
|
50684
|
-
"oh-my-opencode-linux-x64-baseline": "3.
|
|
50685
|
-
"oh-my-opencode-linux-x64-musl": "3.
|
|
50686
|
-
"oh-my-opencode-linux-x64-musl-baseline": "3.
|
|
50687
|
-
"oh-my-opencode-windows-x64": "3.
|
|
50688
|
-
"oh-my-opencode-windows-x64-baseline": "3.
|
|
50689
|
-
},
|
|
50690
|
-
overrides: {
|
|
50691
|
-
"@opencode-ai/sdk": "^1.2.24"
|
|
51495
|
+
"oh-my-opencode-darwin-arm64": "3.16.0",
|
|
51496
|
+
"oh-my-opencode-darwin-x64": "3.16.0",
|
|
51497
|
+
"oh-my-opencode-darwin-x64-baseline": "3.16.0",
|
|
51498
|
+
"oh-my-opencode-linux-arm64": "3.16.0",
|
|
51499
|
+
"oh-my-opencode-linux-arm64-musl": "3.16.0",
|
|
51500
|
+
"oh-my-opencode-linux-x64": "3.16.0",
|
|
51501
|
+
"oh-my-opencode-linux-x64-baseline": "3.16.0",
|
|
51502
|
+
"oh-my-opencode-linux-x64-musl": "3.16.0",
|
|
51503
|
+
"oh-my-opencode-linux-x64-musl-baseline": "3.16.0",
|
|
51504
|
+
"oh-my-opencode-windows-x64": "3.16.0",
|
|
51505
|
+
"oh-my-opencode-windows-x64-baseline": "3.16.0"
|
|
50692
51506
|
},
|
|
51507
|
+
overrides: {},
|
|
50693
51508
|
trustedDependencies: [
|
|
50694
51509
|
"@ast-grep/cli",
|
|
50695
51510
|
"@ast-grep/napi",
|
|
@@ -50700,7 +51515,7 @@ var package_default = {
|
|
|
50700
51515
|
// src/cli/cli-installer.ts
|
|
50701
51516
|
init_shared();
|
|
50702
51517
|
init_config_manager();
|
|
50703
|
-
var
|
|
51518
|
+
var import_picocolors3 = __toESM(require_picocolors(), 1);
|
|
50704
51519
|
|
|
50705
51520
|
// src/cli/install-validators.ts
|
|
50706
51521
|
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
@@ -50847,6 +51662,56 @@ function detectedToInitialValues(detected) {
|
|
|
50847
51662
|
};
|
|
50848
51663
|
}
|
|
50849
51664
|
|
|
51665
|
+
// src/cli/doctor/constants.ts
|
|
51666
|
+
init_shared();
|
|
51667
|
+
var import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
51668
|
+
var SYMBOLS2 = {
|
|
51669
|
+
check: import_picocolors2.default.green("\u2713"),
|
|
51670
|
+
cross: import_picocolors2.default.red("\u2717"),
|
|
51671
|
+
warn: import_picocolors2.default.yellow("\u26A0"),
|
|
51672
|
+
info: import_picocolors2.default.blue("\u2139"),
|
|
51673
|
+
arrow: import_picocolors2.default.cyan("\u2192"),
|
|
51674
|
+
bullet: import_picocolors2.default.dim("\u2022"),
|
|
51675
|
+
skip: import_picocolors2.default.dim("\u25CB")
|
|
51676
|
+
};
|
|
51677
|
+
var STATUS_COLORS = {
|
|
51678
|
+
pass: import_picocolors2.default.green,
|
|
51679
|
+
fail: import_picocolors2.default.red,
|
|
51680
|
+
warn: import_picocolors2.default.yellow,
|
|
51681
|
+
skip: import_picocolors2.default.dim
|
|
51682
|
+
};
|
|
51683
|
+
var CHECK_IDS = {
|
|
51684
|
+
SYSTEM: "system",
|
|
51685
|
+
CONFIG: "config",
|
|
51686
|
+
TOOLS: "tools",
|
|
51687
|
+
MODELS: "models"
|
|
51688
|
+
};
|
|
51689
|
+
var CHECK_NAMES = {
|
|
51690
|
+
[CHECK_IDS.SYSTEM]: "System",
|
|
51691
|
+
[CHECK_IDS.CONFIG]: "Configuration",
|
|
51692
|
+
[CHECK_IDS.TOOLS]: "Tools",
|
|
51693
|
+
[CHECK_IDS.MODELS]: "Models"
|
|
51694
|
+
};
|
|
51695
|
+
var EXIT_CODES = {
|
|
51696
|
+
SUCCESS: 0,
|
|
51697
|
+
FAILURE: 1
|
|
51698
|
+
};
|
|
51699
|
+
var MIN_OPENCODE_VERSION = "1.4.0";
|
|
51700
|
+
var PACKAGE_NAME = PLUGIN_NAME;
|
|
51701
|
+
var OPENCODE_BINARIES2 = ["opencode", "opencode-desktop"];
|
|
51702
|
+
|
|
51703
|
+
// src/cli/minimum-opencode-version.ts
|
|
51704
|
+
init_opencode_version();
|
|
51705
|
+
function getUnsupportedOpenCodeVersionMessage(openCodeVersion) {
|
|
51706
|
+
if (!openCodeVersion) {
|
|
51707
|
+
return null;
|
|
51708
|
+
}
|
|
51709
|
+
if (compareVersions(openCodeVersion, MIN_OPENCODE_VERSION) >= 0) {
|
|
51710
|
+
return null;
|
|
51711
|
+
}
|
|
51712
|
+
return `Detected OpenCode ${openCodeVersion}, but ${MIN_OPENCODE_VERSION}+ is required. Update OpenCode, then rerun the installer.`;
|
|
51713
|
+
}
|
|
51714
|
+
|
|
50850
51715
|
// src/cli/cli-installer.ts
|
|
50851
51716
|
async function runCliInstaller(args, version) {
|
|
50852
51717
|
const validation = validateNonTuiArgs(args);
|
|
@@ -50868,12 +51733,17 @@ async function runCliInstaller(args, version) {
|
|
|
50868
51733
|
let step = 1;
|
|
50869
51734
|
printStep(step++, totalSteps, "Checking OpenCode installation...");
|
|
50870
51735
|
const installed = await isOpenCodeInstalled();
|
|
50871
|
-
const openCodeVersion = await
|
|
51736
|
+
const openCodeVersion = await getOpenCodeVersion2();
|
|
50872
51737
|
if (!installed) {
|
|
50873
51738
|
printWarning("OpenCode binary not found. Plugin will be configured, but you'll need to install OpenCode to use it.");
|
|
50874
51739
|
printInfo("Visit https://opencode.ai/docs for installation instructions");
|
|
50875
51740
|
} else {
|
|
50876
51741
|
printSuccess(`OpenCode ${openCodeVersion ?? ""} detected`);
|
|
51742
|
+
const unsupportedVersionMessage = getUnsupportedOpenCodeVersionMessage(openCodeVersion);
|
|
51743
|
+
if (unsupportedVersionMessage) {
|
|
51744
|
+
printWarning(unsupportedVersionMessage);
|
|
51745
|
+
return 1;
|
|
51746
|
+
}
|
|
50877
51747
|
}
|
|
50878
51748
|
if (isUpdate) {
|
|
50879
51749
|
const initial = detectedToInitialValues(detected);
|
|
@@ -50886,47 +51756,37 @@ async function runCliInstaller(args, version) {
|
|
|
50886
51756
|
printError(`Failed: ${pluginResult.error}`);
|
|
50887
51757
|
return 1;
|
|
50888
51758
|
}
|
|
50889
|
-
printSuccess(`Plugin ${isUpdate ? "verified" : "added"} ${SYMBOLS.arrow} ${
|
|
51759
|
+
printSuccess(`Plugin ${isUpdate ? "verified" : "added"} ${SYMBOLS.arrow} ${import_picocolors3.default.dim(pluginResult.configPath)}`);
|
|
50890
51760
|
printStep(step++, totalSteps, `Writing ${PLUGIN_NAME} configuration...`);
|
|
50891
51761
|
const omoResult = writeOmoConfig(config);
|
|
50892
51762
|
if (!omoResult.success) {
|
|
50893
51763
|
printError(`Failed: ${omoResult.error}`);
|
|
50894
51764
|
return 1;
|
|
50895
51765
|
}
|
|
50896
|
-
printSuccess(`Config written ${SYMBOLS.arrow} ${
|
|
51766
|
+
printSuccess(`Config written ${SYMBOLS.arrow} ${import_picocolors3.default.dim(omoResult.configPath)}`);
|
|
50897
51767
|
printBox(formatConfigSummary(config), isUpdate ? "Updated Configuration" : "Installation Complete");
|
|
50898
51768
|
if (!config.hasClaude) {
|
|
50899
|
-
|
|
50900
|
-
console.log(import_picocolors2.default.bgRed(import_picocolors2.default.white(import_picocolors2.default.bold(" CRITICAL WARNING "))));
|
|
50901
|
-
console.log();
|
|
50902
|
-
console.log(import_picocolors2.default.red(import_picocolors2.default.bold(" Sisyphus agent is STRONGLY optimized for Claude Opus 4.5.")));
|
|
50903
|
-
console.log(import_picocolors2.default.red(" Without Claude, you may experience significantly degraded performance:"));
|
|
50904
|
-
console.log(import_picocolors2.default.dim(" \u2022 Reduced orchestration quality"));
|
|
50905
|
-
console.log(import_picocolors2.default.dim(" \u2022 Weaker tool selection and delegation"));
|
|
50906
|
-
console.log(import_picocolors2.default.dim(" \u2022 Less reliable task completion"));
|
|
50907
|
-
console.log();
|
|
50908
|
-
console.log(import_picocolors2.default.yellow(" Consider subscribing to Claude Pro/Max for the best experience."));
|
|
50909
|
-
console.log();
|
|
51769
|
+
printInfo("Note: Sisyphus agent performs best with Claude Opus 4.5+. " + "Other models work but may have reduced orchestration quality.");
|
|
50910
51770
|
}
|
|
50911
51771
|
if (!config.hasClaude && !config.hasOpenAI && !config.hasGemini && !config.hasCopilot && !config.hasOpencodeZen) {
|
|
50912
51772
|
printWarning("No model providers configured. Using opencode/big-pickle as fallback.");
|
|
50913
51773
|
}
|
|
50914
|
-
console.log(`${SYMBOLS.star} ${
|
|
50915
|
-
console.log(` Run ${
|
|
51774
|
+
console.log(`${SYMBOLS.star} ${import_picocolors3.default.bold(import_picocolors3.default.green(isUpdate ? "Configuration updated!" : "Installation complete!"))}`);
|
|
51775
|
+
console.log(` Run ${import_picocolors3.default.cyan("opencode")} to start!`);
|
|
50916
51776
|
console.log();
|
|
50917
|
-
printBox(`${
|
|
51777
|
+
printBox(`${import_picocolors3.default.bold("Pro Tip:")} Include ${import_picocolors3.default.cyan("ultrawork")} (or ${import_picocolors3.default.cyan("ulw")}) in your prompt.
|
|
50918
51778
|
` + `All features work like magic-parallel agents, background tasks,
|
|
50919
51779
|
` + `deep exploration, and relentless execution until completion.`, "The Magic Word");
|
|
50920
|
-
console.log(`${SYMBOLS.star} ${
|
|
50921
|
-
console.log(` ${
|
|
51780
|
+
console.log(`${SYMBOLS.star} ${import_picocolors3.default.yellow("If you found this helpful, consider starring the repo!")}`);
|
|
51781
|
+
console.log(` ${import_picocolors3.default.dim("gh api --silent --method PUT /user/starred/code-yeongyu/oh-my-openagent >/dev/null 2>&1 || true")}`);
|
|
50922
51782
|
console.log();
|
|
50923
|
-
console.log(
|
|
51783
|
+
console.log(import_picocolors3.default.dim("oMoMoMoMo... Enjoy!"));
|
|
50924
51784
|
console.log();
|
|
50925
51785
|
if ((config.hasClaude || config.hasGemini || config.hasCopilot) && !args.skipAuth) {
|
|
50926
|
-
printBox(`Run ${
|
|
50927
|
-
` + (config.hasClaude ? ` ${SYMBOLS.bullet} Anthropic ${
|
|
50928
|
-
` : "") + (config.hasGemini ? ` ${SYMBOLS.bullet} Google ${
|
|
50929
|
-
` : "") + (config.hasCopilot ? ` ${SYMBOLS.bullet} GitHub ${
|
|
51786
|
+
printBox(`Run ${import_picocolors3.default.cyan("opencode auth login")} and select your provider:
|
|
51787
|
+
` + (config.hasClaude ? ` ${SYMBOLS.bullet} Anthropic ${import_picocolors3.default.gray("\u2192 Claude Pro/Max")}
|
|
51788
|
+
` : "") + (config.hasGemini ? ` ${SYMBOLS.bullet} Google ${import_picocolors3.default.gray("\u2192 Gemini")}
|
|
51789
|
+
` : "") + (config.hasCopilot ? ` ${SYMBOLS.bullet} GitHub ${import_picocolors3.default.gray("\u2192 Copilot")}` : ""), "Authenticate Your Providers");
|
|
50930
51790
|
}
|
|
50931
51791
|
return 0;
|
|
50932
51792
|
}
|
|
@@ -51321,7 +52181,7 @@ class LD extends x {
|
|
|
51321
52181
|
}
|
|
51322
52182
|
|
|
51323
52183
|
// node_modules/@clack/prompts/dist/index.mjs
|
|
51324
|
-
var
|
|
52184
|
+
var import_picocolors4 = __toESM(require_picocolors(), 1);
|
|
51325
52185
|
var import_sisteransi2 = __toESM(require_src(), 1);
|
|
51326
52186
|
import y2 from "process";
|
|
51327
52187
|
function ce() {
|
|
@@ -51354,13 +52214,13 @@ var b2 = (t) => {
|
|
|
51354
52214
|
switch (t) {
|
|
51355
52215
|
case "initial":
|
|
51356
52216
|
case "active":
|
|
51357
|
-
return
|
|
52217
|
+
return import_picocolors4.default.cyan(le);
|
|
51358
52218
|
case "cancel":
|
|
51359
|
-
return
|
|
52219
|
+
return import_picocolors4.default.red(L2);
|
|
51360
52220
|
case "error":
|
|
51361
|
-
return
|
|
52221
|
+
return import_picocolors4.default.yellow(W2);
|
|
51362
52222
|
case "submit":
|
|
51363
|
-
return
|
|
52223
|
+
return import_picocolors4.default.green(C);
|
|
51364
52224
|
}
|
|
51365
52225
|
};
|
|
51366
52226
|
var G2 = (t) => {
|
|
@@ -51370,7 +52230,7 @@ var G2 = (t) => {
|
|
|
51370
52230
|
const $2 = a < r2.length && l2 > 0, g2 = a < r2.length && l2 + a < r2.length;
|
|
51371
52231
|
return r2.slice(l2, l2 + a).map((p2, v, f) => {
|
|
51372
52232
|
const j2 = v === 0 && $2, E = v === f.length - 1 && g2;
|
|
51373
|
-
return j2 || E ?
|
|
52233
|
+
return j2 || E ? import_picocolors4.default.dim("...") : i2(p2, v + l2 === n);
|
|
51374
52234
|
});
|
|
51375
52235
|
};
|
|
51376
52236
|
var ve = (t) => {
|
|
@@ -51378,29 +52238,29 @@ var ve = (t) => {
|
|
|
51378
52238
|
const s = r2.label ?? String(r2.value);
|
|
51379
52239
|
switch (i2) {
|
|
51380
52240
|
case "selected":
|
|
51381
|
-
return `${
|
|
52241
|
+
return `${import_picocolors4.default.dim(s)}`;
|
|
51382
52242
|
case "active":
|
|
51383
|
-
return `${
|
|
52243
|
+
return `${import_picocolors4.default.green(k2)} ${s} ${r2.hint ? import_picocolors4.default.dim(`(${r2.hint})`) : ""}`;
|
|
51384
52244
|
case "cancelled":
|
|
51385
|
-
return `${
|
|
52245
|
+
return `${import_picocolors4.default.strikethrough(import_picocolors4.default.dim(s))}`;
|
|
51386
52246
|
default:
|
|
51387
|
-
return `${
|
|
52247
|
+
return `${import_picocolors4.default.dim(P2)} ${import_picocolors4.default.dim(s)}`;
|
|
51388
52248
|
}
|
|
51389
52249
|
};
|
|
51390
52250
|
return new LD({ options: t.options, initialValue: t.initialValue, render() {
|
|
51391
|
-
const r2 = `${
|
|
52251
|
+
const r2 = `${import_picocolors4.default.gray(o)}
|
|
51392
52252
|
${b2(this.state)} ${t.message}
|
|
51393
52253
|
`;
|
|
51394
52254
|
switch (this.state) {
|
|
51395
52255
|
case "submit":
|
|
51396
|
-
return `${r2}${
|
|
52256
|
+
return `${r2}${import_picocolors4.default.gray(o)} ${n(this.options[this.cursor], "selected")}`;
|
|
51397
52257
|
case "cancel":
|
|
51398
|
-
return `${r2}${
|
|
51399
|
-
${
|
|
52258
|
+
return `${r2}${import_picocolors4.default.gray(o)} ${n(this.options[this.cursor], "cancelled")}
|
|
52259
|
+
${import_picocolors4.default.gray(o)}`;
|
|
51400
52260
|
default:
|
|
51401
|
-
return `${r2}${
|
|
51402
|
-
${
|
|
51403
|
-
${
|
|
52261
|
+
return `${r2}${import_picocolors4.default.cyan(o)} ${G2({ cursor: this.cursor, options: this.options, maxItems: t.maxItems, style: (i2, s) => n(i2, s ? "active" : "inactive") }).join(`
|
|
52262
|
+
${import_picocolors4.default.cyan(o)} `)}
|
|
52263
|
+
${import_picocolors4.default.cyan(d2)}
|
|
51404
52264
|
`;
|
|
51405
52265
|
}
|
|
51406
52266
|
} }).prompt();
|
|
@@ -51412,53 +52272,53 @@ ${t}
|
|
|
51412
52272
|
`), i2 = S2(n).length, s = Math.max(r2.reduce((a, l2) => {
|
|
51413
52273
|
const $2 = S2(l2);
|
|
51414
52274
|
return $2.length > a ? $2.length : a;
|
|
51415
|
-
}, 0), i2) + 2, c = r2.map((a) => `${
|
|
52275
|
+
}, 0), i2) + 2, c = r2.map((a) => `${import_picocolors4.default.gray(o)} ${import_picocolors4.default.dim(a)}${" ".repeat(s - S2(a).length)}${import_picocolors4.default.gray(o)}`).join(`
|
|
51416
52276
|
`);
|
|
51417
|
-
process.stdout.write(`${
|
|
51418
|
-
${
|
|
52277
|
+
process.stdout.write(`${import_picocolors4.default.gray(o)}
|
|
52278
|
+
${import_picocolors4.default.green(C)} ${import_picocolors4.default.reset(n)} ${import_picocolors4.default.gray(_2.repeat(Math.max(s - i2 - 1, 1)) + me)}
|
|
51419
52279
|
${c}
|
|
51420
|
-
${
|
|
52280
|
+
${import_picocolors4.default.gray(de + _2.repeat(s + 2) + pe)}
|
|
51421
52281
|
`);
|
|
51422
52282
|
};
|
|
51423
52283
|
var xe = (t = "") => {
|
|
51424
|
-
process.stdout.write(`${
|
|
52284
|
+
process.stdout.write(`${import_picocolors4.default.gray(d2)} ${import_picocolors4.default.red(t)}
|
|
51425
52285
|
|
|
51426
52286
|
`);
|
|
51427
52287
|
};
|
|
51428
52288
|
var Ie = (t = "") => {
|
|
51429
|
-
process.stdout.write(`${
|
|
52289
|
+
process.stdout.write(`${import_picocolors4.default.gray(ue)} ${t}
|
|
51430
52290
|
`);
|
|
51431
52291
|
};
|
|
51432
52292
|
var Se = (t = "") => {
|
|
51433
|
-
process.stdout.write(`${
|
|
51434
|
-
${
|
|
52293
|
+
process.stdout.write(`${import_picocolors4.default.gray(o)}
|
|
52294
|
+
${import_picocolors4.default.gray(d2)} ${t}
|
|
51435
52295
|
|
|
51436
52296
|
`);
|
|
51437
52297
|
};
|
|
51438
|
-
var M2 = { message: (t = "", { symbol: n =
|
|
51439
|
-
const r2 = [`${
|
|
52298
|
+
var M2 = { message: (t = "", { symbol: n = import_picocolors4.default.gray(o) } = {}) => {
|
|
52299
|
+
const r2 = [`${import_picocolors4.default.gray(o)}`];
|
|
51440
52300
|
if (t) {
|
|
51441
52301
|
const [i2, ...s] = t.split(`
|
|
51442
52302
|
`);
|
|
51443
|
-
r2.push(`${n} ${i2}`, ...s.map((c) => `${
|
|
52303
|
+
r2.push(`${n} ${i2}`, ...s.map((c) => `${import_picocolors4.default.gray(o)} ${c}`));
|
|
51444
52304
|
}
|
|
51445
52305
|
process.stdout.write(`${r2.join(`
|
|
51446
52306
|
`)}
|
|
51447
52307
|
`);
|
|
51448
52308
|
}, info: (t) => {
|
|
51449
|
-
M2.message(t, { symbol:
|
|
52309
|
+
M2.message(t, { symbol: import_picocolors4.default.blue(q) });
|
|
51450
52310
|
}, success: (t) => {
|
|
51451
|
-
M2.message(t, { symbol:
|
|
52311
|
+
M2.message(t, { symbol: import_picocolors4.default.green(D) });
|
|
51452
52312
|
}, step: (t) => {
|
|
51453
|
-
M2.message(t, { symbol:
|
|
52313
|
+
M2.message(t, { symbol: import_picocolors4.default.green(C) });
|
|
51454
52314
|
}, warn: (t) => {
|
|
51455
|
-
M2.message(t, { symbol:
|
|
52315
|
+
M2.message(t, { symbol: import_picocolors4.default.yellow(U) });
|
|
51456
52316
|
}, warning: (t) => {
|
|
51457
52317
|
M2.warn(t);
|
|
51458
52318
|
}, error: (t) => {
|
|
51459
|
-
M2.message(t, { symbol:
|
|
52319
|
+
M2.message(t, { symbol: import_picocolors4.default.red(K2) });
|
|
51460
52320
|
} };
|
|
51461
|
-
var J2 = `${
|
|
52321
|
+
var J2 = `${import_picocolors4.default.gray(o)} `;
|
|
51462
52322
|
var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
51463
52323
|
const n = V2 ? ["\u25D2", "\u25D0", "\u25D3", "\u25D1"] : ["\u2022", "o", "O", "0"], r2 = V2 ? 80 : 120, i2 = process.env.CI === "true";
|
|
51464
52324
|
let s, c, a = false, l2 = "", $2, g2 = performance.now();
|
|
@@ -51481,14 +52341,14 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
51481
52341
|
const h2 = (performance.now() - m2) / 1000, w2 = Math.floor(h2 / 60), I2 = Math.floor(h2 % 60);
|
|
51482
52342
|
return w2 > 0 ? `[${w2}m ${I2}s]` : `[${I2}s]`;
|
|
51483
52343
|
}, H = (m2 = "") => {
|
|
51484
|
-
a = true, s = fD(), l2 = R2(m2), g2 = performance.now(), process.stdout.write(`${
|
|
52344
|
+
a = true, s = fD(), l2 = R2(m2), g2 = performance.now(), process.stdout.write(`${import_picocolors4.default.gray(o)}
|
|
51485
52345
|
`);
|
|
51486
52346
|
let h2 = 0, w2 = 0;
|
|
51487
52347
|
j2(), c = setInterval(() => {
|
|
51488
52348
|
if (i2 && l2 === $2)
|
|
51489
52349
|
return;
|
|
51490
52350
|
B2(), $2 = l2;
|
|
51491
|
-
const I2 =
|
|
52351
|
+
const I2 = import_picocolors4.default.magenta(n[h2]);
|
|
51492
52352
|
if (i2)
|
|
51493
52353
|
process.stdout.write(`${I2} ${l2}...`);
|
|
51494
52354
|
else if (t === "timer")
|
|
@@ -51501,7 +52361,7 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
51501
52361
|
}, r2);
|
|
51502
52362
|
}, N2 = (m2 = "", h2 = 0) => {
|
|
51503
52363
|
a = false, clearInterval(c), B2();
|
|
51504
|
-
const w2 = h2 === 0 ?
|
|
52364
|
+
const w2 = h2 === 0 ? import_picocolors4.default.green(C) : h2 === 1 ? import_picocolors4.default.red(L2) : import_picocolors4.default.red(W2);
|
|
51505
52365
|
l2 = R2(m2 ?? l2), t === "timer" ? process.stdout.write(`${w2} ${l2} ${O2(g2)}
|
|
51506
52366
|
`) : process.stdout.write(`${w2} ${l2}
|
|
51507
52367
|
`), E(), s();
|
|
@@ -51514,7 +52374,7 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
51514
52374
|
// src/cli/tui-installer.ts
|
|
51515
52375
|
init_shared();
|
|
51516
52376
|
init_config_manager();
|
|
51517
|
-
var
|
|
52377
|
+
var import_picocolors5 = __toESM(require_picocolors(), 1);
|
|
51518
52378
|
|
|
51519
52379
|
// src/cli/tui-install-prompts.ts
|
|
51520
52380
|
async function selectOrCancel(params) {
|
|
@@ -51635,7 +52495,7 @@ async function runTuiInstaller(args, version) {
|
|
|
51635
52495
|
}
|
|
51636
52496
|
const detected = detectCurrentConfig();
|
|
51637
52497
|
const isUpdate = detected.isInstalled;
|
|
51638
|
-
Ie(
|
|
52498
|
+
Ie(import_picocolors5.default.bgMagenta(import_picocolors5.default.white(isUpdate ? " oMoMoMoMo... Update " : " oMoMoMoMo... ")));
|
|
51639
52499
|
if (isUpdate) {
|
|
51640
52500
|
const initial = detectedToInitialValues(detected);
|
|
51641
52501
|
M2.info(`Existing configuration detected: Claude=${initial.claude}, Gemini=${initial.gemini}`);
|
|
@@ -51643,13 +52503,19 @@ async function runTuiInstaller(args, version) {
|
|
|
51643
52503
|
const spinner = Y2();
|
|
51644
52504
|
spinner.start("Checking OpenCode installation");
|
|
51645
52505
|
const installed = await isOpenCodeInstalled();
|
|
51646
|
-
const openCodeVersion = await
|
|
52506
|
+
const openCodeVersion = await getOpenCodeVersion2();
|
|
51647
52507
|
if (!installed) {
|
|
51648
|
-
spinner.stop(`OpenCode binary not found ${
|
|
52508
|
+
spinner.stop(`OpenCode binary not found ${import_picocolors5.default.yellow("[!]")}`);
|
|
51649
52509
|
M2.warn("OpenCode binary not found. Plugin will be configured, but you'll need to install OpenCode to use it.");
|
|
51650
52510
|
Me("Visit https://opencode.ai/docs for installation instructions", "Installation Guide");
|
|
51651
52511
|
} else {
|
|
51652
|
-
spinner.stop(`OpenCode ${openCodeVersion ?? "installed"} ${
|
|
52512
|
+
spinner.stop(`OpenCode ${openCodeVersion ?? "installed"} ${import_picocolors5.default.green("[OK]")}`);
|
|
52513
|
+
const unsupportedVersionMessage = getUnsupportedOpenCodeVersionMessage(openCodeVersion);
|
|
52514
|
+
if (unsupportedVersionMessage) {
|
|
52515
|
+
M2.warn(unsupportedVersionMessage);
|
|
52516
|
+
Se(import_picocolors5.default.red("Installation blocked."));
|
|
52517
|
+
return 1;
|
|
52518
|
+
}
|
|
51653
52519
|
}
|
|
51654
52520
|
const config = await promptInstallConfig(detected);
|
|
51655
52521
|
if (!config)
|
|
@@ -51658,55 +52524,46 @@ async function runTuiInstaller(args, version) {
|
|
|
51658
52524
|
const pluginResult = await addPluginToOpenCodeConfig(version);
|
|
51659
52525
|
if (!pluginResult.success) {
|
|
51660
52526
|
spinner.stop(`Failed to add plugin: ${pluginResult.error}`);
|
|
51661
|
-
Se(
|
|
52527
|
+
Se(import_picocolors5.default.red("Installation failed."));
|
|
51662
52528
|
return 1;
|
|
51663
52529
|
}
|
|
51664
|
-
spinner.stop(`Plugin added to ${
|
|
52530
|
+
spinner.stop(`Plugin added to ${import_picocolors5.default.cyan(pluginResult.configPath)}`);
|
|
51665
52531
|
spinner.start(`Writing ${PLUGIN_NAME} configuration`);
|
|
51666
52532
|
const omoResult = writeOmoConfig(config);
|
|
51667
52533
|
if (!omoResult.success) {
|
|
51668
52534
|
spinner.stop(`Failed to write config: ${omoResult.error}`);
|
|
51669
|
-
Se(
|
|
52535
|
+
Se(import_picocolors5.default.red("Installation failed."));
|
|
51670
52536
|
return 1;
|
|
51671
52537
|
}
|
|
51672
|
-
spinner.stop(`Config written to ${
|
|
52538
|
+
spinner.stop(`Config written to ${import_picocolors5.default.cyan(omoResult.configPath)}`);
|
|
51673
52539
|
if (!config.hasClaude) {
|
|
51674
|
-
|
|
51675
|
-
|
|
51676
|
-
console.log();
|
|
51677
|
-
console.log(import_picocolors4.default.red(import_picocolors4.default.bold(" Sisyphus agent is STRONGLY optimized for Claude Opus 4.5.")));
|
|
51678
|
-
console.log(import_picocolors4.default.red(" Without Claude, you may experience significantly degraded performance:"));
|
|
51679
|
-
console.log(import_picocolors4.default.dim(" \u2022 Reduced orchestration quality"));
|
|
51680
|
-
console.log(import_picocolors4.default.dim(" \u2022 Weaker tool selection and delegation"));
|
|
51681
|
-
console.log(import_picocolors4.default.dim(" \u2022 Less reliable task completion"));
|
|
51682
|
-
console.log();
|
|
51683
|
-
console.log(import_picocolors4.default.yellow(" Consider subscribing to Claude Pro/Max for the best experience."));
|
|
51684
|
-
console.log();
|
|
52540
|
+
M2.info(`${import_picocolors5.default.bold("Note:")} Sisyphus agent performs best with Claude Opus 4.5+.
|
|
52541
|
+
` + `Other models work but may have reduced orchestration quality.`);
|
|
51685
52542
|
}
|
|
51686
52543
|
if (!config.hasClaude && !config.hasOpenAI && !config.hasGemini && !config.hasCopilot && !config.hasOpencodeZen) {
|
|
51687
52544
|
M2.warn("No model providers configured. Using opencode/big-pickle as fallback.");
|
|
51688
52545
|
}
|
|
51689
52546
|
Me(formatConfigSummary(config), isUpdate ? "Updated Configuration" : "Installation Complete");
|
|
51690
|
-
M2.success(
|
|
51691
|
-
M2.message(`Run ${
|
|
51692
|
-
Me(`Include ${
|
|
52547
|
+
M2.success(import_picocolors5.default.bold(isUpdate ? "Configuration updated!" : "Installation complete!"));
|
|
52548
|
+
M2.message(`Run ${import_picocolors5.default.cyan("opencode")} to start!`);
|
|
52549
|
+
Me(`Include ${import_picocolors5.default.cyan("ultrawork")} (or ${import_picocolors5.default.cyan("ulw")}) in your prompt.
|
|
51693
52550
|
` + `All features work like magic-parallel agents, background tasks,
|
|
51694
52551
|
` + `deep exploration, and relentless execution until completion.`, "The Magic Word");
|
|
51695
|
-
M2.message(`${
|
|
51696
|
-
M2.message(` ${
|
|
51697
|
-
Se(
|
|
52552
|
+
M2.message(`${import_picocolors5.default.yellow("\u2605")} If you found this helpful, consider starring the repo!`);
|
|
52553
|
+
M2.message(` ${import_picocolors5.default.dim("gh api --silent --method PUT /user/starred/code-yeongyu/oh-my-openagent >/dev/null 2>&1 || true")}`);
|
|
52554
|
+
Se(import_picocolors5.default.green("oMoMoMoMo... Enjoy!"));
|
|
51698
52555
|
if ((config.hasClaude || config.hasGemini || config.hasCopilot) && !args.skipAuth) {
|
|
51699
52556
|
const providers = [];
|
|
51700
52557
|
if (config.hasClaude)
|
|
51701
|
-
providers.push(`Anthropic ${
|
|
52558
|
+
providers.push(`Anthropic ${import_picocolors5.default.gray("\u2192 Claude Pro/Max")}`);
|
|
51702
52559
|
if (config.hasGemini)
|
|
51703
|
-
providers.push(`Google ${
|
|
52560
|
+
providers.push(`Google ${import_picocolors5.default.gray("\u2192 Gemini")}`);
|
|
51704
52561
|
if (config.hasCopilot)
|
|
51705
|
-
providers.push(`GitHub ${
|
|
52562
|
+
providers.push(`GitHub ${import_picocolors5.default.gray("\u2192 Copilot")}`);
|
|
51706
52563
|
console.log();
|
|
51707
|
-
console.log(
|
|
52564
|
+
console.log(import_picocolors5.default.bold("Authenticate Your Providers"));
|
|
51708
52565
|
console.log();
|
|
51709
|
-
console.log(` Run ${
|
|
52566
|
+
console.log(` Run ${import_picocolors5.default.cyan("opencode auth login")} and select:`);
|
|
51710
52567
|
for (const provider of providers) {
|
|
51711
52568
|
console.log(` ${SYMBOLS.bullet} ${provider}`);
|
|
51712
52569
|
}
|
|
@@ -51722,7 +52579,7 @@ async function install(args) {
|
|
|
51722
52579
|
}
|
|
51723
52580
|
|
|
51724
52581
|
// src/cli/run/runner.ts
|
|
51725
|
-
var
|
|
52582
|
+
var import_picocolors15 = __toESM(require_picocolors(), 1);
|
|
51726
52583
|
|
|
51727
52584
|
// src/cli/run/event-state.ts
|
|
51728
52585
|
function createEventState() {
|
|
@@ -51756,7 +52613,7 @@ function createEventState() {
|
|
|
51756
52613
|
};
|
|
51757
52614
|
}
|
|
51758
52615
|
// src/cli/run/event-formatting.ts
|
|
51759
|
-
var
|
|
52616
|
+
var import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
51760
52617
|
function serializeError(error) {
|
|
51761
52618
|
if (!error)
|
|
51762
52619
|
return "Unknown error";
|
|
@@ -51800,10 +52657,10 @@ function getSessionTag(ctx, payload) {
|
|
|
51800
52657
|
const sessionID = props?.sessionID ?? props?.sessionId ?? info?.sessionID ?? info?.sessionId ?? part?.sessionID ?? part?.sessionId;
|
|
51801
52658
|
const isMainSession = sessionID === ctx.sessionID;
|
|
51802
52659
|
if (isMainSession)
|
|
51803
|
-
return
|
|
52660
|
+
return import_picocolors6.default.green("[MAIN]");
|
|
51804
52661
|
if (sessionID)
|
|
51805
|
-
return
|
|
51806
|
-
return
|
|
52662
|
+
return import_picocolors6.default.yellow(`[${String(sessionID).slice(0, 8)}]`);
|
|
52663
|
+
return import_picocolors6.default.dim("[system]");
|
|
51807
52664
|
}
|
|
51808
52665
|
function logEventVerbose(ctx, payload) {
|
|
51809
52666
|
const sessionTag = getSessionTag(ctx, payload);
|
|
@@ -51812,7 +52669,7 @@ function logEventVerbose(ctx, payload) {
|
|
|
51812
52669
|
case "session.idle":
|
|
51813
52670
|
case "session.status": {
|
|
51814
52671
|
const status = props?.status?.type ?? "idle";
|
|
51815
|
-
console.error(
|
|
52672
|
+
console.error(import_picocolors6.default.dim(`${sessionTag} ${payload.type}: ${status}`));
|
|
51816
52673
|
break;
|
|
51817
52674
|
}
|
|
51818
52675
|
case "message.part.updated": {
|
|
@@ -51820,10 +52677,10 @@ function logEventVerbose(ctx, payload) {
|
|
|
51820
52677
|
const part = partProps?.part;
|
|
51821
52678
|
if (part?.type === "tool") {
|
|
51822
52679
|
const status = part.state?.status ?? "unknown";
|
|
51823
|
-
console.error(
|
|
52680
|
+
console.error(import_picocolors6.default.dim(`${sessionTag} message.part (tool): ${part.tool ?? part.name ?? "?"} [${status}]`));
|
|
51824
52681
|
} else if (part?.type === "text" && part.text) {
|
|
51825
52682
|
const preview = part.text.slice(0, 80).replace(/\n/g, "\\n");
|
|
51826
|
-
console.error(
|
|
52683
|
+
console.error(import_picocolors6.default.dim(`${sessionTag} message.part (text): "${preview}${part.text.length > 80 ? "..." : ""}"`));
|
|
51827
52684
|
}
|
|
51828
52685
|
break;
|
|
51829
52686
|
}
|
|
@@ -51832,7 +52689,7 @@ function logEventVerbose(ctx, payload) {
|
|
|
51832
52689
|
const field = deltaProps?.field ?? "unknown";
|
|
51833
52690
|
const delta = deltaProps?.delta ?? "";
|
|
51834
52691
|
const preview = delta.slice(0, 80).replace(/\n/g, "\\n");
|
|
51835
|
-
console.error(
|
|
52692
|
+
console.error(import_picocolors6.default.dim(`${sessionTag} message.part.delta (${field}): "${preview}${delta.length > 80 ? "..." : ""}"`));
|
|
51836
52693
|
break;
|
|
51837
52694
|
}
|
|
51838
52695
|
case "message.updated": {
|
|
@@ -51841,7 +52698,7 @@ function logEventVerbose(ctx, payload) {
|
|
|
51841
52698
|
const model = msgProps?.info?.modelID;
|
|
51842
52699
|
const agent = msgProps?.info?.agent;
|
|
51843
52700
|
const details = [role, agent, model].filter(Boolean).join(", ");
|
|
51844
|
-
console.error(
|
|
52701
|
+
console.error(import_picocolors6.default.dim(`${sessionTag} message.updated (${details})`));
|
|
51845
52702
|
break;
|
|
51846
52703
|
}
|
|
51847
52704
|
case "tool.execute": {
|
|
@@ -51859,32 +52716,32 @@ function logEventVerbose(ctx, payload) {
|
|
|
51859
52716
|
}
|
|
51860
52717
|
}
|
|
51861
52718
|
const inputPreview = inputStr.slice(0, 150);
|
|
51862
|
-
console.error(
|
|
51863
|
-
console.error(
|
|
52719
|
+
console.error(import_picocolors6.default.cyan(`${sessionTag} TOOL.EXECUTE: ${import_picocolors6.default.bold(toolName)}`));
|
|
52720
|
+
console.error(import_picocolors6.default.dim(` input: ${inputPreview}${inputStr.length >= 150 ? "..." : ""}`));
|
|
51864
52721
|
break;
|
|
51865
52722
|
}
|
|
51866
52723
|
case "tool.result": {
|
|
51867
52724
|
const resultProps = props;
|
|
51868
52725
|
const output = resultProps?.output ?? "";
|
|
51869
52726
|
const preview = output.slice(0, 200).replace(/\n/g, "\\n");
|
|
51870
|
-
console.error(
|
|
52727
|
+
console.error(import_picocolors6.default.green(`${sessionTag} TOOL.RESULT: "${preview}${output.length > 200 ? "..." : ""}"`));
|
|
51871
52728
|
break;
|
|
51872
52729
|
}
|
|
51873
52730
|
case "session.error": {
|
|
51874
52731
|
const errorProps = props;
|
|
51875
52732
|
const errorMsg = serializeError(errorProps?.error);
|
|
51876
|
-
console.error(
|
|
52733
|
+
console.error(import_picocolors6.default.red(`${sessionTag} SESSION.ERROR: ${errorMsg}`));
|
|
51877
52734
|
break;
|
|
51878
52735
|
}
|
|
51879
52736
|
default:
|
|
51880
|
-
console.error(
|
|
52737
|
+
console.error(import_picocolors6.default.dim(`${sessionTag} ${payload.type}`));
|
|
51881
52738
|
}
|
|
51882
52739
|
}
|
|
51883
52740
|
// src/cli/run/event-stream-processor.ts
|
|
51884
|
-
var
|
|
52741
|
+
var import_picocolors9 = __toESM(require_picocolors(), 1);
|
|
51885
52742
|
|
|
51886
52743
|
// src/cli/run/event-handlers.ts
|
|
51887
|
-
var
|
|
52744
|
+
var import_picocolors8 = __toESM(require_picocolors(), 1);
|
|
51888
52745
|
|
|
51889
52746
|
// src/cli/run/tool-input-preview.ts
|
|
51890
52747
|
function formatToolHeader(toolName, input) {
|
|
@@ -52020,14 +52877,14 @@ var displayChars = {
|
|
|
52020
52877
|
};
|
|
52021
52878
|
|
|
52022
52879
|
// src/cli/run/output-renderer.ts
|
|
52023
|
-
var
|
|
52880
|
+
var import_picocolors7 = __toESM(require_picocolors(), 1);
|
|
52024
52881
|
function renderAgentHeader(agent, model, variant, agentColorsByName) {
|
|
52025
52882
|
if (!agent && !model)
|
|
52026
52883
|
return;
|
|
52027
|
-
const agentLabel = agent ?
|
|
52884
|
+
const agentLabel = agent ? import_picocolors7.default.bold(colorizeWithProfileColor(agent, agentColorsByName[agent])) : "";
|
|
52028
52885
|
const modelBase = model ?? "";
|
|
52029
52886
|
const variantSuffix = variant ? ` (${variant})` : "";
|
|
52030
|
-
const modelLabel = model ?
|
|
52887
|
+
const modelLabel = model ? import_picocolors7.default.dim(`${modelBase}${variantSuffix}`) : "";
|
|
52031
52888
|
process.stdout.write(`
|
|
52032
52889
|
`);
|
|
52033
52890
|
if (modelLabel) {
|
|
@@ -52035,7 +52892,7 @@ function renderAgentHeader(agent, model, variant, agentColorsByName) {
|
|
|
52035
52892
|
`);
|
|
52036
52893
|
}
|
|
52037
52894
|
if (agentLabel) {
|
|
52038
|
-
process.stdout.write(` ${
|
|
52895
|
+
process.stdout.write(` ${import_picocolors7.default.dim("\u2514\u2500")} ${agentLabel}
|
|
52039
52896
|
`);
|
|
52040
52897
|
}
|
|
52041
52898
|
process.stdout.write(`
|
|
@@ -52043,7 +52900,7 @@ function renderAgentHeader(agent, model, variant, agentColorsByName) {
|
|
|
52043
52900
|
}
|
|
52044
52901
|
function openThinkBlock() {
|
|
52045
52902
|
process.stdout.write(`
|
|
52046
|
-
${
|
|
52903
|
+
${import_picocolors7.default.dim("\u2503 Thinking:")} `);
|
|
52047
52904
|
}
|
|
52048
52905
|
function closeThinkBlock() {
|
|
52049
52906
|
process.stdout.write(`
|
|
@@ -52077,10 +52934,10 @@ function writePaddedText(text, atLineStart) {
|
|
|
52077
52934
|
}
|
|
52078
52935
|
function colorizeWithProfileColor(text, hexColor) {
|
|
52079
52936
|
if (!hexColor)
|
|
52080
|
-
return
|
|
52937
|
+
return import_picocolors7.default.magenta(text);
|
|
52081
52938
|
const rgb = parseHexColor(hexColor);
|
|
52082
52939
|
if (!rgb)
|
|
52083
|
-
return
|
|
52940
|
+
return import_picocolors7.default.magenta(text);
|
|
52084
52941
|
const [r2, g2, b3] = rgb;
|
|
52085
52942
|
return `\x1B[38;2;${r2};${g2};${b3}m${text}\x1B[39m`;
|
|
52086
52943
|
}
|
|
@@ -52120,7 +52977,7 @@ function renderCompletionMetaLine(state, messageID) {
|
|
|
52120
52977
|
const agent = state.currentAgent ?? "assistant";
|
|
52121
52978
|
const model = state.currentModel ?? "unknown-model";
|
|
52122
52979
|
const variant = state.currentVariant ? ` (${state.currentVariant})` : "";
|
|
52123
|
-
process.stdout.write(
|
|
52980
|
+
process.stdout.write(import_picocolors8.default.dim(`
|
|
52124
52981
|
${displayChars.treeEnd} ${agent} \xB7 ${model}${variant} \xB7 ${elapsedSec}s
|
|
52125
52982
|
`));
|
|
52126
52983
|
state.completionMetaPrintedByMessageId[messageID] = true;
|
|
@@ -52154,7 +53011,7 @@ function handleSessionError(ctx, payload, state) {
|
|
|
52154
53011
|
if (getSessionId(props) === ctx.sessionID) {
|
|
52155
53012
|
state.mainSessionError = true;
|
|
52156
53013
|
state.lastError = serializeError(props?.error);
|
|
52157
|
-
console.error(
|
|
53014
|
+
console.error(import_picocolors8.default.red(`
|
|
52158
53015
|
[session.error] ${state.lastError}`));
|
|
52159
53016
|
}
|
|
52160
53017
|
}
|
|
@@ -52182,7 +53039,7 @@ function handleMessagePartUpdated(ctx, payload, state) {
|
|
|
52182
53039
|
const newText = reasoningText.slice(state.lastReasoningText.length);
|
|
52183
53040
|
if (newText) {
|
|
52184
53041
|
const padded = writePaddedText(newText, state.thinkingAtLineStart);
|
|
52185
|
-
process.stdout.write(
|
|
53042
|
+
process.stdout.write(import_picocolors8.default.dim(padded.output));
|
|
52186
53043
|
state.thinkingAtLineStart = padded.atLineStart;
|
|
52187
53044
|
state.hasReceivedMeaningfulWork = true;
|
|
52188
53045
|
}
|
|
@@ -52229,7 +53086,7 @@ function handleMessagePartDelta(ctx, payload, state) {
|
|
|
52229
53086
|
if (partType === "reasoning") {
|
|
52230
53087
|
ensureThinkBlockOpen(state);
|
|
52231
53088
|
const padded2 = writePaddedText(delta, state.thinkingAtLineStart);
|
|
52232
|
-
process.stdout.write(
|
|
53089
|
+
process.stdout.write(import_picocolors8.default.dim(padded2.output));
|
|
52233
53090
|
state.thinkingAtLineStart = padded2.atLineStart;
|
|
52234
53091
|
state.lastReasoningText += delta;
|
|
52235
53092
|
state.hasReceivedMeaningfulWork = true;
|
|
@@ -52250,10 +53107,10 @@ function handleToolPart(_ctx, part, state) {
|
|
|
52250
53107
|
return;
|
|
52251
53108
|
state.currentTool = toolName;
|
|
52252
53109
|
const header = formatToolHeader(toolName, part.state?.input ?? {});
|
|
52253
|
-
const suffix = header.description ? ` ${
|
|
53110
|
+
const suffix = header.description ? ` ${import_picocolors8.default.dim(header.description)}` : "";
|
|
52254
53111
|
state.hasReceivedMeaningfulWork = true;
|
|
52255
53112
|
process.stdout.write(`
|
|
52256
|
-
${
|
|
53113
|
+
${import_picocolors8.default.cyan(header.icon)} ${import_picocolors8.default.bold(header.title)}${suffix}
|
|
52257
53114
|
`);
|
|
52258
53115
|
}
|
|
52259
53116
|
if (status === "completed" || status === "error") {
|
|
@@ -52261,10 +53118,10 @@ function handleToolPart(_ctx, part, state) {
|
|
|
52261
53118
|
return;
|
|
52262
53119
|
const output = part.state?.output || "";
|
|
52263
53120
|
if (output.trim()) {
|
|
52264
|
-
process.stdout.write(
|
|
53121
|
+
process.stdout.write(import_picocolors8.default.dim(` ${displayChars.treeEnd} output
|
|
52265
53122
|
`));
|
|
52266
53123
|
const padded = writePaddedText(output, true);
|
|
52267
|
-
process.stdout.write(
|
|
53124
|
+
process.stdout.write(import_picocolors8.default.dim(padded.output + (padded.atLineStart ? "" : " ")));
|
|
52268
53125
|
process.stdout.write(`
|
|
52269
53126
|
`);
|
|
52270
53127
|
}
|
|
@@ -52326,10 +53183,10 @@ function handleToolExecute(ctx, payload, state) {
|
|
|
52326
53183
|
const toolName = props?.name || "unknown";
|
|
52327
53184
|
state.currentTool = toolName;
|
|
52328
53185
|
const header = formatToolHeader(toolName, props?.input ?? {});
|
|
52329
|
-
const suffix = header.description ? ` ${
|
|
53186
|
+
const suffix = header.description ? ` ${import_picocolors8.default.dim(header.description)}` : "";
|
|
52330
53187
|
state.hasReceivedMeaningfulWork = true;
|
|
52331
53188
|
process.stdout.write(`
|
|
52332
|
-
${
|
|
53189
|
+
${import_picocolors8.default.cyan(header.icon)} ${import_picocolors8.default.bold(header.title)}${suffix}
|
|
52333
53190
|
`);
|
|
52334
53191
|
}
|
|
52335
53192
|
function handleToolResult(ctx, payload, state) {
|
|
@@ -52343,10 +53200,10 @@ function handleToolResult(ctx, payload, state) {
|
|
|
52343
53200
|
return;
|
|
52344
53201
|
const output = props?.output || "";
|
|
52345
53202
|
if (output.trim()) {
|
|
52346
|
-
process.stdout.write(
|
|
53203
|
+
process.stdout.write(import_picocolors8.default.dim(` ${displayChars.treeEnd} output
|
|
52347
53204
|
`));
|
|
52348
53205
|
const padded = writePaddedText(output, true);
|
|
52349
|
-
process.stdout.write(
|
|
53206
|
+
process.stdout.write(import_picocolors8.default.dim(padded.output + (padded.atLineStart ? "" : " ")));
|
|
52350
53207
|
process.stdout.write(`
|
|
52351
53208
|
`);
|
|
52352
53209
|
}
|
|
@@ -52395,7 +53252,7 @@ async function processEvents(ctx, stream, state) {
|
|
|
52395
53252
|
const payload = event;
|
|
52396
53253
|
if (!payload?.type) {
|
|
52397
53254
|
if (ctx.verbose) {
|
|
52398
|
-
console.error(
|
|
53255
|
+
console.error(import_picocolors9.default.dim(`[event] no type: ${JSON.stringify(event)}`));
|
|
52399
53256
|
}
|
|
52400
53257
|
continue;
|
|
52401
53258
|
}
|
|
@@ -52413,7 +53270,7 @@ async function processEvents(ctx, stream, state) {
|
|
|
52413
53270
|
handleToolResult(ctx, payload, state);
|
|
52414
53271
|
handleTuiToast(ctx, payload, state);
|
|
52415
53272
|
} catch (err) {
|
|
52416
|
-
console.error(
|
|
53273
|
+
console.error(import_picocolors9.default.red(`[event error] ${err}`));
|
|
52417
53274
|
}
|
|
52418
53275
|
}
|
|
52419
53276
|
}
|
|
@@ -66488,12 +67345,12 @@ init_shared();
|
|
|
66488
67345
|
// src/shared/migrate-legacy-config-file.ts
|
|
66489
67346
|
init_logger();
|
|
66490
67347
|
init_write_file_atomically();
|
|
66491
|
-
import { existsSync as
|
|
66492
|
-
import { join as
|
|
67348
|
+
import { existsSync as existsSync14, readFileSync as readFileSync9, renameSync as renameSync2, rmSync } from "fs";
|
|
67349
|
+
import { join as join12, dirname as dirname2, basename } from "path";
|
|
66493
67350
|
function buildCanonicalPath(legacyPath) {
|
|
66494
|
-
const dir =
|
|
67351
|
+
const dir = dirname2(legacyPath);
|
|
66495
67352
|
const ext = basename(legacyPath).includes(".jsonc") ? ".jsonc" : ".json";
|
|
66496
|
-
return
|
|
67353
|
+
return join12(dir, `${CONFIG_BASENAME}${ext}`);
|
|
66497
67354
|
}
|
|
66498
67355
|
function archiveLegacyConfigFile(legacyPath) {
|
|
66499
67356
|
const backupPath = `${legacyPath}.bak`;
|
|
@@ -66525,15 +67382,15 @@ function archiveLegacyConfigFile(legacyPath) {
|
|
|
66525
67382
|
}
|
|
66526
67383
|
}
|
|
66527
67384
|
function migrateLegacyConfigFile(legacyPath) {
|
|
66528
|
-
if (!
|
|
67385
|
+
if (!existsSync14(legacyPath))
|
|
66529
67386
|
return false;
|
|
66530
67387
|
if (!basename(legacyPath).startsWith(LEGACY_CONFIG_BASENAME))
|
|
66531
67388
|
return false;
|
|
66532
67389
|
const canonicalPath = buildCanonicalPath(legacyPath);
|
|
66533
|
-
if (
|
|
67390
|
+
if (existsSync14(canonicalPath))
|
|
66534
67391
|
return false;
|
|
66535
67392
|
try {
|
|
66536
|
-
const content =
|
|
67393
|
+
const content = readFileSync9(legacyPath, "utf-8");
|
|
66537
67394
|
writeFileAtomically(canonicalPath, content);
|
|
66538
67395
|
const archivedLegacyConfig = archiveLegacyConfigFile(legacyPath);
|
|
66539
67396
|
log("[migrateLegacyConfigFile] Migrated legacy config to canonical path", {
|
|
@@ -68064,6 +68921,31 @@ class OpencodeClient extends _HeyApiClient {
|
|
|
68064
68921
|
}
|
|
68065
68922
|
|
|
68066
68923
|
// node_modules/@opencode-ai/sdk/dist/client.js
|
|
68924
|
+
function pick2(value, fallback) {
|
|
68925
|
+
if (!value)
|
|
68926
|
+
return;
|
|
68927
|
+
if (!fallback)
|
|
68928
|
+
return value;
|
|
68929
|
+
if (value === fallback)
|
|
68930
|
+
return fallback;
|
|
68931
|
+
if (value === encodeURIComponent(fallback))
|
|
68932
|
+
return fallback;
|
|
68933
|
+
return value;
|
|
68934
|
+
}
|
|
68935
|
+
function rewrite(request, directory) {
|
|
68936
|
+
if (request.method !== "GET" && request.method !== "HEAD")
|
|
68937
|
+
return request;
|
|
68938
|
+
const value = pick2(request.headers.get("x-opencode-directory"), directory);
|
|
68939
|
+
if (!value)
|
|
68940
|
+
return request;
|
|
68941
|
+
const url2 = new URL(request.url);
|
|
68942
|
+
if (!url2.searchParams.has("directory")) {
|
|
68943
|
+
url2.searchParams.set("directory", value);
|
|
68944
|
+
}
|
|
68945
|
+
const next = new Request(url2, request);
|
|
68946
|
+
next.headers.delete("x-opencode-directory");
|
|
68947
|
+
return next;
|
|
68948
|
+
}
|
|
68067
68949
|
function createOpencodeClient(config2) {
|
|
68068
68950
|
if (!config2?.fetch) {
|
|
68069
68951
|
const customFetch = (req) => {
|
|
@@ -68082,10 +68964,46 @@ function createOpencodeClient(config2) {
|
|
|
68082
68964
|
};
|
|
68083
68965
|
}
|
|
68084
68966
|
const client2 = createClient(config2);
|
|
68967
|
+
client2.interceptors.request.use((request) => rewrite(request, config2?.directory));
|
|
68085
68968
|
return new OpencodeClient({ client: client2 });
|
|
68086
68969
|
}
|
|
68087
68970
|
// node_modules/@opencode-ai/sdk/dist/server.js
|
|
68088
|
-
|
|
68971
|
+
var import_cross_spawn = __toESM(require_cross_spawn(), 1);
|
|
68972
|
+
|
|
68973
|
+
// node_modules/@opencode-ai/sdk/dist/process.js
|
|
68974
|
+
import { spawnSync } from "child_process";
|
|
68975
|
+
function stop(proc) {
|
|
68976
|
+
if (proc.exitCode !== null || proc.signalCode !== null)
|
|
68977
|
+
return;
|
|
68978
|
+
if (process.platform === "win32" && proc.pid) {
|
|
68979
|
+
const out = spawnSync("taskkill", ["/pid", String(proc.pid), "/T", "/F"], { windowsHide: true });
|
|
68980
|
+
if (!out.error && out.status === 0)
|
|
68981
|
+
return;
|
|
68982
|
+
}
|
|
68983
|
+
proc.kill();
|
|
68984
|
+
}
|
|
68985
|
+
function bindAbort(proc, signal, onAbort) {
|
|
68986
|
+
if (!signal)
|
|
68987
|
+
return () => {};
|
|
68988
|
+
const abort = () => {
|
|
68989
|
+
clear();
|
|
68990
|
+
stop(proc);
|
|
68991
|
+
onAbort?.();
|
|
68992
|
+
};
|
|
68993
|
+
const clear = () => {
|
|
68994
|
+
signal.removeEventListener("abort", abort);
|
|
68995
|
+
proc.off("exit", clear);
|
|
68996
|
+
proc.off("error", clear);
|
|
68997
|
+
};
|
|
68998
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
68999
|
+
proc.on("exit", clear);
|
|
69000
|
+
proc.on("error", clear);
|
|
69001
|
+
if (signal.aborted)
|
|
69002
|
+
abort();
|
|
69003
|
+
return clear;
|
|
69004
|
+
}
|
|
69005
|
+
|
|
69006
|
+
// node_modules/@opencode-ai/sdk/dist/server.js
|
|
68089
69007
|
async function createOpencodeServer(options) {
|
|
68090
69008
|
options = Object.assign({
|
|
68091
69009
|
hostname: "127.0.0.1",
|
|
@@ -68095,19 +69013,24 @@ async function createOpencodeServer(options) {
|
|
|
68095
69013
|
const args = [`serve`, `--hostname=${options.hostname}`, `--port=${options.port}`];
|
|
68096
69014
|
if (options.config?.logLevel)
|
|
68097
69015
|
args.push(`--log-level=${options.config.logLevel}`);
|
|
68098
|
-
const proc =
|
|
68099
|
-
signal: options.signal,
|
|
69016
|
+
const proc = import_cross_spawn.default(`opencode`, args, {
|
|
68100
69017
|
env: {
|
|
68101
69018
|
...process.env,
|
|
68102
69019
|
OPENCODE_CONFIG_CONTENT: JSON.stringify(options.config ?? {})
|
|
68103
69020
|
}
|
|
68104
69021
|
});
|
|
69022
|
+
let clear = () => {};
|
|
68105
69023
|
const url2 = await new Promise((resolve2, reject) => {
|
|
68106
69024
|
const id = setTimeout(() => {
|
|
69025
|
+
clear();
|
|
69026
|
+
stop(proc);
|
|
68107
69027
|
reject(new Error(`Timeout waiting for server to start after ${options.timeout}ms`));
|
|
68108
69028
|
}, options.timeout);
|
|
68109
69029
|
let output = "";
|
|
69030
|
+
let resolved = false;
|
|
68110
69031
|
proc.stdout?.on("data", (chunk) => {
|
|
69032
|
+
if (resolved)
|
|
69033
|
+
return;
|
|
68111
69034
|
output += chunk.toString();
|
|
68112
69035
|
const lines = output.split(`
|
|
68113
69036
|
`);
|
|
@@ -68115,9 +69038,14 @@ async function createOpencodeServer(options) {
|
|
|
68115
69038
|
if (line.startsWith("opencode server listening")) {
|
|
68116
69039
|
const match = line.match(/on\s+(https?:\/\/[^\s]+)/);
|
|
68117
69040
|
if (!match) {
|
|
68118
|
-
|
|
69041
|
+
clear();
|
|
69042
|
+
stop(proc);
|
|
69043
|
+
clearTimeout(id);
|
|
69044
|
+
reject(new Error(`Failed to parse server url from output: ${line}`));
|
|
69045
|
+
return;
|
|
68119
69046
|
}
|
|
68120
69047
|
clearTimeout(id);
|
|
69048
|
+
resolved = true;
|
|
68121
69049
|
resolve2(match[1]);
|
|
68122
69050
|
return;
|
|
68123
69051
|
}
|
|
@@ -68139,17 +69067,16 @@ Server output: ${output}`;
|
|
|
68139
69067
|
clearTimeout(id);
|
|
68140
69068
|
reject(error48);
|
|
68141
69069
|
});
|
|
68142
|
-
|
|
68143
|
-
|
|
68144
|
-
|
|
68145
|
-
|
|
68146
|
-
});
|
|
68147
|
-
}
|
|
69070
|
+
clear = bindAbort(proc, options.signal, () => {
|
|
69071
|
+
clearTimeout(id);
|
|
69072
|
+
reject(options.signal?.reason);
|
|
69073
|
+
});
|
|
68148
69074
|
});
|
|
68149
69075
|
return {
|
|
68150
69076
|
url: url2,
|
|
68151
69077
|
close() {
|
|
68152
|
-
|
|
69078
|
+
clear();
|
|
69079
|
+
stop(proc);
|
|
68153
69080
|
}
|
|
68154
69081
|
};
|
|
68155
69082
|
}
|
|
@@ -68169,11 +69096,11 @@ async function createOpencode(options) {
|
|
|
68169
69096
|
|
|
68170
69097
|
// src/cli/run/server-connection.ts
|
|
68171
69098
|
init_port_utils();
|
|
68172
|
-
var
|
|
69099
|
+
var import_picocolors10 = __toESM(require_picocolors(), 1);
|
|
68173
69100
|
|
|
68174
69101
|
// src/cli/run/opencode-binary-resolver.ts
|
|
68175
69102
|
init_spawn_with_windows_hide();
|
|
68176
|
-
import { delimiter, dirname as
|
|
69103
|
+
import { delimiter, dirname as dirname4, join as join14 } from "path";
|
|
68177
69104
|
var OPENCODE_COMMANDS = ["opencode", "opencode-desktop"];
|
|
68178
69105
|
var WINDOWS_SUFFIXES = ["", ".exe", ".cmd", ".bat", ".ps1"];
|
|
68179
69106
|
function getCommandCandidates(platform) {
|
|
@@ -68196,7 +69123,7 @@ function collectCandidateBinaryPaths(pathEnv, which = Bun.which, platform = proc
|
|
|
68196
69123
|
}
|
|
68197
69124
|
for (const entry of (pathEnv ?? "").split(delimiter).filter(Boolean)) {
|
|
68198
69125
|
for (const command of commandCandidates) {
|
|
68199
|
-
addCandidate(
|
|
69126
|
+
addCandidate(join14(entry, command));
|
|
68200
69127
|
}
|
|
68201
69128
|
}
|
|
68202
69129
|
return candidates;
|
|
@@ -68223,7 +69150,7 @@ async function findWorkingOpencodeBinary(pathEnv = process.env.PATH, probe = can
|
|
|
68223
69150
|
return null;
|
|
68224
69151
|
}
|
|
68225
69152
|
function buildPathWithBinaryFirst(pathEnv, binaryPath) {
|
|
68226
|
-
const preferredDir =
|
|
69153
|
+
const preferredDir = dirname4(binaryPath);
|
|
68227
69154
|
const existing = (pathEnv ?? "").split(delimiter).filter((entry) => entry.length > 0 && entry !== preferredDir);
|
|
68228
69155
|
return [preferredDir, ...existing].join(delimiter);
|
|
68229
69156
|
}
|
|
@@ -68257,13 +69184,13 @@ function isPortRangeExhausted(error48) {
|
|
|
68257
69184
|
async function startServer(options) {
|
|
68258
69185
|
const { signal, port } = options;
|
|
68259
69186
|
const { client: client3, server: server2 } = await withWorkingOpencodePath(() => createOpencode({ signal, port, hostname: "127.0.0.1" }));
|
|
68260
|
-
console.log(
|
|
69187
|
+
console.log(import_picocolors10.default.dim("Server listening at"), import_picocolors10.default.cyan(server2.url));
|
|
68261
69188
|
return { client: client3, cleanup: () => server2.close() };
|
|
68262
69189
|
}
|
|
68263
69190
|
async function createServerConnection(options) {
|
|
68264
69191
|
const { port, attach, signal } = options;
|
|
68265
69192
|
if (attach !== undefined) {
|
|
68266
|
-
console.log(
|
|
69193
|
+
console.log(import_picocolors10.default.dim("Attaching to existing server at"), import_picocolors10.default.cyan(attach));
|
|
68267
69194
|
const client3 = createOpencodeClient({ baseUrl: attach });
|
|
68268
69195
|
return { client: client3, cleanup: () => {} };
|
|
68269
69196
|
}
|
|
@@ -68273,7 +69200,7 @@ async function createServerConnection(options) {
|
|
|
68273
69200
|
}
|
|
68274
69201
|
const available = await isPortAvailable(port, "127.0.0.1");
|
|
68275
69202
|
if (available) {
|
|
68276
|
-
console.log(
|
|
69203
|
+
console.log(import_picocolors10.default.dim("Starting server on port"), import_picocolors10.default.cyan(port.toString()));
|
|
68277
69204
|
try {
|
|
68278
69205
|
return await startServer({ signal, port });
|
|
68279
69206
|
} catch (error48) {
|
|
@@ -68284,12 +69211,12 @@ async function createServerConnection(options) {
|
|
|
68284
69211
|
if (stillAvailable) {
|
|
68285
69212
|
throw error48;
|
|
68286
69213
|
}
|
|
68287
|
-
console.log(
|
|
69214
|
+
console.log(import_picocolors10.default.dim("Port"), import_picocolors10.default.cyan(port.toString()), import_picocolors10.default.dim("became occupied, attaching to existing server"));
|
|
68288
69215
|
const client4 = createOpencodeClient({ baseUrl: `http://127.0.0.1:${port}` });
|
|
68289
69216
|
return { client: client4, cleanup: () => {} };
|
|
68290
69217
|
}
|
|
68291
69218
|
}
|
|
68292
|
-
console.log(
|
|
69219
|
+
console.log(import_picocolors10.default.dim("Port"), import_picocolors10.default.cyan(port.toString()), import_picocolors10.default.dim("is occupied, attaching to existing server"));
|
|
68293
69220
|
const client3 = createOpencodeClient({ baseUrl: `http://127.0.0.1:${port}` });
|
|
68294
69221
|
return { client: client3, cleanup: () => {} };
|
|
68295
69222
|
}
|
|
@@ -68307,14 +69234,14 @@ async function createServerConnection(options) {
|
|
|
68307
69234
|
if (defaultPortIsAvailable) {
|
|
68308
69235
|
throw error48;
|
|
68309
69236
|
}
|
|
68310
|
-
console.log(
|
|
69237
|
+
console.log(import_picocolors10.default.dim("Port range exhausted, attaching to existing server on"), import_picocolors10.default.cyan(DEFAULT_SERVER_PORT.toString()));
|
|
68311
69238
|
const client3 = createOpencodeClient({ baseUrl: `http://127.0.0.1:${DEFAULT_SERVER_PORT}` });
|
|
68312
69239
|
return { client: client3, cleanup: () => {} };
|
|
68313
69240
|
}
|
|
68314
69241
|
if (wasAutoSelected) {
|
|
68315
|
-
console.log(
|
|
69242
|
+
console.log(import_picocolors10.default.dim("Auto-selected port"), import_picocolors10.default.cyan(selectedPort.toString()));
|
|
68316
69243
|
} else {
|
|
68317
|
-
console.log(
|
|
69244
|
+
console.log(import_picocolors10.default.dim("Starting server on port"), import_picocolors10.default.cyan(selectedPort.toString()));
|
|
68318
69245
|
}
|
|
68319
69246
|
try {
|
|
68320
69247
|
return await startServer({ signal, port: selectedPort });
|
|
@@ -68323,13 +69250,13 @@ async function createServerConnection(options) {
|
|
|
68323
69250
|
throw error48;
|
|
68324
69251
|
}
|
|
68325
69252
|
const { port: retryPort } = await getAvailableServerPort(selectedPort + 1, "127.0.0.1");
|
|
68326
|
-
console.log(
|
|
69253
|
+
console.log(import_picocolors10.default.dim("Retrying server start on port"), import_picocolors10.default.cyan(retryPort.toString()));
|
|
68327
69254
|
return await startServer({ signal, port: retryPort });
|
|
68328
69255
|
}
|
|
68329
69256
|
}
|
|
68330
69257
|
|
|
68331
69258
|
// src/cli/run/session-resolver.ts
|
|
68332
|
-
var
|
|
69259
|
+
var import_picocolors11 = __toESM(require_picocolors(), 1);
|
|
68333
69260
|
var SESSION_CREATE_MAX_RETRIES = 3;
|
|
68334
69261
|
var SESSION_CREATE_RETRY_DELAY_MS = 1000;
|
|
68335
69262
|
async function resolveSession(options) {
|
|
@@ -68355,11 +69282,11 @@ async function resolveSession(options) {
|
|
|
68355
69282
|
query: { directory }
|
|
68356
69283
|
});
|
|
68357
69284
|
if (res.error) {
|
|
68358
|
-
console.error(
|
|
68359
|
-
console.error(
|
|
69285
|
+
console.error(import_picocolors11.default.yellow(`Session create attempt ${attempt}/${SESSION_CREATE_MAX_RETRIES} failed:`));
|
|
69286
|
+
console.error(import_picocolors11.default.dim(` Error: ${serializeError(res.error)}`));
|
|
68360
69287
|
if (attempt < SESSION_CREATE_MAX_RETRIES) {
|
|
68361
69288
|
const delay = SESSION_CREATE_RETRY_DELAY_MS * attempt;
|
|
68362
|
-
console.log(
|
|
69289
|
+
console.log(import_picocolors11.default.dim(` Retrying in ${delay}ms...`));
|
|
68363
69290
|
await new Promise((resolve2) => setTimeout(resolve2, delay));
|
|
68364
69291
|
}
|
|
68365
69292
|
continue;
|
|
@@ -68367,10 +69294,10 @@ async function resolveSession(options) {
|
|
|
68367
69294
|
if (res.data?.id) {
|
|
68368
69295
|
return res.data.id;
|
|
68369
69296
|
}
|
|
68370
|
-
console.error(
|
|
69297
|
+
console.error(import_picocolors11.default.yellow(`Session create attempt ${attempt}/${SESSION_CREATE_MAX_RETRIES}: No session ID returned`));
|
|
68371
69298
|
if (attempt < SESSION_CREATE_MAX_RETRIES) {
|
|
68372
69299
|
const delay = SESSION_CREATE_RETRY_DELAY_MS * attempt;
|
|
68373
|
-
console.log(
|
|
69300
|
+
console.log(import_picocolors11.default.dim(` Retrying in ${delay}ms...`));
|
|
68374
69301
|
await new Promise((resolve2) => setTimeout(resolve2, delay));
|
|
68375
69302
|
}
|
|
68376
69303
|
}
|
|
@@ -68488,7 +69415,7 @@ async function executeOnCompleteHook(options) {
|
|
|
68488
69415
|
|
|
68489
69416
|
// src/cli/run/agent-resolver.ts
|
|
68490
69417
|
init_agent_display_names();
|
|
68491
|
-
var
|
|
69418
|
+
var import_picocolors12 = __toESM(require_picocolors(), 1);
|
|
68492
69419
|
var CORE_AGENT_ORDER = ["sisyphus", "hephaestus", "prometheus", "atlas"];
|
|
68493
69420
|
var DEFAULT_AGENT = "sisyphus";
|
|
68494
69421
|
var normalizeAgentName = (agent) => {
|
|
@@ -68533,10 +69460,10 @@ var resolveRunAgent = (options, pluginConfig, env = process.env) => {
|
|
|
68533
69460
|
const fallbackName = getAgentDisplayName(fallback);
|
|
68534
69461
|
const fallbackDisabled = isAgentDisabled(fallback, pluginConfig);
|
|
68535
69462
|
if (fallbackDisabled) {
|
|
68536
|
-
console.log(
|
|
69463
|
+
console.log(import_picocolors12.default.yellow(`Requested agent "${resolved.resolvedName}" is disabled and no enabled core agent was found. Proceeding with "${fallbackName}".`));
|
|
68537
69464
|
return fallbackName;
|
|
68538
69465
|
}
|
|
68539
|
-
console.log(
|
|
69466
|
+
console.log(import_picocolors12.default.yellow(`Requested agent "${resolved.resolvedName}" is disabled. Falling back to "${fallbackName}".`));
|
|
68540
69467
|
return fallbackName;
|
|
68541
69468
|
}
|
|
68542
69469
|
return resolved.resolvedName;
|
|
@@ -68567,11 +69494,11 @@ function resolveRunModel(modelString) {
|
|
|
68567
69494
|
}
|
|
68568
69495
|
|
|
68569
69496
|
// src/cli/run/poll-for-completion.ts
|
|
68570
|
-
var
|
|
69497
|
+
var import_picocolors14 = __toESM(require_picocolors(), 1);
|
|
68571
69498
|
|
|
68572
69499
|
// src/cli/run/completion.ts
|
|
68573
69500
|
init_shared();
|
|
68574
|
-
var
|
|
69501
|
+
var import_picocolors13 = __toESM(require_picocolors(), 1);
|
|
68575
69502
|
// src/features/boulder-state/constants.ts
|
|
68576
69503
|
var BOULDER_DIR = ".sisyphus";
|
|
68577
69504
|
var BOULDER_FILE = "boulder.json";
|
|
@@ -68579,19 +69506,19 @@ var BOULDER_STATE_PATH = `${BOULDER_DIR}/${BOULDER_FILE}`;
|
|
|
68579
69506
|
var NOTEPAD_DIR = "notepads";
|
|
68580
69507
|
var NOTEPAD_BASE_PATH = `${BOULDER_DIR}/${NOTEPAD_DIR}`;
|
|
68581
69508
|
// src/features/boulder-state/storage.ts
|
|
68582
|
-
import { existsSync as
|
|
68583
|
-
import { dirname as
|
|
69509
|
+
import { existsSync as existsSync16, readFileSync as readFileSync11, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, readdirSync as readdirSync3 } from "fs";
|
|
69510
|
+
import { dirname as dirname5, join as join15, basename as basename3 } from "path";
|
|
68584
69511
|
var RESERVED_KEYS = new Set(["__proto__", "prototype", "constructor"]);
|
|
68585
69512
|
function getBoulderFilePath(directory) {
|
|
68586
|
-
return
|
|
69513
|
+
return join15(directory, BOULDER_DIR, BOULDER_FILE);
|
|
68587
69514
|
}
|
|
68588
69515
|
function readBoulderState(directory) {
|
|
68589
69516
|
const filePath = getBoulderFilePath(directory);
|
|
68590
|
-
if (!
|
|
69517
|
+
if (!existsSync16(filePath)) {
|
|
68591
69518
|
return null;
|
|
68592
69519
|
}
|
|
68593
69520
|
try {
|
|
68594
|
-
const content =
|
|
69521
|
+
const content = readFileSync11(filePath, "utf-8");
|
|
68595
69522
|
const parsed = JSON.parse(content);
|
|
68596
69523
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
68597
69524
|
return null;
|
|
@@ -68599,6 +69526,15 @@ function readBoulderState(directory) {
|
|
|
68599
69526
|
if (!Array.isArray(parsed.session_ids)) {
|
|
68600
69527
|
parsed.session_ids = [];
|
|
68601
69528
|
}
|
|
69529
|
+
if (!parsed.session_origins || typeof parsed.session_origins !== "object" || Array.isArray(parsed.session_origins)) {
|
|
69530
|
+
parsed.session_origins = {};
|
|
69531
|
+
}
|
|
69532
|
+
if (parsed.session_ids.length === 1) {
|
|
69533
|
+
const soleSessionId = parsed.session_ids[0];
|
|
69534
|
+
if (typeof soleSessionId === "string" && parsed.session_origins[soleSessionId] !== "appended" && parsed.session_origins[soleSessionId] !== "direct") {
|
|
69535
|
+
parsed.session_origins[soleSessionId] = "direct";
|
|
69536
|
+
}
|
|
69537
|
+
}
|
|
68602
69538
|
if (!parsed.task_sessions || typeof parsed.task_sessions !== "object" || Array.isArray(parsed.task_sessions)) {
|
|
68603
69539
|
parsed.task_sessions = {};
|
|
68604
69540
|
}
|
|
@@ -68607,39 +69543,101 @@ function readBoulderState(directory) {
|
|
|
68607
69543
|
return null;
|
|
68608
69544
|
}
|
|
68609
69545
|
}
|
|
69546
|
+
var TODO_HEADING_PATTERN = /^##\s+TODOs\b/i;
|
|
69547
|
+
var FINAL_VERIFICATION_HEADING_PATTERN = /^##\s+Final Verification Wave\b/i;
|
|
69548
|
+
var SECOND_LEVEL_HEADING_PATTERN = /^##\s+/;
|
|
69549
|
+
var UNCHECKED_CHECKBOX_PATTERN = /^(\s*)[-*]\s*\[\s*\]\s*(.+)$/;
|
|
69550
|
+
var CHECKED_CHECKBOX_PATTERN = /^(\s*)[-*]\s*\[[xX]\]\s*(.+)$/;
|
|
69551
|
+
var TODO_TASK_PATTERN = /^\d+\.\s+/;
|
|
69552
|
+
var FINAL_WAVE_TASK_PATTERN = /^F\d+\.\s+/i;
|
|
68610
69553
|
function getPlanProgress(planPath) {
|
|
68611
|
-
if (!
|
|
69554
|
+
if (!existsSync16(planPath)) {
|
|
68612
69555
|
return { total: 0, completed: 0, isComplete: true };
|
|
68613
69556
|
}
|
|
68614
69557
|
try {
|
|
68615
|
-
const content =
|
|
68616
|
-
const
|
|
68617
|
-
const
|
|
68618
|
-
|
|
68619
|
-
|
|
68620
|
-
|
|
68621
|
-
|
|
68622
|
-
completed,
|
|
68623
|
-
isComplete: total > 0 && completed === total
|
|
68624
|
-
};
|
|
69558
|
+
const content = readFileSync11(planPath, "utf-8");
|
|
69559
|
+
const lines = content.split(/\r?\n/);
|
|
69560
|
+
const hasStructuredSections = lines.some((line) => TODO_HEADING_PATTERN.test(line) || FINAL_VERIFICATION_HEADING_PATTERN.test(line));
|
|
69561
|
+
if (hasStructuredSections) {
|
|
69562
|
+
return getStructuredPlanProgress(lines);
|
|
69563
|
+
}
|
|
69564
|
+
return getSimplePlanProgress(content);
|
|
68625
69565
|
} catch {
|
|
68626
69566
|
return { total: 0, completed: 0, isComplete: true };
|
|
68627
69567
|
}
|
|
68628
69568
|
}
|
|
69569
|
+
function getStructuredPlanProgress(lines) {
|
|
69570
|
+
let section = "other";
|
|
69571
|
+
let total = 0;
|
|
69572
|
+
let completed = 0;
|
|
69573
|
+
for (const line of lines) {
|
|
69574
|
+
if (SECOND_LEVEL_HEADING_PATTERN.test(line)) {
|
|
69575
|
+
section = TODO_HEADING_PATTERN.test(line) ? "todo" : FINAL_VERIFICATION_HEADING_PATTERN.test(line) ? "final-wave" : "other";
|
|
69576
|
+
continue;
|
|
69577
|
+
}
|
|
69578
|
+
if (section !== "todo" && section !== "final-wave") {
|
|
69579
|
+
continue;
|
|
69580
|
+
}
|
|
69581
|
+
const checkedMatch = line.match(CHECKED_CHECKBOX_PATTERN);
|
|
69582
|
+
const uncheckedMatch = checkedMatch ? null : line.match(UNCHECKED_CHECKBOX_PATTERN);
|
|
69583
|
+
const match = checkedMatch ?? uncheckedMatch;
|
|
69584
|
+
if (!match) {
|
|
69585
|
+
continue;
|
|
69586
|
+
}
|
|
69587
|
+
if (match[1].length > 0) {
|
|
69588
|
+
continue;
|
|
69589
|
+
}
|
|
69590
|
+
const taskBody = match[2].trim();
|
|
69591
|
+
const labelPattern = section === "todo" ? TODO_TASK_PATTERN : FINAL_WAVE_TASK_PATTERN;
|
|
69592
|
+
if (!labelPattern.test(taskBody)) {
|
|
69593
|
+
continue;
|
|
69594
|
+
}
|
|
69595
|
+
total++;
|
|
69596
|
+
if (checkedMatch) {
|
|
69597
|
+
completed++;
|
|
69598
|
+
}
|
|
69599
|
+
}
|
|
69600
|
+
return {
|
|
69601
|
+
total,
|
|
69602
|
+
completed,
|
|
69603
|
+
isComplete: total > 0 && completed === total
|
|
69604
|
+
};
|
|
69605
|
+
}
|
|
69606
|
+
function getSimplePlanProgress(content) {
|
|
69607
|
+
const uncheckedMatches = content.match(/^[-*]\s*\[\s*\]/gm) || [];
|
|
69608
|
+
const checkedMatches = content.match(/^[-*]\s*\[[xX]\]/gm) || [];
|
|
69609
|
+
const total = uncheckedMatches.length + checkedMatches.length;
|
|
69610
|
+
const completed = checkedMatches.length;
|
|
69611
|
+
return {
|
|
69612
|
+
total,
|
|
69613
|
+
completed,
|
|
69614
|
+
isComplete: total > 0 && completed === total
|
|
69615
|
+
};
|
|
69616
|
+
}
|
|
69617
|
+
// src/features/claude-code-session-state/state.ts
|
|
69618
|
+
init_agent_display_names();
|
|
69619
|
+
var subagentSessions = new Set;
|
|
69620
|
+
var syncSubagentSessions = new Set;
|
|
69621
|
+
var registeredAgentNames = new Set;
|
|
69622
|
+
var registeredAgentAliases = new Map;
|
|
69623
|
+
var sessionAgentMap = new Map;
|
|
69624
|
+
function getSessionAgent(sessionID) {
|
|
69625
|
+
return sessionAgentMap.get(sessionID);
|
|
69626
|
+
}
|
|
68629
69627
|
// src/features/run-continuation-state/constants.ts
|
|
68630
69628
|
var CONTINUATION_MARKER_DIR = ".sisyphus/run-continuation";
|
|
68631
69629
|
// src/features/run-continuation-state/storage.ts
|
|
68632
|
-
import { existsSync as
|
|
68633
|
-
import { join as
|
|
69630
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync6, readFileSync as readFileSync12, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "fs";
|
|
69631
|
+
import { join as join16 } from "path";
|
|
68634
69632
|
function getMarkerPath(directory, sessionID) {
|
|
68635
|
-
return
|
|
69633
|
+
return join16(directory, CONTINUATION_MARKER_DIR, `${sessionID}.json`);
|
|
68636
69634
|
}
|
|
68637
69635
|
function readContinuationMarker(directory, sessionID) {
|
|
68638
69636
|
const markerPath = getMarkerPath(directory, sessionID);
|
|
68639
|
-
if (!
|
|
69637
|
+
if (!existsSync17(markerPath))
|
|
68640
69638
|
return null;
|
|
68641
69639
|
try {
|
|
68642
|
-
const raw =
|
|
69640
|
+
const raw = readFileSync12(markerPath, "utf-8");
|
|
68643
69641
|
const parsed = JSON.parse(raw);
|
|
68644
69642
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
68645
69643
|
return null;
|
|
@@ -68662,10 +69660,120 @@ function getActiveContinuationMarkerReason(marker) {
|
|
|
68662
69660
|
const [source, entry] = active;
|
|
68663
69661
|
return entry.reason ?? `${source} continuation is active`;
|
|
68664
69662
|
}
|
|
69663
|
+
// src/hooks/atlas/boulder-session-lineage.ts
|
|
69664
|
+
init_logger();
|
|
69665
|
+
|
|
69666
|
+
// src/hooks/atlas/hook-name.ts
|
|
69667
|
+
var HOOK_NAME = "atlas";
|
|
69668
|
+
|
|
69669
|
+
// src/hooks/atlas/boulder-session-lineage.ts
|
|
69670
|
+
async function isSessionInBoulderLineage(input) {
|
|
69671
|
+
const visitedSessionIDs = new Set;
|
|
69672
|
+
let currentSessionID = input.sessionID;
|
|
69673
|
+
while (!visitedSessionIDs.has(currentSessionID)) {
|
|
69674
|
+
visitedSessionIDs.add(currentSessionID);
|
|
69675
|
+
const sessionResult = await input.client.session.get({ path: { id: currentSessionID } }).catch((error48) => {
|
|
69676
|
+
log(`[${HOOK_NAME}] Failed to resolve session lineage`, {
|
|
69677
|
+
sessionID: input.sessionID,
|
|
69678
|
+
currentSessionID,
|
|
69679
|
+
error: error48
|
|
69680
|
+
});
|
|
69681
|
+
return null;
|
|
69682
|
+
});
|
|
69683
|
+
if (!sessionResult || sessionResult.error) {
|
|
69684
|
+
return false;
|
|
69685
|
+
}
|
|
69686
|
+
const parentSessionID = sessionResult.data?.parentID;
|
|
69687
|
+
if (!parentSessionID) {
|
|
69688
|
+
return false;
|
|
69689
|
+
}
|
|
69690
|
+
if (input.boulderSessionIDs.includes(parentSessionID)) {
|
|
69691
|
+
return true;
|
|
69692
|
+
}
|
|
69693
|
+
currentSessionID = parentSessionID;
|
|
69694
|
+
}
|
|
69695
|
+
return false;
|
|
69696
|
+
}
|
|
69697
|
+
|
|
69698
|
+
// src/hooks/atlas/session-last-agent.ts
|
|
69699
|
+
init_shared();
|
|
69700
|
+
init_compaction_marker();
|
|
69701
|
+
import { readFileSync as readFileSync13, readdirSync as readdirSync4 } from "fs";
|
|
69702
|
+
import { join as join17 } from "path";
|
|
69703
|
+
function getLastAgentFromMessageDir(messageDir) {
|
|
69704
|
+
try {
|
|
69705
|
+
const messages = readdirSync4(messageDir).filter((fileName) => fileName.endsWith(".json")).map((fileName) => {
|
|
69706
|
+
try {
|
|
69707
|
+
const content = readFileSync13(join17(messageDir, fileName), "utf-8");
|
|
69708
|
+
const parsed = JSON.parse(content);
|
|
69709
|
+
return {
|
|
69710
|
+
fileName,
|
|
69711
|
+
id: parsed.id,
|
|
69712
|
+
agent: parsed.agent,
|
|
69713
|
+
createdAt: typeof parsed.time?.created === "number" ? parsed.time.created : Number.NEGATIVE_INFINITY
|
|
69714
|
+
};
|
|
69715
|
+
} catch {
|
|
69716
|
+
return null;
|
|
69717
|
+
}
|
|
69718
|
+
}).filter((message) => message !== null).sort((left, right) => (right?.createdAt ?? 0) - (left?.createdAt ?? 0) || (right?.fileName ?? "").localeCompare(left?.fileName ?? ""));
|
|
69719
|
+
for (const message of messages) {
|
|
69720
|
+
if (!message)
|
|
69721
|
+
continue;
|
|
69722
|
+
if (isCompactionMessage({ agent: message.agent }) || hasCompactionPartInStorage(message?.id)) {
|
|
69723
|
+
continue;
|
|
69724
|
+
}
|
|
69725
|
+
if (typeof message.agent === "string") {
|
|
69726
|
+
return message.agent.toLowerCase();
|
|
69727
|
+
}
|
|
69728
|
+
}
|
|
69729
|
+
} catch {
|
|
69730
|
+
return null;
|
|
69731
|
+
}
|
|
69732
|
+
return null;
|
|
69733
|
+
}
|
|
69734
|
+
async function getLastAgentFromSession(sessionID, client3) {
|
|
69735
|
+
if (isSqliteBackend() && client3) {
|
|
69736
|
+
try {
|
|
69737
|
+
const response = await client3.session.messages({ path: { id: sessionID } });
|
|
69738
|
+
const messages = normalizeSDKResponse(response, [], {
|
|
69739
|
+
preferResponseOnMissingData: true
|
|
69740
|
+
}).sort((left, right) => {
|
|
69741
|
+
const leftTime = left.info?.time?.created ?? Number.NEGATIVE_INFINITY;
|
|
69742
|
+
const rightTime = right.info?.time?.created ?? Number.NEGATIVE_INFINITY;
|
|
69743
|
+
if (leftTime !== rightTime) {
|
|
69744
|
+
return rightTime - leftTime;
|
|
69745
|
+
}
|
|
69746
|
+
const leftId = typeof left.id === "string" ? left.id : "";
|
|
69747
|
+
const rightId = typeof right.id === "string" ? right.id : "";
|
|
69748
|
+
return rightId.localeCompare(leftId);
|
|
69749
|
+
});
|
|
69750
|
+
for (const message of messages) {
|
|
69751
|
+
if (isCompactionMessage(message)) {
|
|
69752
|
+
continue;
|
|
69753
|
+
}
|
|
69754
|
+
const agent = message.info?.agent;
|
|
69755
|
+
if (typeof agent === "string") {
|
|
69756
|
+
return agent.toLowerCase();
|
|
69757
|
+
}
|
|
69758
|
+
}
|
|
69759
|
+
} catch {
|
|
69760
|
+
return null;
|
|
69761
|
+
}
|
|
69762
|
+
return null;
|
|
69763
|
+
}
|
|
69764
|
+
const messageDir = getMessageDir(sessionID);
|
|
69765
|
+
if (!messageDir)
|
|
69766
|
+
return null;
|
|
69767
|
+
return getLastAgentFromMessageDir(messageDir);
|
|
69768
|
+
}
|
|
69769
|
+
|
|
69770
|
+
// src/cli/run/continuation-state.ts
|
|
69771
|
+
init_agent_display_names();
|
|
69772
|
+
|
|
68665
69773
|
// src/hooks/ralph-loop/storage.ts
|
|
68666
69774
|
init_frontmatter();
|
|
68667
|
-
import { existsSync as
|
|
68668
|
-
import { dirname as
|
|
69775
|
+
import { existsSync as existsSync18, readFileSync as readFileSync14, writeFileSync as writeFileSync7, unlinkSync, mkdirSync as mkdirSync7 } from "fs";
|
|
69776
|
+
import { dirname as dirname6, join as join18 } from "path";
|
|
68669
69777
|
|
|
68670
69778
|
// src/hooks/ralph-loop/constants.ts
|
|
68671
69779
|
var DEFAULT_STATE_FILE = ".sisyphus/ralph-loop.local.md";
|
|
@@ -68674,15 +69782,15 @@ var DEFAULT_COMPLETION_PROMISE = "DONE";
|
|
|
68674
69782
|
|
|
68675
69783
|
// src/hooks/ralph-loop/storage.ts
|
|
68676
69784
|
function getStateFilePath(directory, customPath) {
|
|
68677
|
-
return customPath ?
|
|
69785
|
+
return customPath ? join18(directory, customPath) : join18(directory, DEFAULT_STATE_FILE);
|
|
68678
69786
|
}
|
|
68679
69787
|
function readState(directory, customPath) {
|
|
68680
69788
|
const filePath = getStateFilePath(directory, customPath);
|
|
68681
|
-
if (!
|
|
69789
|
+
if (!existsSync18(filePath)) {
|
|
68682
69790
|
return null;
|
|
68683
69791
|
}
|
|
68684
69792
|
try {
|
|
68685
|
-
const content =
|
|
69793
|
+
const content = readFileSync14(filePath, "utf-8");
|
|
68686
69794
|
const { data, body } = parseFrontmatter(content);
|
|
68687
69795
|
const active = data.active;
|
|
68688
69796
|
const iteration = data.iteration;
|
|
@@ -68722,10 +69830,10 @@ function readState(directory, customPath) {
|
|
|
68722
69830
|
}
|
|
68723
69831
|
|
|
68724
69832
|
// src/cli/run/continuation-state.ts
|
|
68725
|
-
function getContinuationState(directory, sessionID) {
|
|
69833
|
+
async function getContinuationState(directory, sessionID, client3) {
|
|
68726
69834
|
const marker = readContinuationMarker(directory, sessionID);
|
|
68727
69835
|
return {
|
|
68728
|
-
hasActiveBoulder: hasActiveBoulderContinuation(directory, sessionID),
|
|
69836
|
+
hasActiveBoulder: await hasActiveBoulderContinuation(directory, sessionID, client3),
|
|
68729
69837
|
hasActiveRalphLoop: hasActiveRalphLoopContinuation(directory, sessionID),
|
|
68730
69838
|
hasHookMarker: marker !== null,
|
|
68731
69839
|
hasTodoHookMarker: marker?.sources.todo !== undefined,
|
|
@@ -68733,20 +69841,54 @@ function getContinuationState(directory, sessionID) {
|
|
|
68733
69841
|
activeHookMarkerReason: getActiveContinuationMarkerReason(marker)
|
|
68734
69842
|
};
|
|
68735
69843
|
}
|
|
68736
|
-
function hasActiveBoulderContinuation(directory, sessionID) {
|
|
69844
|
+
async function hasActiveBoulderContinuation(directory, sessionID, client3) {
|
|
68737
69845
|
const boulder = readBoulderState(directory);
|
|
68738
69846
|
if (!boulder)
|
|
68739
69847
|
return false;
|
|
68740
|
-
if (!boulder.session_ids.includes(sessionID))
|
|
68741
|
-
return false;
|
|
68742
69848
|
const progress = getPlanProgress(boulder.active_plan);
|
|
68743
|
-
|
|
69849
|
+
if (progress.isComplete)
|
|
69850
|
+
return false;
|
|
69851
|
+
if (!client3)
|
|
69852
|
+
return false;
|
|
69853
|
+
const isTrackedSession = boulder.session_ids.includes(sessionID);
|
|
69854
|
+
const sessionOrigin = boulder.session_origins?.[sessionID];
|
|
69855
|
+
if (!isTrackedSession) {
|
|
69856
|
+
return false;
|
|
69857
|
+
}
|
|
69858
|
+
const isTrackedDescendant = await isTrackedDescendantSession(client3, sessionID, boulder.session_ids);
|
|
69859
|
+
if (isTrackedSession && sessionOrigin === "direct") {
|
|
69860
|
+
return true;
|
|
69861
|
+
}
|
|
69862
|
+
if (isTrackedSession && sessionOrigin !== "direct" && !isTrackedDescendant) {
|
|
69863
|
+
return false;
|
|
69864
|
+
}
|
|
69865
|
+
const sessionAgent = await getLastAgentFromSession(sessionID, client3) ?? getSessionAgent(sessionID);
|
|
69866
|
+
if (!sessionAgent) {
|
|
69867
|
+
return false;
|
|
69868
|
+
}
|
|
69869
|
+
const requiredAgentKey = getAgentConfigKey(boulder.agent ?? "atlas");
|
|
69870
|
+
const sessionAgentKey = getAgentConfigKey(sessionAgent);
|
|
69871
|
+
if (sessionAgentKey !== requiredAgentKey && !(requiredAgentKey === getAgentConfigKey("atlas") && sessionAgentKey === getAgentConfigKey("sisyphus"))) {
|
|
69872
|
+
return false;
|
|
69873
|
+
}
|
|
69874
|
+
return isTrackedSession || isTrackedDescendant;
|
|
69875
|
+
}
|
|
69876
|
+
async function isTrackedDescendantSession(client3, sessionID, trackedSessionIDs) {
|
|
69877
|
+
const ancestorSessionIDs = trackedSessionIDs.filter((trackedSessionID) => trackedSessionID !== sessionID);
|
|
69878
|
+
if (ancestorSessionIDs.length === 0) {
|
|
69879
|
+
return false;
|
|
69880
|
+
}
|
|
69881
|
+
return isSessionInBoulderLineage({
|
|
69882
|
+
client: client3,
|
|
69883
|
+
sessionID,
|
|
69884
|
+
boulderSessionIDs: ancestorSessionIDs
|
|
69885
|
+
});
|
|
68744
69886
|
}
|
|
68745
69887
|
function hasActiveRalphLoopContinuation(directory, sessionID) {
|
|
68746
|
-
const
|
|
68747
|
-
if (!
|
|
69888
|
+
const state2 = readState(directory);
|
|
69889
|
+
if (!state2 || !state2.active)
|
|
68748
69890
|
return false;
|
|
68749
|
-
if (
|
|
69891
|
+
if (state2.session_id && state2.session_id !== sessionID) {
|
|
68750
69892
|
return false;
|
|
68751
69893
|
}
|
|
68752
69894
|
return true;
|
|
@@ -68755,7 +69897,7 @@ function hasActiveRalphLoopContinuation(directory, sessionID) {
|
|
|
68755
69897
|
// src/cli/run/completion.ts
|
|
68756
69898
|
async function checkCompletionConditions(ctx) {
|
|
68757
69899
|
try {
|
|
68758
|
-
const continuationState = getContinuationState(ctx.directory, ctx.sessionID);
|
|
69900
|
+
const continuationState = await getContinuationState(ctx.directory, ctx.sessionID, ctx.client);
|
|
68759
69901
|
if (continuationState.hasActiveHookMarker) {
|
|
68760
69902
|
const reason = continuationState.activeHookMarkerReason ?? "continuation hook is active";
|
|
68761
69903
|
logWaiting(ctx, reason);
|
|
@@ -68772,7 +69914,7 @@ async function checkCompletionConditions(ctx) {
|
|
|
68772
69914
|
}
|
|
68773
69915
|
return true;
|
|
68774
69916
|
} catch (err) {
|
|
68775
|
-
console.error(
|
|
69917
|
+
console.error(import_picocolors13.default.red(`[completion] API error: ${err}`));
|
|
68776
69918
|
return false;
|
|
68777
69919
|
}
|
|
68778
69920
|
}
|
|
@@ -68833,7 +69975,7 @@ function logWaiting(ctx, message) {
|
|
|
68833
69975
|
if (!ctx.verbose) {
|
|
68834
69976
|
return;
|
|
68835
69977
|
}
|
|
68836
|
-
console.log(
|
|
69978
|
+
console.log(import_picocolors13.default.dim(` Waiting: ${message}`));
|
|
68837
69979
|
}
|
|
68838
69980
|
|
|
68839
69981
|
// src/cli/run/poll-for-completion.ts
|
|
@@ -68864,10 +70006,10 @@ async function pollForCompletion(ctx, eventState, abortController, options = {})
|
|
|
68864
70006
|
if (eventState.mainSessionError) {
|
|
68865
70007
|
errorCycleCount++;
|
|
68866
70008
|
if (errorCycleCount >= ERROR_GRACE_CYCLES) {
|
|
68867
|
-
console.error(
|
|
70009
|
+
console.error(import_picocolors14.default.red(`
|
|
68868
70010
|
|
|
68869
70011
|
Session ended with error: ${eventState.lastError}`));
|
|
68870
|
-
console.error(
|
|
70012
|
+
console.error(import_picocolors14.default.yellow("Check if todos were completed before the error."));
|
|
68871
70013
|
return 1;
|
|
68872
70014
|
}
|
|
68873
70015
|
continue;
|
|
@@ -68878,7 +70020,7 @@ Session ended with error: ${eventState.lastError}`));
|
|
|
68878
70020
|
if (eventState.lastEventTimestamp !== null) {
|
|
68879
70021
|
const timeSinceLastEvent = Date.now() - eventState.lastEventTimestamp;
|
|
68880
70022
|
if (timeSinceLastEvent > eventWatchdogMs) {
|
|
68881
|
-
console.log(
|
|
70023
|
+
console.log(import_picocolors14.default.yellow(`
|
|
68882
70024
|
No events for ${Math.round(timeSinceLastEvent / 1000)}s, verifying session status...`));
|
|
68883
70025
|
mainSessionStatus = await getMainSessionStatus(ctx);
|
|
68884
70026
|
if (mainSessionStatus === "idle") {
|
|
@@ -68927,7 +70069,7 @@ Session ended with error: ${eventState.lastError}`));
|
|
|
68927
70069
|
const hasActiveWork = hasActiveChildren || hasActiveTodos;
|
|
68928
70070
|
if (hasActiveWork) {
|
|
68929
70071
|
eventState.hasReceivedMeaningfulWork = true;
|
|
68930
|
-
console.log(
|
|
70072
|
+
console.log(import_picocolors14.default.yellow(`
|
|
68931
70073
|
No meaningful work events for ${Math.round(secondaryMeaningfulWorkTimeoutMs / 1000)}s but session has active work - assuming in progress`));
|
|
68932
70074
|
}
|
|
68933
70075
|
}
|
|
@@ -68947,7 +70089,7 @@ Session ended with error: ${eventState.lastError}`));
|
|
|
68947
70089
|
}
|
|
68948
70090
|
consecutiveCompleteChecks++;
|
|
68949
70091
|
if (consecutiveCompleteChecks >= requiredConsecutive) {
|
|
68950
|
-
console.log(
|
|
70092
|
+
console.log(import_picocolors14.default.green(`
|
|
68951
70093
|
|
|
68952
70094
|
All tasks completed.`));
|
|
68953
70095
|
return 0;
|
|
@@ -69116,7 +70258,7 @@ async function run(options) {
|
|
|
69116
70258
|
};
|
|
69117
70259
|
const restoreInput = suppressRunInput();
|
|
69118
70260
|
const handleSigint = () => {
|
|
69119
|
-
console.log(
|
|
70261
|
+
console.log(import_picocolors15.default.yellow(`
|
|
69120
70262
|
Interrupted. Shutting down...`));
|
|
69121
70263
|
restoreInput();
|
|
69122
70264
|
cleanup();
|
|
@@ -69129,9 +70271,9 @@ Interrupted. Shutting down...`));
|
|
|
69129
70271
|
sessionId: options.sessionId,
|
|
69130
70272
|
directory
|
|
69131
70273
|
});
|
|
69132
|
-
console.log(
|
|
70274
|
+
console.log(import_picocolors15.default.dim(`Session: ${sessionID}`));
|
|
69133
70275
|
if (resolvedModel) {
|
|
69134
|
-
console.log(
|
|
70276
|
+
console.log(import_picocolors15.default.dim(`Model: ${resolvedModel.providerID}/${resolvedModel.modelID}`));
|
|
69135
70277
|
}
|
|
69136
70278
|
const ctx = {
|
|
69137
70279
|
client: client3,
|
|
@@ -69194,7 +70336,7 @@ Interrupted. Shutting down...`));
|
|
|
69194
70336
|
if (err instanceof Error && err.name === "AbortError") {
|
|
69195
70337
|
return 130;
|
|
69196
70338
|
}
|
|
69197
|
-
console.error(
|
|
70339
|
+
console.error(import_picocolors15.default.red(`Error: ${serializeError(err)}`));
|
|
69198
70340
|
return 1;
|
|
69199
70341
|
} finally {
|
|
69200
70342
|
timestampOutput?.restore();
|
|
@@ -69204,53 +70346,53 @@ Interrupted. Shutting down...`));
|
|
|
69204
70346
|
init_checker();
|
|
69205
70347
|
|
|
69206
70348
|
// src/cli/get-local-version/formatter.ts
|
|
69207
|
-
var
|
|
69208
|
-
var
|
|
69209
|
-
check:
|
|
69210
|
-
cross:
|
|
69211
|
-
arrow:
|
|
69212
|
-
info:
|
|
69213
|
-
warn:
|
|
69214
|
-
pin:
|
|
69215
|
-
dev:
|
|
70349
|
+
var import_picocolors16 = __toESM(require_picocolors(), 1);
|
|
70350
|
+
var SYMBOLS3 = {
|
|
70351
|
+
check: import_picocolors16.default.green("[OK]"),
|
|
70352
|
+
cross: import_picocolors16.default.red("[X]"),
|
|
70353
|
+
arrow: import_picocolors16.default.cyan("->"),
|
|
70354
|
+
info: import_picocolors16.default.blue("[i]"),
|
|
70355
|
+
warn: import_picocolors16.default.yellow("[!]"),
|
|
70356
|
+
pin: import_picocolors16.default.magenta("[PINNED]"),
|
|
70357
|
+
dev: import_picocolors16.default.cyan("[DEV]")
|
|
69216
70358
|
};
|
|
69217
70359
|
function formatVersionOutput(info) {
|
|
69218
70360
|
const lines = [];
|
|
69219
70361
|
lines.push("");
|
|
69220
|
-
lines.push(
|
|
69221
|
-
lines.push(
|
|
70362
|
+
lines.push(import_picocolors16.default.bold(import_picocolors16.default.white("oh-my-opencode Version Information")));
|
|
70363
|
+
lines.push(import_picocolors16.default.dim("\u2500".repeat(50)));
|
|
69222
70364
|
lines.push("");
|
|
69223
70365
|
if (info.currentVersion) {
|
|
69224
|
-
lines.push(` Current Version: ${
|
|
70366
|
+
lines.push(` Current Version: ${import_picocolors16.default.cyan(info.currentVersion)}`);
|
|
69225
70367
|
} else {
|
|
69226
|
-
lines.push(` Current Version: ${
|
|
70368
|
+
lines.push(` Current Version: ${import_picocolors16.default.dim("unknown")}`);
|
|
69227
70369
|
}
|
|
69228
70370
|
if (!info.isLocalDev && info.latestVersion) {
|
|
69229
|
-
lines.push(` Latest Version: ${
|
|
70371
|
+
lines.push(` Latest Version: ${import_picocolors16.default.cyan(info.latestVersion)}`);
|
|
69230
70372
|
}
|
|
69231
70373
|
lines.push("");
|
|
69232
70374
|
switch (info.status) {
|
|
69233
70375
|
case "up-to-date":
|
|
69234
|
-
lines.push(` ${
|
|
70376
|
+
lines.push(` ${SYMBOLS3.check} ${import_picocolors16.default.green("You're up to date!")}`);
|
|
69235
70377
|
break;
|
|
69236
70378
|
case "outdated":
|
|
69237
|
-
lines.push(` ${
|
|
69238
|
-
lines.push(` ${
|
|
70379
|
+
lines.push(` ${SYMBOLS3.warn} ${import_picocolors16.default.yellow("Update available")}`);
|
|
70380
|
+
lines.push(` ${import_picocolors16.default.dim("Run:")} ${import_picocolors16.default.cyan("cd ~/.config/opencode && bun update oh-my-opencode")}`);
|
|
69239
70381
|
break;
|
|
69240
70382
|
case "local-dev":
|
|
69241
|
-
lines.push(` ${
|
|
69242
|
-
lines.push(` ${
|
|
70383
|
+
lines.push(` ${SYMBOLS3.dev} ${import_picocolors16.default.cyan("Running in local development mode")}`);
|
|
70384
|
+
lines.push(` ${import_picocolors16.default.dim("Using file:// protocol from config")}`);
|
|
69243
70385
|
break;
|
|
69244
70386
|
case "pinned":
|
|
69245
|
-
lines.push(` ${
|
|
69246
|
-
lines.push(` ${
|
|
70387
|
+
lines.push(` ${SYMBOLS3.pin} ${import_picocolors16.default.magenta(`Version pinned to ${info.pinnedVersion}`)}`);
|
|
70388
|
+
lines.push(` ${import_picocolors16.default.dim("Update check skipped for pinned versions")}`);
|
|
69247
70389
|
break;
|
|
69248
70390
|
case "error":
|
|
69249
|
-
lines.push(` ${
|
|
69250
|
-
lines.push(` ${
|
|
70391
|
+
lines.push(` ${SYMBOLS3.cross} ${import_picocolors16.default.red("Unable to check for updates")}`);
|
|
70392
|
+
lines.push(` ${import_picocolors16.default.dim("Network error or npm registry unavailable")}`);
|
|
69251
70393
|
break;
|
|
69252
70394
|
case "unknown":
|
|
69253
|
-
lines.push(` ${
|
|
70395
|
+
lines.push(` ${SYMBOLS3.info} ${import_picocolors16.default.yellow("Version information unavailable")}`);
|
|
69254
70396
|
break;
|
|
69255
70397
|
}
|
|
69256
70398
|
lines.push("");
|
|
@@ -69349,69 +70491,31 @@ async function getLocalVersion(options = {}) {
|
|
|
69349
70491
|
return 1;
|
|
69350
70492
|
}
|
|
69351
70493
|
}
|
|
69352
|
-
// src/cli/doctor/constants.ts
|
|
69353
|
-
init_shared();
|
|
69354
|
-
var import_picocolors16 = __toESM(require_picocolors(), 1);
|
|
69355
|
-
var SYMBOLS3 = {
|
|
69356
|
-
check: import_picocolors16.default.green("\u2713"),
|
|
69357
|
-
cross: import_picocolors16.default.red("\u2717"),
|
|
69358
|
-
warn: import_picocolors16.default.yellow("\u26A0"),
|
|
69359
|
-
info: import_picocolors16.default.blue("\u2139"),
|
|
69360
|
-
arrow: import_picocolors16.default.cyan("\u2192"),
|
|
69361
|
-
bullet: import_picocolors16.default.dim("\u2022"),
|
|
69362
|
-
skip: import_picocolors16.default.dim("\u25CB")
|
|
69363
|
-
};
|
|
69364
|
-
var STATUS_COLORS = {
|
|
69365
|
-
pass: import_picocolors16.default.green,
|
|
69366
|
-
fail: import_picocolors16.default.red,
|
|
69367
|
-
warn: import_picocolors16.default.yellow,
|
|
69368
|
-
skip: import_picocolors16.default.dim
|
|
69369
|
-
};
|
|
69370
|
-
var CHECK_IDS = {
|
|
69371
|
-
SYSTEM: "system",
|
|
69372
|
-
CONFIG: "config",
|
|
69373
|
-
TOOLS: "tools",
|
|
69374
|
-
MODELS: "models"
|
|
69375
|
-
};
|
|
69376
|
-
var CHECK_NAMES = {
|
|
69377
|
-
[CHECK_IDS.SYSTEM]: "System",
|
|
69378
|
-
[CHECK_IDS.CONFIG]: "Configuration",
|
|
69379
|
-
[CHECK_IDS.TOOLS]: "Tools",
|
|
69380
|
-
[CHECK_IDS.MODELS]: "Models"
|
|
69381
|
-
};
|
|
69382
|
-
var EXIT_CODES = {
|
|
69383
|
-
SUCCESS: 0,
|
|
69384
|
-
FAILURE: 1
|
|
69385
|
-
};
|
|
69386
|
-
var MIN_OPENCODE_VERSION = "1.0.150";
|
|
69387
|
-
var PACKAGE_NAME2 = PLUGIN_NAME;
|
|
69388
|
-
var OPENCODE_BINARIES2 = ["opencode", "opencode-desktop"];
|
|
69389
|
-
|
|
69390
70494
|
// src/cli/doctor/checks/system.ts
|
|
69391
|
-
import { existsSync as
|
|
70495
|
+
import { existsSync as existsSync29, readFileSync as readFileSync24 } from "fs";
|
|
69392
70496
|
|
|
69393
70497
|
// src/cli/doctor/checks/system-binary.ts
|
|
69394
70498
|
init_spawn_with_windows_hide();
|
|
69395
|
-
import { existsSync as
|
|
70499
|
+
import { existsSync as existsSync26 } from "fs";
|
|
69396
70500
|
import { homedir as homedir5 } from "os";
|
|
69397
|
-
import { join as
|
|
70501
|
+
import { join as join25 } from "path";
|
|
69398
70502
|
function getDesktopAppPaths(platform) {
|
|
69399
70503
|
const home = homedir5();
|
|
69400
70504
|
switch (platform) {
|
|
69401
70505
|
case "darwin":
|
|
69402
70506
|
return [
|
|
69403
70507
|
"/Applications/OpenCode.app/Contents/MacOS/OpenCode",
|
|
69404
|
-
|
|
70508
|
+
join25(home, "Applications", "OpenCode.app", "Contents", "MacOS", "OpenCode")
|
|
69405
70509
|
];
|
|
69406
70510
|
case "win32": {
|
|
69407
70511
|
const programFiles = process.env.ProgramFiles;
|
|
69408
70512
|
const localAppData = process.env.LOCALAPPDATA;
|
|
69409
70513
|
const paths = [];
|
|
69410
70514
|
if (programFiles) {
|
|
69411
|
-
paths.push(
|
|
70515
|
+
paths.push(join25(programFiles, "OpenCode", "OpenCode.exe"));
|
|
69412
70516
|
}
|
|
69413
70517
|
if (localAppData) {
|
|
69414
|
-
paths.push(
|
|
70518
|
+
paths.push(join25(localAppData, "OpenCode", "OpenCode.exe"));
|
|
69415
70519
|
}
|
|
69416
70520
|
return paths;
|
|
69417
70521
|
}
|
|
@@ -69419,8 +70523,8 @@ function getDesktopAppPaths(platform) {
|
|
|
69419
70523
|
return [
|
|
69420
70524
|
"/usr/bin/opencode",
|
|
69421
70525
|
"/usr/lib/opencode/opencode",
|
|
69422
|
-
|
|
69423
|
-
|
|
70526
|
+
join25(home, "Applications", "opencode-desktop-linux-x86_64.AppImage"),
|
|
70527
|
+
join25(home, "Applications", "opencode-desktop-linux-aarch64.AppImage")
|
|
69424
70528
|
];
|
|
69425
70529
|
default:
|
|
69426
70530
|
return [];
|
|
@@ -69432,7 +70536,7 @@ function buildVersionCommand(binaryPath, platform) {
|
|
|
69432
70536
|
}
|
|
69433
70537
|
return [binaryPath, "--version"];
|
|
69434
70538
|
}
|
|
69435
|
-
function findDesktopBinary(platform = process.platform, checkExists =
|
|
70539
|
+
function findDesktopBinary(platform = process.platform, checkExists = existsSync26) {
|
|
69436
70540
|
for (const desktopPath of getDesktopAppPaths(platform)) {
|
|
69437
70541
|
if (checkExists(desktopPath)) {
|
|
69438
70542
|
return { binary: "opencode", path: desktopPath };
|
|
@@ -69449,7 +70553,7 @@ async function findOpenCodeBinary() {
|
|
|
69449
70553
|
}
|
|
69450
70554
|
return findDesktopBinary();
|
|
69451
70555
|
}
|
|
69452
|
-
async function
|
|
70556
|
+
async function getOpenCodeVersion3(binaryPath, platform = process.platform) {
|
|
69453
70557
|
try {
|
|
69454
70558
|
const command = buildVersionCommand(binaryPath, platform);
|
|
69455
70559
|
const processResult = spawnWithWindowsHide(command, { stdout: "pipe", stderr: "pipe" });
|
|
@@ -69462,10 +70566,10 @@ async function getOpenCodeVersion2(binaryPath, platform = process.platform) {
|
|
|
69462
70566
|
return null;
|
|
69463
70567
|
}
|
|
69464
70568
|
}
|
|
69465
|
-
function
|
|
69466
|
-
const
|
|
69467
|
-
const currentParts =
|
|
69468
|
-
const minimumParts =
|
|
70569
|
+
function compareVersions3(current, minimum) {
|
|
70570
|
+
const parseVersion3 = (version2) => version2.replace(/^v/, "").split("-")[0].split(".").map((part) => Number.parseInt(part, 10) || 0);
|
|
70571
|
+
const currentParts = parseVersion3(current);
|
|
70572
|
+
const minimumParts = parseVersion3(minimum);
|
|
69469
70573
|
const length = Math.max(currentParts.length, minimumParts.length);
|
|
69470
70574
|
for (let index = 0;index < length; index++) {
|
|
69471
70575
|
const currentPart = currentParts[index] ?? 0;
|
|
@@ -69480,12 +70584,12 @@ function compareVersions(current, minimum) {
|
|
|
69480
70584
|
|
|
69481
70585
|
// src/cli/doctor/checks/system-plugin.ts
|
|
69482
70586
|
init_shared();
|
|
69483
|
-
import { existsSync as
|
|
70587
|
+
import { existsSync as existsSync27, readFileSync as readFileSync22 } from "fs";
|
|
69484
70588
|
function detectConfigPath() {
|
|
69485
70589
|
const paths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
|
|
69486
|
-
if (
|
|
70590
|
+
if (existsSync27(paths.configJsonc))
|
|
69487
70591
|
return paths.configJsonc;
|
|
69488
|
-
if (
|
|
70592
|
+
if (existsSync27(paths.configJson))
|
|
69489
70593
|
return paths.configJson;
|
|
69490
70594
|
return null;
|
|
69491
70595
|
}
|
|
@@ -69531,7 +70635,7 @@ function getPluginInfo() {
|
|
|
69531
70635
|
};
|
|
69532
70636
|
}
|
|
69533
70637
|
try {
|
|
69534
|
-
const content =
|
|
70638
|
+
const content = readFileSync22(configPath, "utf-8");
|
|
69535
70639
|
const parsedConfig = parseJsonc(content);
|
|
69536
70640
|
const pluginEntry = findPluginEntry2(parsedConfig.plugin ?? []);
|
|
69537
70641
|
if (!pluginEntry) {
|
|
@@ -69569,37 +70673,37 @@ function getPluginInfo() {
|
|
|
69569
70673
|
init_file_utils();
|
|
69570
70674
|
init_checker();
|
|
69571
70675
|
init_auto_update_checker();
|
|
69572
|
-
import { existsSync as
|
|
70676
|
+
import { existsSync as existsSync28, readFileSync as readFileSync23 } from "fs";
|
|
69573
70677
|
import { homedir as homedir6 } from "os";
|
|
69574
|
-
import { join as
|
|
70678
|
+
import { join as join26 } from "path";
|
|
69575
70679
|
init_shared();
|
|
69576
70680
|
function getPlatformDefaultCacheDir(platform = process.platform) {
|
|
69577
70681
|
if (platform === "darwin")
|
|
69578
|
-
return
|
|
70682
|
+
return join26(homedir6(), "Library", "Caches");
|
|
69579
70683
|
if (platform === "win32")
|
|
69580
|
-
return process.env.LOCALAPPDATA ??
|
|
69581
|
-
return
|
|
70684
|
+
return process.env.LOCALAPPDATA ?? join26(homedir6(), "AppData", "Local");
|
|
70685
|
+
return join26(homedir6(), ".cache");
|
|
69582
70686
|
}
|
|
69583
70687
|
function resolveOpenCodeCacheDir() {
|
|
69584
70688
|
const xdgCacheHome = process.env.XDG_CACHE_HOME;
|
|
69585
70689
|
if (xdgCacheHome)
|
|
69586
|
-
return
|
|
70690
|
+
return join26(xdgCacheHome, "opencode");
|
|
69587
70691
|
const fromShared = getOpenCodeCacheDir();
|
|
69588
|
-
const platformDefault =
|
|
69589
|
-
if (
|
|
70692
|
+
const platformDefault = join26(getPlatformDefaultCacheDir(), "opencode");
|
|
70693
|
+
if (existsSync28(fromShared) || !existsSync28(platformDefault))
|
|
69590
70694
|
return fromShared;
|
|
69591
70695
|
return platformDefault;
|
|
69592
70696
|
}
|
|
69593
70697
|
function resolveExistingDir(dirPath) {
|
|
69594
|
-
if (!
|
|
70698
|
+
if (!existsSync28(dirPath))
|
|
69595
70699
|
return dirPath;
|
|
69596
70700
|
return resolveSymlink(dirPath);
|
|
69597
70701
|
}
|
|
69598
70702
|
function readPackageJson(filePath) {
|
|
69599
|
-
if (!
|
|
70703
|
+
if (!existsSync28(filePath))
|
|
69600
70704
|
return null;
|
|
69601
70705
|
try {
|
|
69602
|
-
const content =
|
|
70706
|
+
const content = readFileSync23(filePath, "utf-8");
|
|
69603
70707
|
return parseJsonc(content);
|
|
69604
70708
|
} catch {
|
|
69605
70709
|
return null;
|
|
@@ -69618,20 +70722,20 @@ function getLoadedPluginVersion() {
|
|
|
69618
70722
|
const candidates = [
|
|
69619
70723
|
{
|
|
69620
70724
|
cacheDir: configDir,
|
|
69621
|
-
cachePackagePath:
|
|
69622
|
-
installedPackagePath:
|
|
70725
|
+
cachePackagePath: join26(configDir, "package.json"),
|
|
70726
|
+
installedPackagePath: join26(configDir, "node_modules", PACKAGE_NAME, "package.json")
|
|
69623
70727
|
},
|
|
69624
70728
|
{
|
|
69625
70729
|
cacheDir,
|
|
69626
|
-
cachePackagePath:
|
|
69627
|
-
installedPackagePath:
|
|
70730
|
+
cachePackagePath: join26(cacheDir, "package.json"),
|
|
70731
|
+
installedPackagePath: join26(cacheDir, "node_modules", PACKAGE_NAME, "package.json")
|
|
69628
70732
|
}
|
|
69629
70733
|
];
|
|
69630
|
-
const selectedCandidate = candidates.find((candidate) =>
|
|
70734
|
+
const selectedCandidate = candidates.find((candidate) => existsSync28(candidate.installedPackagePath)) ?? candidates[0];
|
|
69631
70735
|
const { cacheDir: selectedDir, cachePackagePath, installedPackagePath } = selectedCandidate;
|
|
69632
70736
|
const cachePackage = readPackageJson(cachePackagePath);
|
|
69633
70737
|
const installedPackage = readPackageJson(installedPackagePath);
|
|
69634
|
-
const expectedVersion = normalizeVersion(cachePackage?.dependencies?.[
|
|
70738
|
+
const expectedVersion = normalizeVersion(cachePackage?.dependencies?.[PACKAGE_NAME]);
|
|
69635
70739
|
const loadedVersion = normalizeVersion(installedPackage?.version);
|
|
69636
70740
|
return {
|
|
69637
70741
|
cacheDir: selectedDir,
|
|
@@ -69654,10 +70758,10 @@ init_shared();
|
|
|
69654
70758
|
function isConfigValid(configPath) {
|
|
69655
70759
|
if (!configPath)
|
|
69656
70760
|
return true;
|
|
69657
|
-
if (!
|
|
70761
|
+
if (!existsSync29(configPath))
|
|
69658
70762
|
return false;
|
|
69659
70763
|
try {
|
|
69660
|
-
parseJsonc(
|
|
70764
|
+
parseJsonc(readFileSync24(configPath, "utf-8"));
|
|
69661
70765
|
return true;
|
|
69662
70766
|
} catch {
|
|
69663
70767
|
return false;
|
|
@@ -69680,7 +70784,7 @@ function buildMessage(status, issues) {
|
|
|
69680
70784
|
async function gatherSystemInfo() {
|
|
69681
70785
|
const [binaryInfo, pluginInfo] = await Promise.all([findOpenCodeBinary(), Promise.resolve(getPluginInfo())]);
|
|
69682
70786
|
const loadedInfo = getLoadedPluginVersion();
|
|
69683
|
-
const opencodeVersion = binaryInfo ? await
|
|
70787
|
+
const opencodeVersion = binaryInfo ? await getOpenCodeVersion3(binaryInfo.path) : null;
|
|
69684
70788
|
const pluginVersion = pluginInfo.pinnedVersion ?? loadedInfo.expectedVersion ?? loadedInfo.loadedVersion;
|
|
69685
70789
|
return {
|
|
69686
70790
|
opencodeVersion,
|
|
@@ -69708,7 +70812,7 @@ async function checkSystem() {
|
|
|
69708
70812
|
affects: ["doctor", "run"]
|
|
69709
70813
|
});
|
|
69710
70814
|
}
|
|
69711
|
-
if (systemInfo.opencodeVersion && !
|
|
70815
|
+
if (systemInfo.opencodeVersion && !compareVersions3(systemInfo.opencodeVersion, MIN_OPENCODE_VERSION)) {
|
|
69712
70816
|
issues.push({
|
|
69713
70817
|
title: "OpenCode version below minimum",
|
|
69714
70818
|
description: `Detected ${systemInfo.opencodeVersion}; required >= ${MIN_OPENCODE_VERSION}.`,
|
|
@@ -69748,7 +70852,7 @@ async function checkSystem() {
|
|
|
69748
70852
|
affects: ["plugin loading"]
|
|
69749
70853
|
});
|
|
69750
70854
|
}
|
|
69751
|
-
if (systemInfo.loadedVersion && latestVersion && !
|
|
70855
|
+
if (systemInfo.loadedVersion && latestVersion && !compareVersions3(systemInfo.loadedVersion, latestVersion)) {
|
|
69752
70856
|
issues.push({
|
|
69753
70857
|
title: "Loaded plugin is outdated",
|
|
69754
70858
|
description: `Loaded ${systemInfo.loadedVersion}, latest ${latestVersion}.`,
|
|
@@ -69773,28 +70877,28 @@ async function checkSystem() {
|
|
|
69773
70877
|
}
|
|
69774
70878
|
|
|
69775
70879
|
// src/cli/doctor/checks/config.ts
|
|
69776
|
-
import { readFileSync as
|
|
69777
|
-
import { join as
|
|
70880
|
+
import { readFileSync as readFileSync27 } from "fs";
|
|
70881
|
+
import { join as join30 } from "path";
|
|
69778
70882
|
init_shared();
|
|
69779
70883
|
|
|
69780
70884
|
// src/cli/doctor/checks/model-resolution-cache.ts
|
|
69781
70885
|
init_shared();
|
|
69782
|
-
import { existsSync as
|
|
70886
|
+
import { existsSync as existsSync30, readFileSync as readFileSync25 } from "fs";
|
|
69783
70887
|
import { homedir as homedir7 } from "os";
|
|
69784
|
-
import { join as
|
|
70888
|
+
import { join as join27 } from "path";
|
|
69785
70889
|
function getOpenCodeCacheDir2() {
|
|
69786
70890
|
const xdgCache = process.env.XDG_CACHE_HOME;
|
|
69787
70891
|
if (xdgCache)
|
|
69788
|
-
return
|
|
69789
|
-
return
|
|
70892
|
+
return join27(xdgCache, "opencode");
|
|
70893
|
+
return join27(homedir7(), ".cache", "opencode");
|
|
69790
70894
|
}
|
|
69791
70895
|
function loadAvailableModelsFromCache() {
|
|
69792
|
-
const cacheFile =
|
|
69793
|
-
if (!
|
|
70896
|
+
const cacheFile = join27(getOpenCodeCacheDir2(), "models.json");
|
|
70897
|
+
if (!existsSync30(cacheFile)) {
|
|
69794
70898
|
return { providers: [], modelCount: 0, cacheExists: false };
|
|
69795
70899
|
}
|
|
69796
70900
|
try {
|
|
69797
|
-
const content =
|
|
70901
|
+
const content = readFileSync25(cacheFile, "utf-8");
|
|
69798
70902
|
const data = parseJsonc(content);
|
|
69799
70903
|
const providers = Object.keys(data);
|
|
69800
70904
|
let modelCount = 0;
|
|
@@ -69816,14 +70920,14 @@ init_model_capabilities();
|
|
|
69816
70920
|
|
|
69817
70921
|
// src/cli/doctor/checks/model-resolution-config.ts
|
|
69818
70922
|
init_shared();
|
|
69819
|
-
import { readFileSync as
|
|
69820
|
-
import { join as
|
|
69821
|
-
var PROJECT_CONFIG_DIR =
|
|
70923
|
+
import { readFileSync as readFileSync26 } from "fs";
|
|
70924
|
+
import { join as join28 } from "path";
|
|
70925
|
+
var PROJECT_CONFIG_DIR = join28(process.cwd(), ".opencode");
|
|
69822
70926
|
function loadOmoConfig() {
|
|
69823
70927
|
const projectDetected = detectPluginConfigFile(PROJECT_CONFIG_DIR);
|
|
69824
70928
|
if (projectDetected.format !== "none") {
|
|
69825
70929
|
try {
|
|
69826
|
-
const content =
|
|
70930
|
+
const content = readFileSync26(projectDetected.path, "utf-8");
|
|
69827
70931
|
return parseJsonc(content);
|
|
69828
70932
|
} catch {
|
|
69829
70933
|
return null;
|
|
@@ -69833,7 +70937,7 @@ function loadOmoConfig() {
|
|
|
69833
70937
|
const userDetected = detectPluginConfigFile(userConfigDir);
|
|
69834
70938
|
if (userDetected.format !== "none") {
|
|
69835
70939
|
try {
|
|
69836
|
-
const content =
|
|
70940
|
+
const content = readFileSync26(userDetected.path, "utf-8");
|
|
69837
70941
|
return parseJsonc(content);
|
|
69838
70942
|
} catch {
|
|
69839
70943
|
return null;
|
|
@@ -69844,7 +70948,7 @@ function loadOmoConfig() {
|
|
|
69844
70948
|
|
|
69845
70949
|
// src/cli/doctor/checks/model-resolution-details.ts
|
|
69846
70950
|
init_shared();
|
|
69847
|
-
import { join as
|
|
70951
|
+
import { join as join29 } from "path";
|
|
69848
70952
|
|
|
69849
70953
|
// src/cli/doctor/checks/model-resolution-variant.ts
|
|
69850
70954
|
function formatModelWithVariant(model, variant) {
|
|
@@ -69886,7 +70990,7 @@ function formatCapabilityResolutionLabel(mode) {
|
|
|
69886
70990
|
}
|
|
69887
70991
|
function buildModelResolutionDetails(options) {
|
|
69888
70992
|
const details = [];
|
|
69889
|
-
const cacheFile =
|
|
70993
|
+
const cacheFile = join29(getOpenCodeCacheDir(), "models.json");
|
|
69890
70994
|
details.push("\u2550\u2550\u2550 Available Models (from cache) \u2550\u2550\u2550");
|
|
69891
70995
|
details.push("");
|
|
69892
70996
|
if (options.available.cacheExists) {
|
|
@@ -70041,7 +71145,7 @@ async function checkModels() {
|
|
|
70041
71145
|
}
|
|
70042
71146
|
|
|
70043
71147
|
// src/cli/doctor/checks/config.ts
|
|
70044
|
-
var PROJECT_CONFIG_DIR2 =
|
|
71148
|
+
var PROJECT_CONFIG_DIR2 = join30(process.cwd(), ".opencode");
|
|
70045
71149
|
function findConfigPath() {
|
|
70046
71150
|
const projectConfig = detectPluginConfigFile(PROJECT_CONFIG_DIR2);
|
|
70047
71151
|
if (projectConfig.format !== "none")
|
|
@@ -70058,7 +71162,7 @@ function validateConfig() {
|
|
|
70058
71162
|
return { exists: false, path: null, valid: true, config: null, errors: [] };
|
|
70059
71163
|
}
|
|
70060
71164
|
try {
|
|
70061
|
-
const content =
|
|
71165
|
+
const content = readFileSync27(configPath, "utf-8");
|
|
70062
71166
|
const rawConfig = parseJsonc(content);
|
|
70063
71167
|
const schemaResult = OhMyOpenCodeConfigSchema.safeParse(rawConfig);
|
|
70064
71168
|
if (!schemaResult.success) {
|
|
@@ -70162,9 +71266,9 @@ async function checkConfig() {
|
|
|
70162
71266
|
|
|
70163
71267
|
// src/cli/doctor/checks/dependencies.ts
|
|
70164
71268
|
init_spawn_with_windows_hide();
|
|
70165
|
-
import { existsSync as
|
|
71269
|
+
import { existsSync as existsSync31 } from "fs";
|
|
70166
71270
|
import { createRequire } from "module";
|
|
70167
|
-
import { dirname as
|
|
71271
|
+
import { dirname as dirname10, join as join31 } from "path";
|
|
70168
71272
|
async function checkBinaryExists(binary2) {
|
|
70169
71273
|
try {
|
|
70170
71274
|
const path10 = Bun.which(binary2);
|
|
@@ -70220,15 +71324,15 @@ async function checkAstGrepNapi() {
|
|
|
70220
71324
|
path: null
|
|
70221
71325
|
};
|
|
70222
71326
|
} catch {
|
|
70223
|
-
const { existsSync:
|
|
70224
|
-
const { join:
|
|
71327
|
+
const { existsSync: existsSync32 } = await import("fs");
|
|
71328
|
+
const { join: join32 } = await import("path");
|
|
70225
71329
|
const { homedir: homedir8 } = await import("os");
|
|
70226
71330
|
const pathsToCheck = [
|
|
70227
|
-
|
|
70228
|
-
|
|
71331
|
+
join32(homedir8(), ".config", "opencode", "node_modules", "@ast-grep", "napi"),
|
|
71332
|
+
join32(process.cwd(), "node_modules", "@ast-grep", "napi")
|
|
70229
71333
|
];
|
|
70230
71334
|
for (const napiPath of pathsToCheck) {
|
|
70231
|
-
if (
|
|
71335
|
+
if (existsSync32(napiPath)) {
|
|
70232
71336
|
return {
|
|
70233
71337
|
name: "AST-Grep NAPI",
|
|
70234
71338
|
required: false,
|
|
@@ -70253,8 +71357,8 @@ function findCommentCheckerPackageBinary() {
|
|
|
70253
71357
|
try {
|
|
70254
71358
|
const require2 = createRequire(import.meta.url);
|
|
70255
71359
|
const pkgPath = require2.resolve("@code-yeongyu/comment-checker/package.json");
|
|
70256
|
-
const binaryPath =
|
|
70257
|
-
if (
|
|
71360
|
+
const binaryPath = join31(dirname10(pkgPath), "bin", binaryName);
|
|
71361
|
+
if (existsSync31(binaryPath))
|
|
70258
71362
|
return binaryPath;
|
|
70259
71363
|
} catch {}
|
|
70260
71364
|
return null;
|
|
@@ -70411,15 +71515,15 @@ var BUILTIN_SERVERS = {
|
|
|
70411
71515
|
"kotlin-ls": { command: ["kotlin-lsp"], extensions: [".kt", ".kts"] }
|
|
70412
71516
|
};
|
|
70413
71517
|
// src/tools/lsp/server-config-loader.ts
|
|
70414
|
-
import { existsSync as
|
|
70415
|
-
import { join as
|
|
71518
|
+
import { existsSync as existsSync32, readFileSync as readFileSync28 } from "fs";
|
|
71519
|
+
import { join as join32 } from "path";
|
|
70416
71520
|
init_shared();
|
|
70417
71521
|
init_jsonc_parser();
|
|
70418
71522
|
function loadJsonFile(path10) {
|
|
70419
|
-
if (!
|
|
71523
|
+
if (!existsSync32(path10))
|
|
70420
71524
|
return null;
|
|
70421
71525
|
try {
|
|
70422
|
-
return parseJsonc(
|
|
71526
|
+
return parseJsonc(readFileSync28(path10, "utf-8"));
|
|
70423
71527
|
} catch {
|
|
70424
71528
|
return null;
|
|
70425
71529
|
}
|
|
@@ -70428,9 +71532,9 @@ function getConfigPaths2() {
|
|
|
70428
71532
|
const cwd = process.cwd();
|
|
70429
71533
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
70430
71534
|
return {
|
|
70431
|
-
project: detectPluginConfigFile(
|
|
71535
|
+
project: detectPluginConfigFile(join32(cwd, ".opencode")).path,
|
|
70432
71536
|
user: detectPluginConfigFile(configDir).path,
|
|
70433
|
-
opencode: detectConfigFile(
|
|
71537
|
+
opencode: detectConfigFile(join32(configDir, "opencode")).path
|
|
70434
71538
|
};
|
|
70435
71539
|
}
|
|
70436
71540
|
function loadAllConfigs() {
|
|
@@ -70499,21 +71603,21 @@ function getMergedServers() {
|
|
|
70499
71603
|
}
|
|
70500
71604
|
|
|
70501
71605
|
// src/tools/lsp/server-installation.ts
|
|
70502
|
-
import { existsSync as
|
|
70503
|
-
import { delimiter as delimiter2, join as
|
|
71606
|
+
import { existsSync as existsSync33 } from "fs";
|
|
71607
|
+
import { delimiter as delimiter2, join as join34 } from "path";
|
|
70504
71608
|
|
|
70505
71609
|
// src/tools/lsp/server-path-bases.ts
|
|
70506
71610
|
init_shared();
|
|
70507
|
-
import { join as
|
|
71611
|
+
import { join as join33 } from "path";
|
|
70508
71612
|
function getLspServerAdditionalPathBases(workingDirectory) {
|
|
70509
71613
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
70510
|
-
const dataDir =
|
|
71614
|
+
const dataDir = join33(getDataDir(), "opencode");
|
|
70511
71615
|
return [
|
|
70512
|
-
|
|
70513
|
-
|
|
70514
|
-
|
|
70515
|
-
|
|
70516
|
-
|
|
71616
|
+
join33(workingDirectory, "node_modules", ".bin"),
|
|
71617
|
+
join33(configDir, "bin"),
|
|
71618
|
+
join33(configDir, "node_modules", ".bin"),
|
|
71619
|
+
join33(dataDir, "bin"),
|
|
71620
|
+
join33(dataDir, "bin", "node_modules", ".bin")
|
|
70517
71621
|
];
|
|
70518
71622
|
}
|
|
70519
71623
|
|
|
@@ -70523,7 +71627,7 @@ function isServerInstalled(command) {
|
|
|
70523
71627
|
return false;
|
|
70524
71628
|
const cmd = command[0];
|
|
70525
71629
|
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
70526
|
-
if (
|
|
71630
|
+
if (existsSync33(cmd))
|
|
70527
71631
|
return true;
|
|
70528
71632
|
}
|
|
70529
71633
|
const isWindows = process.platform === "win32";
|
|
@@ -70544,14 +71648,14 @@ function isServerInstalled(command) {
|
|
|
70544
71648
|
const paths = pathEnv.split(delimiter2);
|
|
70545
71649
|
for (const p2 of paths) {
|
|
70546
71650
|
for (const suffix of exts) {
|
|
70547
|
-
if (
|
|
71651
|
+
if (existsSync33(join34(p2, cmd + suffix))) {
|
|
70548
71652
|
return true;
|
|
70549
71653
|
}
|
|
70550
71654
|
}
|
|
70551
71655
|
}
|
|
70552
71656
|
for (const base of getLspServerAdditionalPathBases(process.cwd())) {
|
|
70553
71657
|
for (const suffix of exts) {
|
|
70554
|
-
if (
|
|
71658
|
+
if (existsSync33(join34(base, cmd + suffix))) {
|
|
70555
71659
|
return true;
|
|
70556
71660
|
}
|
|
70557
71661
|
}
|
|
@@ -70613,24 +71717,24 @@ function getInstalledLspServers() {
|
|
|
70613
71717
|
|
|
70614
71718
|
// src/cli/doctor/checks/tools-mcp.ts
|
|
70615
71719
|
init_shared();
|
|
70616
|
-
import { existsSync as
|
|
71720
|
+
import { existsSync as existsSync34, readFileSync as readFileSync29 } from "fs";
|
|
70617
71721
|
import { homedir as homedir8 } from "os";
|
|
70618
|
-
import { join as
|
|
71722
|
+
import { join as join35 } from "path";
|
|
70619
71723
|
var BUILTIN_MCP_SERVERS = ["context7", "grep_app"];
|
|
70620
71724
|
function getMcpConfigPaths() {
|
|
70621
71725
|
return [
|
|
70622
|
-
|
|
70623
|
-
|
|
70624
|
-
|
|
71726
|
+
join35(homedir8(), ".claude", ".mcp.json"),
|
|
71727
|
+
join35(process.cwd(), ".mcp.json"),
|
|
71728
|
+
join35(process.cwd(), ".claude", ".mcp.json")
|
|
70625
71729
|
];
|
|
70626
71730
|
}
|
|
70627
71731
|
function loadUserMcpConfig() {
|
|
70628
71732
|
const servers = {};
|
|
70629
71733
|
for (const configPath of getMcpConfigPaths()) {
|
|
70630
|
-
if (!
|
|
71734
|
+
if (!existsSync34(configPath))
|
|
70631
71735
|
continue;
|
|
70632
71736
|
try {
|
|
70633
|
-
const content =
|
|
71737
|
+
const content = readFileSync29(configPath, "utf-8");
|
|
70634
71738
|
const config2 = parseJsonc(content);
|
|
70635
71739
|
if (config2.mcpServers) {
|
|
70636
71740
|
Object.assign(servers, config2.mcpServers);
|
|
@@ -70797,17 +71901,17 @@ function formatStatusSymbol(status) {
|
|
|
70797
71901
|
const colorFn = STATUS_COLORS[status];
|
|
70798
71902
|
switch (status) {
|
|
70799
71903
|
case "pass":
|
|
70800
|
-
return colorFn(
|
|
71904
|
+
return colorFn(SYMBOLS2.check);
|
|
70801
71905
|
case "fail":
|
|
70802
|
-
return colorFn(
|
|
71906
|
+
return colorFn(SYMBOLS2.cross);
|
|
70803
71907
|
case "warn":
|
|
70804
|
-
return colorFn(
|
|
71908
|
+
return colorFn(SYMBOLS2.warn);
|
|
70805
71909
|
case "skip":
|
|
70806
|
-
return colorFn(
|
|
71910
|
+
return colorFn(SYMBOLS2.skip);
|
|
70807
71911
|
}
|
|
70808
71912
|
}
|
|
70809
71913
|
function formatStatusMark(available) {
|
|
70810
|
-
return available ? import_picocolors17.default.green(
|
|
71914
|
+
return available ? import_picocolors17.default.green(SYMBOLS2.check) : import_picocolors17.default.red(SYMBOLS2.cross);
|
|
70811
71915
|
}
|
|
70812
71916
|
function formatHeader() {
|
|
70813
71917
|
return `
|
|
@@ -70837,12 +71941,12 @@ function formatDefault(result) {
|
|
|
70837
71941
|
if (allIssues.length === 0) {
|
|
70838
71942
|
const opencodeVer = result.systemInfo.opencodeVersion ?? "unknown";
|
|
70839
71943
|
const pluginVer = result.systemInfo.pluginVersion ?? "unknown";
|
|
70840
|
-
lines.push(` ${import_picocolors18.default.green(
|
|
71944
|
+
lines.push(` ${import_picocolors18.default.green(SYMBOLS2.check)} ${import_picocolors18.default.green(`System OK (opencode ${opencodeVer} \xB7 oh-my-opencode ${pluginVer})`)}`);
|
|
70841
71945
|
} else {
|
|
70842
71946
|
const issueCount = allIssues.filter((i2) => i2.severity === "error").length;
|
|
70843
71947
|
const warnCount = allIssues.filter((i2) => i2.severity === "warning").length;
|
|
70844
71948
|
const totalStr = `${issueCount + warnCount} ${issueCount + warnCount === 1 ? "issue" : "issues"}`;
|
|
70845
|
-
lines.push(` ${import_picocolors18.default.yellow(
|
|
71949
|
+
lines.push(` ${import_picocolors18.default.yellow(SYMBOLS2.warn)} ${totalStr} found:
|
|
70846
71950
|
`);
|
|
70847
71951
|
allIssues.forEach((issue2, index) => {
|
|
70848
71952
|
lines.push(formatIssue(issue2, index + 1));
|
|
@@ -71083,11 +72187,11 @@ async function refreshModelCapabilities(options, deps = {}) {
|
|
|
71083
72187
|
|
|
71084
72188
|
// src/features/mcp-oauth/storage.ts
|
|
71085
72189
|
init_shared();
|
|
71086
|
-
import { chmodSync, existsSync as
|
|
71087
|
-
import { dirname as
|
|
72190
|
+
import { chmodSync, existsSync as existsSync35, mkdirSync as mkdirSync9, readFileSync as readFileSync30, renameSync as renameSync4, unlinkSync as unlinkSync4, writeFileSync as writeFileSync10 } from "fs";
|
|
72191
|
+
import { dirname as dirname11, join as join36 } from "path";
|
|
71088
72192
|
var STORAGE_FILE_NAME = "mcp-oauth.json";
|
|
71089
72193
|
function getMcpOauthStoragePath() {
|
|
71090
|
-
return
|
|
72194
|
+
return join36(getOpenCodeConfigDir({ binary: "opencode" }), STORAGE_FILE_NAME);
|
|
71091
72195
|
}
|
|
71092
72196
|
function normalizeHost(serverHost) {
|
|
71093
72197
|
let host = serverHost.trim();
|
|
@@ -71124,11 +72228,11 @@ function buildKey(serverHost, resource) {
|
|
|
71124
72228
|
}
|
|
71125
72229
|
function readStore() {
|
|
71126
72230
|
const filePath = getMcpOauthStoragePath();
|
|
71127
|
-
if (!
|
|
72231
|
+
if (!existsSync35(filePath)) {
|
|
71128
72232
|
return null;
|
|
71129
72233
|
}
|
|
71130
72234
|
try {
|
|
71131
|
-
const content =
|
|
72235
|
+
const content = readFileSync30(filePath, "utf-8");
|
|
71132
72236
|
return JSON.parse(content);
|
|
71133
72237
|
} catch {
|
|
71134
72238
|
return null;
|
|
@@ -71137,12 +72241,14 @@ function readStore() {
|
|
|
71137
72241
|
function writeStore(store2) {
|
|
71138
72242
|
const filePath = getMcpOauthStoragePath();
|
|
71139
72243
|
try {
|
|
71140
|
-
const dir =
|
|
71141
|
-
if (!
|
|
71142
|
-
|
|
71143
|
-
}
|
|
71144
|
-
|
|
71145
|
-
|
|
72244
|
+
const dir = dirname11(filePath);
|
|
72245
|
+
if (!existsSync35(dir)) {
|
|
72246
|
+
mkdirSync9(dir, { recursive: true });
|
|
72247
|
+
}
|
|
72248
|
+
const tempPath = `${filePath}.tmp.${Date.now()}`;
|
|
72249
|
+
writeFileSync10(tempPath, JSON.stringify(store2, null, 2), { encoding: "utf-8", mode: 384 });
|
|
72250
|
+
chmodSync(tempPath, 384);
|
|
72251
|
+
renameSync4(tempPath, filePath);
|
|
71146
72252
|
return true;
|
|
71147
72253
|
} catch {
|
|
71148
72254
|
return false;
|
|
@@ -71173,7 +72279,7 @@ function deleteToken(serverHost, resource) {
|
|
|
71173
72279
|
if (Object.keys(store2).length === 0) {
|
|
71174
72280
|
try {
|
|
71175
72281
|
const filePath = getMcpOauthStoragePath();
|
|
71176
|
-
if (
|
|
72282
|
+
if (existsSync35(filePath)) {
|
|
71177
72283
|
unlinkSync4(filePath);
|
|
71178
72284
|
}
|
|
71179
72285
|
return true;
|
|
@@ -71363,7 +72469,7 @@ async function findAvailablePort2(startPort = DEFAULT_PORT) {
|
|
|
71363
72469
|
}
|
|
71364
72470
|
|
|
71365
72471
|
// src/features/mcp-oauth/oauth-authorization-flow.ts
|
|
71366
|
-
import { spawn
|
|
72472
|
+
import { spawn } from "child_process";
|
|
71367
72473
|
import { createHash, randomBytes as randomBytes2 } from "crypto";
|
|
71368
72474
|
import { createServer } from "http";
|
|
71369
72475
|
function generateCodeVerifier() {
|
|
@@ -71396,7 +72502,7 @@ function startCallbackServer(port) {
|
|
|
71396
72502
|
clearTimeout(timeoutId);
|
|
71397
72503
|
const requestUrl = new URL(request.url ?? "/", `http://localhost:${port}`);
|
|
71398
72504
|
const code = requestUrl.searchParams.get("code");
|
|
71399
|
-
const
|
|
72505
|
+
const state2 = requestUrl.searchParams.get("state");
|
|
71400
72506
|
const error48 = requestUrl.searchParams.get("error");
|
|
71401
72507
|
if (error48) {
|
|
71402
72508
|
const errorDescription = requestUrl.searchParams.get("error_description") ?? error48;
|
|
@@ -71406,7 +72512,7 @@ function startCallbackServer(port) {
|
|
|
71406
72512
|
reject(new Error(`OAuth authorization error: ${errorDescription}`));
|
|
71407
72513
|
return;
|
|
71408
72514
|
}
|
|
71409
|
-
if (!code || !
|
|
72515
|
+
if (!code || !state2) {
|
|
71410
72516
|
response.writeHead(400, { "content-type": "text/html" });
|
|
71411
72517
|
response.end("<html><body><h1>Missing code or state</h1></body></html>");
|
|
71412
72518
|
server2.close();
|
|
@@ -71416,7 +72522,7 @@ function startCallbackServer(port) {
|
|
|
71416
72522
|
response.writeHead(200, { "content-type": "text/html" });
|
|
71417
72523
|
response.end("<html><body><h1>Authorization successful. You can close this tab.</h1></body></html>");
|
|
71418
72524
|
server2.close();
|
|
71419
|
-
resolve2({ code, state });
|
|
72525
|
+
resolve2({ code, state: state2 });
|
|
71420
72526
|
});
|
|
71421
72527
|
timeoutId = setTimeout(() => {
|
|
71422
72528
|
server2.close();
|
|
@@ -71444,7 +72550,7 @@ function openBrowser(url2) {
|
|
|
71444
72550
|
args = [url2];
|
|
71445
72551
|
}
|
|
71446
72552
|
try {
|
|
71447
|
-
const child =
|
|
72553
|
+
const child = spawn(command, args, { stdio: "ignore", detached: true });
|
|
71448
72554
|
child.on("error", () => {});
|
|
71449
72555
|
child.unref();
|
|
71450
72556
|
} catch {}
|
|
@@ -71452,25 +72558,57 @@ function openBrowser(url2) {
|
|
|
71452
72558
|
async function runAuthorizationCodeRedirect(options) {
|
|
71453
72559
|
const verifier = generateCodeVerifier();
|
|
71454
72560
|
const challenge = generateCodeChallenge(verifier);
|
|
71455
|
-
const
|
|
72561
|
+
const state2 = randomBytes2(16).toString("hex");
|
|
71456
72562
|
const authorizationUrl = buildAuthorizationUrl(options.authorizationEndpoint, {
|
|
71457
72563
|
clientId: options.clientId,
|
|
71458
72564
|
redirectUri: options.redirectUri,
|
|
71459
72565
|
codeChallenge: challenge,
|
|
71460
|
-
state,
|
|
72566
|
+
state: state2,
|
|
71461
72567
|
scopes: options.scopes,
|
|
71462
72568
|
resource: options.resource
|
|
71463
72569
|
});
|
|
71464
72570
|
const callbackPromise = startCallbackServer(options.callbackPort);
|
|
71465
72571
|
openBrowser(authorizationUrl);
|
|
71466
72572
|
const result = await callbackPromise;
|
|
71467
|
-
if (result.state !==
|
|
72573
|
+
if (result.state !== state2) {
|
|
71468
72574
|
throw new Error("OAuth state mismatch");
|
|
71469
72575
|
}
|
|
71470
72576
|
return { code: result.code, verifier };
|
|
71471
72577
|
}
|
|
71472
72578
|
|
|
71473
72579
|
// src/features/mcp-oauth/provider.ts
|
|
72580
|
+
async function parseTokenResponse(tokenResponse) {
|
|
72581
|
+
if (!tokenResponse.ok) {
|
|
72582
|
+
let errorDetail = `${tokenResponse.status}`;
|
|
72583
|
+
try {
|
|
72584
|
+
const body = await tokenResponse.json();
|
|
72585
|
+
if (body.error) {
|
|
72586
|
+
errorDetail = `${tokenResponse.status} ${body.error}`;
|
|
72587
|
+
if (body.error_description) {
|
|
72588
|
+
errorDetail += `: ${body.error_description}`;
|
|
72589
|
+
}
|
|
72590
|
+
}
|
|
72591
|
+
} catch {}
|
|
72592
|
+
throw new Error(`Token exchange failed: ${errorDetail}`);
|
|
72593
|
+
}
|
|
72594
|
+
return await tokenResponse.json();
|
|
72595
|
+
}
|
|
72596
|
+
function buildOAuthTokenData(tokenData, clientInfo, fallbackRefreshToken) {
|
|
72597
|
+
const accessToken = tokenData.access_token;
|
|
72598
|
+
if (typeof accessToken !== "string") {
|
|
72599
|
+
throw new Error("Token response missing access_token");
|
|
72600
|
+
}
|
|
72601
|
+
return {
|
|
72602
|
+
accessToken,
|
|
72603
|
+
refreshToken: typeof tokenData.refresh_token === "string" ? tokenData.refresh_token : fallbackRefreshToken,
|
|
72604
|
+
expiresAt: typeof tokenData.expires_in === "number" ? Math.floor(Date.now() / 1000) + tokenData.expires_in : undefined,
|
|
72605
|
+
clientInfo: {
|
|
72606
|
+
clientId: clientInfo.clientId,
|
|
72607
|
+
...clientInfo.clientSecret ? { clientSecret: clientInfo.clientSecret } : {}
|
|
72608
|
+
}
|
|
72609
|
+
};
|
|
72610
|
+
}
|
|
72611
|
+
|
|
71474
72612
|
class McpOAuthProvider {
|
|
71475
72613
|
serverUrl;
|
|
71476
72614
|
configClientId;
|
|
@@ -71565,33 +72703,34 @@ class McpOAuthProvider {
|
|
|
71565
72703
|
...metadata.resource ? { resource: metadata.resource } : {}
|
|
71566
72704
|
}).toString()
|
|
71567
72705
|
});
|
|
71568
|
-
|
|
71569
|
-
|
|
71570
|
-
|
|
71571
|
-
|
|
71572
|
-
|
|
71573
|
-
|
|
71574
|
-
|
|
71575
|
-
|
|
71576
|
-
|
|
71577
|
-
|
|
71578
|
-
|
|
71579
|
-
throw new Error(`Token exchange failed: ${errorDetail}`);
|
|
71580
|
-
}
|
|
71581
|
-
const tokenData = await tokenResponse.json();
|
|
71582
|
-
const accessToken = tokenData.access_token;
|
|
71583
|
-
if (typeof accessToken !== "string") {
|
|
71584
|
-
throw new Error("Token response missing access_token");
|
|
72706
|
+
const tokenData = await parseTokenResponse(tokenResponse);
|
|
72707
|
+
const oauthTokenData = buildOAuthTokenData(tokenData, clientInfo);
|
|
72708
|
+
this.saveTokens(oauthTokenData);
|
|
72709
|
+
return oauthTokenData;
|
|
72710
|
+
}
|
|
72711
|
+
async refresh(refreshToken) {
|
|
72712
|
+
const metadata = await discoverOAuthServerMetadata(this.serverUrl);
|
|
72713
|
+
const clientInfo = this.clientInformation();
|
|
72714
|
+
const clientId = clientInfo?.clientId ?? this.configClientId;
|
|
72715
|
+
if (!clientId) {
|
|
72716
|
+
throw new Error("No client information available. Run login() or register a client first.");
|
|
71585
72717
|
}
|
|
71586
|
-
const
|
|
71587
|
-
|
|
71588
|
-
|
|
71589
|
-
|
|
71590
|
-
|
|
71591
|
-
|
|
71592
|
-
|
|
71593
|
-
|
|
71594
|
-
|
|
72718
|
+
const tokenResponse = await fetch(metadata.tokenEndpoint, {
|
|
72719
|
+
method: "POST",
|
|
72720
|
+
headers: { "content-type": "application/x-www-form-urlencoded" },
|
|
72721
|
+
body: new URLSearchParams({
|
|
72722
|
+
grant_type: "refresh_token",
|
|
72723
|
+
refresh_token: refreshToken,
|
|
72724
|
+
client_id: clientId,
|
|
72725
|
+
...clientInfo?.clientSecret ? { client_secret: clientInfo.clientSecret } : {},
|
|
72726
|
+
...metadata.resource ? { resource: metadata.resource } : {}
|
|
72727
|
+
}).toString()
|
|
72728
|
+
});
|
|
72729
|
+
const tokenData = await parseTokenResponse(tokenResponse);
|
|
72730
|
+
const oauthTokenData = buildOAuthTokenData(tokenData, {
|
|
72731
|
+
clientId,
|
|
72732
|
+
...clientInfo?.clientSecret ? { clientSecret: clientInfo.clientSecret } : {}
|
|
72733
|
+
}, refreshToken);
|
|
71595
72734
|
this.saveTokens(oauthTokenData);
|
|
71596
72735
|
return oauthTokenData;
|
|
71597
72736
|
}
|