@rubytech/create-maxy-code 0.1.444 → 0.1.445

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 (170) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/lib/graph-style/dist/index.d.ts +4 -0
  3. package/payload/platform/lib/graph-style/dist/index.d.ts.map +1 -1
  4. package/payload/platform/lib/graph-style/dist/index.js +37 -1
  5. package/payload/platform/lib/graph-style/dist/index.js.map +1 -1
  6. package/payload/platform/lib/graph-style/src/__tests__/parity.test.ts +39 -0
  7. package/payload/platform/lib/graph-style/src/index.ts +41 -0
  8. package/payload/platform/lib/storage-broker/dist/__tests__/audit.test.d.ts +2 -0
  9. package/payload/platform/lib/storage-broker/dist/__tests__/audit.test.d.ts.map +1 -0
  10. package/payload/platform/lib/storage-broker/dist/__tests__/audit.test.js +46 -0
  11. package/payload/platform/lib/storage-broker/dist/__tests__/audit.test.js.map +1 -0
  12. package/payload/platform/lib/storage-broker/dist/__tests__/authorize.test.d.ts +2 -0
  13. package/payload/platform/lib/storage-broker/dist/__tests__/authorize.test.d.ts.map +1 -0
  14. package/payload/platform/lib/storage-broker/dist/__tests__/authorize.test.js +27 -0
  15. package/payload/platform/lib/storage-broker/dist/__tests__/authorize.test.js.map +1 -0
  16. package/payload/platform/lib/storage-broker/dist/__tests__/cf-exec.test.d.ts +2 -0
  17. package/payload/platform/lib/storage-broker/dist/__tests__/cf-exec.test.d.ts.map +1 -0
  18. package/payload/platform/lib/storage-broker/dist/__tests__/cf-exec.test.js +51 -0
  19. package/payload/platform/lib/storage-broker/dist/__tests__/cf-exec.test.js.map +1 -0
  20. package/payload/platform/lib/storage-broker/dist/__tests__/house-credential.test.d.ts +2 -0
  21. package/payload/platform/lib/storage-broker/dist/__tests__/house-credential.test.d.ts.map +1 -0
  22. package/payload/platform/lib/storage-broker/dist/__tests__/house-credential.test.js +39 -0
  23. package/payload/platform/lib/storage-broker/dist/__tests__/house-credential.test.js.map +1 -0
  24. package/payload/platform/lib/storage-broker/dist/__tests__/registry.test.d.ts +2 -0
  25. package/payload/platform/lib/storage-broker/dist/__tests__/registry.test.d.ts.map +1 -0
  26. package/payload/platform/lib/storage-broker/dist/__tests__/registry.test.js +59 -0
  27. package/payload/platform/lib/storage-broker/dist/__tests__/registry.test.js.map +1 -0
  28. package/payload/platform/lib/storage-broker/dist/__tests__/remediate-run.test.d.ts +2 -0
  29. package/payload/platform/lib/storage-broker/dist/__tests__/remediate-run.test.d.ts.map +1 -0
  30. package/payload/platform/lib/storage-broker/dist/__tests__/remediate-run.test.js +77 -0
  31. package/payload/platform/lib/storage-broker/dist/__tests__/remediate-run.test.js.map +1 -0
  32. package/payload/platform/lib/storage-broker/dist/__tests__/remediate.test.d.ts +2 -0
  33. package/payload/platform/lib/storage-broker/dist/__tests__/remediate.test.d.ts.map +1 -0
  34. package/payload/platform/lib/storage-broker/dist/__tests__/remediate.test.js +23 -0
  35. package/payload/platform/lib/storage-broker/dist/__tests__/remediate.test.js.map +1 -0
  36. package/payload/platform/lib/storage-broker/dist/audit.d.ts +19 -0
  37. package/payload/platform/lib/storage-broker/dist/audit.d.ts.map +1 -0
  38. package/payload/platform/lib/storage-broker/dist/audit.js +41 -0
  39. package/payload/platform/lib/storage-broker/dist/audit.js.map +1 -0
  40. package/payload/platform/lib/storage-broker/dist/authorize.d.ts +11 -0
  41. package/payload/platform/lib/storage-broker/dist/authorize.d.ts.map +1 -0
  42. package/payload/platform/lib/storage-broker/dist/authorize.js +17 -0
  43. package/payload/platform/lib/storage-broker/dist/authorize.js.map +1 -0
  44. package/payload/platform/lib/storage-broker/dist/bin/remediate-run.d.ts +25 -0
  45. package/payload/platform/lib/storage-broker/dist/bin/remediate-run.d.ts.map +1 -0
  46. package/payload/platform/lib/storage-broker/dist/bin/remediate-run.js +131 -0
  47. package/payload/platform/lib/storage-broker/dist/bin/remediate-run.js.map +1 -0
  48. package/payload/platform/lib/storage-broker/dist/cf-exec.d.ts +20 -0
  49. package/payload/platform/lib/storage-broker/dist/cf-exec.d.ts.map +1 -0
  50. package/payload/platform/lib/storage-broker/dist/cf-exec.js +53 -0
  51. package/payload/platform/lib/storage-broker/dist/cf-exec.js.map +1 -0
  52. package/payload/platform/lib/storage-broker/dist/house-credential.d.ts +6 -0
  53. package/payload/platform/lib/storage-broker/dist/house-credential.d.ts.map +1 -0
  54. package/payload/platform/lib/storage-broker/dist/house-credential.js +33 -0
  55. package/payload/platform/lib/storage-broker/dist/house-credential.js.map +1 -0
  56. package/payload/platform/lib/storage-broker/dist/index.d.ts +7 -0
  57. package/payload/platform/lib/storage-broker/dist/index.d.ts.map +1 -0
  58. package/payload/platform/lib/storage-broker/dist/index.js +30 -0
  59. package/payload/platform/lib/storage-broker/dist/index.js.map +1 -0
  60. package/payload/platform/lib/storage-broker/dist/registry.d.ts +18 -0
  61. package/payload/platform/lib/storage-broker/dist/registry.d.ts.map +1 -0
  62. package/payload/platform/lib/storage-broker/dist/registry.js +45 -0
  63. package/payload/platform/lib/storage-broker/dist/registry.js.map +1 -0
  64. package/payload/platform/lib/storage-broker/dist/remediate.d.ts +7 -0
  65. package/payload/platform/lib/storage-broker/dist/remediate.d.ts.map +1 -0
  66. package/payload/platform/lib/storage-broker/dist/remediate.js +25 -0
  67. package/payload/platform/lib/storage-broker/dist/remediate.js.map +1 -0
  68. package/payload/platform/lib/storage-broker/src/__tests__/audit.test.ts +49 -0
  69. package/payload/platform/lib/storage-broker/src/__tests__/authorize.test.ts +28 -0
  70. package/payload/platform/lib/storage-broker/src/__tests__/cf-exec.test.ts +52 -0
  71. package/payload/platform/lib/storage-broker/src/__tests__/house-credential.test.ts +35 -0
  72. package/payload/platform/lib/storage-broker/src/__tests__/registry.test.ts +64 -0
  73. package/payload/platform/lib/storage-broker/src/__tests__/remediate-run.test.ts +79 -0
  74. package/payload/platform/lib/storage-broker/src/__tests__/remediate.test.ts +21 -0
  75. package/payload/platform/lib/storage-broker/src/audit.ts +55 -0
  76. package/payload/platform/lib/storage-broker/src/authorize.ts +22 -0
  77. package/payload/platform/lib/storage-broker/src/bin/remediate-run.ts +156 -0
  78. package/payload/platform/lib/storage-broker/src/cf-exec.ts +73 -0
  79. package/payload/platform/lib/storage-broker/src/house-credential.ts +32 -0
  80. package/payload/platform/lib/storage-broker/src/index.ts +14 -0
  81. package/payload/platform/lib/storage-broker/src/registry.ts +85 -0
  82. package/payload/platform/lib/storage-broker/src/remediate.ts +31 -0
  83. package/payload/platform/lib/storage-broker/tsconfig.json +8 -0
  84. package/payload/platform/package.json +2 -2
  85. package/payload/platform/plugins/.claude-plugin/marketplace.json +5 -0
  86. package/payload/platform/plugins/admin/hooks/lib/maxy-mcp-plugins.txt +1 -0
  87. package/payload/platform/plugins/cloudflare/PLUGIN.md +4 -1
  88. package/payload/platform/plugins/cloudflare/bin/__tests__/cf-schema-check.test.sh +128 -0
  89. package/payload/platform/plugins/cloudflare/bin/__tests__/cf-store-name.test.sh +77 -0
  90. package/payload/platform/plugins/cloudflare/bin/cf-schema-check.sh +60 -0
  91. package/payload/platform/plugins/cloudflare/bin/cf-store-name.sh +37 -0
  92. package/payload/platform/plugins/cloudflare/bin/remediate-storage-isolation.sh +36 -0
  93. package/payload/platform/plugins/cloudflare/references/api.md +4 -0
  94. package/payload/platform/plugins/cloudflare/references/d1-data-capture.md +58 -0
  95. package/payload/platform/plugins/cloudflare/references/r2-object-storage.md +39 -0
  96. package/payload/platform/plugins/cloudflare/skills/cloudflare/SKILL.md +2 -0
  97. package/payload/platform/plugins/cloudflare/skills/site-deploy/SKILL.md +2 -0
  98. package/payload/platform/plugins/scheduling/mcp/dist/scripts/publish-availability.js +11 -4
  99. package/payload/platform/plugins/scheduling/mcp/dist/scripts/publish-availability.js.map +1 -1
  100. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js +15 -10
  101. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js.map +1 -1
  102. package/payload/platform/plugins/storage-broker/.claude-plugin/plugin.json +21 -0
  103. package/payload/platform/plugins/storage-broker/PLUGIN.md +48 -0
  104. package/payload/platform/plugins/storage-broker/lib/mcp-spawn-tee/index.js +193 -0
  105. package/payload/platform/plugins/storage-broker/lib/mcp-spawn-tee/package.json +3 -0
  106. package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/caller-scope-headers.test.d.ts +2 -0
  107. package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/caller-scope-headers.test.d.ts.map +1 -0
  108. package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/caller-scope-headers.test.js +16 -0
  109. package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/caller-scope-headers.test.js.map +1 -0
  110. package/payload/platform/plugins/storage-broker/mcp/dist/call-api.d.ts +8 -0
  111. package/payload/platform/plugins/storage-broker/mcp/dist/call-api.d.ts.map +1 -0
  112. package/payload/platform/plugins/storage-broker/mcp/dist/call-api.js +39 -0
  113. package/payload/platform/plugins/storage-broker/mcp/dist/call-api.js.map +1 -0
  114. package/payload/platform/plugins/storage-broker/mcp/dist/caller-scope-headers.d.ts +7 -0
  115. package/payload/platform/plugins/storage-broker/mcp/dist/caller-scope-headers.d.ts.map +1 -0
  116. package/payload/platform/plugins/storage-broker/mcp/dist/caller-scope-headers.js +16 -0
  117. package/payload/platform/plugins/storage-broker/mcp/dist/caller-scope-headers.js.map +1 -0
  118. package/payload/platform/plugins/storage-broker/mcp/dist/index.d.ts +8 -0
  119. package/payload/platform/plugins/storage-broker/mcp/dist/index.d.ts.map +1 -0
  120. package/payload/platform/plugins/storage-broker/mcp/dist/index.js +98 -0
  121. package/payload/platform/plugins/storage-broker/mcp/dist/index.js.map +1 -0
  122. package/payload/platform/plugins/storage-broker/mcp/package.json +10 -0
  123. package/payload/platform/plugins/storage-broker/mcp/vitest.config.ts +4 -0
  124. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  125. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +6 -0
  126. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  127. package/payload/server/chunk-4W6IEUFE.js +175 -0
  128. package/payload/server/public/assets/{AdminLoginScreens-BJVwtpLH.js → AdminLoginScreens-D9L-CuWi.js} +1 -1
  129. package/payload/server/public/assets/{AdminShell-CMu8_Xwn.js → AdminShell-DSQrvZXq.js} +1 -1
  130. package/payload/server/public/assets/{Checkbox-CzD0ORqA.js → Checkbox-CFdt8ljo.js} +1 -1
  131. package/payload/server/public/assets/{admin-D0yk2LMq.js → admin-Ch4n-G0j.js} +1 -1
  132. package/payload/server/public/assets/{browser-CvfbgznO.js → browser-B2AIxiuk.js} +1 -1
  133. package/payload/server/public/assets/{calendar-fw4WethJ.js → calendar-BvItH3B0.js} +1 -1
  134. package/payload/server/public/assets/chat-eQFMaX9y.js +1 -0
  135. package/payload/server/public/assets/chevron-left-D2AnCEyE.js +1 -0
  136. package/payload/server/public/assets/data-BzOmbHoe.js +1 -0
  137. package/payload/server/public/assets/{file-download-Px4s0Bhp.js → file-download-CK9j_Jx2.js} +1 -1
  138. package/payload/server/public/assets/graph-DrE7KupQ.js +51 -0
  139. package/payload/server/public/assets/graph-labels-CwEtvIRV.js +1 -0
  140. package/payload/server/public/assets/{maximize-2-BwphzI9S.js → maximize-2-CuzEom3K.js} +1 -1
  141. package/payload/server/public/assets/{operator-88m0DMl2.js → operator-DlboYPPu.js} +1 -1
  142. package/payload/server/public/assets/page-BuWH5gNK.js +1 -0
  143. package/payload/server/public/assets/page-Co9E8U5x.js +32 -0
  144. package/payload/server/public/assets/{public-BX2MjsFY.js → public-DtFpPMTG.js} +1 -1
  145. package/payload/server/public/assets/{rotate-ccw-C7BqkMec.js → rotate-ccw-Cqp4oqHV.js} +1 -1
  146. package/payload/server/public/assets/{tasks-DlgiCafL.js → tasks-bQKOhMga.js} +1 -1
  147. package/payload/server/public/assets/{time-entry-format-CyNYVDkq.js → time-entry-format-BIL4ZaDK.js} +1 -1
  148. package/payload/server/public/assets/useCopyFeedback-rB8QuqyH.js +1 -0
  149. package/payload/server/public/assets/{useSubAccountSwitcher-1izQvPiD.css → useSubAccountSwitcher-CVHKTSst.css} +1 -1
  150. package/payload/server/public/assets/{useVoiceRecorder-XgpWvXpk.js → useVoiceRecorder-Ctny8qWx.js} +1 -1
  151. package/payload/server/public/browser.html +5 -5
  152. package/payload/server/public/calendar.html +6 -6
  153. package/payload/server/public/chat.html +12 -12
  154. package/payload/server/public/data.html +10 -10
  155. package/payload/server/public/graph.html +11 -11
  156. package/payload/server/public/index.html +13 -13
  157. package/payload/server/public/operator.html +14 -14
  158. package/payload/server/public/public.html +12 -12
  159. package/payload/server/public/tasks.html +5 -5
  160. package/payload/server/server.js +1017 -828
  161. package/payload/server/src-BQ2NYMOT.js +24 -0
  162. package/payload/server/public/assets/chat-Dq-X-ia8.js +0 -1
  163. package/payload/server/public/assets/chevron-left-B3xSeEDR.js +0 -1
  164. package/payload/server/public/assets/data-CUnDzDox.js +0 -1
  165. package/payload/server/public/assets/graph-DbT8nA6R.js +0 -51
  166. package/payload/server/public/assets/graph-labels-C1YIyLiA.js +0 -1
  167. package/payload/server/public/assets/page-BRfxFXyi.js +0 -32
  168. package/payload/server/public/assets/page-CfQFAJia.js +0 -1
  169. package/payload/server/public/assets/useCopyFeedback-ByGUMN94.js +0 -1
  170. /package/payload/server/public/assets/{useSubAccountSwitcher-s6WlRn52.js → useSubAccountSwitcher-CHEt_m6q.js} +0 -0
@@ -0,0 +1,39 @@
1
+ /**
2
+ * MCP tool helper that calls the storage-broker Hono routes on localhost and
3
+ * surfaces structured error bodies on non-2xx responses, so a denied request
4
+ * returns the route's `error` reason (e.g. "cross-account") the agent can act
5
+ * on, never a bare status line. Mirrors the WhatsApp call-api helper.
6
+ */
7
+ export async function callApi(baseUrl, path, method = "POST", body, extraHeaders) {
8
+ const headers = { ...(extraHeaders ?? {}) };
9
+ if (body)
10
+ headers["Content-Type"] = "application/json";
11
+ const res = await fetch(`${baseUrl}${path}`, {
12
+ method,
13
+ headers: Object.keys(headers).length > 0 ? headers : undefined,
14
+ body: body ? JSON.stringify(body) : undefined,
15
+ });
16
+ if (res.ok)
17
+ return res.json();
18
+ const fallback = `HTTP ${res.status}: ${res.statusText} (${method} ${path})`;
19
+ let text;
20
+ try {
21
+ text = await res.text();
22
+ }
23
+ catch {
24
+ return { ok: false, error: fallback };
25
+ }
26
+ if (!text)
27
+ return { ok: false, error: fallback };
28
+ try {
29
+ const parsed = JSON.parse(text);
30
+ if (typeof parsed.error === "string" && parsed.error.trim()) {
31
+ return { ok: false, error: parsed.error };
32
+ }
33
+ return { ok: false, error: fallback };
34
+ }
35
+ catch {
36
+ return { ok: false, error: fallback };
37
+ }
38
+ }
39
+ //# sourceMappingURL=call-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call-api.js","sourceRoot":"","sources":["../src/call-api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,OAAe,EACf,IAAY,EACZ,SAAyB,MAAM,EAC/B,IAAc,EACd,YAAqC;IAErC,MAAM,OAAO,GAA2B,EAAE,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,EAAE,CAAC;IACpE,IAAI,IAAI;QAAE,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;IACvD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,GAAG,IAAI,EAAE,EAAE;QAC3C,MAAM;QACN,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;QAC9D,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;KAC9C,CAAC,CAAC;IAEH,IAAI,GAAG,CAAC,EAAE;QAAE,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;IAE9B,MAAM,QAAQ,GAAG,QAAQ,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,UAAU,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC;IAC7E,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IACxC,CAAC;IACD,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IAEjD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA4B,CAAC;QAC3D,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;YAC5D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;QAC5C,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IACxC,CAAC;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ /** The trustworthy caller signals a storage-broker tool forwards to the loopback
2
+ * route as HTTP headers, distinct from any tool argument. ACCOUNT_ID is stamped
3
+ * into the spawn env by the platform and inherited by this MCP child; the agent
4
+ * cannot set it. An empty value is omitted so the route reads it as absent
5
+ * (fail closed). Mirrors the WhatsApp caller-scope-headers pattern (Task 1498). */
6
+ export declare function callerScopeHeaders(env: NodeJS.ProcessEnv): Record<string, string>;
7
+ //# sourceMappingURL=caller-scope-headers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"caller-scope-headers.d.ts","sourceRoot":"","sources":["../src/caller-scope-headers.ts"],"names":[],"mappings":"AAAA;;;;oFAIoF;AACpF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOjF"}
@@ -0,0 +1,16 @@
1
+ /** The trustworthy caller signals a storage-broker tool forwards to the loopback
2
+ * route as HTTP headers, distinct from any tool argument. ACCOUNT_ID is stamped
3
+ * into the spawn env by the platform and inherited by this MCP child; the agent
4
+ * cannot set it. An empty value is omitted so the route reads it as absent
5
+ * (fail closed). Mirrors the WhatsApp caller-scope-headers pattern (Task 1498). */
6
+ export function callerScopeHeaders(env) {
7
+ const headers = {};
8
+ const callerAccount = env.ACCOUNT_ID;
9
+ const houseAdminScope = env.HOUSE_ADMIN_SCOPE;
10
+ if (callerAccount && callerAccount.length > 0)
11
+ headers["x-maxy-caller-account"] = callerAccount;
12
+ if (houseAdminScope && houseAdminScope.length > 0)
13
+ headers["x-maxy-house-admin-scope"] = houseAdminScope;
14
+ return headers;
15
+ }
16
+ //# sourceMappingURL=caller-scope-headers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"caller-scope-headers.js","sourceRoot":"","sources":["../src/caller-scope-headers.ts"],"names":[],"mappings":"AAAA;;;;oFAIoF;AACpF,MAAM,UAAU,kBAAkB,CAAC,GAAsB;IACvD,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,MAAM,aAAa,GAAG,GAAG,CAAC,UAAU,CAAC;IACrC,MAAM,eAAe,GAAG,GAAG,CAAC,iBAAiB,CAAC;IAC9C,IAAI,aAAa,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,CAAC,uBAAuB,CAAC,GAAG,aAAa,CAAC;IAChG,IAAI,eAAe,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,CAAC,0BAA0B,CAAC,GAAG,eAAe,CAAC;IACzG,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * storage-broker MCP server — the agent surface for per-account Cloudflare
3
+ * D1/R2. Every tool is a thin client: it forwards the platform-stamped caller
4
+ * account as an HTTP header (never a tool argument) to the loopback broker
5
+ * routes, which hold the sole account-wide credential and enforce ownership.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * storage-broker MCP server — the agent surface for per-account Cloudflare
3
+ * D1/R2. Every tool is a thin client: it forwards the platform-stamped caller
4
+ * account as an HTTP header (never a tool argument) to the loopback broker
5
+ * routes, which hold the sole account-wide credential and enforce ownership.
6
+ */
7
+ import { initStderrTee } from "../../../../lib/mcp-stderr-tee/dist/index.js";
8
+ initStderrTee("storage-broker");
9
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
10
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
11
+ import { z } from "zod";
12
+ import { callApi as rawCallApi } from "./call-api.js";
13
+ import { callerScopeHeaders } from "./caller-scope-headers.js";
14
+ import { requirePortEnv } from "../../../../lib/require-port-env/dist/index.js";
15
+ import { lifelineTool } from "../../../../lib/mcp-lifeline/dist/index.js";
16
+ // PLATFORM_PORT is the loopback port stamped on the platform spawn env. Read is
17
+ // deferred to first invocation: CC's plugin-system enumerates tools/list with
18
+ // empty env, and any module-init throw would empty the tool registry.
19
+ let cachedBaseUrl = null;
20
+ function getBaseUrl(toolName) {
21
+ if (cachedBaseUrl !== null)
22
+ return cachedBaseUrl;
23
+ try {
24
+ const port = requirePortEnv("PLATFORM_PORT", { tag: "storage-broker" });
25
+ cachedBaseUrl = `http://127.0.0.1:${port}`;
26
+ return cachedBaseUrl;
27
+ }
28
+ catch (err) {
29
+ process.stderr.write(`[storage-broker] missing-port-env tool=${toolName} action=tool-result-error\n`);
30
+ throw err;
31
+ }
32
+ }
33
+ const server = new McpServer({ name: "maxy-storage-broker", version: "0.1.0" });
34
+ function callApi(toolName, path, method, body) {
35
+ return rawCallApi(getBaseUrl(toolName), path, method, body, callerScopeHeaders(process.env));
36
+ }
37
+ function textResult(text, isError = false) {
38
+ return {
39
+ content: [{ type: "text", text }],
40
+ ...(isError ? { isError: true } : {}),
41
+ };
42
+ }
43
+ function errorOf(result) {
44
+ const e = result?.error;
45
+ return typeof e === "string" ? e : null;
46
+ }
47
+ // ─── storage-d1-list ──────────────────────────────────────────────────────
48
+ lifelineTool(server, "storage-d1-list", "List the Cloudflare D1 databases your account owns.", {}, async () => {
49
+ const result = await callApi("storage-d1-list", "/api/storage/d1/list", "GET");
50
+ const err = errorOf(result);
51
+ if (err)
52
+ return textResult(`D1 list failed: ${err}`, true);
53
+ const dbs = result.databases ?? [];
54
+ return textResult(dbs.length ? dbs.map((d) => d.name).join("\n") : "No D1 databases.");
55
+ });
56
+ // ─── storage-d1-create ────────────────────────────────────────────────────
57
+ lifelineTool(server, "storage-d1-create", "Create a Cloudflare D1 database owned by your account.", { name: z.string().describe("Database name") }, async ({ name }) => {
58
+ const result = await callApi("storage-d1-create", "/api/storage/d1/create", "POST", { name });
59
+ const err = errorOf(result);
60
+ if (err)
61
+ return textResult(`D1 create failed: ${err}`, true);
62
+ const db = result.database;
63
+ return textResult(db ? `Created D1 database ${db.name} (${db.uuid}).` : "Created.");
64
+ });
65
+ // ─── storage-d1-query ─────────────────────────────────────────────────────
66
+ lifelineTool(server, "storage-d1-query", "Run a SQL statement against a D1 database your account owns.", { name: z.string().describe("Database name"), sql: z.string().describe("SQL statement") }, async ({ name, sql }) => {
67
+ const result = await callApi("storage-d1-query", "/api/storage/d1/query", "POST", { name, sql });
68
+ const err = errorOf(result);
69
+ if (err)
70
+ return textResult(`D1 query failed: ${err}`, true);
71
+ return textResult(JSON.stringify(result.result ?? null, null, 2));
72
+ });
73
+ // ─── storage-r2-bucket-list ───────────────────────────────────────────────
74
+ lifelineTool(server, "storage-r2-bucket-list", "List the Cloudflare R2 buckets your account owns.", {}, async () => {
75
+ const result = await callApi("storage-r2-bucket-list", "/api/storage/r2/list", "GET");
76
+ const err = errorOf(result);
77
+ if (err)
78
+ return textResult(`R2 list failed: ${err}`, true);
79
+ const buckets = result.buckets ?? [];
80
+ return textResult(buckets.length ? buckets.map((b) => b.name).join("\n") : "No R2 buckets.");
81
+ });
82
+ // ─── storage-r2-bucket-create ─────────────────────────────────────────────
83
+ lifelineTool(server, "storage-r2-bucket-create", "Create a Cloudflare R2 bucket owned by your account.", { name: z.string().describe("Bucket name") }, async ({ name }) => {
84
+ const result = await callApi("storage-r2-bucket-create", "/api/storage/r2/create", "POST", { name });
85
+ const err = errorOf(result);
86
+ if (err)
87
+ return textResult(`R2 create failed: ${err}`, true);
88
+ return textResult(`Created R2 bucket ${name}.`);
89
+ });
90
+ async function main() {
91
+ const transport = new StdioServerTransport();
92
+ await server.connect(transport);
93
+ }
94
+ main().catch((err) => {
95
+ console.error(`[storage-broker-mcp] fatal: ${err}`);
96
+ process.exit(1);
97
+ });
98
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "@maxy/storage-broker",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "scripts": { "build": "tsc", "start": "node dist/index.js", "test": "vitest run" },
8
+ "dependencies": { "@modelcontextprotocol/sdk": "^1.12.1", "zod": "^3.24.0" },
9
+ "devDependencies": { "@types/node": "^22.0.0", "typescript": "^5.7.0", "vitest": "^4.1.7" }
10
+ }
@@ -0,0 +1,4 @@
1
+ import { defineConfig } from "vitest/config";
2
+ export default defineConfig({
3
+ test: { environment: "node", include: ["src/**/__tests__/**/*.test.ts"], testTimeout: 10_000 },
4
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"canonical-tool-names.generated.d.ts","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"AAQA,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAqB7C,CAAA;AAED,gEAAgE;AAChE,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EA+QtD,CAAA"}
1
+ {"version":3,"file":"canonical-tool-names.generated.d.ts","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"AAQA,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAsB7C,CAAA;AAED,gEAAgE;AAChE,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EAoRtD,CAAA"}
@@ -22,6 +22,7 @@ export const MAXY_MCP_PLUGINS = [
22
22
  "quickbooks",
23
23
  "replicate",
24
24
  "scheduling",
25
+ "storage-broker",
25
26
  "telegram",
26
27
  "url-get",
27
28
  "whatsapp",
@@ -262,6 +263,11 @@ export const CANONICAL_MAXY_TOOL_NAMES = [
262
263
  "mcp__plugin_scheduling_scheduling__schedule-list",
263
264
  "mcp__plugin_scheduling_scheduling__schedule-update",
264
265
  "mcp__plugin_scheduling_scheduling__time-resolve",
266
+ "mcp__plugin_storage-broker_storage-broker__storage-d1-create",
267
+ "mcp__plugin_storage-broker_storage-broker__storage-d1-list",
268
+ "mcp__plugin_storage-broker_storage-broker__storage-d1-query",
269
+ "mcp__plugin_storage-broker_storage-broker__storage-r2-bucket-create",
270
+ "mcp__plugin_storage-broker_storage-broker__storage-r2-bucket-list",
265
271
  "mcp__plugin_telegram_telegram__message",
266
272
  "mcp__plugin_telegram_telegram__message-history",
267
273
  "mcp__plugin_telegram_telegram__telegram-webhook-register",
@@ -1 +1 @@
1
- {"version":3,"file":"canonical-tool-names.generated.js","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"canonical-tool-names.generated.js","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,175 @@
1
+ import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
2
+
3
+ // ../lib/storage-broker/src/authorize.ts
4
+ function authorizeAccess(params) {
5
+ if (!params.caller) return { allow: false, reason: "no-caller" };
6
+ if (params.owner === null) return { allow: false, reason: "unregistered" };
7
+ if (params.owner !== params.caller) return { allow: false, reason: "cross-account" };
8
+ return { allow: true, reason: "owner" };
9
+ }
10
+
11
+ // ../lib/storage-broker/src/registry.ts
12
+ async function registerResource(session, r) {
13
+ await session.run(
14
+ `MERGE (r:StorageResource {kind: $kind, name: $name})
15
+ ON CREATE SET r.accountId = $accountId,
16
+ r.createdByAgent = 'system',
17
+ r.createdBySource = 'storage-broker',
18
+ r.cfResourceId = $cfResourceId
19
+ ON MATCH SET r.cfResourceId = $cfResourceId`,
20
+ { accountId: r.accountId, kind: r.kind, name: r.name, cfResourceId: r.cfResourceId }
21
+ );
22
+ }
23
+ async function resolveOwner(session, kind, name) {
24
+ const res = await session.run(
25
+ `MATCH (r:StorageResource {kind: $kind, name: $name})
26
+ RETURN r.accountId AS accountId LIMIT 1`,
27
+ { kind, name }
28
+ );
29
+ return res.records.length ? res.records[0].get("accountId") : null;
30
+ }
31
+ async function listResources(session, accountId, kind) {
32
+ const res = await session.run(
33
+ `MATCH (r:StorageResource {accountId: $accountId, kind: $kind})
34
+ RETURN r.name AS name, r.cfResourceId AS cfResourceId
35
+ ORDER BY r.name`,
36
+ { accountId, kind }
37
+ );
38
+ return res.records.map((rec) => ({
39
+ accountId,
40
+ kind,
41
+ name: rec.get("name"),
42
+ cfResourceId: rec.get("cfResourceId")
43
+ }));
44
+ }
45
+
46
+ // ../lib/storage-broker/src/house-credential.ts
47
+ import { readFileSync } from "fs";
48
+ import { join } from "path";
49
+ function readHouseCredential(platformRoot) {
50
+ const path = join(platformRoot, "config", "cloudflare-house.env");
51
+ let raw;
52
+ try {
53
+ raw = readFileSync(path, "utf8");
54
+ } catch {
55
+ throw new Error(`storage-broker: house credential not found at ${path}`);
56
+ }
57
+ const env = {};
58
+ for (const line of raw.split("\n")) {
59
+ const m = line.match(/^\s*([A-Za-z_][A-Za-z0-9_]*)=(.*)$/);
60
+ if (m) env[m[1]] = m[2].trim();
61
+ }
62
+ const apiToken = env.CLOUDFLARE_API_TOKEN;
63
+ const accountId = env.CLOUDFLARE_ACCOUNT_ID;
64
+ if (!apiToken) throw new Error(`storage-broker: CLOUDFLARE_API_TOKEN missing in ${path}`);
65
+ if (!accountId) throw new Error(`storage-broker: CLOUDFLARE_ACCOUNT_ID missing in ${path}`);
66
+ return { apiToken, accountId };
67
+ }
68
+
69
+ // ../lib/storage-broker/src/cf-exec.ts
70
+ import { execFile } from "child_process";
71
+ var defaultRun = (cmd, args, env) => new Promise((resolve, reject) => {
72
+ execFile(cmd, args, { env }, (err, stdout, stderr) => {
73
+ if (err) {
74
+ reject(new Error(`${cmd} ${args.join(" ")} failed: ${err.message}
75
+ ${stderr}`));
76
+ return;
77
+ }
78
+ resolve({ stdout: stdout.toString() });
79
+ });
80
+ });
81
+ function parseJson(raw, context) {
82
+ try {
83
+ return JSON.parse(raw);
84
+ } catch {
85
+ throw new Error(`storage-broker: ${context} returned non-JSON output: ${raw}`);
86
+ }
87
+ }
88
+ function makeCfExec(cred, run = defaultRun) {
89
+ const env = {
90
+ ...process.env,
91
+ CLOUDFLARE_API_TOKEN: cred.apiToken,
92
+ CLOUDFLARE_ACCOUNT_ID: cred.accountId
93
+ };
94
+ return {
95
+ async d1List() {
96
+ const { stdout } = await run("wrangler", ["d1", "list", "--json"], env);
97
+ return parseJson(stdout, "d1 list");
98
+ },
99
+ async d1Create(name) {
100
+ const { stdout } = await run("wrangler", ["d1", "create", name, "--json"], env);
101
+ return parseJson(stdout, "d1 create");
102
+ },
103
+ async d1Query(name, sql) {
104
+ const { stdout } = await run(
105
+ "wrangler",
106
+ ["d1", "execute", name, "--remote", "--json", "--command", sql],
107
+ env
108
+ );
109
+ return parseJson(stdout, "d1 execute");
110
+ },
111
+ async r2List() {
112
+ const { stdout } = await run("wrangler", ["r2", "bucket", "list", "--json"], env);
113
+ return parseJson(stdout, "r2 bucket list");
114
+ },
115
+ async r2Create(name) {
116
+ await run("wrangler", ["r2", "bucket", "create", name], env);
117
+ }
118
+ };
119
+ }
120
+
121
+ // ../lib/storage-broker/src/audit.ts
122
+ var ACCOUNT_WIDE_KEYS = ["CLOUDFLARE_API_TOKEN", "CF_PAGES_D1_TOKEN", "CF_PAGES_TOKEN"];
123
+ async function reconcileStorage(deps) {
124
+ const strays = [];
125
+ const [cfD1, cfR2, regD1, regR2, secretsFiles] = await Promise.all([
126
+ deps.cfD1(),
127
+ deps.cfR2(),
128
+ deps.registeredNames("d1"),
129
+ deps.registeredNames("r2"),
130
+ deps.accountSecretsFiles()
131
+ ]);
132
+ const regD1Set = new Set(regD1);
133
+ for (const name of cfD1) {
134
+ if (!regD1Set.has(name)) strays.push({ kind: "unattributed-d1", detail: name });
135
+ }
136
+ const regR2Set = new Set(regR2);
137
+ for (const name of cfR2) {
138
+ if (!regR2Set.has(name)) strays.push({ kind: "unattributed-r2", detail: name });
139
+ }
140
+ for (const file of secretsFiles) {
141
+ for (const line of file.contents.split("\n")) {
142
+ const key = line.match(/^\s*([A-Za-z_][A-Za-z0-9_]*)=/)?.[1];
143
+ if (key && ACCOUNT_WIDE_KEYS.includes(key)) {
144
+ strays.push({ kind: "account-wide-token", detail: `${file.accountId}:${key}` });
145
+ }
146
+ }
147
+ }
148
+ return { strays };
149
+ }
150
+
151
+ // ../lib/storage-broker/src/remediate.ts
152
+ var STRIP_KEYS = ["CLOUDFLARE_API_TOKEN", "CF_PAGES_D1_TOKEN", "CF_PAGES_TOKEN"];
153
+ function validateMapping(enumerated, mapping) {
154
+ const missing = enumerated.filter((name) => !(name in mapping));
155
+ return { ok: missing.length === 0, missing };
156
+ }
157
+ function stripAccountWideTokens(contents) {
158
+ const kept = contents.split("\n").filter((line) => {
159
+ const key = line.match(/^\s*([A-Za-z_][A-Za-z0-9_]*)=/)?.[1];
160
+ return !(key && STRIP_KEYS.includes(key));
161
+ });
162
+ return kept.join("\n");
163
+ }
164
+
165
+ export {
166
+ authorizeAccess,
167
+ registerResource,
168
+ resolveOwner,
169
+ listResources,
170
+ readHouseCredential,
171
+ makeCfExec,
172
+ reconcileStorage,
173
+ validateMapping,
174
+ stripAccountWideTokens
175
+ };
@@ -1 +1 @@
1
- import{o as e}from"./chunk-Ck5AOu5v.js";import{E as t,S as n,_ as r,x as i,y as a}from"./useSubAccountSwitcher-s6WlRn52.js";import{E as o}from"./useVoiceRecorder-XgpWvXpk.js";import{b as s,y as c}from"./AdminShell-CMu8_Xwn.js";import{t as l}from"./Checkbox-CzD0ORqA.js";var u=`admin-landing-redirected`,d=`/graph`;function f(e){return e.variant===`operator`?!1:e.appState===`chat`&&!e.alreadyRedirected}var p=e(t(),1);function m(e=`admin`){let[t,r]=(0,p.useState)(`loading`),[i,a]=(0,p.useState)(``),[c,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)(()=>{t===`chat`&&fetch(`/api/admin/claude-info`).then(e=>{if(e.ok)return e.json()}).then(e=>{e&&k(e)}).catch(()=>{})},[t]),(0,p.useEffect)(()=>{if(typeof window>`u`)return;let n=!1;try{n=sessionStorage.getItem(u)===`1`}catch{}if(f({appState:t,alreadyRedirected:n,variant:e})){try{sessionStorage.setItem(u,`1`)}catch{}console.info(`[admin-ui] landing-redirect target=${d}`),window.location.replace(d)}},[t,e]);let Y=(0,p.useRef)(null);(0,p.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`){n(`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,p.useEffect)(()=>{t===`connect-claude`&&fetch(`/api/health`).then(e=>e.ok?e.json():null).then(e=>{e?.claude_authenticated&&(K(!0),r(`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`){n(`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 t=c.trim();if(!t){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:t})});if(!e.ok){let t=await e.json().catch(()=>({}));if(e.status===401&&t?.code===`remote-auth-required`){n(`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 n=await e.json();n.pin_configured&&n.claude_authenticated?r(`enter-pin`):n.pin_configured?r(`connect-claude`):h(t.error||`Failed to set PIN.`)}else r(`enter-pin`)}catch{r(`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(o);return}a(``),r(`connect-claude`)}catch(e){console.error(`[admin] connection error:`,e),h(`Could not connect.`)}finally{y(!1)}},[i,v,c]),Q=(0,p.useCallback)(async e=>{e.preventDefault(),h(``),await X(i)},[i]),ee=(0,p.useCallback)(async()=>{T(!0);try{if(!await s())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:t,setAppState:r,pin:i,setPin:a,operatorName:c,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=i();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:i,setShowPin:o,pinLoading:s,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:a,alt:r.productName,className:`connect-logo connect-logo--maxy`}),!r.logoContainsName&&(0,h.jsxs)(`h1`,{className:`connect-title`,children:[`Welcome to `,r.productName]}),(0,h.jsxs)(`p`,{className:`connect-subtitle`,children:[`Tell `,r.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:i}),(0,h.jsx)(c,{variant:`send`,type:`submit`,disabled:!t||!m.trim(),loading:s,"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:i,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:i,setShowPin:o,pinLoading:s,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:a,alt:r.productName,className:`connect-logo connect-logo--maxy`}),!r.logoContainsName&&(0,h.jsx)(`h1`,{className:`connect-title`,children:r.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:i,autoFocus:!0}),(0,h.jsx)(c,{variant:`send`,type:`submit`,disabled:!t,loading:s,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:i,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:i,setAuthLoading:o,pinError:s,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)(c,{variant:`primary`,onClick:T,disabled:i,children:i?(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)(c,{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`})}),s&&(0,h.jsx)(`p`,{className:`admin-pin-error`,style:{textAlign:`center`,padding:`0 20px 16px`},children:s})]}):(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:a,alt:r.productName,className:`connect-logo connect-logo--maxy`}),!r.logoContainsName&&(0,h.jsx)(`span`,{className:`connect-logo-label`,children:r.productName})]})]}),(0,h.jsxs)(`h1`,{className:`connect-title`,children:[`Connect Claude to power `,r.productName]}),(0,h.jsx)(`p`,{className:`connect-subtitle`,children:`Sign in with your Anthropic account to get started.`}),(0,h.jsx)(c,{variant:`primary`,onClick:T,disabled:i,children:i?(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`}),s&&(0,h.jsx)(`p`,{className:`admin-pin-error`,children:s})]})})}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-Ck5AOu5v.js";import{E as t,S as n,_ as r,x as i,y as a}from"./useSubAccountSwitcher-CHEt_m6q.js";import{E as o}from"./useVoiceRecorder-Ctny8qWx.js";import{b as s,y as c}from"./AdminShell-DSQrvZXq.js";import{t as l}from"./Checkbox-CFdt8ljo.js";var u=`admin-landing-redirected`,d=`/graph`;function f(e){return e.variant===`operator`?!1:e.appState===`chat`&&!e.alreadyRedirected}var p=e(t(),1);function m(e=`admin`){let[t,r]=(0,p.useState)(`loading`),[i,a]=(0,p.useState)(``),[c,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)(()=>{t===`chat`&&fetch(`/api/admin/claude-info`).then(e=>{if(e.ok)return e.json()}).then(e=>{e&&k(e)}).catch(()=>{})},[t]),(0,p.useEffect)(()=>{if(typeof window>`u`)return;let n=!1;try{n=sessionStorage.getItem(u)===`1`}catch{}if(f({appState:t,alreadyRedirected:n,variant:e})){try{sessionStorage.setItem(u,`1`)}catch{}console.info(`[admin-ui] landing-redirect target=${d}`),window.location.replace(d)}},[t,e]);let Y=(0,p.useRef)(null);(0,p.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`){n(`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,p.useEffect)(()=>{t===`connect-claude`&&fetch(`/api/health`).then(e=>e.ok?e.json():null).then(e=>{e?.claude_authenticated&&(K(!0),r(`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`){n(`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 t=c.trim();if(!t){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:t})});if(!e.ok){let t=await e.json().catch(()=>({}));if(e.status===401&&t?.code===`remote-auth-required`){n(`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 n=await e.json();n.pin_configured&&n.claude_authenticated?r(`enter-pin`):n.pin_configured?r(`connect-claude`):h(t.error||`Failed to set PIN.`)}else r(`enter-pin`)}catch{r(`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(o);return}a(``),r(`connect-claude`)}catch(e){console.error(`[admin] connection error:`,e),h(`Could not connect.`)}finally{y(!1)}},[i,v,c]),Q=(0,p.useCallback)(async e=>{e.preventDefault(),h(``),await X(i)},[i]),ee=(0,p.useCallback)(async()=>{T(!0);try{if(!await s())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:t,setAppState:r,pin:i,setPin:a,operatorName:c,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=i();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:i,setShowPin:o,pinLoading:s,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:a,alt:r.productName,className:`connect-logo connect-logo--maxy`}),!r.logoContainsName&&(0,h.jsxs)(`h1`,{className:`connect-title`,children:[`Welcome to `,r.productName]}),(0,h.jsxs)(`p`,{className:`connect-subtitle`,children:[`Tell `,r.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:i}),(0,h.jsx)(c,{variant:`send`,type:`submit`,disabled:!t||!m.trim(),loading:s,"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:i,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:i,setShowPin:o,pinLoading:s,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:a,alt:r.productName,className:`connect-logo connect-logo--maxy`}),!r.logoContainsName&&(0,h.jsx)(`h1`,{className:`connect-title`,children:r.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:i,autoFocus:!0}),(0,h.jsx)(c,{variant:`send`,type:`submit`,disabled:!t,loading:s,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:i,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:i,setAuthLoading:o,pinError:s,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)(c,{variant:`primary`,onClick:T,disabled:i,children:i?(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)(c,{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`})}),s&&(0,h.jsx)(`p`,{className:`admin-pin-error`,style:{textAlign:`center`,padding:`0 20px 16px`},children:s})]}):(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:a,alt:r.productName,className:`connect-logo connect-logo--maxy`}),!r.logoContainsName&&(0,h.jsx)(`span`,{className:`connect-logo-label`,children:r.productName})]})]}),(0,h.jsxs)(`h1`,{className:`connect-title`,children:[`Connect Claude to power `,r.productName]}),(0,h.jsx)(`p`,{className:`connect-subtitle`,children:`Sign in with your Anthropic account to get started.`}),(0,h.jsx)(c,{variant:`primary`,onClick:T,disabled:i,children:i?(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`}),s&&(0,h.jsx)(`p`,{className:`admin-pin-error`,children:s})]})})}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};