@liberseek/boft-cli-win32-arm64 0.6.4 → 0.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/app/codexhost-distribution.json +1 -1
- package/app/host-runtime.mjs +508 -242
- package/app/plugins/antigravity/plugin.mjs +9 -7
- package/app/plugins/claude-code/plugin.mjs +664 -229
- package/app/plugins/deepseek-harness/plugin.mjs +7797 -10553
- package/app/plugins/grok/plugin.mjs +48 -24
- package/app/plugins/kiro-cli/plugin.mjs +77 -61
- package/app/plugins/omp/plugin.mjs +6 -0
- package/app/plugins/opencode/plugin.mjs +292 -142
- package/app/plugins/pi/plugin.mjs +1489 -1304
- package/app/renderer-extension.js +812 -449
- package/bin/{codexhost.exe → boft.exe} +0 -0
- package/libexec/{codexhost-node-repl.exe → boft-node-repl.exe} +0 -0
- package/libexec/{codexhost-shim.exe → boft-shim.exe} +0 -0
- package/libexec/{codexhost-updater.exe → boft-updater.exe} +0 -0
- package/package.json +1 -1
|
@@ -7,8 +7,8 @@ var __export = (target, all) => {
|
|
|
7
7
|
|
|
8
8
|
// dist/opencode-adapter.js
|
|
9
9
|
import { randomUUID } from "node:crypto";
|
|
10
|
-
import
|
|
11
|
-
import
|
|
10
|
+
import fs3 from "node:fs";
|
|
11
|
+
import path5 from "node:path";
|
|
12
12
|
|
|
13
13
|
// ../../../node_modules/zod/v4/classic/external.js
|
|
14
14
|
var external_exports = {};
|
|
@@ -776,10 +776,10 @@ function mergeDefs(...defs) {
|
|
|
776
776
|
function cloneDef(schema) {
|
|
777
777
|
return mergeDefs(schema._zod.def);
|
|
778
778
|
}
|
|
779
|
-
function getElementAtPath(obj,
|
|
780
|
-
if (!
|
|
779
|
+
function getElementAtPath(obj, path6) {
|
|
780
|
+
if (!path6)
|
|
781
781
|
return obj;
|
|
782
|
-
return
|
|
782
|
+
return path6.reduce((acc, key) => acc?.[key], obj);
|
|
783
783
|
}
|
|
784
784
|
function promiseAllObject(promisesObj) {
|
|
785
785
|
const keys = Object.keys(promisesObj);
|
|
@@ -1188,11 +1188,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
1188
1188
|
}
|
|
1189
1189
|
return false;
|
|
1190
1190
|
}
|
|
1191
|
-
function prefixIssues(
|
|
1191
|
+
function prefixIssues(path6, issues) {
|
|
1192
1192
|
return issues.map((iss) => {
|
|
1193
1193
|
var _a3;
|
|
1194
1194
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
1195
|
-
iss.path.unshift(
|
|
1195
|
+
iss.path.unshift(path6);
|
|
1196
1196
|
return iss;
|
|
1197
1197
|
});
|
|
1198
1198
|
}
|
|
@@ -1339,16 +1339,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1339
1339
|
}
|
|
1340
1340
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
1341
1341
|
const fieldErrors = { _errors: [] };
|
|
1342
|
-
const processError = (error52,
|
|
1342
|
+
const processError = (error52, path6 = []) => {
|
|
1343
1343
|
for (const issue2 of error52.issues) {
|
|
1344
1344
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1345
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1345
|
+
issue2.errors.map((issues) => processError({ issues }, [...path6, ...issue2.path]));
|
|
1346
1346
|
} else if (issue2.code === "invalid_key") {
|
|
1347
|
-
processError({ issues: issue2.issues }, [...
|
|
1347
|
+
processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
|
|
1348
1348
|
} else if (issue2.code === "invalid_element") {
|
|
1349
|
-
processError({ issues: issue2.issues }, [...
|
|
1349
|
+
processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
|
|
1350
1350
|
} else {
|
|
1351
|
-
const fullpath = [...
|
|
1351
|
+
const fullpath = [...path6, ...issue2.path];
|
|
1352
1352
|
if (fullpath.length === 0) {
|
|
1353
1353
|
fieldErrors._errors.push(mapper(issue2));
|
|
1354
1354
|
} else {
|
|
@@ -1375,17 +1375,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1375
1375
|
}
|
|
1376
1376
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
1377
1377
|
const result = { errors: [] };
|
|
1378
|
-
const processError = (error52,
|
|
1378
|
+
const processError = (error52, path6 = []) => {
|
|
1379
1379
|
var _a3, _b;
|
|
1380
1380
|
for (const issue2 of error52.issues) {
|
|
1381
1381
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1382
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1382
|
+
issue2.errors.map((issues) => processError({ issues }, [...path6, ...issue2.path]));
|
|
1383
1383
|
} else if (issue2.code === "invalid_key") {
|
|
1384
|
-
processError({ issues: issue2.issues }, [...
|
|
1384
|
+
processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
|
|
1385
1385
|
} else if (issue2.code === "invalid_element") {
|
|
1386
|
-
processError({ issues: issue2.issues }, [...
|
|
1386
|
+
processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
|
|
1387
1387
|
} else {
|
|
1388
|
-
const fullpath = [...
|
|
1388
|
+
const fullpath = [...path6, ...issue2.path];
|
|
1389
1389
|
if (fullpath.length === 0) {
|
|
1390
1390
|
result.errors.push(mapper(issue2));
|
|
1391
1391
|
continue;
|
|
@@ -1417,8 +1417,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1417
1417
|
}
|
|
1418
1418
|
function toDotPath(_path) {
|
|
1419
1419
|
const segs = [];
|
|
1420
|
-
const
|
|
1421
|
-
for (const seg of
|
|
1420
|
+
const path6 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
1421
|
+
for (const seg of path6) {
|
|
1422
1422
|
if (typeof seg === "number")
|
|
1423
1423
|
segs.push(`[${seg}]`);
|
|
1424
1424
|
else if (typeof seg === "symbol")
|
|
@@ -14110,13 +14110,13 @@ function resolveRef(ref, ctx) {
|
|
|
14110
14110
|
if (!ref.startsWith("#")) {
|
|
14111
14111
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
14112
14112
|
}
|
|
14113
|
-
const
|
|
14114
|
-
if (
|
|
14113
|
+
const path6 = ref.slice(1).split("/").filter(Boolean);
|
|
14114
|
+
if (path6.length === 0) {
|
|
14115
14115
|
return ctx.rootSchema;
|
|
14116
14116
|
}
|
|
14117
14117
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
14118
|
-
if (
|
|
14119
|
-
const key =
|
|
14118
|
+
if (path6[0] === defsKey) {
|
|
14119
|
+
const key = path6[1];
|
|
14120
14120
|
if (!key || !ctx.defs[key]) {
|
|
14121
14121
|
throw new Error(`Reference not found: ${ref}`);
|
|
14122
14122
|
}
|
|
@@ -15525,6 +15525,12 @@ function parseHostUsage(value) {
|
|
|
15525
15525
|
throw new Error(`Harness Usage contains unknown field '${key}'`);
|
|
15526
15526
|
}
|
|
15527
15527
|
}
|
|
15528
|
+
for (const field of ["totalCredits", "contextUsagePercent"]) {
|
|
15529
|
+
const candidate = value[field];
|
|
15530
|
+
if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate < 0)) {
|
|
15531
|
+
throw new Error(`Harness Usage '${field}' must be a finite non-negative number`);
|
|
15532
|
+
}
|
|
15533
|
+
}
|
|
15528
15534
|
for (const field of tokenFields) {
|
|
15529
15535
|
const candidate = value[field];
|
|
15530
15536
|
if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
|
|
@@ -16219,7 +16225,7 @@ var serializeObjectParam = ({ allowReserved, explode, name, style, value, valueO
|
|
|
16219
16225
|
|
|
16220
16226
|
// ../../../node_modules/@opencode-ai/sdk/dist/v2/gen/core/utils.gen.js
|
|
16221
16227
|
var PATH_PARAM_RE = /\{[^{}]+\}/g;
|
|
16222
|
-
var defaultPathSerializer = ({ path:
|
|
16228
|
+
var defaultPathSerializer = ({ path: path6, url: _url2 }) => {
|
|
16223
16229
|
let url2 = _url2;
|
|
16224
16230
|
const matches = _url2.match(PATH_PARAM_RE);
|
|
16225
16231
|
if (matches) {
|
|
@@ -16238,7 +16244,7 @@ var defaultPathSerializer = ({ path: path5, url: _url2 }) => {
|
|
|
16238
16244
|
name = name.substring(1);
|
|
16239
16245
|
style = "matrix";
|
|
16240
16246
|
}
|
|
16241
|
-
const value =
|
|
16247
|
+
const value = path6[name];
|
|
16242
16248
|
if (value === void 0 || value === null) {
|
|
16243
16249
|
continue;
|
|
16244
16250
|
}
|
|
@@ -16269,11 +16275,11 @@ var defaultPathSerializer = ({ path: path5, url: _url2 }) => {
|
|
|
16269
16275
|
}
|
|
16270
16276
|
return url2;
|
|
16271
16277
|
};
|
|
16272
|
-
var getUrl = ({ baseUrl, path:
|
|
16278
|
+
var getUrl = ({ baseUrl, path: path6, query, querySerializer, url: _url2 }) => {
|
|
16273
16279
|
const pathUrl = _url2.startsWith("/") ? _url2 : `/${_url2}`;
|
|
16274
16280
|
let url2 = (baseUrl ?? "") + pathUrl;
|
|
16275
|
-
if (
|
|
16276
|
-
url2 = defaultPathSerializer({ path:
|
|
16281
|
+
if (path6) {
|
|
16282
|
+
url2 = defaultPathSerializer({ path: path6, url: url2 });
|
|
16277
16283
|
}
|
|
16278
16284
|
let search = query ? querySerializer(query) : "";
|
|
16279
16285
|
if (search.startsWith("?")) {
|
|
@@ -22001,6 +22007,10 @@ var SdkOpenCodeTransport = class {
|
|
|
22001
22007
|
const client2 = await this.#getClient();
|
|
22002
22008
|
return responseData2(await withTimeout2(client2.session.get({ sessionID }), this.#commandTimeoutMs, "OpenCode Session read"), "Session read");
|
|
22003
22009
|
}
|
|
22010
|
+
async getPaths() {
|
|
22011
|
+
const client2 = await this.#getClient();
|
|
22012
|
+
return responseData2(await withTimeout2(client2.path.get(), this.#commandTimeoutMs, "OpenCode Path read"), "Path read");
|
|
22013
|
+
}
|
|
22004
22014
|
async updateSessionMetadata(sessionID, metadata) {
|
|
22005
22015
|
const client2 = await this.#getClient();
|
|
22006
22016
|
return responseData2(await withTimeout2(client2.session.update({ sessionID, metadata }), this.#commandTimeoutMs, "OpenCode Session metadata update"), "Session metadata update");
|
|
@@ -22143,6 +22153,65 @@ var SdkOpenCodeTransport = class {
|
|
|
22143
22153
|
}
|
|
22144
22154
|
};
|
|
22145
22155
|
|
|
22156
|
+
// dist/file-change-verification.js
|
|
22157
|
+
import fs2 from "node:fs";
|
|
22158
|
+
import path4 from "node:path";
|
|
22159
|
+
function missingPath(error51) {
|
|
22160
|
+
if (!error51 || typeof error51 !== "object")
|
|
22161
|
+
return false;
|
|
22162
|
+
const code = Reflect.get(error51, "code");
|
|
22163
|
+
return code === "ENOENT" || code === "ENOTDIR";
|
|
22164
|
+
}
|
|
22165
|
+
function hasDotPathSegment(value) {
|
|
22166
|
+
const segments = process.platform === "win32" ? value.split(/[\\/]+/) : value.split("/");
|
|
22167
|
+
return segments.some((segment) => segment === "." || segment === "..");
|
|
22168
|
+
}
|
|
22169
|
+
function canonicalDirectoryPath(value) {
|
|
22170
|
+
let candidate = path4.resolve(value);
|
|
22171
|
+
const missingSegments = [];
|
|
22172
|
+
for (; ; ) {
|
|
22173
|
+
try {
|
|
22174
|
+
return path4.join(fs2.realpathSync.native(candidate), ...missingSegments);
|
|
22175
|
+
} catch (error51) {
|
|
22176
|
+
if (!missingPath(error51))
|
|
22177
|
+
return void 0;
|
|
22178
|
+
const parent = path4.dirname(candidate);
|
|
22179
|
+
if (parent === candidate)
|
|
22180
|
+
return void 0;
|
|
22181
|
+
missingSegments.unshift(path4.basename(candidate));
|
|
22182
|
+
candidate = parent;
|
|
22183
|
+
}
|
|
22184
|
+
}
|
|
22185
|
+
}
|
|
22186
|
+
function canonicalFilePath(value) {
|
|
22187
|
+
const absolute = path4.resolve(value);
|
|
22188
|
+
const parent = canonicalDirectoryPath(path4.dirname(absolute));
|
|
22189
|
+
return parent ? path4.join(parent, path4.basename(absolute)) : void 0;
|
|
22190
|
+
}
|
|
22191
|
+
function pathIsWithin(root, candidate, allowRoot) {
|
|
22192
|
+
const relative = path4.relative(root, candidate);
|
|
22193
|
+
return allowRoot && relative === "" || relative !== "" && relative !== ".." && !relative.startsWith(`..${path4.sep}`) && !path4.isAbsolute(relative);
|
|
22194
|
+
}
|
|
22195
|
+
function verifiedOpenCodeWorktree(sessionDirectory, paths) {
|
|
22196
|
+
if (!paths || typeof paths !== "object" || typeof sessionDirectory !== "string" || typeof paths.directory !== "string" || typeof paths.worktree !== "string" || hasDotPathSegment(sessionDirectory) || hasDotPathSegment(paths.directory) || hasDotPathSegment(paths.worktree) || !path4.isAbsolute(sessionDirectory) || !path4.isAbsolute(paths.directory) || !path4.isAbsolute(paths.worktree)) {
|
|
22197
|
+
return void 0;
|
|
22198
|
+
}
|
|
22199
|
+
const session = canonicalDirectoryPath(sessionDirectory);
|
|
22200
|
+
const directory = canonicalDirectoryPath(paths.directory);
|
|
22201
|
+
const worktree = canonicalDirectoryPath(paths.worktree);
|
|
22202
|
+
if (!session || !directory || !worktree || session !== directory || !pathIsWithin(worktree, directory, true)) {
|
|
22203
|
+
return void 0;
|
|
22204
|
+
}
|
|
22205
|
+
return worktree;
|
|
22206
|
+
}
|
|
22207
|
+
function openCodeFileIdentity(file2, worktree) {
|
|
22208
|
+
if (typeof file2 !== "string" || typeof worktree !== "string" || hasDotPathSegment(file2) || hasDotPathSegment(worktree) || !path4.isAbsolute(worktree) || !file2 || file2.includes("\0") || file2.includes("\n") || file2.includes("\r")) {
|
|
22209
|
+
return void 0;
|
|
22210
|
+
}
|
|
22211
|
+
const candidate = canonicalFilePath(path4.isAbsolute(file2) ? file2 : path4.resolve(worktree, file2));
|
|
22212
|
+
return candidate && pathIsWithin(worktree, candidate, false) ? candidate : void 0;
|
|
22213
|
+
}
|
|
22214
|
+
|
|
22146
22215
|
// dist/usage.js
|
|
22147
22216
|
function projectOpenCodeUsage(messages, contextWindowTokens) {
|
|
22148
22217
|
if (messages.length === 0)
|
|
@@ -22181,51 +22250,9 @@ function projectOpenCodeUsage(messages, contextWindowTokens) {
|
|
|
22181
22250
|
});
|
|
22182
22251
|
}
|
|
22183
22252
|
|
|
22184
|
-
// dist/
|
|
22185
|
-
var openCodeHarnessId2 = harnessIdSchema.parse("opencode");
|
|
22186
|
-
var DEFAULT_TOOL_OUTPUT_LIMIT = 64e3;
|
|
22187
|
-
var DEFAULT_CLOSE_TIMEOUT_MS2 = 3e3;
|
|
22188
|
-
var DIFF_RECONCILIATION_DELAYS_MS = [25, 50, 100, 200, 400, 800];
|
|
22189
|
-
var COMPACT_COMMAND_ID = "opencode.compact";
|
|
22253
|
+
// dist/history-projection.js
|
|
22190
22254
|
var SELECTION_METADATA_KEY = "codexhost.selection.v1";
|
|
22191
|
-
|
|
22192
|
-
return { code: "invalidState", message, retryable: false };
|
|
22193
|
-
}
|
|
22194
|
-
function unsupported(message) {
|
|
22195
|
-
return { code: "unsupported", message, retryable: false };
|
|
22196
|
-
}
|
|
22197
|
-
function normalizeError(error51, fallback) {
|
|
22198
|
-
if (error51 instanceof OpenCodeTransportError) {
|
|
22199
|
-
return {
|
|
22200
|
-
code: error51.code,
|
|
22201
|
-
message: error51.message,
|
|
22202
|
-
retryable: error51.code === "unavailable" || error51.code === "processExited" || error51.code === "authenticationRequired"
|
|
22203
|
-
};
|
|
22204
|
-
}
|
|
22205
|
-
const text = error51 instanceof Error ? error51.message : String(error51);
|
|
22206
|
-
const lower = text.toLowerCase();
|
|
22207
|
-
if (lower.includes("sessionbusy") || lower.includes("session busy")) {
|
|
22208
|
-
return { code: "sessionBusy", message: text, retryable: true };
|
|
22209
|
-
}
|
|
22210
|
-
if (lower.includes("not found")) {
|
|
22211
|
-
return { code: "sessionNotFound", message: text, retryable: false };
|
|
22212
|
-
}
|
|
22213
|
-
return {
|
|
22214
|
-
code: fallback,
|
|
22215
|
-
message: text,
|
|
22216
|
-
retryable: fallback === "unavailable" || fallback === "nativeFailure"
|
|
22217
|
-
};
|
|
22218
|
-
}
|
|
22219
|
-
function sameCwd(left, right) {
|
|
22220
|
-
const canonical = (value) => {
|
|
22221
|
-
try {
|
|
22222
|
-
return fs2.realpathSync.native(value);
|
|
22223
|
-
} catch {
|
|
22224
|
-
return path4.resolve(value);
|
|
22225
|
-
}
|
|
22226
|
-
};
|
|
22227
|
-
return canonical(left) === canonical(right);
|
|
22228
|
-
}
|
|
22255
|
+
var DIFF_RECONCILIATION_DELAYS_MS = [25, 50, 100, 200, 400, 800];
|
|
22229
22256
|
function storedSelection(session) {
|
|
22230
22257
|
const value = session.metadata?.[SELECTION_METADATA_KEY];
|
|
22231
22258
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
@@ -22275,32 +22302,62 @@ function nativeVariantFromSession(session, messages) {
|
|
|
22275
22302
|
}
|
|
22276
22303
|
return void 0;
|
|
22277
22304
|
}
|
|
22278
|
-
function
|
|
22305
|
+
function turnNativePatchFiles(messages, userMessageID) {
|
|
22279
22306
|
const start = messages.findIndex(({ info }) => info.id === userMessageID);
|
|
22280
22307
|
if (start < 0)
|
|
22281
|
-
return
|
|
22308
|
+
return [];
|
|
22282
22309
|
let end = start + 1;
|
|
22283
22310
|
while (end < messages.length && messages[end]?.info.role !== "user")
|
|
22284
22311
|
end += 1;
|
|
22285
|
-
return
|
|
22312
|
+
return [
|
|
22313
|
+
...new Set(messages.slice(start + 1, end).flatMap(({ parts }) => parts.flatMap((part) => part.type === "patch" ? part.files : [])))
|
|
22314
|
+
];
|
|
22286
22315
|
}
|
|
22287
|
-
async function readTurnDiff(transport, sessionID, userMessageID,
|
|
22316
|
+
async function readTurnDiff(transport, sessionID, userMessageID, nativePatchFiles, options = {}) {
|
|
22317
|
+
const strict = options.strict === true;
|
|
22288
22318
|
for (let attempt = 0; ; attempt += 1) {
|
|
22289
|
-
|
|
22290
|
-
|
|
22319
|
+
let diffs;
|
|
22320
|
+
try {
|
|
22321
|
+
diffs = await transport.getDiff(sessionID, userMessageID);
|
|
22322
|
+
} catch (error51) {
|
|
22323
|
+
if (strict) {
|
|
22324
|
+
throw new OpenCodeTransportError("protocolError", "OpenCode could not verify FileChange history", { cause: error51 });
|
|
22325
|
+
}
|
|
22326
|
+
diffs = [];
|
|
22327
|
+
}
|
|
22328
|
+
const reliableChanges = reliableOpenCodeFileChanges(diffs);
|
|
22329
|
+
const worktree = options.worktree;
|
|
22330
|
+
const reliablePaths = worktree ? reliableChanges.map(({ path: file2 }) => openCodeFileIdentity(file2, worktree)) : [];
|
|
22331
|
+
const nativePatchPaths = worktree ? nativePatchFiles.map((file2) => openCodeFileIdentity(file2, worktree)) : [];
|
|
22332
|
+
const completeStrictProjection = Boolean(worktree) && reliableChanges.length === diffs.length && reliablePaths.every((file2) => file2 !== void 0) && nativePatchPaths.every((file2) => file2 !== void 0 && reliablePaths.includes(file2));
|
|
22333
|
+
if (strict ? completeStrictProjection : reliableChanges.length > 0 || nativePatchFiles.length === 0) {
|
|
22334
|
+
return diffs;
|
|
22335
|
+
}
|
|
22336
|
+
if (attempt >= DIFF_RECONCILIATION_DELAYS_MS.length) {
|
|
22337
|
+
if (strict) {
|
|
22338
|
+
throw new OpenCodeTransportError("protocolError", "OpenCode did not expose complete reliable FileChange history");
|
|
22339
|
+
}
|
|
22291
22340
|
return diffs;
|
|
22292
22341
|
}
|
|
22293
22342
|
await new Promise((resolve) => setTimeout(resolve, DIFF_RECONCILIATION_DELAYS_MS[attempt]));
|
|
22294
22343
|
}
|
|
22295
22344
|
}
|
|
22296
|
-
async function readProjection(transport, sessionID, providerCatalog, toolOutputLimit) {
|
|
22297
|
-
const
|
|
22345
|
+
async function readProjection(transport, sessionID, providerCatalog, toolOutputLimit, options = {}) {
|
|
22346
|
+
const strictFileChanges = options.strictFileChanges === true;
|
|
22347
|
+
const [session, messages, paths] = await Promise.all([
|
|
22298
22348
|
transport.getSession(sessionID),
|
|
22299
|
-
transport.getMessages(sessionID)
|
|
22349
|
+
transport.getMessages(sessionID),
|
|
22350
|
+
strictFileChanges ? transport.getPaths().catch((error51) => {
|
|
22351
|
+
throw new OpenCodeTransportError("protocolError", "OpenCode could not verify worktree paths", { cause: error51 });
|
|
22352
|
+
}) : void 0
|
|
22300
22353
|
]);
|
|
22354
|
+
const worktree = paths ? verifiedOpenCodeWorktree(session.directory, paths) : void 0;
|
|
22355
|
+
if (strictFileChanges && !worktree) {
|
|
22356
|
+
throw new OpenCodeTransportError("protocolError", "OpenCode returned inconsistent Session and worktree paths");
|
|
22357
|
+
}
|
|
22301
22358
|
const userMessageIds = messages.filter(({ info }) => info.role === "user").map(({ info }) => info.id);
|
|
22302
22359
|
const diffEntries = await Promise.all(userMessageIds.map(async (messageID) => {
|
|
22303
|
-
const diffs = await readTurnDiff(transport, sessionID, messageID,
|
|
22360
|
+
const diffs = await readTurnDiff(transport, sessionID, messageID, turnNativePatchFiles(messages, messageID), { strict: strictFileChanges, ...worktree ? { worktree } : {} });
|
|
22304
22361
|
return [messageID, diffs];
|
|
22305
22362
|
}));
|
|
22306
22363
|
const snapshot = projectOpenCodeHistory({
|
|
@@ -22310,7 +22367,9 @@ async function readProjection(transport, sessionID, providerCatalog, toolOutputL
|
|
|
22310
22367
|
toolOutputLimit
|
|
22311
22368
|
});
|
|
22312
22369
|
const model = nativeModelFromSession(session, messages);
|
|
22313
|
-
const
|
|
22370
|
+
const nativeVariant = nativeVariantFromSession(session, messages);
|
|
22371
|
+
const nativeModel = model ? providerCatalog.all.find(({ id }) => id === model.providerID)?.models[model.modelID] : void 0;
|
|
22372
|
+
const variant = nativeVariant === "default" && nativeModel && !Object.hasOwn(nativeModel.variants ?? {}, "default") ? void 0 : nativeVariant;
|
|
22314
22373
|
const usage = projectOpenCodeUsage(openCodeAssistantMessages(session, messages), model ? openCodeContextWindow(providerCatalog, model) : void 0);
|
|
22315
22374
|
return {
|
|
22316
22375
|
session,
|
|
@@ -22321,6 +22380,128 @@ async function readProjection(transport, sessionID, providerCatalog, toolOutputL
|
|
|
22321
22380
|
...variant ? { variant } : {}
|
|
22322
22381
|
};
|
|
22323
22382
|
}
|
|
22383
|
+
|
|
22384
|
+
// dist/history-derivation.js
|
|
22385
|
+
import { isDeepStrictEqual } from "node:util";
|
|
22386
|
+
function semanticHistory(snapshot) {
|
|
22387
|
+
return snapshot.turns.map((turn) => ({
|
|
22388
|
+
input: turn.input,
|
|
22389
|
+
items: turn.items.map(({ item, outcome }) => {
|
|
22390
|
+
const { itemId: _itemId, ...content } = item;
|
|
22391
|
+
void _itemId;
|
|
22392
|
+
return { item: content, outcome };
|
|
22393
|
+
}),
|
|
22394
|
+
outcome: turn.outcome,
|
|
22395
|
+
model: turn.model,
|
|
22396
|
+
checkpoint: Boolean(turn.checkpoint)
|
|
22397
|
+
}));
|
|
22398
|
+
}
|
|
22399
|
+
function sourceState(projection) {
|
|
22400
|
+
return {
|
|
22401
|
+
id: projection.session.id,
|
|
22402
|
+
directory: projection.session.directory,
|
|
22403
|
+
revert: projection.session.revert,
|
|
22404
|
+
metadata: projection.session.metadata,
|
|
22405
|
+
permission: projection.session.permission,
|
|
22406
|
+
model: projection.model,
|
|
22407
|
+
variant: projection.variant,
|
|
22408
|
+
snapshot: projection.snapshot
|
|
22409
|
+
};
|
|
22410
|
+
}
|
|
22411
|
+
async function deriveOpenCodeHistory(options) {
|
|
22412
|
+
const { transport, source, input, providers, toolOutputLimit } = options;
|
|
22413
|
+
const read = (id) => readProjection(transport, id, providers, toolOutputLimit, { strictFileChanges: true });
|
|
22414
|
+
if ((await transport.getStatus(source.id)).type !== "idle") {
|
|
22415
|
+
throw new Error("OpenCode source Session is busy");
|
|
22416
|
+
}
|
|
22417
|
+
const before = await read(source.id);
|
|
22418
|
+
const expectedSource = structuredClone(sourceState(before));
|
|
22419
|
+
let messageID;
|
|
22420
|
+
let retainedCount;
|
|
22421
|
+
if (input.kind === "fork") {
|
|
22422
|
+
const boundary = resolveOpenCodeForkBoundary(before.session, before.messages, input.checkpoint);
|
|
22423
|
+
if (!boundary)
|
|
22424
|
+
throw new OpenCodeTransportError("checkpointNotFound", "OpenCode Checkpoint is not on the source Session transcript");
|
|
22425
|
+
messageID = boundary.messageID;
|
|
22426
|
+
retainedCount = boundary.sourceTurnCount;
|
|
22427
|
+
} else {
|
|
22428
|
+
const boundary = resolveOpenCodeLastTurnBoundary(before.session, before.messages);
|
|
22429
|
+
if (!boundary)
|
|
22430
|
+
throw new OpenCodeTransportError("invalidState", "OpenCode Native Session has no Turn to roll back");
|
|
22431
|
+
messageID = boundary.lastUserMessageID;
|
|
22432
|
+
retainedCount = boundary.sourceTurnCount - 1;
|
|
22433
|
+
}
|
|
22434
|
+
const expectedHistory = structuredClone(semanticHistory(before.snapshot).slice(0, retainedCount));
|
|
22435
|
+
let candidate = await transport.forkSession(source.id, messageID);
|
|
22436
|
+
if (candidate.id === source.id) {
|
|
22437
|
+
throw new OpenCodeTransportError("protocolError", "OpenCode Fork did not create a distinct Native Session");
|
|
22438
|
+
}
|
|
22439
|
+
const candidateID = candidate.id;
|
|
22440
|
+
options.onCreated(candidate);
|
|
22441
|
+
if (candidate.directory !== expectedSource.directory) {
|
|
22442
|
+
throw new OpenCodeTransportError("protocolError", "OpenCode Fork changed working directory");
|
|
22443
|
+
}
|
|
22444
|
+
if (expectedSource.model) {
|
|
22445
|
+
candidate = await transport.updateSessionMetadata(candidateID, selectionMetadata(candidate, expectedSource.model, expectedSource.variant));
|
|
22446
|
+
}
|
|
22447
|
+
if (!isDeepStrictEqual(candidate.permission ?? [], expectedSource.permission ?? [])) {
|
|
22448
|
+
candidate = await transport.updateSessionPermission(candidateID, expectedSource.permission ?? []);
|
|
22449
|
+
}
|
|
22450
|
+
const [derived, after, candidateStatus, sourceStatus] = await Promise.all([
|
|
22451
|
+
read(candidateID),
|
|
22452
|
+
read(source.id),
|
|
22453
|
+
transport.getStatus(candidateID),
|
|
22454
|
+
transport.getStatus(source.id)
|
|
22455
|
+
]);
|
|
22456
|
+
if (derived.session.id !== candidateID || candidate.id !== candidateID || derived.session.directory !== before.session.directory || candidateStatus.type !== "idle" || sourceStatus.type !== "idle" || !isDeepStrictEqual(semanticHistory(derived.snapshot), expectedHistory) || !isDeepStrictEqual(sourceState(after), expectedSource) || !isDeepStrictEqual(derived.model, expectedSource.model) || derived.variant !== expectedSource.variant || !isDeepStrictEqual(derived.session.permission ?? [], expectedSource.permission ?? [])) {
|
|
22457
|
+
throw new OpenCodeTransportError("protocolError", "OpenCode derived history, source or configuration changed during Fork");
|
|
22458
|
+
}
|
|
22459
|
+
return derived.session;
|
|
22460
|
+
}
|
|
22461
|
+
|
|
22462
|
+
// dist/opencode-adapter.js
|
|
22463
|
+
var openCodeHarnessId2 = harnessIdSchema.parse("opencode");
|
|
22464
|
+
var DEFAULT_TOOL_OUTPUT_LIMIT = 64e3;
|
|
22465
|
+
var DEFAULT_CLOSE_TIMEOUT_MS2 = 3e3;
|
|
22466
|
+
var COMPACT_COMMAND_ID = "opencode.compact";
|
|
22467
|
+
function invalidState(message) {
|
|
22468
|
+
return { code: "invalidState", message, retryable: false };
|
|
22469
|
+
}
|
|
22470
|
+
function unsupported(message) {
|
|
22471
|
+
return { code: "unsupported", message, retryable: false };
|
|
22472
|
+
}
|
|
22473
|
+
function normalizeError(error51, fallback) {
|
|
22474
|
+
if (error51 instanceof OpenCodeTransportError) {
|
|
22475
|
+
return {
|
|
22476
|
+
code: error51.code,
|
|
22477
|
+
message: error51.message,
|
|
22478
|
+
retryable: error51.code === "unavailable" || error51.code === "processExited" || error51.code === "authenticationRequired"
|
|
22479
|
+
};
|
|
22480
|
+
}
|
|
22481
|
+
const text = error51 instanceof Error ? error51.message : String(error51);
|
|
22482
|
+
const lower = text.toLowerCase();
|
|
22483
|
+
if (lower.includes("sessionbusy") || lower.includes("session busy")) {
|
|
22484
|
+
return { code: "sessionBusy", message: text, retryable: true };
|
|
22485
|
+
}
|
|
22486
|
+
if (lower.includes("not found")) {
|
|
22487
|
+
return { code: "sessionNotFound", message: text, retryable: false };
|
|
22488
|
+
}
|
|
22489
|
+
return {
|
|
22490
|
+
code: fallback,
|
|
22491
|
+
message: text,
|
|
22492
|
+
retryable: fallback === "unavailable" || fallback === "nativeFailure"
|
|
22493
|
+
};
|
|
22494
|
+
}
|
|
22495
|
+
function sameCwd(left, right) {
|
|
22496
|
+
const canonical = (value) => {
|
|
22497
|
+
try {
|
|
22498
|
+
return fs3.realpathSync.native(value);
|
|
22499
|
+
} catch {
|
|
22500
|
+
return path5.resolve(value);
|
|
22501
|
+
}
|
|
22502
|
+
};
|
|
22503
|
+
return canonical(left) === canonical(right);
|
|
22504
|
+
}
|
|
22324
22505
|
function sessionState(session, modelCatalog, model, variant, executionPolicy = "default", permissionModeId = OPENCODE_DEFAULT_PERMISSION_MODE_ID) {
|
|
22325
22506
|
const effectiveModel = model ? encodeOpenCodeModelRef(model) : void 0;
|
|
22326
22507
|
const modelEntry = effectiveModel ? modelCatalog.models.find(({ ref }) => ref.id === effectiveModel.id) : void 0;
|
|
@@ -22887,6 +23068,11 @@ var OpenCodeHarnessSession = class {
|
|
|
22887
23068
|
}
|
|
22888
23069
|
if (event.type === "session.error" && event.properties.sessionID === this.#session.id && active) {
|
|
22889
23070
|
const error51 = event.properties.error;
|
|
23071
|
+
if (active.cancellationRequested || error51?.name === "MessageAbortedError") {
|
|
23072
|
+
active.cancellationRequested = true;
|
|
23073
|
+
void this.#reconcileAndFinish(active);
|
|
23074
|
+
return;
|
|
23075
|
+
}
|
|
22890
23076
|
this.#completeTurn(active, {
|
|
22891
23077
|
status: active.cancellationRequested ? "cancelled" : "failed",
|
|
22892
23078
|
...active.cancellationRequested ? { reason: "Cancelled by user" } : {
|
|
@@ -23140,6 +23326,19 @@ var OpenCodeHarnessSession = class {
|
|
|
23140
23326
|
const assistants = messages.slice(userIndex + 1, end).filter((entry) => entry.info.role === "assistant");
|
|
23141
23327
|
const terminal = assistants.at(-1)?.info ?? active.terminalAssistant;
|
|
23142
23328
|
if (!terminal || terminal.time.completed === void 0 && !terminal.finish && !terminal.error && !active.nativeCompleted) {
|
|
23329
|
+
if (active.cancellationRequested) {
|
|
23330
|
+
for (const entry of assistants) {
|
|
23331
|
+
for (const part of entry.parts)
|
|
23332
|
+
this.#projectPart(active, part);
|
|
23333
|
+
}
|
|
23334
|
+
this.#completeTurn(active, { status: "cancelled", reason: "Cancelled by user" }, {
|
|
23335
|
+
harnessId: this.harnessId,
|
|
23336
|
+
nativeSessionId: this.#session.id,
|
|
23337
|
+
nativeTurnKey: active.userMessageID,
|
|
23338
|
+
formatVersion: 1
|
|
23339
|
+
});
|
|
23340
|
+
void this.#refreshProjection(active.turnId);
|
|
23341
|
+
}
|
|
23143
23342
|
return;
|
|
23144
23343
|
}
|
|
23145
23344
|
for (const entry of assistants) {
|
|
@@ -23148,7 +23347,7 @@ var OpenCodeHarnessSession = class {
|
|
|
23148
23347
|
}
|
|
23149
23348
|
active.terminalAssistant = terminal;
|
|
23150
23349
|
const userMessageID = active.userMessageID;
|
|
23151
|
-
const changes = reliableOpenCodeFileChanges(await readTurnDiff(this.#transport, this.#session.id, userMessageID,
|
|
23350
|
+
const changes = reliableOpenCodeFileChanges(await readTurnDiff(this.#transport, this.#session.id, userMessageID, turnNativePatchFiles(messages, userMessageID)));
|
|
23152
23351
|
if (changes.length > 0) {
|
|
23153
23352
|
const id = `opencode-live-diff:${active.userMessageID}`;
|
|
23154
23353
|
if (!active.items.has(id)) {
|
|
@@ -23525,7 +23724,6 @@ var OpenCodeAdapter = class {
|
|
|
23525
23724
|
let connection;
|
|
23526
23725
|
let transport;
|
|
23527
23726
|
let createdForCleanup;
|
|
23528
|
-
let revertedForCleanup;
|
|
23529
23727
|
try {
|
|
23530
23728
|
const sourceRef = input.kind === "create" ? void 0 : parseOpenCodeSessionRef(input.kind === "resume" ? input.nativeRef : input.sourceRef);
|
|
23531
23729
|
const executionPolicy = input.kind === "create" ? input.executionPolicy ?? "default" : sourceRef?.executionPolicy ?? "default";
|
|
@@ -23604,61 +23802,17 @@ var OpenCodeAdapter = class {
|
|
|
23604
23802
|
}
|
|
23605
23803
|
if (input.kind === "resume") {
|
|
23606
23804
|
session = source;
|
|
23607
|
-
} else if (input.kind === "fork") {
|
|
23608
|
-
const checkpoint = nativeCheckpointRefSchema.parse(input.checkpoint);
|
|
23609
|
-
if (checkpoint.harnessId !== this.harnessId || checkpoint.nativeSessionId !== source.id) {
|
|
23610
|
-
throw new OpenCodeTransportError("protocolError", "OpenCode Checkpoint does not belong to the source Session");
|
|
23611
|
-
}
|
|
23612
|
-
const sourceMessages = await transport.getMessages(source.id);
|
|
23613
|
-
const boundary = resolveOpenCodeForkBoundary(source, sourceMessages, checkpoint);
|
|
23614
|
-
if (!boundary) {
|
|
23615
|
-
await transport.close().catch(() => void 0);
|
|
23616
|
-
await connection.close().catch(() => void 0);
|
|
23617
|
-
return {
|
|
23618
|
-
ok: false,
|
|
23619
|
-
error: {
|
|
23620
|
-
code: "checkpointNotFound",
|
|
23621
|
-
message: "OpenCode Checkpoint is not on the source Session transcript",
|
|
23622
|
-
retryable: false
|
|
23623
|
-
}
|
|
23624
|
-
};
|
|
23625
|
-
}
|
|
23626
|
-
session = await transport.forkSession(source.id, boundary.messageID);
|
|
23627
|
-
createdForCleanup = session;
|
|
23628
|
-
if (session.id === source.id) {
|
|
23629
|
-
throw new OpenCodeTransportError("protocolError", "OpenCode Fork did not create a distinct Native Session");
|
|
23630
|
-
}
|
|
23631
|
-
const derivedMessages = await transport.getMessages(session.id);
|
|
23632
|
-
const derived = projectOpenCodeHistory({
|
|
23633
|
-
session,
|
|
23634
|
-
messages: derivedMessages,
|
|
23635
|
-
toolOutputLimit: this.#toolOutputLimit
|
|
23636
|
-
});
|
|
23637
|
-
if (derived.turns.length !== boundary.sourceTurnCount) {
|
|
23638
|
-
throw new OpenCodeTransportError("protocolError", "OpenCode Fork derived history does not match the requested Checkpoint");
|
|
23639
|
-
}
|
|
23640
23805
|
} else {
|
|
23641
|
-
|
|
23642
|
-
|
|
23643
|
-
|
|
23644
|
-
|
|
23645
|
-
|
|
23646
|
-
|
|
23647
|
-
|
|
23648
|
-
|
|
23649
|
-
}
|
|
23650
|
-
}
|
|
23651
|
-
session = await transport.revertSession(source.id, boundary.lastUserMessageID);
|
|
23652
|
-
revertedForCleanup = source.id;
|
|
23653
|
-
const afterMessages = await transport.getMessages(session.id);
|
|
23654
|
-
const after = projectOpenCodeHistory({
|
|
23655
|
-
session,
|
|
23656
|
-
messages: afterMessages,
|
|
23657
|
-
toolOutputLimit: this.#toolOutputLimit
|
|
23806
|
+
session = await deriveOpenCodeHistory({
|
|
23807
|
+
transport,
|
|
23808
|
+
source,
|
|
23809
|
+
input,
|
|
23810
|
+
providers,
|
|
23811
|
+
toolOutputLimit: this.#toolOutputLimit,
|
|
23812
|
+
onCreated: (candidate) => {
|
|
23813
|
+
createdForCleanup = candidate;
|
|
23814
|
+
}
|
|
23658
23815
|
});
|
|
23659
|
-
if (after.turns.length !== boundary.sourceTurnCount - 1) {
|
|
23660
|
-
throw new OpenCodeTransportError("protocolError", "OpenCode rollback did not remove exactly the last Turn");
|
|
23661
|
-
}
|
|
23662
23816
|
}
|
|
23663
23817
|
}
|
|
23664
23818
|
const projection = await readProjection(transport, session.id, providers, this.#toolOutputLimit);
|
|
@@ -23678,12 +23832,8 @@ var OpenCodeAdapter = class {
|
|
|
23678
23832
|
await harnessSession.start();
|
|
23679
23833
|
this.#sessions.add(harnessSession);
|
|
23680
23834
|
createdForCleanup = void 0;
|
|
23681
|
-
revertedForCleanup = void 0;
|
|
23682
23835
|
return { ok: true, value: harnessSession };
|
|
23683
23836
|
} catch (error51) {
|
|
23684
|
-
if (revertedForCleanup && transport) {
|
|
23685
|
-
await transport.unrevertSession(revertedForCleanup).catch(() => void 0);
|
|
23686
|
-
}
|
|
23687
23837
|
if (createdForCleanup && transport) {
|
|
23688
23838
|
await transport.deleteSession(createdForCleanup.id).catch(() => void 0);
|
|
23689
23839
|
}
|