@agentknight/client 0.9.46 → 0.9.48

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 CHANGED
@@ -11,6 +11,9 @@ Call `initialize` with an explicit absolute `dataDirectory` and the connection,
11
11
  identity and logging options, then manage the returned runtime with `start` and
12
12
  `stop`. The SDK does not select `~/.ak` or read the CLI configuration for you.
13
13
  Do not share a data directory between running instances.
14
+ After starting, `disconnectRelay()` pauses remote access while preserving local
15
+ providers and credentials. Use `reconnectRelay()` to resume and `getStatus()`
16
+ to verify recovery.
14
17
 
15
18
  The CLI depends on the SDK; both use the same release version. The SDK can be
16
19
  published independently through the [npm release workflow](../../.github/workflows/agentknight-npm-publish.yml).
@@ -121,6 +124,12 @@ HTTPS and WSS for the entire PC Agent connection. `AGENTKNIGHT_MACHINE_NAME`
121
124
  controls the PC name shown to mobile clients. The selection and pairing webpage
122
125
  listens only on loopback; `PAIRING_PAGE_PORT` changes its local port.
123
126
 
127
+ Use **重连** on the local page to retry with saved credentials without
128
+ restarting coding agents. Recognized authorization-service outages retry
129
+ automatically; other server-initiated disconnects require user action.
130
+ **断开连接** pauses remote access until **重连** or a PC Client restart,
131
+ without stopping local agents or clearing saved login.
132
+
124
133
  Repository checkouts also include Windows Scheduled Task and macOS LaunchAgent
125
134
  installers under `clients/pc-agent/scripts`. Services use the same canonical
126
135
  configuration as the CLI, not a copied environment file. Service support files
@@ -198,6 +207,13 @@ Relay is reported explicitly instead of guessing a username from `USER_ID`.
198
207
  See the [AgentKnight repository](https://github.com/hydraxman/AgentKnight) for
199
208
  Relay Server and Android client setup.
200
209
 
210
+ ## Windows app
211
+
212
+ The Windows app's **PC Client** tab downloads and caches the published client;
213
+ it is not bundled with the app. Follow the dependency prompts, then configure
214
+ your Relay connection. Closing the app stops only clients it started;
215
+ an existing client is reused without changing its settings or lifetime.
216
+
201
217
  ## Coding agents
202
218
 
203
219
  The Copilot SDK and bundled CLI are pinned together in the [SDK manifest](../../shared/sdk/package.json).
@@ -261,8 +277,11 @@ AgentKnight with optional dependencies enabled to use PI.
261
277
  Source builds and the complete adapter suite also require the PI-compatible Node
262
278
  version; Copilot-only operation retains the baseline version in the manifest.
263
279
 
264
- Codex (App Server) and Claude (Agent SDK) expose only AgentKnight-created
265
- conversations and their saved history, not existing CLI/IDE conversations.
280
+ Enabling Codex or Claude synchronizes existing and newly discovered native
281
+ sessions to the phone. Reading history does not start model work; sending resumes
282
+ the original session. Disabling synchronization cancels only AgentKnight's work,
283
+ not an external CLI process. Claude discovery and history do not require provider
284
+ credentials; sending requires the authentication described above.
266
285
  Credentials stay on the PC; discovery does not verify authentication.
267
286
  Copilot-specific Workbench, group and peer-chat operations remain unsupported.
268
287
 
package/dist/cli.js CHANGED
@@ -3399,9 +3399,20 @@ function renderAgentSelectionPage(input) {
3399
3399
  const accountPanel = account === void 0 ? "" : `
3400
3400
  <div id="relay-account" class="account" data-state="${account.state}" role="status" aria-label="Relay \u8D26\u6237">
3401
3401
  <span id="relay-account-name" class="account-name">${escapeHtml(relayAccountLabel(account))}</span>
3402
- <div class="account-meta"><span id="relay-account-method">${account.method === "microsoft" ? "Microsoft" : "\u4F20\u7EDF\u8D26\u6237"}</span><span id="relay-account-role"${account.user === void 0 ? " hidden" : ""}>${account.user?.role === "admin" ? "\u7BA1\u7406\u5458" : "\u666E\u901A\u7528\u6237"}</span><span id="relay-account-state">${account.state === "signed-in" ? "\u5DF2\u767B\u5F55" : account.state === "connecting" ? "\u8FDE\u63A5\u4E2D" : account.state === "error" ? "\u767B\u5F55\u5F02\u5E38" : "\u72B6\u6001\u672A\u77E5"}</span>${accountUrl === void 0 ? "" : `<a id="relay-account-link" href="${escapeHtml(accountUrl)}" target="_blank" rel="noopener noreferrer"${account.method === "microsoft" ? "" : " hidden"}>\u67E5\u770B\u8D26\u6237</a>`}</div>
3402
+ <div class="account-meta"><span id="relay-account-method">${account.method === "microsoft" ? "Microsoft" : "\u4F20\u7EDF\u8D26\u6237"}</span><span id="relay-account-role"${account.user === void 0 ? " hidden" : ""}>${account.user?.role === "admin" ? "\u7BA1\u7406\u5458" : "\u666E\u901A\u7528\u6237"}</span><span id="relay-account-state">${account.state === "signed-in" ? "\u5DF2\u767B\u5F55" : account.state === "connecting" ? "\u8FDE\u63A5\u4E2D" : account.state === "disconnected" ? "\u5DF2\u65AD\u5F00" : account.state === "error" ? "\u767B\u5F55\u5F02\u5E38" : "\u72B6\u6001\u672A\u77E5"}</span>${accountUrl === void 0 ? "" : `<a id="relay-account-link" href="${escapeHtml(accountUrl)}" target="_blank" rel="noopener noreferrer"${account.method === "microsoft" ? "" : " hidden"}>\u67E5\u770B\u8D26\u6237</a>`}</div>
3403
3403
  <p id="relay-account-error" class="error"${account.error === void 0 ? " hidden" : ""}>${escapeHtml(account.error ?? "")}</p>
3404
3404
  </div>`;
3405
+ const reconnect = input.relayState === void 0 ? "" : `
3406
+ <form id="relay-reconnect-form" method="post" action="/relay-reconnect" data-state="${input.relayState}">
3407
+ <input type="hidden" name="token" value="${escapeHtml(input.token)}">
3408
+ <button id="relay-reconnect" class="secondary" type="submit"${input.relayState === "registered" ? " hidden" : ""}${input.relayState === "connecting" ? " disabled" : ""}>${input.relayState === "connecting" ? "\u8FDE\u63A5\u4E2D\u2026" : "\u91CD\u8FDE"}</button>
3409
+ <p id="relay-reconnect-error" class="error" role="alert"${input.reconnectError ? "" : " hidden"}>${escapeHtml(input.reconnectError ?? "")}</p>
3410
+ </form>`;
3411
+ const disconnect = !input.canDisconnectRelay || input.relayState === void 0 ? "" : `
3412
+ <form id="relay-disconnect-form" method="post" action="/relay-disconnect">
3413
+ <input type="hidden" name="token" value="${escapeHtml(input.token)}">
3414
+ <button id="relay-disconnect" class="secondary" type="submit"${input.relayState === "disconnected" ? " hidden" : ""}>\u65AD\u5F00\u8FDE\u63A5</button>
3415
+ </form>`;
3405
3416
  const deployment = input.deploymentInfo;
3406
3417
  const upgradedAt = deployment?.upgradedAt;
3407
3418
  const upgradeTime = upgradedAt === void 0 ? void 0 : new Date(upgradedAt);
@@ -3455,6 +3466,7 @@ function renderAgentSelectionPage(input) {
3455
3466
  header { display: flex; gap: 24px; align-items: center; justify-content: space-between; margin-bottom: 38px; }
3456
3467
  .header-actions { display: flex; align-items: center; gap: 24px; min-width: 0; }
3457
3468
  .header-actions > a { flex-shrink: 0; }
3469
+ #relay-reconnect, #relay-disconnect { white-space: nowrap; }
3458
3470
  .account { min-width: 0; max-width: 360px; text-align: right; }
3459
3471
  .account-name { display: block; font-size: 15px; font-weight: 650; overflow-wrap: anywhere; }
3460
3472
  .account-meta { display: flex; justify-content: flex-end; flex-wrap: wrap; gap: 6px 12px; margin-top: 6px; font-size: 12px; color: var(--muted); }
@@ -3546,7 +3558,7 @@ function renderAgentSelectionPage(input) {
3546
3558
  </head>
3547
3559
  <body>
3548
3560
  <main>
3549
- <header><div><span class="brand"><span class="brand-mark" aria-hidden="true"></span>AgentKnight</span><h1>${escapeHtml(input.machineName)}</h1></div>${account === void 0 ? '<a href="/">\u5237\u65B0</a>' : `<div class="header-actions">${accountPanel}<a href="/">\u5237\u65B0</a></div>`}</header>
3561
+ <header><div><span class="brand"><span class="brand-mark" aria-hidden="true"></span>AgentKnight</span><h1>${escapeHtml(input.machineName)}</h1></div><div class="header-actions">${accountPanel}${reconnect}${disconnect}<a href="/">\u5237\u65B0</a></div></header>
3550
3562
  ${deploymentPanel}
3551
3563
  <div class="layout">
3552
3564
  <section aria-labelledby="agents-heading">
@@ -3570,7 +3582,7 @@ function renderAgentSelectionPage(input) {
3570
3582
  <input type="hidden" name="token" value="${escapeHtml(input.token)}">
3571
3583
  <div class="pair-actions"><button id="show-qr" class="secondary" type="submit"${input.pairing ? " hidden" : ""}>\u663E\u793A\u4E8C\u7EF4\u7801</button><button id="refresh-qr" class="secondary" type="submit" formaction="/refresh"${input.pairing ? "" : " hidden"}>\u5237\u65B0\u4E8C\u7EF4\u7801</button><button id="hide-qr" class="secondary" type="button"${input.pairing ? "" : " hidden"}>\u9690\u85CF</button></div>
3572
3584
  </form>
3573
- <p id="pair-error" class="error" role="alert"${input.pairingError ? "" : " hidden"}>${escapeHtml(input.pairingError ?? "")}</p>
3585
+ <p id="pair-error" class="error" role="alert"${input.pairingError ? "" : " hidden"}${input.pairingError && input.relayState !== void 0 && input.relayState !== "registered" ? ' data-relay-offline="true"' : ""}>${escapeHtml(input.pairingError ?? "")}</p>
3574
3586
  </aside>
3575
3587
  </div>
3576
3588
  </main>
@@ -3579,6 +3591,98 @@ function renderAgentSelectionPage(input) {
3579
3591
  }
3580
3592
  var localPageScript = `
3581
3593
  (() => {
3594
+ const reconnectForm = document.querySelector('#relay-reconnect-form');
3595
+ if (reconnectForm) {
3596
+ const button = document.querySelector('#relay-reconnect');
3597
+ const disconnectForm = document.querySelector('#relay-disconnect-form');
3598
+ const disconnectButton = document.querySelector('#relay-disconnect');
3599
+ const error = document.querySelector('#relay-reconnect-error');
3600
+ let stopped = false;
3601
+ let timer;
3602
+ let generation = 0;
3603
+ let submitting = false;
3604
+ let state = reconnectForm.dataset.state;
3605
+ let failureState;
3606
+ const update = next => {
3607
+ if (!next || !['connecting', 'registered', 'disconnected', 'error'].includes(next.state)) throw new Error('Invalid Relay status');
3608
+ state = next.state;
3609
+ button.hidden = next.state === 'registered';
3610
+ button.disabled = next.state === 'connecting';
3611
+ button.textContent = next.state === 'connecting' ? '\u8FDE\u63A5\u4E2D\u2026' : '\u91CD\u8FDE';
3612
+ if (disconnectButton) {
3613
+ disconnectButton.hidden = next.state === 'disconnected';
3614
+ disconnectButton.disabled = false;
3615
+ disconnectButton.textContent = '\u65AD\u5F00\u8FDE\u63A5';
3616
+ }
3617
+ if (next.state === 'disconnected') conceal();
3618
+ const pairingError = document.querySelector('#pair-error');
3619
+ if (next.state === 'registered' && pairingError?.dataset.relayOffline === 'true') {
3620
+ pairingError.hidden = true;
3621
+ pairingError.textContent = '';
3622
+ delete pairingError.dataset.relayOffline;
3623
+ }
3624
+ };
3625
+ const poll = async () => {
3626
+ const current = generation;
3627
+ try {
3628
+ const response = await fetch('/relay-status', { cache: 'no-store', signal: AbortSignal.timeout(5000) });
3629
+ if (!response.ok) throw new Error('Relay status unavailable');
3630
+ const next = await response.json();
3631
+ if (!stopped && current === generation && !submitting) {
3632
+ update(next);
3633
+ if (next.state !== failureState) error.hidden = true;
3634
+ }
3635
+ } catch {
3636
+ if (!stopped && current === generation && !submitting) {
3637
+ error.textContent = '\u65E0\u6CD5\u66F4\u65B0 Relay \u8FDE\u63A5\u72B6\u6001\uFF0C\u8BF7\u5237\u65B0\u9875\u9762\u3002';
3638
+ error.hidden = false;
3639
+ }
3640
+ } finally {
3641
+ if (!stopped && current === generation) timer = setTimeout(poll, 3000);
3642
+ }
3643
+ };
3644
+ const submit = async (event, form, actionButton, disconnecting) => {
3645
+ event.preventDefault();
3646
+ if (actionButton.disabled || submitting) return;
3647
+ const current = ++generation;
3648
+ clearTimeout(timer);
3649
+ submitting = true;
3650
+ button.disabled = true;
3651
+ if (disconnectButton) disconnectButton.disabled = true;
3652
+ actionButton.textContent = disconnecting ? '\u6B63\u5728\u65AD\u5F00\u2026' : '\u8FDE\u63A5\u4E2D\u2026';
3653
+ error.hidden = true;
3654
+ failureState = undefined;
3655
+ try {
3656
+ const response = await fetch(form.action, {
3657
+ method: 'POST', headers: { Accept: 'application/json' },
3658
+ body: new URLSearchParams(new FormData(form)), signal: AbortSignal.timeout(5000),
3659
+ });
3660
+ if (!response.ok) throw new Error('Relay reconnect failed');
3661
+ const next = await response.json();
3662
+ if (!stopped && current === generation) {
3663
+ update(next);
3664
+ if (actionButton.hidden) (button.hidden ? disconnectButton : button)?.focus();
3665
+ }
3666
+ } catch {
3667
+ if (!stopped && current === generation) {
3668
+ update({ state: disconnecting ? state : 'error' });
3669
+ failureState = state;
3670
+ error.textContent = disconnecting ? '\u65E0\u6CD5\u65AD\u5F00 Relay\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002' : '\u65E0\u6CD5\u91CD\u8FDE Relay\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002';
3671
+ error.hidden = false;
3672
+ }
3673
+ } finally {
3674
+ submitting = false;
3675
+ if (!stopped && current === generation) timer = setTimeout(poll, 1000);
3676
+ }
3677
+ };
3678
+ reconnectForm.addEventListener('submit', event => submit(event, reconnectForm, button, false));
3679
+ if (disconnectForm && disconnectButton) {
3680
+ disconnectForm.addEventListener('submit', event => submit(event, disconnectForm, disconnectButton, true));
3681
+ }
3682
+ addEventListener('pagehide', () => { stopped = true; generation++; clearTimeout(timer); });
3683
+ addEventListener('pageshow', () => { if (stopped) { stopped = false; timer = setTimeout(poll, 0); } });
3684
+ timer = setTimeout(poll, 1000);
3685
+ }
3582
3686
  const account = document.querySelector('#relay-account');
3583
3687
  if (account) {
3584
3688
  const accountLabel = ${relayAccountLabel.toString()};
@@ -3605,7 +3709,7 @@ var localPageScript = `
3605
3709
  role.hidden = !next.user;
3606
3710
  role.textContent = next.user?.role === 'admin' ? '\u7BA1\u7406\u5458' : '\u666E\u901A\u7528\u6237';
3607
3711
  account.dataset.state = next.state;
3608
- state.textContent = next.state === 'signed-in' ? '\u5DF2\u767B\u5F55' : next.state === 'connecting' ? '\u8FDE\u63A5\u4E2D' : next.state === 'error' ? '\u767B\u5F55\u5F02\u5E38' : '\u72B6\u6001\u672A\u77E5';
3712
+ state.textContent = next.state === 'signed-in' ? '\u5DF2\u767B\u5F55' : next.state === 'connecting' ? '\u8FDE\u63A5\u4E2D' : next.state === 'disconnected' ? '\u5DF2\u65AD\u5F00' : next.state === 'error' ? '\u767B\u5F55\u5F02\u5E38' : '\u72B6\u6001\u672A\u77E5';
3609
3713
  error.textContent = next.error ?? '';
3610
3714
  error.hidden = !next.error;
3611
3715
  } catch {
@@ -3786,6 +3890,7 @@ var localPageScript = `
3786
3890
  loading = true;
3787
3891
  show.disabled = refresh.disabled = hide.disabled = true;
3788
3892
  pairError.hidden = true;
3893
+ delete pairError.dataset.relayOffline;
3789
3894
  conceal();
3790
3895
  const generation = statusGeneration;
3791
3896
  const endpoint = event.submitter?.getAttribute('formaction') || pairing.action;
@@ -4131,6 +4236,11 @@ var PairingPageServer = class {
4131
4236
  return;
4132
4237
  }
4133
4238
  const relayLogin = this.#options.relayLogin;
4239
+ if (relayLogin === void 0 && this.#options.reconnectRelay !== void 0 && request.method === "GET" && requestUrl.pathname === "/relay-status") {
4240
+ this.#writeHeaders(response, 200, "application/json; charset=utf-8");
4241
+ response.end(JSON.stringify({ state: this.#options.getRegistrationStatus().state }));
4242
+ return;
4243
+ }
4134
4244
  if (relayLogin === void 0 && this.#options.getAccount !== void 0 && request.method === "GET" && requestUrl.pathname === "/relay-account") {
4135
4245
  const account = await this.#options.getAccount();
4136
4246
  this.#writeHeaders(response, 200, "application/json; charset=utf-8");
@@ -4174,12 +4284,44 @@ var PairingPageServer = class {
4174
4284
  this.#redirectLogin(response, operation === "start" && next.state === "pending" ? next.verificationUri : "/");
4175
4285
  return;
4176
4286
  }
4177
- if (request.method === "POST" && ["/pair", "/pair/status", "/refresh", "/selection", "/group-chat-settings", "/peer-chat-settings"].includes(requestUrl.pathname)) {
4287
+ if (request.method === "POST" && ["/pair", "/pair/status", "/refresh", "/selection", "/group-chat-settings", "/peer-chat-settings", "/relay-reconnect", "/relay-disconnect"].includes(requestUrl.pathname)) {
4178
4288
  if (await this.#readAuthorizedForm(request, response) === void 0) return;
4179
4289
  this.#renderLogin(response, 409, this.#loginState(relayLogin));
4180
4290
  return;
4181
4291
  }
4182
4292
  }
4293
+ const relayOperation = requestUrl.pathname === "/relay-reconnect" ? this.#options.reconnectRelay : requestUrl.pathname === "/relay-disconnect" ? this.#options.disconnectRelay : void 0;
4294
+ if (request.method === "POST" && relayOperation !== void 0) {
4295
+ const disconnecting = requestUrl.pathname === "/relay-disconnect";
4296
+ const form = await this.#readAuthorizedForm(request, response);
4297
+ if (form === void 0) return;
4298
+ if (form.getAll("token").length !== 1 || [...form.keys()].some((key) => key !== "token")) {
4299
+ this.#writeHeaders(response, 400, "text/plain; charset=utf-8");
4300
+ response.end(disconnecting ? "Invalid Relay disconnect request." : "Invalid Relay reconnect request.");
4301
+ return;
4302
+ }
4303
+ try {
4304
+ relayOperation();
4305
+ } catch (error) {
4306
+ const message = disconnecting ? "\u65E0\u6CD5\u65AD\u5F00 Relay\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002" : "\u65E0\u6CD5\u91CD\u8FDE Relay\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002";
4307
+ this.#options.logger?.error({ error: toErrorDetails(error) }, disconnecting ? "relay.disconnect.failed" : "relay.reconnect.failed");
4308
+ if (wantsJson(request)) {
4309
+ this.#writeHeaders(response, 503, "application/json; charset=utf-8");
4310
+ response.end(JSON.stringify({ error: message }));
4311
+ } else {
4312
+ await this.#renderPage(response, 503, { reconnectError: message });
4313
+ }
4314
+ return;
4315
+ }
4316
+ if (wantsJson(request)) {
4317
+ this.#writeHeaders(response, 200, "application/json; charset=utf-8");
4318
+ response.end(JSON.stringify({ state: this.#options.getRegistrationStatus().state }));
4319
+ } else {
4320
+ response.writeHead(303, { location: "/", "cache-control": "no-store" });
4321
+ response.end();
4322
+ }
4323
+ return;
4324
+ }
4183
4325
  const chatKind = requestUrl.pathname === "/group-chat-settings" ? "group" : requestUrl.pathname === "/peer-chat-settings" ? "peer" : void 0;
4184
4326
  const chatSettings = chatKind === "group" ? this.#options.groupChatSettings : this.#options.peerChatSettings;
4185
4327
  if (request.method === "POST" && chatKind !== void 0 && chatSettings !== void 0) {
@@ -4312,9 +4454,12 @@ var PairingPageServer = class {
4312
4454
  "/relay-login/start",
4313
4455
  "/relay-login/cancel",
4314
4456
  "/relay-login/callback",
4457
+ "/relay-reconnect",
4458
+ "/relay-disconnect",
4459
+ ...this.#options.reconnectRelay === void 0 || relayLogin !== void 0 ? [] : ["/relay-status"],
4315
4460
  ...relayLogin === void 0 ? [] : ["/relay-login/status"]
4316
4461
  ].includes(requestUrl.pathname)) {
4317
- response.setHeader("allow", requestUrl.pathname === "/pair" ? "GET, POST" : ["/", "/local-page.js", "/relay-login.js", "/relay-login/status", "/relay-login/callback"].includes(requestUrl.pathname) ? "GET" : "POST");
4462
+ response.setHeader("allow", requestUrl.pathname === "/pair" ? "GET, POST" : ["/", "/local-page.js", "/relay-login.js", "/relay-login/status", "/relay-login/callback", "/relay-status"].includes(requestUrl.pathname) ? "GET" : "POST");
4318
4463
  this.#writeHeaders(response, 405, "text/plain; charset=utf-8");
4319
4464
  response.end("Method not allowed.");
4320
4465
  return;
@@ -4354,6 +4499,8 @@ var PairingPageServer = class {
4354
4499
  response.end(renderAgentSelectionPage({
4355
4500
  machineName: this.#options.machineName,
4356
4501
  token: this.#refreshToken,
4502
+ ...this.#options.reconnectRelay === void 0 ? {} : { relayState: registration.state },
4503
+ ...this.#options.disconnectRelay === void 0 ? {} : { canDisconnectRelay: true },
4357
4504
  ...deploymentInfo === void 0 ? {} : { deploymentInfo },
4358
4505
  ...account === void 0 ? {} : { account },
4359
4506
  ...agents === void 0 ? {} : { agents },
@@ -5313,8 +5460,8 @@ var RelayAccount = class {
5313
5460
  this.#expiresAt = 0;
5314
5461
  this.#pending = void 0;
5315
5462
  return this.#view(
5316
- registration.state === "connecting" ? "connecting" : "error",
5317
- registration.state === "error" ? "Relay \u8FDE\u63A5\u5F02\u5E38\uFF0C\u8BF7\u68C0\u67E5\u8FDE\u63A5\u6216\u91CD\u65B0\u767B\u5F55\u3002" : void 0
5463
+ registration.state === "connecting" ? "connecting" : "disconnected",
5464
+ registration.state === "error" ? "Relay \u8FDE\u63A5\u5DF2\u65AD\u5F00\u3002" : void 0
5318
5465
  );
5319
5466
  }
5320
5467
  if (this.#cached !== void 0 && Date.now() < this.#expiresAt) return this.#cached;
@@ -7248,6 +7395,8 @@ async function main() {
7248
7395
  port: config.pairingPagePort,
7249
7396
  pairingProvider,
7250
7397
  getRegistrationStatus: () => runningAgent.relayRegistrationStatus,
7398
+ reconnectRelay: () => runningAgent.reconnectRelay(),
7399
+ disconnectRelay: () => runningAgent.disconnectRelay(),
7251
7400
  getAccount: () => relayAccount.read(runningAgent.relayRegistrationStatus),
7252
7401
  getDeploymentInfo: async () => {
7253
7402
  const lastUpgrade = await readLastUpgrade(config.dataDirectory);
@@ -20193,7 +20193,7 @@ async function installPreparedPackage(options) {
20193
20193
  import { createConnection, createServer } from "node:net";
20194
20194
  import { join as join5, resolve as resolve3 } from "node:path";
20195
20195
 
20196
- // ../../shared/sdk/dist/chunks/chunk-DUMC5F2D.js
20196
+ // ../../shared/sdk/dist/chunks/chunk-BDKVGENQ.js
20197
20197
  var IdSchema = external_exports.string().trim().min(1).max(256);
20198
20198
  var IsoDateSchema = external_exports.iso.datetime({ offset: true });
20199
20199
  var Base64UrlKeyIdSchema = external_exports.string().regex(/^[A-Za-z0-9_-]{22}$/u, "Expected a 16-byte base64url key ID");
@@ -22765,7 +22765,7 @@ var AndroidProtocolSchemas = {
22765
22765
  ProtocolError: ProtocolErrorSchema
22766
22766
  };
22767
22767
 
22768
- // ../../shared/sdk/dist/chunks/chunk-GRXWNM6S.js
22768
+ // ../../shared/sdk/dist/chunks/chunk-7HZ5UZSC.js
22769
22769
  var OwnerSchema = external_exports.object({ pid: external_exports.number().int().positive(), instanceId: external_exports.uuid().optional() });
22770
22770
  var PeerChatRequestSchema = external_exports.object({
22771
22771
  sessionId: IdSchema,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentknight/client",
3
- "version": "0.9.46",
3
+ "version": "0.9.48",
4
4
  "description": "AgentKnight PC Agent CLI for remote coding sessions",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -36,12 +36,12 @@
36
36
  "registry": "https://registry.npmjs.org/"
37
37
  },
38
38
  "dependencies": {
39
- "@napi-rs/keyring": "2.1.0",
39
+ "@napi-rs/keyring": "2.1.2",
40
40
  "pino": "10.3.1",
41
41
  "qrcode": "1.5.4",
42
42
  "qrcode-terminal": "0.12.0",
43
43
  "zod": "4.6.5",
44
- "@agentknight/sdk": "0.9.46"
44
+ "@agentknight/sdk": "0.9.48"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@types/qrcode": "1.5.6",