ds-harness-remote 0.4.10 → 0.4.13
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 +9 -4
- package/dist/client-runtime.d.ts +10 -1
- package/dist/client-runtime.d.ts.map +1 -1
- package/dist/client-runtime.js +47 -22
- package/dist/client-runtime.js.map +1 -1
- package/dist/client.github.js +1 -1
- package/dist/client.js +1 -1
- package/dist/client.js.map +1 -1
- package/dist/codex/peer-bridge.d.ts.map +1 -1
- package/dist/codex/peer-bridge.js +3 -4
- package/dist/codex/peer-bridge.js.map +1 -1
- package/dist/codex/virtual-harness.d.ts +12 -3
- package/dist/codex/virtual-harness.d.ts.map +1 -1
- package/dist/codex/virtual-harness.js +155 -37
- package/dist/codex/virtual-harness.js.map +1 -1
- package/dist/control-route.d.ts +22 -0
- package/dist/control-route.d.ts.map +1 -1
- package/dist/control-route.js +120 -0
- package/dist/control-route.js.map +1 -1
- package/dist/control-runtime.d.ts +2 -1
- package/dist/control-runtime.d.ts.map +1 -1
- package/dist/control-runtime.js +3 -5
- package/dist/control-runtime.js.map +1 -1
- package/dist/harness-api-bridge.d.ts.map +1 -1
- package/dist/harness-api-bridge.js +3 -3
- package/dist/harness-api-bridge.js.map +1 -1
- package/dist/harness-remote-bridge.d.ts.map +1 -1
- package/dist/harness-remote-bridge.js +3 -4
- package/dist/harness-remote-bridge.js.map +1 -1
- package/dist/harness-version.d.ts +7 -0
- package/dist/harness-version.d.ts.map +1 -1
- package/dist/harness-version.js +16 -0
- package/dist/harness-version.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +738 -219
- package/dist/index.js.map +4 -4
- package/dist/remote-api-proxy.d.ts.map +1 -1
- package/dist/remote-api-proxy.js +34 -1
- package/dist/remote-api-proxy.js.map +1 -1
- package/dist/remote-typert-gateway.d.ts +3 -1
- package/dist/remote-typert-gateway.d.ts.map +1 -1
- package/dist/remote-typert-gateway.js +16 -5
- package/dist/remote-typert-gateway.js.map +1 -1
- package/dist/service.d.ts +1 -0
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +8 -4
- package/dist/service.js.map +1 -1
- package/dist/session-format-compat.d.ts +3 -0
- package/dist/session-format-compat.d.ts.map +1 -0
- package/dist/session-format-compat.js +183 -0
- package/dist/session-format-compat.js.map +1 -0
- package/dist/tui-command.js +5 -3
- package/dist/tui-command.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dsh-plugin.json +1 -1
- package/package.json +21 -21
package/dist/index.js
CHANGED
|
@@ -4059,6 +4059,13 @@ var MAX_DEVICE_NAME_LENGTH = 128;
|
|
|
4059
4059
|
var MAX_DEVICE_PLATFORM_LENGTH = 64;
|
|
4060
4060
|
var MAX_DEVICE_VERSION_LENGTH = 64;
|
|
4061
4061
|
var MAX_AUTH_TOKEN_LENGTH = 8 * 1024;
|
|
4062
|
+
var HOST_REGISTRATION_CODE_TTL_MS = 10 * 6e4;
|
|
4063
|
+
var MAX_ACTIVE_TRANSFERS_PER_DIRECTION = 2;
|
|
4064
|
+
var TRANSFER_IDLE_MS = 2 * 6e4;
|
|
4065
|
+
var MAX_RPC_TEXT_INPUT_BYTES = 64 * 1024;
|
|
4066
|
+
var MAX_FILEVIEWER_RANGE_BYTES = 512 * 1024;
|
|
4067
|
+
var MIN_REPLAY_WINDOW_MS = 15 * 6e4;
|
|
4068
|
+
var MAX_ALPHA_STREAMS_PER_CONNECTION = 16;
|
|
4062
4069
|
var SECURE_FRAGMENT_MAGIC = new Uint8Array([68, 83, 72, 70]);
|
|
4063
4070
|
var SECURE_FRAGMENT_VERSION = 1;
|
|
4064
4071
|
var SECURE_FRAGMENT_HEADER_BYTES = 17;
|
|
@@ -4116,6 +4123,52 @@ var rpcMethods = [
|
|
|
4116
4123
|
"codex.app.transfer.read",
|
|
4117
4124
|
"codex.app.transfer.close"
|
|
4118
4125
|
];
|
|
4126
|
+
var errorCodes = [
|
|
4127
|
+
// Protocol / Version
|
|
4128
|
+
"INVALID_MESSAGE",
|
|
4129
|
+
"UNSUPPORTED_VERSION",
|
|
4130
|
+
"CAPABILITY_NOT_SUPPORTED",
|
|
4131
|
+
"METHOD_NOT_FOUND",
|
|
4132
|
+
"METHOD_NOT_ALLOWED",
|
|
4133
|
+
"REQUEST_CONFLICT",
|
|
4134
|
+
"FRAME_TOO_LARGE",
|
|
4135
|
+
"RATE_LIMITED",
|
|
4136
|
+
// Auth / Device
|
|
4137
|
+
"AUTH_REQUIRED",
|
|
4138
|
+
"AUTH_INVALID",
|
|
4139
|
+
"ACCOUNT_AUTH_REQUIRED",
|
|
4140
|
+
"TOKEN_EXPIRED",
|
|
4141
|
+
"DEVICE_NOT_FOUND",
|
|
4142
|
+
"DEVICE_REVOKED",
|
|
4143
|
+
"DEVICE_OWNERSHIP_REQUIRED",
|
|
4144
|
+
"MEMBERSHIP_REQUIRED",
|
|
4145
|
+
"PEER_IDENTITY_MISMATCH",
|
|
4146
|
+
"HOST_REGISTRATION_CODE_NOT_FOUND",
|
|
4147
|
+
"HOST_REGISTRATION_CODE_EXPIRED",
|
|
4148
|
+
"HOST_REGISTRATION_CODE_CONSUMED",
|
|
4149
|
+
// Connection / Transport
|
|
4150
|
+
"HOST_OFFLINE",
|
|
4151
|
+
"CONNECTION_NOT_FOUND",
|
|
4152
|
+
"CONNECTION_FAILED",
|
|
4153
|
+
"CONNECTION_REPLACED",
|
|
4154
|
+
"P2P_FAILED",
|
|
4155
|
+
"TURN_UNAVAILABLE",
|
|
4156
|
+
"RELAY_UNAVAILABLE",
|
|
4157
|
+
"SLOW_CONSUMER",
|
|
4158
|
+
"SECURE_CHANNEL_FAILED",
|
|
4159
|
+
// Harness
|
|
4160
|
+
"HARNESS_UNAVAILABLE",
|
|
4161
|
+
"HARNESS_VERSION_INCOMPATIBLE",
|
|
4162
|
+
"RESPONSE_TOO_LARGE",
|
|
4163
|
+
"SESSION_NOT_FOUND",
|
|
4164
|
+
"SESSION_NOT_READY",
|
|
4165
|
+
"AGENT_BUSY",
|
|
4166
|
+
"PERMISSION_DENIED",
|
|
4167
|
+
"PERMISSION_NOT_PENDING",
|
|
4168
|
+
"RPC_TIMEOUT",
|
|
4169
|
+
"FULL_RESYNC_REQUIRED",
|
|
4170
|
+
"INTERNAL_ERROR"
|
|
4171
|
+
];
|
|
4119
4172
|
var selectedTransports = ["lan", "p2p", "turn", "relay"];
|
|
4120
4173
|
function normalizeSdpMLineIndex(value) {
|
|
4121
4174
|
if (value === void 0)
|
|
@@ -4140,6 +4193,7 @@ function acceptNegotiatedCapabilities(offered, negotiated) {
|
|
|
4140
4193
|
var rpcMethodSchema = external_exports.enum(rpcMethods);
|
|
4141
4194
|
var messageTypeSchema = external_exports.enum(messageTypes);
|
|
4142
4195
|
var controlFrameTypeSchema = external_exports.enum(controlFrameTypes);
|
|
4196
|
+
var errorCodeSchema = external_exports.enum(errorCodes);
|
|
4143
4197
|
var uniqueStrings = (values) => new Set(values).size === values.length;
|
|
4144
4198
|
var uniqueNumbers = (values) => new Set(values).size === values.length;
|
|
4145
4199
|
var utf8Length = (value) => new TextEncoder().encode(value).byteLength;
|
|
@@ -4181,6 +4235,10 @@ var hostRegistrationCodeRequestSchema = external_exports.object({
|
|
|
4181
4235
|
code: external_exports.string().regex(/^[A-Z0-9]{4}-[A-Z0-9]{4}$/u),
|
|
4182
4236
|
device: hostDeviceDescriptorSchema
|
|
4183
4237
|
}).strict();
|
|
4238
|
+
var registerOwnedRoleRequestSchema = external_exports.object({
|
|
4239
|
+
v: external_exports.literal(PROTOCOL_VERSION),
|
|
4240
|
+
device: accountDeviceDescriptorSchema
|
|
4241
|
+
}).strict();
|
|
4184
4242
|
var deviceRefreshRequestSchema = external_exports.object({
|
|
4185
4243
|
deviceId: deviceIdSchema,
|
|
4186
4244
|
refreshToken: authTokenSchema
|
|
@@ -13958,6 +14016,120 @@ async function waitForResponder(inner, noise) {
|
|
|
13958
14016
|
|
|
13959
14017
|
// src/control-route.ts
|
|
13960
14018
|
var CONTROL_RPC_PREFIX = "/ds-harness-remote";
|
|
14019
|
+
var ENDPOINT_SEGMENT_PATTERN = /^[A-Za-z0-9_$.-]+$/;
|
|
14020
|
+
var INVALID_REQUEST_RPC_ID = "invalid-request";
|
|
14021
|
+
function registerControlRoute(connection, handler, webServer) {
|
|
14022
|
+
if (webServer !== void 0 && connection.requestRejection !== void 0) {
|
|
14023
|
+
const dispose = webServer.register({
|
|
14024
|
+
kind: "prefix",
|
|
14025
|
+
path: CONTROL_RPC_PREFIX,
|
|
14026
|
+
handler: (req, res) => handleControlRequest(connection, handler, req, res)
|
|
14027
|
+
});
|
|
14028
|
+
return async () => {
|
|
14029
|
+
await dispose();
|
|
14030
|
+
};
|
|
14031
|
+
}
|
|
14032
|
+
return connection.rpc.handle(CONTROL_RPC_PREFIX, handler, {
|
|
14033
|
+
authority: "loopback"
|
|
14034
|
+
});
|
|
14035
|
+
}
|
|
14036
|
+
async function handleControlRequest(connection, handler, req, res) {
|
|
14037
|
+
const rejection = connection.requestRejection?.(req);
|
|
14038
|
+
if (rejection !== void 0) {
|
|
14039
|
+
res.writeHead(rejection);
|
|
14040
|
+
res.end(rejection === 401 ? "unauthorized" : "forbidden");
|
|
14041
|
+
return;
|
|
14042
|
+
}
|
|
14043
|
+
const endpoint = endpointFromPath(CONTROL_RPC_PREFIX, new URL(req.url ?? "/", "http://dsh.internal").pathname);
|
|
14044
|
+
if (req.method !== "POST" || endpoint === void 0) {
|
|
14045
|
+
writeText(res, 404, "not found");
|
|
14046
|
+
return;
|
|
14047
|
+
}
|
|
14048
|
+
if (contentType(req.headers) !== "application/json") {
|
|
14049
|
+
writeText(res, 415, "content type must be application/json");
|
|
14050
|
+
return;
|
|
14051
|
+
}
|
|
14052
|
+
let body;
|
|
14053
|
+
try {
|
|
14054
|
+
body = await readJsonBody(req);
|
|
14055
|
+
} catch {
|
|
14056
|
+
writeText(res, 400, "body is not JSON");
|
|
14057
|
+
return;
|
|
14058
|
+
}
|
|
14059
|
+
const message = clientRequest(body);
|
|
14060
|
+
if (message === void 0) {
|
|
14061
|
+
writeJson(res, 200, errorResponse(rpcId(body), {
|
|
14062
|
+
code: "gateway/bad-request",
|
|
14063
|
+
message: "invalid client-request message",
|
|
14064
|
+
details: { issues: [] }
|
|
14065
|
+
}));
|
|
14066
|
+
return;
|
|
14067
|
+
}
|
|
14068
|
+
if (message.method !== endpoint) {
|
|
14069
|
+
writeJson(res, 200, errorResponse(message.rpcId, {
|
|
14070
|
+
code: "gateway/bad-request",
|
|
14071
|
+
message: `method ${JSON.stringify(message.method)} does not match endpoint ${JSON.stringify(endpoint)}`,
|
|
14072
|
+
details: { issues: [] }
|
|
14073
|
+
}));
|
|
14074
|
+
return;
|
|
14075
|
+
}
|
|
14076
|
+
try {
|
|
14077
|
+
const result = await handler(endpoint, message.payload, requestSignal(req));
|
|
14078
|
+
writeJson(res, 200, fullResponse(message.rpcId, result));
|
|
14079
|
+
} catch (error) {
|
|
14080
|
+
writeText(res, 500, `handler failure: ${String(error)}`);
|
|
14081
|
+
}
|
|
14082
|
+
}
|
|
14083
|
+
function endpointFromPath(channel, pathname) {
|
|
14084
|
+
if (!pathname.startsWith(`${channel}/`)) return void 0;
|
|
14085
|
+
const endpoint = pathname.slice(channel.length + 1);
|
|
14086
|
+
if (endpoint.split("/").some((segment) => segment === "" || segment === "." || segment === ".." || !ENDPOINT_SEGMENT_PATTERN.test(segment))) {
|
|
14087
|
+
return void 0;
|
|
14088
|
+
}
|
|
14089
|
+
return endpoint;
|
|
14090
|
+
}
|
|
14091
|
+
function contentType(headers) {
|
|
14092
|
+
const raw = headers["content-type"];
|
|
14093
|
+
const value = Array.isArray(raw) ? raw[0] : raw;
|
|
14094
|
+
return value?.split(";", 1)[0]?.trim().toLowerCase();
|
|
14095
|
+
}
|
|
14096
|
+
async function readJsonBody(req) {
|
|
14097
|
+
const chunks = [];
|
|
14098
|
+
for await (const chunk of req) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
14099
|
+
return JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
14100
|
+
}
|
|
14101
|
+
function requestSignal(req) {
|
|
14102
|
+
const abort = new AbortController();
|
|
14103
|
+
req.on("close", () => {
|
|
14104
|
+
if (!req.complete) abort.abort();
|
|
14105
|
+
});
|
|
14106
|
+
return abort.signal;
|
|
14107
|
+
}
|
|
14108
|
+
function clientRequest(value) {
|
|
14109
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
14110
|
+
const record6 = value;
|
|
14111
|
+
if (record6.type !== "client-request" || typeof record6.rpcId !== "string" || typeof record6.method !== "string") return void 0;
|
|
14112
|
+
return { type: "client-request", rpcId: record6.rpcId, method: record6.method, payload: record6.payload };
|
|
14113
|
+
}
|
|
14114
|
+
function rpcId(value) {
|
|
14115
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return INVALID_REQUEST_RPC_ID;
|
|
14116
|
+
const record6 = value;
|
|
14117
|
+
return typeof record6.rpcId === "string" ? record6.rpcId : INVALID_REQUEST_RPC_ID;
|
|
14118
|
+
}
|
|
14119
|
+
function errorResponse(rpcId2, error) {
|
|
14120
|
+
return fullResponse(rpcId2, { ok: false, error });
|
|
14121
|
+
}
|
|
14122
|
+
function fullResponse(rpcId2, result) {
|
|
14123
|
+
return { type: "server-response", rpcId: rpcId2, result };
|
|
14124
|
+
}
|
|
14125
|
+
function writeJson(res, status2, body) {
|
|
14126
|
+
res.writeHead(status2, { "content-type": "application/json" });
|
|
14127
|
+
res.end(JSON.stringify(body));
|
|
14128
|
+
}
|
|
14129
|
+
function writeText(res, status2, body) {
|
|
14130
|
+
res.writeHead(status2);
|
|
14131
|
+
res.end(body);
|
|
14132
|
+
}
|
|
13961
14133
|
|
|
13962
14134
|
// src/ids.ts
|
|
13963
14135
|
import { randomBytes as randomBytes6 } from "node:crypto";
|
|
@@ -13977,8 +14149,51 @@ function uuidV7(now = Date.now()) {
|
|
|
13977
14149
|
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
13978
14150
|
}
|
|
13979
14151
|
|
|
14152
|
+
// src/harness-version.ts
|
|
14153
|
+
import { readFile } from "node:fs/promises";
|
|
14154
|
+
import { dirname, isAbsolute, join } from "node:path";
|
|
14155
|
+
var LEGACY_PLACEHOLDER_VERSION = "0.0.1";
|
|
14156
|
+
function normalizeHarnessVersion(value) {
|
|
14157
|
+
if (typeof value !== "string") return void 0;
|
|
14158
|
+
const version = value.trim();
|
|
14159
|
+
if (version.length === 0 || version.length > 64 || /[\u0000-\u001f]/u.test(version)) return void 0;
|
|
14160
|
+
return version;
|
|
14161
|
+
}
|
|
14162
|
+
function selectHarnessVersion(reportedVersion, distributionVersion) {
|
|
14163
|
+
if (reportedVersion !== void 0 && reportedVersion !== LEGACY_PLACEHOLDER_VERSION) return reportedVersion;
|
|
14164
|
+
return distributionVersion;
|
|
14165
|
+
}
|
|
14166
|
+
function harnessSessionGeneration(version) {
|
|
14167
|
+
if (version === void 0) return "legacy";
|
|
14168
|
+
const match = /^(?:dsh-)?v?(\d+)\.(\d+)\.(\d+)(?:-|$)/u.exec(version.trim());
|
|
14169
|
+
if (match === null) return "legacy";
|
|
14170
|
+
const major = Number(match[1]);
|
|
14171
|
+
const minor = Number(match[2]);
|
|
14172
|
+
const patch = Number(match[3]);
|
|
14173
|
+
return major === 0 && minor === 1 && patch >= 5 ? "v3" : "legacy";
|
|
14174
|
+
}
|
|
14175
|
+
async function readHarnessDistributionVersion(entrypoint = process.argv[1]) {
|
|
14176
|
+
if (entrypoint === void 0 || !isAbsolute(entrypoint)) return void 0;
|
|
14177
|
+
let directory = dirname(entrypoint);
|
|
14178
|
+
for (let depth = 0; depth < 8; depth += 1) {
|
|
14179
|
+
try {
|
|
14180
|
+
const manifest = JSON.parse(await readFile(join(directory, "package.json"), "utf8"));
|
|
14181
|
+
if (manifest.name === "@deepseek-ai/dsh") return normalizeHarnessVersion(manifest.version);
|
|
14182
|
+
} catch {
|
|
14183
|
+
}
|
|
14184
|
+
const parent = dirname(directory);
|
|
14185
|
+
if (parent === directory) break;
|
|
14186
|
+
directory = parent;
|
|
14187
|
+
}
|
|
14188
|
+
return void 0;
|
|
14189
|
+
}
|
|
14190
|
+
|
|
13980
14191
|
// src/remote-api-proxy.ts
|
|
13981
14192
|
var DIRECT_API_CALL_BYTES = 2 * 1024 * 1024;
|
|
14193
|
+
var AGENT_PRESET_SETTINGS_NS = "agent-presets";
|
|
14194
|
+
var LEGACY_AGENT_PRESET_ALIASES = {
|
|
14195
|
+
code: "ptc"
|
|
14196
|
+
};
|
|
13982
14197
|
var RemoteHarnessApiProxy = class {
|
|
13983
14198
|
constructor(client) {
|
|
13984
14199
|
this.client = client;
|
|
@@ -14067,7 +14282,7 @@ var RemoteHarnessApiProxy = class {
|
|
|
14067
14282
|
const params = {
|
|
14068
14283
|
method,
|
|
14069
14284
|
rpcId: String(request.rpcId),
|
|
14070
|
-
payload: request.payload
|
|
14285
|
+
payload: normalizeLegacyRequest(method, request.payload)
|
|
14071
14286
|
};
|
|
14072
14287
|
const encoded = new TextEncoder().encode(JSON.stringify(params));
|
|
14073
14288
|
const response = method === "session.attachment" || encoded.byteLength > DIRECT_API_CALL_BYTES ? await this.callTransferred(encoded, signal) : await this.client.rpc("harness.api.call", params, signal);
|
|
@@ -14179,9 +14394,32 @@ function normalizeLegacyResponse(method, response) {
|
|
|
14179
14394
|
}
|
|
14180
14395
|
};
|
|
14181
14396
|
}
|
|
14397
|
+
function normalizeLegacyRequest(method, payload) {
|
|
14398
|
+
if (!isRecord2(payload)) return payload;
|
|
14399
|
+
if (method === "agentPreset.read") return replaceAgentPreset(payload, "agentPreset");
|
|
14400
|
+
if (method === "agentPreset.select") return replaceAgentPreset(payload, "agentPreset");
|
|
14401
|
+
if (method === "agentPreset.copy") return replaceAgentPreset(payload, "from");
|
|
14402
|
+
if (method === "settings.update" || method === "settings.replace" || method === "settings.mutate") {
|
|
14403
|
+
return replaceAgentPresetSettings(payload);
|
|
14404
|
+
}
|
|
14405
|
+
return payload;
|
|
14406
|
+
}
|
|
14407
|
+
function replaceAgentPreset(payload, key) {
|
|
14408
|
+
const value = payload[key];
|
|
14409
|
+
const replacement = typeof value === "string" ? LEGACY_AGENT_PRESET_ALIASES[value] : void 0;
|
|
14410
|
+
return replacement === void 0 ? payload : { ...payload, [key]: replacement };
|
|
14411
|
+
}
|
|
14412
|
+
function replaceAgentPresetSettings(payload) {
|
|
14413
|
+
if (payload.ns !== AGENT_PRESET_SETTINGS_NS || !isRecord2(payload.patch)) return payload;
|
|
14414
|
+
const patch = replaceAgentPreset(payload.patch, "default");
|
|
14415
|
+
return patch === payload.patch ? payload : { ...payload, patch };
|
|
14416
|
+
}
|
|
14182
14417
|
function isRemoteDisconnect(error) {
|
|
14183
14418
|
return error instanceof RemoteClientError && (error.code === "TRANSPORT_CLOSED" || error.code === "CLIENT_CLOSED");
|
|
14184
14419
|
}
|
|
14420
|
+
function isRecord2(value) {
|
|
14421
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
14422
|
+
}
|
|
14185
14423
|
var AsyncFrameQueue = class {
|
|
14186
14424
|
values = [];
|
|
14187
14425
|
waiters = [];
|
|
@@ -14244,11 +14482,168 @@ function base64ToBytes2(value) {
|
|
|
14244
14482
|
return bytes;
|
|
14245
14483
|
}
|
|
14246
14484
|
|
|
14485
|
+
// src/session-format-compat.ts
|
|
14486
|
+
function normalizeLegacySessionGatewayValue(endpoint, value) {
|
|
14487
|
+
if (endpoint === "session/page") return normalizePage(value);
|
|
14488
|
+
if (endpoint === "session/follow") return normalizeFollowFrame(value);
|
|
14489
|
+
return value;
|
|
14490
|
+
}
|
|
14491
|
+
function normalizeFollowFrame(value) {
|
|
14492
|
+
if (!isRecord3(value)) return value;
|
|
14493
|
+
if (value.type === "snapshot") {
|
|
14494
|
+
return {
|
|
14495
|
+
...value,
|
|
14496
|
+
header: normalizeHeader(value.header),
|
|
14497
|
+
records: normalizeRecords(value.records),
|
|
14498
|
+
...value.assistantStream === void 0 ? { assistantStream: { revision: 0 } } : {}
|
|
14499
|
+
};
|
|
14500
|
+
}
|
|
14501
|
+
return normalizeEntry(value);
|
|
14502
|
+
}
|
|
14503
|
+
function normalizePage(value) {
|
|
14504
|
+
if (!isRecord3(value)) return value;
|
|
14505
|
+
return { ...value, records: normalizeRecords(value.records) };
|
|
14506
|
+
}
|
|
14507
|
+
function normalizeRecords(value) {
|
|
14508
|
+
if (!Array.isArray(value)) return value;
|
|
14509
|
+
const records = [];
|
|
14510
|
+
let previousSeq;
|
|
14511
|
+
for (const record6 of value) {
|
|
14512
|
+
if (!isEventEntry(record6)) continue;
|
|
14513
|
+
const seq = entrySeq(record6);
|
|
14514
|
+
if (previousSeq !== void 0 && seq !== void 0 && seq > previousSeq + 1) {
|
|
14515
|
+
for (let fillerSeq = previousSeq + 1; fillerSeq < seq; fillerSeq += 1) {
|
|
14516
|
+
records.push(createLegacyGapRecord(fillerSeq, record6));
|
|
14517
|
+
}
|
|
14518
|
+
}
|
|
14519
|
+
records.push(normalizeEntry(record6));
|
|
14520
|
+
if (seq !== void 0) previousSeq = seq;
|
|
14521
|
+
}
|
|
14522
|
+
return records;
|
|
14523
|
+
}
|
|
14524
|
+
function normalizeEntry(value) {
|
|
14525
|
+
if (!isEventEntry(value)) return value;
|
|
14526
|
+
return { ...value, event: normalizeEvent(value.event) };
|
|
14527
|
+
}
|
|
14528
|
+
function entrySeq(value) {
|
|
14529
|
+
if (!isEventEntry(value)) return void 0;
|
|
14530
|
+
return isEventSeq(value.event.seq) ? value.event.seq : void 0;
|
|
14531
|
+
}
|
|
14532
|
+
function createLegacyGapRecord(seq, nextRecord) {
|
|
14533
|
+
return {
|
|
14534
|
+
type: "event",
|
|
14535
|
+
event: {
|
|
14536
|
+
type: "legacy/session-gap",
|
|
14537
|
+
seq,
|
|
14538
|
+
time: eventTime(nextRecord),
|
|
14539
|
+
ignorable: true,
|
|
14540
|
+
data: {}
|
|
14541
|
+
}
|
|
14542
|
+
};
|
|
14543
|
+
}
|
|
14544
|
+
function eventTime(value) {
|
|
14545
|
+
if (!isEventEntry(value)) return 0;
|
|
14546
|
+
return typeof value.event.time === "number" && Number.isSafeInteger(value.event.time) ? value.event.time : 0;
|
|
14547
|
+
}
|
|
14548
|
+
function isEventEntry(value) {
|
|
14549
|
+
return isRecord3(value) && value.type === "event" && isRecord3(value.event);
|
|
14550
|
+
}
|
|
14551
|
+
function normalizeHeader(value) {
|
|
14552
|
+
if (!isRecord3(value)) return value;
|
|
14553
|
+
const next = {
|
|
14554
|
+
...value,
|
|
14555
|
+
version: 3,
|
|
14556
|
+
...value.delegationDepth === void 0 ? { delegationDepth: 0 } : {}
|
|
14557
|
+
};
|
|
14558
|
+
return next.agentPreset === "code" ? { ...next, agentPreset: "ptc" } : next;
|
|
14559
|
+
}
|
|
14560
|
+
function normalizeEvent(value) {
|
|
14561
|
+
if (!isRecord3(value)) return value;
|
|
14562
|
+
let next = value;
|
|
14563
|
+
const type = normalizeEventType(value.type);
|
|
14564
|
+
if (type !== value.type) next = { ...next, type };
|
|
14565
|
+
if (type === "assistant/message" && Object.hasOwn(next, "sourceEventSeqs")) {
|
|
14566
|
+
const { sourceEventSeqs: _sourceEventSeqs, ...rest } = next;
|
|
14567
|
+
next = rest;
|
|
14568
|
+
}
|
|
14569
|
+
const data = normalizeEventData(type, next.data);
|
|
14570
|
+
if (data !== next.data) next = { ...next, data };
|
|
14571
|
+
const surfaceOp = normalizeSurfaceOp(next.surfaceOp);
|
|
14572
|
+
if (surfaceOp !== next.surfaceOp) next = { ...next, surfaceOp };
|
|
14573
|
+
return next;
|
|
14574
|
+
}
|
|
14575
|
+
function normalizeEventType(value) {
|
|
14576
|
+
if (value === "tool/code-dispatch-start") return "tool/ptc-dispatch-start";
|
|
14577
|
+
if (value === "tool/code-dispatch") return "tool/ptc-dispatch";
|
|
14578
|
+
return value;
|
|
14579
|
+
}
|
|
14580
|
+
function normalizeEventData(type, value) {
|
|
14581
|
+
if (!isRecord3(value)) return value;
|
|
14582
|
+
if (type === "request/header") return normalizeRequestHeaderData(value);
|
|
14583
|
+
if (type === "agent-preset/selected" && value.agentPreset === "code") return { ...value, agentPreset: "ptc" };
|
|
14584
|
+
if (type === "user/message") return normalizeMessage(value);
|
|
14585
|
+
if (type === "agent/inbox/spliced" && Array.isArray(value.inserted)) {
|
|
14586
|
+
return { ...value, inserted: value.inserted.map((item) => normalizeMessage(item)) };
|
|
14587
|
+
}
|
|
14588
|
+
if (type === "session/title-llm-request" && Array.isArray(value.messages)) {
|
|
14589
|
+
return { ...value, messages: value.messages.map((item) => normalizeMessage(item)) };
|
|
14590
|
+
}
|
|
14591
|
+
return value;
|
|
14592
|
+
}
|
|
14593
|
+
function normalizeRequestHeaderData(value) {
|
|
14594
|
+
if (!isRecord3(value.header)) return value;
|
|
14595
|
+
const header = normalizeRequestHeader(value.header);
|
|
14596
|
+
return header === value.header ? value : { ...value, header };
|
|
14597
|
+
}
|
|
14598
|
+
function normalizeRequestHeader(value) {
|
|
14599
|
+
let changed = false;
|
|
14600
|
+
const next = {};
|
|
14601
|
+
for (const [key, field] of Object.entries(value)) {
|
|
14602
|
+
if (key === "system") {
|
|
14603
|
+
changed = true;
|
|
14604
|
+
continue;
|
|
14605
|
+
}
|
|
14606
|
+
if (key === "tools" && Array.isArray(field) && field.length === 0) {
|
|
14607
|
+
changed = true;
|
|
14608
|
+
continue;
|
|
14609
|
+
}
|
|
14610
|
+
if (key === "adapterDefaults" && isRecord3(field) && Object.keys(field).length === 0) {
|
|
14611
|
+
changed = true;
|
|
14612
|
+
continue;
|
|
14613
|
+
}
|
|
14614
|
+
next[key] = field;
|
|
14615
|
+
}
|
|
14616
|
+
return changed ? next : value;
|
|
14617
|
+
}
|
|
14618
|
+
function normalizeMessage(value) {
|
|
14619
|
+
if (!isRecord3(value) || !isRecord3(value.source)) return value;
|
|
14620
|
+
if (value.source.kind !== "plugin" || value.source.plugin !== "tools-code-mode") return value;
|
|
14621
|
+
return { ...value, source: { ...value.source, plugin: "tools-ptc" } };
|
|
14622
|
+
}
|
|
14623
|
+
function normalizeSurfaceOp(value) {
|
|
14624
|
+
if (!isRecord3(value) || value.op !== "replace") return value;
|
|
14625
|
+
const { start, end, ...rest } = value;
|
|
14626
|
+
if (start === void 0 && end === void 0) return value;
|
|
14627
|
+
return {
|
|
14628
|
+
...rest,
|
|
14629
|
+
op: "replace",
|
|
14630
|
+
...start === void 0 ? {} : { startSeq: start },
|
|
14631
|
+
...end === void 0 ? {} : { endSeq: end }
|
|
14632
|
+
};
|
|
14633
|
+
}
|
|
14634
|
+
function isRecord3(value) {
|
|
14635
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
14636
|
+
}
|
|
14637
|
+
function isEventSeq(value) {
|
|
14638
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 && !Object.is(value, -0);
|
|
14639
|
+
}
|
|
14640
|
+
|
|
14247
14641
|
// src/remote-typert-gateway.ts
|
|
14248
14642
|
var DIRECT_REMOTE_CALL_BYTES2 = 2 * 1024 * 1024;
|
|
14249
14643
|
var RemoteTypertGateway2 = class {
|
|
14250
|
-
constructor(client) {
|
|
14644
|
+
constructor(client, compatibility) {
|
|
14251
14645
|
this.client = client;
|
|
14646
|
+
this.compatibility = compatibility;
|
|
14252
14647
|
}
|
|
14253
14648
|
async invoke(request) {
|
|
14254
14649
|
const result = await this.dispatch(
|
|
@@ -14273,7 +14668,11 @@ var RemoteTypertGateway2 = class {
|
|
|
14273
14668
|
response = await this.callTransferred(encoded, signal);
|
|
14274
14669
|
}
|
|
14275
14670
|
}
|
|
14276
|
-
|
|
14671
|
+
const result = parseRpcResult(response);
|
|
14672
|
+
if (result.ok && this.compatibility === "legacy-to-v3") {
|
|
14673
|
+
return { ...result, value: normalizeLegacySessionGatewayValue(endpoint, result.value) };
|
|
14674
|
+
}
|
|
14675
|
+
return result;
|
|
14277
14676
|
}
|
|
14278
14677
|
async open(endpoint, payload, signal) {
|
|
14279
14678
|
const streamId = uuidV7();
|
|
@@ -14292,11 +14691,13 @@ var RemoteTypertGateway2 = class {
|
|
|
14292
14691
|
unsubscribeClose();
|
|
14293
14692
|
throw error;
|
|
14294
14693
|
}
|
|
14295
|
-
return this.iterate(streamId, queue, unsubscribe, unsubscribeClose, signal, onAbort);
|
|
14694
|
+
return this.iterate(streamId, endpoint, queue, unsubscribe, unsubscribeClose, signal, onAbort);
|
|
14296
14695
|
}
|
|
14297
|
-
async *iterate(streamId, queue, unsubscribe, unsubscribeClose, signal, onAbort) {
|
|
14696
|
+
async *iterate(streamId, endpoint, queue, unsubscribe, unsubscribeClose, signal, onAbort) {
|
|
14298
14697
|
try {
|
|
14299
|
-
|
|
14698
|
+
for await (const value of queue) {
|
|
14699
|
+
yield this.compatibility === "legacy-to-v3" ? normalizeLegacySessionGatewayValue(endpoint, value) : value;
|
|
14700
|
+
}
|
|
14300
14701
|
} finally {
|
|
14301
14702
|
signal.removeEventListener("abort", onAbort);
|
|
14302
14703
|
unsubscribe();
|
|
@@ -14416,16 +14817,16 @@ function routeStreamEvent2(event, streamId, queue) {
|
|
|
14416
14817
|
queue.fail(remoteFailure({
|
|
14417
14818
|
code: typeof failure2?.code === "string" ? failure2.code : "internal",
|
|
14418
14819
|
message: typeof failure2?.message === "string" ? failure2.message : "The remote Harness stream failed.",
|
|
14419
|
-
details:
|
|
14820
|
+
details: isRecord4(failure2?.details) ? failure2.details : {}
|
|
14420
14821
|
}));
|
|
14421
14822
|
} else {
|
|
14422
14823
|
queue.close();
|
|
14423
14824
|
}
|
|
14424
14825
|
}
|
|
14425
14826
|
function parseRpcResult(value) {
|
|
14426
|
-
if (!
|
|
14827
|
+
if (!isRecord4(value)) throw new Error("The remote Host returned an invalid Gateway result.");
|
|
14427
14828
|
if (value.ok === true) return Object.hasOwn(value, "value") ? { ok: true, value: value.value } : { ok: true };
|
|
14428
|
-
if (value.ok !== false || !
|
|
14829
|
+
if (value.ok !== false || !isRecord4(value.error) || typeof value.error.code !== "string" || typeof value.error.message !== "string" || !isRecord4(value.error.details)) {
|
|
14429
14830
|
throw new Error("The remote Host returned an invalid Gateway failure.");
|
|
14430
14831
|
}
|
|
14431
14832
|
return {
|
|
@@ -14459,7 +14860,7 @@ function base64ToBytes3(value) {
|
|
|
14459
14860
|
if (bytesToBase643(bytes) !== value) throw new Error("The remote Host returned non-canonical Harness Remote transfer data.");
|
|
14460
14861
|
return bytes;
|
|
14461
14862
|
}
|
|
14462
|
-
function
|
|
14863
|
+
function isRecord4(value) {
|
|
14463
14864
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
14464
14865
|
}
|
|
14465
14866
|
function hasErrorCode(error, code) {
|
|
@@ -14510,9 +14911,10 @@ async function discoverCodexVirtualWorkspaces(client, signal) {
|
|
|
14510
14911
|
return (await loadCatalog(client, signal)).workspaces;
|
|
14511
14912
|
}
|
|
14512
14913
|
var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
14513
|
-
constructor(client, host) {
|
|
14914
|
+
constructor(client, host, sessionGeneration = "legacy") {
|
|
14514
14915
|
this.client = client;
|
|
14515
14916
|
this.host = host;
|
|
14917
|
+
this.sessionGeneration = sessionGeneration;
|
|
14516
14918
|
this.api = this.createApiProxy();
|
|
14517
14919
|
}
|
|
14518
14920
|
api;
|
|
@@ -14536,8 +14938,8 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14536
14938
|
commandSeq = 0;
|
|
14537
14939
|
selectedWorkspaceId;
|
|
14538
14940
|
closed = false;
|
|
14539
|
-
static remote(core, host) {
|
|
14540
|
-
return new _CodexVirtualHarness(new CodexRemoteClient(core), host);
|
|
14941
|
+
static remote(core, host, sessionGeneration = "legacy") {
|
|
14942
|
+
return new _CodexVirtualHarness(new CodexRemoteClient(core), host, sessionGeneration);
|
|
14541
14943
|
}
|
|
14542
14944
|
async workspaces(signal) {
|
|
14543
14945
|
return (await this.refreshCatalog(signal)).workspaces;
|
|
@@ -14927,6 +15329,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14927
15329
|
streamedBlocks: /* @__PURE__ */ new Map(),
|
|
14928
15330
|
nextBlockIndex: 0,
|
|
14929
15331
|
streamActive: false,
|
|
15332
|
+
assistantStreamRevision: 0,
|
|
14930
15333
|
liveItems: /* @__PURE__ */ new Map(),
|
|
14931
15334
|
liveToolOutput: /* @__PURE__ */ new Map(),
|
|
14932
15335
|
liveToolResultSeq: /* @__PURE__ */ new Map(),
|
|
@@ -14950,7 +15353,8 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14950
15353
|
permissions: codexPermissionsProjection(this.permissionSelection(sessionId)),
|
|
14951
15354
|
imageLimits: codexImageLimitsProjection()
|
|
14952
15355
|
}
|
|
14953
|
-
}
|
|
15356
|
+
},
|
|
15357
|
+
...this.sessionGeneration === "v3" ? { assistantStream: { revision: 0 } } : {}
|
|
14954
15358
|
});
|
|
14955
15359
|
try {
|
|
14956
15360
|
const stream = await this.client.subscribe(
|
|
@@ -14988,6 +15392,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14988
15392
|
}
|
|
14989
15393
|
if (frame.method === "turn/started") {
|
|
14990
15394
|
const turn = record2(params.turn);
|
|
15395
|
+
this.endAssistantAttempt(follow, { kind: "abandoned" });
|
|
14991
15396
|
this.resetLiveTurn(follow);
|
|
14992
15397
|
follow.turn += 1;
|
|
14993
15398
|
follow.activeTurnId = string(turn.id);
|
|
@@ -15103,6 +15508,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15103
15508
|
if (follow.stepOpen) {
|
|
15104
15509
|
this.closeAllStreamBlocks(follow);
|
|
15105
15510
|
if (follow.streamActive) this.finishStream(follow);
|
|
15511
|
+
this.endAssistantAttempt(follow, { kind: "abandoned" });
|
|
15106
15512
|
this.pushEvent(follow, "step/end", { turn: follow.turn, step: 1 });
|
|
15107
15513
|
follow.stepOpen = false;
|
|
15108
15514
|
}
|
|
@@ -15141,6 +15547,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15141
15547
|
this.closeItemStreamBlocks(follow, itemId, itemText2(item));
|
|
15142
15548
|
if (type === "agentMessage" && follow.streamActive && follow.streamedBlocks.size === 0) this.finishStream(follow);
|
|
15143
15549
|
const supplementalImages = type === "agentMessage" ? follow.pendingToolImages : [];
|
|
15550
|
+
let assistantMessageSeq;
|
|
15144
15551
|
for (const event of itemEvents(
|
|
15145
15552
|
item,
|
|
15146
15553
|
follow.turn,
|
|
@@ -15152,7 +15559,17 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15152
15559
|
)) {
|
|
15153
15560
|
if (event.type === "tool/call" && follow.startedItems.has(itemId)) continue;
|
|
15154
15561
|
if (event.type === "tool/result") this.pushToolResult(follow, itemId, event);
|
|
15155
|
-
else
|
|
15562
|
+
else {
|
|
15563
|
+
const seq = this.pushEvent(follow, event.type, event.data, event.view);
|
|
15564
|
+
if (event.type === "assistant/message") assistantMessageSeq = seq;
|
|
15565
|
+
}
|
|
15566
|
+
}
|
|
15567
|
+
if (type === "agentMessage" && assistantMessageSeq !== void 0) {
|
|
15568
|
+
this.endAssistantAttempt(follow, {
|
|
15569
|
+
kind: "committed",
|
|
15570
|
+
eventType: "assistant/message",
|
|
15571
|
+
seq: assistantMessageSeq
|
|
15572
|
+
});
|
|
15156
15573
|
}
|
|
15157
15574
|
if (type === "agentMessage" && supplementalImages.length > 0) follow.pendingToolImages = [];
|
|
15158
15575
|
else if (type !== void 0 && isToolItemType2(type)) {
|
|
@@ -15169,18 +15586,21 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15169
15586
|
type,
|
|
15170
15587
|
seq,
|
|
15171
15588
|
time: Date.now(),
|
|
15172
|
-
data
|
|
15589
|
+
data: adaptEventData(
|
|
15590
|
+
type,
|
|
15591
|
+
type === "assistant/message" && this.sessionGeneration === "v3" && follow.assistantAttempt !== void 0 ? { ...record2(data), stream: follow.assistantAttempt.stream } : data,
|
|
15592
|
+
this.sessionGeneration
|
|
15593
|
+
),
|
|
15173
15594
|
...isSurfaceEvent(type) ? placement === void 0 ? { surfaceOp: "append" } : {
|
|
15174
|
-
surfaceOp: { op: "replace", start: placement.replaceSeq, end: placement.replaceSeq },
|
|
15595
|
+
surfaceOp: this.sessionGeneration === "v3" ? { op: "replace", startSeq: placement.replaceSeq, endSeq: placement.replaceSeq } : { op: "replace", start: placement.replaceSeq, end: placement.replaceSeq },
|
|
15175
15596
|
sourceEventSeqs: [placement.replaceSeq]
|
|
15176
15597
|
} : {}
|
|
15177
15598
|
};
|
|
15178
15599
|
this.cacheImageBlocks(follow.sessionId, event.data);
|
|
15179
15600
|
if (!follow.rcOnly) {
|
|
15180
|
-
const alphaEvent = typeof event.surfaceOp === "object" ? { ...event, surfaceOp: "replace" } : event;
|
|
15181
15601
|
follow.queue.push({
|
|
15182
15602
|
type: "event",
|
|
15183
|
-
event
|
|
15603
|
+
event,
|
|
15184
15604
|
...view === void 0 ? {} : { view }
|
|
15185
15605
|
});
|
|
15186
15606
|
}
|
|
@@ -15207,52 +15627,105 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15207
15627
|
const block = { itemId, index: follow.nextBlockIndex++, kind, text: "" };
|
|
15208
15628
|
follow.streamedBlocks.set(key, block);
|
|
15209
15629
|
follow.streamActive = true;
|
|
15210
|
-
this.
|
|
15211
|
-
turn: follow.turn,
|
|
15212
|
-
step: 1,
|
|
15213
|
-
chunk: { type: "block-start", index: block.index, blockType: kind }
|
|
15214
|
-
});
|
|
15630
|
+
this.pushAssistantChunk(follow, { type: "block-start", index: block.index, blockType: kind });
|
|
15215
15631
|
return block;
|
|
15216
15632
|
}
|
|
15217
15633
|
appendStreamDelta(follow, key, itemId, kind, delta) {
|
|
15218
15634
|
const block = this.ensureStreamBlock(follow, key, itemId, kind);
|
|
15219
15635
|
block.text = appendBoundedText(block.text, delta);
|
|
15220
|
-
this.
|
|
15221
|
-
|
|
15222
|
-
|
|
15223
|
-
|
|
15636
|
+
this.pushAssistantChunk(follow, {
|
|
15637
|
+
type: kind === "reasoning" ? "reasoning-delta" : "text-delta",
|
|
15638
|
+
index: block.index,
|
|
15639
|
+
text: delta
|
|
15224
15640
|
});
|
|
15225
15641
|
}
|
|
15226
15642
|
closeItemStreamBlocks(follow, itemId, fallback) {
|
|
15227
15643
|
const matches = [...follow.streamedBlocks].filter(([, block]) => block.itemId === itemId);
|
|
15228
15644
|
for (const [key, block] of matches) {
|
|
15229
15645
|
const text = block.text || fallback || "";
|
|
15230
|
-
this.
|
|
15231
|
-
|
|
15232
|
-
|
|
15233
|
-
|
|
15646
|
+
this.pushAssistantChunk(follow, {
|
|
15647
|
+
type: "block-end",
|
|
15648
|
+
index: block.index,
|
|
15649
|
+
block: { type: block.kind, text }
|
|
15234
15650
|
});
|
|
15235
15651
|
follow.streamedBlocks.delete(key);
|
|
15236
15652
|
}
|
|
15237
15653
|
}
|
|
15238
15654
|
closeAllStreamBlocks(follow) {
|
|
15239
15655
|
for (const block of follow.streamedBlocks.values()) {
|
|
15240
|
-
this.
|
|
15241
|
-
|
|
15242
|
-
|
|
15243
|
-
|
|
15656
|
+
this.pushAssistantChunk(follow, {
|
|
15657
|
+
type: "block-end",
|
|
15658
|
+
index: block.index,
|
|
15659
|
+
block: { type: block.kind, text: block.text }
|
|
15244
15660
|
});
|
|
15245
15661
|
}
|
|
15246
15662
|
follow.streamedBlocks.clear();
|
|
15247
15663
|
}
|
|
15248
15664
|
finishStream(follow) {
|
|
15249
|
-
this.
|
|
15250
|
-
turn: follow.turn,
|
|
15251
|
-
step: 1,
|
|
15252
|
-
chunk: { type: "finish", reason: { kind: "stop" } }
|
|
15253
|
-
});
|
|
15665
|
+
this.pushAssistantChunk(follow, { type: "finish", reason: { kind: "stop" } });
|
|
15254
15666
|
follow.streamActive = false;
|
|
15255
15667
|
}
|
|
15668
|
+
pushAssistantChunk(follow, chunk) {
|
|
15669
|
+
if (this.sessionGeneration !== "v3" || follow.rcOnly === true) {
|
|
15670
|
+
this.pushEvent(follow, "assistant/chunk", { turn: follow.turn, step: 1, chunk });
|
|
15671
|
+
return;
|
|
15672
|
+
}
|
|
15673
|
+
let attempt = follow.assistantAttempt;
|
|
15674
|
+
if (attempt === void 0) {
|
|
15675
|
+
attempt = {
|
|
15676
|
+
attemptId: `codex-attempt:${follow.activeTurnId ?? follow.turn}:${follow.nextSeq}`,
|
|
15677
|
+
startedAfterSeq: follow.nextSeq - 1,
|
|
15678
|
+
nextIndex: 0,
|
|
15679
|
+
stream: []
|
|
15680
|
+
};
|
|
15681
|
+
follow.assistantAttempt = attempt;
|
|
15682
|
+
follow.assistantStreamRevision += 1;
|
|
15683
|
+
follow.queue.push({
|
|
15684
|
+
type: "assistant-stream",
|
|
15685
|
+
frame: {
|
|
15686
|
+
type: "start",
|
|
15687
|
+
attemptId: attempt.attemptId,
|
|
15688
|
+
revision: follow.assistantStreamRevision,
|
|
15689
|
+
startedAfterSeq: attempt.startedAfterSeq,
|
|
15690
|
+
turn: follow.turn,
|
|
15691
|
+
step: 1
|
|
15692
|
+
}
|
|
15693
|
+
});
|
|
15694
|
+
}
|
|
15695
|
+
const time = Date.now();
|
|
15696
|
+
const index = attempt.nextIndex++;
|
|
15697
|
+
attempt.stream.push({ time, chunk });
|
|
15698
|
+
follow.assistantStreamRevision += 1;
|
|
15699
|
+
follow.queue.push({
|
|
15700
|
+
type: "assistant-stream",
|
|
15701
|
+
frame: {
|
|
15702
|
+
type: "chunk",
|
|
15703
|
+
attemptId: attempt.attemptId,
|
|
15704
|
+
revision: follow.assistantStreamRevision,
|
|
15705
|
+
index,
|
|
15706
|
+
time,
|
|
15707
|
+
chunk
|
|
15708
|
+
}
|
|
15709
|
+
});
|
|
15710
|
+
}
|
|
15711
|
+
endAssistantAttempt(follow, outcome) {
|
|
15712
|
+
const attempt = follow.assistantAttempt;
|
|
15713
|
+
if (attempt === void 0) return;
|
|
15714
|
+
follow.assistantAttempt = void 0;
|
|
15715
|
+
follow.assistantStreamRevision += 1;
|
|
15716
|
+
if (this.sessionGeneration === "v3" && follow.rcOnly !== true) {
|
|
15717
|
+
follow.queue.push({
|
|
15718
|
+
type: "assistant-stream",
|
|
15719
|
+
frame: {
|
|
15720
|
+
type: "end",
|
|
15721
|
+
attemptId: attempt.attemptId,
|
|
15722
|
+
revision: follow.assistantStreamRevision,
|
|
15723
|
+
index: attempt.nextIndex,
|
|
15724
|
+
outcome
|
|
15725
|
+
}
|
|
15726
|
+
});
|
|
15727
|
+
}
|
|
15728
|
+
}
|
|
15256
15729
|
ensureToolStarted(follow, item) {
|
|
15257
15730
|
const itemId = string(item.id);
|
|
15258
15731
|
if (itemId === void 0) return;
|
|
@@ -15295,6 +15768,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15295
15768
|
follow.streamedBlocks.clear();
|
|
15296
15769
|
follow.nextBlockIndex = 0;
|
|
15297
15770
|
follow.streamActive = false;
|
|
15771
|
+
follow.assistantAttempt = void 0;
|
|
15298
15772
|
follow.liveItems.clear();
|
|
15299
15773
|
follow.liveToolOutput.clear();
|
|
15300
15774
|
follow.liveToolResultSeq.clear();
|
|
@@ -15307,7 +15781,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15307
15781
|
this.broadcastRcHost({ type: "host/session-status", sessionId, running: args[1] });
|
|
15308
15782
|
} else if (event === "api-session/removed" && sessionId !== void 0) {
|
|
15309
15783
|
this.broadcastRcHost({ type: "host/session-removed", sessionId });
|
|
15310
|
-
} else if (event === "api-session/added" &&
|
|
15784
|
+
} else if (event === "api-session/added" && isRecord5(args[0])) {
|
|
15311
15785
|
const summary = args[0];
|
|
15312
15786
|
this.broadcastRcHost({
|
|
15313
15787
|
type: "host/session-added",
|
|
@@ -15565,7 +16039,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15565
16039
|
const thread = record2(result.thread);
|
|
15566
16040
|
if (string(thread.id) !== threadId) throw new Error("CodeX returned an invalid Thread history.");
|
|
15567
16041
|
value = paginateCodexNativeHistory(
|
|
15568
|
-
projectCodexNativeHistory(thread, `codex:${threadId}
|
|
16042
|
+
projectCodexNativeHistory(thread, `codex:${threadId}`, this.sessionGeneration),
|
|
15569
16043
|
{
|
|
15570
16044
|
beforeSeq: page.beforeSeq,
|
|
15571
16045
|
throughSeq: page.throughSeq,
|
|
@@ -15573,6 +16047,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15573
16047
|
}
|
|
15574
16048
|
);
|
|
15575
16049
|
}
|
|
16050
|
+
value = adaptCodexHistoryPage(value, this.sessionGeneration);
|
|
15576
16051
|
if (!isCodexNativeHistoryPage(value, `codex:${threadId}`)) {
|
|
15577
16052
|
throw new Error("CodeX Remote returned an invalid paginated History.");
|
|
15578
16053
|
}
|
|
@@ -15640,6 +16115,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15640
16115
|
streamedBlocks: /* @__PURE__ */ new Map(),
|
|
15641
16116
|
nextBlockIndex: 0,
|
|
15642
16117
|
streamActive: false,
|
|
16118
|
+
assistantStreamRevision: 0,
|
|
15643
16119
|
liveItems: /* @__PURE__ */ new Map(),
|
|
15644
16120
|
liveToolOutput: /* @__PURE__ */ new Map(),
|
|
15645
16121
|
liveToolResultSeq: /* @__PURE__ */ new Map(),
|
|
@@ -15690,7 +16166,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15690
16166
|
}
|
|
15691
16167
|
createApiProxy() {
|
|
15692
16168
|
const call = (endpoint) => async (request, signal) => {
|
|
15693
|
-
const payload = endpoint === "session.prompt" &&
|
|
16169
|
+
const payload = endpoint === "session.prompt" && isRecord5(request.payload) ? { ...request.payload, requestId: String(request.rpcId) } : request.payload;
|
|
15694
16170
|
const result = await this.dispatch(rcEndpoint(endpoint), { args: { request: payload } }, signal ?? new AbortController().signal);
|
|
15695
16171
|
return {
|
|
15696
16172
|
rpcId: request.rpcId,
|
|
@@ -15774,8 +16250,8 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15774
16250
|
queue.close();
|
|
15775
16251
|
}
|
|
15776
16252
|
}
|
|
15777
|
-
broadcastRcMux(payload,
|
|
15778
|
-
for (const queue of this.rcMuxStreams) queue.push({ rpcId, payload });
|
|
16253
|
+
broadcastRcMux(payload, rpcId2 = `codex-mux:${Date.now()}:${Math.random()}`) {
|
|
16254
|
+
for (const queue of this.rcMuxStreams) queue.push({ rpcId: rpcId2, payload });
|
|
15779
16255
|
}
|
|
15780
16256
|
broadcastRcHost(payload) {
|
|
15781
16257
|
const frame = { rpcId: `codex-host:${Date.now()}:${Math.random()}`, payload };
|
|
@@ -15922,7 +16398,7 @@ async function loadModelDirectory(client, signal) {
|
|
|
15922
16398
|
models
|
|
15923
16399
|
};
|
|
15924
16400
|
}
|
|
15925
|
-
function projectCodexNativeHistory(thread, sessionId) {
|
|
16401
|
+
function projectCodexNativeHistory(thread, sessionId, sessionGeneration = "legacy") {
|
|
15926
16402
|
const entries = [];
|
|
15927
16403
|
let seq = 0;
|
|
15928
16404
|
let turnNumber = 0;
|
|
@@ -15935,7 +16411,7 @@ function projectCodexNativeHistory(thread, sessionId) {
|
|
|
15935
16411
|
type,
|
|
15936
16412
|
seq: eventSeq,
|
|
15937
16413
|
time,
|
|
15938
|
-
data,
|
|
16414
|
+
data: adaptEventData(type, data, sessionGeneration),
|
|
15939
16415
|
...sourceEventSeqs === void 0 ? {} : { sourceEventSeqs },
|
|
15940
16416
|
...isSurfaceEvent(type) ? { surfaceOp: "append" } : {}
|
|
15941
16417
|
},
|
|
@@ -15988,10 +16464,11 @@ function projectCodexNativeHistory(thread, sessionId) {
|
|
|
15988
16464
|
const projected = projectCodexThread(thread);
|
|
15989
16465
|
return {
|
|
15990
16466
|
header: {
|
|
15991
|
-
version: 1,
|
|
16467
|
+
version: sessionGeneration === "v3" ? 3 : 1,
|
|
15992
16468
|
id: sessionId,
|
|
15993
16469
|
createdAt: projected?.createdAt ?? Date.now(),
|
|
15994
|
-
...projected?.cwd === void 0 ? {} : { cwd: projected.cwd }
|
|
16470
|
+
...projected?.cwd === void 0 ? {} : { cwd: projected.cwd },
|
|
16471
|
+
...sessionGeneration === "v3" ? { isSeeded: false } : {}
|
|
15995
16472
|
},
|
|
15996
16473
|
entries,
|
|
15997
16474
|
lastSeq: seq - 1,
|
|
@@ -16024,6 +16501,40 @@ function paginateCodexNativeHistory(history, request) {
|
|
|
16024
16501
|
...history.activeTurnId === void 0 ? {} : { activeTurnId: history.activeTurnId }
|
|
16025
16502
|
};
|
|
16026
16503
|
}
|
|
16504
|
+
function adaptEventData(type, data, sessionGeneration) {
|
|
16505
|
+
if (sessionGeneration !== "v3" || type !== "assistant/message") return data;
|
|
16506
|
+
const value = record2(data);
|
|
16507
|
+
return Array.isArray(value.stream) ? value : { ...value, stream: [] };
|
|
16508
|
+
}
|
|
16509
|
+
function adaptCodexHistoryPage(value, sessionGeneration) {
|
|
16510
|
+
if (sessionGeneration !== "v3") return value;
|
|
16511
|
+
const page = record2(value);
|
|
16512
|
+
const sourceHeader = record2(page.header);
|
|
16513
|
+
const { seedLength: _seedLength, ...header } = sourceHeader;
|
|
16514
|
+
const records = Array.isArray(page.records) ? page.records.map((raw) => {
|
|
16515
|
+
const entry = record2(raw);
|
|
16516
|
+
const sourceEvent = record2(entry.event);
|
|
16517
|
+
const sourceSurfaceOp = record2(sourceEvent.surfaceOp);
|
|
16518
|
+
const surfaceOp = sourceEvent.surfaceOp === "append" ? "append" : sourceSurfaceOp.op === "replace" && integer(sourceSurfaceOp.startSeq) !== void 0 && integer(sourceSurfaceOp.endSeq) !== void 0 ? sourceSurfaceOp : sourceSurfaceOp.op === "replace" && integer(sourceSurfaceOp.start) !== void 0 && integer(sourceSurfaceOp.end) !== void 0 ? {
|
|
16519
|
+
op: "replace",
|
|
16520
|
+
startSeq: sourceSurfaceOp.start,
|
|
16521
|
+
endSeq: sourceSurfaceOp.end
|
|
16522
|
+
} : sourceEvent.surfaceOp;
|
|
16523
|
+
return {
|
|
16524
|
+
...entry,
|
|
16525
|
+
event: {
|
|
16526
|
+
...sourceEvent,
|
|
16527
|
+
data: adaptEventData(string(sourceEvent.type) ?? "", sourceEvent.data, sessionGeneration),
|
|
16528
|
+
...surfaceOp === void 0 ? {} : { surfaceOp }
|
|
16529
|
+
}
|
|
16530
|
+
};
|
|
16531
|
+
}) : page.records;
|
|
16532
|
+
return {
|
|
16533
|
+
...page,
|
|
16534
|
+
header: { ...header, version: 3, isSeeded: sourceHeader.isSeeded === true },
|
|
16535
|
+
records
|
|
16536
|
+
};
|
|
16537
|
+
}
|
|
16027
16538
|
function itemEvents(item, turn, step, requestId, selection = modelSelection(), sessionId = CODEX_SESSION_PREFIX, supplementalImages = []) {
|
|
16028
16539
|
const type = string(item.type);
|
|
16029
16540
|
const id2 = string(item.id) ?? `${turn}:${step}:${hashString(JSON.stringify(item))}`;
|
|
@@ -16180,7 +16691,7 @@ function collectImageBlocks(value, output = []) {
|
|
|
16180
16691
|
for (const item of value) collectImageBlocks(item, output);
|
|
16181
16692
|
return output;
|
|
16182
16693
|
}
|
|
16183
|
-
if (!
|
|
16694
|
+
if (!isRecord5(value)) return output;
|
|
16184
16695
|
if (value.type === "image") output.push(value);
|
|
16185
16696
|
for (const [key, child] of Object.entries(value)) {
|
|
16186
16697
|
if (key === "attachment") continue;
|
|
@@ -16510,7 +17021,7 @@ function codexPromptInput(content) {
|
|
|
16510
17021
|
if (content.length === 0 || content.length > MAX_CODEX_PROMPT_PARTS) return void 0;
|
|
16511
17022
|
const input2 = [];
|
|
16512
17023
|
for (const value of content) {
|
|
16513
|
-
if (!
|
|
17024
|
+
if (!isRecord5(value)) return void 0;
|
|
16514
17025
|
if (value.type === "text") {
|
|
16515
17026
|
if (typeof value.text !== "string" || value.text.length === 0 || value.text.length > MAX_CODEX_PROMPT_TEXT) return void 0;
|
|
16516
17027
|
input2.push({ type: "text", text: value.text });
|
|
@@ -16763,12 +17274,12 @@ function errorCode(error) {
|
|
|
16763
17274
|
return "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
16764
17275
|
}
|
|
16765
17276
|
function errorDetails(error) {
|
|
16766
|
-
return "details" in error &&
|
|
17277
|
+
return "details" in error && isRecord5(error.details) ? error.details : {};
|
|
16767
17278
|
}
|
|
16768
17279
|
function record2(value) {
|
|
16769
|
-
return
|
|
17280
|
+
return isRecord5(value) ? value : {};
|
|
16770
17281
|
}
|
|
16771
|
-
function
|
|
17282
|
+
function isRecord5(value) {
|
|
16772
17283
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16773
17284
|
}
|
|
16774
17285
|
function array(value) {
|
|
@@ -16982,7 +17493,7 @@ function normalizeServerUrl(value) {
|
|
|
16982
17493
|
}
|
|
16983
17494
|
|
|
16984
17495
|
// src/version.ts
|
|
16985
|
-
var PLUGIN_VERSION = "0.4.
|
|
17496
|
+
var PLUGIN_VERSION = "0.4.13";
|
|
16986
17497
|
|
|
16987
17498
|
// src/server-api.ts
|
|
16988
17499
|
var TERMINAL_CONTROL_CHARACTERS = /[\u0000-\u001f\u007f-\u009f]/u;
|
|
@@ -17501,7 +18012,7 @@ var TypertGatewaySwitch = class {
|
|
|
17501
18012
|
if (normalized !== void 0) return normalized;
|
|
17502
18013
|
const source = error instanceof Error ? error : new Error("The Harness Gateway rejected the request.");
|
|
17503
18014
|
const code = "code" in source && typeof source.code === "string" ? source.code : "internal";
|
|
17504
|
-
const details = "details" in source &&
|
|
18015
|
+
const details = "details" in source && isRecord6(source.details) ? source.details : {};
|
|
17505
18016
|
return { code, message: source.message, details };
|
|
17506
18017
|
}
|
|
17507
18018
|
};
|
|
@@ -17510,7 +18021,7 @@ function requestFromCarrier(endpoint, payload, signal) {
|
|
|
17510
18021
|
if (segments.length !== 2 || segments.some((segment) => segment.length === 0)) {
|
|
17511
18022
|
throw new Error("The Harness Gateway endpoint is invalid.");
|
|
17512
18023
|
}
|
|
17513
|
-
if (!
|
|
18024
|
+
if (!isRecord6(payload) || !isRecord6(payload.args)) {
|
|
17514
18025
|
throw new Error("The Harness Gateway payload is invalid.");
|
|
17515
18026
|
}
|
|
17516
18027
|
return { namespace: segments[0], method: segments[1], args: payload.args, signal };
|
|
@@ -17525,7 +18036,7 @@ function isLocalOnlyEndpoint(endpoint) {
|
|
|
17525
18036
|
function isRemoteCommandMethod(method) {
|
|
17526
18037
|
return REMOTE_COMMAND_METHODS.includes(method);
|
|
17527
18038
|
}
|
|
17528
|
-
function
|
|
18039
|
+
function isRecord6(value) {
|
|
17529
18040
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17530
18041
|
}
|
|
17531
18042
|
|
|
@@ -17536,7 +18047,7 @@ import { networkInterfaces } from "node:os";
|
|
|
17536
18047
|
// src/native-rtc-helper.ts
|
|
17537
18048
|
import { spawn, spawnSync } from "node:child_process";
|
|
17538
18049
|
import { existsSync, readdirSync, realpathSync, statSync } from "node:fs";
|
|
17539
|
-
import { delimiter, dirname, join } from "node:path";
|
|
18050
|
+
import { delimiter, dirname as dirname2, join as join2 } from "node:path";
|
|
17540
18051
|
import { fileURLToPath } from "node:url";
|
|
17541
18052
|
var cachedExternalFactory;
|
|
17542
18053
|
var cachedExternalFactoryResolved = false;
|
|
@@ -17587,21 +18098,21 @@ function nodeBinaryCandidates() {
|
|
|
17587
18098
|
add3(process.env.DSH_REMOTE_NODE);
|
|
17588
18099
|
add3(process.env.NODE);
|
|
17589
18100
|
add3(process.execPath);
|
|
17590
|
-
for (const part of (process.env.PATH ?? "").split(delimiter)) add3(
|
|
18101
|
+
for (const part of (process.env.PATH ?? "").split(delimiter)) add3(join2(part, process.platform === "win32" ? "node.exe" : "node"));
|
|
17591
18102
|
add3("/opt/homebrew/bin/node");
|
|
17592
18103
|
add3("/usr/local/bin/node");
|
|
17593
18104
|
add3("/usr/bin/node");
|
|
17594
|
-
add3(
|
|
17595
|
-
add3(
|
|
17596
|
-
add3(
|
|
18105
|
+
add3(join2(process.env.HOME ?? "", ".volta", "bin", process.platform === "win32" ? "node.exe" : "node"));
|
|
18106
|
+
add3(join2(process.env.HOME ?? "", ".asdf", "shims", process.platform === "win32" ? "node.exe" : "node"));
|
|
18107
|
+
add3(join2(process.env.HOME ?? "", ".local", "bin", process.platform === "win32" ? "node.exe" : "node"));
|
|
17597
18108
|
for (const nvmNode of nvmNodeCandidates()) add3(nvmNode);
|
|
17598
18109
|
return candidates;
|
|
17599
18110
|
}
|
|
17600
18111
|
function nvmNodeCandidates() {
|
|
17601
|
-
const root =
|
|
18112
|
+
const root = join2(process.env.HOME ?? "", ".nvm", "versions", "node");
|
|
17602
18113
|
if (root === "" || !existsSync(root)) return [];
|
|
17603
18114
|
try {
|
|
17604
|
-
return readdirSync(root).map((version) =>
|
|
18115
|
+
return readdirSync(root).map((version) => join2(root, version, "bin", process.platform === "win32" ? "node.exe" : "node")).sort((left, right) => right.localeCompare(left, "en", { numeric: true }));
|
|
17605
18116
|
} catch {
|
|
17606
18117
|
return [];
|
|
17607
18118
|
}
|
|
@@ -17623,7 +18134,7 @@ function isUsableExternalNode(candidate, requireFrom) {
|
|
|
17623
18134
|
"console.log(`node:${process.versions.node}`);"
|
|
17624
18135
|
].join("")
|
|
17625
18136
|
], {
|
|
17626
|
-
cwd:
|
|
18137
|
+
cwd: dirname2(requireFrom),
|
|
17627
18138
|
env,
|
|
17628
18139
|
encoding: "utf8",
|
|
17629
18140
|
timeout: 3e3
|
|
@@ -17645,7 +18156,7 @@ var ExternalNativePeerConnection = class {
|
|
|
17645
18156
|
this.nodeBinary = nodeBinary;
|
|
17646
18157
|
this.requireFrom = requireFrom;
|
|
17647
18158
|
this.child = spawn(this.nodeBinary, ["--input-type=module", "--eval", HELPER_SOURCE], {
|
|
17648
|
-
cwd:
|
|
18159
|
+
cwd: dirname2(this.requireFrom),
|
|
17649
18160
|
env: { ...process.env, DSH_REMOTE_RTC_HELPER_REQUIRE_FROM: this.requireFrom },
|
|
17650
18161
|
stdio: ["pipe", "pipe", "pipe"]
|
|
17651
18162
|
});
|
|
@@ -18629,10 +19140,8 @@ var ClientModeRuntime = class {
|
|
|
18629
19140
|
fingerprint: this.identity.fingerprint
|
|
18630
19141
|
});
|
|
18631
19142
|
}
|
|
18632
|
-
registerControl(connection) {
|
|
18633
|
-
return connection
|
|
18634
|
-
authority: "loopback"
|
|
18635
|
-
});
|
|
19143
|
+
registerControl(connection, webServer) {
|
|
19144
|
+
return registerControlRoute(connection, (endpoint, payload, signal) => this.handleControl(endpoint, payload, signal), webServer);
|
|
18636
19145
|
}
|
|
18637
19146
|
status() {
|
|
18638
19147
|
const targetStatus = this.gatewaySwitch.supportsCarrier() ? this.gatewaySwitch.status() : this.proxySwitch?.status() ?? this.gatewaySwitch.status();
|
|
@@ -18813,9 +19322,9 @@ var ClientModeRuntime = class {
|
|
|
18813
19322
|
async openRemoteWorkspace(targetDeviceId, path, signal) {
|
|
18814
19323
|
if (path.trim() === "") throw new ClientModeError("INVALID_MESSAGE", "A remote working directory is required.");
|
|
18815
19324
|
const remote = await this.ensureConnected(targetDeviceId, signal);
|
|
18816
|
-
this.
|
|
19325
|
+
const transport = this.selectHarnessRemoteTransport(remote);
|
|
18817
19326
|
let workspace;
|
|
18818
|
-
if (
|
|
19327
|
+
if (transport === "remoteGateway") {
|
|
18819
19328
|
workspace = await new RemoteTypertGateway2(remote.client).invoke({
|
|
18820
19329
|
namespace: "workspace",
|
|
18821
19330
|
method: "create",
|
|
@@ -18831,7 +19340,7 @@ var ClientModeRuntime = class {
|
|
|
18831
19340
|
workspace = unwrapNativeResult(response);
|
|
18832
19341
|
}
|
|
18833
19342
|
await this.closeCodexVirtual();
|
|
18834
|
-
this.selectRemoteTarget(remote);
|
|
19343
|
+
this.selectRemoteTarget(remote, transport);
|
|
18835
19344
|
const workspaceId = workspaceRecordId(workspace.workspace);
|
|
18836
19345
|
this.pendingWorkspaceSelection = { targetDeviceId: remote.target.deviceId, workspaceId };
|
|
18837
19346
|
this.logger.info("Remote workspace opened", { targetDeviceId: shortId(remote.target.deviceId) });
|
|
@@ -18851,11 +19360,11 @@ var ClientModeRuntime = class {
|
|
|
18851
19360
|
if (!remote.features.codex) {
|
|
18852
19361
|
throw new ClientModeError("FEATURE_NOT_SUPPORTED", "The selected Host does not provide CodeX workspaces.");
|
|
18853
19362
|
}
|
|
18854
|
-
this.
|
|
19363
|
+
this.assertLocalHarnessCarrierAvailable();
|
|
18855
19364
|
const virtual = CodexVirtualHarness.remote(remote.client, {
|
|
18856
19365
|
deviceId: remote.target.deviceId,
|
|
18857
19366
|
name: remote.target.name
|
|
18858
|
-
});
|
|
19367
|
+
}, harnessSessionGeneration(this.host?.localHarnessVersion?.()));
|
|
18859
19368
|
let workspace;
|
|
18860
19369
|
try {
|
|
18861
19370
|
workspace = await virtual.selectWorkspace(workspaceId, signal);
|
|
@@ -18884,7 +19393,7 @@ var ClientModeRuntime = class {
|
|
|
18884
19393
|
if (!remote.features.codex) {
|
|
18885
19394
|
throw new ClientModeError("FEATURE_NOT_SUPPORTED", "The selected Host does not provide CodeX workspaces.");
|
|
18886
19395
|
}
|
|
18887
|
-
this.
|
|
19396
|
+
this.assertLocalHarnessCarrierAvailable();
|
|
18888
19397
|
const result = record3(await new CodexRemoteClient(remote.client).request("project/create", {
|
|
18889
19398
|
name: remoteWorkspaceTitle(trimmedPath),
|
|
18890
19399
|
roots: [{ path: trimmedPath }],
|
|
@@ -18972,10 +19481,10 @@ var ClientModeRuntime = class {
|
|
|
18972
19481
|
}
|
|
18973
19482
|
}
|
|
18974
19483
|
stream.unsubscribe = remote.client.onEvent((event) => {
|
|
18975
|
-
if (event.event === "codex.app.frame" &&
|
|
19484
|
+
if (event.event === "codex.app.frame" && isRecord7(event.data) && event.data.streamId === value.streamId) {
|
|
18976
19485
|
this.appendCodexFrame(stream, event.data);
|
|
18977
19486
|
}
|
|
18978
|
-
if (event.event === "codex.app.stream.closed" &&
|
|
19487
|
+
if (event.event === "codex.app.stream.closed" && isRecord7(event.data) && event.data.streamId === value.streamId) {
|
|
18979
19488
|
stream.closed = typeof event.data.reason === "string" ? event.data.reason : "closed";
|
|
18980
19489
|
stream.wake();
|
|
18981
19490
|
}
|
|
@@ -19002,7 +19511,7 @@ var ClientModeRuntime = class {
|
|
|
19002
19511
|
stream.wake();
|
|
19003
19512
|
};
|
|
19004
19513
|
appendCodexFrame(stream, data) {
|
|
19005
|
-
if (!
|
|
19514
|
+
if (!isRecord7(data) || !isRecord7(data.frame) || typeof data.frame.method !== "string") return;
|
|
19006
19515
|
if (stream.frames.length >= 256) {
|
|
19007
19516
|
stream.closed = "overflow";
|
|
19008
19517
|
} else {
|
|
@@ -19059,18 +19568,25 @@ var ClientModeRuntime = class {
|
|
|
19059
19568
|
await stream.close();
|
|
19060
19569
|
}));
|
|
19061
19570
|
}
|
|
19062
|
-
selectRemoteTarget(remote) {
|
|
19571
|
+
selectRemoteTarget(remote, transport = this.selectHarnessRemoteTransport(remote)) {
|
|
19063
19572
|
const target = { deviceId: remote.target.deviceId, name: remote.target.name };
|
|
19064
|
-
if (
|
|
19065
|
-
this.gatewaySwitch.selectRemote(
|
|
19573
|
+
if (transport === "remoteGateway") {
|
|
19574
|
+
this.gatewaySwitch.selectRemote(this.remoteTypertGateway(remote), void 0, target);
|
|
19066
19575
|
return;
|
|
19067
19576
|
}
|
|
19068
|
-
this.proxySwitch
|
|
19577
|
+
this.proxySwitch?.selectRemote(new RemoteHarnessApiProxy(remote.client).api, target);
|
|
19069
19578
|
this.gatewaySwitch.selectRemote((request) => invokeRemoteCommand(remote.client, request), {
|
|
19070
19579
|
execute: true,
|
|
19071
19580
|
list: remote.features.commandList
|
|
19072
19581
|
}, target);
|
|
19073
19582
|
}
|
|
19583
|
+
remoteTypertGateway(remote) {
|
|
19584
|
+
const localSessionGeneration = harnessSessionGeneration(this.host?.localHarnessVersion?.());
|
|
19585
|
+
return new RemoteTypertGateway2(
|
|
19586
|
+
remote.client,
|
|
19587
|
+
localSessionGeneration === "v3" && remote.features.sessionFormat !== 3 ? "legacy-to-v3" : void 0
|
|
19588
|
+
);
|
|
19589
|
+
}
|
|
19074
19590
|
selectCodexTarget(virtual, remote) {
|
|
19075
19591
|
const target = { deviceId: remote.target.deviceId, name: remote.target.name };
|
|
19076
19592
|
if (this.gatewaySwitch.supportsCarrier()) {
|
|
@@ -19086,11 +19602,29 @@ var ClientModeRuntime = class {
|
|
|
19086
19602
|
await virtual?.close();
|
|
19087
19603
|
}
|
|
19088
19604
|
assertRemoteCompatible(remote) {
|
|
19605
|
+
this.selectHarnessRemoteTransport(remote);
|
|
19606
|
+
}
|
|
19607
|
+
selectHarnessRemoteTransport(remote) {
|
|
19089
19608
|
const localRemoteGateway = this.gatewaySwitch.supportsCarrier();
|
|
19090
|
-
|
|
19609
|
+
const localSessionGeneration = harnessSessionGeneration(this.host?.localHarnessVersion?.());
|
|
19610
|
+
if (localRemoteGateway && remote.features.remoteGateway) {
|
|
19611
|
+
if (localSessionGeneration === "v3" || remote.features.sessionFormat !== 3) return "remoteGateway";
|
|
19612
|
+
throw new ClientModeError(
|
|
19613
|
+
"HARNESS_VERSION_INCOMPATIBLE",
|
|
19614
|
+
"The selected Host uses Harness Session V3, but this Client uses the legacy Typert Remote session format."
|
|
19615
|
+
);
|
|
19616
|
+
}
|
|
19617
|
+
if (this.proxySwitch !== void 0 && remote.features.apiProxy) return "apiProxy";
|
|
19091
19618
|
throw new ClientModeError(
|
|
19092
19619
|
"HARNESS_VERSION_INCOMPATIBLE",
|
|
19093
|
-
localRemoteGateway ? "The selected Host does not provide
|
|
19620
|
+
localRemoteGateway ? "The selected Host does not provide a compatible Harness Typert Remote Gateway transport." : "The selected Host does not provide the legacy Harness ApiProxy transport."
|
|
19621
|
+
);
|
|
19622
|
+
}
|
|
19623
|
+
assertLocalHarnessCarrierAvailable() {
|
|
19624
|
+
if (this.gatewaySwitch.supportsCarrier() || this.proxySwitch !== void 0) return;
|
|
19625
|
+
throw new ClientModeError(
|
|
19626
|
+
"HARNESS_VERSION_INCOMPATIBLE",
|
|
19627
|
+
"This Client does not provide a compatible Harness carrier for the selected remote workspace."
|
|
19094
19628
|
);
|
|
19095
19629
|
}
|
|
19096
19630
|
async connect(targetDeviceId, signal) {
|
|
@@ -19216,7 +19750,8 @@ var ClientModeRuntime = class {
|
|
|
19216
19750
|
transport: connectedTransport,
|
|
19217
19751
|
features,
|
|
19218
19752
|
progressRunId,
|
|
19219
|
-
...serverDevice.clientVersion === void 0 ? {} : { clientVersion: serverDevice.clientVersion }
|
|
19753
|
+
...serverDevice.clientVersion === void 0 ? {} : { clientVersion: serverDevice.clientVersion },
|
|
19754
|
+
...serverDevice.harnessVersion === void 0 ? {} : { harnessVersion: serverDevice.harnessVersion }
|
|
19220
19755
|
};
|
|
19221
19756
|
} catch (error) {
|
|
19222
19757
|
this.clearConnectionProgress(progressRunId);
|
|
@@ -19468,20 +20003,20 @@ function record3(value) {
|
|
|
19468
20003
|
}
|
|
19469
20004
|
return value;
|
|
19470
20005
|
}
|
|
19471
|
-
function
|
|
20006
|
+
function isRecord7(value) {
|
|
19472
20007
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19473
20008
|
}
|
|
19474
20009
|
function ok2(value) {
|
|
19475
20010
|
return { ok: true, value };
|
|
19476
20011
|
}
|
|
19477
20012
|
async function invokeRemoteCommand(client, request) {
|
|
19478
|
-
const
|
|
20013
|
+
const rpcId2 = uuidV7();
|
|
19479
20014
|
const response = await client.rpc("harness.api.call", {
|
|
19480
20015
|
method: `${request.namespace}.${request.method}`,
|
|
19481
|
-
rpcId,
|
|
20016
|
+
rpcId: rpcId2,
|
|
19482
20017
|
payload: request.args
|
|
19483
20018
|
}, request.signal);
|
|
19484
|
-
if (response.rpcId !==
|
|
20019
|
+
if (response.rpcId !== rpcId2) {
|
|
19485
20020
|
throw new ClientModeError("INVALID_MESSAGE", "The remote Host returned an invalid command response.");
|
|
19486
20021
|
}
|
|
19487
20022
|
return unwrapNativeResult(response);
|
|
@@ -19493,11 +20028,11 @@ async function readRemoteWorkspaceBaseline(gateway, signal) {
|
|
|
19493
20028
|
const iterator = source[Symbol.asyncIterator]();
|
|
19494
20029
|
try {
|
|
19495
20030
|
const first = await iterator.next();
|
|
19496
|
-
if (first.done || !
|
|
20031
|
+
if (first.done || !isRecord7(first.value) || first.value.type !== "baseline" || !isRecord7(first.value.value) || !Array.isArray(first.value.value.items)) {
|
|
19497
20032
|
throw new ClientModeError("INVALID_MESSAGE", "The remote Host returned an invalid Workspace baseline.");
|
|
19498
20033
|
}
|
|
19499
20034
|
return first.value.value.items.map((item) => {
|
|
19500
|
-
if (!
|
|
20035
|
+
if (!isRecord7(item) || typeof item.workspaceId !== "string" || typeof item.path !== "string" || typeof item.title !== "string") {
|
|
19501
20036
|
throw new ClientModeError("INVALID_MESSAGE", "The remote Host returned an invalid Workspace row.");
|
|
19502
20037
|
}
|
|
19503
20038
|
return { workspaceId: item.workspaceId, path: item.path, title: item.title };
|
|
@@ -19562,13 +20097,20 @@ async function probeRemoteHostFeatures(client, clientVersion) {
|
|
|
19562
20097
|
if (error instanceof Error && "code" in error && error.code === "METHOD_NOT_FOUND") return fallback;
|
|
19563
20098
|
throw error;
|
|
19564
20099
|
}
|
|
19565
|
-
if (!
|
|
20100
|
+
if (!isRecord7(value) || !Array.isArray(value.capabilities) || value.capabilities.some((capability) => typeof capability !== "string")) {
|
|
19566
20101
|
throw new ClientModeError("INVALID_MESSAGE", "The remote Host returned invalid transport capabilities.");
|
|
19567
20102
|
}
|
|
19568
20103
|
const capabilities = new Set(value.capabilities);
|
|
19569
20104
|
const apiProxy = capabilities.has("harness.api.v1");
|
|
19570
|
-
const
|
|
19571
|
-
|
|
20105
|
+
const remoteV1 = capabilities.has("harness.remote.v1");
|
|
20106
|
+
const remoteV3 = capabilities.has("harness.remote.v3");
|
|
20107
|
+
const codex = capabilities.has("codex.appserver.v1");
|
|
20108
|
+
if (remoteV1 && remoteV3) {
|
|
20109
|
+
throw new ClientModeError("INVALID_MESSAGE", "The remote Host advertised conflicting Harness Session formats.");
|
|
20110
|
+
}
|
|
20111
|
+
const sessionFormat = remoteV3 ? 3 : void 0;
|
|
20112
|
+
const remoteGateway = remoteV3 || remoteV1;
|
|
20113
|
+
if (!apiProxy && !remoteGateway && !codex) {
|
|
19572
20114
|
throw new ClientModeError("FEATURE_NOT_SUPPORTED", "The remote Host exposes no supported Harness transport.");
|
|
19573
20115
|
}
|
|
19574
20116
|
return {
|
|
@@ -19576,7 +20118,8 @@ async function probeRemoteHostFeatures(client, clientVersion) {
|
|
|
19576
20118
|
fileViewer: capabilities.has("fileviewer.read.v1"),
|
|
19577
20119
|
apiProxy,
|
|
19578
20120
|
remoteGateway,
|
|
19579
|
-
|
|
20121
|
+
...sessionFormat === void 0 ? {} : { sessionFormat },
|
|
20122
|
+
codex
|
|
19580
20123
|
};
|
|
19581
20124
|
}
|
|
19582
20125
|
async function waitForCodexFrames(stream, signal) {
|
|
@@ -19642,9 +20185,9 @@ import { hostname as hostname2 } from "node:os";
|
|
|
19642
20185
|
|
|
19643
20186
|
// src/identity-store.ts
|
|
19644
20187
|
import { createHash } from "node:crypto";
|
|
19645
|
-
import { chmod, mkdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
20188
|
+
import { chmod, mkdir, readFile as readFile2, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
19646
20189
|
import { homedir } from "node:os";
|
|
19647
|
-
import { dirname as
|
|
20190
|
+
import { dirname as dirname3, join as join3 } from "node:path";
|
|
19648
20191
|
var identitySchema = external_exports.object({
|
|
19649
20192
|
schemaVersion: external_exports.literal(1),
|
|
19650
20193
|
deviceId: external_exports.string().uuid(),
|
|
@@ -19673,14 +20216,14 @@ var IdentityStore = class {
|
|
|
19673
20216
|
peers = /* @__PURE__ */ new Map();
|
|
19674
20217
|
constructor(options = {}) {
|
|
19675
20218
|
const env = options.env ?? process.env;
|
|
19676
|
-
const dshHome = env.DSH_HOME ||
|
|
19677
|
-
this.directory = options.directory ??
|
|
20219
|
+
const dshHome = env.DSH_HOME || join3(options.homeDirectory ?? homedir(), ".dsh");
|
|
20220
|
+
this.directory = options.directory ?? join3(dshHome, "remote");
|
|
19678
20221
|
}
|
|
19679
20222
|
async loadOrCreate(deviceName) {
|
|
19680
20223
|
await mkdir(this.directory, { recursive: true, mode: 448 });
|
|
19681
20224
|
await chmod(this.directory, 448);
|
|
19682
|
-
const devicePath =
|
|
19683
|
-
const keyPath =
|
|
20225
|
+
const devicePath = join3(this.directory, "device.json");
|
|
20226
|
+
const keyPath = join3(this.directory, "device.key");
|
|
19684
20227
|
const [hasDevice, hasKey] = await Promise.all([exists(devicePath), exists(keyPath)]);
|
|
19685
20228
|
if (hasDevice !== hasKey) {
|
|
19686
20229
|
throw new IdentityInvalidError("device identity is incomplete; repair it explicitly before reconnecting");
|
|
@@ -19694,8 +20237,8 @@ var IdentityStore = class {
|
|
|
19694
20237
|
}
|
|
19695
20238
|
await assertPrivateMode(keyPath);
|
|
19696
20239
|
try {
|
|
19697
|
-
let record6 = identitySchema.parse(JSON.parse(await
|
|
19698
|
-
const privateKey = (await
|
|
20240
|
+
let record6 = identitySchema.parse(JSON.parse(await readFile2(devicePath, "utf8")));
|
|
20241
|
+
const privateKey = (await readFile2(keyPath, "utf8")).trim();
|
|
19699
20242
|
const regenerated = generateKeyPair(fromBase64Url2(privateKey));
|
|
19700
20243
|
if (regenerated.publicKey !== record6.publicKey) {
|
|
19701
20244
|
throw new IdentityInvalidError("device public and private keys do not match");
|
|
@@ -19749,11 +20292,11 @@ var IdentityStore = class {
|
|
|
19749
20292
|
return removed;
|
|
19750
20293
|
}
|
|
19751
20294
|
async loadPeers() {
|
|
19752
|
-
const path =
|
|
20295
|
+
const path = join3(this.directory, "trusted-peers.json");
|
|
19753
20296
|
if (!await exists(path)) {
|
|
19754
20297
|
await atomicJsonWrite(path, { schemaVersion: 1, peers: [] }, 384);
|
|
19755
20298
|
}
|
|
19756
|
-
const parsed = trustedPeersSchema.parse(JSON.parse(await
|
|
20299
|
+
const parsed = trustedPeersSchema.parse(JSON.parse(await readFile2(path, "utf8")));
|
|
19757
20300
|
const peers = /* @__PURE__ */ new Map();
|
|
19758
20301
|
for (const peer of parsed.peers) {
|
|
19759
20302
|
if (peer.fingerprint !== fingerprint(peer.publicKey)) {
|
|
@@ -19765,7 +20308,7 @@ var IdentityStore = class {
|
|
|
19765
20308
|
this.peers = peers;
|
|
19766
20309
|
}
|
|
19767
20310
|
async savePeers() {
|
|
19768
|
-
await atomicJsonWrite(
|
|
20311
|
+
await atomicJsonWrite(join3(this.directory, "trusted-peers.json"), {
|
|
19769
20312
|
schemaVersion: 1,
|
|
19770
20313
|
peers: [...this.peers.values()]
|
|
19771
20314
|
}, 384);
|
|
@@ -19774,7 +20317,7 @@ var IdentityStore = class {
|
|
|
19774
20317
|
function serverStorageDirectory(root, serverUrl, role) {
|
|
19775
20318
|
const origin = new URL(serverUrl).origin;
|
|
19776
20319
|
const scope = createHash("sha256").update(origin).digest("hex").slice(0, 24);
|
|
19777
|
-
return
|
|
20320
|
+
return join3(root, "servers", scope, role);
|
|
19778
20321
|
}
|
|
19779
20322
|
function fingerprint(publicKey) {
|
|
19780
20323
|
const compact = createHash("sha256").update(fromBase64Url2(publicKey)).digest("hex").slice(0, 12).toUpperCase();
|
|
@@ -19792,7 +20335,7 @@ async function atomicJsonWrite(path, value, mode) {
|
|
|
19792
20335
|
`, mode);
|
|
19793
20336
|
}
|
|
19794
20337
|
async function atomicTextWrite(path, value, mode) {
|
|
19795
|
-
await mkdir(
|
|
20338
|
+
await mkdir(dirname3(path), { recursive: true, mode: 448 });
|
|
19796
20339
|
const temporary = `${path}.${process.pid}.${uuidV7()}.tmp`;
|
|
19797
20340
|
await writeFile(temporary, value, { encoding: "utf8", mode, flag: "wx" });
|
|
19798
20341
|
await chmod(temporary, mode);
|
|
@@ -19816,8 +20359,8 @@ function safeErrorMessage(error) {
|
|
|
19816
20359
|
}
|
|
19817
20360
|
|
|
19818
20361
|
// src/server-credentials.ts
|
|
19819
|
-
import { chmod as chmod2, mkdir as mkdir2, readFile as
|
|
19820
|
-
import { dirname as
|
|
20362
|
+
import { chmod as chmod2, mkdir as mkdir2, readFile as readFile3, rename as rename2, rm as rm2, stat as stat2, writeFile as writeFile2 } from "node:fs/promises";
|
|
20363
|
+
import { dirname as dirname4, join as join4 } from "node:path";
|
|
19821
20364
|
var credentialSchema = external_exports.object({
|
|
19822
20365
|
schemaVersion: external_exports.literal(1),
|
|
19823
20366
|
serverUrl: external_exports.string().url(),
|
|
@@ -19832,14 +20375,14 @@ var credentialSchema = external_exports.object({
|
|
|
19832
20375
|
var ServerCredentialStore = class {
|
|
19833
20376
|
path;
|
|
19834
20377
|
constructor(directory) {
|
|
19835
|
-
this.path =
|
|
20378
|
+
this.path = join4(directory, "server-credentials.json");
|
|
19836
20379
|
}
|
|
19837
20380
|
async load(serverUrl, deviceId) {
|
|
19838
20381
|
if (!await exists2(this.path)) return void 0;
|
|
19839
20382
|
await assertPrivateMode2(this.path);
|
|
19840
20383
|
let parsed;
|
|
19841
20384
|
try {
|
|
19842
|
-
parsed = credentialSchema.parse(JSON.parse(await
|
|
20385
|
+
parsed = credentialSchema.parse(JSON.parse(await readFile3(this.path, "utf8")));
|
|
19843
20386
|
} catch (error) {
|
|
19844
20387
|
throw new ServerCredentialsInvalidError(`server credentials are invalid: ${safeMessage(error)}`);
|
|
19845
20388
|
}
|
|
@@ -19859,7 +20402,7 @@ var ServerCredentialsInvalidError = class extends Error {
|
|
|
19859
20402
|
code = "SERVER_CREDENTIALS_INVALID";
|
|
19860
20403
|
};
|
|
19861
20404
|
async function atomicWrite(path, contents) {
|
|
19862
|
-
await mkdir2(
|
|
20405
|
+
await mkdir2(dirname4(path), { recursive: true, mode: 448 });
|
|
19863
20406
|
const temporary = `${path}.${process.pid}.${uuidV7()}.tmp`;
|
|
19864
20407
|
await writeFile2(temporary, contents, { encoding: "utf8", mode: 384, flag: "wx" });
|
|
19865
20408
|
await chmod2(temporary, 384);
|
|
@@ -19893,10 +20436,8 @@ var PluginControlRuntime = class {
|
|
|
19893
20436
|
this.client = client;
|
|
19894
20437
|
this.host = host;
|
|
19895
20438
|
}
|
|
19896
|
-
register(connection) {
|
|
19897
|
-
return connection
|
|
19898
|
-
authority: "loopback"
|
|
19899
|
-
});
|
|
20439
|
+
register(connection, webServer) {
|
|
20440
|
+
return registerControlRoute(connection, (endpoint, payload, signal) => this.handle(endpoint, payload, signal), webServer);
|
|
19900
20441
|
}
|
|
19901
20442
|
async handle(endpoint, payload, signal) {
|
|
19902
20443
|
try {
|
|
@@ -20110,11 +20651,11 @@ function editableConfig(config) {
|
|
|
20110
20651
|
}
|
|
20111
20652
|
};
|
|
20112
20653
|
}
|
|
20113
|
-
function
|
|
20654
|
+
function isRecord8(value) {
|
|
20114
20655
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20115
20656
|
}
|
|
20116
20657
|
function record4(value) {
|
|
20117
|
-
if (!
|
|
20658
|
+
if (!isRecord8(value)) throw new ClientModeError("INVALID_MESSAGE", "The control request payload is invalid.");
|
|
20118
20659
|
return value;
|
|
20119
20660
|
}
|
|
20120
20661
|
function ok3(value) {
|
|
@@ -20337,36 +20878,6 @@ function shortId2(value) {
|
|
|
20337
20878
|
return value.length <= 12 ? value : `${value.slice(0, 8)}\u2026${value.slice(-4)}`;
|
|
20338
20879
|
}
|
|
20339
20880
|
|
|
20340
|
-
// src/harness-version.ts
|
|
20341
|
-
import { readFile as readFile3 } from "node:fs/promises";
|
|
20342
|
-
import { dirname as dirname4, isAbsolute, join as join4 } from "node:path";
|
|
20343
|
-
var LEGACY_PLACEHOLDER_VERSION = "0.0.1";
|
|
20344
|
-
function normalizeHarnessVersion(value) {
|
|
20345
|
-
if (typeof value !== "string") return void 0;
|
|
20346
|
-
const version = value.trim();
|
|
20347
|
-
if (version.length === 0 || version.length > 64 || /[\u0000-\u001f]/u.test(version)) return void 0;
|
|
20348
|
-
return version;
|
|
20349
|
-
}
|
|
20350
|
-
function selectHarnessVersion(reportedVersion, distributionVersion) {
|
|
20351
|
-
if (reportedVersion !== void 0 && reportedVersion !== LEGACY_PLACEHOLDER_VERSION) return reportedVersion;
|
|
20352
|
-
return distributionVersion;
|
|
20353
|
-
}
|
|
20354
|
-
async function readHarnessDistributionVersion(entrypoint = process.argv[1]) {
|
|
20355
|
-
if (entrypoint === void 0 || !isAbsolute(entrypoint)) return void 0;
|
|
20356
|
-
let directory = dirname4(entrypoint);
|
|
20357
|
-
for (let depth = 0; depth < 8; depth += 1) {
|
|
20358
|
-
try {
|
|
20359
|
-
const manifest = JSON.parse(await readFile3(join4(directory, "package.json"), "utf8"));
|
|
20360
|
-
if (manifest.name === "@deepseek-ai/dsh") return normalizeHarnessVersion(manifest.version);
|
|
20361
|
-
} catch {
|
|
20362
|
-
}
|
|
20363
|
-
const parent = dirname4(directory);
|
|
20364
|
-
if (parent === directory) break;
|
|
20365
|
-
directory = parent;
|
|
20366
|
-
}
|
|
20367
|
-
return void 0;
|
|
20368
|
-
}
|
|
20369
|
-
|
|
20370
20881
|
// src/safe-error.ts
|
|
20371
20882
|
var RpcError = class extends Error {
|
|
20372
20883
|
constructor(code, message, details, retryable = false) {
|
|
@@ -20465,7 +20976,7 @@ var RpcRouter = class {
|
|
|
20465
20976
|
});
|
|
20466
20977
|
return createRpcResponse(request.id, result);
|
|
20467
20978
|
} catch (error) {
|
|
20468
|
-
const response =
|
|
20979
|
+
const response = errorResponse2(request.id, error);
|
|
20469
20980
|
this.logger?.warn("host rpc failed", {
|
|
20470
20981
|
method: request.payload.method,
|
|
20471
20982
|
durationMs: Math.round(performance.now() - startedAt),
|
|
@@ -20564,7 +21075,7 @@ var RpcRouter = class {
|
|
|
20564
21075
|
return this.codex;
|
|
20565
21076
|
}
|
|
20566
21077
|
};
|
|
20567
|
-
function
|
|
21078
|
+
function errorResponse2(requestId, error) {
|
|
20568
21079
|
const code = safeErrorCode(error);
|
|
20569
21080
|
if (error instanceof RpcError) return createRpcError(requestId, code, error.message, error.details, error.retryable);
|
|
20570
21081
|
return createRpcError(
|
|
@@ -21757,8 +22268,8 @@ var HARNESS_API_ALLOWLIST = [
|
|
|
21757
22268
|
"credentials.unset"
|
|
21758
22269
|
];
|
|
21759
22270
|
var NATIVE_CALL_TIMEOUT_MS = 3e4;
|
|
21760
|
-
var MAX_ACTIVE_API_TRANSFERS =
|
|
21761
|
-
var API_TRANSFER_IDLE_MS =
|
|
22271
|
+
var MAX_ACTIVE_API_TRANSFERS = MAX_ACTIVE_TRANSFERS_PER_DIRECTION;
|
|
22272
|
+
var API_TRANSFER_IDLE_MS = TRANSFER_IDLE_MS;
|
|
21762
22273
|
var INLINE_TRANSFER_RESPONSE_BYTES = 2 * 1024 * 1024;
|
|
21763
22274
|
var SESSION_HISTORY_PAGE_SIZES = [50, 30, 20, 12, 6, 3, 1];
|
|
21764
22275
|
var HarnessApiBridge = class {
|
|
@@ -21835,9 +22346,9 @@ var HarnessApiBridge = class {
|
|
|
21835
22346
|
const value = await listRemoteDirectory(payload.path, signal);
|
|
21836
22347
|
return { rpcId: params.rpcId, result: { ok: true, value } };
|
|
21837
22348
|
}
|
|
21838
|
-
describeFallback(
|
|
22349
|
+
describeFallback(rpcId2) {
|
|
21839
22350
|
return {
|
|
21840
|
-
rpcId,
|
|
22351
|
+
rpcId: rpcId2,
|
|
21841
22352
|
result: {
|
|
21842
22353
|
ok: true,
|
|
21843
22354
|
value: {
|
|
@@ -22055,8 +22566,8 @@ var HarnessApiBridge = class {
|
|
|
22055
22566
|
}
|
|
22056
22567
|
}
|
|
22057
22568
|
deleteRespondable(value) {
|
|
22058
|
-
for (const [
|
|
22059
|
-
if (correlation === value) this.respondable.delete(
|
|
22569
|
+
for (const [rpcId2, correlation] of this.respondable) {
|
|
22570
|
+
if (correlation === value) this.respondable.delete(rpcId2);
|
|
22060
22571
|
}
|
|
22061
22572
|
}
|
|
22062
22573
|
};
|
|
@@ -22243,9 +22754,9 @@ function sanitizeModelDiscoveryResponse(response, settingsNs) {
|
|
|
22243
22754
|
if (typeof result === "object" && result !== null && "ok" in result && result.ok === true) return response;
|
|
22244
22755
|
return modelDiscoveryFailure(response.rpcId, settingsNs);
|
|
22245
22756
|
}
|
|
22246
|
-
function modelDiscoveryFailure(
|
|
22757
|
+
function modelDiscoveryFailure(rpcId2, settingsNs) {
|
|
22247
22758
|
return {
|
|
22248
|
-
rpcId,
|
|
22759
|
+
rpcId: rpcId2,
|
|
22249
22760
|
result: {
|
|
22250
22761
|
ok: false,
|
|
22251
22762
|
error: {
|
|
@@ -22305,15 +22816,15 @@ function frameSessionId(frame) {
|
|
|
22305
22816
|
const payload = frame.payload;
|
|
22306
22817
|
return typeof payload.sessionId === "string" && payload.sessionId.length > 0 ? payload.sessionId : void 0;
|
|
22307
22818
|
}
|
|
22308
|
-
function callSessionHistory(callWithTimeout, payload,
|
|
22819
|
+
function callSessionHistory(callWithTimeout, payload, rpcId2) {
|
|
22309
22820
|
const fallbackPageSizes = sessionHistoryFallbackPageSizes(payloadMaxMessages(payload));
|
|
22310
|
-
return callHistoryWithRetry(callWithTimeout, payload,
|
|
22821
|
+
return callHistoryWithRetry(callWithTimeout, payload, rpcId2, fallbackPageSizes);
|
|
22311
22822
|
}
|
|
22312
|
-
async function callHistoryWithRetry(callWithTimeout, payload,
|
|
22823
|
+
async function callHistoryWithRetry(callWithTimeout, payload, rpcId2, pageSizes) {
|
|
22313
22824
|
for (const maxMessages of pageSizes) {
|
|
22314
22825
|
const requestPayload = historyRequestPayload(payload, maxMessages);
|
|
22315
22826
|
const response = await callWithTimeout(requestPayload);
|
|
22316
|
-
const request = createRpcResponse(
|
|
22827
|
+
const request = createRpcResponse(rpcId2, response.result);
|
|
22317
22828
|
if (encodeMessage(request).byteLength <= MAX_SECURE_MESSAGE_BYTES) return response;
|
|
22318
22829
|
if (maxMessages === pageSizes[pageSizes.length - 1]) {
|
|
22319
22830
|
throw new RpcError(
|
|
@@ -22419,9 +22930,8 @@ var transferReadSchema2 = external_exports.object({
|
|
|
22419
22930
|
var directoryListSchema2 = external_exports.object({
|
|
22420
22931
|
path: external_exports.string().min(1).max(4096).optional()
|
|
22421
22932
|
}).strict();
|
|
22422
|
-
var MAX_ACTIVE_STREAMS =
|
|
22423
|
-
var MAX_ACTIVE_TRANSFERS =
|
|
22424
|
-
var TRANSFER_IDLE_MS = 2 * 6e4;
|
|
22933
|
+
var MAX_ACTIVE_STREAMS = MAX_ALPHA_STREAMS_PER_CONNECTION;
|
|
22934
|
+
var MAX_ACTIVE_TRANSFERS = MAX_ACTIVE_TRANSFERS_PER_DIRECTION;
|
|
22425
22935
|
var INLINE_TRANSFER_RESPONSE_BYTES2 = 2 * 1024 * 1024;
|
|
22426
22936
|
var HARNESS_REMOTE_ALLOWLIST = [
|
|
22427
22937
|
"$events",
|
|
@@ -22721,13 +23231,13 @@ function needsDirectoryFallback(result) {
|
|
|
22721
23231
|
}
|
|
22722
23232
|
function requestArgs(payload) {
|
|
22723
23233
|
const root = record5(payload);
|
|
22724
|
-
const args =
|
|
23234
|
+
const args = isRecord9(root.args) ? root.args : root;
|
|
22725
23235
|
return record5(args.request ?? args._request ?? args);
|
|
22726
23236
|
}
|
|
22727
23237
|
function record5(value) {
|
|
22728
|
-
return
|
|
23238
|
+
return isRecord9(value) ? value : {};
|
|
22729
23239
|
}
|
|
22730
|
-
function
|
|
23240
|
+
function isRecord9(value) {
|
|
22731
23241
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
22732
23242
|
}
|
|
22733
23243
|
|
|
@@ -22921,7 +23431,7 @@ var CodexAppServerClient = class {
|
|
|
22921
23431
|
this.handleProcessFailure("CODEX_INVALID_RESPONSE", new Error("Codex App Server emitted invalid JSON."));
|
|
22922
23432
|
return;
|
|
22923
23433
|
}
|
|
22924
|
-
if (!
|
|
23434
|
+
if (!isRecord10(value)) {
|
|
22925
23435
|
this.handleProcessFailure("CODEX_INVALID_RESPONSE", new Error("Codex App Server emitted an invalid message."));
|
|
22926
23436
|
return;
|
|
22927
23437
|
}
|
|
@@ -22966,12 +23476,12 @@ var CodexAppServerClient = class {
|
|
|
22966
23476
|
}
|
|
22967
23477
|
};
|
|
22968
23478
|
function safeUpstreamError(value) {
|
|
22969
|
-
if (!
|
|
23479
|
+
if (!isRecord10(value) || typeof value.message !== "string") return "Codex App Server rejected the request.";
|
|
22970
23480
|
const message = value.message.toLowerCase();
|
|
22971
23481
|
if (message.includes("active writer")) return "Codex thread already has an active writer.";
|
|
22972
23482
|
return message.includes("not initialized") ? "Codex App Server is not initialized." : "Codex App Server rejected the request.";
|
|
22973
23483
|
}
|
|
22974
|
-
function
|
|
23484
|
+
function isRecord10(value) {
|
|
22975
23485
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
22976
23486
|
}
|
|
22977
23487
|
|
|
@@ -23103,9 +23613,8 @@ var transferChunkSchema3 = external_exports.object({
|
|
|
23103
23613
|
}).strict();
|
|
23104
23614
|
var transferIdSchema3 = external_exports.object({ transferId: external_exports.string().uuid() }).strict();
|
|
23105
23615
|
var transferReadSchema3 = external_exports.object({ transferId: external_exports.string().uuid(), index: external_exports.number().int().nonnegative() }).strict();
|
|
23106
|
-
var MAX_ACTIVE_STREAMS2 =
|
|
23107
|
-
var MAX_ACTIVE_TRANSFERS2 =
|
|
23108
|
-
var TRANSFER_IDLE_MS2 = 2 * 6e4;
|
|
23616
|
+
var MAX_ACTIVE_STREAMS2 = MAX_ALPHA_STREAMS_PER_CONNECTION;
|
|
23617
|
+
var MAX_ACTIVE_TRANSFERS2 = MAX_ACTIVE_TRANSFERS_PER_DIRECTION;
|
|
23109
23618
|
var INLINE_TRANSFER_RESPONSE_BYTES3 = 2 * 1024 * 1024;
|
|
23110
23619
|
var CodexPeerBridge = class {
|
|
23111
23620
|
constructor(domain, context, publish, logger) {
|
|
@@ -23319,7 +23828,7 @@ var CodexPeerBridge = class {
|
|
|
23319
23828
|
await this.domain.detachPeer(this.context.connectionId);
|
|
23320
23829
|
}
|
|
23321
23830
|
pruneTransfers() {
|
|
23322
|
-
const staleBefore = Date.now() -
|
|
23831
|
+
const staleBefore = Date.now() - TRANSFER_IDLE_MS;
|
|
23323
23832
|
for (const [id2, transfer] of this.incomingTransfers) {
|
|
23324
23833
|
if (transfer.touchedAt < staleBefore) this.incomingTransfers.delete(id2);
|
|
23325
23834
|
}
|
|
@@ -23341,15 +23850,15 @@ function decodeCanonicalBase643(value) {
|
|
|
23341
23850
|
}
|
|
23342
23851
|
return decoded;
|
|
23343
23852
|
}
|
|
23344
|
-
function
|
|
23853
|
+
function isRecord11(value) {
|
|
23345
23854
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23346
23855
|
}
|
|
23347
23856
|
function safeErrorCode2(error) {
|
|
23348
|
-
if (
|
|
23857
|
+
if (isRecord11(error) && typeof error.code === "string") return error.code;
|
|
23349
23858
|
return "UNKNOWN";
|
|
23350
23859
|
}
|
|
23351
23860
|
function safeMethod(input2) {
|
|
23352
|
-
return
|
|
23861
|
+
return isRecord11(input2) && typeof input2.method === "string" ? input2.method : "invalid";
|
|
23353
23862
|
}
|
|
23354
23863
|
function concatChunks3(chunks, totalBytes) {
|
|
23355
23864
|
const output = new Uint8Array(totalBytes);
|
|
@@ -23766,14 +24275,14 @@ var CodexRemoteDomain = class {
|
|
|
23766
24275
|
await this.assertResultThreadAllowed(result);
|
|
23767
24276
|
if (codexPermissionPresetFromResponse(result) !== params.permissionPreset) {
|
|
23768
24277
|
await this.callUpstream("thread/settings/update", { threadId, ...settings });
|
|
23769
|
-
result = { ...
|
|
24278
|
+
result = { ...isRecord12(result) ? result : {}, ...settings, sandbox: settings.sandboxPolicy };
|
|
23770
24279
|
}
|
|
23771
24280
|
}
|
|
23772
24281
|
await this.publishPermission(threadId, result);
|
|
23773
24282
|
return result;
|
|
23774
24283
|
}
|
|
23775
24284
|
async publishPermission(threadId, value) {
|
|
23776
|
-
const source =
|
|
24285
|
+
const source = isRecord12(value) ? value : {};
|
|
23777
24286
|
const threadSettings = { approvalPolicy: source.approvalPolicy, sandboxPolicy: source.sandboxPolicy ?? source.sandbox };
|
|
23778
24287
|
await this.handleInbound({ kind: "notification", method: "thread/settings/updated", params: { threadId, threadSettings } });
|
|
23779
24288
|
}
|
|
@@ -23869,9 +24378,9 @@ var CodexRemoteDomain = class {
|
|
|
23869
24378
|
itemsView,
|
|
23870
24379
|
...cursor2 === void 0 ? {} : { cursor: cursor2 }
|
|
23871
24380
|
});
|
|
23872
|
-
const pageResult =
|
|
24381
|
+
const pageResult = isRecord12(result) ? result : {};
|
|
23873
24382
|
for (const rawTurn of array2(pageResult.data)) {
|
|
23874
|
-
if (!
|
|
24383
|
+
if (!isRecord12(rawTurn)) continue;
|
|
23875
24384
|
const turnId = typeof rawTurn.id === "string" ? rawTurn.id : void 0;
|
|
23876
24385
|
const items = rawTurn.itemsView === "full" || turnId === void 0 ? array2(rawTurn.items) : await this.readThreadItems(connectionId, threadId, turnId, array2(rawTurn.items));
|
|
23877
24386
|
turns.push({ ...rawTurn, items });
|
|
@@ -23893,9 +24402,9 @@ var CodexRemoteDomain = class {
|
|
|
23893
24402
|
sortDirection: "asc",
|
|
23894
24403
|
...cursor2 === void 0 ? {} : { cursor: cursor2 }
|
|
23895
24404
|
});
|
|
23896
|
-
const pageResult =
|
|
24405
|
+
const pageResult = isRecord12(result) ? result : {};
|
|
23897
24406
|
for (const entry of array2(pageResult.data)) {
|
|
23898
|
-
if (
|
|
24407
|
+
if (isRecord12(entry) && entry.item !== void 0) items.push(entry.item);
|
|
23899
24408
|
}
|
|
23900
24409
|
cursor2 = typeof pageResult.nextCursor === "string" && pageResult.nextCursor.length > 0 ? pageResult.nextCursor : void 0;
|
|
23901
24410
|
if (cursor2 === void 0) break;
|
|
@@ -23959,7 +24468,7 @@ var CodexRemoteDomain = class {
|
|
|
23959
24468
|
return [...this.peers.values()].some((peer) => peer.hasThreadSubscription(threadId));
|
|
23960
24469
|
}
|
|
23961
24470
|
resolveUpstreamApproval(params) {
|
|
23962
|
-
if (!
|
|
24471
|
+
if (!isRecord12(params) || typeof params.requestId !== "string" && typeof params.requestId !== "number") return;
|
|
23963
24472
|
for (const [handle, approval] of this.approvals) {
|
|
23964
24473
|
if (approval.upstreamId === params.requestId) this.approvals.delete(handle);
|
|
23965
24474
|
}
|
|
@@ -24176,24 +24685,24 @@ function codexBinaryCandidates(configured, hostPlatform = process.platform, user
|
|
|
24176
24685
|
])];
|
|
24177
24686
|
}
|
|
24178
24687
|
function parseCallEnvelope(input2) {
|
|
24179
|
-
if (!
|
|
24688
|
+
if (!isRecord12(input2) || typeof input2.method !== "string" || !("params" in input2) || Object.keys(input2).some((key) => key !== "method" && key !== "params")) {
|
|
24180
24689
|
throw new RpcError("INVALID_MESSAGE", "The Codex call envelope is invalid.");
|
|
24181
24690
|
}
|
|
24182
24691
|
return { method: input2.method, params: input2.params };
|
|
24183
24692
|
}
|
|
24184
24693
|
function parseRespond(input2) {
|
|
24185
|
-
if (!
|
|
24694
|
+
if (!isRecord12(input2) || typeof input2.requestHandle !== "string" || !["accept", "decline", "cancel"].includes(String(input2.decision)) || Object.keys(input2).some((key) => key !== "requestHandle" && key !== "decision")) {
|
|
24186
24695
|
throw new RpcError("INVALID_MESSAGE", "The Codex approval response is invalid.");
|
|
24187
24696
|
}
|
|
24188
24697
|
return input2;
|
|
24189
24698
|
}
|
|
24190
24699
|
function accountCanRun(result) {
|
|
24191
|
-
if (!
|
|
24192
|
-
return result.requiresOpenaiAuth === false ||
|
|
24700
|
+
if (!isRecord12(result) || typeof result.requiresOpenaiAuth !== "boolean") return false;
|
|
24701
|
+
return result.requiresOpenaiAuth === false || isRecord12(result.account);
|
|
24193
24702
|
}
|
|
24194
24703
|
function sanitizeAccount(result) {
|
|
24195
|
-
if (!
|
|
24196
|
-
const account =
|
|
24704
|
+
if (!isRecord12(result)) throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned invalid account state.");
|
|
24705
|
+
const account = isRecord12(result.account) ? result.account : void 0;
|
|
24197
24706
|
return {
|
|
24198
24707
|
authenticated: account !== void 0 || result.requiresOpenaiAuth === false,
|
|
24199
24708
|
requiresOpenaiAuth: result.requiresOpenaiAuth === true,
|
|
@@ -24206,11 +24715,11 @@ function sanitizeAccount(result) {
|
|
|
24206
24715
|
};
|
|
24207
24716
|
}
|
|
24208
24717
|
function sanitizeThreadList(result) {
|
|
24209
|
-
if (!
|
|
24718
|
+
if (!isRecord12(result) || !Array.isArray(result.data)) {
|
|
24210
24719
|
throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid thread list.");
|
|
24211
24720
|
}
|
|
24212
24721
|
const data = result.data.flatMap((value) => {
|
|
24213
|
-
if (!
|
|
24722
|
+
if (!isRecord12(value) || typeof value.id !== "string") return [];
|
|
24214
24723
|
return [{
|
|
24215
24724
|
id: value.id,
|
|
24216
24725
|
...typeof value.sessionId === "string" ? { sessionId: value.sessionId } : {},
|
|
@@ -24222,7 +24731,7 @@ function sanitizeThreadList(result) {
|
|
|
24222
24731
|
...typeof value.updatedAt === "number" && Number.isFinite(value.updatedAt) ? { updatedAt: value.updatedAt } : {},
|
|
24223
24732
|
...typeof value.archived === "boolean" ? { archived: value.archived } : {},
|
|
24224
24733
|
...typeof value.isPinned === "boolean" ? { isPinned: value.isPinned } : {},
|
|
24225
|
-
...
|
|
24734
|
+
...isRecord12(value.status) ? { status: value.status } : {}
|
|
24226
24735
|
}];
|
|
24227
24736
|
});
|
|
24228
24737
|
return {
|
|
@@ -24232,18 +24741,18 @@ function sanitizeThreadList(result) {
|
|
|
24232
24741
|
};
|
|
24233
24742
|
}
|
|
24234
24743
|
function filterThreadListByWorkspaceAuthority(result, authority) {
|
|
24235
|
-
if (!
|
|
24744
|
+
if (!isRecord12(result) || !Array.isArray(result.data)) {
|
|
24236
24745
|
throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid thread list.");
|
|
24237
24746
|
}
|
|
24238
24747
|
return {
|
|
24239
24748
|
...result,
|
|
24240
|
-
data: result.data.map((record6) =>
|
|
24749
|
+
data: result.data.map((record6) => isRecord12(record6) ? record6 : void 0).filter((thread) => thread !== void 0 && isThreadAllowedByWorkspaceAuthority(thread, authority))
|
|
24241
24750
|
};
|
|
24242
24751
|
}
|
|
24243
24752
|
function sanitizeProject(value) {
|
|
24244
|
-
if (!
|
|
24753
|
+
if (!isRecord12(value) || typeof value.id !== "string" || typeof value.name !== "string") return void 0;
|
|
24245
24754
|
const roots = Array.isArray(value.roots) ? value.roots.flatMap((root) => {
|
|
24246
|
-
const path =
|
|
24755
|
+
const path = isRecord12(root) && typeof root.path === "string" && root.path.length > 0 ? root.path : void 0;
|
|
24247
24756
|
return path === void 0 || !isAbsolute3(path) ? [] : [{ path }];
|
|
24248
24757
|
}) : [];
|
|
24249
24758
|
if (roots.length === 0) return void 0;
|
|
@@ -24257,7 +24766,7 @@ function sanitizeProject(value) {
|
|
|
24257
24766
|
};
|
|
24258
24767
|
}
|
|
24259
24768
|
function sanitizeProjectList(result) {
|
|
24260
|
-
if (!
|
|
24769
|
+
if (!isRecord12(result) || !Array.isArray(result.data)) {
|
|
24261
24770
|
throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid project list.");
|
|
24262
24771
|
}
|
|
24263
24772
|
const data = result.data.flatMap((value) => sanitizeProject(value) ?? []);
|
|
@@ -24267,7 +24776,7 @@ function sanitizeProjectList(result) {
|
|
|
24267
24776
|
};
|
|
24268
24777
|
}
|
|
24269
24778
|
function sanitizeProjectCreate(result) {
|
|
24270
|
-
const project =
|
|
24779
|
+
const project = isRecord12(result) ? sanitizeProject(result.project) : void 0;
|
|
24271
24780
|
if (project === void 0) {
|
|
24272
24781
|
throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid created project.");
|
|
24273
24782
|
}
|
|
@@ -24299,19 +24808,19 @@ function codexDirectoryCrumbs(root, path) {
|
|
|
24299
24808
|
return crumbs2;
|
|
24300
24809
|
}
|
|
24301
24810
|
function extractThread(result) {
|
|
24302
|
-
return
|
|
24811
|
+
return isRecord12(result) && isRecord12(result.thread) ? result.thread : void 0;
|
|
24303
24812
|
}
|
|
24304
24813
|
function extractTurnId(result) {
|
|
24305
|
-
if (!
|
|
24814
|
+
if (!isRecord12(result)) return void 0;
|
|
24306
24815
|
if (typeof result.turnId === "string" && result.turnId.length > 0) return result.turnId;
|
|
24307
|
-
if (
|
|
24816
|
+
if (isRecord12(result.turn) && typeof result.turn.id === "string" && result.turn.id.length > 0) return result.turn.id;
|
|
24308
24817
|
return void 0;
|
|
24309
24818
|
}
|
|
24310
24819
|
function extractThreadId(params) {
|
|
24311
|
-
if (!
|
|
24820
|
+
if (!isRecord12(params)) return void 0;
|
|
24312
24821
|
if (typeof params.threadId === "string") return params.threadId;
|
|
24313
|
-
if (
|
|
24314
|
-
if (
|
|
24822
|
+
if (isRecord12(params.thread) && typeof params.thread.id === "string") return params.thread.id;
|
|
24823
|
+
if (isRecord12(params.turn) && typeof params.turn.threadId === "string") return params.turn.threadId;
|
|
24315
24824
|
return void 0;
|
|
24316
24825
|
}
|
|
24317
24826
|
function optionalInteger2(value) {
|
|
@@ -24353,13 +24862,13 @@ function mapCodexImageInputs(params) {
|
|
|
24353
24862
|
return {
|
|
24354
24863
|
...params,
|
|
24355
24864
|
input: params.input.map((value) => {
|
|
24356
|
-
if (!
|
|
24865
|
+
if (!isRecord12(value) || value.type !== "image" || typeof value.mediaType !== "string" || typeof value.data !== "string") return value;
|
|
24357
24866
|
return { type: "image", url: `data:${value.mediaType};base64,${value.data}` };
|
|
24358
24867
|
})
|
|
24359
24868
|
};
|
|
24360
24869
|
}
|
|
24361
24870
|
function sanitizeApprovalParams(params, requestHandle) {
|
|
24362
|
-
if (!
|
|
24871
|
+
if (!isRecord12(params)) return { requestHandle };
|
|
24363
24872
|
const safe = { ...params };
|
|
24364
24873
|
delete safe.proposedExecpolicyAmendment;
|
|
24365
24874
|
delete safe.additionalPermissions;
|
|
@@ -24390,7 +24899,7 @@ function isProjectListFallbackError(error) {
|
|
|
24390
24899
|
function canTryNextBinary(error) {
|
|
24391
24900
|
return !(error instanceof RpcError) || !["CODEX_AUTH_REQUIRED", "CODEX_CLOSED"].includes(error.code);
|
|
24392
24901
|
}
|
|
24393
|
-
function
|
|
24902
|
+
function isRecord12(value) {
|
|
24394
24903
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24395
24904
|
}
|
|
24396
24905
|
function array2(value) {
|
|
@@ -24498,6 +25007,9 @@ var HostPluginRuntime = class {
|
|
|
24498
25007
|
accountRequired: error === "ACCOUNT_AUTH_REQUIRED" || error === "AUTH_INVALID" || error === "TOKEN_EXPIRED"
|
|
24499
25008
|
};
|
|
24500
25009
|
}
|
|
25010
|
+
localHarnessVersion() {
|
|
25011
|
+
return this.harnessVersion;
|
|
25012
|
+
}
|
|
24501
25013
|
reconnectHost() {
|
|
24502
25014
|
if (this.closed) throw new Error("remote runtime is closed");
|
|
24503
25015
|
if (this.serverConnection === void 0) {
|
|
@@ -24667,9 +25179,14 @@ var HostPluginRuntime = class {
|
|
|
24667
25179
|
}
|
|
24668
25180
|
hostCapabilities() {
|
|
24669
25181
|
const capabilities = [];
|
|
24670
|
-
if (this.apiProxy !== void 0) capabilities.push("harness.api.v1", "harness.api.transfer.v1");
|
|
24671
25182
|
if (this.localGateway?.supportsCarrier === true) {
|
|
24672
|
-
capabilities.push(
|
|
25183
|
+
capabilities.push(
|
|
25184
|
+
harnessSessionGeneration(this.harnessVersion) === "v3" ? "harness.remote.v3" : "harness.remote.v1",
|
|
25185
|
+
"harness.remote.transfer.v1"
|
|
25186
|
+
);
|
|
25187
|
+
}
|
|
25188
|
+
if (this.apiProxy !== void 0) {
|
|
25189
|
+
capabilities.push("harness.api.v1", "harness.api.transfer.v1");
|
|
24673
25190
|
}
|
|
24674
25191
|
if (this.fileViewerHost?.() !== void 0) capabilities.push("fileviewer.read.v1");
|
|
24675
25192
|
if (this.codex.isAvailable()) capabilities.push("codex.appserver.v1", "codex.appserver.transfer.v1");
|
|
@@ -25123,7 +25640,7 @@ function remoteStatusLines(target) {
|
|
|
25123
25640
|
`Device: ${status2.deviceId ?? "not initialized"}`,
|
|
25124
25641
|
`Authorization: ${status2.authorized ? status2.account === void 0 ? "logged in" : `logged in (${status2.account})` : "logged out"}`,
|
|
25125
25642
|
`Server connection: ${connection}`,
|
|
25126
|
-
`Harness Remote API: ${capabilities.has("harness.api.v1") ? "available (ApiProxy)" : capabilities.has("harness.remote.v1") ? "available (Typert Remote)" : "unavailable"}`,
|
|
25643
|
+
`Harness Remote API: ${capabilities.has("harness.api.v1") ? "available (ApiProxy)" : capabilities.has("harness.remote.v3") ? "available (Typert Remote Session V3)" : capabilities.has("harness.remote.v1") ? "available (Typert Remote)" : "unavailable"}`,
|
|
25127
25644
|
`Remote clients: ${diagnostics.activeConnections}`,
|
|
25128
25645
|
`Codex Remote: ${codex.enabled ? codex.state : "disabled"}`,
|
|
25129
25646
|
"",
|
|
@@ -25396,6 +25913,7 @@ function apply(ctx, input2 = {}) {
|
|
|
25396
25913
|
const activateWhenCarrierReady = (runtimeContext) => {
|
|
25397
25914
|
const gateway = runtimeContext.get("typertGateway");
|
|
25398
25915
|
const connection = runtimeContext.get("connection");
|
|
25916
|
+
const webServer = runtimeContext.get("webServer");
|
|
25399
25917
|
let disposePendingControl;
|
|
25400
25918
|
const installPendingControl = () => {
|
|
25401
25919
|
if (connection === void 0 || disposePendingControl !== void 0) return;
|
|
@@ -25407,7 +25925,7 @@ function apply(ctx, input2 = {}) {
|
|
|
25407
25925
|
void 0,
|
|
25408
25926
|
void 0
|
|
25409
25927
|
);
|
|
25410
|
-
return control.register(connection);
|
|
25928
|
+
return control.register(connection, webServer);
|
|
25411
25929
|
}, "dsh-remote pending control");
|
|
25412
25930
|
};
|
|
25413
25931
|
const startActiveRuntime = async (activeContext) => {
|
|
@@ -25441,13 +25959,14 @@ async function activate(ctx, input2, tuiBinding) {
|
|
|
25441
25959
|
reportSettingsMigration(ctx, await migration);
|
|
25442
25960
|
}
|
|
25443
25961
|
const connection = ctx.get("connection");
|
|
25962
|
+
const webServer = ctx.get("webServer");
|
|
25444
25963
|
const resolvedConfig = resolveConfig(settingsScope?.get() ?? input2);
|
|
25445
25964
|
const config = connection === void 0 && resolvedConfig.serverUrl === void 0 ? { ...resolvedConfig, serverUrl: DEFAULT_REMOTE_SERVER_URL } : resolvedConfig;
|
|
25446
25965
|
const defaultIdentityDirectory = new IdentityStore().directory;
|
|
25447
25966
|
if (!config.enabled) {
|
|
25448
25967
|
if (connection !== void 0) {
|
|
25449
25968
|
const controlRuntime2 = new PluginControlRuntime(config, defaultIdentityDirectory, settingsScope, void 0, void 0);
|
|
25450
|
-
ctx.effect(() => controlRuntime2.register(connection), "dsh-remote disabled control");
|
|
25969
|
+
ctx.effect(() => controlRuntime2.register(connection, webServer), "dsh-remote disabled control");
|
|
25451
25970
|
}
|
|
25452
25971
|
return;
|
|
25453
25972
|
}
|
|
@@ -25506,7 +26025,7 @@ async function activate(ctx, input2, tuiBinding) {
|
|
|
25506
26025
|
if (tuiBinding !== void 0) tuiBinding.target = tuiTarget;
|
|
25507
26026
|
await disableLegacyLoaderEntries(ctx, logger);
|
|
25508
26027
|
await ctx.effect(async () => {
|
|
25509
|
-
const disposeControl = controlRuntime?.register(connection);
|
|
26028
|
+
const disposeControl = controlRuntime?.register(connection, webServer);
|
|
25510
26029
|
try {
|
|
25511
26030
|
await runtime.start();
|
|
25512
26031
|
if (clientRuntime !== void 0) {
|