oh-my-opencode 4.14.0 → 4.14.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/.agents/skills/codex-qa/references/isolation.md +1 -1
- package/README.md +1 -1
- package/dist/cli/doctor/framework/types.d.ts +2 -0
- package/dist/cli/index.js +223 -1447
- package/dist/cli-node/index.js +223 -1447
- package/dist/index.js +4255 -714
- package/dist/plugin/native-skills.d.ts +9 -0
- package/dist/plugin/system-transform.d.ts +1 -1
- package/dist/skills/frontend/ATTRIBUTION.md +7 -1
- package/dist/skills/frontend/SKILL.md +4 -3
- package/dist/skills/frontend/references/design/README.md +4 -3
- package/dist/skills/frontend/references/design/_INDEX.md +5 -3
- package/dist/skills/frontend/references/design/aside.md +209 -0
- package/dist/skills/lcx-contribute-bug-fix/SKILL.md +44 -13
- package/dist/skills/lcx-contribute-bug-fix/agents/openai.yaml +1 -1
- package/dist/skills/lcx-doctor/SKILL.md +48 -13
- package/dist/skills/lcx-doctor/agents/openai.yaml +1 -1
- package/dist/skills/lcx-report-bug/SKILL.md +44 -13
- package/dist/skills/lcx-report-bug/agents/openai.yaml +1 -1
- package/dist/skills/visual-qa/SKILL.md +5 -5
- package/dist/skills/visual-qa/references/agent-browser-setup.md +5 -4
- package/dist/skills/visual-qa/scripts/cli.test.ts +7 -2
- package/dist/skills/visual-qa/scripts/skill-prompt-contract.test.ts +10 -2
- package/dist/skills/visual-qa/scripts/visual-qa.mjs +530 -0
- package/dist/tools/delegate-task/skill-resolver.d.ts +1 -0
- package/dist/tools/delegate-task/types.d.ts +2 -0
- package/dist/tools/skill/types.d.ts +1 -0
- package/package.json +26 -13
- package/packages/git-bash-mcp/dist/cli.js +2 -0
- package/packages/lsp-daemon/dist/cli.js +15 -4
- package/packages/lsp-daemon/dist/ensure-daemon.d.ts +1 -0
- package/packages/lsp-daemon/dist/ensure-daemon.js +9 -3
- package/packages/lsp-daemon/dist/index.js +15 -4
- package/packages/lsp-daemon/dist/paths.d.ts +1 -0
- package/packages/lsp-daemon/dist/paths.js +6 -1
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +4 -7
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/src/setup.ts +1 -1
- package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +123 -10
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +123 -10
- package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +126 -9
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +141 -0
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lsp/dist/cli.js +90 -25
- package/packages/omo-codex/plugin/components/lsp/dist/codex-hook.js +2 -0
- package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.d.ts +2 -0
- package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.js +56 -0
- package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
- package/packages/omo-codex/plugin/components/lsp/src/cli.ts +2 -5
- package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +2 -0
- package/packages/omo-codex/plugin/components/lsp/src/daemon-cli-path.ts +65 -0
- package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +6 -1
- package/packages/omo-codex/plugin/components/rules/dist/cli.js +8 -106
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +4 -17
- package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/SKILL.md +17 -5
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-state.mjs +63 -1
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team.mjs +80 -50
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/directive.md +4 -12
- package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +7 -33
- package/packages/omo-codex/plugin/components/ulw-loop/directive.md +4 -12
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +4 -2
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +4 -4
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/sample-quality-gate.json +7 -7
- package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +3 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-doc.test.ts +2 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +7 -6
- package/packages/omo-codex/plugin/package-lock.json +16 -56
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +7 -1
- package/packages/omo-codex/plugin/skills/frontend/SKILL.md +4 -3
- package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +4 -3
- package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +5 -3
- package/packages/omo-codex/plugin/skills/frontend/references/design/aside.md +209 -0
- package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/SKILL.md +44 -13
- package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +48 -13
- package/packages/omo-codex/plugin/skills/lcx-doctor/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/lcx-report-bug/SKILL.md +44 -13
- package/packages/omo-codex/plugin/skills/lcx-report-bug/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/teammode/SKILL.md +17 -5
- package/packages/omo-codex/plugin/skills/teammode/scripts/team-state.mjs +63 -1
- package/packages/omo-codex/plugin/skills/teammode/scripts/team.mjs +80 -50
- package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +4 -4
- package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +5 -5
- package/packages/omo-codex/plugin/skills/visual-qa/references/agent-browser-setup.md +5 -4
- package/packages/omo-codex/plugin/skills/visual-qa/scripts/visual-qa.mjs +530 -0
- package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +23 -0
- package/packages/omo-codex/plugin/test/bootstrap-binlinks.test.mjs +38 -2
- package/packages/omo-codex/plugin/test/component-bin-names.test.mjs +12 -11
- package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +99 -1
- package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +62 -8
- package/packages/omo-codex/plugin/test/node-install-surface.test.mjs +1 -0
- package/packages/omo-codex/plugin/test/teammode-archive-ambiguity.test.mjs +102 -0
- package/packages/omo-codex/plugin/test/teammode-safety-fixture.mjs +41 -1
- package/packages/omo-codex/plugin/test/teammode-safety.test.mjs +93 -0
- package/packages/omo-codex/scripts/install-bin-links.test.mjs +6 -0
- package/packages/omo-codex/scripts/install-cache-copy.test.mjs +28 -0
- package/packages/omo-codex/scripts/install-config-autonomous-features.test.mjs +43 -3
- package/packages/omo-codex/scripts/install-delegated-command.test.mjs +93 -0
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +169 -41
- package/packages/omo-codex/scripts/install-local-entrypoint.test.mjs +21 -2
- package/packages/omo-codex/scripts/install-local.test.mjs +0 -1
- package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +7 -1
- package/packages/shared-skills/skills/frontend/SKILL.md +4 -3
- package/packages/shared-skills/skills/frontend/references/design/README.md +4 -3
- package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +5 -3
- package/packages/shared-skills/skills/frontend/references/design/aside.md +209 -0
- package/packages/shared-skills/skills/lcx-contribute-bug-fix/SKILL.md +44 -13
- package/packages/shared-skills/skills/lcx-contribute-bug-fix/agents/openai.yaml +1 -1
- package/packages/shared-skills/skills/lcx-doctor/SKILL.md +48 -13
- package/packages/shared-skills/skills/lcx-doctor/agents/openai.yaml +1 -1
- package/packages/shared-skills/skills/lcx-report-bug/SKILL.md +44 -13
- package/packages/shared-skills/skills/lcx-report-bug/agents/openai.yaml +1 -1
- package/packages/shared-skills/skills/visual-qa/SKILL.md +5 -5
- package/packages/shared-skills/skills/visual-qa/references/agent-browser-setup.md +5 -4
- package/packages/shared-skills/skills/visual-qa/scripts/cli.test.ts +7 -2
- package/packages/shared-skills/skills/visual-qa/scripts/skill-prompt-contract.test.ts +10 -2
- package/packages/shared-skills/skills/visual-qa/scripts/visual-qa.mjs +530 -0
- package/dist/cli/sparkshell-appserver-websocket.d.ts +0 -4
- package/dist/cli/sparkshell-appserver.d.ts +0 -16
- package/dist/cli/sparkshell-condense.d.ts +0 -10
- package/dist/cli/sparkshell-parse.d.ts +0 -24
- package/dist/cli/sparkshell-session-context.d.ts +0 -20
- package/dist/cli/sparkshell-spark.d.ts +0 -23
- package/dist/cli/sparkshell.d.ts +0 -33
- package/dist/shared/sparkshell-awareness.d.ts +0 -5
- package/packages/omo-codex/plugin/components/rules/src/sparkshell-awareness.ts +0 -106
- package/packages/omo-codex/plugin/components/rules/test/sparkshell-awareness.test.ts +0 -355
|
@@ -0,0 +1,530 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
3
|
+
|
|
4
|
+
// packages/shared-skills/skills/visual-qa/scripts/cli.ts
|
|
5
|
+
import { readFileSync } from "node:fs";
|
|
6
|
+
|
|
7
|
+
// packages/shared-skills/skills/visual-qa/scripts/image-diff.ts
|
|
8
|
+
var GRID_SIZE = 8;
|
|
9
|
+
function round4(value) {
|
|
10
|
+
return Math.round(value * 1e4) / 1e4;
|
|
11
|
+
}
|
|
12
|
+
function pixelsDiffer(ref, refOffset, act, actOffset) {
|
|
13
|
+
return ref[refOffset] !== act[actOffset] || ref[refOffset + 1] !== act[actOffset + 1] || ref[refOffset + 2] !== act[actOffset + 2] || ref[refOffset + 3] !== act[actOffset + 3];
|
|
14
|
+
}
|
|
15
|
+
function buildHotspots(cellDiff, cellTotal, cols, rows, overlapWidth, overlapHeight) {
|
|
16
|
+
const hotspots = [];
|
|
17
|
+
for (let gridY = 0;gridY < rows; gridY++) {
|
|
18
|
+
for (let gridX = 0;gridX < cols; gridX++) {
|
|
19
|
+
const index = gridY * cols + gridX;
|
|
20
|
+
const diff = cellDiff[index] ?? 0;
|
|
21
|
+
const total = cellTotal[index] ?? 0;
|
|
22
|
+
if (diff === 0 || total === 0)
|
|
23
|
+
continue;
|
|
24
|
+
const left = Math.floor(gridX * overlapWidth / cols);
|
|
25
|
+
const right = Math.floor((gridX + 1) * overlapWidth / cols);
|
|
26
|
+
const top = Math.floor(gridY * overlapHeight / rows);
|
|
27
|
+
const bottom = Math.floor((gridY + 1) * overlapHeight / rows);
|
|
28
|
+
hotspots.push({
|
|
29
|
+
gridX,
|
|
30
|
+
gridY,
|
|
31
|
+
x: left,
|
|
32
|
+
y: top,
|
|
33
|
+
width: right - left,
|
|
34
|
+
height: bottom - top,
|
|
35
|
+
diffRatio: round4(diff / total)
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
hotspots.sort((a, b) => b.diffRatio - a.diffRatio);
|
|
40
|
+
return hotspots;
|
|
41
|
+
}
|
|
42
|
+
function buildSummary(similarityScore, diffPixels, totalPixels, dimensionsMatch, hotspotCount) {
|
|
43
|
+
const parts = [`${similarityScore}/100 similarity`, `${diffPixels}/${totalPixels} pixels differ`];
|
|
44
|
+
if (!dimensionsMatch)
|
|
45
|
+
parts.push("dimensions differ");
|
|
46
|
+
if (hotspotCount > 0)
|
|
47
|
+
parts.push(`${hotspotCount} hotspot region(s)`);
|
|
48
|
+
return `${parts.join("; ")}.`;
|
|
49
|
+
}
|
|
50
|
+
function diffImages(reference, actual) {
|
|
51
|
+
const overlapWidth = Math.min(reference.width, actual.width);
|
|
52
|
+
const overlapHeight = Math.min(reference.height, actual.height);
|
|
53
|
+
const totalPixels = overlapWidth * overlapHeight;
|
|
54
|
+
const cols = Math.max(1, Math.min(GRID_SIZE, overlapWidth));
|
|
55
|
+
const rows = Math.max(1, Math.min(GRID_SIZE, overlapHeight));
|
|
56
|
+
const cellDiff = new Array(cols * rows).fill(0);
|
|
57
|
+
const cellTotal = new Array(cols * rows).fill(0);
|
|
58
|
+
let diffPixels = 0;
|
|
59
|
+
for (let y = 0;y < overlapHeight; y++) {
|
|
60
|
+
const cellY = Math.min(rows - 1, Math.floor(y * rows / overlapHeight));
|
|
61
|
+
for (let x = 0;x < overlapWidth; x++) {
|
|
62
|
+
const cellX = Math.min(cols - 1, Math.floor(x * cols / overlapWidth));
|
|
63
|
+
const cellIndex = cellY * cols + cellX;
|
|
64
|
+
cellTotal[cellIndex] = (cellTotal[cellIndex] ?? 0) + 1;
|
|
65
|
+
const refOffset = (y * reference.width + x) * 4;
|
|
66
|
+
const actOffset = (y * actual.width + x) * 4;
|
|
67
|
+
if (pixelsDiffer(reference.rgba, refOffset, actual.rgba, actOffset)) {
|
|
68
|
+
diffPixels++;
|
|
69
|
+
cellDiff[cellIndex] = (cellDiff[cellIndex] ?? 0) + 1;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const diffRatio = totalPixels === 0 ? 0 : diffPixels / totalPixels;
|
|
74
|
+
const similarityScore = Math.round((1 - diffRatio) * 100);
|
|
75
|
+
const hotspots = buildHotspots(cellDiff, cellTotal, cols, rows, overlapWidth, overlapHeight);
|
|
76
|
+
const dimensionsMatch = reference.width === actual.width && reference.height === actual.height;
|
|
77
|
+
const alphaChannelIntact = !(reference.hasTransparentPixels && !actual.hasTransparentPixels);
|
|
78
|
+
return {
|
|
79
|
+
command: "image-diff",
|
|
80
|
+
dimensionsMatch,
|
|
81
|
+
reference: { width: reference.width, height: reference.height },
|
|
82
|
+
actual: { width: actual.width, height: actual.height },
|
|
83
|
+
totalPixels,
|
|
84
|
+
diffPixels,
|
|
85
|
+
diffRatio: round4(diffRatio),
|
|
86
|
+
similarityScore,
|
|
87
|
+
alphaChannelIntact,
|
|
88
|
+
hotspots,
|
|
89
|
+
summary: buildSummary(similarityScore, diffPixels, totalPixels, dimensionsMatch, hotspots.length)
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// packages/shared-skills/skills/visual-qa/scripts/png-decode.ts
|
|
94
|
+
import { Buffer as Buffer2 } from "node:buffer";
|
|
95
|
+
import { inflateSync } from "node:zlib";
|
|
96
|
+
|
|
97
|
+
// packages/shared-skills/skills/visual-qa/scripts/png-crc.ts
|
|
98
|
+
import { Buffer } from "node:buffer";
|
|
99
|
+
var PNG_SIGNATURE = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);
|
|
100
|
+
function buildCrcTable() {
|
|
101
|
+
const table = new Uint32Array(256);
|
|
102
|
+
for (let n = 0;n < 256; n++) {
|
|
103
|
+
let c = n;
|
|
104
|
+
for (let k = 0;k < 8; k++) {
|
|
105
|
+
c = (c & 1) === 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
|
|
106
|
+
}
|
|
107
|
+
table[n] = c >>> 0;
|
|
108
|
+
}
|
|
109
|
+
return table;
|
|
110
|
+
}
|
|
111
|
+
var CRC_TABLE = buildCrcTable();
|
|
112
|
+
|
|
113
|
+
// packages/shared-skills/skills/visual-qa/scripts/png-decode.ts
|
|
114
|
+
class PngDecodeError extends Error {
|
|
115
|
+
name = "PngDecodeError";
|
|
116
|
+
}
|
|
117
|
+
function readChunks(buffer) {
|
|
118
|
+
const chunks = [];
|
|
119
|
+
let offset = 8;
|
|
120
|
+
while (offset + 8 <= buffer.length) {
|
|
121
|
+
const length = buffer.readUInt32BE(offset);
|
|
122
|
+
const type = buffer.toString("ascii", offset + 4, offset + 8);
|
|
123
|
+
const dataStart = offset + 8;
|
|
124
|
+
const dataEnd = dataStart + length;
|
|
125
|
+
if (dataEnd + 4 > buffer.length)
|
|
126
|
+
break;
|
|
127
|
+
chunks.push({ type, data: buffer.subarray(dataStart, dataEnd) });
|
|
128
|
+
offset = dataEnd + 4;
|
|
129
|
+
}
|
|
130
|
+
return chunks;
|
|
131
|
+
}
|
|
132
|
+
function channelsForColorType(colorType) {
|
|
133
|
+
switch (colorType) {
|
|
134
|
+
case 0:
|
|
135
|
+
return 1;
|
|
136
|
+
case 2:
|
|
137
|
+
return 3;
|
|
138
|
+
case 4:
|
|
139
|
+
return 2;
|
|
140
|
+
case 6:
|
|
141
|
+
return 4;
|
|
142
|
+
default:
|
|
143
|
+
throw new PngDecodeError(`unsupported color type ${colorType}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function parseHeader(data) {
|
|
147
|
+
if (data.length < 13) {
|
|
148
|
+
throw new PngDecodeError("invalid IHDR chunk length");
|
|
149
|
+
}
|
|
150
|
+
const colorType = data[9] ?? 0;
|
|
151
|
+
return {
|
|
152
|
+
width: data.readUInt32BE(0),
|
|
153
|
+
height: data.readUInt32BE(4),
|
|
154
|
+
bitDepth: data[8] ?? 0,
|
|
155
|
+
colorType,
|
|
156
|
+
channels: channelsForColorType(colorType)
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function paeth(a, b, c) {
|
|
160
|
+
const p = a + b - c;
|
|
161
|
+
const pa = Math.abs(p - a);
|
|
162
|
+
const pb = Math.abs(p - b);
|
|
163
|
+
const pc = Math.abs(p - c);
|
|
164
|
+
if (pa <= pb && pa <= pc)
|
|
165
|
+
return a;
|
|
166
|
+
if (pb <= pc)
|
|
167
|
+
return b;
|
|
168
|
+
return c;
|
|
169
|
+
}
|
|
170
|
+
function unfilterRow(filterType, row, prev, bpp) {
|
|
171
|
+
const out = Buffer2.alloc(row.length);
|
|
172
|
+
for (let i = 0;i < row.length; i++) {
|
|
173
|
+
const raw = row[i] ?? 0;
|
|
174
|
+
const a = i >= bpp ? out[i - bpp] ?? 0 : 0;
|
|
175
|
+
const b = prev ? prev[i] ?? 0 : 0;
|
|
176
|
+
const c = i >= bpp && prev ? prev[i - bpp] ?? 0 : 0;
|
|
177
|
+
switch (filterType) {
|
|
178
|
+
case 0:
|
|
179
|
+
out[i] = raw;
|
|
180
|
+
break;
|
|
181
|
+
case 1:
|
|
182
|
+
out[i] = raw + a & 255;
|
|
183
|
+
break;
|
|
184
|
+
case 2:
|
|
185
|
+
out[i] = raw + b & 255;
|
|
186
|
+
break;
|
|
187
|
+
case 3:
|
|
188
|
+
out[i] = raw + (a + b >> 1) & 255;
|
|
189
|
+
break;
|
|
190
|
+
case 4:
|
|
191
|
+
out[i] = raw + paeth(a, b, c) & 255;
|
|
192
|
+
break;
|
|
193
|
+
default:
|
|
194
|
+
throw new PngDecodeError(`unsupported filter type ${filterType}`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return out;
|
|
198
|
+
}
|
|
199
|
+
function decodePixels(idat, width, height, bpp) {
|
|
200
|
+
const inflated = inflateSync(idat);
|
|
201
|
+
const rowBytes = width * bpp;
|
|
202
|
+
if (inflated.length < height * (rowBytes + 1)) {
|
|
203
|
+
throw new PngDecodeError("truncated image data");
|
|
204
|
+
}
|
|
205
|
+
const pixels = Buffer2.alloc(width * height * bpp);
|
|
206
|
+
let prev = null;
|
|
207
|
+
for (let y = 0;y < height; y++) {
|
|
208
|
+
const rowStart = y * (rowBytes + 1);
|
|
209
|
+
const filterType = inflated[rowStart] ?? 0;
|
|
210
|
+
const filtered = inflated.subarray(rowStart + 1, rowStart + 1 + rowBytes);
|
|
211
|
+
const row = unfilterRow(filterType, filtered, prev, bpp);
|
|
212
|
+
row.copy(pixels, y * rowBytes);
|
|
213
|
+
prev = row;
|
|
214
|
+
}
|
|
215
|
+
return pixels;
|
|
216
|
+
}
|
|
217
|
+
function normalizeToRgba(pixels, pixelCount, channels) {
|
|
218
|
+
const rgba = new Uint8Array(pixelCount * 4);
|
|
219
|
+
let hasTransparent = false;
|
|
220
|
+
for (let i = 0;i < pixelCount; i++) {
|
|
221
|
+
const src = i * channels;
|
|
222
|
+
let r = 0;
|
|
223
|
+
let g = 0;
|
|
224
|
+
let b = 0;
|
|
225
|
+
let a = 255;
|
|
226
|
+
switch (channels) {
|
|
227
|
+
case 1: {
|
|
228
|
+
const v = pixels[src] ?? 0;
|
|
229
|
+
r = v;
|
|
230
|
+
g = v;
|
|
231
|
+
b = v;
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
case 2: {
|
|
235
|
+
const v = pixels[src] ?? 0;
|
|
236
|
+
r = v;
|
|
237
|
+
g = v;
|
|
238
|
+
b = v;
|
|
239
|
+
a = pixels[src + 1] ?? 255;
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
case 3: {
|
|
243
|
+
r = pixels[src] ?? 0;
|
|
244
|
+
g = pixels[src + 1] ?? 0;
|
|
245
|
+
b = pixels[src + 2] ?? 0;
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
default: {
|
|
249
|
+
r = pixels[src] ?? 0;
|
|
250
|
+
g = pixels[src + 1] ?? 0;
|
|
251
|
+
b = pixels[src + 2] ?? 0;
|
|
252
|
+
a = pixels[src + 3] ?? 255;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
const dst = i * 4;
|
|
256
|
+
rgba[dst] = r;
|
|
257
|
+
rgba[dst + 1] = g;
|
|
258
|
+
rgba[dst + 2] = b;
|
|
259
|
+
rgba[dst + 3] = a;
|
|
260
|
+
if (a < 255)
|
|
261
|
+
hasTransparent = true;
|
|
262
|
+
}
|
|
263
|
+
return { rgba, hasTransparent };
|
|
264
|
+
}
|
|
265
|
+
function decodePng(buffer) {
|
|
266
|
+
if (buffer.length < 8 || !buffer.subarray(0, 8).equals(PNG_SIGNATURE)) {
|
|
267
|
+
throw new PngDecodeError("not a PNG file (bad signature)");
|
|
268
|
+
}
|
|
269
|
+
const chunks = readChunks(buffer);
|
|
270
|
+
const ihdr = chunks.find((chunk) => chunk.type === "IHDR");
|
|
271
|
+
if (ihdr === undefined) {
|
|
272
|
+
throw new PngDecodeError("missing IHDR chunk");
|
|
273
|
+
}
|
|
274
|
+
const header = parseHeader(ihdr.data);
|
|
275
|
+
if (header.bitDepth !== 8) {
|
|
276
|
+
throw new PngDecodeError(`unsupported bit depth ${header.bitDepth}`);
|
|
277
|
+
}
|
|
278
|
+
const idatChunks = chunks.filter((chunk) => chunk.type === "IDAT");
|
|
279
|
+
if (idatChunks.length === 0) {
|
|
280
|
+
throw new PngDecodeError("missing IDAT chunk");
|
|
281
|
+
}
|
|
282
|
+
const idat = Buffer2.concat(idatChunks.map((chunk) => chunk.data));
|
|
283
|
+
const pixels = decodePixels(idat, header.width, header.height, header.channels);
|
|
284
|
+
const normalized = normalizeToRgba(pixels, header.width * header.height, header.channels);
|
|
285
|
+
return {
|
|
286
|
+
width: header.width,
|
|
287
|
+
height: header.height,
|
|
288
|
+
rgba: normalized.rgba,
|
|
289
|
+
hasAlphaChannel: header.colorType === 4 || header.colorType === 6,
|
|
290
|
+
hasTransparentPixels: normalized.hasTransparent
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// packages/shared-skills/skills/visual-qa/scripts/ansi.ts
|
|
295
|
+
var ESC = String.fromCharCode(27);
|
|
296
|
+
var CSI = String.fromCharCode(155);
|
|
297
|
+
var ANSI_PATTERN = new RegExp(`[${ESC}${CSI}][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]`, "g");
|
|
298
|
+
function stripAnsi(input) {
|
|
299
|
+
return input.replace(ANSI_PATTERN, "");
|
|
300
|
+
}
|
|
301
|
+
function hasAnsi(input) {
|
|
302
|
+
return stripAnsi(input) !== input;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// packages/shared-skills/skills/visual-qa/scripts/east-asian-width.ts
|
|
306
|
+
var ZERO_WIDTH_RANGES = [
|
|
307
|
+
{ start: 768, end: 879 },
|
|
308
|
+
{ start: 1155, end: 1161 },
|
|
309
|
+
{ start: 1425, end: 1469 },
|
|
310
|
+
{ start: 1552, end: 1562 },
|
|
311
|
+
{ start: 1611, end: 1631 },
|
|
312
|
+
{ start: 1648, end: 1648 },
|
|
313
|
+
{ start: 1750, end: 1756 },
|
|
314
|
+
{ start: 4448, end: 4607 },
|
|
315
|
+
{ start: 8203, end: 8207 },
|
|
316
|
+
{ start: 8234, end: 8238 },
|
|
317
|
+
{ start: 8288, end: 8292 },
|
|
318
|
+
{ start: 8400, end: 8447 },
|
|
319
|
+
{ start: 65056, end: 65071 },
|
|
320
|
+
{ start: 65279, end: 65279 }
|
|
321
|
+
];
|
|
322
|
+
var WIDE_RANGES = [
|
|
323
|
+
{ start: 4352, end: 4447 },
|
|
324
|
+
{ start: 8986, end: 8987 },
|
|
325
|
+
{ start: 11904, end: 12350 },
|
|
326
|
+
{ start: 12353, end: 13311 },
|
|
327
|
+
{ start: 13312, end: 19903 },
|
|
328
|
+
{ start: 19968, end: 40959 },
|
|
329
|
+
{ start: 40960, end: 42191 },
|
|
330
|
+
{ start: 43360, end: 43391 },
|
|
331
|
+
{ start: 44032, end: 55203 },
|
|
332
|
+
{ start: 63744, end: 64255 },
|
|
333
|
+
{ start: 65040, end: 65049 },
|
|
334
|
+
{ start: 65072, end: 65135 },
|
|
335
|
+
{ start: 65280, end: 65376 },
|
|
336
|
+
{ start: 65504, end: 65510 },
|
|
337
|
+
{ start: 110592, end: 110959 },
|
|
338
|
+
{ start: 127488, end: 127743 },
|
|
339
|
+
{ start: 127744, end: 129791 },
|
|
340
|
+
{ start: 131072, end: 262141 }
|
|
341
|
+
];
|
|
342
|
+
function inRanges(codePoint, ranges) {
|
|
343
|
+
for (const range of ranges) {
|
|
344
|
+
if (codePoint >= range.start && codePoint <= range.end) {
|
|
345
|
+
return true;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
return false;
|
|
349
|
+
}
|
|
350
|
+
function charWidth(codePoint) {
|
|
351
|
+
if (codePoint === 0)
|
|
352
|
+
return 0;
|
|
353
|
+
if (codePoint < 32)
|
|
354
|
+
return 0;
|
|
355
|
+
if (codePoint >= 127 && codePoint <= 159)
|
|
356
|
+
return 0;
|
|
357
|
+
if (inRanges(codePoint, ZERO_WIDTH_RANGES))
|
|
358
|
+
return 0;
|
|
359
|
+
if (inRanges(codePoint, WIDE_RANGES))
|
|
360
|
+
return 2;
|
|
361
|
+
return 1;
|
|
362
|
+
}
|
|
363
|
+
function stringWidth(text) {
|
|
364
|
+
let total = 0;
|
|
365
|
+
for (const char of text) {
|
|
366
|
+
const codePoint = char.codePointAt(0);
|
|
367
|
+
if (codePoint === undefined)
|
|
368
|
+
continue;
|
|
369
|
+
total += charWidth(codePoint);
|
|
370
|
+
}
|
|
371
|
+
return total;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// packages/shared-skills/skills/visual-qa/scripts/tui-grid.ts
|
|
375
|
+
var BOX_DRAWING_START = 9472;
|
|
376
|
+
var BOX_DRAWING_END = 9599;
|
|
377
|
+
var MAX_WIDE_COLUMNS = 64;
|
|
378
|
+
function splitLines(text) {
|
|
379
|
+
const lines = text.split(/\r?\n/);
|
|
380
|
+
if (lines.length > 1 && lines[lines.length - 1] === "")
|
|
381
|
+
lines.pop();
|
|
382
|
+
return lines;
|
|
383
|
+
}
|
|
384
|
+
function isFrameLine(plain) {
|
|
385
|
+
for (const char of plain) {
|
|
386
|
+
const codePoint = char.codePointAt(0);
|
|
387
|
+
if (codePoint !== undefined && codePoint >= BOX_DRAWING_START && codePoint <= BOX_DRAWING_END) {
|
|
388
|
+
return true;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
return false;
|
|
392
|
+
}
|
|
393
|
+
function wideStartColumns(plain) {
|
|
394
|
+
const columns = [];
|
|
395
|
+
let column = 0;
|
|
396
|
+
for (const char of plain) {
|
|
397
|
+
const codePoint = char.codePointAt(0);
|
|
398
|
+
if (codePoint === undefined)
|
|
399
|
+
continue;
|
|
400
|
+
const width = charWidth(codePoint);
|
|
401
|
+
if (width === 2)
|
|
402
|
+
columns.push(column);
|
|
403
|
+
column += width;
|
|
404
|
+
}
|
|
405
|
+
return columns;
|
|
406
|
+
}
|
|
407
|
+
function summarize(lineCount, maxWidth, expectedColumns, overflowCount, borderMisaligned, containsAnsi) {
|
|
408
|
+
const parts = [`${lineCount} line(s)`, `max width ${maxWidth}/${expectedColumns}`];
|
|
409
|
+
if (overflowCount > 0)
|
|
410
|
+
parts.push(`${overflowCount} overflow line(s)`);
|
|
411
|
+
if (borderMisaligned)
|
|
412
|
+
parts.push("borders misaligned");
|
|
413
|
+
if (containsAnsi)
|
|
414
|
+
parts.push("contains ANSI");
|
|
415
|
+
return `${parts.join("; ")}.`;
|
|
416
|
+
}
|
|
417
|
+
function checkTui(text, expectedColumns) {
|
|
418
|
+
const lines = splitLines(text);
|
|
419
|
+
const lineWidths = [];
|
|
420
|
+
const overflowLines = [];
|
|
421
|
+
const wideColumns = new Set;
|
|
422
|
+
const frameWidths = new Set;
|
|
423
|
+
for (let index = 0;index < lines.length; index++) {
|
|
424
|
+
const plain = stripAnsi(lines[index] ?? "");
|
|
425
|
+
const width = stringWidth(plain);
|
|
426
|
+
lineWidths.push(width);
|
|
427
|
+
if (expectedColumns > 0 && width > expectedColumns) {
|
|
428
|
+
overflowLines.push({ line: index + 1, width });
|
|
429
|
+
}
|
|
430
|
+
if (isFrameLine(plain))
|
|
431
|
+
frameWidths.add(width);
|
|
432
|
+
for (const column of wideStartColumns(plain)) {
|
|
433
|
+
if (wideColumns.size < MAX_WIDE_COLUMNS)
|
|
434
|
+
wideColumns.add(column);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
const maxWidth = lineWidths.reduce((max, width) => width > max ? width : max, 0);
|
|
438
|
+
const borderMisaligned = frameWidths.size > 1;
|
|
439
|
+
const containsAnsi = hasAnsi(text);
|
|
440
|
+
return {
|
|
441
|
+
command: "tui-check",
|
|
442
|
+
expectedColumns,
|
|
443
|
+
lineCount: lines.length,
|
|
444
|
+
lineWidths,
|
|
445
|
+
maxWidth,
|
|
446
|
+
overflowLines,
|
|
447
|
+
borderMisaligned,
|
|
448
|
+
wideCharColumns: [...wideColumns].sort((a, b) => a - b),
|
|
449
|
+
hasAnsi: containsAnsi,
|
|
450
|
+
summary: summarize(lines.length, maxWidth, expectedColumns, overflowLines.length, borderMisaligned, containsAnsi)
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// packages/shared-skills/skills/visual-qa/scripts/cli.ts
|
|
455
|
+
class CliError extends Error {
|
|
456
|
+
name = "CliError";
|
|
457
|
+
}
|
|
458
|
+
var DEFAULT_COLUMNS = 80;
|
|
459
|
+
var COLS_FLAG = "--cols";
|
|
460
|
+
function runImageDiff(args) {
|
|
461
|
+
const referencePath = args[0];
|
|
462
|
+
const actualPath = args[1];
|
|
463
|
+
if (referencePath === undefined || actualPath === undefined) {
|
|
464
|
+
throw new CliError("usage: image-diff <reference.png> <actual.png>");
|
|
465
|
+
}
|
|
466
|
+
const reference = decodePng(readFileSync(referencePath));
|
|
467
|
+
const actual = decodePng(readFileSync(actualPath));
|
|
468
|
+
return diffImages(reference, actual);
|
|
469
|
+
}
|
|
470
|
+
function parseColumns(args) {
|
|
471
|
+
for (let index = 0;index < args.length; index++) {
|
|
472
|
+
const arg = args[index] ?? "";
|
|
473
|
+
if (arg === COLS_FLAG) {
|
|
474
|
+
const parsed = Number(args[index + 1]);
|
|
475
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
476
|
+
throw new CliError(`${COLS_FLAG} requires a positive integer`);
|
|
477
|
+
}
|
|
478
|
+
return parsed;
|
|
479
|
+
}
|
|
480
|
+
if (arg.startsWith(`${COLS_FLAG}=`)) {
|
|
481
|
+
const parsed = Number(arg.slice(COLS_FLAG.length + 1));
|
|
482
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
483
|
+
throw new CliError(`${COLS_FLAG} requires a positive integer`);
|
|
484
|
+
}
|
|
485
|
+
return parsed;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
return DEFAULT_COLUMNS;
|
|
489
|
+
}
|
|
490
|
+
function runTuiCheck(args) {
|
|
491
|
+
const capturePath = args[0];
|
|
492
|
+
if (capturePath === undefined || capturePath.startsWith("--")) {
|
|
493
|
+
throw new CliError("usage: tui-check <capture.txt> [--cols N]");
|
|
494
|
+
}
|
|
495
|
+
const text = readFileSync(capturePath, "utf8");
|
|
496
|
+
return checkTui(text, parseColumns(args.slice(1)));
|
|
497
|
+
}
|
|
498
|
+
function run(argv) {
|
|
499
|
+
const command = argv[0];
|
|
500
|
+
const rest = argv.slice(1);
|
|
501
|
+
switch (command) {
|
|
502
|
+
case "image-diff":
|
|
503
|
+
return runImageDiff(rest);
|
|
504
|
+
case "tui-check":
|
|
505
|
+
return runTuiCheck(rest);
|
|
506
|
+
default:
|
|
507
|
+
throw new CliError(`unknown command "${command ?? ""}"; expected "image-diff" or "tui-check"`);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
function main(argv) {
|
|
511
|
+
try {
|
|
512
|
+
const result = run(argv);
|
|
513
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}
|
|
514
|
+
`);
|
|
515
|
+
} catch (error) {
|
|
516
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
517
|
+
process.stderr.write(`visual-qa error: ${message}
|
|
518
|
+
`);
|
|
519
|
+
process.exitCode = 1;
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
if (__require.main == __require.module) {
|
|
523
|
+
main(process.argv.slice(2));
|
|
524
|
+
}
|
|
525
|
+
export {
|
|
526
|
+
runTuiCheck,
|
|
527
|
+
runImageDiff,
|
|
528
|
+
run,
|
|
529
|
+
CliError
|
|
530
|
+
};
|
|
@@ -10,6 +10,7 @@ type ResolveSkillContentOptions = {
|
|
|
10
10
|
targetAgent?: string;
|
|
11
11
|
nativeSkills?: DelegateTaskToolOptions["nativeSkills"];
|
|
12
12
|
nativeSkillEntries?: NativeSkillEntry[];
|
|
13
|
+
getLoadedSkills?: DelegateTaskToolOptions["getLoadedSkills"];
|
|
13
14
|
};
|
|
14
15
|
export declare function resolveSkillContent(skills: string[], options: ResolveSkillContentOptions): Promise<{
|
|
15
16
|
content: string | undefined;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { BackgroundManager } from "../../features/background-agent";
|
|
2
2
|
import type { CategoriesConfig, GitMasterConfig, BrowserAutomationProvider, AgentOverrides, SisyphusAgentConfig } from "../../config/schema";
|
|
3
3
|
import type { ModelFallbackControllerAccessor } from "../../hooks/model-fallback";
|
|
4
|
+
import type { LoadedSkill } from "../../features/opencode-skill-loader/types";
|
|
4
5
|
import type { SessionPromptAsyncData, SessionPromptData, SessionStatusData } from "@opencode-ai/sdk";
|
|
5
6
|
import type { AvailableCategory, AvailableSkill } from "../../agents/dynamic-agent-prompt-builder";
|
|
6
7
|
type SessionPathInput = {
|
|
@@ -148,6 +149,7 @@ export interface DelegateTaskToolOptions {
|
|
|
148
149
|
} | undefined>;
|
|
149
150
|
dirs(): string[] | Promise<string[]>;
|
|
150
151
|
};
|
|
152
|
+
getLoadedSkills?: () => Promise<LoadedSkill[]>;
|
|
151
153
|
}
|
|
152
154
|
import type { DelegatedModelConfig } from "../../shared/model-resolution-types";
|
|
153
155
|
export type { DelegatedModelConfig };
|
|
@@ -21,6 +21,7 @@ export interface SkillLoadOptions {
|
|
|
21
21
|
opencodeOnly?: boolean;
|
|
22
22
|
/** Pre-merged skills to use instead of discovering */
|
|
23
23
|
skills?: LoadedSkill[];
|
|
24
|
+
getLoadedSkills?: () => Promise<LoadedSkill[]>;
|
|
24
25
|
/** Pre-discovered commands to use instead of discovering */
|
|
25
26
|
commands?: CommandInfo[];
|
|
26
27
|
/** MCP manager for querying skill-embedded MCP servers */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oh-my-opencode",
|
|
3
|
-
"version": "4.14.
|
|
3
|
+
"version": "4.14.2",
|
|
4
4
|
"description": "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -65,7 +65,20 @@
|
|
|
65
65
|
"packages/omo-codex/marketplace.json",
|
|
66
66
|
"packages/omo-codex/lazycodex-repository",
|
|
67
67
|
"packages/omo-codex/plugin",
|
|
68
|
+
"packages/omo-codex/plugin/components/bootstrap/dist/cli.js",
|
|
69
|
+
"packages/omo-codex/plugin/components/bootstrap/scripts/bootstrap.ps1",
|
|
70
|
+
"packages/omo-codex/plugin/components/bootstrap/scripts/node-dispatch.ps1",
|
|
71
|
+
"packages/omo-codex/plugin/components/codegraph/dist/cli.js",
|
|
72
|
+
"packages/omo-codex/plugin/components/codegraph/dist/serve.js",
|
|
73
|
+
"packages/omo-codex/plugin/components/comment-checker/dist/cli.js",
|
|
74
|
+
"packages/omo-codex/plugin/components/git-bash/dist/cli.js",
|
|
75
|
+
"packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js",
|
|
76
|
+
"packages/omo-codex/plugin/components/lsp/dist/cli.js",
|
|
77
|
+
"packages/omo-codex/plugin/components/rules/dist/cli.js",
|
|
68
78
|
"packages/omo-codex/plugin/components/start-work-continuation/dist/cli.js",
|
|
79
|
+
"packages/omo-codex/plugin/components/teammode/dist/cli.js",
|
|
80
|
+
"packages/omo-codex/plugin/components/telemetry/dist/cli.js",
|
|
81
|
+
"packages/omo-codex/plugin/components/ultrawork/dist/cli.js",
|
|
69
82
|
"packages/omo-codex/plugin/components/ulw-loop/dist/cli.js",
|
|
70
83
|
"packages/omo-codex/plugin/.codex-plugin",
|
|
71
84
|
"!packages/omo-codex/plugin/node_modules",
|
|
@@ -178,18 +191,18 @@
|
|
|
178
191
|
"typescript": "^6.0.3"
|
|
179
192
|
},
|
|
180
193
|
"optionalDependencies": {
|
|
181
|
-
"oh-my-opencode-darwin-arm64": "4.14.
|
|
182
|
-
"oh-my-opencode-darwin-x64": "4.14.
|
|
183
|
-
"oh-my-opencode-darwin-x64-baseline": "4.14.
|
|
184
|
-
"oh-my-opencode-linux-arm64": "4.14.
|
|
185
|
-
"oh-my-opencode-linux-arm64-musl": "4.14.
|
|
186
|
-
"oh-my-opencode-linux-x64": "4.14.
|
|
187
|
-
"oh-my-opencode-linux-x64-baseline": "4.14.
|
|
188
|
-
"oh-my-opencode-linux-x64-musl": "4.14.
|
|
189
|
-
"oh-my-opencode-linux-x64-musl-baseline": "4.14.
|
|
190
|
-
"oh-my-opencode-windows-arm64": "4.14.
|
|
191
|
-
"oh-my-opencode-windows-x64": "4.14.
|
|
192
|
-
"oh-my-opencode-windows-x64-baseline": "4.14.
|
|
194
|
+
"oh-my-opencode-darwin-arm64": "4.14.2",
|
|
195
|
+
"oh-my-opencode-darwin-x64": "4.14.2",
|
|
196
|
+
"oh-my-opencode-darwin-x64-baseline": "4.14.2",
|
|
197
|
+
"oh-my-opencode-linux-arm64": "4.14.2",
|
|
198
|
+
"oh-my-opencode-linux-arm64-musl": "4.14.2",
|
|
199
|
+
"oh-my-opencode-linux-x64": "4.14.2",
|
|
200
|
+
"oh-my-opencode-linux-x64-baseline": "4.14.2",
|
|
201
|
+
"oh-my-opencode-linux-x64-musl": "4.14.2",
|
|
202
|
+
"oh-my-opencode-linux-x64-musl-baseline": "4.14.2",
|
|
203
|
+
"oh-my-opencode-windows-arm64": "4.14.2",
|
|
204
|
+
"oh-my-opencode-windows-x64": "4.14.2",
|
|
205
|
+
"oh-my-opencode-windows-x64-baseline": "4.14.2"
|
|
193
206
|
},
|
|
194
207
|
"overrides": {
|
|
195
208
|
"hono": "^4.12.18",
|
|
@@ -381,6 +381,8 @@ async function runMcpStdioServer(input, output, options = {}) {
|
|
|
381
381
|
output,
|
|
382
382
|
handler: handleGitBashMcpRequest,
|
|
383
383
|
handlerOptions: options,
|
|
384
|
+
idleTimeoutMs: 0,
|
|
385
|
+
log: options.lifecycleLog,
|
|
384
386
|
parseErrorResponse: () => errorResponse(null, -32601, "Method not found")
|
|
385
387
|
});
|
|
386
388
|
}
|
|
@@ -3405,6 +3405,7 @@ function unlinkQuietly(path) {
|
|
|
3405
3405
|
var PROBE_TIMEOUT_MS = 500;
|
|
3406
3406
|
var DEFAULT_READY_TIMEOUT_MS = 5000;
|
|
3407
3407
|
var DEFAULT_POLL_INTERVAL_MS = 100;
|
|
3408
|
+
var CODEX_LSP_DAEMON_CLI_ENV = "CODEX_LSP_DAEMON_CLI";
|
|
3408
3409
|
|
|
3409
3410
|
class DaemonUnreachableError extends Error {
|
|
3410
3411
|
constructor(socketPath) {
|
|
@@ -3465,7 +3466,7 @@ function spawnDaemonProcess(paths) {
|
|
|
3465
3466
|
mkdirSync3(dirname5(paths.log), { recursive: true });
|
|
3466
3467
|
const logFd = openSync2(paths.log, "a");
|
|
3467
3468
|
try {
|
|
3468
|
-
const cliPath =
|
|
3469
|
+
const cliPath = resolveDaemonCliPath();
|
|
3469
3470
|
const child = spawn2(execPath, [cliPath, "daemon"], {
|
|
3470
3471
|
detached: true,
|
|
3471
3472
|
stdio: ["ignore", logFd, logFd]
|
|
@@ -3475,6 +3476,12 @@ function spawnDaemonProcess(paths) {
|
|
|
3475
3476
|
closeSync2(logFd);
|
|
3476
3477
|
}
|
|
3477
3478
|
}
|
|
3479
|
+
function resolveDaemonCliPath(env = process.env) {
|
|
3480
|
+
const override = env[CODEX_LSP_DAEMON_CLI_ENV]?.trim();
|
|
3481
|
+
if (override)
|
|
3482
|
+
return override;
|
|
3483
|
+
return fileURLToPath3(new URL("./cli.js", import.meta.url));
|
|
3484
|
+
}
|
|
3478
3485
|
function defaultEnsureDaemonDeps() {
|
|
3479
3486
|
return {
|
|
3480
3487
|
probe: (socketPath) => probeSocket(socketPath),
|
|
@@ -3485,8 +3492,7 @@ function defaultEnsureDaemonDeps() {
|
|
|
3485
3492
|
},
|
|
3486
3493
|
spawnDaemon: (paths) => spawnDaemonProcess(paths),
|
|
3487
3494
|
sleep: (ms) => new Promise((resolve6) => {
|
|
3488
|
-
|
|
3489
|
-
timer.unref?.();
|
|
3495
|
+
setTimeout(resolve6, ms);
|
|
3490
3496
|
}),
|
|
3491
3497
|
now: () => Date.now()
|
|
3492
3498
|
};
|
|
@@ -3499,6 +3505,7 @@ import { homedir as homedir3, tmpdir } from "node:os";
|
|
|
3499
3505
|
import { join as join8 } from "node:path";
|
|
3500
3506
|
var requireFromHere = createRequire(import.meta.url);
|
|
3501
3507
|
var MAX_SOCKET_PATH_LENGTH = 100;
|
|
3508
|
+
var CODEX_LSP_DAEMON_VERSION_ENV = "CODEX_LSP_DAEMON_VERSION";
|
|
3502
3509
|
function resolveDaemonVersion(requireFn = requireFromHere) {
|
|
3503
3510
|
for (const candidate of ["./package.json", "../package.json"]) {
|
|
3504
3511
|
try {
|
|
@@ -3520,7 +3527,7 @@ function daemonBaseDir(env = process.env) {
|
|
|
3520
3527
|
const home = codexHome && codexHome.length > 0 ? codexHome : join8(homedir3(), ".codex");
|
|
3521
3528
|
return join8(home, "codex-lsp", "daemon");
|
|
3522
3529
|
}
|
|
3523
|
-
function daemonPaths(env = process.env, version = resolveDaemonVersion()) {
|
|
3530
|
+
function daemonPaths(env = process.env, version = resolveDaemonVersionFromEnv(env) ?? resolveDaemonVersion()) {
|
|
3524
3531
|
const dir = join8(daemonBaseDir(env), `v${version}`);
|
|
3525
3532
|
return {
|
|
3526
3533
|
version,
|
|
@@ -3531,6 +3538,10 @@ function daemonPaths(env = process.env, version = resolveDaemonVersion()) {
|
|
|
3531
3538
|
log: join8(dir, "daemon.log")
|
|
3532
3539
|
};
|
|
3533
3540
|
}
|
|
3541
|
+
function resolveDaemonVersionFromEnv(env = process.env) {
|
|
3542
|
+
const version = env[CODEX_LSP_DAEMON_VERSION_ENV]?.trim();
|
|
3543
|
+
return version && version.length > 0 ? version : null;
|
|
3544
|
+
}
|
|
3534
3545
|
function resolveSocketPath(dir, version) {
|
|
3535
3546
|
const digest = createHash("sha256").update(dir).digest("hex").slice(0, 16);
|
|
3536
3547
|
if (process.platform === "win32") {
|