xiaozuoassistant 0.1.56 → 0.1.59
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 +19 -8
- package/bin/cli.js +32 -4
- package/dist/client/assets/{browser-ponyfill-DwVSZq2q.js → browser-ponyfill-Ch3dXIqx.js} +1 -1
- package/dist/client/assets/index-Db2x2ZNV.js +176 -0
- package/dist/client/assets/index-OCMDYWfd.css +1 -0
- package/dist/client/index.html +2 -2
- package/dist/client/locales/zh/translation.json +3 -1
- package/dist/server/core/memories/manager.js +3 -0
- package/dist/server/core/memories/short-term.js +24 -1
- package/dist/server/core/memories/structured.js +212 -19
- package/dist/server/index.js +170 -2
- package/package.json +1 -1
- package/public/locales/zh/translation.json +3 -1
- package/dist/client/assets/index-DJdLRlkB.css +0 -1
- package/dist/client/assets/index-DOFAvfov.js +0 -166
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}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;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.top-0{top:0}.z-10{z-index:10}.z-50{z-index:50}.z-\[60\]{z-index:60}.-m-6{margin:-1.5rem}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.h-16{height:4rem}.h-2{height:.5rem}.h-4{height:1rem}.h-8{height:2rem}.h-\[60vh\]{height:60vh}.h-full{height:100%}.h-screen{height:100vh}.max-h-\[200px\]{max-height:200px}.max-h-\[70vh\]{max-height:70vh}.max-h-\[90vh\]{max-height:90vh}.min-h-\[120px\]{min-height:120px}.min-h-\[300px\]{min-height:300px}.min-h-\[50px\]{min-height:50px}.w-16{width:4rem}.w-28{width:7rem}.w-4{width:1rem}.w-8{width:2rem}.w-\[260px\]{width:260px}.w-full{width:100%}.w-screen{width:100vw}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-4xl{max-width:56rem}.max-w-\[46vw\]{max-width:46vw}.max-w-\[85\%\]{max-width:85%}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-xl{max-width:36rem}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.rounded-bl-none{border-bottom-left-radius:0}.rounded-br-none{border-bottom-right-radius:0}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-none{border-style:none}.border-black\/10{border-color:#0000001a}.border-blue-100{--tw-border-opacity: 1;border-color:rgb(219 234 254 / var(--tw-border-opacity, 1))}.border-blue-600{--tw-border-opacity: 1;border-color:rgb(37 99 235 / var(--tw-border-opacity, 1))}.border-gray-100{--tw-border-opacity: 1;border-color:rgb(243 244 246 / var(--tw-border-opacity, 1))}.border-gray-200{--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1))}.border-gray-300{--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1))}.border-gray-700{--tw-border-opacity: 1;border-color:rgb(55 65 81 / var(--tw-border-opacity, 1))}.border-gray-800{--tw-border-opacity: 1;border-color:rgb(31 41 55 / var(--tw-border-opacity, 1))}.border-green-200{--tw-border-opacity: 1;border-color:rgb(187 247 208 / var(--tw-border-opacity, 1))}.border-red-200{--tw-border-opacity: 1;border-color:rgb(254 202 202 / var(--tw-border-opacity, 1))}.bg-black\/20{background-color:#0003}.bg-black\/40{background-color:#0006}.bg-black\/50{background-color:#00000080}.bg-blue-50{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.bg-blue-600{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1))}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.bg-gray-200{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.bg-gray-50{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.bg-gray-800{--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.bg-gray-900{--tw-bg-opacity: 1;background-color:rgb(17 24 39 / var(--tw-bg-opacity, 1))}.bg-green-50{--tw-bg-opacity: 1;background-color:rgb(240 253 244 / var(--tw-bg-opacity, 1))}.bg-red-50{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.bg-teal-600{--tw-bg-opacity: 1;background-color:rgb(13 148 136 / var(--tw-bg-opacity, 1))}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-white\/80{background-color:#fffc}.fill-current{fill:currentColor}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-2\.5{padding:.625rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-20{padding-top:5rem;padding-bottom:5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-2{padding-bottom:.5rem}.pt-2{padding-top:.5rem}.pt-6{padding-top:1.5rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.font-sans{font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"}.text-2xl{font-size:1.5rem;line-height:2rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-\[15px\]{font-size:15px}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.leading-relaxed{line-height:1.625}.tracking-tight{letter-spacing:-.025em}.tracking-wider{letter-spacing:.05em}.text-black{--tw-text-opacity: 1;color:rgb(0 0 0 / var(--tw-text-opacity, 1))}.text-blue-400{--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-blue-800{--tw-text-opacity: 1;color:rgb(30 64 175 / var(--tw-text-opacity, 1))}.text-gray-300{--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}.text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-700{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-gray-800{--tw-text-opacity: 1;color:rgb(31 41 55 / var(--tw-text-opacity, 1))}.text-gray-900{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.text-green-700{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-red-700{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-yellow-500{--tw-text-opacity: 1;color:rgb(234 179 8 / var(--tw-text-opacity, 1))}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.accent-blue-600{accent-color:#2563eb}.opacity-0{opacity:0}.opacity-50{opacity:.5}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.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)}.backdrop-blur-md{--tw-backdrop-blur: blur(12px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}:root{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;line-height:1.5;font-weight:400;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.custom-scrollbar::-webkit-scrollbar{width:5px}.custom-scrollbar::-webkit-scrollbar-track{background:transparent}.custom-scrollbar::-webkit-scrollbar-thumb{background:#9b9b9b33;border-radius:10px}.custom-scrollbar::-webkit-scrollbar-thumb:hover{background:#9b9b9b66}.no-scrollbar::-webkit-scrollbar{display:none}.no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}.selection\:bg-blue-100 *::-moz-selection{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.selection\:bg-blue-100 *::selection{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.selection\:text-blue-900 *::-moz-selection{--tw-text-opacity: 1;color:rgb(30 58 138 / var(--tw-text-opacity, 1))}.selection\:text-blue-900 *::selection{--tw-text-opacity: 1;color:rgb(30 58 138 / var(--tw-text-opacity, 1))}.selection\:bg-blue-100::-moz-selection{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.selection\:bg-blue-100::selection{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.selection\:text-blue-900::-moz-selection{--tw-text-opacity: 1;color:rgb(30 58 138 / var(--tw-text-opacity, 1))}.selection\:text-blue-900::selection{--tw-text-opacity: 1;color:rgb(30 58 138 / var(--tw-text-opacity, 1))}.placeholder\:text-gray-400::-moz-placeholder{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.placeholder\:text-gray-400::placeholder{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.focus-within\:border-blue-400:focus-within{--tw-border-opacity: 1;border-color:rgb(96 165 250 / var(--tw-border-opacity, 1))}.focus-within\:ring-2:focus-within{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-within\:ring-blue-100:focus-within{--tw-ring-opacity: 1;--tw-ring-color: rgb(219 234 254 / var(--tw-ring-opacity, 1))}.hover\:bg-blue-50:hover{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.hover\:bg-blue-700:hover{--tw-bg-opacity: 1;background-color:rgb(29 78 216 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-100:hover{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-200:hover{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-50:hover{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-800:hover{--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-800\/50:hover{background-color:#1f293780}.hover\:bg-red-50:hover{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.hover\:bg-teal-700:hover{--tw-bg-opacity: 1;background-color:rgb(15 118 110 / var(--tw-bg-opacity, 1))}.hover\:text-blue-300:hover{--tw-text-opacity: 1;color:rgb(147 197 253 / var(--tw-text-opacity, 1))}.hover\:text-blue-700:hover{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.hover\:text-gray-600:hover{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.hover\:text-gray-700:hover{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.hover\:text-gray-800:hover{--tw-text-opacity: 1;color:rgb(31 41 55 / var(--tw-text-opacity, 1))}.hover\:text-red-400:hover{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.hover\:text-red-600:hover{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.hover\:text-white:hover{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-0:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-blue-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1))}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:opacity-70:disabled{opacity:.7}.group:hover .group-hover\:rotate-90{--tw-rotate: 90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:border-gray-600{--tw-border-opacity: 1;border-color:rgb(75 85 99 / var(--tw-border-opacity, 1))}.group:hover .group-hover\:text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.group:hover .group-hover\:text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.group:hover .group-hover\:text-yellow-600{--tw-text-opacity: 1;color:rgb(202 138 4 / var(--tw-text-opacity, 1))}.group:hover .group-hover\:opacity-100{opacity:1}
|
package/dist/client/index.html
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🍇</text></svg>" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>xiaozuoAssistant</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-Db2x2ZNV.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/assets/index-OCMDYWfd.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<div id="root"></div>
|
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
"assistant": "xiaozuoAssistant",
|
|
11
11
|
"thinking": "思考中...",
|
|
12
12
|
"inputPlaceholder": "给 xiaozuoAssistant 发送消息...",
|
|
13
|
-
"disclaimer": "xiaozuoAssistant 可能会犯错。请核对重要信息。"
|
|
13
|
+
"disclaimer": "xiaozuoAssistant 可能会犯错。请核对重要信息。",
|
|
14
|
+
"resetSession": "重置会话",
|
|
15
|
+
"confirmReset": "确定要重置当前会话记忆吗?这将清空所有消息历史。"
|
|
14
16
|
},
|
|
15
17
|
"sessionList": {
|
|
16
18
|
"title": "xiaozuoAssistant",
|
|
@@ -49,6 +49,9 @@ export class MemoryManager {
|
|
|
49
49
|
// structured info from the message. For MVP, we skip automatic extraction here
|
|
50
50
|
// but provide the API for the Brain to call explicitly.
|
|
51
51
|
}
|
|
52
|
+
async clearSessionMessages(sessionId) {
|
|
53
|
+
await this.shortTerm.clearMessages(sessionId);
|
|
54
|
+
}
|
|
52
55
|
updateClients() {
|
|
53
56
|
this.vector.updateClient();
|
|
54
57
|
}
|
|
@@ -126,7 +126,9 @@ export class ShortTermMemory {
|
|
|
126
126
|
workspace: normalizeWorkspace(input?.workspace),
|
|
127
127
|
createdAt: now,
|
|
128
128
|
updatedAt: now,
|
|
129
|
-
lastActiveAt: now
|
|
129
|
+
lastActiveAt: now,
|
|
130
|
+
projectId: input?.projectId,
|
|
131
|
+
notebookId: input?.notebookId,
|
|
130
132
|
};
|
|
131
133
|
await fs.ensureDir(meta.workspace);
|
|
132
134
|
const sessionDir = this.getSessionDir(id);
|
|
@@ -165,6 +167,8 @@ export class ShortTermMemory {
|
|
|
165
167
|
...current,
|
|
166
168
|
alias: patch.alias === null ? undefined : (patch.alias !== undefined ? (String(patch.alias).trim() || undefined) : current.alias),
|
|
167
169
|
workspace: patch.workspace !== undefined ? normalizeWorkspace(String(patch.workspace)) : current.workspace,
|
|
170
|
+
projectId: patch.projectId === null ? undefined : (patch.projectId !== undefined ? patch.projectId : current.projectId),
|
|
171
|
+
notebookId: patch.notebookId === null ? undefined : (patch.notebookId !== undefined ? patch.notebookId : current.notebookId),
|
|
168
172
|
updatedAt: Date.now()
|
|
169
173
|
};
|
|
170
174
|
await fs.ensureDir(next.workspace);
|
|
@@ -341,6 +345,25 @@ export class ShortTermMemory {
|
|
|
341
345
|
this.metaCache.set(sessionId, metas.find(m => m.id === sessionId));
|
|
342
346
|
}
|
|
343
347
|
}
|
|
348
|
+
async clearMessages(sessionId) {
|
|
349
|
+
await this.ensureReady();
|
|
350
|
+
const session = await this.getSession(sessionId);
|
|
351
|
+
if (!session)
|
|
352
|
+
throw new Error(`Session ${sessionId} not found`);
|
|
353
|
+
await fs.writeJson(this.getMessagesFile(sessionId), [], { spaces: 2 });
|
|
354
|
+
// Update timestamp
|
|
355
|
+
const metas = await this.loadIndex();
|
|
356
|
+
const idx = metas.findIndex(m => m.id === sessionId);
|
|
357
|
+
if (idx >= 0) {
|
|
358
|
+
metas[idx] = {
|
|
359
|
+
...metas[idx],
|
|
360
|
+
updatedAt: Date.now(),
|
|
361
|
+
lastActiveAt: Date.now()
|
|
362
|
+
};
|
|
363
|
+
await this.saveIndex(metas);
|
|
364
|
+
this.metaCache.set(sessionId, metas[idx]);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
344
367
|
async deleteSession(id) {
|
|
345
368
|
await this.ensureReady();
|
|
346
369
|
const metas = await this.loadIndex();
|
|
@@ -16,20 +16,21 @@ export class StructuredMemory {
|
|
|
16
16
|
return StructuredMemory.instance;
|
|
17
17
|
}
|
|
18
18
|
initTables() {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
19
|
+
try {
|
|
20
|
+
// Facts table: key-value or simple structured data
|
|
21
|
+
this.db.prepare(`
|
|
22
|
+
CREATE TABLE IF NOT EXISTS facts (
|
|
23
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
24
|
+
category TEXT NOT NULL,
|
|
25
|
+
key TEXT NOT NULL,
|
|
26
|
+
value TEXT NOT NULL,
|
|
27
|
+
confidence REAL DEFAULT 1.0,
|
|
28
|
+
source TEXT,
|
|
29
|
+
timestamp INTEGER
|
|
30
|
+
)
|
|
31
|
+
`).run();
|
|
32
|
+
// User Profile: specialized facts (multi-user)
|
|
33
|
+
this.db.prepare(`
|
|
33
34
|
CREATE TABLE IF NOT EXISTS user_profile (
|
|
34
35
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
35
36
|
user_id TEXT NOT NULL,
|
|
@@ -39,9 +40,9 @@ export class StructuredMemory {
|
|
|
39
40
|
UNIQUE(user_id, key)
|
|
40
41
|
)
|
|
41
42
|
`).run();
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
this.migrateUserProfileIfNeeded();
|
|
44
|
+
// Graph nodes (Entities)
|
|
45
|
+
this.db.prepare(`
|
|
45
46
|
CREATE TABLE IF NOT EXISTS entities (
|
|
46
47
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
47
48
|
name TEXT UNIQUE NOT NULL,
|
|
@@ -49,8 +50,8 @@ export class StructuredMemory {
|
|
|
49
50
|
metadata TEXT
|
|
50
51
|
)
|
|
51
52
|
`).run();
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
// Graph edges (Relations)
|
|
54
|
+
this.db.prepare(`
|
|
54
55
|
CREATE TABLE IF NOT EXISTS relations (
|
|
55
56
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
56
57
|
source_id INTEGER,
|
|
@@ -61,6 +62,48 @@ export class StructuredMemory {
|
|
|
61
62
|
FOREIGN KEY(target_id) REFERENCES entities(id)
|
|
62
63
|
)
|
|
63
64
|
`).run();
|
|
65
|
+
// Projects
|
|
66
|
+
this.db.prepare(`
|
|
67
|
+
CREATE TABLE IF NOT EXISTS projects (
|
|
68
|
+
id TEXT PRIMARY KEY,
|
|
69
|
+
name TEXT NOT NULL,
|
|
70
|
+
description TEXT,
|
|
71
|
+
departments TEXT,
|
|
72
|
+
members TEXT,
|
|
73
|
+
directory TEXT,
|
|
74
|
+
created_at INTEGER,
|
|
75
|
+
updated_at INTEGER
|
|
76
|
+
)
|
|
77
|
+
`).run();
|
|
78
|
+
// Notebooks
|
|
79
|
+
this.db.prepare(`
|
|
80
|
+
CREATE TABLE IF NOT EXISTS notebooks (
|
|
81
|
+
id TEXT PRIMARY KEY,
|
|
82
|
+
name TEXT NOT NULL,
|
|
83
|
+
description TEXT,
|
|
84
|
+
created_at INTEGER,
|
|
85
|
+
updated_at INTEGER
|
|
86
|
+
)
|
|
87
|
+
`).run();
|
|
88
|
+
// Notes
|
|
89
|
+
this.db.prepare(`
|
|
90
|
+
CREATE TABLE IF NOT EXISTS notes (
|
|
91
|
+
id TEXT PRIMARY KEY,
|
|
92
|
+
notebook_id TEXT NOT NULL,
|
|
93
|
+
title TEXT NOT NULL,
|
|
94
|
+
content TEXT,
|
|
95
|
+
is_todo INTEGER DEFAULT 0,
|
|
96
|
+
done INTEGER DEFAULT 0,
|
|
97
|
+
created_at INTEGER,
|
|
98
|
+
updated_at INTEGER,
|
|
99
|
+
FOREIGN KEY(notebook_id) REFERENCES notebooks(id) ON DELETE CASCADE
|
|
100
|
+
)
|
|
101
|
+
`).run();
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
console.error('[StructuredMemory] initTables failed:', error);
|
|
105
|
+
throw error; // Rethrow to stop startup if DB is critical
|
|
106
|
+
}
|
|
64
107
|
}
|
|
65
108
|
migrateUserProfileIfNeeded() {
|
|
66
109
|
try {
|
|
@@ -169,4 +212,154 @@ export class StructuredMemory {
|
|
|
169
212
|
.run(source.id, target.id, relation);
|
|
170
213
|
}
|
|
171
214
|
}
|
|
215
|
+
// --- Projects ---
|
|
216
|
+
createProject(id, name, description, departments, members, directory) {
|
|
217
|
+
const now = Date.now();
|
|
218
|
+
this.db.prepare(`
|
|
219
|
+
INSERT INTO projects (id, name, description, departments, members, directory, created_at, updated_at)
|
|
220
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
221
|
+
`).run(id, name, description || null, departments || null, members || null, directory || null, now, now);
|
|
222
|
+
}
|
|
223
|
+
getProject(id) {
|
|
224
|
+
const row = this.db.prepare('SELECT * FROM projects WHERE id = ?').get(id);
|
|
225
|
+
if (!row)
|
|
226
|
+
return null;
|
|
227
|
+
return {
|
|
228
|
+
id: row.id,
|
|
229
|
+
name: row.name,
|
|
230
|
+
description: row.description,
|
|
231
|
+
departments: row.departments,
|
|
232
|
+
members: row.members,
|
|
233
|
+
directory: row.directory,
|
|
234
|
+
createdAt: row.created_at,
|
|
235
|
+
updatedAt: row.updated_at
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
updateProject(id, patch) {
|
|
239
|
+
const current = this.getProject(id);
|
|
240
|
+
if (!current)
|
|
241
|
+
throw new Error('Project not found');
|
|
242
|
+
const next = { ...current, ...patch };
|
|
243
|
+
const now = Date.now();
|
|
244
|
+
this.db.prepare(`
|
|
245
|
+
UPDATE projects SET name = ?, description = ?, departments = ?, members = ?, directory = ?, updated_at = ?
|
|
246
|
+
WHERE id = ?
|
|
247
|
+
`).run(next.name, next.description || null, next.departments || null, next.members || null, next.directory || null, now, id);
|
|
248
|
+
}
|
|
249
|
+
deleteProject(id) {
|
|
250
|
+
this.db.prepare('DELETE FROM projects WHERE id = ?').run(id);
|
|
251
|
+
}
|
|
252
|
+
listProjects() {
|
|
253
|
+
const rows = this.db.prepare('SELECT * FROM projects ORDER BY updated_at DESC').all();
|
|
254
|
+
return rows.map(row => ({
|
|
255
|
+
id: row.id,
|
|
256
|
+
name: row.name,
|
|
257
|
+
description: row.description,
|
|
258
|
+
departments: row.departments,
|
|
259
|
+
members: row.members,
|
|
260
|
+
directory: row.directory,
|
|
261
|
+
createdAt: row.created_at,
|
|
262
|
+
updatedAt: row.updated_at
|
|
263
|
+
}));
|
|
264
|
+
}
|
|
265
|
+
// --- Notebooks ---
|
|
266
|
+
createNotebook(id, name, description) {
|
|
267
|
+
const now = Date.now();
|
|
268
|
+
this.db.prepare(`
|
|
269
|
+
INSERT INTO notebooks (id, name, description, created_at, updated_at)
|
|
270
|
+
VALUES (?, ?, ?, ?, ?)
|
|
271
|
+
`).run(id, name, description || null, now, now);
|
|
272
|
+
}
|
|
273
|
+
getNotebook(id) {
|
|
274
|
+
const row = this.db.prepare('SELECT * FROM notebooks WHERE id = ?').get(id);
|
|
275
|
+
if (!row)
|
|
276
|
+
return null;
|
|
277
|
+
return {
|
|
278
|
+
id: row.id,
|
|
279
|
+
name: row.name,
|
|
280
|
+
description: row.description,
|
|
281
|
+
createdAt: row.created_at,
|
|
282
|
+
updatedAt: row.updated_at
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
updateNotebook(id, patch) {
|
|
286
|
+
const current = this.getNotebook(id);
|
|
287
|
+
if (!current)
|
|
288
|
+
throw new Error('Notebook not found');
|
|
289
|
+
const next = { ...current, ...patch };
|
|
290
|
+
const now = Date.now();
|
|
291
|
+
this.db.prepare(`
|
|
292
|
+
UPDATE notebooks SET name = ?, description = ?, updated_at = ?
|
|
293
|
+
WHERE id = ?
|
|
294
|
+
`).run(next.name, next.description || null, now, id);
|
|
295
|
+
}
|
|
296
|
+
deleteNotebook(id) {
|
|
297
|
+
this.db.prepare('DELETE FROM notebooks WHERE id = ?').run(id);
|
|
298
|
+
}
|
|
299
|
+
listNotebooks() {
|
|
300
|
+
const rows = this.db.prepare('SELECT * FROM notebooks ORDER BY updated_at DESC').all();
|
|
301
|
+
return rows.map(row => ({
|
|
302
|
+
id: row.id,
|
|
303
|
+
name: row.name,
|
|
304
|
+
description: row.description,
|
|
305
|
+
createdAt: row.created_at,
|
|
306
|
+
updatedAt: row.updated_at
|
|
307
|
+
}));
|
|
308
|
+
}
|
|
309
|
+
// --- Notes ---
|
|
310
|
+
createNote(id, notebookId, title, content, isTodo = false, done = false) {
|
|
311
|
+
const now = Date.now();
|
|
312
|
+
this.db.prepare(`
|
|
313
|
+
INSERT INTO notes (id, notebook_id, title, content, is_todo, done, created_at, updated_at)
|
|
314
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
315
|
+
`).run(id, notebookId, title, content || null, isTodo ? 1 : 0, done ? 1 : 0, now, now);
|
|
316
|
+
}
|
|
317
|
+
getNote(id) {
|
|
318
|
+
const row = this.db.prepare('SELECT * FROM notes WHERE id = ?').get(id);
|
|
319
|
+
if (!row)
|
|
320
|
+
return null;
|
|
321
|
+
return {
|
|
322
|
+
id: row.id,
|
|
323
|
+
notebookId: row.notebook_id,
|
|
324
|
+
title: row.title,
|
|
325
|
+
content: row.content,
|
|
326
|
+
isTodo: !!row.is_todo,
|
|
327
|
+
done: !!row.done,
|
|
328
|
+
createdAt: row.created_at,
|
|
329
|
+
updatedAt: row.updated_at
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
updateNote(id, patch) {
|
|
333
|
+
const current = this.getNote(id);
|
|
334
|
+
if (!current)
|
|
335
|
+
throw new Error('Note not found');
|
|
336
|
+
const next = { ...current, ...patch };
|
|
337
|
+
const now = Date.now();
|
|
338
|
+
this.db.prepare(`
|
|
339
|
+
UPDATE notes SET title = ?, content = ?, is_todo = ?, done = ?, updated_at = ?
|
|
340
|
+
WHERE id = ?
|
|
341
|
+
`).run(next.title, next.content || null, next.isTodo ? 1 : 0, next.done ? 1 : 0, now, id);
|
|
342
|
+
}
|
|
343
|
+
deleteNote(id) {
|
|
344
|
+
this.db.prepare('DELETE FROM notes WHERE id = ?').run(id);
|
|
345
|
+
}
|
|
346
|
+
listNotes(notebookId) {
|
|
347
|
+
let rows;
|
|
348
|
+
if (notebookId) {
|
|
349
|
+
rows = this.db.prepare('SELECT * FROM notes WHERE notebook_id = ? ORDER BY created_at DESC').all(notebookId);
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
rows = this.db.prepare('SELECT * FROM notes ORDER BY created_at DESC').all();
|
|
353
|
+
}
|
|
354
|
+
return rows.map(row => ({
|
|
355
|
+
id: row.id,
|
|
356
|
+
notebookId: row.notebook_id,
|
|
357
|
+
title: row.title,
|
|
358
|
+
content: row.content,
|
|
359
|
+
isTodo: !!row.is_todo,
|
|
360
|
+
done: !!row.done,
|
|
361
|
+
createdAt: row.created_at,
|
|
362
|
+
updatedAt: row.updated_at
|
|
363
|
+
}));
|
|
364
|
+
}
|
|
172
365
|
}
|
package/dist/server/index.js
CHANGED
|
@@ -140,8 +140,8 @@ app.post('/api/sessions/:id/messages', async (req, res) => {
|
|
|
140
140
|
// 更新会话元信息
|
|
141
141
|
app.patch('/api/sessions/:id', async (req, res) => {
|
|
142
142
|
try {
|
|
143
|
-
const { alias, workspace, context } = req.body || {};
|
|
144
|
-
const meta = await memory.updateSessionMeta(req.params.id, { alias, workspace, context });
|
|
143
|
+
const { alias, workspace, context, projectId, notebookId } = req.body || {};
|
|
144
|
+
const meta = await memory.updateSessionMeta(req.params.id, { alias, workspace, context, projectId: projectId || null, notebookId: notebookId || null });
|
|
145
145
|
res.json(meta);
|
|
146
146
|
}
|
|
147
147
|
catch (e) {
|
|
@@ -168,6 +168,21 @@ app.post('/api/sessions/:id/persist', async (req, res) => {
|
|
|
168
168
|
res.status(500).json({ error: msg });
|
|
169
169
|
}
|
|
170
170
|
});
|
|
171
|
+
// 重置会话消息
|
|
172
|
+
app.post('/api/sessions/:id/reset', async (req, res) => {
|
|
173
|
+
try {
|
|
174
|
+
await memory.clearSessionMessages(req.params.id);
|
|
175
|
+
res.json({ status: 'success' });
|
|
176
|
+
}
|
|
177
|
+
catch (e) {
|
|
178
|
+
const msg = String(e?.message || 'Unknown error');
|
|
179
|
+
if (msg.toLowerCase().includes('not found')) {
|
|
180
|
+
res.status(404).json({ error: 'Session not found' });
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
res.status(500).json({ error: msg });
|
|
184
|
+
}
|
|
185
|
+
});
|
|
171
186
|
// 删除会话
|
|
172
187
|
app.delete('/api/sessions/:id', async (req, res) => {
|
|
173
188
|
try {
|
|
@@ -306,6 +321,142 @@ app.post('/api/scheduler/run', async (req, res) => {
|
|
|
306
321
|
res.status(500).json({ status: 'error', message: e.message });
|
|
307
322
|
}
|
|
308
323
|
});
|
|
324
|
+
// Projects CRUD
|
|
325
|
+
app.get('/api/projects', async (req, res) => {
|
|
326
|
+
try {
|
|
327
|
+
const list = memory.structured.listProjects();
|
|
328
|
+
res.json(list);
|
|
329
|
+
}
|
|
330
|
+
catch (e) {
|
|
331
|
+
res.status(500).json({ error: e.message });
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
app.post('/api/projects', async (req, res) => {
|
|
335
|
+
try {
|
|
336
|
+
const { id, name, description, departments, members, directory } = req.body;
|
|
337
|
+
if (!id || !name) {
|
|
338
|
+
res.status(400).json({ error: 'id and name are required' });
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
memory.structured.createProject(id, name, description, departments, members, directory);
|
|
342
|
+
const item = memory.structured.getProject(id);
|
|
343
|
+
res.json(item);
|
|
344
|
+
}
|
|
345
|
+
catch (e) {
|
|
346
|
+
res.status(500).json({ error: e.message });
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
app.patch('/api/projects/:id', async (req, res) => {
|
|
350
|
+
try {
|
|
351
|
+
const { name, description, departments, members, directory } = req.body;
|
|
352
|
+
memory.structured.updateProject(req.params.id, { name, description, departments, members, directory });
|
|
353
|
+
const item = memory.structured.getProject(req.params.id);
|
|
354
|
+
res.json(item);
|
|
355
|
+
}
|
|
356
|
+
catch (e) {
|
|
357
|
+
res.status(500).json({ error: e.message });
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
app.delete('/api/projects/:id', async (req, res) => {
|
|
361
|
+
try {
|
|
362
|
+
memory.structured.deleteProject(req.params.id);
|
|
363
|
+
res.json({ status: 'success' });
|
|
364
|
+
}
|
|
365
|
+
catch (e) {
|
|
366
|
+
res.status(500).json({ error: e.message });
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
// Notebooks CRUD
|
|
370
|
+
app.get('/api/notebooks', async (req, res) => {
|
|
371
|
+
try {
|
|
372
|
+
const list = memory.structured.listNotebooks();
|
|
373
|
+
res.json(list);
|
|
374
|
+
}
|
|
375
|
+
catch (e) {
|
|
376
|
+
res.status(500).json({ error: e.message });
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
app.post('/api/notebooks', async (req, res) => {
|
|
380
|
+
try {
|
|
381
|
+
const { id, name, description } = req.body;
|
|
382
|
+
if (!id || !name) {
|
|
383
|
+
res.status(400).json({ error: 'id and name are required' });
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
memory.structured.createNotebook(id, name, description);
|
|
387
|
+
const item = memory.structured.getNotebook(id);
|
|
388
|
+
res.json(item);
|
|
389
|
+
}
|
|
390
|
+
catch (e) {
|
|
391
|
+
res.status(500).json({ error: e.message });
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
app.patch('/api/notebooks/:id', async (req, res) => {
|
|
395
|
+
try {
|
|
396
|
+
const { name, description } = req.body;
|
|
397
|
+
memory.structured.updateNotebook(req.params.id, { name, description });
|
|
398
|
+
const item = memory.structured.getNotebook(req.params.id);
|
|
399
|
+
res.json(item);
|
|
400
|
+
}
|
|
401
|
+
catch (e) {
|
|
402
|
+
res.status(500).json({ error: e.message });
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
app.delete('/api/notebooks/:id', async (req, res) => {
|
|
406
|
+
try {
|
|
407
|
+
memory.structured.deleteNotebook(req.params.id);
|
|
408
|
+
res.json({ status: 'success' });
|
|
409
|
+
}
|
|
410
|
+
catch (e) {
|
|
411
|
+
res.status(500).json({ error: e.message });
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
// Notes CRUD
|
|
415
|
+
app.get('/api/notes', async (req, res) => {
|
|
416
|
+
try {
|
|
417
|
+
const notebookId = req.query.notebookId;
|
|
418
|
+
const list = memory.structured.listNotes(notebookId);
|
|
419
|
+
res.json(list);
|
|
420
|
+
}
|
|
421
|
+
catch (e) {
|
|
422
|
+
res.status(500).json({ error: e.message });
|
|
423
|
+
}
|
|
424
|
+
});
|
|
425
|
+
app.post('/api/notes', async (req, res) => {
|
|
426
|
+
try {
|
|
427
|
+
const { id, notebookId, title, content, isTodo, done } = req.body;
|
|
428
|
+
if (!id || !notebookId || !title) {
|
|
429
|
+
res.status(400).json({ error: 'id, notebookId and title are required' });
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
memory.structured.createNote(id, notebookId, title, content, isTodo, done);
|
|
433
|
+
const item = memory.structured.getNote(id);
|
|
434
|
+
res.json(item);
|
|
435
|
+
}
|
|
436
|
+
catch (e) {
|
|
437
|
+
res.status(500).json({ error: e.message });
|
|
438
|
+
}
|
|
439
|
+
});
|
|
440
|
+
app.patch('/api/notes/:id', async (req, res) => {
|
|
441
|
+
try {
|
|
442
|
+
const { title, content, isTodo, done } = req.body;
|
|
443
|
+
memory.structured.updateNote(req.params.id, { title, content, isTodo, done });
|
|
444
|
+
const item = memory.structured.getNote(req.params.id);
|
|
445
|
+
res.json(item);
|
|
446
|
+
}
|
|
447
|
+
catch (e) {
|
|
448
|
+
res.status(500).json({ error: e.message });
|
|
449
|
+
}
|
|
450
|
+
});
|
|
451
|
+
app.delete('/api/notes/:id', async (req, res) => {
|
|
452
|
+
try {
|
|
453
|
+
memory.structured.deleteNote(req.params.id);
|
|
454
|
+
res.json({ status: 'success' });
|
|
455
|
+
}
|
|
456
|
+
catch (e) {
|
|
457
|
+
res.status(500).json({ error: e.message });
|
|
458
|
+
}
|
|
459
|
+
});
|
|
309
460
|
import { ReadWordSkill, CreateWordSkill } from './skills/office-word.js';
|
|
310
461
|
import { ReadExcelSkill, CreateExcelSkill } from './skills/office-excel.js';
|
|
311
462
|
import { CreatePptxSkill } from './skills/office-ppt.js';
|
|
@@ -441,3 +592,20 @@ httpServer.listen(PORT, () => {
|
|
|
441
592
|
console.log(`Server running on port ${PORT}`);
|
|
442
593
|
console.log(`Socket.IO server running`);
|
|
443
594
|
});
|
|
595
|
+
httpServer.on('error', (err) => {
|
|
596
|
+
console.error('[Server] Startup error:', err);
|
|
597
|
+
if (err.code === 'EADDRINUSE') {
|
|
598
|
+
console.error(`Port ${PORT} is already in use.`);
|
|
599
|
+
process.exit(1);
|
|
600
|
+
}
|
|
601
|
+
});
|
|
602
|
+
// Graceful shutdown
|
|
603
|
+
const shutdown = () => {
|
|
604
|
+
console.log('Shutting down server...');
|
|
605
|
+
httpServer.close(() => {
|
|
606
|
+
console.log('Server closed');
|
|
607
|
+
process.exit(0);
|
|
608
|
+
});
|
|
609
|
+
};
|
|
610
|
+
process.on('SIGTERM', shutdown);
|
|
611
|
+
process.on('SIGINT', shutdown);
|
package/package.json
CHANGED
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
"assistant": "xiaozuoAssistant",
|
|
11
11
|
"thinking": "思考中...",
|
|
12
12
|
"inputPlaceholder": "给 xiaozuoAssistant 发送消息...",
|
|
13
|
-
"disclaimer": "xiaozuoAssistant 可能会犯错。请核对重要信息。"
|
|
13
|
+
"disclaimer": "xiaozuoAssistant 可能会犯错。请核对重要信息。",
|
|
14
|
+
"resetSession": "重置会话",
|
|
15
|
+
"confirmReset": "确定要重置当前会话记忆吗?这将清空所有消息历史。"
|
|
14
16
|
},
|
|
15
17
|
"sessionList": {
|
|
16
18
|
"title": "xiaozuoAssistant",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}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;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.top-0{top:0}.z-10{z-index:10}.z-50{z-index:50}.z-\[60\]{z-index:60}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.flex{display:flex}.table{display:table}.grid{display:grid}.h-16{height:4rem}.h-2{height:.5rem}.h-4{height:1rem}.h-8{height:2rem}.h-full{height:100%}.h-screen{height:100vh}.max-h-\[200px\]{max-height:200px}.max-h-\[70vh\]{max-height:70vh}.max-h-\[90vh\]{max-height:90vh}.min-h-\[120px\]{min-height:120px}.min-h-\[300px\]{min-height:300px}.min-h-\[50px\]{min-height:50px}.w-16{width:4rem}.w-28{width:7rem}.w-8{width:2rem}.w-\[260px\]{width:260px}.w-full{width:100%}.w-screen{width:100vw}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-\[46vw\]{max-width:46vw}.max-w-\[85\%\]{max-width:85%}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-xl{max-width:36rem}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.rounded-2xl{border-radius:1rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.rounded-bl-none{border-bottom-left-radius:0}.rounded-br-none{border-bottom-right-radius:0}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-none{border-style:none}.border-black\/10{border-color:#0000001a}.border-blue-100{--tw-border-opacity: 1;border-color:rgb(219 234 254 / var(--tw-border-opacity, 1))}.border-blue-600{--tw-border-opacity: 1;border-color:rgb(37 99 235 / var(--tw-border-opacity, 1))}.border-gray-100{--tw-border-opacity: 1;border-color:rgb(243 244 246 / var(--tw-border-opacity, 1))}.border-gray-200{--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1))}.border-gray-300{--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1))}.border-gray-700{--tw-border-opacity: 1;border-color:rgb(55 65 81 / var(--tw-border-opacity, 1))}.border-gray-800{--tw-border-opacity: 1;border-color:rgb(31 41 55 / var(--tw-border-opacity, 1))}.border-green-200{--tw-border-opacity: 1;border-color:rgb(187 247 208 / var(--tw-border-opacity, 1))}.border-red-200{--tw-border-opacity: 1;border-color:rgb(254 202 202 / var(--tw-border-opacity, 1))}.bg-black\/20{background-color:#0003}.bg-black\/50{background-color:#00000080}.bg-blue-50{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.bg-blue-600{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1))}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.bg-gray-200{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.bg-gray-50{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.bg-gray-800{--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.bg-gray-900{--tw-bg-opacity: 1;background-color:rgb(17 24 39 / var(--tw-bg-opacity, 1))}.bg-green-50{--tw-bg-opacity: 1;background-color:rgb(240 253 244 / var(--tw-bg-opacity, 1))}.bg-red-50{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.bg-teal-600{--tw-bg-opacity: 1;background-color:rgb(13 148 136 / var(--tw-bg-opacity, 1))}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-white\/80{background-color:#fffc}.fill-current{fill:currentColor}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-2\.5{padding:.625rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-20{padding-top:5rem;padding-bottom:5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-2{padding-bottom:.5rem}.pt-2{padding-top:.5rem}.pt-6{padding-top:1.5rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.font-sans{font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"}.text-2xl{font-size:1.5rem;line-height:2rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-\[15px\]{font-size:15px}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.leading-relaxed{line-height:1.625}.tracking-tight{letter-spacing:-.025em}.tracking-wider{letter-spacing:.05em}.text-black{--tw-text-opacity: 1;color:rgb(0 0 0 / var(--tw-text-opacity, 1))}.text-blue-400{--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-blue-800{--tw-text-opacity: 1;color:rgb(30 64 175 / var(--tw-text-opacity, 1))}.text-gray-300{--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}.text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-700{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-gray-800{--tw-text-opacity: 1;color:rgb(31 41 55 / var(--tw-text-opacity, 1))}.text-gray-900{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.text-green-700{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-red-700{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-yellow-500{--tw-text-opacity: 1;color:rgb(234 179 8 / var(--tw-text-opacity, 1))}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.accent-blue-600{accent-color:#2563eb}.opacity-0{opacity:0}.opacity-50{opacity:.5}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.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)}.backdrop-blur-md{--tw-backdrop-blur: blur(12px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}:root{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;line-height:1.5;font-weight:400;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.custom-scrollbar::-webkit-scrollbar{width:5px}.custom-scrollbar::-webkit-scrollbar-track{background:transparent}.custom-scrollbar::-webkit-scrollbar-thumb{background:#9b9b9b33;border-radius:10px}.custom-scrollbar::-webkit-scrollbar-thumb:hover{background:#9b9b9b66}.no-scrollbar::-webkit-scrollbar{display:none}.no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}.selection\:bg-blue-100 *::-moz-selection{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.selection\:bg-blue-100 *::selection{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.selection\:text-blue-900 *::-moz-selection{--tw-text-opacity: 1;color:rgb(30 58 138 / var(--tw-text-opacity, 1))}.selection\:text-blue-900 *::selection{--tw-text-opacity: 1;color:rgb(30 58 138 / var(--tw-text-opacity, 1))}.selection\:bg-blue-100::-moz-selection{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.selection\:bg-blue-100::selection{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.selection\:text-blue-900::-moz-selection{--tw-text-opacity: 1;color:rgb(30 58 138 / var(--tw-text-opacity, 1))}.selection\:text-blue-900::selection{--tw-text-opacity: 1;color:rgb(30 58 138 / var(--tw-text-opacity, 1))}.placeholder\:text-gray-400::-moz-placeholder{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.placeholder\:text-gray-400::placeholder{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.focus-within\:border-blue-400:focus-within{--tw-border-opacity: 1;border-color:rgb(96 165 250 / var(--tw-border-opacity, 1))}.focus-within\:ring-2:focus-within{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-within\:ring-blue-100:focus-within{--tw-ring-opacity: 1;--tw-ring-color: rgb(219 234 254 / var(--tw-ring-opacity, 1))}.hover\:bg-blue-50:hover{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.hover\:bg-blue-700:hover{--tw-bg-opacity: 1;background-color:rgb(29 78 216 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-100:hover{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-200:hover{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-50:hover{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-800:hover{--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-800\/50:hover{background-color:#1f293780}.hover\:bg-red-50:hover{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.hover\:bg-teal-700:hover{--tw-bg-opacity: 1;background-color:rgb(15 118 110 / var(--tw-bg-opacity, 1))}.hover\:text-blue-300:hover{--tw-text-opacity: 1;color:rgb(147 197 253 / var(--tw-text-opacity, 1))}.hover\:text-blue-700:hover{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.hover\:text-gray-600:hover{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.hover\:text-gray-700:hover{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.hover\:text-gray-800:hover{--tw-text-opacity: 1;color:rgb(31 41 55 / var(--tw-text-opacity, 1))}.hover\:text-red-400:hover{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.hover\:text-white:hover{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-0:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-blue-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1))}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-70:disabled{opacity:.7}.group:hover .group-hover\:rotate-90{--tw-rotate: 90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:border-gray-600{--tw-border-opacity: 1;border-color:rgb(75 85 99 / var(--tw-border-opacity, 1))}.group:hover .group-hover\:text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.group:hover .group-hover\:text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.group:hover .group-hover\:text-yellow-600{--tw-text-opacity: 1;color:rgb(202 138 4 / var(--tw-text-opacity, 1))}.group:hover .group-hover\:opacity-100{opacity:1}
|