From 0e7e4c460200df0a510ad4be41d07b6b85310aa7 Mon Sep 17 00:00:00 2001 From: Harsh-2002 Date: Tue, 11 Aug 2026 07:41:45 +0000 Subject: [PATCH 1/9] feat(ui): declutter dashboard experience Entire-Checkpoint: 01KZQWAC2WE6W36TGP6FPWREM4 --- .impeccable/design.json | 23 +- DESIGN.md | 10 +- PRODUCT.md | 144 +- .../assets/{AI-DiZy-u0r.js => AI-Cybev_nu.js} | 16 +- .../ui_dist/assets/Activity-DsyXryTa.js | 1 + .../ui_dist/assets/Activity-y79g4hAI.js | 1 - .../server/ui_dist/assets/ApiKeys-CH-rpjHf.js | 3 + .../server/ui_dist/assets/ApiKeys-D9lr2hws.js | 3 - .../ui_dist/assets/Channels-ferFGY3i.js | 1 - .../ui_dist/assets/Channels-t_NzfnaS.js | 1 + ...tor-CN_QDpaG.js => CodeEditor-809P47Oq.js} | 2 +- .../ui_dist/assets/CronJobs-BnI-WDdi.js | 1 - .../ui_dist/assets/CronJobs-ChQ_JvvX.js | 1 + .../ui_dist/assets/Dashboard-Bgrzu27X.js | 1 - .../ui_dist/assets/Dashboard-By9Lh_hZ.js | 1 + .../ui_dist/assets/Deployments-9vU6Tb3I.js | 3 + .../ui_dist/assets/Deployments-CrxzN_jC.js | 3 - .../server/ui_dist/assets/Docs-BCHpDwKo.js | 345 +++++ .../server/ui_dist/assets/Docs-D8AUJ3IN.css | 1 + .../server/ui_dist/assets/Docs-r0iOi4Nz.css | 1 - .../server/ui_dist/assets/Docs-u_E_xl53.js | 345 ----- .../server/ui_dist/assets/Drawer-B765_4al.js | 1 + .../server/ui_dist/assets/Drawer-CNvPia4g.js | 1 - ...ditor-DQHCrIvv.css => Editor-4XWCDeWw.css} | 2 +- .../server/ui_dist/assets/Editor-B2TUmRPR.js | 1288 ----------------- .../server/ui_dist/assets/Editor-CbMNvtam.js | 1288 +++++++++++++++++ .../ui_dist/assets/Firewall-CWigGJD2.js | 1 + .../ui_dist/assets/Firewall-D8okbrYC.js | 1 - .../ui_dist/assets/FunctionDiff-CnlgD6wU.js | 4 + .../ui_dist/assets/FunctionDiff-Dq0bsN-d.js | 4 - .../ui_dist/assets/FunctionsList-R11R2PMj.js | 3 + .../ui_dist/assets/FunctionsList-nhvM1KMG.js | 3 - .../ui_dist/assets/IconButton-CsCZOqWo.js | 1 + .../ui_dist/assets/IconButton-D_Xb_fPi.js | 1 - .../assets/InboundWebhooks-BglNrTdR.js | 5 - .../assets/InboundWebhooks-BhEZqJC3.js | 5 + .../server/ui_dist/assets/Input-DQ-tWGkn.js | 1 + .../server/ui_dist/assets/Input-nRG7dQt5.js | 1 - .../ui_dist/assets/InvocationsLog-Ce4G6Njr.js | 5 + .../ui_dist/assets/InvocationsLog-DnGTym7X.js | 5 - .../server/ui_dist/assets/Jobs-C6T-JAqx.js | 1 - .../server/ui_dist/assets/Jobs-DELgTRde.js | 1 + .../server/ui_dist/assets/KVStore-7m72c5r7.js | 1 - .../server/ui_dist/assets/KVStore-MeqbHaJs.js | 1 + .../server/ui_dist/assets/Login-CWq5MQUC.js | 1 - .../server/ui_dist/assets/Login-C_NJU1-B.js | 1 + .../server/ui_dist/assets/Modal-CMnodc09.js | 1 - .../server/ui_dist/assets/Modal-D_xvZeX4.js | 1 + .../ui_dist/assets/NotFound-B3ut6oLt.js | 1 + .../ui_dist/assets/NotFound-u0Ev7ZJ6.js | 1 - .../ui_dist/assets/Onboarding-DUKp_NyK.js | 1 + .../ui_dist/assets/Onboarding-vj_RsDaZ.js | 6 - .../ui_dist/assets/Settings-C0uzogSk.js | 1 + .../ui_dist/assets/Settings-DTuAFL6Q.js | 1 - .../ui_dist/assets/StatusBadge-C3Y8qWdJ.js | 1 - .../ui_dist/assets/StatusBadge-D05dwaq1.js | 1 + .../ui_dist/assets/TraceDetail-CoA5z0nR.js | 1 - .../ui_dist/assets/TraceDetail-DzcELCx5.js | 1 + .../server/ui_dist/assets/Traces-BayDqxAR.js | 1 - .../server/ui_dist/assets/Traces-CgKCmNF_.js | 1 + .../ui_dist/assets/Webhooks-C4OH8SRp.js | 1 + .../ui_dist/assets/Webhooks-yV8Wn4W0.js | 1 - .../assets/{ai-D_iG5rtR.js => ai-DUD_7kL7.js} | 2 +- ...eft-R70wE3H8.js => arrow-left-BufM35P4.js} | 2 +- ...open-DOYPDtOR.js => book-open-Ds3lxPlK.js} | 2 +- .../server/ui_dist/assets/check-ho22bAKW.js | 1 + .../server/ui_dist/assets/check-lEJPUgfZ.js | 1 - .../ui_dist/assets/chevron-down-D3BE3JWH.js | 1 - .../ui_dist/assets/chevron-right-BNHZGbeL.js | 1 + .../ui_dist/assets/chevron-right-Cee8Bzpp.js | 1 - ...{circle-CNJP_P8E.js => circle-BHcDUsj0.js} | 2 +- ...t-BNFtIIyP.js => circle-alert-Buaacgot.js} | 2 +- .../{clock-CYEi9Knb.js => clock-Dx_vxhwd.js} | 2 +- .../{copy-5veW7U_F.js => copy-DHTw5vil.js} | 2 +- .../{flag-CSXzs-fq.js => flag-BApEgnYF.js} | 2 +- ...re-DoufYPrI.js => git-compare-CRDCiUNE.js} | 2 +- .../{globe-L6h6bFKN.js => globe-D4_vTA7d.js} | 2 +- .../server/ui_dist/assets/index-B93KhQc5.js | 2 - .../server/ui_dist/assets/index-C5tWn-5z.css | 1 + .../server/ui_dist/assets/index-CZI-jurg.js | 2 + .../server/ui_dist/assets/index-DjfRwYQD.css | 1 - ...ound-CJGTpWKA.js => key-round-7iKBY7s0.js} | 2 +- .../{lock-Clh4EWdA.js => lock-DzLYLVcq.js} | 2 +- ...{pencil-DemHUXoL.js => pencil-CSU4z7ce.js} | 2 +- .../server/ui_dist/assets/pinia-B41TZNUX.js | 1 + .../server/ui_dist/assets/pinia-D7gh0q31.js | 1 - .../{play-BBWx7r99.js => play-7LGcVtH4.js} | 2 +- ...-cw-BiUNRBGx.js => refresh-cw-DihaytVM.js} | 2 +- ...ccw-B9grc64w.js => rotate-ccw-DWDBjUXf.js} | 2 +- .../runtime-core.esm-bundler-BMQPyJ_W.js | 1 + .../runtime-core.esm-bundler-DWJwptQ-.js | 1 - ...s-2-DyBZntFB.js => settings-2-D6woyAob.js} | 2 +- ...k-DU6_qnwV.js => shield-check-BhZjagef.js} | 2 +- ...rkles-yO26ZD4G.js => sparkles-BJpg1z9b.js} | 2 +- ...pen-W_aBk2wR.js => square-pen-BaygMdb7.js} | 2 +- ...minal-DBfAxzMM.js => terminal-D2TUj2P6.js} | 2 +- ...rash-2-BlIjHjqi.js => trash-2-DDX094Y-.js} | 2 +- ...iable-CmAS7ZoV.js => variable-JBU1Bvu7.js} | 2 +- .../{zap-C_6MZAJC.js => zap-Bv0F6KCG.js} | 2 +- backend/internal/server/ui_dist/index.html | 8 +- .../src/components/ai/AISettingsPanel.vue | 135 +- frontend/src/components/ai/EmptyState.vue | 12 +- .../channels/FunctionPickerModal.vue | 6 +- frontend/src/components/common/Button.vue | 6 +- frontend/src/components/common/EditorCard.vue | 4 +- frontend/src/components/common/IconButton.vue | 10 +- frontend/src/components/common/Input.vue | 28 +- frontend/src/components/layout/Sidebar.vue | 170 ++- frontend/src/style.css | 25 +- frontend/src/views/AI.vue | 2 +- frontend/src/views/Activity.vue | 9 +- frontend/src/views/ApiKeys.vue | 29 +- frontend/src/views/Channels.vue | 24 +- frontend/src/views/CronJobs.vue | 8 +- frontend/src/views/Dashboard.vue | 190 ++- frontend/src/views/Deployments.vue | 31 +- frontend/src/views/Docs.vue | 110 +- frontend/src/views/Editor.vue | 7 + frontend/src/views/Firewall.vue | 128 +- frontend/src/views/FunctionDiff.vue | 14 +- frontend/src/views/FunctionsList.vue | 7 +- frontend/src/views/InboundWebhooks.vue | 16 +- frontend/src/views/InvocationsLog.vue | 7 +- frontend/src/views/Jobs.vue | 12 +- frontend/src/views/KVStore.vue | 10 +- frontend/src/views/Login.vue | 17 +- frontend/src/views/NotFound.vue | 11 +- frontend/src/views/Onboarding.vue | 38 +- frontend/src/views/Settings.vue | 203 ++- frontend/src/views/TraceDetail.vue | 4 +- frontend/src/views/Traces.vue | 8 +- frontend/src/views/Webhooks.vue | 32 +- 132 files changed, 2495 insertions(+), 2443 deletions(-) rename backend/internal/server/ui_dist/assets/{AI-DiZy-u0r.js => AI-Cybev_nu.js} (55%) create mode 100644 backend/internal/server/ui_dist/assets/Activity-DsyXryTa.js delete mode 100644 backend/internal/server/ui_dist/assets/Activity-y79g4hAI.js create mode 100644 backend/internal/server/ui_dist/assets/ApiKeys-CH-rpjHf.js delete mode 100644 backend/internal/server/ui_dist/assets/ApiKeys-D9lr2hws.js delete mode 100644 backend/internal/server/ui_dist/assets/Channels-ferFGY3i.js create mode 100644 backend/internal/server/ui_dist/assets/Channels-t_NzfnaS.js rename backend/internal/server/ui_dist/assets/{CodeEditor-CN_QDpaG.js => CodeEditor-809P47Oq.js} (66%) delete mode 100644 backend/internal/server/ui_dist/assets/CronJobs-BnI-WDdi.js create mode 100644 backend/internal/server/ui_dist/assets/CronJobs-ChQ_JvvX.js delete mode 100644 backend/internal/server/ui_dist/assets/Dashboard-Bgrzu27X.js create mode 100644 backend/internal/server/ui_dist/assets/Dashboard-By9Lh_hZ.js create mode 100644 backend/internal/server/ui_dist/assets/Deployments-9vU6Tb3I.js delete mode 100644 backend/internal/server/ui_dist/assets/Deployments-CrxzN_jC.js create mode 100644 backend/internal/server/ui_dist/assets/Docs-BCHpDwKo.js create mode 100644 backend/internal/server/ui_dist/assets/Docs-D8AUJ3IN.css delete mode 100644 backend/internal/server/ui_dist/assets/Docs-r0iOi4Nz.css delete mode 100644 backend/internal/server/ui_dist/assets/Docs-u_E_xl53.js create mode 100644 backend/internal/server/ui_dist/assets/Drawer-B765_4al.js delete mode 100644 backend/internal/server/ui_dist/assets/Drawer-CNvPia4g.js rename backend/internal/server/ui_dist/assets/{Editor-DQHCrIvv.css => Editor-4XWCDeWw.css} (54%) delete mode 100644 backend/internal/server/ui_dist/assets/Editor-B2TUmRPR.js create mode 100644 backend/internal/server/ui_dist/assets/Editor-CbMNvtam.js create mode 100644 backend/internal/server/ui_dist/assets/Firewall-CWigGJD2.js delete mode 100644 backend/internal/server/ui_dist/assets/Firewall-D8okbrYC.js create mode 100644 backend/internal/server/ui_dist/assets/FunctionDiff-CnlgD6wU.js delete mode 100644 backend/internal/server/ui_dist/assets/FunctionDiff-Dq0bsN-d.js create mode 100644 backend/internal/server/ui_dist/assets/FunctionsList-R11R2PMj.js delete mode 100644 backend/internal/server/ui_dist/assets/FunctionsList-nhvM1KMG.js create mode 100644 backend/internal/server/ui_dist/assets/IconButton-CsCZOqWo.js delete mode 100644 backend/internal/server/ui_dist/assets/IconButton-D_Xb_fPi.js delete mode 100644 backend/internal/server/ui_dist/assets/InboundWebhooks-BglNrTdR.js create mode 100644 backend/internal/server/ui_dist/assets/InboundWebhooks-BhEZqJC3.js create mode 100644 backend/internal/server/ui_dist/assets/Input-DQ-tWGkn.js delete mode 100644 backend/internal/server/ui_dist/assets/Input-nRG7dQt5.js create mode 100644 backend/internal/server/ui_dist/assets/InvocationsLog-Ce4G6Njr.js delete mode 100644 backend/internal/server/ui_dist/assets/InvocationsLog-DnGTym7X.js delete mode 100644 backend/internal/server/ui_dist/assets/Jobs-C6T-JAqx.js create mode 100644 backend/internal/server/ui_dist/assets/Jobs-DELgTRde.js delete mode 100644 backend/internal/server/ui_dist/assets/KVStore-7m72c5r7.js create mode 100644 backend/internal/server/ui_dist/assets/KVStore-MeqbHaJs.js delete mode 100644 backend/internal/server/ui_dist/assets/Login-CWq5MQUC.js create mode 100644 backend/internal/server/ui_dist/assets/Login-C_NJU1-B.js delete mode 100644 backend/internal/server/ui_dist/assets/Modal-CMnodc09.js create mode 100644 backend/internal/server/ui_dist/assets/Modal-D_xvZeX4.js create mode 100644 backend/internal/server/ui_dist/assets/NotFound-B3ut6oLt.js delete mode 100644 backend/internal/server/ui_dist/assets/NotFound-u0Ev7ZJ6.js create mode 100644 backend/internal/server/ui_dist/assets/Onboarding-DUKp_NyK.js delete mode 100644 backend/internal/server/ui_dist/assets/Onboarding-vj_RsDaZ.js create mode 100644 backend/internal/server/ui_dist/assets/Settings-C0uzogSk.js delete mode 100644 backend/internal/server/ui_dist/assets/Settings-DTuAFL6Q.js delete mode 100644 backend/internal/server/ui_dist/assets/StatusBadge-C3Y8qWdJ.js create mode 100644 backend/internal/server/ui_dist/assets/StatusBadge-D05dwaq1.js delete mode 100644 backend/internal/server/ui_dist/assets/TraceDetail-CoA5z0nR.js create mode 100644 backend/internal/server/ui_dist/assets/TraceDetail-DzcELCx5.js delete mode 100644 backend/internal/server/ui_dist/assets/Traces-BayDqxAR.js create mode 100644 backend/internal/server/ui_dist/assets/Traces-CgKCmNF_.js create mode 100644 backend/internal/server/ui_dist/assets/Webhooks-C4OH8SRp.js delete mode 100644 backend/internal/server/ui_dist/assets/Webhooks-yV8Wn4W0.js rename backend/internal/server/ui_dist/assets/{ai-D_iG5rtR.js => ai-DUD_7kL7.js} (98%) rename backend/internal/server/ui_dist/assets/{arrow-left-R70wE3H8.js => arrow-left-BufM35P4.js} (58%) rename backend/internal/server/ui_dist/assets/{book-open-DOYPDtOR.js => book-open-Ds3lxPlK.js} (77%) create mode 100644 backend/internal/server/ui_dist/assets/check-ho22bAKW.js delete mode 100644 backend/internal/server/ui_dist/assets/check-lEJPUgfZ.js delete mode 100644 backend/internal/server/ui_dist/assets/chevron-down-D3BE3JWH.js create mode 100644 backend/internal/server/ui_dist/assets/chevron-right-BNHZGbeL.js delete mode 100644 backend/internal/server/ui_dist/assets/chevron-right-Cee8Bzpp.js rename backend/internal/server/ui_dist/assets/{circle-CNJP_P8E.js => circle-BHcDUsj0.js} (76%) rename backend/internal/server/ui_dist/assets/{circle-alert-BNFtIIyP.js => circle-alert-Buaacgot.js} (73%) rename backend/internal/server/ui_dist/assets/{clock-CYEi9Knb.js => clock-Dx_vxhwd.js} (77%) rename backend/internal/server/ui_dist/assets/{copy-5veW7U_F.js => copy-DHTw5vil.js} (71%) rename backend/internal/server/ui_dist/assets/{flag-CSXzs-fq.js => flag-BApEgnYF.js} (73%) rename backend/internal/server/ui_dist/assets/{git-compare-DoufYPrI.js => git-compare-CRDCiUNE.js} (86%) rename backend/internal/server/ui_dist/assets/{globe-L6h6bFKN.js => globe-D4_vTA7d.js} (72%) delete mode 100644 backend/internal/server/ui_dist/assets/index-B93KhQc5.js create mode 100644 backend/internal/server/ui_dist/assets/index-C5tWn-5z.css create mode 100644 backend/internal/server/ui_dist/assets/index-CZI-jurg.js delete mode 100644 backend/internal/server/ui_dist/assets/index-DjfRwYQD.css rename backend/internal/server/ui_dist/assets/{key-round-CJGTpWKA.js => key-round-7iKBY7s0.js} (81%) rename backend/internal/server/ui_dist/assets/{lock-Clh4EWdA.js => lock-DzLYLVcq.js} (67%) rename backend/internal/server/ui_dist/assets/{pencil-DemHUXoL.js => pencil-CSU4z7ce.js} (75%) create mode 100644 backend/internal/server/ui_dist/assets/pinia-B41TZNUX.js delete mode 100644 backend/internal/server/ui_dist/assets/pinia-D7gh0q31.js rename backend/internal/server/ui_dist/assets/{play-BBWx7r99.js => play-7LGcVtH4.js} (64%) rename backend/internal/server/ui_dist/assets/{refresh-cw-BiUNRBGx.js => refresh-cw-DihaytVM.js} (79%) rename backend/internal/server/ui_dist/assets/{rotate-ccw-B9grc64w.js => rotate-ccw-DWDBjUXf.js} (66%) create mode 100644 backend/internal/server/ui_dist/assets/runtime-core.esm-bundler-BMQPyJ_W.js delete mode 100644 backend/internal/server/ui_dist/assets/runtime-core.esm-bundler-DWJwptQ-.js rename backend/internal/server/ui_dist/assets/{settings-2-DyBZntFB.js => settings-2-D6woyAob.js} (92%) rename backend/internal/server/ui_dist/assets/{shield-check-DU6_qnwV.js => shield-check-BhZjagef.js} (79%) rename backend/internal/server/ui_dist/assets/{sparkles-yO26ZD4G.js => sparkles-BJpg1z9b.js} (86%) rename backend/internal/server/ui_dist/assets/{square-pen-W_aBk2wR.js => square-pen-BaygMdb7.js} (79%) rename backend/internal/server/ui_dist/assets/{terminal-DBfAxzMM.js => terminal-D2TUj2P6.js} (57%) rename backend/internal/server/ui_dist/assets/{trash-2-BlIjHjqi.js => trash-2-DDX094Y-.js} (79%) rename backend/internal/server/ui_dist/assets/{variable-CmAS7ZoV.js => variable-JBU1Bvu7.js} (77%) rename backend/internal/server/ui_dist/assets/{zap-C_6MZAJC.js => zap-Bv0F6KCG.js} (75%) diff --git a/.impeccable/design.json b/.impeccable/design.json index e397cf82..db063c7f 100644 --- a/.impeccable/design.json +++ b/.impeccable/design.json @@ -1,6 +1,6 @@ { "schemaVersion": 2, - "generatedAt": "2026-05-04T00:00:00Z", + "generatedAt": "2026-08-11T07:32:00Z", "title": "Design System: Orva", "extensions": { "colorMeta": { @@ -190,9 +190,9 @@ "name": "Page Card", "kind": "card", "refersTo": "card", - "description": "Dashboard tile / panel. Sits one step deeper than the page surface to read as a content well.", - "html": "
Response time
How long calls take to come back. p99 is the worst-case 1-in-100.
42 ms
", - "css": ".ds-card { background: var(--color-background, #12111C); border: 1px solid var(--color-border, #2D2B42); border-radius: 8px; padding: 20px; font-family: Inter, ui-sans-serif, system-ui, sans-serif; } .ds-card-caption { font-size: 0.75rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: #FFFFFF; } .ds-card-hint { margin-top: 4px; font-size: 0.6875rem; color: var(--color-foreground-muted, #A3A3B3); line-height: 1.55; } .ds-card-value { margin-top: 16px; font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 1.5rem; font-weight: 500; color: #FFFFFF; } .ds-card-unit { font-size: 0.875rem; color: var(--color-foreground-muted, #A3A3B3); margin-left: 4px; }" + "description": "Dashboard tile or panel. Shows decision-ready content first; optional context appears only when the metric is unfamiliar.", + "html": "

Response time

42 ms
", + "css": ".ds-card { background: var(--color-background, #12111C); border: 1px solid var(--color-border, #2D2B42); border-radius: 8px; padding: 20px; font-family: Inter, ui-sans-serif, system-ui, sans-serif; } .ds-card-title { margin: 0; font-size: 0.875rem; font-weight: 600; color: #FFFFFF; } .ds-card-value { margin-top: 16px; font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 1.5rem; font-weight: 500; color: #FFFFFF; } .ds-card-unit { font-size: 0.875rem; color: var(--color-foreground-muted, #A3A3B3); margin-left: 4px; }" }, { "name": "Text Input", @@ -203,11 +203,11 @@ "css": ".ds-input-wrap { display: flex; flex-direction: column; gap: 6px; } .ds-input-label { font-family: Inter, ui-sans-serif, system-ui, sans-serif; font-size: 0.75rem; font-weight: 500; letter-spacing: 0.04em; text-transform: uppercase; color: var(--color-foreground-muted, #A3A3B3); } .ds-input { height: 36px; padding: 0 12px; background: var(--color-background, #12111C); color: #FFFFFF; border: 1px solid var(--color-border, #2D2B42); border-radius: 6px; font-family: Inter, ui-sans-serif, system-ui, sans-serif; font-size: 0.875rem; line-height: 1; transition: border-color 150ms ease-out, box-shadow 150ms ease-out; outline: none; } .ds-input::placeholder { color: rgba(163,163,179,0.5); } .ds-input:focus { border-color: #FFFFFF; box-shadow: inset 0 0 0 1px #FFFFFF; }" }, { - "name": "Sidebar Item (active)", + "name": "Sidebar Group and Active Item", "kind": "nav", "refersTo": "sidebar-item", - "description": "Currently-routed nav item in the dashboard sidebar. Anchors 'you are here' with hue-matched soft shadow.", - "html": "Functions", + "description": "Primary routes stay visible; lower-frequency routes sit in collapsible groups. The current route remains visually anchored.", + "html": "
ObserveActivityInvocations
", "css": ".ds-nav-item { display: inline-flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 6px; font-family: Inter, ui-sans-serif, system-ui, sans-serif; font-size: 0.875rem; font-weight: 500; color: var(--color-foreground-muted, #A3A3B3); text-decoration: none; transition: color 150ms ease-out, background-color 150ms ease-out; } .ds-nav-item:hover { color: #FFFFFF; background: var(--color-surface-hover, #252438); } .ds-nav-icon { width: 16px; height: 16px; } .ds-nav-active { color: #FFFFFF; background: var(--color-primary, #553F83); box-shadow: 0 10px 15px -3px rgba(38,18,87,0.20); } .ds-nav-active:hover { color: #FFFFFF; background: var(--color-primary, #553F83); }" } ], @@ -218,7 +218,7 @@ "Deep violet-tinted dark surfaces; one muted purple accent carries identity.", "Inter for prose, JetBrains Mono for any data the operator might compare digit-to-digit.", "Standardised page heads: text-xl semibold tracking-tight over a one-line subhead in muted text, max-w-prose.", - "Hidden scrollbars by intent: nested overflow areas (modals, drawers, code blocks) feel calmer without 6px tracks in every region.", + "Thin, low-contrast scrollbars keep nested overflow discoverable without dominating the surface.", "Status colour is semantic, never decorative.", "No copy uses em dashes." ], @@ -230,7 +230,8 @@ { "name": "The No-Em-Dash Rule", "section": "typography", "body": "Em dashes are forbidden in any user-facing string. Use periods, commas, colons, semicolons, or parentheses." }, { "name": "The Heading Hierarchy Rule", "section": "typography", "body": "Every page has exactly one H1 (the standardised page header). Section captions inside the page must be real H2 / H3 in markup, even when styled as small uppercase tracked labels." }, { "name": "The Flat-By-Default Rule", "section": "elevation", "body": "Cards, list items, drawers, and inline panels carry no shadow at rest. Depth is read from borders and the background -> surface -> surface-hover ladder." }, - { "name": "The Earned Blur Rule", "section": "elevation", "body": "backdrop-blur exists only on the dimmed background that sits behind a modal or drawer. It is not decoration." } + { "name": "The Earned Blur Rule", "section": "elevation", "body": "backdrop-blur exists only on the dimmed background that sits behind a modal or drawer. It is not decoration." }, + { "name": "The Progressive Disclosure Rule", "section": "components", "body": "Keep decision-ready state visible. Place setup forms, implementation metadata, and advanced detail behind native disclosure controls." } ], "dos": [ "Do keep page heads to one line above one body subhead, both standardised: text-xl font-semibold text-white tracking-tight over text-sm text-foreground-muted mt-1.5 max-w-prose leading-relaxed.", @@ -239,7 +240,8 @@ "Do promote section captions inside cards to real h2 / h3 while keeping the text-xs font-bold uppercase tracking-wider styling.", "Do reach for bg-background border border-border for cards-on-page and bg-surface border border-border for cards-on-deeper-surface.", "Do add aria-label to every icon-only button.", - "Do keep CTAs on roughly 5 to 10 percent of any screen." + "Do keep CTAs on roughly 5 to 10 percent of any screen.", + "Do keep the decision-ready state visible and disclose setup forms, implementation metadata, and advanced detail on demand." ], "donts": [ "Don't use em dashes in any user-facing string. Subheads, alerts, empty-state copy, toast messages: rewrite with periods, commas, colons, semicolons, or parentheses.", @@ -253,6 +255,7 @@ "Don't style section captions as divs and skip the heading.", "Don't introduce border-left-N or border-right-N colored stripes on cards, list items, or alerts.", "Don't animate layout properties. Transforms and opacity only.", + "Don't turn onboarding into a product demo or place decorative terminal output beside account creation.", "Don't ease with bounce or elastic. Exponential ease-out only." ] } diff --git a/DESIGN.md b/DESIGN.md index 81f2e2f7..9d72720a 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -141,7 +141,7 @@ What this system rejects: the SaaS-marketing dashboard family (gradient hero pan - Deep violet-tinted dark surfaces; one muted purple accent carries identity. - Inter for prose, JetBrains Mono for any data the operator might compare digit-to-digit. - Standardised page heads: `text-xl semibold tracking-tight` over a one-line subhead in muted text, max-w-prose. -- Hidden scrollbars by intent: nested overflow areas (modals, drawers, code blocks) feel calmer without 6px tracks in every region. +- Thin, low-contrast scrollbars keep nested overflow discoverable without dominating the surface. - Status colour is semantic, never decorative. A pill that's amber means in-flight; an amber accent that means nothing is forbidden. - No copy uses em dashes. Periods, commas, colons, semicolons, parentheses. The voice is operator-spoken. @@ -249,7 +249,7 @@ Filter pills on `Jobs.vue`, `Webhooks.vue`, `CronJobs.vue` status strips. Same c Two parallel conventions exist in the codebase; document both honestly. -- **Page-Level Card** (used in `Dashboard.vue` for tiles, `Activity.vue` for stat strips, etc.): `bg-background border border-border rounded-lg p-5`. The page itself is `bg-surface`-shaped (via the layout shell), so cards are a step *down* into the deep background. Headline group uses `text-xs font-bold uppercase tracking-wider` followed by `text-[11px] text-foreground-muted` hint copy. +- **Page-Level Card** (used in `Dashboard.vue` for tiles, `Activity.vue` for stat strips, etc.): `bg-background border border-border rounded-lg p-5`. The page itself is `bg-surface`-shaped (via the layout shell), so cards are a step *down* into the deep background. Use a semantic `h2` or `h3` at `text-sm font-semibold`; add hint copy only when the metric cannot explain itself. - **Component Card** (`components/common/Card.vue`): `bg-surface border border-border rounded-lg`, optional header/footer slots with `border-b/t border-border` dividers and a `bg-surface/50` footer tint. Hoverable variant adds `hover:border-foreground-muted`. **Padding scale:** `none / sm: p-4 / normal: px-6 py-4 / lg: p-8`. Dashboard tiles use `p-5` (20px) inline, which is the rhythm step between sm and normal — keep. @@ -258,6 +258,7 @@ Two parallel conventions exist in the codebase; document both honestly. - **Style:** `bg-background border border-border rounded-md px-3 py-2 text-sm`. Sits one step deeper than the surface, so the eye reads "this is where you type". - **Label:** `text-xs font-medium text-foreground-muted uppercase tracking-wide` above the field. Required indicator is a single `*` in danger color. +- **Association:** every label uses `for` with a stable input `id`; hint and error text are connected with `aria-describedby`, and errors set `aria-invalid`. - **Focus:** `focus:ring-1 focus:ring-white focus:border-white`. The ring is white, not primary — it's a "cursor's-here" marker, not an accent. - **Optional leading icon** (Lucide): `pl-9`, icon at `absolute left-3 top-1/2 -translate-y-1/2 text-foreground-muted`. - **Error:** error string in `text-xs text-danger` directly below the field. @@ -277,7 +278,7 @@ The codebase has two: `Badge.vue` (semantic-token-driven, canonical) and `Status - **Width:** `w-64` mobile drawer, `lg:w-52` (208px) desktop inline. - **Background:** `bg-background border-r border-border`. Same as page; only the right border separates it. - **Brand block:** `h-16` with the Orva mark + wordmark in `font-mono` (yes, mono — the brand wears its operator's clothes). -- **Items:** `flex items-center gap-3 px-3 py-2.5 rounded-md text-sm font-medium`. Single-word labels, distinct icons by silhouette (Gauge, Boxes, CalendarClock, ListChecks, Activity, ListTree, Network, Fingerprint, Plug, Webhook, ShieldHalf, Settings, LibraryBig). +- **Items:** Overview, Chat, and Functions stay visible. Lower-frequency routes are grouped under collapsible Automation, Observe, and Connect disclosures; Settings and Docs remain direct links. Rows use `flex items-center gap-3 px-3 py-2.5 rounded-md text-sm font-medium` with distinct icons by silhouette. - **Active:** `bg-primary text-white shadow-lg shadow-purple-900/20`. Hover: `text-white bg-surface-hover`. - **Mobile:** the desktop sidebar transforms into an off-canvas drawer toggled from a `lg:hidden` top bar with a hamburger icon. @@ -304,6 +305,7 @@ A side panel for inspector-style content (invocation request panel, activity row - **Do** reach for `bg-background border border-border` for cards-on-page and `bg-surface border border-border` for cards-on-deeper-surface. The system reads depth through borders + step shifts, not shadow. - **Do** add `aria-label` to every icon-only button (delete, refresh, close, filter chips). Lucide icons announce nothing on their own. - **Do** keep CTAs on roughly 5 to 10 percent of any screen. Most surfaces have one primary action; some have none. +- **Do** keep the decision-ready state visible and place setup forms, implementation metadata, and advanced detail behind native disclosure controls. ### Don't @@ -311,7 +313,7 @@ PRODUCT.md names five anti-references. Each is below as a Don't. - **Don't look like AWS Console.** No region selectors, no every-feature-on-screen surface, no low-density noise. Orva sits on one host; the UI should feel like one host. If a page wants a settings panel that lists ten unrelated knobs, push back: split it, or fold it into context where each knob lives. - **Don't fall into the generic SaaS dashboard template.** No big-number-small-label-with-gradient-accent hero metrics. The shared design law spells this out as the "hero-metric template" ban; PRODUCT.md repeats the rule. Surface metrics on bars, sparklines, and stacked-bar viz, not on template-shaped tiles. -- **Don't lift Vercel / Railway / landing-page onboarding panels.** Diagonal gradient backgrounds, decorative blurred circles, three identical glassmorphic feature chips with icon + heading + short description. The `Onboarding.vue:4` panel is exactly this template today; replace it with a register native to Orva (live terminal output, real curl→response trace, an editor preview of a deployed function). +- **Don't turn onboarding into a product demo.** No gradients, feature panels, terminal theatre, or secondary education beside the account-creation task. - **Don't apply cloud-vendor branding.** No clouds, no sky gradients, no "scale instantly" copy, no planet-scale rhetoric. Orva runs on one box you can touch. - **Don't read as an AI-generated control plane.** The codebase already uses violet on near-black, so the discipline that keeps it from reading like that template comes from the rest of these rules. Specifically: no glowing borders, no gradient text, no animated mesh backgrounds, no decorative blurs. diff --git a/PRODUCT.md b/PRODUCT.md index 8a171939..d98e468f 100644 --- a/PRODUCT.md +++ b/PRODUCT.md @@ -1,58 +1,114 @@ # Product -## Register + -product +## Platform + +web ## Users -A single technical operator running Orva on hardware they own: homelabbers, indie developers, small self-hosting teams. Most often working alone, after hours, on a single monitor in a dim room. They are comfortable with shell, JSON, and curl, and they expect a control plane that respects that competence rather than abstracting it away. +The primary user is a technical operator running Orva on hardware they own: a +homelabber, indie developer, or small on-premises team. They are comfortable +with shells, JSON, and HTTP APIs, and usually operate one Orva instance from a +single screen. -The job to be done is the same loop they would otherwise pay a cloud provider for: write a function, deploy it, invoke it from outside, debug when it breaks, schedule it, and persist a little bit of state. Orva replaces the cloud account, not the function. The user already knows what serverless is; they want it on their own box, with the warm-pool latency and dashboards intact. +Their core loop is to write a function, deploy it, invoke it, inspect failures, +schedule work, and persist small amounts of state without depending on a cloud +control plane. ## Product Purpose -Orva is a self-hosted Function-as-a-Service for homelab and on-premises use. It deploys JavaScript (Node.js 24), Python (3.14), and TypeScript functions into nsjail sandboxes and exposes them over HTTP, with a built-in dashboard, CLI, MCP server, and an in-product AI assistant. - -Success looks like this: an operator brings up the container, writes a function in the editor, hits Deploy, and the first invocation lands in single-digit milliseconds. They never have to leave the dashboard for the day-2 surface, jobs, cron, secrets, KV, webhooks, firewall, traces. The control plane feels like a serious piece of infrastructure they actually want to keep running, not a hobby project they tolerate. - -## Brand Personality - -Three words: **operator-grade, calm, technical.** - -The voice is the voice of someone who has run a function platform at scale and is now building one to keep at home. Dry, pragmatic, slightly opinionated. Empty states explain what something is and what it will look like once it has data, not a sales pitch for the feature. Section captions are short, declarative, and do not introduce themselves. Mono font carries data; sans carries prose; nothing carries marketing. - -Confidence without polish. Linear, Railway, Fly, Tailscale admin: that family. Looks like a tool that an engineer would build for themselves, then realised would also work for the next operator over. - -## Anti-references - -What Orva must not look or feel like: - -- **AWS Console.** Every-feature-on-screen, region selectors, low information density per pixel despite the noise. Orva sits on one host; the UI should feel like one host. -- **Generic SaaS dashboard with hero-metric tiles.** Big number, small label, supporting stats, gradient accent under the value. Orva surfaces metrics, but they belong on bars and sparklines, not in template-shaped tiles. -- **Vercel / Railway / landing-page onboarding panels** with diagonal gradient backgrounds, decorative blurred circles, and three identical glassmorphic feature chips (icon + heading + short description, repeated). The onboarding view today still leans on this template; PRODUCT.md keeps the rule even after it is fixed. -- **Cloud-vendor branding.** Clouds, sky gradients, "scale instantly" copy, planet-scale anything. Orva runs on one box you can touch. -- **AI-generated control planes.** Purple-on-near-black with violet accents, glowing borders, gradient text headings, animated mesh backgrounds. Orva is dark and uses violet, but the discipline that keeps it from reading as that template comes from the rest of these anti-references. - -## Design Principles - -1. **Operator over operator-of-operators.** Built for the person who runs Orva, not for the team that manages a fleet of operators. No multi-tenant shapes, no role-based abstraction layers in the UI surface. One operator, one console. - -2. **Density without noise.** Pack signal into every row. A long table beats a paginated card grid. Hidden scrollbars and tight line-height are intentional, not accidents to be fixed. - -3. **Practice what you preach.** The dashboard runs on the same self-hosted, single-binary ethos that Orva sells. The UI should not require a service the platform itself does not run. - -4. **Show, don't tell.** Empty states show what the data will look like once it exists (a sample row, a real curl example, a trace shape) rather than marketing copy or icon illustrations. - -5. **Confidence without polish.** Skip the demo flourishes (gradient backgrounds, decorative blurs, animated heroes). The platform earns trust by looking like the kind of tool the user could have written themselves, not by impressing them. +Orva is a self-hosted Function-as-a-Service for homelab and on-premises use. It +deploys JavaScript, TypeScript, and Python functions into nsjail sandboxes and +exposes them over HTTP through a built-in dashboard, CLI, MCP server, and AI +assistant. + +Success means an operator can bring up one instance and complete both the first +deploy and routine operations without assembling separate control-plane +services or leaving Orva for common day-two tasks. + +## Positioning + +Orva provides a complete single-host function platform rather than a remote +cloud account or a collection of loosely connected self-hosted tools. The same +instance owns sandboxed execution, warm pools, deployment history, schedules, +jobs, KV state, webhooks, egress policy, observability, CLI access, MCP tools, +and an AI operator. + +## Operating Context + +Orva runs in homelabs and on-premises environments where operators value local +ownership, predictable behavior, and direct access to their infrastructure. +They move between the web dashboard, terminal, CI, external HTTP clients, and +AI/MCP clients. The dashboard is an operating console, not a marketing surface. + +Most sessions are short and task-oriented: deploy or edit one function, inspect +an execution, respond to a failure, or adjust one integration. The interface +must make the next operational action obvious without requiring the operator to +re-read platform explanations on every visit. + +## Capabilities and Constraints + +- The supported runtimes are Node.js 24, Python 3.14, and TypeScript compiled + into the Node runtime. Orva deliberately supports latest-stable runtimes only. +- Linux function execution is isolated with nsjail. Egress policy is per + sandbox and fail-closed. +- The server is distributed as a single binary with the dashboard embedded. +- Server configuration is environment-variable based. CLI configuration is + stored separately in the operator's home directory. +- Orva is a single-instance operator product. Multi-tenant administration and + fleet-management abstractions are not product goals. +- Dark mode is the supported visual environment. A light theme is not a current + commitment. +- Existing functionality must remain accessible while the interface uses + progressive disclosure to keep routine tasks focused. + +## Brand Commitments + +Orva is operator-grade, calm, and technical. Its voice is dry, pragmatic, and +direct. It assumes competence, uses plain operational language, and avoids +marketing copy. Inter carries prose; JetBrains Mono is reserved for code, paths, +identifiers, and comparable measurements. + +The interface must not resemble a cloud-vendor console, a generic SaaS metric +dashboard, or a decorative AI-generated control plane. Violet is the existing +identity accent, but restraint, hierarchy, and product-specific content keep it +from becoming ornamental. + +## Evidence on Hand + +- The repository contains the complete runnable product, including the Vue + dashboard, Go server, CLI, MCP server, runtime adapters, and automated tests. +- `CONTRACT.md` is the canonical operational and release contract. +- `docs/reference.md` is the canonical user-facing product reference. +- `DESIGN.md` records the incumbent visual system and its constraints. +- No testimonials, customer logos, usage claims, or external validation assets + are supplied. Future work must not fabricate them. + +## Product Principles + +1. **Operational clarity.** The current task and next action should be obvious. + Explain a concept once, at the point where the information changes a + decision. +2. **Secure defaults.** Isolation, authentication, secrets, and egress controls + should fail safely without turning every screen into a security lecture. +3. **Low cognitive load.** Preserve complete capability while hiding advanced + detail until it is relevant. Use headings and spacing before adding boxes. +4. **Local ownership.** Core workflows must remain self-hosted and usable + without a hosted control plane or third-party design dependency. +5. **Operator trust.** Show real state, precise errors, and recoverable actions. + Avoid decorative data, invented proof, and interface theatrics. ## Accessibility & Inclusion -Target: WCAG 2.1 AA across the dashboard. Specific commitments: +Target WCAG 2.1 AA across the dashboard: -- `prefers-reduced-motion` respected; transitions are short (≤150ms) and limited to color and opacity, never layout properties. -- Every interactive control reachable by keyboard. Focus rings visible against the dark surface. Modal and drawer dialogs implement focus trap and restore. -- Icon-only buttons carry `aria-label`. Status badges use color plus glyph or text, never colour alone. -- Heading hierarchy is real (`

` → `

` → `

`), not styled `
`s, so screen-reader navigation works. -- Touch targets meet 44×44 on mobile breakpoints, including filter chips and icon controls. -- Dark theme is the default and the only theme. A light theme is not a roadmap commitment; the audience and use case both lean dark, and a half-supported toggle is worse than none. Revisit if real user demand emerges. +- Every interactive control is keyboard reachable with a visible focus state. +- Labels, hints, errors, and icon-only actions expose programmatic names and + relationships. +- Status never relies on color alone. +- Heading hierarchy uses semantic `h1`, `h2`, and `h3` elements. +- Touch targets meet a 44 by 44 pixel effective area on mobile. +- Reduced-motion preferences preserve understandable state changes without + layout animation. diff --git a/backend/internal/server/ui_dist/assets/AI-DiZy-u0r.js b/backend/internal/server/ui_dist/assets/AI-Cybev_nu.js similarity index 55% rename from backend/internal/server/ui_dist/assets/AI-DiZy-u0r.js rename to backend/internal/server/ui_dist/assets/AI-Cybev_nu.js index eddce0ae..46b640e4 100644 --- a/backend/internal/server/ui_dist/assets/AI-DiZy-u0r.js +++ b/backend/internal/server/ui_dist/assets/AI-Cybev_nu.js @@ -1,16 +1,16 @@ -import{r as e}from"./axios-DVDuIpRy.js";import{A as t,C as n,D as r,E as i,F as a,M as o,N as s,P as c,S as l,T as u,W as d,X as f,_t as p,a as m,c as h,d as g,gt as _,h as v,ht as y,k as b,l as x,m as S,r as C,s as w,u as T,x as E}from"./runtime-core.esm-bundler-DWJwptQ-.js";import{t as D}from"./check-lEJPUgfZ.js";import{t as O}from"./chevron-down-D3BE3JWH.js";import{t as k}from"./copy-5veW7U_F.js";import{n as ee,t as A}from"./ai-D_iG5rtR.js";import{t as te}from"./pencil-DemHUXoL.js";import{t as ne}from"./rotate-ccw-B9grc64w.js";import{t as re}from"./sparkles-yO26ZD4G.js";import{t as ie}from"./trash-2-BlIjHjqi.js";import{t as ae}from"./zap-C_6MZAJC.js";import{At as j,It as oe,Rt as se,St as ce,Tt as le,_t as M,bt as ue,gt as de,jt as fe,mt as pe,ut as me,xt as he,zt as ge}from"./index-B93KhQc5.js";import{t as _e}from"./Drawer-CNvPia4g.js";import{a as N,i as ve,n as ye,r as be,t as xe}from"./github-dark-D7LxIVih.js";import{t as Se}from"./clipboard-D_9N0yai.js";var Ce=j(`arrow-down`,[[`path`,{d:`M12 5v14`,key:`s699le`}],[`path`,{d:`m19 12-7 7-7-7`,key:`1idqje`}]]),we=j(`arrow-up`,[[`path`,{d:`m5 12 7-7 7 7`,key:`hav0vg`}],[`path`,{d:`M12 19V5`,key:`x0mq9r`}]]),Te=j(`ban`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M4.929 4.929 19.07 19.071`,key:`196cmz`}]]),Ee=j(`brain`,[[`path`,{d:`M12 18V5`,key:`adv99a`}],[`path`,{d:`M15 13a4.17 4.17 0 0 1-3-4 4.17 4.17 0 0 1-3 4`,key:`1e3is1`}],[`path`,{d:`M17.598 6.5A3 3 0 1 0 12 5a3 3 0 1 0-5.598 1.5`,key:`1gqd8o`}],[`path`,{d:`M17.997 5.125a4 4 0 0 1 2.526 5.77`,key:`iwvgf7`}],[`path`,{d:`M18 18a4 4 0 0 0 2-7.464`,key:`efp6ie`}],[`path`,{d:`M19.967 17.483A4 4 0 1 1 12 18a4 4 0 1 1-7.967-.517`,key:`1gq6am`}],[`path`,{d:`M6 18a4 4 0 0 1-2-7.464`,key:`k1g0md`}],[`path`,{d:`M6.003 5.125a4 4 0 0 0-2.526 5.77`,key:`q97ue3`}]]),De=j(`chevrons-down-up`,[[`path`,{d:`m7 20 5-5 5 5`,key:`13a0gw`}],[`path`,{d:`m7 4 5 5 5-5`,key:`1kwcof`}]]),Oe=j(`chevrons-up-down`,[[`path`,{d:`m7 15 5 5 5-5`,key:`1hf1tw`}],[`path`,{d:`m7 9 5-5 5 5`,key:`sgt6xg`}]]),ke=j(`cpu`,[[`path`,{d:`M12 20v2`,key:`1lh1kg`}],[`path`,{d:`M12 2v2`,key:`tus03m`}],[`path`,{d:`M17 20v2`,key:`1rnc9c`}],[`path`,{d:`M17 2v2`,key:`11trls`}],[`path`,{d:`M2 12h2`,key:`1t8f8n`}],[`path`,{d:`M2 17h2`,key:`7oei6x`}],[`path`,{d:`M2 7h2`,key:`asdhe0`}],[`path`,{d:`M20 12h2`,key:`1q8mjw`}],[`path`,{d:`M20 17h2`,key:`1fpfkl`}],[`path`,{d:`M20 7h2`,key:`1o8tra`}],[`path`,{d:`M7 20v2`,key:`4gnj0m`}],[`path`,{d:`M7 2v2`,key:`1i4yhu`}],[`rect`,{x:`4`,y:`4`,width:`16`,height:`16`,rx:`2`,key:`1vbyd7`}],[`rect`,{x:`8`,y:`8`,width:`8`,height:`8`,rx:`1`,key:`z9xiuo`}]]),Ae=j(`message-square`,[[`path`,{d:`M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z`,key:`18887p`}]]),je=j(`panel-left`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}],[`path`,{d:`M9 3v18`,key:`fh3hqa`}]]),Me=j(`square`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}]]),Ne=j(`wrench`,[[`path`,{d:`M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z`,key:`1ngwbx`}]]),Pe={class:`flex h-16 shrink-0 items-center justify-between gap-3 border-b border-border px-4`},Fe={class:`flex min-w-0 items-center gap-2`},Ie={class:`truncate text-sm font-semibold tracking-tight text-white`},Le={class:`flex items-center gap-0.5`},Re={__name:`ChatHeader`,props:{title:{type:String,default:`Assistant`},canExport:{type:Boolean,default:!1}},emits:[`toggle-rail`,`export`],setup(e){return(t,n)=>(r(),g(`header`,Pe,[h(`div`,Fe,[h(`button`,{class:`touch-expand-iconbtn -ml-1 rounded-md p-2 text-foreground-muted transition-colors hover:bg-surface-hover hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-background md:hidden`,"aria-label":`Conversations`,onClick:n[0]||=e=>t.$emit(`toggle-rail`)},[v(f(je),{class:`h-4 w-4`})]),v(f(Ae),{class:`hidden h-4 w-4 shrink-0 text-foreground-muted md:block`}),h(`h1`,Ie,p(e.title),1)]),h(`div`,Le,[e.canExport?(r(),g(`button`,{key:0,class:`touch-expand-iconbtn -mr-1 rounded-md p-2 text-foreground-muted transition-colors hover:bg-surface-hover hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-background`,"aria-label":`Export conversation as Markdown`,title:`Export conversation`,onClick:n[1]||=e=>t.$emit(`export`)},[v(f(ee),{class:`h-4 w-4`})])):T(``,!0)])]))}},ze={class:`flex h-full flex-col`},Be={key:0,class:`flex h-16 shrink-0 items-center justify-between px-4 border-b border-border`},Ve={class:`flex-1 overflow-y-auto scrollable p-2 space-y-0.5`},He=[`aria-current`,`onClick`],Ue={class:`flex-1 truncate`},We=[`onClick`],Ge=[`onClick`],Ke={key:1,class:`px-2.5 py-2 text-xs text-foreground-muted`},qe={__name:`ConversationRail`,props:{embedded:{type:Boolean,default:!1}},emits:[`select`],setup(e,{emit:t}){let n=A(),i=de();async function a(e){let t=await i.prompt({title:`Rename conversation`,defaultValue:e.title||``,placeholder:`Conversation name`,confirmLabel:`Rename`});t!=null&&t.trim()&&n.renameConversation(e.id,t.trim())}async function o(e){await i.ask({title:`Delete conversation?`,message:`This permanently deletes the conversation and all its messages.`,danger:!0,confirmLabel:`Delete`})&&n.deleteConversation(e)}let s=t;function l(){n.newConversation(),s(`select`)}function u(e){n.openConversation(e),s(`select`)}return(t,i)=>(r(),g(`div`,ze,[e.embedded?T(``,!0):(r(),g(`div`,Be,[i[1]||=h(`span`,{class:`text-sm font-semibold tracking-tight text-white`},`Conversations`,-1),v(M,{size:`xs`,variant:`secondary`,onClick:l},{default:c(()=>[v(f(ce),{class:`h-3.5 w-3.5`}),i[0]||=S(` New `,-1)]),_:1})])),h(`div`,Ve,[e.embedded?(r(),g(`button`,{key:0,class:`touch-expand-sm mb-1 flex w-full items-center gap-2 rounded-md border border-border px-2.5 py-2 text-left text-sm text-foreground transition-colors hover:bg-surface-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary`,onClick:l},[v(f(ce),{class:`h-3.5 w-3.5 shrink-0`}),i[2]||=S(` New conversation `,-1)])):T(``,!0),(r(!0),g(C,null,b(f(n).conversations,e=>(r(),g(`div`,{key:e.id,class:y([`group flex w-full items-center gap-0.5 rounded-md pr-1 transition-colors`,e.id===f(n).activeId?`bg-primary/15`:`hover:bg-surface-hover`])},[h(`button`,{class:y([`touch-expand-sm flex min-w-0 flex-1 items-center gap-2 rounded-md px-2.5 py-2 text-left text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary`,e.id===f(n).activeId?`text-white`:`text-foreground-muted group-hover:text-white`]),"aria-current":e.id===f(n).activeId?`page`:void 0,onClick:t=>u(e.id)},[v(f(Ae),{class:`h-3.5 w-3.5 shrink-0 opacity-70`}),h(`span`,Ue,p(e.title||`New conversation`),1)],10,He),h(`button`,{type:`button`,class:`touch-expand-xs shrink-0 rounded-md p-2 text-foreground-muted opacity-0 transition-opacity hover:bg-surface-hover hover:text-white focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary group-hover:opacity-100 max-md:opacity-100`,title:`Rename conversation`,"aria-label":`Rename conversation`,onClick:ge(t=>a(e),[`stop`])},[v(f(te),{class:`h-3.5 w-3.5`})],8,We),h(`button`,{type:`button`,class:`touch-expand-xs shrink-0 rounded-md p-2 text-foreground-muted opacity-0 transition-opacity hover:bg-surface-hover hover:text-danger-fg focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary group-hover:opacity-100 max-md:opacity-100`,title:`Delete conversation`,"aria-label":`Delete conversation`,onClick:ge(t=>o(e.id),[`stop`])},[v(f(ie),{class:`h-3.5 w-3.5`})],8,Ge)],2))),128)),f(n).conversations.length?T(``,!0):(r(),g(`p`,Ke,` No conversations yet. `))])]))}},Je={class:`text-center`},Ye={class:`mx-auto mb-4 flex h-11 w-11 items-center justify-center rounded-xl bg-primary/15 text-primary`},Xe={class:`mx-auto mt-6 grid max-w-xl gap-2 sm:grid-cols-2`},Ze=[`onClick`],Qe={class:`line-clamp-2`},$e={__name:`EmptyState`,emits:[`pick`],setup(e){let t=[`How many functions do I have?`,`Which function ran most recently?`,`Any errors in the last 24 hours?`,`Show my most recent executions.`,`List my deployed functions.`,`Summarize today’s invocation errors.`,`Show failed deployments and why.`,`What’s my system health right now?`,`Show storage usage for my instance.`,`List my cron schedules.`,`Are any background jobs failing?`,`Check for failed webhook deliveries.`,`Which runtimes are available?`,`Show my slowest functions by duration.`,`Which functions have egress enabled?`,`List my secrets by name only.`,`Write a Python function that returns the current UTC time.`,`Write a Node function that echoes the request body.`,`Create an hourly cron schedule for a function.`,`Walk me through deploying a new function.`];function n(e,t){let n=[...e];for(let e=n.length-1;e>0;e--){let t=Math.floor(Math.random()*(e+1));[n[e],n[t]]=[n[t],n[e]]}return n.slice(0,t)}let i=d(n(t,4));return(e,t)=>(r(),g(`div`,Je,[h(`div`,Ye,[v(f(le),{class:`h-5 w-5`})]),t[0]||=h(`h2`,{class:`text-lg font-semibold tracking-tight text-white`},` What would you like to do? `,-1),t[1]||=h(`p`,{class:`mx-auto mt-1.5 max-w-md text-sm leading-relaxed text-foreground-muted`},` Ask about your functions, logs, deployments, and operations. Or have me create, deploy, and invoke functions for you. `,-1),h(`div`,Xe,[(r(!0),g(C,null,b(i.value,(t,n)=>(r(),g(`button`,{key:n,type:`button`,class:`flex min-h-[4.25rem] items-center rounded-lg border border-border bg-surface/50 px-3.5 py-3 text-left text-[13px] leading-snug text-foreground-muted transition-colors hover:border-foreground-muted/40 hover:bg-surface-hover hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-background`,onClick:n=>e.$emit(`pick`,t)},[h(`span`,Qe,p(t),1)],8,Ze))),128))])]))}},et=`[A-Za-z$_][0-9A-Za-z$_]*`,tt=`as.in.of.if.for.while.finally.var.new.function.do.return.void.else.break.catch.instanceof.with.throw.case.default.try.switch.continue.typeof.delete.let.yield.const.class.debugger.async.await.static.import.from.export.extends.using`.split(`.`),nt=[`true`,`false`,`null`,`undefined`,`NaN`,`Infinity`],rt=`Object.Function.Boolean.Symbol.Math.Date.Number.BigInt.String.RegExp.Array.Float32Array.Float64Array.Int8Array.Uint8Array.Uint8ClampedArray.Int16Array.Int32Array.Uint16Array.Uint32Array.BigInt64Array.BigUint64Array.Set.Map.WeakSet.WeakMap.ArrayBuffer.SharedArrayBuffer.Atomics.DataView.JSON.Promise.Generator.GeneratorFunction.AsyncFunction.Reflect.Proxy.Intl.WebAssembly`.split(`.`),it=[`Error`,`EvalError`,`InternalError`,`RangeError`,`ReferenceError`,`SyntaxError`,`TypeError`,`URIError`],at=[`setInterval`,`setTimeout`,`clearInterval`,`clearTimeout`,`require`,`exports`,`eval`,`isFinite`,`isNaN`,`parseFloat`,`parseInt`,`decodeURI`,`decodeURIComponent`,`encodeURI`,`encodeURIComponent`,`escape`,`unescape`],ot=[`arguments`,`this`,`super`,`console`,`window`,`document`,`localStorage`,`sessionStorage`,`module`,`global`],st=[].concat(at,rt,it);function ct(e){let t=e.regex,n=(e,{after:t})=>{let n=``,end:``},a=/<[A-Za-z0-9\\._:-]+\s*\/>/,o={begin:/<[A-Za-z0-9\\._:-]+/,end:/\/[A-Za-z0-9\\._:-]+>|\/>/,isTrulyOpeningTag:(e,t)=>{let r=e[0].length+e.index,i=e.input[r];if(i===`<`||i===`,`){t.ignoreMatch();return}i===`>`&&(n(e,{after:r})||t.ignoreMatch());let a,o=e.input.substring(r);if(a=o.match(/^\s*=/)){t.ignoreMatch();return}if((a=o.match(/^\s+extends\s+/))&&a.index===0){t.ignoreMatch();return}}},s={$pattern:et,keyword:tt,literal:nt,built_in:st,"variable.language":ot},c=`[0-9](_?[0-9])*`,l=`\\.(${c})`,u=`0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*`,d={className:`number`,variants:[{begin:`(\\b(${u})((${l})|\\.)?|(${l}))[eE][+-]?(${c})\\b`},{begin:`\\b(${u})\\b((${l})\\b|\\.)?|(${l})\\b`},{begin:`\\b(0|[1-9](_?[0-9])*)n\\b`},{begin:`\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*n?\\b`},{begin:`\\b0[bB][0-1](_?[0-1])*n?\\b`},{begin:`\\b0[oO][0-7](_?[0-7])*n?\\b`},{begin:`\\b0[0-7]+n?\\b`}],relevance:0},f={className:`subst`,begin:`\\$\\{`,end:`\\}`,keywords:s,contains:[]},p={begin:".?html`",end:``,starts:{end:"`",returnEnd:!1,contains:[e.BACKSLASH_ESCAPE,f],subLanguage:`xml`}},m={begin:".?css`",end:``,starts:{end:"`",returnEnd:!1,contains:[e.BACKSLASH_ESCAPE,f],subLanguage:`css`}},h={begin:".?gql`",end:``,starts:{end:"`",returnEnd:!1,contains:[e.BACKSLASH_ESCAPE,f],subLanguage:`graphql`}},g={className:`string`,begin:"`",end:"`",contains:[e.BACKSLASH_ESCAPE,f]},_={className:`comment`,variants:[e.COMMENT(/\/\*\*(?!\/)/,`\\*/`,{relevance:0,contains:[{begin:`(?=@[A-Za-z]+)`,relevance:0,contains:[{className:`doctag`,begin:`@[A-Za-z]+`},{className:`type`,begin:`\\{`,end:`\\}`,excludeEnd:!0,excludeBegin:!0,relevance:0},{className:`variable`,begin:`[A-Za-z$_][0-9A-Za-z$_]*(?=\\s*(-)|$)`,endsParent:!0,relevance:0},{begin:/(?=[^\n])\s/,relevance:0}]}]}),e.C_BLOCK_COMMENT_MODE,e.C_LINE_COMMENT_MODE]},v=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,p,m,h,g,{match:/\$\d+/},d];f.contains=v.concat({begin:/\{/,end:/\}/,keywords:s,contains:[`self`].concat(v)});let y=[].concat(_,f.contains),b=y.concat([{begin:/(\s*)\(/,end:/\)/,keywords:s,contains:[`self`].concat(y)}]),x={className:`params`,begin:/(\s*)\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:s,contains:b},S={variants:[{match:[/class/,/\s+/,r,/\s+/,/extends/,/\s+/,t.concat(r,`(`,t.concat(/\./,r),`)*`)],scope:{1:`keyword`,3:`title.class`,5:`keyword`,7:`title.class.inherited`}},{match:[/class/,/\s+/,r],scope:{1:`keyword`,3:`title.class`}}]},C={relevance:0,match:t.either(/\bJSON/,/\b[A-Z][a-z]+([A-Z][a-z]*|\d)*/,/\b[A-Z]{2,}([A-Z][a-z]+|\d)+([A-Z][a-z]*)*/,/\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\d)*([A-Z][a-z]*)*/),className:`title.class`,keywords:{_:[...rt,...it]}},w={label:`use_strict`,className:`meta`,relevance:10,begin:/^\s*['"]use (strict|asm)['"]/},T={variants:[{match:[/function/,/\s+/,r,/(?=\s*\()/]},{match:[/function/,/\s*(?=\()/]}],className:{1:`keyword`,3:`title.function`},label:`func.def`,contains:[x],illegal:/%/},E={relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/,className:`variable.constant`};function D(e){return t.concat(`(?!`,e.join(`|`),`)`)}let O={match:t.concat(/\b/,D([...at,`super`,`import`].map(e=>`${e}\\s*\\(`)),r,t.lookahead(/\s*\(/)),className:`title.function`,relevance:0},k={begin:t.concat(/\./,t.lookahead(t.concat(r,/(?![0-9A-Za-z$_(])/))),end:r,excludeBegin:!0,keywords:`prototype`,className:`property`,relevance:0},ee={match:[/get|set/,/\s+/,r,/(?=\()/],className:{1:`keyword`,3:`title.function`},contains:[{begin:/\(\)/},x]},A=`(\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)|`+e.UNDERSCORE_IDENT_RE+`)\\s*=>`,te={match:[/const|var|let/,/\s+/,r,/\s*/,/=\s*/,/(async\s*)?/,t.lookahead(A)],keywords:`async`,className:{1:`keyword`,3:`title.function`},contains:[x]};return{name:`JavaScript`,aliases:[`js`,`jsx`,`mjs`,`cjs`],keywords:s,exports:{PARAMS_CONTAINS:b,CLASS_REFERENCE:C},illegal:/#(?![$_A-z])/,contains:[e.SHEBANG({label:`shebang`,binary:`node`,relevance:5}),w,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,p,m,h,g,_,{match:/\$\d+/},d,C,{scope:`attr`,match:r+t.lookahead(`:`),relevance:0},te,{begin:`(`+e.RE_STARTERS_RE+`|\\b(case|return|throw)\\b)\\s*`,keywords:`return throw case`,relevance:0,contains:[_,e.REGEXP_MODE,{className:`function`,begin:A,returnBegin:!0,end:`\\s*=>`,contains:[{className:`params`,variants:[{begin:e.UNDERSCORE_IDENT_RE,relevance:0},{className:null,begin:/\(\s*\)/,skip:!0},{begin:/(\s*)\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:s,contains:b}]}]},{begin:/,/,relevance:0},{match:/\s+/,relevance:0},{variants:[{begin:i.begin,end:i.end},{match:a},{begin:o.begin,"on:begin":o.isTrulyOpeningTag,end:o.end}],subLanguage:`xml`,contains:[{begin:o.begin,end:o.end,skip:!0,contains:[`self`]}]}]},T,{beginKeywords:`while if switch catch for`},{begin:`\\b(?!function)`+e.UNDERSCORE_IDENT_RE+`\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{`,returnBegin:!0,label:`func.def`,contains:[x,e.inherit(e.TITLE_MODE,{begin:r,className:`title.function`})]},{match:/\.\.\./,relevance:0},k,{match:`\\$[A-Za-z$_][0-9A-Za-z$_]*`,relevance:0},{match:[/\bconstructor(?=\s*\()/],className:{1:`title.function`},contains:[x]},O,E,S,ee,{match:/\$[(.]/}]}}function lt(e){let t=e.regex,n=ct(e),r=et,i=[`any`,`void`,`number`,`boolean`,`string`,`object`,`never`,`symbol`,`bigint`,`unknown`],a={begin:[/namespace/,/\s+/,e.IDENT_RE],beginScope:{1:`keyword`,3:`title.class`}},o={beginKeywords:`interface`,end:/\{/,excludeEnd:!0,keywords:{keyword:`interface extends`,built_in:i},contains:[n.exports.CLASS_REFERENCE]},s={className:`meta`,relevance:10,begin:/^\s*['"]use strict['"]/},c={$pattern:et,keyword:tt.concat([`type`,`interface`,`public`,`private`,`protected`,`implements`,`declare`,`abstract`,`readonly`,`enum`,`override`,`satisfies`]),literal:nt,built_in:st.concat(i),"variable.language":ot},l={className:`meta`,begin:`@[A-Za-z$_][0-9A-Za-z$_]*`},u=(e,t,n)=>{let r=e.contains.findIndex(e=>e.label===t);if(r===-1)throw Error(`can not find mode to replace`);e.contains.splice(r,1,n)};Object.assign(n.keywords,c),n.exports.PARAMS_CONTAINS.push(l);let d=n.contains.find(e=>e.scope===`attr`),f=Object.assign({},d,{match:t.concat(r,t.lookahead(/\s*\?:/))});n.exports.PARAMS_CONTAINS.push([n.exports.CLASS_REFERENCE,d,f]),n.contains=n.contains.concat([l,a,o,f]),u(n,`shebang`,e.SHEBANG()),u(n,`use_strict`,s);let p=n.contains.find(e=>e.label===`func.def`);return p.relevance=0,Object.assign(n,{name:`TypeScript`,aliases:[`ts`,`tsx`,`mts`,`cts`]}),n}function ut(e){let t=e.regex,n=t.concat(/[\p{L}_]/u,t.optional(/[\p{L}0-9_.-]*:/u),/[\p{L}0-9_.-]*/u),r=/[\p{L}0-9._:-]+/u,i={className:`symbol`,begin:/&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/},a={begin:/\s/,contains:[{className:`keyword`,begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}]},o=e.inherit(a,{begin:/\(/,end:/\)/}),s=e.inherit(e.APOS_STRING_MODE,{className:`string`}),c=e.inherit(e.QUOTE_STRING_MODE,{className:`string`}),l={endsWithParent:!0,illegal:/`]+/}]}]}]};return{name:`HTML, XML`,aliases:[`html`,`xhtml`,`rss`,`atom`,`xjb`,`xsd`,`xsl`,`plist`,`wsf`,`svg`],case_insensitive:!0,unicodeRegex:!0,contains:[{className:`meta`,begin://,relevance:10,contains:[a,c,s,o,{begin:/\[/,end:/\]/,contains:[{className:`meta`,begin://,contains:[a,o,c,s]}]}]},e.COMMENT(//,{relevance:10}),{begin://,relevance:10},i,{className:`meta`,end:/\?>/,variants:[{begin:/<\?xml/,relevance:10,contains:[c]},{begin:/<\?[a-z][a-z0-9]+/}]},{className:`tag`,begin:/)/,end:/>/,keywords:{name:`style`},contains:[l],starts:{end:/<\/style>/,returnEnd:!0,subLanguage:[`css`,`xml`]}},{className:`tag`,begin:/)/,end:/>/,keywords:{name:`script`},contains:[l],starts:{end:/<\/script>/,returnEnd:!0,subLanguage:[`javascript`,`handlebars`,`xml`]}},{className:`tag`,begin:/<>|<\/>/},{className:`tag`,begin:t.concat(//,/>/,/\s/)))),end:/\/?>/,contains:[{className:`name`,begin:n,relevance:0,starts:l}]},{className:`tag`,begin:t.concat(/<\//,t.lookahead(t.concat(n,/>/))),contains:[{className:`name`,begin:n,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]}}var dt=e=>({IMPORTANT:{scope:`meta`,begin:`!important`},BLOCK_COMMENT:e.C_BLOCK_COMMENT_MODE,HEXCOLOR:{scope:`number`,begin:/#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/},FUNCTION_DISPATCH:{className:`built_in`,begin:/[\w-]+(?=\()/},ATTRIBUTE_SELECTOR_MODE:{scope:`selector-attr`,begin:/\[/,end:/\]/,illegal:`$`,contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},CSS_NUMBER_MODE:{scope:`number`,begin:e.NUMBER_RE+`(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?`,relevance:0},CSS_VARIABLE:{className:`attr`,begin:/--[A-Za-z_][A-Za-z0-9_-]*/}}),ft=`a.abbr.address.article.aside.audio.b.blockquote.body.button.canvas.caption.cite.code.dd.del.details.dfn.div.dl.dt.em.fieldset.figcaption.figure.footer.form.h1.h2.h3.h4.h5.h6.header.hgroup.html.i.iframe.img.input.ins.kbd.label.legend.li.main.mark.menu.nav.object.ol.optgroup.option.p.picture.q.quote.samp.section.select.source.span.strong.summary.sup.table.tbody.td.textarea.tfoot.th.thead.time.tr.ul.var.video`.split(`.`),pt=`defs.g.marker.mask.pattern.svg.switch.symbol.feBlend.feColorMatrix.feComponentTransfer.feComposite.feConvolveMatrix.feDiffuseLighting.feDisplacementMap.feFlood.feGaussianBlur.feImage.feMerge.feMorphology.feOffset.feSpecularLighting.feTile.feTurbulence.linearGradient.radialGradient.stop.circle.ellipse.image.line.path.polygon.polyline.rect.text.use.textPath.tspan.foreignObject.clipPath`.split(`.`),mt=[...ft,...pt],ht=`any-hover.any-pointer.aspect-ratio.color.color-gamut.color-index.device-aspect-ratio.device-height.device-width.display-mode.forced-colors.grid.height.hover.inverted-colors.monochrome.orientation.overflow-block.overflow-inline.pointer.prefers-color-scheme.prefers-contrast.prefers-reduced-motion.prefers-reduced-transparency.resolution.scan.scripting.update.width.min-width.max-width.min-height.max-height`.split(`.`).sort().reverse(),gt=`active.any-link.blank.checked.current.default.defined.dir.disabled.drop.empty.enabled.first.first-child.first-of-type.fullscreen.future.focus.focus-visible.focus-within.has.host.host-context.hover.indeterminate.in-range.invalid.is.lang.last-child.last-of-type.left.link.local-link.not.nth-child.nth-col.nth-last-child.nth-last-col.nth-last-of-type.nth-of-type.only-child.only-of-type.optional.out-of-range.past.placeholder-shown.read-only.read-write.required.right.root.scope.target.target-within.user-invalid.valid.visited.where`.split(`.`).sort().reverse(),_t=[`after`,`backdrop`,`before`,`cue`,`cue-region`,`first-letter`,`first-line`,`grammar-error`,`marker`,`part`,`placeholder`,`selection`,`slotted`,`spelling-error`].sort().reverse(),vt=`accent-color.align-content.align-items.align-self.alignment-baseline.all.anchor-name.animation.animation-composition.animation-delay.animation-direction.animation-duration.animation-fill-mode.animation-iteration-count.animation-name.animation-play-state.animation-range.animation-range-end.animation-range-start.animation-timeline.animation-timing-function.appearance.aspect-ratio.backdrop-filter.backface-visibility.background.background-attachment.background-blend-mode.background-clip.background-color.background-image.background-origin.background-position.background-position-x.background-position-y.background-repeat.background-size.baseline-shift.block-size.border.border-block.border-block-color.border-block-end.border-block-end-color.border-block-end-style.border-block-end-width.border-block-start.border-block-start-color.border-block-start-style.border-block-start-width.border-block-style.border-block-width.border-bottom.border-bottom-color.border-bottom-left-radius.border-bottom-right-radius.border-bottom-style.border-bottom-width.border-collapse.border-color.border-end-end-radius.border-end-start-radius.border-image.border-image-outset.border-image-repeat.border-image-slice.border-image-source.border-image-width.border-inline.border-inline-color.border-inline-end.border-inline-end-color.border-inline-end-style.border-inline-end-width.border-inline-start.border-inline-start-color.border-inline-start-style.border-inline-start-width.border-inline-style.border-inline-width.border-left.border-left-color.border-left-style.border-left-width.border-radius.border-right.border-right-color.border-right-style.border-right-width.border-spacing.border-start-end-radius.border-start-start-radius.border-style.border-top.border-top-color.border-top-left-radius.border-top-right-radius.border-top-style.border-top-width.border-width.bottom.box-align.box-decoration-break.box-direction.box-flex.box-flex-group.box-lines.box-ordinal-group.box-orient.box-pack.box-shadow.box-sizing.break-after.break-before.break-inside.caption-side.caret-color.clear.clip.clip-path.clip-rule.color.color-interpolation.color-interpolation-filters.color-profile.color-rendering.color-scheme.column-count.column-fill.column-gap.column-rule.column-rule-color.column-rule-style.column-rule-width.column-span.column-width.columns.contain.contain-intrinsic-block-size.contain-intrinsic-height.contain-intrinsic-inline-size.contain-intrinsic-size.contain-intrinsic-width.container.container-name.container-type.content.content-visibility.counter-increment.counter-reset.counter-set.cue.cue-after.cue-before.cursor.cx.cy.direction.display.dominant-baseline.empty-cells.enable-background.field-sizing.fill.fill-opacity.fill-rule.filter.flex.flex-basis.flex-direction.flex-flow.flex-grow.flex-shrink.flex-wrap.float.flood-color.flood-opacity.flow.font.font-display.font-family.font-feature-settings.font-kerning.font-language-override.font-optical-sizing.font-palette.font-size.font-size-adjust.font-smooth.font-smoothing.font-stretch.font-style.font-synthesis.font-synthesis-position.font-synthesis-small-caps.font-synthesis-style.font-synthesis-weight.font-variant.font-variant-alternates.font-variant-caps.font-variant-east-asian.font-variant-emoji.font-variant-ligatures.font-variant-numeric.font-variant-position.font-variation-settings.font-weight.forced-color-adjust.gap.glyph-orientation-horizontal.glyph-orientation-vertical.grid.grid-area.grid-auto-columns.grid-auto-flow.grid-auto-rows.grid-column.grid-column-end.grid-column-start.grid-gap.grid-row.grid-row-end.grid-row-start.grid-template.grid-template-areas.grid-template-columns.grid-template-rows.hanging-punctuation.height.hyphenate-character.hyphenate-limit-chars.hyphens.icon.image-orientation.image-rendering.image-resolution.ime-mode.initial-letter.initial-letter-align.inline-size.inset.inset-area.inset-block.inset-block-end.inset-block-start.inset-inline.inset-inline-end.inset-inline-start.isolation.justify-content.justify-items.justify-self.kerning.left.letter-spacing.lighting-color.line-break.line-height.line-height-step.list-style.list-style-image.list-style-position.list-style-type.margin.margin-block.margin-block-end.margin-block-start.margin-bottom.margin-inline.margin-inline-end.margin-inline-start.margin-left.margin-right.margin-top.margin-trim.marker.marker-end.marker-mid.marker-start.marks.mask.mask-border.mask-border-mode.mask-border-outset.mask-border-repeat.mask-border-slice.mask-border-source.mask-border-width.mask-clip.mask-composite.mask-image.mask-mode.mask-origin.mask-position.mask-repeat.mask-size.mask-type.masonry-auto-flow.math-depth.math-shift.math-style.max-block-size.max-height.max-inline-size.max-width.min-block-size.min-height.min-inline-size.min-width.mix-blend-mode.nav-down.nav-index.nav-left.nav-right.nav-up.none.normal.object-fit.object-position.offset.offset-anchor.offset-distance.offset-path.offset-position.offset-rotate.opacity.order.orphans.outline.outline-color.outline-offset.outline-style.outline-width.overflow.overflow-anchor.overflow-block.overflow-clip-margin.overflow-inline.overflow-wrap.overflow-x.overflow-y.overlay.overscroll-behavior.overscroll-behavior-block.overscroll-behavior-inline.overscroll-behavior-x.overscroll-behavior-y.padding.padding-block.padding-block-end.padding-block-start.padding-bottom.padding-inline.padding-inline-end.padding-inline-start.padding-left.padding-right.padding-top.page.page-break-after.page-break-before.page-break-inside.paint-order.pause.pause-after.pause-before.perspective.perspective-origin.place-content.place-items.place-self.pointer-events.position.position-anchor.position-visibility.print-color-adjust.quotes.r.resize.rest.rest-after.rest-before.right.rotate.row-gap.ruby-align.ruby-position.scale.scroll-behavior.scroll-margin.scroll-margin-block.scroll-margin-block-end.scroll-margin-block-start.scroll-margin-bottom.scroll-margin-inline.scroll-margin-inline-end.scroll-margin-inline-start.scroll-margin-left.scroll-margin-right.scroll-margin-top.scroll-padding.scroll-padding-block.scroll-padding-block-end.scroll-padding-block-start.scroll-padding-bottom.scroll-padding-inline.scroll-padding-inline-end.scroll-padding-inline-start.scroll-padding-left.scroll-padding-right.scroll-padding-top.scroll-snap-align.scroll-snap-stop.scroll-snap-type.scroll-timeline.scroll-timeline-axis.scroll-timeline-name.scrollbar-color.scrollbar-gutter.scrollbar-width.shape-image-threshold.shape-margin.shape-outside.shape-rendering.speak.speak-as.src.stop-color.stop-opacity.stroke.stroke-dasharray.stroke-dashoffset.stroke-linecap.stroke-linejoin.stroke-miterlimit.stroke-opacity.stroke-width.tab-size.table-layout.text-align.text-align-all.text-align-last.text-anchor.text-combine-upright.text-decoration.text-decoration-color.text-decoration-line.text-decoration-skip.text-decoration-skip-ink.text-decoration-style.text-decoration-thickness.text-emphasis.text-emphasis-color.text-emphasis-position.text-emphasis-style.text-indent.text-justify.text-orientation.text-overflow.text-rendering.text-shadow.text-size-adjust.text-transform.text-underline-offset.text-underline-position.text-wrap.text-wrap-mode.text-wrap-style.timeline-scope.top.touch-action.transform.transform-box.transform-origin.transform-style.transition.transition-behavior.transition-delay.transition-duration.transition-property.transition-timing-function.translate.unicode-bidi.user-modify.user-select.vector-effect.vertical-align.view-timeline.view-timeline-axis.view-timeline-inset.view-timeline-name.view-transition-name.visibility.voice-balance.voice-duration.voice-family.voice-pitch.voice-range.voice-rate.voice-stress.voice-volume.white-space.white-space-collapse.widows.width.will-change.word-break.word-spacing.word-wrap.writing-mode.x.y.z-index.zoom`.split(`.`).sort().reverse();function yt(e){let t=e.regex,n=dt(e),r={begin:/-(webkit|moz|ms|o)-(?=[a-z])/},i=/@-?\w[\w]*(-\w+)*/,a=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE];return{name:`CSS`,case_insensitive:!0,illegal:/[=|'\$]/,keywords:{keyframePosition:`from to`},classNameAliases:{keyframePosition:`selector-tag`},contains:[n.BLOCK_COMMENT,r,n.CSS_NUMBER_MODE,{className:`selector-id`,begin:/#[A-Za-z0-9_-]+/,relevance:0},{className:`selector-class`,begin:`\\.[a-zA-Z-][a-zA-Z0-9_-]*`,relevance:0},n.ATTRIBUTE_SELECTOR_MODE,{className:`selector-pseudo`,variants:[{begin:`:(`+gt.join(`|`)+`)`},{begin:`:(:)?(`+_t.join(`|`)+`)`}]},n.CSS_VARIABLE,{className:`attribute`,begin:`\\b(`+vt.join(`|`)+`)\\b`},{begin:/:/,end:/[;}{]/,contains:[n.BLOCK_COMMENT,n.HEXCOLOR,n.IMPORTANT,n.CSS_NUMBER_MODE,...a,{begin:/(url|data-uri)\(/,end:/\)/,relevance:0,keywords:{built_in:`url data-uri`},contains:[...a,{className:`string`,begin:/[^)]/,endsWithParent:!0,excludeEnd:!0}]},n.FUNCTION_DISPATCH]},{begin:t.lookahead(/@/),end:`[{;]`,relevance:0,illegal:/:/,contains:[{className:`keyword`,begin:i},{begin:/\s/,endsWithParent:!0,excludeEnd:!0,relevance:0,keywords:{$pattern:/[a-z-]+/,keyword:`and or not only`,attribute:ht.join(` `)},contains:[{begin:/[a-z-]+(?=:)/,className:`attribute`},...a,n.CSS_NUMBER_MODE]}]},{className:`selector-tag`,begin:`\\b(`+mt.join(`|`)+`)\\b`}]}}function bt(e){let t=`true false yes no null`,n={className:`attr`,variants:[{begin:/[\w*@][\w*@ :()\./-]*:(?=[ \t]|$)/},{begin:/"[\w*@][\w*@ :()\./-]*":(?=[ \t]|$)/},{begin:/'[\w*@][\w*@ :()\./-]*':(?=[ \t]|$)/}]},r={className:`template-variable`,variants:[{begin:/\{\{/,end:/\}\}/},{begin:/%\{/,end:/\}/}]},i={className:`string`,relevance:0,begin:/'/,end:/'/,contains:[{match:/''/,scope:`char.escape`,relevance:0}]},a={className:`string`,relevance:0,variants:[{begin:/"/,end:/"/},{begin:/\S+/}],contains:[e.BACKSLASH_ESCAPE,r]},o=e.inherit(a,{variants:[{begin:/'/,end:/'/,contains:[{begin:/''/,relevance:0}]},{begin:/"/,end:/"/},{begin:/[^\s,{}[\]]+/}]}),s={className:`number`,begin:`\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b`},c={end:`,`,endsWithParent:!0,excludeEnd:!0,keywords:t,relevance:0},l={begin:/\{/,end:/\}/,contains:[c],illegal:`\\n`,relevance:0},u={begin:`\\[`,end:`\\]`,contains:[c],illegal:`\\n`,relevance:0},d=[n,{className:`meta`,begin:`^---\\s*$`,relevance:10},{className:`string`,begin:`[\\|>]([1-9]?[+-])?[ ]*\\n( +)[^ ][^\\n]*\\n(\\2[^\\n]+\\n?)*`},{begin:`<%[%=-]?`,end:`[%-]?%>`,subLanguage:`ruby`,excludeBegin:!0,excludeEnd:!0,relevance:0},{className:`type`,begin:`!\\w+![\\w#;/?:@&=+$,.~*'()[\\]]+`},{className:`type`,begin:`!<[\\w#;/?:@&=+$,.~*'()[\\]]+>`},{className:`type`,begin:`![\\w#;/?:@&=+$,.~*'()[\\]]+`},{className:`type`,begin:`!![\\w#;/?:@&=+$,.~*'()[\\]]+`},{className:`meta`,begin:`&`+e.UNDERSCORE_IDENT_RE+`$`},{className:`meta`,begin:`\\*`+e.UNDERSCORE_IDENT_RE+`$`},{className:`bullet`,begin:`-(?=[ ]|$)`,relevance:0},e.HASH_COMMENT_MODE,{beginKeywords:t,keywords:{literal:t}},s,{className:`number`,begin:e.C_NUMBER_RE+`\\b`,relevance:0},l,u,i,a],f=[...d];return f.pop(),f.push(o),c.contains=f,{name:`YAML`,case_insensitive:!0,aliases:[`yml`],contains:d}}N.registerLanguage(`javascript`,ve),N.registerLanguage(`typescript`,lt),N.registerLanguage(`python`,be),N.registerLanguage(`json`,ye),N.registerLanguage(`bash`,xe),N.registerLanguage(`xml`,ut),N.registerLanguage(`css`,yt),N.registerLanguage(`yaml`,bt);var xt={js:`javascript`,ts:`typescript`,py:`python`,sh:`bash`,shell:`bash`,yml:`yaml`,html:`xml`};function St(e){return e.replace(/&/g,`&`).replace(//g,`>`)}function Ct(e,t){let n=xt[(t||``).toLowerCase()]||(t||``).toLowerCase();if(n&&N.getLanguage(n))try{return N.highlight(e,{language:n,ignoreIllegals:!0}).value}catch{}return St(e)}var wt=N,Tt={};function Et(e){let t=Tt[e];if(t)return t;t=Tt[e]=[];for(let e=0;e<128;e++){let n=String.fromCharCode(e);t.push(n)}for(let n=0;n=55296&&e<=57343?`���`:String.fromCharCode(e),r+=6;continue}}if((a&248)==240&&r+91114111?t+=`����`:(e-=65536,t+=String.fromCharCode(55296+(e>>10),56320+(e&1023))),r+=9;continue}}t+=`�`}return t})}P.defaultChars=`;/?:@&=+$,#`,P.componentChars=``;var Dt={};function Ot(e){let t=Dt[e];if(t)return t;t=Dt[e]=[];for(let e=0;e<128;e++){let n=String.fromCharCode(e);/^[0-9a-z]$/i.test(n)?t.push(n):t.push(`%`+(`0`+e.toString(16).toUpperCase()).slice(-2))}for(let n=0;n=55296&&o<=57343){if(o>=55296&&o<=56319&&t+1=56320&&n<=57343){i+=encodeURIComponent(e[t]+e[t+1]),t++;continue}}i+=`%EF%BF%BD`;continue}i+=encodeURIComponent(e[t])}return i}F.defaultChars=`;/?:@&=+$,-_.!~*'()#`,F.componentChars=`-_.!~*'()`;function kt(e){let t=``;return t+=e.protocol||``,t+=e.slashes?`//`:``,t+=e.auth?e.auth+`@`:``,e.hostname&&e.hostname.indexOf(`:`)!==-1?t+=`[`+e.hostname+`]`:t+=e.hostname||``,t+=e.port?`:`+e.port:``,t+=e.pathname||``,t+=e.search||``,t+=e.hash||``,t}function At(){this.protocol=null,this.slashes=null,this.auth=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.pathname=null}var jt=/^([a-z0-9.+-]+:)/i,Mt=/:[0-9]*$/,Nt=/^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,Pt=[`%`,`/`,`?`,`;`,`#`,`'`,`{`,`}`,`|`,`\\`,`^`,"`",`<`,`>`,`"`,"`",` `,`\r`,` -`,` `],Ft=[`/`,`?`,`#`],It=255,Lt=/^[+a-z0-9A-Z_-]{0,63}$/,Rt=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,zt={javascript:!0,"javascript:":!0},Bt={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0};function Vt(e,t){if(e&&e instanceof At)return e;let n=new At;return n.parse(e,t),n}At.prototype.parse=function(e,t){let n,r,i,a=e;if(a=a.trim(),!t&&e.split(`#`).length===1){let e=Nt.exec(a);if(e)return this.pathname=e[1],e[2]&&(this.search=e[2]),this}let o=jt.exec(a);if(o&&(o=o[0],n=o.toLowerCase(),this.protocol=o,a=a.substr(o.length)),(t||o||a.match(/^\/\/[^@\/]+@[^@\/]+/))&&(i=a.substr(0,2)===`//`,i&&!(o&&zt[o])&&(a=a.substr(2),this.slashes=!0)),!zt[o]&&(i||o&&!Bt[o])){let e=-1;for(let t=0;t127?r+=`x`:r+=n[e];if(!r.match(Lt)){let r=e.slice(0,t),i=e.slice(t+1),o=n.match(Rt);o&&(r.push(o[1]),i.unshift(o[2])),i.length&&(a=i.join(`.`)+a),this.hostname=r.join(`.`);break}}}}this.hostname.length>It&&(this.hostname=``),o&&(this.hostname=this.hostname.substr(1,this.hostname.length-2))}let s=a.indexOf(`#`);s!==-1&&(this.hash=a.substr(s),a=a.slice(0,s));let c=a.indexOf(`?`);return c!==-1&&(this.search=a.substr(c),a=a.slice(0,c)),a&&(this.pathname=a),Bt[n]&&this.hostname&&!this.pathname&&(this.pathname=``),this},At.prototype.parseHost=function(e){let t=Mt.exec(e);t&&(t=t[0],t!==`:`&&(this.port=t.substr(1)),e=e.substr(0,e.length-t.length)),e&&(this.hostname=e)};var Ht=e({decode:()=>P,encode:()=>F,format:()=>kt,parse:()=>Vt}),Ut=e({Any:()=>Wt,Cc:()=>Gt,Cf:()=>Kt,P:()=>qt,S:()=>Jt,Z:()=>Yt}),Wt=/[\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,Gt=/[\0-\x1F\x7F-\x9F]/,Kt=/[\xAD\u0600-\u0605\u061C\u06DD\u070F\u0890\u0891\u08E2\u180E\u200B-\u200F\u202A-\u202E\u2060-\u2064\u2066-\u206F\uFEFF\uFFF9-\uFFFB]|\uD804[\uDCBD\uDCCD]|\uD80D[\uDC30-\uDC3F]|\uD82F[\uDCA0-\uDCA3]|\uD834[\uDD73-\uDD7A]|\uDB40[\uDC01\uDC20-\uDC7F]/,qt=/[!-#%-\*,-\/:;\?@\[-\]_\{\}\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B4E\u1B4F\u1B5A-\u1B60\u1B7D-\u1B7F\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD803[\uDD6E\uDEAD\uDED0\uDF55-\uDF59\uDF86-\uDF89]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9\uDFD4\uDFD5\uDFD7\uDFD8]|\uD805[\uDC4B-\uDC4F\uDC5A\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDEB9\uDF3C-\uDF3E]|\uD806[\uDC3B\uDD44-\uDD46\uDDE2\uDE3F-\uDE46\uDE9A-\uDE9C\uDE9E-\uDEA2\uDF00-\uDF09\uDFE1]|\uD807[\uDC41-\uDC45\uDC70\uDC71\uDEF7\uDEF8\uDF43-\uDF4F\uDFFF]|\uD809[\uDC70-\uDC74]|\uD80B[\uDFF1\uDFF2]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD81B[\uDD6D-\uDD6F\uDE97-\uDE9A\uDFE2]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]|\uD839\uDDFF|\uD83A[\uDD5E\uDD5F]/,Jt=/[\$\+<->\^`\|~\xA2-\xA6\xA8\xA9\xAC\xAE-\xB1\xB4\xB8\xD7\xF7\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0384\u0385\u03F6\u0482\u058D-\u058F\u0606-\u0608\u060B\u060E\u060F\u06DE\u06E9\u06FD\u06FE\u07F6\u07FE\u07FF\u0888\u09F2\u09F3\u09FA\u09FB\u0AF1\u0B70\u0BF3-\u0BFA\u0C7F\u0D4F\u0D79\u0E3F\u0F01-\u0F03\u0F13\u0F15-\u0F17\u0F1A-\u0F1F\u0F34\u0F36\u0F38\u0FBE-\u0FC5\u0FC7-\u0FCC\u0FCE\u0FCF\u0FD5-\u0FD8\u109E\u109F\u1390-\u1399\u166D\u17DB\u1940\u19DE-\u19FF\u1B61-\u1B6A\u1B74-\u1B7C\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD\u1FFE\u2044\u2052\u207A-\u207C\u208A-\u208C\u20A0-\u20C1\u2100\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F\u218A\u218B\u2190-\u2307\u230C-\u2328\u232B-\u2429\u2440-\u244A\u249C-\u24E9\u2500-\u2767\u2794-\u27C4\u27C7-\u27E5\u27F0-\u2982\u2999-\u29D7\u29DC-\u29FB\u29FE-\u2B73\u2B76-\u2BFF\u2CE5-\u2CEA\u2E50\u2E51\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFF\u3004\u3012\u3013\u3020\u3036\u3037\u303E\u303F\u309B\u309C\u3190\u3191\u3196-\u319F\u31C0-\u31E5\u31EF\u3200-\u321E\u322A-\u3247\u3250\u3260-\u327F\u328A-\u32B0\u32C0-\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA700-\uA716\uA720\uA721\uA789\uA78A\uA828-\uA82B\uA836-\uA839\uAA77-\uAA79\uAB5B\uAB6A\uAB6B\uFB29\uFBB2-\uFBD2\uFD40-\uFD4F\uFD90\uFD91\uFDC8-\uFDCF\uFDFC-\uFDFF\uFE62\uFE64-\uFE66\uFE69\uFF04\uFF0B\uFF1C-\uFF1E\uFF3E\uFF40\uFF5C\uFF5E\uFFE0-\uFFE6\uFFE8-\uFFEE\uFFFC\uFFFD]|\uD800[\uDD37-\uDD3F\uDD79-\uDD89\uDD8C-\uDD8E\uDD90-\uDD9C\uDDA0\uDDD0-\uDDFC]|\uD802[\uDC77\uDC78\uDEC8]|\uD803[\uDD8E\uDD8F\uDED1-\uDED8]|\uD805\uDF3F|\uD807[\uDFD5-\uDFF1]|\uD81A[\uDF3C-\uDF3F\uDF45]|\uD82F\uDC9C|\uD833[\uDC00-\uDCEF\uDCFA-\uDCFC\uDD00-\uDEB3\uDEBA-\uDED0\uDEE0-\uDEF0\uDF50-\uDFC3]|\uD834[\uDC00-\uDCF5\uDD00-\uDD26\uDD29-\uDD64\uDD6A-\uDD6C\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDDEA\uDE00-\uDE41\uDE45\uDF00-\uDF56]|\uD835[\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85\uDE86]|\uD838[\uDD4F\uDEFF]|\uD83B[\uDCAC\uDCB0\uDD2E\uDEF0\uDEF1]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBF\uDCC1-\uDCCF\uDCD1-\uDCF5\uDD0D-\uDDAD\uDDE6-\uDE02\uDE10-\uDE3B\uDE40-\uDE48\uDE50\uDE51\uDE60-\uDE65\uDF00-\uDFFF]|\uD83D[\uDC00-\uDED8\uDEDC-\uDEEC\uDEF0-\uDEFC\uDF00-\uDFD9\uDFE0-\uDFEB\uDFF0]|\uD83E[\uDC00-\uDC0B\uDC10-\uDC47\uDC50-\uDC59\uDC60-\uDC87\uDC90-\uDCAD\uDCB0-\uDCBB\uDCC0\uDCC1\uDCD0-\uDCD8\uDD00-\uDE57\uDE60-\uDE6D\uDE70-\uDE7C\uDE80-\uDE8A\uDE8E-\uDEC6\uDEC8\uDECD-\uDEDC\uDEDF-\uDEEA\uDEEF-\uDEF8\uDF00-\uDF92\uDF94-\uDFEF\uDFFA]/,Yt=/[ \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]/,Xt=new Map([[0,65533],[128,8364],[130,8218],[131,402],[132,8222],[133,8230],[134,8224],[135,8225],[136,710],[137,8240],[138,352],[139,8249],[140,338],[142,381],[145,8216],[146,8217],[147,8220],[148,8221],[149,8226],[150,8211],[151,8212],[152,732],[153,8482],[154,353],[155,8250],[156,339],[158,382],[159,376]]);function Zt(e){return e>=55296&&e<=57343||e>1114111?65533:Xt.get(e)??e}function Qt(e){let t=atob(e),n=t.length&-2,r=new Uint16Array(n/2);for(let e=0,i=0;e=L.ZERO&&e<=L.NINE}function nn(e){return e>=L.UPPER_A&&e<=L.UPPER_F||e>=L.LOWER_A&&e<=L.LOWER_F}function rn(e){return e>=L.UPPER_A&&e<=L.UPPER_Z||e>=L.LOWER_A&&e<=L.LOWER_Z||tn(e)}function an(e){return e===L.EQUALS||rn(e)}var R;(function(e){e[e.EntityStart=0]=`EntityStart`,e[e.NumericStart=1]=`NumericStart`,e[e.NumericDecimal=2]=`NumericDecimal`,e[e.NumericHex=3]=`NumericHex`,e[e.NamedEntity=4]=`NamedEntity`})(R||={});var z;(function(e){e[e.Legacy=0]=`Legacy`,e[e.Strict=1]=`Strict`,e[e.Attribute=2]=`Attribute`})(z||={});var on=class{decodeTree;emitCodePoint;errors;constructor(e,t,n){this.decodeTree=e,this.emitCodePoint=t,this.errors=n}state=R.EntityStart;consumed=1;result=0;treeIndex=0;excess=1;decodeMode=z.Strict;runConsumed=0;startEntity(e){this.decodeMode=e,this.state=R.EntityStart,this.result=0,this.treeIndex=0,this.excess=1,this.consumed=1,this.runConsumed=0}write(e,t){switch(this.state){case R.EntityStart:return e.charCodeAt(t)===L.NUM?(this.state=R.NumericStart,this.consumed+=1,this.stateNumericStart(e,t+1)):(this.state=R.NamedEntity,this.stateNamedEntity(e,t));case R.NumericStart:return this.stateNumericStart(e,t);case R.NumericDecimal:return this.stateNumericDecimal(e,t);case R.NumericHex:return this.stateNumericHex(e,t);case R.NamedEntity:return this.stateNamedEntity(e,t)}}stateNumericStart(e,t){return t>=e.length?-1:(e.charCodeAt(t)|en)===L.LOWER_X?(this.state=R.NumericHex,this.consumed+=1,this.stateNumericHex(e,t+1)):(this.state=R.NumericDecimal,this.stateNumericDecimal(e,t))}stateNumericHex(e,t){for(;t>14;for(;t>7;if(this.runConsumed===0){let n=r&I.JUMP_TABLE;if(e.charCodeAt(t)!==n)return this.result===0?0:this.emitNotTerminatedNamedEntity();t++,this.excess++,this.runConsumed++}for(;this.runConsumed=e.length)return-1;let r=this.runConsumed-1,i=n[this.treeIndex+1+(r>>1)],a=r%2==0?i&255:i>>8&255;if(e.charCodeAt(t)!==a)return this.runConsumed=0,this.result===0?0:this.emitNotTerminatedNamedEntity();t++,this.excess++,this.runConsumed++}this.runConsumed=0,this.treeIndex+=1+(a>>1),r=n[this.treeIndex],i=(r&I.VALUE_LENGTH)>>14}if(t>=e.length)break;let a=e.charCodeAt(t);if(a===L.SEMI&&i!==0&&(r&I.FLAG13)!==0)return this.emitNamedEntityData(this.treeIndex,i,this.consumed+this.excess);if(this.treeIndex=cn(n,r,this.treeIndex+Math.max(1,i),a),this.treeIndex<0)return this.result===0||this.decodeMode===z.Attribute&&(i===0||an(a))?0:this.emitNotTerminatedNamedEntity();if(r=n[this.treeIndex],i=(r&I.VALUE_LENGTH)>>14,i!==0){if(a===L.SEMI)return this.emitNamedEntityData(this.treeIndex,i,this.consumed+this.excess);this.decodeMode!==z.Strict&&(r&I.FLAG13)===0&&(this.result=this.treeIndex,this.consumed+=this.excess,this.excess=0)}t++,this.excess++}return-1}emitNotTerminatedNamedEntity(){let{result:e,decodeTree:t}=this,n=(t[e]&I.VALUE_LENGTH)>>14;return this.emitNamedEntityData(e,n,this.consumed),this.errors?.missingSemicolonAfterCharacterReference(),this.consumed}emitNamedEntityData(e,t,n){let{decodeTree:r}=this;return this.emitCodePoint(t===1?r[e]&~(I.VALUE_LENGTH|I.FLAG13):r[e+1],n),t===3&&this.emitCodePoint(r[e+2],n),n}end(){switch(this.state){case R.NamedEntity:return this.result!==0&&(this.decodeMode!==z.Attribute||this.result===this.treeIndex)?this.emitNotTerminatedNamedEntity():0;case R.NumericDecimal:return this.emitNumericEntity(0,2);case R.NumericHex:return this.emitNumericEntity(0,3);case R.NumericStart:return this.errors?.absenceOfDigitsInNumericCharacterReference(this.consumed),0;case R.EntityStart:return 0}}};function sn(e){let t=``,n=new on(e,e=>t+=String.fromCodePoint(e));return function(e,r){let i=0,a=0;for(;(a=e.indexOf(`&`,a))>=0;){t+=e.slice(i,a),n.startEntity(r);let o=n.write(e,a+1);if(o<0){i=a+n.end();break}i=a+o,a=o===0?i+1:i}let o=t+e.slice(i);return t=``,o}}function cn(e,t,n,r){let i=(t&I.BRANCH_LENGTH)>>7,a=t&I.JUMP_TABLE;if(i===0)return a!==0&&r===a?n:-1;if(a){let t=r-a;return t<0||t>=i?-1:e[n+t]-1}let o=i+1>>1,s=0,c=i-1;for(;s<=c;){let t=s+c>>>1,i=e[n+(t>>1)]>>(t&1)*8&255;if(ir)c=t-1;else return e[n+o+t]}return-1}var ln=sn($t);function un(e){return ln(e,z.Strict)}var dn=class{src_Any=Wt.source;src_Cc=Gt.source;src_Z=Yt.source;src_P=qt.source;src_ZPCc=[this.src_Z,this.src_P,this.src_Cc].join(`|`);src_ZCc=[this.src_Z,this.src_Cc].join(`|`);cache={};opts={maxLength:1e4,urlAuth:!1,schema_names:[]};constructor(e={}){this.opts={...this.opts,...e}}set(e={}){return this.opts={...this.opts,...e},this.cache={},this}escapeRE(e){return e.replace(/[.?*+^$[\]\\(){}|-]/g,`\\$&`)}nestedPairRE(e,t,n=4){let r=this.escapeRE(e),i=this.escapeRE(t),a=`(?:(?!${this.src_ZCc}|${r}|${i}).)`,o=`${r}${a}{0,1000}${i}`;for(let e=2;e<=n;e++)o=`${r}(?:${a}|${o}){0,1000}${i}`;return o}get_text_separators(){return this.cache.text_separators??=/[><\uff5c]/}get_pseudo_letter(){return this.cache.src_pseudo_letter??=RegExp(`(?:(?!${this.get_text_separators().source}|${this.src_ZPCc})${this.src_Any})`)}get_ipv4_addr(){return this.cache.src_ip4??=RegExp(`(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])[.]){3}(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])`)}get_ipv6_addr(){let e=`[0-9A-Fa-f]{1,4}`,t=`(?:(?:${e}:${e})|${this.get_ipv4_addr().source})`;return this.cache.src_ip6_addr??=RegExp(`(?:(?:${e}:){6}${t}|::(?:${e}:){5}${t}|(?:${e})?::(?:${e}:){4}${t}|(?:(?:${e}:){0,1}${e})?::(?:${e}:){3}${t}|(?:(?:${e}:){0,2}${e})?::(?:${e}:){2}${t}|(?:(?:${e}:){0,3}${e})?::${e}:${t}|(?:(?:${e}:){0,4}${e})?::${t}|(?:(?:${e}:){0,5}${e})?::${e}|(?:(?:${e}:){0,6}${e})?::)`)}get_ipv6_url_host(){return this.cache.src_ip6_host??=RegExp(`\\[${this.get_ipv6_addr().source}\\]`)}get_ipv6_mail_host(){return this.cache.src_ipv6_mail_host??=RegExp(`\\[IPv6:${this.get_ipv6_addr().source}\\]`)}get_auth(){return this.cache.src_auth??=RegExp(`(?:(?:(?!${this.src_ZCc}|[@/\\[\\]()]).){1,50}@)?`)}get_port(){return this.cache.src_port??=RegExp(`(?::(?:6(?:[0-4]\\d{3}|5(?:[0-4]\\d{2}|5(?:[0-2]\\d|3[0-5])))|[1-5]?\\d{1,4}))?`)}get_host_terminator(){return this.cache.src_host_terminator??=RegExp(`(?=$|${this.get_text_separators().source}|${this.src_ZPCc})(?!${this.opts[`---`]?`-(?!--)|`:`-|`}_|:\\d|\\.-|\\.(?!$|${this.src_ZPCc}))`)}get_path_terminator(){return this.cache.src_path_terminator??=RegExp(`${this.src_ZPCc}|${this.get_text_separators().source}`)}get_path(){return this.cache.src_path??=RegExp(`(?:[/?#](?:${this.nestedPairRE(`[`,`]`)}|${this.nestedPairRE(`(`,`)`)}|${this.nestedPairRE(`{`,`}`)}|\\"(?:(?!${this.src_ZCc}|["]).){1,100}\\"|\\'(?:(?!${this.src_ZCc}|[']).){1,100}\\'|\\'(?=${this.get_pseudo_letter().source}|[-])|\\.{2,20}[:]?[a-zA-Z0-9%/&]|\\.(?!${this.src_ZCc}|[.]|$)|`+(this.opts[`---`]?`\\-(?!--(?:[^-]|$))(?:-{0,19})|`:`\\-{1,20}|`)+`,(?!${this.src_ZCc}|$)|;(?!${this.src_ZCc}|$)|\\!{1,20}(?!${this.src_ZCc}|[!]|$)|\\?(?!${this.src_ZCc}|[?]|$)|`+this.get_path_extra().source+`[\\\\/:%@#&=_~*]|(?!${this.get_path_terminator().source}).){1,${this.opts.maxLength}}|\\/)?`)}get_mail_name(){return this.cache.src_mail_name??=RegExp("[-!#$%&'*+/=?^_`{|}~a-zA-Z0-9](?:[-!#$%&'*+/=?^_`{|}~a-zA-Z0-9]|[.](?=[-!#$%&'*+/=?^_`{|}~a-zA-Z0-9])){0,63}")}get_xn(){return this.cache.src_xn??=RegExp(`xn--[a-z0-9\\-]{1,59}`)}get_tld(){if(this.cache.tld)return this.cache.tld;let e=[...new Set(this.opts.tlds||[])].sort().reverse().join(`|`);return this.cache.tld=RegExp(`${e||`$#none#$`}|${this.get_xn().source}`),this.cache.tld}get_domain_root(){return this.cache.src_domain_root??=RegExp(`(?:`+this.get_xn().source+`|${this.get_pseudo_letter().source}{1,63})`)}get_domain(){return this.cache.src_domain??=RegExp(`(?:`+this.get_xn().source+`|(?:${this.get_pseudo_letter().source})|(?:${this.get_pseudo_letter().source}(?:-|${this.get_pseudo_letter().source}){0,61}${this.get_pseudo_letter().source}))`)}get_url_host_port(){return this.cache.url_host_port??=RegExp(`(?:`+this.get_ipv6_url_host().source+`|(?:(?:(?:${this.get_domain().source})\\.){0,10}${this.get_domain().source}))`+this.get_port().source+this.get_host_terminator().source)}get_fuzzy_url_host_port(){return this.cache.fuzzy_url_host_port??=RegExp(`(?:`+(this.opts.fuzzyIP?this.get_ipv4_addr().source+`|`:``)+`(?:(?:(?:${this.get_domain().source})\\.){1,10}(?:${this.get_tld().source})))`+this.get_host_terminator().source)}get_mail_host(){return this.cache.src_mail_host??=RegExp(`(?:`+this.get_ipv6_mail_host().source+`|(?:(?:(?:${this.get_domain().source})\\.){0,4}${this.get_domain().source}))`+this.get_host_terminator().source)}get_fuzzy_mail_host(){return this.cache.src_fuzzy_mail_host??=RegExp(`(?:`+this.get_ipv6_mail_host().source+`|(?:(?:(?:${this.get_domain().source})[.]){1,4}${this.get_domain_root().source}))`+this.get_host_terminator().source)}get_path_extra(){return this.cache.src_path_extra??=RegExp(``)}get_fuzzy_mail_host_search(){return this.cache.mail_fuzzy_host_search??=RegExp(`@${this.get_fuzzy_mail_host().source}`,`ig`)}get_fuzzy_link_search(){return this.cache.link_fuzzy_search??=RegExp(`(^|(?![.:/\\-_@])(?:[$+<=>^\`|\uff5c]|${this.src_ZPCc}))(?:(?![$+<=>^\`|\uff5c])${this.get_fuzzy_url_host_port().source}${this.get_path().source})`,`ig`)}get_http_validator(){return this.cache.http_validator??=RegExp(`\\/\\/`+(this.opts.urlAuth?this.get_auth().source:``)+this.get_url_host_port().source+this.get_path().source,`iy`)}get_relative_proto_validator(){return this.cache.relative_proto_validator??=RegExp((this.opts.urlAuth?this.get_auth().source:``)+`(?:localhost|${this.get_ipv6_url_host().source}|(?:(?:${this.get_domain().source})[.]){1,10}${this.get_domain_root().source})`+this.get_port().source+this.get_host_terminator().source+this.get_path().source,`iy`)}get_mail_name_validator(){return this.cache.mail_name_validator??=RegExp(`(?:^|${this.get_text_separators().source}|"|\\(|${this.src_ZCc})(${this.get_mail_name().source})$`)}get_mailto_validator(){return this.cache.mailto_validator??=RegExp(`${this.get_mail_name().source}@${this.get_mail_host().source}`,`iy`)}get_schema_names(){return this.cache.schema_names??=new RegExp((this.opts.schema_names||[]).map(e=>this.escapeRE(e)).join(`|`))}get_schema_search(){return this.cache.schema_search??=RegExp(`(^|(?!_)(?:[><\uff5c]|${this.src_ZPCc}))(${this.get_schema_names().source})`,`ig`)}get_schema_at_start(){return this.cache.schema_at_start??=RegExp(`^${this.get_schema_search().source}`,`i`)}},fn={validate:(e,t,n)=>{let r=n.re.get_http_validator();r.lastIndex=t;let i=r.exec(e);return i?i[0].length:0},normalize:(e,t)=>t.normalize(e)},pn={"http:":fn,"https:":fn,"ftp:":fn,"//":{validate:function(e,t,n){let r=n.re.get_relative_proto_validator();r.lastIndex=t;let i=r.exec(e);return i?t>=3&&e[t-3]===`:`||t>=3&&e[t-3]===`/`?0:i[0].length:0},normalize:(e,t)=>t.normalize(e)},"mailto:":{validate:function(e,t,n){let r=n.re.get_mailto_validator();r.lastIndex=t;let i=r.exec(e);return i?i[0].length:0},normalize:(e,t)=>t.normalize(e)}},mn=`a:cdefgilmnoqrstuwxz|b:abdefghijmnorstvwyz|c:acdfghiklmnoruvwxyz|d:ejkmoz|e:cegrstu|f:ijkmor|g:abdefghilmnpqrstuwy|h:kmnrtu|i:delmnoqrst|j:emop|k:eghimnprwyz|l:abcikrstuvy|m:acdeghklmnopqrstuvwxyz|n:acefgilopruz|o:m|p:aefghklmnrstwy|q:a|r:eosuw|s:abcdeghijklmnortuvxyz|t:cdfghjklmnortvwz|u:agksyz|v:aceginu|w:fs|y:et|z:amw`,hn=`biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|рф`;function gn(){let e=hn.split(`|`);return mn.split(`|`).forEach(t=>{let n=t.indexOf(`:`),r=t.slice(0,n);for(let i of t.slice(n+1))e.push(r+i)}),e}var _n={fuzzyLink:!1,fuzzyEmail:!0,fuzzyIP:!1,"---":!1,tlds:gn(),urlAuth:!1,maxLength:1e4},vn=class{schema;index;lastIndex;raw;text;url;constructor(e,t,n,r){let i=e.slice(n,r);this.schema=t.toLowerCase(),this.index=n,this.lastIndex=r,this.raw=i,this.text=i,this.url=i}},yn=class{__opts__;__schemas__;re;constructor(e={}){let{rebuilder:t,...n}=e;this.__opts__={..._n,...n},this.__schemas__={...pn},this.re=t||new dn,this.re.set({...this.__opts__,schema_names:Object.keys(this.__schemas__)})}add(e,t=null){if(!t)delete this.__schemas__[e];else{let n={normalize:(e,t)=>t.normalize(e),...t};this.__schemas__[e]=n}return this.re.set({...this.__opts__,schema_names:Object.keys(this.__schemas__)}),this}set(e={}){return this.__opts__={...this.__opts__,...e},this.re.set({...this.__opts__,schema_names:Object.keys(this.__schemas__)}),this}test(e){if(!e.length)return!1;let t,n;for(n=this.re.get_schema_search(),n.lastIndex=0;(t=n.exec(e))!==null;)if(this.testSchemaAt(e,t[2],n.lastIndex))return!0;if(this.__opts__.fuzzyLink&&this.__schemas__[`http:`]&&(n=this.re.get_fuzzy_link_search(),n.lastIndex=0,n.exec(e)!==null))return!0;if(this.__opts__.fuzzyEmail&&this.__schemas__[`mailto:`]&&e.indexOf(`@`)>=0){let n=this.re.get_fuzzy_mail_host_search(),r=this.re.get_mail_name_validator();for(n.lastIndex=0;(t=n.exec(e))!==null;){let n=e.slice(Math.max(0,t.index-65),t.index);if(r.test(n))return!0}}return!1}testSchemaAt(e,t,n){return this.__schemas__[t.toLowerCase()]?this.__schemas__[t.toLowerCase()].validate(e.slice(0,n+this.__opts__.maxLength),n,this):0}match(e){let t=[],n=this.re.get_schema_search(),r,i,a,o,s,c,l=!1,u=!1,d=!1,f=0;if(!e.length)return null;for(n.lastIndex=0,this.__opts__.fuzzyLink&&this.__schemas__[`http:`]&&(r=this.re.get_fuzzy_link_search(),r.lastIndex=0),this.__opts__.fuzzyEmail&&this.__schemas__[`mailto:`]&&(i=this.re.get_fuzzy_mail_host_search(),i.lastIndex=0,a=this.re.get_mail_name_validator());;){let p=Math.max(f-1,0);if(i&&a&&!d&&(!s||s.index=f)break;i.lastIndex=f)break;r.lastIndexm.lastIndex))&&(m=o);let h;if(!l)for(;;){if(!c){n.lastIndexm.index)break;let t=c;c=void 0;let r=this.testSchemaAt(e,t.schema,t.lastIndex);if(r){h={schema:t.schema,index:t.index,lastIndex:t.lastIndex+r};break}}let g=h;if((!g||s&&(s.indexg.lastIndex))&&(g=s),(!g||o&&(o.indexg.lastIndex))&&(g=o),!g)break;g===s?s=void 0:g===o&&(o=void 0);let _=new vn(e,g.schema,g.index,g.lastIndex);_.schema?this.__schemas__[_.schema].normalize(_,this):this.normalize(_),t.push(_),f=g.lastIndex}return t.length?t:null}matchAtStart(e){if(!e.length)return null;let t=this.re.get_schema_at_start().exec(e);if(!t)return null;let n=this.testSchemaAt(e,t[2],t[0].length);if(!n)return null;let r=new vn(e,t[2],t.index+t[1].length,t.index+t[0].length+n);return this.__schemas__[r.schema].normalize(r,this),r}tlds(e,t=!1){return e=Array.isArray(e)?e:[e],t?this.__opts__.tlds=this.__opts__.tlds.concat(e):this.__opts__.tlds=e,this.re.set({...this.__opts__,schema_names:Object.keys(this.__schemas__)}),this}normalize(e){e.schema||(e.url=`http://${e.url}`),e.schema===`mailto:`&&!/^mailto:/i.test(e.url)&&(e.url=`mailto:${e.url}`)}},B=2147483647,V=36,bn=1,xn=26,Sn=38,Cn=700,wn=72,Tn=128,En=`-`,Dn=/^xn--/,On=/[^\0-\x7F]/,kn=/[\x2E\u3002\uFF0E\uFF61]/g,An={overflow:`Overflow: input needs wider integers to process`,"not-basic":`Illegal input >= 0x80 (not a basic code point)`,"invalid-input":`Invalid input`},jn=35,H=Math.floor,Mn=String.fromCharCode;function U(e){throw RangeError(An[e])}function Nn(e,t){let n=[],r=e.length;for(;r--;)n[r]=t(e[r]);return n}function Pn(e,t){let n=e.split(`@`),r=``;n.length>1&&(r=n[0]+`@`,e=n[1]),e=e.replace(kn,`.`);let i=Nn(e.split(`.`),t).join(`.`);return r+i}function Fn(e){let t=[],n=0,r=e.length;for(;n=55296&&i<=56319&&nString.fromCodePoint(...e),Ln=function(e){return e>=48&&e<58?26+(e-48):e>=65&&e<91?e-65:e>=97&&e<123?e-97:V},Rn=function(e,t){return e+22+75*(e<26)-((t!=0)<<5)},zn=function(e,t,n){let r=0;for(e=n?H(e/Cn):e>>1,e+=H(e/t);e>455;r+=V)e=H(e/jn);return H(r+36*e/(e+Sn))},Bn=function(e){let t=[],n=e.length,r=0,i=Tn,a=wn,o=e.lastIndexOf(En);o<0&&(o=0);for(let n=0;n=128&&U(`not-basic`),t.push(e.charCodeAt(n));for(let s=o>0?o+1:0;s=n&&U(`invalid-input`);let o=Ln(e.charCodeAt(s++));o>=V&&U(`invalid-input`),o>H((B-r)/t)&&U(`overflow`),r+=o*t;let c=i<=a?bn:i>=a+xn?xn:i-a;if(oH(B/l)&&U(`overflow`),t*=l}let c=t.length+1;a=zn(r-o,c,o==0),H(r/c)>B-i&&U(`overflow`),i+=H(r/c),r%=c,t.splice(r++,0,i)}return String.fromCodePoint(...t)},Vn=function(e){let t=[];e=Fn(e);let n=e.length,r=Tn,i=0,a=wn;for(let n of e)n<128&&t.push(Mn(n));let o=t.length,s=o;for(o&&t.push(En);s=r&&tH((B-i)/c)&&U(`overflow`),i+=(n-r)*c,r=n;for(let n of e)if(nB&&U(`overflow`),n===r){let e=i;for(let n=V;;n+=V){let r=n<=a?bn:n>=a+xn?xn:n-a;if(e{let n={};for(var r in e)Un(n,r,{get:e[r],enumerable:!0});return t||Un(n,Symbol.toStringTag,{value:`Module`}),n},Gn=Wn({arrayReplaceAt:()=>qn,asciiTrim:()=>dr,callable:()=>Kn,escapeHtml:()=>K,escapeRE:()=>ar,fromCodePoint:()=>W,isMdAsciiPunct:()=>cr,isPunctChar:()=>or,isPunctCharCode:()=>sr,isSpace:()=>q,isValidEntityCode:()=>Jn,isWhiteSpace:()=>J,lib:()=>fr,normalizeReference:()=>lr,unescapeAll:()=>G,unescapeMd:()=>$n});function Kn(e){let t=function(...n){return Reflect.construct(e,n,new.target&&new.target!==t?new.target:e)};return Object.defineProperty(t,"name",{value:e.name}),Object.setPrototypeOf(t,e),t.prototype=e.prototype,t}function qn(e,t,n){return[].concat(e.slice(0,t),n,e.slice(t+1))}function Jn(e){return!(e>=55296&&e<=57343||e>=64976&&e<=65007||(e&65535)==65535||(e&65535)==65534||e>=0&&e<=8||e===11||e>=14&&e<=31||e>=127&&e<=159||e>1114111)}function W(e){if(e>65535){e-=65536;let t=55296+(e>>10),n=56320+(e&1023);return String.fromCharCode(t,n)}return String.fromCharCode(e)}var Yn=/\\([!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~])/g,Xn=RegExp(`${Yn.source}|&([a-z#][a-z0-9]{1,31});`,`gi`),Zn=/^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))$/i;function Qn(e,t){if(t.charCodeAt(0)===35&&Zn.test(t)){let n=t[1].toLowerCase()===`x`?parseInt(t.slice(2),16):parseInt(t.slice(1),10);return Jn(n)?W(n):e}let n=un(e);return n===e?e:n}function $n(e){return e.indexOf(`\\`)<0?e:e.replace(Yn,`$1`)}function G(e){return e.indexOf(`\\`)<0&&e.indexOf(`&`)<0?e:e.replace(Xn,function(e,t,n){return t||Qn(e,n)})}var er=/[&<>"]/,tr=/[&<>"]/g,nr={"&":`&`,"<":`<`,">":`>`,'"':`"`};function rr(e){return nr[e]}function K(e){return er.test(e)?e.replace(tr,rr):e}var ir=/[.?*+^$[\]\\(){}|-]/g;function ar(e){return e.replace(ir,`\\$&`)}function q(e){switch(e){case 9:case 32:return!0}return!1}function J(e){if(e>=8192&&e<=8202)return!0;switch(e){case 9:case 10:case 11:case 12:case 13:case 32:case 160:case 5760:case 8239:case 8287:case 12288:return!0}return!1}function or(e){return qt.test(e)||Jt.test(e)}function sr(e){return or(W(e))}function cr(e){switch(e){case 33:case 34:case 35:case 36:case 37:case 38:case 39:case 40:case 41:case 42:case 43:case 44:case 45:case 46:case 47:case 58:case 59:case 60:case 61:case 62:case 63:case 64:case 91:case 92:case 93:case 94:case 95:case 96:case 123:case 124:case 125:case 126:return!0;default:return!1}}function lr(e){return e=e.trim().replace(/\s+/g,` `),e.toLowerCase().toUpperCase()}function ur(e){return e===32||e===9||e===10||e===13}function dr(e){let t=0;for(;t=t&&ur(e.charCodeAt(n));n--);return e.slice(t,n+1)}var fr={mdurl:Ht,ucmicro:Ut};function pr(e,t,n){let r,i,a,o,s=e.posMax,c=e.pos;for(e.pos=t+1,r=1;e.pos32))return a;if(r===41){if(o===0)break;o--}i++}return t===i||o!==0?a:(a.str=G(e.slice(t,i)),a.pos=i,a.ok=!0,a)}function hr(e,t,n,r){let i,a=t,o={ok:!1,can_continue:!1,pos:0,str:``,marker:0};if(r)o.str=r.str,o.marker=r.marker;else{if(a>=n)return o;let r=e.charCodeAt(a);if(r!==34&&r!==39&&r!==40)return o;t++,a++,r===40&&(r=41),o.marker=r}for(;amr,parseLinkLabel:()=>pr,parseLinkTitle:()=>hr});function _r(e){"@babel/helpers - typeof";return _r=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},_r(e)}function vr(e,t){if(_r(e)!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(_r(r)!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function yr(e){var t=vr(e,`string`);return _r(t)==`symbol`?t:t+``}function Y(e,t,n){return(t=yr(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var X=class{constructor(e,t,n){Y(this,`map`,null),Y(this,`level`,0),Y(this,`children`,null),Y(this,`content`,``),Y(this,`markup`,``),Y(this,`info`,``),Y(this,`block`,!1),Y(this,`hidden`,!1),this.type=e,this.tag=t,this.attrs=null,this.nesting=n,this.meta=null}attrIndex(e){if(!this.attrs)return-1;let t=this.attrs;for(let n=0,r=t.length;n=0&&(n=this.attrs[t][1]),n}attrJoin(e,t){let n=this.attrIndex(e);n<0?this.attrPush([e,t]):this.attrs[n][1]=`${this.attrs[n][1]} ${t}`}},br=class{constructor(){Y(this,`__rules__`,[]),Y(this,`__cache__`,null)}__find__(e){for(let t=0;t{t.enabled&&t.alt.forEach(t=>{t&&e.add(t)})}),this.__cache__=Object.create(null),this.__cache__[``]=[],this.__rules__.forEach(e=>{e.enabled&&this.__cache__[``].push(e.fn)}),e.forEach(e=>{this.__cache__[e]=[],this.__rules__.forEach(t=>{t.enabled&&t.alt.indexOf(e)>=0&&this.__cache__[e].push(t.fn)})})}at(e,t,n={}){let r=this.__find__(e);if(r===-1)throw Error(`Parser rule not found: ${e}`);this.__rules__[r].fn=t,this.__rules__[r].alt=n.alt||[],this.__cache__=null}before(e,t,n,r={}){let i=this.__find__(e);if(i===-1)throw Error(`Parser rule not found: ${e}`);this.__rules__.splice(i,0,{name:t,enabled:!0,fn:n,alt:r.alt||[]}),this.__cache__=null}after(e,t,n,r={}){let i=this.__find__(e);if(i===-1)throw Error(`Parser rule not found: ${e}`);this.__rules__.splice(i+1,0,{name:t,enabled:!0,fn:n,alt:r.alt||[]}),this.__cache__=null}push(e,t,n={}){this.__rules__.push({name:e,enabled:!0,fn:t,alt:n.alt||[]}),this.__cache__=null}enable(e,t=!1){Array.isArray(e)||(e=[e]);let n=[];return e.forEach(e=>{let r=this.__find__(e);if(r<0){if(t)return;throw Error(`Rules manager: invalid rule name ${e}`)}this.__rules__[r].enabled=!0,n.push(e)}),this.__cache__=null,n}enableOnly(e,t=!1){Array.isArray(e)||(e=[e]),this.__rules__.forEach(e=>{e.enabled=!1}),this.enable(e,t)}disable(e,t=!1){Array.isArray(e)||(e=[e]);let n=[];return e.forEach(e=>{let r=this.__find__(e);if(r<0){if(t)return;throw Error(`Rules manager: invalid rule name ${e}`)}this.__rules__[r].enabled=!1,n.push(e)}),this.__cache__=null,n}getRules(e){return this.__cache__||this.__compile__(),this.__cache__[e]||[]}},Z={};Z.code_inline=function(e,t,n,r,i){let a=e[t];return`${K(a.content)}`},Z.code_block=function(e,t,n,r,i){let a=e[t];return`${K(e[t].content)}\n`},Z.fence=function(e,t,n,r,i){let a=e[t],o=a.info?G(a.info).trim():``,s=``,c=``;if(o){let e=o.split(/(\s+)/g);s=e[0],c=e.slice(2).join(``)}let l;if(l=n.highlight&&n.highlight(a.content,s,c)||K(a.content),l.indexOf(`(r(),g(`header`,Ne,[h(`div`,Pe,[h(`button`,{class:`touch-expand-iconbtn -ml-1 rounded-md p-2 text-foreground-muted transition-colors hover:bg-surface-hover hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-background md:hidden`,"aria-label":`Conversations`,onClick:n[0]||=e=>t.$emit(`toggle-rail`)},[v(f(Ae),{class:`h-4 w-4`})]),v(f(ke),{class:`hidden h-4 w-4 shrink-0 text-foreground-muted md:block`}),h(`h1`,Fe,T(e.title),1)]),h(`div`,Ie,[e.canExport?(r(),g(`button`,{key:0,class:`touch-expand-iconbtn -mr-1 rounded-md p-2 text-foreground-muted transition-colors hover:bg-surface-hover hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-background`,"aria-label":`Export conversation as Markdown`,title:`Export conversation`,onClick:n[1]||=e=>t.$emit(`export`)},[v(f(k),{class:`h-4 w-4`})])):w(``,!0)])]))}},Re={class:`flex h-full flex-col`},ze={key:0,class:`flex h-16 shrink-0 items-center justify-between px-4 border-b border-border`},Be={class:`flex-1 overflow-y-auto scrollable p-2 space-y-0.5`},Ve=[`aria-current`,`onClick`],He={class:`flex-1 truncate`},Ue=[`onClick`],We=[`onClick`],Ge={key:1,class:`px-2.5 py-2 text-xs text-foreground-muted`},Ke={__name:`ConversationRail`,props:{embedded:{type:Boolean,default:!1}},emits:[`select`],setup(e,{emit:t}){let n=A(),i=de();async function o(e){let t=await i.prompt({title:`Rename conversation`,defaultValue:e.title||``,placeholder:`Conversation name`,confirmLabel:`Rename`});t!=null&&t.trim()&&n.renameConversation(e.id,t.trim())}async function s(e){await i.ask({title:`Delete conversation?`,message:`This permanently deletes the conversation and all its messages.`,danger:!0,confirmLabel:`Delete`})&&n.deleteConversation(e)}let c=t;function l(){n.newConversation(),c(`select`)}function u(e){n.openConversation(e),c(`select`)}return(t,i)=>(r(),g(`div`,Re,[e.embedded?w(``,!0):(r(),g(`div`,ze,[i[1]||=h(`span`,{class:`text-sm font-semibold tracking-tight text-white`},`Conversations`,-1),v(j,{size:`xs`,variant:`secondary`,onClick:l},{default:a(()=>[v(f(le),{class:`h-3.5 w-3.5`}),i[0]||=x(` New `,-1)]),_:1})])),h(`div`,Be,[e.embedded?(r(),g(`button`,{key:0,class:`touch-expand-sm mb-1 flex w-full items-center gap-2 rounded-md border border-border px-2.5 py-2 text-left text-sm text-foreground transition-colors hover:bg-surface-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary`,onClick:l},[v(f(le),{class:`h-3.5 w-3.5 shrink-0`}),i[2]||=x(` New conversation `,-1)])):w(``,!0),(r(!0),g(S,null,y(f(n).conversations,e=>(r(),g(`div`,{key:e.id,class:_([`group flex w-full items-center gap-0.5 rounded-md pr-1 transition-colors`,e.id===f(n).activeId?`bg-primary/15`:`hover:bg-surface-hover`])},[h(`button`,{class:_([`touch-expand-sm flex min-w-0 flex-1 items-center gap-2 rounded-md px-2.5 py-2 text-left text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary`,e.id===f(n).activeId?`text-white`:`text-foreground-muted group-hover:text-white`]),"aria-current":e.id===f(n).activeId?`page`:void 0,onClick:t=>u(e.id)},[v(f(ke),{class:`h-3.5 w-3.5 shrink-0 opacity-70`}),h(`span`,He,T(e.title||`New conversation`),1)],10,Ve),h(`button`,{type:`button`,class:`touch-expand-xs shrink-0 rounded-md p-2 text-foreground-muted opacity-0 transition-opacity hover:bg-surface-hover hover:text-white focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary group-hover:opacity-100 max-md:opacity-100`,title:`Rename conversation`,"aria-label":`Rename conversation`,onClick:ae(t=>o(e),[`stop`])},[v(f(ee),{class:`h-3.5 w-3.5`})],8,Ue),h(`button`,{type:`button`,class:`touch-expand-xs shrink-0 rounded-md p-2 text-foreground-muted opacity-0 transition-opacity hover:bg-surface-hover hover:text-danger-fg focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary group-hover:opacity-100 max-md:opacity-100`,title:`Delete conversation`,"aria-label":`Delete conversation`,onClick:ae(t=>s(e.id),[`stop`])},[v(f(re),{class:`h-3.5 w-3.5`})],8,We)],2))),128)),f(n).conversations.length?w(``,!0):(r(),g(`p`,Ge,` No conversations yet. `))])]))}},qe={class:`text-center`},Je={class:`mx-auto mt-5 flex max-w-xl flex-wrap justify-center gap-2`},Ye=[`onClick`],Xe={class:`line-clamp-2`},Ze={__name:`EmptyState`,emits:[`pick`],setup(e){let t=[`How many functions do I have?`,`Which function ran most recently?`,`Any errors in the last 24 hours?`,`Show my most recent executions.`,`List my deployed functions.`,`Summarize today’s invocation errors.`,`Show failed deployments and why.`,`What’s my system health right now?`,`Show storage usage for my instance.`,`List my cron schedules.`,`Are any background jobs failing?`,`Check for failed webhook deliveries.`,`Which runtimes are available?`,`Show my slowest functions by duration.`,`Which functions have egress enabled?`,`List my secrets by name only.`,`Write a Python function that returns the current UTC time.`,`Write a Node function that echoes the request body.`,`Create an hourly cron schedule for a function.`,`Walk me through deploying a new function.`];function n(e,t){let n=[...e];for(let e=n.length-1;e>0;e--){let t=Math.floor(Math.random()*(e+1));[n[e],n[t]]=[n[t],n[e]]}return n.slice(0,t)}let i=o(n(t,3));return(e,t)=>(r(),g(`div`,qe,[t[0]||=h(`h2`,{class:`text-lg font-semibold tracking-tight text-white`},` What would you like to do? `,-1),t[1]||=h(`p`,{class:`mx-auto mt-1.5 max-w-md text-sm leading-relaxed text-foreground-muted`},` Ask about this instance or operate it with natural language. `,-1),h(`div`,Je,[(r(!0),g(S,null,y(i.value,(t,n)=>(r(),g(`button`,{key:n,type:`button`,class:`rounded-md px-3 py-2 text-left text-xs leading-snug text-foreground-muted transition-colors hover:bg-surface-hover hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-background`,onClick:n=>e.$emit(`pick`,t)},[h(`span`,Xe,T(t),1)],8,Ye))),128))])]))}},Qe=`[A-Za-z$_][0-9A-Za-z$_]*`,$e=`as.in.of.if.for.while.finally.var.new.function.do.return.void.else.break.catch.instanceof.with.throw.case.default.try.switch.continue.typeof.delete.let.yield.const.class.debugger.async.await.static.import.from.export.extends.using`.split(`.`),et=[`true`,`false`,`null`,`undefined`,`NaN`,`Infinity`],tt=`Object.Function.Boolean.Symbol.Math.Date.Number.BigInt.String.RegExp.Array.Float32Array.Float64Array.Int8Array.Uint8Array.Uint8ClampedArray.Int16Array.Int32Array.Uint16Array.Uint32Array.BigInt64Array.BigUint64Array.Set.Map.WeakSet.WeakMap.ArrayBuffer.SharedArrayBuffer.Atomics.DataView.JSON.Promise.Generator.GeneratorFunction.AsyncFunction.Reflect.Proxy.Intl.WebAssembly`.split(`.`),nt=[`Error`,`EvalError`,`InternalError`,`RangeError`,`ReferenceError`,`SyntaxError`,`TypeError`,`URIError`],rt=[`setInterval`,`setTimeout`,`clearInterval`,`clearTimeout`,`require`,`exports`,`eval`,`isFinite`,`isNaN`,`parseFloat`,`parseInt`,`decodeURI`,`decodeURIComponent`,`encodeURI`,`encodeURIComponent`,`escape`,`unescape`],it=[`arguments`,`this`,`super`,`console`,`window`,`document`,`localStorage`,`sessionStorage`,`module`,`global`],at=[].concat(rt,tt,nt);function ot(e){let t=e.regex,n=(e,{after:t})=>{let n=``,end:``},a=/<[A-Za-z0-9\\._:-]+\s*\/>/,o={begin:/<[A-Za-z0-9\\._:-]+/,end:/\/[A-Za-z0-9\\._:-]+>|\/>/,isTrulyOpeningTag:(e,t)=>{let r=e[0].length+e.index,i=e.input[r];if(i===`<`||i===`,`){t.ignoreMatch();return}i===`>`&&(n(e,{after:r})||t.ignoreMatch());let a,o=e.input.substring(r);if(a=o.match(/^\s*=/)){t.ignoreMatch();return}if((a=o.match(/^\s+extends\s+/))&&a.index===0){t.ignoreMatch();return}}},s={$pattern:Qe,keyword:$e,literal:et,built_in:at,"variable.language":it},c=`[0-9](_?[0-9])*`,l=`\\.(${c})`,u=`0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*`,d={className:`number`,variants:[{begin:`(\\b(${u})((${l})|\\.)?|(${l}))[eE][+-]?(${c})\\b`},{begin:`\\b(${u})\\b((${l})\\b|\\.)?|(${l})\\b`},{begin:`\\b(0|[1-9](_?[0-9])*)n\\b`},{begin:`\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*n?\\b`},{begin:`\\b0[bB][0-1](_?[0-1])*n?\\b`},{begin:`\\b0[oO][0-7](_?[0-7])*n?\\b`},{begin:`\\b0[0-7]+n?\\b`}],relevance:0},f={className:`subst`,begin:`\\$\\{`,end:`\\}`,keywords:s,contains:[]},p={begin:".?html`",end:``,starts:{end:"`",returnEnd:!1,contains:[e.BACKSLASH_ESCAPE,f],subLanguage:`xml`}},m={begin:".?css`",end:``,starts:{end:"`",returnEnd:!1,contains:[e.BACKSLASH_ESCAPE,f],subLanguage:`css`}},h={begin:".?gql`",end:``,starts:{end:"`",returnEnd:!1,contains:[e.BACKSLASH_ESCAPE,f],subLanguage:`graphql`}},g={className:`string`,begin:"`",end:"`",contains:[e.BACKSLASH_ESCAPE,f]},_={className:`comment`,variants:[e.COMMENT(/\/\*\*(?!\/)/,`\\*/`,{relevance:0,contains:[{begin:`(?=@[A-Za-z]+)`,relevance:0,contains:[{className:`doctag`,begin:`@[A-Za-z]+`},{className:`type`,begin:`\\{`,end:`\\}`,excludeEnd:!0,excludeBegin:!0,relevance:0},{className:`variable`,begin:`[A-Za-z$_][0-9A-Za-z$_]*(?=\\s*(-)|$)`,endsParent:!0,relevance:0},{begin:/(?=[^\n])\s/,relevance:0}]}]}),e.C_BLOCK_COMMENT_MODE,e.C_LINE_COMMENT_MODE]},v=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,p,m,h,g,{match:/\$\d+/},d];f.contains=v.concat({begin:/\{/,end:/\}/,keywords:s,contains:[`self`].concat(v)});let y=[].concat(_,f.contains),b=y.concat([{begin:/(\s*)\(/,end:/\)/,keywords:s,contains:[`self`].concat(y)}]),x={className:`params`,begin:/(\s*)\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:s,contains:b},S={variants:[{match:[/class/,/\s+/,r,/\s+/,/extends/,/\s+/,t.concat(r,`(`,t.concat(/\./,r),`)*`)],scope:{1:`keyword`,3:`title.class`,5:`keyword`,7:`title.class.inherited`}},{match:[/class/,/\s+/,r],scope:{1:`keyword`,3:`title.class`}}]},C={relevance:0,match:t.either(/\bJSON/,/\b[A-Z][a-z]+([A-Z][a-z]*|\d)*/,/\b[A-Z]{2,}([A-Z][a-z]+|\d)+([A-Z][a-z]*)*/,/\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\d)*([A-Z][a-z]*)*/),className:`title.class`,keywords:{_:[...tt,...nt]}},w={label:`use_strict`,className:`meta`,relevance:10,begin:/^\s*['"]use (strict|asm)['"]/},T={variants:[{match:[/function/,/\s+/,r,/(?=\s*\()/]},{match:[/function/,/\s*(?=\()/]}],className:{1:`keyword`,3:`title.function`},label:`func.def`,contains:[x],illegal:/%/},E={relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/,className:`variable.constant`};function D(e){return t.concat(`(?!`,e.join(`|`),`)`)}let O={match:t.concat(/\b/,D([...rt,`super`,`import`].map(e=>`${e}\\s*\\(`)),r,t.lookahead(/\s*\(/)),className:`title.function`,relevance:0},k={begin:t.concat(/\./,t.lookahead(t.concat(r,/(?![0-9A-Za-z$_(])/))),end:r,excludeBegin:!0,keywords:`prototype`,className:`property`,relevance:0},A={match:[/get|set/,/\s+/,r,/(?=\()/],className:{1:`keyword`,3:`title.function`},contains:[{begin:/\(\)/},x]},ee=`(\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)|`+e.UNDERSCORE_IDENT_RE+`)\\s*=>`,te={match:[/const|var|let/,/\s+/,r,/\s*/,/=\s*/,/(async\s*)?/,t.lookahead(ee)],keywords:`async`,className:{1:`keyword`,3:`title.function`},contains:[x]};return{name:`JavaScript`,aliases:[`js`,`jsx`,`mjs`,`cjs`],keywords:s,exports:{PARAMS_CONTAINS:b,CLASS_REFERENCE:C},illegal:/#(?![$_A-z])/,contains:[e.SHEBANG({label:`shebang`,binary:`node`,relevance:5}),w,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,p,m,h,g,_,{match:/\$\d+/},d,C,{scope:`attr`,match:r+t.lookahead(`:`),relevance:0},te,{begin:`(`+e.RE_STARTERS_RE+`|\\b(case|return|throw)\\b)\\s*`,keywords:`return throw case`,relevance:0,contains:[_,e.REGEXP_MODE,{className:`function`,begin:ee,returnBegin:!0,end:`\\s*=>`,contains:[{className:`params`,variants:[{begin:e.UNDERSCORE_IDENT_RE,relevance:0},{className:null,begin:/\(\s*\)/,skip:!0},{begin:/(\s*)\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:s,contains:b}]}]},{begin:/,/,relevance:0},{match:/\s+/,relevance:0},{variants:[{begin:i.begin,end:i.end},{match:a},{begin:o.begin,"on:begin":o.isTrulyOpeningTag,end:o.end}],subLanguage:`xml`,contains:[{begin:o.begin,end:o.end,skip:!0,contains:[`self`]}]}]},T,{beginKeywords:`while if switch catch for`},{begin:`\\b(?!function)`+e.UNDERSCORE_IDENT_RE+`\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{`,returnBegin:!0,label:`func.def`,contains:[x,e.inherit(e.TITLE_MODE,{begin:r,className:`title.function`})]},{match:/\.\.\./,relevance:0},k,{match:`\\$[A-Za-z$_][0-9A-Za-z$_]*`,relevance:0},{match:[/\bconstructor(?=\s*\()/],className:{1:`title.function`},contains:[x]},O,E,S,A,{match:/\$[(.]/}]}}function st(e){let t=e.regex,n=ot(e),r=Qe,i=[`any`,`void`,`number`,`boolean`,`string`,`object`,`never`,`symbol`,`bigint`,`unknown`],a={begin:[/namespace/,/\s+/,e.IDENT_RE],beginScope:{1:`keyword`,3:`title.class`}},o={beginKeywords:`interface`,end:/\{/,excludeEnd:!0,keywords:{keyword:`interface extends`,built_in:i},contains:[n.exports.CLASS_REFERENCE]},s={className:`meta`,relevance:10,begin:/^\s*['"]use strict['"]/},c={$pattern:Qe,keyword:$e.concat([`type`,`interface`,`public`,`private`,`protected`,`implements`,`declare`,`abstract`,`readonly`,`enum`,`override`,`satisfies`]),literal:et,built_in:at.concat(i),"variable.language":it},l={className:`meta`,begin:`@[A-Za-z$_][0-9A-Za-z$_]*`},u=(e,t,n)=>{let r=e.contains.findIndex(e=>e.label===t);if(r===-1)throw Error(`can not find mode to replace`);e.contains.splice(r,1,n)};Object.assign(n.keywords,c),n.exports.PARAMS_CONTAINS.push(l);let d=n.contains.find(e=>e.scope===`attr`),f=Object.assign({},d,{match:t.concat(r,t.lookahead(/\s*\?:/))});n.exports.PARAMS_CONTAINS.push([n.exports.CLASS_REFERENCE,d,f]),n.contains=n.contains.concat([l,a,o,f]),u(n,`shebang`,e.SHEBANG()),u(n,`use_strict`,s);let p=n.contains.find(e=>e.label===`func.def`);return p.relevance=0,Object.assign(n,{name:`TypeScript`,aliases:[`ts`,`tsx`,`mts`,`cts`]}),n}function ct(e){let t=e.regex,n=t.concat(/[\p{L}_]/u,t.optional(/[\p{L}0-9_.-]*:/u),/[\p{L}0-9_.-]*/u),r=/[\p{L}0-9._:-]+/u,i={className:`symbol`,begin:/&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/},a={begin:/\s/,contains:[{className:`keyword`,begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}]},o=e.inherit(a,{begin:/\(/,end:/\)/}),s=e.inherit(e.APOS_STRING_MODE,{className:`string`}),c=e.inherit(e.QUOTE_STRING_MODE,{className:`string`}),l={endsWithParent:!0,illegal:/`]+/}]}]}]};return{name:`HTML, XML`,aliases:[`html`,`xhtml`,`rss`,`atom`,`xjb`,`xsd`,`xsl`,`plist`,`wsf`,`svg`],case_insensitive:!0,unicodeRegex:!0,contains:[{className:`meta`,begin://,relevance:10,contains:[a,c,s,o,{begin:/\[/,end:/\]/,contains:[{className:`meta`,begin://,contains:[a,o,c,s]}]}]},e.COMMENT(//,{relevance:10}),{begin://,relevance:10},i,{className:`meta`,end:/\?>/,variants:[{begin:/<\?xml/,relevance:10,contains:[c]},{begin:/<\?[a-z][a-z0-9]+/}]},{className:`tag`,begin:/)/,end:/>/,keywords:{name:`style`},contains:[l],starts:{end:/<\/style>/,returnEnd:!0,subLanguage:[`css`,`xml`]}},{className:`tag`,begin:/)/,end:/>/,keywords:{name:`script`},contains:[l],starts:{end:/<\/script>/,returnEnd:!0,subLanguage:[`javascript`,`handlebars`,`xml`]}},{className:`tag`,begin:/<>|<\/>/},{className:`tag`,begin:t.concat(//,/>/,/\s/)))),end:/\/?>/,contains:[{className:`name`,begin:n,relevance:0,starts:l}]},{className:`tag`,begin:t.concat(/<\//,t.lookahead(t.concat(n,/>/))),contains:[{className:`name`,begin:n,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]}}var lt=e=>({IMPORTANT:{scope:`meta`,begin:`!important`},BLOCK_COMMENT:e.C_BLOCK_COMMENT_MODE,HEXCOLOR:{scope:`number`,begin:/#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\b/},FUNCTION_DISPATCH:{className:`built_in`,begin:/[\w-]+(?=\()/},ATTRIBUTE_SELECTOR_MODE:{scope:`selector-attr`,begin:/\[/,end:/\]/,illegal:`$`,contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},CSS_NUMBER_MODE:{scope:`number`,begin:e.NUMBER_RE+`(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?`,relevance:0},CSS_VARIABLE:{className:`attr`,begin:/--[A-Za-z_][A-Za-z0-9_-]*/}}),ut=`a.abbr.address.article.aside.audio.b.blockquote.body.button.canvas.caption.cite.code.dd.del.details.dfn.div.dl.dt.em.fieldset.figcaption.figure.footer.form.h1.h2.h3.h4.h5.h6.header.hgroup.html.i.iframe.img.input.ins.kbd.label.legend.li.main.mark.menu.nav.object.ol.optgroup.option.p.picture.q.quote.samp.section.select.source.span.strong.summary.sup.table.tbody.td.textarea.tfoot.th.thead.time.tr.ul.var.video`.split(`.`),dt=`defs.g.marker.mask.pattern.svg.switch.symbol.feBlend.feColorMatrix.feComponentTransfer.feComposite.feConvolveMatrix.feDiffuseLighting.feDisplacementMap.feFlood.feGaussianBlur.feImage.feMerge.feMorphology.feOffset.feSpecularLighting.feTile.feTurbulence.linearGradient.radialGradient.stop.circle.ellipse.image.line.path.polygon.polyline.rect.text.use.textPath.tspan.foreignObject.clipPath`.split(`.`),ft=[...ut,...dt],pt=`any-hover.any-pointer.aspect-ratio.color.color-gamut.color-index.device-aspect-ratio.device-height.device-width.display-mode.forced-colors.grid.height.hover.inverted-colors.monochrome.orientation.overflow-block.overflow-inline.pointer.prefers-color-scheme.prefers-contrast.prefers-reduced-motion.prefers-reduced-transparency.resolution.scan.scripting.update.width.min-width.max-width.min-height.max-height`.split(`.`).sort().reverse(),mt=`active.any-link.blank.checked.current.default.defined.dir.disabled.drop.empty.enabled.first.first-child.first-of-type.fullscreen.future.focus.focus-visible.focus-within.has.host.host-context.hover.indeterminate.in-range.invalid.is.lang.last-child.last-of-type.left.link.local-link.not.nth-child.nth-col.nth-last-child.nth-last-col.nth-last-of-type.nth-of-type.only-child.only-of-type.optional.out-of-range.past.placeholder-shown.read-only.read-write.required.right.root.scope.target.target-within.user-invalid.valid.visited.where`.split(`.`).sort().reverse(),ht=[`after`,`backdrop`,`before`,`cue`,`cue-region`,`first-letter`,`first-line`,`grammar-error`,`marker`,`part`,`placeholder`,`selection`,`slotted`,`spelling-error`].sort().reverse(),gt=`accent-color.align-content.align-items.align-self.alignment-baseline.all.anchor-name.animation.animation-composition.animation-delay.animation-direction.animation-duration.animation-fill-mode.animation-iteration-count.animation-name.animation-play-state.animation-range.animation-range-end.animation-range-start.animation-timeline.animation-timing-function.appearance.aspect-ratio.backdrop-filter.backface-visibility.background.background-attachment.background-blend-mode.background-clip.background-color.background-image.background-origin.background-position.background-position-x.background-position-y.background-repeat.background-size.baseline-shift.block-size.border.border-block.border-block-color.border-block-end.border-block-end-color.border-block-end-style.border-block-end-width.border-block-start.border-block-start-color.border-block-start-style.border-block-start-width.border-block-style.border-block-width.border-bottom.border-bottom-color.border-bottom-left-radius.border-bottom-right-radius.border-bottom-style.border-bottom-width.border-collapse.border-color.border-end-end-radius.border-end-start-radius.border-image.border-image-outset.border-image-repeat.border-image-slice.border-image-source.border-image-width.border-inline.border-inline-color.border-inline-end.border-inline-end-color.border-inline-end-style.border-inline-end-width.border-inline-start.border-inline-start-color.border-inline-start-style.border-inline-start-width.border-inline-style.border-inline-width.border-left.border-left-color.border-left-style.border-left-width.border-radius.border-right.border-right-color.border-right-style.border-right-width.border-spacing.border-start-end-radius.border-start-start-radius.border-style.border-top.border-top-color.border-top-left-radius.border-top-right-radius.border-top-style.border-top-width.border-width.bottom.box-align.box-decoration-break.box-direction.box-flex.box-flex-group.box-lines.box-ordinal-group.box-orient.box-pack.box-shadow.box-sizing.break-after.break-before.break-inside.caption-side.caret-color.clear.clip.clip-path.clip-rule.color.color-interpolation.color-interpolation-filters.color-profile.color-rendering.color-scheme.column-count.column-fill.column-gap.column-rule.column-rule-color.column-rule-style.column-rule-width.column-span.column-width.columns.contain.contain-intrinsic-block-size.contain-intrinsic-height.contain-intrinsic-inline-size.contain-intrinsic-size.contain-intrinsic-width.container.container-name.container-type.content.content-visibility.counter-increment.counter-reset.counter-set.cue.cue-after.cue-before.cursor.cx.cy.direction.display.dominant-baseline.empty-cells.enable-background.field-sizing.fill.fill-opacity.fill-rule.filter.flex.flex-basis.flex-direction.flex-flow.flex-grow.flex-shrink.flex-wrap.float.flood-color.flood-opacity.flow.font.font-display.font-family.font-feature-settings.font-kerning.font-language-override.font-optical-sizing.font-palette.font-size.font-size-adjust.font-smooth.font-smoothing.font-stretch.font-style.font-synthesis.font-synthesis-position.font-synthesis-small-caps.font-synthesis-style.font-synthesis-weight.font-variant.font-variant-alternates.font-variant-caps.font-variant-east-asian.font-variant-emoji.font-variant-ligatures.font-variant-numeric.font-variant-position.font-variation-settings.font-weight.forced-color-adjust.gap.glyph-orientation-horizontal.glyph-orientation-vertical.grid.grid-area.grid-auto-columns.grid-auto-flow.grid-auto-rows.grid-column.grid-column-end.grid-column-start.grid-gap.grid-row.grid-row-end.grid-row-start.grid-template.grid-template-areas.grid-template-columns.grid-template-rows.hanging-punctuation.height.hyphenate-character.hyphenate-limit-chars.hyphens.icon.image-orientation.image-rendering.image-resolution.ime-mode.initial-letter.initial-letter-align.inline-size.inset.inset-area.inset-block.inset-block-end.inset-block-start.inset-inline.inset-inline-end.inset-inline-start.isolation.justify-content.justify-items.justify-self.kerning.left.letter-spacing.lighting-color.line-break.line-height.line-height-step.list-style.list-style-image.list-style-position.list-style-type.margin.margin-block.margin-block-end.margin-block-start.margin-bottom.margin-inline.margin-inline-end.margin-inline-start.margin-left.margin-right.margin-top.margin-trim.marker.marker-end.marker-mid.marker-start.marks.mask.mask-border.mask-border-mode.mask-border-outset.mask-border-repeat.mask-border-slice.mask-border-source.mask-border-width.mask-clip.mask-composite.mask-image.mask-mode.mask-origin.mask-position.mask-repeat.mask-size.mask-type.masonry-auto-flow.math-depth.math-shift.math-style.max-block-size.max-height.max-inline-size.max-width.min-block-size.min-height.min-inline-size.min-width.mix-blend-mode.nav-down.nav-index.nav-left.nav-right.nav-up.none.normal.object-fit.object-position.offset.offset-anchor.offset-distance.offset-path.offset-position.offset-rotate.opacity.order.orphans.outline.outline-color.outline-offset.outline-style.outline-width.overflow.overflow-anchor.overflow-block.overflow-clip-margin.overflow-inline.overflow-wrap.overflow-x.overflow-y.overlay.overscroll-behavior.overscroll-behavior-block.overscroll-behavior-inline.overscroll-behavior-x.overscroll-behavior-y.padding.padding-block.padding-block-end.padding-block-start.padding-bottom.padding-inline.padding-inline-end.padding-inline-start.padding-left.padding-right.padding-top.page.page-break-after.page-break-before.page-break-inside.paint-order.pause.pause-after.pause-before.perspective.perspective-origin.place-content.place-items.place-self.pointer-events.position.position-anchor.position-visibility.print-color-adjust.quotes.r.resize.rest.rest-after.rest-before.right.rotate.row-gap.ruby-align.ruby-position.scale.scroll-behavior.scroll-margin.scroll-margin-block.scroll-margin-block-end.scroll-margin-block-start.scroll-margin-bottom.scroll-margin-inline.scroll-margin-inline-end.scroll-margin-inline-start.scroll-margin-left.scroll-margin-right.scroll-margin-top.scroll-padding.scroll-padding-block.scroll-padding-block-end.scroll-padding-block-start.scroll-padding-bottom.scroll-padding-inline.scroll-padding-inline-end.scroll-padding-inline-start.scroll-padding-left.scroll-padding-right.scroll-padding-top.scroll-snap-align.scroll-snap-stop.scroll-snap-type.scroll-timeline.scroll-timeline-axis.scroll-timeline-name.scrollbar-color.scrollbar-gutter.scrollbar-width.shape-image-threshold.shape-margin.shape-outside.shape-rendering.speak.speak-as.src.stop-color.stop-opacity.stroke.stroke-dasharray.stroke-dashoffset.stroke-linecap.stroke-linejoin.stroke-miterlimit.stroke-opacity.stroke-width.tab-size.table-layout.text-align.text-align-all.text-align-last.text-anchor.text-combine-upright.text-decoration.text-decoration-color.text-decoration-line.text-decoration-skip.text-decoration-skip-ink.text-decoration-style.text-decoration-thickness.text-emphasis.text-emphasis-color.text-emphasis-position.text-emphasis-style.text-indent.text-justify.text-orientation.text-overflow.text-rendering.text-shadow.text-size-adjust.text-transform.text-underline-offset.text-underline-position.text-wrap.text-wrap-mode.text-wrap-style.timeline-scope.top.touch-action.transform.transform-box.transform-origin.transform-style.transition.transition-behavior.transition-delay.transition-duration.transition-property.transition-timing-function.translate.unicode-bidi.user-modify.user-select.vector-effect.vertical-align.view-timeline.view-timeline-axis.view-timeline-inset.view-timeline-name.view-transition-name.visibility.voice-balance.voice-duration.voice-family.voice-pitch.voice-range.voice-rate.voice-stress.voice-volume.white-space.white-space-collapse.widows.width.will-change.word-break.word-spacing.word-wrap.writing-mode.x.y.z-index.zoom`.split(`.`).sort().reverse();function _t(e){let t=e.regex,n=lt(e),r={begin:/-(webkit|moz|ms|o)-(?=[a-z])/},i=/@-?\w[\w]*(-\w+)*/,a=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE];return{name:`CSS`,case_insensitive:!0,illegal:/[=|'\$]/,keywords:{keyframePosition:`from to`},classNameAliases:{keyframePosition:`selector-tag`},contains:[n.BLOCK_COMMENT,r,n.CSS_NUMBER_MODE,{className:`selector-id`,begin:/#[A-Za-z0-9_-]+/,relevance:0},{className:`selector-class`,begin:`\\.[a-zA-Z-][a-zA-Z0-9_-]*`,relevance:0},n.ATTRIBUTE_SELECTOR_MODE,{className:`selector-pseudo`,variants:[{begin:`:(`+mt.join(`|`)+`)`},{begin:`:(:)?(`+ht.join(`|`)+`)`}]},n.CSS_VARIABLE,{className:`attribute`,begin:`\\b(`+gt.join(`|`)+`)\\b`},{begin:/:/,end:/[;}{]/,contains:[n.BLOCK_COMMENT,n.HEXCOLOR,n.IMPORTANT,n.CSS_NUMBER_MODE,...a,{begin:/(url|data-uri)\(/,end:/\)/,relevance:0,keywords:{built_in:`url data-uri`},contains:[...a,{className:`string`,begin:/[^)]/,endsWithParent:!0,excludeEnd:!0}]},n.FUNCTION_DISPATCH]},{begin:t.lookahead(/@/),end:`[{;]`,relevance:0,illegal:/:/,contains:[{className:`keyword`,begin:i},{begin:/\s/,endsWithParent:!0,excludeEnd:!0,relevance:0,keywords:{$pattern:/[a-z-]+/,keyword:`and or not only`,attribute:pt.join(` `)},contains:[{begin:/[a-z-]+(?=:)/,className:`attribute`},...a,n.CSS_NUMBER_MODE]}]},{className:`selector-tag`,begin:`\\b(`+ft.join(`|`)+`)\\b`}]}}function vt(e){let t=`true false yes no null`,n={className:`attr`,variants:[{begin:/[\w*@][\w*@ :()\./-]*:(?=[ \t]|$)/},{begin:/"[\w*@][\w*@ :()\./-]*":(?=[ \t]|$)/},{begin:/'[\w*@][\w*@ :()\./-]*':(?=[ \t]|$)/}]},r={className:`template-variable`,variants:[{begin:/\{\{/,end:/\}\}/},{begin:/%\{/,end:/\}/}]},i={className:`string`,relevance:0,begin:/'/,end:/'/,contains:[{match:/''/,scope:`char.escape`,relevance:0}]},a={className:`string`,relevance:0,variants:[{begin:/"/,end:/"/},{begin:/\S+/}],contains:[e.BACKSLASH_ESCAPE,r]},o=e.inherit(a,{variants:[{begin:/'/,end:/'/,contains:[{begin:/''/,relevance:0}]},{begin:/"/,end:/"/},{begin:/[^\s,{}[\]]+/}]}),s={className:`number`,begin:`\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b`},c={end:`,`,endsWithParent:!0,excludeEnd:!0,keywords:t,relevance:0},l={begin:/\{/,end:/\}/,contains:[c],illegal:`\\n`,relevance:0},u={begin:`\\[`,end:`\\]`,contains:[c],illegal:`\\n`,relevance:0},d=[n,{className:`meta`,begin:`^---\\s*$`,relevance:10},{className:`string`,begin:`[\\|>]([1-9]?[+-])?[ ]*\\n( +)[^ ][^\\n]*\\n(\\2[^\\n]+\\n?)*`},{begin:`<%[%=-]?`,end:`[%-]?%>`,subLanguage:`ruby`,excludeBegin:!0,excludeEnd:!0,relevance:0},{className:`type`,begin:`!\\w+![\\w#;/?:@&=+$,.~*'()[\\]]+`},{className:`type`,begin:`!<[\\w#;/?:@&=+$,.~*'()[\\]]+>`},{className:`type`,begin:`![\\w#;/?:@&=+$,.~*'()[\\]]+`},{className:`type`,begin:`!![\\w#;/?:@&=+$,.~*'()[\\]]+`},{className:`meta`,begin:`&`+e.UNDERSCORE_IDENT_RE+`$`},{className:`meta`,begin:`\\*`+e.UNDERSCORE_IDENT_RE+`$`},{className:`bullet`,begin:`-(?=[ ]|$)`,relevance:0},e.HASH_COMMENT_MODE,{beginKeywords:t,keywords:{literal:t}},s,{className:`number`,begin:e.C_NUMBER_RE+`\\b`,relevance:0},l,u,i,a],f=[...d];return f.pop(),f.push(o),c.contains=f,{name:`YAML`,case_insensitive:!0,aliases:[`yml`],contains:d}}N.registerLanguage(`javascript`,_e),N.registerLanguage(`typescript`,st),N.registerLanguage(`python`,ye),N.registerLanguage(`json`,ve),N.registerLanguage(`bash`,be),N.registerLanguage(`xml`,ct),N.registerLanguage(`css`,_t),N.registerLanguage(`yaml`,vt);var yt={js:`javascript`,ts:`typescript`,py:`python`,sh:`bash`,shell:`bash`,yml:`yaml`,html:`xml`};function bt(e){return e.replace(/&/g,`&`).replace(//g,`>`)}function xt(e,t){let n=yt[(t||``).toLowerCase()]||(t||``).toLowerCase();if(n&&N.getLanguage(n))try{return N.highlight(e,{language:n,ignoreIllegals:!0}).value}catch{}return bt(e)}var St=N,Ct={};function wt(e){let t=Ct[e];if(t)return t;t=Ct[e]=[];for(let e=0;e<128;e++){let n=String.fromCharCode(e);t.push(n)}for(let n=0;n=55296&&e<=57343?`���`:String.fromCharCode(e),r+=6;continue}}if((a&248)==240&&r+91114111?t+=`����`:(e-=65536,t+=String.fromCharCode(55296+(e>>10),56320+(e&1023))),r+=9;continue}}t+=`�`}return t})}P.defaultChars=`;/?:@&=+$,#`,P.componentChars=``;var Tt={};function Et(e){let t=Tt[e];if(t)return t;t=Tt[e]=[];for(let e=0;e<128;e++){let n=String.fromCharCode(e);/^[0-9a-z]$/i.test(n)?t.push(n):t.push(`%`+(`0`+e.toString(16).toUpperCase()).slice(-2))}for(let n=0;n=55296&&o<=57343){if(o>=55296&&o<=56319&&t+1=56320&&n<=57343){i+=encodeURIComponent(e[t]+e[t+1]),t++;continue}}i+=`%EF%BF%BD`;continue}i+=encodeURIComponent(e[t])}return i}F.defaultChars=`;/?:@&=+$,-_.!~*'()#`,F.componentChars=`-_.!~*'()`;function Dt(e){let t=``;return t+=e.protocol||``,t+=e.slashes?`//`:``,t+=e.auth?e.auth+`@`:``,e.hostname&&e.hostname.indexOf(`:`)!==-1?t+=`[`+e.hostname+`]`:t+=e.hostname||``,t+=e.port?`:`+e.port:``,t+=e.pathname||``,t+=e.search||``,t+=e.hash||``,t}function Ot(){this.protocol=null,this.slashes=null,this.auth=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.pathname=null}var kt=/^([a-z0-9.+-]+:)/i,At=/:[0-9]*$/,jt=/^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,Mt=[`%`,`/`,`?`,`;`,`#`,`'`,`{`,`}`,`|`,`\\`,`^`,"`",`<`,`>`,`"`,"`",` `,`\r`,` +`,` `],Nt=[`/`,`?`,`#`],Pt=255,Ft=/^[+a-z0-9A-Z_-]{0,63}$/,It=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,Lt={javascript:!0,"javascript:":!0},Rt={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0};function zt(e,t){if(e&&e instanceof Ot)return e;let n=new Ot;return n.parse(e,t),n}Ot.prototype.parse=function(e,t){let n,r,i,a=e;if(a=a.trim(),!t&&e.split(`#`).length===1){let e=jt.exec(a);if(e)return this.pathname=e[1],e[2]&&(this.search=e[2]),this}let o=kt.exec(a);if(o&&(o=o[0],n=o.toLowerCase(),this.protocol=o,a=a.substr(o.length)),(t||o||a.match(/^\/\/[^@\/]+@[^@\/]+/))&&(i=a.substr(0,2)===`//`,i&&!(o&&Lt[o])&&(a=a.substr(2),this.slashes=!0)),!Lt[o]&&(i||o&&!Rt[o])){let e=-1;for(let t=0;t127?r+=`x`:r+=n[e];if(!r.match(Ft)){let r=e.slice(0,t),i=e.slice(t+1),o=n.match(It);o&&(r.push(o[1]),i.unshift(o[2])),i.length&&(a=i.join(`.`)+a),this.hostname=r.join(`.`);break}}}}this.hostname.length>Pt&&(this.hostname=``),o&&(this.hostname=this.hostname.substr(1,this.hostname.length-2))}let s=a.indexOf(`#`);s!==-1&&(this.hash=a.substr(s),a=a.slice(0,s));let c=a.indexOf(`?`);return c!==-1&&(this.search=a.substr(c),a=a.slice(0,c)),a&&(this.pathname=a),Rt[n]&&this.hostname&&!this.pathname&&(this.pathname=``),this},Ot.prototype.parseHost=function(e){let t=At.exec(e);t&&(t=t[0],t!==`:`&&(this.port=t.substr(1)),e=e.substr(0,e.length-t.length)),e&&(this.hostname=e)};var Bt=e({decode:()=>P,encode:()=>F,format:()=>Dt,parse:()=>zt}),Vt=e({Any:()=>Ht,Cc:()=>Ut,Cf:()=>Wt,P:()=>Gt,S:()=>Kt,Z:()=>qt}),Ht=/[\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,Ut=/[\0-\x1F\x7F-\x9F]/,Wt=/[\xAD\u0600-\u0605\u061C\u06DD\u070F\u0890\u0891\u08E2\u180E\u200B-\u200F\u202A-\u202E\u2060-\u2064\u2066-\u206F\uFEFF\uFFF9-\uFFFB]|\uD804[\uDCBD\uDCCD]|\uD80D[\uDC30-\uDC3F]|\uD82F[\uDCA0-\uDCA3]|\uD834[\uDD73-\uDD7A]|\uDB40[\uDC01\uDC20-\uDC7F]/,Gt=/[!-#%-\*,-\/:;\?@\[-\]_\{\}\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B4E\u1B4F\u1B5A-\u1B60\u1B7D-\u1B7F\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD803[\uDD6E\uDEAD\uDED0\uDF55-\uDF59\uDF86-\uDF89]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9\uDFD4\uDFD5\uDFD7\uDFD8]|\uD805[\uDC4B-\uDC4F\uDC5A\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDEB9\uDF3C-\uDF3E]|\uD806[\uDC3B\uDD44-\uDD46\uDDE2\uDE3F-\uDE46\uDE9A-\uDE9C\uDE9E-\uDEA2\uDF00-\uDF09\uDFE1]|\uD807[\uDC41-\uDC45\uDC70\uDC71\uDEF7\uDEF8\uDF43-\uDF4F\uDFFF]|\uD809[\uDC70-\uDC74]|\uD80B[\uDFF1\uDFF2]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD81B[\uDD6D-\uDD6F\uDE97-\uDE9A\uDFE2]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]|\uD839\uDDFF|\uD83A[\uDD5E\uDD5F]/,Kt=/[\$\+<->\^`\|~\xA2-\xA6\xA8\xA9\xAC\xAE-\xB1\xB4\xB8\xD7\xF7\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0384\u0385\u03F6\u0482\u058D-\u058F\u0606-\u0608\u060B\u060E\u060F\u06DE\u06E9\u06FD\u06FE\u07F6\u07FE\u07FF\u0888\u09F2\u09F3\u09FA\u09FB\u0AF1\u0B70\u0BF3-\u0BFA\u0C7F\u0D4F\u0D79\u0E3F\u0F01-\u0F03\u0F13\u0F15-\u0F17\u0F1A-\u0F1F\u0F34\u0F36\u0F38\u0FBE-\u0FC5\u0FC7-\u0FCC\u0FCE\u0FCF\u0FD5-\u0FD8\u109E\u109F\u1390-\u1399\u166D\u17DB\u1940\u19DE-\u19FF\u1B61-\u1B6A\u1B74-\u1B7C\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD\u1FFE\u2044\u2052\u207A-\u207C\u208A-\u208C\u20A0-\u20C1\u2100\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F\u218A\u218B\u2190-\u2307\u230C-\u2328\u232B-\u2429\u2440-\u244A\u249C-\u24E9\u2500-\u2767\u2794-\u27C4\u27C7-\u27E5\u27F0-\u2982\u2999-\u29D7\u29DC-\u29FB\u29FE-\u2B73\u2B76-\u2BFF\u2CE5-\u2CEA\u2E50\u2E51\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFF\u3004\u3012\u3013\u3020\u3036\u3037\u303E\u303F\u309B\u309C\u3190\u3191\u3196-\u319F\u31C0-\u31E5\u31EF\u3200-\u321E\u322A-\u3247\u3250\u3260-\u327F\u328A-\u32B0\u32C0-\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA700-\uA716\uA720\uA721\uA789\uA78A\uA828-\uA82B\uA836-\uA839\uAA77-\uAA79\uAB5B\uAB6A\uAB6B\uFB29\uFBB2-\uFBD2\uFD40-\uFD4F\uFD90\uFD91\uFDC8-\uFDCF\uFDFC-\uFDFF\uFE62\uFE64-\uFE66\uFE69\uFF04\uFF0B\uFF1C-\uFF1E\uFF3E\uFF40\uFF5C\uFF5E\uFFE0-\uFFE6\uFFE8-\uFFEE\uFFFC\uFFFD]|\uD800[\uDD37-\uDD3F\uDD79-\uDD89\uDD8C-\uDD8E\uDD90-\uDD9C\uDDA0\uDDD0-\uDDFC]|\uD802[\uDC77\uDC78\uDEC8]|\uD803[\uDD8E\uDD8F\uDED1-\uDED8]|\uD805\uDF3F|\uD807[\uDFD5-\uDFF1]|\uD81A[\uDF3C-\uDF3F\uDF45]|\uD82F\uDC9C|\uD833[\uDC00-\uDCEF\uDCFA-\uDCFC\uDD00-\uDEB3\uDEBA-\uDED0\uDEE0-\uDEF0\uDF50-\uDFC3]|\uD834[\uDC00-\uDCF5\uDD00-\uDD26\uDD29-\uDD64\uDD6A-\uDD6C\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDDEA\uDE00-\uDE41\uDE45\uDF00-\uDF56]|\uD835[\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85\uDE86]|\uD838[\uDD4F\uDEFF]|\uD83B[\uDCAC\uDCB0\uDD2E\uDEF0\uDEF1]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBF\uDCC1-\uDCCF\uDCD1-\uDCF5\uDD0D-\uDDAD\uDDE6-\uDE02\uDE10-\uDE3B\uDE40-\uDE48\uDE50\uDE51\uDE60-\uDE65\uDF00-\uDFFF]|\uD83D[\uDC00-\uDED8\uDEDC-\uDEEC\uDEF0-\uDEFC\uDF00-\uDFD9\uDFE0-\uDFEB\uDFF0]|\uD83E[\uDC00-\uDC0B\uDC10-\uDC47\uDC50-\uDC59\uDC60-\uDC87\uDC90-\uDCAD\uDCB0-\uDCBB\uDCC0\uDCC1\uDCD0-\uDCD8\uDD00-\uDE57\uDE60-\uDE6D\uDE70-\uDE7C\uDE80-\uDE8A\uDE8E-\uDEC6\uDEC8\uDECD-\uDEDC\uDEDF-\uDEEA\uDEEF-\uDEF8\uDF00-\uDF92\uDF94-\uDFEF\uDFFA]/,qt=/[ \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]/,Jt=new Map([[0,65533],[128,8364],[130,8218],[131,402],[132,8222],[133,8230],[134,8224],[135,8225],[136,710],[137,8240],[138,352],[139,8249],[140,338],[142,381],[145,8216],[146,8217],[147,8220],[148,8221],[149,8226],[150,8211],[151,8212],[152,732],[153,8482],[154,353],[155,8250],[156,339],[158,382],[159,376]]);function Yt(e){return e>=55296&&e<=57343||e>1114111?65533:Jt.get(e)??e}function Xt(e){let t=atob(e),n=t.length&-2,r=new Uint16Array(n/2);for(let e=0,i=0;e=L.ZERO&&e<=L.NINE}function en(e){return e>=L.UPPER_A&&e<=L.UPPER_F||e>=L.LOWER_A&&e<=L.LOWER_F}function tn(e){return e>=L.UPPER_A&&e<=L.UPPER_Z||e>=L.LOWER_A&&e<=L.LOWER_Z||$t(e)}function nn(e){return e===L.EQUALS||tn(e)}var R;(function(e){e[e.EntityStart=0]=`EntityStart`,e[e.NumericStart=1]=`NumericStart`,e[e.NumericDecimal=2]=`NumericDecimal`,e[e.NumericHex=3]=`NumericHex`,e[e.NamedEntity=4]=`NamedEntity`})(R||={});var z;(function(e){e[e.Legacy=0]=`Legacy`,e[e.Strict=1]=`Strict`,e[e.Attribute=2]=`Attribute`})(z||={});var rn=class{decodeTree;emitCodePoint;errors;constructor(e,t,n){this.decodeTree=e,this.emitCodePoint=t,this.errors=n}state=R.EntityStart;consumed=1;result=0;treeIndex=0;excess=1;decodeMode=z.Strict;runConsumed=0;startEntity(e){this.decodeMode=e,this.state=R.EntityStart,this.result=0,this.treeIndex=0,this.excess=1,this.consumed=1,this.runConsumed=0}write(e,t){switch(this.state){case R.EntityStart:return e.charCodeAt(t)===L.NUM?(this.state=R.NumericStart,this.consumed+=1,this.stateNumericStart(e,t+1)):(this.state=R.NamedEntity,this.stateNamedEntity(e,t));case R.NumericStart:return this.stateNumericStart(e,t);case R.NumericDecimal:return this.stateNumericDecimal(e,t);case R.NumericHex:return this.stateNumericHex(e,t);case R.NamedEntity:return this.stateNamedEntity(e,t)}}stateNumericStart(e,t){return t>=e.length?-1:(e.charCodeAt(t)|Qt)===L.LOWER_X?(this.state=R.NumericHex,this.consumed+=1,this.stateNumericHex(e,t+1)):(this.state=R.NumericDecimal,this.stateNumericDecimal(e,t))}stateNumericHex(e,t){for(;t>14;for(;t>7;if(this.runConsumed===0){let n=r&I.JUMP_TABLE;if(e.charCodeAt(t)!==n)return this.result===0?0:this.emitNotTerminatedNamedEntity();t++,this.excess++,this.runConsumed++}for(;this.runConsumed=e.length)return-1;let r=this.runConsumed-1,i=n[this.treeIndex+1+(r>>1)],a=r%2==0?i&255:i>>8&255;if(e.charCodeAt(t)!==a)return this.runConsumed=0,this.result===0?0:this.emitNotTerminatedNamedEntity();t++,this.excess++,this.runConsumed++}this.runConsumed=0,this.treeIndex+=1+(a>>1),r=n[this.treeIndex],i=(r&I.VALUE_LENGTH)>>14}if(t>=e.length)break;let a=e.charCodeAt(t);if(a===L.SEMI&&i!==0&&(r&I.FLAG13)!==0)return this.emitNamedEntityData(this.treeIndex,i,this.consumed+this.excess);if(this.treeIndex=on(n,r,this.treeIndex+Math.max(1,i),a),this.treeIndex<0)return this.result===0||this.decodeMode===z.Attribute&&(i===0||nn(a))?0:this.emitNotTerminatedNamedEntity();if(r=n[this.treeIndex],i=(r&I.VALUE_LENGTH)>>14,i!==0){if(a===L.SEMI)return this.emitNamedEntityData(this.treeIndex,i,this.consumed+this.excess);this.decodeMode!==z.Strict&&(r&I.FLAG13)===0&&(this.result=this.treeIndex,this.consumed+=this.excess,this.excess=0)}t++,this.excess++}return-1}emitNotTerminatedNamedEntity(){let{result:e,decodeTree:t}=this,n=(t[e]&I.VALUE_LENGTH)>>14;return this.emitNamedEntityData(e,n,this.consumed),this.errors?.missingSemicolonAfterCharacterReference(),this.consumed}emitNamedEntityData(e,t,n){let{decodeTree:r}=this;return this.emitCodePoint(t===1?r[e]&~(I.VALUE_LENGTH|I.FLAG13):r[e+1],n),t===3&&this.emitCodePoint(r[e+2],n),n}end(){switch(this.state){case R.NamedEntity:return this.result!==0&&(this.decodeMode!==z.Attribute||this.result===this.treeIndex)?this.emitNotTerminatedNamedEntity():0;case R.NumericDecimal:return this.emitNumericEntity(0,2);case R.NumericHex:return this.emitNumericEntity(0,3);case R.NumericStart:return this.errors?.absenceOfDigitsInNumericCharacterReference(this.consumed),0;case R.EntityStart:return 0}}};function an(e){let t=``,n=new rn(e,e=>t+=String.fromCodePoint(e));return function(e,r){let i=0,a=0;for(;(a=e.indexOf(`&`,a))>=0;){t+=e.slice(i,a),n.startEntity(r);let o=n.write(e,a+1);if(o<0){i=a+n.end();break}i=a+o,a=o===0?i+1:i}let o=t+e.slice(i);return t=``,o}}function on(e,t,n,r){let i=(t&I.BRANCH_LENGTH)>>7,a=t&I.JUMP_TABLE;if(i===0)return a!==0&&r===a?n:-1;if(a){let t=r-a;return t<0||t>=i?-1:e[n+t]-1}let o=i+1>>1,s=0,c=i-1;for(;s<=c;){let t=s+c>>>1,i=e[n+(t>>1)]>>(t&1)*8&255;if(ir)c=t-1;else return e[n+o+t]}return-1}var sn=an(Zt);function cn(e){return sn(e,z.Strict)}var ln=class{src_Any=Ht.source;src_Cc=Ut.source;src_Z=qt.source;src_P=Gt.source;src_ZPCc=[this.src_Z,this.src_P,this.src_Cc].join(`|`);src_ZCc=[this.src_Z,this.src_Cc].join(`|`);cache={};opts={maxLength:1e4,urlAuth:!1,schema_names:[]};constructor(e={}){this.opts={...this.opts,...e}}set(e={}){return this.opts={...this.opts,...e},this.cache={},this}escapeRE(e){return e.replace(/[.?*+^$[\]\\(){}|-]/g,`\\$&`)}nestedPairRE(e,t,n=4){let r=this.escapeRE(e),i=this.escapeRE(t),a=`(?:(?!${this.src_ZCc}|${r}|${i}).)`,o=`${r}${a}{0,1000}${i}`;for(let e=2;e<=n;e++)o=`${r}(?:${a}|${o}){0,1000}${i}`;return o}get_text_separators(){return this.cache.text_separators??=/[><\uff5c]/}get_pseudo_letter(){return this.cache.src_pseudo_letter??=RegExp(`(?:(?!${this.get_text_separators().source}|${this.src_ZPCc})${this.src_Any})`)}get_ipv4_addr(){return this.cache.src_ip4??=RegExp(`(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])[.]){3}(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])`)}get_ipv6_addr(){let e=`[0-9A-Fa-f]{1,4}`,t=`(?:(?:${e}:${e})|${this.get_ipv4_addr().source})`;return this.cache.src_ip6_addr??=RegExp(`(?:(?:${e}:){6}${t}|::(?:${e}:){5}${t}|(?:${e})?::(?:${e}:){4}${t}|(?:(?:${e}:){0,1}${e})?::(?:${e}:){3}${t}|(?:(?:${e}:){0,2}${e})?::(?:${e}:){2}${t}|(?:(?:${e}:){0,3}${e})?::${e}:${t}|(?:(?:${e}:){0,4}${e})?::${t}|(?:(?:${e}:){0,5}${e})?::${e}|(?:(?:${e}:){0,6}${e})?::)`)}get_ipv6_url_host(){return this.cache.src_ip6_host??=RegExp(`\\[${this.get_ipv6_addr().source}\\]`)}get_ipv6_mail_host(){return this.cache.src_ipv6_mail_host??=RegExp(`\\[IPv6:${this.get_ipv6_addr().source}\\]`)}get_auth(){return this.cache.src_auth??=RegExp(`(?:(?:(?!${this.src_ZCc}|[@/\\[\\]()]).){1,50}@)?`)}get_port(){return this.cache.src_port??=RegExp(`(?::(?:6(?:[0-4]\\d{3}|5(?:[0-4]\\d{2}|5(?:[0-2]\\d|3[0-5])))|[1-5]?\\d{1,4}))?`)}get_host_terminator(){return this.cache.src_host_terminator??=RegExp(`(?=$|${this.get_text_separators().source}|${this.src_ZPCc})(?!${this.opts[`---`]?`-(?!--)|`:`-|`}_|:\\d|\\.-|\\.(?!$|${this.src_ZPCc}))`)}get_path_terminator(){return this.cache.src_path_terminator??=RegExp(`${this.src_ZPCc}|${this.get_text_separators().source}`)}get_path(){return this.cache.src_path??=RegExp(`(?:[/?#](?:${this.nestedPairRE(`[`,`]`)}|${this.nestedPairRE(`(`,`)`)}|${this.nestedPairRE(`{`,`}`)}|\\"(?:(?!${this.src_ZCc}|["]).){1,100}\\"|\\'(?:(?!${this.src_ZCc}|[']).){1,100}\\'|\\'(?=${this.get_pseudo_letter().source}|[-])|\\.{2,20}[:]?[a-zA-Z0-9%/&]|\\.(?!${this.src_ZCc}|[.]|$)|`+(this.opts[`---`]?`\\-(?!--(?:[^-]|$))(?:-{0,19})|`:`\\-{1,20}|`)+`,(?!${this.src_ZCc}|$)|;(?!${this.src_ZCc}|$)|\\!{1,20}(?!${this.src_ZCc}|[!]|$)|\\?(?!${this.src_ZCc}|[?]|$)|`+this.get_path_extra().source+`[\\\\/:%@#&=_~*]|(?!${this.get_path_terminator().source}).){1,${this.opts.maxLength}}|\\/)?`)}get_mail_name(){return this.cache.src_mail_name??=RegExp("[-!#$%&'*+/=?^_`{|}~a-zA-Z0-9](?:[-!#$%&'*+/=?^_`{|}~a-zA-Z0-9]|[.](?=[-!#$%&'*+/=?^_`{|}~a-zA-Z0-9])){0,63}")}get_xn(){return this.cache.src_xn??=RegExp(`xn--[a-z0-9\\-]{1,59}`)}get_tld(){if(this.cache.tld)return this.cache.tld;let e=[...new Set(this.opts.tlds||[])].sort().reverse().join(`|`);return this.cache.tld=RegExp(`${e||`$#none#$`}|${this.get_xn().source}`),this.cache.tld}get_domain_root(){return this.cache.src_domain_root??=RegExp(`(?:`+this.get_xn().source+`|${this.get_pseudo_letter().source}{1,63})`)}get_domain(){return this.cache.src_domain??=RegExp(`(?:`+this.get_xn().source+`|(?:${this.get_pseudo_letter().source})|(?:${this.get_pseudo_letter().source}(?:-|${this.get_pseudo_letter().source}){0,61}${this.get_pseudo_letter().source}))`)}get_url_host_port(){return this.cache.url_host_port??=RegExp(`(?:`+this.get_ipv6_url_host().source+`|(?:(?:(?:${this.get_domain().source})\\.){0,10}${this.get_domain().source}))`+this.get_port().source+this.get_host_terminator().source)}get_fuzzy_url_host_port(){return this.cache.fuzzy_url_host_port??=RegExp(`(?:`+(this.opts.fuzzyIP?this.get_ipv4_addr().source+`|`:``)+`(?:(?:(?:${this.get_domain().source})\\.){1,10}(?:${this.get_tld().source})))`+this.get_host_terminator().source)}get_mail_host(){return this.cache.src_mail_host??=RegExp(`(?:`+this.get_ipv6_mail_host().source+`|(?:(?:(?:${this.get_domain().source})\\.){0,4}${this.get_domain().source}))`+this.get_host_terminator().source)}get_fuzzy_mail_host(){return this.cache.src_fuzzy_mail_host??=RegExp(`(?:`+this.get_ipv6_mail_host().source+`|(?:(?:(?:${this.get_domain().source})[.]){1,4}${this.get_domain_root().source}))`+this.get_host_terminator().source)}get_path_extra(){return this.cache.src_path_extra??=RegExp(``)}get_fuzzy_mail_host_search(){return this.cache.mail_fuzzy_host_search??=RegExp(`@${this.get_fuzzy_mail_host().source}`,`ig`)}get_fuzzy_link_search(){return this.cache.link_fuzzy_search??=RegExp(`(^|(?![.:/\\-_@])(?:[$+<=>^\`|\uff5c]|${this.src_ZPCc}))(?:(?![$+<=>^\`|\uff5c])${this.get_fuzzy_url_host_port().source}${this.get_path().source})`,`ig`)}get_http_validator(){return this.cache.http_validator??=RegExp(`\\/\\/`+(this.opts.urlAuth?this.get_auth().source:``)+this.get_url_host_port().source+this.get_path().source,`iy`)}get_relative_proto_validator(){return this.cache.relative_proto_validator??=RegExp((this.opts.urlAuth?this.get_auth().source:``)+`(?:localhost|${this.get_ipv6_url_host().source}|(?:(?:${this.get_domain().source})[.]){1,10}${this.get_domain_root().source})`+this.get_port().source+this.get_host_terminator().source+this.get_path().source,`iy`)}get_mail_name_validator(){return this.cache.mail_name_validator??=RegExp(`(?:^|${this.get_text_separators().source}|"|\\(|${this.src_ZCc})(${this.get_mail_name().source})$`)}get_mailto_validator(){return this.cache.mailto_validator??=RegExp(`${this.get_mail_name().source}@${this.get_mail_host().source}`,`iy`)}get_schema_names(){return this.cache.schema_names??=new RegExp((this.opts.schema_names||[]).map(e=>this.escapeRE(e)).join(`|`))}get_schema_search(){return this.cache.schema_search??=RegExp(`(^|(?!_)(?:[><\uff5c]|${this.src_ZPCc}))(${this.get_schema_names().source})`,`ig`)}get_schema_at_start(){return this.cache.schema_at_start??=RegExp(`^${this.get_schema_search().source}`,`i`)}},un={validate:(e,t,n)=>{let r=n.re.get_http_validator();r.lastIndex=t;let i=r.exec(e);return i?i[0].length:0},normalize:(e,t)=>t.normalize(e)},dn={"http:":un,"https:":un,"ftp:":un,"//":{validate:function(e,t,n){let r=n.re.get_relative_proto_validator();r.lastIndex=t;let i=r.exec(e);return i?t>=3&&e[t-3]===`:`||t>=3&&e[t-3]===`/`?0:i[0].length:0},normalize:(e,t)=>t.normalize(e)},"mailto:":{validate:function(e,t,n){let r=n.re.get_mailto_validator();r.lastIndex=t;let i=r.exec(e);return i?i[0].length:0},normalize:(e,t)=>t.normalize(e)}},fn=`a:cdefgilmnoqrstuwxz|b:abdefghijmnorstvwyz|c:acdfghiklmnoruvwxyz|d:ejkmoz|e:cegrstu|f:ijkmor|g:abdefghilmnpqrstuwy|h:kmnrtu|i:delmnoqrst|j:emop|k:eghimnprwyz|l:abcikrstuvy|m:acdeghklmnopqrstuvwxyz|n:acefgilopruz|o:m|p:aefghklmnrstwy|q:a|r:eosuw|s:abcdeghijklmnortuvxyz|t:cdfghjklmnortvwz|u:agksyz|v:aceginu|w:fs|y:et|z:amw`,pn=`biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|рф`;function mn(){let e=pn.split(`|`);return fn.split(`|`).forEach(t=>{let n=t.indexOf(`:`),r=t.slice(0,n);for(let i of t.slice(n+1))e.push(r+i)}),e}var hn={fuzzyLink:!1,fuzzyEmail:!0,fuzzyIP:!1,"---":!1,tlds:mn(),urlAuth:!1,maxLength:1e4},gn=class{schema;index;lastIndex;raw;text;url;constructor(e,t,n,r){let i=e.slice(n,r);this.schema=t.toLowerCase(),this.index=n,this.lastIndex=r,this.raw=i,this.text=i,this.url=i}},_n=class{__opts__;__schemas__;re;constructor(e={}){let{rebuilder:t,...n}=e;this.__opts__={...hn,...n},this.__schemas__={...dn},this.re=t||new ln,this.re.set({...this.__opts__,schema_names:Object.keys(this.__schemas__)})}add(e,t=null){if(!t)delete this.__schemas__[e];else{let n={normalize:(e,t)=>t.normalize(e),...t};this.__schemas__[e]=n}return this.re.set({...this.__opts__,schema_names:Object.keys(this.__schemas__)}),this}set(e={}){return this.__opts__={...this.__opts__,...e},this.re.set({...this.__opts__,schema_names:Object.keys(this.__schemas__)}),this}test(e){if(!e.length)return!1;let t,n;for(n=this.re.get_schema_search(),n.lastIndex=0;(t=n.exec(e))!==null;)if(this.testSchemaAt(e,t[2],n.lastIndex))return!0;if(this.__opts__.fuzzyLink&&this.__schemas__[`http:`]&&(n=this.re.get_fuzzy_link_search(),n.lastIndex=0,n.exec(e)!==null))return!0;if(this.__opts__.fuzzyEmail&&this.__schemas__[`mailto:`]&&e.indexOf(`@`)>=0){let n=this.re.get_fuzzy_mail_host_search(),r=this.re.get_mail_name_validator();for(n.lastIndex=0;(t=n.exec(e))!==null;){let n=e.slice(Math.max(0,t.index-65),t.index);if(r.test(n))return!0}}return!1}testSchemaAt(e,t,n){return this.__schemas__[t.toLowerCase()]?this.__schemas__[t.toLowerCase()].validate(e.slice(0,n+this.__opts__.maxLength),n,this):0}match(e){let t=[],n=this.re.get_schema_search(),r,i,a,o,s,c,l=!1,u=!1,d=!1,f=0;if(!e.length)return null;for(n.lastIndex=0,this.__opts__.fuzzyLink&&this.__schemas__[`http:`]&&(r=this.re.get_fuzzy_link_search(),r.lastIndex=0),this.__opts__.fuzzyEmail&&this.__schemas__[`mailto:`]&&(i=this.re.get_fuzzy_mail_host_search(),i.lastIndex=0,a=this.re.get_mail_name_validator());;){let p=Math.max(f-1,0);if(i&&a&&!d&&(!s||s.index=f)break;i.lastIndex=f)break;r.lastIndexm.lastIndex))&&(m=o);let h;if(!l)for(;;){if(!c){n.lastIndexm.index)break;let t=c;c=void 0;let r=this.testSchemaAt(e,t.schema,t.lastIndex);if(r){h={schema:t.schema,index:t.index,lastIndex:t.lastIndex+r};break}}let g=h;if((!g||s&&(s.indexg.lastIndex))&&(g=s),(!g||o&&(o.indexg.lastIndex))&&(g=o),!g)break;g===s?s=void 0:g===o&&(o=void 0);let _=new gn(e,g.schema,g.index,g.lastIndex);_.schema?this.__schemas__[_.schema].normalize(_,this):this.normalize(_),t.push(_),f=g.lastIndex}return t.length?t:null}matchAtStart(e){if(!e.length)return null;let t=this.re.get_schema_at_start().exec(e);if(!t)return null;let n=this.testSchemaAt(e,t[2],t[0].length);if(!n)return null;let r=new gn(e,t[2],t.index+t[1].length,t.index+t[0].length+n);return this.__schemas__[r.schema].normalize(r,this),r}tlds(e,t=!1){return e=Array.isArray(e)?e:[e],t?this.__opts__.tlds=this.__opts__.tlds.concat(e):this.__opts__.tlds=e,this.re.set({...this.__opts__,schema_names:Object.keys(this.__schemas__)}),this}normalize(e){e.schema||(e.url=`http://${e.url}`),e.schema===`mailto:`&&!/^mailto:/i.test(e.url)&&(e.url=`mailto:${e.url}`)}},B=2147483647,V=36,vn=1,yn=26,bn=38,xn=700,Sn=72,Cn=128,wn=`-`,Tn=/^xn--/,En=/[^\0-\x7F]/,Dn=/[\x2E\u3002\uFF0E\uFF61]/g,On={overflow:`Overflow: input needs wider integers to process`,"not-basic":`Illegal input >= 0x80 (not a basic code point)`,"invalid-input":`Invalid input`},kn=35,H=Math.floor,An=String.fromCharCode;function U(e){throw RangeError(On[e])}function jn(e,t){let n=[],r=e.length;for(;r--;)n[r]=t(e[r]);return n}function Mn(e,t){let n=e.split(`@`),r=``;n.length>1&&(r=n[0]+`@`,e=n[1]),e=e.replace(Dn,`.`);let i=jn(e.split(`.`),t).join(`.`);return r+i}function Nn(e){let t=[],n=0,r=e.length;for(;n=55296&&i<=56319&&nString.fromCodePoint(...e),Fn=function(e){return e>=48&&e<58?26+(e-48):e>=65&&e<91?e-65:e>=97&&e<123?e-97:V},In=function(e,t){return e+22+75*(e<26)-((t!=0)<<5)},Ln=function(e,t,n){let r=0;for(e=n?H(e/xn):e>>1,e+=H(e/t);e>455;r+=V)e=H(e/kn);return H(r+36*e/(e+bn))},Rn=function(e){let t=[],n=e.length,r=0,i=Cn,a=Sn,o=e.lastIndexOf(wn);o<0&&(o=0);for(let n=0;n=128&&U(`not-basic`),t.push(e.charCodeAt(n));for(let s=o>0?o+1:0;s=n&&U(`invalid-input`);let o=Fn(e.charCodeAt(s++));o>=V&&U(`invalid-input`),o>H((B-r)/t)&&U(`overflow`),r+=o*t;let c=i<=a?vn:i>=a+yn?yn:i-a;if(oH(B/l)&&U(`overflow`),t*=l}let c=t.length+1;a=Ln(r-o,c,o==0),H(r/c)>B-i&&U(`overflow`),i+=H(r/c),r%=c,t.splice(r++,0,i)}return String.fromCodePoint(...t)},zn=function(e){let t=[];e=Nn(e);let n=e.length,r=Cn,i=0,a=Sn;for(let n of e)n<128&&t.push(An(n));let o=t.length,s=o;for(o&&t.push(wn);s=r&&tH((B-i)/c)&&U(`overflow`),i+=(n-r)*c,r=n;for(let n of e)if(nB&&U(`overflow`),n===r){let e=i;for(let n=V;;n+=V){let r=n<=a?vn:n>=a+yn?yn:n-a;if(e{let n={};for(var r in e)Vn(n,r,{get:e[r],enumerable:!0});return t||Vn(n,Symbol.toStringTag,{value:`Module`}),n},Un=Hn({arrayReplaceAt:()=>Gn,asciiTrim:()=>lr,callable:()=>Wn,escapeHtml:()=>K,escapeRE:()=>rr,fromCodePoint:()=>W,isMdAsciiPunct:()=>or,isPunctChar:()=>ir,isPunctCharCode:()=>ar,isSpace:()=>q,isValidEntityCode:()=>Kn,isWhiteSpace:()=>J,lib:()=>ur,normalizeReference:()=>sr,unescapeAll:()=>G,unescapeMd:()=>Zn});function Wn(e){let t=function(...n){return Reflect.construct(e,n,new.target&&new.target!==t?new.target:e)};return Object.defineProperty(t,"name",{value:e.name}),Object.setPrototypeOf(t,e),t.prototype=e.prototype,t}function Gn(e,t,n){return[].concat(e.slice(0,t),n,e.slice(t+1))}function Kn(e){return!(e>=55296&&e<=57343||e>=64976&&e<=65007||(e&65535)==65535||(e&65535)==65534||e>=0&&e<=8||e===11||e>=14&&e<=31||e>=127&&e<=159||e>1114111)}function W(e){if(e>65535){e-=65536;let t=55296+(e>>10),n=56320+(e&1023);return String.fromCharCode(t,n)}return String.fromCharCode(e)}var qn=/\\([!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~])/g,Jn=RegExp(`${qn.source}|&([a-z#][a-z0-9]{1,31});`,`gi`),Yn=/^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))$/i;function Xn(e,t){if(t.charCodeAt(0)===35&&Yn.test(t)){let n=t[1].toLowerCase()===`x`?parseInt(t.slice(2),16):parseInt(t.slice(1),10);return Kn(n)?W(n):e}let n=cn(e);return n===e?e:n}function Zn(e){return e.indexOf(`\\`)<0?e:e.replace(qn,`$1`)}function G(e){return e.indexOf(`\\`)<0&&e.indexOf(`&`)<0?e:e.replace(Jn,function(e,t,n){return t||Xn(e,n)})}var Qn=/[&<>"]/,$n=/[&<>"]/g,er={"&":`&`,"<":`<`,">":`>`,'"':`"`};function tr(e){return er[e]}function K(e){return Qn.test(e)?e.replace($n,tr):e}var nr=/[.?*+^$[\]\\(){}|-]/g;function rr(e){return e.replace(nr,`\\$&`)}function q(e){switch(e){case 9:case 32:return!0}return!1}function J(e){if(e>=8192&&e<=8202)return!0;switch(e){case 9:case 10:case 11:case 12:case 13:case 32:case 160:case 5760:case 8239:case 8287:case 12288:return!0}return!1}function ir(e){return Gt.test(e)||Kt.test(e)}function ar(e){return ir(W(e))}function or(e){switch(e){case 33:case 34:case 35:case 36:case 37:case 38:case 39:case 40:case 41:case 42:case 43:case 44:case 45:case 46:case 47:case 58:case 59:case 60:case 61:case 62:case 63:case 64:case 91:case 92:case 93:case 94:case 95:case 96:case 123:case 124:case 125:case 126:return!0;default:return!1}}function sr(e){return e=e.trim().replace(/\s+/g,` `),e.toLowerCase().toUpperCase()}function cr(e){return e===32||e===9||e===10||e===13}function lr(e){let t=0;for(;t=t&&cr(e.charCodeAt(n));n--);return e.slice(t,n+1)}var ur={mdurl:Bt,ucmicro:Vt};function dr(e,t,n){let r,i,a,o,s=e.posMax,c=e.pos;for(e.pos=t+1,r=1;e.pos32))return a;if(r===41){if(o===0)break;o--}i++}return t===i||o!==0?a:(a.str=G(e.slice(t,i)),a.pos=i,a.ok=!0,a)}function pr(e,t,n,r){let i,a=t,o={ok:!1,can_continue:!1,pos:0,str:``,marker:0};if(r)o.str=r.str,o.marker=r.marker;else{if(a>=n)return o;let r=e.charCodeAt(a);if(r!==34&&r!==39&&r!==40)return o;t++,a++,r===40&&(r=41),o.marker=r}for(;afr,parseLinkLabel:()=>dr,parseLinkTitle:()=>pr});function hr(e){"@babel/helpers - typeof";return hr=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},hr(e)}function gr(e,t){if(hr(e)!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(hr(r)!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function _r(e){var t=gr(e,`string`);return hr(t)==`symbol`?t:t+``}function Y(e,t,n){return(t=_r(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var X=class{constructor(e,t,n){Y(this,`map`,null),Y(this,`level`,0),Y(this,`children`,null),Y(this,`content`,``),Y(this,`markup`,``),Y(this,`info`,``),Y(this,`block`,!1),Y(this,`hidden`,!1),this.type=e,this.tag=t,this.attrs=null,this.nesting=n,this.meta=null}attrIndex(e){if(!this.attrs)return-1;let t=this.attrs;for(let n=0,r=t.length;n=0&&(n=this.attrs[t][1]),n}attrJoin(e,t){let n=this.attrIndex(e);n<0?this.attrPush([e,t]):this.attrs[n][1]=`${this.attrs[n][1]} ${t}`}},vr=class{constructor(){Y(this,`__rules__`,[]),Y(this,`__cache__`,null)}__find__(e){for(let t=0;t{t.enabled&&t.alt.forEach(t=>{t&&e.add(t)})}),this.__cache__=Object.create(null),this.__cache__[``]=[],this.__rules__.forEach(e=>{e.enabled&&this.__cache__[``].push(e.fn)}),e.forEach(e=>{this.__cache__[e]=[],this.__rules__.forEach(t=>{t.enabled&&t.alt.indexOf(e)>=0&&this.__cache__[e].push(t.fn)})})}at(e,t,n={}){let r=this.__find__(e);if(r===-1)throw Error(`Parser rule not found: ${e}`);this.__rules__[r].fn=t,this.__rules__[r].alt=n.alt||[],this.__cache__=null}before(e,t,n,r={}){let i=this.__find__(e);if(i===-1)throw Error(`Parser rule not found: ${e}`);this.__rules__.splice(i,0,{name:t,enabled:!0,fn:n,alt:r.alt||[]}),this.__cache__=null}after(e,t,n,r={}){let i=this.__find__(e);if(i===-1)throw Error(`Parser rule not found: ${e}`);this.__rules__.splice(i+1,0,{name:t,enabled:!0,fn:n,alt:r.alt||[]}),this.__cache__=null}push(e,t,n={}){this.__rules__.push({name:e,enabled:!0,fn:t,alt:n.alt||[]}),this.__cache__=null}enable(e,t=!1){Array.isArray(e)||(e=[e]);let n=[];return e.forEach(e=>{let r=this.__find__(e);if(r<0){if(t)return;throw Error(`Rules manager: invalid rule name ${e}`)}this.__rules__[r].enabled=!0,n.push(e)}),this.__cache__=null,n}enableOnly(e,t=!1){Array.isArray(e)||(e=[e]),this.__rules__.forEach(e=>{e.enabled=!1}),this.enable(e,t)}disable(e,t=!1){Array.isArray(e)||(e=[e]);let n=[];return e.forEach(e=>{let r=this.__find__(e);if(r<0){if(t)return;throw Error(`Rules manager: invalid rule name ${e}`)}this.__rules__[r].enabled=!1,n.push(e)}),this.__cache__=null,n}getRules(e){return this.__cache__||this.__compile__(),this.__cache__[e]||[]}},Z={};Z.code_inline=function(e,t,n,r,i){let a=e[t];return`${K(a.content)}`},Z.code_block=function(e,t,n,r,i){let a=e[t];return`${K(e[t].content)}\n`},Z.fence=function(e,t,n,r,i){let a=e[t],o=a.info?G(a.info).trim():``,s=``,c=``;if(o){let e=o.split(/(\s+)/g);s=e[0],c=e.slice(2).join(``)}let l;if(l=n.highlight&&n.highlight(a.content,s,c)||K(a.content),l.indexOf(`${l}\n`}return`
${l}
\n`},Z.image=function(e,t,n,r,i){let a=e[t];return a.attrs[a.attrIndex(`alt`)][1]=i.renderInlineAsText(a.children,n,r),i.renderToken(e,t,n)},Z.hardbreak=function(e,t,n){return n.xhtmlOut?`
`:`
`},Z.softbreak=function(e,t,n){return n.breaks?n.xhtmlOut?`
`:`
`:` -`},Z.text=function(e,t){return K(e[t].content)},Z.html_block=function(e,t){return e[t].content},Z.html_inline=function(e,t){return e[t].content};var xr=class{constructor(){Y(this,`rules`,Object.assign({},Z))}renderAttrs(e){let t,n,r;if(!e.attrs)return``;for(r=``,t=0,n=e.attrs.length;t=0&&e[a].hidden&&e[a].nesting===0;)a--;r.block&&r.nesting!==-1&&a>=0&&e[a].hidden&&e[a].nesting===-1&&(i+=` +`},Z.text=function(e,t){return K(e[t].content)},Z.html_block=function(e,t){return e[t].content},Z.html_inline=function(e,t){return e[t].content};var yr=class{constructor(){Y(this,`rules`,Object.assign({},Z))}renderAttrs(e){let t,n,r;if(!e.attrs)return``;for(r=``,t=0,n=e.attrs.length;t=0&&e[a].hidden&&e[a].nesting===0;)a--;r.block&&r.nesting!==-1&&a>=0&&e[a].hidden&&e[a].nesting===-1&&(i+=` `),i+=(r.nesting===-1?` `:`>`,i}renderInline(e,t,n){let r=``,i=this.rules;for(let a=0,o=e.length;a\s]/i.test(e)}function Ar(e){return/^<\/a\s*>/i.test(e)}function jr(e){let t=e.tokens;if(e.md.options.linkify)for(let n=0,r=t.length;n=0;a--){let o=r[a];if(o.type===`link_close`){for(a--;r[a].level!==o.level&&r[a].type!==`link_open`;)a--;continue}if(o.type===`html_inline`&&(kr(o.content)&&i>0&&i--,Ar(o.content)&&i++),!(i>0)&&o.type===`text`&&e.md.linkify.test(o.content)){let i=o.content,s=e.md.linkify.match(i),c=[],l=o.level,u=0;s.length>0&&s[0].index===0&&a>0&&r[a-1].type===`text_special`&&(s=s.slice(1));for(let t=0;tu){let t=new e.Token(`text`,``,0);t.content=i.slice(u,o),t.level=l,c.push(t)}let d=new e.Token(`link_open`,`a`,1);d.attrs=[[`href`,r]],d.level=l++,d.markup=`linkify`,d.info=`auto`,c.push(d);let f=new e.Token(`text`,``,0);f.content=a,f.level=l,c.push(f);let p=new e.Token(`link_close`,`a`,-1);p.level=--l,p.markup=`linkify`,p.info=`auto`,c.push(p),u=s[t].lastIndex}if(u=0;n--){let r=e[n];r.type===`text`&&!t&&(r.content=r.content.replace(Pr,Ir)),r.type===`link_open`&&r.info===`auto`&&t--,r.type===`link_close`&&r.info===`auto`&&t++}}function Rr(e){let t=0;for(let n=e.length-1;n>=0;n--){let r=e[n];r.type===`text`&&!t&&Mr.test(r.content)&&(r.content=r.content.replace(/\+-/g,`±`).replace(/\.{2,}/g,`…`).replace(/([?!])…/g,`$1..`).replace(/([?!]){4,}/g,`$1$1$1`).replace(/,{2,}/g,`,`).replace(/(^|[^-])---(?=[^-]|$)/gm,`$1—`).replace(/(^|\s)--(?=\s|$)/gm,`$1–`).replace(/(^|[^-\s])--(?=[^-\s]|$)/gm,`$1–`)),r.type===`link_open`&&r.info===`auto`&&t--,r.type===`link_close`&&r.info===`auto`&&t++}}function zr(e){let t;if(e.md.options.typographer)for(t=e.tokens.length-1;t>=0;t--)e.tokens[t].type===`inline`&&(Nr.test(e.tokens[t].content)&&Lr(e.tokens[t].children),Mr.test(e.tokens[t].content)&&Rr(e.tokens[t].children))}var Br=/['"]/,Vr=/['"]/g,Hr=`’`;function Ur(e,t,n,r){e[t]||(e[t]=[]),e[t].push({pos:n,ch:r})}function Wr(e,t){let n=``,r=0;t.sort((e,t)=>e.pos-t.pos);for(let i=0;i=0&&!(r[n].level<=s);n--);if(r.length=n+1,o.type!==`text`)continue;let c=o.content,l=0,u=c.length;OUTER:for(;l=0)m=c.charCodeAt(o.index-1);else for(n=a-1;n>=0&&e[n].type!==`softbreak`&&e[n].type!==`hardbreak`;n--)if(e[n].content){m=e[n].content.charCodeAt(e[n].content.length-1);break}let h=32;if(l=48&&m<=57&&(f=d=!1),d&&f&&(d=g,f=_),!d&&!f){p&&Ur(i,a,o.index,Hr);continue}if(f)for(n=r.length-1;n>=0;n--){let e=r[n];if(r[n].level=0;t--)e.tokens[t].type!==`inline`||!Br.test(e.tokens[t].content)||Gr(e.tokens[t].children,e)}function qr(e){let t,n,r=e.length;for(t=0;t0&&this.level++,this.tokens.push(r),r}isEmpty(e){return this.bMarks[e]+this.tShift[e]>=this.eMarks[e]}skipEmptyLines(e){for(let t=this.lineMax;et;)if(!q(this.src.charCodeAt(--e)))return e+1;return e}skipChars(e,t){for(let n=this.src.length;en;)if(t!==this.src.charCodeAt(--e))return e+1;return e}getLines(e,t,n,r){if(e>=t)return``;let i=Array(t-e);for(let a=0,o=e;on?i[a]=Array(e-n+1).join(` `)+this.src.slice(c,l):i[a]=this.src.slice(c,l)}return i.join(``)}},Qr=65536;function $r(e,t){let n=e.bMarks[t]+e.tShift[t],r=e.eMarks[t];return e.src.slice(n,r)}function ei(e){let t=[],n=e.length,r=0,i=e.charCodeAt(r),a=!1,o=0,s=``;for(;rn)return!1;let i=t+1;if(e.sCount[i]=4)return!1;let a=e.bMarks[i]+e.tShift[i];if(a>=e.eMarks[i])return!1;let o=e.src.charCodeAt(a++);if(o!==124&&o!==45&&o!==58||a>=e.eMarks[i])return!1;let s=e.src.charCodeAt(a++);if(s!==124&&s!==45&&s!==58&&!q(s)||o===45&&q(s))return!1;for(;a=4)return!1;l=ei(c),l.length&&l[0]===``&&l.shift(),l.length&&l[l.length-1]===``&&l.pop();let d=l.length;if(d===0||d!==u.length)return!1;if(r)return!0;let f=e.parentType;e.parentType=`table`;let p=e.md.block.ruler.getRules(`blockquote`),m=e.push(`table_open`,`table`,1),h=[t,0];m.map=h;let g=e.push(`thead_open`,`thead`,1);g.map=[t,t+1];let _=e.push(`tr_open`,`tr`,1);_.map=[t,t+1];for(let t=0;t=4||(l=ei(c),l.length&&l[0]===``&&l.shift(),l.length&&l[l.length-1]===``&&l.pop(),y+=d-l.length,y>Qr))break;if(i===t+2){let n=e.push(`tbody_open`,`tbody`,1);n.map=v=[t+2,0]}let a=e.push(`tr_open`,`tr`,1);a.map=[i,i+1];for(let t=0;t=4){r++,i=r;continue}break}e.line=i;let a=e.push(`code_block`,`code`,0);return a.content=e.getLines(t,i,4+e.blkIndent,!1)+` -`,a.map=[t,e.line],!0}function ri(e,t,n,r){let i=e.bMarks[t]+e.tShift[t],a=e.eMarks[t];if(e.sCount[t]-e.blkIndent>=4||i+3>a)return!1;let o=e.src.charCodeAt(i);if(o!==126&&o!==96)return!1;let s=i;i=e.skipChars(i,o);let c=i-s;if(c<3)return!1;let l=e.src.slice(s,i),u=e.src.slice(i,a);if(o===96&&u.indexOf(String.fromCharCode(o))>=0)return!1;if(r)return!0;let d=t,f=!1;for(;d++,!(d>=n||(i=s=e.bMarks[d]+e.tShift[d],a=e.eMarks[d],i=4)&&(i=e.skipChars(i,o),!(i-s=4||e.src.charCodeAt(i)!==62)return!1;if(r)return!0;let s=[],c=[],l=[],u=[],d=e.md.block.ruler.getRules(`blockquote`),f=e.parentType;e.parentType=`blockquote`;let p=!1,m;for(m=t;m=a)break;if(e.src.charCodeAt(i++)===62&&!t){let t=e.sCount[m]+1,n,r;e.src.charCodeAt(i)===32?(i++,t++,r=!1,n=!0):e.src.charCodeAt(i)===9?(n=!0,(e.bsCount[m]+t)%4==3?(i++,t++,r=!1):r=!0):n=!1;let o=t;for(s.push(e.bMarks[m]),e.bMarks[m]=i;i=a,c.push(e.bsCount[m]),e.bsCount[m]=e.sCount[m]+1+ +!!n,l.push(e.sCount[m]),e.sCount[m]=o-t,u.push(e.tShift[m]),e.tShift[m]=i-e.bMarks[m];continue}if(p)break;let r=!1;for(let t=0,i=d.length;t`;let _=[t,0];g.map=_,e.md.block.tokenize(e,t,m);let v=e.push(`blockquote_close`,`blockquote`,-1);v.markup=`>`,e.lineMax=o,e.parentType=f,_[1]=e.line;for(let n=0;n=4)return!1;let a=e.bMarks[t]+e.tShift[t],o=e.src.charCodeAt(a++);if(o!==42&&o!==45&&o!==95)return!1;let s=1;for(;a=r)return-1;let a=e.src.charCodeAt(i++);if(a<48||a>57)return-1;for(;;){if(i>=r)return-1;if(a=e.src.charCodeAt(i++),a>=48&&a<=57){if(i-n>=10)return-1;continue}if(a===41||a===46)break;return-1}return i=4||e.listIndent>=0&&e.sCount[c]-e.listIndent>=4&&e.sCount[c]=e.blkIndent&&(u=!0);let d,f,p;if((p=si(e,c))>=0){if(d=!0,o=e.bMarks[c]+e.tShift[c],f=Number(e.src.slice(o,p-1)),u&&f!==1)return!1}else if((p=oi(e,c))>=0)d=!1;else return!1;if(u&&e.skipSpaces(p)>=e.eMarks[c])return!1;if(r)return!0;let m=e.src.charCodeAt(p-1),h=e.tokens.length;d?(s=e.push(`ordered_list_open`,`ol`,1),f!==1&&(s.attrs=[[`start`,f]])):s=e.push(`bullet_list_open`,`ul`,1);let g=[c,0];s.map=g,s.markup=String.fromCharCode(m);let _=!1,v=e.md.block.ruler.getRules(`list`),y=e.parentType;for(e.parentType=`list`;c=i?1:r-t,f>4&&(f=1);let h=t+f;s=e.push(`list_item_open`,`li`,1),s.markup=String.fromCharCode(m);let g=[c,0];s.map=g,d&&(s.info=e.src.slice(o,p-1));let y=e.tight,b=e.tShift[c],x=e.sCount[c],S=e.listIndent;if(e.listIndent=e.blkIndent,e.blkIndent=h,e.tight=!0,e.tShift[c]=u-e.bMarks[c],e.sCount[c]=r,u>=i&&e.isEmpty(c+1)?e.line=Math.min(e.line+2,n):e.md.block.tokenize(e,c,n),(!e.tight||_)&&(l=!1),_=e.line-c>1&&e.isEmpty(e.line-1),e.blkIndent=e.listIndent,e.listIndent=S,e.tShift[c]=b,e.sCount[c]=x,e.tight=y,s=e.push(`list_item_close`,`li`,-1),s.markup=String.fromCharCode(m),c=e.line,g[1]=c,c>=n||e.sCount[c]=4)break;let C=!1;for(let t=0,r=v.length;t=4||e.src.charCodeAt(i)!==91)return!1;function s(t){let n=e.lineMax;if(t>=n||e.isEmpty(t))return null;let r=!1;if(e.sCount[t]-e.blkIndent>3&&(r=!0),e.sCount[t]<0&&(r=!0),!r){let r=e.md.block.ruler.getRules(`reference`),i=e.parentType;e.parentType=`reference`;let a=!1;for(let i=0,o=r.length;i\`\\x00-\\x20]+|'[^']*'|"[^"]*"))?)*\\s*\\/?>`,pi=`<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>`,mi=RegExp(`^(?:${fi}|${pi}||<[?][\\s\\S]*?[?]>|]*>|)`),hi=RegExp(`^(?:${fi}|${pi})`),Q=[[/^<(script|pre|style|textarea)(?=(\s|>|$))/i,/<\/(script|pre|style|textarea)>/i,!0],[/^/,!0],[/^<\?/,/\?>/,!0],[/^/,!0],[/^/,!0],[RegExp(`^|$))`,`i`),/^$/,!0],[RegExp(`${hi.source}\\s*$`),/^$/,!1]];function gi(e,t,n,r){let i=e.bMarks[t]+e.tShift[t],a=e.eMarks[t];if(e.sCount[t]-e.blkIndent>=4||!e.md.options.html||e.src.charCodeAt(i)!==60)return!1;let o=e.src.slice(i,a),s=0;for(;s=4)return!1;let o=e.src.charCodeAt(i);if(o!==35||i>=a)return!1;let s=1;for(o=e.src.charCodeAt(++i);o===35&&i6||ii&&q(e.src.charCodeAt(c-1))&&(a=c),e.line=t+1;let l=e.push(`heading_open`,`h${s}`,1);l.markup=`########`.slice(0,s),l.map=[t,e.line];let u=e.push(`inline`,``,0);u.content=dr(e.src.slice(i,a)),u.map=[t,e.line],u.children=[];let d=e.push(`heading_close`,`h${s}`,-1);return d.markup=`########`.slice(0,s),!0}function vi(e,t,n){let r=e.md.block.ruler.getRules(`paragraph`);if(e.sCount[t]-e.blkIndent>=4)return!1;let i=e.parentType;e.parentType=`paragraph`;let a=0,o,s=t+1;for(;s3)continue;if(e.sCount[s]>=e.blkIndent){let t=e.bMarks[s]+e.tShift[s],n=e.eMarks[s];if(t=n))){a=o===61?1:2;break}}if(e.sCount[s]<0)continue;let t=!1;for(let i=0,a=r.length;i3||e.sCount[a]<0)continue;let t=!1;for(let i=0,o=r.length;i=n||e.sCount[o]=a){e.line=n;break}let t=e.line,c=!1;for(let a=0;a=e.line)throw Error(`block rule didn't increment state.line`);break}if(!c)throw Error(`none of the block rules matched`);e.tight=!s,e.isEmpty(e.line-1)&&(s=!0),o=e.line,o0&&(this.level++,this._prev_delimiters.push(this.delimiters),this.delimiters=[],i={delimiters:this.delimiters}),this.pendingLevel=this.level,this.tokens.push(r),this.tokens_meta.push(i),r}scanDelims(e,t){let n=this.posMax,r=this.src.charCodeAt(e),i;if(e===0)i=32;else if(e===1)i=this.src.charCodeAt(0),(i&63488)==55296&&(i=65533);else if(i=this.src.charCodeAt(e-1),(i&64512)==56320){let t=this.src.charCodeAt(e-2);i=(t&64512)==55296?65536+(t-55296<<10)+(i-56320):65533}else(i&64512)==55296&&(i=65533);let a=e;for(;a0)return!1;let n=e.pos,r=e.posMax;if(n+3>r||e.src.charCodeAt(n)!==58||e.src.charCodeAt(n+1)!==47||e.src.charCodeAt(n+2)!==47)return!1;let i=e.pending.match(Ti);if(!i)return!1;let a=i[1],o=e.md.linkify.matchAtStart(e.src.slice(n-a.length));if(!o)return!1;let s=o.url;if(s.length<=a.length)return!1;let c=s.length;for(;c>0&&s.charCodeAt(c-1)===42;)c--;c!==s.length&&(s=s.slice(0,c));let l=e.md.normalizeLink(s);if(!e.md.validateLink(l))return!1;if(!t){e.pending=e.pending.slice(0,-a.length);let t=e.push(`link_open`,`a`,1);t.attrs=[[`href`,l]],t.markup=`linkify`,t.info=`auto`;let n=e.push(`text`,``,0);n.content=e.md.normalizeLinkText(s);let r=e.push(`link_close`,`a`,-1);r.markup=`linkify`,r.info=`auto`}return e.pos+=s.length-a.length,!0}function Di(e,t){let n=e.pos;if(e.src.charCodeAt(n)!==10)return!1;let r=e.pending.length-1,i=e.posMax;if(!t)if(r>=0&&e.pending.charCodeAt(r)===32)if(r>=1&&e.pending.charCodeAt(r-1)===32){let t=r-1;for(;t>=1&&e.pending.charCodeAt(t-1)===32;)t--;e.pending=e.pending.slice(0,t),e.push(`hardbreak`,`br`,0)}else e.pending=e.pending.slice(0,-1),e.push(`softbreak`,`br`,0);else e.push(`softbreak`,`br`,0);for(n++;n?@[]^_\`{|}~-`.split(``).forEach(function(e){Oi[e.charCodeAt(0)]=1});function ki(e,t){let n=e.pos,r=e.posMax;if(e.src.charCodeAt(n)!==92||(n++,n>=r))return!1;let i=e.src.charCodeAt(n);if(i===10){for(t||e.push(`hardbreak`,`br`,0),n++;n=55296&&i<=56319&&n+1=56320&&t<=57343&&(a+=e.src[n+1],n++)}let o=`\\`+a;if(!t){let t=e.push(`text_special`,``,0);t.content=i<256&&Oi[i]!==0?a:o,t.markup=o,t.info=`escape`}return e.pos=n+1,!0}function Ai(e,t){let n=e.pos;if(e.src.charCodeAt(n)!==96)return!1;let r=n;n++;let i=e.posMax;for(;n=0;r--){let n=t[r];if(n.marker!==95&&n.marker!==42||n.end===-1)continue;let i=t[n.end],a=r>0&&t[r-1].end===n.end+1&&t[r-1].marker===n.marker&&t[r-1].token===n.token-1&&t[n.end+1].token===i.token+1,o=String.fromCharCode(n.marker),s=e.tokens[n.token];s.type=a?`strong_open`:`em_open`,s.tag=a?`strong`:`em`,s.nesting=1,s.markup=a?o+o:o,s.content=``;let c=e.tokens[i.token];c.type=a?`strong_close`:`em_close`,c.tag=a?`strong`:`em`,c.nesting=-1,c.markup=a?o+o:o,c.content=``,a&&(e.tokens[t[r-1].token].content=``,e.tokens[t[n.end+1].token].content=``,r--)}}function Li(e){let t=e.tokens_meta,n=e.tokens_meta.length;Ii(e,e.delimiters);for(let r=0;r=d)return!1;if(c=m,i=e.md.helpers.parseLinkDestination(e.src,m,e.posMax),i.ok){for(o=e.md.normalizeLink(i.str),e.md.validateLink(o)?m=i.pos:o=``,c=m;m=d||e.src.charCodeAt(m)!==41)&&(l=!0),m++}if(l){if(e.env.references===void 0)return!1;if(m=0?r=e.src.slice(c,m++):m=p+1):m=p+1,r||=e.src.slice(f,p),r=lr(r),a=e.env.references[r],!a)return e.pos=u,!1;o=a.href,s=a.title}if(!t){e.pos=f,e.posMax=p;let t=e.push(`link_open`,`a`,1),n=[[`href`,o]];if(t.attrs=n,s&&n.push([`title`,s]),r){let e=Object.create(null);e.label=r,t.meta=e}e.linkLevel++,e.md.inline.tokenize(e),e.linkLevel--,e.push(`link_close`,`a`,-1)}return e.pos=m,e.posMax=d,!0}function Bi(e,t){let n,r,i,a,o,s,c,l,u=``,d=e.pos,f=e.posMax;if(e.src.charCodeAt(e.pos)!==33||e.src.charCodeAt(e.pos+1)!==91)return!1;let p=e.pos+2,m=e.md.helpers.parseLinkLabel(e,e.pos+1,!1);if(m<0)return!1;if(a=m+1,a=f)return!1;for(l=a,s=e.md.helpers.parseLinkDestination(e.src,a,e.posMax),s.ok&&(u=e.md.normalizeLink(s.str),e.md.validateLink(u)?a=s.pos:u=``),l=a;a=f||e.src.charCodeAt(a)!==41)return e.pos=d,!1;a++}else{if(e.env.references===void 0)return!1;if(a=0?i=e.src.slice(l,a++):a=m+1):a=m+1,i||=e.src.slice(p,m),i=lr(i),o=e.env.references[i],!o)return e.pos=d,!1;u=o.href,c=o.title}if(!t){r=e.src.slice(p,m);let t=[];e.md.inline.parse(r,e.md,e.env,t);let n=e.push(`image`,`img`,0),a=[[`src`,u],[`alt`,``]];if(n.attrs=a,n.children=t,n.content=r,c&&a.push([`title`,c]),i){let e=Object.create(null);e.label=i,n.meta=e}}return e.pos=a,e.posMax=f,!0}var Vi=/^([a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)$/,Hi=/^([a-zA-Z][a-zA-Z0-9+.-]{1,31}):([^<>\x00-\x20]*)$/;function Ui(e,t){let n=e.pos;if(e.src.charCodeAt(n)!==60)return!1;let r=e.pos,i=e.posMax;for(;;){if(++n>=i)return!1;let t=e.src.charCodeAt(n);if(t===60)return!1;if(t===62)break}let a=e.src.slice(r+1,n);if(Hi.test(a)){let n=e.md.normalizeLink(a);if(!e.md.validateLink(n))return!1;if(!t){let t=e.push(`link_open`,`a`,1);t.attrs=[[`href`,n]],t.markup=`autolink`,t.info=`auto`;let r=e.push(`text`,``,0);r.content=e.md.normalizeLinkText(a);let i=e.push(`link_close`,`a`,-1);i.markup=`autolink`,i.info=`auto`}return e.pos+=a.length+2,!0}if(Vi.test(a)){let n=e.md.normalizeLink(`mailto:${a}`);if(!e.md.validateLink(n))return!1;if(!t){let t=e.push(`link_open`,`a`,1);t.attrs=[[`href`,n]],t.markup=`autolink`,t.info=`auto`;let r=e.push(`text`,``,0);r.content=e.md.normalizeLinkText(a);let i=e.push(`link_close`,`a`,-1);i.markup=`autolink`,i.info=`auto`}return e.pos+=a.length+2,!0}return!1}function Wi(e){return/^\s]/i.test(e)}function Gi(e){return/^<\/a\s*>/i.test(e)}function Ki(e){let t=e|32;return t>=97&&t<=122}function qi(e,t){if(!e.md.options.html)return!1;let n=e.posMax,r=e.pos;if(e.src.charCodeAt(r)!==60||r+2>=n)return!1;let i=e.src.charCodeAt(r+1);if(i!==33&&i!==63&&i!==47&&!Ki(i))return!1;let a=e.src.slice(r).match(mi);if(!a)return!1;if(!t){let t=e.push(`html_inline`,``,0);t.content=a[0],Wi(t.content)&&e.linkLevel++,Gi(t.content)&&e.linkLevel--}return e.pos+=a[0].length,!0}var Ji=/^&#((?:x[a-f0-9]{1,6}|[0-9]{1,7}));/i,Yi=/^&([a-z][a-z0-9]{1,31});/i;function Xi(e,t){let n=e.pos,r=e.posMax;if(e.src.charCodeAt(n)!==38||n+1>=r)return!1;if(e.src.charCodeAt(n+1)===35){let r=e.src.slice(n).match(Ji);if(r){if(!t){let t=r[1][0].toLowerCase()===`x`?parseInt(r[1].slice(1),16):parseInt(r[1],10),n=e.push(`text_special`,``,0);n.content=Jn(t)?W(t):W(65533),n.markup=r[0],n.info=`entity`}return e.pos+=r[0].length,!0}}else{let r=e.src.slice(n).match(Yi);if(r){let n=un(r[0]);if(n!==r[0]){if(!t){let t=e.push(`text_special`,``,0);t.content=n,t.markup=r[0],t.info=`entity`}return e.pos+=r[0].length,!0}}}return!1}function Zi(e){let t={},n=e.length;if(!n)return;let r=0,i=-2,a=[];for(let o=0;os;c-=a[c]+1){let t=e[c];if(t.marker===n.marker&&t.open&&t.end<0){let r=!1;if((t.close||n.open)&&(t.length+n.length)%3==0&&(t.length%3!=0||n.length%3!=0)&&(r=!0),!r){let r=c>0&&!e[c-1].open?a[c-1]+1:0;a[o]=o-c+r,a[c]=r,n.open=!1,t.end=o,t.close=!1,l=-1,i=-2;break}}}l!==-1&&(t[n.marker][(n.open?3:0)+(n.length||0)%3]=l)}}function Qi(e){let t=e.tokens_meta,n=e.tokens_meta.length;Zi(e.delimiters);for(let e=0;e0&&r++,i[t].type===`text`&&t+1=e.pos)throw Error(`inline rule didn't increment state.pos`);break}}else e.pos=e.posMax;o||e.pos++,a[t]=e.pos}tokenize(e){let t=this.ruler.getRules(``),n=t.length,r=e.posMax,i=e.md.options.maxNesting;for(;e.pos=e.pos)throw Error(`inline rule didn't increment state.pos`);break}}if(o){if(e.pos>=r)break;continue}e.pending+=e.src[e.pos++]}e.pending&&e.pushPending()}parse(e,t,n,r){let i=new this.State(e,t,n,r);this.tokenize(i);let a=this.ruler2.getRules(``),o=a.length;for(let e=0;e=0))try{t.hostname=Hn.toASCII(t.hostname)}catch{}return F(kt(t))}normalizeLinkText(e){let t=Vt(e,!0);if(t.hostname&&(!t.protocol||oa.indexOf(t.protocol)>=0))try{t.hostname=Hn.toUnicode(t.hostname)}catch{}return P(kt(t),P.defaultChars+`%`)}constructor(...e){Y(this,`inline`,new na),Y(this,`block`,new xi),Y(this,`core`,new Xr),Y(this,`renderer`,new xr),Y(this,`linkify`,new yn),Y(this,`utils`,Gn),Y(this,`helpers`,Object.assign({},gr));let[t,n]=e;typeof t==`string`?(this.configure(t),n&&this.set(n)):(this.configure(`default`),this.set(t||{}))}set(e){return Object.assign(this.options,e),this}configure(e){let t;if(typeof e==`string`){let n=e;if(t=ra[n],!t)throw Error(`Wrong 'markdown-it' preset "${n}", check name`)}else t=e;if(!t)throw Error("Wrong `markdown-it` preset, can't be empty");t.options&&(this.options={...t.options});let n=t.components;if(n){[`core`,`block`,`inline`].forEach(e=>{let t=n[e]?.rules;t&&this[e].ruler.enableOnly(t)});let e=n.inline?.rules2;e&&this.inline.ruler2.enableOnly(e)}return this}enable(e,t=!1){let n=[];Array.isArray(e)||(e=[e]),[`core`,`block`,`inline`].forEach(t=>{n=n.concat(this[t].ruler.enable(e,!0))}),n=n.concat(this.inline.ruler2.enable(e,!0));let r=e.filter(e=>n.indexOf(e)<0);if(r.length&&!t)throw Error(`MarkdownIt. Failed to enable unknown rule(s): ${r}`);return this}disable(e,t=!1){let n=[];Array.isArray(e)||(e=[e]),[`core`,`block`,`inline`].forEach(t=>{n=n.concat(this[t].ruler.disable(e,!0))}),n=n.concat(this.inline.ruler2.disable(e,!0));let r=e.filter(e=>n.indexOf(e)<0);if(r.length&&!t)throw Error(`MarkdownIt. Failed to disable unknown rule(s): ${r}`);return this}use(e,...t){return e.apply(e,[this,...t]),this}parse(e,t){if(typeof e!=`string`)throw Error(`Input data should be a String`);let n=new this.core.State(e,this,t);return this.core.process(n),n.tokens}render(e,t={}){return this.renderer.render(this.parse(e,t),this.options,t)}parseInline(e,t){let n=new this.core.State(e,this,t);return n.inlineMode=!0,this.core.process(n),n.tokens}renderInline(e,t={}){return this.renderer.render(this.parseInline(e,t),this.options,t)}};Y($,`Token`,X),Y($,`Ruler`,br),Y($,`Renderer`,xr),Y($,`ParserCore`,Xr),Y($,`StateCore`,Sr),Y($,`ParserBlock`,xi),Y($,`StateBlock`,Zr),Y($,`ParserInline`,na),Y($,`StateInline`,Si);var sa=Kn($);function ca(e={}){let t=new sa(e);return t.linkify.set({fuzzyLink:!0}),t}var la={class:`cb`},ua={class:`cb-bar`},da={class:`cb-lang`},fa=[`title`],pa={class:`cb-pre`},ma=[`innerHTML`],ha={key:0,class:`cb-fade`},ga=me({__name:`CodeBlock`,props:{code:{type:String,required:!0},lang:{type:String,default:``},collapseAfter:{type:Number,default:24}},setup(e){let t=e,i=w(()=>t.code.split(` -`).length),a=w(()=>i.value>t.collapseAfter),c=d(a.value),l=d(Ct(t.code,t.lang)),u=null,m=0;s(()=>t.code,()=>{let e=Date.now()-m,n=()=>{m=Date.now(),l.value=Ct(t.code,t.lang)};e>=80?n():(clearTimeout(u),u=setTimeout(n,80-e))}),n(()=>clearTimeout(u));let _=d(!1),v=null;async function b(){await Se(t.code)&&(_.value=!0,clearTimeout(v),v=setTimeout(()=>{_.value=!1},1200))}return(t,n)=>(r(),g(`div`,la,[h(`div`,ua,[h(`span`,da,p(e.lang||`text`),1),h(`button`,{class:`cb-copy`,type:`button`,title:_.value?`Copied`:`Copy code`,onClick:b},[(r(),x(o(_.value?f(D):f(k)),{class:`w-3 h-3`})),S(` `+p(_.value?`Copied`:`Copy`),1)],8,fa)]),h(`div`,{class:y([`cb-scroll`,{"cb-clamped":c.value}])},[h(`pre`,pa,[h(`code`,{class:`hljs`,innerHTML:l.value},null,8,ma)]),c.value?(r(),g(`div`,ha)):T(``,!0)],2),a.value?(r(),g(`button`,{key:0,class:`cb-expand`,type:`button`,onClick:n[0]||=e=>c.value=!c.value},[(r(),x(o(c.value?f(Oe):f(De)),{class:`w-3 h-3`})),S(` `+p(c.value?`Show all ${i.value} lines`:`Collapse`),1)])):T(``,!0)]))}},[[`__scopeId`,`data-v-d48d08ad`]]),_a={class:`rounded-lg border border-border/70 bg-surface/40`},va=[`aria-expanded`],ya={key:0,class:`px-3 pb-2.5`},ba={class:`border-t border-border/70 pt-2 text-xs leading-relaxed text-foreground-muted font-mono whitespace-pre-wrap break-words`},xa=me({__name:`ThinkingBlock`,props:{part:{type:Object,required:!0}},setup(e){let t=e,n=w(()=>!!t.part.streaming),a=d(Date.now()),o=d(null),c=null,l=w(()=>o.value==null?t.part.startedAt==null?null:Math.max(0,Math.round((a.value-t.part.startedAt)/1e3)):o.value),m=w(()=>{if(n.value){let e=l.value;return e==null?`Thinking…`:`Thinking… ${e}s`}let e=l.value;return e==null?`Reasoning`:`Thought for ${e}s`}),_=d(!1),b=d(n.value);function x(){_.value=!0,b.value=!b.value}function S(){C(),c=setInterval(()=>{a.value=Date.now()},1e3)}function C(){c&&=(clearInterval(c),null)}return s(n,(e,n)=>{e?(_.value||(b.value=!0),S()):(t.part.startedAt!=null&&(o.value=Math.max(0,Math.round((Date.now()-t.part.startedAt)/1e3))),C(),n&&!_.value&&(b.value=!1))}),u(()=>{n.value&&S()}),i(C),(t,i)=>(r(),g(`div`,_a,[h(`button`,{type:`button`,class:`flex w-full items-center gap-2 rounded-lg px-3 py-2 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary`,"aria-expanded":b.value,onClick:x},[v(f(Ee),{class:y([`w-3.5 h-3.5 shrink-0`,n.value?`text-primary`:`text-foreground-muted`])},null,8,[`class`]),h(`span`,{class:y([`text-xs font-medium`,n.value?`thinking-shimmer text-foreground`:`text-foreground-muted`])},p(m.value),3),i[0]||=h(`span`,{class:`flex-1`},null,-1),v(f(O),{class:y([`w-3.5 h-3.5 shrink-0 text-foreground-muted transition-transform duration-150`,{"rotate-180":b.value}])},null,8,[`class`])],8,va),b.value?(r(),g(`div`,ya,[h(`div`,ba,p(e.part.text),1)])):T(``,!0)]))}},[[`__scopeId`,`data-v-e0c99020`]]),Sa={key:0},Ca=[`innerHTML`],wa=me({__name:`MessagePart`,props:{part:{type:Object,required:!0}},setup(e){let t=e,i=ca({html:!1,linkify:!0,breaks:!0,highlight(e,t){if(t&&wt.getLanguage(t))try{return wt.highlight(e,{language:t,ignoreIllegals:!0}).value}catch{}return``}});function a(e){e||=``;let t;try{t=i.parse(e,{})}catch{return[{type:`html`,html:i.render(e)}]}let n=[],r=[],a=()=>{r.length&&(n.push({type:`html`,html:i.renderer.render(r,i.options,{})}),r=[])};for(let e of t)e.type===`fence`?(a(),n.push({type:`code`,code:e.content.replace(/\n$/,``),lang:(e.info||``).trim().split(/\s+/)[0]})):r.push(e);return a(),n}let o=d(a(t.part.text)),c=null,l=0;return s(()=>t.part.text,()=>{let e=Date.now()-l,n=()=>{l=Date.now(),o.value=a(t.part.text)};e>=80?n():(clearTimeout(c),c=setTimeout(n,80-e))}),n(()=>clearTimeout(c)),(t,n)=>e.part.type===`text`?(r(),g(`div`,Sa,[(r(!0),g(C,null,b(o.value,(e,t)=>(r(),g(C,{key:t},[e.type===`code`?(r(),x(ga,{key:0,code:e.code,lang:e.lang},null,8,[`code`,`lang`])):(r(),g(`div`,{key:1,class:`md-body`,innerHTML:e.html},null,8,Ca))],64))),128))])):e.part.type===`thinking`?(r(),x(xa,{key:1,part:e.part},null,8,[`part`])):T(``,!0)}},[[`__scopeId`,`data-v-96385b47`]]),Ta={key:0,class:`flex max-w-[85%] flex-col items-end`},Ea={class:`mt-1.5 flex items-center gap-2`},Da={class:`rounded-2xl rounded-br-md bg-primary px-3.5 py-2.5 text-sm leading-relaxed text-primary-foreground`},Oa={class:`mt-1 flex items-center gap-1`},ka={key:1,class:`w-full text-sm leading-relaxed text-foreground`},Aa={class:`mt-1.5 flex items-center gap-1`},ja=[`title`],Ma=`inline-flex items-center rounded-md px-1.5 py-1 text-[11px] text-foreground-muted opacity-0 transition-[opacity,color,background-color] hover:bg-surface-hover hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-background group-hover:opacity-100 max-md:opacity-100`,Na=Object.assign({name:`AIMessage`},{__name:`Message`,props:{role:{type:String,required:!0,validator:e=>e===`user`||e===`assistant`},parts:{type:Array,default:()=>[]},canRegenerate:{type:Boolean,default:!1},editable:{type:Boolean,default:!1},deletable:{type:Boolean,default:!1}},emits:[`regenerate`,`edit`,`delete`],setup(e,{emit:t}){let n=e,i=t,a=w(()=>n.parts.filter(e=>e.type===`text`&&e.text).map(e=>e.text).join(` +`}return r}render(e,t,n){let r=``,i=this.rules;for(let a=0,o=e.length;a\s]/i.test(e)}function Or(e){return/^<\/a\s*>/i.test(e)}function kr(e){let t=e.tokens;if(e.md.options.linkify)for(let n=0,r=t.length;n=0;a--){let o=r[a];if(o.type===`link_close`){for(a--;r[a].level!==o.level&&r[a].type!==`link_open`;)a--;continue}if(o.type===`html_inline`&&(Dr(o.content)&&i>0&&i--,Or(o.content)&&i++),!(i>0)&&o.type===`text`&&e.md.linkify.test(o.content)){let i=o.content,s=e.md.linkify.match(i),c=[],l=o.level,u=0;s.length>0&&s[0].index===0&&a>0&&r[a-1].type===`text_special`&&(s=s.slice(1));for(let t=0;tu){let t=new e.Token(`text`,``,0);t.content=i.slice(u,o),t.level=l,c.push(t)}let d=new e.Token(`link_open`,`a`,1);d.attrs=[[`href`,r]],d.level=l++,d.markup=`linkify`,d.info=`auto`,c.push(d);let f=new e.Token(`text`,``,0);f.content=a,f.level=l,c.push(f);let p=new e.Token(`link_close`,`a`,-1);p.level=--l,p.markup=`linkify`,p.info=`auto`,c.push(p),u=s[t].lastIndex}if(u=0;n--){let r=e[n];r.type===`text`&&!t&&(r.content=r.content.replace(Mr,Pr)),r.type===`link_open`&&r.info===`auto`&&t--,r.type===`link_close`&&r.info===`auto`&&t++}}function Ir(e){let t=0;for(let n=e.length-1;n>=0;n--){let r=e[n];r.type===`text`&&!t&&Ar.test(r.content)&&(r.content=r.content.replace(/\+-/g,`±`).replace(/\.{2,}/g,`…`).replace(/([?!])…/g,`$1..`).replace(/([?!]){4,}/g,`$1$1$1`).replace(/,{2,}/g,`,`).replace(/(^|[^-])---(?=[^-]|$)/gm,`$1—`).replace(/(^|\s)--(?=\s|$)/gm,`$1–`).replace(/(^|[^-\s])--(?=[^-\s]|$)/gm,`$1–`)),r.type===`link_open`&&r.info===`auto`&&t--,r.type===`link_close`&&r.info===`auto`&&t++}}function Lr(e){let t;if(e.md.options.typographer)for(t=e.tokens.length-1;t>=0;t--)e.tokens[t].type===`inline`&&(jr.test(e.tokens[t].content)&&Fr(e.tokens[t].children),Ar.test(e.tokens[t].content)&&Ir(e.tokens[t].children))}var Rr=/['"]/,zr=/['"]/g,Br=`’`;function Vr(e,t,n,r){e[t]||(e[t]=[]),e[t].push({pos:n,ch:r})}function Hr(e,t){let n=``,r=0;t.sort((e,t)=>e.pos-t.pos);for(let i=0;i=0&&!(r[n].level<=s);n--);if(r.length=n+1,o.type!==`text`)continue;let c=o.content,l=0,u=c.length;OUTER:for(;l=0)m=c.charCodeAt(o.index-1);else for(n=a-1;n>=0&&e[n].type!==`softbreak`&&e[n].type!==`hardbreak`;n--)if(e[n].content){m=e[n].content.charCodeAt(e[n].content.length-1);break}let h=32;if(l=48&&m<=57&&(f=d=!1),d&&f&&(d=g,f=_),!d&&!f){p&&Vr(i,a,o.index,Br);continue}if(f)for(n=r.length-1;n>=0;n--){let e=r[n];if(r[n].level=0;t--)e.tokens[t].type!==`inline`||!Rr.test(e.tokens[t].content)||Ur(e.tokens[t].children,e)}function Gr(e){let t,n,r=e.length;for(t=0;t0&&this.level++,this.tokens.push(r),r}isEmpty(e){return this.bMarks[e]+this.tShift[e]>=this.eMarks[e]}skipEmptyLines(e){for(let t=this.lineMax;et;)if(!q(this.src.charCodeAt(--e)))return e+1;return e}skipChars(e,t){for(let n=this.src.length;en;)if(t!==this.src.charCodeAt(--e))return e+1;return e}getLines(e,t,n,r){if(e>=t)return``;let i=Array(t-e);for(let a=0,o=e;on?i[a]=Array(e-n+1).join(` `)+this.src.slice(c,l):i[a]=this.src.slice(c,l)}return i.join(``)}},Xr=65536;function Zr(e,t){let n=e.bMarks[t]+e.tShift[t],r=e.eMarks[t];return e.src.slice(n,r)}function Qr(e){let t=[],n=e.length,r=0,i=e.charCodeAt(r),a=!1,o=0,s=``;for(;rn)return!1;let i=t+1;if(e.sCount[i]=4)return!1;let a=e.bMarks[i]+e.tShift[i];if(a>=e.eMarks[i])return!1;let o=e.src.charCodeAt(a++);if(o!==124&&o!==45&&o!==58||a>=e.eMarks[i])return!1;let s=e.src.charCodeAt(a++);if(s!==124&&s!==45&&s!==58&&!q(s)||o===45&&q(s))return!1;for(;a=4)return!1;l=Qr(c),l.length&&l[0]===``&&l.shift(),l.length&&l[l.length-1]===``&&l.pop();let d=l.length;if(d===0||d!==u.length)return!1;if(r)return!0;let f=e.parentType;e.parentType=`table`;let p=e.md.block.ruler.getRules(`blockquote`),m=e.push(`table_open`,`table`,1),h=[t,0];m.map=h;let g=e.push(`thead_open`,`thead`,1);g.map=[t,t+1];let _=e.push(`tr_open`,`tr`,1);_.map=[t,t+1];for(let t=0;t=4||(l=Qr(c),l.length&&l[0]===``&&l.shift(),l.length&&l[l.length-1]===``&&l.pop(),y+=d-l.length,y>Xr))break;if(i===t+2){let n=e.push(`tbody_open`,`tbody`,1);n.map=v=[t+2,0]}let a=e.push(`tr_open`,`tr`,1);a.map=[i,i+1];for(let t=0;t=4){r++,i=r;continue}break}e.line=i;let a=e.push(`code_block`,`code`,0);return a.content=e.getLines(t,i,4+e.blkIndent,!1)+` +`,a.map=[t,e.line],!0}function ti(e,t,n,r){let i=e.bMarks[t]+e.tShift[t],a=e.eMarks[t];if(e.sCount[t]-e.blkIndent>=4||i+3>a)return!1;let o=e.src.charCodeAt(i);if(o!==126&&o!==96)return!1;let s=i;i=e.skipChars(i,o);let c=i-s;if(c<3)return!1;let l=e.src.slice(s,i),u=e.src.slice(i,a);if(o===96&&u.indexOf(String.fromCharCode(o))>=0)return!1;if(r)return!0;let d=t,f=!1;for(;d++,!(d>=n||(i=s=e.bMarks[d]+e.tShift[d],a=e.eMarks[d],i=4)&&(i=e.skipChars(i,o),!(i-s=4||e.src.charCodeAt(i)!==62)return!1;if(r)return!0;let s=[],c=[],l=[],u=[],d=e.md.block.ruler.getRules(`blockquote`),f=e.parentType;e.parentType=`blockquote`;let p=!1,m;for(m=t;m=a)break;if(e.src.charCodeAt(i++)===62&&!t){let t=e.sCount[m]+1,n,r;e.src.charCodeAt(i)===32?(i++,t++,r=!1,n=!0):e.src.charCodeAt(i)===9?(n=!0,(e.bsCount[m]+t)%4==3?(i++,t++,r=!1):r=!0):n=!1;let o=t;for(s.push(e.bMarks[m]),e.bMarks[m]=i;i=a,c.push(e.bsCount[m]),e.bsCount[m]=e.sCount[m]+1+ +!!n,l.push(e.sCount[m]),e.sCount[m]=o-t,u.push(e.tShift[m]),e.tShift[m]=i-e.bMarks[m];continue}if(p)break;let r=!1;for(let t=0,i=d.length;t`;let _=[t,0];g.map=_,e.md.block.tokenize(e,t,m);let v=e.push(`blockquote_close`,`blockquote`,-1);v.markup=`>`,e.lineMax=o,e.parentType=f,_[1]=e.line;for(let n=0;n=4)return!1;let a=e.bMarks[t]+e.tShift[t],o=e.src.charCodeAt(a++);if(o!==42&&o!==45&&o!==95)return!1;let s=1;for(;a=r)return-1;let a=e.src.charCodeAt(i++);if(a<48||a>57)return-1;for(;;){if(i>=r)return-1;if(a=e.src.charCodeAt(i++),a>=48&&a<=57){if(i-n>=10)return-1;continue}if(a===41||a===46)break;return-1}return i=4||e.listIndent>=0&&e.sCount[c]-e.listIndent>=4&&e.sCount[c]=e.blkIndent&&(u=!0);let d,f,p;if((p=ai(e,c))>=0){if(d=!0,o=e.bMarks[c]+e.tShift[c],f=Number(e.src.slice(o,p-1)),u&&f!==1)return!1}else if((p=ii(e,c))>=0)d=!1;else return!1;if(u&&e.skipSpaces(p)>=e.eMarks[c])return!1;if(r)return!0;let m=e.src.charCodeAt(p-1),h=e.tokens.length;d?(s=e.push(`ordered_list_open`,`ol`,1),f!==1&&(s.attrs=[[`start`,f]])):s=e.push(`bullet_list_open`,`ul`,1);let g=[c,0];s.map=g,s.markup=String.fromCharCode(m);let _=!1,v=e.md.block.ruler.getRules(`list`),y=e.parentType;for(e.parentType=`list`;c=i?1:r-t,f>4&&(f=1);let h=t+f;s=e.push(`list_item_open`,`li`,1),s.markup=String.fromCharCode(m);let g=[c,0];s.map=g,d&&(s.info=e.src.slice(o,p-1));let y=e.tight,b=e.tShift[c],x=e.sCount[c],S=e.listIndent;if(e.listIndent=e.blkIndent,e.blkIndent=h,e.tight=!0,e.tShift[c]=u-e.bMarks[c],e.sCount[c]=r,u>=i&&e.isEmpty(c+1)?e.line=Math.min(e.line+2,n):e.md.block.tokenize(e,c,n),(!e.tight||_)&&(l=!1),_=e.line-c>1&&e.isEmpty(e.line-1),e.blkIndent=e.listIndent,e.listIndent=S,e.tShift[c]=b,e.sCount[c]=x,e.tight=y,s=e.push(`list_item_close`,`li`,-1),s.markup=String.fromCharCode(m),c=e.line,g[1]=c,c>=n||e.sCount[c]=4)break;let C=!1;for(let t=0,r=v.length;t=4||e.src.charCodeAt(i)!==91)return!1;function s(t){let n=e.lineMax;if(t>=n||e.isEmpty(t))return null;let r=!1;if(e.sCount[t]-e.blkIndent>3&&(r=!0),e.sCount[t]<0&&(r=!0),!r){let r=e.md.block.ruler.getRules(`reference`),i=e.parentType;e.parentType=`reference`;let a=!1;for(let i=0,o=r.length;i\`\\x00-\\x20]+|'[^']*'|"[^"]*"))?)*\\s*\\/?>`,di=`<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>`,fi=RegExp(`^(?:${ui}|${di}||<[?][\\s\\S]*?[?]>|]*>|)`),pi=RegExp(`^(?:${ui}|${di})`),Q=[[/^<(script|pre|style|textarea)(?=(\s|>|$))/i,/<\/(script|pre|style|textarea)>/i,!0],[/^/,!0],[/^<\?/,/\?>/,!0],[/^/,!0],[/^/,!0],[RegExp(`^|$))`,`i`),/^$/,!0],[RegExp(`${pi.source}\\s*$`),/^$/,!1]];function mi(e,t,n,r){let i=e.bMarks[t]+e.tShift[t],a=e.eMarks[t];if(e.sCount[t]-e.blkIndent>=4||!e.md.options.html||e.src.charCodeAt(i)!==60)return!1;let o=e.src.slice(i,a),s=0;for(;s=4)return!1;let o=e.src.charCodeAt(i);if(o!==35||i>=a)return!1;let s=1;for(o=e.src.charCodeAt(++i);o===35&&i6||ii&&q(e.src.charCodeAt(c-1))&&(a=c),e.line=t+1;let l=e.push(`heading_open`,`h${s}`,1);l.markup=`########`.slice(0,s),l.map=[t,e.line];let u=e.push(`inline`,``,0);u.content=lr(e.src.slice(i,a)),u.map=[t,e.line],u.children=[];let d=e.push(`heading_close`,`h${s}`,-1);return d.markup=`########`.slice(0,s),!0}function gi(e,t,n){let r=e.md.block.ruler.getRules(`paragraph`);if(e.sCount[t]-e.blkIndent>=4)return!1;let i=e.parentType;e.parentType=`paragraph`;let a=0,o,s=t+1;for(;s3)continue;if(e.sCount[s]>=e.blkIndent){let t=e.bMarks[s]+e.tShift[s],n=e.eMarks[s];if(t=n))){a=o===61?1:2;break}}if(e.sCount[s]<0)continue;let t=!1;for(let i=0,a=r.length;i3||e.sCount[a]<0)continue;let t=!1;for(let i=0,o=r.length;i=n||e.sCount[o]=a){e.line=n;break}let t=e.line,c=!1;for(let a=0;a=e.line)throw Error(`block rule didn't increment state.line`);break}if(!c)throw Error(`none of the block rules matched`);e.tight=!s,e.isEmpty(e.line-1)&&(s=!0),o=e.line,o0&&(this.level++,this._prev_delimiters.push(this.delimiters),this.delimiters=[],i={delimiters:this.delimiters}),this.pendingLevel=this.level,this.tokens.push(r),this.tokens_meta.push(i),r}scanDelims(e,t){let n=this.posMax,r=this.src.charCodeAt(e),i;if(e===0)i=32;else if(e===1)i=this.src.charCodeAt(0),(i&63488)==55296&&(i=65533);else if(i=this.src.charCodeAt(e-1),(i&64512)==56320){let t=this.src.charCodeAt(e-2);i=(t&64512)==55296?65536+(t-55296<<10)+(i-56320):65533}else(i&64512)==55296&&(i=65533);let a=e;for(;a0)return!1;let n=e.pos,r=e.posMax;if(n+3>r||e.src.charCodeAt(n)!==58||e.src.charCodeAt(n+1)!==47||e.src.charCodeAt(n+2)!==47)return!1;let i=e.pending.match(Ci);if(!i)return!1;let a=i[1],o=e.md.linkify.matchAtStart(e.src.slice(n-a.length));if(!o)return!1;let s=o.url;if(s.length<=a.length)return!1;let c=s.length;for(;c>0&&s.charCodeAt(c-1)===42;)c--;c!==s.length&&(s=s.slice(0,c));let l=e.md.normalizeLink(s);if(!e.md.validateLink(l))return!1;if(!t){e.pending=e.pending.slice(0,-a.length);let t=e.push(`link_open`,`a`,1);t.attrs=[[`href`,l]],t.markup=`linkify`,t.info=`auto`;let n=e.push(`text`,``,0);n.content=e.md.normalizeLinkText(s);let r=e.push(`link_close`,`a`,-1);r.markup=`linkify`,r.info=`auto`}return e.pos+=s.length-a.length,!0}function Ti(e,t){let n=e.pos;if(e.src.charCodeAt(n)!==10)return!1;let r=e.pending.length-1,i=e.posMax;if(!t)if(r>=0&&e.pending.charCodeAt(r)===32)if(r>=1&&e.pending.charCodeAt(r-1)===32){let t=r-1;for(;t>=1&&e.pending.charCodeAt(t-1)===32;)t--;e.pending=e.pending.slice(0,t),e.push(`hardbreak`,`br`,0)}else e.pending=e.pending.slice(0,-1),e.push(`softbreak`,`br`,0);else e.push(`softbreak`,`br`,0);for(n++;n?@[]^_\`{|}~-`.split(``).forEach(function(e){Ei[e.charCodeAt(0)]=1});function Di(e,t){let n=e.pos,r=e.posMax;if(e.src.charCodeAt(n)!==92||(n++,n>=r))return!1;let i=e.src.charCodeAt(n);if(i===10){for(t||e.push(`hardbreak`,`br`,0),n++;n=55296&&i<=56319&&n+1=56320&&t<=57343&&(a+=e.src[n+1],n++)}let o=`\\`+a;if(!t){let t=e.push(`text_special`,``,0);t.content=i<256&&Ei[i]!==0?a:o,t.markup=o,t.info=`escape`}return e.pos=n+1,!0}function Oi(e,t){let n=e.pos;if(e.src.charCodeAt(n)!==96)return!1;let r=n;n++;let i=e.posMax;for(;n=0;r--){let n=t[r];if(n.marker!==95&&n.marker!==42||n.end===-1)continue;let i=t[n.end],a=r>0&&t[r-1].end===n.end+1&&t[r-1].marker===n.marker&&t[r-1].token===n.token-1&&t[n.end+1].token===i.token+1,o=String.fromCharCode(n.marker),s=e.tokens[n.token];s.type=a?`strong_open`:`em_open`,s.tag=a?`strong`:`em`,s.nesting=1,s.markup=a?o+o:o,s.content=``;let c=e.tokens[i.token];c.type=a?`strong_close`:`em_close`,c.tag=a?`strong`:`em`,c.nesting=-1,c.markup=a?o+o:o,c.content=``,a&&(e.tokens[t[r-1].token].content=``,e.tokens[t[n.end+1].token].content=``,r--)}}function Fi(e){let t=e.tokens_meta,n=e.tokens_meta.length;Pi(e,e.delimiters);for(let r=0;r=d)return!1;if(c=m,i=e.md.helpers.parseLinkDestination(e.src,m,e.posMax),i.ok){for(o=e.md.normalizeLink(i.str),e.md.validateLink(o)?m=i.pos:o=``,c=m;m=d||e.src.charCodeAt(m)!==41)&&(l=!0),m++}if(l){if(e.env.references===void 0)return!1;if(m=0?r=e.src.slice(c,m++):m=p+1):m=p+1,r||=e.src.slice(f,p),r=sr(r),a=e.env.references[r],!a)return e.pos=u,!1;o=a.href,s=a.title}if(!t){e.pos=f,e.posMax=p;let t=e.push(`link_open`,`a`,1),n=[[`href`,o]];if(t.attrs=n,s&&n.push([`title`,s]),r){let e=Object.create(null);e.label=r,t.meta=e}e.linkLevel++,e.md.inline.tokenize(e),e.linkLevel--,e.push(`link_close`,`a`,-1)}return e.pos=m,e.posMax=d,!0}function Ri(e,t){let n,r,i,a,o,s,c,l,u=``,d=e.pos,f=e.posMax;if(e.src.charCodeAt(e.pos)!==33||e.src.charCodeAt(e.pos+1)!==91)return!1;let p=e.pos+2,m=e.md.helpers.parseLinkLabel(e,e.pos+1,!1);if(m<0)return!1;if(a=m+1,a=f)return!1;for(l=a,s=e.md.helpers.parseLinkDestination(e.src,a,e.posMax),s.ok&&(u=e.md.normalizeLink(s.str),e.md.validateLink(u)?a=s.pos:u=``),l=a;a=f||e.src.charCodeAt(a)!==41)return e.pos=d,!1;a++}else{if(e.env.references===void 0)return!1;if(a=0?i=e.src.slice(l,a++):a=m+1):a=m+1,i||=e.src.slice(p,m),i=sr(i),o=e.env.references[i],!o)return e.pos=d,!1;u=o.href,c=o.title}if(!t){r=e.src.slice(p,m);let t=[];e.md.inline.parse(r,e.md,e.env,t);let n=e.push(`image`,`img`,0),a=[[`src`,u],[`alt`,``]];if(n.attrs=a,n.children=t,n.content=r,c&&a.push([`title`,c]),i){let e=Object.create(null);e.label=i,n.meta=e}}return e.pos=a,e.posMax=f,!0}var zi=/^([a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)$/,Bi=/^([a-zA-Z][a-zA-Z0-9+.-]{1,31}):([^<>\x00-\x20]*)$/;function Vi(e,t){let n=e.pos;if(e.src.charCodeAt(n)!==60)return!1;let r=e.pos,i=e.posMax;for(;;){if(++n>=i)return!1;let t=e.src.charCodeAt(n);if(t===60)return!1;if(t===62)break}let a=e.src.slice(r+1,n);if(Bi.test(a)){let n=e.md.normalizeLink(a);if(!e.md.validateLink(n))return!1;if(!t){let t=e.push(`link_open`,`a`,1);t.attrs=[[`href`,n]],t.markup=`autolink`,t.info=`auto`;let r=e.push(`text`,``,0);r.content=e.md.normalizeLinkText(a);let i=e.push(`link_close`,`a`,-1);i.markup=`autolink`,i.info=`auto`}return e.pos+=a.length+2,!0}if(zi.test(a)){let n=e.md.normalizeLink(`mailto:${a}`);if(!e.md.validateLink(n))return!1;if(!t){let t=e.push(`link_open`,`a`,1);t.attrs=[[`href`,n]],t.markup=`autolink`,t.info=`auto`;let r=e.push(`text`,``,0);r.content=e.md.normalizeLinkText(a);let i=e.push(`link_close`,`a`,-1);i.markup=`autolink`,i.info=`auto`}return e.pos+=a.length+2,!0}return!1}function Hi(e){return/^\s]/i.test(e)}function Ui(e){return/^<\/a\s*>/i.test(e)}function Wi(e){let t=e|32;return t>=97&&t<=122}function Gi(e,t){if(!e.md.options.html)return!1;let n=e.posMax,r=e.pos;if(e.src.charCodeAt(r)!==60||r+2>=n)return!1;let i=e.src.charCodeAt(r+1);if(i!==33&&i!==63&&i!==47&&!Wi(i))return!1;let a=e.src.slice(r).match(fi);if(!a)return!1;if(!t){let t=e.push(`html_inline`,``,0);t.content=a[0],Hi(t.content)&&e.linkLevel++,Ui(t.content)&&e.linkLevel--}return e.pos+=a[0].length,!0}var Ki=/^&#((?:x[a-f0-9]{1,6}|[0-9]{1,7}));/i,qi=/^&([a-z][a-z0-9]{1,31});/i;function Ji(e,t){let n=e.pos,r=e.posMax;if(e.src.charCodeAt(n)!==38||n+1>=r)return!1;if(e.src.charCodeAt(n+1)===35){let r=e.src.slice(n).match(Ki);if(r){if(!t){let t=r[1][0].toLowerCase()===`x`?parseInt(r[1].slice(1),16):parseInt(r[1],10),n=e.push(`text_special`,``,0);n.content=Kn(t)?W(t):W(65533),n.markup=r[0],n.info=`entity`}return e.pos+=r[0].length,!0}}else{let r=e.src.slice(n).match(qi);if(r){let n=cn(r[0]);if(n!==r[0]){if(!t){let t=e.push(`text_special`,``,0);t.content=n,t.markup=r[0],t.info=`entity`}return e.pos+=r[0].length,!0}}}return!1}function Yi(e){let t={},n=e.length;if(!n)return;let r=0,i=-2,a=[];for(let o=0;os;c-=a[c]+1){let t=e[c];if(t.marker===n.marker&&t.open&&t.end<0){let r=!1;if((t.close||n.open)&&(t.length+n.length)%3==0&&(t.length%3!=0||n.length%3!=0)&&(r=!0),!r){let r=c>0&&!e[c-1].open?a[c-1]+1:0;a[o]=o-c+r,a[c]=r,n.open=!1,t.end=o,t.close=!1,l=-1,i=-2;break}}}l!==-1&&(t[n.marker][(n.open?3:0)+(n.length||0)%3]=l)}}function Xi(e){let t=e.tokens_meta,n=e.tokens_meta.length;Yi(e.delimiters);for(let e=0;e0&&r++,i[t].type===`text`&&t+1=e.pos)throw Error(`inline rule didn't increment state.pos`);break}}else e.pos=e.posMax;o||e.pos++,a[t]=e.pos}tokenize(e){let t=this.ruler.getRules(``),n=t.length,r=e.posMax,i=e.md.options.maxNesting;for(;e.pos=e.pos)throw Error(`inline rule didn't increment state.pos`);break}}if(o){if(e.pos>=r)break;continue}e.pending+=e.src[e.pos++]}e.pending&&e.pushPending()}parse(e,t,n,r){let i=new this.State(e,t,n,r);this.tokenize(i);let a=this.ruler2.getRules(``),o=a.length;for(let e=0;e=0))try{t.hostname=Bn.toASCII(t.hostname)}catch{}return F(Dt(t))}normalizeLinkText(e){let t=zt(e,!0);if(t.hostname&&(!t.protocol||ia.indexOf(t.protocol)>=0))try{t.hostname=Bn.toUnicode(t.hostname)}catch{}return P(Dt(t),P.defaultChars+`%`)}constructor(...e){Y(this,`inline`,new ea),Y(this,`block`,new yi),Y(this,`core`,new Jr),Y(this,`renderer`,new yr),Y(this,`linkify`,new _n),Y(this,`utils`,Un),Y(this,`helpers`,Object.assign({},mr));let[t,n]=e;typeof t==`string`?(this.configure(t),n&&this.set(n)):(this.configure(`default`),this.set(t||{}))}set(e){return Object.assign(this.options,e),this}configure(e){let t;if(typeof e==`string`){let n=e;if(t=ta[n],!t)throw Error(`Wrong 'markdown-it' preset "${n}", check name`)}else t=e;if(!t)throw Error("Wrong `markdown-it` preset, can't be empty");t.options&&(this.options={...t.options});let n=t.components;if(n){[`core`,`block`,`inline`].forEach(e=>{let t=n[e]?.rules;t&&this[e].ruler.enableOnly(t)});let e=n.inline?.rules2;e&&this.inline.ruler2.enableOnly(e)}return this}enable(e,t=!1){let n=[];Array.isArray(e)||(e=[e]),[`core`,`block`,`inline`].forEach(t=>{n=n.concat(this[t].ruler.enable(e,!0))}),n=n.concat(this.inline.ruler2.enable(e,!0));let r=e.filter(e=>n.indexOf(e)<0);if(r.length&&!t)throw Error(`MarkdownIt. Failed to enable unknown rule(s): ${r}`);return this}disable(e,t=!1){let n=[];Array.isArray(e)||(e=[e]),[`core`,`block`,`inline`].forEach(t=>{n=n.concat(this[t].ruler.disable(e,!0))}),n=n.concat(this.inline.ruler2.disable(e,!0));let r=e.filter(e=>n.indexOf(e)<0);if(r.length&&!t)throw Error(`MarkdownIt. Failed to disable unknown rule(s): ${r}`);return this}use(e,...t){return e.apply(e,[this,...t]),this}parse(e,t){if(typeof e!=`string`)throw Error(`Input data should be a String`);let n=new this.core.State(e,this,t);return this.core.process(n),n.tokens}render(e,t={}){return this.renderer.render(this.parse(e,t),this.options,t)}parseInline(e,t){let n=new this.core.State(e,this,t);return n.inlineMode=!0,this.core.process(n),n.tokens}renderInline(e,t={}){return this.renderer.render(this.parseInline(e,t),this.options,t)}};Y($,`Token`,X),Y($,`Ruler`,vr),Y($,`Renderer`,yr),Y($,`ParserCore`,Jr),Y($,`StateCore`,br),Y($,`ParserBlock`,yi),Y($,`StateBlock`,Yr),Y($,`ParserInline`,ea),Y($,`StateInline`,bi);var aa=Wn($);function oa(e={}){let t=new aa(e);return t.linkify.set({fuzzyLink:!0}),t}var sa={class:`cb`},ca={class:`cb-bar`},la={class:`cb-lang`},ua=[`title`],da={class:`cb-pre`},fa=[`innerHTML`],pa={key:0,class:`cb-fade`},ma=pe({__name:`CodeBlock`,props:{code:{type:String,required:!0},lang:{type:String,default:``},collapseAfter:{type:Number,default:24}},setup(e){let t=e,i=C(()=>t.code.split(` +`).length),a=C(()=>i.value>t.collapseAfter),s=o(a.value),u=o(xt(t.code,t.lang)),d=null,p=0;l(()=>t.code,()=>{let e=Date.now()-p,n=()=>{p=Date.now(),u.value=xt(t.code,t.lang)};e>=80?n():(clearTimeout(d),d=setTimeout(n,80-e))}),n(()=>clearTimeout(d));let m=o(!1),v=null;async function y(){await xe(t.code)&&(m.value=!0,clearTimeout(v),v=setTimeout(()=>{m.value=!1},1200))}return(t,n)=>(r(),g(`div`,sa,[h(`div`,ca,[h(`span`,la,T(e.lang||`text`),1),h(`button`,{class:`cb-copy`,type:`button`,title:m.value?`Copied`:`Copy code`,onClick:y},[(r(),b(c(m.value?f(D):f(O)),{class:`w-3 h-3`})),x(` `+T(m.value?`Copied`:`Copy`),1)],8,ua)]),h(`div`,{class:_([`cb-scroll`,{"cb-clamped":s.value}])},[h(`pre`,da,[h(`code`,{class:`hljs`,innerHTML:u.value},null,8,fa)]),s.value?(r(),g(`div`,pa)):w(``,!0)],2),a.value?(r(),g(`button`,{key:0,class:`cb-expand`,type:`button`,onClick:n[0]||=e=>s.value=!s.value},[(r(),b(c(s.value?f(De):f(Ee)),{class:`w-3 h-3`})),x(` `+T(s.value?`Show all ${i.value} lines`:`Collapse`),1)])):w(``,!0)]))}},[[`__scopeId`,`data-v-d48d08ad`]]),ha={class:`rounded-lg border border-border/70 bg-surface/40`},ga=[`aria-expanded`],_a={key:0,class:`px-3 pb-2.5`},va={class:`border-t border-border/70 pt-2 text-xs leading-relaxed text-foreground-muted font-mono whitespace-pre-wrap break-words`},ya=pe({__name:`ThinkingBlock`,props:{part:{type:Object,required:!0}},setup(e){let t=e,n=C(()=>!!t.part.streaming),a=o(Date.now()),s=o(null),c=null,u=C(()=>s.value==null?t.part.startedAt==null?null:Math.max(0,Math.round((a.value-t.part.startedAt)/1e3)):s.value),p=C(()=>{if(n.value){let e=u.value;return e==null?`Thinking…`:`Thinking… ${e}s`}let e=u.value;return e==null?`Reasoning`:`Thought for ${e}s`}),m=o(!1),y=o(n.value);function b(){m.value=!0,y.value=!y.value}function x(){S(),c=setInterval(()=>{a.value=Date.now()},1e3)}function S(){c&&=(clearInterval(c),null)}return l(n,(e,n)=>{e?(m.value||(y.value=!0),x()):(t.part.startedAt!=null&&(s.value=Math.max(0,Math.round((Date.now()-t.part.startedAt)/1e3))),S(),n&&!m.value&&(y.value=!1))}),d(()=>{n.value&&x()}),i(S),(t,i)=>(r(),g(`div`,ha,[h(`button`,{type:`button`,class:`flex w-full items-center gap-2 rounded-lg px-3 py-2 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary`,"aria-expanded":y.value,onClick:b},[v(f(Te),{class:_([`w-3.5 h-3.5 shrink-0`,n.value?`text-primary`:`text-foreground-muted`])},null,8,[`class`]),h(`span`,{class:_([`text-xs font-medium`,n.value?`thinking-shimmer text-foreground`:`text-foreground-muted`])},T(p.value),3),i[0]||=h(`span`,{class:`flex-1`},null,-1),v(f(oe),{class:_([`w-3.5 h-3.5 shrink-0 text-foreground-muted transition-transform duration-150`,{"rotate-180":y.value}])},null,8,[`class`])],8,ga),y.value?(r(),g(`div`,_a,[h(`div`,va,T(e.part.text),1)])):w(``,!0)]))}},[[`__scopeId`,`data-v-e0c99020`]]),ba={key:0},xa=[`innerHTML`],Sa=pe({__name:`MessagePart`,props:{part:{type:Object,required:!0}},setup(e){let t=e,i=oa({html:!1,linkify:!0,breaks:!0,highlight(e,t){if(t&&St.getLanguage(t))try{return St.highlight(e,{language:t,ignoreIllegals:!0}).value}catch{}return``}});function a(e){e||=``;let t;try{t=i.parse(e,{})}catch{return[{type:`html`,html:i.render(e)}]}let n=[],r=[],a=()=>{r.length&&(n.push({type:`html`,html:i.renderer.render(r,i.options,{})}),r=[])};for(let e of t)e.type===`fence`?(a(),n.push({type:`code`,code:e.content.replace(/\n$/,``),lang:(e.info||``).trim().split(/\s+/)[0]})):r.push(e);return a(),n}let s=o(a(t.part.text)),c=null,u=0;return l(()=>t.part.text,()=>{let e=Date.now()-u,n=()=>{u=Date.now(),s.value=a(t.part.text)};e>=80?n():(clearTimeout(c),c=setTimeout(n,80-e))}),n(()=>clearTimeout(c)),(t,n)=>e.part.type===`text`?(r(),g(`div`,ba,[(r(!0),g(S,null,y(s.value,(e,t)=>(r(),g(S,{key:t},[e.type===`code`?(r(),b(ma,{key:0,code:e.code,lang:e.lang},null,8,[`code`,`lang`])):(r(),g(`div`,{key:1,class:`md-body`,innerHTML:e.html},null,8,xa))],64))),128))])):e.part.type===`thinking`?(r(),b(ya,{key:1,part:e.part},null,8,[`part`])):w(``,!0)}},[[`__scopeId`,`data-v-96385b47`]]),Ca={key:0,class:`flex max-w-[85%] flex-col items-end`},wa={class:`mt-1.5 flex items-center gap-2`},Ta={class:`rounded-2xl rounded-br-md bg-primary px-3.5 py-2.5 text-sm leading-relaxed text-primary-foreground`},Ea={class:`mt-1 flex items-center gap-1`},Da={key:1,class:`w-full text-sm leading-relaxed text-foreground`},Oa={class:`mt-1.5 flex items-center gap-1`},ka=[`title`],Aa=`inline-flex items-center rounded-md px-1.5 py-1 text-[11px] text-foreground-muted opacity-0 transition-[opacity,color,background-color] hover:bg-surface-hover hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-background group-hover:opacity-100 max-md:opacity-100`,ja=Object.assign({name:`AIMessage`},{__name:`Message`,props:{role:{type:String,required:!0,validator:e=>e===`user`||e===`assistant`},parts:{type:Array,default:()=>[]},canRegenerate:{type:Boolean,default:!1},editable:{type:Boolean,default:!1},deletable:{type:Boolean,default:!1}},emits:[`regenerate`,`edit`,`delete`],setup(e,{emit:t}){let n=e,i=t,s=C(()=>n.parts.filter(e=>e.type===`text`&&e.text).map(e=>e.text).join(` -`).trim()),s=d(!1),l=null;async function u(){await Se(a.value)&&(s.value=!0,clearTimeout(l),l=setTimeout(()=>{s.value=!1},1200))}let m=d(!1),_=d(null),O=d(!1);function ee(){m.value=!0,E(()=>{let e=_.value;if(!e)return;e.textContent=a.value,O.value=!a.value.trim(),e.focus();let t=document.createRange();t.selectNodeContents(e),t.collapse(!1);let n=window.getSelection();n.removeAllRanges(),n.addRange(t)})}function A(){O.value=!(_.value?.innerText||``).trim()}function re(){m.value=!1}function ae(){let e=(_.value?.innerText||``).trim();e&&(m.value=!1,i(`edit`,e))}function j(e){e.key===`Enter`&&!e.shiftKey?(e.preventDefault(),ae()):e.key===`Escape`&&(e.preventDefault(),re())}return(t,n)=>(r(),g(`div`,{class:y([`group flex`,{"justify-end":e.role===`user`}])},[e.role===`user`?(r(),g(`div`,Ta,[m.value?(r(),g(C,{key:0},[h(`div`,{ref_key:`editBox`,ref:_,contenteditable:`plaintext-only`,role:`textbox`,"aria-multiline":`true`,"aria-label":`Edit message`,class:`max-w-full whitespace-pre-wrap break-words rounded-2xl rounded-br-md border border-border bg-surface px-3.5 py-2.5 text-sm leading-relaxed text-foreground outline-none transition-colors focus:border-white focus:ring-1 focus:ring-white`,onInput:A,onKeydown:j},null,544),h(`div`,Ea,[v(M,{size:`xs`,variant:`ghost`,onClick:re},{default:c(()=>[...n[3]||=[S(` Cancel `,-1)]]),_:1}),v(M,{size:`xs`,variant:`primary`,disabled:O.value,onClick:ae},{default:c(()=>[...n[4]||=[S(` Send `,-1)]]),_:1},8,[`disabled`])])],64)):(r(),g(C,{key:1},[h(`div`,Da,[(r(!0),g(C,null,b(e.parts,(e,t)=>(r(),x(wa,{key:`${e.type}-${t}`,part:e},null,8,[`part`]))),128))]),h(`div`,Oa,[e.editable?(r(),g(`button`,{key:0,type:`button`,class:y(Ma),"aria-label":`Edit and resend`,title:`Edit and resend`,onClick:ee},[v(f(te),{class:`h-3 w-3`})])):T(``,!0),e.deletable?(r(),g(`button`,{key:1,type:`button`,class:y(Ma),"aria-label":`Delete from here`,title:`Delete from here`,onClick:n[0]||=e=>i(`delete`)},[v(f(ie),{class:`h-3 w-3`})])):T(``,!0)])],64))])):(r(),g(`div`,ka,[(r(!0),g(C,null,b(e.parts,(e,t)=>(r(),x(wa,{key:`${e.type}-${t}`,part:e,class:y(t>0?`mt-3`:``)},null,8,[`part`,`class`]))),128)),h(`div`,Aa,[a.value?(r(),g(`button`,{key:0,type:`button`,class:y([Ma,`gap-1`]),title:s.value?`Copied`:`Copy message`,onClick:u},[(r(),x(o(s.value?f(D):f(k)),{class:`h-3 w-3`})),S(` `+p(s.value?`Copied`:`Copy`),1)],10,ja)):T(``,!0),e.canRegenerate?(r(),g(`button`,{key:1,type:`button`,class:y([Ma,`gap-1`]),title:`Regenerate this answer`,onClick:n[1]||=e=>i(`regenerate`)},[v(f(ne),{class:`h-3 w-3`}),n[5]||=S(` Retry `,-1)],2)):T(``,!0),e.deletable?(r(),g(`button`,{key:2,type:`button`,class:y(Ma),"aria-label":`Delete from here`,title:`Delete from here`,onClick:n[2]||=e=>i(`delete`)},[v(f(ie),{class:`h-3 w-3`})])):T(``,!0)])]))],2))}}),Pa=[`data-approval`],Fa=[`aria-expanded`],Ia={class:`truncate font-mono text-foreground`},La={key:0,class:`shrink-0 rounded bg-surface-hover px-1.5 py-0.5 text-[10px] uppercase tracking-label text-foreground-muted`},Ra={key:0,class:`border-t border-border px-3 py-3`},za={key:1,class:`flex gap-2 border-t border-border px-3 py-2`},Ba={__name:`ToolCallCard`,props:{tool:{type:Object,required:!0}},emits:[`approve`,`reject`],setup(e){let t=e,n=w(()=>t.tool.status),i={pending_approval:{label:`needs approval`,classes:`bg-warning-tint text-warning-fg`},running:{label:`running…`,classes:`bg-info-tint text-info-fg`},succeeded:{label:`done`,classes:`bg-success-tint text-success-fg`},failed:{label:`failed`,classes:`bg-danger-tint text-danger-fg`},rejected:{label:`rejected`,classes:`bg-surface-hover text-foreground-muted`}},a=w(()=>i[n.value]??{label:n.value??`unknown`,classes:`bg-surface-hover text-foreground-muted`});function o(e){if(e==null)return``;if(typeof e==`string`)try{return JSON.stringify(JSON.parse(e),null,2)}catch{return e}return JSON.stringify(e,null,2)}let l=w(()=>o(t.tool.args)),m=w(()=>o(t.tool.result)),_=e=>e===`running`||e===`pending_approval`||e===`failed`,b=d(!1),x=d(_(n.value));function D(){b.value=!0,x.value=!x.value}s(n,e=>{b.value||(x.value=_(e))});let k=d(null);function ee(){E(()=>{let e=k.value?.$el;e&&(e.scrollIntoView({behavior:`smooth`,block:`center`}),e.focus?.())})}return u(()=>{n.value===`pending_approval`&&ee()}),s(n,e=>{e===`pending_approval`&&ee()}),(t,i)=>(r(),g(`div`,{class:`overflow-hidden rounded-lg border border-border bg-surface text-sm`,"data-approval":e.tool.status===`pending_approval`?`pending`:null},[h(`button`,{type:`button`,class:`flex w-full items-center gap-2 rounded-lg px-3 py-2 text-left transition-colors hover:bg-surface-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary`,"aria-expanded":x.value,onClick:D},[v(f(Ne),{class:`h-3.5 w-3.5 shrink-0 text-foreground-muted`,"aria-hidden":`true`}),h(`span`,Ia,p(e.tool.name),1),e.tool.group?(r(),g(`span`,La,p(e.tool.group),1)):T(``,!0),i[2]||=h(`span`,{class:`flex-1`},null,-1),h(`span`,{class:y([`shrink-0 rounded-full px-2 py-0.5 text-xs`,[a.value.classes,n.value===`running`?`animate-pulse motion-reduce:animate-none`:``]])},p(a.value.label),3),v(f(O),{class:y([`h-3.5 w-3.5 shrink-0 text-foreground-muted transition-transform duration-150`,{"rotate-180":x.value}])},null,8,[`class`])],8,Fa),x.value?(r(),g(`div`,Ra,[i[4]||=h(`p`,{class:`mb-1 text-[10px] uppercase tracking-label text-foreground-muted`},` Arguments `,-1),v(ga,{code:l.value||`(none)`,lang:`json`},null,8,[`code`]),e.tool.result==null?T(``,!0):(r(),g(C,{key:0},[i[3]||=h(`p`,{class:`mb-1 mt-3 text-[10px] uppercase tracking-label text-foreground-muted`},` Result `,-1),v(ga,{code:m.value,lang:`json`},null,8,[`code`])],64))])):T(``,!0),e.tool.status===`pending_approval`?(r(),g(`div`,za,[v(M,{ref_key:`approveBtn`,ref:k,size:`xs`,variant:`primary`,onClick:i[0]||=n=>t.$emit(`approve`,e.tool.id)},{default:c(()=>[...i[5]||=[S(` Approve `,-1)]]),_:1},512),v(M,{size:`xs`,variant:`ghost`,onClick:i[1]||=n=>t.$emit(`reject`,e.tool.id)},{default:c(()=>[...i[6]||=[S(` Reject `,-1)]]),_:1})])):T(``,!0)],8,Pa))}},Va={class:`flex items-start gap-2.5 rounded-lg border border-danger-ring bg-danger-tint px-3.5 py-3 text-sm`,role:`alert`},Ha={class:`min-w-0 flex-1`},Ua={class:`mt-0.5 break-words text-foreground-muted`},Wa={class:`mt-2.5 flex items-center gap-2`},Ga={__name:`ErrorCard`,props:{message:{type:String,default:``}},emits:[`retry`,`dismiss`],setup(e){return(t,n)=>(r(),g(`div`,Va,[v(f(ue),{class:`mt-0.5 h-4 w-4 shrink-0 text-danger-fg`,"aria-hidden":`true`}),h(`div`,Ha,[n[4]||=h(`p`,{class:`font-medium text-danger-fg`},` Something went wrong `,-1),h(`p`,Ua,p(e.message),1),h(`div`,Wa,[v(M,{size:`xs`,variant:`secondary`,onClick:n[0]||=e=>t.$emit(`retry`)},{default:c(()=>[v(f(ne),{class:`h-3.5 w-3.5`}),n[2]||=S(` Retry `,-1)]),_:1}),v(M,{size:`xs`,variant:`ghost`,onClick:n[1]||=e=>t.$emit(`dismiss`)},{default:c(()=>[...n[3]||=[S(` Dismiss `,-1)]]),_:1})])])]))}},Ka={},qa={class:`flex items-center gap-1.5 py-1`,role:`status`,"aria-label":`Assistant is responding`};function Ja(e,t){return r(),g(`div`,qa,[...t[0]||=[h(`span`,{class:`dot`},null,-1),h(`span`,{class:`dot`,style:{"animation-delay":`0.18s`}},null,-1),h(`span`,{class:`dot`,style:{"animation-delay":`0.36s`}},null,-1),h(`span`,{class:`sr-only`},`Assistant is responding…`,-1)]])}var Ya=me(Ka,[[`render`,Ja],[`__scopeId`,`data-v-3a0eeb7e`]]),Xa={__name:`ScrollToBottom`,props:{visible:{type:Boolean,default:!1}},emits:[`click`],setup(e){return(t,n)=>(r(),x(fe,{name:`fade`},{default:c(()=>[e.visible?(r(),g(`button`,{key:0,type:`button`,class:`absolute bottom-3 left-1/2 -translate-x-1/2 z-10 flex items-center gap-1.5 rounded-full border border-border bg-surface px-3 py-1.5 text-xs text-foreground-muted shadow-lg shadow-black/30 transition-colors hover:text-white hover:bg-surface-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-background`,"aria-label":`Scroll to latest`,onClick:n[0]||=e=>t.$emit(`click`)},[v(f(Ce),{class:`h-3.5 w-3.5`}),n[1]||=S(` Latest `,-1)])):T(``,!0)]),_:1}))}},Za={class:`relative min-h-0 flex-1`},Qa={class:`mx-auto w-full max-w-3xl py-6`},$a={__name:`MessageList`,props:{items:{type:Array,required:!0},streaming:{type:Boolean,default:!1}},emits:[`approve`,`reject`,`regenerate`,`edit`,`delete`,`retry`,`dismiss`],setup(e){let t=e,n=w(()=>{for(let e=t.items.length-1;e>=0;e--){let n=t.items[e];if(n.kind===`message`&&n.role===`assistant`)return e}return-1}),i=w(()=>{if(!t.streaming)return!1;let e=t.items[t.items.length-1];return e?e.kind===`tool`?!0:e.kind===`message`?e.role===`user`||!(e.parts||[]).some(e=>e.type===`text`&&e.text||e.type===`thinking`&&e.text):!1:!1}),a=d(null),o=d(!0);function c(e){if(e===0)return``;let n=t.items[e],r=t.items[e-1];return n.kind===`message`&&n.role===`user`?`mt-8`:n.kind===`tool`?`mt-2`:r.kind===`tool`?`mt-3`:`mt-4`}function l(){let e=t.items[t.items.length-1];if(!e||e.kind!==`message`||!Array.isArray(e.parts))return 0;let n=0;for(let t of e.parts)n+=t&&typeof t.text==`string`?t.text.length:0;return n}function f(){let e=a.value;return!e||e.scrollTop+e.clientHeight>=e.scrollHeight-100}function p(){o.value=f()}async function m(){await E();let e=a.value;e&&(e.scrollTop=e.scrollHeight)}function _(){o.value=!0,m()}return s(()=>[t.items.length,t.streaming,l()],()=>{o.value&&m()}),u(m),(t,s)=>(r(),g(`div`,Za,[h(`div`,{ref_key:`scroller`,ref:a,class:`scrollable h-full overflow-y-auto px-4`,role:`log`,"aria-live":`polite`,"aria-atomic":`false`,"aria-label":`Chat messages`,onScroll:p},[h(`div`,Qa,[(r(!0),g(C,null,b(e.items,(i,a)=>(r(),g(C,{key:i.id??a},[i.kind===`message`?(r(),x(Na,{key:0,role:i.role,parts:i.parts,"can-regenerate":i.role===`assistant`&&!e.streaming&&a===n.value,editable:i.role===`user`&&!e.streaming,deletable:!e.streaming&&!!i.id,class:y(c(a)),onRegenerate:s[0]||=e=>t.$emit(`regenerate`),onEdit:e=>t.$emit(`edit`,{id:i.id,content:e}),onDelete:e=>t.$emit(`delete`,i.id)},null,8,[`role`,`parts`,`can-regenerate`,`editable`,`deletable`,`class`,`onEdit`,`onDelete`])):i.kind===`tool`?(r(),x(Ba,{key:1,tool:i,class:y(c(a)),onApprove:s[1]||=e=>t.$emit(`approve`,e),onReject:s[2]||=e=>t.$emit(`reject`,e)},null,8,[`tool`,`class`])):i.kind===`error`?(r(),x(Ga,{key:2,message:i.message,class:y(c(a)),onRetry:s[3]||=e=>t.$emit(`retry`),onDismiss:e=>t.$emit(`dismiss`,i.id)},null,8,[`message`,`class`,`onDismiss`])):T(``,!0)],64))),128)),i.value?(r(),x(Ya,{key:0,class:y(e.items.length?`mt-4`:``)},null,8,[`class`])):T(``,!0)])],544),v(Xa,{visible:!o.value,onClick:_},null,8,[`visible`])]))}},eo={class:`py-1`},to=Object.assign({name:`CommonPopover`},{__name:`Popover`,props:{title:{type:String,default:``}},setup(e,{expose:n}){let a=d(!1),o=d(null),s=d(null),l=d({}),f=d(!1),p=null,y=()=>{p&&(f.value=p.matches)};function b(){let e=o.value?.firstElementChild||o.value;if(!e)return;let t=e.getBoundingClientRect(),n=Math.max(8,Math.min(t.left,window.innerWidth-8-200));l.value={left:`${n}px`,bottom:`${window.innerHeight-t.top+6}px`},E(()=>{let e=s.value;if(!e)return;let n=e.offsetWidth,r=Math.max(8,Math.min(t.left,window.innerWidth-8-n));l.value={...l.value,left:`${r}px`}})}function S(){a.value=!0,f.value||E(b)}function w(){a.value=!1}function D(){a.value?w():S()}function O(e){!a.value||f.value||s.value?.contains(e.target)||o.value?.contains(e.target)||w()}function k(){a.value&&!f.value&&b()}return u(()=>{p=window.matchMedia(`(max-width: 639px)`),y(),p.addEventListener(`change`,y),document.addEventListener(`pointerdown`,O,!0),window.addEventListener(`resize`,k)}),i(()=>{p?.removeEventListener(`change`,y),document.removeEventListener(`pointerdown`,O,!0),window.removeEventListener(`resize`,k)}),n({open:S,close:w}),(n,i)=>(r(),g(C,null,[h(`span`,{ref_key:`triggerEl`,ref:o,class:`inline-flex`},[t(n.$slots,`trigger`,{open:a.value,toggle:D})],512),(r(),x(m,{to:`body`},[v(fe,{name:`fade`},{default:c(()=>[a.value&&!f.value?(r(),g(`div`,{key:0,ref_key:`panelEl`,ref:s,class:`fixed z-50 min-w-[200px] max-w-[min(320px,calc(100vw-1rem))] bg-background border border-border rounded-lg shadow-xl overflow-hidden`,style:_(l.value),role:`menu`,onKeydown:se(w,[`esc`])},[t(n.$slots,`default`,{close:w})],36)):T(``,!0)]),_:3})])),f.value?(r(),x(_e,{key:0,modelValue:a.value,"onUpdate:modelValue":i[0]||=e=>a.value=e,title:e.title},{default:c(()=>[h(`div`,eo,[t(n.$slots,`default`,{close:w})])]),_:3},8,[`modelValue`,`title`])):T(``,!0)],64))}}),no=[`title`,`onClick`],ro={key:0},io={class:`py-1`},ao=[`aria-checked`,`onClick`],oo={class:`flex-1`},so={class:`block`},co={class:`block text-[11px] text-foreground-muted`},lo={key:0,class:`px-3 pt-1.5 pb-1.5 mt-1 border-t border-border text-[11px] text-foreground-muted leading-snug`},uo={__name:`ReasoningMenu`,setup(e){let t=A(),n=[{v:`off`,label:`Off`,hint:`Answer directly`,icon:Te},{v:`standard`,label:`Think`,hint:`Reason before answering`,icon:ae},{v:`deep`,label:`Deep`,hint:`Extended reasoning`,icon:re}],i=w(()=>t.thinking&&t.thinking!==`off`),a=w(()=>n.find(e=>e.v===t.thinking)?.label||`Off`),s=[/\bo[1-9]/i,/gpt-5/i,/-thinking/i,/reason/i,/deepseek-r/i,/claude.*(sonnet|opus)/i,/qwen.*(think|3)/i,/grok.*(3|4)/i],l=w(()=>{let e=t.selectedModel||``;return s.some(t=>t.test(e))});function u(e,n){t.setThinking(e),n()}return(e,s)=>(r(),x(to,{title:`Reasoning`},{trigger:c(({toggle:e})=>[h(`button`,{type:`button`,class:y([`touch-expand-sm inline-flex h-8 items-center justify-center gap-1.5 rounded-lg px-2.5 text-xs transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-surface`,i.value?`text-primary bg-primary/15 hover:bg-primary/20`:`text-foreground-muted hover:text-foreground hover:bg-surface-hover`]),title:`Reasoning: ${a.value}`,"aria-label":`Reasoning level`,onClick:e},[v(f(Ee),{class:`w-4 h-4 shrink-0`}),i.value?(r(),g(`span`,ro,p(a.value),1)):T(``,!0)],10,no)]),default:c(({close:e})=>[h(`div`,io,[s[0]||=h(`p`,{class:`px-3 pt-1.5 pb-1 text-[10px] uppercase tracking-label text-foreground-muted`},` Reasoning `,-1),(r(),g(C,null,b(n,n=>h(`button`,{key:n.v,type:`button`,class:y([`flex w-full items-center gap-2.5 px-3 py-2 text-left text-sm transition-colors focus-visible:outline-none focus-visible:bg-surface-hover`,f(t).thinking===n.v?`text-white bg-primary/15`:`text-foreground hover:bg-surface-hover`]),role:`menuitemradio`,"aria-checked":f(t).thinking===n.v,onClick:t=>u(n.v,e)},[(r(),x(o(n.icon),{class:y([`w-3.5 h-3.5 shrink-0`,f(t).thinking===n.v?`text-primary`:`text-foreground-muted`])},null,8,[`class`])),h(`span`,oo,[h(`span`,so,p(n.label),1),h(`span`,co,p(n.hint),1)]),f(t).thinking===n.v?(r(),x(f(D),{key:0,class:`w-3.5 h-3.5 shrink-0 text-primary`})):T(``,!0)],10,ao)),64)),i.value&&!l.value?(r(),g(`p`,lo,p(f(t).selectedModel||`This model`)+` may ignore reasoning requests. `,1)):T(``,!0)])]),_:1}))}},fo=[`title`,`onClick`],po={class:`truncate font-mono`},mo={class:`max-h-[60dvh] overflow-y-auto scrollable py-1`},ho=[`onClick`],go={class:`flex-1 truncate`},_o={key:1,class:`sticky top-0 z-10 bg-background px-3 pb-2 pt-0.5`},vo={class:`relative`},yo={key:2,class:`px-3 py-2 text-sm text-foreground-muted`},bo={key:3,class:`px-3 py-2 text-xs text-foreground-muted leading-snug`},xo={key:4,class:`px-3 py-2 text-xs text-foreground-muted leading-snug`},So=[`onClick`],Co={class:`flex-1 truncate`},wo={__name:`ModelMenu`,setup(e){let t=A(),n=d(``),i=w(()=>t.models.length>6);function o(e,t){let n=0,r=0,i=-1;for(let a of t){let t=e.indexOf(a,r);if(t===-1)return-1;n+=t===i+1?3:1,n-=t-r,i=t,r=t+1}return n}let l=w(()=>{let e=n.value.trim().toLowerCase();return e?t.models.map(t=>({m:t,s:o(t.id.toLowerCase(),e)})).filter(e=>e.s>=0).sort((e,t)=>t.s-e.s).map(e=>e.m):t.models});s(()=>t.selectedProviderId,()=>{n.value=``});function u(e,r){t.selectModel(e),n.value=``,r()}return(e,o)=>(r(),x(to,{title:`Model`},{trigger:c(({toggle:e})=>[h(`button`,{type:`button`,class:`touch-expand-sm inline-flex items-center gap-1.5 h-8 max-w-[180px] px-2.5 rounded-lg text-xs text-foreground-muted hover:text-foreground hover:bg-surface-hover transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-surface`,title:f(t).selectedModel||`Select model`,"aria-label":`Select model`,onClick:e},[v(f(ke),{class:`w-3.5 h-3.5 shrink-0`}),h(`span`,po,p(f(t).selectedModel||`No model`),1),v(f(O),{class:`w-3 h-3 shrink-0 opacity-70`})],8,fo)]),default:c(({close:e})=>[h(`div`,mo,[f(t).providers.length>1?(r(),g(C,{key:0},[o[1]||=h(`p`,{class:`px-3 pt-1.5 pb-1 text-[10px] uppercase tracking-label text-foreground-muted`},` Provider `,-1),(r(!0),g(C,null,b(f(t).providers,e=>(r(),g(`button`,{key:e.id,type:`button`,class:y([`flex w-full items-center gap-2.5 px-3 py-1.5 text-left text-sm transition-colors focus-visible:outline-none focus-visible:bg-surface-hover`,f(t).selectedProviderId===e.id?`text-white bg-primary/15`:`text-foreground hover:bg-surface-hover`]),onClick:n=>f(t).selectProvider(e.id)},[h(`span`,go,p(e.label||e.provider),1),f(t).selectedProviderId===e.id?(r(),x(f(D),{key:0,class:`w-3.5 h-3.5 shrink-0 text-primary`})):T(``,!0)],10,ho))),128)),o[2]||=h(`div`,{class:`my-1 border-t border-border`},null,-1)],64)):T(``,!0),o[3]||=h(`p`,{class:`px-3 pt-1 pb-1 text-[10px] uppercase tracking-label text-foreground-muted`},` Model `,-1),i.value?(r(),g(`div`,_o,[h(`div`,vo,[v(f(he),{class:`pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-foreground-muted`}),a(h(`input`,{"onUpdate:modelValue":o[0]||=e=>n.value=e,type:`text`,placeholder:`Search models…`,class:`w-full rounded-md border border-border bg-surface py-1.5 pl-8 pr-2.5 text-base sm:text-sm text-foreground placeholder-foreground-muted/50 transition-colors duration-200 focus:border-white focus:outline-none focus:ring-1 focus:ring-white`},null,512),[[oe,n.value]])])])):T(``,!0),f(t).modelsLoading?(r(),g(`p`,yo,` Loading models… `)):f(t).models.length?l.value.length?(r(!0),g(C,{key:5},b(l.value,n=>(r(),g(`button`,{key:n.id,type:`button`,class:y([`flex w-full items-center gap-2.5 px-3 py-1.5 text-left text-sm font-mono transition-colors focus-visible:outline-none focus-visible:bg-surface-hover`,f(t).selectedModel===n.id?`text-white bg-primary/15`:`text-foreground hover:bg-surface-hover`]),onClick:t=>u(n.id,e)},[h(`span`,Co,p(n.id),1),f(t).selectedModel===n.id?(r(),x(f(D),{key:0,class:`w-3.5 h-3.5 shrink-0 text-primary`})):T(``,!0)],10,So))),128)):(r(),g(`p`,xo,` No models match “`+p(n.value.trim())+`”. `,1)):(r(),g(`p`,bo,p(f(t).modelsError?`No models. Check the provider endpoint.`:`No models reported.`),1))])]),_:1}))}},To={class:`mx-auto w-full max-w-3xl`},Eo=[`disabled`,`placeholder`],Do={class:`flex items-center gap-1.5 px-2 pb-2`},Oo=[`disabled`],ko=Object.assign({name:`AIComposer`},{__name:`Composer`,props:{streaming:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1},docked:{type:Boolean,default:!0},modelReady:{type:Boolean,default:!0}},emits:[`send`,`stop`],setup(e,{expose:t,emit:n}){let i=e,s=n,l=d(``),u=d(null),p=w(()=>i.disabled?`Configure a provider to start`:`Message the assistant…`);function m(){let e=u.value;e&&(e.style.height=`auto`,e.style.height=`${e.scrollHeight}px`)}function _(){let e=l.value.trim();!e||i.streaming||i.disabled||!i.modelReady||(s(`send`,e),l.value=``,E(()=>{u.value&&(u.value.style.height=`auto`)}))}function b(e){e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),_())}function S(e){l.value=e,E(()=>{m(),u.value?.focus()})}return t({focus:()=>u.value?.focus(),setText:S}),(t,n)=>(r(),x(o(e.docked?`footer`:`div`),{class:y([`shrink-0 px-4`,e.docked?`pt-3 pb-composer`:`py-0`])},{default:c(()=>[h(`div`,To,[h(`div`,{class:y([`rounded-2xl border border-border bg-surface transition-colors focus-within:border-foreground-muted/50`,{"opacity-60":e.disabled}])},[a(h(`textarea`,{ref_key:`ta`,ref:u,"onUpdate:modelValue":n[0]||=e=>l.value=e,rows:`1`,disabled:e.disabled,placeholder:p.value,"aria-label":`Message the assistant`,class:`max-h-40 w-full resize-none overflow-y-auto bg-transparent px-3.5 pt-3 pb-1.5 text-sm text-foreground placeholder-foreground-muted/60 focus:outline-none disabled:cursor-not-allowed`,onInput:m,onKeydown:b},null,40,Eo),[[oe,l.value]]),h(`div`,Do,[e.disabled?T(``,!0):(r(),g(C,{key:0},[v(uo),v(wo)],64)),n[2]||=h(`span`,{class:`flex-1`},null,-1),e.streaming?(r(),g(`button`,{key:1,type:`button`,class:`touch-expand-iconbtn inline-flex h-8 w-8 items-center justify-center rounded-lg bg-surface-hover text-foreground transition-colors hover:bg-border focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-surface`,"aria-label":`Stop generating (Esc)`,title:`Stop generating (Esc)`,onClick:n[1]||=e=>t.$emit(`stop`)},[v(f(Me),{class:`h-3.5 w-3.5 fill-current`})])):(r(),g(`button`,{key:2,type:`button`,class:`touch-expand-iconbtn inline-flex h-8 w-8 items-center justify-center rounded-lg bg-primary text-primary-foreground shadow-sm transition-colors hover:bg-primary-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-surface disabled:opacity-40 disabled:shadow-none`,disabled:e.disabled||!e.modelReady||!l.value.trim(),"aria-label":`Send message`,title:`Send message`,onClick:_},[v(f(we),{class:`h-4 w-4`})],8,Oo))])],2)])]),_:1},8,[`class`]))}}),Ao={class:`flex h-full bg-background`,style:{overflow:`hidden`,padding:`0`}},jo={class:`hidden w-64 shrink-0 border-r border-border md:block`},Mo={class:`flex min-w-0 flex-1 flex-col`},No={key:0,class:`flex shrink-0 items-center justify-between gap-3 border-b border-warning-ring bg-warning-tint px-4 py-2.5 text-xs text-warning-fg`},Po={key:1,class:`scrollable flex flex-1 flex-col items-center justify-center overflow-y-auto px-4 py-6`},Fo={class:`w-full max-w-3xl`},Io={__name:`AI`,setup(e){let t=A(),n=de(),a=pe();function o(){a.push({name:`settings`,hash:`#ai`})}function s({id:e,content:n}){t.editAndResend(e,n)}async function p(e){await n.ask({title:`Delete from here?`,message:`This removes this message and everything after it in the conversation. This cannot be undone.`,danger:!0,confirmLabel:`Delete`})&&t.deleteMessageFrom(e)}let m=d(!1),_=d(null);function y(e){_.value?.setText(e)}let b=w(()=>t.conversations.find(e=>e.id===t.activeId)?.title||`Assistant`);async function x(){await t.loadSettings(),await Promise.all([t.loadProviders(),t.loadConversations()])}u(x),l(()=>{t.loadConversations(),t.loadSettings(),t.loadProviders()});function E(e){e.key===`Escape`&&t.streaming&&!document.querySelector(`[role="dialog"], [role="menu"]`)&&t.stop()}return u(()=>window.addEventListener(`keydown`,E)),i(()=>window.removeEventListener(`keydown`,E)),(e,n)=>(r(),g(`div`,Ao,[h(`aside`,jo,[v(qe)]),v(_e,{modelValue:m.value,"onUpdate:modelValue":n[1]||=e=>m.value=e,title:`Conversations`},{default:c(()=>[v(qe,{embedded:``,onSelect:n[0]||=e=>m.value=!1})]),_:1},8,[`modelValue`]),h(`div`,Mo,[v(Re,{title:b.value,"can-export":!!f(t).timeline.length,onToggleRail:n[2]||=e=>m.value=!0,onExport:f(t).exportActive},null,8,[`title`,`can-export`,`onExport`]),f(t).providersLoaded&&!f(t).providers.length?(r(),g(`div`,No,[n[4]||=h(`span`,null,`No AI provider configured. Add a provider API key to start chatting.`,-1),v(M,{size:`xs`,variant:`secondary`,onClick:o},{default:c(()=>[...n[3]||=[S(` Configure `,-1)]]),_:1})])):T(``,!0),f(t).timeline.length?(r(),g(C,{key:2},[v($a,{items:f(t).timeline,streaming:f(t).streaming,onApprove:f(t).approveTool,onReject:f(t).rejectTool,onRegenerate:f(t).regenerate,onEdit:s,onDelete:p,onRetry:f(t).retry,onDismiss:f(t).dismissError},null,8,[`items`,`streaming`,`onApprove`,`onReject`,`onRegenerate`,`onRetry`,`onDismiss`]),v(ko,{streaming:f(t).streaming,disabled:f(t).providersLoaded&&!f(t).providers.length,"model-ready":!!f(t).selectedModel,onSend:f(t).sendMessage,onStop:f(t).stop},null,8,[`streaming`,`disabled`,`model-ready`,`onSend`,`onStop`])],64)):(r(),g(`div`,Po,[h(`div`,Fo,[v($e,{onPick:y}),v(ko,{ref_key:`emptyComposer`,ref:_,class:`mt-6`,docked:!1,streaming:f(t).streaming,disabled:f(t).providersLoaded&&!f(t).providers.length,"model-ready":!!f(t).selectedModel,onSend:f(t).sendMessage,onStop:f(t).stop},null,8,[`streaming`,`disabled`,`model-ready`,`onSend`,`onStop`])])]))])]))}};export{Io as default}; \ No newline at end of file +`).trim()),l=o(!1),u=null;async function d(){await xe(s.value)&&(l.value=!0,clearTimeout(u),u=setTimeout(()=>{l.value=!1},1200))}let p=o(!1),m=o(null),k=o(!1);function A(){p.value=!0,E(()=>{let e=m.value;if(!e)return;e.textContent=s.value,k.value=!s.value.trim(),e.focus();let t=document.createRange();t.selectNodeContents(e),t.collapse(!1);let n=window.getSelection();n.removeAllRanges(),n.addRange(t)})}function ne(){k.value=!(m.value?.innerText||``).trim()}function ie(){p.value=!1}function ae(){let e=(m.value?.innerText||``).trim();e&&(p.value=!1,i(`edit`,e))}function oe(e){e.key===`Enter`&&!e.shiftKey?(e.preventDefault(),ae()):e.key===`Escape`&&(e.preventDefault(),ie())}return(t,n)=>(r(),g(`div`,{class:_([`group flex`,{"justify-end":e.role===`user`}])},[e.role===`user`?(r(),g(`div`,Ca,[p.value?(r(),g(S,{key:0},[h(`div`,{ref_key:`editBox`,ref:m,contenteditable:`plaintext-only`,role:`textbox`,"aria-multiline":`true`,"aria-label":`Edit message`,class:`max-w-full whitespace-pre-wrap break-words rounded-2xl rounded-br-md border border-border bg-surface px-3.5 py-2.5 text-sm leading-relaxed text-foreground outline-none transition-colors focus:border-white focus:ring-1 focus:ring-white`,onInput:ne,onKeydown:oe},null,544),h(`div`,wa,[v(j,{size:`xs`,variant:`ghost`,onClick:ie},{default:a(()=>[...n[3]||=[x(` Cancel `,-1)]]),_:1}),v(j,{size:`xs`,variant:`primary`,disabled:k.value,onClick:ae},{default:a(()=>[...n[4]||=[x(` Send `,-1)]]),_:1},8,[`disabled`])])],64)):(r(),g(S,{key:1},[h(`div`,Ta,[(r(!0),g(S,null,y(e.parts,(e,t)=>(r(),b(Sa,{key:`${e.type}-${t}`,part:e},null,8,[`part`]))),128))]),h(`div`,Ea,[e.editable?(r(),g(`button`,{key:0,type:`button`,class:_(Aa),"aria-label":`Edit and resend`,title:`Edit and resend`,onClick:A},[v(f(ee),{class:`h-3 w-3`})])):w(``,!0),e.deletable?(r(),g(`button`,{key:1,type:`button`,class:_(Aa),"aria-label":`Delete from here`,title:`Delete from here`,onClick:n[0]||=e=>i(`delete`)},[v(f(re),{class:`h-3 w-3`})])):w(``,!0)])],64))])):(r(),g(`div`,Da,[(r(!0),g(S,null,y(e.parts,(e,t)=>(r(),b(Sa,{key:`${e.type}-${t}`,part:e,class:_(t>0?`mt-3`:``)},null,8,[`part`,`class`]))),128)),h(`div`,Oa,[s.value?(r(),g(`button`,{key:0,type:`button`,class:_([Aa,`gap-1`]),title:l.value?`Copied`:`Copy message`,onClick:d},[(r(),b(c(l.value?f(D):f(O)),{class:`h-3 w-3`})),x(` `+T(l.value?`Copied`:`Copy`),1)],10,ka)):w(``,!0),e.canRegenerate?(r(),g(`button`,{key:1,type:`button`,class:_([Aa,`gap-1`]),title:`Regenerate this answer`,onClick:n[1]||=e=>i(`regenerate`)},[v(f(te),{class:`h-3 w-3`}),n[5]||=x(` Retry `,-1)],2)):w(``,!0),e.deletable?(r(),g(`button`,{key:2,type:`button`,class:_(Aa),"aria-label":`Delete from here`,title:`Delete from here`,onClick:n[2]||=e=>i(`delete`)},[v(f(re),{class:`h-3 w-3`})])):w(``,!0)])]))],2))}}),Ma=[`data-approval`],Na=[`aria-expanded`],Pa={class:`truncate font-mono text-foreground`},Fa={key:0,class:`shrink-0 rounded bg-surface-hover px-1.5 py-0.5 text-[10px] uppercase tracking-label text-foreground-muted`},Ia={key:0,class:`border-t border-border px-3 py-3`},La={key:1,class:`flex gap-2 border-t border-border px-3 py-2`},Ra={__name:`ToolCallCard`,props:{tool:{type:Object,required:!0}},emits:[`approve`,`reject`],setup(e){let t=e,n=C(()=>t.tool.status),i={pending_approval:{label:`needs approval`,classes:`bg-warning-tint text-warning-fg`},running:{label:`running…`,classes:`bg-info-tint text-info-fg`},succeeded:{label:`done`,classes:`bg-success-tint text-success-fg`},failed:{label:`failed`,classes:`bg-danger-tint text-danger-fg`},rejected:{label:`rejected`,classes:`bg-surface-hover text-foreground-muted`}},s=C(()=>i[n.value]??{label:n.value??`unknown`,classes:`bg-surface-hover text-foreground-muted`});function c(e){if(e==null)return``;if(typeof e==`string`)try{return JSON.stringify(JSON.parse(e),null,2)}catch{return e}return JSON.stringify(e,null,2)}let u=C(()=>c(t.tool.args)),p=C(()=>c(t.tool.result)),m=e=>e===`running`||e===`pending_approval`||e===`failed`,y=o(!1),b=o(m(n.value));function D(){y.value=!0,b.value=!b.value}l(n,e=>{y.value||(b.value=m(e))});let O=o(null);function k(){E(()=>{let e=O.value?.$el;e&&(e.scrollIntoView({behavior:`smooth`,block:`center`}),e.focus?.())})}return d(()=>{n.value===`pending_approval`&&k()}),l(n,e=>{e===`pending_approval`&&k()}),(t,i)=>(r(),g(`div`,{class:`overflow-hidden rounded-lg border border-border bg-surface text-sm`,"data-approval":e.tool.status===`pending_approval`?`pending`:null},[h(`button`,{type:`button`,class:`flex w-full items-center gap-2 rounded-lg px-3 py-2 text-left transition-colors hover:bg-surface-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary`,"aria-expanded":b.value,onClick:D},[v(f(Me),{class:`h-3.5 w-3.5 shrink-0 text-foreground-muted`,"aria-hidden":`true`}),h(`span`,Pa,T(e.tool.name),1),e.tool.group?(r(),g(`span`,Fa,T(e.tool.group),1)):w(``,!0),i[2]||=h(`span`,{class:`flex-1`},null,-1),h(`span`,{class:_([`shrink-0 rounded-full px-2 py-0.5 text-xs`,[s.value.classes,n.value===`running`?`animate-pulse motion-reduce:animate-none`:``]])},T(s.value.label),3),v(f(oe),{class:_([`h-3.5 w-3.5 shrink-0 text-foreground-muted transition-transform duration-150`,{"rotate-180":b.value}])},null,8,[`class`])],8,Na),b.value?(r(),g(`div`,Ia,[i[4]||=h(`p`,{class:`mb-1 text-[10px] uppercase tracking-label text-foreground-muted`},` Arguments `,-1),v(ma,{code:u.value||`(none)`,lang:`json`},null,8,[`code`]),e.tool.result==null?w(``,!0):(r(),g(S,{key:0},[i[3]||=h(`p`,{class:`mb-1 mt-3 text-[10px] uppercase tracking-label text-foreground-muted`},` Result `,-1),v(ma,{code:p.value,lang:`json`},null,8,[`code`])],64))])):w(``,!0),e.tool.status===`pending_approval`?(r(),g(`div`,La,[v(j,{ref_key:`approveBtn`,ref:O,size:`xs`,variant:`primary`,onClick:i[0]||=n=>t.$emit(`approve`,e.tool.id)},{default:a(()=>[...i[5]||=[x(` Approve `,-1)]]),_:1},512),v(j,{size:`xs`,variant:`ghost`,onClick:i[1]||=n=>t.$emit(`reject`,e.tool.id)},{default:a(()=>[...i[6]||=[x(` Reject `,-1)]]),_:1})])):w(``,!0)],8,Ma))}},za={class:`flex items-start gap-2.5 rounded-lg border border-danger-ring bg-danger-tint px-3.5 py-3 text-sm`,role:`alert`},Ba={class:`min-w-0 flex-1`},Va={class:`mt-0.5 break-words text-foreground-muted`},Ha={class:`mt-2.5 flex items-center gap-2`},Ua={__name:`ErrorCard`,props:{message:{type:String,default:``}},emits:[`retry`,`dismiss`],setup(e){return(t,n)=>(r(),g(`div`,za,[v(f(ue),{class:`mt-0.5 h-4 w-4 shrink-0 text-danger-fg`,"aria-hidden":`true`}),h(`div`,Ba,[n[4]||=h(`p`,{class:`font-medium text-danger-fg`},` Something went wrong `,-1),h(`p`,Va,T(e.message),1),h(`div`,Ha,[v(j,{size:`xs`,variant:`secondary`,onClick:n[0]||=e=>t.$emit(`retry`)},{default:a(()=>[v(f(te),{class:`h-3.5 w-3.5`}),n[2]||=x(` Retry `,-1)]),_:1}),v(j,{size:`xs`,variant:`ghost`,onClick:n[1]||=e=>t.$emit(`dismiss`)},{default:a(()=>[...n[3]||=[x(` Dismiss `,-1)]]),_:1})])])]))}},Wa={},Ga={class:`flex items-center gap-1.5 py-1`,role:`status`,"aria-label":`Assistant is responding`};function Ka(e,t){return r(),g(`div`,Ga,[...t[0]||=[h(`span`,{class:`dot`},null,-1),h(`span`,{class:`dot`,style:{"animation-delay":`0.18s`}},null,-1),h(`span`,{class:`dot`,style:{"animation-delay":`0.36s`}},null,-1),h(`span`,{class:`sr-only`},`Assistant is responding…`,-1)]])}var qa=pe(Wa,[[`render`,Ka],[`__scopeId`,`data-v-3a0eeb7e`]]),Ja={__name:`ScrollToBottom`,props:{visible:{type:Boolean,default:!1}},emits:[`click`],setup(e){return(t,n)=>(r(),b(ce,{name:`fade`},{default:a(()=>[e.visible?(r(),g(`button`,{key:0,type:`button`,class:`absolute bottom-3 left-1/2 -translate-x-1/2 z-10 flex items-center gap-1.5 rounded-full border border-border bg-surface px-3 py-1.5 text-xs text-foreground-muted shadow-lg shadow-black/30 transition-colors hover:text-white hover:bg-surface-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-background`,"aria-label":`Scroll to latest`,onClick:n[0]||=e=>t.$emit(`click`)},[v(f(Se),{class:`h-3.5 w-3.5`}),n[1]||=x(` Latest `,-1)])):w(``,!0)]),_:1}))}},Ya={class:`relative min-h-0 flex-1`},Xa={class:`mx-auto w-full max-w-3xl py-6`},Za={__name:`MessageList`,props:{items:{type:Array,required:!0},streaming:{type:Boolean,default:!1}},emits:[`approve`,`reject`,`regenerate`,`edit`,`delete`,`retry`,`dismiss`],setup(e){let t=e,n=C(()=>{for(let e=t.items.length-1;e>=0;e--){let n=t.items[e];if(n.kind===`message`&&n.role===`assistant`)return e}return-1}),i=C(()=>{if(!t.streaming)return!1;let e=t.items[t.items.length-1];return e?e.kind===`tool`?!0:e.kind===`message`?e.role===`user`||!(e.parts||[]).some(e=>e.type===`text`&&e.text||e.type===`thinking`&&e.text):!1:!1}),a=o(null),s=o(!0);function c(e){if(e===0)return``;let n=t.items[e],r=t.items[e-1];return n.kind===`message`&&n.role===`user`?`mt-8`:n.kind===`tool`?`mt-2`:r.kind===`tool`?`mt-3`:`mt-4`}function u(){let e=t.items[t.items.length-1];if(!e||e.kind!==`message`||!Array.isArray(e.parts))return 0;let n=0;for(let t of e.parts)n+=t&&typeof t.text==`string`?t.text.length:0;return n}function f(){let e=a.value;return!e||e.scrollTop+e.clientHeight>=e.scrollHeight-100}function p(){s.value=f()}async function m(){await E();let e=a.value;e&&(e.scrollTop=e.scrollHeight)}function x(){s.value=!0,m()}return l(()=>[t.items.length,t.streaming,u()],()=>{s.value&&m()}),d(m),(t,o)=>(r(),g(`div`,Ya,[h(`div`,{ref_key:`scroller`,ref:a,class:`scrollable h-full overflow-y-auto px-4`,role:`log`,"aria-live":`polite`,"aria-atomic":`false`,"aria-label":`Chat messages`,onScroll:p},[h(`div`,Xa,[(r(!0),g(S,null,y(e.items,(i,a)=>(r(),g(S,{key:i.id??a},[i.kind===`message`?(r(),b(ja,{key:0,role:i.role,parts:i.parts,"can-regenerate":i.role===`assistant`&&!e.streaming&&a===n.value,editable:i.role===`user`&&!e.streaming,deletable:!e.streaming&&!!i.id,class:_(c(a)),onRegenerate:o[0]||=e=>t.$emit(`regenerate`),onEdit:e=>t.$emit(`edit`,{id:i.id,content:e}),onDelete:e=>t.$emit(`delete`,i.id)},null,8,[`role`,`parts`,`can-regenerate`,`editable`,`deletable`,`class`,`onEdit`,`onDelete`])):i.kind===`tool`?(r(),b(Ra,{key:1,tool:i,class:_(c(a)),onApprove:o[1]||=e=>t.$emit(`approve`,e),onReject:o[2]||=e=>t.$emit(`reject`,e)},null,8,[`tool`,`class`])):i.kind===`error`?(r(),b(Ua,{key:2,message:i.message,class:_(c(a)),onRetry:o[3]||=e=>t.$emit(`retry`),onDismiss:e=>t.$emit(`dismiss`,i.id)},null,8,[`message`,`class`,`onDismiss`])):w(``,!0)],64))),128)),i.value?(r(),b(qa,{key:0,class:_(e.items.length?`mt-4`:``)},null,8,[`class`])):w(``,!0)])],544),v(Ja,{visible:!s.value,onClick:x},null,8,[`visible`])]))}},Qa={class:`py-1`},$a=Object.assign({name:`CommonPopover`},{__name:`Popover`,props:{title:{type:String,default:``}},setup(e,{expose:n}){let s=o(!1),c=o(null),l=o(null),u=o({}),f=o(!1),_=null,y=()=>{_&&(f.value=_.matches)};function x(){let e=c.value?.firstElementChild||c.value;if(!e)return;let t=e.getBoundingClientRect(),n=Math.max(8,Math.min(t.left,window.innerWidth-8-200));u.value={left:`${n}px`,bottom:`${window.innerHeight-t.top+6}px`},E(()=>{let e=l.value;if(!e)return;let n=e.offsetWidth,r=Math.max(8,Math.min(t.left,window.innerWidth-8-n));u.value={...u.value,left:`${r}px`}})}function C(){s.value=!0,f.value||E(x)}function T(){s.value=!1}function D(){s.value?T():C()}function O(e){!s.value||f.value||l.value?.contains(e.target)||c.value?.contains(e.target)||T()}function k(){s.value&&!f.value&&x()}return d(()=>{_=window.matchMedia(`(max-width: 639px)`),y(),_.addEventListener(`change`,y),document.addEventListener(`pointerdown`,O,!0),window.addEventListener(`resize`,k)}),i(()=>{_?.removeEventListener(`change`,y),document.removeEventListener(`pointerdown`,O,!0),window.removeEventListener(`resize`,k)}),n({open:C,close:T}),(n,i)=>(r(),g(S,null,[h(`span`,{ref_key:`triggerEl`,ref:c,class:`inline-flex`},[t(n.$slots,`trigger`,{open:s.value,toggle:D})],512),(r(),b(m,{to:`body`},[v(ce,{name:`fade`},{default:a(()=>[s.value&&!f.value?(r(),g(`div`,{key:0,ref_key:`panelEl`,ref:l,class:`fixed z-50 min-w-[200px] max-w-[min(320px,calc(100vw-1rem))] bg-background border border-border rounded-lg shadow-xl overflow-hidden`,style:p(u.value),role:`menu`,onKeydown:he(T,[`esc`])},[t(n.$slots,`default`,{close:T})],36)):w(``,!0)]),_:3})])),f.value?(r(),b(ge,{key:0,modelValue:s.value,"onUpdate:modelValue":i[0]||=e=>s.value=e,title:e.title},{default:a(()=>[h(`div`,Qa,[t(n.$slots,`default`,{close:T})])]),_:3},8,[`modelValue`,`title`])):w(``,!0)],64))}}),eo=[`title`,`onClick`],to={key:0},no={class:`py-1`},ro=[`aria-checked`,`onClick`],io={class:`flex-1`},ao={class:`block`},oo={class:`block text-[11px] text-foreground-muted`},so={key:0,class:`px-3 pt-1.5 pb-1.5 mt-1 border-t border-border text-[11px] text-foreground-muted leading-snug`},co={__name:`ReasoningMenu`,setup(e){let t=A(),n=[{v:`off`,label:`Off`,hint:`Answer directly`,icon:we},{v:`standard`,label:`Think`,hint:`Reason before answering`,icon:ie},{v:`deep`,label:`Deep`,hint:`Extended reasoning`,icon:ne}],i=C(()=>t.thinking&&t.thinking!==`off`),o=C(()=>n.find(e=>e.v===t.thinking)?.label||`Off`),s=[/\bo[1-9]/i,/gpt-5/i,/-thinking/i,/reason/i,/deepseek-r/i,/claude.*(sonnet|opus)/i,/qwen.*(think|3)/i,/grok.*(3|4)/i],l=C(()=>{let e=t.selectedModel||``;return s.some(t=>t.test(e))});function u(e,n){t.setThinking(e),n()}return(e,s)=>(r(),b($a,{title:`Reasoning`},{trigger:a(({toggle:e})=>[h(`button`,{type:`button`,class:_([`touch-expand-sm inline-flex h-8 items-center justify-center gap-1.5 rounded-lg px-2.5 text-xs transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-surface`,i.value?`text-primary bg-primary/15 hover:bg-primary/20`:`text-foreground-muted hover:text-foreground hover:bg-surface-hover`]),title:`Reasoning: ${o.value}`,"aria-label":`Reasoning level`,onClick:e},[v(f(Te),{class:`w-4 h-4 shrink-0`}),i.value?(r(),g(`span`,to,T(o.value),1)):w(``,!0)],10,eo)]),default:a(({close:e})=>[h(`div`,no,[s[0]||=h(`p`,{class:`px-3 pt-1.5 pb-1 text-[10px] uppercase tracking-label text-foreground-muted`},` Reasoning `,-1),(r(),g(S,null,y(n,n=>h(`button`,{key:n.v,type:`button`,class:_([`flex w-full items-center gap-2.5 px-3 py-2 text-left text-sm transition-colors focus-visible:outline-none focus-visible:bg-surface-hover`,f(t).thinking===n.v?`text-white bg-primary/15`:`text-foreground hover:bg-surface-hover`]),role:`menuitemradio`,"aria-checked":f(t).thinking===n.v,onClick:t=>u(n.v,e)},[(r(),b(c(n.icon),{class:_([`w-3.5 h-3.5 shrink-0`,f(t).thinking===n.v?`text-primary`:`text-foreground-muted`])},null,8,[`class`])),h(`span`,io,[h(`span`,ao,T(n.label),1),h(`span`,oo,T(n.hint),1)]),f(t).thinking===n.v?(r(),b(f(D),{key:0,class:`w-3.5 h-3.5 shrink-0 text-primary`})):w(``,!0)],10,ro)),64)),i.value&&!l.value?(r(),g(`p`,so,T(f(t).selectedModel||`This model`)+` may ignore reasoning requests. `,1)):w(``,!0)])]),_:1}))}},lo=[`title`,`onClick`],uo={class:`truncate font-mono`},fo={class:`max-h-[60dvh] overflow-y-auto scrollable py-1`},po=[`onClick`],mo={class:`flex-1 truncate`},ho={key:1,class:`sticky top-0 z-10 bg-background px-3 pb-2 pt-0.5`},go={class:`relative`},_o={key:2,class:`px-3 py-2 text-sm text-foreground-muted`},vo={key:3,class:`px-3 py-2 text-xs text-foreground-muted leading-snug`},yo={key:4,class:`px-3 py-2 text-xs text-foreground-muted leading-snug`},bo=[`onClick`],xo={class:`flex-1 truncate`},So={__name:`ModelMenu`,setup(e){let t=A(),n=o(``),i=C(()=>t.models.length>6);function c(e,t){let n=0,r=0,i=-1;for(let a of t){let t=e.indexOf(a,r);if(t===-1)return-1;n+=t===i+1?3:1,n-=t-r,i=t,r=t+1}return n}let u=C(()=>{let e=n.value.trim().toLowerCase();return e?t.models.map(t=>({m:t,s:c(t.id.toLowerCase(),e)})).filter(e=>e.s>=0).sort((e,t)=>t.s-e.s).map(e=>e.m):t.models});l(()=>t.selectedProviderId,()=>{n.value=``});function d(e,r){t.selectModel(e),n.value=``,r()}return(e,o)=>(r(),b($a,{title:`Model`},{trigger:a(({toggle:e})=>[h(`button`,{type:`button`,class:`touch-expand-sm inline-flex items-center gap-1.5 h-8 max-w-[180px] px-2.5 rounded-lg text-xs text-foreground-muted hover:text-foreground hover:bg-surface-hover transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-surface`,title:f(t).selectedModel||`Select model`,"aria-label":`Select model`,onClick:e},[v(f(Oe),{class:`w-3.5 h-3.5 shrink-0`}),h(`span`,uo,T(f(t).selectedModel||`No model`),1),v(f(oe),{class:`w-3 h-3 shrink-0 opacity-70`})],8,lo)]),default:a(({close:e})=>[h(`div`,fo,[f(t).providers.length>1?(r(),g(S,{key:0},[o[1]||=h(`p`,{class:`px-3 pt-1.5 pb-1 text-[10px] uppercase tracking-label text-foreground-muted`},` Provider `,-1),(r(!0),g(S,null,y(f(t).providers,e=>(r(),g(`button`,{key:e.id,type:`button`,class:_([`flex w-full items-center gap-2.5 px-3 py-1.5 text-left text-sm transition-colors focus-visible:outline-none focus-visible:bg-surface-hover`,f(t).selectedProviderId===e.id?`text-white bg-primary/15`:`text-foreground hover:bg-surface-hover`]),onClick:n=>f(t).selectProvider(e.id)},[h(`span`,mo,T(e.label||e.provider),1),f(t).selectedProviderId===e.id?(r(),b(f(D),{key:0,class:`w-3.5 h-3.5 shrink-0 text-primary`})):w(``,!0)],10,po))),128)),o[2]||=h(`div`,{class:`my-1 border-t border-border`},null,-1)],64)):w(``,!0),o[3]||=h(`p`,{class:`px-3 pt-1 pb-1 text-[10px] uppercase tracking-label text-foreground-muted`},` Model `,-1),i.value?(r(),g(`div`,ho,[h(`div`,go,[v(f(me),{class:`pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-foreground-muted`}),s(h(`input`,{"onUpdate:modelValue":o[0]||=e=>n.value=e,type:`text`,placeholder:`Search models…`,class:`w-full rounded-md border border-border bg-surface py-1.5 pl-8 pr-2.5 text-base sm:text-sm text-foreground placeholder-foreground-muted/50 transition-colors duration-200 focus:border-white focus:outline-none focus:ring-1 focus:ring-white`},null,512),[[se,n.value]])])])):w(``,!0),f(t).modelsLoading?(r(),g(`p`,_o,` Loading models… `)):f(t).models.length?u.value.length?(r(!0),g(S,{key:5},y(u.value,n=>(r(),g(`button`,{key:n.id,type:`button`,class:_([`flex w-full items-center gap-2.5 px-3 py-1.5 text-left text-sm font-mono transition-colors focus-visible:outline-none focus-visible:bg-surface-hover`,f(t).selectedModel===n.id?`text-white bg-primary/15`:`text-foreground hover:bg-surface-hover`]),onClick:t=>d(n.id,e)},[h(`span`,xo,T(n.id),1),f(t).selectedModel===n.id?(r(),b(f(D),{key:0,class:`w-3.5 h-3.5 shrink-0 text-primary`})):w(``,!0)],10,bo))),128)):(r(),g(`p`,yo,` No models match “`+T(n.value.trim())+`”. `,1)):(r(),g(`p`,vo,T(f(t).modelsError?`No models. Check the provider endpoint.`:`No models reported.`),1))])]),_:1}))}},Co={class:`mx-auto w-full max-w-3xl`},wo=[`disabled`,`placeholder`],To={class:`flex items-center gap-1.5 px-2 pb-2`},Eo=[`disabled`],Do=Object.assign({name:`AIComposer`},{__name:`Composer`,props:{streaming:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1},docked:{type:Boolean,default:!0},modelReady:{type:Boolean,default:!0}},emits:[`send`,`stop`],setup(e,{expose:t,emit:n}){let i=e,l=n,u=o(``),d=o(null),p=C(()=>i.disabled?`Configure a provider to start`:`Message the assistant…`);function m(){let e=d.value;e&&(e.style.height=`auto`,e.style.height=`${e.scrollHeight}px`)}function y(){let e=u.value.trim();!e||i.streaming||i.disabled||!i.modelReady||(l(`send`,e),u.value=``,E(()=>{d.value&&(d.value.style.height=`auto`)}))}function x(e){e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),y())}function T(e){u.value=e,E(()=>{m(),d.value?.focus()})}return t({focus:()=>d.value?.focus(),setText:T}),(t,n)=>(r(),b(c(e.docked?`footer`:`div`),{class:_([`shrink-0 px-4`,e.docked?`pt-3 pb-composer`:`py-0`])},{default:a(()=>[h(`div`,Co,[h(`div`,{class:_([`rounded-2xl border border-border bg-surface transition-colors focus-within:border-foreground-muted/50`,{"opacity-60":e.disabled}])},[s(h(`textarea`,{ref_key:`ta`,ref:d,"onUpdate:modelValue":n[0]||=e=>u.value=e,rows:`1`,disabled:e.disabled,placeholder:p.value,"aria-label":`Message the assistant`,class:`max-h-40 w-full resize-none overflow-y-auto bg-transparent px-3.5 pt-3 pb-1.5 text-sm text-foreground placeholder-foreground-muted/60 focus:outline-none disabled:cursor-not-allowed`,onInput:m,onKeydown:x},null,40,wo),[[se,u.value]]),h(`div`,To,[e.disabled?w(``,!0):(r(),g(S,{key:0},[v(co),v(So)],64)),n[2]||=h(`span`,{class:`flex-1`},null,-1),e.streaming?(r(),g(`button`,{key:1,type:`button`,class:`touch-expand-iconbtn inline-flex h-8 w-8 items-center justify-center rounded-lg bg-surface-hover text-foreground transition-colors hover:bg-border focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-surface`,"aria-label":`Stop generating (Esc)`,title:`Stop generating (Esc)`,onClick:n[1]||=e=>t.$emit(`stop`)},[v(f(je),{class:`h-3.5 w-3.5 fill-current`})])):(r(),g(`button`,{key:2,type:`button`,class:`touch-expand-iconbtn inline-flex h-8 w-8 items-center justify-center rounded-lg bg-primary text-primary-foreground shadow-sm transition-colors hover:bg-primary-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-surface disabled:opacity-40 disabled:shadow-none`,disabled:e.disabled||!e.modelReady||!u.value.trim(),"aria-label":`Send message`,title:`Send message`,onClick:y},[v(f(Ce),{class:`h-4 w-4`})],8,Eo))])],2)])]),_:1},8,[`class`]))}}),Oo={class:`flex h-full bg-background`,style:{overflow:`hidden`,padding:`0`}},ko={class:`hidden w-64 shrink-0 border-r border-border md:block`},Ao={class:`flex min-w-0 flex-1 flex-col`},jo={key:0,class:`flex shrink-0 items-center justify-between gap-3 border-b border-warning-ring bg-warning-tint px-4 py-2.5 text-xs text-warning-fg`},Mo={key:1,class:`scrollable flex flex-1 flex-col items-center justify-center overflow-y-auto px-4 py-6`},No={class:`w-full max-w-3xl`},Po={__name:`AI`,setup(e){let t=A(),n=de(),s=fe();function c(){s.push({name:`settings`,hash:`#ai`})}function l({id:e,content:n}){t.editAndResend(e,n)}async function p(e){await n.ask({title:`Delete from here?`,message:`This removes this message and everything after it in the conversation. This cannot be undone.`,danger:!0,confirmLabel:`Delete`})&&t.deleteMessageFrom(e)}let m=o(!1),_=o(null);function y(e){_.value?.setText(e)}let b=C(()=>t.conversations.find(e=>e.id===t.activeId)?.title||`Assistant`);async function T(){await t.loadSettings(),await Promise.all([t.loadProviders(),t.loadConversations()])}d(T),u(()=>{t.loadConversations(),t.loadSettings(),t.loadProviders()});function E(e){e.key===`Escape`&&t.streaming&&!document.querySelector(`[role="dialog"], [role="menu"]`)&&t.stop()}return d(()=>window.addEventListener(`keydown`,E)),i(()=>window.removeEventListener(`keydown`,E)),(e,n)=>(r(),g(`div`,Oo,[h(`aside`,ko,[v(Ke)]),v(ge,{modelValue:m.value,"onUpdate:modelValue":n[1]||=e=>m.value=e,title:`Conversations`},{default:a(()=>[v(Ke,{embedded:``,onSelect:n[0]||=e=>m.value=!1})]),_:1},8,[`modelValue`]),h(`div`,Ao,[v(Le,{title:b.value,"can-export":!!f(t).timeline.length,onToggleRail:n[2]||=e=>m.value=!0,onExport:f(t).exportActive},null,8,[`title`,`can-export`,`onExport`]),f(t).providersLoaded&&!f(t).providers.length?(r(),g(`div`,jo,[n[4]||=h(`span`,null,`Add an AI provider to start chatting.`,-1),v(j,{size:`xs`,variant:`secondary`,onClick:c},{default:a(()=>[...n[3]||=[x(` Configure `,-1)]]),_:1})])):w(``,!0),f(t).timeline.length?(r(),g(S,{key:2},[v(Za,{items:f(t).timeline,streaming:f(t).streaming,onApprove:f(t).approveTool,onReject:f(t).rejectTool,onRegenerate:f(t).regenerate,onEdit:l,onDelete:p,onRetry:f(t).retry,onDismiss:f(t).dismissError},null,8,[`items`,`streaming`,`onApprove`,`onReject`,`onRegenerate`,`onRetry`,`onDismiss`]),v(Do,{streaming:f(t).streaming,disabled:f(t).providersLoaded&&!f(t).providers.length,"model-ready":!!f(t).selectedModel,onSend:f(t).sendMessage,onStop:f(t).stop},null,8,[`streaming`,`disabled`,`model-ready`,`onSend`,`onStop`])],64)):(r(),g(`div`,Mo,[h(`div`,No,[v(Ze,{onPick:y}),v(Do,{ref_key:`emptyComposer`,ref:_,class:`mt-6`,docked:!1,streaming:f(t).streaming,disabled:f(t).providersLoaded&&!f(t).providers.length,"model-ready":!!f(t).selectedModel,onSend:f(t).sendMessage,onStop:f(t).stop},null,8,[`streaming`,`disabled`,`model-ready`,`onSend`,`onStop`])])]))])]))}};export{Po as default}; \ No newline at end of file diff --git a/backend/internal/server/ui_dist/assets/Activity-DsyXryTa.js b/backend/internal/server/ui_dist/assets/Activity-DsyXryTa.js new file mode 100644 index 00000000..57b8a25a --- /dev/null +++ b/backend/internal/server/ui_dist/assets/Activity-DsyXryTa.js @@ -0,0 +1 @@ +import{D as e,E as t,F as n,G as r,I as ee,S as te,T as ne,Z as i,c as a,d as o,gt as re,h as s,k as c,l,m as u,r as d,s as f,u as p,vt as m,w as ie}from"./runtime-core.esm-bundler-BMQPyJ_W.js";import{t as ae}from"./chevron-right-BNHZGbeL.js";import{Lt as oe,N as se,_t as h,jt as g,r as ce,xt as le}from"./index-CZI-jurg.js";import{t as ue}from"./Drawer-B765_4al.js";import{t as _}from"./StatusBadge-D05dwaq1.js";var de=g(`chevron-left`,[[`path`,{d:`m15 18-6-6 6-6`,key:`1wnfg3`}]]),v={__name:`SourceTag`,props:{source:{type:String,default:``}},setup(t){let n=t,r=f(()=>{switch(n.source){case`web`:return`text-indigo-300 border-indigo-900/40`;case`api`:return`text-sky-300 border-sky-900/40`;case`mcp`:return`text-violet-300 border-violet-900/40`;case`sdk`:return`text-teal-300 border-teal-900/40`;case`webhook`:return`text-amber-300 border-amber-900/40`;case`cron`:return`text-emerald-300 border-emerald-900/40`;case`internal`:return`text-foreground-muted border-border`;default:return`text-foreground-muted border-border`}});return(n,ee)=>(e(),o(`span`,{class:re([`inline-flex items-center px-2 py-0.5 rounded text-xs border bg-background font-mono uppercase tracking-wide`,r.value])},m(t.source||i(`—`)),3))}},fe={class:`space-y-6`},pe={class:`flex flex-col sm:flex-row sm:items-center gap-2 sm:flex-wrap`},me={class:`relative w-full sm:flex-1 sm:min-w-[260px] sm:max-w-[420px]`},he={class:`flex items-center gap-2 sm:flex-wrap overflow-x-auto sm:overflow-visible scrollable snap-x min-w-0`},ge={key:0,class:`ml-1 opacity-60 tabular-nums`},_e={class:`bg-background border border-border rounded-lg overflow-x-auto`},ve={class:`sm:hidden divide-y divide-border`},ye=[`onClick`],be={class:`flex items-start justify-between gap-2`},xe={class:`min-w-0 flex-1`},Se={class:`flex items-center gap-2 flex-wrap`},Ce={class:`mt-1 text-xs font-mono text-white break-all`},we={key:0,class:`mt-1 text-[11px] text-foreground-muted break-words`},Te={class:`mt-1 flex flex-wrap items-center gap-x-3 gap-y-0.5 text-[11px] text-foreground-muted font-mono`},Ee={key:0},De={key:1,class:`break-all`},Oe={key:0,class:`px-6 py-12 text-center text-sm text-foreground-muted`},y={class:`hidden sm:table w-full text-sm text-left`},b={class:`divide-y divide-border`},x=[`onClick`],S={class:`px-4 py-2.5 font-mono text-xs text-foreground-muted`},C={class:`px-4 py-2.5`},w={class:`px-4 py-2.5 hidden md:table-cell`},T={class:`text-xs text-white truncate max-w-[200px]`},ke={key:0,class:`text-[10px] text-foreground-muted/70 font-mono truncate`},Ae={class:`px-4 py-2.5 text-xs font-mono text-foreground-muted hidden sm:table-cell`},je={class:`px-4 py-2.5 text-xs font-mono text-white truncate max-w-[440px]`},Me={class:`px-4 py-2.5 hidden sm:table-cell`},Ne={key:1,class:`text-foreground-muted text-xs`},Pe={class:`px-4 py-2.5 text-xs font-mono text-foreground-muted hidden lg:table-cell`},Fe={class:`px-4 py-2.5 text-xs text-foreground-muted truncate max-w-[280px] hidden xl:table-cell`},Ie={key:0},Le={key:0,class:`flex items-center justify-between text-xs`},Re={class:`text-foreground-muted`},ze={class:`flex items-center gap-1`},Be={key:0,class:`p-5 space-y-5 text-sm`},Ve={class:`grid grid-cols-2 gap-3`},He={class:`bg-surface border border-border rounded p-3 min-w-0`},Ue={class:`text-xs text-white font-mono truncate`},We={class:`bg-surface border border-border rounded p-3 min-w-0`},Ge={class:`bg-surface border border-border rounded p-3 min-w-0`},Ke={class:`text-sm text-white truncate`},qe={key:0,class:`text-[11px] text-foreground-muted font-mono truncate mt-0.5`},Je={class:`bg-surface border border-border rounded p-3 min-w-0`},Ye={class:`flex items-center gap-2`},Xe={key:1,class:`text-foreground-muted text-xs`},Ze={key:2,class:`text-xs text-foreground-muted font-mono`},Qe={class:`bg-surface border border-border rounded p-3 min-w-0`},$e={class:`text-xs text-white font-mono truncate`},et={class:`bg-surface border border-border rounded p-3 min-w-0`},tt={class:`text-xs text-white font-mono`},nt={class:`bg-surface border border-border rounded p-3 text-xs text-white font-mono whitespace-pre-wrap break-all`},rt={class:`text-foreground break-words`},it={key:0},at={class:`bg-surface border border-border rounded p-3 text-xs text-foreground-muted font-mono whitespace-pre-wrap break-all`},ot={key:1},st={class:`bg-surface border border-border rounded p-3 text-xs text-foreground font-mono overflow-auto max-h-72 whitespace-pre-wrap break-words`},E=100,D=200,O=Object.assign({name:`ActivityView`},{__name:`Activity`,setup(re){let g=ce(),O=[{label:`All`,value:``},{label:`Web`,value:`web`},{label:`API`,value:`api`},{label:`MCP`,value:`mcp`},{label:`SDK`,value:`sdk`},{label:`Webhook`,value:`webhook`},{label:`Internal`,value:`internal`}],ct=[{label:`All`,value:``},{label:`Success`,value:`ok`},{label:`Errors`,value:`err`}],lt=[{label:`5m`,value:`5m`},{label:`1h`,value:`1h`},{label:`24h`,value:`24h`},{label:`7d`,value:`7d`}],k=r({q:``,source:``,statusBucket:``,range:`24h`}),A=r([]),j=r([]),M=r(!1),N=r(null),P=r(0),F=r(!1),I=r(1),L=r([{since:void 0,until:void 0}]),R=f(()=>I.value===1?[...j.value,...A.value]:A.value),z=f(()=>{let e={};for(let t of R.value)e[t.source]=(e[t.source]||0)+1;return e[``]=R.value.length,e}),B=f(()=>Math.max(L.value.length,I.value)),ut=f(()=>{let e=B.value,t=I.value;return[...new Set([1,e,t-1,t,t+1])].filter(t=>t>=1&&t<=e).sort((e,t)=>e-t)}),dt=e=>{switch(e){case`5m`:return 3e5;case`1h`:return 36e5;case`24h`:return 864e5;case`7d`:return 6048e5;default:return 0}},ft=(e={})=>{let t={limit:E};k.value.source&&(t.source=k.value.source),k.value.statusBucket===`err`&&(t.status_min=400),k.value.q&&(t.q=k.value.q);let n=dt(k.value.range);return n&&(t.since=Date.now()-n),Object.assign(t,e)},V=async e=>{if(e<1||e>L.value.length+1)return;let t=L.value[e-1]?.cursor,n=await se(ft(t?{cursor:t}:{}));A.value=n.data?.rows||[];let r=n.data?.next_cursor||0;F.value=r>0,L.value[e-1]||(L.value[e-1]={}),L.value[e-1].cursor=t,r?(L.value[e]||(L.value[e]={}),L.value[e].cursor=r):L.value=L.value.slice(0,e),P.value=(e-1)*E+A.value.length,I.value=e,e>1&&(j.value=[])},H=async()=>{L.value=[{since:void 0,until:void 0}],j.value=[],I.value=1,await V(1)},U=null,pt=e=>{if(k.value.source&&e.source!==k.value.source||k.value.statusBucket===`err`&&(e.status||0)<400)return!1;if(k.value.q){let t=k.value.q.toLowerCase();if(!(e.path+` `+e.summary+` `+e.actor_label).toLowerCase().includes(t))return!1}return!0},W=e=>{pt(e)&&I.value===1&&(j.value.unshift(e),j.value.length>D&&(j.value=j.value.slice(0,D)))},G=null,mt=()=>{clearTimeout(G),G=setTimeout(H,250)},K=e=>{N.value=e,M.value=!0},ht=f(()=>N.value?N.value.summary||N.value.method+` `+N.value.path:`Activity`),q=f(()=>{if(!N.value?.metadata)return``;try{return JSON.stringify(JSON.parse(N.value.metadata),null,2)}catch{return N.value.metadata}}),J=e=>e?new Date(e).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`,second:`2-digit`,hour12:!1}):`—`,gt=e=>e?new Date(e).toLocaleString():`—`,Y=e=>e==null?`—`:e<1?`<1ms`:e<1e3?e+`ms`:(e/1e3).toFixed(2)+`s`,X=e=>e?e>=500?`error`:e>=400?`failed`:e>=200?`success`:`pending`:``,Z=e=>e.id?`db-${e.id}`:`live-${e.ts}-${e.request_id}-${e.path}`,Q=()=>{U||(U=g.subscribe(`activity`,W),g.connect())},$=()=>{U&&=(U(),null)};return ne(()=>{Q(),H()}),t($),te(()=>{Q(),H()}),ie($),(t,r)=>(e(),o(`div`,fe,[r[20]||=a(`div`,null,[a(`h1`,{class:`text-xl font-semibold text-white tracking-tight`},` Activity `),a(`p`,{class:`text-sm text-foreground-muted mt-1.5 max-w-prose leading-body`},` Every API and MCP request. `)],-1),a(`div`,pe,[a(`div`,me,[s(i(le),{class:`w-3.5 h-3.5 absolute left-2.5 top-1/2 -translate-y-1/2 text-foreground-muted/60 pointer-events-none`}),ee(a(`input`,{"onUpdate:modelValue":r[0]||=e=>k.value.q=e,"aria-label":`Search activity by path, summary, or actor`,placeholder:`Search path, summary, actor…`,class:`w-full bg-background border border-border rounded-md pl-8 pr-3 py-1.5 text-base sm:text-xs text-foreground placeholder-foreground-muted/60 focus:outline-none focus:ring-1 focus:ring-white focus:border-white`,onInput:mt},null,544),[[oe,k.value.q]])]),a(`div`,he,[(e(),o(d,null,c(O,t=>s(h,{key:t.value,variant:`chip`,size:`xs`,active:k.value.source===t.value,class:`shrink-0 snap-start`,onClick:e=>{k.value.source=t.value,H()}},{default:n(()=>[u(m(t.label)+` `,1),z.value[t.value]!=null&&t.value!==``?(e(),o(`span`,ge,m(z.value[t.value]),1)):p(``,!0)]),_:2},1032,[`active`,`onClick`])),64)),r[4]||=a(`span`,{class:`text-foreground-muted/40 shrink-0`},`·`,-1),(e(),o(d,null,c(ct,e=>s(h,{key:e.value,variant:`chip`,size:`xs`,active:k.value.statusBucket===e.value,class:`shrink-0 snap-start`,onClick:t=>{k.value.statusBucket=e.value,H()}},{default:n(()=>[u(m(e.label),1)]),_:2},1032,[`active`,`onClick`])),64)),r[5]||=a(`span`,{class:`text-foreground-muted/40 shrink-0`},`·`,-1),(e(),o(d,null,c(lt,e=>s(h,{key:e.value,variant:`chip`,size:`xs`,active:k.value.range===e.value,class:`shrink-0 snap-start`,onClick:t=>{k.value.range=e.value,H()}},{default:n(()=>[u(m(e.label),1)]),_:2},1032,[`active`,`onClick`])),64))])]),a(`div`,_e,[a(`ul`,ve,[(e(!0),o(d,null,c(R.value,t=>(e(),o(`li`,{key:Z(t),class:`px-4 py-3 cursor-pointer hover:bg-surface-hover transition-colors`,onClick:e=>K(t)},[a(`div`,be,[a(`div`,xe,[a(`div`,Se,[s(v,{source:t.source},null,8,[`source`]),t.status?(e(),l(_,{key:0,status:X(t.status)},null,8,[`status`])):p(``,!0)]),a(`div`,Ce,m(t.method?t.method+` `:``)+m(t.path||i(`—`)),1),t.summary?(e(),o(`div`,we,m(t.summary),1)):p(``,!0),a(`div`,Te,[a(`span`,null,m(J(t.ts)),1),t.duration_ms==null?p(``,!0):(e(),o(`span`,Ee,m(Y(t.duration_ms)),1)),t.actor_label||t.actor_id?(e(),o(`span`,De,m(t.actor_label||t.actor_id),1)):p(``,!0)])])])],8,ye))),128)),R.value.length?p(``,!0):(e(),o(`li`,Oe,` Requests and tool calls appear here. `))]),a(`table`,y,[r[7]||=a(`thead`,{class:`text-xs text-foreground-muted uppercase bg-surface border-b border-border`},[a(`tr`,null,[a(`th`,{class:`px-4 py-3 w-32`},` Time `),a(`th`,{class:`px-4 py-3 w-24`},` Source `),a(`th`,{class:`px-4 py-3 w-40 hidden md:table-cell`},` Actor `),a(`th`,{class:`px-4 py-3 w-20 hidden sm:table-cell`},` Method `),a(`th`,{class:`px-4 py-3`},` Path / Tool `),a(`th`,{class:`px-4 py-3 w-16 hidden sm:table-cell`},` Status `),a(`th`,{class:`px-4 py-3 w-20 hidden lg:table-cell`},` Duration `),a(`th`,{class:`px-4 py-3 hidden xl:table-cell`},` Summary `)])],-1),a(`tbody`,b,[(e(!0),o(d,null,c(R.value,t=>(e(),o(`tr`,{key:Z(t),class:`hover:bg-surface-hover cursor-pointer transition-colors`,onClick:e=>K(t)},[a(`td`,S,m(J(t.ts)),1),a(`td`,C,[s(v,{source:t.source},null,8,[`source`])]),a(`td`,w,[a(`div`,T,m(t.actor_label||t.actor_id||i(`—`)),1),t.actor_label&&t.actor_id&&t.actor_label!==t.actor_id?(e(),o(`div`,ke,m(t.actor_id),1)):p(``,!0)]),a(`td`,Ae,m(t.method||i(`—`)),1),a(`td`,je,m(t.path||i(`—`)),1),a(`td`,Me,[t.status?(e(),l(_,{key:0,status:X(t.status)},null,8,[`status`])):(e(),o(`span`,Ne,m(i(`—`)),1))]),a(`td`,Pe,m(Y(t.duration_ms)),1),a(`td`,Fe,m(t.summary),1)],8,x))),128)),R.value.length?p(``,!0):(e(),o(`tr`,Ie,[...r[6]||=[a(`td`,{colspan:`8`,class:`px-4 py-12 text-center text-foreground-muted text-sm`},` Requests and tool calls appear here. `,-1)]]))])])]),B.value>1?(e(),o(`div`,Le,[a(`div`,Re,` Page `+m(I.value)+` of `+m(B.value)+` · `+m(P.value)+m(F.value?`+`:``)+` rows `,1),a(`div`,ze,[s(h,{variant:`secondary`,size:`xs`,disabled:I.value<=1,onClick:r[1]||=e=>V(I.value-1)},{default:n(()=>[s(i(de),{class:`w-3.5 h-3.5`}),r[8]||=u(` Prev `,-1)]),_:1},8,[`disabled`]),(e(!0),o(d,null,c(ut.value,t=>(e(),l(h,{key:t,variant:t===I.value?`primary`:`secondary`,size:`xs`,onClick:e=>V(t)},{default:n(()=>[u(m(t),1)]),_:2},1032,[`variant`,`onClick`]))),128)),s(h,{variant:`secondary`,size:`xs`,disabled:I.value>=B.value&&!F.value,onClick:r[2]||=e=>V(I.value+1)},{default:n(()=>[r[9]||=u(` Next `,-1),s(i(ae),{class:`w-3.5 h-3.5`})]),_:1},8,[`disabled`])])])):p(``,!0),s(ue,{modelValue:M.value,"onUpdate:modelValue":r[3]||=e=>M.value=e,title:ht.value,width:`640px`},{default:n(()=>[N.value?(e(),o(`div`,Be,[a(`div`,Ve,[a(`div`,He,[r[10]||=a(`div`,{class:`text-[10px] uppercase tracking-wider text-foreground-muted mb-1`},` Time `,-1),a(`div`,Ue,m(gt(N.value.ts)),1)]),a(`div`,We,[r[11]||=a(`div`,{class:`text-[10px] uppercase tracking-wider text-foreground-muted mb-1`},` Source `,-1),s(v,{source:N.value.source},null,8,[`source`])]),a(`div`,Ge,[r[12]||=a(`div`,{class:`text-[10px] uppercase tracking-wider text-foreground-muted mb-1`},` Actor `,-1),a(`div`,Ke,m(N.value.actor_label||i(`—`)),1),N.value.actor_id?(e(),o(`div`,qe,m(N.value.actor_id),1)):p(``,!0)]),a(`div`,Je,[r[13]||=a(`div`,{class:`text-[10px] uppercase tracking-wider text-foreground-muted mb-1`},` Status `,-1),a(`div`,Ye,[N.value.status?(e(),l(_,{key:0,status:X(N.value.status)},null,8,[`status`])):(e(),o(`span`,Xe,m(i(`—`)),1)),N.value.status?(e(),o(`span`,Ze,`HTTP `+m(N.value.status),1)):p(``,!0)])]),a(`div`,Qe,[r[14]||=a(`div`,{class:`text-[10px] uppercase tracking-wider text-foreground-muted mb-1`},` Method `,-1),a(`div`,$e,m(N.value.method||i(`—`)),1)]),a(`div`,et,[r[15]||=a(`div`,{class:`text-[10px] uppercase tracking-wider text-foreground-muted mb-1`},` Duration `,-1),a(`div`,tt,m(Y(N.value.duration_ms)),1)])]),a(`div`,null,[r[16]||=a(`h3`,{class:`text-xs uppercase tracking-wider text-foreground-muted mb-2`},` Path / Tool `,-1),a(`pre`,nt,m(N.value.path||i(`—`)),1)]),a(`div`,null,[r[17]||=a(`h3`,{class:`text-xs uppercase tracking-wider text-foreground-muted mb-2`},` Summary `,-1),a(`div`,rt,m(N.value.summary||i(`—`)),1)]),N.value.request_id?(e(),o(`div`,it,[r[18]||=a(`h3`,{class:`text-xs uppercase tracking-wider text-foreground-muted mb-2`},` Request ID `,-1),a(`pre`,at,m(N.value.request_id),1)])):p(``,!0),q.value?(e(),o(`div`,ot,[r[19]||=a(`h3`,{class:`text-xs uppercase tracking-wider text-foreground-muted mb-2`},` Metadata `,-1),a(`pre`,st,m(q.value),1)])):p(``,!0)])):p(``,!0)]),_:1},8,[`modelValue`,`title`])]))}});export{O as default}; \ No newline at end of file diff --git a/backend/internal/server/ui_dist/assets/Activity-y79g4hAI.js b/backend/internal/server/ui_dist/assets/Activity-y79g4hAI.js deleted file mode 100644 index e563cd7e..00000000 --- a/backend/internal/server/ui_dist/assets/Activity-y79g4hAI.js +++ /dev/null @@ -1 +0,0 @@ -import{D as e,E as t,F as n,P as r,S as i,T as ee,W as a,X as o,_t as s,c,d as l,h as u,ht as te,k as d,l as f,m as p,r as m,s as h,u as g,w as ne}from"./runtime-core.esm-bundler-DWJwptQ-.js";import{t as re}from"./chevron-right-Cee8Bzpp.js";import{At as _,It as ie,N as ae,_t as v,r as oe,xt as se}from"./index-B93KhQc5.js";import{t as ce}from"./Drawer-CNvPia4g.js";import{t as y}from"./StatusBadge-C3Y8qWdJ.js";var le=_(`chevron-left`,[[`path`,{d:`m15 18-6-6 6-6`,key:`1wnfg3`}]]),b={__name:`SourceTag`,props:{source:{type:String,default:``}},setup(t){let n=t,r=h(()=>{switch(n.source){case`web`:return`text-indigo-300 border-indigo-900/40`;case`api`:return`text-sky-300 border-sky-900/40`;case`mcp`:return`text-violet-300 border-violet-900/40`;case`sdk`:return`text-teal-300 border-teal-900/40`;case`webhook`:return`text-amber-300 border-amber-900/40`;case`cron`:return`text-emerald-300 border-emerald-900/40`;case`internal`:return`text-foreground-muted border-border`;default:return`text-foreground-muted border-border`}});return(n,i)=>(e(),l(`span`,{class:te([`inline-flex items-center px-2 py-0.5 rounded text-xs border bg-background font-mono uppercase tracking-wide`,r.value])},s(t.source||o(`—`)),3))}},ue={class:`space-y-6`},de={class:`flex flex-col sm:flex-row sm:items-center gap-2 sm:flex-wrap`},fe={class:`relative w-full sm:flex-1 sm:min-w-[260px] sm:max-w-[420px]`},pe={class:`flex items-center gap-2 sm:flex-wrap overflow-x-auto sm:overflow-visible scrollable snap-x min-w-0`},me={key:0,class:`ml-1 opacity-60 tabular-nums`},he={class:`bg-background border border-border rounded-lg overflow-x-auto`},ge={class:`sm:hidden divide-y divide-border`},_e=[`onClick`],ve={class:`flex items-start justify-between gap-2`},ye={class:`min-w-0 flex-1`},be={class:`flex items-center gap-2 flex-wrap`},xe={class:`mt-1 text-xs font-mono text-white break-all`},Se={key:0,class:`mt-1 text-[11px] text-foreground-muted break-words`},Ce={class:`mt-1 flex flex-wrap items-center gap-x-3 gap-y-0.5 text-[11px] text-foreground-muted font-mono`},we={key:0},Te={key:1,class:`break-all`},Ee={key:0,class:`px-6 py-12 text-center text-sm text-foreground-muted`},De={class:`hidden sm:table w-full text-sm text-left`},Oe={class:`divide-y divide-border`},x=[`onClick`],S={class:`px-4 py-2.5 font-mono text-xs text-foreground-muted`},C={class:`px-4 py-2.5`},w={class:`px-4 py-2.5 hidden md:table-cell`},T={class:`text-xs text-white truncate max-w-[200px]`},ke={key:0,class:`text-[10px] text-foreground-muted/70 font-mono truncate`},Ae={class:`px-4 py-2.5 text-xs font-mono text-foreground-muted hidden sm:table-cell`},je={class:`px-4 py-2.5 text-xs font-mono text-white truncate max-w-[440px]`},Me={class:`px-4 py-2.5 hidden sm:table-cell`},Ne={key:1,class:`text-foreground-muted text-xs`},Pe={class:`px-4 py-2.5 text-xs font-mono text-foreground-muted hidden lg:table-cell`},Fe={class:`px-4 py-2.5 text-xs text-foreground-muted truncate max-w-[280px] hidden xl:table-cell`},Ie={key:0},Le={key:0,class:`flex items-center justify-between text-xs`},Re={class:`text-foreground-muted`},ze={class:`flex items-center gap-1`},Be={key:0,class:`p-5 space-y-5 text-sm`},Ve={class:`grid grid-cols-2 gap-3`},He={class:`bg-surface border border-border rounded p-3 min-w-0`},Ue={class:`text-xs text-white font-mono truncate`},We={class:`bg-surface border border-border rounded p-3 min-w-0`},Ge={class:`bg-surface border border-border rounded p-3 min-w-0`},Ke={class:`text-sm text-white truncate`},qe={key:0,class:`text-[11px] text-foreground-muted font-mono truncate mt-0.5`},Je={class:`bg-surface border border-border rounded p-3 min-w-0`},Ye={class:`flex items-center gap-2`},Xe={key:1,class:`text-foreground-muted text-xs`},Ze={key:2,class:`text-xs text-foreground-muted font-mono`},Qe={class:`bg-surface border border-border rounded p-3 min-w-0`},$e={class:`text-xs text-white font-mono truncate`},et={class:`bg-surface border border-border rounded p-3 min-w-0`},tt={class:`text-xs text-white font-mono`},nt={class:`bg-surface border border-border rounded p-3 text-xs text-white font-mono whitespace-pre-wrap break-all`},rt={class:`text-foreground break-words`},it={key:0},at={class:`bg-surface border border-border rounded p-3 text-xs text-foreground-muted font-mono whitespace-pre-wrap break-all`},ot={key:1},st={class:`bg-surface border border-border rounded p-3 text-xs text-foreground font-mono overflow-auto max-h-72 whitespace-pre-wrap break-words`},E=100,D=200,O=Object.assign({name:`ActivityView`},{__name:`Activity`,setup(te){let _=oe(),O=[{label:`All`,value:``},{label:`Web`,value:`web`},{label:`API`,value:`api`},{label:`MCP`,value:`mcp`},{label:`SDK`,value:`sdk`},{label:`Webhook`,value:`webhook`},{label:`Internal`,value:`internal`}],ct=[{label:`All`,value:``},{label:`Success`,value:`ok`},{label:`Errors`,value:`err`}],lt=[{label:`5m`,value:`5m`},{label:`1h`,value:`1h`},{label:`24h`,value:`24h`},{label:`7d`,value:`7d`}],k=a({q:``,source:``,statusBucket:``,range:`24h`}),A=a([]),j=a([]),M=a(!1),N=a(null),P=a(0),F=a(!1),I=a(1),L=a([{since:void 0,until:void 0}]),R=h(()=>I.value===1?[...j.value,...A.value]:A.value),z=h(()=>{let e={};for(let t of R.value)e[t.source]=(e[t.source]||0)+1;return e[``]=R.value.length,e}),B=h(()=>Math.max(L.value.length,I.value)),ut=h(()=>{let e=B.value,t=I.value;return[...new Set([1,e,t-1,t,t+1])].filter(t=>t>=1&&t<=e).sort((e,t)=>e-t)}),dt=e=>{switch(e){case`5m`:return 3e5;case`1h`:return 36e5;case`24h`:return 864e5;case`7d`:return 6048e5;default:return 0}},ft=(e={})=>{let t={limit:E};k.value.source&&(t.source=k.value.source),k.value.statusBucket===`err`&&(t.status_min=400),k.value.q&&(t.q=k.value.q);let n=dt(k.value.range);return n&&(t.since=Date.now()-n),Object.assign(t,e)},V=async e=>{if(e<1||e>L.value.length+1)return;let t=L.value[e-1]?.cursor,n=await ae(ft(t?{cursor:t}:{}));A.value=n.data?.rows||[];let r=n.data?.next_cursor||0;F.value=r>0,L.value[e-1]||(L.value[e-1]={}),L.value[e-1].cursor=t,r?(L.value[e]||(L.value[e]={}),L.value[e].cursor=r):L.value=L.value.slice(0,e),P.value=(e-1)*E+A.value.length,I.value=e,e>1&&(j.value=[])},H=async()=>{L.value=[{since:void 0,until:void 0}],j.value=[],I.value=1,await V(1)},U=null,pt=e=>{if(k.value.source&&e.source!==k.value.source||k.value.statusBucket===`err`&&(e.status||0)<400)return!1;if(k.value.q){let t=k.value.q.toLowerCase();if(!(e.path+` `+e.summary+` `+e.actor_label).toLowerCase().includes(t))return!1}return!0},W=e=>{pt(e)&&I.value===1&&(j.value.unshift(e),j.value.length>D&&(j.value=j.value.slice(0,D)))},G=null,mt=()=>{clearTimeout(G),G=setTimeout(H,250)},K=e=>{N.value=e,M.value=!0},ht=h(()=>N.value?N.value.summary||N.value.method+` `+N.value.path:`Activity`),q=h(()=>{if(!N.value?.metadata)return``;try{return JSON.stringify(JSON.parse(N.value.metadata),null,2)}catch{return N.value.metadata}}),J=e=>e?new Date(e).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`,second:`2-digit`,hour12:!1}):`—`,gt=e=>e?new Date(e).toLocaleString():`—`,Y=e=>e==null?`—`:e<1?`<1ms`:e<1e3?e+`ms`:(e/1e3).toFixed(2)+`s`,X=e=>e?e>=500?`error`:e>=400?`failed`:e>=200?`success`:`pending`:``,Z=e=>e.id?`db-${e.id}`:`live-${e.ts}-${e.request_id}-${e.path}`,Q=()=>{U||(U=_.subscribe(`activity`,W),_.connect())},$=()=>{U&&=(U(),null)};return ee(()=>{Q(),H()}),t($),i(()=>{Q(),H()}),ne($),(t,i)=>(e(),l(`div`,ue,[i[20]||=c(`div`,null,[c(`h1`,{class:`text-xl font-semibold text-white tracking-tight`},` Activity `),c(`p`,{class:`text-sm text-foreground-muted mt-1.5 max-w-prose leading-body`},` Live feed of every API call hitting Orva: UI clicks, REST/SDK, MCP tools, webhook deliveries. `)],-1),c(`div`,de,[c(`div`,fe,[u(o(se),{class:`w-3.5 h-3.5 absolute left-2.5 top-1/2 -translate-y-1/2 text-foreground-muted/60 pointer-events-none`}),n(c(`input`,{"onUpdate:modelValue":i[0]||=e=>k.value.q=e,"aria-label":`Search activity by path, summary, or actor`,placeholder:`Search path, summary, actor…`,class:`w-full bg-background border border-border rounded-md pl-8 pr-3 py-1.5 text-base sm:text-xs text-foreground placeholder-foreground-muted/60 focus:outline-none focus:ring-1 focus:ring-white focus:border-white`,onInput:mt},null,544),[[ie,k.value.q]])]),c(`div`,pe,[(e(),l(m,null,d(O,t=>u(v,{key:t.value,variant:`chip`,size:`xs`,active:k.value.source===t.value,class:`shrink-0 snap-start`,onClick:e=>{k.value.source=t.value,H()}},{default:r(()=>[p(s(t.label)+` `,1),z.value[t.value]!=null&&t.value!==``?(e(),l(`span`,me,s(z.value[t.value]),1)):g(``,!0)]),_:2},1032,[`active`,`onClick`])),64)),i[4]||=c(`span`,{class:`text-foreground-muted/40 shrink-0`},`·`,-1),(e(),l(m,null,d(ct,e=>u(v,{key:e.value,variant:`chip`,size:`xs`,active:k.value.statusBucket===e.value,class:`shrink-0 snap-start`,onClick:t=>{k.value.statusBucket=e.value,H()}},{default:r(()=>[p(s(e.label),1)]),_:2},1032,[`active`,`onClick`])),64)),i[5]||=c(`span`,{class:`text-foreground-muted/40 shrink-0`},`·`,-1),(e(),l(m,null,d(lt,e=>u(v,{key:e.value,variant:`chip`,size:`xs`,active:k.value.range===e.value,class:`shrink-0 snap-start`,onClick:t=>{k.value.range=e.value,H()}},{default:r(()=>[p(s(e.label),1)]),_:2},1032,[`active`,`onClick`])),64))])]),c(`div`,he,[c(`ul`,ge,[(e(!0),l(m,null,d(R.value,t=>(e(),l(`li`,{key:Z(t),class:`px-4 py-3 cursor-pointer hover:bg-surface-hover transition-colors`,onClick:e=>K(t)},[c(`div`,ve,[c(`div`,ye,[c(`div`,be,[u(b,{source:t.source},null,8,[`source`]),t.status?(e(),f(y,{key:0,status:X(t.status)},null,8,[`status`])):g(``,!0)]),c(`div`,xe,s(t.method?t.method+` `:``)+s(t.path||o(`—`)),1),t.summary?(e(),l(`div`,Se,s(t.summary),1)):g(``,!0),c(`div`,Ce,[c(`span`,null,s(J(t.ts)),1),t.duration_ms==null?g(``,!0):(e(),l(`span`,we,s(Y(t.duration_ms)),1)),t.actor_label||t.actor_id?(e(),l(`span`,Te,s(t.actor_label||t.actor_id),1)):g(``,!0)])])])],8,_e))),128)),R.value.length?g(``,!0):(e(),l(`li`,Ee,` No activity yet. Drive any action (open the dashboard, call a function, fire an MCP tool) and rows will land here. `))]),c(`table`,De,[i[7]||=c(`thead`,{class:`text-xs text-foreground-muted uppercase bg-surface border-b border-border`},[c(`tr`,null,[c(`th`,{class:`px-4 py-3 w-32`},` Time `),c(`th`,{class:`px-4 py-3 w-24`},` Source `),c(`th`,{class:`px-4 py-3 w-40 hidden md:table-cell`},` Actor `),c(`th`,{class:`px-4 py-3 w-20 hidden sm:table-cell`},` Method `),c(`th`,{class:`px-4 py-3`},` Path / Tool `),c(`th`,{class:`px-4 py-3 w-16 hidden sm:table-cell`},` Status `),c(`th`,{class:`px-4 py-3 w-20 hidden lg:table-cell`},` Duration `),c(`th`,{class:`px-4 py-3 hidden xl:table-cell`},` Summary `)])],-1),c(`tbody`,Oe,[(e(!0),l(m,null,d(R.value,t=>(e(),l(`tr`,{key:Z(t),class:`hover:bg-surface-hover cursor-pointer transition-colors`,onClick:e=>K(t)},[c(`td`,S,s(J(t.ts)),1),c(`td`,C,[u(b,{source:t.source},null,8,[`source`])]),c(`td`,w,[c(`div`,T,s(t.actor_label||t.actor_id||o(`—`)),1),t.actor_label&&t.actor_id&&t.actor_label!==t.actor_id?(e(),l(`div`,ke,s(t.actor_id),1)):g(``,!0)]),c(`td`,Ae,s(t.method||o(`—`)),1),c(`td`,je,s(t.path||o(`—`)),1),c(`td`,Me,[t.status?(e(),f(y,{key:0,status:X(t.status)},null,8,[`status`])):(e(),l(`span`,Ne,s(o(`—`)),1))]),c(`td`,Pe,s(Y(t.duration_ms)),1),c(`td`,Fe,s(t.summary),1)],8,x))),128)),R.value.length?g(``,!0):(e(),l(`tr`,Ie,[...i[6]||=[c(`td`,{colspan:`8`,class:`px-4 py-12 text-center text-foreground-muted text-sm`},` No activity yet. Drive any action (open the dashboard, call a function, fire an MCP tool) and rows will land here. `,-1)]]))])])]),B.value>1?(e(),l(`div`,Le,[c(`div`,Re,` Page `+s(I.value)+` of `+s(B.value)+` · `+s(P.value)+s(F.value?`+`:``)+` rows `,1),c(`div`,ze,[u(v,{variant:`secondary`,size:`xs`,disabled:I.value<=1,onClick:i[1]||=e=>V(I.value-1)},{default:r(()=>[u(o(le),{class:`w-3.5 h-3.5`}),i[8]||=p(` Prev `,-1)]),_:1},8,[`disabled`]),(e(!0),l(m,null,d(ut.value,t=>(e(),f(v,{key:t,variant:t===I.value?`primary`:`secondary`,size:`xs`,onClick:e=>V(t)},{default:r(()=>[p(s(t),1)]),_:2},1032,[`variant`,`onClick`]))),128)),u(v,{variant:`secondary`,size:`xs`,disabled:I.value>=B.value&&!F.value,onClick:i[2]||=e=>V(I.value+1)},{default:r(()=>[i[9]||=p(` Next `,-1),u(o(re),{class:`w-3.5 h-3.5`})]),_:1},8,[`disabled`])])])):g(``,!0),u(ce,{modelValue:M.value,"onUpdate:modelValue":i[3]||=e=>M.value=e,title:ht.value,width:`640px`},{default:r(()=>[N.value?(e(),l(`div`,Be,[c(`div`,Ve,[c(`div`,He,[i[10]||=c(`div`,{class:`text-[10px] uppercase tracking-wider text-foreground-muted mb-1`},` Time `,-1),c(`div`,Ue,s(gt(N.value.ts)),1)]),c(`div`,We,[i[11]||=c(`div`,{class:`text-[10px] uppercase tracking-wider text-foreground-muted mb-1`},` Source `,-1),u(b,{source:N.value.source},null,8,[`source`])]),c(`div`,Ge,[i[12]||=c(`div`,{class:`text-[10px] uppercase tracking-wider text-foreground-muted mb-1`},` Actor `,-1),c(`div`,Ke,s(N.value.actor_label||o(`—`)),1),N.value.actor_id?(e(),l(`div`,qe,s(N.value.actor_id),1)):g(``,!0)]),c(`div`,Je,[i[13]||=c(`div`,{class:`text-[10px] uppercase tracking-wider text-foreground-muted mb-1`},` Status `,-1),c(`div`,Ye,[N.value.status?(e(),f(y,{key:0,status:X(N.value.status)},null,8,[`status`])):(e(),l(`span`,Xe,s(o(`—`)),1)),N.value.status?(e(),l(`span`,Ze,`HTTP `+s(N.value.status),1)):g(``,!0)])]),c(`div`,Qe,[i[14]||=c(`div`,{class:`text-[10px] uppercase tracking-wider text-foreground-muted mb-1`},` Method `,-1),c(`div`,$e,s(N.value.method||o(`—`)),1)]),c(`div`,et,[i[15]||=c(`div`,{class:`text-[10px] uppercase tracking-wider text-foreground-muted mb-1`},` Duration `,-1),c(`div`,tt,s(Y(N.value.duration_ms)),1)])]),c(`div`,null,[i[16]||=c(`h3`,{class:`text-xs uppercase tracking-wider text-foreground-muted mb-2`},` Path / Tool `,-1),c(`pre`,nt,s(N.value.path||o(`—`)),1)]),c(`div`,null,[i[17]||=c(`h3`,{class:`text-xs uppercase tracking-wider text-foreground-muted mb-2`},` Summary `,-1),c(`div`,rt,s(N.value.summary||o(`—`)),1)]),N.value.request_id?(e(),l(`div`,it,[i[18]||=c(`h3`,{class:`text-xs uppercase tracking-wider text-foreground-muted mb-2`},` Request ID `,-1),c(`pre`,at,s(N.value.request_id),1)])):g(``,!0),q.value?(e(),l(`div`,ot,[i[19]||=c(`h3`,{class:`text-xs uppercase tracking-wider text-foreground-muted mb-2`},` Metadata `,-1),c(`pre`,st,s(q.value),1)])):g(``,!0)])):g(``,!0)]),_:1},8,[`modelValue`,`title`])]))}});export{O as default}; \ No newline at end of file diff --git a/backend/internal/server/ui_dist/assets/ApiKeys-CH-rpjHf.js b/backend/internal/server/ui_dist/assets/ApiKeys-CH-rpjHf.js new file mode 100644 index 00000000..295b2156 --- /dev/null +++ b/backend/internal/server/ui_dist/assets/ApiKeys-CH-rpjHf.js @@ -0,0 +1,3 @@ +import{D as e,F as t,G as n,I as r,T as i,Z as a,c as o,d as s,h as c,k as l,l as u,m as d,r as f,u as p,vt as m}from"./runtime-core.esm-bundler-BMQPyJ_W.js";import{t as ee}from"./check-ho22bAKW.js";import{t as h}from"./copy-DHTw5vil.js";import{t as g}from"./key-round-7iKBY7s0.js";import{t as _}from"./trash-2-DDX094Y-.js";import{It as te,Lt as ne,P as re,_t as v,d as ie,gt as ae,o as oe,vt as se}from"./index-CZI-jurg.js";import{t as ce}from"./clipboard-D_9N0yai.js";import{t as y}from"./IconButton-CsCZOqWo.js";import{n as b,t as x}from"./time-D8OmbYzY.js";var S={class:`space-y-6`},C={class:`flex items-start justify-between gap-4`},w={key:0,class:`bg-background border border-amber-700/40 rounded-lg p-4 space-y-2`},T={class:`flex items-start justify-between gap-3`},E={class:`flex items-center gap-2`},D={class:`flex-1 font-mono text-sm text-white break-all bg-surface px-3 py-2 rounded border border-border`},O={key:1,class:`bg-background border border-border rounded-lg p-5 space-y-4`},k={class:`grid grid-cols-1 md:grid-cols-2 gap-3`},A={class:`flex gap-2 pt-1`},j={class:`bg-background border border-border rounded-lg overflow-x-auto`},M={class:`sm:hidden divide-y divide-border`},N={class:`flex items-start justify-between gap-2`},P={class:`min-w-0 flex-1`},F={class:`flex items-center gap-2 flex-wrap`},I={class:`font-medium text-white truncate`},L={key:0,class:`text-[11px] font-mono text-foreground-muted bg-surface px-1.5 py-0.5 rounded`},R={class:`mt-1 flex flex-wrap items-center gap-x-3 gap-y-0.5 text-[11px] text-foreground-muted`},z={key:0},B={key:1,class:`text-warning-fg`},V={key:2},H={key:3,class:`text-danger-fg`},U={key:4},W={key:0,class:`px-6 py-8 text-center text-sm text-foreground-muted`},le={class:`hidden sm:table w-full text-sm text-left`},ue={class:`divide-y divide-border`},de={class:`px-6 py-4 text-white font-medium`},fe={class:`px-6 py-4 text-foreground-muted font-mono text-xs hidden sm:table-cell`},pe={class:`px-6 py-4 text-foreground-muted hidden xl:table-cell`},me={class:`px-6 py-4 hidden md:table-cell`},he={key:0,class:`text-foreground-muted`},ge={key:1,class:`text-warning-fg text-xs`},_e={class:`px-6 py-4 hidden lg:table-cell`},ve={key:0,class:`text-foreground-muted`},ye={key:1,class:`text-danger-fg text-xs`},be={key:2,class:`text-foreground-muted`},xe={class:`px-6 py-4 text-right`},Se={key:0},Ce={__name:`ApiKeys`,setup(Ce){let G=ae(),K=n([]),q=n(``),J=n(!1),Y=n(!1),X=n(!1),Z=n({name:``,expiresInDays:0}),Q=async()=>{let e=await re();K.value=e.data.keys||[]},we=()=>{Z.value={name:``,expiresInDays:0},Y.value=!0},Te=()=>{Y.value=!1,Z.value={name:``,expiresInDays:0}},Ee=async()=>{X.value=!0;try{let e={name:Z.value.name.trim()};Z.value.expiresInDays>0&&(e.expires_in_days=Z.value.expiresInDays);let t=await oe(e);q.value=t.data.key,J.value=!1,Y.value=!1,await Q()}catch(e){console.error(e),G.notify({title:`Failed to create key`,message:e?.response?.data?.error?.message||`Unknown error`,danger:!0})}finally{X.value=!1}},De=async()=>{await ce(q.value)?(J.value=!0,setTimeout(()=>{J.value=!1},1500)):G.notify({title:`Copy failed`,message:`Could not copy to clipboard. Select the key manually: + +`+q.value})},$=async e=>{if(await G.ask({title:`Delete API key?`,message:`"${e.name||e.id}" will stop working immediately. This cannot be undone.`,confirmLabel:`Delete`,danger:!0}))try{await ie(e.id),await Q()}catch(e){console.error(e),G.notify({title:`Failed to delete key`,message:e?.response?.data?.error?.message||`Unknown error`,danger:!0})}},Oe=e=>new Date(e).toLocaleString();return i(Q),(n,i)=>(e(),s(`div`,S,[o(`div`,C,[i[4]||=o(`div`,null,[o(`h1`,{class:`text-xl font-semibold text-white tracking-tight`},` API Keys `),o(`p`,{class:`text-sm text-foreground-muted mt-1.5 max-w-prose leading-body`},` Tokens for REST and MCP clients. Secrets are shown once. `)],-1),c(v,{onClick:we},{default:t(()=>[c(a(g),{class:`w-4 h-4`}),i[3]||=d(` New Key `,-1)]),_:1})]),q.value?(e(),s(`div`,w,[o(`div`,T,[i[5]||=o(`div`,null,[o(`h2`,{class:`text-xs font-bold text-amber-300 uppercase tracking-wider`},` Copy this key now `),o(`div`,{class:`text-xs text-foreground-muted mt-0.5`},` Store it securely. This secret will not be shown again. `)],-1),o(`button`,{class:`text-foreground-muted hover:text-white`,title:`Dismiss`,"aria-label":`Dismiss API key`,onClick:i[0]||=e=>q.value=``},[c(a(se),{class:`w-4 h-4`})])]),o(`div`,E,[o(`code`,D,m(q.value),1),o(`button`,{class:`px-3 py-2 rounded-md border border-border bg-surface-hover hover:bg-surface text-foreground-muted hover:text-white transition-colors flex items-center gap-1.5 text-xs`,onClick:De},[J.value?(e(),u(a(ee),{key:0,class:`w-3.5 h-3.5 text-success`})):(e(),u(a(h),{key:1,class:`w-3.5 h-3.5`})),d(` `+m(J.value?`Copied`:`Copy`),1)])])])):p(``,!0),Y.value?(e(),s(`div`,O,[i[11]||=o(`div`,{class:`text-sm font-semibold text-white`},` New API Key `,-1),o(`div`,k,[o(`div`,null,[i[6]||=o(`label`,{for:`api-key-name`,class:`text-xs font-medium text-foreground-muted uppercase tracking-wide block mb-1.5`},`Name`,-1),r(o(`input`,{id:`api-key-name`,"onUpdate:modelValue":i[1]||=e=>Z.value.name=e,placeholder:`e.g. ci-deployer`,class:`w-full bg-surface-hover border border-border rounded-md px-3 py-2 text-sm text-foreground focus:outline-none focus:border-white`},null,512),[[ne,Z.value.name]])]),o(`div`,null,[i[8]||=o(`label`,{for:`api-key-expiry`,class:`text-xs font-medium text-foreground-muted uppercase tracking-wide block mb-1.5`},`Expires in`,-1),r(o(`select`,{id:`api-key-expiry`,"onUpdate:modelValue":i[2]||=e=>Z.value.expiresInDays=e,class:`w-full bg-surface-hover border border-border rounded-md px-3 py-2 text-sm text-foreground focus:outline-none focus:border-white`},[...i[7]||=[o(`option`,{value:0},` Never `,-1),o(`option`,{value:1},` 1 day `,-1),o(`option`,{value:7},` 7 days `,-1),o(`option`,{value:30},` 30 days `,-1),o(`option`,{value:90},` 90 days `,-1),o(`option`,{value:365},` 1 year `,-1)]],512),[[te,Z.value.expiresInDays]])])]),o(`div`,A,[c(v,{disabled:!Z.value.name.trim()||X.value,loading:X.value,onClick:Ee},{default:t(()=>[...i[9]||=[d(` Generate Key `,-1)]]),_:1},8,[`disabled`,`loading`]),c(v,{variant:`secondary`,onClick:Te},{default:t(()=>[...i[10]||=[d(` Cancel `,-1)]]),_:1})])])):p(``,!0),o(`div`,j,[o(`ul`,M,[(e(!0),s(f,null,l(K.value,t=>(e(),s(`li`,{key:t.id,class:`px-4 py-3`},[o(`div`,N,[o(`div`,P,[o(`div`,F,[o(`span`,I,m(t.name||`Unnamed`),1),t.prefix?(e(),s(`code`,L,m(t.prefix)+`…`,1)):p(``,!0)]),o(`div`,R,[t.last_used_at?(e(),s(`span`,z,`used `+m(a(x)(t.last_used_at)),1)):(e(),s(`span`,B,`never used`)),t.expires_at?a(b)(t.expires_at)?(e(),s(`span`,H,`expired `+m(a(x)(t.expires_at)),1)):(e(),s(`span`,U,`expires `+m(a(x)(t.expires_at)),1)):(e(),s(`span`,V,`no expiry`))])]),c(y,{icon:a(_),variant:`danger`,title:`Delete key`,onClick:e=>$(t)},null,8,[`icon`,`onClick`])])]))),128)),K.value.length===0?(e(),s(`li`,W,` No API keys yet. `)):p(``,!0)]),o(`table`,le,[i[13]||=o(`thead`,{class:`text-xs text-foreground-muted uppercase bg-surface border-b border-border`},[o(`tr`,null,[o(`th`,{scope:`col`,class:`px-6 py-3 font-medium`},` Name `),o(`th`,{scope:`col`,class:`px-6 py-3 font-medium hidden sm:table-cell`},` Prefix `),o(`th`,{scope:`col`,class:`px-6 py-3 font-medium hidden xl:table-cell`},` Created `),o(`th`,{scope:`col`,class:`px-6 py-3 font-medium hidden md:table-cell`},` Last Used `),o(`th`,{scope:`col`,class:`px-6 py-3 font-medium hidden lg:table-cell`},` Expires `),o(`th`,{scope:`col`,class:`px-6 py-3 font-medium text-right`},` Actions `)])],-1),o(`tbody`,ue,[(e(!0),s(f,null,l(K.value,t=>(e(),s(`tr`,{key:t.id,class:`hover:bg-surface/50 transition-colors`},[o(`td`,de,m(t.name||`Unnamed`),1),o(`td`,fe,m(t.prefix?t.prefix+`…`:a(`—`)),1),o(`td`,pe,m(Oe(t.created_at)),1),o(`td`,me,[t.last_used_at?(e(),s(`span`,he,m(a(x)(t.last_used_at)),1)):(e(),s(`span`,ge,`Never used`))]),o(`td`,_e,[t.expires_at?a(b)(t.expires_at)?(e(),s(`span`,ye,`Expired `+m(a(x)(t.expires_at)),1)):(e(),s(`span`,be,m(a(x)(t.expires_at)),1)):(e(),s(`span`,ve,`Never`))]),o(`td`,xe,[c(y,{icon:a(_),variant:`danger`,title:`Delete key`,onClick:e=>$(t)},null,8,[`icon`,`onClick`])])]))),128)),K.value.length===0?(e(),s(`tr`,Se,[...i[12]||=[o(`td`,{colspan:`6`,class:`px-6 py-8 text-center text-foreground-muted`},` No API keys yet. `,-1)]])):p(``,!0)])])])]))}};export{Ce as default}; \ No newline at end of file diff --git a/backend/internal/server/ui_dist/assets/ApiKeys-D9lr2hws.js b/backend/internal/server/ui_dist/assets/ApiKeys-D9lr2hws.js deleted file mode 100644 index 7a23f6d5..00000000 --- a/backend/internal/server/ui_dist/assets/ApiKeys-D9lr2hws.js +++ /dev/null @@ -1,3 +0,0 @@ -import{D as e,F as t,P as n,T as ee,W as r,X as i,_t as a,c as o,d as s,h as c,k as l,l as u,m as d,r as f,u as p}from"./runtime-core.esm-bundler-DWJwptQ-.js";import{t as te}from"./check-lEJPUgfZ.js";import{t as m}from"./copy-5veW7U_F.js";import{t as h}from"./key-round-CJGTpWKA.js";import{t as g}from"./trash-2-BlIjHjqi.js";import{Ft as _,It as ne,P as re,_t as v,d as ie,gt as ae,o as oe,vt as se}from"./index-B93KhQc5.js";import{t as ce}from"./clipboard-D_9N0yai.js";import{t as y}from"./IconButton-D_Xb_fPi.js";import{n as b,t as x}from"./time-D8OmbYzY.js";var S={class:`space-y-6`},C={class:`flex items-start justify-between gap-4`},w={key:0,class:`bg-background border border-amber-700/40 rounded-lg p-4 space-y-2`},T={class:`flex items-start justify-between gap-3`},E={class:`flex items-center gap-2`},D={class:`flex-1 font-mono text-sm text-white break-all bg-surface px-3 py-2 rounded border border-border`},O={key:1,class:`bg-background border border-border rounded-lg p-5 space-y-4`},k={class:`grid grid-cols-1 md:grid-cols-2 gap-3`},A={class:`flex gap-2 pt-1`},j={class:`bg-background border border-border rounded-lg overflow-x-auto`},M={class:`sm:hidden divide-y divide-border`},N={class:`flex items-start justify-between gap-2`},P={class:`min-w-0 flex-1`},F={class:`flex items-center gap-2 flex-wrap`},I={class:`font-medium text-white truncate`},L={key:0,class:`text-[11px] font-mono text-foreground-muted bg-surface px-1.5 py-0.5 rounded`},R={class:`mt-1 flex flex-wrap items-center gap-x-3 gap-y-0.5 text-[11px] text-foreground-muted`},z={key:0},B={key:1,class:`text-amber-400/80`},V={key:2},H={key:3,class:`text-red-400`},U={key:4},le={key:0,class:`px-6 py-8 text-center text-sm text-foreground-muted`},W={class:`hidden sm:table w-full text-sm text-left`},ue={class:`divide-y divide-border`},de={class:`px-6 py-4 text-white font-medium`},fe={class:`px-6 py-4 text-foreground-muted font-mono text-xs hidden sm:table-cell`},pe={class:`px-6 py-4 text-foreground-muted hidden xl:table-cell`},me={class:`px-6 py-4 hidden md:table-cell`},he={key:0,class:`text-foreground-muted`},ge={key:1,class:`text-amber-400/70 text-xs`},_e={class:`px-6 py-4 hidden lg:table-cell`},ve={key:0,class:`text-foreground-muted`},ye={key:1,class:`text-red-400 text-xs`},be={key:2,class:`text-foreground-muted`},xe={class:`px-6 py-4 text-right`},Se={key:0},Ce={__name:`ApiKeys`,setup(Ce){let G=ae(),K=r([]),q=r(``),J=r(!1),Y=r(!1),X=r(!1),Z=r({name:``,expiresInDays:0}),Q=async()=>{let e=await re();K.value=e.data.keys||[]},we=()=>{Z.value={name:``,expiresInDays:0},Y.value=!0},Te=()=>{Y.value=!1,Z.value={name:``,expiresInDays:0}},Ee=async()=>{X.value=!0;try{let e={name:Z.value.name.trim()};Z.value.expiresInDays>0&&(e.expires_in_days=Z.value.expiresInDays);let t=await oe(e);q.value=t.data.key,J.value=!1,Y.value=!1,await Q()}catch(e){console.error(e),G.notify({title:`Failed to create key`,message:e?.response?.data?.error?.message||`Unknown error`,danger:!0})}finally{X.value=!1}},De=async()=>{await ce(q.value)?(J.value=!0,setTimeout(()=>{J.value=!1},1500)):G.notify({title:`Copy failed`,message:`Could not copy to clipboard. Select the key manually: - -`+q.value})},$=async e=>{if(await G.ask({title:`Delete API key?`,message:`"${e.name||e.id}" will stop working immediately. This cannot be undone.`,confirmLabel:`Delete`,danger:!0}))try{await ie(e.id),await Q()}catch(e){console.error(e),G.notify({title:`Failed to delete key`,message:e?.response?.data?.error?.message||`Unknown error`,danger:!0})}},Oe=e=>new Date(e).toLocaleString();return ee(Q),(ee,r)=>(e(),s(`div`,S,[o(`div`,C,[r[4]||=o(`div`,null,[o(`h1`,{class:`text-xl font-semibold text-white tracking-tight`},` API Keys `),o(`p`,{class:`text-sm text-foreground-muted mt-1.5 max-w-prose leading-body`},` Long-lived bearer tokens that authorise REST and MCP calls from CI, scripts, and external services. Plaintext is shown once at creation; the server keeps only a SHA-256 hash. `)],-1),c(v,{onClick:we},{default:n(()=>[c(i(h),{class:`w-4 h-4`}),r[3]||=d(` New Key `,-1)]),_:1})]),q.value?(e(),s(`div`,w,[o(`div`,T,[r[5]||=o(`div`,null,[o(`h2`,{class:`text-xs font-bold text-amber-300 uppercase tracking-wider`},` Copy this key now `),o(`div`,{class:`text-xs text-foreground-muted mt-0.5`},` It will not be shown again. Anyone with this key can invoke your functions. `)],-1),o(`button`,{class:`text-foreground-muted hover:text-white`,title:`Dismiss`,onClick:r[0]||=e=>q.value=``},[c(i(se),{class:`w-4 h-4`})])]),o(`div`,E,[o(`code`,D,a(q.value),1),o(`button`,{class:`px-3 py-2 rounded-md border border-border bg-surface-hover hover:bg-surface text-foreground-muted hover:text-white transition-colors flex items-center gap-1.5 text-xs`,onClick:De},[J.value?(e(),u(i(te),{key:0,class:`w-3.5 h-3.5 text-success`})):(e(),u(i(m),{key:1,class:`w-3.5 h-3.5`})),d(` `+a(J.value?`Copied`:`Copy`),1)])])])):p(``,!0),Y.value?(e(),s(`div`,O,[r[11]||=o(`div`,{class:`text-sm font-semibold text-white`},` New API Key `,-1),o(`div`,k,[o(`div`,null,[r[6]||=o(`label`,{class:`text-xs font-medium text-foreground-muted uppercase tracking-wide block mb-1.5`},`Name`,-1),t(o(`input`,{"onUpdate:modelValue":r[1]||=e=>Z.value.name=e,placeholder:`e.g. ci-deployer`,class:`w-full bg-surface-hover border border-border rounded-md px-3 py-2 text-sm text-foreground focus:outline-none focus:border-white`},null,512),[[ne,Z.value.name]])]),o(`div`,null,[r[8]||=o(`label`,{class:`text-xs font-medium text-foreground-muted uppercase tracking-wide block mb-1.5`},`Expires in`,-1),t(o(`select`,{"onUpdate:modelValue":r[2]||=e=>Z.value.expiresInDays=e,class:`w-full bg-surface-hover border border-border rounded-md px-3 py-2 text-sm text-foreground focus:outline-none focus:border-white`},[...r[7]||=[o(`option`,{value:0},` Never `,-1),o(`option`,{value:1},` 1 day `,-1),o(`option`,{value:7},` 7 days `,-1),o(`option`,{value:30},` 30 days `,-1),o(`option`,{value:90},` 90 days `,-1),o(`option`,{value:365},` 1 year `,-1)]],512),[[_,Z.value.expiresInDays]])])]),o(`div`,A,[c(v,{disabled:!Z.value.name.trim()||X.value,loading:X.value,onClick:Ee},{default:n(()=>[...r[9]||=[d(` Generate Key `,-1)]]),_:1},8,[`disabled`,`loading`]),c(v,{variant:`secondary`,onClick:Te},{default:n(()=>[...r[10]||=[d(` Cancel `,-1)]]),_:1})])])):p(``,!0),o(`div`,j,[o(`ul`,M,[(e(!0),s(f,null,l(K.value,t=>(e(),s(`li`,{key:t.id,class:`px-4 py-3`},[o(`div`,N,[o(`div`,P,[o(`div`,F,[o(`span`,I,a(t.name||`Unnamed`),1),t.prefix?(e(),s(`code`,L,a(t.prefix)+`…`,1)):p(``,!0)]),o(`div`,R,[t.last_used_at?(e(),s(`span`,z,`used `+a(i(x)(t.last_used_at)),1)):(e(),s(`span`,B,`never used`)),t.expires_at?i(b)(t.expires_at)?(e(),s(`span`,H,`expired `+a(i(x)(t.expires_at)),1)):(e(),s(`span`,U,`expires `+a(i(x)(t.expires_at)),1)):(e(),s(`span`,V,`no expiry`))])]),c(y,{icon:i(g),variant:`danger`,title:`Delete key`,onClick:e=>$(t)},null,8,[`icon`,`onClick`])])]))),128)),K.value.length===0?(e(),s(`li`,le,[...r[12]||=[d(` No API keys yet. Tap `,-1),o(`span`,{class:`text-white`},`New Key`,-1),d(` to generate one. `,-1)]])):p(``,!0)]),o(`table`,W,[r[14]||=o(`thead`,{class:`text-xs text-foreground-muted uppercase bg-surface border-b border-border`},[o(`tr`,null,[o(`th`,{scope:`col`,class:`px-6 py-3 font-medium`},` Name `),o(`th`,{scope:`col`,class:`px-6 py-3 font-medium hidden sm:table-cell`},` Prefix `),o(`th`,{scope:`col`,class:`px-6 py-3 font-medium hidden xl:table-cell`},` Created `),o(`th`,{scope:`col`,class:`px-6 py-3 font-medium hidden md:table-cell`},` Last Used `),o(`th`,{scope:`col`,class:`px-6 py-3 font-medium hidden lg:table-cell`},` Expires `),o(`th`,{scope:`col`,class:`px-6 py-3 font-medium text-right`},` Actions `)])],-1),o(`tbody`,ue,[(e(!0),s(f,null,l(K.value,t=>(e(),s(`tr`,{key:t.id,class:`hover:bg-surface/50 transition-colors`},[o(`td`,de,a(t.name||`Unnamed`),1),o(`td`,fe,a(t.prefix?t.prefix+`…`:i(`—`)),1),o(`td`,pe,a(Oe(t.created_at)),1),o(`td`,me,[t.last_used_at?(e(),s(`span`,he,a(i(x)(t.last_used_at)),1)):(e(),s(`span`,ge,`Never used`))]),o(`td`,_e,[t.expires_at?i(b)(t.expires_at)?(e(),s(`span`,ye,`Expired `+a(i(x)(t.expires_at)),1)):(e(),s(`span`,be,a(i(x)(t.expires_at)),1)):(e(),s(`span`,ve,`Never`))]),o(`td`,xe,[c(y,{icon:i(g),variant:`danger`,title:`Delete key`,onClick:e=>$(t)},null,8,[`icon`,`onClick`])])]))),128)),K.value.length===0?(e(),s(`tr`,Se,[...r[13]||=[o(`td`,{colspan:`6`,class:`px-6 py-8 text-center text-foreground-muted`},[d(` No API keys yet. Click `),o(`span`,{class:`text-white`},`New Key`),d(` to generate one. `)],-1)]])):p(``,!0)])])])]))}};export{Ce as default}; \ No newline at end of file diff --git a/backend/internal/server/ui_dist/assets/Channels-ferFGY3i.js b/backend/internal/server/ui_dist/assets/Channels-ferFGY3i.js deleted file mode 100644 index c61f76d5..00000000 --- a/backend/internal/server/ui_dist/assets/Channels-ferFGY3i.js +++ /dev/null @@ -1 +0,0 @@ -import{D as e,F as t,P as n,T as r,W as i,X as a,_t as o,c as s,d as c,h as l,ht as u,k as d,l as f,m as p,r as m,s as h,u as g}from"./runtime-core.esm-bundler-DWJwptQ-.js";import{t as _}from"./check-lEJPUgfZ.js";import{t as v}from"./circle-alert-BNFtIIyP.js";import{t as y}from"./copy-5veW7U_F.js";import{t as b}from"./rotate-ccw-B9grc64w.js";import{t as x}from"./trash-2-BlIjHjqi.js";import{B as S,Ct as C,F as w,Ft as T,It as E,Ot as D,_t as O,f as k,gt as A,s as ee,tt as te,vt as j,xt as M,zt as N}from"./index-B93KhQc5.js";import{t as ne}from"./clipboard-D_9N0yai.js";import{t as P}from"./IconButton-D_Xb_fPi.js";import{n as F,t as I}from"./time-D8OmbYzY.js";var L={class:`w-full max-w-2xl bg-background border border-border rounded-lg shadow-lg flex flex-col max-h-[80vh]`},R={class:`px-5 py-4 border-b border-border flex items-start justify-between gap-3`},z={class:`px-5 py-3 border-b border-border flex items-center gap-2`},B={class:`flex-1 overflow-y-auto`},V={key:0,class:`px-5 py-10 text-center text-xs text-foreground-muted italic`},H={key:1,class:`px-5 py-10 text-center`},U={class:`text-xs text-foreground-muted`},W={key:2,class:`divide-y divide-border`},G=[`onClick`],K=[`checked`,`onClick`],q={class:`flex-1 min-w-0`},J={class:`text-sm font-medium text-white truncate`},Y={key:0,class:`text-xs text-foreground-muted mt-0.5 line-clamp-1`},X={class:`text-[11px] text-foreground-muted font-mono shrink-0`},Z={class:`px-5 py-3 border-t border-border flex items-center justify-between gap-3`},Q={class:`text-xs text-foreground-muted tabular-nums`},re={class:`flex gap-2`},ie={__name:`FunctionPickerModal`,props:{selected:{type:Array,default:()=>[]}},emits:[`close`,`apply`],setup(f,{emit:_}){let v=f,y=_,b=i([]),x=i(!0),C=i(``),w=i(new Set(v.selected)),T=e=>{let t=new Set(w.value);t.has(e)?t.delete(e):t.add(e),w.value=t},D=h(()=>{let e=C.value.trim().toLowerCase();return e?b.value.filter(t=>t.name.toLowerCase().includes(e)||(t.description||``).toLowerCase().includes(e)||(t.runtime||``).toLowerCase().includes(e)):b.value}),k=()=>{y(`apply`,Array.from(w.value))};return r(async()=>{try{let e=await S({limit:200});b.value=e.data.functions||[]}finally{x.value=!1}}),(r,i)=>(e(),c(`div`,{class:`fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/60 backdrop-blur-sm`,onClick:i[3]||=N(e=>r.$emit(`close`),[`self`])},[s(`div`,L,[s(`div`,R,[i[4]||=s(`div`,null,[s(`div`,{class:`text-sm font-semibold text-white`},` Pick functions `),s(`div`,{class:`text-xs text-foreground-muted mt-0.5 max-w-prose leading-relaxed`},[p(` Each selected function becomes one MCP tool in this channel. Names with dashes are converted to snake_case (e.g. `),s(`code`,{class:`text-foreground`},`stripe-charge`),p(` → `),s(`code`,{class:`text-foreground`},`stripe_charge`),p(`). `)])],-1),s(`button`,{class:`text-foreground-muted hover:text-white transition-colors`,title:`Dismiss`,onClick:i[0]||=e=>r.$emit(`close`)},[l(a(j),{class:`w-4 h-4`})])]),s(`div`,z,[l(a(M),{class:`w-4 h-4 text-foreground-muted shrink-0`}),t(s(`input`,{"onUpdate:modelValue":i[1]||=e=>C.value=e,type:`text`,placeholder:`Filter by name, description, or runtime`,class:`flex-1 bg-transparent text-sm text-foreground placeholder-foreground-muted focus:outline-none`},null,512),[[E,C.value]])]),s(`div`,B,[x.value?(e(),c(`div`,V,` Loading functions… `)):D.value.length===0?(e(),c(`div`,H,[l(a(M),{class:`w-8 h-8 text-foreground-muted mx-auto mb-2 opacity-30`}),s(`p`,U,[b.value.length===0?(e(),c(m,{key:0},[p(` No functions deployed yet. `)],64)):(e(),c(m,{key:1},[p(` No functions match "`+o(C.value)+`". `,1)],64))])])):(e(),c(`ul`,W,[(e(!0),c(m,null,d(D.value,t=>(e(),c(`li`,{key:t.id,class:u([`px-5 py-3 flex items-center gap-3 cursor-pointer transition-colors`,w.value.has(t.id)?`bg-surface/30 hover:bg-surface/50`:`hover:bg-surface/40`]),onClick:e=>T(t.id)},[s(`input`,{type:`checkbox`,checked:w.value.has(t.id),class:`accent-primary cursor-pointer`,onClick:N(e=>T(t.id),[`stop`])},null,8,K),s(`div`,q,[s(`div`,J,o(t.name),1),t.description?(e(),c(`div`,Y,o(t.description),1)):g(``,!0)]),s(`code`,X,o(t.runtime),1)],10,G))),128))]))]),s(`div`,Z,[s(`div`,Q,o(w.value.size)+` of `+o(b.value.length)+` selected `,1),s(`div`,re,[l(O,{variant:`secondary`,onClick:i[2]||=e=>r.$emit(`close`)},{default:n(()=>[...i[5]||=[p(` Cancel `,-1)]]),_:1}),l(O,{disabled:w.value.size===0,onClick:k},{default:n(()=>[...i[6]||=[p(` Apply `,-1)]]),_:1},8,[`disabled`])])])])]))}},ae={class:`space-y-6`},oe={class:`flex items-center justify-between gap-4`},se={key:0,class:`bg-background border border-warning-ring rounded-lg p-4 space-y-3`},ce={class:`flex items-start justify-between gap-3`},le={class:`flex items-center gap-2`},ue={class:`flex-1 font-mono text-sm text-white break-all bg-surface px-3 py-2 rounded border border-border`},de={class:`text-[11px] text-foreground-muted flex flex-wrap items-center gap-x-3 gap-y-1`},fe={class:`text-foreground bg-surface px-1.5 py-0.5 rounded`},pe={key:1,class:`bg-background border border-border rounded-lg p-5 space-y-4`},me={class:`grid grid-cols-1 md:grid-cols-2 gap-3`},he={class:`flex items-center justify-between mb-1.5`},ge={key:0,class:`text-[11px] text-foreground-muted`},_e={key:0,class:`rounded-md border border-red-700/40 bg-red-950/30 p-3 text-xs text-red-200 flex items-start gap-2`},ve={class:`flex gap-2 pt-1`},ye={class:`bg-background border border-border rounded-lg overflow-x-auto`},be={class:`sm:hidden divide-y divide-border`},xe={class:`flex items-start justify-between gap-2`},Se={class:`min-w-0 flex-1`},Ce={class:`flex items-center gap-2 flex-wrap`},we={class:`font-medium text-white truncate`},Te={class:`inline-flex items-center gap-1 text-[11px] text-foreground-muted`},Ee={key:0,class:`mt-1 text-xs text-foreground-muted line-clamp-2`},De={class:`mt-1 flex flex-wrap items-center gap-x-3 gap-y-0.5 text-[11px] text-foreground-muted`},Oe={class:`font-mono`},ke={key:0},Ae={key:1,class:`text-amber-400/80`},je={key:2,class:`text-red-400`},Me={key:3},Ne={class:`flex items-center gap-1 shrink-0`},Pe={key:0,class:`px-6 py-8 text-center text-sm text-foreground-muted`},Fe={class:`hidden sm:table w-full text-sm text-left`},Ie={class:`divide-y divide-border`},Le={class:`px-6 py-4`},Re={class:`font-medium text-white`},ze={key:0,class:`text-xs text-foreground-muted mt-0.5 line-clamp-1 max-w-md`},Be={class:`px-6 py-4`},Ve={class:`inline-flex items-center gap-1.5 text-foreground-muted`},$={class:`tabular-nums`},He={class:`px-6 py-4 hidden sm:table-cell`},Ue={class:`text-foreground-muted font-mono text-xs`},We={class:`px-6 py-4 hidden md:table-cell`},Ge={key:0,class:`text-foreground-muted`},Ke={key:1,class:`text-amber-400/70 text-xs`},qe={class:`px-6 py-4 hidden lg:table-cell`},Je={key:0,class:`text-foreground-muted`},Ye={key:1,class:`text-red-400 text-xs`},Xe={key:2,class:`text-foreground-muted`},Ze={class:`px-6 py-4 text-right`},Qe={class:`inline-flex justify-end gap-1`},$e={key:0},et=Object.assign({name:`ChannelsView`},{__name:`Channels`,setup(u){let S=A(),M=i([]),N=i(``),L=i(!1),R=i(!1),z=i(!1),B=i(``),V=i(!1),H=i({name:``,description:``,expiresInDays:0,functionIds:[]}),U=h(()=>`${window.location.origin}/mcp`),W=h(()=>H.value.name.trim()&&H.value.functionIds.length>0),G=async()=>{let e=await w();M.value=e.data.channels||[]},K=()=>{H.value={name:``,description:``,expiresInDays:0,functionIds:[]},B.value=``,R.value=!0},q=()=>{R.value=!1},J=e=>{H.value.functionIds=e,V.value=!1},Y=async()=>{z.value=!0,B.value=``;try{let e={name:H.value.name.trim(),description:H.value.description.trim(),function_ids:H.value.functionIds};H.value.expiresInDays>0&&(e.expires_in_days=H.value.expiresInDays);let t=await ee(e);N.value=t.data.token,R.value=!1,await G()}catch(e){B.value=e?.response?.data?.error?.message||`Failed to create channel.`}finally{z.value=!1}},X=async()=>{N.value&&await ne(N.value)&&(L.value=!0,setTimeout(()=>{L.value=!1},1500))},Z=async e=>{if(!await S.ask({title:`Rotate ${e.name}?`,message:`A new token will be issued. The previous token stops working immediately. Agents using it will need the new value.`,confirmLabel:`Rotate`,danger:!0}))return;let t=await te(e.id);N.value=t.data.token,await G()},Q=async e=>{await S.ask({title:`Delete ${e.name}?`,message:`${e.name} will lose MCP access immediately. Functions inside are not affected. Re-create the channel if you need it again.`,confirmLabel:`Delete`,danger:!0})&&(await k(e.id),await G())};return r(G),(r,i)=>(e(),c(`div`,ae,[s(`div`,oe,[i[7]||=s(`div`,null,[s(`h1`,{class:`text-xl font-semibold text-white tracking-tight`},` Channels `),s(`p`,{class:`text-sm text-foreground-muted mt-1.5 max-w-prose leading-body`},` Bundle deployed functions and expose them as MCP tools to a third-party agent. Each channel has its own bearer token that grants invoke-only access to its functions and nothing else on Orva, but the bundled functions themselves remain as powerful as you've configured them, including any in-sandbox SDK calls they make. `)],-1),l(O,{onClick:K},{default:n(()=>[l(a(C),{class:`w-4 h-4`}),i[6]||=p(` New channel `,-1)]),_:1})]),N.value?(e(),c(`div`,se,[s(`div`,ce,[i[8]||=s(`div`,null,[s(`h2`,{class:`text-xs font-bold text-warning-fg uppercase tracking-wider`},` Copy this token now `),s(`div`,{class:`text-xs text-foreground-muted mt-0.5`},` It will not be shown again. Configure it in your agent's MCP client. `)],-1),s(`button`,{class:`text-foreground-muted hover:text-white transition-colors`,title:`Dismiss`,onClick:i[0]||=e=>N.value=``},[l(a(j),{class:`w-4 h-4`})])]),s(`div`,le,[s(`code`,ue,o(N.value),1),s(`button`,{class:`px-3 py-2 rounded-md border border-border bg-surface-hover hover:bg-surface text-foreground-muted hover:text-white transition-colors flex items-center gap-1.5 text-xs`,onClick:X},[L.value?(e(),f(a(_),{key:0,class:`w-3.5 h-3.5 text-success`})):(e(),f(a(y),{key:1,class:`w-3.5 h-3.5`})),p(` `+o(L.value?`Copied`:`Copy`),1)])]),s(`div`,de,[s(`span`,null,[i[9]||=p(`URL `,-1),s(`code`,fe,o(U.value),1)]),i[10]||=s(`span`,null,[p(`Header `),s(`code`,{class:`text-foreground bg-surface px-1.5 py-0.5 rounded`},`Authorization: Bearer `)],-1)])])):g(``,!0),R.value?(e(),c(`div`,pe,[i[18]||=s(`div`,{class:`text-sm font-semibold text-white`},` New channel `,-1),s(`div`,me,[s(`div`,null,[i[11]||=s(`label`,{class:`text-xs font-medium text-foreground-muted uppercase tracking-wide block mb-1.5`},`Name`,-1),t(s(`input`,{"onUpdate:modelValue":i[1]||=e=>H.value.name=e,placeholder:`e.g. support-bot`,class:`w-full bg-surface-hover border border-border rounded-md px-3 py-2 text-sm text-foreground focus:outline-none focus:ring-1 focus:ring-primary transition-colors`},null,512),[[E,H.value.name]])]),s(`div`,null,[i[13]||=s(`label`,{class:`text-xs font-medium text-foreground-muted uppercase tracking-wide block mb-1.5`},`Expires in`,-1),t(s(`select`,{"onUpdate:modelValue":i[2]||=e=>H.value.expiresInDays=e,class:`w-full bg-surface-hover border border-border rounded-md px-3 py-2 text-sm text-foreground focus:outline-none focus:ring-1 focus:ring-primary transition-colors`},[...i[12]||=[s(`option`,{value:0},` Never `,-1),s(`option`,{value:7},` 7 days `,-1),s(`option`,{value:30},` 30 days `,-1),s(`option`,{value:90},` 90 days `,-1)]],512),[[T,H.value.expiresInDays]])])]),s(`div`,null,[i[14]||=s(`label`,{class:`text-xs font-medium text-foreground-muted uppercase tracking-wide block mb-1.5`},`Description (optional)`,-1),t(s(`input`,{"onUpdate:modelValue":i[3]||=e=>H.value.description=e,placeholder:`What this channel is for`,class:`w-full bg-surface-hover border border-border rounded-md px-3 py-2 text-sm text-foreground focus:outline-none focus:ring-1 focus:ring-primary transition-colors`},null,512),[[E,H.value.description]])]),s(`div`,null,[s(`div`,he,[i[15]||=s(`label`,{class:`text-xs font-medium text-foreground-muted uppercase tracking-wide`},`Functions`,-1),H.value.functionIds.length>0?(e(),c(`span`,ge,o(H.value.functionIds.length)+` selected`,1)):g(``,!0)]),l(O,{variant:`secondary`,onClick:i[4]||=e=>V.value=!0},{default:n(()=>[l(a(D),{class:`w-4 h-4`}),p(` `+o(H.value.functionIds.length===0?`Pick functions`:`Edit selection`),1)]),_:1})]),B.value?(e(),c(`div`,_e,[l(a(v),{class:`w-4 h-4 text-red-400 shrink-0 mt-0.5`}),s(`span`,null,o(B.value),1)])):g(``,!0),s(`div`,ve,[l(O,{disabled:!W.value||z.value,loading:z.value,onClick:Y},{default:n(()=>[...i[16]||=[p(` Generate token `,-1)]]),_:1},8,[`disabled`,`loading`]),l(O,{variant:`secondary`,onClick:q},{default:n(()=>[...i[17]||=[p(` Cancel `,-1)]]),_:1})])])):g(``,!0),s(`div`,ye,[s(`ul`,be,[(e(!0),c(m,null,d(M.value,t=>(e(),c(`li`,{key:t.id,class:`px-4 py-3`},[s(`div`,xe,[s(`div`,Se,[s(`div`,Ce,[s(`span`,we,o(t.name),1),s(`span`,Te,[l(a(D),{class:`w-3 h-3`}),p(` `+o(t.function_count),1)])]),t.description?(e(),c(`div`,Ee,o(t.description),1)):g(``,!0),s(`div`,De,[s(`code`,Oe,o(t.prefix)+`…`,1),t.last_used_at?(e(),c(`span`,ke,`used `+o(a(I)(t.last_used_at)),1)):(e(),c(`span`,Ae,`never used`)),t.expires_at&&a(F)(t.expires_at)?(e(),c(`span`,je,`expired`)):t.expires_at?(e(),c(`span`,Me,`expires `+o(a(I)(t.expires_at)),1)):g(``,!0)])]),s(`div`,Ne,[l(P,{icon:a(b),title:`Rotate token`,onClick:e=>Z(t)},null,8,[`icon`,`onClick`]),l(P,{icon:a(x),variant:`danger`,title:`Delete channel`,onClick:e=>Q(t)},null,8,[`icon`,`onClick`])])])]))),128)),M.value.length===0?(e(),c(`li`,Pe,` No channels yet. `)):g(``,!0)]),s(`table`,Fe,[i[20]||=s(`thead`,{class:`text-xs text-foreground-muted uppercase bg-surface border-b border-border`},[s(`tr`,null,[s(`th`,{class:`px-6 py-3 font-medium`},` Name `),s(`th`,{class:`px-6 py-3 font-medium`},` Functions `),s(`th`,{class:`px-6 py-3 font-medium hidden sm:table-cell`},` Prefix `),s(`th`,{class:`px-6 py-3 font-medium hidden md:table-cell`},` Last used `),s(`th`,{class:`px-6 py-3 font-medium hidden lg:table-cell`},` Expires `),s(`th`,{class:`px-6 py-3 font-medium text-right`},` Actions `)])],-1),s(`tbody`,Ie,[(e(!0),c(m,null,d(M.value,t=>(e(),c(`tr`,{key:t.id,class:`hover:bg-surface/50 transition-colors`},[s(`td`,Le,[s(`div`,Re,o(t.name),1),t.description?(e(),c(`div`,ze,o(t.description),1)):g(``,!0)]),s(`td`,Be,[s(`span`,Ve,[l(a(D),{class:`w-3.5 h-3.5`}),s(`span`,$,o(t.function_count),1)])]),s(`td`,He,[s(`code`,Ue,o(t.prefix)+`…`,1)]),s(`td`,We,[t.last_used_at?(e(),c(`span`,Ge,o(a(I)(t.last_used_at)),1)):(e(),c(`span`,Ke,`Never used`))]),s(`td`,qe,[t.expires_at?a(F)(t.expires_at)?(e(),c(`span`,Ye,`Expired `+o(a(I)(t.expires_at)),1)):(e(),c(`span`,Xe,o(a(I)(t.expires_at)),1)):(e(),c(`span`,Je,`Never`))]),s(`td`,Ze,[s(`div`,Qe,[l(P,{icon:a(b),title:`Rotate token`,onClick:e=>Z(t)},null,8,[`icon`,`onClick`]),l(P,{icon:a(x),variant:`danger`,title:`Delete channel`,onClick:e=>Q(t)},null,8,[`icon`,`onClick`])])])]))),128)),M.value.length===0?(e(),c(`tr`,$e,[...i[19]||=[s(`td`,{colspan:`6`,class:`px-6 py-8 text-center text-foreground-muted`},[p(` No channels yet. Click `),s(`span`,{class:`text-white`},`New channel`),p(` to bundle functions for an agent. `)],-1)]])):g(``,!0)])])]),V.value?(e(),f(ie,{key:2,selected:H.value.functionIds,onClose:i[5]||=e=>V.value=!1,onApply:J},null,8,[`selected`])):g(``,!0)]))}});export{et as default}; \ No newline at end of file diff --git a/backend/internal/server/ui_dist/assets/Channels-t_NzfnaS.js b/backend/internal/server/ui_dist/assets/Channels-t_NzfnaS.js new file mode 100644 index 00000000..11f0c0e1 --- /dev/null +++ b/backend/internal/server/ui_dist/assets/Channels-t_NzfnaS.js @@ -0,0 +1 @@ +import{D as e,F as t,G as n,I as r,T as i,Z as a,c as o,d as s,gt as c,h as l,k as u,l as d,m as f,r as p,s as m,u as h,vt as g}from"./runtime-core.esm-bundler-BMQPyJ_W.js";import{t as _}from"./check-ho22bAKW.js";import{t as v}from"./circle-alert-Buaacgot.js";import{t as y}from"./copy-DHTw5vil.js";import{t as b}from"./rotate-ccw-DWDBjUXf.js";import{t as x}from"./trash-2-DDX094Y-.js";import{B as S,Bt as C,Ct as w,F as T,It as E,Lt as D,_t as O,f as k,gt as A,kt as j,s as ee,tt as te,vt as M,xt as N}from"./index-CZI-jurg.js";import{t as ne}from"./clipboard-D_9N0yai.js";import{t as P}from"./IconButton-CsCZOqWo.js";import{n as F,t as I}from"./time-D8OmbYzY.js";var L={class:`w-full max-w-2xl bg-background border border-border rounded-lg shadow-lg flex flex-col max-h-[80vh]`},R={class:`px-5 py-4 border-b border-border flex items-start justify-between gap-3`},z={class:`px-5 py-3 border-b border-border flex items-center gap-2`},B={class:`flex-1 overflow-y-auto`},V={key:0,class:`px-5 py-10 text-center text-xs text-foreground-muted italic`},H={key:1,class:`px-5 py-10 text-center`},U={class:`text-xs text-foreground-muted`},W={key:2,class:`divide-y divide-border`},G=[`onClick`],K=[`checked`,`onClick`],q={class:`flex-1 min-w-0`},J={class:`text-sm font-medium text-white truncate`},Y={key:0,class:`text-xs text-foreground-muted mt-0.5 line-clamp-1`},X={class:`text-[11px] text-foreground-muted font-mono shrink-0`},Z={class:`px-5 py-3 border-t border-border flex items-center justify-between gap-3`},Q={class:`text-xs text-foreground-muted tabular-nums`},re={class:`flex gap-2`},ie={__name:`FunctionPickerModal`,props:{selected:{type:Array,default:()=>[]}},emits:[`close`,`apply`],setup(d,{emit:_}){let v=d,y=_,b=n([]),x=n(!0),w=n(``),T=n(new Set(v.selected)),E=e=>{let t=new Set(T.value);t.has(e)?t.delete(e):t.add(e),T.value=t},k=m(()=>{let e=w.value.trim().toLowerCase();return e?b.value.filter(t=>t.name.toLowerCase().includes(e)||(t.description||``).toLowerCase().includes(e)||(t.runtime||``).toLowerCase().includes(e)):b.value}),A=()=>{y(`apply`,Array.from(T.value))};return i(async()=>{try{let e=await S({limit:200});b.value=e.data.functions||[]}finally{x.value=!1}}),(n,i)=>(e(),s(`div`,{class:`fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/60 backdrop-blur-sm`,onClick:i[3]||=C(e=>n.$emit(`close`),[`self`])},[o(`div`,L,[o(`div`,R,[i[4]||=o(`div`,null,[o(`div`,{class:`text-sm font-semibold text-white`},` Pick functions `),o(`div`,{class:`text-xs text-foreground-muted mt-0.5 max-w-prose leading-relaxed`},` Each selection becomes an MCP tool. Dashes become underscores. `)],-1),o(`button`,{class:`text-foreground-muted hover:text-white transition-colors`,title:`Dismiss`,"aria-label":`Close function picker`,onClick:i[0]||=e=>n.$emit(`close`)},[l(a(M),{class:`w-4 h-4`})])]),o(`div`,z,[l(a(N),{class:`w-4 h-4 text-foreground-muted shrink-0`}),r(o(`input`,{"onUpdate:modelValue":i[1]||=e=>w.value=e,"aria-label":`Search functions`,type:`text`,placeholder:`Filter by name, description, or runtime`,class:`flex-1 bg-transparent text-sm text-foreground placeholder-foreground-muted focus:outline-none`},null,512),[[D,w.value]])]),o(`div`,B,[x.value?(e(),s(`div`,V,` Loading functions… `)):k.value.length===0?(e(),s(`div`,H,[l(a(N),{class:`w-8 h-8 text-foreground-muted mx-auto mb-2 opacity-30`}),o(`p`,U,[b.value.length===0?(e(),s(p,{key:0},[f(` No functions deployed yet. `)],64)):(e(),s(p,{key:1},[f(` No functions match "`+g(w.value)+`". `,1)],64))])])):(e(),s(`ul`,W,[(e(!0),s(p,null,u(k.value,t=>(e(),s(`li`,{key:t.id,class:c([`px-5 py-3 flex items-center gap-3 cursor-pointer transition-colors`,T.value.has(t.id)?`bg-surface/30 hover:bg-surface/50`:`hover:bg-surface/40`]),onClick:e=>E(t.id)},[o(`input`,{type:`checkbox`,checked:T.value.has(t.id),class:`accent-primary cursor-pointer`,onClick:C(e=>E(t.id),[`stop`])},null,8,K),o(`div`,q,[o(`div`,J,g(t.name),1),t.description?(e(),s(`div`,Y,g(t.description),1)):h(``,!0)]),o(`code`,X,g(t.runtime),1)],10,G))),128))]))]),o(`div`,Z,[o(`div`,Q,g(T.value.size)+` of `+g(b.value.length)+` selected `,1),o(`div`,re,[l(O,{variant:`secondary`,onClick:i[2]||=e=>n.$emit(`close`)},{default:t(()=>[...i[5]||=[f(` Cancel `,-1)]]),_:1}),l(O,{disabled:T.value.size===0,onClick:A},{default:t(()=>[...i[6]||=[f(` Apply `,-1)]]),_:1},8,[`disabled`])])])])]))}},ae={class:`space-y-6`},oe={class:`flex items-center justify-between gap-4`},se={key:0,class:`bg-background border border-warning-ring rounded-lg p-4 space-y-3`},ce={class:`flex items-start justify-between gap-3`},le={class:`flex items-center gap-2`},ue={class:`flex-1 font-mono text-sm text-white break-all bg-surface px-3 py-2 rounded border border-border`},de={class:`text-xs text-foreground-muted flex flex-wrap items-center gap-x-3 gap-y-1`},fe={class:`text-foreground bg-surface px-1.5 py-0.5 rounded`},pe={key:1,class:`bg-background border border-border rounded-lg p-5 space-y-4`},me={class:`grid grid-cols-1 md:grid-cols-2 gap-3`},he={class:`flex items-center justify-between mb-1.5`},ge={key:0,class:`text-[11px] text-foreground-muted`},_e={key:0,class:`rounded-md border border-red-700/40 bg-red-950/30 p-3 text-xs text-red-200 flex items-start gap-2`},ve={class:`flex gap-2 pt-1`},ye={class:`bg-background border border-border rounded-lg overflow-x-auto`},be={class:`sm:hidden divide-y divide-border`},xe={class:`flex items-start justify-between gap-2`},Se={class:`min-w-0 flex-1`},Ce={class:`flex items-center gap-2 flex-wrap`},we={class:`font-medium text-white truncate`},Te={class:`inline-flex items-center gap-1 text-[11px] text-foreground-muted`},Ee={key:0,class:`mt-1 text-xs text-foreground-muted line-clamp-2`},De={class:`mt-1 flex flex-wrap items-center gap-x-3 gap-y-0.5 text-[11px] text-foreground-muted`},Oe={class:`font-mono`},ke={key:0},Ae={key:1,class:`text-amber-400/80`},je={key:2,class:`text-red-400`},Me={key:3},Ne={class:`flex items-center gap-1 shrink-0`},Pe={key:0,class:`px-6 py-8 text-center text-sm text-foreground-muted`},Fe={class:`hidden sm:table w-full text-sm text-left`},Ie={class:`divide-y divide-border`},Le={class:`px-6 py-4`},Re={class:`font-medium text-white`},ze={key:0,class:`text-xs text-foreground-muted mt-0.5 line-clamp-1 max-w-md`},Be={class:`px-6 py-4`},Ve={class:`inline-flex items-center gap-1.5 text-foreground-muted`},$={class:`tabular-nums`},He={class:`px-6 py-4 hidden sm:table-cell`},Ue={class:`text-foreground-muted font-mono text-xs`},We={class:`px-6 py-4 hidden md:table-cell`},Ge={key:0,class:`text-foreground-muted`},Ke={key:1,class:`text-amber-400/70 text-xs`},qe={class:`px-6 py-4 hidden lg:table-cell`},Je={key:0,class:`text-foreground-muted`},Ye={key:1,class:`text-red-400 text-xs`},Xe={key:2,class:`text-foreground-muted`},Ze={class:`px-6 py-4 text-right`},Qe={class:`inline-flex justify-end gap-1`},$e={key:0},et=Object.assign({name:`ChannelsView`},{__name:`Channels`,setup(c){let S=A(),C=n([]),N=n(``),L=n(!1),R=n(!1),z=n(!1),B=n(``),V=n(!1),H=n({name:``,description:``,expiresInDays:0,functionIds:[]}),U=m(()=>`${window.location.origin}/mcp`),W=m(()=>H.value.name.trim()&&H.value.functionIds.length>0),G=async()=>{let e=await T();C.value=e.data.channels||[]},K=()=>{H.value={name:``,description:``,expiresInDays:0,functionIds:[]},B.value=``,R.value=!0},q=()=>{R.value=!1},J=e=>{H.value.functionIds=e,V.value=!1},Y=async()=>{z.value=!0,B.value=``;try{let e={name:H.value.name.trim(),description:H.value.description.trim(),function_ids:H.value.functionIds};H.value.expiresInDays>0&&(e.expires_in_days=H.value.expiresInDays);let t=await ee(e);N.value=t.data.token,R.value=!1,await G()}catch(e){B.value=e?.response?.data?.error?.message||`Failed to create channel.`}finally{z.value=!1}},X=async()=>{N.value&&await ne(N.value)&&(L.value=!0,setTimeout(()=>{L.value=!1},1500))},Z=async e=>{if(!await S.ask({title:`Rotate ${e.name}?`,message:`A new token will be issued. The previous token stops working immediately. Agents using it will need the new value.`,confirmLabel:`Rotate`,danger:!0}))return;let t=await te(e.id);N.value=t.data.token,await G()},Q=async e=>{await S.ask({title:`Delete ${e.name}?`,message:`${e.name} will lose MCP access immediately. Functions inside are not affected. Re-create the channel if you need it again.`,confirmLabel:`Delete`,danger:!0})&&(await k(e.id),await G())};return i(G),(n,i)=>(e(),s(`div`,ae,[o(`div`,oe,[i[7]||=o(`div`,null,[o(`h1`,{class:`text-xl font-semibold text-white tracking-tight`},` Channels `),o(`p`,{class:`text-sm text-foreground-muted mt-1.5 max-w-prose leading-body`},` Expose selected functions as scoped MCP tools. `)],-1),l(O,{onClick:K},{default:t(()=>[l(a(w),{class:`w-4 h-4`}),i[6]||=f(` New channel `,-1)]),_:1})]),N.value?(e(),s(`div`,se,[o(`div`,ce,[i[8]||=o(`div`,null,[o(`h2`,{class:`text-xs font-bold text-warning-fg uppercase tracking-wider`},` Copy this token now `),o(`div`,{class:`text-xs text-foreground-muted mt-0.5`},` Store it securely, then add it to your MCP client. `)],-1),o(`button`,{class:`text-foreground-muted hover:text-white transition-colors`,title:`Dismiss`,"aria-label":`Dismiss channel token`,onClick:i[0]||=e=>N.value=``},[l(a(M),{class:`w-4 h-4`})])]),o(`div`,le,[o(`code`,ue,g(N.value),1),o(`button`,{class:`px-3 py-2 rounded-md border border-border bg-surface-hover hover:bg-surface text-foreground-muted hover:text-white transition-colors flex items-center gap-1.5 text-xs`,onClick:X},[L.value?(e(),d(a(_),{key:0,class:`w-3.5 h-3.5 text-success`})):(e(),d(a(y),{key:1,class:`w-3.5 h-3.5`})),f(` `+g(L.value?`Copied`:`Copy`),1)])]),o(`div`,de,[o(`span`,null,[i[9]||=f(`URL `,-1),o(`code`,fe,g(U.value),1)]),i[10]||=o(`span`,null,[f(`Header `),o(`code`,{class:`text-foreground bg-surface px-1.5 py-0.5 rounded`},`Authorization: Bearer `)],-1)])])):h(``,!0),R.value?(e(),s(`div`,pe,[i[18]||=o(`div`,{class:`text-sm font-semibold text-white`},` New channel `,-1),o(`div`,me,[o(`div`,null,[i[11]||=o(`label`,{for:`channel-name`,class:`text-xs font-medium text-foreground-muted uppercase tracking-wide block mb-1.5`},`Name`,-1),r(o(`input`,{id:`channel-name`,"onUpdate:modelValue":i[1]||=e=>H.value.name=e,placeholder:`e.g. support-bot`,class:`w-full bg-surface-hover border border-border rounded-md px-3 py-2 text-sm text-foreground focus:outline-none focus:ring-1 focus:ring-primary transition-colors`},null,512),[[D,H.value.name]])]),o(`div`,null,[i[13]||=o(`label`,{for:`channel-expiry`,class:`text-xs font-medium text-foreground-muted uppercase tracking-wide block mb-1.5`},`Expires in`,-1),r(o(`select`,{id:`channel-expiry`,"onUpdate:modelValue":i[2]||=e=>H.value.expiresInDays=e,class:`w-full bg-surface-hover border border-border rounded-md px-3 py-2 text-sm text-foreground focus:outline-none focus:ring-1 focus:ring-primary transition-colors`},[...i[12]||=[o(`option`,{value:0},` Never `,-1),o(`option`,{value:7},` 7 days `,-1),o(`option`,{value:30},` 30 days `,-1),o(`option`,{value:90},` 90 days `,-1)]],512),[[E,H.value.expiresInDays]])])]),o(`div`,null,[i[14]||=o(`label`,{class:`text-xs font-medium text-foreground-muted uppercase tracking-wide block mb-1.5`},`Description (optional)`,-1),r(o(`input`,{"onUpdate:modelValue":i[3]||=e=>H.value.description=e,placeholder:`What this channel is for`,class:`w-full bg-surface-hover border border-border rounded-md px-3 py-2 text-sm text-foreground focus:outline-none focus:ring-1 focus:ring-primary transition-colors`},null,512),[[D,H.value.description]])]),o(`div`,null,[o(`div`,he,[i[15]||=o(`label`,{class:`text-xs font-medium text-foreground-muted uppercase tracking-wide`},`Functions`,-1),H.value.functionIds.length>0?(e(),s(`span`,ge,g(H.value.functionIds.length)+` selected`,1)):h(``,!0)]),l(O,{variant:`secondary`,onClick:i[4]||=e=>V.value=!0},{default:t(()=>[l(a(j),{class:`w-4 h-4`}),f(` `+g(H.value.functionIds.length===0?`Pick functions`:`Edit selection`),1)]),_:1})]),B.value?(e(),s(`div`,_e,[l(a(v),{class:`w-4 h-4 text-red-400 shrink-0 mt-0.5`}),o(`span`,null,g(B.value),1)])):h(``,!0),o(`div`,ve,[l(O,{disabled:!W.value||z.value,loading:z.value,onClick:Y},{default:t(()=>[...i[16]||=[f(` Generate token `,-1)]]),_:1},8,[`disabled`,`loading`]),l(O,{variant:`secondary`,onClick:q},{default:t(()=>[...i[17]||=[f(` Cancel `,-1)]]),_:1})])])):h(``,!0),o(`div`,ye,[o(`ul`,be,[(e(!0),s(p,null,u(C.value,t=>(e(),s(`li`,{key:t.id,class:`px-4 py-3`},[o(`div`,xe,[o(`div`,Se,[o(`div`,Ce,[o(`span`,we,g(t.name),1),o(`span`,Te,[l(a(j),{class:`w-3 h-3`}),f(` `+g(t.function_count),1)])]),t.description?(e(),s(`div`,Ee,g(t.description),1)):h(``,!0),o(`div`,De,[o(`code`,Oe,g(t.prefix)+`…`,1),t.last_used_at?(e(),s(`span`,ke,`used `+g(a(I)(t.last_used_at)),1)):(e(),s(`span`,Ae,`never used`)),t.expires_at&&a(F)(t.expires_at)?(e(),s(`span`,je,`expired`)):t.expires_at?(e(),s(`span`,Me,`expires `+g(a(I)(t.expires_at)),1)):h(``,!0)])]),o(`div`,Ne,[l(P,{icon:a(b),title:`Rotate token`,onClick:e=>Z(t)},null,8,[`icon`,`onClick`]),l(P,{icon:a(x),variant:`danger`,title:`Delete channel`,onClick:e=>Q(t)},null,8,[`icon`,`onClick`])])])]))),128)),C.value.length===0?(e(),s(`li`,Pe,` No channels yet. `)):h(``,!0)]),o(`table`,Fe,[i[20]||=o(`thead`,{class:`text-xs text-foreground-muted uppercase bg-surface border-b border-border`},[o(`tr`,null,[o(`th`,{class:`px-6 py-3 font-medium`},` Name `),o(`th`,{class:`px-6 py-3 font-medium`},` Functions `),o(`th`,{class:`px-6 py-3 font-medium hidden sm:table-cell`},` Prefix `),o(`th`,{class:`px-6 py-3 font-medium hidden md:table-cell`},` Last used `),o(`th`,{class:`px-6 py-3 font-medium hidden lg:table-cell`},` Expires `),o(`th`,{class:`px-6 py-3 font-medium text-right`},` Actions `)])],-1),o(`tbody`,Ie,[(e(!0),s(p,null,u(C.value,t=>(e(),s(`tr`,{key:t.id,class:`hover:bg-surface/50 transition-colors`},[o(`td`,Le,[o(`div`,Re,g(t.name),1),t.description?(e(),s(`div`,ze,g(t.description),1)):h(``,!0)]),o(`td`,Be,[o(`span`,Ve,[l(a(j),{class:`w-3.5 h-3.5`}),o(`span`,$,g(t.function_count),1)])]),o(`td`,He,[o(`code`,Ue,g(t.prefix)+`…`,1)]),o(`td`,We,[t.last_used_at?(e(),s(`span`,Ge,g(a(I)(t.last_used_at)),1)):(e(),s(`span`,Ke,`Never used`))]),o(`td`,qe,[t.expires_at?a(F)(t.expires_at)?(e(),s(`span`,Ye,`Expired `+g(a(I)(t.expires_at)),1)):(e(),s(`span`,Xe,g(a(I)(t.expires_at)),1)):(e(),s(`span`,Je,`Never`))]),o(`td`,Ze,[o(`div`,Qe,[l(P,{icon:a(b),title:`Rotate token`,onClick:e=>Z(t)},null,8,[`icon`,`onClick`]),l(P,{icon:a(x),variant:`danger`,title:`Delete channel`,onClick:e=>Q(t)},null,8,[`icon`,`onClick`])])])]))),128)),C.value.length===0?(e(),s(`tr`,$e,[...i[19]||=[o(`td`,{colspan:`6`,class:`px-6 py-8 text-center text-foreground-muted`},[f(` No channels yet. Click `),o(`span`,{class:`text-white`},`New channel`),f(` to bundle functions for an agent. `)],-1)]])):h(``,!0)])])]),V.value?(e(),d(ie,{key:2,selected:H.value.functionIds,onClose:i[5]||=e=>V.value=!1,onApply:J},null,8,[`selected`])):h(``,!0)]))}});export{et as default}; \ No newline at end of file diff --git a/backend/internal/server/ui_dist/assets/CodeEditor-CN_QDpaG.js b/backend/internal/server/ui_dist/assets/CodeEditor-809P47Oq.js similarity index 66% rename from backend/internal/server/ui_dist/assets/CodeEditor-CN_QDpaG.js rename to backend/internal/server/ui_dist/assets/CodeEditor-809P47Oq.js index a447d987..945653c3 100644 --- a/backend/internal/server/ui_dist/assets/CodeEditor-CN_QDpaG.js +++ b/backend/internal/server/ui_dist/assets/CodeEditor-809P47Oq.js @@ -1 +1 @@ -import{D as e,E as t,N as n,T as r,W as i,d as a}from"./runtime-core.esm-bundler-DWJwptQ-.js";import{ut as o}from"./index-B93KhQc5.js";import{E as s,T as c,a as l,n as u,r as d,t as f,v as p}from"./dist-CR15Grce.js";var m=o({__name:`CodeEditor`,props:{modelValue:{type:String,default:``},language:{type:String,default:`javascript`},readOnly:{type:Boolean,default:!1}},emits:[`update:modelValue`],setup(o,{emit:m}){let h=o,g=m,_=i(null),v=null,y=new c,b=e=>e?.startsWith(`python`)?u():(e?.startsWith(`node`),d());return r(()=>{let e=s.create({doc:h.modelValue,extensions:[l,y.of(b(h.language)),f,p.updateListener.of(e=>{e.docChanged&&g(`update:modelValue`,e.state.doc.toString())}),p.theme({"&":{fontSize:`16px`,height:`100%`},"@media (min-width: 640px)":{"&":{fontSize:`14px`}},".cm-scroller":{fontFamily:`JetBrains Mono, monospace`,lineHeight:`1.6`},".cm-content":{padding:`16px 0`},".cm-line":{padding:`0 16px`}}),s.readOnly.of(h.readOnly)]});v=new p({state:e,parent:_.value})}),t(()=>{v&&v.destroy()}),n(()=>h.modelValue,e=>{v&&e!==v.state.doc.toString()&&v.dispatch({changes:{from:0,to:v.state.doc.length,insert:e}})}),n(()=>h.language,e=>{v&&v.dispatch({effects:y.reconfigure(b(e))})}),(t,n)=>(e(),a(`div`,{ref_key:`editorRef`,ref:_,class:`h-full w-full`},null,512))}},[[`__scopeId`,`data-v-ccca551c`]]);export{m as default}; \ No newline at end of file +import{D as e,E as t,G as n,P as r,T as i,d as a}from"./runtime-core.esm-bundler-BMQPyJ_W.js";import{ut as o}from"./index-CZI-jurg.js";import{E as s,T as c,a as l,n as u,r as d,t as f,v as p}from"./dist-CR15Grce.js";var m=o({__name:`CodeEditor`,props:{modelValue:{type:String,default:``},language:{type:String,default:`javascript`},readOnly:{type:Boolean,default:!1}},emits:[`update:modelValue`],setup(o,{emit:m}){let h=o,g=m,_=n(null),v=null,y=new c,b=e=>e?.startsWith(`python`)?u():(e?.startsWith(`node`),d());return i(()=>{let e=s.create({doc:h.modelValue,extensions:[l,y.of(b(h.language)),f,p.updateListener.of(e=>{e.docChanged&&g(`update:modelValue`,e.state.doc.toString())}),p.theme({"&":{fontSize:`16px`,height:`100%`},"@media (min-width: 640px)":{"&":{fontSize:`14px`}},".cm-scroller":{fontFamily:`JetBrains Mono, monospace`,lineHeight:`1.6`},".cm-content":{padding:`16px 0`},".cm-line":{padding:`0 16px`}}),s.readOnly.of(h.readOnly)]});v=new p({state:e,parent:_.value})}),t(()=>{v&&v.destroy()}),r(()=>h.modelValue,e=>{v&&e!==v.state.doc.toString()&&v.dispatch({changes:{from:0,to:v.state.doc.length,insert:e}})}),r(()=>h.language,e=>{v&&v.dispatch({effects:y.reconfigure(b(e))})}),(t,n)=>(e(),a(`div`,{ref_key:`editorRef`,ref:_,class:`h-full w-full`},null,512))}},[[`__scopeId`,`data-v-ccca551c`]]);export{m as default}; \ No newline at end of file diff --git a/backend/internal/server/ui_dist/assets/CronJobs-BnI-WDdi.js b/backend/internal/server/ui_dist/assets/CronJobs-BnI-WDdi.js deleted file mode 100644 index 438612cf..00000000 --- a/backend/internal/server/ui_dist/assets/CronJobs-BnI-WDdi.js +++ /dev/null @@ -1 +0,0 @@ -import{D as e,F as t,M as n,P as r,T as i,W as a,X as o,_t as s,c,d as l,h as u,ht as d,k as f,l as p,m,r as h,u as g}from"./runtime-core.esm-bundler-DWJwptQ-.js";import{n as _,t as v}from"./clock-CYEi9Knb.js";import{t as y}from"./play-BBWx7r99.js";import{t as b}from"./square-pen-W_aBk2wR.js";import{t as x}from"./trash-2-BlIjHjqi.js";import{At as S,B as ee,Ft as C,It as w,L as te,Mt as ne,_t as T,at as E,c as re,gt as ie,i as ae,p as oe}from"./index-B93KhQc5.js";import{t as D}from"./IconButton-D_Xb_fPi.js";import{t as se}from"./Modal-CMnodc09.js";var ce=S(`circle-plus`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M8 12h8`,key:`1wcyev`}],[`path`,{d:`M12 8v8`,key:`napkw2`}]]),O=S(`pause`,[[`rect`,{x:`14`,y:`3`,width:`5`,height:`18`,rx:`1`,key:`kaeet6`}],[`rect`,{x:`5`,y:`3`,width:`5`,height:`18`,rx:`1`,key:`1wsw3u`}]]),le={class:`space-y-6`},ue={class:`flex items-center justify-between`},de={class:`bg-background border border-border rounded-lg overflow-x-auto`},fe={class:`sm:hidden divide-y divide-border`},pe={class:`flex items-start justify-between gap-2`},me={class:`min-w-0 flex-1`},he={class:`flex items-center gap-2 flex-wrap`},ge={class:`font-medium text-foreground truncate`},_e={class:`mt-1 text-[11px] text-foreground font-mono break-all`},ve={class:`mt-0.5 text-[11px] text-foreground-muted`},k={class:`text-foreground-muted/70`},A={class:`mt-1 flex flex-wrap items-center gap-x-3 gap-y-0.5 text-[11px] text-foreground-muted`},j={class:`flex items-center gap-1 shrink-0`},M={key:0,class:`px-6 py-12 text-center`},N={class:`hidden sm:table w-full text-sm text-left`},P={class:`divide-y divide-border`},F={class:`px-6 py-4 font-medium text-foreground max-w-[16rem] truncate`},ye={class:`px-6 py-4`},be={class:`flex flex-col gap-1`},xe={class:`text-foreground font-mono text-xs break-all`},Se={class:`text-foreground-muted text-[10px]`},Ce={class:`text-foreground-muted/70`},we={class:`px-6 py-4 hidden sm:table-cell`},Te={class:`px-6 py-4 text-foreground-muted text-xs hidden md:table-cell`},Ee={class:`px-6 py-4 text-foreground-muted text-xs hidden lg:table-cell`},De={class:`px-6 py-4 text-right`},Oe={class:`inline-flex items-center gap-1`},ke={key:0},Ae={colspan:`6`,class:`px-6 py-12 text-center`},I={class:`space-y-5`},je=[`disabled`],Me=[`value`],Ne={class:`flex gap-2 bg-background rounded-lg p-1 border border-border`},Pe=[`onClick`],Fe={key:0,class:`space-y-4`},Ie={class:`grid grid-cols-3 gap-3`},Le={key:0},Re={key:1},ze={key:2},Be={key:3},Ve={class:`bg-background border border-border rounded-lg p-4`},He={class:`font-mono text-sm text-foreground`},Ue={class:`text-xs text-foreground-muted mt-1`},We={key:1,class:`space-y-3`},Ge={class:`bg-background border border-border rounded-lg p-4`},Ke={class:`text-xs text-foreground`},qe=[`value`],Je={class:`text-xs text-foreground-muted mt-1.5`},Ye={class:`bg-surface px-1 rounded`},Xe={class:`flex items-center gap-3`},L={__name:`CronJobs`,setup(S){let L=ae(),Ze=[...new Set([L,`UTC`,`America/Los_Angeles`,`America/New_York`,`America/Chicago`,`America/Denver`,`America/Sao_Paulo`,`Europe/London`,`Europe/Berlin`,`Europe/Paris`,`Europe/Moscow`,`Africa/Lagos`,`Africa/Cairo`,`Africa/Johannesburg`,`Asia/Dubai`,`Asia/Kolkata`,`Asia/Singapore`,`Asia/Shanghai`,`Asia/Tokyo`,`Australia/Sydney`,`Pacific/Auckland`])],R=ie(),z=a([]),B=a([]),V=a(!1),H=a(null),U=a(`simple`),W=a({function_name:``,cron:`0 0 * * *`,timezone:L,enabled:!0}),G=a({frequency:`day`,minute:0,hour:0,dayOfWeek:1,dayOfMonth:1}),K=async()=>{try{let e=await te();z.value=e.data.schedules||[]}catch(e){console.error(`Failed to load cron jobs`,e)}},Qe=async()=>{try{let e=await ee();B.value=e.data.functions||[]}catch(e){console.error(`Failed to load functions`,e)}},q=()=>{let{frequency:e,minute:t,hour:n,dayOfWeek:r,dayOfMonth:i}=G.value;switch(e){case`minute`:W.value.cron=`* * * * *`;break;case`hour`:W.value.cron=`${t} * * * *`;break;case`day`:W.value.cron=`${t} ${n} * * *`;break;case`week`:W.value.cron=`${t} ${n} * * ${r}`;break;case`month`:W.value.cron=`${t} ${n} ${i} * *`}},J=e=>{if(!e)return`Invalid expression`;let t=e.trim().split(/\s+/);if(t.length!==5)return`Invalid format (use 5 fields)`;let[n,r,i,a,o]=t;return e===`* * * * *`?`Every minute`:n!==`*`&&r===`*`&&i===`*`&&a===`*`&&o===`*`?`Every hour at minute ${n}`:n!==`*`&&r!==`*`&&i===`*`&&a===`*`&&o===`*`?`Every day at ${r.padStart(2,`0`)}:${n.padStart(2,`0`)}`:n!==`*`&&r!==`*`&&i===`*`&&a===`*`&&o!==`*`?`Every ${[`Sunday`,`Monday`,`Tuesday`,`Wednesday`,`Thursday`,`Friday`,`Saturday`][o]} at ${r.padStart(2,`0`)}:${n.padStart(2,`0`)}`:n!==`*`&&r!==`*`&&i!==`*`&&a===`*`&&o===`*`?`On day ${i} of every month at ${r.padStart(2,`0`)}:${n.padStart(2,`0`)}`:`Custom: ${e}`},Y=e=>new Date(e).toLocaleString(`en-US`,{month:`short`,day:`numeric`,hour:`2-digit`,minute:`2-digit`}),$e=async()=>{try{H.value?await E(H.value.id,{function_id:H.value.function_id,cron:W.value.cron,timezone:W.value.timezone,enabled:W.value.enabled}):await re(W.value.function_name,{cron:W.value.cron,timezone:W.value.timezone,enabled:W.value.enabled}),await K(),$()}catch(e){console.error(`Failed to save schedule`,e),R.notify({title:`Failed to save schedule`,danger:!0})}},X=e=>{H.value=e,W.value={function_name:e.function_name,cron:e.cron_expression,timezone:e.timezone||`UTC`,enabled:e.enabled},V.value=!0},Z=async e=>{try{await E(e.id,{function_id:e.function_id,enabled:!e.enabled}),await K()}catch(e){console.error(`Failed to toggle schedule`,e)}},Q=async e=>{if(await R.ask({title:`Delete schedule?`,message:`Cron schedule for "${e.function_name}" will be removed.`,confirmLabel:`Delete`,danger:!0}))try{await oe(e.id,e.function_id),await K()}catch(e){console.error(`Failed to delete schedule`,e)}},$=()=>{V.value=!1,H.value=null,W.value={function_name:``,cron:`0 0 * * *`,timezone:L,enabled:!0},G.value={frequency:`day`,minute:0,hour:0,dayOfWeek:1,dayOfMonth:1},U.value=`simple`};return i(()=>{K(),Qe(),q()}),(i,a)=>(e(),l(`div`,le,[c(`div`,ue,[a[12]||=c(`div`,null,[c(`h1`,{class:`text-xl font-semibold text-white tracking-tight`},` Scheduled Jobs `),c(`p`,{class:`text-sm text-foreground-muted mt-1.5 max-w-prose leading-body`},` Cron-driven triggers that fire any deployed function on a schedule. Use them for periodic cleanup, daily reports, polling external APIs, anything you'd normally pin to a server's crontab. Orva runs the schedule, captures stdout/stderr, and surfaces failures in the activity feed. `)],-1),u(T,{onClick:a[0]||=e=>V.value=!0},{default:r(()=>[u(o(ce),{class:`w-4 h-4`}),a[11]||=m(` New Schedule `,-1)]),_:1})]),c(`div`,de,[c(`ul`,fe,[(e(!0),l(h,null,f(z.value,t=>(e(),l(`li`,{key:t.id,class:`px-4 py-3`},[c(`div`,pe,[c(`div`,me,[c(`div`,he,[c(`span`,ge,s(t.function_name),1),c(`span`,{class:d([`inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] font-medium border`,t.enabled?`bg-success-tint text-success-fg border-success-ring`:`bg-warning-tint text-warning-fg border-warning-ring`])},[(e(),p(n(t.enabled?o(_):o(v)),{class:`h-3 w-3 shrink-0`,"aria-hidden":`true`})),m(` `+s(t.enabled?`Active`:`Paused`),1)],2)]),c(`div`,_e,s(t.cron_expression),1),c(`div`,ve,[m(s(J(t.cron_expression))+` `,1),c(`span`,k,`· `+s(t.timezone||`UTC`),1)]),c(`div`,A,[c(`span`,null,`last `+s(t.last_run_at?Y(t.last_run_at):o(`—`)),1),c(`span`,null,`next `+s(t.next_run_at?Y(t.next_run_at):o(`—`)),1)])]),c(`div`,j,[u(D,{icon:t.enabled?o(O):o(y),title:t.enabled?`Pause`:`Resume`,onClick:e=>Z(t)},null,8,[`icon`,`title`,`onClick`]),u(D,{icon:o(b),title:`Edit`,onClick:e=>X(t)},null,8,[`icon`,`onClick`]),u(D,{icon:o(x),variant:`danger`,title:`Delete`,onClick:e=>Q(t)},null,8,[`icon`,`onClick`])])])]))),128)),z.value.length===0?(e(),l(`li`,M,[u(o(v),{class:`w-12 h-12 text-foreground-muted mx-auto mb-3 opacity-60`}),a[13]||=c(`p`,{class:`text-foreground-muted`},` No scheduled jobs yet. `,-1),a[14]||=c(`p`,{class:`text-foreground-muted text-xs mt-1`},` Create your first schedule to automate function execution. `,-1)])):g(``,!0)]),c(`table`,N,[a[17]||=c(`thead`,{class:`text-xs text-foreground-muted uppercase bg-surface border-b border-border`},[c(`tr`,null,[c(`th`,{class:`px-6 py-3 font-medium`},` Function `),c(`th`,{class:`px-6 py-3 font-medium`},` Schedule `),c(`th`,{class:`px-6 py-3 font-medium hidden sm:table-cell`},` Status `),c(`th`,{class:`px-6 py-3 font-medium hidden md:table-cell`},` Last Run `),c(`th`,{class:`px-6 py-3 font-medium hidden lg:table-cell`},` Next Run `),c(`th`,{class:`px-6 py-3 font-medium text-right`},` Actions `)])],-1),c(`tbody`,P,[(e(!0),l(h,null,f(z.value,t=>(e(),l(`tr`,{key:t.id,class:`hover:bg-surface-hover transition-colors`},[c(`td`,F,s(t.function_name),1),c(`td`,ye,[c(`div`,be,[c(`span`,xe,s(t.cron_expression),1),c(`span`,Se,[m(s(J(t.cron_expression))+` `,1),c(`span`,Ce,`· `+s(t.timezone||`UTC`),1)])])]),c(`td`,we,[c(`span`,{class:d([`inline-flex items-center gap-1 px-2 py-0.5 rounded text-xs font-medium border`,t.enabled?`bg-success-tint text-success-fg border-success-ring`:`bg-warning-tint text-warning-fg border-warning-ring`])},[(e(),p(n(t.enabled?o(_):o(v)),{class:`h-3 w-3 shrink-0`,"aria-hidden":`true`})),m(` `+s(t.enabled?`Active`:`Paused`),1)],2)]),c(`td`,Te,s(t.last_run_at?Y(t.last_run_at):o(`—`)),1),c(`td`,Ee,s(t.next_run_at?Y(t.next_run_at):o(`—`)),1),c(`td`,De,[c(`div`,Oe,[u(D,{icon:t.enabled?o(O):o(y),title:t.enabled?`Pause`:`Resume`,onClick:e=>Z(t)},null,8,[`icon`,`title`,`onClick`]),u(D,{icon:o(b),title:`Edit`,onClick:e=>X(t)},null,8,[`icon`,`onClick`]),u(D,{icon:o(x),variant:`danger`,title:`Delete`,onClick:e=>Q(t)},null,8,[`icon`,`onClick`])])])]))),128)),z.value.length===0?(e(),l(`tr`,ke,[c(`td`,Ae,[u(o(v),{class:`w-12 h-12 text-foreground-muted mx-auto mb-3 opacity-60`}),a[15]||=c(`p`,{class:`text-foreground-muted`},` No scheduled jobs yet. `,-1),a[16]||=c(`p`,{class:`text-foreground-muted text-xs mt-1`},` Create your first schedule to automate function execution. `,-1)])])):g(``,!0)])])]),u(se,{"model-value":V.value,title:H.value?`Edit Schedule`:`Create Schedule`,size:`lg`,"onUpdate:modelValue":a[10]||=e=>{e||$()}},{footer:r(()=>[u(T,{variant:`ghost`,onClick:$},{default:r(()=>[...a[38]||=[m(` Cancel `,-1)]]),_:1}),u(T,{disabled:!W.value.function_name||!W.value.cron,onClick:$e},{default:r(()=>[m(s(H.value?`Update`:`Create`)+` Schedule `,1)]),_:1},8,[`disabled`])]),default:r(()=>[c(`div`,I,[c(`div`,null,[a[19]||=c(`label`,{class:`text-xs font-medium text-foreground-muted uppercase tracking-wide block mb-2`},`Function`,-1),t(c(`select`,{"onUpdate:modelValue":a[1]||=e=>W.value.function_name=e,class:`w-full bg-background border border-border rounded-md px-3 py-2 text-sm text-foreground focus:outline-none focus:ring-1 focus:ring-white focus:border-white`,disabled:!!H.value},[a[18]||=c(`option`,{value:``},` Select a function `,-1),(e(!0),l(h,null,f(B.value,t=>(e(),l(`option`,{key:t.name,value:t.name},s(t.name)+` (`+s(t.runtime)+`) `,9,Me))),128))],8,je),[[C,W.value.function_name]])]),c(`div`,null,[a[20]||=c(`label`,{class:`text-xs font-medium text-foreground-muted uppercase tracking-wide block mb-2`},`Schedule Type`,-1),c(`div`,Ne,[(e(),l(h,null,f([`simple`,`advanced`],e=>c(`button`,{key:e,class:d([`flex-1 py-2 px-3 text-sm font-medium rounded transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-background`,U.value===e?`bg-primary text-primary-foreground shadow-sm`:`text-foreground-muted hover:text-foreground`]),onClick:t=>U.value=e},s(e===`simple`?`Natural Language`:`Cron Expression`),11,Pe)),64))])]),U.value===`simple`?(e(),l(`div`,Fe,[c(`div`,Ie,[c(`div`,null,[a[22]||=c(`label`,{class:`text-xs font-medium text-foreground-muted block mb-1.5`},`Frequency`,-1),t(c(`select`,{"onUpdate:modelValue":a[2]||=e=>G.value.frequency=e,class:`w-full bg-background border border-border rounded-md px-3 py-2 text-sm text-foreground focus:outline-none focus:ring-1 focus:ring-white focus:border-white`,onChange:q},[...a[21]||=[c(`option`,{value:`minute`},` Every Minute `,-1),c(`option`,{value:`hour`},` Hourly `,-1),c(`option`,{value:`day`},` Daily `,-1),c(`option`,{value:`week`},` Weekly `,-1),c(`option`,{value:`month`},` Monthly `,-1)]],544),[[C,G.value.frequency]])]),[`hour`,`day`,`week`,`month`].includes(G.value.frequency)?(e(),l(`div`,Le,[a[23]||=c(`label`,{class:`text-xs font-medium text-foreground-muted block mb-1.5`},`At Minute`,-1),t(c(`input`,{"onUpdate:modelValue":a[3]||=e=>G.value.minute=e,type:`number`,min:`0`,max:`59`,class:`w-full bg-background border border-border rounded-md px-3 py-2 text-sm text-foreground focus:outline-none focus:ring-1 focus:ring-white focus:border-white`,onInput:q},null,544),[[w,G.value.minute,void 0,{number:!0}]])])):g(``,!0),[`day`,`week`,`month`].includes(G.value.frequency)?(e(),l(`div`,Re,[a[24]||=c(`label`,{class:`text-xs font-medium text-foreground-muted block mb-1.5`},`At Hour`,-1),t(c(`input`,{"onUpdate:modelValue":a[4]||=e=>G.value.hour=e,type:`number`,min:`0`,max:`23`,class:`w-full bg-background border border-border rounded-md px-3 py-2 text-sm text-foreground focus:outline-none focus:ring-1 focus:ring-white focus:border-white`,onInput:q},null,544),[[w,G.value.hour,void 0,{number:!0}]])])):g(``,!0),G.value.frequency===`week`?(e(),l(`div`,ze,[a[26]||=c(`label`,{class:`text-xs font-medium text-foreground-muted block mb-1.5`},`Day of Week`,-1),t(c(`select`,{"onUpdate:modelValue":a[5]||=e=>G.value.dayOfWeek=e,class:`w-full bg-background border border-border rounded-md px-3 py-2 text-sm text-foreground focus:outline-none focus:ring-1 focus:ring-white focus:border-white`,onChange:q},[...a[25]||=[c(`option`,{value:`0`},` Sunday `,-1),c(`option`,{value:`1`},` Monday `,-1),c(`option`,{value:`2`},` Tuesday `,-1),c(`option`,{value:`3`},` Wednesday `,-1),c(`option`,{value:`4`},` Thursday `,-1),c(`option`,{value:`5`},` Friday `,-1),c(`option`,{value:`6`},` Saturday `,-1)]],544),[[C,G.value.dayOfWeek]])])):g(``,!0),G.value.frequency===`month`?(e(),l(`div`,Be,[a[27]||=c(`label`,{class:`text-xs font-medium text-foreground-muted block mb-1.5`},`Day of Month`,-1),t(c(`input`,{"onUpdate:modelValue":a[6]||=e=>G.value.dayOfMonth=e,type:`number`,min:`1`,max:`31`,class:`w-full bg-background border border-border rounded-md px-3 py-2 text-sm text-foreground focus:outline-none focus:ring-1 focus:ring-white focus:border-white`,onInput:q},null,544),[[w,G.value.dayOfMonth,void 0,{number:!0}]])])):g(``,!0)]),c(`div`,Ve,[a[28]||=c(`div`,{class:`text-xs font-medium text-foreground-muted uppercase tracking-wide mb-2`},` Generated Expression `,-1),c(`div`,He,s(W.value.cron),1),c(`div`,Ue,s(J(W.value.cron)),1)])])):g(``,!0),U.value===`advanced`?(e(),l(`div`,We,[c(`div`,null,[a[29]||=c(`label`,{class:`text-xs font-medium text-foreground-muted block mb-1.5`},`Cron Expression`,-1),t(c(`input`,{"onUpdate:modelValue":a[7]||=e=>W.value.cron=e,placeholder:`* * * * *`,class:`w-full bg-background border border-border rounded-md px-3 py-2 text-sm font-mono text-foreground focus:outline-none focus:ring-1 focus:ring-white focus:border-white`},null,512),[[w,W.value.cron]]),a[30]||=c(`p`,{class:`text-xs text-foreground-muted mt-1.5`},` Format: minute hour day month weekday `,-1)]),c(`div`,Ge,[a[31]||=c(`div`,{class:`text-xs font-medium text-foreground-muted uppercase tracking-wide mb-2`},` Preview `,-1),c(`div`,Ke,s(J(W.value.cron)),1)])])):g(``,!0),c(`div`,null,[a[36]||=c(`label`,{class:`block text-xs font-medium text-foreground-muted uppercase tracking-wide mb-1.5`},` Timezone `,-1),t(c(`select`,{"onUpdate:modelValue":a[8]||=e=>W.value.timezone=e,class:`w-full bg-surface-hover border border-border rounded-md px-3 py-2 text-sm text-foreground focus:outline-none focus:border-white`},[(e(!0),l(h,null,f(o(Ze),t=>(e(),l(`option`,{key:t,value:t},s(t)+s(t===o(L)?` (your browser)`:``),9,qe))),128))],512),[[C,W.value.timezone]]),c(`div`,Je,[a[32]||=m(` The cron expression is interpreted in this zone (e.g. `,-1),a[33]||=c(`code`,{class:`bg-surface px-1 rounded`},`0 9 * * *`,-1),a[34]||=m(` with timezone `,-1),c(`code`,Ye,s(W.value.timezone),1),a[35]||=m(` fires at 9 AM local time every day. `,-1)])]),c(`div`,Xe,[t(c(`input`,{id:`enabled-toggle`,"onUpdate:modelValue":a[9]||=e=>W.value.enabled=e,type:`checkbox`,class:`w-4 h-4 text-primary bg-background border-border rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-background`},null,512),[[ne,W.value.enabled]]),a[37]||=c(`label`,{for:`enabled-toggle`,class:`text-sm font-medium text-foreground cursor-pointer`},` Enable schedule immediately `,-1)])])]),_:1},8,[`model-value`,`title`])]))}};export{L as default}; \ No newline at end of file diff --git a/backend/internal/server/ui_dist/assets/CronJobs-ChQ_JvvX.js b/backend/internal/server/ui_dist/assets/CronJobs-ChQ_JvvX.js new file mode 100644 index 00000000..17772074 --- /dev/null +++ b/backend/internal/server/ui_dist/assets/CronJobs-ChQ_JvvX.js @@ -0,0 +1 @@ +import{D as e,F as t,G as n,I as r,M as i,T as a,Z as o,c as s,d as c,gt as l,h as u,k as d,l as f,m as p,r as m,u as h,vt as g}from"./runtime-core.esm-bundler-BMQPyJ_W.js";import{n as _,t as v}from"./clock-Dx_vxhwd.js";import{t as y}from"./play-7LGcVtH4.js";import{t as b}from"./square-pen-BaygMdb7.js";import{t as x}from"./trash-2-DDX094Y-.js";import{B as ee,It as S,L as te,Lt as C,Nt as ne,_t as w,at as T,c as re,gt as ie,i as ae,jt as E,p as oe}from"./index-CZI-jurg.js";import{t as D}from"./IconButton-CsCZOqWo.js";import{t as se}from"./Modal-D_xvZeX4.js";var ce=E(`circle-plus`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M8 12h8`,key:`1wcyev`}],[`path`,{d:`M12 8v8`,key:`napkw2`}]]),O=E(`pause`,[[`rect`,{x:`14`,y:`3`,width:`5`,height:`18`,rx:`1`,key:`kaeet6`}],[`rect`,{x:`5`,y:`3`,width:`5`,height:`18`,rx:`1`,key:`1wsw3u`}]]),le={class:`space-y-6`},ue={class:`flex items-center justify-between`},de={class:`bg-background border border-border rounded-lg overflow-x-auto`},fe={class:`sm:hidden divide-y divide-border`},pe={class:`flex items-start justify-between gap-2`},me={class:`min-w-0 flex-1`},he={class:`flex items-center gap-2 flex-wrap`},ge={class:`font-medium text-foreground truncate`},_e={class:`mt-1 text-[11px] text-foreground font-mono break-all`},ve={class:`mt-0.5 text-[11px] text-foreground-muted`},k={class:`text-foreground-muted/70`},A={class:`mt-1 flex flex-wrap items-center gap-x-3 gap-y-0.5 text-[11px] text-foreground-muted`},j={class:`flex items-center gap-1 shrink-0`},M={key:0,class:`px-6 py-12 text-center`},N={class:`hidden sm:table w-full text-sm text-left`},P={class:`divide-y divide-border`},F={class:`px-6 py-4 font-medium text-foreground max-w-[16rem] truncate`},ye={class:`px-6 py-4`},be={class:`flex flex-col gap-1`},xe={class:`text-foreground font-mono text-xs break-all`},Se={class:`text-foreground-muted text-[10px]`},Ce={class:`text-foreground-muted/70`},we={class:`px-6 py-4 hidden sm:table-cell`},Te={class:`px-6 py-4 text-foreground-muted text-xs hidden md:table-cell`},Ee={class:`px-6 py-4 text-foreground-muted text-xs hidden lg:table-cell`},De={class:`px-6 py-4 text-right`},Oe={class:`inline-flex items-center gap-1`},ke={key:0},Ae={class:`space-y-5`},je=[`disabled`],Me=[`value`],Ne={class:`flex gap-2 bg-background rounded-lg p-1 border border-border`},Pe=[`onClick`],Fe={key:0,class:`space-y-4`},Ie={class:`grid grid-cols-3 gap-3`},I={key:0},Le={key:1},Re={key:2},ze={key:3},Be={class:`bg-background border border-border rounded-lg p-4`},Ve={class:`font-mono text-sm text-foreground`},He={class:`text-xs text-foreground-muted mt-1`},Ue={key:1,class:`space-y-3`},We={class:`bg-background border border-border rounded-lg p-4`},Ge={class:`text-xs text-foreground`},Ke=[`value`],qe={class:`text-xs text-foreground-muted mt-1.5`},Je={class:`bg-surface px-1 rounded`},Ye={class:`flex items-center gap-3`},L={__name:`CronJobs`,setup(E){let L=ae(),Xe=[...new Set([L,`UTC`,`America/Los_Angeles`,`America/New_York`,`America/Chicago`,`America/Denver`,`America/Sao_Paulo`,`Europe/London`,`Europe/Berlin`,`Europe/Paris`,`Europe/Moscow`,`Africa/Lagos`,`Africa/Cairo`,`Africa/Johannesburg`,`Asia/Dubai`,`Asia/Kolkata`,`Asia/Singapore`,`Asia/Shanghai`,`Asia/Tokyo`,`Australia/Sydney`,`Pacific/Auckland`])],R=ie(),z=n([]),B=n([]),V=n(!1),H=n(null),U=n(`simple`),W=n({function_name:``,cron:`0 0 * * *`,timezone:L,enabled:!0}),G=n({frequency:`day`,minute:0,hour:0,dayOfWeek:1,dayOfMonth:1}),K=async()=>{try{let e=await te();z.value=e.data.schedules||[]}catch(e){console.error(`Failed to load cron jobs`,e)}},Ze=async()=>{try{let e=await ee();B.value=e.data.functions||[]}catch(e){console.error(`Failed to load functions`,e)}},q=()=>{let{frequency:e,minute:t,hour:n,dayOfWeek:r,dayOfMonth:i}=G.value;switch(e){case`minute`:W.value.cron=`* * * * *`;break;case`hour`:W.value.cron=`${t} * * * *`;break;case`day`:W.value.cron=`${t} ${n} * * *`;break;case`week`:W.value.cron=`${t} ${n} * * ${r}`;break;case`month`:W.value.cron=`${t} ${n} ${i} * *`}},J=e=>{if(!e)return`Invalid expression`;let t=e.trim().split(/\s+/);if(t.length!==5)return`Invalid format (use 5 fields)`;let[n,r,i,a,o]=t;return e===`* * * * *`?`Every minute`:n!==`*`&&r===`*`&&i===`*`&&a===`*`&&o===`*`?`Every hour at minute ${n}`:n!==`*`&&r!==`*`&&i===`*`&&a===`*`&&o===`*`?`Every day at ${r.padStart(2,`0`)}:${n.padStart(2,`0`)}`:n!==`*`&&r!==`*`&&i===`*`&&a===`*`&&o!==`*`?`Every ${[`Sunday`,`Monday`,`Tuesday`,`Wednesday`,`Thursday`,`Friday`,`Saturday`][o]} at ${r.padStart(2,`0`)}:${n.padStart(2,`0`)}`:n!==`*`&&r!==`*`&&i!==`*`&&a===`*`&&o===`*`?`On day ${i} of every month at ${r.padStart(2,`0`)}:${n.padStart(2,`0`)}`:`Custom: ${e}`},Y=e=>new Date(e).toLocaleString(`en-US`,{month:`short`,day:`numeric`,hour:`2-digit`,minute:`2-digit`}),Qe=async()=>{try{H.value?await T(H.value.id,{function_id:H.value.function_id,cron:W.value.cron,timezone:W.value.timezone,enabled:W.value.enabled}):await re(W.value.function_name,{cron:W.value.cron,timezone:W.value.timezone,enabled:W.value.enabled}),await K(),$()}catch(e){console.error(`Failed to save schedule`,e),R.notify({title:`Failed to save schedule`,danger:!0})}},X=e=>{H.value=e,W.value={function_name:e.function_name,cron:e.cron_expression,timezone:e.timezone||`UTC`,enabled:e.enabled},V.value=!0},Z=async e=>{try{await T(e.id,{function_id:e.function_id,enabled:!e.enabled}),await K()}catch(e){console.error(`Failed to toggle schedule`,e)}},Q=async e=>{if(await R.ask({title:`Delete schedule?`,message:`Cron schedule for "${e.function_name}" will be removed.`,confirmLabel:`Delete`,danger:!0}))try{await oe(e.id,e.function_id),await K()}catch(e){console.error(`Failed to delete schedule`,e)}},$=()=>{V.value=!1,H.value=null,W.value={function_name:``,cron:`0 0 * * *`,timezone:L,enabled:!0},G.value={frequency:`day`,minute:0,hour:0,dayOfWeek:1,dayOfMonth:1},U.value=`simple`};return a(()=>{K(),Ze(),q()}),(n,a)=>(e(),c(`div`,le,[s(`div`,ue,[a[12]||=s(`div`,null,[s(`h1`,{class:`text-xl font-semibold text-white tracking-tight`},` Scheduled Jobs `),s(`p`,{class:`text-sm text-foreground-muted mt-1.5 max-w-prose leading-body`},` Run functions on a cron schedule. `)],-1),u(w,{onClick:a[0]||=e=>V.value=!0},{default:t(()=>[u(o(ce),{class:`w-4 h-4`}),a[11]||=p(` New Schedule `,-1)]),_:1})]),s(`div`,de,[s(`ul`,fe,[(e(!0),c(m,null,d(z.value,t=>(e(),c(`li`,{key:t.id,class:`px-4 py-3`},[s(`div`,pe,[s(`div`,me,[s(`div`,he,[s(`span`,ge,g(t.function_name),1),s(`span`,{class:l([`inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] font-medium border`,t.enabled?`bg-success-tint text-success-fg border-success-ring`:`bg-warning-tint text-warning-fg border-warning-ring`])},[(e(),f(i(t.enabled?o(_):o(v)),{class:`h-3 w-3 shrink-0`,"aria-hidden":`true`})),p(` `+g(t.enabled?`Active`:`Paused`),1)],2)]),s(`div`,_e,g(t.cron_expression),1),s(`div`,ve,[p(g(J(t.cron_expression))+` `,1),s(`span`,k,`· `+g(t.timezone||`UTC`),1)]),s(`div`,A,[s(`span`,null,`last `+g(t.last_run_at?Y(t.last_run_at):o(`—`)),1),s(`span`,null,`next `+g(t.next_run_at?Y(t.next_run_at):o(`—`)),1)])]),s(`div`,j,[u(D,{icon:t.enabled?o(O):o(y),title:t.enabled?`Pause`:`Resume`,onClick:e=>Z(t)},null,8,[`icon`,`title`,`onClick`]),u(D,{icon:o(b),title:`Edit`,onClick:e=>X(t)},null,8,[`icon`,`onClick`]),u(D,{icon:o(x),variant:`danger`,title:`Delete`,onClick:e=>Q(t)},null,8,[`icon`,`onClick`])])])]))),128)),z.value.length===0?(e(),c(`li`,M,[...a[13]||=[s(`p`,{class:`text-foreground-muted`},` No scheduled jobs yet. `,-1),s(`p`,{class:`text-foreground-muted text-xs mt-1`},` Create a schedule to run a function automatically. `,-1)]])):h(``,!0)]),s(`table`,N,[a[15]||=s(`thead`,{class:`text-xs text-foreground-muted uppercase bg-surface border-b border-border`},[s(`tr`,null,[s(`th`,{class:`px-6 py-3 font-medium`},` Function `),s(`th`,{class:`px-6 py-3 font-medium`},` Schedule `),s(`th`,{class:`px-6 py-3 font-medium hidden sm:table-cell`},` Status `),s(`th`,{class:`px-6 py-3 font-medium hidden md:table-cell`},` Last Run `),s(`th`,{class:`px-6 py-3 font-medium hidden lg:table-cell`},` Next Run `),s(`th`,{class:`px-6 py-3 font-medium text-right`},` Actions `)])],-1),s(`tbody`,P,[(e(!0),c(m,null,d(z.value,t=>(e(),c(`tr`,{key:t.id,class:`hover:bg-surface-hover transition-colors`},[s(`td`,F,g(t.function_name),1),s(`td`,ye,[s(`div`,be,[s(`span`,xe,g(t.cron_expression),1),s(`span`,Se,[p(g(J(t.cron_expression))+` `,1),s(`span`,Ce,`· `+g(t.timezone||`UTC`),1)])])]),s(`td`,we,[s(`span`,{class:l([`inline-flex items-center gap-1 px-2 py-0.5 rounded text-xs font-medium border`,t.enabled?`bg-success-tint text-success-fg border-success-ring`:`bg-warning-tint text-warning-fg border-warning-ring`])},[(e(),f(i(t.enabled?o(_):o(v)),{class:`h-3 w-3 shrink-0`,"aria-hidden":`true`})),p(` `+g(t.enabled?`Active`:`Paused`),1)],2)]),s(`td`,Te,g(t.last_run_at?Y(t.last_run_at):o(`—`)),1),s(`td`,Ee,g(t.next_run_at?Y(t.next_run_at):o(`—`)),1),s(`td`,De,[s(`div`,Oe,[u(D,{icon:t.enabled?o(O):o(y),title:t.enabled?`Pause`:`Resume`,onClick:e=>Z(t)},null,8,[`icon`,`title`,`onClick`]),u(D,{icon:o(b),title:`Edit`,onClick:e=>X(t)},null,8,[`icon`,`onClick`]),u(D,{icon:o(x),variant:`danger`,title:`Delete`,onClick:e=>Q(t)},null,8,[`icon`,`onClick`])])])]))),128)),z.value.length===0?(e(),c(`tr`,ke,[...a[14]||=[s(`td`,{colspan:`6`,class:`px-6 py-12 text-center`},[s(`p`,{class:`text-foreground-muted`},` No scheduled jobs yet. `),s(`p`,{class:`text-foreground-muted text-xs mt-1`},` Create a schedule to run a function automatically. `)],-1)]])):h(``,!0)])])]),u(se,{"model-value":V.value,title:H.value?`Edit Schedule`:`Create Schedule`,size:`lg`,"onUpdate:modelValue":a[10]||=e=>{e||$()}},{footer:t(()=>[u(w,{variant:`ghost`,onClick:$},{default:t(()=>[...a[36]||=[p(` Cancel `,-1)]]),_:1}),u(w,{disabled:!W.value.function_name||!W.value.cron,onClick:Qe},{default:t(()=>[p(g(H.value?`Update`:`Create`)+` Schedule `,1)]),_:1},8,[`disabled`])]),default:t(()=>[s(`div`,Ae,[s(`div`,null,[a[17]||=s(`label`,{class:`text-xs font-medium text-foreground-muted uppercase tracking-wide block mb-2`},`Function`,-1),r(s(`select`,{"onUpdate:modelValue":a[1]||=e=>W.value.function_name=e,class:`w-full bg-background border border-border rounded-md px-3 py-2 text-sm text-foreground focus:outline-none focus:ring-1 focus:ring-white focus:border-white`,disabled:!!H.value},[a[16]||=s(`option`,{value:``},` Select a function `,-1),(e(!0),c(m,null,d(B.value,t=>(e(),c(`option`,{key:t.name,value:t.name},g(t.name)+` (`+g(t.runtime)+`) `,9,Me))),128))],8,je),[[S,W.value.function_name]])]),s(`div`,null,[a[18]||=s(`label`,{class:`text-xs font-medium text-foreground-muted uppercase tracking-wide block mb-2`},`Schedule Type`,-1),s(`div`,Ne,[(e(),c(m,null,d([`simple`,`advanced`],e=>s(`button`,{key:e,class:l([`flex-1 py-2 px-3 text-sm font-medium rounded transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-background`,U.value===e?`bg-primary text-primary-foreground shadow-sm`:`text-foreground-muted hover:text-foreground`]),onClick:t=>U.value=e},g(e===`simple`?`Natural Language`:`Cron Expression`),11,Pe)),64))])]),U.value===`simple`?(e(),c(`div`,Fe,[s(`div`,Ie,[s(`div`,null,[a[20]||=s(`label`,{class:`text-xs font-medium text-foreground-muted block mb-1.5`},`Frequency`,-1),r(s(`select`,{"onUpdate:modelValue":a[2]||=e=>G.value.frequency=e,class:`w-full bg-background border border-border rounded-md px-3 py-2 text-sm text-foreground focus:outline-none focus:ring-1 focus:ring-white focus:border-white`,onChange:q},[...a[19]||=[s(`option`,{value:`minute`},` Every Minute `,-1),s(`option`,{value:`hour`},` Hourly `,-1),s(`option`,{value:`day`},` Daily `,-1),s(`option`,{value:`week`},` Weekly `,-1),s(`option`,{value:`month`},` Monthly `,-1)]],544),[[S,G.value.frequency]])]),[`hour`,`day`,`week`,`month`].includes(G.value.frequency)?(e(),c(`div`,I,[a[21]||=s(`label`,{class:`text-xs font-medium text-foreground-muted block mb-1.5`},`At Minute`,-1),r(s(`input`,{"onUpdate:modelValue":a[3]||=e=>G.value.minute=e,type:`number`,min:`0`,max:`59`,class:`w-full bg-background border border-border rounded-md px-3 py-2 text-sm text-foreground focus:outline-none focus:ring-1 focus:ring-white focus:border-white`,onInput:q},null,544),[[C,G.value.minute,void 0,{number:!0}]])])):h(``,!0),[`day`,`week`,`month`].includes(G.value.frequency)?(e(),c(`div`,Le,[a[22]||=s(`label`,{class:`text-xs font-medium text-foreground-muted block mb-1.5`},`At Hour`,-1),r(s(`input`,{"onUpdate:modelValue":a[4]||=e=>G.value.hour=e,type:`number`,min:`0`,max:`23`,class:`w-full bg-background border border-border rounded-md px-3 py-2 text-sm text-foreground focus:outline-none focus:ring-1 focus:ring-white focus:border-white`,onInput:q},null,544),[[C,G.value.hour,void 0,{number:!0}]])])):h(``,!0),G.value.frequency===`week`?(e(),c(`div`,Re,[a[24]||=s(`label`,{class:`text-xs font-medium text-foreground-muted block mb-1.5`},`Day of Week`,-1),r(s(`select`,{"onUpdate:modelValue":a[5]||=e=>G.value.dayOfWeek=e,class:`w-full bg-background border border-border rounded-md px-3 py-2 text-sm text-foreground focus:outline-none focus:ring-1 focus:ring-white focus:border-white`,onChange:q},[...a[23]||=[s(`option`,{value:`0`},` Sunday `,-1),s(`option`,{value:`1`},` Monday `,-1),s(`option`,{value:`2`},` Tuesday `,-1),s(`option`,{value:`3`},` Wednesday `,-1),s(`option`,{value:`4`},` Thursday `,-1),s(`option`,{value:`5`},` Friday `,-1),s(`option`,{value:`6`},` Saturday `,-1)]],544),[[S,G.value.dayOfWeek]])])):h(``,!0),G.value.frequency===`month`?(e(),c(`div`,ze,[a[25]||=s(`label`,{class:`text-xs font-medium text-foreground-muted block mb-1.5`},`Day of Month`,-1),r(s(`input`,{"onUpdate:modelValue":a[6]||=e=>G.value.dayOfMonth=e,type:`number`,min:`1`,max:`31`,class:`w-full bg-background border border-border rounded-md px-3 py-2 text-sm text-foreground focus:outline-none focus:ring-1 focus:ring-white focus:border-white`,onInput:q},null,544),[[C,G.value.dayOfMonth,void 0,{number:!0}]])])):h(``,!0)]),s(`div`,Be,[a[26]||=s(`div`,{class:`text-xs font-medium text-foreground-muted uppercase tracking-wide mb-2`},` Generated Expression `,-1),s(`div`,Ve,g(W.value.cron),1),s(`div`,He,g(J(W.value.cron)),1)])])):h(``,!0),U.value===`advanced`?(e(),c(`div`,Ue,[s(`div`,null,[a[27]||=s(`label`,{class:`text-xs font-medium text-foreground-muted block mb-1.5`},`Cron Expression`,-1),r(s(`input`,{"onUpdate:modelValue":a[7]||=e=>W.value.cron=e,placeholder:`* * * * *`,class:`w-full bg-background border border-border rounded-md px-3 py-2 text-sm font-mono text-foreground focus:outline-none focus:ring-1 focus:ring-white focus:border-white`},null,512),[[C,W.value.cron]]),a[28]||=s(`p`,{class:`text-xs text-foreground-muted mt-1.5`},` Format: minute hour day month weekday `,-1)]),s(`div`,We,[a[29]||=s(`div`,{class:`text-xs font-medium text-foreground-muted uppercase tracking-wide mb-2`},` Preview `,-1),s(`div`,Ge,g(J(W.value.cron)),1)])])):h(``,!0),s(`div`,null,[a[34]||=s(`label`,{class:`block text-xs font-medium text-foreground-muted uppercase tracking-wide mb-1.5`},` Timezone `,-1),r(s(`select`,{"onUpdate:modelValue":a[8]||=e=>W.value.timezone=e,class:`w-full bg-surface-hover border border-border rounded-md px-3 py-2 text-sm text-foreground focus:outline-none focus:border-white`},[(e(!0),c(m,null,d(o(Xe),t=>(e(),c(`option`,{key:t,value:t},g(t)+g(t===o(L)?` (your browser)`:``),9,Ke))),128))],512),[[S,W.value.timezone]]),s(`div`,qe,[a[30]||=p(` The cron expression is interpreted in this zone (e.g. `,-1),a[31]||=s(`code`,{class:`bg-surface px-1 rounded`},`0 9 * * *`,-1),a[32]||=p(` with timezone `,-1),s(`code`,Je,g(W.value.timezone),1),a[33]||=p(` fires at 9 AM local time every day. `,-1)])]),s(`div`,Ye,[r(s(`input`,{id:`enabled-toggle`,"onUpdate:modelValue":a[9]||=e=>W.value.enabled=e,type:`checkbox`,class:`w-4 h-4 text-primary bg-background border-border rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-background`},null,512),[[ne,W.value.enabled]]),a[35]||=s(`label`,{for:`enabled-toggle`,class:`text-sm font-medium text-foreground cursor-pointer`},` Enable schedule immediately `,-1)])])]),_:1},8,[`model-value`,`title`])]))}};export{L as default}; \ No newline at end of file diff --git a/backend/internal/server/ui_dist/assets/Dashboard-Bgrzu27X.js b/backend/internal/server/ui_dist/assets/Dashboard-Bgrzu27X.js deleted file mode 100644 index d2d7459c..00000000 --- a/backend/internal/server/ui_dist/assets/Dashboard-Bgrzu27X.js +++ /dev/null @@ -1 +0,0 @@ -import{D as e,E as t,P as n,T as r,X as i,_t as a,c as o,d as s,h as c,k as ee,m as l,r as te,s as u,u as d,v as f}from"./runtime-core.esm-bundler-DWJwptQ-.js";import{At as p,Ot as ne,St as re,_t as ie,kt as ae,n as oe}from"./index-B93KhQc5.js";var se=p(`snowflake`,[[`path`,{d:`m10 20-1.25-2.5L6 18`,key:`18frcb`}],[`path`,{d:`M10 4 8.75 6.5 6 6`,key:`7mghy3`}],[`path`,{d:`m14 20 1.25-2.5L18 18`,key:`1chtki`}],[`path`,{d:`m14 4 1.25 2.5L18 6`,key:`1b4wsy`}],[`path`,{d:`m17 21-3-6h-4`,key:`15hhxa`}],[`path`,{d:`m17 3-3 6 1.5 3`,key:`11697g`}],[`path`,{d:`M2 12h6.5L10 9`,key:`kv9z4n`}],[`path`,{d:`m20 10-1.5 2 1.5 2`,key:`1swlpi`}],[`path`,{d:`M22 12h-6.5L14 15`,key:`1mxi28`}],[`path`,{d:`m4 10 1.5 2L4 14`,key:`k9enpj`}],[`path`,{d:`m7 21 3-6-1.5-3`,key:`j8hb9u`}],[`path`,{d:`m7 3 3 6h4`,key:`1otusx`}]]),ce=p(`trending-up`,[[`path`,{d:`M16 7h6v6`,key:`box55l`}],[`path`,{d:`m22 7-8.5 8.5-5-5L2 17`,key:`1t1m79`}]]),le={class:`space-y-6`},ue={class:`grid grid-cols-2 md:grid-cols-4 gap-4`},de={class:`grid grid-cols-1 lg:grid-cols-3 gap-4`},m={class:`bg-background border border-border rounded-lg p-5 lg:col-span-1`},h={class:`bg-background border border-border rounded-lg p-5 lg:col-span-2 space-y-5`},g={class:`grid grid-cols-2 gap-4 text-sm`},_={class:`text-lg font-mono text-white mt-0.5`},v={class:`text-lg font-mono text-white mt-0.5`},y={class:`text-foreground-muted text-sm`},b={class:`text-[11px] text-foreground-muted mt-0.5`},x={class:`space-y-2`},S={class:`flex flex-wrap items-center gap-x-4 gap-y-1 text-[11px] text-foreground-muted`},C={class:`flex items-center gap-1.5`},w={class:`flex items-center gap-1.5`},T={class:`grid grid-cols-1 md:grid-cols-2 gap-4`},E={class:`bg-background border border-border rounded-lg p-5 space-y-3`},D={class:`grid grid-cols-3 gap-3`},O={key:0,class:`text-xs text-red-400 flex items-center gap-1.5 pt-1`},k={class:`bg-background border border-border rounded-lg p-5 space-y-3`},A={class:`grid grid-cols-3 gap-3`},j={key:0},M={class:`flex items-baseline justify-between mb-3`},N={class:`text-xs font-bold text-white uppercase tracking-wider`},P={class:`grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4`},F={class:`flex items-start justify-between gap-2`},I={class:`min-w-0`},L={class:`text-sm font-medium text-white truncate`},R={class:`text-[10px] text-foreground-muted font-mono truncate`},z={class:`text-right shrink-0`},B={class:`text-xs font-mono text-white`},V={class:`grid grid-cols-3 gap-2`},fe={class:`border-t border-border pt-3 grid grid-cols-2 gap-3 text-[11px]`},pe={class:`font-mono text-white`},me={class:`font-mono text-white`},he={class:`font-mono text-white`,title:`Average memory used per invocation vs allocated limit`},ge={class:`text-foreground-muted`},_e={class:`font-mono text-white`,title:`Average CPU cores consumed per invocation vs allocated`},ve={key:0,class:`text-foreground-muted`},ye={key:1,class:`bg-background border border-border rounded-lg p-8 text-center space-y-4`},H={__name:`Dashboard`,setup(p){let H=oe(),U=u(()=>H.metrics||{}),be=e=>H.poolHistory[e]||[],xe=e=>e==null?`—`:`${e.toFixed(1)}%`,Se=e=>e==null?`0`:e.toFixed(1),W=e=>{let t=e||0;return t>=1024?`${(t/1024).toFixed(1)} GB`:`${Math.round(t)} MB`},G=e=>{let t=Number(e)||0;return t>=1e6?`${(t/1e6).toFixed(1)}M`:t>=1e3?`${(t/1e3).toFixed(1)}k`:String(t)},K=u(()=>U.value.host?.mem_total_mb??0),q=u(()=>U.value.host?.mem_reserved_mb??0),Ce=u(()=>U.value.host?.mem_available_mb??0),J=u(()=>Math.max(0,K.value-Ce.value)),Y=u(()=>Math.max(0,K.value-J.value)),we=u(()=>K.value>0?J.value/K.value*100:0),Te=u(()=>K.value>0?q.value/K.value*100:0);r(()=>H.connect()),t(()=>H.disconnect());let X={props:{label:String,value:[String,Number],icon:Object,hint:String},setup(e){return()=>f(`div`,{class:`bg-background border border-border rounded-lg p-5 flex flex-col h-full hover:border-primary/50 transition-colors group`},[f(`div`,{class:`flex items-center justify-between mb-3`},[f(`span`,{class:`text-xs font-medium text-foreground-muted uppercase tracking-wide`},e.label),e.icon?f(e.icon,{class:`w-4 h-4 text-foreground-muted group-hover:text-primary`}):null]),f(`div`,{class:`text-2xl font-mono text-foreground leading-none`},String(e.value)),e.hint?f(`div`,{class:`text-[11px] text-foreground-muted mt-auto pt-3 leading-snug`},e.hint):null])}},Z={props:{p50:Number,p95:Number,p99:Number},setup(e){return()=>{let t=[{label:`p50`,ms:e.p50,color:`bg-success/70`},{label:`p95`,ms:e.p95,color:`bg-warning/70`},{label:`p99`,ms:e.p99,color:`bg-danger/70`}],n=Math.max(e.p50||0,e.p95||0,e.p99||0,1);return f(`div`,{class:`space-y-2.5`},t.map(e=>{let t=e.ms==null?0:e.ms/n*100;return f(`div`,{class:`space-y-1`},[f(`div`,{class:`flex items-baseline justify-between text-[11px]`},[f(`span`,{class:`font-mono uppercase text-foreground-muted tracking-wider`},e.label),f(`span`,{class:`font-mono text-white`},e.ms==null?`—`:`${e.ms}ms`)]),f(`div`,{class:`h-1.5 bg-surface rounded overflow-hidden`},[f(`div`,{class:`h-full ${e.color} transition-[width] duration-500 ease-out`,style:{width:`${t.toFixed(1)}%`}})])])}))}}},Q={props:{label:String,value:[String,Number],hint:String},setup(e){return()=>f(`div`,{class:`bg-surface border border-border rounded p-3 flex flex-col h-full`},[f(`div`,{class:`text-[10px] uppercase tracking-wider text-foreground-muted`},e.label),f(`div`,{class:`text-lg font-mono text-white mt-0.5`},String(e.value??0)),e.hint?f(`div`,{class:`text-[10px] text-foreground-muted mt-auto pt-1.5 leading-snug`},e.hint):null])}},$={props:{label:String,value:[String,Number],hint:String},setup(e){return()=>f(`div`,{class:`bg-surface border border-border rounded p-2.5 flex flex-col h-full`},[f(`div`,{class:`text-[10px] uppercase tracking-wider text-foreground-muted`},e.label),f(`div`,{class:`text-base font-mono text-white mt-0.5 leading-none`},String(e.value??0)),e.hint?f(`div`,{class:`text-[10px] text-foreground-muted mt-auto pt-1.5`},e.hint):null])}},Ee={props:{total:{type:Number,required:!0},segments:{type:Array,required:!0}},setup(e){return()=>{let t=e.total>0?e.total:1;return f(`div`,{class:`h-2.5 bg-surface rounded overflow-hidden flex`,role:`img`,"aria-label":e.segments.map(t=>`${t.label}: ${t.value} of ${e.total}`).join(`; `)},e.segments.map(e=>f(`div`,{class:`h-full ${e.color}`,style:{width:`${(e.value/t*100).toFixed(2)}%`},title:`${e.label}: ${e.value}`})))}}},De={props:{points:{type:Array,default:()=>[]}},setup(e){return()=>{let t=e.points||[];if(t.length<2)return f(`div`,{class:`h-8 flex items-center text-[10px] text-foreground-muted`},`(collecting samples…)`);let n=Math.max(...t,1),r=100/(t.length-1),i=t.map((e,t)=>{let i=(t*r).toFixed(2),a=(32-e/n*32).toFixed(2);return`${t===0?`M`:`L`}${i},${a}`}).join(` `);return f(`svg`,{viewBox:`0 0 100 32`,class:`w-full h-8 text-blue-400`,preserveAspectRatio:`none`},[f(`path`,{d:i,fill:`none`,stroke:`currentColor`,"stroke-width":`1.5`})])}}};return(t,r)=>(e(),s(`div`,le,[r[21]||=o(`div`,null,[o(`h1`,{class:`text-xl font-semibold text-white tracking-tight`},` System Overview `),o(`p`,{class:`text-sm text-foreground-muted mt-1.5 max-w-prose leading-body`},` Live snapshot of what your platform is doing right now. `)],-1),o(`div`,ue,[c(X,{label:`Functions`,hint:`Deployed in this workspace`,value:i(H).functionsCount,icon:i(ne)},null,8,[`value`,`icon`]),c(X,{label:`In flight`,hint:`Requests being handled right now`,value:U.value.active_requests??0,icon:i(ae)},null,8,[`value`,`icon`]),c(X,{label:`Invocations`,hint:`Total calls served since the platform started`,value:G(U.value.totals?.invocations??0),icon:i(ce)},null,8,[`value`,`icon`]),c(X,{label:`Cold starts`,hint:`Calls that had to spawn a fresh sandbox`,value:xe(U.value.rates?.cold_start_pct),icon:i(se)},null,8,[`value`,`icon`])]),o(`div`,de,[o(`div`,m,[r[1]||=o(`div`,{class:`mb-3`},[o(`h2`,{class:`text-xs font-bold text-white uppercase tracking-wider`},` Response time `),o(`div`,{class:`text-[11px] text-foreground-muted mt-1`},` How long calls take to come back. p99 is the worst-case 1-in-100. `)],-1),c(Z,{p50:U.value.latency_ms?.p50,p95:U.value.latency_ms?.p95,p99:U.value.latency_ms?.p99},null,8,[`p50`,`p95`,`p99`])]),o(`div`,h,[r[7]||=o(`div`,null,[o(`h2`,{class:`text-xs font-bold text-white uppercase tracking-wider`},` Host machine `),o(`div`,{class:`text-[11px] text-foreground-muted mt-1`},` The server Orva is running on: how much of its RAM is actually in use, and how much your warm pools reserve as headroom. `)],-1),o(`div`,g,[o(`div`,null,[r[2]||=o(`div`,{class:`text-[10px] uppercase tracking-wider text-foreground-muted`},` CPU cores `,-1),o(`div`,_,a(U.value.host?.num_cpu??`?`),1),r[3]||=o(`div`,{class:`text-[11px] text-foreground-muted mt-0.5`},` available to functions on this host `,-1)]),o(`div`,null,[r[4]||=o(`div`,{class:`text-[10px] uppercase tracking-wider text-foreground-muted`},` Memory in use `,-1),o(`div`,v,[l(a(W(J.value))+` `,1),o(`span`,y,`/ `+a(W(K.value)),1)]),o(`div`,b,a(we.value.toFixed(1))+`% used · `+a(W(q.value))+` reserved by warm pools `,1)])]),o(`div`,x,[c(Ee,{total:K.value,segments:[{label:`In use`,value:J.value,color:`bg-info/70`},{label:`Free`,value:Y.value,color:`bg-success/40`}]},null,8,[`total`,`segments`]),o(`div`,S,[o(`span`,C,[r[5]||=o(`span`,{class:`w-2 h-2 rounded-full bg-info/70`},null,-1),l(` `+a(W(J.value))+` in use `,1)]),o(`span`,w,[r[6]||=o(`span`,{class:`w-2 h-2 rounded-full bg-success/40`},null,-1),l(` `+a(W(Y.value))+` free `,1)]),o(`span`,null,a(W(q.value))+` reserved by warm pools (`+a(Te.value.toFixed(1))+`% — held ready, not all in use) `,1)])])])]),o(`div`,T,[o(`div`,E,[r[9]||=o(`div`,null,[o(`h2`,{class:`text-xs font-bold text-white uppercase tracking-wider`},` Builds `),o(`div`,{class:`text-[11px] text-foreground-muted mt-1`},` Where deploys go: extracted, dependencies installed, then activated. `)],-1),o(`div`,D,[c(Q,{label:`In queue`,value:U.value.build_queue?.pending??0,hint:`waiting to start`},null,8,[`value`]),c(Q,{label:`Build workers`,value:U.value.build_queue?.workers??0,hint:`parallel slots`},null,8,[`value`]),c(Q,{label:`Built so far`,value:G(U.value.totals?.builds??0),hint:`lifetime total`},null,8,[`value`])]),(U.value.totals?.build_errors??0)>0?(e(),s(`div`,O,[r[8]||=o(`span`,{class:`w-1.5 h-1.5 rounded-full bg-red-400`},null,-1),l(` `+a(U.value.totals.build_errors)+` build`+a(U.value.totals.build_errors===1?` has`:`s have`)+` failed since start `,1)])):d(``,!0)]),o(`div`,k,[r[10]||=o(`div`,null,[o(`h2`,{class:`text-xs font-bold text-white uppercase tracking-wider`},` Sandbox activity `),o(`div`,{class:`text-[11px] text-foreground-muted mt-1`},` Each invocation runs inside an isolated nsjail sandbox process. `)],-1),o(`div`,A,[c(Q,{label:`Running now`,value:U.value.sandbox?.active??0,hint:`serving a request`},null,8,[`value`]),c(Q,{label:`Reused`,value:G(U.value.totals?.warm_hits??0),hint:`warm-pool hits`},null,8,[`value`]),c(Q,{label:`Spawned fresh`,value:G(U.value.totals?.cold_starts??0),hint:`cold starts`},null,8,[`value`])])])]),(U.value.pools||[]).length?(e(),s(`div`,j,[o(`div`,M,[o(`div`,null,[o(`h2`,N,` Warm pools (`+a(U.value.pools.length)+`) `,1),r[11]||=o(`div`,{class:`text-[11px] text-foreground-muted mt-1`},` One pool per active function. Sandboxes stay ready so the next call doesn't pay a cold start. `,-1)])]),o(`div`,P,[(e(!0),s(te,null,ee(U.value.pools,t=>(e(),s(`div`,{key:t.function_id,class:`bg-background border border-border rounded-lg p-4 space-y-3`},[o(`div`,F,[o(`div`,I,[o(`div`,L,a(t.function_name||t.function_id),1),o(`div`,R,a(t.function_id),1)]),o(`div`,z,[r[13]||=o(`div`,{class:`text-[10px] text-foreground-muted`},` Target / cap `,-1),o(`div`,B,[l(a(t.target)+` `,1),r[12]||=o(`span`,{class:`text-foreground-muted`},`/`,-1),l(` `+a(t.dynamic_max),1)])])]),o(`div`,V,[c($,{label:`Ready`,value:t.idle,hint:`idle workers`},null,8,[`value`]),c($,{label:`Busy`,value:t.busy,hint:`serving now`},null,8,[`value`]),c($,{label:`Calls / sec`,value:Se(t.rate_ewma),hint:`recent rate`},null,8,[`value`])]),o(`div`,null,[c(De,{points:be(t.function_id)},null,8,[`points`]),r[14]||=o(`div`,{class:`text-[10px] text-foreground-muted mt-1`},` Recent calls per second (last 5 min) `,-1)]),o(`div`,fe,[o(`div`,null,[r[15]||=o(`div`,{class:`text-foreground-muted`},` Spawned · killed `,-1),o(`div`,pe,a(t.spawned)+` · `+a(t.killed),1)]),o(`div`,null,[r[16]||=o(`div`,{class:`text-foreground-muted`},` Avg latency `,-1),o(`div`,me,a(t.latency_ewma_ms?.toFixed?.(1)??0)+` ms `,1)]),o(`div`,null,[r[17]||=o(`div`,{class:`text-foreground-muted`},` Avg memory `,-1),o(`div`,he,[l(a(t.mem_used_avg_mb>0?`~`+Math.round(t.mem_used_avg_mb):i(`—`))+` `,1),o(`span`,ge,`/ `+a(t.mem_limit_mb)+` MB`,1)])]),o(`div`,null,[r[18]||=o(`div`,{class:`text-foreground-muted`},` Avg CPU `,-1),o(`div`,_e,[l(a(t.cpu_frac_avg>0&&t.cpu_limit>0?(t.cpu_frac_avg*t.cpu_limit).toFixed(2):i(`—`))+` `,1),t.cpu_limit>0?(e(),s(`span`,ve,`/ `+a(t.cpu_limit)+` CPU`,1)):d(``,!0)])])])]))),128))])])):(e(),s(`div`,ye,[r[20]||=o(`div`,null,[o(`div`,{class:`text-sm text-white`},` No warm pools yet `),o(`div`,{class:`text-xs text-foreground-muted mt-1 max-w-prose mx-auto leading-body`},` Deploy your first function to see live worker pools, latency, and cold-start rate land in the tiles above. `)],-1),o(`div`,null,[c(ie,{onClick:r[0]||=e=>t.$router.push(`/functions/new`)},{default:n(()=>[c(i(re),{class:`w-4 h-4`}),r[19]||=l(` Deploy your first function `,-1)]),_:1})])]))]))}};export{H as default}; \ No newline at end of file diff --git a/backend/internal/server/ui_dist/assets/Dashboard-By9Lh_hZ.js b/backend/internal/server/ui_dist/assets/Dashboard-By9Lh_hZ.js new file mode 100644 index 00000000..f18c8a43 --- /dev/null +++ b/backend/internal/server/ui_dist/assets/Dashboard-By9Lh_hZ.js @@ -0,0 +1 @@ +import{D as e,E as t,F as n,T as r,Z as i,c as a,d as o,h as s,k as ee,m as c,r as te,s as l,u,v as d,vt as f}from"./runtime-core.esm-bundler-BMQPyJ_W.js";import{At as ne,St as re,_t as ie,jt as p,kt as ae,n as oe}from"./index-CZI-jurg.js";var se=p(`snowflake`,[[`path`,{d:`m10 20-1.25-2.5L6 18`,key:`18frcb`}],[`path`,{d:`M10 4 8.75 6.5 6 6`,key:`7mghy3`}],[`path`,{d:`m14 20 1.25-2.5L18 18`,key:`1chtki`}],[`path`,{d:`m14 4 1.25 2.5L18 6`,key:`1b4wsy`}],[`path`,{d:`m17 21-3-6h-4`,key:`15hhxa`}],[`path`,{d:`m17 3-3 6 1.5 3`,key:`11697g`}],[`path`,{d:`M2 12h6.5L10 9`,key:`kv9z4n`}],[`path`,{d:`m20 10-1.5 2 1.5 2`,key:`1swlpi`}],[`path`,{d:`M22 12h-6.5L14 15`,key:`1mxi28`}],[`path`,{d:`m4 10 1.5 2L4 14`,key:`k9enpj`}],[`path`,{d:`m7 21 3-6-1.5-3`,key:`j8hb9u`}],[`path`,{d:`m7 3 3 6h4`,key:`1otusx`}]]),m=p(`trending-up`,[[`path`,{d:`M16 7h6v6`,key:`box55l`}],[`path`,{d:`m22 7-8.5 8.5-5-5L2 17`,key:`1t1m79`}]]),h={class:`space-y-6`},ce={class:`grid grid-cols-2 md:grid-cols-4 gap-4`},le={class:`grid grid-cols-1 lg:grid-cols-3 gap-4`},ue={class:`bg-background border border-border rounded-lg p-5 lg:col-span-1`},g={class:`bg-background border border-border rounded-lg p-5 lg:col-span-2 space-y-5`},_={class:`grid grid-cols-2 gap-4 text-sm`},v={class:`text-lg font-mono text-white mt-0.5`},y={class:`text-lg font-mono text-white mt-0.5`},b={class:`text-foreground-muted text-sm`},x={class:`text-xs text-foreground-muted mt-0.5`},S={class:`space-y-2`},C={class:`flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-foreground-muted`},w={class:`flex items-center gap-1.5`},T={class:`flex items-center gap-1.5`},E={class:`grid grid-cols-1 md:grid-cols-2 gap-4`},D={class:`bg-background border border-border rounded-lg p-5 space-y-3`},O={class:`grid grid-cols-3 gap-3`},k={key:0,class:`text-xs text-danger-fg flex items-center gap-1.5 pt-1`},A={class:`bg-background border border-border rounded-lg p-5 space-y-3`},j={class:`grid grid-cols-3 gap-3`},M={key:0},N={class:`flex items-baseline justify-between mb-3`},P={class:`text-sm font-semibold text-white`},F={class:`grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4`},I={class:`flex items-start justify-between gap-2`},L={class:`min-w-0`},R={class:`text-sm font-medium text-white truncate`},z={class:`text-xs text-foreground-muted font-mono truncate`},B={class:`text-right shrink-0`},V={class:`text-xs font-mono text-white`},H={class:`grid grid-cols-3 gap-2`},de={class:`border-t border-border pt-3 text-xs`},fe={class:`mt-3 grid grid-cols-2 gap-3`},pe={class:`font-mono text-white`},me={class:`font-mono text-white`},he={class:`font-mono text-white`,title:`Average memory used per invocation vs allocated limit`},ge={class:`text-foreground-muted`},_e={class:`font-mono text-white`,title:`Average CPU cores consumed per invocation vs allocated`},ve={key:0,class:`text-foreground-muted`},ye={key:1,class:`bg-background border border-border rounded-lg p-8 text-center space-y-4`},U={__name:`Dashboard`,setup(p){let U=oe(),W=l(()=>U.metrics||{}),be=e=>U.poolHistory[e]||[],xe=e=>e==null?`—`:`${e.toFixed(1)}%`,Se=e=>e==null?`0`:e.toFixed(1),G=e=>{let t=e||0;return t>=1024?`${(t/1024).toFixed(1)} GB`:`${Math.round(t)} MB`},K=e=>{let t=Number(e)||0;return t>=1e6?`${(t/1e6).toFixed(1)}M`:t>=1e3?`${(t/1e3).toFixed(1)}k`:String(t)},q=l(()=>W.value.host?.mem_total_mb??0),J=l(()=>W.value.host?.mem_reserved_mb??0),Ce=l(()=>W.value.host?.mem_available_mb??0),Y=l(()=>Math.max(0,q.value-Ce.value)),X=l(()=>Math.max(0,q.value-Y.value)),we=l(()=>q.value>0?Y.value/q.value*100:0);r(()=>U.connect()),t(()=>U.disconnect());let Z={props:{label:String,value:[String,Number],icon:Object},setup(e){return()=>d(`div`,{class:`bg-background border border-border rounded-lg p-5 flex flex-col h-full hover:border-primary/50 transition-colors group`},[d(`div`,{class:`flex items-center justify-between mb-3`},[d(`span`,{class:`text-xs font-medium text-foreground-muted uppercase tracking-wide`},e.label),e.icon?d(e.icon,{class:`w-4 h-4 text-foreground-muted group-hover:text-primary`}):null]),d(`div`,{class:`text-2xl font-mono text-foreground leading-none`},String(e.value))])}},Te={props:{p50:Number,p95:Number,p99:Number},setup(e){return()=>{let t=[{label:`p50`,ms:e.p50,color:`bg-success/70`},{label:`p95`,ms:e.p95,color:`bg-warning/70`},{label:`p99`,ms:e.p99,color:`bg-danger/70`}],n=Math.max(e.p50||0,e.p95||0,e.p99||0,1);return d(`div`,{class:`space-y-2.5`},t.map(e=>{let t=e.ms==null?0:e.ms/n*100;return d(`div`,{class:`space-y-1`},[d(`div`,{class:`flex items-baseline justify-between text-xs`},[d(`span`,{class:`font-mono uppercase text-foreground-muted tracking-wider`},e.label),d(`span`,{class:`font-mono text-white`},e.ms==null?`—`:`${e.ms}ms`)]),d(`div`,{class:`h-1.5 bg-surface rounded overflow-hidden`},[d(`div`,{class:`h-full ${e.color} transition-[width] duration-500 ease-out`,style:{width:`${t.toFixed(1)}%`}})])])}))}}},Q={props:{label:String,value:[String,Number]},setup(e){return()=>d(`div`,{class:`bg-surface border border-border rounded p-3 flex flex-col h-full`},[d(`div`,{class:`text-xs uppercase tracking-wider text-foreground-muted`},e.label),d(`div`,{class:`text-lg font-mono text-white mt-0.5`},String(e.value??0))])}},$={props:{label:String,value:[String,Number]},setup(e){return()=>d(`div`,{class:`bg-surface border border-border rounded p-2.5 flex flex-col h-full`},[d(`div`,{class:`text-xs uppercase tracking-wider text-foreground-muted`},e.label),d(`div`,{class:`text-base font-mono text-white mt-0.5 leading-none`},String(e.value??0))])}},Ee={props:{total:{type:Number,required:!0},segments:{type:Array,required:!0}},setup(e){return()=>{let t=e.total>0?e.total:1;return d(`div`,{class:`h-2.5 bg-surface rounded overflow-hidden flex`,role:`img`,"aria-label":e.segments.map(t=>`${t.label}: ${t.value} of ${e.total}`).join(`; `)},e.segments.map(e=>d(`div`,{class:`h-full ${e.color}`,style:{width:`${(e.value/t*100).toFixed(2)}%`},title:`${e.label}: ${e.value}`})))}}},De={props:{points:{type:Array,default:()=>[]}},setup(e){return()=>{let t=e.points||[];if(t.length<2)return d(`div`,{class:`h-8 flex items-center text-xs text-foreground-muted`},`Collecting samples…`);let n=Math.max(...t,1),r=100/(t.length-1),i=t.map((e,t)=>{let i=(t*r).toFixed(2),a=(32-e/n*32).toFixed(2);return`${t===0?`M`:`L`}${i},${a}`}).join(` `);return d(`svg`,{viewBox:`0 0 100 32`,class:`w-full h-8 text-primary`,preserveAspectRatio:`none`},[d(`path`,{d:i,fill:`none`,stroke:`currentColor`,"stroke-width":`1.5`})])}}};return(t,r)=>(e(),o(`div`,h,[r[21]||=a(`div`,null,[a(`h1`,{class:`text-xl font-semibold text-white tracking-tight`},` System Overview `),a(`p`,{class:`text-sm text-foreground-muted mt-1.5 max-w-prose leading-body`},` Live platform health and activity. `)],-1),a(`div`,ce,[s(Z,{label:`Functions`,value:i(U).functionsCount,icon:i(ae)},null,8,[`value`,`icon`]),s(Z,{label:`In flight`,value:W.value.active_requests??0,icon:i(ne)},null,8,[`value`,`icon`]),s(Z,{label:`Invocations`,value:K(W.value.totals?.invocations??0),icon:i(m)},null,8,[`value`,`icon`]),s(Z,{label:`Cold starts`,value:xe(W.value.rates?.cold_start_pct),icon:i(se)},null,8,[`value`,`icon`])]),a(`div`,le,[a(`div`,ue,[r[1]||=a(`div`,{class:`mb-3`},[a(`h2`,{class:`text-sm font-semibold text-white`},` Response time `),a(`div`,{class:`text-xs text-foreground-muted mt-1`},` Invocation latency by percentile. `)],-1),s(Te,{p50:W.value.latency_ms?.p50,p95:W.value.latency_ms?.p95,p99:W.value.latency_ms?.p99},null,8,[`p50`,`p95`,`p99`])]),a(`div`,g,[r[6]||=a(`div`,null,[a(`h2`,{class:`text-sm font-semibold text-white`},` Host machine `),a(`div`,{class:`text-xs text-foreground-muted mt-1`},` Capacity and current memory use. `)],-1),a(`div`,_,[a(`div`,null,[r[2]||=a(`div`,{class:`text-xs uppercase tracking-wider text-foreground-muted`},` CPU cores `,-1),a(`div`,v,f(W.value.host?.num_cpu??`?`),1)]),a(`div`,null,[r[3]||=a(`div`,{class:`text-xs uppercase tracking-wider text-foreground-muted`},` Memory in use `,-1),a(`div`,y,[c(f(G(Y.value))+` `,1),a(`span`,b,`/ `+f(G(q.value)),1)]),a(`div`,x,f(we.value.toFixed(1))+`% used · `+f(G(J.value))+` reserved by warm pools `,1)])]),a(`div`,S,[s(Ee,{total:q.value,segments:[{label:`In use`,value:Y.value,color:`bg-info/70`},{label:`Free`,value:X.value,color:`bg-success/40`}]},null,8,[`total`,`segments`]),a(`div`,C,[a(`span`,w,[r[4]||=a(`span`,{class:`w-2 h-2 rounded-full bg-info/70`},null,-1),c(` `+f(G(Y.value))+` in use `,1)]),a(`span`,T,[r[5]||=a(`span`,{class:`w-2 h-2 rounded-full bg-success/40`},null,-1),c(` `+f(G(X.value))+` free `,1)]),a(`span`,null,f(G(J.value))+` reserved for warm pools `,1)])])])]),a(`div`,E,[a(`div`,D,[r[8]||=a(`div`,null,[a(`h2`,{class:`text-sm font-semibold text-white`},` Builds `),a(`div`,{class:`text-xs text-foreground-muted mt-1`},` Deployment work in progress. `)],-1),a(`div`,O,[s(Q,{label:`In queue`,value:W.value.build_queue?.pending??0},null,8,[`value`]),s(Q,{label:`Build workers`,value:W.value.build_queue?.workers??0},null,8,[`value`]),s(Q,{label:`Built so far`,value:K(W.value.totals?.builds??0)},null,8,[`value`])]),(W.value.totals?.build_errors??0)>0?(e(),o(`div`,k,[r[7]||=a(`span`,{class:`w-1.5 h-1.5 rounded-full bg-danger`},null,-1),c(` `+f(W.value.totals.build_errors)+` build`+f(W.value.totals.build_errors===1?` has`:`s have`)+` failed since start `,1)])):u(``,!0)]),a(`div`,A,[r[9]||=a(`div`,null,[a(`h2`,{class:`text-sm font-semibold text-white`},` Sandbox activity `),a(`div`,{class:`text-xs text-foreground-muted mt-1`},` Current sandbox reuse and startup activity. `)],-1),a(`div`,j,[s(Q,{label:`Running now`,value:W.value.sandbox?.active??0},null,8,[`value`]),s(Q,{label:`Reused`,value:K(W.value.totals?.warm_hits??0)},null,8,[`value`]),s(Q,{label:`Spawned fresh`,value:K(W.value.totals?.cold_starts??0)},null,8,[`value`])])])]),(W.value.pools||[]).length?(e(),o(`div`,M,[a(`div`,N,[a(`div`,null,[a(`h2`,P,` Warm pools (`+f(W.value.pools.length)+`) `,1),r[10]||=a(`div`,{class:`text-xs text-foreground-muted mt-1`},` Ready sandboxes by function. `,-1)])]),a(`div`,F,[(e(!0),o(te,null,ee(W.value.pools,t=>(e(),o(`div`,{key:t.function_id,class:`bg-background border border-border rounded-lg p-4 space-y-3`},[a(`div`,I,[a(`div`,L,[a(`div`,R,f(t.function_name||t.function_id),1),a(`div`,z,f(t.function_id),1)]),a(`div`,B,[r[12]||=a(`div`,{class:`text-xs text-foreground-muted`},` Target / cap `,-1),a(`div`,V,[c(f(t.target)+` `,1),r[11]||=a(`span`,{class:`text-foreground-muted`},`/`,-1),c(` `+f(t.dynamic_max),1)])])]),a(`div`,H,[s($,{label:`Ready`,value:t.idle},null,8,[`value`]),s($,{label:`Busy`,value:t.busy},null,8,[`value`]),s($,{label:`Calls / sec`,value:Se(t.rate_ewma)},null,8,[`value`])]),a(`div`,null,[s(De,{points:be(t.function_id)},null,8,[`points`]),r[13]||=a(`div`,{class:`text-xs text-foreground-muted mt-1`},` Recent calls per second (last 5 min) `,-1)]),a(`details`,de,[r[18]||=a(`summary`,{class:`cursor-pointer text-foreground-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary`},` Runtime details `,-1),a(`div`,fe,[a(`div`,null,[r[14]||=a(`div`,{class:`text-foreground-muted`},` Spawned · killed `,-1),a(`div`,pe,f(t.spawned)+` · `+f(t.killed),1)]),a(`div`,null,[r[15]||=a(`div`,{class:`text-foreground-muted`},` Avg latency `,-1),a(`div`,me,f(t.latency_ewma_ms?.toFixed?.(1)??0)+` ms `,1)]),a(`div`,null,[r[16]||=a(`div`,{class:`text-foreground-muted`},` Avg memory `,-1),a(`div`,he,[c(f(t.mem_used_avg_mb>0?`~`+Math.round(t.mem_used_avg_mb):i(`—`))+` `,1),a(`span`,ge,`/ `+f(t.mem_limit_mb)+` MB`,1)])]),a(`div`,null,[r[17]||=a(`div`,{class:`text-foreground-muted`},` Avg CPU `,-1),a(`div`,_e,[c(f(t.cpu_frac_avg>0&&t.cpu_limit>0?(t.cpu_frac_avg*t.cpu_limit).toFixed(2):i(`—`))+` `,1),t.cpu_limit>0?(e(),o(`span`,ve,`/ `+f(t.cpu_limit)+` CPU`,1)):u(``,!0)])])])])]))),128))])])):(e(),o(`div`,ye,[r[20]||=a(`div`,null,[a(`div`,{class:`text-sm text-white`},` No warm pools yet `),a(`div`,{class:`text-xs text-foreground-muted mt-1 max-w-prose mx-auto leading-body`},` Deploy a function to start collecting runtime metrics. `)],-1),a(`div`,null,[s(ie,{onClick:r[0]||=e=>t.$router.push(`/functions/new`)},{default:n(()=>[s(i(re),{class:`w-4 h-4`}),r[19]||=c(` Deploy your first function `,-1)]),_:1})])]))]))}};export{U as default}; \ No newline at end of file diff --git a/backend/internal/server/ui_dist/assets/Deployments-9vU6Tb3I.js b/backend/internal/server/ui_dist/assets/Deployments-9vU6Tb3I.js new file mode 100644 index 00000000..4ed4de3f --- /dev/null +++ b/backend/internal/server/ui_dist/assets/Deployments-9vU6Tb3I.js @@ -0,0 +1,3 @@ +import{C as e,D as t,F as n,G as r,P as i,T as ee,Z as a,c as o,d as s,gt as c,h as l,j as te,k as u,l as d,m as f,r as p,s as m,u as h,v as g,vt as _}from"./runtime-core.esm-bundler-BMQPyJ_W.js";import{n as ne}from"./clock-Dx_vxhwd.js";import{n as re,t as v}from"./git-compare-CRDCiUNE.js";import{t as ie}from"./refresh-cw-DihaytVM.js";import{t as y}from"./rotate-ccw-DWDBjUXf.js";import{B as ae,Bt as b,R as oe,_t as x,b as S,et as se,gt as ce,pt as le,r as ue,x as de}from"./index-CZI-jurg.js";import{t as fe}from"./Drawer-B765_4al.js";import{t as C}from"./StatusBadge-D05dwaq1.js";import{t as pe}from"./rollbackDiff-DsaWcdbl.js";var me={class:`space-y-6`},he={class:`flex items-center justify-between`},ge={class:`text-sm text-foreground-muted mt-1.5 max-w-prose leading-body`},_e={class:`flex items-center gap-2`},ve={key:0,class:`border-y border-border py-3 flex items-center gap-3`},ye={class:`flex-1 min-w-0`},be={class:`flex items-center gap-2 flex-wrap`},xe={class:`text-xs px-2 py-0.5 rounded bg-success/15 text-success border border-success/30 font-mono`},Se={key:0,class:`text-xs px-2 py-0.5 rounded bg-warning-tint text-warning-fg border border-warning-ring`},Ce={class:`text-xs text-foreground-muted mt-1 font-mono truncate`},we={key:1,class:`bg-danger-tint border border-danger-ring rounded p-3 text-xs text-danger-fg`,role:`alert`},Te={class:`bg-background border border-border rounded-lg overflow-x-auto`},Ee={class:`sm:hidden divide-y divide-border`},De=[`onClick`],Oe={class:`flex items-start justify-between gap-2`},ke={class:`min-w-0 flex-1`},Ae={class:`flex items-center gap-2 flex-wrap`},je={key:0,class:`px-1.5 py-0.5 rounded text-xs bg-success-tint text-success-fg border border-success-ring`},Me={class:`mt-1 flex flex-wrap items-center gap-x-3 gap-y-0.5 text-xs text-foreground-muted`},Ne={key:0,class:`font-mono`},Pe={key:1},Fe={key:0,class:`px-6 py-8 text-center text-sm text-foreground-muted`},Ie={class:`hidden sm:table w-full text-sm text-left`},Le={class:`divide-y divide-border`},Re=[`onClick`],ze={class:`px-6 py-4 font-mono text-xs`},Be={class:`flex items-center gap-2`},Ve={key:0,class:`px-1.5 py-0.5 rounded text-xs bg-success-tint text-success-fg border border-success-ring normal-case`},He={class:`px-6 py-4 text-foreground`},Ue={class:`px-6 py-4`},We={class:`px-6 py-4 text-foreground-muted text-xs hidden md:table-cell`},Ge={class:`px-6 py-4 text-foreground-muted font-mono text-xs hidden sm:table-cell`},Ke={class:`px-6 py-4 text-foreground-muted font-mono text-xs hidden xl:table-cell`},qe={class:`inline-flex items-center gap-2 justify-end`},Je={key:2,class:`text-foreground-muted/50`},Ye={key:3,class:`text-foreground-muted/30`},Xe={key:0},Ze={key:0,class:`p-6 text-sm text-foreground-muted`},Qe={key:1,class:`p-5 space-y-4`},$e={class:`flex items-center gap-2 flex-wrap`},et={key:0,class:`inline-flex items-center px-2.5 py-1 rounded text-xs border bg-background font-mono text-foreground-muted`},tt={class:`grid grid-cols-2 gap-3 text-sm`},nt={key:0},rt={class:`bg-danger-tint border border-danger-ring rounded p-3 text-xs text-danger-fg font-mono whitespace-pre-wrap break-words`},it={class:`flex items-center justify-between mb-2`},at={key:0,class:`text-xs text-success-fg`},ot={class:`bg-surface border border-border rounded p-3 text-xs text-foreground font-mono overflow-auto max-h-96 whitespace-pre-wrap break-words`},st=Object.assign({name:`DeploymentsView`},{__name:`Deployments`,setup(st){let w=ce(),ct=le(),T=m(()=>ct.params.name),E=r(null),D=r(null),O=r([]),k=r(!1),A=r(``),j=r(!1),M=e=>e&&e.status===`succeeded`&&e.code_hash&&!I(e),N=m(()=>O.value.find(e=>I(e))?.id||null),P=e=>e&&e.status===`succeeded`&&e.code_hash&&!I(e)&&N.value,F=async e=>{if(!E.value||!e?.id||j.value)return;let t=(e.code_hash||``).slice(0,12),n=`Code hash ${t}. Current ${D.value?`v`+D.value.version:`version`} stays in history.`;try{let r=(await S(e.id))?.data?.snapshot;if(r&&D.value){let i=pe(D.value,r);n=i.length?`Rolling back to v${e.version} (code ${t}) will also change:\n\n${i.join(` +`)}\n\nSecrets keep their current values; they aren't part of the rollback.`:`Rolling back to v${e.version} (code ${t}). Settings and env are already identical, so only the code changes.`}}catch{}if(N.value&&N.value!==e.id&&(n+=`\n\nFull source diff: ${window.location.origin}/web/functions/${T.value}/diff?from=${e.id}&to=${N.value}`),await w.ask({title:`Restore v${e.version}?`,message:n,confirmLabel:`Rollback`})){j.value=!0;try{await se(E.value,{deployment_id:e.id}),await G()}catch(e){let t=e.response?.data?.error?.code||``,n=e.response?.data?.error?.message||e.message||`Rollback failed`;t===`VERSION_GCD`?w.notify({title:`Version unavailable`,message:`This version has been garbage-collected and can no longer be restored.\n\n${n}`,danger:!0}):w.notify({title:`Rollback failed`,message:n,danger:!0})}finally{j.value=!1}}},I=e=>D.value&&e.version===D.value.version&&e.status===`succeeded`,L=r(!1),R=r(null),z=r([]),B=r(!1),V=null,lt=m(()=>R.value?`Deployment · ${R.value.id?.substring(0,14)}`:`Deployment`),ut=m(()=>z.value.join(` +`)),H=e=>e?new Date(e).toLocaleString():`—`,U={props:{label:String,value:[String,Number],mono:Boolean},setup(e){return()=>g(`div`,{class:`bg-surface border border-border rounded p-3`},[g(`div`,{class:`text-xs uppercase tracking-wider text-foreground-muted mb-1`},e.label),g(`div`,{class:[`text-sm text-white`,e.mono&&`font-mono text-xs`].filter(Boolean)},String(e.value))])}},W=async()=>{let e=((await ae()).data.functions||[]).find(e=>e.name===T.value);if(!e)throw Error(`Function "${T.value}" not found`);return e},G=async()=>{k.value=!0,A.value=``;try{let e=await W();E.value=e.id,D.value=e;let t=await oe(E.value,100);O.value=t.data.deployments||[]}catch(e){A.value=e.message||`Failed to load deployments`}finally{k.value=!1}},K=async e=>{R.value=e,L.value=!0,z.value=[],B.value=!1;try{let t=await S(e.id);R.value={...e,...t.data}}catch{}try{let t=await de(e.id,0,1e3);z.value=(t.data.logs||[]).map(q)}catch{}(e.status===`queued`||e.status===`building`)&&dt(e.id)},q=e=>`[${e.stream||`log`}] ${e.line}`,dt=e=>{J();let t=new EventSource(`/api/v1/deployments/${e}/stream`);V=t,B.value=!0,t.addEventListener(`log`,e=>{try{let t=JSON.parse(e.data);z.value.push(q(t))}catch{}}),t.addEventListener(`succeeded`,()=>J(!0)),t.addEventListener(`failed`,()=>J(!0)),t.onerror=()=>{t.readyState===EventSource.CLOSED&&J()}},J=(e=!1)=>{if(V){try{V.close()}catch{}V=null}B.value=!1,e&&R.value&&(S(R.value.id).then(e=>{R.value={...R.value,...e.data}}).catch(()=>{}),G())};i(L,e=>{e||J()});let Y=ue(),X=null,Z=()=>{X||=setTimeout(()=>{X=null,G()},300)},Q=null,$=null;return ee(()=>{G(),Q=Y.subscribe(`deployment`,Z),$=Y.subscribe(`function`,Z)}),e(()=>{J(),Q&&=(Q(),null),$&&=($(),null),X&&=(clearTimeout(X),null)}),(e,r)=>{let i=te(`router-link`);return t(),s(`div`,me,[o(`div`,he,[o(`div`,null,[r[5]||=o(`h1`,{class:`text-xl font-semibold text-white tracking-tight`},` Deployments `,-1),o(`p`,ge,[r[4]||=f(` History for `,-1),l(i,{to:`/functions/${T.value}`,class:`text-white underline`},{default:n(()=>[f(_(T.value),1)]),_:1},8,[`to`])])]),o(`div`,_e,[l(x,{variant:`secondary`,onClick:r[0]||=t=>e.$router.push(`/functions/${T.value}`)},{default:n(()=>[l(a(re),{class:`w-4 h-4 mr-2`}),r[6]||=f(` New version `,-1)]),_:1}),l(x,{variant:`secondary`,onClick:G},{default:n(()=>[l(a(ie),{class:c([`w-4 h-4 mr-2`,{"animate-spin":k.value}])},null,8,[`class`]),r[7]||=f(` Refresh `,-1)]),_:1})])]),D.value?(t(),s(`div`,ve,[l(a(ne),{class:`w-4 h-4 text-success-fg shrink-0`}),o(`div`,ye,[o(`div`,be,[r[8]||=o(`span`,{class:`text-sm text-white font-medium`},`Currently serving`,-1),o(`span`,xe,` v`+_(D.value.version),1),D.value.status===`active`?h(``,!0):(t(),s(`span`,Se,` status: `+_(D.value.status),1))]),o(`div`,Ce,` hash: `+_(D.value.code_hash||a(`—`))+` · runtime: `+_(D.value.runtime)+` · updated `+_(H(D.value.updated_at)),1)])])):h(``,!0),A.value?(t(),s(`div`,we,_(A.value),1)):h(``,!0),o(`div`,Te,[o(`ul`,Ee,[(t(!0),s(p,null,u(O.value,e=>(t(),s(`li`,{key:e.id,class:c([`px-4 py-3 cursor-pointer active:bg-surface-hover/50 transition-colors`,I(e)?`bg-success/5`:``]),onClick:t=>K(e)},[o(`div`,Oe,[o(`div`,ke,[o(`div`,Ae,[o(`span`,{class:c([`font-mono text-xs`,I(e)?`text-white font-semibold`:`text-foreground-muted`])},`v`+_(e.version),3),l(C,{status:e.status},null,8,[`status`]),I(e)?(t(),s(`span`,je,`Active`)):h(``,!0)]),o(`div`,Me,[o(`span`,null,_(H(e.submitted_at)),1),e.duration_ms==null?h(``,!0):(t(),s(`span`,Ne,_(e.duration_ms)+` ms`,1)),e.phase?(t(),s(`span`,Pe,_(e.phase),1)):h(``,!0)])]),o(`div`,{class:`shrink-0 flex items-center gap-1`,onClick:r[1]||=b(()=>{},[`stop`])},[P(e)?(t(),d(i,{key:0,to:{name:`function-diff`,params:{name:T.value},query:{from:e.id,to:N.value}},class:`text-foreground-muted hover:text-white text-xs flex items-center gap-1 px-2 py-1`,title:`Compare with active version`},{default:n(()=>[l(a(v),{class:`w-3 h-3`}),r[9]||=f(` Compare `,-1)]),_:1},8,[`to`])):h(``,!0),M(e)?(t(),d(x,{key:1,size:`xs`,variant:`ghost`,disabled:j.value,onClick:t=>F(e)},{default:n(()=>[l(a(y),{class:`w-3 h-3`}),r[10]||=f(` Rollback `,-1)]),_:1},8,[`disabled`,`onClick`])):h(``,!0)])])],10,De))),128)),!k.value&&O.value.length===0?(t(),s(`li`,Fe,` No deployments yet. `)):h(``,!0)]),o(`table`,Ie,[r[14]||=o(`thead`,{class:`text-xs text-foreground-muted uppercase bg-surface border-b border-border`},[o(`tr`,null,[o(`th`,{class:`px-6 py-3 font-medium`},` Version `),o(`th`,{class:`px-6 py-3 font-medium`},` Submitted `),o(`th`,{class:`px-6 py-3 font-medium`},` Status `),o(`th`,{class:`px-6 py-3 font-medium hidden md:table-cell`},` Phase `),o(`th`,{class:`px-6 py-3 font-medium hidden sm:table-cell`},` Duration `),o(`th`,{class:`px-6 py-3 font-medium hidden xl:table-cell`},` Deployment ID `),o(`th`,{class:`px-6 py-3 font-medium text-right`},` Actions `)])],-1),o(`tbody`,Le,[(t(!0),s(p,null,u(O.value,e=>(t(),s(`tr`,{key:e.id,class:c([`hover:bg-surface/50 transition-colors cursor-pointer`,I(e)?`bg-success/5`:``]),onClick:t=>K(e)},[o(`td`,ze,[o(`div`,Be,[o(`span`,{class:c([`text-white`,I(e)?`font-semibold`:`text-foreground-muted`])},`v`+_(e.version),3),I(e)?(t(),s(`span`,Ve,`Active`)):h(``,!0)])]),o(`td`,He,_(H(e.submitted_at)),1),o(`td`,Ue,[l(C,{status:e.status},null,8,[`status`])]),o(`td`,We,_(e.phase||a(`—`)),1),o(`td`,Ge,_(e.duration_ms==null?a(`—`):e.duration_ms+`ms`),1),o(`td`,Ke,_(e.id?.substring(0,14)),1),o(`td`,{class:`px-6 py-4 text-right text-xs`,onClick:r[2]||=b(()=>{},[`stop`])},[o(`div`,qe,[P(e)?(t(),d(i,{key:0,to:{name:`function-diff`,params:{name:T.value},query:{from:e.id,to:N.value}},class:`text-foreground-muted hover:text-white flex items-center gap-1`,title:`Compare with active version`},{default:n(()=>[l(a(v),{class:`w-3 h-3`}),r[11]||=f(` Compare `,-1)]),_:1},8,[`to`])):h(``,!0),M(e)?(t(),d(x,{key:1,size:`xs`,variant:`ghost`,disabled:j.value,onClick:t=>F(e)},{default:n(()=>[l(a(y),{class:`w-3 h-3`}),r[12]||=f(` Rollback `,-1)]),_:1},8,[`disabled`,`onClick`])):h(``,!0),!M(e)&&e.source===`rollback`?(t(),s(`span`,Je,`via rollback`)):!P(e)&&!M(e)?(t(),s(`span`,Ye,_(a(`—`)),1)):h(``,!0)])])],10,Re))),128)),!k.value&&O.value.length===0?(t(),s(`tr`,Xe,[...r[13]||=[o(`td`,{colspan:`7`,class:`px-6 py-8 text-center text-foreground-muted`},` No deployments yet. `,-1)]])):h(``,!0)])])]),l(fe,{modelValue:L.value,"onUpdate:modelValue":r[3]||=e=>L.value=e,title:lt.value,width:`640px`},{default:n(()=>[R.value?(t(),s(`div`,Qe,[o(`div`,$e,[l(C,{status:R.value.status},null,8,[`status`]),R.value.phase?(t(),s(`span`,et,_(R.value.phase),1)):h(``,!0)]),o(`div`,tt,[l(U,{label:`Version`,value:`v${R.value.version}`,mono:``},null,8,[`value`]),l(U,{label:`Duration`,value:R.value.duration_ms==null?a(`—`):R.value.duration_ms+` ms`},null,8,[`value`]),l(U,{label:`Submitted`,value:H(R.value.submitted_at)},null,8,[`value`]),l(U,{label:`Finished`,value:R.value.finished_at?H(R.value.finished_at):a(`—`)},null,8,[`value`])]),R.value.error_message?(t(),s(`div`,nt,[r[15]||=o(`h3`,{class:`text-xs uppercase tracking-wider text-foreground-muted mb-2`},` Error `,-1),o(`pre`,rt,_(R.value.error_message),1)])):h(``,!0),o(`div`,null,[o(`div`,it,[r[16]||=o(`h3`,{class:`text-xs uppercase tracking-wider text-foreground-muted`},` Build log `,-1),B.value?(t(),s(`span`,at,`live`)):h(``,!0)]),o(`pre`,ot,_(ut.value||`(no logs available)`),1)])])):(t(),s(`div`,Ze,` Nothing selected. `))]),_:1},8,[`modelValue`,`title`])])}}});export{st as default}; \ No newline at end of file diff --git a/backend/internal/server/ui_dist/assets/Deployments-CrxzN_jC.js b/backend/internal/server/ui_dist/assets/Deployments-CrxzN_jC.js deleted file mode 100644 index 4e83b1f4..00000000 --- a/backend/internal/server/ui_dist/assets/Deployments-CrxzN_jC.js +++ /dev/null @@ -1,3 +0,0 @@ -import{C as e,D as t,N as n,P as r,T as i,W as a,X as o,_t as s,c,d as l,h as u,ht as d,j as ee,k as f,l as p,m,r as h,s as g,u as _,v}from"./runtime-core.esm-bundler-DWJwptQ-.js";import{n as te}from"./clock-CYEi9Knb.js";import{n as ne,t as y}from"./git-compare-DoufYPrI.js";import{t as re}from"./refresh-cw-BiUNRBGx.js";import{t as b}from"./rotate-ccw-B9grc64w.js";import{B as ie,R as ae,_t as x,b as S,et as oe,gt as se,pt as ce,r as le,x as ue,zt as C}from"./index-B93KhQc5.js";import{t as de}from"./Drawer-CNvPia4g.js";import{t as w}from"./StatusBadge-C3Y8qWdJ.js";import{t as fe}from"./rollbackDiff-DsaWcdbl.js";var pe={class:`space-y-6`},me={class:`flex items-center justify-between`},he={class:`text-sm text-foreground-muted mt-1.5 max-w-prose leading-body`},ge={class:`flex items-center gap-2`},_e={key:0,class:`bg-background border border-border rounded-lg p-4 flex items-center gap-4`},ve={class:`w-10 h-10 rounded-md bg-success/15 border border-success/30 flex items-center justify-center shrink-0`},ye={class:`flex-1 min-w-0`},be={class:`flex items-center gap-2 flex-wrap`},xe={class:`text-xs px-2 py-0.5 rounded bg-success/15 text-success border border-success/30 font-mono`},Se={key:0,class:`text-xs px-2 py-0.5 rounded bg-amber-500/15 text-amber-400 border border-amber-500/30`},Ce={class:`text-xs text-foreground-muted mt-1 font-mono truncate`},we={key:1,class:`bg-red-950/30 border border-red-900/40 rounded p-3 text-xs text-red-300`},Te={class:`bg-background border border-border rounded-lg overflow-x-auto`},Ee={class:`sm:hidden divide-y divide-border`},De=[`onClick`],Oe={class:`flex items-start justify-between gap-2`},ke={class:`min-w-0 flex-1`},Ae={class:`flex items-center gap-2 flex-wrap`},je={key:0,class:`px-1.5 py-0.5 rounded text-[10px] bg-success/15 text-success border border-success/30`},Me={class:`mt-1 flex flex-wrap items-center gap-x-3 gap-y-0.5 text-[11px] text-foreground-muted`},Ne={key:0,class:`font-mono`},Pe={key:1},Fe={key:0,class:`px-6 py-8 text-center text-sm text-foreground-muted`},Ie={class:`hidden sm:table w-full text-sm text-left`},Le={class:`divide-y divide-border`},Re=[`onClick`],ze={class:`px-6 py-4 font-mono text-xs`},Be={class:`flex items-center gap-2`},Ve={key:0,class:`px-1.5 py-0.5 rounded text-[10px] bg-success/15 text-success border border-success/30 normal-case`},He={class:`px-6 py-4 text-foreground`},Ue={class:`px-6 py-4`},We={class:`px-6 py-4 text-foreground-muted text-xs hidden md:table-cell`},Ge={class:`px-6 py-4 text-foreground-muted font-mono text-xs hidden sm:table-cell`},Ke={class:`px-6 py-4 text-foreground-muted font-mono text-xs hidden xl:table-cell`},qe={class:`inline-flex items-center gap-2 justify-end`},Je={key:2,class:`text-foreground-muted/50`},Ye={key:3,class:`text-foreground-muted/30`},Xe={key:0},Ze={key:0,class:`p-6 text-sm text-foreground-muted`},Qe={key:1,class:`p-5 space-y-4`},$e={class:`flex items-center gap-2 flex-wrap`},et={key:0,class:`inline-flex items-center px-2.5 py-1 rounded text-xs border bg-background font-mono text-foreground-muted`},tt={class:`grid grid-cols-2 gap-3 text-sm`},nt={key:0},rt={class:`bg-red-950/30 border border-red-900/40 rounded p-3 text-xs text-red-300 font-mono whitespace-pre-wrap break-words`},it={class:`flex items-center justify-between mb-2`},at={key:0,class:`text-[10px] text-green-400`},ot={class:`bg-surface border border-border rounded p-3 text-xs text-foreground font-mono overflow-auto max-h-96 whitespace-pre-wrap break-words`},st=Object.assign({name:`DeploymentsView`},{__name:`Deployments`,setup(st){let T=se(),ct=ce(),E=g(()=>ct.params.name),D=a(null),O=a(null),k=a([]),A=a(!1),j=a(``),M=a(!1),N=e=>e&&e.status===`succeeded`&&e.code_hash&&!L(e),P=g(()=>k.value.find(e=>L(e))?.id||null),F=e=>e&&e.status===`succeeded`&&e.code_hash&&!L(e)&&P.value,I=async e=>{if(!D.value||!e?.id||M.value)return;let t=(e.code_hash||``).slice(0,12),n=`Code hash ${t}. Current ${O.value?`v`+O.value.version:`version`} stays in history.`;try{let r=(await S(e.id))?.data?.snapshot;if(r&&O.value){let i=fe(O.value,r);n=i.length?`Rolling back to v${e.version} (code ${t}) will also change:\n\n${i.join(` -`)}\n\nSecrets keep their current values — they aren't part of the rollback.`:`Rolling back to v${e.version} (code ${t}). Settings and env are already identical, so only the code changes.`}}catch{}if(P.value&&P.value!==e.id&&(n+=`\n\nFull source diff: ${window.location.origin}/web/functions/${E.value}/diff?from=${e.id}&to=${P.value}`),await T.ask({title:`Restore v${e.version}?`,message:n,confirmLabel:`Rollback`})){M.value=!0;try{await oe(D.value,{deployment_id:e.id}),await G()}catch(e){let t=e.response?.data?.error?.code||``,n=e.response?.data?.error?.message||e.message||`Rollback failed`;t===`VERSION_GCD`?T.notify({title:`Version unavailable`,message:`This version has been garbage-collected and can no longer be restored.\n\n${n}`,danger:!0}):T.notify({title:`Rollback failed`,message:n,danger:!0})}finally{M.value=!1}}},L=e=>O.value&&e.version===O.value.version&&e.status===`succeeded`,R=a(!1),z=a(null),B=a([]),V=a(!1),H=null,lt=g(()=>z.value?`Deployment · ${z.value.id?.substring(0,14)}`:`Deployment`),ut=g(()=>B.value.join(` -`)),U=e=>e?new Date(e).toLocaleString():`—`,W={props:{label:String,value:[String,Number],mono:Boolean},setup(e){return()=>v(`div`,{class:`bg-surface border border-border rounded p-3`},[v(`div`,{class:`text-[10px] uppercase tracking-wider text-foreground-muted mb-1`},e.label),v(`div`,{class:[`text-sm text-white`,e.mono&&`font-mono text-xs`].filter(Boolean)},String(e.value))])}},dt=async()=>{let e=((await ie()).data.functions||[]).find(e=>e.name===E.value);if(!e)throw Error(`Function "${E.value}" not found`);return e},G=async()=>{A.value=!0,j.value=``;try{let e=await dt();D.value=e.id,O.value=e;let t=await ae(D.value,100);k.value=t.data.deployments||[]}catch(e){j.value=e.message||`Failed to load deployments`}finally{A.value=!1}},K=async e=>{z.value=e,R.value=!0,B.value=[],V.value=!1;try{let t=await S(e.id);z.value={...e,...t.data}}catch{}try{let t=await ue(e.id,0,1e3);B.value=(t.data.logs||[]).map(q)}catch{}(e.status===`queued`||e.status===`building`)&&ft(e.id)},q=e=>`[${e.stream||`log`}] ${e.line}`,ft=e=>{J();let t=new EventSource(`/api/v1/deployments/${e}/stream`);H=t,V.value=!0,t.addEventListener(`log`,e=>{try{let t=JSON.parse(e.data);B.value.push(q(t))}catch{}}),t.addEventListener(`succeeded`,()=>J(!0)),t.addEventListener(`failed`,()=>J(!0)),t.onerror=()=>{t.readyState===EventSource.CLOSED&&J()}},J=(e=!1)=>{if(H){try{H.close()}catch{}H=null}V.value=!1,e&&z.value&&(S(z.value.id).then(e=>{z.value={...z.value,...e.data}}).catch(()=>{}),G())};n(R,e=>{e||J()});let Y=le(),X=null,Z=()=>{X||=setTimeout(()=>{X=null,G()},300)},Q=null,$=null;return i(()=>{G(),Q=Y.subscribe(`deployment`,Z),$=Y.subscribe(`function`,Z)}),e(()=>{J(),Q&&=(Q(),null),$&&=($(),null),X&&=(clearTimeout(X),null)}),(e,n)=>{let i=ee(`router-link`);return t(),l(`div`,pe,[c(`div`,me,[c(`div`,null,[n[5]||=c(`h1`,{class:`text-xl font-semibold text-white tracking-tight`},` Deployments `,-1),c(`p`,he,[n[4]||=m(` History for `,-1),u(i,{to:`/functions/${E.value}`,class:`text-white underline`},{default:r(()=>[m(s(E.value),1)]),_:1},8,[`to`])])]),c(`div`,ge,[u(x,{variant:`secondary`,onClick:n[0]||=t=>e.$router.push(`/functions/${E.value}`)},{default:r(()=>[u(o(ne),{class:`w-4 h-4 mr-2`}),n[6]||=m(` Deploy New Version `,-1)]),_:1}),u(x,{variant:`secondary`,onClick:G},{default:r(()=>[u(o(re),{class:d([`w-4 h-4 mr-2`,{"animate-spin":A.value}])},null,8,[`class`]),n[7]||=m(` Refresh `,-1)]),_:1})])]),O.value?(t(),l(`div`,_e,[c(`div`,ve,[u(o(te),{class:`w-5 h-5 text-success`})]),c(`div`,ye,[c(`div`,be,[n[8]||=c(`span`,{class:`text-sm text-white font-medium`},`Currently serving`,-1),c(`span`,xe,` v`+s(O.value.version),1),O.value.status===`active`?_(``,!0):(t(),l(`span`,Se,` status: `+s(O.value.status),1))]),c(`div`,Ce,` hash: `+s(O.value.code_hash||o(`—`))+` · runtime: `+s(O.value.runtime)+` · updated `+s(U(O.value.updated_at)),1)])])):_(``,!0),j.value?(t(),l(`div`,we,s(j.value),1)):_(``,!0),c(`div`,Te,[c(`ul`,Ee,[(t(!0),l(h,null,f(k.value,e=>(t(),l(`li`,{key:e.id,class:d([`px-4 py-3 cursor-pointer active:bg-surface-hover/50 transition-colors`,L(e)?`bg-success/5`:``]),onClick:t=>K(e)},[c(`div`,Oe,[c(`div`,ke,[c(`div`,Ae,[c(`span`,{class:d([`font-mono text-xs`,L(e)?`text-white font-semibold`:`text-foreground-muted`])},`v`+s(e.version),3),u(w,{status:e.status},null,8,[`status`]),L(e)?(t(),l(`span`,je,`Active`)):_(``,!0)]),c(`div`,Me,[c(`span`,null,s(U(e.submitted_at)),1),e.duration_ms==null?_(``,!0):(t(),l(`span`,Ne,s(e.duration_ms)+` ms`,1)),e.phase?(t(),l(`span`,Pe,s(e.phase),1)):_(``,!0)])]),c(`div`,{class:`shrink-0 flex items-center gap-1`,onClick:n[1]||=C(()=>{},[`stop`])},[F(e)?(t(),p(i,{key:0,to:{name:`function-diff`,params:{name:E.value},query:{from:e.id,to:P.value}},class:`text-foreground-muted hover:text-white text-xs flex items-center gap-1 px-2 py-1`,title:`Compare with active version`},{default:r(()=>[u(o(y),{class:`w-3 h-3`}),n[9]||=m(` Compare `,-1)]),_:1},8,[`to`])):_(``,!0),N(e)?(t(),p(x,{key:1,size:`xs`,variant:`ghost`,disabled:M.value,onClick:t=>I(e)},{default:r(()=>[u(o(b),{class:`w-3 h-3`}),n[10]||=m(` Rollback `,-1)]),_:1},8,[`disabled`,`onClick`])):_(``,!0)])])],10,De))),128)),!A.value&&k.value.length===0?(t(),l(`li`,Fe,` No deployments yet for this function. `)):_(``,!0)]),c(`table`,Ie,[n[14]||=c(`thead`,{class:`text-xs text-foreground-muted uppercase bg-surface border-b border-border`},[c(`tr`,null,[c(`th`,{class:`px-6 py-3 font-medium`},` Version `),c(`th`,{class:`px-6 py-3 font-medium`},` Submitted `),c(`th`,{class:`px-6 py-3 font-medium`},` Status `),c(`th`,{class:`px-6 py-3 font-medium hidden md:table-cell`},` Phase `),c(`th`,{class:`px-6 py-3 font-medium hidden sm:table-cell`},` Duration `),c(`th`,{class:`px-6 py-3 font-medium hidden xl:table-cell`},` Deployment ID `),c(`th`,{class:`px-6 py-3 font-medium text-right`},` Actions `)])],-1),c(`tbody`,Le,[(t(!0),l(h,null,f(k.value,e=>(t(),l(`tr`,{key:e.id,class:d([`hover:bg-surface/50 transition-colors cursor-pointer`,L(e)?`bg-success/5`:``]),onClick:t=>K(e)},[c(`td`,ze,[c(`div`,Be,[c(`span`,{class:d([`text-white`,L(e)?`font-semibold`:`text-foreground-muted`])},`v`+s(e.version),3),L(e)?(t(),l(`span`,Ve,`Active`)):_(``,!0)])]),c(`td`,He,s(U(e.submitted_at)),1),c(`td`,Ue,[u(w,{status:e.status},null,8,[`status`])]),c(`td`,We,s(e.phase||o(`—`)),1),c(`td`,Ge,s(e.duration_ms==null?o(`—`):e.duration_ms+`ms`),1),c(`td`,Ke,s(e.id?.substring(0,14)),1),c(`td`,{class:`px-6 py-4 text-right text-xs`,onClick:n[2]||=C(()=>{},[`stop`])},[c(`div`,qe,[F(e)?(t(),p(i,{key:0,to:{name:`function-diff`,params:{name:E.value},query:{from:e.id,to:P.value}},class:`text-foreground-muted hover:text-white flex items-center gap-1`,title:`Compare with active version`},{default:r(()=>[u(o(y),{class:`w-3 h-3`}),n[11]||=m(` Compare `,-1)]),_:1},8,[`to`])):_(``,!0),N(e)?(t(),p(x,{key:1,size:`xs`,variant:`ghost`,disabled:M.value,onClick:t=>I(e)},{default:r(()=>[u(o(b),{class:`w-3 h-3`}),n[12]||=m(` Rollback `,-1)]),_:1},8,[`disabled`,`onClick`])):_(``,!0),!N(e)&&e.source===`rollback`?(t(),l(`span`,Je,`via rollback`)):!F(e)&&!N(e)?(t(),l(`span`,Ye,s(o(`—`)),1)):_(``,!0)])])],10,Re))),128)),!A.value&&k.value.length===0?(t(),l(`tr`,Xe,[...n[13]||=[c(`td`,{colspan:`7`,class:`px-6 py-8 text-center text-foreground-muted`},` No deployments yet for this function. `,-1)]])):_(``,!0)])])]),u(de,{modelValue:R.value,"onUpdate:modelValue":n[3]||=e=>R.value=e,title:lt.value,width:`640px`},{default:r(()=>[z.value?(t(),l(`div`,Qe,[c(`div`,$e,[u(w,{status:z.value.status},null,8,[`status`]),z.value.phase?(t(),l(`span`,et,s(z.value.phase),1)):_(``,!0)]),c(`div`,tt,[u(W,{label:`Version`,value:`v${z.value.version}`,mono:``},null,8,[`value`]),u(W,{label:`Duration`,value:z.value.duration_ms==null?o(`—`):z.value.duration_ms+` ms`},null,8,[`value`]),u(W,{label:`Submitted`,value:U(z.value.submitted_at)},null,8,[`value`]),u(W,{label:`Finished`,value:z.value.finished_at?U(z.value.finished_at):o(`—`)},null,8,[`value`])]),z.value.error_message?(t(),l(`div`,nt,[n[15]||=c(`h3`,{class:`text-xs uppercase tracking-wider text-foreground-muted mb-2`},` Error `,-1),c(`pre`,rt,s(z.value.error_message),1)])):_(``,!0),c(`div`,null,[c(`div`,it,[n[16]||=c(`h3`,{class:`text-xs uppercase tracking-wider text-foreground-muted`},` Build log `,-1),V.value?(t(),l(`span`,at,`live`)):_(``,!0)]),c(`pre`,ot,s(ut.value||`(no logs available)`),1)])])):(t(),l(`div`,Ze,` Nothing selected. `))]),_:1},8,[`modelValue`,`title`])])}}});export{st as default}; \ No newline at end of file diff --git a/backend/internal/server/ui_dist/assets/Docs-BCHpDwKo.js b/backend/internal/server/ui_dist/assets/Docs-BCHpDwKo.js new file mode 100644 index 00000000..b726458c --- /dev/null +++ b/backend/internal/server/ui_dist/assets/Docs-BCHpDwKo.js @@ -0,0 +1,345 @@ +import{C as e,D as t,F as n,G as r,M as i,T as a,Z as o,_ as s,c,d as l,gt as u,h as d,j as ee,k as f,l as p,m,p as h,r as g,s as _,u as te,v,vt as y}from"./runtime-core.esm-bundler-BMQPyJ_W.js";import{t as b}from"./check-ho22bAKW.js";import{t as x}from"./chevron-right-BNHZGbeL.js";import{t as S}from"./copy-DHTw5vil.js";import{t as C}from"./globe-D4_vTA7d.js";import{t as w}from"./key-round-7iKBY7s0.js";import{t as T}from"./lock-DzLYLVcq.js";import{t as ne}from"./variable-JBU1Bvu7.js";import{t as re}from"./client-BF51V3uE.js";import{Dt as ie,Et as ae,Ot as oe,gt as se}from"./index-CZI-jurg.js";import{a as E,i as D,n as ce,r as le,t as O}from"./github-dark-D7LxIVih.js";import{t as k}from"./clipboard-D_9N0yai.js";import{r as ue,t as de}from"./aiPrompts-NjljN3ld.js";function fe(e){let t=e.regex,n=`HTTP/([32]|1\\.[01])`,r={className:`attribute`,begin:t.concat(`^`,/[A-Za-z][A-Za-z0-9-]*/,`(?=\\:\\s)`),starts:{contains:[{className:`punctuation`,begin:/: /,relevance:0,starts:{end:`$`,relevance:0}}]}},i=[r,{begin:`\\n\\n`,starts:{subLanguage:[],endsWithParent:!0}}];return{name:`HTTP`,aliases:[`https`],illegal:/\S/,contains:[{begin:`^(?=HTTP/([32]|1\\.[01]) \\d{3})`,end:/$/,contains:[{className:`meta`,begin:n},{className:`number`,begin:`\\b\\d{3}\\b`}],starts:{end:/\b\B/,illegal:/\S/,contains:i}},{begin:`(?=^[A-Z]+ (.*?) HTTP/([32]|1\\.[01])$)`,end:/$/,contains:[{className:`string`,begin:` `,end:` `,excludeBegin:!0,excludeEnd:!0},{className:`meta`,begin:n},{className:`keyword`,begin:`[A-Z]+`}],starts:{end:/\b\B/,illegal:/\S/,contains:i}},e.inherit(r,{relevance:0})]}}var pe={class:`space-y-12 pb-16`},me={class:`docs-hero`},he={class:`docs-hero-content`},ge={class:`docs-hero-row`},_e={class:`docs-hero-actions`},ve=[`title`,`aria-label`],A={class:`docs-hero-toc`,"aria-label":`Jump to docs section`},j=[`href`],M={class:`docs-hero-toc-num`},N={id:`handler`,class:`space-y-5 scroll-mt-6`},P={class:`doc-table-wrap`},F={class:`doc-table`},ye={class:`doc-cell-key`},be={class:`doc-cell-mono`},xe={class:`doc-cell-mono hidden sm:table-cell`},Se={class:`doc-cell-mono hidden md:table-cell`},Ce={id:`deploy`,class:`space-y-5 scroll-mt-6 border-t border-border pt-12`},we={class:`grid grid-cols-1 lg:grid-cols-2 gap-3`},Te={class:`space-y-2`},Ee={class:`space-y-2`},De={class:`space-y-2`},Oe={id:`config`,class:`space-y-5 scroll-mt-6 border-t border-border pt-12`},ke={class:`doc-table-wrap`},Ae={class:`doc-table`},je={class:`doc-cell-key whitespace-nowrap`},Me={class:`doc-cell-mono hidden sm:table-cell whitespace-nowrap`},Ne={class:`doc-cell-body`},Pe={class:`space-y-2`},Fe={class:`doc-details group`},Ie={class:`doc-details-summary`},Le={class:`doc-details-body`},Re={id:`sdk`,class:`space-y-5 scroll-mt-6 border-t border-border pt-12`},ze={class:`space-y-2`},Be={class:`space-y-2`},Ve={class:`space-y-2`},He={id:`schedules`,class:`space-y-5 scroll-mt-6 border-t border-border pt-12`},Ue={class:`doc-section-head`},We={class:`doc-lede`},Ge={id:`webhooks`,class:`space-y-5 scroll-mt-6 border-t border-border pt-12`},Ke={class:`doc-section-head`},qe={class:`doc-lede`},Je={class:`doc-table-wrap`},Ye={class:`doc-table`},Xe={class:`doc-cell-key whitespace-nowrap`},Ze={class:`doc-cell-body`},Qe={class:`space-y-2`},$e={id:`mcp`,class:`space-y-5 scroll-mt-6 border-t border-border pt-12`},et={class:`grid grid-cols-1 md:grid-cols-3 gap-3`},tt={class:`doc-card`},nt={class:`doc-card-body`},rt={class:`doc-chip break-all`},it={class:`doc-token-bar`},at={class:`flex items-center gap-2 min-w-0 flex-1`},ot={key:0,class:`text-sm text-foreground-muted truncate`},st={key:1,class:`text-sm text-success truncate`},ct={class:`doc-chip`},lt=[`disabled`],ut={class:`doc-details group`},dt={class:`doc-details-summary`},ft={class:`doc-details-body space-y-4`},pt={id:`generate`,class:`space-y-5 scroll-mt-6 border-t border-border pt-12`},mt={class:`ai-prompt-actions`},ht={key:0,class:`prompt-collapse-fade`,"aria-hidden":`true`},gt=[`aria-expanded`],_t={id:`tracing`,class:`space-y-5 scroll-mt-6 border-t border-border pt-12`},vt={class:`doc-table-wrap`},yt={class:`doc-table`},bt={class:`doc-cell-key whitespace-nowrap`},xt={class:`doc-cell-body`},St={id:`errors`,class:`space-y-5 scroll-mt-6 border-t border-border pt-12`},Ct={class:`doc-table-wrap`},wt={class:`doc-table`},Tt={class:`doc-cell-key whitespace-nowrap`},Et={class:`doc-cell-body`},Dt={id:`cli`,class:`space-y-5 scroll-mt-6 border-t border-border pt-12`},Ot={class:`doc-prose`},kt={class:`doc-table-wrap`},At={class:`doc-table`},jt={class:`doc-cell-key whitespace-nowrap`},Mt={class:`doc-cell-mono`},Nt={class:`doc-cell-body hidden md:table-cell`},Pt={class:`space-y-2`},Ft={class:`space-y-2`},It={class:`space-y-2`},Lt={class:`space-y-2`},Rt={class:`space-y-2`},zt=`# Available inside every running function — refresh per-invocation: +ORVA_TRACE_ID=tr_3e39f6991c66f140577c6021da7dd13b # one per causal chain +ORVA_SPAN_ID=sp_4ceba57f6b1c982e # this execution + +# Python: os.environ["ORVA_TRACE_ID"] +# Node.js: process.env.ORVA_TRACE_ID +# Reading them is optional — the platform records the trace for you.`,Bt=`// Function A — calls B via the SDK. Trace context flows automatically. +const { invoke, jobs } = require('orva') + +module.exports.handler = async (event) => { + // F2F call — B becomes a child span under A. + const result = await invoke('send_email', { to: event.email }) + + // Job enqueue — when this job runs (now or in 6 hours), the resulting + // execution lands in the SAME trace as A. + await jobs.enqueue('audit_log', { action: 'sent', to: event.email }) + + return { statusCode: 200, body: 'ok' } +}`,Vt=`# Send the W3C traceparent header — Orva will adopt it as the trace root. +curl -H "traceparent: 00-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bbbbbbbbbbbbbbbb-01" \\ + https://orva.example.com/fn/myfn/ + +# Response always echoes: +# X-Trace-Id: tr_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`,Ht=`{ + "error": { + "code": "VALIDATION", + "message": "name must be lowercase and dash-separated", + "request_id": "req_abc123" + } +}`,Ut=`# 1. Generate an API key in the dashboard (Keys page) or via the API +# 2. Tell the CLI where to find your Orva and which key to use +orva login \\ + --endpoint https://orva.example.com \\ + --api-key orva_xxx_your_key_here + +# Writes ~/.orva/config.yaml. Subsequent commands need no flags. +orva system health # smoke test`,Wt=`# Deploy from a directory. Auto-detects handler.ts when tsconfig.json +# is present; else uses the runtime default (handler.js / handler.py). +orva deploy ./my-fn \\ + --name resize-image \\ + --runtime node + +# Override the entrypoint explicitly: +orva deploy ./my-fn --name api --runtime python --entrypoint app.py`,Gt=`# Invoke a function by name or UUID: +orva invoke resize-image --body '{"url":"https://example.com/cat.jpg"}' + +# Recent executions: +orva logs resize-image + +# Single execution, with stdout/stderr: +orva logs resize-image --exec-id exec_abc123 + +# Live tail — SSE stream, Ctrl-C to stop: +orva logs resize-image --follow`,Kt=`# List keys (optionally by prefix) +orva kv list resize-image +orva kv list resize-image --prefix user: + +# Read / write / delete +orva kv get resize-image cache:home +orva kv put resize-image cache:home '{"hits":42}' --ttl 3600 +orva kv delete resize-image cache:home`,qt=`# Secrets — encrypted at rest, injected as env vars at spawn: +orva secrets set resize-image S3_BUCKET my-bucket +orva secrets list resize-image +orva secrets delete resize-image S3_BUCKET + +# Cron — fire a function on a schedule: +orva cron create --fn daily-report --expr '0 9 * * *' --tz Asia/Kolkata +orva cron list +orva cron update --enabled false # pause +orva cron delete + +# Jobs — fire-and-forget background queue: +orva jobs enqueue --fn send-email --data '{"to":"a@b.c"}' +orva jobs list --status pending +orva jobs retry +orva jobs delete + +# Outbound webhooks (system events): +orva webhooks create --url https://hooks.slack.com/... --events deployment.failed,job.failed +orva webhooks test + +# Inbound webhook triggers (external POST → function): +orva webhooks inbound create --fn order-handler --signature stripe`,Jt=`orva system health # daemon up + DB ok +orva system metrics # JSON metrics snapshot +orva system db-stats # on-disk breakdown (orva.db, WAL, functions/) +orva system vacuum # rewrite SQLite to reclaim freelist pages + +orva activity # last 50 activity rows +orva activity --follow # live feed (Ctrl-C) +orva activity --source mcp --limit 200 # MCP-only, last 200`,I=``,Yt={__name:`Docs`,setup(Yt){let Xt=se();E.registerLanguage(`python`,le),E.registerLanguage(`javascript`,D),E.registerLanguage(`js`,D),E.registerLanguage(`json`,ce),E.registerLanguage(`bash`,O),E.registerLanguage(`shell`,O),E.registerLanguage(`sh`,O),E.registerLanguage(`http`,fe);let L=_(()=>window.location.origin),R=[{id:`handler`,num:`01`,label:`Handler`},{id:`deploy`,num:`02`,label:`Deploy`},{id:`config`,num:`03`,label:`Config`},{id:`sdk`,num:`04`,label:`SDK`},{id:`schedules`,num:`05`,label:`Schedules`},{id:`webhooks`,num:`06`,label:`Webhooks`},{id:`mcp`,num:`07`,label:`MCP`},{id:`generate`,num:`08`,label:`AI prompt`},{id:`tracing`,num:`09`,label:`Tracing`},{id:`errors`,num:`10`,label:`Errors`},{id:`cli`,num:`11`,label:`CLI`}],z=r(`handler`),B=null;a(()=>{if(typeof IntersectionObserver>`u`)return;let e=new Set;B=new IntersectionObserver(t=>{for(let n of t)n.isIntersecting?e.add(n.target.id):e.delete(n.target.id);for(let t of R)if(e.has(t.id)){z.value=t.id;break}},{rootMargin:`-20% 0px -70% 0px`,threshold:0});for(let e of R){let t=document.getElementById(e.id);t&&B.observe(t)}}),e(()=>{B&&B.disconnect()});let Zt=de(),V=r(!1),H=null,Qt=async()=>{await ue()&&(V.value=!0,clearTimeout(H),H=setTimeout(()=>{V.value=!1},1500))},$t=s({setup(){return()=>v(`svg`,{viewBox:`0 0 256 255`,width:`14`,height:`14`,xmlns:`http://www.w3.org/2000/svg`},[v(`defs`,null,[v(`linearGradient`,{id:`pyg1`,x1:`0`,y1:`0`,x2:`1`,y2:`1`},[v(`stop`,{offset:`0`,"stop-color":`#387EB8`}),v(`stop`,{offset:`1`,"stop-color":`#366994`})]),v(`linearGradient`,{id:`pyg2`,x1:`0`,y1:`0`,x2:`1`,y2:`1`},[v(`stop`,{offset:`0`,"stop-color":`#FFE052`}),v(`stop`,{offset:`1`,"stop-color":`#FFC331`})])]),v(`path`,{fill:`url(#pyg1)`,d:`M126.9 12c-58.3 0-54.7 25.3-54.7 25.3l.1 26.2H128v8H50.5S12 67.2 12 126.1c0 58.9 33.6 56.8 33.6 56.8h19.4v-27.4s-1-33.6 33.1-33.6h55.9s32 .5 32-30.9V43.5S191.7 12 126.9 12zM95.7 29.9a10 10 0 0 1 0 20 10 10 0 0 1 0-20z`}),v(`path`,{fill:`url(#pyg2)`,d:`M129.1 243c58.3 0 54.7-25.3 54.7-25.3l-.1-26.2H128v-8h77.5s38.5 4.4 38.5-54.5c0-58.9-33.6-56.8-33.6-56.8h-19.4v27.4s1 33.6-33.1 33.6H102s-32-.5-32 30.9v52S64.3 243 129.1 243zm30.4-17.9a10 10 0 0 1 0-20 10 10 0 0 1 0 20z`})])}}),en=s({setup(){return()=>v(`svg`,{viewBox:`0 0 256 280`,width:`14`,height:`14`,xmlns:`http://www.w3.org/2000/svg`},[v(`path`,{fill:`#3F873F`,d:`M128 0 12 67v146l116 67 116-67V67L128 0zm0 24.6 95 54.8v121.2l-95 54.8-95-54.8V79.4l95-54.8z`}),v(`path`,{fill:`#3F873F`,d:`M128 64c-3 0-5.7.7-8 2.3L73 92c-5 2.7-8 8-8 13.6V169c0 5.6 3 10.7 8 13.5l13 7.4c6.3 3.1 8.5 3.1 11.4 3.1 9.4 0 14.8-5.7 14.8-15.6V117c0-1-.7-1.7-1.7-1.7H103c-1 0-1.7.7-1.7 1.7v60.2c0 4.4-4.5 8.7-11.8 5.1l-13.7-7.9a1.6 1.6 0 0 1-.8-1.4v-63.4c0-.6.3-1 .8-1.4l46.8-26.9c.4-.3 1-.3 1.4 0L171 110c.5.4.8.8.8 1.4V174a1.7 1.7 0 0 1-.8 1.4l-46.8 27c-.4.2-1 .2-1.4 0l-12-7.2c-.4-.2-.8-.2-1.2 0-3.4 1.9-4 2.2-7.2 3.3-.8.3-2 .7.4 2.1l15.7 9.3c2.5 1.4 5.3 2.2 8.2 2.2 2.9 0 5.7-.8 8.2-2.2L181 184c5-2.8 8-7.9 8-13.5V107c0-5.6-3-10.7-8-13.5l-46.7-26.7a17 17 0 0 0-6.3-2.8z`})])}}),tn=s({name:`DeployPipelineDiagram`,setup(){let e=[{glyph:`▣`,label:`Tarball`,sub:`POST /deploy`},{glyph:`⟜`,label:`Extract`,sub:`untar → scratch dir`},{glyph:`◍`,label:`Install`,sub:`npm / pip`},{glyph:`⟐`,label:`Compile`,sub:`tsc (TypeScript)`},{glyph:`◉`,label:`Activate`,sub:`rename → current`},{glyph:`✦`,label:`Warm pool`,sub:`pre-spawn N workers`}];return()=>v(`figure`,{class:`doc-diagram`},[v(`figcaption`,{class:`doc-diagram-cap`},`Deploy pipeline`),v(`div`,{class:`doc-pipeline`},e.flatMap((t,n)=>{let r=v(`div`,{key:`s${n}`,class:`doc-pipeline-stage`},[v(`div`,{class:`doc-pipeline-glyph`},t.glyph),v(`div`,{class:`doc-pipeline-label`},[v(`span`,{class:`doc-pipeline-name`},t.label),v(`span`,{class:`doc-pipeline-sub`},t.sub)])]),i=ne/220*100;return()=>v(`figure`,{class:`doc-diagram`},[v(`figcaption`,{class:`doc-diagram-cap`},`Causal trace, one HTTP request and three spans`),v(`div`,{class:`doc-trace`},[v(`div`,{class:`doc-trace-axis`},[v(`span`,null,`0 ms`),v(`span`,null,`220 ms`)]),...e.map(e=>v(`div`,{key:e.fn,class:[`doc-trace-row`,`is-${e.klass}`]},[v(`div`,{class:`doc-trace-label`},[v(`span`,{class:`doc-trace-fn`},e.fn),v(`span`,{class:`doc-trace-trigger`},e.trigger)]),v(`div`,{class:`doc-trace-track`},[v(`div`,{class:`doc-trace-bar`,style:{left:`${t(e.start)}%`,width:`${t(e.dur)}%`},title:`+${e.start}ms · ${e.dur}ms`})]),v(`div`,{class:`doc-trace-dur`},`${e.dur}ms`)])),v(`div`,{class:`doc-trace-legend`},[v(`span`,null,`Same `),v(`code`,{class:`doc-chip`},`trace_id`),v(`span`,null,` across all spans · `),v(`code`,{class:`doc-chip`},`parent_span_id`),v(`span`,null,` chains them into a tree.`)])])])}}),rn=s({name:`WebhookDeliveryDiagram`,setup(){return()=>v(`figure`,{class:`doc-diagram`},[v(`figcaption`,{class:`doc-diagram-cap`},`Signed webhook delivery`),v(`div`,{class:`doc-webhook`},[v(`div`,{class:`doc-webhook-actor`},[v(`div`,{class:`doc-webhook-actor-head`},`orvad`),v(`div`,{class:`doc-webhook-actor-body`},[v(`span`,null,`event fires`),v(`code`,{class:`doc-chip`},`deployment.succeeded`)])]),v(`div`,{class:`doc-webhook-wire`},[v(`div`,{class:`doc-webhook-wire-line`,"aria-hidden":`true`}),v(`div`,{class:`doc-webhook-wire-payload`},[v(`div`,{class:`doc-webhook-wire-method`},`POST`),v(`div`,{class:`doc-webhook-wire-headers`},[v(`code`,null,`X-Orva-Event`),v(`code`,null,`X-Orva-Timestamp`),v(`code`,null,`X-Orva-Signature`)]),v(`div`,{class:`doc-webhook-wire-sig`},`sha256=hex(hmac(secret, ts.body))`)])]),v(`div`,{class:`doc-webhook-actor`},[v(`div`,{class:`doc-webhook-actor-head`},`your receiver`),v(`div`,{class:`doc-webhook-actor-body`},[v(`span`,null,`verify HMAC`),v(`span`,null,`→ 2xx within 15s or get retried`)])])])])}}),an=_(()=>[{label:`Python`,lang:`python`,code:`def handler(event): + body = event.get("body") or {} + return { + "statusCode": 200, + "headers": {"Content-Type": "application/json"}, + "body": {"hello": body.get("name", "world")}, + }`},{label:`Node.js`,lang:`js`,code:`exports.handler = async (event) => { + const body = event.body || {}; + return { + statusCode: 200, + headers: { 'Content-Type': 'application/json' }, + body: { hello: body.name || 'world' }, + }; +};`}]),on=_(()=>[{label:`curl`,lang:`bash`,code:`curl -X POST ${L.value}/fn/ \\ + -H 'Content-Type: application/json' \\ + -d '{"name": "Orva"}'`},{label:`fetch`,lang:`js`,code:`const res = await fetch('${L.value}/fn/', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ name: 'Orva' }), +}); +console.log(await res.json());`},{label:`Python`,lang:`python`,code:`import httpx + +r = httpx.post( + "${L.value}/fn/", + json={"name": "Orva"}, +) +print(r.json())`}]),sn=[{id:`python`,name:`Python 3.14`,entry:`handler.py`,deps:`requirements.txt`,icon:$t},{id:`node`,name:`Node.js 24`,entry:`handler.js`,deps:`package.json`,icon:en}],cn=[{field:`env_vars`,purpose:`Plain config`,body:`Plaintext config stored on the function record. Use for feature flags and non-secret settings.`,icon:ne,iconClass:`text-primary`},{field:`/secrets`,purpose:`Encrypted`,body:`AES-256-GCM at rest. Values decrypt only into the worker environment at spawn time.`,icon:w,iconClass:`text-primary`},{field:`network_mode`,purpose:`Egress control`,body:`none = isolated loopback. egress = outbound HTTPS allowed, filtered by the sandbox egress policy.`,icon:C,iconClass:`text-primary`},{field:`auth_mode`,purpose:`Invoke gate`,body:`none = public. platform_key = require Orva API key. signed = require HMAC.`,icon:T,iconClass:`text-primary`},{field:`rate_limit_per_min`,purpose:`Per-IP throttle`,body:`Optional cap for public or webhook-facing functions. Exceeding it returns 429.`,icon:ae,iconClass:`text-primary`}],ln=_(()=>`curl -X POST ${L.value}/api/v1/functions \\ + -H 'X-Orva-API-Key: ' \\ + -H 'Content-Type: application/json' \\ + -d '{"name":"hello","runtime":"python","memory_mb":128,"cpus":0.5}'`),un=_(()=>`tar czf code.tar.gz handler.py requirements.txt +curl -X POST ${L.value}/api/v1/functions//deploy \\ + -H 'X-Orva-API-Key: ' \\ + -F code=@code.tar.gz`),dn=_(()=>`curl -X POST ${L.value}/api/v1/functions//secrets \\ + -H 'X-Orva-API-Key: ' \\ + -H 'Content-Type: application/json' \\ + -d '{"key":"DATABASE_URL","value":"postgres://..."}'`),fn=_(()=>`# generate signature +SECRET='your-shared-secret-stored-in-function-secrets' +TS=$(date +%s) +BODY='{"hello":"world"}' +SIG=$(printf '%s.%s' "$TS" "$BODY" | openssl dgst -sha256 -hmac "$SECRET" -hex | awk '{print $2}') + +curl -X POST ${L.value}/fn/ \\ + -H "X-Orva-Timestamp: $TS" \\ + -H "X-Orva-Signature: sha256=$SIG" \\ + -H 'Content-Type: application/json' \\ + -d "$BODY"`),pn=_(()=>[{label:`curl`,lang:`bash`,note:`Create a daily-9am schedule for an existing function. payload is delivered as the invoke body.`,code:`curl -X POST ${L.value}/api/v1/functions//cron \\ + -H 'X-Orva-API-Key: ' \\ + -H 'Content-Type: application/json' \\ + -d '{ + "cron_expr": "0 9 * * *", + "enabled": true, + "payload": {"task": "daily-summary"} + }'`},{label:`Toggle / edit`,lang:`bash`,note:`PUT accepts any subset of {cron_expr, enabled, payload}; omitted fields keep their previous value. next_run_at is recomputed on expr changes.`,code:`# pause +curl -X PUT ${L.value}/api/v1/functions//cron/ \\ + -H 'X-Orva-API-Key: ' \\ + -H 'Content-Type: application/json' \\ + -d '{"enabled": false}' + +# change schedule +curl -X PUT ${L.value}/api/v1/functions//cron/ \\ + -H 'X-Orva-API-Key: ' \\ + -H 'Content-Type: application/json' \\ + -d '{"cron_expr": "*/15 * * * *"}'`},{label:`List & delete`,lang:`bash`,note:`GET /api/v1/cron lists every schedule across functions (with function_name JOIN); per-function uses the nested route.`,code:`# all schedules +curl ${L.value}/api/v1/cron \\ + -H 'X-Orva-API-Key: ' + +# delete one +curl -X DELETE ${L.value}/api/v1/functions//cron/ \\ + -H 'X-Orva-API-Key: '`}]),mn=[{label:`Python`,lang:`python`,code:`from orva import kv + +def handler(event): + # Store with optional TTL (seconds). 0 = no expiry. + kv.put("user:42", {"name": "Ada", "tier": "pro"}, ttl_seconds=3600) + + # Read; default returned if missing or expired. + user = kv.get("user:42", default=None) + + # List by prefix. + pages = kv.list(prefix="page:", limit=50) + + # Delete is idempotent. + kv.delete("user:42") + + return {"statusCode": 200, "body": str(user)}`},{label:`Node.js`,lang:`js`,code:`const { kv } = require('orva') + +exports.handler = async (event) => { + await kv.put('user:42', { name: 'Ada', tier: 'pro' }, { ttlSeconds: 3600 }) + + const user = await kv.get('user:42', null) + + const pages = await kv.list({ prefix: 'page:', limit: 50 }) + + await kv.delete('user:42') + + return { statusCode: 200, body: JSON.stringify(user) } +}`}],hn=[{label:`Python`,lang:`python`,code:`from orva import invoke, OrvaError + +def handler(event): + try: + # invoke() returns the downstream {statusCode, headers, body}. + # body is JSON-decoded when possible. + result = invoke("resize-image", {"url": event["body"]["url"]}) + return {"statusCode": 200, "body": result["body"]} + except OrvaError as e: + # 404 = function not found, 507 = call depth exceeded. + return {"statusCode": e.status or 502, "body": str(e)}`},{label:`Node.js`,lang:`js`,code:`const { invoke, OrvaError } = require('orva') + +exports.handler = async (event) => { + try { + const result = await invoke('resize-image', { url: event.body.url }) + return { statusCode: 200, body: result.body } + } catch (e) { + if (e instanceof OrvaError) { + return { statusCode: e.status || 502, body: e.message } + } + throw e + } +}`}],gn=[{label:`Python`,lang:`python`,code:`from orva import jobs + +def handler(event): + # Fire-and-forget. Returns the job id immediately; the function + # body runs later via the scheduler. max_attempts retries with + # exponential backoff on 5xx / exception. + job_id = jobs.enqueue( + "send-welcome-email", + {"to": event["body"]["email"]}, + max_attempts=3, + ) + return {"statusCode": 202, "body": job_id}`},{label:`Node.js`,lang:`js`,code:`const { jobs } = require('orva') + +exports.handler = async (event) => { + const jobId = await jobs.enqueue( + 'send-welcome-email', + { to: event.body.email }, + { maxAttempts: 3 } + ) + return { statusCode: 202, body: jobId } +}`}],_n=[{name:`deployment.succeeded`,when:`A function build finished and the new version is active.`},{name:`deployment.failed`,when:`A build failed or was rejected.`},{name:`function.created`,when:`A new function row was created via POST /api/v1/functions.`},{name:`function.updated`,when:`A function config was edited via PUT /api/v1/functions/{id} (status flips during a deploy do NOT fire this; see deployment.*).`},{name:`function.deleted`,when:`A function was removed.`},{name:`execution.error`,when:`An invocation finished with status=error or 5xx.`},{name:`cron.failed`,when:`A scheduled run failed (bad expr, missing fn, dispatch error, or 5xx).`},{name:`job.succeeded`,when:`A queued background job finished successfully.`},{name:`job.failed`,when:`A queued job exhausted its retries (terminal failure).`}],vn=[{label:`Python`,lang:`python`,note:`Run on the receiver. Reject anything that fails verification. The signature ensures the request really came from this Orva instance.`,code:`import hmac, hashlib, time + +def verify(secret: str, ts: str, body: bytes, sig_header: str) -> bool: + if abs(time.time() - int(ts)) > 300: # 5-min skew window + return False + mac = hmac.new(secret.encode(), f"{ts}.".encode() + body, hashlib.sha256) + expected = "sha256=" + mac.hexdigest() + return hmac.compare_digest(expected, sig_header) + +# In your Flask/FastAPI/etc. handler: +ts = request.headers["X-Orva-Timestamp"] +sig = request.headers["X-Orva-Signature"] +if not verify(WEBHOOK_SECRET, ts, request.get_data(), sig): + return "bad signature", 401`},{label:`Node.js`,lang:`js`,note:`Same shape as Stripe. Use timingSafeEqual to avoid sig-leak via timing.`,code:`const crypto = require('crypto') + +function verify(secret, ts, body, sigHeader) { + if (Math.abs(Date.now() / 1000 - parseInt(ts, 10)) > 300) return false + const mac = crypto.createHmac('sha256', secret) + mac.update(ts + '.') + mac.update(body) + const expected = 'sha256=' + mac.digest('hex') + if (expected.length !== sigHeader.length) return false + return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sigHeader)) +} + +// In an express handler with raw body middleware: +app.post('/webhooks/orva', (req, res) => { + const ok = verify( + process.env.WEBHOOK_SECRET, + req.headers['x-orva-timestamp'], + req.body, // raw bytes — NOT parsed JSON + req.headers['x-orva-signature'] + ) + if (!ok) return res.status(401).send('bad signature') + res.sendStatus(200) +})`}],U=[{name:`http`,desc:`Public HTTP request hit /fn//. Almost always a root span.`},{name:`f2f`,desc:`Another function called this one via orva.invoke(). Has a parent_span_id.`},{name:`job`,desc:`Background job runner picked up an enqueued job. Parent_span_id is whoever enqueued it.`},{name:`cron`,desc:`Scheduler fired a cron entry. Always a root span.`},{name:`inbound`,desc:`External webhook hit /webhook/{id}. Always a root span.`},{name:`replay`,desc:`Operator clicked Replay on a captured execution. Fresh trace, no link to original.`},{name:`mcp`,desc:`AI agent invoked the function via MCP invoke_function. Fresh trace.`}],yn=[{code:`VALIDATION`,when:`Bad request body or path parameter.`},{code:`UNAUTHORIZED`,when:`Missing or invalid API key / session cookie.`},{code:`NOT_FOUND`,when:`Function, deployment, or secret doesn't exist.`},{code:`RATE_LIMITED`,when:`Too many requests; check the Retry-After header.`},{code:`VERSION_GCD`,when:`Rollback target was garbage-collected.`},{code:`INSUFFICIENT_DISK`,when:`Host is below min_free_disk_mb.`}],bn=[{cmd:`login`,subs:`—`,purpose:`Save endpoint + API key to ~/.orva/config.yaml`},{cmd:`init`,subs:`—`,purpose:`Full server only: write the legacy orva.yaml template`},{cmd:`deploy`,subs:`[path]`,purpose:`Package a directory and deploy as a function`},{cmd:`invoke`,subs:`[name|id]`,purpose:`POST to /fn// and print the response`},{cmd:`logs`,subs:`[name|id] [--follow]`,purpose:`List recent executions; --follow streams live via SSE`},{cmd:`functions`,subs:`list / get / create / delete`,purpose:`CRUD for the function registry`},{cmd:`cron`,subs:`list / create / update / delete`,purpose:`Manage cron schedules attached to functions`},{cmd:`jobs`,subs:`list / enqueue / retry / delete`,purpose:`Background queue management`},{cmd:`kv`,subs:`list / get / put / delete`,purpose:`Browse a function’s key/value store`},{cmd:`secrets`,subs:`list / set / delete`,purpose:`AES-256-GCM secrets per function`},{cmd:`webhooks`,subs:`list / create / test / delete / inbound`,purpose:`System-event subscribers + inbound triggers`},{cmd:`routes`,subs:`list / set / delete`,purpose:`Custom URL → function path mappings`},{cmd:`keys`,subs:`list / create / revoke`,purpose:`Manage API keys`},{cmd:`activity`,subs:`[--follow] [--source web|api|...]`,purpose:`Paginated activity rows; live SSE with --follow`},{cmd:`system`,subs:`health / metrics / db-stats / vacuum`,purpose:`Server diagnostics`},{cmd:`setup`,subs:`[--skip-nsjail] [--skip-rootfs]`,purpose:`Install nsjail + rootfs on a bare host`},{cmd:`serve`,subs:`[--port N]`,purpose:`Run as the server daemon (not the CLI client)`},{cmd:`completion`,subs:`bash / zsh / fish / powershell`,purpose:`Emit shell completion script`}],W=r(``);a(async()=>{try{let e=await fetch(`/web/docs.md`,{cache:`no-cache`});e.ok&&(W.value=await e.text())}catch{}});let xn=_(()=>W.value.replaceAll(`{{ORIGIN}}`,window.location.origin)),G=r(!1),K=null,Sn=async()=>{await k(xn.value)&&(G.value=!0,clearTimeout(K),K=setTimeout(()=>{G.value=!1},1500))},q=r(!1),J=r(``),Y=r(!1),Cn=_(()=>J.value.slice(0,12)),X=_(()=>J.value||I),wn=async()=>{if(!Y.value){Y.value=!0;try{let e=new Date().toISOString().slice(0,16).replace(`T`,` `),t=await re.post(`/keys`,{name:`MCP: `+e,permissions:[`invoke`,`read`,`write`,`admin`]});J.value=t.data.key}catch(e){console.error(`mint mcp key failed`,e),Xt.notify({title:`Could not mint key`,message:e?.response?.data?.error?.message||e.message||`Unknown error`,danger:!0})}finally{Y.value=!1}}},Tn=_(()=>[{label:`Claude Code`,lang:`bash`,note:"Anthropic's `claude` CLI. Restart Claude Code afterwards; `/mcp` lists Orva's 73 tools.",code:`claude mcp add --transport http --scope user orva ${L.value}/mcp --header "Authorization: Bearer ${X.value}"`},{label:`curl`,lang:`bash`,note:"Talk to MCP directly — no handshake, no session id. Step 1 asks the server what it supports; Step 2 lists the tools. A successful reply is one SSE `message` event; a rejected one is plain JSON with a 4xx.",code:`curl -sN -X POST ${L.value}/mcp \\ + -H 'Authorization: Bearer ${X.value}' \\ + -H 'Content-Type: application/json' \\ + -H 'Accept: application/json, text/event-stream' \\ + -H 'Mcp-Protocol-Version: 2026-07-28' \\ + -H 'Mcp-Method: server/discover' \\ + -d '{"jsonrpc":"2.0","id":1,"method":"server/discover","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}' + +curl -sN -X POST ${L.value}/mcp \\ + -H 'Authorization: Bearer ${X.value}' \\ + -H 'Content-Type: application/json' \\ + -H 'Accept: application/json, text/event-stream' \\ + -H 'Mcp-Protocol-Version: 2026-07-28' \\ + -H 'Mcp-Method: tools/list' \\ + -d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{},"io.modelcontextprotocol/clientInfo":{"name":"curl","version":"0"}}}}' + +# Calling a tool needs a third header. Mcp-Name must repeat params.name, or the +# request is refused with -32020 before the tool runs: +curl -sN -X POST ${L.value}/mcp \\ + -H 'Authorization: Bearer ${X.value}' \\ + -H 'Content-Type: application/json' \\ + -H 'Accept: application/json, text/event-stream' \\ + -H 'Mcp-Protocol-Version: 2026-07-28' \\ + -H 'Mcp-Method: tools/call' \\ + -H 'Mcp-Name: system_health' \\ + -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"system_health","arguments":{},"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}' + +# Older clients need none of that — a bare list returns the same catalog: +curl -sN -X POST ${L.value}/mcp \\ + -H 'Authorization: Bearer ${X.value}' \\ + -H 'Content-Type: application/json' \\ + -H 'Accept: application/json, text/event-stream' \\ + -d '{"jsonrpc":"2.0","id":3,"method":"tools/list","params":{}}'`}]),En=_(()=>[{label:`Claude Desktop`,lang:`json`,note:`Paste into ~/Library/Application Support/Claude/claude_desktop_config.json (macOS), %APPDATA%\\Claude\\claude_desktop_config.json (Windows), or ~/.config/Claude/claude_desktop_config.json (Linux). Restart Claude Desktop.`,code:`{ + "mcpServers": { + "orva": { + "url": "${L.value}/mcp", + "headers": { + "Authorization": "Bearer ${X.value}" + } + } + } +}`},{label:`Cursor`,lang:`bash`,note:`Open the link in your browser. Cursor pops an approval dialog and writes ~/.cursor/mcp.json.`,code:`cursor://anysphere.cursor-deeplink/mcp/install?name=orva&config=${Dn.value}`},{label:`VS Code`,lang:`bash`,note:'User-scoped install via the Copilot-MCP `code --add-mcp` flag. Pick "Workspace" at the prompt to write .vscode/mcp.json instead.',code:`code --add-mcp '{"name":"orva","type":"http","url":"${L.value}/mcp","headers":{"Authorization":"Bearer ${X.value}"}}'`},{label:`Codex CLI`,lang:`bash`,note:"OpenAI's `codex` CLI. Writes to ~/.codex/config.toml.",code:`codex mcp add --transport streamable-http orva ${L.value}/mcp --header "Authorization: Bearer ${X.value}"`},{label:`OpenCode`,lang:`bash`,note:`Interactive add. Pick "Remote", paste ${L.value}/mcp, then add the header Authorization: Bearer ${X.value}.`,code:`opencode mcp add`},{label:`Zed`,lang:`json`,note:"Zed runs MCP as stdio subprocesses, so use the `mcp-remote` bridge. Paste under context_servers in ~/.config/zed/settings.json. Restart Zed.",code:`{ + "context_servers": { + "orva": { + "source": "custom", + "command": "npx", + "args": [ + "-y", "mcp-remote", + "${L.value}/mcp", + "--header", "Authorization:Bearer ${X.value}" + ] + } + } +}`},{label:`Windsurf`,lang:`json`,note:`Paste into ~/.codeium/windsurf/mcp_config.json and reload Windsurf.`,code:`{ + "mcpServers": { + "orva": { + "serverUrl": "${L.value}/mcp", + "headers": { + "Authorization": "Bearer ${X.value}" + } + } + } +}`},{label:`claude.ai web`,lang:`text`,note:`UI-only flow. Settings → Connectors → Add custom connector. claude.ai opens an Orva login + consent popup and issues an OAuth 2.1 token automatically; no token paste required.`,code:`URL: ${L.value}/mcp +Auth: OAuth (auto-discovered)`},{label:`ChatGPT`,lang:`text`,note:`UI-only flow. Settings → Apps & Connectors → Developer mode → Add new connector. ChatGPT discovers OIDC metadata, performs Dynamic Client Registration, and pops the Orva consent screen. No token paste required.`,code:`URL: ${L.value}/mcp +Auth: OAuth (auto-discovered)`}]),Dn=_(()=>{let e=JSON.stringify({url:L.value+`/mcp`,headers:{Authorization:`Bearer `+X.value}});return typeof window.btoa==`function`?window.btoa(e):e}),On=_(()=>[{label:`Cursor (global)`,lang:`json`,note:`Paste into ~/.cursor/mcp.json, or .cursor/mcp.json in your project root for a per-workspace install.`,code:`{ + "mcpServers": { + "orva": { + "url": "${L.value}/mcp", + "headers": { + "Authorization": "Bearer ${X.value}" + } + } + } +}`},{label:`Cline`,lang:`json`,note:`In VS Code: open Cline → MCP icon → Configure MCP Servers. Cline writes cline_mcp_settings.json.`,code:`{ + "mcpServers": { + "orva": { + "url": "${L.value}/mcp", + "headers": { + "Authorization": "Bearer ${X.value}" + }, + "disabled": false + } + } +}`}]),Z=s({name:`CodeBlock`,props:{code:{type:String,required:!0},lang:{type:String,default:``}},setup(e){let t=r(!1),n=async()=>{await k(e.code)&&(t.value=!0,setTimeout(()=>{t.value=!1},1200))},i=_(()=>{let t=(e.lang||``).toLowerCase();if(t&&E.getLanguage(t))try{return E.highlight(e.code,{language:t,ignoreIllegals:!0}).value}catch{}return e.code.replace(/&/g,`&`).replace(//g,`>`)});return()=>v(`div`,{class:`codeblock`},[v(`div`,{class:`codeblock-bar`},[v(`span`,{class:`codeblock-lang`},e.lang||``),v(`button`,{class:`codeblock-copy`,onClick:n,title:`Copy code`},[t.value?v(b,{class:`w-3 h-3`}):v(S,{class:`w-3 h-3`}),t.value?`Copied`:`Copy`])]),v(`pre`,{class:`codeblock-pre`},[v(`code`,{class:`hljs language-${(e.lang||`text`).toLowerCase()}`,innerHTML:i.value})])])}}),Q=s({name:`TabbedCode`,props:{tabs:{type:Array,required:!0},storageKey:{type:String,default:``}},setup(e){let t=(()=>{try{if(e.storageKey){let t=localStorage.getItem(e.storageKey);if(t&&e.tabs.some(e=>e.label===t))return t}}catch{}return e.tabs[0]?.label})(),n=r(t),i=t=>{n.value=t;try{e.storageKey&&localStorage.setItem(e.storageKey,t)}catch{}};return()=>{let t=e.tabs.find(e=>e.label===n.value)||e.tabs[0];return v(`div`,{class:`tabbed`},[v(`div`,{class:`tabbed-tabs`},e.tabs.map(e=>v(`button`,{key:e.label,class:[`tabbed-tab`,{active:e.label===n.value}],onClick:()=>i(e.label)},e.label))),t.note?v(`div`,{class:`tabbed-note`},t.note):null,v(Z,{code:t.code,lang:t.lang})])}}}),$=s({name:`DocsCallout`,props:{title:{type:String,default:``},icon:{type:[Object,Function],default:null}},setup(e,{slots:t}){return()=>v(`div`,{class:`callout`},[v(`div`,{class:`callout-head`},[e.icon?v(e.icon,{class:`callout-icon`}):null,e.title?v(`span`,null,e.title):null]),v(`div`,{class:`callout-body`},t.default?.())])}});return(e,r)=>{let a=ee(`router-link`);return t(),l(`div`,pe,[c(`header`,me,[c(`div`,he,[c(`div`,ge,[r[1]||=c(`div`,{class:`docs-hero-text`},[c(`h1`,{class:`docs-hero-title`},` Documentation `),c(`p`,{class:`docs-hero-sub`},` Build, deploy, and operate functions on Orva. `)],-1),c(`div`,_e,[c(`button`,{class:u([`docs-hero-copy-icon`,{copied:G.value}]),title:G.value?`Copied`:`Copy entire docs page as Markdown`,"aria-label":G.value?`Markdown copied to clipboard`:`Copy entire docs page as Markdown`,onClick:Sn},[G.value?(t(),p(o(b),{key:0,class:`w-4 h-4`})):(t(),p(o(S),{key:1,class:`w-4 h-4`}))],10,ve)])]),c(`nav`,A,[r[2]||=c(`span`,{class:`docs-hero-toc-label`},`Jump to`,-1),(t(),l(g,null,f(R,e=>c(`a`,{key:e.id,href:`#${e.id}`,class:u([`docs-hero-toc-link`,{active:z.value===e.id}])},[c(`span`,M,y(e.num),1),c(`span`,null,y(e.label),1)],10,j)),64))])])]),c(`section`,N,[r[4]||=c(`div`,{class:`doc-section-head`},[c(`span`,{class:`doc-section-num`},`01`),c(`div`,null,[c(`h2`,{class:`doc-section-title`},` Handler contract `),c(`p`,{class:`doc-lede`},` One exported function receives the inbound HTTP event and returns an HTTP-shaped response. The adapter handles serialization and headers. `)])],-1),d(o(Q),{tabs:an.value,"storage-key":`docs.handler`},null,8,[`tabs`]),r[5]||=h(`
Event shape
methodpathheadersquerybody
Response
{ statusCode, headers, body }

Non-string bodies are JSON-encoded by the adapter.

Runtime env
Env vars and secrets land in process.env / os.environ.
`,1),c(`div`,P,[c(`table`,F,[r[3]||=c(`thead`,null,[c(`tr`,null,[c(`th`,null,`Runtime`),c(`th`,null,`ID`),c(`th`,{class:`hidden sm:table-cell`},` Entrypoint `),c(`th`,{class:`hidden md:table-cell`},` Dependencies `)])],-1),c(`tbody`,null,[(t(),l(g,null,f(sn,e=>c(`tr`,{key:e.id},[c(`td`,ye,[(t(),p(i(e.icon),{class:`shrink-0`})),m(` `+y(e.name),1)]),c(`td`,be,y(e.id),1),c(`td`,xe,y(e.entry),1),c(`td`,Se,y(e.deps),1)])),64))])])])]),c(`section`,Ce,[r[10]||=h(`
02

Deploy & invoke

The dashboard handles day-to-day work; these calls are for CI and automation. Builds run async; poll /api/v1/deployments/<id> or stream /api/v1/deployments/<id>/stream until phase: done.

`,1),d(o(tn)),c(`div`,we,[c(`div`,Te,[r[6]||=c(`div`,{class:`doc-step-label`},[c(`span`,{class:`doc-step-num`},`1`),m(` Create the function row `)],-1),d(o(Z),{code:ln.value,lang:`bash`},null,8,[`code`])]),c(`div`,Ee,[r[7]||=c(`div`,{class:`doc-step-label`},[c(`span`,{class:`doc-step-num`},`2`),m(` Upload code `)],-1),d(o(Z),{code:un.value,lang:`bash`},null,8,[`code`])])]),c(`div`,De,[r[8]||=c(`div`,{class:`doc-microlabel`},` Invoke `,-1),d(o(Q),{tabs:on.value,"storage-key":`docs.invoke`},null,8,[`tabs`])]),d(o($),{icon:o(C),title:`Custom routes`},{default:n(()=>[...r[9]||=[m(` Attach a friendly path with `,-1),c(`code`,{class:`doc-chip`},`POST /api/v1/routes`,-1),m(`. Reserved prefixes: `,-1),c(`code`,{class:`doc-chip`},`/api/`,-1),c(`code`,{class:`doc-chip`},`/fn/`,-1),c(`code`,{class:`doc-chip`},`/mcp/`,-1),c(`code`,{class:`doc-chip`},`/web/`,-1),c(`code`,{class:`doc-chip`},`/_orva/`,-1),m(`. `,-1)]]),_:1},8,[`icon`])]),c(`section`,Oe,[r[14]||=c(`div`,{class:`doc-section-head`},[c(`span`,{class:`doc-section-num`},`03`),c(`div`,null,[c(`h2`,{class:`doc-section-title`},` Configuration reference `),c(`p`,{class:`doc-lede`},` Everything below lives on the function record. Secrets are stored encrypted and only decrypt into the worker environment at spawn time. `)])],-1),c(`div`,ke,[c(`table`,Ae,[r[11]||=c(`thead`,null,[c(`tr`,null,[c(`th`,null,`Field`),c(`th`,{class:`hidden sm:table-cell`},` Purpose `),c(`th`,null,`Behaviour`)])],-1),c(`tbody`,null,[(t(),l(g,null,f(cn,e=>c(`tr`,{key:e.field,class:`align-top`},[c(`td`,je,[(t(),p(i(e.icon),{class:u([`w-3.5 h-3.5 shrink-0`,e.iconClass])},null,8,[`class`])),c(`code`,null,y(e.field),1)]),c(`td`,Me,y(e.purpose),1),c(`td`,Ne,y(e.body),1)])),64))])])]),c(`div`,Pe,[r[12]||=c(`div`,{class:`doc-microlabel`},` Set a secret `,-1),d(o(Z),{code:dn.value,lang:`bash`},null,8,[`code`])]),c(`details`,Fe,[c(`summary`,Ie,[d(o(x),{class:`w-3.5 h-3.5 transition-transform group-open:rotate-90 text-foreground-muted`}),r[13]||=m(` Signed-invoke recipe (HMAC, opt-in) `,-1)]),c(`div`,Le,[d(o(Z),{code:fn.value,lang:`bash`},null,8,[`code`])])])]),c(`section`,Re,[r[20]||=h(`
04

SDK from inside a function

The bundled orva module exposes three primitives every function can use without extra dependencies: a per-function key/value store, in-process calls to other Orva functions, and a fire-and-forget background job queue. Routes through the per-process internal token injected at worker spawn time.

orva.kv
put / get / delete / list

Per-function namespace on SQLite, optional TTL.

orva.invoke
invoke(name, payload)

In-process call to another function. 8-deep call cap.

orva.jobs
jobs.enqueue(name, payload)

Fire-and-forget; persisted; retried with exp backoff.

`,2),c(`div`,ze,[r[15]||=c(`div`,{class:`doc-microlabel`},` KV: get/put with TTL `,-1),d(o(Q),{tabs:mn,"storage-key":`docs.sdk.kv`}),r[16]||=h(`

Browse / inspect / edit / delete / set keys without leaving the dashboard at /web/functions/<name>/kv (or click the KV button in the editor's action bar). REST mirror at GET/PUT/DELETE /api/v1/functions/<id>/kv[/<key>]; MCP tools kv_list / kv_get / kv_put / kv_delete for agents.

`,1)]),c(`div`,Be,[r[17]||=c(`div`,{class:`doc-microlabel`},` Function-to-function: invoke() `,-1),d(o(Q),{tabs:hn,"storage-key":`docs.sdk.invoke`})]),c(`div`,Ve,[r[18]||=c(`div`,{class:`doc-microlabel`},` Background jobs: jobs.enqueue() `,-1),d(o(Q),{tabs:gn,"storage-key":`docs.sdk.jobs`})]),d(o($),{icon:o(C),title:`Network mode`},{default:n(()=>[...r[19]||=[m(` The SDK reaches orvad over loopback through the host gateway, so the function needs `,-1),c(`code`,{class:`doc-chip`},`network_mode: "egress"`,-1),m(`. On the default `,-1),c(`code`,{class:`doc-chip`},`"none"`,-1),m(` the SDK throws `,-1),c(`code`,{class:`doc-chip`},`OrvaUnavailableError`,-1),m(` with a clear hint. `,-1)]]),_:1},8,[`icon`])]),c(`section`,He,[c(`div`,Ue,[r[31]||=c(`span`,{class:`doc-section-num`},`05`,-1),c(`div`,null,[r[30]||=c(`h2`,{class:`doc-section-title`},` Schedules `,-1),c(`p`,We,[r[22]||=m(` Fire any function on a cron expression. The scheduler runs as part of the orvad process; no external service. Manage from the `,-1),d(a,{to:`/cron`,class:`text-foreground hover:text-white underline decoration-dotted underline-offset-4`},{default:n(()=>[...r[21]||=[m(` Schedules page `,-1)]]),_:1}),r[23]||=m(` or via the API. Standard 5-field cron with the usual shorthands (`,-1),r[24]||=c(`code`,{class:`doc-chip`},`@daily`,-1),r[25]||=m(`, `,-1),r[26]||=c(`code`,{class:`doc-chip`},`@hourly`,-1),r[27]||=m(`, `,-1),r[28]||=c(`code`,{class:`doc-chip`},`*/5 * * * *`,-1),r[29]||=m(`). `,-1)])])]),d(o(Q),{tabs:pn.value,"storage-key":`docs.cron`},null,8,[`tabs`]),d(o($),{icon:o(oe),title:`Cron-fired headers`},{default:n(()=>[...r[32]||=[m(` Every cron-triggered invocation arrives at the function with `,-1),c(`code`,{class:`doc-chip`},`x-orva-trigger: cron`,-1),m(` and `,-1),c(`code`,{class:`doc-chip`},`x-orva-cron-id: cron_…`,-1),m(` on the event headers, so user code can branch on origin. `,-1)]]),_:1},8,[`icon`])]),c(`section`,Ge,[c(`div`,Ke,[r[37]||=c(`span`,{class:`doc-section-num`},`06`,-1),c(`div`,null,[r[36]||=c(`h2`,{class:`doc-section-title`},` Webhooks `,-1),c(`p`,qe,[r[34]||=m(` Operator-managed subscriptions for system events. Configure URLs from the `,-1),d(a,{to:`/webhooks`,class:`text-foreground hover:text-white underline decoration-dotted underline-offset-4`},{default:n(()=>[...r[33]||=[m(` Webhooks page `,-1)]]),_:1}),r[35]||=m(`; Orva delivers signed POSTs to them when matching events fire (deployments, function lifecycle, cron failures, job outcomes). Subscriptions are global, not per-function. `,-1)])])]),d(o(rn)),r[40]||=h(`
Headers
X-Orva-EventX-Orva-Delivery-IdX-Orva-TimestampX-Orva-Signature
Signature
sha256=hex(hmac(secret, ts.body))

Same shape as Stripe / signed-invoke. Receivers verify with the secret returned at create time.

Retries
5 attemptsexp backoff (≤ 1h)

Receiver must 2xx within 15s.

`,1),c(`div`,Je,[c(`table`,Ye,[r[38]||=c(`thead`,null,[c(`tr`,null,[c(`th`,null,`Event`),c(`th`,null,`When it fires`)])],-1),c(`tbody`,null,[(t(),l(g,null,f(_n,e=>c(`tr`,{key:e.name},[c(`td`,Xe,[c(`code`,null,y(e.name),1)]),c(`td`,Ze,y(e.when),1)])),64))])])]),c(`div`,Qe,[r[39]||=c(`div`,{class:`doc-microlabel`},` Verify a delivery `,-1),d(o(Q),{tabs:vn,"storage-key":`docs.webhooks.verify`})])]),c(`section`,$e,[r[52]||=c(`div`,{class:`doc-section-head`},[c(`span`,{class:`doc-section-num`},`07`),c(`div`,null,[c(`h2`,{class:`doc-section-title`},` MCP: Model Context Protocol `),c(`p`,{class:`doc-lede`},` Same API surface the dashboard uses, exposed as 73 tools an agent can call directly. API key permissions scope the available tool set. `)])],-1),c(`div`,et,[c(`div`,tt,[r[41]||=c(`div`,{class:`doc-microlabel`},` Endpoint `,-1),c(`div`,nt,[c(`code`,rt,y(L.value)+`/mcp`,1)])]),r[42]||=h(`
Auth header
Authorization: Bearer <token>

Or as a fallback: X-Orva-API-Key: <token>

Transport
Streamable HTTPStatelessMCP 2026-07-28

Older clients negotiate down — server/discover advertises 2026-07-28, 2025-11-25, 2025-06-18, 2025-03-26 and 2024-11-05.

`,2)]),d(o($),{icon:o(w),title:`Two header formats; same auth`},{default:n(()=>[...r[43]||=[m(` Either header works against the same API key store with identical permission gating. `,-1),c(`code`,{class:`doc-chip`},`Authorization: Bearer`,-1),m(` is the MCP / OAuth 2 spec form; every MCP SDK (Claude Code, Claude Desktop, Cursor, mcp-remote, Python `,-1),c(`code`,{class:`doc-chip`},`mcp`,-1),m(`) configures it natively, so prefer it for new setups. `,-1),c(`code`,{class:`doc-chip`},`X-Orva-API-Key`,-1),m(` is the same header the REST API accepts; useful when a tool reuses an existing Orva REST integration. Internally both paths SHA-256-hash the token and look it up against the same `,-1),c(`code`,{class:`doc-chip`},`api_keys`,-1),m(` table. `,-1)]]),_:1},8,[`icon`]),d(o($),{icon:o(C),title:`No handshake, no session`},{default:n(()=>[...r[44]||=[m(` The transport is stateless. There is no `,-1),c(`code`,{class:`doc-chip`},`initialize`,-1),m(` step to perform first, no `,-1),c(`code`,{class:`doc-chip`},`Mcp-Session-Id`,-1),m(` is ever issued, and `,-1),c(`code`,{class:`doc-chip`},`GET /mcp`,-1),m(` / `,-1),c(`code`,{class:`doc-chip`},`DELETE /mcp`,-1),m(` — the SSE-resume and session-teardown verbs of the older session transport — return `,-1),c(`code`,{class:`doc-chip`},`405`,-1),m(`. Every POST carries its own bearer token and is answered on its own; a legacy client that still sends `,-1),c(`code`,{class:`doc-chip`},`initialize`,-1),m(` gets a normal reply with its own `,-1),c(`code`,{class:`doc-chip`},`protocolVersion`,-1),m(` echoed back, and simply never receives a session header. A request that opts into 2026-07-28 sends the headers `,-1),c(`code`,{class:`doc-chip`},`Mcp-Protocol-Version`,-1),m(` and `,-1),c(`code`,{class:`doc-chip`},`Mcp-Method`,-1),m(` — plus `,-1),c(`code`,{class:`doc-chip`},`Mcp-Name`,-1),m(` for `,-1),c(`code`,{class:`doc-chip`},`tools/call`,-1),m(`, `,-1),c(`code`,{class:`doc-chip`},`resources/read`,-1),m(` and `,-1),c(`code`,{class:`doc-chip`},`prompts/get`,-1),m(`, which must repeat the name from the body — plus `,-1),c(`code`,{class:`doc-chip`},`io.modelcontextprotocol/protocolVersion`,-1),m(` and `,-1),c(`code`,{class:`doc-chip`},`io.modelcontextprotocol/clientCapabilities`,-1),m(` in `,-1),c(`code`,{class:`doc-chip`},`params._meta`,-1),m(` (a `,-1),c(`code`,{class:`doc-chip`},`clientInfo`,-1),m(` key is optional). The headers let a proxy route on the operation without parsing the body, so one that disagrees with the body is rejected, not ignored. Every POST must send `,-1),c(`code`,{class:`doc-chip`},`Accept: application/json, text/event-stream`,-1),m(`. A successful reply is one SSE `,-1),c(`code`,{class:`doc-chip`},`message`,-1),m(` event; a request rejected at the transport layer comes back as plain `,-1),c(`code`,{class:`doc-chip`},`application/json`,-1),m(` with a 4xx status. `,-1)]]),_:1},8,[`icon`]),d(o($),{icon:o(T),title:`List results are private and immediately stale`},{default:n(()=>[...r[45]||=[c(`code`,{class:`doc-chip`},`tools/list`,-1),m(`, `,-1),c(`code`,{class:`doc-chip`},`resources/list`,-1),m(`, `,-1),c(`code`,{class:`doc-chip`},`resources/templates/list`,-1),m(`, `,-1),c(`code`,{class:`doc-chip`},`prompts/list`,-1),m(`, `,-1),c(`code`,{class:`doc-chip`},`resources/read`,-1),m(` and `,-1),c(`code`,{class:`doc-chip`},`server/discover`,-1),m(` results carry `,-1),c(`code`,{class:`doc-chip`},`ttlMs`,-1),m(` and `,-1),c(`code`,{class:`doc-chip`},`cacheScope`,-1),m(`. Orva returns `,-1),c(`code`,{class:`doc-chip`},`cacheScope: "private"`,-1),m(` because the tool catalog is permission-scoped (a full-permission key lists 73 tools; a `,-1),c(`code`,{class:`doc-chip`},`read`,-1),m(`-only key lists 27) and channel-specific (a channel token sees only that channel's functions) — a shared cache entry would hand one caller another caller's tool surface. `,-1),c(`code`,{class:`doc-chip`},`ttlMs`,-1),m(` is `,-1),c(`code`,{class:`doc-chip`},`0`,-1),m(` because the catalog changes on any deploy, channel edit, or permission change, and statelessness removed the session a `,-1),c(`code`,{class:`doc-chip`},`tools/list_changed`,-1),m(` notification would have travelled over. Re-list instead of caching. `,-1)]]),_:1},8,[`icon`]),c(`div`,it,[c(`div`,at,[d(o(w),{class:`w-4 h-4 shrink-0 text-foreground-muted`}),J.value?(t(),l(`span`,st,[r[48]||=m(` Token minted: `,-1),c(`code`,ct,y(Cn.value)+`…`,1),r[49]||=m(` Shown once, copy now. `,-1)])):(t(),l(`span`,ot,[r[46]||=m(` Snippets show `,-1),c(`code`,{class:`doc-chip`},y(I)),r[47]||=m(`. Mint a token to substitute it everywhere. `,-1)]))]),c(`button`,{class:`doc-token-btn`,disabled:Y.value,onClick:wn},[d(o(w),{class:`w-3.5 h-3.5`}),m(` `+y(J.value?`Mint another`:Y.value?`Minting…`:`Generate token`),1)],8,lt)]),d(o(Q),{tabs:Tn.value,"storage-key":`docs.mcp.install`},null,8,[`tabs`]),c(`details`,ut,[c(`summary`,dt,[d(o(x),{class:`w-3.5 h-3.5 transition-transform group-open:rotate-90 text-foreground-muted`}),r[50]||=m(` More clients (Cursor, VS Code, Codex CLI, OpenCode, Zed, Windsurf, ChatGPT, manual config) `,-1)]),c(`div`,ft,[d(o(Q),{tabs:En.value,"storage-key":`docs.mcp.install.more`},null,8,[`tabs`]),r[51]||=c(`div`,{class:`doc-microlabel pt-1`},` Hand-edited config files `,-1),d(o(Q),{tabs:On.value,"storage-key":`docs.mcp.manual`},null,8,[`tabs`])])])]),c(`section`,pt,[r[53]||=c(`div`,{class:`doc-section-head`},[c(`span`,{class:`doc-section-num`},`08`),c(`div`,null,[c(`h2`,{class:`doc-section-title`},` System prompt for AI assistants `),c(`p`,{class:`doc-lede`},` Copy Orva's full reference into another AI assistant. `)])],-1),c(`div`,mt,[c(`button`,{class:u([`ai-copy-btn`,{copied:V.value}]),onClick:Qt},[V.value?(t(),p(o(b),{key:0,class:`w-3.5 h-3.5`})):(t(),p(o(S),{key:1,class:`w-3.5 h-3.5`})),m(` `+y(V.value?`Copied`:`Copy system prompt`),1)],2)]),c(`div`,{class:u([`prompt-collapse`,{expanded:q.value}])},[d(o(Z),{code:o(Zt),lang:`text`},null,8,[`code`]),q.value?te(``,!0):(t(),l(`div`,ht))],2),c(`button`,{class:`prompt-expand-btn`,"aria-expanded":q.value,onClick:r[0]||=e=>q.value=!q.value},[d(o(ie),{class:u([`w-3.5 h-3.5 transition-transform`,{"rotate-180":q.value}])},null,8,[`class`]),m(` `+y(q.value?`Collapse system prompt`:`Show full system prompt`),1)],8,gt)]),c(`section`,_t,[r[55]||=h(`
09

Tracing

Every invocation chain is recorded as a causal trace. automatically, with zero changes to your function code. HTTP requests, F2F invokes, jobs, cron, inbound webhooks, and replays all stitch into the same tree. The dashboard renders it as a waterfall at /traces.

Each execution row IS a span. Spans share a trace_id; child spans point at their parent via parent_span_id. You don't instantiate spans, you don't import a tracer; you just write your handler and the platform plumbs IDs through every internal hop.

`,2),d(o(nn)),r[56]||=c(`h3`,{class:`doc-h3`},` What user code sees `,-1),r[57]||=c(`p`,{class:`doc-prose`},` Two env vars are stamped per invocation. Read them only if you want to log the trace_id alongside your own messages; they're optional. `,-1),d(o(Z),{code:zt,lang:`text`}),r[58]||=c(`h3`,{class:`doc-h3`},` Automatic propagation `,-1),r[59]||=c(`p`,{class:`doc-prose`},[m(` When a function calls another via the SDK, the trace context flows through automatically. The called function becomes a child span of the caller; both share the same `),c(`code`,{class:`doc-chip`},`trace_id`),m(`. `)],-1),d(o(Z),{code:Bt,lang:`js`}),r[60]||=h(`

Job enqueues work the same way: orva.jobs.enqueue() records the trace context on the job row. When the scheduler picks the job up later, the resulting execution lands in the same trace as the function that enqueued it, even if the gap is hours or days.

Triggers

Each span carries a trigger label so the UI can show how the chain started.

`,3),c(`div`,vt,[c(`table`,yt,[r[54]||=c(`thead`,null,[c(`tr`,null,[c(`th`,null,`Trigger`),c(`th`,null,`Meaning`)])],-1),c(`tbody`,null,[(t(),l(g,null,f(U,e=>c(`tr`,{key:e.name},[c(`td`,bt,[c(`code`,null,y(e.name),1)]),c(`td`,xt,y(e.desc),1)])),64))])])]),r[61]||=c(`h3`,{class:`doc-h3`},` External correlation (W3C traceparent) `,-1),r[62]||=c(`p`,{class:`doc-prose`},[m(` Send a standard `),c(`code`,{class:`doc-chip`},`traceparent`),m(` header on the inbound HTTP request and Orva makes its trace a child of yours. The same trace_id is echoed back as `),c(`code`,{class:`doc-chip`},`X-Trace-Id`),m(` on every response, so external systems can correlate without parsing bodies. `)],-1),d(o(Z),{code:Vt,lang:`bash`}),r[63]||=h(`

Outlier detection

Each function maintains an in-memory rolling P95 baseline over its last 100 successful warm executions. An invocation is flagged as an outlier when it has at least 20 baseline samples AND its duration exceeds P95 × 2. Cold starts and errors are excluded from the baseline so a flapping function can't drag it down. The flag and baseline P95 are stored on the execution row and rendered as an amber flag icon next to the span.

Where to look

  • /traces: list of recent traces, filterable by function / status / outlier-only.
  • /traces/:id: waterfall + per-span detail. Click a span to jump to its execution in the Invocations log.
  • GET /api/v1/traces/{id}: full span tree as JSON. Pair with list_traces / get_trace MCP tools for AI agents.
  • GET /api/v1/functions/{id}/baseline: current P95/P99/mean for a function.
`,4)]),c(`section`,St,[r[65]||=h(`
10

Errors & recovery

Every error response uses the same envelope so log scrapers and retries can match on code. Deploys are content-addressed; rollback retargets the active version pointer and refreshes warm workers.

`,1),d(o(Z),{code:Ht,lang:`json`}),c(`div`,Ct,[c(`table`,wt,[r[64]||=c(`thead`,null,[c(`tr`,null,[c(`th`,null,`Code`),c(`th`,null,`When you see it`)])],-1),c(`tbody`,null,[(t(),l(g,null,f(yn,e=>c(`tr`,{key:e.code},[c(`td`,Tt,[c(`code`,null,y(e.code),1)]),c(`td`,Et,y(e.when),1)])),64))])])])]),c(`section`,Dt,[r[82]||=h(`
11

CLI

Orva ships a full Linux server binary and a slim cross-platform CLI, both named orva. They share every client command; only the full build adds serve, setup, and init.

Install (server included)
curl … install.sh | sh

Full install: daemon + nsjail + rootfs + CLI.

Install (CLI only)
curl … install-cli.sh | sh

~20 MB binary at /usr/local/bin/orva. No service.

Inside Docker
docker exec orva orva …

CLI auto-authed via ~/.orva/config.yaml.

Authenticate

`,3),c(`p`,Ot,[r[67]||=m(` The CLI reads `,-1),r[68]||=c(`code`,{class:`doc-chip`},`~/.orva/config.yaml`,-1),r[69]||=m(` for `,-1),r[70]||=c(`code`,{class:`doc-chip`},`endpoint`,-1),r[71]||=m(` + `,-1),r[72]||=c(`code`,{class:`doc-chip`},`api_key`,-1),r[73]||=m(`. Generate a key from `,-1),d(a,{to:`/api-keys`,class:`text-foreground hover:text-white underline decoration-dotted underline-offset-4`},{default:n(()=>[...r[66]||=[m(` Keys `,-1)]]),_:1}),r[74]||=m(` in the dashboard, then: `,-1)]),d(o(Z),{code:Ut,lang:`bash`}),r[83]||=c(`h3`,{class:`doc-h3`},` Command index `,-1),c(`div`,kt,[c(`table`,At,[r[75]||=c(`thead`,null,[c(`tr`,null,[c(`th`,null,`Command`),c(`th`,null,`Subcommands`),c(`th`,{class:`hidden md:table-cell`},` Purpose `)])],-1),c(`tbody`,null,[(t(),l(g,null,f(bn,e=>c(`tr`,{key:e.cmd},[c(`td`,jt,[c(`code`,null,`orva `+y(e.cmd),1)]),c(`td`,Mt,y(e.subs),1),c(`td`,Nt,y(e.purpose),1)])),64))])])]),r[84]||=c(`h3`,{class:`doc-h3`},` Common recipes `,-1),c(`div`,Pt,[r[76]||=c(`div`,{class:`doc-microlabel`},` Deploy a function from a directory `,-1),d(o(Z),{code:Wt,lang:`bash`})]),c(`div`,Ft,[r[77]||=c(`div`,{class:`doc-microlabel`},` Invoke + tail logs `,-1),d(o(Z),{code:Gt,lang:`bash`})]),c(`div`,It,[r[78]||=c(`div`,{class:`doc-microlabel`},` Manage KV state `,-1),d(o(Z),{code:Kt,lang:`bash`})]),c(`div`,Lt,[r[79]||=c(`div`,{class:`doc-microlabel`},` Secrets, cron, jobs, webhooks `,-1),d(o(Z),{code:qt,lang:`bash`})]),c(`div`,Rt,[r[80]||=c(`div`,{class:`doc-microlabel`},` System health, metrics, vacuum `,-1),d(o(Z),{code:Jt,lang:`bash`})]),d(o($),{icon:o(w),title:`Shell completion`},{default:n(()=>[...r[81]||=[m(` Generate completion for your shell: `,-1),c(`code`,{class:`doc-chip`},`orva completion bash | sudo tee /etc/bash_completion.d/orva`,-1),m(`, or `,-1),c(`code`,{class:`doc-chip`},`zsh`,-1),m(` / `,-1),c(`code`,{class:`doc-chip`},`fish`,-1),m(` / `,-1),c(`code`,{class:`doc-chip`},`powershell`,-1),m(`. Tab-completes commands, subcommands, and flags. `,-1)]]),_:1},8,[`icon`])])])}}};export{Yt as default}; \ No newline at end of file diff --git a/backend/internal/server/ui_dist/assets/Docs-D8AUJ3IN.css b/backend/internal/server/ui_dist/assets/Docs-D8AUJ3IN.css new file mode 100644 index 00000000..d765d944 --- /dev/null +++ b/backend/internal/server/ui_dist/assets/Docs-D8AUJ3IN.css @@ -0,0 +1 @@ +.docs-hero{border-bottom:1px solid var(--color-border)}.docs-hero-content{flex-direction:column;gap:1rem;padding:0 0 1.5rem;display:flex}@media (width>=640px){.docs-hero-content{gap:1.25rem;padding-bottom:1.5rem}}.docs-hero-row{flex-direction:column;align-items:stretch;gap:1rem;display:flex}@media (width>=768px){.docs-hero-row{flex-direction:row;justify-content:space-between;align-items:flex-start;gap:2rem}}.docs-hero-text{max-width:56ch}.docs-hero-title{font-family:var(--font-sans);letter-spacing:-.02em;color:var(--color-foreground);margin:0;font-size:20px;font-weight:600;line-height:1.05}.docs-hero-sub{font-family:var(--font-sans);color:var(--color-foreground-muted);margin:.6rem 0 0;font-size:14px;line-height:1.55}.docs-hero-actions{flex-shrink:0;align-items:flex-start;display:flex}.docs-hero-copy-icon{border:1px solid var(--color-border);background:var(--color-surface);width:2.2rem;height:2.2rem;color:var(--color-foreground-muted);cursor:pointer;border-radius:.45rem;justify-content:center;align-items:center;transition:color .12s,border-color .12s,background-color .12s;display:inline-flex}.docs-hero-copy-icon:hover{color:var(--color-foreground);border-color:var(--color-foreground-muted);background:var(--color-surface-hover,#ffffff0a)}.docs-hero-copy-icon:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}.docs-hero-copy-icon.copied{color:var(--color-success-fg);background:#4caf5014;border-color:#4caf5073}.docs-hero-copy{border:1px solid var(--color-border);background:var(--color-surface);color:var(--color-foreground);font-family:var(--font-sans);cursor:pointer;border-radius:.5rem;align-items:center;gap:.45rem;padding:.55rem .9rem;font-size:12.5px;font-weight:500;transition:background-color .12s,border-color .12s,color .12s;display:inline-flex}.docs-hero-copy:hover{background:var(--color-surface-hover,#ffffff0a);border-color:var(--color-foreground-muted)}.docs-hero-copy:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}.docs-hero-copy.copied{color:var(--color-success-fg);background:#4caf5014;border-color:#4caf5066}.docs-hero-toc{border-top:1px dashed #ffffff0d;flex-wrap:wrap;align-items:center;gap:.4rem;padding-top:1rem;display:flex}.docs-hero-toc-label{font-family:var(--font-mono);letter-spacing:.18em;text-transform:uppercase;color:var(--color-foreground-muted);margin-right:.3rem;font-size:10px;font-weight:600}.docs-hero-toc-link{border:1px solid var(--color-border);background:var(--color-surface);color:var(--color-foreground-muted);font-family:var(--font-sans);border-radius:.4rem;align-items:center;gap:.4rem;padding:.32rem .6rem;font-size:11.5px;font-weight:500;text-decoration:none;transition:color .12s,border-color .12s,background-color .12s;display:inline-flex}.docs-hero-toc-link:hover{color:var(--color-foreground);border-color:var(--color-foreground-muted)}.docs-hero-toc-link.active{color:var(--color-foreground);border-color:var(--color-primary);background:#553f832e}.docs-hero-toc-num{font-family:var(--font-mono);letter-spacing:.04em;color:var(--color-foreground-muted);opacity:.7;font-size:10px}.docs-hero-toc-link.active .docs-hero-toc-num{color:#ffffffd9;opacity:1}.doc-diagram{border:1px solid var(--color-border);background:radial-gradient(ellipse 50% 80% at 100% 0%, #553f830f 0%, transparent 70%), var(--color-background);border-radius:.7rem;margin:0 0 .75rem;padding:1.2rem 1.2rem 1.4rem}.doc-diagram-cap{font-family:var(--font-mono);letter-spacing:.16em;text-transform:uppercase;color:var(--color-foreground-muted);margin:0 0 1rem;font-size:10px;font-weight:600}.doc-pipeline{justify-content:center;align-items:stretch;gap:.4rem;padding-bottom:.4rem;display:flex;overflow-x:auto}.doc-pipeline-stage{border:1px solid var(--color-border);background:var(--color-surface);border-radius:.55rem;flex-shrink:0;align-items:center;gap:.6rem;min-width:0;padding:.65rem .85rem;display:flex}.doc-pipeline-glyph{width:1.6rem;height:1.6rem;color:var(--color-foreground);font-family:var(--font-mono);background:#553f832e;border:1px solid #553f8373;border-radius:.4rem;justify-content:center;align-items:center;font-size:13px;line-height:1;display:inline-flex}.doc-pipeline-label{flex-direction:column;gap:.05rem;min-width:0;display:flex}.doc-pipeline-name{font-family:var(--font-sans);color:var(--color-foreground);white-space:nowrap;font-size:12.5px;font-weight:600}.doc-pipeline-sub{font-family:var(--font-mono);color:var(--color-foreground-muted);white-space:nowrap;font-size:10px}.doc-pipeline-arrow{background:linear-gradient(90deg,#ffffff0d 0%,#ffffff2e 100%);flex-shrink:0;align-self:center;width:1.6rem;height:1px;position:relative}.doc-pipeline-arrow:after{content:"";border-top:1px solid #ffffff59;border-right:1px solid #ffffff59;width:.42rem;height:.42rem;position:absolute;top:50%;right:-2px;transform:translateY(-50%)rotate(45deg)}.doc-trace{flex-direction:column;gap:.55rem;display:flex}.doc-trace-axis{font-family:var(--font-mono);color:var(--color-foreground-muted);border-bottom:1px dashed #ffffff0d;justify-content:space-between;padding:0 0 .2rem;font-size:10px;display:flex}.doc-trace-row{font-family:var(--font-sans);grid-template-columns:11rem 1fr 3rem;align-items:center;gap:.7rem;display:grid}.doc-trace-row.is-child .doc-trace-label,.doc-trace-row.is-grand .doc-trace-label{position:relative}.doc-trace-row.is-child .doc-trace-label:before,.doc-trace-row.is-grand .doc-trace-label:before{content:"└";color:var(--color-foreground-muted);font-family:var(--font-mono);opacity:.55;position:absolute;top:.05rem;left:-.7rem}.doc-trace-row.is-child .doc-trace-label,.doc-trace-row.is-grand .doc-trace-label{padding-left:1rem}.doc-trace-label{align-items:center;gap:.45rem;min-width:0;display:flex}.doc-trace-fn{color:var(--color-foreground);white-space:nowrap;text-overflow:ellipsis;font-size:12.5px;font-weight:500;overflow:hidden}.doc-trace-trigger{font-family:var(--font-mono);letter-spacing:.06em;text-transform:lowercase;color:var(--color-foreground-muted);border:1px solid var(--color-border);background:var(--color-background);border-radius:.25rem;padding:.05rem .35rem;font-size:9.5px}.doc-trace-track{background:#ffffff06;border-radius:999px;height:10px;position:relative;overflow:hidden}.doc-trace-bar{background:linear-gradient(90deg,#553f83d9 0%,#553f838c 100%);border-radius:999px;position:absolute;top:1px;bottom:1px;box-shadow:0 0 12px #553f8340}.doc-trace-row.is-child .doc-trace-bar{background:linear-gradient(90deg,#60a5facc 0%,#60a5fa80 100%);box-shadow:0 0 10px #60a5fa40}.doc-trace-row.is-grand .doc-trace-bar{background:linear-gradient(90deg,#34d399cc 0%,#34d39980 100%);box-shadow:0 0 10px #34d39940}.doc-trace-dur{font-family:var(--font-mono);color:var(--color-foreground);text-align:right;font-size:10.5px}.doc-trace-legend{font-family:var(--font-sans);color:var(--color-foreground-muted);border-top:1px dashed #ffffff0d;padding-top:.4rem;font-size:11.5px}.doc-webhook{grid-template-columns:1fr;align-items:stretch;gap:.7rem;display:grid}@media (width>=768px){.doc-webhook{grid-template-columns:1fr 1.4fr 1fr}}.doc-webhook-actor{border:1px solid var(--color-border);background:var(--color-surface);border-radius:.55rem;flex-direction:column;gap:.4rem;padding:.85rem;display:flex}.doc-webhook-actor-head{font-family:var(--font-mono);color:var(--color-foreground);letter-spacing:.06em;font-size:11px;font-weight:600}.doc-webhook-actor-body{font-family:var(--font-sans);color:var(--color-foreground-muted);flex-direction:column;gap:.3rem;font-size:11.5px;display:flex}.doc-webhook-wire{background:radial-gradient(80% 100%,#553f8314 0%,#0000 70%);border:1px dashed #553f8373;border-radius:.55rem;flex-direction:column;justify-content:center;align-items:stretch;padding:.85rem .7rem;display:flex;position:relative}.doc-webhook-wire-line{display:none}.doc-webhook-wire-payload{font-family:var(--font-sans);flex-direction:column;gap:.45rem;font-size:11.5px;display:flex}.doc-webhook-wire-method{color:var(--color-foreground);font-family:var(--font-mono);letter-spacing:.08em;background:#553f8340;border:1px solid #553f838c;border-radius:.3rem;align-self:flex-start;align-items:center;padding:.15rem .55rem;font-size:10.5px;font-weight:600;display:inline-flex}.doc-webhook-wire-headers{flex-wrap:wrap;gap:.3rem;display:flex}.doc-webhook-wire-headers code{font-family:var(--font-mono);border:1px solid var(--color-border);background:var(--color-background);color:var(--color-foreground);border-radius:.25rem;padding:.1rem .4rem;font-size:10.5px}.doc-webhook-wire-sig{font-family:var(--font-mono);color:var(--color-foreground-muted);border-top:1px dashed #ffffff0d;padding-top:.2rem;font-size:10.5px}.prompt-collapse{border-radius:.6rem;max-height:9.5rem;position:relative;overflow:hidden}.prompt-collapse.expanded{max-height:7000px}.prompt-collapse-fade{pointer-events:none;background:linear-gradient(180deg, transparent 0%, var(--color-background) 85%);border-radius:0 0 .6rem .6rem;height:4.5rem;position:absolute;inset:auto 0 0}.prompt-expand-btn{border:1px solid var(--color-border);background:var(--color-surface);color:var(--color-foreground-muted);font-family:var(--font-sans);cursor:pointer;border-radius:.45rem;align-items:center;gap:.4rem;margin-top:.5rem;padding:.45rem .85rem;font-size:12px;font-weight:500;transition:color .12s,border-color .12s,background-color .12s;display:inline-flex}.prompt-expand-btn:hover{color:var(--color-foreground);border-color:var(--color-foreground-muted)}.prompt-expand-btn:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}.doc-section-head{align-items:flex-start;gap:.85rem;display:flex}.doc-section-num{background:linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-hover) 100%);width:1.85rem;height:1.85rem;color:var(--color-primary-foreground);font-family:var(--font-mono);letter-spacing:.04em;border-radius:.5rem;flex-shrink:0;justify-content:center;align-items:center;font-size:11px;font-weight:700;display:inline-flex;box-shadow:inset 0 0 0 1px #ffffff0a,0 6px 18px -8px #553f8399}.doc-section-title{font-family:var(--font-sans);letter-spacing:-.01em;color:var(--color-foreground);margin:0;font-size:1.05rem;font-weight:600;line-height:1.25}.doc-lede{font-family:var(--font-sans);color:var(--color-foreground-muted);max-width:64ch;margin:.35rem 0 0;font-size:13px;line-height:1.6}.doc-chip{font-family:var(--font-mono);background:var(--color-surface);border:1px solid var(--color-border);color:var(--color-foreground);white-space:nowrap;vertical-align:baseline;border-radius:.3rem;margin:0 .05rem;padding:.1rem .4rem;font-size:11.5px;line-height:1.4;display:inline-block}.doc-chip.break-all{white-space:normal;word-break:break-all}.doc-microlabel{font-family:var(--font-sans);letter-spacing:-.005em;color:var(--color-foreground);text-transform:none;border-left:2px solid #553f838c;padding-left:.55rem;font-size:12.5px;font-weight:600}.doc-card .doc-microlabel{color:var(--color-foreground);border-left:none;padding-left:0;font-size:12px;font-weight:600}.doc-card{background:linear-gradient(180deg, #ffffff04 0%, transparent 100%), var(--color-background);border:1px solid var(--color-border);border-radius:.6rem;flex-direction:column;gap:.5rem;padding:.85rem .95rem;transition:border-color .16s;display:flex;position:relative}.doc-card:hover{border-color:#553f8399}.doc-card-body{font-family:var(--font-sans);color:var(--color-foreground);flex-wrap:wrap;align-items:center;gap:.3rem .35rem;font-size:13px;line-height:1.55;display:flex}.doc-card-body p{flex-basis:100%;margin:0;font-size:12.5px;line-height:1.55}.doc-step-label{font-family:var(--font-sans);letter-spacing:-.005em;color:var(--color-foreground);align-items:center;gap:.55rem;font-size:12.5px;font-weight:600;display:flex}.doc-step-num{width:1.1rem;height:1.1rem;color:var(--color-foreground);letter-spacing:0;background:#553f832e;border:1px solid #553f8399;border-radius:999px;justify-content:center;align-items:center;font-size:10px;font-weight:700;display:inline-flex}.doc-table-wrap{background:var(--color-background);border:1px solid var(--color-border);border-radius:.6rem;overflow:hidden}.doc-table{border-collapse:collapse;width:100%;font-family:var(--font-sans)}.doc-table thead{background:var(--color-surface);border-bottom:1px solid var(--color-border)}.doc-table thead th{text-align:left;font-family:var(--font-mono);letter-spacing:.14em;text-transform:uppercase;color:var(--color-foreground-muted);padding:.7rem 1rem;font-size:10px;font-weight:600}.doc-table tbody tr{border-top:1px solid var(--color-border);transition:background-color .12s}.doc-table tbody tr:first-child{border-top:0}.doc-table tbody tr:hover{background:#ffffff04}.doc-table td{vertical-align:top;padding:.75rem 1rem}.doc-cell-key{font-family:var(--font-sans);color:var(--color-foreground);align-items:center;gap:.5rem;font-size:13px;font-weight:500;display:flex}.doc-cell-key code{font-family:var(--font-mono);color:var(--color-foreground);font-size:12px;font-weight:500}.doc-cell-mono{font-family:var(--font-mono);color:var(--color-foreground-muted);font-size:12px}.doc-cell-body{font-family:var(--font-sans);color:var(--color-foreground);font-size:12.5px;line-height:1.55}.doc-token-bar{background:linear-gradient(90deg, #553f831a 0%, #553f8305 70%, transparent 100%), var(--color-background);border:1px solid var(--color-border);border-radius:.6rem;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:.85rem;padding:.65rem .85rem;display:flex}.doc-token-btn{font-family:var(--font-sans);color:var(--color-foreground);background:var(--color-surface);border:1px solid var(--color-border);cursor:pointer;border-radius:.4rem;align-items:center;gap:.45rem;padding:.45rem .85rem;font-size:12.5px;font-weight:500;transition:background .12s,border-color .12s;display:inline-flex}.doc-token-btn:hover{background:var(--color-surface-hover);border-color:#553f8399}.doc-token-btn:disabled{opacity:.5;cursor:not-allowed}.doc-details{background:var(--color-background);border:1px solid var(--color-border);border-radius:.6rem;overflow:hidden}.doc-details-summary{cursor:pointer;font-family:var(--font-sans);color:var(--color-foreground);-webkit-user-select:none;user-select:none;align-items:center;gap:.5rem;padding:.7rem .95rem;font-size:13px;font-weight:500;list-style:none;transition:background .12s;display:flex}.doc-details-summary::-webkit-details-marker{display:none}.doc-details-summary:hover{background:#ffffff05}.doc-details[open]>.doc-details-summary{border-bottom:1px solid var(--color-border)}.doc-details-body{padding:.85rem}.codeblock{background:var(--color-background);border:1px solid var(--color-border);border-radius:.6rem;overflow:hidden}.codeblock-bar{background:var(--color-surface);border-bottom:1px solid var(--color-border);justify-content:space-between;align-items:center;padding:.45rem .85rem;display:flex}.codeblock-lang{font-family:var(--font-mono);letter-spacing:.14em;text-transform:uppercase;color:var(--color-foreground-muted);font-size:10px;font-weight:600}.codeblock-copy{background:var(--color-background);border:1px solid var(--color-border);color:var(--color-foreground-muted);font-family:var(--font-sans);cursor:pointer;border-radius:.35rem;align-items:center;gap:.35rem;padding:.3rem .6rem;font-size:11.5px;transition:color .12s,border-color .12s,background .12s;display:inline-flex}.codeblock-copy:hover{color:var(--color-foreground);background:var(--color-surface-hover);border-color:#553f8399}.codeblock-pre{font-family:var(--font-mono);color:var(--color-foreground-muted);background:var(--color-background);margin:0;padding:.95rem 1.1rem;font-size:12.5px;line-height:1.6;overflow-x:auto}.codeblock-pre code{font-family:inherit;font-size:inherit;line-height:inherit;background:0 0!important;padding:0!important}.tabbed{background:var(--color-background);border:1px solid var(--color-border);border-radius:.6rem;overflow:hidden}.tabbed-tabs{background:var(--color-surface);border-bottom:1px solid var(--color-border);flex-wrap:wrap;gap:0;padding:0 .35rem;display:flex}.tabbed-tab{font-family:var(--font-sans);color:var(--color-foreground-muted);cursor:pointer;background:0 0;border:0;padding:.6rem .95rem;font-size:12.5px;font-weight:500;transition:color .12s;position:relative}.tabbed-tab:hover{color:var(--color-foreground)}.tabbed-tab.active{color:var(--color-foreground);font-weight:600}.tabbed-tab.active:after{content:"";background:var(--color-primary);border-radius:2px 2px 0 0;height:2px;position:absolute;bottom:-1px;left:.6rem;right:.6rem}.tabbed-note{border-bottom:1px solid var(--color-border);background:var(--color-surface);color:var(--color-foreground-muted);font-family:var(--font-sans);padding:.65rem .95rem;font-size:12px;line-height:1.55}.tabbed>.codeblock{border:0;border-radius:0}.callout{background:linear-gradient(90deg, #553f8314 0%, #553f8303 60%, transparent 100%), var(--color-background);border:1px solid var(--color-border);border-radius:.6rem;flex-direction:column;gap:.4rem;padding:.85rem 1rem;display:flex}.callout-head{font-family:var(--font-mono);letter-spacing:.14em;text-transform:uppercase;color:var(--color-foreground-muted);align-items:center;gap:.5rem;font-size:10px;font-weight:600;display:flex}.callout-icon{width:.95rem;height:.95rem}.callout-body{font-family:var(--font-sans);color:var(--color-foreground);flex-wrap:wrap;align-items:center;gap:.3rem .4rem;font-size:13px;line-height:1.55;display:flex}.ai-prompt-actions{flex-wrap:wrap;align-items:center;gap:.75rem;display:flex}.ai-copy-btn{border:1px solid var(--color-border);background:var(--color-surface);color:var(--color-foreground-muted);cursor:pointer;border-radius:6px;align-items:center;gap:.4rem;padding:.4rem .75rem;font-size:12px;transition:color .15s,border-color .15s;display:inline-flex}.ai-copy-btn:hover{color:#fff;border-color:var(--color-foreground-muted)}.ai-copy-btn.copied{color:var(--color-success-fg);border-color:#4ade8066}.codeblock-pre .hljs{color:inherit;padding:0;background:0 0!important} diff --git a/backend/internal/server/ui_dist/assets/Docs-r0iOi4Nz.css b/backend/internal/server/ui_dist/assets/Docs-r0iOi4Nz.css deleted file mode 100644 index e4e3d2a2..00000000 --- a/backend/internal/server/ui_dist/assets/Docs-r0iOi4Nz.css +++ /dev/null @@ -1 +0,0 @@ -.docs-hero{border:1px solid var(--color-border);background:radial-gradient(ellipse 60% 80% at 0% 0%, #553f831f 0%, #553f8300 60%), linear-gradient(180deg, #ffffff03 0%, transparent 100%), var(--color-background);border-radius:.85rem;position:relative;overflow:hidden}.docs-hero-bg{pointer-events:none;background-image:radial-gradient(#ffffff06 1px,#0000 1px);background-position:0 0;background-size:14px 14px;position:absolute;inset:0;-webkit-mask-image:linear-gradient(#000 0%,#0000 100%);mask-image:linear-gradient(#000 0%,#0000 100%)}.docs-hero-content{flex-direction:column;gap:1rem;padding:1.6rem 1.5rem 1.2rem;display:flex;position:relative}@media (width>=640px){.docs-hero-content{gap:1.4rem;padding:2.2rem 2.2rem 1.6rem}}.docs-hero-eyebrow{align-items:center;gap:.55rem;display:inline-flex}.docs-hero-eyebrow-mark{background:var(--color-primary);border-radius:999px;width:6px;height:6px;display:inline-block;box-shadow:0 0 12px #553f8399}.docs-hero-eyebrow-label{font-family:var(--font-mono);letter-spacing:.2em;text-transform:uppercase;color:var(--color-foreground-muted);font-size:10px;font-weight:600}.docs-hero-row{flex-direction:column;align-items:stretch;gap:1rem;display:flex}@media (width>=768px){.docs-hero-row{flex-direction:row;justify-content:space-between;align-items:flex-start;gap:2rem}}.docs-hero-text{max-width:56ch}.docs-hero-title{font-family:var(--font-sans);letter-spacing:-.02em;color:var(--color-foreground);margin:0;font-size:30px;font-weight:600;line-height:1.05}@media (width>=640px){.docs-hero-title{font-size:38px}}.docs-hero-sub{font-family:var(--font-sans);color:var(--color-foreground-muted);margin:.6rem 0 0;font-size:13.5px;line-height:1.55}.docs-hero-actions{flex-shrink:0;align-items:flex-start;display:flex}.docs-hero-copy-icon{border:1px solid var(--color-border);background:var(--color-surface);width:2.2rem;height:2.2rem;color:var(--color-foreground-muted);cursor:pointer;border-radius:.45rem;justify-content:center;align-items:center;transition:color .12s,border-color .12s,background-color .12s;display:inline-flex}.docs-hero-copy-icon:hover{color:var(--color-foreground);border-color:var(--color-foreground-muted);background:var(--color-surface-hover,#ffffff0a)}.docs-hero-copy-icon:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}.docs-hero-copy-icon.copied{color:var(--color-success-fg);background:#4caf5014;border-color:#4caf5073}.docs-hero-copy{border:1px solid var(--color-border);background:var(--color-surface);color:var(--color-foreground);font-family:var(--font-sans);cursor:pointer;border-radius:.5rem;align-items:center;gap:.45rem;padding:.55rem .9rem;font-size:12.5px;font-weight:500;transition:background-color .12s,border-color .12s,color .12s;display:inline-flex}.docs-hero-copy:hover{background:var(--color-surface-hover,#ffffff0a);border-color:var(--color-foreground-muted)}.docs-hero-copy:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}.docs-hero-copy.copied{color:var(--color-success-fg);background:#4caf5014;border-color:#4caf5066}.docs-hero-toc{border-top:1px dashed #ffffff0d;flex-wrap:wrap;align-items:center;gap:.4rem;padding-top:1rem;display:flex}.docs-hero-toc-label{font-family:var(--font-mono);letter-spacing:.18em;text-transform:uppercase;color:var(--color-foreground-muted);margin-right:.3rem;font-size:10px;font-weight:600}.docs-hero-toc-link{border:1px solid var(--color-border);background:var(--color-surface);color:var(--color-foreground-muted);font-family:var(--font-sans);border-radius:.4rem;align-items:center;gap:.4rem;padding:.32rem .6rem;font-size:11.5px;font-weight:500;text-decoration:none;transition:color .12s,border-color .12s,background-color .12s;display:inline-flex}.docs-hero-toc-link:hover{color:var(--color-foreground);border-color:var(--color-foreground-muted)}.docs-hero-toc-link.active{color:var(--color-foreground);border-color:var(--color-primary);background:#553f832e}.docs-hero-toc-num{font-family:var(--font-mono);letter-spacing:.04em;color:var(--color-foreground-muted);opacity:.7;font-size:10px}.docs-hero-toc-link.active .docs-hero-toc-num{color:#ffffffd9;opacity:1}.doc-diagram{border:1px solid var(--color-border);background:radial-gradient(ellipse 50% 80% at 100% 0%, #553f830f 0%, transparent 70%), var(--color-background);border-radius:.7rem;margin:0 0 .75rem;padding:1.2rem 1.2rem 1.4rem}.doc-diagram-cap{font-family:var(--font-mono);letter-spacing:.16em;text-transform:uppercase;color:var(--color-foreground-muted);margin:0 0 1rem;font-size:10px;font-weight:600}.doc-pipeline{justify-content:center;align-items:stretch;gap:.4rem;padding-bottom:.4rem;display:flex;overflow-x:auto}.doc-pipeline-stage{border:1px solid var(--color-border);background:var(--color-surface);border-radius:.55rem;flex-shrink:0;align-items:center;gap:.6rem;min-width:0;padding:.65rem .85rem;display:flex}.doc-pipeline-glyph{width:1.6rem;height:1.6rem;color:var(--color-foreground);font-family:var(--font-mono);background:#553f832e;border:1px solid #553f8373;border-radius:.4rem;justify-content:center;align-items:center;font-size:13px;line-height:1;display:inline-flex}.doc-pipeline-label{flex-direction:column;gap:.05rem;min-width:0;display:flex}.doc-pipeline-name{font-family:var(--font-sans);color:var(--color-foreground);white-space:nowrap;font-size:12.5px;font-weight:600}.doc-pipeline-sub{font-family:var(--font-mono);color:var(--color-foreground-muted);white-space:nowrap;font-size:10px}.doc-pipeline-arrow{background:linear-gradient(90deg,#ffffff0d 0%,#ffffff2e 100%);flex-shrink:0;align-self:center;width:1.6rem;height:1px;position:relative}.doc-pipeline-arrow:after{content:"";border-top:1px solid #ffffff59;border-right:1px solid #ffffff59;width:.42rem;height:.42rem;position:absolute;top:50%;right:-2px;transform:translateY(-50%)rotate(45deg)}.doc-trace{flex-direction:column;gap:.55rem;display:flex}.doc-trace-axis{font-family:var(--font-mono);color:var(--color-foreground-muted);border-bottom:1px dashed #ffffff0d;justify-content:space-between;padding:0 0 .2rem;font-size:10px;display:flex}.doc-trace-row{font-family:var(--font-sans);grid-template-columns:11rem 1fr 3rem;align-items:center;gap:.7rem;display:grid}.doc-trace-row.is-child .doc-trace-label,.doc-trace-row.is-grand .doc-trace-label{position:relative}.doc-trace-row.is-child .doc-trace-label:before,.doc-trace-row.is-grand .doc-trace-label:before{content:"└";color:var(--color-foreground-muted);font-family:var(--font-mono);opacity:.55;position:absolute;top:.05rem;left:-.7rem}.doc-trace-row.is-child .doc-trace-label,.doc-trace-row.is-grand .doc-trace-label{padding-left:1rem}.doc-trace-label{align-items:center;gap:.45rem;min-width:0;display:flex}.doc-trace-fn{color:var(--color-foreground);white-space:nowrap;text-overflow:ellipsis;font-size:12.5px;font-weight:500;overflow:hidden}.doc-trace-trigger{font-family:var(--font-mono);letter-spacing:.06em;text-transform:lowercase;color:var(--color-foreground-muted);border:1px solid var(--color-border);background:var(--color-background);border-radius:.25rem;padding:.05rem .35rem;font-size:9.5px}.doc-trace-track{background:#ffffff06;border-radius:999px;height:10px;position:relative;overflow:hidden}.doc-trace-bar{background:linear-gradient(90deg,#553f83d9 0%,#553f838c 100%);border-radius:999px;position:absolute;top:1px;bottom:1px;box-shadow:0 0 12px #553f8340}.doc-trace-row.is-child .doc-trace-bar{background:linear-gradient(90deg,#60a5facc 0%,#60a5fa80 100%);box-shadow:0 0 10px #60a5fa40}.doc-trace-row.is-grand .doc-trace-bar{background:linear-gradient(90deg,#34d399cc 0%,#34d39980 100%);box-shadow:0 0 10px #34d39940}.doc-trace-dur{font-family:var(--font-mono);color:var(--color-foreground);text-align:right;font-size:10.5px}.doc-trace-legend{font-family:var(--font-sans);color:var(--color-foreground-muted);border-top:1px dashed #ffffff0d;padding-top:.4rem;font-size:11.5px}.doc-webhook{grid-template-columns:1fr;align-items:stretch;gap:.7rem;display:grid}@media (width>=768px){.doc-webhook{grid-template-columns:1fr 1.4fr 1fr}}.doc-webhook-actor{border:1px solid var(--color-border);background:var(--color-surface);border-radius:.55rem;flex-direction:column;gap:.4rem;padding:.85rem;display:flex}.doc-webhook-actor-head{font-family:var(--font-mono);color:var(--color-foreground);letter-spacing:.06em;font-size:11px;font-weight:600}.doc-webhook-actor-body{font-family:var(--font-sans);color:var(--color-foreground-muted);flex-direction:column;gap:.3rem;font-size:11.5px;display:flex}.doc-webhook-wire{background:radial-gradient(80% 100%,#553f8314 0%,#0000 70%);border:1px dashed #553f8373;border-radius:.55rem;flex-direction:column;justify-content:center;align-items:stretch;padding:.85rem .7rem;display:flex;position:relative}.doc-webhook-wire-line{display:none}.doc-webhook-wire-payload{font-family:var(--font-sans);flex-direction:column;gap:.45rem;font-size:11.5px;display:flex}.doc-webhook-wire-method{color:var(--color-foreground);font-family:var(--font-mono);letter-spacing:.08em;background:#553f8340;border:1px solid #553f838c;border-radius:.3rem;align-self:flex-start;align-items:center;padding:.15rem .55rem;font-size:10.5px;font-weight:600;display:inline-flex}.doc-webhook-wire-headers{flex-wrap:wrap;gap:.3rem;display:flex}.doc-webhook-wire-headers code{font-family:var(--font-mono);border:1px solid var(--color-border);background:var(--color-background);color:var(--color-foreground);border-radius:.25rem;padding:.1rem .4rem;font-size:10.5px}.doc-webhook-wire-sig{font-family:var(--font-mono);color:var(--color-foreground-muted);border-top:1px dashed #ffffff0d;padding-top:.2rem;font-size:10.5px}.prompt-collapse{border-radius:.6rem;max-height:9.5rem;transition:max-height .28s;position:relative;overflow:hidden}.prompt-collapse.expanded{max-height:7000px}.prompt-collapse-fade{pointer-events:none;background:linear-gradient(180deg, transparent 0%, var(--color-background) 85%);border-radius:0 0 .6rem .6rem;height:4.5rem;position:absolute;inset:auto 0 0}.prompt-expand-btn{border:1px solid var(--color-border);background:var(--color-surface);color:var(--color-foreground-muted);font-family:var(--font-sans);cursor:pointer;border-radius:.45rem;align-items:center;gap:.4rem;margin-top:.5rem;padding:.45rem .85rem;font-size:12px;font-weight:500;transition:color .12s,border-color .12s,background-color .12s;display:inline-flex}.prompt-expand-btn:hover{color:var(--color-foreground);border-color:var(--color-foreground-muted)}.prompt-expand-btn:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}.doc-section-head{align-items:flex-start;gap:.85rem;display:flex}.doc-section-num{background:linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-hover) 100%);width:1.85rem;height:1.85rem;color:var(--color-primary-foreground);font-family:var(--font-mono);letter-spacing:.04em;border-radius:.5rem;flex-shrink:0;justify-content:center;align-items:center;font-size:11px;font-weight:700;display:inline-flex;box-shadow:inset 0 0 0 1px #ffffff0a,0 6px 18px -8px #553f8399}.doc-section-title{font-family:var(--font-sans);letter-spacing:-.01em;color:var(--color-foreground);margin:0;font-size:1.05rem;font-weight:600;line-height:1.25}.doc-lede{font-family:var(--font-sans);color:var(--color-foreground-muted);max-width:64ch;margin:.35rem 0 0;font-size:13px;line-height:1.6}.doc-chip{font-family:var(--font-mono);background:var(--color-surface);border:1px solid var(--color-border);color:var(--color-foreground);white-space:nowrap;vertical-align:baseline;border-radius:.3rem;margin:0 .05rem;padding:.1rem .4rem;font-size:11.5px;line-height:1.4;display:inline-block}.doc-chip.break-all{white-space:normal;word-break:break-all}.doc-microlabel{font-family:var(--font-sans);letter-spacing:-.005em;color:var(--color-foreground);text-transform:none;border-left:2px solid #553f838c;padding-left:.55rem;font-size:12.5px;font-weight:600}.doc-card .doc-microlabel{color:var(--color-foreground);border-left:none;padding-left:0;font-size:12px;font-weight:600}.doc-card{background:linear-gradient(180deg, #ffffff04 0%, transparent 100%), var(--color-background);border:1px solid var(--color-border);border-radius:.6rem;flex-direction:column;gap:.5rem;padding:.85rem .95rem;transition:border-color .16s;display:flex;position:relative}.doc-card:hover{border-color:#553f8399}.doc-card-body{font-family:var(--font-sans);color:var(--color-foreground);flex-wrap:wrap;align-items:center;gap:.3rem .35rem;font-size:13px;line-height:1.55;display:flex}.doc-card-body p{flex-basis:100%;margin:0;font-size:12.5px;line-height:1.55}.doc-step-label{font-family:var(--font-sans);letter-spacing:-.005em;color:var(--color-foreground);align-items:center;gap:.55rem;font-size:12.5px;font-weight:600;display:flex}.doc-step-num{width:1.1rem;height:1.1rem;color:var(--color-foreground);letter-spacing:0;background:#553f832e;border:1px solid #553f8399;border-radius:999px;justify-content:center;align-items:center;font-size:10px;font-weight:700;display:inline-flex}.doc-table-wrap{background:var(--color-background);border:1px solid var(--color-border);border-radius:.6rem;overflow:hidden}.doc-table{border-collapse:collapse;width:100%;font-family:var(--font-sans)}.doc-table thead{background:var(--color-surface);border-bottom:1px solid var(--color-border)}.doc-table thead th{text-align:left;font-family:var(--font-mono);letter-spacing:.14em;text-transform:uppercase;color:var(--color-foreground-muted);padding:.7rem 1rem;font-size:10px;font-weight:600}.doc-table tbody tr{border-top:1px solid var(--color-border);transition:background-color .12s}.doc-table tbody tr:first-child{border-top:0}.doc-table tbody tr:hover{background:#ffffff04}.doc-table td{vertical-align:top;padding:.75rem 1rem}.doc-cell-key{font-family:var(--font-sans);color:var(--color-foreground);align-items:center;gap:.5rem;font-size:13px;font-weight:500;display:flex}.doc-cell-key code{font-family:var(--font-mono);color:var(--color-foreground);font-size:12px;font-weight:500}.doc-cell-mono{font-family:var(--font-mono);color:var(--color-foreground-muted);font-size:12px}.doc-cell-body{font-family:var(--font-sans);color:var(--color-foreground);font-size:12.5px;line-height:1.55}.doc-token-bar{background:linear-gradient(90deg, #553f831a 0%, #553f8305 70%, transparent 100%), var(--color-background);border:1px solid var(--color-border);border-radius:.6rem;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:.85rem;padding:.65rem .85rem;display:flex}.doc-token-btn{font-family:var(--font-sans);color:var(--color-foreground);background:var(--color-surface);border:1px solid var(--color-border);cursor:pointer;border-radius:.4rem;align-items:center;gap:.45rem;padding:.45rem .85rem;font-size:12.5px;font-weight:500;transition:background .12s,border-color .12s;display:inline-flex}.doc-token-btn:hover{background:var(--color-surface-hover);border-color:#553f8399}.doc-token-btn:disabled{opacity:.5;cursor:not-allowed}.doc-details{background:var(--color-background);border:1px solid var(--color-border);border-radius:.6rem;overflow:hidden}.doc-details-summary{cursor:pointer;font-family:var(--font-sans);color:var(--color-foreground);-webkit-user-select:none;user-select:none;align-items:center;gap:.5rem;padding:.7rem .95rem;font-size:13px;font-weight:500;list-style:none;transition:background .12s;display:flex}.doc-details-summary::-webkit-details-marker{display:none}.doc-details-summary:hover{background:#ffffff05}.doc-details[open]>.doc-details-summary{border-bottom:1px solid var(--color-border)}.doc-details-body{padding:.85rem}.codeblock{background:var(--color-background);border:1px solid var(--color-border);border-radius:.6rem;overflow:hidden}.codeblock-bar{background:var(--color-surface);border-bottom:1px solid var(--color-border);justify-content:space-between;align-items:center;padding:.45rem .85rem;display:flex}.codeblock-lang{font-family:var(--font-mono);letter-spacing:.14em;text-transform:uppercase;color:var(--color-foreground-muted);font-size:10px;font-weight:600}.codeblock-copy{background:var(--color-background);border:1px solid var(--color-border);color:var(--color-foreground-muted);font-family:var(--font-sans);cursor:pointer;border-radius:.35rem;align-items:center;gap:.35rem;padding:.3rem .6rem;font-size:11.5px;transition:color .12s,border-color .12s,background .12s;display:inline-flex}.codeblock-copy:hover{color:var(--color-foreground);background:var(--color-surface-hover);border-color:#553f8399}.codeblock-pre{font-family:var(--font-mono);color:var(--color-foreground-muted);background:var(--color-background);margin:0;padding:.95rem 1.1rem;font-size:12.5px;line-height:1.6;overflow-x:auto}.codeblock-pre code{font-family:inherit;font-size:inherit;line-height:inherit;background:0 0!important;padding:0!important}.tabbed{background:var(--color-background);border:1px solid var(--color-border);border-radius:.6rem;overflow:hidden}.tabbed-tabs{background:var(--color-surface);border-bottom:1px solid var(--color-border);flex-wrap:wrap;gap:0;padding:0 .35rem;display:flex}.tabbed-tab{font-family:var(--font-sans);color:var(--color-foreground-muted);cursor:pointer;background:0 0;border:0;padding:.6rem .95rem;font-size:12.5px;font-weight:500;transition:color .12s;position:relative}.tabbed-tab:hover{color:var(--color-foreground)}.tabbed-tab.active{color:var(--color-foreground);font-weight:600}.tabbed-tab.active:after{content:"";background:var(--color-primary);border-radius:2px 2px 0 0;height:2px;position:absolute;bottom:-1px;left:.6rem;right:.6rem}.tabbed-note{border-bottom:1px solid var(--color-border);background:var(--color-surface);color:var(--color-foreground-muted);font-family:var(--font-sans);padding:.65rem .95rem;font-size:12px;line-height:1.55}.tabbed>.codeblock{border:0;border-radius:0}.callout{background:linear-gradient(90deg, #553f8314 0%, #553f8303 60%, transparent 100%), var(--color-background);border:1px solid var(--color-border);border-radius:.6rem;flex-direction:column;gap:.4rem;padding:.85rem 1rem;display:flex}.callout-head{font-family:var(--font-mono);letter-spacing:.14em;text-transform:uppercase;color:var(--color-foreground-muted);align-items:center;gap:.5rem;font-size:10px;font-weight:600;display:flex}.callout-icon{width:.95rem;height:.95rem}.callout-body{font-family:var(--font-sans);color:var(--color-foreground);flex-wrap:wrap;align-items:center;gap:.3rem .4rem;font-size:13px;line-height:1.55;display:flex}.ai-prompt-actions{flex-wrap:wrap;align-items:center;gap:.75rem;display:flex}.ai-copy-btn{border:1px solid var(--color-border);background:var(--color-surface);color:var(--color-foreground-muted);cursor:pointer;border-radius:6px;align-items:center;gap:.4rem;padding:.4rem .75rem;font-size:12px;transition:color .15s,border-color .15s;display:inline-flex}.ai-copy-btn:hover{color:#fff;border-color:var(--color-foreground-muted)}.ai-copy-btn.copied{color:var(--color-success-fg);border-color:#4ade8066}.codeblock-pre .hljs{color:inherit;padding:0;background:0 0!important} diff --git a/backend/internal/server/ui_dist/assets/Docs-u_E_xl53.js b/backend/internal/server/ui_dist/assets/Docs-u_E_xl53.js deleted file mode 100644 index fbf9e483..00000000 --- a/backend/internal/server/ui_dist/assets/Docs-u_E_xl53.js +++ /dev/null @@ -1,345 +0,0 @@ -import{C as e,D as t,M as n,P as r,T as i,W as a,X as o,_ as s,_t as c,c as l,d as u,h as d,ht as f,j as ee,k as p,l as m,m as h,p as g,r as _,s as v,u as te,v as y}from"./runtime-core.esm-bundler-DWJwptQ-.js";import{t as b}from"./check-lEJPUgfZ.js";import{t as ne}from"./chevron-down-D3BE3JWH.js";import{t as x}from"./chevron-right-Cee8Bzpp.js";import{t as S}from"./copy-5veW7U_F.js";import{t as C}from"./globe-L6h6bFKN.js";import{t as w}from"./key-round-CJGTpWKA.js";import{t as T}from"./lock-Clh4EWdA.js";import{t as re}from"./variable-CmAS7ZoV.js";import{t as ie}from"./client-BF51V3uE.js";import{Dt as ae,Et as oe,gt as se}from"./index-B93KhQc5.js";import{a as E,i as D,n as ce,r as le,t as O}from"./github-dark-D7LxIVih.js";import{t as k}from"./clipboard-D_9N0yai.js";import{r as ue,t as de}from"./aiPrompts-NjljN3ld.js";function fe(e){let t=e.regex,n=`HTTP/([32]|1\\.[01])`,r={className:`attribute`,begin:t.concat(`^`,/[A-Za-z][A-Za-z0-9-]*/,`(?=\\:\\s)`),starts:{contains:[{className:`punctuation`,begin:/: /,relevance:0,starts:{end:`$`,relevance:0}}]}},i=[r,{begin:`\\n\\n`,starts:{subLanguage:[],endsWithParent:!0}}];return{name:`HTTP`,aliases:[`https`],illegal:/\S/,contains:[{begin:`^(?=HTTP/([32]|1\\.[01]) \\d{3})`,end:/$/,contains:[{className:`meta`,begin:n},{className:`number`,begin:`\\b\\d{3}\\b`}],starts:{end:/\b\B/,illegal:/\S/,contains:i}},{begin:`(?=^[A-Z]+ (.*?) HTTP/([32]|1\\.[01])$)`,end:/$/,contains:[{className:`string`,begin:` `,end:` `,excludeBegin:!0,excludeEnd:!0},{className:`meta`,begin:n},{className:`keyword`,begin:`[A-Z]+`}],starts:{end:/\b\B/,illegal:/\S/,contains:i}},e.inherit(r,{relevance:0})]}}var pe={class:`space-y-12 pb-16`},me={class:`docs-hero`},he={class:`docs-hero-content`},ge={class:`docs-hero-row`},_e={class:`docs-hero-actions`},ve=[`title`,`aria-label`],A={class:`docs-hero-toc`,"aria-label":`Jump to docs section`},j=[`href`],M={class:`docs-hero-toc-num`},N={id:`handler`,class:`space-y-5 scroll-mt-6`},P={class:`doc-table-wrap`},F={class:`doc-table`},ye={class:`doc-cell-key`},be={class:`doc-cell-mono`},xe={class:`doc-cell-mono hidden sm:table-cell`},Se={class:`doc-cell-mono hidden md:table-cell`},Ce={id:`deploy`,class:`space-y-5 scroll-mt-6 border-t border-border pt-12`},we={class:`grid grid-cols-1 lg:grid-cols-2 gap-3`},Te={class:`space-y-2`},Ee={class:`space-y-2`},De={class:`space-y-2`},Oe={id:`config`,class:`space-y-5 scroll-mt-6 border-t border-border pt-12`},ke={class:`doc-table-wrap`},Ae={class:`doc-table`},je={class:`doc-cell-key whitespace-nowrap`},Me={class:`doc-cell-mono hidden sm:table-cell whitespace-nowrap`},Ne={class:`doc-cell-body`},Pe={class:`space-y-2`},Fe={class:`doc-details group`},Ie={class:`doc-details-summary`},Le={class:`doc-details-body`},Re={id:`sdk`,class:`space-y-5 scroll-mt-6 border-t border-border pt-12`},ze={class:`space-y-2`},Be={class:`space-y-2`},Ve={class:`space-y-2`},He={id:`schedules`,class:`space-y-5 scroll-mt-6 border-t border-border pt-12`},Ue={class:`doc-section-head`},We={class:`doc-lede`},Ge={id:`webhooks`,class:`space-y-5 scroll-mt-6 border-t border-border pt-12`},Ke={class:`doc-section-head`},qe={class:`doc-lede`},Je={class:`doc-table-wrap`},Ye={class:`doc-table`},Xe={class:`doc-cell-key whitespace-nowrap`},Ze={class:`doc-cell-body`},Qe={class:`space-y-2`},$e={id:`mcp`,class:`space-y-5 scroll-mt-6 border-t border-border pt-12`},et={class:`grid grid-cols-1 md:grid-cols-3 gap-3`},tt={class:`doc-card`},nt={class:`doc-card-body`},rt={class:`doc-chip break-all`},it={class:`doc-token-bar`},at={class:`flex items-center gap-2 min-w-0 flex-1`},ot={key:0,class:`text-sm text-foreground-muted truncate`},st={key:1,class:`text-sm text-success truncate`},ct={class:`doc-chip`},lt=[`disabled`],ut={class:`doc-details group`},dt={class:`doc-details-summary`},ft={class:`doc-details-body space-y-4`},pt={id:`generate`,class:`space-y-5 scroll-mt-6 border-t border-border pt-12`},mt={class:`ai-prompt-actions`},ht={key:0,class:`prompt-collapse-fade`,"aria-hidden":`true`},gt=[`aria-expanded`],_t={id:`tracing`,class:`space-y-5 scroll-mt-6 border-t border-border pt-12`},vt={class:`doc-table-wrap`},yt={class:`doc-table`},bt={class:`doc-cell-key whitespace-nowrap`},xt={class:`doc-cell-body`},St={id:`errors`,class:`space-y-5 scroll-mt-6 border-t border-border pt-12`},Ct={class:`doc-table-wrap`},wt={class:`doc-table`},Tt={class:`doc-cell-key whitespace-nowrap`},Et={class:`doc-cell-body`},Dt={id:`cli`,class:`space-y-5 scroll-mt-6 border-t border-border pt-12`},Ot={class:`doc-prose`},kt={class:`doc-table-wrap`},At={class:`doc-table`},jt={class:`doc-cell-key whitespace-nowrap`},Mt={class:`doc-cell-mono`},Nt={class:`doc-cell-body hidden md:table-cell`},Pt={class:`space-y-2`},Ft={class:`space-y-2`},It={class:`space-y-2`},Lt={class:`space-y-2`},Rt={class:`space-y-2`},zt=`# Available inside every running function — refresh per-invocation: -ORVA_TRACE_ID=tr_3e39f6991c66f140577c6021da7dd13b # one per causal chain -ORVA_SPAN_ID=sp_4ceba57f6b1c982e # this execution - -# Python: os.environ["ORVA_TRACE_ID"] -# Node.js: process.env.ORVA_TRACE_ID -# Reading them is optional — the platform records the trace for you.`,Bt=`// Function A — calls B via the SDK. Trace context flows automatically. -const { invoke, jobs } = require('orva') - -module.exports.handler = async (event) => { - // F2F call — B becomes a child span under A. - const result = await invoke('send_email', { to: event.email }) - - // Job enqueue — when this job runs (now or in 6 hours), the resulting - // execution lands in the SAME trace as A. - await jobs.enqueue('audit_log', { action: 'sent', to: event.email }) - - return { statusCode: 200, body: 'ok' } -}`,Vt=`# Send the W3C traceparent header — Orva will adopt it as the trace root. -curl -H "traceparent: 00-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bbbbbbbbbbbbbbbb-01" \\ - https://orva.example.com/fn/myfn/ - -# Response always echoes: -# X-Trace-Id: tr_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`,Ht=`{ - "error": { - "code": "VALIDATION", - "message": "name must be lowercase and dash-separated", - "request_id": "req_abc123" - } -}`,Ut=`# 1. Generate an API key in the dashboard (Keys page) or via the API -# 2. Tell the CLI where to find your Orva and which key to use -orva login \\ - --endpoint https://orva.example.com \\ - --api-key orva_xxx_your_key_here - -# Writes ~/.orva/config.yaml. Subsequent commands need no flags. -orva system health # smoke test`,Wt=`# Deploy from a directory. Auto-detects handler.ts when tsconfig.json -# is present; else uses the runtime default (handler.js / handler.py). -orva deploy ./my-fn \\ - --name resize-image \\ - --runtime node - -# Override the entrypoint explicitly: -orva deploy ./my-fn --name api --runtime python --entrypoint app.py`,Gt=`# Invoke a function by name or UUID: -orva invoke resize-image --body '{"url":"https://example.com/cat.jpg"}' - -# Recent executions: -orva logs resize-image - -# Single execution, with stdout/stderr: -orva logs resize-image --exec-id exec_abc123 - -# Live tail — SSE stream, Ctrl-C to stop: -orva logs resize-image --follow`,Kt=`# List keys (optionally by prefix) -orva kv list resize-image -orva kv list resize-image --prefix user: - -# Read / write / delete -orva kv get resize-image cache:home -orva kv put resize-image cache:home '{"hits":42}' --ttl 3600 -orva kv delete resize-image cache:home`,qt=`# Secrets — encrypted at rest, injected as env vars at spawn: -orva secrets set resize-image S3_BUCKET my-bucket -orva secrets list resize-image -orva secrets delete resize-image S3_BUCKET - -# Cron — fire a function on a schedule: -orva cron create --fn daily-report --expr '0 9 * * *' --tz Asia/Kolkata -orva cron list -orva cron update --enabled false # pause -orva cron delete - -# Jobs — fire-and-forget background queue: -orva jobs enqueue --fn send-email --data '{"to":"a@b.c"}' -orva jobs list --status pending -orva jobs retry -orva jobs delete - -# Outbound webhooks (system events): -orva webhooks create --url https://hooks.slack.com/... --events deployment.failed,job.failed -orva webhooks test - -# Inbound webhook triggers (external POST → function): -orva webhooks inbound create --fn order-handler --signature stripe`,Jt=`orva system health # daemon up + DB ok -orva system metrics # JSON metrics snapshot -orva system db-stats # on-disk breakdown (orva.db, WAL, functions/) -orva system vacuum # rewrite SQLite to reclaim freelist pages - -orva activity # last 50 activity rows -orva activity --follow # live feed (Ctrl-C) -orva activity --source mcp --limit 200 # MCP-only, last 200`,I=``,Yt={__name:`Docs`,setup(Yt){let Xt=se();E.registerLanguage(`python`,le),E.registerLanguage(`javascript`,D),E.registerLanguage(`js`,D),E.registerLanguage(`json`,ce),E.registerLanguage(`bash`,O),E.registerLanguage(`shell`,O),E.registerLanguage(`sh`,O),E.registerLanguage(`http`,fe);let L=v(()=>window.location.origin),R=[{id:`handler`,num:`01`,label:`Handler`},{id:`deploy`,num:`02`,label:`Deploy`},{id:`config`,num:`03`,label:`Config`},{id:`sdk`,num:`04`,label:`SDK`},{id:`schedules`,num:`05`,label:`Schedules`},{id:`webhooks`,num:`06`,label:`Webhooks`},{id:`mcp`,num:`07`,label:`MCP`},{id:`generate`,num:`08`,label:`AI prompt`},{id:`tracing`,num:`09`,label:`Tracing`},{id:`errors`,num:`10`,label:`Errors`},{id:`cli`,num:`11`,label:`CLI`}],z=a(`handler`),B=null;i(()=>{if(typeof IntersectionObserver>`u`)return;let e=new Set;B=new IntersectionObserver(t=>{for(let n of t)n.isIntersecting?e.add(n.target.id):e.delete(n.target.id);for(let t of R)if(e.has(t.id)){z.value=t.id;break}},{rootMargin:`-20% 0px -70% 0px`,threshold:0});for(let e of R){let t=document.getElementById(e.id);t&&B.observe(t)}}),e(()=>{B&&B.disconnect()});let Zt=de(),V=a(!1),H=null,Qt=async()=>{await ue()&&(V.value=!0,clearTimeout(H),H=setTimeout(()=>{V.value=!1},1500))},$t=s({setup(){return()=>y(`svg`,{viewBox:`0 0 256 255`,width:`14`,height:`14`,xmlns:`http://www.w3.org/2000/svg`},[y(`defs`,null,[y(`linearGradient`,{id:`pyg1`,x1:`0`,y1:`0`,x2:`1`,y2:`1`},[y(`stop`,{offset:`0`,"stop-color":`#387EB8`}),y(`stop`,{offset:`1`,"stop-color":`#366994`})]),y(`linearGradient`,{id:`pyg2`,x1:`0`,y1:`0`,x2:`1`,y2:`1`},[y(`stop`,{offset:`0`,"stop-color":`#FFE052`}),y(`stop`,{offset:`1`,"stop-color":`#FFC331`})])]),y(`path`,{fill:`url(#pyg1)`,d:`M126.9 12c-58.3 0-54.7 25.3-54.7 25.3l.1 26.2H128v8H50.5S12 67.2 12 126.1c0 58.9 33.6 56.8 33.6 56.8h19.4v-27.4s-1-33.6 33.1-33.6h55.9s32 .5 32-30.9V43.5S191.7 12 126.9 12zM95.7 29.9a10 10 0 0 1 0 20 10 10 0 0 1 0-20z`}),y(`path`,{fill:`url(#pyg2)`,d:`M129.1 243c58.3 0 54.7-25.3 54.7-25.3l-.1-26.2H128v-8h77.5s38.5 4.4 38.5-54.5c0-58.9-33.6-56.8-33.6-56.8h-19.4v27.4s1 33.6-33.1 33.6H102s-32-.5-32 30.9v52S64.3 243 129.1 243zm30.4-17.9a10 10 0 0 1 0-20 10 10 0 0 1 0 20z`})])}}),en=s({setup(){return()=>y(`svg`,{viewBox:`0 0 256 280`,width:`14`,height:`14`,xmlns:`http://www.w3.org/2000/svg`},[y(`path`,{fill:`#3F873F`,d:`M128 0 12 67v146l116 67 116-67V67L128 0zm0 24.6 95 54.8v121.2l-95 54.8-95-54.8V79.4l95-54.8z`}),y(`path`,{fill:`#3F873F`,d:`M128 64c-3 0-5.7.7-8 2.3L73 92c-5 2.7-8 8-8 13.6V169c0 5.6 3 10.7 8 13.5l13 7.4c6.3 3.1 8.5 3.1 11.4 3.1 9.4 0 14.8-5.7 14.8-15.6V117c0-1-.7-1.7-1.7-1.7H103c-1 0-1.7.7-1.7 1.7v60.2c0 4.4-4.5 8.7-11.8 5.1l-13.7-7.9a1.6 1.6 0 0 1-.8-1.4v-63.4c0-.6.3-1 .8-1.4l46.8-26.9c.4-.3 1-.3 1.4 0L171 110c.5.4.8.8.8 1.4V174a1.7 1.7 0 0 1-.8 1.4l-46.8 27c-.4.2-1 .2-1.4 0l-12-7.2c-.4-.2-.8-.2-1.2 0-3.4 1.9-4 2.2-7.2 3.3-.8.3-2 .7.4 2.1l15.7 9.3c2.5 1.4 5.3 2.2 8.2 2.2 2.9 0 5.7-.8 8.2-2.2L181 184c5-2.8 8-7.9 8-13.5V107c0-5.6-3-10.7-8-13.5l-46.7-26.7a17 17 0 0 0-6.3-2.8z`})])}}),tn=s({name:`DeployPipelineDiagram`,setup(){let e=[{glyph:`▣`,label:`Tarball`,sub:`POST /deploy`},{glyph:`⟜`,label:`Extract`,sub:`untar → scratch dir`},{glyph:`◍`,label:`Install`,sub:`npm / pip`},{glyph:`⟐`,label:`Compile`,sub:`tsc (TypeScript)`},{glyph:`◉`,label:`Activate`,sub:`rename → current`},{glyph:`✦`,label:`Warm pool`,sub:`pre-spawn N workers`}];return()=>y(`figure`,{class:`doc-diagram`},[y(`figcaption`,{class:`doc-diagram-cap`},`Deploy pipeline`),y(`div`,{class:`doc-pipeline`},e.flatMap((t,n)=>{let r=y(`div`,{key:`s${n}`,class:`doc-pipeline-stage`},[y(`div`,{class:`doc-pipeline-glyph`},t.glyph),y(`div`,{class:`doc-pipeline-label`},[y(`span`,{class:`doc-pipeline-name`},t.label),y(`span`,{class:`doc-pipeline-sub`},t.sub)])]),i=ne/220*100;return()=>y(`figure`,{class:`doc-diagram`},[y(`figcaption`,{class:`doc-diagram-cap`},`Causal trace, one HTTP request and three spans`),y(`div`,{class:`doc-trace`},[y(`div`,{class:`doc-trace-axis`},[y(`span`,null,`0 ms`),y(`span`,null,`220 ms`)]),...e.map(e=>y(`div`,{key:e.fn,class:[`doc-trace-row`,`is-${e.klass}`]},[y(`div`,{class:`doc-trace-label`},[y(`span`,{class:`doc-trace-fn`},e.fn),y(`span`,{class:`doc-trace-trigger`},e.trigger)]),y(`div`,{class:`doc-trace-track`},[y(`div`,{class:`doc-trace-bar`,style:{left:`${t(e.start)}%`,width:`${t(e.dur)}%`},title:`+${e.start}ms · ${e.dur}ms`})]),y(`div`,{class:`doc-trace-dur`},`${e.dur}ms`)])),y(`div`,{class:`doc-trace-legend`},[y(`span`,null,`Same `),y(`code`,{class:`doc-chip`},`trace_id`),y(`span`,null,` across all spans · `),y(`code`,{class:`doc-chip`},`parent_span_id`),y(`span`,null,` chains them into a tree.`)])])])}}),rn=s({name:`WebhookDeliveryDiagram`,setup(){return()=>y(`figure`,{class:`doc-diagram`},[y(`figcaption`,{class:`doc-diagram-cap`},`Signed webhook delivery`),y(`div`,{class:`doc-webhook`},[y(`div`,{class:`doc-webhook-actor`},[y(`div`,{class:`doc-webhook-actor-head`},`orvad`),y(`div`,{class:`doc-webhook-actor-body`},[y(`span`,null,`event fires`),y(`code`,{class:`doc-chip`},`deployment.succeeded`)])]),y(`div`,{class:`doc-webhook-wire`},[y(`div`,{class:`doc-webhook-wire-line`,"aria-hidden":`true`}),y(`div`,{class:`doc-webhook-wire-payload`},[y(`div`,{class:`doc-webhook-wire-method`},`POST`),y(`div`,{class:`doc-webhook-wire-headers`},[y(`code`,null,`X-Orva-Event`),y(`code`,null,`X-Orva-Timestamp`),y(`code`,null,`X-Orva-Signature`)]),y(`div`,{class:`doc-webhook-wire-sig`},`sha256=hex(hmac(secret, ts.body))`)])]),y(`div`,{class:`doc-webhook-actor`},[y(`div`,{class:`doc-webhook-actor-head`},`your receiver`),y(`div`,{class:`doc-webhook-actor-body`},[y(`span`,null,`verify HMAC`),y(`span`,null,`→ 2xx within 15s or get retried`)])])])])}}),an=v(()=>[{label:`Python`,lang:`python`,code:`def handler(event): - body = event.get("body") or {} - return { - "statusCode": 200, - "headers": {"Content-Type": "application/json"}, - "body": {"hello": body.get("name", "world")}, - }`},{label:`Node.js`,lang:`js`,code:`exports.handler = async (event) => { - const body = event.body || {}; - return { - statusCode: 200, - headers: { 'Content-Type': 'application/json' }, - body: { hello: body.name || 'world' }, - }; -};`}]),on=v(()=>[{label:`curl`,lang:`bash`,code:`curl -X POST ${L.value}/fn/ \\ - -H 'Content-Type: application/json' \\ - -d '{"name": "Orva"}'`},{label:`fetch`,lang:`js`,code:`const res = await fetch('${L.value}/fn/', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ name: 'Orva' }), -}); -console.log(await res.json());`},{label:`Python`,lang:`python`,code:`import httpx - -r = httpx.post( - "${L.value}/fn/", - json={"name": "Orva"}, -) -print(r.json())`}]),sn=[{id:`python`,name:`Python 3.14`,entry:`handler.py`,deps:`requirements.txt`,icon:$t},{id:`node`,name:`Node.js 24`,entry:`handler.js`,deps:`package.json`,icon:en}],cn=[{field:`env_vars`,purpose:`Plain config`,body:`Plaintext config stored on the function record. Use for feature flags and non-secret settings.`,icon:re,iconClass:`text-violet-300`},{field:`/secrets`,purpose:`Encrypted`,body:`AES-256-GCM at rest. Values decrypt only into the worker environment at spawn time.`,icon:w,iconClass:`text-emerald-300`},{field:`network_mode`,purpose:`Egress control`,body:`none = isolated loopback. egress = outbound HTTPS allowed, filtered by the sandbox egress policy.`,icon:C,iconClass:`text-sky-300`},{field:`auth_mode`,purpose:`Invoke gate`,body:`none = public. platform_key = require Orva API key. signed = require HMAC.`,icon:T,iconClass:`text-violet-300`},{field:`rate_limit_per_min`,purpose:`Per-IP throttle`,body:`Optional cap for public or webhook-facing functions. Exceeding it returns 429.`,icon:oe,iconClass:`text-amber-300`}],ln=v(()=>`curl -X POST ${L.value}/api/v1/functions \\ - -H 'X-Orva-API-Key: ' \\ - -H 'Content-Type: application/json' \\ - -d '{"name":"hello","runtime":"python","memory_mb":128,"cpus":0.5}'`),un=v(()=>`tar czf code.tar.gz handler.py requirements.txt -curl -X POST ${L.value}/api/v1/functions//deploy \\ - -H 'X-Orva-API-Key: ' \\ - -F code=@code.tar.gz`),dn=v(()=>`curl -X POST ${L.value}/api/v1/functions//secrets \\ - -H 'X-Orva-API-Key: ' \\ - -H 'Content-Type: application/json' \\ - -d '{"key":"DATABASE_URL","value":"postgres://..."}'`),fn=v(()=>`# generate signature -SECRET='your-shared-secret-stored-in-function-secrets' -TS=$(date +%s) -BODY='{"hello":"world"}' -SIG=$(printf '%s.%s' "$TS" "$BODY" | openssl dgst -sha256 -hmac "$SECRET" -hex | awk '{print $2}') - -curl -X POST ${L.value}/fn/ \\ - -H "X-Orva-Timestamp: $TS" \\ - -H "X-Orva-Signature: sha256=$SIG" \\ - -H 'Content-Type: application/json' \\ - -d "$BODY"`),pn=v(()=>[{label:`curl`,lang:`bash`,note:`Create a daily-9am schedule for an existing function. payload is delivered as the invoke body.`,code:`curl -X POST ${L.value}/api/v1/functions//cron \\ - -H 'X-Orva-API-Key: ' \\ - -H 'Content-Type: application/json' \\ - -d '{ - "cron_expr": "0 9 * * *", - "enabled": true, - "payload": {"task": "daily-summary"} - }'`},{label:`Toggle / edit`,lang:`bash`,note:`PUT accepts any subset of {cron_expr, enabled, payload}; omitted fields keep their previous value. next_run_at is recomputed on expr changes.`,code:`# pause -curl -X PUT ${L.value}/api/v1/functions//cron/ \\ - -H 'X-Orva-API-Key: ' \\ - -H 'Content-Type: application/json' \\ - -d '{"enabled": false}' - -# change schedule -curl -X PUT ${L.value}/api/v1/functions//cron/ \\ - -H 'X-Orva-API-Key: ' \\ - -H 'Content-Type: application/json' \\ - -d '{"cron_expr": "*/15 * * * *"}'`},{label:`List & delete`,lang:`bash`,note:`GET /api/v1/cron lists every schedule across functions (with function_name JOIN); per-function uses the nested route.`,code:`# all schedules -curl ${L.value}/api/v1/cron \\ - -H 'X-Orva-API-Key: ' - -# delete one -curl -X DELETE ${L.value}/api/v1/functions//cron/ \\ - -H 'X-Orva-API-Key: '`}]),mn=[{label:`Python`,lang:`python`,code:`from orva import kv - -def handler(event): - # Store with optional TTL (seconds). 0 = no expiry. - kv.put("user:42", {"name": "Ada", "tier": "pro"}, ttl_seconds=3600) - - # Read; default returned if missing or expired. - user = kv.get("user:42", default=None) - - # List by prefix. - pages = kv.list(prefix="page:", limit=50) - - # Delete is idempotent. - kv.delete("user:42") - - return {"statusCode": 200, "body": str(user)}`},{label:`Node.js`,lang:`js`,code:`const { kv } = require('orva') - -exports.handler = async (event) => { - await kv.put('user:42', { name: 'Ada', tier: 'pro' }, { ttlSeconds: 3600 }) - - const user = await kv.get('user:42', null) - - const pages = await kv.list({ prefix: 'page:', limit: 50 }) - - await kv.delete('user:42') - - return { statusCode: 200, body: JSON.stringify(user) } -}`}],hn=[{label:`Python`,lang:`python`,code:`from orva import invoke, OrvaError - -def handler(event): - try: - # invoke() returns the downstream {statusCode, headers, body}. - # body is JSON-decoded when possible. - result = invoke("resize-image", {"url": event["body"]["url"]}) - return {"statusCode": 200, "body": result["body"]} - except OrvaError as e: - # 404 = function not found, 507 = call depth exceeded. - return {"statusCode": e.status or 502, "body": str(e)}`},{label:`Node.js`,lang:`js`,code:`const { invoke, OrvaError } = require('orva') - -exports.handler = async (event) => { - try { - const result = await invoke('resize-image', { url: event.body.url }) - return { statusCode: 200, body: result.body } - } catch (e) { - if (e instanceof OrvaError) { - return { statusCode: e.status || 502, body: e.message } - } - throw e - } -}`}],gn=[{label:`Python`,lang:`python`,code:`from orva import jobs - -def handler(event): - # Fire-and-forget. Returns the job id immediately; the function - # body runs later via the scheduler. max_attempts retries with - # exponential backoff on 5xx / exception. - job_id = jobs.enqueue( - "send-welcome-email", - {"to": event["body"]["email"]}, - max_attempts=3, - ) - return {"statusCode": 202, "body": job_id}`},{label:`Node.js`,lang:`js`,code:`const { jobs } = require('orva') - -exports.handler = async (event) => { - const jobId = await jobs.enqueue( - 'send-welcome-email', - { to: event.body.email }, - { maxAttempts: 3 } - ) - return { statusCode: 202, body: jobId } -}`}],_n=[{name:`deployment.succeeded`,when:`A function build finished and the new version is active.`},{name:`deployment.failed`,when:`A build failed or was rejected.`},{name:`function.created`,when:`A new function row was created via POST /api/v1/functions.`},{name:`function.updated`,when:`A function config was edited via PUT /api/v1/functions/{id} (status flips during a deploy do NOT fire this; see deployment.*).`},{name:`function.deleted`,when:`A function was removed.`},{name:`execution.error`,when:`An invocation finished with status=error or 5xx.`},{name:`cron.failed`,when:`A scheduled run failed (bad expr, missing fn, dispatch error, or 5xx).`},{name:`job.succeeded`,when:`A queued background job finished successfully.`},{name:`job.failed`,when:`A queued job exhausted its retries (terminal failure).`}],vn=[{label:`Python`,lang:`python`,note:`Run on the receiver. Reject anything that fails verification. The signature ensures the request really came from this Orva instance.`,code:`import hmac, hashlib, time - -def verify(secret: str, ts: str, body: bytes, sig_header: str) -> bool: - if abs(time.time() - int(ts)) > 300: # 5-min skew window - return False - mac = hmac.new(secret.encode(), f"{ts}.".encode() + body, hashlib.sha256) - expected = "sha256=" + mac.hexdigest() - return hmac.compare_digest(expected, sig_header) - -# In your Flask/FastAPI/etc. handler: -ts = request.headers["X-Orva-Timestamp"] -sig = request.headers["X-Orva-Signature"] -if not verify(WEBHOOK_SECRET, ts, request.get_data(), sig): - return "bad signature", 401`},{label:`Node.js`,lang:`js`,note:`Same shape as Stripe. Use timingSafeEqual to avoid sig-leak via timing.`,code:`const crypto = require('crypto') - -function verify(secret, ts, body, sigHeader) { - if (Math.abs(Date.now() / 1000 - parseInt(ts, 10)) > 300) return false - const mac = crypto.createHmac('sha256', secret) - mac.update(ts + '.') - mac.update(body) - const expected = 'sha256=' + mac.digest('hex') - if (expected.length !== sigHeader.length) return false - return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sigHeader)) -} - -// In an express handler with raw body middleware: -app.post('/webhooks/orva', (req, res) => { - const ok = verify( - process.env.WEBHOOK_SECRET, - req.headers['x-orva-timestamp'], - req.body, // raw bytes — NOT parsed JSON - req.headers['x-orva-signature'] - ) - if (!ok) return res.status(401).send('bad signature') - res.sendStatus(200) -})`}],U=[{name:`http`,desc:`Public HTTP request hit /fn//. Almost always a root span.`},{name:`f2f`,desc:`Another function called this one via orva.invoke(). Has a parent_span_id.`},{name:`job`,desc:`Background job runner picked up an enqueued job. Parent_span_id is whoever enqueued it.`},{name:`cron`,desc:`Scheduler fired a cron entry. Always a root span.`},{name:`inbound`,desc:`External webhook hit /webhook/{id}. Always a root span.`},{name:`replay`,desc:`Operator clicked Replay on a captured execution. Fresh trace, no link to original.`},{name:`mcp`,desc:`AI agent invoked the function via MCP invoke_function. Fresh trace.`}],yn=[{code:`VALIDATION`,when:`Bad request body or path parameter.`},{code:`UNAUTHORIZED`,when:`Missing or invalid API key / session cookie.`},{code:`NOT_FOUND`,when:`Function, deployment, or secret doesn't exist.`},{code:`RATE_LIMITED`,when:`Too many requests; check the Retry-After header.`},{code:`VERSION_GCD`,when:`Rollback target was garbage-collected.`},{code:`INSUFFICIENT_DISK`,when:`Host is below min_free_disk_mb.`}],bn=[{cmd:`login`,subs:`—`,purpose:`Save endpoint + API key to ~/.orva/config.yaml`},{cmd:`init`,subs:`—`,purpose:`Full server only: write the legacy orva.yaml template`},{cmd:`deploy`,subs:`[path]`,purpose:`Package a directory and deploy as a function`},{cmd:`invoke`,subs:`[name|id]`,purpose:`POST to /fn// and print the response`},{cmd:`logs`,subs:`[name|id] [--follow]`,purpose:`List recent executions; --follow streams live via SSE`},{cmd:`functions`,subs:`list / get / create / delete`,purpose:`CRUD for the function registry`},{cmd:`cron`,subs:`list / create / update / delete`,purpose:`Manage cron schedules attached to functions`},{cmd:`jobs`,subs:`list / enqueue / retry / delete`,purpose:`Background queue management`},{cmd:`kv`,subs:`list / get / put / delete`,purpose:`Browse a function’s key/value store`},{cmd:`secrets`,subs:`list / set / delete`,purpose:`AES-256-GCM secrets per function`},{cmd:`webhooks`,subs:`list / create / test / delete / inbound`,purpose:`System-event subscribers + inbound triggers`},{cmd:`routes`,subs:`list / set / delete`,purpose:`Custom URL → function path mappings`},{cmd:`keys`,subs:`list / create / revoke`,purpose:`Manage API keys`},{cmd:`activity`,subs:`[--follow] [--source web|api|...]`,purpose:`Paginated activity rows; live SSE with --follow`},{cmd:`system`,subs:`health / metrics / db-stats / vacuum`,purpose:`Server diagnostics`},{cmd:`setup`,subs:`[--skip-nsjail] [--skip-rootfs]`,purpose:`Install nsjail + rootfs on a bare host`},{cmd:`serve`,subs:`[--port N]`,purpose:`Run as the server daemon (not the CLI client)`},{cmd:`completion`,subs:`bash / zsh / fish / powershell`,purpose:`Emit shell completion script`}],W=a(``);i(async()=>{try{let e=await fetch(`/web/docs.md`,{cache:`no-cache`});e.ok&&(W.value=await e.text())}catch{}});let xn=v(()=>W.value.replaceAll(`{{ORIGIN}}`,window.location.origin)),G=a(!1),K=null,Sn=async()=>{await k(xn.value)&&(G.value=!0,clearTimeout(K),K=setTimeout(()=>{G.value=!1},1500))},q=a(!1),J=a(``),Y=a(!1),Cn=v(()=>J.value.slice(0,12)),X=v(()=>J.value||I),wn=async()=>{if(!Y.value){Y.value=!0;try{let e=new Date().toISOString().slice(0,16).replace(`T`,` `),t=await ie.post(`/keys`,{name:`MCP: `+e,permissions:[`invoke`,`read`,`write`,`admin`]});J.value=t.data.key}catch(e){console.error(`mint mcp key failed`,e),Xt.notify({title:`Could not mint key`,message:e?.response?.data?.error?.message||e.message||`Unknown error`,danger:!0})}finally{Y.value=!1}}},Tn=v(()=>[{label:`Claude Code`,lang:`bash`,note:"Anthropic's `claude` CLI. Restart Claude Code afterwards; `/mcp` lists Orva's 73 tools.",code:`claude mcp add --transport http --scope user orva ${L.value}/mcp --header "Authorization: Bearer ${X.value}"`},{label:`curl`,lang:`bash`,note:"Talk to MCP directly — no handshake, no session id. Step 1 asks the server what it supports; Step 2 lists the tools. A successful reply is one SSE `message` event; a rejected one is plain JSON with a 4xx.",code:`curl -sN -X POST ${L.value}/mcp \\ - -H 'Authorization: Bearer ${X.value}' \\ - -H 'Content-Type: application/json' \\ - -H 'Accept: application/json, text/event-stream' \\ - -H 'Mcp-Protocol-Version: 2026-07-28' \\ - -H 'Mcp-Method: server/discover' \\ - -d '{"jsonrpc":"2.0","id":1,"method":"server/discover","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}' - -curl -sN -X POST ${L.value}/mcp \\ - -H 'Authorization: Bearer ${X.value}' \\ - -H 'Content-Type: application/json' \\ - -H 'Accept: application/json, text/event-stream' \\ - -H 'Mcp-Protocol-Version: 2026-07-28' \\ - -H 'Mcp-Method: tools/list' \\ - -d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{},"io.modelcontextprotocol/clientInfo":{"name":"curl","version":"0"}}}}' - -# Calling a tool needs a third header. Mcp-Name must repeat params.name, or the -# request is refused with -32020 before the tool runs: -curl -sN -X POST ${L.value}/mcp \\ - -H 'Authorization: Bearer ${X.value}' \\ - -H 'Content-Type: application/json' \\ - -H 'Accept: application/json, text/event-stream' \\ - -H 'Mcp-Protocol-Version: 2026-07-28' \\ - -H 'Mcp-Method: tools/call' \\ - -H 'Mcp-Name: system_health' \\ - -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"system_health","arguments":{},"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}' - -# Older clients need none of that — a bare list returns the same catalog: -curl -sN -X POST ${L.value}/mcp \\ - -H 'Authorization: Bearer ${X.value}' \\ - -H 'Content-Type: application/json' \\ - -H 'Accept: application/json, text/event-stream' \\ - -d '{"jsonrpc":"2.0","id":3,"method":"tools/list","params":{}}'`}]),En=v(()=>[{label:`Claude Desktop`,lang:`json`,note:`Paste into ~/Library/Application Support/Claude/claude_desktop_config.json (macOS), %APPDATA%\\Claude\\claude_desktop_config.json (Windows), or ~/.config/Claude/claude_desktop_config.json (Linux). Restart Claude Desktop.`,code:`{ - "mcpServers": { - "orva": { - "url": "${L.value}/mcp", - "headers": { - "Authorization": "Bearer ${X.value}" - } - } - } -}`},{label:`Cursor`,lang:`bash`,note:`Open the link in your browser. Cursor pops an approval dialog and writes ~/.cursor/mcp.json.`,code:`cursor://anysphere.cursor-deeplink/mcp/install?name=orva&config=${Dn.value}`},{label:`VS Code`,lang:`bash`,note:'User-scoped install via the Copilot-MCP `code --add-mcp` flag. Pick "Workspace" at the prompt to write .vscode/mcp.json instead.',code:`code --add-mcp '{"name":"orva","type":"http","url":"${L.value}/mcp","headers":{"Authorization":"Bearer ${X.value}"}}'`},{label:`Codex CLI`,lang:`bash`,note:"OpenAI's `codex` CLI. Writes to ~/.codex/config.toml.",code:`codex mcp add --transport streamable-http orva ${L.value}/mcp --header "Authorization: Bearer ${X.value}"`},{label:`OpenCode`,lang:`bash`,note:`Interactive add. Pick "Remote", paste ${L.value}/mcp, then add the header Authorization: Bearer ${X.value}.`,code:`opencode mcp add`},{label:`Zed`,lang:`json`,note:"Zed runs MCP as stdio subprocesses, so use the `mcp-remote` bridge. Paste under context_servers in ~/.config/zed/settings.json. Restart Zed.",code:`{ - "context_servers": { - "orva": { - "source": "custom", - "command": "npx", - "args": [ - "-y", "mcp-remote", - "${L.value}/mcp", - "--header", "Authorization:Bearer ${X.value}" - ] - } - } -}`},{label:`Windsurf`,lang:`json`,note:`Paste into ~/.codeium/windsurf/mcp_config.json and reload Windsurf.`,code:`{ - "mcpServers": { - "orva": { - "serverUrl": "${L.value}/mcp", - "headers": { - "Authorization": "Bearer ${X.value}" - } - } - } -}`},{label:`claude.ai web`,lang:`text`,note:`UI-only flow. Settings → Connectors → Add custom connector. claude.ai opens an Orva login + consent popup and issues an OAuth 2.1 token automatically; no token paste required.`,code:`URL: ${L.value}/mcp -Auth: OAuth (auto-discovered)`},{label:`ChatGPT`,lang:`text`,note:`UI-only flow. Settings → Apps & Connectors → Developer mode → Add new connector. ChatGPT discovers OIDC metadata, performs Dynamic Client Registration, and pops the Orva consent screen. No token paste required.`,code:`URL: ${L.value}/mcp -Auth: OAuth (auto-discovered)`}]),Dn=v(()=>{let e=JSON.stringify({url:L.value+`/mcp`,headers:{Authorization:`Bearer `+X.value}});return typeof window.btoa==`function`?window.btoa(e):e}),On=v(()=>[{label:`Cursor (global)`,lang:`json`,note:`Paste into ~/.cursor/mcp.json, or .cursor/mcp.json in your project root for a per-workspace install.`,code:`{ - "mcpServers": { - "orva": { - "url": "${L.value}/mcp", - "headers": { - "Authorization": "Bearer ${X.value}" - } - } - } -}`},{label:`Cline`,lang:`json`,note:`In VS Code: open Cline → MCP icon → Configure MCP Servers. Cline writes cline_mcp_settings.json.`,code:`{ - "mcpServers": { - "orva": { - "url": "${L.value}/mcp", - "headers": { - "Authorization": "Bearer ${X.value}" - }, - "disabled": false - } - } -}`}]),Z=s({name:`CodeBlock`,props:{code:{type:String,required:!0},lang:{type:String,default:``}},setup(e){let t=a(!1),n=async()=>{await k(e.code)&&(t.value=!0,setTimeout(()=>{t.value=!1},1200))},r=v(()=>{let t=(e.lang||``).toLowerCase();if(t&&E.getLanguage(t))try{return E.highlight(e.code,{language:t,ignoreIllegals:!0}).value}catch{}return e.code.replace(/&/g,`&`).replace(//g,`>`)});return()=>y(`div`,{class:`codeblock`},[y(`div`,{class:`codeblock-bar`},[y(`span`,{class:`codeblock-lang`},e.lang||``),y(`button`,{class:`codeblock-copy`,onClick:n,title:`Copy code`},[t.value?y(b,{class:`w-3 h-3`}):y(S,{class:`w-3 h-3`}),t.value?`Copied`:`Copy`])]),y(`pre`,{class:`codeblock-pre`},[y(`code`,{class:`hljs language-${(e.lang||`text`).toLowerCase()}`,innerHTML:r.value})])])}}),Q=s({name:`TabbedCode`,props:{tabs:{type:Array,required:!0},storageKey:{type:String,default:``}},setup(e){let t=(()=>{try{if(e.storageKey){let t=localStorage.getItem(e.storageKey);if(t&&e.tabs.some(e=>e.label===t))return t}}catch{}return e.tabs[0]?.label})(),n=a(t),r=t=>{n.value=t;try{e.storageKey&&localStorage.setItem(e.storageKey,t)}catch{}};return()=>{let t=e.tabs.find(e=>e.label===n.value)||e.tabs[0];return y(`div`,{class:`tabbed`},[y(`div`,{class:`tabbed-tabs`},e.tabs.map(e=>y(`button`,{key:e.label,class:[`tabbed-tab`,{active:e.label===n.value}],onClick:()=>r(e.label)},e.label))),t.note?y(`div`,{class:`tabbed-note`},t.note):null,y(Z,{code:t.code,lang:t.lang})])}}}),$=s({name:`DocsCallout`,props:{title:{type:String,default:``},icon:{type:[Object,Function],default:null}},setup(e,{slots:t}){return()=>y(`div`,{class:`callout`},[y(`div`,{class:`callout-head`},[e.icon?y(e.icon,{class:`callout-icon`}):null,e.title?y(`span`,null,e.title):null]),y(`div`,{class:`callout-body`},t.default?.())])}});return(e,i)=>{let a=ee(`router-link`);return t(),u(`div`,pe,[l(`header`,me,[i[3]||=l(`div`,{class:`docs-hero-bg`,"aria-hidden":`true`},null,-1),l(`div`,he,[l(`div`,ge,[i[1]||=l(`div`,{class:`docs-hero-text`},[l(`h1`,{class:`docs-hero-title`},` Documentation `),l(`p`,{class:`docs-hero-sub`},` Everything you need to write, deploy, and operate functions on Orva. Handler contract, deploy + invoke, SDK, MCP, tracing, error taxonomy. `)],-1),l(`div`,_e,[l(`button`,{class:f([`docs-hero-copy-icon`,{copied:G.value}]),title:G.value?`Copied`:`Copy entire docs page as Markdown`,"aria-label":G.value?`Markdown copied to clipboard`:`Copy entire docs page as Markdown`,onClick:Sn},[G.value?(t(),m(o(b),{key:0,class:`w-4 h-4`})):(t(),m(o(S),{key:1,class:`w-4 h-4`}))],10,ve)])]),l(`nav`,A,[i[2]||=l(`span`,{class:`docs-hero-toc-label`},`Jump to`,-1),(t(),u(_,null,p(R,e=>l(`a`,{key:e.id,href:`#${e.id}`,class:f([`docs-hero-toc-link`,{active:z.value===e.id}])},[l(`span`,M,c(e.num),1),l(`span`,null,c(e.label),1)],10,j)),64))])])]),l(`section`,N,[i[5]||=l(`div`,{class:`doc-section-head`},[l(`span`,{class:`doc-section-num`},`01`),l(`div`,null,[l(`h2`,{class:`doc-section-title`},` Handler contract `),l(`p`,{class:`doc-lede`},` One exported function receives the inbound HTTP event and returns an HTTP-shaped response. The adapter handles serialization and headers. `)])],-1),d(o(Q),{tabs:an.value,"storage-key":`docs.handler`},null,8,[`tabs`]),i[6]||=g(`
Event shape
methodpathheadersquerybody
Response
{ statusCode, headers, body }

Non-string bodies are JSON-encoded by the adapter.

Runtime env
Env vars and secrets land in process.env / os.environ.
`,1),l(`div`,P,[l(`table`,F,[i[4]||=l(`thead`,null,[l(`tr`,null,[l(`th`,null,`Runtime`),l(`th`,null,`ID`),l(`th`,{class:`hidden sm:table-cell`},` Entrypoint `),l(`th`,{class:`hidden md:table-cell`},` Dependencies `)])],-1),l(`tbody`,null,[(t(),u(_,null,p(sn,e=>l(`tr`,{key:e.id},[l(`td`,ye,[(t(),m(n(e.icon),{class:`shrink-0`})),h(` `+c(e.name),1)]),l(`td`,be,c(e.id),1),l(`td`,xe,c(e.entry),1),l(`td`,Se,c(e.deps),1)])),64))])])])]),l(`section`,Ce,[i[11]||=g(`
02

Deploy & invoke

The dashboard handles day-to-day work; these calls are for CI and automation. Builds run async; poll /api/v1/deployments/<id> or stream /api/v1/deployments/<id>/stream until phase: done.

`,1),d(o(tn)),l(`div`,we,[l(`div`,Te,[i[7]||=l(`div`,{class:`doc-step-label`},[l(`span`,{class:`doc-step-num`},`1`),h(` Create the function row `)],-1),d(o(Z),{code:ln.value,lang:`bash`},null,8,[`code`])]),l(`div`,Ee,[i[8]||=l(`div`,{class:`doc-step-label`},[l(`span`,{class:`doc-step-num`},`2`),h(` Upload code `)],-1),d(o(Z),{code:un.value,lang:`bash`},null,8,[`code`])])]),l(`div`,De,[i[9]||=l(`div`,{class:`doc-microlabel`},` Invoke `,-1),d(o(Q),{tabs:on.value,"storage-key":`docs.invoke`},null,8,[`tabs`])]),d(o($),{icon:o(C),title:`Custom routes`},{default:r(()=>[...i[10]||=[h(` Attach a friendly path with `,-1),l(`code`,{class:`doc-chip`},`POST /api/v1/routes`,-1),h(`. Reserved prefixes: `,-1),l(`code`,{class:`doc-chip`},`/api/`,-1),l(`code`,{class:`doc-chip`},`/fn/`,-1),l(`code`,{class:`doc-chip`},`/mcp/`,-1),l(`code`,{class:`doc-chip`},`/web/`,-1),l(`code`,{class:`doc-chip`},`/_orva/`,-1),h(`. `,-1)]]),_:1},8,[`icon`])]),l(`section`,Oe,[i[15]||=l(`div`,{class:`doc-section-head`},[l(`span`,{class:`doc-section-num`},`03`),l(`div`,null,[l(`h2`,{class:`doc-section-title`},` Configuration reference `),l(`p`,{class:`doc-lede`},` Everything below lives on the function record. Secrets are stored encrypted and only decrypt into the worker environment at spawn time. `)])],-1),l(`div`,ke,[l(`table`,Ae,[i[12]||=l(`thead`,null,[l(`tr`,null,[l(`th`,null,`Field`),l(`th`,{class:`hidden sm:table-cell`},` Purpose `),l(`th`,null,`Behaviour`)])],-1),l(`tbody`,null,[(t(),u(_,null,p(cn,e=>l(`tr`,{key:e.field,class:`align-top`},[l(`td`,je,[(t(),m(n(e.icon),{class:f([`w-3.5 h-3.5 shrink-0`,e.iconClass])},null,8,[`class`])),l(`code`,null,c(e.field),1)]),l(`td`,Me,c(e.purpose),1),l(`td`,Ne,c(e.body),1)])),64))])])]),l(`div`,Pe,[i[13]||=l(`div`,{class:`doc-microlabel`},` Set a secret `,-1),d(o(Z),{code:dn.value,lang:`bash`},null,8,[`code`])]),l(`details`,Fe,[l(`summary`,Ie,[d(o(x),{class:`w-3.5 h-3.5 transition-transform group-open:rotate-90 text-foreground-muted`}),i[14]||=h(` Signed-invoke recipe (HMAC, opt-in) `,-1)]),l(`div`,Le,[d(o(Z),{code:fn.value,lang:`bash`},null,8,[`code`])])])]),l(`section`,Re,[i[21]||=g(`
04

SDK from inside a function

The bundled orva module exposes three primitives every function can use without extra dependencies: a per-function key/value store, in-process calls to other Orva functions, and a fire-and-forget background job queue. Routes through the per-process internal token injected at worker spawn time.

orva.kv
put / get / delete / list

Per-function namespace on SQLite, optional TTL.

orva.invoke
invoke(name, payload)

In-process call to another function. 8-deep call cap.

orva.jobs
jobs.enqueue(name, payload)

Fire-and-forget; persisted; retried with exp backoff.

`,2),l(`div`,ze,[i[16]||=l(`div`,{class:`doc-microlabel`},` KV: get/put with TTL `,-1),d(o(Q),{tabs:mn,"storage-key":`docs.sdk.kv`}),i[17]||=g(`

Browse / inspect / edit / delete / set keys without leaving the dashboard at /web/functions/<name>/kv (or click the KV button in the editor's action bar). REST mirror at GET/PUT/DELETE /api/v1/functions/<id>/kv[/<key>]; MCP tools kv_list / kv_get / kv_put / kv_delete for agents.

`,1)]),l(`div`,Be,[i[18]||=l(`div`,{class:`doc-microlabel`},` Function-to-function: invoke() `,-1),d(o(Q),{tabs:hn,"storage-key":`docs.sdk.invoke`})]),l(`div`,Ve,[i[19]||=l(`div`,{class:`doc-microlabel`},` Background jobs: jobs.enqueue() `,-1),d(o(Q),{tabs:gn,"storage-key":`docs.sdk.jobs`})]),d(o($),{icon:o(C),title:`Network mode`},{default:r(()=>[...i[20]||=[h(` The SDK reaches orvad over loopback through the host gateway, so the function needs `,-1),l(`code`,{class:`doc-chip`},`network_mode: "egress"`,-1),h(`. On the default `,-1),l(`code`,{class:`doc-chip`},`"none"`,-1),h(` the SDK throws `,-1),l(`code`,{class:`doc-chip`},`OrvaUnavailableError`,-1),h(` with a clear hint. `,-1)]]),_:1},8,[`icon`])]),l(`section`,He,[l(`div`,Ue,[i[32]||=l(`span`,{class:`doc-section-num`},`05`,-1),l(`div`,null,[i[31]||=l(`h2`,{class:`doc-section-title`},` Schedules `,-1),l(`p`,We,[i[23]||=h(` Fire any function on a cron expression. The scheduler runs as part of the orvad process; no external service. Manage from the `,-1),d(a,{to:`/cron`,class:`text-foreground hover:text-white underline decoration-dotted underline-offset-4`},{default:r(()=>[...i[22]||=[h(` Schedules page `,-1)]]),_:1}),i[24]||=h(` or via the API. Standard 5-field cron with the usual shorthands (`,-1),i[25]||=l(`code`,{class:`doc-chip`},`@daily`,-1),i[26]||=h(`, `,-1),i[27]||=l(`code`,{class:`doc-chip`},`@hourly`,-1),i[28]||=h(`, `,-1),i[29]||=l(`code`,{class:`doc-chip`},`*/5 * * * *`,-1),i[30]||=h(`). `,-1)])])]),d(o(Q),{tabs:pn.value,"storage-key":`docs.cron`},null,8,[`tabs`]),d(o($),{icon:o(ae),title:`Cron-fired headers`},{default:r(()=>[...i[33]||=[h(` Every cron-triggered invocation arrives at the function with `,-1),l(`code`,{class:`doc-chip`},`x-orva-trigger: cron`,-1),h(` and `,-1),l(`code`,{class:`doc-chip`},`x-orva-cron-id: cron_…`,-1),h(` on the event headers, so user code can branch on origin. `,-1)]]),_:1},8,[`icon`])]),l(`section`,Ge,[l(`div`,Ke,[i[38]||=l(`span`,{class:`doc-section-num`},`06`,-1),l(`div`,null,[i[37]||=l(`h2`,{class:`doc-section-title`},` Webhooks `,-1),l(`p`,qe,[i[35]||=h(` Operator-managed subscriptions for system events. Configure URLs from the `,-1),d(a,{to:`/webhooks`,class:`text-foreground hover:text-white underline decoration-dotted underline-offset-4`},{default:r(()=>[...i[34]||=[h(` Webhooks page `,-1)]]),_:1}),i[36]||=h(`; Orva delivers signed POSTs to them when matching events fire (deployments, function lifecycle, cron failures, job outcomes). Subscriptions are global, not per-function. `,-1)])])]),d(o(rn)),i[41]||=g(`
Headers
X-Orva-EventX-Orva-Delivery-IdX-Orva-TimestampX-Orva-Signature
Signature
sha256=hex(hmac(secret, ts.body))

Same shape as Stripe / signed-invoke. Receivers verify with the secret returned at create time.

Retries
5 attemptsexp backoff (≤ 1h)

Receiver must 2xx within 15s.

`,1),l(`div`,Je,[l(`table`,Ye,[i[39]||=l(`thead`,null,[l(`tr`,null,[l(`th`,null,`Event`),l(`th`,null,`When it fires`)])],-1),l(`tbody`,null,[(t(),u(_,null,p(_n,e=>l(`tr`,{key:e.name},[l(`td`,Xe,[l(`code`,null,c(e.name),1)]),l(`td`,Ze,c(e.when),1)])),64))])])]),l(`div`,Qe,[i[40]||=l(`div`,{class:`doc-microlabel`},` Verify a delivery `,-1),d(o(Q),{tabs:vn,"storage-key":`docs.webhooks.verify`})])]),l(`section`,$e,[i[53]||=l(`div`,{class:`doc-section-head`},[l(`span`,{class:`doc-section-num`},`07`),l(`div`,null,[l(`h2`,{class:`doc-section-title`},` MCP: Model Context Protocol `),l(`p`,{class:`doc-lede`},` Same API surface the dashboard uses, exposed as 73 tools an agent can call directly. API key permissions scope the available tool set. `)])],-1),l(`div`,et,[l(`div`,tt,[i[42]||=l(`div`,{class:`doc-microlabel`},` Endpoint `,-1),l(`div`,nt,[l(`code`,rt,c(L.value)+`/mcp`,1)])]),i[43]||=g(`
Auth header
Authorization: Bearer <token>

Or as a fallback: X-Orva-API-Key: <token>

Transport
Streamable HTTPStatelessMCP 2026-07-28

Older clients negotiate down — server/discover advertises 2026-07-28, 2025-11-25, 2025-06-18, 2025-03-26 and 2024-11-05.

`,2)]),d(o($),{icon:o(w),title:`Two header formats; same auth`},{default:r(()=>[...i[44]||=[h(` Either header works against the same API key store with identical permission gating. `,-1),l(`code`,{class:`doc-chip`},`Authorization: Bearer`,-1),h(` is the MCP / OAuth 2 spec form; every MCP SDK (Claude Code, Claude Desktop, Cursor, mcp-remote, Python `,-1),l(`code`,{class:`doc-chip`},`mcp`,-1),h(`) configures it natively, so prefer it for new setups. `,-1),l(`code`,{class:`doc-chip`},`X-Orva-API-Key`,-1),h(` is the same header the REST API accepts; useful when a tool reuses an existing Orva REST integration. Internally both paths SHA-256-hash the token and look it up against the same `,-1),l(`code`,{class:`doc-chip`},`api_keys`,-1),h(` table. `,-1)]]),_:1},8,[`icon`]),d(o($),{icon:o(C),title:`No handshake, no session`},{default:r(()=>[...i[45]||=[h(` The transport is stateless. There is no `,-1),l(`code`,{class:`doc-chip`},`initialize`,-1),h(` step to perform first, no `,-1),l(`code`,{class:`doc-chip`},`Mcp-Session-Id`,-1),h(` is ever issued, and `,-1),l(`code`,{class:`doc-chip`},`GET /mcp`,-1),h(` / `,-1),l(`code`,{class:`doc-chip`},`DELETE /mcp`,-1),h(` — the SSE-resume and session-teardown verbs of the older session transport — return `,-1),l(`code`,{class:`doc-chip`},`405`,-1),h(`. Every POST carries its own bearer token and is answered on its own; a legacy client that still sends `,-1),l(`code`,{class:`doc-chip`},`initialize`,-1),h(` gets a normal reply with its own `,-1),l(`code`,{class:`doc-chip`},`protocolVersion`,-1),h(` echoed back, and simply never receives a session header. A request that opts into 2026-07-28 sends the headers `,-1),l(`code`,{class:`doc-chip`},`Mcp-Protocol-Version`,-1),h(` and `,-1),l(`code`,{class:`doc-chip`},`Mcp-Method`,-1),h(` — plus `,-1),l(`code`,{class:`doc-chip`},`Mcp-Name`,-1),h(` for `,-1),l(`code`,{class:`doc-chip`},`tools/call`,-1),h(`, `,-1),l(`code`,{class:`doc-chip`},`resources/read`,-1),h(` and `,-1),l(`code`,{class:`doc-chip`},`prompts/get`,-1),h(`, which must repeat the name from the body — plus `,-1),l(`code`,{class:`doc-chip`},`io.modelcontextprotocol/protocolVersion`,-1),h(` and `,-1),l(`code`,{class:`doc-chip`},`io.modelcontextprotocol/clientCapabilities`,-1),h(` in `,-1),l(`code`,{class:`doc-chip`},`params._meta`,-1),h(` (a `,-1),l(`code`,{class:`doc-chip`},`clientInfo`,-1),h(` key is optional). The headers let a proxy route on the operation without parsing the body, so one that disagrees with the body is rejected, not ignored. Every POST must send `,-1),l(`code`,{class:`doc-chip`},`Accept: application/json, text/event-stream`,-1),h(`. A successful reply is one SSE `,-1),l(`code`,{class:`doc-chip`},`message`,-1),h(` event; a request rejected at the transport layer comes back as plain `,-1),l(`code`,{class:`doc-chip`},`application/json`,-1),h(` with a 4xx status. `,-1)]]),_:1},8,[`icon`]),d(o($),{icon:o(T),title:`List results are private and immediately stale`},{default:r(()=>[...i[46]||=[l(`code`,{class:`doc-chip`},`tools/list`,-1),h(`, `,-1),l(`code`,{class:`doc-chip`},`resources/list`,-1),h(`, `,-1),l(`code`,{class:`doc-chip`},`resources/templates/list`,-1),h(`, `,-1),l(`code`,{class:`doc-chip`},`prompts/list`,-1),h(`, `,-1),l(`code`,{class:`doc-chip`},`resources/read`,-1),h(` and `,-1),l(`code`,{class:`doc-chip`},`server/discover`,-1),h(` results carry `,-1),l(`code`,{class:`doc-chip`},`ttlMs`,-1),h(` and `,-1),l(`code`,{class:`doc-chip`},`cacheScope`,-1),h(`. Orva returns `,-1),l(`code`,{class:`doc-chip`},`cacheScope: "private"`,-1),h(` because the tool catalog is permission-scoped (a full-permission key lists 73 tools; a `,-1),l(`code`,{class:`doc-chip`},`read`,-1),h(`-only key lists 27) and channel-specific (a channel token sees only that channel's functions) — a shared cache entry would hand one caller another caller's tool surface. `,-1),l(`code`,{class:`doc-chip`},`ttlMs`,-1),h(` is `,-1),l(`code`,{class:`doc-chip`},`0`,-1),h(` because the catalog changes on any deploy, channel edit, or permission change, and statelessness removed the session a `,-1),l(`code`,{class:`doc-chip`},`tools/list_changed`,-1),h(` notification would have travelled over. Re-list instead of caching. `,-1)]]),_:1},8,[`icon`]),l(`div`,it,[l(`div`,at,[d(o(w),{class:`w-4 h-4 shrink-0 text-foreground-muted`}),J.value?(t(),u(`span`,st,[i[49]||=h(` Token minted: `,-1),l(`code`,ct,c(Cn.value)+`…`,1),i[50]||=h(` Shown once, copy now. `,-1)])):(t(),u(`span`,ot,[i[47]||=h(` Snippets show `,-1),l(`code`,{class:`doc-chip`},c(I)),i[48]||=h(`. Mint a token to substitute it everywhere. `,-1)]))]),l(`button`,{class:`doc-token-btn`,disabled:Y.value,onClick:wn},[d(o(w),{class:`w-3.5 h-3.5`}),h(` `+c(J.value?`Mint another`:Y.value?`Minting…`:`Generate token`),1)],8,lt)]),d(o(Q),{tabs:Tn.value,"storage-key":`docs.mcp.install`},null,8,[`tabs`]),l(`details`,ut,[l(`summary`,dt,[d(o(x),{class:`w-3.5 h-3.5 transition-transform group-open:rotate-90 text-foreground-muted`}),i[51]||=h(` More clients (Cursor, VS Code, Codex CLI, OpenCode, Zed, Windsurf, ChatGPT, manual config) `,-1)]),l(`div`,ft,[d(o(Q),{tabs:En.value,"storage-key":`docs.mcp.install.more`},null,8,[`tabs`]),i[52]||=l(`div`,{class:`doc-microlabel pt-1`},` Hand-edited config files `,-1),d(o(Q),{tabs:On.value,"storage-key":`docs.mcp.manual`},null,8,[`tabs`])])])]),l(`section`,pt,[i[54]||=g(`
08

System prompt for AI assistants

Paste the prompt below into ChatGPT, Claude, Gemini, Cursor, Copilot, or any other AI tool to teach it Orva's full surface Handler contract, runtimes, sandbox limits, the in-sandbox orva SDK (kv / invoke / jobs), cron triggers, system-event webhooks, auth modes, and production patterns. The model then turns "describe what I want" into a pasteable handler on the first try.

`,1),l(`div`,mt,[l(`button`,{class:f([`ai-copy-btn`,{copied:V.value}]),onClick:Qt},[V.value?(t(),m(o(b),{key:0,class:`w-3.5 h-3.5`})):(t(),m(o(S),{key:1,class:`w-3.5 h-3.5`})),h(` `+c(V.value?`Copied`:`Copy system prompt`),1)],2)]),l(`div`,{class:f([`prompt-collapse`,{expanded:q.value}])},[d(o(Z),{code:o(Zt),lang:`text`},null,8,[`code`]),q.value?te(``,!0):(t(),u(`div`,ht))],2),l(`button`,{class:`prompt-expand-btn`,"aria-expanded":q.value,onClick:i[0]||=e=>q.value=!q.value},[d(o(ne),{class:f([`w-3.5 h-3.5 transition-transform`,{"rotate-180":q.value}])},null,8,[`class`]),h(` `+c(q.value?`Collapse system prompt`:`Expand full system prompt (~400 lines)`),1)],8,gt)]),l(`section`,_t,[i[56]||=g(`
09

Tracing

Every invocation chain is recorded as a causal trace. automatically, with zero changes to your function code. HTTP requests, F2F invokes, jobs, cron, inbound webhooks, and replays all stitch into the same tree. The dashboard renders it as a waterfall at /traces.

Each execution row IS a span. Spans share a trace_id; child spans point at their parent via parent_span_id. You don't instantiate spans, you don't import a tracer; you just write your handler and the platform plumbs IDs through every internal hop.

`,2),d(o(nn)),i[57]||=l(`h3`,{class:`doc-h3`},` What user code sees `,-1),i[58]||=l(`p`,{class:`doc-prose`},` Two env vars are stamped per invocation. Read them only if you want to log the trace_id alongside your own messages; they're optional. `,-1),d(o(Z),{code:zt,lang:`text`}),i[59]||=l(`h3`,{class:`doc-h3`},` Automatic propagation `,-1),i[60]||=l(`p`,{class:`doc-prose`},[h(` When a function calls another via the SDK, the trace context flows through automatically. The called function becomes a child span of the caller; both share the same `),l(`code`,{class:`doc-chip`},`trace_id`),h(`. `)],-1),d(o(Z),{code:Bt,lang:`js`}),i[61]||=g(`

Job enqueues work the same way: orva.jobs.enqueue() records the trace context on the job row. When the scheduler picks the job up later, the resulting execution lands in the same trace as the function that enqueued it, even if the gap is hours or days.

Triggers

Each span carries a trigger label so the UI can show how the chain started.

`,3),l(`div`,vt,[l(`table`,yt,[i[55]||=l(`thead`,null,[l(`tr`,null,[l(`th`,null,`Trigger`),l(`th`,null,`Meaning`)])],-1),l(`tbody`,null,[(t(),u(_,null,p(U,e=>l(`tr`,{key:e.name},[l(`td`,bt,[l(`code`,null,c(e.name),1)]),l(`td`,xt,c(e.desc),1)])),64))])])]),i[62]||=l(`h3`,{class:`doc-h3`},` External correlation (W3C traceparent) `,-1),i[63]||=l(`p`,{class:`doc-prose`},[h(` Send a standard `),l(`code`,{class:`doc-chip`},`traceparent`),h(` header on the inbound HTTP request and Orva makes its trace a child of yours. The same trace_id is echoed back as `),l(`code`,{class:`doc-chip`},`X-Trace-Id`),h(` on every response, so external systems can correlate without parsing bodies. `)],-1),d(o(Z),{code:Vt,lang:`bash`}),i[64]||=g(`

Outlier detection

Each function maintains an in-memory rolling P95 baseline over its last 100 successful warm executions. An invocation is flagged as an outlier when it has at least 20 baseline samples AND its duration exceeds P95 × 2. Cold starts and errors are excluded from the baseline so a flapping function can't drag it down. The flag and baseline P95 are stored on the execution row and rendered as an amber flag icon next to the span.

Where to look

  • /traces: list of recent traces, filterable by function / status / outlier-only.
  • /traces/:id: waterfall + per-span detail. Click a span to jump to its execution in the Invocations log.
  • GET /api/v1/traces/{id}: full span tree as JSON. Pair with list_traces / get_trace MCP tools for AI agents.
  • GET /api/v1/functions/{id}/baseline: current P95/P99/mean for a function.
`,4)]),l(`section`,St,[i[66]||=g(`
10

Errors & recovery

Every error response uses the same envelope so log scrapers and retries can match on code. Deploys are content-addressed; rollback retargets the active version pointer and refreshes warm workers.

`,1),d(o(Z),{code:Ht,lang:`json`}),l(`div`,Ct,[l(`table`,wt,[i[65]||=l(`thead`,null,[l(`tr`,null,[l(`th`,null,`Code`),l(`th`,null,`When you see it`)])],-1),l(`tbody`,null,[(t(),u(_,null,p(yn,e=>l(`tr`,{key:e.code},[l(`td`,Tt,[l(`code`,null,c(e.code),1)]),l(`td`,Et,c(e.when),1)])),64))])])])]),l(`section`,Dt,[i[83]||=g(`
11

CLI

Orva ships a full Linux server binary and a slim cross-platform CLI, both named orva. They share every client command; only the full build adds serve, setup, and init.

Install (server included)
curl … install.sh | sh

Full install: daemon + nsjail + rootfs + CLI.

Install (CLI only)
curl … install-cli.sh | sh

~20 MB binary at /usr/local/bin/orva. No service.

Inside Docker
docker exec orva orva …

CLI auto-authed via ~/.orva/config.yaml.

Authenticate

`,3),l(`p`,Ot,[i[68]||=h(` The CLI reads `,-1),i[69]||=l(`code`,{class:`doc-chip`},`~/.orva/config.yaml`,-1),i[70]||=h(` for `,-1),i[71]||=l(`code`,{class:`doc-chip`},`endpoint`,-1),i[72]||=h(` + `,-1),i[73]||=l(`code`,{class:`doc-chip`},`api_key`,-1),i[74]||=h(`. Generate a key from `,-1),d(a,{to:`/api-keys`,class:`text-foreground hover:text-white underline decoration-dotted underline-offset-4`},{default:r(()=>[...i[67]||=[h(` Keys `,-1)]]),_:1}),i[75]||=h(` in the dashboard, then: `,-1)]),d(o(Z),{code:Ut,lang:`bash`}),i[84]||=l(`h3`,{class:`doc-h3`},` Command index `,-1),l(`div`,kt,[l(`table`,At,[i[76]||=l(`thead`,null,[l(`tr`,null,[l(`th`,null,`Command`),l(`th`,null,`Subcommands`),l(`th`,{class:`hidden md:table-cell`},` Purpose `)])],-1),l(`tbody`,null,[(t(),u(_,null,p(bn,e=>l(`tr`,{key:e.cmd},[l(`td`,jt,[l(`code`,null,`orva `+c(e.cmd),1)]),l(`td`,Mt,c(e.subs),1),l(`td`,Nt,c(e.purpose),1)])),64))])])]),i[85]||=l(`h3`,{class:`doc-h3`},` Common recipes `,-1),l(`div`,Pt,[i[77]||=l(`div`,{class:`doc-microlabel`},` Deploy a function from a directory `,-1),d(o(Z),{code:Wt,lang:`bash`})]),l(`div`,Ft,[i[78]||=l(`div`,{class:`doc-microlabel`},` Invoke + tail logs `,-1),d(o(Z),{code:Gt,lang:`bash`})]),l(`div`,It,[i[79]||=l(`div`,{class:`doc-microlabel`},` Manage KV state `,-1),d(o(Z),{code:Kt,lang:`bash`})]),l(`div`,Lt,[i[80]||=l(`div`,{class:`doc-microlabel`},` Secrets, cron, jobs, webhooks `,-1),d(o(Z),{code:qt,lang:`bash`})]),l(`div`,Rt,[i[81]||=l(`div`,{class:`doc-microlabel`},` System health, metrics, vacuum `,-1),d(o(Z),{code:Jt,lang:`bash`})]),d(o($),{icon:o(w),title:`Shell completion`},{default:r(()=>[...i[82]||=[h(` Generate completion for your shell: `,-1),l(`code`,{class:`doc-chip`},`orva completion bash | sudo tee /etc/bash_completion.d/orva`,-1),h(`, or `,-1),l(`code`,{class:`doc-chip`},`zsh`,-1),h(` / `,-1),l(`code`,{class:`doc-chip`},`fish`,-1),h(` / `,-1),l(`code`,{class:`doc-chip`},`powershell`,-1),h(`. Tab-completes commands, subcommands, and flags. `,-1)]]),_:1},8,[`icon`])])])}}};export{Yt as default}; \ No newline at end of file diff --git a/backend/internal/server/ui_dist/assets/Drawer-B765_4al.js b/backend/internal/server/ui_dist/assets/Drawer-B765_4al.js new file mode 100644 index 00000000..9ab1b7d4 --- /dev/null +++ b/backend/internal/server/ui_dist/assets/Drawer-B765_4al.js @@ -0,0 +1 @@ +import{A as e,D as t,E as n,F as r,G as i,P as a,T as o,Z as s,_t as c,a as l,c as u,d,h as f,l as p,m,u as h,vt as g,x as _}from"./runtime-core.esm-bundler-BMQPyJ_W.js";import{Mt as v,ut as y,vt as b,zt as x}from"./index-CZI-jurg.js";var S={key:0,class:`fixed inset-0 z-50 pointer-events-none`},C={class:`px-5 py-3 border-b border-border flex items-center justify-between shrink-0`},w={class:`text-sm font-medium text-white truncate`},T={class:`flex-1 overflow-y-auto scrollable`},E={key:0,class:`px-5 py-3 border-t border-border shrink-0`},D=y(Object.assign({name:`CommonDrawer`},{__name:`Drawer`,props:{modelValue:{type:Boolean,default:!1},title:{type:String,default:``},width:{type:String,default:`560px`}},emits:[`update:modelValue`],setup(y,{emit:D}){let O=y,k=D,A=i(null),j=()=>k(`update:modelValue`,!1);a(()=>O.modelValue,async e=>{e&&(await _(),A.value?.focus?.())});let M=e=>{e.key===`Escape`&&O.modelValue&&j()};return o(()=>window.addEventListener(`keydown`,M)),n(()=>window.removeEventListener(`keydown`,M)),(n,i)=>(t(),p(l,{to:`body`},[f(v,{name:`drawer-fade`},{default:r(()=>[y.modelValue?(t(),d(`div`,S,[u(`div`,{class:`absolute inset-0 pointer-events-auto`,onClick:j}),f(v,{name:`drawer-slide`},{default:r(()=>[y.modelValue?(t(),d(`div`,{key:0,ref_key:`root`,ref:A,class:`absolute pointer-events-auto bg-background flex flex-col inset-x-0 bottom-0 max-h-[85dvh] border-t border-border rounded-t-lg pb-safe sm:inset-x-auto sm:right-0 sm:top-0 sm:bottom-0 sm:max-h-none sm:border-t-0 sm:border-l sm:rounded-none sm:pb-0 sm:w-[var(--drawer-w,560px)]`,style:c({"--drawer-w":y.width}),tabindex:`-1`,onKeydown:x(j,[`esc`])},[u(`header`,C,[u(`div`,w,[e(n.$slots,`title`,{},()=>[m(g(y.title),1)],!0)]),u(`button`,{class:`text-foreground-muted hover:text-white transition-colors touch-expand-iconbtn -mr-1`,"aria-label":`Close`,onClick:j},[f(s(b),{class:`w-4 h-4`})])]),u(`div`,T,[e(n.$slots,`default`,{},void 0,!0)]),n.$slots.footer?(t(),d(`footer`,E,[e(n.$slots,`footer`,{},void 0,!0)])):h(``,!0)],36)):h(``,!0)]),_:3})])):h(``,!0)]),_:3})]))}}),[[`__scopeId`,`data-v-42911a7f`]]);export{D as t}; \ No newline at end of file diff --git a/backend/internal/server/ui_dist/assets/Drawer-CNvPia4g.js b/backend/internal/server/ui_dist/assets/Drawer-CNvPia4g.js deleted file mode 100644 index ac1e8107..00000000 --- a/backend/internal/server/ui_dist/assets/Drawer-CNvPia4g.js +++ /dev/null @@ -1 +0,0 @@ -import{A as e,D as t,E as n,N as r,P as i,T as a,W as o,X as s,_t as c,a as l,c as u,d,gt as f,h as p,l as m,m as h,u as g,x as _}from"./runtime-core.esm-bundler-DWJwptQ-.js";import{Rt as v,jt as y,ut as b,vt as x}from"./index-B93KhQc5.js";var S={key:0,class:`fixed inset-0 z-50 pointer-events-none`},C={class:`px-5 py-3 border-b border-border flex items-center justify-between shrink-0`},w={class:`text-sm font-medium text-white truncate`},T={class:`flex-1 overflow-y-auto scrollable`},E={key:0,class:`px-5 py-3 border-t border-border shrink-0`},D=b(Object.assign({name:`CommonDrawer`},{__name:`Drawer`,props:{modelValue:{type:Boolean,default:!1},title:{type:String,default:``},width:{type:String,default:`560px`}},emits:[`update:modelValue`],setup(b,{emit:D}){let O=b,k=D,A=o(null),j=()=>k(`update:modelValue`,!1);r(()=>O.modelValue,async e=>{e&&(await _(),A.value?.focus?.())});let M=e=>{e.key===`Escape`&&O.modelValue&&j()};return a(()=>window.addEventListener(`keydown`,M)),n(()=>window.removeEventListener(`keydown`,M)),(n,r)=>(t(),m(l,{to:`body`},[p(y,{name:`drawer-fade`},{default:i(()=>[b.modelValue?(t(),d(`div`,S,[u(`div`,{class:`absolute inset-0 pointer-events-auto`,onClick:j}),p(y,{name:`drawer-slide`},{default:i(()=>[b.modelValue?(t(),d(`div`,{key:0,ref_key:`root`,ref:A,class:`absolute pointer-events-auto bg-background flex flex-col inset-x-0 bottom-0 max-h-[85dvh] border-t border-border rounded-t-lg pb-safe sm:inset-x-auto sm:right-0 sm:top-0 sm:bottom-0 sm:max-h-none sm:border-t-0 sm:border-l sm:rounded-none sm:pb-0 sm:w-[var(--drawer-w,560px)]`,style:f({"--drawer-w":b.width}),tabindex:`-1`,onKeydown:v(j,[`esc`])},[u(`header`,C,[u(`div`,w,[e(n.$slots,`title`,{},()=>[h(c(b.title),1)],!0)]),u(`button`,{class:`text-foreground-muted hover:text-white transition-colors touch-expand-iconbtn -mr-1`,"aria-label":`Close`,onClick:j},[p(s(x),{class:`w-4 h-4`})])]),u(`div`,T,[e(n.$slots,`default`,{},void 0,!0)]),n.$slots.footer?(t(),d(`footer`,E,[e(n.$slots,`footer`,{},void 0,!0)])):g(``,!0)],36)):g(``,!0)]),_:3})])):g(``,!0)]),_:3})]))}}),[[`__scopeId`,`data-v-42911a7f`]]);export{D as t}; \ No newline at end of file diff --git a/backend/internal/server/ui_dist/assets/Editor-DQHCrIvv.css b/backend/internal/server/ui_dist/assets/Editor-4XWCDeWw.css similarity index 54% rename from backend/internal/server/ui_dist/assets/Editor-DQHCrIvv.css rename to backend/internal/server/ui_dist/assets/Editor-4XWCDeWw.css index a1bd3903..dfa947ff 100644 --- a/backend/internal/server/ui_dist/assets/Editor-DQHCrIvv.css +++ b/backend/internal/server/ui_dist/assets/Editor-4XWCDeWw.css @@ -1 +1 @@ -.panel-btn[data-v-36b579d7]{border:1px solid var(--color-border);background-color:var(--color-surface-hover);color:var(--color-foreground-muted);white-space:nowrap;border-radius:.375rem;align-items:center;gap:.375rem;padding:.375rem .625rem;font-size:11px;font-weight:500;transition:color .15s,background-color .15s,border-color .15s;display:inline-flex;position:relative}.panel-btn[data-v-36b579d7]:before{content:"";position:absolute;inset-block:-8px;inset-inline:0}.panel-btn[data-v-36b579d7]:hover{color:var(--color-foreground);border-color:var(--color-foreground-muted)}.panel-btn[data-v-36b579d7]:disabled{opacity:.5;cursor:not-allowed}.menu-item[data-v-36b579d7]{width:100%;min-height:44px;color:var(--color-foreground);text-align:left;cursor:pointer;background-color:#0000;border:0;align-items:center;gap:.5rem;padding:.5rem .75rem;font-size:12px;transition:background-color .12s;display:flex}.menu-item[data-v-36b579d7]:hover,.menu-item[data-v-36b579d7]:focus-visible{background-color:var(--color-surface-hover);outline:none}.menu-item+.menu-item[data-v-36b579d7]{border-top:1px solid var(--color-border)}.run-btn[data-v-36b579d7]{color:var(--color-foreground);cursor:pointer;background:#553f832e;border:1px solid #553f838c;border-radius:.3rem;align-items:center;gap:.3rem;padding:.2rem .55rem;font-size:11px;font-weight:500;transition:background .12s,border-color .12s,color .12s;display:inline-flex}.run-btn[data-v-36b579d7]:hover:not(:disabled){border-color:var(--color-primary);color:#fff;background:#553f8352}.run-btn[data-v-36b579d7]:disabled{opacity:.4;cursor:not-allowed}.run-spinner[data-v-36b579d7]{border:1.5px solid;border-top-color:#0000;border-radius:999px;width:.65rem;height:.65rem;animation:.7s linear infinite run-spin-36b579d7}@keyframes run-spin-36b579d7{to{transform:rotate(360deg)}} +.panel-btn[data-v-a96acd9b]{border:1px solid var(--color-border);background-color:var(--color-surface-hover);color:var(--color-foreground-muted);white-space:nowrap;border-radius:.375rem;align-items:center;gap:.375rem;padding:.375rem .625rem;font-size:11px;font-weight:500;transition:color .15s,background-color .15s,border-color .15s;display:inline-flex;position:relative}.panel-btn[data-v-a96acd9b]:before{content:"";position:absolute;inset-block:-8px;inset-inline:0}.panel-btn[data-v-a96acd9b]:hover{color:var(--color-foreground);border-color:var(--color-foreground-muted)}.panel-btn[data-v-a96acd9b]:disabled{opacity:.5;cursor:not-allowed}.menu-item[data-v-a96acd9b]{width:100%;min-height:44px;color:var(--color-foreground);text-align:left;cursor:pointer;background-color:#0000;border:0;align-items:center;gap:.5rem;padding:.5rem .75rem;font-size:12px;transition:background-color .12s;display:flex}.menu-item[data-v-a96acd9b]:hover,.menu-item[data-v-a96acd9b]:focus-visible{background-color:var(--color-surface-hover);outline:none}.menu-item+.menu-item[data-v-a96acd9b]{border-top:1px solid var(--color-border)}.run-btn[data-v-a96acd9b]{color:var(--color-foreground);cursor:pointer;background:#553f832e;border:1px solid #553f838c;border-radius:.3rem;align-items:center;gap:.3rem;padding:.2rem .55rem;font-size:11px;font-weight:500;transition:background .12s,border-color .12s,color .12s;display:inline-flex}.run-btn[data-v-a96acd9b]:hover:not(:disabled){border-color:var(--color-primary);color:#fff;background:#553f8352}.run-btn[data-v-a96acd9b]:disabled{opacity:.4;cursor:not-allowed}.run-spinner[data-v-a96acd9b]{border:1.5px solid;border-top-color:#0000;border-radius:999px;width:.65rem;height:.65rem;animation:.7s linear infinite run-spin-a96acd9b}@keyframes run-spin-a96acd9b{to{transform:rotate(360deg)}} diff --git a/backend/internal/server/ui_dist/assets/Editor-B2TUmRPR.js b/backend/internal/server/ui_dist/assets/Editor-B2TUmRPR.js deleted file mode 100644 index 1b17dd83..00000000 --- a/backend/internal/server/ui_dist/assets/Editor-B2TUmRPR.js +++ /dev/null @@ -1,1288 +0,0 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/CodeEditor-CN_QDpaG.js","assets/runtime-core.esm-bundler-DWJwptQ-.js","assets/index-B93KhQc5.js","assets/axios-DVDuIpRy.js","assets/pinia-D7gh0q31.js","assets/client-BF51V3uE.js","assets/index-DjfRwYQD.css","assets/dist-CR15Grce.js","assets/CodeEditor-x1XGuNl0.css"])))=>i.map(i=>d[i]); -import{C as e,D as t,F as n,M as r,N as i,P as a,T as ee,W as o,X as s,_t as c,c as l,d as u,g as te,h as d,ht as f,j as ne,k as p,l as re,m,r as h,s as g,u as _,v as ie}from"./runtime-core.esm-bundler-DWJwptQ-.js";import{t as ae}from"./book-open-DOYPDtOR.js";import{t as oe}from"./check-lEJPUgfZ.js";import{t as se}from"./chevron-down-D3BE3JWH.js";import{n as ce,t as le}from"./git-compare-DoufYPrI.js";import{t as ue}from"./copy-5veW7U_F.js";import{n as de,r as fe,t as pe}from"./settings-2-DyBZntFB.js";import{t as me}from"./globe-L6h6bFKN.js";import{t as he}from"./key-round-CJGTpWKA.js";import{t as ge}from"./lock-Clh4EWdA.js";import{t as _e}from"./play-BBWx7r99.js";import{t as ve}from"./rotate-ccw-B9grc64w.js";import{t as ye}from"./shield-check-DU6_qnwV.js";import{t as be}from"./sparkles-yO26ZD4G.js";import{t as xe}from"./terminal-DBfAxzMM.js";import{t as Se}from"./trash-2-BlIjHjqi.js";import{t as Ce}from"./variable-CmAS7ZoV.js";import{r as we,t as v}from"./client-BF51V3uE.js";import{At as Te,Ct as Ee,Ft as De,It as y,Lt as Oe,Mt as ke,Rt as Ae,W as je,_ as Me,_t as b,et as Ne,gt as Pe,k as Fe,m as Ie,mt as Le,ot as Re,pt as ze,rt as Be,t as Ve,ut as He,vt as Ue,yt as We,z as Ge,zt as Ke}from"./index-B93KhQc5.js";import{t as qe}from"./clipboard-D_9N0yai.js";import{t as x}from"./Modal-CMnodc09.js";import{t as Je}from"./rollbackDiff-DsaWcdbl.js";import{n as Ye}from"./aiPrompts-NjljN3ld.js";import{t as Xe}from"./Input-nRG7dQt5.js";var Ze=Te(`database`,[[`ellipse`,{cx:`12`,cy:`5`,rx:`9`,ry:`3`,key:`msslwz`}],[`path`,{d:`M3 5V19A9 3 0 0 0 21 19V5`,key:`1wlel7`}],[`path`,{d:`M3 12A9 3 0 0 0 21 12`,key:`mv7ke4`}]]),Qe=Te(`layers`,[[`path`,{d:`M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z`,key:`zw3jo`}],[`path`,{d:`M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12`,key:`1wduqc`}],[`path`,{d:`M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17`,key:`kqbvx6`}]]),$e=Te(`shuffle`,[[`path`,{d:`m18 14 4 4-4 4`,key:`10pe0f`}],[`path`,{d:`m18 2 4 4-4 4`,key:`pucp1d`}],[`path`,{d:`M2 18h1.973a4 4 0 0 0 3.3-1.7l5.454-8.6a4 4 0 0 1 3.3-1.7H22`,key:`1ailkh`}],[`path`,{d:`M2 6h1.972a4 4 0 0 1 3.6 2.2`,key:`km57vx`}],[`path`,{d:`M22 18h-6.041a4 4 0 0 1-3.3-1.8l-.359-.45`,key:`os18l9`}]]),S=`amber.arctic.aurora.bold.brave.breezy.bright.brisk.calm.celestial.cobalt.cosmic.crimson.crisp.crystal.dapper.dazzling.deep.eager.ember.fearless.feisty.fierce.flaming.fluent.fluorescent.frosty.gentle.glacial.golden.graceful.happy.hazy.icy.indigo.jade.jolly.jovial.keen.kindred.lavender.lively.lucent.lunar.magenta.magnetic.merry.midnight.mighty.mellow.mossy.mystic.neon.nimble.noble.obsidian.opal.pearl.peppy.pixel.plucky.plush.polar.prime.quartz.quick.quiet.radiant.rapid.rare.roaming.rosy.royal.rugged.runic.rustic.sapphire.scarlet.sharp.silent.silken.silver.sleek.smooth.snowy.snug.solar.sonic.spry.starlit.stellar.sturdy.sublime.sunny.svelte.swift.tame.tender.thunder.tidal.topaz.tropic.turquoise.twilight.urban.velvet.verdant.vibrant.violet.vivid.warm.whisper.wild.wise.witty.woven.zesty.zen`.split(`.`),et=`albatross.amber.antler.apricot.archer.arrow.atlas.aurora.badger.bayou.beacon.bison.blossom.bramble.breeze.cactus.canyon.caravan.cedar.cliff.comet.compass.coral.cosmos.cypress.dawn.delta.dolphin.drift.dune.eagle.ember.fable.falcon.fern.fjord.flame.flint.forest.galaxy.garnet.geyser.glacier.glade.glint.gorge.gull.harbor.haven.horizon.iceberg.iris.jaguar.jetty.jungle.kelp.kestrel.kettle.kraken.lagoon.lantern.lark.ledge.lily.lighthouse.lupine.lynx.maple.meadow.meridian.meteor.mirage.mistral.monsoon.moon.moss.mountain.nebula.oak.oasis.ocean.orchid.osprey.otter.panda.panther.parrot.pebble.phoenix.pine.pinion.pixel.planet.plume.pond.poppy.prairie.puffin.puma.quartz.quasar.quill.rapids.raven.reef.ridge.river.robin.rune.sage.satellite.savanna.sequoia.shadow.signal.silo.sky.sloth.snow.sparrow.spire.star.stream.summit.swan.tempest.thicket.thistle.thunder.tide.tiger.totem.tower.tundra.twilight.twister.valley.vortex.walnut.wave.whale.whisper.wildflower.willow.wolf.wren.zenith.zephyr`.split(`.`),C=e=>e[Math.floor(Math.random()*e.length)];function tt(){return`${C(S)}-${C(et)}`}var w=`import json - - -def handler(event): - body = event.get("body") or {} - if isinstance(body, str): - body = json.loads(body) if body else {} - name = body.get("name", "World") if isinstance(body, dict) else "World" - - return { - "statusCode": 200, - "headers": {"Content-Type": "application/json"}, - "body": json.dumps({"message": f"Hello {name}!", "language": "Python"}), - } -`,nt=`# Verify a Stripe webhook and branch on event type. -# Set the secret as STRIPE_WEBHOOK_SECRET in the function's secrets so -# rotation doesn't require a redeploy. -import hashlib -import hmac -import json -import os -import time - - -def _verify(payload: bytes, header: str, secret: str, tolerance: int = 300) -> bool: - # Stripe sends a header like: t=1614265978,v1=abcdef... - parts = dict(p.split("=", 1) for p in header.split(",") if "=" in p) - ts = int(parts.get("t", "0")) - sig = parts.get("v1", "") - if abs(time.time() - ts) > tolerance: - return False - signed = f"{ts}.{payload.decode('utf-8')}".encode() - expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest() - return hmac.compare_digest(expected, sig) - - -def handler(event): - headers = {k.lower(): v for k, v in (event.get("headers") or {}).items()} - sig_header = headers.get("stripe-signature", "") - secret = os.environ.get("STRIPE_WEBHOOK_SECRET", "") - raw = (event.get("body") or "").encode("utf-8") if isinstance(event.get("body"), str) else json.dumps(event.get("body") or {}).encode() - - if not _verify(raw, sig_header, secret): - return {"statusCode": 401, "body": "invalid signature"} - - payload = json.loads(raw) - event_type = payload.get("type", "unknown") - - # Branch on the event types you care about. Anything else is ack'd 200 - # so Stripe stops retrying. - if event_type == "checkout.session.completed": - session_id = payload["data"]["object"]["id"] - # TODO: fulfil the order — record session_id in your DB. - print(f"checkout completed: {session_id}") - elif event_type == "customer.subscription.deleted": - sub_id = payload["data"]["object"]["id"] - print(f"subscription cancelled: {sub_id}") - - return {"statusCode": 200, "body": json.dumps({"received": True, "type": event_type})} -`,T=`# Verify a GitHub webhook (HMAC-SHA256) and route on X-GitHub-Event. -# Set the secret as GITHUB_WEBHOOK_SECRET in the function's secrets. -import hashlib -import hmac -import json -import os - - -def handler(event): - headers = {k.lower(): v for k, v in (event.get("headers") or {}).items()} - sig = headers.get("x-hub-signature-256", "") - if not sig.startswith("sha256="): - return {"statusCode": 401, "body": "missing signature"} - - secret = os.environ.get("GITHUB_WEBHOOK_SECRET", "") - raw = event.get("body") or "" - if not isinstance(raw, str): - raw = json.dumps(raw) - expected = "sha256=" + hmac.new(secret.encode(), raw.encode(), hashlib.sha256).hexdigest() - if not hmac.compare_digest(expected, sig): - return {"statusCode": 401, "body": "bad signature"} - - gh_event = headers.get("x-github-event", "ping") - payload = json.loads(raw) if raw else {} - - if gh_event == "ping": - return {"statusCode": 200, "body": json.dumps({"pong": True})} - if gh_event == "push": - ref = payload.get("ref", "") - commits = len(payload.get("commits", [])) - print(f"push to {ref}: {commits} commit(s)") - elif gh_event == "pull_request": - action = payload.get("action", "") - pr_num = payload.get("number", 0) - print(f"PR #{pr_num} {action}") - - return {"statusCode": 200, "body": json.dumps({"event": gh_event})} -`,rt=`# Slack slash command handler. Slack POSTs application/x-www-form-urlencoded -# to the request URL and expects a JSON response within 3 seconds. Set -# SLACK_SIGNING_SECRET in the function's secrets to verify requests. -import hashlib -import hmac -import json -import os -import time -import urllib.parse - - -def _verify(ts: str, body: str, sig: str, secret: str) -> bool: - if abs(time.time() - int(ts or "0")) > 300: - return False - base = f"v0:{ts}:{body}".encode() - expected = "v0=" + hmac.new(secret.encode(), base, hashlib.sha256).hexdigest() - return hmac.compare_digest(expected, sig) - - -def handler(event): - headers = {k.lower(): v for k, v in (event.get("headers") or {}).items()} - body = event.get("body") or "" - if not isinstance(body, str): - body = urllib.parse.urlencode(body) - - secret = os.environ.get("SLACK_SIGNING_SECRET", "") - if not _verify(headers.get("x-slack-request-timestamp", ""), - body, - headers.get("x-slack-signature", ""), - secret): - return {"statusCode": 401, "body": "invalid signature"} - - form = dict(urllib.parse.parse_qsl(body)) - user = form.get("user_name", "?") - text = form.get("text", "").strip() - - return { - "statusCode": 200, - "headers": {"Content-Type": "application/json"}, - "body": json.dumps({ - "response_type": "in_channel", - "text": f":wave: Hello @{user}! You said: \\"{text or '(nothing)'}\\"", - }), - } -`,it=`# Convert a CSV upload to JSON. Accepts plain text body OR a multipart -# upload with field name "file". Stream-parses with csv.reader so a 5MB -# CSV doesn't blow the 6MB request body cap with intermediate copies. -import csv -import io -import json - - -def handler(event): - body = event.get("body") or "" - if not isinstance(body, str): - body = json.dumps(body) - - headers = {k.lower(): v for k, v in (event.get("headers") or {}).items()} - ctype = headers.get("content-type", "") - - # Strip multipart wrapper if present. Real multipart parsing is more - # involved; this covers the common "single file, plain CSV body" - # case that simple uploaders produce. - if ctype.startswith("multipart/"): - marker = "\\r\\n\\r\\n" - if marker in body: - body = body.split(marker, 1)[1] - tail = body.rfind("\\r\\n--") - if tail > 0: - body = body[:tail] - - reader = csv.reader(io.StringIO(body)) - rows = list(reader) - if not rows: - return {"statusCode": 400, "body": "empty CSV"} - - header_row, *data_rows = rows - out = [dict(zip(header_row, r)) for r in data_rows] - - return { - "statusCode": 200, - "headers": {"Content-Type": "application/json"}, - "body": json.dumps({"count": len(out), "rows": out}), - } -`,at=`# Scheduled DB cleanup: delete rows older than RETENTION_DAYS. -# Pair this with a Schedules entry like "0 2 * * *" (daily at 02:00). -# Configure DB_DSN as a secret. The handler is idempotent so multiple -# fires within the same window are safe. -import json -import os -from datetime import datetime, timedelta, timezone - -# Replace this with your actual DB driver; psycopg2/asyncpg/etc. -# import psycopg2 - - -def handler(event): - retention_days = int(os.environ.get("RETENTION_DAYS", "30")) - cutoff = datetime.now(timezone.utc) - timedelta(days=retention_days) - - # Example DB call (commented — drop your driver in): - # conn = psycopg2.connect(os.environ["DB_DSN"]) - # cur = conn.cursor() - # cur.execute("DELETE FROM events WHERE created_at < %s", (cutoff,)) - # deleted = cur.rowcount - # conn.commit() - # conn.close() - deleted = 0 # replace with real count - - headers = {k.lower(): v for k, v in (event.get("headers") or {}).items()} - triggered_by = headers.get("x-orva-trigger", "manual") - - return { - "statusCode": 200, - "headers": {"Content-Type": "application/json"}, - "body": json.dumps({ - "trigger": triggered_by, - "cutoff": cutoff.isoformat(), - "deleted_rows": deleted, - }), - } -`,ot=`# RSS / Atom summarizer. Fetches a feed and returns the latest N items -# as JSON. Works for both RSS 2.0 and Atom. Requires network_mode=egress -# on the function settings to reach the upstream feed. -import json -import os -import urllib.request -import xml.etree.ElementTree as ET - - -def _strip_ns(tag: str) -> str: - return tag.split("}", 1)[1] if "}" in tag else tag - - -def handler(event): - body = event.get("body") or {} - if isinstance(body, str): - body = json.loads(body) if body else {} - - feed_url = body.get("url") or os.environ.get("FEED_URL", "") - if not feed_url: - return {"statusCode": 400, "body": "url is required"} - - limit = int(body.get("limit", 10)) - - with urllib.request.urlopen(feed_url, timeout=10) as resp: - xml_bytes = resp.read() - - root = ET.fromstring(xml_bytes) - items = [] - # RSS: ...; Atom: ... - for el in root.iter(): - tag = _strip_ns(el.tag) - if tag in ("item", "entry"): - entry = {_strip_ns(c.tag): (c.text or "").strip() for c in el} - items.append(entry) - if len(items) >= limit: - break - - return { - "statusCode": 200, - "headers": {"Content-Type": "application/json"}, - "body": json.dumps({"feed": feed_url, "count": len(items), "items": items}), - } -`,st=`# Resize an image to a thumbnail. Accepts {"image_b64": "...", "width": 200} -# and returns base64 PNG. Requires Pillow (add "Pillow" to requirements.txt). -import base64 -import io -import json - -from PIL import Image - - -def handler(event): - body = event.get("body") or {} - if isinstance(body, str): - body = json.loads(body) if body else {} - - img_b64 = body.get("image_b64") or "" - if not img_b64: - return {"statusCode": 400, "body": "image_b64 is required"} - - width = int(body.get("width", 200)) - height = int(body.get("height", 0)) or None - - raw = base64.b64decode(img_b64) - img = Image.open(io.BytesIO(raw)) - - # Preserve aspect ratio when only width is given. - if height is None: - ratio = width / img.width - height = int(img.height * ratio) - img.thumbnail((width, height)) - - out = io.BytesIO() - img.save(out, format="PNG", optimize=True) - out_b64 = base64.b64encode(out.getvalue()).decode() - - return { - "statusCode": 200, - "headers": {"Content-Type": "application/json"}, - "body": json.dumps({"thumbnail_b64": out_b64, "width": width, "height": height}), - } -`,ct=`Pillow>=10.0 -`,lt=`""" -guestbook — Orva showcase template - -A single function that demonstrates EVERY core Orva surface: - - • Server-rendered dark-mode HTML page with form + feed - • JSON API with pagination, validation, and CORS - • orva.kv for durable per-function state - • orva.jobs to enqueue post-submit enrichment work back to itself - • Cron-trigger handling for periodic cleanup of stale entries - • Admin auth via a function secret (ADMIN_TOKEN) on destructive ops - • Custom route mount under /guestbook/* - -Setup steps after deploy: - 1. Set the ADMIN_TOKEN secret (Settings → Secrets) to enable DELETE. - 2. Create a custom route /guestbook/* → this function (Routes API). - 3. (optional) Schedule a daily cron via the Schedules page; the - handler reads x-orva-trigger and runs the cleanup branch. - -Endpoints (after the route is mounted): - GET /guestbook/ → render the page - POST /guestbook/ → form submission, 303 back - GET /guestbook/api/submissions → list with ?limit=&cursor= - GET /guestbook/api/submissions/ → one entry - POST /guestbook/api/submissions → JSON body, 201 - DELETE /guestbook/api/submissions/ → admin only (Bearer ADMIN_TOKEN) - GET /guestbook/api/stats → totals + last-24h count -""" - -import html as _html -import json -import os -import re -import secrets -import time -from urllib.parse import parse_qs - -from orva import kv, jobs - -ROUTE_BASE = "/guestbook" -NAME_RE = re.compile(r"^[\\w \\-\\.\\'\\"@]{1,40}$") -MAX_MSG = 280 -LIST_LIMIT = 200 -RETENTION_DAYS = int(os.environ.get("RETENTION_DAYS", "30")) - - -# ── helpers ────────────────────────────────────────────────────────── - -def _new_id(): - return f"sub:{time.time_ns()}:{secrets.token_hex(2)}" - - -def _now_iso(): - return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()) - - -def _now_unix(): - return int(time.time()) - - -def _json_response(status, body, headers=None): - h = {"Content-Type": "application/json", "Cache-Control": "no-store", - "Access-Control-Allow-Origin": "*"} - if headers: - h.update(headers) - return {"statusCode": status, "headers": h, "body": body} - - -def _html_response(body, status=200): - return { - "statusCode": status, - "headers": {"Content-Type": "text/html; charset=utf-8", "Cache-Control": "no-store"}, - "body": body, - } - - -def _read_body(event): - body = event.get("body") - ct = (event.get("headers") or {}).get("content-type", "").lower() - if isinstance(body, dict): - return body - if not body: - return {} - if "application/json" in ct: - try: - return json.loads(body) if isinstance(body, str) else body - except json.JSONDecodeError: - return {} - if "application/x-www-form-urlencoded" in ct or "multipart/form-data" in ct: - if isinstance(body, str): - return {k: v[0] for k, v in parse_qs(body, keep_blank_values=True).items()} - if isinstance(body, str): - try: - return json.loads(body) - except json.JSONDecodeError: - return {} - return {} - - -def _validate(data): - name = (data.get("name") or "").strip() - message = (data.get("message") or "").strip() - if not name: - return "", "", "name is required" - if not NAME_RE.match(name): - return "", "", "name must be <= 40 chars; letters / digits / @ . - _ ' \\" space only" - if not message: - return "", "", "message is required" - if len(message) > MAX_MSG: - return "", "", f"message must be <= {MAX_MSG} chars" - return name, message, "" - - -def _save(name, message): - sid = _new_id() - record = { - "id": sid, - "name": name, - "message": message, - "ts": _now_iso(), - "ts_unix": _now_unix(), - } - kv.put(sid, record) - counter = (kv.get("meta:counter", default=0) or 0) + 1 - kv.put("meta:counter", counter) - - # Hand off enrichment to the background queue. The same function - # picks up the job (see _on_job_trigger) — no separate worker - # function. The user's POST returns immediately. - try: - jobs.enqueue("guestbook", {"action": "enrich", "id": sid}) - except Exception as e: - _log("warn", "jobs.enqueue failed", error=str(e)) - - return record - - -def _unwrap(row): - """orva.kv.list returns either a parsed dict OR a {key, value: } envelope depending on runtime. Handle both.""" - if isinstance(row, dict) and "key" in row and "value" in row: - v = row["value"] - if isinstance(v, str): - try: - return json.loads(v) - except json.JSONDecodeError: - return None - return v - return row - - -def _list(limit=LIST_LIMIT, cursor=None): - rows = kv.list(prefix="sub:", limit=limit) or [] - parsed = [_unwrap(r) for r in rows] - parsed = [r for r in parsed if isinstance(r, dict)] - parsed = list(reversed(parsed)) # newest first - if cursor: - try: - i = next(idx for idx, r in enumerate(parsed) if r.get("id") == cursor) - parsed = parsed[i + 1:] - except StopIteration: - pass - return parsed - - -def _log(level, msg, **fields): - fields.update({"level": level, "msg": msg}) - print(json.dumps(fields)) - - -# ── HTML page (inline CSS, no external deps) ──────────────────────── - -PAGE = """\\ - - - - - -guestbook · {count} - - - -
-
-

guestbook.

-

Drop a note — say hi, share a link, leave a thought.

-
- -
-
- - -
-
- - -
- {error_html} -
- 0 / {max_msg} - -
-
- - {entries_html} - -
- {count} {entry_word} - · JSON at {base}/api/submissions - · Stats at {base}/api/stats -
-
- + - - + + - +
diff --git a/frontend/src/components/ai/AISettingsPanel.vue b/frontend/src/components/ai/AISettingsPanel.vue index 63b75339..0f0011b4 100644 --- a/frontend/src/components/ai/AISettingsPanel.vue +++ b/frontend/src/components/ai/AISettingsPanel.vue @@ -11,19 +11,19 @@
-

+

Providers

- Bring your own keys. Keys are encrypted at rest; models are listed live from each provider. Pick the provider + model inside the chat composer. + Keys are encrypted at rest. Choose the active model in Chat.

-
+
{{ p.provider }} @@ -32,7 +32,7 @@ class="text-xs text-foreground-muted" >{{ p.label }} {{ p.has_key ? 'key set' : 'no key' }} @@ -76,7 +76,7 @@ {{ m.id }}
@@ -91,64 +91,74 @@
-
-

+
+ Add provider -

-

- For any OpenAI-compatible endpoint (self-hosted, vLLM, Together, …) choose openai and set the Base URL. -

-
- - - {{ opt }} - - + + +
+ + + +
- - - - - +
-

+

Defaults

@@ -156,15 +166,12 @@ Approval policy

- Reads always run on their own. This controls when the assistant pauses for your OK before it changes anything. + Choose when changes require confirmation.

{ switch (props.variant) { case 'danger': - return 'text-foreground-muted hover:text-danger-fg hover:bg-surface-hover focus:ring-red-500' + return 'text-foreground-muted hover:text-danger-fg hover:bg-surface-hover focus-visible:ring-danger' case 'success': - return 'text-foreground-muted hover:text-success hover:bg-surface-hover focus:ring-green-500' + return 'text-foreground-muted hover:text-success hover:bg-surface-hover focus-visible:ring-success' // Brand-accent variant: violet instead of green for "this just // worked" affordances inside the dashboard chrome (Copy URL, Copy // ID, etc.). Green is reserved for genuine semantic-success states @@ -69,9 +69,9 @@ const variantClasses = computed(() => { // as a six-colour zoo. Solid primary-violet text + matching ring // on focus, surface-hover background tint to anchor the moment. case 'primary': - return 'text-primary hover:text-primary-hover bg-primary/10 hover:bg-primary/15 focus:ring-primary' + return 'text-primary hover:text-primary-hover bg-primary/10 hover:bg-primary/15 focus-visible:ring-primary' default: - return 'text-foreground-muted hover:text-foreground hover:bg-surface-hover focus:ring-primary' + return 'text-foreground-muted hover:text-foreground hover:bg-surface-hover focus-visible:ring-primary' } }) diff --git a/frontend/src/components/common/Input.vue b/frontend/src/components/common/Input.vue index 1d364bf4..9edcdd45 100644 --- a/frontend/src/components/common/Input.vue +++ b/frontend/src/components/common/Input.vue @@ -2,6 +2,7 @@
-