@mediamonks/canopy-cli 0.7.18 → 0.7.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/{db-BAaqh_2O.mjs → db-TaSLpQZ5.mjs} +2 -2
  2. package/dist/{deploy-DID3xhMJ.mjs → deploy-DCggsLD7.mjs} +2 -2
  3. package/dist/dev-DjkK-50R.mjs +2 -0
  4. package/dist/{dev-CjaomJ2D.mjs → dev-DtEwiNYi.mjs} +4 -4
  5. package/dist/docs/index.json +7 -2
  6. package/dist/docs/notifications.md +14 -1
  7. package/dist/docs/sdk-email.md +114 -0
  8. package/dist/docs/sdk.md +4 -4
  9. package/dist/{docs-DP_p_mmy.mjs → docs-C2D7__Iz.mjs} +2 -2
  10. package/dist/{egress-DDM-_7Yo.mjs → egress-BhbQfjjV.mjs} +1 -1
  11. package/dist/{feedback-DX99gDFp.mjs → feedback-BvkCjS-g.mjs} +2 -2
  12. package/dist/index.mjs +25 -25
  13. package/dist/{local-dAQdVFEK.mjs → local-CKRZur_5.mjs} +2 -2
  14. package/dist/login-D-Ac_kFW.mjs +285 -0
  15. package/dist/{logs-D60VRbHZ.mjs → logs-Beqz--Df.mjs} +1 -1
  16. package/dist/{migrations-kKKDlR_H.mjs → migrations-Bg9FEGFh.mjs} +1 -1
  17. package/dist/{open-B5XHmEmv.mjs → open-D7f1wNn3.mjs} +1 -1
  18. package/dist/{package-x-_qF58q.mjs → package-B-aXVcQu.mjs} +1 -1
  19. package/dist/{projects-TE1PVwMy.mjs → projects-1r5387ui.mjs} +1 -1
  20. package/dist/{schedule-Blldchmj.mjs → schedule-DK_Cv6Xf.mjs} +1 -1
  21. package/dist/{skill-CSFhZmBk.mjs → skill-CqiSkac0.mjs} +2 -2
  22. package/dist/{staging-Cw-Rzbsj.mjs → staging-CdpV2YHB.mjs} +1 -1
  23. package/dist/{token-BqxRIRkT.mjs → token-C8Bmzwfl.mjs} +1 -1
  24. package/dist/{ui-DLZNEen6.mjs → ui--atbZ-TM.mjs} +4 -0
  25. package/dist/{upgrade-DcU4YMr_.mjs → upgrade-CpUCVTrN.mjs} +2 -2
  26. package/dist/{usage-2cGnpSVc.mjs → usage-CRpVLLi6.mjs} +1 -1
  27. package/package.json +4 -3
  28. package/dist/dev-A2doKMCS.mjs +0 -2
  29. package/dist/login-CU0pev0k.mjs +0 -401
@@ -0,0 +1,285 @@
1
+ import { _ as writeConfigFile, f as clearAllProfileTokens, g as upsertProfileAuth, h as setActiveProfile, m as readConfigFile, n as siteConfig, p as listBakedProfiles, v as getBakedProfile, y as isProfileId } from "./site-BFaWfSVu.mjs";
2
+ import { n as openBrowser, r as reportErrors } from "./ui--atbZ-TM.mjs";
3
+ import { defineCommand } from "citty";
4
+ import * as p from "@clack/prompts";
5
+ import { createHash, randomBytes } from "node:crypto";
6
+ import { createServer } from "node:http";
7
+ //#region ../pages/src/generated/cli-login.ts
8
+ const okHtml = "<!doctype html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"/><title>You’re signed in · Canopy</title><style>/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-outline-style:solid;--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0}}}@layer theme{:root,:host{--font-sans:\"Helvetica Now for Monks\", ui-sans-serif, system-ui, sans-serif;--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;--color-red-100:#ffebf0;--color-red-200:#ffd1dd;--color-red-300:#ffa8be;--color-red-400:#ff7a9c;--color-red-500:#ff527d;--color-red-600:#ff245b;--color-red-800:#a30029;--color-red-950:#610018;--color-amber-200:#fde68a;--color-amber-950:#451a03;--color-yellow-100:#fff7db;--color-yellow-900:#7a6000;--color-green-100:#e3fcf1;--color-green-200:#b8fadd;--color-green-900:#067445;--color-green-950:#065533;--color-purple-50:#faf6fd;--color-purple-300:#d6b6f1;--color-purple-400:#c598ec;--color-purple-500:#ac6de3;--color-purple-600:#8c3fd2;--color-purple-700:#7d26c9;--color-purple-900:#501881;--color-gray-800:#5d5d60;--color-neutral-50:#f5f5f4;--color-neutral-100:#e9e8e7;--color-neutral-200:#d6d4d2;--color-neutral-300:#c0beb9;--color-neutral-400:#adaaa4;--color-neutral-500:#97938c;--color-neutral-600:#837f77;--color-neutral-700:#6c6962;--color-neutral-900:#484641;--color-neutral-950:#3e3c38;--color-stone-500:#78716c;--color-stone-600:#57534e;--color-stone-700:#44403c;--color-stone-800:#292524;--color-stone-900:#1c1917;--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--text-xs:12px;--text-xs--line-height:16px;--text-sm:14px;--text-sm--line-height:20px;--text-2xl:24px;--text-2xl--line-height:32px;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.01em;--tracking-wide:.015em;--leading-snug:1.375;--leading-normal:1.5;--leading-relaxed:1.625;--radius-md:6px;--radius-lg:8px;--radius-xl:12px;--radius-2xl:16px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-foreground:var(--foreground);--color-primary:var(--primary);--color-primary-foreground:var(--primary-foreground);--color-muted-foreground:var(--muted-foreground);--color-destructive:var(--destructive);--color-border:var(--border);--color-card:var(--card);--color-brand:var(--brand);--color-brand-foreground:var(--brand-foreground)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", \"Noto Sans\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:root,[data-theme=monks-flow]{--background:var(--color-white);--background-emphasis:var(--color-neutral-900);--foreground:var(--color-neutral-950);--foreground-alt:var(--color-neutral-700);--foreground-subtle:var(--color-neutral-600);--primary:var(--color-neutral-900);--primary-foreground:var(--color-neutral-50);--primary-hover:var(--color-neutral-950);--secondary:#f5f3f0;--secondary-foreground:var(--color-neutral-900);--secondary-hover:#e7e2dc;--muted:var(--color-neutral-100);--muted-foreground:var(--color-neutral-500);--accent:#e7e2dc;--accent-foreground:var(--color-neutral-900);--destructive:#e11d48;--destructive-foreground:var(--color-white);--destructive-soft:var(--color-red-100);--destructive-soft-foreground:var(--color-red-800);--ghost:#fff0;--ghost-foreground:var(--color-neutral-700);--ghost-hover:#0000000d;--positive:var(--color-green-100);--positive-foreground:var(--color-green-900);--surface:var(--color-neutral-50);--surface-emphasis:var(--color-neutral-300);--surface-raised:var(--color-neutral-200);--border:var(--color-neutral-200);--border-light:var(--color-neutral-100);--border-lighter:var(--color-neutral-50);--border-strong:var(--color-neutral-400);--input:var(--color-neutral-50);--input-foreground:var(--color-neutral-950);--ring:var(--color-black);--ring-error:var(--color-red-300);--card:var(--color-white);--card-foreground:var(--color-neutral-950);--popover:var(--color-white);--popover-foreground:var(--color-neutral-950);--warning:var(--color-yellow-100);--warning-foreground:var(--color-yellow-900);--chart-1:#f54a00;--chart-2:#009689;--chart-3:#104e64;--chart-4:#ffb900;--chart-5:#fe9a00;--chart-negative:#f54a00;--chart-positive:#009689;--chart-fill:#bfdeffb3;--chart-fill-2:#aaccffb3;--chart-stroke-2:#3f8dff;--sidebar:var(--color-neutral-50);--sidebar-foreground:var(--color-gray-800);--sidebar-primary:var(--primary);--sidebar-primary-foreground:var(--primary-foreground);--sidebar-accent:var(--accent);--sidebar-accent-foreground:var(--accent-foreground);--sidebar-border:var(--color-neutral-200);--sidebar-ring:var(--ring);--backdrop:#0009;--theme-background:#f5f4f2}:root.dark:not([data-theme]),[data-theme=monks-flow].dark,[data-theme=monks-flow] .dark{--background:var(--color-stone-900);--background-emphasis:var(--color-neutral-100);--foreground:var(--color-neutral-50);--foreground-alt:var(--color-neutral-300);--foreground-subtle:var(--color-neutral-400);--primary:var(--color-neutral-50);--primary-foreground:var(--color-black);--primary-hover:var(--color-neutral-100);--secondary:var(--color-stone-700);--secondary-foreground:var(--color-neutral-100);--secondary-hover:var(--color-stone-600);--muted:var(--color-stone-800);--muted-foreground:var(--color-neutral-500);--accent:var(--color-neutral-900);--accent-foreground:var(--color-neutral-300);--destructive:var(--color-red-500);--destructive-foreground:var(--color-white);--destructive-soft:var(--color-red-950);--destructive-soft-foreground:var(--color-red-200);--ghost:#fff0;--ghost-foreground:var(--color-neutral-300);--ghost-hover:#ffffff14;--positive:var(--color-green-950);--positive-foreground:var(--color-green-200);--surface:var(--color-stone-800);--surface-emphasis:var(--color-stone-600);--surface-raised:var(--color-stone-700);--border:var(--color-stone-600);--border-light:var(--color-stone-700);--border-lighter:var(--color-stone-800);--border-strong:var(--color-stone-500);--input:var(--color-stone-800);--input-foreground:var(--color-neutral-50);--ring:var(--color-white);--ring-error:var(--color-red-400);--card:var(--color-stone-800);--card-foreground:var(--color-neutral-100);--popover:var(--color-stone-800);--popover-foreground:var(--color-neutral-100);--warning:var(--color-amber-950);--warning-foreground:var(--color-amber-200);--chart-1:#ff6b33;--chart-2:#00b3a4;--chart-3:#2196a8;--chart-4:#ffc733;--chart-5:#ffad33;--chart-negative:#ff6b33;--chart-positive:#00b3a4;--chart-fill:#3382ff40;--chart-fill-2:#5096ff33;--chart-stroke-2:#5da3ff;--sidebar:var(--color-stone-800);--sidebar-foreground:var(--color-neutral-300);--sidebar-primary:var(--primary);--sidebar-primary-foreground:var(--primary-foreground);--sidebar-accent:var(--accent);--sidebar-accent-foreground:var(--accent-foreground);--sidebar-border:var(--color-stone-700);--sidebar-ring:var(--ring);--backdrop:#000c;--theme-background:#0c0a09}[data-theme=metropolis]{--background:var(--color-white);--background-emphasis:var(--color-neutral-900);--foreground:var(--color-neutral-950);--foreground-alt:var(--color-neutral-700);--foreground-subtle:var(--color-neutral-600);--primary:var(--color-purple-600);--primary-foreground:var(--color-neutral-50);--primary-hover:var(--color-purple-700);--secondary:var(--color-neutral-100);--secondary-foreground:var(--color-neutral-900);--secondary-hover:var(--color-neutral-50);--muted:var(--color-neutral-100);--muted-foreground:var(--color-neutral-500);--accent:var(--color-purple-50);--accent-foreground:var(--color-purple-600);--destructive:var(--color-red-600);--destructive-foreground:var(--color-white);--destructive-soft:var(--color-red-100);--destructive-soft-foreground:var(--color-red-800);--ghost:#fff0;--ghost-foreground:var(--color-neutral-700);--ghost-hover:#0000000d;--positive:var(--color-green-100);--positive-foreground:var(--color-green-900);--surface:var(--color-neutral-50);--surface-emphasis:var(--color-neutral-300);--surface-raised:var(--color-neutral-200);--border:var(--color-neutral-200);--border-light:var(--color-neutral-100);--border-lighter:var(--color-neutral-50);--border-strong:var(--color-neutral-400);--input:var(--color-neutral-50);--input-foreground:var(--color-neutral-950);--ring:var(--color-neutral-300);--ring-error:var(--color-red-300);--card:var(--color-white);--card-foreground:var(--color-neutral-950);--popover:var(--color-white);--popover-foreground:var(--color-neutral-950);--warning:var(--color-yellow-100);--warning-foreground:var(--color-yellow-900);--chart-1:#f54a00;--chart-2:#009689;--chart-3:#104e64;--chart-4:#ffb900;--chart-5:#fe9a00;--chart-negative:#f54a00;--chart-positive:#009689;--chart-fill:#bfdeffb3;--chart-fill-2:#aaccffb3;--chart-stroke-2:#3f8dff;--sidebar:var(--color-neutral-50);--sidebar-foreground:var(--color-gray-800);--sidebar-primary:var(--primary);--sidebar-primary-foreground:var(--primary-foreground);--sidebar-accent:var(--accent);--sidebar-accent-foreground:var(--accent-foreground);--sidebar-border:var(--color-neutral-200);--sidebar-ring:var(--color-neutral-300);--backdrop:#0009;--theme-background:#f0f3f8}[data-theme=metropolis].dark,[data-theme=metropolis] .dark{--background:var(--color-stone-900);--background-emphasis:var(--color-neutral-100);--foreground:var(--color-neutral-50);--foreground-alt:var(--color-neutral-300);--foreground-subtle:var(--color-neutral-400);--primary:var(--color-purple-500);--primary-foreground:var(--color-white);--primary-hover:var(--color-purple-400);--secondary:var(--color-stone-700);--secondary-foreground:var(--color-neutral-100);--secondary-hover:var(--color-stone-600);--muted:var(--color-stone-800);--muted-foreground:var(--color-neutral-400);--accent:var(--color-purple-900);--accent-foreground:var(--color-purple-300);--destructive:var(--color-red-500);--destructive-foreground:var(--color-white);--destructive-soft:var(--color-red-950);--destructive-soft-foreground:var(--color-red-200);--ghost:#fff0;--ghost-foreground:var(--color-neutral-300);--ghost-hover:#ffffff14;--positive:var(--color-green-950);--positive-foreground:var(--color-green-200);--surface:var(--color-stone-800);--surface-emphasis:var(--color-stone-600);--surface-raised:var(--color-stone-700);--border:var(--color-stone-600);--border-light:var(--color-stone-700);--border-lighter:var(--color-stone-800);--border-strong:var(--color-stone-500);--input:var(--color-stone-800);--input-foreground:var(--color-neutral-50);--ring:var(--color-neutral-500);--ring-error:var(--color-red-400);--card:var(--color-stone-800);--card-foreground:var(--color-neutral-100);--popover:var(--color-stone-800);--popover-foreground:var(--color-neutral-100);--warning:var(--color-amber-950);--warning-foreground:var(--color-amber-200);--chart-1:#ff6b33;--chart-2:#00b3a4;--chart-3:#2196a8;--chart-4:#ffc733;--chart-5:#ffad33;--chart-negative:#ff6b33;--chart-positive:#00b3a4;--chart-fill:#3382ff40;--chart-fill-2:#5096ff33;--chart-stroke-2:#5da3ff;--sidebar:var(--color-stone-800);--sidebar-foreground:var(--color-neutral-300);--sidebar-primary:var(--primary);--sidebar-primary-foreground:var(--primary-foreground);--sidebar-accent:var(--accent);--sidebar-accent-foreground:var(--accent-foreground);--sidebar-border:var(--color-stone-700);--sidebar-ring:var(--color-neutral-500);--backdrop:#000c;--theme-background:#0c0a09}*{border-color:var(--border)}body{background-color:var(--background);color:var(--foreground)}button,[role=button]{cursor:pointer}:focus-visible{outline:2px solid var(--ring);outline-offset:2px}}@layer components;@layer utilities{.relative{position:relative}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3\\.5{margin-top:calc(var(--spacing) * 3.5)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mt-px{margin-top:1px}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-1{margin-bottom:var(--spacing)}.mb-1\\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-5{margin-bottom:calc(var(--spacing) * 5)}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.size-11{width:calc(var(--spacing) * 11);height:calc(var(--spacing) * 11)}.h-11{height:calc(var(--spacing) * 11)}.min-h-svh{min-height:100svh}.w-full{width:100%}.max-w-sm{max-width:var(--container-sm)}.shrink-0{flex-shrink:0}.place-items-center{place-items:center}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-center{justify-content:center}.gap-1\\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\\.5{gap:calc(var(--spacing) * 2.5)}.overflow-x-auto{overflow-x:auto}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-lg{border-radius:var(--radius-lg)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-r-md{border-top-right-radius:var(--radius-md);border-bottom-right-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-border{border-color:var(--color-border)}.border-brand{border-color:var(--color-brand)}.border-destructive{border-color:var(--color-destructive)}.bg-\\[color-mix\\(in_oklab\\,var\\(--destructive\\)_8\\%\\,transparent\\)\\]{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.bg-\\[color-mix\\(in_oklab\\,var\\(--destructive\\)_8\\%\\,transparent\\)\\]{background-color:color-mix(in oklab,var(--destructive) 8%,transparent)}}.bg-\\[color-mix\\(in_oklab\\,var\\(--foreground\\)_6\\%\\,transparent\\)\\]{background-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.bg-\\[color-mix\\(in_oklab\\,var\\(--foreground\\)_6\\%\\,transparent\\)\\]{background-color:color-mix(in oklab,var(--foreground) 6%,transparent)}}.bg-\\[var\\(--input\\)\\]{background-color:var(--input)}.bg-brand{background-color:var(--color-brand)}.bg-card{background-color:var(--color-card)}.bg-destructive{background-color:var(--color-destructive)}.bg-primary{background-color:var(--color-primary)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.px-1{padding-inline:var(--spacing)}.px-2\\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3\\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\\.5{padding-block:calc(var(--spacing) * 2.5)}.py-px{padding-block:1px}.pt-4{padding-top:calc(var(--spacing) * 4)}.pr-3{padding-right:calc(var(--spacing) * 3)}.pl-3{padding-left:calc(var(--spacing) * 3)}.text-center{text-align:center}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\\[0\\.85em\\]{font-size:.85em}.leading-normal{--tw-leading:var(--leading-normal);line-height:var(--leading-normal)}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.break-words{overflow-wrap:break-word}.text-\\[var\\(--card\\)\\]{color:var(--card)}.text-brand{color:var(--color-brand)}.text-brand-foreground{color:var(--color-brand-foreground)}.text-destructive{color:var(--color-destructive)}.text-foreground{color:var(--color-foreground)}.text-muted-foreground{color:var(--color-muted-foreground)}.text-primary-foreground{color:var(--color-primary-foreground)}.uppercase{text-transform:uppercase}.underline{text-decoration-line:underline}.underline-offset-2{text-underline-offset:2px}.shadow-panel{--tw-shadow:var(--panel-shadow);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.backdrop-blur-\\[10px\\]{--tw-backdrop-blur:blur(10px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.select-none{-webkit-user-select:none;user-select:none}.canopy-backdrop{background:var(--backdrop)}.paused{animation-play-state:paused}.running{animation-play-state:running}@media (hover:hover){.hover\\:bg-\\[var\\(--primary-hover\\)\\]:hover{background-color:var(--primary-hover)}.hover\\:text-foreground:hover{color:var(--color-foreground)}}.focus-visible\\:border-brand:focus-visible{border-color:var(--color-brand)}.focus-visible\\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\\:outline-offset-1:focus-visible{outline-offset:1px}.focus-visible\\:outline-offset-2:focus-visible{outline-offset:2px}.focus-visible\\:outline-offset-\\[3px\\]:focus-visible{outline-offset:3px}.focus-visible\\:outline-brand:focus-visible{outline-color:var(--color-brand)}.aria-invalid\\:border-destructive[aria-invalid=true]{border-color:var(--color-destructive)}}@property --tw-animation-delay{syntax:\"*\";inherits:false;initial-value:0s}@property --tw-animation-direction{syntax:\"*\";inherits:false;initial-value:normal}@property --tw-animation-duration{syntax:\"*\";inherits:false}@property --tw-animation-fill-mode{syntax:\"*\";inherits:false;initial-value:none}@property --tw-animation-iteration-count{syntax:\"*\";inherits:false;initial-value:1}@property --tw-enter-blur{syntax:\"*\";inherits:false;initial-value:0}@property --tw-enter-opacity{syntax:\"*\";inherits:false;initial-value:1}@property --tw-enter-rotate{syntax:\"*\";inherits:false;initial-value:0}@property --tw-enter-scale{syntax:\"*\";inherits:false;initial-value:1}@property --tw-enter-translate-x{syntax:\"*\";inherits:false;initial-value:0}@property --tw-enter-translate-y{syntax:\"*\";inherits:false;initial-value:0}@property --tw-exit-blur{syntax:\"*\";inherits:false;initial-value:0}@property --tw-exit-opacity{syntax:\"*\";inherits:false;initial-value:1}@property --tw-exit-rotate{syntax:\"*\";inherits:false;initial-value:0}@property --tw-exit-scale{syntax:\"*\";inherits:false;initial-value:1}@property --tw-exit-translate-x{syntax:\"*\";inherits:false;initial-value:0}@property --tw-exit-translate-y{syntax:\"*\";inherits:false;initial-value:0}@media (prefers-reduced-motion:reduce){:root{--duration-instant:0s;--duration-fast:0s;--duration-base:0s;--duration-slow:0s;--duration-slower:0s;--default-transition-duration:0s}[data-vaul-drawer],[data-vaul-overlay]{transition-duration:0s!important;animation-duration:0s!important}}.dark{--input:#35312f}@supports (color:color-mix(in lab, red, red)){.dark{--input:color-mix(in oklab, var(--color-stone-800) 55%, var(--color-stone-700))}}.dark{--surface:#35312f}@supports (color:color-mix(in lab, red, red)){.dark{--surface:color-mix(in oklab, var(--color-stone-800) 55%, var(--color-stone-700))}}.dark{--muted:#35312f}@supports (color:color-mix(in lab, red, red)){.dark{--muted:color-mix(in oklab, var(--color-stone-800) 55%, var(--color-stone-700))}}:root:not(.dark){--background:var(--color-neutral-50)}[data-slot=dialog-content],[data-slot=alert-dialog-content],[data-slot=sheet-content],[data-slot=drawer-content]{background-color:var(--card)}[data-slot=table-body] tr:hover{background-color:var(--accent)}@supports (color:color-mix(in lab, red, red)){[data-slot=table-body] tr:hover{background-color:color-mix(in oklab, var(--accent) 45%, transparent)}}:root{--brand:#2f6b4f;--brand-foreground:#f4faf6;--foreground:#14201a;--muted-foreground:#4a5c52;--border:#d5ddd7;--card:#ffffffd1;--input:#ffffffe6;--primary:#14201a;--primary-foreground:#f4f7f5;--primary-hover:var(--primary)}@supports (color:color-mix(in lab, red, red)){:root{--primary-hover:color-mix(in oklab, var(--primary) 72%, var(--brand))}}:root{--destructive:#a23b28;--ring:var(--brand);--panel-shadow:0 18px 40px -28px #14201a73;--backdrop:radial-gradient(900px 480px at 12% -10%, #dfece3, transparent 60%), radial-gradient(700px 420px at 100% 0%, #e7efe4, transparent 55%), linear-gradient(165deg, #e8f0ea, #f7f5f0 55%, #eef2ef)}.dark{--brand:#7cc39d;--brand-foreground:#0d1410;--foreground:#e9f0ec;--muted-foreground:#a2b3aa;--border:#e9f0ec24;--card:#181f1bb8;--input:#e9f0ec0f;--primary:#e9f0ec;--primary-foreground:#101711;--primary-hover:var(--primary)}@supports (color:color-mix(in lab, red, red)){.dark{--primary-hover:color-mix(in oklab, var(--primary) 72%, var(--brand))}}.dark{--destructive:#f0a596;--panel-shadow:0 18px 44px -26px #000000b3;--backdrop:radial-gradient(900px 480px at 12% -10%, #16261d, transparent 60%), radial-gradient(700px 420px at 100% 0%, #16221c, transparent 55%), linear-gradient(165deg, #0e1512, #121a15 55%, #0d130f)}@property --tw-border-style{syntax:\"*\";inherits:false;initial-value:solid}@property --tw-leading{syntax:\"*\";inherits:false}@property --tw-font-weight{syntax:\"*\";inherits:false}@property --tw-tracking{syntax:\"*\";inherits:false}@property --tw-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:\"*\";inherits:false}@property --tw-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:\"*\";inherits:false}@property --tw-inset-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:\"*\";inherits:false}@property --tw-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:\"*\";inherits:false}@property --tw-inset-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:\"*\";inherits:false}@property --tw-ring-offset-width{syntax:\"<length>\";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:\"*\";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-backdrop-blur{syntax:\"*\";inherits:false}@property --tw-backdrop-brightness{syntax:\"*\";inherits:false}@property --tw-backdrop-contrast{syntax:\"*\";inherits:false}@property --tw-backdrop-grayscale{syntax:\"*\";inherits:false}@property --tw-backdrop-hue-rotate{syntax:\"*\";inherits:false}@property --tw-backdrop-invert{syntax:\"*\";inherits:false}@property --tw-backdrop-opacity{syntax:\"*\";inherits:false}@property --tw-backdrop-saturate{syntax:\"*\";inherits:false}@property --tw-backdrop-sepia{syntax:\"*\";inherits:false}@property --tw-duration{syntax:\"*\";inherits:false}@property --tw-outline-style{syntax:\"*\";inherits:false;initial-value:solid}</style><script>matchMedia('(prefers-color-scheme:dark)').matches&&document.documentElement.classList.add('dark')<\/script></head><body class=\"canopy-backdrop grid min-h-svh place-items-center p-6 text-foreground\"><main class=\"w-full max-w-sm rounded-2xl border border-border bg-card p-8 shadow-panel backdrop-blur-[10px]\"><div class=\"mb-5 grid size-11 place-items-center rounded-xl bg-brand text-brand-foreground\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-check size-5\" aria-hidden=\"true\"><path d=\"M20 6 9 17l-5-5\"></path></svg></div><p class=\"mb-1 text-xs font-semibold uppercase tracking-wide text-brand\">Canopy CLI</p><h1 class=\"mb-2 text-2xl font-semibold tracking-tight break-words\">You’re signed in</h1><p class=\"mt-2 text-sm leading-relaxed text-muted-foreground\">You can close this tab and return to the terminal — the CLI has your code.</p><p class=\"mt-6 border-t border-border pt-4 text-xs text-muted-foreground\">This tab only finishes the browser step — keep using the terminal for the rest.</p></main></body></html>";
9
+ const failedHtml = "<!doctype html><html lang=\"en\"><head><meta charSet=\"utf-8\"/><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"/><title>Sign-in didn’t finish · Canopy</title><style>/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-outline-style:solid;--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0}}}@layer theme{:root,:host{--font-sans:\"Helvetica Now for Monks\", ui-sans-serif, system-ui, sans-serif;--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;--color-red-100:#ffebf0;--color-red-200:#ffd1dd;--color-red-300:#ffa8be;--color-red-400:#ff7a9c;--color-red-500:#ff527d;--color-red-600:#ff245b;--color-red-800:#a30029;--color-red-950:#610018;--color-amber-200:#fde68a;--color-amber-950:#451a03;--color-yellow-100:#fff7db;--color-yellow-900:#7a6000;--color-green-100:#e3fcf1;--color-green-200:#b8fadd;--color-green-900:#067445;--color-green-950:#065533;--color-purple-50:#faf6fd;--color-purple-300:#d6b6f1;--color-purple-400:#c598ec;--color-purple-500:#ac6de3;--color-purple-600:#8c3fd2;--color-purple-700:#7d26c9;--color-purple-900:#501881;--color-gray-800:#5d5d60;--color-neutral-50:#f5f5f4;--color-neutral-100:#e9e8e7;--color-neutral-200:#d6d4d2;--color-neutral-300:#c0beb9;--color-neutral-400:#adaaa4;--color-neutral-500:#97938c;--color-neutral-600:#837f77;--color-neutral-700:#6c6962;--color-neutral-900:#484641;--color-neutral-950:#3e3c38;--color-stone-500:#78716c;--color-stone-600:#57534e;--color-stone-700:#44403c;--color-stone-800:#292524;--color-stone-900:#1c1917;--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--text-xs:12px;--text-xs--line-height:16px;--text-sm:14px;--text-sm--line-height:20px;--text-2xl:24px;--text-2xl--line-height:32px;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.01em;--tracking-wide:.015em;--leading-snug:1.375;--leading-normal:1.5;--leading-relaxed:1.625;--radius-md:6px;--radius-lg:8px;--radius-xl:12px;--radius-2xl:16px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-foreground:var(--foreground);--color-primary:var(--primary);--color-primary-foreground:var(--primary-foreground);--color-muted-foreground:var(--muted-foreground);--color-destructive:var(--destructive);--color-border:var(--border);--color-card:var(--card);--color-brand:var(--brand);--color-brand-foreground:var(--brand-foreground)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", \"Noto Sans\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:root,[data-theme=monks-flow]{--background:var(--color-white);--background-emphasis:var(--color-neutral-900);--foreground:var(--color-neutral-950);--foreground-alt:var(--color-neutral-700);--foreground-subtle:var(--color-neutral-600);--primary:var(--color-neutral-900);--primary-foreground:var(--color-neutral-50);--primary-hover:var(--color-neutral-950);--secondary:#f5f3f0;--secondary-foreground:var(--color-neutral-900);--secondary-hover:#e7e2dc;--muted:var(--color-neutral-100);--muted-foreground:var(--color-neutral-500);--accent:#e7e2dc;--accent-foreground:var(--color-neutral-900);--destructive:#e11d48;--destructive-foreground:var(--color-white);--destructive-soft:var(--color-red-100);--destructive-soft-foreground:var(--color-red-800);--ghost:#fff0;--ghost-foreground:var(--color-neutral-700);--ghost-hover:#0000000d;--positive:var(--color-green-100);--positive-foreground:var(--color-green-900);--surface:var(--color-neutral-50);--surface-emphasis:var(--color-neutral-300);--surface-raised:var(--color-neutral-200);--border:var(--color-neutral-200);--border-light:var(--color-neutral-100);--border-lighter:var(--color-neutral-50);--border-strong:var(--color-neutral-400);--input:var(--color-neutral-50);--input-foreground:var(--color-neutral-950);--ring:var(--color-black);--ring-error:var(--color-red-300);--card:var(--color-white);--card-foreground:var(--color-neutral-950);--popover:var(--color-white);--popover-foreground:var(--color-neutral-950);--warning:var(--color-yellow-100);--warning-foreground:var(--color-yellow-900);--chart-1:#f54a00;--chart-2:#009689;--chart-3:#104e64;--chart-4:#ffb900;--chart-5:#fe9a00;--chart-negative:#f54a00;--chart-positive:#009689;--chart-fill:#bfdeffb3;--chart-fill-2:#aaccffb3;--chart-stroke-2:#3f8dff;--sidebar:var(--color-neutral-50);--sidebar-foreground:var(--color-gray-800);--sidebar-primary:var(--primary);--sidebar-primary-foreground:var(--primary-foreground);--sidebar-accent:var(--accent);--sidebar-accent-foreground:var(--accent-foreground);--sidebar-border:var(--color-neutral-200);--sidebar-ring:var(--ring);--backdrop:#0009;--theme-background:#f5f4f2}:root.dark:not([data-theme]),[data-theme=monks-flow].dark,[data-theme=monks-flow] .dark{--background:var(--color-stone-900);--background-emphasis:var(--color-neutral-100);--foreground:var(--color-neutral-50);--foreground-alt:var(--color-neutral-300);--foreground-subtle:var(--color-neutral-400);--primary:var(--color-neutral-50);--primary-foreground:var(--color-black);--primary-hover:var(--color-neutral-100);--secondary:var(--color-stone-700);--secondary-foreground:var(--color-neutral-100);--secondary-hover:var(--color-stone-600);--muted:var(--color-stone-800);--muted-foreground:var(--color-neutral-500);--accent:var(--color-neutral-900);--accent-foreground:var(--color-neutral-300);--destructive:var(--color-red-500);--destructive-foreground:var(--color-white);--destructive-soft:var(--color-red-950);--destructive-soft-foreground:var(--color-red-200);--ghost:#fff0;--ghost-foreground:var(--color-neutral-300);--ghost-hover:#ffffff14;--positive:var(--color-green-950);--positive-foreground:var(--color-green-200);--surface:var(--color-stone-800);--surface-emphasis:var(--color-stone-600);--surface-raised:var(--color-stone-700);--border:var(--color-stone-600);--border-light:var(--color-stone-700);--border-lighter:var(--color-stone-800);--border-strong:var(--color-stone-500);--input:var(--color-stone-800);--input-foreground:var(--color-neutral-50);--ring:var(--color-white);--ring-error:var(--color-red-400);--card:var(--color-stone-800);--card-foreground:var(--color-neutral-100);--popover:var(--color-stone-800);--popover-foreground:var(--color-neutral-100);--warning:var(--color-amber-950);--warning-foreground:var(--color-amber-200);--chart-1:#ff6b33;--chart-2:#00b3a4;--chart-3:#2196a8;--chart-4:#ffc733;--chart-5:#ffad33;--chart-negative:#ff6b33;--chart-positive:#00b3a4;--chart-fill:#3382ff40;--chart-fill-2:#5096ff33;--chart-stroke-2:#5da3ff;--sidebar:var(--color-stone-800);--sidebar-foreground:var(--color-neutral-300);--sidebar-primary:var(--primary);--sidebar-primary-foreground:var(--primary-foreground);--sidebar-accent:var(--accent);--sidebar-accent-foreground:var(--accent-foreground);--sidebar-border:var(--color-stone-700);--sidebar-ring:var(--ring);--backdrop:#000c;--theme-background:#0c0a09}[data-theme=metropolis]{--background:var(--color-white);--background-emphasis:var(--color-neutral-900);--foreground:var(--color-neutral-950);--foreground-alt:var(--color-neutral-700);--foreground-subtle:var(--color-neutral-600);--primary:var(--color-purple-600);--primary-foreground:var(--color-neutral-50);--primary-hover:var(--color-purple-700);--secondary:var(--color-neutral-100);--secondary-foreground:var(--color-neutral-900);--secondary-hover:var(--color-neutral-50);--muted:var(--color-neutral-100);--muted-foreground:var(--color-neutral-500);--accent:var(--color-purple-50);--accent-foreground:var(--color-purple-600);--destructive:var(--color-red-600);--destructive-foreground:var(--color-white);--destructive-soft:var(--color-red-100);--destructive-soft-foreground:var(--color-red-800);--ghost:#fff0;--ghost-foreground:var(--color-neutral-700);--ghost-hover:#0000000d;--positive:var(--color-green-100);--positive-foreground:var(--color-green-900);--surface:var(--color-neutral-50);--surface-emphasis:var(--color-neutral-300);--surface-raised:var(--color-neutral-200);--border:var(--color-neutral-200);--border-light:var(--color-neutral-100);--border-lighter:var(--color-neutral-50);--border-strong:var(--color-neutral-400);--input:var(--color-neutral-50);--input-foreground:var(--color-neutral-950);--ring:var(--color-neutral-300);--ring-error:var(--color-red-300);--card:var(--color-white);--card-foreground:var(--color-neutral-950);--popover:var(--color-white);--popover-foreground:var(--color-neutral-950);--warning:var(--color-yellow-100);--warning-foreground:var(--color-yellow-900);--chart-1:#f54a00;--chart-2:#009689;--chart-3:#104e64;--chart-4:#ffb900;--chart-5:#fe9a00;--chart-negative:#f54a00;--chart-positive:#009689;--chart-fill:#bfdeffb3;--chart-fill-2:#aaccffb3;--chart-stroke-2:#3f8dff;--sidebar:var(--color-neutral-50);--sidebar-foreground:var(--color-gray-800);--sidebar-primary:var(--primary);--sidebar-primary-foreground:var(--primary-foreground);--sidebar-accent:var(--accent);--sidebar-accent-foreground:var(--accent-foreground);--sidebar-border:var(--color-neutral-200);--sidebar-ring:var(--color-neutral-300);--backdrop:#0009;--theme-background:#f0f3f8}[data-theme=metropolis].dark,[data-theme=metropolis] .dark{--background:var(--color-stone-900);--background-emphasis:var(--color-neutral-100);--foreground:var(--color-neutral-50);--foreground-alt:var(--color-neutral-300);--foreground-subtle:var(--color-neutral-400);--primary:var(--color-purple-500);--primary-foreground:var(--color-white);--primary-hover:var(--color-purple-400);--secondary:var(--color-stone-700);--secondary-foreground:var(--color-neutral-100);--secondary-hover:var(--color-stone-600);--muted:var(--color-stone-800);--muted-foreground:var(--color-neutral-400);--accent:var(--color-purple-900);--accent-foreground:var(--color-purple-300);--destructive:var(--color-red-500);--destructive-foreground:var(--color-white);--destructive-soft:var(--color-red-950);--destructive-soft-foreground:var(--color-red-200);--ghost:#fff0;--ghost-foreground:var(--color-neutral-300);--ghost-hover:#ffffff14;--positive:var(--color-green-950);--positive-foreground:var(--color-green-200);--surface:var(--color-stone-800);--surface-emphasis:var(--color-stone-600);--surface-raised:var(--color-stone-700);--border:var(--color-stone-600);--border-light:var(--color-stone-700);--border-lighter:var(--color-stone-800);--border-strong:var(--color-stone-500);--input:var(--color-stone-800);--input-foreground:var(--color-neutral-50);--ring:var(--color-neutral-500);--ring-error:var(--color-red-400);--card:var(--color-stone-800);--card-foreground:var(--color-neutral-100);--popover:var(--color-stone-800);--popover-foreground:var(--color-neutral-100);--warning:var(--color-amber-950);--warning-foreground:var(--color-amber-200);--chart-1:#ff6b33;--chart-2:#00b3a4;--chart-3:#2196a8;--chart-4:#ffc733;--chart-5:#ffad33;--chart-negative:#ff6b33;--chart-positive:#00b3a4;--chart-fill:#3382ff40;--chart-fill-2:#5096ff33;--chart-stroke-2:#5da3ff;--sidebar:var(--color-stone-800);--sidebar-foreground:var(--color-neutral-300);--sidebar-primary:var(--primary);--sidebar-primary-foreground:var(--primary-foreground);--sidebar-accent:var(--accent);--sidebar-accent-foreground:var(--accent-foreground);--sidebar-border:var(--color-stone-700);--sidebar-ring:var(--color-neutral-500);--backdrop:#000c;--theme-background:#0c0a09}*{border-color:var(--border)}body{background-color:var(--background);color:var(--foreground)}button,[role=button]{cursor:pointer}:focus-visible{outline:2px solid var(--ring);outline-offset:2px}}@layer components;@layer utilities{.relative{position:relative}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3\\.5{margin-top:calc(var(--spacing) * 3.5)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mt-px{margin-top:1px}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-1{margin-bottom:var(--spacing)}.mb-1\\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-5{margin-bottom:calc(var(--spacing) * 5)}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.size-11{width:calc(var(--spacing) * 11);height:calc(var(--spacing) * 11)}.h-11{height:calc(var(--spacing) * 11)}.min-h-svh{min-height:100svh}.w-full{width:100%}.max-w-sm{max-width:var(--container-sm)}.shrink-0{flex-shrink:0}.place-items-center{place-items:center}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-center{justify-content:center}.gap-1\\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\\.5{gap:calc(var(--spacing) * 2.5)}.overflow-x-auto{overflow-x:auto}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-lg{border-radius:var(--radius-lg)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-r-md{border-top-right-radius:var(--radius-md);border-bottom-right-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-border{border-color:var(--color-border)}.border-brand{border-color:var(--color-brand)}.border-destructive{border-color:var(--color-destructive)}.bg-\\[color-mix\\(in_oklab\\,var\\(--destructive\\)_8\\%\\,transparent\\)\\]{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.bg-\\[color-mix\\(in_oklab\\,var\\(--destructive\\)_8\\%\\,transparent\\)\\]{background-color:color-mix(in oklab,var(--destructive) 8%,transparent)}}.bg-\\[color-mix\\(in_oklab\\,var\\(--foreground\\)_6\\%\\,transparent\\)\\]{background-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.bg-\\[color-mix\\(in_oklab\\,var\\(--foreground\\)_6\\%\\,transparent\\)\\]{background-color:color-mix(in oklab,var(--foreground) 6%,transparent)}}.bg-\\[var\\(--input\\)\\]{background-color:var(--input)}.bg-brand{background-color:var(--color-brand)}.bg-card{background-color:var(--color-card)}.bg-destructive{background-color:var(--color-destructive)}.bg-primary{background-color:var(--color-primary)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.px-1{padding-inline:var(--spacing)}.px-2\\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3\\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\\.5{padding-block:calc(var(--spacing) * 2.5)}.py-px{padding-block:1px}.pt-4{padding-top:calc(var(--spacing) * 4)}.pr-3{padding-right:calc(var(--spacing) * 3)}.pl-3{padding-left:calc(var(--spacing) * 3)}.text-center{text-align:center}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\\[0\\.85em\\]{font-size:.85em}.leading-normal{--tw-leading:var(--leading-normal);line-height:var(--leading-normal)}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.break-words{overflow-wrap:break-word}.text-\\[var\\(--card\\)\\]{color:var(--card)}.text-brand{color:var(--color-brand)}.text-brand-foreground{color:var(--color-brand-foreground)}.text-destructive{color:var(--color-destructive)}.text-foreground{color:var(--color-foreground)}.text-muted-foreground{color:var(--color-muted-foreground)}.text-primary-foreground{color:var(--color-primary-foreground)}.uppercase{text-transform:uppercase}.underline{text-decoration-line:underline}.underline-offset-2{text-underline-offset:2px}.shadow-panel{--tw-shadow:var(--panel-shadow);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.backdrop-blur-\\[10px\\]{--tw-backdrop-blur:blur(10px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.select-none{-webkit-user-select:none;user-select:none}.canopy-backdrop{background:var(--backdrop)}.paused{animation-play-state:paused}.running{animation-play-state:running}@media (hover:hover){.hover\\:bg-\\[var\\(--primary-hover\\)\\]:hover{background-color:var(--primary-hover)}.hover\\:text-foreground:hover{color:var(--color-foreground)}}.focus-visible\\:border-brand:focus-visible{border-color:var(--color-brand)}.focus-visible\\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\\:outline-offset-1:focus-visible{outline-offset:1px}.focus-visible\\:outline-offset-2:focus-visible{outline-offset:2px}.focus-visible\\:outline-offset-\\[3px\\]:focus-visible{outline-offset:3px}.focus-visible\\:outline-brand:focus-visible{outline-color:var(--color-brand)}.aria-invalid\\:border-destructive[aria-invalid=true]{border-color:var(--color-destructive)}}@property --tw-animation-delay{syntax:\"*\";inherits:false;initial-value:0s}@property --tw-animation-direction{syntax:\"*\";inherits:false;initial-value:normal}@property --tw-animation-duration{syntax:\"*\";inherits:false}@property --tw-animation-fill-mode{syntax:\"*\";inherits:false;initial-value:none}@property --tw-animation-iteration-count{syntax:\"*\";inherits:false;initial-value:1}@property --tw-enter-blur{syntax:\"*\";inherits:false;initial-value:0}@property --tw-enter-opacity{syntax:\"*\";inherits:false;initial-value:1}@property --tw-enter-rotate{syntax:\"*\";inherits:false;initial-value:0}@property --tw-enter-scale{syntax:\"*\";inherits:false;initial-value:1}@property --tw-enter-translate-x{syntax:\"*\";inherits:false;initial-value:0}@property --tw-enter-translate-y{syntax:\"*\";inherits:false;initial-value:0}@property --tw-exit-blur{syntax:\"*\";inherits:false;initial-value:0}@property --tw-exit-opacity{syntax:\"*\";inherits:false;initial-value:1}@property --tw-exit-rotate{syntax:\"*\";inherits:false;initial-value:0}@property --tw-exit-scale{syntax:\"*\";inherits:false;initial-value:1}@property --tw-exit-translate-x{syntax:\"*\";inherits:false;initial-value:0}@property --tw-exit-translate-y{syntax:\"*\";inherits:false;initial-value:0}@media (prefers-reduced-motion:reduce){:root{--duration-instant:0s;--duration-fast:0s;--duration-base:0s;--duration-slow:0s;--duration-slower:0s;--default-transition-duration:0s}[data-vaul-drawer],[data-vaul-overlay]{transition-duration:0s!important;animation-duration:0s!important}}.dark{--input:#35312f}@supports (color:color-mix(in lab, red, red)){.dark{--input:color-mix(in oklab, var(--color-stone-800) 55%, var(--color-stone-700))}}.dark{--surface:#35312f}@supports (color:color-mix(in lab, red, red)){.dark{--surface:color-mix(in oklab, var(--color-stone-800) 55%, var(--color-stone-700))}}.dark{--muted:#35312f}@supports (color:color-mix(in lab, red, red)){.dark{--muted:color-mix(in oklab, var(--color-stone-800) 55%, var(--color-stone-700))}}:root:not(.dark){--background:var(--color-neutral-50)}[data-slot=dialog-content],[data-slot=alert-dialog-content],[data-slot=sheet-content],[data-slot=drawer-content]{background-color:var(--card)}[data-slot=table-body] tr:hover{background-color:var(--accent)}@supports (color:color-mix(in lab, red, red)){[data-slot=table-body] tr:hover{background-color:color-mix(in oklab, var(--accent) 45%, transparent)}}:root{--brand:#2f6b4f;--brand-foreground:#f4faf6;--foreground:#14201a;--muted-foreground:#4a5c52;--border:#d5ddd7;--card:#ffffffd1;--input:#ffffffe6;--primary:#14201a;--primary-foreground:#f4f7f5;--primary-hover:var(--primary)}@supports (color:color-mix(in lab, red, red)){:root{--primary-hover:color-mix(in oklab, var(--primary) 72%, var(--brand))}}:root{--destructive:#a23b28;--ring:var(--brand);--panel-shadow:0 18px 40px -28px #14201a73;--backdrop:radial-gradient(900px 480px at 12% -10%, #dfece3, transparent 60%), radial-gradient(700px 420px at 100% 0%, #e7efe4, transparent 55%), linear-gradient(165deg, #e8f0ea, #f7f5f0 55%, #eef2ef)}.dark{--brand:#7cc39d;--brand-foreground:#0d1410;--foreground:#e9f0ec;--muted-foreground:#a2b3aa;--border:#e9f0ec24;--card:#181f1bb8;--input:#e9f0ec0f;--primary:#e9f0ec;--primary-foreground:#101711;--primary-hover:var(--primary)}@supports (color:color-mix(in lab, red, red)){.dark{--primary-hover:color-mix(in oklab, var(--primary) 72%, var(--brand))}}.dark{--destructive:#f0a596;--panel-shadow:0 18px 44px -26px #000000b3;--backdrop:radial-gradient(900px 480px at 12% -10%, #16261d, transparent 60%), radial-gradient(700px 420px at 100% 0%, #16221c, transparent 55%), linear-gradient(165deg, #0e1512, #121a15 55%, #0d130f)}@property --tw-border-style{syntax:\"*\";inherits:false;initial-value:solid}@property --tw-leading{syntax:\"*\";inherits:false}@property --tw-font-weight{syntax:\"*\";inherits:false}@property --tw-tracking{syntax:\"*\";inherits:false}@property --tw-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:\"*\";inherits:false}@property --tw-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:\"*\";inherits:false}@property --tw-inset-shadow-alpha{syntax:\"<percentage>\";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:\"*\";inherits:false}@property --tw-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:\"*\";inherits:false}@property --tw-inset-ring-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:\"*\";inherits:false}@property --tw-ring-offset-width{syntax:\"<length>\";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:\"*\";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:\"*\";inherits:false;initial-value:0 0 #0000}@property --tw-backdrop-blur{syntax:\"*\";inherits:false}@property --tw-backdrop-brightness{syntax:\"*\";inherits:false}@property --tw-backdrop-contrast{syntax:\"*\";inherits:false}@property --tw-backdrop-grayscale{syntax:\"*\";inherits:false}@property --tw-backdrop-hue-rotate{syntax:\"*\";inherits:false}@property --tw-backdrop-invert{syntax:\"*\";inherits:false}@property --tw-backdrop-opacity{syntax:\"*\";inherits:false}@property --tw-backdrop-saturate{syntax:\"*\";inherits:false}@property --tw-backdrop-sepia{syntax:\"*\";inherits:false}@property --tw-duration{syntax:\"*\";inherits:false}@property --tw-outline-style{syntax:\"*\";inherits:false;initial-value:solid}</style><script>matchMedia('(prefers-color-scheme:dark)').matches&&document.documentElement.classList.add('dark')<\/script></head><body class=\"canopy-backdrop grid min-h-svh place-items-center p-6 text-foreground\"><main class=\"w-full max-w-sm rounded-2xl border border-border bg-card p-8 shadow-panel backdrop-blur-[10px]\"><div class=\"mb-5 grid size-11 place-items-center rounded-xl bg-destructive text-[var(--card)]\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-circle-alert size-5\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" x2=\"12\" y1=\"8\" y2=\"12\"></line><line x1=\"12\" x2=\"12.01\" y1=\"16\" y2=\"16\"></line></svg></div><p class=\"mb-1 text-xs font-semibold uppercase tracking-wide text-brand\">Canopy CLI</p><h1 class=\"mb-2 text-2xl font-semibold tracking-tight break-words\">Sign-in didn’t finish</h1><p class=\"mt-2 text-sm leading-relaxed text-muted-foreground\">Return to the terminal and run canopy login again. Reloading this page won’t help.</p><p class=\"mt-6 border-t border-border pt-4 text-xs text-muted-foreground\">If the terminal still says it’s waiting, cancel with <kbd class=\"rounded border border-border bg-[var(--input)] px-1 py-px text-[0.85em] font-normal\">Ctrl</kbd>+<kbd class=\"rounded border border-border bg-[var(--input)] px-1 py-px text-[0.85em] font-normal\">C</kbd> and try again.</p></main></body></html>";
10
+ //#endregion
11
+ //#region src/login-page.ts
12
+ /**
13
+ * Branded HTML for the local OneLogin PKCE callback (127.0.0.1:8976). The page
14
+ * lives in @mediamonks/canopy-pages next to the gateway's sign-in and error
15
+ * walls so all seven look like one another, and is pre-rendered there at build
16
+ * time: it takes no data, and the CLI has no business shipping React and an
17
+ * icon set to print two fixed documents.
18
+ */
19
+ function loginCallbackPage(ok) {
20
+ return ok ? okHtml : failedHtml;
21
+ }
22
+ //#endregion
23
+ //#region src/login.ts
24
+ /**
25
+ * canopy login | whoami | logout — browser PKCE flow against OneLogin (public
26
+ * client), then trade the ID token for platform CLI tokens via POST
27
+ * /control/v1/auth/cli-token on every baked site (docs/10-cli-sites.md D17).
28
+ */
29
+ const CALLBACK_PORT = 8976;
30
+ const REDIRECT_URI = `http://127.0.0.1:${CALLBACK_PORT}/callback`;
31
+ const LOGIN_TIMEOUT_MS = 300 * 1e3;
32
+ const base64url = (buf) => buf.toString("base64url");
33
+ const whoamiCommand = defineCommand({
34
+ meta: {
35
+ name: "whoami",
36
+ description: "Show the current Canopy login"
37
+ },
38
+ run: reportErrors("whoami", async () => {
39
+ const config = siteConfig();
40
+ if (!config.token) throw new Error("Not logged in — run `canopy login`.");
41
+ console.log(config.email ?? "<unknown email>");
42
+ if (config.cloud) console.log(`Cloud: ${config.cloud}`);
43
+ console.log(`API: ${config.apiUrl}`);
44
+ if (config.tokenExpiresAt !== void 0) {
45
+ const expired = Date.parse(config.tokenExpiresAt) < Date.now();
46
+ console.log(expired ? `Token EXPIRED ${config.tokenExpiresAt} — run \`canopy login\` again.` : `Token expires ${config.tokenExpiresAt}.`);
47
+ }
48
+ })
49
+ });
50
+ const logoutCommand = defineCommand({
51
+ meta: {
52
+ name: "logout",
53
+ description: "Sign out: forget all local CLI tokens"
54
+ },
55
+ run: reportErrors("logout", async () => {
56
+ const file = readConfigFile();
57
+ if (!Object.values(file.profiles ?? {}).some((p) => p?.token)) {
58
+ console.log("Not logged in.");
59
+ return;
60
+ }
61
+ clearAllProfileTokens();
62
+ console.log("Logged out — all site tokens removed from ~/.canopy/config.json.");
63
+ })
64
+ });
65
+ /** Wait for OneLogin to redirect back to the local loopback server. */
66
+ function waitForCallback(expectedState) {
67
+ return new Promise((resolve, reject) => {
68
+ const server = createServer((req, res) => {
69
+ const url = new URL(req.url ?? "/", REDIRECT_URI);
70
+ if (url.pathname !== "/callback") {
71
+ res.writeHead(404).end();
72
+ return;
73
+ }
74
+ const code = url.searchParams.get("code");
75
+ const state = url.searchParams.get("state");
76
+ const ok = Boolean(code) && state === expectedState;
77
+ res.writeHead(ok ? 200 : 400, {
78
+ "content-type": "text/html; charset=utf-8",
79
+ "cache-control": "no-store"
80
+ }).end(loginCallbackPage(ok));
81
+ server.close();
82
+ clearTimeout(timer);
83
+ if (ok) resolve(code);
84
+ else reject(new Error(url.searchParams.get("error_description") ?? "Login rejected"));
85
+ });
86
+ const timer = setTimeout(() => {
87
+ server.close();
88
+ reject(/* @__PURE__ */ new Error("Timed out waiting for the browser login (5 minutes)."));
89
+ }, LOGIN_TIMEOUT_MS);
90
+ server.on("error", (err) => reject(err.message.includes("EADDRINUSE") ? /* @__PURE__ */ new Error(`Port ${CALLBACK_PORT} is in use — close the other process and retry.`) : err));
91
+ server.listen(CALLBACK_PORT, "127.0.0.1");
92
+ });
93
+ }
94
+ async function pickActiveProfile(json, flag) {
95
+ if (flag) {
96
+ if (!isProfileId(flag)) throw new Error(`Unknown profile "${flag}". Choose one of: ${listBakedProfiles().map((p) => p.id).join(", ")}.`);
97
+ return flag;
98
+ }
99
+ const env = process.env["CANOPY_PROFILE"]?.trim();
100
+ if (env) {
101
+ if (!isProfileId(env)) throw new Error(`Unknown CANOPY_PROFILE "${env}".`);
102
+ return env;
103
+ }
104
+ const profiles = listBakedProfiles();
105
+ if (!process.stdin.isTTY || json) throw new Error(`Pass --profile <id> (or CANOPY_PROFILE) when not on a TTY. Options: ${profiles.map((p) => p.id).join(", ")}.`);
106
+ const choice = await p.select({
107
+ message: "Which Canopy site should be your default?",
108
+ options: profiles.map((prof) => ({
109
+ value: prof.id,
110
+ label: prof.label,
111
+ hint: prof.cloud
112
+ })),
113
+ initialValue: "main"
114
+ });
115
+ if (p.isCancel(choice)) {
116
+ p.cancel("Login cancelled.");
117
+ process.exit(1);
118
+ }
119
+ p.note(`Using profile "${choice}". Agents/non-TTY: canopy login --profile ${choice}`, "Active profile");
120
+ return choice;
121
+ }
122
+ async function mintForProfile(id, idToken) {
123
+ const baked = getBakedProfile(id);
124
+ try {
125
+ const cliTokenRes = await fetch(`${baked.apiUrl}/control/v1/auth/cli-token`, {
126
+ method: "POST",
127
+ headers: { "content-type": "application/json" },
128
+ body: JSON.stringify({ id_token: idToken })
129
+ });
130
+ if (!cliTokenRes.ok) return {
131
+ ok: false,
132
+ error: `${cliTokenRes.status} ${await cliTokenRes.text()}`
133
+ };
134
+ const { token, expires_at, user } = await cliTokenRes.json();
135
+ upsertProfileAuth(id, {
136
+ token,
137
+ tokenExpiresAt: expires_at,
138
+ email: user.email
139
+ });
140
+ return {
141
+ ok: true,
142
+ email: user.email,
143
+ expiresAt: expires_at
144
+ };
145
+ } catch (err) {
146
+ return {
147
+ ok: false,
148
+ error: err instanceof Error ? err.message : String(err)
149
+ };
150
+ }
151
+ }
152
+ async function login(json, profileFlag) {
153
+ if (!json) p.intro("canopy login");
154
+ const active = await pickActiveProfile(json, profileFlag);
155
+ const file = readConfigFile();
156
+ const { issuer, cliClientId } = {
157
+ issuer: process.env["CANOPY_OIDC_ISSUER"] ?? file.issuer ?? "https://s4capital.onelogin.com/oidc/2",
158
+ cliClientId: process.env["CANOPY_OIDC_CLIENT_ID"] ?? file.cliClientId ?? "b69755d0-6678-013f-b5ce-09fe44a57aa0180501"
159
+ };
160
+ if (cliClientId.includes("REPLACE")) throw new Error("The CLI's OneLogin app is not configured yet (set CANOPY_OIDC_CLIENT_ID or packages/cli/src/config.ts).");
161
+ writeConfigFile({
162
+ ...file,
163
+ issuer,
164
+ cliClientId,
165
+ activeProfile: active
166
+ });
167
+ const discoveryRes = await fetch(`${issuer}/.well-known/openid-configuration`);
168
+ if (!discoveryRes.ok) throw new Error(`OIDC discovery failed: ${discoveryRes.status}`);
169
+ const discovery = await discoveryRes.json();
170
+ const state = base64url(randomBytes(32));
171
+ const codeVerifier = base64url(randomBytes(32));
172
+ const authorizeUrl = new URL(discovery.authorization_endpoint);
173
+ authorizeUrl.search = new URLSearchParams({
174
+ response_type: "code",
175
+ client_id: cliClientId,
176
+ redirect_uri: REDIRECT_URI,
177
+ scope: "openid profile email",
178
+ state,
179
+ code_challenge: base64url(createHash("sha256").update(codeVerifier).digest()),
180
+ code_challenge_method: "S256"
181
+ }).toString();
182
+ const authorizeHref = authorizeUrl.toString();
183
+ openBrowser(authorizeHref);
184
+ const spin = json ? void 0 : p.spinner();
185
+ if (json) console.log(JSON.stringify({
186
+ status: "waiting",
187
+ url: authorizeHref
188
+ }));
189
+ else {
190
+ p.log.step("Opening OneLogin in your browser");
191
+ p.log.message("If nothing opens, visit:");
192
+ console.log(authorizeHref);
193
+ spin?.start("Waiting for you to sign in in the browser…");
194
+ }
195
+ let code;
196
+ try {
197
+ code = await waitForCallback(state);
198
+ } catch (err) {
199
+ spin?.error("Sign-in failed.");
200
+ throw err;
201
+ }
202
+ spin?.stop("Signed in with OneLogin.");
203
+ const tokenRes = await fetch(discovery.token_endpoint, {
204
+ method: "POST",
205
+ headers: { "content-type": "application/x-www-form-urlencoded" },
206
+ body: new URLSearchParams({
207
+ grant_type: "authorization_code",
208
+ client_id: cliClientId,
209
+ code,
210
+ redirect_uri: REDIRECT_URI,
211
+ code_verifier: codeVerifier
212
+ })
213
+ });
214
+ if (!tokenRes.ok) throw new Error(`Token exchange failed: ${tokenRes.status} ${await tokenRes.text()}`);
215
+ const { id_token: idToken } = await tokenRes.json();
216
+ if (!idToken) throw new Error("OneLogin returned no id_token.");
217
+ const mintSpin = json ? void 0 : p.spinner();
218
+ mintSpin?.start("Minting CLI tokens for each site…");
219
+ const results = [];
220
+ for (const prof of listBakedProfiles()) {
221
+ const result = await mintForProfile(prof.id, idToken);
222
+ results.push({
223
+ id: prof.id,
224
+ ok: result.ok,
225
+ detail: result.ok ? `expires ${result.expiresAt}` : result.error
226
+ });
227
+ }
228
+ mintSpin?.stop("Token mint finished.");
229
+ if (!results.find((r) => r.id === active)?.ok) {
230
+ const summary = results.map((r) => `${r.id} ${r.ok ? "✓" : "✗"}`).join(" ");
231
+ throw new Error(`Could not mint a token for active profile "${active}". ${summary}. Re-run \`canopy login\`.`);
232
+ }
233
+ setActiveProfile(active);
234
+ const email = readConfigFile().profiles?.[active]?.email;
235
+ const summary = results.map((r) => `${r.id} ${r.ok ? "✓" : `✗ (${r.detail})`}`).join("\n");
236
+ if (json) console.log(JSON.stringify({
237
+ status: "ok",
238
+ email,
239
+ activeProfile: active,
240
+ profiles: Object.fromEntries(results.map((r) => [r.id, {
241
+ ok: r.ok,
242
+ detail: r.detail
243
+ }]))
244
+ }));
245
+ else {
246
+ p.note(summary, "Sites");
247
+ p.outro(`Logged in as ${email ?? "unknown"} — default profile "${active}".`);
248
+ for (const r of results.filter((x) => !x.ok)) p.log.warn(`${r.id} failed — re-run \`canopy login\` to retry all sites.`);
249
+ }
250
+ }
251
+ const loginCommand = defineCommand({
252
+ meta: {
253
+ name: "login",
254
+ description: "Sign in to Canopy via OneLogin"
255
+ },
256
+ args: {
257
+ json: {
258
+ type: "boolean",
259
+ default: false,
260
+ description: "Emit machine-readable status to stdout (for agents/CI)"
261
+ },
262
+ profile: {
263
+ type: "string",
264
+ description: "Active default profile (main | staging | gcp-pilot); required non-TTY"
265
+ }
266
+ },
267
+ run: reportErrors("login", async ({ args }) => {
268
+ const json = args.json;
269
+ try {
270
+ await login(json, args.profile);
271
+ } catch (err) {
272
+ if (json) {
273
+ console.log(JSON.stringify({
274
+ status: "error",
275
+ message: err instanceof Error ? err.message : String(err)
276
+ }));
277
+ process.exitCode = 1;
278
+ return;
279
+ }
280
+ throw err;
281
+ }
282
+ })
283
+ });
284
+ //#endregion
285
+ export { loginCommand, logoutCommand, whoamiCommand };
@@ -1,5 +1,5 @@
1
1
  import { c as resolveProject, o as projectFlagArgs } from "./site-BFaWfSVu.mjs";
2
- import { d as withContext, l as apiRequest, r as reportErrors } from "./ui-DLZNEen6.mjs";
2
+ import { d as withContext, l as apiRequest, r as reportErrors } from "./ui--atbZ-TM.mjs";
3
3
  import { defineCommand } from "citty";
4
4
  //#region src/logs.ts
5
5
  /**
@@ -1,5 +1,5 @@
1
1
  import { u as tryReadCanopyJson } from "./site-BFaWfSVu.mjs";
2
- import { s as apiDataRequest } from "./ui-DLZNEen6.mjs";
2
+ import { s as apiDataRequest } from "./ui--atbZ-TM.mjs";
3
3
  import { readFileSync, readdirSync } from "node:fs";
4
4
  import { join, resolve } from "node:path";
5
5
  //#region src/migrations.ts
@@ -1,5 +1,5 @@
1
1
  import { a as projectDirArgs, c as resolveProject, l as stagingUrl, s as projectUrl } from "./site-BFaWfSVu.mjs";
2
- import { n as openBrowser, r as reportErrors } from "./ui-DLZNEen6.mjs";
2
+ import { n as openBrowser, r as reportErrors } from "./ui--atbZ-TM.mjs";
3
3
  import { defineCommand } from "citty";
4
4
  //#region src/open.ts
5
5
  /**
@@ -1,4 +1,4 @@
1
1
  //#region package.json
2
- var version = "0.7.18";
2
+ var version = "0.7.20";
3
3
  //#endregion
4
4
  export { version as t };
@@ -1,5 +1,5 @@
1
1
  import { n as siteConfig, s as projectUrl, u as tryReadCanopyJson } from "./site-BFaWfSVu.mjs";
2
- import { a as unwrap, i as requireTty, l as apiRequest, r as reportErrors } from "./ui-DLZNEen6.mjs";
2
+ import { a as unwrap, i as requireTty, l as apiRequest, r as reportErrors } from "./ui--atbZ-TM.mjs";
3
3
  import { defineCommand } from "citty";
4
4
  import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
5
5
  import { join, relative, resolve, sep } from "node:path";
@@ -1,5 +1,5 @@
1
1
  import { c as resolveProject, o as projectFlagArgs } from "./site-BFaWfSVu.mjs";
2
- import { d as withContext, l as apiRequest, r as reportErrors, t as formatDateTime } from "./ui-DLZNEen6.mjs";
2
+ import { d as withContext, l as apiRequest, r as reportErrors, t as formatDateTime } from "./ui--atbZ-TM.mjs";
3
3
  import { defineCommand } from "citty";
4
4
  //#region src/schedule.ts
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { t as version } from "./package-x-_qF58q.mjs";
2
- import { r as reportErrors } from "./ui-DLZNEen6.mjs";
1
+ import { t as version } from "./package-B-aXVcQu.mjs";
2
+ import { r as reportErrors } from "./ui--atbZ-TM.mjs";
3
3
  import { defineCommand } from "citty";
4
4
  import { cpSync, existsSync, mkdirSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
5
5
  import { homedir } from "node:os";
@@ -1,5 +1,5 @@
1
1
  import { c as resolveProject, l as stagingUrl, o as projectFlagArgs, s as projectUrl } from "./site-BFaWfSVu.mjs";
2
- import { a as unwrap, d as withContext, i as requireTty, l as apiRequest, r as reportErrors, t as formatDateTime } from "./ui-DLZNEen6.mjs";
2
+ import { a as unwrap, d as withContext, i as requireTty, l as apiRequest, r as reportErrors, t as formatDateTime } from "./ui--atbZ-TM.mjs";
3
3
  import { defineCommand } from "citty";
4
4
  import * as p from "@clack/prompts";
5
5
  //#region src/staging.ts
@@ -1,5 +1,5 @@
1
1
  import { a as projectDirArgs, c as resolveProject, o as projectFlagArgs } from "./site-BFaWfSVu.mjs";
2
- import { l as apiRequest, r as reportErrors, t as formatDateTime } from "./ui-DLZNEen6.mjs";
2
+ import { l as apiRequest, r as reportErrors, t as formatDateTime } from "./ui--atbZ-TM.mjs";
3
3
  import { defineCommand } from "citty";
4
4
  const tokenCommand = defineCommand({
5
5
  meta: {
@@ -82,6 +82,10 @@ const ERROR_COPY = {
82
82
  why: "the database rejected the restore while executing the SQL",
83
83
  fix: "Fix the SQL the server reported above, then retry. A snapshot (`canopy db snapshot`) first is safest."
84
84
  },
85
+ staging_provision_failed: {
86
+ why: "setting up the staging copy of the live database failed",
87
+ fix: "The detail above is the platform's own error. If it names a limit, retrying won't help — file it with `canopy feedback report`; otherwise retry in a moment."
88
+ },
85
89
  invalid_description: {
86
90
  why: "the description is invalid (at most 1000 characters)",
87
91
  fix: "Shorten the description to 1000 characters or fewer."
@@ -1,5 +1,5 @@
1
1
  import { t as PACKAGE_NAME } from "./version-check-CcsA1QjI.mjs";
2
- import { r as reportErrors } from "./ui-DLZNEen6.mjs";
2
+ import { r as reportErrors } from "./ui--atbZ-TM.mjs";
3
3
  import { defineCommand } from "citty";
4
4
  import { spawn } from "node:child_process";
5
5
  import { fileURLToPath } from "node:url";
@@ -112,7 +112,7 @@ const upgradeCommand = defineCommand({
112
112
  const spec = `${PACKAGE_NAME}@${args.version ?? "latest"}`;
113
113
  const command = pmCommand(pm);
114
114
  const cmd = installArgs(pm, spec);
115
- const { skillInstalled } = await import("./skill-CSFhZmBk.mjs");
115
+ const { skillInstalled } = await import("./skill-CqiSkac0.mjs");
116
116
  const { homedir } = await import("node:os");
117
117
  const refreshGlobal = skillInstalled(homedir());
118
118
  const refreshRepo = process.cwd() !== homedir() && skillInstalled(process.cwd());
@@ -1,5 +1,5 @@
1
1
  import { c as resolveProject, o as projectFlagArgs } from "./site-BFaWfSVu.mjs";
2
- import { d as withContext, l as apiRequest, r as reportErrors } from "./ui-DLZNEen6.mjs";
2
+ import { d as withContext, l as apiRequest, r as reportErrors } from "./ui--atbZ-TM.mjs";
3
3
  import { defineCommand } from "citty";
4
4
  //#region src/usage.ts
5
5
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mediamonks/canopy-cli",
3
- "version": "0.7.18",
3
+ "version": "0.7.20",
4
4
  "description": "Canopy CLI — create, develop and deploy Canopy projects.",
5
5
  "bin": {
6
6
  "canopy": "./dist/index.mjs"
@@ -26,10 +26,11 @@
26
26
  "devDependencies": {
27
27
  "@types/node": "^26.1.1",
28
28
  "typescript": "^7.0.2",
29
- "vite-plus": "0.2.5"
29
+ "vite-plus": "0.2.5",
30
+ "@mediamonks/canopy-pages": "0.0.0"
30
31
  },
31
32
  "scripts": {
32
- "build": "vp pack && node ./scripts/sync-templates.mjs",
33
+ "build": "pnpm --filter @mediamonks/canopy-pages run build && vp pack && node ./scripts/sync-templates.mjs",
33
34
  "dev": "vp pack --watch",
34
35
  "test": "vp test",
35
36
  "check": "vp check"
@@ -1,2 +0,0 @@
1
- import { t as devCommand } from "./dev-CjaomJ2D.mjs";
2
- export { devCommand };