ds-harness-remote 0.4.10 → 0.4.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -4
- package/dist/client-runtime.d.ts +2 -0
- package/dist/client-runtime.d.ts.map +1 -1
- package/dist/client-runtime.js +19 -4
- package/dist/client-runtime.js.map +1 -1
- package/dist/client.github.js +1 -1
- package/dist/client.js +1 -1
- package/dist/client.js.map +1 -1
- package/dist/codex/virtual-harness.d.ts +12 -3
- package/dist/codex/virtual-harness.d.ts.map +1 -1
- package/dist/codex/virtual-harness.js +155 -37
- package/dist/codex/virtual-harness.js.map +1 -1
- package/dist/harness-version.d.ts +7 -0
- package/dist/harness-version.d.ts.map +1 -1
- package/dist/harness-version.js +16 -0
- package/dist/harness-version.js.map +1 -1
- package/dist/index.js +334 -164
- package/dist/index.js.map +4 -4
- package/dist/remote-api-proxy.d.ts.map +1 -1
- package/dist/remote-api-proxy.js +34 -1
- package/dist/remote-api-proxy.js.map +1 -1
- package/dist/service.d.ts +1 -0
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +8 -4
- package/dist/service.js.map +1 -1
- package/dist/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
|
@@ -13977,8 +13977,51 @@ function uuidV7(now = Date.now()) {
|
|
|
13977
13977
|
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
13978
13978
|
}
|
|
13979
13979
|
|
|
13980
|
+
// src/harness-version.ts
|
|
13981
|
+
import { readFile } from "node:fs/promises";
|
|
13982
|
+
import { dirname, isAbsolute, join } from "node:path";
|
|
13983
|
+
var LEGACY_PLACEHOLDER_VERSION = "0.0.1";
|
|
13984
|
+
function normalizeHarnessVersion(value) {
|
|
13985
|
+
if (typeof value !== "string") return void 0;
|
|
13986
|
+
const version = value.trim();
|
|
13987
|
+
if (version.length === 0 || version.length > 64 || /[\u0000-\u001f]/u.test(version)) return void 0;
|
|
13988
|
+
return version;
|
|
13989
|
+
}
|
|
13990
|
+
function selectHarnessVersion(reportedVersion, distributionVersion) {
|
|
13991
|
+
if (reportedVersion !== void 0 && reportedVersion !== LEGACY_PLACEHOLDER_VERSION) return reportedVersion;
|
|
13992
|
+
return distributionVersion;
|
|
13993
|
+
}
|
|
13994
|
+
function harnessSessionGeneration(version) {
|
|
13995
|
+
if (version === void 0) return "legacy";
|
|
13996
|
+
const match = /^(?:dsh-)?v?(\d+)\.(\d+)\.(\d+)(?:-|$)/u.exec(version.trim());
|
|
13997
|
+
if (match === null) return "legacy";
|
|
13998
|
+
const major = Number(match[1]);
|
|
13999
|
+
const minor = Number(match[2]);
|
|
14000
|
+
const patch = Number(match[3]);
|
|
14001
|
+
return major === 0 && minor === 1 && patch >= 5 ? "v3" : "legacy";
|
|
14002
|
+
}
|
|
14003
|
+
async function readHarnessDistributionVersion(entrypoint = process.argv[1]) {
|
|
14004
|
+
if (entrypoint === void 0 || !isAbsolute(entrypoint)) return void 0;
|
|
14005
|
+
let directory = dirname(entrypoint);
|
|
14006
|
+
for (let depth = 0; depth < 8; depth += 1) {
|
|
14007
|
+
try {
|
|
14008
|
+
const manifest = JSON.parse(await readFile(join(directory, "package.json"), "utf8"));
|
|
14009
|
+
if (manifest.name === "@deepseek-ai/dsh") return normalizeHarnessVersion(manifest.version);
|
|
14010
|
+
} catch {
|
|
14011
|
+
}
|
|
14012
|
+
const parent = dirname(directory);
|
|
14013
|
+
if (parent === directory) break;
|
|
14014
|
+
directory = parent;
|
|
14015
|
+
}
|
|
14016
|
+
return void 0;
|
|
14017
|
+
}
|
|
14018
|
+
|
|
13980
14019
|
// src/remote-api-proxy.ts
|
|
13981
14020
|
var DIRECT_API_CALL_BYTES = 2 * 1024 * 1024;
|
|
14021
|
+
var AGENT_PRESET_SETTINGS_NS = "agent-presets";
|
|
14022
|
+
var LEGACY_AGENT_PRESET_ALIASES = {
|
|
14023
|
+
code: "ptc"
|
|
14024
|
+
};
|
|
13982
14025
|
var RemoteHarnessApiProxy = class {
|
|
13983
14026
|
constructor(client) {
|
|
13984
14027
|
this.client = client;
|
|
@@ -14067,7 +14110,7 @@ var RemoteHarnessApiProxy = class {
|
|
|
14067
14110
|
const params = {
|
|
14068
14111
|
method,
|
|
14069
14112
|
rpcId: String(request.rpcId),
|
|
14070
|
-
payload: request.payload
|
|
14113
|
+
payload: normalizeLegacyRequest(method, request.payload)
|
|
14071
14114
|
};
|
|
14072
14115
|
const encoded = new TextEncoder().encode(JSON.stringify(params));
|
|
14073
14116
|
const response = method === "session.attachment" || encoded.byteLength > DIRECT_API_CALL_BYTES ? await this.callTransferred(encoded, signal) : await this.client.rpc("harness.api.call", params, signal);
|
|
@@ -14179,9 +14222,32 @@ function normalizeLegacyResponse(method, response) {
|
|
|
14179
14222
|
}
|
|
14180
14223
|
};
|
|
14181
14224
|
}
|
|
14225
|
+
function normalizeLegacyRequest(method, payload) {
|
|
14226
|
+
if (!isRecord2(payload)) return payload;
|
|
14227
|
+
if (method === "agentPreset.read") return replaceAgentPreset(payload, "agentPreset");
|
|
14228
|
+
if (method === "agentPreset.select") return replaceAgentPreset(payload, "agentPreset");
|
|
14229
|
+
if (method === "agentPreset.copy") return replaceAgentPreset(payload, "from");
|
|
14230
|
+
if (method === "settings.update" || method === "settings.replace" || method === "settings.mutate") {
|
|
14231
|
+
return replaceAgentPresetSettings(payload);
|
|
14232
|
+
}
|
|
14233
|
+
return payload;
|
|
14234
|
+
}
|
|
14235
|
+
function replaceAgentPreset(payload, key) {
|
|
14236
|
+
const value = payload[key];
|
|
14237
|
+
const replacement = typeof value === "string" ? LEGACY_AGENT_PRESET_ALIASES[value] : void 0;
|
|
14238
|
+
return replacement === void 0 ? payload : { ...payload, [key]: replacement };
|
|
14239
|
+
}
|
|
14240
|
+
function replaceAgentPresetSettings(payload) {
|
|
14241
|
+
if (payload.ns !== AGENT_PRESET_SETTINGS_NS || !isRecord2(payload.patch)) return payload;
|
|
14242
|
+
const patch = replaceAgentPreset(payload.patch, "default");
|
|
14243
|
+
return patch === payload.patch ? payload : { ...payload, patch };
|
|
14244
|
+
}
|
|
14182
14245
|
function isRemoteDisconnect(error) {
|
|
14183
14246
|
return error instanceof RemoteClientError && (error.code === "TRANSPORT_CLOSED" || error.code === "CLIENT_CLOSED");
|
|
14184
14247
|
}
|
|
14248
|
+
function isRecord2(value) {
|
|
14249
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
14250
|
+
}
|
|
14185
14251
|
var AsyncFrameQueue = class {
|
|
14186
14252
|
values = [];
|
|
14187
14253
|
waiters = [];
|
|
@@ -14416,16 +14482,16 @@ function routeStreamEvent2(event, streamId, queue) {
|
|
|
14416
14482
|
queue.fail(remoteFailure({
|
|
14417
14483
|
code: typeof failure2?.code === "string" ? failure2.code : "internal",
|
|
14418
14484
|
message: typeof failure2?.message === "string" ? failure2.message : "The remote Harness stream failed.",
|
|
14419
|
-
details:
|
|
14485
|
+
details: isRecord3(failure2?.details) ? failure2.details : {}
|
|
14420
14486
|
}));
|
|
14421
14487
|
} else {
|
|
14422
14488
|
queue.close();
|
|
14423
14489
|
}
|
|
14424
14490
|
}
|
|
14425
14491
|
function parseRpcResult(value) {
|
|
14426
|
-
if (!
|
|
14492
|
+
if (!isRecord3(value)) throw new Error("The remote Host returned an invalid Gateway result.");
|
|
14427
14493
|
if (value.ok === true) return Object.hasOwn(value, "value") ? { ok: true, value: value.value } : { ok: true };
|
|
14428
|
-
if (value.ok !== false || !
|
|
14494
|
+
if (value.ok !== false || !isRecord3(value.error) || typeof value.error.code !== "string" || typeof value.error.message !== "string" || !isRecord3(value.error.details)) {
|
|
14429
14495
|
throw new Error("The remote Host returned an invalid Gateway failure.");
|
|
14430
14496
|
}
|
|
14431
14497
|
return {
|
|
@@ -14459,7 +14525,7 @@ function base64ToBytes3(value) {
|
|
|
14459
14525
|
if (bytesToBase643(bytes) !== value) throw new Error("The remote Host returned non-canonical Harness Remote transfer data.");
|
|
14460
14526
|
return bytes;
|
|
14461
14527
|
}
|
|
14462
|
-
function
|
|
14528
|
+
function isRecord3(value) {
|
|
14463
14529
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
14464
14530
|
}
|
|
14465
14531
|
function hasErrorCode(error, code) {
|
|
@@ -14510,9 +14576,10 @@ async function discoverCodexVirtualWorkspaces(client, signal) {
|
|
|
14510
14576
|
return (await loadCatalog(client, signal)).workspaces;
|
|
14511
14577
|
}
|
|
14512
14578
|
var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
14513
|
-
constructor(client, host) {
|
|
14579
|
+
constructor(client, host, sessionGeneration = "legacy") {
|
|
14514
14580
|
this.client = client;
|
|
14515
14581
|
this.host = host;
|
|
14582
|
+
this.sessionGeneration = sessionGeneration;
|
|
14516
14583
|
this.api = this.createApiProxy();
|
|
14517
14584
|
}
|
|
14518
14585
|
api;
|
|
@@ -14536,8 +14603,8 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14536
14603
|
commandSeq = 0;
|
|
14537
14604
|
selectedWorkspaceId;
|
|
14538
14605
|
closed = false;
|
|
14539
|
-
static remote(core, host) {
|
|
14540
|
-
return new _CodexVirtualHarness(new CodexRemoteClient(core), host);
|
|
14606
|
+
static remote(core, host, sessionGeneration = "legacy") {
|
|
14607
|
+
return new _CodexVirtualHarness(new CodexRemoteClient(core), host, sessionGeneration);
|
|
14541
14608
|
}
|
|
14542
14609
|
async workspaces(signal) {
|
|
14543
14610
|
return (await this.refreshCatalog(signal)).workspaces;
|
|
@@ -14927,6 +14994,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14927
14994
|
streamedBlocks: /* @__PURE__ */ new Map(),
|
|
14928
14995
|
nextBlockIndex: 0,
|
|
14929
14996
|
streamActive: false,
|
|
14997
|
+
assistantStreamRevision: 0,
|
|
14930
14998
|
liveItems: /* @__PURE__ */ new Map(),
|
|
14931
14999
|
liveToolOutput: /* @__PURE__ */ new Map(),
|
|
14932
15000
|
liveToolResultSeq: /* @__PURE__ */ new Map(),
|
|
@@ -14950,7 +15018,8 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14950
15018
|
permissions: codexPermissionsProjection(this.permissionSelection(sessionId)),
|
|
14951
15019
|
imageLimits: codexImageLimitsProjection()
|
|
14952
15020
|
}
|
|
14953
|
-
}
|
|
15021
|
+
},
|
|
15022
|
+
...this.sessionGeneration === "v3" ? { assistantStream: { revision: 0 } } : {}
|
|
14954
15023
|
});
|
|
14955
15024
|
try {
|
|
14956
15025
|
const stream = await this.client.subscribe(
|
|
@@ -14988,6 +15057,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14988
15057
|
}
|
|
14989
15058
|
if (frame.method === "turn/started") {
|
|
14990
15059
|
const turn = record2(params.turn);
|
|
15060
|
+
this.endAssistantAttempt(follow, { kind: "abandoned" });
|
|
14991
15061
|
this.resetLiveTurn(follow);
|
|
14992
15062
|
follow.turn += 1;
|
|
14993
15063
|
follow.activeTurnId = string(turn.id);
|
|
@@ -15103,6 +15173,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15103
15173
|
if (follow.stepOpen) {
|
|
15104
15174
|
this.closeAllStreamBlocks(follow);
|
|
15105
15175
|
if (follow.streamActive) this.finishStream(follow);
|
|
15176
|
+
this.endAssistantAttempt(follow, { kind: "abandoned" });
|
|
15106
15177
|
this.pushEvent(follow, "step/end", { turn: follow.turn, step: 1 });
|
|
15107
15178
|
follow.stepOpen = false;
|
|
15108
15179
|
}
|
|
@@ -15141,6 +15212,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15141
15212
|
this.closeItemStreamBlocks(follow, itemId, itemText2(item));
|
|
15142
15213
|
if (type === "agentMessage" && follow.streamActive && follow.streamedBlocks.size === 0) this.finishStream(follow);
|
|
15143
15214
|
const supplementalImages = type === "agentMessage" ? follow.pendingToolImages : [];
|
|
15215
|
+
let assistantMessageSeq;
|
|
15144
15216
|
for (const event of itemEvents(
|
|
15145
15217
|
item,
|
|
15146
15218
|
follow.turn,
|
|
@@ -15152,7 +15224,17 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15152
15224
|
)) {
|
|
15153
15225
|
if (event.type === "tool/call" && follow.startedItems.has(itemId)) continue;
|
|
15154
15226
|
if (event.type === "tool/result") this.pushToolResult(follow, itemId, event);
|
|
15155
|
-
else
|
|
15227
|
+
else {
|
|
15228
|
+
const seq = this.pushEvent(follow, event.type, event.data, event.view);
|
|
15229
|
+
if (event.type === "assistant/message") assistantMessageSeq = seq;
|
|
15230
|
+
}
|
|
15231
|
+
}
|
|
15232
|
+
if (type === "agentMessage" && assistantMessageSeq !== void 0) {
|
|
15233
|
+
this.endAssistantAttempt(follow, {
|
|
15234
|
+
kind: "committed",
|
|
15235
|
+
eventType: "assistant/message",
|
|
15236
|
+
seq: assistantMessageSeq
|
|
15237
|
+
});
|
|
15156
15238
|
}
|
|
15157
15239
|
if (type === "agentMessage" && supplementalImages.length > 0) follow.pendingToolImages = [];
|
|
15158
15240
|
else if (type !== void 0 && isToolItemType2(type)) {
|
|
@@ -15169,18 +15251,21 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15169
15251
|
type,
|
|
15170
15252
|
seq,
|
|
15171
15253
|
time: Date.now(),
|
|
15172
|
-
data
|
|
15254
|
+
data: adaptEventData(
|
|
15255
|
+
type,
|
|
15256
|
+
type === "assistant/message" && this.sessionGeneration === "v3" && follow.assistantAttempt !== void 0 ? { ...record2(data), stream: follow.assistantAttempt.stream } : data,
|
|
15257
|
+
this.sessionGeneration
|
|
15258
|
+
),
|
|
15173
15259
|
...isSurfaceEvent(type) ? placement === void 0 ? { surfaceOp: "append" } : {
|
|
15174
|
-
surfaceOp: { op: "replace", start: placement.replaceSeq, end: placement.replaceSeq },
|
|
15260
|
+
surfaceOp: this.sessionGeneration === "v3" ? { op: "replace", startSeq: placement.replaceSeq, endSeq: placement.replaceSeq } : { op: "replace", start: placement.replaceSeq, end: placement.replaceSeq },
|
|
15175
15261
|
sourceEventSeqs: [placement.replaceSeq]
|
|
15176
15262
|
} : {}
|
|
15177
15263
|
};
|
|
15178
15264
|
this.cacheImageBlocks(follow.sessionId, event.data);
|
|
15179
15265
|
if (!follow.rcOnly) {
|
|
15180
|
-
const alphaEvent = typeof event.surfaceOp === "object" ? { ...event, surfaceOp: "replace" } : event;
|
|
15181
15266
|
follow.queue.push({
|
|
15182
15267
|
type: "event",
|
|
15183
|
-
event
|
|
15268
|
+
event,
|
|
15184
15269
|
...view === void 0 ? {} : { view }
|
|
15185
15270
|
});
|
|
15186
15271
|
}
|
|
@@ -15207,52 +15292,105 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15207
15292
|
const block = { itemId, index: follow.nextBlockIndex++, kind, text: "" };
|
|
15208
15293
|
follow.streamedBlocks.set(key, block);
|
|
15209
15294
|
follow.streamActive = true;
|
|
15210
|
-
this.
|
|
15211
|
-
turn: follow.turn,
|
|
15212
|
-
step: 1,
|
|
15213
|
-
chunk: { type: "block-start", index: block.index, blockType: kind }
|
|
15214
|
-
});
|
|
15295
|
+
this.pushAssistantChunk(follow, { type: "block-start", index: block.index, blockType: kind });
|
|
15215
15296
|
return block;
|
|
15216
15297
|
}
|
|
15217
15298
|
appendStreamDelta(follow, key, itemId, kind, delta) {
|
|
15218
15299
|
const block = this.ensureStreamBlock(follow, key, itemId, kind);
|
|
15219
15300
|
block.text = appendBoundedText(block.text, delta);
|
|
15220
|
-
this.
|
|
15221
|
-
|
|
15222
|
-
|
|
15223
|
-
|
|
15301
|
+
this.pushAssistantChunk(follow, {
|
|
15302
|
+
type: kind === "reasoning" ? "reasoning-delta" : "text-delta",
|
|
15303
|
+
index: block.index,
|
|
15304
|
+
text: delta
|
|
15224
15305
|
});
|
|
15225
15306
|
}
|
|
15226
15307
|
closeItemStreamBlocks(follow, itemId, fallback) {
|
|
15227
15308
|
const matches = [...follow.streamedBlocks].filter(([, block]) => block.itemId === itemId);
|
|
15228
15309
|
for (const [key, block] of matches) {
|
|
15229
15310
|
const text = block.text || fallback || "";
|
|
15230
|
-
this.
|
|
15231
|
-
|
|
15232
|
-
|
|
15233
|
-
|
|
15311
|
+
this.pushAssistantChunk(follow, {
|
|
15312
|
+
type: "block-end",
|
|
15313
|
+
index: block.index,
|
|
15314
|
+
block: { type: block.kind, text }
|
|
15234
15315
|
});
|
|
15235
15316
|
follow.streamedBlocks.delete(key);
|
|
15236
15317
|
}
|
|
15237
15318
|
}
|
|
15238
15319
|
closeAllStreamBlocks(follow) {
|
|
15239
15320
|
for (const block of follow.streamedBlocks.values()) {
|
|
15240
|
-
this.
|
|
15241
|
-
|
|
15242
|
-
|
|
15243
|
-
|
|
15321
|
+
this.pushAssistantChunk(follow, {
|
|
15322
|
+
type: "block-end",
|
|
15323
|
+
index: block.index,
|
|
15324
|
+
block: { type: block.kind, text: block.text }
|
|
15244
15325
|
});
|
|
15245
15326
|
}
|
|
15246
15327
|
follow.streamedBlocks.clear();
|
|
15247
15328
|
}
|
|
15248
15329
|
finishStream(follow) {
|
|
15249
|
-
this.
|
|
15250
|
-
turn: follow.turn,
|
|
15251
|
-
step: 1,
|
|
15252
|
-
chunk: { type: "finish", reason: { kind: "stop" } }
|
|
15253
|
-
});
|
|
15330
|
+
this.pushAssistantChunk(follow, { type: "finish", reason: { kind: "stop" } });
|
|
15254
15331
|
follow.streamActive = false;
|
|
15255
15332
|
}
|
|
15333
|
+
pushAssistantChunk(follow, chunk) {
|
|
15334
|
+
if (this.sessionGeneration !== "v3" || follow.rcOnly === true) {
|
|
15335
|
+
this.pushEvent(follow, "assistant/chunk", { turn: follow.turn, step: 1, chunk });
|
|
15336
|
+
return;
|
|
15337
|
+
}
|
|
15338
|
+
let attempt = follow.assistantAttempt;
|
|
15339
|
+
if (attempt === void 0) {
|
|
15340
|
+
attempt = {
|
|
15341
|
+
attemptId: `codex-attempt:${follow.activeTurnId ?? follow.turn}:${follow.nextSeq}`,
|
|
15342
|
+
startedAfterSeq: follow.nextSeq - 1,
|
|
15343
|
+
nextIndex: 0,
|
|
15344
|
+
stream: []
|
|
15345
|
+
};
|
|
15346
|
+
follow.assistantAttempt = attempt;
|
|
15347
|
+
follow.assistantStreamRevision += 1;
|
|
15348
|
+
follow.queue.push({
|
|
15349
|
+
type: "assistant-stream",
|
|
15350
|
+
frame: {
|
|
15351
|
+
type: "start",
|
|
15352
|
+
attemptId: attempt.attemptId,
|
|
15353
|
+
revision: follow.assistantStreamRevision,
|
|
15354
|
+
startedAfterSeq: attempt.startedAfterSeq,
|
|
15355
|
+
turn: follow.turn,
|
|
15356
|
+
step: 1
|
|
15357
|
+
}
|
|
15358
|
+
});
|
|
15359
|
+
}
|
|
15360
|
+
const time = Date.now();
|
|
15361
|
+
const index = attempt.nextIndex++;
|
|
15362
|
+
attempt.stream.push({ time, chunk });
|
|
15363
|
+
follow.assistantStreamRevision += 1;
|
|
15364
|
+
follow.queue.push({
|
|
15365
|
+
type: "assistant-stream",
|
|
15366
|
+
frame: {
|
|
15367
|
+
type: "chunk",
|
|
15368
|
+
attemptId: attempt.attemptId,
|
|
15369
|
+
revision: follow.assistantStreamRevision,
|
|
15370
|
+
index,
|
|
15371
|
+
time,
|
|
15372
|
+
chunk
|
|
15373
|
+
}
|
|
15374
|
+
});
|
|
15375
|
+
}
|
|
15376
|
+
endAssistantAttempt(follow, outcome) {
|
|
15377
|
+
const attempt = follow.assistantAttempt;
|
|
15378
|
+
if (attempt === void 0) return;
|
|
15379
|
+
follow.assistantAttempt = void 0;
|
|
15380
|
+
follow.assistantStreamRevision += 1;
|
|
15381
|
+
if (this.sessionGeneration === "v3" && follow.rcOnly !== true) {
|
|
15382
|
+
follow.queue.push({
|
|
15383
|
+
type: "assistant-stream",
|
|
15384
|
+
frame: {
|
|
15385
|
+
type: "end",
|
|
15386
|
+
attemptId: attempt.attemptId,
|
|
15387
|
+
revision: follow.assistantStreamRevision,
|
|
15388
|
+
index: attempt.nextIndex,
|
|
15389
|
+
outcome
|
|
15390
|
+
}
|
|
15391
|
+
});
|
|
15392
|
+
}
|
|
15393
|
+
}
|
|
15256
15394
|
ensureToolStarted(follow, item) {
|
|
15257
15395
|
const itemId = string(item.id);
|
|
15258
15396
|
if (itemId === void 0) return;
|
|
@@ -15295,6 +15433,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15295
15433
|
follow.streamedBlocks.clear();
|
|
15296
15434
|
follow.nextBlockIndex = 0;
|
|
15297
15435
|
follow.streamActive = false;
|
|
15436
|
+
follow.assistantAttempt = void 0;
|
|
15298
15437
|
follow.liveItems.clear();
|
|
15299
15438
|
follow.liveToolOutput.clear();
|
|
15300
15439
|
follow.liveToolResultSeq.clear();
|
|
@@ -15307,7 +15446,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15307
15446
|
this.broadcastRcHost({ type: "host/session-status", sessionId, running: args[1] });
|
|
15308
15447
|
} else if (event === "api-session/removed" && sessionId !== void 0) {
|
|
15309
15448
|
this.broadcastRcHost({ type: "host/session-removed", sessionId });
|
|
15310
|
-
} else if (event === "api-session/added" &&
|
|
15449
|
+
} else if (event === "api-session/added" && isRecord4(args[0])) {
|
|
15311
15450
|
const summary = args[0];
|
|
15312
15451
|
this.broadcastRcHost({
|
|
15313
15452
|
type: "host/session-added",
|
|
@@ -15565,7 +15704,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15565
15704
|
const thread = record2(result.thread);
|
|
15566
15705
|
if (string(thread.id) !== threadId) throw new Error("CodeX returned an invalid Thread history.");
|
|
15567
15706
|
value = paginateCodexNativeHistory(
|
|
15568
|
-
projectCodexNativeHistory(thread, `codex:${threadId}
|
|
15707
|
+
projectCodexNativeHistory(thread, `codex:${threadId}`, this.sessionGeneration),
|
|
15569
15708
|
{
|
|
15570
15709
|
beforeSeq: page.beforeSeq,
|
|
15571
15710
|
throughSeq: page.throughSeq,
|
|
@@ -15573,6 +15712,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15573
15712
|
}
|
|
15574
15713
|
);
|
|
15575
15714
|
}
|
|
15715
|
+
value = adaptCodexHistoryPage(value, this.sessionGeneration);
|
|
15576
15716
|
if (!isCodexNativeHistoryPage(value, `codex:${threadId}`)) {
|
|
15577
15717
|
throw new Error("CodeX Remote returned an invalid paginated History.");
|
|
15578
15718
|
}
|
|
@@ -15640,6 +15780,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15640
15780
|
streamedBlocks: /* @__PURE__ */ new Map(),
|
|
15641
15781
|
nextBlockIndex: 0,
|
|
15642
15782
|
streamActive: false,
|
|
15783
|
+
assistantStreamRevision: 0,
|
|
15643
15784
|
liveItems: /* @__PURE__ */ new Map(),
|
|
15644
15785
|
liveToolOutput: /* @__PURE__ */ new Map(),
|
|
15645
15786
|
liveToolResultSeq: /* @__PURE__ */ new Map(),
|
|
@@ -15690,7 +15831,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15690
15831
|
}
|
|
15691
15832
|
createApiProxy() {
|
|
15692
15833
|
const call = (endpoint) => async (request, signal) => {
|
|
15693
|
-
const payload = endpoint === "session.prompt" &&
|
|
15834
|
+
const payload = endpoint === "session.prompt" && isRecord4(request.payload) ? { ...request.payload, requestId: String(request.rpcId) } : request.payload;
|
|
15694
15835
|
const result = await this.dispatch(rcEndpoint(endpoint), { args: { request: payload } }, signal ?? new AbortController().signal);
|
|
15695
15836
|
return {
|
|
15696
15837
|
rpcId: request.rpcId,
|
|
@@ -15922,7 +16063,7 @@ async function loadModelDirectory(client, signal) {
|
|
|
15922
16063
|
models
|
|
15923
16064
|
};
|
|
15924
16065
|
}
|
|
15925
|
-
function projectCodexNativeHistory(thread, sessionId) {
|
|
16066
|
+
function projectCodexNativeHistory(thread, sessionId, sessionGeneration = "legacy") {
|
|
15926
16067
|
const entries = [];
|
|
15927
16068
|
let seq = 0;
|
|
15928
16069
|
let turnNumber = 0;
|
|
@@ -15935,7 +16076,7 @@ function projectCodexNativeHistory(thread, sessionId) {
|
|
|
15935
16076
|
type,
|
|
15936
16077
|
seq: eventSeq,
|
|
15937
16078
|
time,
|
|
15938
|
-
data,
|
|
16079
|
+
data: adaptEventData(type, data, sessionGeneration),
|
|
15939
16080
|
...sourceEventSeqs === void 0 ? {} : { sourceEventSeqs },
|
|
15940
16081
|
...isSurfaceEvent(type) ? { surfaceOp: "append" } : {}
|
|
15941
16082
|
},
|
|
@@ -15988,10 +16129,11 @@ function projectCodexNativeHistory(thread, sessionId) {
|
|
|
15988
16129
|
const projected = projectCodexThread(thread);
|
|
15989
16130
|
return {
|
|
15990
16131
|
header: {
|
|
15991
|
-
version: 1,
|
|
16132
|
+
version: sessionGeneration === "v3" ? 3 : 1,
|
|
15992
16133
|
id: sessionId,
|
|
15993
16134
|
createdAt: projected?.createdAt ?? Date.now(),
|
|
15994
|
-
...projected?.cwd === void 0 ? {} : { cwd: projected.cwd }
|
|
16135
|
+
...projected?.cwd === void 0 ? {} : { cwd: projected.cwd },
|
|
16136
|
+
...sessionGeneration === "v3" ? { isSeeded: false } : {}
|
|
15995
16137
|
},
|
|
15996
16138
|
entries,
|
|
15997
16139
|
lastSeq: seq - 1,
|
|
@@ -16024,6 +16166,40 @@ function paginateCodexNativeHistory(history, request) {
|
|
|
16024
16166
|
...history.activeTurnId === void 0 ? {} : { activeTurnId: history.activeTurnId }
|
|
16025
16167
|
};
|
|
16026
16168
|
}
|
|
16169
|
+
function adaptEventData(type, data, sessionGeneration) {
|
|
16170
|
+
if (sessionGeneration !== "v3" || type !== "assistant/message") return data;
|
|
16171
|
+
const value = record2(data);
|
|
16172
|
+
return Array.isArray(value.stream) ? value : { ...value, stream: [] };
|
|
16173
|
+
}
|
|
16174
|
+
function adaptCodexHistoryPage(value, sessionGeneration) {
|
|
16175
|
+
if (sessionGeneration !== "v3") return value;
|
|
16176
|
+
const page = record2(value);
|
|
16177
|
+
const sourceHeader = record2(page.header);
|
|
16178
|
+
const { seedLength: _seedLength, ...header } = sourceHeader;
|
|
16179
|
+
const records = Array.isArray(page.records) ? page.records.map((raw) => {
|
|
16180
|
+
const entry = record2(raw);
|
|
16181
|
+
const sourceEvent = record2(entry.event);
|
|
16182
|
+
const sourceSurfaceOp = record2(sourceEvent.surfaceOp);
|
|
16183
|
+
const surfaceOp = sourceEvent.surfaceOp === "append" ? "append" : sourceSurfaceOp.op === "replace" && integer(sourceSurfaceOp.startSeq) !== void 0 && integer(sourceSurfaceOp.endSeq) !== void 0 ? sourceSurfaceOp : sourceSurfaceOp.op === "replace" && integer(sourceSurfaceOp.start) !== void 0 && integer(sourceSurfaceOp.end) !== void 0 ? {
|
|
16184
|
+
op: "replace",
|
|
16185
|
+
startSeq: sourceSurfaceOp.start,
|
|
16186
|
+
endSeq: sourceSurfaceOp.end
|
|
16187
|
+
} : sourceEvent.surfaceOp;
|
|
16188
|
+
return {
|
|
16189
|
+
...entry,
|
|
16190
|
+
event: {
|
|
16191
|
+
...sourceEvent,
|
|
16192
|
+
data: adaptEventData(string(sourceEvent.type) ?? "", sourceEvent.data, sessionGeneration),
|
|
16193
|
+
...surfaceOp === void 0 ? {} : { surfaceOp }
|
|
16194
|
+
}
|
|
16195
|
+
};
|
|
16196
|
+
}) : page.records;
|
|
16197
|
+
return {
|
|
16198
|
+
...page,
|
|
16199
|
+
header: { ...header, version: 3, isSeeded: sourceHeader.isSeeded === true },
|
|
16200
|
+
records
|
|
16201
|
+
};
|
|
16202
|
+
}
|
|
16027
16203
|
function itemEvents(item, turn, step, requestId, selection = modelSelection(), sessionId = CODEX_SESSION_PREFIX, supplementalImages = []) {
|
|
16028
16204
|
const type = string(item.type);
|
|
16029
16205
|
const id2 = string(item.id) ?? `${turn}:${step}:${hashString(JSON.stringify(item))}`;
|
|
@@ -16180,7 +16356,7 @@ function collectImageBlocks(value, output = []) {
|
|
|
16180
16356
|
for (const item of value) collectImageBlocks(item, output);
|
|
16181
16357
|
return output;
|
|
16182
16358
|
}
|
|
16183
|
-
if (!
|
|
16359
|
+
if (!isRecord4(value)) return output;
|
|
16184
16360
|
if (value.type === "image") output.push(value);
|
|
16185
16361
|
for (const [key, child] of Object.entries(value)) {
|
|
16186
16362
|
if (key === "attachment") continue;
|
|
@@ -16510,7 +16686,7 @@ function codexPromptInput(content) {
|
|
|
16510
16686
|
if (content.length === 0 || content.length > MAX_CODEX_PROMPT_PARTS) return void 0;
|
|
16511
16687
|
const input2 = [];
|
|
16512
16688
|
for (const value of content) {
|
|
16513
|
-
if (!
|
|
16689
|
+
if (!isRecord4(value)) return void 0;
|
|
16514
16690
|
if (value.type === "text") {
|
|
16515
16691
|
if (typeof value.text !== "string" || value.text.length === 0 || value.text.length > MAX_CODEX_PROMPT_TEXT) return void 0;
|
|
16516
16692
|
input2.push({ type: "text", text: value.text });
|
|
@@ -16763,12 +16939,12 @@ function errorCode(error) {
|
|
|
16763
16939
|
return "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
16764
16940
|
}
|
|
16765
16941
|
function errorDetails(error) {
|
|
16766
|
-
return "details" in error &&
|
|
16942
|
+
return "details" in error && isRecord4(error.details) ? error.details : {};
|
|
16767
16943
|
}
|
|
16768
16944
|
function record2(value) {
|
|
16769
|
-
return
|
|
16945
|
+
return isRecord4(value) ? value : {};
|
|
16770
16946
|
}
|
|
16771
|
-
function
|
|
16947
|
+
function isRecord4(value) {
|
|
16772
16948
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16773
16949
|
}
|
|
16774
16950
|
function array(value) {
|
|
@@ -16982,7 +17158,7 @@ function normalizeServerUrl(value) {
|
|
|
16982
17158
|
}
|
|
16983
17159
|
|
|
16984
17160
|
// src/version.ts
|
|
16985
|
-
var PLUGIN_VERSION = "0.4.
|
|
17161
|
+
var PLUGIN_VERSION = "0.4.12";
|
|
16986
17162
|
|
|
16987
17163
|
// src/server-api.ts
|
|
16988
17164
|
var TERMINAL_CONTROL_CHARACTERS = /[\u0000-\u001f\u007f-\u009f]/u;
|
|
@@ -17501,7 +17677,7 @@ var TypertGatewaySwitch = class {
|
|
|
17501
17677
|
if (normalized !== void 0) return normalized;
|
|
17502
17678
|
const source = error instanceof Error ? error : new Error("The Harness Gateway rejected the request.");
|
|
17503
17679
|
const code = "code" in source && typeof source.code === "string" ? source.code : "internal";
|
|
17504
|
-
const details = "details" in source &&
|
|
17680
|
+
const details = "details" in source && isRecord5(source.details) ? source.details : {};
|
|
17505
17681
|
return { code, message: source.message, details };
|
|
17506
17682
|
}
|
|
17507
17683
|
};
|
|
@@ -17510,7 +17686,7 @@ function requestFromCarrier(endpoint, payload, signal) {
|
|
|
17510
17686
|
if (segments.length !== 2 || segments.some((segment) => segment.length === 0)) {
|
|
17511
17687
|
throw new Error("The Harness Gateway endpoint is invalid.");
|
|
17512
17688
|
}
|
|
17513
|
-
if (!
|
|
17689
|
+
if (!isRecord5(payload) || !isRecord5(payload.args)) {
|
|
17514
17690
|
throw new Error("The Harness Gateway payload is invalid.");
|
|
17515
17691
|
}
|
|
17516
17692
|
return { namespace: segments[0], method: segments[1], args: payload.args, signal };
|
|
@@ -17525,7 +17701,7 @@ function isLocalOnlyEndpoint(endpoint) {
|
|
|
17525
17701
|
function isRemoteCommandMethod(method) {
|
|
17526
17702
|
return REMOTE_COMMAND_METHODS.includes(method);
|
|
17527
17703
|
}
|
|
17528
|
-
function
|
|
17704
|
+
function isRecord5(value) {
|
|
17529
17705
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17530
17706
|
}
|
|
17531
17707
|
|
|
@@ -17536,7 +17712,7 @@ import { networkInterfaces } from "node:os";
|
|
|
17536
17712
|
// src/native-rtc-helper.ts
|
|
17537
17713
|
import { spawn, spawnSync } from "node:child_process";
|
|
17538
17714
|
import { existsSync, readdirSync, realpathSync, statSync } from "node:fs";
|
|
17539
|
-
import { delimiter, dirname, join } from "node:path";
|
|
17715
|
+
import { delimiter, dirname as dirname2, join as join2 } from "node:path";
|
|
17540
17716
|
import { fileURLToPath } from "node:url";
|
|
17541
17717
|
var cachedExternalFactory;
|
|
17542
17718
|
var cachedExternalFactoryResolved = false;
|
|
@@ -17587,21 +17763,21 @@ function nodeBinaryCandidates() {
|
|
|
17587
17763
|
add3(process.env.DSH_REMOTE_NODE);
|
|
17588
17764
|
add3(process.env.NODE);
|
|
17589
17765
|
add3(process.execPath);
|
|
17590
|
-
for (const part of (process.env.PATH ?? "").split(delimiter)) add3(
|
|
17766
|
+
for (const part of (process.env.PATH ?? "").split(delimiter)) add3(join2(part, process.platform === "win32" ? "node.exe" : "node"));
|
|
17591
17767
|
add3("/opt/homebrew/bin/node");
|
|
17592
17768
|
add3("/usr/local/bin/node");
|
|
17593
17769
|
add3("/usr/bin/node");
|
|
17594
|
-
add3(
|
|
17595
|
-
add3(
|
|
17596
|
-
add3(
|
|
17770
|
+
add3(join2(process.env.HOME ?? "", ".volta", "bin", process.platform === "win32" ? "node.exe" : "node"));
|
|
17771
|
+
add3(join2(process.env.HOME ?? "", ".asdf", "shims", process.platform === "win32" ? "node.exe" : "node"));
|
|
17772
|
+
add3(join2(process.env.HOME ?? "", ".local", "bin", process.platform === "win32" ? "node.exe" : "node"));
|
|
17597
17773
|
for (const nvmNode of nvmNodeCandidates()) add3(nvmNode);
|
|
17598
17774
|
return candidates;
|
|
17599
17775
|
}
|
|
17600
17776
|
function nvmNodeCandidates() {
|
|
17601
|
-
const root =
|
|
17777
|
+
const root = join2(process.env.HOME ?? "", ".nvm", "versions", "node");
|
|
17602
17778
|
if (root === "" || !existsSync(root)) return [];
|
|
17603
17779
|
try {
|
|
17604
|
-
return readdirSync(root).map((version) =>
|
|
17780
|
+
return readdirSync(root).map((version) => join2(root, version, "bin", process.platform === "win32" ? "node.exe" : "node")).sort((left, right) => right.localeCompare(left, "en", { numeric: true }));
|
|
17605
17781
|
} catch {
|
|
17606
17782
|
return [];
|
|
17607
17783
|
}
|
|
@@ -17623,7 +17799,7 @@ function isUsableExternalNode(candidate, requireFrom) {
|
|
|
17623
17799
|
"console.log(`node:${process.versions.node}`);"
|
|
17624
17800
|
].join("")
|
|
17625
17801
|
], {
|
|
17626
|
-
cwd:
|
|
17802
|
+
cwd: dirname2(requireFrom),
|
|
17627
17803
|
env,
|
|
17628
17804
|
encoding: "utf8",
|
|
17629
17805
|
timeout: 3e3
|
|
@@ -17645,7 +17821,7 @@ var ExternalNativePeerConnection = class {
|
|
|
17645
17821
|
this.nodeBinary = nodeBinary;
|
|
17646
17822
|
this.requireFrom = requireFrom;
|
|
17647
17823
|
this.child = spawn(this.nodeBinary, ["--input-type=module", "--eval", HELPER_SOURCE], {
|
|
17648
|
-
cwd:
|
|
17824
|
+
cwd: dirname2(this.requireFrom),
|
|
17649
17825
|
env: { ...process.env, DSH_REMOTE_RTC_HELPER_REQUIRE_FROM: this.requireFrom },
|
|
17650
17826
|
stdio: ["pipe", "pipe", "pipe"]
|
|
17651
17827
|
});
|
|
@@ -18855,7 +19031,7 @@ var ClientModeRuntime = class {
|
|
|
18855
19031
|
const virtual = CodexVirtualHarness.remote(remote.client, {
|
|
18856
19032
|
deviceId: remote.target.deviceId,
|
|
18857
19033
|
name: remote.target.name
|
|
18858
|
-
});
|
|
19034
|
+
}, harnessSessionGeneration(this.host?.localHarnessVersion?.()));
|
|
18859
19035
|
let workspace;
|
|
18860
19036
|
try {
|
|
18861
19037
|
workspace = await virtual.selectWorkspace(workspaceId, signal);
|
|
@@ -18972,10 +19148,10 @@ var ClientModeRuntime = class {
|
|
|
18972
19148
|
}
|
|
18973
19149
|
}
|
|
18974
19150
|
stream.unsubscribe = remote.client.onEvent((event) => {
|
|
18975
|
-
if (event.event === "codex.app.frame" &&
|
|
19151
|
+
if (event.event === "codex.app.frame" && isRecord6(event.data) && event.data.streamId === value.streamId) {
|
|
18976
19152
|
this.appendCodexFrame(stream, event.data);
|
|
18977
19153
|
}
|
|
18978
|
-
if (event.event === "codex.app.stream.closed" &&
|
|
19154
|
+
if (event.event === "codex.app.stream.closed" && isRecord6(event.data) && event.data.streamId === value.streamId) {
|
|
18979
19155
|
stream.closed = typeof event.data.reason === "string" ? event.data.reason : "closed";
|
|
18980
19156
|
stream.wake();
|
|
18981
19157
|
}
|
|
@@ -19002,7 +19178,7 @@ var ClientModeRuntime = class {
|
|
|
19002
19178
|
stream.wake();
|
|
19003
19179
|
};
|
|
19004
19180
|
appendCodexFrame(stream, data) {
|
|
19005
|
-
if (!
|
|
19181
|
+
if (!isRecord6(data) || !isRecord6(data.frame) || typeof data.frame.method !== "string") return;
|
|
19006
19182
|
if (stream.frames.length >= 256) {
|
|
19007
19183
|
stream.closed = "overflow";
|
|
19008
19184
|
} else {
|
|
@@ -19087,7 +19263,16 @@ var ClientModeRuntime = class {
|
|
|
19087
19263
|
}
|
|
19088
19264
|
assertRemoteCompatible(remote) {
|
|
19089
19265
|
const localRemoteGateway = this.gatewaySwitch.supportsCarrier();
|
|
19090
|
-
if (localRemoteGateway && remote.features.remoteGateway
|
|
19266
|
+
if (localRemoteGateway && remote.features.remoteGateway) {
|
|
19267
|
+
const localSessionGeneration = harnessSessionGeneration(this.host?.localHarnessVersion?.());
|
|
19268
|
+
const remoteSessionGeneration = remote.features.sessionFormat === 3 ? "v3" : "legacy";
|
|
19269
|
+
if (localSessionGeneration === remoteSessionGeneration) return;
|
|
19270
|
+
throw new ClientModeError(
|
|
19271
|
+
"HARNESS_VERSION_INCOMPATIBLE",
|
|
19272
|
+
`The local and remote Harness Session formats differ (${localSessionGeneration} vs ${remoteSessionGeneration}).`
|
|
19273
|
+
);
|
|
19274
|
+
}
|
|
19275
|
+
if (!localRemoteGateway && this.proxySwitch !== void 0 && remote.features.apiProxy) return;
|
|
19091
19276
|
throw new ClientModeError(
|
|
19092
19277
|
"HARNESS_VERSION_INCOMPATIBLE",
|
|
19093
19278
|
localRemoteGateway ? "The selected Host does not provide the Harness v0.1.2 Typert Remote Gateway transport." : "The selected Host does not provide the legacy Harness ApiProxy transport."
|
|
@@ -19216,7 +19401,8 @@ var ClientModeRuntime = class {
|
|
|
19216
19401
|
transport: connectedTransport,
|
|
19217
19402
|
features,
|
|
19218
19403
|
progressRunId,
|
|
19219
|
-
...serverDevice.clientVersion === void 0 ? {} : { clientVersion: serverDevice.clientVersion }
|
|
19404
|
+
...serverDevice.clientVersion === void 0 ? {} : { clientVersion: serverDevice.clientVersion },
|
|
19405
|
+
...serverDevice.harnessVersion === void 0 ? {} : { harnessVersion: serverDevice.harnessVersion }
|
|
19220
19406
|
};
|
|
19221
19407
|
} catch (error) {
|
|
19222
19408
|
this.clearConnectionProgress(progressRunId);
|
|
@@ -19468,7 +19654,7 @@ function record3(value) {
|
|
|
19468
19654
|
}
|
|
19469
19655
|
return value;
|
|
19470
19656
|
}
|
|
19471
|
-
function
|
|
19657
|
+
function isRecord6(value) {
|
|
19472
19658
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19473
19659
|
}
|
|
19474
19660
|
function ok2(value) {
|
|
@@ -19493,11 +19679,11 @@ async function readRemoteWorkspaceBaseline(gateway, signal) {
|
|
|
19493
19679
|
const iterator = source[Symbol.asyncIterator]();
|
|
19494
19680
|
try {
|
|
19495
19681
|
const first = await iterator.next();
|
|
19496
|
-
if (first.done || !
|
|
19682
|
+
if (first.done || !isRecord6(first.value) || first.value.type !== "baseline" || !isRecord6(first.value.value) || !Array.isArray(first.value.value.items)) {
|
|
19497
19683
|
throw new ClientModeError("INVALID_MESSAGE", "The remote Host returned an invalid Workspace baseline.");
|
|
19498
19684
|
}
|
|
19499
19685
|
return first.value.value.items.map((item) => {
|
|
19500
|
-
if (!
|
|
19686
|
+
if (!isRecord6(item) || typeof item.workspaceId !== "string" || typeof item.path !== "string" || typeof item.title !== "string") {
|
|
19501
19687
|
throw new ClientModeError("INVALID_MESSAGE", "The remote Host returned an invalid Workspace row.");
|
|
19502
19688
|
}
|
|
19503
19689
|
return { workspaceId: item.workspaceId, path: item.path, title: item.title };
|
|
@@ -19562,12 +19748,18 @@ async function probeRemoteHostFeatures(client, clientVersion) {
|
|
|
19562
19748
|
if (error instanceof Error && "code" in error && error.code === "METHOD_NOT_FOUND") return fallback;
|
|
19563
19749
|
throw error;
|
|
19564
19750
|
}
|
|
19565
|
-
if (!
|
|
19751
|
+
if (!isRecord6(value) || !Array.isArray(value.capabilities) || value.capabilities.some((capability) => typeof capability !== "string")) {
|
|
19566
19752
|
throw new ClientModeError("INVALID_MESSAGE", "The remote Host returned invalid transport capabilities.");
|
|
19567
19753
|
}
|
|
19568
19754
|
const capabilities = new Set(value.capabilities);
|
|
19569
19755
|
const apiProxy = capabilities.has("harness.api.v1");
|
|
19570
|
-
const
|
|
19756
|
+
const remoteV1 = capabilities.has("harness.remote.v1");
|
|
19757
|
+
const remoteV3 = capabilities.has("harness.remote.v3");
|
|
19758
|
+
if (remoteV1 && remoteV3) {
|
|
19759
|
+
throw new ClientModeError("INVALID_MESSAGE", "The remote Host advertised conflicting Harness Session formats.");
|
|
19760
|
+
}
|
|
19761
|
+
const sessionFormat = remoteV3 ? 3 : void 0;
|
|
19762
|
+
const remoteGateway = remoteV3 || remoteV1;
|
|
19571
19763
|
if (!apiProxy && !remoteGateway) {
|
|
19572
19764
|
throw new ClientModeError("FEATURE_NOT_SUPPORTED", "The remote Host exposes no supported Harness transport.");
|
|
19573
19765
|
}
|
|
@@ -19576,6 +19768,7 @@ async function probeRemoteHostFeatures(client, clientVersion) {
|
|
|
19576
19768
|
fileViewer: capabilities.has("fileviewer.read.v1"),
|
|
19577
19769
|
apiProxy,
|
|
19578
19770
|
remoteGateway,
|
|
19771
|
+
...sessionFormat === void 0 ? {} : { sessionFormat },
|
|
19579
19772
|
codex: capabilities.has("codex.appserver.v1")
|
|
19580
19773
|
};
|
|
19581
19774
|
}
|
|
@@ -19642,9 +19835,9 @@ import { hostname as hostname2 } from "node:os";
|
|
|
19642
19835
|
|
|
19643
19836
|
// src/identity-store.ts
|
|
19644
19837
|
import { createHash } from "node:crypto";
|
|
19645
|
-
import { chmod, mkdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
19838
|
+
import { chmod, mkdir, readFile as readFile2, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
19646
19839
|
import { homedir } from "node:os";
|
|
19647
|
-
import { dirname as
|
|
19840
|
+
import { dirname as dirname3, join as join3 } from "node:path";
|
|
19648
19841
|
var identitySchema = external_exports.object({
|
|
19649
19842
|
schemaVersion: external_exports.literal(1),
|
|
19650
19843
|
deviceId: external_exports.string().uuid(),
|
|
@@ -19673,14 +19866,14 @@ var IdentityStore = class {
|
|
|
19673
19866
|
peers = /* @__PURE__ */ new Map();
|
|
19674
19867
|
constructor(options = {}) {
|
|
19675
19868
|
const env = options.env ?? process.env;
|
|
19676
|
-
const dshHome = env.DSH_HOME ||
|
|
19677
|
-
this.directory = options.directory ??
|
|
19869
|
+
const dshHome = env.DSH_HOME || join3(options.homeDirectory ?? homedir(), ".dsh");
|
|
19870
|
+
this.directory = options.directory ?? join3(dshHome, "remote");
|
|
19678
19871
|
}
|
|
19679
19872
|
async loadOrCreate(deviceName) {
|
|
19680
19873
|
await mkdir(this.directory, { recursive: true, mode: 448 });
|
|
19681
19874
|
await chmod(this.directory, 448);
|
|
19682
|
-
const devicePath =
|
|
19683
|
-
const keyPath =
|
|
19875
|
+
const devicePath = join3(this.directory, "device.json");
|
|
19876
|
+
const keyPath = join3(this.directory, "device.key");
|
|
19684
19877
|
const [hasDevice, hasKey] = await Promise.all([exists(devicePath), exists(keyPath)]);
|
|
19685
19878
|
if (hasDevice !== hasKey) {
|
|
19686
19879
|
throw new IdentityInvalidError("device identity is incomplete; repair it explicitly before reconnecting");
|
|
@@ -19694,8 +19887,8 @@ var IdentityStore = class {
|
|
|
19694
19887
|
}
|
|
19695
19888
|
await assertPrivateMode(keyPath);
|
|
19696
19889
|
try {
|
|
19697
|
-
let record6 = identitySchema.parse(JSON.parse(await
|
|
19698
|
-
const privateKey = (await
|
|
19890
|
+
let record6 = identitySchema.parse(JSON.parse(await readFile2(devicePath, "utf8")));
|
|
19891
|
+
const privateKey = (await readFile2(keyPath, "utf8")).trim();
|
|
19699
19892
|
const regenerated = generateKeyPair(fromBase64Url2(privateKey));
|
|
19700
19893
|
if (regenerated.publicKey !== record6.publicKey) {
|
|
19701
19894
|
throw new IdentityInvalidError("device public and private keys do not match");
|
|
@@ -19749,11 +19942,11 @@ var IdentityStore = class {
|
|
|
19749
19942
|
return removed;
|
|
19750
19943
|
}
|
|
19751
19944
|
async loadPeers() {
|
|
19752
|
-
const path =
|
|
19945
|
+
const path = join3(this.directory, "trusted-peers.json");
|
|
19753
19946
|
if (!await exists(path)) {
|
|
19754
19947
|
await atomicJsonWrite(path, { schemaVersion: 1, peers: [] }, 384);
|
|
19755
19948
|
}
|
|
19756
|
-
const parsed = trustedPeersSchema.parse(JSON.parse(await
|
|
19949
|
+
const parsed = trustedPeersSchema.parse(JSON.parse(await readFile2(path, "utf8")));
|
|
19757
19950
|
const peers = /* @__PURE__ */ new Map();
|
|
19758
19951
|
for (const peer of parsed.peers) {
|
|
19759
19952
|
if (peer.fingerprint !== fingerprint(peer.publicKey)) {
|
|
@@ -19765,7 +19958,7 @@ var IdentityStore = class {
|
|
|
19765
19958
|
this.peers = peers;
|
|
19766
19959
|
}
|
|
19767
19960
|
async savePeers() {
|
|
19768
|
-
await atomicJsonWrite(
|
|
19961
|
+
await atomicJsonWrite(join3(this.directory, "trusted-peers.json"), {
|
|
19769
19962
|
schemaVersion: 1,
|
|
19770
19963
|
peers: [...this.peers.values()]
|
|
19771
19964
|
}, 384);
|
|
@@ -19774,7 +19967,7 @@ var IdentityStore = class {
|
|
|
19774
19967
|
function serverStorageDirectory(root, serverUrl, role) {
|
|
19775
19968
|
const origin = new URL(serverUrl).origin;
|
|
19776
19969
|
const scope = createHash("sha256").update(origin).digest("hex").slice(0, 24);
|
|
19777
|
-
return
|
|
19970
|
+
return join3(root, "servers", scope, role);
|
|
19778
19971
|
}
|
|
19779
19972
|
function fingerprint(publicKey) {
|
|
19780
19973
|
const compact = createHash("sha256").update(fromBase64Url2(publicKey)).digest("hex").slice(0, 12).toUpperCase();
|
|
@@ -19792,7 +19985,7 @@ async function atomicJsonWrite(path, value, mode) {
|
|
|
19792
19985
|
`, mode);
|
|
19793
19986
|
}
|
|
19794
19987
|
async function atomicTextWrite(path, value, mode) {
|
|
19795
|
-
await mkdir(
|
|
19988
|
+
await mkdir(dirname3(path), { recursive: true, mode: 448 });
|
|
19796
19989
|
const temporary = `${path}.${process.pid}.${uuidV7()}.tmp`;
|
|
19797
19990
|
await writeFile(temporary, value, { encoding: "utf8", mode, flag: "wx" });
|
|
19798
19991
|
await chmod(temporary, mode);
|
|
@@ -19816,8 +20009,8 @@ function safeErrorMessage(error) {
|
|
|
19816
20009
|
}
|
|
19817
20010
|
|
|
19818
20011
|
// src/server-credentials.ts
|
|
19819
|
-
import { chmod as chmod2, mkdir as mkdir2, readFile as
|
|
19820
|
-
import { dirname as
|
|
20012
|
+
import { chmod as chmod2, mkdir as mkdir2, readFile as readFile3, rename as rename2, rm as rm2, stat as stat2, writeFile as writeFile2 } from "node:fs/promises";
|
|
20013
|
+
import { dirname as dirname4, join as join4 } from "node:path";
|
|
19821
20014
|
var credentialSchema = external_exports.object({
|
|
19822
20015
|
schemaVersion: external_exports.literal(1),
|
|
19823
20016
|
serverUrl: external_exports.string().url(),
|
|
@@ -19832,14 +20025,14 @@ var credentialSchema = external_exports.object({
|
|
|
19832
20025
|
var ServerCredentialStore = class {
|
|
19833
20026
|
path;
|
|
19834
20027
|
constructor(directory) {
|
|
19835
|
-
this.path =
|
|
20028
|
+
this.path = join4(directory, "server-credentials.json");
|
|
19836
20029
|
}
|
|
19837
20030
|
async load(serverUrl, deviceId) {
|
|
19838
20031
|
if (!await exists2(this.path)) return void 0;
|
|
19839
20032
|
await assertPrivateMode2(this.path);
|
|
19840
20033
|
let parsed;
|
|
19841
20034
|
try {
|
|
19842
|
-
parsed = credentialSchema.parse(JSON.parse(await
|
|
20035
|
+
parsed = credentialSchema.parse(JSON.parse(await readFile3(this.path, "utf8")));
|
|
19843
20036
|
} catch (error) {
|
|
19844
20037
|
throw new ServerCredentialsInvalidError(`server credentials are invalid: ${safeMessage(error)}`);
|
|
19845
20038
|
}
|
|
@@ -19859,7 +20052,7 @@ var ServerCredentialsInvalidError = class extends Error {
|
|
|
19859
20052
|
code = "SERVER_CREDENTIALS_INVALID";
|
|
19860
20053
|
};
|
|
19861
20054
|
async function atomicWrite(path, contents) {
|
|
19862
|
-
await mkdir2(
|
|
20055
|
+
await mkdir2(dirname4(path), { recursive: true, mode: 448 });
|
|
19863
20056
|
const temporary = `${path}.${process.pid}.${uuidV7()}.tmp`;
|
|
19864
20057
|
await writeFile2(temporary, contents, { encoding: "utf8", mode: 384, flag: "wx" });
|
|
19865
20058
|
await chmod2(temporary, 384);
|
|
@@ -20110,11 +20303,11 @@ function editableConfig(config) {
|
|
|
20110
20303
|
}
|
|
20111
20304
|
};
|
|
20112
20305
|
}
|
|
20113
|
-
function
|
|
20306
|
+
function isRecord7(value) {
|
|
20114
20307
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20115
20308
|
}
|
|
20116
20309
|
function record4(value) {
|
|
20117
|
-
if (!
|
|
20310
|
+
if (!isRecord7(value)) throw new ClientModeError("INVALID_MESSAGE", "The control request payload is invalid.");
|
|
20118
20311
|
return value;
|
|
20119
20312
|
}
|
|
20120
20313
|
function ok3(value) {
|
|
@@ -20337,36 +20530,6 @@ function shortId2(value) {
|
|
|
20337
20530
|
return value.length <= 12 ? value : `${value.slice(0, 8)}\u2026${value.slice(-4)}`;
|
|
20338
20531
|
}
|
|
20339
20532
|
|
|
20340
|
-
// src/harness-version.ts
|
|
20341
|
-
import { readFile as readFile3 } from "node:fs/promises";
|
|
20342
|
-
import { dirname as dirname4, isAbsolute, join as join4 } from "node:path";
|
|
20343
|
-
var LEGACY_PLACEHOLDER_VERSION = "0.0.1";
|
|
20344
|
-
function normalizeHarnessVersion(value) {
|
|
20345
|
-
if (typeof value !== "string") return void 0;
|
|
20346
|
-
const version = value.trim();
|
|
20347
|
-
if (version.length === 0 || version.length > 64 || /[\u0000-\u001f]/u.test(version)) return void 0;
|
|
20348
|
-
return version;
|
|
20349
|
-
}
|
|
20350
|
-
function selectHarnessVersion(reportedVersion, distributionVersion) {
|
|
20351
|
-
if (reportedVersion !== void 0 && reportedVersion !== LEGACY_PLACEHOLDER_VERSION) return reportedVersion;
|
|
20352
|
-
return distributionVersion;
|
|
20353
|
-
}
|
|
20354
|
-
async function readHarnessDistributionVersion(entrypoint = process.argv[1]) {
|
|
20355
|
-
if (entrypoint === void 0 || !isAbsolute(entrypoint)) return void 0;
|
|
20356
|
-
let directory = dirname4(entrypoint);
|
|
20357
|
-
for (let depth = 0; depth < 8; depth += 1) {
|
|
20358
|
-
try {
|
|
20359
|
-
const manifest = JSON.parse(await readFile3(join4(directory, "package.json"), "utf8"));
|
|
20360
|
-
if (manifest.name === "@deepseek-ai/dsh") return normalizeHarnessVersion(manifest.version);
|
|
20361
|
-
} catch {
|
|
20362
|
-
}
|
|
20363
|
-
const parent = dirname4(directory);
|
|
20364
|
-
if (parent === directory) break;
|
|
20365
|
-
directory = parent;
|
|
20366
|
-
}
|
|
20367
|
-
return void 0;
|
|
20368
|
-
}
|
|
20369
|
-
|
|
20370
20533
|
// src/safe-error.ts
|
|
20371
20534
|
var RpcError = class extends Error {
|
|
20372
20535
|
constructor(code, message, details, retryable = false) {
|
|
@@ -22721,13 +22884,13 @@ function needsDirectoryFallback(result) {
|
|
|
22721
22884
|
}
|
|
22722
22885
|
function requestArgs(payload) {
|
|
22723
22886
|
const root = record5(payload);
|
|
22724
|
-
const args =
|
|
22887
|
+
const args = isRecord8(root.args) ? root.args : root;
|
|
22725
22888
|
return record5(args.request ?? args._request ?? args);
|
|
22726
22889
|
}
|
|
22727
22890
|
function record5(value) {
|
|
22728
|
-
return
|
|
22891
|
+
return isRecord8(value) ? value : {};
|
|
22729
22892
|
}
|
|
22730
|
-
function
|
|
22893
|
+
function isRecord8(value) {
|
|
22731
22894
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
22732
22895
|
}
|
|
22733
22896
|
|
|
@@ -22921,7 +23084,7 @@ var CodexAppServerClient = class {
|
|
|
22921
23084
|
this.handleProcessFailure("CODEX_INVALID_RESPONSE", new Error("Codex App Server emitted invalid JSON."));
|
|
22922
23085
|
return;
|
|
22923
23086
|
}
|
|
22924
|
-
if (!
|
|
23087
|
+
if (!isRecord9(value)) {
|
|
22925
23088
|
this.handleProcessFailure("CODEX_INVALID_RESPONSE", new Error("Codex App Server emitted an invalid message."));
|
|
22926
23089
|
return;
|
|
22927
23090
|
}
|
|
@@ -22966,12 +23129,12 @@ var CodexAppServerClient = class {
|
|
|
22966
23129
|
}
|
|
22967
23130
|
};
|
|
22968
23131
|
function safeUpstreamError(value) {
|
|
22969
|
-
if (!
|
|
23132
|
+
if (!isRecord9(value) || typeof value.message !== "string") return "Codex App Server rejected the request.";
|
|
22970
23133
|
const message = value.message.toLowerCase();
|
|
22971
23134
|
if (message.includes("active writer")) return "Codex thread already has an active writer.";
|
|
22972
23135
|
return message.includes("not initialized") ? "Codex App Server is not initialized." : "Codex App Server rejected the request.";
|
|
22973
23136
|
}
|
|
22974
|
-
function
|
|
23137
|
+
function isRecord9(value) {
|
|
22975
23138
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
22976
23139
|
}
|
|
22977
23140
|
|
|
@@ -23341,15 +23504,15 @@ function decodeCanonicalBase643(value) {
|
|
|
23341
23504
|
}
|
|
23342
23505
|
return decoded;
|
|
23343
23506
|
}
|
|
23344
|
-
function
|
|
23507
|
+
function isRecord10(value) {
|
|
23345
23508
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23346
23509
|
}
|
|
23347
23510
|
function safeErrorCode2(error) {
|
|
23348
|
-
if (
|
|
23511
|
+
if (isRecord10(error) && typeof error.code === "string") return error.code;
|
|
23349
23512
|
return "UNKNOWN";
|
|
23350
23513
|
}
|
|
23351
23514
|
function safeMethod(input2) {
|
|
23352
|
-
return
|
|
23515
|
+
return isRecord10(input2) && typeof input2.method === "string" ? input2.method : "invalid";
|
|
23353
23516
|
}
|
|
23354
23517
|
function concatChunks3(chunks, totalBytes) {
|
|
23355
23518
|
const output = new Uint8Array(totalBytes);
|
|
@@ -23766,14 +23929,14 @@ var CodexRemoteDomain = class {
|
|
|
23766
23929
|
await this.assertResultThreadAllowed(result);
|
|
23767
23930
|
if (codexPermissionPresetFromResponse(result) !== params.permissionPreset) {
|
|
23768
23931
|
await this.callUpstream("thread/settings/update", { threadId, ...settings });
|
|
23769
|
-
result = { ...
|
|
23932
|
+
result = { ...isRecord11(result) ? result : {}, ...settings, sandbox: settings.sandboxPolicy };
|
|
23770
23933
|
}
|
|
23771
23934
|
}
|
|
23772
23935
|
await this.publishPermission(threadId, result);
|
|
23773
23936
|
return result;
|
|
23774
23937
|
}
|
|
23775
23938
|
async publishPermission(threadId, value) {
|
|
23776
|
-
const source =
|
|
23939
|
+
const source = isRecord11(value) ? value : {};
|
|
23777
23940
|
const threadSettings = { approvalPolicy: source.approvalPolicy, sandboxPolicy: source.sandboxPolicy ?? source.sandbox };
|
|
23778
23941
|
await this.handleInbound({ kind: "notification", method: "thread/settings/updated", params: { threadId, threadSettings } });
|
|
23779
23942
|
}
|
|
@@ -23869,9 +24032,9 @@ var CodexRemoteDomain = class {
|
|
|
23869
24032
|
itemsView,
|
|
23870
24033
|
...cursor2 === void 0 ? {} : { cursor: cursor2 }
|
|
23871
24034
|
});
|
|
23872
|
-
const pageResult =
|
|
24035
|
+
const pageResult = isRecord11(result) ? result : {};
|
|
23873
24036
|
for (const rawTurn of array2(pageResult.data)) {
|
|
23874
|
-
if (!
|
|
24037
|
+
if (!isRecord11(rawTurn)) continue;
|
|
23875
24038
|
const turnId = typeof rawTurn.id === "string" ? rawTurn.id : void 0;
|
|
23876
24039
|
const items = rawTurn.itemsView === "full" || turnId === void 0 ? array2(rawTurn.items) : await this.readThreadItems(connectionId, threadId, turnId, array2(rawTurn.items));
|
|
23877
24040
|
turns.push({ ...rawTurn, items });
|
|
@@ -23893,9 +24056,9 @@ var CodexRemoteDomain = class {
|
|
|
23893
24056
|
sortDirection: "asc",
|
|
23894
24057
|
...cursor2 === void 0 ? {} : { cursor: cursor2 }
|
|
23895
24058
|
});
|
|
23896
|
-
const pageResult =
|
|
24059
|
+
const pageResult = isRecord11(result) ? result : {};
|
|
23897
24060
|
for (const entry of array2(pageResult.data)) {
|
|
23898
|
-
if (
|
|
24061
|
+
if (isRecord11(entry) && entry.item !== void 0) items.push(entry.item);
|
|
23899
24062
|
}
|
|
23900
24063
|
cursor2 = typeof pageResult.nextCursor === "string" && pageResult.nextCursor.length > 0 ? pageResult.nextCursor : void 0;
|
|
23901
24064
|
if (cursor2 === void 0) break;
|
|
@@ -23959,7 +24122,7 @@ var CodexRemoteDomain = class {
|
|
|
23959
24122
|
return [...this.peers.values()].some((peer) => peer.hasThreadSubscription(threadId));
|
|
23960
24123
|
}
|
|
23961
24124
|
resolveUpstreamApproval(params) {
|
|
23962
|
-
if (!
|
|
24125
|
+
if (!isRecord11(params) || typeof params.requestId !== "string" && typeof params.requestId !== "number") return;
|
|
23963
24126
|
for (const [handle, approval] of this.approvals) {
|
|
23964
24127
|
if (approval.upstreamId === params.requestId) this.approvals.delete(handle);
|
|
23965
24128
|
}
|
|
@@ -24176,24 +24339,24 @@ function codexBinaryCandidates(configured, hostPlatform = process.platform, user
|
|
|
24176
24339
|
])];
|
|
24177
24340
|
}
|
|
24178
24341
|
function parseCallEnvelope(input2) {
|
|
24179
|
-
if (!
|
|
24342
|
+
if (!isRecord11(input2) || typeof input2.method !== "string" || !("params" in input2) || Object.keys(input2).some((key) => key !== "method" && key !== "params")) {
|
|
24180
24343
|
throw new RpcError("INVALID_MESSAGE", "The Codex call envelope is invalid.");
|
|
24181
24344
|
}
|
|
24182
24345
|
return { method: input2.method, params: input2.params };
|
|
24183
24346
|
}
|
|
24184
24347
|
function parseRespond(input2) {
|
|
24185
|
-
if (!
|
|
24348
|
+
if (!isRecord11(input2) || typeof input2.requestHandle !== "string" || !["accept", "decline", "cancel"].includes(String(input2.decision)) || Object.keys(input2).some((key) => key !== "requestHandle" && key !== "decision")) {
|
|
24186
24349
|
throw new RpcError("INVALID_MESSAGE", "The Codex approval response is invalid.");
|
|
24187
24350
|
}
|
|
24188
24351
|
return input2;
|
|
24189
24352
|
}
|
|
24190
24353
|
function accountCanRun(result) {
|
|
24191
|
-
if (!
|
|
24192
|
-
return result.requiresOpenaiAuth === false ||
|
|
24354
|
+
if (!isRecord11(result) || typeof result.requiresOpenaiAuth !== "boolean") return false;
|
|
24355
|
+
return result.requiresOpenaiAuth === false || isRecord11(result.account);
|
|
24193
24356
|
}
|
|
24194
24357
|
function sanitizeAccount(result) {
|
|
24195
|
-
if (!
|
|
24196
|
-
const account =
|
|
24358
|
+
if (!isRecord11(result)) throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned invalid account state.");
|
|
24359
|
+
const account = isRecord11(result.account) ? result.account : void 0;
|
|
24197
24360
|
return {
|
|
24198
24361
|
authenticated: account !== void 0 || result.requiresOpenaiAuth === false,
|
|
24199
24362
|
requiresOpenaiAuth: result.requiresOpenaiAuth === true,
|
|
@@ -24206,11 +24369,11 @@ function sanitizeAccount(result) {
|
|
|
24206
24369
|
};
|
|
24207
24370
|
}
|
|
24208
24371
|
function sanitizeThreadList(result) {
|
|
24209
|
-
if (!
|
|
24372
|
+
if (!isRecord11(result) || !Array.isArray(result.data)) {
|
|
24210
24373
|
throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid thread list.");
|
|
24211
24374
|
}
|
|
24212
24375
|
const data = result.data.flatMap((value) => {
|
|
24213
|
-
if (!
|
|
24376
|
+
if (!isRecord11(value) || typeof value.id !== "string") return [];
|
|
24214
24377
|
return [{
|
|
24215
24378
|
id: value.id,
|
|
24216
24379
|
...typeof value.sessionId === "string" ? { sessionId: value.sessionId } : {},
|
|
@@ -24222,7 +24385,7 @@ function sanitizeThreadList(result) {
|
|
|
24222
24385
|
...typeof value.updatedAt === "number" && Number.isFinite(value.updatedAt) ? { updatedAt: value.updatedAt } : {},
|
|
24223
24386
|
...typeof value.archived === "boolean" ? { archived: value.archived } : {},
|
|
24224
24387
|
...typeof value.isPinned === "boolean" ? { isPinned: value.isPinned } : {},
|
|
24225
|
-
...
|
|
24388
|
+
...isRecord11(value.status) ? { status: value.status } : {}
|
|
24226
24389
|
}];
|
|
24227
24390
|
});
|
|
24228
24391
|
return {
|
|
@@ -24232,18 +24395,18 @@ function sanitizeThreadList(result) {
|
|
|
24232
24395
|
};
|
|
24233
24396
|
}
|
|
24234
24397
|
function filterThreadListByWorkspaceAuthority(result, authority) {
|
|
24235
|
-
if (!
|
|
24398
|
+
if (!isRecord11(result) || !Array.isArray(result.data)) {
|
|
24236
24399
|
throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid thread list.");
|
|
24237
24400
|
}
|
|
24238
24401
|
return {
|
|
24239
24402
|
...result,
|
|
24240
|
-
data: result.data.map((record6) =>
|
|
24403
|
+
data: result.data.map((record6) => isRecord11(record6) ? record6 : void 0).filter((thread) => thread !== void 0 && isThreadAllowedByWorkspaceAuthority(thread, authority))
|
|
24241
24404
|
};
|
|
24242
24405
|
}
|
|
24243
24406
|
function sanitizeProject(value) {
|
|
24244
|
-
if (!
|
|
24407
|
+
if (!isRecord11(value) || typeof value.id !== "string" || typeof value.name !== "string") return void 0;
|
|
24245
24408
|
const roots = Array.isArray(value.roots) ? value.roots.flatMap((root) => {
|
|
24246
|
-
const path =
|
|
24409
|
+
const path = isRecord11(root) && typeof root.path === "string" && root.path.length > 0 ? root.path : void 0;
|
|
24247
24410
|
return path === void 0 || !isAbsolute3(path) ? [] : [{ path }];
|
|
24248
24411
|
}) : [];
|
|
24249
24412
|
if (roots.length === 0) return void 0;
|
|
@@ -24257,7 +24420,7 @@ function sanitizeProject(value) {
|
|
|
24257
24420
|
};
|
|
24258
24421
|
}
|
|
24259
24422
|
function sanitizeProjectList(result) {
|
|
24260
|
-
if (!
|
|
24423
|
+
if (!isRecord11(result) || !Array.isArray(result.data)) {
|
|
24261
24424
|
throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid project list.");
|
|
24262
24425
|
}
|
|
24263
24426
|
const data = result.data.flatMap((value) => sanitizeProject(value) ?? []);
|
|
@@ -24267,7 +24430,7 @@ function sanitizeProjectList(result) {
|
|
|
24267
24430
|
};
|
|
24268
24431
|
}
|
|
24269
24432
|
function sanitizeProjectCreate(result) {
|
|
24270
|
-
const project =
|
|
24433
|
+
const project = isRecord11(result) ? sanitizeProject(result.project) : void 0;
|
|
24271
24434
|
if (project === void 0) {
|
|
24272
24435
|
throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid created project.");
|
|
24273
24436
|
}
|
|
@@ -24299,19 +24462,19 @@ function codexDirectoryCrumbs(root, path) {
|
|
|
24299
24462
|
return crumbs2;
|
|
24300
24463
|
}
|
|
24301
24464
|
function extractThread(result) {
|
|
24302
|
-
return
|
|
24465
|
+
return isRecord11(result) && isRecord11(result.thread) ? result.thread : void 0;
|
|
24303
24466
|
}
|
|
24304
24467
|
function extractTurnId(result) {
|
|
24305
|
-
if (!
|
|
24468
|
+
if (!isRecord11(result)) return void 0;
|
|
24306
24469
|
if (typeof result.turnId === "string" && result.turnId.length > 0) return result.turnId;
|
|
24307
|
-
if (
|
|
24470
|
+
if (isRecord11(result.turn) && typeof result.turn.id === "string" && result.turn.id.length > 0) return result.turn.id;
|
|
24308
24471
|
return void 0;
|
|
24309
24472
|
}
|
|
24310
24473
|
function extractThreadId(params) {
|
|
24311
|
-
if (!
|
|
24474
|
+
if (!isRecord11(params)) return void 0;
|
|
24312
24475
|
if (typeof params.threadId === "string") return params.threadId;
|
|
24313
|
-
if (
|
|
24314
|
-
if (
|
|
24476
|
+
if (isRecord11(params.thread) && typeof params.thread.id === "string") return params.thread.id;
|
|
24477
|
+
if (isRecord11(params.turn) && typeof params.turn.threadId === "string") return params.turn.threadId;
|
|
24315
24478
|
return void 0;
|
|
24316
24479
|
}
|
|
24317
24480
|
function optionalInteger2(value) {
|
|
@@ -24353,13 +24516,13 @@ function mapCodexImageInputs(params) {
|
|
|
24353
24516
|
return {
|
|
24354
24517
|
...params,
|
|
24355
24518
|
input: params.input.map((value) => {
|
|
24356
|
-
if (!
|
|
24519
|
+
if (!isRecord11(value) || value.type !== "image" || typeof value.mediaType !== "string" || typeof value.data !== "string") return value;
|
|
24357
24520
|
return { type: "image", url: `data:${value.mediaType};base64,${value.data}` };
|
|
24358
24521
|
})
|
|
24359
24522
|
};
|
|
24360
24523
|
}
|
|
24361
24524
|
function sanitizeApprovalParams(params, requestHandle) {
|
|
24362
|
-
if (!
|
|
24525
|
+
if (!isRecord11(params)) return { requestHandle };
|
|
24363
24526
|
const safe = { ...params };
|
|
24364
24527
|
delete safe.proposedExecpolicyAmendment;
|
|
24365
24528
|
delete safe.additionalPermissions;
|
|
@@ -24390,7 +24553,7 @@ function isProjectListFallbackError(error) {
|
|
|
24390
24553
|
function canTryNextBinary(error) {
|
|
24391
24554
|
return !(error instanceof RpcError) || !["CODEX_AUTH_REQUIRED", "CODEX_CLOSED"].includes(error.code);
|
|
24392
24555
|
}
|
|
24393
|
-
function
|
|
24556
|
+
function isRecord11(value) {
|
|
24394
24557
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24395
24558
|
}
|
|
24396
24559
|
function array2(value) {
|
|
@@ -24498,6 +24661,9 @@ var HostPluginRuntime = class {
|
|
|
24498
24661
|
accountRequired: error === "ACCOUNT_AUTH_REQUIRED" || error === "AUTH_INVALID" || error === "TOKEN_EXPIRED"
|
|
24499
24662
|
};
|
|
24500
24663
|
}
|
|
24664
|
+
localHarnessVersion() {
|
|
24665
|
+
return this.harnessVersion;
|
|
24666
|
+
}
|
|
24501
24667
|
reconnectHost() {
|
|
24502
24668
|
if (this.closed) throw new Error("remote runtime is closed");
|
|
24503
24669
|
if (this.serverConnection === void 0) {
|
|
@@ -24667,9 +24833,13 @@ var HostPluginRuntime = class {
|
|
|
24667
24833
|
}
|
|
24668
24834
|
hostCapabilities() {
|
|
24669
24835
|
const capabilities = [];
|
|
24670
|
-
if (this.apiProxy !== void 0) capabilities.push("harness.api.v1", "harness.api.transfer.v1");
|
|
24671
24836
|
if (this.localGateway?.supportsCarrier === true) {
|
|
24672
|
-
capabilities.push(
|
|
24837
|
+
capabilities.push(
|
|
24838
|
+
harnessSessionGeneration(this.harnessVersion) === "v3" ? "harness.remote.v3" : "harness.remote.v1",
|
|
24839
|
+
"harness.remote.transfer.v1"
|
|
24840
|
+
);
|
|
24841
|
+
} else if (this.apiProxy !== void 0) {
|
|
24842
|
+
capabilities.push("harness.api.v1", "harness.api.transfer.v1");
|
|
24673
24843
|
}
|
|
24674
24844
|
if (this.fileViewerHost?.() !== void 0) capabilities.push("fileviewer.read.v1");
|
|
24675
24845
|
if (this.codex.isAvailable()) capabilities.push("codex.appserver.v1", "codex.appserver.transfer.v1");
|