@codexhost/cli-win32-arm64 0.6.0 → 0.6.1
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/desktop-controller.mjs +2 -1
- package/app/host-runtime.mjs +296 -147
- package/app/plugins/antigravity/plugin.mjs +6 -1
- package/app/plugins/claude-code/plugin.mjs +661 -219
- package/app/plugins/deepseek-harness/plugin.mjs +87 -18
- package/app/plugins/enabled.json +2 -1
- package/app/plugins/grok/plugin.mjs +11 -1
- package/app/plugins/kiro-cli/assets/icon.svg +5 -0
- package/app/plugins/kiro-cli/manifest.json +12 -0
- package/app/plugins/kiro-cli/plugin.mjs +23316 -0
- package/app/plugins/omp/plugin.mjs +11 -1
- package/app/plugins/opencode/plugin.mjs +297 -143
- package/app/plugins/pi/plugin.mjs +1489 -1300
- package/app/renderer-extension.js +152 -84
- package/bin/codexhost.exe +0 -0
- package/libexec/codexhost-node-repl.exe +0 -0
- package/libexec/codexhost-shim.exe +0 -0
- package/libexec/codexhost-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
|
}
|
|
@@ -14550,6 +14550,8 @@ var threadUsageSnapshotSchema = external_exports.object({
|
|
|
14550
14550
|
reasoningOutputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
14551
14551
|
totalTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
14552
14552
|
totalCostUsd: finiteNonNegativeNumberSchema.optional(),
|
|
14553
|
+
totalCredits: finiteNonNegativeNumberSchema.optional(),
|
|
14554
|
+
contextUsagePercent: finiteNonNegativeNumberSchema.optional(),
|
|
14553
14555
|
cacheHitRatePercent: cacheHitRatePercentSchema.optional(),
|
|
14554
14556
|
contextWindowTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
14555
14557
|
contextUsedTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
@@ -15481,7 +15483,9 @@ var usageFields = /* @__PURE__ */ new Set([
|
|
|
15481
15483
|
...tokenFields,
|
|
15482
15484
|
...safeIntegerFields,
|
|
15483
15485
|
...percentFields,
|
|
15484
|
-
"totalCostUsd"
|
|
15486
|
+
"totalCostUsd",
|
|
15487
|
+
"totalCredits",
|
|
15488
|
+
"contextUsagePercent"
|
|
15485
15489
|
]);
|
|
15486
15490
|
function isRecord(value) {
|
|
15487
15491
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -15497,6 +15501,12 @@ function parseHostUsage(value) {
|
|
|
15497
15501
|
throw new Error(`Harness Usage contains unknown field '${key}'`);
|
|
15498
15502
|
}
|
|
15499
15503
|
}
|
|
15504
|
+
for (const field of ["totalCredits", "contextUsagePercent"]) {
|
|
15505
|
+
const candidate = value[field];
|
|
15506
|
+
if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate < 0)) {
|
|
15507
|
+
throw new Error(`Harness Usage '${field}' must be a finite non-negative number`);
|
|
15508
|
+
}
|
|
15509
|
+
}
|
|
15500
15510
|
for (const field of tokenFields) {
|
|
15501
15511
|
const candidate = value[field];
|
|
15502
15512
|
if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
|
|
@@ -16185,7 +16195,7 @@ var serializeObjectParam = ({ allowReserved, explode, name, style, value, valueO
|
|
|
16185
16195
|
|
|
16186
16196
|
// ../../../node_modules/@opencode-ai/sdk/dist/v2/gen/core/utils.gen.js
|
|
16187
16197
|
var PATH_PARAM_RE = /\{[^{}]+\}/g;
|
|
16188
|
-
var defaultPathSerializer = ({ path:
|
|
16198
|
+
var defaultPathSerializer = ({ path: path6, url: _url2 }) => {
|
|
16189
16199
|
let url2 = _url2;
|
|
16190
16200
|
const matches = _url2.match(PATH_PARAM_RE);
|
|
16191
16201
|
if (matches) {
|
|
@@ -16204,7 +16214,7 @@ var defaultPathSerializer = ({ path: path5, url: _url2 }) => {
|
|
|
16204
16214
|
name = name.substring(1);
|
|
16205
16215
|
style = "matrix";
|
|
16206
16216
|
}
|
|
16207
|
-
const value =
|
|
16217
|
+
const value = path6[name];
|
|
16208
16218
|
if (value === void 0 || value === null) {
|
|
16209
16219
|
continue;
|
|
16210
16220
|
}
|
|
@@ -16235,11 +16245,11 @@ var defaultPathSerializer = ({ path: path5, url: _url2 }) => {
|
|
|
16235
16245
|
}
|
|
16236
16246
|
return url2;
|
|
16237
16247
|
};
|
|
16238
|
-
var getUrl = ({ baseUrl, path:
|
|
16248
|
+
var getUrl = ({ baseUrl, path: path6, query, querySerializer, url: _url2 }) => {
|
|
16239
16249
|
const pathUrl = _url2.startsWith("/") ? _url2 : `/${_url2}`;
|
|
16240
16250
|
let url2 = (baseUrl ?? "") + pathUrl;
|
|
16241
|
-
if (
|
|
16242
|
-
url2 = defaultPathSerializer({ path:
|
|
16251
|
+
if (path6) {
|
|
16252
|
+
url2 = defaultPathSerializer({ path: path6, url: url2 });
|
|
16243
16253
|
}
|
|
16244
16254
|
let search = query ? querySerializer(query) : "";
|
|
16245
16255
|
if (search.startsWith("?")) {
|
|
@@ -21967,6 +21977,10 @@ var SdkOpenCodeTransport = class {
|
|
|
21967
21977
|
const client2 = await this.#getClient();
|
|
21968
21978
|
return responseData2(await withTimeout2(client2.session.get({ sessionID }), this.#commandTimeoutMs, "OpenCode Session read"), "Session read");
|
|
21969
21979
|
}
|
|
21980
|
+
async getPaths() {
|
|
21981
|
+
const client2 = await this.#getClient();
|
|
21982
|
+
return responseData2(await withTimeout2(client2.path.get(), this.#commandTimeoutMs, "OpenCode Path read"), "Path read");
|
|
21983
|
+
}
|
|
21970
21984
|
async updateSessionMetadata(sessionID, metadata) {
|
|
21971
21985
|
const client2 = await this.#getClient();
|
|
21972
21986
|
return responseData2(await withTimeout2(client2.session.update({ sessionID, metadata }), this.#commandTimeoutMs, "OpenCode Session metadata update"), "Session metadata update");
|
|
@@ -22109,6 +22123,65 @@ var SdkOpenCodeTransport = class {
|
|
|
22109
22123
|
}
|
|
22110
22124
|
};
|
|
22111
22125
|
|
|
22126
|
+
// dist/file-change-verification.js
|
|
22127
|
+
import fs2 from "node:fs";
|
|
22128
|
+
import path4 from "node:path";
|
|
22129
|
+
function missingPath(error51) {
|
|
22130
|
+
if (!error51 || typeof error51 !== "object")
|
|
22131
|
+
return false;
|
|
22132
|
+
const code = Reflect.get(error51, "code");
|
|
22133
|
+
return code === "ENOENT" || code === "ENOTDIR";
|
|
22134
|
+
}
|
|
22135
|
+
function hasDotPathSegment(value) {
|
|
22136
|
+
const segments = process.platform === "win32" ? value.split(/[\\/]+/) : value.split("/");
|
|
22137
|
+
return segments.some((segment) => segment === "." || segment === "..");
|
|
22138
|
+
}
|
|
22139
|
+
function canonicalDirectoryPath(value) {
|
|
22140
|
+
let candidate = path4.resolve(value);
|
|
22141
|
+
const missingSegments = [];
|
|
22142
|
+
for (; ; ) {
|
|
22143
|
+
try {
|
|
22144
|
+
return path4.join(fs2.realpathSync.native(candidate), ...missingSegments);
|
|
22145
|
+
} catch (error51) {
|
|
22146
|
+
if (!missingPath(error51))
|
|
22147
|
+
return void 0;
|
|
22148
|
+
const parent = path4.dirname(candidate);
|
|
22149
|
+
if (parent === candidate)
|
|
22150
|
+
return void 0;
|
|
22151
|
+
missingSegments.unshift(path4.basename(candidate));
|
|
22152
|
+
candidate = parent;
|
|
22153
|
+
}
|
|
22154
|
+
}
|
|
22155
|
+
}
|
|
22156
|
+
function canonicalFilePath(value) {
|
|
22157
|
+
const absolute = path4.resolve(value);
|
|
22158
|
+
const parent = canonicalDirectoryPath(path4.dirname(absolute));
|
|
22159
|
+
return parent ? path4.join(parent, path4.basename(absolute)) : void 0;
|
|
22160
|
+
}
|
|
22161
|
+
function pathIsWithin(root, candidate, allowRoot) {
|
|
22162
|
+
const relative = path4.relative(root, candidate);
|
|
22163
|
+
return allowRoot && relative === "" || relative !== "" && relative !== ".." && !relative.startsWith(`..${path4.sep}`) && !path4.isAbsolute(relative);
|
|
22164
|
+
}
|
|
22165
|
+
function verifiedOpenCodeWorktree(sessionDirectory, paths) {
|
|
22166
|
+
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)) {
|
|
22167
|
+
return void 0;
|
|
22168
|
+
}
|
|
22169
|
+
const session = canonicalDirectoryPath(sessionDirectory);
|
|
22170
|
+
const directory = canonicalDirectoryPath(paths.directory);
|
|
22171
|
+
const worktree = canonicalDirectoryPath(paths.worktree);
|
|
22172
|
+
if (!session || !directory || !worktree || session !== directory || !pathIsWithin(worktree, directory, true)) {
|
|
22173
|
+
return void 0;
|
|
22174
|
+
}
|
|
22175
|
+
return worktree;
|
|
22176
|
+
}
|
|
22177
|
+
function openCodeFileIdentity(file2, worktree) {
|
|
22178
|
+
if (typeof file2 !== "string" || typeof worktree !== "string" || hasDotPathSegment(file2) || hasDotPathSegment(worktree) || !path4.isAbsolute(worktree) || !file2 || file2.includes("\0") || file2.includes("\n") || file2.includes("\r")) {
|
|
22179
|
+
return void 0;
|
|
22180
|
+
}
|
|
22181
|
+
const candidate = canonicalFilePath(path4.isAbsolute(file2) ? file2 : path4.resolve(worktree, file2));
|
|
22182
|
+
return candidate && pathIsWithin(worktree, candidate, false) ? candidate : void 0;
|
|
22183
|
+
}
|
|
22184
|
+
|
|
22112
22185
|
// dist/usage.js
|
|
22113
22186
|
function projectOpenCodeUsage(messages, contextWindowTokens) {
|
|
22114
22187
|
if (messages.length === 0)
|
|
@@ -22148,51 +22221,9 @@ function projectOpenCodeUsage(messages, contextWindowTokens) {
|
|
|
22148
22221
|
});
|
|
22149
22222
|
}
|
|
22150
22223
|
|
|
22151
|
-
// dist/
|
|
22152
|
-
var openCodeHarnessId2 = harnessIdSchema.parse("opencode");
|
|
22153
|
-
var DEFAULT_TOOL_OUTPUT_LIMIT = 64e3;
|
|
22154
|
-
var DEFAULT_CLOSE_TIMEOUT_MS2 = 3e3;
|
|
22155
|
-
var DIFF_RECONCILIATION_DELAYS_MS = [25, 50, 100, 200, 400, 800];
|
|
22156
|
-
var COMPACT_COMMAND_ID = "opencode.compact";
|
|
22224
|
+
// dist/history-projection.js
|
|
22157
22225
|
var SELECTION_METADATA_KEY = "codexhost.selection.v1";
|
|
22158
|
-
|
|
22159
|
-
return { code: "invalidState", message, retryable: false };
|
|
22160
|
-
}
|
|
22161
|
-
function unsupported(message) {
|
|
22162
|
-
return { code: "unsupported", message, retryable: false };
|
|
22163
|
-
}
|
|
22164
|
-
function normalizeError(error51, fallback) {
|
|
22165
|
-
if (error51 instanceof OpenCodeTransportError) {
|
|
22166
|
-
return {
|
|
22167
|
-
code: error51.code,
|
|
22168
|
-
message: error51.message,
|
|
22169
|
-
retryable: error51.code === "unavailable" || error51.code === "processExited" || error51.code === "authenticationRequired"
|
|
22170
|
-
};
|
|
22171
|
-
}
|
|
22172
|
-
const text = error51 instanceof Error ? error51.message : String(error51);
|
|
22173
|
-
const lower = text.toLowerCase();
|
|
22174
|
-
if (lower.includes("sessionbusy") || lower.includes("session busy")) {
|
|
22175
|
-
return { code: "sessionBusy", message: text, retryable: true };
|
|
22176
|
-
}
|
|
22177
|
-
if (lower.includes("not found")) {
|
|
22178
|
-
return { code: "sessionNotFound", message: text, retryable: false };
|
|
22179
|
-
}
|
|
22180
|
-
return {
|
|
22181
|
-
code: fallback,
|
|
22182
|
-
message: text,
|
|
22183
|
-
retryable: fallback === "unavailable" || fallback === "nativeFailure"
|
|
22184
|
-
};
|
|
22185
|
-
}
|
|
22186
|
-
function sameCwd(left, right) {
|
|
22187
|
-
const canonical = (value) => {
|
|
22188
|
-
try {
|
|
22189
|
-
return fs2.realpathSync.native(value);
|
|
22190
|
-
} catch {
|
|
22191
|
-
return path4.resolve(value);
|
|
22192
|
-
}
|
|
22193
|
-
};
|
|
22194
|
-
return canonical(left) === canonical(right);
|
|
22195
|
-
}
|
|
22226
|
+
var DIFF_RECONCILIATION_DELAYS_MS = [25, 50, 100, 200, 400, 800];
|
|
22196
22227
|
function storedSelection(session) {
|
|
22197
22228
|
const value = session.metadata?.[SELECTION_METADATA_KEY];
|
|
22198
22229
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
@@ -22242,32 +22273,62 @@ function nativeVariantFromSession(session, messages) {
|
|
|
22242
22273
|
}
|
|
22243
22274
|
return void 0;
|
|
22244
22275
|
}
|
|
22245
|
-
function
|
|
22276
|
+
function turnNativePatchFiles(messages, userMessageID) {
|
|
22246
22277
|
const start = messages.findIndex(({ info }) => info.id === userMessageID);
|
|
22247
22278
|
if (start < 0)
|
|
22248
|
-
return
|
|
22279
|
+
return [];
|
|
22249
22280
|
let end = start + 1;
|
|
22250
22281
|
while (end < messages.length && messages[end]?.info.role !== "user")
|
|
22251
22282
|
end += 1;
|
|
22252
|
-
return
|
|
22283
|
+
return [
|
|
22284
|
+
...new Set(messages.slice(start + 1, end).flatMap(({ parts }) => parts.flatMap((part) => part.type === "patch" ? part.files : [])))
|
|
22285
|
+
];
|
|
22253
22286
|
}
|
|
22254
|
-
async function readTurnDiff(transport, sessionID, userMessageID,
|
|
22287
|
+
async function readTurnDiff(transport, sessionID, userMessageID, nativePatchFiles, options = {}) {
|
|
22288
|
+
const strict = options.strict === true;
|
|
22255
22289
|
for (let attempt = 0; ; attempt += 1) {
|
|
22256
|
-
|
|
22257
|
-
|
|
22290
|
+
let diffs;
|
|
22291
|
+
try {
|
|
22292
|
+
diffs = await transport.getDiff(sessionID, userMessageID);
|
|
22293
|
+
} catch (error51) {
|
|
22294
|
+
if (strict) {
|
|
22295
|
+
throw new OpenCodeTransportError("protocolError", "OpenCode could not verify FileChange history", { cause: error51 });
|
|
22296
|
+
}
|
|
22297
|
+
diffs = [];
|
|
22298
|
+
}
|
|
22299
|
+
const reliableChanges = reliableOpenCodeFileChanges(diffs);
|
|
22300
|
+
const worktree = options.worktree;
|
|
22301
|
+
const reliablePaths = worktree ? reliableChanges.map(({ path: file2 }) => openCodeFileIdentity(file2, worktree)) : [];
|
|
22302
|
+
const nativePatchPaths = worktree ? nativePatchFiles.map((file2) => openCodeFileIdentity(file2, worktree)) : [];
|
|
22303
|
+
const completeStrictProjection = Boolean(worktree) && reliableChanges.length === diffs.length && reliablePaths.every((file2) => file2 !== void 0) && nativePatchPaths.every((file2) => file2 !== void 0 && reliablePaths.includes(file2));
|
|
22304
|
+
if (strict ? completeStrictProjection : reliableChanges.length > 0 || nativePatchFiles.length === 0) {
|
|
22305
|
+
return diffs;
|
|
22306
|
+
}
|
|
22307
|
+
if (attempt >= DIFF_RECONCILIATION_DELAYS_MS.length) {
|
|
22308
|
+
if (strict) {
|
|
22309
|
+
throw new OpenCodeTransportError("protocolError", "OpenCode did not expose complete reliable FileChange history");
|
|
22310
|
+
}
|
|
22258
22311
|
return diffs;
|
|
22259
22312
|
}
|
|
22260
22313
|
await new Promise((resolve) => setTimeout(resolve, DIFF_RECONCILIATION_DELAYS_MS[attempt]));
|
|
22261
22314
|
}
|
|
22262
22315
|
}
|
|
22263
|
-
async function readProjection(transport, sessionID, providerCatalog, toolOutputLimit) {
|
|
22264
|
-
const
|
|
22316
|
+
async function readProjection(transport, sessionID, providerCatalog, toolOutputLimit, options = {}) {
|
|
22317
|
+
const strictFileChanges = options.strictFileChanges === true;
|
|
22318
|
+
const [session, messages, paths] = await Promise.all([
|
|
22265
22319
|
transport.getSession(sessionID),
|
|
22266
|
-
transport.getMessages(sessionID)
|
|
22320
|
+
transport.getMessages(sessionID),
|
|
22321
|
+
strictFileChanges ? transport.getPaths().catch((error51) => {
|
|
22322
|
+
throw new OpenCodeTransportError("protocolError", "OpenCode could not verify worktree paths", { cause: error51 });
|
|
22323
|
+
}) : void 0
|
|
22267
22324
|
]);
|
|
22325
|
+
const worktree = paths ? verifiedOpenCodeWorktree(session.directory, paths) : void 0;
|
|
22326
|
+
if (strictFileChanges && !worktree) {
|
|
22327
|
+
throw new OpenCodeTransportError("protocolError", "OpenCode returned inconsistent Session and worktree paths");
|
|
22328
|
+
}
|
|
22268
22329
|
const userMessageIds = messages.filter(({ info }) => info.role === "user").map(({ info }) => info.id);
|
|
22269
22330
|
const diffEntries = await Promise.all(userMessageIds.map(async (messageID) => {
|
|
22270
|
-
const diffs = await readTurnDiff(transport, sessionID, messageID,
|
|
22331
|
+
const diffs = await readTurnDiff(transport, sessionID, messageID, turnNativePatchFiles(messages, messageID), { strict: strictFileChanges, ...worktree ? { worktree } : {} });
|
|
22271
22332
|
return [messageID, diffs];
|
|
22272
22333
|
}));
|
|
22273
22334
|
const snapshot = projectOpenCodeHistory({
|
|
@@ -22277,7 +22338,9 @@ async function readProjection(transport, sessionID, providerCatalog, toolOutputL
|
|
|
22277
22338
|
toolOutputLimit
|
|
22278
22339
|
});
|
|
22279
22340
|
const model = nativeModelFromSession(session, messages);
|
|
22280
|
-
const
|
|
22341
|
+
const nativeVariant = nativeVariantFromSession(session, messages);
|
|
22342
|
+
const nativeModel = model ? providerCatalog.all.find(({ id }) => id === model.providerID)?.models[model.modelID] : void 0;
|
|
22343
|
+
const variant = nativeVariant === "default" && nativeModel && !Object.hasOwn(nativeModel.variants ?? {}, "default") ? void 0 : nativeVariant;
|
|
22281
22344
|
const usage = projectOpenCodeUsage(openCodeAssistantMessages(session, messages), model ? openCodeContextWindow(providerCatalog, model) : void 0);
|
|
22282
22345
|
return {
|
|
22283
22346
|
session,
|
|
@@ -22288,6 +22351,128 @@ async function readProjection(transport, sessionID, providerCatalog, toolOutputL
|
|
|
22288
22351
|
...variant ? { variant } : {}
|
|
22289
22352
|
};
|
|
22290
22353
|
}
|
|
22354
|
+
|
|
22355
|
+
// dist/history-derivation.js
|
|
22356
|
+
import { isDeepStrictEqual } from "node:util";
|
|
22357
|
+
function semanticHistory(snapshot) {
|
|
22358
|
+
return snapshot.turns.map((turn) => ({
|
|
22359
|
+
input: turn.input,
|
|
22360
|
+
items: turn.items.map(({ item, outcome }) => {
|
|
22361
|
+
const { itemId: _itemId, ...content } = item;
|
|
22362
|
+
void _itemId;
|
|
22363
|
+
return { item: content, outcome };
|
|
22364
|
+
}),
|
|
22365
|
+
outcome: turn.outcome,
|
|
22366
|
+
model: turn.model,
|
|
22367
|
+
checkpoint: Boolean(turn.checkpoint)
|
|
22368
|
+
}));
|
|
22369
|
+
}
|
|
22370
|
+
function sourceState(projection) {
|
|
22371
|
+
return {
|
|
22372
|
+
id: projection.session.id,
|
|
22373
|
+
directory: projection.session.directory,
|
|
22374
|
+
revert: projection.session.revert,
|
|
22375
|
+
metadata: projection.session.metadata,
|
|
22376
|
+
permission: projection.session.permission,
|
|
22377
|
+
model: projection.model,
|
|
22378
|
+
variant: projection.variant,
|
|
22379
|
+
snapshot: projection.snapshot
|
|
22380
|
+
};
|
|
22381
|
+
}
|
|
22382
|
+
async function deriveOpenCodeHistory(options) {
|
|
22383
|
+
const { transport, source, input, providers, toolOutputLimit } = options;
|
|
22384
|
+
const read = (id) => readProjection(transport, id, providers, toolOutputLimit, { strictFileChanges: true });
|
|
22385
|
+
if ((await transport.getStatus(source.id)).type !== "idle") {
|
|
22386
|
+
throw new Error("OpenCode source Session is busy");
|
|
22387
|
+
}
|
|
22388
|
+
const before = await read(source.id);
|
|
22389
|
+
const expectedSource = structuredClone(sourceState(before));
|
|
22390
|
+
let messageID;
|
|
22391
|
+
let retainedCount;
|
|
22392
|
+
if (input.kind === "fork") {
|
|
22393
|
+
const boundary = resolveOpenCodeForkBoundary(before.session, before.messages, input.checkpoint);
|
|
22394
|
+
if (!boundary)
|
|
22395
|
+
throw new OpenCodeTransportError("checkpointNotFound", "OpenCode Checkpoint is not on the source Session transcript");
|
|
22396
|
+
messageID = boundary.messageID;
|
|
22397
|
+
retainedCount = boundary.sourceTurnCount;
|
|
22398
|
+
} else {
|
|
22399
|
+
const boundary = resolveOpenCodeLastTurnBoundary(before.session, before.messages);
|
|
22400
|
+
if (!boundary)
|
|
22401
|
+
throw new OpenCodeTransportError("invalidState", "OpenCode Native Session has no Turn to roll back");
|
|
22402
|
+
messageID = boundary.lastUserMessageID;
|
|
22403
|
+
retainedCount = boundary.sourceTurnCount - 1;
|
|
22404
|
+
}
|
|
22405
|
+
const expectedHistory = structuredClone(semanticHistory(before.snapshot).slice(0, retainedCount));
|
|
22406
|
+
let candidate = await transport.forkSession(source.id, messageID);
|
|
22407
|
+
if (candidate.id === source.id) {
|
|
22408
|
+
throw new OpenCodeTransportError("protocolError", "OpenCode Fork did not create a distinct Native Session");
|
|
22409
|
+
}
|
|
22410
|
+
const candidateID = candidate.id;
|
|
22411
|
+
options.onCreated(candidate);
|
|
22412
|
+
if (candidate.directory !== expectedSource.directory) {
|
|
22413
|
+
throw new OpenCodeTransportError("protocolError", "OpenCode Fork changed working directory");
|
|
22414
|
+
}
|
|
22415
|
+
if (expectedSource.model) {
|
|
22416
|
+
candidate = await transport.updateSessionMetadata(candidateID, selectionMetadata(candidate, expectedSource.model, expectedSource.variant));
|
|
22417
|
+
}
|
|
22418
|
+
if (!isDeepStrictEqual(candidate.permission ?? [], expectedSource.permission ?? [])) {
|
|
22419
|
+
candidate = await transport.updateSessionPermission(candidateID, expectedSource.permission ?? []);
|
|
22420
|
+
}
|
|
22421
|
+
const [derived, after, candidateStatus, sourceStatus] = await Promise.all([
|
|
22422
|
+
read(candidateID),
|
|
22423
|
+
read(source.id),
|
|
22424
|
+
transport.getStatus(candidateID),
|
|
22425
|
+
transport.getStatus(source.id)
|
|
22426
|
+
]);
|
|
22427
|
+
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 ?? [])) {
|
|
22428
|
+
throw new OpenCodeTransportError("protocolError", "OpenCode derived history, source or configuration changed during Fork");
|
|
22429
|
+
}
|
|
22430
|
+
return derived.session;
|
|
22431
|
+
}
|
|
22432
|
+
|
|
22433
|
+
// dist/opencode-adapter.js
|
|
22434
|
+
var openCodeHarnessId2 = harnessIdSchema.parse("opencode");
|
|
22435
|
+
var DEFAULT_TOOL_OUTPUT_LIMIT = 64e3;
|
|
22436
|
+
var DEFAULT_CLOSE_TIMEOUT_MS2 = 3e3;
|
|
22437
|
+
var COMPACT_COMMAND_ID = "opencode.compact";
|
|
22438
|
+
function invalidState(message) {
|
|
22439
|
+
return { code: "invalidState", message, retryable: false };
|
|
22440
|
+
}
|
|
22441
|
+
function unsupported(message) {
|
|
22442
|
+
return { code: "unsupported", message, retryable: false };
|
|
22443
|
+
}
|
|
22444
|
+
function normalizeError(error51, fallback) {
|
|
22445
|
+
if (error51 instanceof OpenCodeTransportError) {
|
|
22446
|
+
return {
|
|
22447
|
+
code: error51.code,
|
|
22448
|
+
message: error51.message,
|
|
22449
|
+
retryable: error51.code === "unavailable" || error51.code === "processExited" || error51.code === "authenticationRequired"
|
|
22450
|
+
};
|
|
22451
|
+
}
|
|
22452
|
+
const text = error51 instanceof Error ? error51.message : String(error51);
|
|
22453
|
+
const lower = text.toLowerCase();
|
|
22454
|
+
if (lower.includes("sessionbusy") || lower.includes("session busy")) {
|
|
22455
|
+
return { code: "sessionBusy", message: text, retryable: true };
|
|
22456
|
+
}
|
|
22457
|
+
if (lower.includes("not found")) {
|
|
22458
|
+
return { code: "sessionNotFound", message: text, retryable: false };
|
|
22459
|
+
}
|
|
22460
|
+
return {
|
|
22461
|
+
code: fallback,
|
|
22462
|
+
message: text,
|
|
22463
|
+
retryable: fallback === "unavailable" || fallback === "nativeFailure"
|
|
22464
|
+
};
|
|
22465
|
+
}
|
|
22466
|
+
function sameCwd(left, right) {
|
|
22467
|
+
const canonical = (value) => {
|
|
22468
|
+
try {
|
|
22469
|
+
return fs3.realpathSync.native(value);
|
|
22470
|
+
} catch {
|
|
22471
|
+
return path5.resolve(value);
|
|
22472
|
+
}
|
|
22473
|
+
};
|
|
22474
|
+
return canonical(left) === canonical(right);
|
|
22475
|
+
}
|
|
22291
22476
|
function sessionState(session, modelCatalog, model, variant, executionPolicy = "default", permissionModeId = OPENCODE_DEFAULT_PERMISSION_MODE_ID) {
|
|
22292
22477
|
const effectiveModel = model ? encodeOpenCodeModelRef(model) : void 0;
|
|
22293
22478
|
const modelEntry = effectiveModel ? modelCatalog.models.find(({ ref }) => ref.id === effectiveModel.id) : void 0;
|
|
@@ -22849,6 +23034,11 @@ var OpenCodeHarnessSession = class {
|
|
|
22849
23034
|
}
|
|
22850
23035
|
if (event.type === "session.error" && event.properties.sessionID === this.#session.id && active) {
|
|
22851
23036
|
const error51 = event.properties.error;
|
|
23037
|
+
if (active.cancellationRequested || error51?.name === "MessageAbortedError") {
|
|
23038
|
+
active.cancellationRequested = true;
|
|
23039
|
+
void this.#reconcileAndFinish(active);
|
|
23040
|
+
return;
|
|
23041
|
+
}
|
|
22852
23042
|
this.#completeTurn(active, {
|
|
22853
23043
|
status: active.cancellationRequested ? "cancelled" : "failed",
|
|
22854
23044
|
...active.cancellationRequested ? { reason: "Cancelled by user" } : {
|
|
@@ -23102,6 +23292,19 @@ var OpenCodeHarnessSession = class {
|
|
|
23102
23292
|
const assistants = messages.slice(userIndex + 1, end).filter((entry) => entry.info.role === "assistant");
|
|
23103
23293
|
const terminal = assistants.at(-1)?.info ?? active.terminalAssistant;
|
|
23104
23294
|
if (!terminal || terminal.time.completed === void 0 && !terminal.finish && !terminal.error && !active.nativeCompleted) {
|
|
23295
|
+
if (active.cancellationRequested) {
|
|
23296
|
+
for (const entry of assistants) {
|
|
23297
|
+
for (const part of entry.parts)
|
|
23298
|
+
this.#projectPart(active, part);
|
|
23299
|
+
}
|
|
23300
|
+
this.#completeTurn(active, { status: "cancelled", reason: "Cancelled by user" }, {
|
|
23301
|
+
harnessId: this.harnessId,
|
|
23302
|
+
nativeSessionId: this.#session.id,
|
|
23303
|
+
nativeTurnKey: active.userMessageID,
|
|
23304
|
+
formatVersion: 1
|
|
23305
|
+
});
|
|
23306
|
+
void this.#refreshProjection(active.turnId);
|
|
23307
|
+
}
|
|
23105
23308
|
return;
|
|
23106
23309
|
}
|
|
23107
23310
|
for (const entry of assistants) {
|
|
@@ -23110,7 +23313,7 @@ var OpenCodeHarnessSession = class {
|
|
|
23110
23313
|
}
|
|
23111
23314
|
active.terminalAssistant = terminal;
|
|
23112
23315
|
const userMessageID = active.userMessageID;
|
|
23113
|
-
const changes = reliableOpenCodeFileChanges(await readTurnDiff(this.#transport, this.#session.id, userMessageID,
|
|
23316
|
+
const changes = reliableOpenCodeFileChanges(await readTurnDiff(this.#transport, this.#session.id, userMessageID, turnNativePatchFiles(messages, userMessageID)));
|
|
23114
23317
|
if (changes.length > 0) {
|
|
23115
23318
|
const id = `opencode-live-diff:${active.userMessageID}`;
|
|
23116
23319
|
if (!active.items.has(id)) {
|
|
@@ -23487,7 +23690,6 @@ var OpenCodeAdapter = class {
|
|
|
23487
23690
|
let connection;
|
|
23488
23691
|
let transport;
|
|
23489
23692
|
let createdForCleanup;
|
|
23490
|
-
let revertedForCleanup;
|
|
23491
23693
|
try {
|
|
23492
23694
|
const sourceRef = input.kind === "create" ? void 0 : parseOpenCodeSessionRef(input.kind === "resume" ? input.nativeRef : input.sourceRef);
|
|
23493
23695
|
const executionPolicy = input.kind === "create" ? input.executionPolicy ?? "default" : sourceRef?.executionPolicy ?? "default";
|
|
@@ -23566,61 +23768,17 @@ var OpenCodeAdapter = class {
|
|
|
23566
23768
|
}
|
|
23567
23769
|
if (input.kind === "resume") {
|
|
23568
23770
|
session = source;
|
|
23569
|
-
} else if (input.kind === "fork") {
|
|
23570
|
-
const checkpoint = nativeCheckpointRefSchema.parse(input.checkpoint);
|
|
23571
|
-
if (checkpoint.harnessId !== this.harnessId || checkpoint.nativeSessionId !== source.id) {
|
|
23572
|
-
throw new OpenCodeTransportError("protocolError", "OpenCode Checkpoint does not belong to the source Session");
|
|
23573
|
-
}
|
|
23574
|
-
const sourceMessages = await transport.getMessages(source.id);
|
|
23575
|
-
const boundary = resolveOpenCodeForkBoundary(source, sourceMessages, checkpoint);
|
|
23576
|
-
if (!boundary) {
|
|
23577
|
-
await transport.close().catch(() => void 0);
|
|
23578
|
-
await connection.close().catch(() => void 0);
|
|
23579
|
-
return {
|
|
23580
|
-
ok: false,
|
|
23581
|
-
error: {
|
|
23582
|
-
code: "checkpointNotFound",
|
|
23583
|
-
message: "OpenCode Checkpoint is not on the source Session transcript",
|
|
23584
|
-
retryable: false
|
|
23585
|
-
}
|
|
23586
|
-
};
|
|
23587
|
-
}
|
|
23588
|
-
session = await transport.forkSession(source.id, boundary.messageID);
|
|
23589
|
-
createdForCleanup = session;
|
|
23590
|
-
if (session.id === source.id) {
|
|
23591
|
-
throw new OpenCodeTransportError("protocolError", "OpenCode Fork did not create a distinct Native Session");
|
|
23592
|
-
}
|
|
23593
|
-
const derivedMessages = await transport.getMessages(session.id);
|
|
23594
|
-
const derived = projectOpenCodeHistory({
|
|
23595
|
-
session,
|
|
23596
|
-
messages: derivedMessages,
|
|
23597
|
-
toolOutputLimit: this.#toolOutputLimit
|
|
23598
|
-
});
|
|
23599
|
-
if (derived.turns.length !== boundary.sourceTurnCount) {
|
|
23600
|
-
throw new OpenCodeTransportError("protocolError", "OpenCode Fork derived history does not match the requested Checkpoint");
|
|
23601
|
-
}
|
|
23602
23771
|
} else {
|
|
23603
|
-
|
|
23604
|
-
|
|
23605
|
-
|
|
23606
|
-
|
|
23607
|
-
|
|
23608
|
-
|
|
23609
|
-
|
|
23610
|
-
|
|
23611
|
-
}
|
|
23612
|
-
}
|
|
23613
|
-
session = await transport.revertSession(source.id, boundary.lastUserMessageID);
|
|
23614
|
-
revertedForCleanup = source.id;
|
|
23615
|
-
const afterMessages = await transport.getMessages(session.id);
|
|
23616
|
-
const after = projectOpenCodeHistory({
|
|
23617
|
-
session,
|
|
23618
|
-
messages: afterMessages,
|
|
23619
|
-
toolOutputLimit: this.#toolOutputLimit
|
|
23772
|
+
session = await deriveOpenCodeHistory({
|
|
23773
|
+
transport,
|
|
23774
|
+
source,
|
|
23775
|
+
input,
|
|
23776
|
+
providers,
|
|
23777
|
+
toolOutputLimit: this.#toolOutputLimit,
|
|
23778
|
+
onCreated: (candidate) => {
|
|
23779
|
+
createdForCleanup = candidate;
|
|
23780
|
+
}
|
|
23620
23781
|
});
|
|
23621
|
-
if (after.turns.length !== boundary.sourceTurnCount - 1) {
|
|
23622
|
-
throw new OpenCodeTransportError("protocolError", "OpenCode rollback did not remove exactly the last Turn");
|
|
23623
|
-
}
|
|
23624
23782
|
}
|
|
23625
23783
|
}
|
|
23626
23784
|
const projection = await readProjection(transport, session.id, providers, this.#toolOutputLimit);
|
|
@@ -23640,12 +23798,8 @@ var OpenCodeAdapter = class {
|
|
|
23640
23798
|
await harnessSession.start();
|
|
23641
23799
|
this.#sessions.add(harnessSession);
|
|
23642
23800
|
createdForCleanup = void 0;
|
|
23643
|
-
revertedForCleanup = void 0;
|
|
23644
23801
|
return { ok: true, value: harnessSession };
|
|
23645
23802
|
} catch (error51) {
|
|
23646
|
-
if (revertedForCleanup && transport) {
|
|
23647
|
-
await transport.unrevertSession(revertedForCleanup).catch(() => void 0);
|
|
23648
|
-
}
|
|
23649
23803
|
if (createdForCleanup && transport) {
|
|
23650
23804
|
await transport.deleteSession(createdForCleanup.id).catch(() => void 0);
|
|
23651
23805
|
}
|