@loghead/core 0.1.32 → 0.1.34

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.
@@ -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}.\!container{width:100%!important}.container{width:100%}@media (min-width: 640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media (min-width: 768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media (min-width: 1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media (min-width: 1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media (min-width: 1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.visible{visibility:visible}.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}.inset-x-0{left:0;right:0}.left-0{left:0}.right-2{right:.5rem}.top-0{top:0}.top-2{top:.5rem}.top-full{top:100%}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.z-\[100\]{z-index:100}.m-4{margin:1rem}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.ml-auto{margin-left:auto}.mr-2{margin-right:.5rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.block{display:block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-12{height:3rem}.h-16{height:4rem}.h-3{height:.75rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-full{height:100%}.h-screen{height:100vh}.max-h-48{max-height:12rem}.max-h-60{max-height:15rem}.max-h-\[70vh\]{max-height:70vh}.min-h-0{min-height:0px}.min-h-\[60px\]{min-height:60px}.min-h-screen{min-height:100vh}.w-12{width:3rem}.w-16{width:4rem}.w-3{width:.75rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-8{width:2rem}.w-80{width:20rem}.w-9{width:2.25rem}.w-full{width:100%}.w-screen{width:100vw}.min-w-0{min-width:0px}.max-w-4xl{max-width:56rem}.max-w-7xl{max-width:80rem}.max-w-lg{max-width:32rem}.max-w-sm{max-width:24rem}.max-w-xl{max-width:36rem}.flex-1{flex:1 1 0%}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.rotate-180{--tw-rotate: 180deg;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))}.rotate-\[30deg\]{--tw-rotate: 30deg;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))}.transform{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))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.cursor-pointer{cursor:pointer}.select-all{-webkit-user-select:all;-moz-user-select:all;user-select:all}.resize{resize:both}.list-inside{list-style-position:inside}.list-decimal{list-style-type:decimal}.columns-2{-moz-columns:2;columns:2}.columns-3{-moz-columns:3;columns:3}.columns-4{-moz-columns:4;columns:4}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-col{flex-direction:column}.items-start{align-items:flex-start}.items-center{align-items:center}.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}.gap-6{gap:1.5rem}.gap-x-6{-moz-column-gap:1.5rem;column-gap:1.5rem}.gap-y-2{row-gap:.5rem}.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))}.divide-x>:not([hidden])~:not([hidden]){--tw-divide-x-reverse: 0;border-right-width:calc(1px * var(--tw-divide-x-reverse));border-left-width:calc(1px * calc(1 - var(--tw-divide-x-reverse)))}.divide-zinc-800>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:rgb(39 39 42 / var(--tw-divide-opacity, 1))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.scroll-smooth{scroll-behavior:smooth}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-wrap{text-wrap:wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.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}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-l-4{border-left-width:4px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-current{border-color:currentColor}.border-emerald-500{--tw-border-opacity: 1;border-color:rgb(16 185 129 / var(--tw-border-opacity, 1))}.border-emerald-500\/30{border-color:#10b9814d}.border-emerald-500\/50{border-color:#10b98180}.border-green-500{--tw-border-opacity: 1;border-color:rgb(34 197 94 / var(--tw-border-opacity, 1))}.border-red-900{--tw-border-opacity: 1;border-color:rgb(127 29 29 / var(--tw-border-opacity, 1))}.border-transparent{border-color:transparent}.border-zinc-700{--tw-border-opacity: 1;border-color:rgb(63 63 70 / var(--tw-border-opacity, 1))}.border-zinc-800{--tw-border-opacity: 1;border-color:rgb(39 39 42 / var(--tw-border-opacity, 1))}.border-l-emerald-500{--tw-border-opacity: 1;border-left-color:rgb(16 185 129 / var(--tw-border-opacity, 1))}.border-l-red-500{--tw-border-opacity: 1;border-left-color:rgb(239 68 68 / var(--tw-border-opacity, 1))}.bg-\[\#00FF94\]\/10{background-color:#00ff941a}.bg-\[\#0d0d0d\]{--tw-bg-opacity: 1;background-color:rgb(13 13 13 / var(--tw-bg-opacity, 1))}.bg-black\/50{background-color:#00000080}.bg-black\/80{background-color:#000c}.bg-emerald-500\/10{background-color:#10b9811a}.bg-emerald-500\/20{background-color:#10b98133}.bg-emerald-600{--tw-bg-opacity: 1;background-color:rgb(5 150 105 / var(--tw-bg-opacity, 1))}.bg-emerald-600\/20{background-color:#05966933}.bg-emerald-900\/30{background-color:#064e3b4d}.bg-gray-900{--tw-bg-opacity: 1;background-color:rgb(17 24 39 / var(--tw-bg-opacity, 1))}.bg-red-500\/10{background-color:#ef44441a}.bg-red-900\/50{background-color:#7f1d1d80}.bg-transparent{background-color:transparent}.bg-yellow-500\/20{background-color:#eab30833}.bg-zinc-700{--tw-bg-opacity: 1;background-color:rgb(63 63 70 / var(--tw-bg-opacity, 1))}.bg-zinc-800{--tw-bg-opacity: 1;background-color:rgb(39 39 42 / var(--tw-bg-opacity, 1))}.bg-zinc-900{--tw-bg-opacity: 1;background-color:rgb(24 24 27 / var(--tw-bg-opacity, 1))}.bg-zinc-900\/40{background-color:#18181b66}.bg-zinc-900\/50{background-color:#18181b80}.bg-zinc-900\/60{background-color:#18181b99}.bg-zinc-950{--tw-bg-opacity: 1;background-color:rgb(9 9 11 / var(--tw-bg-opacity, 1))}.bg-zinc-950\/40{background-color:#09090b66}.bg-zinc-950\/50{background-color:#09090b80}.bg-zinc-950\/60{background-color:#09090b99}.bg-zinc-950\/80{background-color:#09090bcc}.object-contain{-o-object-fit:contain;object-fit:contain}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-0\.5{padding-left:.125rem;padding-right:.125rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.pl-2{padding-left:.5rem}.pr-12{padding-right:3rem}.pr-2{padding-right:.5rem}.pr-3{padding-right:.75rem}.pt-1{padding-top:.25rem}.pt-16{padding-top:4rem}.pt-2{padding-top:.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}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.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}.lowercase{text-transform:lowercase}.italic{font-style:italic}.leading-relaxed{line-height:1.625}.leading-tight{line-height:1.25}.tracking-wider{letter-spacing:.05em}.text-emerald-300{--tw-text-opacity: 1;color:rgb(110 231 183 / var(--tw-text-opacity, 1))}.text-emerald-400{--tw-text-opacity: 1;color:rgb(52 211 153 / var(--tw-text-opacity, 1))}.text-emerald-500{--tw-text-opacity: 1;color:rgb(16 185 129 / var(--tw-text-opacity, 1))}.text-gray-100{--tw-text-opacity: 1;color:rgb(243 244 246 / var(--tw-text-opacity, 1))}.text-green-500{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-yellow-200{--tw-text-opacity: 1;color:rgb(254 240 138 / var(--tw-text-opacity, 1))}.text-zinc-100{--tw-text-opacity: 1;color:rgb(244 244 245 / var(--tw-text-opacity, 1))}.text-zinc-200{--tw-text-opacity: 1;color:rgb(228 228 231 / var(--tw-text-opacity, 1))}.text-zinc-300{--tw-text-opacity: 1;color:rgb(212 212 216 / var(--tw-text-opacity, 1))}.text-zinc-400{--tw-text-opacity: 1;color:rgb(161 161 170 / var(--tw-text-opacity, 1))}.text-zinc-500{--tw-text-opacity: 1;color:rgb(113 113 122 / var(--tw-text-opacity, 1))}.text-zinc-600{--tw-text-opacity: 1;color:rgb(82 82 91 / var(--tw-text-opacity, 1))}.text-zinc-700{--tw-text-opacity: 1;color:rgb(63 63 70 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.placeholder-zinc-600::-moz-placeholder{--tw-placeholder-opacity: 1;color:rgb(82 82 91 / var(--tw-placeholder-opacity, 1))}.placeholder-zinc-600::placeholder{--tw-placeholder-opacity: 1;color:rgb(82 82 91 / var(--tw-placeholder-opacity, 1))}.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-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)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.blur{--tw-blur: blur(8px);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)}.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{--tw-backdrop-blur: blur(8px);-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{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.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-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-100{transition-duration:.1s}.duration-200{transition-duration:.2s}.placeholder\:text-zinc-500::-moz-placeholder{--tw-text-opacity: 1;color:rgb(113 113 122 / var(--tw-text-opacity, 1))}.placeholder\:text-zinc-500::placeholder{--tw-text-opacity: 1;color:rgb(113 113 122 / var(--tw-text-opacity, 1))}.hover\:border-zinc-700:hover{--tw-border-opacity: 1;border-color:rgb(63 63 70 / var(--tw-border-opacity, 1))}.hover\:border-zinc-800:hover{--tw-border-opacity: 1;border-color:rgb(39 39 42 / var(--tw-border-opacity, 1))}.hover\:bg-emerald-500:hover{--tw-bg-opacity: 1;background-color:rgb(16 185 129 / var(--tw-bg-opacity, 1))}.hover\:bg-emerald-600\/30:hover{background-color:#0596694d}.hover\:bg-emerald-900\/50:hover{background-color:#064e3b80}.hover\:bg-red-900:hover{--tw-bg-opacity: 1;background-color:rgb(127 29 29 / var(--tw-bg-opacity, 1))}.hover\:bg-zinc-700:hover{--tw-bg-opacity: 1;background-color:rgb(63 63 70 / var(--tw-bg-opacity, 1))}.hover\:bg-zinc-800:hover{--tw-bg-opacity: 1;background-color:rgb(39 39 42 / var(--tw-bg-opacity, 1))}.hover\:bg-zinc-900:hover{--tw-bg-opacity: 1;background-color:rgb(24 24 27 / var(--tw-bg-opacity, 1))}.hover\:bg-zinc-900\/20:hover{background-color:#18181b33}.hover\:bg-zinc-900\/40:hover{background-color:#18181b66}.hover\:bg-zinc-900\/60:hover{background-color:#18181b99}.hover\:text-white:hover{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.hover\:text-zinc-200:hover{--tw-text-opacity: 1;color:rgb(228 228 231 / var(--tw-text-opacity, 1))}.hover\:text-zinc-300:hover{--tw-text-opacity: 1;color:rgb(212 212 216 / var(--tw-text-opacity, 1))}.focus\:border-emerald-500:focus{--tw-border-opacity: 1;border-color:rgb(16 185 129 / var(--tw-border-opacity, 1))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.group:hover .group-hover\:bg-zinc-700{--tw-bg-opacity: 1;background-color:rgb(63 63 70 / var(--tw-bg-opacity, 1))}.group:hover .group-hover\:text-emerald-400{--tw-text-opacity: 1;color:rgb(52 211 153 / 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\:opacity-100{opacity:1}@media (min-width: 640px){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.sm\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:py-4{padding-top:1rem;padding-bottom:1rem}}@media (min-width: 768px){.md\:grid-cols-\[minmax\(220px\,auto\)_1fr\]{grid-template-columns:minmax(220px,auto) 1fr}}@media (min-width: 1024px){.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}
@@ -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>Loghead</title>
7
- <script type="module" crossorigin src="/assets/index-BtWnFjRZ.js"></script>
8
- <link rel="stylesheet" crossorigin href="/assets/index-BGOKjK0s.css">
7
+ <script type="module" crossorigin src="/assets/index-Bhs7GffT.js"></script>
8
+ <link rel="stylesheet" crossorigin href="/assets/index-DNKOkq6D.css">
9
9
  </head>
10
10
  <body>
11
11
  <div id="root"></div>
Binary file
@@ -90,8 +90,7 @@ class DbService {
90
90
  }
91
91
  const vectorJson = JSON.stringify(embedding);
92
92
  // Explicitly cast rowid to BigInt to ensure better-sqlite3 binds it as an INTEGER
93
- // Use REPLACE INTO to handle potential collisions gracefully
94
- client_1.db.prepare("REPLACE INTO vec_logs(rowid, embedding) VALUES (?, ?)").run(BigInt(rowid), vectorJson);
93
+ client_1.db.prepare("INSERT INTO vec_logs(rowid, embedding) VALUES (?, ?)").run(BigInt(rowid), vectorJson);
95
94
  }
96
95
  });
97
96
  try {
package/dist/types.js CHANGED
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
package/dist/ui/main.js CHANGED
@@ -1,12 +1,6 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.startTui = startTui;
7
- const auth_1 = require("../services/auth");
8
- const inquirer_1 = __importDefault(require("inquirer"));
9
- const chalk_1 = __importDefault(require("chalk"));
1
+ import { authService } from "../db/client.js";
2
+ import inquirer from "inquirer";
3
+ import chalk from "chalk";
10
4
  let title = `
11
5
  █████ █████ █████
12
6
  ▒▒███ ▒▒███ ▒▒███
@@ -19,22 +13,22 @@ let title = `
19
13
  ███ ▒███
20
14
  ▒▒██████
21
15
  ▒▒▒▒▒▒ `;
22
- async function startTui(db, token) {
16
+ export async function startTui(db, token) {
23
17
  const port = process.env.PORT || 4567;
24
18
  const showHeader = () => {
25
19
  console.clear();
26
- console.log(chalk_1.default.bold(title));
27
- console.log(chalk_1.default.bold(`\nServer URL :`) + " " + chalk_1.default.dim(`http://localhost:${port}`));
28
- console.log(chalk_1.default.bold(`MCP Token :`) + " " + chalk_1.default.dim(token) + "\n");
20
+ console.log(chalk.bold(title));
21
+ console.log(chalk.bold(`\nServer URL :`) + " " + chalk.dim(`http://localhost:${port}`));
22
+ console.log(chalk.bold(`MCP Token :`) + " " + chalk.dim(token) + "\n");
29
23
  };
30
24
  while (true) {
31
25
  showHeader();
32
- const projects = db.listProjects();
26
+ const projects = await db.listProjects();
33
27
  const projectChoices = projects.map(p => ({ name: p.name, value: p.id }));
34
- projectChoices.push(new inquirer_1.default.Separator());
35
- projectChoices.push({ name: chalk_1.default.green("+ Create Project"), value: "create_project" });
36
- projectChoices.push({ name: chalk_1.default.red("Exit"), value: "exit" });
37
- const { projectId } = await inquirer_1.default.prompt([{
28
+ projectChoices.push(new inquirer.Separator());
29
+ projectChoices.push({ name: chalk.green("+ Create Project"), value: "create_project" });
30
+ projectChoices.push({ name: chalk.red("Exit"), value: "exit" });
31
+ const { projectId } = await inquirer.prompt([{
38
32
  type: "list",
39
33
  name: "projectId",
40
34
  message: "Select a project",
@@ -45,31 +39,31 @@ async function startTui(db, token) {
45
39
  if (projectId === "exit")
46
40
  break;
47
41
  if (projectId === "create_project") {
48
- const { name } = await inquirer_1.default.prompt([{
42
+ const { name } = await inquirer.prompt([{
49
43
  type: "input",
50
44
  name: "name",
51
45
  message: "Project Name:",
52
46
  prefix: "💡"
53
47
  }]);
54
48
  if (name) {
55
- db.createProject(name);
49
+ await db.createProject(name);
56
50
  }
57
51
  continue;
58
52
  }
59
53
  // List streams for project
60
54
  while (true) {
61
55
  showHeader();
62
- const project = projects.find(p => p.id === projectId);
63
- console.log(chalk_1.default.bold.blue(`Project: ${project?.name}\n`));
64
- const streams = db.listStreams(projectId);
65
- const streamChoices = streams.map(s => ({
56
+ const project = projects.find((p) => p.id === projectId);
57
+ console.log(chalk.bold.blue(`Project: ${project?.name}\n`));
58
+ const streams = await db.listStreams(projectId);
59
+ const streamChoices = streams.map((s) => ({
66
60
  name: `${s.name} (${s.type})`,
67
61
  value: s.id
68
62
  }));
69
- streamChoices.push(new inquirer_1.default.Separator());
70
- streamChoices.push({ name: chalk_1.default.green("+ Create Stream"), value: "create_stream" });
71
- streamChoices.push({ name: chalk_1.default.yellow("Back"), value: "back" });
72
- const { streamId } = await inquirer_1.default.prompt([{
63
+ streamChoices.push(new inquirer.Separator());
64
+ streamChoices.push({ name: chalk.green("+ Create Stream"), value: "create_stream" });
65
+ streamChoices.push({ name: chalk.yellow("Back"), value: "back" });
66
+ const { streamId } = await inquirer.prompt([{
73
67
  type: "list",
74
68
  name: "streamId",
75
69
  message: "Select a stream",
@@ -81,9 +75,9 @@ async function startTui(db, token) {
81
75
  break;
82
76
  if (streamId === "create_stream") {
83
77
  showHeader();
84
- console.log(chalk_1.default.bold.blue(`Project: ${project?.name}`));
85
- console.log(chalk_1.default.bold.blue(` └─ Create Stream\n`));
86
- const { name, type } = await inquirer_1.default.prompt([
78
+ console.log(chalk.bold.blue(`Project: ${project?.name}`));
79
+ console.log(chalk.bold.blue(` └─ Create Stream\n`));
80
+ const { name, type } = await inquirer.prompt([
87
81
  {
88
82
  type: "input",
89
83
  name: "name",
@@ -101,9 +95,9 @@ async function startTui(db, token) {
101
95
  if (name && type) {
102
96
  // For now, empty config
103
97
  const s = await db.createStream(projectId, type, name, {});
104
- console.log(chalk_1.default.green(`\nStream created!`));
105
- console.log(chalk_1.default.bold.yellow(`Token: ${s.token}\n`));
106
- await inquirer_1.default.prompt([{
98
+ console.log(chalk.green(`\nStream created!`));
99
+ console.log(chalk.bold.yellow(`Token: ${s.token}\n`));
100
+ await inquirer.prompt([{
107
101
  type: "input",
108
102
  name: "continue",
109
103
  message: "Press enter to continue...",
@@ -115,10 +109,10 @@ async function startTui(db, token) {
115
109
  // Stream Actions
116
110
  while (true) {
117
111
  showHeader();
118
- const stream = streams.find(s => s.id === streamId);
119
- console.log(chalk_1.default.bold.blue(`Project: ${project?.name}`));
120
- console.log(chalk_1.default.bold.blue(` └─ Stream: ${stream?.name} (${stream?.type})\n`));
121
- const { action } = await inquirer_1.default.prompt([{
112
+ const stream = streams.find((s) => s.id === streamId);
113
+ console.log(chalk.bold.blue(`Project: ${project?.name}`));
114
+ console.log(chalk.bold.blue(` └─ Stream: ${stream?.name} (${stream?.type})\n`));
115
+ const { action } = await inquirer.prompt([{
122
116
  type: "list",
123
117
  name: "action",
124
118
  message: "Action",
@@ -126,18 +120,17 @@ async function startTui(db, token) {
126
120
  { name: "View logs", value: "view_logs" },
127
121
  { name: "Get token", value: "get_token" },
128
122
  { name: "Delete stream", value: "delete_stream" },
129
- { name: chalk_1.default.yellow("Back"), value: "back" }
123
+ { name: chalk.yellow("Back"), value: "back" }
130
124
  ],
131
125
  prefix: "💡"
132
126
  }]);
133
127
  if (action === "back")
134
128
  break;
135
129
  if (action === "get_token") {
136
- const auth = new auth_1.AuthService();
137
- const token = await auth.createStreamToken(streamId);
138
- console.log(chalk_1.default.green(`\nToken for ${stream?.name}:`));
139
- console.log(chalk_1.default.bold.yellow(`${token}\n`));
140
- await inquirer_1.default.prompt([{
130
+ const token = await authService.createStreamToken(streamId);
131
+ console.log(chalk.green(`\nToken for ${stream?.name}:`));
132
+ console.log(chalk.bold.yellow(`${token}\n`));
133
+ await inquirer.prompt([{
141
134
  type: "input",
142
135
  name: "continue",
143
136
  message: "Press enter to continue...",
@@ -145,30 +138,30 @@ async function startTui(db, token) {
145
138
  }]);
146
139
  }
147
140
  if (action === "delete_stream") {
148
- const { confirm } = await inquirer_1.default.prompt([{
141
+ const { confirm } = await inquirer.prompt([{
149
142
  type: "confirm",
150
143
  name: "confirm",
151
144
  message: `Are you sure you want to delete stream ${stream?.name}?`
152
145
  }]);
153
146
  if (confirm) {
154
- db.deleteStream(streamId);
147
+ await db.deleteStream(streamId);
155
148
  break; // Go back to stream list
156
149
  }
157
150
  }
158
151
  if (action === "view_logs") {
159
152
  console.clear();
160
- console.log(chalk_1.default.bold.green(`Logs for ${stream?.name}:\n`));
161
- const logs = db.getRecentLogs(streamId, 20);
153
+ console.log(chalk.bold.green(`Logs for ${stream?.name}:\n`));
154
+ const logs = await db.getRecentLogs(streamId, 20);
162
155
  if (logs.length === 0) {
163
156
  console.log("No logs recorded yet.");
164
157
  }
165
158
  else {
166
159
  [...logs].reverse().forEach(log => {
167
- console.log(`${chalk_1.default.dim(log.timestamp)} ${log.content}`);
160
+ console.log(`${chalk.dim(log.timestamp)} ${log.content}`);
168
161
  });
169
162
  }
170
163
  console.log("\n");
171
- await inquirer_1.default.prompt([{
164
+ await inquirer.prompt([{
172
165
  type: "input",
173
166
  name: "return",
174
167
  message: "Press enter to return...",
@@ -1,14 +1,12 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.ensureInfrastructure = ensureInfrastructure;
7
- const chalk_1 = __importDefault(require("chalk"));
8
- const ollama_1 = require("../services/ollama");
9
- const migrate_1 = require("../db/migrate");
10
- async function ensureInfrastructure() {
11
- console.log(chalk_1.default.bold.blue("\n🚀Performing system preflight checks..."));
1
+ import chalk from "chalk";
2
+ import { OllamaService, migrate } from "@loghead/db";
3
+ import { dbAdapter } from "../db/client.js";
4
+ function isUnsupportedVectorIndexError(error) {
5
+ const msg = error instanceof Error ? error.message : String(error);
6
+ return msg.includes("invalid expression in CREATE INDEX") && msg.includes("libsql_vector_idx");
7
+ }
8
+ export async function ensureInfrastructure() {
9
+ console.log(chalk.bold.blue("\n🚀Performing system preflight checks..."));
12
10
  // 1. Check Local Ollama
13
11
  await checkStep("Checking local Ollama...", async () => {
14
12
  try {
@@ -22,34 +20,38 @@ async function ensureInfrastructure() {
22
20
  throw new Error("Ollama is not accessible at http://localhost:11434. Please install and run Ollama.");
23
21
  }
24
22
  });
25
- // 2. Check Database & Migrations (SQLite)
23
+ // 2. Check Database & Migrations (LibSQL)
26
24
  await checkStep("Initializing database...", async () => {
27
25
  try {
28
- (0, migrate_1.migrate)(false);
26
+ await migrate(dbAdapter, false);
29
27
  }
30
28
  catch (e) {
31
- console.log(chalk_1.default.yellow("\n ➤ Migration failed..."));
29
+ if (isUnsupportedVectorIndexError(e)) {
30
+ console.log(chalk.yellow("\n ➤ Embedded DB does not support vector index expressions yet; continuing without vec_logs_idx."));
31
+ return;
32
+ }
33
+ console.log(chalk.yellow("\n ➤ Migration failed..."));
32
34
  throw e;
33
35
  }
34
36
  });
35
37
  // 3. Check Ollama Model
36
38
  await checkStep("Checking embedding model (qwen3-embedding)...", async () => {
37
- const ollama = new ollama_1.OllamaService();
39
+ const ollama = new OllamaService();
38
40
  await ollama.ensureModel();
39
41
  });
40
- console.log(`${chalk_1.default.green("✔")} System preflight checks complete`);
42
+ console.log(`${chalk.green("✔")} System preflight checks complete`);
41
43
  }
42
44
  async function checkStep(name, action) {
43
45
  // Print pending state
44
- process.stdout.write(`${chalk_1.default.cyan("○")} ${name}`);
46
+ process.stdout.write(`${chalk.cyan("○")} ${name}`);
45
47
  try {
46
48
  await action();
47
49
  // Clear line and print success
48
- process.stdout.write(`\r${chalk_1.default.green("✔")} ${name} \n`);
50
+ process.stdout.write(`\r${chalk.green("✔")} ${name} \n`);
49
51
  }
50
52
  catch (e) {
51
- process.stdout.write(`\r${chalk_1.default.red("✖")} ${name}\n`);
52
- console.error(chalk_1.default.red(` Error: ${e instanceof Error ? e.message : e}`));
53
+ process.stdout.write(`\r${chalk.red("✖")} ${name}\n`);
54
+ console.error(chalk.red(` Error: ${e instanceof Error ? e.message : e}`));
53
55
  process.exit(1);
54
56
  }
55
57
  }
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@loghead/core",
3
- "version": "0.1.32",
3
+ "version": "0.1.34",
4
+ "type": "module",
4
5
  "license": "MIT",
5
6
  "description": "Core API and Database for Loghead",
6
7
  "repository": {
@@ -27,11 +28,13 @@
27
28
  "ui": "tsx src/cli_main.ts ui",
28
29
  "build:frontend": "cd frontend && yarn install && yarn build",
29
30
  "build": "npm run build:frontend && tsc",
30
- "dev": "tsx watch src/cli_main.ts",
31
+ "dev:backend": "tsx watch src/cli_main.ts",
32
+ "dev:frontend": "cd frontend && yarn build --watch",
33
+ "dev": "sh -c 'yarn dev:frontend & yarn dev:backend'",
31
34
  "deploy": "npm publish --access public"
32
35
  },
33
36
  "dependencies": {
34
- "better-sqlite3": "^9.4.0",
37
+ "@loghead/db": "*",
35
38
  "chalk": "^5.3.0",
36
39
  "cli-table3": "^0.6.3",
37
40
  "cors": "^2.8.5",
@@ -41,11 +44,10 @@
41
44
  "jsonwebtoken": "^9.0.2",
42
45
  "ollama": "^0.5.9",
43
46
  "open": "^8.4.2",
44
- "sqlite-vec": "^0.1.0",
47
+ "@tursodatabase/database": "^0.4.2",
45
48
  "yargs": "^17.7.2"
46
49
  },
47
50
  "devDependencies": {
48
- "@types/better-sqlite3": "^7.6.9",
49
51
  "@types/cors": "^2.8.17",
50
52
  "@types/express": "^4.17.21",
51
53
  "@types/inquirer": "^9.0.7",
@@ -1,194 +0,0 @@
1
- # Loghead
2
-
3
- Loghead is a smart log aggregation tool and MCP server. It collects logs from various sources like your Terminal, Docker containers, or Browser, stores them in a database, and makes them searchable for AI assistants (like Claude, Cursor, or Windsurf).
4
-
5
- Think of it as a "long-term memory" for your development logs that your AI coding agent can read.
6
-
7
- ## Prerequisites
8
-
9
- Before you start, make sure you have:
10
-
11
- 1. **Local Ollama**: [Download here](https://ollama.com/download).
12
- - Ensure it is running (`ollama serve`) and accessible at `http://localhost:11434`.
13
- - Pull the embedding model: `ollama pull qwen3-embedding:0.6b` (or similar).
14
- 2. **The Loghead Executable**: You can download the latest release or build it yourself (see below).
15
-
16
- _(Note: [Deno](https://docs.deno.com/runtime/fundamentals/installation/) is only required if you want to build the project from source.)_
17
-
18
- ## Setup Guide
19
-
20
- Follow these steps to get Loghead running on your machine.
21
-
22
- ### 1. Install the Tool
23
-
24
- Download the `loghead` binary from the releases page and move it to a directory in your PATH (e.g., `/usr/local/bin`).
25
-
26
- **Verify installation:**
27
-
28
- ```bash
29
- loghead --help
30
- ```
31
-
32
- ### 2. Initialize the Database
33
-
34
- Run this command to set up the database tables (SQLite):
35
-
36
- ```bash
37
- loghead init
38
- ```
39
-
40
- ## How to Use
41
-
42
- ### 1. Start the MCP Server
43
-
44
- This is the bridge that allows your AI editor to talk to Loghead.
45
-
46
- ```bash
47
- loghead start
48
- ```
49
-
50
- You will see instructions on how to connect your specific AI tool (Claude, Cursor, VS Code, Windsurf) in the output.
51
-
52
- **Example for Claude Desktop Config:**
53
-
54
- ```json
55
- "loghead": {
56
- "command": "loghead",
57
- "args": ["stdio"]
58
- }
59
- ```
60
-
61
- ### 2. Create a Project
62
-
63
- Organize your logs into projects.
64
-
65
- ```bash
66
- loghead projects add "My Awesome App"
67
- ```
68
-
69
- ### 3. Add a Log Stream
70
-
71
- A "stream" is a specific source of logs (e.g., your terminal output, or a specific Docker container). You need the Project ID from the previous step (use `loghead projects list` to see it).
72
-
73
- **Example: Creating a stream for Docker logs**
74
-
75
- ```bash
76
- loghead streams add docker --project <PROJECT_ID> --name "Backend API" --container my-api-container
77
- ```
78
-
79
- **Example: Creating a generic terminal stream**
80
-
81
- ```bash
82
- loghead streams add terminal --project <PROJECT_ID> --name "Build Logs"
83
- ```
84
-
85
- ### 4. Ingest Logs
86
-
87
- Now, feed logs into the stream you created. You need the Stream ID (use `loghead streams list --project <PROJECT_ID>` to find it).
88
-
89
- **From Standard Input (Manual):**
90
- You can pipe any command's output into Loghead:
91
-
92
- ```bash
93
- echo "Something happened" | loghead ingest --stream <STREAM_ID>
94
- ```
95
-
96
- Or run a script and capture its output:
97
-
98
- ```bash
99
- deno run my_script.ts | loghead ingest --stream <STREAM_ID>
100
- ```
101
-
102
- ### 5. Query Logs (The AI Part)
103
-
104
- Your AI assistant can now "call" tools to search these logs. It can ask things like:
105
-
106
- - "Show me the recent errors in the Backend API stream."
107
- - "Find logs related to 'database connection failure'."
108
-
109
- You can also check logs manually:
110
-
111
- ```bash
112
- npx loghead log list --stream <STREAM_ID>
113
- ```
114
-
115
- ## Building from Source
116
-
117
- If you want to build the `loghead` executable yourself (e.g., to contribute or modify it):
118
-
119
- 1. Install **Deno** (see Prerequisites).
120
- 2. Compile the tool into a single executable file in the `build` directory:
121
-
122
- ```bash
123
- mkdir -p build
124
- deno task build
125
- ```
126
-
127
- 3. This will generate the `loghead` binary in your `packages/core/build/` directory.
128
-
129
- ## Architecture Overview
130
-
131
- - **Language:** TypeScript (Deno)
132
- - **Database:** SQLite with `sqlite-vec` for storing log embeddings.
133
- - **AI:** Local Ollama running `mxbai-embed-large` (or similar) to understand the semantic meaning of logs.
134
- - **Protocol:** Model Context Protocol (MCP) for integration with AI agents.
135
-
136
- ## Sample Apps
137
-
138
- We provide sample applications in the `sample_apps` directory to help you test Loghead's capabilities.
139
-
140
- ### 1. CLI Calculator
141
-
142
- A simple script that generates random logs and simulates a crash.
143
-
144
- **How to test:**
145
-
146
- 1. Create a project and a stream:
147
- ```bash
148
- npx loghead projects add "Calculator App"
149
- # Copy Project ID
150
- npx loghead streams add terminal --project <PROJECT_ID> --name "CLI Output"
151
- # Copy Stream ID
152
- ```
153
- 2. Run the calculator and pipe logs to Loghead:
154
- ```bash
155
- deno run sample_apps/cli_calculator/main.ts | npx @loghead/terminal --token <TOKEN>
156
- ```
157
- 3. Ask your AI Agent: "Why did the calculator app crash?"
158
-
159
- ### 2. Docker App
160
-
161
- A Python worker process running in Docker that logs tasks and simulates occasional warnings.
162
-
163
- **How to test:**
164
-
165
- 1. Create a stream for Docker:
166
- ```bash
167
- # Use existing Project ID
168
- npx loghead streams add docker --project <PROJECT_ID> --name "Worker Node" --container worker-app
169
- # Note the container name "worker-app" matches the --name in docker run below
170
- # Copy Stream ID
171
- ```
172
- 2. Build and run the container:
173
- ```bash
174
- cd sample_apps/docker_app
175
- docker build -t docker-app .
176
- docker run --name worker-app -d docker-app
177
- ```
178
- 3. Attach Loghead to the container logs:
179
- ```bash
180
- npx @loghead/docker --token <TOKEN> --container worker-app
181
- ```
182
- 4. Ask your AI Agent: "What tasks is the worker processing?" or "Are there any performance warnings?"
183
-
184
- ### 3. Browser App
185
-
186
- A simple HTML/JS Calculator that logs actions to the browser console.
187
-
188
- **How to test:**
189
-
190
- 1. Open `sample_apps/browser_app/index.html` in your browser.
191
- 2. Ensure the Loghead Chrome Extension is installed and connected to a browser stream.
192
- 3. Open Developer Tools (Console).
193
- 4. Perform some calculations (try dividing by zero!).
194
- 5. Logs will automatically appear in your Loghead dashboard.
Binary file
@@ -1,32 +0,0 @@
1
- {
2
- "name": "@loghead/core",
3
- "version": "0.1.1",
4
- "description": "Smart log aggregation tool and MCP server",
5
- "bin": {
6
- "loghead": "./bin/loghead"
7
- },
8
- "files": [
9
- "bin"
10
- ],
11
- "os": [
12
- "darwin"
13
- ],
14
- "cpu": [
15
- "arm64"
16
- ],
17
- "scripts": {
18
- "postinstall": "echo 'Note: This package contains a prebuilt binary for macOS ARM64.'"
19
- },
20
- "author": "Onvo AI",
21
- "license": "MIT",
22
- "publishConfig": {
23
- "access": "public"
24
- },
25
- "repository": {
26
- "type": "git",
27
- "url": "git+https://github.com/onvo-ai/loghead.git"
28
- },
29
- "bugs": {
30
- "url": "https://github.com/onvo-ai/loghead/issues"
31
- }
32
- }