ds-harness-remote 0.4.5 → 0.4.7
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 +18 -31
- package/dist/client-runtime.d.ts +1 -0
- package/dist/client-runtime.d.ts.map +1 -1
- package/dist/client-runtime.js +34 -2
- package/dist/client-runtime.js.map +1 -1
- package/dist/client.github.js +130 -79
- package/dist/client.js +130 -79
- package/dist/client.js.map +1 -1
- package/dist/codex/domain.d.ts +1 -0
- package/dist/codex/domain.d.ts.map +1 -1
- package/dist/codex/domain.js +51 -20
- package/dist/codex/domain.js.map +1 -1
- package/dist/codex/method-policy.d.ts +24 -1
- package/dist/codex/method-policy.d.ts.map +1 -1
- package/dist/codex/method-policy.js +8 -0
- package/dist/codex/method-policy.js.map +1 -1
- package/dist/codex/virtual-harness.d.ts +1 -0
- package/dist/codex/virtual-harness.d.ts.map +1 -1
- package/dist/codex/virtual-harness.js +53 -11
- package/dist/codex/virtual-harness.js.map +1 -1
- package/dist/harness-api-bridge.d.ts +2 -0
- package/dist/harness-api-bridge.d.ts.map +1 -1
- package/dist/harness-api-bridge.js +34 -6
- 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 +51 -2
- package/dist/harness-remote-bridge.js.map +1 -1
- package/dist/index.js +295 -81
- package/dist/index.js.map +3 -3
- package/dist/remote-typert-gateway.js +2 -2
- package/dist/remote-typert-gateway.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 +15 -9
package/dist/index.js
CHANGED
|
@@ -4715,7 +4715,15 @@ function projectCodexItem(value, threadId, turnId, sessionId, index) {
|
|
|
4715
4715
|
return { ...base, kind: "tool", text: commandExecutionText(item), status: projectItemStatus(item.status), details: { type } };
|
|
4716
4716
|
}
|
|
4717
4717
|
if (isToolItemType(type)) {
|
|
4718
|
-
|
|
4718
|
+
const images = toolItemImages(item);
|
|
4719
|
+
return {
|
|
4720
|
+
...base,
|
|
4721
|
+
kind: "tool",
|
|
4722
|
+
text: toolCallText(item),
|
|
4723
|
+
...images.length === 0 ? {} : { images },
|
|
4724
|
+
status: projectItemStatus(item.status),
|
|
4725
|
+
details: { type }
|
|
4726
|
+
};
|
|
4719
4727
|
}
|
|
4720
4728
|
if (type === "fileChange") {
|
|
4721
4729
|
return { ...base, kind: "file-change", text: fileChangeText(item.changes), status: projectItemStatus(item.status), details: { type } };
|
|
@@ -4786,6 +4794,22 @@ function itemImages(item) {
|
|
|
4786
4794
|
}];
|
|
4787
4795
|
});
|
|
4788
4796
|
}
|
|
4797
|
+
function toolItemImages(item) {
|
|
4798
|
+
const candidates = [
|
|
4799
|
+
isRecord(item.result) ? item.result : void 0,
|
|
4800
|
+
isRecord(item.output) ? item.output : void 0,
|
|
4801
|
+
Array.isArray(item.contentItems) ? { content: item.contentItems } : void 0,
|
|
4802
|
+
Array.isArray(item.output) ? { content: item.output } : void 0
|
|
4803
|
+
];
|
|
4804
|
+
for (const candidate of candidates) {
|
|
4805
|
+
if (candidate === void 0 || !Array.isArray(candidate.content))
|
|
4806
|
+
continue;
|
|
4807
|
+
const images = itemImages(candidate);
|
|
4808
|
+
if (images.length > 0)
|
|
4809
|
+
return images;
|
|
4810
|
+
}
|
|
4811
|
+
return [];
|
|
4812
|
+
}
|
|
4789
4813
|
function isImageContent(value) {
|
|
4790
4814
|
return value.type === "image" || value.type === "input_image";
|
|
4791
4815
|
}
|
|
@@ -4796,7 +4820,7 @@ function imageDataUri(value) {
|
|
|
4796
4820
|
return parsed.url;
|
|
4797
4821
|
if (typeof value.data !== "string" || !isCanonicalBase64(value.data))
|
|
4798
4822
|
return void 0;
|
|
4799
|
-
const mediaType = typeof value.mediaType === "string" ? value.mediaType : sniffImageMediaType(value.data);
|
|
4823
|
+
const mediaType = typeof value.mediaType === "string" ? value.mediaType : typeof value.mimeType === "string" ? value.mimeType : sniffImageMediaType(value.data);
|
|
4800
4824
|
return mediaType !== void 0 && CODEX_IMAGE_MEDIA_TYPES.has(mediaType) ? `data:${mediaType};base64,${value.data}` : void 0;
|
|
4801
4825
|
}
|
|
4802
4826
|
function parseDataImageUrl(value) {
|
|
@@ -4885,7 +4909,8 @@ function toolCallText(item) {
|
|
|
4885
4909
|
}
|
|
4886
4910
|
const label = toolLabel(item);
|
|
4887
4911
|
const error = compactUnknown(item.error);
|
|
4888
|
-
const
|
|
4912
|
+
const rawResult = item.result ?? item.contentItems;
|
|
4913
|
+
const result = itemText(isRecord(rawResult) ? rawResult : {}) ?? (toolItemImages(item).length > 0 ? void 0 : compactUnknown(rawResult));
|
|
4889
4914
|
return boundedText([label, error, result].filter((value) => value !== void 0 && value !== "").join("\n\n")) || void 0;
|
|
4890
4915
|
}
|
|
4891
4916
|
function fileChangeText(value) {
|
|
@@ -14388,6 +14413,9 @@ var MAX_CODEX_IMAGE_BASE64 = 288 * 1024 * 1024;
|
|
|
14388
14413
|
var CODEX_IMAGE_MEDIA_TYPES2 = /* @__PURE__ */ new Set(["image/png", "image/jpeg", "image/webp", "image/gif"]);
|
|
14389
14414
|
var CODEX_IMAGE_ATTACHMENT_PREFIX = "codex-image:";
|
|
14390
14415
|
var DATA_IMAGE_URL2 = /^data:(image\/(?:png|jpeg|webp|gif));base64,([A-Za-z0-9+/]+={0,2})$/u;
|
|
14416
|
+
function codexProjectWorkspaceId(projectId) {
|
|
14417
|
+
return `${CODEX_WORKSPACE_PREFIX}project:${projectId}`;
|
|
14418
|
+
}
|
|
14391
14419
|
async function discoverCodexVirtualWorkspaces(client, signal) {
|
|
14392
14420
|
return (await loadCatalog(client, signal)).workspaces;
|
|
14393
14421
|
}
|
|
@@ -14806,6 +14834,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
14806
14834
|
liveItems: /* @__PURE__ */ new Map(),
|
|
14807
14835
|
liveToolOutput: /* @__PURE__ */ new Map(),
|
|
14808
14836
|
liveToolResultSeq: /* @__PURE__ */ new Map(),
|
|
14837
|
+
pendingToolImages: [],
|
|
14809
14838
|
requestId: this.pendingRequestIds.get(sessionId),
|
|
14810
14839
|
...history.activeTurnId === void 0 ? {} : { activeTurnId: history.activeTurnId }
|
|
14811
14840
|
};
|
|
@@ -15015,18 +15044,24 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15015
15044
|
follow.completedItems.add(itemId);
|
|
15016
15045
|
this.closeItemStreamBlocks(follow, itemId, itemText2(item));
|
|
15017
15046
|
if (type === "agentMessage" && follow.streamActive && follow.streamedBlocks.size === 0) this.finishStream(follow);
|
|
15047
|
+
const supplementalImages = type === "agentMessage" ? follow.pendingToolImages : [];
|
|
15018
15048
|
for (const event of itemEvents(
|
|
15019
15049
|
item,
|
|
15020
15050
|
follow.turn,
|
|
15021
15051
|
1,
|
|
15022
15052
|
follow.requestId,
|
|
15023
15053
|
this.modelSelection(follow.sessionId),
|
|
15024
|
-
follow.sessionId
|
|
15054
|
+
follow.sessionId,
|
|
15055
|
+
supplementalImages
|
|
15025
15056
|
)) {
|
|
15026
15057
|
if (event.type === "tool/call" && follow.startedItems.has(itemId)) continue;
|
|
15027
15058
|
if (event.type === "tool/result") this.pushToolResult(follow, itemId, event);
|
|
15028
15059
|
else this.pushEvent(follow, event.type, event.data, event.view);
|
|
15029
15060
|
}
|
|
15061
|
+
if (type === "agentMessage" && supplementalImages.length > 0) follow.pendingToolImages = [];
|
|
15062
|
+
else if (type !== void 0 && isToolItemType2(type)) {
|
|
15063
|
+
follow.pendingToolImages.push(...toolOutputImageBlocks(item));
|
|
15064
|
+
}
|
|
15030
15065
|
follow.liveItems.delete(itemId);
|
|
15031
15066
|
follow.liveToolOutput.delete(itemId);
|
|
15032
15067
|
follow.liveToolResultSeq.delete(itemId);
|
|
@@ -15167,6 +15202,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15167
15202
|
follow.liveItems.clear();
|
|
15168
15203
|
follow.liveToolOutput.clear();
|
|
15169
15204
|
follow.liveToolResultSeq.clear();
|
|
15205
|
+
follow.pendingToolImages = [];
|
|
15170
15206
|
}
|
|
15171
15207
|
emitRemoteEvent(event, args) {
|
|
15172
15208
|
for (const queue of this.eventStreams.values()) queue.push({ type: "emit", event, args });
|
|
@@ -15512,6 +15548,7 @@ var CodexVirtualHarness = class _CodexVirtualHarness {
|
|
|
15512
15548
|
liveItems: /* @__PURE__ */ new Map(),
|
|
15513
15549
|
liveToolOutput: /* @__PURE__ */ new Map(),
|
|
15514
15550
|
liveToolResultSeq: /* @__PURE__ */ new Map(),
|
|
15551
|
+
pendingToolImages: [],
|
|
15515
15552
|
requestId: this.pendingRequestIds.get(sessionId),
|
|
15516
15553
|
rcOnly: true,
|
|
15517
15554
|
...history.activeTurnId === void 0 ? {} : { activeTurnId: history.activeTurnId }
|
|
@@ -15813,15 +15850,29 @@ function projectCodexNativeHistory(thread, sessionId) {
|
|
|
15813
15850
|
};
|
|
15814
15851
|
for (const rawTurn of array(thread.turns)) {
|
|
15815
15852
|
const turn = record(rawTurn);
|
|
15853
|
+
const turnItems = array(turn.items).map(record);
|
|
15854
|
+
const toolImages = turnItems.flatMap(toolOutputImageBlocks);
|
|
15855
|
+
let imageOwner = -1;
|
|
15856
|
+
for (let index = 0; index < turnItems.length; index += 1) {
|
|
15857
|
+
if (turnItems[index].type === "agentMessage") imageOwner = index;
|
|
15858
|
+
}
|
|
15816
15859
|
turnNumber += 1;
|
|
15817
15860
|
const turnActive = isActiveCodexTurn(turn);
|
|
15818
15861
|
const time = normalizeTime(turn.createdAt) || normalizeTime(turn.startedAt) || normalizeTime(thread.createdAt) || Date.now();
|
|
15819
15862
|
append("turn/start", { turn: turnNumber }, time);
|
|
15820
15863
|
append("step/start", { turn: turnNumber, step: 1 }, time);
|
|
15821
|
-
for (
|
|
15822
|
-
const item =
|
|
15864
|
+
for (let itemIndex = 0; itemIndex < turnItems.length; itemIndex += 1) {
|
|
15865
|
+
const item = turnItems[itemIndex];
|
|
15823
15866
|
let toolCallSeq;
|
|
15824
|
-
for (const event of itemEvents(
|
|
15867
|
+
for (const event of itemEvents(
|
|
15868
|
+
item,
|
|
15869
|
+
turnNumber,
|
|
15870
|
+
1,
|
|
15871
|
+
void 0,
|
|
15872
|
+
modelSelection(),
|
|
15873
|
+
sessionId,
|
|
15874
|
+
itemIndex === imageOwner ? toolImages : []
|
|
15875
|
+
)) {
|
|
15825
15876
|
const eventSeq = append(
|
|
15826
15877
|
event.type,
|
|
15827
15878
|
event.data,
|
|
@@ -15878,7 +15929,7 @@ function paginateCodexNativeHistory(history, request) {
|
|
|
15878
15929
|
...history.activeTurnId === void 0 ? {} : { activeTurnId: history.activeTurnId }
|
|
15879
15930
|
};
|
|
15880
15931
|
}
|
|
15881
|
-
function itemEvents(item, turn, step, requestId, selection = modelSelection(), sessionId = CODEX_SESSION_PREFIX) {
|
|
15932
|
+
function itemEvents(item, turn, step, requestId, selection = modelSelection(), sessionId = CODEX_SESSION_PREFIX, supplementalImages = []) {
|
|
15882
15933
|
const type = string(item.type);
|
|
15883
15934
|
const id2 = string(item.id) ?? `${turn}:${step}:${hashString(JSON.stringify(item))}`;
|
|
15884
15935
|
const text = itemText2(item);
|
|
@@ -15899,7 +15950,13 @@ function itemEvents(item, turn, step, requestId, selection = modelSelection(), s
|
|
|
15899
15950
|
message: {
|
|
15900
15951
|
id: id2,
|
|
15901
15952
|
role: "assistant",
|
|
15902
|
-
content: messageContent(
|
|
15953
|
+
content: messageContent(
|
|
15954
|
+
item,
|
|
15955
|
+
`${sessionId}:${id2}`,
|
|
15956
|
+
type === "reasoning" ? "reasoning" : "text",
|
|
15957
|
+
text,
|
|
15958
|
+
type === "agentMessage" ? supplementalImages : []
|
|
15959
|
+
),
|
|
15903
15960
|
source: { kind: "model", provider: selection.provider, model: selection.model }
|
|
15904
15961
|
}
|
|
15905
15962
|
}
|
|
@@ -15931,12 +15988,32 @@ function itemEvents(item, turn, step, requestId, selection = modelSelection(), s
|
|
|
15931
15988
|
}];
|
|
15932
15989
|
return [];
|
|
15933
15990
|
}
|
|
15934
|
-
function messageContent(item, attachmentSeed, fallbackType, fallbackText) {
|
|
15991
|
+
function messageContent(item, attachmentSeed, fallbackType, fallbackText, supplementalImages = []) {
|
|
15935
15992
|
const source = item.content ?? item.input;
|
|
15936
15993
|
const blocks = contentBlocks(source, attachmentSeed);
|
|
15937
|
-
|
|
15994
|
+
const images = contentBlocks(supplementalImages, `${attachmentSeed}:tool-output`);
|
|
15995
|
+
if (blocks.length > 0 || images.length > 0) {
|
|
15996
|
+
return [...blocks.length > 0 ? blocks : [{ type: fallbackType, text: fallbackText ?? "" }], ...images];
|
|
15997
|
+
}
|
|
15938
15998
|
return [{ type: fallbackType, text: fallbackText ?? "" }];
|
|
15939
15999
|
}
|
|
16000
|
+
function toolOutputImageBlocks(item) {
|
|
16001
|
+
const candidates = [
|
|
16002
|
+
record(item.result).content,
|
|
16003
|
+
record(item.output).content,
|
|
16004
|
+
item.contentItems,
|
|
16005
|
+
Array.isArray(item.output) ? item.output : void 0
|
|
16006
|
+
];
|
|
16007
|
+
for (const candidate of candidates) {
|
|
16008
|
+
if (!Array.isArray(candidate)) continue;
|
|
16009
|
+
const images = candidate.flatMap((value) => {
|
|
16010
|
+
const block = record(value);
|
|
16011
|
+
return isImageContent2(block) && parseImageBlock(block) !== void 0 ? [block] : [];
|
|
16012
|
+
});
|
|
16013
|
+
if (images.length > 0) return images;
|
|
16014
|
+
}
|
|
16015
|
+
return [];
|
|
16016
|
+
}
|
|
15940
16017
|
function contentBlocks(value, attachmentSeed) {
|
|
15941
16018
|
if (typeof value === "string") return [{ type: "text", text: value }];
|
|
15942
16019
|
if (!Array.isArray(value)) return [];
|
|
@@ -15991,7 +16068,8 @@ function parseImageBlock(block) {
|
|
|
15991
16068
|
if (parsed !== void 0) return parsed;
|
|
15992
16069
|
const data = string(block.data);
|
|
15993
16070
|
if (data === void 0 || !isCanonicalBase642(data)) return void 0;
|
|
15994
|
-
|
|
16071
|
+
if (data.length > MAX_CODEX_IMAGE_BASE64) return void 0;
|
|
16072
|
+
const mediaType = string(block.mediaType) ?? string(block.mimeType) ?? sniffImageMediaType2(data);
|
|
15995
16073
|
return mediaType !== void 0 && CODEX_IMAGE_MEDIA_TYPES2.has(mediaType) ? { mediaType, data, url: `data:${mediaType};base64,${data}` } : void 0;
|
|
15996
16074
|
}
|
|
15997
16075
|
function parseDataImageUrl2(value) {
|
|
@@ -16274,7 +16352,7 @@ function nativeVisibleWorkspaces(catalog, selectedWorkspaceId) {
|
|
|
16274
16352
|
function projectWorkspace(project) {
|
|
16275
16353
|
const root = project.roots[0];
|
|
16276
16354
|
return {
|
|
16277
|
-
workspaceId:
|
|
16355
|
+
workspaceId: codexProjectWorkspaceId(project.id),
|
|
16278
16356
|
path: root.path,
|
|
16279
16357
|
title: project.name.trim() || basename(root.path),
|
|
16280
16358
|
sessionIds: [],
|
|
@@ -16825,7 +16903,7 @@ function normalizeServerUrl(value) {
|
|
|
16825
16903
|
}
|
|
16826
16904
|
|
|
16827
16905
|
// src/version.ts
|
|
16828
|
-
var PLUGIN_VERSION = "0.4.
|
|
16906
|
+
var PLUGIN_VERSION = "0.4.7";
|
|
16829
16907
|
|
|
16830
16908
|
// src/server-api.ts
|
|
16831
16909
|
var TERMINAL_CONTROL_CHARACTERS = /[\u0000-\u001f\u007f-\u009f]/u;
|
|
@@ -18703,6 +18781,26 @@ var ClientModeRuntime = class {
|
|
|
18703
18781
|
this.logger.info("CodeX virtual workspace opened", { targetDeviceId: shortId(remote.target.deviceId) });
|
|
18704
18782
|
return { ...this.status(), workspace };
|
|
18705
18783
|
}
|
|
18784
|
+
async createCodexWorkspace(targetDeviceId, path, signal) {
|
|
18785
|
+
const trimmedPath = path.trim();
|
|
18786
|
+
if (trimmedPath === "") throw new ClientModeError("INVALID_MESSAGE", "A CodeX project directory is required.");
|
|
18787
|
+
const remote = await this.ensureConnected(targetDeviceId, signal);
|
|
18788
|
+
remote.features = await probeRemoteHostFeatures(remote.client, remote.clientVersion);
|
|
18789
|
+
if (!remote.features.codex) {
|
|
18790
|
+
throw new ClientModeError("FEATURE_NOT_SUPPORTED", "The selected Host does not provide CodeX workspaces.");
|
|
18791
|
+
}
|
|
18792
|
+
this.assertRemoteCompatible(remote);
|
|
18793
|
+
const result = record2(await new CodexRemoteClient(remote.client).request("project/create", {
|
|
18794
|
+
name: remoteWorkspaceTitle(trimmedPath),
|
|
18795
|
+
roots: [{ path: trimmedPath }],
|
|
18796
|
+
idempotencyKey: uuidV7()
|
|
18797
|
+
}, signal));
|
|
18798
|
+
const project = record2(result.project);
|
|
18799
|
+
if (typeof project.id !== "string" || project.id.length === 0) {
|
|
18800
|
+
throw new ClientModeError("INVALID_MESSAGE", "The Host returned an invalid CodeX project.");
|
|
18801
|
+
}
|
|
18802
|
+
return this.openCodexWorkspace(targetDeviceId, codexProjectWorkspaceId(project.id), signal);
|
|
18803
|
+
}
|
|
18706
18804
|
consumeWorkspaceSelection(selection) {
|
|
18707
18805
|
const pending = this.pendingWorkspaceSelection;
|
|
18708
18806
|
if (pending?.targetDeviceId === selection.targetDeviceId && pending.workspaceId === selection.workspaceId && (pending.backend ?? "harness") === (selection.backend ?? "harness")) {
|
|
@@ -18896,7 +18994,7 @@ var ClientModeRuntime = class {
|
|
|
18896
18994
|
if (localRemoteGateway && remote.features.remoteGateway || !localRemoteGateway && this.proxySwitch !== void 0 && remote.features.apiProxy) return;
|
|
18897
18995
|
throw new ClientModeError(
|
|
18898
18996
|
"HARNESS_VERSION_INCOMPATIBLE",
|
|
18899
|
-
localRemoteGateway ? "The selected Host does not provide the Harness
|
|
18997
|
+
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."
|
|
18900
18998
|
);
|
|
18901
18999
|
}
|
|
18902
19000
|
async connect(targetDeviceId, signal) {
|
|
@@ -19079,6 +19177,13 @@ var ClientModeRuntime = class {
|
|
|
19079
19177
|
}
|
|
19080
19178
|
return ok2(await this.openCodexWorkspace(value.targetDeviceId, value.workspaceId, signal));
|
|
19081
19179
|
}
|
|
19180
|
+
if (endpoint === "codex.workspace.create") {
|
|
19181
|
+
const value = record2(payload);
|
|
19182
|
+
if (typeof value.targetDeviceId !== "string" || typeof value.path !== "string") {
|
|
19183
|
+
throw new ClientModeError("INVALID_MESSAGE", "A Host and CodeX project directory are required.");
|
|
19184
|
+
}
|
|
19185
|
+
return ok2(await this.createCodexWorkspace(value.targetDeviceId, value.path, signal));
|
|
19186
|
+
}
|
|
19082
19187
|
if (endpoint === "workspace.selection.consume") {
|
|
19083
19188
|
const value = record2(payload);
|
|
19084
19189
|
if (typeof value.targetDeviceId !== "string" || typeof value.workspaceId !== "string") {
|
|
@@ -19279,6 +19384,10 @@ function workspaceRecordId(value) {
|
|
|
19279
19384
|
}
|
|
19280
19385
|
return value.workspaceId;
|
|
19281
19386
|
}
|
|
19387
|
+
function remoteWorkspaceTitle(path) {
|
|
19388
|
+
const normalized = path.replace(/[\\/]+$/u, "");
|
|
19389
|
+
return normalized.split(/[\\/]+/u).filter(Boolean).at(-1) ?? path;
|
|
19390
|
+
}
|
|
19282
19391
|
function fail2(error) {
|
|
19283
19392
|
const source = error instanceof Error ? error : void 0;
|
|
19284
19393
|
const remoteCode = source !== void 0 && "code" in source && typeof source.code === "string" ? source.code : source instanceof ClientModeError ? source.code : void 0;
|
|
@@ -19431,24 +19540,24 @@ var IdentityStore = class {
|
|
|
19431
19540
|
}
|
|
19432
19541
|
if (!hasDevice) {
|
|
19433
19542
|
const keys = generateKeyPair();
|
|
19434
|
-
const
|
|
19435
|
-
await atomicJsonWrite(devicePath,
|
|
19543
|
+
const record5 = { schemaVersion: 1, deviceId: uuidV7(), name: deviceName, publicKey: keys.publicKey };
|
|
19544
|
+
await atomicJsonWrite(devicePath, record5, 384);
|
|
19436
19545
|
await atomicTextWrite(keyPath, `${keys.privateKey}
|
|
19437
19546
|
`, 384);
|
|
19438
19547
|
}
|
|
19439
19548
|
await assertPrivateMode(keyPath);
|
|
19440
19549
|
try {
|
|
19441
|
-
let
|
|
19550
|
+
let record5 = identitySchema.parse(JSON.parse(await readFile(devicePath, "utf8")));
|
|
19442
19551
|
const privateKey = (await readFile(keyPath, "utf8")).trim();
|
|
19443
19552
|
const regenerated = generateKeyPair(fromBase64Url2(privateKey));
|
|
19444
|
-
if (regenerated.publicKey !==
|
|
19553
|
+
if (regenerated.publicKey !== record5.publicKey) {
|
|
19445
19554
|
throw new IdentityInvalidError("device public and private keys do not match");
|
|
19446
19555
|
}
|
|
19447
|
-
if (
|
|
19448
|
-
|
|
19449
|
-
await atomicJsonWrite(devicePath,
|
|
19556
|
+
if (record5.name !== deviceName) {
|
|
19557
|
+
record5 = { ...record5, name: deviceName };
|
|
19558
|
+
await atomicJsonWrite(devicePath, record5, 384);
|
|
19450
19559
|
}
|
|
19451
|
-
this.identity = { ...
|
|
19560
|
+
this.identity = { ...record5, privateKey, fingerprint: fingerprint(record5.publicKey) };
|
|
19452
19561
|
await this.loadPeers();
|
|
19453
19562
|
return this.identity;
|
|
19454
19563
|
} catch (error) {
|
|
@@ -19590,10 +19699,10 @@ var ServerCredentialStore = class {
|
|
|
19590
19699
|
return parsed.serverUrl === serverUrl && parsed.deviceId === deviceId ? parsed : void 0;
|
|
19591
19700
|
}
|
|
19592
19701
|
async save(credentials) {
|
|
19593
|
-
const
|
|
19594
|
-
await atomicWrite(this.path, `${JSON.stringify(
|
|
19702
|
+
const record5 = credentialSchema.parse({ schemaVersion: 1, ...credentials });
|
|
19703
|
+
await atomicWrite(this.path, `${JSON.stringify(record5, null, 2)}
|
|
19595
19704
|
`);
|
|
19596
|
-
return
|
|
19705
|
+
return record5;
|
|
19597
19706
|
}
|
|
19598
19707
|
async clear() {
|
|
19599
19708
|
await rm2(this.path, { force: true });
|
|
@@ -21395,6 +21504,9 @@ var commandExecuteSchema = external_exports.object({
|
|
|
21395
21504
|
var commandListSchema = external_exports.object({
|
|
21396
21505
|
agentId: external_exports.string().min(1).max(128)
|
|
21397
21506
|
}).strict();
|
|
21507
|
+
var directoryListSchema = external_exports.object({
|
|
21508
|
+
path: external_exports.string().min(1).max(4096).optional()
|
|
21509
|
+
}).strict();
|
|
21398
21510
|
var credentialRefSchema = external_exports.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/, "Invalid credential reference name").max(128);
|
|
21399
21511
|
var CONFIG_PLANE_SETTINGS_BYTES = 64 * 1024;
|
|
21400
21512
|
var CONFIG_PLANE_MAX_OPS = 64;
|
|
@@ -21524,10 +21636,18 @@ var HarnessApiBridge = class {
|
|
|
21524
21636
|
answer;
|
|
21525
21637
|
async call(input2) {
|
|
21526
21638
|
const params = callSchema2.parse(input2);
|
|
21639
|
+
const signal = AbortSignal.timeout(NATIVE_CALL_TIMEOUT_MS);
|
|
21527
21640
|
const method = this.methods.get(params.method);
|
|
21528
|
-
if (method === void 0)
|
|
21641
|
+
if (method === void 0) {
|
|
21642
|
+
if (params.method === "host.listDirectory") {
|
|
21643
|
+
return this.callDirectoryFallback(params, signal);
|
|
21644
|
+
}
|
|
21645
|
+
if (params.method === "host.describe") {
|
|
21646
|
+
return this.describeFallback(params.rpcId);
|
|
21647
|
+
}
|
|
21648
|
+
throw deniedMethod(params.method);
|
|
21649
|
+
}
|
|
21529
21650
|
const startedAt = performance.now();
|
|
21530
|
-
const signal = AbortSignal.timeout(NATIVE_CALL_TIMEOUT_MS);
|
|
21531
21651
|
const request = { rpcId: params.rpcId, payload: params.payload };
|
|
21532
21652
|
try {
|
|
21533
21653
|
const callWithTimeout = (overridePayload) => withTimeout(
|
|
@@ -21542,12 +21662,10 @@ var HarnessApiBridge = class {
|
|
|
21542
21662
|
response = await callWithTimeout(request.payload);
|
|
21543
21663
|
}
|
|
21544
21664
|
if (params.method === "host.listDirectory" && needsRemoteDirectoryFallback(response)) {
|
|
21545
|
-
|
|
21546
|
-
const value = await listRemoteDirectory(typeof payload.path === "string" ? payload.path : void 0, signal);
|
|
21547
|
-
response = { rpcId: params.rpcId, result: { ok: true, value } };
|
|
21665
|
+
response = await this.callDirectoryFallback(params, signal);
|
|
21548
21666
|
}
|
|
21549
21667
|
if (params.method === "host.describe") {
|
|
21550
|
-
response = normalizeHostDescribe(response, this.harnessVersion,
|
|
21668
|
+
response = normalizeHostDescribe(response, this.harnessVersion, true);
|
|
21551
21669
|
}
|
|
21552
21670
|
this.logger?.debug("harness api call ok", {
|
|
21553
21671
|
method: params.method,
|
|
@@ -21565,6 +21683,26 @@ var HarnessApiBridge = class {
|
|
|
21565
21683
|
throw error;
|
|
21566
21684
|
}
|
|
21567
21685
|
}
|
|
21686
|
+
async callDirectoryFallback(params, signal) {
|
|
21687
|
+
const payload = directoryListSchema.parse(params.payload);
|
|
21688
|
+
const value = await listRemoteDirectory(payload.path, signal);
|
|
21689
|
+
return { rpcId: params.rpcId, result: { ok: true, value } };
|
|
21690
|
+
}
|
|
21691
|
+
describeFallback(rpcId) {
|
|
21692
|
+
return {
|
|
21693
|
+
rpcId,
|
|
21694
|
+
result: {
|
|
21695
|
+
ok: true,
|
|
21696
|
+
value: {
|
|
21697
|
+
version: this.harnessVersion ?? "0.0.1",
|
|
21698
|
+
cwd: "",
|
|
21699
|
+
home: "",
|
|
21700
|
+
attachedSessions: 0,
|
|
21701
|
+
canOpenPath: true
|
|
21702
|
+
}
|
|
21703
|
+
}
|
|
21704
|
+
};
|
|
21705
|
+
}
|
|
21568
21706
|
openTransfer(input2) {
|
|
21569
21707
|
this.pruneTransfers();
|
|
21570
21708
|
const params = transferOpenSchema.parse(input2);
|
|
@@ -22131,6 +22269,9 @@ var transferReadSchema2 = external_exports.object({
|
|
|
22131
22269
|
transferId: external_exports.string().uuid(),
|
|
22132
22270
|
index: external_exports.number().int().nonnegative()
|
|
22133
22271
|
}).strict();
|
|
22272
|
+
var directoryListSchema2 = external_exports.object({
|
|
22273
|
+
path: external_exports.string().min(1).max(4096).optional()
|
|
22274
|
+
}).strict();
|
|
22134
22275
|
var MAX_ACTIVE_STREAMS = 16;
|
|
22135
22276
|
var MAX_ACTIVE_TRANSFERS = 2;
|
|
22136
22277
|
var TRANSFER_IDLE_MS = 2 * 6e4;
|
|
@@ -22206,15 +22347,29 @@ var HarnessRemoteBridge = class {
|
|
|
22206
22347
|
async call(input2) {
|
|
22207
22348
|
const params = callSchema3.parse(input2);
|
|
22208
22349
|
this.assertAllowed(params.endpoint);
|
|
22350
|
+
if (params.endpoint === "session/canOpenWorkspacePath") {
|
|
22351
|
+
return { ok: true, value: true };
|
|
22352
|
+
}
|
|
22209
22353
|
const startedAt = performance.now();
|
|
22354
|
+
const signal = AbortSignal.timeout(6e4);
|
|
22210
22355
|
try {
|
|
22211
|
-
const
|
|
22356
|
+
const nativeResult = await this.gateway.dispatch(params.endpoint, params.payload, signal);
|
|
22357
|
+
const result = params.endpoint === "directoryPicker/list" && needsDirectoryFallback(nativeResult) ? await this.directoryList(params.payload, signal) : nativeResult;
|
|
22212
22358
|
this.logger?.debug("harness remote call ok", {
|
|
22213
22359
|
endpoint: params.endpoint,
|
|
22214
22360
|
durationMs: Math.round(performance.now() - startedAt)
|
|
22215
22361
|
});
|
|
22216
22362
|
return result;
|
|
22217
22363
|
} catch (error) {
|
|
22364
|
+
if (params.endpoint === "directoryPicker/list") {
|
|
22365
|
+
const result = await this.directoryList(params.payload, signal);
|
|
22366
|
+
this.logger?.debug("harness remote call ok", {
|
|
22367
|
+
endpoint: params.endpoint,
|
|
22368
|
+
durationMs: Math.round(performance.now() - startedAt),
|
|
22369
|
+
fallback: "directory-browser"
|
|
22370
|
+
});
|
|
22371
|
+
return result;
|
|
22372
|
+
}
|
|
22218
22373
|
this.logger?.warn("harness remote call failed", {
|
|
22219
22374
|
endpoint: params.endpoint,
|
|
22220
22375
|
durationMs: Math.round(performance.now() - startedAt),
|
|
@@ -22223,6 +22378,11 @@ var HarnessRemoteBridge = class {
|
|
|
22223
22378
|
throw error;
|
|
22224
22379
|
}
|
|
22225
22380
|
}
|
|
22381
|
+
async directoryList(payload, signal) {
|
|
22382
|
+
const args = requestArgs(payload);
|
|
22383
|
+
const params = directoryListSchema2.parse(args);
|
|
22384
|
+
return { ok: true, value: await listRemoteDirectory(params.path, signal) };
|
|
22385
|
+
}
|
|
22226
22386
|
openTransfer(input2) {
|
|
22227
22387
|
this.pruneTransfers();
|
|
22228
22388
|
const params = transferOpenSchema2.parse(input2);
|
|
@@ -22406,6 +22566,23 @@ function concatChunks2(chunks, totalBytes) {
|
|
|
22406
22566
|
}
|
|
22407
22567
|
return result;
|
|
22408
22568
|
}
|
|
22569
|
+
function needsDirectoryFallback(result) {
|
|
22570
|
+
if (result.ok) return false;
|
|
22571
|
+
const code = result.error.code.toLocaleLowerCase();
|
|
22572
|
+
const message = result.error.message.toLocaleLowerCase();
|
|
22573
|
+
return code.includes("capability") || code === "directory-picker/unavailable" || code === "directory-picker-unavailable" || message.includes("browse capability") || message.includes("browser capability") || message.includes("brower capability") || message.includes("directory-picker-unavailable");
|
|
22574
|
+
}
|
|
22575
|
+
function requestArgs(payload) {
|
|
22576
|
+
const root = record4(payload);
|
|
22577
|
+
const args = isRecord7(root.args) ? root.args : root;
|
|
22578
|
+
return record4(args.request ?? args._request ?? args);
|
|
22579
|
+
}
|
|
22580
|
+
function record4(value) {
|
|
22581
|
+
return isRecord7(value) ? value : {};
|
|
22582
|
+
}
|
|
22583
|
+
function isRecord7(value) {
|
|
22584
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
22585
|
+
}
|
|
22409
22586
|
|
|
22410
22587
|
// src/codex/domain.ts
|
|
22411
22588
|
import { randomUUID } from "node:crypto";
|
|
@@ -22597,7 +22774,7 @@ var CodexAppServerClient = class {
|
|
|
22597
22774
|
this.handleProcessFailure("CODEX_INVALID_RESPONSE", new Error("Codex App Server emitted invalid JSON."));
|
|
22598
22775
|
return;
|
|
22599
22776
|
}
|
|
22600
|
-
if (!
|
|
22777
|
+
if (!isRecord8(value)) {
|
|
22601
22778
|
this.handleProcessFailure("CODEX_INVALID_RESPONSE", new Error("Codex App Server emitted an invalid message."));
|
|
22602
22779
|
return;
|
|
22603
22780
|
}
|
|
@@ -22642,12 +22819,12 @@ var CodexAppServerClient = class {
|
|
|
22642
22819
|
}
|
|
22643
22820
|
};
|
|
22644
22821
|
function safeUpstreamError(value) {
|
|
22645
|
-
if (!
|
|
22822
|
+
if (!isRecord8(value) || typeof value.message !== "string") return "Codex App Server rejected the request.";
|
|
22646
22823
|
const message = value.message.toLowerCase();
|
|
22647
22824
|
if (message.includes("active writer")) return "Codex thread already has an active writer.";
|
|
22648
22825
|
return message.includes("not initialized") ? "Codex App Server is not initialized." : "Codex App Server rejected the request.";
|
|
22649
22826
|
}
|
|
22650
|
-
function
|
|
22827
|
+
function isRecord8(value) {
|
|
22651
22828
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
22652
22829
|
}
|
|
22653
22830
|
|
|
@@ -22669,6 +22846,9 @@ var imageInput = external_exports.object({
|
|
|
22669
22846
|
}).strict();
|
|
22670
22847
|
var input = external_exports.array(external_exports.union([textInput, imageInput])).min(1).max(16);
|
|
22671
22848
|
var permissionPreset = external_exports.enum(["workspace-write", "danger-full-access"]);
|
|
22849
|
+
var projectRoot = external_exports.object({
|
|
22850
|
+
path: external_exports.string().min(1).max(4096)
|
|
22851
|
+
}).strict();
|
|
22672
22852
|
var schemas = {
|
|
22673
22853
|
"account/read": external_exports.object({ refreshToken: external_exports.literal(false).optional() }).strict(),
|
|
22674
22854
|
"model/list": external_exports.object({
|
|
@@ -22680,6 +22860,11 @@ var schemas = {
|
|
|
22680
22860
|
cursor,
|
|
22681
22861
|
limit: external_exports.number().int().min(1).max(100).optional()
|
|
22682
22862
|
}).strict(),
|
|
22863
|
+
"project/create": external_exports.object({
|
|
22864
|
+
name: external_exports.string().trim().min(1).max(256),
|
|
22865
|
+
roots: external_exports.array(projectRoot).length(1),
|
|
22866
|
+
idempotencyKey: external_exports.string().min(16).max(256)
|
|
22867
|
+
}).strict(),
|
|
22683
22868
|
"thread/list": external_exports.object({
|
|
22684
22869
|
cursor,
|
|
22685
22870
|
limit: external_exports.number().int().min(1).max(100).optional(),
|
|
@@ -23009,15 +23194,15 @@ function decodeCanonicalBase643(value) {
|
|
|
23009
23194
|
}
|
|
23010
23195
|
return decoded;
|
|
23011
23196
|
}
|
|
23012
|
-
function
|
|
23197
|
+
function isRecord9(value) {
|
|
23013
23198
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23014
23199
|
}
|
|
23015
23200
|
function safeErrorCode2(error) {
|
|
23016
|
-
if (
|
|
23201
|
+
if (isRecord9(error) && typeof error.code === "string") return error.code;
|
|
23017
23202
|
return "UNKNOWN";
|
|
23018
23203
|
}
|
|
23019
23204
|
function safeMethod(input2) {
|
|
23020
|
-
return
|
|
23205
|
+
return isRecord9(input2) && typeof input2.method === "string" ? input2.method : "invalid";
|
|
23021
23206
|
}
|
|
23022
23207
|
function concatChunks3(chunks, totalBytes) {
|
|
23023
23208
|
const output = new Uint8Array(totalBytes);
|
|
@@ -23101,6 +23286,15 @@ var CodexRemoteDomain = class {
|
|
|
23101
23286
|
if (call.method === "project/list") {
|
|
23102
23287
|
return sanitizeProjectList(await this.callUpstream(call.method, call.params));
|
|
23103
23288
|
}
|
|
23289
|
+
if (call.method === "project/create") {
|
|
23290
|
+
const roots = call.params.roots;
|
|
23291
|
+
const path = await this.requireNewCodexProjectPath(roots[0].path);
|
|
23292
|
+
return sanitizeProjectCreate(await this.callUpstream(call.method, {
|
|
23293
|
+
name: call.params.name,
|
|
23294
|
+
roots: [{ path }],
|
|
23295
|
+
idempotencyKey: call.params.idempotencyKey
|
|
23296
|
+
}));
|
|
23297
|
+
}
|
|
23104
23298
|
if (call.method === "thread/list") {
|
|
23105
23299
|
const result = sanitizeThreadList(await this.callUpstream(call.method, call.params));
|
|
23106
23300
|
return filterThreadListByWorkspaceAuthority(
|
|
@@ -23463,9 +23657,9 @@ var CodexRemoteDomain = class {
|
|
|
23463
23657
|
itemsView,
|
|
23464
23658
|
...cursor2 === void 0 ? {} : { cursor: cursor2 }
|
|
23465
23659
|
});
|
|
23466
|
-
const pageResult =
|
|
23660
|
+
const pageResult = isRecord10(result) ? result : {};
|
|
23467
23661
|
for (const rawTurn of array2(pageResult.data)) {
|
|
23468
|
-
if (!
|
|
23662
|
+
if (!isRecord10(rawTurn)) continue;
|
|
23469
23663
|
const turnId = typeof rawTurn.id === "string" ? rawTurn.id : void 0;
|
|
23470
23664
|
const items = rawTurn.itemsView === "full" || turnId === void 0 ? array2(rawTurn.items) : await this.readThreadItems(connectionId, threadId, turnId, array2(rawTurn.items));
|
|
23471
23665
|
turns.push({ ...rawTurn, items });
|
|
@@ -23487,9 +23681,9 @@ var CodexRemoteDomain = class {
|
|
|
23487
23681
|
sortDirection: "asc",
|
|
23488
23682
|
...cursor2 === void 0 ? {} : { cursor: cursor2 }
|
|
23489
23683
|
});
|
|
23490
|
-
const pageResult =
|
|
23684
|
+
const pageResult = isRecord10(result) ? result : {};
|
|
23491
23685
|
for (const entry of array2(pageResult.data)) {
|
|
23492
|
-
if (
|
|
23686
|
+
if (isRecord10(entry) && entry.item !== void 0) items.push(entry.item);
|
|
23493
23687
|
}
|
|
23494
23688
|
cursor2 = typeof pageResult.nextCursor === "string" && pageResult.nextCursor.length > 0 ? pageResult.nextCursor : void 0;
|
|
23495
23689
|
if (cursor2 === void 0) break;
|
|
@@ -23553,7 +23747,7 @@ var CodexRemoteDomain = class {
|
|
|
23553
23747
|
return [...this.peers.values()].some((peer) => peer.hasThreadSubscription(threadId));
|
|
23554
23748
|
}
|
|
23555
23749
|
resolveUpstreamApproval(params) {
|
|
23556
|
-
if (!
|
|
23750
|
+
if (!isRecord10(params) || typeof params.requestId !== "string" && typeof params.requestId !== "number") return;
|
|
23557
23751
|
for (const [handle, approval] of this.approvals) {
|
|
23558
23752
|
if (approval.upstreamId === params.requestId) this.approvals.delete(handle);
|
|
23559
23753
|
}
|
|
@@ -23680,6 +23874,18 @@ var CodexRemoteDomain = class {
|
|
|
23680
23874
|
}
|
|
23681
23875
|
throw new RpcError("CODEX_PATH_NOT_ALLOWED", "The CodeX working directory is not available as a Workspace.");
|
|
23682
23876
|
}
|
|
23877
|
+
async requireNewCodexProjectPath(path) {
|
|
23878
|
+
if (!isAbsolute3(path)) {
|
|
23879
|
+
throw new RpcError("CODEX_PATH_NOT_ALLOWED", "The CodeX project directory must be an existing absolute directory.");
|
|
23880
|
+
}
|
|
23881
|
+
try {
|
|
23882
|
+
const canonical = await realpath(resolve2(path));
|
|
23883
|
+
if (!(await stat4(canonical)).isDirectory()) throw new Error("not a directory");
|
|
23884
|
+
return canonical;
|
|
23885
|
+
} catch {
|
|
23886
|
+
throw new RpcError("CODEX_PATH_NOT_ALLOWED", "The CodeX project directory must be an existing absolute directory.");
|
|
23887
|
+
}
|
|
23888
|
+
}
|
|
23683
23889
|
async listCodexDirectory(path) {
|
|
23684
23890
|
const target = await this.resolveCodexDirectory(path);
|
|
23685
23891
|
const rows = await readdir2(target.path, { withFileTypes: true }).catch(() => void 0);
|
|
@@ -23758,24 +23964,24 @@ function codexBinaryCandidates(configured, hostPlatform = process.platform, user
|
|
|
23758
23964
|
])];
|
|
23759
23965
|
}
|
|
23760
23966
|
function parseCallEnvelope(input2) {
|
|
23761
|
-
if (!
|
|
23967
|
+
if (!isRecord10(input2) || typeof input2.method !== "string" || !("params" in input2) || Object.keys(input2).some((key) => key !== "method" && key !== "params")) {
|
|
23762
23968
|
throw new RpcError("INVALID_MESSAGE", "The Codex call envelope is invalid.");
|
|
23763
23969
|
}
|
|
23764
23970
|
return { method: input2.method, params: input2.params };
|
|
23765
23971
|
}
|
|
23766
23972
|
function parseRespond(input2) {
|
|
23767
|
-
if (!
|
|
23973
|
+
if (!isRecord10(input2) || typeof input2.requestHandle !== "string" || !["accept", "decline", "cancel"].includes(String(input2.decision)) || Object.keys(input2).some((key) => key !== "requestHandle" && key !== "decision")) {
|
|
23768
23974
|
throw new RpcError("INVALID_MESSAGE", "The Codex approval response is invalid.");
|
|
23769
23975
|
}
|
|
23770
23976
|
return input2;
|
|
23771
23977
|
}
|
|
23772
23978
|
function accountCanRun(result) {
|
|
23773
|
-
if (!
|
|
23774
|
-
return result.requiresOpenaiAuth === false ||
|
|
23979
|
+
if (!isRecord10(result) || typeof result.requiresOpenaiAuth !== "boolean") return false;
|
|
23980
|
+
return result.requiresOpenaiAuth === false || isRecord10(result.account);
|
|
23775
23981
|
}
|
|
23776
23982
|
function sanitizeAccount(result) {
|
|
23777
|
-
if (!
|
|
23778
|
-
const account =
|
|
23983
|
+
if (!isRecord10(result)) throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned invalid account state.");
|
|
23984
|
+
const account = isRecord10(result.account) ? result.account : void 0;
|
|
23779
23985
|
return {
|
|
23780
23986
|
authenticated: account !== void 0 || result.requiresOpenaiAuth === false,
|
|
23781
23987
|
requiresOpenaiAuth: result.requiresOpenaiAuth === true,
|
|
@@ -23788,11 +23994,11 @@ function sanitizeAccount(result) {
|
|
|
23788
23994
|
};
|
|
23789
23995
|
}
|
|
23790
23996
|
function sanitizeThreadList(result) {
|
|
23791
|
-
if (!
|
|
23997
|
+
if (!isRecord10(result) || !Array.isArray(result.data)) {
|
|
23792
23998
|
throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid thread list.");
|
|
23793
23999
|
}
|
|
23794
24000
|
const data = result.data.flatMap((value) => {
|
|
23795
|
-
if (!
|
|
24001
|
+
if (!isRecord10(value) || typeof value.id !== "string") return [];
|
|
23796
24002
|
return [{
|
|
23797
24003
|
id: value.id,
|
|
23798
24004
|
...typeof value.sessionId === "string" ? { sessionId: value.sessionId } : {},
|
|
@@ -23804,7 +24010,7 @@ function sanitizeThreadList(result) {
|
|
|
23804
24010
|
...typeof value.updatedAt === "number" && Number.isFinite(value.updatedAt) ? { updatedAt: value.updatedAt } : {},
|
|
23805
24011
|
...typeof value.archived === "boolean" ? { archived: value.archived } : {},
|
|
23806
24012
|
...typeof value.isPinned === "boolean" ? { isPinned: value.isPinned } : {},
|
|
23807
|
-
...
|
|
24013
|
+
...isRecord10(value.status) ? { status: value.status } : {}
|
|
23808
24014
|
}];
|
|
23809
24015
|
});
|
|
23810
24016
|
return {
|
|
@@ -23814,39 +24020,47 @@ function sanitizeThreadList(result) {
|
|
|
23814
24020
|
};
|
|
23815
24021
|
}
|
|
23816
24022
|
function filterThreadListByWorkspaceAuthority(result, authority) {
|
|
23817
|
-
if (!
|
|
24023
|
+
if (!isRecord10(result) || !Array.isArray(result.data)) {
|
|
23818
24024
|
throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid thread list.");
|
|
23819
24025
|
}
|
|
23820
24026
|
return {
|
|
23821
24027
|
...result,
|
|
23822
|
-
data: result.data.map((
|
|
24028
|
+
data: result.data.map((record5) => isRecord10(record5) ? record5 : void 0).filter((thread) => thread !== void 0 && isThreadAllowedByWorkspaceAuthority(thread, authority))
|
|
24029
|
+
};
|
|
24030
|
+
}
|
|
24031
|
+
function sanitizeProject(value) {
|
|
24032
|
+
if (!isRecord10(value) || typeof value.id !== "string" || typeof value.name !== "string") return void 0;
|
|
24033
|
+
const roots = Array.isArray(value.roots) ? value.roots.flatMap((root) => {
|
|
24034
|
+
const path = isRecord10(root) && typeof root.path === "string" && root.path.length > 0 ? root.path : void 0;
|
|
24035
|
+
return path === void 0 || !isAbsolute3(path) ? [] : [{ path }];
|
|
24036
|
+
}) : [];
|
|
24037
|
+
if (roots.length === 0) return void 0;
|
|
24038
|
+
return {
|
|
24039
|
+
id: value.id,
|
|
24040
|
+
name: value.name,
|
|
24041
|
+
roots,
|
|
24042
|
+
...typeof value.position === "number" && Number.isFinite(value.position) ? { position: value.position } : {},
|
|
24043
|
+
...typeof value.createdAt === "number" && Number.isFinite(value.createdAt) ? { createdAt: value.createdAt } : {},
|
|
24044
|
+
...typeof value.updatedAt === "number" && Number.isFinite(value.updatedAt) ? { updatedAt: value.updatedAt } : {}
|
|
23823
24045
|
};
|
|
23824
24046
|
}
|
|
23825
24047
|
function sanitizeProjectList(result) {
|
|
23826
|
-
if (!
|
|
24048
|
+
if (!isRecord10(result) || !Array.isArray(result.data)) {
|
|
23827
24049
|
throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid project list.");
|
|
23828
24050
|
}
|
|
23829
|
-
const data = result.data.flatMap((value) =>
|
|
23830
|
-
if (!isRecord9(value) || typeof value.id !== "string" || typeof value.name !== "string") return [];
|
|
23831
|
-
const roots = Array.isArray(value.roots) ? value.roots.flatMap((root) => {
|
|
23832
|
-
const path = isRecord9(root) && typeof root.path === "string" && root.path.length > 0 ? root.path : void 0;
|
|
23833
|
-
return path === void 0 || !isAbsolute3(path) ? [] : [{ path }];
|
|
23834
|
-
}) : [];
|
|
23835
|
-
if (roots.length === 0) return [];
|
|
23836
|
-
return [{
|
|
23837
|
-
id: value.id,
|
|
23838
|
-
name: value.name,
|
|
23839
|
-
roots,
|
|
23840
|
-
...typeof value.position === "number" && Number.isFinite(value.position) ? { position: value.position } : {},
|
|
23841
|
-
...typeof value.createdAt === "number" && Number.isFinite(value.createdAt) ? { createdAt: value.createdAt } : {},
|
|
23842
|
-
...typeof value.updatedAt === "number" && Number.isFinite(value.updatedAt) ? { updatedAt: value.updatedAt } : {}
|
|
23843
|
-
}];
|
|
23844
|
-
});
|
|
24051
|
+
const data = result.data.flatMap((value) => sanitizeProject(value) ?? []);
|
|
23845
24052
|
return {
|
|
23846
24053
|
data,
|
|
23847
24054
|
...typeof result.nextCursor === "string" && result.nextCursor.length > 0 ? { nextCursor: result.nextCursor } : { nextCursor: null }
|
|
23848
24055
|
};
|
|
23849
24056
|
}
|
|
24057
|
+
function sanitizeProjectCreate(result) {
|
|
24058
|
+
const project = isRecord10(result) ? sanitizeProject(result.project) : void 0;
|
|
24059
|
+
if (project === void 0) {
|
|
24060
|
+
throw new RpcError("CODEX_INVALID_RESPONSE", "Codex App Server returned an invalid created project.");
|
|
24061
|
+
}
|
|
24062
|
+
return { project };
|
|
24063
|
+
}
|
|
23850
24064
|
function isThreadAllowedByWorkspaceAuthority(thread, authority) {
|
|
23851
24065
|
const projectId = typeof thread.projectId === "string" ? thread.projectId : void 0;
|
|
23852
24066
|
if (projectId !== void 0 && authority.projectIds.has(projectId)) return true;
|
|
@@ -23873,19 +24087,19 @@ function codexDirectoryCrumbs(root, path) {
|
|
|
23873
24087
|
return crumbs2;
|
|
23874
24088
|
}
|
|
23875
24089
|
function extractThread(result) {
|
|
23876
|
-
return
|
|
24090
|
+
return isRecord10(result) && isRecord10(result.thread) ? result.thread : void 0;
|
|
23877
24091
|
}
|
|
23878
24092
|
function extractTurnId(result) {
|
|
23879
|
-
if (!
|
|
24093
|
+
if (!isRecord10(result)) return void 0;
|
|
23880
24094
|
if (typeof result.turnId === "string" && result.turnId.length > 0) return result.turnId;
|
|
23881
|
-
if (
|
|
24095
|
+
if (isRecord10(result.turn) && typeof result.turn.id === "string" && result.turn.id.length > 0) return result.turn.id;
|
|
23882
24096
|
return void 0;
|
|
23883
24097
|
}
|
|
23884
24098
|
function extractThreadId(params) {
|
|
23885
|
-
if (!
|
|
24099
|
+
if (!isRecord10(params)) return void 0;
|
|
23886
24100
|
if (typeof params.threadId === "string") return params.threadId;
|
|
23887
|
-
if (
|
|
23888
|
-
if (
|
|
24101
|
+
if (isRecord10(params.thread) && typeof params.thread.id === "string") return params.thread.id;
|
|
24102
|
+
if (isRecord10(params.turn) && typeof params.turn.threadId === "string") return params.turn.threadId;
|
|
23889
24103
|
return void 0;
|
|
23890
24104
|
}
|
|
23891
24105
|
function optionalInteger2(value) {
|
|
@@ -23927,13 +24141,13 @@ function mapCodexImageInputs(params) {
|
|
|
23927
24141
|
return {
|
|
23928
24142
|
...params,
|
|
23929
24143
|
input: params.input.map((value) => {
|
|
23930
|
-
if (!
|
|
24144
|
+
if (!isRecord10(value) || value.type !== "image" || typeof value.mediaType !== "string" || typeof value.data !== "string") return value;
|
|
23931
24145
|
return { type: "image", url: `data:${value.mediaType};base64,${value.data}` };
|
|
23932
24146
|
})
|
|
23933
24147
|
};
|
|
23934
24148
|
}
|
|
23935
24149
|
function sanitizeApprovalParams(params, requestHandle) {
|
|
23936
|
-
if (!
|
|
24150
|
+
if (!isRecord10(params)) return { requestHandle };
|
|
23937
24151
|
const safe = { ...params };
|
|
23938
24152
|
delete safe.proposedExecpolicyAmendment;
|
|
23939
24153
|
delete safe.additionalPermissions;
|
|
@@ -23964,7 +24178,7 @@ function isProjectListFallbackError(error) {
|
|
|
23964
24178
|
function canTryNextBinary(error) {
|
|
23965
24179
|
return !(error instanceof RpcError) || !["CODEX_AUTH_REQUIRED", "CODEX_CLOSED"].includes(error.code);
|
|
23966
24180
|
}
|
|
23967
|
-
function
|
|
24181
|
+
function isRecord10(value) {
|
|
23968
24182
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23969
24183
|
}
|
|
23970
24184
|
function array2(value) {
|