@xdelivered/emberflow 0.2.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/bin/commands.ts +7 -3
  2. package/bin/init.test.ts +94 -0
  3. package/bin/init.ts +108 -2
  4. package/dist/bin/commands.d.ts +1 -0
  5. package/dist/bin/commands.js +6 -3
  6. package/dist/bin/init.d.ts +4 -0
  7. package/dist/bin/init.js +96 -2
  8. package/dist/server/agents/codexParse.js +31 -0
  9. package/dist/server/agents/detect.d.ts +18 -8
  10. package/dist/server/agents/detect.js +78 -13
  11. package/dist/server/agents/modelRejectionHint.js +1 -1
  12. package/dist/server/agents/prompt.d.ts +15 -1
  13. package/dist/server/agents/prompt.js +59 -37
  14. package/dist/server/agents/runManager.d.ts +23 -2
  15. package/dist/server/agents/runManager.js +36 -8
  16. package/dist/server/client.d.ts +1 -0
  17. package/dist/server/client.js +7 -2
  18. package/dist/server/index.js +208 -16
  19. package/dist/server/nodesPayload.d.ts +14 -1
  20. package/dist/server/nodesPayload.js +15 -2
  21. package/dist/server/projectMode.js +5 -2
  22. package/dist/server/runRegistry.d.ts +52 -1
  23. package/dist/server/runRegistry.js +170 -1
  24. package/dist/server/sourceNav.d.ts +77 -0
  25. package/dist/server/sourceNav.js +503 -0
  26. package/dist/server/subflowRunner.d.ts +48 -1
  27. package/dist/server/subflowRunner.js +34 -7
  28. package/dist/server/updateCheck.d.ts +68 -0
  29. package/dist/server/updateCheck.js +142 -0
  30. package/dist/src/engine/executor.js +4 -3
  31. package/dist/src/engine/registry.d.ts +27 -2
  32. package/dist/src/engine/registry.js +84 -2
  33. package/dist/src/nodes/index.d.ts +8 -2
  34. package/dist/src/nodes/index.js +7 -3
  35. package/dist/src/nodes/login.d.ts +3 -1
  36. package/dist/src/nodes/login.js +2 -2
  37. package/package.json +28 -7
  38. package/server/agentRoute.test.ts +20 -0
  39. package/server/agents/codexParse.test.ts +37 -0
  40. package/server/agents/codexParse.ts +34 -0
  41. package/server/agents/detect.test.ts +26 -7
  42. package/server/agents/detect.ts +82 -14
  43. package/server/agents/modelRejectionHint.ts +2 -1
  44. package/server/agents/prompt.test.ts +128 -0
  45. package/server/agents/prompt.ts +102 -3
  46. package/server/agents/runManager.test.ts +9 -0
  47. package/server/agents/runManager.ts +37 -7
  48. package/server/client.ts +10 -4
  49. package/server/index.ts +213 -15
  50. package/server/nodeRun.test.ts +189 -0
  51. package/server/nodesPayload.test.ts +38 -0
  52. package/server/nodesPayload.ts +28 -3
  53. package/server/projectMode.ts +5 -2
  54. package/server/runRegistry.ts +200 -3
  55. package/server/setupStatus.test.ts +3 -0
  56. package/server/sourceNav.test.ts +382 -0
  57. package/server/sourceNav.ts +644 -0
  58. package/server/sourceNavRoute.test.ts +163 -0
  59. package/server/stepDrill.test.ts +380 -0
  60. package/server/subflowRunner.ts +92 -11
  61. package/server/updateCheck.test.ts +209 -0
  62. package/server/updateCheck.ts +175 -0
  63. package/server/workflowTestRoute.test.ts +1 -1
  64. package/src/App.tsx +82 -2
  65. package/src/components/AgentConsole.tsx +7 -280
  66. package/src/components/AgentStream.test.tsx +88 -0
  67. package/src/components/AgentStream.tsx +303 -0
  68. package/src/components/CreateModal.tsx +43 -9
  69. package/src/components/Dock.tsx +1 -1
  70. package/src/components/EmptyState.test.tsx +49 -0
  71. package/src/components/EmptyState.tsx +61 -0
  72. package/src/components/EnvironmentDialog.tsx +4 -1
  73. package/src/components/EnvironmentPicker.tsx +8 -3
  74. package/src/components/EnvironmentsDialog.tsx +4 -1
  75. package/src/components/InfraPanel.tsx +30 -2
  76. package/src/components/InfrastructureDialog.test.tsx +97 -0
  77. package/src/components/InfrastructureDialog.tsx +111 -0
  78. package/src/components/Inspector.tsx +9 -26
  79. package/src/components/RunbookView.tsx +70 -6
  80. package/src/components/SettingsDialog.tsx +4 -59
  81. package/src/components/Sidebar.tsx +6 -26
  82. package/src/components/SourceNavigator.test.tsx +226 -0
  83. package/src/components/SourceNavigator.tsx +520 -0
  84. package/src/components/StatusBar.tsx +227 -26
  85. package/src/components/Toolbar.tsx +28 -16
  86. package/src/components/UpdateChip.test.tsx +31 -0
  87. package/src/components/WelcomeDialog.test.tsx +384 -13
  88. package/src/components/WelcomeDialog.tsx +996 -177
  89. package/src/engine/executor.ts +4 -3
  90. package/src/engine/registry.sourceRef.test.ts +112 -0
  91. package/src/engine/registry.ts +103 -2
  92. package/src/lib/guidedQuestions.test.ts +224 -0
  93. package/src/lib/guidedQuestions.ts +181 -0
  94. package/src/lib/runbookModel.ts +3 -3
  95. package/src/lib/runbookProjection.test.ts +43 -0
  96. package/src/lib/runbookProjection.ts +26 -6
  97. package/src/nodes/index.ts +10 -3
  98. package/src/nodes/login.ts +5 -2
  99. package/src/store/agentClient.ts +27 -8
  100. package/src/store/apiTree.ts +12 -0
  101. package/src/store/builderStore.test.ts +441 -99
  102. package/src/store/builderStore.ts +385 -314
  103. package/src/store/nodeMeta.ts +10 -2
  104. package/src/store/serverRunner.ts +56 -5
  105. package/src/store/setupClient.ts +7 -2
  106. package/src/store/sourceNavClient.ts +48 -0
  107. package/src/store/updateClient.ts +50 -0
  108. package/studio-dist/assets/index-BbzppDpt.js +65 -0
  109. package/studio-dist/assets/index-CLf6blcA.css +1 -0
  110. package/studio-dist/index.html +2 -2
  111. package/templates/skills/emberflow-basics/SKILL.md +29 -1
  112. package/templates/skills/emberflow-model-process/SKILL.md +92 -9
  113. package/templates/skills/emberflow-new-workflow/SKILL.md +8 -1
  114. package/templates/skills/emberflow-review-workflow/SKILL.md +64 -1
  115. package/studio-dist/assets/index-DNJwW-hM.css +0 -1
  116. package/studio-dist/assets/index-O26dKRjW.js +0 -65
@@ -0,0 +1 @@
1
+ @font-face{font-family:Inter Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2)format("woff2-variations");unicode-range:U+460-52F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Inter Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2)format("woff2-variations");unicode-range:U+301,U+400-45F,U+490-491,U+4B0-4B1,U+2116}@font-face{font-family:Inter Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2)format("woff2-variations");unicode-range:U+1F??}@font-face{font-family:Inter Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/inter-greek-wght-normal-CkhJZR-_.woff2)format("woff2-variations");unicode-range:U+370-377,U+37A-37F,U+384-38A,U+38C,U+38E-3A1,U+3A3-3FF}@font-face{font-family:Inter Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2)format("woff2-variations");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Inter Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2)format("woff2-variations");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inter Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/inter-latin-wght-normal-Dx4kXJAl.woff2)format("woff2-variations");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/ibm-plex-mono-cyrillic-ext-400-normal-xuaO2J-f.woff2)format("woff2"),url(/assets/ibm-plex-mono-cyrillic-ext-400-normal-DMdlQ8Kv.woff)format("woff");unicode-range:U+460-52F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/ibm-plex-mono-cyrillic-400-normal-BSMlKf0J.woff2)format("woff2"),url(/assets/ibm-plex-mono-cyrillic-400-normal-CEL4l2ZJ.woff)format("woff");unicode-range:U+301,U+400-45F,U+490-491,U+4B0-4B1,U+2116}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/ibm-plex-mono-vietnamese-400-normal-BulugwFq.woff2)format("woff2"),url(/assets/ibm-plex-mono-vietnamese-400-normal-DDuiU_S-.woff)format("woff");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/ibm-plex-mono-latin-ext-400-normal-BmRBH3aV.woff2)format("woff2"),url(/assets/ibm-plex-mono-latin-ext-400-normal-D3D2R8hC.woff)format("woff");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2)format("woff2"),url(/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff)format("woff");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/ibm-plex-mono-cyrillic-ext-500-normal-BqneJy0T.woff2)format("woff2"),url(/assets/ibm-plex-mono-cyrillic-ext-500-normal-BIfNGwUT.woff)format("woff");unicode-range:U+460-52F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/ibm-plex-mono-cyrillic-500-normal-Bq9vWWag.woff2)format("woff2"),url(/assets/ibm-plex-mono-cyrillic-500-normal-Ael50iVv.woff)format("woff");unicode-range:U+301,U+400-45F,U+490-491,U+4B0-4B1,U+2116}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/ibm-plex-mono-vietnamese-500-normal-DZ4AoWbu.woff2)format("woff2"),url(/assets/ibm-plex-mono-vietnamese-500-normal-C8zxqsMH.woff)format("woff");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/ibm-plex-mono-latin-ext-500-normal-CAhNIIs5.woff2)format("woff2"),url(/assets/ibm-plex-mono-latin-ext-500-normal-CZ70TYgx.woff)format("woff");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2)format("woff2"),url(/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff)format("woff");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@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-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction: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-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-ease:initial;--tw-content:"";--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-mono:"IBM Plex Mono", "SF Mono", ui-monospace, Menlo, monospace;--color-amber-500:oklch(76.9% .188 70.08);--color-yellow-500:oklch(79.5% .184 86.047);--color-emerald-500:oklch(69.6% .17 162.48);--color-teal-500:oklch(70.4% .14 182.503);--color-cyan-500:oklch(71.5% .143 215.221);--color-sky-500:oklch(68.5% .169 237.323);--color-violet-500:oklch(60.6% .25 292.717);--color-fuchsia-500:oklch(66.7% .295 322.15);--color-pink-500:oklch(65.6% .241 354.308);--color-rose-500:oklch(64.5% .246 16.439);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-xl:36rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-normal:0em;--tracking-wide:.025em;--tracking-wider:.05em;--tracking-widest:.1em;--leading-tight:1.25;--leading-snug:1.375;--leading-relaxed:1.625;--radius-xs:.125rem;--ease-out:cubic-bezier(0, 0, .2, 1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:"Inter Variable", "Inter", ui-sans-serif, system-ui, sans-serif;--default-mono-font-family:"IBM Plex Mono", "SF Mono", ui-monospace, Menlo, monospace}}@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,ui-sans-serif, system-ui, 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;-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{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}*{border-color:var(--border);outline-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){*{outline-color:color-mix(in oklab, var(--ring) 50%, transparent)}}body{background-color:var(--background);color:var(--foreground);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:Inter Variable,Inter,ui-sans-serif,system-ui,sans-serif;font-size:13px}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-thumb{background:#3f3f4680;border-radius:6px}::-webkit-scrollbar-track{background:0 0}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:0}.inset-x-0{inset-inline:0}.top-0{top:0}.top-1{top:var(--spacing)}.top-1\.5{top:calc(var(--spacing) * 1.5)}.top-1\/2{top:50%}.top-4{top:calc(var(--spacing) * 4)}.top-6{top:calc(var(--spacing) * 6)}.top-full{top:100%}.right-1{right:var(--spacing)}.right-1\.5{right:calc(var(--spacing) * 1.5)}.right-4{right:calc(var(--spacing) * 4)}.bottom-0{bottom:0}.left-0{left:0}.left-1\/2{left:50%}.z-10{z-index:10}.z-50{z-index:50}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.-mx-2\.5{margin-inline:calc(var(--spacing) * -2.5)}.mx-0\.5{margin-inline:calc(var(--spacing) * .5)}.mx-auto{margin-inline:auto}.my-0\.5{margin-block:calc(var(--spacing) * .5)}.my-1{margin-block:var(--spacing)}.-mt-1{margin-top:calc(var(--spacing) * -1)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-2\.5{margin-top:calc(var(--spacing) * 2.5)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-3\.5{margin-top:calc(var(--spacing) * 3.5)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-8{margin-top:calc(var(--spacing) * 8)}.mt-10{margin-top:calc(var(--spacing) * 10)}.mt-\[5px\]{margin-top:5px}.mt-\[7px\]{margin-top:7px}.mr-1{margin-right:var(--spacing)}.mr-1\.5{margin-right:calc(var(--spacing) * 1.5)}.mb-0\.5{margin-bottom:calc(var(--spacing) * .5)}.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-2\.5{margin-bottom:calc(var(--spacing) * 2.5)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.-ml-1\.5{margin-left:calc(var(--spacing) * -1.5)}.ml-0\.5{margin-left:calc(var(--spacing) * .5)}.ml-1{margin-left:var(--spacing)}.ml-1\.5{margin-left:calc(var(--spacing) * 1.5)}.ml-3{margin-left:calc(var(--spacing) * 3)}.ml-4{margin-left:calc(var(--spacing) * 4)}.ml-11{margin-left:calc(var(--spacing) * 11)}.ml-\[18px\]{margin-left:18px}.ml-\[54px\]{margin-left:54px}.ml-auto{margin-left:auto}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.size-1{width:var(--spacing);height:var(--spacing)}.size-1\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-2{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.size-2\.5{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}.size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.size-3\.5{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.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-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.size-11{width:calc(var(--spacing) * 11);height:calc(var(--spacing) * 11)}.size-\[5px\]{width:5px;height:5px}.size-\[9px\]{width:9px;height:9px}.h-0\.5{height:calc(var(--spacing) * .5)}.h-3{height:calc(var(--spacing) * 3)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-11{height:calc(var(--spacing) * 11)}.h-12{height:calc(var(--spacing) * 12)}.h-\[2px\]{height:2px}.h-\[24px\]{height:24px}.h-\[85vh\]{height:85vh}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-32{max-height:calc(var(--spacing) * 32)}.max-h-40{max-height:calc(var(--spacing) * 40)}.max-h-64{max-height:calc(var(--spacing) * 64)}.max-h-72{max-height:calc(var(--spacing) * 72)}.max-h-96{max-height:calc(var(--spacing) * 96)}.max-h-\[55vh\]{max-height:55vh}.max-h-\[65vh\]{max-height:65vh}.max-h-\[85vh\]{max-height:85vh}.min-h-0{min-height:0}.w-\(--radix-popover-trigger-width\){width:var(--radix-popover-trigger-width)}.w-3{width:calc(var(--spacing) * 3)}.w-6{width:calc(var(--spacing) * 6)}.w-9{width:calc(var(--spacing) * 9)}.w-10{width:calc(var(--spacing) * 10)}.w-11{width:calc(var(--spacing) * 11)}.w-14{width:calc(var(--spacing) * 14)}.w-20{width:calc(var(--spacing) * 20)}.w-24{width:calc(var(--spacing) * 24)}.w-28{width:calc(var(--spacing) * 28)}.w-36{width:calc(var(--spacing) * 36)}.w-40{width:calc(var(--spacing) * 40)}.w-44{width:calc(var(--spacing) * 44)}.w-64{width:calc(var(--spacing) * 64)}.w-72{width:calc(var(--spacing) * 72)}.w-96{width:calc(var(--spacing) * 96)}.w-\[26rem\]{width:26rem}.w-\[380px\]{width:380px}.w-fit{width:fit-content}.w-full{width:100%}.w-px{width:1px}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-28{max-width:calc(var(--spacing) * 28)}.max-w-36{max-width:calc(var(--spacing) * 36)}.max-w-40{max-width:calc(var(--spacing) * 40)}.max-w-44{max-width:calc(var(--spacing) * 44)}.max-w-72{max-width:calc(var(--spacing) * 72)}.max-w-\[65ch\]{max-width:65ch}.max-w-\[80vw\]{max-width:80vw}.max-w-\[90\%\]{max-width:90%}.max-w-\[800px\]{max-width:800px}.max-w-\[calc\(100vw-2rem\)\]{max-width:calc(100vw - 2rem)}.max-w-full{max-width:100%}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.max-w-xl{max-width:var(--container-xl)}.min-w-0{min-width:0}.min-w-32{min-width:calc(var(--spacing) * 32)}.min-w-44{min-width:calc(var(--spacing) * 44)}.min-w-56{min-width:calc(var(--spacing) * 56)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-0{--tw-translate-x:0;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-full{--tw-translate-x:100%;translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-90{rotate:90deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-help{cursor:help}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.resize-y{resize:vertical}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-\[repeat\(auto-fill\,minmax\(240px\,1fr\)\)\]{grid-template-columns:repeat(auto-fill,minmax(240px,1fr))}.grid-cols-\[repeat\(auto-fit\,minmax\(280px\,1fr\)\)\]{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0{gap:0}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.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)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-3\.5{gap:calc(var(--spacing) * 3.5)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}:where(.space-y-0\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * .5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * .5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(var(--spacing) * var(--tw-space-y-reverse));margin-block-end:calc(var(--spacing) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-2{column-gap:calc(var(--spacing) * 2)}.gap-y-1{row-gap:var(--spacing)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-border>:not(:last-child)),:where(.divide-border\/50>:not(:last-child)){border-color:var(--border)}@supports (color:color-mix(in lab, red, red)){:where(.divide-border\/50>:not(:last-child)){border-color:color-mix(in oklab, var(--border) 50%, transparent)}}.self-center{align-self:center}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-\[3px\]{border-radius:3px}.rounded-\[4px\]{border-radius:4px}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.rounded-xl{border-radius:calc(var(--radius) + 4px)}.rounded-xs{border-radius:var(--radius-xs)}.rounded-l-none{border-top-left-radius:0;border-bottom-left-radius:0}.rounded-r-none{border-top-right-radius:0;border-bottom-right-radius:0}.rounded-br-sm{border-bottom-right-radius:calc(var(--radius) - 4px)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-\[1\.5px\]{border-left-style:var(--tw-border-style);border-left-width:1.5px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-\[\#8fb8d8\]\/40{border-color:oklab(76.4209% -.0297927 -.056321/.4)}.border-black\/20{border-color:#0003}@supports (color:color-mix(in lab, red, red)){.border-black\/20{border-color:color-mix(in oklab, var(--color-black) 20%, transparent)}}.border-border,.border-border\/35{border-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.border-border\/35{border-color:color-mix(in oklab, var(--border) 35%, transparent)}}.border-border\/50{border-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.border-border\/50{border-color:color-mix(in oklab, var(--border) 50%, transparent)}}.border-border\/60{border-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.border-border\/60{border-color:color-mix(in oklab, var(--border) 60%, transparent)}}.border-border\/70{border-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.border-border\/70{border-color:color-mix(in oklab, var(--border) 70%, transparent)}}.border-destructive,.border-destructive\/40{border-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.border-destructive\/40{border-color:color-mix(in oklab, var(--destructive) 40%, transparent)}}.border-destructive\/50{border-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.border-destructive\/50{border-color:color-mix(in oklab, var(--destructive) 50%, transparent)}}.border-highlight,.border-highlight\/30{border-color:var(--highlight)}@supports (color:color-mix(in lab, red, red)){.border-highlight\/30{border-color:color-mix(in oklab, var(--highlight) 30%, transparent)}}.border-highlight\/40{border-color:var(--highlight)}@supports (color:color-mix(in lab, red, red)){.border-highlight\/40{border-color:color-mix(in oklab, var(--highlight) 40%, transparent)}}.border-highlight\/60{border-color:var(--highlight)}@supports (color:color-mix(in lab, red, red)){.border-highlight\/60{border-color:color-mix(in oklab, var(--highlight) 60%, transparent)}}.border-input{border-color:var(--input)}.border-muted-foreground{border-color:var(--muted-foreground)}.border-ring{border-color:var(--ring)}.border-sidebar-border{border-color:var(--sidebar-border)}.border-success,.border-success\/40{border-color:var(--success)}@supports (color:color-mix(in lab, red, red)){.border-success\/40{border-color:color-mix(in oklab, var(--success) 40%, transparent)}}.border-transparent{border-color:#0000}.border-warn\/40{border-color:var(--warn)}@supports (color:color-mix(in lab, red, red)){.border-warn\/40{border-color:color-mix(in oklab, var(--warn) 40%, transparent)}}.bg-\[\#8fb8d8\]{background-color:#8fb8d8}.bg-background,.bg-background\/40{background-color:var(--background)}@supports (color:color-mix(in lab, red, red)){.bg-background\/40{background-color:color-mix(in oklab, var(--background) 40%, transparent)}}.bg-background\/50{background-color:var(--background)}@supports (color:color-mix(in lab, red, red)){.bg-background\/50{background-color:color-mix(in oklab, var(--background) 50%, transparent)}}.bg-background\/60{background-color:var(--background)}@supports (color:color-mix(in lab, red, red)){.bg-background\/60{background-color:color-mix(in oklab, var(--background) 60%, transparent)}}.bg-black\/15{background-color:#00000026}@supports (color:color-mix(in lab, red, red)){.bg-black\/15{background-color:color-mix(in oklab, var(--color-black) 15%, transparent)}}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab, red, red)){.bg-black\/60{background-color:color-mix(in oklab, var(--color-black) 60%, transparent)}}.bg-border,.bg-border\/70{background-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.bg-border\/70{background-color:color-mix(in oklab, var(--border) 70%, transparent)}}.bg-card,.bg-card\/50{background-color:var(--card)}@supports (color:color-mix(in lab, red, red)){.bg-card\/50{background-color:color-mix(in oklab, var(--card) 50%, transparent)}}.bg-card\/60{background-color:var(--card)}@supports (color:color-mix(in lab, red, red)){.bg-card\/60{background-color:color-mix(in oklab, var(--card) 60%, transparent)}}.bg-current{background-color:currentColor}.bg-destructive,.bg-destructive\/15{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.bg-destructive\/15{background-color:color-mix(in oklab, var(--destructive) 15%, transparent)}}.bg-destructive\/80{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.bg-destructive\/80{background-color:color-mix(in oklab, var(--destructive) 80%, transparent)}}.bg-highlight,.bg-highlight\/12{background-color:var(--highlight)}@supports (color:color-mix(in lab, red, red)){.bg-highlight\/12{background-color:color-mix(in oklab, var(--highlight) 12%, transparent)}}.bg-highlight\/15{background-color:var(--highlight)}@supports (color:color-mix(in lab, red, red)){.bg-highlight\/15{background-color:color-mix(in oklab, var(--highlight) 15%, transparent)}}.bg-highlight\/80{background-color:var(--highlight)}@supports (color:color-mix(in lab, red, red)){.bg-highlight\/80{background-color:color-mix(in oklab, var(--highlight) 80%, transparent)}}.bg-highlight\/\[0\.03\]{background-color:var(--highlight)}@supports (color:color-mix(in lab, red, red)){.bg-highlight\/\[0\.03\]{background-color:color-mix(in oklab, var(--highlight) 3%, transparent)}}.bg-highlight\/\[0\.06\]{background-color:var(--highlight)}@supports (color:color-mix(in lab, red, red)){.bg-highlight\/\[0\.06\]{background-color:color-mix(in oklab, var(--highlight) 6%, transparent)}}.bg-input\/30{background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.bg-input\/30{background-color:color-mix(in oklab, var(--input) 30%, transparent)}}.bg-muted-foreground,.bg-muted-foreground\/40{background-color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.bg-muted-foreground\/40{background-color:color-mix(in oklab, var(--muted-foreground) 40%, transparent)}}.bg-popover{background-color:var(--popover)}.bg-primary{background-color:var(--primary)}.bg-secondary,.bg-secondary\/40{background-color:var(--secondary)}@supports (color:color-mix(in lab, red, red)){.bg-secondary\/40{background-color:color-mix(in oklab, var(--secondary) 40%, transparent)}}.bg-secondary\/60{background-color:var(--secondary)}@supports (color:color-mix(in lab, red, red)){.bg-secondary\/60{background-color:color-mix(in oklab, var(--secondary) 60%, transparent)}}.bg-sidebar{background-color:var(--sidebar)}.bg-sidebar-accent{background-color:var(--sidebar-accent)}.bg-success,.bg-success\/15{background-color:var(--success)}@supports (color:color-mix(in lab, red, red)){.bg-success\/15{background-color:color-mix(in oklab, var(--success) 15%, transparent)}}.bg-success\/70{background-color:var(--success)}@supports (color:color-mix(in lab, red, red)){.bg-success\/70{background-color:color-mix(in oklab, var(--success) 70%, transparent)}}.bg-tertiary{background-color:var(--tertiary)}.bg-transparent{background-color:#0000}.bg-warn,.bg-warn\/15{background-color:var(--warn)}@supports (color:color-mix(in lab, red, red)){.bg-warn\/15{background-color:color-mix(in oklab, var(--warn) 15%, transparent)}}.bg-warn\/85{background-color:var(--warn)}@supports (color:color-mix(in lab, red, red)){.bg-warn\/85{background-color:color-mix(in oklab, var(--warn) 85%, transparent)}}.fill-current{fill:currentColor}.p-0{padding:0}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1{padding:var(--spacing)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-3\.5{padding:calc(var(--spacing) * 3.5)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-8{padding:calc(var(--spacing) * 8)}.px-0\.5{padding-inline:calc(var(--spacing) * .5)}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-5{padding-block:calc(var(--spacing) * 5)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-14{padding-block:calc(var(--spacing) * 14)}.py-px{padding-block:1px}.pt-0\.5{padding-top:calc(var(--spacing) * .5)}.pt-1{padding-top:var(--spacing)}.pt-1\.5{padding-top:calc(var(--spacing) * 1.5)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-2\.5{padding-top:calc(var(--spacing) * 2.5)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-6{padding-top:calc(var(--spacing) * 6)}.pt-\[26px\]{padding-top:26px}.pr-0\.5{padding-right:calc(var(--spacing) * .5)}.pr-1\.5{padding-right:calc(var(--spacing) * 1.5)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pr-2\.5{padding-right:calc(var(--spacing) * 2.5)}.pr-8{padding-right:calc(var(--spacing) * 8)}.pb-1{padding-bottom:var(--spacing)}.pb-1\.5{padding-bottom:calc(var(--spacing) * 1.5)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-\[140px\]{padding-bottom:140px}.pl-0\.5{padding-left:calc(var(--spacing) * .5)}.pl-1{padding-left:var(--spacing)}.pl-1\.5{padding-left:calc(var(--spacing) * 1.5)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-3{padding-left:calc(var(--spacing) * 3)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:IBM Plex Mono,SF Mono,ui-monospace,Menlo,monospace}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[7px\]{font-size:7px}.text-\[8\.5px\]{font-size:8.5px}.text-\[9\.5px\]{font-size:9.5px}.text-\[9px\]{font-size:9px}.text-\[10\.5px\]{font-size:10.5px}.text-\[10px\]{font-size:10px}.text-\[11\.5px\]{font-size:11.5px}.text-\[11px\]{font-size:11px}.text-\[12\.5px\]{font-size:12.5px}.text-\[12px\]{font-size:12px}.text-\[13\.5px\]{font-size:13.5px}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.text-\[15px\]{font-size:15px}.text-\[22px\]{font-size:22px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.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-normal{--tw-tracking:var(--tracking-normal);letter-spacing:var(--tracking-normal)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-words{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[\#8fb8d8\]{color:#8fb8d8}.text-amber-500{color:var(--color-amber-500)}.text-background{color:var(--background)}.text-black{color:var(--color-black)}.text-border{color:var(--border)}.text-cyan-500{color:var(--color-cyan-500)}.text-destructive{color:var(--destructive)}.text-destructive-foreground,.text-destructive-foreground\/80{color:var(--destructive-foreground)}@supports (color:color-mix(in lab, red, red)){.text-destructive-foreground\/80{color:color-mix(in oklab, var(--destructive-foreground) 80%, transparent)}}.text-destructive\/90{color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.text-destructive\/90{color:color-mix(in oklab, var(--destructive) 90%, transparent)}}.text-emerald-500{color:var(--color-emerald-500)}.text-foreground,.text-foreground\/70{color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.text-foreground\/70{color:color-mix(in oklab, var(--foreground) 70%, transparent)}}.text-foreground\/75{color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.text-foreground\/75{color:color-mix(in oklab, var(--foreground) 75%, transparent)}}.text-foreground\/80{color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.text-foreground\/80{color:color-mix(in oklab, var(--foreground) 80%, transparent)}}.text-foreground\/85{color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.text-foreground\/85{color:color-mix(in oklab, var(--foreground) 85%, transparent)}}.text-foreground\/90{color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.text-foreground\/90{color:color-mix(in oklab, var(--foreground) 90%, transparent)}}.text-fuchsia-500{color:var(--color-fuchsia-500)}.text-highlight{color:var(--highlight)}.text-highlight-foreground{color:var(--highlight-foreground)}.text-highlight\/60{color:var(--highlight)}@supports (color:color-mix(in lab, red, red)){.text-highlight\/60{color:color-mix(in oklab, var(--highlight) 60%, transparent)}}.text-highlight\/80{color:var(--highlight)}@supports (color:color-mix(in lab, red, red)){.text-highlight\/80{color:color-mix(in oklab, var(--highlight) 80%, transparent)}}.text-highlight\/90{color:var(--highlight)}@supports (color:color-mix(in lab, red, red)){.text-highlight\/90{color:color-mix(in oklab, var(--highlight) 90%, transparent)}}.text-muted-foreground,.text-muted-foreground\/30{color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.text-muted-foreground\/30{color:color-mix(in oklab, var(--muted-foreground) 30%, transparent)}}.text-muted-foreground\/45{color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.text-muted-foreground\/45{color:color-mix(in oklab, var(--muted-foreground) 45%, transparent)}}.text-muted-foreground\/50{color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.text-muted-foreground\/50{color:color-mix(in oklab, var(--muted-foreground) 50%, transparent)}}.text-muted-foreground\/60{color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.text-muted-foreground\/60{color:color-mix(in oklab, var(--muted-foreground) 60%, transparent)}}.text-muted-foreground\/70{color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.text-muted-foreground\/70{color:color-mix(in oklab, var(--muted-foreground) 70%, transparent)}}.text-muted-foreground\/75{color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.text-muted-foreground\/75{color:color-mix(in oklab, var(--muted-foreground) 75%, transparent)}}.text-muted-foreground\/80{color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.text-muted-foreground\/80{color:color-mix(in oklab, var(--muted-foreground) 80%, transparent)}}.text-pink-500{color:var(--color-pink-500)}.text-popover-foreground{color:var(--popover-foreground)}.text-primary-foreground{color:var(--primary-foreground)}.text-rose-500{color:var(--color-rose-500)}.text-secondary-foreground{color:var(--secondary-foreground)}.text-sidebar-accent-foreground{color:var(--sidebar-accent-foreground)}.text-sky-500{color:var(--color-sky-500)}.text-success,.text-success\/70{color:var(--success)}@supports (color:color-mix(in lab, red, red)){.text-success\/70{color:color-mix(in oklab, var(--success) 70%, transparent)}}.text-success\/80{color:var(--success)}@supports (color:color-mix(in lab, red, red)){.text-success\/80{color:color-mix(in oklab, var(--success) 80%, transparent)}}.text-teal-500{color:var(--color-teal-500)}.text-violet-500{color:var(--color-violet-500)}.text-warn{color:var(--warn)}.text-white{color:var(--color-white)}.text-yellow-500{color:var(--color-yellow-500)}.capitalize{text-transform:capitalize}.lowercase{text-transform:lowercase}.normal-case{text-transform:none}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.underline{text-decoration-line:underline}.decoration-dotted{text-decoration-style:dotted}.underline-offset-2{text-underline-offset:2px}.underline-offset-4{text-underline-offset:4px}.accent-\(--highlight\){accent-color:var(--highlight)}.opacity-0{opacity:0}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.opacity-55{opacity:.55}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-80{opacity:.8}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_18px_48px_rgb\(0_0_0\/0\.55\)\]{--tw-shadow:0 18px 48px var(--tw-shadow-color,#0000008c);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-highlight{--tw-ring-color:var(--highlight)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.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))}.transition-\[width\,opacity\]{transition-property:width,opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-500{--tw-duration:.5s;transition-duration:.5s}.duration-\[400ms\]{--tw-duration:.4s;transition-duration:.4s}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.\!running{animation-play-state:running!important}.paused{animation-play-state:paused}.ring-inset{--tw-ring-inset:inset}.running{animation-play-state:running}.group-focus-within\:opacity-100:is(:where(.group):focus-within *){opacity:1}@media (hover:hover){.group-hover\:hidden:is(:where(.group):hover *){display:none}.group-hover\:inline:is(:where(.group):hover *){display:inline}.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.group-hover\/badge\:block:is(:where(.group\/badge):hover *){display:block}}.selection\:bg-highlight ::selection{background-color:var(--highlight)}.selection\:bg-highlight::selection{background-color:var(--highlight)}.selection\:text-highlight-foreground ::selection{color:var(--highlight-foreground)}.selection\:text-highlight-foreground::selection{color:var(--highlight-foreground)}.placeholder\:text-muted-foreground::placeholder,.placeholder\:text-muted-foreground\/50::placeholder{color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.placeholder\:text-muted-foreground\/50::placeholder{color:color-mix(in oklab, var(--muted-foreground) 50%, transparent)}}.placeholder\:text-muted-foreground\/60::placeholder{color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.placeholder\:text-muted-foreground\/60::placeholder{color:color-mix(in oklab, var(--muted-foreground) 60%, transparent)}}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:inset-y-0:after{content:var(--tw-content);inset-block:0}.after\:left-1\/2:after{content:var(--tw-content);left:50%}.after\:w-1\.5:after{content:var(--tw-content);width:calc(var(--spacing) * 1.5)}.after\:-translate-x-1\/2:after{content:var(--tw-content);--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}@media (hover:hover){.hover\:border-border:hover{border-color:var(--border)}.hover\:border-highlight\/40:hover{border-color:var(--highlight)}@supports (color:color-mix(in lab, red, red)){.hover\:border-highlight\/40:hover{border-color:color-mix(in oklab, var(--highlight) 40%, transparent)}}.hover\:border-highlight\/50:hover{border-color:var(--highlight)}@supports (color:color-mix(in lab, red, red)){.hover\:border-highlight\/50:hover{border-color:color-mix(in oklab, var(--highlight) 50%, transparent)}}.hover\:border-ring\/50:hover{border-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.hover\:border-ring\/50:hover{border-color:color-mix(in oklab, var(--ring) 50%, transparent)}}.hover\:bg-accent:hover{background-color:var(--accent)}.hover\:bg-card:hover{background-color:var(--card)}.hover\:bg-destructive\/10:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-destructive\/10:hover{background-color:color-mix(in oklab, var(--destructive) 10%, transparent)}}.hover\:bg-destructive\/25:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-destructive\/25:hover{background-color:color-mix(in oklab, var(--destructive) 25%, transparent)}}.hover\:bg-destructive\/90:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-destructive\/90:hover{background-color:color-mix(in oklab, var(--destructive) 90%, transparent)}}.hover\:bg-highlight\/5:hover{background-color:var(--highlight)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-highlight\/5:hover{background-color:color-mix(in oklab, var(--highlight) 5%, transparent)}}.hover\:bg-highlight\/90:hover{background-color:var(--highlight)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-highlight\/90:hover{background-color:color-mix(in oklab, var(--highlight) 90%, transparent)}}.hover\:bg-primary\/90:hover{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab, var(--primary) 90%, transparent)}}.hover\:bg-ring:hover{background-color:var(--ring)}.hover\:bg-secondary:hover,.hover\:bg-secondary\/40:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-secondary\/40:hover{background-color:color-mix(in oklab, var(--secondary) 40%, transparent)}}.hover\:bg-secondary\/50:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-secondary\/50:hover{background-color:color-mix(in oklab, var(--secondary) 50%, transparent)}}.hover\:bg-secondary\/60:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-secondary\/60:hover{background-color:color-mix(in oklab, var(--secondary) 60%, transparent)}}.hover\:bg-secondary\/80:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-secondary\/80:hover{background-color:color-mix(in oklab, var(--secondary) 80%, transparent)}}.hover\:bg-sidebar-accent\/60:hover{background-color:var(--sidebar-accent)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-sidebar-accent\/60:hover{background-color:color-mix(in oklab, var(--sidebar-accent) 60%, transparent)}}.hover\:bg-warn:hover,.hover\:bg-warn\/10:hover{background-color:var(--warn)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-warn\/10:hover{background-color:color-mix(in oklab, var(--warn) 10%, transparent)}}.hover\:bg-warn\/25:hover{background-color:var(--warn)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-warn\/25:hover{background-color:color-mix(in oklab, var(--warn) 25%, transparent)}}.hover\:text-accent-foreground:hover{color:var(--accent-foreground)}.hover\:text-destructive:hover{color:var(--destructive)}.hover\:text-foreground:hover{color:var(--foreground)}.hover\:text-highlight:hover{color:var(--highlight)}.hover\:underline:hover{text-decoration-line:underline}.hover\:decoration-solid:hover{text-decoration-style:solid}.hover\:opacity-100:hover{opacity:1}}.focus\:border-ring:focus{border-color:var(--ring)}.focus\:text-foreground:focus{color:var(--foreground)}.focus-visible\:border-ring:focus-visible{border-color:var(--ring)}.focus-visible\:opacity-100:focus-visible{opacity:1}.focus-visible\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-\[3px\]:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-ring:focus-visible,.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:cursor-wait:disabled{cursor:wait}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:opacity-60:disabled{opacity:.6}.data-\[disabled\=true\]\:pointer-events-none[data-disabled=true]{pointer-events:none}.data-\[disabled\=true\]\:opacity-50[data-disabled=true]{opacity:.5}.data-\[panel-group-direction\=vertical\]\:h-px[data-panel-group-direction=vertical]{height:1px}.data-\[panel-group-direction\=vertical\]\:w-full[data-panel-group-direction=vertical]{width:100%}.data-\[panel-group-direction\=vertical\]\:flex-col[data-panel-group-direction=vertical]{flex-direction:column}.data-\[panel-group-direction\=vertical\]\:after\:top-1\/2[data-panel-group-direction=vertical]:after{content:var(--tw-content);top:50%}.data-\[panel-group-direction\=vertical\]\:after\:left-0[data-panel-group-direction=vertical]:after{content:var(--tw-content);left:0}.data-\[panel-group-direction\=vertical\]\:after\:h-1\.5[data-panel-group-direction=vertical]:after{content:var(--tw-content);height:calc(var(--spacing) * 1.5)}.data-\[panel-group-direction\=vertical\]\:after\:w-full[data-panel-group-direction=vertical]:after{content:var(--tw-content);width:100%}.data-\[panel-group-direction\=vertical\]\:after\:translate-x-0[data-panel-group-direction=vertical]:after{content:var(--tw-content);--tw-translate-x:0;translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[panel-group-direction\=vertical\]\:after\:-translate-y-1\/2[data-panel-group-direction=vertical]:after{content:var(--tw-content);--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[resize-handle-state\=drag\]\:bg-highlight[data-resize-handle-state=drag]{background-color:var(--highlight)}.data-\[selected\=true\]\:bg-accent[data-selected=true]{background-color:var(--accent)}.data-\[selected\=true\]\:text-accent-foreground[data-selected=true]{color:var(--accent-foreground)}.data-\[state\=active\]\:border-highlight[data-state=active]{border-color:var(--highlight)}.data-\[state\=active\]\:text-foreground[data-state=active]{color:var(--foreground)}.data-\[state\=closed\]\:animate-out[data-state=closed]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-\[state\=closed\]\:fade-out-0[data-state=closed]{--tw-exit-opacity:0}.data-\[state\=closed\]\:zoom-out-95[data-state=closed]{--tw-exit-scale:.95}.data-\[state\=open\]\:animate-in[data-state=open]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-\[state\=open\]\:opacity-100[data-state=open]{opacity:1}.data-\[state\=open\]\:fade-in-0[data-state=open]{--tw-enter-opacity:0}.data-\[state\=open\]\:zoom-in-95[data-state=open]{--tw-enter-scale:.95}@media (prefers-reduced-motion:no-preference){.motion-safe\:animate-pulse{animation:var(--animate-pulse)}}@media (prefers-reduced-motion:reduce){.motion-reduce\:animate-none{animation:none}.motion-reduce\:transition-none{transition-property:none}}@media (width>=40rem){.sm\:inline{display:inline}}@media (width>=48rem){.md\:grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,1\.15fr\)\]{grid-template-columns:minmax(0,1fr) minmax(0,1.15fr)}}.\[\&_\[cmdk-group-heading\]\]\:px-2 [cmdk-group-heading]{padding-inline:calc(var(--spacing) * 2)}.\[\&_\[cmdk-group-heading\]\]\:py-1\.5 [cmdk-group-heading]{padding-block:calc(var(--spacing) * 1.5)}.\[\&_\[cmdk-group-heading\]\]\:text-\[10px\] [cmdk-group-heading]{font-size:10px}.\[\&_\[cmdk-group-heading\]\]\:font-medium [cmdk-group-heading]{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.\[\&_\[cmdk-group-heading\]\]\:tracking-wider [cmdk-group-heading]{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.\[\&_\[cmdk-group-heading\]\]\:text-muted-foreground [cmdk-group-heading]{color:var(--muted-foreground)}.\[\&_\[cmdk-group-heading\]\]\:uppercase [cmdk-group-heading]{text-transform:uppercase}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_svg\]\:text-muted-foreground svg{color:var(--muted-foreground)}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-3\.5 svg:not([class*=size-]){width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-4 svg:not([class*=size-]){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}}@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}:root{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark;--background:#151110;--foreground:#eae8e6;--card:#201e1c;--card-foreground:#eae8e6;--popover:#201e1c;--popover-foreground:#eae8e6;--primary:#eae8e6;--primary-foreground:#151110;--secondary:#2a2827;--secondary-foreground:#eae8e6;--muted:#2a2827;--muted-foreground:#a8a5a3;--accent:#2a2827;--accent-foreground:#eae8e6;--tertiary:#1a1716;--tertiary-active:#252220;--destructive:#c44;--destructive-foreground:#fcc;--border:#2a2827;--input:#2a2827;--ring:#3a3837;--radius:.625rem;--sidebar:#1a1716;--sidebar-foreground:#eae8e6;--sidebar-primary:#e07850;--sidebar-primary-foreground:#151110;--sidebar-accent:#252220;--sidebar-accent-foreground:#eae8e6;--sidebar-border:#2a2827;--sidebar-ring:#3a3837;--highlight:#e07850;--highlight-foreground:#151110;--success:#50a878;--warn:#d9a441}#root{height:100vh}.ember-step-active{animation:1.3s ease-in-out infinite ember-step-pulse}@keyframes ember-step-pulse{0%,to{box-shadow:0 0 0 1px #e0785099,0 0 6px #e0785059}50%{box-shadow:0 0 0 2px #e0785066,0 0 10px #e0785099}}@media (prefers-reduced-motion:reduce){.ember-step-active{animation:none;box-shadow:0 0 0 2px #e0785080,0 0 8px #e0785066}}[data-panel-group]:not(:has([data-resize-handle-state=drag]))>[data-panel]{transition:flex-grow .28s cubic-bezier(.22,1,.36,1)}@media (prefers-reduced-motion:reduce){[data-panel-group]>[data-panel]{transition:none}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@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-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{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-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0));filter:blur(var(--tw-enter-blur,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0));filter:blur(var(--tw-exit-blur,0))}}
@@ -5,8 +5,8 @@
5
5
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>Emberflow</title>
8
- <script type="module" crossorigin src="/assets/index-O26dKRjW.js"></script>
9
- <link rel="stylesheet" crossorigin href="/assets/index-DNJwW-hM.css">
8
+ <script type="module" crossorigin src="/assets/index-BbzppDpt.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-CLf6blcA.css">
10
10
  </head>
11
11
  <body>
12
12
  <div id="root"></div>
@@ -2,7 +2,7 @@
2
2
  name: emberflow-basics
3
3
  description: Use whenever working with Emberflow in this project — running the studio, understanding the file layout, adding or editing API operations and scenarios, registering custom nodes, or using the CLI/MCP. The foundation the other emberflow-* skills build on. Trigger on "emberflow", "workflow builder", "operation", "api", "flow", "run a scenario", "emberflow dev".
4
4
  metadata:
5
- version: 2.7.0
5
+ version: 2.8.0
6
6
  ---
7
7
 
8
8
  # Emberflow basics
@@ -101,6 +101,34 @@ export default defineConfig({
101
101
  clear error naming the missing key. Fake success is worse than failure;
102
102
  `doctor` flags simulated commit paths as `simulated-commit`.
103
103
 
104
+ ## Node source is executable documentation — keep it in ONE file
105
+
106
+ The studio shows each node's implementation as source, and can navigate into
107
+ project files the implementation imports. That works because Emberflow records
108
+ where each node was registered and resolves ordinary ESM/TS imports. Keep it
109
+ inspectable:
110
+
111
+ - **When YOU author node logic, it lives in ONE module** — the file the
112
+ `registry.register(...)` call sits in. Helpers are named functions in that
113
+ SAME file, above or below the registrations; the studio's file view shows
114
+ them all together. Do NOT spread newly-authored node logic across multiple
115
+ files: every extra hop is a place a reader can get lost, and a file split
116
+ buys nothing the single-file view doesn't already give.
117
+ - **Existing project code is different.** When a node wraps logic the project
118
+ already owns (a `src/pricing.ts` the app also uses), IMPORT it normally —
119
+ never copy or inline it. The studio resolves the import and navigates to it.
120
+ Ordinary relative imports and tsconfig path aliases resolve automatically;
121
+ you do not maintain any reference list.
122
+ - **Never inline logic merely to satisfy the inspector.** The rule is "one
123
+ file for NEW node logic", not "no imports".
124
+ - A registration whose implementation is generated at runtime (a factory, a
125
+ wrapper) can pass an explicit source location:
126
+ `registry.register(def, impl, { sourceRef: { file: 'src/factory.ts', line: 12 } })`.
127
+ - **A thin adapter is not an implementation.** If the displayed handler just
128
+ calls `computeX(ctx.input)` and `computeX` can't be resolved to source, the
129
+ node is NOT adequately inspectable — fix the import so it resolves, or move
130
+ the logic into the registering file.
131
+
104
132
  ## Operation file shape
105
133
 
106
134
  ```json
@@ -2,7 +2,7 @@
2
2
  name: emberflow-model-process
3
3
  description: Use when modeling or MIGRATING EXISTING functionality into Emberflow — a single process (script, controller, job, runbook) as one operation, or a whole subsystem (a worker, a pipeline, a service's job handlers) as an API of operations. Emphasises verbatim porting, branch fidelity, determinism, and (at subsystem scale) decomposition and seam verification. For designing something brand-new, use emberflow-new-workflow instead.
4
4
  metadata:
5
- version: 2.7.0
5
+ version: 2.9.0
6
6
  ---
7
7
 
8
8
  # Modeling an existing process as an Emberflow operation
@@ -14,6 +14,12 @@ documentation of the system. Sections 1–6 govern each individual port; when
14
14
  the source is a whole subsystem spanning several operations, ALSO apply
15
15
  **At subsystem scale** at the end.
16
16
 
17
+ **Fidelity means preserving behaviour and real execution boundaries, not
18
+ copying the source's file, class, helper-function, or implementation-task
19
+ boundaries into the canvas.** The visible graph tells the domain process in the
20
+ language of its intended readers; existing functions sit underneath those
21
+ domain steps as their implementations.
22
+
17
23
  If the process is (or is triggered by) an HTTP endpoint, model it as an HTTP
18
24
  operation: create `emberflow/apis/<api>/<folder…>/<name>.json` with `id` equal to
19
25
  that path (`emberflow/apis/billing/charge.json` → `"billing/charge"`), add the
@@ -54,9 +60,30 @@ secret NAMES instead of re-deriving infrastructure the manifest already names.
54
60
  4. **Scenarios.** "Beyond one scenario per branch of the source, which
55
61
  specific cases do you want named and asserted?" (A known incident, a
56
62
  particular account shape, the case that motivated the port.)
63
+ 5. **Domain read-through.** "Who must be able to read this flow, and which
64
+ decisions or conclusions must they be able to explain from the canvas?"
65
+ Skip the question when the user has already named the audience and the
66
+ domain questions. Record those terms verbatim; they become node and branch
67
+ labels rather than names copied from helper functions.
57
68
 
58
69
  Confirm the summary before porting. The answers feed sections 4–6.
59
70
 
71
+ ### Process-model proposal — required before implementation
72
+
73
+ Present one compact proposal before authoring operation files. It contains:
74
+
75
+ 1. The process trigger and outcome in one sentence.
76
+ 2. The intended reader and what they must be able to explain from the canvas.
77
+ 3. Each proposed operation boundary and the real trigger, durability, retry, or
78
+ lifecycle reason that justifies it.
79
+ 4. The visible read-through in domain language, including meaningful decisions
80
+ and intermediate conclusions.
81
+ 5. How existing source functions map underneath those visible steps, plus any
82
+ genuinely opaque dependency or deliberate divergence.
83
+
84
+ Get the user's approval when working interactively. Route names, file lists,
85
+ helper names, or implementation tasks are not a substitute for this proposal.
86
+
60
87
  ## 1. Read the source first, fully
61
88
 
62
89
  Find and read the actual implementation — the script, controller, job, or written
@@ -68,6 +95,13 @@ runbook. Identify:
68
95
  - **The side effects** — DB writes, external POSTs, emails, queue sends. These
69
96
  become custom nodes marked `effects: 'mutation'`.
70
97
  - **The inputs and external data sources** it reads.
98
+ - **The domain story** — trigger, meaningful actions and decisions, and the
99
+ outcome the intended reader cares about. Keep this separate from source helper
100
+ calls, modules, controllers, repositories, and technical layers.
101
+ - **The real process boundaries** — independently triggered HTTP/queue/cron
102
+ handlers, durable hand-offs, separate lifecycles, and independently invoked
103
+ reusable domain processes. A function call or file boundary alone is not a
104
+ process boundary.
71
105
 
72
106
  Do not skim. A faithful model requires knowing what the code actually does,
73
107
  including the edge cases.
@@ -94,17 +128,41 @@ stale constants are findings worth reporting — not things to tidy away.
94
128
 
95
129
  ## 4. Map the shape onto Emberflow
96
130
 
131
+ Before choosing files or operation ids, write the visible domain read-through
132
+ as `trigger → domain action/decision → outcome`. A person in the audience
133
+ named during intake must be able to follow that sequence from node and branch
134
+ labels without opening the node implementations. Then map the existing source
135
+ underneath it:
136
+
97
137
  - Request in → an `Input` node reading `{ params, query, body, headers }` (for an
98
138
  HTTP op); response out → a `Response` node `{ status, body }` per real exit,
99
139
  matching the source's status codes (internal flow → `Result`).
100
- - Linear steps → a chain of nodes with `inputMap` + edges.
140
+ - Domain-meaningful linear steps → a chain of nodes with `inputMap` + edges.
141
+ A node may call one existing function or coordinate several helpers; its
142
+ boundary is the result the intended reader needs to inspect, not the number of
143
+ functions involved.
101
144
  - Decisions → `Conditional` (ordered rules) or `Route` (switch on a field), one
102
145
  branch per real code path, including the else/default. A branch that returns a
103
146
  different HTTP status gets its own `Response`.
104
147
  - Loops over collections → `ForEach`/`Collect`.
105
- - Sub-procedures the source factors outa `Subflow` node calling a separate
106
- operation (mirror the real call structure if `handleA()` calls `handleB()`,
107
- operation A calls operation B).
148
+ - Existing helper functions and technical layers implementation code beneath
149
+ the relevant domain node. Promote a helper to its own visible node when it
150
+ produces a meaningful intermediate domain result, owns an infrastructure
151
+ or effect boundary, or needs distinct retry/inspection behaviour.
152
+ - **Port by importing, never by copying.** A node implementation that wraps
153
+ existing source IMPORTS it from where it lives — the studio resolves the
154
+ import and navigates to the real code, so the port stays verbatim and the
155
+ source of truth stays single. Copying helper bodies into the registering
156
+ file forks them. New glue you write for the port (adapters, small
157
+ reshaping helpers) follows the one-file rule: it lives in the registering
158
+ module itself, not in new satellite files. After porting, open each node's
159
+ source in the studio: every project-owned reference must resolve —
160
+ an unresolved reference hiding ported business logic defeats the port's
161
+ documentation purpose (the review skill treats it as Important/Critical).
162
+ - A coherent in-process domain process that is repeated or independently
163
+ useful → a `Subflow` node calling a separate internal operation. Subflow
164
+ extraction must make the domain read-through clearer. Do not mirror a
165
+ helper call merely because the source factors it out.
108
166
  - Effects → `effects: 'mutation'` nodes that dry-run by default and only commit
109
167
  under an explicit opt-in. The commit path performs the REAL side effect the
110
168
  source performs — the same insert, the same webhook, the same send. A
@@ -123,6 +181,25 @@ a node's implementation in `registerNodes` before you reference its `type`; the
123
181
  runner rejects an unregistered type (a name with no implementation), but a type
124
182
  you register in the same change is exactly how you model the step.
125
183
 
184
+ ### Keep domain logic visible
185
+
186
+ A generic bridge such as `RunStage`, `ExecuteScript`, or `CallService` may be a
187
+ leaf implementation detail, but it is not a faithful visible model when it
188
+ contains several domain actions or decisions. A graph shaped only as
189
+ `Input → RunWholeStage → Result` documents plumbing, not the process.
190
+
191
+ For each bridge or broad adapter, inspect the source it invokes:
192
+
193
+ 1. Put each reader-relevant decision and intermediate conclusion on the
194
+ canvas as a specifically named node or branch.
195
+ 2. Keep formulas and constants in the existing implementation when duplicating
196
+ them would risk drift; call that implementation from the domain-named node.
197
+ 3. Expose the inputs, calculation basis, outcome, and provenance needed to
198
+ explain the result in the run trace.
199
+ 4. If the dependency is genuinely opaque and cannot yet be decomposed, label it
200
+ explicitly as an opaque external step and report the model as
201
+ `process-logic-opaque`; do not call it executable documentation.
202
+
126
203
  ## 5. Make it deterministic and reproducible
127
204
 
128
205
  Real processes read the clock, the DB, live data. For a faithful, testable model,
@@ -171,10 +248,13 @@ phases — and a wrongly-shaped mock masks every one of them.
171
248
  every constant in a table (that table becomes the fidelity checklist all
172
249
  reviews check against), external dependencies per phase, and the data
173
250
  shapes phases pass each other.
174
- - **One operation per process boundary.** A queue or cron hop in the source is
175
- an operation boundary in the model — do NOT collapse an async boundary into
176
- a synchronous `Subflow` (the fan-out op models the *send*; the per-job op is
177
- invoked separately). A sub-procedure called in-process IS a `Subflow`.
251
+ - **One operation per real process boundary.** A queue or cron hop in the source
252
+ is an operation boundary in the model — do NOT collapse an async boundary
253
+ into a synchronous `Subflow` (the fan-out op models the *send*; the per-job op
254
+ is invoked separately). Files, classes, helper functions, source-code phases,
255
+ implementation-plan tasks, and test seams are NOT operation boundaries. An
256
+ in-process helper normally stays beneath a node; use a `Subflow` only for a
257
+ coherent repeated or independently useful domain process.
178
258
  - **Inventory existing nodes before authoring new ones** — migrations often
179
259
  land where partial models already exist. Reuse and extend.
180
260
  - **Producers own their output contracts.** If a consumer needs rows, the
@@ -204,6 +284,9 @@ phases — and a wrongly-shaped mock masks every one of them.
204
284
  Someone who knows the original system should read the flow and recognise it
205
285
  exactly — same steps, same decisions, same constants, same effects — with every
206
286
  divergence explicitly marked. If they'd be surprised by a branch, you modeled it wrong.
287
+ The intended reader should also be able to explain from the canvas why the
288
+ process reached its conclusion. If they must open a generic bridge node or read
289
+ source helper names to discover the domain logic, the model is too opaque.
207
290
  For a subsystem migration the same bar holds system-wide, and both worlds must
208
291
  work: every scenario green in mock mode, and the real path proven or explicitly
209
292
  pending.
@@ -2,7 +2,7 @@
2
2
  name: emberflow-new-workflow
3
3
  description: Use when creating a BRAND-NEW Emberflow API operation from scratch (greenfield) — the user describes a goal or endpoint they want and no existing code models it yet. Guides choosing method + path, wiring Input → logic → Response, choosing built-in vs custom nodes, and covering branches with scenarios. For porting an EXISTING system, use emberflow-model-process instead.
4
4
  metadata:
5
- version: 2.5.0
5
+ version: 2.6.0
6
6
  ---
7
7
 
8
8
  # Building a new Emberflow operation (greenfield)
@@ -95,6 +95,13 @@ List the steps the endpoint takes, in order. Each becomes a node:
95
95
  (`'db'|'http'|'llm'`) on every node that touches infrastructure — mock mode
96
96
  uses it to know what to intercept. An unmarked infra node silently executes
97
97
  for real during mock runs.
98
+ - **Node logic lives in ONE file.** Everything you write for a node — its
99
+ implementation and any helpers — goes in the module the `registry.register`
100
+ call sits in, helpers as named functions in that same file. The studio shows
101
+ that whole file as the node's source, so a reader sees the complete story in
102
+ one place. Never spread newly-authored node logic across multiple files.
103
+ Code the project ALREADY owns is the exception: import it normally (never
104
+ copy it) — the studio resolves imports and navigates to them.
98
105
  - **Implementations are real.** A custom node's implementation calls the actual
99
106
  dependency (the real query, the real HTTP call, the real SDK) — never canned
100
107
  data pretending to be an implementation. Canned data belongs in the scenario
@@ -2,7 +2,7 @@
2
2
  name: emberflow-review-workflow
3
3
  description: Use to code-review an Emberflow API operation before it ships — after authoring or modeling one, or when asked to check/audit/review an existing operation. A rubric covering HTTP trigger + auth, wiring integrity, branch coverage, effects/safe-mode correctness, determinism, and readability. Reports findings by severity; does not rubber-stamp.
4
4
  metadata:
5
- version: 2.2.0
5
+ version: 2.4.0
6
6
  ---
7
7
 
8
8
  # Reviewing an Emberflow operation
@@ -107,6 +107,33 @@ serving, mocks for mock mode. Check both halves.
107
107
  are mock (canned), dry-run (`wouldSend`/`wouldWrite`), and real commit;
108
108
  missing credentials at commit time must THROW naming the secretRef, never
109
109
  succeed quietly. `doctor` reports these as `simulated-commit`.
110
+
111
+ ## 4c. Source inspectability
112
+
113
+ A node is executable documentation only if its displayed implementation shows
114
+ (or navigates to) the behaviour it delegates. Open each custom node's source
115
+ in the studio and check:
116
+
117
+ - **No unresolved project-owned references.** Every project function, constant
118
+ or class the implementation uses must resolve — either declared in the same
119
+ file or reachable through the studio's reference navigation (ordinary
120
+ imports resolve automatically). An unresolved project-owned reference that
121
+ hides a business decision, formula, classification, or side effect is
122
+ **Important** — **Critical** when the operation's documentation value
123
+ depends on it (a thin adapter presenting `computeX(ctx.input)` as if it
124
+ were the implementation, with `computeX` unreachable).
125
+ - **Newly-authored logic lives in ONE file.** Node logic written for this
126
+ operation belongs in the registering module — helpers as named functions in
127
+ the same file. New logic scattered across multiple new files is Important:
128
+ it fragments the readable story without buying anything. (Imports of code
129
+ the project ALREADY owned are correct and expected — that's what navigation
130
+ is for.)
131
+ - **Nobody inlined to appease the inspector.** Pre-existing shared code that
132
+ was copy-pasted into the registering file (instead of imported) is Important
133
+ — it forks the source of truth.
134
+ - Runtime-generated implementations (factories) must carry an explicit
135
+ `sourceRef` (third argument to `register`) — a generated function with no
136
+ navigable source is Important.
110
137
  - **Both modes verified.** Run the scenarios in mock mode; if an environment
111
138
  exists, run the real path too. Green in only one world is an unproven
112
139
  operation — Important.
@@ -128,6 +155,37 @@ serving, mocks for mock mode. Check both halves.
128
155
  - **Layout reads left-to-right, no overlaps** (auto-layout in the studio). Minor,
129
156
  but a jumbled graph hides wiring bugs.
130
157
 
158
+ ### Domain read-through (for modeled processes)
159
+
160
+ When an operation claims to model an existing process or serve as executable
161
+ documentation, read the source process and identify its audience before
162
+ approving it. The canvas itself must read as:
163
+
164
+ `trigger → reader-relevant actions/decisions → explained outcome`
165
+
166
+ - **Domain decisions are visible.** Decisions needed to explain the result
167
+ appear as domain-named nodes and `Conditional`/`Route` branches. Existing formulas
168
+ may remain in source functions called by those nodes; do not require copied
169
+ logic merely to make it visible.
170
+ - **Intermediate conclusions are inspectable.** Outputs carry the facts,
171
+ calculation basis, outcome, and provenance the named audience needs to
172
+ explain why the process reached its result.
173
+ - **The graph is not a generic bridge.** `Input → RunWholeStage → Result` is
174
+ Important when `RunWholeStage` hides several reader-relevant actions or
175
+ decisions. Report `process-logic-opaque` and name the hidden decisions.
176
+ - **The graph is not source/task decomposition.** Files, classes, helper
177
+ functions, source-code phases, implementation-plan tasks, and test seams do
178
+ not justify separate operations. Fragmentation that replaces the domain
179
+ read-through with technical stage names is Important.
180
+ - **Real process boundaries remain real.** Independently triggered HTTP,
181
+ queue, and cron handlers and durable hand-offs remain separate operations;
182
+ collapsing one into a synchronous `Subflow` is Critical when it changes
183
+ lifecycle, retry, or delivery semantics.
184
+
185
+ A typed proxy to a genuinely opaque external service is not required to expose
186
+ that service's unavailable internals. It must be described as a proxy or opaque
187
+ step, not as executable documentation of the external process.
188
+
131
189
  ## 7. Fidelity (for modeled processes)
132
190
 
133
191
  If the flow models existing code (see emberflow-model-process): spot-check the
@@ -135,6 +193,11 @@ ported constants/thresholds/branch-order against the source. A silently "cleaned
135
193
  up" constant or dropped branch is a Critical fidelity break. Documented
136
194
  `PORT NOTE:` divergences are fine; undocumented ones are findings.
137
195
 
196
+ Also compare operation and `Subflow` boundaries with the source's real trigger,
197
+ durability, retry, and lifecycle boundaries. Matching function/file structure
198
+ is not fidelity; preserving behaviour while making its domain explanation
199
+ visible is.
200
+
138
201
  ## Output format
139
202
 
140
203
  ```