ds-harness-remote 0.4.12 → 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 +4 -4
- package/dist/client-runtime.d.ts +8 -1
- package/dist/client-runtime.d.ts.map +1 -1
- package/dist/client-runtime.js +34 -24
- package/dist/client-runtime.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/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/index.d.ts.map +1 -1
- package/dist/index.js +474 -125
- package/dist/index.js.map +4 -4
- 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.map +1 -1
- package/dist/service.js +1 -1
- 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 +1 -1
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";
|
|
@@ -14310,11 +14482,168 @@ function base64ToBytes2(value) {
|
|
|
14310
14482
|
return bytes;
|
|
14311
14483
|
}
|
|
14312
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
|
+
|
|
14313
14641
|
// src/remote-typert-gateway.ts
|
|
14314
14642
|
var DIRECT_REMOTE_CALL_BYTES2 = 2 * 1024 * 1024;
|
|
14315
14643
|
var RemoteTypertGateway2 = class {
|
|
14316
|
-
constructor(client) {
|
|
14644
|
+
constructor(client, compatibility) {
|
|
14317
14645
|
this.client = client;
|
|
14646
|
+
this.compatibility = compatibility;
|
|
14318
14647
|
}
|
|
14319
14648
|
async invoke(request) {
|
|
14320
14649
|
const result = await this.dispatch(
|
|
@@ -14339,7 +14668,11 @@ var RemoteTypertGateway2 = class {
|
|
|
14339
14668
|
response = await this.callTransferred(encoded, signal);
|
|
14340
14669
|
}
|
|
14341
14670
|
}
|
|
14342
|
-
|
|
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;
|
|
14343
14676
|
}
|
|
14344
14677
|
async open(endpoint, payload, signal) {
|
|
14345
14678
|
const streamId = uuidV7();
|
|
@@ -14358,11 +14691,13 @@ var RemoteTypertGateway2 = class {
|
|
|
14358
14691
|
unsubscribeClose();
|
|
14359
14692
|
throw error;
|
|
14360
14693
|
}
|
|
14361
|
-
return this.iterate(streamId, queue, unsubscribe, unsubscribeClose, signal, onAbort);
|
|
14694
|
+
return this.iterate(streamId, endpoint, queue, unsubscribe, unsubscribeClose, signal, onAbort);
|
|
14362
14695
|
}
|
|
14363
|
-
async *iterate(streamId, queue, unsubscribe, unsubscribeClose, signal, onAbort) {
|
|
14696
|
+
async *iterate(streamId, endpoint, queue, unsubscribe, unsubscribeClose, signal, onAbort) {
|
|
14364
14697
|
try {
|
|
14365
|
-
|
|
14698
|
+
for await (const value of queue) {
|
|
14699
|
+
yield this.compatibility === "legacy-to-v3" ? normalizeLegacySessionGatewayValue(endpoint, value) : value;
|
|
14700
|
+
}
|
|
14366
14701
|
} finally {
|
|
14367
14702
|
signal.removeEventListener("abort", onAbort);
|
|
14368
14703
|
unsubscribe();
|
|
@@ -14482,16 +14817,16 @@ function routeStreamEvent2(event, streamId, queue) {
|
|
|
14482
14817
|
queue.fail(remoteFailure({
|
|
14483
14818
|
code: typeof failure2?.code === "string" ? failure2.code : "internal",
|
|
14484
14819
|
message: typeof failure2?.message === "string" ? failure2.message : "The remote Harness stream failed.",
|
|
14485
|
-
details:
|
|
14820
|
+
details: isRecord4(failure2?.details) ? failure2.details : {}
|
|
14486
14821
|
}));
|
|
14487
14822
|
} else {
|
|
14488
14823
|
queue.close();
|
|
14489
14824
|
}
|
|
14490
14825
|
}
|
|
14491
14826
|
function parseRpcResult(value) {
|
|
14492
|
-
if (!
|
|
14827
|
+
if (!isRecord4(value)) throw new Error("The remote Host returned an invalid Gateway result.");
|
|
14493
14828
|
if (value.ok === true) return Object.hasOwn(value, "value") ? { ok: true, value: value.value } : { ok: true };
|
|
14494
|
-
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)) {
|
|
14495
14830
|
throw new Error("The remote Host returned an invalid Gateway failure.");
|
|
14496
14831
|
}
|
|
14497
14832
|
return {
|
|
@@ -14525,7 +14860,7 @@ function base64ToBytes3(value) {
|
|
|
14525
14860
|
if (bytesToBase643(bytes) !== value) throw new Error("The remote Host returned non-canonical Harness Remote transfer data.");
|
|
14526
14861
|
return bytes;
|
|
14527
14862
|
}
|
|
14528
|
-
function
|
|
14863
|
+
function isRecord4(value) {
|
|
14529
14864
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
14530
14865
|
}
|
|
14531
14866
|
function hasErrorCode(error, code) {
|
|
@@ -15446,7 +15781,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15446
15781
|
this.broadcastRcHost({ type: "host/session-status", sessionId, running: args[1] });
|
|
15447
15782
|
} else if (event === "api-session/removed" && sessionId !== void 0) {
|
|
15448
15783
|
this.broadcastRcHost({ type: "host/session-removed", sessionId });
|
|
15449
|
-
} else if (event === "api-session/added" &&
|
|
15784
|
+
} else if (event === "api-session/added" && isRecord5(args[0])) {
|
|
15450
15785
|
const summary = args[0];
|
|
15451
15786
|
this.broadcastRcHost({
|
|
15452
15787
|
type: "host/session-added",
|
|
@@ -15831,7 +16166,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15831
16166
|
}
|
|
15832
16167
|
createApiProxy() {
|
|
15833
16168
|
const call = (endpoint) => async (request, signal) => {
|
|
15834
|
-
const payload = endpoint === "session.prompt" &&
|
|
16169
|
+
const payload = endpoint === "session.prompt" && isRecord5(request.payload) ? { ...request.payload, requestId: String(request.rpcId) } : request.payload;
|
|
15835
16170
|
const result = await this.dispatch(rcEndpoint(endpoint), { args: { request: payload } }, signal ?? new AbortController().signal);
|
|
15836
16171
|
return {
|
|
15837
16172
|
rpcId: request.rpcId,
|
|
@@ -15915,8 +16250,8 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15915
16250
|
queue.close();
|
|
15916
16251
|
}
|
|
15917
16252
|
}
|
|
15918
|
-
broadcastRcMux(payload,
|
|
15919
|
-
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 });
|
|
15920
16255
|
}
|
|
15921
16256
|
broadcastRcHost(payload) {
|
|
15922
16257
|
const frame = { rpcId: `codex-host:${Date.now()}:${Math.random()}`, payload };
|
|
@@ -16356,7 +16691,7 @@ function collectImageBlocks(value, output = []) {
|
|
|
16356
16691
|
for (const item of value) collectImageBlocks(item, output);
|
|
16357
16692
|
return output;
|
|
16358
16693
|
}
|
|
16359
|
-
if (!
|
|
16694
|
+
if (!isRecord5(value)) return output;
|
|
16360
16695
|
if (value.type === "image") output.push(value);
|
|
16361
16696
|
for (const [key, child] of Object.entries(value)) {
|
|
16362
16697
|
if (key === "attachment") continue;
|
|
@@ -16686,7 +17021,7 @@ function codexPromptInput(content) {
|
|
|
16686
17021
|
if (content.length === 0 || content.length > MAX_CODEX_PROMPT_PARTS) return void 0;
|
|
16687
17022
|
const input2 = [];
|
|
16688
17023
|
for (const value of content) {
|
|
16689
|
-
if (!
|
|
17024
|
+
if (!isRecord5(value)) return void 0;
|
|
16690
17025
|
if (value.type === "text") {
|
|
16691
17026
|
if (typeof value.text !== "string" || value.text.length === 0 || value.text.length > MAX_CODEX_PROMPT_TEXT) return void 0;
|
|
16692
17027
|
input2.push({ type: "text", text: value.text });
|
|
@@ -16939,12 +17274,12 @@ function errorCode(error) {
|
|
|
16939
17274
|
return "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
16940
17275
|
}
|
|
16941
17276
|
function errorDetails(error) {
|
|
16942
|
-
return "details" in error &&
|
|
17277
|
+
return "details" in error && isRecord5(error.details) ? error.details : {};
|
|
16943
17278
|
}
|
|
16944
17279
|
function record2(value) {
|
|
16945
|
-
return
|
|
17280
|
+
return isRecord5(value) ? value : {};
|
|
16946
17281
|
}
|
|
16947
|
-
function
|
|
17282
|
+
function isRecord5(value) {
|
|
16948
17283
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16949
17284
|
}
|
|
16950
17285
|
function array(value) {
|
|
@@ -17158,7 +17493,7 @@ function normalizeServerUrl(value) {
|
|
|
17158
17493
|
}
|
|
17159
17494
|
|
|
17160
17495
|
// src/version.ts
|
|
17161
|
-
var PLUGIN_VERSION = "0.4.
|
|
17496
|
+
var PLUGIN_VERSION = "0.4.13";
|
|
17162
17497
|
|
|
17163
17498
|
// src/server-api.ts
|
|
17164
17499
|
var TERMINAL_CONTROL_CHARACTERS = /[\u0000-\u001f\u007f-\u009f]/u;
|
|
@@ -17677,7 +18012,7 @@ var TypertGatewaySwitch = class {
|
|
|
17677
18012
|
if (normalized !== void 0) return normalized;
|
|
17678
18013
|
const source = error instanceof Error ? error : new Error("The Harness Gateway rejected the request.");
|
|
17679
18014
|
const code = "code" in source && typeof source.code === "string" ? source.code : "internal";
|
|
17680
|
-
const details = "details" in source &&
|
|
18015
|
+
const details = "details" in source && isRecord6(source.details) ? source.details : {};
|
|
17681
18016
|
return { code, message: source.message, details };
|
|
17682
18017
|
}
|
|
17683
18018
|
};
|
|
@@ -17686,7 +18021,7 @@ function requestFromCarrier(endpoint, payload, signal) {
|
|
|
17686
18021
|
if (segments.length !== 2 || segments.some((segment) => segment.length === 0)) {
|
|
17687
18022
|
throw new Error("The Harness Gateway endpoint is invalid.");
|
|
17688
18023
|
}
|
|
17689
|
-
if (!
|
|
18024
|
+
if (!isRecord6(payload) || !isRecord6(payload.args)) {
|
|
17690
18025
|
throw new Error("The Harness Gateway payload is invalid.");
|
|
17691
18026
|
}
|
|
17692
18027
|
return { namespace: segments[0], method: segments[1], args: payload.args, signal };
|
|
@@ -17701,7 +18036,7 @@ function isLocalOnlyEndpoint(endpoint) {
|
|
|
17701
18036
|
function isRemoteCommandMethod(method) {
|
|
17702
18037
|
return REMOTE_COMMAND_METHODS.includes(method);
|
|
17703
18038
|
}
|
|
17704
|
-
function
|
|
18039
|
+
function isRecord6(value) {
|
|
17705
18040
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17706
18041
|
}
|
|
17707
18042
|
|
|
@@ -18805,10 +19140,8 @@ var ClientModeRuntime = class {
|
|
|
18805
19140
|
fingerprint: this.identity.fingerprint
|
|
18806
19141
|
});
|
|
18807
19142
|
}
|
|
18808
|
-
registerControl(connection) {
|
|
18809
|
-
return connection
|
|
18810
|
-
authority: "loopback"
|
|
18811
|
-
});
|
|
19143
|
+
registerControl(connection, webServer) {
|
|
19144
|
+
return registerControlRoute(connection, (endpoint, payload, signal) => this.handleControl(endpoint, payload, signal), webServer);
|
|
18812
19145
|
}
|
|
18813
19146
|
status() {
|
|
18814
19147
|
const targetStatus = this.gatewaySwitch.supportsCarrier() ? this.gatewaySwitch.status() : this.proxySwitch?.status() ?? this.gatewaySwitch.status();
|
|
@@ -18989,9 +19322,9 @@ var ClientModeRuntime = class {
|
|
|
18989
19322
|
async openRemoteWorkspace(targetDeviceId, path, signal) {
|
|
18990
19323
|
if (path.trim() === "") throw new ClientModeError("INVALID_MESSAGE", "A remote working directory is required.");
|
|
18991
19324
|
const remote = await this.ensureConnected(targetDeviceId, signal);
|
|
18992
|
-
this.
|
|
19325
|
+
const transport = this.selectHarnessRemoteTransport(remote);
|
|
18993
19326
|
let workspace;
|
|
18994
|
-
if (
|
|
19327
|
+
if (transport === "remoteGateway") {
|
|
18995
19328
|
workspace = await new RemoteTypertGateway2(remote.client).invoke({
|
|
18996
19329
|
namespace: "workspace",
|
|
18997
19330
|
method: "create",
|
|
@@ -19007,7 +19340,7 @@ var ClientModeRuntime = class {
|
|
|
19007
19340
|
workspace = unwrapNativeResult(response);
|
|
19008
19341
|
}
|
|
19009
19342
|
await this.closeCodexVirtual();
|
|
19010
|
-
this.selectRemoteTarget(remote);
|
|
19343
|
+
this.selectRemoteTarget(remote, transport);
|
|
19011
19344
|
const workspaceId = workspaceRecordId(workspace.workspace);
|
|
19012
19345
|
this.pendingWorkspaceSelection = { targetDeviceId: remote.target.deviceId, workspaceId };
|
|
19013
19346
|
this.logger.info("Remote workspace opened", { targetDeviceId: shortId(remote.target.deviceId) });
|
|
@@ -19027,7 +19360,7 @@ var ClientModeRuntime = class {
|
|
|
19027
19360
|
if (!remote.features.codex) {
|
|
19028
19361
|
throw new ClientModeError("FEATURE_NOT_SUPPORTED", "The selected Host does not provide CodeX workspaces.");
|
|
19029
19362
|
}
|
|
19030
|
-
this.
|
|
19363
|
+
this.assertLocalHarnessCarrierAvailable();
|
|
19031
19364
|
const virtual = CodexVirtualHarness.remote(remote.client, {
|
|
19032
19365
|
deviceId: remote.target.deviceId,
|
|
19033
19366
|
name: remote.target.name
|
|
@@ -19060,7 +19393,7 @@ var ClientModeRuntime = class {
|
|
|
19060
19393
|
if (!remote.features.codex) {
|
|
19061
19394
|
throw new ClientModeError("FEATURE_NOT_SUPPORTED", "The selected Host does not provide CodeX workspaces.");
|
|
19062
19395
|
}
|
|
19063
|
-
this.
|
|
19396
|
+
this.assertLocalHarnessCarrierAvailable();
|
|
19064
19397
|
const result = record3(await new CodexRemoteClient(remote.client).request("project/create", {
|
|
19065
19398
|
name: remoteWorkspaceTitle(trimmedPath),
|
|
19066
19399
|
roots: [{ path: trimmedPath }],
|
|
@@ -19148,10 +19481,10 @@ var ClientModeRuntime = class {
|
|
|
19148
19481
|
}
|
|
19149
19482
|
}
|
|
19150
19483
|
stream.unsubscribe = remote.client.onEvent((event) => {
|
|
19151
|
-
if (event.event === "codex.app.frame" &&
|
|
19484
|
+
if (event.event === "codex.app.frame" && isRecord7(event.data) && event.data.streamId === value.streamId) {
|
|
19152
19485
|
this.appendCodexFrame(stream, event.data);
|
|
19153
19486
|
}
|
|
19154
|
-
if (event.event === "codex.app.stream.closed" &&
|
|
19487
|
+
if (event.event === "codex.app.stream.closed" && isRecord7(event.data) && event.data.streamId === value.streamId) {
|
|
19155
19488
|
stream.closed = typeof event.data.reason === "string" ? event.data.reason : "closed";
|
|
19156
19489
|
stream.wake();
|
|
19157
19490
|
}
|
|
@@ -19178,7 +19511,7 @@ var ClientModeRuntime = class {
|
|
|
19178
19511
|
stream.wake();
|
|
19179
19512
|
};
|
|
19180
19513
|
appendCodexFrame(stream, data) {
|
|
19181
|
-
if (!
|
|
19514
|
+
if (!isRecord7(data) || !isRecord7(data.frame) || typeof data.frame.method !== "string") return;
|
|
19182
19515
|
if (stream.frames.length >= 256) {
|
|
19183
19516
|
stream.closed = "overflow";
|
|
19184
19517
|
} else {
|
|
@@ -19235,18 +19568,25 @@ var ClientModeRuntime = class {
|
|
|
19235
19568
|
await stream.close();
|
|
19236
19569
|
}));
|
|
19237
19570
|
}
|
|
19238
|
-
selectRemoteTarget(remote) {
|
|
19571
|
+
selectRemoteTarget(remote, transport = this.selectHarnessRemoteTransport(remote)) {
|
|
19239
19572
|
const target = { deviceId: remote.target.deviceId, name: remote.target.name };
|
|
19240
|
-
if (
|
|
19241
|
-
this.gatewaySwitch.selectRemote(
|
|
19573
|
+
if (transport === "remoteGateway") {
|
|
19574
|
+
this.gatewaySwitch.selectRemote(this.remoteTypertGateway(remote), void 0, target);
|
|
19242
19575
|
return;
|
|
19243
19576
|
}
|
|
19244
|
-
this.proxySwitch
|
|
19577
|
+
this.proxySwitch?.selectRemote(new RemoteHarnessApiProxy(remote.client).api, target);
|
|
19245
19578
|
this.gatewaySwitch.selectRemote((request) => invokeRemoteCommand(remote.client, request), {
|
|
19246
19579
|
execute: true,
|
|
19247
19580
|
list: remote.features.commandList
|
|
19248
19581
|
}, target);
|
|
19249
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
|
+
}
|
|
19250
19590
|
selectCodexTarget(virtual, remote) {
|
|
19251
19591
|
const target = { deviceId: remote.target.deviceId, name: remote.target.name };
|
|
19252
19592
|
if (this.gatewaySwitch.supportsCarrier()) {
|
|
@@ -19262,20 +19602,29 @@ var ClientModeRuntime = class {
|
|
|
19262
19602
|
await virtual?.close();
|
|
19263
19603
|
}
|
|
19264
19604
|
assertRemoteCompatible(remote) {
|
|
19605
|
+
this.selectHarnessRemoteTransport(remote);
|
|
19606
|
+
}
|
|
19607
|
+
selectHarnessRemoteTransport(remote) {
|
|
19265
19608
|
const localRemoteGateway = this.gatewaySwitch.supportsCarrier();
|
|
19609
|
+
const localSessionGeneration = harnessSessionGeneration(this.host?.localHarnessVersion?.());
|
|
19266
19610
|
if (localRemoteGateway && remote.features.remoteGateway) {
|
|
19267
|
-
|
|
19268
|
-
const remoteSessionGeneration = remote.features.sessionFormat === 3 ? "v3" : "legacy";
|
|
19269
|
-
if (localSessionGeneration === remoteSessionGeneration) return;
|
|
19611
|
+
if (localSessionGeneration === "v3" || remote.features.sessionFormat !== 3) return "remoteGateway";
|
|
19270
19612
|
throw new ClientModeError(
|
|
19271
19613
|
"HARNESS_VERSION_INCOMPATIBLE",
|
|
19272
|
-
|
|
19614
|
+
"The selected Host uses Harness Session V3, but this Client uses the legacy Typert Remote session format."
|
|
19273
19615
|
);
|
|
19274
19616
|
}
|
|
19275
|
-
if (
|
|
19617
|
+
if (this.proxySwitch !== void 0 && remote.features.apiProxy) return "apiProxy";
|
|
19276
19618
|
throw new ClientModeError(
|
|
19277
19619
|
"HARNESS_VERSION_INCOMPATIBLE",
|
|
19278
|
-
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."
|
|
19279
19628
|
);
|
|
19280
19629
|
}
|
|
19281
19630
|
async connect(targetDeviceId, signal) {
|
|
@@ -19654,20 +20003,20 @@ function record3(value) {
|
|
|
19654
20003
|
}
|
|
19655
20004
|
return value;
|
|
19656
20005
|
}
|
|
19657
|
-
function
|
|
20006
|
+
function isRecord7(value) {
|
|
19658
20007
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19659
20008
|
}
|
|
19660
20009
|
function ok2(value) {
|
|
19661
20010
|
return { ok: true, value };
|
|
19662
20011
|
}
|
|
19663
20012
|
async function invokeRemoteCommand(client, request) {
|
|
19664
|
-
const
|
|
20013
|
+
const rpcId2 = uuidV7();
|
|
19665
20014
|
const response = await client.rpc("harness.api.call", {
|
|
19666
20015
|
method: `${request.namespace}.${request.method}`,
|
|
19667
|
-
rpcId,
|
|
20016
|
+
rpcId: rpcId2,
|
|
19668
20017
|
payload: request.args
|
|
19669
20018
|
}, request.signal);
|
|
19670
|
-
if (response.rpcId !==
|
|
20019
|
+
if (response.rpcId !== rpcId2) {
|
|
19671
20020
|
throw new ClientModeError("INVALID_MESSAGE", "The remote Host returned an invalid command response.");
|
|
19672
20021
|
}
|
|
19673
20022
|
return unwrapNativeResult(response);
|
|
@@ -19679,11 +20028,11 @@ async function readRemoteWorkspaceBaseline(gateway, signal) {
|
|
|
19679
20028
|
const iterator = source[Symbol.asyncIterator]();
|
|
19680
20029
|
try {
|
|
19681
20030
|
const first = await iterator.next();
|
|
19682
|
-
if (first.done || !
|
|
20031
|
+
if (first.done || !isRecord7(first.value) || first.value.type !== "baseline" || !isRecord7(first.value.value) || !Array.isArray(first.value.value.items)) {
|
|
19683
20032
|
throw new ClientModeError("INVALID_MESSAGE", "The remote Host returned an invalid Workspace baseline.");
|
|
19684
20033
|
}
|
|
19685
20034
|
return first.value.value.items.map((item) => {
|
|
19686
|
-
if (!
|
|
20035
|
+
if (!isRecord7(item) || typeof item.workspaceId !== "string" || typeof item.path !== "string" || typeof item.title !== "string") {
|
|
19687
20036
|
throw new ClientModeError("INVALID_MESSAGE", "The remote Host returned an invalid Workspace row.");
|
|
19688
20037
|
}
|
|
19689
20038
|
return { workspaceId: item.workspaceId, path: item.path, title: item.title };
|
|
@@ -19748,19 +20097,20 @@ async function probeRemoteHostFeatures(client, clientVersion) {
|
|
|
19748
20097
|
if (error instanceof Error && "code" in error && error.code === "METHOD_NOT_FOUND") return fallback;
|
|
19749
20098
|
throw error;
|
|
19750
20099
|
}
|
|
19751
|
-
if (!
|
|
20100
|
+
if (!isRecord7(value) || !Array.isArray(value.capabilities) || value.capabilities.some((capability) => typeof capability !== "string")) {
|
|
19752
20101
|
throw new ClientModeError("INVALID_MESSAGE", "The remote Host returned invalid transport capabilities.");
|
|
19753
20102
|
}
|
|
19754
20103
|
const capabilities = new Set(value.capabilities);
|
|
19755
20104
|
const apiProxy = capabilities.has("harness.api.v1");
|
|
19756
20105
|
const remoteV1 = capabilities.has("harness.remote.v1");
|
|
19757
20106
|
const remoteV3 = capabilities.has("harness.remote.v3");
|
|
20107
|
+
const codex = capabilities.has("codex.appserver.v1");
|
|
19758
20108
|
if (remoteV1 && remoteV3) {
|
|
19759
20109
|
throw new ClientModeError("INVALID_MESSAGE", "The remote Host advertised conflicting Harness Session formats.");
|
|
19760
20110
|
}
|
|
19761
20111
|
const sessionFormat = remoteV3 ? 3 : void 0;
|
|
19762
20112
|
const remoteGateway = remoteV3 || remoteV1;
|
|
19763
|
-
if (!apiProxy && !remoteGateway) {
|
|
20113
|
+
if (!apiProxy && !remoteGateway && !codex) {
|
|
19764
20114
|
throw new ClientModeError("FEATURE_NOT_SUPPORTED", "The remote Host exposes no supported Harness transport.");
|
|
19765
20115
|
}
|
|
19766
20116
|
return {
|
|
@@ -19769,7 +20119,7 @@ async function probeRemoteHostFeatures(client, clientVersion) {
|
|
|
19769
20119
|
apiProxy,
|
|
19770
20120
|
remoteGateway,
|
|
19771
20121
|
...sessionFormat === void 0 ? {} : { sessionFormat },
|
|
19772
|
-
codex
|
|
20122
|
+
codex
|
|
19773
20123
|
};
|
|
19774
20124
|
}
|
|
19775
20125
|
async function waitForCodexFrames(stream, signal) {
|
|
@@ -20086,10 +20436,8 @@ var PluginControlRuntime = class {
|
|
|
20086
20436
|
this.client = client;
|
|
20087
20437
|
this.host = host;
|
|
20088
20438
|
}
|
|
20089
|
-
register(connection) {
|
|
20090
|
-
return connection
|
|
20091
|
-
authority: "loopback"
|
|
20092
|
-
});
|
|
20439
|
+
register(connection, webServer) {
|
|
20440
|
+
return registerControlRoute(connection, (endpoint, payload, signal) => this.handle(endpoint, payload, signal), webServer);
|
|
20093
20441
|
}
|
|
20094
20442
|
async handle(endpoint, payload, signal) {
|
|
20095
20443
|
try {
|
|
@@ -20303,11 +20651,11 @@ function editableConfig(config) {
|
|
|
20303
20651
|
}
|
|
20304
20652
|
};
|
|
20305
20653
|
}
|
|
20306
|
-
function
|
|
20654
|
+
function isRecord8(value) {
|
|
20307
20655
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20308
20656
|
}
|
|
20309
20657
|
function record4(value) {
|
|
20310
|
-
if (!
|
|
20658
|
+
if (!isRecord8(value)) throw new ClientModeError("INVALID_MESSAGE", "The control request payload is invalid.");
|
|
20311
20659
|
return value;
|
|
20312
20660
|
}
|
|
20313
20661
|
function ok3(value) {
|
|
@@ -20628,7 +20976,7 @@ var RpcRouter = class {
|
|
|
20628
20976
|
});
|
|
20629
20977
|
return createRpcResponse(request.id, result);
|
|
20630
20978
|
} catch (error) {
|
|
20631
|
-
const response =
|
|
20979
|
+
const response = errorResponse2(request.id, error);
|
|
20632
20980
|
this.logger?.warn("host rpc failed", {
|
|
20633
20981
|
method: request.payload.method,
|
|
20634
20982
|
durationMs: Math.round(performance.now() - startedAt),
|
|
@@ -20727,7 +21075,7 @@ var RpcRouter = class {
|
|
|
20727
21075
|
return this.codex;
|
|
20728
21076
|
}
|
|
20729
21077
|
};
|
|
20730
|
-
function
|
|
21078
|
+
function errorResponse2(requestId, error) {
|
|
20731
21079
|
const code = safeErrorCode(error);
|
|
20732
21080
|
if (error instanceof RpcError) return createRpcError(requestId, code, error.message, error.details, error.retryable);
|
|
20733
21081
|
return createRpcError(
|
|
@@ -21920,8 +22268,8 @@ var HARNESS_API_ALLOWLIST = [
|
|
|
21920
22268
|
"credentials.unset"
|
|
21921
22269
|
];
|
|
21922
22270
|
var NATIVE_CALL_TIMEOUT_MS = 3e4;
|
|
21923
|
-
var MAX_ACTIVE_API_TRANSFERS =
|
|
21924
|
-
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;
|
|
21925
22273
|
var INLINE_TRANSFER_RESPONSE_BYTES = 2 * 1024 * 1024;
|
|
21926
22274
|
var SESSION_HISTORY_PAGE_SIZES = [50, 30, 20, 12, 6, 3, 1];
|
|
21927
22275
|
var HarnessApiBridge = class {
|
|
@@ -21998,9 +22346,9 @@ var HarnessApiBridge = class {
|
|
|
21998
22346
|
const value = await listRemoteDirectory(payload.path, signal);
|
|
21999
22347
|
return { rpcId: params.rpcId, result: { ok: true, value } };
|
|
22000
22348
|
}
|
|
22001
|
-
describeFallback(
|
|
22349
|
+
describeFallback(rpcId2) {
|
|
22002
22350
|
return {
|
|
22003
|
-
rpcId,
|
|
22351
|
+
rpcId: rpcId2,
|
|
22004
22352
|
result: {
|
|
22005
22353
|
ok: true,
|
|
22006
22354
|
value: {
|
|
@@ -22218,8 +22566,8 @@ var HarnessApiBridge = class {
|
|
|
22218
22566
|
}
|
|
22219
22567
|
}
|
|
22220
22568
|
deleteRespondable(value) {
|
|
22221
|
-
for (const [
|
|
22222
|
-
if (correlation === value) this.respondable.delete(
|
|
22569
|
+
for (const [rpcId2, correlation] of this.respondable) {
|
|
22570
|
+
if (correlation === value) this.respondable.delete(rpcId2);
|
|
22223
22571
|
}
|
|
22224
22572
|
}
|
|
22225
22573
|
};
|
|
@@ -22406,9 +22754,9 @@ function sanitizeModelDiscoveryResponse(response, settingsNs) {
|
|
|
22406
22754
|
if (typeof result === "object" && result !== null && "ok" in result && result.ok === true) return response;
|
|
22407
22755
|
return modelDiscoveryFailure(response.rpcId, settingsNs);
|
|
22408
22756
|
}
|
|
22409
|
-
function modelDiscoveryFailure(
|
|
22757
|
+
function modelDiscoveryFailure(rpcId2, settingsNs) {
|
|
22410
22758
|
return {
|
|
22411
|
-
rpcId,
|
|
22759
|
+
rpcId: rpcId2,
|
|
22412
22760
|
result: {
|
|
22413
22761
|
ok: false,
|
|
22414
22762
|
error: {
|
|
@@ -22468,15 +22816,15 @@ function frameSessionId(frame) {
|
|
|
22468
22816
|
const payload = frame.payload;
|
|
22469
22817
|
return typeof payload.sessionId === "string" && payload.sessionId.length > 0 ? payload.sessionId : void 0;
|
|
22470
22818
|
}
|
|
22471
|
-
function callSessionHistory(callWithTimeout, payload,
|
|
22819
|
+
function callSessionHistory(callWithTimeout, payload, rpcId2) {
|
|
22472
22820
|
const fallbackPageSizes = sessionHistoryFallbackPageSizes(payloadMaxMessages(payload));
|
|
22473
|
-
return callHistoryWithRetry(callWithTimeout, payload,
|
|
22821
|
+
return callHistoryWithRetry(callWithTimeout, payload, rpcId2, fallbackPageSizes);
|
|
22474
22822
|
}
|
|
22475
|
-
async function callHistoryWithRetry(callWithTimeout, payload,
|
|
22823
|
+
async function callHistoryWithRetry(callWithTimeout, payload, rpcId2, pageSizes) {
|
|
22476
22824
|
for (const maxMessages of pageSizes) {
|
|
22477
22825
|
const requestPayload = historyRequestPayload(payload, maxMessages);
|
|
22478
22826
|
const response = await callWithTimeout(requestPayload);
|
|
22479
|
-
const request = createRpcResponse(
|
|
22827
|
+
const request = createRpcResponse(rpcId2, response.result);
|
|
22480
22828
|
if (encodeMessage(request).byteLength <= MAX_SECURE_MESSAGE_BYTES) return response;
|
|
22481
22829
|
if (maxMessages === pageSizes[pageSizes.length - 1]) {
|
|
22482
22830
|
throw new RpcError(
|
|
@@ -22582,9 +22930,8 @@ var transferReadSchema2 = external_exports.object({
|
|
|
22582
22930
|
var directoryListSchema2 = external_exports.object({
|
|
22583
22931
|
path: external_exports.string().min(1).max(4096).optional()
|
|
22584
22932
|
}).strict();
|
|
22585
|
-
var MAX_ACTIVE_STREAMS =
|
|
22586
|
-
var MAX_ACTIVE_TRANSFERS =
|
|
22587
|
-
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;
|
|
22588
22935
|
var INLINE_TRANSFER_RESPONSE_BYTES2 = 2 * 1024 * 1024;
|
|
22589
22936
|
var HARNESS_REMOTE_ALLOWLIST = [
|
|
22590
22937
|
"$events",
|
|
@@ -22884,13 +23231,13 @@ function needsDirectoryFallback(result) {
|
|
|
22884
23231
|
}
|
|
22885
23232
|
function requestArgs(payload) {
|
|
22886
23233
|
const root = record5(payload);
|
|
22887
|
-
const args =
|
|
23234
|
+
const args = isRecord9(root.args) ? root.args : root;
|
|
22888
23235
|
return record5(args.request ?? args._request ?? args);
|
|
22889
23236
|
}
|
|
22890
23237
|
function record5(value) {
|
|
22891
|
-
return
|
|
23238
|
+
return isRecord9(value) ? value : {};
|
|
22892
23239
|
}
|
|
22893
|
-
function
|
|
23240
|
+
function isRecord9(value) {
|
|
22894
23241
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
22895
23242
|
}
|
|
22896
23243
|
|
|
@@ -23084,7 +23431,7 @@ var CodexAppServerClient = class {
|
|
|
23084
23431
|
this.handleProcessFailure("CODEX_INVALID_RESPONSE", new Error("Codex App Server emitted invalid JSON."));
|
|
23085
23432
|
return;
|
|
23086
23433
|
}
|
|
23087
|
-
if (!
|
|
23434
|
+
if (!isRecord10(value)) {
|
|
23088
23435
|
this.handleProcessFailure("CODEX_INVALID_RESPONSE", new Error("Codex App Server emitted an invalid message."));
|
|
23089
23436
|
return;
|
|
23090
23437
|
}
|
|
@@ -23129,12 +23476,12 @@ var CodexAppServerClient = class {
|
|
|
23129
23476
|
}
|
|
23130
23477
|
};
|
|
23131
23478
|
function safeUpstreamError(value) {
|
|
23132
|
-
if (!
|
|
23479
|
+
if (!isRecord10(value) || typeof value.message !== "string") return "Codex App Server rejected the request.";
|
|
23133
23480
|
const message = value.message.toLowerCase();
|
|
23134
23481
|
if (message.includes("active writer")) return "Codex thread already has an active writer.";
|
|
23135
23482
|
return message.includes("not initialized") ? "Codex App Server is not initialized." : "Codex App Server rejected the request.";
|
|
23136
23483
|
}
|
|
23137
|
-
function
|
|
23484
|
+
function isRecord10(value) {
|
|
23138
23485
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23139
23486
|
}
|
|
23140
23487
|
|
|
@@ -23266,9 +23613,8 @@ var transferChunkSchema3 = external_exports.object({
|
|
|
23266
23613
|
}).strict();
|
|
23267
23614
|
var transferIdSchema3 = external_exports.object({ transferId: external_exports.string().uuid() }).strict();
|
|
23268
23615
|
var transferReadSchema3 = external_exports.object({ transferId: external_exports.string().uuid(), index: external_exports.number().int().nonnegative() }).strict();
|
|
23269
|
-
var MAX_ACTIVE_STREAMS2 =
|
|
23270
|
-
var MAX_ACTIVE_TRANSFERS2 =
|
|
23271
|
-
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;
|
|
23272
23618
|
var INLINE_TRANSFER_RESPONSE_BYTES3 = 2 * 1024 * 1024;
|
|
23273
23619
|
var CodexPeerBridge = class {
|
|
23274
23620
|
constructor(domain, context, publish, logger) {
|
|
@@ -23482,7 +23828,7 @@ var CodexPeerBridge = class {
|
|
|
23482
23828
|
await this.domain.detachPeer(this.context.connectionId);
|
|
23483
23829
|
}
|
|
23484
23830
|
pruneTransfers() {
|
|
23485
|
-
const staleBefore = Date.now() -
|
|
23831
|
+
const staleBefore = Date.now() - TRANSFER_IDLE_MS;
|
|
23486
23832
|
for (const [id2, transfer] of this.incomingTransfers) {
|
|
23487
23833
|
if (transfer.touchedAt < staleBefore) this.incomingTransfers.delete(id2);
|
|
23488
23834
|
}
|
|
@@ -23504,15 +23850,15 @@ function decodeCanonicalBase643(value) {
|
|
|
23504
23850
|
}
|
|
23505
23851
|
return decoded;
|
|
23506
23852
|
}
|
|
23507
|
-
function
|
|
23853
|
+
function isRecord11(value) {
|
|
23508
23854
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23509
23855
|
}
|
|
23510
23856
|
function safeErrorCode2(error) {
|
|
23511
|
-
if (
|
|
23857
|
+
if (isRecord11(error) && typeof error.code === "string") return error.code;
|
|
23512
23858
|
return "UNKNOWN";
|
|
23513
23859
|
}
|
|
23514
23860
|
function safeMethod(input2) {
|
|
23515
|
-
return
|
|
23861
|
+
return isRecord11(input2) && typeof input2.method === "string" ? input2.method : "invalid";
|
|
23516
23862
|
}
|
|
23517
23863
|
function concatChunks3(chunks, totalBytes) {
|
|
23518
23864
|
const output = new Uint8Array(totalBytes);
|
|
@@ -23929,14 +24275,14 @@ var CodexRemoteDomain = class {
|
|
|
23929
24275
|
await this.assertResultThreadAllowed(result);
|
|
23930
24276
|
if (codexPermissionPresetFromResponse(result) !== params.permissionPreset) {
|
|
23931
24277
|
await this.callUpstream("thread/settings/update", { threadId, ...settings });
|
|
23932
|
-
result = { ...
|
|
24278
|
+
result = { ...isRecord12(result) ? result : {}, ...settings, sandbox: settings.sandboxPolicy };
|
|
23933
24279
|
}
|
|
23934
24280
|
}
|
|
23935
24281
|
await this.publishPermission(threadId, result);
|
|
23936
24282
|
return result;
|
|
23937
24283
|
}
|
|
23938
24284
|
async publishPermission(threadId, value) {
|
|
23939
|
-
const source =
|
|
24285
|
+
const source = isRecord12(value) ? value : {};
|
|
23940
24286
|
const threadSettings = { approvalPolicy: source.approvalPolicy, sandboxPolicy: source.sandboxPolicy ?? source.sandbox };
|
|
23941
24287
|
await this.handleInbound({ kind: "notification", method: "thread/settings/updated", params: { threadId, threadSettings } });
|
|
23942
24288
|
}
|
|
@@ -24032,9 +24378,9 @@ var CodexRemoteDomain = class {
|
|
|
24032
24378
|
itemsView,
|
|
24033
24379
|
...cursor2 === void 0 ? {} : { cursor: cursor2 }
|
|
24034
24380
|
});
|
|
24035
|
-
const pageResult =
|
|
24381
|
+
const pageResult = isRecord12(result) ? result : {};
|
|
24036
24382
|
for (const rawTurn of array2(pageResult.data)) {
|
|
24037
|
-
if (!
|
|
24383
|
+
if (!isRecord12(rawTurn)) continue;
|
|
24038
24384
|
const turnId = typeof rawTurn.id === "string" ? rawTurn.id : void 0;
|
|
24039
24385
|
const items = rawTurn.itemsView === "full" || turnId === void 0 ? array2(rawTurn.items) : await this.readThreadItems(connectionId, threadId, turnId, array2(rawTurn.items));
|
|
24040
24386
|
turns.push({ ...rawTurn, items });
|
|
@@ -24056,9 +24402,9 @@ var CodexRemoteDomain = class {
|
|
|
24056
24402
|
sortDirection: "asc",
|
|
24057
24403
|
...cursor2 === void 0 ? {} : { cursor: cursor2 }
|
|
24058
24404
|
});
|
|
24059
|
-
const pageResult =
|
|
24405
|
+
const pageResult = isRecord12(result) ? result : {};
|
|
24060
24406
|
for (const entry of array2(pageResult.data)) {
|
|
24061
|
-
if (
|
|
24407
|
+
if (isRecord12(entry) && entry.item !== void 0) items.push(entry.item);
|
|
24062
24408
|
}
|
|
24063
24409
|
cursor2 = typeof pageResult.nextCursor === "string" && pageResult.nextCursor.length > 0 ? pageResult.nextCursor : void 0;
|
|
24064
24410
|
if (cursor2 === void 0) break;
|
|
@@ -24122,7 +24468,7 @@ var CodexRemoteDomain = class {
|
|
|
24122
24468
|
return [...this.peers.values()].some((peer) => peer.hasThreadSubscription(threadId));
|
|
24123
24469
|
}
|
|
24124
24470
|
resolveUpstreamApproval(params) {
|
|
24125
|
-
if (!
|
|
24471
|
+
if (!isRecord12(params) || typeof params.requestId !== "string" && typeof params.requestId !== "number") return;
|
|
24126
24472
|
for (const [handle, approval] of this.approvals) {
|
|
24127
24473
|
if (approval.upstreamId === params.requestId) this.approvals.delete(handle);
|
|
24128
24474
|
}
|
|
@@ -24339,24 +24685,24 @@ function codexBinaryCandidates(configured, hostPlatform = process.platform, user
|
|
|
24339
24685
|
])];
|
|
24340
24686
|
}
|
|
24341
24687
|
function parseCallEnvelope(input2) {
|
|
24342
|
-
if (!
|
|
24688
|
+
if (!isRecord12(input2) || typeof input2.method !== "string" || !("params" in input2) || Object.keys(input2).some((key) => key !== "method" && key !== "params")) {
|
|
24343
24689
|
throw new RpcError("INVALID_MESSAGE", "The Codex call envelope is invalid.");
|
|
24344
24690
|
}
|
|
24345
24691
|
return { method: input2.method, params: input2.params };
|
|
24346
24692
|
}
|
|
24347
24693
|
function parseRespond(input2) {
|
|
24348
|
-
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")) {
|
|
24349
24695
|
throw new RpcError("INVALID_MESSAGE", "The Codex approval response is invalid.");
|
|
24350
24696
|
}
|
|
24351
24697
|
return input2;
|
|
24352
24698
|
}
|
|
24353
24699
|
function accountCanRun(result) {
|
|
24354
|
-
if (!
|
|
24355
|
-
return result.requiresOpenaiAuth === false ||
|
|
24700
|
+
if (!isRecord12(result) || typeof result.requiresOpenaiAuth !== "boolean") return false;
|
|
24701
|
+
return result.requiresOpenaiAuth === false || isRecord12(result.account);
|
|
24356
24702
|
}
|
|
24357
24703
|
function sanitizeAccount(result) {
|
|
24358
|
-
if (!
|
|
24359
|
-
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;
|
|
24360
24706
|
return {
|
|
24361
24707
|
authenticated: account !== void 0 || result.requiresOpenaiAuth === false,
|
|
24362
24708
|
requiresOpenaiAuth: result.requiresOpenaiAuth === true,
|
|
@@ -24369,11 +24715,11 @@ function sanitizeAccount(result) {
|
|
|
24369
24715
|
};
|
|
24370
24716
|
}
|
|
24371
24717
|
function sanitizeThreadList(result) {
|
|
24372
|
-
if (!
|
|
24718
|
+
if (!isRecord12(result) || !Array.isArray(result.data)) {
|
|
24373
24719
|
throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid thread list.");
|
|
24374
24720
|
}
|
|
24375
24721
|
const data = result.data.flatMap((value) => {
|
|
24376
|
-
if (!
|
|
24722
|
+
if (!isRecord12(value) || typeof value.id !== "string") return [];
|
|
24377
24723
|
return [{
|
|
24378
24724
|
id: value.id,
|
|
24379
24725
|
...typeof value.sessionId === "string" ? { sessionId: value.sessionId } : {},
|
|
@@ -24385,7 +24731,7 @@ function sanitizeThreadList(result) {
|
|
|
24385
24731
|
...typeof value.updatedAt === "number" && Number.isFinite(value.updatedAt) ? { updatedAt: value.updatedAt } : {},
|
|
24386
24732
|
...typeof value.archived === "boolean" ? { archived: value.archived } : {},
|
|
24387
24733
|
...typeof value.isPinned === "boolean" ? { isPinned: value.isPinned } : {},
|
|
24388
|
-
...
|
|
24734
|
+
...isRecord12(value.status) ? { status: value.status } : {}
|
|
24389
24735
|
}];
|
|
24390
24736
|
});
|
|
24391
24737
|
return {
|
|
@@ -24395,18 +24741,18 @@ function sanitizeThreadList(result) {
|
|
|
24395
24741
|
};
|
|
24396
24742
|
}
|
|
24397
24743
|
function filterThreadListByWorkspaceAuthority(result, authority) {
|
|
24398
|
-
if (!
|
|
24744
|
+
if (!isRecord12(result) || !Array.isArray(result.data)) {
|
|
24399
24745
|
throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid thread list.");
|
|
24400
24746
|
}
|
|
24401
24747
|
return {
|
|
24402
24748
|
...result,
|
|
24403
|
-
data: result.data.map((record6) =>
|
|
24749
|
+
data: result.data.map((record6) => isRecord12(record6) ? record6 : void 0).filter((thread) => thread !== void 0 && isThreadAllowedByWorkspaceAuthority(thread, authority))
|
|
24404
24750
|
};
|
|
24405
24751
|
}
|
|
24406
24752
|
function sanitizeProject(value) {
|
|
24407
|
-
if (!
|
|
24753
|
+
if (!isRecord12(value) || typeof value.id !== "string" || typeof value.name !== "string") return void 0;
|
|
24408
24754
|
const roots = Array.isArray(value.roots) ? value.roots.flatMap((root) => {
|
|
24409
|
-
const path =
|
|
24755
|
+
const path = isRecord12(root) && typeof root.path === "string" && root.path.length > 0 ? root.path : void 0;
|
|
24410
24756
|
return path === void 0 || !isAbsolute3(path) ? [] : [{ path }];
|
|
24411
24757
|
}) : [];
|
|
24412
24758
|
if (roots.length === 0) return void 0;
|
|
@@ -24420,7 +24766,7 @@ function sanitizeProject(value) {
|
|
|
24420
24766
|
};
|
|
24421
24767
|
}
|
|
24422
24768
|
function sanitizeProjectList(result) {
|
|
24423
|
-
if (!
|
|
24769
|
+
if (!isRecord12(result) || !Array.isArray(result.data)) {
|
|
24424
24770
|
throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid project list.");
|
|
24425
24771
|
}
|
|
24426
24772
|
const data = result.data.flatMap((value) => sanitizeProject(value) ?? []);
|
|
@@ -24430,7 +24776,7 @@ function sanitizeProjectList(result) {
|
|
|
24430
24776
|
};
|
|
24431
24777
|
}
|
|
24432
24778
|
function sanitizeProjectCreate(result) {
|
|
24433
|
-
const project =
|
|
24779
|
+
const project = isRecord12(result) ? sanitizeProject(result.project) : void 0;
|
|
24434
24780
|
if (project === void 0) {
|
|
24435
24781
|
throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid created project.");
|
|
24436
24782
|
}
|
|
@@ -24462,19 +24808,19 @@ function codexDirectoryCrumbs(root, path) {
|
|
|
24462
24808
|
return crumbs2;
|
|
24463
24809
|
}
|
|
24464
24810
|
function extractThread(result) {
|
|
24465
|
-
return
|
|
24811
|
+
return isRecord12(result) && isRecord12(result.thread) ? result.thread : void 0;
|
|
24466
24812
|
}
|
|
24467
24813
|
function extractTurnId(result) {
|
|
24468
|
-
if (!
|
|
24814
|
+
if (!isRecord12(result)) return void 0;
|
|
24469
24815
|
if (typeof result.turnId === "string" && result.turnId.length > 0) return result.turnId;
|
|
24470
|
-
if (
|
|
24816
|
+
if (isRecord12(result.turn) && typeof result.turn.id === "string" && result.turn.id.length > 0) return result.turn.id;
|
|
24471
24817
|
return void 0;
|
|
24472
24818
|
}
|
|
24473
24819
|
function extractThreadId(params) {
|
|
24474
|
-
if (!
|
|
24820
|
+
if (!isRecord12(params)) return void 0;
|
|
24475
24821
|
if (typeof params.threadId === "string") return params.threadId;
|
|
24476
|
-
if (
|
|
24477
|
-
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;
|
|
24478
24824
|
return void 0;
|
|
24479
24825
|
}
|
|
24480
24826
|
function optionalInteger2(value) {
|
|
@@ -24516,13 +24862,13 @@ function mapCodexImageInputs(params) {
|
|
|
24516
24862
|
return {
|
|
24517
24863
|
...params,
|
|
24518
24864
|
input: params.input.map((value) => {
|
|
24519
|
-
if (!
|
|
24865
|
+
if (!isRecord12(value) || value.type !== "image" || typeof value.mediaType !== "string" || typeof value.data !== "string") return value;
|
|
24520
24866
|
return { type: "image", url: `data:${value.mediaType};base64,${value.data}` };
|
|
24521
24867
|
})
|
|
24522
24868
|
};
|
|
24523
24869
|
}
|
|
24524
24870
|
function sanitizeApprovalParams(params, requestHandle) {
|
|
24525
|
-
if (!
|
|
24871
|
+
if (!isRecord12(params)) return { requestHandle };
|
|
24526
24872
|
const safe = { ...params };
|
|
24527
24873
|
delete safe.proposedExecpolicyAmendment;
|
|
24528
24874
|
delete safe.additionalPermissions;
|
|
@@ -24553,7 +24899,7 @@ function isProjectListFallbackError(error) {
|
|
|
24553
24899
|
function canTryNextBinary(error) {
|
|
24554
24900
|
return !(error instanceof RpcError) || !["CODEX_AUTH_REQUIRED", "CODEX_CLOSED"].includes(error.code);
|
|
24555
24901
|
}
|
|
24556
|
-
function
|
|
24902
|
+
function isRecord12(value) {
|
|
24557
24903
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24558
24904
|
}
|
|
24559
24905
|
function array2(value) {
|
|
@@ -24838,7 +25184,8 @@ var HostPluginRuntime = class {
|
|
|
24838
25184
|
harnessSessionGeneration(this.harnessVersion) === "v3" ? "harness.remote.v3" : "harness.remote.v1",
|
|
24839
25185
|
"harness.remote.transfer.v1"
|
|
24840
25186
|
);
|
|
24841
|
-
}
|
|
25187
|
+
}
|
|
25188
|
+
if (this.apiProxy !== void 0) {
|
|
24842
25189
|
capabilities.push("harness.api.v1", "harness.api.transfer.v1");
|
|
24843
25190
|
}
|
|
24844
25191
|
if (this.fileViewerHost?.() !== void 0) capabilities.push("fileviewer.read.v1");
|
|
@@ -25293,7 +25640,7 @@ function remoteStatusLines(target) {
|
|
|
25293
25640
|
`Device: ${status2.deviceId ?? "not initialized"}`,
|
|
25294
25641
|
`Authorization: ${status2.authorized ? status2.account === void 0 ? "logged in" : `logged in (${status2.account})` : "logged out"}`,
|
|
25295
25642
|
`Server connection: ${connection}`,
|
|
25296
|
-
`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"}`,
|
|
25297
25644
|
`Remote clients: ${diagnostics.activeConnections}`,
|
|
25298
25645
|
`Codex Remote: ${codex.enabled ? codex.state : "disabled"}`,
|
|
25299
25646
|
"",
|
|
@@ -25566,6 +25913,7 @@ function apply(ctx, input2 = {}) {
|
|
|
25566
25913
|
const activateWhenCarrierReady = (runtimeContext) => {
|
|
25567
25914
|
const gateway = runtimeContext.get("typertGateway");
|
|
25568
25915
|
const connection = runtimeContext.get("connection");
|
|
25916
|
+
const webServer = runtimeContext.get("webServer");
|
|
25569
25917
|
let disposePendingControl;
|
|
25570
25918
|
const installPendingControl = () => {
|
|
25571
25919
|
if (connection === void 0 || disposePendingControl !== void 0) return;
|
|
@@ -25577,7 +25925,7 @@ function apply(ctx, input2 = {}) {
|
|
|
25577
25925
|
void 0,
|
|
25578
25926
|
void 0
|
|
25579
25927
|
);
|
|
25580
|
-
return control.register(connection);
|
|
25928
|
+
return control.register(connection, webServer);
|
|
25581
25929
|
}, "dsh-remote pending control");
|
|
25582
25930
|
};
|
|
25583
25931
|
const startActiveRuntime = async (activeContext) => {
|
|
@@ -25611,13 +25959,14 @@ async function activate(ctx, input2, tuiBinding) {
|
|
|
25611
25959
|
reportSettingsMigration(ctx, await migration);
|
|
25612
25960
|
}
|
|
25613
25961
|
const connection = ctx.get("connection");
|
|
25962
|
+
const webServer = ctx.get("webServer");
|
|
25614
25963
|
const resolvedConfig = resolveConfig(settingsScope?.get() ?? input2);
|
|
25615
25964
|
const config = connection === void 0 && resolvedConfig.serverUrl === void 0 ? { ...resolvedConfig, serverUrl: DEFAULT_REMOTE_SERVER_URL } : resolvedConfig;
|
|
25616
25965
|
const defaultIdentityDirectory = new IdentityStore().directory;
|
|
25617
25966
|
if (!config.enabled) {
|
|
25618
25967
|
if (connection !== void 0) {
|
|
25619
25968
|
const controlRuntime2 = new PluginControlRuntime(config, defaultIdentityDirectory, settingsScope, void 0, void 0);
|
|
25620
|
-
ctx.effect(() => controlRuntime2.register(connection), "dsh-remote disabled control");
|
|
25969
|
+
ctx.effect(() => controlRuntime2.register(connection, webServer), "dsh-remote disabled control");
|
|
25621
25970
|
}
|
|
25622
25971
|
return;
|
|
25623
25972
|
}
|
|
@@ -25676,7 +26025,7 @@ async function activate(ctx, input2, tuiBinding) {
|
|
|
25676
26025
|
if (tuiBinding !== void 0) tuiBinding.target = tuiTarget;
|
|
25677
26026
|
await disableLegacyLoaderEntries(ctx, logger);
|
|
25678
26027
|
await ctx.effect(async () => {
|
|
25679
|
-
const disposeControl = controlRuntime?.register(connection);
|
|
26028
|
+
const disposeControl = controlRuntime?.register(connection, webServer);
|
|
25680
26029
|
try {
|
|
25681
26030
|
await runtime.start();
|
|
25682
26031
|
if (clientRuntime !== void 0) {
|