@rubytech/create-realagent-code 0.1.506 → 0.1.507

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 (106) hide show
  1. package/package.json +2 -2
  2. package/payload/platform/config/brand.json +92 -32
  3. package/payload/platform/lib/account-schema-regions/dist/index.d.ts +17 -5
  4. package/payload/platform/lib/account-schema-regions/dist/index.d.ts.map +1 -1
  5. package/payload/platform/lib/account-schema-regions/dist/index.js +20 -6
  6. package/payload/platform/lib/account-schema-regions/dist/index.js.map +1 -1
  7. package/payload/platform/lib/account-schema-regions/src/index.ts +20 -6
  8. package/payload/platform/plugins/admin/PLUGIN.md +36 -0
  9. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +48 -2
  10. package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +7 -0
  11. package/payload/platform/plugins/aeo/PLUGIN.md +3 -0
  12. package/payload/platform/plugins/browser/PLUGIN.md +18 -0
  13. package/payload/platform/plugins/connector/PLUGIN.md +4 -0
  14. package/payload/platform/plugins/contacts/PLUGIN.md +9 -0
  15. package/payload/platform/plugins/docs/references/admin-ui.md +21 -1
  16. package/payload/platform/plugins/docs/references/plugins-guide.md +26 -0
  17. package/payload/platform/plugins/email/PLUGIN.md +17 -0
  18. package/payload/platform/plugins/filesystem/PLUGIN.md +6 -0
  19. package/payload/platform/plugins/google/PLUGIN.md +12 -0
  20. package/payload/platform/plugins/graph/PLUGIN.md +3 -0
  21. package/payload/platform/plugins/graph-viewer/PLUGIN.md +1 -0
  22. package/payload/platform/plugins/ledger/PLUGIN.md +7 -0
  23. package/payload/platform/plugins/memory/PLUGIN.md +41 -0
  24. package/payload/platform/plugins/outlook/PLUGIN.md +24 -0
  25. package/payload/platform/plugins/quickbooks/PLUGIN.md +15 -0
  26. package/payload/platform/plugins/replicate/PLUGIN.md +3 -0
  27. package/payload/platform/plugins/scheduling/PLUGIN.md +10 -0
  28. package/payload/platform/plugins/storage-broker/PLUGIN.md +12 -0
  29. package/payload/platform/plugins/url-get/PLUGIN.md +1 -0
  30. package/payload/platform/plugins/voice-mirror/PLUGIN.md +5 -0
  31. package/payload/platform/plugins/whatsapp/PLUGIN.md +12 -0
  32. package/payload/platform/plugins/work/PLUGIN.md +15 -0
  33. package/payload/platform/plugins/workflows/PLUGIN.md +8 -0
  34. package/payload/platform/scripts/check-risk-class.mjs +145 -0
  35. package/payload/platform/scripts/lib/__pycache__/account-schema-owned-dirs.cpython-314.pyc +0 -0
  36. package/payload/platform/scripts/lib/provision-account-dir.sh +4 -1
  37. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  38. package/payload/platform/services/claude-session-manager/dist/http-server.js +4 -0
  39. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  40. package/payload/platform/services/claude-session-manager/dist/index.js +8 -0
  41. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  42. package/payload/platform/services/claude-session-manager/dist/tool-surface.d.ts +13 -0
  43. package/payload/platform/services/claude-session-manager/dist/tool-surface.d.ts.map +1 -1
  44. package/payload/platform/services/claude-session-manager/dist/tool-surface.js +33 -8
  45. package/payload/platform/services/claude-session-manager/dist/tool-surface.js.map +1 -1
  46. package/payload/premium-plugins/real-agent/plugins/buyers/PLUGIN.md +8 -0
  47. package/payload/premium-plugins/real-agent/plugins/estate-sales/PLUGIN.md +5 -0
  48. package/payload/premium-plugins/real-agent/plugins/loop/PLUGIN.md +27 -0
  49. package/payload/premium-plugins/real-agent/plugins/property-data/PLUGIN.md +22 -0
  50. package/payload/server/{chunk-5ADBNEJA.js → chunk-2WAXM5N2.js} +111 -111
  51. package/payload/server/maxy-edge.js +1 -1
  52. package/payload/server/public/activity.html +5 -5
  53. package/payload/server/public/agents.html +4 -4
  54. package/payload/server/public/assets/{AdminLoginScreens-D5KOQA8S.js → AdminLoginScreens-YT7jsh_H.js} +1 -1
  55. package/payload/server/public/assets/{AdminShell-C8wazpnz.js → AdminShell-Ckht9hmU.js} +1 -1
  56. package/payload/server/public/assets/{activity-CFqkDhTs.js → activity-DH3Wgc3O.js} +1 -1
  57. package/payload/server/public/assets/admin-DetvulAu.js +1 -0
  58. package/payload/server/public/assets/{agents-DPulfmrd.js → agents-X_IvDHLZ.js} +1 -1
  59. package/payload/server/public/assets/{browser-T_5xbnJh.js → browser-Bym8QhfA.js} +1 -1
  60. package/payload/server/public/assets/{calendar-CKjuiG8c.js → calendar-CFnufJOy.js} +1 -1
  61. package/payload/server/public/assets/chat-wrckyIpw.js +1 -0
  62. package/payload/server/public/assets/chevron-left-Dtk3jEK5.js +1 -0
  63. package/payload/server/public/assets/chevron-right-Dih6IZ8B.js +1 -0
  64. package/payload/server/public/assets/clock-iJCrrmWM.js +1 -0
  65. package/payload/server/public/assets/data-D76--TYs.js +1 -0
  66. package/payload/server/public/assets/{file-text-c6cA4Evd.js → file-text-zch0E1GJ.js} +1 -1
  67. package/payload/server/public/assets/{graph-DIk-o45J.js → graph-BavHLzpV.js} +1 -1
  68. package/payload/server/public/assets/{graph-labels-5bjxhC_p.js → graph-labels-CBwh4g-6.js} +1 -1
  69. package/payload/server/public/assets/{maximize-2-BCQkFb1_.js → maximize-2-bTn_Ozpi.js} +1 -1
  70. package/payload/server/public/assets/{operator-0UnNo2ms.js → operator-a4IOwf62.js} +1 -1
  71. package/payload/server/public/assets/page-3T2mE63b.js +1 -0
  72. package/payload/server/public/assets/{page-HVtUfub2.js → page-D6M1CmPe.js} +4 -4
  73. package/payload/server/public/assets/{public-CKEYyIPn.js → public-B3y_YU1G.js} +1 -1
  74. package/payload/server/public/assets/{rotate-ccw-dTpO5dhL.js → rotate-ccw-BGvzNB1b.js} +1 -1
  75. package/payload/server/public/assets/{routines-C6P1-Dto.js → routines-C7Dr16am.js} +1 -1
  76. package/payload/server/public/assets/{skills-ClrpVqlz.js → skills-DFeb3XO3.js} +1 -1
  77. package/payload/server/public/assets/{tasks-C8SNhSFC.js → tasks-CSfnCKJe.js} +1 -1
  78. package/payload/server/public/assets/{time-entry-format-CCO6N6XZ.js → time-entry-format-BgZqOOqG.js} +1 -1
  79. package/payload/server/public/assets/{triangle-alert-CHjdKpag.js → triangle-alert-DBJ7xz_t.js} +1 -1
  80. package/payload/server/public/assets/{useCopyFeedback-BTUu3-l8.js → useCopyFeedback-BFOujMl-.js} +1 -1
  81. package/payload/server/public/assets/useSubAccountSwitcher-BkQ5tA8A.css +1 -0
  82. package/payload/server/public/assets/{useVoiceRecorder-BeNqxmm2.js → useVoiceRecorder-BP6CpYQD.js} +1 -1
  83. package/payload/server/public/assets/{wrench-CeNnc7oO.js → wrench-DdaRhfzS.js} +1 -1
  84. package/payload/server/public/brand/real-agent-mark.svg +23 -0
  85. package/payload/server/public/brand-defaults.css +55 -20
  86. package/payload/server/public/browser.html +4 -4
  87. package/payload/server/public/calendar.html +7 -7
  88. package/payload/server/public/chat.html +13 -13
  89. package/payload/server/public/data.html +11 -11
  90. package/payload/server/public/graph.html +9 -9
  91. package/payload/server/public/index.html +14 -14
  92. package/payload/server/public/operator.html +14 -14
  93. package/payload/server/public/public.html +13 -13
  94. package/payload/server/public/routines.html +6 -6
  95. package/payload/server/public/skills.html +5 -5
  96. package/payload/server/public/tasks.html +6 -6
  97. package/payload/server/server.js +702 -586
  98. package/payload/server/public/assets/admin-B-EGUWS4.js +0 -1
  99. package/payload/server/public/assets/chat-DWLYAA70.js +0 -1
  100. package/payload/server/public/assets/chevron-left-DBMCTKlT.js +0 -1
  101. package/payload/server/public/assets/chevron-right-SBAr6zzc.js +0 -1
  102. package/payload/server/public/assets/clock-kkzt7Scf.js +0 -1
  103. package/payload/server/public/assets/data-CV8N9qcy.js +0 -1
  104. package/payload/server/public/assets/page-JJa2xdzf.js +0 -1
  105. package/payload/server/public/assets/useSubAccountSwitcher-DyrH8DA8.css +0 -1
  106. /package/payload/server/public/assets/{useSubAccountSwitcher-DSW9vDi2.js → useSubAccountSwitcher-0PfRrN6i.js} +0 -0
@@ -5,69 +5,91 @@ tools:
5
5
  - name: property-data-key-register
6
6
  publicAllowlist: false
7
7
  adminAllowlist: false
8
+ riskClass: write_local
8
9
  - name: property-data-key-deregister
9
10
  publicAllowlist: false
10
11
  adminAllowlist: false
12
+ riskClass: write_local
11
13
  - name: property-data-key-list
12
14
  publicAllowlist: false
13
15
  adminAllowlist: false
16
+ riskClass: read
14
17
  - name: property-data-valuation-sale
15
18
  publicAllowlist: false
16
19
  adminAllowlist: false
20
+ riskClass: read
17
21
  - name: property-data-valuation-rent
18
22
  publicAllowlist: false
19
23
  adminAllowlist: false
24
+ riskClass: read
20
25
  - name: property-data-prices
21
26
  publicAllowlist: false
22
27
  adminAllowlist: false
28
+ riskClass: read
23
29
  - name: property-data-prices-rent
24
30
  publicAllowlist: false
25
31
  adminAllowlist: false
32
+ riskClass: read
26
33
  - name: property-data-sold-prices
27
34
  publicAllowlist: false
28
35
  adminAllowlist: false
36
+ riskClass: read
29
37
  - name: property-data-demand
30
38
  publicAllowlist: false
31
39
  adminAllowlist: false
40
+ riskClass: read
32
41
  - name: property-data-yields
33
42
  publicAllowlist: false
34
43
  adminAllowlist: false
44
+ riskClass: read
35
45
  - name: property-data-growth
36
46
  publicAllowlist: false
37
47
  adminAllowlist: false
48
+ riskClass: read
38
49
  - name: property-data-national-hpi
39
50
  publicAllowlist: false
40
51
  adminAllowlist: false
52
+ riskClass: read
41
53
  - name: property-data-prices-per-sqf
42
54
  publicAllowlist: false
43
55
  adminAllowlist: false
56
+ riskClass: read
44
57
  - name: property-data-sold-prices-per-sqf
45
58
  publicAllowlist: false
46
59
  adminAllowlist: false
60
+ riskClass: read
47
61
  - name: property-data-crime
48
62
  publicAllowlist: false
49
63
  adminAllowlist: false
64
+ riskClass: read
50
65
  - name: property-data-flood-risk
51
66
  publicAllowlist: false
52
67
  adminAllowlist: false
68
+ riskClass: read
53
69
  - name: property-data-council-tax
54
70
  publicAllowlist: false
55
71
  adminAllowlist: false
72
+ riskClass: read
56
73
  - name: property-data-planning-applications
57
74
  publicAllowlist: false
58
75
  adminAllowlist: false
76
+ riskClass: read
59
77
  - name: property-data-address-match-uprn
60
78
  publicAllowlist: false
61
79
  adminAllowlist: false
80
+ riskClass: read
62
81
  - name: property-data-growth-psf
63
82
  publicAllowlist: false
64
83
  adminAllowlist: false
84
+ riskClass: read
65
85
  - name: property-data-demand-rent
66
86
  publicAllowlist: false
67
87
  adminAllowlist: false
88
+ riskClass: read
68
89
  - name: property-data-property-types
69
90
  publicAllowlist: false
70
91
  adminAllowlist: false
92
+ riskClass: read
71
93
  skills:
72
94
  - skills/property-data/SKILL.md
73
95
  always: false
@@ -3047,6 +3047,101 @@ function getDefaultAccountId() {
3047
3047
  return resolveAccount()?.accountId ?? null;
3048
3048
  }
3049
3049
 
3050
+ // ../lib/require-port-env/src/index.ts
3051
+ var MissingPortEnvError = class extends Error {
3052
+ envName;
3053
+ tag;
3054
+ failLine;
3055
+ constructor(envName, tag, failLine, message) {
3056
+ super(message);
3057
+ this.name = "MissingPortEnvError";
3058
+ this.envName = envName;
3059
+ this.tag = tag;
3060
+ this.failLine = failLine;
3061
+ }
3062
+ };
3063
+ var VALID_PORT_MIN = 1;
3064
+ var VALID_PORT_MAX = 65535;
3065
+ function requirePortEnv(envName, options = {}) {
3066
+ const tag = options.tag ?? "port-env";
3067
+ const failLine = options.failLine ?? "missing-port-env";
3068
+ const raw2 = process.env[envName];
3069
+ if (raw2 === void 0 || raw2 === "") {
3070
+ const msg = `[${tag}] ${failLine} reason=missing-env env=${envName}`;
3071
+ throw new MissingPortEnvError(envName, tag, failLine, msg);
3072
+ }
3073
+ const parsed = Number.parseInt(raw2, 10);
3074
+ if (!Number.isInteger(parsed) || parsed < VALID_PORT_MIN || parsed > VALID_PORT_MAX || String(parsed) !== raw2.trim()) {
3075
+ const msg = `[${tag}] ${failLine} reason=invalid-port-env env=${envName} value=${JSON.stringify(raw2)}`;
3076
+ throw new MissingPortEnvError(envName, tag, failLine, msg);
3077
+ }
3078
+ return parsed;
3079
+ }
3080
+
3081
+ // app/lib/claude-agent/session-store.ts
3082
+ import { createHash } from "crypto";
3083
+ var SESSION_TTL_MS = 24 * 60 * 60 * 1e3;
3084
+ var sessionStore = /* @__PURE__ */ new Map();
3085
+ function fingerprintSessionKey(raw2) {
3086
+ if (typeof raw2 !== "string" || !raw2) return raw2;
3087
+ if (/^sk_[a-f0-9]{16}$/.test(raw2)) return raw2;
3088
+ if (!raw2.startsWith("v1.")) return raw2;
3089
+ return `sk_${createHash("sha256").update(raw2).digest("hex").slice(0, 16)}`;
3090
+ }
3091
+ function registerSession(cacheKey2, agentType, accountId, _unused, userId, userName, role) {
3092
+ const existing = sessionStore.get(cacheKey2);
3093
+ if (existing) {
3094
+ existing.agentType = agentType;
3095
+ existing.accountId = accountId;
3096
+ existing.userId = userId ?? existing.userId;
3097
+ existing.userName = userName ?? existing.userName;
3098
+ existing.role = role ?? existing.role;
3099
+ return;
3100
+ }
3101
+ sessionStore.set(cacheKey2, { agentType, createdAt: Date.now(), accountId, userId, userName, role });
3102
+ }
3103
+ function validateSession(cacheKey2, agentType, _signedSessionToken) {
3104
+ const session = sessionStore.get(cacheKey2);
3105
+ if (!session) return { ok: false, reason: "session-not-registered" };
3106
+ if (session.agentType !== agentType) return { ok: false, reason: "agent-type-mismatch" };
3107
+ if (Date.now() - session.createdAt > SESSION_TTL_MS) {
3108
+ sessionStore.delete(cacheKey2);
3109
+ return { ok: false, reason: "session-expired-age" };
3110
+ }
3111
+ return { ok: true };
3112
+ }
3113
+ function getAccountIdForSession(cacheKey2) {
3114
+ return sessionStore.get(cacheKey2)?.accountId;
3115
+ }
3116
+ function getUserIdForSession(cacheKey2) {
3117
+ return sessionStore.get(cacheKey2)?.userId;
3118
+ }
3119
+ function getUserNameForSession(cacheKey2) {
3120
+ return sessionStore.get(cacheKey2)?.userName;
3121
+ }
3122
+ function getRoleForSession(cacheKey2) {
3123
+ return sessionStore.get(cacheKey2)?.role;
3124
+ }
3125
+ function getSessionIdForSession(cacheKey2) {
3126
+ return sessionStore.get(cacheKey2)?.sessionId;
3127
+ }
3128
+ function setSessionIdForSession(cacheKey2, sessionId) {
3129
+ const session = sessionStore.get(cacheKey2);
3130
+ if (!session) return false;
3131
+ session.sessionId = sessionId;
3132
+ return true;
3133
+ }
3134
+ function setWantsPriorConversation(cacheKey2) {
3135
+ const session = sessionStore.get(cacheKey2);
3136
+ if (session) session.wantsPriorConversation = true;
3137
+ }
3138
+ function unregisterSession(cacheKey2) {
3139
+ return sessionStore.delete(cacheKey2);
3140
+ }
3141
+ function getSessionKeyBySessionId(_sessionId) {
3142
+ return void 0;
3143
+ }
3144
+
3050
3145
  // server/loop-registry.ts
3051
3146
  import { readFileSync as readFileSync4 } from "fs";
3052
3147
  var TAG = "[loop-registry]";
@@ -3524,7 +3619,7 @@ async function verifyRemotePassword(password) {
3524
3619
  const configured = anyAccessPasswordConfigured(USERS_FILE) || legacy !== null;
3525
3620
  return { ok: false, why: configured ? "password-mismatch" : "no-password-file", hashBytes: 0 };
3526
3621
  }
3527
- var SESSION_TTL_MS = 24 * 60 * 60 * 1e3;
3622
+ var SESSION_TTL_MS2 = 24 * 60 * 60 * 1e3;
3528
3623
  var TOKEN_PREFIX = "v1.";
3529
3624
  var SECRET_BYTES = 32;
3530
3625
  var NONCE_BYTES = 16;
@@ -3599,13 +3694,13 @@ function validateRemoteSession(token, now = Date.now()) {
3599
3694
  if (!token) return false;
3600
3695
  const parsed = parseToken(token);
3601
3696
  if (!parsed || !parsed.signatureValid) return false;
3602
- return now - parsed.payload.c <= SESSION_TTL_MS;
3697
+ return now - parsed.payload.c <= SESSION_TTL_MS2;
3603
3698
  }
3604
3699
  function describeRemoteSession(token, now = Date.now()) {
3605
3700
  if (!token) return { present: false, expired: false };
3606
3701
  const parsed = parseToken(token);
3607
3702
  if (!parsed || !parsed.signatureValid) return { present: false, expired: false };
3608
- return { present: true, expired: now - parsed.payload.c > SESSION_TTL_MS };
3703
+ return { present: true, expired: now - parsed.payload.c > SESSION_TTL_MS2 };
3609
3704
  }
3610
3705
  function normalizeIp(ip) {
3611
3706
  if (!ip) return void 0;
@@ -4244,70 +4339,6 @@ function getOperatorDomains() {
4244
4339
  return operatorDomains;
4245
4340
  }
4246
4341
 
4247
- // app/lib/claude-agent/session-store.ts
4248
- import { createHash } from "crypto";
4249
- var SESSION_TTL_MS2 = 24 * 60 * 60 * 1e3;
4250
- var sessionStore = /* @__PURE__ */ new Map();
4251
- function fingerprintSessionKey(raw2) {
4252
- if (typeof raw2 !== "string" || !raw2) return raw2;
4253
- if (/^sk_[a-f0-9]{16}$/.test(raw2)) return raw2;
4254
- if (!raw2.startsWith("v1.")) return raw2;
4255
- return `sk_${createHash("sha256").update(raw2).digest("hex").slice(0, 16)}`;
4256
- }
4257
- function registerSession(cacheKey2, agentType, accountId, _unused, userId, userName, role) {
4258
- const existing = sessionStore.get(cacheKey2);
4259
- if (existing) {
4260
- existing.agentType = agentType;
4261
- existing.accountId = accountId;
4262
- existing.userId = userId ?? existing.userId;
4263
- existing.userName = userName ?? existing.userName;
4264
- existing.role = role ?? existing.role;
4265
- return;
4266
- }
4267
- sessionStore.set(cacheKey2, { agentType, createdAt: Date.now(), accountId, userId, userName, role });
4268
- }
4269
- function validateSession(cacheKey2, agentType, _signedSessionToken) {
4270
- const session = sessionStore.get(cacheKey2);
4271
- if (!session) return { ok: false, reason: "session-not-registered" };
4272
- if (session.agentType !== agentType) return { ok: false, reason: "agent-type-mismatch" };
4273
- if (Date.now() - session.createdAt > SESSION_TTL_MS2) {
4274
- sessionStore.delete(cacheKey2);
4275
- return { ok: false, reason: "session-expired-age" };
4276
- }
4277
- return { ok: true };
4278
- }
4279
- function getAccountIdForSession(cacheKey2) {
4280
- return sessionStore.get(cacheKey2)?.accountId;
4281
- }
4282
- function getUserIdForSession(cacheKey2) {
4283
- return sessionStore.get(cacheKey2)?.userId;
4284
- }
4285
- function getUserNameForSession(cacheKey2) {
4286
- return sessionStore.get(cacheKey2)?.userName;
4287
- }
4288
- function getRoleForSession(cacheKey2) {
4289
- return sessionStore.get(cacheKey2)?.role;
4290
- }
4291
- function getSessionIdForSession(cacheKey2) {
4292
- return sessionStore.get(cacheKey2)?.sessionId;
4293
- }
4294
- function setSessionIdForSession(cacheKey2, sessionId) {
4295
- const session = sessionStore.get(cacheKey2);
4296
- if (!session) return false;
4297
- session.sessionId = sessionId;
4298
- return true;
4299
- }
4300
- function setWantsPriorConversation(cacheKey2) {
4301
- const session = sessionStore.get(cacheKey2);
4302
- if (session) session.wantsPriorConversation = true;
4303
- }
4304
- function unregisterSession(cacheKey2) {
4305
- return sessionStore.delete(cacheKey2);
4306
- }
4307
- function getSessionKeyBySessionId(_sessionId) {
4308
- return void 0;
4309
- }
4310
-
4311
4342
  // app/lib/claude-agent/plugin-manifest.ts
4312
4343
  import { resolve as resolve5, join as join3 } from "path";
4313
4344
  import {
@@ -4522,37 +4553,6 @@ var emitMissingOnResolve = (..._args) => null;
4522
4553
  // app/lib/claude-agent/summary-helpers.ts
4523
4554
  var stripAttachmentMetaSuffix = (..._args) => null;
4524
4555
 
4525
- // ../lib/require-port-env/src/index.ts
4526
- var MissingPortEnvError = class extends Error {
4527
- envName;
4528
- tag;
4529
- failLine;
4530
- constructor(envName, tag, failLine, message) {
4531
- super(message);
4532
- this.name = "MissingPortEnvError";
4533
- this.envName = envName;
4534
- this.tag = tag;
4535
- this.failLine = failLine;
4536
- }
4537
- };
4538
- var VALID_PORT_MIN = 1;
4539
- var VALID_PORT_MAX = 65535;
4540
- function requirePortEnv(envName, options = {}) {
4541
- const tag = options.tag ?? "port-env";
4542
- const failLine = options.failLine ?? "missing-port-env";
4543
- const raw2 = process.env[envName];
4544
- if (raw2 === void 0 || raw2 === "") {
4545
- const msg = `[${tag}] ${failLine} reason=missing-env env=${envName}`;
4546
- throw new MissingPortEnvError(envName, tag, failLine, msg);
4547
- }
4548
- const parsed = Number.parseInt(raw2, 10);
4549
- if (!Number.isInteger(parsed) || parsed < VALID_PORT_MIN || parsed > VALID_PORT_MAX || String(parsed) !== raw2.trim()) {
4550
- const msg = `[${tag}] ${failLine} reason=invalid-port-env env=${envName} value=${JSON.stringify(raw2)}`;
4551
- throw new MissingPortEnvError(envName, tag, failLine, msg);
4552
- }
4553
- return parsed;
4554
- }
4555
-
4556
4556
  // app/lib/neo4j-store.ts
4557
4557
  import neo4j from "neo4j-driver";
4558
4558
  import { randomUUID } from "crypto";
@@ -6236,6 +6236,19 @@ export {
6236
6236
  resolveAgentConfig,
6237
6237
  isActiveAgentSlug,
6238
6238
  getDefaultAccountId,
6239
+ requirePortEnv,
6240
+ fingerprintSessionKey,
6241
+ registerSession,
6242
+ validateSession,
6243
+ getAccountIdForSession,
6244
+ getUserIdForSession,
6245
+ getUserNameForSession,
6246
+ getRoleForSession,
6247
+ getSessionIdForSession,
6248
+ setSessionIdForSession,
6249
+ setWantsPriorConversation,
6250
+ unregisterSession,
6251
+ getSessionKeyBySessionId,
6239
6252
  sampleCpu,
6240
6253
  sampleProcessCpu,
6241
6254
  registerLoop,
@@ -6271,18 +6284,6 @@ export {
6271
6284
  isOperatorHost,
6272
6285
  classifyHost,
6273
6286
  getOperatorDomains,
6274
- fingerprintSessionKey,
6275
- registerSession,
6276
- validateSession,
6277
- getAccountIdForSession,
6278
- getUserIdForSession,
6279
- getUserNameForSession,
6280
- getRoleForSession,
6281
- getSessionIdForSession,
6282
- setSessionIdForSession,
6283
- setWantsPriorConversation,
6284
- unregisterSession,
6285
- getSessionKeyBySessionId,
6286
6287
  findMissingPlugins,
6287
6288
  walkPremiumBundles,
6288
6289
  autoDeliverPremiumPlugins,
@@ -6290,7 +6291,6 @@ export {
6290
6291
  cleanupLeakedPremiumSubs,
6291
6292
  emitMissingOnResolve,
6292
6293
  stripAttachmentMetaSuffix,
6293
- requirePortEnv,
6294
6294
  getSession,
6295
6295
  runAdminUserSelfHeal,
6296
6296
  runUserProfileReconcile,
@@ -16,7 +16,7 @@ import {
16
16
  sanitizeClientCorrId,
17
17
  vncLog,
18
18
  websockifyLog
19
- } from "./chunk-5ADBNEJA.js";
19
+ } from "./chunk-2WAXM5N2.js";
20
20
  import "./chunk-PFF6I7KP.js";
21
21
 
22
22
  // server/edge.ts
@@ -5,12 +5,12 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Activity — Maxy</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/activity-CFqkDhTs.js"></script>
8
+ <script type="module" crossorigin src="/assets/activity-DH3Wgc3O.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-CltuBf4Z.js">
10
- <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-DSW9vDi2.js">
11
- <link rel="modulepreload" crossorigin href="/assets/AdminShell-C8wazpnz.js">
12
- <link rel="modulepreload" crossorigin href="/assets/triangle-alert-CHjdKpag.js">
13
- <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-DyrH8DA8.css">
10
+ <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-0PfRrN6i.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/AdminShell-Ckht9hmU.js">
12
+ <link rel="modulepreload" crossorigin href="/assets/triangle-alert-DBJ7xz_t.js">
13
+ <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-BkQ5tA8A.css">
14
14
  <link rel="stylesheet" href="/brand-defaults.css">
15
15
  </head>
16
16
  <body>
@@ -5,11 +5,11 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Agents — Maxy</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/agents-DPulfmrd.js"></script>
8
+ <script type="module" crossorigin src="/assets/agents-X_IvDHLZ.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-CltuBf4Z.js">
10
- <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-DSW9vDi2.js">
11
- <link rel="modulepreload" crossorigin href="/assets/AdminShell-C8wazpnz.js">
12
- <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-DyrH8DA8.css">
10
+ <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-0PfRrN6i.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/AdminShell-Ckht9hmU.js">
12
+ <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-BkQ5tA8A.css">
13
13
  <link rel="stylesheet" href="/brand-defaults.css">
14
14
  </head>
15
15
  <body>
@@ -1 +1 @@
1
- import{o as e}from"./chunk-CltuBf4Z.js";import{B as t,F as n,H as r,I as i,K as a,R as o}from"./useSubAccountSwitcher-DSW9vDi2.js";import{D as s}from"./useVoiceRecorder-BeNqxmm2.js";import{C as c,T as l,w as u}from"./AdminShell-C8wazpnz.js";var d=`admin-landing-redirected`,f=`/graph`;function p(e){return e.variant===`operator`?!1:e.appState===`chat`&&!e.alreadyRedirected}var m=e(a(),1);function h(e=`admin`){let[t,n]=(0,m.useState)(`loading`),[i,a]=(0,m.useState)(``),[o,c]=(0,m.useState)(``),[u,h]=(0,m.useState)(``),[g,_]=(0,m.useState)(!1),[v,y]=(0,m.useState)(!1),[b,x]=(0,m.useState)(!1),[S,C]=(0,m.useState)(!1),[w,T]=(0,m.useState)(!1),[E,D]=(0,m.useState)(null),[O,k]=(0,m.useState)(null),[A,j]=(0,m.useState)(void 0),[M,N]=(0,m.useState)(null),[P,F]=(0,m.useState)(void 0),[I,L]=(0,m.useState)(null),[R,z]=(0,m.useState)(null),[B,V]=(0,m.useState)(void 0),H=(0,m.useRef)(void 0),[U,W]=(0,m.useState)(!1),[G,K]=(0,m.useState)(!0);(0,m.useEffect)(()=>{typeof window>`u`||fetch(`/api/remote-auth/status`).then(e=>e.ok?e.json():null).then(e=>{e?.configured&&W(!0)}).catch(()=>{})},[]);let q=(0,m.useRef)(null),J=(0,m.useRef)(null);(0,m.useEffect)(()=>{async function e(){let e=null;try{e=sessionStorage.getItem(`maxy-admin-session-key`)}catch{}if(!e)return!1;try{let t=await fetch(`/api/admin/session?session_key=${encodeURIComponent(e)}`);if(t.status===401){try{sessionStorage.removeItem(`maxy-admin-session-key`)}catch{}return!1}if(!t.ok)return!1;let r=await t.json();D(r.session_key),z(r.sessionId??null),j(r.businessName),N(r.role??null),F(r.userName===void 0?null:r.userName),L(r.avatar??null);let i=s(r.thinkingView);return H.current=i,V(i),n(`chat`),!0}catch(e){return console.error(`[admin] session restore failed:`,e),!1}}async function t(r=2){try{let i=await fetch(`/api/health`);if(!i.ok){if(r>0)return await new Promise(e=>setTimeout(e,1500)),t(r-1);console.error(`[admin] health check returned ${i.status} after retries`),n(`set-pin`);return}let a=await i.json();if(!a.pin_configured){n(`set-pin`);return}K(!!a.claude_authenticated);let o=!1;try{o=new URLSearchParams(window.location.search).get(`connect`)===`claude`}catch{}if(o){try{let e=new URL(window.location.href);e.searchParams.delete(`connect`),window.history.replaceState(null,``,e.pathname+e.search+e.hash)}catch{}if(!a.claude_authenticated){n(`connect-claude`);return}}if(await e())return;n(`enter-pin`)}catch(e){if(r>0)return await new Promise(e=>setTimeout(e,1500)),t(r-1);console.error(`[admin] health check failed:`,e),n(`set-pin`)}}t()},[]),(0,m.useEffect)(()=>{t===`chat`&&fetch(`/api/admin/claude-info`).then(e=>{if(e.ok)return e.json()}).then(e=>{e&&k(e)}).catch(()=>{})},[t]),(0,m.useEffect)(()=>{if(typeof window>`u`)return;let n=!1;try{n=sessionStorage.getItem(d)===`1`}catch{}if(p({appState:t,alreadyRedirected:n,variant:e})){try{sessionStorage.setItem(d,`1`)}catch{}console.info(`[admin-ui] landing-redirect target=${f}`),window.location.replace(f)}},[t,e]);let Y=(0,m.useRef)(null);(0,m.useEffect)(()=>{if(t!==`chat`)return;let e=setInterval(async()=>{try{let e=await fetch(`/api/health`);if(e.ok){let t=await e.json();K(t.auth_status!==`dead`&&t.auth_status!==`missing`)}}catch{}if(E)try{let e=await fetch(`/api/admin/session?session_key=${encodeURIComponent(E)}`);if(e.status!==401)return;let t=(await e.clone().json().catch(()=>null))?.code??`unknown-401`;if(t===`remote-auth-required`){r(`heartbeat`,`/api/admin/session`);return}console.warn(`[admin-auth] outcome=heartbeat-detected-expiry code=${t}`),Y.current?.()}catch{}},300*1e3);return()=>clearInterval(e)},[t,E]),(0,m.useEffect)(()=>{t===`connect-claude`&&fetch(`/api/health`).then(e=>e.ok?e.json():null).then(e=>{e?.claude_authenticated&&(K(!0),n(`enter-pin`))}).catch(()=>{})},[t]);async function X(e,t){y(!0);try{let i=await fetch(`/api/admin/session`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pin:e,...t?{accountId:t}:{}})});if(!i.ok){let e=await i.json().catch(()=>({}));if(i.status===401&&e?.code===`remote-auth-required`){r(`enter-pin`,`/api/admin/session`);return}h(e.error||`Invalid PIN`);return}let o=await i.json();D(o.session_key),z(o.sessionId??null),j(o.businessName),N(o.role??null),F(o.userName===void 0?null:o.userName),L(o.avatar??null);let c=s(o.thinkingView);H.current=c,V(c);try{sessionStorage.setItem(`maxy-admin-session-key`,o.session_key)}catch{}a(``),n(`chat`)}catch(e){console.error(`[admin] connection error:`,e),h(`Could not connect.`)}finally{y(!1)}}let Z=(0,m.useCallback)(async e=>{if(e.preventDefault(),v)return;h(``);let t=o.trim();if(!t){h(`Please enter your name.`);return}if(i.length<4){h(`PIN must be at least 4 characters.`);return}let s=i;y(!0);try{let e=await fetch(`/api/onboarding/set-pin`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pin:s,name:t})});if(!e.ok){let t=await e.json().catch(()=>({}));if(e.status===401&&t?.code===`remote-auth-required`){r(`set-pin`,`/api/onboarding/set-pin`);return}if(e.status===409){console.log(`[admin] PIN already configured — re-checking health`);try{let e=await fetch(`/api/health`);if(e.ok){let r=await e.json();r.pin_configured&&r.claude_authenticated?n(`enter-pin`):r.pin_configured?n(`connect-claude`):h(t.error||`Failed to set PIN.`)}else n(`enter-pin`)}catch{n(`enter-pin`)}return}h(t.error||`Failed to set PIN.`);return}let i=await fetch(`/api/health`);if((i.ok?await i.json():null)?.claude_authenticated){await X(s);return}a(``),n(`connect-claude`)}catch(e){console.error(`[admin] connection error:`,e),h(`Could not connect.`)}finally{y(!1)}},[i,v,o]),Q=(0,m.useCallback)(async e=>{e.preventDefault(),h(``),await X(i)},[i]),ee=(0,m.useCallback)(async()=>{T(!0);try{if(!await l())return console.warn(`[admin-ui] claude-disconnect not verified — credentials may persist; staying put`),!1;K(!1),D(null),N(null),F(void 0),L(null);try{sessionStorage.removeItem(`maxy-admin-session-key`),sessionStorage.removeItem(d)}catch{}return n(`connect-claude`),!0}finally{T(!1)}},[]),$=(0,m.useCallback)(()=>{D(null),N(null),F(void 0),L(null);try{sessionStorage.removeItem(`maxy-admin-session-key`),sessionStorage.removeItem(d)}catch{}a(``),h(``),n(`enter-pin`)},[]);return(0,m.useEffect)(()=>{Y.current=$},[$]),{appState:t,setAppState:n,pin:i,setPin:a,operatorName:o,setOperatorName:c,pinError:u,setPinError:h,showPin:g,setShowPin:_,pinLoading:v,authPolling:b,setAuthPolling:x,authLoading:S,setAuthLoading:C,disconnecting:w,cacheKey:E,setCacheKey:D,claudeInfo:O,setClaudeInfo:k,businessName:A,role:M,userName:P,userAvatar:I,sessionId:R,setSessionId:z,expandAll:B,setExpandAll:V,expandAllDefaultRef:H,remoteAuthEnabled:U,claudeConnected:G,pinInputRef:q,setPinFormRef:J,handleSetPin:Z,handleLogin:Q,handleDisconnect:ee,handleLogout:$}}var g=t();function _({inputRef:e,value:t,onChange:n,onComplete:r,showPin:i,autoFocus:a}){let o=(0,m.useRef)([]);function s(e,r){r.key===`Backspace`?(r.preventDefault(),t[e]?n(t.slice(0,e)+t.slice(e+1)):e>0&&(n(t.slice(0,e-1)+t.slice(e)),o.current[e-1]?.focus())):r.key===`ArrowLeft`&&e>0?o.current[e-1]?.focus():r.key===`ArrowRight`&&e<5?o.current[e+1]?.focus():r.key===`Enter`&&(r.preventDefault(),r.currentTarget.form?.requestSubmit())}function c(e,i){let a=i.nativeEvent.data;if(!a||!/^\d$/.test(a))return;let s=t.split(``);for(s[e]=a;s.length<e;)s.push(``);let c=s.join(``).replace(/\D/g,``).slice(0,6);n(c),c.length===6?r?.(c):e<5&&o.current[e+1]?.focus()}function l(e){e.preventDefault();let t=e.clipboardData.getData(`text`).replace(/\D/g,``).slice(0,6);t&&(n(t),t.length===6?r?.(t):o.current[t.length]?.focus())}return(0,g.jsx)(`div`,{className:`pin-field`,children:Array.from({length:6}).map((n,r)=>(0,g.jsx)(`input`,{ref:t=>{o.current[r]=t,r===0&&e&&(e.current=t)},type:`text`,inputMode:`numeric`,className:`pin-box${t[r]?` pin-box-filled`:``}`,value:t[r]?i?t[r]:`•`:``,onKeyDown:e=>s(r,e),onInput:e=>c(r,e),onPaste:l,onFocus:e=>e.target.select(),autoFocus:a&&r===0,autoComplete:`off`,maxLength:1,"aria-label":`PIN digit ${r+1}`},r))})}function v(e){let{pin:t,setPin:n,showPin:r,setShowPin:a,pinLoading:s,pinError:l,pinInputRef:d,setPinFormRef:f,onSubmit:p,operatorName:m,setOperatorName:h}=e;return(0,g.jsx)(`div`,{className:`connect-page`,children:(0,g.jsxs)(`div`,{className:`connect-content`,children:[(0,g.jsx)(`img`,{src:o,alt:i.productName,className:`connect-logo connect-logo--maxy`}),!i.logoContainsName&&(0,g.jsxs)(`h1`,{className:`connect-title`,children:[`Welcome to `,i.productName]}),(0,g.jsxs)(`p`,{className:`connect-subtitle`,children:[`Tell `,i.productName,` who you are, then choose a PIN.`]}),(0,g.jsxs)(`form`,{ref:f,onSubmit:p,className:`connect-pin-form`,children:[(0,g.jsxs)(`div`,{className:`pin-input-row`,children:[(0,g.jsx)(`input`,{type:`text`,className:`connect-name-input`,placeholder:`Your full name`,value:m,onChange:e=>h(e.target.value),autoComplete:`name`,autoFocus:!0,required:!0,"aria-label":`Your full name`}),(0,g.jsx)(`div`,{style:{width:38,flexShrink:0},"aria-hidden":`true`})]}),(0,g.jsxs)(`div`,{className:`pin-input-row`,children:[(0,g.jsx)(_,{inputRef:d,value:t,onChange:n,onComplete:()=>{},showPin:r}),(0,g.jsx)(c,{variant:`send`,type:`submit`,disabled:!t||!m.trim(),loading:s,"aria-label":`Set PIN`,children:(0,g.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,g.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,g.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,g.jsx)(u,{checked:r,onChange:()=>a(e=>!e),label:`Show PIN`})]}),l&&(0,g.jsx)(`p`,{className:`admin-pin-error`,children:l})]})})}function y(e){let{pin:t,setPin:n,showPin:r,setShowPin:a,pinLoading:s,pinError:l,pinInputRef:d,onSubmit:f,remoteAuthEnabled:p,onSignOutRemote:m}=e;return(0,g.jsxs)(`div`,{className:`connect-page`,children:[p&&m&&(0,g.jsx)(`button`,{type:`button`,className:`connect-signout`,onClick:m,children:`Sign out`}),(0,g.jsxs)(`div`,{className:`connect-content`,children:[(0,g.jsx)(`img`,{src:o,alt:i.productName,className:`connect-logo connect-logo--maxy`}),!i.logoContainsName&&(0,g.jsx)(`h1`,{className:`connect-title`,children:i.productName}),(0,g.jsxs)(`form`,{onSubmit:f,className:`connect-pin-form`,children:[(0,g.jsxs)(`div`,{className:`pin-input-row`,children:[(0,g.jsx)(_,{inputRef:d,value:t,onChange:n,onComplete:()=>{},showPin:r,autoFocus:!0}),(0,g.jsx)(c,{variant:`send`,type:`submit`,disabled:!t,loading:s,children:(0,g.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,g.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,g.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,g.jsx)(`div`,{className:`pin-options`,children:(0,g.jsx)(u,{checked:r,onChange:()=>a(e=>!e),label:`Show PIN`})})]}),l&&(0,g.jsx)(`p`,{className:`admin-pin-error`,children:l})]})]})}function b(e){let{authPolling:t,setAuthPolling:n,authLoading:r,setAuthLoading:a,pinError:s,setPinError:l,setAppState:u}=e,[d,f]=(0,m.useState)(!1),[p,h]=(0,m.useState)(!1),[_,v]=(0,m.useState)(``),[y,b]=(0,m.useState)(``),[x,S]=(0,m.useState)(``);async function C(){S(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`paste-code`,code:y})})).json();e.accepted?(S(`Code submitted. Finishing sign-in…`),b(``)):S(e.error||`Could not submit code.`)}catch(e){console.error(`[admin] paste-code error:`,e),S(`Could not submit code.`)}}async function w(){h(!0),l(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`launch-browser`})})).json();e.launched?f(!0):e.error&&l(e.error)}catch(e){console.error(`[admin] browser launch error:`,e),l(`Could not launch browser.`)}h(!1)}async function T(){a(!0),l(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`})).json();if(e.started){n(!0),f(!0),a(!1),v(e.transport||``);for(let e=0;e<120;e++)if(await new Promise(e=>setTimeout(e,2e3)),(await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`wait`})})).json()).authenticated){await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`stop`})}),u(`enter-pin`);return}l(`Timed out waiting for sign-in. Try again.`),n(!1)}else e.error&&l(e.error)}catch(e){console.error(`[admin] auth flow error:`,e),l(`Could not start auth flow.`)}a(!1)}async function E(){await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`stop`})}),n(!1),l(``)}return t||d?(0,g.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100dvh`,overflow:`auto`},children:[(0,g.jsxs)(`header`,{className:`chat-header`,style:{paddingBottom:`12px`,flexShrink:0,position:`relative`,maxWidth:`680px`,width:`100%`,margin:`0 auto`,padding:`24px 20px 12px`},children:[t?(0,g.jsx)(`button`,{onClick:E,style:{position:`absolute`,top:`12px`,right:`12px`,background:`none`,border:`none`,color:`#999`,fontSize:`13px`,cursor:`pointer`,padding:`4px 8px`},"aria-label":`Cancel`,children:`✕`}):(0,g.jsx)(`button`,{onClick:()=>f(!1),style:{position:`absolute`,top:`12px`,right:`12px`,background:`none`,border:`none`,color:`#999`,fontSize:`13px`,cursor:`pointer`,padding:`4px 8px`},"aria-label":`Close browser`,children:`✕`}),(0,g.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`chat-logo`}),(0,g.jsx)(`h1`,{className:`chat-tagline`,children:`Connect Claude`}),(0,g.jsx)(`p`,{className:`chat-intro`,children:t?`Sign in and authorize in the browser below.`:`Open your email or prepare your accounts, then sign in.`}),!t&&(0,g.jsx)(`div`,{style:{marginTop:`12px`},children:(0,g.jsx)(c,{variant:`primary`,onClick:T,disabled:r,children:r?(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`})}),t&&_===`native`&&(0,g.jsxs)(`div`,{style:{marginTop:`14px`,maxWidth:`420px`,margin:`14px auto 0`,display:`flex`,flexDirection:`column`,gap:`8px`},children:[(0,g.jsx)(`label`,{style:{fontSize:`12px`,color:`#999`,lineHeight:1.4},children:`If the browser didn't finish sign-in, paste the code or full redirect URL from Claude's page:`}),(0,g.jsxs)(`div`,{style:{display:`flex`,gap:`8px`},children:[(0,g.jsx)(`input`,{type:`text`,value:y,onChange:e=>b(e.target.value),placeholder:`Paste code or redirect URL`,style:{flex:1,padding:`8px 10px`,fontSize:`13px`,border:`1px solid #ccc`,borderRadius:`6px`}}),(0,g.jsx)(c,{variant:`primary`,onClick:C,disabled:!y.trim(),children:`Submit`})]}),x&&(0,g.jsx)(`p`,{style:{fontSize:`12px`,color:`#999`,margin:0},children:x})]})]}),(0,g.jsx)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,minHeight:0,gap:`10px`,padding:`0 0 16px`},children:(0,g.jsx)(`iframe`,{src:`/vnc-viewer.html`,style:{flex:1,width:`100%`,minHeight:0,border:`none`,background:`#111`,display:`block`},title:`Claude Sign-in`})}),s&&(0,g.jsx)(`p`,{className:`admin-pin-error`,style:{textAlign:`center`,padding:`0 20px 16px`},children:s})]}):(0,g.jsx)(`div`,{className:`connect-page`,children:(0,g.jsxs)(`div`,{className:`connect-content`,children:[(0,g.jsxs)(`div`,{className:`connect-logos`,children:[(0,g.jsx)(`div`,{className:`connect-logo-wrap`,children:(0,g.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`connect-logo`})}),(0,g.jsx)(`svg`,{className:`connect-arrow`,viewBox:`0 0 48 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:(0,g.jsx)(`path`,{d:`M0 12h44m0 0l-8-8m8 8l-8 8`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`})}),(0,g.jsxs)(`div`,{className:`connect-logo-wrap`,children:[(0,g.jsx)(`img`,{src:o,alt:i.productName,className:`connect-logo connect-logo--maxy`}),!i.logoContainsName&&(0,g.jsx)(`span`,{className:`connect-logo-label`,children:i.productName})]})]}),(0,g.jsxs)(`h1`,{className:`connect-title`,children:[`Connect Claude to power `,i.productName]}),(0,g.jsx)(`p`,{className:`connect-subtitle`,children:`Sign in with your Anthropic account to get started.`}),(0,g.jsx)(c,{variant:`primary`,onClick:T,disabled:r,children:r?(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`}),(0,g.jsx)(`p`,{style:{marginTop:`6px`,fontSize:`11px`,color:`#999`,maxWidth:`300px`,textAlign:`center`,lineHeight:`1.4`},children:`First time? You may need to sign into your email and Anthropic account in the browser before connecting.`}),(0,g.jsx)(`button`,{onClick:w,disabled:p,style:{marginTop:`12px`,background:`none`,border:`none`,color:`var(--color-primary, #666)`,fontSize:`13px`,cursor:`pointer`,textDecoration:`underline`,textUnderlineOffset:`3px`},children:p?`Launching…`:`Open browser first`}),s&&(0,g.jsx)(`p`,{className:`admin-pin-error`,children:s})]})})}function x({auth:e}){return e.appState===`loading`?(0,g.jsx)(n,{surface:`gate`}):e.appState===`set-pin`?(0,g.jsx)(v,{pin:e.pin,setPin:e.setPin,showPin:e.showPin,setShowPin:e.setShowPin,pinLoading:e.pinLoading,pinError:e.pinError,pinInputRef:e.pinInputRef,setPinFormRef:e.setPinFormRef,onSubmit:e.handleSetPin,operatorName:e.operatorName,setOperatorName:e.setOperatorName}):e.appState===`connect-claude`?(0,g.jsx)(b,{authPolling:e.authPolling,setAuthPolling:e.setAuthPolling,authLoading:e.authLoading,setAuthLoading:e.setAuthLoading,pinError:e.pinError,setPinError:e.setPinError,setAppState:e.setAppState}):e.appState===`enter-pin`?(0,g.jsx)(y,{pin:e.pin,setPin:e.setPin,showPin:e.showPin,setShowPin:e.setShowPin,pinLoading:e.pinLoading,pinError:e.pinError,pinInputRef:e.pinInputRef,onSubmit:e.handleLogin,remoteAuthEnabled:e.remoteAuthEnabled,onSignOutRemote:()=>{console.info(`[admin-ui] remote-auth sign-out → /__remote-auth/logout`),window.location.href=`/__remote-auth/logout`}}):null}export{h as n,x as t};
1
+ import{o as e}from"./chunk-CltuBf4Z.js";import{B as t,F as n,H as r,I as i,K as a,R as o}from"./useSubAccountSwitcher-0PfRrN6i.js";import{D as s}from"./useVoiceRecorder-BP6CpYQD.js";import{C as c,T as l,w as u}from"./AdminShell-Ckht9hmU.js";var d=`admin-landing-redirected`,f=`/graph`;function p(e){return e.variant===`operator`?!1:e.appState===`chat`&&!e.alreadyRedirected}var m=e(a(),1);function h(e=`admin`){let[t,n]=(0,m.useState)(`loading`),[i,a]=(0,m.useState)(``),[o,c]=(0,m.useState)(``),[u,h]=(0,m.useState)(``),[g,_]=(0,m.useState)(!1),[v,y]=(0,m.useState)(!1),[b,x]=(0,m.useState)(!1),[S,C]=(0,m.useState)(!1),[w,T]=(0,m.useState)(!1),[E,D]=(0,m.useState)(null),[O,k]=(0,m.useState)(null),[A,j]=(0,m.useState)(void 0),[M,N]=(0,m.useState)(null),[P,F]=(0,m.useState)(void 0),[I,L]=(0,m.useState)(null),[R,z]=(0,m.useState)(null),[B,V]=(0,m.useState)(void 0),H=(0,m.useRef)(void 0),[U,W]=(0,m.useState)(!1),[G,K]=(0,m.useState)(!0);(0,m.useEffect)(()=>{typeof window>`u`||fetch(`/api/remote-auth/status`).then(e=>e.ok?e.json():null).then(e=>{e?.configured&&W(!0)}).catch(()=>{})},[]);let q=(0,m.useRef)(null),J=(0,m.useRef)(null);(0,m.useEffect)(()=>{async function e(){let e=null;try{e=sessionStorage.getItem(`maxy-admin-session-key`)}catch{}if(!e)return!1;try{let t=await fetch(`/api/admin/session?session_key=${encodeURIComponent(e)}`);if(t.status===401){try{sessionStorage.removeItem(`maxy-admin-session-key`)}catch{}return!1}if(!t.ok)return!1;let r=await t.json();D(r.session_key),z(r.sessionId??null),j(r.businessName),N(r.role??null),F(r.userName===void 0?null:r.userName),L(r.avatar??null);let i=s(r.thinkingView);return H.current=i,V(i),n(`chat`),!0}catch(e){return console.error(`[admin] session restore failed:`,e),!1}}async function t(r=2){try{let i=await fetch(`/api/health`);if(!i.ok){if(r>0)return await new Promise(e=>setTimeout(e,1500)),t(r-1);console.error(`[admin] health check returned ${i.status} after retries`),n(`set-pin`);return}let a=await i.json();if(!a.pin_configured){n(`set-pin`);return}K(!!a.claude_authenticated);let o=!1;try{o=new URLSearchParams(window.location.search).get(`connect`)===`claude`}catch{}if(o){try{let e=new URL(window.location.href);e.searchParams.delete(`connect`),window.history.replaceState(null,``,e.pathname+e.search+e.hash)}catch{}if(!a.claude_authenticated){n(`connect-claude`);return}}if(await e())return;n(`enter-pin`)}catch(e){if(r>0)return await new Promise(e=>setTimeout(e,1500)),t(r-1);console.error(`[admin] health check failed:`,e),n(`set-pin`)}}t()},[]),(0,m.useEffect)(()=>{t===`chat`&&fetch(`/api/admin/claude-info`).then(e=>{if(e.ok)return e.json()}).then(e=>{e&&k(e)}).catch(()=>{})},[t]),(0,m.useEffect)(()=>{if(typeof window>`u`)return;let n=!1;try{n=sessionStorage.getItem(d)===`1`}catch{}if(p({appState:t,alreadyRedirected:n,variant:e})){try{sessionStorage.setItem(d,`1`)}catch{}console.info(`[admin-ui] landing-redirect target=${f}`),window.location.replace(f)}},[t,e]);let Y=(0,m.useRef)(null);(0,m.useEffect)(()=>{if(t!==`chat`)return;let e=setInterval(async()=>{try{let e=await fetch(`/api/health`);if(e.ok){let t=await e.json();K(t.auth_status!==`dead`&&t.auth_status!==`missing`)}}catch{}if(E)try{let e=await fetch(`/api/admin/session?session_key=${encodeURIComponent(E)}`);if(e.status!==401)return;let t=(await e.clone().json().catch(()=>null))?.code??`unknown-401`;if(t===`remote-auth-required`){r(`heartbeat`,`/api/admin/session`);return}console.warn(`[admin-auth] outcome=heartbeat-detected-expiry code=${t}`),Y.current?.()}catch{}},300*1e3);return()=>clearInterval(e)},[t,E]),(0,m.useEffect)(()=>{t===`connect-claude`&&fetch(`/api/health`).then(e=>e.ok?e.json():null).then(e=>{e?.claude_authenticated&&(K(!0),n(`enter-pin`))}).catch(()=>{})},[t]);async function X(e,t){y(!0);try{let i=await fetch(`/api/admin/session`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pin:e,...t?{accountId:t}:{}})});if(!i.ok){let e=await i.json().catch(()=>({}));if(i.status===401&&e?.code===`remote-auth-required`){r(`enter-pin`,`/api/admin/session`);return}h(e.error||`Invalid PIN`);return}let o=await i.json();D(o.session_key),z(o.sessionId??null),j(o.businessName),N(o.role??null),F(o.userName===void 0?null:o.userName),L(o.avatar??null);let c=s(o.thinkingView);H.current=c,V(c);try{sessionStorage.setItem(`maxy-admin-session-key`,o.session_key)}catch{}a(``),n(`chat`)}catch(e){console.error(`[admin] connection error:`,e),h(`Could not connect.`)}finally{y(!1)}}let Z=(0,m.useCallback)(async e=>{if(e.preventDefault(),v)return;h(``);let t=o.trim();if(!t){h(`Please enter your name.`);return}if(i.length<4){h(`PIN must be at least 4 characters.`);return}let s=i;y(!0);try{let e=await fetch(`/api/onboarding/set-pin`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pin:s,name:t})});if(!e.ok){let t=await e.json().catch(()=>({}));if(e.status===401&&t?.code===`remote-auth-required`){r(`set-pin`,`/api/onboarding/set-pin`);return}if(e.status===409){console.log(`[admin] PIN already configured — re-checking health`);try{let e=await fetch(`/api/health`);if(e.ok){let r=await e.json();r.pin_configured&&r.claude_authenticated?n(`enter-pin`):r.pin_configured?n(`connect-claude`):h(t.error||`Failed to set PIN.`)}else n(`enter-pin`)}catch{n(`enter-pin`)}return}h(t.error||`Failed to set PIN.`);return}let i=await fetch(`/api/health`);if((i.ok?await i.json():null)?.claude_authenticated){await X(s);return}a(``),n(`connect-claude`)}catch(e){console.error(`[admin] connection error:`,e),h(`Could not connect.`)}finally{y(!1)}},[i,v,o]),Q=(0,m.useCallback)(async e=>{e.preventDefault(),h(``),await X(i)},[i]),ee=(0,m.useCallback)(async()=>{T(!0);try{if(!await l())return console.warn(`[admin-ui] claude-disconnect not verified — credentials may persist; staying put`),!1;K(!1),D(null),N(null),F(void 0),L(null);try{sessionStorage.removeItem(`maxy-admin-session-key`),sessionStorage.removeItem(d)}catch{}return n(`connect-claude`),!0}finally{T(!1)}},[]),$=(0,m.useCallback)(()=>{D(null),N(null),F(void 0),L(null);try{sessionStorage.removeItem(`maxy-admin-session-key`),sessionStorage.removeItem(d)}catch{}a(``),h(``),n(`enter-pin`)},[]);return(0,m.useEffect)(()=>{Y.current=$},[$]),{appState:t,setAppState:n,pin:i,setPin:a,operatorName:o,setOperatorName:c,pinError:u,setPinError:h,showPin:g,setShowPin:_,pinLoading:v,authPolling:b,setAuthPolling:x,authLoading:S,setAuthLoading:C,disconnecting:w,cacheKey:E,setCacheKey:D,claudeInfo:O,setClaudeInfo:k,businessName:A,role:M,userName:P,userAvatar:I,sessionId:R,setSessionId:z,expandAll:B,setExpandAll:V,expandAllDefaultRef:H,remoteAuthEnabled:U,claudeConnected:G,pinInputRef:q,setPinFormRef:J,handleSetPin:Z,handleLogin:Q,handleDisconnect:ee,handleLogout:$}}var g=t();function _({inputRef:e,value:t,onChange:n,onComplete:r,showPin:i,autoFocus:a}){let o=(0,m.useRef)([]);function s(e,r){r.key===`Backspace`?(r.preventDefault(),t[e]?n(t.slice(0,e)+t.slice(e+1)):e>0&&(n(t.slice(0,e-1)+t.slice(e)),o.current[e-1]?.focus())):r.key===`ArrowLeft`&&e>0?o.current[e-1]?.focus():r.key===`ArrowRight`&&e<5?o.current[e+1]?.focus():r.key===`Enter`&&(r.preventDefault(),r.currentTarget.form?.requestSubmit())}function c(e,i){let a=i.nativeEvent.data;if(!a||!/^\d$/.test(a))return;let s=t.split(``);for(s[e]=a;s.length<e;)s.push(``);let c=s.join(``).replace(/\D/g,``).slice(0,6);n(c),c.length===6?r?.(c):e<5&&o.current[e+1]?.focus()}function l(e){e.preventDefault();let t=e.clipboardData.getData(`text`).replace(/\D/g,``).slice(0,6);t&&(n(t),t.length===6?r?.(t):o.current[t.length]?.focus())}return(0,g.jsx)(`div`,{className:`pin-field`,children:Array.from({length:6}).map((n,r)=>(0,g.jsx)(`input`,{ref:t=>{o.current[r]=t,r===0&&e&&(e.current=t)},type:`text`,inputMode:`numeric`,className:`pin-box${t[r]?` pin-box-filled`:``}`,value:t[r]?i?t[r]:`•`:``,onKeyDown:e=>s(r,e),onInput:e=>c(r,e),onPaste:l,onFocus:e=>e.target.select(),autoFocus:a&&r===0,autoComplete:`off`,maxLength:1,"aria-label":`PIN digit ${r+1}`},r))})}function v(e){let{pin:t,setPin:n,showPin:r,setShowPin:a,pinLoading:s,pinError:l,pinInputRef:d,setPinFormRef:f,onSubmit:p,operatorName:m,setOperatorName:h}=e;return(0,g.jsx)(`div`,{className:`connect-page`,children:(0,g.jsxs)(`div`,{className:`connect-content`,children:[(0,g.jsx)(`img`,{src:o,alt:i.productName,className:`connect-logo connect-logo--maxy`}),!i.logoContainsName&&(0,g.jsxs)(`h1`,{className:`connect-title`,children:[`Welcome to `,i.productName]}),(0,g.jsxs)(`p`,{className:`connect-subtitle`,children:[`Tell `,i.productName,` who you are, then choose a PIN.`]}),(0,g.jsxs)(`form`,{ref:f,onSubmit:p,className:`connect-pin-form`,children:[(0,g.jsxs)(`div`,{className:`pin-input-row`,children:[(0,g.jsx)(`input`,{type:`text`,className:`connect-name-input`,placeholder:`Your full name`,value:m,onChange:e=>h(e.target.value),autoComplete:`name`,autoFocus:!0,required:!0,"aria-label":`Your full name`}),(0,g.jsx)(`div`,{style:{width:38,flexShrink:0},"aria-hidden":`true`})]}),(0,g.jsxs)(`div`,{className:`pin-input-row`,children:[(0,g.jsx)(_,{inputRef:d,value:t,onChange:n,onComplete:()=>{},showPin:r}),(0,g.jsx)(c,{variant:`send`,type:`submit`,disabled:!t||!m.trim(),loading:s,"aria-label":`Set PIN`,children:(0,g.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,g.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,g.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,g.jsx)(u,{checked:r,onChange:()=>a(e=>!e),label:`Show PIN`})]}),l&&(0,g.jsx)(`p`,{className:`admin-pin-error`,children:l})]})})}function y(e){let{pin:t,setPin:n,showPin:r,setShowPin:a,pinLoading:s,pinError:l,pinInputRef:d,onSubmit:f,remoteAuthEnabled:p,onSignOutRemote:m}=e;return(0,g.jsxs)(`div`,{className:`connect-page`,children:[p&&m&&(0,g.jsx)(`button`,{type:`button`,className:`connect-signout`,onClick:m,children:`Sign out`}),(0,g.jsxs)(`div`,{className:`connect-content`,children:[(0,g.jsx)(`img`,{src:o,alt:i.productName,className:`connect-logo connect-logo--maxy`}),!i.logoContainsName&&(0,g.jsx)(`h1`,{className:`connect-title`,children:i.productName}),(0,g.jsxs)(`form`,{onSubmit:f,className:`connect-pin-form`,children:[(0,g.jsxs)(`div`,{className:`pin-input-row`,children:[(0,g.jsx)(_,{inputRef:d,value:t,onChange:n,onComplete:()=>{},showPin:r,autoFocus:!0}),(0,g.jsx)(c,{variant:`send`,type:`submit`,disabled:!t,loading:s,children:(0,g.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,g.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,g.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,g.jsx)(`div`,{className:`pin-options`,children:(0,g.jsx)(u,{checked:r,onChange:()=>a(e=>!e),label:`Show PIN`})})]}),l&&(0,g.jsx)(`p`,{className:`admin-pin-error`,children:l})]})]})}function b(e){let{authPolling:t,setAuthPolling:n,authLoading:r,setAuthLoading:a,pinError:s,setPinError:l,setAppState:u}=e,[d,f]=(0,m.useState)(!1),[p,h]=(0,m.useState)(!1),[_,v]=(0,m.useState)(``),[y,b]=(0,m.useState)(``),[x,S]=(0,m.useState)(``);async function C(){S(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`paste-code`,code:y})})).json();e.accepted?(S(`Code submitted. Finishing sign-in…`),b(``)):S(e.error||`Could not submit code.`)}catch(e){console.error(`[admin] paste-code error:`,e),S(`Could not submit code.`)}}async function w(){h(!0),l(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`launch-browser`})})).json();e.launched?f(!0):e.error&&l(e.error)}catch(e){console.error(`[admin] browser launch error:`,e),l(`Could not launch browser.`)}h(!1)}async function T(){a(!0),l(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`})).json();if(e.started){n(!0),f(!0),a(!1),v(e.transport||``);for(let e=0;e<120;e++)if(await new Promise(e=>setTimeout(e,2e3)),(await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`wait`})})).json()).authenticated){await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`stop`})}),u(`enter-pin`);return}l(`Timed out waiting for sign-in. Try again.`),n(!1)}else e.error&&l(e.error)}catch(e){console.error(`[admin] auth flow error:`,e),l(`Could not start auth flow.`)}a(!1)}async function E(){await fetch(`/api/onboarding/claude-auth`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({action:`stop`})}),n(!1),l(``)}return t||d?(0,g.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100dvh`,overflow:`auto`},children:[(0,g.jsxs)(`header`,{className:`chat-header`,style:{paddingBottom:`12px`,flexShrink:0,position:`relative`,maxWidth:`680px`,width:`100%`,margin:`0 auto`,padding:`24px 20px 12px`},children:[t?(0,g.jsx)(`button`,{onClick:E,style:{position:`absolute`,top:`12px`,right:`12px`,background:`none`,border:`none`,color:`#999`,fontSize:`13px`,cursor:`pointer`,padding:`4px 8px`},"aria-label":`Cancel`,children:`✕`}):(0,g.jsx)(`button`,{onClick:()=>f(!1),style:{position:`absolute`,top:`12px`,right:`12px`,background:`none`,border:`none`,color:`#999`,fontSize:`13px`,cursor:`pointer`,padding:`4px 8px`},"aria-label":`Close browser`,children:`✕`}),(0,g.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`chat-logo`}),(0,g.jsx)(`h1`,{className:`chat-tagline`,children:`Connect Claude`}),(0,g.jsx)(`p`,{className:`chat-intro`,children:t?`Sign in and authorize in the browser below.`:`Open your email or prepare your accounts, then sign in.`}),!t&&(0,g.jsx)(`div`,{style:{marginTop:`12px`},children:(0,g.jsx)(c,{variant:`primary`,onClick:T,disabled:r,children:r?(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`})}),t&&_===`native`&&(0,g.jsxs)(`div`,{style:{marginTop:`14px`,maxWidth:`420px`,margin:`14px auto 0`,display:`flex`,flexDirection:`column`,gap:`8px`},children:[(0,g.jsx)(`label`,{style:{fontSize:`12px`,color:`#999`,lineHeight:1.4},children:`If the browser didn't finish sign-in, paste the code or full redirect URL from Claude's page:`}),(0,g.jsxs)(`div`,{style:{display:`flex`,gap:`8px`},children:[(0,g.jsx)(`input`,{type:`text`,value:y,onChange:e=>b(e.target.value),placeholder:`Paste code or redirect URL`,style:{flex:1,padding:`8px 10px`,fontSize:`13px`,border:`1px solid #ccc`,borderRadius:`6px`}}),(0,g.jsx)(c,{variant:`primary`,onClick:C,disabled:!y.trim(),children:`Submit`})]}),x&&(0,g.jsx)(`p`,{style:{fontSize:`12px`,color:`#999`,margin:0},children:x})]})]}),(0,g.jsx)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,minHeight:0,gap:`10px`,padding:`0 0 16px`},children:(0,g.jsx)(`iframe`,{src:`/vnc-viewer.html`,style:{flex:1,width:`100%`,minHeight:0,border:`none`,background:`#111`,display:`block`},title:`Claude Sign-in`})}),s&&(0,g.jsx)(`p`,{className:`admin-pin-error`,style:{textAlign:`center`,padding:`0 20px 16px`},children:s})]}):(0,g.jsx)(`div`,{className:`connect-page`,children:(0,g.jsxs)(`div`,{className:`connect-content`,children:[(0,g.jsxs)(`div`,{className:`connect-logos`,children:[(0,g.jsx)(`div`,{className:`connect-logo-wrap`,children:(0,g.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`connect-logo`})}),(0,g.jsx)(`svg`,{className:`connect-arrow`,viewBox:`0 0 48 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:(0,g.jsx)(`path`,{d:`M0 12h44m0 0l-8-8m8 8l-8 8`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`})}),(0,g.jsxs)(`div`,{className:`connect-logo-wrap`,children:[(0,g.jsx)(`img`,{src:o,alt:i.productName,className:`connect-logo connect-logo--maxy`}),!i.logoContainsName&&(0,g.jsx)(`span`,{className:`connect-logo-label`,children:i.productName})]})]}),(0,g.jsxs)(`h1`,{className:`connect-title`,children:[`Connect Claude to power `,i.productName]}),(0,g.jsx)(`p`,{className:`connect-subtitle`,children:`Sign in with your Anthropic account to get started.`}),(0,g.jsx)(c,{variant:`primary`,onClick:T,disabled:r,children:r?(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`}),(0,g.jsx)(`p`,{style:{marginTop:`6px`,fontSize:`11px`,color:`#999`,maxWidth:`300px`,textAlign:`center`,lineHeight:`1.4`},children:`First time? You may need to sign into your email and Anthropic account in the browser before connecting.`}),(0,g.jsx)(`button`,{onClick:w,disabled:p,style:{marginTop:`12px`,background:`none`,border:`none`,color:`var(--color-primary, #666)`,fontSize:`13px`,cursor:`pointer`,textDecoration:`underline`,textUnderlineOffset:`3px`},children:p?`Launching…`:`Open browser first`}),s&&(0,g.jsx)(`p`,{className:`admin-pin-error`,children:s})]})})}function x({auth:e}){return e.appState===`loading`?(0,g.jsx)(n,{surface:`gate`}):e.appState===`set-pin`?(0,g.jsx)(v,{pin:e.pin,setPin:e.setPin,showPin:e.showPin,setShowPin:e.setShowPin,pinLoading:e.pinLoading,pinError:e.pinError,pinInputRef:e.pinInputRef,setPinFormRef:e.setPinFormRef,onSubmit:e.handleSetPin,operatorName:e.operatorName,setOperatorName:e.setOperatorName}):e.appState===`connect-claude`?(0,g.jsx)(b,{authPolling:e.authPolling,setAuthPolling:e.setAuthPolling,authLoading:e.authLoading,setAuthLoading:e.setAuthLoading,pinError:e.pinError,setPinError:e.setPinError,setAppState:e.setAppState}):e.appState===`enter-pin`?(0,g.jsx)(y,{pin:e.pin,setPin:e.setPin,showPin:e.showPin,setShowPin:e.setShowPin,pinLoading:e.pinLoading,pinError:e.pinError,pinInputRef:e.pinInputRef,onSubmit:e.handleLogin,remoteAuthEnabled:e.remoteAuthEnabled,onSignOutRemote:()=>{console.info(`[admin-ui] remote-auth sign-out → /__remote-auth/logout`),window.location.href=`/__remote-auth/logout`}}):null}export{h as n,x as t};