@agentknight/client 0.9.40 → 0.9.42
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/cli.js +97 -21
- package/dist/upgrade-worker.js +15 -3
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -680,13 +680,25 @@ var PairingCreateResultSchema = z5.discriminatedUnion("ok", [
|
|
|
680
680
|
z5.object({
|
|
681
681
|
ok: z5.literal(true),
|
|
682
682
|
code: z5.string().min(32).max(256),
|
|
683
|
-
expiresAt: z5.number().int().positive()
|
|
683
|
+
expiresAt: z5.number().int().positive(),
|
|
684
|
+
// Presence advertises the PC-only status endpoint; older Relays omit it.
|
|
685
|
+
statusId: z5.string().regex(/^[A-Za-z0-9_-]{43}$/u).optional()
|
|
684
686
|
}),
|
|
685
687
|
z5.object({
|
|
686
688
|
ok: z5.literal(false),
|
|
687
689
|
error: ProtocolFailureSchema
|
|
688
690
|
})
|
|
689
691
|
]);
|
|
692
|
+
var PairingStatusRequestSchema = z5.object({
|
|
693
|
+
userId: IdSchema,
|
|
694
|
+
machineId: IdSchema,
|
|
695
|
+
statusId: z5.string().regex(/^[A-Za-z0-9_-]{43}$/u)
|
|
696
|
+
});
|
|
697
|
+
var PairingStatusSchema = z5.enum(["pending", "paired", "unavailable"]);
|
|
698
|
+
var PairingStatusResultSchema = z5.discriminatedUnion("ok", [
|
|
699
|
+
z5.object({ ok: z5.literal(true), state: PairingStatusSchema }),
|
|
700
|
+
z5.object({ ok: z5.literal(false), error: ProtocolFailureSchema })
|
|
701
|
+
]);
|
|
690
702
|
var PairingExchangeRequestSchema = z5.object({
|
|
691
703
|
code: z5.string().min(32).max(256),
|
|
692
704
|
clientId: IdSchema
|
|
@@ -3146,19 +3158,12 @@ var EnvironmentSchema = z28.object({
|
|
|
3146
3158
|
SNAPSHOT_SUPPRESSION_ENABLED: EnabledBooleanStringSchema,
|
|
3147
3159
|
TIMELINE_COMPRESSION_ENABLED: BooleanStringSchema,
|
|
3148
3160
|
TIMELINE_INCREMENTAL_ENABLED: EnabledBooleanStringSchema,
|
|
3149
|
-
SESSION_IMAGES_ALLOW_UNENCRYPTED_STORAGE:
|
|
3150
|
-
SESSION_IMAGES_STORAGE_ACCOUNT: SessionImagesConfigSchema.shape.storageAccount.
|
|
3161
|
+
SESSION_IMAGES_ALLOW_UNENCRYPTED_STORAGE: EnabledBooleanStringSchema,
|
|
3162
|
+
SESSION_IMAGES_STORAGE_ACCOUNT: SessionImagesConfigSchema.shape.storageAccount.default("agentknightimagesbsp09"),
|
|
3151
3163
|
SESSION_IMAGES_STORAGE_CONTAINER: SessionImagesConfigSchema.shape.storageContainer.optional(),
|
|
3152
3164
|
SECURE_MESSAGE_PACKET_BUDGET: z28.coerce.number().int().min(2048).max(SECURE_MESSAGE_MAX_CIPHERTEXT_LENGTH).default(SECURE_MESSAGE_MAX_CIPHERTEXT_LENGTH)
|
|
3153
3165
|
}).superRefine((value, context) => {
|
|
3154
3166
|
if (value.SESSION_IMAGES_ALLOW_UNENCRYPTED_STORAGE) {
|
|
3155
|
-
if (value.SESSION_IMAGES_STORAGE_ACCOUNT === void 0) {
|
|
3156
|
-
context.addIssue({
|
|
3157
|
-
code: "custom",
|
|
3158
|
-
path: ["SESSION_IMAGES_STORAGE_ACCOUNT"],
|
|
3159
|
-
message: "Session images require an independently configured Azure storage account"
|
|
3160
|
-
});
|
|
3161
|
-
}
|
|
3162
3167
|
if (!SessionImageRelayUrlSchema.safeParse(value.RELAY_URL).success) {
|
|
3163
3168
|
context.addIssue({
|
|
3164
3169
|
code: "custom",
|
|
@@ -3166,12 +3171,6 @@ var EnvironmentSchema = z28.object({
|
|
|
3166
3171
|
message: "Session images require an HTTPS Relay origin without a path, credentials, query or fragment"
|
|
3167
3172
|
});
|
|
3168
3173
|
}
|
|
3169
|
-
} else if (value.SESSION_IMAGES_STORAGE_ACCOUNT !== void 0 || value.SESSION_IMAGES_STORAGE_CONTAINER !== void 0) {
|
|
3170
|
-
context.addIssue({
|
|
3171
|
-
code: "custom",
|
|
3172
|
-
path: ["SESSION_IMAGES_ALLOW_UNENCRYPTED_STORAGE"],
|
|
3173
|
-
message: "Session images require explicit consent to storage that is NOT end-to-end encrypted"
|
|
3174
|
-
});
|
|
3175
3174
|
}
|
|
3176
3175
|
if (value.RELAY_AUTH === "token" && value.RELAY_TOKEN === void 0) {
|
|
3177
3176
|
context.addIssue({ code: "custom", path: ["RELAY_TOKEN"], message: "Token authentication requires RELAY_TOKEN" });
|
|
@@ -3228,6 +3227,9 @@ function loadConfig(environment = process.env, options = {}) {
|
|
|
3228
3227
|
}
|
|
3229
3228
|
function loadStartupConfig(environment = process.env, options = {}) {
|
|
3230
3229
|
const normalizedEnvironment = normalizeClientEnvironment(environment);
|
|
3230
|
+
if (normalizedEnvironment.SESSION_IMAGES_ALLOW_UNENCRYPTED_STORAGE === void 0 && !SessionImageRelayUrlSchema.safeParse(normalizedEnvironment.RELAY_URL).success) {
|
|
3231
|
+
normalizedEnvironment.SESSION_IMAGES_ALLOW_UNENCRYPTED_STORAGE = "false";
|
|
3232
|
+
}
|
|
3231
3233
|
const initialSelection = options.agents === void 0 ? void 0 : AgentSelectionSchema2.parse({ agents: options.agents });
|
|
3232
3234
|
const startupEnvironment = normalizedEnvironment.RELAY_AUTH === "microsoft" ? { ...normalizedEnvironment, RELAY_TOKEN: void 0, USER_ID: void 0 } : normalizedEnvironment;
|
|
3233
3235
|
const parsed = EnvironmentSchema.parse(initialSelection === void 0 ? startupEnvironment : { ...startupEnvironment, AGENTKNIGHT_CODING_AGENT: "managed" });
|
|
@@ -3509,7 +3511,8 @@ function renderAgentSelectionPage(input) {
|
|
|
3509
3511
|
<h2 id="pairing-heading">\u624B\u673A\u914D\u5BF9</h2>
|
|
3510
3512
|
<div class="qr-area">
|
|
3511
3513
|
<svg id="qr-placeholder" class="qr-placeholder" viewBox="0 0 64 64" fill="none" stroke="currentColor" stroke-width="3" aria-hidden="true"${input.pairing ? " hidden" : ""}><rect x="8" y="8" width="18" height="18" rx="3"/><rect x="38" y="8" width="18" height="18" rx="3"/><rect x="8" y="38" width="18" height="18" rx="3"/><path d="M39 38h8v8h9M39 49v7h8M55 38v3"/></svg>
|
|
3512
|
-
<div id="pairing-qr" class="qr" role="img" aria-label="\u914D\u5BF9\u4E8C\u7EF4\u7801"${input.pairing ? ` data-expires-at="${input.pairing.expiresAt}"` : " hidden"}>${input.pairing?.svg ?? ""}</div>
|
|
3514
|
+
<div id="pairing-qr" class="qr" role="img" aria-label="\u914D\u5BF9\u4E8C\u7EF4\u7801"${input.pairing ? ` data-expires-at="${input.pairing.expiresAt}"${input.pairing.statusId ? ` data-status-id="${escapeHtml(input.pairing.statusId)}"` : ""}` : " hidden"}>${input.pairing?.svg ?? ""}</div>
|
|
3515
|
+
<div id="pair-success" role="status" hidden>\u2713 \u914D\u5BF9\u6210\u529F</div>
|
|
3513
3516
|
</div>
|
|
3514
3517
|
<form id="pairing-form" method="post" action="/pair">
|
|
3515
3518
|
<input type="hidden" name="token" value="${escapeHtml(input.token)}">
|
|
@@ -3655,17 +3658,64 @@ var localPageScript = `
|
|
|
3655
3658
|
const refresh = document.querySelector('#refresh-qr');
|
|
3656
3659
|
const hide = document.querySelector('#hide-qr');
|
|
3657
3660
|
const pairError = document.querySelector('#pair-error');
|
|
3661
|
+
const pairSuccess = document.querySelector('#pair-success');
|
|
3658
3662
|
let expiry;
|
|
3663
|
+
let statusTimer;
|
|
3664
|
+
let statusGeneration = 0;
|
|
3659
3665
|
let loading = false;
|
|
3666
|
+
const stopStatus = () => {
|
|
3667
|
+
clearTimeout(statusTimer);
|
|
3668
|
+
statusGeneration++;
|
|
3669
|
+
};
|
|
3660
3670
|
const conceal = () => {
|
|
3661
3671
|
clearTimeout(expiry);
|
|
3672
|
+
stopStatus();
|
|
3662
3673
|
qr.replaceChildren();
|
|
3663
3674
|
qr.hidden = true;
|
|
3664
|
-
|
|
3675
|
+
delete qr.dataset.statusId;
|
|
3676
|
+
delete qr.dataset.expiresAt;
|
|
3677
|
+
placeholder.removeAttribute('hidden');
|
|
3678
|
+
pairSuccess.hidden = true;
|
|
3665
3679
|
show.hidden = false;
|
|
3666
3680
|
refresh.hidden = true;
|
|
3667
3681
|
hide.hidden = true;
|
|
3668
3682
|
};
|
|
3683
|
+
const watchStatus = statusId => {
|
|
3684
|
+
stopStatus();
|
|
3685
|
+
if (typeof statusId !== 'string') return;
|
|
3686
|
+
const generation = statusGeneration;
|
|
3687
|
+
const poll = async () => {
|
|
3688
|
+
try {
|
|
3689
|
+
const body = new URLSearchParams(new FormData(pairing));
|
|
3690
|
+
body.set('statusId', statusId);
|
|
3691
|
+
const response = await fetch('/pair/status', { method: 'POST', headers: { Accept: 'application/json' }, body });
|
|
3692
|
+
const result = await response.json();
|
|
3693
|
+
if (generation !== statusGeneration) return;
|
|
3694
|
+
if (!response.ok || !['pending', 'paired', 'unavailable'].includes(result?.state)) throw new Error('Pairing status unavailable');
|
|
3695
|
+
if (result.state === 'paired') {
|
|
3696
|
+
conceal();
|
|
3697
|
+
placeholder.setAttribute('hidden', '');
|
|
3698
|
+
pairSuccess.hidden = false;
|
|
3699
|
+
pairError.hidden = true;
|
|
3700
|
+
return;
|
|
3701
|
+
}
|
|
3702
|
+
if (result.state === 'unavailable') {
|
|
3703
|
+
conceal();
|
|
3704
|
+
pairError.textContent = '\u4E8C\u7EF4\u7801\u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u663E\u793A\u3002';
|
|
3705
|
+
pairError.hidden = false;
|
|
3706
|
+
return;
|
|
3707
|
+
}
|
|
3708
|
+
pairError.hidden = true;
|
|
3709
|
+
} catch {
|
|
3710
|
+
// A lost status response is not pairing success. Retry until this QR expires.
|
|
3711
|
+
if (generation !== statusGeneration) return;
|
|
3712
|
+
pairError.textContent = '\u65E0\u6CD5\u786E\u8BA4\u914D\u5BF9\u72B6\u6001\uFF0C\u6B63\u5728\u91CD\u8BD5\u3002';
|
|
3713
|
+
pairError.hidden = false;
|
|
3714
|
+
}
|
|
3715
|
+
if (generation === statusGeneration) statusTimer = setTimeout(poll, 1000);
|
|
3716
|
+
};
|
|
3717
|
+
statusTimer = setTimeout(poll, 1000);
|
|
3718
|
+
};
|
|
3669
3719
|
const expire = expiresAt => {
|
|
3670
3720
|
clearTimeout(expiry);
|
|
3671
3721
|
expiry = setTimeout(() => {
|
|
@@ -3675,6 +3725,8 @@ var localPageScript = `
|
|
|
3675
3725
|
}, Math.max(0, expiresAt - Date.now()));
|
|
3676
3726
|
};
|
|
3677
3727
|
if (qr.dataset.expiresAt) expire(Number(qr.dataset.expiresAt));
|
|
3728
|
+
if (qr.dataset.statusId) watchStatus(qr.dataset.statusId);
|
|
3729
|
+
if (typeof window !== 'undefined') window.addEventListener('pagehide', conceal);
|
|
3678
3730
|
hide.addEventListener('click', conceal);
|
|
3679
3731
|
pairing.addEventListener('submit', async event => {
|
|
3680
3732
|
event.preventDefault();
|
|
@@ -3682,18 +3734,23 @@ var localPageScript = `
|
|
|
3682
3734
|
loading = true;
|
|
3683
3735
|
show.disabled = refresh.disabled = hide.disabled = true;
|
|
3684
3736
|
pairError.hidden = true;
|
|
3737
|
+
conceal();
|
|
3738
|
+
const generation = statusGeneration;
|
|
3685
3739
|
const endpoint = event.submitter?.getAttribute('formaction') || pairing.action;
|
|
3686
3740
|
try {
|
|
3687
3741
|
const response = await fetch(endpoint, { method: 'POST', headers: { Accept: 'application/json' }, body: new URLSearchParams(new FormData(pairing)) });
|
|
3688
3742
|
const result = await response.json().catch(() => null);
|
|
3743
|
+
if (generation !== statusGeneration) return;
|
|
3689
3744
|
if (!response.ok || typeof result?.svg !== 'string' || typeof result?.expiresAt !== 'number') throw new Error(result?.error || '\u65E0\u6CD5\u751F\u6210\u4E8C\u7EF4\u7801\uFF08HTTP ' + response.status + '\uFF09\uFF0C\u8BF7\u91CD\u8BD5\u3002');
|
|
3690
3745
|
qr.innerHTML = result.svg;
|
|
3691
3746
|
qr.hidden = false;
|
|
3692
|
-
placeholder.hidden
|
|
3747
|
+
placeholder.setAttribute('hidden', '');
|
|
3693
3748
|
show.hidden = true;
|
|
3694
3749
|
refresh.hidden = hide.hidden = false;
|
|
3695
3750
|
expire(result.expiresAt);
|
|
3751
|
+
watchStatus(result.statusId);
|
|
3696
3752
|
} catch (reason) {
|
|
3753
|
+
if (generation !== statusGeneration) return;
|
|
3697
3754
|
conceal();
|
|
3698
3755
|
pairError.textContent = reason instanceof Error ? reason.message : '\u65E0\u6CD5\u751F\u6210\u4E8C\u7EF4\u7801\uFF0C\u8BF7\u91CD\u8BD5\u3002';
|
|
3699
3756
|
pairError.hidden = false;
|
|
@@ -4065,7 +4122,7 @@ var PairingPageServer = class {
|
|
|
4065
4122
|
this.#redirectLogin(response, operation === "start" && next.state === "pending" ? next.verificationUri : "/");
|
|
4066
4123
|
return;
|
|
4067
4124
|
}
|
|
4068
|
-
if (request.method === "POST" && ["/pair", "/refresh", "/selection", "/group-chat-settings", "/peer-chat-settings"].includes(requestUrl.pathname)) {
|
|
4125
|
+
if (request.method === "POST" && ["/pair", "/pair/status", "/refresh", "/selection", "/group-chat-settings", "/peer-chat-settings"].includes(requestUrl.pathname)) {
|
|
4069
4126
|
if (await this.#readAuthorizedForm(request, response) === void 0) return;
|
|
4070
4127
|
this.#renderLogin(response, 409, this.#loginState(relayLogin));
|
|
4071
4128
|
return;
|
|
@@ -4143,6 +4200,20 @@ var PairingPageServer = class {
|
|
|
4143
4200
|
}
|
|
4144
4201
|
return;
|
|
4145
4202
|
}
|
|
4203
|
+
if (request.method === "POST" && requestUrl.pathname === "/pair/status") {
|
|
4204
|
+
const form = await this.#readAuthorizedForm(request, response);
|
|
4205
|
+
if (form === void 0) return;
|
|
4206
|
+
const statusId = PairingStatusRequestSchema.shape.statusId.safeParse(form.get("statusId"));
|
|
4207
|
+
if (!statusId.success || form.getAll("statusId").length !== 1) {
|
|
4208
|
+
this.#writeHeaders(response, 400, "application/json; charset=utf-8");
|
|
4209
|
+
response.end(JSON.stringify({ error: "Invalid pairing status identity." }));
|
|
4210
|
+
return;
|
|
4211
|
+
}
|
|
4212
|
+
const state = await this.#options.pairingProvider.getPairingStatus?.(statusId.data) ?? "unavailable";
|
|
4213
|
+
this.#writeHeaders(response, 200, "application/json; charset=utf-8");
|
|
4214
|
+
response.end(JSON.stringify({ state }));
|
|
4215
|
+
return;
|
|
4216
|
+
}
|
|
4146
4217
|
if (request.method === "POST" && (requestUrl.pathname === "/pair" || requestUrl.pathname === "/refresh")) {
|
|
4147
4218
|
if (await this.#readAuthorizedForm(request, response) === void 0) return;
|
|
4148
4219
|
const registration = this.#options.getRegistrationStatus();
|
|
@@ -4159,7 +4230,11 @@ var PairingPageServer = class {
|
|
|
4159
4230
|
width: 420,
|
|
4160
4231
|
color: { dark: "#101820", light: "#ffffff" }
|
|
4161
4232
|
});
|
|
4162
|
-
const rendered = {
|
|
4233
|
+
const rendered = {
|
|
4234
|
+
svg,
|
|
4235
|
+
expiresAt: pairing.expiresAt,
|
|
4236
|
+
...pairing.statusId === void 0 ? {} : { statusId: pairing.statusId }
|
|
4237
|
+
};
|
|
4163
4238
|
if (wantsJson(request)) {
|
|
4164
4239
|
this.#writeHeaders(response, 200, "application/json; charset=utf-8");
|
|
4165
4240
|
response.end(JSON.stringify(rendered));
|
|
@@ -4175,6 +4250,7 @@ var PairingPageServer = class {
|
|
|
4175
4250
|
if ([
|
|
4176
4251
|
"/",
|
|
4177
4252
|
"/pair",
|
|
4253
|
+
"/pair/status",
|
|
4178
4254
|
"/selection",
|
|
4179
4255
|
"/group-chat-settings",
|
|
4180
4256
|
"/peer-chat-settings",
|
package/dist/upgrade-worker.js
CHANGED
|
@@ -19391,7 +19391,7 @@ async function installPreparedPackage(options) {
|
|
|
19391
19391
|
import { createConnection, createServer } from "node:net";
|
|
19392
19392
|
import { join as join5, resolve as resolve3 } from "node:path";
|
|
19393
19393
|
|
|
19394
|
-
// ../../shared/sdk/dist/chunks/chunk-
|
|
19394
|
+
// ../../shared/sdk/dist/chunks/chunk-QTBB2U7G.js
|
|
19395
19395
|
var IdSchema = external_exports.string().trim().min(1).max(256);
|
|
19396
19396
|
var IsoDateSchema = external_exports.iso.datetime({ offset: true });
|
|
19397
19397
|
var Base64UrlKeyIdSchema = external_exports.string().regex(/^[A-Za-z0-9_-]{22}$/u, "Expected a 16-byte base64url key ID");
|
|
@@ -20499,13 +20499,25 @@ var PairingCreateResultSchema = external_exports.discriminatedUnion("ok", [
|
|
|
20499
20499
|
external_exports.object({
|
|
20500
20500
|
ok: external_exports.literal(true),
|
|
20501
20501
|
code: external_exports.string().min(32).max(256),
|
|
20502
|
-
expiresAt: external_exports.number().int().positive()
|
|
20502
|
+
expiresAt: external_exports.number().int().positive(),
|
|
20503
|
+
// Presence advertises the PC-only status endpoint; older Relays omit it.
|
|
20504
|
+
statusId: external_exports.string().regex(/^[A-Za-z0-9_-]{43}$/u).optional()
|
|
20503
20505
|
}),
|
|
20504
20506
|
external_exports.object({
|
|
20505
20507
|
ok: external_exports.literal(false),
|
|
20506
20508
|
error: ProtocolFailureSchema
|
|
20507
20509
|
})
|
|
20508
20510
|
]);
|
|
20511
|
+
var PairingStatusRequestSchema = external_exports.object({
|
|
20512
|
+
userId: IdSchema,
|
|
20513
|
+
machineId: IdSchema,
|
|
20514
|
+
statusId: external_exports.string().regex(/^[A-Za-z0-9_-]{43}$/u)
|
|
20515
|
+
});
|
|
20516
|
+
var PairingStatusSchema = external_exports.enum(["pending", "paired", "unavailable"]);
|
|
20517
|
+
var PairingStatusResultSchema = external_exports.discriminatedUnion("ok", [
|
|
20518
|
+
external_exports.object({ ok: external_exports.literal(true), state: PairingStatusSchema }),
|
|
20519
|
+
external_exports.object({ ok: external_exports.literal(false), error: ProtocolFailureSchema })
|
|
20520
|
+
]);
|
|
20509
20521
|
var PairingExchangeRequestSchema = external_exports.object({
|
|
20510
20522
|
code: external_exports.string().min(32).max(256),
|
|
20511
20523
|
clientId: IdSchema
|
|
@@ -21912,7 +21924,7 @@ var AndroidProtocolSchemas = {
|
|
|
21912
21924
|
ProtocolError: ProtocolErrorSchema
|
|
21913
21925
|
};
|
|
21914
21926
|
|
|
21915
|
-
// ../../shared/sdk/dist/chunks/chunk-
|
|
21927
|
+
// ../../shared/sdk/dist/chunks/chunk-QN3OD5UE.js
|
|
21916
21928
|
var OwnerSchema = external_exports.object({ pid: external_exports.number().int().positive(), instanceId: external_exports.uuid().optional() });
|
|
21917
21929
|
var PeerChatRequestSchema = external_exports.object({
|
|
21918
21930
|
sessionId: IdSchema,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentknight/client",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.42",
|
|
4
4
|
"description": "AgentKnight PC Agent CLI for remote Copilot, PI and ACP coding sessions",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"qrcode": "1.5.4",
|
|
42
42
|
"qrcode-terminal": "0.12.0",
|
|
43
43
|
"zod": "4.5.4",
|
|
44
|
-
"@agentknight/sdk": "0.9.
|
|
44
|
+
"@agentknight/sdk": "0.9.42"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@types/qrcode": "1.5.6",
|