@byok-sdk/client 0.5.0 → 0.6.0
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/bin/byok-agent.js +153 -10
- package/dist/bin/byok-agent.js.map +1 -1
- package/dist/bin/byok-approval-mcp.js.map +1 -1
- package/dist/bin/config.d.ts +3 -1
- package/dist/bin/format.d.ts +2 -1
- package/dist/bin/official-release.d.ts +1 -0
- package/dist/bin/version.d.ts +2 -0
- package/dist/daemon/connection-manager.d.ts +2 -0
- package/dist/daemon/control-protocol.d.ts +3 -0
- package/dist/daemon/create-daemon.d.ts +5 -0
- package/dist/daemon/presence-publisher.d.ts +7 -1
- package/dist/daemon/task-runner.d.ts +20 -0
- package/dist/daemon/ws-transport.d.ts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +127 -10
- package/dist/index.js.map +1 -1
- package/dist/release-identity.d.ts +15 -0
- package/package.json +4 -4
package/dist/bin/byok-agent.js
CHANGED
|
@@ -5,7 +5,7 @@ import { readFileSync, promises, linkSync, fstatSync, lstatSync, unlinkSync, con
|
|
|
5
5
|
import path20, { isAbsolute, join } from 'path';
|
|
6
6
|
import os from 'os';
|
|
7
7
|
import { DEVICE_ASSERTION_AUDIENCE_MAX_BYTES, DEVICE_ASSERTION_DEFAULT_TTL_MS, DEVICE_ASSERTION_MAX_TTL_MS, nonceSigningBytes, CapabilityDeclarationSchema, hasCapability, DeviceAssertionClaimsSchema, deviceAssertionSigningInput, DEVICE_ASSERTION_SCHEMA_ID } from '@byok-sdk/core';
|
|
8
|
-
import { TASK_STATES, CONFIGURED_TOOLSETS_MAX_ITEMS, ToolsetIdSchema, BYOK_PAIR_PATH, BYOK_CHALLENGE_PATH, BYOK_TOKEN_PATH, partitionAgentEvents, TASK_TRANSITIONS, encodeEnvelope, createEnvelope, byokBlobUrlPath, BYOK_BLOBS_PATH, byokBlobFinalizePath, checkResultDocument, MAX_MESSAGES_PER_BATCH, BYOK_CAPABILITIES_PATH, BYOK_PRESENCE_PATH, RuntimeIdSchema,
|
|
8
|
+
import { TASK_STATES, CONFIGURED_TOOLSETS_MAX_ITEMS, ToolsetIdSchema, BYOK_PAIR_PATH, BYOK_CHALLENGE_PATH, BYOK_TOKEN_PATH, partitionAgentEvents, TASK_TRANSITIONS, encodeEnvelope, PROTOCOL_VERSION, createEnvelope, byokBlobUrlPath, BYOK_BLOBS_PATH, byokBlobFinalizePath, checkResultDocument, MAX_MESSAGES_PER_BATCH, BYOK_CAPABILITIES_PATH, BYOK_PRESENCE_PATH, RuntimeIdSchema, TERMINAL_INFERENCE_USAGE_MAX_DURATION_MS, TERMINAL_INFERENCE_USAGE_MAX_TOKENS, RESULT_DOCUMENT_MAX_BYTES, decodeEnvelope, BYOK_MESSAGES_PATH, MessagesSendResponseSchema, BYOK_EVENTS_PATH, parseMessage, UnknownMessageTypeError, BYOK_WS_PATH } from '@byok-sdk/protocol';
|
|
9
9
|
import { promisify } from 'util';
|
|
10
10
|
import { fileURLToPath } from 'url';
|
|
11
11
|
import 'readline';
|
|
@@ -77,6 +77,28 @@ var SteerUnsupportedError = class extends Error {
|
|
|
77
77
|
}
|
|
78
78
|
};
|
|
79
79
|
|
|
80
|
+
// src/release-identity.ts
|
|
81
|
+
var LOCAL_AGENT_RELEASE_VERSION_MAX_LENGTH = 128;
|
|
82
|
+
var LOCAL_AGENT_RELEASE_BUILD_ID_MAX_LENGTH = 128;
|
|
83
|
+
var STRICT_SEMVER_PATTERN = new RegExp(
|
|
84
|
+
"^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-(?:0|[1-9]\\d*|\\d*[A-Za-z-][0-9A-Za-z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[A-Za-z-][0-9A-Za-z-]*))*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$"
|
|
85
|
+
);
|
|
86
|
+
var BUILD_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:-]*$/;
|
|
87
|
+
function resolveLocalAgentReleaseIdentity(input) {
|
|
88
|
+
if (input === void 0 || typeof input.version !== "string" || input.version.length > LOCAL_AGENT_RELEASE_VERSION_MAX_LENGTH || !STRICT_SEMVER_PATTERN.test(input.version)) {
|
|
89
|
+
throw new Error("DaemonConfig.localAgentRelease.version must be canonical strict SemVer");
|
|
90
|
+
}
|
|
91
|
+
if (input.buildId !== void 0 && (typeof input.buildId !== "string" || input.buildId.length > LOCAL_AGENT_RELEASE_BUILD_ID_MAX_LENGTH || !BUILD_ID_PATTERN.test(input.buildId))) {
|
|
92
|
+
throw new Error(
|
|
93
|
+
`DaemonConfig.localAgentRelease.buildId must be 1-${LOCAL_AGENT_RELEASE_BUILD_ID_MAX_LENGTH} safe opaque characters`
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
return Object.freeze({
|
|
97
|
+
version: input.version,
|
|
98
|
+
...input.buildId === void 0 ? {} : { buildId: input.buildId }
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
80
102
|
// src/runtime-failure.ts
|
|
81
103
|
var RUNTIME_EXECUTION_FAILURE_BRAND = /* @__PURE__ */ Symbol.for("@byok-sdk/client/RuntimeExecutionFailure/v1");
|
|
82
104
|
var RUNTIME_DISPOSAL_FAILURE_BRAND = /* @__PURE__ */ Symbol.for("@byok-sdk/client/RuntimeDisposalFailure/v1");
|
|
@@ -4419,7 +4441,20 @@ var PresencePublisher = class {
|
|
|
4419
4441
|
headers: { "content-type": "application/json" },
|
|
4420
4442
|
body: JSON.stringify({
|
|
4421
4443
|
level: "online",
|
|
4422
|
-
...this.opts.configuredToolsets === void 0 ? {} : { configuredToolsets: this.opts.configuredToolsets }
|
|
4444
|
+
...this.opts.configuredToolsets === void 0 ? {} : { configuredToolsets: this.opts.configuredToolsets },
|
|
4445
|
+
...this.opts.clientVersion === void 0 ? {} : { clientVersion: this.opts.clientVersion },
|
|
4446
|
+
...this.opts.protocolVersions === void 0 ? {} : { protocolVersions: [...this.opts.protocolVersions] },
|
|
4447
|
+
// Presence is a lightweight readiness fact, not a second
|
|
4448
|
+
// capability-negotiation channel. Keep its projection identical
|
|
4449
|
+
// to the persisted presence contract: the conn.hello snapshot's
|
|
4450
|
+
// runtime identity/version/auth facts, with no capabilities blob.
|
|
4451
|
+
...this.opts.runtimes === void 0 ? {} : {
|
|
4452
|
+
runtimes: this.opts.runtimes.map(({ id, version, authPresent }) => ({
|
|
4453
|
+
id,
|
|
4454
|
+
...version === void 0 ? {} : { version },
|
|
4455
|
+
...authPresent === void 0 ? {} : { authPresent }
|
|
4456
|
+
}))
|
|
4457
|
+
}
|
|
4423
4458
|
})
|
|
4424
4459
|
},
|
|
4425
4460
|
this.opts.auth
|
|
@@ -5145,6 +5180,7 @@ var WsTransport = class {
|
|
|
5145
5180
|
capabilities: this.opts.capabilities,
|
|
5146
5181
|
deviceId: this.opts.deviceId,
|
|
5147
5182
|
productId: this.opts.productId,
|
|
5183
|
+
clientVersion: this.opts.clientVersion,
|
|
5148
5184
|
runtimes: this.opts.runtimes,
|
|
5149
5185
|
configuredToolsets: this.opts.configuredToolsets === void 0 ? void 0 : [...this.opts.configuredToolsets],
|
|
5150
5186
|
cursor: this.opts.getCursor?.()
|
|
@@ -5235,6 +5271,7 @@ var ConnectionManager = class {
|
|
|
5235
5271
|
deviceId: opts.deviceId,
|
|
5236
5272
|
productId: opts.productId,
|
|
5237
5273
|
capabilities: opts.capabilities,
|
|
5274
|
+
clientVersion: opts.clientVersion,
|
|
5238
5275
|
runtimes: opts.runtimes,
|
|
5239
5276
|
configuredToolsets: opts.configuredToolsets,
|
|
5240
5277
|
getCursor: () => this.cursor,
|
|
@@ -8508,6 +8545,9 @@ var DEFAULT_MAX_TASK_OUTPUT_BYTES = 64 * 1024 * 1024;
|
|
|
8508
8545
|
function isKnownRuntimeId(id) {
|
|
8509
8546
|
return RuntimeIdSchema.safeParse(id).success;
|
|
8510
8547
|
}
|
|
8548
|
+
function terminalUsageNumber(value, maximum) {
|
|
8549
|
+
return value !== void 0 && Number.isSafeInteger(value) && value >= 0 && value <= maximum ? value : void 0;
|
|
8550
|
+
}
|
|
8511
8551
|
var DEFAULT_RUNTIME_PREFERENCE = ["claude", "codex", "pi"];
|
|
8512
8552
|
function orderByPreference(candidates, preference) {
|
|
8513
8553
|
const rank = new Map(preference.map((id, index) => [id, index]));
|
|
@@ -8807,7 +8847,13 @@ var TaskRunner = class {
|
|
|
8807
8847
|
const timeoutMs = this.deps.shutdownInterruptTimeoutMs ?? DEFAULT_SHUTDOWN_INTERRUPT_TIMEOUT_MS;
|
|
8808
8848
|
await raceSettleFirst(() => active.session.interrupt(), timeoutMs);
|
|
8809
8849
|
if (this.tasks.get(active.taskId) !== active) return true;
|
|
8810
|
-
this.deps.send(
|
|
8850
|
+
this.deps.send(
|
|
8851
|
+
createEnvelope(
|
|
8852
|
+
"task.fail",
|
|
8853
|
+
{ reason, retryable, ...this.terminalInferenceUsagePayload(active) },
|
|
8854
|
+
{ taskId: active.taskId }
|
|
8855
|
+
)
|
|
8856
|
+
);
|
|
8811
8857
|
return this.finish(active.taskId);
|
|
8812
8858
|
}
|
|
8813
8859
|
/** Graceful-shutdown caller of {@link teardownActiveTask} — see `shutdownActiveTasks`'s own doc comment. `retryable: true`: nothing about the task/policy itself was ever at fault, only this device's own availability right now. */
|
|
@@ -9185,7 +9231,8 @@ var TaskRunner = class {
|
|
|
9185
9231
|
this.deps.batcherOptions
|
|
9186
9232
|
),
|
|
9187
9233
|
approvalQueue: [],
|
|
9188
|
-
outputBytesSoFar: 0
|
|
9234
|
+
outputBytesSoFar: 0,
|
|
9235
|
+
startedAtMs: Date.now()
|
|
9189
9236
|
};
|
|
9190
9237
|
if (this.pendingCancelled.has(taskId)) {
|
|
9191
9238
|
const reason = this.pendingCancelled.get(taskId);
|
|
@@ -9197,7 +9244,13 @@ var TaskRunner = class {
|
|
|
9197
9244
|
} catch {
|
|
9198
9245
|
}
|
|
9199
9246
|
await this.updateGitPhaseBestEffort(gitWorkspaceId, "cancelled");
|
|
9200
|
-
this.deps.send(
|
|
9247
|
+
this.deps.send(
|
|
9248
|
+
createEnvelope(
|
|
9249
|
+
"task.cancelled",
|
|
9250
|
+
{ reason, ...this.terminalInferenceUsagePayload(active) },
|
|
9251
|
+
{ taskId }
|
|
9252
|
+
)
|
|
9253
|
+
);
|
|
9201
9254
|
await this.finish(taskId);
|
|
9202
9255
|
return;
|
|
9203
9256
|
}
|
|
@@ -9270,6 +9323,9 @@ var TaskRunner = class {
|
|
|
9270
9323
|
);
|
|
9271
9324
|
return;
|
|
9272
9325
|
}
|
|
9326
|
+
if (event.type === "usage") {
|
|
9327
|
+
active.lastUsage = event;
|
|
9328
|
+
}
|
|
9273
9329
|
if (event.type === "needs_approval") {
|
|
9274
9330
|
active.batcher.flush();
|
|
9275
9331
|
const { taskId } = active;
|
|
@@ -9322,7 +9378,8 @@ var TaskRunner = class {
|
|
|
9322
9378
|
// (where the codec actually serializes it), so a contextual
|
|
9323
9379
|
// `toJSON(key)` or an unstable getter cannot make the wire
|
|
9324
9380
|
// bytes differ from what the cap gate approved.
|
|
9325
|
-
...outcome.document !== void 0 ? { document: outcome.document } : {}
|
|
9381
|
+
...outcome.document !== void 0 ? { document: outcome.document } : {},
|
|
9382
|
+
...this.terminalInferenceUsagePayload(active)
|
|
9326
9383
|
},
|
|
9327
9384
|
{ taskId: active.taskId, sessionRef: active.session.sessionRef }
|
|
9328
9385
|
)
|
|
@@ -9439,7 +9496,13 @@ var TaskRunner = class {
|
|
|
9439
9496
|
} catch {
|
|
9440
9497
|
}
|
|
9441
9498
|
await this.observeGit(active, "salvage");
|
|
9442
|
-
this.deps.send(
|
|
9499
|
+
this.deps.send(
|
|
9500
|
+
createEnvelope(
|
|
9501
|
+
"task.cancelled",
|
|
9502
|
+
{ reason, ...this.terminalInferenceUsagePayload(active) },
|
|
9503
|
+
{ taskId }
|
|
9504
|
+
)
|
|
9505
|
+
);
|
|
9443
9506
|
await this.finish(taskId);
|
|
9444
9507
|
}
|
|
9445
9508
|
/** M3-B: bounded insert for `pendingCancelled` — see its class-level doc comment and `MAX_TRACKED_TASK_IDS`. Evicts the oldest SAFE-TO-EVICT entry once over cap — see `evictPendingCancelled` (finding #5: not simply "the oldest entry", which could be an in-flight offer's own cancel marker). */
|
|
@@ -9877,7 +9940,13 @@ var TaskRunner = class {
|
|
|
9877
9940
|
} catch {
|
|
9878
9941
|
}
|
|
9879
9942
|
await this.observeGit(active, "salvage");
|
|
9880
|
-
this.deps.send(
|
|
9943
|
+
this.deps.send(
|
|
9944
|
+
createEnvelope(
|
|
9945
|
+
"task.fail",
|
|
9946
|
+
{ reason: reason ?? "rejected", retryable: false, ...this.terminalInferenceUsagePayload(active) },
|
|
9947
|
+
{ taskId }
|
|
9948
|
+
)
|
|
9949
|
+
);
|
|
9881
9950
|
await this.finish(taskId);
|
|
9882
9951
|
}
|
|
9883
9952
|
/** Pre-claim, fail-closed rejection (protocol §3.2) — never claims first. */
|
|
@@ -9895,9 +9964,44 @@ var TaskRunner = class {
|
|
|
9895
9964
|
return;
|
|
9896
9965
|
}
|
|
9897
9966
|
if (active) await this.observeGit(active, "salvage");
|
|
9898
|
-
this.deps.send(
|
|
9967
|
+
this.deps.send(
|
|
9968
|
+
createEnvelope(
|
|
9969
|
+
"task.fail",
|
|
9970
|
+
active === void 0 ? { reason, retryable } : { reason, retryable, ...this.terminalInferenceUsagePayload(active) },
|
|
9971
|
+
{ taskId }
|
|
9972
|
+
)
|
|
9973
|
+
);
|
|
9899
9974
|
await this.finish(taskId);
|
|
9900
9975
|
}
|
|
9976
|
+
/**
|
|
9977
|
+
* Build the optional terminal observation from facts this running daemon
|
|
9978
|
+
* actually has. No offered `dispatchSelection` is echoed here: it is a
|
|
9979
|
+
* requested execution target, not an adapter-reported provider/model fact.
|
|
9980
|
+
* The bundled adapter event contracts currently expose token observations
|
|
9981
|
+
* (Codex and Claude) but no provider/model observation, so those keys stay
|
|
9982
|
+
* absent. Pi exposes no native usage observation, so its terminal payload
|
|
9983
|
+
* omits this optional block rather than fabricating a usage observation from
|
|
9984
|
+
* independently known runtime, elapsed duration, or Local Agent version.
|
|
9985
|
+
*/
|
|
9986
|
+
terminalInferenceUsagePayload(active) {
|
|
9987
|
+
const release = this.deps.localAgentRelease;
|
|
9988
|
+
const runtimeId = active.adapter.descriptor.id;
|
|
9989
|
+
if (release === void 0 || active.lastUsage === void 0 || !isKnownRuntimeId(runtimeId)) return {};
|
|
9990
|
+
const nowMs = Date.now();
|
|
9991
|
+
const durationMs = terminalUsageNumber(nowMs - active.startedAtMs, TERMINAL_INFERENCE_USAGE_MAX_DURATION_MS);
|
|
9992
|
+
const promptTokens = terminalUsageNumber(active.lastUsage?.inputTokens, TERMINAL_INFERENCE_USAGE_MAX_TOKENS);
|
|
9993
|
+
const completionTokens = terminalUsageNumber(active.lastUsage?.outputTokens, TERMINAL_INFERENCE_USAGE_MAX_TOKENS);
|
|
9994
|
+
return {
|
|
9995
|
+
usage: {
|
|
9996
|
+
runtime: runtimeId,
|
|
9997
|
+
clientVersion: release.version,
|
|
9998
|
+
reportedAt: new Date(nowMs).toISOString(),
|
|
9999
|
+
...promptTokens === void 0 ? {} : { promptTokens },
|
|
10000
|
+
...completionTokens === void 0 ? {} : { completionTokens },
|
|
10001
|
+
...durationMs === void 0 ? {} : { durationMs }
|
|
10002
|
+
}
|
|
10003
|
+
};
|
|
10004
|
+
}
|
|
9901
10005
|
/**
|
|
9902
10006
|
* additive-minor (`task.complete.document`): the whole daemon-side gate
|
|
9903
10007
|
* between a configured {@link ResultDocumentExtractor} and the wire —
|
|
@@ -10426,6 +10530,7 @@ function createDaemonWithAdapters(config, adapters, overrides = {}) {
|
|
|
10426
10530
|
return buildDaemonWithAdapters(config, adapters, overrides);
|
|
10427
10531
|
}
|
|
10428
10532
|
function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProbe) {
|
|
10533
|
+
const localAgentRelease = resolveLocalAgentReleaseIdentity(config.localAgentRelease);
|
|
10429
10534
|
const mcpToolsets = resolveMcpToolsets(config.mcpToolsets);
|
|
10430
10535
|
const configuredToolsets = Object.freeze(
|
|
10431
10536
|
[...mcpToolsets?.keys() ?? []].sort()
|
|
@@ -10539,6 +10644,7 @@ function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProb
|
|
|
10539
10644
|
let controlServerHandle;
|
|
10540
10645
|
let daemonOwnerLease;
|
|
10541
10646
|
let presencePublisher;
|
|
10647
|
+
let detectedRuntimeFacts = [];
|
|
10542
10648
|
let presenceDiscovery;
|
|
10543
10649
|
let presenceDiscoveryInFlight = false;
|
|
10544
10650
|
let shutdownPromise;
|
|
@@ -10672,6 +10778,7 @@ function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProb
|
|
|
10672
10778
|
Promise.resolve(new BlobClient(config.serverUrl, auth))
|
|
10673
10779
|
]);
|
|
10674
10780
|
observer.noteRuntimesDetected(runtimes);
|
|
10781
|
+
detectedRuntimeFacts = runtimes;
|
|
10675
10782
|
const capabilities = computeCapabilities(adapters);
|
|
10676
10783
|
const journalIdentity = config.hostedJournal ? { tenantId: config.hostedJournal.tenantId, productId: config.productId, deviceId: record.deviceId } : void 0;
|
|
10677
10784
|
const sendEnvelope = activeJournal && journalIdentity ? (envelope) => {
|
|
@@ -10749,6 +10856,10 @@ function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProb
|
|
|
10749
10856
|
approvalRegistry,
|
|
10750
10857
|
storeDir,
|
|
10751
10858
|
productId: config.productId,
|
|
10859
|
+
// U2 terminal inference usage consumes the one U4a-resolved,
|
|
10860
|
+
// process-immutable identity captured above. This is composition-only:
|
|
10861
|
+
// TaskRunner receives no config, manifest, or second identity resolver.
|
|
10862
|
+
localAgentRelease,
|
|
10752
10863
|
approvalTimeoutMs: overrides.approvalTimeoutMs,
|
|
10753
10864
|
// Finding F5(a): see TaskRunnerDeps.shutdownInterruptTimeoutMs's own doc comment.
|
|
10754
10865
|
shutdownInterruptTimeoutMs: overrides.shutdown?.taskInterruptTimeoutMs,
|
|
@@ -10794,6 +10905,7 @@ function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProb
|
|
|
10794
10905
|
deviceId: record.deviceId,
|
|
10795
10906
|
productId: config.productId,
|
|
10796
10907
|
capabilities,
|
|
10908
|
+
clientVersion: localAgentRelease.version,
|
|
10797
10909
|
runtimes,
|
|
10798
10910
|
configuredToolsets,
|
|
10799
10911
|
auth,
|
|
@@ -10883,6 +10995,9 @@ function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProb
|
|
|
10883
10995
|
serverUrl: config.serverUrl,
|
|
10884
10996
|
auth,
|
|
10885
10997
|
configuredToolsets,
|
|
10998
|
+
clientVersion: localAgentRelease.version,
|
|
10999
|
+
protocolVersions: [PROTOCOL_VERSION],
|
|
11000
|
+
runtimes: detectedRuntimeFacts,
|
|
10886
11001
|
...presenceCadence,
|
|
10887
11002
|
onDegraded: (reason) => console.warn(`[byok/client] ${reason}`)
|
|
10888
11003
|
});
|
|
@@ -11064,6 +11179,7 @@ function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProb
|
|
|
11064
11179
|
const activeTasks = observer.tasks().filter((task) => TASK_TRANSITIONS[task.state].length > 0).map((task) => ({ taskId: task.taskId, state: task.state }));
|
|
11065
11180
|
const pendingApprovals = approvalRegistry.list();
|
|
11066
11181
|
return {
|
|
11182
|
+
localAgentRelease,
|
|
11067
11183
|
pid: process.pid,
|
|
11068
11184
|
uptimeMs: startedAt !== void 0 ? Date.now() - startedAt : 0,
|
|
11069
11185
|
paired: auth.deviceId !== void 0,
|
|
@@ -11262,6 +11378,7 @@ function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProb
|
|
|
11262
11378
|
}
|
|
11263
11379
|
function status() {
|
|
11264
11380
|
return {
|
|
11381
|
+
localAgentRelease,
|
|
11265
11382
|
paired: auth.deviceId !== void 0,
|
|
11266
11383
|
connected: connectionState === "open",
|
|
11267
11384
|
degraded: connection?.isTransportDegraded() ?? false,
|
|
@@ -11891,6 +12008,13 @@ function createServiceLifecycle(def, opts = {}) {
|
|
|
11891
12008
|
throw new UnsupportedServicePlatformError(platform);
|
|
11892
12009
|
}
|
|
11893
12010
|
}
|
|
12011
|
+
|
|
12012
|
+
// src/bin/official-release.ts
|
|
12013
|
+
var OFFICIAL_LOCAL_AGENT_RELEASE = resolveLocalAgentReleaseIdentity({
|
|
12014
|
+
version: "0.6.0"
|
|
12015
|
+
});
|
|
12016
|
+
|
|
12017
|
+
// src/bin/config.ts
|
|
11894
12018
|
var REQUIRED_FIELDS = ["productName", "productId", "serverUrl", "workspaceRoot"];
|
|
11895
12019
|
var ConfigError = class extends Error {
|
|
11896
12020
|
constructor(message) {
|
|
@@ -11913,6 +12037,9 @@ function loadConfig(configPath, overrides = {}) {
|
|
|
11913
12037
|
throw new ConfigError(`config at "${configPath}" is not valid JSON: ${err instanceof Error ? err.message : String(err)}`);
|
|
11914
12038
|
}
|
|
11915
12039
|
}
|
|
12040
|
+
if (Object.prototype.hasOwnProperty.call(base, "localAgentRelease") || Object.prototype.hasOwnProperty.call(overrides, "localAgentRelease")) {
|
|
12041
|
+
throw new ConfigError('config field "localAgentRelease" is distribution-owned and must not be supplied');
|
|
12042
|
+
}
|
|
11916
12043
|
const merged = { ...base, ...overrides };
|
|
11917
12044
|
if (merged.gitWorkspace !== void 0) {
|
|
11918
12045
|
try {
|
|
@@ -11926,7 +12053,7 @@ function loadConfig(configPath, overrides = {}) {
|
|
|
11926
12053
|
throw new ConfigError(`config is missing required field "${field}"`);
|
|
11927
12054
|
}
|
|
11928
12055
|
}
|
|
11929
|
-
return merged;
|
|
12056
|
+
return { ...merged, localAgentRelease: OFFICIAL_LOCAL_AGENT_RELEASE };
|
|
11930
12057
|
}
|
|
11931
12058
|
function resolveStoreDir(config) {
|
|
11932
12059
|
return DeviceStore.resolveDir(config.productId, config.storeDir);
|
|
@@ -12100,6 +12227,9 @@ function formatStatusLines(view) {
|
|
|
12100
12227
|
const lines = [];
|
|
12101
12228
|
const label = view.branding?.displayName ?? view.productName;
|
|
12102
12229
|
lines.push(`product: ${label} (${view.productId})`);
|
|
12230
|
+
lines.push(
|
|
12231
|
+
`local-agent-release: ${view.localAgentRelease.version}${view.localAgentRelease.buildId ? ` buildId=${view.localAgentRelease.buildId}` : ""}`
|
|
12232
|
+
);
|
|
12103
12233
|
if (view.branding?.supportUrl) lines.push(`support: ${view.branding.supportUrl}`);
|
|
12104
12234
|
lines.push(`paired: ${view.paired ? "yes" : "no"}${view.deviceId ? ` deviceId=${view.deviceId}` : ""}`);
|
|
12105
12235
|
lines.push(
|
|
@@ -12115,8 +12245,10 @@ function formatStatusLines(view) {
|
|
|
12115
12245
|
return lines;
|
|
12116
12246
|
}
|
|
12117
12247
|
function formatLiveStatusLines(live) {
|
|
12248
|
+
const liveRelease = live.localAgentRelease;
|
|
12118
12249
|
const lines = [
|
|
12119
12250
|
`live: pid=${live.pid} uptimeMs=${live.uptimeMs} transport=${live.transport}`,
|
|
12251
|
+
liveRelease ? `live-local-agent-release: ${liveRelease.version}${liveRelease.buildId ? ` buildId=${liveRelease.buildId}` : ""}` : "live-local-agent-release: unknown",
|
|
12120
12252
|
`live-paired: ${live.paired ? "yes" : "no"}${live.deviceId ? ` deviceId=${live.deviceId}` : ""}`,
|
|
12121
12253
|
`live-runtimes: ${live.runtimeIds.length ? live.runtimeIds.join(",") : "(none)"}`
|
|
12122
12254
|
];
|
|
@@ -13805,6 +13937,7 @@ async function runStatusCommand(config, deps = {}) {
|
|
|
13805
13937
|
]);
|
|
13806
13938
|
const tasks = deriveTasksFromEvents(events);
|
|
13807
13939
|
const view = {
|
|
13940
|
+
localAgentRelease: config.localAgentRelease,
|
|
13808
13941
|
productName: config.productName,
|
|
13809
13942
|
productId: config.productId,
|
|
13810
13943
|
branding: config.branding,
|
|
@@ -14233,11 +14366,17 @@ async function runWorkspacesCommand(config, deps = {}) {
|
|
|
14233
14366
|
for (const record of records) log(formatWorkspaceLine(record, deps.showPaths === true));
|
|
14234
14367
|
}
|
|
14235
14368
|
|
|
14369
|
+
// src/bin/version.ts
|
|
14370
|
+
function runVersionCommand(log = console.log) {
|
|
14371
|
+
log(OFFICIAL_LOCAL_AGENT_RELEASE.version);
|
|
14372
|
+
}
|
|
14373
|
+
|
|
14236
14374
|
// src/bin/byok-agent.ts
|
|
14237
14375
|
function usage() {
|
|
14238
14376
|
console.error(
|
|
14239
14377
|
[
|
|
14240
14378
|
"Usage:",
|
|
14379
|
+
" byok-agent --version",
|
|
14241
14380
|
" byok-agent pair <code> --server <url> [--config <path>]",
|
|
14242
14381
|
" byok-agent start [--config <path>] (or BYOK_CONFIG env var)",
|
|
14243
14382
|
" byok-agent status [--config <path>]",
|
|
@@ -14273,6 +14412,10 @@ function abortOnSignal() {
|
|
|
14273
14412
|
}
|
|
14274
14413
|
async function main() {
|
|
14275
14414
|
const [, , command, ...rest] = process.argv;
|
|
14415
|
+
if (command === "--version") {
|
|
14416
|
+
runVersionCommand();
|
|
14417
|
+
return;
|
|
14418
|
+
}
|
|
14276
14419
|
if (command === "pair") {
|
|
14277
14420
|
const [code] = positionalArgs(rest, ["--server", "--config"]);
|
|
14278
14421
|
const server = argValue(rest, "--server");
|