@rubytech/create-maxy-code 0.1.476 → 0.1.477

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 (59) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-block-sqlite.test.d.ts +2 -0
  3. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-block-sqlite.test.d.ts.map +1 -0
  4. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-block-sqlite.test.js +150 -0
  5. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-block-sqlite.test.js.map +1 -0
  6. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-block.test.d.ts +2 -0
  7. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-block.test.d.ts.map +1 -0
  8. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-block.test.js +248 -0
  9. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-block.test.js.map +1 -0
  10. package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts +90 -0
  11. package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts.map +1 -1
  12. package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js +105 -0
  13. package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js.map +1 -1
  14. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js +88 -10
  15. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js.map +1 -1
  16. package/payload/platform/scripts/cpu-triage.sh +313 -0
  17. package/payload/server/{chunk-LBCMFD4O.js → chunk-JECAP3Z2.js} +126 -37
  18. package/payload/server/maxy-edge.js +1 -1
  19. package/payload/server/public/activity.html +6 -6
  20. package/payload/server/public/assets/{AdminLoginScreens-DximwPlS.js → AdminLoginScreens-mEKP4pDi.js} +1 -1
  21. package/payload/server/public/assets/{AdminShell-BehbH-Oa.js → AdminShell-BwSaZ88d.js} +1 -1
  22. package/payload/server/public/assets/{Checkbox-DM-eHqOS.js → Checkbox-CN4uQ80w.js} +1 -1
  23. package/payload/server/public/assets/activity-CIQ8ozNZ.js +1 -0
  24. package/payload/server/public/assets/{admin-CAkDnGdk.js → admin-BVhgfgs1.js} +1 -1
  25. package/payload/server/public/assets/{browser-DXl8hOoi.js → browser-D-HMmHcM.js} +1 -1
  26. package/payload/server/public/assets/{calendar-DP6hn4-6.js → calendar-tGWvFyFn.js} +1 -1
  27. package/payload/server/public/assets/chat-DkttVxAz.js +1 -0
  28. package/payload/server/public/assets/chevron-left-CZ4ez9G5.js +1 -0
  29. package/payload/server/public/assets/data-P-mcmnNi.js +1 -0
  30. package/payload/server/public/assets/{graph-labels-CZykslZM.js → graph-labels-qnBleOE6.js} +1 -1
  31. package/payload/server/public/assets/{graph-CHcYoEJ5.js → graph-zEw610xK.js} +1 -1
  32. package/payload/server/public/assets/{maximize-2-31AZEcMS.js → maximize-2-BlTjXT_Y.js} +1 -1
  33. package/payload/server/public/assets/{operator-BGGpdsO_.js → operator-C7oIw2PG.js} +1 -1
  34. package/payload/server/public/assets/{page-DOeiiqbR.js → page-CTP7OFZa.js} +1 -1
  35. package/payload/server/public/assets/{page-BloC6ygA.js → page-DL6Zsdvk.js} +1 -1
  36. package/payload/server/public/assets/{public-CGgO6IZv.js → public-r1A9dqR_.js} +1 -1
  37. package/payload/server/public/assets/{rotate-ccw-BlAi6iFg.js → rotate-ccw-CzkkKx4-.js} +1 -1
  38. package/payload/server/public/assets/{tasks-C1giFRRL.js → tasks-fIJwYFWG.js} +1 -1
  39. package/payload/server/public/assets/{time-entry-format-CiUUQdq7.js → time-entry-format-j669DgXj.js} +1 -1
  40. package/payload/server/public/assets/{triangle-alert-CVqKuLoa.js → triangle-alert-BPgCgIef.js} +1 -1
  41. package/payload/server/public/assets/{useCopyFeedback-ksyUe_g1.js → useCopyFeedback-BmLa2aes.js} +1 -1
  42. package/payload/server/public/assets/{useSelectionMode-BPrBkdTd.js → useSelectionMode-DnnM7A8-.js} +1 -1
  43. package/payload/server/public/assets/{useSubAccountSwitcher-K4kYeN6i.css → useSubAccountSwitcher-C_E8h07P.css} +1 -1
  44. package/payload/server/public/assets/{useVoiceRecorder-CTXP8oTW.js → useVoiceRecorder-u2dwZfen.js} +1 -1
  45. package/payload/server/public/browser.html +5 -5
  46. package/payload/server/public/calendar.html +6 -6
  47. package/payload/server/public/chat.html +12 -12
  48. package/payload/server/public/data.html +11 -11
  49. package/payload/server/public/graph.html +11 -11
  50. package/payload/server/public/index.html +14 -14
  51. package/payload/server/public/operator.html +14 -14
  52. package/payload/server/public/public.html +12 -12
  53. package/payload/server/public/tasks.html +5 -5
  54. package/payload/server/server.js +173 -60
  55. package/payload/server/public/assets/activity-hDwUeQd6.js +0 -1
  56. package/payload/server/public/assets/chat-DhOfVGYM.js +0 -1
  57. package/payload/server/public/assets/chevron-left-DYNBoLii.js +0 -1
  58. package/payload/server/public/assets/data-bq8fTo_s.js +0 -1
  59. /package/payload/server/public/assets/{useSubAccountSwitcher-DzgzTRRn.js → useSubAccountSwitcher-CFa6ZAT1.js} +0 -0
@@ -2658,9 +2658,77 @@ var serve = (options, listeningListener) => {
2658
2658
  };
2659
2659
 
2660
2660
  // server/loop-registry.ts
2661
+ import { readFileSync } from "fs";
2661
2662
  var TAG = "[loop-registry]";
2662
2663
  var STALL_INTERVALS = 3;
2663
2664
  var entries = /* @__PURE__ */ new Map();
2665
+ var defaultCpuIo = {
2666
+ ownCpuUs: () => {
2667
+ const u = process.cpuUsage();
2668
+ return u.user + u.system;
2669
+ },
2670
+ childCpuUs: (pid) => readPidCpuUs(pid)
2671
+ };
2672
+ var cpuIo = defaultCpuIo;
2673
+ function parsePidStatCpuUs(raw2) {
2674
+ const close = raw2.lastIndexOf(")");
2675
+ if (close === -1) return null;
2676
+ const after = raw2.slice(close + 2).split(" ");
2677
+ const utime = Number(after[11]);
2678
+ const stime = Number(after[12]);
2679
+ if (!Number.isFinite(utime) || !Number.isFinite(stime)) return null;
2680
+ return (utime + stime) / 100 * 1e6;
2681
+ }
2682
+ function readPidCpuUs(pid) {
2683
+ if (process.platform !== "linux") return null;
2684
+ try {
2685
+ return parsePidStatCpuUs(readFileSync(`/proc/${pid}/stat`, "utf8"));
2686
+ } catch {
2687
+ return null;
2688
+ }
2689
+ }
2690
+ function sampleCpu(nowMs = Date.now()) {
2691
+ for (const e of entries.values()) {
2692
+ if (!e.cpuAttributable) {
2693
+ e.cpuPct = null;
2694
+ continue;
2695
+ }
2696
+ let childUs = 0;
2697
+ for (const pid of [...e.children]) {
2698
+ const us = cpuIo.childCpuUs(pid);
2699
+ if (us === null) {
2700
+ e.children.delete(pid);
2701
+ continue;
2702
+ }
2703
+ childUs += us;
2704
+ }
2705
+ e.lastChildCpuUs = Math.max(e.lastChildCpuUs, childUs);
2706
+ const totalUs = e.cumulativeCpuUs + e.lastChildCpuUs;
2707
+ const p = e.prior;
2708
+ if (p) {
2709
+ const wallUs = (nowMs - p.atMs) * 1e3;
2710
+ e.cpuPct = wallUs > 0 && totalUs >= p.cpuUs ? (totalUs - p.cpuUs) / wallUs * 100 : null;
2711
+ } else {
2712
+ e.cpuPct = null;
2713
+ }
2714
+ e.prior = { cpuUs: totalUs, atMs: nowMs };
2715
+ }
2716
+ }
2717
+ var processPrior = null;
2718
+ function sampleProcessCpu(nowMs = Date.now()) {
2719
+ const cpuUs = cpuIo.ownCpuUs();
2720
+ let processPct = null;
2721
+ if (processPrior) {
2722
+ const wallUs = (nowMs - processPrior.atMs) * 1e3;
2723
+ if (wallUs > 0) processPct = (cpuUs - processPrior.cpuUs) / wallUs * 100;
2724
+ }
2725
+ processPrior = { cpuUs, atMs: nowMs };
2726
+ const rows = [...entries.values()];
2727
+ const measured = rows.filter((e) => e.cpuPct !== null);
2728
+ const attributedPct = measured.length === 0 ? null : measured.reduce((sum, e) => sum + (e.cpuPct ?? 0), 0);
2729
+ const unattributedPct = processPct === null || attributedPct === null ? null : Math.max(0, processPct - attributedPct);
2730
+ return { processPct, attributedPct, unattributedPct };
2731
+ }
2664
2732
  function messageOf(err) {
2665
2733
  return err instanceof Error ? err.message : String(err);
2666
2734
  }
@@ -2695,20 +2763,29 @@ function invoke(e) {
2695
2763
  e.lastStartMs = Date.now();
2696
2764
  const startedAt = e.lastStartMs;
2697
2765
  const cpuStart = process.cpuUsage();
2766
+ const ownStartUs = cpuIo.ownCpuUs();
2767
+ const ctx = {
2768
+ child: (pid) => {
2769
+ if (typeof pid === "number" && Number.isFinite(pid)) e.children.add(pid);
2770
+ }
2771
+ };
2698
2772
  let result;
2699
2773
  try {
2700
- result = e.spec.run();
2774
+ result = e.spec.run(ctx);
2701
2775
  } catch (err) {
2776
+ e.cumulativeCpuUs += Math.max(0, cpuIo.ownCpuUs() - ownStartUs);
2702
2777
  finish(e, startedAt, cpuStart, true, null, err);
2703
2778
  return;
2704
2779
  }
2705
2780
  if (result instanceof Promise) {
2781
+ e.cpuAttributable = false;
2706
2782
  result.then(
2707
2783
  (note) => finish(e, startedAt, cpuStart, false, note, null),
2708
2784
  (err) => finish(e, startedAt, cpuStart, false, null, err)
2709
2785
  );
2710
2786
  return;
2711
2787
  }
2788
+ e.cumulativeCpuUs += Math.max(0, cpuIo.ownCpuUs() - ownStartUs);
2712
2789
  finish(e, startedAt, cpuStart, true, result, null);
2713
2790
  }
2714
2791
  function registerLoop(spec) {
@@ -2728,7 +2805,13 @@ function registerLoop(spec) {
2728
2805
  successCount: 0,
2729
2806
  consecutiveFailures: 0,
2730
2807
  running: false,
2731
- timers: []
2808
+ timers: [],
2809
+ cumulativeCpuUs: 0,
2810
+ cpuAttributable: true,
2811
+ children: /* @__PURE__ */ new Set(),
2812
+ lastChildCpuUs: 0,
2813
+ prior: null,
2814
+ cpuPct: null
2732
2815
  };
2733
2816
  entries.set(spec.name, e);
2734
2817
  const interval = setInterval(() => invoke(e), spec.intervalMs);
@@ -2754,7 +2837,9 @@ function registerLoop(spec) {
2754
2837
  };
2755
2838
  }
2756
2839
  function stateOf(e, nowMs) {
2757
- if (e.lastStartMs === null) return "never-run";
2840
+ if (e.lastStartMs === null) {
2841
+ return nowMs - e.armedAtMs < e.spec.intervalMs ? "waiting" : "never-run";
2842
+ }
2758
2843
  const overdue = nowMs - e.lastStartMs > e.spec.intervalMs * STALL_INTERVALS;
2759
2844
  if (overdue) return "stalled";
2760
2845
  if (e.running) return "running";
@@ -2776,6 +2861,8 @@ function listLoops(nowMs = Date.now()) {
2776
2861
  lastStartMs: e.lastStartMs,
2777
2862
  lastDurationMs: e.lastDurationMs,
2778
2863
  lastCpuMs: e.lastCpuMs,
2864
+ cpuPct: e.cpuPct,
2865
+ cpuAttributable: e.cpuAttributable,
2779
2866
  lastOutcome: e.lastOutcome,
2780
2867
  lastError: e.lastError,
2781
2868
  lastNote: e.lastNote,
@@ -2794,7 +2881,7 @@ function armedCount() {
2794
2881
  // app/lib/paths.ts
2795
2882
  import { homedir } from "os";
2796
2883
  import { resolve, join } from "path";
2797
- import { existsSync, readFileSync } from "fs";
2884
+ import { existsSync, readFileSync as readFileSync2 } from "fs";
2798
2885
  var configDirName = ".maxy";
2799
2886
  var commercialMode = false;
2800
2887
  var bundleMode = "none";
@@ -2810,7 +2897,7 @@ if (platformRoot) {
2810
2897
  if (existsSync(brandPath)) {
2811
2898
  let brand;
2812
2899
  try {
2813
- brand = JSON.parse(readFileSync(brandPath, "utf-8"));
2900
+ brand = JSON.parse(readFileSync2(brandPath, "utf-8"));
2814
2901
  } catch (err) {
2815
2902
  const detail = (err instanceof Error ? err.message : String(err)).slice(0, 160);
2816
2903
  console.error(`[paths] error reason=brand-config-missing path=${brandPath} detail="parse failed: ${detail.replace(/"/g, "'")}"`);
@@ -2926,7 +3013,7 @@ function websockifyLog(event, fields = {}) {
2926
3013
 
2927
3014
  // ../lib/admin-access-password/src/index.ts
2928
3015
  import { scrypt, randomBytes, timingSafeEqual } from "crypto";
2929
- import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync, renameSync, unlinkSync, appendFileSync as appendFileSync2, mkdirSync as mkdirSync2 } from "fs";
3016
+ import { existsSync as existsSync2, readFileSync as readFileSync3, writeFileSync, renameSync, unlinkSync, appendFileSync as appendFileSync2, mkdirSync as mkdirSync2 } from "fs";
2930
3017
  import { dirname } from "path";
2931
3018
  var SCRYPT_N = 16384;
2932
3019
  var SCRYPT_R = 8;
@@ -2982,7 +3069,7 @@ async function matchesHash(password, stored) {
2982
3069
  }
2983
3070
  function readUsers(usersFile) {
2984
3071
  if (!existsSync2(usersFile)) return [];
2985
- const raw2 = readFileSync2(usersFile, "utf-8").trim();
3072
+ const raw2 = readFileSync3(usersFile, "utf-8").trim();
2986
3073
  if (!raw2) return [];
2987
3074
  const parsed = JSON.parse(raw2);
2988
3075
  if (!Array.isArray(parsed)) throw new Error("users.json is not an array");
@@ -3054,7 +3141,7 @@ function accessStoreUnreadable(usersFile) {
3054
3141
  }
3055
3142
  function migrateLegacyRemotePassword(usersFile, legacyFile, ownerUserId, audit) {
3056
3143
  if (!existsSync2(legacyFile)) return "noop-no-legacy";
3057
- const legacy = readFileSync2(legacyFile, "utf-8").trim();
3144
+ const legacy = readFileSync3(legacyFile, "utf-8").trim();
3058
3145
  const users = readUsers(usersFile);
3059
3146
  const idx = users.findIndex((u) => u.userId === ownerUserId);
3060
3147
  if (idx === -1) return "noop-no-owner";
@@ -3076,7 +3163,7 @@ function migrateLegacyRemotePassword(usersFile, legacyFile, ownerUserId, audit)
3076
3163
  }
3077
3164
  function readLegacyRemoteHash(legacyFile) {
3078
3165
  if (!existsSync2(legacyFile)) return null;
3079
- const raw2 = readFileSync2(legacyFile, "utf-8").trim();
3166
+ const raw2 = readFileSync3(legacyFile, "utf-8").trim();
3080
3167
  return raw2.includes(":") ? raw2 : null;
3081
3168
  }
3082
3169
 
@@ -3095,7 +3182,7 @@ function isPasswordValid(password) {
3095
3182
 
3096
3183
  // app/lib/remote-auth.ts
3097
3184
  import { scrypt as scrypt2, randomBytes as randomBytes2, timingSafeEqual as timingSafeEqual2, createHmac } from "crypto";
3098
- import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync3 } from "fs";
3185
+ import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, mkdirSync as mkdirSync3 } from "fs";
3099
3186
  import { dirname as dirname2 } from "path";
3100
3187
  var SCRYPT_N2 = 16384;
3101
3188
  var SCRYPT_R2 = 8;
@@ -3141,7 +3228,7 @@ var cachedSecret = null;
3141
3228
  function getSecret() {
3142
3229
  if (cachedSecret) return cachedSecret;
3143
3230
  try {
3144
- const hex2 = readFileSync3(REMOTE_SESSION_SECRET_FILE, "utf-8").trim();
3231
+ const hex2 = readFileSync4(REMOTE_SESSION_SECRET_FILE, "utf-8").trim();
3145
3232
  if (hex2.length === SECRET_BYTES * 2) {
3146
3233
  cachedSecret = Buffer.from(hex2, "hex");
3147
3234
  return cachedSecret;
@@ -3154,7 +3241,7 @@ function getSecret() {
3154
3241
  writeFileSync2(REMOTE_SESSION_SECRET_FILE, fresh, { mode: 384, flag: "wx" });
3155
3242
  } catch {
3156
3243
  }
3157
- const hex = readFileSync3(REMOTE_SESSION_SECRET_FILE, "utf-8").trim();
3244
+ const hex = readFileSync4(REMOTE_SESSION_SECRET_FILE, "utf-8").trim();
3158
3245
  cachedSecret = Buffer.from(hex, "hex");
3159
3246
  return cachedSecret;
3160
3247
  }
@@ -3819,13 +3906,13 @@ function classifyHost(host, operatorDomains2, isPublicHost) {
3819
3906
  import { watchFile } from "fs";
3820
3907
 
3821
3908
  // app/lib/operator-domains.ts
3822
- import { existsSync as existsSync3, mkdirSync as mkdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
3909
+ import { existsSync as existsSync3, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "fs";
3823
3910
  import { dirname as dirname3, resolve as resolve3 } from "path";
3824
3911
  var OPERATOR_DOMAINS_PATH = resolve3(MAXY_DIR, "operator-domains.json");
3825
3912
  function loadOperatorDomains() {
3826
3913
  if (!existsSync3(OPERATOR_DOMAINS_PATH)) return /* @__PURE__ */ new Set();
3827
3914
  try {
3828
- const parsed = JSON.parse(readFileSync4(OPERATOR_DOMAINS_PATH, "utf-8"));
3915
+ const parsed = JSON.parse(readFileSync5(OPERATOR_DOMAINS_PATH, "utf-8"));
3829
3916
  if (!Array.isArray(parsed)) return /* @__PURE__ */ new Set();
3830
3917
  return new Set(parsed.filter((h) => typeof h === "string"));
3831
3918
  } catch {
@@ -3852,11 +3939,11 @@ function getOperatorDomains() {
3852
3939
 
3853
3940
  // app/lib/claude-agent/account.ts
3854
3941
  import { resolve as resolve4 } from "path";
3855
- import { readFileSync as readFileSync6, readdirSync, existsSync as existsSync5, statSync } from "fs";
3942
+ import { readFileSync as readFileSync7, readdirSync, existsSync as existsSync5, statSync } from "fs";
3856
3943
 
3857
3944
  // ../lib/brand-templating/src/index.ts
3858
3945
  import { join as join2 } from "path";
3859
- import { existsSync as existsSync4, readFileSync as readFileSync5 } from "fs";
3946
+ import { existsSync as existsSync4, readFileSync as readFileSync6 } from "fs";
3860
3947
  var PLACEHOLDER = "{{productName}}";
3861
3948
  var cachedProductName = null;
3862
3949
  function brandJsonPath() {
@@ -3876,7 +3963,7 @@ function getBrandProductName() {
3876
3963
  }
3877
3964
  let parsed;
3878
3965
  try {
3879
- parsed = JSON.parse(readFileSync5(path, "utf-8"));
3966
+ parsed = JSON.parse(readFileSync6(path, "utf-8"));
3880
3967
  } catch (err) {
3881
3968
  throw new Error(
3882
3969
  `[skill-loader] brand.json unreadable at ${path}: ${err instanceof Error ? err.message : String(err)}`
@@ -3940,7 +4027,7 @@ function listValidAccounts() {
3940
4027
  }
3941
4028
  let config;
3942
4029
  try {
3943
- config = JSON.parse(readFileSync6(configPath, "utf-8"));
4030
+ config = JSON.parse(readFileSync7(configPath, "utf-8"));
3944
4031
  } catch {
3945
4032
  console.error(
3946
4033
  `[platform] accounts-state CORRUPT-JSON id=${entry.name} \u2014 account.json failed to parse; treating as stub`
@@ -3959,7 +4046,7 @@ function resolveAccount() {
3959
4046
  let usersJsonUserId = null;
3960
4047
  if (existsSync5(USERS_FILE)) {
3961
4048
  try {
3962
- const raw2 = readFileSync6(USERS_FILE, "utf-8").trim();
4049
+ const raw2 = readFileSync7(USERS_FILE, "utf-8").trim();
3963
4050
  if (raw2) {
3964
4051
  const users = JSON.parse(raw2);
3965
4052
  if (users.length > 0) {
@@ -3975,7 +4062,7 @@ function resolveAccount() {
3975
4062
  if (!entry.isDirectory()) continue;
3976
4063
  const configPath = resolve4(ACCOUNTS_DIR, entry.name, "account.json");
3977
4064
  if (!existsSync5(configPath)) continue;
3978
- const raw2 = readFileSync6(configPath, "utf-8");
4065
+ const raw2 = readFileSync7(configPath, "utf-8");
3979
4066
  let config;
3980
4067
  try {
3981
4068
  config = JSON.parse(raw2);
@@ -4010,7 +4097,7 @@ function resolveAccount() {
4010
4097
  function readAgentFile(accountDir, agentName, filename) {
4011
4098
  const filePath = resolve4(accountDir, "agents", agentName, filename);
4012
4099
  if (!existsSync5(filePath)) return null;
4013
- const raw2 = readFileSync6(filePath, "utf-8");
4100
+ const raw2 = readFileSync7(filePath, "utf-8");
4014
4101
  if (filename.endsWith(".md")) {
4015
4102
  return substituteBrandPlaceholders(raw2, filePath);
4016
4103
  }
@@ -4039,7 +4126,7 @@ function resolveDefaultAgentSlug(accountDir) {
4039
4126
  }
4040
4127
  let config;
4041
4128
  try {
4042
- config = JSON.parse(readFileSync6(configPath, "utf-8"));
4129
+ config = JSON.parse(readFileSync7(configPath, "utf-8"));
4043
4130
  } catch (err) {
4044
4131
  console.error("[agent-resolve] failed to read account.json:", err);
4045
4132
  return null;
@@ -4114,14 +4201,14 @@ function resolveAgentConfig(accountDir, agentName) {
4114
4201
  const knowledgeMtime = statSync(knowledgePath).mtimeMs;
4115
4202
  const summaryMtime = statSync(summaryPath).mtimeMs;
4116
4203
  if (summaryMtime >= knowledgeMtime) {
4117
- knowledge = readFileSync6(summaryPath, "utf-8");
4204
+ knowledge = readFileSync7(summaryPath, "utf-8");
4118
4205
  } else {
4119
4206
  console.warn(`[agent-config] ${agentName}: KNOWLEDGE-SUMMARY.md is stale (KNOWLEDGE.md is newer) \u2014 using full knowledge`);
4120
- knowledge = readFileSync6(knowledgePath, "utf-8");
4207
+ knowledge = readFileSync7(knowledgePath, "utf-8");
4121
4208
  }
4122
4209
  knowledgeBaked = true;
4123
4210
  } else if (hasKnowledge) {
4124
- knowledge = readFileSync6(knowledgePath, "utf-8");
4211
+ knowledge = readFileSync7(knowledgePath, "utf-8");
4125
4212
  knowledgeBaked = true;
4126
4213
  }
4127
4214
  let budget = null;
@@ -4215,7 +4302,7 @@ function getSessionKeyBySessionId(_sessionId) {
4215
4302
  // app/lib/claude-agent/plugin-manifest.ts
4216
4303
  import { resolve as resolve5, join as join3 } from "path";
4217
4304
  import {
4218
- readFileSync as readFileSync7,
4305
+ readFileSync as readFileSync8,
4219
4306
  writeFileSync as writeFileSync4,
4220
4307
  readdirSync as readdirSync2,
4221
4308
  existsSync as existsSync6,
@@ -4237,7 +4324,7 @@ function readBundleSubPlugins(bundlePath) {
4237
4324
  if (!existsSync6(bundlePath)) return [];
4238
4325
  let raw2;
4239
4326
  try {
4240
- raw2 = readFileSync7(bundlePath, "utf-8");
4327
+ raw2 = readFileSync8(bundlePath, "utf-8");
4241
4328
  } catch {
4242
4329
  return [];
4243
4330
  }
@@ -4310,8 +4397,8 @@ function reapDuplicateFlatPremiumSubs(bundles, stagingRoot, pluginsDir) {
4310
4397
  const flatDir = resolve5(pluginsDir, sub);
4311
4398
  const flatManifest = resolve5(flatDir, "PLUGIN.md");
4312
4399
  if (!existsSync6(premiumManifest) || !existsSync6(flatManifest)) continue;
4313
- const premiumSha = createHash2("sha256").update(readFileSync7(premiumManifest)).digest("hex");
4314
- const flatSha = createHash2("sha256").update(readFileSync7(flatManifest)).digest("hex");
4400
+ const premiumSha = createHash2("sha256").update(readFileSync8(premiumManifest)).digest("hex");
4401
+ const flatSha = createHash2("sha256").update(readFileSync8(flatManifest)).digest("hex");
4315
4402
  if (isBundle) {
4316
4403
  if (premiumSha === flatSha) {
4317
4404
  try {
@@ -4373,7 +4460,7 @@ function reconcileEnabledPlugins(accountDir, config, accountId) {
4373
4460
  const merged = [...currentSet];
4374
4461
  const configPath = resolve5(accountDir, "account.json");
4375
4462
  try {
4376
- const raw2 = readFileSync7(configPath, "utf-8");
4463
+ const raw2 = readFileSync8(configPath, "utf-8");
4377
4464
  const parsed = JSON.parse(raw2);
4378
4465
  parsed.enabledPlugins = merged;
4379
4466
  writeFileSync4(configPath, JSON.stringify(parsed, null, 2) + "\n");
@@ -4409,7 +4496,7 @@ function cleanupLeakedPremiumSubs(accountDir, config, accountId) {
4409
4496
  if (removed.length === 0) return;
4410
4497
  const configPath = resolve5(accountDir, "account.json");
4411
4498
  try {
4412
- const raw2 = readFileSync7(configPath, "utf-8");
4499
+ const raw2 = readFileSync8(configPath, "utf-8");
4413
4500
  const parsed = JSON.parse(raw2);
4414
4501
  parsed.enabledPlugins = kept;
4415
4502
  writeFileSync4(configPath, JSON.stringify(parsed, null, 2) + "\n");
@@ -4460,7 +4547,7 @@ function requirePortEnv(envName, options = {}) {
4460
4547
  // app/lib/neo4j-store.ts
4461
4548
  import neo4j from "neo4j-driver";
4462
4549
  import { randomUUID } from "crypto";
4463
- import { readFileSync as readFileSync8, readdirSync as readdirSync3, existsSync as existsSync7, openSync, readSync, closeSync, statSync as statSync3 } from "fs";
4550
+ import { readFileSync as readFileSync9, readdirSync as readdirSync3, existsSync as existsSync7, openSync, readSync, closeSync, statSync as statSync3 } from "fs";
4464
4551
  import { resolve as resolve6 } from "path";
4465
4552
  var PLATFORM_ROOT3 = process.env.MAXY_PLATFORM_ROOT ?? resolve6(process.cwd(), "..");
4466
4553
  var driver = null;
@@ -4468,7 +4555,7 @@ function readPassword() {
4468
4555
  if (process.env.NEO4J_PASSWORD) return process.env.NEO4J_PASSWORD;
4469
4556
  const passwordFile = resolve6(PLATFORM_ROOT3, "config/.neo4j-password");
4470
4557
  try {
4471
- return readFileSync8(passwordFile, "utf-8").trim();
4558
+ return readFileSync9(passwordFile, "utf-8").trim();
4472
4559
  } catch {
4473
4560
  throw new Error(
4474
4561
  `Neo4j password not found. Expected at ${passwordFile} or in NEO4J_PASSWORD env var.`
@@ -5585,7 +5672,7 @@ function loadEnabledPluginProfileKeys(accountId) {
5585
5672
  if (!existsSync7(accountFile)) return {};
5586
5673
  let enabled;
5587
5674
  try {
5588
- const raw2 = readFileSync8(accountFile, "utf-8");
5675
+ const raw2 = readFileSync9(accountFile, "utf-8");
5589
5676
  const parsed = JSON.parse(raw2);
5590
5677
  enabled = Array.isArray(parsed.enabledPlugins) ? parsed.enabledPlugins.filter((p) => typeof p === "string") : [];
5591
5678
  } catch (err) {
@@ -5600,7 +5687,7 @@ function loadEnabledPluginProfileKeys(accountId) {
5600
5687
  if (!existsSync7(manifestPath)) continue;
5601
5688
  let manifest;
5602
5689
  try {
5603
- manifest = readFileSync8(manifestPath, "utf-8");
5690
+ manifest = readFileSync9(manifestPath, "utf-8");
5604
5691
  } catch {
5605
5692
  continue;
5606
5693
  }
@@ -5858,11 +5945,11 @@ async function projectAgent(accountId, accountDir, slug) {
5858
5945
  );
5859
5946
  return;
5860
5947
  }
5861
- config = JSON.parse(readFileSync8(configPath, "utf-8"));
5948
+ config = JSON.parse(readFileSync9(configPath, "utf-8"));
5862
5949
  for (const { filename, role } of AGENT_FILE_ROLES) {
5863
5950
  const filePath = resolve6(agentDir, filename);
5864
5951
  if (!existsSync7(filePath)) continue;
5865
- const body = readFileSync8(filePath, "utf-8");
5952
+ const body = readFileSync9(filePath, "utf-8");
5866
5953
  presentRoles.push({ role, body, edge: ROLE_TO_EDGE[role] });
5867
5954
  }
5868
5955
  } catch (err) {
@@ -6112,6 +6199,8 @@ export {
6112
6199
  Hono2 as Hono,
6113
6200
  getRequestListener,
6114
6201
  serve,
6202
+ sampleCpu,
6203
+ sampleProcessCpu,
6115
6204
  registerLoop,
6116
6205
  listLoops,
6117
6206
  armedCount,
@@ -16,7 +16,7 @@ import {
16
16
  sanitizeClientCorrId,
17
17
  vncLog,
18
18
  websockifyLog
19
- } from "./chunk-LBCMFD4O.js";
19
+ } from "./chunk-JECAP3Z2.js";
20
20
  import "./chunk-PFF6I7KP.js";
21
21
 
22
22
  // server/edge.ts
@@ -5,13 +5,13 @@
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-hDwUeQd6.js"></script>
8
+ <script type="module" crossorigin src="/assets/activity-CIQ8ozNZ.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-TPjIAO9U.js">
10
- <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-DzgzTRRn.js">
11
- <link rel="modulepreload" crossorigin href="/assets/useSelectionMode-BPrBkdTd.js">
12
- <link rel="modulepreload" crossorigin href="/assets/AdminShell-BehbH-Oa.js">
13
- <link rel="modulepreload" crossorigin href="/assets/triangle-alert-CVqKuLoa.js">
14
- <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-K4kYeN6i.css">
10
+ <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-CFa6ZAT1.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/useSelectionMode-DnnM7A8-.js">
12
+ <link rel="modulepreload" crossorigin href="/assets/AdminShell-BwSaZ88d.js">
13
+ <link rel="modulepreload" crossorigin href="/assets/triangle-alert-BPgCgIef.js">
14
+ <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-C_E8h07P.css">
15
15
  </head>
16
16
  <body>
17
17
  <div id="root"></div>
@@ -1 +1 @@
1
- import{o as e}from"./chunk-TPjIAO9U.js";import{C as t,D as n,S as r,b as i,v as a}from"./useSubAccountSwitcher-DzgzTRRn.js";import{E as o}from"./useVoiceRecorder-CTXP8oTW.js";import{v as s,y as c}from"./AdminShell-BehbH-Oa.js";import{t as l}from"./Checkbox-DM-eHqOS.js";var u=`admin-landing-redirected`,d=`/graph`;function f(e){return e.variant===`operator`?!1:e.appState===`chat`&&!e.alreadyRedirected}var p=e(n(),1);function m(e=`admin`){let[n,r]=(0,p.useState)(`loading`),[i,a]=(0,p.useState)(``),[s,l]=(0,p.useState)(``),[m,h]=(0,p.useState)(``),[g,_]=(0,p.useState)(!1),[v,y]=(0,p.useState)(!1),[b,x]=(0,p.useState)(!1),[S,C]=(0,p.useState)(!1),[w,T]=(0,p.useState)(!1),[E,D]=(0,p.useState)(null),[O,k]=(0,p.useState)(null),[A,j]=(0,p.useState)(void 0),[M,N]=(0,p.useState)(null),[P,F]=(0,p.useState)(void 0),[I,L]=(0,p.useState)(null),[R,z]=(0,p.useState)(null),[B,V]=(0,p.useState)(void 0),H=(0,p.useRef)(void 0),[U,W]=(0,p.useState)(!1),[G,K]=(0,p.useState)(!0);(0,p.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,p.useRef)(null),J=(0,p.useRef)(null);(0,p.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 n=await t.json();D(n.session_key),z(n.sessionId??null),j(n.businessName),N(n.role??null),F(n.userName===void 0?null:n.userName),L(n.avatar??null);let i=o(n.thinkingView);return H.current=i,V(i),r(`chat`),!0}catch(e){return console.error(`[admin] session restore failed:`,e),!1}}async function t(n=2){try{let i=await fetch(`/api/health`);if(!i.ok){if(n>0)return await new Promise(e=>setTimeout(e,1500)),t(n-1);console.error(`[admin] health check returned ${i.status} after retries`),r(`set-pin`);return}let a=await i.json();if(!a.pin_configured){r(`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){r(`connect-claude`);return}}if(await e())return;r(`enter-pin`)}catch(e){if(n>0)return await new Promise(e=>setTimeout(e,1500)),t(n-1);console.error(`[admin] health check failed:`,e),r(`set-pin`)}}t()},[]),(0,p.useEffect)(()=>{n===`chat`&&fetch(`/api/admin/claude-info`).then(e=>{if(e.ok)return e.json()}).then(e=>{e&&k(e)}).catch(()=>{})},[n]),(0,p.useEffect)(()=>{if(typeof window>`u`)return;let t=!1;try{t=sessionStorage.getItem(u)===`1`}catch{}if(f({appState:n,alreadyRedirected:t,variant:e})){try{sessionStorage.setItem(u,`1`)}catch{}console.info(`[admin-ui] landing-redirect target=${d}`),window.location.replace(d)}},[n,e]);let Y=(0,p.useRef)(null);(0,p.useEffect)(()=>{if(n!==`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 n=(await e.clone().json().catch(()=>null))?.code??`unknown-401`;if(n===`remote-auth-required`){t(`heartbeat`,`/api/admin/session`);return}console.warn(`[admin-auth] outcome=heartbeat-detected-expiry code=${n}`),Y.current?.()}catch{}},300*1e3);return()=>clearInterval(e)},[n,E]),(0,p.useEffect)(()=>{n===`connect-claude`&&fetch(`/api/health`).then(e=>e.ok?e.json():null).then(e=>{e?.claude_authenticated&&(K(!0),r(`enter-pin`))}).catch(()=>{})},[n]);async function X(e,n){y(!0);try{let i=await fetch(`/api/admin/session`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pin:e,...n?{accountId:n}:{}})});if(!i.ok){let e=await i.json().catch(()=>({}));if(i.status===401&&e?.code===`remote-auth-required`){t(`enter-pin`,`/api/admin/session`);return}h(e.error||`Invalid PIN`);return}let s=await i.json();D(s.session_key),z(s.sessionId??null),j(s.businessName),N(s.role??null),F(s.userName===void 0?null:s.userName),L(s.avatar??null);let c=o(s.thinkingView);H.current=c,V(c);try{sessionStorage.setItem(`maxy-admin-session-key`,s.session_key)}catch{}a(``),r(`chat`)}catch(e){console.error(`[admin] connection error:`,e),h(`Could not connect.`)}finally{y(!1)}}let Z=(0,p.useCallback)(async e=>{if(e.preventDefault(),v)return;h(``);let n=s.trim();if(!n){h(`Please enter your name.`);return}if(i.length<4){h(`PIN must be at least 4 characters.`);return}let o=i;y(!0);try{let e=await fetch(`/api/onboarding/set-pin`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pin:o,name:n})});if(!e.ok){let n=await e.json().catch(()=>({}));if(e.status===401&&n?.code===`remote-auth-required`){t(`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 t=await e.json();t.pin_configured&&t.claude_authenticated?r(`enter-pin`):t.pin_configured?r(`connect-claude`):h(n.error||`Failed to set PIN.`)}else r(`enter-pin`)}catch{r(`enter-pin`)}return}h(n.error||`Failed to set PIN.`);return}let i=await fetch(`/api/health`);if((i.ok?await i.json():null)?.claude_authenticated){await X(o);return}a(``),r(`connect-claude`)}catch(e){console.error(`[admin] connection error:`,e),h(`Could not connect.`)}finally{y(!1)}},[i,v,s]),Q=(0,p.useCallback)(async e=>{e.preventDefault(),h(``),await X(i)},[i]),ee=(0,p.useCallback)(async()=>{T(!0);try{if(!await c())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(u)}catch{}return r(`connect-claude`),!0}finally{T(!1)}},[]),$=(0,p.useCallback)(()=>{D(null),N(null),F(void 0),L(null);try{sessionStorage.removeItem(`maxy-admin-session-key`),sessionStorage.removeItem(u)}catch{}a(``),h(``),r(`enter-pin`)},[]);return(0,p.useEffect)(()=>{Y.current=$},[$]),{appState:n,setAppState:r,pin:i,setPin:a,operatorName:s,setOperatorName:l,pinError:m,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 h=r();function g({inputRef:e,value:t,onChange:n,onComplete:r,showPin:i,autoFocus:a}){let o=(0,p.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,h.jsx)(`div`,{className:`pin-field`,children:Array.from({length:6}).map((n,r)=>(0,h.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 _(e){let{pin:t,setPin:n,showPin:r,setShowPin:o,pinLoading:c,pinError:u,pinInputRef:d,setPinFormRef:f,onSubmit:p,operatorName:m,setOperatorName:_}=e;return(0,h.jsx)(`div`,{className:`connect-page`,children:(0,h.jsxs)(`div`,{className:`connect-content`,children:[(0,h.jsx)(`img`,{src:i,alt:a.productName,className:`connect-logo connect-logo--maxy`}),!a.logoContainsName&&(0,h.jsxs)(`h1`,{className:`connect-title`,children:[`Welcome to `,a.productName]}),(0,h.jsxs)(`p`,{className:`connect-subtitle`,children:[`Tell `,a.productName,` who you are, then choose a PIN.`]}),(0,h.jsxs)(`form`,{ref:f,onSubmit:p,className:`connect-pin-form`,children:[(0,h.jsxs)(`div`,{className:`pin-input-row`,children:[(0,h.jsx)(`input`,{type:`text`,className:`connect-name-input`,placeholder:`Your full name`,value:m,onChange:e=>_(e.target.value),autoComplete:`name`,autoFocus:!0,required:!0,"aria-label":`Your full name`}),(0,h.jsx)(`div`,{style:{width:38,flexShrink:0},"aria-hidden":`true`})]}),(0,h.jsxs)(`div`,{className:`pin-input-row`,children:[(0,h.jsx)(g,{inputRef:d,value:t,onChange:n,onComplete:()=>{},showPin:r}),(0,h.jsx)(s,{variant:`send`,type:`submit`,disabled:!t||!m.trim(),loading:c,"aria-label":`Set PIN`,children:(0,h.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,h.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,h.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,h.jsx)(l,{checked:r,onChange:()=>o(e=>!e),label:`Show PIN`})]}),u&&(0,h.jsx)(`p`,{className:`admin-pin-error`,children:u})]})})}function v(e){let{pin:t,setPin:n,showPin:r,setShowPin:o,pinLoading:c,pinError:u,pinInputRef:d,onSubmit:f,remoteAuthEnabled:p,onSignOutRemote:m}=e;return(0,h.jsxs)(`div`,{className:`connect-page`,children:[p&&m&&(0,h.jsx)(`button`,{type:`button`,className:`connect-signout`,onClick:m,children:`Sign out`}),(0,h.jsxs)(`div`,{className:`connect-content`,children:[(0,h.jsx)(`img`,{src:i,alt:a.productName,className:`connect-logo connect-logo--maxy`}),!a.logoContainsName&&(0,h.jsx)(`h1`,{className:`connect-title`,children:a.productName}),(0,h.jsxs)(`form`,{onSubmit:f,className:`connect-pin-form`,children:[(0,h.jsxs)(`div`,{className:`pin-input-row`,children:[(0,h.jsx)(g,{inputRef:d,value:t,onChange:n,onComplete:()=>{},showPin:r,autoFocus:!0}),(0,h.jsx)(s,{variant:`send`,type:`submit`,disabled:!t,loading:c,children:(0,h.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,h.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,h.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,h.jsx)(`div`,{className:`pin-options`,children:(0,h.jsx)(l,{checked:r,onChange:()=>o(e=>!e),label:`Show PIN`})})]}),u&&(0,h.jsx)(`p`,{className:`admin-pin-error`,children:u})]})]})}function y(e){let{authPolling:t,setAuthPolling:n,authLoading:r,setAuthLoading:o,pinError:c,setPinError:l,setAppState:u}=e,[d,f]=(0,p.useState)(!1),[m,g]=(0,p.useState)(!1),[_,v]=(0,p.useState)(``),[y,b]=(0,p.useState)(``),[x,S]=(0,p.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(){g(!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.`)}g(!1)}async function T(){o(!0),l(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`})).json();if(e.started){n(!0),f(!0),o(!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.`)}o(!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,h.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100dvh`,overflow:`auto`},children:[(0,h.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,h.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,h.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,h.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`chat-logo`}),(0,h.jsx)(`h1`,{className:`chat-tagline`,children:`Connect Claude`}),(0,h.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,h.jsx)(`div`,{style:{marginTop:`12px`},children:(0,h.jsx)(s,{variant:`primary`,onClick:T,disabled:r,children:r?(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`})}),t&&_===`native`&&(0,h.jsxs)(`div`,{style:{marginTop:`14px`,maxWidth:`420px`,margin:`14px auto 0`,display:`flex`,flexDirection:`column`,gap:`8px`},children:[(0,h.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,h.jsxs)(`div`,{style:{display:`flex`,gap:`8px`},children:[(0,h.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,h.jsx)(s,{variant:`primary`,onClick:C,disabled:!y.trim(),children:`Submit`})]}),x&&(0,h.jsx)(`p`,{style:{fontSize:`12px`,color:`#999`,margin:0},children:x})]})]}),(0,h.jsx)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,minHeight:0,gap:`10px`,padding:`0 0 16px`},children:(0,h.jsx)(`iframe`,{src:`/vnc-viewer.html`,style:{flex:1,width:`100%`,minHeight:0,border:`none`,background:`#111`,display:`block`},title:`Claude Sign-in`})}),c&&(0,h.jsx)(`p`,{className:`admin-pin-error`,style:{textAlign:`center`,padding:`0 20px 16px`},children:c})]}):(0,h.jsx)(`div`,{className:`connect-page`,children:(0,h.jsxs)(`div`,{className:`connect-content`,children:[(0,h.jsxs)(`div`,{className:`connect-logos`,children:[(0,h.jsx)(`div`,{className:`connect-logo-wrap`,children:(0,h.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`connect-logo`})}),(0,h.jsx)(`svg`,{className:`connect-arrow`,viewBox:`0 0 48 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:(0,h.jsx)(`path`,{d:`M0 12h44m0 0l-8-8m8 8l-8 8`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`})}),(0,h.jsxs)(`div`,{className:`connect-logo-wrap`,children:[(0,h.jsx)(`img`,{src:i,alt:a.productName,className:`connect-logo connect-logo--maxy`}),!a.logoContainsName&&(0,h.jsx)(`span`,{className:`connect-logo-label`,children:a.productName})]})]}),(0,h.jsxs)(`h1`,{className:`connect-title`,children:[`Connect Claude to power `,a.productName]}),(0,h.jsx)(`p`,{className:`connect-subtitle`,children:`Sign in with your Anthropic account to get started.`}),(0,h.jsx)(s,{variant:`primary`,onClick:T,disabled:r,children:r?(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`}),(0,h.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,h.jsx)(`button`,{onClick:w,disabled:m,style:{marginTop:`12px`,background:`none`,border:`none`,color:`var(--color-primary, #666)`,fontSize:`13px`,cursor:`pointer`,textDecoration:`underline`,textUnderlineOffset:`3px`},children:m?`Launching…`:`Open browser first`}),c&&(0,h.jsx)(`p`,{className:`admin-pin-error`,children:c})]})})}function b({auth:e}){return e.appState===`loading`?(0,h.jsx)(`div`,{className:`connect-page`}):e.appState===`set-pin`?(0,h.jsx)(_,{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,h.jsx)(y,{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,h.jsx)(v,{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{m as n,b as t};
1
+ import{o as e}from"./chunk-TPjIAO9U.js";import{C as t,D as n,S as r,b as i,v as a}from"./useSubAccountSwitcher-CFa6ZAT1.js";import{E as o}from"./useVoiceRecorder-u2dwZfen.js";import{v as s,y as c}from"./AdminShell-BwSaZ88d.js";import{t as l}from"./Checkbox-CN4uQ80w.js";var u=`admin-landing-redirected`,d=`/graph`;function f(e){return e.variant===`operator`?!1:e.appState===`chat`&&!e.alreadyRedirected}var p=e(n(),1);function m(e=`admin`){let[n,r]=(0,p.useState)(`loading`),[i,a]=(0,p.useState)(``),[s,l]=(0,p.useState)(``),[m,h]=(0,p.useState)(``),[g,_]=(0,p.useState)(!1),[v,y]=(0,p.useState)(!1),[b,x]=(0,p.useState)(!1),[S,C]=(0,p.useState)(!1),[w,T]=(0,p.useState)(!1),[E,D]=(0,p.useState)(null),[O,k]=(0,p.useState)(null),[A,j]=(0,p.useState)(void 0),[M,N]=(0,p.useState)(null),[P,F]=(0,p.useState)(void 0),[I,L]=(0,p.useState)(null),[R,z]=(0,p.useState)(null),[B,V]=(0,p.useState)(void 0),H=(0,p.useRef)(void 0),[U,W]=(0,p.useState)(!1),[G,K]=(0,p.useState)(!0);(0,p.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,p.useRef)(null),J=(0,p.useRef)(null);(0,p.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 n=await t.json();D(n.session_key),z(n.sessionId??null),j(n.businessName),N(n.role??null),F(n.userName===void 0?null:n.userName),L(n.avatar??null);let i=o(n.thinkingView);return H.current=i,V(i),r(`chat`),!0}catch(e){return console.error(`[admin] session restore failed:`,e),!1}}async function t(n=2){try{let i=await fetch(`/api/health`);if(!i.ok){if(n>0)return await new Promise(e=>setTimeout(e,1500)),t(n-1);console.error(`[admin] health check returned ${i.status} after retries`),r(`set-pin`);return}let a=await i.json();if(!a.pin_configured){r(`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){r(`connect-claude`);return}}if(await e())return;r(`enter-pin`)}catch(e){if(n>0)return await new Promise(e=>setTimeout(e,1500)),t(n-1);console.error(`[admin] health check failed:`,e),r(`set-pin`)}}t()},[]),(0,p.useEffect)(()=>{n===`chat`&&fetch(`/api/admin/claude-info`).then(e=>{if(e.ok)return e.json()}).then(e=>{e&&k(e)}).catch(()=>{})},[n]),(0,p.useEffect)(()=>{if(typeof window>`u`)return;let t=!1;try{t=sessionStorage.getItem(u)===`1`}catch{}if(f({appState:n,alreadyRedirected:t,variant:e})){try{sessionStorage.setItem(u,`1`)}catch{}console.info(`[admin-ui] landing-redirect target=${d}`),window.location.replace(d)}},[n,e]);let Y=(0,p.useRef)(null);(0,p.useEffect)(()=>{if(n!==`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 n=(await e.clone().json().catch(()=>null))?.code??`unknown-401`;if(n===`remote-auth-required`){t(`heartbeat`,`/api/admin/session`);return}console.warn(`[admin-auth] outcome=heartbeat-detected-expiry code=${n}`),Y.current?.()}catch{}},300*1e3);return()=>clearInterval(e)},[n,E]),(0,p.useEffect)(()=>{n===`connect-claude`&&fetch(`/api/health`).then(e=>e.ok?e.json():null).then(e=>{e?.claude_authenticated&&(K(!0),r(`enter-pin`))}).catch(()=>{})},[n]);async function X(e,n){y(!0);try{let i=await fetch(`/api/admin/session`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pin:e,...n?{accountId:n}:{}})});if(!i.ok){let e=await i.json().catch(()=>({}));if(i.status===401&&e?.code===`remote-auth-required`){t(`enter-pin`,`/api/admin/session`);return}h(e.error||`Invalid PIN`);return}let s=await i.json();D(s.session_key),z(s.sessionId??null),j(s.businessName),N(s.role??null),F(s.userName===void 0?null:s.userName),L(s.avatar??null);let c=o(s.thinkingView);H.current=c,V(c);try{sessionStorage.setItem(`maxy-admin-session-key`,s.session_key)}catch{}a(``),r(`chat`)}catch(e){console.error(`[admin] connection error:`,e),h(`Could not connect.`)}finally{y(!1)}}let Z=(0,p.useCallback)(async e=>{if(e.preventDefault(),v)return;h(``);let n=s.trim();if(!n){h(`Please enter your name.`);return}if(i.length<4){h(`PIN must be at least 4 characters.`);return}let o=i;y(!0);try{let e=await fetch(`/api/onboarding/set-pin`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({pin:o,name:n})});if(!e.ok){let n=await e.json().catch(()=>({}));if(e.status===401&&n?.code===`remote-auth-required`){t(`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 t=await e.json();t.pin_configured&&t.claude_authenticated?r(`enter-pin`):t.pin_configured?r(`connect-claude`):h(n.error||`Failed to set PIN.`)}else r(`enter-pin`)}catch{r(`enter-pin`)}return}h(n.error||`Failed to set PIN.`);return}let i=await fetch(`/api/health`);if((i.ok?await i.json():null)?.claude_authenticated){await X(o);return}a(``),r(`connect-claude`)}catch(e){console.error(`[admin] connection error:`,e),h(`Could not connect.`)}finally{y(!1)}},[i,v,s]),Q=(0,p.useCallback)(async e=>{e.preventDefault(),h(``),await X(i)},[i]),ee=(0,p.useCallback)(async()=>{T(!0);try{if(!await c())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(u)}catch{}return r(`connect-claude`),!0}finally{T(!1)}},[]),$=(0,p.useCallback)(()=>{D(null),N(null),F(void 0),L(null);try{sessionStorage.removeItem(`maxy-admin-session-key`),sessionStorage.removeItem(u)}catch{}a(``),h(``),r(`enter-pin`)},[]);return(0,p.useEffect)(()=>{Y.current=$},[$]),{appState:n,setAppState:r,pin:i,setPin:a,operatorName:s,setOperatorName:l,pinError:m,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 h=r();function g({inputRef:e,value:t,onChange:n,onComplete:r,showPin:i,autoFocus:a}){let o=(0,p.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,h.jsx)(`div`,{className:`pin-field`,children:Array.from({length:6}).map((n,r)=>(0,h.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 _(e){let{pin:t,setPin:n,showPin:r,setShowPin:o,pinLoading:c,pinError:u,pinInputRef:d,setPinFormRef:f,onSubmit:p,operatorName:m,setOperatorName:_}=e;return(0,h.jsx)(`div`,{className:`connect-page`,children:(0,h.jsxs)(`div`,{className:`connect-content`,children:[(0,h.jsx)(`img`,{src:i,alt:a.productName,className:`connect-logo connect-logo--maxy`}),!a.logoContainsName&&(0,h.jsxs)(`h1`,{className:`connect-title`,children:[`Welcome to `,a.productName]}),(0,h.jsxs)(`p`,{className:`connect-subtitle`,children:[`Tell `,a.productName,` who you are, then choose a PIN.`]}),(0,h.jsxs)(`form`,{ref:f,onSubmit:p,className:`connect-pin-form`,children:[(0,h.jsxs)(`div`,{className:`pin-input-row`,children:[(0,h.jsx)(`input`,{type:`text`,className:`connect-name-input`,placeholder:`Your full name`,value:m,onChange:e=>_(e.target.value),autoComplete:`name`,autoFocus:!0,required:!0,"aria-label":`Your full name`}),(0,h.jsx)(`div`,{style:{width:38,flexShrink:0},"aria-hidden":`true`})]}),(0,h.jsxs)(`div`,{className:`pin-input-row`,children:[(0,h.jsx)(g,{inputRef:d,value:t,onChange:n,onComplete:()=>{},showPin:r}),(0,h.jsx)(s,{variant:`send`,type:`submit`,disabled:!t||!m.trim(),loading:c,"aria-label":`Set PIN`,children:(0,h.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,h.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,h.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,h.jsx)(l,{checked:r,onChange:()=>o(e=>!e),label:`Show PIN`})]}),u&&(0,h.jsx)(`p`,{className:`admin-pin-error`,children:u})]})})}function v(e){let{pin:t,setPin:n,showPin:r,setShowPin:o,pinLoading:c,pinError:u,pinInputRef:d,onSubmit:f,remoteAuthEnabled:p,onSignOutRemote:m}=e;return(0,h.jsxs)(`div`,{className:`connect-page`,children:[p&&m&&(0,h.jsx)(`button`,{type:`button`,className:`connect-signout`,onClick:m,children:`Sign out`}),(0,h.jsxs)(`div`,{className:`connect-content`,children:[(0,h.jsx)(`img`,{src:i,alt:a.productName,className:`connect-logo connect-logo--maxy`}),!a.logoContainsName&&(0,h.jsx)(`h1`,{className:`connect-title`,children:a.productName}),(0,h.jsxs)(`form`,{onSubmit:f,className:`connect-pin-form`,children:[(0,h.jsxs)(`div`,{className:`pin-input-row`,children:[(0,h.jsx)(g,{inputRef:d,value:t,onChange:n,onComplete:()=>{},showPin:r,autoFocus:!0}),(0,h.jsx)(s,{variant:`send`,type:`submit`,disabled:!t,loading:c,children:(0,h.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,h.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,h.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]}),(0,h.jsx)(`div`,{className:`pin-options`,children:(0,h.jsx)(l,{checked:r,onChange:()=>o(e=>!e),label:`Show PIN`})})]}),u&&(0,h.jsx)(`p`,{className:`admin-pin-error`,children:u})]})]})}function y(e){let{authPolling:t,setAuthPolling:n,authLoading:r,setAuthLoading:o,pinError:c,setPinError:l,setAppState:u}=e,[d,f]=(0,p.useState)(!1),[m,g]=(0,p.useState)(!1),[_,v]=(0,p.useState)(``),[y,b]=(0,p.useState)(``),[x,S]=(0,p.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(){g(!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.`)}g(!1)}async function T(){o(!0),l(``);try{let e=await(await fetch(`/api/onboarding/claude-auth`,{method:`POST`})).json();if(e.started){n(!0),f(!0),o(!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.`)}o(!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,h.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,height:`100dvh`,overflow:`auto`},children:[(0,h.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,h.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,h.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,h.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`chat-logo`}),(0,h.jsx)(`h1`,{className:`chat-tagline`,children:`Connect Claude`}),(0,h.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,h.jsx)(`div`,{style:{marginTop:`12px`},children:(0,h.jsx)(s,{variant:`primary`,onClick:T,disabled:r,children:r?(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`})}),t&&_===`native`&&(0,h.jsxs)(`div`,{style:{marginTop:`14px`,maxWidth:`420px`,margin:`14px auto 0`,display:`flex`,flexDirection:`column`,gap:`8px`},children:[(0,h.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,h.jsxs)(`div`,{style:{display:`flex`,gap:`8px`},children:[(0,h.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,h.jsx)(s,{variant:`primary`,onClick:C,disabled:!y.trim(),children:`Submit`})]}),x&&(0,h.jsx)(`p`,{style:{fontSize:`12px`,color:`#999`,margin:0},children:x})]})]}),(0,h.jsx)(`div`,{style:{flex:1,display:`flex`,flexDirection:`column`,minHeight:0,gap:`10px`,padding:`0 0 16px`},children:(0,h.jsx)(`iframe`,{src:`/vnc-viewer.html`,style:{flex:1,width:`100%`,minHeight:0,border:`none`,background:`#111`,display:`block`},title:`Claude Sign-in`})}),c&&(0,h.jsx)(`p`,{className:`admin-pin-error`,style:{textAlign:`center`,padding:`0 20px 16px`},children:c})]}):(0,h.jsx)(`div`,{className:`connect-page`,children:(0,h.jsxs)(`div`,{className:`connect-content`,children:[(0,h.jsxs)(`div`,{className:`connect-logos`,children:[(0,h.jsx)(`div`,{className:`connect-logo-wrap`,children:(0,h.jsx)(`img`,{src:`/brand/claude.png`,alt:`Claude`,className:`connect-logo`})}),(0,h.jsx)(`svg`,{className:`connect-arrow`,viewBox:`0 0 48 24`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:(0,h.jsx)(`path`,{d:`M0 12h44m0 0l-8-8m8 8l-8 8`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`})}),(0,h.jsxs)(`div`,{className:`connect-logo-wrap`,children:[(0,h.jsx)(`img`,{src:i,alt:a.productName,className:`connect-logo connect-logo--maxy`}),!a.logoContainsName&&(0,h.jsx)(`span`,{className:`connect-logo-label`,children:a.productName})]})]}),(0,h.jsxs)(`h1`,{className:`connect-title`,children:[`Connect Claude to power `,a.productName]}),(0,h.jsx)(`p`,{className:`connect-subtitle`,children:`Sign in with your Anthropic account to get started.`}),(0,h.jsx)(s,{variant:`primary`,onClick:T,disabled:r,children:r?(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`span`,{className:`spin`,style:{display:`inline-block`},children:`✱`}),` Connecting…`]}):`Sign in to Claude`}),(0,h.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,h.jsx)(`button`,{onClick:w,disabled:m,style:{marginTop:`12px`,background:`none`,border:`none`,color:`var(--color-primary, #666)`,fontSize:`13px`,cursor:`pointer`,textDecoration:`underline`,textUnderlineOffset:`3px`},children:m?`Launching…`:`Open browser first`}),c&&(0,h.jsx)(`p`,{className:`admin-pin-error`,children:c})]})})}function b({auth:e}){return e.appState===`loading`?(0,h.jsx)(`div`,{className:`connect-page`}):e.appState===`set-pin`?(0,h.jsx)(_,{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,h.jsx)(y,{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,h.jsx)(v,{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{m as n,b as t};