@hasna/todos 0.9.15 → 0.9.17
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/README.md +50 -2
- package/dashboard/dist/assets/index-CpjKnPxm.js +341 -0
- package/dashboard/dist/assets/index-DWpVlvWb.css +1 -0
- package/dashboard/dist/index.html +2 -2
- package/dist/cli/index.js +85 -3
- package/dist/index.js +19 -2
- package/dist/mcp/index.js +20 -3
- package/dist/server/index.js +152 -1
- package/package.json +16 -4
- package/dashboard/dist/assets/index-C0v4F2Nz.js +0 -336
- package/dashboard/dist/assets/index-C2L8R7ya.css +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */@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-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-space-y-reverse:0;--tw-space-x-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-duration:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, 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;--color-red-50:oklch(97.1% .013 17.38);--color-red-100:oklch(93.6% .032 17.717);--color-red-200:oklch(88.5% .062 18.334);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-800:oklch(44.4% .177 26.899);--color-red-900:oklch(39.6% .141 25.723);--color-red-950:oklch(25.8% .092 26.042);--color-orange-100:oklch(95.4% .038 75.164);--color-orange-200:oklch(90.1% .076 70.697);--color-orange-500:oklch(70.5% .213 47.604);--color-orange-800:oklch(47% .157 37.304);--color-orange-900:oklch(40.8% .123 38.172);--color-yellow-500:oklch(79.5% .184 86.047);--color-green-50:oklch(98.2% .018 155.826);--color-green-200:oklch(92.5% .084 155.995);--color-green-500:oklch(72.3% .219 149.579);--color-green-800:oklch(44.8% .119 151.328);--color-green-900:oklch(39.3% .095 152.535);--color-green-950:oklch(26.6% .065 152.934);--color-teal-500:oklch(70.4% .14 182.503);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-200:oklch(88.2% .059 254.128);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-800:oklch(42.4% .199 265.638);--color-blue-900:oklch(37.9% .146 265.522);--color-indigo-500:oklch(58.5% .233 277.117);--color-purple-100:oklch(94.6% .033 307.174);--color-purple-200:oklch(90.2% .063 306.703);--color-purple-500:oklch(62.7% .265 303.9);--color-purple-800:oklch(43.8% .218 303.724);--color-purple-900:oklch(38.1% .176 304.987);--color-pink-500:oklch(65.6% .241 354.308);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-800:oklch(27.8% .033 256.848);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-2xl:42rem;--container-6xl:72rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--leading-tight:1.25;--leading-relaxed:1.625;--animate-spin:spin 1s linear infinite;--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%;-moz-tab-size:4;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;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]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance: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)}body{background-color:var(--background);color:var(--foreground);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}}@layer components;@layer utilities{.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}.inset-0{inset:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.top-2\.5{top:calc(var(--spacing) * 2.5)}.top-4{top:calc(var(--spacing) * 4)}.top-\[50\%\]{top:50%}.right-1{right:calc(var(--spacing) * 1)}.right-2{right:calc(var(--spacing) * 2)}.right-4{right:calc(var(--spacing) * 4)}.right-6{right:calc(var(--spacing) * 6)}.bottom-6{bottom:calc(var(--spacing) * 6)}.left-1{left:calc(var(--spacing) * 1)}.left-1\/2{left:50%}.left-2{left:calc(var(--spacing) * 2)}.left-2\.5{left:calc(var(--spacing) * 2.5)}.left-\[50\%\]{left:50%}.z-10{z-index:10}.z-50{z-index:50}.-mx-1{margin-inline:calc(var(--spacing) * -1)}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing) * 1)}.my-1\.5{margin-block:calc(var(--spacing) * 1.5)}.my-2{margin-block:calc(var(--spacing) * 2)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mr-1{margin-right:calc(var(--spacing) * 1)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.-ml-2{margin-left:calc(var(--spacing) * -2)}.-ml-3{margin-left:calc(var(--spacing) * -3)}.ml-1\.5{margin-left:calc(var(--spacing) * 1.5)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-4{margin-left:calc(var(--spacing) * 4)}.ml-auto{margin-left:auto}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.table{display:table}.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-10{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.h-2{height:calc(var(--spacing) * 2)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.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-14{height:calc(var(--spacing) * 14)}.h-24{height:calc(var(--spacing) * 24)}.h-\[var\(--radix-select-trigger-height\)\]{height:var(--radix-select-trigger-height)}.h-full{height:100%}.h-px{height:1px}.max-h-96{max-height:calc(var(--spacing) * 96)}.max-h-\[70vh\]{max-height:70vh}.max-h-\[85vh\]{max-height:85vh}.max-h-\[200px\]{max-height:200px}.max-h-\[300px\]{max-height:300px}.max-h-\[400px\]{max-height:400px}.min-h-\[100px\]{min-height:100px}.min-h-screen{min-height:100vh}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-72{width:calc(var(--spacing) * 72)}.w-\[130px\]{width:130px}.w-\[140px\]{width:140px}.w-auto{width:auto}.w-full{width:100%}.w-max{width:max-content}.w-px{width:1px}.max-w-2xl{max-width:var(--container-2xl)}.max-w-6xl{max-width:var(--container-6xl)}.max-w-\[120px\]{max-width:120px}.max-w-\[150px\]{max-width:150px}.max-w-\[180px\]{max-width:180px}.max-w-\[200px\]{max-width:200px}.max-w-\[250px\]{max-width:250px}.max-w-\[300px\]{max-width:300px}.max-w-\[400px\]{max-width:400px}.max-w-lg{max-width:var(--container-lg)}.max-w-max{max-width:max-content}.max-w-md{max-width:var(--container-md)}.max-w-none{max-width:none}.max-w-sm{max-width:var(--container-sm)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-\[8rem\]{min-width:8rem}.min-w-\[180px\]{min-width:180px}.min-w-\[200px\]{min-width:200px}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.caption-bottom{caption-side:bottom}.border-collapse{border-collapse:collapse}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-\[-50\%\]{--tw-translate-x:-50%;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-1{--tw-translate-y:calc(var(--spacing) * 1);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-\[-50\%\]{--tw-translate-y:-50%;translate:var(--tw-translate-x) var(--tw-translate-y)}.scale-0{--tw-scale-x:0%;--tw-scale-y:0%;--tw-scale-z:0%;scale:var(--tw-scale-x) var(--tw-scale-y)}.scale-100{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y)}.rotate-0{rotate:none}.rotate-90{rotate:90deg}.animate-in{animation:.2s ease-out enter}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.resize-y{resize:vertical}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.list-none{list-style-type:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-start{justify-content:flex-start}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}:where(.space-y-0>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 0) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 0) * calc(1 - var(--tw-space-y-reverse)))}: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(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * 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)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-8{column-gap:calc(var(--spacing) * 8)}:where(.space-x-1>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing) * 1) * var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-x-reverse)))}.gap-y-2{row-gap:calc(var(--spacing) * 2)}: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)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.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-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}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-green-200{border-color:var(--color-green-200)}.border-input{border-color:var(--input)}.border-red-200{border-color:var(--color-red-200)}.border-transparent{border-color:#0000}.border-l-blue-500{border-left-color:var(--color-blue-500)}.border-l-gray-400{border-left-color:var(--color-gray-400)}.border-l-orange-500{border-left-color:var(--color-orange-500)}.border-l-red-500{border-left-color:var(--color-red-500)}.bg-accent{background-color:var(--accent)}.bg-background{background-color:var(--background)}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab,red,red)){.bg-black\/50{background-color:color-mix(in oklab,var(--color-black) 50%,transparent)}}.bg-blue-100{background-color:var(--color-blue-100)}.bg-blue-500{background-color:var(--color-blue-500)}.bg-border{background-color:var(--border)}.bg-card{background-color:var(--card)}.bg-destructive{background-color:var(--destructive)}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-400{background-color:var(--color-gray-400)}.bg-green-50{background-color:var(--color-green-50)}.bg-green-500{background-color:var(--color-green-500)}.bg-indigo-500{background-color:var(--color-indigo-500)}.bg-muted,.bg-muted\/30{background-color:var(--muted)}@supports (color:color-mix(in lab,red,red)){.bg-muted\/30{background-color:color-mix(in oklab,var(--muted) 30%,transparent)}}.bg-muted\/50{background-color:var(--muted)}@supports (color:color-mix(in lab,red,red)){.bg-muted\/50{background-color:color-mix(in oklab,var(--muted) 50%,transparent)}}.bg-orange-100{background-color:var(--color-orange-100)}.bg-orange-500{background-color:var(--color-orange-500)}.bg-pink-500{background-color:var(--color-pink-500)}.bg-popover{background-color:var(--popover)}.bg-primary{background-color:var(--primary)}.bg-purple-100{background-color:var(--color-purple-100)}.bg-purple-500{background-color:var(--color-purple-500)}.bg-red-50{background-color:var(--color-red-50)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-500{background-color:var(--color-red-500)}.bg-secondary{background-color:var(--secondary)}.bg-teal-500{background-color:var(--color-teal-500)}.bg-transparent{background-color:#0000}.bg-yellow-500{background-color:var(--color-yellow-500)}.p-0{padding:calc(var(--spacing) * 0)}.p-1{padding:calc(var(--spacing) * 1)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.px-1{padding-inline:calc(var(--spacing) * 1)}.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-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-8{padding-inline:calc(var(--spacing) * 8)}.py-0{padding-block:calc(var(--spacing) * 0)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-12{padding-block:calc(var(--spacing) * 12)}.pt-0{padding-top:calc(var(--spacing) * 0)}.pt-1{padding-top:calc(var(--spacing) * 1)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pr-4{padding-right:calc(var(--spacing) * 4)}.pr-8{padding-right:calc(var(--spacing) * 8)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-8{padding-left:calc(var(--spacing) * 8)}.text-center{text-align:center}.text-left{text-align:left}.align-middle{vertical-align:middle}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[0\.8rem\]{font-size:.8rem}.text-\[10px\]{font-size:10px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.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-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.whitespace-nowrap{white-space:nowrap}.text-accent-foreground{color:var(--accent-foreground)}.text-blue-500{color:var(--color-blue-500)}.text-blue-800{color:var(--color-blue-800)}.text-card-foreground{color:var(--card-foreground)}.text-foreground{color:var(--foreground)}.text-gray-400{color:var(--color-gray-400)}.text-gray-700{color:var(--color-gray-700)}.text-green-500{color:var(--color-green-500)}.text-green-800{color:var(--color-green-800)}.text-muted-foreground,.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-orange-500{color:var(--color-orange-500)}.text-orange-800{color:var(--color-orange-800)}.text-popover-foreground{color:var(--popover-foreground)}.text-primary{color:var(--primary)}.text-primary-foreground{color:var(--primary-foreground)}.text-purple-500{color:var(--color-purple-500)}.text-purple-800{color:var(--color-purple-800)}.text-red-500{color:var(--color-red-500)}.text-red-800{color:var(--color-red-800)}.text-secondary-foreground{color:var(--secondary-foreground)}.text-white{color:var(--color-white)}.text-yellow-500{color:var(--color-yellow-500)}.capitalize{text-transform:capitalize}.underline-offset-4{text-underline-offset:4px}.opacity-50{opacity:.5}.opacity-70{opacity:.7}.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-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-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--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-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px 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)}.ring-offset-background{--tw-ring-offset-color:var(--background)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition-all{transition-property:all;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))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.file\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\:bg-transparent::file-selector-button{background-color:#0000}.file\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\:text-foreground::file-selector-button{color:var(--foreground)}.placeholder\:text-muted-foreground::placeholder{color:var(--muted-foreground)}.focus-within\:relative:focus-within{position:relative}.focus-within\:z-20:focus-within{z-index:20}@media(hover:hover){.hover\:bg-accent:hover,.hover\:bg-accent\/50:hover{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-accent\/50:hover{background-color:color-mix(in oklab,var(--accent) 50%,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-muted\/50:hover{background-color:var(--muted)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-muted\/50:hover{background-color:color-mix(in oklab,var(--muted) 50%,transparent)}}.hover\:bg-primary:hover,.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-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\:text-accent-foreground:hover{color:var(--accent-foreground)}.hover\:text-primary-foreground:hover{color:var(--primary-foreground)}.hover\:text-red-600:hover{color:var(--color-red-600)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-80:hover{opacity:.8}.hover\:opacity-100:hover{opacity:1}}.focus\:bg-accent:focus{background-color:var(--accent)}.focus\:bg-primary:focus{background-color:var(--primary)}.focus\:text-accent-foreground:focus{color:var(--accent-foreground)}.focus\:text-primary-foreground:focus{color:var(--primary-foreground)}.focus\:text-red-500:focus{color:var(--color-red-500)}.focus\:ring-1:focus{--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\:ring-2:focus{--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)}.focus\:ring-ring:focus{--tw-ring-color:var(--ring)}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.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-2:focus-visible{--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)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color:var(--ring)}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.aria-selected\:bg-accent[aria-selected=true],.aria-selected\:bg-accent\/50[aria-selected=true]{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.aria-selected\:bg-accent\/50[aria-selected=true]{background-color:color-mix(in oklab,var(--accent) 50%,transparent)}}.aria-selected\:text-accent-foreground[aria-selected=true]{color:var(--accent-foreground)}.aria-selected\:text-muted-foreground[aria-selected=true]{color:var(--muted-foreground)}.aria-selected\:opacity-100[aria-selected=true]{opacity:1}.data-\[active\]\:bg-accent\/50[data-active]{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.data-\[active\]\:bg-accent\/50[data-active]{background-color:color-mix(in oklab,var(--accent) 50%,transparent)}}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[state\=closed\]\:animate-out[data-state=closed]{animation:.15s ease-in exit}.data-\[state\=open\]\:animate-in[data-state=open]{animation:.2s ease-out enter}.data-\[state\=open\]\:bg-accent\/50[data-state=open]{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.data-\[state\=open\]\:bg-accent\/50[data-state=open]{background-color:color-mix(in oklab,var(--accent) 50%,transparent)}}.data-\[state\=selected\]\:bg-muted[data-state=selected]{background-color:var(--muted)}@media(min-width:40rem){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:justify-end{justify-content:flex-end}:where(.sm\:space-y-0>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 0) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 0) * calc(1 - var(--tw-space-y-reverse)))}:where(.sm\:space-x-2>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing) * 2) * var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-x-reverse)))}:where(.sm\:space-x-4>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing) * 4) * var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-x-reverse)))}.sm\:rounded-lg{border-radius:var(--radius)}.sm\:text-left{text-align:left}}@media(min-width:48rem){.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}@media(prefers-color-scheme:dark){.dark\:scale-0{--tw-scale-x:0%;--tw-scale-y:0%;--tw-scale-z:0%;scale:var(--tw-scale-x) var(--tw-scale-y)}.dark\:scale-100{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y)}.dark\:-rotate-90{rotate:-90deg}.dark\:rotate-0{rotate:none}.dark\:border-green-900{border-color:var(--color-green-900)}.dark\:border-red-900{border-color:var(--color-red-900)}.dark\:bg-blue-900{background-color:var(--color-blue-900)}.dark\:bg-gray-800{background-color:var(--color-gray-800)}.dark\:bg-green-950{background-color:var(--color-green-950)}.dark\:bg-input\/30{background-color:var(--input)}@supports (color:color-mix(in lab,red,red)){.dark\:bg-input\/30{background-color:color-mix(in oklab,var(--input) 30%,transparent)}}.dark\:bg-orange-900{background-color:var(--color-orange-900)}.dark\:bg-purple-900{background-color:var(--color-purple-900)}.dark\:bg-red-900{background-color:var(--color-red-900)}.dark\:bg-red-950{background-color:var(--color-red-950)}.dark\:text-blue-200{color:var(--color-blue-200)}.dark\:text-gray-300{color:var(--color-gray-300)}.dark\:text-green-200{color:var(--color-green-200)}.dark\:text-orange-200{color:var(--color-orange-200)}.dark\:text-purple-200{color:var(--color-purple-200)}.dark\:text-red-200{color:var(--color-red-200)}}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-4 svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_tr\]\:border-b tr{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-style:var(--tw-border-style);border-width:0}.\[\&\:has\(\[aria-selected\]\)\]\:bg-accent:has([aria-selected]),.\[\&\:has\(\[aria-selected\]\.day-outside\)\]\:bg-accent\/50:has([aria-selected].day-outside){background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.\[\&\:has\(\[aria-selected\]\.day-outside\)\]\:bg-accent\/50:has([aria-selected].day-outside){background-color:color-mix(in oklab,var(--accent) 50%,transparent)}}.\[\&\:has\(\[aria-selected\]\.day-range-end\)\]\:rounded-r-md:has([aria-selected].day-range-end){border-top-right-radius:calc(var(--radius) - 2px);border-bottom-right-radius:calc(var(--radius) - 2px)}.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]){padding-right:calc(var(--spacing) * 0)}.\[\&\>\[role\=checkbox\]\]\:translate-y-\[2px\]>[role=checkbox]{--tw-translate-y:2px;translate:var(--tw-translate-x) var(--tw-translate-y)}.\[\&\>span\]\:line-clamp-1>span{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.\[\&\>svg\]\:size-4>svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&\>svg\]\:shrink-0>svg{flex-shrink:0}.\[\&\>tr\]\:last\:border-b-0>tr:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}}@keyframes enter{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes exit{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.95)}}:root{--radius:.625rem;--background:oklch(100% 0 0);--foreground:oklch(14.5% 0 0);--card:oklch(100% 0 0);--card-foreground:oklch(14.5% 0 0);--popover:oklch(100% 0 0);--popover-foreground:oklch(14.5% 0 0);--primary:oklch(20.5% 0 0);--primary-foreground:oklch(98.5% 0 0);--secondary:oklch(96.5% 0 0);--secondary-foreground:oklch(20.5% 0 0);--muted:oklch(96.5% 0 0);--muted-foreground:oklch(55.6% 0 0);--accent:oklch(96.5% 0 0);--accent-foreground:oklch(20.5% 0 0);--destructive:oklch(57.7% .245 27.325);--border:oklch(92.1% 0 0);--input:oklch(92.1% 0 0);--ring:oklch(70.8% 0 0)}.dark{--background:oklch(14.5% 0 0);--foreground:oklch(98.5% 0 0);--card:oklch(17.5% 0 0);--card-foreground:oklch(98.5% 0 0);--popover:oklch(17.5% 0 0);--popover-foreground:oklch(98.5% 0 0);--primary:oklch(98.5% 0 0);--primary-foreground:oklch(20.5% 0 0);--secondary:oklch(26.9% 0 0);--secondary-foreground:oklch(98.5% 0 0);--muted:oklch(26.9% 0 0);--muted-foreground:oklch(70.8% 0 0);--accent:oklch(26.9% 0 0);--accent-foreground:oklch(98.5% 0 0);--destructive:oklch(39.6% .141 25.723);--border:oklch(26.9% 0 0);--input:oklch(26.9% 0 0);--ring:oklch(43.9% 0 0)}@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-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-space-x-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-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-duration{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>Hasna Todos</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-CpjKnPxm.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="/assets/index-DWpVlvWb.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="root"></div>
|
package/dist/cli/index.js
CHANGED
|
@@ -2383,6 +2383,13 @@ var init_database = __esm(() => {
|
|
|
2383
2383
|
`
|
|
2384
2384
|
ALTER TABLE agents ADD COLUMN role TEXT DEFAULT 'agent';
|
|
2385
2385
|
INSERT OR IGNORE INTO _migrations (id) VALUES (8);
|
|
2386
|
+
`,
|
|
2387
|
+
`
|
|
2388
|
+
ALTER TABLE plans ADD COLUMN task_list_id TEXT REFERENCES task_lists(id) ON DELETE SET NULL;
|
|
2389
|
+
ALTER TABLE plans ADD COLUMN agent_id TEXT;
|
|
2390
|
+
CREATE INDEX IF NOT EXISTS idx_plans_task_list ON plans(task_list_id);
|
|
2391
|
+
CREATE INDEX IF NOT EXISTS idx_plans_agent ON plans(agent_id);
|
|
2392
|
+
INSERT OR IGNORE INTO _migrations (id) VALUES (9);
|
|
2386
2393
|
`
|
|
2387
2394
|
];
|
|
2388
2395
|
});
|
|
@@ -3255,10 +3262,12 @@ function createPlan(input, db) {
|
|
|
3255
3262
|
const d = db || getDatabase();
|
|
3256
3263
|
const id = uuid();
|
|
3257
3264
|
const timestamp = now();
|
|
3258
|
-
d.run(`INSERT INTO plans (id, project_id, name, description, status, created_at, updated_at)
|
|
3259
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)`, [
|
|
3265
|
+
d.run(`INSERT INTO plans (id, project_id, task_list_id, agent_id, name, description, status, created_at, updated_at)
|
|
3266
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
3260
3267
|
id,
|
|
3261
3268
|
input.project_id || null,
|
|
3269
|
+
input.task_list_id || null,
|
|
3270
|
+
input.agent_id || null,
|
|
3262
3271
|
input.name,
|
|
3263
3272
|
input.description || null,
|
|
3264
3273
|
input.status || "active",
|
|
@@ -3298,6 +3307,14 @@ function updatePlan(id, input, db) {
|
|
|
3298
3307
|
sets.push("status = ?");
|
|
3299
3308
|
params.push(input.status);
|
|
3300
3309
|
}
|
|
3310
|
+
if (input.task_list_id !== undefined) {
|
|
3311
|
+
sets.push("task_list_id = ?");
|
|
3312
|
+
params.push(input.task_list_id);
|
|
3313
|
+
}
|
|
3314
|
+
if (input.agent_id !== undefined) {
|
|
3315
|
+
sets.push("agent_id = ?");
|
|
3316
|
+
params.push(input.agent_id);
|
|
3317
|
+
}
|
|
3301
3318
|
params.push(id);
|
|
3302
3319
|
d.run(`UPDATE plans SET ${sets.join(", ")} WHERE id = ?`, params);
|
|
3303
3320
|
return getPlan(id, d);
|
|
@@ -7965,7 +7982,7 @@ var init_mcp = __esm(() => {
|
|
|
7965
7982
|
init_types();
|
|
7966
7983
|
server = new McpServer({
|
|
7967
7984
|
name: "todos",
|
|
7968
|
-
version: "0.
|
|
7985
|
+
version: "0.9.15"
|
|
7969
7986
|
});
|
|
7970
7987
|
server.tool("create_task", "Create a new task", {
|
|
7971
7988
|
title: exports_external.string().describe("Task title"),
|
|
@@ -8967,6 +8984,70 @@ Dashboard not found at: ${dashboardDir}`);
|
|
|
8967
8984
|
return json({ error: e instanceof Error ? e.message : "Failed" }, 500, port);
|
|
8968
8985
|
}
|
|
8969
8986
|
}
|
|
8987
|
+
if (path === "/api/plans" && method === "GET") {
|
|
8988
|
+
const projectId = url.searchParams.get("project_id") || undefined;
|
|
8989
|
+
const plans = listPlans(projectId);
|
|
8990
|
+
return json(plans, 200, port);
|
|
8991
|
+
}
|
|
8992
|
+
if (path === "/api/plans" && method === "POST") {
|
|
8993
|
+
try {
|
|
8994
|
+
const body = await req.json();
|
|
8995
|
+
if (!body.name)
|
|
8996
|
+
return json({ error: "Missing 'name'" }, 400, port);
|
|
8997
|
+
const plan = createPlan({
|
|
8998
|
+
name: body.name,
|
|
8999
|
+
description: body.description,
|
|
9000
|
+
project_id: body.project_id,
|
|
9001
|
+
task_list_id: body.task_list_id,
|
|
9002
|
+
agent_id: body.agent_id,
|
|
9003
|
+
status: body.status
|
|
9004
|
+
});
|
|
9005
|
+
return json(plan, 201, port);
|
|
9006
|
+
} catch (e) {
|
|
9007
|
+
return json({ error: e instanceof Error ? e.message : "Failed to create plan" }, 500, port);
|
|
9008
|
+
}
|
|
9009
|
+
}
|
|
9010
|
+
if (path === "/api/plans/bulk" && method === "POST") {
|
|
9011
|
+
try {
|
|
9012
|
+
const body = await req.json();
|
|
9013
|
+
if (!body.ids?.length || body.action !== "delete")
|
|
9014
|
+
return json({ error: "Missing ids or invalid action" }, 400, port);
|
|
9015
|
+
let succeeded = 0;
|
|
9016
|
+
for (const id of body.ids) {
|
|
9017
|
+
if (deletePlan(id))
|
|
9018
|
+
succeeded++;
|
|
9019
|
+
}
|
|
9020
|
+
return json({ succeeded, failed: body.ids.length - succeeded }, 200, port);
|
|
9021
|
+
} catch (e) {
|
|
9022
|
+
return json({ error: e instanceof Error ? e.message : "Failed" }, 500, port);
|
|
9023
|
+
}
|
|
9024
|
+
}
|
|
9025
|
+
const planMatch = path.match(/^\/api\/plans\/([^/]+)$/);
|
|
9026
|
+
if (planMatch) {
|
|
9027
|
+
const id = planMatch[1];
|
|
9028
|
+
if (method === "GET") {
|
|
9029
|
+
const plan = getPlan(id);
|
|
9030
|
+
if (!plan)
|
|
9031
|
+
return json({ error: "Plan not found" }, 404, port);
|
|
9032
|
+
const tasks = listTasks({ plan_id: id });
|
|
9033
|
+
return json({ ...plan, tasks: tasks.map(taskToSummary) }, 200, port);
|
|
9034
|
+
}
|
|
9035
|
+
if (method === "PATCH") {
|
|
9036
|
+
try {
|
|
9037
|
+
const body = await req.json();
|
|
9038
|
+
const plan = updatePlan(id, body);
|
|
9039
|
+
return json(plan, 200, port);
|
|
9040
|
+
} catch (e) {
|
|
9041
|
+
return json({ error: e instanceof Error ? e.message : "Failed to update plan" }, 500, port);
|
|
9042
|
+
}
|
|
9043
|
+
}
|
|
9044
|
+
if (method === "DELETE") {
|
|
9045
|
+
const deleted = deletePlan(id);
|
|
9046
|
+
if (!deleted)
|
|
9047
|
+
return json({ error: "Plan not found" }, 404, port);
|
|
9048
|
+
return json({ success: true }, 200, port);
|
|
9049
|
+
}
|
|
9050
|
+
}
|
|
8970
9051
|
if (dashboardExists && (method === "GET" || method === "HEAD")) {
|
|
8971
9052
|
if (path !== "/") {
|
|
8972
9053
|
const filePath = join6(dashboardDir, path);
|
|
@@ -9003,6 +9084,7 @@ var init_serve = __esm(() => {
|
|
|
9003
9084
|
init_tasks();
|
|
9004
9085
|
init_projects();
|
|
9005
9086
|
init_agents();
|
|
9087
|
+
init_plans();
|
|
9006
9088
|
init_database();
|
|
9007
9089
|
MIME_TYPES = {
|
|
9008
9090
|
".html": "text/html; charset=utf-8",
|
package/dist/index.js
CHANGED
|
@@ -212,6 +212,13 @@ var MIGRATIONS = [
|
|
|
212
212
|
`
|
|
213
213
|
ALTER TABLE agents ADD COLUMN role TEXT DEFAULT 'agent';
|
|
214
214
|
INSERT OR IGNORE INTO _migrations (id) VALUES (8);
|
|
215
|
+
`,
|
|
216
|
+
`
|
|
217
|
+
ALTER TABLE plans ADD COLUMN task_list_id TEXT REFERENCES task_lists(id) ON DELETE SET NULL;
|
|
218
|
+
ALTER TABLE plans ADD COLUMN agent_id TEXT;
|
|
219
|
+
CREATE INDEX IF NOT EXISTS idx_plans_task_list ON plans(task_list_id);
|
|
220
|
+
CREATE INDEX IF NOT EXISTS idx_plans_agent ON plans(agent_id);
|
|
221
|
+
INSERT OR IGNORE INTO _migrations (id) VALUES (9);
|
|
215
222
|
`
|
|
216
223
|
];
|
|
217
224
|
var _db = null;
|
|
@@ -1044,10 +1051,12 @@ function createPlan(input, db) {
|
|
|
1044
1051
|
const d = db || getDatabase();
|
|
1045
1052
|
const id = uuid();
|
|
1046
1053
|
const timestamp = now();
|
|
1047
|
-
d.run(`INSERT INTO plans (id, project_id, name, description, status, created_at, updated_at)
|
|
1048
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)`, [
|
|
1054
|
+
d.run(`INSERT INTO plans (id, project_id, task_list_id, agent_id, name, description, status, created_at, updated_at)
|
|
1055
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
1049
1056
|
id,
|
|
1050
1057
|
input.project_id || null,
|
|
1058
|
+
input.task_list_id || null,
|
|
1059
|
+
input.agent_id || null,
|
|
1051
1060
|
input.name,
|
|
1052
1061
|
input.description || null,
|
|
1053
1062
|
input.status || "active",
|
|
@@ -1087,6 +1096,14 @@ function updatePlan(id, input, db) {
|
|
|
1087
1096
|
sets.push("status = ?");
|
|
1088
1097
|
params.push(input.status);
|
|
1089
1098
|
}
|
|
1099
|
+
if (input.task_list_id !== undefined) {
|
|
1100
|
+
sets.push("task_list_id = ?");
|
|
1101
|
+
params.push(input.task_list_id);
|
|
1102
|
+
}
|
|
1103
|
+
if (input.agent_id !== undefined) {
|
|
1104
|
+
sets.push("agent_id = ?");
|
|
1105
|
+
params.push(input.agent_id);
|
|
1106
|
+
}
|
|
1090
1107
|
params.push(id);
|
|
1091
1108
|
d.run(`UPDATE plans SET ${sets.join(", ")} WHERE id = ?`, params);
|
|
1092
1109
|
return getPlan(id, d);
|
package/dist/mcp/index.js
CHANGED
|
@@ -4273,6 +4273,13 @@ var MIGRATIONS = [
|
|
|
4273
4273
|
`
|
|
4274
4274
|
ALTER TABLE agents ADD COLUMN role TEXT DEFAULT 'agent';
|
|
4275
4275
|
INSERT OR IGNORE INTO _migrations (id) VALUES (8);
|
|
4276
|
+
`,
|
|
4277
|
+
`
|
|
4278
|
+
ALTER TABLE plans ADD COLUMN task_list_id TEXT REFERENCES task_lists(id) ON DELETE SET NULL;
|
|
4279
|
+
ALTER TABLE plans ADD COLUMN agent_id TEXT;
|
|
4280
|
+
CREATE INDEX IF NOT EXISTS idx_plans_task_list ON plans(task_list_id);
|
|
4281
|
+
CREATE INDEX IF NOT EXISTS idx_plans_agent ON plans(agent_id);
|
|
4282
|
+
INSERT OR IGNORE INTO _migrations (id) VALUES (9);
|
|
4276
4283
|
`
|
|
4277
4284
|
];
|
|
4278
4285
|
var _db = null;
|
|
@@ -4966,10 +4973,12 @@ function createPlan(input, db) {
|
|
|
4966
4973
|
const d = db || getDatabase();
|
|
4967
4974
|
const id = uuid();
|
|
4968
4975
|
const timestamp = now();
|
|
4969
|
-
d.run(`INSERT INTO plans (id, project_id, name, description, status, created_at, updated_at)
|
|
4970
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)`, [
|
|
4976
|
+
d.run(`INSERT INTO plans (id, project_id, task_list_id, agent_id, name, description, status, created_at, updated_at)
|
|
4977
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
4971
4978
|
id,
|
|
4972
4979
|
input.project_id || null,
|
|
4980
|
+
input.task_list_id || null,
|
|
4981
|
+
input.agent_id || null,
|
|
4973
4982
|
input.name,
|
|
4974
4983
|
input.description || null,
|
|
4975
4984
|
input.status || "active",
|
|
@@ -5009,6 +5018,14 @@ function updatePlan(id, input, db) {
|
|
|
5009
5018
|
sets.push("status = ?");
|
|
5010
5019
|
params.push(input.status);
|
|
5011
5020
|
}
|
|
5021
|
+
if (input.task_list_id !== undefined) {
|
|
5022
|
+
sets.push("task_list_id = ?");
|
|
5023
|
+
params.push(input.task_list_id);
|
|
5024
|
+
}
|
|
5025
|
+
if (input.agent_id !== undefined) {
|
|
5026
|
+
sets.push("agent_id = ?");
|
|
5027
|
+
params.push(input.agent_id);
|
|
5028
|
+
}
|
|
5012
5029
|
params.push(id);
|
|
5013
5030
|
d.run(`UPDATE plans SET ${sets.join(", ")} WHERE id = ?`, params);
|
|
5014
5031
|
return getPlan(id, d);
|
|
@@ -5670,7 +5687,7 @@ function syncWithAgents(agents, taskListIdByAgent, projectId, direction = "both"
|
|
|
5670
5687
|
// src/mcp/index.ts
|
|
5671
5688
|
var server = new McpServer({
|
|
5672
5689
|
name: "todos",
|
|
5673
|
-
version: "0.
|
|
5690
|
+
version: "0.9.15"
|
|
5674
5691
|
});
|
|
5675
5692
|
function formatError(error) {
|
|
5676
5693
|
if (error instanceof VersionConflictError)
|
package/dist/server/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
|
14
14
|
var __require = import.meta.require;
|
|
15
15
|
|
|
16
16
|
// src/types/index.ts
|
|
17
|
-
var VersionConflictError, TaskNotFoundError, ProjectNotFoundError, LockError, CompletionGuardError;
|
|
17
|
+
var VersionConflictError, TaskNotFoundError, ProjectNotFoundError, PlanNotFoundError, LockError, CompletionGuardError;
|
|
18
18
|
var init_types = __esm(() => {
|
|
19
19
|
VersionConflictError = class VersionConflictError extends Error {
|
|
20
20
|
taskId;
|
|
@@ -44,6 +44,14 @@ var init_types = __esm(() => {
|
|
|
44
44
|
this.name = "ProjectNotFoundError";
|
|
45
45
|
}
|
|
46
46
|
};
|
|
47
|
+
PlanNotFoundError = class PlanNotFoundError extends Error {
|
|
48
|
+
planId;
|
|
49
|
+
constructor(planId) {
|
|
50
|
+
super(`Plan not found: ${planId}`);
|
|
51
|
+
this.planId = planId;
|
|
52
|
+
this.name = "PlanNotFoundError";
|
|
53
|
+
}
|
|
54
|
+
};
|
|
47
55
|
LockError = class LockError extends Error {
|
|
48
56
|
taskId;
|
|
49
57
|
lockedBy;
|
|
@@ -372,6 +380,13 @@ var init_database = __esm(() => {
|
|
|
372
380
|
`
|
|
373
381
|
ALTER TABLE agents ADD COLUMN role TEXT DEFAULT 'agent';
|
|
374
382
|
INSERT OR IGNORE INTO _migrations (id) VALUES (8);
|
|
383
|
+
`,
|
|
384
|
+
`
|
|
385
|
+
ALTER TABLE plans ADD COLUMN task_list_id TEXT REFERENCES task_lists(id) ON DELETE SET NULL;
|
|
386
|
+
ALTER TABLE plans ADD COLUMN agent_id TEXT;
|
|
387
|
+
CREATE INDEX IF NOT EXISTS idx_plans_task_list ON plans(task_list_id);
|
|
388
|
+
CREATE INDEX IF NOT EXISTS idx_plans_agent ON plans(agent_id);
|
|
389
|
+
INSERT OR IGNORE INTO _migrations (id) VALUES (9);
|
|
375
390
|
`
|
|
376
391
|
];
|
|
377
392
|
});
|
|
@@ -930,6 +945,78 @@ function completeTask(id, agentId, db) {
|
|
|
930
945
|
// src/server/serve.ts
|
|
931
946
|
init_projects();
|
|
932
947
|
init_agents();
|
|
948
|
+
|
|
949
|
+
// src/db/plans.ts
|
|
950
|
+
init_types();
|
|
951
|
+
init_database();
|
|
952
|
+
function createPlan(input, db) {
|
|
953
|
+
const d = db || getDatabase();
|
|
954
|
+
const id = uuid();
|
|
955
|
+
const timestamp = now();
|
|
956
|
+
d.run(`INSERT INTO plans (id, project_id, task_list_id, agent_id, name, description, status, created_at, updated_at)
|
|
957
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
958
|
+
id,
|
|
959
|
+
input.project_id || null,
|
|
960
|
+
input.task_list_id || null,
|
|
961
|
+
input.agent_id || null,
|
|
962
|
+
input.name,
|
|
963
|
+
input.description || null,
|
|
964
|
+
input.status || "active",
|
|
965
|
+
timestamp,
|
|
966
|
+
timestamp
|
|
967
|
+
]);
|
|
968
|
+
return getPlan(id, d);
|
|
969
|
+
}
|
|
970
|
+
function getPlan(id, db) {
|
|
971
|
+
const d = db || getDatabase();
|
|
972
|
+
const row = d.query("SELECT * FROM plans WHERE id = ?").get(id);
|
|
973
|
+
return row;
|
|
974
|
+
}
|
|
975
|
+
function listPlans(projectId, db) {
|
|
976
|
+
const d = db || getDatabase();
|
|
977
|
+
if (projectId) {
|
|
978
|
+
return d.query("SELECT * FROM plans WHERE project_id = ? ORDER BY created_at DESC").all(projectId);
|
|
979
|
+
}
|
|
980
|
+
return d.query("SELECT * FROM plans ORDER BY created_at DESC").all();
|
|
981
|
+
}
|
|
982
|
+
function updatePlan(id, input, db) {
|
|
983
|
+
const d = db || getDatabase();
|
|
984
|
+
const plan = getPlan(id, d);
|
|
985
|
+
if (!plan)
|
|
986
|
+
throw new PlanNotFoundError(id);
|
|
987
|
+
const sets = ["updated_at = ?"];
|
|
988
|
+
const params = [now()];
|
|
989
|
+
if (input.name !== undefined) {
|
|
990
|
+
sets.push("name = ?");
|
|
991
|
+
params.push(input.name);
|
|
992
|
+
}
|
|
993
|
+
if (input.description !== undefined) {
|
|
994
|
+
sets.push("description = ?");
|
|
995
|
+
params.push(input.description);
|
|
996
|
+
}
|
|
997
|
+
if (input.status !== undefined) {
|
|
998
|
+
sets.push("status = ?");
|
|
999
|
+
params.push(input.status);
|
|
1000
|
+
}
|
|
1001
|
+
if (input.task_list_id !== undefined) {
|
|
1002
|
+
sets.push("task_list_id = ?");
|
|
1003
|
+
params.push(input.task_list_id);
|
|
1004
|
+
}
|
|
1005
|
+
if (input.agent_id !== undefined) {
|
|
1006
|
+
sets.push("agent_id = ?");
|
|
1007
|
+
params.push(input.agent_id);
|
|
1008
|
+
}
|
|
1009
|
+
params.push(id);
|
|
1010
|
+
d.run(`UPDATE plans SET ${sets.join(", ")} WHERE id = ?`, params);
|
|
1011
|
+
return getPlan(id, d);
|
|
1012
|
+
}
|
|
1013
|
+
function deletePlan(id, db) {
|
|
1014
|
+
const d = db || getDatabase();
|
|
1015
|
+
const result = d.run("DELETE FROM plans WHERE id = ?", [id]);
|
|
1016
|
+
return result.changes > 0;
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
// src/server/serve.ts
|
|
933
1020
|
init_database();
|
|
934
1021
|
function resolveDashboardDir() {
|
|
935
1022
|
const candidates = [];
|
|
@@ -1280,6 +1367,70 @@ Dashboard not found at: ${dashboardDir}`);
|
|
|
1280
1367
|
return json({ error: e instanceof Error ? e.message : "Failed" }, 500, port);
|
|
1281
1368
|
}
|
|
1282
1369
|
}
|
|
1370
|
+
if (path === "/api/plans" && method === "GET") {
|
|
1371
|
+
const projectId = url.searchParams.get("project_id") || undefined;
|
|
1372
|
+
const plans = listPlans(projectId);
|
|
1373
|
+
return json(plans, 200, port);
|
|
1374
|
+
}
|
|
1375
|
+
if (path === "/api/plans" && method === "POST") {
|
|
1376
|
+
try {
|
|
1377
|
+
const body = await req.json();
|
|
1378
|
+
if (!body.name)
|
|
1379
|
+
return json({ error: "Missing 'name'" }, 400, port);
|
|
1380
|
+
const plan = createPlan({
|
|
1381
|
+
name: body.name,
|
|
1382
|
+
description: body.description,
|
|
1383
|
+
project_id: body.project_id,
|
|
1384
|
+
task_list_id: body.task_list_id,
|
|
1385
|
+
agent_id: body.agent_id,
|
|
1386
|
+
status: body.status
|
|
1387
|
+
});
|
|
1388
|
+
return json(plan, 201, port);
|
|
1389
|
+
} catch (e) {
|
|
1390
|
+
return json({ error: e instanceof Error ? e.message : "Failed to create plan" }, 500, port);
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
if (path === "/api/plans/bulk" && method === "POST") {
|
|
1394
|
+
try {
|
|
1395
|
+
const body = await req.json();
|
|
1396
|
+
if (!body.ids?.length || body.action !== "delete")
|
|
1397
|
+
return json({ error: "Missing ids or invalid action" }, 400, port);
|
|
1398
|
+
let succeeded = 0;
|
|
1399
|
+
for (const id of body.ids) {
|
|
1400
|
+
if (deletePlan(id))
|
|
1401
|
+
succeeded++;
|
|
1402
|
+
}
|
|
1403
|
+
return json({ succeeded, failed: body.ids.length - succeeded }, 200, port);
|
|
1404
|
+
} catch (e) {
|
|
1405
|
+
return json({ error: e instanceof Error ? e.message : "Failed" }, 500, port);
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
const planMatch = path.match(/^\/api\/plans\/([^/]+)$/);
|
|
1409
|
+
if (planMatch) {
|
|
1410
|
+
const id = planMatch[1];
|
|
1411
|
+
if (method === "GET") {
|
|
1412
|
+
const plan = getPlan(id);
|
|
1413
|
+
if (!plan)
|
|
1414
|
+
return json({ error: "Plan not found" }, 404, port);
|
|
1415
|
+
const tasks = listTasks({ plan_id: id });
|
|
1416
|
+
return json({ ...plan, tasks: tasks.map(taskToSummary) }, 200, port);
|
|
1417
|
+
}
|
|
1418
|
+
if (method === "PATCH") {
|
|
1419
|
+
try {
|
|
1420
|
+
const body = await req.json();
|
|
1421
|
+
const plan = updatePlan(id, body);
|
|
1422
|
+
return json(plan, 200, port);
|
|
1423
|
+
} catch (e) {
|
|
1424
|
+
return json({ error: e instanceof Error ? e.message : "Failed to update plan" }, 500, port);
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
if (method === "DELETE") {
|
|
1428
|
+
const deleted = deletePlan(id);
|
|
1429
|
+
if (!deleted)
|
|
1430
|
+
return json({ error: "Plan not found" }, 404, port);
|
|
1431
|
+
return json({ success: true }, 200, port);
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1283
1434
|
if (dashboardExists && (method === "GET" || method === "HEAD")) {
|
|
1284
1435
|
if (path !== "/") {
|
|
1285
1436
|
const filePath = join3(dashboardDir, path);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/todos",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.17",
|
|
4
4
|
"description": "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -25,7 +25,6 @@
|
|
|
25
25
|
"scripts": {
|
|
26
26
|
"build": "cd dashboard && bun run build && cd .. && bun build src/cli/index.tsx --outdir dist/cli --target bun --external ink --external react --external chalk --external @modelcontextprotocol/sdk && bun build src/mcp/index.ts --outdir dist/mcp --target bun --external @modelcontextprotocol/sdk && bun build src/server/index.ts --outdir dist/server --target bun && bun build src/index.ts --outdir dist --target bun && tsc --emitDeclarationOnly --outDir dist",
|
|
27
27
|
"build:dashboard": "cd dashboard && bun run build",
|
|
28
|
-
"postinstall": "cd dashboard && bun install",
|
|
29
28
|
"typecheck": "tsc --noEmit",
|
|
30
29
|
"test": "bun test",
|
|
31
30
|
"dev:cli": "bun run src/cli/index.tsx",
|
|
@@ -45,10 +44,23 @@
|
|
|
45
44
|
"cli",
|
|
46
45
|
"dashboard"
|
|
47
46
|
],
|
|
48
|
-
"
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
},
|
|
50
|
+
"repository": {
|
|
51
|
+
"type": "git",
|
|
52
|
+
"url": "https://github.com/hasna/open-todos.git"
|
|
53
|
+
},
|
|
54
|
+
"homepage": "https://github.com/hasna/open-todos",
|
|
55
|
+
"bugs": {
|
|
56
|
+
"url": "https://github.com/hasna/open-todos/issues"
|
|
57
|
+
},
|
|
58
|
+
"engines": {
|
|
59
|
+
"bun": ">=1.0.0"
|
|
60
|
+
},
|
|
61
|
+
"author": "Andrei Hasna <andrei@hasna.com>",
|
|
49
62
|
"license": "Apache-2.0",
|
|
50
63
|
"dependencies": {
|
|
51
|
-
"@hasna/todos": "^0.9.11",
|
|
52
64
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
53
65
|
"chalk": "^5.4.1",
|
|
54
66
|
"commander": "^13.1.0",
|