oh-my-opencode 3.7.1 → 3.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/prometheus/identity-constraints.d.ts +1 -1
- package/dist/agents/prometheus/system-prompt.d.ts +1 -1
- package/dist/cli/index.js +922 -325
- package/dist/cli/run/agent-profile-colors.d.ts +2 -0
- package/dist/cli/run/continuation-state.d.ts +9 -0
- package/dist/cli/run/display-chars.d.ts +5 -0
- package/dist/cli/run/event-handlers.d.ts +1 -0
- package/dist/cli/run/event-state.d.ts +30 -0
- package/dist/cli/run/output-renderer.d.ts +7 -0
- package/dist/cli/run/tool-input-preview.d.ts +6 -0
- package/dist/cli/run/types.d.ts +12 -1
- package/dist/config/schema/hooks.d.ts +2 -0
- package/dist/config/schema/oh-my-opencode-config.d.ts +2 -0
- package/dist/create-hooks.d.ts +2 -0
- package/dist/features/run-continuation-state/constants.d.ts +1 -0
- package/dist/features/run-continuation-state/index.d.ts +3 -0
- package/dist/features/run-continuation-state/storage.d.ts +6 -0
- package/dist/features/run-continuation-state/types.d.ts +12 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/json-error-recovery/hook.d.ts +15 -0
- package/dist/hooks/json-error-recovery/index.d.ts +1 -0
- package/dist/hooks/sisyphus-gpt-hephaestus-reminder/hook.d.ts +11 -0
- package/dist/hooks/sisyphus-gpt-hephaestus-reminder/index.d.ts +1 -0
- package/dist/hooks/stop-continuation-guard/hook.d.ts +1 -1
- package/dist/index.js +866 -686
- package/dist/plugin/hooks/create-core-hooks.d.ts +2 -0
- package/dist/plugin/hooks/create-session-hooks.d.ts +3 -1
- package/package.json +8 -8
package/dist/cli/index.js
CHANGED
|
@@ -4440,7 +4440,7 @@ function renamed(from, to) {
|
|
|
4440
4440
|
};
|
|
4441
4441
|
}
|
|
4442
4442
|
var isNothing_1, isObject_1, toArray_1, repeat_1, isNegativeZero_1, extend_1, common, exception, snippet, TYPE_CONSTRUCTOR_OPTIONS, YAML_NODE_KINDS, type, schema, str, seq, map, failsafe, _null, bool, int, YAML_FLOAT_PATTERN, SCIENTIFIC_WITHOUT_DOT, float, json, core, YAML_DATE_REGEXP, YAML_TIMESTAMP_REGEXP, timestamp, merge, BASE64_MAP = `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
|
|
4443
|
-
\r`, binary, _hasOwnProperty$3, _toString$2, omap, _toString$1, pairs, _hasOwnProperty$2, set, _default, _hasOwnProperty$1, CONTEXT_FLOW_IN = 1, CONTEXT_FLOW_OUT = 2, CONTEXT_BLOCK_IN = 3, CONTEXT_BLOCK_OUT = 4, CHOMPING_CLIP = 1, CHOMPING_STRIP = 2, CHOMPING_KEEP = 3, PATTERN_NON_PRINTABLE, PATTERN_NON_ASCII_LINE_BREAKS, PATTERN_FLOW_INDICATORS, PATTERN_TAG_HANDLE, PATTERN_TAG_URI, simpleEscapeCheck, simpleEscapeMap, i, directiveHandlers, loadAll_1, load_1, loader, _toString, _hasOwnProperty, CHAR_BOM = 65279, CHAR_TAB = 9, CHAR_LINE_FEED = 10, CHAR_CARRIAGE_RETURN = 13, CHAR_SPACE = 32, CHAR_EXCLAMATION = 33, CHAR_DOUBLE_QUOTE = 34, CHAR_SHARP = 35, CHAR_PERCENT = 37, CHAR_AMPERSAND = 38, CHAR_SINGLE_QUOTE = 39, CHAR_ASTERISK = 42, CHAR_COMMA = 44, CHAR_MINUS = 45, CHAR_COLON = 58, CHAR_EQUALS = 61, CHAR_GREATER_THAN = 62, CHAR_QUESTION = 63, CHAR_COMMERCIAL_AT = 64, CHAR_LEFT_SQUARE_BRACKET = 91, CHAR_RIGHT_SQUARE_BRACKET = 93, CHAR_GRAVE_ACCENT = 96, CHAR_LEFT_CURLY_BRACKET = 123, CHAR_VERTICAL_LINE = 124, CHAR_RIGHT_CURLY_BRACKET = 125, ESCAPE_SEQUENCES, DEPRECATED_BOOLEANS_SYNTAX, DEPRECATED_BASE60_SYNTAX, QUOTING_TYPE_SINGLE = 1, QUOTING_TYPE_DOUBLE = 2, STYLE_PLAIN = 1, STYLE_SINGLE = 2, STYLE_LITERAL = 3, STYLE_FOLDED = 4, STYLE_DOUBLE = 5, dump_1, dumper, load, loadAll, dump, safeLoad, safeLoadAll, safeDump;
|
|
4443
|
+
\r`, binary, _hasOwnProperty$3, _toString$2, omap, _toString$1, pairs, _hasOwnProperty$2, set, _default, _hasOwnProperty$1, CONTEXT_FLOW_IN = 1, CONTEXT_FLOW_OUT = 2, CONTEXT_BLOCK_IN = 3, CONTEXT_BLOCK_OUT = 4, CHOMPING_CLIP = 1, CHOMPING_STRIP = 2, CHOMPING_KEEP = 3, PATTERN_NON_PRINTABLE, PATTERN_NON_ASCII_LINE_BREAKS, PATTERN_FLOW_INDICATORS, PATTERN_TAG_HANDLE, PATTERN_TAG_URI, simpleEscapeCheck, simpleEscapeMap, i, directiveHandlers, loadAll_1, load_1, loader, _toString, _hasOwnProperty, CHAR_BOM = 65279, CHAR_TAB = 9, CHAR_LINE_FEED = 10, CHAR_CARRIAGE_RETURN = 13, CHAR_SPACE = 32, CHAR_EXCLAMATION = 33, CHAR_DOUBLE_QUOTE = 34, CHAR_SHARP = 35, CHAR_PERCENT = 37, CHAR_AMPERSAND = 38, CHAR_SINGLE_QUOTE = 39, CHAR_ASTERISK = 42, CHAR_COMMA = 44, CHAR_MINUS = 45, CHAR_COLON = 58, CHAR_EQUALS = 61, CHAR_GREATER_THAN = 62, CHAR_QUESTION = 63, CHAR_COMMERCIAL_AT = 64, CHAR_LEFT_SQUARE_BRACKET = 91, CHAR_RIGHT_SQUARE_BRACKET = 93, CHAR_GRAVE_ACCENT = 96, CHAR_LEFT_CURLY_BRACKET = 123, CHAR_VERTICAL_LINE = 124, CHAR_RIGHT_CURLY_BRACKET = 125, ESCAPE_SEQUENCES, DEPRECATED_BOOLEANS_SYNTAX, DEPRECATED_BASE60_SYNTAX, QUOTING_TYPE_SINGLE = 1, QUOTING_TYPE_DOUBLE = 2, STYLE_PLAIN = 1, STYLE_SINGLE = 2, STYLE_LITERAL = 3, STYLE_FOLDED = 4, STYLE_DOUBLE = 5, dump_1, dumper, Type, Schema, FAILSAFE_SCHEMA, JSON_SCHEMA, CORE_SCHEMA, DEFAULT_SCHEMA, load, loadAll, dump, YAMLException, types, safeLoad, safeLoadAll, safeDump, jsYaml;
|
|
4444
4444
|
var init_js_yaml = __esm(() => {
|
|
4445
4445
|
/*! js-yaml 4.1.1 https://github.com/nodeca/js-yaml @license MIT */
|
|
4446
4446
|
isNothing_1 = isNothing;
|
|
@@ -4793,15 +4793,69 @@ var init_js_yaml = __esm(() => {
|
|
|
4793
4793
|
dumper = {
|
|
4794
4794
|
dump: dump_1
|
|
4795
4795
|
};
|
|
4796
|
+
Type = type;
|
|
4797
|
+
Schema = schema;
|
|
4798
|
+
FAILSAFE_SCHEMA = failsafe;
|
|
4799
|
+
JSON_SCHEMA = json;
|
|
4800
|
+
CORE_SCHEMA = core;
|
|
4801
|
+
DEFAULT_SCHEMA = _default;
|
|
4796
4802
|
load = loader.load;
|
|
4797
4803
|
loadAll = loader.loadAll;
|
|
4798
4804
|
dump = dumper.dump;
|
|
4805
|
+
YAMLException = exception;
|
|
4806
|
+
types = {
|
|
4807
|
+
binary,
|
|
4808
|
+
float,
|
|
4809
|
+
map,
|
|
4810
|
+
null: _null,
|
|
4811
|
+
pairs,
|
|
4812
|
+
set,
|
|
4813
|
+
timestamp,
|
|
4814
|
+
bool,
|
|
4815
|
+
int,
|
|
4816
|
+
merge,
|
|
4817
|
+
omap,
|
|
4818
|
+
seq,
|
|
4819
|
+
str
|
|
4820
|
+
};
|
|
4799
4821
|
safeLoad = renamed("safeLoad", "load");
|
|
4800
4822
|
safeLoadAll = renamed("safeLoadAll", "loadAll");
|
|
4801
4823
|
safeDump = renamed("safeDump", "dump");
|
|
4824
|
+
jsYaml = {
|
|
4825
|
+
Type,
|
|
4826
|
+
Schema,
|
|
4827
|
+
FAILSAFE_SCHEMA,
|
|
4828
|
+
JSON_SCHEMA,
|
|
4829
|
+
CORE_SCHEMA,
|
|
4830
|
+
DEFAULT_SCHEMA,
|
|
4831
|
+
load,
|
|
4832
|
+
loadAll,
|
|
4833
|
+
dump,
|
|
4834
|
+
YAMLException,
|
|
4835
|
+
types,
|
|
4836
|
+
safeLoad,
|
|
4837
|
+
safeLoadAll,
|
|
4838
|
+
safeDump
|
|
4839
|
+
};
|
|
4802
4840
|
});
|
|
4803
4841
|
|
|
4804
4842
|
// src/shared/frontmatter.ts
|
|
4843
|
+
function parseFrontmatter(content) {
|
|
4844
|
+
const frontmatterRegex = /^---\r?\n([\s\S]*?)\r?\n?---\r?\n([\s\S]*)$/;
|
|
4845
|
+
const match = content.match(frontmatterRegex);
|
|
4846
|
+
if (!match) {
|
|
4847
|
+
return { data: {}, body: content, hadFrontmatter: false, parseError: false };
|
|
4848
|
+
}
|
|
4849
|
+
const yamlContent = match[1];
|
|
4850
|
+
const body = match[2];
|
|
4851
|
+
try {
|
|
4852
|
+
const parsed = jsYaml.load(yamlContent, { schema: jsYaml.JSON_SCHEMA });
|
|
4853
|
+
const data = parsed ?? {};
|
|
4854
|
+
return { data, body, hadFrontmatter: true, parseError: false };
|
|
4855
|
+
} catch {
|
|
4856
|
+
return { data: {}, body, hadFrontmatter: true, parseError: true };
|
|
4857
|
+
}
|
|
4858
|
+
}
|
|
4805
4859
|
var init_frontmatter = __esm(() => {
|
|
4806
4860
|
init_js_yaml();
|
|
4807
4861
|
});
|
|
@@ -8999,7 +9053,7 @@ var {
|
|
|
8999
9053
|
// package.json
|
|
9000
9054
|
var package_default = {
|
|
9001
9055
|
name: "oh-my-opencode",
|
|
9002
|
-
version: "3.7.
|
|
9056
|
+
version: "3.7.3",
|
|
9003
9057
|
description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
9004
9058
|
main: "dist/index.js",
|
|
9005
9059
|
types: "dist/index.d.ts",
|
|
@@ -9073,13 +9127,13 @@ var package_default = {
|
|
|
9073
9127
|
typescript: "^5.7.3"
|
|
9074
9128
|
},
|
|
9075
9129
|
optionalDependencies: {
|
|
9076
|
-
"oh-my-opencode-darwin-arm64": "3.7.
|
|
9077
|
-
"oh-my-opencode-darwin-x64": "3.7.
|
|
9078
|
-
"oh-my-opencode-linux-arm64": "3.7.
|
|
9079
|
-
"oh-my-opencode-linux-arm64-musl": "3.7.
|
|
9080
|
-
"oh-my-opencode-linux-x64": "3.7.
|
|
9081
|
-
"oh-my-opencode-linux-x64-musl": "3.7.
|
|
9082
|
-
"oh-my-opencode-windows-x64": "3.7.
|
|
9130
|
+
"oh-my-opencode-darwin-arm64": "3.7.3",
|
|
9131
|
+
"oh-my-opencode-darwin-x64": "3.7.3",
|
|
9132
|
+
"oh-my-opencode-linux-arm64": "3.7.3",
|
|
9133
|
+
"oh-my-opencode-linux-arm64-musl": "3.7.3",
|
|
9134
|
+
"oh-my-opencode-linux-x64": "3.7.3",
|
|
9135
|
+
"oh-my-opencode-linux-x64-musl": "3.7.3",
|
|
9136
|
+
"oh-my-opencode-windows-x64": "3.7.3"
|
|
9083
9137
|
},
|
|
9084
9138
|
trustedDependencies: [
|
|
9085
9139
|
"@ast-grep/cli",
|
|
@@ -10131,7 +10185,7 @@ async function install(args) {
|
|
|
10131
10185
|
}
|
|
10132
10186
|
|
|
10133
10187
|
// src/cli/run/runner.ts
|
|
10134
|
-
var
|
|
10188
|
+
var import_picocolors15 = __toESM(require_picocolors(), 1);
|
|
10135
10189
|
|
|
10136
10190
|
// src/cli/run/event-state.ts
|
|
10137
10191
|
function createEventState() {
|
|
@@ -10143,7 +10197,22 @@ function createEventState() {
|
|
|
10143
10197
|
lastPartText: "",
|
|
10144
10198
|
currentTool: null,
|
|
10145
10199
|
hasReceivedMeaningfulWork: false,
|
|
10146
|
-
messageCount: 0
|
|
10200
|
+
messageCount: 0,
|
|
10201
|
+
currentAgent: null,
|
|
10202
|
+
currentModel: null,
|
|
10203
|
+
currentVariant: null,
|
|
10204
|
+
currentMessageRole: null,
|
|
10205
|
+
agentColorsByName: {},
|
|
10206
|
+
partTypesById: {},
|
|
10207
|
+
inThinkBlock: false,
|
|
10208
|
+
lastReasoningText: "",
|
|
10209
|
+
hasPrintedThinkingLine: false,
|
|
10210
|
+
lastThinkingLineWidth: 0,
|
|
10211
|
+
messageRoleById: {},
|
|
10212
|
+
lastThinkingSummary: "",
|
|
10213
|
+
textAtLineStart: true,
|
|
10214
|
+
thinkingAtLineStart: false,
|
|
10215
|
+
currentMessageId: null
|
|
10147
10216
|
};
|
|
10148
10217
|
}
|
|
10149
10218
|
// src/cli/run/event-formatting.ts
|
|
@@ -10218,6 +10287,14 @@ function logEventVerbose(ctx, payload) {
|
|
|
10218
10287
|
}
|
|
10219
10288
|
break;
|
|
10220
10289
|
}
|
|
10290
|
+
case "message.part.delta": {
|
|
10291
|
+
const deltaProps = props;
|
|
10292
|
+
const field = deltaProps?.field ?? "unknown";
|
|
10293
|
+
const delta = deltaProps?.delta ?? "";
|
|
10294
|
+
const preview = delta.slice(0, 80).replace(/\n/g, "\\n");
|
|
10295
|
+
console.error(import_picocolors5.default.dim(`${sessionTag} message.part.delta (${field}): "${preview}${delta.length > 80 ? "..." : ""}"`));
|
|
10296
|
+
break;
|
|
10297
|
+
}
|
|
10221
10298
|
case "message.updated": {
|
|
10222
10299
|
const msgProps = props;
|
|
10223
10300
|
const role = msgProps?.info?.role ?? "unknown";
|
|
@@ -10264,10 +10341,222 @@ function logEventVerbose(ctx, payload) {
|
|
|
10264
10341
|
}
|
|
10265
10342
|
}
|
|
10266
10343
|
// src/cli/run/event-stream-processor.ts
|
|
10267
|
-
var
|
|
10344
|
+
var import_picocolors8 = __toESM(require_picocolors(), 1);
|
|
10268
10345
|
|
|
10269
10346
|
// src/cli/run/event-handlers.ts
|
|
10347
|
+
var import_picocolors7 = __toESM(require_picocolors(), 1);
|
|
10348
|
+
|
|
10349
|
+
// src/cli/run/tool-input-preview.ts
|
|
10350
|
+
function formatToolHeader(toolName, input) {
|
|
10351
|
+
if (toolName === "glob") {
|
|
10352
|
+
const pattern = str2(input.pattern);
|
|
10353
|
+
const root = str2(input.path);
|
|
10354
|
+
return {
|
|
10355
|
+
icon: "\u2731",
|
|
10356
|
+
title: pattern ? `Glob "${pattern}"` : "Glob",
|
|
10357
|
+
description: root ? `in ${root}` : undefined
|
|
10358
|
+
};
|
|
10359
|
+
}
|
|
10360
|
+
if (toolName === "grep") {
|
|
10361
|
+
const pattern = str2(input.pattern);
|
|
10362
|
+
const root = str2(input.path);
|
|
10363
|
+
return {
|
|
10364
|
+
icon: "\u2731",
|
|
10365
|
+
title: pattern ? `Grep "${pattern}"` : "Grep",
|
|
10366
|
+
description: root ? `in ${root}` : undefined
|
|
10367
|
+
};
|
|
10368
|
+
}
|
|
10369
|
+
if (toolName === "list") {
|
|
10370
|
+
const path3 = str2(input.path);
|
|
10371
|
+
return {
|
|
10372
|
+
icon: "\u2192",
|
|
10373
|
+
title: path3 ? `List ${path3}` : "List"
|
|
10374
|
+
};
|
|
10375
|
+
}
|
|
10376
|
+
if (toolName === "read") {
|
|
10377
|
+
const filePath = str2(input.filePath);
|
|
10378
|
+
return {
|
|
10379
|
+
icon: "\u2192",
|
|
10380
|
+
title: filePath ? `Read ${filePath}` : "Read",
|
|
10381
|
+
description: formatKeyValues(input, ["filePath"])
|
|
10382
|
+
};
|
|
10383
|
+
}
|
|
10384
|
+
if (toolName === "write") {
|
|
10385
|
+
const filePath = str2(input.filePath);
|
|
10386
|
+
return {
|
|
10387
|
+
icon: "\u2190",
|
|
10388
|
+
title: filePath ? `Write ${filePath}` : "Write"
|
|
10389
|
+
};
|
|
10390
|
+
}
|
|
10391
|
+
if (toolName === "edit") {
|
|
10392
|
+
const filePath = str2(input.filePath);
|
|
10393
|
+
return {
|
|
10394
|
+
icon: "\u2190",
|
|
10395
|
+
title: filePath ? `Edit ${filePath}` : "Edit",
|
|
10396
|
+
description: formatKeyValues(input, ["filePath", "oldString", "newString"])
|
|
10397
|
+
};
|
|
10398
|
+
}
|
|
10399
|
+
if (toolName === "webfetch") {
|
|
10400
|
+
const url = str2(input.url);
|
|
10401
|
+
return {
|
|
10402
|
+
icon: "%",
|
|
10403
|
+
title: url ? `WebFetch ${url}` : "WebFetch",
|
|
10404
|
+
description: formatKeyValues(input, ["url"])
|
|
10405
|
+
};
|
|
10406
|
+
}
|
|
10407
|
+
if (toolName === "websearch_web_search_exa") {
|
|
10408
|
+
const query = str2(input.query);
|
|
10409
|
+
return {
|
|
10410
|
+
icon: "\u25C8",
|
|
10411
|
+
title: query ? `Web Search "${query}"` : "Web Search"
|
|
10412
|
+
};
|
|
10413
|
+
}
|
|
10414
|
+
if (toolName === "grep_app_searchGitHub") {
|
|
10415
|
+
const query = str2(input.query);
|
|
10416
|
+
return {
|
|
10417
|
+
icon: "\u25C7",
|
|
10418
|
+
title: query ? `Code Search "${query}"` : "Code Search"
|
|
10419
|
+
};
|
|
10420
|
+
}
|
|
10421
|
+
if (toolName === "task") {
|
|
10422
|
+
const desc = str2(input.description);
|
|
10423
|
+
const subagent = str2(input.subagent_type);
|
|
10424
|
+
return {
|
|
10425
|
+
icon: "#",
|
|
10426
|
+
title: desc || (subagent ? `${subagent} Task` : "Task"),
|
|
10427
|
+
description: subagent ? `agent=${subagent}` : undefined
|
|
10428
|
+
};
|
|
10429
|
+
}
|
|
10430
|
+
if (toolName === "bash") {
|
|
10431
|
+
const command = str2(input.command);
|
|
10432
|
+
return {
|
|
10433
|
+
icon: "$",
|
|
10434
|
+
title: command || "bash",
|
|
10435
|
+
description: formatKeyValues(input, ["command"])
|
|
10436
|
+
};
|
|
10437
|
+
}
|
|
10438
|
+
if (toolName === "skill") {
|
|
10439
|
+
const name = str2(input.name);
|
|
10440
|
+
return {
|
|
10441
|
+
icon: "\u2192",
|
|
10442
|
+
title: name ? `Skill "${name}"` : "Skill"
|
|
10443
|
+
};
|
|
10444
|
+
}
|
|
10445
|
+
if (toolName === "todowrite") {
|
|
10446
|
+
return {
|
|
10447
|
+
icon: "#",
|
|
10448
|
+
title: "Todos"
|
|
10449
|
+
};
|
|
10450
|
+
}
|
|
10451
|
+
return {
|
|
10452
|
+
icon: "\u2699",
|
|
10453
|
+
title: toolName,
|
|
10454
|
+
description: formatKeyValues(input, [])
|
|
10455
|
+
};
|
|
10456
|
+
}
|
|
10457
|
+
function formatKeyValues(input, exclude) {
|
|
10458
|
+
const entries = Object.entries(input).filter(([key, value]) => {
|
|
10459
|
+
if (exclude.includes(key))
|
|
10460
|
+
return false;
|
|
10461
|
+
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
10462
|
+
});
|
|
10463
|
+
if (!entries.length)
|
|
10464
|
+
return;
|
|
10465
|
+
return entries.map(([key, value]) => `${key}=${String(value)}`).join(" ");
|
|
10466
|
+
}
|
|
10467
|
+
function str2(value) {
|
|
10468
|
+
if (typeof value !== "string")
|
|
10469
|
+
return;
|
|
10470
|
+
const trimmed = value.trim();
|
|
10471
|
+
return trimmed.length ? trimmed : undefined;
|
|
10472
|
+
}
|
|
10473
|
+
|
|
10474
|
+
// src/cli/run/display-chars.ts
|
|
10475
|
+
var isCI = Boolean(process.env.CI || process.env.GITHUB_ACTIONS);
|
|
10476
|
+
var displayChars = {
|
|
10477
|
+
treeEnd: isCI ? "`-" : "\u2514\u2500",
|
|
10478
|
+
treeIndent: " ",
|
|
10479
|
+
treeJoin: isCI ? " " : " "
|
|
10480
|
+
};
|
|
10481
|
+
|
|
10482
|
+
// src/cli/run/output-renderer.ts
|
|
10270
10483
|
var import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
10484
|
+
function renderAgentHeader(agent, model, variant, agentColorsByName) {
|
|
10485
|
+
if (!agent && !model)
|
|
10486
|
+
return;
|
|
10487
|
+
const agentLabel = agent ? import_picocolors6.default.bold(colorizeWithProfileColor(agent, agentColorsByName[agent])) : "";
|
|
10488
|
+
const modelBase = model ?? "";
|
|
10489
|
+
const variantSuffix = variant ? ` (${variant})` : "";
|
|
10490
|
+
const modelLabel = model ? import_picocolors6.default.dim(`${modelBase}${variantSuffix}`) : "";
|
|
10491
|
+
process.stdout.write(`
|
|
10492
|
+
`);
|
|
10493
|
+
if (modelLabel) {
|
|
10494
|
+
process.stdout.write(` ${modelLabel}
|
|
10495
|
+
`);
|
|
10496
|
+
}
|
|
10497
|
+
if (agentLabel) {
|
|
10498
|
+
process.stdout.write(` ${import_picocolors6.default.dim("\u2514\u2500")} ${agentLabel}
|
|
10499
|
+
`);
|
|
10500
|
+
}
|
|
10501
|
+
process.stdout.write(`
|
|
10502
|
+
`);
|
|
10503
|
+
}
|
|
10504
|
+
function openThinkBlock() {
|
|
10505
|
+
process.stdout.write(`
|
|
10506
|
+
${import_picocolors6.default.dim("\u2503 Thinking:")} `);
|
|
10507
|
+
}
|
|
10508
|
+
function closeThinkBlock() {
|
|
10509
|
+
process.stdout.write(`
|
|
10510
|
+
|
|
10511
|
+
`);
|
|
10512
|
+
}
|
|
10513
|
+
function writePaddedText(text, atLineStart) {
|
|
10514
|
+
const isGitHubActions = process.env.GITHUB_ACTIONS === "true";
|
|
10515
|
+
if (isGitHubActions) {
|
|
10516
|
+
return { output: text, atLineStart: text.endsWith(`
|
|
10517
|
+
`) };
|
|
10518
|
+
}
|
|
10519
|
+
let output = "";
|
|
10520
|
+
let lineStart = atLineStart;
|
|
10521
|
+
for (let i2 = 0;i2 < text.length; i2++) {
|
|
10522
|
+
const ch = text[i2];
|
|
10523
|
+
if (lineStart) {
|
|
10524
|
+
output += " ";
|
|
10525
|
+
lineStart = false;
|
|
10526
|
+
}
|
|
10527
|
+
if (ch === `
|
|
10528
|
+
`) {
|
|
10529
|
+
output += `
|
|
10530
|
+
`;
|
|
10531
|
+
lineStart = true;
|
|
10532
|
+
continue;
|
|
10533
|
+
}
|
|
10534
|
+
output += ch;
|
|
10535
|
+
}
|
|
10536
|
+
return { output, atLineStart: lineStart };
|
|
10537
|
+
}
|
|
10538
|
+
function colorizeWithProfileColor(text, hexColor) {
|
|
10539
|
+
if (!hexColor)
|
|
10540
|
+
return import_picocolors6.default.magenta(text);
|
|
10541
|
+
const rgb = parseHexColor(hexColor);
|
|
10542
|
+
if (!rgb)
|
|
10543
|
+
return import_picocolors6.default.magenta(text);
|
|
10544
|
+
const [r2, g2, b3] = rgb;
|
|
10545
|
+
return `\x1B[38;2;${r2};${g2};${b3}m${text}\x1B[39m`;
|
|
10546
|
+
}
|
|
10547
|
+
function parseHexColor(hexColor) {
|
|
10548
|
+
const cleaned = hexColor.trim();
|
|
10549
|
+
const match = cleaned.match(/^#?([A-Fa-f0-9]{6})$/);
|
|
10550
|
+
if (!match)
|
|
10551
|
+
return null;
|
|
10552
|
+
const hex = match[1];
|
|
10553
|
+
const r2 = Number.parseInt(hex.slice(0, 2), 16);
|
|
10554
|
+
const g2 = Number.parseInt(hex.slice(2, 4), 16);
|
|
10555
|
+
const b3 = Number.parseInt(hex.slice(4, 6), 16);
|
|
10556
|
+
return [r2, g2, b3];
|
|
10557
|
+
}
|
|
10558
|
+
|
|
10559
|
+
// src/cli/run/event-handlers.ts
|
|
10271
10560
|
function getSessionId(props) {
|
|
10272
10561
|
return props?.sessionID ?? props?.sessionId;
|
|
10273
10562
|
}
|
|
@@ -10277,6 +10566,12 @@ function getInfoSessionId(props) {
|
|
|
10277
10566
|
function getPartSessionId(props) {
|
|
10278
10567
|
return props?.part?.sessionID ?? props?.part?.sessionId;
|
|
10279
10568
|
}
|
|
10569
|
+
function getPartMessageId(props) {
|
|
10570
|
+
return props?.part?.messageID;
|
|
10571
|
+
}
|
|
10572
|
+
function getDeltaMessageId(props) {
|
|
10573
|
+
return props?.messageID;
|
|
10574
|
+
}
|
|
10280
10575
|
function handleSessionIdle(ctx, payload, state) {
|
|
10281
10576
|
if (payload.type !== "session.idle")
|
|
10282
10577
|
return;
|
|
@@ -10306,7 +10601,7 @@ function handleSessionError(ctx, payload, state) {
|
|
|
10306
10601
|
if (getSessionId(props) === ctx.sessionID) {
|
|
10307
10602
|
state.mainSessionError = true;
|
|
10308
10603
|
state.lastError = serializeError(props?.error);
|
|
10309
|
-
console.error(
|
|
10604
|
+
console.error(import_picocolors7.default.red(`
|
|
10310
10605
|
[session.error] ${state.lastError}`));
|
|
10311
10606
|
}
|
|
10312
10607
|
}
|
|
@@ -10318,13 +10613,36 @@ function handleMessagePartUpdated(ctx, payload, state) {
|
|
|
10318
10613
|
const infoSid = getInfoSessionId(props);
|
|
10319
10614
|
if ((partSid ?? infoSid) !== ctx.sessionID)
|
|
10320
10615
|
return;
|
|
10616
|
+
const role = props?.info?.role;
|
|
10617
|
+
const mappedRole = getPartMessageId(props) ? state.messageRoleById[getPartMessageId(props) ?? ""] : undefined;
|
|
10618
|
+
if ((role ?? mappedRole) === "user")
|
|
10619
|
+
return;
|
|
10321
10620
|
const part = props?.part;
|
|
10322
10621
|
if (!part)
|
|
10323
10622
|
return;
|
|
10623
|
+
if (part.id && part.type) {
|
|
10624
|
+
state.partTypesById[part.id] = part.type;
|
|
10625
|
+
}
|
|
10626
|
+
if (part.type === "reasoning") {
|
|
10627
|
+
ensureThinkBlockOpen(state);
|
|
10628
|
+
const reasoningText = part.text ?? "";
|
|
10629
|
+
const newText = reasoningText.slice(state.lastReasoningText.length);
|
|
10630
|
+
if (newText) {
|
|
10631
|
+
const padded = writePaddedText(newText, state.thinkingAtLineStart);
|
|
10632
|
+
process.stdout.write(import_picocolors7.default.dim(padded.output));
|
|
10633
|
+
state.thinkingAtLineStart = padded.atLineStart;
|
|
10634
|
+
state.hasReceivedMeaningfulWork = true;
|
|
10635
|
+
}
|
|
10636
|
+
state.lastReasoningText = reasoningText;
|
|
10637
|
+
return;
|
|
10638
|
+
}
|
|
10639
|
+
closeThinkBlockIfNeeded(state);
|
|
10324
10640
|
if (part.type === "text" && part.text) {
|
|
10325
10641
|
const newText = part.text.slice(state.lastPartText.length);
|
|
10326
10642
|
if (newText) {
|
|
10327
|
-
|
|
10643
|
+
const padded = writePaddedText(newText, state.textAtLineStart);
|
|
10644
|
+
process.stdout.write(padded.output);
|
|
10645
|
+
state.textAtLineStart = padded.atLineStart;
|
|
10328
10646
|
state.hasReceivedMeaningfulWork = true;
|
|
10329
10647
|
}
|
|
10330
10648
|
state.lastPartText = part.text;
|
|
@@ -10333,42 +10651,67 @@ function handleMessagePartUpdated(ctx, payload, state) {
|
|
|
10333
10651
|
handleToolPart(ctx, part, state);
|
|
10334
10652
|
}
|
|
10335
10653
|
}
|
|
10654
|
+
function handleMessagePartDelta(ctx, payload, state) {
|
|
10655
|
+
if (payload.type !== "message.part.delta")
|
|
10656
|
+
return;
|
|
10657
|
+
const props = payload.properties;
|
|
10658
|
+
const sessionID = props?.sessionID ?? props?.sessionId;
|
|
10659
|
+
if (sessionID !== ctx.sessionID)
|
|
10660
|
+
return;
|
|
10661
|
+
const role = getDeltaMessageId(props) ? state.messageRoleById[getDeltaMessageId(props) ?? ""] : undefined;
|
|
10662
|
+
if (role === "user")
|
|
10663
|
+
return;
|
|
10664
|
+
if (props?.field !== "text")
|
|
10665
|
+
return;
|
|
10666
|
+
const partType = props?.partID ? state.partTypesById[props.partID] : undefined;
|
|
10667
|
+
const delta = props.delta ?? "";
|
|
10668
|
+
if (!delta)
|
|
10669
|
+
return;
|
|
10670
|
+
if (partType === "reasoning") {
|
|
10671
|
+
ensureThinkBlockOpen(state);
|
|
10672
|
+
const padded2 = writePaddedText(delta, state.thinkingAtLineStart);
|
|
10673
|
+
process.stdout.write(import_picocolors7.default.dim(padded2.output));
|
|
10674
|
+
state.thinkingAtLineStart = padded2.atLineStart;
|
|
10675
|
+
state.lastReasoningText += delta;
|
|
10676
|
+
state.hasReceivedMeaningfulWork = true;
|
|
10677
|
+
return;
|
|
10678
|
+
}
|
|
10679
|
+
closeThinkBlockIfNeeded(state);
|
|
10680
|
+
const padded = writePaddedText(delta, state.textAtLineStart);
|
|
10681
|
+
process.stdout.write(padded.output);
|
|
10682
|
+
state.textAtLineStart = padded.atLineStart;
|
|
10683
|
+
state.lastPartText += delta;
|
|
10684
|
+
state.hasReceivedMeaningfulWork = true;
|
|
10685
|
+
}
|
|
10336
10686
|
function handleToolPart(_ctx, part, state) {
|
|
10337
10687
|
const toolName = part.tool || part.name || "unknown";
|
|
10338
10688
|
const status = part.state?.status;
|
|
10339
10689
|
if (status === "running") {
|
|
10690
|
+
if (state.currentTool !== null)
|
|
10691
|
+
return;
|
|
10340
10692
|
state.currentTool = toolName;
|
|
10341
|
-
|
|
10342
|
-
const
|
|
10343
|
-
if (input) {
|
|
10344
|
-
if (input.command) {
|
|
10345
|
-
inputPreview = ` ${import_picocolors6.default.dim(String(input.command).slice(0, 60))}`;
|
|
10346
|
-
} else if (input.pattern) {
|
|
10347
|
-
inputPreview = ` ${import_picocolors6.default.dim(String(input.pattern).slice(0, 40))}`;
|
|
10348
|
-
} else if (input.filePath) {
|
|
10349
|
-
inputPreview = ` ${import_picocolors6.default.dim(String(input.filePath))}`;
|
|
10350
|
-
} else if (input.query) {
|
|
10351
|
-
inputPreview = ` ${import_picocolors6.default.dim(String(input.query).slice(0, 40))}`;
|
|
10352
|
-
}
|
|
10353
|
-
}
|
|
10693
|
+
const header = formatToolHeader(toolName, part.state?.input ?? {});
|
|
10694
|
+
const suffix = header.description ? ` ${import_picocolors7.default.dim(header.description)}` : "";
|
|
10354
10695
|
state.hasReceivedMeaningfulWork = true;
|
|
10355
10696
|
process.stdout.write(`
|
|
10356
|
-
${
|
|
10697
|
+
${import_picocolors7.default.cyan(header.icon)} ${import_picocolors7.default.bold(header.title)}${suffix}
|
|
10357
10698
|
`);
|
|
10358
10699
|
}
|
|
10359
10700
|
if (status === "completed" || status === "error") {
|
|
10701
|
+
if (state.currentTool === null)
|
|
10702
|
+
return;
|
|
10360
10703
|
const output = part.state?.output || "";
|
|
10361
|
-
|
|
10362
|
-
|
|
10363
|
-
if (preview.trim()) {
|
|
10364
|
-
const lines = preview.split(`
|
|
10365
|
-
`).slice(0, 3);
|
|
10366
|
-
process.stdout.write(import_picocolors6.default.dim(` \u2514\u2500 ${lines.join(`
|
|
10367
|
-
`)}
|
|
10704
|
+
if (output.trim()) {
|
|
10705
|
+
process.stdout.write(import_picocolors7.default.dim(` ${displayChars.treeEnd} output
|
|
10368
10706
|
`));
|
|
10707
|
+
const padded = writePaddedText(output, true);
|
|
10708
|
+
process.stdout.write(import_picocolors7.default.dim(padded.output + (padded.atLineStart ? "" : " ")));
|
|
10709
|
+
process.stdout.write(`
|
|
10710
|
+
`);
|
|
10369
10711
|
}
|
|
10370
10712
|
state.currentTool = null;
|
|
10371
10713
|
state.lastPartText = "";
|
|
10714
|
+
state.textAtLineStart = true;
|
|
10372
10715
|
}
|
|
10373
10716
|
}
|
|
10374
10717
|
function handleMessageUpdated(ctx, payload, state) {
|
|
@@ -10377,11 +10720,36 @@ function handleMessageUpdated(ctx, payload, state) {
|
|
|
10377
10720
|
const props = payload.properties;
|
|
10378
10721
|
if (getInfoSessionId(props) !== ctx.sessionID)
|
|
10379
10722
|
return;
|
|
10723
|
+
state.currentMessageRole = props?.info?.role ?? null;
|
|
10724
|
+
const messageID = props?.info?.id ?? null;
|
|
10725
|
+
const role = props?.info?.role;
|
|
10726
|
+
if (messageID && role) {
|
|
10727
|
+
state.messageRoleById[messageID] = role;
|
|
10728
|
+
}
|
|
10380
10729
|
if (props?.info?.role !== "assistant")
|
|
10381
10730
|
return;
|
|
10382
|
-
|
|
10383
|
-
|
|
10384
|
-
|
|
10731
|
+
const isNewMessage = !messageID || messageID !== state.currentMessageId;
|
|
10732
|
+
if (isNewMessage) {
|
|
10733
|
+
state.currentMessageId = messageID;
|
|
10734
|
+
state.hasReceivedMeaningfulWork = true;
|
|
10735
|
+
state.messageCount++;
|
|
10736
|
+
state.lastPartText = "";
|
|
10737
|
+
state.lastReasoningText = "";
|
|
10738
|
+
state.hasPrintedThinkingLine = false;
|
|
10739
|
+
state.lastThinkingSummary = "";
|
|
10740
|
+
state.textAtLineStart = true;
|
|
10741
|
+
state.thinkingAtLineStart = false;
|
|
10742
|
+
closeThinkBlockIfNeeded(state);
|
|
10743
|
+
}
|
|
10744
|
+
const agent = props?.info?.agent ?? null;
|
|
10745
|
+
const model = props?.info?.modelID ?? null;
|
|
10746
|
+
const variant = props?.info?.variant ?? null;
|
|
10747
|
+
if (agent !== state.currentAgent || model !== state.currentModel || variant !== state.currentVariant) {
|
|
10748
|
+
state.currentAgent = agent;
|
|
10749
|
+
state.currentModel = model;
|
|
10750
|
+
state.currentVariant = variant;
|
|
10751
|
+
renderAgentHeader(agent, model, variant, state.agentColorsByName);
|
|
10752
|
+
}
|
|
10385
10753
|
}
|
|
10386
10754
|
function handleToolExecute(ctx, payload, state) {
|
|
10387
10755
|
if (payload.type !== "tool.execute")
|
|
@@ -10389,24 +10757,16 @@ function handleToolExecute(ctx, payload, state) {
|
|
|
10389
10757
|
const props = payload.properties;
|
|
10390
10758
|
if (getSessionId(props) !== ctx.sessionID)
|
|
10391
10759
|
return;
|
|
10760
|
+
closeThinkBlockIfNeeded(state);
|
|
10761
|
+
if (state.currentTool !== null)
|
|
10762
|
+
return;
|
|
10392
10763
|
const toolName = props?.name || "unknown";
|
|
10393
10764
|
state.currentTool = toolName;
|
|
10394
|
-
|
|
10395
|
-
|
|
10396
|
-
const input = props.input;
|
|
10397
|
-
if (input.command) {
|
|
10398
|
-
inputPreview = ` ${import_picocolors6.default.dim(String(input.command).slice(0, 60))}`;
|
|
10399
|
-
} else if (input.pattern) {
|
|
10400
|
-
inputPreview = ` ${import_picocolors6.default.dim(String(input.pattern).slice(0, 40))}`;
|
|
10401
|
-
} else if (input.filePath) {
|
|
10402
|
-
inputPreview = ` ${import_picocolors6.default.dim(String(input.filePath))}`;
|
|
10403
|
-
} else if (input.query) {
|
|
10404
|
-
inputPreview = ` ${import_picocolors6.default.dim(String(input.query).slice(0, 40))}`;
|
|
10405
|
-
}
|
|
10406
|
-
}
|
|
10765
|
+
const header = formatToolHeader(toolName, props?.input ?? {});
|
|
10766
|
+
const suffix = header.description ? ` ${import_picocolors7.default.dim(header.description)}` : "";
|
|
10407
10767
|
state.hasReceivedMeaningfulWork = true;
|
|
10408
10768
|
process.stdout.write(`
|
|
10409
|
-
${
|
|
10769
|
+
${import_picocolors7.default.cyan(header.icon)} ${import_picocolors7.default.bold(header.title)}${suffix}
|
|
10410
10770
|
`);
|
|
10411
10771
|
}
|
|
10412
10772
|
function handleToolResult(ctx, payload, state) {
|
|
@@ -10415,37 +10775,52 @@ function handleToolResult(ctx, payload, state) {
|
|
|
10415
10775
|
const props = payload.properties;
|
|
10416
10776
|
if (getSessionId(props) !== ctx.sessionID)
|
|
10417
10777
|
return;
|
|
10778
|
+
closeThinkBlockIfNeeded(state);
|
|
10779
|
+
if (state.currentTool === null)
|
|
10780
|
+
return;
|
|
10418
10781
|
const output = props?.output || "";
|
|
10419
|
-
|
|
10420
|
-
|
|
10421
|
-
if (preview.trim()) {
|
|
10422
|
-
const lines = preview.split(`
|
|
10423
|
-
`).slice(0, 3);
|
|
10424
|
-
process.stdout.write(import_picocolors6.default.dim(` \u2514\u2500 ${lines.join(`
|
|
10425
|
-
`)}
|
|
10782
|
+
if (output.trim()) {
|
|
10783
|
+
process.stdout.write(import_picocolors7.default.dim(` ${displayChars.treeEnd} output
|
|
10426
10784
|
`));
|
|
10785
|
+
const padded = writePaddedText(output, true);
|
|
10786
|
+
process.stdout.write(import_picocolors7.default.dim(padded.output + (padded.atLineStart ? "" : " ")));
|
|
10787
|
+
process.stdout.write(`
|
|
10788
|
+
`);
|
|
10427
10789
|
}
|
|
10428
10790
|
state.currentTool = null;
|
|
10429
10791
|
state.lastPartText = "";
|
|
10792
|
+
state.textAtLineStart = true;
|
|
10430
10793
|
}
|
|
10431
10794
|
function handleTuiToast(_ctx, payload, state) {
|
|
10432
10795
|
if (payload.type !== "tui.toast.show")
|
|
10433
10796
|
return;
|
|
10434
10797
|
const props = payload.properties;
|
|
10435
|
-
const title = props?.title ? `${props.title}: ` : "";
|
|
10436
|
-
const message = props?.message?.trim();
|
|
10437
10798
|
const variant = props?.variant ?? "info";
|
|
10438
|
-
if (!message)
|
|
10439
|
-
return;
|
|
10440
10799
|
if (variant === "error") {
|
|
10441
|
-
|
|
10442
|
-
|
|
10443
|
-
|
|
10444
|
-
|
|
10445
|
-
|
|
10800
|
+
const title = props?.title ? `${props.title}: ` : "";
|
|
10801
|
+
const message = props?.message?.trim();
|
|
10802
|
+
if (message) {
|
|
10803
|
+
state.mainSessionError = true;
|
|
10804
|
+
state.lastError = `${title}${message}`;
|
|
10805
|
+
}
|
|
10446
10806
|
}
|
|
10447
|
-
|
|
10448
|
-
|
|
10807
|
+
}
|
|
10808
|
+
function ensureThinkBlockOpen(state) {
|
|
10809
|
+
if (state.inThinkBlock)
|
|
10810
|
+
return;
|
|
10811
|
+
openThinkBlock();
|
|
10812
|
+
state.inThinkBlock = true;
|
|
10813
|
+
state.hasPrintedThinkingLine = false;
|
|
10814
|
+
state.thinkingAtLineStart = false;
|
|
10815
|
+
}
|
|
10816
|
+
function closeThinkBlockIfNeeded(state) {
|
|
10817
|
+
if (!state.inThinkBlock)
|
|
10818
|
+
return;
|
|
10819
|
+
closeThinkBlock();
|
|
10820
|
+
state.inThinkBlock = false;
|
|
10821
|
+
state.lastThinkingLineWidth = 0;
|
|
10822
|
+
state.lastThinkingSummary = "";
|
|
10823
|
+
state.thinkingAtLineStart = false;
|
|
10449
10824
|
}
|
|
10450
10825
|
|
|
10451
10826
|
// src/cli/run/event-stream-processor.ts
|
|
@@ -10456,20 +10831,25 @@ async function processEvents(ctx, stream, state) {
|
|
|
10456
10831
|
try {
|
|
10457
10832
|
const payload = event;
|
|
10458
10833
|
if (!payload?.type) {
|
|
10459
|
-
|
|
10834
|
+
if (ctx.verbose) {
|
|
10835
|
+
console.error(import_picocolors8.default.dim(`[event] no type: ${JSON.stringify(event)}`));
|
|
10836
|
+
}
|
|
10460
10837
|
continue;
|
|
10461
10838
|
}
|
|
10462
|
-
|
|
10839
|
+
if (ctx.verbose) {
|
|
10840
|
+
logEventVerbose(ctx, payload);
|
|
10841
|
+
}
|
|
10463
10842
|
handleSessionError(ctx, payload, state);
|
|
10464
10843
|
handleSessionIdle(ctx, payload, state);
|
|
10465
10844
|
handleSessionStatus(ctx, payload, state);
|
|
10466
10845
|
handleMessagePartUpdated(ctx, payload, state);
|
|
10846
|
+
handleMessagePartDelta(ctx, payload, state);
|
|
10467
10847
|
handleMessageUpdated(ctx, payload, state);
|
|
10468
10848
|
handleToolExecute(ctx, payload, state);
|
|
10469
10849
|
handleToolResult(ctx, payload, state);
|
|
10470
10850
|
handleTuiToast(ctx, payload, state);
|
|
10471
10851
|
} catch (err) {
|
|
10472
|
-
console.error(
|
|
10852
|
+
console.error(import_picocolors8.default.red(`[event error] ${err}`));
|
|
10473
10853
|
}
|
|
10474
10854
|
}
|
|
10475
10855
|
}
|
|
@@ -11224,14 +11604,14 @@ function promiseAllObject(promisesObj) {
|
|
|
11224
11604
|
}
|
|
11225
11605
|
function randomString(length = 10) {
|
|
11226
11606
|
const chars = "abcdefghijklmnopqrstuvwxyz";
|
|
11227
|
-
let
|
|
11607
|
+
let str3 = "";
|
|
11228
11608
|
for (let i2 = 0;i2 < length; i2++) {
|
|
11229
|
-
|
|
11609
|
+
str3 += chars[Math.floor(Math.random() * chars.length)];
|
|
11230
11610
|
}
|
|
11231
|
-
return
|
|
11611
|
+
return str3;
|
|
11232
11612
|
}
|
|
11233
|
-
function esc(
|
|
11234
|
-
return JSON.stringify(
|
|
11613
|
+
function esc(str3) {
|
|
11614
|
+
return JSON.stringify(str3);
|
|
11235
11615
|
}
|
|
11236
11616
|
var captureStackTrace = "captureStackTrace" in Error ? Error.captureStackTrace : (..._args) => {};
|
|
11237
11617
|
function isObject2(data) {
|
|
@@ -11325,8 +11705,8 @@ var getParsedType = (data) => {
|
|
|
11325
11705
|
};
|
|
11326
11706
|
var propertyKeyTypes = new Set(["string", "number", "symbol"]);
|
|
11327
11707
|
var primitiveTypes = new Set(["string", "number", "bigint", "boolean", "symbol", "undefined"]);
|
|
11328
|
-
function escapeRegex(
|
|
11329
|
-
return
|
|
11708
|
+
function escapeRegex(str3) {
|
|
11709
|
+
return str3.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
11330
11710
|
}
|
|
11331
11711
|
function clone(inst, def, params) {
|
|
11332
11712
|
const cl = new inst._zod.constr(def ?? inst._zod.def);
|
|
@@ -20561,10 +20941,10 @@ function _property(property, schema2, params) {
|
|
|
20561
20941
|
...normalizeParams(params)
|
|
20562
20942
|
});
|
|
20563
20943
|
}
|
|
20564
|
-
function _mime(
|
|
20944
|
+
function _mime(types3, params) {
|
|
20565
20945
|
return new $ZodCheckMimeType({
|
|
20566
20946
|
check: "mime_type",
|
|
20567
|
-
mime:
|
|
20947
|
+
mime: types3,
|
|
20568
20948
|
...normalizeParams(params)
|
|
20569
20949
|
});
|
|
20570
20950
|
}
|
|
@@ -22474,7 +22854,7 @@ var ZodFile = /* @__PURE__ */ $constructor("ZodFile", (inst, def) => {
|
|
|
22474
22854
|
ZodType.init(inst, def);
|
|
22475
22855
|
inst.min = (size, params) => inst.check(_minSize(size, params));
|
|
22476
22856
|
inst.max = (size, params) => inst.check(_maxSize(size, params));
|
|
22477
|
-
inst.mime = (
|
|
22857
|
+
inst.mime = (types3, params) => inst.check(_mime(Array.isArray(types3) ? types3 : [types3], params));
|
|
22478
22858
|
});
|
|
22479
22859
|
function file(params) {
|
|
22480
22860
|
return _file(ZodFile, params);
|
|
@@ -23040,9 +23420,11 @@ var HookNameSchema = exports_external.enum([
|
|
|
23040
23420
|
"claude-code-hooks",
|
|
23041
23421
|
"auto-slash-command",
|
|
23042
23422
|
"edit-error-recovery",
|
|
23423
|
+
"json-error-recovery",
|
|
23043
23424
|
"delegate-task-retry",
|
|
23044
23425
|
"prometheus-md-only",
|
|
23045
23426
|
"sisyphus-junior-notepad",
|
|
23427
|
+
"sisyphus-gpt-hephaestus-reminder",
|
|
23046
23428
|
"start-work",
|
|
23047
23429
|
"atlas",
|
|
23048
23430
|
"unstable-agent-babysitter",
|
|
@@ -24739,7 +25121,7 @@ async function createOpencode(options) {
|
|
|
24739
25121
|
|
|
24740
25122
|
// src/cli/run/server-connection.ts
|
|
24741
25123
|
init_port_utils();
|
|
24742
|
-
var
|
|
25124
|
+
var import_picocolors9 = __toESM(require_picocolors(), 1);
|
|
24743
25125
|
|
|
24744
25126
|
// src/cli/run/opencode-binary-resolver.ts
|
|
24745
25127
|
import { delimiter, dirname, join as join8 } from "path";
|
|
@@ -24831,13 +25213,25 @@ function prependResolvedOpencodeBinToPath(env = process.env, resolve2 = resolveF
|
|
|
24831
25213
|
}
|
|
24832
25214
|
|
|
24833
25215
|
// src/cli/run/server-connection.ts
|
|
25216
|
+
function isPortStartFailure(error45, port) {
|
|
25217
|
+
if (!(error45 instanceof Error)) {
|
|
25218
|
+
return false;
|
|
25219
|
+
}
|
|
25220
|
+
return error45.message.includes(`Failed to start server on port ${port}`);
|
|
25221
|
+
}
|
|
25222
|
+
async function startServer(options) {
|
|
25223
|
+
const { signal, port } = options;
|
|
25224
|
+
const { client: client3, server: server2 } = await withWorkingOpencodePath(() => createOpencode({ signal, port, hostname: "127.0.0.1" }));
|
|
25225
|
+
console.log(import_picocolors9.default.dim("Server listening at"), import_picocolors9.default.cyan(server2.url));
|
|
25226
|
+
return { client: client3, cleanup: () => server2.close() };
|
|
25227
|
+
}
|
|
24834
25228
|
async function createServerConnection(options) {
|
|
24835
25229
|
prependResolvedOpencodeBinToPath();
|
|
24836
25230
|
const { port, attach, signal } = options;
|
|
24837
25231
|
if (attach !== undefined) {
|
|
24838
|
-
console.log(
|
|
24839
|
-
const
|
|
24840
|
-
return { client:
|
|
25232
|
+
console.log(import_picocolors9.default.dim("Attaching to existing server at"), import_picocolors9.default.cyan(attach));
|
|
25233
|
+
const client3 = createOpencodeClient({ baseUrl: attach });
|
|
25234
|
+
return { client: client3, cleanup: () => {} };
|
|
24841
25235
|
}
|
|
24842
25236
|
if (port !== undefined) {
|
|
24843
25237
|
if (port < 1 || port > 65535) {
|
|
@@ -24845,28 +25239,46 @@ async function createServerConnection(options) {
|
|
|
24845
25239
|
}
|
|
24846
25240
|
const available = await isPortAvailable(port, "127.0.0.1");
|
|
24847
25241
|
if (available) {
|
|
24848
|
-
console.log(
|
|
24849
|
-
|
|
24850
|
-
|
|
24851
|
-
|
|
25242
|
+
console.log(import_picocolors9.default.dim("Starting server on port"), import_picocolors9.default.cyan(port.toString()));
|
|
25243
|
+
try {
|
|
25244
|
+
return await startServer({ signal, port });
|
|
25245
|
+
} catch (error45) {
|
|
25246
|
+
if (!isPortStartFailure(error45, port)) {
|
|
25247
|
+
throw error45;
|
|
25248
|
+
}
|
|
25249
|
+
const stillAvailable = await isPortAvailable(port, "127.0.0.1");
|
|
25250
|
+
if (stillAvailable) {
|
|
25251
|
+
throw error45;
|
|
25252
|
+
}
|
|
25253
|
+
console.log(import_picocolors9.default.dim("Port"), import_picocolors9.default.cyan(port.toString()), import_picocolors9.default.dim("became occupied, attaching to existing server"));
|
|
25254
|
+
const client4 = createOpencodeClient({ baseUrl: `http://127.0.0.1:${port}` });
|
|
25255
|
+
return { client: client4, cleanup: () => {} };
|
|
25256
|
+
}
|
|
24852
25257
|
}
|
|
24853
|
-
console.log(
|
|
24854
|
-
const
|
|
24855
|
-
return { client:
|
|
25258
|
+
console.log(import_picocolors9.default.dim("Port"), import_picocolors9.default.cyan(port.toString()), import_picocolors9.default.dim("is occupied, attaching to existing server"));
|
|
25259
|
+
const client3 = createOpencodeClient({ baseUrl: `http://127.0.0.1:${port}` });
|
|
25260
|
+
return { client: client3, cleanup: () => {} };
|
|
24856
25261
|
}
|
|
24857
25262
|
const { port: selectedPort, wasAutoSelected } = await getAvailableServerPort(DEFAULT_SERVER_PORT, "127.0.0.1");
|
|
24858
25263
|
if (wasAutoSelected) {
|
|
24859
|
-
console.log(
|
|
25264
|
+
console.log(import_picocolors9.default.dim("Auto-selected port"), import_picocolors9.default.cyan(selectedPort.toString()));
|
|
24860
25265
|
} else {
|
|
24861
|
-
console.log(
|
|
25266
|
+
console.log(import_picocolors9.default.dim("Starting server on port"), import_picocolors9.default.cyan(selectedPort.toString()));
|
|
25267
|
+
}
|
|
25268
|
+
try {
|
|
25269
|
+
return await startServer({ signal, port: selectedPort });
|
|
25270
|
+
} catch (error45) {
|
|
25271
|
+
if (!isPortStartFailure(error45, selectedPort)) {
|
|
25272
|
+
throw error45;
|
|
25273
|
+
}
|
|
25274
|
+
const { port: retryPort } = await getAvailableServerPort(selectedPort + 1, "127.0.0.1");
|
|
25275
|
+
console.log(import_picocolors9.default.dim("Retrying server start on port"), import_picocolors9.default.cyan(retryPort.toString()));
|
|
25276
|
+
return await startServer({ signal, port: retryPort });
|
|
24862
25277
|
}
|
|
24863
|
-
const { client: client3, server: server2 } = await withWorkingOpencodePath(() => createOpencode({ signal, port: selectedPort, hostname: "127.0.0.1" }));
|
|
24864
|
-
console.log(import_picocolors8.default.dim("Server listening at"), import_picocolors8.default.cyan(server2.url));
|
|
24865
|
-
return { client: client3, cleanup: () => server2.close() };
|
|
24866
25278
|
}
|
|
24867
25279
|
|
|
24868
25280
|
// src/cli/run/session-resolver.ts
|
|
24869
|
-
var
|
|
25281
|
+
var import_picocolors10 = __toESM(require_picocolors(), 1);
|
|
24870
25282
|
var SESSION_CREATE_MAX_RETRIES = 3;
|
|
24871
25283
|
var SESSION_CREATE_RETRY_DELAY_MS = 1000;
|
|
24872
25284
|
async function resolveSession(options) {
|
|
@@ -24892,11 +25304,11 @@ async function resolveSession(options) {
|
|
|
24892
25304
|
query: { directory }
|
|
24893
25305
|
});
|
|
24894
25306
|
if (res.error) {
|
|
24895
|
-
console.error(
|
|
24896
|
-
console.error(
|
|
25307
|
+
console.error(import_picocolors10.default.yellow(`Session create attempt ${attempt}/${SESSION_CREATE_MAX_RETRIES} failed:`));
|
|
25308
|
+
console.error(import_picocolors10.default.dim(` Error: ${serializeError(res.error)}`));
|
|
24897
25309
|
if (attempt < SESSION_CREATE_MAX_RETRIES) {
|
|
24898
25310
|
const delay = SESSION_CREATE_RETRY_DELAY_MS * attempt;
|
|
24899
|
-
console.log(
|
|
25311
|
+
console.log(import_picocolors10.default.dim(` Retrying in ${delay}ms...`));
|
|
24900
25312
|
await new Promise((resolve2) => setTimeout(resolve2, delay));
|
|
24901
25313
|
}
|
|
24902
25314
|
continue;
|
|
@@ -24904,10 +25316,10 @@ async function resolveSession(options) {
|
|
|
24904
25316
|
if (res.data?.id) {
|
|
24905
25317
|
return res.data.id;
|
|
24906
25318
|
}
|
|
24907
|
-
console.error(
|
|
25319
|
+
console.error(import_picocolors10.default.yellow(`Session create attempt ${attempt}/${SESSION_CREATE_MAX_RETRIES}: No session ID returned`));
|
|
24908
25320
|
if (attempt < SESSION_CREATE_MAX_RETRIES) {
|
|
24909
25321
|
const delay = SESSION_CREATE_RETRY_DELAY_MS * attempt;
|
|
24910
|
-
console.log(
|
|
25322
|
+
console.log(import_picocolors10.default.dim(` Retrying in ${delay}ms...`));
|
|
24911
25323
|
await new Promise((resolve2) => setTimeout(resolve2, delay));
|
|
24912
25324
|
}
|
|
24913
25325
|
}
|
|
@@ -24946,14 +25358,14 @@ function createJsonOutputManager(options = {}) {
|
|
|
24946
25358
|
}
|
|
24947
25359
|
|
|
24948
25360
|
// src/cli/run/on-complete-hook.ts
|
|
24949
|
-
var
|
|
25361
|
+
var import_picocolors11 = __toESM(require_picocolors(), 1);
|
|
24950
25362
|
async function executeOnCompleteHook(options) {
|
|
24951
25363
|
const { command, sessionId, exitCode, durationMs, messageCount } = options;
|
|
24952
25364
|
const trimmedCommand = command.trim();
|
|
24953
25365
|
if (!trimmedCommand) {
|
|
24954
25366
|
return;
|
|
24955
25367
|
}
|
|
24956
|
-
console.error(
|
|
25368
|
+
console.error(import_picocolors11.default.dim(`Running on-complete hook: ${trimmedCommand}`));
|
|
24957
25369
|
try {
|
|
24958
25370
|
const proc = Bun.spawn(["sh", "-c", trimmedCommand], {
|
|
24959
25371
|
env: {
|
|
@@ -24968,16 +25380,16 @@ async function executeOnCompleteHook(options) {
|
|
|
24968
25380
|
});
|
|
24969
25381
|
const hookExitCode = await proc.exited;
|
|
24970
25382
|
if (hookExitCode !== 0) {
|
|
24971
|
-
console.error(
|
|
25383
|
+
console.error(import_picocolors11.default.yellow(`Warning: on-complete hook exited with code ${hookExitCode}`));
|
|
24972
25384
|
}
|
|
24973
25385
|
} catch (error45) {
|
|
24974
|
-
console.error(
|
|
25386
|
+
console.error(import_picocolors11.default.yellow(`Warning: Failed to execute on-complete hook: ${error45 instanceof Error ? error45.message : String(error45)}`));
|
|
24975
25387
|
}
|
|
24976
25388
|
}
|
|
24977
25389
|
|
|
24978
25390
|
// src/cli/run/agent-resolver.ts
|
|
24979
25391
|
init_agent_display_names();
|
|
24980
|
-
var
|
|
25392
|
+
var import_picocolors12 = __toESM(require_picocolors(), 1);
|
|
24981
25393
|
var CORE_AGENT_ORDER = ["sisyphus", "hephaestus", "prometheus", "atlas"];
|
|
24982
25394
|
var DEFAULT_AGENT = "sisyphus";
|
|
24983
25395
|
var normalizeAgentName = (agent) => {
|
|
@@ -25022,35 +25434,224 @@ var resolveRunAgent = (options, pluginConfig, env = process.env) => {
|
|
|
25022
25434
|
const fallbackName = getAgentDisplayName(fallback);
|
|
25023
25435
|
const fallbackDisabled = isAgentDisabled(fallback, pluginConfig);
|
|
25024
25436
|
if (fallbackDisabled) {
|
|
25025
|
-
console.log(
|
|
25437
|
+
console.log(import_picocolors12.default.yellow(`Requested agent "${resolved.resolvedName}" is disabled and no enabled core agent was found. Proceeding with "${fallbackName}".`));
|
|
25026
25438
|
return fallbackName;
|
|
25027
25439
|
}
|
|
25028
|
-
console.log(
|
|
25440
|
+
console.log(import_picocolors12.default.yellow(`Requested agent "${resolved.resolvedName}" is disabled. Falling back to "${fallbackName}".`));
|
|
25029
25441
|
return fallbackName;
|
|
25030
25442
|
}
|
|
25031
25443
|
return resolved.resolvedName;
|
|
25032
25444
|
};
|
|
25033
25445
|
|
|
25034
25446
|
// src/cli/run/poll-for-completion.ts
|
|
25035
|
-
var
|
|
25447
|
+
var import_picocolors14 = __toESM(require_picocolors(), 1);
|
|
25036
25448
|
|
|
25037
25449
|
// src/cli/run/completion.ts
|
|
25038
25450
|
init_shared();
|
|
25039
|
-
var
|
|
25451
|
+
var import_picocolors13 = __toESM(require_picocolors(), 1);
|
|
25452
|
+
// src/features/boulder-state/constants.ts
|
|
25453
|
+
var BOULDER_DIR = ".sisyphus";
|
|
25454
|
+
var BOULDER_FILE = "boulder.json";
|
|
25455
|
+
var BOULDER_STATE_PATH = `${BOULDER_DIR}/${BOULDER_FILE}`;
|
|
25456
|
+
var NOTEPAD_DIR = "notepads";
|
|
25457
|
+
var NOTEPAD_BASE_PATH = `${BOULDER_DIR}/${NOTEPAD_DIR}`;
|
|
25458
|
+
// src/features/boulder-state/storage.ts
|
|
25459
|
+
import { existsSync as existsSync11, readFileSync as readFileSync11, writeFileSync as writeFileSync7, mkdirSync as mkdirSync3, readdirSync } from "fs";
|
|
25460
|
+
import { dirname as dirname3, join as join9, basename } from "path";
|
|
25461
|
+
function getBoulderFilePath(directory) {
|
|
25462
|
+
return join9(directory, BOULDER_DIR, BOULDER_FILE);
|
|
25463
|
+
}
|
|
25464
|
+
function readBoulderState(directory) {
|
|
25465
|
+
const filePath = getBoulderFilePath(directory);
|
|
25466
|
+
if (!existsSync11(filePath)) {
|
|
25467
|
+
return null;
|
|
25468
|
+
}
|
|
25469
|
+
try {
|
|
25470
|
+
const content = readFileSync11(filePath, "utf-8");
|
|
25471
|
+
const parsed = JSON.parse(content);
|
|
25472
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
25473
|
+
return null;
|
|
25474
|
+
}
|
|
25475
|
+
if (!Array.isArray(parsed.session_ids)) {
|
|
25476
|
+
parsed.session_ids = [];
|
|
25477
|
+
}
|
|
25478
|
+
return parsed;
|
|
25479
|
+
} catch {
|
|
25480
|
+
return null;
|
|
25481
|
+
}
|
|
25482
|
+
}
|
|
25483
|
+
function getPlanProgress(planPath) {
|
|
25484
|
+
if (!existsSync11(planPath)) {
|
|
25485
|
+
return { total: 0, completed: 0, isComplete: true };
|
|
25486
|
+
}
|
|
25487
|
+
try {
|
|
25488
|
+
const content = readFileSync11(planPath, "utf-8");
|
|
25489
|
+
const uncheckedMatches = content.match(/^[-*]\s*\[\s*\]/gm) || [];
|
|
25490
|
+
const checkedMatches = content.match(/^[-*]\s*\[[xX]\]/gm) || [];
|
|
25491
|
+
const total = uncheckedMatches.length + checkedMatches.length;
|
|
25492
|
+
const completed = checkedMatches.length;
|
|
25493
|
+
return {
|
|
25494
|
+
total,
|
|
25495
|
+
completed,
|
|
25496
|
+
isComplete: total === 0 || completed === total
|
|
25497
|
+
};
|
|
25498
|
+
} catch {
|
|
25499
|
+
return { total: 0, completed: 0, isComplete: true };
|
|
25500
|
+
}
|
|
25501
|
+
}
|
|
25502
|
+
// src/features/run-continuation-state/constants.ts
|
|
25503
|
+
var CONTINUATION_MARKER_DIR = ".sisyphus/run-continuation";
|
|
25504
|
+
// src/features/run-continuation-state/storage.ts
|
|
25505
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync4, readFileSync as readFileSync12, rmSync, writeFileSync as writeFileSync8 } from "fs";
|
|
25506
|
+
import { join as join10 } from "path";
|
|
25507
|
+
function getMarkerPath(directory, sessionID) {
|
|
25508
|
+
return join10(directory, CONTINUATION_MARKER_DIR, `${sessionID}.json`);
|
|
25509
|
+
}
|
|
25510
|
+
function readContinuationMarker(directory, sessionID) {
|
|
25511
|
+
const markerPath = getMarkerPath(directory, sessionID);
|
|
25512
|
+
if (!existsSync12(markerPath))
|
|
25513
|
+
return null;
|
|
25514
|
+
try {
|
|
25515
|
+
const raw = readFileSync12(markerPath, "utf-8");
|
|
25516
|
+
const parsed = JSON.parse(raw);
|
|
25517
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
25518
|
+
return null;
|
|
25519
|
+
return parsed;
|
|
25520
|
+
} catch {
|
|
25521
|
+
return null;
|
|
25522
|
+
}
|
|
25523
|
+
}
|
|
25524
|
+
function isContinuationMarkerActive(marker) {
|
|
25525
|
+
if (!marker)
|
|
25526
|
+
return false;
|
|
25527
|
+
return Object.values(marker.sources).some((entry) => entry?.state === "active");
|
|
25528
|
+
}
|
|
25529
|
+
function getActiveContinuationMarkerReason(marker) {
|
|
25530
|
+
if (!marker)
|
|
25531
|
+
return null;
|
|
25532
|
+
const active = Object.entries(marker.sources).find(([, entry2]) => entry2?.state === "active");
|
|
25533
|
+
if (!active || !active[1])
|
|
25534
|
+
return null;
|
|
25535
|
+
const [source, entry] = active;
|
|
25536
|
+
return entry.reason ?? `${source} continuation is active`;
|
|
25537
|
+
}
|
|
25538
|
+
// src/hooks/ralph-loop/storage.ts
|
|
25539
|
+
init_frontmatter();
|
|
25540
|
+
import { existsSync as existsSync13, readFileSync as readFileSync13, writeFileSync as writeFileSync9, unlinkSync, mkdirSync as mkdirSync5 } from "fs";
|
|
25541
|
+
import { dirname as dirname4, join as join11 } from "path";
|
|
25542
|
+
|
|
25543
|
+
// src/hooks/ralph-loop/constants.ts
|
|
25544
|
+
var DEFAULT_STATE_FILE = ".sisyphus/ralph-loop.local.md";
|
|
25545
|
+
var DEFAULT_MAX_ITERATIONS = 100;
|
|
25546
|
+
var DEFAULT_COMPLETION_PROMISE = "DONE";
|
|
25547
|
+
|
|
25548
|
+
// src/hooks/ralph-loop/storage.ts
|
|
25549
|
+
function getStateFilePath(directory, customPath) {
|
|
25550
|
+
return customPath ? join11(directory, customPath) : join11(directory, DEFAULT_STATE_FILE);
|
|
25551
|
+
}
|
|
25552
|
+
function readState(directory, customPath) {
|
|
25553
|
+
const filePath = getStateFilePath(directory, customPath);
|
|
25554
|
+
if (!existsSync13(filePath)) {
|
|
25555
|
+
return null;
|
|
25556
|
+
}
|
|
25557
|
+
try {
|
|
25558
|
+
const content = readFileSync13(filePath, "utf-8");
|
|
25559
|
+
const { data, body } = parseFrontmatter(content);
|
|
25560
|
+
const active = data.active;
|
|
25561
|
+
const iteration = data.iteration;
|
|
25562
|
+
if (active === undefined || iteration === undefined) {
|
|
25563
|
+
return null;
|
|
25564
|
+
}
|
|
25565
|
+
const isActive = active === true || active === "true";
|
|
25566
|
+
const iterationNum = typeof iteration === "number" ? iteration : Number(iteration);
|
|
25567
|
+
if (isNaN(iterationNum)) {
|
|
25568
|
+
return null;
|
|
25569
|
+
}
|
|
25570
|
+
const stripQuotes = (val) => {
|
|
25571
|
+
const str3 = String(val ?? "");
|
|
25572
|
+
return str3.replace(/^["']|["']$/g, "");
|
|
25573
|
+
};
|
|
25574
|
+
return {
|
|
25575
|
+
active: isActive,
|
|
25576
|
+
iteration: iterationNum,
|
|
25577
|
+
max_iterations: Number(data.max_iterations) || DEFAULT_MAX_ITERATIONS,
|
|
25578
|
+
completion_promise: stripQuotes(data.completion_promise) || DEFAULT_COMPLETION_PROMISE,
|
|
25579
|
+
started_at: stripQuotes(data.started_at) || new Date().toISOString(),
|
|
25580
|
+
prompt: body.trim(),
|
|
25581
|
+
session_id: data.session_id ? stripQuotes(data.session_id) : undefined,
|
|
25582
|
+
ultrawork: data.ultrawork === true || data.ultrawork === "true" ? true : undefined
|
|
25583
|
+
};
|
|
25584
|
+
} catch {
|
|
25585
|
+
return null;
|
|
25586
|
+
}
|
|
25587
|
+
}
|
|
25588
|
+
|
|
25589
|
+
// src/cli/run/continuation-state.ts
|
|
25590
|
+
function getContinuationState(directory, sessionID) {
|
|
25591
|
+
const marker = readContinuationMarker(directory, sessionID);
|
|
25592
|
+
return {
|
|
25593
|
+
hasActiveBoulder: hasActiveBoulderContinuation(directory, sessionID),
|
|
25594
|
+
hasActiveRalphLoop: hasActiveRalphLoopContinuation(directory, sessionID),
|
|
25595
|
+
hasHookMarker: marker !== null,
|
|
25596
|
+
hasTodoHookMarker: marker?.sources.todo !== undefined,
|
|
25597
|
+
hasActiveHookMarker: isContinuationMarkerActive(marker),
|
|
25598
|
+
activeHookMarkerReason: getActiveContinuationMarkerReason(marker)
|
|
25599
|
+
};
|
|
25600
|
+
}
|
|
25601
|
+
function hasActiveBoulderContinuation(directory, sessionID) {
|
|
25602
|
+
const boulder = readBoulderState(directory);
|
|
25603
|
+
if (!boulder)
|
|
25604
|
+
return false;
|
|
25605
|
+
if (!boulder.session_ids.includes(sessionID))
|
|
25606
|
+
return false;
|
|
25607
|
+
const progress = getPlanProgress(boulder.active_plan);
|
|
25608
|
+
return !progress.isComplete;
|
|
25609
|
+
}
|
|
25610
|
+
function hasActiveRalphLoopContinuation(directory, sessionID) {
|
|
25611
|
+
const state = readState(directory);
|
|
25612
|
+
if (!state || !state.active)
|
|
25613
|
+
return false;
|
|
25614
|
+
if (state.session_id && state.session_id !== sessionID) {
|
|
25615
|
+
return false;
|
|
25616
|
+
}
|
|
25617
|
+
return true;
|
|
25618
|
+
}
|
|
25619
|
+
|
|
25620
|
+
// src/cli/run/completion.ts
|
|
25040
25621
|
async function checkCompletionConditions(ctx) {
|
|
25041
25622
|
try {
|
|
25042
|
-
|
|
25623
|
+
const continuationState = getContinuationState(ctx.directory, ctx.sessionID);
|
|
25624
|
+
if (continuationState.hasActiveHookMarker) {
|
|
25625
|
+
const reason = continuationState.activeHookMarkerReason ?? "continuation hook is active";
|
|
25626
|
+
console.log(import_picocolors13.default.dim(` Waiting: ${reason}`));
|
|
25627
|
+
return false;
|
|
25628
|
+
}
|
|
25629
|
+
if (!continuationState.hasTodoHookMarker && !await areAllTodosComplete(ctx)) {
|
|
25043
25630
|
return false;
|
|
25044
25631
|
}
|
|
25045
25632
|
if (!await areAllChildrenIdle(ctx)) {
|
|
25046
25633
|
return false;
|
|
25047
25634
|
}
|
|
25635
|
+
if (!areContinuationHooksIdle(continuationState)) {
|
|
25636
|
+
return false;
|
|
25637
|
+
}
|
|
25048
25638
|
return true;
|
|
25049
25639
|
} catch (err) {
|
|
25050
|
-
console.error(
|
|
25640
|
+
console.error(import_picocolors13.default.red(`[completion] API error: ${err}`));
|
|
25051
25641
|
return false;
|
|
25052
25642
|
}
|
|
25053
25643
|
}
|
|
25644
|
+
function areContinuationHooksIdle(continuationState) {
|
|
25645
|
+
if (continuationState.hasActiveBoulder) {
|
|
25646
|
+
console.log(import_picocolors13.default.dim(" Waiting: boulder continuation is active"));
|
|
25647
|
+
return false;
|
|
25648
|
+
}
|
|
25649
|
+
if (continuationState.hasActiveRalphLoop) {
|
|
25650
|
+
console.log(import_picocolors13.default.dim(" Waiting: ralph-loop continuation is active"));
|
|
25651
|
+
return false;
|
|
25652
|
+
}
|
|
25653
|
+
return true;
|
|
25654
|
+
}
|
|
25054
25655
|
async function areAllTodosComplete(ctx) {
|
|
25055
25656
|
const todosRes = await ctx.client.session.todo({
|
|
25056
25657
|
path: { id: ctx.sessionID },
|
|
@@ -25059,7 +25660,7 @@ async function areAllTodosComplete(ctx) {
|
|
|
25059
25660
|
const todos = normalizeSDKResponse(todosRes, []);
|
|
25060
25661
|
const incompleteTodos = todos.filter((t) => t.status !== "completed" && t.status !== "cancelled");
|
|
25061
25662
|
if (incompleteTodos.length > 0) {
|
|
25062
|
-
console.log(
|
|
25663
|
+
console.log(import_picocolors13.default.dim(` Waiting: ${incompleteTodos.length} todos remaining`));
|
|
25063
25664
|
return false;
|
|
25064
25665
|
}
|
|
25065
25666
|
return true;
|
|
@@ -25083,7 +25684,7 @@ async function areAllDescendantsIdle(ctx, sessionID, allStatuses) {
|
|
|
25083
25684
|
for (const child of children) {
|
|
25084
25685
|
const status = allStatuses[child.id];
|
|
25085
25686
|
if (status && status.type !== "idle") {
|
|
25086
|
-
console.log(
|
|
25687
|
+
console.log(import_picocolors13.default.dim(` Waiting: session ${child.id.slice(0, 8)}... is ${status.type}`));
|
|
25087
25688
|
return false;
|
|
25088
25689
|
}
|
|
25089
25690
|
const descendantsIdle = await areAllDescendantsIdle(ctx, child.id, allStatuses);
|
|
@@ -25097,9 +25698,9 @@ async function areAllDescendantsIdle(ctx, sessionID, allStatuses) {
|
|
|
25097
25698
|
// src/cli/run/poll-for-completion.ts
|
|
25098
25699
|
init_shared();
|
|
25099
25700
|
var DEFAULT_POLL_INTERVAL_MS = 500;
|
|
25100
|
-
var DEFAULT_REQUIRED_CONSECUTIVE =
|
|
25701
|
+
var DEFAULT_REQUIRED_CONSECUTIVE = 1;
|
|
25101
25702
|
var ERROR_GRACE_CYCLES = 3;
|
|
25102
|
-
var MIN_STABILIZATION_MS =
|
|
25703
|
+
var MIN_STABILIZATION_MS = 0;
|
|
25103
25704
|
async function pollForCompletion(ctx, eventState, abortController, options = {}) {
|
|
25104
25705
|
const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
25105
25706
|
const requiredConsecutive = options.requiredConsecutive ?? DEFAULT_REQUIRED_CONSECUTIVE;
|
|
@@ -25110,13 +25711,16 @@ async function pollForCompletion(ctx, eventState, abortController, options = {})
|
|
|
25110
25711
|
const pollStartTimestamp = Date.now();
|
|
25111
25712
|
while (!abortController.signal.aborted) {
|
|
25112
25713
|
await new Promise((resolve2) => setTimeout(resolve2, pollIntervalMs));
|
|
25714
|
+
if (abortController.signal.aborted) {
|
|
25715
|
+
return 130;
|
|
25716
|
+
}
|
|
25113
25717
|
if (eventState.mainSessionError) {
|
|
25114
25718
|
errorCycleCount++;
|
|
25115
25719
|
if (errorCycleCount >= ERROR_GRACE_CYCLES) {
|
|
25116
|
-
console.error(
|
|
25720
|
+
console.error(import_picocolors14.default.red(`
|
|
25117
25721
|
|
|
25118
25722
|
Session ended with error: ${eventState.lastError}`));
|
|
25119
|
-
console.error(
|
|
25723
|
+
console.error(import_picocolors14.default.yellow("Check if todos were completed before the error."));
|
|
25120
25724
|
return 1;
|
|
25121
25725
|
}
|
|
25122
25726
|
continue;
|
|
@@ -25138,6 +25742,10 @@ Session ended with error: ${eventState.lastError}`));
|
|
|
25138
25742
|
continue;
|
|
25139
25743
|
}
|
|
25140
25744
|
if (!eventState.hasReceivedMeaningfulWork) {
|
|
25745
|
+
if (minStabilizationMs <= 0) {
|
|
25746
|
+
consecutiveCompleteChecks = 0;
|
|
25747
|
+
continue;
|
|
25748
|
+
}
|
|
25141
25749
|
if (Date.now() - pollStartTimestamp < minStabilizationMs) {
|
|
25142
25750
|
consecutiveCompleteChecks = 0;
|
|
25143
25751
|
continue;
|
|
@@ -25153,9 +25761,12 @@ Session ended with error: ${eventState.lastError}`));
|
|
|
25153
25761
|
}
|
|
25154
25762
|
const shouldExit = await checkCompletionConditions(ctx);
|
|
25155
25763
|
if (shouldExit) {
|
|
25764
|
+
if (abortController.signal.aborted) {
|
|
25765
|
+
return 130;
|
|
25766
|
+
}
|
|
25156
25767
|
consecutiveCompleteChecks++;
|
|
25157
25768
|
if (consecutiveCompleteChecks >= requiredConsecutive) {
|
|
25158
|
-
console.log(
|
|
25769
|
+
console.log(import_picocolors14.default.green(`
|
|
25159
25770
|
|
|
25160
25771
|
All tasks completed.`));
|
|
25161
25772
|
return 0;
|
|
@@ -25182,25 +25793,40 @@ async function getMainSessionStatus(ctx) {
|
|
|
25182
25793
|
}
|
|
25183
25794
|
}
|
|
25184
25795
|
|
|
25796
|
+
// src/cli/run/agent-profile-colors.ts
|
|
25797
|
+
init_shared();
|
|
25798
|
+
async function loadAgentProfileColors(client3) {
|
|
25799
|
+
try {
|
|
25800
|
+
const agentsRes = await client3.app.agents();
|
|
25801
|
+
const agents = normalizeSDKResponse(agentsRes, [], {
|
|
25802
|
+
preferResponseOnMissingData: true
|
|
25803
|
+
});
|
|
25804
|
+
const colors = {};
|
|
25805
|
+
for (const agent of agents) {
|
|
25806
|
+
if (!agent.name || !agent.color)
|
|
25807
|
+
continue;
|
|
25808
|
+
colors[agent.name] = agent.color;
|
|
25809
|
+
}
|
|
25810
|
+
return colors;
|
|
25811
|
+
} catch {
|
|
25812
|
+
return {};
|
|
25813
|
+
}
|
|
25814
|
+
}
|
|
25815
|
+
|
|
25185
25816
|
// src/cli/run/runner.ts
|
|
25186
|
-
var DEFAULT_TIMEOUT_MS = 600000;
|
|
25187
25817
|
var EVENT_PROCESSOR_SHUTDOWN_TIMEOUT_MS = 2000;
|
|
25188
25818
|
async function waitForEventProcessorShutdown(eventProcessor, timeoutMs = EVENT_PROCESSOR_SHUTDOWN_TIMEOUT_MS) {
|
|
25189
25819
|
const completed = await Promise.race([
|
|
25190
25820
|
eventProcessor.then(() => true),
|
|
25191
25821
|
new Promise((resolve2) => setTimeout(() => resolve2(false), timeoutMs))
|
|
25192
25822
|
]);
|
|
25193
|
-
if (!completed) {
|
|
25194
|
-
console.log(import_picocolors14.default.dim(`[run] Event stream did not close within ${timeoutMs}ms after abort; continuing shutdown.`));
|
|
25195
|
-
}
|
|
25196
25823
|
}
|
|
25197
25824
|
async function run(options) {
|
|
25198
25825
|
process.env.OPENCODE_CLI_RUN_MODE = "true";
|
|
25199
25826
|
const startTime = Date.now();
|
|
25200
25827
|
const {
|
|
25201
25828
|
message,
|
|
25202
|
-
directory = process.cwd()
|
|
25203
|
-
timeout = DEFAULT_TIMEOUT_MS
|
|
25829
|
+
directory = process.cwd()
|
|
25204
25830
|
} = options;
|
|
25205
25831
|
const jsonManager = options.json ? createJsonOutputManager() : null;
|
|
25206
25832
|
if (jsonManager)
|
|
@@ -25208,14 +25834,6 @@ async function run(options) {
|
|
|
25208
25834
|
const pluginConfig = loadPluginConfig(directory, { command: "run" });
|
|
25209
25835
|
const resolvedAgent = resolveRunAgent(options, pluginConfig);
|
|
25210
25836
|
const abortController = new AbortController;
|
|
25211
|
-
let timeoutId = null;
|
|
25212
|
-
if (timeout > 0) {
|
|
25213
|
-
timeoutId = setTimeout(() => {
|
|
25214
|
-
console.log(import_picocolors14.default.yellow(`
|
|
25215
|
-
Timeout reached. Aborting...`));
|
|
25216
|
-
abortController.abort();
|
|
25217
|
-
}, timeout);
|
|
25218
|
-
}
|
|
25219
25837
|
try {
|
|
25220
25838
|
const { client: client3, cleanup: serverCleanup } = await createServerConnection({
|
|
25221
25839
|
port: options.port,
|
|
@@ -25223,12 +25841,10 @@ Timeout reached. Aborting...`));
|
|
|
25223
25841
|
signal: abortController.signal
|
|
25224
25842
|
});
|
|
25225
25843
|
const cleanup = () => {
|
|
25226
|
-
if (timeoutId)
|
|
25227
|
-
clearTimeout(timeoutId);
|
|
25228
25844
|
serverCleanup();
|
|
25229
25845
|
};
|
|
25230
25846
|
process.on("SIGINT", () => {
|
|
25231
|
-
console.log(
|
|
25847
|
+
console.log(import_picocolors15.default.yellow(`
|
|
25232
25848
|
Interrupted. Shutting down...`));
|
|
25233
25849
|
cleanup();
|
|
25234
25850
|
process.exit(130);
|
|
@@ -25239,13 +25855,18 @@ Interrupted. Shutting down...`));
|
|
|
25239
25855
|
sessionId: options.sessionId,
|
|
25240
25856
|
directory
|
|
25241
25857
|
});
|
|
25242
|
-
console.log(
|
|
25243
|
-
const ctx = {
|
|
25858
|
+
console.log(import_picocolors15.default.dim(`Session: ${sessionID}`));
|
|
25859
|
+
const ctx = {
|
|
25860
|
+
client: client3,
|
|
25861
|
+
sessionID,
|
|
25862
|
+
directory,
|
|
25863
|
+
abortController,
|
|
25864
|
+
verbose: options.verbose ?? false
|
|
25865
|
+
};
|
|
25244
25866
|
const events = await client3.event.subscribe({ query: { directory } });
|
|
25245
25867
|
const eventState = createEventState();
|
|
25868
|
+
eventState.agentColorsByName = await loadAgentProfileColors(client3);
|
|
25246
25869
|
const eventProcessor = processEvents(ctx, events.stream, eventState).catch(() => {});
|
|
25247
|
-
console.log(import_picocolors14.default.dim(`
|
|
25248
|
-
Sending prompt...`));
|
|
25249
25870
|
await client3.session.promptAsync({
|
|
25250
25871
|
path: { id: sessionID },
|
|
25251
25872
|
body: {
|
|
@@ -25254,8 +25875,6 @@ Sending prompt...`));
|
|
|
25254
25875
|
},
|
|
25255
25876
|
query: { directory }
|
|
25256
25877
|
});
|
|
25257
|
-
console.log(import_picocolors14.default.dim(`Waiting for completion...
|
|
25258
|
-
`));
|
|
25259
25878
|
const exitCode = await pollForCompletion(ctx, eventState, abortController);
|
|
25260
25879
|
abortController.abort();
|
|
25261
25880
|
await waitForEventProcessorShutdown(eventProcessor);
|
|
@@ -25285,14 +25904,12 @@ Sending prompt...`));
|
|
|
25285
25904
|
throw err;
|
|
25286
25905
|
}
|
|
25287
25906
|
} catch (err) {
|
|
25288
|
-
if (timeoutId)
|
|
25289
|
-
clearTimeout(timeoutId);
|
|
25290
25907
|
if (jsonManager)
|
|
25291
25908
|
jsonManager.restore();
|
|
25292
25909
|
if (err instanceof Error && err.name === "AbortError") {
|
|
25293
25910
|
return 130;
|
|
25294
25911
|
}
|
|
25295
|
-
console.error(
|
|
25912
|
+
console.error(import_picocolors15.default.red(`Error: ${serializeError(err)}`));
|
|
25296
25913
|
return 1;
|
|
25297
25914
|
}
|
|
25298
25915
|
}
|
|
@@ -25300,53 +25917,53 @@ Sending prompt...`));
|
|
|
25300
25917
|
init_checker();
|
|
25301
25918
|
|
|
25302
25919
|
// src/cli/get-local-version/formatter.ts
|
|
25303
|
-
var
|
|
25920
|
+
var import_picocolors16 = __toESM(require_picocolors(), 1);
|
|
25304
25921
|
var SYMBOLS2 = {
|
|
25305
|
-
check:
|
|
25306
|
-
cross:
|
|
25307
|
-
arrow:
|
|
25308
|
-
info:
|
|
25309
|
-
warn:
|
|
25310
|
-
pin:
|
|
25311
|
-
dev:
|
|
25922
|
+
check: import_picocolors16.default.green("[OK]"),
|
|
25923
|
+
cross: import_picocolors16.default.red("[X]"),
|
|
25924
|
+
arrow: import_picocolors16.default.cyan("->"),
|
|
25925
|
+
info: import_picocolors16.default.blue("[i]"),
|
|
25926
|
+
warn: import_picocolors16.default.yellow("[!]"),
|
|
25927
|
+
pin: import_picocolors16.default.magenta("[PINNED]"),
|
|
25928
|
+
dev: import_picocolors16.default.cyan("[DEV]")
|
|
25312
25929
|
};
|
|
25313
25930
|
function formatVersionOutput(info) {
|
|
25314
25931
|
const lines = [];
|
|
25315
25932
|
lines.push("");
|
|
25316
|
-
lines.push(
|
|
25317
|
-
lines.push(
|
|
25933
|
+
lines.push(import_picocolors16.default.bold(import_picocolors16.default.white("oh-my-opencode Version Information")));
|
|
25934
|
+
lines.push(import_picocolors16.default.dim("\u2500".repeat(50)));
|
|
25318
25935
|
lines.push("");
|
|
25319
25936
|
if (info.currentVersion) {
|
|
25320
|
-
lines.push(` Current Version: ${
|
|
25937
|
+
lines.push(` Current Version: ${import_picocolors16.default.cyan(info.currentVersion)}`);
|
|
25321
25938
|
} else {
|
|
25322
|
-
lines.push(` Current Version: ${
|
|
25939
|
+
lines.push(` Current Version: ${import_picocolors16.default.dim("unknown")}`);
|
|
25323
25940
|
}
|
|
25324
25941
|
if (!info.isLocalDev && info.latestVersion) {
|
|
25325
|
-
lines.push(` Latest Version: ${
|
|
25942
|
+
lines.push(` Latest Version: ${import_picocolors16.default.cyan(info.latestVersion)}`);
|
|
25326
25943
|
}
|
|
25327
25944
|
lines.push("");
|
|
25328
25945
|
switch (info.status) {
|
|
25329
25946
|
case "up-to-date":
|
|
25330
|
-
lines.push(` ${SYMBOLS2.check} ${
|
|
25947
|
+
lines.push(` ${SYMBOLS2.check} ${import_picocolors16.default.green("You're up to date!")}`);
|
|
25331
25948
|
break;
|
|
25332
25949
|
case "outdated":
|
|
25333
|
-
lines.push(` ${SYMBOLS2.warn} ${
|
|
25334
|
-
lines.push(` ${
|
|
25950
|
+
lines.push(` ${SYMBOLS2.warn} ${import_picocolors16.default.yellow("Update available")}`);
|
|
25951
|
+
lines.push(` ${import_picocolors16.default.dim("Run:")} ${import_picocolors16.default.cyan("cd ~/.config/opencode && bun update oh-my-opencode")}`);
|
|
25335
25952
|
break;
|
|
25336
25953
|
case "local-dev":
|
|
25337
|
-
lines.push(` ${SYMBOLS2.dev} ${
|
|
25338
|
-
lines.push(` ${
|
|
25954
|
+
lines.push(` ${SYMBOLS2.dev} ${import_picocolors16.default.cyan("Running in local development mode")}`);
|
|
25955
|
+
lines.push(` ${import_picocolors16.default.dim("Using file:// protocol from config")}`);
|
|
25339
25956
|
break;
|
|
25340
25957
|
case "pinned":
|
|
25341
|
-
lines.push(` ${SYMBOLS2.pin} ${
|
|
25342
|
-
lines.push(` ${
|
|
25958
|
+
lines.push(` ${SYMBOLS2.pin} ${import_picocolors16.default.magenta(`Version pinned to ${info.pinnedVersion}`)}`);
|
|
25959
|
+
lines.push(` ${import_picocolors16.default.dim("Update check skipped for pinned versions")}`);
|
|
25343
25960
|
break;
|
|
25344
25961
|
case "error":
|
|
25345
|
-
lines.push(` ${SYMBOLS2.cross} ${
|
|
25346
|
-
lines.push(` ${
|
|
25962
|
+
lines.push(` ${SYMBOLS2.cross} ${import_picocolors16.default.red("Unable to check for updates")}`);
|
|
25963
|
+
lines.push(` ${import_picocolors16.default.dim("Network error or npm registry unavailable")}`);
|
|
25347
25964
|
break;
|
|
25348
25965
|
case "unknown":
|
|
25349
|
-
lines.push(` ${SYMBOLS2.info} ${
|
|
25966
|
+
lines.push(` ${SYMBOLS2.info} ${import_picocolors16.default.yellow("Version information unavailable")}`);
|
|
25350
25967
|
break;
|
|
25351
25968
|
}
|
|
25352
25969
|
lines.push("");
|
|
@@ -25446,21 +26063,21 @@ async function getLocalVersion(options = {}) {
|
|
|
25446
26063
|
}
|
|
25447
26064
|
}
|
|
25448
26065
|
// src/cli/doctor/constants.ts
|
|
25449
|
-
var
|
|
26066
|
+
var import_picocolors17 = __toESM(require_picocolors(), 1);
|
|
25450
26067
|
var SYMBOLS3 = {
|
|
25451
|
-
check:
|
|
25452
|
-
cross:
|
|
25453
|
-
warn:
|
|
25454
|
-
info:
|
|
25455
|
-
arrow:
|
|
25456
|
-
bullet:
|
|
25457
|
-
skip:
|
|
26068
|
+
check: import_picocolors17.default.green("\u2713"),
|
|
26069
|
+
cross: import_picocolors17.default.red("\u2717"),
|
|
26070
|
+
warn: import_picocolors17.default.yellow("\u26A0"),
|
|
26071
|
+
info: import_picocolors17.default.blue("\u2139"),
|
|
26072
|
+
arrow: import_picocolors17.default.cyan("\u2192"),
|
|
26073
|
+
bullet: import_picocolors17.default.dim("\u2022"),
|
|
26074
|
+
skip: import_picocolors17.default.dim("\u25CB")
|
|
25458
26075
|
};
|
|
25459
26076
|
var STATUS_COLORS = {
|
|
25460
|
-
pass:
|
|
25461
|
-
fail:
|
|
25462
|
-
warn:
|
|
25463
|
-
skip:
|
|
26077
|
+
pass: import_picocolors17.default.green,
|
|
26078
|
+
fail: import_picocolors17.default.red,
|
|
26079
|
+
warn: import_picocolors17.default.yellow,
|
|
26080
|
+
skip: import_picocolors17.default.dim
|
|
25464
26081
|
};
|
|
25465
26082
|
var CHECK_IDS = {
|
|
25466
26083
|
SYSTEM: "system",
|
|
@@ -25483,29 +26100,29 @@ var PACKAGE_NAME4 = "oh-my-opencode";
|
|
|
25483
26100
|
var OPENCODE_BINARIES2 = ["opencode", "opencode-desktop"];
|
|
25484
26101
|
|
|
25485
26102
|
// src/cli/doctor/checks/system.ts
|
|
25486
|
-
import { existsSync as
|
|
26103
|
+
import { existsSync as existsSync22, readFileSync as readFileSync23 } from "fs";
|
|
25487
26104
|
|
|
25488
26105
|
// src/cli/doctor/checks/system-binary.ts
|
|
25489
|
-
import { existsSync as
|
|
26106
|
+
import { existsSync as existsSync19 } from "fs";
|
|
25490
26107
|
import { homedir as homedir5 } from "os";
|
|
25491
|
-
import { join as
|
|
26108
|
+
import { join as join16 } from "path";
|
|
25492
26109
|
function getDesktopAppPaths(platform) {
|
|
25493
26110
|
const home = homedir5();
|
|
25494
26111
|
switch (platform) {
|
|
25495
26112
|
case "darwin":
|
|
25496
26113
|
return [
|
|
25497
26114
|
"/Applications/OpenCode.app/Contents/MacOS/OpenCode",
|
|
25498
|
-
|
|
26115
|
+
join16(home, "Applications", "OpenCode.app", "Contents", "MacOS", "OpenCode")
|
|
25499
26116
|
];
|
|
25500
26117
|
case "win32": {
|
|
25501
26118
|
const programFiles = process.env.ProgramFiles;
|
|
25502
26119
|
const localAppData = process.env.LOCALAPPDATA;
|
|
25503
26120
|
const paths = [];
|
|
25504
26121
|
if (programFiles) {
|
|
25505
|
-
paths.push(
|
|
26122
|
+
paths.push(join16(programFiles, "OpenCode", "OpenCode.exe"));
|
|
25506
26123
|
}
|
|
25507
26124
|
if (localAppData) {
|
|
25508
|
-
paths.push(
|
|
26125
|
+
paths.push(join16(localAppData, "OpenCode", "OpenCode.exe"));
|
|
25509
26126
|
}
|
|
25510
26127
|
return paths;
|
|
25511
26128
|
}
|
|
@@ -25513,8 +26130,8 @@ function getDesktopAppPaths(platform) {
|
|
|
25513
26130
|
return [
|
|
25514
26131
|
"/usr/bin/opencode",
|
|
25515
26132
|
"/usr/lib/opencode/opencode",
|
|
25516
|
-
|
|
25517
|
-
|
|
26133
|
+
join16(home, "Applications", "opencode-desktop-linux-x86_64.AppImage"),
|
|
26134
|
+
join16(home, "Applications", "opencode-desktop-linux-aarch64.AppImage")
|
|
25518
26135
|
];
|
|
25519
26136
|
default:
|
|
25520
26137
|
return [];
|
|
@@ -25526,7 +26143,7 @@ function buildVersionCommand(binaryPath, platform) {
|
|
|
25526
26143
|
}
|
|
25527
26144
|
return [binaryPath, "--version"];
|
|
25528
26145
|
}
|
|
25529
|
-
function findDesktopBinary(platform = process.platform, checkExists =
|
|
26146
|
+
function findDesktopBinary(platform = process.platform, checkExists = existsSync19) {
|
|
25530
26147
|
for (const desktopPath of getDesktopAppPaths(platform)) {
|
|
25531
26148
|
if (checkExists(desktopPath)) {
|
|
25532
26149
|
return { binary: "opencode", path: desktopPath };
|
|
@@ -25573,13 +26190,13 @@ function compareVersions(current, minimum) {
|
|
|
25573
26190
|
}
|
|
25574
26191
|
|
|
25575
26192
|
// src/cli/doctor/checks/system-plugin.ts
|
|
25576
|
-
import { existsSync as
|
|
26193
|
+
import { existsSync as existsSync20, readFileSync as readFileSync21 } from "fs";
|
|
25577
26194
|
init_shared();
|
|
25578
26195
|
function detectConfigPath() {
|
|
25579
26196
|
const paths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
|
|
25580
|
-
if (
|
|
26197
|
+
if (existsSync20(paths.configJsonc))
|
|
25581
26198
|
return paths.configJsonc;
|
|
25582
|
-
if (
|
|
26199
|
+
if (existsSync20(paths.configJson))
|
|
25583
26200
|
return paths.configJson;
|
|
25584
26201
|
return null;
|
|
25585
26202
|
}
|
|
@@ -25615,7 +26232,7 @@ function getPluginInfo() {
|
|
|
25615
26232
|
};
|
|
25616
26233
|
}
|
|
25617
26234
|
try {
|
|
25618
|
-
const content =
|
|
26235
|
+
const content = readFileSync21(configPath, "utf-8");
|
|
25619
26236
|
const parsedConfig = parseJsonc(content);
|
|
25620
26237
|
const pluginEntry = findPluginEntry2(parsedConfig.plugin ?? []);
|
|
25621
26238
|
if (!pluginEntry) {
|
|
@@ -25652,32 +26269,32 @@ function getPluginInfo() {
|
|
|
25652
26269
|
// src/cli/doctor/checks/system-loaded-version.ts
|
|
25653
26270
|
init_checker();
|
|
25654
26271
|
init_auto_update_checker();
|
|
25655
|
-
import { existsSync as
|
|
26272
|
+
import { existsSync as existsSync21, readFileSync as readFileSync22 } from "fs";
|
|
25656
26273
|
import { homedir as homedir6 } from "os";
|
|
25657
|
-
import { join as
|
|
26274
|
+
import { join as join17 } from "path";
|
|
25658
26275
|
init_shared();
|
|
25659
26276
|
function getPlatformDefaultCacheDir(platform = process.platform) {
|
|
25660
26277
|
if (platform === "darwin")
|
|
25661
|
-
return
|
|
26278
|
+
return join17(homedir6(), "Library", "Caches");
|
|
25662
26279
|
if (platform === "win32")
|
|
25663
|
-
return process.env.LOCALAPPDATA ??
|
|
25664
|
-
return
|
|
26280
|
+
return process.env.LOCALAPPDATA ?? join17(homedir6(), "AppData", "Local");
|
|
26281
|
+
return join17(homedir6(), ".cache");
|
|
25665
26282
|
}
|
|
25666
26283
|
function resolveOpenCodeCacheDir() {
|
|
25667
26284
|
const xdgCacheHome = process.env.XDG_CACHE_HOME;
|
|
25668
26285
|
if (xdgCacheHome)
|
|
25669
|
-
return
|
|
26286
|
+
return join17(xdgCacheHome, "opencode");
|
|
25670
26287
|
const fromShared = getOpenCodeCacheDir();
|
|
25671
|
-
const platformDefault =
|
|
25672
|
-
if (
|
|
26288
|
+
const platformDefault = join17(getPlatformDefaultCacheDir(), "opencode");
|
|
26289
|
+
if (existsSync21(fromShared) || !existsSync21(platformDefault))
|
|
25673
26290
|
return fromShared;
|
|
25674
26291
|
return platformDefault;
|
|
25675
26292
|
}
|
|
25676
26293
|
function readPackageJson(filePath) {
|
|
25677
|
-
if (!
|
|
26294
|
+
if (!existsSync21(filePath))
|
|
25678
26295
|
return null;
|
|
25679
26296
|
try {
|
|
25680
|
-
const content =
|
|
26297
|
+
const content = readFileSync22(filePath, "utf-8");
|
|
25681
26298
|
return parseJsonc(content);
|
|
25682
26299
|
} catch {
|
|
25683
26300
|
return null;
|
|
@@ -25691,8 +26308,8 @@ function normalizeVersion(value) {
|
|
|
25691
26308
|
}
|
|
25692
26309
|
function getLoadedPluginVersion() {
|
|
25693
26310
|
const cacheDir = resolveOpenCodeCacheDir();
|
|
25694
|
-
const cachePackagePath =
|
|
25695
|
-
const installedPackagePath =
|
|
26311
|
+
const cachePackagePath = join17(cacheDir, "package.json");
|
|
26312
|
+
const installedPackagePath = join17(cacheDir, "node_modules", PACKAGE_NAME4, "package.json");
|
|
25696
26313
|
const cachePackage = readPackageJson(cachePackagePath);
|
|
25697
26314
|
const installedPackage = readPackageJson(installedPackagePath);
|
|
25698
26315
|
const expectedVersion = normalizeVersion(cachePackage?.dependencies?.[PACKAGE_NAME4]);
|
|
@@ -25715,10 +26332,10 @@ init_shared();
|
|
|
25715
26332
|
function isConfigValid(configPath) {
|
|
25716
26333
|
if (!configPath)
|
|
25717
26334
|
return true;
|
|
25718
|
-
if (!
|
|
26335
|
+
if (!existsSync22(configPath))
|
|
25719
26336
|
return false;
|
|
25720
26337
|
try {
|
|
25721
|
-
parseJsonc(
|
|
26338
|
+
parseJsonc(readFileSync23(configPath, "utf-8"));
|
|
25722
26339
|
return true;
|
|
25723
26340
|
} catch {
|
|
25724
26341
|
return false;
|
|
@@ -25820,28 +26437,28 @@ async function checkSystem() {
|
|
|
25820
26437
|
}
|
|
25821
26438
|
|
|
25822
26439
|
// src/cli/doctor/checks/config.ts
|
|
25823
|
-
import { readFileSync as
|
|
25824
|
-
import { join as
|
|
26440
|
+
import { readFileSync as readFileSync26 } from "fs";
|
|
26441
|
+
import { join as join21 } from "path";
|
|
25825
26442
|
init_shared();
|
|
25826
26443
|
|
|
25827
26444
|
// src/cli/doctor/checks/model-resolution-cache.ts
|
|
25828
26445
|
init_shared();
|
|
25829
|
-
import { existsSync as
|
|
26446
|
+
import { existsSync as existsSync23, readFileSync as readFileSync24 } from "fs";
|
|
25830
26447
|
import { homedir as homedir7 } from "os";
|
|
25831
|
-
import { join as
|
|
26448
|
+
import { join as join18 } from "path";
|
|
25832
26449
|
function getOpenCodeCacheDir2() {
|
|
25833
26450
|
const xdgCache = process.env.XDG_CACHE_HOME;
|
|
25834
26451
|
if (xdgCache)
|
|
25835
|
-
return
|
|
25836
|
-
return
|
|
26452
|
+
return join18(xdgCache, "opencode");
|
|
26453
|
+
return join18(homedir7(), ".cache", "opencode");
|
|
25837
26454
|
}
|
|
25838
26455
|
function loadAvailableModelsFromCache() {
|
|
25839
|
-
const cacheFile =
|
|
25840
|
-
if (!
|
|
26456
|
+
const cacheFile = join18(getOpenCodeCacheDir2(), "models.json");
|
|
26457
|
+
if (!existsSync23(cacheFile)) {
|
|
25841
26458
|
return { providers: [], modelCount: 0, cacheExists: false };
|
|
25842
26459
|
}
|
|
25843
26460
|
try {
|
|
25844
|
-
const content =
|
|
26461
|
+
const content = readFileSync24(cacheFile, "utf-8");
|
|
25845
26462
|
const data = parseJsonc(content);
|
|
25846
26463
|
const providers = Object.keys(data);
|
|
25847
26464
|
let modelCount = 0;
|
|
@@ -25862,16 +26479,16 @@ init_model_requirements();
|
|
|
25862
26479
|
|
|
25863
26480
|
// src/cli/doctor/checks/model-resolution-config.ts
|
|
25864
26481
|
init_shared();
|
|
25865
|
-
import { readFileSync as
|
|
25866
|
-
import { join as
|
|
26482
|
+
import { readFileSync as readFileSync25 } from "fs";
|
|
26483
|
+
import { join as join19 } from "path";
|
|
25867
26484
|
var PACKAGE_NAME5 = "oh-my-opencode";
|
|
25868
|
-
var USER_CONFIG_BASE =
|
|
25869
|
-
var PROJECT_CONFIG_BASE =
|
|
26485
|
+
var USER_CONFIG_BASE = join19(getOpenCodeConfigPaths({ binary: "opencode", version: null }).configDir, PACKAGE_NAME5);
|
|
26486
|
+
var PROJECT_CONFIG_BASE = join19(process.cwd(), ".opencode", PACKAGE_NAME5);
|
|
25870
26487
|
function loadOmoConfig() {
|
|
25871
26488
|
const projectDetected = detectConfigFile(PROJECT_CONFIG_BASE);
|
|
25872
26489
|
if (projectDetected.format !== "none") {
|
|
25873
26490
|
try {
|
|
25874
|
-
const content =
|
|
26491
|
+
const content = readFileSync25(projectDetected.path, "utf-8");
|
|
25875
26492
|
return parseJsonc(content);
|
|
25876
26493
|
} catch {
|
|
25877
26494
|
return null;
|
|
@@ -25880,7 +26497,7 @@ function loadOmoConfig() {
|
|
|
25880
26497
|
const userDetected = detectConfigFile(USER_CONFIG_BASE);
|
|
25881
26498
|
if (userDetected.format !== "none") {
|
|
25882
26499
|
try {
|
|
25883
|
-
const content =
|
|
26500
|
+
const content = readFileSync25(userDetected.path, "utf-8");
|
|
25884
26501
|
return parseJsonc(content);
|
|
25885
26502
|
} catch {
|
|
25886
26503
|
return null;
|
|
@@ -25891,7 +26508,7 @@ function loadOmoConfig() {
|
|
|
25891
26508
|
|
|
25892
26509
|
// src/cli/doctor/checks/model-resolution-details.ts
|
|
25893
26510
|
init_shared();
|
|
25894
|
-
import { join as
|
|
26511
|
+
import { join as join20 } from "path";
|
|
25895
26512
|
|
|
25896
26513
|
// src/cli/doctor/checks/model-resolution-variant.ts
|
|
25897
26514
|
function formatModelWithVariant(model, variant) {
|
|
@@ -25930,7 +26547,7 @@ function getCategoryEffectiveVariant(categoryName, requirement, config2) {
|
|
|
25930
26547
|
// src/cli/doctor/checks/model-resolution-details.ts
|
|
25931
26548
|
function buildModelResolutionDetails(options) {
|
|
25932
26549
|
const details = [];
|
|
25933
|
-
const cacheFile =
|
|
26550
|
+
const cacheFile = join20(getOpenCodeCacheDir(), "models.json");
|
|
25934
26551
|
details.push("\u2550\u2550\u2550 Available Models (from cache) \u2550\u2550\u2550");
|
|
25935
26552
|
details.push("");
|
|
25936
26553
|
if (options.available.cacheExists) {
|
|
@@ -26042,8 +26659,8 @@ async function checkModels() {
|
|
|
26042
26659
|
}
|
|
26043
26660
|
|
|
26044
26661
|
// src/cli/doctor/checks/config.ts
|
|
26045
|
-
var USER_CONFIG_BASE2 =
|
|
26046
|
-
var PROJECT_CONFIG_BASE2 =
|
|
26662
|
+
var USER_CONFIG_BASE2 = join21(getOpenCodeConfigDir({ binary: "opencode" }), PACKAGE_NAME4);
|
|
26663
|
+
var PROJECT_CONFIG_BASE2 = join21(process.cwd(), ".opencode", PACKAGE_NAME4);
|
|
26047
26664
|
function findConfigPath() {
|
|
26048
26665
|
const projectConfig = detectConfigFile(PROJECT_CONFIG_BASE2);
|
|
26049
26666
|
if (projectConfig.format !== "none")
|
|
@@ -26059,7 +26676,7 @@ function validateConfig() {
|
|
|
26059
26676
|
return { exists: false, path: null, valid: true, config: null, errors: [] };
|
|
26060
26677
|
}
|
|
26061
26678
|
try {
|
|
26062
|
-
const content =
|
|
26679
|
+
const content = readFileSync26(configPath, "utf-8");
|
|
26063
26680
|
const rawConfig = parseJsonc(content);
|
|
26064
26681
|
const schemaResult = OhMyOpenCodeConfigSchema.safeParse(rawConfig);
|
|
26065
26682
|
if (!schemaResult.success) {
|
|
@@ -26162,9 +26779,9 @@ async function checkConfig() {
|
|
|
26162
26779
|
}
|
|
26163
26780
|
|
|
26164
26781
|
// src/cli/doctor/checks/dependencies.ts
|
|
26165
|
-
import { existsSync as
|
|
26782
|
+
import { existsSync as existsSync24 } from "fs";
|
|
26166
26783
|
import { createRequire as createRequire2 } from "module";
|
|
26167
|
-
import { dirname as
|
|
26784
|
+
import { dirname as dirname7, join as join22 } from "path";
|
|
26168
26785
|
async function checkBinaryExists(binary2) {
|
|
26169
26786
|
try {
|
|
26170
26787
|
const path9 = Bun.which(binary2);
|
|
@@ -26220,15 +26837,15 @@ async function checkAstGrepNapi() {
|
|
|
26220
26837
|
path: null
|
|
26221
26838
|
};
|
|
26222
26839
|
} catch {
|
|
26223
|
-
const { existsSync:
|
|
26224
|
-
const { join:
|
|
26840
|
+
const { existsSync: existsSync25 } = await import("fs");
|
|
26841
|
+
const { join: join23 } = await import("path");
|
|
26225
26842
|
const { homedir: homedir8 } = await import("os");
|
|
26226
26843
|
const pathsToCheck = [
|
|
26227
|
-
|
|
26228
|
-
|
|
26844
|
+
join23(homedir8(), ".config", "opencode", "node_modules", "@ast-grep", "napi"),
|
|
26845
|
+
join23(process.cwd(), "node_modules", "@ast-grep", "napi")
|
|
26229
26846
|
];
|
|
26230
26847
|
for (const napiPath of pathsToCheck) {
|
|
26231
|
-
if (
|
|
26848
|
+
if (existsSync25(napiPath)) {
|
|
26232
26849
|
return {
|
|
26233
26850
|
name: "AST-Grep NAPI",
|
|
26234
26851
|
required: false,
|
|
@@ -26253,8 +26870,8 @@ function findCommentCheckerPackageBinary() {
|
|
|
26253
26870
|
try {
|
|
26254
26871
|
const require2 = createRequire2(import.meta.url);
|
|
26255
26872
|
const pkgPath = require2.resolve("@code-yeongyu/comment-checker/package.json");
|
|
26256
|
-
const binaryPath =
|
|
26257
|
-
if (
|
|
26873
|
+
const binaryPath = join22(dirname7(pkgPath), "bin", binaryName);
|
|
26874
|
+
if (existsSync24(binaryPath))
|
|
26258
26875
|
return binaryPath;
|
|
26259
26876
|
} catch {}
|
|
26260
26877
|
return null;
|
|
@@ -26372,14 +26989,14 @@ init_jsonc_parser();
|
|
|
26372
26989
|
|
|
26373
26990
|
// src/tools/lsp/server-installation.ts
|
|
26374
26991
|
init_shared();
|
|
26375
|
-
import { existsSync as
|
|
26376
|
-
import { join as
|
|
26992
|
+
import { existsSync as existsSync25 } from "fs";
|
|
26993
|
+
import { join as join23 } from "path";
|
|
26377
26994
|
function isServerInstalled(command) {
|
|
26378
26995
|
if (command.length === 0)
|
|
26379
26996
|
return false;
|
|
26380
26997
|
const cmd = command[0];
|
|
26381
26998
|
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
26382
|
-
if (
|
|
26999
|
+
if (existsSync25(cmd))
|
|
26383
27000
|
return true;
|
|
26384
27001
|
}
|
|
26385
27002
|
const isWindows = process.platform === "win32";
|
|
@@ -26401,23 +27018,23 @@ function isServerInstalled(command) {
|
|
|
26401
27018
|
const paths = pathEnv.split(pathSeparator);
|
|
26402
27019
|
for (const p2 of paths) {
|
|
26403
27020
|
for (const suffix of exts) {
|
|
26404
|
-
if (
|
|
27021
|
+
if (existsSync25(join23(p2, cmd + suffix))) {
|
|
26405
27022
|
return true;
|
|
26406
27023
|
}
|
|
26407
27024
|
}
|
|
26408
27025
|
}
|
|
26409
27026
|
const cwd = process.cwd();
|
|
26410
27027
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
26411
|
-
const dataDir =
|
|
27028
|
+
const dataDir = join23(getDataDir(), "opencode");
|
|
26412
27029
|
const additionalBases = [
|
|
26413
|
-
|
|
26414
|
-
|
|
26415
|
-
|
|
26416
|
-
|
|
27030
|
+
join23(cwd, "node_modules", ".bin"),
|
|
27031
|
+
join23(configDir, "bin"),
|
|
27032
|
+
join23(configDir, "node_modules", ".bin"),
|
|
27033
|
+
join23(dataDir, "bin")
|
|
26417
27034
|
];
|
|
26418
27035
|
for (const base of additionalBases) {
|
|
26419
27036
|
for (const suffix of exts) {
|
|
26420
|
-
if (
|
|
27037
|
+
if (existsSync25(join23(base, cmd + suffix))) {
|
|
26421
27038
|
return true;
|
|
26422
27039
|
}
|
|
26423
27040
|
}
|
|
@@ -26451,24 +27068,24 @@ function getLspServerStats(servers) {
|
|
|
26451
27068
|
|
|
26452
27069
|
// src/cli/doctor/checks/tools-mcp.ts
|
|
26453
27070
|
init_shared();
|
|
26454
|
-
import { existsSync as
|
|
27071
|
+
import { existsSync as existsSync26, readFileSync as readFileSync27 } from "fs";
|
|
26455
27072
|
import { homedir as homedir8 } from "os";
|
|
26456
|
-
import { join as
|
|
27073
|
+
import { join as join24 } from "path";
|
|
26457
27074
|
var BUILTIN_MCP_SERVERS = ["context7", "grep_app"];
|
|
26458
27075
|
function getMcpConfigPaths() {
|
|
26459
27076
|
return [
|
|
26460
|
-
|
|
26461
|
-
|
|
26462
|
-
|
|
27077
|
+
join24(homedir8(), ".claude", ".mcp.json"),
|
|
27078
|
+
join24(process.cwd(), ".mcp.json"),
|
|
27079
|
+
join24(process.cwd(), ".claude", ".mcp.json")
|
|
26463
27080
|
];
|
|
26464
27081
|
}
|
|
26465
27082
|
function loadUserMcpConfig() {
|
|
26466
27083
|
const servers = {};
|
|
26467
27084
|
for (const configPath of getMcpConfigPaths()) {
|
|
26468
|
-
if (!
|
|
27085
|
+
if (!existsSync26(configPath))
|
|
26469
27086
|
continue;
|
|
26470
27087
|
try {
|
|
26471
|
-
const content =
|
|
27088
|
+
const content = readFileSync27(configPath, "utf-8");
|
|
26472
27089
|
const config2 = parseJsonc(content);
|
|
26473
27090
|
if (config2.mcpServers) {
|
|
26474
27091
|
Object.assign(servers, config2.mcpServers);
|
|
@@ -26629,10 +27246,10 @@ function getAllCheckDefinitions() {
|
|
|
26629
27246
|
}
|
|
26630
27247
|
|
|
26631
27248
|
// src/cli/doctor/format-default.ts
|
|
26632
|
-
var
|
|
27249
|
+
var import_picocolors19 = __toESM(require_picocolors(), 1);
|
|
26633
27250
|
|
|
26634
27251
|
// src/cli/doctor/format-shared.ts
|
|
26635
|
-
var
|
|
27252
|
+
var import_picocolors18 = __toESM(require_picocolors(), 1);
|
|
26636
27253
|
function formatStatusSymbol(status) {
|
|
26637
27254
|
const colorFn = STATUS_COLORS[status];
|
|
26638
27255
|
switch (status) {
|
|
@@ -26647,23 +27264,23 @@ function formatStatusSymbol(status) {
|
|
|
26647
27264
|
}
|
|
26648
27265
|
}
|
|
26649
27266
|
function formatStatusMark(available) {
|
|
26650
|
-
return available ?
|
|
27267
|
+
return available ? import_picocolors18.default.green(SYMBOLS3.check) : import_picocolors18.default.red(SYMBOLS3.cross);
|
|
26651
27268
|
}
|
|
26652
27269
|
function formatHeader() {
|
|
26653
27270
|
return `
|
|
26654
|
-
${
|
|
27271
|
+
${import_picocolors18.default.bgMagenta(import_picocolors18.default.white(" oMoMoMoMo Doctor "))}
|
|
26655
27272
|
`;
|
|
26656
27273
|
}
|
|
26657
27274
|
function formatIssue(issue2, index) {
|
|
26658
27275
|
const lines = [];
|
|
26659
|
-
const severityColor = issue2.severity === "error" ?
|
|
27276
|
+
const severityColor = issue2.severity === "error" ? import_picocolors18.default.red : import_picocolors18.default.yellow;
|
|
26660
27277
|
lines.push(`${index}. ${severityColor(issue2.title)}`);
|
|
26661
|
-
lines.push(` ${
|
|
27278
|
+
lines.push(` ${import_picocolors18.default.dim(issue2.description)}`);
|
|
26662
27279
|
if (issue2.fix) {
|
|
26663
|
-
lines.push(` ${
|
|
27280
|
+
lines.push(` ${import_picocolors18.default.cyan("Fix:")} ${import_picocolors18.default.dim(issue2.fix)}`);
|
|
26664
27281
|
}
|
|
26665
27282
|
if (issue2.affects && issue2.affects.length > 0) {
|
|
26666
|
-
lines.push(` ${
|
|
27283
|
+
lines.push(` ${import_picocolors18.default.cyan("Affects:")} ${import_picocolors18.default.dim(issue2.affects.join(", "))}`);
|
|
26667
27284
|
}
|
|
26668
27285
|
return lines.join(`
|
|
26669
27286
|
`);
|
|
@@ -26677,12 +27294,12 @@ function formatDefault(result) {
|
|
|
26677
27294
|
if (allIssues.length === 0) {
|
|
26678
27295
|
const opencodeVer = result.systemInfo.opencodeVersion ?? "unknown";
|
|
26679
27296
|
const pluginVer = result.systemInfo.pluginVersion ?? "unknown";
|
|
26680
|
-
lines.push(` ${
|
|
27297
|
+
lines.push(` ${import_picocolors19.default.green(SYMBOLS3.check)} ${import_picocolors19.default.green(`System OK (opencode ${opencodeVer} \xB7 oh-my-opencode ${pluginVer})`)}`);
|
|
26681
27298
|
} else {
|
|
26682
27299
|
const issueCount = allIssues.filter((i2) => i2.severity === "error").length;
|
|
26683
27300
|
const warnCount = allIssues.filter((i2) => i2.severity === "warning").length;
|
|
26684
27301
|
const totalStr = `${issueCount + warnCount} ${issueCount + warnCount === 1 ? "issue" : "issues"}`;
|
|
26685
|
-
lines.push(` ${
|
|
27302
|
+
lines.push(` ${import_picocolors19.default.yellow(SYMBOLS3.warn)} ${totalStr} found:
|
|
26686
27303
|
`);
|
|
26687
27304
|
allIssues.forEach((issue2, index) => {
|
|
26688
27305
|
lines.push(formatIssue(issue2, index + 1));
|
|
@@ -26694,7 +27311,7 @@ function formatDefault(result) {
|
|
|
26694
27311
|
}
|
|
26695
27312
|
|
|
26696
27313
|
// src/cli/doctor/format-status.ts
|
|
26697
|
-
var
|
|
27314
|
+
var import_picocolors20 = __toESM(require_picocolors(), 1);
|
|
26698
27315
|
function formatStatus(result) {
|
|
26699
27316
|
const lines = [];
|
|
26700
27317
|
lines.push(formatHeader());
|
|
@@ -26705,7 +27322,7 @@ function formatStatus(result) {
|
|
|
26705
27322
|
const bunVer = systemInfo.bunVersion ?? "unknown";
|
|
26706
27323
|
lines.push(` ${padding}System ${opencodeVer} \xB7 ${pluginVer} \xB7 Bun ${bunVer}`);
|
|
26707
27324
|
const configPath = systemInfo.configPath ?? "unknown";
|
|
26708
|
-
const configStatus = systemInfo.configValid ?
|
|
27325
|
+
const configStatus = systemInfo.configValid ? import_picocolors20.default.green("(valid)") : import_picocolors20.default.red("(invalid)");
|
|
26709
27326
|
lines.push(` ${padding}Config ${configPath} ${configStatus}`);
|
|
26710
27327
|
const lspText = `LSP ${tools.lspInstalled}/${tools.lspTotal}`;
|
|
26711
27328
|
const astGrepMark = formatStatusMark(tools.astGrepCli);
|
|
@@ -26722,13 +27339,13 @@ function formatStatus(result) {
|
|
|
26722
27339
|
}
|
|
26723
27340
|
|
|
26724
27341
|
// src/cli/doctor/format-verbose.ts
|
|
26725
|
-
var
|
|
27342
|
+
var import_picocolors21 = __toESM(require_picocolors(), 1);
|
|
26726
27343
|
function formatVerbose(result) {
|
|
26727
27344
|
const lines = [];
|
|
26728
27345
|
lines.push(formatHeader());
|
|
26729
27346
|
const { systemInfo, tools, results, summary } = result;
|
|
26730
|
-
lines.push(`${
|
|
26731
|
-
lines.push(`${
|
|
27347
|
+
lines.push(`${import_picocolors21.default.bold("System Information")}`);
|
|
27348
|
+
lines.push(`${import_picocolors21.default.dim("\u2500".repeat(40))}`);
|
|
26732
27349
|
lines.push(` ${formatStatusSymbol("pass")} opencode ${systemInfo.opencodeVersion ?? "unknown"}`);
|
|
26733
27350
|
lines.push(` ${formatStatusSymbol("pass")} oh-my-opencode ${systemInfo.pluginVersion ?? "unknown"}`);
|
|
26734
27351
|
if (systemInfo.loadedVersion) {
|
|
@@ -26739,33 +27356,33 @@ function formatVerbose(result) {
|
|
|
26739
27356
|
}
|
|
26740
27357
|
lines.push(` ${formatStatusSymbol("pass")} path ${systemInfo.opencodePath ?? "unknown"}`);
|
|
26741
27358
|
if (systemInfo.isLocalDev) {
|
|
26742
|
-
lines.push(` ${
|
|
27359
|
+
lines.push(` ${import_picocolors21.default.yellow("*")} ${import_picocolors21.default.dim("(local development mode)")}`);
|
|
26743
27360
|
}
|
|
26744
27361
|
lines.push("");
|
|
26745
|
-
lines.push(`${
|
|
26746
|
-
lines.push(`${
|
|
26747
|
-
const configStatus = systemInfo.configValid ?
|
|
27362
|
+
lines.push(`${import_picocolors21.default.bold("Configuration")}`);
|
|
27363
|
+
lines.push(`${import_picocolors21.default.dim("\u2500".repeat(40))}`);
|
|
27364
|
+
const configStatus = systemInfo.configValid ? import_picocolors21.default.green("valid") : import_picocolors21.default.red("invalid");
|
|
26748
27365
|
lines.push(` ${formatStatusSymbol(systemInfo.configValid ? "pass" : "fail")} ${systemInfo.configPath ?? "unknown"} (${configStatus})`);
|
|
26749
27366
|
lines.push("");
|
|
26750
|
-
lines.push(`${
|
|
26751
|
-
lines.push(`${
|
|
27367
|
+
lines.push(`${import_picocolors21.default.bold("Tools")}`);
|
|
27368
|
+
lines.push(`${import_picocolors21.default.dim("\u2500".repeat(40))}`);
|
|
26752
27369
|
lines.push(` ${formatStatusSymbol("pass")} LSP ${tools.lspInstalled}/${tools.lspTotal} installed`);
|
|
26753
27370
|
lines.push(` ${formatStatusSymbol(tools.astGrepCli ? "pass" : "fail")} ast-grep CLI ${tools.astGrepCli ? "installed" : "not found"}`);
|
|
26754
27371
|
lines.push(` ${formatStatusSymbol(tools.astGrepNapi ? "pass" : "fail")} ast-grep napi ${tools.astGrepNapi ? "installed" : "not found"}`);
|
|
26755
27372
|
lines.push(` ${formatStatusSymbol(tools.commentChecker ? "pass" : "fail")} comment-checker ${tools.commentChecker ? "installed" : "not found"}`);
|
|
26756
27373
|
lines.push(` ${formatStatusSymbol(tools.ghCli.installed && tools.ghCli.authenticated ? "pass" : "fail")} gh CLI ${tools.ghCli.installed ? "installed" : "not found"}${tools.ghCli.authenticated && tools.ghCli.username ? ` (${tools.ghCli.username})` : ""}`);
|
|
26757
27374
|
lines.push("");
|
|
26758
|
-
lines.push(`${
|
|
26759
|
-
lines.push(`${
|
|
27375
|
+
lines.push(`${import_picocolors21.default.bold("MCPs")}`);
|
|
27376
|
+
lines.push(`${import_picocolors21.default.dim("\u2500".repeat(40))}`);
|
|
26760
27377
|
if (tools.mcpBuiltin.length === 0) {
|
|
26761
|
-
lines.push(` ${
|
|
27378
|
+
lines.push(` ${import_picocolors21.default.dim("No built-in MCPs")}`);
|
|
26762
27379
|
} else {
|
|
26763
27380
|
for (const mcp of tools.mcpBuiltin) {
|
|
26764
27381
|
lines.push(` ${formatStatusSymbol("pass")} ${mcp}`);
|
|
26765
27382
|
}
|
|
26766
27383
|
}
|
|
26767
27384
|
if (tools.mcpUser.length > 0) {
|
|
26768
|
-
lines.push(` ${
|
|
27385
|
+
lines.push(` ${import_picocolors21.default.cyan("+")} ${tools.mcpUser.length} user MCP(s):`);
|
|
26769
27386
|
for (const mcp of tools.mcpUser) {
|
|
26770
27387
|
lines.push(` ${formatStatusSymbol("pass")} ${mcp}`);
|
|
26771
27388
|
}
|
|
@@ -26773,20 +27390,20 @@ function formatVerbose(result) {
|
|
|
26773
27390
|
lines.push("");
|
|
26774
27391
|
const allIssues = results.flatMap((r2) => r2.issues);
|
|
26775
27392
|
if (allIssues.length > 0) {
|
|
26776
|
-
lines.push(`${
|
|
26777
|
-
lines.push(`${
|
|
27393
|
+
lines.push(`${import_picocolors21.default.bold("Issues")}`);
|
|
27394
|
+
lines.push(`${import_picocolors21.default.dim("\u2500".repeat(40))}`);
|
|
26778
27395
|
allIssues.forEach((issue2, index) => {
|
|
26779
27396
|
lines.push(formatIssue(issue2, index + 1));
|
|
26780
27397
|
lines.push("");
|
|
26781
27398
|
});
|
|
26782
27399
|
}
|
|
26783
|
-
lines.push(`${
|
|
26784
|
-
lines.push(`${
|
|
26785
|
-
const passText = summary.passed > 0 ?
|
|
26786
|
-
const failText = summary.failed > 0 ?
|
|
26787
|
-
const warnText = summary.warnings > 0 ?
|
|
27400
|
+
lines.push(`${import_picocolors21.default.bold("Summary")}`);
|
|
27401
|
+
lines.push(`${import_picocolors21.default.dim("\u2500".repeat(40))}`);
|
|
27402
|
+
const passText = summary.passed > 0 ? import_picocolors21.default.green(`${summary.passed} passed`) : `${summary.passed} passed`;
|
|
27403
|
+
const failText = summary.failed > 0 ? import_picocolors21.default.red(`${summary.failed} failed`) : `${summary.failed} failed`;
|
|
27404
|
+
const warnText = summary.warnings > 0 ? import_picocolors21.default.yellow(`${summary.warnings} warnings`) : `${summary.warnings} warnings`;
|
|
26788
27405
|
lines.push(` ${passText}, ${failText}, ${warnText}`);
|
|
26789
|
-
lines.push(` ${
|
|
27406
|
+
lines.push(` ${import_picocolors21.default.dim(`Total: ${summary.total} checks in ${summary.duration}ms`)}`);
|
|
26790
27407
|
return lines.join(`
|
|
26791
27408
|
`);
|
|
26792
27409
|
}
|
|
@@ -26870,11 +27487,11 @@ async function doctor(options = { mode: "default" }) {
|
|
|
26870
27487
|
|
|
26871
27488
|
// src/features/mcp-oauth/storage.ts
|
|
26872
27489
|
init_shared();
|
|
26873
|
-
import { chmodSync, existsSync as
|
|
26874
|
-
import { dirname as
|
|
27490
|
+
import { chmodSync, existsSync as existsSync27, mkdirSync as mkdirSync6, readFileSync as readFileSync28, unlinkSync as unlinkSync2, writeFileSync as writeFileSync12 } from "fs";
|
|
27491
|
+
import { dirname as dirname8, join as join25 } from "path";
|
|
26875
27492
|
var STORAGE_FILE_NAME = "mcp-oauth.json";
|
|
26876
27493
|
function getMcpOauthStoragePath() {
|
|
26877
|
-
return
|
|
27494
|
+
return join25(getOpenCodeConfigDir({ binary: "opencode" }), STORAGE_FILE_NAME);
|
|
26878
27495
|
}
|
|
26879
27496
|
function normalizeHost(serverHost) {
|
|
26880
27497
|
let host = serverHost.trim();
|
|
@@ -26911,11 +27528,11 @@ function buildKey(serverHost, resource) {
|
|
|
26911
27528
|
}
|
|
26912
27529
|
function readStore() {
|
|
26913
27530
|
const filePath = getMcpOauthStoragePath();
|
|
26914
|
-
if (!
|
|
27531
|
+
if (!existsSync27(filePath)) {
|
|
26915
27532
|
return null;
|
|
26916
27533
|
}
|
|
26917
27534
|
try {
|
|
26918
|
-
const content =
|
|
27535
|
+
const content = readFileSync28(filePath, "utf-8");
|
|
26919
27536
|
return JSON.parse(content);
|
|
26920
27537
|
} catch {
|
|
26921
27538
|
return null;
|
|
@@ -26924,11 +27541,11 @@ function readStore() {
|
|
|
26924
27541
|
function writeStore(store) {
|
|
26925
27542
|
const filePath = getMcpOauthStoragePath();
|
|
26926
27543
|
try {
|
|
26927
|
-
const dir =
|
|
26928
|
-
if (!
|
|
26929
|
-
|
|
27544
|
+
const dir = dirname8(filePath);
|
|
27545
|
+
if (!existsSync27(dir)) {
|
|
27546
|
+
mkdirSync6(dir, { recursive: true });
|
|
26930
27547
|
}
|
|
26931
|
-
|
|
27548
|
+
writeFileSync12(filePath, JSON.stringify(store, null, 2), { encoding: "utf-8", mode: 384 });
|
|
26932
27549
|
chmodSync(filePath, 384);
|
|
26933
27550
|
return true;
|
|
26934
27551
|
} catch {
|
|
@@ -26960,8 +27577,8 @@ function deleteToken(serverHost, resource) {
|
|
|
26960
27577
|
if (Object.keys(store).length === 0) {
|
|
26961
27578
|
try {
|
|
26962
27579
|
const filePath = getMcpOauthStoragePath();
|
|
26963
|
-
if (
|
|
26964
|
-
|
|
27580
|
+
if (existsSync27(filePath)) {
|
|
27581
|
+
unlinkSync2(filePath);
|
|
26965
27582
|
}
|
|
26966
27583
|
return true;
|
|
26967
27584
|
} catch {
|
|
@@ -27132,30 +27749,11 @@ function isRecord2(value) {
|
|
|
27132
27749
|
}
|
|
27133
27750
|
|
|
27134
27751
|
// src/features/mcp-oauth/callback-server.ts
|
|
27752
|
+
init_port_utils();
|
|
27135
27753
|
var DEFAULT_PORT = 19877;
|
|
27136
|
-
var MAX_PORT_ATTEMPTS2 = 20;
|
|
27137
27754
|
var TIMEOUT_MS = 5 * 60 * 1000;
|
|
27138
|
-
async function isPortAvailable2(port) {
|
|
27139
|
-
try {
|
|
27140
|
-
const server2 = Bun.serve({
|
|
27141
|
-
port,
|
|
27142
|
-
hostname: "127.0.0.1",
|
|
27143
|
-
fetch: () => new Response
|
|
27144
|
-
});
|
|
27145
|
-
server2.stop(true);
|
|
27146
|
-
return true;
|
|
27147
|
-
} catch {
|
|
27148
|
-
return false;
|
|
27149
|
-
}
|
|
27150
|
-
}
|
|
27151
27755
|
async function findAvailablePort2(startPort = DEFAULT_PORT) {
|
|
27152
|
-
|
|
27153
|
-
const port = startPort + attempt;
|
|
27154
|
-
if (await isPortAvailable2(port)) {
|
|
27155
|
-
return port;
|
|
27156
|
-
}
|
|
27157
|
-
}
|
|
27158
|
-
throw new Error(`No available port found in range ${startPort}-${startPort + MAX_PORT_ATTEMPTS2 - 1}`);
|
|
27756
|
+
return findAvailablePort(startPort);
|
|
27159
27757
|
}
|
|
27160
27758
|
|
|
27161
27759
|
// src/features/mcp-oauth/oauth-authorization-flow.ts
|
|
@@ -27542,11 +28140,10 @@ Model Providers (Priority: Native > Copilot > OpenCode Zen > Z.ai > Kimi):
|
|
|
27542
28140
|
const exitCode = await install(args);
|
|
27543
28141
|
process.exit(exitCode);
|
|
27544
28142
|
});
|
|
27545
|
-
program2.command("run <message>").allowUnknownOption().passThroughOptions().description("Run opencode with todo/background task completion enforcement").option("-a, --agent <name>", "Agent to use (default: from CLI/env/config, fallback: Sisyphus)").option("-d, --directory <path>", "Working directory").option("-
|
|
28143
|
+
program2.command("run <message>").allowUnknownOption().passThroughOptions().description("Run opencode with todo/background task completion enforcement").option("-a, --agent <name>", "Agent to use (default: from CLI/env/config, fallback: Sisyphus)").option("-d, --directory <path>", "Working directory").option("-p, --port <port>", "Server port (attaches if port already in use)", parseInt).option("--attach <url>", "Attach to existing opencode server URL").option("--on-complete <command>", "Shell command to run after completion").option("--json", "Output structured JSON result to stdout").option("--verbose", "Show full event stream (default: messages/tools only)").option("--session-id <id>", "Resume existing session instead of creating new one").addHelpText("after", `
|
|
27546
28144
|
Examples:
|
|
27547
28145
|
$ bunx oh-my-opencode run "Fix the bug in index.ts"
|
|
27548
28146
|
$ bunx oh-my-opencode run --agent Sisyphus "Implement feature X"
|
|
27549
|
-
$ bunx oh-my-opencode run --timeout 3600000 "Large refactoring task"
|
|
27550
28147
|
$ bunx oh-my-opencode run --port 4321 "Fix the bug"
|
|
27551
28148
|
$ bunx oh-my-opencode run --attach http://127.0.0.1:4321 "Fix the bug"
|
|
27552
28149
|
$ bunx oh-my-opencode run --json "Fix the bug" | jq .sessionId
|
|
@@ -27574,11 +28171,11 @@ Unlike 'opencode run', this command waits until:
|
|
|
27574
28171
|
message,
|
|
27575
28172
|
agent: options.agent,
|
|
27576
28173
|
directory: options.directory,
|
|
27577
|
-
timeout: options.timeout,
|
|
27578
28174
|
port: options.port,
|
|
27579
28175
|
attach: options.attach,
|
|
27580
28176
|
onComplete: options.onComplete,
|
|
27581
28177
|
json: options.json ?? false,
|
|
28178
|
+
verbose: options.verbose ?? false,
|
|
27582
28179
|
sessionId: options.sessionId
|
|
27583
28180
|
};
|
|
27584
28181
|
const exitCode = await run(runOptions);
|