ds-harness-remote 0.3.29 → 0.3.31
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 -9
- package/dist/api-proxy-switch.d.ts.map +1 -1
- package/dist/api-proxy-switch.js +2 -0
- package/dist/api-proxy-switch.js.map +1 -1
- package/dist/client-runtime.d.ts.map +1 -1
- package/dist/client-runtime.js +1 -0
- package/dist/client-runtime.js.map +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.github.js +71 -17
- package/dist/client.js +71 -17
- package/dist/client.js.map +1 -1
- package/dist/harness-api-bridge.d.ts +9 -3
- package/dist/harness-api-bridge.d.ts.map +1 -1
- package/dist/harness-api-bridge.js +250 -3
- package/dist/harness-api-bridge.js.map +1 -1
- package/dist/index.js +239 -5
- package/dist/index.js.map +2 -2
- package/dist/remote-file-content-provider.d.ts +11 -1
- package/dist/remote-file-content-provider.d.ts.map +1 -1
- package/dist/remote-file-content-provider.js +12 -1
- package/dist/remote-file-content-provider.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5636,7 +5636,9 @@ var SWITCHED_DOMAINS = [
|
|
|
5636
5636
|
"agentPresets",
|
|
5637
5637
|
"events",
|
|
5638
5638
|
"goals",
|
|
5639
|
-
"llm"
|
|
5639
|
+
"llm",
|
|
5640
|
+
"settings",
|
|
5641
|
+
"credentials"
|
|
5640
5642
|
];
|
|
5641
5643
|
var ApiProxySwitch = class {
|
|
5642
5644
|
remote;
|
|
@@ -13210,7 +13212,7 @@ function normalizeServerUrl(value) {
|
|
|
13210
13212
|
}
|
|
13211
13213
|
|
|
13212
13214
|
// src/version.ts
|
|
13213
|
-
var PLUGIN_VERSION = "0.3.
|
|
13215
|
+
var PLUGIN_VERSION = "0.3.31";
|
|
13214
13216
|
|
|
13215
13217
|
// src/server-api.ts
|
|
13216
13218
|
var HostServerApi = class {
|
|
@@ -13881,6 +13883,7 @@ var ClientModeRuntime = class {
|
|
|
13881
13883
|
...this.proxySwitch.status(),
|
|
13882
13884
|
connected: this.connected !== void 0,
|
|
13883
13885
|
transport: this.connected?.client.getStats().mode ?? "Disconnected",
|
|
13886
|
+
preferredTransports: this.config.forceRelay ? ["relay"] : ["lan", "p2p", "turn", "relay"],
|
|
13884
13887
|
remoteFeatures: this.connected?.features ?? remoteHostFeatures(),
|
|
13885
13888
|
...this.pendingWorkspaceSelection === void 0 ? {} : { workspaceSelection: { ...this.pendingWorkspaceSelection } },
|
|
13886
13889
|
hostAuthorizationAvailable: this.host !== void 0,
|
|
@@ -16072,6 +16075,59 @@ var commandExecuteSchema = external_exports.object({
|
|
|
16072
16075
|
var commandListSchema = external_exports.object({
|
|
16073
16076
|
agentId: external_exports.string().min(1).max(128)
|
|
16074
16077
|
}).strict();
|
|
16078
|
+
var credentialRefSchema = external_exports.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/, "Invalid credential reference name").max(128);
|
|
16079
|
+
var CONFIG_PLANE_SETTINGS_BYTES = 64 * 1024;
|
|
16080
|
+
var CONFIG_PLANE_MAX_OPS = 64;
|
|
16081
|
+
var CONFIG_PLANE_MAX_PATH_SEGMENTS = 8;
|
|
16082
|
+
var CONFIG_PLANE_MAX_PATH_SEGMENT_BYTES = 64;
|
|
16083
|
+
var CONFIG_PLANE_MAX_CREDENTIAL_VALUE_BYTES = 8 * 1024;
|
|
16084
|
+
var CONFIG_PLANE_MAX_BASE_URL_BYTES = 2048;
|
|
16085
|
+
var CONFIG_PLANE_MAX_NS_BYTES = 128;
|
|
16086
|
+
var settingsDescribeSchema = external_exports.object({}).strict();
|
|
16087
|
+
var settingsWriteBase = {
|
|
16088
|
+
ns: external_exports.string().min(1).max(CONFIG_PLANE_MAX_NS_BYTES),
|
|
16089
|
+
expectedRevision: external_exports.number().int().nonnegative().optional()
|
|
16090
|
+
};
|
|
16091
|
+
var settingsUpdateSchema = external_exports.object({
|
|
16092
|
+
...settingsWriteBase,
|
|
16093
|
+
patch: external_exports.record(external_exports.string().min(1).max(CONFIG_PLANE_MAX_PATH_SEGMENT_BYTES), external_exports.unknown())
|
|
16094
|
+
}).strict();
|
|
16095
|
+
var settingsReplaceSchema = external_exports.object({
|
|
16096
|
+
...settingsWriteBase,
|
|
16097
|
+
section: external_exports.record(external_exports.string().min(1).max(CONFIG_PLANE_MAX_PATH_SEGMENT_BYTES), external_exports.unknown())
|
|
16098
|
+
}).strict();
|
|
16099
|
+
var settingsOpSchema = external_exports.union([
|
|
16100
|
+
external_exports.object({
|
|
16101
|
+
op: external_exports.literal("set"),
|
|
16102
|
+
path: external_exports.array(external_exports.string().min(1).max(CONFIG_PLANE_MAX_PATH_SEGMENT_BYTES)).max(CONFIG_PLANE_MAX_PATH_SEGMENTS),
|
|
16103
|
+
value: external_exports.unknown()
|
|
16104
|
+
}).strict(),
|
|
16105
|
+
external_exports.object({
|
|
16106
|
+
op: external_exports.literal("unset"),
|
|
16107
|
+
path: external_exports.array(external_exports.string().min(1).max(CONFIG_PLANE_MAX_PATH_SEGMENT_BYTES)).max(CONFIG_PLANE_MAX_PATH_SEGMENTS)
|
|
16108
|
+
}).strict()
|
|
16109
|
+
]);
|
|
16110
|
+
var settingsMutateSchema = external_exports.object({
|
|
16111
|
+
...settingsWriteBase,
|
|
16112
|
+
ops: external_exports.array(settingsOpSchema).min(1).max(CONFIG_PLANE_MAX_OPS)
|
|
16113
|
+
}).strict();
|
|
16114
|
+
var credentialsDescribeSchema = external_exports.object({
|
|
16115
|
+
refs: external_exports.array(credentialRefSchema).max(CONFIG_PLANE_MAX_OPS)
|
|
16116
|
+
}).strict();
|
|
16117
|
+
var credentialsSetSchema = external_exports.object({
|
|
16118
|
+
ref: credentialRefSchema,
|
|
16119
|
+
value: external_exports.string().min(1).max(CONFIG_PLANE_MAX_CREDENTIAL_VALUE_BYTES)
|
|
16120
|
+
}).strict();
|
|
16121
|
+
var credentialsUnsetSchema = external_exports.object({
|
|
16122
|
+
ref: credentialRefSchema
|
|
16123
|
+
}).strict();
|
|
16124
|
+
var discoverModelsSchema = external_exports.object({
|
|
16125
|
+
settingsNs: external_exports.string().min(1).max(CONFIG_PLANE_MAX_NS_BYTES),
|
|
16126
|
+
provider: external_exports.string().min(1).max(CONFIG_PLANE_MAX_NS_BYTES).optional(),
|
|
16127
|
+
baseURL: external_exports.string().max(CONFIG_PLANE_MAX_BASE_URL_BYTES).optional(),
|
|
16128
|
+
api: external_exports.string().min(1).max(CONFIG_PLANE_MAX_NS_BYTES).optional(),
|
|
16129
|
+
apiKey: external_exports.string().min(1).max(CONFIG_PLANE_MAX_CREDENTIAL_VALUE_BYTES).optional()
|
|
16130
|
+
}).strict();
|
|
16075
16131
|
var HARNESS_API_ALLOWLIST = [
|
|
16076
16132
|
"session.list",
|
|
16077
16133
|
"session.search",
|
|
@@ -16111,7 +16167,15 @@ var HARNESS_API_ALLOWLIST = [
|
|
|
16111
16167
|
"commands.execute",
|
|
16112
16168
|
"commands.list",
|
|
16113
16169
|
"llm.providers",
|
|
16114
|
-
"llm.models"
|
|
16170
|
+
"llm.models",
|
|
16171
|
+
"llm.discoverModels",
|
|
16172
|
+
"settings.describe",
|
|
16173
|
+
"settings.update",
|
|
16174
|
+
"settings.replace",
|
|
16175
|
+
"settings.mutate",
|
|
16176
|
+
"credentials.describe",
|
|
16177
|
+
"credentials.set",
|
|
16178
|
+
"credentials.unset"
|
|
16115
16179
|
];
|
|
16116
16180
|
var NATIVE_CALL_TIMEOUT_MS = 3e4;
|
|
16117
16181
|
var MAX_ACTIVE_API_TRANSFERS = 2;
|
|
@@ -16425,7 +16489,8 @@ function createMethodMap(api, typertGateway) {
|
|
|
16425
16489
|
const domain = domainProperty(wireDomain);
|
|
16426
16490
|
const implementation = domains[domain]?.[action];
|
|
16427
16491
|
if (typeof implementation !== "function") continue;
|
|
16428
|
-
|
|
16492
|
+
const scoped = CONFIG_PLANE_METHODS.includes(method) ? scopeConfigPlaneMethod(api, method, implementation) : void 0;
|
|
16493
|
+
methods.set(method, scoped ?? implementation.bind(domains[domain]));
|
|
16429
16494
|
}
|
|
16430
16495
|
return methods;
|
|
16431
16496
|
}
|
|
@@ -16437,6 +16502,167 @@ function domainProperty(wireDomain) {
|
|
|
16437
16502
|
if (wireDomain === "goal") return "goals";
|
|
16438
16503
|
return wireDomain;
|
|
16439
16504
|
}
|
|
16505
|
+
var CONFIG_PLANE_METHODS = [
|
|
16506
|
+
"llm.discoverModels",
|
|
16507
|
+
"settings.describe",
|
|
16508
|
+
"settings.update",
|
|
16509
|
+
"settings.replace",
|
|
16510
|
+
"settings.mutate",
|
|
16511
|
+
"credentials.describe",
|
|
16512
|
+
"credentials.set",
|
|
16513
|
+
"credentials.unset"
|
|
16514
|
+
];
|
|
16515
|
+
function scopeConfigPlaneMethod(api, method, native) {
|
|
16516
|
+
switch (method) {
|
|
16517
|
+
case "llm.discoverModels":
|
|
16518
|
+
return async (request, signal) => {
|
|
16519
|
+
const payload = parseConfigPlane(discoverModelsSchema, request.payload, "llm.discoverModels");
|
|
16520
|
+
if (payload.baseURL !== void 0) validateDiscoverBaseUrl(payload.baseURL);
|
|
16521
|
+
try {
|
|
16522
|
+
const response = await native({ rpcId: request.rpcId, payload }, signal);
|
|
16523
|
+
return sanitizeModelDiscoveryResponse(response, payload.settingsNs);
|
|
16524
|
+
} catch {
|
|
16525
|
+
return modelDiscoveryFailure(request.rpcId, payload.settingsNs);
|
|
16526
|
+
}
|
|
16527
|
+
};
|
|
16528
|
+
case "settings.describe":
|
|
16529
|
+
return async (request, signal) => {
|
|
16530
|
+
parseConfigPlane(settingsDescribeSchema, request.payload, "settings.describe");
|
|
16531
|
+
const response = await native({ rpcId: request.rpcId, payload: {} }, signal);
|
|
16532
|
+
return disableRemoteSettingsDocument(response);
|
|
16533
|
+
};
|
|
16534
|
+
case "settings.update":
|
|
16535
|
+
return async (request, signal) => {
|
|
16536
|
+
const payload = parseConfigPlane(settingsUpdateSchema, request.payload, "settings.update");
|
|
16537
|
+
await assertRegisteredSettingsNamespace(api, payload.ns);
|
|
16538
|
+
assertSerializedBytes(payload.patch, CONFIG_PLANE_SETTINGS_BYTES, "settings.update patch");
|
|
16539
|
+
return native({ rpcId: request.rpcId, payload }, signal);
|
|
16540
|
+
};
|
|
16541
|
+
case "settings.replace":
|
|
16542
|
+
return async (request, signal) => {
|
|
16543
|
+
const payload = parseConfigPlane(settingsReplaceSchema, request.payload, "settings.replace");
|
|
16544
|
+
await assertRegisteredSettingsNamespace(api, payload.ns);
|
|
16545
|
+
assertSerializedBytes(payload.section, CONFIG_PLANE_SETTINGS_BYTES, "settings.replace section");
|
|
16546
|
+
return native({ rpcId: request.rpcId, payload }, signal);
|
|
16547
|
+
};
|
|
16548
|
+
case "settings.mutate":
|
|
16549
|
+
return async (request, signal) => {
|
|
16550
|
+
const payload = parseConfigPlane(settingsMutateSchema, request.payload, "settings.mutate");
|
|
16551
|
+
await assertRegisteredSettingsNamespace(api, payload.ns);
|
|
16552
|
+
assertSerializedBytes(payload.ops, CONFIG_PLANE_SETTINGS_BYTES, "settings.mutate ops");
|
|
16553
|
+
return native({ rpcId: request.rpcId, payload }, signal);
|
|
16554
|
+
};
|
|
16555
|
+
case "credentials.describe":
|
|
16556
|
+
return async (request, signal) => {
|
|
16557
|
+
const payload = parseConfigPlane(credentialsDescribeSchema, request.payload, "credentials.describe");
|
|
16558
|
+
return native({ rpcId: request.rpcId, payload }, signal);
|
|
16559
|
+
};
|
|
16560
|
+
case "credentials.set":
|
|
16561
|
+
return async (request, signal) => {
|
|
16562
|
+
const payload = parseConfigPlane(credentialsSetSchema, request.payload, "credentials.set");
|
|
16563
|
+
return native({ rpcId: request.rpcId, payload }, signal);
|
|
16564
|
+
};
|
|
16565
|
+
case "credentials.unset":
|
|
16566
|
+
return async (request, signal) => {
|
|
16567
|
+
const payload = parseConfigPlane(credentialsUnsetSchema, request.payload, "credentials.unset");
|
|
16568
|
+
return native({ rpcId: request.rpcId, payload }, signal);
|
|
16569
|
+
};
|
|
16570
|
+
}
|
|
16571
|
+
}
|
|
16572
|
+
function parseConfigPlane(schema, payload, label) {
|
|
16573
|
+
try {
|
|
16574
|
+
return schema.parse(payload);
|
|
16575
|
+
} catch (error) {
|
|
16576
|
+
if (error instanceof external_exports.ZodError) {
|
|
16577
|
+
throw new RpcError("INVALID_MESSAGE", `The ${label} payload is invalid for the remote channel.`);
|
|
16578
|
+
}
|
|
16579
|
+
throw error;
|
|
16580
|
+
}
|
|
16581
|
+
}
|
|
16582
|
+
function validateDiscoverBaseUrl(value) {
|
|
16583
|
+
let url;
|
|
16584
|
+
try {
|
|
16585
|
+
url = new URL(value);
|
|
16586
|
+
} catch {
|
|
16587
|
+
throw new RpcError("INVALID_MESSAGE", "The model discovery baseURL is invalid.");
|
|
16588
|
+
}
|
|
16589
|
+
const local = url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "::1";
|
|
16590
|
+
if (url.protocol !== "https:" && !(local && url.protocol === "http:")) {
|
|
16591
|
+
throw new RpcError("INVALID_MESSAGE", "The model discovery baseURL must use HTTPS (HTTP is allowed only for localhost).");
|
|
16592
|
+
}
|
|
16593
|
+
if (url.username !== "" || url.password !== "") {
|
|
16594
|
+
throw new RpcError("INVALID_MESSAGE", "The model discovery baseURL must not contain credentials.");
|
|
16595
|
+
}
|
|
16596
|
+
if (url.hash !== "") {
|
|
16597
|
+
throw new RpcError("INVALID_MESSAGE", "The model discovery baseURL must not contain a fragment.");
|
|
16598
|
+
}
|
|
16599
|
+
}
|
|
16600
|
+
function assertSerializedBytes(value, maxBytes, label) {
|
|
16601
|
+
const bytes = new TextEncoder().encode(JSON.stringify(value)).byteLength;
|
|
16602
|
+
if (bytes > maxBytes) {
|
|
16603
|
+
throw new RpcError("INVALID_MESSAGE", `The ${label} exceeds the ${maxBytes}-byte remote limit.`);
|
|
16604
|
+
}
|
|
16605
|
+
}
|
|
16606
|
+
function sanitizeModelDiscoveryResponse(response, settingsNs) {
|
|
16607
|
+
const result = response.result;
|
|
16608
|
+
if (typeof result === "object" && result !== null && "ok" in result && result.ok === true) return response;
|
|
16609
|
+
return modelDiscoveryFailure(response.rpcId, settingsNs);
|
|
16610
|
+
}
|
|
16611
|
+
function modelDiscoveryFailure(rpcId, settingsNs) {
|
|
16612
|
+
return {
|
|
16613
|
+
rpcId,
|
|
16614
|
+
result: {
|
|
16615
|
+
ok: false,
|
|
16616
|
+
error: {
|
|
16617
|
+
code: "model-discovery-failed",
|
|
16618
|
+
message: "Model discovery failed.",
|
|
16619
|
+
details: { settingsNs }
|
|
16620
|
+
}
|
|
16621
|
+
}
|
|
16622
|
+
};
|
|
16623
|
+
}
|
|
16624
|
+
function disableRemoteSettingsDocument(response) {
|
|
16625
|
+
const result = response.result;
|
|
16626
|
+
if (typeof result !== "object" || result === null || !("ok" in result) || result.ok !== true) return response;
|
|
16627
|
+
const value = result.value;
|
|
16628
|
+
if (typeof value !== "object" || value === null) return response;
|
|
16629
|
+
return { ...response, result: { ...result, value: { ...value, hasDocument: false } } };
|
|
16630
|
+
}
|
|
16631
|
+
var EMPTY_SETTINGS_NAMESPACES = /* @__PURE__ */ new Set();
|
|
16632
|
+
async function assertRegisteredSettingsNamespace(api, ns) {
|
|
16633
|
+
const allowed = await registeredSettingsNamespaces(api);
|
|
16634
|
+
if (!allowed.has(ns)) throw deniedSettingsNamespace(ns);
|
|
16635
|
+
}
|
|
16636
|
+
async function registeredSettingsNamespaces(api) {
|
|
16637
|
+
const settings = api.settings;
|
|
16638
|
+
const describe = settings?.describe;
|
|
16639
|
+
if (typeof describe !== "function") return EMPTY_SETTINGS_NAMESPACES;
|
|
16640
|
+
const response = await withTimeout(
|
|
16641
|
+
describe.call(settings, { rpcId: "bridge-settings-scope", payload: {} }, AbortSignal.timeout(NATIVE_CALL_TIMEOUT_MS)),
|
|
16642
|
+
NATIVE_CALL_TIMEOUT_MS,
|
|
16643
|
+
"The Host settings.describe call timed out."
|
|
16644
|
+
);
|
|
16645
|
+
const value = unwrapNativeValue(response, "settings.describe");
|
|
16646
|
+
const list = typeof value === "object" && value !== null ? value.namespaces : void 0;
|
|
16647
|
+
if (!Array.isArray(list)) return EMPTY_SETTINGS_NAMESPACES;
|
|
16648
|
+
const namespaces = /* @__PURE__ */ new Set();
|
|
16649
|
+
for (const item of list) {
|
|
16650
|
+
if (typeof item !== "object" || item === null) continue;
|
|
16651
|
+
const ns = item.ns;
|
|
16652
|
+
if (typeof ns === "string" && ns.length > 0) namespaces.add(ns);
|
|
16653
|
+
}
|
|
16654
|
+
return namespaces;
|
|
16655
|
+
}
|
|
16656
|
+
function unwrapNativeValue(response, method) {
|
|
16657
|
+
const result = response.result;
|
|
16658
|
+
if (typeof result !== "object" || result === null || !("ok" in result) || result.ok !== true || !("value" in result)) {
|
|
16659
|
+
throw new RpcError("INTERNAL_ERROR", `The Host ${method} call did not succeed.`);
|
|
16660
|
+
}
|
|
16661
|
+
return result.value;
|
|
16662
|
+
}
|
|
16663
|
+
function deniedSettingsNamespace(ns) {
|
|
16664
|
+
return new RpcError("METHOD_NOT_ALLOWED", `Harness settings namespace ${JSON.stringify(ns)} is not registered on the Host.`);
|
|
16665
|
+
}
|
|
16440
16666
|
function deniedMethod(method) {
|
|
16441
16667
|
return new RpcError("METHOD_NOT_ALLOWED", `Harness API method ${JSON.stringify(method)} is not available in remote mode.`);
|
|
16442
16668
|
}
|
|
@@ -16723,11 +16949,16 @@ function shortId5(value) {
|
|
|
16723
16949
|
}
|
|
16724
16950
|
|
|
16725
16951
|
// src/remote-file-content-provider.ts
|
|
16726
|
-
|
|
16952
|
+
var REMOTE_FILE_SAVE_AS_MAX_BYTES = 100 * 1024 * 1024;
|
|
16953
|
+
function createRemoteFileContentProvider(call, options = {}) {
|
|
16727
16954
|
return {
|
|
16728
16955
|
id: "dsh-remote-files",
|
|
16729
16956
|
priority: 1e4,
|
|
16730
16957
|
supports: () => true,
|
|
16958
|
+
saveAsAllowed: () => ({
|
|
16959
|
+
allowed: currentSaveAsAllowed(options.saveAsAllowed),
|
|
16960
|
+
maxBytes: options.saveAsMaxBytes ?? REMOTE_FILE_SAVE_AS_MAX_BYTES
|
|
16961
|
+
}),
|
|
16731
16962
|
async stat(locator, signal) {
|
|
16732
16963
|
const value = await call("fileviewer.stat", { path: locator }, signal);
|
|
16733
16964
|
if (!value.exists) return void 0;
|
|
@@ -16776,6 +17007,9 @@ function createRemoteFileContentProvider(call) {
|
|
|
16776
17007
|
}
|
|
16777
17008
|
};
|
|
16778
17009
|
}
|
|
17010
|
+
function currentSaveAsAllowed(value) {
|
|
17011
|
+
return typeof value === "function" ? value() : value === true;
|
|
17012
|
+
}
|
|
16779
17013
|
function decodeBase64(value) {
|
|
16780
17014
|
const binary = atob(value);
|
|
16781
17015
|
const bytes = new Uint8Array(binary.length);
|