evil-omo 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/README.ja.md +27 -16
- package/README.ko.md +27 -16
- package/README.md +1 -1
- package/README.ru.md +20 -9
- package/README.zh-cn.md +26 -15
- package/bin/evil-omo.js +1 -1
- package/bin/platform.js +14 -17
- package/dist/agents/dynamic-agent-core-sections.d.ts +7 -0
- package/dist/agents/dynamic-agent-prompt-builder.d.ts +1 -1
- package/dist/agents/hephaestus/gpt-5-4.d.ts +22 -1
- package/dist/cli/config-manager/backup-config.d.ts +6 -0
- package/dist/cli/config-manager/config-context.d.ts +0 -1
- 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 +2065 -805
- 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/create-runtime-tmux-config.d.ts +1 -0
- package/dist/features/background-agent/compaction-aware-message-resolver.d.ts +5 -2
- package/dist/features/background-agent/spawner.d.ts +3 -0
- 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/discovery.d.ts +2 -1
- package/dist/features/claude-code-plugin-loader/loader.d.ts +16 -0
- package/dist/features/claude-code-plugin-loader/scope-filter.d.ts +2 -0
- package/dist/features/claude-code-plugin-loader/types.d.ts +21 -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 +5 -5
- package/dist/hooks/comment-checker/downloader.d.ts +1 -1
- 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 +7425 -6114
- package/dist/plugin/chat-params.d.ts +1 -0
- package/dist/plugin/hooks/create-transform-hooks.d.ts +2 -0
- package/dist/plugin/tool-registry.d.ts +1 -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/shared/system-directive.d.ts +5 -5
- 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 +77 -4
package/dist/cli/index.js
CHANGED
|
@@ -4917,6 +4917,196 @@ var init_command_executor = __esm(() => {
|
|
|
4917
4917
|
// src/shared/contains-path.ts
|
|
4918
4918
|
var init_contains_path = () => {};
|
|
4919
4919
|
|
|
4920
|
+
// src/shared/logger.ts
|
|
4921
|
+
import * as fs from "fs";
|
|
4922
|
+
import * as os from "os";
|
|
4923
|
+
import * as path from "path";
|
|
4924
|
+
function flush() {
|
|
4925
|
+
if (buffer.length === 0)
|
|
4926
|
+
return;
|
|
4927
|
+
const data = buffer.join("");
|
|
4928
|
+
buffer = [];
|
|
4929
|
+
try {
|
|
4930
|
+
fs.appendFileSync(logFile, data);
|
|
4931
|
+
} catch {}
|
|
4932
|
+
}
|
|
4933
|
+
function scheduleFlush() {
|
|
4934
|
+
if (flushTimer)
|
|
4935
|
+
return;
|
|
4936
|
+
flushTimer = setTimeout(() => {
|
|
4937
|
+
flushTimer = null;
|
|
4938
|
+
flush();
|
|
4939
|
+
}, FLUSH_INTERVAL_MS);
|
|
4940
|
+
}
|
|
4941
|
+
function log(message, data) {
|
|
4942
|
+
try {
|
|
4943
|
+
const timestamp2 = new Date().toISOString();
|
|
4944
|
+
const logEntry = `[${timestamp2}] ${message} ${data ? JSON.stringify(data) : ""}
|
|
4945
|
+
`;
|
|
4946
|
+
buffer.push(logEntry);
|
|
4947
|
+
if (buffer.length >= BUFFER_SIZE_LIMIT) {
|
|
4948
|
+
flush();
|
|
4949
|
+
} else {
|
|
4950
|
+
scheduleFlush();
|
|
4951
|
+
}
|
|
4952
|
+
} catch {}
|
|
4953
|
+
}
|
|
4954
|
+
var logFile, buffer, flushTimer = null, FLUSH_INTERVAL_MS = 500, BUFFER_SIZE_LIMIT = 50;
|
|
4955
|
+
var init_logger = __esm(() => {
|
|
4956
|
+
logFile = path.join(os.tmpdir(), "evil-omo.log");
|
|
4957
|
+
buffer = [];
|
|
4958
|
+
});
|
|
4959
|
+
|
|
4960
|
+
// src/shared/file-reference-resolver.ts
|
|
4961
|
+
var init_file_reference_resolver = __esm(() => {
|
|
4962
|
+
init_contains_path();
|
|
4963
|
+
init_logger();
|
|
4964
|
+
});
|
|
4965
|
+
// src/shared/deep-merge.ts
|
|
4966
|
+
function isPlainObject(value) {
|
|
4967
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.prototype.toString.call(value) === "[object Object]";
|
|
4968
|
+
}
|
|
4969
|
+
function deepMerge(base, override, depth = 0) {
|
|
4970
|
+
if (!base && !override)
|
|
4971
|
+
return;
|
|
4972
|
+
if (!base)
|
|
4973
|
+
return override;
|
|
4974
|
+
if (!override)
|
|
4975
|
+
return base;
|
|
4976
|
+
if (depth > MAX_DEPTH)
|
|
4977
|
+
return override ?? base;
|
|
4978
|
+
const result = { ...base };
|
|
4979
|
+
for (const key of Object.keys(override)) {
|
|
4980
|
+
if (DANGEROUS_KEYS.has(key))
|
|
4981
|
+
continue;
|
|
4982
|
+
const baseValue = base[key];
|
|
4983
|
+
const overrideValue = override[key];
|
|
4984
|
+
if (overrideValue === undefined)
|
|
4985
|
+
continue;
|
|
4986
|
+
if (isPlainObject(baseValue) && isPlainObject(overrideValue)) {
|
|
4987
|
+
result[key] = deepMerge(baseValue, overrideValue, depth + 1);
|
|
4988
|
+
} else {
|
|
4989
|
+
result[key] = overrideValue;
|
|
4990
|
+
}
|
|
4991
|
+
}
|
|
4992
|
+
return result;
|
|
4993
|
+
}
|
|
4994
|
+
var DANGEROUS_KEYS, MAX_DEPTH = 50;
|
|
4995
|
+
var init_deep_merge = __esm(() => {
|
|
4996
|
+
DANGEROUS_KEYS = new Set(["__proto__", "constructor", "prototype"]);
|
|
4997
|
+
});
|
|
4998
|
+
|
|
4999
|
+
// src/shared/snake-case.ts
|
|
5000
|
+
var init_snake_case = __esm(() => {
|
|
5001
|
+
init_deep_merge();
|
|
5002
|
+
});
|
|
5003
|
+
|
|
5004
|
+
// src/shared/tool-name.ts
|
|
5005
|
+
var init_tool_name = () => {};
|
|
5006
|
+
|
|
5007
|
+
// src/shared/pattern-matcher.ts
|
|
5008
|
+
var regexCache;
|
|
5009
|
+
var init_pattern_matcher = __esm(() => {
|
|
5010
|
+
regexCache = new Map;
|
|
5011
|
+
});
|
|
5012
|
+
// src/shared/file-utils.ts
|
|
5013
|
+
import { lstatSync, realpathSync } from "fs";
|
|
5014
|
+
function normalizeDarwinRealpath(filePath) {
|
|
5015
|
+
return filePath.startsWith("/private/var/") ? filePath.slice("/private".length) : filePath;
|
|
5016
|
+
}
|
|
5017
|
+
function resolveSymlink(filePath) {
|
|
5018
|
+
try {
|
|
5019
|
+
return normalizeDarwinRealpath(realpathSync(filePath));
|
|
5020
|
+
} catch {
|
|
5021
|
+
return filePath;
|
|
5022
|
+
}
|
|
5023
|
+
}
|
|
5024
|
+
var init_file_utils = () => {};
|
|
5025
|
+
|
|
5026
|
+
// src/shared/context-limit-resolver.ts
|
|
5027
|
+
var init_context_limit_resolver = () => {};
|
|
5028
|
+
|
|
5029
|
+
// src/shared/normalize-sdk-response.ts
|
|
5030
|
+
function normalizeSDKResponse(response, fallback, options) {
|
|
5031
|
+
if (response === null || response === undefined) {
|
|
5032
|
+
return fallback;
|
|
5033
|
+
}
|
|
5034
|
+
if (Array.isArray(response)) {
|
|
5035
|
+
return response;
|
|
5036
|
+
}
|
|
5037
|
+
if (typeof response === "object" && "data" in response) {
|
|
5038
|
+
const data = response.data;
|
|
5039
|
+
if (data !== null && data !== undefined) {
|
|
5040
|
+
return data;
|
|
5041
|
+
}
|
|
5042
|
+
if (options?.preferResponseOnMissingData === true) {
|
|
5043
|
+
return response;
|
|
5044
|
+
}
|
|
5045
|
+
return fallback;
|
|
5046
|
+
}
|
|
5047
|
+
if (options?.preferResponseOnMissingData === true) {
|
|
5048
|
+
return response;
|
|
5049
|
+
}
|
|
5050
|
+
return fallback;
|
|
5051
|
+
}
|
|
5052
|
+
|
|
5053
|
+
// src/shared/dynamic-truncator.ts
|
|
5054
|
+
var init_dynamic_truncator = __esm(() => {
|
|
5055
|
+
init_context_limit_resolver();
|
|
5056
|
+
});
|
|
5057
|
+
|
|
5058
|
+
// src/shared/data-path.ts
|
|
5059
|
+
import * as path2 from "path";
|
|
5060
|
+
import * as os2 from "os";
|
|
5061
|
+
import { accessSync, constants, mkdirSync } from "fs";
|
|
5062
|
+
function resolveWritableDirectory(preferredDir, fallbackSuffix) {
|
|
5063
|
+
try {
|
|
5064
|
+
mkdirSync(preferredDir, { recursive: true });
|
|
5065
|
+
accessSync(preferredDir, constants.W_OK);
|
|
5066
|
+
return preferredDir;
|
|
5067
|
+
} catch {
|
|
5068
|
+
const fallbackDir = path2.join(os2.tmpdir(), fallbackSuffix);
|
|
5069
|
+
mkdirSync(fallbackDir, { recursive: true });
|
|
5070
|
+
return fallbackDir;
|
|
5071
|
+
}
|
|
5072
|
+
}
|
|
5073
|
+
function getDataDir() {
|
|
5074
|
+
const preferredDir = process.env.XDG_DATA_HOME ?? path2.join(os2.homedir(), ".local", "share");
|
|
5075
|
+
return resolveWritableDirectory(preferredDir, "opencode-data");
|
|
5076
|
+
}
|
|
5077
|
+
function getOpenCodeStorageDir() {
|
|
5078
|
+
return path2.join(getDataDir(), "opencode", "storage");
|
|
5079
|
+
}
|
|
5080
|
+
function getCacheDir() {
|
|
5081
|
+
const preferredDir = process.env.XDG_CACHE_HOME ?? path2.join(os2.homedir(), ".cache");
|
|
5082
|
+
return resolveWritableDirectory(preferredDir, "opencode-cache");
|
|
5083
|
+
}
|
|
5084
|
+
function getOmoOpenCodeCacheDir() {
|
|
5085
|
+
return path2.join(getCacheDir(), "evil-omo");
|
|
5086
|
+
}
|
|
5087
|
+
function getOpenCodeCacheDir() {
|
|
5088
|
+
return path2.join(getCacheDir(), "opencode");
|
|
5089
|
+
}
|
|
5090
|
+
var init_data_path = () => {};
|
|
5091
|
+
|
|
5092
|
+
// src/shared/config-errors.ts
|
|
5093
|
+
function getConfigLoadErrors() {
|
|
5094
|
+
return configLoadErrors;
|
|
5095
|
+
}
|
|
5096
|
+
function clearConfigLoadErrors() {
|
|
5097
|
+
configLoadErrors = [];
|
|
5098
|
+
}
|
|
5099
|
+
function addConfigLoadError(error) {
|
|
5100
|
+
configLoadErrors.push(error);
|
|
5101
|
+
}
|
|
5102
|
+
var configLoadErrors;
|
|
5103
|
+
var init_config_errors = __esm(() => {
|
|
5104
|
+
configLoadErrors = [];
|
|
5105
|
+
});
|
|
5106
|
+
|
|
5107
|
+
// src/shared/claude-config-dir.ts
|
|
5108
|
+
var init_claude_config_dir = () => {};
|
|
5109
|
+
|
|
4920
5110
|
// node_modules/jsonc-parser/lib/esm/impl/scanner.js
|
|
4921
5111
|
function createScanner(text, ignoreTrivia = false) {
|
|
4922
5112
|
const len = text.length;
|
|
@@ -5781,11 +5971,37 @@ var init_main = __esm(() => {
|
|
|
5781
5971
|
})(ParseErrorCode || (ParseErrorCode = {}));
|
|
5782
5972
|
});
|
|
5783
5973
|
|
|
5974
|
+
// src/shared/plugin-identity.ts
|
|
5975
|
+
import { join as join3 } from "path";
|
|
5976
|
+
function detectManagedConfigFile(directory) {
|
|
5977
|
+
for (const baseName of ALL_CONFIG_BASENAMES) {
|
|
5978
|
+
const detected = detectConfigFile(join3(directory, baseName));
|
|
5979
|
+
if (detected.format !== "none") {
|
|
5980
|
+
return { ...detected, baseName };
|
|
5981
|
+
}
|
|
5982
|
+
}
|
|
5983
|
+
return {
|
|
5984
|
+
format: "none",
|
|
5985
|
+
path: join3(directory, `${CONFIG_BASENAME}.json`),
|
|
5986
|
+
baseName: CONFIG_BASENAME
|
|
5987
|
+
};
|
|
5988
|
+
}
|
|
5989
|
+
var PLUGIN_NAME = "evil-omo", LEGACY_PLUGIN_NAME = "oh-my-opencode", CONFIG_BASENAME = "evil-omo", LEGACY_CONFIG_BASENAME = "oh-my-opencode", ALL_CONFIG_BASENAMES;
|
|
5990
|
+
var init_plugin_identity = __esm(() => {
|
|
5991
|
+
init_jsonc_parser();
|
|
5992
|
+
ALL_CONFIG_BASENAMES = [CONFIG_BASENAME, LEGACY_CONFIG_BASENAME];
|
|
5993
|
+
});
|
|
5994
|
+
|
|
5784
5995
|
// src/shared/jsonc-parser.ts
|
|
5785
5996
|
import { existsSync, readFileSync } from "fs";
|
|
5997
|
+
import { join as join4 } from "path";
|
|
5998
|
+
function stripBom(content) {
|
|
5999
|
+
return content.charCodeAt(0) === 65279 ? content.slice(1) : content;
|
|
6000
|
+
}
|
|
5786
6001
|
function parseJsonc(content) {
|
|
6002
|
+
content = content.replace(/^\uFEFF/, "");
|
|
5787
6003
|
const errors = [];
|
|
5788
|
-
const result = parse2(content, errors, {
|
|
6004
|
+
const result = parse2(stripBom(content), errors, {
|
|
5789
6005
|
allowTrailingComma: true,
|
|
5790
6006
|
disallowComments: false
|
|
5791
6007
|
});
|
|
@@ -5806,202 +6022,25 @@ function detectConfigFile(basePath) {
|
|
|
5806
6022
|
}
|
|
5807
6023
|
return { format: "none", path: jsonPath };
|
|
5808
6024
|
}
|
|
5809
|
-
|
|
5810
|
-
|
|
5811
|
-
|
|
5812
|
-
|
|
5813
|
-
|
|
5814
|
-
|
|
5815
|
-
|
|
5816
|
-
|
|
5817
|
-
return entry === packageName || entry.startsWith(`${packageName}@`);
|
|
5818
|
-
}
|
|
5819
|
-
function findManagedPluginEntry(plugins) {
|
|
5820
|
-
for (const [index, entry] of plugins.entries()) {
|
|
5821
|
-
for (const packageName of ALL_PLUGIN_NAMES) {
|
|
5822
|
-
if (matchesManagedName(entry, packageName)) {
|
|
5823
|
-
return { index, packageName };
|
|
5824
|
-
}
|
|
5825
|
-
}
|
|
5826
|
-
}
|
|
5827
|
-
return null;
|
|
5828
|
-
}
|
|
5829
|
-
function detectManagedConfigFile(directory) {
|
|
5830
|
-
for (const baseName of ALL_CONFIG_BASENAMES) {
|
|
5831
|
-
const detected = detectConfigFile(join(directory, baseName));
|
|
5832
|
-
if (detected.format !== "none") {
|
|
5833
|
-
return { ...detected, baseName };
|
|
5834
|
-
}
|
|
5835
|
-
}
|
|
5836
|
-
return {
|
|
5837
|
-
format: "none",
|
|
5838
|
-
path: join(directory, `${CONFIG_BASENAME}.json`),
|
|
5839
|
-
baseName: CONFIG_BASENAME
|
|
5840
|
-
};
|
|
5841
|
-
}
|
|
5842
|
-
var PLUGIN_NAME = "evil-omo", LEGACY_PLUGIN_NAME = "oh-my-opencode", ALL_PLUGIN_NAMES, CONFIG_BASENAME = "evil-omo", LEGACY_CONFIG_BASENAME = "oh-my-opencode", ALL_CONFIG_BASENAMES, LOG_FILENAME = "evil-omo.log", CACHE_DIR_NAME = "evil-omo", SCHEMA_FILENAME = "evil-omo.schema.json";
|
|
5843
|
-
var init_plugin_identity = __esm(() => {
|
|
5844
|
-
init_jsonc_parser();
|
|
5845
|
-
ALL_PLUGIN_NAMES = [PLUGIN_NAME, LEGACY_PLUGIN_NAME];
|
|
5846
|
-
ALL_CONFIG_BASENAMES = [CONFIG_BASENAME, LEGACY_CONFIG_BASENAME];
|
|
5847
|
-
});
|
|
5848
|
-
|
|
5849
|
-
// src/shared/logger.ts
|
|
5850
|
-
import * as fs from "fs";
|
|
5851
|
-
import * as os from "os";
|
|
5852
|
-
import * as path from "path";
|
|
5853
|
-
function log(message, data) {
|
|
5854
|
-
try {
|
|
5855
|
-
const timestamp2 = new Date().toISOString();
|
|
5856
|
-
const logEntry = `[${timestamp2}] ${message} ${data ? JSON.stringify(data) : ""}
|
|
5857
|
-
`;
|
|
5858
|
-
fs.appendFileSync(logFile, logEntry);
|
|
5859
|
-
} catch {}
|
|
5860
|
-
}
|
|
5861
|
-
var logFile;
|
|
5862
|
-
var init_logger = __esm(() => {
|
|
5863
|
-
init_plugin_identity();
|
|
5864
|
-
logFile = path.join(os.tmpdir(), LOG_FILENAME);
|
|
5865
|
-
});
|
|
5866
|
-
|
|
5867
|
-
// src/shared/file-reference-resolver.ts
|
|
5868
|
-
var init_file_reference_resolver = __esm(() => {
|
|
5869
|
-
init_contains_path();
|
|
5870
|
-
init_logger();
|
|
5871
|
-
});
|
|
5872
|
-
// src/shared/deep-merge.ts
|
|
5873
|
-
function isPlainObject(value) {
|
|
5874
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.prototype.toString.call(value) === "[object Object]";
|
|
5875
|
-
}
|
|
5876
|
-
function deepMerge(base, override, depth = 0) {
|
|
5877
|
-
if (!base && !override)
|
|
5878
|
-
return;
|
|
5879
|
-
if (!base)
|
|
5880
|
-
return override;
|
|
5881
|
-
if (!override)
|
|
5882
|
-
return base;
|
|
5883
|
-
if (depth > MAX_DEPTH)
|
|
5884
|
-
return override ?? base;
|
|
5885
|
-
const result = { ...base };
|
|
5886
|
-
for (const key of Object.keys(override)) {
|
|
5887
|
-
if (DANGEROUS_KEYS.has(key))
|
|
5888
|
-
continue;
|
|
5889
|
-
const baseValue = base[key];
|
|
5890
|
-
const overrideValue = override[key];
|
|
5891
|
-
if (overrideValue === undefined)
|
|
5892
|
-
continue;
|
|
5893
|
-
if (isPlainObject(baseValue) && isPlainObject(overrideValue)) {
|
|
5894
|
-
result[key] = deepMerge(baseValue, overrideValue, depth + 1);
|
|
5895
|
-
} else {
|
|
5896
|
-
result[key] = overrideValue;
|
|
5897
|
-
}
|
|
5898
|
-
}
|
|
5899
|
-
return result;
|
|
5900
|
-
}
|
|
5901
|
-
var DANGEROUS_KEYS, MAX_DEPTH = 50;
|
|
5902
|
-
var init_deep_merge = __esm(() => {
|
|
5903
|
-
DANGEROUS_KEYS = new Set(["__proto__", "constructor", "prototype"]);
|
|
5904
|
-
});
|
|
5905
|
-
|
|
5906
|
-
// src/shared/snake-case.ts
|
|
5907
|
-
var init_snake_case = __esm(() => {
|
|
5908
|
-
init_deep_merge();
|
|
5909
|
-
});
|
|
5910
|
-
|
|
5911
|
-
// src/shared/tool-name.ts
|
|
5912
|
-
var init_tool_name = () => {};
|
|
5913
|
-
|
|
5914
|
-
// src/shared/pattern-matcher.ts
|
|
5915
|
-
var regexCache;
|
|
5916
|
-
var init_pattern_matcher = __esm(() => {
|
|
5917
|
-
regexCache = new Map;
|
|
5918
|
-
});
|
|
5919
|
-
// src/shared/file-utils.ts
|
|
5920
|
-
import { lstatSync, realpathSync } from "fs";
|
|
5921
|
-
function normalizeDarwinRealpath(filePath) {
|
|
5922
|
-
return filePath.startsWith("/private/var/") ? filePath.slice("/private".length) : filePath;
|
|
5923
|
-
}
|
|
5924
|
-
function resolveSymlink(filePath) {
|
|
5925
|
-
try {
|
|
5926
|
-
return normalizeDarwinRealpath(realpathSync(filePath));
|
|
5927
|
-
} catch {
|
|
5928
|
-
return filePath;
|
|
5929
|
-
}
|
|
5930
|
-
}
|
|
5931
|
-
var init_file_utils = () => {};
|
|
5932
|
-
|
|
5933
|
-
// src/shared/context-limit-resolver.ts
|
|
5934
|
-
var init_context_limit_resolver = () => {};
|
|
5935
|
-
|
|
5936
|
-
// src/shared/normalize-sdk-response.ts
|
|
5937
|
-
function normalizeSDKResponse(response, fallback, options) {
|
|
5938
|
-
if (response === null || response === undefined) {
|
|
5939
|
-
return fallback;
|
|
5940
|
-
}
|
|
5941
|
-
if (Array.isArray(response)) {
|
|
5942
|
-
return response;
|
|
6025
|
+
function detectPluginConfigFile(dir) {
|
|
6026
|
+
const canonicalResult = detectConfigFile(join4(dir, CONFIG_BASENAME));
|
|
6027
|
+
const legacyResult = detectConfigFile(join4(dir, LEGACY_CONFIG_BASENAME));
|
|
6028
|
+
if (canonicalResult.format !== "none") {
|
|
6029
|
+
return {
|
|
6030
|
+
...canonicalResult,
|
|
6031
|
+
legacyPath: legacyResult.format !== "none" ? legacyResult.path : undefined
|
|
6032
|
+
};
|
|
5943
6033
|
}
|
|
5944
|
-
if (
|
|
5945
|
-
|
|
5946
|
-
if (data !== null && data !== undefined) {
|
|
5947
|
-
return data;
|
|
5948
|
-
}
|
|
5949
|
-
if (options?.preferResponseOnMissingData === true) {
|
|
5950
|
-
return response;
|
|
5951
|
-
}
|
|
5952
|
-
return fallback;
|
|
6034
|
+
if (legacyResult.format !== "none") {
|
|
6035
|
+
return legacyResult;
|
|
5953
6036
|
}
|
|
5954
|
-
|
|
5955
|
-
return response;
|
|
5956
|
-
}
|
|
5957
|
-
return fallback;
|
|
5958
|
-
}
|
|
5959
|
-
|
|
5960
|
-
// src/shared/dynamic-truncator.ts
|
|
5961
|
-
var init_dynamic_truncator = __esm(() => {
|
|
5962
|
-
init_context_limit_resolver();
|
|
5963
|
-
});
|
|
5964
|
-
|
|
5965
|
-
// src/shared/data-path.ts
|
|
5966
|
-
import * as path2 from "path";
|
|
5967
|
-
import * as os2 from "os";
|
|
5968
|
-
function getDataDir() {
|
|
5969
|
-
return process.env.XDG_DATA_HOME ?? path2.join(os2.homedir(), ".local", "share");
|
|
5970
|
-
}
|
|
5971
|
-
function getOpenCodeStorageDir() {
|
|
5972
|
-
return path2.join(getDataDir(), "opencode", "storage");
|
|
5973
|
-
}
|
|
5974
|
-
function getCacheDir() {
|
|
5975
|
-
return process.env.XDG_CACHE_HOME ?? path2.join(os2.homedir(), ".cache");
|
|
5976
|
-
}
|
|
5977
|
-
function getOmoOpenCodeCacheDir() {
|
|
5978
|
-
return path2.join(getCacheDir(), CACHE_DIR_NAME);
|
|
5979
|
-
}
|
|
5980
|
-
function getOpenCodeCacheDir() {
|
|
5981
|
-
return path2.join(getCacheDir(), "opencode");
|
|
6037
|
+
return { format: "none", path: join4(dir, `${CONFIG_BASENAME}.json`) };
|
|
5982
6038
|
}
|
|
5983
|
-
var
|
|
6039
|
+
var init_jsonc_parser = __esm(() => {
|
|
6040
|
+
init_main();
|
|
5984
6041
|
init_plugin_identity();
|
|
5985
6042
|
});
|
|
5986
6043
|
|
|
5987
|
-
// src/shared/config-errors.ts
|
|
5988
|
-
function getConfigLoadErrors() {
|
|
5989
|
-
return configLoadErrors;
|
|
5990
|
-
}
|
|
5991
|
-
function clearConfigLoadErrors() {
|
|
5992
|
-
configLoadErrors = [];
|
|
5993
|
-
}
|
|
5994
|
-
function addConfigLoadError(error) {
|
|
5995
|
-
configLoadErrors.push(error);
|
|
5996
|
-
}
|
|
5997
|
-
var configLoadErrors;
|
|
5998
|
-
var init_config_errors = __esm(() => {
|
|
5999
|
-
configLoadErrors = [];
|
|
6000
|
-
});
|
|
6001
|
-
|
|
6002
|
-
// src/shared/claude-config-dir.ts
|
|
6003
|
-
var init_claude_config_dir = () => {};
|
|
6004
|
-
|
|
6005
6044
|
// src/shared/migration/agent-names.ts
|
|
6006
6045
|
function migrateAgentNames(agents) {
|
|
6007
6046
|
const migrated = {};
|
|
@@ -6026,15 +6065,15 @@ var init_agent_names = __esm(() => {
|
|
|
6026
6065
|
"omo-plan": "prometheus",
|
|
6027
6066
|
"Planner-Sisyphus": "prometheus",
|
|
6028
6067
|
"planner-sisyphus": "prometheus",
|
|
6029
|
-
"Prometheus
|
|
6068
|
+
"Prometheus - Plan Builder": "prometheus",
|
|
6030
6069
|
prometheus: "prometheus",
|
|
6031
6070
|
"orchestrator-sisyphus": "atlas",
|
|
6032
6071
|
Atlas: "atlas",
|
|
6033
6072
|
atlas: "atlas",
|
|
6034
6073
|
"plan-consultant": "metis",
|
|
6035
|
-
"Metis
|
|
6074
|
+
"Metis - Plan Consultant": "metis",
|
|
6036
6075
|
metis: "metis",
|
|
6037
|
-
"Momus
|
|
6076
|
+
"Momus - Plan Critic": "momus",
|
|
6038
6077
|
momus: "momus",
|
|
6039
6078
|
"Sisyphus-Junior": "sisyphus-junior",
|
|
6040
6079
|
"sisyphus-junior": "sisyphus-junior",
|
|
@@ -6277,9 +6316,9 @@ var init_migration = __esm(() => {
|
|
|
6277
6316
|
});
|
|
6278
6317
|
|
|
6279
6318
|
// src/shared/opencode-config-dir.ts
|
|
6280
|
-
import { existsSync as existsSync2 } from "fs";
|
|
6319
|
+
import { existsSync as existsSync2, realpathSync as realpathSync2 } from "fs";
|
|
6281
6320
|
import { homedir as homedir2 } from "os";
|
|
6282
|
-
import { join as
|
|
6321
|
+
import { join as join5, resolve, win32 } from "path";
|
|
6283
6322
|
function isDevBuild(version) {
|
|
6284
6323
|
if (!version)
|
|
6285
6324
|
return false;
|
|
@@ -6289,25 +6328,35 @@ function getTauriConfigDir(identifier) {
|
|
|
6289
6328
|
const platform = process.platform;
|
|
6290
6329
|
switch (platform) {
|
|
6291
6330
|
case "darwin":
|
|
6292
|
-
return
|
|
6331
|
+
return join5(homedir2(), "Library", "Application Support", identifier);
|
|
6293
6332
|
case "win32": {
|
|
6294
|
-
const appData = process.env.APPDATA ||
|
|
6295
|
-
return
|
|
6333
|
+
const appData = process.env.APPDATA || join5(homedir2(), "AppData", "Roaming");
|
|
6334
|
+
return win32.join(appData, identifier);
|
|
6296
6335
|
}
|
|
6297
6336
|
case "linux":
|
|
6298
6337
|
default: {
|
|
6299
|
-
const xdgConfig = process.env.XDG_CONFIG_HOME ||
|
|
6300
|
-
return
|
|
6338
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME || join5(homedir2(), ".config");
|
|
6339
|
+
return join5(xdgConfig, identifier);
|
|
6301
6340
|
}
|
|
6302
6341
|
}
|
|
6303
6342
|
}
|
|
6343
|
+
function resolveConfigPath(pathValue) {
|
|
6344
|
+
const resolvedPath = resolve(pathValue);
|
|
6345
|
+
if (!existsSync2(resolvedPath))
|
|
6346
|
+
return resolvedPath;
|
|
6347
|
+
try {
|
|
6348
|
+
return realpathSync2(resolvedPath);
|
|
6349
|
+
} catch {
|
|
6350
|
+
return resolvedPath;
|
|
6351
|
+
}
|
|
6352
|
+
}
|
|
6304
6353
|
function getCliConfigDir() {
|
|
6305
6354
|
const envConfigDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
6306
6355
|
if (envConfigDir) {
|
|
6307
|
-
return
|
|
6356
|
+
return resolveConfigPath(envConfigDir);
|
|
6308
6357
|
}
|
|
6309
|
-
const xdgConfig = process.env.XDG_CONFIG_HOME ||
|
|
6310
|
-
return
|
|
6358
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME || join5(homedir2(), ".config");
|
|
6359
|
+
return resolveConfigPath(join5(xdgConfig, "opencode"));
|
|
6311
6360
|
}
|
|
6312
6361
|
function getOpenCodeConfigDir(options) {
|
|
6313
6362
|
const { binary: binary2, version, checkExisting = true } = options;
|
|
@@ -6315,11 +6364,12 @@ function getOpenCodeConfigDir(options) {
|
|
|
6315
6364
|
return getCliConfigDir();
|
|
6316
6365
|
}
|
|
6317
6366
|
const identifier = isDevBuild(version) ? TAURI_APP_IDENTIFIER_DEV : TAURI_APP_IDENTIFIER;
|
|
6318
|
-
const
|
|
6367
|
+
const tauriDirBase = getTauriConfigDir(identifier);
|
|
6368
|
+
const tauriDir = process.platform === "win32" ? win32.isAbsolute(tauriDirBase) ? win32.normalize(tauriDirBase) : win32.resolve(tauriDirBase) : resolveConfigPath(tauriDirBase);
|
|
6319
6369
|
if (checkExisting) {
|
|
6320
6370
|
const legacyDir = getCliConfigDir();
|
|
6321
|
-
const legacyConfig =
|
|
6322
|
-
const legacyConfigC =
|
|
6371
|
+
const legacyConfig = join5(legacyDir, "opencode.json");
|
|
6372
|
+
const legacyConfigC = join5(legacyDir, "opencode.jsonc");
|
|
6323
6373
|
if (existsSync2(legacyConfig) || existsSync2(legacyConfigC)) {
|
|
6324
6374
|
return legacyDir;
|
|
6325
6375
|
}
|
|
@@ -6330,10 +6380,10 @@ function getOpenCodeConfigPaths(options) {
|
|
|
6330
6380
|
const configDir = getOpenCodeConfigDir(options);
|
|
6331
6381
|
return {
|
|
6332
6382
|
configDir,
|
|
6333
|
-
configJson:
|
|
6334
|
-
configJsonc:
|
|
6335
|
-
packageJson:
|
|
6336
|
-
omoConfig:
|
|
6383
|
+
configJson: join5(configDir, "opencode.json"),
|
|
6384
|
+
configJsonc: join5(configDir, "opencode.jsonc"),
|
|
6385
|
+
packageJson: join5(configDir, "package.json"),
|
|
6386
|
+
omoConfig: join5(configDir, `${CONFIG_BASENAME}.json`)
|
|
6337
6387
|
};
|
|
6338
6388
|
}
|
|
6339
6389
|
var TAURI_APP_IDENTIFIER = "ai.opencode.desktop", TAURI_APP_IDENTIFIER_DEV = "ai.opencode.desktop.dev";
|
|
@@ -6342,18 +6392,88 @@ var init_opencode_config_dir = __esm(() => {
|
|
|
6342
6392
|
});
|
|
6343
6393
|
|
|
6344
6394
|
// src/shared/opencode-version.ts
|
|
6345
|
-
|
|
6395
|
+
import { execSync } from "child_process";
|
|
6396
|
+
function parseVersion(version) {
|
|
6397
|
+
const cleaned = version.replace(/^v/, "").split("-")[0];
|
|
6398
|
+
return cleaned.split(".").map((n) => parseInt(n, 10) || 0);
|
|
6399
|
+
}
|
|
6400
|
+
function compareVersions(a, b) {
|
|
6401
|
+
const partsA = parseVersion(a);
|
|
6402
|
+
const partsB = parseVersion(b);
|
|
6403
|
+
const maxLen = Math.max(partsA.length, partsB.length);
|
|
6404
|
+
for (let i2 = 0;i2 < maxLen; i2++) {
|
|
6405
|
+
const numA = partsA[i2] ?? 0;
|
|
6406
|
+
const numB = partsB[i2] ?? 0;
|
|
6407
|
+
if (numA < numB)
|
|
6408
|
+
return -1;
|
|
6409
|
+
if (numA > numB)
|
|
6410
|
+
return 1;
|
|
6411
|
+
}
|
|
6412
|
+
return 0;
|
|
6413
|
+
}
|
|
6414
|
+
function getOpenCodeVersion() {
|
|
6415
|
+
if (cachedVersion !== NOT_CACHED) {
|
|
6416
|
+
return cachedVersion;
|
|
6417
|
+
}
|
|
6418
|
+
try {
|
|
6419
|
+
const result = execSync("opencode --version", {
|
|
6420
|
+
encoding: "utf-8",
|
|
6421
|
+
timeout: 5000,
|
|
6422
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
6423
|
+
}).trim();
|
|
6424
|
+
const versionMatch = result.match(/(\d+\.\d+\.\d+(?:-[\w.]+)?)/);
|
|
6425
|
+
cachedVersion = versionMatch?.[1] ?? null;
|
|
6426
|
+
return cachedVersion;
|
|
6427
|
+
} catch {
|
|
6428
|
+
cachedVersion = null;
|
|
6429
|
+
return null;
|
|
6430
|
+
}
|
|
6431
|
+
}
|
|
6432
|
+
function isOpenCodeVersionAtLeast(version) {
|
|
6433
|
+
const current = getOpenCodeVersion();
|
|
6434
|
+
if (!current)
|
|
6435
|
+
return true;
|
|
6436
|
+
return compareVersions(current, version) >= 0;
|
|
6437
|
+
}
|
|
6438
|
+
var OPENCODE_SQLITE_VERSION = "1.1.53", NOT_CACHED, cachedVersion;
|
|
6346
6439
|
var init_opencode_version = __esm(() => {
|
|
6347
6440
|
NOT_CACHED = Symbol("NOT_CACHED");
|
|
6441
|
+
cachedVersion = NOT_CACHED;
|
|
6348
6442
|
});
|
|
6349
6443
|
|
|
6350
6444
|
// src/shared/opencode-storage-detection.ts
|
|
6351
|
-
|
|
6445
|
+
import { existsSync as existsSync3 } from "fs";
|
|
6446
|
+
import { join as join6 } from "path";
|
|
6447
|
+
function isSqliteBackend() {
|
|
6448
|
+
if (cachedResult === true)
|
|
6449
|
+
return true;
|
|
6450
|
+
if (cachedResult === false)
|
|
6451
|
+
return false;
|
|
6452
|
+
const check = () => {
|
|
6453
|
+
const versionOk = isOpenCodeVersionAtLeast(OPENCODE_SQLITE_VERSION);
|
|
6454
|
+
const dbPath = join6(getDataDir(), "opencode", "opencode.db");
|
|
6455
|
+
return versionOk && existsSync3(dbPath);
|
|
6456
|
+
};
|
|
6457
|
+
if (cachedResult === FALSE_PENDING_RETRY) {
|
|
6458
|
+
const result2 = check();
|
|
6459
|
+
cachedResult = result2;
|
|
6460
|
+
return result2;
|
|
6461
|
+
}
|
|
6462
|
+
const result = check();
|
|
6463
|
+
if (result) {
|
|
6464
|
+
cachedResult = true;
|
|
6465
|
+
} else {
|
|
6466
|
+
cachedResult = FALSE_PENDING_RETRY;
|
|
6467
|
+
}
|
|
6468
|
+
return result;
|
|
6469
|
+
}
|
|
6470
|
+
var NOT_CACHED2, FALSE_PENDING_RETRY, cachedResult;
|
|
6352
6471
|
var init_opencode_storage_detection = __esm(() => {
|
|
6353
6472
|
init_data_path();
|
|
6354
6473
|
init_opencode_version();
|
|
6355
6474
|
NOT_CACHED2 = Symbol("NOT_CACHED");
|
|
6356
6475
|
FALSE_PENDING_RETRY = Symbol("FALSE_PENDING_RETRY");
|
|
6476
|
+
cachedResult = NOT_CACHED2;
|
|
6357
6477
|
});
|
|
6358
6478
|
// src/shared/external-plugin-detector.ts
|
|
6359
6479
|
var init_external_plugin_detector = __esm(() => {
|
|
@@ -6764,20 +6884,20 @@ function normalizeModelID(modelID) {
|
|
|
6764
6884
|
}
|
|
6765
6885
|
|
|
6766
6886
|
// src/shared/json-file-cache-store.ts
|
|
6767
|
-
import { existsSync as
|
|
6768
|
-
import { join as
|
|
6887
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
6888
|
+
import { join as join7 } from "path";
|
|
6769
6889
|
function toLogLabel(cacheLabel) {
|
|
6770
6890
|
return cacheLabel.toLowerCase();
|
|
6771
6891
|
}
|
|
6772
6892
|
function createJsonFileCacheStore(options) {
|
|
6773
6893
|
let memoryValue;
|
|
6774
6894
|
function getCacheFilePath() {
|
|
6775
|
-
return
|
|
6895
|
+
return join7(options.getCacheDir(), options.filename);
|
|
6776
6896
|
}
|
|
6777
6897
|
function ensureCacheDir() {
|
|
6778
6898
|
const cacheDir = options.getCacheDir();
|
|
6779
|
-
if (!
|
|
6780
|
-
|
|
6899
|
+
if (!existsSync4(cacheDir)) {
|
|
6900
|
+
mkdirSync2(cacheDir, { recursive: true });
|
|
6781
6901
|
}
|
|
6782
6902
|
}
|
|
6783
6903
|
function read() {
|
|
@@ -6785,7 +6905,7 @@ function createJsonFileCacheStore(options) {
|
|
|
6785
6905
|
return memoryValue;
|
|
6786
6906
|
}
|
|
6787
6907
|
const cacheFile = getCacheFilePath();
|
|
6788
|
-
if (!
|
|
6908
|
+
if (!existsSync4(cacheFile)) {
|
|
6789
6909
|
memoryValue = null;
|
|
6790
6910
|
log(`[${options.logPrefix}] ${options.cacheLabel} file not found`, { cacheFile });
|
|
6791
6911
|
return null;
|
|
@@ -6805,7 +6925,7 @@ function createJsonFileCacheStore(options) {
|
|
|
6805
6925
|
}
|
|
6806
6926
|
}
|
|
6807
6927
|
function has() {
|
|
6808
|
-
return
|
|
6928
|
+
return existsSync4(getCacheFilePath());
|
|
6809
6929
|
}
|
|
6810
6930
|
function write(value) {
|
|
6811
6931
|
ensureCacheDir();
|
|
@@ -6974,14 +7094,14 @@ var init_connected_providers_cache = __esm(() => {
|
|
|
6974
7094
|
});
|
|
6975
7095
|
|
|
6976
7096
|
// src/shared/model-availability.ts
|
|
6977
|
-
import { existsSync as
|
|
6978
|
-
import { join as
|
|
7097
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3 } from "fs";
|
|
7098
|
+
import { join as join8 } from "path";
|
|
6979
7099
|
function isModelCacheAvailable() {
|
|
6980
7100
|
if (hasProviderModelsCache()) {
|
|
6981
7101
|
return true;
|
|
6982
7102
|
}
|
|
6983
|
-
const cacheFile =
|
|
6984
|
-
return
|
|
7103
|
+
const cacheFile = join8(getOpenCodeCacheDir(), "models.json");
|
|
7104
|
+
return existsSync5(cacheFile);
|
|
6985
7105
|
}
|
|
6986
7106
|
var init_model_availability = __esm(() => {
|
|
6987
7107
|
init_logger();
|
|
@@ -48276,6 +48396,57 @@ var init_constants = __esm(() => {
|
|
|
48276
48396
|
init_shared();
|
|
48277
48397
|
});
|
|
48278
48398
|
|
|
48399
|
+
// src/shared/opencode-storage-paths.ts
|
|
48400
|
+
import { join as join9 } from "path";
|
|
48401
|
+
var OPENCODE_STORAGE, MESSAGE_STORAGE, PART_STORAGE, SESSION_STORAGE;
|
|
48402
|
+
var init_opencode_storage_paths = __esm(() => {
|
|
48403
|
+
init_data_path();
|
|
48404
|
+
OPENCODE_STORAGE = getOpenCodeStorageDir();
|
|
48405
|
+
MESSAGE_STORAGE = join9(OPENCODE_STORAGE, "message");
|
|
48406
|
+
PART_STORAGE = join9(OPENCODE_STORAGE, "part");
|
|
48407
|
+
SESSION_STORAGE = join9(OPENCODE_STORAGE, "session");
|
|
48408
|
+
});
|
|
48409
|
+
|
|
48410
|
+
// src/shared/compaction-marker.ts
|
|
48411
|
+
import { existsSync as existsSync6, readdirSync, readFileSync as readFileSync4 } from "fs";
|
|
48412
|
+
import { join as join10 } from "path";
|
|
48413
|
+
function isCompactionPart(part) {
|
|
48414
|
+
return typeof part === "object" && part !== null && part.type === "compaction";
|
|
48415
|
+
}
|
|
48416
|
+
function isCompactionAgent(agent) {
|
|
48417
|
+
return typeof agent === "string" && agent.trim().toLowerCase() === "compaction";
|
|
48418
|
+
}
|
|
48419
|
+
function hasCompactionPart(parts) {
|
|
48420
|
+
return Array.isArray(parts) && parts.some((part) => isCompactionPart(part));
|
|
48421
|
+
}
|
|
48422
|
+
function isCompactionMessage(message) {
|
|
48423
|
+
return isCompactionAgent(message.info?.agent ?? message.agent) || hasCompactionPart(message.parts);
|
|
48424
|
+
}
|
|
48425
|
+
function hasCompactionPartInStorage(messageID) {
|
|
48426
|
+
if (!messageID) {
|
|
48427
|
+
return false;
|
|
48428
|
+
}
|
|
48429
|
+
const partDir = join10(PART_STORAGE, messageID);
|
|
48430
|
+
if (!existsSync6(partDir)) {
|
|
48431
|
+
return false;
|
|
48432
|
+
}
|
|
48433
|
+
try {
|
|
48434
|
+
return readdirSync(partDir).filter((fileName) => fileName.endsWith(".json")).some((fileName) => {
|
|
48435
|
+
try {
|
|
48436
|
+
const content = readFileSync4(join10(partDir, fileName), "utf-8");
|
|
48437
|
+
return isCompactionPart(JSON.parse(content));
|
|
48438
|
+
} catch {
|
|
48439
|
+
return false;
|
|
48440
|
+
}
|
|
48441
|
+
});
|
|
48442
|
+
} catch {
|
|
48443
|
+
return false;
|
|
48444
|
+
}
|
|
48445
|
+
}
|
|
48446
|
+
var init_compaction_marker = __esm(() => {
|
|
48447
|
+
init_opencode_storage_paths();
|
|
48448
|
+
});
|
|
48449
|
+
|
|
48279
48450
|
// src/features/hook-message-injector/injector.ts
|
|
48280
48451
|
import { randomBytes } from "crypto";
|
|
48281
48452
|
var processPrefix;
|
|
@@ -48284,6 +48455,7 @@ var init_injector = __esm(() => {
|
|
|
48284
48455
|
init_logger();
|
|
48285
48456
|
init_opencode_storage_detection();
|
|
48286
48457
|
init_shared();
|
|
48458
|
+
init_compaction_marker();
|
|
48287
48459
|
processPrefix = randomBytes(4).toString("hex");
|
|
48288
48460
|
});
|
|
48289
48461
|
|
|
@@ -48293,18 +48465,33 @@ var init_hook_message_injector = __esm(() => {
|
|
|
48293
48465
|
init_constants();
|
|
48294
48466
|
});
|
|
48295
48467
|
|
|
48296
|
-
// src/shared/opencode-storage-paths.ts
|
|
48297
|
-
import { join as join7 } from "path";
|
|
48298
|
-
var OPENCODE_STORAGE, MESSAGE_STORAGE, PART_STORAGE, SESSION_STORAGE;
|
|
48299
|
-
var init_opencode_storage_paths = __esm(() => {
|
|
48300
|
-
init_data_path();
|
|
48301
|
-
OPENCODE_STORAGE = getOpenCodeStorageDir();
|
|
48302
|
-
MESSAGE_STORAGE = join7(OPENCODE_STORAGE, "message");
|
|
48303
|
-
PART_STORAGE = join7(OPENCODE_STORAGE, "part");
|
|
48304
|
-
SESSION_STORAGE = join7(OPENCODE_STORAGE, "session");
|
|
48305
|
-
});
|
|
48306
|
-
|
|
48307
48468
|
// src/shared/opencode-message-dir.ts
|
|
48469
|
+
import { existsSync as existsSync7, readdirSync as readdirSync2 } from "fs";
|
|
48470
|
+
import { join as join11 } from "path";
|
|
48471
|
+
function getMessageDir(sessionID) {
|
|
48472
|
+
if (!sessionID.startsWith("ses_"))
|
|
48473
|
+
return null;
|
|
48474
|
+
if (/[/\\]|\.\./.test(sessionID))
|
|
48475
|
+
return null;
|
|
48476
|
+
if (!existsSync7(MESSAGE_STORAGE))
|
|
48477
|
+
return null;
|
|
48478
|
+
const directPath = join11(MESSAGE_STORAGE, sessionID);
|
|
48479
|
+
if (existsSync7(directPath)) {
|
|
48480
|
+
return directPath;
|
|
48481
|
+
}
|
|
48482
|
+
try {
|
|
48483
|
+
for (const dir of readdirSync2(MESSAGE_STORAGE)) {
|
|
48484
|
+
const sessionPath = join11(MESSAGE_STORAGE, dir, sessionID);
|
|
48485
|
+
if (existsSync7(sessionPath)) {
|
|
48486
|
+
return sessionPath;
|
|
48487
|
+
}
|
|
48488
|
+
}
|
|
48489
|
+
} catch (error) {
|
|
48490
|
+
log("[opencode-message-dir] Failed to scan message directories", { sessionID, error: String(error) });
|
|
48491
|
+
return null;
|
|
48492
|
+
}
|
|
48493
|
+
return null;
|
|
48494
|
+
}
|
|
48308
48495
|
var init_opencode_message_dir = __esm(() => {
|
|
48309
48496
|
init_opencode_storage_paths();
|
|
48310
48497
|
init_logger();
|
|
@@ -48330,22 +48517,25 @@ function getAgentConfigKey(agentName) {
|
|
|
48330
48517
|
const reversed = REVERSE_DISPLAY_NAMES[lower];
|
|
48331
48518
|
if (reversed !== undefined)
|
|
48332
48519
|
return reversed;
|
|
48520
|
+
const legacy = LEGACY_DISPLAY_NAMES[lower];
|
|
48521
|
+
if (legacy !== undefined)
|
|
48522
|
+
return legacy;
|
|
48333
48523
|
if (AGENT_DISPLAY_NAMES[lower] !== undefined)
|
|
48334
48524
|
return lower;
|
|
48335
48525
|
return lower;
|
|
48336
48526
|
}
|
|
48337
|
-
var AGENT_DISPLAY_NAMES, REVERSE_DISPLAY_NAMES;
|
|
48527
|
+
var AGENT_DISPLAY_NAMES, REVERSE_DISPLAY_NAMES, LEGACY_DISPLAY_NAMES;
|
|
48338
48528
|
var init_agent_display_names = __esm(() => {
|
|
48339
48529
|
AGENT_DISPLAY_NAMES = {
|
|
48340
|
-
sisyphus: "Sisyphus
|
|
48341
|
-
hephaestus: "Hephaestus
|
|
48342
|
-
prometheus: "Prometheus
|
|
48343
|
-
atlas: "Atlas
|
|
48530
|
+
sisyphus: "Sisyphus - Ultraworker",
|
|
48531
|
+
hephaestus: "Hephaestus - Deep Agent",
|
|
48532
|
+
prometheus: "Prometheus - Plan Builder",
|
|
48533
|
+
atlas: "Atlas - Plan Executor",
|
|
48344
48534
|
"sisyphus-junior": "Sisyphus-Junior",
|
|
48345
|
-
metis: "Metis
|
|
48346
|
-
momus: "Momus
|
|
48347
|
-
athena: "Athena
|
|
48348
|
-
"athena-junior": "Athena-Junior
|
|
48535
|
+
metis: "Metis - Plan Consultant",
|
|
48536
|
+
momus: "Momus - Plan Critic",
|
|
48537
|
+
athena: "Athena - Council",
|
|
48538
|
+
"athena-junior": "Athena-Junior - Council",
|
|
48349
48539
|
oracle: "oracle",
|
|
48350
48540
|
librarian: "librarian",
|
|
48351
48541
|
explore: "explore",
|
|
@@ -48353,6 +48543,16 @@ var init_agent_display_names = __esm(() => {
|
|
|
48353
48543
|
"council-member": "council-member"
|
|
48354
48544
|
};
|
|
48355
48545
|
REVERSE_DISPLAY_NAMES = Object.fromEntries(Object.entries(AGENT_DISPLAY_NAMES).map(([key, displayName]) => [displayName.toLowerCase(), key]));
|
|
48546
|
+
LEGACY_DISPLAY_NAMES = {
|
|
48547
|
+
"sisyphus (ultraworker)": "sisyphus",
|
|
48548
|
+
"hephaestus (deep agent)": "hephaestus",
|
|
48549
|
+
"prometheus (plan builder)": "prometheus",
|
|
48550
|
+
"atlas (plan executor)": "atlas",
|
|
48551
|
+
"metis (plan consultant)": "metis",
|
|
48552
|
+
"momus (plan critic)": "momus",
|
|
48553
|
+
"athena (council)": "athena",
|
|
48554
|
+
"athena-junior (council)": "athena-junior"
|
|
48555
|
+
};
|
|
48356
48556
|
});
|
|
48357
48557
|
|
|
48358
48558
|
// src/shared/session-utils.ts
|
|
@@ -48516,9 +48716,18 @@ var init_session_tools_store = __esm(() => {
|
|
|
48516
48716
|
var init_prompt_tools = __esm(() => {
|
|
48517
48717
|
init_session_tools_store();
|
|
48518
48718
|
});
|
|
48719
|
+
|
|
48720
|
+
// src/shared/internal-initiator-marker.ts
|
|
48721
|
+
var init_internal_initiator_marker = () => {};
|
|
48722
|
+
// src/features/claude-code-plugin-loader/scope-filter.ts
|
|
48723
|
+
var init_scope_filter = __esm(() => {
|
|
48724
|
+
init_contains_path();
|
|
48725
|
+
});
|
|
48726
|
+
|
|
48519
48727
|
// src/features/claude-code-plugin-loader/discovery.ts
|
|
48520
48728
|
var init_discovery = __esm(() => {
|
|
48521
48729
|
init_logger();
|
|
48730
|
+
init_scope_filter();
|
|
48522
48731
|
});
|
|
48523
48732
|
|
|
48524
48733
|
// src/features/claude-code-plugin-loader/command-loader.ts
|
|
@@ -48569,7 +48778,7 @@ var init_env_expander = __esm(() => {
|
|
|
48569
48778
|
});
|
|
48570
48779
|
|
|
48571
48780
|
// src/features/claude-code-mcp-loader/scope-filter.ts
|
|
48572
|
-
var
|
|
48781
|
+
var init_scope_filter2 = __esm(() => {
|
|
48573
48782
|
init_contains_path();
|
|
48574
48783
|
});
|
|
48575
48784
|
|
|
@@ -48580,7 +48789,7 @@ var init_transformer = __esm(() => {
|
|
|
48580
48789
|
// src/features/claude-code-plugin-loader/mcp-server-loader.ts
|
|
48581
48790
|
var init_mcp_server_loader = __esm(() => {
|
|
48582
48791
|
init_env_expander();
|
|
48583
|
-
|
|
48792
|
+
init_scope_filter2();
|
|
48584
48793
|
init_transformer();
|
|
48585
48794
|
init_logger();
|
|
48586
48795
|
});
|
|
@@ -48591,6 +48800,7 @@ var init_hook_loader = __esm(() => {
|
|
|
48591
48800
|
});
|
|
48592
48801
|
|
|
48593
48802
|
// src/features/claude-code-plugin-loader/loader.ts
|
|
48803
|
+
var cachedPluginComponentsByKey;
|
|
48594
48804
|
var init_loader = __esm(() => {
|
|
48595
48805
|
init_logger();
|
|
48596
48806
|
init_discovery();
|
|
@@ -48605,6 +48815,7 @@ var init_loader = __esm(() => {
|
|
|
48605
48815
|
init_agent_loader();
|
|
48606
48816
|
init_mcp_server_loader();
|
|
48607
48817
|
init_hook_loader();
|
|
48818
|
+
cachedPluginComponentsByKey = new Map;
|
|
48608
48819
|
});
|
|
48609
48820
|
|
|
48610
48821
|
// src/features/claude-code-plugin-loader/index.ts
|
|
@@ -48714,6 +48925,8 @@ var init_shared = __esm(() => {
|
|
|
48714
48925
|
init_project_discovery_dirs();
|
|
48715
48926
|
init_session_directory_resolver();
|
|
48716
48927
|
init_prompt_tools();
|
|
48928
|
+
init_compaction_marker();
|
|
48929
|
+
init_internal_initiator_marker();
|
|
48717
48930
|
init_plugin_command_discovery();
|
|
48718
48931
|
init_plugin_identity();
|
|
48719
48932
|
init_log_legacy_plugin_startup_warning();
|
|
@@ -48741,16 +48954,15 @@ function getConfigJsonc() {
|
|
|
48741
48954
|
return getConfigContext().paths.configJsonc;
|
|
48742
48955
|
}
|
|
48743
48956
|
function getOmoConfigPath() {
|
|
48957
|
+
const configDir = getConfigContext().paths.configDir;
|
|
48958
|
+
const detected = detectPluginConfigFile(configDir);
|
|
48959
|
+
if (detected.format !== "none")
|
|
48960
|
+
return detected.path;
|
|
48744
48961
|
return getConfigContext().paths.omoConfig;
|
|
48745
48962
|
}
|
|
48746
|
-
function getExistingOmoConfigPath() {
|
|
48747
|
-
const detected = detectManagedConfigFile(getConfigDir());
|
|
48748
|
-
return detected.format === "none" ? null : detected.path;
|
|
48749
|
-
}
|
|
48750
48963
|
var configContext = null;
|
|
48751
48964
|
var init_config_context = __esm(() => {
|
|
48752
48965
|
init_shared();
|
|
48753
|
-
init_plugin_identity();
|
|
48754
48966
|
});
|
|
48755
48967
|
|
|
48756
48968
|
// src/cli/config-manager/npm-dist-tags.ts
|
|
@@ -48791,17 +49003,42 @@ async function getPluginNameWithVersion(currentVersion, packageName = DEFAULT_PA
|
|
|
48791
49003
|
}
|
|
48792
49004
|
var DEFAULT_PACKAGE_NAME, PRIORITIZED_TAGS;
|
|
48793
49005
|
var init_plugin_name_with_version = __esm(() => {
|
|
48794
|
-
|
|
49006
|
+
init_shared();
|
|
48795
49007
|
DEFAULT_PACKAGE_NAME = PLUGIN_NAME;
|
|
48796
49008
|
PRIORITIZED_TAGS = ["latest", "beta", "next"];
|
|
48797
49009
|
});
|
|
48798
49010
|
|
|
49011
|
+
// src/cli/config-manager/backup-config.ts
|
|
49012
|
+
import { copyFileSync as copyFileSync2, existsSync as existsSync8, mkdirSync as mkdirSync3 } from "fs";
|
|
49013
|
+
import { dirname } from "path";
|
|
49014
|
+
function backupConfigFile(configPath) {
|
|
49015
|
+
if (!existsSync8(configPath)) {
|
|
49016
|
+
return { success: true };
|
|
49017
|
+
}
|
|
49018
|
+
const timestamp2 = new Date().toISOString().replace(/[:.]/g, "-");
|
|
49019
|
+
const backupPath = `${configPath}.backup-${timestamp2}`;
|
|
49020
|
+
try {
|
|
49021
|
+
const dir = dirname(backupPath);
|
|
49022
|
+
if (!existsSync8(dir)) {
|
|
49023
|
+
mkdirSync3(dir, { recursive: true });
|
|
49024
|
+
}
|
|
49025
|
+
copyFileSync2(configPath, backupPath);
|
|
49026
|
+
return { success: true, backupPath };
|
|
49027
|
+
} catch (err) {
|
|
49028
|
+
return {
|
|
49029
|
+
success: false,
|
|
49030
|
+
error: err instanceof Error ? err.message : "Failed to create backup"
|
|
49031
|
+
};
|
|
49032
|
+
}
|
|
49033
|
+
}
|
|
49034
|
+
var init_backup_config = () => {};
|
|
49035
|
+
|
|
48799
49036
|
// src/cli/config-manager/ensure-config-directory-exists.ts
|
|
48800
|
-
import { existsSync as
|
|
49037
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync4 } from "fs";
|
|
48801
49038
|
function ensureConfigDirectoryExists() {
|
|
48802
49039
|
const configDir = getConfigDir();
|
|
48803
|
-
if (!
|
|
48804
|
-
|
|
49040
|
+
if (!existsSync9(configDir)) {
|
|
49041
|
+
mkdirSync4(configDir, { recursive: true });
|
|
48805
49042
|
}
|
|
48806
49043
|
}
|
|
48807
49044
|
var init_ensure_config_directory_exists = __esm(() => {
|
|
@@ -48838,14 +49075,14 @@ function formatErrorWithSuggestion(err, context) {
|
|
|
48838
49075
|
}
|
|
48839
49076
|
|
|
48840
49077
|
// src/cli/config-manager/opencode-config-format.ts
|
|
48841
|
-
import { existsSync as
|
|
49078
|
+
import { existsSync as existsSync10 } from "fs";
|
|
48842
49079
|
function detectConfigFormat() {
|
|
48843
49080
|
const configJsonc = getConfigJsonc();
|
|
48844
49081
|
const configJson = getConfigJson();
|
|
48845
|
-
if (
|
|
49082
|
+
if (existsSync10(configJsonc)) {
|
|
48846
49083
|
return { format: "jsonc", path: configJsonc };
|
|
48847
49084
|
}
|
|
48848
|
-
if (
|
|
49085
|
+
if (existsSync10(configJson)) {
|
|
48849
49086
|
return { format: "json", path: configJson };
|
|
48850
49087
|
}
|
|
48851
49088
|
return { format: "none", path: configJson };
|
|
@@ -48855,7 +49092,7 @@ var init_opencode_config_format = __esm(() => {
|
|
|
48855
49092
|
});
|
|
48856
49093
|
|
|
48857
49094
|
// src/cli/config-manager/parse-opencode-config-file.ts
|
|
48858
|
-
import { readFileSync as
|
|
49095
|
+
import { readFileSync as readFileSync5, statSync } from "fs";
|
|
48859
49096
|
function isEmptyOrWhitespace(content) {
|
|
48860
49097
|
return content.trim().length === 0;
|
|
48861
49098
|
}
|
|
@@ -48865,7 +49102,7 @@ function parseOpenCodeConfigFileWithError(path3) {
|
|
|
48865
49102
|
if (stat.size === 0) {
|
|
48866
49103
|
return { config: null, error: `Config file is empty: ${path3}. Delete it or add valid JSON content.` };
|
|
48867
49104
|
}
|
|
48868
|
-
const content =
|
|
49105
|
+
const content = readFileSync5(path3, "utf-8");
|
|
48869
49106
|
if (isEmptyOrWhitespace(content)) {
|
|
48870
49107
|
return { config: null, error: `Config file contains only whitespace: ${path3}. Delete it or add valid JSON content.` };
|
|
48871
49108
|
}
|
|
@@ -48888,8 +49125,90 @@ var init_parse_opencode_config_file = __esm(() => {
|
|
|
48888
49125
|
init_shared();
|
|
48889
49126
|
});
|
|
48890
49127
|
|
|
49128
|
+
// src/cli/config-manager/version-compatibility.ts
|
|
49129
|
+
function parseVersion2(version) {
|
|
49130
|
+
const clean = version.replace(/^v/, "").split("-")[0];
|
|
49131
|
+
return clean.split(".").map(Number);
|
|
49132
|
+
}
|
|
49133
|
+
function compareVersions2(a, b) {
|
|
49134
|
+
const partsA = parseVersion2(a);
|
|
49135
|
+
const partsB = parseVersion2(b);
|
|
49136
|
+
const maxLen = Math.max(partsA.length, partsB.length);
|
|
49137
|
+
for (let i2 = 0;i2 < maxLen; i2++) {
|
|
49138
|
+
const numA = partsA[i2] ?? 0;
|
|
49139
|
+
const numB = partsB[i2] ?? 0;
|
|
49140
|
+
if (numA !== numB) {
|
|
49141
|
+
return numA - numB;
|
|
49142
|
+
}
|
|
49143
|
+
}
|
|
49144
|
+
return 0;
|
|
49145
|
+
}
|
|
49146
|
+
function checkVersionCompatibility(currentVersion, newVersion) {
|
|
49147
|
+
if (!currentVersion) {
|
|
49148
|
+
return {
|
|
49149
|
+
canUpgrade: true,
|
|
49150
|
+
isDowngrade: false,
|
|
49151
|
+
isMajorBump: false,
|
|
49152
|
+
requiresMigration: false
|
|
49153
|
+
};
|
|
49154
|
+
}
|
|
49155
|
+
const cleanCurrent = currentVersion.replace(/^v/, "");
|
|
49156
|
+
const cleanNew = newVersion.replace(/^v/, "");
|
|
49157
|
+
try {
|
|
49158
|
+
const comparison = compareVersions2(cleanNew, cleanCurrent);
|
|
49159
|
+
if (comparison < 0) {
|
|
49160
|
+
return {
|
|
49161
|
+
canUpgrade: false,
|
|
49162
|
+
reason: `Downgrade from ${currentVersion} to ${newVersion} is not allowed`,
|
|
49163
|
+
isDowngrade: true,
|
|
49164
|
+
isMajorBump: false,
|
|
49165
|
+
requiresMigration: false
|
|
49166
|
+
};
|
|
49167
|
+
}
|
|
49168
|
+
if (comparison === 0) {
|
|
49169
|
+
return {
|
|
49170
|
+
canUpgrade: true,
|
|
49171
|
+
reason: `Version ${newVersion} is already installed`,
|
|
49172
|
+
isDowngrade: false,
|
|
49173
|
+
isMajorBump: false,
|
|
49174
|
+
requiresMigration: false
|
|
49175
|
+
};
|
|
49176
|
+
}
|
|
49177
|
+
const currentMajor = cleanCurrent.split(".")[0];
|
|
49178
|
+
const newMajor = cleanNew.split(".")[0];
|
|
49179
|
+
const isMajorBump = currentMajor !== newMajor;
|
|
49180
|
+
if (isMajorBump) {
|
|
49181
|
+
return {
|
|
49182
|
+
canUpgrade: true,
|
|
49183
|
+
reason: `Major version upgrade from ${currentVersion} to ${newVersion} - configuration migration may be required`,
|
|
49184
|
+
isDowngrade: false,
|
|
49185
|
+
isMajorBump: true,
|
|
49186
|
+
requiresMigration: true
|
|
49187
|
+
};
|
|
49188
|
+
}
|
|
49189
|
+
return {
|
|
49190
|
+
canUpgrade: true,
|
|
49191
|
+
isDowngrade: false,
|
|
49192
|
+
isMajorBump: false,
|
|
49193
|
+
requiresMigration: false
|
|
49194
|
+
};
|
|
49195
|
+
} catch {
|
|
49196
|
+
return {
|
|
49197
|
+
canUpgrade: true,
|
|
49198
|
+
reason: `Unable to compare versions ${currentVersion} and ${newVersion} - proceeding with caution`,
|
|
49199
|
+
isDowngrade: false,
|
|
49200
|
+
isMajorBump: false,
|
|
49201
|
+
requiresMigration: false
|
|
49202
|
+
};
|
|
49203
|
+
}
|
|
49204
|
+
}
|
|
49205
|
+
function extractVersionFromPluginEntry(entry) {
|
|
49206
|
+
const match = entry.match(/@(.+)$/);
|
|
49207
|
+
return match ? match[1] : null;
|
|
49208
|
+
}
|
|
49209
|
+
|
|
48891
49210
|
// src/cli/config-manager/add-plugin-to-opencode-config.ts
|
|
48892
|
-
import { readFileSync as
|
|
49211
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync3 } from "fs";
|
|
48893
49212
|
async function addPluginToOpenCodeConfig(currentVersion) {
|
|
48894
49213
|
try {
|
|
48895
49214
|
ensureConfigDirectoryExists();
|
|
@@ -48901,7 +49220,7 @@ async function addPluginToOpenCodeConfig(currentVersion) {
|
|
|
48901
49220
|
};
|
|
48902
49221
|
}
|
|
48903
49222
|
const { format: format2, path: path3 } = detectConfigFormat();
|
|
48904
|
-
const pluginEntry = await getPluginNameWithVersion(currentVersion,
|
|
49223
|
+
const pluginEntry = await getPluginNameWithVersion(currentVersion, PLUGIN_NAME);
|
|
48905
49224
|
try {
|
|
48906
49225
|
if (format2 === "none") {
|
|
48907
49226
|
const config2 = { plugin: [pluginEntry] };
|
|
@@ -48919,24 +49238,44 @@ async function addPluginToOpenCodeConfig(currentVersion) {
|
|
|
48919
49238
|
}
|
|
48920
49239
|
const config = parseResult.config;
|
|
48921
49240
|
const plugins = config.plugin ?? [];
|
|
48922
|
-
const
|
|
48923
|
-
|
|
48924
|
-
|
|
48925
|
-
|
|
49241
|
+
const canonicalEntries = plugins.filter((plugin) => plugin === PLUGIN_NAME || plugin.startsWith(`${PLUGIN_NAME}@`));
|
|
49242
|
+
const legacyEntries = plugins.filter((plugin) => plugin === LEGACY_PLUGIN_NAME || plugin.startsWith(`${LEGACY_PLUGIN_NAME}@`));
|
|
49243
|
+
const otherPlugins = plugins.filter((plugin) => !(plugin === PLUGIN_NAME || plugin.startsWith(`${PLUGIN_NAME}@`)) && !(plugin === LEGACY_PLUGIN_NAME || plugin.startsWith(`${LEGACY_PLUGIN_NAME}@`)));
|
|
49244
|
+
const existingEntry = canonicalEntries[0] ?? legacyEntries[0];
|
|
49245
|
+
if (existingEntry) {
|
|
49246
|
+
const installedVersion = extractVersionFromPluginEntry(existingEntry);
|
|
49247
|
+
const compatibility = checkVersionCompatibility(installedVersion, currentVersion);
|
|
49248
|
+
if (!compatibility.canUpgrade) {
|
|
49249
|
+
return {
|
|
49250
|
+
success: false,
|
|
49251
|
+
configPath: path3,
|
|
49252
|
+
error: compatibility.reason ?? "Version compatibility check failed"
|
|
49253
|
+
};
|
|
48926
49254
|
}
|
|
48927
|
-
|
|
49255
|
+
const backupResult = backupConfigFile(path3);
|
|
49256
|
+
if (!backupResult.success) {
|
|
49257
|
+
return {
|
|
49258
|
+
success: false,
|
|
49259
|
+
configPath: path3,
|
|
49260
|
+
error: `Failed to create backup: ${backupResult.error}`
|
|
49261
|
+
};
|
|
49262
|
+
}
|
|
49263
|
+
}
|
|
49264
|
+
const normalizedPlugins = [...otherPlugins];
|
|
49265
|
+
if (canonicalEntries.length > 0 || legacyEntries.length > 0) {
|
|
49266
|
+
normalizedPlugins.push(pluginEntry);
|
|
48928
49267
|
} else {
|
|
48929
|
-
|
|
49268
|
+
normalizedPlugins.push(pluginEntry);
|
|
48930
49269
|
}
|
|
48931
|
-
config.plugin =
|
|
49270
|
+
config.plugin = normalizedPlugins;
|
|
48932
49271
|
if (format2 === "jsonc") {
|
|
48933
|
-
const content =
|
|
48934
|
-
const pluginArrayRegex = /"plugin"\s*:\s
|
|
49272
|
+
const content = readFileSync6(path3, "utf-8");
|
|
49273
|
+
const pluginArrayRegex = /((?:"plugin"|plugin)\s*:\s*)\[([\s\S]*?)\]/;
|
|
48935
49274
|
const match = content.match(pluginArrayRegex);
|
|
48936
49275
|
if (match) {
|
|
48937
|
-
const formattedPlugins =
|
|
49276
|
+
const formattedPlugins = normalizedPlugins.map((p) => `"${p}"`).join(`,
|
|
48938
49277
|
`);
|
|
48939
|
-
const newContent = content.replace(pluginArrayRegex,
|
|
49278
|
+
const newContent = content.replace(pluginArrayRegex, `$1[
|
|
48940
49279
|
${formattedPlugins}
|
|
48941
49280
|
]`);
|
|
48942
49281
|
writeFileSync3(path3, newContent);
|
|
@@ -48958,15 +49297,14 @@ async function addPluginToOpenCodeConfig(currentVersion) {
|
|
|
48958
49297
|
};
|
|
48959
49298
|
}
|
|
48960
49299
|
}
|
|
48961
|
-
var PACKAGE_NAME;
|
|
48962
49300
|
var init_add_plugin_to_opencode_config = __esm(() => {
|
|
48963
|
-
|
|
49301
|
+
init_shared();
|
|
49302
|
+
init_backup_config();
|
|
48964
49303
|
init_config_context();
|
|
48965
49304
|
init_ensure_config_directory_exists();
|
|
48966
49305
|
init_opencode_config_format();
|
|
48967
49306
|
init_parse_opencode_config_file();
|
|
48968
49307
|
init_plugin_name_with_version();
|
|
48969
|
-
PACKAGE_NAME = PLUGIN_NAME;
|
|
48970
49308
|
});
|
|
48971
49309
|
|
|
48972
49310
|
// src/cli/model-fallback-requirements.ts
|
|
@@ -49077,6 +49415,47 @@ var init_fallback_chain_resolution = __esm(() => {
|
|
|
49077
49415
|
});
|
|
49078
49416
|
|
|
49079
49417
|
// src/cli/model-fallback.ts
|
|
49418
|
+
function toFallbackModelObject(entry, provider) {
|
|
49419
|
+
return {
|
|
49420
|
+
model: `${provider}/${transformModelForProvider(provider, entry.model)}`,
|
|
49421
|
+
...entry.variant ? { variant: entry.variant } : {},
|
|
49422
|
+
...entry.reasoningEffort ? { reasoningEffort: entry.reasoningEffort } : {},
|
|
49423
|
+
...entry.temperature !== undefined ? { temperature: entry.temperature } : {},
|
|
49424
|
+
...entry.top_p !== undefined ? { top_p: entry.top_p } : {},
|
|
49425
|
+
...entry.maxTokens !== undefined ? { maxTokens: entry.maxTokens } : {},
|
|
49426
|
+
...entry.thinking ? { thinking: entry.thinking } : {}
|
|
49427
|
+
};
|
|
49428
|
+
}
|
|
49429
|
+
function collectAvailableFallbacks(fallbackChain, availability) {
|
|
49430
|
+
const expandedFallbacks = fallbackChain.flatMap((entry) => entry.providers.filter((provider) => isProviderAvailable(provider, availability)).map((provider) => toFallbackModelObject(entry, provider)));
|
|
49431
|
+
return expandedFallbacks.filter((entry, index, allEntries) => allEntries.findIndex((candidate) => candidate.model === entry.model && candidate.variant === entry.variant) === index);
|
|
49432
|
+
}
|
|
49433
|
+
function attachFallbackModels(config, fallbackChain, availability) {
|
|
49434
|
+
const uniqueFallbacks = collectAvailableFallbacks(fallbackChain, availability);
|
|
49435
|
+
const primaryIndex = uniqueFallbacks.findIndex((entry) => entry.model === config.model);
|
|
49436
|
+
if (primaryIndex === -1) {
|
|
49437
|
+
return config;
|
|
49438
|
+
}
|
|
49439
|
+
const fallbackModels = uniqueFallbacks.slice(primaryIndex + 1);
|
|
49440
|
+
if (fallbackModels.length === 0) {
|
|
49441
|
+
return config;
|
|
49442
|
+
}
|
|
49443
|
+
return {
|
|
49444
|
+
...config,
|
|
49445
|
+
fallback_models: fallbackModels
|
|
49446
|
+
};
|
|
49447
|
+
}
|
|
49448
|
+
function attachAllFallbackModels(config, fallbackChain, availability) {
|
|
49449
|
+
const uniqueFallbacks = collectAvailableFallbacks(fallbackChain, availability);
|
|
49450
|
+
const fallbackModels = uniqueFallbacks.filter((entry) => entry.model !== config.model);
|
|
49451
|
+
if (fallbackModels.length === 0) {
|
|
49452
|
+
return config;
|
|
49453
|
+
}
|
|
49454
|
+
return {
|
|
49455
|
+
...config,
|
|
49456
|
+
fallback_models: fallbackModels
|
|
49457
|
+
};
|
|
49458
|
+
}
|
|
49080
49459
|
function generateModelConfig(config) {
|
|
49081
49460
|
const avail = toProviderAvailability(config);
|
|
49082
49461
|
const hasAnyProvider = avail.native.claude || avail.native.openai || avail.native.gemini || avail.opencodeZen || avail.copilot || avail.zai || avail.kimiForCoding || avail.opencodeGo;
|
|
@@ -49091,25 +49470,31 @@ function generateModelConfig(config) {
|
|
|
49091
49470
|
const categories = {};
|
|
49092
49471
|
for (const [role, req] of Object.entries(CLI_AGENT_MODEL_REQUIREMENTS)) {
|
|
49093
49472
|
if (role === "librarian") {
|
|
49473
|
+
let agentConfig;
|
|
49094
49474
|
if (avail.opencodeGo) {
|
|
49095
|
-
|
|
49475
|
+
agentConfig = { model: "opencode-go/minimax-m2.7" };
|
|
49096
49476
|
} else if (avail.zai) {
|
|
49097
|
-
|
|
49477
|
+
agentConfig = { model: ZAI_MODEL };
|
|
49478
|
+
}
|
|
49479
|
+
if (agentConfig) {
|
|
49480
|
+
agents[role] = attachAllFallbackModels(agentConfig, req.fallbackChain, avail);
|
|
49098
49481
|
}
|
|
49099
49482
|
continue;
|
|
49100
49483
|
}
|
|
49101
49484
|
if (role === "explore") {
|
|
49485
|
+
let agentConfig;
|
|
49102
49486
|
if (avail.native.claude) {
|
|
49103
|
-
|
|
49487
|
+
agentConfig = { model: "anthropic/claude-haiku-4-5" };
|
|
49104
49488
|
} else if (avail.opencodeZen) {
|
|
49105
|
-
|
|
49489
|
+
agentConfig = { model: "opencode/claude-haiku-4-5" };
|
|
49106
49490
|
} else if (avail.opencodeGo) {
|
|
49107
|
-
|
|
49491
|
+
agentConfig = { model: "opencode-go/minimax-m2.7" };
|
|
49108
49492
|
} else if (avail.copilot) {
|
|
49109
|
-
|
|
49493
|
+
agentConfig = { model: "github-copilot/gpt-5-mini" };
|
|
49110
49494
|
} else {
|
|
49111
|
-
|
|
49495
|
+
agentConfig = { model: "opencode/gpt-5-nano" };
|
|
49112
49496
|
}
|
|
49497
|
+
agents[role] = attachAllFallbackModels(agentConfig, req.fallbackChain, avail);
|
|
49113
49498
|
continue;
|
|
49114
49499
|
}
|
|
49115
49500
|
if (role === "sisyphus") {
|
|
@@ -49120,7 +49505,8 @@ function generateModelConfig(config) {
|
|
|
49120
49505
|
const resolved2 = resolveModelFromChain(fallbackChain, avail);
|
|
49121
49506
|
if (resolved2) {
|
|
49122
49507
|
const variant = resolved2.variant ?? req.variant;
|
|
49123
|
-
|
|
49508
|
+
const agentConfig = variant ? { model: resolved2.model, variant } : { model: resolved2.model };
|
|
49509
|
+
agents[role] = attachFallbackModels(agentConfig, fallbackChain, avail);
|
|
49124
49510
|
}
|
|
49125
49511
|
continue;
|
|
49126
49512
|
}
|
|
@@ -49133,7 +49519,8 @@ function generateModelConfig(config) {
|
|
|
49133
49519
|
const resolved = resolveModelFromChain(req.fallbackChain, avail);
|
|
49134
49520
|
if (resolved) {
|
|
49135
49521
|
const variant = resolved.variant ?? req.variant;
|
|
49136
|
-
|
|
49522
|
+
const agentConfig = variant ? { model: resolved.model, variant } : { model: resolved.model };
|
|
49523
|
+
agents[role] = attachFallbackModels(agentConfig, req.fallbackChain, avail);
|
|
49137
49524
|
} else {
|
|
49138
49525
|
agents[role] = { model: ULTIMATE_FALLBACK };
|
|
49139
49526
|
}
|
|
@@ -49149,7 +49536,8 @@ function generateModelConfig(config) {
|
|
|
49149
49536
|
const resolved = resolveModelFromChain(fallbackChain, avail);
|
|
49150
49537
|
if (resolved) {
|
|
49151
49538
|
const variant = resolved.variant ?? req.variant;
|
|
49152
|
-
|
|
49539
|
+
const categoryConfig = variant ? { model: resolved.model, variant } : { model: resolved.model };
|
|
49540
|
+
categories[cat] = attachFallbackModels(categoryConfig, fallbackChain, avail);
|
|
49153
49541
|
} else {
|
|
49154
49542
|
categories[cat] = { model: ULTIMATE_FALLBACK };
|
|
49155
49543
|
}
|
|
@@ -49161,13 +49549,12 @@ function generateModelConfig(config) {
|
|
|
49161
49549
|
};
|
|
49162
49550
|
return isOpenAiOnlyAvailability(avail) ? applyOpenAiOnlyModelCatalog(generatedConfig) : generatedConfig;
|
|
49163
49551
|
}
|
|
49164
|
-
var ZAI_MODEL = "zai-coding-plan/glm-4.7", ULTIMATE_FALLBACK = "opencode/
|
|
49552
|
+
var ZAI_MODEL = "zai-coding-plan/glm-4.7", ULTIMATE_FALLBACK = "opencode/gpt-5-nano", SCHEMA_URL = "https://raw.githubusercontent.com/D4ch1au/evil-oh-my-openagent/dev/assets/evil-omo.schema.json";
|
|
49165
49553
|
var init_model_fallback = __esm(() => {
|
|
49166
49554
|
init_model_fallback_requirements();
|
|
49167
49555
|
init_openai_only_model_catalog();
|
|
49168
49556
|
init_fallback_chain_resolution();
|
|
49169
|
-
|
|
49170
|
-
SCHEMA_URL = `https://raw.githubusercontent.com/D4ch1au/evil-oh-my-openagent/dev/assets/${SCHEMA_FILENAME}`;
|
|
49557
|
+
init_provider_model_id_transform();
|
|
49171
49558
|
});
|
|
49172
49559
|
|
|
49173
49560
|
// src/cli/config-manager/generate-omo-config.ts
|
|
@@ -49196,7 +49583,7 @@ function deepMergeRecord(target, source) {
|
|
|
49196
49583
|
}
|
|
49197
49584
|
|
|
49198
49585
|
// src/cli/config-manager/write-omo-config.ts
|
|
49199
|
-
import { existsSync as
|
|
49586
|
+
import { existsSync as existsSync11, readFileSync as readFileSync7, statSync as statSync2, writeFileSync as writeFileSync4 } from "fs";
|
|
49200
49587
|
function isEmptyOrWhitespace2(content) {
|
|
49201
49588
|
return content.trim().length === 0;
|
|
49202
49589
|
}
|
|
@@ -49211,13 +49598,20 @@ function writeOmoConfig(installConfig) {
|
|
|
49211
49598
|
};
|
|
49212
49599
|
}
|
|
49213
49600
|
const omoConfigPath = getOmoConfigPath();
|
|
49214
|
-
const existingConfigPath = getExistingOmoConfigPath() ?? omoConfigPath;
|
|
49215
49601
|
try {
|
|
49216
49602
|
const newConfig = generateOmoConfig(installConfig);
|
|
49217
|
-
if (
|
|
49603
|
+
if (existsSync11(omoConfigPath)) {
|
|
49604
|
+
const backupResult = backupConfigFile(omoConfigPath);
|
|
49605
|
+
if (!backupResult.success) {
|
|
49606
|
+
return {
|
|
49607
|
+
success: false,
|
|
49608
|
+
configPath: omoConfigPath,
|
|
49609
|
+
error: `Failed to create backup: ${backupResult.error}`
|
|
49610
|
+
};
|
|
49611
|
+
}
|
|
49218
49612
|
try {
|
|
49219
|
-
const stat = statSync2(
|
|
49220
|
-
const content =
|
|
49613
|
+
const stat = statSync2(omoConfigPath);
|
|
49614
|
+
const content = readFileSync7(omoConfigPath, "utf-8");
|
|
49221
49615
|
if (stat.size === 0 || isEmptyOrWhitespace2(content)) {
|
|
49222
49616
|
writeFileSync4(omoConfigPath, JSON.stringify(newConfig, null, 2) + `
|
|
49223
49617
|
`);
|
|
@@ -49230,7 +49624,6 @@ function writeOmoConfig(installConfig) {
|
|
|
49230
49624
|
return { success: true, configPath: omoConfigPath };
|
|
49231
49625
|
}
|
|
49232
49626
|
const merged = deepMergeRecord(newConfig, existing);
|
|
49233
|
-
merged.$schema = newConfig.$schema;
|
|
49234
49627
|
writeFileSync4(omoConfigPath, JSON.stringify(merged, null, 2) + `
|
|
49235
49628
|
`);
|
|
49236
49629
|
} catch (parseErr) {
|
|
@@ -49256,6 +49649,7 @@ function writeOmoConfig(installConfig) {
|
|
|
49256
49649
|
}
|
|
49257
49650
|
var init_write_omo_config = __esm(() => {
|
|
49258
49651
|
init_shared();
|
|
49652
|
+
init_backup_config();
|
|
49259
49653
|
init_config_context();
|
|
49260
49654
|
init_ensure_config_directory_exists();
|
|
49261
49655
|
init_generate_omo_config();
|
|
@@ -49346,7 +49740,7 @@ async function isOpenCodeInstalled() {
|
|
|
49346
49740
|
const result = await findOpenCodeBinaryWithVersion();
|
|
49347
49741
|
return result !== null;
|
|
49348
49742
|
}
|
|
49349
|
-
async function
|
|
49743
|
+
async function getOpenCodeVersion2() {
|
|
49350
49744
|
const result = await findOpenCodeBinaryWithVersion();
|
|
49351
49745
|
return result?.version ?? null;
|
|
49352
49746
|
}
|
|
@@ -49358,10 +49752,10 @@ var init_opencode_binary = __esm(() => {
|
|
|
49358
49752
|
});
|
|
49359
49753
|
|
|
49360
49754
|
// src/cli/config-manager/detect-current-config.ts
|
|
49361
|
-
import { existsSync as
|
|
49755
|
+
import { existsSync as existsSync12, readFileSync as readFileSync8 } from "fs";
|
|
49362
49756
|
function detectProvidersFromOmoConfig() {
|
|
49363
|
-
const omoConfigPath =
|
|
49364
|
-
if (!
|
|
49757
|
+
const omoConfigPath = getOmoConfigPath();
|
|
49758
|
+
if (!existsSync12(omoConfigPath)) {
|
|
49365
49759
|
return {
|
|
49366
49760
|
hasOpenAI: true,
|
|
49367
49761
|
hasOpencodeZen: true,
|
|
@@ -49371,7 +49765,7 @@ function detectProvidersFromOmoConfig() {
|
|
|
49371
49765
|
};
|
|
49372
49766
|
}
|
|
49373
49767
|
try {
|
|
49374
|
-
const content =
|
|
49768
|
+
const content = readFileSync8(omoConfigPath, "utf-8");
|
|
49375
49769
|
const omoConfig = parseJsonc(content);
|
|
49376
49770
|
if (!omoConfig || typeof omoConfig !== "object") {
|
|
49377
49771
|
return {
|
|
@@ -49399,9 +49793,16 @@ function detectProvidersFromOmoConfig() {
|
|
|
49399
49793
|
};
|
|
49400
49794
|
}
|
|
49401
49795
|
}
|
|
49796
|
+
function isOurPlugin(plugin) {
|
|
49797
|
+
return plugin === PLUGIN_NAME || plugin.startsWith(`${PLUGIN_NAME}@`) || plugin === LEGACY_PLUGIN_NAME || plugin.startsWith(`${LEGACY_PLUGIN_NAME}@`);
|
|
49798
|
+
}
|
|
49799
|
+
function findOurPluginEntry(plugins) {
|
|
49800
|
+
return plugins.find(isOurPlugin) ?? null;
|
|
49801
|
+
}
|
|
49402
49802
|
function detectCurrentConfig() {
|
|
49403
49803
|
const result = {
|
|
49404
49804
|
isInstalled: false,
|
|
49805
|
+
installedVersion: null,
|
|
49405
49806
|
hasClaude: true,
|
|
49406
49807
|
isMax20: true,
|
|
49407
49808
|
hasOpenAI: true,
|
|
@@ -49422,7 +49823,11 @@ function detectCurrentConfig() {
|
|
|
49422
49823
|
}
|
|
49423
49824
|
const openCodeConfig = parseResult.config;
|
|
49424
49825
|
const plugins = openCodeConfig.plugin ?? [];
|
|
49425
|
-
|
|
49826
|
+
const ourPluginEntry = findOurPluginEntry(plugins);
|
|
49827
|
+
result.isInstalled = !!ourPluginEntry;
|
|
49828
|
+
if (ourPluginEntry) {
|
|
49829
|
+
result.installedVersion = extractVersionFromPluginEntry(ourPluginEntry);
|
|
49830
|
+
}
|
|
49426
49831
|
if (!result.isInstalled) {
|
|
49427
49832
|
return result;
|
|
49428
49833
|
}
|
|
@@ -49438,17 +49843,16 @@ function detectCurrentConfig() {
|
|
|
49438
49843
|
}
|
|
49439
49844
|
var init_detect_current_config = __esm(() => {
|
|
49440
49845
|
init_shared();
|
|
49441
|
-
init_plugin_identity();
|
|
49442
49846
|
init_config_context();
|
|
49443
49847
|
init_opencode_config_format();
|
|
49444
49848
|
init_parse_opencode_config_file();
|
|
49445
49849
|
});
|
|
49446
49850
|
|
|
49447
49851
|
// src/cli/config-manager/bun-install.ts
|
|
49448
|
-
import { existsSync as
|
|
49449
|
-
import { join as
|
|
49852
|
+
import { existsSync as existsSync13 } from "fs";
|
|
49853
|
+
import { join as join12 } from "path";
|
|
49450
49854
|
function getDefaultWorkspaceDir() {
|
|
49451
|
-
return
|
|
49855
|
+
return join12(getOpenCodeCacheDir(), "packages");
|
|
49452
49856
|
}
|
|
49453
49857
|
function readProcessOutput(stream) {
|
|
49454
49858
|
if (!stream) {
|
|
@@ -49474,7 +49878,7 @@ async function runBunInstallWithDetails(options) {
|
|
|
49474
49878
|
const outputMode = options?.outputMode ?? "pipe";
|
|
49475
49879
|
const cacheDir = options?.workspaceDir ?? getDefaultWorkspaceDir();
|
|
49476
49880
|
const packageJsonPath = `${cacheDir}/package.json`;
|
|
49477
|
-
if (!
|
|
49881
|
+
if (!existsSync13(packageJsonPath)) {
|
|
49478
49882
|
return {
|
|
49479
49883
|
success: false,
|
|
49480
49884
|
error: `Workspace not initialized: ${packageJsonPath} not found. OpenCode should create this on first run.`
|
|
@@ -49550,6 +49954,7 @@ var init_config_manager = __esm(() => {
|
|
|
49550
49954
|
init_opencode_binary();
|
|
49551
49955
|
init_detect_current_config();
|
|
49552
49956
|
init_bun_install();
|
|
49957
|
+
init_backup_config();
|
|
49553
49958
|
});
|
|
49554
49959
|
|
|
49555
49960
|
// node_modules/sisteransi/src/index.js
|
|
@@ -49610,6 +50015,462 @@ var require_src = __commonJS((exports, module) => {
|
|
|
49610
50015
|
module.exports = { cursor, scroll, erase, beep };
|
|
49611
50016
|
});
|
|
49612
50017
|
|
|
50018
|
+
// node_modules/isexe/windows.js
|
|
50019
|
+
var require_windows = __commonJS((exports, module) => {
|
|
50020
|
+
module.exports = isexe;
|
|
50021
|
+
isexe.sync = sync;
|
|
50022
|
+
var fs4 = __require("fs");
|
|
50023
|
+
function checkPathExt(path4, options) {
|
|
50024
|
+
var pathext = options.pathExt !== undefined ? options.pathExt : process.env.PATHEXT;
|
|
50025
|
+
if (!pathext) {
|
|
50026
|
+
return true;
|
|
50027
|
+
}
|
|
50028
|
+
pathext = pathext.split(";");
|
|
50029
|
+
if (pathext.indexOf("") !== -1) {
|
|
50030
|
+
return true;
|
|
50031
|
+
}
|
|
50032
|
+
for (var i2 = 0;i2 < pathext.length; i2++) {
|
|
50033
|
+
var p2 = pathext[i2].toLowerCase();
|
|
50034
|
+
if (p2 && path4.substr(-p2.length).toLowerCase() === p2) {
|
|
50035
|
+
return true;
|
|
50036
|
+
}
|
|
50037
|
+
}
|
|
50038
|
+
return false;
|
|
50039
|
+
}
|
|
50040
|
+
function checkStat(stat, path4, options) {
|
|
50041
|
+
if (!stat.isSymbolicLink() && !stat.isFile()) {
|
|
50042
|
+
return false;
|
|
50043
|
+
}
|
|
50044
|
+
return checkPathExt(path4, options);
|
|
50045
|
+
}
|
|
50046
|
+
function isexe(path4, options, cb) {
|
|
50047
|
+
fs4.stat(path4, function(er, stat) {
|
|
50048
|
+
cb(er, er ? false : checkStat(stat, path4, options));
|
|
50049
|
+
});
|
|
50050
|
+
}
|
|
50051
|
+
function sync(path4, options) {
|
|
50052
|
+
return checkStat(fs4.statSync(path4), path4, options);
|
|
50053
|
+
}
|
|
50054
|
+
});
|
|
50055
|
+
|
|
50056
|
+
// node_modules/isexe/mode.js
|
|
50057
|
+
var require_mode = __commonJS((exports, module) => {
|
|
50058
|
+
module.exports = isexe;
|
|
50059
|
+
isexe.sync = sync;
|
|
50060
|
+
var fs4 = __require("fs");
|
|
50061
|
+
function isexe(path4, options, cb) {
|
|
50062
|
+
fs4.stat(path4, function(er, stat) {
|
|
50063
|
+
cb(er, er ? false : checkStat(stat, options));
|
|
50064
|
+
});
|
|
50065
|
+
}
|
|
50066
|
+
function sync(path4, options) {
|
|
50067
|
+
return checkStat(fs4.statSync(path4), options);
|
|
50068
|
+
}
|
|
50069
|
+
function checkStat(stat, options) {
|
|
50070
|
+
return stat.isFile() && checkMode(stat, options);
|
|
50071
|
+
}
|
|
50072
|
+
function checkMode(stat, options) {
|
|
50073
|
+
var mod = stat.mode;
|
|
50074
|
+
var uid = stat.uid;
|
|
50075
|
+
var gid = stat.gid;
|
|
50076
|
+
var myUid = options.uid !== undefined ? options.uid : process.getuid && process.getuid();
|
|
50077
|
+
var myGid = options.gid !== undefined ? options.gid : process.getgid && process.getgid();
|
|
50078
|
+
var u2 = parseInt("100", 8);
|
|
50079
|
+
var g2 = parseInt("010", 8);
|
|
50080
|
+
var o2 = parseInt("001", 8);
|
|
50081
|
+
var ug = u2 | g2;
|
|
50082
|
+
var ret = mod & o2 || mod & g2 && gid === myGid || mod & u2 && uid === myUid || mod & ug && myUid === 0;
|
|
50083
|
+
return ret;
|
|
50084
|
+
}
|
|
50085
|
+
});
|
|
50086
|
+
|
|
50087
|
+
// node_modules/isexe/index.js
|
|
50088
|
+
var require_isexe = __commonJS((exports, module) => {
|
|
50089
|
+
var fs4 = __require("fs");
|
|
50090
|
+
var core3;
|
|
50091
|
+
if (process.platform === "win32" || global.TESTING_WINDOWS) {
|
|
50092
|
+
core3 = require_windows();
|
|
50093
|
+
} else {
|
|
50094
|
+
core3 = require_mode();
|
|
50095
|
+
}
|
|
50096
|
+
module.exports = isexe;
|
|
50097
|
+
isexe.sync = sync;
|
|
50098
|
+
function isexe(path4, options, cb) {
|
|
50099
|
+
if (typeof options === "function") {
|
|
50100
|
+
cb = options;
|
|
50101
|
+
options = {};
|
|
50102
|
+
}
|
|
50103
|
+
if (!cb) {
|
|
50104
|
+
if (typeof Promise !== "function") {
|
|
50105
|
+
throw new TypeError("callback not provided");
|
|
50106
|
+
}
|
|
50107
|
+
return new Promise(function(resolve2, reject) {
|
|
50108
|
+
isexe(path4, options || {}, function(er, is) {
|
|
50109
|
+
if (er) {
|
|
50110
|
+
reject(er);
|
|
50111
|
+
} else {
|
|
50112
|
+
resolve2(is);
|
|
50113
|
+
}
|
|
50114
|
+
});
|
|
50115
|
+
});
|
|
50116
|
+
}
|
|
50117
|
+
core3(path4, options || {}, function(er, is) {
|
|
50118
|
+
if (er) {
|
|
50119
|
+
if (er.code === "EACCES" || options && options.ignoreErrors) {
|
|
50120
|
+
er = null;
|
|
50121
|
+
is = false;
|
|
50122
|
+
}
|
|
50123
|
+
}
|
|
50124
|
+
cb(er, is);
|
|
50125
|
+
});
|
|
50126
|
+
}
|
|
50127
|
+
function sync(path4, options) {
|
|
50128
|
+
try {
|
|
50129
|
+
return core3.sync(path4, options || {});
|
|
50130
|
+
} catch (er) {
|
|
50131
|
+
if (options && options.ignoreErrors || er.code === "EACCES") {
|
|
50132
|
+
return false;
|
|
50133
|
+
} else {
|
|
50134
|
+
throw er;
|
|
50135
|
+
}
|
|
50136
|
+
}
|
|
50137
|
+
}
|
|
50138
|
+
});
|
|
50139
|
+
|
|
50140
|
+
// node_modules/which/which.js
|
|
50141
|
+
var require_which = __commonJS((exports, module) => {
|
|
50142
|
+
var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
|
|
50143
|
+
var path4 = __require("path");
|
|
50144
|
+
var COLON = isWindows ? ";" : ":";
|
|
50145
|
+
var isexe = require_isexe();
|
|
50146
|
+
var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
|
|
50147
|
+
var getPathInfo = (cmd, opt) => {
|
|
50148
|
+
const colon = opt.colon || COLON;
|
|
50149
|
+
const pathEnv = cmd.match(/\//) || isWindows && cmd.match(/\\/) ? [""] : [
|
|
50150
|
+
...isWindows ? [process.cwd()] : [],
|
|
50151
|
+
...(opt.path || process.env.PATH || "").split(colon)
|
|
50152
|
+
];
|
|
50153
|
+
const pathExtExe = isWindows ? opt.pathExt || process.env.PATHEXT || ".EXE;.CMD;.BAT;.COM" : "";
|
|
50154
|
+
const pathExt = isWindows ? pathExtExe.split(colon) : [""];
|
|
50155
|
+
if (isWindows) {
|
|
50156
|
+
if (cmd.indexOf(".") !== -1 && pathExt[0] !== "")
|
|
50157
|
+
pathExt.unshift("");
|
|
50158
|
+
}
|
|
50159
|
+
return {
|
|
50160
|
+
pathEnv,
|
|
50161
|
+
pathExt,
|
|
50162
|
+
pathExtExe
|
|
50163
|
+
};
|
|
50164
|
+
};
|
|
50165
|
+
var which = (cmd, opt, cb) => {
|
|
50166
|
+
if (typeof opt === "function") {
|
|
50167
|
+
cb = opt;
|
|
50168
|
+
opt = {};
|
|
50169
|
+
}
|
|
50170
|
+
if (!opt)
|
|
50171
|
+
opt = {};
|
|
50172
|
+
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
50173
|
+
const found = [];
|
|
50174
|
+
const step = (i2) => new Promise((resolve2, reject) => {
|
|
50175
|
+
if (i2 === pathEnv.length)
|
|
50176
|
+
return opt.all && found.length ? resolve2(found) : reject(getNotFoundError(cmd));
|
|
50177
|
+
const ppRaw = pathEnv[i2];
|
|
50178
|
+
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
50179
|
+
const pCmd = path4.join(pathPart, cmd);
|
|
50180
|
+
const p2 = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
50181
|
+
resolve2(subStep(p2, i2, 0));
|
|
50182
|
+
});
|
|
50183
|
+
const subStep = (p2, i2, ii) => new Promise((resolve2, reject) => {
|
|
50184
|
+
if (ii === pathExt.length)
|
|
50185
|
+
return resolve2(step(i2 + 1));
|
|
50186
|
+
const ext = pathExt[ii];
|
|
50187
|
+
isexe(p2 + ext, { pathExt: pathExtExe }, (er, is) => {
|
|
50188
|
+
if (!er && is) {
|
|
50189
|
+
if (opt.all)
|
|
50190
|
+
found.push(p2 + ext);
|
|
50191
|
+
else
|
|
50192
|
+
return resolve2(p2 + ext);
|
|
50193
|
+
}
|
|
50194
|
+
return resolve2(subStep(p2, i2, ii + 1));
|
|
50195
|
+
});
|
|
50196
|
+
});
|
|
50197
|
+
return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
|
|
50198
|
+
};
|
|
50199
|
+
var whichSync = (cmd, opt) => {
|
|
50200
|
+
opt = opt || {};
|
|
50201
|
+
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
50202
|
+
const found = [];
|
|
50203
|
+
for (let i2 = 0;i2 < pathEnv.length; i2++) {
|
|
50204
|
+
const ppRaw = pathEnv[i2];
|
|
50205
|
+
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
50206
|
+
const pCmd = path4.join(pathPart, cmd);
|
|
50207
|
+
const p2 = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
50208
|
+
for (let j2 = 0;j2 < pathExt.length; j2++) {
|
|
50209
|
+
const cur = p2 + pathExt[j2];
|
|
50210
|
+
try {
|
|
50211
|
+
const is = isexe.sync(cur, { pathExt: pathExtExe });
|
|
50212
|
+
if (is) {
|
|
50213
|
+
if (opt.all)
|
|
50214
|
+
found.push(cur);
|
|
50215
|
+
else
|
|
50216
|
+
return cur;
|
|
50217
|
+
}
|
|
50218
|
+
} catch (ex) {}
|
|
50219
|
+
}
|
|
50220
|
+
}
|
|
50221
|
+
if (opt.all && found.length)
|
|
50222
|
+
return found;
|
|
50223
|
+
if (opt.nothrow)
|
|
50224
|
+
return null;
|
|
50225
|
+
throw getNotFoundError(cmd);
|
|
50226
|
+
};
|
|
50227
|
+
module.exports = which;
|
|
50228
|
+
which.sync = whichSync;
|
|
50229
|
+
});
|
|
50230
|
+
|
|
50231
|
+
// node_modules/path-key/index.js
|
|
50232
|
+
var require_path_key = __commonJS((exports, module) => {
|
|
50233
|
+
var pathKey = (options = {}) => {
|
|
50234
|
+
const environment = options.env || process.env;
|
|
50235
|
+
const platform = options.platform || process.platform;
|
|
50236
|
+
if (platform !== "win32") {
|
|
50237
|
+
return "PATH";
|
|
50238
|
+
}
|
|
50239
|
+
return Object.keys(environment).reverse().find((key) => key.toUpperCase() === "PATH") || "Path";
|
|
50240
|
+
};
|
|
50241
|
+
module.exports = pathKey;
|
|
50242
|
+
module.exports.default = pathKey;
|
|
50243
|
+
});
|
|
50244
|
+
|
|
50245
|
+
// node_modules/cross-spawn/lib/util/resolveCommand.js
|
|
50246
|
+
var require_resolveCommand = __commonJS((exports, module) => {
|
|
50247
|
+
var path4 = __require("path");
|
|
50248
|
+
var which = require_which();
|
|
50249
|
+
var getPathKey = require_path_key();
|
|
50250
|
+
function resolveCommandAttempt(parsed, withoutPathExt) {
|
|
50251
|
+
const env = parsed.options.env || process.env;
|
|
50252
|
+
const cwd = process.cwd();
|
|
50253
|
+
const hasCustomCwd = parsed.options.cwd != null;
|
|
50254
|
+
const shouldSwitchCwd = hasCustomCwd && process.chdir !== undefined && !process.chdir.disabled;
|
|
50255
|
+
if (shouldSwitchCwd) {
|
|
50256
|
+
try {
|
|
50257
|
+
process.chdir(parsed.options.cwd);
|
|
50258
|
+
} catch (err) {}
|
|
50259
|
+
}
|
|
50260
|
+
let resolved;
|
|
50261
|
+
try {
|
|
50262
|
+
resolved = which.sync(parsed.command, {
|
|
50263
|
+
path: env[getPathKey({ env })],
|
|
50264
|
+
pathExt: withoutPathExt ? path4.delimiter : undefined
|
|
50265
|
+
});
|
|
50266
|
+
} catch (e2) {} finally {
|
|
50267
|
+
if (shouldSwitchCwd) {
|
|
50268
|
+
process.chdir(cwd);
|
|
50269
|
+
}
|
|
50270
|
+
}
|
|
50271
|
+
if (resolved) {
|
|
50272
|
+
resolved = path4.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
|
|
50273
|
+
}
|
|
50274
|
+
return resolved;
|
|
50275
|
+
}
|
|
50276
|
+
function resolveCommand(parsed) {
|
|
50277
|
+
return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true);
|
|
50278
|
+
}
|
|
50279
|
+
module.exports = resolveCommand;
|
|
50280
|
+
});
|
|
50281
|
+
|
|
50282
|
+
// node_modules/cross-spawn/lib/util/escape.js
|
|
50283
|
+
var require_escape = __commonJS((exports, module) => {
|
|
50284
|
+
var metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g;
|
|
50285
|
+
function escapeCommand(arg) {
|
|
50286
|
+
arg = arg.replace(metaCharsRegExp, "^$1");
|
|
50287
|
+
return arg;
|
|
50288
|
+
}
|
|
50289
|
+
function escapeArgument(arg, doubleEscapeMetaChars) {
|
|
50290
|
+
arg = `${arg}`;
|
|
50291
|
+
arg = arg.replace(/(?=(\\+?)?)\1"/g, "$1$1\\\"");
|
|
50292
|
+
arg = arg.replace(/(?=(\\+?)?)\1$/, "$1$1");
|
|
50293
|
+
arg = `"${arg}"`;
|
|
50294
|
+
arg = arg.replace(metaCharsRegExp, "^$1");
|
|
50295
|
+
if (doubleEscapeMetaChars) {
|
|
50296
|
+
arg = arg.replace(metaCharsRegExp, "^$1");
|
|
50297
|
+
}
|
|
50298
|
+
return arg;
|
|
50299
|
+
}
|
|
50300
|
+
exports.command = escapeCommand;
|
|
50301
|
+
exports.argument = escapeArgument;
|
|
50302
|
+
});
|
|
50303
|
+
|
|
50304
|
+
// node_modules/shebang-regex/index.js
|
|
50305
|
+
var require_shebang_regex = __commonJS((exports, module) => {
|
|
50306
|
+
module.exports = /^#!(.*)/;
|
|
50307
|
+
});
|
|
50308
|
+
|
|
50309
|
+
// node_modules/shebang-command/index.js
|
|
50310
|
+
var require_shebang_command = __commonJS((exports, module) => {
|
|
50311
|
+
var shebangRegex = require_shebang_regex();
|
|
50312
|
+
module.exports = (string4 = "") => {
|
|
50313
|
+
const match = string4.match(shebangRegex);
|
|
50314
|
+
if (!match) {
|
|
50315
|
+
return null;
|
|
50316
|
+
}
|
|
50317
|
+
const [path4, argument] = match[0].replace(/#! ?/, "").split(" ");
|
|
50318
|
+
const binary2 = path4.split("/").pop();
|
|
50319
|
+
if (binary2 === "env") {
|
|
50320
|
+
return argument;
|
|
50321
|
+
}
|
|
50322
|
+
return argument ? `${binary2} ${argument}` : binary2;
|
|
50323
|
+
};
|
|
50324
|
+
});
|
|
50325
|
+
|
|
50326
|
+
// node_modules/cross-spawn/lib/util/readShebang.js
|
|
50327
|
+
var require_readShebang = __commonJS((exports, module) => {
|
|
50328
|
+
var fs4 = __require("fs");
|
|
50329
|
+
var shebangCommand = require_shebang_command();
|
|
50330
|
+
function readShebang(command) {
|
|
50331
|
+
const size = 150;
|
|
50332
|
+
const buffer2 = Buffer.alloc(size);
|
|
50333
|
+
let fd;
|
|
50334
|
+
try {
|
|
50335
|
+
fd = fs4.openSync(command, "r");
|
|
50336
|
+
fs4.readSync(fd, buffer2, 0, size, 0);
|
|
50337
|
+
fs4.closeSync(fd);
|
|
50338
|
+
} catch (e2) {}
|
|
50339
|
+
return shebangCommand(buffer2.toString());
|
|
50340
|
+
}
|
|
50341
|
+
module.exports = readShebang;
|
|
50342
|
+
});
|
|
50343
|
+
|
|
50344
|
+
// node_modules/cross-spawn/lib/parse.js
|
|
50345
|
+
var require_parse = __commonJS((exports, module) => {
|
|
50346
|
+
var path4 = __require("path");
|
|
50347
|
+
var resolveCommand = require_resolveCommand();
|
|
50348
|
+
var escape = require_escape();
|
|
50349
|
+
var readShebang = require_readShebang();
|
|
50350
|
+
var isWin = process.platform === "win32";
|
|
50351
|
+
var isExecutableRegExp = /\.(?:com|exe)$/i;
|
|
50352
|
+
var isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;
|
|
50353
|
+
function detectShebang(parsed) {
|
|
50354
|
+
parsed.file = resolveCommand(parsed);
|
|
50355
|
+
const shebang = parsed.file && readShebang(parsed.file);
|
|
50356
|
+
if (shebang) {
|
|
50357
|
+
parsed.args.unshift(parsed.file);
|
|
50358
|
+
parsed.command = shebang;
|
|
50359
|
+
return resolveCommand(parsed);
|
|
50360
|
+
}
|
|
50361
|
+
return parsed.file;
|
|
50362
|
+
}
|
|
50363
|
+
function parseNonShell(parsed) {
|
|
50364
|
+
if (!isWin) {
|
|
50365
|
+
return parsed;
|
|
50366
|
+
}
|
|
50367
|
+
const commandFile = detectShebang(parsed);
|
|
50368
|
+
const needsShell = !isExecutableRegExp.test(commandFile);
|
|
50369
|
+
if (parsed.options.forceShell || needsShell) {
|
|
50370
|
+
const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
|
|
50371
|
+
parsed.command = path4.normalize(parsed.command);
|
|
50372
|
+
parsed.command = escape.command(parsed.command);
|
|
50373
|
+
parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars));
|
|
50374
|
+
const shellCommand = [parsed.command].concat(parsed.args).join(" ");
|
|
50375
|
+
parsed.args = ["/d", "/s", "/c", `"${shellCommand}"`];
|
|
50376
|
+
parsed.command = process.env.comspec || "cmd.exe";
|
|
50377
|
+
parsed.options.windowsVerbatimArguments = true;
|
|
50378
|
+
}
|
|
50379
|
+
return parsed;
|
|
50380
|
+
}
|
|
50381
|
+
function parse7(command, args, options) {
|
|
50382
|
+
if (args && !Array.isArray(args)) {
|
|
50383
|
+
options = args;
|
|
50384
|
+
args = null;
|
|
50385
|
+
}
|
|
50386
|
+
args = args ? args.slice(0) : [];
|
|
50387
|
+
options = Object.assign({}, options);
|
|
50388
|
+
const parsed = {
|
|
50389
|
+
command,
|
|
50390
|
+
args,
|
|
50391
|
+
options,
|
|
50392
|
+
file: undefined,
|
|
50393
|
+
original: {
|
|
50394
|
+
command,
|
|
50395
|
+
args
|
|
50396
|
+
}
|
|
50397
|
+
};
|
|
50398
|
+
return options.shell ? parsed : parseNonShell(parsed);
|
|
50399
|
+
}
|
|
50400
|
+
module.exports = parse7;
|
|
50401
|
+
});
|
|
50402
|
+
|
|
50403
|
+
// node_modules/cross-spawn/lib/enoent.js
|
|
50404
|
+
var require_enoent = __commonJS((exports, module) => {
|
|
50405
|
+
var isWin = process.platform === "win32";
|
|
50406
|
+
function notFoundError(original, syscall) {
|
|
50407
|
+
return Object.assign(new Error(`${syscall} ${original.command} ENOENT`), {
|
|
50408
|
+
code: "ENOENT",
|
|
50409
|
+
errno: "ENOENT",
|
|
50410
|
+
syscall: `${syscall} ${original.command}`,
|
|
50411
|
+
path: original.command,
|
|
50412
|
+
spawnargs: original.args
|
|
50413
|
+
});
|
|
50414
|
+
}
|
|
50415
|
+
function hookChildProcess(cp, parsed) {
|
|
50416
|
+
if (!isWin) {
|
|
50417
|
+
return;
|
|
50418
|
+
}
|
|
50419
|
+
const originalEmit = cp.emit;
|
|
50420
|
+
cp.emit = function(name, arg1) {
|
|
50421
|
+
if (name === "exit") {
|
|
50422
|
+
const err = verifyENOENT(arg1, parsed);
|
|
50423
|
+
if (err) {
|
|
50424
|
+
return originalEmit.call(cp, "error", err);
|
|
50425
|
+
}
|
|
50426
|
+
}
|
|
50427
|
+
return originalEmit.apply(cp, arguments);
|
|
50428
|
+
};
|
|
50429
|
+
}
|
|
50430
|
+
function verifyENOENT(status, parsed) {
|
|
50431
|
+
if (isWin && status === 1 && !parsed.file) {
|
|
50432
|
+
return notFoundError(parsed.original, "spawn");
|
|
50433
|
+
}
|
|
50434
|
+
return null;
|
|
50435
|
+
}
|
|
50436
|
+
function verifyENOENTSync(status, parsed) {
|
|
50437
|
+
if (isWin && status === 1 && !parsed.file) {
|
|
50438
|
+
return notFoundError(parsed.original, "spawnSync");
|
|
50439
|
+
}
|
|
50440
|
+
return null;
|
|
50441
|
+
}
|
|
50442
|
+
module.exports = {
|
|
50443
|
+
hookChildProcess,
|
|
50444
|
+
verifyENOENT,
|
|
50445
|
+
verifyENOENTSync,
|
|
50446
|
+
notFoundError
|
|
50447
|
+
};
|
|
50448
|
+
});
|
|
50449
|
+
|
|
50450
|
+
// node_modules/cross-spawn/index.js
|
|
50451
|
+
var require_cross_spawn = __commonJS((exports, module) => {
|
|
50452
|
+
var cp = __require("child_process");
|
|
50453
|
+
var parse7 = require_parse();
|
|
50454
|
+
var enoent = require_enoent();
|
|
50455
|
+
function spawn(command, args, options) {
|
|
50456
|
+
const parsed = parse7(command, args, options);
|
|
50457
|
+
const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);
|
|
50458
|
+
enoent.hookChildProcess(spawned, parsed);
|
|
50459
|
+
return spawned;
|
|
50460
|
+
}
|
|
50461
|
+
function spawnSync(command, args, options) {
|
|
50462
|
+
const parsed = parse7(command, args, options);
|
|
50463
|
+
const result = cp.spawnSync(parsed.command, parsed.args, parsed.options);
|
|
50464
|
+
result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
|
|
50465
|
+
return result;
|
|
50466
|
+
}
|
|
50467
|
+
module.exports = spawn;
|
|
50468
|
+
module.exports.spawn = spawn;
|
|
50469
|
+
module.exports.sync = spawnSync;
|
|
50470
|
+
module.exports._parse = parse7;
|
|
50471
|
+
module.exports._enoent = enoent;
|
|
50472
|
+
});
|
|
50473
|
+
|
|
49613
50474
|
// src/hooks/auto-update-checker/constants.ts
|
|
49614
50475
|
import * as path4 from "path";
|
|
49615
50476
|
import * as os3 from "os";
|
|
@@ -49618,19 +50479,23 @@ function getWindowsAppdataDir() {
|
|
|
49618
50479
|
return null;
|
|
49619
50480
|
return process.env.APPDATA ?? path4.join(os3.homedir(), "AppData", "Roaming");
|
|
49620
50481
|
}
|
|
49621
|
-
|
|
50482
|
+
function getUserConfigDir() {
|
|
50483
|
+
return getOpenCodeConfigDir({ binary: "opencode" });
|
|
50484
|
+
}
|
|
50485
|
+
function getUserOpencodeConfig() {
|
|
50486
|
+
return path4.join(getUserConfigDir(), "opencode.json");
|
|
50487
|
+
}
|
|
50488
|
+
function getUserOpencodeConfigJsonc() {
|
|
50489
|
+
return path4.join(getUserConfigDir(), "opencode.jsonc");
|
|
50490
|
+
}
|
|
50491
|
+
var PACKAGE_NAME2 = "oh-my-opencode", NPM_REGISTRY_URL, NPM_FETCH_TIMEOUT = 5000, CACHE_ROOT_DIR, CACHE_DIR, VERSION_FILE, INSTALLED_PACKAGE_JSON;
|
|
49622
50492
|
var init_constants3 = __esm(() => {
|
|
49623
50493
|
init_data_path();
|
|
49624
50494
|
init_opencode_config_dir();
|
|
49625
|
-
init_plugin_identity();
|
|
49626
|
-
PACKAGE_NAME2 = PLUGIN_NAME;
|
|
49627
50495
|
NPM_REGISTRY_URL = `https://registry.npmjs.org/-/package/${PACKAGE_NAME2}/dist-tags`;
|
|
49628
50496
|
CACHE_ROOT_DIR = getOpenCodeCacheDir();
|
|
49629
50497
|
CACHE_DIR = path4.join(CACHE_ROOT_DIR, "packages");
|
|
49630
50498
|
VERSION_FILE = path4.join(CACHE_ROOT_DIR, "version");
|
|
49631
|
-
USER_CONFIG_DIR = getOpenCodeConfigDir({ binary: "opencode" });
|
|
49632
|
-
USER_OPENCODE_CONFIG = path4.join(USER_CONFIG_DIR, "opencode.json");
|
|
49633
|
-
USER_OPENCODE_CONFIG_JSONC = path4.join(USER_CONFIG_DIR, "opencode.jsonc");
|
|
49634
50499
|
INSTALLED_PACKAGE_JSON = path4.join(CACHE_DIR, "node_modules", PACKAGE_NAME2, "package.json");
|
|
49635
50500
|
});
|
|
49636
50501
|
|
|
@@ -49638,17 +50503,18 @@ var init_constants3 = __esm(() => {
|
|
|
49638
50503
|
import * as os4 from "os";
|
|
49639
50504
|
import * as path5 from "path";
|
|
49640
50505
|
function getConfigPaths(directory) {
|
|
50506
|
+
const userConfigDir = getUserConfigDir();
|
|
49641
50507
|
const paths = [
|
|
49642
50508
|
path5.join(directory, ".opencode", "opencode.json"),
|
|
49643
50509
|
path5.join(directory, ".opencode", "opencode.jsonc"),
|
|
49644
|
-
|
|
49645
|
-
|
|
50510
|
+
getUserOpencodeConfig(),
|
|
50511
|
+
getUserOpencodeConfigJsonc()
|
|
49646
50512
|
];
|
|
49647
50513
|
if (process.platform === "win32") {
|
|
49648
50514
|
const crossPlatformDir = path5.join(os4.homedir(), ".config");
|
|
49649
50515
|
const appdataDir = getWindowsAppdataDir();
|
|
49650
50516
|
if (appdataDir) {
|
|
49651
|
-
const alternateDir =
|
|
50517
|
+
const alternateDir = userConfigDir === crossPlatformDir ? appdataDir : crossPlatformDir;
|
|
49652
50518
|
const alternateConfig = path5.join(alternateDir, "opencode", "opencode.json");
|
|
49653
50519
|
const alternateConfigJsonc = path5.join(alternateDir, "opencode", "opencode.jsonc");
|
|
49654
50520
|
if (!paths.includes(alternateConfig)) {
|
|
@@ -49765,15 +50631,17 @@ function findPluginEntry(directory) {
|
|
|
49765
50631
|
const content = fs7.readFileSync(configPath, "utf-8");
|
|
49766
50632
|
const config2 = JSON.parse(stripJsonComments(content));
|
|
49767
50633
|
const plugins = config2.plugin ?? [];
|
|
49768
|
-
const
|
|
49769
|
-
|
|
49770
|
-
|
|
49771
|
-
|
|
49772
|
-
|
|
50634
|
+
for (const entry of plugins) {
|
|
50635
|
+
for (const pluginName of MATCH_PLUGIN_NAMES) {
|
|
50636
|
+
if (entry === pluginName) {
|
|
50637
|
+
return { entry, isPinned: false, pinnedVersion: null, configPath };
|
|
50638
|
+
}
|
|
50639
|
+
if (entry.startsWith(`${pluginName}@`)) {
|
|
50640
|
+
const pinnedVersion = entry.slice(pluginName.length + 1);
|
|
50641
|
+
const isPinned = EXACT_SEMVER_REGEX.test(pinnedVersion.trim());
|
|
50642
|
+
return { entry, isPinned, pinnedVersion, configPath };
|
|
50643
|
+
}
|
|
49773
50644
|
}
|
|
49774
|
-
const pinnedVersion = entry.slice(managedEntry.packageName.length + 1);
|
|
49775
|
-
const isPinned = EXACT_SEMVER_REGEX.test(pinnedVersion.trim());
|
|
49776
|
-
return { entry, isPinned, pinnedVersion, configPath };
|
|
49777
50645
|
}
|
|
49778
50646
|
} catch {
|
|
49779
50647
|
continue;
|
|
@@ -49781,11 +50649,13 @@ function findPluginEntry(directory) {
|
|
|
49781
50649
|
}
|
|
49782
50650
|
return null;
|
|
49783
50651
|
}
|
|
49784
|
-
var EXACT_SEMVER_REGEX;
|
|
50652
|
+
var EXACT_SEMVER_REGEX, MATCH_PLUGIN_NAMES;
|
|
49785
50653
|
var init_plugin_entry = __esm(() => {
|
|
49786
|
-
|
|
50654
|
+
init_constants3();
|
|
49787
50655
|
init_config_paths();
|
|
50656
|
+
init_plugin_identity();
|
|
49788
50657
|
EXACT_SEMVER_REGEX = /^\d+\.\d+\.\d+(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$/;
|
|
50658
|
+
MATCH_PLUGIN_NAMES = [PACKAGE_NAME2, PLUGIN_NAME, LEGACY_PLUGIN_NAME];
|
|
49789
50659
|
});
|
|
49790
50660
|
|
|
49791
50661
|
// src/hooks/auto-update-checker/checker/cached-version.ts
|
|
@@ -49825,6 +50695,23 @@ function getCachedVersion() {
|
|
|
49825
50695
|
} catch (err) {
|
|
49826
50696
|
log("[auto-update-checker] Failed to resolve version from execPath:", err);
|
|
49827
50697
|
}
|
|
50698
|
+
try {
|
|
50699
|
+
const currentFile = fileURLToPath2(import.meta.url);
|
|
50700
|
+
let dir = path7.dirname(currentFile);
|
|
50701
|
+
for (let i2 = 0;i2 < 10; i2++) {
|
|
50702
|
+
const pkgPath = path7.join(dir, "package.json");
|
|
50703
|
+
if (fs8.existsSync(pkgPath)) {
|
|
50704
|
+
const content = fs8.readFileSync(pkgPath, "utf-8");
|
|
50705
|
+
const pkg = JSON.parse(content);
|
|
50706
|
+
if (pkg.version)
|
|
50707
|
+
return pkg.version;
|
|
50708
|
+
}
|
|
50709
|
+
const parent = path7.dirname(dir);
|
|
50710
|
+
if (parent === dir)
|
|
50711
|
+
break;
|
|
50712
|
+
dir = parent;
|
|
50713
|
+
}
|
|
50714
|
+
} catch {}
|
|
49828
50715
|
return null;
|
|
49829
50716
|
}
|
|
49830
50717
|
var init_cached_version = __esm(() => {
|
|
@@ -50105,8 +50992,9 @@ function removeFromBunLock(packageName) {
|
|
|
50105
50992
|
}
|
|
50106
50993
|
function invalidatePackage(packageName = PACKAGE_NAME2) {
|
|
50107
50994
|
try {
|
|
50995
|
+
const userConfigDir = getUserConfigDir();
|
|
50108
50996
|
const pkgDirs = [
|
|
50109
|
-
path9.join(
|
|
50997
|
+
path9.join(userConfigDir, "node_modules", packageName),
|
|
50110
50998
|
path9.join(CACHE_DIR, "node_modules", packageName)
|
|
50111
50999
|
];
|
|
50112
51000
|
let packageRemoved = false;
|
|
@@ -50142,7 +51030,7 @@ var init_cache = __esm(() => {
|
|
|
50142
51030
|
async function showUpdateAvailableToast(ctx, latestVersion, getToastMessage) {
|
|
50143
51031
|
await ctx.client.tui.showToast({
|
|
50144
51032
|
body: {
|
|
50145
|
-
title: `
|
|
51033
|
+
title: `EvilOMO ${latestVersion}`,
|
|
50146
51034
|
message: getToastMessage(true, latestVersion),
|
|
50147
51035
|
variant: "info",
|
|
50148
51036
|
duration: 8000
|
|
@@ -50153,7 +51041,7 @@ async function showUpdateAvailableToast(ctx, latestVersion, getToastMessage) {
|
|
|
50153
51041
|
async function showAutoUpdatedToast(ctx, oldVersion, newVersion) {
|
|
50154
51042
|
await ctx.client.tui.showToast({
|
|
50155
51043
|
body: {
|
|
50156
|
-
title: "
|
|
51044
|
+
title: "EvilOMO Updated!",
|
|
50157
51045
|
message: `v${oldVersion} \u2192 v${newVersion}
|
|
50158
51046
|
Restart OpenCode to apply.`,
|
|
50159
51047
|
variant: "success",
|
|
@@ -50167,8 +51055,8 @@ var init_update_toasts = __esm(() => {
|
|
|
50167
51055
|
});
|
|
50168
51056
|
|
|
50169
51057
|
// src/hooks/auto-update-checker/hook/background-update-check.ts
|
|
50170
|
-
import { existsSync as
|
|
50171
|
-
import { join as
|
|
51058
|
+
import { existsSync as existsSync24 } from "fs";
|
|
51059
|
+
import { join as join25 } from "path";
|
|
50172
51060
|
function getCacheWorkspaceDir(deps) {
|
|
50173
51061
|
return deps.join(deps.getOpenCodeCacheDir(), "packages");
|
|
50174
51062
|
}
|
|
@@ -50225,8 +51113,8 @@ function createBackgroundUpdateCheckRunner(overrides = {}) {
|
|
|
50225
51113
|
deps.log("[auto-update-checker] Plugin not found in config");
|
|
50226
51114
|
return;
|
|
50227
51115
|
}
|
|
50228
|
-
const
|
|
50229
|
-
const currentVersion =
|
|
51116
|
+
const cachedVersion2 = deps.getCachedVersion();
|
|
51117
|
+
const currentVersion = cachedVersion2 ?? pluginInfo.pinnedVersion;
|
|
50230
51118
|
if (!currentVersion) {
|
|
50231
51119
|
deps.log("[auto-update-checker] No version found (cached or pinned)");
|
|
50232
51120
|
return;
|
|
@@ -50286,8 +51174,8 @@ var init_background_update_check = __esm(() => {
|
|
|
50286
51174
|
init_checker();
|
|
50287
51175
|
init_update_toasts();
|
|
50288
51176
|
defaultDeps = {
|
|
50289
|
-
existsSync:
|
|
50290
|
-
join:
|
|
51177
|
+
existsSync: existsSync24,
|
|
51178
|
+
join: join25,
|
|
50291
51179
|
runBunInstallWithDetails,
|
|
50292
51180
|
log,
|
|
50293
51181
|
getOpenCodeCacheDir,
|
|
@@ -50434,7 +51322,7 @@ async function showSpinnerToast(ctx, version2, message) {
|
|
|
50434
51322
|
const spinner = SISYPHUS_SPINNER[i2 % SISYPHUS_SPINNER.length];
|
|
50435
51323
|
await ctx.client.tui.showToast({
|
|
50436
51324
|
body: {
|
|
50437
|
-
title: `${spinner}
|
|
51325
|
+
title: `${spinner} EvilOMO ${version2}`,
|
|
50438
51326
|
message,
|
|
50439
51327
|
variant: "info",
|
|
50440
51328
|
duration: frameInterval + 50
|
|
@@ -50496,9 +51384,9 @@ v${latestVersion} available. Restart OpenCode to apply.` : "OpenCode is now on S
|
|
|
50496
51384
|
return;
|
|
50497
51385
|
hasChecked = true;
|
|
50498
51386
|
setTimeout(async () => {
|
|
50499
|
-
const
|
|
51387
|
+
const cachedVersion2 = getCachedVersion();
|
|
50500
51388
|
const localDevVersion = getLocalDevVersion(ctx.directory);
|
|
50501
|
-
const displayVersion = localDevVersion ??
|
|
51389
|
+
const displayVersion = localDevVersion ?? cachedVersion2;
|
|
50502
51390
|
await showConfigErrorsIfAny(ctx);
|
|
50503
51391
|
await updateAndShowConnectedProvidersCacheStatus(ctx);
|
|
50504
51392
|
await refreshModelCapabilitiesOnStartup(modelCapabilities);
|
|
@@ -50567,7 +51455,7 @@ var {
|
|
|
50567
51455
|
// package.json
|
|
50568
51456
|
var package_default = {
|
|
50569
51457
|
name: "evil-omo",
|
|
50570
|
-
version: "3.
|
|
51458
|
+
version: "3.16.0",
|
|
50571
51459
|
description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
50572
51460
|
main: "./dist/index.js",
|
|
50573
51461
|
types: "dist/index.d.ts",
|
|
@@ -50626,8 +51514,8 @@ var package_default = {
|
|
|
50626
51514
|
"@clack/prompts": "^0.11.0",
|
|
50627
51515
|
"@code-yeongyu/comment-checker": "^0.7.0",
|
|
50628
51516
|
"@modelcontextprotocol/sdk": "^1.25.2",
|
|
50629
|
-
"@opencode-ai/plugin": "^1.
|
|
50630
|
-
"@opencode-ai/sdk": "^1.
|
|
51517
|
+
"@opencode-ai/plugin": "^1.4.0",
|
|
51518
|
+
"@opencode-ai/sdk": "^1.4.0",
|
|
50631
51519
|
commander: "^14.0.2",
|
|
50632
51520
|
"detect-libc": "^2.0.0",
|
|
50633
51521
|
diff: "^8.0.3",
|
|
@@ -50636,7 +51524,7 @@ var package_default = {
|
|
|
50636
51524
|
picocolors: "^1.1.1",
|
|
50637
51525
|
picomatch: "^4.0.2",
|
|
50638
51526
|
"vscode-jsonrpc": "^8.2.0",
|
|
50639
|
-
zod: "^4.
|
|
51527
|
+
zod: "^4.3.0"
|
|
50640
51528
|
},
|
|
50641
51529
|
devDependencies: {
|
|
50642
51530
|
"@types/js-yaml": "^4.0.9",
|
|
@@ -50645,21 +51533,19 @@ var package_default = {
|
|
|
50645
51533
|
typescript: "^5.7.3"
|
|
50646
51534
|
},
|
|
50647
51535
|
optionalDependencies: {
|
|
50648
|
-
"evil-omo-darwin-arm64": "3.
|
|
50649
|
-
"evil-omo-darwin-x64": "3.
|
|
50650
|
-
"evil-omo-darwin-x64-baseline": "3.
|
|
50651
|
-
"evil-omo-linux-x64": "3.
|
|
50652
|
-
"evil-omo-linux-x64-baseline": "3.
|
|
50653
|
-
"evil-omo-linux-arm64": "3.
|
|
50654
|
-
"evil-omo-linux-x64-musl": "3.
|
|
50655
|
-
"evil-omo-linux-x64-musl-baseline": "3.
|
|
50656
|
-
"evil-omo-linux-arm64-musl": "3.
|
|
50657
|
-
"evil-omo-windows-x64": "3.
|
|
50658
|
-
"evil-omo-windows-x64-baseline": "3.
|
|
50659
|
-
},
|
|
50660
|
-
overrides: {
|
|
50661
|
-
"@opencode-ai/sdk": "^1.2.24"
|
|
51536
|
+
"evil-omo-darwin-arm64": "3.16.0",
|
|
51537
|
+
"evil-omo-darwin-x64": "3.16.0",
|
|
51538
|
+
"evil-omo-darwin-x64-baseline": "3.16.0",
|
|
51539
|
+
"evil-omo-linux-x64": "3.16.0",
|
|
51540
|
+
"evil-omo-linux-x64-baseline": "3.16.0",
|
|
51541
|
+
"evil-omo-linux-arm64": "3.16.0",
|
|
51542
|
+
"evil-omo-linux-x64-musl": "3.16.0",
|
|
51543
|
+
"evil-omo-linux-x64-musl-baseline": "3.16.0",
|
|
51544
|
+
"evil-omo-linux-arm64-musl": "3.16.0",
|
|
51545
|
+
"evil-omo-windows-x64": "3.16.0",
|
|
51546
|
+
"evil-omo-windows-x64-baseline": "3.16.0"
|
|
50662
51547
|
},
|
|
51548
|
+
overrides: {},
|
|
50663
51549
|
trustedDependencies: [
|
|
50664
51550
|
"@ast-grep/cli",
|
|
50665
51551
|
"@ast-grep/napi",
|
|
@@ -50668,8 +51554,9 @@ var package_default = {
|
|
|
50668
51554
|
};
|
|
50669
51555
|
|
|
50670
51556
|
// src/cli/cli-installer.ts
|
|
51557
|
+
init_shared();
|
|
50671
51558
|
init_config_manager();
|
|
50672
|
-
var
|
|
51559
|
+
var import_picocolors3 = __toESM(require_picocolors(), 1);
|
|
50673
51560
|
|
|
50674
51561
|
// src/cli/install-validators.ts
|
|
50675
51562
|
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
@@ -50816,6 +51703,56 @@ function detectedToInitialValues(detected) {
|
|
|
50816
51703
|
};
|
|
50817
51704
|
}
|
|
50818
51705
|
|
|
51706
|
+
// src/cli/doctor/constants.ts
|
|
51707
|
+
init_shared();
|
|
51708
|
+
var import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
51709
|
+
var SYMBOLS2 = {
|
|
51710
|
+
check: import_picocolors2.default.green("\u2713"),
|
|
51711
|
+
cross: import_picocolors2.default.red("\u2717"),
|
|
51712
|
+
warn: import_picocolors2.default.yellow("\u26A0"),
|
|
51713
|
+
info: import_picocolors2.default.blue("\u2139"),
|
|
51714
|
+
arrow: import_picocolors2.default.cyan("\u2192"),
|
|
51715
|
+
bullet: import_picocolors2.default.dim("\u2022"),
|
|
51716
|
+
skip: import_picocolors2.default.dim("\u25CB")
|
|
51717
|
+
};
|
|
51718
|
+
var STATUS_COLORS = {
|
|
51719
|
+
pass: import_picocolors2.default.green,
|
|
51720
|
+
fail: import_picocolors2.default.red,
|
|
51721
|
+
warn: import_picocolors2.default.yellow,
|
|
51722
|
+
skip: import_picocolors2.default.dim
|
|
51723
|
+
};
|
|
51724
|
+
var CHECK_IDS = {
|
|
51725
|
+
SYSTEM: "system",
|
|
51726
|
+
CONFIG: "config",
|
|
51727
|
+
TOOLS: "tools",
|
|
51728
|
+
MODELS: "models"
|
|
51729
|
+
};
|
|
51730
|
+
var CHECK_NAMES = {
|
|
51731
|
+
[CHECK_IDS.SYSTEM]: "System",
|
|
51732
|
+
[CHECK_IDS.CONFIG]: "Configuration",
|
|
51733
|
+
[CHECK_IDS.TOOLS]: "Tools",
|
|
51734
|
+
[CHECK_IDS.MODELS]: "Models"
|
|
51735
|
+
};
|
|
51736
|
+
var EXIT_CODES = {
|
|
51737
|
+
SUCCESS: 0,
|
|
51738
|
+
FAILURE: 1
|
|
51739
|
+
};
|
|
51740
|
+
var MIN_OPENCODE_VERSION = "1.4.0";
|
|
51741
|
+
var PACKAGE_NAME = PLUGIN_NAME;
|
|
51742
|
+
var OPENCODE_BINARIES2 = ["opencode", "opencode-desktop"];
|
|
51743
|
+
|
|
51744
|
+
// src/cli/minimum-opencode-version.ts
|
|
51745
|
+
init_opencode_version();
|
|
51746
|
+
function getUnsupportedOpenCodeVersionMessage(openCodeVersion) {
|
|
51747
|
+
if (!openCodeVersion) {
|
|
51748
|
+
return null;
|
|
51749
|
+
}
|
|
51750
|
+
if (compareVersions(openCodeVersion, MIN_OPENCODE_VERSION) >= 0) {
|
|
51751
|
+
return null;
|
|
51752
|
+
}
|
|
51753
|
+
return `Detected OpenCode ${openCodeVersion}, but ${MIN_OPENCODE_VERSION}+ is required. Update OpenCode, then rerun the installer.`;
|
|
51754
|
+
}
|
|
51755
|
+
|
|
50819
51756
|
// src/cli/cli-installer.ts
|
|
50820
51757
|
async function runCliInstaller(args, version) {
|
|
50821
51758
|
const validation = validateNonTuiArgs(args);
|
|
@@ -50826,7 +51763,7 @@ async function runCliInstaller(args, version) {
|
|
|
50826
51763
|
console.log(` ${SYMBOLS.bullet} ${err}`);
|
|
50827
51764
|
}
|
|
50828
51765
|
console.log();
|
|
50829
|
-
printInfo(
|
|
51766
|
+
printInfo(`Usage: bunx ${PLUGIN_NAME} install --no-tui --claude=<no|yes|max20> --gemini=<no|yes> --copilot=<no|yes>`);
|
|
50830
51767
|
console.log();
|
|
50831
51768
|
return 1;
|
|
50832
51769
|
}
|
|
@@ -50837,65 +51774,60 @@ async function runCliInstaller(args, version) {
|
|
|
50837
51774
|
let step = 1;
|
|
50838
51775
|
printStep(step++, totalSteps, "Checking OpenCode installation...");
|
|
50839
51776
|
const installed = await isOpenCodeInstalled();
|
|
50840
|
-
const openCodeVersion = await
|
|
51777
|
+
const openCodeVersion = await getOpenCodeVersion2();
|
|
50841
51778
|
if (!installed) {
|
|
50842
51779
|
printWarning("OpenCode binary not found. Plugin will be configured, but you'll need to install OpenCode to use it.");
|
|
50843
51780
|
printInfo("Visit https://opencode.ai/docs for installation instructions");
|
|
50844
51781
|
} else {
|
|
50845
51782
|
printSuccess(`OpenCode ${openCodeVersion ?? ""} detected`);
|
|
51783
|
+
const unsupportedVersionMessage = getUnsupportedOpenCodeVersionMessage(openCodeVersion);
|
|
51784
|
+
if (unsupportedVersionMessage) {
|
|
51785
|
+
printWarning(unsupportedVersionMessage);
|
|
51786
|
+
return 1;
|
|
51787
|
+
}
|
|
50846
51788
|
}
|
|
50847
51789
|
if (isUpdate) {
|
|
50848
51790
|
const initial = detectedToInitialValues(detected);
|
|
50849
51791
|
printInfo(`Current config: Claude=${initial.claude}, Gemini=${initial.gemini}`);
|
|
50850
51792
|
}
|
|
50851
51793
|
const config = argsToConfig(args);
|
|
50852
|
-
printStep(step++, totalSteps,
|
|
51794
|
+
printStep(step++, totalSteps, `Adding ${PLUGIN_NAME} plugin...`);
|
|
50853
51795
|
const pluginResult = await addPluginToOpenCodeConfig(version);
|
|
50854
51796
|
if (!pluginResult.success) {
|
|
50855
51797
|
printError(`Failed: ${pluginResult.error}`);
|
|
50856
51798
|
return 1;
|
|
50857
51799
|
}
|
|
50858
|
-
printSuccess(`Plugin ${isUpdate ? "verified" : "added"} ${SYMBOLS.arrow} ${
|
|
50859
|
-
printStep(step++, totalSteps,
|
|
51800
|
+
printSuccess(`Plugin ${isUpdate ? "verified" : "added"} ${SYMBOLS.arrow} ${import_picocolors3.default.dim(pluginResult.configPath)}`);
|
|
51801
|
+
printStep(step++, totalSteps, `Writing ${PLUGIN_NAME} configuration...`);
|
|
50860
51802
|
const omoResult = writeOmoConfig(config);
|
|
50861
51803
|
if (!omoResult.success) {
|
|
50862
51804
|
printError(`Failed: ${omoResult.error}`);
|
|
50863
51805
|
return 1;
|
|
50864
51806
|
}
|
|
50865
|
-
printSuccess(`Config written ${SYMBOLS.arrow} ${
|
|
51807
|
+
printSuccess(`Config written ${SYMBOLS.arrow} ${import_picocolors3.default.dim(omoResult.configPath)}`);
|
|
50866
51808
|
printBox(formatConfigSummary(config), isUpdate ? "Updated Configuration" : "Installation Complete");
|
|
50867
51809
|
if (!config.hasClaude) {
|
|
50868
|
-
|
|
50869
|
-
console.log(import_picocolors2.default.bgRed(import_picocolors2.default.white(import_picocolors2.default.bold(" CRITICAL WARNING "))));
|
|
50870
|
-
console.log();
|
|
50871
|
-
console.log(import_picocolors2.default.red(import_picocolors2.default.bold(" Sisyphus agent is STRONGLY optimized for Claude Opus 4.5.")));
|
|
50872
|
-
console.log(import_picocolors2.default.red(" Without Claude, you may experience significantly degraded performance:"));
|
|
50873
|
-
console.log(import_picocolors2.default.dim(" \u2022 Reduced orchestration quality"));
|
|
50874
|
-
console.log(import_picocolors2.default.dim(" \u2022 Weaker tool selection and delegation"));
|
|
50875
|
-
console.log(import_picocolors2.default.dim(" \u2022 Less reliable task completion"));
|
|
50876
|
-
console.log();
|
|
50877
|
-
console.log(import_picocolors2.default.yellow(" Consider subscribing to Claude Pro/Max for the best experience."));
|
|
50878
|
-
console.log();
|
|
51810
|
+
printInfo("Note: Sisyphus agent performs best with Claude Opus 4.5+. " + "Other models work but may have reduced orchestration quality.");
|
|
50879
51811
|
}
|
|
50880
51812
|
if (!config.hasClaude && !config.hasOpenAI && !config.hasGemini && !config.hasCopilot && !config.hasOpencodeZen) {
|
|
50881
51813
|
printWarning("No model providers configured. Using opencode/big-pickle as fallback.");
|
|
50882
51814
|
}
|
|
50883
|
-
console.log(`${SYMBOLS.star} ${
|
|
50884
|
-
console.log(` Run ${
|
|
51815
|
+
console.log(`${SYMBOLS.star} ${import_picocolors3.default.bold(import_picocolors3.default.green(isUpdate ? "Configuration updated!" : "Installation complete!"))}`);
|
|
51816
|
+
console.log(` Run ${import_picocolors3.default.cyan("opencode")} to start!`);
|
|
50885
51817
|
console.log();
|
|
50886
|
-
printBox(`${
|
|
50887
|
-
` + `All features work like magic
|
|
51818
|
+
printBox(`${import_picocolors3.default.bold("Pro Tip:")} Include ${import_picocolors3.default.cyan("ultrawork")} (or ${import_picocolors3.default.cyan("ulw")}) in your prompt.
|
|
51819
|
+
` + `All features work like magic-parallel agents, background tasks,
|
|
50888
51820
|
` + `deep exploration, and relentless execution until completion.`, "The Magic Word");
|
|
50889
|
-
console.log(`${SYMBOLS.star} ${
|
|
50890
|
-
console.log(` ${
|
|
51821
|
+
console.log(`${SYMBOLS.star} ${import_picocolors3.default.yellow("If you found this helpful, consider starring the repo!")}`);
|
|
51822
|
+
console.log(` ${import_picocolors3.default.dim("gh api --silent --method PUT /user/starred/D4ch1au/evil-oh-my-openagent >/dev/null 2>&1 || true")}`);
|
|
50891
51823
|
console.log();
|
|
50892
|
-
console.log(
|
|
51824
|
+
console.log(import_picocolors3.default.dim("oMoMoMoMo... Enjoy!"));
|
|
50893
51825
|
console.log();
|
|
50894
51826
|
if ((config.hasClaude || config.hasGemini || config.hasCopilot) && !args.skipAuth) {
|
|
50895
|
-
printBox(`Run ${
|
|
50896
|
-
` + (config.hasClaude ? ` ${SYMBOLS.bullet} Anthropic ${
|
|
50897
|
-
` : "") + (config.hasGemini ? ` ${SYMBOLS.bullet} Google ${
|
|
50898
|
-
` : "") + (config.hasCopilot ? ` ${SYMBOLS.bullet} GitHub ${
|
|
51827
|
+
printBox(`Run ${import_picocolors3.default.cyan("opencode auth login")} and select your provider:
|
|
51828
|
+
` + (config.hasClaude ? ` ${SYMBOLS.bullet} Anthropic ${import_picocolors3.default.gray("\u2192 Claude Pro/Max")}
|
|
51829
|
+
` : "") + (config.hasGemini ? ` ${SYMBOLS.bullet} Google ${import_picocolors3.default.gray("\u2192 Gemini")}
|
|
51830
|
+
` : "") + (config.hasCopilot ? ` ${SYMBOLS.bullet} GitHub ${import_picocolors3.default.gray("\u2192 Copilot")}` : ""), "Authenticate Your Providers");
|
|
50899
51831
|
}
|
|
50900
51832
|
return 0;
|
|
50901
51833
|
}
|
|
@@ -51290,7 +52222,7 @@ class LD extends x {
|
|
|
51290
52222
|
}
|
|
51291
52223
|
|
|
51292
52224
|
// node_modules/@clack/prompts/dist/index.mjs
|
|
51293
|
-
var
|
|
52225
|
+
var import_picocolors4 = __toESM(require_picocolors(), 1);
|
|
51294
52226
|
var import_sisteransi2 = __toESM(require_src(), 1);
|
|
51295
52227
|
import y2 from "process";
|
|
51296
52228
|
function ce() {
|
|
@@ -51323,13 +52255,13 @@ var b2 = (t) => {
|
|
|
51323
52255
|
switch (t) {
|
|
51324
52256
|
case "initial":
|
|
51325
52257
|
case "active":
|
|
51326
|
-
return
|
|
52258
|
+
return import_picocolors4.default.cyan(le);
|
|
51327
52259
|
case "cancel":
|
|
51328
|
-
return
|
|
52260
|
+
return import_picocolors4.default.red(L2);
|
|
51329
52261
|
case "error":
|
|
51330
|
-
return
|
|
52262
|
+
return import_picocolors4.default.yellow(W2);
|
|
51331
52263
|
case "submit":
|
|
51332
|
-
return
|
|
52264
|
+
return import_picocolors4.default.green(C);
|
|
51333
52265
|
}
|
|
51334
52266
|
};
|
|
51335
52267
|
var G2 = (t) => {
|
|
@@ -51339,7 +52271,7 @@ var G2 = (t) => {
|
|
|
51339
52271
|
const $2 = a < r2.length && l2 > 0, g2 = a < r2.length && l2 + a < r2.length;
|
|
51340
52272
|
return r2.slice(l2, l2 + a).map((p2, v, f) => {
|
|
51341
52273
|
const j2 = v === 0 && $2, E = v === f.length - 1 && g2;
|
|
51342
|
-
return j2 || E ?
|
|
52274
|
+
return j2 || E ? import_picocolors4.default.dim("...") : i2(p2, v + l2 === n);
|
|
51343
52275
|
});
|
|
51344
52276
|
};
|
|
51345
52277
|
var ve = (t) => {
|
|
@@ -51347,29 +52279,29 @@ var ve = (t) => {
|
|
|
51347
52279
|
const s = r2.label ?? String(r2.value);
|
|
51348
52280
|
switch (i2) {
|
|
51349
52281
|
case "selected":
|
|
51350
|
-
return `${
|
|
52282
|
+
return `${import_picocolors4.default.dim(s)}`;
|
|
51351
52283
|
case "active":
|
|
51352
|
-
return `${
|
|
52284
|
+
return `${import_picocolors4.default.green(k2)} ${s} ${r2.hint ? import_picocolors4.default.dim(`(${r2.hint})`) : ""}`;
|
|
51353
52285
|
case "cancelled":
|
|
51354
|
-
return `${
|
|
52286
|
+
return `${import_picocolors4.default.strikethrough(import_picocolors4.default.dim(s))}`;
|
|
51355
52287
|
default:
|
|
51356
|
-
return `${
|
|
52288
|
+
return `${import_picocolors4.default.dim(P2)} ${import_picocolors4.default.dim(s)}`;
|
|
51357
52289
|
}
|
|
51358
52290
|
};
|
|
51359
52291
|
return new LD({ options: t.options, initialValue: t.initialValue, render() {
|
|
51360
|
-
const r2 = `${
|
|
52292
|
+
const r2 = `${import_picocolors4.default.gray(o)}
|
|
51361
52293
|
${b2(this.state)} ${t.message}
|
|
51362
52294
|
`;
|
|
51363
52295
|
switch (this.state) {
|
|
51364
52296
|
case "submit":
|
|
51365
|
-
return `${r2}${
|
|
52297
|
+
return `${r2}${import_picocolors4.default.gray(o)} ${n(this.options[this.cursor], "selected")}`;
|
|
51366
52298
|
case "cancel":
|
|
51367
|
-
return `${r2}${
|
|
51368
|
-
${
|
|
52299
|
+
return `${r2}${import_picocolors4.default.gray(o)} ${n(this.options[this.cursor], "cancelled")}
|
|
52300
|
+
${import_picocolors4.default.gray(o)}`;
|
|
51369
52301
|
default:
|
|
51370
|
-
return `${r2}${
|
|
51371
|
-
${
|
|
51372
|
-
${
|
|
52302
|
+
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(`
|
|
52303
|
+
${import_picocolors4.default.cyan(o)} `)}
|
|
52304
|
+
${import_picocolors4.default.cyan(d2)}
|
|
51373
52305
|
`;
|
|
51374
52306
|
}
|
|
51375
52307
|
} }).prompt();
|
|
@@ -51381,53 +52313,53 @@ ${t}
|
|
|
51381
52313
|
`), i2 = S2(n).length, s = Math.max(r2.reduce((a, l2) => {
|
|
51382
52314
|
const $2 = S2(l2);
|
|
51383
52315
|
return $2.length > a ? $2.length : a;
|
|
51384
|
-
}, 0), i2) + 2, c = r2.map((a) => `${
|
|
52316
|
+
}, 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(`
|
|
51385
52317
|
`);
|
|
51386
|
-
process.stdout.write(`${
|
|
51387
|
-
${
|
|
52318
|
+
process.stdout.write(`${import_picocolors4.default.gray(o)}
|
|
52319
|
+
${import_picocolors4.default.green(C)} ${import_picocolors4.default.reset(n)} ${import_picocolors4.default.gray(_2.repeat(Math.max(s - i2 - 1, 1)) + me)}
|
|
51388
52320
|
${c}
|
|
51389
|
-
${
|
|
52321
|
+
${import_picocolors4.default.gray(de + _2.repeat(s + 2) + pe)}
|
|
51390
52322
|
`);
|
|
51391
52323
|
};
|
|
51392
52324
|
var xe = (t = "") => {
|
|
51393
|
-
process.stdout.write(`${
|
|
52325
|
+
process.stdout.write(`${import_picocolors4.default.gray(d2)} ${import_picocolors4.default.red(t)}
|
|
51394
52326
|
|
|
51395
52327
|
`);
|
|
51396
52328
|
};
|
|
51397
52329
|
var Ie = (t = "") => {
|
|
51398
|
-
process.stdout.write(`${
|
|
52330
|
+
process.stdout.write(`${import_picocolors4.default.gray(ue)} ${t}
|
|
51399
52331
|
`);
|
|
51400
52332
|
};
|
|
51401
52333
|
var Se = (t = "") => {
|
|
51402
|
-
process.stdout.write(`${
|
|
51403
|
-
${
|
|
52334
|
+
process.stdout.write(`${import_picocolors4.default.gray(o)}
|
|
52335
|
+
${import_picocolors4.default.gray(d2)} ${t}
|
|
51404
52336
|
|
|
51405
52337
|
`);
|
|
51406
52338
|
};
|
|
51407
|
-
var M2 = { message: (t = "", { symbol: n =
|
|
51408
|
-
const r2 = [`${
|
|
52339
|
+
var M2 = { message: (t = "", { symbol: n = import_picocolors4.default.gray(o) } = {}) => {
|
|
52340
|
+
const r2 = [`${import_picocolors4.default.gray(o)}`];
|
|
51409
52341
|
if (t) {
|
|
51410
52342
|
const [i2, ...s] = t.split(`
|
|
51411
52343
|
`);
|
|
51412
|
-
r2.push(`${n} ${i2}`, ...s.map((c) => `${
|
|
52344
|
+
r2.push(`${n} ${i2}`, ...s.map((c) => `${import_picocolors4.default.gray(o)} ${c}`));
|
|
51413
52345
|
}
|
|
51414
52346
|
process.stdout.write(`${r2.join(`
|
|
51415
52347
|
`)}
|
|
51416
52348
|
`);
|
|
51417
52349
|
}, info: (t) => {
|
|
51418
|
-
M2.message(t, { symbol:
|
|
52350
|
+
M2.message(t, { symbol: import_picocolors4.default.blue(q) });
|
|
51419
52351
|
}, success: (t) => {
|
|
51420
|
-
M2.message(t, { symbol:
|
|
52352
|
+
M2.message(t, { symbol: import_picocolors4.default.green(D) });
|
|
51421
52353
|
}, step: (t) => {
|
|
51422
|
-
M2.message(t, { symbol:
|
|
52354
|
+
M2.message(t, { symbol: import_picocolors4.default.green(C) });
|
|
51423
52355
|
}, warn: (t) => {
|
|
51424
|
-
M2.message(t, { symbol:
|
|
52356
|
+
M2.message(t, { symbol: import_picocolors4.default.yellow(U) });
|
|
51425
52357
|
}, warning: (t) => {
|
|
51426
52358
|
M2.warn(t);
|
|
51427
52359
|
}, error: (t) => {
|
|
51428
|
-
M2.message(t, { symbol:
|
|
52360
|
+
M2.message(t, { symbol: import_picocolors4.default.red(K2) });
|
|
51429
52361
|
} };
|
|
51430
|
-
var J2 = `${
|
|
52362
|
+
var J2 = `${import_picocolors4.default.gray(o)} `;
|
|
51431
52363
|
var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
51432
52364
|
const n = V2 ? ["\u25D2", "\u25D0", "\u25D3", "\u25D1"] : ["\u2022", "o", "O", "0"], r2 = V2 ? 80 : 120, i2 = process.env.CI === "true";
|
|
51433
52365
|
let s, c, a = false, l2 = "", $2, g2 = performance.now();
|
|
@@ -51450,14 +52382,14 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
51450
52382
|
const h2 = (performance.now() - m2) / 1000, w2 = Math.floor(h2 / 60), I2 = Math.floor(h2 % 60);
|
|
51451
52383
|
return w2 > 0 ? `[${w2}m ${I2}s]` : `[${I2}s]`;
|
|
51452
52384
|
}, H = (m2 = "") => {
|
|
51453
|
-
a = true, s = fD(), l2 = R2(m2), g2 = performance.now(), process.stdout.write(`${
|
|
52385
|
+
a = true, s = fD(), l2 = R2(m2), g2 = performance.now(), process.stdout.write(`${import_picocolors4.default.gray(o)}
|
|
51454
52386
|
`);
|
|
51455
52387
|
let h2 = 0, w2 = 0;
|
|
51456
52388
|
j2(), c = setInterval(() => {
|
|
51457
52389
|
if (i2 && l2 === $2)
|
|
51458
52390
|
return;
|
|
51459
52391
|
B2(), $2 = l2;
|
|
51460
|
-
const I2 =
|
|
52392
|
+
const I2 = import_picocolors4.default.magenta(n[h2]);
|
|
51461
52393
|
if (i2)
|
|
51462
52394
|
process.stdout.write(`${I2} ${l2}...`);
|
|
51463
52395
|
else if (t === "timer")
|
|
@@ -51470,7 +52402,7 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
51470
52402
|
}, r2);
|
|
51471
52403
|
}, N2 = (m2 = "", h2 = 0) => {
|
|
51472
52404
|
a = false, clearInterval(c), B2();
|
|
51473
|
-
const w2 = h2 === 0 ?
|
|
52405
|
+
const w2 = h2 === 0 ? import_picocolors4.default.green(C) : h2 === 1 ? import_picocolors4.default.red(L2) : import_picocolors4.default.red(W2);
|
|
51474
52406
|
l2 = R2(m2 ?? l2), t === "timer" ? process.stdout.write(`${w2} ${l2} ${O2(g2)}
|
|
51475
52407
|
`) : process.stdout.write(`${w2} ${l2}
|
|
51476
52408
|
`), E(), s();
|
|
@@ -51481,8 +52413,9 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
51481
52413
|
};
|
|
51482
52414
|
|
|
51483
52415
|
// src/cli/tui-installer.ts
|
|
52416
|
+
init_shared();
|
|
51484
52417
|
init_config_manager();
|
|
51485
|
-
var
|
|
52418
|
+
var import_picocolors5 = __toESM(require_picocolors(), 1);
|
|
51486
52419
|
|
|
51487
52420
|
// src/cli/tui-install-prompts.ts
|
|
51488
52421
|
async function selectOrCancel(params) {
|
|
@@ -51603,7 +52536,7 @@ async function runTuiInstaller(args, version) {
|
|
|
51603
52536
|
}
|
|
51604
52537
|
const detected = detectCurrentConfig();
|
|
51605
52538
|
const isUpdate = detected.isInstalled;
|
|
51606
|
-
Ie(
|
|
52539
|
+
Ie(import_picocolors5.default.bgMagenta(import_picocolors5.default.white(isUpdate ? " oMoMoMoMo... Update " : " oMoMoMoMo... ")));
|
|
51607
52540
|
if (isUpdate) {
|
|
51608
52541
|
const initial = detectedToInitialValues(detected);
|
|
51609
52542
|
M2.info(`Existing configuration detected: Claude=${initial.claude}, Gemini=${initial.gemini}`);
|
|
@@ -51611,70 +52544,67 @@ async function runTuiInstaller(args, version) {
|
|
|
51611
52544
|
const spinner = Y2();
|
|
51612
52545
|
spinner.start("Checking OpenCode installation");
|
|
51613
52546
|
const installed = await isOpenCodeInstalled();
|
|
51614
|
-
const openCodeVersion = await
|
|
52547
|
+
const openCodeVersion = await getOpenCodeVersion2();
|
|
51615
52548
|
if (!installed) {
|
|
51616
|
-
spinner.stop(`OpenCode binary not found ${
|
|
52549
|
+
spinner.stop(`OpenCode binary not found ${import_picocolors5.default.yellow("[!]")}`);
|
|
51617
52550
|
M2.warn("OpenCode binary not found. Plugin will be configured, but you'll need to install OpenCode to use it.");
|
|
51618
52551
|
Me("Visit https://opencode.ai/docs for installation instructions", "Installation Guide");
|
|
51619
52552
|
} else {
|
|
51620
|
-
spinner.stop(`OpenCode ${openCodeVersion ?? "installed"} ${
|
|
52553
|
+
spinner.stop(`OpenCode ${openCodeVersion ?? "installed"} ${import_picocolors5.default.green("[OK]")}`);
|
|
52554
|
+
const unsupportedVersionMessage = getUnsupportedOpenCodeVersionMessage(openCodeVersion);
|
|
52555
|
+
if (unsupportedVersionMessage) {
|
|
52556
|
+
M2.warn(unsupportedVersionMessage);
|
|
52557
|
+
Se(import_picocolors5.default.red("Installation blocked."));
|
|
52558
|
+
return 1;
|
|
52559
|
+
}
|
|
51621
52560
|
}
|
|
51622
52561
|
const config = await promptInstallConfig(detected);
|
|
51623
52562
|
if (!config)
|
|
51624
52563
|
return 1;
|
|
51625
|
-
spinner.start(
|
|
52564
|
+
spinner.start(`Adding ${PLUGIN_NAME} to OpenCode config`);
|
|
51626
52565
|
const pluginResult = await addPluginToOpenCodeConfig(version);
|
|
51627
52566
|
if (!pluginResult.success) {
|
|
51628
52567
|
spinner.stop(`Failed to add plugin: ${pluginResult.error}`);
|
|
51629
|
-
Se(
|
|
52568
|
+
Se(import_picocolors5.default.red("Installation failed."));
|
|
51630
52569
|
return 1;
|
|
51631
52570
|
}
|
|
51632
|
-
spinner.stop(`Plugin added to ${
|
|
51633
|
-
spinner.start(
|
|
52571
|
+
spinner.stop(`Plugin added to ${import_picocolors5.default.cyan(pluginResult.configPath)}`);
|
|
52572
|
+
spinner.start(`Writing ${PLUGIN_NAME} configuration`);
|
|
51634
52573
|
const omoResult = writeOmoConfig(config);
|
|
51635
52574
|
if (!omoResult.success) {
|
|
51636
52575
|
spinner.stop(`Failed to write config: ${omoResult.error}`);
|
|
51637
|
-
Se(
|
|
52576
|
+
Se(import_picocolors5.default.red("Installation failed."));
|
|
51638
52577
|
return 1;
|
|
51639
52578
|
}
|
|
51640
|
-
spinner.stop(`Config written to ${
|
|
52579
|
+
spinner.stop(`Config written to ${import_picocolors5.default.cyan(omoResult.configPath)}`);
|
|
51641
52580
|
if (!config.hasClaude) {
|
|
51642
|
-
|
|
51643
|
-
|
|
51644
|
-
console.log();
|
|
51645
|
-
console.log(import_picocolors4.default.red(import_picocolors4.default.bold(" Sisyphus agent is STRONGLY optimized for Claude Opus 4.5.")));
|
|
51646
|
-
console.log(import_picocolors4.default.red(" Without Claude, you may experience significantly degraded performance:"));
|
|
51647
|
-
console.log(import_picocolors4.default.dim(" \u2022 Reduced orchestration quality"));
|
|
51648
|
-
console.log(import_picocolors4.default.dim(" \u2022 Weaker tool selection and delegation"));
|
|
51649
|
-
console.log(import_picocolors4.default.dim(" \u2022 Less reliable task completion"));
|
|
51650
|
-
console.log();
|
|
51651
|
-
console.log(import_picocolors4.default.yellow(" Consider subscribing to Claude Pro/Max for the best experience."));
|
|
51652
|
-
console.log();
|
|
52581
|
+
M2.info(`${import_picocolors5.default.bold("Note:")} Sisyphus agent performs best with Claude Opus 4.5+.
|
|
52582
|
+
` + `Other models work but may have reduced orchestration quality.`);
|
|
51653
52583
|
}
|
|
51654
52584
|
if (!config.hasClaude && !config.hasOpenAI && !config.hasGemini && !config.hasCopilot && !config.hasOpencodeZen) {
|
|
51655
52585
|
M2.warn("No model providers configured. Using opencode/big-pickle as fallback.");
|
|
51656
52586
|
}
|
|
51657
52587
|
Me(formatConfigSummary(config), isUpdate ? "Updated Configuration" : "Installation Complete");
|
|
51658
|
-
M2.success(
|
|
51659
|
-
M2.message(`Run ${
|
|
51660
|
-
Me(`Include ${
|
|
51661
|
-
` + `All features work like magic
|
|
52588
|
+
M2.success(import_picocolors5.default.bold(isUpdate ? "Configuration updated!" : "Installation complete!"));
|
|
52589
|
+
M2.message(`Run ${import_picocolors5.default.cyan("opencode")} to start!`);
|
|
52590
|
+
Me(`Include ${import_picocolors5.default.cyan("ultrawork")} (or ${import_picocolors5.default.cyan("ulw")}) in your prompt.
|
|
52591
|
+
` + `All features work like magic-parallel agents, background tasks,
|
|
51662
52592
|
` + `deep exploration, and relentless execution until completion.`, "The Magic Word");
|
|
51663
|
-
M2.message(`${
|
|
51664
|
-
M2.message(` ${
|
|
51665
|
-
Se(
|
|
52593
|
+
M2.message(`${import_picocolors5.default.yellow("\u2605")} If you found this helpful, consider starring the repo!`);
|
|
52594
|
+
M2.message(` ${import_picocolors5.default.dim("gh api --silent --method PUT /user/starred/D4ch1au/evil-oh-my-openagent >/dev/null 2>&1 || true")}`);
|
|
52595
|
+
Se(import_picocolors5.default.green("oMoMoMoMo... Enjoy!"));
|
|
51666
52596
|
if ((config.hasClaude || config.hasGemini || config.hasCopilot) && !args.skipAuth) {
|
|
51667
52597
|
const providers = [];
|
|
51668
52598
|
if (config.hasClaude)
|
|
51669
|
-
providers.push(`Anthropic ${
|
|
52599
|
+
providers.push(`Anthropic ${import_picocolors5.default.gray("\u2192 Claude Pro/Max")}`);
|
|
51670
52600
|
if (config.hasGemini)
|
|
51671
|
-
providers.push(`Google ${
|
|
52601
|
+
providers.push(`Google ${import_picocolors5.default.gray("\u2192 Gemini")}`);
|
|
51672
52602
|
if (config.hasCopilot)
|
|
51673
|
-
providers.push(`GitHub ${
|
|
52603
|
+
providers.push(`GitHub ${import_picocolors5.default.gray("\u2192 Copilot")}`);
|
|
51674
52604
|
console.log();
|
|
51675
|
-
console.log(
|
|
52605
|
+
console.log(import_picocolors5.default.bold("Authenticate Your Providers"));
|
|
51676
52606
|
console.log();
|
|
51677
|
-
console.log(` Run ${
|
|
52607
|
+
console.log(` Run ${import_picocolors5.default.cyan("opencode auth login")} and select:`);
|
|
51678
52608
|
for (const provider of providers) {
|
|
51679
52609
|
console.log(` ${SYMBOLS.bullet} ${provider}`);
|
|
51680
52610
|
}
|
|
@@ -51690,7 +52620,7 @@ async function install(args) {
|
|
|
51690
52620
|
}
|
|
51691
52621
|
|
|
51692
52622
|
// src/cli/run/runner.ts
|
|
51693
|
-
var
|
|
52623
|
+
var import_picocolors15 = __toESM(require_picocolors(), 1);
|
|
51694
52624
|
|
|
51695
52625
|
// src/cli/run/event-state.ts
|
|
51696
52626
|
function createEventState() {
|
|
@@ -51724,7 +52654,7 @@ function createEventState() {
|
|
|
51724
52654
|
};
|
|
51725
52655
|
}
|
|
51726
52656
|
// src/cli/run/event-formatting.ts
|
|
51727
|
-
var
|
|
52657
|
+
var import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
51728
52658
|
function serializeError(error) {
|
|
51729
52659
|
if (!error)
|
|
51730
52660
|
return "Unknown error";
|
|
@@ -51768,10 +52698,10 @@ function getSessionTag(ctx, payload) {
|
|
|
51768
52698
|
const sessionID = props?.sessionID ?? props?.sessionId ?? info?.sessionID ?? info?.sessionId ?? part?.sessionID ?? part?.sessionId;
|
|
51769
52699
|
const isMainSession = sessionID === ctx.sessionID;
|
|
51770
52700
|
if (isMainSession)
|
|
51771
|
-
return
|
|
52701
|
+
return import_picocolors6.default.green("[MAIN]");
|
|
51772
52702
|
if (sessionID)
|
|
51773
|
-
return
|
|
51774
|
-
return
|
|
52703
|
+
return import_picocolors6.default.yellow(`[${String(sessionID).slice(0, 8)}]`);
|
|
52704
|
+
return import_picocolors6.default.dim("[system]");
|
|
51775
52705
|
}
|
|
51776
52706
|
function logEventVerbose(ctx, payload) {
|
|
51777
52707
|
const sessionTag = getSessionTag(ctx, payload);
|
|
@@ -51780,7 +52710,7 @@ function logEventVerbose(ctx, payload) {
|
|
|
51780
52710
|
case "session.idle":
|
|
51781
52711
|
case "session.status": {
|
|
51782
52712
|
const status = props?.status?.type ?? "idle";
|
|
51783
|
-
console.error(
|
|
52713
|
+
console.error(import_picocolors6.default.dim(`${sessionTag} ${payload.type}: ${status}`));
|
|
51784
52714
|
break;
|
|
51785
52715
|
}
|
|
51786
52716
|
case "message.part.updated": {
|
|
@@ -51788,10 +52718,10 @@ function logEventVerbose(ctx, payload) {
|
|
|
51788
52718
|
const part = partProps?.part;
|
|
51789
52719
|
if (part?.type === "tool") {
|
|
51790
52720
|
const status = part.state?.status ?? "unknown";
|
|
51791
|
-
console.error(
|
|
52721
|
+
console.error(import_picocolors6.default.dim(`${sessionTag} message.part (tool): ${part.tool ?? part.name ?? "?"} [${status}]`));
|
|
51792
52722
|
} else if (part?.type === "text" && part.text) {
|
|
51793
52723
|
const preview = part.text.slice(0, 80).replace(/\n/g, "\\n");
|
|
51794
|
-
console.error(
|
|
52724
|
+
console.error(import_picocolors6.default.dim(`${sessionTag} message.part (text): "${preview}${part.text.length > 80 ? "..." : ""}"`));
|
|
51795
52725
|
}
|
|
51796
52726
|
break;
|
|
51797
52727
|
}
|
|
@@ -51800,7 +52730,7 @@ function logEventVerbose(ctx, payload) {
|
|
|
51800
52730
|
const field = deltaProps?.field ?? "unknown";
|
|
51801
52731
|
const delta = deltaProps?.delta ?? "";
|
|
51802
52732
|
const preview = delta.slice(0, 80).replace(/\n/g, "\\n");
|
|
51803
|
-
console.error(
|
|
52733
|
+
console.error(import_picocolors6.default.dim(`${sessionTag} message.part.delta (${field}): "${preview}${delta.length > 80 ? "..." : ""}"`));
|
|
51804
52734
|
break;
|
|
51805
52735
|
}
|
|
51806
52736
|
case "message.updated": {
|
|
@@ -51809,7 +52739,7 @@ function logEventVerbose(ctx, payload) {
|
|
|
51809
52739
|
const model = msgProps?.info?.modelID;
|
|
51810
52740
|
const agent = msgProps?.info?.agent;
|
|
51811
52741
|
const details = [role, agent, model].filter(Boolean).join(", ");
|
|
51812
|
-
console.error(
|
|
52742
|
+
console.error(import_picocolors6.default.dim(`${sessionTag} message.updated (${details})`));
|
|
51813
52743
|
break;
|
|
51814
52744
|
}
|
|
51815
52745
|
case "tool.execute": {
|
|
@@ -51827,32 +52757,32 @@ function logEventVerbose(ctx, payload) {
|
|
|
51827
52757
|
}
|
|
51828
52758
|
}
|
|
51829
52759
|
const inputPreview = inputStr.slice(0, 150);
|
|
51830
|
-
console.error(
|
|
51831
|
-
console.error(
|
|
52760
|
+
console.error(import_picocolors6.default.cyan(`${sessionTag} TOOL.EXECUTE: ${import_picocolors6.default.bold(toolName)}`));
|
|
52761
|
+
console.error(import_picocolors6.default.dim(` input: ${inputPreview}${inputStr.length >= 150 ? "..." : ""}`));
|
|
51832
52762
|
break;
|
|
51833
52763
|
}
|
|
51834
52764
|
case "tool.result": {
|
|
51835
52765
|
const resultProps = props;
|
|
51836
52766
|
const output = resultProps?.output ?? "";
|
|
51837
52767
|
const preview = output.slice(0, 200).replace(/\n/g, "\\n");
|
|
51838
|
-
console.error(
|
|
52768
|
+
console.error(import_picocolors6.default.green(`${sessionTag} TOOL.RESULT: "${preview}${output.length > 200 ? "..." : ""}"`));
|
|
51839
52769
|
break;
|
|
51840
52770
|
}
|
|
51841
52771
|
case "session.error": {
|
|
51842
52772
|
const errorProps = props;
|
|
51843
52773
|
const errorMsg = serializeError(errorProps?.error);
|
|
51844
|
-
console.error(
|
|
52774
|
+
console.error(import_picocolors6.default.red(`${sessionTag} SESSION.ERROR: ${errorMsg}`));
|
|
51845
52775
|
break;
|
|
51846
52776
|
}
|
|
51847
52777
|
default:
|
|
51848
|
-
console.error(
|
|
52778
|
+
console.error(import_picocolors6.default.dim(`${sessionTag} ${payload.type}`));
|
|
51849
52779
|
}
|
|
51850
52780
|
}
|
|
51851
52781
|
// src/cli/run/event-stream-processor.ts
|
|
51852
|
-
var
|
|
52782
|
+
var import_picocolors9 = __toESM(require_picocolors(), 1);
|
|
51853
52783
|
|
|
51854
52784
|
// src/cli/run/event-handlers.ts
|
|
51855
|
-
var
|
|
52785
|
+
var import_picocolors8 = __toESM(require_picocolors(), 1);
|
|
51856
52786
|
|
|
51857
52787
|
// src/cli/run/tool-input-preview.ts
|
|
51858
52788
|
function formatToolHeader(toolName, input) {
|
|
@@ -51988,14 +52918,14 @@ var displayChars = {
|
|
|
51988
52918
|
};
|
|
51989
52919
|
|
|
51990
52920
|
// src/cli/run/output-renderer.ts
|
|
51991
|
-
var
|
|
52921
|
+
var import_picocolors7 = __toESM(require_picocolors(), 1);
|
|
51992
52922
|
function renderAgentHeader(agent, model, variant, agentColorsByName) {
|
|
51993
52923
|
if (!agent && !model)
|
|
51994
52924
|
return;
|
|
51995
|
-
const agentLabel = agent ?
|
|
52925
|
+
const agentLabel = agent ? import_picocolors7.default.bold(colorizeWithProfileColor(agent, agentColorsByName[agent])) : "";
|
|
51996
52926
|
const modelBase = model ?? "";
|
|
51997
52927
|
const variantSuffix = variant ? ` (${variant})` : "";
|
|
51998
|
-
const modelLabel = model ?
|
|
52928
|
+
const modelLabel = model ? import_picocolors7.default.dim(`${modelBase}${variantSuffix}`) : "";
|
|
51999
52929
|
process.stdout.write(`
|
|
52000
52930
|
`);
|
|
52001
52931
|
if (modelLabel) {
|
|
@@ -52003,7 +52933,7 @@ function renderAgentHeader(agent, model, variant, agentColorsByName) {
|
|
|
52003
52933
|
`);
|
|
52004
52934
|
}
|
|
52005
52935
|
if (agentLabel) {
|
|
52006
|
-
process.stdout.write(` ${
|
|
52936
|
+
process.stdout.write(` ${import_picocolors7.default.dim("\u2514\u2500")} ${agentLabel}
|
|
52007
52937
|
`);
|
|
52008
52938
|
}
|
|
52009
52939
|
process.stdout.write(`
|
|
@@ -52011,7 +52941,7 @@ function renderAgentHeader(agent, model, variant, agentColorsByName) {
|
|
|
52011
52941
|
}
|
|
52012
52942
|
function openThinkBlock() {
|
|
52013
52943
|
process.stdout.write(`
|
|
52014
|
-
${
|
|
52944
|
+
${import_picocolors7.default.dim("\u2503 Thinking:")} `);
|
|
52015
52945
|
}
|
|
52016
52946
|
function closeThinkBlock() {
|
|
52017
52947
|
process.stdout.write(`
|
|
@@ -52045,10 +52975,10 @@ function writePaddedText(text, atLineStart) {
|
|
|
52045
52975
|
}
|
|
52046
52976
|
function colorizeWithProfileColor(text, hexColor) {
|
|
52047
52977
|
if (!hexColor)
|
|
52048
|
-
return
|
|
52978
|
+
return import_picocolors7.default.magenta(text);
|
|
52049
52979
|
const rgb = parseHexColor(hexColor);
|
|
52050
52980
|
if (!rgb)
|
|
52051
|
-
return
|
|
52981
|
+
return import_picocolors7.default.magenta(text);
|
|
52052
52982
|
const [r2, g2, b3] = rgb;
|
|
52053
52983
|
return `\x1B[38;2;${r2};${g2};${b3}m${text}\x1B[39m`;
|
|
52054
52984
|
}
|
|
@@ -52088,7 +53018,7 @@ function renderCompletionMetaLine(state, messageID) {
|
|
|
52088
53018
|
const agent = state.currentAgent ?? "assistant";
|
|
52089
53019
|
const model = state.currentModel ?? "unknown-model";
|
|
52090
53020
|
const variant = state.currentVariant ? ` (${state.currentVariant})` : "";
|
|
52091
|
-
process.stdout.write(
|
|
53021
|
+
process.stdout.write(import_picocolors8.default.dim(`
|
|
52092
53022
|
${displayChars.treeEnd} ${agent} \xB7 ${model}${variant} \xB7 ${elapsedSec}s
|
|
52093
53023
|
`));
|
|
52094
53024
|
state.completionMetaPrintedByMessageId[messageID] = true;
|
|
@@ -52122,7 +53052,7 @@ function handleSessionError(ctx, payload, state) {
|
|
|
52122
53052
|
if (getSessionId(props) === ctx.sessionID) {
|
|
52123
53053
|
state.mainSessionError = true;
|
|
52124
53054
|
state.lastError = serializeError(props?.error);
|
|
52125
|
-
console.error(
|
|
53055
|
+
console.error(import_picocolors8.default.red(`
|
|
52126
53056
|
[session.error] ${state.lastError}`));
|
|
52127
53057
|
}
|
|
52128
53058
|
}
|
|
@@ -52150,7 +53080,7 @@ function handleMessagePartUpdated(ctx, payload, state) {
|
|
|
52150
53080
|
const newText = reasoningText.slice(state.lastReasoningText.length);
|
|
52151
53081
|
if (newText) {
|
|
52152
53082
|
const padded = writePaddedText(newText, state.thinkingAtLineStart);
|
|
52153
|
-
process.stdout.write(
|
|
53083
|
+
process.stdout.write(import_picocolors8.default.dim(padded.output));
|
|
52154
53084
|
state.thinkingAtLineStart = padded.atLineStart;
|
|
52155
53085
|
state.hasReceivedMeaningfulWork = true;
|
|
52156
53086
|
}
|
|
@@ -52197,7 +53127,7 @@ function handleMessagePartDelta(ctx, payload, state) {
|
|
|
52197
53127
|
if (partType === "reasoning") {
|
|
52198
53128
|
ensureThinkBlockOpen(state);
|
|
52199
53129
|
const padded2 = writePaddedText(delta, state.thinkingAtLineStart);
|
|
52200
|
-
process.stdout.write(
|
|
53130
|
+
process.stdout.write(import_picocolors8.default.dim(padded2.output));
|
|
52201
53131
|
state.thinkingAtLineStart = padded2.atLineStart;
|
|
52202
53132
|
state.lastReasoningText += delta;
|
|
52203
53133
|
state.hasReceivedMeaningfulWork = true;
|
|
@@ -52218,10 +53148,10 @@ function handleToolPart(_ctx, part, state) {
|
|
|
52218
53148
|
return;
|
|
52219
53149
|
state.currentTool = toolName;
|
|
52220
53150
|
const header = formatToolHeader(toolName, part.state?.input ?? {});
|
|
52221
|
-
const suffix = header.description ? ` ${
|
|
53151
|
+
const suffix = header.description ? ` ${import_picocolors8.default.dim(header.description)}` : "";
|
|
52222
53152
|
state.hasReceivedMeaningfulWork = true;
|
|
52223
53153
|
process.stdout.write(`
|
|
52224
|
-
${
|
|
53154
|
+
${import_picocolors8.default.cyan(header.icon)} ${import_picocolors8.default.bold(header.title)}${suffix}
|
|
52225
53155
|
`);
|
|
52226
53156
|
}
|
|
52227
53157
|
if (status === "completed" || status === "error") {
|
|
@@ -52229,10 +53159,10 @@ function handleToolPart(_ctx, part, state) {
|
|
|
52229
53159
|
return;
|
|
52230
53160
|
const output = part.state?.output || "";
|
|
52231
53161
|
if (output.trim()) {
|
|
52232
|
-
process.stdout.write(
|
|
53162
|
+
process.stdout.write(import_picocolors8.default.dim(` ${displayChars.treeEnd} output
|
|
52233
53163
|
`));
|
|
52234
53164
|
const padded = writePaddedText(output, true);
|
|
52235
|
-
process.stdout.write(
|
|
53165
|
+
process.stdout.write(import_picocolors8.default.dim(padded.output + (padded.atLineStart ? "" : " ")));
|
|
52236
53166
|
process.stdout.write(`
|
|
52237
53167
|
`);
|
|
52238
53168
|
}
|
|
@@ -52294,10 +53224,10 @@ function handleToolExecute(ctx, payload, state) {
|
|
|
52294
53224
|
const toolName = props?.name || "unknown";
|
|
52295
53225
|
state.currentTool = toolName;
|
|
52296
53226
|
const header = formatToolHeader(toolName, props?.input ?? {});
|
|
52297
|
-
const suffix = header.description ? ` ${
|
|
53227
|
+
const suffix = header.description ? ` ${import_picocolors8.default.dim(header.description)}` : "";
|
|
52298
53228
|
state.hasReceivedMeaningfulWork = true;
|
|
52299
53229
|
process.stdout.write(`
|
|
52300
|
-
${
|
|
53230
|
+
${import_picocolors8.default.cyan(header.icon)} ${import_picocolors8.default.bold(header.title)}${suffix}
|
|
52301
53231
|
`);
|
|
52302
53232
|
}
|
|
52303
53233
|
function handleToolResult(ctx, payload, state) {
|
|
@@ -52311,10 +53241,10 @@ function handleToolResult(ctx, payload, state) {
|
|
|
52311
53241
|
return;
|
|
52312
53242
|
const output = props?.output || "";
|
|
52313
53243
|
if (output.trim()) {
|
|
52314
|
-
process.stdout.write(
|
|
53244
|
+
process.stdout.write(import_picocolors8.default.dim(` ${displayChars.treeEnd} output
|
|
52315
53245
|
`));
|
|
52316
53246
|
const padded = writePaddedText(output, true);
|
|
52317
|
-
process.stdout.write(
|
|
53247
|
+
process.stdout.write(import_picocolors8.default.dim(padded.output + (padded.atLineStart ? "" : " ")));
|
|
52318
53248
|
process.stdout.write(`
|
|
52319
53249
|
`);
|
|
52320
53250
|
}
|
|
@@ -52363,7 +53293,7 @@ async function processEvents(ctx, stream, state) {
|
|
|
52363
53293
|
const payload = event;
|
|
52364
53294
|
if (!payload?.type) {
|
|
52365
53295
|
if (ctx.verbose) {
|
|
52366
|
-
console.error(
|
|
53296
|
+
console.error(import_picocolors9.default.dim(`[event] no type: ${JSON.stringify(event)}`));
|
|
52367
53297
|
}
|
|
52368
53298
|
continue;
|
|
52369
53299
|
}
|
|
@@ -52381,7 +53311,7 @@ async function processEvents(ctx, stream, state) {
|
|
|
52381
53311
|
handleToolResult(ctx, payload, state);
|
|
52382
53312
|
handleTuiToast(ctx, payload, state);
|
|
52383
53313
|
} catch (err) {
|
|
52384
|
-
console.error(
|
|
53314
|
+
console.error(import_picocolors9.default.red(`[event error] ${err}`));
|
|
52385
53315
|
}
|
|
52386
53316
|
}
|
|
52387
53317
|
}
|
|
@@ -66618,7 +67548,7 @@ var createSseClient = ({ onSseError, onSseEvent, responseTransformer, responseVa
|
|
|
66618
67548
|
if (!response.body)
|
|
66619
67549
|
throw new Error("No body in SSE response");
|
|
66620
67550
|
const reader = response.body.pipeThrough(new TextDecoderStream).getReader();
|
|
66621
|
-
let
|
|
67551
|
+
let buffer2 = "";
|
|
66622
67552
|
const abortHandler = () => {
|
|
66623
67553
|
try {
|
|
66624
67554
|
reader.cancel();
|
|
@@ -66630,11 +67560,11 @@ var createSseClient = ({ onSseError, onSseEvent, responseTransformer, responseVa
|
|
|
66630
67560
|
const { done, value } = await reader.read();
|
|
66631
67561
|
if (done)
|
|
66632
67562
|
break;
|
|
66633
|
-
|
|
66634
|
-
const chunks =
|
|
67563
|
+
buffer2 += value;
|
|
67564
|
+
const chunks = buffer2.split(`
|
|
66635
67565
|
|
|
66636
67566
|
`);
|
|
66637
|
-
|
|
67567
|
+
buffer2 = chunks.pop() ?? "";
|
|
66638
67568
|
for (const chunk of chunks) {
|
|
66639
67569
|
const lines = chunk.split(`
|
|
66640
67570
|
`);
|
|
@@ -67934,6 +68864,31 @@ class OpencodeClient extends _HeyApiClient {
|
|
|
67934
68864
|
}
|
|
67935
68865
|
|
|
67936
68866
|
// node_modules/@opencode-ai/sdk/dist/client.js
|
|
68867
|
+
function pick2(value, fallback) {
|
|
68868
|
+
if (!value)
|
|
68869
|
+
return;
|
|
68870
|
+
if (!fallback)
|
|
68871
|
+
return value;
|
|
68872
|
+
if (value === fallback)
|
|
68873
|
+
return fallback;
|
|
68874
|
+
if (value === encodeURIComponent(fallback))
|
|
68875
|
+
return fallback;
|
|
68876
|
+
return value;
|
|
68877
|
+
}
|
|
68878
|
+
function rewrite(request, directory) {
|
|
68879
|
+
if (request.method !== "GET" && request.method !== "HEAD")
|
|
68880
|
+
return request;
|
|
68881
|
+
const value = pick2(request.headers.get("x-opencode-directory"), directory);
|
|
68882
|
+
if (!value)
|
|
68883
|
+
return request;
|
|
68884
|
+
const url2 = new URL(request.url);
|
|
68885
|
+
if (!url2.searchParams.has("directory")) {
|
|
68886
|
+
url2.searchParams.set("directory", value);
|
|
68887
|
+
}
|
|
68888
|
+
const next = new Request(url2, request);
|
|
68889
|
+
next.headers.delete("x-opencode-directory");
|
|
68890
|
+
return next;
|
|
68891
|
+
}
|
|
67937
68892
|
function createOpencodeClient(config2) {
|
|
67938
68893
|
if (!config2?.fetch) {
|
|
67939
68894
|
const customFetch = (req) => {
|
|
@@ -67952,10 +68907,46 @@ function createOpencodeClient(config2) {
|
|
|
67952
68907
|
};
|
|
67953
68908
|
}
|
|
67954
68909
|
const client2 = createClient(config2);
|
|
68910
|
+
client2.interceptors.request.use((request) => rewrite(request, config2?.directory));
|
|
67955
68911
|
return new OpencodeClient({ client: client2 });
|
|
67956
68912
|
}
|
|
67957
68913
|
// node_modules/@opencode-ai/sdk/dist/server.js
|
|
67958
|
-
|
|
68914
|
+
var import_cross_spawn = __toESM(require_cross_spawn(), 1);
|
|
68915
|
+
|
|
68916
|
+
// node_modules/@opencode-ai/sdk/dist/process.js
|
|
68917
|
+
import { spawnSync } from "child_process";
|
|
68918
|
+
function stop(proc) {
|
|
68919
|
+
if (proc.exitCode !== null || proc.signalCode !== null)
|
|
68920
|
+
return;
|
|
68921
|
+
if (process.platform === "win32" && proc.pid) {
|
|
68922
|
+
const out = spawnSync("taskkill", ["/pid", String(proc.pid), "/T", "/F"], { windowsHide: true });
|
|
68923
|
+
if (!out.error && out.status === 0)
|
|
68924
|
+
return;
|
|
68925
|
+
}
|
|
68926
|
+
proc.kill();
|
|
68927
|
+
}
|
|
68928
|
+
function bindAbort(proc, signal, onAbort) {
|
|
68929
|
+
if (!signal)
|
|
68930
|
+
return () => {};
|
|
68931
|
+
const abort = () => {
|
|
68932
|
+
clear();
|
|
68933
|
+
stop(proc);
|
|
68934
|
+
onAbort?.();
|
|
68935
|
+
};
|
|
68936
|
+
const clear = () => {
|
|
68937
|
+
signal.removeEventListener("abort", abort);
|
|
68938
|
+
proc.off("exit", clear);
|
|
68939
|
+
proc.off("error", clear);
|
|
68940
|
+
};
|
|
68941
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
68942
|
+
proc.on("exit", clear);
|
|
68943
|
+
proc.on("error", clear);
|
|
68944
|
+
if (signal.aborted)
|
|
68945
|
+
abort();
|
|
68946
|
+
return clear;
|
|
68947
|
+
}
|
|
68948
|
+
|
|
68949
|
+
// node_modules/@opencode-ai/sdk/dist/server.js
|
|
67959
68950
|
async function createOpencodeServer(options) {
|
|
67960
68951
|
options = Object.assign({
|
|
67961
68952
|
hostname: "127.0.0.1",
|
|
@@ -67965,19 +68956,24 @@ async function createOpencodeServer(options) {
|
|
|
67965
68956
|
const args = [`serve`, `--hostname=${options.hostname}`, `--port=${options.port}`];
|
|
67966
68957
|
if (options.config?.logLevel)
|
|
67967
68958
|
args.push(`--log-level=${options.config.logLevel}`);
|
|
67968
|
-
const proc =
|
|
67969
|
-
signal: options.signal,
|
|
68959
|
+
const proc = import_cross_spawn.default(`opencode`, args, {
|
|
67970
68960
|
env: {
|
|
67971
68961
|
...process.env,
|
|
67972
68962
|
OPENCODE_CONFIG_CONTENT: JSON.stringify(options.config ?? {})
|
|
67973
68963
|
}
|
|
67974
68964
|
});
|
|
68965
|
+
let clear = () => {};
|
|
67975
68966
|
const url2 = await new Promise((resolve2, reject) => {
|
|
67976
68967
|
const id = setTimeout(() => {
|
|
68968
|
+
clear();
|
|
68969
|
+
stop(proc);
|
|
67977
68970
|
reject(new Error(`Timeout waiting for server to start after ${options.timeout}ms`));
|
|
67978
68971
|
}, options.timeout);
|
|
67979
68972
|
let output = "";
|
|
68973
|
+
let resolved = false;
|
|
67980
68974
|
proc.stdout?.on("data", (chunk) => {
|
|
68975
|
+
if (resolved)
|
|
68976
|
+
return;
|
|
67981
68977
|
output += chunk.toString();
|
|
67982
68978
|
const lines = output.split(`
|
|
67983
68979
|
`);
|
|
@@ -67985,9 +68981,14 @@ async function createOpencodeServer(options) {
|
|
|
67985
68981
|
if (line.startsWith("opencode server listening")) {
|
|
67986
68982
|
const match = line.match(/on\s+(https?:\/\/[^\s]+)/);
|
|
67987
68983
|
if (!match) {
|
|
67988
|
-
|
|
68984
|
+
clear();
|
|
68985
|
+
stop(proc);
|
|
68986
|
+
clearTimeout(id);
|
|
68987
|
+
reject(new Error(`Failed to parse server url from output: ${line}`));
|
|
68988
|
+
return;
|
|
67989
68989
|
}
|
|
67990
68990
|
clearTimeout(id);
|
|
68991
|
+
resolved = true;
|
|
67991
68992
|
resolve2(match[1]);
|
|
67992
68993
|
return;
|
|
67993
68994
|
}
|
|
@@ -68009,17 +69010,16 @@ Server output: ${output}`;
|
|
|
68009
69010
|
clearTimeout(id);
|
|
68010
69011
|
reject(error48);
|
|
68011
69012
|
});
|
|
68012
|
-
|
|
68013
|
-
|
|
68014
|
-
|
|
68015
|
-
|
|
68016
|
-
});
|
|
68017
|
-
}
|
|
69013
|
+
clear = bindAbort(proc, options.signal, () => {
|
|
69014
|
+
clearTimeout(id);
|
|
69015
|
+
reject(options.signal?.reason);
|
|
69016
|
+
});
|
|
68018
69017
|
});
|
|
68019
69018
|
return {
|
|
68020
69019
|
url: url2,
|
|
68021
69020
|
close() {
|
|
68022
|
-
|
|
69021
|
+
clear();
|
|
69022
|
+
stop(proc);
|
|
68023
69023
|
}
|
|
68024
69024
|
};
|
|
68025
69025
|
}
|
|
@@ -68039,11 +69039,11 @@ async function createOpencode(options) {
|
|
|
68039
69039
|
|
|
68040
69040
|
// src/cli/run/server-connection.ts
|
|
68041
69041
|
init_port_utils();
|
|
68042
|
-
var
|
|
69042
|
+
var import_picocolors10 = __toESM(require_picocolors(), 1);
|
|
68043
69043
|
|
|
68044
69044
|
// src/cli/run/opencode-binary-resolver.ts
|
|
68045
69045
|
init_spawn_with_windows_hide();
|
|
68046
|
-
import { delimiter, dirname, join as
|
|
69046
|
+
import { delimiter, dirname as dirname2, join as join14 } from "path";
|
|
68047
69047
|
var OPENCODE_COMMANDS = ["opencode", "opencode-desktop"];
|
|
68048
69048
|
var WINDOWS_SUFFIXES = ["", ".exe", ".cmd", ".bat", ".ps1"];
|
|
68049
69049
|
function getCommandCandidates(platform) {
|
|
@@ -68066,7 +69066,7 @@ function collectCandidateBinaryPaths(pathEnv, which = Bun.which, platform = proc
|
|
|
68066
69066
|
}
|
|
68067
69067
|
for (const entry of (pathEnv ?? "").split(delimiter).filter(Boolean)) {
|
|
68068
69068
|
for (const command of commandCandidates) {
|
|
68069
|
-
addCandidate(
|
|
69069
|
+
addCandidate(join14(entry, command));
|
|
68070
69070
|
}
|
|
68071
69071
|
}
|
|
68072
69072
|
return candidates;
|
|
@@ -68093,7 +69093,7 @@ async function findWorkingOpencodeBinary(pathEnv = process.env.PATH, probe = can
|
|
|
68093
69093
|
return null;
|
|
68094
69094
|
}
|
|
68095
69095
|
function buildPathWithBinaryFirst(pathEnv, binaryPath) {
|
|
68096
|
-
const preferredDir =
|
|
69096
|
+
const preferredDir = dirname2(binaryPath);
|
|
68097
69097
|
const existing = (pathEnv ?? "").split(delimiter).filter((entry) => entry.length > 0 && entry !== preferredDir);
|
|
68098
69098
|
return [preferredDir, ...existing].join(delimiter);
|
|
68099
69099
|
}
|
|
@@ -68127,13 +69127,13 @@ function isPortRangeExhausted(error48) {
|
|
|
68127
69127
|
async function startServer(options) {
|
|
68128
69128
|
const { signal, port } = options;
|
|
68129
69129
|
const { client: client3, server: server2 } = await withWorkingOpencodePath(() => createOpencode({ signal, port, hostname: "127.0.0.1" }));
|
|
68130
|
-
console.log(
|
|
69130
|
+
console.log(import_picocolors10.default.dim("Server listening at"), import_picocolors10.default.cyan(server2.url));
|
|
68131
69131
|
return { client: client3, cleanup: () => server2.close() };
|
|
68132
69132
|
}
|
|
68133
69133
|
async function createServerConnection(options) {
|
|
68134
69134
|
const { port, attach, signal } = options;
|
|
68135
69135
|
if (attach !== undefined) {
|
|
68136
|
-
console.log(
|
|
69136
|
+
console.log(import_picocolors10.default.dim("Attaching to existing server at"), import_picocolors10.default.cyan(attach));
|
|
68137
69137
|
const client3 = createOpencodeClient({ baseUrl: attach });
|
|
68138
69138
|
return { client: client3, cleanup: () => {} };
|
|
68139
69139
|
}
|
|
@@ -68143,7 +69143,7 @@ async function createServerConnection(options) {
|
|
|
68143
69143
|
}
|
|
68144
69144
|
const available = await isPortAvailable(port, "127.0.0.1");
|
|
68145
69145
|
if (available) {
|
|
68146
|
-
console.log(
|
|
69146
|
+
console.log(import_picocolors10.default.dim("Starting server on port"), import_picocolors10.default.cyan(port.toString()));
|
|
68147
69147
|
try {
|
|
68148
69148
|
return await startServer({ signal, port });
|
|
68149
69149
|
} catch (error48) {
|
|
@@ -68154,12 +69154,12 @@ async function createServerConnection(options) {
|
|
|
68154
69154
|
if (stillAvailable) {
|
|
68155
69155
|
throw error48;
|
|
68156
69156
|
}
|
|
68157
|
-
console.log(
|
|
69157
|
+
console.log(import_picocolors10.default.dim("Port"), import_picocolors10.default.cyan(port.toString()), import_picocolors10.default.dim("became occupied, attaching to existing server"));
|
|
68158
69158
|
const client4 = createOpencodeClient({ baseUrl: `http://127.0.0.1:${port}` });
|
|
68159
69159
|
return { client: client4, cleanup: () => {} };
|
|
68160
69160
|
}
|
|
68161
69161
|
}
|
|
68162
|
-
console.log(
|
|
69162
|
+
console.log(import_picocolors10.default.dim("Port"), import_picocolors10.default.cyan(port.toString()), import_picocolors10.default.dim("is occupied, attaching to existing server"));
|
|
68163
69163
|
const client3 = createOpencodeClient({ baseUrl: `http://127.0.0.1:${port}` });
|
|
68164
69164
|
return { client: client3, cleanup: () => {} };
|
|
68165
69165
|
}
|
|
@@ -68177,14 +69177,14 @@ async function createServerConnection(options) {
|
|
|
68177
69177
|
if (defaultPortIsAvailable) {
|
|
68178
69178
|
throw error48;
|
|
68179
69179
|
}
|
|
68180
|
-
console.log(
|
|
69180
|
+
console.log(import_picocolors10.default.dim("Port range exhausted, attaching to existing server on"), import_picocolors10.default.cyan(DEFAULT_SERVER_PORT.toString()));
|
|
68181
69181
|
const client3 = createOpencodeClient({ baseUrl: `http://127.0.0.1:${DEFAULT_SERVER_PORT}` });
|
|
68182
69182
|
return { client: client3, cleanup: () => {} };
|
|
68183
69183
|
}
|
|
68184
69184
|
if (wasAutoSelected) {
|
|
68185
|
-
console.log(
|
|
69185
|
+
console.log(import_picocolors10.default.dim("Auto-selected port"), import_picocolors10.default.cyan(selectedPort.toString()));
|
|
68186
69186
|
} else {
|
|
68187
|
-
console.log(
|
|
69187
|
+
console.log(import_picocolors10.default.dim("Starting server on port"), import_picocolors10.default.cyan(selectedPort.toString()));
|
|
68188
69188
|
}
|
|
68189
69189
|
try {
|
|
68190
69190
|
return await startServer({ signal, port: selectedPort });
|
|
@@ -68193,14 +69193,13 @@ async function createServerConnection(options) {
|
|
|
68193
69193
|
throw error48;
|
|
68194
69194
|
}
|
|
68195
69195
|
const { port: retryPort } = await getAvailableServerPort(selectedPort + 1, "127.0.0.1");
|
|
68196
|
-
console.log(
|
|
69196
|
+
console.log(import_picocolors10.default.dim("Retrying server start on port"), import_picocolors10.default.cyan(retryPort.toString()));
|
|
68197
69197
|
return await startServer({ signal, port: retryPort });
|
|
68198
69198
|
}
|
|
68199
69199
|
}
|
|
68200
69200
|
|
|
68201
69201
|
// src/cli/run/session-resolver.ts
|
|
68202
|
-
var
|
|
68203
|
-
init_plugin_identity();
|
|
69202
|
+
var import_picocolors11 = __toESM(require_picocolors(), 1);
|
|
68204
69203
|
var SESSION_CREATE_MAX_RETRIES = 3;
|
|
68205
69204
|
var SESSION_CREATE_RETRY_DELAY_MS = 1000;
|
|
68206
69205
|
async function resolveSession(options) {
|
|
@@ -68218,7 +69217,7 @@ async function resolveSession(options) {
|
|
|
68218
69217
|
for (let attempt = 1;attempt <= SESSION_CREATE_MAX_RETRIES; attempt++) {
|
|
68219
69218
|
const res = await client3.session.create({
|
|
68220
69219
|
body: {
|
|
68221
|
-
title:
|
|
69220
|
+
title: "evil-omo run",
|
|
68222
69221
|
permission: [
|
|
68223
69222
|
{ permission: "question", action: "deny", pattern: "*" }
|
|
68224
69223
|
]
|
|
@@ -68226,11 +69225,11 @@ async function resolveSession(options) {
|
|
|
68226
69225
|
query: { directory }
|
|
68227
69226
|
});
|
|
68228
69227
|
if (res.error) {
|
|
68229
|
-
console.error(
|
|
68230
|
-
console.error(
|
|
69228
|
+
console.error(import_picocolors11.default.yellow(`Session create attempt ${attempt}/${SESSION_CREATE_MAX_RETRIES} failed:`));
|
|
69229
|
+
console.error(import_picocolors11.default.dim(` Error: ${serializeError(res.error)}`));
|
|
68231
69230
|
if (attempt < SESSION_CREATE_MAX_RETRIES) {
|
|
68232
69231
|
const delay = SESSION_CREATE_RETRY_DELAY_MS * attempt;
|
|
68233
|
-
console.log(
|
|
69232
|
+
console.log(import_picocolors11.default.dim(` Retrying in ${delay}ms...`));
|
|
68234
69233
|
await new Promise((resolve2) => setTimeout(resolve2, delay));
|
|
68235
69234
|
}
|
|
68236
69235
|
continue;
|
|
@@ -68238,10 +69237,10 @@ async function resolveSession(options) {
|
|
|
68238
69237
|
if (res.data?.id) {
|
|
68239
69238
|
return res.data.id;
|
|
68240
69239
|
}
|
|
68241
|
-
console.error(
|
|
69240
|
+
console.error(import_picocolors11.default.yellow(`Session create attempt ${attempt}/${SESSION_CREATE_MAX_RETRIES}: No session ID returned`));
|
|
68242
69241
|
if (attempt < SESSION_CREATE_MAX_RETRIES) {
|
|
68243
69242
|
const delay = SESSION_CREATE_RETRY_DELAY_MS * attempt;
|
|
68244
|
-
console.log(
|
|
69243
|
+
console.log(import_picocolors11.default.dim(` Retrying in ${delay}ms...`));
|
|
68245
69244
|
await new Promise((resolve2) => setTimeout(resolve2, delay));
|
|
68246
69245
|
}
|
|
68247
69246
|
}
|
|
@@ -68359,7 +69358,7 @@ async function executeOnCompleteHook(options) {
|
|
|
68359
69358
|
|
|
68360
69359
|
// src/cli/run/agent-resolver.ts
|
|
68361
69360
|
init_agent_display_names();
|
|
68362
|
-
var
|
|
69361
|
+
var import_picocolors12 = __toESM(require_picocolors(), 1);
|
|
68363
69362
|
var CORE_AGENT_ORDER = ["sisyphus", "hephaestus", "prometheus", "atlas"];
|
|
68364
69363
|
var DEFAULT_AGENT = "sisyphus";
|
|
68365
69364
|
var normalizeAgentName = (agent) => {
|
|
@@ -68404,10 +69403,10 @@ var resolveRunAgent = (options, pluginConfig, env = process.env) => {
|
|
|
68404
69403
|
const fallbackName = getAgentDisplayName(fallback);
|
|
68405
69404
|
const fallbackDisabled = isAgentDisabled(fallback, pluginConfig);
|
|
68406
69405
|
if (fallbackDisabled) {
|
|
68407
|
-
console.log(
|
|
69406
|
+
console.log(import_picocolors12.default.yellow(`Requested agent "${resolved.resolvedName}" is disabled and no enabled core agent was found. Proceeding with "${fallbackName}".`));
|
|
68408
69407
|
return fallbackName;
|
|
68409
69408
|
}
|
|
68410
|
-
console.log(
|
|
69409
|
+
console.log(import_picocolors12.default.yellow(`Requested agent "${resolved.resolvedName}" is disabled. Falling back to "${fallbackName}".`));
|
|
68411
69410
|
return fallbackName;
|
|
68412
69411
|
}
|
|
68413
69412
|
return resolved.resolvedName;
|
|
@@ -68438,11 +69437,11 @@ function resolveRunModel(modelString) {
|
|
|
68438
69437
|
}
|
|
68439
69438
|
|
|
68440
69439
|
// src/cli/run/poll-for-completion.ts
|
|
68441
|
-
var
|
|
69440
|
+
var import_picocolors14 = __toESM(require_picocolors(), 1);
|
|
68442
69441
|
|
|
68443
69442
|
// src/cli/run/completion.ts
|
|
68444
69443
|
init_shared();
|
|
68445
|
-
var
|
|
69444
|
+
var import_picocolors13 = __toESM(require_picocolors(), 1);
|
|
68446
69445
|
// src/features/boulder-state/constants.ts
|
|
68447
69446
|
var BOULDER_DIR = ".sisyphus";
|
|
68448
69447
|
var BOULDER_FILE = "boulder.json";
|
|
@@ -68450,19 +69449,19 @@ var BOULDER_STATE_PATH = `${BOULDER_DIR}/${BOULDER_FILE}`;
|
|
|
68450
69449
|
var NOTEPAD_DIR = "notepads";
|
|
68451
69450
|
var NOTEPAD_BASE_PATH = `${BOULDER_DIR}/${NOTEPAD_DIR}`;
|
|
68452
69451
|
// src/features/boulder-state/storage.ts
|
|
68453
|
-
import { existsSync as
|
|
68454
|
-
import { dirname as
|
|
69452
|
+
import { existsSync as existsSync15, readFileSync as readFileSync10, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, readdirSync as readdirSync3 } from "fs";
|
|
69453
|
+
import { dirname as dirname3, join as join15, basename } from "path";
|
|
68455
69454
|
var RESERVED_KEYS = new Set(["__proto__", "prototype", "constructor"]);
|
|
68456
69455
|
function getBoulderFilePath(directory) {
|
|
68457
|
-
return
|
|
69456
|
+
return join15(directory, BOULDER_DIR, BOULDER_FILE);
|
|
68458
69457
|
}
|
|
68459
69458
|
function readBoulderState(directory) {
|
|
68460
69459
|
const filePath = getBoulderFilePath(directory);
|
|
68461
|
-
if (!
|
|
69460
|
+
if (!existsSync15(filePath)) {
|
|
68462
69461
|
return null;
|
|
68463
69462
|
}
|
|
68464
69463
|
try {
|
|
68465
|
-
const content =
|
|
69464
|
+
const content = readFileSync10(filePath, "utf-8");
|
|
68466
69465
|
const parsed = JSON.parse(content);
|
|
68467
69466
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
68468
69467
|
return null;
|
|
@@ -68470,6 +69469,15 @@ function readBoulderState(directory) {
|
|
|
68470
69469
|
if (!Array.isArray(parsed.session_ids)) {
|
|
68471
69470
|
parsed.session_ids = [];
|
|
68472
69471
|
}
|
|
69472
|
+
if (!parsed.session_origins || typeof parsed.session_origins !== "object" || Array.isArray(parsed.session_origins)) {
|
|
69473
|
+
parsed.session_origins = {};
|
|
69474
|
+
}
|
|
69475
|
+
if (parsed.session_ids.length === 1) {
|
|
69476
|
+
const soleSessionId = parsed.session_ids[0];
|
|
69477
|
+
if (typeof soleSessionId === "string" && parsed.session_origins[soleSessionId] !== "appended" && parsed.session_origins[soleSessionId] !== "direct") {
|
|
69478
|
+
parsed.session_origins[soleSessionId] = "direct";
|
|
69479
|
+
}
|
|
69480
|
+
}
|
|
68473
69481
|
if (!parsed.task_sessions || typeof parsed.task_sessions !== "object" || Array.isArray(parsed.task_sessions)) {
|
|
68474
69482
|
parsed.task_sessions = {};
|
|
68475
69483
|
}
|
|
@@ -68478,39 +69486,101 @@ function readBoulderState(directory) {
|
|
|
68478
69486
|
return null;
|
|
68479
69487
|
}
|
|
68480
69488
|
}
|
|
69489
|
+
var TODO_HEADING_PATTERN = /^##\s+TODOs\b/i;
|
|
69490
|
+
var FINAL_VERIFICATION_HEADING_PATTERN = /^##\s+Final Verification Wave\b/i;
|
|
69491
|
+
var SECOND_LEVEL_HEADING_PATTERN = /^##\s+/;
|
|
69492
|
+
var UNCHECKED_CHECKBOX_PATTERN = /^(\s*)[-*]\s*\[\s*\]\s*(.+)$/;
|
|
69493
|
+
var CHECKED_CHECKBOX_PATTERN = /^(\s*)[-*]\s*\[[xX]\]\s*(.+)$/;
|
|
69494
|
+
var TODO_TASK_PATTERN = /^\d+\.\s+/;
|
|
69495
|
+
var FINAL_WAVE_TASK_PATTERN = /^F\d+\.\s+/i;
|
|
68481
69496
|
function getPlanProgress(planPath) {
|
|
68482
|
-
if (!
|
|
69497
|
+
if (!existsSync15(planPath)) {
|
|
68483
69498
|
return { total: 0, completed: 0, isComplete: true };
|
|
68484
69499
|
}
|
|
68485
69500
|
try {
|
|
68486
|
-
const content =
|
|
68487
|
-
const
|
|
68488
|
-
const
|
|
68489
|
-
|
|
68490
|
-
|
|
68491
|
-
|
|
68492
|
-
|
|
68493
|
-
completed,
|
|
68494
|
-
isComplete: total > 0 && completed === total
|
|
68495
|
-
};
|
|
69501
|
+
const content = readFileSync10(planPath, "utf-8");
|
|
69502
|
+
const lines = content.split(/\r?\n/);
|
|
69503
|
+
const hasStructuredSections = lines.some((line) => TODO_HEADING_PATTERN.test(line) || FINAL_VERIFICATION_HEADING_PATTERN.test(line));
|
|
69504
|
+
if (hasStructuredSections) {
|
|
69505
|
+
return getStructuredPlanProgress(lines);
|
|
69506
|
+
}
|
|
69507
|
+
return getSimplePlanProgress(content);
|
|
68496
69508
|
} catch {
|
|
68497
69509
|
return { total: 0, completed: 0, isComplete: true };
|
|
68498
69510
|
}
|
|
68499
69511
|
}
|
|
69512
|
+
function getStructuredPlanProgress(lines) {
|
|
69513
|
+
let section = "other";
|
|
69514
|
+
let total = 0;
|
|
69515
|
+
let completed = 0;
|
|
69516
|
+
for (const line of lines) {
|
|
69517
|
+
if (SECOND_LEVEL_HEADING_PATTERN.test(line)) {
|
|
69518
|
+
section = TODO_HEADING_PATTERN.test(line) ? "todo" : FINAL_VERIFICATION_HEADING_PATTERN.test(line) ? "final-wave" : "other";
|
|
69519
|
+
continue;
|
|
69520
|
+
}
|
|
69521
|
+
if (section !== "todo" && section !== "final-wave") {
|
|
69522
|
+
continue;
|
|
69523
|
+
}
|
|
69524
|
+
const checkedMatch = line.match(CHECKED_CHECKBOX_PATTERN);
|
|
69525
|
+
const uncheckedMatch = checkedMatch ? null : line.match(UNCHECKED_CHECKBOX_PATTERN);
|
|
69526
|
+
const match = checkedMatch ?? uncheckedMatch;
|
|
69527
|
+
if (!match) {
|
|
69528
|
+
continue;
|
|
69529
|
+
}
|
|
69530
|
+
if (match[1].length > 0) {
|
|
69531
|
+
continue;
|
|
69532
|
+
}
|
|
69533
|
+
const taskBody = match[2].trim();
|
|
69534
|
+
const labelPattern = section === "todo" ? TODO_TASK_PATTERN : FINAL_WAVE_TASK_PATTERN;
|
|
69535
|
+
if (!labelPattern.test(taskBody)) {
|
|
69536
|
+
continue;
|
|
69537
|
+
}
|
|
69538
|
+
total++;
|
|
69539
|
+
if (checkedMatch) {
|
|
69540
|
+
completed++;
|
|
69541
|
+
}
|
|
69542
|
+
}
|
|
69543
|
+
return {
|
|
69544
|
+
total,
|
|
69545
|
+
completed,
|
|
69546
|
+
isComplete: total > 0 && completed === total
|
|
69547
|
+
};
|
|
69548
|
+
}
|
|
69549
|
+
function getSimplePlanProgress(content) {
|
|
69550
|
+
const uncheckedMatches = content.match(/^[-*]\s*\[\s*\]/gm) || [];
|
|
69551
|
+
const checkedMatches = content.match(/^[-*]\s*\[[xX]\]/gm) || [];
|
|
69552
|
+
const total = uncheckedMatches.length + checkedMatches.length;
|
|
69553
|
+
const completed = checkedMatches.length;
|
|
69554
|
+
return {
|
|
69555
|
+
total,
|
|
69556
|
+
completed,
|
|
69557
|
+
isComplete: total > 0 && completed === total
|
|
69558
|
+
};
|
|
69559
|
+
}
|
|
69560
|
+
// src/features/claude-code-session-state/state.ts
|
|
69561
|
+
init_agent_display_names();
|
|
69562
|
+
var subagentSessions = new Set;
|
|
69563
|
+
var syncSubagentSessions = new Set;
|
|
69564
|
+
var registeredAgentNames = new Set;
|
|
69565
|
+
var registeredAgentAliases = new Map;
|
|
69566
|
+
var sessionAgentMap = new Map;
|
|
69567
|
+
function getSessionAgent(sessionID) {
|
|
69568
|
+
return sessionAgentMap.get(sessionID);
|
|
69569
|
+
}
|
|
68500
69570
|
// src/features/run-continuation-state/constants.ts
|
|
68501
69571
|
var CONTINUATION_MARKER_DIR = ".sisyphus/run-continuation";
|
|
68502
69572
|
// src/features/run-continuation-state/storage.ts
|
|
68503
|
-
import { existsSync as
|
|
68504
|
-
import { join as
|
|
69573
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync6, readFileSync as readFileSync11, rmSync, writeFileSync as writeFileSync6 } from "fs";
|
|
69574
|
+
import { join as join16 } from "path";
|
|
68505
69575
|
function getMarkerPath(directory, sessionID) {
|
|
68506
|
-
return
|
|
69576
|
+
return join16(directory, CONTINUATION_MARKER_DIR, `${sessionID}.json`);
|
|
68507
69577
|
}
|
|
68508
69578
|
function readContinuationMarker(directory, sessionID) {
|
|
68509
69579
|
const markerPath = getMarkerPath(directory, sessionID);
|
|
68510
|
-
if (!
|
|
69580
|
+
if (!existsSync16(markerPath))
|
|
68511
69581
|
return null;
|
|
68512
69582
|
try {
|
|
68513
|
-
const raw =
|
|
69583
|
+
const raw = readFileSync11(markerPath, "utf-8");
|
|
68514
69584
|
const parsed = JSON.parse(raw);
|
|
68515
69585
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
68516
69586
|
return null;
|
|
@@ -68533,10 +69603,120 @@ function getActiveContinuationMarkerReason(marker) {
|
|
|
68533
69603
|
const [source, entry] = active;
|
|
68534
69604
|
return entry.reason ?? `${source} continuation is active`;
|
|
68535
69605
|
}
|
|
69606
|
+
// src/hooks/atlas/boulder-session-lineage.ts
|
|
69607
|
+
init_logger();
|
|
69608
|
+
|
|
69609
|
+
// src/hooks/atlas/hook-name.ts
|
|
69610
|
+
var HOOK_NAME = "atlas";
|
|
69611
|
+
|
|
69612
|
+
// src/hooks/atlas/boulder-session-lineage.ts
|
|
69613
|
+
async function isSessionInBoulderLineage(input) {
|
|
69614
|
+
const visitedSessionIDs = new Set;
|
|
69615
|
+
let currentSessionID = input.sessionID;
|
|
69616
|
+
while (!visitedSessionIDs.has(currentSessionID)) {
|
|
69617
|
+
visitedSessionIDs.add(currentSessionID);
|
|
69618
|
+
const sessionResult = await input.client.session.get({ path: { id: currentSessionID } }).catch((error48) => {
|
|
69619
|
+
log(`[${HOOK_NAME}] Failed to resolve session lineage`, {
|
|
69620
|
+
sessionID: input.sessionID,
|
|
69621
|
+
currentSessionID,
|
|
69622
|
+
error: error48
|
|
69623
|
+
});
|
|
69624
|
+
return null;
|
|
69625
|
+
});
|
|
69626
|
+
if (!sessionResult || sessionResult.error) {
|
|
69627
|
+
return false;
|
|
69628
|
+
}
|
|
69629
|
+
const parentSessionID = sessionResult.data?.parentID;
|
|
69630
|
+
if (!parentSessionID) {
|
|
69631
|
+
return false;
|
|
69632
|
+
}
|
|
69633
|
+
if (input.boulderSessionIDs.includes(parentSessionID)) {
|
|
69634
|
+
return true;
|
|
69635
|
+
}
|
|
69636
|
+
currentSessionID = parentSessionID;
|
|
69637
|
+
}
|
|
69638
|
+
return false;
|
|
69639
|
+
}
|
|
69640
|
+
|
|
69641
|
+
// src/hooks/atlas/session-last-agent.ts
|
|
69642
|
+
init_shared();
|
|
69643
|
+
init_compaction_marker();
|
|
69644
|
+
import { readFileSync as readFileSync12, readdirSync as readdirSync4 } from "fs";
|
|
69645
|
+
import { join as join17 } from "path";
|
|
69646
|
+
function getLastAgentFromMessageDir(messageDir) {
|
|
69647
|
+
try {
|
|
69648
|
+
const messages = readdirSync4(messageDir).filter((fileName) => fileName.endsWith(".json")).map((fileName) => {
|
|
69649
|
+
try {
|
|
69650
|
+
const content = readFileSync12(join17(messageDir, fileName), "utf-8");
|
|
69651
|
+
const parsed = JSON.parse(content);
|
|
69652
|
+
return {
|
|
69653
|
+
fileName,
|
|
69654
|
+
id: parsed.id,
|
|
69655
|
+
agent: parsed.agent,
|
|
69656
|
+
createdAt: typeof parsed.time?.created === "number" ? parsed.time.created : Number.NEGATIVE_INFINITY
|
|
69657
|
+
};
|
|
69658
|
+
} catch {
|
|
69659
|
+
return null;
|
|
69660
|
+
}
|
|
69661
|
+
}).filter((message) => message !== null).sort((left, right) => (right?.createdAt ?? 0) - (left?.createdAt ?? 0) || (right?.fileName ?? "").localeCompare(left?.fileName ?? ""));
|
|
69662
|
+
for (const message of messages) {
|
|
69663
|
+
if (!message)
|
|
69664
|
+
continue;
|
|
69665
|
+
if (isCompactionMessage({ agent: message.agent }) || hasCompactionPartInStorage(message?.id)) {
|
|
69666
|
+
continue;
|
|
69667
|
+
}
|
|
69668
|
+
if (typeof message.agent === "string") {
|
|
69669
|
+
return message.agent.toLowerCase();
|
|
69670
|
+
}
|
|
69671
|
+
}
|
|
69672
|
+
} catch {
|
|
69673
|
+
return null;
|
|
69674
|
+
}
|
|
69675
|
+
return null;
|
|
69676
|
+
}
|
|
69677
|
+
async function getLastAgentFromSession(sessionID, client3) {
|
|
69678
|
+
if (isSqliteBackend() && client3) {
|
|
69679
|
+
try {
|
|
69680
|
+
const response = await client3.session.messages({ path: { id: sessionID } });
|
|
69681
|
+
const messages = normalizeSDKResponse(response, [], {
|
|
69682
|
+
preferResponseOnMissingData: true
|
|
69683
|
+
}).sort((left, right) => {
|
|
69684
|
+
const leftTime = left.info?.time?.created ?? Number.NEGATIVE_INFINITY;
|
|
69685
|
+
const rightTime = right.info?.time?.created ?? Number.NEGATIVE_INFINITY;
|
|
69686
|
+
if (leftTime !== rightTime) {
|
|
69687
|
+
return rightTime - leftTime;
|
|
69688
|
+
}
|
|
69689
|
+
const leftId = typeof left.id === "string" ? left.id : "";
|
|
69690
|
+
const rightId = typeof right.id === "string" ? right.id : "";
|
|
69691
|
+
return rightId.localeCompare(leftId);
|
|
69692
|
+
});
|
|
69693
|
+
for (const message of messages) {
|
|
69694
|
+
if (isCompactionMessage(message)) {
|
|
69695
|
+
continue;
|
|
69696
|
+
}
|
|
69697
|
+
const agent = message.info?.agent;
|
|
69698
|
+
if (typeof agent === "string") {
|
|
69699
|
+
return agent.toLowerCase();
|
|
69700
|
+
}
|
|
69701
|
+
}
|
|
69702
|
+
} catch {
|
|
69703
|
+
return null;
|
|
69704
|
+
}
|
|
69705
|
+
return null;
|
|
69706
|
+
}
|
|
69707
|
+
const messageDir = getMessageDir(sessionID);
|
|
69708
|
+
if (!messageDir)
|
|
69709
|
+
return null;
|
|
69710
|
+
return getLastAgentFromMessageDir(messageDir);
|
|
69711
|
+
}
|
|
69712
|
+
|
|
69713
|
+
// src/cli/run/continuation-state.ts
|
|
69714
|
+
init_agent_display_names();
|
|
69715
|
+
|
|
68536
69716
|
// src/hooks/ralph-loop/storage.ts
|
|
68537
69717
|
init_frontmatter();
|
|
68538
|
-
import { existsSync as
|
|
68539
|
-
import { dirname as
|
|
69718
|
+
import { existsSync as existsSync17, readFileSync as readFileSync13, writeFileSync as writeFileSync7, unlinkSync, mkdirSync as mkdirSync7 } from "fs";
|
|
69719
|
+
import { dirname as dirname4, join as join18 } from "path";
|
|
68540
69720
|
|
|
68541
69721
|
// src/hooks/ralph-loop/constants.ts
|
|
68542
69722
|
var DEFAULT_STATE_FILE = ".sisyphus/ralph-loop.local.md";
|
|
@@ -68545,15 +69725,15 @@ var DEFAULT_COMPLETION_PROMISE = "DONE";
|
|
|
68545
69725
|
|
|
68546
69726
|
// src/hooks/ralph-loop/storage.ts
|
|
68547
69727
|
function getStateFilePath(directory, customPath) {
|
|
68548
|
-
return customPath ?
|
|
69728
|
+
return customPath ? join18(directory, customPath) : join18(directory, DEFAULT_STATE_FILE);
|
|
68549
69729
|
}
|
|
68550
69730
|
function readState(directory, customPath) {
|
|
68551
69731
|
const filePath = getStateFilePath(directory, customPath);
|
|
68552
|
-
if (!
|
|
69732
|
+
if (!existsSync17(filePath)) {
|
|
68553
69733
|
return null;
|
|
68554
69734
|
}
|
|
68555
69735
|
try {
|
|
68556
|
-
const content =
|
|
69736
|
+
const content = readFileSync13(filePath, "utf-8");
|
|
68557
69737
|
const { data, body } = parseFrontmatter(content);
|
|
68558
69738
|
const active = data.active;
|
|
68559
69739
|
const iteration = data.iteration;
|
|
@@ -68593,10 +69773,10 @@ function readState(directory, customPath) {
|
|
|
68593
69773
|
}
|
|
68594
69774
|
|
|
68595
69775
|
// src/cli/run/continuation-state.ts
|
|
68596
|
-
function getContinuationState(directory, sessionID) {
|
|
69776
|
+
async function getContinuationState(directory, sessionID, client3) {
|
|
68597
69777
|
const marker = readContinuationMarker(directory, sessionID);
|
|
68598
69778
|
return {
|
|
68599
|
-
hasActiveBoulder: hasActiveBoulderContinuation(directory, sessionID),
|
|
69779
|
+
hasActiveBoulder: await hasActiveBoulderContinuation(directory, sessionID, client3),
|
|
68600
69780
|
hasActiveRalphLoop: hasActiveRalphLoopContinuation(directory, sessionID),
|
|
68601
69781
|
hasHookMarker: marker !== null,
|
|
68602
69782
|
hasTodoHookMarker: marker?.sources.todo !== undefined,
|
|
@@ -68604,20 +69784,54 @@ function getContinuationState(directory, sessionID) {
|
|
|
68604
69784
|
activeHookMarkerReason: getActiveContinuationMarkerReason(marker)
|
|
68605
69785
|
};
|
|
68606
69786
|
}
|
|
68607
|
-
function hasActiveBoulderContinuation(directory, sessionID) {
|
|
69787
|
+
async function hasActiveBoulderContinuation(directory, sessionID, client3) {
|
|
68608
69788
|
const boulder = readBoulderState(directory);
|
|
68609
69789
|
if (!boulder)
|
|
68610
69790
|
return false;
|
|
68611
|
-
if (!boulder.session_ids.includes(sessionID))
|
|
68612
|
-
return false;
|
|
68613
69791
|
const progress = getPlanProgress(boulder.active_plan);
|
|
68614
|
-
|
|
69792
|
+
if (progress.isComplete)
|
|
69793
|
+
return false;
|
|
69794
|
+
if (!client3)
|
|
69795
|
+
return false;
|
|
69796
|
+
const isTrackedSession = boulder.session_ids.includes(sessionID);
|
|
69797
|
+
const sessionOrigin = boulder.session_origins?.[sessionID];
|
|
69798
|
+
if (!isTrackedSession) {
|
|
69799
|
+
return false;
|
|
69800
|
+
}
|
|
69801
|
+
const isTrackedDescendant = await isTrackedDescendantSession(client3, sessionID, boulder.session_ids);
|
|
69802
|
+
if (isTrackedSession && sessionOrigin === "direct") {
|
|
69803
|
+
return true;
|
|
69804
|
+
}
|
|
69805
|
+
if (isTrackedSession && sessionOrigin !== "direct" && !isTrackedDescendant) {
|
|
69806
|
+
return false;
|
|
69807
|
+
}
|
|
69808
|
+
const sessionAgent = await getLastAgentFromSession(sessionID, client3) ?? getSessionAgent(sessionID);
|
|
69809
|
+
if (!sessionAgent) {
|
|
69810
|
+
return false;
|
|
69811
|
+
}
|
|
69812
|
+
const requiredAgentKey = getAgentConfigKey(boulder.agent ?? "atlas");
|
|
69813
|
+
const sessionAgentKey = getAgentConfigKey(sessionAgent);
|
|
69814
|
+
if (sessionAgentKey !== requiredAgentKey && !(requiredAgentKey === getAgentConfigKey("atlas") && sessionAgentKey === getAgentConfigKey("sisyphus"))) {
|
|
69815
|
+
return false;
|
|
69816
|
+
}
|
|
69817
|
+
return isTrackedSession || isTrackedDescendant;
|
|
69818
|
+
}
|
|
69819
|
+
async function isTrackedDescendantSession(client3, sessionID, trackedSessionIDs) {
|
|
69820
|
+
const ancestorSessionIDs = trackedSessionIDs.filter((trackedSessionID) => trackedSessionID !== sessionID);
|
|
69821
|
+
if (ancestorSessionIDs.length === 0) {
|
|
69822
|
+
return false;
|
|
69823
|
+
}
|
|
69824
|
+
return isSessionInBoulderLineage({
|
|
69825
|
+
client: client3,
|
|
69826
|
+
sessionID,
|
|
69827
|
+
boulderSessionIDs: ancestorSessionIDs
|
|
69828
|
+
});
|
|
68615
69829
|
}
|
|
68616
69830
|
function hasActiveRalphLoopContinuation(directory, sessionID) {
|
|
68617
|
-
const
|
|
68618
|
-
if (!
|
|
69831
|
+
const state2 = readState(directory);
|
|
69832
|
+
if (!state2 || !state2.active)
|
|
68619
69833
|
return false;
|
|
68620
|
-
if (
|
|
69834
|
+
if (state2.session_id && state2.session_id !== sessionID) {
|
|
68621
69835
|
return false;
|
|
68622
69836
|
}
|
|
68623
69837
|
return true;
|
|
@@ -68626,7 +69840,7 @@ function hasActiveRalphLoopContinuation(directory, sessionID) {
|
|
|
68626
69840
|
// src/cli/run/completion.ts
|
|
68627
69841
|
async function checkCompletionConditions(ctx) {
|
|
68628
69842
|
try {
|
|
68629
|
-
const continuationState = getContinuationState(ctx.directory, ctx.sessionID);
|
|
69843
|
+
const continuationState = await getContinuationState(ctx.directory, ctx.sessionID, ctx.client);
|
|
68630
69844
|
if (continuationState.hasActiveHookMarker) {
|
|
68631
69845
|
const reason = continuationState.activeHookMarkerReason ?? "continuation hook is active";
|
|
68632
69846
|
logWaiting(ctx, reason);
|
|
@@ -68643,7 +69857,7 @@ async function checkCompletionConditions(ctx) {
|
|
|
68643
69857
|
}
|
|
68644
69858
|
return true;
|
|
68645
69859
|
} catch (err) {
|
|
68646
|
-
console.error(
|
|
69860
|
+
console.error(import_picocolors13.default.red(`[completion] API error: ${err}`));
|
|
68647
69861
|
return false;
|
|
68648
69862
|
}
|
|
68649
69863
|
}
|
|
@@ -68704,7 +69918,7 @@ function logWaiting(ctx, message) {
|
|
|
68704
69918
|
if (!ctx.verbose) {
|
|
68705
69919
|
return;
|
|
68706
69920
|
}
|
|
68707
|
-
console.log(
|
|
69921
|
+
console.log(import_picocolors13.default.dim(` Waiting: ${message}`));
|
|
68708
69922
|
}
|
|
68709
69923
|
|
|
68710
69924
|
// src/cli/run/poll-for-completion.ts
|
|
@@ -68735,10 +69949,10 @@ async function pollForCompletion(ctx, eventState, abortController, options = {})
|
|
|
68735
69949
|
if (eventState.mainSessionError) {
|
|
68736
69950
|
errorCycleCount++;
|
|
68737
69951
|
if (errorCycleCount >= ERROR_GRACE_CYCLES) {
|
|
68738
|
-
console.error(
|
|
69952
|
+
console.error(import_picocolors14.default.red(`
|
|
68739
69953
|
|
|
68740
69954
|
Session ended with error: ${eventState.lastError}`));
|
|
68741
|
-
console.error(
|
|
69955
|
+
console.error(import_picocolors14.default.yellow("Check if todos were completed before the error."));
|
|
68742
69956
|
return 1;
|
|
68743
69957
|
}
|
|
68744
69958
|
continue;
|
|
@@ -68749,7 +69963,7 @@ Session ended with error: ${eventState.lastError}`));
|
|
|
68749
69963
|
if (eventState.lastEventTimestamp !== null) {
|
|
68750
69964
|
const timeSinceLastEvent = Date.now() - eventState.lastEventTimestamp;
|
|
68751
69965
|
if (timeSinceLastEvent > eventWatchdogMs) {
|
|
68752
|
-
console.log(
|
|
69966
|
+
console.log(import_picocolors14.default.yellow(`
|
|
68753
69967
|
No events for ${Math.round(timeSinceLastEvent / 1000)}s, verifying session status...`));
|
|
68754
69968
|
mainSessionStatus = await getMainSessionStatus(ctx);
|
|
68755
69969
|
if (mainSessionStatus === "idle") {
|
|
@@ -68798,7 +70012,7 @@ Session ended with error: ${eventState.lastError}`));
|
|
|
68798
70012
|
const hasActiveWork = hasActiveChildren || hasActiveTodos;
|
|
68799
70013
|
if (hasActiveWork) {
|
|
68800
70014
|
eventState.hasReceivedMeaningfulWork = true;
|
|
68801
|
-
console.log(
|
|
70015
|
+
console.log(import_picocolors14.default.yellow(`
|
|
68802
70016
|
No meaningful work events for ${Math.round(secondaryMeaningfulWorkTimeoutMs / 1000)}s but session has active work - assuming in progress`));
|
|
68803
70017
|
}
|
|
68804
70018
|
}
|
|
@@ -68818,7 +70032,7 @@ Session ended with error: ${eventState.lastError}`));
|
|
|
68818
70032
|
}
|
|
68819
70033
|
consecutiveCompleteChecks++;
|
|
68820
70034
|
if (consecutiveCompleteChecks >= requiredConsecutive) {
|
|
68821
|
-
console.log(
|
|
70035
|
+
console.log(import_picocolors14.default.green(`
|
|
68822
70036
|
|
|
68823
70037
|
All tasks completed.`));
|
|
68824
70038
|
return 0;
|
|
@@ -68987,7 +70201,7 @@ async function run(options) {
|
|
|
68987
70201
|
};
|
|
68988
70202
|
const restoreInput = suppressRunInput();
|
|
68989
70203
|
const handleSigint = () => {
|
|
68990
|
-
console.log(
|
|
70204
|
+
console.log(import_picocolors15.default.yellow(`
|
|
68991
70205
|
Interrupted. Shutting down...`));
|
|
68992
70206
|
restoreInput();
|
|
68993
70207
|
cleanup();
|
|
@@ -69000,9 +70214,9 @@ Interrupted. Shutting down...`));
|
|
|
69000
70214
|
sessionId: options.sessionId,
|
|
69001
70215
|
directory
|
|
69002
70216
|
});
|
|
69003
|
-
console.log(
|
|
70217
|
+
console.log(import_picocolors15.default.dim(`Session: ${sessionID}`));
|
|
69004
70218
|
if (resolvedModel) {
|
|
69005
|
-
console.log(
|
|
70219
|
+
console.log(import_picocolors15.default.dim(`Model: ${resolvedModel.providerID}/${resolvedModel.modelID}`));
|
|
69006
70220
|
}
|
|
69007
70221
|
const ctx = {
|
|
69008
70222
|
client: client3,
|
|
@@ -69065,7 +70279,7 @@ Interrupted. Shutting down...`));
|
|
|
69065
70279
|
if (err instanceof Error && err.name === "AbortError") {
|
|
69066
70280
|
return 130;
|
|
69067
70281
|
}
|
|
69068
|
-
console.error(
|
|
70282
|
+
console.error(import_picocolors15.default.red(`Error: ${serializeError(err)}`));
|
|
69069
70283
|
return 1;
|
|
69070
70284
|
} finally {
|
|
69071
70285
|
timestampOutput?.restore();
|
|
@@ -69075,53 +70289,53 @@ Interrupted. Shutting down...`));
|
|
|
69075
70289
|
init_checker();
|
|
69076
70290
|
|
|
69077
70291
|
// src/cli/get-local-version/formatter.ts
|
|
69078
|
-
var
|
|
69079
|
-
var
|
|
69080
|
-
check:
|
|
69081
|
-
cross:
|
|
69082
|
-
arrow:
|
|
69083
|
-
info:
|
|
69084
|
-
warn:
|
|
69085
|
-
pin:
|
|
69086
|
-
dev:
|
|
70292
|
+
var import_picocolors16 = __toESM(require_picocolors(), 1);
|
|
70293
|
+
var SYMBOLS3 = {
|
|
70294
|
+
check: import_picocolors16.default.green("[OK]"),
|
|
70295
|
+
cross: import_picocolors16.default.red("[X]"),
|
|
70296
|
+
arrow: import_picocolors16.default.cyan("->"),
|
|
70297
|
+
info: import_picocolors16.default.blue("[i]"),
|
|
70298
|
+
warn: import_picocolors16.default.yellow("[!]"),
|
|
70299
|
+
pin: import_picocolors16.default.magenta("[PINNED]"),
|
|
70300
|
+
dev: import_picocolors16.default.cyan("[DEV]")
|
|
69087
70301
|
};
|
|
69088
70302
|
function formatVersionOutput(info) {
|
|
69089
70303
|
const lines = [];
|
|
69090
70304
|
lines.push("");
|
|
69091
|
-
lines.push(
|
|
69092
|
-
lines.push(
|
|
70305
|
+
lines.push(import_picocolors16.default.bold(import_picocolors16.default.white("evil-omo Version Information")));
|
|
70306
|
+
lines.push(import_picocolors16.default.dim("\u2500".repeat(50)));
|
|
69093
70307
|
lines.push("");
|
|
69094
70308
|
if (info.currentVersion) {
|
|
69095
|
-
lines.push(` Current Version: ${
|
|
70309
|
+
lines.push(` Current Version: ${import_picocolors16.default.cyan(info.currentVersion)}`);
|
|
69096
70310
|
} else {
|
|
69097
|
-
lines.push(` Current Version: ${
|
|
70311
|
+
lines.push(` Current Version: ${import_picocolors16.default.dim("unknown")}`);
|
|
69098
70312
|
}
|
|
69099
70313
|
if (!info.isLocalDev && info.latestVersion) {
|
|
69100
|
-
lines.push(` Latest Version: ${
|
|
70314
|
+
lines.push(` Latest Version: ${import_picocolors16.default.cyan(info.latestVersion)}`);
|
|
69101
70315
|
}
|
|
69102
70316
|
lines.push("");
|
|
69103
70317
|
switch (info.status) {
|
|
69104
70318
|
case "up-to-date":
|
|
69105
|
-
lines.push(` ${
|
|
70319
|
+
lines.push(` ${SYMBOLS3.check} ${import_picocolors16.default.green("You're up to date!")}`);
|
|
69106
70320
|
break;
|
|
69107
70321
|
case "outdated":
|
|
69108
|
-
lines.push(` ${
|
|
69109
|
-
lines.push(` ${
|
|
70322
|
+
lines.push(` ${SYMBOLS3.warn} ${import_picocolors16.default.yellow("Update available")}`);
|
|
70323
|
+
lines.push(` ${import_picocolors16.default.dim("Run:")} ${import_picocolors16.default.cyan("cd ~/.config/opencode && bun update evil-omo")}`);
|
|
69110
70324
|
break;
|
|
69111
70325
|
case "local-dev":
|
|
69112
|
-
lines.push(` ${
|
|
69113
|
-
lines.push(` ${
|
|
70326
|
+
lines.push(` ${SYMBOLS3.dev} ${import_picocolors16.default.cyan("Running in local development mode")}`);
|
|
70327
|
+
lines.push(` ${import_picocolors16.default.dim("Using file:// protocol from config")}`);
|
|
69114
70328
|
break;
|
|
69115
70329
|
case "pinned":
|
|
69116
|
-
lines.push(` ${
|
|
69117
|
-
lines.push(` ${
|
|
70330
|
+
lines.push(` ${SYMBOLS3.pin} ${import_picocolors16.default.magenta(`Version pinned to ${info.pinnedVersion}`)}`);
|
|
70331
|
+
lines.push(` ${import_picocolors16.default.dim("Update check skipped for pinned versions")}`);
|
|
69118
70332
|
break;
|
|
69119
70333
|
case "error":
|
|
69120
|
-
lines.push(` ${
|
|
69121
|
-
lines.push(` ${
|
|
70334
|
+
lines.push(` ${SYMBOLS3.cross} ${import_picocolors16.default.red("Unable to check for updates")}`);
|
|
70335
|
+
lines.push(` ${import_picocolors16.default.dim("Network error or npm registry unavailable")}`);
|
|
69122
70336
|
break;
|
|
69123
70337
|
case "unknown":
|
|
69124
|
-
lines.push(` ${
|
|
70338
|
+
lines.push(` ${SYMBOLS3.info} ${import_picocolors16.default.yellow("Version information unavailable")}`);
|
|
69125
70339
|
break;
|
|
69126
70340
|
}
|
|
69127
70341
|
lines.push("");
|
|
@@ -69220,69 +70434,31 @@ async function getLocalVersion(options = {}) {
|
|
|
69220
70434
|
return 1;
|
|
69221
70435
|
}
|
|
69222
70436
|
}
|
|
69223
|
-
// src/cli/doctor/constants.ts
|
|
69224
|
-
init_plugin_identity();
|
|
69225
|
-
var import_picocolors16 = __toESM(require_picocolors(), 1);
|
|
69226
|
-
var SYMBOLS3 = {
|
|
69227
|
-
check: import_picocolors16.default.green("\u2713"),
|
|
69228
|
-
cross: import_picocolors16.default.red("\u2717"),
|
|
69229
|
-
warn: import_picocolors16.default.yellow("\u26A0"),
|
|
69230
|
-
info: import_picocolors16.default.blue("\u2139"),
|
|
69231
|
-
arrow: import_picocolors16.default.cyan("\u2192"),
|
|
69232
|
-
bullet: import_picocolors16.default.dim("\u2022"),
|
|
69233
|
-
skip: import_picocolors16.default.dim("\u25CB")
|
|
69234
|
-
};
|
|
69235
|
-
var STATUS_COLORS = {
|
|
69236
|
-
pass: import_picocolors16.default.green,
|
|
69237
|
-
fail: import_picocolors16.default.red,
|
|
69238
|
-
warn: import_picocolors16.default.yellow,
|
|
69239
|
-
skip: import_picocolors16.default.dim
|
|
69240
|
-
};
|
|
69241
|
-
var CHECK_IDS = {
|
|
69242
|
-
SYSTEM: "system",
|
|
69243
|
-
CONFIG: "config",
|
|
69244
|
-
TOOLS: "tools",
|
|
69245
|
-
MODELS: "models"
|
|
69246
|
-
};
|
|
69247
|
-
var CHECK_NAMES = {
|
|
69248
|
-
[CHECK_IDS.SYSTEM]: "System",
|
|
69249
|
-
[CHECK_IDS.CONFIG]: "Configuration",
|
|
69250
|
-
[CHECK_IDS.TOOLS]: "Tools",
|
|
69251
|
-
[CHECK_IDS.MODELS]: "Models"
|
|
69252
|
-
};
|
|
69253
|
-
var EXIT_CODES = {
|
|
69254
|
-
SUCCESS: 0,
|
|
69255
|
-
FAILURE: 1
|
|
69256
|
-
};
|
|
69257
|
-
var MIN_OPENCODE_VERSION = "1.0.150";
|
|
69258
|
-
var PACKAGE_NAME3 = PLUGIN_NAME;
|
|
69259
|
-
var OPENCODE_BINARIES2 = ["opencode", "opencode-desktop"];
|
|
69260
|
-
|
|
69261
70437
|
// src/cli/doctor/checks/system.ts
|
|
69262
|
-
import { existsSync as
|
|
70438
|
+
import { existsSync as existsSync28, readFileSync as readFileSync23 } from "fs";
|
|
69263
70439
|
|
|
69264
70440
|
// src/cli/doctor/checks/system-binary.ts
|
|
69265
70441
|
init_spawn_with_windows_hide();
|
|
69266
|
-
import { existsSync as
|
|
70442
|
+
import { existsSync as existsSync25 } from "fs";
|
|
69267
70443
|
import { homedir as homedir5 } from "os";
|
|
69268
|
-
import { join as
|
|
70444
|
+
import { join as join26 } from "path";
|
|
69269
70445
|
function getDesktopAppPaths(platform) {
|
|
69270
70446
|
const home = homedir5();
|
|
69271
70447
|
switch (platform) {
|
|
69272
70448
|
case "darwin":
|
|
69273
70449
|
return [
|
|
69274
70450
|
"/Applications/OpenCode.app/Contents/MacOS/OpenCode",
|
|
69275
|
-
|
|
70451
|
+
join26(home, "Applications", "OpenCode.app", "Contents", "MacOS", "OpenCode")
|
|
69276
70452
|
];
|
|
69277
70453
|
case "win32": {
|
|
69278
70454
|
const programFiles = process.env.ProgramFiles;
|
|
69279
70455
|
const localAppData = process.env.LOCALAPPDATA;
|
|
69280
70456
|
const paths = [];
|
|
69281
70457
|
if (programFiles) {
|
|
69282
|
-
paths.push(
|
|
70458
|
+
paths.push(join26(programFiles, "OpenCode", "OpenCode.exe"));
|
|
69283
70459
|
}
|
|
69284
70460
|
if (localAppData) {
|
|
69285
|
-
paths.push(
|
|
70461
|
+
paths.push(join26(localAppData, "OpenCode", "OpenCode.exe"));
|
|
69286
70462
|
}
|
|
69287
70463
|
return paths;
|
|
69288
70464
|
}
|
|
@@ -69290,8 +70466,8 @@ function getDesktopAppPaths(platform) {
|
|
|
69290
70466
|
return [
|
|
69291
70467
|
"/usr/bin/opencode",
|
|
69292
70468
|
"/usr/lib/opencode/opencode",
|
|
69293
|
-
|
|
69294
|
-
|
|
70469
|
+
join26(home, "Applications", "opencode-desktop-linux-x86_64.AppImage"),
|
|
70470
|
+
join26(home, "Applications", "opencode-desktop-linux-aarch64.AppImage")
|
|
69295
70471
|
];
|
|
69296
70472
|
default:
|
|
69297
70473
|
return [];
|
|
@@ -69303,7 +70479,7 @@ function buildVersionCommand(binaryPath, platform) {
|
|
|
69303
70479
|
}
|
|
69304
70480
|
return [binaryPath, "--version"];
|
|
69305
70481
|
}
|
|
69306
|
-
function findDesktopBinary(platform = process.platform, checkExists =
|
|
70482
|
+
function findDesktopBinary(platform = process.platform, checkExists = existsSync25) {
|
|
69307
70483
|
for (const desktopPath of getDesktopAppPaths(platform)) {
|
|
69308
70484
|
if (checkExists(desktopPath)) {
|
|
69309
70485
|
return { binary: "opencode", path: desktopPath };
|
|
@@ -69320,7 +70496,7 @@ async function findOpenCodeBinary() {
|
|
|
69320
70496
|
}
|
|
69321
70497
|
return findDesktopBinary();
|
|
69322
70498
|
}
|
|
69323
|
-
async function
|
|
70499
|
+
async function getOpenCodeVersion3(binaryPath, platform = process.platform) {
|
|
69324
70500
|
try {
|
|
69325
70501
|
const command = buildVersionCommand(binaryPath, platform);
|
|
69326
70502
|
const processResult = spawnWithWindowsHide(command, { stdout: "pipe", stderr: "pipe" });
|
|
@@ -69333,10 +70509,10 @@ async function getOpenCodeVersion2(binaryPath, platform = process.platform) {
|
|
|
69333
70509
|
return null;
|
|
69334
70510
|
}
|
|
69335
70511
|
}
|
|
69336
|
-
function
|
|
69337
|
-
const
|
|
69338
|
-
const currentParts =
|
|
69339
|
-
const minimumParts =
|
|
70512
|
+
function compareVersions3(current, minimum) {
|
|
70513
|
+
const parseVersion3 = (version2) => version2.replace(/^v/, "").split("-")[0].split(".").map((part) => Number.parseInt(part, 10) || 0);
|
|
70514
|
+
const currentParts = parseVersion3(current);
|
|
70515
|
+
const minimumParts = parseVersion3(minimum);
|
|
69340
70516
|
const length = Math.max(currentParts.length, minimumParts.length);
|
|
69341
70517
|
for (let index = 0;index < length; index++) {
|
|
69342
70518
|
const currentPart = currentParts[index] ?? 0;
|
|
@@ -69351,12 +70527,12 @@ function compareVersions(current, minimum) {
|
|
|
69351
70527
|
|
|
69352
70528
|
// src/cli/doctor/checks/system-plugin.ts
|
|
69353
70529
|
init_shared();
|
|
69354
|
-
import { existsSync as
|
|
70530
|
+
import { existsSync as existsSync26, readFileSync as readFileSync21 } from "fs";
|
|
69355
70531
|
function detectConfigPath() {
|
|
69356
70532
|
const paths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
|
|
69357
|
-
if (
|
|
70533
|
+
if (existsSync26(paths.configJsonc))
|
|
69358
70534
|
return paths.configJsonc;
|
|
69359
|
-
if (
|
|
70535
|
+
if (existsSync26(paths.configJson))
|
|
69360
70536
|
return paths.configJson;
|
|
69361
70537
|
return null;
|
|
69362
70538
|
}
|
|
@@ -69402,7 +70578,7 @@ function getPluginInfo() {
|
|
|
69402
70578
|
};
|
|
69403
70579
|
}
|
|
69404
70580
|
try {
|
|
69405
|
-
const content =
|
|
70581
|
+
const content = readFileSync21(configPath, "utf-8");
|
|
69406
70582
|
const parsedConfig = parseJsonc(content);
|
|
69407
70583
|
const pluginEntry = findPluginEntry2(parsedConfig.plugin ?? []);
|
|
69408
70584
|
if (!pluginEntry) {
|
|
@@ -69440,37 +70616,37 @@ function getPluginInfo() {
|
|
|
69440
70616
|
init_file_utils();
|
|
69441
70617
|
init_checker();
|
|
69442
70618
|
init_auto_update_checker();
|
|
69443
|
-
import { existsSync as
|
|
70619
|
+
import { existsSync as existsSync27, readFileSync as readFileSync22 } from "fs";
|
|
69444
70620
|
import { homedir as homedir6 } from "os";
|
|
69445
|
-
import { join as
|
|
70621
|
+
import { join as join27 } from "path";
|
|
69446
70622
|
init_shared();
|
|
69447
70623
|
function getPlatformDefaultCacheDir(platform = process.platform) {
|
|
69448
70624
|
if (platform === "darwin")
|
|
69449
|
-
return
|
|
70625
|
+
return join27(homedir6(), "Library", "Caches");
|
|
69450
70626
|
if (platform === "win32")
|
|
69451
|
-
return process.env.LOCALAPPDATA ??
|
|
69452
|
-
return
|
|
70627
|
+
return process.env.LOCALAPPDATA ?? join27(homedir6(), "AppData", "Local");
|
|
70628
|
+
return join27(homedir6(), ".cache");
|
|
69453
70629
|
}
|
|
69454
70630
|
function resolveOpenCodeCacheDir() {
|
|
69455
70631
|
const xdgCacheHome = process.env.XDG_CACHE_HOME;
|
|
69456
70632
|
if (xdgCacheHome)
|
|
69457
|
-
return
|
|
70633
|
+
return join27(xdgCacheHome, "opencode");
|
|
69458
70634
|
const fromShared = getOpenCodeCacheDir();
|
|
69459
|
-
const platformDefault =
|
|
69460
|
-
if (
|
|
70635
|
+
const platformDefault = join27(getPlatformDefaultCacheDir(), "opencode");
|
|
70636
|
+
if (existsSync27(fromShared) || !existsSync27(platformDefault))
|
|
69461
70637
|
return fromShared;
|
|
69462
70638
|
return platformDefault;
|
|
69463
70639
|
}
|
|
69464
70640
|
function resolveExistingDir(dirPath) {
|
|
69465
|
-
if (!
|
|
70641
|
+
if (!existsSync27(dirPath))
|
|
69466
70642
|
return dirPath;
|
|
69467
70643
|
return resolveSymlink(dirPath);
|
|
69468
70644
|
}
|
|
69469
70645
|
function readPackageJson(filePath) {
|
|
69470
|
-
if (!
|
|
70646
|
+
if (!existsSync27(filePath))
|
|
69471
70647
|
return null;
|
|
69472
70648
|
try {
|
|
69473
|
-
const content =
|
|
70649
|
+
const content = readFileSync22(filePath, "utf-8");
|
|
69474
70650
|
return parseJsonc(content);
|
|
69475
70651
|
} catch {
|
|
69476
70652
|
return null;
|
|
@@ -69489,20 +70665,20 @@ function getLoadedPluginVersion() {
|
|
|
69489
70665
|
const candidates = [
|
|
69490
70666
|
{
|
|
69491
70667
|
cacheDir: configDir,
|
|
69492
|
-
cachePackagePath:
|
|
69493
|
-
installedPackagePath:
|
|
70668
|
+
cachePackagePath: join27(configDir, "package.json"),
|
|
70669
|
+
installedPackagePath: join27(configDir, "node_modules", PACKAGE_NAME, "package.json")
|
|
69494
70670
|
},
|
|
69495
70671
|
{
|
|
69496
70672
|
cacheDir,
|
|
69497
|
-
cachePackagePath:
|
|
69498
|
-
installedPackagePath:
|
|
70673
|
+
cachePackagePath: join27(cacheDir, "package.json"),
|
|
70674
|
+
installedPackagePath: join27(cacheDir, "node_modules", PACKAGE_NAME, "package.json")
|
|
69499
70675
|
}
|
|
69500
70676
|
];
|
|
69501
|
-
const selectedCandidate = candidates.find((candidate) =>
|
|
70677
|
+
const selectedCandidate = candidates.find((candidate) => existsSync27(candidate.installedPackagePath)) ?? candidates[0];
|
|
69502
70678
|
const { cacheDir: selectedDir, cachePackagePath, installedPackagePath } = selectedCandidate;
|
|
69503
70679
|
const cachePackage = readPackageJson(cachePackagePath);
|
|
69504
70680
|
const installedPackage = readPackageJson(installedPackagePath);
|
|
69505
|
-
const expectedVersion = normalizeVersion(cachePackage?.dependencies?.[
|
|
70681
|
+
const expectedVersion = normalizeVersion(cachePackage?.dependencies?.[PACKAGE_NAME]);
|
|
69506
70682
|
const loadedVersion = normalizeVersion(installedPackage?.version);
|
|
69507
70683
|
return {
|
|
69508
70684
|
cacheDir: selectedDir,
|
|
@@ -69522,13 +70698,14 @@ function getSuggestedInstallTag(currentVersion) {
|
|
|
69522
70698
|
|
|
69523
70699
|
// src/cli/doctor/checks/system.ts
|
|
69524
70700
|
init_shared();
|
|
70701
|
+
init_plugin_identity();
|
|
69525
70702
|
function isConfigValid(configPath) {
|
|
69526
70703
|
if (!configPath)
|
|
69527
70704
|
return true;
|
|
69528
|
-
if (!
|
|
70705
|
+
if (!existsSync28(configPath))
|
|
69529
70706
|
return false;
|
|
69530
70707
|
try {
|
|
69531
|
-
parseJsonc(
|
|
70708
|
+
parseJsonc(readFileSync23(configPath, "utf-8"));
|
|
69532
70709
|
return true;
|
|
69533
70710
|
} catch {
|
|
69534
70711
|
return false;
|
|
@@ -69551,7 +70728,7 @@ function buildMessage(status, issues) {
|
|
|
69551
70728
|
async function gatherSystemInfo() {
|
|
69552
70729
|
const [binaryInfo, pluginInfo] = await Promise.all([findOpenCodeBinary(), Promise.resolve(getPluginInfo())]);
|
|
69553
70730
|
const loadedInfo = getLoadedPluginVersion();
|
|
69554
|
-
const opencodeVersion = binaryInfo ? await
|
|
70731
|
+
const opencodeVersion = binaryInfo ? await getOpenCodeVersion3(binaryInfo.path) : null;
|
|
69555
70732
|
const pluginVersion = pluginInfo.pinnedVersion ?? loadedInfo.expectedVersion ?? loadedInfo.loadedVersion;
|
|
69556
70733
|
return {
|
|
69557
70734
|
opencodeVersion,
|
|
@@ -69579,7 +70756,7 @@ async function checkSystem() {
|
|
|
69579
70756
|
affects: ["doctor", "run"]
|
|
69580
70757
|
});
|
|
69581
70758
|
}
|
|
69582
|
-
if (systemInfo.opencodeVersion && !
|
|
70759
|
+
if (systemInfo.opencodeVersion && !compareVersions3(systemInfo.opencodeVersion, MIN_OPENCODE_VERSION)) {
|
|
69583
70760
|
issues.push({
|
|
69584
70761
|
title: "OpenCode version below minimum",
|
|
69585
70762
|
description: `Detected ${systemInfo.opencodeVersion}; required >= ${MIN_OPENCODE_VERSION}.`,
|
|
@@ -69590,13 +70767,26 @@ async function checkSystem() {
|
|
|
69590
70767
|
}
|
|
69591
70768
|
if (!pluginInfo.registered) {
|
|
69592
70769
|
issues.push({
|
|
69593
|
-
title: `${
|
|
70770
|
+
title: `${PLUGIN_NAME} is not registered`,
|
|
69594
70771
|
description: "Plugin entry is missing from OpenCode configuration.",
|
|
69595
|
-
fix: `Run: bunx ${
|
|
70772
|
+
fix: `Run: bunx ${PLUGIN_NAME} install`,
|
|
69596
70773
|
severity: "error",
|
|
69597
70774
|
affects: ["all agents"]
|
|
69598
70775
|
});
|
|
69599
70776
|
}
|
|
70777
|
+
if (pluginInfo.entry && !pluginInfo.isLocalDev) {
|
|
70778
|
+
const isLegacyName = pluginInfo.entry === LEGACY_PLUGIN_NAME || pluginInfo.entry.startsWith(`${LEGACY_PLUGIN_NAME}@`);
|
|
70779
|
+
if (isLegacyName) {
|
|
70780
|
+
const suggestedEntry = pluginInfo.entry.replace(LEGACY_PLUGIN_NAME, PLUGIN_NAME);
|
|
70781
|
+
issues.push({
|
|
70782
|
+
title: "Using legacy package name",
|
|
70783
|
+
description: `Your opencode.json references "${LEGACY_PLUGIN_NAME}" which has been renamed to "${PLUGIN_NAME}". The old name may stop working in a future release.`,
|
|
70784
|
+
fix: `Update your opencode.json plugin entry: "${pluginInfo.entry}" \u2192 "${suggestedEntry}"`,
|
|
70785
|
+
severity: "warning",
|
|
70786
|
+
affects: ["plugin loading"]
|
|
70787
|
+
});
|
|
70788
|
+
}
|
|
70789
|
+
}
|
|
69600
70790
|
if (loadedInfo.expectedVersion && loadedInfo.loadedVersion && loadedInfo.expectedVersion !== loadedInfo.loadedVersion) {
|
|
69601
70791
|
issues.push({
|
|
69602
70792
|
title: "Loaded plugin version mismatch",
|
|
@@ -69606,11 +70796,11 @@ async function checkSystem() {
|
|
|
69606
70796
|
affects: ["plugin loading"]
|
|
69607
70797
|
});
|
|
69608
70798
|
}
|
|
69609
|
-
if (systemInfo.loadedVersion && latestVersion && !
|
|
70799
|
+
if (systemInfo.loadedVersion && latestVersion && !compareVersions3(systemInfo.loadedVersion, latestVersion)) {
|
|
69610
70800
|
issues.push({
|
|
69611
70801
|
title: "Loaded plugin is outdated",
|
|
69612
70802
|
description: `Loaded ${systemInfo.loadedVersion}, latest ${latestVersion}.`,
|
|
69613
|
-
fix: `Update: cd "${loadedInfo.cacheDir}" && bun add ${
|
|
70803
|
+
fix: `Update: cd "${loadedInfo.cacheDir}" && bun add ${PLUGIN_NAME}@${installTag}`,
|
|
69614
70804
|
severity: "warning",
|
|
69615
70805
|
affects: ["plugin features"]
|
|
69616
70806
|
});
|
|
@@ -69631,29 +70821,28 @@ async function checkSystem() {
|
|
|
69631
70821
|
}
|
|
69632
70822
|
|
|
69633
70823
|
// src/cli/doctor/checks/config.ts
|
|
69634
|
-
import { readFileSync as
|
|
69635
|
-
import { join as
|
|
70824
|
+
import { readFileSync as readFileSync26 } from "fs";
|
|
70825
|
+
import { join as join31 } from "path";
|
|
69636
70826
|
init_shared();
|
|
69637
|
-
init_plugin_identity();
|
|
69638
70827
|
|
|
69639
70828
|
// src/cli/doctor/checks/model-resolution-cache.ts
|
|
69640
70829
|
init_shared();
|
|
69641
|
-
import { existsSync as
|
|
70830
|
+
import { existsSync as existsSync29, readFileSync as readFileSync24 } from "fs";
|
|
69642
70831
|
import { homedir as homedir7 } from "os";
|
|
69643
|
-
import { join as
|
|
70832
|
+
import { join as join28 } from "path";
|
|
69644
70833
|
function getOpenCodeCacheDir2() {
|
|
69645
70834
|
const xdgCache = process.env.XDG_CACHE_HOME;
|
|
69646
70835
|
if (xdgCache)
|
|
69647
|
-
return
|
|
69648
|
-
return
|
|
70836
|
+
return join28(xdgCache, "opencode");
|
|
70837
|
+
return join28(homedir7(), ".cache", "opencode");
|
|
69649
70838
|
}
|
|
69650
70839
|
function loadAvailableModelsFromCache() {
|
|
69651
|
-
const cacheFile =
|
|
69652
|
-
if (!
|
|
70840
|
+
const cacheFile = join28(getOpenCodeCacheDir2(), "models.json");
|
|
70841
|
+
if (!existsSync29(cacheFile)) {
|
|
69653
70842
|
return { providers: [], modelCount: 0, cacheExists: false };
|
|
69654
70843
|
}
|
|
69655
70844
|
try {
|
|
69656
|
-
const content =
|
|
70845
|
+
const content = readFileSync24(cacheFile, "utf-8");
|
|
69657
70846
|
const data = parseJsonc(content);
|
|
69658
70847
|
const providers = Object.keys(data);
|
|
69659
70848
|
let modelCount = 0;
|
|
@@ -69675,25 +70864,24 @@ init_model_capabilities();
|
|
|
69675
70864
|
|
|
69676
70865
|
// src/cli/doctor/checks/model-resolution-config.ts
|
|
69677
70866
|
init_shared();
|
|
69678
|
-
|
|
69679
|
-
import {
|
|
69680
|
-
|
|
69681
|
-
var USER_CONFIG_DIR2 = getOpenCodeConfigPaths({ binary: "opencode", version: null }).configDir;
|
|
69682
|
-
var PROJECT_CONFIG_DIR = join23(process.cwd(), ".opencode");
|
|
70867
|
+
import { readFileSync as readFileSync25 } from "fs";
|
|
70868
|
+
import { join as join29 } from "path";
|
|
70869
|
+
var PROJECT_CONFIG_DIR = join29(process.cwd(), ".opencode");
|
|
69683
70870
|
function loadOmoConfig() {
|
|
69684
|
-
const projectDetected =
|
|
70871
|
+
const projectDetected = detectPluginConfigFile(PROJECT_CONFIG_DIR);
|
|
69685
70872
|
if (projectDetected.format !== "none") {
|
|
69686
70873
|
try {
|
|
69687
|
-
const content =
|
|
70874
|
+
const content = readFileSync25(projectDetected.path, "utf-8");
|
|
69688
70875
|
return parseJsonc(content);
|
|
69689
70876
|
} catch {
|
|
69690
70877
|
return null;
|
|
69691
70878
|
}
|
|
69692
70879
|
}
|
|
69693
|
-
const
|
|
70880
|
+
const userConfigDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
70881
|
+
const userDetected = detectPluginConfigFile(userConfigDir);
|
|
69694
70882
|
if (userDetected.format !== "none") {
|
|
69695
70883
|
try {
|
|
69696
|
-
const content =
|
|
70884
|
+
const content = readFileSync25(userDetected.path, "utf-8");
|
|
69697
70885
|
return parseJsonc(content);
|
|
69698
70886
|
} catch {
|
|
69699
70887
|
return null;
|
|
@@ -69704,7 +70892,7 @@ function loadOmoConfig() {
|
|
|
69704
70892
|
|
|
69705
70893
|
// src/cli/doctor/checks/model-resolution-details.ts
|
|
69706
70894
|
init_shared();
|
|
69707
|
-
import { join as
|
|
70895
|
+
import { join as join30 } from "path";
|
|
69708
70896
|
|
|
69709
70897
|
// src/cli/doctor/checks/model-resolution-variant.ts
|
|
69710
70898
|
function formatModelWithVariant(model, variant) {
|
|
@@ -69746,7 +70934,7 @@ function formatCapabilityResolutionLabel(mode) {
|
|
|
69746
70934
|
}
|
|
69747
70935
|
function buildModelResolutionDetails(options) {
|
|
69748
70936
|
const details = [];
|
|
69749
|
-
const cacheFile =
|
|
70937
|
+
const cacheFile = join30(getOpenCodeCacheDir(), "models.json");
|
|
69750
70938
|
details.push("\u2550\u2550\u2550 Available Models (from cache) \u2550\u2550\u2550");
|
|
69751
70939
|
details.push("");
|
|
69752
70940
|
if (options.available.cacheExists) {
|
|
@@ -69901,11 +71089,13 @@ async function checkModels() {
|
|
|
69901
71089
|
}
|
|
69902
71090
|
|
|
69903
71091
|
// src/cli/doctor/checks/config.ts
|
|
71092
|
+
var PROJECT_CONFIG_DIR2 = join31(process.cwd(), ".opencode");
|
|
69904
71093
|
function findConfigPath() {
|
|
69905
|
-
const projectConfig =
|
|
71094
|
+
const projectConfig = detectPluginConfigFile(PROJECT_CONFIG_DIR2);
|
|
69906
71095
|
if (projectConfig.format !== "none")
|
|
69907
71096
|
return projectConfig.path;
|
|
69908
|
-
const
|
|
71097
|
+
const userConfigDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
71098
|
+
const userConfig = detectPluginConfigFile(userConfigDir);
|
|
69909
71099
|
if (userConfig.format !== "none")
|
|
69910
71100
|
return userConfig.path;
|
|
69911
71101
|
return null;
|
|
@@ -69916,7 +71106,7 @@ function validateConfig() {
|
|
|
69916
71106
|
return { exists: false, path: null, valid: true, config: null, errors: [] };
|
|
69917
71107
|
}
|
|
69918
71108
|
try {
|
|
69919
|
-
const content =
|
|
71109
|
+
const content = readFileSync26(configPath, "utf-8");
|
|
69920
71110
|
const rawConfig = parseJsonc(content);
|
|
69921
71111
|
const schemaResult = OhMyOpenCodeConfigSchema.safeParse(rawConfig);
|
|
69922
71112
|
if (!schemaResult.success) {
|
|
@@ -70020,9 +71210,9 @@ async function checkConfig() {
|
|
|
70020
71210
|
|
|
70021
71211
|
// src/cli/doctor/checks/dependencies.ts
|
|
70022
71212
|
init_spawn_with_windows_hide();
|
|
70023
|
-
import { existsSync as
|
|
71213
|
+
import { existsSync as existsSync30 } from "fs";
|
|
70024
71214
|
import { createRequire } from "module";
|
|
70025
|
-
import { dirname as
|
|
71215
|
+
import { dirname as dirname8, join as join32 } from "path";
|
|
70026
71216
|
async function checkBinaryExists(binary2) {
|
|
70027
71217
|
try {
|
|
70028
71218
|
const path10 = Bun.which(binary2);
|
|
@@ -70078,15 +71268,15 @@ async function checkAstGrepNapi() {
|
|
|
70078
71268
|
path: null
|
|
70079
71269
|
};
|
|
70080
71270
|
} catch {
|
|
70081
|
-
const { existsSync:
|
|
70082
|
-
const { join:
|
|
71271
|
+
const { existsSync: existsSync31 } = await import("fs");
|
|
71272
|
+
const { join: join33 } = await import("path");
|
|
70083
71273
|
const { homedir: homedir8 } = await import("os");
|
|
70084
71274
|
const pathsToCheck = [
|
|
70085
|
-
|
|
70086
|
-
|
|
71275
|
+
join33(homedir8(), ".config", "opencode", "node_modules", "@ast-grep", "napi"),
|
|
71276
|
+
join33(process.cwd(), "node_modules", "@ast-grep", "napi")
|
|
70087
71277
|
];
|
|
70088
71278
|
for (const napiPath of pathsToCheck) {
|
|
70089
|
-
if (
|
|
71279
|
+
if (existsSync31(napiPath)) {
|
|
70090
71280
|
return {
|
|
70091
71281
|
name: "AST-Grep NAPI",
|
|
70092
71282
|
required: false,
|
|
@@ -70111,8 +71301,8 @@ function findCommentCheckerPackageBinary() {
|
|
|
70111
71301
|
try {
|
|
70112
71302
|
const require2 = createRequire(import.meta.url);
|
|
70113
71303
|
const pkgPath = require2.resolve("@code-yeongyu/comment-checker/package.json");
|
|
70114
|
-
const binaryPath =
|
|
70115
|
-
if (
|
|
71304
|
+
const binaryPath = join32(dirname8(pkgPath), "bin", binaryName);
|
|
71305
|
+
if (existsSync30(binaryPath))
|
|
70116
71306
|
return binaryPath;
|
|
70117
71307
|
} catch {}
|
|
70118
71308
|
return null;
|
|
@@ -70269,16 +71459,15 @@ var BUILTIN_SERVERS = {
|
|
|
70269
71459
|
"kotlin-ls": { command: ["kotlin-lsp"], extensions: [".kt", ".kts"] }
|
|
70270
71460
|
};
|
|
70271
71461
|
// src/tools/lsp/server-config-loader.ts
|
|
70272
|
-
import { existsSync as
|
|
70273
|
-
import { join as
|
|
71462
|
+
import { existsSync as existsSync31, readFileSync as readFileSync27 } from "fs";
|
|
71463
|
+
import { join as join33 } from "path";
|
|
70274
71464
|
init_shared();
|
|
70275
71465
|
init_jsonc_parser();
|
|
70276
|
-
init_plugin_identity();
|
|
70277
71466
|
function loadJsonFile(path10) {
|
|
70278
|
-
if (!
|
|
71467
|
+
if (!existsSync31(path10))
|
|
70279
71468
|
return null;
|
|
70280
71469
|
try {
|
|
70281
|
-
return parseJsonc(
|
|
71470
|
+
return parseJsonc(readFileSync27(path10, "utf-8"));
|
|
70282
71471
|
} catch {
|
|
70283
71472
|
return null;
|
|
70284
71473
|
}
|
|
@@ -70287,9 +71476,9 @@ function getConfigPaths2() {
|
|
|
70287
71476
|
const cwd = process.cwd();
|
|
70288
71477
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
70289
71478
|
return {
|
|
70290
|
-
project:
|
|
70291
|
-
user:
|
|
70292
|
-
opencode: detectConfigFile(
|
|
71479
|
+
project: detectPluginConfigFile(join33(cwd, ".opencode")).path,
|
|
71480
|
+
user: detectPluginConfigFile(configDir).path,
|
|
71481
|
+
opencode: detectConfigFile(join33(configDir, "opencode")).path
|
|
70293
71482
|
};
|
|
70294
71483
|
}
|
|
70295
71484
|
function loadAllConfigs() {
|
|
@@ -70358,21 +71547,21 @@ function getMergedServers() {
|
|
|
70358
71547
|
}
|
|
70359
71548
|
|
|
70360
71549
|
// src/tools/lsp/server-installation.ts
|
|
70361
|
-
import { existsSync as
|
|
70362
|
-
import { delimiter as delimiter2, join as
|
|
71550
|
+
import { existsSync as existsSync32 } from "fs";
|
|
71551
|
+
import { delimiter as delimiter2, join as join35 } from "path";
|
|
70363
71552
|
|
|
70364
71553
|
// src/tools/lsp/server-path-bases.ts
|
|
70365
71554
|
init_shared();
|
|
70366
|
-
import { join as
|
|
71555
|
+
import { join as join34 } from "path";
|
|
70367
71556
|
function getLspServerAdditionalPathBases(workingDirectory) {
|
|
70368
71557
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
70369
|
-
const dataDir =
|
|
71558
|
+
const dataDir = join34(getDataDir(), "opencode");
|
|
70370
71559
|
return [
|
|
70371
|
-
|
|
70372
|
-
|
|
70373
|
-
|
|
70374
|
-
|
|
70375
|
-
|
|
71560
|
+
join34(workingDirectory, "node_modules", ".bin"),
|
|
71561
|
+
join34(configDir, "bin"),
|
|
71562
|
+
join34(configDir, "node_modules", ".bin"),
|
|
71563
|
+
join34(dataDir, "bin"),
|
|
71564
|
+
join34(dataDir, "bin", "node_modules", ".bin")
|
|
70376
71565
|
];
|
|
70377
71566
|
}
|
|
70378
71567
|
|
|
@@ -70382,7 +71571,7 @@ function isServerInstalled(command) {
|
|
|
70382
71571
|
return false;
|
|
70383
71572
|
const cmd = command[0];
|
|
70384
71573
|
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
70385
|
-
if (
|
|
71574
|
+
if (existsSync32(cmd))
|
|
70386
71575
|
return true;
|
|
70387
71576
|
}
|
|
70388
71577
|
const isWindows = process.platform === "win32";
|
|
@@ -70403,14 +71592,14 @@ function isServerInstalled(command) {
|
|
|
70403
71592
|
const paths = pathEnv.split(delimiter2);
|
|
70404
71593
|
for (const p2 of paths) {
|
|
70405
71594
|
for (const suffix of exts) {
|
|
70406
|
-
if (
|
|
71595
|
+
if (existsSync32(join35(p2, cmd + suffix))) {
|
|
70407
71596
|
return true;
|
|
70408
71597
|
}
|
|
70409
71598
|
}
|
|
70410
71599
|
}
|
|
70411
71600
|
for (const base of getLspServerAdditionalPathBases(process.cwd())) {
|
|
70412
71601
|
for (const suffix of exts) {
|
|
70413
|
-
if (
|
|
71602
|
+
if (existsSync32(join35(base, cmd + suffix))) {
|
|
70414
71603
|
return true;
|
|
70415
71604
|
}
|
|
70416
71605
|
}
|
|
@@ -70472,24 +71661,24 @@ function getInstalledLspServers() {
|
|
|
70472
71661
|
|
|
70473
71662
|
// src/cli/doctor/checks/tools-mcp.ts
|
|
70474
71663
|
init_shared();
|
|
70475
|
-
import { existsSync as
|
|
71664
|
+
import { existsSync as existsSync33, readFileSync as readFileSync28 } from "fs";
|
|
70476
71665
|
import { homedir as homedir8 } from "os";
|
|
70477
|
-
import { join as
|
|
71666
|
+
import { join as join36 } from "path";
|
|
70478
71667
|
var BUILTIN_MCP_SERVERS = ["context7", "grep_app"];
|
|
70479
71668
|
function getMcpConfigPaths() {
|
|
70480
71669
|
return [
|
|
70481
|
-
|
|
70482
|
-
|
|
70483
|
-
|
|
71670
|
+
join36(homedir8(), ".claude", ".mcp.json"),
|
|
71671
|
+
join36(process.cwd(), ".mcp.json"),
|
|
71672
|
+
join36(process.cwd(), ".claude", ".mcp.json")
|
|
70484
71673
|
];
|
|
70485
71674
|
}
|
|
70486
71675
|
function loadUserMcpConfig() {
|
|
70487
71676
|
const servers = {};
|
|
70488
71677
|
for (const configPath of getMcpConfigPaths()) {
|
|
70489
|
-
if (!
|
|
71678
|
+
if (!existsSync33(configPath))
|
|
70490
71679
|
continue;
|
|
70491
71680
|
try {
|
|
70492
|
-
const content =
|
|
71681
|
+
const content = readFileSync28(configPath, "utf-8");
|
|
70493
71682
|
const config2 = parseJsonc(content);
|
|
70494
71683
|
if (config2.mcpServers) {
|
|
70495
71684
|
Object.assign(servers, config2.mcpServers);
|
|
@@ -70656,17 +71845,17 @@ function formatStatusSymbol(status) {
|
|
|
70656
71845
|
const colorFn = STATUS_COLORS[status];
|
|
70657
71846
|
switch (status) {
|
|
70658
71847
|
case "pass":
|
|
70659
|
-
return colorFn(
|
|
71848
|
+
return colorFn(SYMBOLS2.check);
|
|
70660
71849
|
case "fail":
|
|
70661
|
-
return colorFn(
|
|
71850
|
+
return colorFn(SYMBOLS2.cross);
|
|
70662
71851
|
case "warn":
|
|
70663
|
-
return colorFn(
|
|
71852
|
+
return colorFn(SYMBOLS2.warn);
|
|
70664
71853
|
case "skip":
|
|
70665
|
-
return colorFn(
|
|
71854
|
+
return colorFn(SYMBOLS2.skip);
|
|
70666
71855
|
}
|
|
70667
71856
|
}
|
|
70668
71857
|
function formatStatusMark(available) {
|
|
70669
|
-
return available ? import_picocolors17.default.green(
|
|
71858
|
+
return available ? import_picocolors17.default.green(SYMBOLS2.check) : import_picocolors17.default.red(SYMBOLS2.cross);
|
|
70670
71859
|
}
|
|
70671
71860
|
function formatHeader() {
|
|
70672
71861
|
return `
|
|
@@ -70689,7 +71878,6 @@ function formatIssue(issue2, index) {
|
|
|
70689
71878
|
}
|
|
70690
71879
|
|
|
70691
71880
|
// src/cli/doctor/format-default.ts
|
|
70692
|
-
init_plugin_identity();
|
|
70693
71881
|
function formatDefault(result) {
|
|
70694
71882
|
const lines = [];
|
|
70695
71883
|
lines.push(formatHeader());
|
|
@@ -70697,12 +71885,12 @@ function formatDefault(result) {
|
|
|
70697
71885
|
if (allIssues.length === 0) {
|
|
70698
71886
|
const opencodeVer = result.systemInfo.opencodeVersion ?? "unknown";
|
|
70699
71887
|
const pluginVer = result.systemInfo.pluginVersion ?? "unknown";
|
|
70700
|
-
lines.push(` ${import_picocolors18.default.green(
|
|
71888
|
+
lines.push(` ${import_picocolors18.default.green(SYMBOLS2.check)} ${import_picocolors18.default.green(`System OK (opencode ${opencodeVer} \xB7 evil-omo ${pluginVer})`)}`);
|
|
70701
71889
|
} else {
|
|
70702
71890
|
const issueCount = allIssues.filter((i2) => i2.severity === "error").length;
|
|
70703
71891
|
const warnCount = allIssues.filter((i2) => i2.severity === "warning").length;
|
|
70704
71892
|
const totalStr = `${issueCount + warnCount} ${issueCount + warnCount === 1 ? "issue" : "issues"}`;
|
|
70705
|
-
lines.push(` ${import_picocolors18.default.yellow(
|
|
71893
|
+
lines.push(` ${import_picocolors18.default.yellow(SYMBOLS2.warn)} ${totalStr} found:
|
|
70706
71894
|
`);
|
|
70707
71895
|
allIssues.forEach((issue2, index) => {
|
|
70708
71896
|
lines.push(formatIssue(issue2, index + 1));
|
|
@@ -70745,7 +71933,6 @@ function formatStatus(result) {
|
|
|
70745
71933
|
|
|
70746
71934
|
// src/cli/doctor/format-verbose.ts
|
|
70747
71935
|
var import_picocolors20 = __toESM(require_picocolors(), 1);
|
|
70748
|
-
init_plugin_identity();
|
|
70749
71936
|
function formatVerbose(result) {
|
|
70750
71937
|
const lines = [];
|
|
70751
71938
|
lines.push(formatHeader());
|
|
@@ -70753,7 +71940,7 @@ function formatVerbose(result) {
|
|
|
70753
71940
|
lines.push(`${import_picocolors20.default.bold("System Information")}`);
|
|
70754
71941
|
lines.push(`${import_picocolors20.default.dim("\u2500".repeat(40))}`);
|
|
70755
71942
|
lines.push(` ${formatStatusSymbol("pass")} opencode ${systemInfo.opencodeVersion ?? "unknown"}`);
|
|
70756
|
-
lines.push(` ${formatStatusSymbol("pass")}
|
|
71943
|
+
lines.push(` ${formatStatusSymbol("pass")} evil-omo ${systemInfo.pluginVersion ?? "unknown"}`);
|
|
70757
71944
|
if (systemInfo.loadedVersion) {
|
|
70758
71945
|
lines.push(` ${formatStatusSymbol("pass")} loaded ${systemInfo.loadedVersion}`);
|
|
70759
71946
|
}
|
|
@@ -70910,13 +72097,45 @@ async function doctor(options = { mode: "default" }) {
|
|
|
70910
72097
|
return result.exitCode;
|
|
70911
72098
|
}
|
|
70912
72099
|
|
|
72100
|
+
// src/cli/refresh-model-capabilities.ts
|
|
72101
|
+
init_model_capabilities_cache();
|
|
72102
|
+
async function refreshModelCapabilities(options, deps = {}) {
|
|
72103
|
+
const directory = options.directory ?? process.cwd();
|
|
72104
|
+
const loadConfig = deps.loadConfig ?? loadPluginConfig;
|
|
72105
|
+
const refreshCache = deps.refreshCache ?? refreshModelCapabilitiesCache;
|
|
72106
|
+
const stdout = deps.stdout ?? process.stdout;
|
|
72107
|
+
const stderr = deps.stderr ?? process.stderr;
|
|
72108
|
+
try {
|
|
72109
|
+
const config2 = loadConfig(directory, null);
|
|
72110
|
+
const sourceUrl = options.sourceUrl ?? config2.model_capabilities?.source_url;
|
|
72111
|
+
const snapshot = await refreshCache({ sourceUrl });
|
|
72112
|
+
const summary = {
|
|
72113
|
+
sourceUrl: snapshot.sourceUrl,
|
|
72114
|
+
generatedAt: snapshot.generatedAt,
|
|
72115
|
+
modelCount: Object.keys(snapshot.models).length
|
|
72116
|
+
};
|
|
72117
|
+
if (options.json) {
|
|
72118
|
+
stdout.write(`${JSON.stringify(summary, null, 2)}
|
|
72119
|
+
`);
|
|
72120
|
+
} else {
|
|
72121
|
+
stdout.write(`Refreshed model capabilities cache (${summary.modelCount} models) from ${summary.sourceUrl}
|
|
72122
|
+
`);
|
|
72123
|
+
}
|
|
72124
|
+
return 0;
|
|
72125
|
+
} catch (error48) {
|
|
72126
|
+
stderr.write(`Failed to refresh model capabilities cache: ${String(error48)}
|
|
72127
|
+
`);
|
|
72128
|
+
return 1;
|
|
72129
|
+
}
|
|
72130
|
+
}
|
|
72131
|
+
|
|
70913
72132
|
// src/features/mcp-oauth/storage.ts
|
|
70914
72133
|
init_shared();
|
|
70915
|
-
import { chmodSync, existsSync as
|
|
70916
|
-
import { dirname as
|
|
72134
|
+
import { chmodSync, existsSync as existsSync34, mkdirSync as mkdirSync9, readFileSync as readFileSync29, renameSync as renameSync3, unlinkSync as unlinkSync4, writeFileSync as writeFileSync10 } from "fs";
|
|
72135
|
+
import { dirname as dirname9, join as join37 } from "path";
|
|
70917
72136
|
var STORAGE_FILE_NAME = "mcp-oauth.json";
|
|
70918
72137
|
function getMcpOauthStoragePath() {
|
|
70919
|
-
return
|
|
72138
|
+
return join37(getOpenCodeConfigDir({ binary: "opencode" }), STORAGE_FILE_NAME);
|
|
70920
72139
|
}
|
|
70921
72140
|
function normalizeHost(serverHost) {
|
|
70922
72141
|
let host = serverHost.trim();
|
|
@@ -70953,11 +72172,11 @@ function buildKey(serverHost, resource) {
|
|
|
70953
72172
|
}
|
|
70954
72173
|
function readStore() {
|
|
70955
72174
|
const filePath = getMcpOauthStoragePath();
|
|
70956
|
-
if (!
|
|
72175
|
+
if (!existsSync34(filePath)) {
|
|
70957
72176
|
return null;
|
|
70958
72177
|
}
|
|
70959
72178
|
try {
|
|
70960
|
-
const content =
|
|
72179
|
+
const content = readFileSync29(filePath, "utf-8");
|
|
70961
72180
|
return JSON.parse(content);
|
|
70962
72181
|
} catch {
|
|
70963
72182
|
return null;
|
|
@@ -70966,12 +72185,14 @@ function readStore() {
|
|
|
70966
72185
|
function writeStore(store2) {
|
|
70967
72186
|
const filePath = getMcpOauthStoragePath();
|
|
70968
72187
|
try {
|
|
70969
|
-
const dir =
|
|
70970
|
-
if (!
|
|
70971
|
-
|
|
70972
|
-
}
|
|
70973
|
-
|
|
70974
|
-
|
|
72188
|
+
const dir = dirname9(filePath);
|
|
72189
|
+
if (!existsSync34(dir)) {
|
|
72190
|
+
mkdirSync9(dir, { recursive: true });
|
|
72191
|
+
}
|
|
72192
|
+
const tempPath = `${filePath}.tmp.${Date.now()}`;
|
|
72193
|
+
writeFileSync10(tempPath, JSON.stringify(store2, null, 2), { encoding: "utf-8", mode: 384 });
|
|
72194
|
+
chmodSync(tempPath, 384);
|
|
72195
|
+
renameSync3(tempPath, filePath);
|
|
70975
72196
|
return true;
|
|
70976
72197
|
} catch {
|
|
70977
72198
|
return false;
|
|
@@ -71002,7 +72223,7 @@ function deleteToken(serverHost, resource) {
|
|
|
71002
72223
|
if (Object.keys(store2).length === 0) {
|
|
71003
72224
|
try {
|
|
71004
72225
|
const filePath = getMcpOauthStoragePath();
|
|
71005
|
-
if (
|
|
72226
|
+
if (existsSync34(filePath)) {
|
|
71006
72227
|
unlinkSync4(filePath);
|
|
71007
72228
|
}
|
|
71008
72229
|
return true;
|
|
@@ -71192,7 +72413,7 @@ async function findAvailablePort2(startPort = DEFAULT_PORT) {
|
|
|
71192
72413
|
}
|
|
71193
72414
|
|
|
71194
72415
|
// src/features/mcp-oauth/oauth-authorization-flow.ts
|
|
71195
|
-
import { spawn
|
|
72416
|
+
import { spawn } from "child_process";
|
|
71196
72417
|
import { createHash, randomBytes as randomBytes2 } from "crypto";
|
|
71197
72418
|
import { createServer } from "http";
|
|
71198
72419
|
function generateCodeVerifier() {
|
|
@@ -71225,7 +72446,7 @@ function startCallbackServer(port) {
|
|
|
71225
72446
|
clearTimeout(timeoutId);
|
|
71226
72447
|
const requestUrl = new URL(request.url ?? "/", `http://localhost:${port}`);
|
|
71227
72448
|
const code = requestUrl.searchParams.get("code");
|
|
71228
|
-
const
|
|
72449
|
+
const state2 = requestUrl.searchParams.get("state");
|
|
71229
72450
|
const error48 = requestUrl.searchParams.get("error");
|
|
71230
72451
|
if (error48) {
|
|
71231
72452
|
const errorDescription = requestUrl.searchParams.get("error_description") ?? error48;
|
|
@@ -71235,7 +72456,7 @@ function startCallbackServer(port) {
|
|
|
71235
72456
|
reject(new Error(`OAuth authorization error: ${errorDescription}`));
|
|
71236
72457
|
return;
|
|
71237
72458
|
}
|
|
71238
|
-
if (!code || !
|
|
72459
|
+
if (!code || !state2) {
|
|
71239
72460
|
response.writeHead(400, { "content-type": "text/html" });
|
|
71240
72461
|
response.end("<html><body><h1>Missing code or state</h1></body></html>");
|
|
71241
72462
|
server2.close();
|
|
@@ -71245,7 +72466,7 @@ function startCallbackServer(port) {
|
|
|
71245
72466
|
response.writeHead(200, { "content-type": "text/html" });
|
|
71246
72467
|
response.end("<html><body><h1>Authorization successful. You can close this tab.</h1></body></html>");
|
|
71247
72468
|
server2.close();
|
|
71248
|
-
resolve2({ code, state });
|
|
72469
|
+
resolve2({ code, state: state2 });
|
|
71249
72470
|
});
|
|
71250
72471
|
timeoutId = setTimeout(() => {
|
|
71251
72472
|
server2.close();
|
|
@@ -71273,7 +72494,7 @@ function openBrowser(url2) {
|
|
|
71273
72494
|
args = [url2];
|
|
71274
72495
|
}
|
|
71275
72496
|
try {
|
|
71276
|
-
const child =
|
|
72497
|
+
const child = spawn(command, args, { stdio: "ignore", detached: true });
|
|
71277
72498
|
child.on("error", () => {});
|
|
71278
72499
|
child.unref();
|
|
71279
72500
|
} catch {}
|
|
@@ -71281,26 +72502,56 @@ function openBrowser(url2) {
|
|
|
71281
72502
|
async function runAuthorizationCodeRedirect(options) {
|
|
71282
72503
|
const verifier = generateCodeVerifier();
|
|
71283
72504
|
const challenge = generateCodeChallenge(verifier);
|
|
71284
|
-
const
|
|
72505
|
+
const state2 = randomBytes2(16).toString("hex");
|
|
71285
72506
|
const authorizationUrl = buildAuthorizationUrl(options.authorizationEndpoint, {
|
|
71286
72507
|
clientId: options.clientId,
|
|
71287
72508
|
redirectUri: options.redirectUri,
|
|
71288
72509
|
codeChallenge: challenge,
|
|
71289
|
-
state,
|
|
72510
|
+
state: state2,
|
|
71290
72511
|
scopes: options.scopes,
|
|
71291
72512
|
resource: options.resource
|
|
71292
72513
|
});
|
|
71293
72514
|
const callbackPromise = startCallbackServer(options.callbackPort);
|
|
71294
72515
|
openBrowser(authorizationUrl);
|
|
71295
72516
|
const result = await callbackPromise;
|
|
71296
|
-
if (result.state !==
|
|
72517
|
+
if (result.state !== state2) {
|
|
71297
72518
|
throw new Error("OAuth state mismatch");
|
|
71298
72519
|
}
|
|
71299
72520
|
return { code: result.code, verifier };
|
|
71300
72521
|
}
|
|
71301
72522
|
|
|
71302
72523
|
// src/features/mcp-oauth/provider.ts
|
|
71303
|
-
|
|
72524
|
+
async function parseTokenResponse(tokenResponse) {
|
|
72525
|
+
if (!tokenResponse.ok) {
|
|
72526
|
+
let errorDetail = `${tokenResponse.status}`;
|
|
72527
|
+
try {
|
|
72528
|
+
const body = await tokenResponse.json();
|
|
72529
|
+
if (body.error) {
|
|
72530
|
+
errorDetail = `${tokenResponse.status} ${body.error}`;
|
|
72531
|
+
if (body.error_description) {
|
|
72532
|
+
errorDetail += `: ${body.error_description}`;
|
|
72533
|
+
}
|
|
72534
|
+
}
|
|
72535
|
+
} catch {}
|
|
72536
|
+
throw new Error(`Token exchange failed: ${errorDetail}`);
|
|
72537
|
+
}
|
|
72538
|
+
return await tokenResponse.json();
|
|
72539
|
+
}
|
|
72540
|
+
function buildOAuthTokenData(tokenData, clientInfo, fallbackRefreshToken) {
|
|
72541
|
+
const accessToken = tokenData.access_token;
|
|
72542
|
+
if (typeof accessToken !== "string") {
|
|
72543
|
+
throw new Error("Token response missing access_token");
|
|
72544
|
+
}
|
|
72545
|
+
return {
|
|
72546
|
+
accessToken,
|
|
72547
|
+
refreshToken: typeof tokenData.refresh_token === "string" ? tokenData.refresh_token : fallbackRefreshToken,
|
|
72548
|
+
expiresAt: typeof tokenData.expires_in === "number" ? Math.floor(Date.now() / 1000) + tokenData.expires_in : undefined,
|
|
72549
|
+
clientInfo: {
|
|
72550
|
+
clientId: clientInfo.clientId,
|
|
72551
|
+
...clientInfo.clientSecret ? { clientSecret: clientInfo.clientSecret } : {}
|
|
72552
|
+
}
|
|
72553
|
+
};
|
|
72554
|
+
}
|
|
71304
72555
|
|
|
71305
72556
|
class McpOAuthProvider {
|
|
71306
72557
|
serverUrl;
|
|
@@ -71369,7 +72620,7 @@ class McpOAuthProvider {
|
|
|
71369
72620
|
const clientInfo = await getOrRegisterClient({
|
|
71370
72621
|
registrationEndpoint: metadata.registrationEndpoint,
|
|
71371
72622
|
serverIdentifier: this.serverUrl,
|
|
71372
|
-
clientName:
|
|
72623
|
+
clientName: "evil-omo",
|
|
71373
72624
|
redirectUris: [this.redirectUrl()],
|
|
71374
72625
|
tokenEndpointAuthMethod: "none",
|
|
71375
72626
|
clientId: this.configClientId,
|
|
@@ -71396,33 +72647,34 @@ class McpOAuthProvider {
|
|
|
71396
72647
|
...metadata.resource ? { resource: metadata.resource } : {}
|
|
71397
72648
|
}).toString()
|
|
71398
72649
|
});
|
|
71399
|
-
|
|
71400
|
-
|
|
71401
|
-
|
|
71402
|
-
|
|
71403
|
-
|
|
71404
|
-
|
|
71405
|
-
|
|
71406
|
-
|
|
71407
|
-
|
|
71408
|
-
|
|
71409
|
-
|
|
71410
|
-
throw new Error(`Token exchange failed: ${errorDetail}`);
|
|
71411
|
-
}
|
|
71412
|
-
const tokenData = await tokenResponse.json();
|
|
71413
|
-
const accessToken = tokenData.access_token;
|
|
71414
|
-
if (typeof accessToken !== "string") {
|
|
71415
|
-
throw new Error("Token response missing access_token");
|
|
72650
|
+
const tokenData = await parseTokenResponse(tokenResponse);
|
|
72651
|
+
const oauthTokenData = buildOAuthTokenData(tokenData, clientInfo);
|
|
72652
|
+
this.saveTokens(oauthTokenData);
|
|
72653
|
+
return oauthTokenData;
|
|
72654
|
+
}
|
|
72655
|
+
async refresh(refreshToken) {
|
|
72656
|
+
const metadata = await discoverOAuthServerMetadata(this.serverUrl);
|
|
72657
|
+
const clientInfo = this.clientInformation();
|
|
72658
|
+
const clientId = clientInfo?.clientId ?? this.configClientId;
|
|
72659
|
+
if (!clientId) {
|
|
72660
|
+
throw new Error("No client information available. Run login() or register a client first.");
|
|
71416
72661
|
}
|
|
71417
|
-
const
|
|
71418
|
-
|
|
71419
|
-
|
|
71420
|
-
|
|
71421
|
-
|
|
71422
|
-
|
|
71423
|
-
|
|
71424
|
-
|
|
71425
|
-
|
|
72662
|
+
const tokenResponse = await fetch(metadata.tokenEndpoint, {
|
|
72663
|
+
method: "POST",
|
|
72664
|
+
headers: { "content-type": "application/x-www-form-urlencoded" },
|
|
72665
|
+
body: new URLSearchParams({
|
|
72666
|
+
grant_type: "refresh_token",
|
|
72667
|
+
refresh_token: refreshToken,
|
|
72668
|
+
client_id: clientId,
|
|
72669
|
+
...clientInfo?.clientSecret ? { client_secret: clientInfo.clientSecret } : {},
|
|
72670
|
+
...metadata.resource ? { resource: metadata.resource } : {}
|
|
72671
|
+
}).toString()
|
|
72672
|
+
});
|
|
72673
|
+
const tokenData = await parseTokenResponse(tokenResponse);
|
|
72674
|
+
const oauthTokenData = buildOAuthTokenData(tokenData, {
|
|
72675
|
+
clientId,
|
|
72676
|
+
...clientInfo?.clientSecret ? { clientSecret: clientInfo.clientSecret } : {}
|
|
72677
|
+
}, refreshToken);
|
|
71426
72678
|
this.saveTokens(oauthTokenData);
|
|
71427
72679
|
return oauthTokenData;
|
|
71428
72680
|
}
|
|
@@ -71560,7 +72812,7 @@ Examples:
|
|
|
71560
72812
|
Model Providers (Priority: Native > Copilot > OpenCode Zen > Z.ai > Kimi):
|
|
71561
72813
|
Claude Native anthropic/ models (Opus, Sonnet, Haiku)
|
|
71562
72814
|
OpenAI Native openai/ models (GPT-5.4 for Oracle)
|
|
71563
|
-
Gemini Native google/ models (Gemini 3 Pro, Flash)
|
|
72815
|
+
Gemini Native google/ models (Gemini 3.1 Pro, Flash)
|
|
71564
72816
|
Copilot github-copilot/ models (fallback)
|
|
71565
72817
|
OpenCode Zen opencode/ models (opencode/claude-opus-4-6, etc.)
|
|
71566
72818
|
Z.ai zai-coding-plan/glm-5 (visual-engineering fallback)
|
|
@@ -71660,6 +72912,14 @@ Examples:
|
|
|
71660
72912
|
const exitCode = await doctor(doctorOptions);
|
|
71661
72913
|
process.exit(exitCode);
|
|
71662
72914
|
});
|
|
72915
|
+
program2.command("refresh-model-capabilities").description("Refresh the cached models.dev-based model capabilities snapshot").option("-d, --directory <path>", "Working directory to read evil-omo config from").option("--source-url <url>", "Override the models.dev source URL").option("--json", "Output refresh summary as JSON").action(async (options) => {
|
|
72916
|
+
const exitCode = await refreshModelCapabilities({
|
|
72917
|
+
directory: options.directory,
|
|
72918
|
+
sourceUrl: options.sourceUrl,
|
|
72919
|
+
json: options.json ?? false
|
|
72920
|
+
});
|
|
72921
|
+
process.exit(exitCode);
|
|
72922
|
+
});
|
|
71663
72923
|
program2.command("version").description("Show version information").action(() => {
|
|
71664
72924
|
console.log(`evil-omo v${VERSION2}`);
|
|
71665
72925
|
});
|