ds-harness-remote 0.4.12 → 0.4.14
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/acp.d.ts +75 -0
- package/dist/acp.d.ts.map +1 -0
- package/dist/acp.js +61 -0
- package/dist/acp.js.map +1 -0
- package/dist/client-runtime.d.ts +14 -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/client.github.js +224 -9
- package/dist/client.js +224 -9
- package/dist/client.js.map +1 -1
- package/dist/codex/method-policy.d.ts +10 -10
- 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/config.d.ts +24 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -0
- package/dist/config.js.map +1 -1
- package/dist/connection-controller.d.ts +5 -0
- package/dist/connection-controller.d.ts.map +1 -1
- package/dist/connection-controller.js +16 -1
- package/dist/connection-controller.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 +6 -1
- package/dist/control-runtime.d.ts.map +1 -1
- package/dist/control-runtime.js +58 -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 +32 -11
- package/dist/harness-api-bridge.js.map +1 -1
- package/dist/harness-remote-bridge.d.ts +2 -1
- package/dist/harness-remote-bridge.d.ts.map +1 -1
- package/dist/harness-remote-bridge.js +47 -6
- package/dist/harness-remote-bridge.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +801 -147
- 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/rpc-router.d.ts +5 -2
- package/dist/rpc-router.d.ts.map +1 -1
- package/dist/rpc-router.js +18 -1
- package/dist/rpc-router.js.map +1 -1
- package/dist/service.d.ts +9 -0
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +32 -3
- 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,15 @@ 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;
|
|
4069
|
+
var MAX_ACP_PROMPT_BYTES = 64 * 1024;
|
|
4070
|
+
var MAX_ACP_UPDATE_BYTES = 512 * 1024;
|
|
4062
4071
|
var SECURE_FRAGMENT_MAGIC = new Uint8Array([68, 83, 72, 70]);
|
|
4063
4072
|
var SECURE_FRAGMENT_VERSION = 1;
|
|
4064
4073
|
var SECURE_FRAGMENT_HEADER_BYTES = 17;
|
|
@@ -4114,7 +4123,60 @@ var rpcMethods = [
|
|
|
4114
4123
|
"codex.app.transfer.chunk",
|
|
4115
4124
|
"codex.app.transfer.commit",
|
|
4116
4125
|
"codex.app.transfer.read",
|
|
4117
|
-
"codex.app.transfer.close"
|
|
4126
|
+
"codex.app.transfer.close",
|
|
4127
|
+
"acp.initialize",
|
|
4128
|
+
"acp.session.new",
|
|
4129
|
+
"acp.session.load",
|
|
4130
|
+
"acp.session.prompt",
|
|
4131
|
+
"acp.session.respond_permission",
|
|
4132
|
+
"acp.session.cancel",
|
|
4133
|
+
"acp.session.set_mode"
|
|
4134
|
+
];
|
|
4135
|
+
var errorCodes = [
|
|
4136
|
+
// Protocol / Version
|
|
4137
|
+
"INVALID_MESSAGE",
|
|
4138
|
+
"UNSUPPORTED_VERSION",
|
|
4139
|
+
"CAPABILITY_NOT_SUPPORTED",
|
|
4140
|
+
"METHOD_NOT_FOUND",
|
|
4141
|
+
"METHOD_NOT_ALLOWED",
|
|
4142
|
+
"REQUEST_CONFLICT",
|
|
4143
|
+
"FRAME_TOO_LARGE",
|
|
4144
|
+
"RATE_LIMITED",
|
|
4145
|
+
// Auth / Device
|
|
4146
|
+
"AUTH_REQUIRED",
|
|
4147
|
+
"AUTH_INVALID",
|
|
4148
|
+
"ACCOUNT_AUTH_REQUIRED",
|
|
4149
|
+
"TOKEN_EXPIRED",
|
|
4150
|
+
"DEVICE_NOT_FOUND",
|
|
4151
|
+
"DEVICE_REVOKED",
|
|
4152
|
+
"DEVICE_OWNERSHIP_REQUIRED",
|
|
4153
|
+
"MEMBERSHIP_REQUIRED",
|
|
4154
|
+
"PEER_IDENTITY_MISMATCH",
|
|
4155
|
+
"HOST_REGISTRATION_CODE_NOT_FOUND",
|
|
4156
|
+
"HOST_REGISTRATION_CODE_EXPIRED",
|
|
4157
|
+
"HOST_REGISTRATION_CODE_CONSUMED",
|
|
4158
|
+
// Connection / Transport
|
|
4159
|
+
"HOST_OFFLINE",
|
|
4160
|
+
"CONNECTION_NOT_FOUND",
|
|
4161
|
+
"CONNECTION_FAILED",
|
|
4162
|
+
"CONNECTION_REPLACED",
|
|
4163
|
+
"P2P_FAILED",
|
|
4164
|
+
"TURN_UNAVAILABLE",
|
|
4165
|
+
"RELAY_UNAVAILABLE",
|
|
4166
|
+
"SLOW_CONSUMER",
|
|
4167
|
+
"SECURE_CHANNEL_FAILED",
|
|
4168
|
+
// Harness
|
|
4169
|
+
"HARNESS_UNAVAILABLE",
|
|
4170
|
+
"HARNESS_VERSION_INCOMPATIBLE",
|
|
4171
|
+
"RESPONSE_TOO_LARGE",
|
|
4172
|
+
"SESSION_NOT_FOUND",
|
|
4173
|
+
"SESSION_NOT_READY",
|
|
4174
|
+
"AGENT_BUSY",
|
|
4175
|
+
"PERMISSION_DENIED",
|
|
4176
|
+
"PERMISSION_NOT_PENDING",
|
|
4177
|
+
"RPC_TIMEOUT",
|
|
4178
|
+
"FULL_RESYNC_REQUIRED",
|
|
4179
|
+
"INTERNAL_ERROR"
|
|
4118
4180
|
];
|
|
4119
4181
|
var selectedTransports = ["lan", "p2p", "turn", "relay"];
|
|
4120
4182
|
function normalizeSdpMLineIndex(value) {
|
|
@@ -4140,6 +4202,7 @@ function acceptNegotiatedCapabilities(offered, negotiated) {
|
|
|
4140
4202
|
var rpcMethodSchema = external_exports.enum(rpcMethods);
|
|
4141
4203
|
var messageTypeSchema = external_exports.enum(messageTypes);
|
|
4142
4204
|
var controlFrameTypeSchema = external_exports.enum(controlFrameTypes);
|
|
4205
|
+
var errorCodeSchema = external_exports.enum(errorCodes);
|
|
4143
4206
|
var uniqueStrings = (values) => new Set(values).size === values.length;
|
|
4144
4207
|
var uniqueNumbers = (values) => new Set(values).size === values.length;
|
|
4145
4208
|
var utf8Length = (value) => new TextEncoder().encode(value).byteLength;
|
|
@@ -4181,6 +4244,10 @@ var hostRegistrationCodeRequestSchema = external_exports.object({
|
|
|
4181
4244
|
code: external_exports.string().regex(/^[A-Z0-9]{4}-[A-Z0-9]{4}$/u),
|
|
4182
4245
|
device: hostDeviceDescriptorSchema
|
|
4183
4246
|
}).strict();
|
|
4247
|
+
var registerOwnedRoleRequestSchema = external_exports.object({
|
|
4248
|
+
v: external_exports.literal(PROTOCOL_VERSION),
|
|
4249
|
+
device: accountDeviceDescriptorSchema
|
|
4250
|
+
}).strict();
|
|
4184
4251
|
var deviceRefreshRequestSchema = external_exports.object({
|
|
4185
4252
|
deviceId: deviceIdSchema,
|
|
4186
4253
|
refreshToken: authTokenSchema
|
|
@@ -13958,6 +14025,120 @@ async function waitForResponder(inner, noise) {
|
|
|
13958
14025
|
|
|
13959
14026
|
// src/control-route.ts
|
|
13960
14027
|
var CONTROL_RPC_PREFIX = "/ds-harness-remote";
|
|
14028
|
+
var ENDPOINT_SEGMENT_PATTERN = /^[A-Za-z0-9_$.-]+$/;
|
|
14029
|
+
var INVALID_REQUEST_RPC_ID = "invalid-request";
|
|
14030
|
+
function registerControlRoute(connection, handler, webServer) {
|
|
14031
|
+
if (webServer !== void 0 && connection.requestRejection !== void 0) {
|
|
14032
|
+
const dispose = webServer.register({
|
|
14033
|
+
kind: "prefix",
|
|
14034
|
+
path: CONTROL_RPC_PREFIX,
|
|
14035
|
+
handler: (req, res) => handleControlRequest(connection, handler, req, res)
|
|
14036
|
+
});
|
|
14037
|
+
return async () => {
|
|
14038
|
+
await dispose();
|
|
14039
|
+
};
|
|
14040
|
+
}
|
|
14041
|
+
return connection.rpc.handle(CONTROL_RPC_PREFIX, handler, {
|
|
14042
|
+
authority: "loopback"
|
|
14043
|
+
});
|
|
14044
|
+
}
|
|
14045
|
+
async function handleControlRequest(connection, handler, req, res) {
|
|
14046
|
+
const rejection = connection.requestRejection?.(req);
|
|
14047
|
+
if (rejection !== void 0) {
|
|
14048
|
+
res.writeHead(rejection);
|
|
14049
|
+
res.end(rejection === 401 ? "unauthorized" : "forbidden");
|
|
14050
|
+
return;
|
|
14051
|
+
}
|
|
14052
|
+
const endpoint = endpointFromPath(CONTROL_RPC_PREFIX, new URL(req.url ?? "/", "http://dsh.internal").pathname);
|
|
14053
|
+
if (req.method !== "POST" || endpoint === void 0) {
|
|
14054
|
+
writeText(res, 404, "not found");
|
|
14055
|
+
return;
|
|
14056
|
+
}
|
|
14057
|
+
if (contentType(req.headers) !== "application/json") {
|
|
14058
|
+
writeText(res, 415, "content type must be application/json");
|
|
14059
|
+
return;
|
|
14060
|
+
}
|
|
14061
|
+
let body;
|
|
14062
|
+
try {
|
|
14063
|
+
body = await readJsonBody(req);
|
|
14064
|
+
} catch {
|
|
14065
|
+
writeText(res, 400, "body is not JSON");
|
|
14066
|
+
return;
|
|
14067
|
+
}
|
|
14068
|
+
const message = clientRequest(body);
|
|
14069
|
+
if (message === void 0) {
|
|
14070
|
+
writeJson(res, 200, errorResponse(rpcId(body), {
|
|
14071
|
+
code: "gateway/bad-request",
|
|
14072
|
+
message: "invalid client-request message",
|
|
14073
|
+
details: { issues: [] }
|
|
14074
|
+
}));
|
|
14075
|
+
return;
|
|
14076
|
+
}
|
|
14077
|
+
if (message.method !== endpoint) {
|
|
14078
|
+
writeJson(res, 200, errorResponse(message.rpcId, {
|
|
14079
|
+
code: "gateway/bad-request",
|
|
14080
|
+
message: `method ${JSON.stringify(message.method)} does not match endpoint ${JSON.stringify(endpoint)}`,
|
|
14081
|
+
details: { issues: [] }
|
|
14082
|
+
}));
|
|
14083
|
+
return;
|
|
14084
|
+
}
|
|
14085
|
+
try {
|
|
14086
|
+
const result = await handler(endpoint, message.payload, requestSignal(req));
|
|
14087
|
+
writeJson(res, 200, fullResponse(message.rpcId, result));
|
|
14088
|
+
} catch (error) {
|
|
14089
|
+
writeText(res, 500, `handler failure: ${String(error)}`);
|
|
14090
|
+
}
|
|
14091
|
+
}
|
|
14092
|
+
function endpointFromPath(channel, pathname) {
|
|
14093
|
+
if (!pathname.startsWith(`${channel}/`)) return void 0;
|
|
14094
|
+
const endpoint = pathname.slice(channel.length + 1);
|
|
14095
|
+
if (endpoint.split("/").some((segment) => segment === "" || segment === "." || segment === ".." || !ENDPOINT_SEGMENT_PATTERN.test(segment))) {
|
|
14096
|
+
return void 0;
|
|
14097
|
+
}
|
|
14098
|
+
return endpoint;
|
|
14099
|
+
}
|
|
14100
|
+
function contentType(headers) {
|
|
14101
|
+
const raw = headers["content-type"];
|
|
14102
|
+
const value = Array.isArray(raw) ? raw[0] : raw;
|
|
14103
|
+
return value?.split(";", 1)[0]?.trim().toLowerCase();
|
|
14104
|
+
}
|
|
14105
|
+
async function readJsonBody(req) {
|
|
14106
|
+
const chunks = [];
|
|
14107
|
+
for await (const chunk of req) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
14108
|
+
return JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
14109
|
+
}
|
|
14110
|
+
function requestSignal(req) {
|
|
14111
|
+
const abort = new AbortController();
|
|
14112
|
+
req.on("close", () => {
|
|
14113
|
+
if (!req.complete) abort.abort();
|
|
14114
|
+
});
|
|
14115
|
+
return abort.signal;
|
|
14116
|
+
}
|
|
14117
|
+
function clientRequest(value) {
|
|
14118
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
14119
|
+
const record6 = value;
|
|
14120
|
+
if (record6.type !== "client-request" || typeof record6.rpcId !== "string" || typeof record6.method !== "string") return void 0;
|
|
14121
|
+
return { type: "client-request", rpcId: record6.rpcId, method: record6.method, payload: record6.payload };
|
|
14122
|
+
}
|
|
14123
|
+
function rpcId(value) {
|
|
14124
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return INVALID_REQUEST_RPC_ID;
|
|
14125
|
+
const record6 = value;
|
|
14126
|
+
return typeof record6.rpcId === "string" ? record6.rpcId : INVALID_REQUEST_RPC_ID;
|
|
14127
|
+
}
|
|
14128
|
+
function errorResponse(rpcId2, error) {
|
|
14129
|
+
return fullResponse(rpcId2, { ok: false, error });
|
|
14130
|
+
}
|
|
14131
|
+
function fullResponse(rpcId2, result) {
|
|
14132
|
+
return { type: "server-response", rpcId: rpcId2, result };
|
|
14133
|
+
}
|
|
14134
|
+
function writeJson(res, status2, body) {
|
|
14135
|
+
res.writeHead(status2, { "content-type": "application/json" });
|
|
14136
|
+
res.end(JSON.stringify(body));
|
|
14137
|
+
}
|
|
14138
|
+
function writeText(res, status2, body) {
|
|
14139
|
+
res.writeHead(status2);
|
|
14140
|
+
res.end(body);
|
|
14141
|
+
}
|
|
13961
14142
|
|
|
13962
14143
|
// src/ids.ts
|
|
13963
14144
|
import { randomBytes as randomBytes6 } from "node:crypto";
|
|
@@ -14310,11 +14491,168 @@ function base64ToBytes2(value) {
|
|
|
14310
14491
|
return bytes;
|
|
14311
14492
|
}
|
|
14312
14493
|
|
|
14494
|
+
// src/session-format-compat.ts
|
|
14495
|
+
function normalizeLegacySessionGatewayValue(endpoint, value) {
|
|
14496
|
+
if (endpoint === "session/page") return normalizePage(value);
|
|
14497
|
+
if (endpoint === "session/follow") return normalizeFollowFrame(value);
|
|
14498
|
+
return value;
|
|
14499
|
+
}
|
|
14500
|
+
function normalizeFollowFrame(value) {
|
|
14501
|
+
if (!isRecord3(value)) return value;
|
|
14502
|
+
if (value.type === "snapshot") {
|
|
14503
|
+
return {
|
|
14504
|
+
...value,
|
|
14505
|
+
header: normalizeHeader(value.header),
|
|
14506
|
+
records: normalizeRecords(value.records),
|
|
14507
|
+
...value.assistantStream === void 0 ? { assistantStream: { revision: 0 } } : {}
|
|
14508
|
+
};
|
|
14509
|
+
}
|
|
14510
|
+
return normalizeEntry(value);
|
|
14511
|
+
}
|
|
14512
|
+
function normalizePage(value) {
|
|
14513
|
+
if (!isRecord3(value)) return value;
|
|
14514
|
+
return { ...value, records: normalizeRecords(value.records) };
|
|
14515
|
+
}
|
|
14516
|
+
function normalizeRecords(value) {
|
|
14517
|
+
if (!Array.isArray(value)) return value;
|
|
14518
|
+
const records = [];
|
|
14519
|
+
let previousSeq;
|
|
14520
|
+
for (const record6 of value) {
|
|
14521
|
+
if (!isEventEntry(record6)) continue;
|
|
14522
|
+
const seq = entrySeq(record6);
|
|
14523
|
+
if (previousSeq !== void 0 && seq !== void 0 && seq > previousSeq + 1) {
|
|
14524
|
+
for (let fillerSeq = previousSeq + 1; fillerSeq < seq; fillerSeq += 1) {
|
|
14525
|
+
records.push(createLegacyGapRecord(fillerSeq, record6));
|
|
14526
|
+
}
|
|
14527
|
+
}
|
|
14528
|
+
records.push(normalizeEntry(record6));
|
|
14529
|
+
if (seq !== void 0) previousSeq = seq;
|
|
14530
|
+
}
|
|
14531
|
+
return records;
|
|
14532
|
+
}
|
|
14533
|
+
function normalizeEntry(value) {
|
|
14534
|
+
if (!isEventEntry(value)) return value;
|
|
14535
|
+
return { ...value, event: normalizeEvent(value.event) };
|
|
14536
|
+
}
|
|
14537
|
+
function entrySeq(value) {
|
|
14538
|
+
if (!isEventEntry(value)) return void 0;
|
|
14539
|
+
return isEventSeq(value.event.seq) ? value.event.seq : void 0;
|
|
14540
|
+
}
|
|
14541
|
+
function createLegacyGapRecord(seq, nextRecord) {
|
|
14542
|
+
return {
|
|
14543
|
+
type: "event",
|
|
14544
|
+
event: {
|
|
14545
|
+
type: "legacy/session-gap",
|
|
14546
|
+
seq,
|
|
14547
|
+
time: eventTime(nextRecord),
|
|
14548
|
+
ignorable: true,
|
|
14549
|
+
data: {}
|
|
14550
|
+
}
|
|
14551
|
+
};
|
|
14552
|
+
}
|
|
14553
|
+
function eventTime(value) {
|
|
14554
|
+
if (!isEventEntry(value)) return 0;
|
|
14555
|
+
return typeof value.event.time === "number" && Number.isSafeInteger(value.event.time) ? value.event.time : 0;
|
|
14556
|
+
}
|
|
14557
|
+
function isEventEntry(value) {
|
|
14558
|
+
return isRecord3(value) && value.type === "event" && isRecord3(value.event);
|
|
14559
|
+
}
|
|
14560
|
+
function normalizeHeader(value) {
|
|
14561
|
+
if (!isRecord3(value)) return value;
|
|
14562
|
+
const next = {
|
|
14563
|
+
...value,
|
|
14564
|
+
version: 3,
|
|
14565
|
+
...value.delegationDepth === void 0 ? { delegationDepth: 0 } : {}
|
|
14566
|
+
};
|
|
14567
|
+
return next.agentPreset === "code" ? { ...next, agentPreset: "ptc" } : next;
|
|
14568
|
+
}
|
|
14569
|
+
function normalizeEvent(value) {
|
|
14570
|
+
if (!isRecord3(value)) return value;
|
|
14571
|
+
let next = value;
|
|
14572
|
+
const type = normalizeEventType(value.type);
|
|
14573
|
+
if (type !== value.type) next = { ...next, type };
|
|
14574
|
+
if (type === "assistant/message" && Object.hasOwn(next, "sourceEventSeqs")) {
|
|
14575
|
+
const { sourceEventSeqs: _sourceEventSeqs, ...rest } = next;
|
|
14576
|
+
next = rest;
|
|
14577
|
+
}
|
|
14578
|
+
const data = normalizeEventData(type, next.data);
|
|
14579
|
+
if (data !== next.data) next = { ...next, data };
|
|
14580
|
+
const surfaceOp = normalizeSurfaceOp(next.surfaceOp);
|
|
14581
|
+
if (surfaceOp !== next.surfaceOp) next = { ...next, surfaceOp };
|
|
14582
|
+
return next;
|
|
14583
|
+
}
|
|
14584
|
+
function normalizeEventType(value) {
|
|
14585
|
+
if (value === "tool/code-dispatch-start") return "tool/ptc-dispatch-start";
|
|
14586
|
+
if (value === "tool/code-dispatch") return "tool/ptc-dispatch";
|
|
14587
|
+
return value;
|
|
14588
|
+
}
|
|
14589
|
+
function normalizeEventData(type, value) {
|
|
14590
|
+
if (!isRecord3(value)) return value;
|
|
14591
|
+
if (type === "request/header") return normalizeRequestHeaderData(value);
|
|
14592
|
+
if (type === "agent-preset/selected" && value.agentPreset === "code") return { ...value, agentPreset: "ptc" };
|
|
14593
|
+
if (type === "user/message") return normalizeMessage(value);
|
|
14594
|
+
if (type === "agent/inbox/spliced" && Array.isArray(value.inserted)) {
|
|
14595
|
+
return { ...value, inserted: value.inserted.map((item) => normalizeMessage(item)) };
|
|
14596
|
+
}
|
|
14597
|
+
if (type === "session/title-llm-request" && Array.isArray(value.messages)) {
|
|
14598
|
+
return { ...value, messages: value.messages.map((item) => normalizeMessage(item)) };
|
|
14599
|
+
}
|
|
14600
|
+
return value;
|
|
14601
|
+
}
|
|
14602
|
+
function normalizeRequestHeaderData(value) {
|
|
14603
|
+
if (!isRecord3(value.header)) return value;
|
|
14604
|
+
const header = normalizeRequestHeader(value.header);
|
|
14605
|
+
return header === value.header ? value : { ...value, header };
|
|
14606
|
+
}
|
|
14607
|
+
function normalizeRequestHeader(value) {
|
|
14608
|
+
let changed = false;
|
|
14609
|
+
const next = {};
|
|
14610
|
+
for (const [key, field] of Object.entries(value)) {
|
|
14611
|
+
if (key === "system") {
|
|
14612
|
+
changed = true;
|
|
14613
|
+
continue;
|
|
14614
|
+
}
|
|
14615
|
+
if (key === "tools" && Array.isArray(field) && field.length === 0) {
|
|
14616
|
+
changed = true;
|
|
14617
|
+
continue;
|
|
14618
|
+
}
|
|
14619
|
+
if (key === "adapterDefaults" && isRecord3(field) && Object.keys(field).length === 0) {
|
|
14620
|
+
changed = true;
|
|
14621
|
+
continue;
|
|
14622
|
+
}
|
|
14623
|
+
next[key] = field;
|
|
14624
|
+
}
|
|
14625
|
+
return changed ? next : value;
|
|
14626
|
+
}
|
|
14627
|
+
function normalizeMessage(value) {
|
|
14628
|
+
if (!isRecord3(value) || !isRecord3(value.source)) return value;
|
|
14629
|
+
if (value.source.kind !== "plugin" || value.source.plugin !== "tools-code-mode") return value;
|
|
14630
|
+
return { ...value, source: { ...value.source, plugin: "tools-ptc" } };
|
|
14631
|
+
}
|
|
14632
|
+
function normalizeSurfaceOp(value) {
|
|
14633
|
+
if (!isRecord3(value) || value.op !== "replace") return value;
|
|
14634
|
+
const { start, end, ...rest } = value;
|
|
14635
|
+
if (start === void 0 && end === void 0) return value;
|
|
14636
|
+
return {
|
|
14637
|
+
...rest,
|
|
14638
|
+
op: "replace",
|
|
14639
|
+
...start === void 0 ? {} : { startSeq: start },
|
|
14640
|
+
...end === void 0 ? {} : { endSeq: end }
|
|
14641
|
+
};
|
|
14642
|
+
}
|
|
14643
|
+
function isRecord3(value) {
|
|
14644
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
14645
|
+
}
|
|
14646
|
+
function isEventSeq(value) {
|
|
14647
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 && !Object.is(value, -0);
|
|
14648
|
+
}
|
|
14649
|
+
|
|
14313
14650
|
// src/remote-typert-gateway.ts
|
|
14314
14651
|
var DIRECT_REMOTE_CALL_BYTES2 = 2 * 1024 * 1024;
|
|
14315
14652
|
var RemoteTypertGateway2 = class {
|
|
14316
|
-
constructor(client) {
|
|
14653
|
+
constructor(client, compatibility) {
|
|
14317
14654
|
this.client = client;
|
|
14655
|
+
this.compatibility = compatibility;
|
|
14318
14656
|
}
|
|
14319
14657
|
async invoke(request) {
|
|
14320
14658
|
const result = await this.dispatch(
|
|
@@ -14339,7 +14677,11 @@ var RemoteTypertGateway2 = class {
|
|
|
14339
14677
|
response = await this.callTransferred(encoded, signal);
|
|
14340
14678
|
}
|
|
14341
14679
|
}
|
|
14342
|
-
|
|
14680
|
+
const result = parseRpcResult(response);
|
|
14681
|
+
if (result.ok && this.compatibility === "legacy-to-v3") {
|
|
14682
|
+
return { ...result, value: normalizeLegacySessionGatewayValue(endpoint, result.value) };
|
|
14683
|
+
}
|
|
14684
|
+
return result;
|
|
14343
14685
|
}
|
|
14344
14686
|
async open(endpoint, payload, signal) {
|
|
14345
14687
|
const streamId = uuidV7();
|
|
@@ -14358,11 +14700,13 @@ var RemoteTypertGateway2 = class {
|
|
|
14358
14700
|
unsubscribeClose();
|
|
14359
14701
|
throw error;
|
|
14360
14702
|
}
|
|
14361
|
-
return this.iterate(streamId, queue, unsubscribe, unsubscribeClose, signal, onAbort);
|
|
14703
|
+
return this.iterate(streamId, endpoint, queue, unsubscribe, unsubscribeClose, signal, onAbort);
|
|
14362
14704
|
}
|
|
14363
|
-
async *iterate(streamId, queue, unsubscribe, unsubscribeClose, signal, onAbort) {
|
|
14705
|
+
async *iterate(streamId, endpoint, queue, unsubscribe, unsubscribeClose, signal, onAbort) {
|
|
14364
14706
|
try {
|
|
14365
|
-
|
|
14707
|
+
for await (const value of queue) {
|
|
14708
|
+
yield this.compatibility === "legacy-to-v3" ? normalizeLegacySessionGatewayValue(endpoint, value) : value;
|
|
14709
|
+
}
|
|
14366
14710
|
} finally {
|
|
14367
14711
|
signal.removeEventListener("abort", onAbort);
|
|
14368
14712
|
unsubscribe();
|
|
@@ -14482,16 +14826,16 @@ function routeStreamEvent2(event, streamId, queue) {
|
|
|
14482
14826
|
queue.fail(remoteFailure({
|
|
14483
14827
|
code: typeof failure2?.code === "string" ? failure2.code : "internal",
|
|
14484
14828
|
message: typeof failure2?.message === "string" ? failure2.message : "The remote Harness stream failed.",
|
|
14485
|
-
details:
|
|
14829
|
+
details: isRecord4(failure2?.details) ? failure2.details : {}
|
|
14486
14830
|
}));
|
|
14487
14831
|
} else {
|
|
14488
14832
|
queue.close();
|
|
14489
14833
|
}
|
|
14490
14834
|
}
|
|
14491
14835
|
function parseRpcResult(value) {
|
|
14492
|
-
if (!
|
|
14836
|
+
if (!isRecord4(value)) throw new Error("The remote Host returned an invalid Gateway result.");
|
|
14493
14837
|
if (value.ok === true) return Object.hasOwn(value, "value") ? { ok: true, value: value.value } : { ok: true };
|
|
14494
|
-
if (value.ok !== false || !
|
|
14838
|
+
if (value.ok !== false || !isRecord4(value.error) || typeof value.error.code !== "string" || typeof value.error.message !== "string" || !isRecord4(value.error.details)) {
|
|
14495
14839
|
throw new Error("The remote Host returned an invalid Gateway failure.");
|
|
14496
14840
|
}
|
|
14497
14841
|
return {
|
|
@@ -14525,7 +14869,7 @@ function base64ToBytes3(value) {
|
|
|
14525
14869
|
if (bytesToBase643(bytes) !== value) throw new Error("The remote Host returned non-canonical Harness Remote transfer data.");
|
|
14526
14870
|
return bytes;
|
|
14527
14871
|
}
|
|
14528
|
-
function
|
|
14872
|
+
function isRecord4(value) {
|
|
14529
14873
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
14530
14874
|
}
|
|
14531
14875
|
function hasErrorCode(error, code) {
|
|
@@ -15446,7 +15790,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15446
15790
|
this.broadcastRcHost({ type: "host/session-status", sessionId, running: args[1] });
|
|
15447
15791
|
} else if (event === "api-session/removed" && sessionId !== void 0) {
|
|
15448
15792
|
this.broadcastRcHost({ type: "host/session-removed", sessionId });
|
|
15449
|
-
} else if (event === "api-session/added" &&
|
|
15793
|
+
} else if (event === "api-session/added" && isRecord5(args[0])) {
|
|
15450
15794
|
const summary = args[0];
|
|
15451
15795
|
this.broadcastRcHost({
|
|
15452
15796
|
type: "host/session-added",
|
|
@@ -15831,7 +16175,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15831
16175
|
}
|
|
15832
16176
|
createApiProxy() {
|
|
15833
16177
|
const call = (endpoint) => async (request, signal) => {
|
|
15834
|
-
const payload = endpoint === "session.prompt" &&
|
|
16178
|
+
const payload = endpoint === "session.prompt" && isRecord5(request.payload) ? { ...request.payload, requestId: String(request.rpcId) } : request.payload;
|
|
15835
16179
|
const result = await this.dispatch(rcEndpoint(endpoint), { args: { request: payload } }, signal ?? new AbortController().signal);
|
|
15836
16180
|
return {
|
|
15837
16181
|
rpcId: request.rpcId,
|
|
@@ -15915,8 +16259,8 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15915
16259
|
queue.close();
|
|
15916
16260
|
}
|
|
15917
16261
|
}
|
|
15918
|
-
broadcastRcMux(payload,
|
|
15919
|
-
for (const queue of this.rcMuxStreams) queue.push({ rpcId, payload });
|
|
16262
|
+
broadcastRcMux(payload, rpcId2 = `codex-mux:${Date.now()}:${Math.random()}`) {
|
|
16263
|
+
for (const queue of this.rcMuxStreams) queue.push({ rpcId: rpcId2, payload });
|
|
15920
16264
|
}
|
|
15921
16265
|
broadcastRcHost(payload) {
|
|
15922
16266
|
const frame = { rpcId: `codex-host:${Date.now()}:${Math.random()}`, payload };
|
|
@@ -16356,7 +16700,7 @@ function collectImageBlocks(value, output = []) {
|
|
|
16356
16700
|
for (const item of value) collectImageBlocks(item, output);
|
|
16357
16701
|
return output;
|
|
16358
16702
|
}
|
|
16359
|
-
if (!
|
|
16703
|
+
if (!isRecord5(value)) return output;
|
|
16360
16704
|
if (value.type === "image") output.push(value);
|
|
16361
16705
|
for (const [key, child] of Object.entries(value)) {
|
|
16362
16706
|
if (key === "attachment") continue;
|
|
@@ -16686,7 +17030,7 @@ function codexPromptInput(content) {
|
|
|
16686
17030
|
if (content.length === 0 || content.length > MAX_CODEX_PROMPT_PARTS) return void 0;
|
|
16687
17031
|
const input2 = [];
|
|
16688
17032
|
for (const value of content) {
|
|
16689
|
-
if (!
|
|
17033
|
+
if (!isRecord5(value)) return void 0;
|
|
16690
17034
|
if (value.type === "text") {
|
|
16691
17035
|
if (typeof value.text !== "string" || value.text.length === 0 || value.text.length > MAX_CODEX_PROMPT_TEXT) return void 0;
|
|
16692
17036
|
input2.push({ type: "text", text: value.text });
|
|
@@ -16939,12 +17283,12 @@ function errorCode(error) {
|
|
|
16939
17283
|
return "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
16940
17284
|
}
|
|
16941
17285
|
function errorDetails(error) {
|
|
16942
|
-
return "details" in error &&
|
|
17286
|
+
return "details" in error && isRecord5(error.details) ? error.details : {};
|
|
16943
17287
|
}
|
|
16944
17288
|
function record2(value) {
|
|
16945
|
-
return
|
|
17289
|
+
return isRecord5(value) ? value : {};
|
|
16946
17290
|
}
|
|
16947
|
-
function
|
|
17291
|
+
function isRecord5(value) {
|
|
16948
17292
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16949
17293
|
}
|
|
16950
17294
|
function array(value) {
|
|
@@ -17087,7 +17431,8 @@ var Config = s.object({
|
|
|
17087
17431
|
codex: s.object({
|
|
17088
17432
|
enabled: s.boolean(),
|
|
17089
17433
|
binary: s.string()
|
|
17090
|
-
})
|
|
17434
|
+
}),
|
|
17435
|
+
acp: s.object({ enabled: s.boolean(), backends: s.array(s.object({ id: s.string(), enabled: s.boolean(), command: s.string(), args: s.array(s.string()), cwd: s.string() })) })
|
|
17091
17436
|
});
|
|
17092
17437
|
var reconnectSchema = external_exports.union([
|
|
17093
17438
|
external_exports.boolean(),
|
|
@@ -17108,7 +17453,8 @@ var configSchema = external_exports.object({
|
|
|
17108
17453
|
codex: external_exports.object({
|
|
17109
17454
|
enabled: external_exports.boolean().optional(),
|
|
17110
17455
|
binary: external_exports.string().trim().min(1).max(4096).optional()
|
|
17111
|
-
}).strict().optional()
|
|
17456
|
+
}).strict().optional(),
|
|
17457
|
+
acp: external_exports.object({ enabled: external_exports.boolean().optional(), backends: external_exports.array(external_exports.object({ id: external_exports.string().trim().regex(/^[a-z0-9][a-z0-9._-]{0,31}$/i), enabled: external_exports.boolean().optional(), command: external_exports.string().trim().min(1).max(4096).optional(), args: external_exports.array(external_exports.string().max(4096)).max(32).optional(), cwd: external_exports.string().max(4096).optional() }).strict()).max(12).optional(), backend: external_exports.string().trim().regex(/^[a-z0-9][a-z0-9._-]{0,31}$/i).optional(), command: external_exports.string().trim().min(1).max(4096).optional(), args: external_exports.array(external_exports.string().max(4096)).max(32).optional(), cwd: external_exports.string().max(4096).optional() }).strict().optional()
|
|
17112
17458
|
}).strict();
|
|
17113
17459
|
function resolveConfig(input2 = {}, env = process.env) {
|
|
17114
17460
|
const parsed = configSchema.parse(input2);
|
|
@@ -17136,7 +17482,12 @@ function resolveConfig(input2 = {}, env = process.env) {
|
|
|
17136
17482
|
codex: {
|
|
17137
17483
|
enabled: parsed.codex?.enabled ?? true,
|
|
17138
17484
|
binary: parsed.codex?.binary ?? "codex"
|
|
17139
|
-
}
|
|
17485
|
+
},
|
|
17486
|
+
acp: { enabled: parsed.acp?.enabled ?? true, backends: [.../* @__PURE__ */ new Set(["codex", "cursor", "kimi", ...parsed.acp?.backends?.map((item) => item.id) ?? []])].map((id2) => {
|
|
17487
|
+
const d = parsed.acp?.backends?.find((x) => x.id === id2);
|
|
17488
|
+
const legacy = parsed.acp?.backend === id2 ? parsed.acp : void 0;
|
|
17489
|
+
return { id: id2, enabled: d?.enabled ?? legacy?.enabled ?? true, command: d?.command ?? legacy?.command ?? { codex: "codex", cursor: "agent", kimi: "kimi" }[id2] ?? id2, args: d?.args ?? legacy?.args ?? ["acp"], ...d?.cwd ?? legacy?.cwd ? { cwd: d?.cwd ?? legacy?.cwd } : {} };
|
|
17490
|
+
}) }
|
|
17140
17491
|
};
|
|
17141
17492
|
}
|
|
17142
17493
|
function normalizeServerUrl(value) {
|
|
@@ -17158,7 +17509,7 @@ function normalizeServerUrl(value) {
|
|
|
17158
17509
|
}
|
|
17159
17510
|
|
|
17160
17511
|
// src/version.ts
|
|
17161
|
-
var PLUGIN_VERSION = "0.4.
|
|
17512
|
+
var PLUGIN_VERSION = "0.4.14";
|
|
17162
17513
|
|
|
17163
17514
|
// src/server-api.ts
|
|
17164
17515
|
var TERMINAL_CONTROL_CHARACTERS = /[\u0000-\u001f\u007f-\u009f]/u;
|
|
@@ -17677,7 +18028,7 @@ var TypertGatewaySwitch = class {
|
|
|
17677
18028
|
if (normalized !== void 0) return normalized;
|
|
17678
18029
|
const source = error instanceof Error ? error : new Error("The Harness Gateway rejected the request.");
|
|
17679
18030
|
const code = "code" in source && typeof source.code === "string" ? source.code : "internal";
|
|
17680
|
-
const details = "details" in source &&
|
|
18031
|
+
const details = "details" in source && isRecord6(source.details) ? source.details : {};
|
|
17681
18032
|
return { code, message: source.message, details };
|
|
17682
18033
|
}
|
|
17683
18034
|
};
|
|
@@ -17686,7 +18037,7 @@ function requestFromCarrier(endpoint, payload, signal) {
|
|
|
17686
18037
|
if (segments.length !== 2 || segments.some((segment) => segment.length === 0)) {
|
|
17687
18038
|
throw new Error("The Harness Gateway endpoint is invalid.");
|
|
17688
18039
|
}
|
|
17689
|
-
if (!
|
|
18040
|
+
if (!isRecord6(payload) || !isRecord6(payload.args)) {
|
|
17690
18041
|
throw new Error("The Harness Gateway payload is invalid.");
|
|
17691
18042
|
}
|
|
17692
18043
|
return { namespace: segments[0], method: segments[1], args: payload.args, signal };
|
|
@@ -17701,7 +18052,7 @@ function isLocalOnlyEndpoint(endpoint) {
|
|
|
17701
18052
|
function isRemoteCommandMethod(method) {
|
|
17702
18053
|
return REMOTE_COMMAND_METHODS.includes(method);
|
|
17703
18054
|
}
|
|
17704
|
-
function
|
|
18055
|
+
function isRecord6(value) {
|
|
17705
18056
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17706
18057
|
}
|
|
17707
18058
|
|
|
@@ -18805,10 +19156,8 @@ var ClientModeRuntime = class {
|
|
|
18805
19156
|
fingerprint: this.identity.fingerprint
|
|
18806
19157
|
});
|
|
18807
19158
|
}
|
|
18808
|
-
registerControl(connection) {
|
|
18809
|
-
return connection
|
|
18810
|
-
authority: "loopback"
|
|
18811
|
-
});
|
|
19159
|
+
registerControl(connection, webServer) {
|
|
19160
|
+
return registerControlRoute(connection, (endpoint, payload, signal) => this.handleControl(endpoint, payload, signal), webServer);
|
|
18812
19161
|
}
|
|
18813
19162
|
status() {
|
|
18814
19163
|
const targetStatus = this.gatewaySwitch.supportsCarrier() ? this.gatewaySwitch.status() : this.proxySwitch?.status() ?? this.gatewaySwitch.status();
|
|
@@ -18989,9 +19338,9 @@ var ClientModeRuntime = class {
|
|
|
18989
19338
|
async openRemoteWorkspace(targetDeviceId, path, signal) {
|
|
18990
19339
|
if (path.trim() === "") throw new ClientModeError("INVALID_MESSAGE", "A remote working directory is required.");
|
|
18991
19340
|
const remote = await this.ensureConnected(targetDeviceId, signal);
|
|
18992
|
-
this.
|
|
19341
|
+
const transport = this.selectHarnessRemoteTransport(remote);
|
|
18993
19342
|
let workspace;
|
|
18994
|
-
if (
|
|
19343
|
+
if (transport === "remoteGateway") {
|
|
18995
19344
|
workspace = await new RemoteTypertGateway2(remote.client).invoke({
|
|
18996
19345
|
namespace: "workspace",
|
|
18997
19346
|
method: "create",
|
|
@@ -19007,7 +19356,7 @@ var ClientModeRuntime = class {
|
|
|
19007
19356
|
workspace = unwrapNativeResult(response);
|
|
19008
19357
|
}
|
|
19009
19358
|
await this.closeCodexVirtual();
|
|
19010
|
-
this.selectRemoteTarget(remote);
|
|
19359
|
+
this.selectRemoteTarget(remote, transport);
|
|
19011
19360
|
const workspaceId = workspaceRecordId(workspace.workspace);
|
|
19012
19361
|
this.pendingWorkspaceSelection = { targetDeviceId: remote.target.deviceId, workspaceId };
|
|
19013
19362
|
this.logger.info("Remote workspace opened", { targetDeviceId: shortId(remote.target.deviceId) });
|
|
@@ -19027,7 +19376,7 @@ var ClientModeRuntime = class {
|
|
|
19027
19376
|
if (!remote.features.codex) {
|
|
19028
19377
|
throw new ClientModeError("FEATURE_NOT_SUPPORTED", "The selected Host does not provide CodeX workspaces.");
|
|
19029
19378
|
}
|
|
19030
|
-
this.
|
|
19379
|
+
this.assertLocalHarnessCarrierAvailable();
|
|
19031
19380
|
const virtual = CodexVirtualHarness.remote(remote.client, {
|
|
19032
19381
|
deviceId: remote.target.deviceId,
|
|
19033
19382
|
name: remote.target.name
|
|
@@ -19060,7 +19409,7 @@ var ClientModeRuntime = class {
|
|
|
19060
19409
|
if (!remote.features.codex) {
|
|
19061
19410
|
throw new ClientModeError("FEATURE_NOT_SUPPORTED", "The selected Host does not provide CodeX workspaces.");
|
|
19062
19411
|
}
|
|
19063
|
-
this.
|
|
19412
|
+
this.assertLocalHarnessCarrierAvailable();
|
|
19064
19413
|
const result = record3(await new CodexRemoteClient(remote.client).request("project/create", {
|
|
19065
19414
|
name: remoteWorkspaceTitle(trimmedPath),
|
|
19066
19415
|
roots: [{ path: trimmedPath }],
|
|
@@ -19148,10 +19497,10 @@ var ClientModeRuntime = class {
|
|
|
19148
19497
|
}
|
|
19149
19498
|
}
|
|
19150
19499
|
stream.unsubscribe = remote.client.onEvent((event) => {
|
|
19151
|
-
if (event.event === "codex.app.frame" &&
|
|
19500
|
+
if (event.event === "codex.app.frame" && isRecord7(event.data) && event.data.streamId === value.streamId) {
|
|
19152
19501
|
this.appendCodexFrame(stream, event.data);
|
|
19153
19502
|
}
|
|
19154
|
-
if (event.event === "codex.app.stream.closed" &&
|
|
19503
|
+
if (event.event === "codex.app.stream.closed" && isRecord7(event.data) && event.data.streamId === value.streamId) {
|
|
19155
19504
|
stream.closed = typeof event.data.reason === "string" ? event.data.reason : "closed";
|
|
19156
19505
|
stream.wake();
|
|
19157
19506
|
}
|
|
@@ -19178,7 +19527,7 @@ var ClientModeRuntime = class {
|
|
|
19178
19527
|
stream.wake();
|
|
19179
19528
|
};
|
|
19180
19529
|
appendCodexFrame(stream, data) {
|
|
19181
|
-
if (!
|
|
19530
|
+
if (!isRecord7(data) || !isRecord7(data.frame) || typeof data.frame.method !== "string") return;
|
|
19182
19531
|
if (stream.frames.length >= 256) {
|
|
19183
19532
|
stream.closed = "overflow";
|
|
19184
19533
|
} else {
|
|
@@ -19235,18 +19584,25 @@ var ClientModeRuntime = class {
|
|
|
19235
19584
|
await stream.close();
|
|
19236
19585
|
}));
|
|
19237
19586
|
}
|
|
19238
|
-
selectRemoteTarget(remote) {
|
|
19587
|
+
selectRemoteTarget(remote, transport = this.selectHarnessRemoteTransport(remote)) {
|
|
19239
19588
|
const target = { deviceId: remote.target.deviceId, name: remote.target.name };
|
|
19240
|
-
if (
|
|
19241
|
-
this.gatewaySwitch.selectRemote(
|
|
19589
|
+
if (transport === "remoteGateway") {
|
|
19590
|
+
this.gatewaySwitch.selectRemote(this.remoteTypertGateway(remote), void 0, target);
|
|
19242
19591
|
return;
|
|
19243
19592
|
}
|
|
19244
|
-
this.proxySwitch
|
|
19593
|
+
this.proxySwitch?.selectRemote(new RemoteHarnessApiProxy(remote.client).api, target);
|
|
19245
19594
|
this.gatewaySwitch.selectRemote((request) => invokeRemoteCommand(remote.client, request), {
|
|
19246
19595
|
execute: true,
|
|
19247
19596
|
list: remote.features.commandList
|
|
19248
19597
|
}, target);
|
|
19249
19598
|
}
|
|
19599
|
+
remoteTypertGateway(remote) {
|
|
19600
|
+
const localSessionGeneration = harnessSessionGeneration(this.host?.localHarnessVersion?.());
|
|
19601
|
+
return new RemoteTypertGateway2(
|
|
19602
|
+
remote.client,
|
|
19603
|
+
localSessionGeneration === "v3" && remote.features.sessionFormat !== 3 ? "legacy-to-v3" : void 0
|
|
19604
|
+
);
|
|
19605
|
+
}
|
|
19250
19606
|
selectCodexTarget(virtual, remote) {
|
|
19251
19607
|
const target = { deviceId: remote.target.deviceId, name: remote.target.name };
|
|
19252
19608
|
if (this.gatewaySwitch.supportsCarrier()) {
|
|
@@ -19262,20 +19618,29 @@ var ClientModeRuntime = class {
|
|
|
19262
19618
|
await virtual?.close();
|
|
19263
19619
|
}
|
|
19264
19620
|
assertRemoteCompatible(remote) {
|
|
19621
|
+
this.selectHarnessRemoteTransport(remote);
|
|
19622
|
+
}
|
|
19623
|
+
selectHarnessRemoteTransport(remote) {
|
|
19265
19624
|
const localRemoteGateway = this.gatewaySwitch.supportsCarrier();
|
|
19625
|
+
const localSessionGeneration = harnessSessionGeneration(this.host?.localHarnessVersion?.());
|
|
19266
19626
|
if (localRemoteGateway && remote.features.remoteGateway) {
|
|
19267
|
-
|
|
19268
|
-
const remoteSessionGeneration = remote.features.sessionFormat === 3 ? "v3" : "legacy";
|
|
19269
|
-
if (localSessionGeneration === remoteSessionGeneration) return;
|
|
19627
|
+
if (localSessionGeneration === "v3" || remote.features.sessionFormat !== 3) return "remoteGateway";
|
|
19270
19628
|
throw new ClientModeError(
|
|
19271
19629
|
"HARNESS_VERSION_INCOMPATIBLE",
|
|
19272
|
-
|
|
19630
|
+
"The selected Host uses Harness Session V3, but this Client uses the legacy Typert Remote session format."
|
|
19273
19631
|
);
|
|
19274
19632
|
}
|
|
19275
|
-
if (
|
|
19633
|
+
if (this.proxySwitch !== void 0 && remote.features.apiProxy) return "apiProxy";
|
|
19634
|
+
throw new ClientModeError(
|
|
19635
|
+
"HARNESS_VERSION_INCOMPATIBLE",
|
|
19636
|
+
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."
|
|
19637
|
+
);
|
|
19638
|
+
}
|
|
19639
|
+
assertLocalHarnessCarrierAvailable() {
|
|
19640
|
+
if (this.gatewaySwitch.supportsCarrier() || this.proxySwitch !== void 0) return;
|
|
19276
19641
|
throw new ClientModeError(
|
|
19277
19642
|
"HARNESS_VERSION_INCOMPATIBLE",
|
|
19278
|
-
|
|
19643
|
+
"This Client does not provide a compatible Harness carrier for the selected remote workspace."
|
|
19279
19644
|
);
|
|
19280
19645
|
}
|
|
19281
19646
|
async connect(targetDeviceId, signal) {
|
|
@@ -19654,20 +20019,20 @@ function record3(value) {
|
|
|
19654
20019
|
}
|
|
19655
20020
|
return value;
|
|
19656
20021
|
}
|
|
19657
|
-
function
|
|
20022
|
+
function isRecord7(value) {
|
|
19658
20023
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19659
20024
|
}
|
|
19660
20025
|
function ok2(value) {
|
|
19661
20026
|
return { ok: true, value };
|
|
19662
20027
|
}
|
|
19663
20028
|
async function invokeRemoteCommand(client, request) {
|
|
19664
|
-
const
|
|
20029
|
+
const rpcId2 = uuidV7();
|
|
19665
20030
|
const response = await client.rpc("harness.api.call", {
|
|
19666
20031
|
method: `${request.namespace}.${request.method}`,
|
|
19667
|
-
rpcId,
|
|
20032
|
+
rpcId: rpcId2,
|
|
19668
20033
|
payload: request.args
|
|
19669
20034
|
}, request.signal);
|
|
19670
|
-
if (response.rpcId !==
|
|
20035
|
+
if (response.rpcId !== rpcId2) {
|
|
19671
20036
|
throw new ClientModeError("INVALID_MESSAGE", "The remote Host returned an invalid command response.");
|
|
19672
20037
|
}
|
|
19673
20038
|
return unwrapNativeResult(response);
|
|
@@ -19679,11 +20044,11 @@ async function readRemoteWorkspaceBaseline(gateway, signal) {
|
|
|
19679
20044
|
const iterator = source[Symbol.asyncIterator]();
|
|
19680
20045
|
try {
|
|
19681
20046
|
const first = await iterator.next();
|
|
19682
|
-
if (first.done || !
|
|
20047
|
+
if (first.done || !isRecord7(first.value) || first.value.type !== "baseline" || !isRecord7(first.value.value) || !Array.isArray(first.value.value.items)) {
|
|
19683
20048
|
throw new ClientModeError("INVALID_MESSAGE", "The remote Host returned an invalid Workspace baseline.");
|
|
19684
20049
|
}
|
|
19685
20050
|
return first.value.value.items.map((item) => {
|
|
19686
|
-
if (!
|
|
20051
|
+
if (!isRecord7(item) || typeof item.workspaceId !== "string" || typeof item.path !== "string" || typeof item.title !== "string") {
|
|
19687
20052
|
throw new ClientModeError("INVALID_MESSAGE", "The remote Host returned an invalid Workspace row.");
|
|
19688
20053
|
}
|
|
19689
20054
|
return { workspaceId: item.workspaceId, path: item.path, title: item.title };
|
|
@@ -19748,19 +20113,20 @@ async function probeRemoteHostFeatures(client, clientVersion) {
|
|
|
19748
20113
|
if (error instanceof Error && "code" in error && error.code === "METHOD_NOT_FOUND") return fallback;
|
|
19749
20114
|
throw error;
|
|
19750
20115
|
}
|
|
19751
|
-
if (!
|
|
20116
|
+
if (!isRecord7(value) || !Array.isArray(value.capabilities) || value.capabilities.some((capability) => typeof capability !== "string")) {
|
|
19752
20117
|
throw new ClientModeError("INVALID_MESSAGE", "The remote Host returned invalid transport capabilities.");
|
|
19753
20118
|
}
|
|
19754
20119
|
const capabilities = new Set(value.capabilities);
|
|
19755
20120
|
const apiProxy = capabilities.has("harness.api.v1");
|
|
19756
20121
|
const remoteV1 = capabilities.has("harness.remote.v1");
|
|
19757
20122
|
const remoteV3 = capabilities.has("harness.remote.v3");
|
|
20123
|
+
const codex = capabilities.has("codex.appserver.v1");
|
|
19758
20124
|
if (remoteV1 && remoteV3) {
|
|
19759
20125
|
throw new ClientModeError("INVALID_MESSAGE", "The remote Host advertised conflicting Harness Session formats.");
|
|
19760
20126
|
}
|
|
19761
20127
|
const sessionFormat = remoteV3 ? 3 : void 0;
|
|
19762
20128
|
const remoteGateway = remoteV3 || remoteV1;
|
|
19763
|
-
if (!apiProxy && !remoteGateway) {
|
|
20129
|
+
if (!apiProxy && !remoteGateway && !codex) {
|
|
19764
20130
|
throw new ClientModeError("FEATURE_NOT_SUPPORTED", "The remote Host exposes no supported Harness transport.");
|
|
19765
20131
|
}
|
|
19766
20132
|
return {
|
|
@@ -19769,7 +20135,7 @@ async function probeRemoteHostFeatures(client, clientVersion) {
|
|
|
19769
20135
|
apiProxy,
|
|
19770
20136
|
remoteGateway,
|
|
19771
20137
|
...sessionFormat === void 0 ? {} : { sessionFormat },
|
|
19772
|
-
codex
|
|
20138
|
+
codex
|
|
19773
20139
|
};
|
|
19774
20140
|
}
|
|
19775
20141
|
async function waitForCodexFrames(stream, signal) {
|
|
@@ -19832,6 +20198,7 @@ function iceServersForAttempt(attempt, iceServers) {
|
|
|
19832
20198
|
|
|
19833
20199
|
// src/control-runtime.ts
|
|
19834
20200
|
import { hostname as hostname2 } from "node:os";
|
|
20201
|
+
import { execFileSync } from "node:child_process";
|
|
19835
20202
|
|
|
19836
20203
|
// src/identity-store.ts
|
|
19837
20204
|
import { createHash } from "node:crypto";
|
|
@@ -20086,10 +20453,8 @@ var PluginControlRuntime = class {
|
|
|
20086
20453
|
this.client = client;
|
|
20087
20454
|
this.host = host;
|
|
20088
20455
|
}
|
|
20089
|
-
register(connection) {
|
|
20090
|
-
return connection
|
|
20091
|
-
authority: "loopback"
|
|
20092
|
-
});
|
|
20456
|
+
register(connection, webServer) {
|
|
20457
|
+
return registerControlRoute(connection, (endpoint, payload, signal) => this.handle(endpoint, payload, signal), webServer);
|
|
20093
20458
|
}
|
|
20094
20459
|
async handle(endpoint, payload, signal) {
|
|
20095
20460
|
try {
|
|
@@ -20098,6 +20463,9 @@ var PluginControlRuntime = class {
|
|
|
20098
20463
|
if (endpoint === "settings.server.set") return ok3(await this.setServer(payload));
|
|
20099
20464
|
if (endpoint === "settings.role.set") return ok3(await this.setRole(payload));
|
|
20100
20465
|
if (endpoint === "settings.codex.set") return ok3(await this.setCodex(payload));
|
|
20466
|
+
if (endpoint === "settings.acp.set") return ok3(await this.setAcp(payload));
|
|
20467
|
+
if (endpoint === "settings.acp.add") return ok3(await this.addAcp(payload));
|
|
20468
|
+
if (endpoint === "settings.acp.remove") return ok3(await this.removeAcp(payload));
|
|
20101
20469
|
if (endpoint === "settings.logout") return ok3(await this.logout());
|
|
20102
20470
|
if (endpoint === "host.reconnect") {
|
|
20103
20471
|
if (this.host === void 0) throw new ClientModeError("METHOD_NOT_ALLOWED", "This plugin is not running as a Host.");
|
|
@@ -20209,6 +20577,37 @@ var PluginControlRuntime = class {
|
|
|
20209
20577
|
await this.settings.replace(editableConfig(next));
|
|
20210
20578
|
return this.settingsView();
|
|
20211
20579
|
}
|
|
20580
|
+
async setAcp(payload) {
|
|
20581
|
+
if (this.settings === void 0) throw new ClientModeError("SETTINGS_UNAVAILABLE", "DSH user settings are unavailable in this profile.");
|
|
20582
|
+
const value = record4(payload);
|
|
20583
|
+
if (typeof value.backend !== "string" || typeof value.enabled !== "boolean") throw new ClientModeError("INVALID_MESSAGE", "ACP backend and enabled are required.");
|
|
20584
|
+
const current = resolveConfig(this.settings.get());
|
|
20585
|
+
const backends = current.acp?.backends.map((item) => item.id === value.backend ? { ...item, enabled: value.enabled } : item) ?? [];
|
|
20586
|
+
await this.settings.replace({ ...editableConfig(current), acp: { enabled: current.acp?.enabled ?? true, backends } });
|
|
20587
|
+
return this.settingsView();
|
|
20588
|
+
}
|
|
20589
|
+
async addAcp(payload) {
|
|
20590
|
+
if (this.settings === void 0) throw new ClientModeError("SETTINGS_UNAVAILABLE", "DSH user settings are unavailable in this profile.");
|
|
20591
|
+
const value = record4(payload);
|
|
20592
|
+
if (typeof value.id !== "string" || typeof value.command !== "string" || !Array.isArray(value.args) || !value.args.every((item) => typeof item === "string")) {
|
|
20593
|
+
throw new ClientModeError("INVALID_MESSAGE", "ACP name, command, and arguments are required.");
|
|
20594
|
+
}
|
|
20595
|
+
const current = resolveConfig(this.settings.get());
|
|
20596
|
+
if (current.acp?.backends.some((item) => item.id === value.id)) throw new ClientModeError("INVALID_MESSAGE", "ACP backend already exists.");
|
|
20597
|
+
const backends = [...current.acp?.backends ?? [], { id: value.id, command: value.command, args: value.args, enabled: false }];
|
|
20598
|
+
const next = resolveConfig({ ...editableConfig(current), acp: { enabled: current.acp?.enabled ?? true, backends } });
|
|
20599
|
+
await this.settings.replace(editableConfig(next));
|
|
20600
|
+
return this.settingsView();
|
|
20601
|
+
}
|
|
20602
|
+
async removeAcp(payload) {
|
|
20603
|
+
if (this.settings === void 0) throw new ClientModeError("SETTINGS_UNAVAILABLE", "DSH user settings are unavailable in this profile.");
|
|
20604
|
+
const id2 = record4(payload).id;
|
|
20605
|
+
if (typeof id2 !== "string" || ["codex", "cursor", "kimi"].includes(id2)) throw new ClientModeError("INVALID_MESSAGE", "Only custom ACP backends can be removed.");
|
|
20606
|
+
const current = resolveConfig(this.settings.get());
|
|
20607
|
+
const backends = (current.acp?.backends ?? []).filter((item) => item.id !== id2);
|
|
20608
|
+
await this.settings.replace(editableConfig({ ...current, acp: { enabled: current.acp?.enabled ?? true, backends } }));
|
|
20609
|
+
return this.settingsView();
|
|
20610
|
+
}
|
|
20212
20611
|
async authorizeOwnedRole(serverUrl, sourceRole, targetRole) {
|
|
20213
20612
|
const sourceDirectory = serverStorageDirectory(this.identityDirectory, serverUrl, sourceRole);
|
|
20214
20613
|
const sourceIdentity = await new IdentityStore({ directory: sourceDirectory }).loadOrCreate(hostname2());
|
|
@@ -20249,6 +20648,7 @@ var PluginControlRuntime = class {
|
|
|
20249
20648
|
writable: this.settings !== void 0,
|
|
20250
20649
|
applies: "restart",
|
|
20251
20650
|
associations,
|
|
20651
|
+
acpAvailability: Object.fromEntries((config.acp?.backends ?? []).map((item) => [item.id, commandAvailable(item.command ?? "")])),
|
|
20252
20652
|
...association === void 0 ? {} : { association }
|
|
20253
20653
|
};
|
|
20254
20654
|
}
|
|
@@ -20285,6 +20685,14 @@ var PluginControlRuntime = class {
|
|
|
20285
20685
|
};
|
|
20286
20686
|
}
|
|
20287
20687
|
};
|
|
20688
|
+
function commandAvailable(command) {
|
|
20689
|
+
try {
|
|
20690
|
+
execFileSync(process.platform === "win32" ? "where" : "which", [command], { stdio: "ignore" });
|
|
20691
|
+
return true;
|
|
20692
|
+
} catch {
|
|
20693
|
+
return false;
|
|
20694
|
+
}
|
|
20695
|
+
}
|
|
20288
20696
|
function editableConfig(config) {
|
|
20289
20697
|
return {
|
|
20290
20698
|
enabled: config.enabled,
|
|
@@ -20300,14 +20708,15 @@ function editableConfig(config) {
|
|
|
20300
20708
|
codex: {
|
|
20301
20709
|
enabled: config.codex.enabled,
|
|
20302
20710
|
binary: config.codex.binary
|
|
20303
|
-
}
|
|
20711
|
+
},
|
|
20712
|
+
...config.acp === void 0 ? {} : { acp: { enabled: config.acp.enabled, backends: config.acp.backends } }
|
|
20304
20713
|
};
|
|
20305
20714
|
}
|
|
20306
|
-
function
|
|
20715
|
+
function isRecord8(value) {
|
|
20307
20716
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20308
20717
|
}
|
|
20309
20718
|
function record4(value) {
|
|
20310
|
-
if (!
|
|
20719
|
+
if (!isRecord8(value)) throw new ClientModeError("INVALID_MESSAGE", "The control request payload is invalid.");
|
|
20311
20720
|
return value;
|
|
20312
20721
|
}
|
|
20313
20722
|
function ok3(value) {
|
|
@@ -20431,7 +20840,21 @@ var ConnectionController = class {
|
|
|
20431
20840
|
return this.active.size;
|
|
20432
20841
|
}
|
|
20433
20842
|
peerDeviceIds() {
|
|
20434
|
-
return
|
|
20843
|
+
return this.connectedPeers().map((peer) => peer.deviceId);
|
|
20844
|
+
}
|
|
20845
|
+
connectedPeers() {
|
|
20846
|
+
const peers = [];
|
|
20847
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20848
|
+
for (const connection of this.active.values()) {
|
|
20849
|
+
const deviceId = connection.channel.peerDeviceId;
|
|
20850
|
+
if (seen.has(deviceId)) continue;
|
|
20851
|
+
seen.add(deviceId);
|
|
20852
|
+
peers.push({
|
|
20853
|
+
deviceId,
|
|
20854
|
+
...connection.channel.mode === void 0 ? {} : { mode: connection.channel.mode }
|
|
20855
|
+
});
|
|
20856
|
+
}
|
|
20857
|
+
return peers;
|
|
20435
20858
|
}
|
|
20436
20859
|
peerDeviceId() {
|
|
20437
20860
|
const peers = this.peerDeviceIds();
|
|
@@ -20576,7 +20999,14 @@ var apiMethods = /* @__PURE__ */ new Set([
|
|
|
20576
20999
|
"codex.app.transfer.chunk",
|
|
20577
21000
|
"codex.app.transfer.commit",
|
|
20578
21001
|
"codex.app.transfer.read",
|
|
20579
|
-
"codex.app.transfer.close"
|
|
21002
|
+
"codex.app.transfer.close",
|
|
21003
|
+
"acp.initialize",
|
|
21004
|
+
"acp.session.new",
|
|
21005
|
+
"acp.session.load",
|
|
21006
|
+
"acp.session.prompt",
|
|
21007
|
+
"acp.session.respond_permission",
|
|
21008
|
+
"acp.session.cancel",
|
|
21009
|
+
"acp.session.set_mode"
|
|
20580
21010
|
]);
|
|
20581
21011
|
var HOST_CAPABILITIES = [
|
|
20582
21012
|
"harness.api.v1",
|
|
@@ -20585,10 +21015,11 @@ var HOST_CAPABILITIES = [
|
|
|
20585
21015
|
"harness.remote.transfer.v1",
|
|
20586
21016
|
"fileviewer.read.v1",
|
|
20587
21017
|
"codex.appserver.v1",
|
|
20588
|
-
"codex.appserver.transfer.v1"
|
|
21018
|
+
"codex.appserver.transfer.v1",
|
|
21019
|
+
"agent.acp.v1"
|
|
20589
21020
|
];
|
|
20590
21021
|
var RpcRouter = class {
|
|
20591
|
-
constructor(harnessApi, maxPending = 128, logger, fileViewer, harnessRemote, capabilities = () => HOST_CAPABILITIES, codex) {
|
|
21022
|
+
constructor(harnessApi, maxPending = 128, logger, fileViewer, harnessRemote, capabilities = () => HOST_CAPABILITIES, codex, acp) {
|
|
20592
21023
|
this.harnessApi = harnessApi;
|
|
20593
21024
|
this.maxPending = maxPending;
|
|
20594
21025
|
this.logger = logger;
|
|
@@ -20596,6 +21027,7 @@ var RpcRouter = class {
|
|
|
20596
21027
|
this.harnessRemote = harnessRemote;
|
|
20597
21028
|
this.capabilities = capabilities;
|
|
20598
21029
|
this.codex = codex;
|
|
21030
|
+
this.acp = acp;
|
|
20599
21031
|
}
|
|
20600
21032
|
active = 0;
|
|
20601
21033
|
async closePeerStreams() {
|
|
@@ -20628,7 +21060,7 @@ var RpcRouter = class {
|
|
|
20628
21060
|
});
|
|
20629
21061
|
return createRpcResponse(request.id, result);
|
|
20630
21062
|
} catch (error) {
|
|
20631
|
-
const response =
|
|
21063
|
+
const response = errorResponse2(request.id, error);
|
|
20632
21064
|
this.logger?.warn("host rpc failed", {
|
|
20633
21065
|
method: request.payload.method,
|
|
20634
21066
|
durationMs: Math.round(performance.now() - startedAt),
|
|
@@ -20704,6 +21136,20 @@ var RpcRouter = class {
|
|
|
20704
21136
|
return this.requireCodex().readTransfer(params);
|
|
20705
21137
|
case "codex.app.transfer.close":
|
|
20706
21138
|
return this.requireCodex().closeTransfer(params);
|
|
21139
|
+
case "acp.initialize":
|
|
21140
|
+
return this.requireAcp().initialize(params);
|
|
21141
|
+
case "acp.session.new":
|
|
21142
|
+
return this.requireAcp().sessionNew(params);
|
|
21143
|
+
case "acp.session.load":
|
|
21144
|
+
return this.requireAcp().sessionLoad(params);
|
|
21145
|
+
case "acp.session.prompt":
|
|
21146
|
+
return this.requireAcp().prompt(params, async () => void 0);
|
|
21147
|
+
case "acp.session.respond_permission":
|
|
21148
|
+
return this.requireAcp().respondPermission(params);
|
|
21149
|
+
case "acp.session.cancel":
|
|
21150
|
+
return this.requireAcp().cancel(params);
|
|
21151
|
+
case "acp.session.set_mode":
|
|
21152
|
+
return this.requireAcp().setMode(params);
|
|
20707
21153
|
default:
|
|
20708
21154
|
throw new RpcError("METHOD_NOT_FOUND", "The requested method does not exist.");
|
|
20709
21155
|
}
|
|
@@ -20720,6 +21166,10 @@ var RpcRouter = class {
|
|
|
20720
21166
|
}
|
|
20721
21167
|
return this.harnessRemote;
|
|
20722
21168
|
}
|
|
21169
|
+
requireAcp() {
|
|
21170
|
+
if (!this.acp) throw new RpcError("CAPABILITY_NOT_SUPPORTED", "ACP is not configured on this Host.");
|
|
21171
|
+
return this.acp;
|
|
21172
|
+
}
|
|
20723
21173
|
requireCodex() {
|
|
20724
21174
|
if (this.codex === void 0) {
|
|
20725
21175
|
throw new RpcError("FEATURE_NOT_SUPPORTED", "Codex Remote is disabled or unavailable on this Host.");
|
|
@@ -20727,7 +21177,7 @@ var RpcRouter = class {
|
|
|
20727
21177
|
return this.codex;
|
|
20728
21178
|
}
|
|
20729
21179
|
};
|
|
20730
|
-
function
|
|
21180
|
+
function errorResponse2(requestId, error) {
|
|
20731
21181
|
const code = safeErrorCode(error);
|
|
20732
21182
|
if (error instanceof RpcError) return createRpcError(requestId, code, error.message, error.details, error.retryable);
|
|
20733
21183
|
return createRpcError(
|
|
@@ -21806,11 +22256,22 @@ var transferCloseSchema = external_exports.object({ transferId: transferIdSchema
|
|
|
21806
22256
|
var commandExecuteSchema = external_exports.object({
|
|
21807
22257
|
agentId: external_exports.string().min(1).max(128),
|
|
21808
22258
|
line: external_exports.string().min(1).max(2048),
|
|
21809
|
-
//
|
|
21810
|
-
//
|
|
21811
|
-
//
|
|
21812
|
-
|
|
21813
|
-
|
|
22259
|
+
// dsh-commands <= 0.1.2 calls this field `images`; dsh-commands 0.1.5
|
|
22260
|
+
// renamed it to `submittedAttachments` and expanded its element type to
|
|
22261
|
+
// include staged file receipts. Remote command execution keeps attachments
|
|
22262
|
+
// out of scope, so either compatibility field is restricted to an empty
|
|
22263
|
+
// list. The dispatcher below chooses the matching Host descriptor.
|
|
22264
|
+
images: external_exports.array(external_exports.never()).length(0).optional(),
|
|
22265
|
+
submittedAttachments: external_exports.array(external_exports.never()).length(0).optional()
|
|
22266
|
+
}).strict().superRefine((value, context) => {
|
|
22267
|
+
if (value.images !== void 0 && value.submittedAttachments !== void 0) {
|
|
22268
|
+
context.addIssue({
|
|
22269
|
+
code: external_exports.ZodIssueCode.custom,
|
|
22270
|
+
message: "Use either images or submittedAttachments, not both.",
|
|
22271
|
+
path: ["submittedAttachments"]
|
|
22272
|
+
});
|
|
22273
|
+
}
|
|
22274
|
+
});
|
|
21814
22275
|
var commandListSchema = external_exports.object({
|
|
21815
22276
|
agentId: external_exports.string().min(1).max(128)
|
|
21816
22277
|
}).strict();
|
|
@@ -21920,8 +22381,8 @@ var HARNESS_API_ALLOWLIST = [
|
|
|
21920
22381
|
"credentials.unset"
|
|
21921
22382
|
];
|
|
21922
22383
|
var NATIVE_CALL_TIMEOUT_MS = 3e4;
|
|
21923
|
-
var MAX_ACTIVE_API_TRANSFERS =
|
|
21924
|
-
var API_TRANSFER_IDLE_MS =
|
|
22384
|
+
var MAX_ACTIVE_API_TRANSFERS = MAX_ACTIVE_TRANSFERS_PER_DIRECTION;
|
|
22385
|
+
var API_TRANSFER_IDLE_MS = TRANSFER_IDLE_MS;
|
|
21925
22386
|
var INLINE_TRANSFER_RESPONSE_BYTES = 2 * 1024 * 1024;
|
|
21926
22387
|
var SESSION_HISTORY_PAGE_SIZES = [50, 30, 20, 12, 6, 3, 1];
|
|
21927
22388
|
var HarnessApiBridge = class {
|
|
@@ -21931,7 +22392,7 @@ var HarnessApiBridge = class {
|
|
|
21931
22392
|
this.maxStreams = maxStreams;
|
|
21932
22393
|
this.logger = logger;
|
|
21933
22394
|
this.harnessVersion = harnessVersion;
|
|
21934
|
-
this.methods = createMethodMap(api, typertGateway);
|
|
22395
|
+
this.methods = createMethodMap(api, typertGateway, harnessVersion);
|
|
21935
22396
|
this.mux = api.events.mux.bind(api.events);
|
|
21936
22397
|
this.host = api.events.host.bind(api.events);
|
|
21937
22398
|
this.answer = api.respond.bind(api);
|
|
@@ -21998,9 +22459,9 @@ var HarnessApiBridge = class {
|
|
|
21998
22459
|
const value = await listRemoteDirectory(payload.path, signal);
|
|
21999
22460
|
return { rpcId: params.rpcId, result: { ok: true, value } };
|
|
22000
22461
|
}
|
|
22001
|
-
describeFallback(
|
|
22462
|
+
describeFallback(rpcId2) {
|
|
22002
22463
|
return {
|
|
22003
|
-
rpcId,
|
|
22464
|
+
rpcId: rpcId2,
|
|
22004
22465
|
result: {
|
|
22005
22466
|
ok: true,
|
|
22006
22467
|
value: {
|
|
@@ -22218,8 +22679,8 @@ var HarnessApiBridge = class {
|
|
|
22218
22679
|
}
|
|
22219
22680
|
}
|
|
22220
22681
|
deleteRespondable(value) {
|
|
22221
|
-
for (const [
|
|
22222
|
-
if (correlation === value) this.respondable.delete(
|
|
22682
|
+
for (const [rpcId2, correlation] of this.respondable) {
|
|
22683
|
+
if (correlation === value) this.respondable.delete(rpcId2);
|
|
22223
22684
|
}
|
|
22224
22685
|
}
|
|
22225
22686
|
};
|
|
@@ -22252,7 +22713,7 @@ function normalizeHostDescribe(response, harnessVersion, canListDirectory) {
|
|
|
22252
22713
|
}
|
|
22253
22714
|
};
|
|
22254
22715
|
}
|
|
22255
|
-
function createMethodMap(api, typertGateway) {
|
|
22716
|
+
function createMethodMap(api, typertGateway, harnessVersion) {
|
|
22256
22717
|
const domains = api;
|
|
22257
22718
|
const methods = /* @__PURE__ */ new Map();
|
|
22258
22719
|
for (const method of HARNESS_API_ALLOWLIST) {
|
|
@@ -22262,7 +22723,17 @@ function createMethodMap(api, typertGateway) {
|
|
|
22262
22723
|
const implementation2 = async (request, signal) => {
|
|
22263
22724
|
if (commandMethod === "execute") {
|
|
22264
22725
|
const payload = commandExecuteSchema.parse(request.payload);
|
|
22265
|
-
const
|
|
22726
|
+
const legacyArgs = {
|
|
22727
|
+
agentId: payload.agentId,
|
|
22728
|
+
line: payload.line,
|
|
22729
|
+
images: payload.images ?? []
|
|
22730
|
+
};
|
|
22731
|
+
const currentArgs = {
|
|
22732
|
+
agentId: payload.agentId,
|
|
22733
|
+
line: payload.line,
|
|
22734
|
+
submittedAttachments: payload.submittedAttachments ?? []
|
|
22735
|
+
};
|
|
22736
|
+
const args2 = harnessSessionGeneration(harnessVersion) === "v3" ? currentArgs : legacyArgs;
|
|
22266
22737
|
const value2 = await typertGateway.invoke({
|
|
22267
22738
|
namespace,
|
|
22268
22739
|
method: "execute",
|
|
@@ -22406,9 +22877,9 @@ function sanitizeModelDiscoveryResponse(response, settingsNs) {
|
|
|
22406
22877
|
if (typeof result === "object" && result !== null && "ok" in result && result.ok === true) return response;
|
|
22407
22878
|
return modelDiscoveryFailure(response.rpcId, settingsNs);
|
|
22408
22879
|
}
|
|
22409
|
-
function modelDiscoveryFailure(
|
|
22880
|
+
function modelDiscoveryFailure(rpcId2, settingsNs) {
|
|
22410
22881
|
return {
|
|
22411
|
-
rpcId,
|
|
22882
|
+
rpcId: rpcId2,
|
|
22412
22883
|
result: {
|
|
22413
22884
|
ok: false,
|
|
22414
22885
|
error: {
|
|
@@ -22468,15 +22939,15 @@ function frameSessionId(frame) {
|
|
|
22468
22939
|
const payload = frame.payload;
|
|
22469
22940
|
return typeof payload.sessionId === "string" && payload.sessionId.length > 0 ? payload.sessionId : void 0;
|
|
22470
22941
|
}
|
|
22471
|
-
function callSessionHistory(callWithTimeout, payload,
|
|
22942
|
+
function callSessionHistory(callWithTimeout, payload, rpcId2) {
|
|
22472
22943
|
const fallbackPageSizes = sessionHistoryFallbackPageSizes(payloadMaxMessages(payload));
|
|
22473
|
-
return callHistoryWithRetry(callWithTimeout, payload,
|
|
22944
|
+
return callHistoryWithRetry(callWithTimeout, payload, rpcId2, fallbackPageSizes);
|
|
22474
22945
|
}
|
|
22475
|
-
async function callHistoryWithRetry(callWithTimeout, payload,
|
|
22946
|
+
async function callHistoryWithRetry(callWithTimeout, payload, rpcId2, pageSizes) {
|
|
22476
22947
|
for (const maxMessages of pageSizes) {
|
|
22477
22948
|
const requestPayload = historyRequestPayload(payload, maxMessages);
|
|
22478
22949
|
const response = await callWithTimeout(requestPayload);
|
|
22479
|
-
const request = createRpcResponse(
|
|
22950
|
+
const request = createRpcResponse(rpcId2, response.result);
|
|
22480
22951
|
if (encodeMessage(request).byteLength <= MAX_SECURE_MESSAGE_BYTES) return response;
|
|
22481
22952
|
if (maxMessages === pageSizes[pageSizes.length - 1]) {
|
|
22482
22953
|
throw new RpcError(
|
|
@@ -22564,6 +23035,24 @@ var streamOpenSchema2 = external_exports.object({
|
|
|
22564
23035
|
payload: external_exports.unknown()
|
|
22565
23036
|
}).strict();
|
|
22566
23037
|
var streamCloseSchema2 = external_exports.object({ streamId: external_exports.string().min(1).max(128) }).strict();
|
|
23038
|
+
var commandExecuteArgsSchema = external_exports.object({
|
|
23039
|
+
agentId: external_exports.string().min(1).max(128),
|
|
23040
|
+
line: external_exports.string().min(1).max(2048),
|
|
23041
|
+
// dsh-commands <= 0.1.2 calls this field `images`; dsh-commands 0.1.5
|
|
23042
|
+
// renamed it to `submittedAttachments`. Only empty arrays are exposed by
|
|
23043
|
+
// the Remote bridge; command attachments are deliberately out of scope.
|
|
23044
|
+
images: external_exports.array(external_exports.never()).length(0).optional(),
|
|
23045
|
+
submittedAttachments: external_exports.array(external_exports.never()).length(0).optional()
|
|
23046
|
+
}).strict().superRefine((value, context) => {
|
|
23047
|
+
if (value.images !== void 0 && value.submittedAttachments !== void 0) {
|
|
23048
|
+
context.addIssue({
|
|
23049
|
+
code: external_exports.ZodIssueCode.custom,
|
|
23050
|
+
message: "Use either images or submittedAttachments, not both.",
|
|
23051
|
+
path: ["submittedAttachments"]
|
|
23052
|
+
});
|
|
23053
|
+
}
|
|
23054
|
+
});
|
|
23055
|
+
var commandExecutePayloadSchema = external_exports.object({ args: commandExecuteArgsSchema }).strict();
|
|
22567
23056
|
var transferOpenSchema2 = external_exports.object({
|
|
22568
23057
|
transferId: external_exports.string().uuid(),
|
|
22569
23058
|
totalBytes: external_exports.number().int().positive().max(MAX_HARNESS_API_TRANSFER_BYTES),
|
|
@@ -22582,9 +23071,8 @@ var transferReadSchema2 = external_exports.object({
|
|
|
22582
23071
|
var directoryListSchema2 = external_exports.object({
|
|
22583
23072
|
path: external_exports.string().min(1).max(4096).optional()
|
|
22584
23073
|
}).strict();
|
|
22585
|
-
var MAX_ACTIVE_STREAMS =
|
|
22586
|
-
var MAX_ACTIVE_TRANSFERS =
|
|
22587
|
-
var TRANSFER_IDLE_MS = 2 * 6e4;
|
|
23074
|
+
var MAX_ACTIVE_STREAMS = MAX_ALPHA_STREAMS_PER_CONNECTION;
|
|
23075
|
+
var MAX_ACTIVE_TRANSFERS = MAX_ACTIVE_TRANSFERS_PER_DIRECTION;
|
|
22588
23076
|
var INLINE_TRANSFER_RESPONSE_BYTES2 = 2 * 1024 * 1024;
|
|
22589
23077
|
var HARNESS_REMOTE_ALLOWLIST = [
|
|
22590
23078
|
"$events",
|
|
@@ -22646,10 +23134,11 @@ var HARNESS_REMOTE_ALLOWLIST = [
|
|
|
22646
23134
|
];
|
|
22647
23135
|
var allowedEndpoints = new Set(HARNESS_REMOTE_ALLOWLIST);
|
|
22648
23136
|
var HarnessRemoteBridge = class {
|
|
22649
|
-
constructor(gateway, publish, logger) {
|
|
23137
|
+
constructor(gateway, publish, logger, harnessVersion) {
|
|
22650
23138
|
this.gateway = gateway;
|
|
22651
23139
|
this.publish = publish;
|
|
22652
23140
|
this.logger = logger;
|
|
23141
|
+
this.harnessVersion = harnessVersion;
|
|
22653
23142
|
}
|
|
22654
23143
|
streams = /* @__PURE__ */ new Map();
|
|
22655
23144
|
incomingTransfers = /* @__PURE__ */ new Map();
|
|
@@ -22663,7 +23152,7 @@ var HarnessRemoteBridge = class {
|
|
|
22663
23152
|
const startedAt = performance.now();
|
|
22664
23153
|
const signal = AbortSignal.timeout(6e4);
|
|
22665
23154
|
try {
|
|
22666
|
-
const nativeResult = await this.gateway.dispatch(params.endpoint, params.payload, signal);
|
|
23155
|
+
const nativeResult = params.endpoint === "commands/execute" ? await dispatchCommandForHost(this.gateway, params.payload, signal, this.harnessVersion) : await this.gateway.dispatch(params.endpoint, params.payload, signal);
|
|
22667
23156
|
const result = params.endpoint === "directoryPicker/list" && needsDirectoryFallback(nativeResult) ? await this.directoryList(params.payload, signal) : nativeResult;
|
|
22668
23157
|
this.logger?.debug("harness remote call ok", {
|
|
22669
23158
|
endpoint: params.endpoint,
|
|
@@ -22862,6 +23351,29 @@ var HarnessRemoteBridge = class {
|
|
|
22862
23351
|
for (const [id2, transfer] of this.outgoingTransfers) if (transfer.touchedAt < cutoff) this.outgoingTransfers.delete(id2);
|
|
22863
23352
|
}
|
|
22864
23353
|
};
|
|
23354
|
+
async function dispatchCommandForHost(gateway, payload, signal, harnessVersion) {
|
|
23355
|
+
const parsed = commandExecutePayloadSchema.parse(payload);
|
|
23356
|
+
const legacyPayload = {
|
|
23357
|
+
args: {
|
|
23358
|
+
agentId: parsed.args.agentId,
|
|
23359
|
+
line: parsed.args.line,
|
|
23360
|
+
images: parsed.args.images ?? []
|
|
23361
|
+
}
|
|
23362
|
+
};
|
|
23363
|
+
const currentPayload = {
|
|
23364
|
+
args: {
|
|
23365
|
+
agentId: parsed.args.agentId,
|
|
23366
|
+
line: parsed.args.line,
|
|
23367
|
+
submittedAttachments: parsed.args.submittedAttachments ?? []
|
|
23368
|
+
}
|
|
23369
|
+
};
|
|
23370
|
+
const args = harnessSessionGeneration(harnessVersion) === "v3" ? currentPayload : legacyPayload;
|
|
23371
|
+
return gateway.dispatch(
|
|
23372
|
+
"commands/execute",
|
|
23373
|
+
args,
|
|
23374
|
+
signal
|
|
23375
|
+
);
|
|
23376
|
+
}
|
|
22865
23377
|
function decodeCanonicalBase642(value) {
|
|
22866
23378
|
const bytes = Buffer.from(value, "base64");
|
|
22867
23379
|
if (bytes.toString("base64") !== value) throw new RpcError("INVALID_MESSAGE", "The Harness Remote transfer chunk is invalid.");
|
|
@@ -22884,13 +23396,13 @@ function needsDirectoryFallback(result) {
|
|
|
22884
23396
|
}
|
|
22885
23397
|
function requestArgs(payload) {
|
|
22886
23398
|
const root = record5(payload);
|
|
22887
|
-
const args =
|
|
23399
|
+
const args = isRecord9(root.args) ? root.args : root;
|
|
22888
23400
|
return record5(args.request ?? args._request ?? args);
|
|
22889
23401
|
}
|
|
22890
23402
|
function record5(value) {
|
|
22891
|
-
return
|
|
23403
|
+
return isRecord9(value) ? value : {};
|
|
22892
23404
|
}
|
|
22893
|
-
function
|
|
23405
|
+
function isRecord9(value) {
|
|
22894
23406
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
22895
23407
|
}
|
|
22896
23408
|
|
|
@@ -23084,7 +23596,7 @@ var CodexAppServerClient = class {
|
|
|
23084
23596
|
this.handleProcessFailure("CODEX_INVALID_RESPONSE", new Error("Codex App Server emitted invalid JSON."));
|
|
23085
23597
|
return;
|
|
23086
23598
|
}
|
|
23087
|
-
if (!
|
|
23599
|
+
if (!isRecord10(value)) {
|
|
23088
23600
|
this.handleProcessFailure("CODEX_INVALID_RESPONSE", new Error("Codex App Server emitted an invalid message."));
|
|
23089
23601
|
return;
|
|
23090
23602
|
}
|
|
@@ -23129,12 +23641,12 @@ var CodexAppServerClient = class {
|
|
|
23129
23641
|
}
|
|
23130
23642
|
};
|
|
23131
23643
|
function safeUpstreamError(value) {
|
|
23132
|
-
if (!
|
|
23644
|
+
if (!isRecord10(value) || typeof value.message !== "string") return "Codex App Server rejected the request.";
|
|
23133
23645
|
const message = value.message.toLowerCase();
|
|
23134
23646
|
if (message.includes("active writer")) return "Codex thread already has an active writer.";
|
|
23135
23647
|
return message.includes("not initialized") ? "Codex App Server is not initialized." : "Codex App Server rejected the request.";
|
|
23136
23648
|
}
|
|
23137
|
-
function
|
|
23649
|
+
function isRecord10(value) {
|
|
23138
23650
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23139
23651
|
}
|
|
23140
23652
|
|
|
@@ -23266,9 +23778,8 @@ var transferChunkSchema3 = external_exports.object({
|
|
|
23266
23778
|
}).strict();
|
|
23267
23779
|
var transferIdSchema3 = external_exports.object({ transferId: external_exports.string().uuid() }).strict();
|
|
23268
23780
|
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;
|
|
23781
|
+
var MAX_ACTIVE_STREAMS2 = MAX_ALPHA_STREAMS_PER_CONNECTION;
|
|
23782
|
+
var MAX_ACTIVE_TRANSFERS2 = MAX_ACTIVE_TRANSFERS_PER_DIRECTION;
|
|
23272
23783
|
var INLINE_TRANSFER_RESPONSE_BYTES3 = 2 * 1024 * 1024;
|
|
23273
23784
|
var CodexPeerBridge = class {
|
|
23274
23785
|
constructor(domain, context, publish, logger) {
|
|
@@ -23482,7 +23993,7 @@ var CodexPeerBridge = class {
|
|
|
23482
23993
|
await this.domain.detachPeer(this.context.connectionId);
|
|
23483
23994
|
}
|
|
23484
23995
|
pruneTransfers() {
|
|
23485
|
-
const staleBefore = Date.now() -
|
|
23996
|
+
const staleBefore = Date.now() - TRANSFER_IDLE_MS;
|
|
23486
23997
|
for (const [id2, transfer] of this.incomingTransfers) {
|
|
23487
23998
|
if (transfer.touchedAt < staleBefore) this.incomingTransfers.delete(id2);
|
|
23488
23999
|
}
|
|
@@ -23504,15 +24015,15 @@ function decodeCanonicalBase643(value) {
|
|
|
23504
24015
|
}
|
|
23505
24016
|
return decoded;
|
|
23506
24017
|
}
|
|
23507
|
-
function
|
|
24018
|
+
function isRecord11(value) {
|
|
23508
24019
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23509
24020
|
}
|
|
23510
24021
|
function safeErrorCode2(error) {
|
|
23511
|
-
if (
|
|
24022
|
+
if (isRecord11(error) && typeof error.code === "string") return error.code;
|
|
23512
24023
|
return "UNKNOWN";
|
|
23513
24024
|
}
|
|
23514
24025
|
function safeMethod(input2) {
|
|
23515
|
-
return
|
|
24026
|
+
return isRecord11(input2) && typeof input2.method === "string" ? input2.method : "invalid";
|
|
23516
24027
|
}
|
|
23517
24028
|
function concatChunks3(chunks, totalBytes) {
|
|
23518
24029
|
const output = new Uint8Array(totalBytes);
|
|
@@ -23929,14 +24440,14 @@ var CodexRemoteDomain = class {
|
|
|
23929
24440
|
await this.assertResultThreadAllowed(result);
|
|
23930
24441
|
if (codexPermissionPresetFromResponse(result) !== params.permissionPreset) {
|
|
23931
24442
|
await this.callUpstream("thread/settings/update", { threadId, ...settings });
|
|
23932
|
-
result = { ...
|
|
24443
|
+
result = { ...isRecord12(result) ? result : {}, ...settings, sandbox: settings.sandboxPolicy };
|
|
23933
24444
|
}
|
|
23934
24445
|
}
|
|
23935
24446
|
await this.publishPermission(threadId, result);
|
|
23936
24447
|
return result;
|
|
23937
24448
|
}
|
|
23938
24449
|
async publishPermission(threadId, value) {
|
|
23939
|
-
const source =
|
|
24450
|
+
const source = isRecord12(value) ? value : {};
|
|
23940
24451
|
const threadSettings = { approvalPolicy: source.approvalPolicy, sandboxPolicy: source.sandboxPolicy ?? source.sandbox };
|
|
23941
24452
|
await this.handleInbound({ kind: "notification", method: "thread/settings/updated", params: { threadId, threadSettings } });
|
|
23942
24453
|
}
|
|
@@ -24032,9 +24543,9 @@ var CodexRemoteDomain = class {
|
|
|
24032
24543
|
itemsView,
|
|
24033
24544
|
...cursor2 === void 0 ? {} : { cursor: cursor2 }
|
|
24034
24545
|
});
|
|
24035
|
-
const pageResult =
|
|
24546
|
+
const pageResult = isRecord12(result) ? result : {};
|
|
24036
24547
|
for (const rawTurn of array2(pageResult.data)) {
|
|
24037
|
-
if (!
|
|
24548
|
+
if (!isRecord12(rawTurn)) continue;
|
|
24038
24549
|
const turnId = typeof rawTurn.id === "string" ? rawTurn.id : void 0;
|
|
24039
24550
|
const items = rawTurn.itemsView === "full" || turnId === void 0 ? array2(rawTurn.items) : await this.readThreadItems(connectionId, threadId, turnId, array2(rawTurn.items));
|
|
24040
24551
|
turns.push({ ...rawTurn, items });
|
|
@@ -24056,9 +24567,9 @@ var CodexRemoteDomain = class {
|
|
|
24056
24567
|
sortDirection: "asc",
|
|
24057
24568
|
...cursor2 === void 0 ? {} : { cursor: cursor2 }
|
|
24058
24569
|
});
|
|
24059
|
-
const pageResult =
|
|
24570
|
+
const pageResult = isRecord12(result) ? result : {};
|
|
24060
24571
|
for (const entry of array2(pageResult.data)) {
|
|
24061
|
-
if (
|
|
24572
|
+
if (isRecord12(entry) && entry.item !== void 0) items.push(entry.item);
|
|
24062
24573
|
}
|
|
24063
24574
|
cursor2 = typeof pageResult.nextCursor === "string" && pageResult.nextCursor.length > 0 ? pageResult.nextCursor : void 0;
|
|
24064
24575
|
if (cursor2 === void 0) break;
|
|
@@ -24122,7 +24633,7 @@ var CodexRemoteDomain = class {
|
|
|
24122
24633
|
return [...this.peers.values()].some((peer) => peer.hasThreadSubscription(threadId));
|
|
24123
24634
|
}
|
|
24124
24635
|
resolveUpstreamApproval(params) {
|
|
24125
|
-
if (!
|
|
24636
|
+
if (!isRecord12(params) || typeof params.requestId !== "string" && typeof params.requestId !== "number") return;
|
|
24126
24637
|
for (const [handle, approval] of this.approvals) {
|
|
24127
24638
|
if (approval.upstreamId === params.requestId) this.approvals.delete(handle);
|
|
24128
24639
|
}
|
|
@@ -24339,24 +24850,24 @@ function codexBinaryCandidates(configured, hostPlatform = process.platform, user
|
|
|
24339
24850
|
])];
|
|
24340
24851
|
}
|
|
24341
24852
|
function parseCallEnvelope(input2) {
|
|
24342
|
-
if (!
|
|
24853
|
+
if (!isRecord12(input2) || typeof input2.method !== "string" || !("params" in input2) || Object.keys(input2).some((key) => key !== "method" && key !== "params")) {
|
|
24343
24854
|
throw new RpcError("INVALID_MESSAGE", "The Codex call envelope is invalid.");
|
|
24344
24855
|
}
|
|
24345
24856
|
return { method: input2.method, params: input2.params };
|
|
24346
24857
|
}
|
|
24347
24858
|
function parseRespond(input2) {
|
|
24348
|
-
if (!
|
|
24859
|
+
if (!isRecord12(input2) || typeof input2.requestHandle !== "string" || !["accept", "decline", "cancel"].includes(String(input2.decision)) || Object.keys(input2).some((key) => key !== "requestHandle" && key !== "decision")) {
|
|
24349
24860
|
throw new RpcError("INVALID_MESSAGE", "The Codex approval response is invalid.");
|
|
24350
24861
|
}
|
|
24351
24862
|
return input2;
|
|
24352
24863
|
}
|
|
24353
24864
|
function accountCanRun(result) {
|
|
24354
|
-
if (!
|
|
24355
|
-
return result.requiresOpenaiAuth === false ||
|
|
24865
|
+
if (!isRecord12(result) || typeof result.requiresOpenaiAuth !== "boolean") return false;
|
|
24866
|
+
return result.requiresOpenaiAuth === false || isRecord12(result.account);
|
|
24356
24867
|
}
|
|
24357
24868
|
function sanitizeAccount(result) {
|
|
24358
|
-
if (!
|
|
24359
|
-
const account =
|
|
24869
|
+
if (!isRecord12(result)) throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned invalid account state.");
|
|
24870
|
+
const account = isRecord12(result.account) ? result.account : void 0;
|
|
24360
24871
|
return {
|
|
24361
24872
|
authenticated: account !== void 0 || result.requiresOpenaiAuth === false,
|
|
24362
24873
|
requiresOpenaiAuth: result.requiresOpenaiAuth === true,
|
|
@@ -24369,11 +24880,11 @@ function sanitizeAccount(result) {
|
|
|
24369
24880
|
};
|
|
24370
24881
|
}
|
|
24371
24882
|
function sanitizeThreadList(result) {
|
|
24372
|
-
if (!
|
|
24883
|
+
if (!isRecord12(result) || !Array.isArray(result.data)) {
|
|
24373
24884
|
throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid thread list.");
|
|
24374
24885
|
}
|
|
24375
24886
|
const data = result.data.flatMap((value) => {
|
|
24376
|
-
if (!
|
|
24887
|
+
if (!isRecord12(value) || typeof value.id !== "string") return [];
|
|
24377
24888
|
return [{
|
|
24378
24889
|
id: value.id,
|
|
24379
24890
|
...typeof value.sessionId === "string" ? { sessionId: value.sessionId } : {},
|
|
@@ -24385,7 +24896,7 @@ function sanitizeThreadList(result) {
|
|
|
24385
24896
|
...typeof value.updatedAt === "number" && Number.isFinite(value.updatedAt) ? { updatedAt: value.updatedAt } : {},
|
|
24386
24897
|
...typeof value.archived === "boolean" ? { archived: value.archived } : {},
|
|
24387
24898
|
...typeof value.isPinned === "boolean" ? { isPinned: value.isPinned } : {},
|
|
24388
|
-
...
|
|
24899
|
+
...isRecord12(value.status) ? { status: value.status } : {}
|
|
24389
24900
|
}];
|
|
24390
24901
|
});
|
|
24391
24902
|
return {
|
|
@@ -24395,18 +24906,18 @@ function sanitizeThreadList(result) {
|
|
|
24395
24906
|
};
|
|
24396
24907
|
}
|
|
24397
24908
|
function filterThreadListByWorkspaceAuthority(result, authority) {
|
|
24398
|
-
if (!
|
|
24909
|
+
if (!isRecord12(result) || !Array.isArray(result.data)) {
|
|
24399
24910
|
throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid thread list.");
|
|
24400
24911
|
}
|
|
24401
24912
|
return {
|
|
24402
24913
|
...result,
|
|
24403
|
-
data: result.data.map((record6) =>
|
|
24914
|
+
data: result.data.map((record6) => isRecord12(record6) ? record6 : void 0).filter((thread) => thread !== void 0 && isThreadAllowedByWorkspaceAuthority(thread, authority))
|
|
24404
24915
|
};
|
|
24405
24916
|
}
|
|
24406
24917
|
function sanitizeProject(value) {
|
|
24407
|
-
if (!
|
|
24918
|
+
if (!isRecord12(value) || typeof value.id !== "string" || typeof value.name !== "string") return void 0;
|
|
24408
24919
|
const roots = Array.isArray(value.roots) ? value.roots.flatMap((root) => {
|
|
24409
|
-
const path =
|
|
24920
|
+
const path = isRecord12(root) && typeof root.path === "string" && root.path.length > 0 ? root.path : void 0;
|
|
24410
24921
|
return path === void 0 || !isAbsolute3(path) ? [] : [{ path }];
|
|
24411
24922
|
}) : [];
|
|
24412
24923
|
if (roots.length === 0) return void 0;
|
|
@@ -24420,7 +24931,7 @@ function sanitizeProject(value) {
|
|
|
24420
24931
|
};
|
|
24421
24932
|
}
|
|
24422
24933
|
function sanitizeProjectList(result) {
|
|
24423
|
-
if (!
|
|
24934
|
+
if (!isRecord12(result) || !Array.isArray(result.data)) {
|
|
24424
24935
|
throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid project list.");
|
|
24425
24936
|
}
|
|
24426
24937
|
const data = result.data.flatMap((value) => sanitizeProject(value) ?? []);
|
|
@@ -24430,7 +24941,7 @@ function sanitizeProjectList(result) {
|
|
|
24430
24941
|
};
|
|
24431
24942
|
}
|
|
24432
24943
|
function sanitizeProjectCreate(result) {
|
|
24433
|
-
const project =
|
|
24944
|
+
const project = isRecord12(result) ? sanitizeProject(result.project) : void 0;
|
|
24434
24945
|
if (project === void 0) {
|
|
24435
24946
|
throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid created project.");
|
|
24436
24947
|
}
|
|
@@ -24462,19 +24973,19 @@ function codexDirectoryCrumbs(root, path) {
|
|
|
24462
24973
|
return crumbs2;
|
|
24463
24974
|
}
|
|
24464
24975
|
function extractThread(result) {
|
|
24465
|
-
return
|
|
24976
|
+
return isRecord12(result) && isRecord12(result.thread) ? result.thread : void 0;
|
|
24466
24977
|
}
|
|
24467
24978
|
function extractTurnId(result) {
|
|
24468
|
-
if (!
|
|
24979
|
+
if (!isRecord12(result)) return void 0;
|
|
24469
24980
|
if (typeof result.turnId === "string" && result.turnId.length > 0) return result.turnId;
|
|
24470
|
-
if (
|
|
24981
|
+
if (isRecord12(result.turn) && typeof result.turn.id === "string" && result.turn.id.length > 0) return result.turn.id;
|
|
24471
24982
|
return void 0;
|
|
24472
24983
|
}
|
|
24473
24984
|
function extractThreadId(params) {
|
|
24474
|
-
if (!
|
|
24985
|
+
if (!isRecord12(params)) return void 0;
|
|
24475
24986
|
if (typeof params.threadId === "string") return params.threadId;
|
|
24476
|
-
if (
|
|
24477
|
-
if (
|
|
24987
|
+
if (isRecord12(params.thread) && typeof params.thread.id === "string") return params.thread.id;
|
|
24988
|
+
if (isRecord12(params.turn) && typeof params.turn.threadId === "string") return params.turn.threadId;
|
|
24478
24989
|
return void 0;
|
|
24479
24990
|
}
|
|
24480
24991
|
function optionalInteger2(value) {
|
|
@@ -24516,13 +25027,13 @@ function mapCodexImageInputs(params) {
|
|
|
24516
25027
|
return {
|
|
24517
25028
|
...params,
|
|
24518
25029
|
input: params.input.map((value) => {
|
|
24519
|
-
if (!
|
|
25030
|
+
if (!isRecord12(value) || value.type !== "image" || typeof value.mediaType !== "string" || typeof value.data !== "string") return value;
|
|
24520
25031
|
return { type: "image", url: `data:${value.mediaType};base64,${value.data}` };
|
|
24521
25032
|
})
|
|
24522
25033
|
};
|
|
24523
25034
|
}
|
|
24524
25035
|
function sanitizeApprovalParams(params, requestHandle) {
|
|
24525
|
-
if (!
|
|
25036
|
+
if (!isRecord12(params)) return { requestHandle };
|
|
24526
25037
|
const safe = { ...params };
|
|
24527
25038
|
delete safe.proposedExecpolicyAmendment;
|
|
24528
25039
|
delete safe.additionalPermissions;
|
|
@@ -24553,7 +25064,7 @@ function isProjectListFallbackError(error) {
|
|
|
24553
25064
|
function canTryNextBinary(error) {
|
|
24554
25065
|
return !(error instanceof RpcError) || !["CODEX_AUTH_REQUIRED", "CODEX_CLOSED"].includes(error.code);
|
|
24555
25066
|
}
|
|
24556
|
-
function
|
|
25067
|
+
function isRecord12(value) {
|
|
24557
25068
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24558
25069
|
}
|
|
24559
25070
|
function array2(value) {
|
|
@@ -24566,7 +25077,119 @@ function isActiveWriterMessage(message) {
|
|
|
24566
25077
|
return message.toLowerCase().includes("active writer");
|
|
24567
25078
|
}
|
|
24568
25079
|
|
|
25080
|
+
// src/acp.ts
|
|
25081
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
25082
|
+
var AcpGateway = class {
|
|
25083
|
+
constructor(adapters) {
|
|
25084
|
+
this.adapters = adapters;
|
|
25085
|
+
}
|
|
25086
|
+
get(p) {
|
|
25087
|
+
const list = this.adapters instanceof Object && "backend" in this.adapters ? [this.adapters] : [...this.adapters];
|
|
25088
|
+
const a = list.find((x) => !p.backend || x.backend === p.backend);
|
|
25089
|
+
if (!a) throw new Error("CAPABILITY_NOT_SUPPORTED");
|
|
25090
|
+
return a;
|
|
25091
|
+
}
|
|
25092
|
+
initialize(p) {
|
|
25093
|
+
return this.get(p).initialize(p);
|
|
25094
|
+
}
|
|
25095
|
+
sessionNew(p) {
|
|
25096
|
+
return this.get(p).sessionNew(p);
|
|
25097
|
+
}
|
|
25098
|
+
sessionLoad(p) {
|
|
25099
|
+
const a = this.get(p);
|
|
25100
|
+
if (!a.sessionLoad) throw new Error("CAPABILITY_NOT_SUPPORTED");
|
|
25101
|
+
return a.sessionLoad(p);
|
|
25102
|
+
}
|
|
25103
|
+
prompt(p, emit) {
|
|
25104
|
+
return this.get(p).prompt(p, emit);
|
|
25105
|
+
}
|
|
25106
|
+
respondPermission(p) {
|
|
25107
|
+
const a = this.get(p);
|
|
25108
|
+
if (!a.respondPermission) throw new Error("CAPABILITY_NOT_SUPPORTED");
|
|
25109
|
+
return a.respondPermission(p);
|
|
25110
|
+
}
|
|
25111
|
+
cancel(p) {
|
|
25112
|
+
const a = this.get(p);
|
|
25113
|
+
if (!a.cancel) throw new Error("CAPABILITY_NOT_SUPPORTED");
|
|
25114
|
+
return a.cancel(p);
|
|
25115
|
+
}
|
|
25116
|
+
setMode(p) {
|
|
25117
|
+
const a = this.get(p);
|
|
25118
|
+
if (!a.setMode) throw new Error("CAPABILITY_NOT_SUPPORTED");
|
|
25119
|
+
return a.setMode(p);
|
|
25120
|
+
}
|
|
25121
|
+
};
|
|
25122
|
+
var StdioAcpAdapter = class {
|
|
25123
|
+
constructor(config) {
|
|
25124
|
+
this.config = config;
|
|
25125
|
+
this.backend = config.id;
|
|
25126
|
+
}
|
|
25127
|
+
backend;
|
|
25128
|
+
child;
|
|
25129
|
+
nextId = 1;
|
|
25130
|
+
ensure() {
|
|
25131
|
+
if (!this.child) this.child = spawn3(this.config.command, this.config.args ?? [], { cwd: this.config.cwd, stdio: "pipe" });
|
|
25132
|
+
return this.child;
|
|
25133
|
+
}
|
|
25134
|
+
async initialize(params) {
|
|
25135
|
+
await this.call("initialize", params);
|
|
25136
|
+
return { protocolVersion: 1, capability: "agent.acp.v1", backend: this.backend, capabilities: ["session.new", "session.load", "session.prompt", "session.cancel"] };
|
|
25137
|
+
}
|
|
25138
|
+
async sessionNew(params) {
|
|
25139
|
+
const r = await this.call("session/new", params);
|
|
25140
|
+
if (!r.sessionId) throw new Error("INVALID_MESSAGE");
|
|
25141
|
+
return { sessionId: r.sessionId };
|
|
25142
|
+
}
|
|
25143
|
+
async sessionLoad(params) {
|
|
25144
|
+
const r = await this.call("session/load", params);
|
|
25145
|
+
if (!r.sessionId) throw new Error("INVALID_MESSAGE");
|
|
25146
|
+
return { sessionId: r.sessionId };
|
|
25147
|
+
}
|
|
25148
|
+
async prompt(params, emit) {
|
|
25149
|
+
await this.call("session/prompt", params, async (n) => emit({ sessionId: params.sessionId, update: n, seq: this.nextId++ }));
|
|
25150
|
+
}
|
|
25151
|
+
async cancel(p) {
|
|
25152
|
+
await this.call("session/cancel", p);
|
|
25153
|
+
}
|
|
25154
|
+
async setMode(p) {
|
|
25155
|
+
await this.call("session/set_mode", p);
|
|
25156
|
+
}
|
|
25157
|
+
async respondPermission(p) {
|
|
25158
|
+
await this.call("session/request_permission", p);
|
|
25159
|
+
}
|
|
25160
|
+
async close() {
|
|
25161
|
+
this.child?.kill();
|
|
25162
|
+
this.child = void 0;
|
|
25163
|
+
}
|
|
25164
|
+
call(method, params, onNotification) {
|
|
25165
|
+
const c = this.ensure();
|
|
25166
|
+
const id2 = this.nextId++;
|
|
25167
|
+
c.stdin.write(JSON.stringify({ jsonrpc: "2.0", id: id2, method, params }) + "\n");
|
|
25168
|
+
return new Promise((resolve3, reject) => {
|
|
25169
|
+
let buf = "";
|
|
25170
|
+
const onData = async (d) => {
|
|
25171
|
+
buf += d;
|
|
25172
|
+
const lines = buf.split("\n");
|
|
25173
|
+
buf = lines.pop() ?? "";
|
|
25174
|
+
for (const l of lines) {
|
|
25175
|
+
try {
|
|
25176
|
+
const m = JSON.parse(l);
|
|
25177
|
+
if (m.id === id2) {
|
|
25178
|
+
c.stdout.off("data", onData);
|
|
25179
|
+
m.error ? reject(new Error(m.error.message ?? "ACP error")) : resolve3(m.result);
|
|
25180
|
+
} else if (m.method && onNotification) await onNotification(m.params);
|
|
25181
|
+
} catch {
|
|
25182
|
+
}
|
|
25183
|
+
}
|
|
25184
|
+
};
|
|
25185
|
+
c.stdout.on("data", onData);
|
|
25186
|
+
c.once("error", reject);
|
|
25187
|
+
});
|
|
25188
|
+
}
|
|
25189
|
+
};
|
|
25190
|
+
|
|
24569
25191
|
// src/service.ts
|
|
25192
|
+
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
24570
25193
|
var HostPluginRuntime = class {
|
|
24571
25194
|
constructor(config, identities, apiProxy, logger, localGateway, fileViewerHost) {
|
|
24572
25195
|
this.config = config;
|
|
@@ -24588,7 +25211,8 @@ var HostPluginRuntime = class {
|
|
|
24588
25211
|
const harnessRemote = this.localGateway?.supportsCarrier === true ? new HarnessRemoteBridge(
|
|
24589
25212
|
this.localGateway,
|
|
24590
25213
|
(event, data) => send(createEvent(event, data)),
|
|
24591
|
-
this.logger
|
|
25214
|
+
this.logger,
|
|
25215
|
+
this.harnessVersion
|
|
24592
25216
|
) : void 0;
|
|
24593
25217
|
const fileViewer = new RemoteFileViewerBridge(
|
|
24594
25218
|
() => this.fileViewerHost?.(),
|
|
@@ -24598,6 +25222,8 @@ var HostPluginRuntime = class {
|
|
|
24598
25222
|
context,
|
|
24599
25223
|
(event, data) => send(createEvent(event, data))
|
|
24600
25224
|
);
|
|
25225
|
+
const adapters = (config.acp?.backends ?? []).filter((item) => item.enabled && this.acpAvailable(item.command)).map((item) => new StdioAcpAdapter(item));
|
|
25226
|
+
const acp = config.acp?.enabled && adapters.length > 0 ? new AcpGateway(adapters) : void 0;
|
|
24601
25227
|
return new RpcRouter(
|
|
24602
25228
|
harnessApi,
|
|
24603
25229
|
void 0,
|
|
@@ -24605,7 +25231,8 @@ var HostPluginRuntime = class {
|
|
|
24605
25231
|
fileViewer,
|
|
24606
25232
|
harnessRemote,
|
|
24607
25233
|
() => this.hostCapabilities(),
|
|
24608
|
-
codex
|
|
25234
|
+
codex,
|
|
25235
|
+
acp
|
|
24609
25236
|
);
|
|
24610
25237
|
}, this.logger);
|
|
24611
25238
|
if (config.serverUrl !== void 0) {
|
|
@@ -24658,9 +25285,21 @@ var HostPluginRuntime = class {
|
|
|
24658
25285
|
...error === void 0 ? {} : { error },
|
|
24659
25286
|
...authorization?.account === void 0 ? {} : { account: authorization.account },
|
|
24660
25287
|
authorized: authorization !== void 0,
|
|
24661
|
-
accountRequired: error === "ACCOUNT_AUTH_REQUIRED" || error === "AUTH_INVALID" || error === "TOKEN_EXPIRED"
|
|
25288
|
+
accountRequired: error === "ACCOUNT_AUTH_REQUIRED" || error === "AUTH_INVALID" || error === "TOKEN_EXPIRED",
|
|
25289
|
+
connectedClients: this.listConnectedClients()
|
|
24662
25290
|
};
|
|
24663
25291
|
}
|
|
25292
|
+
listConnectedClients() {
|
|
25293
|
+
return this.connections.connectedPeers().map((peer) => {
|
|
25294
|
+
const trusted = this.identities.trustedPeer(peer.deviceId);
|
|
25295
|
+
return {
|
|
25296
|
+
deviceId: peer.deviceId,
|
|
25297
|
+
name: trusted?.name.trim() ?? "",
|
|
25298
|
+
...trusted === void 0 ? {} : { platform: trusted.platform },
|
|
25299
|
+
...peer.mode === void 0 ? {} : { mode: peer.mode }
|
|
25300
|
+
};
|
|
25301
|
+
});
|
|
25302
|
+
}
|
|
24664
25303
|
localHarnessVersion() {
|
|
24665
25304
|
return this.harnessVersion;
|
|
24666
25305
|
}
|
|
@@ -24838,13 +25477,25 @@ var HostPluginRuntime = class {
|
|
|
24838
25477
|
harnessSessionGeneration(this.harnessVersion) === "v3" ? "harness.remote.v3" : "harness.remote.v1",
|
|
24839
25478
|
"harness.remote.transfer.v1"
|
|
24840
25479
|
);
|
|
24841
|
-
}
|
|
25480
|
+
}
|
|
25481
|
+
if (this.apiProxy !== void 0) {
|
|
24842
25482
|
capabilities.push("harness.api.v1", "harness.api.transfer.v1");
|
|
24843
25483
|
}
|
|
24844
25484
|
if (this.fileViewerHost?.() !== void 0) capabilities.push("fileviewer.read.v1");
|
|
24845
25485
|
if (this.codex.isAvailable()) capabilities.push("codex.appserver.v1", "codex.appserver.transfer.v1");
|
|
25486
|
+
if (this.config.acp?.enabled) {
|
|
25487
|
+
for (const item of this.config.acp.backends) if (item.enabled && this.acpAvailable(item.command)) capabilities.push(`agent.acp.v1.${item.id}`);
|
|
25488
|
+
}
|
|
24846
25489
|
return capabilities;
|
|
24847
25490
|
}
|
|
25491
|
+
acpAvailable(command) {
|
|
25492
|
+
try {
|
|
25493
|
+
execFileSync2(process.platform === "win32" ? "where" : "which", [command], { stdio: "ignore" });
|
|
25494
|
+
return true;
|
|
25495
|
+
} catch {
|
|
25496
|
+
return false;
|
|
25497
|
+
}
|
|
25498
|
+
}
|
|
24848
25499
|
requireLocalCodexPeer() {
|
|
24849
25500
|
if (!this.codex.isAvailable()) {
|
|
24850
25501
|
throw new RpcError("CODEX_UNAVAILABLE", "Local CodeX is disabled or unavailable on this Host.");
|
|
@@ -25293,7 +25944,7 @@ function remoteStatusLines(target) {
|
|
|
25293
25944
|
`Device: ${status2.deviceId ?? "not initialized"}`,
|
|
25294
25945
|
`Authorization: ${status2.authorized ? status2.account === void 0 ? "logged in" : `logged in (${status2.account})` : "logged out"}`,
|
|
25295
25946
|
`Server connection: ${connection}`,
|
|
25296
|
-
`Harness Remote API: ${capabilities.has("harness.api.v1") ? "available (ApiProxy)" : capabilities.has("harness.remote.v1") ? "available (Typert Remote)" : "unavailable"}`,
|
|
25947
|
+
`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
25948
|
`Remote clients: ${diagnostics.activeConnections}`,
|
|
25298
25949
|
`Codex Remote: ${codex.enabled ? codex.state : "disabled"}`,
|
|
25299
25950
|
"",
|
|
@@ -25566,6 +26217,7 @@ function apply(ctx, input2 = {}) {
|
|
|
25566
26217
|
const activateWhenCarrierReady = (runtimeContext) => {
|
|
25567
26218
|
const gateway = runtimeContext.get("typertGateway");
|
|
25568
26219
|
const connection = runtimeContext.get("connection");
|
|
26220
|
+
const webServer = runtimeContext.get("webServer");
|
|
25569
26221
|
let disposePendingControl;
|
|
25570
26222
|
const installPendingControl = () => {
|
|
25571
26223
|
if (connection === void 0 || disposePendingControl !== void 0) return;
|
|
@@ -25577,7 +26229,7 @@ function apply(ctx, input2 = {}) {
|
|
|
25577
26229
|
void 0,
|
|
25578
26230
|
void 0
|
|
25579
26231
|
);
|
|
25580
|
-
return control.register(connection);
|
|
26232
|
+
return control.register(connection, webServer);
|
|
25581
26233
|
}, "dsh-remote pending control");
|
|
25582
26234
|
};
|
|
25583
26235
|
const startActiveRuntime = async (activeContext) => {
|
|
@@ -25611,13 +26263,14 @@ async function activate(ctx, input2, tuiBinding) {
|
|
|
25611
26263
|
reportSettingsMigration(ctx, await migration);
|
|
25612
26264
|
}
|
|
25613
26265
|
const connection = ctx.get("connection");
|
|
26266
|
+
const webServer = ctx.get("webServer");
|
|
25614
26267
|
const resolvedConfig = resolveConfig(settingsScope?.get() ?? input2);
|
|
25615
26268
|
const config = connection === void 0 && resolvedConfig.serverUrl === void 0 ? { ...resolvedConfig, serverUrl: DEFAULT_REMOTE_SERVER_URL } : resolvedConfig;
|
|
25616
26269
|
const defaultIdentityDirectory = new IdentityStore().directory;
|
|
25617
26270
|
if (!config.enabled) {
|
|
25618
26271
|
if (connection !== void 0) {
|
|
25619
26272
|
const controlRuntime2 = new PluginControlRuntime(config, defaultIdentityDirectory, settingsScope, void 0, void 0);
|
|
25620
|
-
ctx.effect(() => controlRuntime2.register(connection), "dsh-remote disabled control");
|
|
26273
|
+
ctx.effect(() => controlRuntime2.register(connection, webServer), "dsh-remote disabled control");
|
|
25621
26274
|
}
|
|
25622
26275
|
return;
|
|
25623
26276
|
}
|
|
@@ -25676,7 +26329,7 @@ async function activate(ctx, input2, tuiBinding) {
|
|
|
25676
26329
|
if (tuiBinding !== void 0) tuiBinding.target = tuiTarget;
|
|
25677
26330
|
await disableLegacyLoaderEntries(ctx, logger);
|
|
25678
26331
|
await ctx.effect(async () => {
|
|
25679
|
-
const disposeControl = controlRuntime?.register(connection);
|
|
26332
|
+
const disposeControl = controlRuntime?.register(connection, webServer);
|
|
25680
26333
|
try {
|
|
25681
26334
|
await runtime.start();
|
|
25682
26335
|
if (clientRuntime !== void 0) {
|
|
@@ -25759,6 +26412,7 @@ function isPlainRecord2(value) {
|
|
|
25759
26412
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25760
26413
|
}
|
|
25761
26414
|
export {
|
|
26415
|
+
AcpGateway,
|
|
25762
26416
|
ApiProxySwitch,
|
|
25763
26417
|
CODEX_APP_ALLOWLIST,
|
|
25764
26418
|
ClientModeError,
|