@nextclaw/ui 0.12.22 → 0.12.23

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.
Files changed (96) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/assets/{api-lwyw9j7i.js → api-BGd3rgv_.js} +5 -5
  3. package/dist/assets/app-manager-provider-BuJ_U9eC.js +1 -0
  4. package/dist/assets/{app-navigation.config-DgiR0c5_.js → app-navigation.config-BTdUuqXS.js} +1 -1
  5. package/dist/assets/{book-open-DgLqYpNY.js → book-open-DDlN5MvX.js} +1 -1
  6. package/dist/assets/{channels-list-page-Dl839n02.js → channels-list-page-BrwymXPe.js} +2 -2
  7. package/dist/assets/{chat-DwUf7AKR.js → chat-DGM6K3Qs.js} +5 -5
  8. package/dist/assets/{chat-page-B-FvPmA7.js → chat-page-DpmXMWNS.js} +1 -1
  9. package/dist/assets/{chunk-JZWAC4HX-u4uYphxM.js → chunk-JZWAC4HX-Kydj4yEz.js} +1 -1
  10. package/dist/assets/{config-split-page-BMRGuCJQ.js → config-split-page-DIOCjj2Q.js} +1 -1
  11. package/dist/assets/{createLucideIcon-BZkY6emz.js → createLucideIcon-BLMK3QUd.js} +1 -1
  12. package/dist/assets/{desktop-update-config-D5g_gPak.js → desktop-update-config-BGKiqc6q.js} +1 -1
  13. package/dist/assets/{dialog-CdtCU2xX.js → dialog-dxsKz7jJ.js} +1 -1
  14. package/dist/assets/{dist-CuqvE--P.js → dist-DsYTOyq7.js} +1 -1
  15. package/dist/assets/{doc-browser-BUlCkZo2.js → doc-browser-C8FM5fC0.js} +1 -1
  16. package/dist/assets/doc-browser-RJUOL_GO.js +1 -0
  17. package/dist/assets/{doc-browser-context-DfLHAWbG.js → doc-browser-context-BJuMaI3o.js} +1 -1
  18. package/dist/assets/{doc-browser-CzCV73NJ.js → doc-browser-p82AdNO-.js} +1 -1
  19. package/dist/assets/{es2015-yYU5Ad5w.js → es2015-V75WQJ2s.js} +1 -1
  20. package/dist/assets/{external-link-Sw3ah_JD.js → external-link-DwfSfTLB.js} +1 -1
  21. package/dist/assets/{folder-D7-VTnkz.js → folder-CeJKPx5P.js} +1 -1
  22. package/dist/assets/{hash-zajSTDXZ.js → hash-BqxRTZW5.js} +1 -1
  23. package/dist/assets/i18n-DnTGDIRw.js +1 -0
  24. package/dist/assets/{index-Doxyk7L2.js → index-BrEdR78s.js} +2 -2
  25. package/dist/assets/{key-round-CnI1mc9F.js → key-round-CJ5gDAAG.js} +1 -1
  26. package/dist/assets/loader-circle-fd-vQKtW.js +1 -0
  27. package/dist/assets/{logo-badge-BQgKnVtz.js → logo-badge-KAe-7d8c.js} +1 -1
  28. package/dist/assets/{logos-CqVm0q0W.js → logos-C4sYP1Vl.js} +1 -1
  29. package/dist/assets/marketplace-page-B2Pm2RDJ.js +1 -0
  30. package/dist/assets/{marketplace-page-CawcdL6Y.js → marketplace-page-CPHxlYL8.js} +1 -1
  31. package/dist/assets/mcp-marketplace-page-BcjVmw36.js +1 -0
  32. package/dist/assets/{mcp-marketplace-page-DEGfJ_70.js → mcp-marketplace-page-CswPXSjf.js} +1 -1
  33. package/dist/assets/message-square-z_osm9c0.js +1 -0
  34. package/dist/assets/{model-config-r-1RPSrZ.js → model-config-Cmruiqdx.js} +1 -1
  35. package/dist/assets/{notice-card-BPtCVEKW.js → notice-card-D1RNsTn_.js} +1 -1
  36. package/dist/assets/play-Dv6Nr1Ew.js +1 -0
  37. package/dist/assets/plus-D8eKFY7h.js +1 -0
  38. package/dist/assets/{popover-jbfQhYQh.js → popover-BMyiifTA.js} +1 -1
  39. package/dist/assets/{provider-scoped-model-input-gdk2lmRi.js → provider-scoped-model-input-D7ACiMAO.js} +1 -1
  40. package/dist/assets/{providers-list-DpISIr3M.js → providers-list-gg7LrfuB.js} +1 -1
  41. package/dist/assets/{refresh-ccw-Bii4w8aB.js → refresh-ccw-ByVwmnN_.js} +1 -1
  42. package/dist/assets/{refresh-cw-BxojR62w.js → refresh-cw-PcqoYB3K.js} +1 -1
  43. package/dist/assets/remote-Db2M39Cv.js +1 -0
  44. package/dist/assets/{rotate-cw-1Xqa7LZ8.js → rotate-cw-BZ2JObNs.js} +1 -1
  45. package/dist/assets/runtime-config-page-BT_VV41p.js +1 -0
  46. package/dist/assets/{save--BVI5wZX.js → save-euRxl8pI.js} +1 -1
  47. package/dist/assets/{search-vChioOoe.js → search-CLd7m0M7.js} +1 -1
  48. package/dist/assets/{search-config-BWqz8nqY.js → search-config-0VTPpz-w.js} +1 -1
  49. package/dist/assets/{secrets-config-CjzSNg0Y.js → secrets-config-DwQbLLEy.js} +1 -1
  50. package/dist/assets/{select-Cw5Zkb1w.js → select-DTdzR8j8.js} +1 -1
  51. package/dist/assets/{sessions-config-page-beoDPtII.js → sessions-config-page-CAG7Zevv.js} +1 -1
  52. package/dist/assets/{setting-row-Cjl2d40s.js → setting-row-CvKngoNI.js} +1 -1
  53. package/dist/assets/{settings-CiRChctQ.js → settings-drbWqzA4.js} +1 -1
  54. package/dist/assets/skeleton-BK1SOSRA.js +1 -0
  55. package/dist/assets/{sparkles-D1ZKWdm4.js → sparkles-DVfeSVJQ.js} +1 -1
  56. package/dist/assets/{status-dot-Dv_hiUVa.js → status-dot-ChvPCib9.js} +1 -1
  57. package/dist/assets/{tabs-custom-CsACkVji.js → tabs-custom-Hia_ong0.js} +1 -1
  58. package/dist/assets/{tag-chip-CoWHxYJj.js → tag-chip-BywQeHJj.js} +1 -1
  59. package/dist/assets/theme-provider-COAwWFv8.js +2 -0
  60. package/dist/assets/{tooltip-GYzH-Hfq.js → tooltip-BOYp8Ue7.js} +1 -1
  61. package/dist/assets/{trash-2-rY9ZteZX.js → trash-2-CBsHCfqq.js} +1 -1
  62. package/dist/assets/{use-config-BhJHD3-G.js → use-config-DTwhNDQE.js} +1 -1
  63. package/dist/assets/{use-confirm-dialog-Bqgy3Gi-.js → use-confirm-dialog-oeSqhmrx.js} +1 -1
  64. package/dist/assets/{use-infinite-scroll-loader-BfexitoF.js → use-infinite-scroll-loader-X3KGuME8.js} +1 -1
  65. package/dist/assets/{use-viewport-layout-D33zVbr5.js → use-viewport-layout-C0NJAVXs.js} +1 -1
  66. package/dist/assets/x-CM-XDMpk.js +1 -0
  67. package/dist/index.html +39 -39
  68. package/package.json +6 -6
  69. package/src/features/account/hooks/use-auth.test.ts +7 -5
  70. package/src/features/account/hooks/use-auth.ts +23 -20
  71. package/src/features/system-status/hooks/use-system-status.ts +6 -28
  72. package/src/features/system-status/index.ts +2 -1
  73. package/src/features/system-status/managers/system-status.manager.bootstrap-polling.test.ts +14 -4
  74. package/src/features/system-status/managers/system-status.manager.test.ts +2 -8
  75. package/src/features/system-status/managers/system-status.manager.ts +20 -30
  76. package/src/shared/components/common/brand-header.test.tsx +84 -3
  77. package/src/shared/components/common/brand-header.tsx +37 -39
  78. package/src/shared/lib/api/managers/client.manager.ts +30 -2
  79. package/src/shared/lib/api/utils/config.utils.ts +6 -4
  80. package/src/shared/lib/i18n/desktop-update-labels.utils.ts +3 -1
  81. package/src/shared/lib/transport/index.ts +1 -0
  82. package/src/shared/lib/transport/transport.types.ts +20 -0
  83. package/dist/assets/app-manager-provider-C0ONQxUg.js +0 -1
  84. package/dist/assets/doc-browser-Doh2541x.js +0 -1
  85. package/dist/assets/i18n-C5Mibli1.js +0 -1
  86. package/dist/assets/loader-circle-B5i8oMMY.js +0 -1
  87. package/dist/assets/marketplace-page-BRHkZaO5.js +0 -1
  88. package/dist/assets/mcp-marketplace-page-CL7BF4dD.js +0 -1
  89. package/dist/assets/message-square-D6Z4NwpG.js +0 -1
  90. package/dist/assets/play-D8WJLnJe.js +0 -1
  91. package/dist/assets/plus-Di0KAkiO.js +0 -1
  92. package/dist/assets/remote-BnRNqMlb.js +0 -1
  93. package/dist/assets/runtime-config-page-DQ8YY8Lc.js +0 -1
  94. package/dist/assets/skeleton-CFQRIUzt.js +0 -1
  95. package/dist/assets/theme-provider-B5XReW_-.js +0 -1
  96. package/dist/assets/x-DpTzXQcX.js +0 -1
@@ -3,7 +3,6 @@ import { runtimeUpdateManager, useRuntimeUpdateStore } from '@/features/system-s
3
3
  import { useAppMeta } from '@/shared/hooks/use-config';
4
4
  import { type ReactNode, useState } from 'react';
5
5
  import { RuntimeStatusEntry } from '@/app/components/layout/runtime-status-entry';
6
- import { cn } from '@/shared/lib/utils';
7
6
  import { t } from '@/shared/lib/i18n';
8
7
 
9
8
  type BrandHeaderProps = {
@@ -74,10 +73,7 @@ function RuntimeUpdateInlineStatus() {
74
73
  return (
75
74
  <button
76
75
  type="button"
77
- className={cn(
78
- 'inline-flex h-5 shrink-0 items-center rounded-full px-2 text-[11px] font-semibold leading-none ring-1 transition-colors',
79
- resolveInlineUpdateTone(snapshot.status)
80
- )}
76
+ className="inline-flex h-5 shrink-0 items-center rounded-full bg-emerald-50 px-2 text-[11px] font-semibold leading-none text-emerald-700 ring-1 ring-emerald-100 transition-colors hover:bg-emerald-100 disabled:opacity-70"
81
77
  disabled={busyAction === 'applying'}
82
78
  onClick={() => void runtimeUpdateManager.applyDownloadedUpdate()}
83
79
  >
@@ -89,10 +85,7 @@ function RuntimeUpdateInlineStatus() {
89
85
  return (
90
86
  <button
91
87
  type="button"
92
- className={cn(
93
- 'inline-flex h-5 shrink-0 items-center rounded-full px-2 text-[11px] font-semibold leading-none ring-1 transition-colors',
94
- resolveInlineUpdateTone(snapshot.status)
95
- )}
88
+ className="inline-flex h-5 shrink-0 items-center rounded-full bg-amber-50 px-2 text-[11px] font-semibold leading-none text-amber-700 ring-1 ring-amber-100 transition-colors hover:bg-amber-100 disabled:opacity-70"
96
89
  disabled={busyAction === 'downloading'}
97
90
  onClick={() => void runtimeUpdateManager.downloadUpdate()}
98
91
  >
@@ -104,16 +97,22 @@ function RuntimeUpdateInlineStatus() {
104
97
  }
105
98
 
106
99
  function RuntimeUpdateInlineBadge({ snapshot }: { snapshot: UpdateSnapshot }) {
107
- const label = resolveInlineUpdateLabel(snapshot);
100
+ if (snapshot.status === 'blocked' || snapshot.status === 'failed') {
101
+ return <RuntimeUpdateIssueIcon snapshot={snapshot} />;
102
+ }
103
+ const label = snapshot.status === 'downloading'
104
+ ? resolveInlineDownloadLabel(snapshot)
105
+ : snapshot.status === 'downloaded'
106
+ ? t('desktopUpdatesInlineReady')
107
+ : snapshot.status === 'update-available'
108
+ ? t('desktopUpdatesInlineDownload')
109
+ : null;
108
110
  if (!label) {
109
111
  return null;
110
112
  }
111
113
  return (
112
114
  <span
113
- className={cn(
114
- 'inline-flex h-5 shrink-0 items-center rounded-full px-2 text-[11px] font-semibold leading-none ring-1 transition-colors',
115
- resolveInlineUpdateTone(snapshot.status)
116
- )}
115
+ className="inline-flex h-5 shrink-0 items-center rounded-full bg-amber-50 px-2 text-[11px] font-semibold leading-none text-amber-700 ring-1 ring-amber-100 transition-colors hover:bg-amber-100 disabled:opacity-70"
117
116
  title={t('updates')}
118
117
  >
119
118
  {label}
@@ -121,31 +120,30 @@ function RuntimeUpdateInlineBadge({ snapshot }: { snapshot: UpdateSnapshot }) {
121
120
  );
122
121
  }
123
122
 
124
- function resolveInlineUpdateLabel(snapshot: UpdateSnapshot): string | null {
125
- if (snapshot.status === 'downloading') {
126
- const percent = snapshot.progress?.percent;
127
- return percent === null || percent === undefined
128
- ? t('desktopUpdatesInlineDownloading')
129
- : t('desktopUpdatesInlineDownloadingPercent').replace('{percent}', String(percent));
130
- }
131
- if (snapshot.status === 'downloaded') {
132
- return t('desktopUpdatesInlineReady');
133
- }
134
- if (snapshot.status === 'update-available') {
135
- return t('desktopUpdatesInlineDownload');
136
- }
137
- if (snapshot.status === 'blocked' || snapshot.status === 'failed') {
138
- return t('desktopUpdatesInlineAttention');
139
- }
140
- return null;
123
+ function RuntimeUpdateIssueIcon({ snapshot }: { snapshot: UpdateSnapshot }) {
124
+ const title = snapshot.status === 'failed' ? t('desktopUpdatesStatusFailed') : t('desktopUpdatesStatusBlocked');
125
+ const recoveryCommand = snapshot.recoveryCommand?.trim() || null;
126
+ const diagnostic = snapshot.errorMessage?.trim() || snapshot.blockReason?.trim() || null;
127
+ const rootCause = snapshot.status === 'blocked' && snapshot.blockReason
128
+ ? t(`desktopUpdatesBlockedRootCause.${snapshot.blockReason}`)
129
+ : null;
130
+ const tooltip = [title, rootCause, diagnostic, recoveryCommand].filter(Boolean).join('\n');
131
+ return (
132
+ <span
133
+ role="img"
134
+ aria-label={title}
135
+ title={tooltip}
136
+ tabIndex={0}
137
+ className="inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-amber-50 text-[13px] font-bold leading-none text-amber-700 ring-1 ring-amber-100"
138
+ >
139
+ !
140
+ </span>
141
+ );
141
142
  }
142
143
 
143
- function resolveInlineUpdateTone(status: UpdateSnapshot['status']): string {
144
- if (status === 'downloaded') {
145
- return 'bg-emerald-50 text-emerald-700 ring-emerald-100 hover:bg-emerald-100 disabled:opacity-70';
146
- }
147
- if (status === 'blocked' || status === 'failed') {
148
- return 'bg-red-50 text-red-700 ring-red-100';
149
- }
150
- return 'bg-amber-50 text-amber-700 ring-amber-100 hover:bg-amber-100 disabled:opacity-70';
144
+ function resolveInlineDownloadLabel(snapshot: UpdateSnapshot): string {
145
+ const percent = snapshot.progress?.percent;
146
+ return percent === null || percent === undefined
147
+ ? t('desktopUpdatesInlineDownloading')
148
+ : t('desktopUpdatesInlineDownloadingPercent').replace('{percent}', String(percent));
151
149
  }
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  NextClawClient,
3
3
  type NextClawRealtimeEvent,
4
+ type NextClawQueryParams,
4
5
  type NextClawTransport,
5
6
  type NextClawTransportRequestInput,
6
7
  type NextClawTransportUploadInput
@@ -10,10 +11,10 @@ import { appClient } from '@/shared/lib/transport';
10
11
  import type { ApiResponse } from '@/shared/lib/api/types';
11
12
 
12
13
  const nextclawUiTransport: NextClawTransport = {
13
- request: async <T>({ body, method, path, signal, timeoutMs }: NextClawTransportRequestInput): Promise<T> => {
14
+ request: async <T>({ body, method, path, query, signal, timeoutMs }: NextClawTransportRequestInput): Promise<T> => {
14
15
  return await appClient.request({
15
16
  method,
16
- path,
17
+ path: appendQueryToPath(path, serializeQuery(query)),
17
18
  ...(body !== undefined ? { body } : {}),
18
19
  ...(signal ? { signal } : {}),
19
20
  ...(timeoutMs !== undefined ? { timeoutMs } : {})
@@ -105,6 +106,33 @@ function parseRequestBody(body: BodyInit | null | undefined): unknown {
105
106
  return body;
106
107
  }
107
108
 
109
+ function serializeQuery(query?: NextClawQueryParams): URLSearchParams | undefined {
110
+ if (!query) {
111
+ return undefined;
112
+ }
113
+ if (query instanceof URLSearchParams) {
114
+ return query;
115
+ }
116
+ const params = new URLSearchParams();
117
+ for (const [key, rawValue] of Object.entries(query)) {
118
+ const values = Array.isArray(rawValue) ? rawValue : [rawValue];
119
+ for (const value of values) {
120
+ if (value !== null && value !== undefined) {
121
+ params.append(key, String(value));
122
+ }
123
+ }
124
+ }
125
+ return params;
126
+ }
127
+
128
+ function appendQueryToPath(path: string, query?: URLSearchParams): string {
129
+ const serialized = query?.toString();
130
+ if (!serialized) {
131
+ return path;
132
+ }
133
+ return `${path}${path.includes('?') ? '&' : '?'}${serialized}`;
134
+ }
135
+
108
136
  function readApiErrorMessage(payload: ApiResponse<unknown>, fallback: string): string {
109
137
  return !payload.ok ? payload.error.message : fallback;
110
138
  }
@@ -1,4 +1,4 @@
1
- import { nextclawClient } from '../managers/client.manager';
1
+ import { nextclawClient } from '@/shared/lib/api/managers/client.manager';
2
2
  import type {
3
3
  AuthEnabledUpdateRequest,
4
4
  AuthLoginRequest,
@@ -38,7 +38,9 @@ import type {
38
38
  } from '@/shared/lib/api/types';
39
39
 
40
40
  export async function fetchAuthStatus(options: { timeoutMs?: number } = {}): Promise<AuthStatusView> {
41
- return await nextclawClient.auth.fetchStatus({ timeoutMs: options.timeoutMs ?? 5_000 });
41
+ return await nextclawClient.auth.fetchStatus({
42
+ timeoutMs: options.timeoutMs ?? 5_000,
43
+ });
42
44
  }
43
45
 
44
46
  export async function setupAuth(data: AuthSetupRequest): Promise<AuthStatusView> {
@@ -65,8 +67,8 @@ export async function fetchAppMeta(): Promise<AppMetaView> {
65
67
  return await nextclawClient.app.fetchMeta();
66
68
  }
67
69
 
68
- export async function fetchBootstrapStatus(): Promise<BootstrapStatusView> {
69
- return await nextclawClient.app.fetchBootstrapStatus();
70
+ export async function fetchBootstrapStatus(options: { timeoutMs?: number } = {}): Promise<BootstrapStatusView> {
71
+ return await nextclawClient.app.fetchBootstrapStatus(options);
70
72
  }
71
73
 
72
74
  export async function fetchConfig(): Promise<ConfigView> {
@@ -75,7 +75,6 @@ export const DESKTOP_UPDATE_LABELS: Record<string, { zh: string; en: string }> =
75
75
  desktopUpdatesInlineDownloadingPercent: { zh: '下载 {percent}%', en: '{percent}%' },
76
76
  desktopUpdatesInlineReady: { zh: '更新', en: 'Update' },
77
77
  desktopUpdatesInlineApplying: { zh: '应用中', en: 'Applying' },
78
- desktopUpdatesInlineAttention: { zh: '更新异常', en: 'Update Issue' },
79
78
  desktopUpdatesLauncherVersion: { zh: '桌面壳版本', en: 'Launcher Version' },
80
79
  desktopUpdatesCurrentBundleVersion: { zh: '当前内核版本', en: 'Current Kernel Version' },
81
80
  desktopUpdatesAvailableVersion: { zh: '可用版本', en: 'Available Version' },
@@ -102,6 +101,9 @@ export const DESKTOP_UPDATE_LABELS: Record<string, { zh: string; en: string }> =
102
101
  zh: '当前安装环境需要先处理阻塞项,之后才能继续更新。',
103
102
  en: 'Resolve the current installation requirement before continuing the update.'
104
103
  },
104
+ 'desktopUpdatesBlockedRootCause.signature-verification-unavailable': { zh: '根因:缺少更新签名公钥,无法验证更新包来源;请安装包含正确更新配置的新版本,或由维护者配置更新公钥。', en: 'Root cause: missing update public key; install a configured build or ask the maintainer to set the key.' },
105
+ 'desktopUpdatesBlockedRootCause.host-too-old': { zh: '根因:当前宿主版本太旧,不满足新运行包的最低宿主版本要求;请先升级 NextClaw 启动器。', en: 'Root cause: the host is too old for this runtime bundle; upgrade the NextClaw launcher first.' },
106
+ 'desktopUpdatesBlockedRootCause.unsupported-installation': { zh: '根因:当前安装形态或更新源配置不支持自动更新;请安装支持自动更新的版本,或由维护者补齐更新源配置。', en: 'Root cause: this installation or update source does not support auto-update; use a configured build.' },
105
107
  desktopUpdatesPreferencesTitle: { zh: '更新偏好', en: 'Update Preferences' },
106
108
  desktopUpdatesPreferencesDescription: {
107
109
  zh: '默认自动检查更新,但是否后台下载由你决定。',
@@ -1,5 +1,6 @@
1
1
  export { appClient } from './app-client.service';
2
2
  export { requestRawApiResponse } from './request-raw-api-response.utils';
3
+ export { isTransientRuntimeConnectionErrorMessage } from './transport.types';
3
4
  export type {
4
5
  AppEvent,
5
6
  AppTransport,
@@ -46,3 +46,23 @@ export type RemoteRuntimeInfo = {
46
46
  protocolVersion: 1;
47
47
  wsPath: string;
48
48
  };
49
+
50
+ export function isTransientRuntimeConnectionErrorMessage(message: string): boolean {
51
+ const normalized = message.trim().toLowerCase();
52
+ if (!normalized) {
53
+ return false;
54
+ }
55
+ return [
56
+ 'failed to fetch',
57
+ 'networkerror',
58
+ 'network request failed',
59
+ 'load failed',
60
+ 'request timed out',
61
+ 'timed out waiting for remote request response',
62
+ 'remote transport connection closed',
63
+ 'websocket error',
64
+ 'fetch failed on ',
65
+ 'stream request failed for ',
66
+ 'ncp fetch failed for ',
67
+ ].some((snippet) => normalized.includes(snippet));
68
+ }
@@ -1 +0,0 @@
1
- import{_ as e,i as t,m as n,n as r,p as i}from"./i18n-C5Mibli1.js";import{At as a,Ct as o,Dt as s,Et as c,It as l,Mt as u,Ot as d,Pt as f,Rt as p,Tt as m,a as h,bt as g,c as _,i as ee,jt as v,kt as y,l as te,o as ne,r as b,s as re,u as x,ut as S,wt as C}from"./api-lwyw9j7i.js";import{a as ie,n as ae,o as oe,r as se,t as w}from"./dialog-CdtCU2xX.js";import{t as T}from"./createLucideIcon-BZkY6emz.js";import{t as ce}from"./key-round-CnI1mc9F.js";import{t as E}from"./refresh-ccw-Bii4w8aB.js";import{t as D}from"./notice-card-BPtCVEKW.js";import{t as O}from"./status-dot-Dv_hiUVa.js";var k=T(`Laptop`,[[`path`,{d:`M20 16V7a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v9m16 0H4m16 0 1.28 2.55a1 1 0 0 1-.9 1.45H3.62a1 1 0 0 1-.9-1.45L4 16`,key:`tarvll`}]]),A=T(`LogOut`,[[`path`,{d:`M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4`,key:`1uf3rs`}],[`polyline`,{points:`16 17 21 12 16 7`,key:`1gabdz`}],[`line`,{x1:`21`,x2:`9`,y1:`12`,y2:`12`,key:`1uyos4`}]]),j=T(`SquareArrowOutUpRight`,[[`path`,{d:`M21 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h6`,key:`y09zxi`}],[`path`,{d:`m21 3-9 9`,key:`mpx6sq`}],[`path`,{d:`M15 3h6v6`,key:`1q9fwt`}]]);function M(){return p({queryKey:I,queryFn:h,staleTime:5e3,refetchOnWindowFocus:!0})}var N=e(n(),1),P=i();function F(e){let{label:t,muted:n,value:r}=e;return(0,P.jsxs)(`div`,{className:`flex items-start justify-between gap-4 py-2 text-sm`,children:[(0,P.jsx)(`span`,{className:`text-gray-500`,children:t}),(0,P.jsx)(`span`,{className:n?`text-right text-gray-500`:`text-right text-gray-900`,children:r==null||r===``?`-`:String(r)})]})}function le(){let e=$(),n=M(),i=n.data,a=U(e=>e.actionLabel),l=(0,N.useMemo)(()=>q(i),[i]),f=!!a,p=i?.runtime?.deviceName?.trim()||i?.settings.deviceName?.trim()||t(`remoteDeviceNameAuto`),h=!!(i?.account.loggedIn&&H(i)),{hero:g,issueHint:_}=l;return(0,N.useEffect)(()=>{e.remoteAccessManager.syncStatus(i)},[e,i]),n.isLoading&&!i?(0,P.jsx)(`div`,{className:`p-8 text-gray-400`,children:t(`remoteLoading`)}):(0,P.jsxs)(y,{className:`space-y-6`,children:[(0,P.jsx)(d,{title:t(`remotePageTitle`),description:t(`remotePageDescription`)}),(0,P.jsxs)(`div`,{className:`grid gap-6 xl:grid-cols-[1.2fr_0.8fr]`,children:[(0,P.jsxs)(o,{children:[(0,P.jsxs)(c,{className:`space-y-4`,children:[(0,P.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[(0,P.jsx)(s,{children:g.title}),(0,P.jsx)(O,{status:g.badgeStatus,label:g.badgeLabel})]}),(0,P.jsx)(m,{children:g.description})]}),(0,P.jsxs)(C,{className:`space-y-5`,children:[(0,P.jsxs)(D,{tone:`neutral`,children:[(0,P.jsx)(F,{label:t(`remoteSignedInAccount`),value:i?.account.email}),(0,P.jsx)(F,{label:t(`remoteDeviceName`),value:p}),(0,P.jsx)(F,{label:t(`remoteConnectionStatus`),value:g.badgeLabel}),(0,P.jsx)(F,{label:t(`remoteLastConnectedAt`),value:i?.runtime?.lastConnectedAt?r(i.runtime.lastConnectedAt):`-`,muted:!0})]}),(0,P.jsxs)(`div`,{className:`flex flex-wrap gap-3`,children:[l.primaryAction?(0,P.jsxs)(u,{onClick:()=>{if(l.primaryAction?.kind===`reauthorize`){e.remoteAccessManager.reauthorizeRemoteAccess(i);return}if(l.primaryAction?.kind===`repair`){e.remoteAccessManager.repairRemoteAccess(i);return}e.remoteAccessManager.enableRemoteAccess(i)},disabled:f,children:[l.primaryAction.showRefreshIcon?(0,P.jsx)(E,{className:`mr-2 h-4 w-4`}):null,a||l.primaryAction.label]}):null,(0,P.jsxs)(u,{variant:`outline`,onClick:()=>void e.accountManager.openNextClawWeb(),disabled:f||!h,children:[(0,P.jsx)(j,{className:`mr-2 h-4 w-4`}),t(`remoteOpenDeviceList`)]}),i?.settings.enabled?(0,P.jsx)(u,{variant:`outline`,onClick:()=>void e.remoteAccessManager.disableRemoteAccess(i),disabled:f,children:t(`remoteDisable`)}):null]}),l.shouldShowIssueHint&&_?(0,P.jsx)(D,{tone:`warning`,title:_.title,description:_.body}):null,(0,P.jsx)(`p`,{className:`text-xs text-gray-500`,children:t(`remoteOpenWebHint`)})]})]}),(0,P.jsxs)(o,{children:[(0,P.jsxs)(c,{children:[(0,P.jsxs)(s,{className:`flex items-center gap-2`,children:[(0,P.jsx)(k,{className:`h-4 w-4 text-primary`}),t(`remoteDeviceSectionTitle`)]}),(0,P.jsx)(m,{children:t(`remoteDeviceSectionDescription`)})]}),(0,P.jsxs)(C,{className:`space-y-5`,children:[(0,P.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,P.jsx)(O,{status:i?.account.loggedIn?`ready`:`inactive`,label:i?.account.loggedIn?t(`remoteAccountConnected`):t(`remoteAccountNotConnected`)}),(0,P.jsx)(O,{status:i?.settings.enabled?`active`:`inactive`,label:i?.settings.enabled?t(`remoteEnabled`):t(`remoteStateDisabled`)}),(0,P.jsx)(O,{status:i?.service.running?`active`:`inactive`,label:i?.service.running?t(`remoteServiceRunning`):t(`remoteServiceStopped`)})]}),(0,P.jsxs)(D,{tone:`neutral`,children:[(0,P.jsx)(F,{label:t(`remoteDeviceName`),value:p}),(0,P.jsx)(F,{label:t(`remoteConnectionStatus`),value:g.badgeLabel}),(0,P.jsx)(F,{label:t(`remoteLastConnectedAt`),value:i?.runtime?.lastConnectedAt?r(i.runtime.lastConnectedAt):`-`,muted:!0})]}),(0,P.jsx)(D,{tone:`neutral`,borderStyle:`dashed`,description:i?.account.loggedIn?t(`remoteOpenWebHint`):t(`remoteStatusNeedsSignInDescription`),className:`text-sm`})]})]})]})]})}var I=[`remote-status`],ue=`https://platform.nextclaw.io`,L=`https://nextclaw-platform-console.pages.dev`,R=async()=>await f.fetchQuery({queryKey:I,queryFn:h,staleTime:5e3}),z=async()=>(await f.invalidateQueries({queryKey:I}),await R()),B=(e,t)=>t?.trim()||e?.settings.platformApiBase?.trim()||e?.account.apiBase?.trim()||void 0;function V(e){let t=e?.trim();if(!t)return;let n;try{n=new URL(t)}catch{return}if(n.hostname===`platform.nextclaw.io`||n.hostname===`nextclaw-platform-console.pages.dev`)return n.origin;if(n.hostname===`ai-gateway-api.nextclaw.io`)return ue;if(n.hostname.includes(`nextclaw-provider-gateway-api`)&&n.hostname.endsWith(`.workers.dev`))return L}var H=e=>V(e?.account.apiBase)||V(e?.settings.platformApiBase)||V(e?.platformBase)||V(e?.account.platformBase)||void 0,U=g(e=>({enabled:!1,deviceName:``,platformApiBase:``,advancedOpen:!1,draftTouched:!1,actionLabel:null,doctor:null,setEnabled:t=>e({enabled:t,draftTouched:!0}),setDeviceName:t=>e({deviceName:t,draftTouched:!0}),setPlatformApiBase:t=>e({platformApiBase:t,draftTouched:!0}),setAdvancedOpen:t=>e({advancedOpen:t}),hydrateDraft:({enabled:t,deviceName:n,platformApiBase:r})=>e({enabled:t,deviceName:n,platformApiBase:r,draftTouched:!1}),beginAction:t=>e({actionLabel:t}),finishAction:()=>e({actionLabel:null}),setDoctor:t=>e({doctor:t})})),W=class{constructor(){this.accountManager=null,this.bindAccountManager=e=>{this.accountManager=e},this.syncStatus=e=>{if(!e)return;let t=U.getState();t.draftTouched||t.actionLabel||this.hydrateDraftFromStatus(e)},this.setEnabled=e=>{U.getState().setEnabled(e)},this.setDeviceName=e=>{U.getState().setDeviceName(e)},this.setPlatformApiBase=e=>{U.getState().setPlatformApiBase(e)},this.setAdvancedOpen=e=>{U.getState().setAdvancedOpen(e)},this.enableRemoteAccess=async e=>{let t=e??await z(),n=U.getState();if(!t.account.loggedIn){await this.accountManager?.ensureSignedIn({pendingAction:{type:`enable-remote`},apiBase:n.platformApiBase});return}await this.applyEnabledState(!0,t)},this.disableRemoteAccess=async e=>{let t=e??await z();await this.applyEnabledState(!1,t)},this.repairRemoteAccess=async e=>{let n=e??await z();if(!n.account.loggedIn){await this.accountManager?.ensureSignedIn({pendingAction:{type:`enable-remote`}});return}let r=n.service.running?`restart`:`start`;await this.runManagedAction({actionLabel:t(r===`restart`?`remoteActionRestarting`:`remoteActionStarting`),job:async()=>{await b(r);let e=await z();this.hydrateDraftFromStatus(e)},successMessage:t(`remoteServiceRecovered`)})},this.reauthorizeRemoteAccess=async e=>{let t=e??await z();await this.accountManager?.startBrowserSignIn({status:t,apiBase:U.getState().platformApiBase,pendingAction:{type:`repair-remote`}})},this.saveAdvancedSettings=async e=>{let n=e??await z(),r=U.getState();await this.runManagedAction({actionLabel:t(`remoteActionSavingAdvanced`),job:async()=>{await x({enabled:r.enabled,deviceName:r.deviceName.trim(),platformApiBase:r.platformApiBase.trim()});let e=await z();this.hydrateDraftFromStatus(e)},successMessage:n.settings.enabled===r.enabled?t(`remoteSettingsSaved`):t(`remoteAdvancedSaved`)})},this.runDoctor=async()=>{await this.runManagedAction({actionLabel:t(`remoteDoctorRunning`),job:async()=>{let e=await ee();U.getState().setDoctor(e)},successMessage:t(`remoteDoctorCompleted`)})},this.startService=async()=>{await this.runServiceAction(`start`,t(`remoteActionStarting`))},this.restartService=async()=>{await this.runServiceAction(`restart`,t(`remoteActionRestarting`))},this.stopService=async()=>{await this.runServiceAction(`stop`,t(`remoteActionStopping`))},this.resumePendingActionAfterSignIn=async(e,t)=>{if(e){if(e.type===`enable-remote`){await this.applyEnabledState(!0,t);return}e.type===`repair-remote`&&await this.repairRemoteAccess(t)}},this.applyEnabledState=async(e,n)=>{let r=U.getState();await this.runManagedAction({actionLabel:t(e?`remoteActionEnabling`:`remoteActionDisabling`),job:async()=>{await x({enabled:e,deviceName:r.deviceName.trim(),platformApiBase:r.platformApiBase.trim()});let t=await z();this.hydrateDraftFromStatus(t),e?await b(t.service.running?`restart`:`start`):n.service.running&&await b(`restart`);let i=await z();this.hydrateDraftFromStatus(i)},successMessage:t(e?`remoteEnabledReady`:`remoteDisabledDone`)})},this.runServiceAction=async(e,t)=>{await this.runManagedAction({actionLabel:t,job:async()=>{let t=await b(e),n=await z();this.hydrateDraftFromStatus(n),l.success(t.message)}})},this.hydrateDraftFromStatus=e=>{U.getState().hydrateDraft({enabled:e.settings.enabled,deviceName:e.settings.deviceName,platformApiBase:e.settings.platformApiBase})},this.runManagedAction=async e=>{U.getState().beginAction(e.actionLabel);try{await e.job(),e.successMessage&&l.success(e.successMessage)}catch(e){let n=e instanceof Error?e.message:t(`error`);throw l.error(n),e}finally{U.getState().finishAction()}}}},de=[/invalid or expired token/i,/missing bearer token/i,/token expired/i,/token is invalid/i,/run "nextclaw login"/i,/browser sign-in again/i];function G(e){return e?.runtime?.lastError?.trim()||``}function fe(e){let n=t(`remoteStatusIssueDetailGeneric`),r=G(e);return r?`${n} (${r})`:n}function K(e){if(!e?.settings.enabled)return!1;let t=G(e);return de.some(e=>e.test(t))}function q(e){return K(e)?{hero:{badgeStatus:`warning`,badgeLabel:t(`remoteStateReauthorizationRequired`),title:t(`remoteStatusReauthorizationTitle`),description:t(`remoteStatusReauthorizationDescription`)},primaryAction:{kind:`reauthorize`,label:t(`remoteReauthorizeNow`),showRefreshIcon:!1},issueHint:{title:t(`remoteStatusRecoveryTitle`),body:t(`remoteStatusReauthorizationHint`)},shouldShowIssueHint:!0,requiresReauthorization:!0}:e?.account.loggedIn?e.settings.enabled?e.service.running?e.runtime?.state===`connected`?{hero:{badgeStatus:`ready`,badgeLabel:t(`statusReady`),title:t(`remoteStatusReadyTitle`),description:t(`remoteStatusReadyDescription`)},primaryAction:{kind:`repair`,label:t(`remoteReconnectNow`),showRefreshIcon:!0},issueHint:null,shouldShowIssueHint:!1,requiresReauthorization:!1}:e.runtime?.state===`connecting`?{hero:{badgeStatus:`active`,badgeLabel:t(`connecting`),title:t(`remoteStatusConnectingTitle`),description:t(`remoteStatusConnectingDescription`)},primaryAction:{kind:`repair`,label:t(`remoteReconnectNow`),showRefreshIcon:!0},issueHint:null,shouldShowIssueHint:!1,requiresReauthorization:!1}:{hero:{badgeStatus:`warning`,badgeLabel:t(`remoteStateDisconnected`),title:t(`remoteStatusIssueTitle`),description:t(`remoteStatusIssueDescription`)},primaryAction:{kind:`repair`,label:t(`remoteReconnectNow`),showRefreshIcon:!0},issueHint:{title:t(`remoteStatusRecoveryTitle`),body:fe(e)},shouldShowIssueHint:!!(e.settings.enabled&&e.account.loggedIn),requiresReauthorization:!1}:{hero:{badgeStatus:`warning`,badgeLabel:t(`remoteServiceStopped`),title:t(`remoteStatusNeedsServiceTitle`),description:t(`remoteStatusNeedsServiceDescription`)},primaryAction:{kind:`repair`,label:t(`remoteReconnectNow`),showRefreshIcon:!0},issueHint:{title:t(`remoteStatusRecoveryTitle`),body:t(`remoteStatusIssueDetailServiceStopped`)},shouldShowIssueHint:!0,requiresReauthorization:!1}:{hero:{badgeStatus:`inactive`,badgeLabel:t(`statusInactive`),title:t(`remoteStatusNeedsEnable`),description:t(`remoteStatusNeedsEnableDescription`)},primaryAction:{kind:`enable`,label:t(`remoteEnableNow`),showRefreshIcon:!1},issueHint:null,shouldShowIssueHint:!1,requiresReauthorization:!1}:{hero:{badgeStatus:`setup`,badgeLabel:t(`statusSetup`),title:t(`remoteStatusNeedsSignIn`),description:t(`remoteStatusNeedsSignInDescription`)},primaryAction:{kind:`sign-in-enable`,label:t(`remoteSignInAndEnable`),showRefreshIcon:!1},issueHint:null,shouldShowIssueHint:!1,requiresReauthorization:!1}}var J=g(e=>({panelOpen:!1,authSessionId:null,authVerificationUri:null,authExpiresAt:null,authStatusMessage:``,authPollIntervalMs:1500,pendingAction:null,openPanel:()=>e({panelOpen:!0}),closePanel:()=>e({panelOpen:!1}),setPendingAction:t=>e({pendingAction:t}),clearPendingAction:()=>e({pendingAction:null}),beginBrowserAuth:({sessionId:t,verificationUri:n,expiresAt:r,intervalMs:i,statusMessage:a})=>e({panelOpen:!0,authSessionId:t,authVerificationUri:n,authExpiresAt:r,authPollIntervalMs:i,authStatusMessage:a}),updateBrowserAuth:({statusMessage:t,intervalMs:n})=>e(e=>({authStatusMessage:t??e.authStatusMessage,authPollIntervalMs:n??e.authPollIntervalMs})),clearBrowserAuth:()=>e({authSessionId:null,authVerificationUri:null,authExpiresAt:null,authStatusMessage:``,authPollIntervalMs:1500}),setAuthStatusMessage:t=>e({authStatusMessage:t})}));function Y({label:e,value:t}){return(0,P.jsxs)(`div`,{className:`flex items-start justify-between gap-4 py-2 text-sm`,children:[(0,P.jsx)(`span`,{className:`text-gray-500`,children:e}),(0,P.jsx)(`span`,{className:`text-right text-gray-900`,children:t?.trim()||`-`})]})}function pe(e){let{email:n,username:r,role:i,canSubmitUsername:o,savingUsername:s,usernameDraft:c,onUsernameDraftChange:l,onSubmitUsername:d,onOpenDeviceList:f,onLogout:p}=e;return(0,P.jsxs)(`div`,{className:`space-y-4`,children:[(0,P.jsx)(D,{tone:`success`,title:t(`accountPanelSignedInTitle`),description:t(`accountPanelSignedInDescription`)}),(0,P.jsxs)(D,{tone:`neutral`,children:[(0,P.jsx)(Y,{label:t(`remoteAccountEmail`),value:n}),(0,P.jsx)(Y,{label:t(`remoteAccountUsername`),value:r}),(0,P.jsx)(Y,{label:t(`remoteAccountRole`),value:i})]}),r?(0,P.jsx)(`p`,{className:`text-xs text-gray-500`,children:t(`remoteAccountUsernameLockedHelp`)}):(0,P.jsxs)(D,{tone:`warning`,title:t(`remoteAccountUsernameRequiredTitle`),description:t(`remoteAccountUsernameRequiredDescription`),children:[(0,P.jsxs)(`div`,{className:`mt-4 space-y-2`,children:[(0,P.jsx)(a,{htmlFor:`account-panel-username`,children:t(`remoteAccountUsername`)}),(0,P.jsx)(v,{id:`account-panel-username`,value:c,onChange:e=>l(e.target.value),placeholder:t(`remoteAccountUsernamePlaceholder`),autoCapitalize:`none`,autoCorrect:`off`,spellCheck:!1})]}),(0,P.jsx)(`div`,{className:`mt-4 flex flex-wrap gap-3`,children:(0,P.jsx)(u,{disabled:!o,onClick:()=>void d(),children:t(s?`remoteAccountUsernameSaving`:`remoteAccountUsernameSave`)})})]}),(0,P.jsxs)(`div`,{className:`flex flex-wrap gap-3`,children:[(0,P.jsxs)(u,{onClick:()=>void f(),children:[(0,P.jsx)(j,{className:`mr-2 h-4 w-4`}),t(`remoteOpenDeviceList`)]}),(0,P.jsxs)(u,{variant:`outline`,onClick:()=>void p(),children:[(0,P.jsx)(A,{className:`mr-2 h-4 w-4`}),t(`remoteLogout`)]})]})]})}function me(e){let{authSessionId:n,authExpiresAt:i,authStatusMessage:a,authVerificationUri:o,onStartBrowserSignIn:s,onResumeBrowserSignIn:c}=e;return(0,P.jsxs)(`div`,{className:`space-y-4`,children:[(0,P.jsx)(D,{tone:`neutral`,title:t(`accountPanelSignedOutTitle`),description:t(`accountPanelSignedOutDescription`),children:n?(0,P.jsxs)(`div`,{className:`mt-3 border-t border-white/80 pt-3`,children:[(0,P.jsx)(Y,{label:t(`remoteBrowserAuthSession`),value:n}),(0,P.jsx)(Y,{label:t(`remoteBrowserAuthExpiresAt`),value:i?r(i):`-`})]}):null}),a?(0,P.jsx)(`p`,{className:`text-sm text-gray-600`,children:a}):null,(0,P.jsxs)(`div`,{className:`flex flex-wrap gap-3`,children:[(0,P.jsx)(u,{onClick:()=>void s(),children:t(n?`remoteBrowserAuthActionRetry`:`remoteBrowserAuthAction`)}),o?(0,P.jsx)(u,{variant:`outline`,onClick:c,children:t(`remoteBrowserAuthResume`)}):null]})]})}function he(){let e=$(),n=M(),r=J(e=>e.panelOpen),i=J(e=>e.authSessionId),a=J(e=>e.authVerificationUri),o=J(e=>e.authExpiresAt),s=J(e=>e.authStatusMessage),c=n.data,[l,u]=(0,N.useState)(``),[d,f]=(0,N.useState)(!1);(0,N.useEffect)(()=>{e.accountManager.syncRemoteStatus(c)},[e,c]);let p=!d&&l.trim().length>0&&!c?.account.username;return(0,P.jsx)(w,{open:r,onOpenChange:t=>t?e.accountManager.openAccountPanel():e.accountManager.closeAccountPanel(),children:(0,P.jsxs)(ae,{className:`max-w-xl`,children:[(0,P.jsxs)(ie,{children:[(0,P.jsxs)(oe,{className:`flex items-center gap-2`,children:[(0,P.jsx)(ce,{className:`h-5 w-5 text-primary`}),t(`accountPanelTitle`)]}),(0,P.jsx)(se,{children:t(`accountPanelDescription`)})]}),c?.account.loggedIn?(0,P.jsx)(pe,{email:c.account.email,username:c.account.username,role:c.account.role,canSubmitUsername:p,savingUsername:d,usernameDraft:l,onUsernameDraftChange:u,onSubmitUsername:async()=>{f(!0);try{await e.accountManager.updateUsername(l)}finally{f(!1)}},onOpenDeviceList:()=>e.accountManager.openNextClawWeb(`/account`),onLogout:()=>e.accountManager.logout()}):(0,P.jsx)(me,{authSessionId:i,authExpiresAt:o,authStatusMessage:s,authVerificationUri:a,onStartBrowserSignIn:()=>e.accountManager.startBrowserSignIn(),onResumeBrowserSignIn:()=>e.accountManager.resumeBrowserSignIn()})]})})}function X({username:e}){let n=S(),[r,i]=(0,N.useState)(e??``),[a,l]=(0,N.useState)(``),d=r.trim().length>0&&a.length>0&&!n.isPending;return(0,P.jsx)(`main`,{className:`flex min-h-screen items-center justify-center bg-secondary px-6 py-10`,children:(0,P.jsxs)(o,{hover:!1,className:`w-full max-w-md shadow-card-hover`,children:[(0,P.jsxs)(c,{children:[(0,P.jsx)(`p`,{className:`text-xs font-semibold uppercase tracking-[0.24em] text-gray-500`,children:t(`authBrand`)}),(0,P.jsx)(s,{className:`text-2xl`,children:t(`authLoginTitle`)}),(0,P.jsx)(m,{children:t(`authLoginDescription`)})]}),(0,P.jsx)(C,{children:(0,P.jsxs)(`form`,{className:`space-y-4`,onSubmit:e=>{e?.preventDefault(),d&&n.mutate({username:r.trim(),password:a})},children:[(0,P.jsxs)(`div`,{className:`space-y-2`,children:[(0,P.jsx)(`label`,{className:`text-sm font-medium text-gray-800`,children:t(`authUsername`)}),(0,P.jsx)(v,{value:r,onChange:e=>i(e.target.value),placeholder:t(`authUsernamePlaceholder`),autoFocus:!0})]}),(0,P.jsxs)(`div`,{className:`space-y-2`,children:[(0,P.jsx)(`label`,{className:`text-sm font-medium text-gray-800`,children:t(`authPassword`)}),(0,P.jsx)(v,{type:`password`,value:a,onChange:e=>l(e.target.value),placeholder:t(`authPasswordPlaceholder`)})]}),(0,P.jsx)(u,{type:`submit`,className:`w-full`,disabled:!d,children:n.isPending?t(`authLoggingIn`):t(`authLoginAction`)})]})})]})})}var ge=class{constructor(){this.authPollTimerId=null,this.afterSignedIn=null,this.bindSignedInContinuation=e=>{this.afterSignedIn=e},this.openAccountPanel=()=>{J.getState().openPanel()},this.closeAccountPanel=()=>{J.getState().closePanel()},this.syncRemoteStatus=e=>{e?.account.loggedIn&&(this.clearPollTimer(),J.getState().clearBrowserAuth())},this.ensureSignedIn=async e=>{let t=await R();return t.account.loggedIn?!0:(e?.pendingAction&&J.getState().setPendingAction(e.pendingAction),this.openAccountPanel(),await this.startBrowserSignIn({apiBase:e?.apiBase,status:t}),!1)},this.startBrowserSignIn=async e=>{try{let n=e?.apiBase,r=e?.pendingAction,i=e?.status??await R();r&&J.getState().setPendingAction(r);let a=await _({apiBase:B(i,n)});J.getState().beginBrowserAuth({sessionId:a.sessionId,verificationUri:a.verificationUri,expiresAt:a.expiresAt,intervalMs:a.intervalMs,statusMessage:t(`remoteBrowserAuthWaiting`)}),window.open(a.verificationUri,`_blank`,`noopener,noreferrer`)||J.getState().setAuthStatusMessage(t(`remoteBrowserAuthPopupBlocked`)),this.scheduleBrowserAuthPoll()}catch(e){let n=e instanceof Error?e.message:t(`remoteBrowserAuthStartFailed`);l.error(`${t(`remoteBrowserAuthStartFailed`)}: ${n}`)}},this.resumeBrowserSignIn=()=>{let e=J.getState().authVerificationUri;e&&window.open(e,`_blank`,`noopener,noreferrer`)},this.logout=async()=>{try{await ne(),J.getState().clearPendingAction(),J.getState().clearBrowserAuth(),await z(),l.success(t(`remoteLogoutSuccess`))}catch(e){let n=e instanceof Error?e.message:t(`remoteLogoutFailed`);l.error(`${t(`remoteLogoutFailed`)}: ${n}`)}},this.updateUsername=async e=>{try{await te({username:e.trim()}),await z(),l.success(t(`remoteAccountUsernameSetSuccess`))}catch(e){let n=e instanceof Error?e.message:t(`remoteAccountUsernameSetFailed`);l.error(`${t(`remoteAccountUsernameSetFailed`)}: ${n}`)}},this.openNextClawWeb=async(e=`/`)=>{let n=H(await R());if(!n){l.error(t(`remoteOpenWebUnavailable`));return}let r=new URL(e,`${n.replace(/\/+$/,``)}/`).toString();window.open(r,`_blank`,`noopener,noreferrer`)},this.scheduleBrowserAuthPoll=()=>{this.clearPollTimer();let{authSessionId:e,authPollIntervalMs:t}=J.getState();e&&(this.authPollTimerId=window.setTimeout(async()=>{await this.pollBrowserSignIn()},t))},this.pollBrowserSignIn=async()=>{let e=J.getState();if(e.authSessionId)try{let n=await R(),r=await re({sessionId:e.authSessionId,apiBase:B(n)});if(r.status===`pending`){J.getState().updateBrowserAuth({statusMessage:t(`remoteBrowserAuthWaiting`),intervalMs:r.nextPollMs??1500}),this.scheduleBrowserAuthPoll();return}if(r.status===`expired`){this.clearPollTimer(),J.getState().clearBrowserAuth(),l.error(r.message||t(`remoteBrowserAuthExpired`));return}J.getState().setAuthStatusMessage(t(`remoteBrowserAuthCompleted`));let i=await z(),{pendingAction:a}=J.getState();this.clearPollTimer(),J.getState().clearBrowserAuth(),l.success(t(`remoteLoginSuccess`)),a&&this.afterSignedIn&&await this.afterSignedIn(a,i),J.getState().clearPendingAction()}catch(e){this.clearPollTimer(),J.getState().clearBrowserAuth();let n=e instanceof Error?e.message:t(`remoteBrowserAuthPollFailed`);l.error(`${t(`remoteBrowserAuthPollFailed`)}: ${n}`)}},this.clearPollTimer=()=>{this.authPollTimerId!==null&&(window.clearTimeout(this.authPollTimerId),this.authPollTimerId=null)},this.getBrowserAuthSummary=()=>{let e=J.getState();return{sessionId:e.authSessionId,expiresAt:e.authExpiresAt?r(e.authExpiresAt):`-`}}}},Z=new class{constructor(){this.accountManager=new ge,this.remoteAccessManager=new W}};Z.accountManager.bindSignedInContinuation(Z.remoteAccessManager.resumePendingActionAfterSignIn),Z.remoteAccessManager.bindAccountManager(Z.accountManager);var Q=(0,N.createContext)(null);function _e({children:e}){return(0,P.jsx)(Q.Provider,{value:Z,children:e})}function $(){let e=(0,N.useContext)(Q);if(!e)throw Error(`useAppManager must be used inside AppManagerProvider`);return e}export{q as a,U as c,z as d,B as f,M as h,he as i,I as l,le as m,$ as n,K as o,H as p,X as r,W as s,_e as t,R as u};
@@ -1 +0,0 @@
1
- import{t as e}from"./doc-browser-CzCV73NJ.js";export{e as DocBrowser};