ds-harness-remote 0.3.20 → 0.3.21

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/dist/index.js CHANGED
@@ -4111,7 +4111,8 @@ var helloPayloadSchema = external_exports.object({
4111
4111
  accessToken: external_exports.string().min(1),
4112
4112
  protocols: external_exports.array(external_exports.number().int()).min(1),
4113
4113
  capabilities: external_exports.array(external_exports.string()),
4114
- clientVersion: external_exports.string().optional()
4114
+ clientVersion: external_exports.string().optional(),
4115
+ harnessVersion: external_exports.string().optional()
4115
4116
  });
4116
4117
  var helloAckPayloadSchema = external_exports.object({
4117
4118
  protocol: external_exports.literal(PROTOCOL_VERSION),
@@ -4359,6 +4360,14 @@ function cryptoRandomId() {
4359
4360
  }
4360
4361
 
4361
4362
  // ../client-core/dist/index.js
4363
+ var RemoteClientError = class extends Error {
4364
+ code;
4365
+ constructor(code, message, options) {
4366
+ super(message, options);
4367
+ this.code = code;
4368
+ this.name = "RemoteClientError";
4369
+ }
4370
+ };
4362
4371
  var RemoteClientCore = class {
4363
4372
  transport;
4364
4373
  timeoutMs;
@@ -4367,6 +4376,7 @@ var RemoteClientCore = class {
4367
4376
  unsubscribeTransport;
4368
4377
  unsubscribeClose;
4369
4378
  closeHandlers = /* @__PURE__ */ new Set();
4379
+ closeNotified = false;
4370
4380
  constructor(transport, timeoutMs = 3e4) {
4371
4381
  this.transport = transport;
4372
4382
  this.timeoutMs = timeoutMs;
@@ -4374,6 +4384,7 @@ var RemoteClientCore = class {
4374
4384
  async connect() {
4375
4385
  if (this.unsubscribeTransport !== void 0)
4376
4386
  return;
4387
+ this.closeNotified = false;
4377
4388
  this.unsubscribeTransport = this.transport.onMessage((data) => this.handleMessage(data));
4378
4389
  this.unsubscribeClose = this.transport.onClose?.(() => this.handleTransportClose());
4379
4390
  try {
@@ -4387,23 +4398,24 @@ var RemoteClientCore = class {
4387
4398
  }
4388
4399
  }
4389
4400
  async rpc(method, params, signal) {
4390
- signal?.throwIfAborted();
4401
+ if (signal?.aborted)
4402
+ throw rpcAbortedError(method, signal.reason);
4391
4403
  const request = createRpcRequest(method, params);
4392
4404
  const result = new Promise((resolve2, reject) => {
4393
4405
  const timer = setTimeout(() => {
4394
- const pending2 = this.pending.get(request.id);
4395
- pending2?.removeAbort?.();
4396
- this.pending.delete(request.id);
4397
- reject(new Error(`RPC ${method} timed out`));
4406
+ this.rejectPending(request.id, new RemoteClientError("RPC_TIMEOUT", `RPC ${method} timed out after ${this.timeoutMs}ms`));
4398
4407
  }, this.timeoutMs);
4399
- const pending = { resolve: resolve2, reject, timer };
4408
+ const pending = {
4409
+ method,
4410
+ resolve: resolve2,
4411
+ reject,
4412
+ timer
4413
+ };
4400
4414
  if (signal !== void 0) {
4401
4415
  const onAbort = () => {
4402
4416
  if (this.pending.get(request.id) !== pending)
4403
4417
  return;
4404
- clearTimeout(timer);
4405
- this.pending.delete(request.id);
4406
- reject(signal.reason instanceof Error ? signal.reason : new Error("RPC was cancelled"));
4418
+ this.rejectPending(request.id, rpcAbortedError(method, signal.reason));
4407
4419
  };
4408
4420
  signal.addEventListener("abort", onAbort, { once: true });
4409
4421
  pending.removeAbort = () => signal.removeEventListener("abort", onAbort);
@@ -4411,15 +4423,12 @@ var RemoteClientCore = class {
4411
4423
  this.pending.set(request.id, pending);
4412
4424
  });
4413
4425
  try {
4414
- await this.transport.send(encodeMessage(request));
4426
+ const send = this.transport.send(encodeMessage(request));
4427
+ void send.catch((error) => {
4428
+ this.rejectPending(request.id, transportSendError(error));
4429
+ });
4415
4430
  } catch (error) {
4416
- const pending = this.pending.get(request.id);
4417
- if (pending !== void 0) {
4418
- clearTimeout(pending.timer);
4419
- pending.removeAbort?.();
4420
- }
4421
- this.pending.delete(request.id);
4422
- throw error;
4431
+ this.rejectPending(request.id, transportSendError(error));
4423
4432
  }
4424
4433
  return result;
4425
4434
  }
@@ -4439,23 +4448,13 @@ var RemoteClientCore = class {
4439
4448
  this.unsubscribeTransport = void 0;
4440
4449
  this.unsubscribeClose?.();
4441
4450
  this.unsubscribeClose = void 0;
4451
+ this.rejectAllPending((pending) => new RemoteClientError("CLIENT_CLOSED", `RPC ${pending.method} terminated because the remote client closed`));
4452
+ this.notifyClose();
4442
4453
  await this.transport.close();
4443
- for (const pending of this.pending.values()) {
4444
- clearTimeout(pending.timer);
4445
- pending.removeAbort?.();
4446
- pending.reject(new Error("remote client closed"));
4447
- }
4448
- this.pending.clear();
4449
4454
  }
4450
4455
  handleTransportClose() {
4451
- for (const pending of this.pending.values()) {
4452
- clearTimeout(pending.timer);
4453
- pending.removeAbort?.();
4454
- pending.reject(new Error("remote transport closed"));
4455
- }
4456
- this.pending.clear();
4457
- for (const handler of this.closeHandlers)
4458
- handler();
4456
+ this.rejectAllPending((pending) => new RemoteClientError("TRANSPORT_CLOSED", `RPC ${pending.method} terminated because the remote transport closed`));
4457
+ this.notifyClose();
4459
4458
  }
4460
4459
  handleMessage(data) {
4461
4460
  const message = decodeMessage(data);
@@ -4470,24 +4469,54 @@ var RemoteClientCore = class {
4470
4469
  }
4471
4470
  }
4472
4471
  handleResponse(message) {
4473
- const pending = this.pending.get(message.payload.requestId);
4472
+ const pending = this.takePending(message.payload.requestId);
4474
4473
  if (pending === void 0)
4475
4474
  return;
4476
- this.pending.delete(message.payload.requestId);
4477
- clearTimeout(pending.timer);
4478
- pending.removeAbort?.();
4479
4475
  pending.resolve(message.payload.result);
4480
4476
  }
4481
4477
  handleError(message) {
4482
- const pending = this.pending.get(message.payload.requestId);
4478
+ const pending = this.takePending(message.payload.requestId);
4483
4479
  if (pending === void 0)
4484
4480
  return;
4485
- this.pending.delete(message.payload.requestId);
4481
+ pending.reject(Object.assign(new Error(message.payload.message), { code: message.payload.code }));
4482
+ }
4483
+ takePending(requestId) {
4484
+ const pending = this.pending.get(requestId);
4485
+ if (pending === void 0)
4486
+ return void 0;
4487
+ this.pending.delete(requestId);
4486
4488
  clearTimeout(pending.timer);
4487
4489
  pending.removeAbort?.();
4488
- pending.reject(Object.assign(new Error(message.payload.message), { code: message.payload.code }));
4490
+ return pending;
4491
+ }
4492
+ rejectPending(requestId, error) {
4493
+ const pending = this.takePending(requestId);
4494
+ if (pending === void 0)
4495
+ return false;
4496
+ pending.reject(error);
4497
+ return true;
4498
+ }
4499
+ rejectAllPending(createError) {
4500
+ for (const requestId of [...this.pending.keys()]) {
4501
+ const pending = this.takePending(requestId);
4502
+ if (pending !== void 0)
4503
+ pending.reject(createError(pending));
4504
+ }
4505
+ }
4506
+ notifyClose() {
4507
+ if (this.closeNotified)
4508
+ return;
4509
+ this.closeNotified = true;
4510
+ for (const handler of this.closeHandlers)
4511
+ handler();
4489
4512
  }
4490
4513
  };
4514
+ function rpcAbortedError(method, reason) {
4515
+ return new RemoteClientError("RPC_ABORTED", `RPC ${method} was aborted`, reason === void 0 ? void 0 : { cause: reason });
4516
+ }
4517
+ function transportSendError(error) {
4518
+ return error instanceof Error ? error : new Error("remote transport send failed", { cause: error });
4519
+ }
4491
4520
 
4492
4521
  // ../webrtc/dist/transport.js
4493
4522
  var BaseTransport = class {
@@ -12966,7 +12995,7 @@ function normalizeLegacyResponse(method, response) {
12966
12995
  };
12967
12996
  }
12968
12997
  function isRemoteDisconnect(error) {
12969
- return error instanceof Error && (error.message === "remote transport closed" || error.message === "remote client closed");
12998
+ return error instanceof RemoteClientError && (error.code === "TRANSPORT_CLOSED" || error.code === "CLIENT_CLOSED");
12970
12999
  }
12971
13000
  var AsyncFrameQueue = class {
12972
13001
  values = [];
@@ -13092,7 +13121,7 @@ function normalizeServerUrl(value) {
13092
13121
  }
13093
13122
 
13094
13123
  // src/version.ts
13095
- var PLUGIN_VERSION = "0.3.20";
13124
+ var PLUGIN_VERSION = "0.3.21";
13096
13125
 
13097
13126
  // src/server-api.ts
13098
13127
  var HostServerApi = class {
@@ -13315,8 +13344,7 @@ var HostServerApi = class {
13315
13344
  role: this.role,
13316
13345
  platform: platform(),
13317
13346
  identityKey: identity.publicKey,
13318
- clientVersion: PLUGIN_VERSION,
13319
- ...this.role === "host" ? { harnessVersion: "0.1.0-rc.6" } : {}
13347
+ clientVersion: PLUGIN_VERSION
13320
13348
  };
13321
13349
  }
13322
13350
  saveTokens(identity, tokens, authorization) {
@@ -13735,6 +13763,7 @@ var ClientModeRuntime = class {
13735
13763
  }
13736
13764
  identity;
13737
13765
  connected;
13766
+ pendingWorkspaceSelection;
13738
13767
  proxySwitch;
13739
13768
  gatewaySwitch;
13740
13769
  closed = false;
@@ -13764,6 +13793,7 @@ var ClientModeRuntime = class {
13764
13793
  connected: this.connected !== void 0,
13765
13794
  transport: this.connected?.client.getStats().mode ?? "Disconnected",
13766
13795
  remoteFeatures: this.connected?.features ?? remoteHostFeatures(),
13796
+ ...this.pendingWorkspaceSelection === void 0 ? {} : { workspaceSelection: { ...this.pendingWorkspaceSelection } },
13767
13797
  hostAuthorizationAvailable: this.host !== void 0,
13768
13798
  ...this.host === void 0 ? {} : { host: this.host.hostStatus() }
13769
13799
  };
@@ -13832,6 +13862,7 @@ var ClientModeRuntime = class {
13832
13862
  async clearClientAuthorization() {
13833
13863
  const previous = this.connected;
13834
13864
  this.connected = void 0;
13865
+ this.pendingWorkspaceSelection = void 0;
13835
13866
  this.proxySwitch.selectLocal();
13836
13867
  this.gatewaySwitch.selectLocal();
13837
13868
  await previous?.client.close().catch(() => void 0);
@@ -13855,6 +13886,7 @@ var ClientModeRuntime = class {
13855
13886
  this.gatewaySwitch.selectLocal();
13856
13887
  const previous2 = this.connected;
13857
13888
  this.connected = void 0;
13889
+ this.pendingWorkspaceSelection = void 0;
13858
13890
  await previous2?.client.close().catch(() => void 0);
13859
13891
  this.logger.info("Harness target switched", { mode: "local" });
13860
13892
  return this.status();
@@ -13865,6 +13897,7 @@ var ClientModeRuntime = class {
13865
13897
  const next = await this.connect(targetDeviceId, signal);
13866
13898
  const previous = this.connected;
13867
13899
  this.connected = next;
13900
+ this.pendingWorkspaceSelection = void 0;
13868
13901
  const remoteApi = new RemoteHarnessApiProxy(next.client).api;
13869
13902
  this.proxySwitch.selectRemote(remoteApi, { deviceId: next.target.deviceId, name: next.target.name });
13870
13903
  this.selectRemoteCommands(next);
@@ -13902,14 +13935,24 @@ var ClientModeRuntime = class {
13902
13935
  const workspace = unwrapNativeResult(response);
13903
13936
  this.proxySwitch.selectRemote(api, { deviceId: remote.target.deviceId, name: remote.target.name });
13904
13937
  this.selectRemoteCommands(remote);
13938
+ const workspaceId = workspaceRecordId(workspace.workspace);
13939
+ this.pendingWorkspaceSelection = { targetDeviceId: remote.target.deviceId, workspaceId };
13905
13940
  this.logger.info("Remote workspace opened", { targetDeviceId: shortId(remote.target.deviceId) });
13906
13941
  return { ...this.status(), workspace };
13907
13942
  }
13943
+ consumeWorkspaceSelection(selection) {
13944
+ const pending = this.pendingWorkspaceSelection;
13945
+ if (pending?.targetDeviceId === selection.targetDeviceId && pending.workspaceId === selection.workspaceId) {
13946
+ this.pendingWorkspaceSelection = void 0;
13947
+ }
13948
+ return this.status();
13949
+ }
13908
13950
  async close() {
13909
13951
  if (this.closed) return;
13910
13952
  this.closed = true;
13911
13953
  this.proxySwitch.selectLocal();
13912
13954
  this.gatewaySwitch.selectLocal();
13955
+ this.pendingWorkspaceSelection = void 0;
13913
13956
  await this.connected?.client.close().catch(() => void 0);
13914
13957
  this.connected = void 0;
13915
13958
  this.proxySwitch.restore();
@@ -13982,6 +14025,7 @@ var ClientModeRuntime = class {
13982
14025
  client.onClose(() => {
13983
14026
  if (this.connected?.client !== client) return;
13984
14027
  this.connected = void 0;
14028
+ this.pendingWorkspaceSelection = void 0;
13985
14029
  this.proxySwitch.selectLocal();
13986
14030
  this.gatewaySwitch.selectLocal();
13987
14031
  void client.close().catch(() => void 0);
@@ -14047,6 +14091,16 @@ var ClientModeRuntime = class {
14047
14091
  }
14048
14092
  return ok(await this.openRemoteWorkspace(value.targetDeviceId, value.path, signal));
14049
14093
  }
14094
+ if (endpoint === "workspace.selection.consume") {
14095
+ const value = record(payload);
14096
+ if (typeof value.targetDeviceId !== "string" || typeof value.workspaceId !== "string") {
14097
+ throw new ClientModeError("INVALID_MESSAGE", "A Host and Workspace are required.");
14098
+ }
14099
+ return ok(this.consumeWorkspaceSelection({
14100
+ targetDeviceId: value.targetDeviceId,
14101
+ workspaceId: value.workspaceId
14102
+ }));
14103
+ }
14050
14104
  if (endpoint === "fileviewer.stat" || endpoint === "fileviewer.readRange" || endpoint === "fileviewer.list") {
14051
14105
  const method = endpoint === "fileviewer.stat" ? "stat" : endpoint === "fileviewer.readRange" ? "readRange" : "list";
14052
14106
  return ok(await this.callRemoteFileViewer(method, payload, signal));
@@ -14157,6 +14211,12 @@ function unwrapNativeResult(response) {
14157
14211
  }
14158
14212
  return result.value;
14159
14213
  }
14214
+ function workspaceRecordId(value) {
14215
+ if (typeof value !== "object" || value === null || !("workspaceId" in value) || typeof value.workspaceId !== "string" || value.workspaceId.length === 0) {
14216
+ throw new ClientModeError("INVALID_MESSAGE", "The remote Host returned an invalid Workspace.");
14217
+ }
14218
+ return value.workspaceId;
14219
+ }
14160
14220
  function fail(error) {
14161
14221
  const source = error instanceof Error ? error : void 0;
14162
14222
  const remoteCode = source !== void 0 && "code" in source && typeof source.code === "string" ? source.code : source instanceof ClientModeError ? source.code : void 0;
@@ -14704,6 +14764,10 @@ function redact(value, key = "") {
14704
14764
  return Object.fromEntries(Object.entries(value).map(([childKey, child]) => [childKey, redact(child, childKey)]));
14705
14765
  }
14706
14766
 
14767
+ // src/service.ts
14768
+ import { randomUUID } from "node:crypto";
14769
+ import { RpcId } from "@deepseek-ai/dsh-host-apiproxy/api";
14770
+
14707
14771
  // src/connection-controller.ts
14708
14772
  var ConnectionController = class {
14709
14773
  constructor(identities, createRouter, logger) {
@@ -14872,6 +14936,36 @@ function shortId2(value) {
14872
14936
  return value.length <= 12 ? value : `${value.slice(0, 8)}\u2026${value.slice(-4)}`;
14873
14937
  }
14874
14938
 
14939
+ // src/harness-version.ts
14940
+ import { readFile as readFile3 } from "node:fs/promises";
14941
+ import { dirname as dirname3, isAbsolute, join as join3 } from "node:path";
14942
+ var LEGACY_PLACEHOLDER_VERSION = "0.0.1";
14943
+ function normalizeHarnessVersion(value) {
14944
+ if (typeof value !== "string") return void 0;
14945
+ const version = value.trim();
14946
+ if (version.length === 0 || version.length > 64 || /[\u0000-\u001f]/u.test(version)) return void 0;
14947
+ return version;
14948
+ }
14949
+ function selectHarnessVersion(reportedVersion, distributionVersion) {
14950
+ if (reportedVersion !== void 0 && reportedVersion !== LEGACY_PLACEHOLDER_VERSION) return reportedVersion;
14951
+ return distributionVersion;
14952
+ }
14953
+ async function readHarnessDistributionVersion(entrypoint = process.argv[1]) {
14954
+ if (entrypoint === void 0 || !isAbsolute(entrypoint)) return void 0;
14955
+ let directory = dirname3(entrypoint);
14956
+ for (let depth = 0; depth < 8; depth += 1) {
14957
+ try {
14958
+ const manifest = JSON.parse(await readFile3(join3(directory, "package.json"), "utf8"));
14959
+ if (manifest.name === "@deepseek-ai/dsh") return normalizeHarnessVersion(manifest.version);
14960
+ } catch {
14961
+ }
14962
+ const parent = dirname3(directory);
14963
+ if (parent === directory) break;
14964
+ directory = parent;
14965
+ }
14966
+ return void 0;
14967
+ }
14968
+
14875
14969
  // src/rpc-router.ts
14876
14970
  var wireRequestSchema = external_exports.object({ method: external_exports.string().min(1), params: external_exports.unknown() }).strict();
14877
14971
  var apiMethods = /* @__PURE__ */ new Set([
@@ -15091,7 +15185,7 @@ function isOversizedListing(value) {
15091
15185
  // src/server-connection.ts
15092
15186
  var DEFAULT_WEBRTC_NEGOTIATE_TIMEOUT_MS = 8e3;
15093
15187
  var HostServerConnection = class {
15094
- constructor(config, identity, identities, api, connections, logger, createWebSocket = (url) => new WebSocket(url), rtcFactoryProvider, hostCapabilities = () => ["harness.api.v1"]) {
15188
+ constructor(config, identity, identities, api, connections, logger, createWebSocket = (url) => new WebSocket(url), rtcFactoryProvider, hostCapabilities = () => ["harness.api.v1"], harnessVersion) {
15095
15189
  this.config = config;
15096
15190
  this.identity = identity;
15097
15191
  this.identities = identities;
@@ -15101,6 +15195,7 @@ var HostServerConnection = class {
15101
15195
  this.createWebSocket = createWebSocket;
15102
15196
  this.rtcFactoryProvider = rtcFactoryProvider;
15103
15197
  this.hostCapabilities = hostCapabilities;
15198
+ this.harnessVersion = harnessVersion;
15104
15199
  }
15105
15200
  socket;
15106
15201
  running;
@@ -15224,6 +15319,7 @@ var HostServerConnection = class {
15224
15319
  accessToken: credentials.accessToken,
15225
15320
  protocols: [PROTOCOL_VERSION],
15226
15321
  clientVersion: PLUGIN_VERSION,
15322
+ ...this.harnessVersion === void 0 ? {} : { harnessVersion: this.harnessVersion },
15227
15323
  capabilities: this.rtcFactoryProvider === void 0 || this.config.forceRelay ? ["transport.relay", ...this.hostCapabilities()] : ["transport.p2p", "transport.turn", "transport.relay", ...this.hostCapabilities()]
15228
15324
  });
15229
15325
  };
@@ -15776,13 +15872,13 @@ function closeCode(code) {
15776
15872
  // src/remote-directory-browser.ts
15777
15873
  import { readdir, stat as stat3 } from "node:fs/promises";
15778
15874
  import { homedir as homedir2, platform as platform2 } from "node:os";
15779
- import { basename, dirname as dirname3, isAbsolute, parse, resolve } from "node:path";
15875
+ import { basename, dirname as dirname4, isAbsolute as isAbsolute2, parse, resolve } from "node:path";
15780
15876
  var MAX_ENTRIES = 500;
15781
15877
  async function listRemoteDirectory(path, signal) {
15782
15878
  signal?.throwIfAborted();
15783
15879
  const home = resolve(homedir2());
15784
15880
  const target = path === void 0 || path.trim() === "" ? home : resolve(path);
15785
- if (!isAbsolute(target)) throw new Error("The remote directory path must be absolute.");
15881
+ if (!isAbsolute2(target)) throw new Error("The remote directory path must be absolute.");
15786
15882
  const rows = await readdir(target, { withFileTypes: true });
15787
15883
  const directories = [];
15788
15884
  for (const row of rows) {
@@ -15809,7 +15905,7 @@ function crumbs(path) {
15809
15905
  let current = path;
15810
15906
  while (current !== root) {
15811
15907
  segments.unshift(basename(current));
15812
- current = dirname3(current);
15908
+ current = dirname4(current);
15813
15909
  }
15814
15910
  for (const segment of segments) {
15815
15911
  current = resolve(current, segment);
@@ -16173,11 +16269,12 @@ var HostPluginRuntime = class {
16173
16269
  constructor(config, identities, apiProxy, logger, typertGateway, fileViewerHost) {
16174
16270
  this.config = config;
16175
16271
  this.identities = identities;
16272
+ this.apiProxy = apiProxy;
16176
16273
  this.logger = logger;
16177
16274
  this.fileViewerHost = fileViewerHost;
16178
16275
  this.connections = new ConnectionController(this.identities, (_context, send) => {
16179
16276
  const harnessApi = new HarnessApiBridge(
16180
- apiProxy,
16277
+ this.apiProxy,
16181
16278
  (event, data) => send(createEvent(event, data)),
16182
16279
  void 0,
16183
16280
  this.logger,
@@ -16197,6 +16294,7 @@ var HostPluginRuntime = class {
16197
16294
  identity;
16198
16295
  serverApi;
16199
16296
  serverConnection;
16297
+ harnessVersion;
16200
16298
  closed = false;
16201
16299
  async start() {
16202
16300
  if (this.closed) throw new Error("remote runtime is closed");
@@ -16207,6 +16305,7 @@ var HostPluginRuntime = class {
16207
16305
  server: this.config.serverUrl ?? "not configured"
16208
16306
  });
16209
16307
  if (this.serverApi !== void 0) {
16308
+ this.harnessVersion = await this.readHarnessVersion();
16210
16309
  this.serverApi.bindIdentity(this.identity);
16211
16310
  this.serverConnection = this.createServerConnection(this.identity);
16212
16311
  this.serverConnection.start();
@@ -16325,9 +16424,28 @@ var HostPluginRuntime = class {
16325
16424
  this.logger,
16326
16425
  void 0,
16327
16426
  this.config.forceRelay ? void 0 : loadWeriftFactory,
16328
- () => this.fileViewerHost?.() === void 0 ? ["harness.api.v1"] : ["harness.api.v1", "fileviewer.read.v1"]
16427
+ () => this.fileViewerHost?.() === void 0 ? ["harness.api.v1"] : ["harness.api.v1", "fileviewer.read.v1"],
16428
+ this.harnessVersion
16329
16429
  );
16330
16430
  }
16431
+ async readHarnessVersion() {
16432
+ let reportedVersion;
16433
+ let errorCode2;
16434
+ try {
16435
+ const response = await this.apiProxy.host.describe({ rpcId: RpcId(randomUUID()), payload: {} });
16436
+ if (!response.result.ok) {
16437
+ errorCode2 = response.result.error.code;
16438
+ } else {
16439
+ reportedVersion = normalizeHarnessVersion(response.result.value.version);
16440
+ }
16441
+ } catch {
16442
+ }
16443
+ const distributionVersion = reportedVersion === void 0 || reportedVersion === "0.0.1" ? await readHarnessDistributionVersion() : void 0;
16444
+ const version = selectHarnessVersion(reportedVersion, distributionVersion);
16445
+ if (version !== void 0) return version;
16446
+ this.logger.warn("Harness version is unavailable", errorCode2 === void 0 ? void 0 : { code: errorCode2 });
16447
+ return void 0;
16448
+ }
16331
16449
  };
16332
16450
  function shortId5(value) {
16333
16451
  return value.length <= 12 ? value : `${value.slice(0, 8)}\u2026${value.slice(-4)}`;