oh-my-opencode 3.7.1 → 3.7.2
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 +884 -317
- 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.2",
|
|
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.2",
|
|
9131
|
+
"oh-my-opencode-darwin-x64": "3.7.2",
|
|
9132
|
+
"oh-my-opencode-linux-arm64": "3.7.2",
|
|
9133
|
+
"oh-my-opencode-linux-arm64-musl": "3.7.2",
|
|
9134
|
+
"oh-my-opencode-linux-x64": "3.7.2",
|
|
9135
|
+
"oh-my-opencode-linux-x64-musl": "3.7.2",
|
|
9136
|
+
"oh-my-opencode-windows-x64": "3.7.2"
|
|
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";
|
|
@@ -24835,7 +25217,7 @@ async function createServerConnection(options) {
|
|
|
24835
25217
|
prependResolvedOpencodeBinToPath();
|
|
24836
25218
|
const { port, attach, signal } = options;
|
|
24837
25219
|
if (attach !== undefined) {
|
|
24838
|
-
console.log(
|
|
25220
|
+
console.log(import_picocolors9.default.dim("Attaching to existing server at"), import_picocolors9.default.cyan(attach));
|
|
24839
25221
|
const client4 = createOpencodeClient({ baseUrl: attach });
|
|
24840
25222
|
return { client: client4, cleanup: () => {} };
|
|
24841
25223
|
}
|
|
@@ -24845,28 +25227,28 @@ async function createServerConnection(options) {
|
|
|
24845
25227
|
}
|
|
24846
25228
|
const available = await isPortAvailable(port, "127.0.0.1");
|
|
24847
25229
|
if (available) {
|
|
24848
|
-
console.log(
|
|
25230
|
+
console.log(import_picocolors9.default.dim("Starting server on port"), import_picocolors9.default.cyan(port.toString()));
|
|
24849
25231
|
const { client: client5, server: server3 } = await withWorkingOpencodePath(() => createOpencode({ signal, port, hostname: "127.0.0.1" }));
|
|
24850
|
-
console.log(
|
|
25232
|
+
console.log(import_picocolors9.default.dim("Server listening at"), import_picocolors9.default.cyan(server3.url));
|
|
24851
25233
|
return { client: client5, cleanup: () => server3.close() };
|
|
24852
25234
|
}
|
|
24853
|
-
console.log(
|
|
25235
|
+
console.log(import_picocolors9.default.dim("Port"), import_picocolors9.default.cyan(port.toString()), import_picocolors9.default.dim("is occupied, attaching to existing server"));
|
|
24854
25236
|
const client4 = createOpencodeClient({ baseUrl: `http://127.0.0.1:${port}` });
|
|
24855
25237
|
return { client: client4, cleanup: () => {} };
|
|
24856
25238
|
}
|
|
24857
25239
|
const { port: selectedPort, wasAutoSelected } = await getAvailableServerPort(DEFAULT_SERVER_PORT, "127.0.0.1");
|
|
24858
25240
|
if (wasAutoSelected) {
|
|
24859
|
-
console.log(
|
|
25241
|
+
console.log(import_picocolors9.default.dim("Auto-selected port"), import_picocolors9.default.cyan(selectedPort.toString()));
|
|
24860
25242
|
} else {
|
|
24861
|
-
console.log(
|
|
25243
|
+
console.log(import_picocolors9.default.dim("Starting server on port"), import_picocolors9.default.cyan(selectedPort.toString()));
|
|
24862
25244
|
}
|
|
24863
25245
|
const { client: client3, server: server2 } = await withWorkingOpencodePath(() => createOpencode({ signal, port: selectedPort, hostname: "127.0.0.1" }));
|
|
24864
|
-
console.log(
|
|
25246
|
+
console.log(import_picocolors9.default.dim("Server listening at"), import_picocolors9.default.cyan(server2.url));
|
|
24865
25247
|
return { client: client3, cleanup: () => server2.close() };
|
|
24866
25248
|
}
|
|
24867
25249
|
|
|
24868
25250
|
// src/cli/run/session-resolver.ts
|
|
24869
|
-
var
|
|
25251
|
+
var import_picocolors10 = __toESM(require_picocolors(), 1);
|
|
24870
25252
|
var SESSION_CREATE_MAX_RETRIES = 3;
|
|
24871
25253
|
var SESSION_CREATE_RETRY_DELAY_MS = 1000;
|
|
24872
25254
|
async function resolveSession(options) {
|
|
@@ -24892,11 +25274,11 @@ async function resolveSession(options) {
|
|
|
24892
25274
|
query: { directory }
|
|
24893
25275
|
});
|
|
24894
25276
|
if (res.error) {
|
|
24895
|
-
console.error(
|
|
24896
|
-
console.error(
|
|
25277
|
+
console.error(import_picocolors10.default.yellow(`Session create attempt ${attempt}/${SESSION_CREATE_MAX_RETRIES} failed:`));
|
|
25278
|
+
console.error(import_picocolors10.default.dim(` Error: ${serializeError(res.error)}`));
|
|
24897
25279
|
if (attempt < SESSION_CREATE_MAX_RETRIES) {
|
|
24898
25280
|
const delay = SESSION_CREATE_RETRY_DELAY_MS * attempt;
|
|
24899
|
-
console.log(
|
|
25281
|
+
console.log(import_picocolors10.default.dim(` Retrying in ${delay}ms...`));
|
|
24900
25282
|
await new Promise((resolve2) => setTimeout(resolve2, delay));
|
|
24901
25283
|
}
|
|
24902
25284
|
continue;
|
|
@@ -24904,10 +25286,10 @@ async function resolveSession(options) {
|
|
|
24904
25286
|
if (res.data?.id) {
|
|
24905
25287
|
return res.data.id;
|
|
24906
25288
|
}
|
|
24907
|
-
console.error(
|
|
25289
|
+
console.error(import_picocolors10.default.yellow(`Session create attempt ${attempt}/${SESSION_CREATE_MAX_RETRIES}: No session ID returned`));
|
|
24908
25290
|
if (attempt < SESSION_CREATE_MAX_RETRIES) {
|
|
24909
25291
|
const delay = SESSION_CREATE_RETRY_DELAY_MS * attempt;
|
|
24910
|
-
console.log(
|
|
25292
|
+
console.log(import_picocolors10.default.dim(` Retrying in ${delay}ms...`));
|
|
24911
25293
|
await new Promise((resolve2) => setTimeout(resolve2, delay));
|
|
24912
25294
|
}
|
|
24913
25295
|
}
|
|
@@ -24946,14 +25328,14 @@ function createJsonOutputManager(options = {}) {
|
|
|
24946
25328
|
}
|
|
24947
25329
|
|
|
24948
25330
|
// src/cli/run/on-complete-hook.ts
|
|
24949
|
-
var
|
|
25331
|
+
var import_picocolors11 = __toESM(require_picocolors(), 1);
|
|
24950
25332
|
async function executeOnCompleteHook(options) {
|
|
24951
25333
|
const { command, sessionId, exitCode, durationMs, messageCount } = options;
|
|
24952
25334
|
const trimmedCommand = command.trim();
|
|
24953
25335
|
if (!trimmedCommand) {
|
|
24954
25336
|
return;
|
|
24955
25337
|
}
|
|
24956
|
-
console.error(
|
|
25338
|
+
console.error(import_picocolors11.default.dim(`Running on-complete hook: ${trimmedCommand}`));
|
|
24957
25339
|
try {
|
|
24958
25340
|
const proc = Bun.spawn(["sh", "-c", trimmedCommand], {
|
|
24959
25341
|
env: {
|
|
@@ -24968,16 +25350,16 @@ async function executeOnCompleteHook(options) {
|
|
|
24968
25350
|
});
|
|
24969
25351
|
const hookExitCode = await proc.exited;
|
|
24970
25352
|
if (hookExitCode !== 0) {
|
|
24971
|
-
console.error(
|
|
25353
|
+
console.error(import_picocolors11.default.yellow(`Warning: on-complete hook exited with code ${hookExitCode}`));
|
|
24972
25354
|
}
|
|
24973
25355
|
} catch (error45) {
|
|
24974
|
-
console.error(
|
|
25356
|
+
console.error(import_picocolors11.default.yellow(`Warning: Failed to execute on-complete hook: ${error45 instanceof Error ? error45.message : String(error45)}`));
|
|
24975
25357
|
}
|
|
24976
25358
|
}
|
|
24977
25359
|
|
|
24978
25360
|
// src/cli/run/agent-resolver.ts
|
|
24979
25361
|
init_agent_display_names();
|
|
24980
|
-
var
|
|
25362
|
+
var import_picocolors12 = __toESM(require_picocolors(), 1);
|
|
24981
25363
|
var CORE_AGENT_ORDER = ["sisyphus", "hephaestus", "prometheus", "atlas"];
|
|
24982
25364
|
var DEFAULT_AGENT = "sisyphus";
|
|
24983
25365
|
var normalizeAgentName = (agent) => {
|
|
@@ -25022,35 +25404,224 @@ var resolveRunAgent = (options, pluginConfig, env = process.env) => {
|
|
|
25022
25404
|
const fallbackName = getAgentDisplayName(fallback);
|
|
25023
25405
|
const fallbackDisabled = isAgentDisabled(fallback, pluginConfig);
|
|
25024
25406
|
if (fallbackDisabled) {
|
|
25025
|
-
console.log(
|
|
25407
|
+
console.log(import_picocolors12.default.yellow(`Requested agent "${resolved.resolvedName}" is disabled and no enabled core agent was found. Proceeding with "${fallbackName}".`));
|
|
25026
25408
|
return fallbackName;
|
|
25027
25409
|
}
|
|
25028
|
-
console.log(
|
|
25410
|
+
console.log(import_picocolors12.default.yellow(`Requested agent "${resolved.resolvedName}" is disabled. Falling back to "${fallbackName}".`));
|
|
25029
25411
|
return fallbackName;
|
|
25030
25412
|
}
|
|
25031
25413
|
return resolved.resolvedName;
|
|
25032
25414
|
};
|
|
25033
25415
|
|
|
25034
25416
|
// src/cli/run/poll-for-completion.ts
|
|
25035
|
-
var
|
|
25417
|
+
var import_picocolors14 = __toESM(require_picocolors(), 1);
|
|
25036
25418
|
|
|
25037
25419
|
// src/cli/run/completion.ts
|
|
25038
25420
|
init_shared();
|
|
25039
|
-
var
|
|
25421
|
+
var import_picocolors13 = __toESM(require_picocolors(), 1);
|
|
25422
|
+
// src/features/boulder-state/constants.ts
|
|
25423
|
+
var BOULDER_DIR = ".sisyphus";
|
|
25424
|
+
var BOULDER_FILE = "boulder.json";
|
|
25425
|
+
var BOULDER_STATE_PATH = `${BOULDER_DIR}/${BOULDER_FILE}`;
|
|
25426
|
+
var NOTEPAD_DIR = "notepads";
|
|
25427
|
+
var NOTEPAD_BASE_PATH = `${BOULDER_DIR}/${NOTEPAD_DIR}`;
|
|
25428
|
+
// src/features/boulder-state/storage.ts
|
|
25429
|
+
import { existsSync as existsSync11, readFileSync as readFileSync11, writeFileSync as writeFileSync7, mkdirSync as mkdirSync3, readdirSync } from "fs";
|
|
25430
|
+
import { dirname as dirname3, join as join9, basename } from "path";
|
|
25431
|
+
function getBoulderFilePath(directory) {
|
|
25432
|
+
return join9(directory, BOULDER_DIR, BOULDER_FILE);
|
|
25433
|
+
}
|
|
25434
|
+
function readBoulderState(directory) {
|
|
25435
|
+
const filePath = getBoulderFilePath(directory);
|
|
25436
|
+
if (!existsSync11(filePath)) {
|
|
25437
|
+
return null;
|
|
25438
|
+
}
|
|
25439
|
+
try {
|
|
25440
|
+
const content = readFileSync11(filePath, "utf-8");
|
|
25441
|
+
const parsed = JSON.parse(content);
|
|
25442
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
25443
|
+
return null;
|
|
25444
|
+
}
|
|
25445
|
+
if (!Array.isArray(parsed.session_ids)) {
|
|
25446
|
+
parsed.session_ids = [];
|
|
25447
|
+
}
|
|
25448
|
+
return parsed;
|
|
25449
|
+
} catch {
|
|
25450
|
+
return null;
|
|
25451
|
+
}
|
|
25452
|
+
}
|
|
25453
|
+
function getPlanProgress(planPath) {
|
|
25454
|
+
if (!existsSync11(planPath)) {
|
|
25455
|
+
return { total: 0, completed: 0, isComplete: true };
|
|
25456
|
+
}
|
|
25457
|
+
try {
|
|
25458
|
+
const content = readFileSync11(planPath, "utf-8");
|
|
25459
|
+
const uncheckedMatches = content.match(/^[-*]\s*\[\s*\]/gm) || [];
|
|
25460
|
+
const checkedMatches = content.match(/^[-*]\s*\[[xX]\]/gm) || [];
|
|
25461
|
+
const total = uncheckedMatches.length + checkedMatches.length;
|
|
25462
|
+
const completed = checkedMatches.length;
|
|
25463
|
+
return {
|
|
25464
|
+
total,
|
|
25465
|
+
completed,
|
|
25466
|
+
isComplete: total === 0 || completed === total
|
|
25467
|
+
};
|
|
25468
|
+
} catch {
|
|
25469
|
+
return { total: 0, completed: 0, isComplete: true };
|
|
25470
|
+
}
|
|
25471
|
+
}
|
|
25472
|
+
// src/features/run-continuation-state/constants.ts
|
|
25473
|
+
var CONTINUATION_MARKER_DIR = ".sisyphus/run-continuation";
|
|
25474
|
+
// src/features/run-continuation-state/storage.ts
|
|
25475
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync4, readFileSync as readFileSync12, rmSync, writeFileSync as writeFileSync8 } from "fs";
|
|
25476
|
+
import { join as join10 } from "path";
|
|
25477
|
+
function getMarkerPath(directory, sessionID) {
|
|
25478
|
+
return join10(directory, CONTINUATION_MARKER_DIR, `${sessionID}.json`);
|
|
25479
|
+
}
|
|
25480
|
+
function readContinuationMarker(directory, sessionID) {
|
|
25481
|
+
const markerPath = getMarkerPath(directory, sessionID);
|
|
25482
|
+
if (!existsSync12(markerPath))
|
|
25483
|
+
return null;
|
|
25484
|
+
try {
|
|
25485
|
+
const raw = readFileSync12(markerPath, "utf-8");
|
|
25486
|
+
const parsed = JSON.parse(raw);
|
|
25487
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
25488
|
+
return null;
|
|
25489
|
+
return parsed;
|
|
25490
|
+
} catch {
|
|
25491
|
+
return null;
|
|
25492
|
+
}
|
|
25493
|
+
}
|
|
25494
|
+
function isContinuationMarkerActive(marker) {
|
|
25495
|
+
if (!marker)
|
|
25496
|
+
return false;
|
|
25497
|
+
return Object.values(marker.sources).some((entry) => entry?.state === "active");
|
|
25498
|
+
}
|
|
25499
|
+
function getActiveContinuationMarkerReason(marker) {
|
|
25500
|
+
if (!marker)
|
|
25501
|
+
return null;
|
|
25502
|
+
const active = Object.entries(marker.sources).find(([, entry2]) => entry2?.state === "active");
|
|
25503
|
+
if (!active || !active[1])
|
|
25504
|
+
return null;
|
|
25505
|
+
const [source, entry] = active;
|
|
25506
|
+
return entry.reason ?? `${source} continuation is active`;
|
|
25507
|
+
}
|
|
25508
|
+
// src/hooks/ralph-loop/storage.ts
|
|
25509
|
+
init_frontmatter();
|
|
25510
|
+
import { existsSync as existsSync13, readFileSync as readFileSync13, writeFileSync as writeFileSync9, unlinkSync, mkdirSync as mkdirSync5 } from "fs";
|
|
25511
|
+
import { dirname as dirname4, join as join11 } from "path";
|
|
25512
|
+
|
|
25513
|
+
// src/hooks/ralph-loop/constants.ts
|
|
25514
|
+
var DEFAULT_STATE_FILE = ".sisyphus/ralph-loop.local.md";
|
|
25515
|
+
var DEFAULT_MAX_ITERATIONS = 100;
|
|
25516
|
+
var DEFAULT_COMPLETION_PROMISE = "DONE";
|
|
25517
|
+
|
|
25518
|
+
// src/hooks/ralph-loop/storage.ts
|
|
25519
|
+
function getStateFilePath(directory, customPath) {
|
|
25520
|
+
return customPath ? join11(directory, customPath) : join11(directory, DEFAULT_STATE_FILE);
|
|
25521
|
+
}
|
|
25522
|
+
function readState(directory, customPath) {
|
|
25523
|
+
const filePath = getStateFilePath(directory, customPath);
|
|
25524
|
+
if (!existsSync13(filePath)) {
|
|
25525
|
+
return null;
|
|
25526
|
+
}
|
|
25527
|
+
try {
|
|
25528
|
+
const content = readFileSync13(filePath, "utf-8");
|
|
25529
|
+
const { data, body } = parseFrontmatter(content);
|
|
25530
|
+
const active = data.active;
|
|
25531
|
+
const iteration = data.iteration;
|
|
25532
|
+
if (active === undefined || iteration === undefined) {
|
|
25533
|
+
return null;
|
|
25534
|
+
}
|
|
25535
|
+
const isActive = active === true || active === "true";
|
|
25536
|
+
const iterationNum = typeof iteration === "number" ? iteration : Number(iteration);
|
|
25537
|
+
if (isNaN(iterationNum)) {
|
|
25538
|
+
return null;
|
|
25539
|
+
}
|
|
25540
|
+
const stripQuotes = (val) => {
|
|
25541
|
+
const str3 = String(val ?? "");
|
|
25542
|
+
return str3.replace(/^["']|["']$/g, "");
|
|
25543
|
+
};
|
|
25544
|
+
return {
|
|
25545
|
+
active: isActive,
|
|
25546
|
+
iteration: iterationNum,
|
|
25547
|
+
max_iterations: Number(data.max_iterations) || DEFAULT_MAX_ITERATIONS,
|
|
25548
|
+
completion_promise: stripQuotes(data.completion_promise) || DEFAULT_COMPLETION_PROMISE,
|
|
25549
|
+
started_at: stripQuotes(data.started_at) || new Date().toISOString(),
|
|
25550
|
+
prompt: body.trim(),
|
|
25551
|
+
session_id: data.session_id ? stripQuotes(data.session_id) : undefined,
|
|
25552
|
+
ultrawork: data.ultrawork === true || data.ultrawork === "true" ? true : undefined
|
|
25553
|
+
};
|
|
25554
|
+
} catch {
|
|
25555
|
+
return null;
|
|
25556
|
+
}
|
|
25557
|
+
}
|
|
25558
|
+
|
|
25559
|
+
// src/cli/run/continuation-state.ts
|
|
25560
|
+
function getContinuationState(directory, sessionID) {
|
|
25561
|
+
const marker = readContinuationMarker(directory, sessionID);
|
|
25562
|
+
return {
|
|
25563
|
+
hasActiveBoulder: hasActiveBoulderContinuation(directory, sessionID),
|
|
25564
|
+
hasActiveRalphLoop: hasActiveRalphLoopContinuation(directory, sessionID),
|
|
25565
|
+
hasHookMarker: marker !== null,
|
|
25566
|
+
hasTodoHookMarker: marker?.sources.todo !== undefined,
|
|
25567
|
+
hasActiveHookMarker: isContinuationMarkerActive(marker),
|
|
25568
|
+
activeHookMarkerReason: getActiveContinuationMarkerReason(marker)
|
|
25569
|
+
};
|
|
25570
|
+
}
|
|
25571
|
+
function hasActiveBoulderContinuation(directory, sessionID) {
|
|
25572
|
+
const boulder = readBoulderState(directory);
|
|
25573
|
+
if (!boulder)
|
|
25574
|
+
return false;
|
|
25575
|
+
if (!boulder.session_ids.includes(sessionID))
|
|
25576
|
+
return false;
|
|
25577
|
+
const progress = getPlanProgress(boulder.active_plan);
|
|
25578
|
+
return !progress.isComplete;
|
|
25579
|
+
}
|
|
25580
|
+
function hasActiveRalphLoopContinuation(directory, sessionID) {
|
|
25581
|
+
const state = readState(directory);
|
|
25582
|
+
if (!state || !state.active)
|
|
25583
|
+
return false;
|
|
25584
|
+
if (state.session_id && state.session_id !== sessionID) {
|
|
25585
|
+
return false;
|
|
25586
|
+
}
|
|
25587
|
+
return true;
|
|
25588
|
+
}
|
|
25589
|
+
|
|
25590
|
+
// src/cli/run/completion.ts
|
|
25040
25591
|
async function checkCompletionConditions(ctx) {
|
|
25041
25592
|
try {
|
|
25042
|
-
|
|
25593
|
+
const continuationState = getContinuationState(ctx.directory, ctx.sessionID);
|
|
25594
|
+
if (continuationState.hasActiveHookMarker) {
|
|
25595
|
+
const reason = continuationState.activeHookMarkerReason ?? "continuation hook is active";
|
|
25596
|
+
console.log(import_picocolors13.default.dim(` Waiting: ${reason}`));
|
|
25597
|
+
return false;
|
|
25598
|
+
}
|
|
25599
|
+
if (!continuationState.hasTodoHookMarker && !await areAllTodosComplete(ctx)) {
|
|
25043
25600
|
return false;
|
|
25044
25601
|
}
|
|
25045
25602
|
if (!await areAllChildrenIdle(ctx)) {
|
|
25046
25603
|
return false;
|
|
25047
25604
|
}
|
|
25605
|
+
if (!areContinuationHooksIdle(continuationState)) {
|
|
25606
|
+
return false;
|
|
25607
|
+
}
|
|
25048
25608
|
return true;
|
|
25049
25609
|
} catch (err) {
|
|
25050
|
-
console.error(
|
|
25610
|
+
console.error(import_picocolors13.default.red(`[completion] API error: ${err}`));
|
|
25051
25611
|
return false;
|
|
25052
25612
|
}
|
|
25053
25613
|
}
|
|
25614
|
+
function areContinuationHooksIdle(continuationState) {
|
|
25615
|
+
if (continuationState.hasActiveBoulder) {
|
|
25616
|
+
console.log(import_picocolors13.default.dim(" Waiting: boulder continuation is active"));
|
|
25617
|
+
return false;
|
|
25618
|
+
}
|
|
25619
|
+
if (continuationState.hasActiveRalphLoop) {
|
|
25620
|
+
console.log(import_picocolors13.default.dim(" Waiting: ralph-loop continuation is active"));
|
|
25621
|
+
return false;
|
|
25622
|
+
}
|
|
25623
|
+
return true;
|
|
25624
|
+
}
|
|
25054
25625
|
async function areAllTodosComplete(ctx) {
|
|
25055
25626
|
const todosRes = await ctx.client.session.todo({
|
|
25056
25627
|
path: { id: ctx.sessionID },
|
|
@@ -25059,7 +25630,7 @@ async function areAllTodosComplete(ctx) {
|
|
|
25059
25630
|
const todos = normalizeSDKResponse(todosRes, []);
|
|
25060
25631
|
const incompleteTodos = todos.filter((t) => t.status !== "completed" && t.status !== "cancelled");
|
|
25061
25632
|
if (incompleteTodos.length > 0) {
|
|
25062
|
-
console.log(
|
|
25633
|
+
console.log(import_picocolors13.default.dim(` Waiting: ${incompleteTodos.length} todos remaining`));
|
|
25063
25634
|
return false;
|
|
25064
25635
|
}
|
|
25065
25636
|
return true;
|
|
@@ -25083,7 +25654,7 @@ async function areAllDescendantsIdle(ctx, sessionID, allStatuses) {
|
|
|
25083
25654
|
for (const child of children) {
|
|
25084
25655
|
const status = allStatuses[child.id];
|
|
25085
25656
|
if (status && status.type !== "idle") {
|
|
25086
|
-
console.log(
|
|
25657
|
+
console.log(import_picocolors13.default.dim(` Waiting: session ${child.id.slice(0, 8)}... is ${status.type}`));
|
|
25087
25658
|
return false;
|
|
25088
25659
|
}
|
|
25089
25660
|
const descendantsIdle = await areAllDescendantsIdle(ctx, child.id, allStatuses);
|
|
@@ -25097,9 +25668,9 @@ async function areAllDescendantsIdle(ctx, sessionID, allStatuses) {
|
|
|
25097
25668
|
// src/cli/run/poll-for-completion.ts
|
|
25098
25669
|
init_shared();
|
|
25099
25670
|
var DEFAULT_POLL_INTERVAL_MS = 500;
|
|
25100
|
-
var DEFAULT_REQUIRED_CONSECUTIVE =
|
|
25671
|
+
var DEFAULT_REQUIRED_CONSECUTIVE = 1;
|
|
25101
25672
|
var ERROR_GRACE_CYCLES = 3;
|
|
25102
|
-
var MIN_STABILIZATION_MS =
|
|
25673
|
+
var MIN_STABILIZATION_MS = 0;
|
|
25103
25674
|
async function pollForCompletion(ctx, eventState, abortController, options = {}) {
|
|
25104
25675
|
const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
25105
25676
|
const requiredConsecutive = options.requiredConsecutive ?? DEFAULT_REQUIRED_CONSECUTIVE;
|
|
@@ -25110,13 +25681,16 @@ async function pollForCompletion(ctx, eventState, abortController, options = {})
|
|
|
25110
25681
|
const pollStartTimestamp = Date.now();
|
|
25111
25682
|
while (!abortController.signal.aborted) {
|
|
25112
25683
|
await new Promise((resolve2) => setTimeout(resolve2, pollIntervalMs));
|
|
25684
|
+
if (abortController.signal.aborted) {
|
|
25685
|
+
return 130;
|
|
25686
|
+
}
|
|
25113
25687
|
if (eventState.mainSessionError) {
|
|
25114
25688
|
errorCycleCount++;
|
|
25115
25689
|
if (errorCycleCount >= ERROR_GRACE_CYCLES) {
|
|
25116
|
-
console.error(
|
|
25690
|
+
console.error(import_picocolors14.default.red(`
|
|
25117
25691
|
|
|
25118
25692
|
Session ended with error: ${eventState.lastError}`));
|
|
25119
|
-
console.error(
|
|
25693
|
+
console.error(import_picocolors14.default.yellow("Check if todos were completed before the error."));
|
|
25120
25694
|
return 1;
|
|
25121
25695
|
}
|
|
25122
25696
|
continue;
|
|
@@ -25138,6 +25712,10 @@ Session ended with error: ${eventState.lastError}`));
|
|
|
25138
25712
|
continue;
|
|
25139
25713
|
}
|
|
25140
25714
|
if (!eventState.hasReceivedMeaningfulWork) {
|
|
25715
|
+
if (minStabilizationMs <= 0) {
|
|
25716
|
+
consecutiveCompleteChecks = 0;
|
|
25717
|
+
continue;
|
|
25718
|
+
}
|
|
25141
25719
|
if (Date.now() - pollStartTimestamp < minStabilizationMs) {
|
|
25142
25720
|
consecutiveCompleteChecks = 0;
|
|
25143
25721
|
continue;
|
|
@@ -25153,9 +25731,12 @@ Session ended with error: ${eventState.lastError}`));
|
|
|
25153
25731
|
}
|
|
25154
25732
|
const shouldExit = await checkCompletionConditions(ctx);
|
|
25155
25733
|
if (shouldExit) {
|
|
25734
|
+
if (abortController.signal.aborted) {
|
|
25735
|
+
return 130;
|
|
25736
|
+
}
|
|
25156
25737
|
consecutiveCompleteChecks++;
|
|
25157
25738
|
if (consecutiveCompleteChecks >= requiredConsecutive) {
|
|
25158
|
-
console.log(
|
|
25739
|
+
console.log(import_picocolors14.default.green(`
|
|
25159
25740
|
|
|
25160
25741
|
All tasks completed.`));
|
|
25161
25742
|
return 0;
|
|
@@ -25182,25 +25763,40 @@ async function getMainSessionStatus(ctx) {
|
|
|
25182
25763
|
}
|
|
25183
25764
|
}
|
|
25184
25765
|
|
|
25766
|
+
// src/cli/run/agent-profile-colors.ts
|
|
25767
|
+
init_shared();
|
|
25768
|
+
async function loadAgentProfileColors(client3) {
|
|
25769
|
+
try {
|
|
25770
|
+
const agentsRes = await client3.app.agents();
|
|
25771
|
+
const agents = normalizeSDKResponse(agentsRes, [], {
|
|
25772
|
+
preferResponseOnMissingData: true
|
|
25773
|
+
});
|
|
25774
|
+
const colors = {};
|
|
25775
|
+
for (const agent of agents) {
|
|
25776
|
+
if (!agent.name || !agent.color)
|
|
25777
|
+
continue;
|
|
25778
|
+
colors[agent.name] = agent.color;
|
|
25779
|
+
}
|
|
25780
|
+
return colors;
|
|
25781
|
+
} catch {
|
|
25782
|
+
return {};
|
|
25783
|
+
}
|
|
25784
|
+
}
|
|
25785
|
+
|
|
25185
25786
|
// src/cli/run/runner.ts
|
|
25186
|
-
var DEFAULT_TIMEOUT_MS = 600000;
|
|
25187
25787
|
var EVENT_PROCESSOR_SHUTDOWN_TIMEOUT_MS = 2000;
|
|
25188
25788
|
async function waitForEventProcessorShutdown(eventProcessor, timeoutMs = EVENT_PROCESSOR_SHUTDOWN_TIMEOUT_MS) {
|
|
25189
25789
|
const completed = await Promise.race([
|
|
25190
25790
|
eventProcessor.then(() => true),
|
|
25191
25791
|
new Promise((resolve2) => setTimeout(() => resolve2(false), timeoutMs))
|
|
25192
25792
|
]);
|
|
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
25793
|
}
|
|
25197
25794
|
async function run(options) {
|
|
25198
25795
|
process.env.OPENCODE_CLI_RUN_MODE = "true";
|
|
25199
25796
|
const startTime = Date.now();
|
|
25200
25797
|
const {
|
|
25201
25798
|
message,
|
|
25202
|
-
directory = process.cwd()
|
|
25203
|
-
timeout = DEFAULT_TIMEOUT_MS
|
|
25799
|
+
directory = process.cwd()
|
|
25204
25800
|
} = options;
|
|
25205
25801
|
const jsonManager = options.json ? createJsonOutputManager() : null;
|
|
25206
25802
|
if (jsonManager)
|
|
@@ -25208,14 +25804,6 @@ async function run(options) {
|
|
|
25208
25804
|
const pluginConfig = loadPluginConfig(directory, { command: "run" });
|
|
25209
25805
|
const resolvedAgent = resolveRunAgent(options, pluginConfig);
|
|
25210
25806
|
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
25807
|
try {
|
|
25220
25808
|
const { client: client3, cleanup: serverCleanup } = await createServerConnection({
|
|
25221
25809
|
port: options.port,
|
|
@@ -25223,12 +25811,10 @@ Timeout reached. Aborting...`));
|
|
|
25223
25811
|
signal: abortController.signal
|
|
25224
25812
|
});
|
|
25225
25813
|
const cleanup = () => {
|
|
25226
|
-
if (timeoutId)
|
|
25227
|
-
clearTimeout(timeoutId);
|
|
25228
25814
|
serverCleanup();
|
|
25229
25815
|
};
|
|
25230
25816
|
process.on("SIGINT", () => {
|
|
25231
|
-
console.log(
|
|
25817
|
+
console.log(import_picocolors15.default.yellow(`
|
|
25232
25818
|
Interrupted. Shutting down...`));
|
|
25233
25819
|
cleanup();
|
|
25234
25820
|
process.exit(130);
|
|
@@ -25239,13 +25825,18 @@ Interrupted. Shutting down...`));
|
|
|
25239
25825
|
sessionId: options.sessionId,
|
|
25240
25826
|
directory
|
|
25241
25827
|
});
|
|
25242
|
-
console.log(
|
|
25243
|
-
const ctx = {
|
|
25828
|
+
console.log(import_picocolors15.default.dim(`Session: ${sessionID}`));
|
|
25829
|
+
const ctx = {
|
|
25830
|
+
client: client3,
|
|
25831
|
+
sessionID,
|
|
25832
|
+
directory,
|
|
25833
|
+
abortController,
|
|
25834
|
+
verbose: options.verbose ?? false
|
|
25835
|
+
};
|
|
25244
25836
|
const events = await client3.event.subscribe({ query: { directory } });
|
|
25245
25837
|
const eventState = createEventState();
|
|
25838
|
+
eventState.agentColorsByName = await loadAgentProfileColors(client3);
|
|
25246
25839
|
const eventProcessor = processEvents(ctx, events.stream, eventState).catch(() => {});
|
|
25247
|
-
console.log(import_picocolors14.default.dim(`
|
|
25248
|
-
Sending prompt...`));
|
|
25249
25840
|
await client3.session.promptAsync({
|
|
25250
25841
|
path: { id: sessionID },
|
|
25251
25842
|
body: {
|
|
@@ -25254,8 +25845,6 @@ Sending prompt...`));
|
|
|
25254
25845
|
},
|
|
25255
25846
|
query: { directory }
|
|
25256
25847
|
});
|
|
25257
|
-
console.log(import_picocolors14.default.dim(`Waiting for completion...
|
|
25258
|
-
`));
|
|
25259
25848
|
const exitCode = await pollForCompletion(ctx, eventState, abortController);
|
|
25260
25849
|
abortController.abort();
|
|
25261
25850
|
await waitForEventProcessorShutdown(eventProcessor);
|
|
@@ -25285,14 +25874,12 @@ Sending prompt...`));
|
|
|
25285
25874
|
throw err;
|
|
25286
25875
|
}
|
|
25287
25876
|
} catch (err) {
|
|
25288
|
-
if (timeoutId)
|
|
25289
|
-
clearTimeout(timeoutId);
|
|
25290
25877
|
if (jsonManager)
|
|
25291
25878
|
jsonManager.restore();
|
|
25292
25879
|
if (err instanceof Error && err.name === "AbortError") {
|
|
25293
25880
|
return 130;
|
|
25294
25881
|
}
|
|
25295
|
-
console.error(
|
|
25882
|
+
console.error(import_picocolors15.default.red(`Error: ${serializeError(err)}`));
|
|
25296
25883
|
return 1;
|
|
25297
25884
|
}
|
|
25298
25885
|
}
|
|
@@ -25300,53 +25887,53 @@ Sending prompt...`));
|
|
|
25300
25887
|
init_checker();
|
|
25301
25888
|
|
|
25302
25889
|
// src/cli/get-local-version/formatter.ts
|
|
25303
|
-
var
|
|
25890
|
+
var import_picocolors16 = __toESM(require_picocolors(), 1);
|
|
25304
25891
|
var SYMBOLS2 = {
|
|
25305
|
-
check:
|
|
25306
|
-
cross:
|
|
25307
|
-
arrow:
|
|
25308
|
-
info:
|
|
25309
|
-
warn:
|
|
25310
|
-
pin:
|
|
25311
|
-
dev:
|
|
25892
|
+
check: import_picocolors16.default.green("[OK]"),
|
|
25893
|
+
cross: import_picocolors16.default.red("[X]"),
|
|
25894
|
+
arrow: import_picocolors16.default.cyan("->"),
|
|
25895
|
+
info: import_picocolors16.default.blue("[i]"),
|
|
25896
|
+
warn: import_picocolors16.default.yellow("[!]"),
|
|
25897
|
+
pin: import_picocolors16.default.magenta("[PINNED]"),
|
|
25898
|
+
dev: import_picocolors16.default.cyan("[DEV]")
|
|
25312
25899
|
};
|
|
25313
25900
|
function formatVersionOutput(info) {
|
|
25314
25901
|
const lines = [];
|
|
25315
25902
|
lines.push("");
|
|
25316
|
-
lines.push(
|
|
25317
|
-
lines.push(
|
|
25903
|
+
lines.push(import_picocolors16.default.bold(import_picocolors16.default.white("oh-my-opencode Version Information")));
|
|
25904
|
+
lines.push(import_picocolors16.default.dim("\u2500".repeat(50)));
|
|
25318
25905
|
lines.push("");
|
|
25319
25906
|
if (info.currentVersion) {
|
|
25320
|
-
lines.push(` Current Version: ${
|
|
25907
|
+
lines.push(` Current Version: ${import_picocolors16.default.cyan(info.currentVersion)}`);
|
|
25321
25908
|
} else {
|
|
25322
|
-
lines.push(` Current Version: ${
|
|
25909
|
+
lines.push(` Current Version: ${import_picocolors16.default.dim("unknown")}`);
|
|
25323
25910
|
}
|
|
25324
25911
|
if (!info.isLocalDev && info.latestVersion) {
|
|
25325
|
-
lines.push(` Latest Version: ${
|
|
25912
|
+
lines.push(` Latest Version: ${import_picocolors16.default.cyan(info.latestVersion)}`);
|
|
25326
25913
|
}
|
|
25327
25914
|
lines.push("");
|
|
25328
25915
|
switch (info.status) {
|
|
25329
25916
|
case "up-to-date":
|
|
25330
|
-
lines.push(` ${SYMBOLS2.check} ${
|
|
25917
|
+
lines.push(` ${SYMBOLS2.check} ${import_picocolors16.default.green("You're up to date!")}`);
|
|
25331
25918
|
break;
|
|
25332
25919
|
case "outdated":
|
|
25333
|
-
lines.push(` ${SYMBOLS2.warn} ${
|
|
25334
|
-
lines.push(` ${
|
|
25920
|
+
lines.push(` ${SYMBOLS2.warn} ${import_picocolors16.default.yellow("Update available")}`);
|
|
25921
|
+
lines.push(` ${import_picocolors16.default.dim("Run:")} ${import_picocolors16.default.cyan("cd ~/.config/opencode && bun update oh-my-opencode")}`);
|
|
25335
25922
|
break;
|
|
25336
25923
|
case "local-dev":
|
|
25337
|
-
lines.push(` ${SYMBOLS2.dev} ${
|
|
25338
|
-
lines.push(` ${
|
|
25924
|
+
lines.push(` ${SYMBOLS2.dev} ${import_picocolors16.default.cyan("Running in local development mode")}`);
|
|
25925
|
+
lines.push(` ${import_picocolors16.default.dim("Using file:// protocol from config")}`);
|
|
25339
25926
|
break;
|
|
25340
25927
|
case "pinned":
|
|
25341
|
-
lines.push(` ${SYMBOLS2.pin} ${
|
|
25342
|
-
lines.push(` ${
|
|
25928
|
+
lines.push(` ${SYMBOLS2.pin} ${import_picocolors16.default.magenta(`Version pinned to ${info.pinnedVersion}`)}`);
|
|
25929
|
+
lines.push(` ${import_picocolors16.default.dim("Update check skipped for pinned versions")}`);
|
|
25343
25930
|
break;
|
|
25344
25931
|
case "error":
|
|
25345
|
-
lines.push(` ${SYMBOLS2.cross} ${
|
|
25346
|
-
lines.push(` ${
|
|
25932
|
+
lines.push(` ${SYMBOLS2.cross} ${import_picocolors16.default.red("Unable to check for updates")}`);
|
|
25933
|
+
lines.push(` ${import_picocolors16.default.dim("Network error or npm registry unavailable")}`);
|
|
25347
25934
|
break;
|
|
25348
25935
|
case "unknown":
|
|
25349
|
-
lines.push(` ${SYMBOLS2.info} ${
|
|
25936
|
+
lines.push(` ${SYMBOLS2.info} ${import_picocolors16.default.yellow("Version information unavailable")}`);
|
|
25350
25937
|
break;
|
|
25351
25938
|
}
|
|
25352
25939
|
lines.push("");
|
|
@@ -25446,21 +26033,21 @@ async function getLocalVersion(options = {}) {
|
|
|
25446
26033
|
}
|
|
25447
26034
|
}
|
|
25448
26035
|
// src/cli/doctor/constants.ts
|
|
25449
|
-
var
|
|
26036
|
+
var import_picocolors17 = __toESM(require_picocolors(), 1);
|
|
25450
26037
|
var SYMBOLS3 = {
|
|
25451
|
-
check:
|
|
25452
|
-
cross:
|
|
25453
|
-
warn:
|
|
25454
|
-
info:
|
|
25455
|
-
arrow:
|
|
25456
|
-
bullet:
|
|
25457
|
-
skip:
|
|
26038
|
+
check: import_picocolors17.default.green("\u2713"),
|
|
26039
|
+
cross: import_picocolors17.default.red("\u2717"),
|
|
26040
|
+
warn: import_picocolors17.default.yellow("\u26A0"),
|
|
26041
|
+
info: import_picocolors17.default.blue("\u2139"),
|
|
26042
|
+
arrow: import_picocolors17.default.cyan("\u2192"),
|
|
26043
|
+
bullet: import_picocolors17.default.dim("\u2022"),
|
|
26044
|
+
skip: import_picocolors17.default.dim("\u25CB")
|
|
25458
26045
|
};
|
|
25459
26046
|
var STATUS_COLORS = {
|
|
25460
|
-
pass:
|
|
25461
|
-
fail:
|
|
25462
|
-
warn:
|
|
25463
|
-
skip:
|
|
26047
|
+
pass: import_picocolors17.default.green,
|
|
26048
|
+
fail: import_picocolors17.default.red,
|
|
26049
|
+
warn: import_picocolors17.default.yellow,
|
|
26050
|
+
skip: import_picocolors17.default.dim
|
|
25464
26051
|
};
|
|
25465
26052
|
var CHECK_IDS = {
|
|
25466
26053
|
SYSTEM: "system",
|
|
@@ -25483,29 +26070,29 @@ var PACKAGE_NAME4 = "oh-my-opencode";
|
|
|
25483
26070
|
var OPENCODE_BINARIES2 = ["opencode", "opencode-desktop"];
|
|
25484
26071
|
|
|
25485
26072
|
// src/cli/doctor/checks/system.ts
|
|
25486
|
-
import { existsSync as
|
|
26073
|
+
import { existsSync as existsSync22, readFileSync as readFileSync23 } from "fs";
|
|
25487
26074
|
|
|
25488
26075
|
// src/cli/doctor/checks/system-binary.ts
|
|
25489
|
-
import { existsSync as
|
|
26076
|
+
import { existsSync as existsSync19 } from "fs";
|
|
25490
26077
|
import { homedir as homedir5 } from "os";
|
|
25491
|
-
import { join as
|
|
26078
|
+
import { join as join16 } from "path";
|
|
25492
26079
|
function getDesktopAppPaths(platform) {
|
|
25493
26080
|
const home = homedir5();
|
|
25494
26081
|
switch (platform) {
|
|
25495
26082
|
case "darwin":
|
|
25496
26083
|
return [
|
|
25497
26084
|
"/Applications/OpenCode.app/Contents/MacOS/OpenCode",
|
|
25498
|
-
|
|
26085
|
+
join16(home, "Applications", "OpenCode.app", "Contents", "MacOS", "OpenCode")
|
|
25499
26086
|
];
|
|
25500
26087
|
case "win32": {
|
|
25501
26088
|
const programFiles = process.env.ProgramFiles;
|
|
25502
26089
|
const localAppData = process.env.LOCALAPPDATA;
|
|
25503
26090
|
const paths = [];
|
|
25504
26091
|
if (programFiles) {
|
|
25505
|
-
paths.push(
|
|
26092
|
+
paths.push(join16(programFiles, "OpenCode", "OpenCode.exe"));
|
|
25506
26093
|
}
|
|
25507
26094
|
if (localAppData) {
|
|
25508
|
-
paths.push(
|
|
26095
|
+
paths.push(join16(localAppData, "OpenCode", "OpenCode.exe"));
|
|
25509
26096
|
}
|
|
25510
26097
|
return paths;
|
|
25511
26098
|
}
|
|
@@ -25513,8 +26100,8 @@ function getDesktopAppPaths(platform) {
|
|
|
25513
26100
|
return [
|
|
25514
26101
|
"/usr/bin/opencode",
|
|
25515
26102
|
"/usr/lib/opencode/opencode",
|
|
25516
|
-
|
|
25517
|
-
|
|
26103
|
+
join16(home, "Applications", "opencode-desktop-linux-x86_64.AppImage"),
|
|
26104
|
+
join16(home, "Applications", "opencode-desktop-linux-aarch64.AppImage")
|
|
25518
26105
|
];
|
|
25519
26106
|
default:
|
|
25520
26107
|
return [];
|
|
@@ -25526,7 +26113,7 @@ function buildVersionCommand(binaryPath, platform) {
|
|
|
25526
26113
|
}
|
|
25527
26114
|
return [binaryPath, "--version"];
|
|
25528
26115
|
}
|
|
25529
|
-
function findDesktopBinary(platform = process.platform, checkExists =
|
|
26116
|
+
function findDesktopBinary(platform = process.platform, checkExists = existsSync19) {
|
|
25530
26117
|
for (const desktopPath of getDesktopAppPaths(platform)) {
|
|
25531
26118
|
if (checkExists(desktopPath)) {
|
|
25532
26119
|
return { binary: "opencode", path: desktopPath };
|
|
@@ -25573,13 +26160,13 @@ function compareVersions(current, minimum) {
|
|
|
25573
26160
|
}
|
|
25574
26161
|
|
|
25575
26162
|
// src/cli/doctor/checks/system-plugin.ts
|
|
25576
|
-
import { existsSync as
|
|
26163
|
+
import { existsSync as existsSync20, readFileSync as readFileSync21 } from "fs";
|
|
25577
26164
|
init_shared();
|
|
25578
26165
|
function detectConfigPath() {
|
|
25579
26166
|
const paths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
|
|
25580
|
-
if (
|
|
26167
|
+
if (existsSync20(paths.configJsonc))
|
|
25581
26168
|
return paths.configJsonc;
|
|
25582
|
-
if (
|
|
26169
|
+
if (existsSync20(paths.configJson))
|
|
25583
26170
|
return paths.configJson;
|
|
25584
26171
|
return null;
|
|
25585
26172
|
}
|
|
@@ -25615,7 +26202,7 @@ function getPluginInfo() {
|
|
|
25615
26202
|
};
|
|
25616
26203
|
}
|
|
25617
26204
|
try {
|
|
25618
|
-
const content =
|
|
26205
|
+
const content = readFileSync21(configPath, "utf-8");
|
|
25619
26206
|
const parsedConfig = parseJsonc(content);
|
|
25620
26207
|
const pluginEntry = findPluginEntry2(parsedConfig.plugin ?? []);
|
|
25621
26208
|
if (!pluginEntry) {
|
|
@@ -25652,32 +26239,32 @@ function getPluginInfo() {
|
|
|
25652
26239
|
// src/cli/doctor/checks/system-loaded-version.ts
|
|
25653
26240
|
init_checker();
|
|
25654
26241
|
init_auto_update_checker();
|
|
25655
|
-
import { existsSync as
|
|
26242
|
+
import { existsSync as existsSync21, readFileSync as readFileSync22 } from "fs";
|
|
25656
26243
|
import { homedir as homedir6 } from "os";
|
|
25657
|
-
import { join as
|
|
26244
|
+
import { join as join17 } from "path";
|
|
25658
26245
|
init_shared();
|
|
25659
26246
|
function getPlatformDefaultCacheDir(platform = process.platform) {
|
|
25660
26247
|
if (platform === "darwin")
|
|
25661
|
-
return
|
|
26248
|
+
return join17(homedir6(), "Library", "Caches");
|
|
25662
26249
|
if (platform === "win32")
|
|
25663
|
-
return process.env.LOCALAPPDATA ??
|
|
25664
|
-
return
|
|
26250
|
+
return process.env.LOCALAPPDATA ?? join17(homedir6(), "AppData", "Local");
|
|
26251
|
+
return join17(homedir6(), ".cache");
|
|
25665
26252
|
}
|
|
25666
26253
|
function resolveOpenCodeCacheDir() {
|
|
25667
26254
|
const xdgCacheHome = process.env.XDG_CACHE_HOME;
|
|
25668
26255
|
if (xdgCacheHome)
|
|
25669
|
-
return
|
|
26256
|
+
return join17(xdgCacheHome, "opencode");
|
|
25670
26257
|
const fromShared = getOpenCodeCacheDir();
|
|
25671
|
-
const platformDefault =
|
|
25672
|
-
if (
|
|
26258
|
+
const platformDefault = join17(getPlatformDefaultCacheDir(), "opencode");
|
|
26259
|
+
if (existsSync21(fromShared) || !existsSync21(platformDefault))
|
|
25673
26260
|
return fromShared;
|
|
25674
26261
|
return platformDefault;
|
|
25675
26262
|
}
|
|
25676
26263
|
function readPackageJson(filePath) {
|
|
25677
|
-
if (!
|
|
26264
|
+
if (!existsSync21(filePath))
|
|
25678
26265
|
return null;
|
|
25679
26266
|
try {
|
|
25680
|
-
const content =
|
|
26267
|
+
const content = readFileSync22(filePath, "utf-8");
|
|
25681
26268
|
return parseJsonc(content);
|
|
25682
26269
|
} catch {
|
|
25683
26270
|
return null;
|
|
@@ -25691,8 +26278,8 @@ function normalizeVersion(value) {
|
|
|
25691
26278
|
}
|
|
25692
26279
|
function getLoadedPluginVersion() {
|
|
25693
26280
|
const cacheDir = resolveOpenCodeCacheDir();
|
|
25694
|
-
const cachePackagePath =
|
|
25695
|
-
const installedPackagePath =
|
|
26281
|
+
const cachePackagePath = join17(cacheDir, "package.json");
|
|
26282
|
+
const installedPackagePath = join17(cacheDir, "node_modules", PACKAGE_NAME4, "package.json");
|
|
25696
26283
|
const cachePackage = readPackageJson(cachePackagePath);
|
|
25697
26284
|
const installedPackage = readPackageJson(installedPackagePath);
|
|
25698
26285
|
const expectedVersion = normalizeVersion(cachePackage?.dependencies?.[PACKAGE_NAME4]);
|
|
@@ -25715,10 +26302,10 @@ init_shared();
|
|
|
25715
26302
|
function isConfigValid(configPath) {
|
|
25716
26303
|
if (!configPath)
|
|
25717
26304
|
return true;
|
|
25718
|
-
if (!
|
|
26305
|
+
if (!existsSync22(configPath))
|
|
25719
26306
|
return false;
|
|
25720
26307
|
try {
|
|
25721
|
-
parseJsonc(
|
|
26308
|
+
parseJsonc(readFileSync23(configPath, "utf-8"));
|
|
25722
26309
|
return true;
|
|
25723
26310
|
} catch {
|
|
25724
26311
|
return false;
|
|
@@ -25820,28 +26407,28 @@ async function checkSystem() {
|
|
|
25820
26407
|
}
|
|
25821
26408
|
|
|
25822
26409
|
// src/cli/doctor/checks/config.ts
|
|
25823
|
-
import { readFileSync as
|
|
25824
|
-
import { join as
|
|
26410
|
+
import { readFileSync as readFileSync26 } from "fs";
|
|
26411
|
+
import { join as join21 } from "path";
|
|
25825
26412
|
init_shared();
|
|
25826
26413
|
|
|
25827
26414
|
// src/cli/doctor/checks/model-resolution-cache.ts
|
|
25828
26415
|
init_shared();
|
|
25829
|
-
import { existsSync as
|
|
26416
|
+
import { existsSync as existsSync23, readFileSync as readFileSync24 } from "fs";
|
|
25830
26417
|
import { homedir as homedir7 } from "os";
|
|
25831
|
-
import { join as
|
|
26418
|
+
import { join as join18 } from "path";
|
|
25832
26419
|
function getOpenCodeCacheDir2() {
|
|
25833
26420
|
const xdgCache = process.env.XDG_CACHE_HOME;
|
|
25834
26421
|
if (xdgCache)
|
|
25835
|
-
return
|
|
25836
|
-
return
|
|
26422
|
+
return join18(xdgCache, "opencode");
|
|
26423
|
+
return join18(homedir7(), ".cache", "opencode");
|
|
25837
26424
|
}
|
|
25838
26425
|
function loadAvailableModelsFromCache() {
|
|
25839
|
-
const cacheFile =
|
|
25840
|
-
if (!
|
|
26426
|
+
const cacheFile = join18(getOpenCodeCacheDir2(), "models.json");
|
|
26427
|
+
if (!existsSync23(cacheFile)) {
|
|
25841
26428
|
return { providers: [], modelCount: 0, cacheExists: false };
|
|
25842
26429
|
}
|
|
25843
26430
|
try {
|
|
25844
|
-
const content =
|
|
26431
|
+
const content = readFileSync24(cacheFile, "utf-8");
|
|
25845
26432
|
const data = parseJsonc(content);
|
|
25846
26433
|
const providers = Object.keys(data);
|
|
25847
26434
|
let modelCount = 0;
|
|
@@ -25862,16 +26449,16 @@ init_model_requirements();
|
|
|
25862
26449
|
|
|
25863
26450
|
// src/cli/doctor/checks/model-resolution-config.ts
|
|
25864
26451
|
init_shared();
|
|
25865
|
-
import { readFileSync as
|
|
25866
|
-
import { join as
|
|
26452
|
+
import { readFileSync as readFileSync25 } from "fs";
|
|
26453
|
+
import { join as join19 } from "path";
|
|
25867
26454
|
var PACKAGE_NAME5 = "oh-my-opencode";
|
|
25868
|
-
var USER_CONFIG_BASE =
|
|
25869
|
-
var PROJECT_CONFIG_BASE =
|
|
26455
|
+
var USER_CONFIG_BASE = join19(getOpenCodeConfigPaths({ binary: "opencode", version: null }).configDir, PACKAGE_NAME5);
|
|
26456
|
+
var PROJECT_CONFIG_BASE = join19(process.cwd(), ".opencode", PACKAGE_NAME5);
|
|
25870
26457
|
function loadOmoConfig() {
|
|
25871
26458
|
const projectDetected = detectConfigFile(PROJECT_CONFIG_BASE);
|
|
25872
26459
|
if (projectDetected.format !== "none") {
|
|
25873
26460
|
try {
|
|
25874
|
-
const content =
|
|
26461
|
+
const content = readFileSync25(projectDetected.path, "utf-8");
|
|
25875
26462
|
return parseJsonc(content);
|
|
25876
26463
|
} catch {
|
|
25877
26464
|
return null;
|
|
@@ -25880,7 +26467,7 @@ function loadOmoConfig() {
|
|
|
25880
26467
|
const userDetected = detectConfigFile(USER_CONFIG_BASE);
|
|
25881
26468
|
if (userDetected.format !== "none") {
|
|
25882
26469
|
try {
|
|
25883
|
-
const content =
|
|
26470
|
+
const content = readFileSync25(userDetected.path, "utf-8");
|
|
25884
26471
|
return parseJsonc(content);
|
|
25885
26472
|
} catch {
|
|
25886
26473
|
return null;
|
|
@@ -25891,7 +26478,7 @@ function loadOmoConfig() {
|
|
|
25891
26478
|
|
|
25892
26479
|
// src/cli/doctor/checks/model-resolution-details.ts
|
|
25893
26480
|
init_shared();
|
|
25894
|
-
import { join as
|
|
26481
|
+
import { join as join20 } from "path";
|
|
25895
26482
|
|
|
25896
26483
|
// src/cli/doctor/checks/model-resolution-variant.ts
|
|
25897
26484
|
function formatModelWithVariant(model, variant) {
|
|
@@ -25930,7 +26517,7 @@ function getCategoryEffectiveVariant(categoryName, requirement, config2) {
|
|
|
25930
26517
|
// src/cli/doctor/checks/model-resolution-details.ts
|
|
25931
26518
|
function buildModelResolutionDetails(options) {
|
|
25932
26519
|
const details = [];
|
|
25933
|
-
const cacheFile =
|
|
26520
|
+
const cacheFile = join20(getOpenCodeCacheDir(), "models.json");
|
|
25934
26521
|
details.push("\u2550\u2550\u2550 Available Models (from cache) \u2550\u2550\u2550");
|
|
25935
26522
|
details.push("");
|
|
25936
26523
|
if (options.available.cacheExists) {
|
|
@@ -26042,8 +26629,8 @@ async function checkModels() {
|
|
|
26042
26629
|
}
|
|
26043
26630
|
|
|
26044
26631
|
// src/cli/doctor/checks/config.ts
|
|
26045
|
-
var USER_CONFIG_BASE2 =
|
|
26046
|
-
var PROJECT_CONFIG_BASE2 =
|
|
26632
|
+
var USER_CONFIG_BASE2 = join21(getOpenCodeConfigDir({ binary: "opencode" }), PACKAGE_NAME4);
|
|
26633
|
+
var PROJECT_CONFIG_BASE2 = join21(process.cwd(), ".opencode", PACKAGE_NAME4);
|
|
26047
26634
|
function findConfigPath() {
|
|
26048
26635
|
const projectConfig = detectConfigFile(PROJECT_CONFIG_BASE2);
|
|
26049
26636
|
if (projectConfig.format !== "none")
|
|
@@ -26059,7 +26646,7 @@ function validateConfig() {
|
|
|
26059
26646
|
return { exists: false, path: null, valid: true, config: null, errors: [] };
|
|
26060
26647
|
}
|
|
26061
26648
|
try {
|
|
26062
|
-
const content =
|
|
26649
|
+
const content = readFileSync26(configPath, "utf-8");
|
|
26063
26650
|
const rawConfig = parseJsonc(content);
|
|
26064
26651
|
const schemaResult = OhMyOpenCodeConfigSchema.safeParse(rawConfig);
|
|
26065
26652
|
if (!schemaResult.success) {
|
|
@@ -26162,9 +26749,9 @@ async function checkConfig() {
|
|
|
26162
26749
|
}
|
|
26163
26750
|
|
|
26164
26751
|
// src/cli/doctor/checks/dependencies.ts
|
|
26165
|
-
import { existsSync as
|
|
26752
|
+
import { existsSync as existsSync24 } from "fs";
|
|
26166
26753
|
import { createRequire as createRequire2 } from "module";
|
|
26167
|
-
import { dirname as
|
|
26754
|
+
import { dirname as dirname7, join as join22 } from "path";
|
|
26168
26755
|
async function checkBinaryExists(binary2) {
|
|
26169
26756
|
try {
|
|
26170
26757
|
const path9 = Bun.which(binary2);
|
|
@@ -26220,15 +26807,15 @@ async function checkAstGrepNapi() {
|
|
|
26220
26807
|
path: null
|
|
26221
26808
|
};
|
|
26222
26809
|
} catch {
|
|
26223
|
-
const { existsSync:
|
|
26224
|
-
const { join:
|
|
26810
|
+
const { existsSync: existsSync25 } = await import("fs");
|
|
26811
|
+
const { join: join23 } = await import("path");
|
|
26225
26812
|
const { homedir: homedir8 } = await import("os");
|
|
26226
26813
|
const pathsToCheck = [
|
|
26227
|
-
|
|
26228
|
-
|
|
26814
|
+
join23(homedir8(), ".config", "opencode", "node_modules", "@ast-grep", "napi"),
|
|
26815
|
+
join23(process.cwd(), "node_modules", "@ast-grep", "napi")
|
|
26229
26816
|
];
|
|
26230
26817
|
for (const napiPath of pathsToCheck) {
|
|
26231
|
-
if (
|
|
26818
|
+
if (existsSync25(napiPath)) {
|
|
26232
26819
|
return {
|
|
26233
26820
|
name: "AST-Grep NAPI",
|
|
26234
26821
|
required: false,
|
|
@@ -26253,8 +26840,8 @@ function findCommentCheckerPackageBinary() {
|
|
|
26253
26840
|
try {
|
|
26254
26841
|
const require2 = createRequire2(import.meta.url);
|
|
26255
26842
|
const pkgPath = require2.resolve("@code-yeongyu/comment-checker/package.json");
|
|
26256
|
-
const binaryPath =
|
|
26257
|
-
if (
|
|
26843
|
+
const binaryPath = join22(dirname7(pkgPath), "bin", binaryName);
|
|
26844
|
+
if (existsSync24(binaryPath))
|
|
26258
26845
|
return binaryPath;
|
|
26259
26846
|
} catch {}
|
|
26260
26847
|
return null;
|
|
@@ -26372,14 +26959,14 @@ init_jsonc_parser();
|
|
|
26372
26959
|
|
|
26373
26960
|
// src/tools/lsp/server-installation.ts
|
|
26374
26961
|
init_shared();
|
|
26375
|
-
import { existsSync as
|
|
26376
|
-
import { join as
|
|
26962
|
+
import { existsSync as existsSync25 } from "fs";
|
|
26963
|
+
import { join as join23 } from "path";
|
|
26377
26964
|
function isServerInstalled(command) {
|
|
26378
26965
|
if (command.length === 0)
|
|
26379
26966
|
return false;
|
|
26380
26967
|
const cmd = command[0];
|
|
26381
26968
|
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
26382
|
-
if (
|
|
26969
|
+
if (existsSync25(cmd))
|
|
26383
26970
|
return true;
|
|
26384
26971
|
}
|
|
26385
26972
|
const isWindows = process.platform === "win32";
|
|
@@ -26401,23 +26988,23 @@ function isServerInstalled(command) {
|
|
|
26401
26988
|
const paths = pathEnv.split(pathSeparator);
|
|
26402
26989
|
for (const p2 of paths) {
|
|
26403
26990
|
for (const suffix of exts) {
|
|
26404
|
-
if (
|
|
26991
|
+
if (existsSync25(join23(p2, cmd + suffix))) {
|
|
26405
26992
|
return true;
|
|
26406
26993
|
}
|
|
26407
26994
|
}
|
|
26408
26995
|
}
|
|
26409
26996
|
const cwd = process.cwd();
|
|
26410
26997
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
26411
|
-
const dataDir =
|
|
26998
|
+
const dataDir = join23(getDataDir(), "opencode");
|
|
26412
26999
|
const additionalBases = [
|
|
26413
|
-
|
|
26414
|
-
|
|
26415
|
-
|
|
26416
|
-
|
|
27000
|
+
join23(cwd, "node_modules", ".bin"),
|
|
27001
|
+
join23(configDir, "bin"),
|
|
27002
|
+
join23(configDir, "node_modules", ".bin"),
|
|
27003
|
+
join23(dataDir, "bin")
|
|
26417
27004
|
];
|
|
26418
27005
|
for (const base of additionalBases) {
|
|
26419
27006
|
for (const suffix of exts) {
|
|
26420
|
-
if (
|
|
27007
|
+
if (existsSync25(join23(base, cmd + suffix))) {
|
|
26421
27008
|
return true;
|
|
26422
27009
|
}
|
|
26423
27010
|
}
|
|
@@ -26451,24 +27038,24 @@ function getLspServerStats(servers) {
|
|
|
26451
27038
|
|
|
26452
27039
|
// src/cli/doctor/checks/tools-mcp.ts
|
|
26453
27040
|
init_shared();
|
|
26454
|
-
import { existsSync as
|
|
27041
|
+
import { existsSync as existsSync26, readFileSync as readFileSync27 } from "fs";
|
|
26455
27042
|
import { homedir as homedir8 } from "os";
|
|
26456
|
-
import { join as
|
|
27043
|
+
import { join as join24 } from "path";
|
|
26457
27044
|
var BUILTIN_MCP_SERVERS = ["context7", "grep_app"];
|
|
26458
27045
|
function getMcpConfigPaths() {
|
|
26459
27046
|
return [
|
|
26460
|
-
|
|
26461
|
-
|
|
26462
|
-
|
|
27047
|
+
join24(homedir8(), ".claude", ".mcp.json"),
|
|
27048
|
+
join24(process.cwd(), ".mcp.json"),
|
|
27049
|
+
join24(process.cwd(), ".claude", ".mcp.json")
|
|
26463
27050
|
];
|
|
26464
27051
|
}
|
|
26465
27052
|
function loadUserMcpConfig() {
|
|
26466
27053
|
const servers = {};
|
|
26467
27054
|
for (const configPath of getMcpConfigPaths()) {
|
|
26468
|
-
if (!
|
|
27055
|
+
if (!existsSync26(configPath))
|
|
26469
27056
|
continue;
|
|
26470
27057
|
try {
|
|
26471
|
-
const content =
|
|
27058
|
+
const content = readFileSync27(configPath, "utf-8");
|
|
26472
27059
|
const config2 = parseJsonc(content);
|
|
26473
27060
|
if (config2.mcpServers) {
|
|
26474
27061
|
Object.assign(servers, config2.mcpServers);
|
|
@@ -26629,10 +27216,10 @@ function getAllCheckDefinitions() {
|
|
|
26629
27216
|
}
|
|
26630
27217
|
|
|
26631
27218
|
// src/cli/doctor/format-default.ts
|
|
26632
|
-
var
|
|
27219
|
+
var import_picocolors19 = __toESM(require_picocolors(), 1);
|
|
26633
27220
|
|
|
26634
27221
|
// src/cli/doctor/format-shared.ts
|
|
26635
|
-
var
|
|
27222
|
+
var import_picocolors18 = __toESM(require_picocolors(), 1);
|
|
26636
27223
|
function formatStatusSymbol(status) {
|
|
26637
27224
|
const colorFn = STATUS_COLORS[status];
|
|
26638
27225
|
switch (status) {
|
|
@@ -26647,23 +27234,23 @@ function formatStatusSymbol(status) {
|
|
|
26647
27234
|
}
|
|
26648
27235
|
}
|
|
26649
27236
|
function formatStatusMark(available) {
|
|
26650
|
-
return available ?
|
|
27237
|
+
return available ? import_picocolors18.default.green(SYMBOLS3.check) : import_picocolors18.default.red(SYMBOLS3.cross);
|
|
26651
27238
|
}
|
|
26652
27239
|
function formatHeader() {
|
|
26653
27240
|
return `
|
|
26654
|
-
${
|
|
27241
|
+
${import_picocolors18.default.bgMagenta(import_picocolors18.default.white(" oMoMoMoMo Doctor "))}
|
|
26655
27242
|
`;
|
|
26656
27243
|
}
|
|
26657
27244
|
function formatIssue(issue2, index) {
|
|
26658
27245
|
const lines = [];
|
|
26659
|
-
const severityColor = issue2.severity === "error" ?
|
|
27246
|
+
const severityColor = issue2.severity === "error" ? import_picocolors18.default.red : import_picocolors18.default.yellow;
|
|
26660
27247
|
lines.push(`${index}. ${severityColor(issue2.title)}`);
|
|
26661
|
-
lines.push(` ${
|
|
27248
|
+
lines.push(` ${import_picocolors18.default.dim(issue2.description)}`);
|
|
26662
27249
|
if (issue2.fix) {
|
|
26663
|
-
lines.push(` ${
|
|
27250
|
+
lines.push(` ${import_picocolors18.default.cyan("Fix:")} ${import_picocolors18.default.dim(issue2.fix)}`);
|
|
26664
27251
|
}
|
|
26665
27252
|
if (issue2.affects && issue2.affects.length > 0) {
|
|
26666
|
-
lines.push(` ${
|
|
27253
|
+
lines.push(` ${import_picocolors18.default.cyan("Affects:")} ${import_picocolors18.default.dim(issue2.affects.join(", "))}`);
|
|
26667
27254
|
}
|
|
26668
27255
|
return lines.join(`
|
|
26669
27256
|
`);
|
|
@@ -26677,12 +27264,12 @@ function formatDefault(result) {
|
|
|
26677
27264
|
if (allIssues.length === 0) {
|
|
26678
27265
|
const opencodeVer = result.systemInfo.opencodeVersion ?? "unknown";
|
|
26679
27266
|
const pluginVer = result.systemInfo.pluginVersion ?? "unknown";
|
|
26680
|
-
lines.push(` ${
|
|
27267
|
+
lines.push(` ${import_picocolors19.default.green(SYMBOLS3.check)} ${import_picocolors19.default.green(`System OK (opencode ${opencodeVer} \xB7 oh-my-opencode ${pluginVer})`)}`);
|
|
26681
27268
|
} else {
|
|
26682
27269
|
const issueCount = allIssues.filter((i2) => i2.severity === "error").length;
|
|
26683
27270
|
const warnCount = allIssues.filter((i2) => i2.severity === "warning").length;
|
|
26684
27271
|
const totalStr = `${issueCount + warnCount} ${issueCount + warnCount === 1 ? "issue" : "issues"}`;
|
|
26685
|
-
lines.push(` ${
|
|
27272
|
+
lines.push(` ${import_picocolors19.default.yellow(SYMBOLS3.warn)} ${totalStr} found:
|
|
26686
27273
|
`);
|
|
26687
27274
|
allIssues.forEach((issue2, index) => {
|
|
26688
27275
|
lines.push(formatIssue(issue2, index + 1));
|
|
@@ -26694,7 +27281,7 @@ function formatDefault(result) {
|
|
|
26694
27281
|
}
|
|
26695
27282
|
|
|
26696
27283
|
// src/cli/doctor/format-status.ts
|
|
26697
|
-
var
|
|
27284
|
+
var import_picocolors20 = __toESM(require_picocolors(), 1);
|
|
26698
27285
|
function formatStatus(result) {
|
|
26699
27286
|
const lines = [];
|
|
26700
27287
|
lines.push(formatHeader());
|
|
@@ -26705,7 +27292,7 @@ function formatStatus(result) {
|
|
|
26705
27292
|
const bunVer = systemInfo.bunVersion ?? "unknown";
|
|
26706
27293
|
lines.push(` ${padding}System ${opencodeVer} \xB7 ${pluginVer} \xB7 Bun ${bunVer}`);
|
|
26707
27294
|
const configPath = systemInfo.configPath ?? "unknown";
|
|
26708
|
-
const configStatus = systemInfo.configValid ?
|
|
27295
|
+
const configStatus = systemInfo.configValid ? import_picocolors20.default.green("(valid)") : import_picocolors20.default.red("(invalid)");
|
|
26709
27296
|
lines.push(` ${padding}Config ${configPath} ${configStatus}`);
|
|
26710
27297
|
const lspText = `LSP ${tools.lspInstalled}/${tools.lspTotal}`;
|
|
26711
27298
|
const astGrepMark = formatStatusMark(tools.astGrepCli);
|
|
@@ -26722,13 +27309,13 @@ function formatStatus(result) {
|
|
|
26722
27309
|
}
|
|
26723
27310
|
|
|
26724
27311
|
// src/cli/doctor/format-verbose.ts
|
|
26725
|
-
var
|
|
27312
|
+
var import_picocolors21 = __toESM(require_picocolors(), 1);
|
|
26726
27313
|
function formatVerbose(result) {
|
|
26727
27314
|
const lines = [];
|
|
26728
27315
|
lines.push(formatHeader());
|
|
26729
27316
|
const { systemInfo, tools, results, summary } = result;
|
|
26730
|
-
lines.push(`${
|
|
26731
|
-
lines.push(`${
|
|
27317
|
+
lines.push(`${import_picocolors21.default.bold("System Information")}`);
|
|
27318
|
+
lines.push(`${import_picocolors21.default.dim("\u2500".repeat(40))}`);
|
|
26732
27319
|
lines.push(` ${formatStatusSymbol("pass")} opencode ${systemInfo.opencodeVersion ?? "unknown"}`);
|
|
26733
27320
|
lines.push(` ${formatStatusSymbol("pass")} oh-my-opencode ${systemInfo.pluginVersion ?? "unknown"}`);
|
|
26734
27321
|
if (systemInfo.loadedVersion) {
|
|
@@ -26739,33 +27326,33 @@ function formatVerbose(result) {
|
|
|
26739
27326
|
}
|
|
26740
27327
|
lines.push(` ${formatStatusSymbol("pass")} path ${systemInfo.opencodePath ?? "unknown"}`);
|
|
26741
27328
|
if (systemInfo.isLocalDev) {
|
|
26742
|
-
lines.push(` ${
|
|
27329
|
+
lines.push(` ${import_picocolors21.default.yellow("*")} ${import_picocolors21.default.dim("(local development mode)")}`);
|
|
26743
27330
|
}
|
|
26744
27331
|
lines.push("");
|
|
26745
|
-
lines.push(`${
|
|
26746
|
-
lines.push(`${
|
|
26747
|
-
const configStatus = systemInfo.configValid ?
|
|
27332
|
+
lines.push(`${import_picocolors21.default.bold("Configuration")}`);
|
|
27333
|
+
lines.push(`${import_picocolors21.default.dim("\u2500".repeat(40))}`);
|
|
27334
|
+
const configStatus = systemInfo.configValid ? import_picocolors21.default.green("valid") : import_picocolors21.default.red("invalid");
|
|
26748
27335
|
lines.push(` ${formatStatusSymbol(systemInfo.configValid ? "pass" : "fail")} ${systemInfo.configPath ?? "unknown"} (${configStatus})`);
|
|
26749
27336
|
lines.push("");
|
|
26750
|
-
lines.push(`${
|
|
26751
|
-
lines.push(`${
|
|
27337
|
+
lines.push(`${import_picocolors21.default.bold("Tools")}`);
|
|
27338
|
+
lines.push(`${import_picocolors21.default.dim("\u2500".repeat(40))}`);
|
|
26752
27339
|
lines.push(` ${formatStatusSymbol("pass")} LSP ${tools.lspInstalled}/${tools.lspTotal} installed`);
|
|
26753
27340
|
lines.push(` ${formatStatusSymbol(tools.astGrepCli ? "pass" : "fail")} ast-grep CLI ${tools.astGrepCli ? "installed" : "not found"}`);
|
|
26754
27341
|
lines.push(` ${formatStatusSymbol(tools.astGrepNapi ? "pass" : "fail")} ast-grep napi ${tools.astGrepNapi ? "installed" : "not found"}`);
|
|
26755
27342
|
lines.push(` ${formatStatusSymbol(tools.commentChecker ? "pass" : "fail")} comment-checker ${tools.commentChecker ? "installed" : "not found"}`);
|
|
26756
27343
|
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
27344
|
lines.push("");
|
|
26758
|
-
lines.push(`${
|
|
26759
|
-
lines.push(`${
|
|
27345
|
+
lines.push(`${import_picocolors21.default.bold("MCPs")}`);
|
|
27346
|
+
lines.push(`${import_picocolors21.default.dim("\u2500".repeat(40))}`);
|
|
26760
27347
|
if (tools.mcpBuiltin.length === 0) {
|
|
26761
|
-
lines.push(` ${
|
|
27348
|
+
lines.push(` ${import_picocolors21.default.dim("No built-in MCPs")}`);
|
|
26762
27349
|
} else {
|
|
26763
27350
|
for (const mcp of tools.mcpBuiltin) {
|
|
26764
27351
|
lines.push(` ${formatStatusSymbol("pass")} ${mcp}`);
|
|
26765
27352
|
}
|
|
26766
27353
|
}
|
|
26767
27354
|
if (tools.mcpUser.length > 0) {
|
|
26768
|
-
lines.push(` ${
|
|
27355
|
+
lines.push(` ${import_picocolors21.default.cyan("+")} ${tools.mcpUser.length} user MCP(s):`);
|
|
26769
27356
|
for (const mcp of tools.mcpUser) {
|
|
26770
27357
|
lines.push(` ${formatStatusSymbol("pass")} ${mcp}`);
|
|
26771
27358
|
}
|
|
@@ -26773,20 +27360,20 @@ function formatVerbose(result) {
|
|
|
26773
27360
|
lines.push("");
|
|
26774
27361
|
const allIssues = results.flatMap((r2) => r2.issues);
|
|
26775
27362
|
if (allIssues.length > 0) {
|
|
26776
|
-
lines.push(`${
|
|
26777
|
-
lines.push(`${
|
|
27363
|
+
lines.push(`${import_picocolors21.default.bold("Issues")}`);
|
|
27364
|
+
lines.push(`${import_picocolors21.default.dim("\u2500".repeat(40))}`);
|
|
26778
27365
|
allIssues.forEach((issue2, index) => {
|
|
26779
27366
|
lines.push(formatIssue(issue2, index + 1));
|
|
26780
27367
|
lines.push("");
|
|
26781
27368
|
});
|
|
26782
27369
|
}
|
|
26783
|
-
lines.push(`${
|
|
26784
|
-
lines.push(`${
|
|
26785
|
-
const passText = summary.passed > 0 ?
|
|
26786
|
-
const failText = summary.failed > 0 ?
|
|
26787
|
-
const warnText = summary.warnings > 0 ?
|
|
27370
|
+
lines.push(`${import_picocolors21.default.bold("Summary")}`);
|
|
27371
|
+
lines.push(`${import_picocolors21.default.dim("\u2500".repeat(40))}`);
|
|
27372
|
+
const passText = summary.passed > 0 ? import_picocolors21.default.green(`${summary.passed} passed`) : `${summary.passed} passed`;
|
|
27373
|
+
const failText = summary.failed > 0 ? import_picocolors21.default.red(`${summary.failed} failed`) : `${summary.failed} failed`;
|
|
27374
|
+
const warnText = summary.warnings > 0 ? import_picocolors21.default.yellow(`${summary.warnings} warnings`) : `${summary.warnings} warnings`;
|
|
26788
27375
|
lines.push(` ${passText}, ${failText}, ${warnText}`);
|
|
26789
|
-
lines.push(` ${
|
|
27376
|
+
lines.push(` ${import_picocolors21.default.dim(`Total: ${summary.total} checks in ${summary.duration}ms`)}`);
|
|
26790
27377
|
return lines.join(`
|
|
26791
27378
|
`);
|
|
26792
27379
|
}
|
|
@@ -26870,11 +27457,11 @@ async function doctor(options = { mode: "default" }) {
|
|
|
26870
27457
|
|
|
26871
27458
|
// src/features/mcp-oauth/storage.ts
|
|
26872
27459
|
init_shared();
|
|
26873
|
-
import { chmodSync, existsSync as
|
|
26874
|
-
import { dirname as
|
|
27460
|
+
import { chmodSync, existsSync as existsSync27, mkdirSync as mkdirSync6, readFileSync as readFileSync28, unlinkSync as unlinkSync2, writeFileSync as writeFileSync12 } from "fs";
|
|
27461
|
+
import { dirname as dirname8, join as join25 } from "path";
|
|
26875
27462
|
var STORAGE_FILE_NAME = "mcp-oauth.json";
|
|
26876
27463
|
function getMcpOauthStoragePath() {
|
|
26877
|
-
return
|
|
27464
|
+
return join25(getOpenCodeConfigDir({ binary: "opencode" }), STORAGE_FILE_NAME);
|
|
26878
27465
|
}
|
|
26879
27466
|
function normalizeHost(serverHost) {
|
|
26880
27467
|
let host = serverHost.trim();
|
|
@@ -26911,11 +27498,11 @@ function buildKey(serverHost, resource) {
|
|
|
26911
27498
|
}
|
|
26912
27499
|
function readStore() {
|
|
26913
27500
|
const filePath = getMcpOauthStoragePath();
|
|
26914
|
-
if (!
|
|
27501
|
+
if (!existsSync27(filePath)) {
|
|
26915
27502
|
return null;
|
|
26916
27503
|
}
|
|
26917
27504
|
try {
|
|
26918
|
-
const content =
|
|
27505
|
+
const content = readFileSync28(filePath, "utf-8");
|
|
26919
27506
|
return JSON.parse(content);
|
|
26920
27507
|
} catch {
|
|
26921
27508
|
return null;
|
|
@@ -26924,11 +27511,11 @@ function readStore() {
|
|
|
26924
27511
|
function writeStore(store) {
|
|
26925
27512
|
const filePath = getMcpOauthStoragePath();
|
|
26926
27513
|
try {
|
|
26927
|
-
const dir =
|
|
26928
|
-
if (!
|
|
26929
|
-
|
|
27514
|
+
const dir = dirname8(filePath);
|
|
27515
|
+
if (!existsSync27(dir)) {
|
|
27516
|
+
mkdirSync6(dir, { recursive: true });
|
|
26930
27517
|
}
|
|
26931
|
-
|
|
27518
|
+
writeFileSync12(filePath, JSON.stringify(store, null, 2), { encoding: "utf-8", mode: 384 });
|
|
26932
27519
|
chmodSync(filePath, 384);
|
|
26933
27520
|
return true;
|
|
26934
27521
|
} catch {
|
|
@@ -26960,8 +27547,8 @@ function deleteToken(serverHost, resource) {
|
|
|
26960
27547
|
if (Object.keys(store).length === 0) {
|
|
26961
27548
|
try {
|
|
26962
27549
|
const filePath = getMcpOauthStoragePath();
|
|
26963
|
-
if (
|
|
26964
|
-
|
|
27550
|
+
if (existsSync27(filePath)) {
|
|
27551
|
+
unlinkSync2(filePath);
|
|
26965
27552
|
}
|
|
26966
27553
|
return true;
|
|
26967
27554
|
} catch {
|
|
@@ -27132,30 +27719,11 @@ function isRecord2(value) {
|
|
|
27132
27719
|
}
|
|
27133
27720
|
|
|
27134
27721
|
// src/features/mcp-oauth/callback-server.ts
|
|
27722
|
+
init_port_utils();
|
|
27135
27723
|
var DEFAULT_PORT = 19877;
|
|
27136
|
-
var MAX_PORT_ATTEMPTS2 = 20;
|
|
27137
27724
|
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
27725
|
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}`);
|
|
27726
|
+
return findAvailablePort(startPort);
|
|
27159
27727
|
}
|
|
27160
27728
|
|
|
27161
27729
|
// src/features/mcp-oauth/oauth-authorization-flow.ts
|
|
@@ -27542,11 +28110,10 @@ Model Providers (Priority: Native > Copilot > OpenCode Zen > Z.ai > Kimi):
|
|
|
27542
28110
|
const exitCode = await install(args);
|
|
27543
28111
|
process.exit(exitCode);
|
|
27544
28112
|
});
|
|
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("-
|
|
28113
|
+
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
28114
|
Examples:
|
|
27547
28115
|
$ bunx oh-my-opencode run "Fix the bug in index.ts"
|
|
27548
28116
|
$ bunx oh-my-opencode run --agent Sisyphus "Implement feature X"
|
|
27549
|
-
$ bunx oh-my-opencode run --timeout 3600000 "Large refactoring task"
|
|
27550
28117
|
$ bunx oh-my-opencode run --port 4321 "Fix the bug"
|
|
27551
28118
|
$ bunx oh-my-opencode run --attach http://127.0.0.1:4321 "Fix the bug"
|
|
27552
28119
|
$ bunx oh-my-opencode run --json "Fix the bug" | jq .sessionId
|
|
@@ -27574,11 +28141,11 @@ Unlike 'opencode run', this command waits until:
|
|
|
27574
28141
|
message,
|
|
27575
28142
|
agent: options.agent,
|
|
27576
28143
|
directory: options.directory,
|
|
27577
|
-
timeout: options.timeout,
|
|
27578
28144
|
port: options.port,
|
|
27579
28145
|
attach: options.attach,
|
|
27580
28146
|
onComplete: options.onComplete,
|
|
27581
28147
|
json: options.json ?? false,
|
|
28148
|
+
verbose: options.verbose ?? false,
|
|
27582
28149
|
sessionId: options.sessionId
|
|
27583
28150
|
};
|
|
27584
28151
|
const exitCode = await run(runOptions);
|