@hasna/mementos 0.1.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dashboard/dist/assets/{index-C5oRjtKB.js → index-DqyMbv89.js} +20 -20
- package/dashboard/dist/assets/index-UBCddFo_.css +1 -0
- package/dashboard/dist/index.html +2 -2
- package/dist/cli/index.js +448 -23
- package/dist/db/memories.d.ts +1 -0
- package/dist/db/memories.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +148 -17
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/injector.d.ts +1 -1
- package/dist/lib/injector.d.ts.map +1 -1
- package/dist/lib/project-detect.d.ts +18 -0
- package/dist/lib/project-detect.d.ts.map +1 -0
- package/dist/lib/redact.d.ts +10 -0
- package/dist/lib/redact.d.ts.map +1 -0
- package/dist/lib/retention.d.ts +4 -0
- package/dist/lib/retention.d.ts.map +1 -1
- package/dist/mcp/index.js +270 -20
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +69 -3
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/dashboard/dist/assets/index-C8vbNL_5.css +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-500:oklch(63.7% .237 25.331);--color-orange-500:oklch(70.5% .213 47.604);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-600:oklch(66.6% .179 58.318);--color-amber-700:oklch(55.5% .163 48.998);--color-yellow-400:oklch(85.2% .199 91.936);--color-yellow-500:oklch(79.5% .184 86.047);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-teal-400:oklch(77.7% .152 181.912);--color-teal-500:oklch(70.4% .14 182.503);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-purple-400:oklch(71.4% .203 305.504);--color-purple-500:oklch(62.7% .265 303.9);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*{border-color:var(--border)}body{background-color:var(--background);color:var(--foreground);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}}@layer components;@layer utilities{.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.relative{position:relative}.end{inset-inline-end:var(--spacing)}.top-2\.5{top:calc(var(--spacing) * 2.5)}.right-2{right:calc(var(--spacing) * 2)}.right-2\.5{right:calc(var(--spacing) * 2.5)}.left-2{left:calc(var(--spacing) * 2)}.left-2\.5{left:calc(var(--spacing) * 2.5)}.z-10{z-index:10}.z-50{z-index:50}.-mx-1{margin-inline:calc(var(--spacing) * -1)}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing) * 1)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.-ml-2{margin-left:calc(var(--spacing) * -2)}.-ml-3{margin-left:calc(var(--spacing) * -3)}.ml-4{margin-left:calc(var(--spacing) * 4)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.inline-flex{display:inline-flex}.table{display:table}.size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.size-3\.5{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.size-10{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.h-2{height:calc(var(--spacing) * 2)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-24{height:calc(var(--spacing) * 24)}.h-\[var\(--radix-select-trigger-height\)\]{height:var(--radix-select-trigger-height)}.h-full{height:100%}.h-px{height:1px}.max-h-96{max-height:calc(var(--spacing) * 96)}.min-h-screen{min-height:100vh}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-7{width:calc(var(--spacing) * 7)}.w-9{width:calc(var(--spacing) * 9)}.w-\[130px\]{width:130px}.w-\[140px\]{width:140px}.w-\[150px\]{width:150px}.w-full{width:100%}.w-max{width:max-content}.max-w-7xl{max-width:var(--container-7xl)}.max-w-\[120px\]{max-width:120px}.max-w-\[200px\]{max-width:200px}.max-w-\[250px\]{max-width:250px}.max-w-\[300px\]{max-width:300px}.max-w-max{max-width:max-content}.max-w-none{max-width:none}.max-w-sm{max-width:var(--container-sm)}.min-w-\[8rem\]{min-width:8rem}.min-w-\[200px\]{min-width:200px}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.caption-bottom{caption-side:bottom}.translate-y-1{--tw-translate-y:calc(var(--spacing) * 1);translate:var(--tw-translate-x) var(--tw-translate-y)}.scale-0{--tw-scale-x:0%;--tw-scale-y:0%;--tw-scale-z:0%;scale:var(--tw-scale-x) var(--tw-scale-y)}.scale-100{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y)}.rotate-0{rotate:none}.rotate-90{rotate:90deg}.animate-in{animation:.2s ease-out enter}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.list-none{list-style-type:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}:where(.space-y-0>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 0) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 0) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.rounded-xl{border-radius:calc(var(--radius) + 4px)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-amber-500\/30{border-color:#f99c004d}@supports (color:color-mix(in lab,red,red)){.border-amber-500\/30{border-color:color-mix(in oklab,var(--color-amber-500) 30%,transparent)}}.border-blue-500\/30{border-color:#3080ff4d}@supports (color:color-mix(in lab,red,red)){.border-blue-500\/30{border-color:color-mix(in oklab,var(--color-blue-500) 30%,transparent)}}.border-border{border-color:var(--border)}.border-gray-500\/30{border-color:#6a72824d}@supports (color:color-mix(in lab,red,red)){.border-gray-500\/30{border-color:color-mix(in oklab,var(--color-gray-500) 30%,transparent)}}.border-green-500\/30{border-color:#00c7584d}@supports (color:color-mix(in lab,red,red)){.border-green-500\/30{border-color:color-mix(in oklab,var(--color-green-500) 30%,transparent)}}.border-input{border-color:var(--input)}.border-purple-500\/30{border-color:#ac4bff4d}@supports (color:color-mix(in lab,red,red)){.border-purple-500\/30{border-color:color-mix(in oklab,var(--color-purple-500) 30%,transparent)}}.border-teal-500\/30{border-color:#00baa74d}@supports (color:color-mix(in lab,red,red)){.border-teal-500\/30{border-color:color-mix(in oklab,var(--color-teal-500) 30%,transparent)}}.border-transparent{border-color:#0000}.border-yellow-500\/30{border-color:#edb2004d}@supports (color:color-mix(in lab,red,red)){.border-yellow-500\/30{border-color:color-mix(in oklab,var(--color-yellow-500) 30%,transparent)}}.border-l-amber-500{border-left-color:var(--color-amber-500)}.bg-amber-500\/5{background-color:#f99c000d}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/5{background-color:color-mix(in oklab,var(--color-amber-500) 5%,transparent)}}.bg-amber-500\/10{background-color:#f99c001a}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/10{background-color:color-mix(in oklab,var(--color-amber-500) 10%,transparent)}}.bg-amber-500\/15{background-color:#f99c0026}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/15{background-color:color-mix(in oklab,var(--color-amber-500) 15%,transparent)}}.bg-amber-600{background-color:var(--color-amber-600)}.bg-background{background-color:var(--background)}.bg-blue-500\/10{background-color:#3080ff1a}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/10{background-color:color-mix(in oklab,var(--color-blue-500) 10%,transparent)}}.bg-blue-500\/15{background-color:#3080ff26}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/15{background-color:color-mix(in oklab,var(--color-blue-500) 15%,transparent)}}.bg-card{background-color:var(--card)}.bg-destructive{background-color:var(--destructive)}.bg-gray-500\/10{background-color:#6a72821a}@supports (color:color-mix(in lab,red,red)){.bg-gray-500\/10{background-color:color-mix(in oklab,var(--color-gray-500) 10%,transparent)}}.bg-gray-500\/15{background-color:#6a728226}@supports (color:color-mix(in lab,red,red)){.bg-gray-500\/15{background-color:color-mix(in oklab,var(--color-gray-500) 15%,transparent)}}.bg-green-500\/10{background-color:#00c7581a}@supports (color:color-mix(in lab,red,red)){.bg-green-500\/10{background-color:color-mix(in oklab,var(--color-green-500) 10%,transparent)}}.bg-green-500\/15{background-color:#00c75826}@supports (color:color-mix(in lab,red,red)){.bg-green-500\/15{background-color:color-mix(in oklab,var(--color-green-500) 15%,transparent)}}.bg-muted,.bg-muted\/30{background-color:var(--muted)}@supports (color:color-mix(in lab,red,red)){.bg-muted\/30{background-color:color-mix(in oklab,var(--muted) 30%,transparent)}}.bg-muted\/50{background-color:var(--muted)}@supports (color:color-mix(in lab,red,red)){.bg-muted\/50{background-color:color-mix(in oklab,var(--muted) 50%,transparent)}}.bg-popover{background-color:var(--popover)}.bg-primary{background-color:var(--primary)}.bg-purple-500\/10{background-color:#ac4bff1a}@supports (color:color-mix(in lab,red,red)){.bg-purple-500\/10{background-color:color-mix(in oklab,var(--color-purple-500) 10%,transparent)}}.bg-purple-500\/15{background-color:#ac4bff26}@supports (color:color-mix(in lab,red,red)){.bg-purple-500\/15{background-color:color-mix(in oklab,var(--color-purple-500) 15%,transparent)}}.bg-secondary{background-color:var(--secondary)}.bg-teal-500\/10{background-color:#00baa71a}@supports (color:color-mix(in lab,red,red)){.bg-teal-500\/10{background-color:color-mix(in oklab,var(--color-teal-500) 10%,transparent)}}.bg-teal-500\/15{background-color:#00baa726}@supports (color:color-mix(in lab,red,red)){.bg-teal-500\/15{background-color:color-mix(in oklab,var(--color-teal-500) 15%,transparent)}}.bg-transparent{background-color:#0000}.bg-yellow-500\/10{background-color:#edb2001a}@supports (color:color-mix(in lab,red,red)){.bg-yellow-500\/10{background-color:color-mix(in oklab,var(--color-yellow-500) 10%,transparent)}}.bg-yellow-500\/15{background-color:#edb20026}@supports (color:color-mix(in lab,red,red)){.bg-yellow-500\/15{background-color:color-mix(in oklab,var(--color-yellow-500) 15%,transparent)}}.p-1{padding:calc(var(--spacing) * 1)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-8{padding-inline:calc(var(--spacing) * 8)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-12{padding-block:calc(var(--spacing) * 12)}.pt-0{padding-top:calc(var(--spacing) * 0)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pr-8{padding-right:calc(var(--spacing) * 8)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-8{padding-left:calc(var(--spacing) * 8)}.text-center{text-align:center}.text-left{text-align:left}.align-middle{vertical-align:middle}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-none{--tw-leading:1;line-height:1}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.break-words{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.text-amber-400{color:var(--color-amber-400)}.text-amber-500{color:var(--color-amber-500)}.text-blue-400{color:var(--color-blue-400)}.text-blue-500{color:var(--color-blue-500)}.text-card-foreground{color:var(--card-foreground)}.text-foreground{color:var(--foreground)}.text-gray-400{color:var(--color-gray-400)}.text-green-400{color:var(--color-green-400)}.text-green-500{color:var(--color-green-500)}.text-muted-foreground,.text-muted-foreground\/50{color:var(--muted-foreground)}@supports (color:color-mix(in lab,red,red)){.text-muted-foreground\/50{color:color-mix(in oklab,var(--muted-foreground) 50%,transparent)}}.text-orange-500{color:var(--color-orange-500)}.text-popover-foreground{color:var(--popover-foreground)}.text-primary{color:var(--primary)}.text-primary-foreground{color:var(--primary-foreground)}.text-purple-400{color:var(--color-purple-400)}.text-purple-500{color:var(--color-purple-500)}.text-red-500{color:var(--color-red-500)}.text-secondary-foreground{color:var(--secondary-foreground)}.text-teal-400{color:var(--color-teal-400)}.text-teal-500{color:var(--color-teal-500)}.text-white{color:var(--color-white)}.text-yellow-400{color:var(--color-yellow-400)}.text-yellow-500{color:var(--color-yellow-500)}.underline{text-decoration-line:underline}.underline-offset-4{text-underline-offset:4px}.opacity-50{opacity:.5}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-offset-background{--tw-ring-offset-color:var(--background)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.file\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\:bg-transparent::file-selector-button{background-color:#0000}.file\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\:text-foreground::file-selector-button{color:var(--foreground)}.placeholder\:text-muted-foreground::placeholder{color:var(--muted-foreground)}@media(hover:hover){.hover\:bg-accent:hover{background-color:var(--accent)}.hover\:bg-amber-700:hover{background-color:var(--color-amber-700)}.hover\:bg-background\/50:hover{background-color:var(--background)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-background\/50:hover{background-color:color-mix(in oklab,var(--background) 50%,transparent)}}.hover\:bg-destructive\/90:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-destructive\/90:hover{background-color:color-mix(in oklab,var(--destructive) 90%,transparent)}}.hover\:bg-muted\/50:hover{background-color:var(--muted)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-muted\/50:hover{background-color:color-mix(in oklab,var(--muted) 50%,transparent)}}.hover\:bg-primary\/90:hover{background-color:var(--primary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab,var(--primary) 90%,transparent)}}.hover\:bg-secondary\/80:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-secondary\/80:hover{background-color:color-mix(in oklab,var(--secondary) 80%,transparent)}}.hover\:text-accent-foreground:hover{color:var(--accent-foreground)}.hover\:text-foreground:hover{color:var(--foreground)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:bg-accent:focus{background-color:var(--accent)}.focus\:text-accent-foreground:focus{color:var(--accent-foreground)}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-ring:focus{--tw-ring-color:var(--ring)}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color:var(--ring)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.data-\[active\]\:bg-accent\/50[data-active]{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.data-\[active\]\:bg-accent\/50[data-active]{background-color:color-mix(in oklab,var(--accent) 50%,transparent)}}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[state\=open\]\:bg-accent\/50[data-state=open]{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.data-\[state\=open\]\:bg-accent\/50[data-state=open]{background-color:color-mix(in oklab,var(--accent) 50%,transparent)}}.data-\[state\=selected\]\:bg-muted[data-state=selected]{background-color:var(--muted)}@media(min-width:40rem){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}}@media(min-width:48rem){.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}@media(prefers-color-scheme:dark){.dark\:scale-0{--tw-scale-x:0%;--tw-scale-y:0%;--tw-scale-z:0%;scale:var(--tw-scale-x) var(--tw-scale-y)}.dark\:scale-100{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y)}.dark\:-rotate-90{rotate:-90deg}.dark\:rotate-0{rotate:none}.dark\:bg-input\/30{background-color:var(--input)}@supports (color:color-mix(in lab,red,red)){.dark\:bg-input\/30{background-color:color-mix(in oklab,var(--input) 30%,transparent)}}}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-4 svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_tr\]\:border-b tr{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-style:var(--tw-border-style);border-width:0}.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]){padding-right:calc(var(--spacing) * 0)}.\[\&\>\[role\=checkbox\]\]\:translate-y-\[2px\]>[role=checkbox]{--tw-translate-y:2px;translate:var(--tw-translate-x) var(--tw-translate-y)}.\[\&\>span\]\:line-clamp-1>span{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.\[\&\>svg\]\:size-4>svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&\>svg\]\:shrink-0>svg{flex-shrink:0}.\[\&\>tr\]\:last\:border-b-0>tr:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}}@keyframes enter{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes exit{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.95)}}:root{--radius:.625rem;--background:oklch(100% 0 0);--foreground:oklch(14.5% 0 0);--card:oklch(100% 0 0);--card-foreground:oklch(14.5% 0 0);--popover:oklch(100% 0 0);--popover-foreground:oklch(14.5% 0 0);--primary:oklch(20.5% 0 0);--primary-foreground:oklch(98.5% 0 0);--secondary:oklch(96.5% 0 0);--secondary-foreground:oklch(20.5% 0 0);--muted:oklch(96.5% 0 0);--muted-foreground:oklch(55.6% 0 0);--accent:oklch(96.5% 0 0);--accent-foreground:oklch(20.5% 0 0);--destructive:oklch(57.7% .245 27.325);--border:oklch(92.1% 0 0);--input:oklch(92.1% 0 0);--ring:oklch(70.8% 0 0)}.dark{--background:oklch(14.5% 0 0);--foreground:oklch(98.5% 0 0);--card:oklch(17.5% 0 0);--card-foreground:oklch(98.5% 0 0);--popover:oklch(17.5% 0 0);--popover-foreground:oklch(98.5% 0 0);--primary:oklch(98.5% 0 0);--primary-foreground:oklch(20.5% 0 0);--secondary:oklch(26.9% 0 0);--secondary-foreground:oklch(98.5% 0 0);--muted:oklch(26.9% 0 0);--muted-foreground:oklch(70.8% 0 0);--accent:oklch(26.9% 0 0);--accent-foreground:oklch(98.5% 0 0);--destructive:oklch(39.6% .141 25.723);--border:oklch(26.9% 0 0);--input:oklch(26.9% 0 0);--ring:oklch(43.9% 0 0)}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}
|
|
@@ -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>Mementos Dashboard</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-DqyMbv89.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="/assets/index-UBCddFo_.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="root"></div>
|
package/dist/cli/index.js
CHANGED
|
@@ -2298,6 +2298,36 @@ var init_types = __esm(() => {
|
|
|
2298
2298
|
};
|
|
2299
2299
|
});
|
|
2300
2300
|
|
|
2301
|
+
// src/lib/redact.ts
|
|
2302
|
+
function redactSecrets(text) {
|
|
2303
|
+
let result = text;
|
|
2304
|
+
for (const { pattern } of SECRET_PATTERNS) {
|
|
2305
|
+
pattern.lastIndex = 0;
|
|
2306
|
+
result = result.replace(pattern, REDACTED);
|
|
2307
|
+
}
|
|
2308
|
+
return result;
|
|
2309
|
+
}
|
|
2310
|
+
var REDACTED = "[REDACTED]", SECRET_PATTERNS;
|
|
2311
|
+
var init_redact = __esm(() => {
|
|
2312
|
+
SECRET_PATTERNS = [
|
|
2313
|
+
{ name: "openai_key", pattern: /sk-[a-zA-Z0-9_-]{20,}/g },
|
|
2314
|
+
{ name: "anthropic_key", pattern: /sk-ant-[a-zA-Z0-9_-]{20,}/g },
|
|
2315
|
+
{ name: "generic_key", pattern: /(?:pk|tok|key|token|api[_-]?key)[_-][a-zA-Z0-9_-]{16,}/gi },
|
|
2316
|
+
{ name: "aws_key", pattern: /AKIA[A-Z0-9]{16}/g },
|
|
2317
|
+
{ name: "aws_secret", pattern: /(?<=AWS_SECRET_ACCESS_KEY\s*=\s*)[A-Za-z0-9/+=]{40}/g },
|
|
2318
|
+
{ name: "github_token", pattern: /gh[ps]_[a-zA-Z0-9]{36,}/g },
|
|
2319
|
+
{ name: "github_oauth", pattern: /gho_[a-zA-Z0-9]{36,}/g },
|
|
2320
|
+
{ name: "npm_token", pattern: /npm_[a-zA-Z0-9]{36,}/g },
|
|
2321
|
+
{ name: "bearer", pattern: /Bearer\s+[a-zA-Z0-9_\-.]{20,}/g },
|
|
2322
|
+
{ name: "conn_string", pattern: /(?:postgres|postgresql|mysql|mongodb|redis|amqp|mqtt):\/\/[^\s"'`]+@[^\s"'`]+/gi },
|
|
2323
|
+
{ name: "env_secret", pattern: /(?:SECRET|TOKEN|PASSWORD|PASSPHRASE|API_KEY|PRIVATE_KEY|AUTH|CREDENTIAL)[_A-Z]*\s*=\s*["']?[^\s"'\n]{8,}["']?/gi },
|
|
2324
|
+
{ name: "stripe_key", pattern: /(?:sk|pk|rk)_(?:test|live)_[a-zA-Z0-9]{20,}/g },
|
|
2325
|
+
{ name: "slack_token", pattern: /xox[bpras]-[a-zA-Z0-9-]{20,}/g },
|
|
2326
|
+
{ name: "jwt", pattern: /eyJ[a-zA-Z0-9_-]{10,}\.eyJ[a-zA-Z0-9_-]{10,}\.[a-zA-Z0-9_-]{10,}/g },
|
|
2327
|
+
{ name: "hex_secret", pattern: /(?<=(?:key|token|secret|password|hash)\s*[:=]\s*["']?)[0-9a-f]{32,}(?=["']?)/gi }
|
|
2328
|
+
];
|
|
2329
|
+
});
|
|
2330
|
+
|
|
2301
2331
|
// src/db/memories.ts
|
|
2302
2332
|
function parseMemoryRow(row) {
|
|
2303
2333
|
return {
|
|
@@ -2335,6 +2365,8 @@ function createMemory(input, dedupeMode = "merge", db) {
|
|
|
2335
2365
|
const tags = input.tags || [];
|
|
2336
2366
|
const tagsJson = JSON.stringify(tags);
|
|
2337
2367
|
const metadataJson = JSON.stringify(input.metadata || {});
|
|
2368
|
+
const safeValue = redactSecrets(input.value);
|
|
2369
|
+
const safeSummary = input.summary ? redactSecrets(input.summary) : null;
|
|
2338
2370
|
if (dedupeMode === "merge") {
|
|
2339
2371
|
const existing = d.query(`SELECT id, version FROM memories
|
|
2340
2372
|
WHERE key = ? AND scope = ?
|
|
@@ -2348,9 +2380,9 @@ function createMemory(input, dedupeMode = "merge", db) {
|
|
|
2348
2380
|
pinned = COALESCE(pinned, 0),
|
|
2349
2381
|
version = version + 1, updated_at = ?
|
|
2350
2382
|
WHERE id = ?`, [
|
|
2351
|
-
|
|
2383
|
+
safeValue,
|
|
2352
2384
|
input.category || "knowledge",
|
|
2353
|
-
|
|
2385
|
+
safeSummary,
|
|
2354
2386
|
tagsJson,
|
|
2355
2387
|
input.importance ?? 5,
|
|
2356
2388
|
metadataJson,
|
|
@@ -2529,7 +2561,7 @@ function updateMemory(id, input, db) {
|
|
|
2529
2561
|
const params = [now()];
|
|
2530
2562
|
if (input.value !== undefined) {
|
|
2531
2563
|
sets.push("value = ?");
|
|
2532
|
-
params.push(input.value);
|
|
2564
|
+
params.push(redactSecrets(input.value));
|
|
2533
2565
|
}
|
|
2534
2566
|
if (input.category !== undefined) {
|
|
2535
2567
|
sets.push("category = ?");
|
|
@@ -2602,6 +2634,7 @@ function cleanExpiredMemories(db) {
|
|
|
2602
2634
|
var init_memories = __esm(() => {
|
|
2603
2635
|
init_types();
|
|
2604
2636
|
init_database();
|
|
2637
|
+
init_redact();
|
|
2605
2638
|
});
|
|
2606
2639
|
|
|
2607
2640
|
// src/lib/poll.ts
|
|
@@ -2737,7 +2770,7 @@ var {
|
|
|
2737
2770
|
init_database();
|
|
2738
2771
|
init_memories();
|
|
2739
2772
|
import chalk from "chalk";
|
|
2740
|
-
import { readFileSync as readFileSync2 } from "fs";
|
|
2773
|
+
import { readFileSync as readFileSync2, existsSync as existsSync3, accessSync, constants as fsConstants } from "fs";
|
|
2741
2774
|
import { dirname as dirname3, join as join3, resolve as resolve3 } from "path";
|
|
2742
2775
|
import { fileURLToPath } from "url";
|
|
2743
2776
|
|
|
@@ -3048,7 +3081,9 @@ var DEFAULT_CONFIG = {
|
|
|
3048
3081
|
sync_agents: ["claude", "codex", "gemini"],
|
|
3049
3082
|
auto_cleanup: {
|
|
3050
3083
|
enabled: true,
|
|
3051
|
-
expired_check_interval: 3600
|
|
3084
|
+
expired_check_interval: 3600,
|
|
3085
|
+
unused_archive_days: 7,
|
|
3086
|
+
stale_deprioritize_days: 14
|
|
3052
3087
|
}
|
|
3053
3088
|
};
|
|
3054
3089
|
function deepMerge(target, source) {
|
|
@@ -3142,12 +3177,187 @@ function archiveStale(staleDays, db) {
|
|
|
3142
3177
|
AND COALESCE(accessed_at, created_at) < ?`, [timestamp, cutoff]);
|
|
3143
3178
|
return result.changes;
|
|
3144
3179
|
}
|
|
3180
|
+
function archiveUnused(days, db) {
|
|
3181
|
+
const d = db || getDatabase();
|
|
3182
|
+
const timestamp = now();
|
|
3183
|
+
const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
|
|
3184
|
+
const result = d.run(`UPDATE memories
|
|
3185
|
+
SET status = 'archived', updated_at = ?
|
|
3186
|
+
WHERE status = 'active'
|
|
3187
|
+
AND pinned = 0
|
|
3188
|
+
AND access_count = 0
|
|
3189
|
+
AND created_at < ?`, [timestamp, cutoff]);
|
|
3190
|
+
return result.changes;
|
|
3191
|
+
}
|
|
3192
|
+
function deprioritizeStale(days, db) {
|
|
3193
|
+
const d = db || getDatabase();
|
|
3194
|
+
const timestamp = now();
|
|
3195
|
+
const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
|
|
3196
|
+
const result = d.run(`UPDATE memories
|
|
3197
|
+
SET importance = MAX(importance - 1, 1),
|
|
3198
|
+
version = version + 1,
|
|
3199
|
+
updated_at = ?
|
|
3200
|
+
WHERE status = 'active'
|
|
3201
|
+
AND pinned = 0
|
|
3202
|
+
AND importance > 1
|
|
3203
|
+
AND COALESCE(accessed_at, updated_at) < ?`, [timestamp, cutoff]);
|
|
3204
|
+
return result.changes;
|
|
3205
|
+
}
|
|
3145
3206
|
function runCleanup(config, db) {
|
|
3146
3207
|
const d = db || getDatabase();
|
|
3147
3208
|
const expired = cleanExpiredMemories(d);
|
|
3148
3209
|
const evicted = enforceQuotas(config, d);
|
|
3149
3210
|
const archived = archiveStale(90, d);
|
|
3150
|
-
|
|
3211
|
+
const unused_archived = archiveUnused(config.auto_cleanup.unused_archive_days ?? 7, d);
|
|
3212
|
+
const deprioritized = deprioritizeStale(config.auto_cleanup.stale_deprioritize_days ?? 14, d);
|
|
3213
|
+
return { expired, evicted, archived, unused_archived, deprioritized };
|
|
3214
|
+
}
|
|
3215
|
+
|
|
3216
|
+
// src/lib/injector.ts
|
|
3217
|
+
init_memories();
|
|
3218
|
+
class MemoryInjector {
|
|
3219
|
+
config;
|
|
3220
|
+
injectedIds = new Set;
|
|
3221
|
+
constructor(config) {
|
|
3222
|
+
this.config = config || loadConfig();
|
|
3223
|
+
}
|
|
3224
|
+
getInjectionContext(options = {}) {
|
|
3225
|
+
const maxTokens = options.max_tokens || this.config.injection.max_tokens;
|
|
3226
|
+
const minImportance = options.min_importance || this.config.injection.min_importance;
|
|
3227
|
+
const categories = options.categories || this.config.injection.categories;
|
|
3228
|
+
const db = options.db;
|
|
3229
|
+
const allMemories = [];
|
|
3230
|
+
const globalMems = listMemories({
|
|
3231
|
+
scope: "global",
|
|
3232
|
+
category: categories,
|
|
3233
|
+
min_importance: minImportance,
|
|
3234
|
+
status: "active",
|
|
3235
|
+
limit: 100
|
|
3236
|
+
}, db);
|
|
3237
|
+
allMemories.push(...globalMems);
|
|
3238
|
+
if (options.project_id) {
|
|
3239
|
+
const sharedMems = listMemories({
|
|
3240
|
+
scope: "shared",
|
|
3241
|
+
category: categories,
|
|
3242
|
+
min_importance: minImportance,
|
|
3243
|
+
status: "active",
|
|
3244
|
+
project_id: options.project_id,
|
|
3245
|
+
limit: 100
|
|
3246
|
+
}, db);
|
|
3247
|
+
allMemories.push(...sharedMems);
|
|
3248
|
+
}
|
|
3249
|
+
if (options.agent_id) {
|
|
3250
|
+
const privateMems = listMemories({
|
|
3251
|
+
scope: "private",
|
|
3252
|
+
category: categories,
|
|
3253
|
+
min_importance: minImportance,
|
|
3254
|
+
status: "active",
|
|
3255
|
+
agent_id: options.agent_id,
|
|
3256
|
+
limit: 100
|
|
3257
|
+
}, db);
|
|
3258
|
+
allMemories.push(...privateMems);
|
|
3259
|
+
}
|
|
3260
|
+
const seen = new Set;
|
|
3261
|
+
const unique = allMemories.filter((m) => {
|
|
3262
|
+
if (seen.has(m.id))
|
|
3263
|
+
return false;
|
|
3264
|
+
seen.add(m.id);
|
|
3265
|
+
return true;
|
|
3266
|
+
});
|
|
3267
|
+
if (unique.length === 0) {
|
|
3268
|
+
return "";
|
|
3269
|
+
}
|
|
3270
|
+
const totalCharBudget = maxTokens * 4;
|
|
3271
|
+
const footer = "Tip: Use memory_search for deeper lookup on specific topics.";
|
|
3272
|
+
const footerChars = footer.length;
|
|
3273
|
+
const keyBudget = Math.floor((totalCharBudget - footerChars) * 0.67);
|
|
3274
|
+
const recentBudget = Math.floor((totalCharBudget - footerChars) * 0.33);
|
|
3275
|
+
const keyRanked = [...unique].sort((a, b) => {
|
|
3276
|
+
if (a.pinned !== b.pinned)
|
|
3277
|
+
return a.pinned ? -1 : 1;
|
|
3278
|
+
if (b.importance !== a.importance)
|
|
3279
|
+
return b.importance - a.importance;
|
|
3280
|
+
return new Date(b.updated_at).getTime() - new Date(a.updated_at).getTime();
|
|
3281
|
+
});
|
|
3282
|
+
const keyLines = [];
|
|
3283
|
+
const keyIds = new Set;
|
|
3284
|
+
let keyChars = 0;
|
|
3285
|
+
for (const m of keyRanked) {
|
|
3286
|
+
if (this.injectedIds.has(m.id))
|
|
3287
|
+
continue;
|
|
3288
|
+
const line = `- [${m.scope}/${m.category}] ${m.key}: ${m.value}`;
|
|
3289
|
+
if (keyChars + line.length > keyBudget)
|
|
3290
|
+
break;
|
|
3291
|
+
keyLines.push(line);
|
|
3292
|
+
keyIds.add(m.id);
|
|
3293
|
+
keyChars += line.length;
|
|
3294
|
+
}
|
|
3295
|
+
const recentRanked = [...unique].sort((a, b) => {
|
|
3296
|
+
const aTime = a.accessed_at ? new Date(a.accessed_at).getTime() : 0;
|
|
3297
|
+
const bTime = b.accessed_at ? new Date(b.accessed_at).getTime() : 0;
|
|
3298
|
+
return bTime - aTime;
|
|
3299
|
+
});
|
|
3300
|
+
const recentLines = [];
|
|
3301
|
+
let recentChars = 0;
|
|
3302
|
+
const maxRecent = 5;
|
|
3303
|
+
for (const m of recentRanked) {
|
|
3304
|
+
if (recentLines.length >= maxRecent)
|
|
3305
|
+
break;
|
|
3306
|
+
if (keyIds.has(m.id))
|
|
3307
|
+
continue;
|
|
3308
|
+
if (this.injectedIds.has(m.id))
|
|
3309
|
+
continue;
|
|
3310
|
+
const line = `- [${m.scope}/${m.category}] ${m.key}: ${m.value}`;
|
|
3311
|
+
if (recentChars + line.length > recentBudget)
|
|
3312
|
+
break;
|
|
3313
|
+
recentLines.push(line);
|
|
3314
|
+
recentChars += line.length;
|
|
3315
|
+
}
|
|
3316
|
+
if (keyLines.length === 0 && recentLines.length === 0) {
|
|
3317
|
+
return "";
|
|
3318
|
+
}
|
|
3319
|
+
const allInjectedMemoryIds = [
|
|
3320
|
+
...keyIds,
|
|
3321
|
+
...recentLines.map((_, i) => {
|
|
3322
|
+
let idx = 0;
|
|
3323
|
+
for (const m of recentRanked) {
|
|
3324
|
+
if (keyIds.has(m.id) || this.injectedIds.has(m.id))
|
|
3325
|
+
continue;
|
|
3326
|
+
if (idx === i)
|
|
3327
|
+
return m.id;
|
|
3328
|
+
idx++;
|
|
3329
|
+
}
|
|
3330
|
+
return "";
|
|
3331
|
+
})
|
|
3332
|
+
].filter(Boolean);
|
|
3333
|
+
for (const id of allInjectedMemoryIds) {
|
|
3334
|
+
this.injectedIds.add(id);
|
|
3335
|
+
touchMemory(id, db);
|
|
3336
|
+
}
|
|
3337
|
+
const sections = [];
|
|
3338
|
+
if (keyLines.length > 0) {
|
|
3339
|
+
sections.push(`## Key Memories
|
|
3340
|
+
${keyLines.join(`
|
|
3341
|
+
`)}`);
|
|
3342
|
+
}
|
|
3343
|
+
if (recentLines.length > 0) {
|
|
3344
|
+
sections.push(`## Recent Context
|
|
3345
|
+
${recentLines.join(`
|
|
3346
|
+
`)}`);
|
|
3347
|
+
}
|
|
3348
|
+
sections.push(footer);
|
|
3349
|
+
return `<agent-memories>
|
|
3350
|
+
${sections.join(`
|
|
3351
|
+
|
|
3352
|
+
`)}
|
|
3353
|
+
</agent-memories>`;
|
|
3354
|
+
}
|
|
3355
|
+
resetDedup() {
|
|
3356
|
+
this.injectedIds.clear();
|
|
3357
|
+
}
|
|
3358
|
+
getInjectedCount() {
|
|
3359
|
+
return this.injectedIds.size;
|
|
3360
|
+
}
|
|
3151
3361
|
}
|
|
3152
3362
|
|
|
3153
3363
|
// src/cli/index.tsx
|
|
@@ -3254,16 +3464,53 @@ function resolveMemoryId(partialId) {
|
|
|
3254
3464
|
return id;
|
|
3255
3465
|
}
|
|
3256
3466
|
program2.name("mementos").description("Universal memory system for AI agents").version(getPackageVersion()).option("--project <path>", "Project path for scoping").option("--json", "Output as JSON").option("--agent <name>", "Agent name or ID").option("--session <id>", "Session ID");
|
|
3257
|
-
program2.command("save <key> <value>").description("Save a memory (create or upsert)").option("-c, --category <cat>", "Category: preference, fact, knowledge, history").option("-s, --scope <scope>", "Scope: global, shared, private").option("--importance <n>", "Importance 1-10", parseInt).option("--tags <tags>", "Comma-separated tags").option("--summary <text>", "Brief summary").option("--ttl <ms>", "Time-to-live in milliseconds", parseInt).option("--source <src>", "Source: user, agent, system, auto, imported").action((key, value, opts) => {
|
|
3467
|
+
program2.command("save <key> <value>").description("Save a memory (create or upsert)").option("-c, --category <cat>", "Category: preference, fact, knowledge, history").option("-s, --scope <scope>", "Scope: global, shared, private").option("--importance <n>", "Importance 1-10", parseInt).option("--tags <tags>", "Comma-separated tags").option("--summary <text>", "Brief summary").option("--ttl <ms>", "Time-to-live in milliseconds", parseInt).option("--source <src>", "Source: user, agent, system, auto, imported").option("--template <name>", "Apply a template: correction, preference, decision, learning").action((key, value, opts) => {
|
|
3258
3468
|
try {
|
|
3259
3469
|
const globalOpts = program2.opts();
|
|
3470
|
+
const templates = {
|
|
3471
|
+
correction: {
|
|
3472
|
+
scope: "shared",
|
|
3473
|
+
category: "knowledge",
|
|
3474
|
+
importance: 9,
|
|
3475
|
+
tags: ["correction"]
|
|
3476
|
+
},
|
|
3477
|
+
preference: {
|
|
3478
|
+
scope: "global",
|
|
3479
|
+
category: "preference",
|
|
3480
|
+
importance: 8,
|
|
3481
|
+
tags: []
|
|
3482
|
+
},
|
|
3483
|
+
decision: {
|
|
3484
|
+
scope: "shared",
|
|
3485
|
+
category: "fact",
|
|
3486
|
+
importance: 8,
|
|
3487
|
+
tags: ["decision"]
|
|
3488
|
+
},
|
|
3489
|
+
learning: {
|
|
3490
|
+
scope: "shared",
|
|
3491
|
+
category: "knowledge",
|
|
3492
|
+
importance: 7,
|
|
3493
|
+
tags: ["learning"]
|
|
3494
|
+
}
|
|
3495
|
+
};
|
|
3496
|
+
let templateDefaults;
|
|
3497
|
+
if (opts.template) {
|
|
3498
|
+
const tpl = templates[opts.template];
|
|
3499
|
+
if (!tpl) {
|
|
3500
|
+
console.error(chalk.red(`Unknown template: ${opts.template}. Valid templates: ${Object.keys(templates).join(", ")}`));
|
|
3501
|
+
process.exit(1);
|
|
3502
|
+
}
|
|
3503
|
+
templateDefaults = tpl;
|
|
3504
|
+
}
|
|
3505
|
+
const explicitTags = opts.tags ? opts.tags.split(",").map((t) => t.trim()) : undefined;
|
|
3506
|
+
const mergedTags = explicitTags ? explicitTags : templateDefaults?.tags && templateDefaults.tags.length > 0 ? templateDefaults.tags : undefined;
|
|
3260
3507
|
const input = {
|
|
3261
3508
|
key,
|
|
3262
3509
|
value,
|
|
3263
|
-
category: opts.category,
|
|
3264
|
-
scope: opts.scope,
|
|
3265
|
-
importance: opts.importance,
|
|
3266
|
-
tags:
|
|
3510
|
+
category: opts.category ?? templateDefaults?.category,
|
|
3511
|
+
scope: opts.scope ?? templateDefaults?.scope,
|
|
3512
|
+
importance: opts.importance ?? templateDefaults?.importance,
|
|
3513
|
+
tags: mergedTags,
|
|
3267
3514
|
summary: opts.summary,
|
|
3268
3515
|
ttl_ms: opts.ttl,
|
|
3269
3516
|
source: opts.source,
|
|
@@ -3298,20 +3545,38 @@ program2.command("recall <key>").description("Recall a memory by key").option("-
|
|
|
3298
3545
|
projectId = project.id;
|
|
3299
3546
|
}
|
|
3300
3547
|
const memory = getMemoryByKey(key, opts.scope, agentId, projectId);
|
|
3301
|
-
if (
|
|
3548
|
+
if (memory) {
|
|
3549
|
+
touchMemory(memory.id);
|
|
3302
3550
|
if (globalOpts.json) {
|
|
3303
|
-
outputJson(
|
|
3551
|
+
outputJson(memory);
|
|
3304
3552
|
} else {
|
|
3305
|
-
console.
|
|
3553
|
+
console.log(formatMemoryDetail(memory));
|
|
3306
3554
|
}
|
|
3307
|
-
|
|
3555
|
+
return;
|
|
3556
|
+
}
|
|
3557
|
+
const results = searchMemories(key, {
|
|
3558
|
+
scope: opts.scope,
|
|
3559
|
+
agent_id: agentId,
|
|
3560
|
+
project_id: projectId,
|
|
3561
|
+
limit: 1
|
|
3562
|
+
});
|
|
3563
|
+
if (results.length > 0) {
|
|
3564
|
+
const best = results[0];
|
|
3565
|
+
touchMemory(best.memory.id);
|
|
3566
|
+
if (globalOpts.json) {
|
|
3567
|
+
outputJson({ fuzzy_match: true, score: best.score, match_type: best.match_type, memory: best.memory });
|
|
3568
|
+
} else {
|
|
3569
|
+
console.log(chalk.yellow(`No exact match, showing best result (score: ${best.score.toFixed(2)}, match: ${best.match_type}):`));
|
|
3570
|
+
console.log(formatMemoryDetail(best.memory));
|
|
3571
|
+
}
|
|
3572
|
+
return;
|
|
3308
3573
|
}
|
|
3309
|
-
touchMemory(memory.id);
|
|
3310
3574
|
if (globalOpts.json) {
|
|
3311
|
-
outputJson(memory);
|
|
3575
|
+
outputJson({ error: `No memory found for key: ${key}` });
|
|
3312
3576
|
} else {
|
|
3313
|
-
console.
|
|
3577
|
+
console.error(chalk.yellow(`No memory found for key: ${key}`));
|
|
3314
3578
|
}
|
|
3579
|
+
process.exit(1);
|
|
3315
3580
|
} catch (e) {
|
|
3316
3581
|
handleError(e);
|
|
3317
3582
|
}
|
|
@@ -3542,10 +3807,18 @@ program2.command("export").description("Export memories as JSON").option("-s, --
|
|
|
3542
3807
|
handleError(e);
|
|
3543
3808
|
}
|
|
3544
3809
|
});
|
|
3545
|
-
program2.command("import
|
|
3810
|
+
program2.command("import [file]").description("Import memories from a JSON file or stdin (use '-' or pipe data)").option("--overwrite", "Overwrite existing memories (default: merge)").action(async (file, opts) => {
|
|
3546
3811
|
try {
|
|
3547
3812
|
const globalOpts = program2.opts();
|
|
3548
|
-
|
|
3813
|
+
let raw;
|
|
3814
|
+
if (file === "-" || !file && !process.stdin.isTTY) {
|
|
3815
|
+
raw = await Bun.stdin.text();
|
|
3816
|
+
} else if (file) {
|
|
3817
|
+
raw = readFileSync2(resolve3(file), "utf-8");
|
|
3818
|
+
} else {
|
|
3819
|
+
console.error(chalk.red("No input: provide a file path, use '-' for stdin, or pipe data."));
|
|
3820
|
+
process.exit(1);
|
|
3821
|
+
}
|
|
3549
3822
|
const memories = JSON.parse(raw);
|
|
3550
3823
|
if (!Array.isArray(memories)) {
|
|
3551
3824
|
throw new Error("JSON file must contain an array of memories");
|
|
@@ -3574,9 +3847,11 @@ program2.command("clean").description("Remove expired memories and enforce quota
|
|
|
3574
3847
|
outputJson(result);
|
|
3575
3848
|
} else {
|
|
3576
3849
|
console.log(chalk.bold("Cleanup complete:"));
|
|
3577
|
-
console.log(` Expired removed:
|
|
3578
|
-
console.log(` Evicted (quota):
|
|
3579
|
-
console.log(` Archived (stale):
|
|
3850
|
+
console.log(` Expired removed: ${chalk.red(String(result.expired))}`);
|
|
3851
|
+
console.log(` Evicted (quota): ${chalk.yellow(String(result.evicted))}`);
|
|
3852
|
+
console.log(` Archived (stale): ${chalk.gray(String(result.archived))}`);
|
|
3853
|
+
console.log(` Archived (unused): ${chalk.gray(String(result.unused_archived))}`);
|
|
3854
|
+
console.log(` Deprioritized: ${chalk.blue(String(result.deprioritized))}`);
|
|
3580
3855
|
}
|
|
3581
3856
|
} catch (e) {
|
|
3582
3857
|
handleError(e);
|
|
@@ -3860,6 +4135,156 @@ program2.command("bulk <action> <ids...>").description("Batch operations: forget
|
|
|
3860
4135
|
handleError(e);
|
|
3861
4136
|
}
|
|
3862
4137
|
});
|
|
4138
|
+
program2.command("doctor").description("Run health checks on the mementos database").action(() => {
|
|
4139
|
+
const globalOpts = program2.opts();
|
|
4140
|
+
const checks = [];
|
|
4141
|
+
const dbPath = getDbPath();
|
|
4142
|
+
if (existsSync3(dbPath)) {
|
|
4143
|
+
try {
|
|
4144
|
+
accessSync(dbPath, fsConstants.R_OK | fsConstants.W_OK);
|
|
4145
|
+
checks.push({ name: "Database file", status: "ok", detail: dbPath });
|
|
4146
|
+
} catch {
|
|
4147
|
+
checks.push({ name: "Database file", status: "fail", detail: `Not readable/writable: ${dbPath}` });
|
|
4148
|
+
}
|
|
4149
|
+
} else {
|
|
4150
|
+
checks.push({ name: "Database file", status: "fail", detail: `Not found: ${dbPath}` });
|
|
4151
|
+
}
|
|
4152
|
+
try {
|
|
4153
|
+
const db = getDatabase();
|
|
4154
|
+
const migRow = db.query("SELECT MAX(id) as max_id FROM _migrations").get();
|
|
4155
|
+
const schemaVersion = migRow?.max_id ?? 0;
|
|
4156
|
+
checks.push({ name: "Schema version", status: schemaVersion > 0 ? "ok" : "warn", detail: `v${schemaVersion}` });
|
|
4157
|
+
const memCount = db.query("SELECT COUNT(*) as c FROM memories").get().c;
|
|
4158
|
+
const agentCount = db.query("SELECT COUNT(*) as c FROM agents").get().c;
|
|
4159
|
+
const projectCount = db.query("SELECT COUNT(*) as c FROM projects").get().c;
|
|
4160
|
+
checks.push({ name: "Memories", status: "ok", detail: String(memCount) });
|
|
4161
|
+
checks.push({ name: "Agents", status: "ok", detail: String(agentCount) });
|
|
4162
|
+
checks.push({ name: "Projects", status: "ok", detail: String(projectCount) });
|
|
4163
|
+
const orphanedTags = db.query("SELECT COUNT(*) as c FROM memory_tags WHERE memory_id NOT IN (SELECT id FROM memories)").get().c;
|
|
4164
|
+
checks.push({
|
|
4165
|
+
name: "Orphaned tags",
|
|
4166
|
+
status: orphanedTags > 0 ? "warn" : "ok",
|
|
4167
|
+
detail: orphanedTags > 0 ? `${orphanedTags} orphaned tag(s)` : "None"
|
|
4168
|
+
});
|
|
4169
|
+
const expiredCount = db.query("SELECT COUNT(*) as c FROM memories WHERE status != 'expired' AND expires_at IS NOT NULL AND expires_at < datetime('now')").get().c;
|
|
4170
|
+
checks.push({
|
|
4171
|
+
name: "Expired memories",
|
|
4172
|
+
status: expiredCount > 0 ? "warn" : "ok",
|
|
4173
|
+
detail: expiredCount > 0 ? `${expiredCount} expired but not cleaned up (run 'mementos clean')` : "None pending"
|
|
4174
|
+
});
|
|
4175
|
+
} catch (e) {
|
|
4176
|
+
checks.push({ name: "Database connection", status: "fail", detail: e instanceof Error ? e.message : String(e) });
|
|
4177
|
+
}
|
|
4178
|
+
if (globalOpts.json) {
|
|
4179
|
+
outputJson({ checks, healthy: checks.every((c) => c.status === "ok") });
|
|
4180
|
+
} else {
|
|
4181
|
+
console.log(chalk.bold(`
|
|
4182
|
+
Mementos Health Report
|
|
4183
|
+
`));
|
|
4184
|
+
for (const check of checks) {
|
|
4185
|
+
const icon = check.status === "ok" ? chalk.green("\u2713") : check.status === "warn" ? chalk.yellow("!") : chalk.red("\u2717");
|
|
4186
|
+
console.log(` ${icon} ${chalk.bold(check.name)}: ${check.detail}`);
|
|
4187
|
+
}
|
|
4188
|
+
const healthy = checks.every((c) => c.status === "ok");
|
|
4189
|
+
const warnings = checks.filter((c) => c.status === "warn").length;
|
|
4190
|
+
const failures = checks.filter((c) => c.status === "fail").length;
|
|
4191
|
+
console.log("");
|
|
4192
|
+
if (healthy) {
|
|
4193
|
+
console.log(chalk.green(" All checks passed."));
|
|
4194
|
+
} else {
|
|
4195
|
+
if (failures > 0)
|
|
4196
|
+
console.log(chalk.red(` ${failures} check(s) failed.`));
|
|
4197
|
+
if (warnings > 0)
|
|
4198
|
+
console.log(chalk.yellow(` ${warnings} warning(s).`));
|
|
4199
|
+
}
|
|
4200
|
+
console.log("");
|
|
4201
|
+
}
|
|
4202
|
+
});
|
|
4203
|
+
program2.command("show <id>").description("Show full detail of a memory by ID (supports partial IDs)").action((id) => {
|
|
4204
|
+
try {
|
|
4205
|
+
const globalOpts = program2.opts();
|
|
4206
|
+
const resolvedId = resolveMemoryId(id);
|
|
4207
|
+
const memory = getMemory(resolvedId);
|
|
4208
|
+
if (!memory) {
|
|
4209
|
+
if (globalOpts.json) {
|
|
4210
|
+
outputJson({ error: `Memory not found: ${id}` });
|
|
4211
|
+
} else {
|
|
4212
|
+
console.error(chalk.red(`Memory not found: ${id}`));
|
|
4213
|
+
}
|
|
4214
|
+
process.exit(1);
|
|
4215
|
+
}
|
|
4216
|
+
touchMemory(memory.id);
|
|
4217
|
+
if (globalOpts.json) {
|
|
4218
|
+
outputJson(memory);
|
|
4219
|
+
} else {
|
|
4220
|
+
console.log(formatMemoryDetail(memory));
|
|
4221
|
+
}
|
|
4222
|
+
} catch (e) {
|
|
4223
|
+
handleError(e);
|
|
4224
|
+
}
|
|
4225
|
+
});
|
|
4226
|
+
program2.command("history").description("List memories sorted by most recently accessed").option("--limit <n>", "Max results (default: 20)", parseInt).action((opts) => {
|
|
4227
|
+
try {
|
|
4228
|
+
const globalOpts = program2.opts();
|
|
4229
|
+
const limit = opts.limit || 20;
|
|
4230
|
+
const db = getDatabase();
|
|
4231
|
+
const rows = db.query("SELECT * FROM memories WHERE status = 'active' AND accessed_at IS NOT NULL ORDER BY accessed_at DESC LIMIT ?").all(limit);
|
|
4232
|
+
const memories = rows.map(parseMemoryRow);
|
|
4233
|
+
if (globalOpts.json) {
|
|
4234
|
+
outputJson(memories);
|
|
4235
|
+
return;
|
|
4236
|
+
}
|
|
4237
|
+
if (memories.length === 0) {
|
|
4238
|
+
console.log(chalk.yellow("No recently accessed memories."));
|
|
4239
|
+
return;
|
|
4240
|
+
}
|
|
4241
|
+
console.log(chalk.bold(`${memories.length} recently accessed memor${memories.length === 1 ? "y" : "ies"}:`));
|
|
4242
|
+
for (const m of memories) {
|
|
4243
|
+
const id = chalk.dim(m.id.slice(0, 8));
|
|
4244
|
+
const scope = colorScope(m.scope);
|
|
4245
|
+
const cat = colorCategory(m.category);
|
|
4246
|
+
const value = m.value.length > 60 ? m.value.slice(0, 60) + "..." : m.value;
|
|
4247
|
+
const accessed = m.accessed_at ? chalk.dim(m.accessed_at) : chalk.dim("never");
|
|
4248
|
+
console.log(`${id} [${scope}/${cat}] ${chalk.bold(m.key)} = ${value} ${accessed}`);
|
|
4249
|
+
}
|
|
4250
|
+
} catch (e) {
|
|
4251
|
+
handleError(e);
|
|
4252
|
+
}
|
|
4253
|
+
});
|
|
4254
|
+
program2.command("context").description("Output formatted injection context (for piping into agent prompts)").option("--agent <name>", "Agent ID for private memory scope").option("--project <path>", "Project path for shared memory scope").option("--max-tokens <n>", "Token budget for context", parseInt).option("--categories <cats>", "Comma-separated categories: preference, fact, knowledge, history").action((opts) => {
|
|
4255
|
+
try {
|
|
4256
|
+
const globalOpts = program2.opts();
|
|
4257
|
+
const agentId = opts.agent || globalOpts.agent;
|
|
4258
|
+
const projectPath = opts.project || globalOpts.project;
|
|
4259
|
+
let projectId;
|
|
4260
|
+
if (projectPath) {
|
|
4261
|
+
const project = getProject(resolve3(projectPath));
|
|
4262
|
+
if (project)
|
|
4263
|
+
projectId = project.id;
|
|
4264
|
+
}
|
|
4265
|
+
const categories = opts.categories ? opts.categories.split(",").map((c) => c.trim()) : undefined;
|
|
4266
|
+
const injector = new MemoryInjector;
|
|
4267
|
+
const context = injector.getInjectionContext({
|
|
4268
|
+
agent_id: agentId,
|
|
4269
|
+
project_id: projectId,
|
|
4270
|
+
max_tokens: opts.maxTokens,
|
|
4271
|
+
categories
|
|
4272
|
+
});
|
|
4273
|
+
if (globalOpts.json) {
|
|
4274
|
+
outputJson({
|
|
4275
|
+
context,
|
|
4276
|
+
injected_count: injector.getInjectedCount()
|
|
4277
|
+
});
|
|
4278
|
+
} else if (context) {
|
|
4279
|
+
console.log(context);
|
|
4280
|
+
} else {
|
|
4281
|
+
console.error(chalk.yellow("No memories matched the injection criteria."));
|
|
4282
|
+
process.exit(1);
|
|
4283
|
+
}
|
|
4284
|
+
} catch (e) {
|
|
4285
|
+
handleError(e);
|
|
4286
|
+
}
|
|
4287
|
+
});
|
|
3863
4288
|
program2.command("mcp").description("Install mementos MCP server into Claude Code, Codex, or Gemini").option("--claude", "Install into Claude Code (~/.claude/.mcp.json)").option("--codex", "Install into Codex (~/.codex/config.toml)").option("--gemini", "Install into Gemini (~/.gemini/settings.json)").option("--all", "Install into all supported agents").option("--uninstall", "Remove mementos MCP from config").action((opts) => {
|
|
3864
4289
|
const { readFileSync: readFileSync3, writeFileSync, existsSync: fileExists } = __require("fs");
|
|
3865
4290
|
const { join: pathJoin } = __require("path");
|