ds-harness-remote 0.4.8 → 0.4.10
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 +65 -170
- package/dist/client-runtime.d.ts +5 -0
- package/dist/client-runtime.d.ts.map +1 -1
- package/dist/client-runtime.js +126 -51
- package/dist/client-runtime.js.map +1 -1
- package/dist/client.github.js +166 -121
- package/dist/client.js +166 -121
- package/dist/client.js.map +1 -1
- package/dist/codex/domain.d.ts +4 -0
- package/dist/codex/domain.d.ts.map +1 -1
- package/dist/codex/domain.js +74 -1
- package/dist/codex/domain.js.map +1 -1
- package/dist/codex/method-policy.d.ts +2 -2
- package/dist/codex/permissions.d.ts +4 -0
- package/dist/codex/permissions.d.ts.map +1 -0
- package/dist/codex/permissions.js +21 -0
- package/dist/codex/permissions.js.map +1 -0
- package/dist/codex/virtual-harness.d.ts +2 -1
- package/dist/codex/virtual-harness.d.ts.map +1 -1
- package/dist/codex/virtual-harness.js +25 -36
- package/dist/codex/virtual-harness.js.map +1 -1
- package/dist/index.js +410 -198
- package/dist/index.js.map +4 -4
- package/dist/server-api.d.ts.map +1 -1
- package/dist/server-api.js +4 -5
- package/dist/server-api.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/dsh-plugin.json +1 -1
- package/package.json +18 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CodexRemoteClient, deriveCodexCwdWorkspaces, projectCodexThread, } from '@dsh-remote/client-core';
|
|
2
|
+
import { codexPermissionPresetFromResponse } from './permissions.js';
|
|
2
3
|
const CODEX_SESSION_PREFIX = 'codex:';
|
|
3
4
|
const CODEX_WORKSPACE_PREFIX = 'codex-workspace:';
|
|
4
5
|
const CODEX_PROVIDER = 'codex';
|
|
@@ -245,10 +246,13 @@ export class CodexVirtualHarness {
|
|
|
245
246
|
return this.selectedModels.get(sessionId) ?? directory?.default ?? modelSelection();
|
|
246
247
|
}
|
|
247
248
|
permissionSelection(sessionId) {
|
|
248
|
-
return this.selectedPermissions.get(sessionId)
|
|
249
|
+
return this.selectedPermissions.get(sessionId);
|
|
249
250
|
}
|
|
250
251
|
setPermissionSelection(sessionId, preset) {
|
|
251
|
-
|
|
252
|
+
if (preset === undefined)
|
|
253
|
+
this.selectedPermissions.delete(sessionId);
|
|
254
|
+
else
|
|
255
|
+
this.selectedPermissions.set(sessionId, preset);
|
|
252
256
|
this.publishProjection(sessionId, 'permissions', codexPermissionsProjection(preset), this.nextProjectionSeq());
|
|
253
257
|
}
|
|
254
258
|
commandList(args) {
|
|
@@ -275,19 +279,25 @@ export class CodexVirtualHarness {
|
|
|
275
279
|
result: { kind: 'error', text: 'CodeX Remote permission commands do not accept attachments.' },
|
|
276
280
|
};
|
|
277
281
|
const requested = (match[1] ?? '').trim();
|
|
278
|
-
if (requested === '')
|
|
282
|
+
if (requested === '') {
|
|
283
|
+
await this.readHistoryPage(threadId, { maxMessages: 1 }, signal);
|
|
279
284
|
return {
|
|
280
285
|
commandId,
|
|
281
|
-
result: { kind: 'success', text: `current preset ${this.permissionSelection(sessionId)}` },
|
|
286
|
+
result: { kind: 'success', text: `current preset ${this.permissionSelection(sessionId) ?? 'Host settings (not reported)'}` },
|
|
282
287
|
};
|
|
288
|
+
}
|
|
283
289
|
if (!isCodexPermissionPreset(requested))
|
|
284
290
|
return {
|
|
285
291
|
commandId,
|
|
286
292
|
result: { kind: 'error', text: `unknown preset "${requested}" (available: workspace-write, danger-full-access)` },
|
|
287
293
|
};
|
|
288
294
|
const result = await this.client.request('thread/resume', { threadId, permissionPreset: requested }, signal);
|
|
289
|
-
const effective = codexPermissionPresetFromResponse(result)
|
|
295
|
+
const effective = codexPermissionPresetFromResponse(result);
|
|
296
|
+
if (effective === undefined)
|
|
297
|
+
throw new Error('The Host did not confirm the CodeX permission preset.');
|
|
290
298
|
this.setPermissionSelection(sessionId, effective);
|
|
299
|
+
if (effective !== requested)
|
|
300
|
+
throw new Error('The Host did not apply the requested CodeX permission preset.');
|
|
291
301
|
return { commandId, result: { kind: 'success', text: `preset ${effective}` } };
|
|
292
302
|
}
|
|
293
303
|
sessionTitle(sessionId) {
|
|
@@ -499,8 +509,7 @@ export class CodexVirtualHarness {
|
|
|
499
509
|
}
|
|
500
510
|
if (frame.method === 'thread/settings/updated') {
|
|
501
511
|
const preset = codexPermissionPresetFromResponse(params);
|
|
502
|
-
|
|
503
|
-
this.setPermissionSelection(follow.sessionId, preset);
|
|
512
|
+
this.setPermissionSelection(follow.sessionId, preset);
|
|
504
513
|
return;
|
|
505
514
|
}
|
|
506
515
|
if (frame.method === 'turn/started') {
|
|
@@ -1006,17 +1015,15 @@ export class CodexVirtualHarness {
|
|
|
1006
1015
|
}
|
|
1007
1016
|
async forkSession(request, signal) {
|
|
1008
1017
|
const sessionId = requiredString(request.sessionId, 'sessionId');
|
|
1009
|
-
let permissionPreset = this.selectedPermissions.get(sessionId);
|
|
1010
1018
|
const result = record(await this.client.request('thread/fork', {
|
|
1011
1019
|
threadId: nativeThreadId(sessionId),
|
|
1012
|
-
...(permissionPreset === undefined ? {} : { permissionPreset }),
|
|
1013
1020
|
}, signal));
|
|
1014
|
-
permissionPreset = codexPermissionPresetFromResponse(result)
|
|
1021
|
+
const permissionPreset = codexPermissionPresetFromResponse(result);
|
|
1015
1022
|
const projected = projectCodexThread(record(result.thread));
|
|
1016
1023
|
if (projected === undefined)
|
|
1017
1024
|
return failure('internal', 'CodeX returned an invalid forked Thread.');
|
|
1018
1025
|
this.selectedModels.set(projected.id, this.modelSelection(sessionId, await this.models(signal)));
|
|
1019
|
-
this.
|
|
1026
|
+
this.setPermissionSelection(projected.id, permissionPreset);
|
|
1020
1027
|
await this.refreshAndPublishWorkspaces();
|
|
1021
1028
|
const seq = this.nextProjectionSeq();
|
|
1022
1029
|
this.publishProjection(projected.id, 'title', displayTitle(projected), seq);
|
|
@@ -1030,7 +1037,6 @@ export class CodexVirtualHarness {
|
|
|
1030
1037
|
return failure('attachment-error', 'CodeX virtual Sessions accept text and pasted PNG, JPEG, WebP, or GIF images only.');
|
|
1031
1038
|
const threadId = nativeThreadId(sessionId);
|
|
1032
1039
|
const selection = this.modelSelection(sessionId, await this.models(signal));
|
|
1033
|
-
let permissionPreset = this.selectedPermissions.get(sessionId);
|
|
1034
1040
|
const isFreshBlankThread = this.blankThreads.has(threadId) || this.pendingThreads.has(threadId);
|
|
1035
1041
|
await this.ensureRcFollow(sessionId);
|
|
1036
1042
|
if (!isFreshBlankThread) {
|
|
@@ -1039,8 +1045,7 @@ export class CodexVirtualHarness {
|
|
|
1039
1045
|
model: selection.model,
|
|
1040
1046
|
}, signal);
|
|
1041
1047
|
const serverPreset = codexPermissionPresetFromResponse(resumeResult);
|
|
1042
|
-
if (
|
|
1043
|
-
permissionPreset = serverPreset;
|
|
1048
|
+
if (serverPreset !== undefined) {
|
|
1044
1049
|
this.setPermissionSelection(sessionId, serverPreset);
|
|
1045
1050
|
}
|
|
1046
1051
|
}
|
|
@@ -1057,7 +1062,6 @@ export class CodexVirtualHarness {
|
|
|
1057
1062
|
threadId,
|
|
1058
1063
|
input,
|
|
1059
1064
|
...codexModelParams(selection),
|
|
1060
|
-
...(permissionPreset === undefined ? {} : { permissionPreset }),
|
|
1061
1065
|
}, signal);
|
|
1062
1066
|
}
|
|
1063
1067
|
this.blankThreads.delete(threadId);
|
|
@@ -1153,6 +1157,10 @@ export class CodexVirtualHarness {
|
|
|
1153
1157
|
if (!isCodexNativeHistoryPage(value, `codex:${threadId}`)) {
|
|
1154
1158
|
throw new Error('CodeX Remote returned an invalid paginated History.');
|
|
1155
1159
|
}
|
|
1160
|
+
if (Object.hasOwn(value, 'permissionPreset')) {
|
|
1161
|
+
const preset = value.permissionPreset;
|
|
1162
|
+
this.setPermissionSelection(`codex:${threadId}`, preset === 'workspace-write' || preset === 'danger-full-access' ? preset : undefined);
|
|
1163
|
+
}
|
|
1156
1164
|
this.cacheHistoryImages(value);
|
|
1157
1165
|
return value;
|
|
1158
1166
|
}
|
|
@@ -2256,7 +2264,7 @@ function isCanonicalBase64(value) {
|
|
|
2256
2264
|
function modelSelectionProjection(selection) {
|
|
2257
2265
|
return { lastUsed: selection, next: selection };
|
|
2258
2266
|
}
|
|
2259
|
-
function codexPermissionsProjection(
|
|
2267
|
+
function codexPermissionsProjection(preset) {
|
|
2260
2268
|
return {
|
|
2261
2269
|
options: [
|
|
2262
2270
|
{
|
|
@@ -2270,7 +2278,7 @@ function codexPermissionsProjection(currentValue) {
|
|
|
2270
2278
|
description: 'Full Host file access without approval prompts for subsequent turns in this virtual Session.',
|
|
2271
2279
|
},
|
|
2272
2280
|
],
|
|
2273
|
-
currentValue,
|
|
2281
|
+
currentValue: preset ?? 'Host settings (not reported)',
|
|
2274
2282
|
};
|
|
2275
2283
|
}
|
|
2276
2284
|
function codexImageLimitsProjection() {
|
|
@@ -2286,25 +2294,6 @@ function codexImageLimitsProjection() {
|
|
|
2286
2294
|
function isCodexPermissionPreset(value) {
|
|
2287
2295
|
return value === 'workspace-write' || value === 'danger-full-access';
|
|
2288
2296
|
}
|
|
2289
|
-
function codexPermissionPresetFromResponse(value) {
|
|
2290
|
-
const root = record(value);
|
|
2291
|
-
return codexPermissionPresetFromPolicyRecord(root)
|
|
2292
|
-
?? codexPermissionPresetFromPolicyRecord(record(root.threadSettings));
|
|
2293
|
-
}
|
|
2294
|
-
function codexPermissionPresetFromPolicyRecord(value) {
|
|
2295
|
-
const sandbox = value.sandbox ?? value.sandboxPolicy;
|
|
2296
|
-
if (value.approvalPolicy === 'never' && isDangerFullAccessSandbox(sandbox))
|
|
2297
|
-
return 'danger-full-access';
|
|
2298
|
-
if (value.approvalPolicy === 'on-request' && isWorkspaceWriteSandbox(sandbox))
|
|
2299
|
-
return 'workspace-write';
|
|
2300
|
-
return undefined;
|
|
2301
|
-
}
|
|
2302
|
-
function isDangerFullAccessSandbox(value) {
|
|
2303
|
-
return value === 'danger-full-access' || record(value).type === 'dangerFullAccess';
|
|
2304
|
-
}
|
|
2305
|
-
function isWorkspaceWriteSandbox(value) {
|
|
2306
|
-
return value === 'workspace-write' || record(value).type === 'workspaceWrite';
|
|
2307
|
-
}
|
|
2308
2297
|
function modelCatalog(directory) {
|
|
2309
2298
|
return {
|
|
2310
2299
|
default: directory.default,
|