@kaddo/cli 3.69.0 → 3.69.2
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.
- package/dist/admin-dist/assets/index-96WpHq9_.js +10 -0
- package/dist/admin-dist/assets/index-zcGzKcF4.css +2 -0
- package/dist/admin-dist/favicon.svg +1 -0
- package/dist/admin-dist/icons.svg +24 -0
- package/dist/admin-dist/index.html +14 -0
- package/dist/admin-server/index.js +448 -0
- package/dist/index.js +16 -1
- package/package.json +2 -2
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
|
|
2
|
+
@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-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-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-ease:initial}}}@layer theme{:root,:host{--font-sans:-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-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--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)}}@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;-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}}@layer components;@layer utilities{.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.border{border-style:var(--tw-border-style);border-width:1px}.font-mono{font-family:var(--font-mono)}.capitalize{text-transform:capitalize}.uppercase{text-transform:uppercase}.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))}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}}:root{--background:#fff;--surface:#f8f9fa;--surface-muted:#f1f3f5;--foreground:#1a1a2e;--foreground-muted:#6c757d;--border:#dee2e6;--border-strong:#adb5bd;--primary:#4361ee;--primary-foreground:#fff;--success:#2d9f5c;--warning:#e9a820;--danger:#dc3545;--info:#3b82f6;--finding-blocking:#dc3545;--finding-warning:#e9a820;--finding-fyi:#6c757d;--work-item-draft:#6c757d;--work-item-ready:#3b82f6;--work-item-progress:#8b5cf6;--work-item-blocked:#dc3545;--work-item-completed:#2d9f5c;--work-item-archived:#adb5bd;--knowledge-ready:#2d9f5c;--knowledge-missing:#dc3545;--knowledge-placeholder:#e9a820;--knowledge-unknown:#6c757d;--module-core:#4361ee;--module-module:#3b82f6;--module-unavailable:#dc3545;--readiness-ready:#2d9f5c;--readiness-warning:#e9a820;--readiness-blocked:#dc3545;--font-sans:"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;--font-mono:"JetBrains Mono", "Fira Code", "Cascadia Code", monospace;--radius:6px}@media (prefers-color-scheme:dark){:root:not([data-theme=light]){--background:#0f0f23;--surface:#1a1a2e;--surface-muted:#16213e;--foreground:#e8e8e8;--foreground-muted:#a0a0b0;--border:#2a2a3e;--border-strong:#4a4a5e;--primary:#6580f5;--primary-foreground:#fff;--success:#3cb371;--warning:#f0b840;--danger:#ef4444;--info:#60a5fa;--finding-blocking:#ef4444;--finding-warning:#f0b840;--finding-fyi:#a0a0b0;--work-item-draft:#a0a0b0;--work-item-ready:#60a5fa;--work-item-progress:#a78bfa;--work-item-blocked:#ef4444;--work-item-completed:#3cb371;--work-item-archived:#6a6a7e;--knowledge-ready:#3cb371;--knowledge-missing:#ef4444;--knowledge-placeholder:#f0b840;--knowledge-unknown:#a0a0b0;--module-core:#6580f5;--module-module:#60a5fa;--module-unavailable:#ef4444;--readiness-ready:#3cb371;--readiness-warning:#f0b840;--readiness-blocked:#ef4444}}:root[data-theme=dark]{--background:#0f0f23;--surface:#1a1a2e;--surface-muted:#16213e;--foreground:#e8e8e8;--foreground-muted:#a0a0b0;--border:#2a2a3e;--border-strong:#4a4a5e;--primary:#6580f5;--primary-foreground:#fff;--success:#3cb371;--warning:#f0b840;--danger:#ef4444;--info:#60a5fa;--finding-blocking:#ef4444;--finding-warning:#f0b840;--finding-fyi:#a0a0b0;--work-item-draft:#a0a0b0;--work-item-ready:#60a5fa;--work-item-progress:#a78bfa;--work-item-blocked:#ef4444;--work-item-completed:#3cb371;--work-item-archived:#6a6a7e;--knowledge-ready:#3cb371;--knowledge-missing:#ef4444;--knowledge-placeholder:#f0b840;--knowledge-unknown:#a0a0b0;--module-core:#6580f5;--module-module:#60a5fa;--module-unavailable:#ef4444;--readiness-ready:#3cb371;--readiness-warning:#f0b840;--readiness-blocked:#ef4444}body{font-family:var(--font-sans);background:var(--background);color:var(--foreground);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;margin:0}code,.font-mono{font-family:var(--font-mono)}@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-border-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-ease{syntax:"*";inherits:false}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="46" fill="none" viewBox="0 0 48 46"><path fill="#863bff" d="M25.946 44.938c-.664.845-2.021.375-2.021-.698V33.937a2.26 2.26 0 0 0-2.262-2.262H10.287c-.92 0-1.456-1.04-.92-1.788l7.48-10.471c1.07-1.497 0-3.578-1.842-3.578H1.237c-.92 0-1.456-1.04-.92-1.788L10.013.474c.214-.297.556-.474.92-.474h28.894c.92 0 1.456 1.04.92 1.788l-7.48 10.471c-1.07 1.498 0 3.579 1.842 3.579h11.377c.943 0 1.473 1.088.89 1.83L25.947 44.94z" style="fill:#863bff;fill:color(display-p3 .5252 .23 1);fill-opacity:1"/><mask id="a" width="48" height="46" x="0" y="0" maskUnits="userSpaceOnUse" style="mask-type:alpha"><path fill="#000" d="M25.842 44.938c-.664.844-2.021.375-2.021-.698V33.937a2.26 2.26 0 0 0-2.262-2.262H10.183c-.92 0-1.456-1.04-.92-1.788l7.48-10.471c1.07-1.498 0-3.579-1.842-3.579H1.133c-.92 0-1.456-1.04-.92-1.787L9.91.473c.214-.297.556-.474.92-.474h28.894c.92 0 1.456 1.04.92 1.788l-7.48 10.471c-1.07 1.498 0 3.578 1.842 3.578h11.377c.943 0 1.473 1.088.89 1.832L25.843 44.94z" style="fill:#000;fill-opacity:1"/></mask><g mask="url(#a)"><g filter="url(#b)"><ellipse cx="5.508" cy="14.704" fill="#ede6ff" rx="5.508" ry="14.704" style="fill:#ede6ff;fill:color(display-p3 .9275 .9033 1);fill-opacity:1" transform="matrix(.00324 1 1 -.00324 -4.47 31.516)"/></g><g filter="url(#c)"><ellipse cx="10.399" cy="29.851" fill="#ede6ff" rx="10.399" ry="29.851" style="fill:#ede6ff;fill:color(display-p3 .9275 .9033 1);fill-opacity:1" transform="matrix(.00324 1 1 -.00324 -39.328 7.883)"/></g><g filter="url(#d)"><ellipse cx="5.508" cy="30.487" fill="#7e14ff" rx="5.508" ry="30.487" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.814 -25.913 -14.639)scale(1 -1)"/></g><g filter="url(#e)"><ellipse cx="5.508" cy="30.599" fill="#7e14ff" rx="5.508" ry="30.599" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.814 -32.644 -3.334)scale(1 -1)"/></g><g filter="url(#f)"><ellipse cx="5.508" cy="30.599" fill="#7e14ff" rx="5.508" ry="30.599" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="matrix(.00324 1 1 -.00324 -34.34 30.47)"/></g><g filter="url(#g)"><ellipse cx="14.072" cy="22.078" fill="#ede6ff" rx="14.072" ry="22.078" style="fill:#ede6ff;fill:color(display-p3 .9275 .9033 1);fill-opacity:1" transform="rotate(93.35 24.506 48.493)scale(-1 1)"/></g><g filter="url(#h)"><ellipse cx="3.47" cy="21.501" fill="#7e14ff" rx="3.47" ry="21.501" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.009 28.708 47.59)scale(-1 1)"/></g><g filter="url(#i)"><ellipse cx="3.47" cy="21.501" fill="#7e14ff" rx="3.47" ry="21.501" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(89.009 28.708 47.59)scale(-1 1)"/></g><g filter="url(#j)"><ellipse cx=".387" cy="8.972" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(39.51 .387 8.972)"/></g><g filter="url(#k)"><ellipse cx="47.523" cy="-6.092" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 47.523 -6.092)"/></g><g filter="url(#l)"><ellipse cx="41.412" cy="6.333" fill="#47bfff" rx="5.971" ry="9.665" style="fill:#47bfff;fill:color(display-p3 .2799 .748 1);fill-opacity:1" transform="rotate(37.892 41.412 6.333)"/></g><g filter="url(#m)"><ellipse cx="-1.879" cy="38.332" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 -1.88 38.332)"/></g><g filter="url(#n)"><ellipse cx="-1.879" cy="38.332" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 -1.88 38.332)"/></g><g filter="url(#o)"><ellipse cx="35.651" cy="29.907" fill="#7e14ff" rx="4.407" ry="29.108" style="fill:#7e14ff;fill:color(display-p3 .4922 .0767 1);fill-opacity:1" transform="rotate(37.892 35.651 29.907)"/></g><g filter="url(#p)"><ellipse cx="38.418" cy="32.4" fill="#47bfff" rx="5.971" ry="15.297" style="fill:#47bfff;fill:color(display-p3 .2799 .748 1);fill-opacity:1" transform="rotate(37.892 38.418 32.4)"/></g></g><defs><filter id="b" width="60.045" height="41.654" x="-19.77" y="16.149" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="7.659"/></filter><filter id="c" width="90.34" height="51.437" x="-54.613" y="-7.533" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="7.659"/></filter><filter id="d" width="79.355" height="29.4" x="-49.64" y="2.03" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="e" width="79.579" height="29.4" x="-45.045" y="20.029" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="f" width="79.579" height="29.4" x="-43.513" y="21.178" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="g" width="74.749" height="58.852" x="15.756" y="-17.901" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="7.659"/></filter><filter id="h" width="61.377" height="25.362" x="23.548" y="2.284" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="i" width="61.377" height="25.362" x="23.548" y="2.284" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="j" width="56.045" height="63.649" x="-27.636" y="-22.853" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="k" width="54.814" height="64.646" x="20.116" y="-38.415" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="l" width="33.541" height="35.313" x="24.641" y="-11.323" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="m" width="54.814" height="64.646" x="-29.286" y="6.009" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="n" width="54.814" height="64.646" x="-29.286" y="6.009" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="o" width="54.814" height="64.646" x="8.244" y="-2.416" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter><filter id="p" width="39.409" height="43.623" x="18.713" y="10.588" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_2002_17158" stdDeviation="4.596"/></filter></defs></svg>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<symbol id="bluesky-icon" viewBox="0 0 16 17">
|
|
3
|
+
<g clip-path="url(#bluesky-clip)"><path fill="#08060d" d="M7.75 7.735c-.693-1.348-2.58-3.86-4.334-5.097-1.68-1.187-2.32-.981-2.74-.79C.188 2.065.1 2.812.1 3.251s.241 3.602.398 4.13c.52 1.744 2.367 2.333 4.07 2.145-2.495.37-4.71 1.278-1.805 4.512 3.196 3.309 4.38-.71 4.987-2.746.608 2.036 1.307 5.91 4.93 2.746 2.72-2.746.747-4.143-1.747-4.512 1.702.189 3.55-.4 4.07-2.145.156-.528.397-3.691.397-4.13s-.088-1.186-.575-1.406c-.42-.19-1.06-.395-2.741.79-1.755 1.24-3.64 3.752-4.334 5.099"/></g>
|
|
4
|
+
<defs><clipPath id="bluesky-clip"><path fill="#fff" d="M.1.85h15.3v15.3H.1z"/></clipPath></defs>
|
|
5
|
+
</symbol>
|
|
6
|
+
<symbol id="discord-icon" viewBox="0 0 20 19">
|
|
7
|
+
<path fill="#08060d" d="M16.224 3.768a14.5 14.5 0 0 0-3.67-1.153c-.158.286-.343.67-.47.976a13.5 13.5 0 0 0-4.067 0c-.128-.306-.317-.69-.476-.976A14.4 14.4 0 0 0 3.868 3.77C1.546 7.28.916 10.703 1.231 14.077a14.7 14.7 0 0 0 4.5 2.306q.545-.748.965-1.587a9.5 9.5 0 0 1-1.518-.74q.191-.14.372-.293c2.927 1.369 6.107 1.369 8.999 0q.183.152.372.294-.723.437-1.52.74.418.838.963 1.588a14.6 14.6 0 0 0 4.504-2.308c.37-3.911-.63-7.302-2.644-10.309m-9.13 8.234c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.894 0 1.614.82 1.599 1.82.001 1-.705 1.82-1.6 1.82m5.91 0c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.893 0 1.614.82 1.599 1.82 0 1-.706 1.82-1.6 1.82"/>
|
|
8
|
+
</symbol>
|
|
9
|
+
<symbol id="documentation-icon" viewBox="0 0 21 20">
|
|
10
|
+
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="m15.5 13.333 1.533 1.322c.645.555.967.833.967 1.178s-.322.623-.967 1.179L15.5 18.333m-3.333-5-1.534 1.322c-.644.555-.966.833-.966 1.178s.322.623.966 1.179l1.534 1.321"/>
|
|
11
|
+
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M17.167 10.836v-4.32c0-1.41 0-2.117-.224-2.68-.359-.906-1.118-1.621-2.08-1.96-.599-.21-1.349-.21-2.848-.21-2.623 0-3.935 0-4.983.369-1.684.591-3.013 1.842-3.641 3.428C3 6.449 3 7.684 3 10.154v2.122c0 2.558 0 3.838.706 4.726q.306.383.713.671c.76.536 1.79.64 3.581.66"/>
|
|
12
|
+
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M3 10a2.78 2.78 0 0 1 2.778-2.778c.555 0 1.209.097 1.748-.047.48-.129.854-.503.982-.982.145-.54.048-1.194.048-1.749a2.78 2.78 0 0 1 2.777-2.777"/>
|
|
13
|
+
</symbol>
|
|
14
|
+
<symbol id="github-icon" viewBox="0 0 19 19">
|
|
15
|
+
<path fill="#08060d" fill-rule="evenodd" d="M9.356 1.85C5.05 1.85 1.57 5.356 1.57 9.694a7.84 7.84 0 0 0 5.324 7.44c.387.079.528-.168.528-.376 0-.182-.013-.805-.013-1.454-2.165.467-2.616-.935-2.616-.935-.349-.91-.864-1.143-.864-1.143-.71-.48.051-.48.051-.48.787.051 1.2.805 1.2.805.695 1.194 1.817.857 2.268.649.064-.507.27-.857.49-1.052-1.728-.182-3.545-.857-3.545-3.87 0-.857.31-1.558.8-2.104-.078-.195-.349-1 .077-2.078 0 0 .657-.208 2.14.805a7.5 7.5 0 0 1 1.946-.26c.657 0 1.328.092 1.946.26 1.483-1.013 2.14-.805 2.14-.805.426 1.078.155 1.883.078 2.078.502.546.799 1.247.799 2.104 0 3.013-1.818 3.675-3.558 3.87.284.247.528.714.528 1.454 0 1.052-.012 1.896-.012 2.156 0 .208.142.455.528.377a7.84 7.84 0 0 0 5.324-7.441c.013-4.338-3.48-7.844-7.773-7.844" clip-rule="evenodd"/>
|
|
16
|
+
</symbol>
|
|
17
|
+
<symbol id="social-icon" viewBox="0 0 20 20">
|
|
18
|
+
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M12.5 6.667a4.167 4.167 0 1 0-8.334 0 4.167 4.167 0 0 0 8.334 0"/>
|
|
19
|
+
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M2.5 16.667a5.833 5.833 0 0 1 8.75-5.053m3.837.474.513 1.035c.07.144.257.282.414.309l.93.155c.596.1.736.536.307.965l-.723.73a.64.64 0 0 0-.152.531l.207.903c.164.715-.213.991-.84.618l-.872-.52a.63.63 0 0 0-.577 0l-.872.52c-.624.373-1.003.094-.84-.618l.207-.903a.64.64 0 0 0-.152-.532l-.723-.729c-.426-.43-.289-.864.306-.964l.93-.156a.64.64 0 0 0 .412-.31l.513-1.034c.28-.562.735-.562 1.012 0"/>
|
|
20
|
+
</symbol>
|
|
21
|
+
<symbol id="x-icon" viewBox="0 0 19 19">
|
|
22
|
+
<path fill="#08060d" fill-rule="evenodd" d="M1.893 1.98c.052.072 1.245 1.769 2.653 3.77l2.892 4.114c.183.261.333.48.333.486s-.068.089-.152.183l-.522.593-.765.867-3.597 4.087c-.375.426-.734.834-.798.905a1 1 0 0 0-.118.148c0 .01.236.017.664.017h.663l.729-.83c.4-.457.796-.906.879-.999a692 692 0 0 0 1.794-2.038c.034-.037.301-.34.594-.675l.551-.624.345-.392a7 7 0 0 1 .34-.374c.006 0 .93 1.306 2.052 2.903l2.084 2.965.045.063h2.275c1.87 0 2.273-.003 2.266-.021-.008-.02-1.098-1.572-3.894-5.547-2.013-2.862-2.28-3.246-2.273-3.266.008-.019.282-.332 2.085-2.38l2-2.274 1.567-1.782c.022-.028-.016-.03-.65-.03h-.674l-.3.342a871 871 0 0 1-1.782 2.025c-.067.075-.405.458-.75.852a100 100 0 0 1-.803.91c-.148.172-.299.344-.99 1.127-.304.343-.32.358-.345.327-.015-.019-.904-1.282-1.976-2.808L6.365 1.85H1.8zm1.782.91 8.078 11.294c.772 1.08 1.413 1.973 1.425 1.984.016.017.241.02 1.05.017l1.03-.004-2.694-3.766L7.796 5.75 5.722 2.852l-1.039-.004-1.039-.004z" clip-rule="evenodd"/>
|
|
23
|
+
</symbol>
|
|
24
|
+
</svg>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>admin</title>
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-96WpHq9_.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/assets/index-zcGzKcF4.css">
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<div id="root"></div>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
// src/server.ts
|
|
2
|
+
import Fastify from "fastify";
|
|
3
|
+
import fastifyCookie from "@fastify/cookie";
|
|
4
|
+
import fastifyCors from "@fastify/cors";
|
|
5
|
+
import fastifyStatic from "@fastify/static";
|
|
6
|
+
import path from "path";
|
|
7
|
+
|
|
8
|
+
// src/session.ts
|
|
9
|
+
import { randomBytes } from "crypto";
|
|
10
|
+
var SESSION_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
11
|
+
var SessionManager = class {
|
|
12
|
+
constructor(storage) {
|
|
13
|
+
this.storage = storage;
|
|
14
|
+
}
|
|
15
|
+
storage;
|
|
16
|
+
activeSessionId = null;
|
|
17
|
+
createSession() {
|
|
18
|
+
this.storage.sessions.deleteExpired();
|
|
19
|
+
const id = randomBytes(32).toString("hex");
|
|
20
|
+
const now = /* @__PURE__ */ new Date();
|
|
21
|
+
const expiresAt = new Date(now.getTime() + SESSION_TTL_MS);
|
|
22
|
+
this.storage.sessions.create({
|
|
23
|
+
id,
|
|
24
|
+
createdAt: now.toISOString(),
|
|
25
|
+
expiresAt: expiresAt.toISOString()
|
|
26
|
+
});
|
|
27
|
+
this.activeSessionId = id;
|
|
28
|
+
return id;
|
|
29
|
+
}
|
|
30
|
+
validateSession(id) {
|
|
31
|
+
if (!id) return false;
|
|
32
|
+
const session = this.storage.sessions.findById(id);
|
|
33
|
+
if (!session) return false;
|
|
34
|
+
if (new Date(session.expiresAt) < /* @__PURE__ */ new Date()) {
|
|
35
|
+
this.storage.sessions.deleteById(id);
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
invalidateSession(id) {
|
|
41
|
+
this.storage.sessions.deleteById(id);
|
|
42
|
+
if (this.activeSessionId === id) this.activeSessionId = null;
|
|
43
|
+
}
|
|
44
|
+
invalidateAll() {
|
|
45
|
+
if (this.activeSessionId) {
|
|
46
|
+
this.storage.sessions.deleteById(this.activeSessionId);
|
|
47
|
+
this.activeSessionId = null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// src/core-adapter.ts
|
|
53
|
+
import {
|
|
54
|
+
buildProjectExplanation,
|
|
55
|
+
buildReadinessReport,
|
|
56
|
+
buildProjectRoute,
|
|
57
|
+
loadConfig,
|
|
58
|
+
loadMappedModules
|
|
59
|
+
} from "@kaddo/cli/core";
|
|
60
|
+
function getProjectSummary(dir) {
|
|
61
|
+
const config = loadConfig(dir);
|
|
62
|
+
if (!config) throw new CoreError("PROJECT_NOT_FOUND", "No Kaddo project was found.");
|
|
63
|
+
return {
|
|
64
|
+
name: config.project.name ?? "unknown",
|
|
65
|
+
state: config.project.state ?? "unknown",
|
|
66
|
+
structure: config.project.structure ?? "unknown",
|
|
67
|
+
language: config.project.language ?? "en",
|
|
68
|
+
teamSize: config.team.size ?? "unknown"
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function getKnowledgeSummary(dir) {
|
|
72
|
+
const exp = buildProjectExplanation(dir);
|
|
73
|
+
return {
|
|
74
|
+
layers: exp.layers.map((l) => ({ layer: l.layer, status: l.status })),
|
|
75
|
+
missing: exp.missingKnowledge
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function getWorkItemSummary(dir) {
|
|
79
|
+
const exp = buildProjectExplanation(dir);
|
|
80
|
+
return {
|
|
81
|
+
total: exp.workItems.total,
|
|
82
|
+
byState: exp.workItems.byState,
|
|
83
|
+
byType: exp.workItems.byType,
|
|
84
|
+
items: exp.workItems.items.map((i) => ({
|
|
85
|
+
id: i.id,
|
|
86
|
+
title: i.title,
|
|
87
|
+
type: i.type,
|
|
88
|
+
lifecycle: i.lifecycle,
|
|
89
|
+
initiative: i.initiative
|
|
90
|
+
}))
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function getModules(dir) {
|
|
94
|
+
const mapped = loadMappedModules(dir);
|
|
95
|
+
return {
|
|
96
|
+
modules: mapped.map((m) => ({
|
|
97
|
+
id: m.id,
|
|
98
|
+
role: m.role,
|
|
99
|
+
path: m.path,
|
|
100
|
+
available: m.available
|
|
101
|
+
}))
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function getProjectReadiness(dir) {
|
|
105
|
+
const report = buildReadinessReport(dir);
|
|
106
|
+
return {
|
|
107
|
+
overall: report.overall,
|
|
108
|
+
recommendedNextStep: {
|
|
109
|
+
label: report.nextStepRecommendation.label,
|
|
110
|
+
command: report.nextStepRecommendation.command
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function getProjectRoute(dir) {
|
|
115
|
+
const route = buildProjectRoute(dir);
|
|
116
|
+
return {
|
|
117
|
+
type: route.type,
|
|
118
|
+
completed: route.completed,
|
|
119
|
+
total: route.total,
|
|
120
|
+
progressPercent: route.progressPercent,
|
|
121
|
+
steps: route.steps.map((s) => ({
|
|
122
|
+
id: s.id,
|
|
123
|
+
label: s.label,
|
|
124
|
+
status: s.status,
|
|
125
|
+
...s.evidence ? { evidence: s.evidence } : {},
|
|
126
|
+
...s.reason ? { reason: s.reason } : {},
|
|
127
|
+
...s.command ? { command: s.command } : {}
|
|
128
|
+
}))
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
function getFindings(dir) {
|
|
132
|
+
const exp = buildProjectExplanation(dir);
|
|
133
|
+
const items = [];
|
|
134
|
+
if (exp.missingKnowledge.length > 0) {
|
|
135
|
+
for (const m of exp.missingKnowledge) {
|
|
136
|
+
items.push({ level: "warning", message: `Missing: ${m}` });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (exp.duplicateWorkItems.length > 0) {
|
|
140
|
+
for (const d of exp.duplicateWorkItems) {
|
|
141
|
+
items.push({ level: "warning", message: `Possible duplicate Work Items: ${d.items.map((i) => i.id).join(", ")} (${d.reason})` });
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
const blocking = items.filter((i) => i.level === "blocking").length;
|
|
145
|
+
const warning = items.filter((i) => i.level === "warning").length;
|
|
146
|
+
const fyi = items.filter((i) => i.level === "fyi").length;
|
|
147
|
+
return { blocking, warning, fyi, items };
|
|
148
|
+
}
|
|
149
|
+
function getProjectOverview(dir) {
|
|
150
|
+
return {
|
|
151
|
+
project: getProjectSummary(dir),
|
|
152
|
+
knowledge: getKnowledgeSummary(dir),
|
|
153
|
+
workItems: getWorkItemSummary(dir),
|
|
154
|
+
modules: getModules(dir),
|
|
155
|
+
readiness: getProjectReadiness(dir),
|
|
156
|
+
route: getProjectRoute(dir),
|
|
157
|
+
findings: getFindings(dir)
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
var CoreError = class extends Error {
|
|
161
|
+
constructor(code, message) {
|
|
162
|
+
super(message);
|
|
163
|
+
this.code = code;
|
|
164
|
+
this.name = "CoreError";
|
|
165
|
+
}
|
|
166
|
+
code;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
// src/server.ts
|
|
170
|
+
async function createAdminServer(opts) {
|
|
171
|
+
const { projectDir, storage, staticDir, host = "127.0.0.1", port = 4173 } = opts;
|
|
172
|
+
const app = Fastify({ logger: false });
|
|
173
|
+
const sessionManager = new SessionManager(storage);
|
|
174
|
+
await app.register(fastifyCookie);
|
|
175
|
+
await app.register(fastifyCors, {
|
|
176
|
+
origin: `http://${host}:${port}`,
|
|
177
|
+
credentials: true
|
|
178
|
+
});
|
|
179
|
+
if (staticDir) {
|
|
180
|
+
await app.register(fastifyStatic, {
|
|
181
|
+
root: path.resolve(staticDir),
|
|
182
|
+
prefix: "/",
|
|
183
|
+
wildcard: false
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
const sessionId = sessionManager.createSession();
|
|
187
|
+
app.addHook("onRequest", async (request, reply) => {
|
|
188
|
+
if (!request.url.startsWith("/api/")) return;
|
|
189
|
+
const cookieSession = request.cookies["kaddo-session"];
|
|
190
|
+
if (!sessionManager.validateSession(cookieSession)) {
|
|
191
|
+
reply.code(401).send({ error: { code: "SESSION_INVALID", message: "Invalid or expired session." } });
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
app.get("/api/v1/admin/health", async () => ({ status: "ok" }));
|
|
195
|
+
app.get("/api/v1/admin/session", async (_request, reply) => {
|
|
196
|
+
reply.setCookie("kaddo-session", sessionId, {
|
|
197
|
+
path: "/",
|
|
198
|
+
httpOnly: true,
|
|
199
|
+
sameSite: "strict",
|
|
200
|
+
maxAge: 86400
|
|
201
|
+
});
|
|
202
|
+
return { status: "active" };
|
|
203
|
+
});
|
|
204
|
+
const coreRoute = (handler) => {
|
|
205
|
+
return async () => {
|
|
206
|
+
try {
|
|
207
|
+
return handler(projectDir);
|
|
208
|
+
} catch (err) {
|
|
209
|
+
if (err instanceof CoreError) {
|
|
210
|
+
return { error: { code: err.code, message: err.message } };
|
|
211
|
+
}
|
|
212
|
+
throw err;
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
};
|
|
216
|
+
app.get("/api/v1/admin/overview", coreRoute(getProjectOverview));
|
|
217
|
+
app.get("/api/v1/admin/project", coreRoute(getProjectSummary));
|
|
218
|
+
app.get("/api/v1/admin/knowledge", coreRoute(getKnowledgeSummary));
|
|
219
|
+
app.get("/api/v1/admin/work-items", coreRoute(getWorkItemSummary));
|
|
220
|
+
app.get("/api/v1/admin/modules", coreRoute(getModules));
|
|
221
|
+
app.get("/api/v1/admin/readiness", coreRoute(getProjectReadiness));
|
|
222
|
+
app.get("/api/v1/admin/route", coreRoute(getProjectRoute));
|
|
223
|
+
app.get("/api/v1/admin/findings", coreRoute(getFindings));
|
|
224
|
+
if (staticDir) {
|
|
225
|
+
app.setNotFoundHandler(async (_request, reply) => {
|
|
226
|
+
return reply.sendFile("index.html");
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
return {
|
|
230
|
+
app,
|
|
231
|
+
sessionId,
|
|
232
|
+
sessionManager,
|
|
233
|
+
start: async () => {
|
|
234
|
+
await app.listen({ host, port });
|
|
235
|
+
return `http://${host}:${port}`;
|
|
236
|
+
},
|
|
237
|
+
stop: async () => {
|
|
238
|
+
sessionManager.invalidateAll();
|
|
239
|
+
await app.close();
|
|
240
|
+
await storage.close();
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// src/storage/sqlite-storage.ts
|
|
246
|
+
import { DatabaseSync } from "sqlite";
|
|
247
|
+
var SQLiteAdminStorage = class {
|
|
248
|
+
constructor(dbPath) {
|
|
249
|
+
this.dbPath = dbPath;
|
|
250
|
+
this.db = new DatabaseSync(dbPath);
|
|
251
|
+
this.db.exec("PRAGMA journal_mode = WAL");
|
|
252
|
+
this.sessions = {
|
|
253
|
+
create: (session) => {
|
|
254
|
+
this.db.prepare(
|
|
255
|
+
"INSERT OR REPLACE INTO admin_sessions (id, created_at, expires_at) VALUES (?, ?, ?)"
|
|
256
|
+
).run(session.id, session.createdAt, session.expiresAt);
|
|
257
|
+
},
|
|
258
|
+
findById: (id) => {
|
|
259
|
+
const row = this.db.prepare(
|
|
260
|
+
"SELECT id, created_at, expires_at FROM admin_sessions WHERE id = ?"
|
|
261
|
+
).get(id);
|
|
262
|
+
if (!row) return void 0;
|
|
263
|
+
return { id: row.id, createdAt: row.created_at, expiresAt: row.expires_at };
|
|
264
|
+
},
|
|
265
|
+
deleteById: (id) => {
|
|
266
|
+
this.db.prepare("DELETE FROM admin_sessions WHERE id = ?").run(id);
|
|
267
|
+
},
|
|
268
|
+
deleteExpired: () => {
|
|
269
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
270
|
+
this.db.prepare("DELETE FROM admin_sessions WHERE expires_at < ?").run(now);
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
this.preferences = {
|
|
274
|
+
get: (key) => {
|
|
275
|
+
const row = this.db.prepare(
|
|
276
|
+
"SELECT value FROM admin_preferences WHERE key = ?"
|
|
277
|
+
).get(key);
|
|
278
|
+
return row?.value;
|
|
279
|
+
},
|
|
280
|
+
set: (key, value) => {
|
|
281
|
+
this.db.prepare(
|
|
282
|
+
"INSERT OR REPLACE INTO admin_preferences (key, value) VALUES (?, ?)"
|
|
283
|
+
).run(key, value);
|
|
284
|
+
},
|
|
285
|
+
delete: (key) => {
|
|
286
|
+
this.db.prepare("DELETE FROM admin_preferences WHERE key = ?").run(key);
|
|
287
|
+
},
|
|
288
|
+
all: () => {
|
|
289
|
+
return this.db.prepare("SELECT key, value FROM admin_preferences").all();
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
this.cache = {
|
|
293
|
+
get: (key) => {
|
|
294
|
+
const row = this.db.prepare(
|
|
295
|
+
"SELECT value, expires_at FROM admin_cache WHERE key = ?"
|
|
296
|
+
).get(key);
|
|
297
|
+
if (!row) return void 0;
|
|
298
|
+
if (row.expires_at && new Date(row.expires_at) < /* @__PURE__ */ new Date()) {
|
|
299
|
+
this.db.prepare("DELETE FROM admin_cache WHERE key = ?").run(key);
|
|
300
|
+
return void 0;
|
|
301
|
+
}
|
|
302
|
+
return row.value;
|
|
303
|
+
},
|
|
304
|
+
set: (key, value, ttlMs) => {
|
|
305
|
+
const expiresAt = ttlMs ? new Date(Date.now() + ttlMs).toISOString() : null;
|
|
306
|
+
this.db.prepare(
|
|
307
|
+
"INSERT OR REPLACE INTO admin_cache (key, value, expires_at) VALUES (?, ?, ?)"
|
|
308
|
+
).run(key, value, expiresAt);
|
|
309
|
+
},
|
|
310
|
+
delete: (key) => {
|
|
311
|
+
this.db.prepare("DELETE FROM admin_cache WHERE key = ?").run(key);
|
|
312
|
+
},
|
|
313
|
+
clear: () => {
|
|
314
|
+
this.db.exec("DELETE FROM admin_cache");
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
dbPath;
|
|
319
|
+
db;
|
|
320
|
+
sessions;
|
|
321
|
+
preferences;
|
|
322
|
+
cache;
|
|
323
|
+
async initialize() {
|
|
324
|
+
this.db.exec(`
|
|
325
|
+
CREATE TABLE IF NOT EXISTS admin_sessions (
|
|
326
|
+
id TEXT PRIMARY KEY,
|
|
327
|
+
created_at TEXT NOT NULL,
|
|
328
|
+
expires_at TEXT NOT NULL
|
|
329
|
+
);
|
|
330
|
+
CREATE TABLE IF NOT EXISTS admin_preferences (
|
|
331
|
+
key TEXT PRIMARY KEY,
|
|
332
|
+
value TEXT NOT NULL
|
|
333
|
+
);
|
|
334
|
+
CREATE TABLE IF NOT EXISTS admin_cache (
|
|
335
|
+
key TEXT PRIMARY KEY,
|
|
336
|
+
value TEXT NOT NULL,
|
|
337
|
+
expires_at TEXT
|
|
338
|
+
);
|
|
339
|
+
CREATE TABLE IF NOT EXISTS audit_events (
|
|
340
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
341
|
+
timestamp TEXT NOT NULL,
|
|
342
|
+
action TEXT NOT NULL,
|
|
343
|
+
detail TEXT
|
|
344
|
+
);
|
|
345
|
+
`);
|
|
346
|
+
}
|
|
347
|
+
async close() {
|
|
348
|
+
this.db.close();
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
// src/contracts/schemas.ts
|
|
353
|
+
import { z } from "zod";
|
|
354
|
+
var ProjectSummarySchema = z.object({
|
|
355
|
+
name: z.string(),
|
|
356
|
+
state: z.string(),
|
|
357
|
+
structure: z.string(),
|
|
358
|
+
language: z.string(),
|
|
359
|
+
teamSize: z.string()
|
|
360
|
+
});
|
|
361
|
+
var KnowledgeSummarySchema = z.object({
|
|
362
|
+
layers: z.array(z.object({
|
|
363
|
+
layer: z.string(),
|
|
364
|
+
status: z.string()
|
|
365
|
+
})),
|
|
366
|
+
missing: z.array(z.string())
|
|
367
|
+
});
|
|
368
|
+
var WorkItemSummarySchema = z.object({
|
|
369
|
+
total: z.number(),
|
|
370
|
+
byState: z.record(z.string(), z.number()),
|
|
371
|
+
byType: z.record(z.string(), z.number()),
|
|
372
|
+
items: z.array(z.object({
|
|
373
|
+
id: z.string(),
|
|
374
|
+
title: z.string(),
|
|
375
|
+
type: z.string(),
|
|
376
|
+
lifecycle: z.string(),
|
|
377
|
+
initiative: z.string()
|
|
378
|
+
}))
|
|
379
|
+
});
|
|
380
|
+
var ModuleSummarySchema = z.object({
|
|
381
|
+
modules: z.array(z.object({
|
|
382
|
+
id: z.string(),
|
|
383
|
+
role: z.string(),
|
|
384
|
+
path: z.string().optional(),
|
|
385
|
+
available: z.boolean()
|
|
386
|
+
}))
|
|
387
|
+
});
|
|
388
|
+
var ProjectReadinessSchema = z.object({
|
|
389
|
+
overall: z.string(),
|
|
390
|
+
recommendedNextStep: z.object({
|
|
391
|
+
label: z.string(),
|
|
392
|
+
command: z.string().optional()
|
|
393
|
+
})
|
|
394
|
+
});
|
|
395
|
+
var RouteStepSchema = z.object({
|
|
396
|
+
id: z.string(),
|
|
397
|
+
label: z.string(),
|
|
398
|
+
status: z.string(),
|
|
399
|
+
evidence: z.array(z.string()).optional(),
|
|
400
|
+
reason: z.string().optional(),
|
|
401
|
+
command: z.string().optional()
|
|
402
|
+
});
|
|
403
|
+
var ProjectRouteSchema = z.object({
|
|
404
|
+
type: z.string(),
|
|
405
|
+
completed: z.number(),
|
|
406
|
+
total: z.number(),
|
|
407
|
+
progressPercent: z.number(),
|
|
408
|
+
steps: z.array(RouteStepSchema)
|
|
409
|
+
});
|
|
410
|
+
var FindingsSummarySchema = z.object({
|
|
411
|
+
blocking: z.number(),
|
|
412
|
+
warning: z.number(),
|
|
413
|
+
fyi: z.number(),
|
|
414
|
+
items: z.array(z.object({
|
|
415
|
+
level: z.enum(["blocking", "warning", "fyi"]),
|
|
416
|
+
message: z.string()
|
|
417
|
+
}))
|
|
418
|
+
});
|
|
419
|
+
var ProjectOverviewSchema = z.object({
|
|
420
|
+
project: ProjectSummarySchema,
|
|
421
|
+
knowledge: KnowledgeSummarySchema,
|
|
422
|
+
workItems: WorkItemSummarySchema,
|
|
423
|
+
modules: ModuleSummarySchema,
|
|
424
|
+
readiness: ProjectReadinessSchema,
|
|
425
|
+
route: ProjectRouteSchema,
|
|
426
|
+
findings: FindingsSummarySchema
|
|
427
|
+
});
|
|
428
|
+
var ErrorResponseSchema = z.object({
|
|
429
|
+
error: z.object({
|
|
430
|
+
code: z.string(),
|
|
431
|
+
message: z.string()
|
|
432
|
+
})
|
|
433
|
+
});
|
|
434
|
+
export {
|
|
435
|
+
ErrorResponseSchema,
|
|
436
|
+
FindingsSummarySchema,
|
|
437
|
+
KnowledgeSummarySchema,
|
|
438
|
+
ModuleSummarySchema,
|
|
439
|
+
ProjectOverviewSchema,
|
|
440
|
+
ProjectReadinessSchema,
|
|
441
|
+
ProjectRouteSchema,
|
|
442
|
+
ProjectSummarySchema,
|
|
443
|
+
RouteStepSchema,
|
|
444
|
+
SQLiteAdminStorage,
|
|
445
|
+
SessionManager,
|
|
446
|
+
WorkItemSummarySchema,
|
|
447
|
+
createAdminServer
|
|
448
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -18510,6 +18510,9 @@ function isPortAvailable(port, host) {
|
|
|
18510
18510
|
function resolveStaticDir() {
|
|
18511
18511
|
const __dirname = path8.dirname(fileURLToPath2(import.meta.url));
|
|
18512
18512
|
const candidates = [
|
|
18513
|
+
// Bundled inside CLI dist (npm install)
|
|
18514
|
+
path8.resolve(__dirname, "admin-dist"),
|
|
18515
|
+
// Monorepo development
|
|
18513
18516
|
path8.resolve(__dirname, "..", "..", "admin", "dist"),
|
|
18514
18517
|
path8.resolve(__dirname, "..", "node_modules", "@kaddo", "admin", "dist")
|
|
18515
18518
|
];
|
|
@@ -18551,7 +18554,19 @@ async function runAdmin(opts = {}) {
|
|
|
18551
18554
|
console.error("Admin frontend not built. Run `pnpm -r build` first.");
|
|
18552
18555
|
process.exit(1);
|
|
18553
18556
|
}
|
|
18554
|
-
|
|
18557
|
+
let adminServer;
|
|
18558
|
+
try {
|
|
18559
|
+
const __dirname = path8.dirname(fileURLToPath2(import.meta.url));
|
|
18560
|
+
const bundled = path8.resolve(__dirname, "admin-server", "index.js");
|
|
18561
|
+
if (exists(bundled)) {
|
|
18562
|
+
adminServer = await import(bundled);
|
|
18563
|
+
} else {
|
|
18564
|
+
adminServer = await import("@kaddo/admin-server");
|
|
18565
|
+
}
|
|
18566
|
+
} catch {
|
|
18567
|
+
adminServer = await import("@kaddo/admin-server");
|
|
18568
|
+
}
|
|
18569
|
+
const { createAdminServer, SQLiteAdminStorage } = adminServer;
|
|
18555
18570
|
const dbDir = join(dir, ".kaddo", "admin");
|
|
18556
18571
|
ensureDir(dbDir);
|
|
18557
18572
|
const dbPath = join(dbDir, "admin.db");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kaddo/cli",
|
|
3
|
-
"version": "3.69.
|
|
3
|
+
"version": "3.69.2",
|
|
4
4
|
"description": "Knowledge Driven Development toolkit",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"access": "public"
|
|
37
37
|
},
|
|
38
38
|
"scripts": {
|
|
39
|
-
"build": "tsup",
|
|
39
|
+
"build": "tsup && node -e \"const fs=require('fs');[['../admin/dist','dist/admin-dist'],['../admin-server/dist','dist/admin-server']].forEach(([s,d])=>{if(fs.existsSync(s)){fs.cpSync(s,d,{recursive:true})}})\"",
|
|
40
40
|
"dev": "tsup --watch",
|
|
41
41
|
"test": "vitest run",
|
|
42
42
|
"prepublishOnly": "npm run build"
|