@zackbart/connecta 0.24.4 → 0.26.0

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 (155) hide show
  1. package/AGENTS.md +43 -12
  2. package/CHANGELOG.md +524 -0
  3. package/README.md +32 -15
  4. package/SECURITY.md +6 -5
  5. package/bin/connecta.mjs +5 -1
  6. package/dist/activity.d.ts +10 -3
  7. package/dist/activity.js +10 -1
  8. package/dist/advertised-schema.js +53 -0
  9. package/dist/artifacts/connector.d.ts +55 -0
  10. package/dist/artifacts/connector.js +724 -0
  11. package/dist/artifacts/document.js +76 -0
  12. package/dist/artifacts/guide.js +140 -0
  13. package/dist/artifacts/html-scan.js +329 -0
  14. package/dist/artifacts/json.js +68 -0
  15. package/dist/artifacts/kv-store.d.ts +20 -0
  16. package/dist/artifacts/kv-store.js +140 -0
  17. package/dist/artifacts/markdown.js +449 -0
  18. package/dist/artifacts/module.d.ts +37 -0
  19. package/dist/artifacts/module.js +60 -0
  20. package/dist/artifacts/operations.d.ts +195 -0
  21. package/dist/artifacts/operations.js +944 -0
  22. package/dist/artifacts/refresh.d.ts +53 -0
  23. package/dist/artifacts/refresh.js +235 -0
  24. package/dist/artifacts/routes.js +194 -0
  25. package/dist/artifacts/types.d.ts +214 -0
  26. package/dist/artifacts/types.js +22 -0
  27. package/dist/artifacts/validate.d.ts +62 -0
  28. package/dist/artifacts/validate.js +652 -0
  29. package/dist/artifacts.d.ts +6 -0
  30. package/dist/artifacts.js +9 -0
  31. package/dist/auth/downstream-oauth.js +490 -106
  32. package/dist/call-admission.js +139 -113
  33. package/dist/catalog-service.js +152 -106
  34. package/dist/catalog.js +297 -38
  35. package/dist/concurrency.js +24 -23
  36. package/dist/connector-access.d.ts +18 -4
  37. package/dist/connector-access.js +65 -20
  38. package/dist/connector-caller.d.ts +8 -0
  39. package/dist/connector-caller.js +19 -0
  40. package/dist/connector-scope.js +6 -37
  41. package/dist/connectors/api.d.ts +2 -2
  42. package/dist/connectors/remote-mcp.d.ts +6 -5
  43. package/dist/connectors/remote-mcp.js +330 -240
  44. package/dist/credential-contract.d.ts +9 -0
  45. package/dist/credential-rules.js +2 -2
  46. package/dist/credentials.d.ts +6 -1
  47. package/dist/credentials.js +45 -3
  48. package/dist/errors.d.ts +16 -1
  49. package/dist/errors.js +28 -0
  50. package/dist/execute.js +745 -282
  51. package/dist/executor-admission.d.ts +11 -1
  52. package/dist/executor-admission.js +145 -63
  53. package/dist/executors/quickjs-runtime.js +4 -2
  54. package/dist/executors/quickjs.js +255 -212
  55. package/dist/fix-prompt.js +37 -0
  56. package/dist/index.d.ts +72 -7
  57. package/dist/index.js +281 -26
  58. package/dist/invocation.js +371 -286
  59. package/dist/meta-tools.js +213 -94
  60. package/dist/module-contracts.d.ts +21 -1
  61. package/dist/oauth-callback-outcome.js +94 -0
  62. package/dist/oauth-sealing.js +29 -0
  63. package/dist/operator-ui/fix-prompts.js +87 -0
  64. package/dist/operator-ui/generated.js +2 -2
  65. package/dist/operator-ui/model.d.ts +103 -1
  66. package/dist/operator-ui/setup-commands.js +53 -0
  67. package/dist/operator-ui/view.js +128 -3
  68. package/dist/program-source.js +321 -0
  69. package/dist/providers/notion.js +2 -2
  70. package/dist/providers/revenuecat.js +32 -5
  71. package/dist/providers/stripe.d.ts +3 -2
  72. package/dist/providers/vercel.js +1 -1
  73. package/dist/registry.d.ts +43 -7
  74. package/dist/registry.js +434 -288
  75. package/dist/resumable.js +1291 -0
  76. package/dist/routes/activity.js +74 -154
  77. package/dist/routes/actor-labels.js +114 -0
  78. package/dist/routes/credentials.js +196 -163
  79. package/dist/routes/mcp.js +228 -112
  80. package/dist/routes/oauth-management.js +73 -71
  81. package/dist/routes/oauth.js +44 -16
  82. package/dist/routes/operator.js +83 -0
  83. package/dist/routes/shared.d.ts +25 -1
  84. package/dist/routes/shared.js +20 -2
  85. package/dist/routes/ui-data.js +211 -0
  86. package/dist/routes/ui.js +76 -35
  87. package/dist/run-journal.js +347 -0
  88. package/dist/runtime/admission.js +43 -0
  89. package/dist/runtime/call-admission.js +67 -0
  90. package/dist/runtime/connector-scope.js +72 -0
  91. package/dist/runtime/run.js +174 -0
  92. package/dist/runtime/services.js +130 -0
  93. package/dist/runtime/shared-read.js +106 -0
  94. package/dist/runtime/storage.js +66 -0
  95. package/dist/server.js +137 -89
  96. package/dist/skills.js +28 -9
  97. package/dist/storage/file.js +39 -2
  98. package/dist/storage/memory.js +28 -16
  99. package/dist/timeout.js +39 -43
  100. package/dist/tool-safety.d.ts +27 -1
  101. package/dist/tool-safety.js +31 -0
  102. package/dist/types.d.ts +45 -7
  103. package/dist/ui.d.ts +25 -4
  104. package/dist/ui.js +77 -167
  105. package/dist/url-safety.js +157 -0
  106. package/dist/version.d.ts +1 -1
  107. package/dist/version.js +1 -1
  108. package/documentation/architecture.md +367 -16
  109. package/documentation/auth.md +163 -2
  110. package/documentation/code-mode.md +274 -56
  111. package/documentation/meta-tools.md +200 -44
  112. package/ethos.md +46 -47
  113. package/examples/worker/AGENTS.md +6 -0
  114. package/examples/worker/README.md +224 -14
  115. package/examples/worker/src/d1-activity-row.ts +14 -2
  116. package/examples/worker/src/d1-activity.ts +4 -2
  117. package/examples/worker/src/d1-storage.ts +116 -0
  118. package/examples/worker/src/index.ts +42 -7
  119. package/examples/worker/src/r2-artifact-blobs.ts +29 -0
  120. package/examples/worker/wrangler.jsonc +21 -5
  121. package/package.json +16 -4
  122. package/templates/node/AGENTS.md +9 -2
  123. package/templates/node/README.md +31 -3
  124. package/templates/node/package.json +1 -1
  125. package/templates/node/src/index.ts +27 -0
  126. package/dist/auth/downstream-oauth.d.ts +0 -200
  127. package/dist/catalog-fingerprint.d.ts +0 -19
  128. package/dist/catalog-limits.d.ts +0 -9
  129. package/dist/catalog-service.d.ts +0 -263
  130. package/dist/catalog.d.ts +0 -87
  131. package/dist/concurrency.d.ts +0 -3
  132. package/dist/connectors/guarded-fetch.d.ts +0 -96
  133. package/dist/credential-rules.d.ts +0 -85
  134. package/dist/execute.d.ts +0 -154
  135. package/dist/executor-result.d.ts +0 -10
  136. package/dist/executors/quickjs-child.d.ts +0 -1
  137. package/dist/executors/quickjs-protocol.d.ts +0 -67
  138. package/dist/favicon.d.ts +0 -1
  139. package/dist/identity.d.ts +0 -4
  140. package/dist/invocation.d.ts +0 -74
  141. package/dist/mcp-result.d.ts +0 -8
  142. package/dist/meta-tools.d.ts +0 -129
  143. package/dist/operator-ui/generated.d.ts +0 -2
  144. package/dist/operator-ui/view.d.ts +0 -188
  145. package/dist/result-shapes.d.ts +0 -13
  146. package/dist/retired-toolkits.d.ts +0 -2
  147. package/dist/routes/activity.d.ts +0 -2
  148. package/dist/routes/credentials.d.ts +0 -2
  149. package/dist/routes/mcp.d.ts +0 -10
  150. package/dist/routes/oauth-management.d.ts +0 -2
  151. package/dist/routes/oauth.d.ts +0 -2
  152. package/dist/routes/ui.d.ts +0 -2
  153. package/dist/server.d.ts +0 -9
  154. package/dist/skills.d.ts +0 -44
  155. package/dist/timeout.d.ts +0 -21
@@ -1,4 +1,4 @@
1
1
  // Generated by scripts/build-operator-ui.mjs. Do not edit.
2
2
  // Source: src/operator-ui/app/main.tsx and src/operator-ui/browser.css.
3
- export const OPERATOR_UI_CSS = "/* src/operator-ui/browser.css */\n:root {\n color-scheme: light;\n --accent: #2f5fe0;\n --radius: 10px;\n --sans:\n ui-sans-serif,\n system-ui,\n -apple-system,\n \"Segoe UI\",\n Roboto,\n \"Helvetica Neue\",\n Arial,\n sans-serif;\n --mono:\n ui-monospace,\n \"SF Mono\",\n Menlo,\n Monaco,\n \"Cascadia Code\",\n Consolas,\n monospace;\n --bg: #f6f7f9;\n --surface: #ffffff;\n --surface-2: #f1f3f6;\n --border: #e2e5ea;\n --border-strong: #cdd2da;\n --text: #131820;\n --muted: #5b6472;\n --ok: #12734a;\n --warn: #9a5b06;\n --danger: #bb3226;\n --on-accent: #ffffff;\n --link: var(--accent);\n --tint: color-mix(in srgb, var(--accent) 8%, var(--surface));\n --shell: 68rem;\n --pad: 1.25rem;\n --gap: 1rem;\n}\n@media (prefers-color-scheme: dark) {\n html:not([data-scheme=light]) {\n color-scheme: dark;\n }\n}\nhtml[data-scheme=dark] {\n color-scheme: dark;\n}\n@media (prefers-color-scheme: dark) {\n html:not([data-scheme=light]) {\n --bg: #0d1016;\n --surface: #151a21;\n --surface-2: #1c222c;\n --border: #262d39;\n --border-strong: #38414f;\n --text: #e6eaf1;\n --muted: #97a1b2;\n --ok: #4cc48c;\n --warn: #e2a33f;\n --danger: #f4776c;\n --link: color-mix(in srgb, var(--accent) 55%, #ffffff);\n --tint: color-mix(in srgb, var(--accent) 16%, var(--surface));\n }\n}\nhtml[data-scheme=dark] {\n --bg: #0d1016;\n --surface: #151a21;\n --surface-2: #1c222c;\n --border: #262d39;\n --border-strong: #38414f;\n --text: #e6eaf1;\n --muted: #97a1b2;\n --ok: #4cc48c;\n --warn: #e2a33f;\n --danger: #f4776c;\n --link: color-mix(in srgb, var(--accent) 55%, #ffffff);\n --tint: color-mix(in srgb, var(--accent) 16%, var(--surface));\n}\n* {\n box-sizing: border-box;\n}\nhtml {\n background: var(--bg);\n color: var(--text);\n font-family: var(--sans);\n font-size: 16px;\n line-height: 1.5;\n -webkit-font-smoothing: antialiased;\n}\nbody {\n margin: 0;\n min-height: 100vh;\n}\n:is(h1, h2, h3, p, ul, ol) {\n margin: 0;\n padding: 0;\n}\n:is(h1, h2, h3) {\n font-weight: 600;\n line-height: 1.3;\n}\nh1 {\n font-size: 1.5rem;\n letter-spacing: -.01em;\n}\nh2 {\n font-size: 1rem;\n}\n:is(ul, ol) {\n list-style: none;\n}\na {\n color: var(--link);\n text-decoration-thickness: 1px;\n text-underline-offset: 2px;\n}\nbutton,\ninput {\n font: inherit;\n}\n:is(a, button, input, summary):focus-visible {\n border-radius: calc(var(--radius) / 2);\n outline: 2px solid var(--link);\n outline-offset: 2px;\n}\n.skip-link {\n background: var(--surface);\n border: 1px solid var(--border);\n border-radius: var(--radius);\n left: var(--pad);\n padding: .5rem .75rem;\n position: fixed;\n top: -4rem;\n z-index: 10;\n}\n.skip-link:focus {\n top: var(--pad);\n}\n.shell {\n margin: 0 auto;\n max-width: var(--shell);\n padding-left: var(--pad);\n padding-right: var(--pad);\n}\n.cap,\n.meta {\n color: var(--muted);\n font-size: .875rem;\n}\n.mono {\n font-family: var(--mono);\n font-size: .8125rem;\n}\n.visually-hidden {\n clip-path: inset(50%);\n height: 1px;\n overflow: hidden;\n position: absolute;\n white-space: nowrap;\n width: 1px;\n}\n.masthead {\n align-items: center;\n background: var(--surface);\n border-bottom: 1px solid var(--border);\n display: flex;\n gap: var(--gap);\n justify-content: space-between;\n max-width: none;\n padding-bottom: .75rem;\n padding-top: .75rem;\n position: sticky;\n top: 0;\n z-index: 5;\n}\n.masthead-inner {\n align-items: center;\n display: flex;\n gap: var(--gap);\n justify-content: space-between;\n margin: 0 auto;\n max-width: var(--shell);\n width: 100%;\n}\n.mast-nav,\n.mast-actions,\n.page-nav,\n.session-actions {\n align-items: center;\n display: flex;\n flex-wrap: wrap;\n gap: .25rem;\n}\n.mast-nav {\n gap: var(--gap);\n}\n.mast-actions {\n gap: var(--gap);\n}\n.navlink {\n background: none;\n border: 0;\n border-radius: calc(var(--radius) - 2px);\n color: var(--muted);\n cursor: pointer;\n font-size: .9375rem;\n padding: .35rem .6rem;\n text-decoration: none;\n}\n.navlink:hover {\n background: var(--surface-2);\n color: var(--text);\n}\n.navlink[aria-current=page] {\n background: var(--tint);\n color: var(--link);\n font-weight: 500;\n}\n.brand,\n.product {\n padding-left: 0;\n padding-right: 0;\n text-decoration: none;\n}\n.brand {\n color: var(--text);\n font-weight: 600;\n}\n.brand:hover,\n.product:hover {\n background: none;\n}\n.product {\n color: var(--muted);\n}\n.page {\n padding-bottom: 4rem;\n padding-top: 2rem;\n}\n.lead {\n margin-bottom: 1.5rem;\n}\n.lead-copy {\n color: var(--muted);\n display: grid;\n gap: .5rem;\n margin-top: .35rem;\n}\n.lead-copy p {\n max-width: 60ch;\n}\n.btn {\n background: var(--surface);\n border: 1px solid var(--border-strong);\n border-radius: calc(var(--radius) - 2px);\n color: var(--text);\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n font-size: .875rem;\n gap: .35rem;\n padding: .35rem .7rem;\n text-decoration: none;\n white-space: nowrap;\n}\n.btn:hover {\n background: var(--surface-2);\n}\n.btn:disabled {\n cursor: not-allowed;\n opacity: .55;\n}\n.btn.primary {\n background: var(--accent);\n border-color: var(--accent);\n color: var(--on-accent);\n}\n.btn.primary:hover {\n background: color-mix(in srgb, var(--accent) 88%, black);\n}\n.btn.danger {\n color: var(--danger);\n}\n.btn.danger:hover {\n background: color-mix(in srgb, var(--danger) 10%, var(--surface));\n}\n.btn.quiet {\n background: none;\n border-color: var(--border);\n color: var(--muted);\n}\n.btn.quiet:hover {\n background: var(--surface-2);\n color: var(--text);\n}\ninput {\n background: var(--surface);\n border: 1px solid var(--border-strong);\n border-radius: calc(var(--radius) - 2px);\n color: var(--text);\n min-height: 2.25rem;\n padding: .3rem .6rem;\n width: 100%;\n}\ninput::placeholder {\n color: var(--muted);\n}\n.row {\n align-items: center;\n display: flex;\n flex-wrap: wrap;\n gap: .5rem;\n}\n.row input {\n flex: 1 1 14rem;\n width: auto;\n}\n.actions {\n display: flex;\n flex-wrap: wrap;\n gap: .5rem;\n}\n.dot {\n border-radius: 50%;\n display: inline-block;\n flex: none;\n height: .5rem;\n width: .5rem;\n background: var(--muted);\n}\n.dot.ok,\n.dot.success {\n background: var(--ok);\n}\n.dot.auth_required {\n background: var(--warn);\n}\n.dot.error,\n.dot.timeout {\n background: var(--danger);\n}\n.dot.loading {\n background: var(--border-strong);\n}\n.badge {\n align-items: center;\n background: var(--surface-2);\n border-radius: 999px;\n color: var(--muted);\n display: inline-flex;\n font-size: .75rem;\n gap: .3rem;\n line-height: 1.6;\n padding: .1rem .5rem;\n white-space: nowrap;\n}\n.badge.ok {\n background: color-mix(in srgb, var(--ok) 12%, var(--surface));\n color: var(--ok);\n}\n.badge.warn {\n background: color-mix(in srgb, var(--warn) 14%, var(--surface));\n color: var(--warn);\n}\n.badge.danger {\n background: color-mix(in srgb, var(--danger) 12%, var(--surface));\n color: var(--danger);\n}\n.badge.accent {\n background: var(--tint);\n color: var(--link);\n}\n.section {\n display: grid;\n gap: .75rem;\n margin-top: 1.75rem;\n}\n.section-head {\n align-items: baseline;\n display: flex;\n gap: var(--gap);\n justify-content: space-between;\n}\n.empty,\n.unavailable {\n background: var(--surface);\n border: 1px dashed var(--border-strong);\n border-radius: var(--radius);\n color: var(--muted);\n padding: 1.5rem var(--pad);\n text-align: center;\n}\n.unavailable {\n text-align: left;\n}\n.msg {\n background: color-mix(in srgb, var(--danger) 8%, var(--surface));\n border: 1px solid color-mix(in srgb, var(--danger) 28%, var(--surface));\n border-radius: calc(var(--radius) - 2px);\n color: var(--danger);\n font-size: .875rem;\n padding: .5rem .75rem;\n}\n.error-notice {\n color: var(--danger);\n}\n.notice:empty {\n block-size: 0;\n margin: 0;\n}\n.summary {\n color: var(--muted);\n font-size: .875rem;\n}\n.summary .sep {\n opacity: .5;\n}\n.summary .warn {\n color: var(--warn);\n}\n.summary .danger {\n color: var(--danger);\n}\n.endpoint {\n align-items: center;\n background: var(--surface);\n border: 1px solid var(--border);\n border-radius: var(--radius);\n display: flex;\n gap: .75rem;\n justify-content: space-between;\n padding: .5rem .5rem .5rem .75rem;\n}\n.endpoint code {\n overflow-wrap: anywhere;\n}\n.rows {\n background: var(--surface);\n border: 1px solid var(--border);\n border-radius: var(--radius);\n overflow: hidden;\n}\n.rows > * + * {\n border-top: 1px solid var(--border);\n}\n.conn[open] {\n background: var(--surface-2);\n}\n.conn-head {\n align-items: center;\n cursor: pointer;\n display: flex;\n gap: .75rem;\n justify-content: space-between;\n list-style: none;\n padding: .7rem var(--pad);\n}\n.conn-head::-webkit-details-marker {\n display: none;\n}\n.conn-head:focus-visible {\n outline-offset: -2px;\n}\n.conn-head:hover {\n background: var(--surface-2);\n}\n.conn-main {\n align-items: center;\n display: flex;\n gap: .6rem;\n min-width: 0;\n}\n.conn-name {\n font-size: 1rem;\n font-weight: 500;\n overflow-wrap: anywhere;\n}\n.conn-id {\n color: var(--muted);\n}\n.conn-badges {\n align-items: center;\n display: flex;\n flex-wrap: wrap;\n gap: .35rem;\n justify-content: flex-end;\n}\n.conn-caret {\n border-right: 1.5px solid var(--muted);\n border-bottom: 1.5px solid var(--muted);\n flex: none;\n height: .4rem;\n rotate: -45deg;\n transform-origin: center;\n width: .4rem;\n}\n.conn[open] .conn-caret {\n rotate: 45deg;\n}\n.conn-body {\n background: var(--surface);\n border-top: 1px solid var(--border);\n display: grid;\n gap: .75rem;\n padding: var(--pad);\n}\n.conn-note {\n color: var(--muted);\n max-width: 70ch;\n}\n.subcard {\n background: var(--surface-2);\n border: 1px solid var(--border);\n border-radius: calc(var(--radius) - 2px);\n display: grid;\n gap: .5rem;\n padding: .75rem;\n}\n.subcard-head {\n align-items: baseline;\n display: flex;\n flex-wrap: wrap;\n gap: .5rem;\n justify-content: space-between;\n}\ndetails > .subcard,\ndetails > .tool-list {\n margin-top: .5rem;\n}\n.tool-list {\n display: grid;\n gap: .4rem;\n max-height: 22rem;\n overflow: auto;\n}\n.filter {\n flex: 0 1 18rem;\n min-width: 10rem;\n width: auto;\n}\n.connector-drift {\n display: grid;\n gap: .15rem;\n}\n.tool {\n display: grid;\n gap: .1rem;\n border-left: 2px solid var(--border-strong);\n padding-left: .6rem;\n}\n.tool code {\n font-family: var(--mono);\n font-size: .8125rem;\n}\n.td {\n color: var(--muted);\n font-size: .8125rem;\n}\ndetails > summary {\n cursor: pointer;\n}\n.disclosure {\n color: var(--link);\n font-size: .875rem;\n list-style: none;\n}\n.disclosure::-webkit-details-marker {\n display: none;\n}\n.disclosure::before {\n content: \"▸ \";\n}\ndetails[open] > .disclosure::before {\n content: \"▾ \";\n}\n.drift-counts {\n display: grid;\n gap: .5rem;\n grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));\n margin-top: .5rem;\n}\n.drift-count {\n background: var(--surface);\n border: 1px solid var(--border);\n border-radius: calc(var(--radius) - 2px);\n display: grid;\n gap: .1rem;\n padding: .4rem .6rem;\n}\n.drift-count.flagged {\n border-color: color-mix(in srgb, var(--warn) 45%, var(--surface));\n}\n.drift-count-value {\n font-size: 1.125rem;\n font-weight: 600;\n}\n.drift-count.flagged .drift-count-value {\n color: var(--warn);\n}\n.drift-count-label {\n color: var(--muted);\n font-size: .75rem;\n}\n.credential-fields,\n.credential-field-summary {\n display: grid;\n gap: .5rem;\n}\n.credential-field {\n display: grid;\n gap: .25rem;\n}\n.credential-field label {\n color: var(--muted);\n font-size: .8125rem;\n}\n.credential-field-summary > div {\n display: flex;\n gap: .5rem;\n justify-content: space-between;\n}\n.credential-form {\n display: grid;\n gap: .5rem;\n}\n.credential-form .actions {\n justify-content: flex-end;\n}\n.activity-list {\n background: var(--surface);\n border: 1px solid var(--border);\n border-radius: var(--radius);\n overflow: hidden;\n}\n.activity-list > * + * {\n border-top: 1px solid var(--border);\n}\n.activity-item {\n align-items: center;\n display: grid;\n gap: .5rem var(--gap);\n grid-template-columns: minmax(0, 14rem) minmax(0, 1fr) auto;\n padding: .6rem var(--pad);\n}\n.activity-stamp {\n align-items: center;\n display: flex;\n gap: .6rem;\n min-width: 0;\n}\n.activity-time {\n display: block;\n font-size: .8125rem;\n}\n.activity-actor {\n color: var(--muted);\n font-size: .8125rem;\n}\n.activity-actor-id {\n color: var(--muted);\n}\n.activity-address {\n font-family: var(--mono);\n font-size: .8125rem;\n overflow-wrap: anywhere;\n}\n.activity-detail {\n color: var(--muted);\n font-size: .8125rem;\n}\n.activity-outcome {\n text-align: right;\n}\n.activity-item.error .activity-outcome,\n.activity-item.timeout .activity-outcome {\n color: var(--danger);\n}\n.activity-item.success .activity-outcome {\n color: var(--ok);\n}\n.activity-empty {\n color: var(--muted);\n padding: 1.5rem var(--pad);\n text-align: center;\n}\n.activity-more {\n margin-top: .75rem;\n}\n.gate {\n display: grid;\n gap: .75rem;\n margin: 3rem auto 0;\n max-width: 30rem;\n}\n.gate h1 {\n font-size: 1.25rem;\n}\n.gate .row {\n flex-wrap: nowrap;\n}\n@media (max-width: 40rem) {\n :root {\n --pad: 1rem;\n }\n .conn-head {\n align-items: flex-start;\n flex-direction: column;\n gap: .4rem;\n }\n .conn-badges {\n justify-content: flex-start;\n }\n .activity-item {\n grid-template-columns: minmax(0, 1fr);\n }\n .activity-outcome {\n text-align: left;\n }\n}\n";
4
- export const OPERATOR_UI_SCRIPT = "\"use strict\";\n(() => {\n // node_modules/preact/dist/preact.module.js\n var n;\n var l;\n var u;\n var t;\n var i;\n var r;\n var o;\n var e;\n var f;\n var c;\n var a;\n var s;\n var h;\n var p;\n var v;\n var y;\n var d = {};\n var w = [];\n var _ = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;\n var g = Array.isArray;\n function m(n2, l3) {\n for (var u4 in l3) n2[u4] = l3[u4];\n return n2;\n }\n function b(n2) {\n n2 && n2.parentNode && n2.parentNode.removeChild(n2);\n }\n function k(l3, u4, t3) {\n var i3, r3, o3, e3 = {};\n for (o3 in u4) \"key\" == o3 ? i3 = u4[o3] : \"ref\" == o3 ? r3 = u4[o3] : e3[o3] = u4[o3];\n if (arguments.length > 2 && (e3.children = arguments.length > 3 ? n.call(arguments, 2) : t3), \"function\" == typeof l3 && null != l3.defaultProps) for (o3 in l3.defaultProps) void 0 === e3[o3] && (e3[o3] = l3.defaultProps[o3]);\n return x(l3, e3, i3, r3, null);\n }\n function x(n2, t3, i3, r3, o3) {\n var e3 = { type: n2, props: t3, key: i3, ref: r3, __k: null, __: null, __b: 0, __e: null, __c: null, constructor: void 0, __v: null == o3 ? ++u : o3, __i: -1, __u: 0 };\n return null == o3 && null != l.vnode && l.vnode(e3), e3;\n }\n function S(n2) {\n return n2.children;\n }\n function C(n2, l3) {\n this.props = n2, this.context = l3;\n }\n function $(n2, l3) {\n if (null == l3) return n2.__ ? $(n2.__, n2.__i + 1) : null;\n for (var u4; l3 < n2.__k.length; l3++) if (null != (u4 = n2.__k[l3]) && null != u4.__e) return u4.__e;\n return \"function\" == typeof n2.type ? $(n2) : null;\n }\n function I(n2) {\n if (n2.__P && n2.__d) {\n var u4 = n2.__v, t3 = u4.__e, i3 = [], r3 = [], o3 = m({}, u4);\n o3.__v = u4.__v + 1, l.vnode && l.vnode(o3), q(n2.__P, o3, u4, n2.__n, n2.__P.namespaceURI, 32 & u4.__u ? [t3] : null, i3, null == t3 ? $(u4) : t3, !!(32 & u4.__u), r3), o3.__v = u4.__v, o3.__.__k[o3.__i] = o3, D(i3, o3, r3), u4.__e = u4.__ = null, o3.__e != t3 && P(o3);\n }\n }\n function P(n2) {\n if (null != (n2 = n2.__) && null != n2.__c) return n2.__e = n2.__c.base = null, n2.__k.some(function(l3) {\n if (null != l3 && null != l3.__e) return n2.__e = n2.__c.base = l3.__e;\n }), P(n2);\n }\n function A(n2) {\n (!n2.__d && (n2.__d = true) && i.push(n2) && !H.__r++ || r != l.debounceRendering) && ((r = l.debounceRendering) || o)(H);\n }\n function H() {\n try {\n for (var n2, l3 = 1; i.length; ) i.length > l3 && i.sort(e), n2 = i.shift(), l3 = i.length, I(n2);\n } finally {\n i.length = H.__r = 0;\n }\n }\n function L(n2, l3, u4, t3, i3, r3, o3, e3, f4, c3, a3) {\n var s3, h3, p3, v3, y3, _3, g2 = t3 && t3.__k || w, m3 = l3.length;\n for (f4 = T(u4, l3, g2, f4, m3), s3 = 0; s3 < m3; s3++) null != (p3 = u4.__k[s3]) && (h3 = -1 != p3.__i && g2[p3.__i] || d, p3.__i = s3, _3 = q(n2, p3, h3, i3, r3, o3, e3, f4, c3, a3), v3 = p3.__e, p3.ref && h3.ref != p3.ref && (h3.ref && J(h3.ref, null, p3), a3.push(p3.ref, p3.__c || v3, p3)), null == y3 && null != v3 && (y3 = v3), 4 & p3.__u ? (f4 = j(p3, f4, n2), h3.__e && (h3.__e = null)) : \"function\" == typeof p3.type && void 0 !== _3 ? f4 = _3 : v3 && (f4 = v3.nextSibling), p3.__u &= -7);\n return u4.__e = y3, f4;\n }\n function T(n2, l3, u4, t3, i3) {\n var r3, o3, e3, f4, c3, a3 = u4.length, s3 = a3, h3 = 0;\n for (n2.__k = new Array(i3), r3 = 0; r3 < i3; r3++) null != (o3 = l3[r3]) && \"boolean\" != typeof o3 && \"function\" != typeof o3 ? (\"string\" == typeof o3 || \"number\" == typeof o3 || \"bigint\" == typeof o3 || o3.constructor == String ? o3 = n2.__k[r3] = x(null, o3, null, null, null) : g(o3) ? o3 = n2.__k[r3] = x(S, { children: o3 }, null, null, null) : void 0 === o3.constructor && o3.__b > 0 ? o3 = n2.__k[r3] = x(o3.type, o3.props, o3.key, o3.ref ? o3.ref : null, o3.__v) : n2.__k[r3] = o3, f4 = r3 + h3, o3.__ = n2, o3.__b = n2.__b + 1, e3 = null, -1 != (c3 = o3.__i = O(o3, u4, f4, s3)) && (s3--, (e3 = u4[c3]) && (e3.__u |= 2)), null == e3 || null == e3.__v ? (-1 == c3 && (i3 > a3 ? h3-- : i3 < a3 && h3++), \"function\" != typeof o3.type && (o3.__u |= 4)) : c3 != f4 && (c3 == f4 - 1 ? h3-- : c3 == f4 + 1 ? h3++ : (c3 > f4 ? h3-- : h3++, o3.__u |= 4))) : n2.__k[r3] = null;\n if (s3) for (r3 = 0; r3 < a3; r3++) null != (e3 = u4[r3]) && 0 == (2 & e3.__u) && (e3.__e == t3 && (t3 = $(e3)), K(e3, e3));\n return t3;\n }\n function j(n2, l3, u4) {\n var t3, i3;\n if (\"function\" == typeof n2.type) {\n for (t3 = n2.__k, i3 = 0; t3 && i3 < t3.length; i3++) t3[i3] && (t3[i3].__ = n2, l3 = j(t3[i3], l3, u4));\n return l3;\n }\n n2.__e != l3 && (l3 && n2.type && !l3.parentNode && (l3 = $(n2)), l3 = u4.insertBefore(n2.__e, l3 || null));\n do {\n l3 = l3 && l3.nextSibling;\n } while (null != l3 && 8 == l3.nodeType);\n return l3;\n }\n function O(n2, l3, u4, t3) {\n var i3, r3, o3, e3 = n2.key, f4 = n2.type, c3 = l3[u4], a3 = null != c3 && 0 == (2 & c3.__u);\n if (null === c3 && null == e3 || a3 && e3 == c3.key && f4 == c3.type) return u4;\n if (t3 > (a3 ? 1 : 0)) {\n for (i3 = u4 - 1, r3 = u4 + 1; i3 >= 0 || r3 < l3.length; ) if (null != (c3 = l3[o3 = i3 >= 0 ? i3-- : r3++]) && 0 == (2 & c3.__u) && e3 == c3.key && f4 == c3.type) return o3;\n }\n return -1;\n }\n function z(n2, l3, u4) {\n \"-\" == l3[0] ? n2.setProperty(l3, null == u4 ? \"\" : u4) : n2[l3] = null == u4 ? \"\" : \"number\" != typeof u4 || _.test(l3) ? u4 : u4 + \"px\";\n }\n function N(n2, l3, u4, t3, i3) {\n var r3, o3;\n n: if (\"style\" == l3) if (\"string\" == typeof u4) n2.style.cssText = u4;\n else {\n if (\"string\" == typeof t3 && (n2.style.cssText = t3 = \"\"), t3) for (l3 in t3) u4 && l3 in u4 || z(n2.style, l3, \"\");\n if (u4) for (l3 in u4) t3 && u4[l3] == t3[l3] || z(n2.style, l3, u4[l3]);\n }\n else if (\"o\" == l3[0] && \"n\" == l3[1]) r3 = l3 != (l3 = l3.replace(s, \"$1\")), o3 = l3.toLowerCase(), l3 = o3 in n2 || \"onFocusOut\" == l3 || \"onFocusIn\" == l3 ? o3.slice(2) : l3.slice(2), n2.l || (n2.l = {}), n2.l[l3 + r3] = u4, u4 ? t3 ? u4[a] = t3[a] : (u4[a] = h, n2.addEventListener(l3, r3 ? v : p, r3)) : n2.removeEventListener(l3, r3 ? v : p, r3);\n else {\n if (\"http://www.w3.org/2000/svg\" == i3) l3 = l3.replace(/xlink(H|:h)/, \"h\").replace(/sName$/, \"s\");\n else if (\"width\" != l3 && \"height\" != l3 && \"href\" != l3 && \"list\" != l3 && \"form\" != l3 && \"tabIndex\" != l3 && \"download\" != l3 && \"rowSpan\" != l3 && \"colSpan\" != l3 && \"role\" != l3 && \"popover\" != l3 && l3 in n2) try {\n n2[l3] = null == u4 ? \"\" : u4;\n break n;\n } catch (n3) {\n }\n \"function\" == typeof u4 || (null == u4 || false === u4 && \"-\" != l3[4] ? n2.removeAttribute(l3) : n2.setAttribute(l3, \"popover\" == l3 && 1 == u4 ? \"\" : u4));\n }\n }\n function V(n2) {\n return function(u4) {\n if (this.l) {\n var t3 = this.l[u4.type + n2];\n if (null == u4[c]) u4[c] = h++;\n else if (u4[c] < t3[a]) return;\n return t3(l.event ? l.event(u4) : u4);\n }\n };\n }\n function q(n2, u4, t3, i3, r3, o3, e3, f4, c3, a3) {\n var s3, h3, p3, v3, y3, d3, _3, k3, x2, M, I2, P2, A2, H2, T2, j3, F = u4.type;\n if (void 0 !== u4.constructor) return null;\n 128 & t3.__u && (c3 = !!(32 & t3.__u), o3 = [f4 = u4.__e = t3.__e]), (s3 = l.__b) && s3(u4);\n n: if (\"function\" == typeof F) {\n h3 = e3.length;\n try {\n if (x2 = u4.props, M = F.prototype && F.prototype.render, I2 = (s3 = F.contextType) && i3[s3.__c], P2 = s3 ? I2 ? I2.props.value : s3.__ : i3, t3.__c ? k3 = (p3 = u4.__c = t3.__c).__ = p3.__E : (M ? u4.__c = p3 = new F(x2, P2) : (u4.__c = p3 = new C(x2, P2), p3.constructor = F, p3.render = Q), I2 && I2.sub(p3), p3.state || (p3.state = {}), p3.__n = i3, v3 = p3.__d = true, p3.__h = [], p3._sb = []), M && null == p3.__s && (p3.__s = p3.state), M && null != F.getDerivedStateFromProps && (p3.__s == p3.state && (p3.__s = m({}, p3.__s)), m(p3.__s, F.getDerivedStateFromProps(x2, p3.__s))), y3 = p3.props, d3 = p3.state, p3.__v = u4, v3) M && null == F.getDerivedStateFromProps && null != p3.componentWillMount && p3.componentWillMount(), M && null != p3.componentDidMount && p3.__h.push(p3.componentDidMount);\n else {\n if (M && null == F.getDerivedStateFromProps && x2 !== y3 && null != p3.componentWillReceiveProps && p3.componentWillReceiveProps(x2, P2), u4.__v == t3.__v || !p3.__e && null != p3.shouldComponentUpdate && false === p3.shouldComponentUpdate(x2, p3.__s, P2)) {\n u4.__v != t3.__v && (p3.props = x2, p3.state = p3.__s, p3.__d = false), u4.__e = t3.__e, u4.__k = t3.__k, u4.__k.some(function(n3) {\n n3 && (n3.__ = u4);\n }), w.push.apply(p3.__h, p3._sb), p3._sb = [], p3.__h.length && e3.push(p3), f4 = $(t3);\n break n;\n }\n null != p3.componentWillUpdate && p3.componentWillUpdate(x2, p3.__s, P2), M && null != p3.componentDidUpdate && p3.__h.push(function() {\n p3.componentDidUpdate(y3, d3, _3);\n });\n }\n if (p3.context = P2, p3.props = x2, p3.__P = n2, p3.__e = false, A2 = l.__r, H2 = 0, M) p3.state = p3.__s, p3.__d = false, A2 && A2(u4), s3 = p3.render(p3.props, p3.state, p3.context), w.push.apply(p3.__h, p3._sb), p3._sb = [];\n else do {\n p3.__d = false, A2 && A2(u4), s3 = p3.render(p3.props, p3.state, p3.context), p3.state = p3.__s;\n } while (p3.__d && ++H2 < 25);\n p3.state = p3.__s, null != p3.getChildContext && (i3 = m(m({}, i3), p3.getChildContext())), M && !v3 && null != p3.getSnapshotBeforeUpdate && (_3 = p3.getSnapshotBeforeUpdate(y3, d3)), T2 = null != s3 && s3.type === S && null == s3.key ? E(s3.props.children) : s3, f4 = L(n2, g(T2) ? T2 : [T2], u4, t3, i3, r3, o3, e3, f4, c3, a3), p3.base = u4.__e, u4.__u &= -161, p3.__h.length && e3.push(p3), k3 && (p3.__E = p3.__ = null);\n } catch (n3) {\n if (e3.length = h3, u4.__v = null, c3 || null != o3) {\n if (n3.then) {\n for (u4.__u |= c3 ? 160 : 128; f4 && 8 == f4.nodeType && f4.nextSibling; ) f4 = f4.nextSibling;\n null != o3 && (o3[o3.indexOf(f4)] = null), u4.__e = f4;\n } else if (null != o3) for (j3 = o3.length; j3--; ) b(o3[j3]);\n } else u4.__e = t3.__e;\n null == u4.__k && (u4.__k = t3.__k || []), n3.then || B(u4), l.__e(n3, u4, t3);\n }\n } else null == o3 && u4.__v == t3.__v ? (u4.__k = t3.__k, u4.__e = t3.__e) : f4 = u4.__e = G(t3.__e, u4, t3, i3, r3, o3, e3, c3, a3);\n return (s3 = l.diffed) && s3(u4), 128 & u4.__u ? void 0 : f4;\n }\n function B(n2) {\n n2 && (n2.__c && (n2.__c.__e = true), n2.__k && n2.__k.some(B));\n }\n function D(n2, u4, t3) {\n for (var i3 = 0; i3 < t3.length; i3++) J(t3[i3], t3[++i3], t3[++i3]);\n l.__c && l.__c(u4, n2), n2.some(function(u5) {\n try {\n n2 = u5.__h, u5.__h = [], n2.some(function(n3) {\n n3.call(u5);\n });\n } catch (n3) {\n l.__e(n3, u5.__v);\n }\n });\n }\n function E(n2) {\n return \"object\" != typeof n2 || null == n2 || n2.__b > 0 ? n2 : g(n2) ? n2.map(E) : void 0 !== n2.constructor ? null : m({}, n2);\n }\n function G(u4, t3, i3, r3, o3, e3, f4, c3, a3) {\n var s3, h3, p3, v3, y3, w3, _3, m3 = i3.props || d, k3 = t3.props, x2 = t3.type;\n if (\"svg\" == x2 ? o3 = \"http://www.w3.org/2000/svg\" : \"math\" == x2 ? o3 = \"http://www.w3.org/1998/Math/MathML\" : o3 || (o3 = \"http://www.w3.org/1999/xhtml\"), null != e3) {\n for (s3 = 0; s3 < e3.length; s3++) if ((y3 = e3[s3]) && \"setAttribute\" in y3 == !!x2 && (x2 ? y3.localName == x2 : 3 == y3.nodeType)) {\n u4 = y3, e3[s3] = null;\n break;\n }\n }\n if (null == u4) {\n if (null == x2) return document.createTextNode(k3);\n u4 = document.createElementNS(o3, x2, k3.is && k3), c3 && (l.__m && l.__m(t3, e3), c3 = false), e3 = null;\n }\n if (null == x2) m3 === k3 || c3 && u4.data == k3 || (u4.data = k3);\n else {\n if (e3 = \"textarea\" == x2 && null != k3.defaultValue ? null : e3 && n.call(u4.childNodes), !c3 && null != e3) for (m3 = {}, s3 = 0; s3 < u4.attributes.length; s3++) m3[(y3 = u4.attributes[s3]).name] = y3.value;\n for (s3 in m3) y3 = m3[s3], \"dangerouslySetInnerHTML\" == s3 ? p3 = y3 : \"children\" == s3 || s3 in k3 || \"value\" == s3 && \"defaultValue\" in k3 || \"checked\" == s3 && \"defaultChecked\" in k3 || N(u4, s3, null, y3, o3);\n for (s3 in k3) y3 = k3[s3], \"children\" == s3 ? v3 = y3 : \"dangerouslySetInnerHTML\" == s3 ? h3 = y3 : \"value\" == s3 ? w3 = y3 : \"checked\" == s3 ? _3 = y3 : c3 && \"function\" != typeof y3 || m3[s3] === y3 || N(u4, s3, y3, m3[s3], o3);\n if (h3) c3 || p3 && (h3.__html == p3.__html || h3.__html == u4.innerHTML) || (u4.innerHTML = h3.__html), t3.__k = [];\n else if (p3 && (u4.innerHTML = \"\"), L(\"template\" == t3.type ? u4.content : u4, g(v3) ? v3 : [v3], t3, i3, r3, \"foreignObject\" == x2 ? \"http://www.w3.org/1999/xhtml\" : o3, e3, f4, e3 ? e3[0] : i3.__k && $(i3, 0), c3, a3), null != e3) for (s3 = e3.length; s3--; ) b(e3[s3]);\n c3 && \"textarea\" != x2 || (s3 = \"value\", \"progress\" == x2 && null == w3 ? u4.removeAttribute(\"value\") : null != w3 && (w3 !== u4[s3] || \"progress\" == x2 && !w3 || \"option\" == x2 && w3 != m3[s3]) && N(u4, s3, w3, m3[s3], o3), s3 = \"checked\", null != _3 && _3 != u4[s3] && N(u4, s3, _3, m3[s3], o3));\n }\n return u4;\n }\n function J(n2, u4, t3) {\n try {\n if (\"function\" == typeof n2) {\n var i3 = \"function\" == typeof n2.__u;\n i3 && n2.__u(), i3 && null == u4 || (n2.__u = n2(u4));\n } else n2.current = u4;\n } catch (n3) {\n l.__e(n3, t3);\n }\n }\n function K(n2, u4, t3) {\n var i3, r3;\n if (l.unmount && l.unmount(n2), (i3 = n2.ref) && (i3.current && i3.current != n2.__e || J(i3, null, u4)), null != (i3 = n2.__c)) {\n if (i3.componentWillUnmount) try {\n i3.componentWillUnmount();\n } catch (n3) {\n l.__e(n3, u4);\n }\n i3.base = i3.__P = i3.__n = null;\n }\n if (i3 = n2.__k) for (r3 = 0; r3 < i3.length; r3++) i3[r3] && K(i3[r3], u4, t3 || \"function\" != typeof n2.type);\n t3 || b(n2.__e), n2.__c = n2.__ = n2.__e = void 0;\n }\n function Q(n2, l3, u4) {\n return this.constructor(n2, u4);\n }\n function R(u4, t3, i3) {\n var r3, o3, e3, f4;\n t3 == document && (t3 = document.documentElement), l.__ && l.__(u4, t3), o3 = (r3 = \"function\" == typeof i3) ? null : i3 && i3.__k || t3.__k, e3 = [], f4 = [], q(t3, u4 = (!r3 && i3 || t3).__k = k(S, null, [u4]), o3 || d, d, t3.namespaceURI, !r3 && i3 ? [i3] : o3 ? null : t3.firstChild ? n.call(t3.childNodes) : null, e3, !r3 && i3 ? i3 : o3 ? o3.__e : t3.firstChild, r3, f4), D(e3, u4, f4), u4.props.children = null;\n }\n n = w.slice, l = { __e: function(n2, l3, u4, t3) {\n for (var i3, r3, o3; l3 = l3.__; ) if ((i3 = l3.__c) && !i3.__) try {\n if ((r3 = i3.constructor) && null != r3.getDerivedStateFromError && (i3.setState(r3.getDerivedStateFromError(n2)), o3 = i3.__d), null != i3.componentDidCatch && (i3.componentDidCatch(n2, t3 || {}), o3 = i3.__d), o3) return i3.__E = i3;\n } catch (l4) {\n n2 = l4;\n }\n throw n2;\n } }, u = 0, t = function(n2) {\n return null != n2 && void 0 === n2.constructor;\n }, C.prototype.setState = function(n2, l3) {\n var u4;\n u4 = null != this.__s && this.__s != this.state ? this.__s : this.__s = m({}, this.state), \"function\" == typeof n2 && (n2 = n2(m({}, u4), this.props)), n2 && m(u4, n2), null != n2 && this.__v && (l3 && this._sb.push(l3), A(this));\n }, C.prototype.forceUpdate = function(n2) {\n this.__v && (this.__e = true, n2 && this.__h.push(n2), A(this));\n }, C.prototype.render = S, i = [], o = \"function\" == typeof Promise ? Promise.prototype.then.bind(Promise.resolve()) : setTimeout, e = function(n2, l3) {\n return n2.__v.__b - l3.__v.__b;\n }, H.__r = 0, f = Math.random().toString(8), c = \"__d\" + f, a = \"__a\" + f, s = /(PointerCapture)$|Capture$/i, h = 0, p = V(false), v = V(true), y = 0;\n\n // node_modules/preact/hooks/dist/hooks.module.js\n var t2;\n var r2;\n var u2;\n var i2;\n var o2 = 0;\n var f2 = [];\n var c2 = l;\n var e2 = c2.__b;\n var a2 = c2.__r;\n var v2 = c2.diffed;\n var l2 = c2.__c;\n var m2 = c2.unmount;\n var p2 = c2.__;\n function s2(n2, t3) {\n c2.__h && c2.__h(r2, n2, o2 || t3), o2 = 0;\n var u4 = r2.__H || (r2.__H = { __: [], __h: [] });\n return n2 >= u4.__.length && u4.__.push({}), u4.__[n2];\n }\n function d2(n2) {\n return o2 = 1, y2(D2, n2);\n }\n function y2(n2, u4, i3) {\n var o3 = s2(t2++, 2);\n if (o3.t = n2, !o3.__c && (o3.__ = [i3 ? i3(u4) : D2(void 0, u4), function(n3) {\n var t3 = o3.__N ? o3.__N[0] : o3.__[0], r3 = o3.t(t3, n3);\n t3 !== r3 && (o3.__N = [r3, o3.__[1]], o3.__c.setState({}));\n }], o3.__c = r2, !r2.__f)) {\n var f4 = function(n3, t3, r3) {\n if (!o3.__c.__H) return true;\n var u5 = false, i4 = o3.__c.props !== n3;\n if (o3.__c.__H.__.some(function(n4) {\n if (n4.__N) {\n u5 = true;\n var t4 = n4.__[0];\n n4.__ = n4.__N, n4.__N = void 0, t4 !== n4.__[0] && (i4 = true);\n }\n }), c3) {\n var f5 = c3.call(this, n3, t3, r3);\n return u5 ? f5 || i4 : f5;\n }\n return !u5 || i4;\n };\n r2.__f = true;\n var c3 = r2.shouldComponentUpdate, e3 = r2.componentWillUpdate;\n r2.componentWillUpdate = function(n3, t3, r3) {\n if (this.__e) {\n var u5 = c3;\n c3 = void 0, f4(n3, t3, r3), c3 = u5;\n }\n e3 && e3.call(this, n3, t3, r3);\n }, r2.shouldComponentUpdate = f4;\n }\n return o3.__N || o3.__;\n }\n function h2(n2, u4) {\n var i3 = s2(t2++, 3);\n !c2.__s && C2(i3.__H, u4) && (i3.__ = n2, i3.u = u4, r2.__H.__h.push(i3));\n }\n function _2(n2, u4) {\n var i3 = s2(t2++, 4);\n !c2.__s && C2(i3.__H, u4) && (i3.__ = n2, i3.u = u4, r2.__h.push(i3));\n }\n function j2() {\n for (var n2; n2 = f2.shift(); ) {\n var t3 = n2.__H;\n if (n2.__P && t3) try {\n t3.__h.some(z2), t3.__h.some(B2), t3.__h = [];\n } catch (r3) {\n t3.__h = [], c2.__e(r3, n2.__v);\n }\n }\n }\n c2.__b = function(n2) {\n r2 = null, e2 && e2(n2);\n }, c2.__ = function(n2, t3) {\n n2 && t3.__k && t3.__k.__m && (n2.__m = t3.__k.__m), p2 && p2(n2, t3);\n }, c2.__r = function(n2) {\n a2 && a2(n2), t2 = 0;\n var i3 = (r2 = n2.__c).__H;\n i3 && (u2 === r2 ? (i3.__h = [], r2.__h = [], i3.__.some(function(n3) {\n n3.__N && (n3.__ = n3.__N), n3.u = n3.__N = void 0;\n })) : (i3.__h.some(z2), i3.__h.some(B2), i3.__h = [], t2 = 0)), u2 = r2;\n }, c2.diffed = function(n2) {\n v2 && v2(n2);\n var t3 = n2.__c;\n t3 && t3.__H && (t3.__H.__h.length && (1 !== f2.push(t3) && i2 === c2.requestAnimationFrame || ((i2 = c2.requestAnimationFrame) || w2)(j2)), t3.__H.__.some(function(n3) {\n n3.u && (n3.__H = n3.u, n3.u = void 0);\n })), u2 = r2 = null;\n }, c2.__c = function(n2, t3) {\n t3.some(function(n3) {\n try {\n n3.__h.some(z2), n3.__h = n3.__h.filter(function(n4) {\n return !n4.__ || B2(n4);\n });\n } catch (r3) {\n t3.some(function(n4) {\n n4.__h && (n4.__h = []);\n }), t3 = [], c2.__e(r3, n3.__v);\n }\n }), l2 && l2(n2, t3);\n }, c2.unmount = function(n2) {\n m2 && m2(n2);\n var t3, r3 = n2.__c;\n r3 && r3.__H && (r3.__H.__.some(function(n3) {\n try {\n z2(n3);\n } catch (n4) {\n t3 = n4;\n }\n }), r3.__H = void 0, t3 && c2.__e(t3, r3.__v));\n };\n var k2 = \"function\" == typeof requestAnimationFrame;\n function w2(n2) {\n var t3, r3 = function() {\n clearTimeout(u4), k2 && cancelAnimationFrame(t3), setTimeout(n2);\n }, u4 = setTimeout(r3, 35);\n k2 && (t3 = requestAnimationFrame(r3));\n }\n function z2(n2) {\n var t3 = r2, u4 = n2.__c;\n \"function\" == typeof u4 && (n2.__c = void 0, u4()), r2 = t3;\n }\n function B2(n2) {\n var t3 = r2;\n n2.__c = n2.__(), r2 = t3;\n }\n function C2(n2, t3) {\n return !n2 || n2.length !== t3.length || t3.some(function(t4, r3) {\n return t4 !== n2[r3];\n });\n }\n function D2(n2, t3) {\n return \"function\" == typeof t3 ? t3(n2) : t3;\n }\n\n // src/operator-ui/view.ts\n var OPERATOR_PAGES = [\n \"connections\",\n \"activity\"\n ];\n var PAGE_META = {\n connections: { path: \"/\", label: \"Connections\" },\n activity: { path: \"/activity\", label: \"Activity\" }\n };\n function pageForPath(path) {\n const match = OPERATOR_PAGES.find((page) => PAGE_META[page].path === path);\n return match ?? \"connections\";\n }\n function info(message2) {\n return { message: message2, tone: \"info\" };\n }\n function failure(message2) {\n return { message: message2, tone: \"error\" };\n }\n function initialState(page) {\n return {\n page,\n generation: 0,\n session: \"loading\",\n gate: null,\n refreshing: false,\n pendingFocus: null,\n ...identityScopedState()\n };\n }\n function identityScopedState() {\n return {\n data: null,\n connectorFilter: \"\",\n oauthNotice: null,\n oauthBusy: null,\n credentialNotice: null,\n credentialEditing: null,\n credentialBusy: null,\n activityPhase: \"idle\",\n activityNotice: null,\n activityEvents: [],\n activityCursor: null,\n activitySearch: \"\"\n };\n }\n function resetIdentity(state2, gate2 = null) {\n return {\n ...state2,\n generation: state2.generation + 1,\n session: \"gated\",\n gate: gate2,\n refreshing: false,\n pendingFocus: null,\n ...identityScopedState()\n };\n }\n function withPage(state2, page) {\n return {\n ...state2,\n page,\n credentialEditing: null,\n credentialNotice: null\n };\n }\n function connectorStatusLabel(status) {\n if (status === \"loading\") return \"Loading details\";\n if (status === \"ok\") return \"Connected\";\n if (status === \"auth_required\") return \"Authorization needed\";\n return \"Unavailable\";\n }\n function toolCountLabel(count) {\n return `${count} ${count === 1 ? \"tool\" : \"tools\"}`;\n }\n function connectorStatusTone(status) {\n if (status === \"ok\") return \"ok\";\n if (status === \"auth_required\") return \"warn\";\n if (status === \"loading\") return \"neutral\";\n return \"danger\";\n }\n function summarizeConnectors(connectors) {\n const summary = {\n total: connectors.length,\n connected: 0,\n attention: 0,\n unavailable: 0,\n tools: 0,\n drifting: 0\n };\n for (const connector of connectors) {\n if (connector.status === \"ok\") summary.connected += 1;\n else if (connector.status === \"auth_required\") summary.attention += 1;\n else if (connector.status !== \"loading\") summary.unavailable += 1;\n summary.tools += connector.toolCount || 0;\n if (driftState(connector.catalogDrift) === \"warning\") summary.drifting += 1;\n }\n return summary;\n }\n function connectorSummaryParts(summary) {\n return [\n { text: `${summary.connected} connected`, tone: \"neutral\" },\n ...summary.attention ? [\n {\n text: `${summary.attention} need${summary.attention === 1 ? \"s\" : \"\"} authorization`,\n tone: \"warn\"\n }\n ] : [],\n ...summary.unavailable ? [{ text: `${summary.unavailable} unavailable`, tone: \"danger\" }] : [],\n { text: toolCountLabel(summary.tools), tone: \"neutral\" }\n ];\n }\n function authScopeLabel(scope) {\n return scope === \"personal\" ? \"personal auth\" : \"shared auth\";\n }\n function permissionLabel(connector) {\n if (connector.permissions?.manageSharedAuth) {\n return \"You can manage shared authentication for this connection.\";\n }\n if (connector.permissions?.connectPersonal) {\n return \"You can connect your own account to this connection.\";\n }\n return \"Authentication for this connection is managed by your deployment.\";\n }\n var DRIFT_CATEGORIES = [\n { key: \"unclassifiedTools\", label: \"Unclassified\" },\n { key: \"unservedTools\", label: \"Unserved\" },\n { key: \"annotationConflicts\", label: \"Annotation conflicts\" },\n { key: \"schemaChanges\", label: \"Schema changes\" }\n ];\n function driftTotal(drift) {\n if (!drift) return 0;\n return DRIFT_CATEGORIES.reduce((sum, { key }) => sum + (drift[key] || 0), 0);\n }\n function driftState(drift) {\n if (!drift) return \"unavailable\";\n return driftTotal(drift) > 0 ? \"warning\" : \"clean\";\n }\n function driftCounts(drift) {\n if (!drift) return [];\n return DRIFT_CATEGORIES.map(({ key, label }) => ({\n key,\n label,\n count: drift[key] || 0\n }));\n }\n function driftSummary(drift) {\n const state2 = driftState(drift);\n if (state2 === \"unavailable\") {\n return \"No catalog refresh observed yet in this runtime.\";\n }\n const observed = formatDate(drift?.observedAt);\n const when = observed ? ` · observed ${observed}` : \"\";\n if (state2 === \"clean\") return `Matches the reviewed manifest${when}`;\n const total = driftTotal(drift);\n return `${total} difference${total === 1 ? \"\" : \"s\"} from the reviewed manifest${when}`;\n }\n function safeHttpHref(url) {\n if (!url) return null;\n try {\n const protocol = new URL(url).protocol;\n return protocol === \"http:\" || protocol === \"https:\" ? url : null;\n } catch {\n return null;\n }\n }\n function formatDate(value) {\n if (!value) return \"\";\n const date = new Date(value);\n return Number.isNaN(date.valueOf()) ? \"\" : date.toLocaleString();\n }\n function actorLabel(actor) {\n if (!actor?.kind) return \"unknown\";\n if (actor.label) return `${actor.kind} · ${actor.label}`;\n return actor.id ? `${actor.kind} · ${actor.id}` : actor.kind;\n }\n function actorStableId(actor) {\n if (!actor?.id) return null;\n if (!actor.label && !actor.namespace) return null;\n return actor.namespace ? `${actor.namespace} · ${actor.id}` : actor.id;\n }\n function activityMatches(event, query) {\n const q2 = query.trim().toLowerCase();\n if (!q2) return true;\n return [\n event.address,\n event.connectorId,\n event.toolName,\n event.source,\n event.outcome,\n event.errorCode,\n event.friction,\n event.actor?.kind,\n event.actor?.id,\n event.actor?.namespace,\n event.actor?.label\n ].some((value) => String(value ?? \"\").toLowerCase().includes(q2));\n }\n function filterActivity(events, query) {\n return events.filter((event) => activityMatches(event, query));\n }\n function activitySummary(events) {\n if (events.length === 0) return \"Arguments and results are never stored.\";\n const tools = new Set(events.map((event) => event.address)).size;\n return `${events.length} loaded call${events.length === 1 ? \"\" : \"s\"} · ${tools} tool${tools === 1 ? \"\" : \"s\"} · no arguments or results stored`;\n }\n var ACTIVITY_OUTCOMES = [\"success\", \"error\", \"timeout\", \"cancelled\"];\n function activityOutcomeClass(outcome) {\n return ACTIVITY_OUTCOMES.includes(outcome) ? outcome : \"error\";\n }\n function activityDetail(event) {\n const parts = [event.source];\n if (event.attempts > 1) parts.push(`${event.attempts} attempts`);\n if (event.friction) parts.push(event.friction);\n if (event.errorCode && event.errorCode !== event.friction) {\n parts.push(event.errorCode);\n }\n return parts.join(\" · \");\n }\n function credentialStateLabel(credential) {\n if (!credential.configured) return \"not configured\";\n const masked = credential.fields?.length ? \"configured\" : `configured · ••••${credential.lastFour ?? \"\"}`;\n return credential.updatedAt ? `${masked} · updated ${formatDate(credential.updatedAt)}` : masked;\n }\n function gateCopy(kind, signedIn) {\n if (kind === \"cloudflare-access\") {\n return \"Cloudflare Access admitted this browser, but the current identity cannot open deployment-wide operator pages.\";\n }\n if (kind !== \"clerk\") {\n return \"Paste an operator bearer token to open this page. Nothing is requested until you do.\";\n }\n return signedIn ? \"Signed in with Clerk, but this account cannot open deployment-wide operator pages.\" : \"Sign in with Clerk to open this operator page.\";\n }\n\n // src/operator-ui/app/config.ts\n var auth = AUTH;\n var mcpUrl = MCP_URL;\n var initialPage = INITIAL_PAGE;\n var titleSuffix = TITLE_SUFFIX;\n var productName = PRODUCT_NAME;\n var productDescription = PRODUCT_DESCRIPTION;\n var productOperatorLabel = PRODUCT_OPERATOR_LABEL;\n var TOKEN_KEY = \"connecta:token\";\n\n // src/operator-ui/app/store.ts\n var state = initialState(initialPage);\n var listeners = /* @__PURE__ */ new Set();\n function getState() {\n return state;\n }\n function subscribe(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n }\n function set(patch) {\n state = { ...state, ...patch };\n for (const listener of listeners) listener();\n }\n function fence() {\n const generation = state.generation;\n return () => generation === state.generation;\n }\n function message(error, fallback) {\n return error instanceof Error && error.message ? error.message : fallback;\n }\n function sessionToken() {\n if (auth.kind === \"cloudflare-access\") return Promise.resolve(void 0);\n return auth.kind === \"clerk\" ? Promise.resolve(window.Clerk?.session?.getToken() ?? null) : Promise.resolve(localStorage.getItem(TOKEN_KEY));\n }\n function requestHeaders(token, body = false) {\n return {\n ...token ? { Authorization: `Bearer ${token}` } : {},\n ...body ? { \"Content-Type\": \"application/json\" } : {}\n };\n }\n function gate(notice = null) {\n state = resetIdentity(state, notice);\n for (const listener of listeners) listener();\n }\n async function operatorRequest(path, method, current, body) {\n const token = await sessionToken();\n if (!current()) throw new Error(\"The operator session changed.\");\n if (!token && auth.kind !== \"cloudflare-access\") {\n throw new Error(\"Your operator session has expired.\");\n }\n const res = await fetch(path, {\n method,\n headers: requestHeaders(token, Boolean(body)),\n credentials: \"same-origin\",\n ...body ? { body: JSON.stringify(body) } : {}\n });\n if (res.status === 204) return null;\n let payload = {};\n try {\n payload = await res.json();\n } catch {\n }\n if (res.status === 401) {\n throw new Error(\"Your operator session was not accepted. Sign in again.\");\n }\n if (res.status === 403) {\n throw new Error(\"This identity may not perform that action.\");\n }\n if (!res.ok) {\n throw new Error(payload.error || `Request failed (${res.status}).`);\n }\n return payload;\n }\n async function loadData() {\n const current = fence();\n if (state.session === \"ready\") set({ refreshing: true });\n let token;\n try {\n token = await sessionToken();\n } catch (error) {\n if (!current()) return;\n const why = message(error, \"unknown error\");\n return gate(failure(`Could not read the Clerk session: ${why}`));\n }\n if (!current()) return;\n if (!token && auth.kind !== \"cloudflare-access\") return gate(null);\n let res;\n try {\n res = await fetch(\"/ui/data\", {\n headers: requestHeaders(token),\n credentials: \"same-origin\"\n });\n } catch (error) {\n if (!current()) return;\n return gate(failure(`Network error: ${message(error, \"unknown error\")}`));\n }\n if (!current()) return;\n if (res.status === 401 || res.status === 403) {\n if (auth.kind === \"clerk\") {\n return gate(\n failure(\n res.status === 403 ? \"This Clerk account is not allowed to access connecta.\" : \"Your Clerk session was not accepted. Sign out and try again.\"\n )\n );\n }\n if (auth.kind === \"cloudflare-access\") {\n return gate(\n failure(\n \"Cloudflare Access admitted the request, but this identity is not an eligible operator.\"\n )\n );\n }\n localStorage.removeItem(TOKEN_KEY);\n return gate(failure(\"Token rejected — enter a valid bearer token.\"));\n }\n if (!res.ok) return gate(failure(`Error ${res.status}`));\n let data;\n try {\n data = await res.json();\n } catch {\n if (!current()) return;\n return gate(failure(\"Operator data could not be read.\"));\n }\n if (!current()) return;\n if (!Array.isArray(data.connectors)) return gate(failure(\"Connection list could not be read.\"));\n set({ data, session: \"ready\", gate: null, refreshing: false });\n void loadConnectorDetails(data, current, token);\n }\n async function mutate(options) {\n const current = fence();\n if (options.reload) detailRevisions.set(options.reload, (detailRevisions.get(options.reload) ?? 0) + 1);\n set(options.busy);\n try {\n const payload = await options.request(current);\n if (!current()) return;\n if (!current()) return;\n set(options.done(payload));\n if (options.reload) void refreshConnector(options.reload);\n } catch (error) {\n if (!current()) return;\n set(options.failed(failure(message(error, options.fallback))));\n }\n }\n function focusHandled() {\n if (state.pendingFocus !== null) set({ pendingFocus: null });\n }\n function setPage(page, focus = false) {\n state = withPage(state, page);\n if (focus) {\n state = {\n ...state,\n pendingFocus: state.session === \"ready\" ? `${page}Heading` : \"gateHeading\"\n };\n }\n for (const listener of listeners) listener();\n }\n function navigate(page, href) {\n history.pushState({ operatorPage: page }, \"\", href);\n setPage(page, true);\n }\n function setConnectorFilter(connectorFilter) {\n set({ connectorFilter });\n }\n function setActivitySearch(activitySearch) {\n set({ activitySearch });\n }\n function signInWithBearer(value) {\n gate(null);\n localStorage.setItem(TOKEN_KEY, value);\n void loadData().then(() => {\n if (state.session === \"ready\") set({ pendingFocus: `${state.page}Heading` });\n });\n }\n function forgetBearer() {\n localStorage.removeItem(TOKEN_KEY);\n gate(null);\n set({ pendingFocus: \"token\" });\n }\n function oauthAction(connector, action) {\n const disconnecting = action === \"disconnect\";\n const confirmed = window.confirm(\n disconnecting ? `Disconnect OAuth for ${connector}? Stored credentials and any pending authorization will be removed.` : `Restart OAuth for ${connector}? Stored credentials and any pending authorization will be replaced.`\n );\n if (!confirmed) return Promise.resolve();\n return mutate({\n request: (current) => operatorRequest(\n `/ui/oauth/${encodeURIComponent(connector)}`,\n disconnecting ? \"DELETE\" : \"POST\",\n current\n ),\n busy: { oauthNotice: null, oauthBusy: connector },\n done: (payload) => ({\n ...state.data ? { data: { ...state.data, connectors: state.data.connectors.map((c3) => {\n if (c3.id !== connector) return c3;\n const { authorizationUrl: _old, ...rest } = c3;\n return { ...rest, status: \"auth_required\", tools: [], toolCount: 0, ...!disconnecting && payload?.authorizationUrl ? { authorizationUrl: payload.authorizationUrl } : {} };\n }) } } : {},\n oauthBusy: null,\n pendingFocus: \"oauthNotice\",\n oauthNotice: info(\n disconnecting ? \"OAuth disconnected. Restart authorization when you are ready to reconnect.\" : payload?.message || \"Authorization restarted. Open the authorization link to reconnect.\"\n )\n }),\n failed: (notice) => ({\n oauthBusy: null,\n oauthNotice: notice,\n pendingFocus: \"oauthNotice\"\n }),\n fallback: \"OAuth action failed.\",\n reload: connector\n });\n }\n function editCredential(connector) {\n set({ credentialEditing: connector, credentialNotice: null });\n }\n function refuseCredential(copy) {\n set({ credentialNotice: failure(copy), pendingFocus: \"credentialNotice\" });\n }\n function credentialMutation(connector, request, done, reload = true) {\n const land = (credentialNotice) => ({\n credentialBusy: null,\n credentialNotice,\n pendingFocus: \"credentialNotice\"\n });\n return mutate({\n request,\n busy: { credentialBusy: connector, credentialNotice: null },\n done: (payload) => land(done(payload)),\n failed: land,\n fallback: \"Credential action failed.\",\n reload: reload ? connector : void 0\n });\n }\n function saveCredential(connector, body) {\n return credentialMutation(\n connector,\n (current) => operatorRequest(\n `/ui/credentials/${encodeURIComponent(connector)}`,\n \"PUT\",\n current,\n body\n ),\n () => {\n set({ credentialEditing: null });\n return info(\"Credential saved.\");\n }\n );\n }\n function removeCredential(connector) {\n const confirmed = window.confirm(\n \"Remove this credential? The connector will stop authenticating until a replacement is added.\"\n );\n if (!confirmed) return Promise.resolve();\n return credentialMutation(\n connector,\n (current) => operatorRequest(\n `/ui/credentials/${encodeURIComponent(connector)}`,\n \"DELETE\",\n current\n ),\n () => info(\"Credential removed.\")\n );\n }\n function testCredential(connector) {\n return credentialMutation(\n connector,\n (current) => operatorRequest(\n `/ui/credentials/${encodeURIComponent(connector)}/test`,\n \"POST\",\n current\n ),\n (payload) => {\n const copy = payload?.message || (payload?.ok ? \"Credential is valid.\" : \"Credential test failed.\");\n return payload?.ok ? info(copy) : failure(copy);\n },\n false\n );\n }\n async function loadActivity(reset) {\n if (!state.data?.activityEnabled) return;\n const current = fence();\n set({\n activityPhase: \"loading\",\n activityNotice: null,\n ...reset ? { activityEvents: [], activityCursor: null } : {}\n });\n const params = new URLSearchParams({ limit: \"50\" });\n if (!reset && state.activityCursor) {\n params.set(\"cursor\", state.activityCursor);\n }\n try {\n const payload = await operatorRequest(\n `/ui/activity?${params}`,\n \"GET\",\n current\n );\n if (!current()) return;\n set({\n activityPhase: \"ready\",\n activityEvents: [\n ...reset ? [] : state.activityEvents,\n ...payload?.events ?? []\n ],\n activityCursor: payload?.nextCursor ?? null\n });\n } catch (error) {\n if (!current()) return;\n set({\n activityPhase: \"error\",\n activityNotice: failure(message(error, \"Activity could not be loaded.\"))\n });\n }\n }\n function signIn() {\n window.Clerk?.redirectToSignIn({\n signInFallbackRedirectUrl: window.location.href,\n signUpFallbackRedirectUrl: window.location.href\n });\n }\n function signOut() {\n if (auth.kind === \"cloudflare-access\") {\n gate(null);\n window.location.assign(\"/cdn-cgi/access/logout\");\n return;\n }\n const clerk = window.Clerk;\n gate(null);\n void clerk?.signOut({ redirectUrl: window.location.href });\n }\n async function boot() {\n const onPop = () => setPage(pageForPath(window.location.pathname), true);\n window.addEventListener(\"popstate\", onPop);\n if (auth.kind === \"clerk\") {\n const clerk = window.Clerk;\n if (!clerk) {\n const why = \"Clerk could not load. Check your network and try again.\";\n return gate(failure(why));\n }\n try {\n await clerk.load({\n ...auth.signInUrl ? { signInUrl: auth.signInUrl } : {},\n ...auth.signUpUrl ? { signUpUrl: auth.signUpUrl } : {},\n signInFallbackRedirectUrl: window.location.href,\n signUpFallbackRedirectUrl: window.location.href,\n afterSignOutUrl: window.location.href\n });\n let sessionId = clerk.session?.id ?? null;\n clerk.addListener((resources) => {\n const next = resources.session?.id ?? null;\n if (next === sessionId) return;\n sessionId = next;\n gate(null);\n void loadData();\n });\n } catch (error) {\n const why = message(error, \"unknown error\");\n return gate(failure(`Clerk could not initialize: ${why}`));\n }\n }\n await loadData();\n }\n var detailGeneration = 0;\n var detailRevisions = /* @__PURE__ */ new Map();\n async function loadConnectorDetails(data, current, token) {\n const generation = ++detailGeneration;\n let next = 0;\n const worker = async () => {\n while (next < data.connectors.length && current() && generation === detailGeneration) {\n const connector = data.connectors[next++];\n const revision = (detailRevisions.get(connector.id) ?? 0) + 1;\n detailRevisions.set(connector.id, revision);\n let detail;\n try {\n const response = await fetch(`/ui/connectors/${encodeURIComponent(connector.id)}`, { headers: requestHeaders(token), credentials: \"same-origin\" });\n if (!response.ok) throw new Error(`Connection details unavailable (${response.status})`);\n detail = await response.json();\n } catch (error) {\n detail = { ...connector, status: \"error\", message: message(error, \"Connection details unavailable\") };\n }\n if (!current() || generation !== detailGeneration || !state.data) return;\n if (detailRevisions.get(connector.id) !== revision) continue;\n set({ data: { ...state.data, connectors: state.data.connectors.map((c3) => c3.id === connector.id ? detail : c3) } });\n }\n };\n await Promise.all(Array.from({ length: Math.min(4, data.connectors.length) }, worker));\n }\n async function refreshConnector(id) {\n const current = fence();\n const revision = (detailRevisions.get(id) ?? 0) + 1;\n detailRevisions.set(id, revision);\n if (state.data) set({ data: { ...state.data, connectors: state.data.connectors.map((c3) => c3.id === id ? { ...c3, status: \"loading\" } : c3) } });\n try {\n const token = await sessionToken();\n if (!current()) return;\n const response = await fetch(`/ui/connectors/${encodeURIComponent(id)}`, { headers: requestHeaders(token), credentials: \"same-origin\" });\n if (!response.ok) throw new Error(`Connection details unavailable (${response.status})`);\n const detail = await response.json();\n if (!current() || !state.data || detailRevisions.get(id) !== revision) return;\n set({ data: { ...state.data, connectors: state.data.connectors.map((c3) => c3.id === id ? { ...detail, ...detail.status === \"auth_required\" && c3.authorizationUrl ? { authorizationUrl: c3.authorizationUrl } : {} } : c3) } });\n } catch (error) {\n if (!current() || !state.data || detailRevisions.get(id) !== revision) return;\n set({ data: { ...state.data, connectors: state.data.connectors.map((c3) => c3.id === id ? { ...c3, status: \"error\", message: message(error, \"Connection details unavailable\") } : c3) } });\n }\n }\n\n // node_modules/preact/jsx-runtime/dist/jsxRuntime.module.js\n var f3 = 0;\n function u3(e3, t3, n2, o3, i3, u4) {\n t3 || (t3 = {});\n var a3, c3, p3 = t3;\n if (\"ref\" in p3) for (c3 in p3 = {}, t3) \"ref\" == c3 ? a3 = t3[c3] : p3[c3] = t3[c3];\n var l3 = { type: e3, props: p3, key: n2, ref: a3, __k: null, __: null, __b: 0, __e: null, __c: null, constructor: void 0, __v: --f3, __i: -1, __u: 0, __source: i3, __self: u4 };\n if (\"function\" == typeof e3 && (a3 = e3.defaultProps)) for (c3 in a3) void 0 === p3[c3] && (p3[c3] = a3[c3]);\n return l.vnode && l.vnode(l3), l3;\n }\n\n // src/operator-ui/app/parts.tsx\n function NoticeLine({\n id,\n notice,\n className = \"meta\"\n }) {\n return /* @__PURE__ */ u3(\n \"p\",\n {\n id,\n class: notice?.tone === \"error\" ? `notice ${className} error-notice` : `notice ${className}`,\n role: notice?.tone === \"error\" ? \"alert\" : \"status\",\n \"aria-live\": \"polite\",\n tabIndex: -1,\n children: notice ? notice.message : null\n }\n );\n }\n function Badge({\n tone = \"neutral\",\n children\n }) {\n return /* @__PURE__ */ u3(\"span\", { class: tone === \"neutral\" ? \"badge\" : `badge ${tone}`, children });\n }\n function Empty({ children }) {\n return /* @__PURE__ */ u3(\"p\", { class: \"empty\", children });\n }\n function Unavailable({ children }) {\n return /* @__PURE__ */ u3(\"div\", { class: \"unavailable\", children });\n }\n function PageLink({\n page,\n class: className,\n current,\n children\n }) {\n const href = PAGE_META[page].path;\n return /* @__PURE__ */ u3(\n \"a\",\n {\n class: className,\n href,\n ...current ? { \"aria-current\": \"page\" } : {},\n onClick: (event) => {\n if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {\n return;\n }\n event.preventDefault();\n navigate(page, href);\n },\n children\n }\n );\n }\n function CopyButton({\n value,\n label,\n class: className = \"btn\"\n }) {\n const [status, setStatus] = d2(\"idle\");\n h2(() => {\n if (status === \"idle\") return;\n const timer = window.setTimeout(() => setStatus(\"idle\"), 1600);\n return () => window.clearTimeout(timer);\n }, [status]);\n return /* @__PURE__ */ u3(\n \"button\",\n {\n class: className,\n type: \"button\",\n onClick: () => {\n navigator.clipboard.writeText(value).then(\n () => setStatus(\"copied\"),\n () => setStatus(\"failed\")\n );\n },\n children: status === \"copied\" ? \"Copied\" : status === \"failed\" ? \"Copy failed\" : label\n }\n );\n }\n\n // src/operator-ui/app/activity.tsx\n function ActivityRow({ event }) {\n const outcome = activityOutcomeClass(event.outcome);\n const stableId = actorStableId(event.actor);\n return /* @__PURE__ */ u3(\"article\", { class: `activity-item ${outcome}`, children: [\n /* @__PURE__ */ u3(\"div\", { class: \"activity-stamp\", children: [\n /* @__PURE__ */ u3(\"span\", { class: `dot ${outcome}`, \"aria-hidden\": \"true\" }),\n /* @__PURE__ */ u3(\"div\", { children: [\n /* @__PURE__ */ u3(\"time\", { class: \"activity-time\", dateTime: event.occurredAt, children: formatDate(event.occurredAt) }),\n /* @__PURE__ */ u3(\"div\", { class: \"activity-actor\", children: actorLabel(event.actor) }),\n stableId ? /* @__PURE__ */ u3(\"div\", { class: \"activity-actor-id mono\", children: stableId }) : null\n ] })\n ] }),\n /* @__PURE__ */ u3(\"div\", { children: [\n /* @__PURE__ */ u3(\"div\", { class: \"activity-address\", children: event.address }),\n /* @__PURE__ */ u3(\"div\", { class: \"activity-detail\", children: activityDetail(event) })\n ] }),\n /* @__PURE__ */ u3(\"div\", { children: [\n /* @__PURE__ */ u3(\"div\", { class: \"activity-outcome\", children: event.outcome }),\n /* @__PURE__ */ u3(\"div\", { class: \"activity-detail\", children: [\n event.durationMs,\n \" ms\"\n ] })\n ] })\n ] });\n }\n function ActivityPage({ state: state2 }) {\n const enabled = Boolean(state2.data?.activityEnabled);\n const loading = state2.activityPhase === \"loading\";\n const visible = filterActivity(state2.activityEvents, state2.activitySearch);\n return /* @__PURE__ */ u3(\"section\", { id: \"activityView\", children: /* @__PURE__ */ u3(\"div\", { class: \"lead\", children: [\n /* @__PURE__ */ u3(\"h1\", { id: \"activityHeading\", tabIndex: -1, children: \"Activity\" }),\n /* @__PURE__ */ u3(\"div\", { class: \"lead-copy\", children: [\n /* @__PURE__ */ u3(\"p\", { id: \"activitySummary\", children: activitySummary(state2.activityEvents) }),\n !enabled ? /* @__PURE__ */ u3(Unavailable, { children: [\n \"Activity history is not configured. Add an\",\n \" \",\n /* @__PURE__ */ u3(\"span\", { class: \"mono\", children: \"activity.store\" }),\n \" with a list reader to enable this page.\"\n ] }) : /* @__PURE__ */ u3(\"div\", { id: \"activityAvailable\", children: [\n /* @__PURE__ */ u3(\"div\", { class: \"row\", children: [\n /* @__PURE__ */ u3(\n \"input\",\n {\n id: \"activitySearch\",\n type: \"search\",\n placeholder: \"Search user, tool, or outcome…\",\n \"aria-label\": \"Search loaded activity\",\n value: state2.activitySearch,\n onInput: (event) => setActivitySearch(event.currentTarget.value)\n }\n ),\n /* @__PURE__ */ u3(\n \"button\",\n {\n id: \"refreshActivity\",\n class: \"btn\",\n type: \"button\",\n disabled: loading,\n onClick: () => void loadActivity(true),\n children: loading ? \"Loading…\" : \"Refresh\"\n }\n )\n ] }),\n /* @__PURE__ */ u3(NoticeLine, { id: \"activityNotice\", notice: state2.activityNotice }),\n /* @__PURE__ */ u3(\n \"div\",\n {\n id: \"activityList\",\n class: \"activity-list\",\n \"aria-busy\": loading ? \"true\" : \"false\",\n children: loading && state2.activityEvents.length === 0 ? /* @__PURE__ */ u3(\"div\", { class: \"activity-empty\", children: \"Loading activity…\" }) : state2.activityPhase === \"error\" && state2.activityEvents.length === 0 ? /* @__PURE__ */ u3(\"p\", { class: \"activity-empty\", children: /* @__PURE__ */ u3(\n \"button\",\n {\n class: \"btn\",\n type: \"button\",\n onClick: () => void loadActivity(true),\n children: \"Try loading activity again\"\n }\n ) }) : visible.length === 0 ? /* @__PURE__ */ u3(\"div\", { class: \"activity-empty\", children: state2.activitySearch.trim() ? \"No loaded activity matches this search.\" : \"No connector tool calls recorded yet.\" }) : visible.map((event, index) => /* @__PURE__ */ u3(\n ActivityRow,\n {\n event\n },\n `${event.occurredAt}-${event.address}-${index}`\n ))\n }\n ),\n state2.activityCursor ? /* @__PURE__ */ u3(\n \"button\",\n {\n id: \"moreActivity\",\n class: \"btn activity-more\",\n type: \"button\",\n disabled: loading,\n onClick: () => void loadActivity(false),\n children: loading ? \"Loading…\" : \"Load older\"\n }\n ) : null\n ] })\n ] })\n ] }) });\n }\n\n // src/operator-ui/app/credentials.tsx\n function CredentialForm({\n connector,\n credential,\n busy\n }) {\n const fields = credential.fields ?? [];\n const [values, setValues] = d2({});\n const single = fields.length === 0;\n const inputId = `credential-input-${connector}`;\n const submit = () => {\n if (single) {\n const value = (values.value ?? \"\").trim();\n if (!value) return refuseCredential(\"Paste a credential before saving.\");\n return void saveCredential(connector, { value });\n }\n const entries = {};\n for (const field of fields) {\n const value = (values[field.name] ?? \"\").trim();\n if (!value) {\n return refuseCredential(\n \"Complete every credential field before saving.\"\n );\n }\n entries[field.name] = value;\n }\n void saveCredential(connector, { values: entries });\n };\n return /* @__PURE__ */ u3(\"div\", { class: \"credential-form\", \"data-credential-form\": connector, children: [\n single ? /* @__PURE__ */ u3(S, { children: [\n /* @__PURE__ */ u3(\"label\", { class: \"visually-hidden\", for: inputId, children: credential.label }),\n /* @__PURE__ */ u3(\n \"input\",\n {\n id: inputId,\n type: \"password\",\n \"aria-label\": credential.label,\n placeholder: credential.placeholder || \"Paste credential\",\n autocomplete: \"new-password\",\n autocapitalize: \"none\",\n spellcheck: false,\n value: values.value ?? \"\",\n onInput: (event) => setValues({ value: event.currentTarget.value })\n }\n )\n ] }) : /* @__PURE__ */ u3(\"div\", { class: \"credential-fields\", children: fields.map((field, index) => {\n const id = `credential-input-${connector}-${index}`;\n return /* @__PURE__ */ u3(\"div\", { class: \"credential-field\", children: [\n /* @__PURE__ */ u3(\"label\", { for: id, children: field.label }),\n /* @__PURE__ */ u3(\n \"input\",\n {\n id,\n type: field.inputType || \"password\",\n placeholder: field.placeholder || field.label,\n autocomplete: (field.inputType ?? \"password\") === \"password\" ? \"new-password\" : \"off\",\n autocapitalize: \"none\",\n spellcheck: false,\n value: values[field.name] ?? \"\",\n onInput: (event) => setValues({\n ...values,\n [field.name]: event.currentTarget.value\n })\n }\n )\n ] }, field.name);\n }) }),\n /* @__PURE__ */ u3(\"div\", { class: \"actions\", children: [\n /* @__PURE__ */ u3(\"button\", { class: \"btn primary\", type: \"button\", disabled: busy, onClick: submit, children: busy ? \"Saving…\" : \"Save\" }),\n /* @__PURE__ */ u3(\n \"button\",\n {\n class: \"btn quiet\",\n type: \"button\",\n disabled: busy,\n onClick: () => editCredential(null),\n children: \"Cancel\"\n }\n )\n ] })\n ] });\n }\n function CredentialCard({\n connector,\n credential,\n editing,\n busy\n }) {\n const configured = Boolean(credential.configured);\n const removable = configured || Boolean(credential.removable);\n return /* @__PURE__ */ u3(\n \"section\",\n {\n class: \"subcard\",\n id: `credential-${connector.id}`,\n \"aria-labelledby\": `credential-title-${connector.id}`,\n children: [\n /* @__PURE__ */ u3(\"div\", { class: \"subcard-head\", children: [\n /* @__PURE__ */ u3(\"h3\", { id: `credential-title-${connector.id}`, children: credential.label }),\n /* @__PURE__ */ u3(\"span\", { class: \"meta\", children: credentialStateLabel(credential) })\n ] }),\n credential.description ? /* @__PURE__ */ u3(\"p\", { class: \"meta\", children: credential.description }) : null,\n credential.fields?.length ? /* @__PURE__ */ u3(\"div\", { class: \"credential-field-summary\", children: credential.fields.map((field) => /* @__PURE__ */ u3(\"div\", { children: [\n /* @__PURE__ */ u3(\"span\", { children: field.label }),\n /* @__PURE__ */ u3(\"span\", { class: \"meta\", children: field.configured ? `configured · ••••${field.lastFour ?? \"\"}${field.updatedAt ? ` · updated ${formatDate(field.updatedAt)}` : \"\"}` : \"not configured\" })\n ] }, field.name)) }) : null,\n credential.error ? /* @__PURE__ */ u3(\"div\", { class: \"msg\", children: credential.error }) : null,\n credential.notice ? /* @__PURE__ */ u3(\"p\", { class: \"meta\", children: credential.notice }) : null,\n /* @__PURE__ */ u3(\"div\", { class: \"actions\", children: [\n /* @__PURE__ */ u3(\n \"button\",\n {\n class: \"btn\",\n type: \"button\",\n disabled: busy,\n onClick: () => editCredential(editing ? null : connector.id),\n children: removable ? \"Replace\" : \"Add credential\"\n }\n ),\n configured && credential.testable ? /* @__PURE__ */ u3(\n \"button\",\n {\n class: \"btn\",\n type: \"button\",\n disabled: busy,\n onClick: () => void testCredential(connector.id),\n children: busy ? \"Working…\" : \"Test\"\n }\n ) : null,\n removable ? /* @__PURE__ */ u3(\n \"button\",\n {\n class: \"btn danger\",\n type: \"button\",\n disabled: busy,\n onClick: () => void removeCredential(connector.id),\n children: \"Remove\"\n }\n ) : null\n ] }),\n editing ? /* @__PURE__ */ u3(\n CredentialForm,\n {\n connector: connector.id,\n credential,\n busy\n }\n ) : null\n ]\n }\n );\n }\n\n // src/operator-ui/model.ts\n function filterUiConnectors(connectors, query) {\n const q2 = query.trim().toLowerCase();\n const filtered = [];\n for (const connector of connectors) {\n const connectorText = [\n connector.id,\n connector.title,\n connector.description,\n connector.status\n ].join(\" \").toLowerCase();\n const connectorMatches = Boolean(q2 && connectorText.includes(q2));\n const tools = connector.tools.filter(\n (tool) => !q2 || connectorMatches || `${tool.name} ${tool.description ?? \"\"}`.toLowerCase().includes(q2)\n );\n if (q2 && tools.length === 0 && !connectorMatches) continue;\n filtered.push({ connector, tools });\n }\n return filtered;\n }\n\n // src/operator-ui/app/connections.tsx\n var DRIFT_HEADING = {\n clean: \"Catalog drift · none\",\n warning: \"Catalog drift · review\",\n unavailable: \"Catalog drift · not observed\"\n };\n function DriftPanel({ connector }) {\n const drift = connector.catalogDrift;\n const state2 = driftState(drift);\n return /* @__PURE__ */ u3(\n \"div\",\n {\n id: `drift-${connector.id}`,\n class: `connector-drift ${state2}`,\n \"data-drift\": state2,\n children: [\n /* @__PURE__ */ u3(\"p\", { class: \"cap\", children: DRIFT_HEADING[state2] }),\n /* @__PURE__ */ u3(\"p\", { class: \"meta\", children: driftSummary(drift) }),\n state2 === \"unavailable\" ? null : /* @__PURE__ */ u3(\"ul\", { class: \"drift-counts\", children: driftCounts(drift).map(({ key, label, count }) => /* @__PURE__ */ u3(\"li\", { class: count > 0 ? \"drift-count flagged\" : \"drift-count\", children: [\n /* @__PURE__ */ u3(\"span\", { class: \"drift-count-value\", children: count }),\n /* @__PURE__ */ u3(\"span\", { class: \"drift-count-label\", children: label })\n ] }, key)) })\n ]\n }\n );\n }\n function ConnectorRow({\n connector,\n tools,\n expanded,\n oauthManagement,\n busy,\n state: state2\n }) {\n const name = connector.title || connector.id;\n const authorization = safeHttpHref(connector.authorizationUrl);\n const drift = driftState(connector.catalogDrift);\n return /* @__PURE__ */ u3(\"details\", { class: \"conn\", open: expanded, children: [\n /* @__PURE__ */ u3(\"summary\", { class: \"conn-head\", children: [\n /* @__PURE__ */ u3(\"span\", { class: \"conn-main\", children: [\n /* @__PURE__ */ u3(\"span\", { class: `dot ${connector.status}`, \"aria-hidden\": \"true\" }),\n /* @__PURE__ */ u3(\"h2\", { class: \"conn-name\", children: name }),\n connector.title ? /* @__PURE__ */ u3(\"span\", { class: \"conn-id mono\", children: connector.id }) : null\n ] }),\n /* @__PURE__ */ u3(\"span\", { class: \"conn-badges\", children: [\n drift === \"warning\" ? /* @__PURE__ */ u3(Badge, { tone: \"warn\", children: \"drift\" }) : null,\n /* @__PURE__ */ u3(Badge, { children: authScopeLabel(connector.authScope) }),\n /* @__PURE__ */ u3(Badge, { children: connector.status === \"loading\" ? \"tools not loaded\" : toolCountLabel(connector.toolCount) }),\n /* @__PURE__ */ u3(Badge, { tone: connectorStatusTone(connector.status), children: connectorStatusLabel(connector.status) }),\n /* @__PURE__ */ u3(\"span\", { class: \"conn-caret\", \"aria-hidden\": \"true\" })\n ] })\n ] }),\n /* @__PURE__ */ u3(\"div\", { class: \"conn-body\", children: [\n connector.description ? /* @__PURE__ */ u3(\"p\", { class: \"conn-note\", children: connector.description }) : null,\n connector.message ? /* @__PURE__ */ u3(\"p\", { class: \"msg\", children: connector.message }) : null,\n connector.authorizationUrl && !authorization ? /* @__PURE__ */ u3(\"p\", { class: \"meta\", children: [\n \"Authorization URL: \",\n connector.authorizationUrl\n ] }) : null,\n /* @__PURE__ */ u3(\"p\", { class: \"meta\", children: permissionLabel(connector) }),\n /* @__PURE__ */ u3(\"div\", { class: \"actions\", children: [\n authorization ? /* @__PURE__ */ u3(\"a\", { class: \"btn primary\", href: authorization, target: \"_blank\", rel: \"noopener\", children: \"Authorize connector\" }) : null,\n connector.oauth && oauthManagement ? /* @__PURE__ */ u3(S, { children: [\n /* @__PURE__ */ u3(\n \"button\",\n {\n type: \"button\",\n class: \"btn\",\n \"aria-label\": `${connector.status === \"ok\" ? \"Reconnect OAuth for\" : \"Restart authorization for\"} ${name}`,\n disabled: busy,\n onClick: () => void oauthAction(connector.id, \"reconnect\"),\n children: connector.status === \"ok\" ? \"Reconnect OAuth\" : \"Connect account\"\n }\n ),\n connector.status === \"ok\" ? /* @__PURE__ */ u3(\n \"button\",\n {\n type: \"button\",\n class: \"btn danger\",\n \"aria-label\": `Disconnect OAuth for ${name}`,\n disabled: busy,\n onClick: () => void oauthAction(connector.id, \"disconnect\"),\n children: \"Disconnect OAuth\"\n }\n ) : null\n ] }) : null,\n /* @__PURE__ */ u3(\n \"button\",\n {\n class: \"btn quiet\",\n type: \"button\",\n \"aria-label\": `Refresh ${name}`,\n disabled: connector.status === \"loading\",\n onClick: () => void refreshConnector(connector.id),\n children: \"Refresh\"\n }\n )\n ] }),\n connector.credential ? /* @__PURE__ */ u3(\n CredentialCard,\n {\n connector,\n credential: connector.credential,\n editing: state2.credentialEditing === connector.id,\n busy: state2.credentialBusy === connector.id\n }\n ) : null,\n tools.length ? /* @__PURE__ */ u3(\"details\", { open: expanded, children: [\n /* @__PURE__ */ u3(\"summary\", { class: \"disclosure\", children: [\n \"Tools (\",\n tools.length,\n \")\"\n ] }),\n /* @__PURE__ */ u3(\"div\", { class: \"tool-list\", children: tools.map((tool) => /* @__PURE__ */ u3(\"div\", { class: \"tool\", children: [\n /* @__PURE__ */ u3(\"code\", { children: tool.address }),\n tool.description ? /* @__PURE__ */ u3(\"span\", { class: \"td\", children: tool.description }) : null\n ] }, tool.address)) })\n ] }) : null,\n /* @__PURE__ */ u3(\"details\", { children: [\n /* @__PURE__ */ u3(\"summary\", { class: \"disclosure\", children: \"Diagnostics\" }),\n /* @__PURE__ */ u3(\"div\", { class: \"subcard\", children: [\n /* @__PURE__ */ u3(DriftPanel, { connector }),\n connector.catalogAccess ? /* @__PURE__ */ u3(\"p\", { class: \"meta\", children: [\n \"Last agent catalog read · \",\n connector.catalogAccess.state,\n \" ·\",\n \" \",\n formatDate(connector.catalogAccess.observedAt)\n ] }) : null\n ] })\n ] })\n ] })\n ] });\n }\n function SummaryLine({ connectors }) {\n const parts = connectorSummaryParts(summarizeConnectors(connectors));\n return /* @__PURE__ */ u3(\"p\", { class: \"summary\", id: \"connectorSummary\", children: parts.map((part, index) => /* @__PURE__ */ u3(\"span\", { children: [\n index > 0 ? /* @__PURE__ */ u3(\"span\", { class: \"sep\", children: \" · \" }) : null,\n /* @__PURE__ */ u3(\"span\", { class: part.tone === \"neutral\" ? \"\" : part.tone, children: part.text })\n ] }, part.text)) });\n }\n function ConnectionsPage({ state: state2 }) {\n const data = state2.data;\n const query = state2.connectorFilter.trim();\n const filtered = data ? filterUiConnectors(data.connectors, query) : [];\n return /* @__PURE__ */ u3(\"section\", { id: \"connectionsView\", children: [\n /* @__PURE__ */ u3(\"div\", { class: \"lead\", children: [\n /* @__PURE__ */ u3(\"h1\", { id: \"connectionsHeading\", tabIndex: -1, children: \"Connections\" }),\n /* @__PURE__ */ u3(\"div\", { class: \"lead-copy\", children: [\n /* @__PURE__ */ u3(\"p\", { children: \"Point an MCP client at this endpoint to reach the tools below.\" }),\n /* @__PURE__ */ u3(\"div\", { class: \"endpoint\", children: [\n /* @__PURE__ */ u3(\"code\", { id: \"mcpUrl\", class: \"mono\", children: mcpUrl }),\n /* @__PURE__ */ u3(CopyButton, { value: mcpUrl, label: \"Copy URL\" })\n ] }),\n /* @__PURE__ */ u3(\"p\", { class: \"cap\", id: \"serverInfo\", children: data ? `${data.serverInfo?.name || productName} v${data.connectaVersion || \"?\"}` : productOperatorLabel }),\n data ? /* @__PURE__ */ u3(SummaryLine, { connectors: data.connectors }) : null,\n /* @__PURE__ */ u3(NoticeLine, { id: \"oauthNotice\", notice: state2.oauthNotice }),\n /* @__PURE__ */ u3(NoticeLine, { id: \"credentialNotice\", notice: state2.credentialNotice })\n ] })\n ] }),\n /* @__PURE__ */ u3(\"section\", { class: \"section\", \"aria-labelledby\": \"connectorLedgerHeading\", children: [\n /* @__PURE__ */ u3(\"div\", { class: \"section-head\", children: [\n /* @__PURE__ */ u3(\"h2\", { id: \"connectorLedgerHeading\", children: \"Connectors\" }),\n /* @__PURE__ */ u3(\n \"input\",\n {\n id: \"filter\",\n type: \"search\",\n class: \"filter\",\n placeholder: \"Filter connectors or tools…\",\n \"aria-label\": \"Filter connectors or tools\",\n value: state2.connectorFilter,\n onInput: (event) => setConnectorFilter(event.currentTarget.value)\n }\n )\n ] }),\n /* @__PURE__ */ u3(\n \"div\",\n {\n id: \"list\",\n class: !data || filtered.length === 0 ? \"\" : \"rows\",\n \"aria-busy\": state2.refreshing || !data ? \"true\" : \"false\",\n children: !data ? /* @__PURE__ */ u3(Empty, { children: \"Loading connectors…\" }) : filtered.length === 0 ? /* @__PURE__ */ u3(Empty, { children: query ? \"No connectors or tools match this filter.\" : \"No connectors are declared in this deployment.\" }) : filtered.map(({ connector, tools }) => /* @__PURE__ */ u3(\n ConnectorRow,\n {\n connector,\n tools,\n expanded: Boolean(query),\n oauthManagement: Boolean(\n connector.permissions?.manageSharedAuth || connector.permissions?.connectPersonal\n ),\n state: state2,\n busy: state2.oauthBusy === connector.id\n },\n connector.id\n ))\n }\n )\n ] })\n ] });\n }\n\n // src/operator-ui/app/main.tsx\n function useOperatorState() {\n const [, bump] = y2((count) => count + 1, 0);\n const snapshot = getState();\n _2(() => {\n const unsubscribe = subscribe(() => bump(void 0));\n if (getState() !== snapshot) bump(void 0);\n return unsubscribe;\n }, []);\n return snapshot;\n }\n function visiblePages(state2) {\n return OPERATOR_PAGES.filter((page) => {\n if (page === \"activity\") return Boolean(state2.data?.activityEnabled);\n return true;\n });\n }\n function OperatorNav() {\n const state2 = useOperatorState();\n if (state2.session !== \"ready\") return null;\n return /* @__PURE__ */ u3(\"div\", { class: \"mast-actions\", children: [\n /* @__PURE__ */ u3(\"nav\", { class: \"page-nav\", \"aria-label\": \"Operator pages\", children: visiblePages(state2).map((page) => /* @__PURE__ */ u3(\n PageLink,\n {\n page,\n class: \"navlink\",\n current: state2.page === page,\n children: PAGE_META[page].label\n },\n page\n )) }),\n /* @__PURE__ */ u3(\"div\", { class: \"session-actions\", \"aria-label\": \"Session actions\", children: auth.kind === \"clerk\" || auth.kind === \"cloudflare-access\" ? /* @__PURE__ */ u3(\"button\", { class: \"navlink\", type: \"button\", onClick: signOut, children: \"Sign out\" }) : /* @__PURE__ */ u3(\"button\", { class: \"navlink\", type: \"button\", onClick: forgetBearer, children: \"Change token\" }) })\n ] });\n }\n function Gate({ state: state2 }) {\n const [token, setToken] = d2(\"\");\n const signedIn = auth.kind === \"clerk\" && Boolean(window.Clerk?.user);\n const loading = state2.session === \"loading\";\n return /* @__PURE__ */ u3(\"section\", { id: \"gate\", class: \"gate\", children: /* @__PURE__ */ u3(\"div\", { children: [\n /* @__PURE__ */ u3(\"h1\", { id: \"gateHeading\", tabIndex: -1, children: PAGE_META[state2.page].label }),\n /* @__PURE__ */ u3(\"div\", { class: \"lead-copy\", children: [\n /* @__PURE__ */ u3(\"p\", { children: productDescription }),\n /* @__PURE__ */ u3(\"p\", { id: \"gateCopy\", class: \"meta\", children: loading ? \"Checking your session…\" : gateCopy(auth.kind, signedIn) }),\n loading ? null : auth.kind === \"clerk\" ? /* @__PURE__ */ u3(\"div\", { id: \"clerkGate\", class: \"actions\", children: signedIn ? /* @__PURE__ */ u3(\"button\", { class: \"btn\", type: \"button\", onClick: signOut, children: \"Sign out\" }) : /* @__PURE__ */ u3(\"button\", { id: \"signin\", class: \"btn primary\", type: \"button\", onClick: signIn, children: \"Team sign in\" }) }) : auth.kind === \"cloudflare-access\" ? /* @__PURE__ */ u3(\"div\", { class: \"actions\", children: /* @__PURE__ */ u3(\"button\", { class: \"btn\", type: \"button\", onClick: signOut, children: \"Sign out of Cloudflare Access\" }) }) : /* @__PURE__ */ u3(\n \"form\",\n {\n id: \"tokenGate\",\n class: \"row\",\n onSubmit: (event) => {\n event.preventDefault();\n const value = token.trim();\n if (!value) return;\n setToken(\"\");\n signInWithBearer(value);\n },\n children: [\n /* @__PURE__ */ u3(\n \"input\",\n {\n id: \"token\",\n type: \"password\",\n placeholder: \"Bearer token\",\n autocomplete: \"off\",\n \"aria-label\": \"Bearer token\",\n value: token,\n onInput: (event) => setToken(event.currentTarget.value)\n }\n ),\n /* @__PURE__ */ u3(\"button\", { id: \"save\", class: \"btn primary\", type: \"submit\", children: \"Open operator pages\" })\n ]\n }\n ),\n /* @__PURE__ */ u3(NoticeLine, { id: \"err\", notice: state2.gate, className: \"\" })\n ] })\n ] }) });\n }\n function CurrentPage({ state: state2 }) {\n if (state2.page === \"activity\") return /* @__PURE__ */ u3(ActivityPage, { state: state2 });\n return /* @__PURE__ */ u3(ConnectionsPage, { state: state2 });\n }\n function OperatorApp() {\n const state2 = useOperatorState();\n const ready = state2.session === \"ready\";\n h2(() => {\n document.title = `${PAGE_META[state2.page].label} — ${titleSuffix}`;\n }, [state2.page]);\n h2(() => {\n if (!ready) return;\n if (state2.page === \"activity\" && state2.data?.activityEnabled && state2.activityPhase === \"idle\") {\n void loadActivity(true);\n }\n });\n h2(() => {\n if (!state2.pendingFocus) return;\n document.getElementById(state2.pendingFocus)?.focus();\n focusHandled();\n }, [state2.pendingFocus]);\n return ready ? /* @__PURE__ */ u3(\"div\", { id: \"app\", children: /* @__PURE__ */ u3(CurrentPage, { state: state2 }) }) : /* @__PURE__ */ u3(Gate, { state: state2 });\n }\n function mount(id, view) {\n const host = document.getElementById(id);\n if (!host) return;\n host.textContent = \"\";\n R(view, host);\n }\n mount(\"operatorNav\", /* @__PURE__ */ u3(OperatorNav, {}));\n mount(\"operatorContent\", /* @__PURE__ */ u3(OperatorApp, {}));\n void boot();\n})();\n";
3
+ export const OPERATOR_UI_CSS = "/* src/operator-ui/browser.css */\n:root {\n color-scheme: light;\n --accent: #2f5fe0;\n --radius: 10px;\n --sans:\n ui-sans-serif,\n system-ui,\n -apple-system,\n \"Segoe UI\",\n Roboto,\n \"Helvetica Neue\",\n Arial,\n sans-serif;\n --mono:\n ui-monospace,\n \"SF Mono\",\n Menlo,\n Monaco,\n \"Cascadia Code\",\n Consolas,\n monospace;\n --bg: #f6f7f9;\n --surface: #ffffff;\n --surface-2: #f1f3f6;\n --border: #e2e5ea;\n --border-strong: #cdd2da;\n --text: #131820;\n --muted: #5b6472;\n --ok: #12734a;\n --warn: #9a5b06;\n --danger: #bb3226;\n --on-accent: #ffffff;\n --link: var(--accent);\n --tint: color-mix(in srgb, var(--accent) 8%, var(--surface));\n --shell: 68rem;\n --pad: 1.25rem;\n --gap: 1rem;\n}\n@media (prefers-color-scheme: dark) {\n html:not([data-scheme=light]) {\n color-scheme: dark;\n }\n}\nhtml[data-scheme=dark] {\n color-scheme: dark;\n}\n@media (prefers-color-scheme: dark) {\n html:not([data-scheme=light]) {\n --bg: #0d1016;\n --surface: #151a21;\n --surface-2: #1c222c;\n --border: #262d39;\n --border-strong: #38414f;\n --text: #e6eaf1;\n --muted: #97a1b2;\n --ok: #4cc48c;\n --warn: #e2a33f;\n --danger: #f4776c;\n --link: color-mix(in srgb, var(--accent) 55%, #ffffff);\n --tint: color-mix(in srgb, var(--accent) 16%, var(--surface));\n }\n}\nhtml[data-scheme=dark] {\n --bg: #0d1016;\n --surface: #151a21;\n --surface-2: #1c222c;\n --border: #262d39;\n --border-strong: #38414f;\n --text: #e6eaf1;\n --muted: #97a1b2;\n --ok: #4cc48c;\n --warn: #e2a33f;\n --danger: #f4776c;\n --link: color-mix(in srgb, var(--accent) 55%, #ffffff);\n --tint: color-mix(in srgb, var(--accent) 16%, var(--surface));\n}\n* {\n box-sizing: border-box;\n}\nhtml {\n background: var(--bg);\n color: var(--text);\n font-family: var(--sans);\n font-size: 16px;\n line-height: 1.5;\n -webkit-font-smoothing: antialiased;\n}\nbody {\n margin: 0;\n min-height: 100vh;\n}\n:is(h1, h2, h3, p, ul, ol) {\n margin: 0;\n padding: 0;\n}\n:is(h1, h2, h3) {\n font-weight: 600;\n line-height: 1.3;\n}\nh1 {\n font-size: 1.5rem;\n letter-spacing: -.01em;\n}\nh2 {\n font-size: 1rem;\n}\n:is(ul, ol) {\n list-style: none;\n}\na {\n color: var(--link);\n text-decoration-thickness: 1px;\n text-underline-offset: 2px;\n}\nbutton,\ninput {\n font: inherit;\n}\n:is(a, button, input, summary):focus-visible {\n border-radius: calc(var(--radius) / 2);\n outline: 2px solid var(--link);\n outline-offset: 2px;\n}\n.skip-link {\n background: var(--surface);\n border: 1px solid var(--border);\n border-radius: var(--radius);\n left: var(--pad);\n padding: .5rem .75rem;\n position: fixed;\n top: -4rem;\n z-index: 10;\n}\n.skip-link:focus {\n top: var(--pad);\n}\n.shell {\n margin: 0 auto;\n max-width: var(--shell);\n padding-left: var(--pad);\n padding-right: var(--pad);\n}\n.cap,\n.meta {\n color: var(--muted);\n font-size: .875rem;\n}\n.mono {\n font-family: var(--mono);\n font-size: .8125rem;\n}\n.visually-hidden {\n clip-path: inset(50%);\n height: 1px;\n overflow: hidden;\n position: absolute;\n white-space: nowrap;\n width: 1px;\n}\n.masthead {\n align-items: center;\n background: var(--surface);\n border-bottom: 1px solid var(--border);\n display: flex;\n gap: var(--gap);\n justify-content: space-between;\n max-width: none;\n padding-bottom: .75rem;\n padding-top: .75rem;\n position: sticky;\n top: 0;\n z-index: 5;\n}\n.masthead-inner {\n align-items: center;\n display: flex;\n gap: var(--gap);\n justify-content: space-between;\n margin: 0 auto;\n max-width: var(--shell);\n width: 100%;\n}\n.mast-nav,\n.mast-actions,\n.page-nav,\n.session-actions {\n align-items: center;\n display: flex;\n flex-wrap: wrap;\n gap: .25rem;\n}\n.mast-nav {\n gap: var(--gap);\n}\n.mast-actions {\n gap: var(--gap);\n}\n.navlink {\n background: none;\n border: 0;\n border-radius: calc(var(--radius) - 2px);\n color: var(--muted);\n cursor: pointer;\n font-size: .9375rem;\n padding: .35rem .6rem;\n text-decoration: none;\n}\n.navlink:hover {\n background: var(--surface-2);\n color: var(--text);\n}\n.navlink[aria-current=page] {\n background: var(--tint);\n color: var(--link);\n font-weight: 500;\n}\n.brand,\n.product {\n padding-left: 0;\n padding-right: 0;\n text-decoration: none;\n}\n.brand {\n color: var(--text);\n font-weight: 600;\n}\n.brand:hover,\n.product:hover {\n background: none;\n}\n.product {\n color: var(--muted);\n}\n.page {\n padding-bottom: 4rem;\n padding-top: 2rem;\n}\n.lead {\n margin-bottom: 1.5rem;\n}\n.lead-copy {\n color: var(--muted);\n display: grid;\n gap: .5rem;\n margin-top: .35rem;\n}\n.lead-copy p {\n max-width: 60ch;\n}\n.btn {\n background: var(--surface);\n border: 1px solid var(--border-strong);\n border-radius: calc(var(--radius) - 2px);\n color: var(--text);\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n font-size: .875rem;\n gap: .35rem;\n padding: .35rem .7rem;\n text-decoration: none;\n white-space: nowrap;\n}\n.btn:hover {\n background: var(--surface-2);\n}\n.btn:disabled {\n cursor: not-allowed;\n opacity: .55;\n}\n.btn.primary {\n background: var(--accent);\n border-color: var(--accent);\n color: var(--on-accent);\n}\n.btn.primary:hover {\n background: color-mix(in srgb, var(--accent) 88%, black);\n}\n.btn.danger {\n color: var(--danger);\n}\n.btn.danger:hover {\n background: color-mix(in srgb, var(--danger) 10%, var(--surface));\n}\n.btn.quiet {\n background: none;\n border-color: var(--border);\n color: var(--muted);\n}\n.btn.quiet:hover {\n background: var(--surface-2);\n color: var(--text);\n}\ninput {\n background: var(--surface);\n border: 1px solid var(--border-strong);\n border-radius: calc(var(--radius) - 2px);\n color: var(--text);\n min-height: 2.25rem;\n padding: .3rem .6rem;\n width: 100%;\n}\ninput::placeholder {\n color: var(--muted);\n}\n.row {\n align-items: center;\n display: flex;\n flex-wrap: wrap;\n gap: .5rem;\n}\n.row input {\n flex: 1 1 14rem;\n width: auto;\n}\n.actions {\n display: flex;\n flex-wrap: wrap;\n gap: .5rem;\n}\n.dot {\n border-radius: 50%;\n display: inline-block;\n flex: none;\n height: .5rem;\n width: .5rem;\n background: var(--muted);\n}\n.dot.ok,\n.dot.success {\n background: var(--ok);\n}\n.dot.auth_required {\n background: var(--warn);\n}\n.dot.error,\n.dot.timeout {\n background: var(--danger);\n}\n.dot.loading {\n background: var(--border-strong);\n}\n.badge {\n align-items: center;\n background: var(--surface-2);\n border-radius: 999px;\n color: var(--muted);\n display: inline-flex;\n font-size: .75rem;\n gap: .3rem;\n line-height: 1.6;\n padding: .1rem .5rem;\n white-space: nowrap;\n}\n.badge.ok {\n background: color-mix(in srgb, var(--ok) 12%, var(--surface));\n color: var(--ok);\n}\n.badge.warn {\n background: color-mix(in srgb, var(--warn) 14%, var(--surface));\n color: var(--warn);\n}\n.badge.danger {\n background: color-mix(in srgb, var(--danger) 12%, var(--surface));\n color: var(--danger);\n}\n.badge.accent {\n background: var(--tint);\n color: var(--link);\n}\n.section {\n display: grid;\n gap: .75rem;\n margin-top: 1.75rem;\n}\n.section-head {\n align-items: baseline;\n display: flex;\n gap: var(--gap);\n justify-content: space-between;\n}\n.empty,\n.unavailable {\n background: var(--surface);\n border: 1px dashed var(--border-strong);\n border-radius: var(--radius);\n color: var(--muted);\n padding: 1.5rem var(--pad);\n text-align: center;\n}\n.unavailable {\n text-align: left;\n}\n.msg {\n background: color-mix(in srgb, var(--danger) 8%, var(--surface));\n border: 1px solid color-mix(in srgb, var(--danger) 28%, var(--surface));\n border-radius: calc(var(--radius) - 2px);\n color: var(--danger);\n font-size: .875rem;\n padding: .5rem .75rem;\n}\n.error-notice {\n color: var(--danger);\n}\n.notice:empty {\n block-size: 0;\n margin: 0;\n}\n.summary {\n color: var(--muted);\n font-size: .875rem;\n}\n.summary .sep {\n opacity: .5;\n}\n.summary .warn {\n color: var(--warn);\n}\n.summary .danger {\n color: var(--danger);\n}\n.endpoint {\n align-items: center;\n background: var(--surface);\n border: 1px solid var(--border);\n border-radius: var(--radius);\n display: flex;\n gap: .75rem;\n justify-content: space-between;\n padding: .5rem .5rem .5rem .75rem;\n}\n.endpoint code {\n flex: 1 1 auto;\n min-width: 0;\n overflow-wrap: anywhere;\n}\n.endpoints,\n.endpoint-block {\n display: grid;\n gap: .35rem;\n}\n.endpoints {\n gap: .6rem;\n}\n.endpoint-label {\n flex: none;\n}\n.setup-list {\n display: grid;\n gap: .6rem;\n margin-top: .5rem;\n}\n.setup-item {\n background: var(--surface);\n border: 1px solid var(--border);\n border-radius: calc(var(--radius) - 2px);\n display: grid;\n gap: .35rem;\n padding: .5rem .6rem .6rem .75rem;\n}\n.setup-head {\n align-items: center;\n display: flex;\n gap: .5rem;\n justify-content: space-between;\n}\n.setup-code,\n.fix-prompt-text {\n background: var(--surface-2);\n border-radius: calc(var(--radius) / 2);\n color: var(--text);\n font-family: var(--mono);\n font-size: .75rem;\n line-height: 1.55;\n margin: 0;\n overflow-wrap: anywhere;\n padding: .5rem .6rem;\n white-space: pre-wrap;\n}\n.fix-prompt {\n display: grid;\n gap: .35rem;\n}\n.fix-prompt-head {\n align-items: center;\n display: flex;\n flex-wrap: wrap;\n gap: .5rem;\n}\n.fix-prompt .fix-prompt-text {\n border: 1px solid var(--border);\n margin-top: .4rem;\n max-height: 18rem;\n overflow: auto;\n}\n.rows {\n background: var(--surface);\n border: 1px solid var(--border);\n border-radius: var(--radius);\n overflow: hidden;\n}\n.rows > * + * {\n border-top: 1px solid var(--border);\n}\n.conn[open] {\n background: var(--surface-2);\n}\n.conn-head {\n align-items: center;\n cursor: pointer;\n display: flex;\n gap: .75rem;\n justify-content: space-between;\n list-style: none;\n padding: .7rem var(--pad);\n}\n.conn-head::-webkit-details-marker {\n display: none;\n}\n.conn-head:focus-visible {\n outline-offset: -2px;\n}\n.conn-head:hover {\n background: var(--surface-2);\n}\n.conn-main {\n align-items: center;\n display: flex;\n gap: .6rem;\n min-width: 0;\n}\n.conn-name {\n font-size: 1rem;\n font-weight: 500;\n overflow-wrap: anywhere;\n}\n.conn-id {\n color: var(--muted);\n}\n.conn-badges {\n align-items: center;\n display: flex;\n flex-wrap: wrap;\n gap: .35rem;\n justify-content: flex-end;\n}\n.conn-caret {\n border-right: 1.5px solid var(--muted);\n border-bottom: 1.5px solid var(--muted);\n flex: none;\n height: .4rem;\n rotate: -45deg;\n transform-origin: center;\n width: .4rem;\n}\n.conn[open] .conn-caret {\n rotate: 45deg;\n}\n.conn-body {\n background: var(--surface);\n border-top: 1px solid var(--border);\n display: grid;\n gap: .75rem;\n padding: var(--pad);\n}\n.conn-note {\n color: var(--muted);\n max-width: 70ch;\n}\n.subcard {\n background: var(--surface-2);\n border: 1px solid var(--border);\n border-radius: calc(var(--radius) - 2px);\n display: grid;\n gap: .5rem;\n padding: .75rem;\n}\n.subcard-head {\n align-items: baseline;\n display: flex;\n flex-wrap: wrap;\n gap: .5rem;\n justify-content: space-between;\n}\ndetails > .subcard,\ndetails > .tool-list {\n margin-top: .5rem;\n}\n.tool-list {\n display: grid;\n gap: .4rem;\n max-height: 22rem;\n overflow: auto;\n}\n.filter {\n flex: 0 1 18rem;\n min-width: 10rem;\n width: auto;\n}\n.connector-drift {\n display: grid;\n gap: .15rem;\n}\n.tool {\n display: grid;\n gap: .1rem;\n border-left: 2px solid var(--border-strong);\n padding-left: .6rem;\n}\n.tool code {\n font-family: var(--mono);\n font-size: .8125rem;\n overflow-wrap: anywhere;\n}\n.tool-head {\n align-items: center;\n display: flex;\n flex-wrap: wrap;\n gap: .25rem .5rem;\n}\n.tool-legend {\n margin-bottom: .15rem;\n}\n.td {\n color: var(--muted);\n font-size: .8125rem;\n}\ndetails > summary {\n cursor: pointer;\n}\n.disclosure {\n color: var(--link);\n font-size: .875rem;\n list-style: none;\n}\n.disclosure::-webkit-details-marker {\n display: none;\n}\n.disclosure::before {\n content: \"▸ \";\n}\ndetails[open] > .disclosure::before {\n content: \"▾ \";\n}\n.drift-counts {\n display: grid;\n gap: .5rem;\n grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));\n margin-top: .5rem;\n}\n.drift-count {\n background: var(--surface);\n border: 1px solid var(--border);\n border-radius: calc(var(--radius) - 2px);\n display: grid;\n gap: .1rem;\n padding: .4rem .6rem;\n}\n.drift-count.flagged {\n border-color: color-mix(in srgb, var(--warn) 45%, var(--surface));\n}\n.drift-count-value {\n font-size: 1.125rem;\n font-weight: 600;\n}\n.drift-count.flagged .drift-count-value {\n color: var(--warn);\n}\n.drift-count-label {\n color: var(--muted);\n font-size: .75rem;\n}\n.credential-fields,\n.credential-field-summary {\n display: grid;\n gap: .5rem;\n}\n.credential-field {\n display: grid;\n gap: .25rem;\n}\n.credential-field label {\n color: var(--muted);\n font-size: .8125rem;\n}\n.credential-field-summary > div {\n display: flex;\n gap: .5rem;\n justify-content: space-between;\n}\n.credential-form {\n display: grid;\n gap: .5rem;\n}\n.credential-form .actions {\n justify-content: flex-end;\n}\n.activity-list {\n background: var(--surface);\n border: 1px solid var(--border);\n border-radius: var(--radius);\n overflow: hidden;\n}\n.activity-list > * + * {\n border-top: 1px solid var(--border);\n}\n.activity-item {\n align-items: center;\n display: grid;\n gap: .5rem var(--gap);\n grid-template-columns: minmax(0, 14rem) minmax(0, 1fr) auto;\n padding: .6rem var(--pad);\n}\n.activity-stamp {\n align-items: center;\n display: flex;\n gap: .6rem;\n min-width: 0;\n}\n.activity-time {\n display: block;\n font-size: .8125rem;\n}\n.activity-actor {\n color: var(--muted);\n font-size: .8125rem;\n}\n.activity-actor-id {\n color: var(--muted);\n}\n.activity-address {\n font-family: var(--mono);\n font-size: .8125rem;\n overflow-wrap: anywhere;\n}\n.activity-detail {\n color: var(--muted);\n font-size: .8125rem;\n}\n.activity-outcome {\n text-align: right;\n}\n.activity-item.error .activity-outcome,\n.activity-item.timeout .activity-outcome {\n color: var(--danger);\n}\n.activity-item.success .activity-outcome {\n color: var(--ok);\n}\n.activity-empty {\n color: var(--muted);\n padding: 1.5rem var(--pad);\n text-align: center;\n}\n.activity-more {\n margin-top: .75rem;\n}\n.artifact-row {\n align-items: center;\n display: grid;\n gap: .25rem var(--gap);\n grid-template-columns: minmax(0, 1fr) auto;\n padding: .6rem var(--pad);\n}\n.artifact-row .artifact-title {\n font-weight: 600;\n overflow-wrap: anywhere;\n}\n.artifact-row .artifact-meta,\n.artifact-meta {\n color: var(--muted);\n font-size: .8125rem;\n}\n.artifact-badges {\n display: flex;\n flex-wrap: wrap;\n gap: .35rem;\n justify-content: flex-end;\n}\n.artifact-head {\n display: grid;\n gap: .35rem;\n margin-bottom: .75rem;\n}\n.artifact-banner {\n background: color-mix(in srgb, var(--warn) 12%, var(--surface));\n border: 1px solid color-mix(in srgb, var(--warn) 35%, var(--border));\n border-radius: var(--radius);\n color: var(--text);\n padding: .5rem .75rem;\n}\n.artifact-frame {\n background: #ffffff;\n border: 1px solid var(--border);\n border-radius: var(--radius);\n display: block;\n height: calc(100vh - 14rem);\n min-height: 28rem;\n width: 100%;\n}\n.gate {\n display: grid;\n gap: .75rem;\n margin: 3rem auto 0;\n max-width: 30rem;\n}\n.gate h1 {\n font-size: 1.25rem;\n}\n.gate .row {\n flex-wrap: nowrap;\n}\n@media (max-width: 40rem) {\n :root {\n --pad: 1rem;\n }\n .conn-head {\n align-items: flex-start;\n flex-direction: column;\n gap: .4rem;\n }\n .conn-badges {\n justify-content: flex-start;\n }\n .endpoint {\n flex-wrap: wrap;\n }\n .activity-item {\n grid-template-columns: minmax(0, 1fr);\n }\n .activity-outcome {\n text-align: left;\n }\n}\n";
4
+ export const OPERATOR_UI_SCRIPT = "\"use strict\";\n(() => {\n // node_modules/preact/dist/preact.module.js\n var n;\n var l;\n var u;\n var t;\n var i;\n var r;\n var o;\n var e;\n var f;\n var c;\n var a;\n var s;\n var h;\n var p;\n var v;\n var y;\n var d = {};\n var w = [];\n var _ = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;\n var g = Array.isArray;\n function m(n2, l3) {\n for (var u4 in l3) n2[u4] = l3[u4];\n return n2;\n }\n function b(n2) {\n n2 && n2.parentNode && n2.parentNode.removeChild(n2);\n }\n function k(l3, u4, t3) {\n var i3, r3, o3, e3 = {};\n for (o3 in u4) \"key\" == o3 ? i3 = u4[o3] : \"ref\" == o3 ? r3 = u4[o3] : e3[o3] = u4[o3];\n if (arguments.length > 2 && (e3.children = arguments.length > 3 ? n.call(arguments, 2) : t3), \"function\" == typeof l3 && null != l3.defaultProps) for (o3 in l3.defaultProps) void 0 === e3[o3] && (e3[o3] = l3.defaultProps[o3]);\n return x(l3, e3, i3, r3, null);\n }\n function x(n2, t3, i3, r3, o3) {\n var e3 = { type: n2, props: t3, key: i3, ref: r3, __k: null, __: null, __b: 0, __e: null, __c: null, constructor: void 0, __v: null == o3 ? ++u : o3, __i: -1, __u: 0 };\n return null == o3 && null != l.vnode && l.vnode(e3), e3;\n }\n function S(n2) {\n return n2.children;\n }\n function C(n2, l3) {\n this.props = n2, this.context = l3;\n }\n function $(n2, l3) {\n if (null == l3) return n2.__ ? $(n2.__, n2.__i + 1) : null;\n for (var u4; l3 < n2.__k.length; l3++) if (null != (u4 = n2.__k[l3]) && null != u4.__e) return u4.__e;\n return \"function\" == typeof n2.type ? $(n2) : null;\n }\n function I(n2) {\n if (n2.__P && n2.__d) {\n var u4 = n2.__v, t3 = u4.__e, i3 = [], r3 = [], o3 = m({}, u4);\n o3.__v = u4.__v + 1, l.vnode && l.vnode(o3), q(n2.__P, o3, u4, n2.__n, n2.__P.namespaceURI, 32 & u4.__u ? [t3] : null, i3, null == t3 ? $(u4) : t3, !!(32 & u4.__u), r3), o3.__v = u4.__v, o3.__.__k[o3.__i] = o3, D(i3, o3, r3), u4.__e = u4.__ = null, o3.__e != t3 && P(o3);\n }\n }\n function P(n2) {\n if (null != (n2 = n2.__) && null != n2.__c) return n2.__e = n2.__c.base = null, n2.__k.some(function(l3) {\n if (null != l3 && null != l3.__e) return n2.__e = n2.__c.base = l3.__e;\n }), P(n2);\n }\n function A(n2) {\n (!n2.__d && (n2.__d = true) && i.push(n2) && !H.__r++ || r != l.debounceRendering) && ((r = l.debounceRendering) || o)(H);\n }\n function H() {\n try {\n for (var n2, l3 = 1; i.length; ) i.length > l3 && i.sort(e), n2 = i.shift(), l3 = i.length, I(n2);\n } finally {\n i.length = H.__r = 0;\n }\n }\n function L(n2, l3, u4, t3, i3, r3, o3, e3, f4, c3, a3) {\n var s3, h3, p3, v3, y3, _3, g2 = t3 && t3.__k || w, m3 = l3.length;\n for (f4 = T(u4, l3, g2, f4, m3), s3 = 0; s3 < m3; s3++) null != (p3 = u4.__k[s3]) && (h3 = -1 != p3.__i && g2[p3.__i] || d, p3.__i = s3, _3 = q(n2, p3, h3, i3, r3, o3, e3, f4, c3, a3), v3 = p3.__e, p3.ref && h3.ref != p3.ref && (h3.ref && J(h3.ref, null, p3), a3.push(p3.ref, p3.__c || v3, p3)), null == y3 && null != v3 && (y3 = v3), 4 & p3.__u ? (f4 = j(p3, f4, n2), h3.__e && (h3.__e = null)) : \"function\" == typeof p3.type && void 0 !== _3 ? f4 = _3 : v3 && (f4 = v3.nextSibling), p3.__u &= -7);\n return u4.__e = y3, f4;\n }\n function T(n2, l3, u4, t3, i3) {\n var r3, o3, e3, f4, c3, a3 = u4.length, s3 = a3, h3 = 0;\n for (n2.__k = new Array(i3), r3 = 0; r3 < i3; r3++) null != (o3 = l3[r3]) && \"boolean\" != typeof o3 && \"function\" != typeof o3 ? (\"string\" == typeof o3 || \"number\" == typeof o3 || \"bigint\" == typeof o3 || o3.constructor == String ? o3 = n2.__k[r3] = x(null, o3, null, null, null) : g(o3) ? o3 = n2.__k[r3] = x(S, { children: o3 }, null, null, null) : void 0 === o3.constructor && o3.__b > 0 ? o3 = n2.__k[r3] = x(o3.type, o3.props, o3.key, o3.ref ? o3.ref : null, o3.__v) : n2.__k[r3] = o3, f4 = r3 + h3, o3.__ = n2, o3.__b = n2.__b + 1, e3 = null, -1 != (c3 = o3.__i = O(o3, u4, f4, s3)) && (s3--, (e3 = u4[c3]) && (e3.__u |= 2)), null == e3 || null == e3.__v ? (-1 == c3 && (i3 > a3 ? h3-- : i3 < a3 && h3++), \"function\" != typeof o3.type && (o3.__u |= 4)) : c3 != f4 && (c3 == f4 - 1 ? h3-- : c3 == f4 + 1 ? h3++ : (c3 > f4 ? h3-- : h3++, o3.__u |= 4))) : n2.__k[r3] = null;\n if (s3) for (r3 = 0; r3 < a3; r3++) null != (e3 = u4[r3]) && 0 == (2 & e3.__u) && (e3.__e == t3 && (t3 = $(e3)), K(e3, e3));\n return t3;\n }\n function j(n2, l3, u4) {\n var t3, i3;\n if (\"function\" == typeof n2.type) {\n for (t3 = n2.__k, i3 = 0; t3 && i3 < t3.length; i3++) t3[i3] && (t3[i3].__ = n2, l3 = j(t3[i3], l3, u4));\n return l3;\n }\n n2.__e != l3 && (l3 && n2.type && !l3.parentNode && (l3 = $(n2)), l3 = u4.insertBefore(n2.__e, l3 || null));\n do {\n l3 = l3 && l3.nextSibling;\n } while (null != l3 && 8 == l3.nodeType);\n return l3;\n }\n function O(n2, l3, u4, t3) {\n var i3, r3, o3, e3 = n2.key, f4 = n2.type, c3 = l3[u4], a3 = null != c3 && 0 == (2 & c3.__u);\n if (null === c3 && null == e3 || a3 && e3 == c3.key && f4 == c3.type) return u4;\n if (t3 > (a3 ? 1 : 0)) {\n for (i3 = u4 - 1, r3 = u4 + 1; i3 >= 0 || r3 < l3.length; ) if (null != (c3 = l3[o3 = i3 >= 0 ? i3-- : r3++]) && 0 == (2 & c3.__u) && e3 == c3.key && f4 == c3.type) return o3;\n }\n return -1;\n }\n function z(n2, l3, u4) {\n \"-\" == l3[0] ? n2.setProperty(l3, null == u4 ? \"\" : u4) : n2[l3] = null == u4 ? \"\" : \"number\" != typeof u4 || _.test(l3) ? u4 : u4 + \"px\";\n }\n function N(n2, l3, u4, t3, i3) {\n var r3, o3;\n n: if (\"style\" == l3) if (\"string\" == typeof u4) n2.style.cssText = u4;\n else {\n if (\"string\" == typeof t3 && (n2.style.cssText = t3 = \"\"), t3) for (l3 in t3) u4 && l3 in u4 || z(n2.style, l3, \"\");\n if (u4) for (l3 in u4) t3 && u4[l3] == t3[l3] || z(n2.style, l3, u4[l3]);\n }\n else if (\"o\" == l3[0] && \"n\" == l3[1]) r3 = l3 != (l3 = l3.replace(s, \"$1\")), o3 = l3.toLowerCase(), l3 = o3 in n2 || \"onFocusOut\" == l3 || \"onFocusIn\" == l3 ? o3.slice(2) : l3.slice(2), n2.l || (n2.l = {}), n2.l[l3 + r3] = u4, u4 ? t3 ? u4[a] = t3[a] : (u4[a] = h, n2.addEventListener(l3, r3 ? v : p, r3)) : n2.removeEventListener(l3, r3 ? v : p, r3);\n else {\n if (\"http://www.w3.org/2000/svg\" == i3) l3 = l3.replace(/xlink(H|:h)/, \"h\").replace(/sName$/, \"s\");\n else if (\"width\" != l3 && \"height\" != l3 && \"href\" != l3 && \"list\" != l3 && \"form\" != l3 && \"tabIndex\" != l3 && \"download\" != l3 && \"rowSpan\" != l3 && \"colSpan\" != l3 && \"role\" != l3 && \"popover\" != l3 && l3 in n2) try {\n n2[l3] = null == u4 ? \"\" : u4;\n break n;\n } catch (n3) {\n }\n \"function\" == typeof u4 || (null == u4 || false === u4 && \"-\" != l3[4] ? n2.removeAttribute(l3) : n2.setAttribute(l3, \"popover\" == l3 && 1 == u4 ? \"\" : u4));\n }\n }\n function V(n2) {\n return function(u4) {\n if (this.l) {\n var t3 = this.l[u4.type + n2];\n if (null == u4[c]) u4[c] = h++;\n else if (u4[c] < t3[a]) return;\n return t3(l.event ? l.event(u4) : u4);\n }\n };\n }\n function q(n2, u4, t3, i3, r3, o3, e3, f4, c3, a3) {\n var s3, h3, p3, v3, y3, d3, _3, k3, x2, M, I2, P2, A3, H2, T3, j3, F = u4.type;\n if (void 0 !== u4.constructor) return null;\n 128 & t3.__u && (c3 = !!(32 & t3.__u), o3 = [f4 = u4.__e = t3.__e]), (s3 = l.__b) && s3(u4);\n n: if (\"function\" == typeof F) {\n h3 = e3.length;\n try {\n if (x2 = u4.props, M = F.prototype && F.prototype.render, I2 = (s3 = F.contextType) && i3[s3.__c], P2 = s3 ? I2 ? I2.props.value : s3.__ : i3, t3.__c ? k3 = (p3 = u4.__c = t3.__c).__ = p3.__E : (M ? u4.__c = p3 = new F(x2, P2) : (u4.__c = p3 = new C(x2, P2), p3.constructor = F, p3.render = Q), I2 && I2.sub(p3), p3.state || (p3.state = {}), p3.__n = i3, v3 = p3.__d = true, p3.__h = [], p3._sb = []), M && null == p3.__s && (p3.__s = p3.state), M && null != F.getDerivedStateFromProps && (p3.__s == p3.state && (p3.__s = m({}, p3.__s)), m(p3.__s, F.getDerivedStateFromProps(x2, p3.__s))), y3 = p3.props, d3 = p3.state, p3.__v = u4, v3) M && null == F.getDerivedStateFromProps && null != p3.componentWillMount && p3.componentWillMount(), M && null != p3.componentDidMount && p3.__h.push(p3.componentDidMount);\n else {\n if (M && null == F.getDerivedStateFromProps && x2 !== y3 && null != p3.componentWillReceiveProps && p3.componentWillReceiveProps(x2, P2), u4.__v == t3.__v || !p3.__e && null != p3.shouldComponentUpdate && false === p3.shouldComponentUpdate(x2, p3.__s, P2)) {\n u4.__v != t3.__v && (p3.props = x2, p3.state = p3.__s, p3.__d = false), u4.__e = t3.__e, u4.__k = t3.__k, u4.__k.some(function(n3) {\n n3 && (n3.__ = u4);\n }), w.push.apply(p3.__h, p3._sb), p3._sb = [], p3.__h.length && e3.push(p3), f4 = $(t3);\n break n;\n }\n null != p3.componentWillUpdate && p3.componentWillUpdate(x2, p3.__s, P2), M && null != p3.componentDidUpdate && p3.__h.push(function() {\n p3.componentDidUpdate(y3, d3, _3);\n });\n }\n if (p3.context = P2, p3.props = x2, p3.__P = n2, p3.__e = false, A3 = l.__r, H2 = 0, M) p3.state = p3.__s, p3.__d = false, A3 && A3(u4), s3 = p3.render(p3.props, p3.state, p3.context), w.push.apply(p3.__h, p3._sb), p3._sb = [];\n else do {\n p3.__d = false, A3 && A3(u4), s3 = p3.render(p3.props, p3.state, p3.context), p3.state = p3.__s;\n } while (p3.__d && ++H2 < 25);\n p3.state = p3.__s, null != p3.getChildContext && (i3 = m(m({}, i3), p3.getChildContext())), M && !v3 && null != p3.getSnapshotBeforeUpdate && (_3 = p3.getSnapshotBeforeUpdate(y3, d3)), T3 = null != s3 && s3.type === S && null == s3.key ? E(s3.props.children) : s3, f4 = L(n2, g(T3) ? T3 : [T3], u4, t3, i3, r3, o3, e3, f4, c3, a3), p3.base = u4.__e, u4.__u &= -161, p3.__h.length && e3.push(p3), k3 && (p3.__E = p3.__ = null);\n } catch (n3) {\n if (e3.length = h3, u4.__v = null, c3 || null != o3) {\n if (n3.then) {\n for (u4.__u |= c3 ? 160 : 128; f4 && 8 == f4.nodeType && f4.nextSibling; ) f4 = f4.nextSibling;\n null != o3 && (o3[o3.indexOf(f4)] = null), u4.__e = f4;\n } else if (null != o3) for (j3 = o3.length; j3--; ) b(o3[j3]);\n } else u4.__e = t3.__e;\n null == u4.__k && (u4.__k = t3.__k || []), n3.then || B(u4), l.__e(n3, u4, t3);\n }\n } else null == o3 && u4.__v == t3.__v ? (u4.__k = t3.__k, u4.__e = t3.__e) : f4 = u4.__e = G(t3.__e, u4, t3, i3, r3, o3, e3, c3, a3);\n return (s3 = l.diffed) && s3(u4), 128 & u4.__u ? void 0 : f4;\n }\n function B(n2) {\n n2 && (n2.__c && (n2.__c.__e = true), n2.__k && n2.__k.some(B));\n }\n function D(n2, u4, t3) {\n for (var i3 = 0; i3 < t3.length; i3++) J(t3[i3], t3[++i3], t3[++i3]);\n l.__c && l.__c(u4, n2), n2.some(function(u5) {\n try {\n n2 = u5.__h, u5.__h = [], n2.some(function(n3) {\n n3.call(u5);\n });\n } catch (n3) {\n l.__e(n3, u5.__v);\n }\n });\n }\n function E(n2) {\n return \"object\" != typeof n2 || null == n2 || n2.__b > 0 ? n2 : g(n2) ? n2.map(E) : void 0 !== n2.constructor ? null : m({}, n2);\n }\n function G(u4, t3, i3, r3, o3, e3, f4, c3, a3) {\n var s3, h3, p3, v3, y3, w3, _3, m3 = i3.props || d, k3 = t3.props, x2 = t3.type;\n if (\"svg\" == x2 ? o3 = \"http://www.w3.org/2000/svg\" : \"math\" == x2 ? o3 = \"http://www.w3.org/1998/Math/MathML\" : o3 || (o3 = \"http://www.w3.org/1999/xhtml\"), null != e3) {\n for (s3 = 0; s3 < e3.length; s3++) if ((y3 = e3[s3]) && \"setAttribute\" in y3 == !!x2 && (x2 ? y3.localName == x2 : 3 == y3.nodeType)) {\n u4 = y3, e3[s3] = null;\n break;\n }\n }\n if (null == u4) {\n if (null == x2) return document.createTextNode(k3);\n u4 = document.createElementNS(o3, x2, k3.is && k3), c3 && (l.__m && l.__m(t3, e3), c3 = false), e3 = null;\n }\n if (null == x2) m3 === k3 || c3 && u4.data == k3 || (u4.data = k3);\n else {\n if (e3 = \"textarea\" == x2 && null != k3.defaultValue ? null : e3 && n.call(u4.childNodes), !c3 && null != e3) for (m3 = {}, s3 = 0; s3 < u4.attributes.length; s3++) m3[(y3 = u4.attributes[s3]).name] = y3.value;\n for (s3 in m3) y3 = m3[s3], \"dangerouslySetInnerHTML\" == s3 ? p3 = y3 : \"children\" == s3 || s3 in k3 || \"value\" == s3 && \"defaultValue\" in k3 || \"checked\" == s3 && \"defaultChecked\" in k3 || N(u4, s3, null, y3, o3);\n for (s3 in k3) y3 = k3[s3], \"children\" == s3 ? v3 = y3 : \"dangerouslySetInnerHTML\" == s3 ? h3 = y3 : \"value\" == s3 ? w3 = y3 : \"checked\" == s3 ? _3 = y3 : c3 && \"function\" != typeof y3 || m3[s3] === y3 || N(u4, s3, y3, m3[s3], o3);\n if (h3) c3 || p3 && (h3.__html == p3.__html || h3.__html == u4.innerHTML) || (u4.innerHTML = h3.__html), t3.__k = [];\n else if (p3 && (u4.innerHTML = \"\"), L(\"template\" == t3.type ? u4.content : u4, g(v3) ? v3 : [v3], t3, i3, r3, \"foreignObject\" == x2 ? \"http://www.w3.org/1999/xhtml\" : o3, e3, f4, e3 ? e3[0] : i3.__k && $(i3, 0), c3, a3), null != e3) for (s3 = e3.length; s3--; ) b(e3[s3]);\n c3 && \"textarea\" != x2 || (s3 = \"value\", \"progress\" == x2 && null == w3 ? u4.removeAttribute(\"value\") : null != w3 && (w3 !== u4[s3] || \"progress\" == x2 && !w3 || \"option\" == x2 && w3 != m3[s3]) && N(u4, s3, w3, m3[s3], o3), s3 = \"checked\", null != _3 && _3 != u4[s3] && N(u4, s3, _3, m3[s3], o3));\n }\n return u4;\n }\n function J(n2, u4, t3) {\n try {\n if (\"function\" == typeof n2) {\n var i3 = \"function\" == typeof n2.__u;\n i3 && n2.__u(), i3 && null == u4 || (n2.__u = n2(u4));\n } else n2.current = u4;\n } catch (n3) {\n l.__e(n3, t3);\n }\n }\n function K(n2, u4, t3) {\n var i3, r3;\n if (l.unmount && l.unmount(n2), (i3 = n2.ref) && (i3.current && i3.current != n2.__e || J(i3, null, u4)), null != (i3 = n2.__c)) {\n if (i3.componentWillUnmount) try {\n i3.componentWillUnmount();\n } catch (n3) {\n l.__e(n3, u4);\n }\n i3.base = i3.__P = i3.__n = null;\n }\n if (i3 = n2.__k) for (r3 = 0; r3 < i3.length; r3++) i3[r3] && K(i3[r3], u4, t3 || \"function\" != typeof n2.type);\n t3 || b(n2.__e), n2.__c = n2.__ = n2.__e = void 0;\n }\n function Q(n2, l3, u4) {\n return this.constructor(n2, u4);\n }\n function R(u4, t3, i3) {\n var r3, o3, e3, f4;\n t3 == document && (t3 = document.documentElement), l.__ && l.__(u4, t3), o3 = (r3 = \"function\" == typeof i3) ? null : i3 && i3.__k || t3.__k, e3 = [], f4 = [], q(t3, u4 = (!r3 && i3 || t3).__k = k(S, null, [u4]), o3 || d, d, t3.namespaceURI, !r3 && i3 ? [i3] : o3 ? null : t3.firstChild ? n.call(t3.childNodes) : null, e3, !r3 && i3 ? i3 : o3 ? o3.__e : t3.firstChild, r3, f4), D(e3, u4, f4), u4.props.children = null;\n }\n n = w.slice, l = { __e: function(n2, l3, u4, t3) {\n for (var i3, r3, o3; l3 = l3.__; ) if ((i3 = l3.__c) && !i3.__) try {\n if ((r3 = i3.constructor) && null != r3.getDerivedStateFromError && (i3.setState(r3.getDerivedStateFromError(n2)), o3 = i3.__d), null != i3.componentDidCatch && (i3.componentDidCatch(n2, t3 || {}), o3 = i3.__d), o3) return i3.__E = i3;\n } catch (l4) {\n n2 = l4;\n }\n throw n2;\n } }, u = 0, t = function(n2) {\n return null != n2 && void 0 === n2.constructor;\n }, C.prototype.setState = function(n2, l3) {\n var u4;\n u4 = null != this.__s && this.__s != this.state ? this.__s : this.__s = m({}, this.state), \"function\" == typeof n2 && (n2 = n2(m({}, u4), this.props)), n2 && m(u4, n2), null != n2 && this.__v && (l3 && this._sb.push(l3), A(this));\n }, C.prototype.forceUpdate = function(n2) {\n this.__v && (this.__e = true, n2 && this.__h.push(n2), A(this));\n }, C.prototype.render = S, i = [], o = \"function\" == typeof Promise ? Promise.prototype.then.bind(Promise.resolve()) : setTimeout, e = function(n2, l3) {\n return n2.__v.__b - l3.__v.__b;\n }, H.__r = 0, f = Math.random().toString(8), c = \"__d\" + f, a = \"__a\" + f, s = /(PointerCapture)$|Capture$/i, h = 0, p = V(false), v = V(true), y = 0;\n\n // node_modules/preact/hooks/dist/hooks.module.js\n var t2;\n var r2;\n var u2;\n var i2;\n var o2 = 0;\n var f2 = [];\n var c2 = l;\n var e2 = c2.__b;\n var a2 = c2.__r;\n var v2 = c2.diffed;\n var l2 = c2.__c;\n var m2 = c2.unmount;\n var p2 = c2.__;\n function s2(n2, t3) {\n c2.__h && c2.__h(r2, n2, o2 || t3), o2 = 0;\n var u4 = r2.__H || (r2.__H = { __: [], __h: [] });\n return n2 >= u4.__.length && u4.__.push({}), u4.__[n2];\n }\n function d2(n2) {\n return o2 = 1, y2(D2, n2);\n }\n function y2(n2, u4, i3) {\n var o3 = s2(t2++, 2);\n if (o3.t = n2, !o3.__c && (o3.__ = [i3 ? i3(u4) : D2(void 0, u4), function(n3) {\n var t3 = o3.__N ? o3.__N[0] : o3.__[0], r3 = o3.t(t3, n3);\n t3 !== r3 && (o3.__N = [r3, o3.__[1]], o3.__c.setState({}));\n }], o3.__c = r2, !r2.__f)) {\n var f4 = function(n3, t3, r3) {\n if (!o3.__c.__H) return true;\n var u5 = false, i4 = o3.__c.props !== n3;\n if (o3.__c.__H.__.some(function(n4) {\n if (n4.__N) {\n u5 = true;\n var t4 = n4.__[0];\n n4.__ = n4.__N, n4.__N = void 0, t4 !== n4.__[0] && (i4 = true);\n }\n }), c3) {\n var f5 = c3.call(this, n3, t3, r3);\n return u5 ? f5 || i4 : f5;\n }\n return !u5 || i4;\n };\n r2.__f = true;\n var c3 = r2.shouldComponentUpdate, e3 = r2.componentWillUpdate;\n r2.componentWillUpdate = function(n3, t3, r3) {\n if (this.__e) {\n var u5 = c3;\n c3 = void 0, f4(n3, t3, r3), c3 = u5;\n }\n e3 && e3.call(this, n3, t3, r3);\n }, r2.shouldComponentUpdate = f4;\n }\n return o3.__N || o3.__;\n }\n function h2(n2, u4) {\n var i3 = s2(t2++, 3);\n !c2.__s && C2(i3.__H, u4) && (i3.__ = n2, i3.u = u4, r2.__H.__h.push(i3));\n }\n function _2(n2, u4) {\n var i3 = s2(t2++, 4);\n !c2.__s && C2(i3.__H, u4) && (i3.__ = n2, i3.u = u4, r2.__h.push(i3));\n }\n function A2(n2) {\n return o2 = 5, T2(function() {\n return { current: n2 };\n }, []);\n }\n function T2(n2, r3) {\n var u4 = s2(t2++, 7);\n return C2(u4.__H, r3) && (u4.__ = n2(), u4.__H = r3, u4.__h = n2), u4.__;\n }\n function j2() {\n for (var n2; n2 = f2.shift(); ) {\n var t3 = n2.__H;\n if (n2.__P && t3) try {\n t3.__h.some(z2), t3.__h.some(B2), t3.__h = [];\n } catch (r3) {\n t3.__h = [], c2.__e(r3, n2.__v);\n }\n }\n }\n c2.__b = function(n2) {\n r2 = null, e2 && e2(n2);\n }, c2.__ = function(n2, t3) {\n n2 && t3.__k && t3.__k.__m && (n2.__m = t3.__k.__m), p2 && p2(n2, t3);\n }, c2.__r = function(n2) {\n a2 && a2(n2), t2 = 0;\n var i3 = (r2 = n2.__c).__H;\n i3 && (u2 === r2 ? (i3.__h = [], r2.__h = [], i3.__.some(function(n3) {\n n3.__N && (n3.__ = n3.__N), n3.u = n3.__N = void 0;\n })) : (i3.__h.some(z2), i3.__h.some(B2), i3.__h = [], t2 = 0)), u2 = r2;\n }, c2.diffed = function(n2) {\n v2 && v2(n2);\n var t3 = n2.__c;\n t3 && t3.__H && (t3.__H.__h.length && (1 !== f2.push(t3) && i2 === c2.requestAnimationFrame || ((i2 = c2.requestAnimationFrame) || w2)(j2)), t3.__H.__.some(function(n3) {\n n3.u && (n3.__H = n3.u, n3.u = void 0);\n })), u2 = r2 = null;\n }, c2.__c = function(n2, t3) {\n t3.some(function(n3) {\n try {\n n3.__h.some(z2), n3.__h = n3.__h.filter(function(n4) {\n return !n4.__ || B2(n4);\n });\n } catch (r3) {\n t3.some(function(n4) {\n n4.__h && (n4.__h = []);\n }), t3 = [], c2.__e(r3, n3.__v);\n }\n }), l2 && l2(n2, t3);\n }, c2.unmount = function(n2) {\n m2 && m2(n2);\n var t3, r3 = n2.__c;\n r3 && r3.__H && (r3.__H.__.some(function(n3) {\n try {\n z2(n3);\n } catch (n4) {\n t3 = n4;\n }\n }), r3.__H = void 0, t3 && c2.__e(t3, r3.__v));\n };\n var k2 = \"function\" == typeof requestAnimationFrame;\n function w2(n2) {\n var t3, r3 = function() {\n clearTimeout(u4), k2 && cancelAnimationFrame(t3), setTimeout(n2);\n }, u4 = setTimeout(r3, 35);\n k2 && (t3 = requestAnimationFrame(r3));\n }\n function z2(n2) {\n var t3 = r2, u4 = n2.__c;\n \"function\" == typeof u4 && (n2.__c = void 0, u4()), r2 = t3;\n }\n function B2(n2) {\n var t3 = r2;\n n2.__c = n2.__(), r2 = t3;\n }\n function C2(n2, t3) {\n return !n2 || n2.length !== t3.length || t3.some(function(t4, r3) {\n return t4 !== n2[r3];\n });\n }\n function D2(n2, t3) {\n return \"function\" == typeof t3 ? t3(n2) : t3;\n }\n\n // src/operator-ui/view.ts\n var OPERATOR_PAGES = [\n \"connections\",\n \"activity\",\n \"artifacts\"\n ];\n var PAGE_META = {\n connections: { path: \"/\", label: \"Connections\" },\n activity: { path: \"/activity\", label: \"Activity\" },\n artifacts: { path: \"/artifacts\", label: \"Artifacts\" },\n artifact: { path: \"/artifacts\", label: \"Artifact\" }\n };\n function pageForPath(path) {\n if (path.startsWith(\"/artifacts/\")) return \"artifact\";\n const match = OPERATOR_PAGES.find((page) => PAGE_META[page].path === path);\n return match ?? \"connections\";\n }\n function isArtifactPage(page) {\n return page === \"artifacts\" || page === \"artifact\";\n }\n function artifactViewRequest(pathname, search) {\n const match = /^\\/artifacts\\/([a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?)(?:\\/v\\/(\\d{1,9}))?$/.exec(pathname);\n if (!match?.[1]) return void 0;\n const params = new URLSearchParams();\n if (match[2]) {\n params.set(\"v\", match[2]);\n for (const pin of new URLSearchParams(search).getAll(\"d\")) params.append(\"d\", pin);\n }\n const query = params.toString();\n return `/artifacts/_api/view/${match[1]}${query ? `?${query}` : \"\"}`;\n }\n function info(message2) {\n return { message: message2, tone: \"info\" };\n }\n function failure(message2, fix) {\n return fix ? { message: message2, tone: \"error\", fix } : { message: message2, tone: \"error\" };\n }\n var REFUSED_COPY = {\n oauth_disconnect: \"OAuth disconnect failed. If the downstream refused it, the deployment's log has its reply.\",\n oauth_reconnect: \"OAuth authorization could not restart. If the downstream refused it, the deployment's log has its reply.\",\n credential_test: \"The credential test could not run.\"\n };\n function oauthDoneNotice(action, answer) {\n if (action === \"oauth_disconnect\") {\n return info(\"OAuth disconnected. Restart authorization when you are ready to reconnect.\");\n }\n return info(\n answer?.state === \"ok\" ? \"OAuth reconnected.\" : \"Authorization restarted. Open the authorization link to reconnect.\"\n );\n }\n function credentialTestNotice(connectorId, answer) {\n return answer?.ok === true ? info(\"Credential is valid.\") : failure(\n \"Credential test failed: the downstream rejected the stored credential, or the test could not reach it. The deployment's log has the downstream's reply.\",\n { kind: \"credential_test_failed\", connectorId }\n );\n }\n function refusedNotice(action, connectorId, problem) {\n if (action === \"credential_test\" && (problem === \"credential_required\" || problem === \"credential_mismatch\")) {\n return failure(PROBLEM_COPY[problem], { kind: problem, connectorId });\n }\n return failure(REFUSED_COPY[action], {\n kind: action === \"credential_test\" ? \"credential_test_failed\" : \"oauth_action_failed\",\n connectorId\n });\n }\n function initialState(page) {\n return {\n page,\n generation: 0,\n session: \"loading\",\n gate: null,\n refreshing: false,\n pendingFocus: null,\n ...identityScopedState()\n };\n }\n function identityScopedState() {\n return {\n data: null,\n connectorFilter: \"\",\n oauthNotice: null,\n oauthBusy: null,\n credentialNotice: null,\n credentialEditing: null,\n credentialBusy: null,\n activityPhase: \"idle\",\n activityNotice: null,\n activityEvents: [],\n activityCursor: null,\n activitySearch: \"\",\n artifactPhase: \"idle\",\n artifactNotice: null,\n artifactRows: [],\n artifactCursor: null,\n artifactQuery: \"\",\n artifactArchived: false,\n artifactView: null\n };\n }\n function resetIdentity(state2, gate2 = null) {\n return {\n ...state2,\n generation: state2.generation + 1,\n session: \"gated\",\n gate: gate2,\n refreshing: false,\n pendingFocus: null,\n ...identityScopedState()\n };\n }\n function withPage(state2, page) {\n return {\n ...state2,\n page,\n credentialEditing: null,\n credentialNotice: null\n };\n }\n function connectorStatusLabel(status) {\n if (status === \"loading\") return \"Loading details\";\n if (status === \"ok\") return \"Connected\";\n if (status === \"auth_required\") return \"Authorization needed\";\n return \"Unavailable\";\n }\n function toolCountLabel(count) {\n return `${count} ${count === 1 ? \"tool\" : \"tools\"}`;\n }\n function connectorStatusTone(status) {\n if (status === \"ok\") return \"ok\";\n if (status === \"auth_required\") return \"warn\";\n if (status === \"loading\") return \"neutral\";\n return \"danger\";\n }\n function summarizeConnectors(connectors) {\n const summary = {\n total: connectors.length,\n connected: 0,\n attention: 0,\n unavailable: 0,\n tools: 0,\n drifting: 0\n };\n for (const connector of connectors) {\n if (connector.status === \"ok\") summary.connected += 1;\n else if (connector.status === \"auth_required\") summary.attention += 1;\n else if (connector.status !== \"loading\") summary.unavailable += 1;\n summary.tools += connector.toolCount || 0;\n if (driftState(connector.catalogDrift) === \"warning\") summary.drifting += 1;\n }\n return summary;\n }\n function connectorSummaryParts(summary) {\n return [\n { text: `${summary.connected} connected`, tone: \"neutral\" },\n ...summary.attention ? [\n {\n text: `${summary.attention} need${summary.attention === 1 ? \"s\" : \"\"} authorization`,\n tone: \"warn\"\n }\n ] : [],\n ...summary.unavailable ? [{ text: `${summary.unavailable} unavailable`, tone: \"danger\" }] : [],\n { text: toolCountLabel(summary.tools), tone: \"neutral\" }\n ];\n }\n var TOOL_SAFETY_BADGE = {\n runs_in_programs: {\n label: \"runs in programs\",\n tone: \"ok\",\n title: \"Explicitly read-only: execute_code programs may call it without asking.\"\n },\n exempt: {\n label: \"exempt from approval\",\n tone: \"neutral\",\n title: \"Not read-only, but this deployment's config lets programs call it without pausing. Each call still counts against the write budget and appears in activity; call_tool still refuses it.\"\n },\n needs_approval: {\n label: \"asks for approval\",\n tone: \"warn\",\n title: \"Not explicitly read-only: a program pauses for resume_execution, and a direct call crosses call_destructive_tool — either way the host asks first.\"\n }\n };\n var PROBLEM_COPY = {\n connector_unavailable: \"Unavailable: its status check or catalog load failed, or did not finish in time. The deployment's log has the downstream error.\",\n oauth_required: \"Needs OAuth authorization: no grant is stored, or the stored grant expired or was revoked.\",\n credential_required: \"Needs a credential: nothing usable is stored in its credential slot.\",\n auth_required: \"Needs authorization. Its secret lives in deployment configuration, not on this page.\",\n credential_mismatch: \"The stored credential does not match the fields this connector declares, so it cannot be used.\",\n catalog_failed: \"Connected, but its tool catalog could not be loaded, so none of its tools are served.\"\n };\n function problemCopy(problem) {\n return problem ? PROBLEM_COPY[problem] ?? null : null;\n }\n function authScopeLabel(scope) {\n return scope === \"personal\" ? \"personal auth\" : \"shared auth\";\n }\n function permissionLabel(connector) {\n if (connector.permissions?.manageSharedAuth) {\n return \"You can manage shared authentication for this connection.\";\n }\n if (connector.permissions?.connectPersonal) {\n return \"You can connect your own account to this connection.\";\n }\n return \"Authentication for this connection is managed by your deployment.\";\n }\n var DRIFT_CATEGORIES = [\n { key: \"unclassifiedTools\", label: \"Unclassified\" },\n { key: \"unservedTools\", label: \"Unserved\" },\n { key: \"annotationConflicts\", label: \"Annotation conflicts\" },\n { key: \"schemaChanges\", label: \"Schema changes\" }\n ];\n function driftTotal(drift) {\n if (!drift) return 0;\n return DRIFT_CATEGORIES.reduce((sum, { key }) => sum + (drift[key] || 0), 0);\n }\n function driftState(drift) {\n if (!drift) return \"unavailable\";\n return driftTotal(drift) > 0 ? \"warning\" : \"clean\";\n }\n function driftCounts(drift) {\n if (!drift) return [];\n return DRIFT_CATEGORIES.map(({ key, label }) => ({\n key,\n label,\n count: drift[key] || 0\n }));\n }\n function driftSummary(drift) {\n const state2 = driftState(drift);\n if (state2 === \"unavailable\") {\n return \"No catalog refresh observed yet in this runtime.\";\n }\n const observed = formatDate(drift?.observedAt);\n const when = observed ? ` · observed ${observed}` : \"\";\n if (state2 === \"clean\") return `Matches the reviewed manifest${when}`;\n const total = driftTotal(drift);\n return `${total} difference${total === 1 ? \"\" : \"s\"} from the reviewed manifest${when}`;\n }\n function safeHttpHref(url) {\n if (!url) return null;\n try {\n const protocol = new URL(url).protocol;\n return protocol === \"http:\" || protocol === \"https:\" ? url : null;\n } catch {\n return null;\n }\n }\n function formatDate(value) {\n if (!value) return \"\";\n const date = new Date(value);\n return Number.isNaN(date.valueOf()) ? \"\" : date.toLocaleString();\n }\n function actorLabel(actor) {\n if (!actor?.kind) return \"unknown\";\n if (actor.label) return `${actor.kind} · ${actor.label}`;\n return actor.id ? `${actor.kind} · ${actor.id}` : actor.kind;\n }\n function actorStableId(actor) {\n if (!actor?.id) return null;\n if (!actor.label && !actor.namespace) return null;\n return actor.namespace ? `${actor.namespace} · ${actor.id}` : actor.id;\n }\n function activityMatches(event, query) {\n const q2 = query.trim().toLowerCase();\n if (!q2) return true;\n return [\n event.address,\n event.connectorId,\n event.toolName,\n event.source,\n event.outcome,\n event.errorCode,\n event.friction,\n event.actor?.kind,\n event.actor?.id,\n event.actor?.namespace,\n event.actor?.label\n ].some((value) => String(value ?? \"\").toLowerCase().includes(q2));\n }\n function filterActivity(events, query) {\n return events.filter((event) => activityMatches(event, query));\n }\n function activitySummary(events) {\n if (events.length === 0) return \"Arguments and results are never stored.\";\n const tools = new Set(events.map((event) => event.address)).size;\n return `${events.length} loaded call${events.length === 1 ? \"\" : \"s\"} · ${tools} tool${tools === 1 ? \"\" : \"s\"} · no arguments or results stored`;\n }\n var ACTIVITY_OUTCOMES = [\n \"success\",\n \"error\",\n \"timeout\",\n \"cancelled\",\n \"paused\",\n \"approved\"\n ];\n function activityOutcomeClass(outcome) {\n return ACTIVITY_OUTCOMES.includes(outcome) ? outcome : \"error\";\n }\n function activityDetail(event) {\n const parts = [event.source];\n if (event.approval === \"tool\") parts.push(\"approved for the rest of the run\");\n if (event.approval === \"call\") parts.push(\"approved for this call\");\n if (event.attempts > 1) parts.push(`${event.attempts} attempts`);\n if (event.friction) parts.push(event.friction);\n if (event.errorCode && event.errorCode !== event.friction) {\n parts.push(event.errorCode);\n }\n return parts.join(\" · \");\n }\n function credentialStateLabel(credential) {\n if (!credential.configured) return \"not configured\";\n const masked = credential.fields?.length ? \"configured\" : `configured · ••••${credential.lastFour ?? \"\"}`;\n return credential.updatedAt ? `${masked} · updated ${formatDate(credential.updatedAt)}` : masked;\n }\n function gateCopy(kind, signedIn) {\n if (kind === \"cloudflare-access\") {\n return \"Cloudflare Access admitted this browser, but the current identity cannot open deployment-wide operator pages.\";\n }\n if (kind !== \"clerk\") {\n return \"Paste an operator bearer token to open this page. Nothing is requested until you do.\";\n }\n return signedIn ? \"Signed in with Clerk, but this account cannot open deployment-wide operator pages.\" : \"Sign in with Clerk to open this operator page.\";\n }\n\n // src/operator-ui/app/config.ts\n var auth = AUTH;\n var mcpUrl = MCP_URL;\n var initialPage = INITIAL_PAGE;\n var homeUrl = HOME_URL;\n var titleSuffix = TITLE_SUFFIX;\n var productName = PRODUCT_NAME;\n var productDescription = PRODUCT_DESCRIPTION;\n var productOperatorLabel = PRODUCT_OPERATOR_LABEL;\n var TOKEN_KEY = \"connecta:token\";\n\n // src/fix-prompt.ts\n var CONNECTOR_ID_RE = /^[a-z0-9_-]+$/;\n function renderFixPrompt(spec, connectorId) {\n const id = connectorId !== void 0 && CONNECTOR_ID_RE.test(connectorId) ? connectorId : void 0;\n return [\n \"Diagnose and fix a problem in this connecta deployment (the @zackbart/connecta package). It is configured as code: connectors, credential slots, OAuth clients, pools, and inbound auth are declared in the deployment's source and environment, so the fix belongs there and not in the operator page.\",\n `Problem: ${spec.problem}` + (id ? `\nConnector id: ${id}` : \"\"),\n `Where to look:\n${spec.steps.map((step) => `- ${step}`).join(\"\\n\")}`,\n \"This prompt deliberately carries no error text, tokens, or URLs. Find the underlying cause in the deployment's own logs (lines prefixed [connecta]) or by reproducing the failure locally. Never put a secret in source, a log line, or your reply: secrets belong in the deployment's environment or its credential vault.\",\n \"Make the smallest change that fixes it, then verify it by redeploying and refreshing the connection on the operator Connections page. If the fix needs something you cannot do yourself — a provider console setting, a secret only the operator holds — name that exact step instead.\"\n ].join(\"\\n\\n\");\n }\n\n // src/operator-ui/fix-prompts.ts\n var CATALOGUE = {\n connector_unavailable: {\n problem: \"A connector is unavailable: its status check or catalog load failed, or did not finish before the operator page's deadline.\",\n steps: [\n \"Confirm the connector's downstream URL or API base in the deployment config, and that the deployment can reach it from where it runs.\",\n \"Check the credentials or headers the connector sends; a rejected credential often surfaces as a failed status rather than as an authorization prompt.\",\n \"If the downstream is slow rather than down, review the connector's timeouts and the deployment's discovery.probeTimeoutMs.\"\n ]\n },\n oauth_required: {\n problem: \"A downstream OAuth connector needs authorization: no grant is stored, or the stored grant expired or was revoked and could not be refreshed.\",\n steps: [\n \"Reauthorize from the operator page (Connect account or Reconnect OAuth) or with authorize_connector; this needs no code change if the grant simply lapsed.\",\n \"If it needs reauthorizing again soon after, check that the OAuth client requests offline access or a refresh token, and that the storage holding OAuth tokens persists across restarts and is shared by every instance.\",\n \"If authorization cannot start at all, check the connector's OAuth client configuration and the deployment's publicUrl, which forms the /oauth/callback/<connector id> redirect URI.\"\n ]\n },\n credential_required: {\n problem: \"A connector with an operator-managed credential slot has no usable credential stored.\",\n steps: [\n \"An operator with credential administration can add the credential on the operator page; that needs no code change.\",\n \"If nobody can, grant credential administration through the deployment's identity config (credentialAdministration for shared auth, personalConnection for personal auth), which is denied by default.\",\n \"Check that the connector's credential declaration (label and fields) matches what the downstream actually needs.\"\n ]\n },\n auth_required: {\n problem: \"A connector reports that it needs authorization, and its secret lives in deployment configuration rather than in an operator-managed slot.\",\n steps: [\n \"Find where the connector's secret is read (usually an environment variable or Worker secret passed into the connector config) and confirm it is set in the running environment.\",\n \"Rotate the secret at the provider if it expired or was revoked, then update the deployment's environment, not its source.\",\n \"If operators should manage this secret from the page instead, declare a credential slot on the connector and configure a credential vault.\"\n ]\n },\n credential_mismatch: {\n problem: \"The credential stored for a connector does not match the fields the connector currently declares, so it cannot be used.\",\n steps: [\n \"If the connector's credential fields changed on purpose, re-enter the credential on the operator page so the stored fields match.\",\n \"If they changed by accident, restore the previous field names in the connector's credential declaration.\"\n ]\n },\n credential_unreadable: {\n problem: \"A stored credential exists but could not be read or decrypted.\",\n steps: [\n \"Check that the credential vault's encryption key in the deployment environment is the one the credential was stored with; a rotated or missing key makes every stored value unreadable.\",\n \"Check the storage adapter backing the vault is reachable from the deployment.\",\n \"If the key was lost, remove and re-add the credential on the operator page; the old value cannot be recovered.\"\n ]\n },\n credential_test_failed: {\n problem: \"The test for a stored connector credential failed: the downstream rejected it, or the test could not reach the downstream.\",\n steps: [\n \"Confirm the stored value is current at the provider (not rotated, revoked, or scoped too narrowly), and replace it on the operator page if not.\",\n \"Check that the connector's credential test targets the same API base and auth scheme its tool calls use.\"\n ]\n },\n oauth_action_failed: {\n problem: \"Restarting or disconnecting a connector's downstream OAuth from the operator page failed.\",\n steps: [\n \"Check that the connector implements startAuth and disconnectAuth, and that the storage holding its OAuth state is writable.\",\n \"Check the connector's OAuth client configuration, including the authorization server it discovers or is given.\",\n \"Confirm the operator has the config-derived permission for this action (credentialAdministration for shared auth, personalConnection for personal auth).\"\n ]\n },\n catalog_failed: {\n problem: \"A connector reports itself connected, but loading its tool catalog failed, so none of its tools are being served.\",\n steps: [\n \"Check that the downstream still serves a complete tools list; connecta refuses a partial catalog rather than serving part of it.\",\n \"Check for tools the connector cannot accept: invalid schemas, missing descriptions, or names that collide.\",\n \"Pin or upgrade the @zackbart/connecta version if a maintained provider's catalog changed shape underneath it.\"\n ]\n },\n catalog_drift: {\n problem: \"A hosted provider's live catalog differs from the reviewed manifest shipped with connecta: new unclassified tools, unserved tools, annotation conflicts, or schema changes.\",\n steps: [\n \"Unclassified tools are withheld until a release classifies them. Check whether a newer @zackbart/connecta release has, and upgrade if so.\",\n \"If a tool the deployment depends on is now unserved or changed shape, review callers of it before upgrading.\",\n \"Report drift the release does not cover as an issue on the connecta repository, naming the provider and the kinds of drift but no tool data.\"\n ]\n }\n };\n function fixPrompt(kind, connectorId) {\n return renderFixPrompt(CATALOGUE[kind], connectorId);\n }\n var FIX_PROMPT_KINDS = Object.keys(CATALOGUE);\n\n // src/operator-ui/app/store.ts\n var state = initialState(initialPage);\n var listeners = /* @__PURE__ */ new Set();\n function getState() {\n return state;\n }\n function subscribe(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n }\n function set(patch) {\n state = { ...state, ...patch };\n for (const listener of listeners) listener();\n }\n function fence() {\n const generation = state.generation;\n return () => generation === state.generation;\n }\n function message(error, fallback) {\n return error instanceof Error && error.message ? error.message : fallback;\n }\n function sessionToken() {\n if (auth.kind === \"cloudflare-access\") return Promise.resolve(void 0);\n return auth.kind === \"clerk\" ? Promise.resolve(window.Clerk?.session?.getToken() ?? null) : Promise.resolve(localStorage.getItem(TOKEN_KEY));\n }\n function requestHeaders(token, body = false) {\n return {\n ...token ? { Authorization: `Bearer ${token}` } : {},\n ...body ? { \"Content-Type\": \"application/json\" } : {}\n };\n }\n function gate(notice = null) {\n state = resetIdentity(state, notice);\n for (const listener of listeners) listener();\n }\n var Refusal = class extends Error {\n problem;\n constructor(message2, problem) {\n super(message2);\n this.problem = problem;\n }\n };\n async function operatorRequest(path, method, current, body) {\n const token = await sessionToken();\n if (!current()) throw new Error(\"The operator session changed.\");\n if (!token && auth.kind !== \"cloudflare-access\") {\n throw new Error(\"Your operator session has expired.\");\n }\n const res = await fetch(path, {\n method,\n headers: requestHeaders(token, Boolean(body)),\n credentials: \"same-origin\",\n ...body ? { body: JSON.stringify(body) } : {}\n });\n if (res.status === 204) return null;\n let payload = {};\n try {\n payload = await res.json();\n } catch {\n }\n if (res.status === 401) {\n throw new Error(\"Your operator session was not accepted. Sign in again.\");\n }\n if (res.status === 403) {\n throw new Error(\"This identity may not perform that action.\");\n }\n if (!res.ok) {\n throw new Refusal(payload.error || `Request failed (${res.status}).`, payload.problem);\n }\n return payload;\n }\n async function loadData() {\n const current = fence();\n if (state.session === \"ready\") set({ refreshing: true });\n let token;\n try {\n token = await sessionToken();\n } catch (error) {\n if (!current()) return;\n const why = message(error, \"unknown error\");\n return gate(failure(`Could not read the Clerk session: ${why}`));\n }\n if (!current()) return;\n if (!token && auth.kind !== \"cloudflare-access\") return gate(null);\n let res;\n try {\n res = await fetch(\"/ui/data\", {\n headers: requestHeaders(token),\n credentials: \"same-origin\"\n });\n } catch (error) {\n if (!current()) return;\n return gate(failure(`Network error: ${message(error, \"unknown error\")}`));\n }\n if (!current()) return;\n if (res.status === 401 || res.status === 403) {\n if (auth.kind === \"clerk\") {\n return gate(\n failure(\n res.status === 403 ? \"This Clerk account is not allowed to access connecta.\" : \"Your Clerk session was not accepted. Sign out and try again.\"\n )\n );\n }\n if (auth.kind === \"cloudflare-access\") {\n return gate(\n failure(\n \"Cloudflare Access admitted the request, but this identity is not an eligible operator.\"\n )\n );\n }\n localStorage.removeItem(TOKEN_KEY);\n return gate(failure(\"Token rejected — enter a valid bearer token.\"));\n }\n if (!res.ok) return gate(failure(`Error ${res.status}`));\n let data;\n try {\n data = await res.json();\n } catch {\n if (!current()) return;\n return gate(failure(\"Operator data could not be read.\"));\n }\n if (!current()) return;\n if (!Array.isArray(data.connectors)) return gate(failure(\"Connection list could not be read.\"));\n set({ data, session: \"ready\", gate: null, refreshing: false });\n void loadConnectorDetails(data, current, token);\n }\n async function mutate(options) {\n const current = fence();\n if (options.reload) detailRevisions.set(options.reload, (detailRevisions.get(options.reload) ?? 0) + 1);\n set(options.busy);\n try {\n const payload = await options.request(current);\n if (!current()) return;\n if (!current()) return;\n set(options.done(payload));\n if (options.reload) void refreshConnector(options.reload);\n } catch (error) {\n if (!current()) return;\n set(options.failed(failure(message(error, options.fallback)), error));\n }\n }\n function focusHandled() {\n if (state.pendingFocus !== null) set({ pendingFocus: null });\n }\n function setPage(page, focus = false) {\n state = withPage(state, page);\n if (focus) {\n state = {\n ...state,\n pendingFocus: state.session === \"ready\" ? `${page}Heading` : \"gateHeading\"\n };\n }\n for (const listener of listeners) listener();\n }\n function navigate(page, href) {\n history.pushState({ operatorPage: page }, \"\", href);\n setPage(page, true);\n }\n function setConnectorFilter(connectorFilter) {\n set({ connectorFilter });\n }\n function setActivitySearch(activitySearch) {\n set({ activitySearch });\n }\n function signInWithBearer(value) {\n gate(null);\n localStorage.setItem(TOKEN_KEY, value);\n void loadCurrent().then(() => {\n if (state.session === \"ready\") set({ pendingFocus: `${state.page}Heading` });\n });\n }\n function forgetBearer() {\n localStorage.removeItem(TOKEN_KEY);\n gate(null);\n set({ pendingFocus: \"token\" });\n }\n function oauthAction(connector, action) {\n const disconnecting = action === \"disconnect\";\n const kind = disconnecting ? \"oauth_disconnect\" : \"oauth_reconnect\";\n const confirmed = window.confirm(\n disconnecting ? `Disconnect OAuth for ${connector}? Stored credentials and any pending authorization will be removed.` : `Restart OAuth for ${connector}? Stored credentials and any pending authorization will be replaced.`\n );\n if (!confirmed) return Promise.resolve();\n return mutate({\n request: (current) => operatorRequest(\n `/ui/oauth/${encodeURIComponent(connector)}`,\n disconnecting ? \"DELETE\" : \"POST\",\n current\n ),\n busy: { oauthNotice: null, oauthBusy: connector },\n done: (payload) => ({\n ...state.data ? { data: { ...state.data, connectors: state.data.connectors.map((c3) => {\n if (c3.id !== connector) return c3;\n const { authorizationUrl: _old, ...rest } = c3;\n return { ...rest, status: \"auth_required\", tools: [], toolCount: 0, ...!disconnecting && payload?.authorizationUrl ? { authorizationUrl: payload.authorizationUrl } : {} };\n }) } } : {},\n oauthBusy: null,\n pendingFocus: \"oauthNotice\",\n oauthNotice: oauthDoneNotice(kind, payload)\n }),\n // The route's words never reach this notice (see `refusedNotice`); a\n // failure the page described itself — a lapsed session, a denied\n // identity, a dropped connection — keeps its own.\n failed: (notice, error) => ({\n oauthBusy: null,\n oauthNotice: error instanceof Refusal ? refusedNotice(kind, connector, error.problem) : { ...notice, fix: { kind: \"oauth_action_failed\", connectorId: connector } },\n pendingFocus: \"oauthNotice\"\n }),\n fallback: \"OAuth action failed.\",\n reload: connector\n });\n }\n function editCredential(connector) {\n set({ credentialEditing: connector, credentialNotice: null });\n }\n function refuseCredential(copy) {\n set({ credentialNotice: failure(copy), pendingFocus: \"credentialNotice\" });\n }\n function credentialMutation(connector, request, done, reload = true, failed = (notice) => notice) {\n const land = (credentialNotice) => ({\n credentialBusy: null,\n credentialNotice,\n pendingFocus: \"credentialNotice\"\n });\n return mutate({\n request,\n busy: { credentialBusy: connector, credentialNotice: null },\n done: (payload) => land(done(payload)),\n failed: (notice, error) => land(failed(notice, error)),\n fallback: \"Credential action failed.\",\n reload: reload ? connector : void 0\n });\n }\n function saveCredential(connector, body) {\n return credentialMutation(\n connector,\n (current) => operatorRequest(\n `/ui/credentials/${encodeURIComponent(connector)}`,\n \"PUT\",\n current,\n body\n ),\n () => {\n set({ credentialEditing: null });\n return info(\"Credential saved.\");\n }\n );\n }\n function removeCredential(connector) {\n const confirmed = window.confirm(\n \"Remove this credential? The connector will stop authenticating until a replacement is added.\"\n );\n if (!confirmed) return Promise.resolve();\n return credentialMutation(\n connector,\n (current) => operatorRequest(\n `/ui/credentials/${encodeURIComponent(connector)}`,\n \"DELETE\",\n current\n ),\n () => info(\"Credential removed.\")\n );\n }\n function testCredential(connector) {\n return credentialMutation(\n connector,\n (current) => operatorRequest(\n `/ui/credentials/${encodeURIComponent(connector)}/test`,\n \"POST\",\n current\n ),\n (payload) => credentialTestNotice(connector, payload),\n false,\n // As for OAuth: the route's words never, the page's own always.\n (notice, error) => error instanceof Refusal ? refusedNotice(\"credential_test\", connector, error.problem) : { ...notice, fix: { kind: \"credential_test_failed\", connectorId: connector } }\n );\n }\n async function loadActivity(reset) {\n if (!state.data?.activityEnabled) return;\n const current = fence();\n set({\n activityPhase: \"loading\",\n activityNotice: null,\n ...reset ? { activityEvents: [], activityCursor: null } : {}\n });\n const params = new URLSearchParams({ limit: \"50\" });\n if (!reset && state.activityCursor) {\n params.set(\"cursor\", state.activityCursor);\n }\n try {\n const payload = await operatorRequest(\n `/ui/activity?${params}`,\n \"GET\",\n current\n );\n if (!current()) return;\n set({\n activityPhase: \"ready\",\n activityEvents: [\n ...reset ? [] : state.activityEvents,\n ...payload?.events ?? []\n ],\n activityCursor: payload?.nextCursor ?? null\n });\n } catch (error) {\n if (!current()) return;\n set({\n activityPhase: \"error\",\n activityNotice: failure(message(error, \"Activity could not be loaded.\"))\n });\n }\n }\n async function artifactRead(path, current) {\n let token;\n try {\n token = await sessionToken();\n } catch {\n if (current()) gate(failure(\"Could not read the sign-in session.\"));\n return void 0;\n }\n if (!current()) return void 0;\n if (!token && auth.kind !== \"cloudflare-access\") {\n gate(null);\n return void 0;\n }\n let res;\n try {\n res = await fetch(path, { headers: requestHeaders(token), credentials: \"same-origin\" });\n } catch {\n if (current()) gate(failure(\"Network error: the artifact could not be reached.\"));\n return void 0;\n }\n if (!current()) return void 0;\n if (res.status === 401) {\n if (auth.kind !== \"clerk\" && auth.kind !== \"cloudflare-access\") {\n localStorage.removeItem(TOKEN_KEY);\n gate(failure(\"Token rejected — enter a valid bearer token.\"));\n } else {\n gate(failure(\"Your session was not accepted. Sign out and try again.\"));\n }\n return void 0;\n }\n if (res.status === 403) {\n gate(failure(\"This deployment does not open artifact pages to this identity.\"));\n return void 0;\n }\n return res;\n }\n async function loadArtifacts(reset) {\n const current = fence();\n set({\n artifactPhase: \"loading\",\n artifactNotice: null,\n ...reset ? { artifactRows: [], artifactCursor: null } : {}\n });\n const params = new URLSearchParams();\n if (state.artifactQuery.trim()) params.set(\"q\", state.artifactQuery.trim());\n if (state.artifactArchived) params.set(\"archived\", \"1\");\n if (!reset && state.artifactCursor) params.set(\"cursor\", state.artifactCursor);\n const query = params.toString();\n const res = await artifactRead(`/artifacts/_api/list${query ? `?${query}` : \"\"}`, current);\n if (!res || !current()) return;\n if (!res.ok) {\n return set({\n session: \"ready\",\n gate: null,\n artifactPhase: \"error\",\n artifactNotice: failure(\n res.status === 404 ? \"Artifacts are not available to this identity.\" : \"Artifacts could not be loaded.\"\n )\n });\n }\n let payload;\n try {\n payload = await res.json();\n } catch {\n payload = {};\n }\n if (!current()) return;\n set({\n session: \"ready\",\n gate: null,\n artifactPhase: \"ready\",\n artifactRows: [...reset ? [] : state.artifactRows, ...payload.artifacts ?? []],\n artifactCursor: payload.nextCursor ?? null\n });\n }\n async function loadArtifactView() {\n const current = fence();\n const request = artifactViewRequest(window.location.pathname, window.location.search);\n set({ artifactPhase: \"loading\", artifactNotice: null });\n if (!request) {\n return set({\n session: \"ready\",\n artifactPhase: \"error\",\n artifactNotice: failure(\"There is no artifact at this address.\")\n });\n }\n const res = await artifactRead(request, current);\n if (!res || !current()) return;\n if (!res.ok) {\n return set({\n session: \"ready\",\n gate: null,\n artifactPhase: \"error\",\n artifactNotice: failure(\n res.status === 404 ? \"There is no artifact here, or this identity cannot open it.\" : \"The artifact could not be loaded.\"\n )\n });\n }\n let view = null;\n try {\n view = await res.json();\n } catch {\n view = null;\n }\n if (!current()) return;\n if (!view || typeof view.document !== \"string\") {\n return set({\n session: \"ready\",\n gate: null,\n artifactPhase: \"error\",\n artifactNotice: failure(\"The artifact could not be read.\")\n });\n }\n set({ session: \"ready\", gate: null, artifactPhase: \"ready\", artifactView: view });\n }\n function setArtifactQuery(artifactQuery) {\n set({ artifactQuery });\n }\n function setArtifactArchived(artifactArchived) {\n set({ artifactArchived });\n void loadArtifacts(true);\n }\n function loadCurrent() {\n if (state.page === \"artifacts\") return loadArtifacts(true);\n if (state.page === \"artifact\") return loadArtifactView();\n return loadData();\n }\n function signIn() {\n window.Clerk?.redirectToSignIn({\n signInFallbackRedirectUrl: window.location.href,\n signUpFallbackRedirectUrl: window.location.href\n });\n }\n function signOut() {\n if (auth.kind === \"cloudflare-access\") {\n gate(null);\n window.location.assign(\"/cdn-cgi/access/logout\");\n return;\n }\n const clerk = window.Clerk;\n gate(null);\n void clerk?.signOut({ redirectUrl: window.location.href });\n }\n async function boot() {\n const onPop = () => setPage(pageForPath(window.location.pathname), true);\n window.addEventListener(\"popstate\", onPop);\n if (auth.kind === \"clerk\") {\n const clerk = window.Clerk;\n if (!clerk) {\n const why = \"Clerk could not load. Check your network and try again.\";\n return gate(failure(why));\n }\n try {\n await clerk.load({\n ...auth.signInUrl ? { signInUrl: auth.signInUrl } : {},\n ...auth.signUpUrl ? { signUpUrl: auth.signUpUrl } : {},\n signInFallbackRedirectUrl: window.location.href,\n signUpFallbackRedirectUrl: window.location.href,\n afterSignOutUrl: window.location.href\n });\n let sessionId = clerk.session?.id ?? null;\n clerk.addListener((resources) => {\n const next = resources.session?.id ?? null;\n if (next === sessionId) return;\n sessionId = next;\n gate(null);\n void loadCurrent();\n });\n } catch (error) {\n const why = message(error, \"unknown error\");\n return gate(failure(`Clerk could not initialize: ${why}`));\n }\n }\n await loadCurrent();\n }\n var detailGeneration = 0;\n var detailRevisions = /* @__PURE__ */ new Map();\n async function loadConnectorDetails(data, current, token) {\n const generation = ++detailGeneration;\n let next = 0;\n const worker = async () => {\n while (next < data.connectors.length && current() && generation === detailGeneration) {\n const connector = data.connectors[next++];\n const revision = (detailRevisions.get(connector.id) ?? 0) + 1;\n detailRevisions.set(connector.id, revision);\n let detail;\n try {\n const response = await fetch(`/ui/connectors/${encodeURIComponent(connector.id)}`, { headers: requestHeaders(token), credentials: \"same-origin\" });\n if (!response.ok) throw new Error(`Connection details unavailable (${response.status})`);\n detail = await response.json();\n } catch {\n detail = { ...connector, status: \"error\", problem: \"connector_unavailable\" };\n }\n if (!current() || generation !== detailGeneration || !state.data) return;\n if (detailRevisions.get(connector.id) !== revision) continue;\n set({ data: { ...state.data, connectors: state.data.connectors.map((c3) => c3.id === connector.id ? detail : c3) } });\n }\n };\n await Promise.all(Array.from({ length: Math.min(4, data.connectors.length) }, worker));\n }\n async function refreshConnector(id) {\n const current = fence();\n const revision = (detailRevisions.get(id) ?? 0) + 1;\n detailRevisions.set(id, revision);\n if (state.data) set({ data: { ...state.data, connectors: state.data.connectors.map((c3) => c3.id === id ? { ...c3, status: \"loading\" } : c3) } });\n try {\n const token = await sessionToken();\n if (!current()) return;\n const response = await fetch(`/ui/connectors/${encodeURIComponent(id)}`, { headers: requestHeaders(token), credentials: \"same-origin\" });\n if (!response.ok) throw new Error(`Connection details unavailable (${response.status})`);\n const detail = await response.json();\n if (!current() || !state.data || detailRevisions.get(id) !== revision) return;\n set({ data: { ...state.data, connectors: state.data.connectors.map((c3) => c3.id === id ? { ...detail, ...detail.status === \"auth_required\" && c3.authorizationUrl ? { authorizationUrl: c3.authorizationUrl } : {} } : c3) } });\n } catch {\n if (!current() || !state.data || detailRevisions.get(id) !== revision) return;\n set({ data: { ...state.data, connectors: state.data.connectors.map((c3) => c3.id === id ? { ...c3, status: \"error\", problem: \"connector_unavailable\" } : c3) } });\n }\n }\n\n // node_modules/preact/jsx-runtime/dist/jsxRuntime.module.js\n var f3 = 0;\n function u3(e3, t3, n2, o3, i3, u4) {\n t3 || (t3 = {});\n var a3, c3, p3 = t3;\n if (\"ref\" in p3) for (c3 in p3 = {}, t3) \"ref\" == c3 ? a3 = t3[c3] : p3[c3] = t3[c3];\n var l3 = { type: e3, props: p3, key: n2, ref: a3, __k: null, __: null, __b: 0, __e: null, __c: null, constructor: void 0, __v: --f3, __i: -1, __u: 0, __source: i3, __self: u4 };\n if (\"function\" == typeof e3 && (a3 = e3.defaultProps)) for (c3 in a3) void 0 === p3[c3] && (p3[c3] = a3[c3]);\n return l.vnode && l.vnode(l3), l3;\n }\n\n // src/operator-ui/app/parts.tsx\n function NoticeLine({\n id,\n notice,\n className = \"meta\"\n }) {\n return /* @__PURE__ */ u3(S, { children: [\n /* @__PURE__ */ u3(\n \"p\",\n {\n id,\n class: notice?.tone === \"error\" ? `notice ${className} error-notice` : `notice ${className}`,\n role: notice?.tone === \"error\" ? \"alert\" : \"status\",\n \"aria-live\": \"polite\",\n tabIndex: -1,\n children: notice ? notice.message : null\n }\n ),\n notice?.tone === \"error\" && notice.fix ? /* @__PURE__ */ u3(FixPrompt, { kind: notice.fix.kind, connectorId: notice.fix.connectorId }) : null\n ] });\n }\n function FixPrompt({\n kind,\n connectorId,\n name\n }) {\n const text = fixPrompt(kind, connectorId);\n return /* @__PURE__ */ u3(\"div\", { class: \"fix-prompt\", \"data-fix-prompt\": kind, children: [\n /* @__PURE__ */ u3(\"div\", { class: \"fix-prompt-head\", children: [\n /* @__PURE__ */ u3(\n CopyButton,\n {\n value: text,\n label: \"Copy fix prompt\",\n class: \"btn quiet\",\n ariaLabel: `Copy fix prompt for ${name ?? connectorId}`\n }\n ),\n /* @__PURE__ */ u3(\"span\", { class: \"meta\", children: \"Fixed text for a coding agent working on this deployment. It carries no error details or secrets.\" })\n ] }),\n /* @__PURE__ */ u3(\"details\", { children: [\n /* @__PURE__ */ u3(\"summary\", { class: \"disclosure\", children: \"Preview prompt\" }),\n /* @__PURE__ */ u3(\"pre\", { class: \"fix-prompt-text\", children: text })\n ] })\n ] });\n }\n function Badge({\n tone = \"neutral\",\n children\n }) {\n return /* @__PURE__ */ u3(\"span\", { class: tone === \"neutral\" ? \"badge\" : `badge ${tone}`, children });\n }\n function Empty({ children }) {\n return /* @__PURE__ */ u3(\"p\", { class: \"empty\", children });\n }\n function Unavailable({ children }) {\n return /* @__PURE__ */ u3(\"div\", { class: \"unavailable\", children });\n }\n function PageLink({\n page,\n class: className,\n current,\n children\n }) {\n const href = PAGE_META[page].path;\n return /* @__PURE__ */ u3(\n \"a\",\n {\n class: className,\n href,\n ...current ? { \"aria-current\": \"page\" } : {},\n onClick: (event) => {\n if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {\n return;\n }\n event.preventDefault();\n navigate(page, href);\n },\n children\n }\n );\n }\n function CopyButton({\n value,\n label,\n class: className = \"btn\",\n ariaLabel\n }) {\n const [status, setStatus] = d2(\"idle\");\n h2(() => {\n if (status === \"idle\") return;\n const timer = window.setTimeout(() => setStatus(\"idle\"), 1600);\n return () => window.clearTimeout(timer);\n }, [status]);\n return /* @__PURE__ */ u3(\n \"button\",\n {\n class: className,\n type: \"button\",\n ...ariaLabel && status === \"idle\" ? { \"aria-label\": ariaLabel } : {},\n onClick: () => {\n navigator.clipboard.writeText(value).then(\n () => setStatus(\"copied\"),\n () => setStatus(\"failed\")\n );\n },\n children: status === \"copied\" ? \"Copied\" : status === \"failed\" ? \"Copy failed\" : label\n }\n );\n }\n\n // src/operator-ui/app/activity.tsx\n function ActivityRow({ event }) {\n const outcome = activityOutcomeClass(event.outcome);\n const stableId = actorStableId(event.actor);\n return /* @__PURE__ */ u3(\"article\", { class: `activity-item ${outcome}`, children: [\n /* @__PURE__ */ u3(\"div\", { class: \"activity-stamp\", children: [\n /* @__PURE__ */ u3(\"span\", { class: `dot ${outcome}`, \"aria-hidden\": \"true\" }),\n /* @__PURE__ */ u3(\"div\", { children: [\n /* @__PURE__ */ u3(\"time\", { class: \"activity-time\", dateTime: event.occurredAt, children: formatDate(event.occurredAt) }),\n /* @__PURE__ */ u3(\"div\", { class: \"activity-actor\", children: actorLabel(event.actor) }),\n stableId ? /* @__PURE__ */ u3(\"div\", { class: \"activity-actor-id mono\", children: stableId }) : null\n ] })\n ] }),\n /* @__PURE__ */ u3(\"div\", { children: [\n /* @__PURE__ */ u3(\"div\", { class: \"activity-address\", children: event.address }),\n /* @__PURE__ */ u3(\"div\", { class: \"activity-detail\", children: activityDetail(event) })\n ] }),\n /* @__PURE__ */ u3(\"div\", { children: [\n /* @__PURE__ */ u3(\"div\", { class: \"activity-outcome\", children: event.outcome }),\n /* @__PURE__ */ u3(\"div\", { class: \"activity-detail\", children: [\n event.durationMs,\n \" ms\"\n ] })\n ] })\n ] });\n }\n function ActivityPage({ state: state2 }) {\n const enabled = Boolean(state2.data?.activityEnabled);\n const loading = state2.activityPhase === \"loading\";\n const visible = filterActivity(state2.activityEvents, state2.activitySearch);\n return /* @__PURE__ */ u3(\"section\", { id: \"activityView\", children: /* @__PURE__ */ u3(\"div\", { class: \"lead\", children: [\n /* @__PURE__ */ u3(\"h1\", { id: \"activityHeading\", tabIndex: -1, children: \"Activity\" }),\n /* @__PURE__ */ u3(\"div\", { class: \"lead-copy\", children: [\n /* @__PURE__ */ u3(\"p\", { id: \"activitySummary\", children: activitySummary(state2.activityEvents) }),\n !enabled ? /* @__PURE__ */ u3(Unavailable, { children: [\n \"Activity history is not configured. Add an\",\n \" \",\n /* @__PURE__ */ u3(\"span\", { class: \"mono\", children: \"activity.store\" }),\n \" with a list reader to enable this page.\"\n ] }) : /* @__PURE__ */ u3(\"div\", { id: \"activityAvailable\", children: [\n /* @__PURE__ */ u3(\"div\", { class: \"row\", children: [\n /* @__PURE__ */ u3(\n \"input\",\n {\n id: \"activitySearch\",\n type: \"search\",\n placeholder: \"Search user, tool, or outcome…\",\n \"aria-label\": \"Search loaded activity\",\n value: state2.activitySearch,\n onInput: (event) => setActivitySearch(event.currentTarget.value)\n }\n ),\n /* @__PURE__ */ u3(\n \"button\",\n {\n id: \"refreshActivity\",\n class: \"btn\",\n type: \"button\",\n disabled: loading,\n onClick: () => void loadActivity(true),\n children: loading ? \"Loading…\" : \"Refresh\"\n }\n )\n ] }),\n /* @__PURE__ */ u3(NoticeLine, { id: \"activityNotice\", notice: state2.activityNotice }),\n /* @__PURE__ */ u3(\n \"div\",\n {\n id: \"activityList\",\n class: \"activity-list\",\n \"aria-busy\": loading ? \"true\" : \"false\",\n children: loading && state2.activityEvents.length === 0 ? /* @__PURE__ */ u3(\"div\", { class: \"activity-empty\", children: \"Loading activity…\" }) : state2.activityPhase === \"error\" && state2.activityEvents.length === 0 ? /* @__PURE__ */ u3(\"p\", { class: \"activity-empty\", children: /* @__PURE__ */ u3(\n \"button\",\n {\n class: \"btn\",\n type: \"button\",\n onClick: () => void loadActivity(true),\n children: \"Try loading activity again\"\n }\n ) }) : visible.length === 0 ? /* @__PURE__ */ u3(\"div\", { class: \"activity-empty\", children: state2.activitySearch.trim() ? \"No loaded activity matches this search.\" : \"No connector tool calls recorded yet.\" }) : visible.map((event, index) => /* @__PURE__ */ u3(\n ActivityRow,\n {\n event\n },\n `${event.occurredAt}-${event.address}-${index}`\n ))\n }\n ),\n state2.activityCursor ? /* @__PURE__ */ u3(\n \"button\",\n {\n id: \"moreActivity\",\n class: \"btn activity-more\",\n type: \"button\",\n disabled: loading,\n onClick: () => void loadActivity(false),\n children: loading ? \"Loading…\" : \"Load older\"\n }\n ) : null\n ] })\n ] })\n ] }) });\n }\n\n // src/operator-ui/app/artifacts.tsx\n function ArtifactRow({ row }) {\n return /* @__PURE__ */ u3(\"article\", { class: \"artifact-row\", children: [\n /* @__PURE__ */ u3(\"div\", { children: [\n /* @__PURE__ */ u3(\"a\", { class: \"artifact-title\", href: `/artifacts/${row.id}`, children: row.title }),\n /* @__PURE__ */ u3(\"div\", { class: \"artifact-meta\", children: [\n /* @__PURE__ */ u3(\"span\", { class: \"mono\", children: row.id }),\n \" · version \",\n row.viewVersion,\n \" · updated\",\n \" \",\n /* @__PURE__ */ u3(\"time\", { dateTime: row.updatedAt, children: formatDate(row.updatedAt) }),\n \" by \",\n row.updatedBy.label\n ] })\n ] }),\n /* @__PURE__ */ u3(\"div\", { class: \"artifact-badges\", children: [\n /* @__PURE__ */ u3(\"span\", { class: \"badge\", children: row.kind === \"markdown\" ? \"Markdown\" : \"HTML\" }),\n row.freshness?.state === \"stale\" ? /* @__PURE__ */ u3(\"span\", { class: \"badge warn\", children: \"Stale data\" }) : row.freshness?.state === \"current\" ? /* @__PURE__ */ u3(\"span\", { class: \"badge\", children: \"Current data\" }) : null,\n row.freshness?.last ? /* @__PURE__ */ u3(\"span\", { class: \"artifact-meta\", children: [\n \"Last refresh: \",\n row.freshness.last.status\n ] }) : null,\n row.archived ? /* @__PURE__ */ u3(\"span\", { class: \"badge warn\", children: \"Archived\" }) : null\n ] })\n ] });\n }\n function ArtifactsPage({ state: state2 }) {\n const loading = state2.artifactPhase === \"loading\";\n return /* @__PURE__ */ u3(\"section\", { id: \"artifactsView\", children: /* @__PURE__ */ u3(\"div\", { class: \"lead\", children: [\n /* @__PURE__ */ u3(\"h1\", { id: \"artifactsHeading\", tabIndex: -1, children: \"Artifacts\" }),\n /* @__PURE__ */ u3(\"div\", { class: \"lead-copy\", children: [\n /* @__PURE__ */ u3(\"p\", { children: \"Pages agents published for the team. Each one keeps every version.\" }),\n /* @__PURE__ */ u3(\n \"form\",\n {\n class: \"row\",\n onSubmit: (event) => {\n event.preventDefault();\n void loadArtifacts(true);\n },\n children: [\n /* @__PURE__ */ u3(\n \"input\",\n {\n id: \"artifactSearch\",\n type: \"search\",\n placeholder: \"Search titles…\",\n \"aria-label\": \"Search artifact titles\",\n value: state2.artifactQuery,\n onInput: (event) => setArtifactQuery(event.currentTarget.value)\n }\n ),\n /* @__PURE__ */ u3(\"button\", { id: \"searchArtifacts\", class: \"btn\", type: \"submit\", disabled: loading, children: \"Search\" }),\n /* @__PURE__ */ u3(\"label\", { class: \"artifact-meta\", children: [\n /* @__PURE__ */ u3(\n \"input\",\n {\n id: \"showArchived\",\n type: \"checkbox\",\n checked: state2.artifactArchived,\n onChange: (event) => setArtifactArchived(event.currentTarget.checked)\n }\n ),\n \" \",\n \"Show archived\"\n ] })\n ]\n }\n ),\n /* @__PURE__ */ u3(NoticeLine, { id: \"artifactNotice\", notice: state2.artifactNotice }),\n /* @__PURE__ */ u3(\"div\", { id: \"artifactList\", class: \"activity-list\", \"aria-busy\": loading ? \"true\" : \"false\", children: loading && state2.artifactRows.length === 0 ? /* @__PURE__ */ u3(\"div\", { class: \"activity-empty\", children: \"Loading artifacts…\" }) : state2.artifactRows.length === 0 ? /* @__PURE__ */ u3(\"div\", { class: \"activity-empty\", children: state2.artifactPhase === \"error\" ? \"No artifacts to show.\" : state2.artifactQuery.trim() ? \"No artifact title matches this search.\" : \"No artifacts yet. Ask an agent to publish one.\" }) : state2.artifactRows.map((row) => /* @__PURE__ */ u3(ArtifactRow, { row }, row.id)) }),\n state2.artifactCursor ? /* @__PURE__ */ u3(\n \"button\",\n {\n id: \"moreArtifacts\",\n class: \"btn activity-more\",\n type: \"button\",\n disabled: loading,\n onClick: () => void loadArtifacts(false),\n children: loading ? \"Loading…\" : \"Load more\"\n }\n ) : null\n ] })\n ] }) });\n }\n function ArtifactFrame({ view }) {\n const frame = A2(null);\n _2(() => {\n const element = frame.current;\n if (!element) return;\n const onMessage = (event) => {\n if (event.source !== element.contentWindow || event.origin !== \"null\") return;\n const data = event.data;\n if (!data || data.type !== \"ready\") return;\n window.removeEventListener(\"message\", onMessage);\n const policy = document.createElement(\"meta\");\n policy.httpEquiv = \"Content-Security-Policy\";\n policy.content = \"frame-src 'none'\";\n document.head.append(policy);\n element.contentWindow?.postMessage({ type: \"document\", html: view.document }, \"*\");\n };\n window.addEventListener(\"message\", onMessage);\n return () => window.removeEventListener(\"message\", onMessage);\n }, [view.document]);\n return /* @__PURE__ */ u3(\n \"iframe\",\n {\n ref: frame,\n id: \"artifactFrame\",\n class: \"artifact-frame\",\n title: view.title,\n sandbox: \"allow-scripts\",\n referrerpolicy: \"no-referrer\",\n src: \"/artifacts/_frame\"\n }\n );\n }\n function ArtifactPage({ state: state2 }) {\n const view = state2.artifactView;\n const [copied, setCopied] = d2(false);\n return /* @__PURE__ */ u3(\"section\", { id: \"artifactView\", children: [\n /* @__PURE__ */ u3(\"div\", { class: \"artifact-head\", children: [\n /* @__PURE__ */ u3(\"h1\", { id: \"artifactHeading\", tabIndex: -1, children: view?.title ?? \"Artifact\" }),\n view ? /* @__PURE__ */ u3(\"div\", { class: \"artifact-meta\", id: \"artifactMeta\", children: [\n view.snapshot ? \"Snapshot of \" : \"\",\n \"version \",\n view.view.version,\n view.snapshot && view.view.version !== view.latestViewVersion ? ` (latest is ${view.latestViewVersion})` : \"\",\n \" \",\n \"· updated \",\n /* @__PURE__ */ u3(\"time\", { dateTime: view.view.at, children: formatDate(view.view.at) }),\n \" by\",\n \" \",\n view.view.by.label,\n \" ·\",\n \" \",\n /* @__PURE__ */ u3(\"a\", { href: \"/artifacts\", children: \"All artifacts\" }),\n view.snapshot ? /* @__PURE__ */ u3(S, { children: [\n \" \",\n \"· \",\n /* @__PURE__ */ u3(\"a\", { href: view.url, children: \"Current version\" })\n ] }) : /* @__PURE__ */ u3(S, { children: [\n \" \",\n \"·\",\n \" \",\n /* @__PURE__ */ u3(\n \"button\",\n {\n id: \"copySnapshot\",\n class: \"navlink\",\n type: \"button\",\n onClick: () => {\n void navigator.clipboard?.writeText(view.snapshotUrl).then(\n () => setCopied(true),\n () => setCopied(false)\n );\n },\n children: copied ? \"Snapshot link copied\" : \"Copy snapshot link\"\n }\n )\n ] })\n ] }) : null,\n view?.archived ? /* @__PURE__ */ u3(\"div\", { id: \"archivedBanner\", class: \"artifact-banner\", role: \"status\", children: \"This artifact is archived. It keeps every version, and an agent can restore it.\" }) : null,\n !view?.snapshot && view?.freshness?.state === \"stale\" ? /* @__PURE__ */ u3(\"div\", { id: \"staleBanner\", class: \"artifact-banner\", role: \"status\", children: [\n \"Data may be out of date. The last refresh \",\n view.freshness.last?.status === \"failed\" ? \"failed\" : \"is overdue\",\n \"; the last good document is still shown.\"\n ] }) : null,\n /* @__PURE__ */ u3(NoticeLine, { id: \"artifactNotice\", notice: state2.artifactNotice })\n ] }),\n view ? /* @__PURE__ */ u3(ArtifactFrame, { view }, view.snapshotUrl) : null\n ] });\n }\n\n // src/operator-ui/app/credentials.tsx\n function CredentialForm({\n connector,\n credential,\n busy\n }) {\n const fields = credential.fields ?? [];\n const [values, setValues] = d2({});\n const single = fields.length === 0;\n const inputId = `credential-input-${connector}`;\n const submit = () => {\n if (single) {\n const value = (values.value ?? \"\").trim();\n if (!value) return refuseCredential(\"Paste a credential before saving.\");\n return void saveCredential(connector, { value });\n }\n const entries = {};\n for (const field of fields) {\n const value = (values[field.name] ?? \"\").trim();\n if (!value) {\n return refuseCredential(\n \"Complete every credential field before saving.\"\n );\n }\n entries[field.name] = value;\n }\n void saveCredential(connector, { values: entries });\n };\n return /* @__PURE__ */ u3(\"div\", { class: \"credential-form\", \"data-credential-form\": connector, children: [\n single ? /* @__PURE__ */ u3(S, { children: [\n /* @__PURE__ */ u3(\"label\", { class: \"visually-hidden\", for: inputId, children: credential.label }),\n /* @__PURE__ */ u3(\n \"input\",\n {\n id: inputId,\n type: \"password\",\n \"aria-label\": credential.label,\n placeholder: credential.placeholder || \"Paste credential\",\n autocomplete: \"new-password\",\n autocapitalize: \"none\",\n spellcheck: false,\n value: values.value ?? \"\",\n onInput: (event) => setValues({ value: event.currentTarget.value })\n }\n )\n ] }) : /* @__PURE__ */ u3(\"div\", { class: \"credential-fields\", children: fields.map((field, index) => {\n const id = `credential-input-${connector}-${index}`;\n return /* @__PURE__ */ u3(\"div\", { class: \"credential-field\", children: [\n /* @__PURE__ */ u3(\"label\", { for: id, children: field.label }),\n /* @__PURE__ */ u3(\n \"input\",\n {\n id,\n type: field.inputType || \"password\",\n placeholder: field.placeholder || field.label,\n autocomplete: (field.inputType ?? \"password\") === \"password\" ? \"new-password\" : \"off\",\n autocapitalize: \"none\",\n spellcheck: false,\n value: values[field.name] ?? \"\",\n onInput: (event) => setValues({\n ...values,\n [field.name]: event.currentTarget.value\n })\n }\n )\n ] }, field.name);\n }) }),\n /* @__PURE__ */ u3(\"div\", { class: \"actions\", children: [\n /* @__PURE__ */ u3(\"button\", { class: \"btn primary\", type: \"button\", disabled: busy, onClick: submit, children: busy ? \"Saving…\" : \"Save\" }),\n /* @__PURE__ */ u3(\n \"button\",\n {\n class: \"btn quiet\",\n type: \"button\",\n disabled: busy,\n onClick: () => editCredential(null),\n children: \"Cancel\"\n }\n )\n ] })\n ] });\n }\n function CredentialCard({\n connector,\n credential,\n editing,\n busy\n }) {\n const configured = Boolean(credential.configured);\n const removable = configured || Boolean(credential.removable);\n return /* @__PURE__ */ u3(\n \"section\",\n {\n class: \"subcard\",\n id: `credential-${connector.id}`,\n \"aria-labelledby\": `credential-title-${connector.id}`,\n children: [\n /* @__PURE__ */ u3(\"div\", { class: \"subcard-head\", children: [\n /* @__PURE__ */ u3(\"h3\", { id: `credential-title-${connector.id}`, children: credential.label }),\n /* @__PURE__ */ u3(\"span\", { class: \"meta\", children: credentialStateLabel(credential) })\n ] }),\n credential.description ? /* @__PURE__ */ u3(\"p\", { class: \"meta\", children: credential.description }) : null,\n credential.fields?.length ? /* @__PURE__ */ u3(\"div\", { class: \"credential-field-summary\", children: credential.fields.map((field) => /* @__PURE__ */ u3(\"div\", { children: [\n /* @__PURE__ */ u3(\"span\", { children: field.label }),\n /* @__PURE__ */ u3(\"span\", { class: \"meta\", children: field.configured ? `configured · ••••${field.lastFour ?? \"\"}${field.updatedAt ? ` · updated ${formatDate(field.updatedAt)}` : \"\"}` : \"not configured\" })\n ] }, field.name)) }) : null,\n credential.error ? /* @__PURE__ */ u3(\"div\", { class: \"msg\", children: credential.error }) : null,\n credential.error && credential.problem ? /* @__PURE__ */ u3(\n FixPrompt,\n {\n kind: credential.problem,\n connectorId: connector.id,\n name: connector.title || connector.id\n }\n ) : null,\n credential.notice ? /* @__PURE__ */ u3(\"p\", { class: \"meta\", children: credential.notice }) : null,\n /* @__PURE__ */ u3(\"div\", { class: \"actions\", children: [\n /* @__PURE__ */ u3(\n \"button\",\n {\n class: \"btn\",\n type: \"button\",\n disabled: busy,\n onClick: () => editCredential(editing ? null : connector.id),\n children: removable ? \"Replace\" : \"Add credential\"\n }\n ),\n configured && credential.testable ? /* @__PURE__ */ u3(\n \"button\",\n {\n class: \"btn\",\n type: \"button\",\n disabled: busy,\n onClick: () => void testCredential(connector.id),\n children: busy ? \"Working…\" : \"Test\"\n }\n ) : null,\n removable ? /* @__PURE__ */ u3(\n \"button\",\n {\n class: \"btn danger\",\n type: \"button\",\n disabled: busy,\n onClick: () => void removeCredential(connector.id),\n children: \"Remove\"\n }\n ) : null\n ] }),\n editing ? /* @__PURE__ */ u3(\n CredentialForm,\n {\n connector: connector.id,\n credential,\n busy\n }\n ) : null\n ]\n }\n );\n }\n\n // src/operator-ui/model.ts\n function filterUiConnectors(connectors, query) {\n const q2 = query.trim().toLowerCase();\n const filtered = [];\n for (const connector of connectors) {\n const connectorText = [\n connector.id,\n connector.title,\n connector.description,\n connector.status\n ].join(\" \").toLowerCase();\n const connectorMatches = Boolean(q2 && connectorText.includes(q2));\n const tools = connector.tools.filter(\n (tool) => !q2 || connectorMatches || `${tool.name} ${tool.description ?? \"\"}`.toLowerCase().includes(q2)\n );\n if (q2 && tools.length === 0 && !connectorMatches) continue;\n filtered.push({ connector, tools });\n }\n return filtered;\n }\n\n // src/operator-ui/setup-commands.ts\n function clientServerName(serverName, pool) {\n const base = (serverName ?? \"\").toLowerCase().replace(/[^a-z0-9_-]+/g, \"-\").replace(/-{2,}/g, \"-\").replace(/^-+|-+$/g, \"\").slice(0, 48) || \"connecta\";\n return pool ? `${base}-${pool}` : base;\n }\n function poolEndpointUrl(mcpUrl2, pool) {\n return `${mcpUrl2.replace(/\\/+$/, \"\")}/${encodeURIComponent(pool)}`;\n }\n function shellWord(value) {\n return /^[A-Za-z0-9_./:@%+=,~-]+$/.test(value) ? value : `'${value.replace(/'/g, `'\"'\"'`)}'`;\n }\n function clientSetupCommands(name, url) {\n return [\n {\n id: \"claude\",\n label: \"Claude Code\",\n text: `claude mcp add --transport http ${shellWord(name)} ${shellWord(url)}`\n },\n {\n id: \"codex\",\n label: \"Codex\",\n text: `codex mcp add ${shellWord(name)} --url ${shellWord(url)}`\n },\n {\n id: \"json\",\n label: \"JSON config\",\n text: JSON.stringify(\n { mcpServers: { [name]: { type: \"http\", url } } },\n null,\n 2\n )\n }\n ];\n }\n\n // src/operator-ui/app/connections.tsx\n var DRIFT_HEADING = {\n clean: \"Catalog drift · none\",\n warning: \"Catalog drift · review\",\n unavailable: \"Catalog drift · not observed\"\n };\n function DriftPanel({ connector }) {\n const drift = connector.catalogDrift;\n const state2 = driftState(drift);\n return /* @__PURE__ */ u3(S, { children: [\n /* @__PURE__ */ u3(\n \"div\",\n {\n id: `drift-${connector.id}`,\n class: `connector-drift ${state2}`,\n \"data-drift\": state2,\n children: [\n /* @__PURE__ */ u3(\"p\", { class: \"cap\", children: DRIFT_HEADING[state2] }),\n /* @__PURE__ */ u3(\"p\", { class: \"meta\", children: driftSummary(drift) }),\n state2 === \"unavailable\" ? null : /* @__PURE__ */ u3(\"ul\", { class: \"drift-counts\", children: driftCounts(drift).map(({ key, label, count }) => /* @__PURE__ */ u3(\"li\", { class: count > 0 ? \"drift-count flagged\" : \"drift-count\", children: [\n /* @__PURE__ */ u3(\"span\", { class: \"drift-count-value\", children: count }),\n /* @__PURE__ */ u3(\"span\", { class: \"drift-count-label\", children: label })\n ] }, key)) })\n ]\n }\n ),\n state2 === \"warning\" ? /* @__PURE__ */ u3(\n FixPrompt,\n {\n kind: \"catalog_drift\",\n connectorId: connector.id,\n name: connector.title || connector.id\n }\n ) : null\n ] });\n }\n function SafetyBadge({ safety }) {\n const badge = safety ? TOOL_SAFETY_BADGE[safety] : void 0;\n if (!badge) return null;\n return /* @__PURE__ */ u3(\"span\", { class: \"tool-safety\", title: badge.title, \"data-safety\": safety, children: /* @__PURE__ */ u3(Badge, { tone: badge.tone, children: badge.label }) });\n }\n function Endpoint({\n url,\n name,\n label,\n primary\n }) {\n return /* @__PURE__ */ u3(\"div\", { class: \"endpoint-block\", \"data-endpoint\": name, children: [\n /* @__PURE__ */ u3(\"div\", { class: \"endpoint\", children: [\n label ? /* @__PURE__ */ u3(\"span\", { class: \"endpoint-label cap\", children: label }) : null,\n /* @__PURE__ */ u3(\"code\", { ...primary ? { id: \"mcpUrl\" } : {}, class: \"mono\", children: url }),\n /* @__PURE__ */ u3(\n CopyButton,\n {\n value: url,\n label: \"Copy URL\",\n ...label ? { ariaLabel: `Copy URL for ${label}` } : {}\n }\n )\n ] }),\n /* @__PURE__ */ u3(\"details\", { class: \"setup\", children: [\n /* @__PURE__ */ u3(\"summary\", { class: \"disclosure\", children: [\n \"Client setup\",\n label ? ` · ${label}` : \"\"\n ] }),\n /* @__PURE__ */ u3(\"div\", { class: \"setup-list\", children: [\n clientSetupCommands(name, url).map((command) => /* @__PURE__ */ u3(\"div\", { class: \"setup-item\", \"data-setup\": command.id, children: [\n /* @__PURE__ */ u3(\"div\", { class: \"setup-head\", children: [\n /* @__PURE__ */ u3(\"span\", { class: \"cap\", children: command.label }),\n /* @__PURE__ */ u3(\n CopyButton,\n {\n value: command.text,\n label: \"Copy\",\n class: \"btn quiet\",\n ariaLabel: `Copy ${command.label} setup${label ? ` for ${label}` : \"\"}`\n }\n )\n ] }),\n /* @__PURE__ */ u3(\"pre\", { class: \"setup-code\", children: command.text })\n ] }, command.id)),\n /* @__PURE__ */ u3(\"p\", { class: \"meta\", children: \"No token is included. Clients sign in through this deployment's inbound auth.\" })\n ] })\n ] })\n ] });\n }\n function ConnectorRow({\n connector,\n tools,\n expanded,\n oauthManagement,\n busy,\n state: state2\n }) {\n const name = connector.title || connector.id;\n const authorization = safeHttpHref(connector.authorizationUrl);\n const drift = driftState(connector.catalogDrift);\n const problem = connector.status === \"loading\" ? null : problemCopy(connector.problem);\n return /* @__PURE__ */ u3(\"details\", { class: \"conn\", open: expanded, children: [\n /* @__PURE__ */ u3(\"summary\", { class: \"conn-head\", children: [\n /* @__PURE__ */ u3(\"span\", { class: \"conn-main\", children: [\n /* @__PURE__ */ u3(\"span\", { class: `dot ${connector.status}`, \"aria-hidden\": \"true\" }),\n /* @__PURE__ */ u3(\"h2\", { class: \"conn-name\", children: name }),\n connector.title ? /* @__PURE__ */ u3(\"span\", { class: \"conn-id mono\", children: connector.id }) : null\n ] }),\n /* @__PURE__ */ u3(\"span\", { class: \"conn-badges\", children: [\n drift === \"warning\" ? /* @__PURE__ */ u3(Badge, { tone: \"warn\", children: \"drift\" }) : null,\n /* @__PURE__ */ u3(Badge, { children: authScopeLabel(connector.authScope) }),\n /* @__PURE__ */ u3(Badge, { children: connector.status === \"loading\" ? \"tools not loaded\" : toolCountLabel(connector.toolCount) }),\n /* @__PURE__ */ u3(Badge, { tone: connectorStatusTone(connector.status), children: connectorStatusLabel(connector.status) }),\n /* @__PURE__ */ u3(\"span\", { class: \"conn-caret\", \"aria-hidden\": \"true\" })\n ] })\n ] }),\n /* @__PURE__ */ u3(\"div\", { class: \"conn-body\", children: [\n connector.description ? /* @__PURE__ */ u3(\"p\", { class: \"conn-note\", children: connector.description }) : null,\n problem ? /* @__PURE__ */ u3(\"p\", { class: \"msg\", \"data-problem\": connector.problem, children: problem }) : null,\n problem && connector.problem && connector.problem !== connector.credential?.problem ? /* @__PURE__ */ u3(FixPrompt, { kind: connector.problem, connectorId: connector.id, name }) : null,\n connector.authorizationUrl && !authorization ? /* @__PURE__ */ u3(\"p\", { class: \"meta\", children: [\n \"Authorization URL: \",\n connector.authorizationUrl\n ] }) : null,\n /* @__PURE__ */ u3(\"p\", { class: \"meta\", children: permissionLabel(connector) }),\n /* @__PURE__ */ u3(\"div\", { class: \"actions\", children: [\n authorization ? /* @__PURE__ */ u3(\"a\", { class: \"btn primary\", href: authorization, target: \"_blank\", rel: \"noopener\", children: \"Authorize connector\" }) : null,\n connector.oauth && oauthManagement ? /* @__PURE__ */ u3(S, { children: [\n /* @__PURE__ */ u3(\n \"button\",\n {\n type: \"button\",\n class: \"btn\",\n \"aria-label\": `${connector.status === \"ok\" ? \"Reconnect OAuth for\" : \"Restart authorization for\"} ${name}`,\n disabled: busy,\n onClick: () => void oauthAction(connector.id, \"reconnect\"),\n children: connector.status === \"ok\" ? \"Reconnect OAuth\" : \"Connect account\"\n }\n ),\n connector.status === \"ok\" ? /* @__PURE__ */ u3(\n \"button\",\n {\n type: \"button\",\n class: \"btn danger\",\n \"aria-label\": `Disconnect OAuth for ${name}`,\n disabled: busy,\n onClick: () => void oauthAction(connector.id, \"disconnect\"),\n children: \"Disconnect OAuth\"\n }\n ) : null\n ] }) : null,\n /* @__PURE__ */ u3(\n \"button\",\n {\n class: \"btn quiet\",\n type: \"button\",\n \"aria-label\": `Refresh ${name}`,\n disabled: connector.status === \"loading\",\n onClick: () => void refreshConnector(connector.id),\n children: \"Refresh\"\n }\n )\n ] }),\n connector.credential ? /* @__PURE__ */ u3(\n CredentialCard,\n {\n connector,\n credential: connector.credential,\n editing: state2.credentialEditing === connector.id,\n busy: state2.credentialBusy === connector.id\n }\n ) : null,\n tools.length ? /* @__PURE__ */ u3(\"details\", { open: expanded, children: [\n /* @__PURE__ */ u3(\"summary\", { class: \"disclosure\", children: [\n \"Tools (\",\n tools.length,\n \")\"\n ] }),\n /* @__PURE__ */ u3(\"div\", { class: \"tool-list\", children: [\n tools.some((tool) => tool.safety) ? /* @__PURE__ */ u3(\"p\", { class: \"meta tool-legend\", children: \"Read-only tools run inside execute_code programs. Everything else asks the host first: a program pauses for resume_execution, and a direct call goes through call_destructive_tool — unless this deployment's config exempts the tool, in which case programs call it unasked.\" }) : null,\n tools.map((tool) => /* @__PURE__ */ u3(\"div\", { class: \"tool\", children: [\n /* @__PURE__ */ u3(\"div\", { class: \"tool-head\", children: [\n /* @__PURE__ */ u3(\"code\", { children: tool.address }),\n /* @__PURE__ */ u3(SafetyBadge, { safety: tool.safety })\n ] }),\n tool.description ? /* @__PURE__ */ u3(\"span\", { class: \"td\", children: tool.description }) : null\n ] }, tool.address))\n ] })\n ] }) : null,\n /* @__PURE__ */ u3(\"details\", { children: [\n /* @__PURE__ */ u3(\"summary\", { class: \"disclosure\", children: \"Diagnostics\" }),\n /* @__PURE__ */ u3(\"div\", { class: \"subcard\", children: [\n /* @__PURE__ */ u3(DriftPanel, { connector }),\n connector.catalogAccess ? /* @__PURE__ */ u3(\"p\", { class: \"meta\", children: [\n \"Last agent catalog read · \",\n connector.catalogAccess.state,\n \" ·\",\n \" \",\n formatDate(connector.catalogAccess.observedAt)\n ] }) : null\n ] })\n ] })\n ] })\n ] });\n }\n function Endpoints({\n pools,\n serverName\n }) {\n return /* @__PURE__ */ u3(\"div\", { class: \"endpoints\", children: [\n /* @__PURE__ */ u3(\n Endpoint,\n {\n url: mcpUrl,\n name: clientServerName(serverName),\n primary: true,\n ...pools.length ? { label: \"All tools\" } : {}\n }\n ),\n pools.map((pool) => /* @__PURE__ */ u3(\n Endpoint,\n {\n url: poolEndpointUrl(mcpUrl, pool),\n name: clientServerName(serverName, pool),\n label: `Pool · ${pool}`\n },\n pool\n ))\n ] });\n }\n function SummaryLine({ connectors }) {\n const parts = connectorSummaryParts(summarizeConnectors(connectors));\n return /* @__PURE__ */ u3(\"p\", { class: \"summary\", id: \"connectorSummary\", children: parts.map((part, index) => /* @__PURE__ */ u3(\"span\", { children: [\n index > 0 ? /* @__PURE__ */ u3(\"span\", { class: \"sep\", children: \" · \" }) : null,\n /* @__PURE__ */ u3(\"span\", { class: part.tone === \"neutral\" ? \"\" : part.tone, children: part.text })\n ] }, part.text)) });\n }\n function ConnectionsPage({ state: state2 }) {\n const data = state2.data;\n const query = state2.connectorFilter.trim();\n const filtered = data ? filterUiConnectors(data.connectors, query) : [];\n return /* @__PURE__ */ u3(\"section\", { id: \"connectionsView\", children: [\n /* @__PURE__ */ u3(\"div\", { class: \"lead\", children: [\n /* @__PURE__ */ u3(\"h1\", { id: \"connectionsHeading\", tabIndex: -1, children: \"Connections\" }),\n /* @__PURE__ */ u3(\"div\", { class: \"lead-copy\", children: [\n /* @__PURE__ */ u3(\"p\", { children: \"Point an MCP client at this endpoint to reach the tools below.\" }),\n /* @__PURE__ */ u3(Endpoints, { pools: data?.pools ?? [], serverName: data?.serverInfo?.name }),\n /* @__PURE__ */ u3(\"p\", { class: \"cap\", id: \"serverInfo\", children: data ? `${data.serverInfo?.name || productName} v${data.connectaVersion || \"?\"}` : productOperatorLabel }),\n data ? /* @__PURE__ */ u3(SummaryLine, { connectors: data.connectors }) : null,\n /* @__PURE__ */ u3(NoticeLine, { id: \"oauthNotice\", notice: state2.oauthNotice }),\n /* @__PURE__ */ u3(NoticeLine, { id: \"credentialNotice\", notice: state2.credentialNotice })\n ] })\n ] }),\n /* @__PURE__ */ u3(\"section\", { class: \"section\", \"aria-labelledby\": \"connectorLedgerHeading\", children: [\n /* @__PURE__ */ u3(\"div\", { class: \"section-head\", children: [\n /* @__PURE__ */ u3(\"h2\", { id: \"connectorLedgerHeading\", children: \"Connectors\" }),\n /* @__PURE__ */ u3(\n \"input\",\n {\n id: \"filter\",\n type: \"search\",\n class: \"filter\",\n placeholder: \"Filter connectors or tools…\",\n \"aria-label\": \"Filter connectors or tools\",\n value: state2.connectorFilter,\n onInput: (event) => setConnectorFilter(event.currentTarget.value)\n }\n )\n ] }),\n /* @__PURE__ */ u3(\n \"div\",\n {\n id: \"list\",\n class: !data || filtered.length === 0 ? \"\" : \"rows\",\n \"aria-busy\": state2.refreshing || !data ? \"true\" : \"false\",\n children: !data ? /* @__PURE__ */ u3(Empty, { children: \"Loading connectors…\" }) : filtered.length === 0 ? /* @__PURE__ */ u3(Empty, { children: query ? \"No connectors or tools match this filter.\" : \"No connectors are declared in this deployment.\" }) : filtered.map(({ connector, tools }) => /* @__PURE__ */ u3(\n ConnectorRow,\n {\n connector,\n tools,\n expanded: Boolean(query),\n oauthManagement: Boolean(\n connector.permissions?.manageSharedAuth || connector.permissions?.connectPersonal\n ),\n state: state2,\n busy: state2.oauthBusy === connector.id\n },\n connector.id\n ))\n }\n )\n ] })\n ] });\n }\n\n // src/operator-ui/app/main.tsx\n function useOperatorState() {\n const [, bump] = y2((count) => count + 1, 0);\n const snapshot = getState();\n _2(() => {\n const unsubscribe = subscribe(() => bump(void 0));\n if (getState() !== snapshot) bump(void 0);\n return unsubscribe;\n }, []);\n return snapshot;\n }\n function visiblePages(state2) {\n if (isArtifactPage(state2.page)) return [\"connections\", \"artifacts\"];\n return OPERATOR_PAGES.filter((page) => {\n if (page === \"activity\") return Boolean(state2.data?.activityEnabled);\n if (page === \"artifacts\") return Boolean(state2.data?.artifactsEnabled);\n return true;\n });\n }\n function OperatorNav() {\n const state2 = useOperatorState();\n if (state2.session !== \"ready\") return null;\n const onArtifactPage = isArtifactPage(state2.page);\n return /* @__PURE__ */ u3(\"div\", { class: \"mast-actions\", children: [\n /* @__PURE__ */ u3(\"nav\", { class: \"page-nav\", \"aria-label\": \"Operator pages\", children: visiblePages(state2).map(\n (page) => (\n // Crossing between artifact pages and the rest is a full navigation:\n // with a dedicated artifact origin, the two live on different hosts.\n page === \"artifacts\" || onArtifactPage && page === \"connections\" ? /* @__PURE__ */ u3(\n \"a\",\n {\n class: \"navlink\",\n href: page === \"artifacts\" ? PAGE_META.artifacts.path : homeUrl,\n ...state2.page === page ? { \"aria-current\": \"page\" } : {},\n children: PAGE_META[page].label\n },\n page\n ) : /* @__PURE__ */ u3(\n PageLink,\n {\n page,\n class: \"navlink\",\n current: state2.page === page,\n children: PAGE_META[page].label\n },\n page\n )\n )\n ) }),\n /* @__PURE__ */ u3(\"div\", { class: \"session-actions\", \"aria-label\": \"Session actions\", children: auth.kind === \"clerk\" || auth.kind === \"cloudflare-access\" ? /* @__PURE__ */ u3(\"button\", { class: \"navlink\", type: \"button\", onClick: signOut, children: \"Sign out\" }) : /* @__PURE__ */ u3(\"button\", { class: \"navlink\", type: \"button\", onClick: forgetBearer, children: \"Change token\" }) })\n ] });\n }\n function Gate({ state: state2 }) {\n const [token, setToken] = d2(\"\");\n const signedIn = auth.kind === \"clerk\" && Boolean(window.Clerk?.user);\n const loading = state2.session === \"loading\";\n return /* @__PURE__ */ u3(\"section\", { id: \"gate\", class: \"gate\", children: /* @__PURE__ */ u3(\"div\", { children: [\n /* @__PURE__ */ u3(\"h1\", { id: \"gateHeading\", tabIndex: -1, children: PAGE_META[state2.page].label }),\n /* @__PURE__ */ u3(\"div\", { class: \"lead-copy\", children: [\n /* @__PURE__ */ u3(\"p\", { children: productDescription }),\n /* @__PURE__ */ u3(\"p\", { id: \"gateCopy\", class: \"meta\", children: loading ? \"Checking your session…\" : gateCopy(auth.kind, signedIn) }),\n loading ? null : auth.kind === \"clerk\" ? /* @__PURE__ */ u3(\"div\", { id: \"clerkGate\", class: \"actions\", children: signedIn ? /* @__PURE__ */ u3(\"button\", { class: \"btn\", type: \"button\", onClick: signOut, children: \"Sign out\" }) : /* @__PURE__ */ u3(\"button\", { id: \"signin\", class: \"btn primary\", type: \"button\", onClick: signIn, children: \"Team sign in\" }) }) : auth.kind === \"cloudflare-access\" ? /* @__PURE__ */ u3(\"div\", { class: \"actions\", children: /* @__PURE__ */ u3(\"button\", { class: \"btn\", type: \"button\", onClick: signOut, children: \"Sign out of Cloudflare Access\" }) }) : /* @__PURE__ */ u3(\n \"form\",\n {\n id: \"tokenGate\",\n class: \"row\",\n onSubmit: (event) => {\n event.preventDefault();\n const value = token.trim();\n if (!value) return;\n setToken(\"\");\n signInWithBearer(value);\n },\n children: [\n /* @__PURE__ */ u3(\n \"input\",\n {\n id: \"token\",\n type: \"password\",\n placeholder: \"Bearer token\",\n autocomplete: \"off\",\n \"aria-label\": \"Bearer token\",\n value: token,\n onInput: (event) => setToken(event.currentTarget.value)\n }\n ),\n /* @__PURE__ */ u3(\"button\", { id: \"save\", class: \"btn primary\", type: \"submit\", children: \"Open operator pages\" })\n ]\n }\n ),\n /* @__PURE__ */ u3(NoticeLine, { id: \"err\", notice: state2.gate, className: \"\" })\n ] })\n ] }) });\n }\n function CurrentPage({ state: state2 }) {\n if (state2.page === \"activity\") return /* @__PURE__ */ u3(ActivityPage, { state: state2 });\n if (state2.page === \"artifacts\") return /* @__PURE__ */ u3(ArtifactsPage, { state: state2 });\n if (state2.page === \"artifact\") return /* @__PURE__ */ u3(ArtifactPage, { state: state2 });\n return /* @__PURE__ */ u3(ConnectionsPage, { state: state2 });\n }\n function OperatorApp() {\n const state2 = useOperatorState();\n const ready = state2.session === \"ready\";\n h2(() => {\n const label = state2.page === \"artifact\" && state2.artifactView ? state2.artifactView.title : PAGE_META[state2.page].label;\n document.title = `${label} — ${titleSuffix}`;\n }, [state2.page, state2.artifactView]);\n h2(() => {\n if (!ready) return;\n if (state2.page === \"activity\" && state2.data?.activityEnabled && state2.activityPhase === \"idle\") {\n void loadActivity(true);\n }\n });\n h2(() => {\n if (!state2.pendingFocus) return;\n document.getElementById(state2.pendingFocus)?.focus();\n focusHandled();\n }, [state2.pendingFocus]);\n return ready ? /* @__PURE__ */ u3(\"div\", { id: \"app\", children: /* @__PURE__ */ u3(CurrentPage, { state: state2 }) }) : /* @__PURE__ */ u3(Gate, { state: state2 });\n }\n function mount(id, view) {\n const host = document.getElementById(id);\n if (!host) return;\n host.textContent = \"\";\n R(view, host);\n }\n mount(\"operatorNav\", /* @__PURE__ */ u3(OperatorNav, {}));\n mount(\"operatorContent\", /* @__PURE__ */ u3(OperatorApp, {}));\n void boot();\n})();\n";