claude-launchpad 0.11.0 → 0.12.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/README.md +12 -23
- package/dist/{chunk-JXFTVFPC.js → chunk-4D3EBDNB.js} +20 -2
- package/dist/{chunk-JXFTVFPC.js.map → chunk-4D3EBDNB.js.map} +1 -1
- package/dist/{chunk-UCU3PG3D.js → chunk-6IXA2NQN.js} +2 -2
- package/dist/{chunk-JTKRLIEV.js → chunk-JWT7EHTU.js} +18 -9
- package/dist/chunk-JWT7EHTU.js.map +1 -0
- package/dist/{chunk-LRJW32ZW.js → chunk-QMWQOL75.js} +3 -3
- package/dist/{chunk-J5NT4JGE.js → chunk-VDXWW5H5.js} +2 -2
- package/dist/chunk-VDXWW5H5.js.map +1 -0
- package/dist/cli.js +8 -8
- package/dist/cli.js.map +1 -1
- package/dist/commands/memory/server.js +58 -7
- package/dist/commands/memory/server.js.map +1 -1
- package/dist/{context-HB6EK2LE.js → context-U2JJISLS.js} +71 -34
- package/dist/context-U2JJISLS.js.map +1 -0
- package/dist/{extract-SRE5TBS2.js → extract-HMAN7RW4.js} +4 -4
- package/dist/{install-PSSMUGLO.js → install-C5XDWATE.js} +2 -2
- package/dist/{pull-OGPDUNZ2.js → pull-7ZF3OBPZ.js} +6 -6
- package/dist/{push-EXJEKBU4.js → push-SYSRB6OP.js} +6 -6
- package/dist/{stats-W3BHM3WF.js → stats-AYVXQIJJ.js} +4 -4
- package/dist/tui-YMBDAVTI.js +1008 -0
- package/dist/tui-YMBDAVTI.js.map +1 -0
- package/package.json +7 -3
- package/dist/chunk-J5NT4JGE.js.map +0 -1
- package/dist/chunk-JTKRLIEV.js.map +0 -1
- package/dist/context-HB6EK2LE.js.map +0 -1
- package/dist/tui-R6XSBUKS.js +0 -1101
- package/dist/tui-R6XSBUKS.js.map +0 -1
- /package/dist/{chunk-UCU3PG3D.js.map → chunk-6IXA2NQN.js.map} +0 -0
- /package/dist/{chunk-LRJW32ZW.js.map → chunk-QMWQOL75.js.map} +0 -0
- /package/dist/{extract-SRE5TBS2.js.map → extract-HMAN7RW4.js.map} +0 -0
- /package/dist/{install-PSSMUGLO.js.map → install-C5XDWATE.js.map} +0 -0
- /package/dist/{pull-OGPDUNZ2.js.map → pull-7ZF3OBPZ.js.map} +0 -0
- /package/dist/{push-EXJEKBU4.js.map → push-SYSRB6OP.js.map} +0 -0
- /package/dist/{stats-W3BHM3WF.js.map → stats-AYVXQIJJ.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/memory/dashboard/tui.tsx","../src/commands/memory/dashboard/data/data-source.ts","../src/commands/memory/dashboard/app.tsx","../src/commands/memory/dashboard/hooks/use-dashboard-state.ts","../src/commands/memory/dashboard/data/formatters.ts","../src/commands/memory/dashboard/hooks/use-keybindings.ts","../src/commands/memory/dashboard/hooks/use-terminal-size.ts","../src/commands/memory/dashboard/components/keybinding-bar.tsx","../src/commands/memory/dashboard/components/header.tsx","../src/commands/memory/dashboard/components/search-bar.tsx","../src/commands/memory/dashboard/components/memory-list.tsx","../src/commands/memory/dashboard/colors.ts","../src/commands/memory/dashboard/components/memory-detail.tsx","../src/commands/memory/dashboard/components/project-list.tsx","../src/commands/memory/dashboard/components/stats-bar.tsx","../src/commands/memory/dashboard/components/help-overlay.tsx","../src/commands/memory/dashboard/components/project-picker.tsx"],"sourcesContent":["import React from 'react';\nimport { render } from 'ink';\nimport { createDatabase, closeDatabase } from '../storage/database.js';\nimport { migrate } from '../storage/migrator.js';\nimport { MemoryRepo } from '../storage/memory-repo.js';\nimport { RelationRepo } from '../storage/relation-repo.js';\nimport { SearchRepo } from '../storage/search-repo.js';\nimport { loadConfig, resolveDataDir } from '../config.js';\nimport { DashboardDataSource } from './data/data-source.js';\nimport { App } from './app.js';\n\nexport interface TuiOptions {\n readonly dbPath?: string;\n}\n\nexport async function startTui(options?: TuiOptions): Promise<void> {\n const config = loadConfig(\n options?.dbPath ? { dataDir: options.dbPath } : undefined,\n );\n const dataDir = resolveDataDir(config.dataDir);\n const db = createDatabase({ dataDir });\n migrate(db);\n\n const memoryRepo = new MemoryRepo(db);\n const relationRepo = new RelationRepo(db);\n const searchRepo = new SearchRepo(db);\n\n const dataSource = new DashboardDataSource(\n memoryRepo, relationRepo, searchRepo, dataDir,\n );\n\n let shuttingDown = false;\n\n const { waitUntilExit, unmount } = render(\n <App dataSource={dataSource} />,\n );\n\n function shutdown(): void {\n if (shuttingDown) return;\n shuttingDown = true;\n dataSource.stopWatching();\n unmount();\n closeDatabase(db);\n }\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n try {\n await waitUntilExit();\n } finally {\n if (!shuttingDown) {\n dataSource.stopWatching();\n closeDatabase(db);\n }\n }\n}\n","import { statSync, watchFile, unwatchFile } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { MemoryRepo } from \"../../storage/memory-repo.js\";\nimport type { RelationRepo } from \"../../storage/relation-repo.js\";\nimport type { SearchRepo } from \"../../storage/search-repo.js\";\nimport type { Memory, Relation } from \"../../types.js\";\n\n// -- Types --------------------------------------------------------------------\n\nexport interface MemoryFilter {\n readonly type?: string;\n readonly project?: string;\n readonly query?: string;\n}\n\nexport interface DashboardStats {\n readonly total: number;\n readonly byType: Record<string, number>;\n readonly byProject: Record<string, number>;\n readonly relations: number;\n readonly dbSizeBytes: number;\n readonly oldest: string | null;\n readonly newest: string | null;\n}\n\n// -- Data Source --------------------------------------------------------------\n\nexport class DashboardDataSource {\n readonly #memoryRepo: MemoryRepo;\n readonly #relationRepo: RelationRepo;\n readonly #searchRepo: SearchRepo;\n readonly #dbPath: string;\n\n #cachedMemories: readonly Memory[] = [];\n\n constructor(\n memoryRepo: MemoryRepo,\n relationRepo: RelationRepo,\n searchRepo: SearchRepo,\n dataDir: string,\n ) {\n this.#memoryRepo = memoryRepo;\n this.#relationRepo = relationRepo;\n this.#searchRepo = searchRepo;\n this.#dbPath = join(dataDir, \"memory.db\");\n }\n\n /** Re-query all memories from DB and cache them. Excludes soft-deleted (importance=0). */\n refresh(): void {\n this.#cachedMemories = this.#memoryRepo\n .getAll()\n .filter((m) => m.importance > 0);\n }\n\n /** Return cached memories, optionally filtered by type, project, or FTS query. */\n getMemories(filter?: MemoryFilter): readonly Memory[] {\n if (!filter) return this.#cachedMemories;\n\n let results: readonly Memory[] = this.#cachedMemories;\n\n if (filter.type) {\n const t = filter.type;\n results = results.filter((m) => m.type === t);\n }\n\n if (filter.project) {\n const p = filter.project;\n results = results.filter((m) => m.project === p);\n }\n\n if (filter.query) {\n const matches = this.#searchRepo.searchFts({\n query: filter.query,\n limit: 100,\n });\n const matchedIds = new Set(matches.map((m) => m.memoryId));\n results = results.filter((m) => matchedIds.has(m.id));\n }\n\n return results;\n }\n\n /** Get all relations for a specific memory. */\n getRelationsForMemory(id: string): readonly Relation[] {\n return this.#relationRepo.getByMemory(id);\n }\n\n /** Compute aggregate stats from cached data + DB queries. */\n getStats(): DashboardStats {\n const total = this.#memoryRepo.count();\n const byType = this.#memoryRepo.countByType();\n const relations = this.#relationRepo.count();\n const { oldest, newest } = this.#memoryRepo.dateRange();\n const dbSizeBytes = this.#getDbSize();\n const byProject = this.#computeByProject();\n\n return { total, byType, byProject, relations, dbSizeBytes, oldest, newest };\n }\n\n /** Derive unique project names from cached memories. */\n getProjects(): readonly string[] {\n const projects = new Set<string>();\n for (const m of this.#cachedMemories) {\n if (m.project) {\n projects.add(m.project);\n }\n }\n return [...projects].sort();\n }\n\n /** Watch the DB file for changes (2s polling interval). Only fires on mtime change. */\n startWatching(onChange: () => void): void {\n let lastMtime = 0;\n watchFile(this.#dbPath, { interval: 2000 }, (curr) => {\n const mtime = curr.mtimeMs;\n if (mtime === lastMtime) return;\n lastMtime = mtime;\n this.refresh();\n onChange();\n });\n }\n\n /** Stop watching the DB file. */\n stopWatching(): void {\n unwatchFile(this.#dbPath);\n }\n\n // -- Private helpers --------------------------------------------------------\n\n #getDbSize(): number {\n try {\n return statSync(this.#dbPath).size;\n } catch {\n return 0;\n }\n }\n\n #computeByProject(): Record<string, number> {\n const counts: Record<string, number> = {};\n for (const m of this.#cachedMemories) {\n const key = m.project ?? \"(none)\";\n counts[key] = (counts[key] ?? 0) + 1;\n }\n return counts;\n }\n}\n","import React from 'react';\nimport { Box, useApp } from 'ink';\nimport type { DashboardDataSource } from './data/data-source.js';\nimport { useDashboardState } from './hooks/use-dashboard-state.js';\nimport { useKeybindings } from './hooks/use-keybindings.js';\nimport { useTerminalSize } from './hooks/use-terminal-size.js';\nimport { KeybindingBar } from './components/keybinding-bar.js';\nimport { Header } from './components/header.js';\nimport { SearchBar } from './components/search-bar.js';\nimport { MemoryList } from './components/memory-list.js';\nimport { MemoryDetail } from './components/memory-detail.js';\nimport { ProjectList } from './components/project-list.js';\nimport { StatsBar } from './components/stats-bar.js';\nimport { HelpOverlay } from './components/help-overlay.js';\nimport { ProjectPicker } from './components/project-picker.js';\n\ninterface AppProps {\n readonly dataSource: DashboardDataSource;\n}\n\nexport function App({ dataSource }: AppProps): React.ReactNode {\n const { exit } = useApp();\n const { rows, layout } = useTerminalSize();\n const state = useDashboardState(dataSource);\n\n useKeybindings({\n navigateUp: state.navigateUp,\n navigateDown: state.navigateDown,\n openSearch: state.openSearch,\n closeSearch: state.closeSearch,\n filterByType: state.filterByType,\n cycleLifespan: state.cycleLifespan,\n cycleProjectNext: state.cycleProjectNext,\n cycleProjectPrev: state.cycleProjectPrev,\n cycleSort: state.cycleSort,\n focusNext: state.focusNext,\n openProjectPicker: () => state.setShowProjectPicker((v) => !v),\n showHelp: () => state.setShowHelp((v) => !v),\n refresh: state.refresh,\n quit: exit,\n }, {\n searchActive: state.searchActive,\n pickerOpen: state.showProjectPicker,\n });\n\n if (state.showHelp) {\n return <HelpOverlay onClose={() => state.setShowHelp(false)} />;\n }\n\n if (state.showProjectPicker) {\n return (\n <ProjectPicker\n projects={[...state.projects]}\n activeProject={state.currentProject}\n onSelect={(p) => { state.setCurrentProject(p); state.setSelectedIndex(0); }}\n onClose={() => state.setShowProjectPicker(false)}\n />\n );\n }\n\n const contentHeight = Math.max(4, rows - 6);\n const isNarrow = layout === 'narrow';\n\n return (\n <Box flexDirection=\"column\">\n <KeybindingBar />\n <Header\n project={state.currentProject}\n typeFilter={state.typeFilter}\n lifespanFilter={state.lifespanFilter}\n sortMode={state.sortMode}\n searchQuery={state.searchQuery}\n />\n {state.searchActive && (\n <SearchBar\n query={state.searchQuery}\n onChange={state.setSearchQuery}\n onClose={() => state.setSearchQuery(state.searchQuery)}\n />\n )}\n <Box flexDirection={isNarrow ? 'column' : 'row'}>\n <Box width={isNarrow ? '100%' : '60%'}>\n <MemoryList\n memories={state.filteredMemories}\n selectedIndex={state.selectedIndex}\n isFocused={state.focusedPane === 'list'}\n height={contentHeight}\n />\n </Box>\n <Box flexDirection=\"column\" width={isNarrow ? '100%' : '40%'}>\n {!isNarrow && (\n <ProjectList\n memories={state.filteredMemories}\n activeProject={state.currentProject}\n isFocused={state.focusedPane === 'projects'}\n />\n )}\n <MemoryDetail\n memory={state.selectedMemory}\n relations={state.relations}\n isFocused={state.focusedPane === 'detail'}\n />\n </Box>\n </Box>\n <StatsBar stats={state.stats} visible={state.filteredMemories} />\n </Box>\n );\n}\n","import { useState, useMemo, useEffect, useCallback } from 'react';\nimport type { DashboardDataSource } from '../data/data-source.js';\nimport type { Memory, MemoryType, Relation } from '../../types.js';\nimport type { DashboardStats } from '../data/data-source.js';\nimport { computeLifespan, type LifespanStatus } from '../data/formatters.js';\n\nexport type SortMode = 'importance' | 'age' | 'access' | 'lifespan';\nexport type FocusedPane = 'list' | 'projects' | 'detail';\n\nconst SORT_MODES: readonly SortMode[] = ['importance', 'age', 'access', 'lifespan'];\nconst LIFESPAN_FILTERS: readonly (LifespanStatus | undefined)[] = [\n undefined, 'healthy', 'fading', 'stale', 'session',\n];\n\nexport function useDashboardState(dataSource: DashboardDataSource) {\n const [revision, setRevision] = useState(0);\n const [typeFilter, setTypeFilter] = useState<MemoryType | undefined>();\n const [lifespanFilter, setLifespanFilter] = useState<LifespanStatus | undefined>();\n const [searchQuery, setSearchQuery] = useState('');\n const [searchActive, setSearchActive] = useState(false);\n const [currentProject, setCurrentProject] = useState<string | undefined>();\n const [sortMode, setSortMode] = useState<SortMode>('importance');\n const [selectedIndex, setSelectedIndex] = useState(0);\n const [focusedPane, setFocusedPane] = useState<FocusedPane>('list');\n const [showHelp, setShowHelp] = useState(false);\n const [showProjectPicker, setShowProjectPicker] = useState(false);\n\n useEffect(() => {\n dataSource.refresh();\n setRevision((r) => r + 1);\n dataSource.startWatching(() => {\n dataSource.refresh();\n setRevision((r) => r + 1);\n });\n return () => dataSource.stopWatching();\n }, [dataSource]);\n\n const projects = useMemo(() => {\n void revision;\n return dataSource.getProjects();\n }, [dataSource, revision]);\n\n const filteredMemories = useMemo(() => {\n void revision;\n const raw = dataSource.getMemories({ type: typeFilter, project: currentProject });\n const withLife = lifespanFilter\n ? raw.filter((m) => computeLifespan(m).status === lifespanFilter)\n : raw;\n const withSearch = searchQuery\n ? withLife.filter((m) =>\n (m.title?.toLowerCase().includes(searchQuery.toLowerCase()) ?? false) ||\n m.content.toLowerCase().includes(searchQuery.toLowerCase()) ||\n m.tags.some((t) => t.toLowerCase().includes(searchQuery.toLowerCase()))\n )\n : withLife;\n return sortMemories(withSearch, sortMode);\n }, [dataSource, revision, typeFilter, lifespanFilter, searchQuery, currentProject, sortMode]);\n\n const selectedMemory = filteredMemories[selectedIndex];\n const relations = useMemo(\n () => selectedMemory ? dataSource.getRelationsForMemory(selectedMemory.id) : [],\n [dataSource, selectedMemory, revision],\n );\n const stats = useMemo(() => { void revision; return dataSource.getStats(); }, [dataSource, revision]);\n\n const navigateUp = useCallback(() => {\n setSelectedIndex((i) => Math.max(0, i - 1));\n }, []);\n const navigateDown = useCallback(() => {\n setSelectedIndex((i) => Math.min(filteredMemories.length - 1, i + 1));\n }, [filteredMemories.length]);\n\n const cycleSort = useCallback(() => {\n setSortMode((m) => SORT_MODES[(SORT_MODES.indexOf(m) + 1) % SORT_MODES.length]!);\n }, []);\n const cycleLifespan = useCallback(() => {\n setLifespanFilter((f) => {\n const idx = LIFESPAN_FILTERS.findIndex((x) => x === f);\n return LIFESPAN_FILTERS[(idx + 1) % LIFESPAN_FILTERS.length];\n });\n }, []);\n const cycleProjectNext = useCallback(() => {\n setCurrentProject((curr) => {\n const idx = curr ? projects.indexOf(curr) : -1;\n return idx >= projects.length - 1 ? undefined : projects[idx + 1];\n });\n setSelectedIndex(0);\n }, [projects]);\n const cycleProjectPrev = useCallback(() => {\n setCurrentProject((curr) => {\n const idx = curr ? projects.indexOf(curr) : -1;\n return idx <= 0 ? (idx === 0 ? undefined : projects[projects.length - 1]) : projects[idx - 1];\n });\n setSelectedIndex(0);\n }, [projects]);\n const focusNext = useCallback(() => {\n setFocusedPane((p) => p === 'list' ? 'projects' : p === 'projects' ? 'detail' : 'list');\n }, []);\n const filterByType = useCallback((type: MemoryType | undefined) => {\n setTypeFilter(type);\n setSelectedIndex(0);\n }, []);\n const openSearch = useCallback(() => setSearchActive(true), []);\n const closeSearch = useCallback(() => {\n setSearchActive(false);\n setSearchQuery('');\n setSelectedIndex(0);\n }, []);\n const refresh = useCallback(() => {\n dataSource.refresh();\n setRevision((r) => r + 1);\n }, [dataSource]);\n\n return {\n typeFilter, lifespanFilter, searchQuery, searchActive, currentProject,\n sortMode, selectedIndex, focusedPane, showHelp, showProjectPicker,\n filteredMemories, selectedMemory, relations, projects, stats,\n setSearchQuery, setCurrentProject, setSelectedIndex, setShowHelp, setShowProjectPicker,\n navigateUp, navigateDown, cycleSort, cycleLifespan,\n cycleProjectNext, cycleProjectPrev, focusNext, filterByType,\n openSearch, closeSearch, refresh,\n };\n}\n\nfunction sortMemories(memories: readonly Memory[], mode: SortMode): readonly Memory[] {\n const sorted = [...memories];\n const sorters: Record<SortMode, (a: Memory, b: Memory) => number> = {\n importance: (a, b) => b.importance - a.importance,\n age: (a, b) => b.createdAt.localeCompare(a.createdAt),\n access: (a, b) => b.accessCount - a.accessCount,\n lifespan: (a, b) => computeLifespan(a).remaining - computeLifespan(b).remaining,\n };\n sorted.sort(sorters[mode]);\n return sorted;\n}\n","import type { Memory, MemoryType } from \"../../types.js\";\nimport { DEFAULT_DECAY_PARAMS } from \"../../config.js\";\n\n// -- Relative Time ------------------------------------------------------------\n\nconst MINUTE = 60_000;\nconst HOUR = 3_600_000;\nconst DAY = 86_400_000;\nconst MONTH = 30 * DAY;\nconst YEAR = 365 * DAY;\n\nexport function formatRelativeTime(isoString: string): string {\n const diff = Date.now() - new Date(isoString).getTime();\n\n if (diff < 0) return \"just now\";\n if (diff < MINUTE) return \"just now\";\n if (diff < HOUR) return `${Math.floor(diff / MINUTE)}m ago`;\n if (diff < DAY) return `${Math.floor(diff / HOUR)}h ago`;\n if (diff < MONTH) return `${Math.floor(diff / DAY)}d ago`;\n if (diff < YEAR) return `${Math.floor(diff / MONTH)}mo ago`;\n return `${Math.floor(diff / YEAR)}y ago`;\n}\n\n// -- Importance Bar -----------------------------------------------------------\n\nconst FILLED = \"\\u2588\"; // full block\nconst EMPTY = \"\\u2591\"; // light shade\n\nexport function formatImportanceBar(\n value: number,\n width: number = 8,\n): string {\n const clamped = Math.max(0, Math.min(1, value));\n const filled = Math.round(clamped * width);\n return FILLED.repeat(filled) + EMPTY.repeat(width - filled);\n}\n\n// -- Truncation ---------------------------------------------------------------\n\nexport function truncate(text: string, maxLen: number): string {\n if (text.length <= maxLen) return text;\n if (maxLen <= 1) return \"\\u2026\";\n return text.slice(0, maxLen - 1) + \"\\u2026\";\n}\n\n// -- Byte Formatting ----------------------------------------------------------\n\nconst UNITS = [\"B\", \"KB\", \"MB\", \"GB\"] as const;\n\nexport function formatBytes(bytes: number): string {\n if (bytes < 0) return \"0B\";\n let value = bytes;\n let unitIndex = 0;\n while (value >= 1024 && unitIndex < UNITS.length - 1) {\n value /= 1024;\n unitIndex++;\n }\n if (unitIndex === 0) return `${value}B`;\n return `${value.toFixed(1)}${UNITS[unitIndex]}`;\n}\n\n// -- Lifespan Helpers ---------------------------------------------------------\n\nexport type LifespanStatus = \"healthy\" | \"fading\" | \"stale\" | \"session\";\n\nexport interface LifespanInfo {\n readonly status: LifespanStatus;\n readonly tauDays: number;\n readonly ageDays: number;\n readonly remaining: number;\n}\n\nexport function tauDaysForType(type: MemoryType): number {\n return DEFAULT_DECAY_PARAMS.tauByType[type];\n}\n\nexport function computeLifespan(memory: Memory): LifespanInfo {\n const tauDays = tauDaysForType(memory.type);\n if (tauDays === 0) {\n return {\n status: \"session\",\n tauDays,\n ageDays: 0,\n remaining: 0,\n };\n }\n\n const ageDays = Math.max(\n 0,\n (Date.now() - new Date(memory.createdAt).getTime()) / DAY,\n );\n const remaining = Math.max(0, Math.min(1, 1 - ageDays / (tauDays * 2)));\n const status: LifespanStatus =\n remaining > 0.62 ? \"healthy\" : remaining > 0.32 ? \"fading\" : \"stale\";\n return { status, tauDays, ageDays, remaining };\n}\n\nexport function formatLifespanLabel(status: LifespanStatus): string {\n switch (status) {\n case \"healthy\":\n return \"HEALTHY\";\n case \"fading\":\n return \"FADING \";\n case \"stale\":\n return \"STALE \";\n case \"session\":\n return \"SESSION\";\n }\n}\n","import { useInput } from 'ink';\nimport type { MemoryType } from '../../types.js';\n\nconst TYPE_KEYS: Record<string, MemoryType> = {\n '1': 'working',\n '2': 'episodic',\n '3': 'semantic',\n '4': 'procedural',\n '5': 'pattern',\n};\n\nexport interface KeybindingActions {\n readonly navigateUp: () => void;\n readonly navigateDown: () => void;\n readonly openSearch: () => void;\n readonly closeSearch: () => void;\n readonly filterByType: (type: MemoryType | undefined) => void;\n readonly cycleLifespan: () => void;\n readonly cycleProjectNext: () => void;\n readonly cycleProjectPrev: () => void;\n readonly cycleSort: () => void;\n readonly focusNext: () => void;\n readonly openProjectPicker: () => void;\n readonly showHelp: () => void;\n readonly refresh: () => void;\n readonly quit: () => void;\n}\n\nexport function useKeybindings(\n actions: KeybindingActions,\n opts: { searchActive: boolean; pickerOpen: boolean },\n): void {\n useInput((input, key) => {\n if (opts.searchActive) {\n if (key.escape) actions.closeSearch();\n return;\n }\n if (opts.pickerOpen) {\n if (key.escape) actions.openProjectPicker(); // toggle off\n return;\n }\n\n if (input === 'j' || key.downArrow) actions.navigateDown();\n if (input === 'k' || key.upArrow) actions.navigateUp();\n if (input === '/') actions.openSearch();\n if (key.escape) actions.closeSearch();\n if (input === '0') actions.filterByType(undefined);\n if (input in TYPE_KEYS) actions.filterByType(TYPE_KEYS[input]!);\n if (input === 'l') actions.cycleLifespan();\n if (input === 's') actions.cycleSort();\n if (input === 'p') actions.openProjectPicker();\n if (input === ']' || key.rightArrow) actions.cycleProjectNext();\n if (input === '[' || key.leftArrow) actions.cycleProjectPrev();\n if (key.tab) actions.focusNext();\n if (input === '?') actions.showHelp();\n if (input === 'r') actions.refresh();\n if (input === 'q') actions.quit();\n });\n}\n","import { useStdout } from 'ink';\nimport { useState, useEffect } from 'react';\n\nexport interface TerminalSize {\n readonly columns: number;\n readonly rows: number;\n}\n\nexport type LayoutMode = 'wide' | 'medium' | 'narrow';\n\nexport function useTerminalSize(): TerminalSize & { layout: LayoutMode } {\n const { stdout } = useStdout();\n const [size, setSize] = useState<TerminalSize>({\n columns: stdout.columns ?? 80,\n rows: stdout.rows ?? 24,\n });\n\n useEffect(() => {\n const handler = () => setSize({ columns: stdout.columns, rows: stdout.rows });\n stdout.on('resize', handler);\n return () => { stdout.off('resize', handler); };\n }, [stdout]);\n\n const layout: LayoutMode =\n size.columns >= 120 ? 'wide' :\n size.columns >= 80 ? 'medium' : 'narrow';\n\n return { ...size, layout };\n}\n","import React from 'react';\nimport { Box, Text } from 'ink';\n\nconst HINTS = [\n ['j/k', 'navigate'],\n ['/', 'search'],\n ['p', 'projects'],\n ['1-5', 'type'],\n ['l', 'life'],\n ['s', 'sort'],\n ['Tab', 'focus'],\n ['?', 'help'],\n ['q', 'quit'],\n] as const;\n\nexport function KeybindingBar(): React.ReactNode {\n return (\n <Box>\n {HINTS.map(([key, label], i) => (\n <React.Fragment key={key}>\n {i > 0 && <Text dimColor> </Text>}\n <Text color=\"cyan\">{key}</Text>\n <Text dimColor> {label}</Text>\n </React.Fragment>\n ))}\n </Box>\n );\n}\n","import React from 'react';\nimport { Box, Text } from 'ink';\nimport type { MemoryType } from '../../types.js';\nimport type { LifespanStatus } from '../data/formatters.js';\nimport type { SortMode } from '../hooks/use-dashboard-state.js';\n\ninterface HeaderProps {\n readonly project?: string;\n readonly typeFilter?: MemoryType;\n readonly lifespanFilter?: LifespanStatus;\n readonly sortMode: SortMode;\n readonly searchQuery: string;\n}\n\nexport function Header({ project, typeFilter, lifespanFilter, sortMode, searchQuery }: HeaderProps): React.ReactNode {\n return (\n <Box>\n <Text bold color=\"green\"> agentic-memory </Text>\n <Text dimColor> | </Text>\n <Text color=\"white\">{project ?? 'all projects'}</Text>\n <Text dimColor> | </Text>\n <Text dimColor>{typeFilter ?? 'all types'}</Text>\n <Text dimColor> | </Text>\n <Text dimColor>{lifespanFilter ?? 'all life'}</Text>\n <Text dimColor> | </Text>\n <Text dimColor>sort:{sortMode}</Text>\n {searchQuery && (\n <>\n <Text dimColor> | </Text>\n <Text color=\"yellow\">search:{searchQuery}</Text>\n </>\n )}\n </Box>\n );\n}\n","import React from 'react';\nimport { Box, Text } from 'ink';\nimport TextInput from 'ink-text-input';\n\ninterface SearchBarProps {\n readonly query: string;\n readonly onChange: (value: string) => void;\n readonly onClose: () => void;\n}\n\nexport function SearchBar({ query, onChange, onClose }: SearchBarProps): React.ReactNode {\n return (\n <Box>\n <Text color=\"yellow\">Search: </Text>\n <TextInput value={query} onChange={onChange} onSubmit={onClose} />\n <Text dimColor> (Esc to clear, Enter to keep)</Text>\n </Box>\n );\n}\n","import React, { useMemo } from 'react';\nimport { Box, Text } from 'ink';\nimport type { Memory } from '../../types.js';\nimport { truncate, formatRelativeTime, computeLifespan, formatLifespanLabel } from '../data/formatters.js';\nimport { TYPE_ABBREV } from '../colors.js';\n\ninterface MemoryListProps {\n readonly memories: readonly Memory[];\n readonly selectedIndex: number;\n readonly isFocused: boolean;\n readonly height: number;\n}\n\ntype LifeColor = 'green' | 'yellow' | 'red' | 'magenta';\n\nconst LIFE_COLORS: Record<string, LifeColor> = {\n healthy: 'green',\n fading: 'yellow',\n stale: 'red',\n session: 'magenta',\n};\n\nexport function MemoryList({ memories, selectedIndex, isFocused, height }: MemoryListProps): React.ReactNode {\n const viewportHeight = Math.max(1, height - 2);\n\n const scrollOffset = useMemo(() => {\n if (selectedIndex < 0) return 0;\n if (memories.length <= viewportHeight) return 0;\n const half = Math.floor(viewportHeight / 2);\n const offset = Math.max(0, selectedIndex - half);\n return Math.min(offset, memories.length - viewportHeight);\n }, [selectedIndex, memories.length, viewportHeight]);\n\n const visible = memories.slice(scrollOffset, scrollOffset + viewportHeight);\n const label = ` Memories [${memories.length}] `;\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={isFocused ? 'cyan' : 'gray'}\n >\n <Text bold color={isFocused ? 'cyan' : 'gray'}>{label}</Text>\n {visible.length === 0 && <Text dimColor> No memories found</Text>}\n {visible.map((m, i) => {\n const isSelected = scrollOffset + i === selectedIndex;\n return <MemoryRow key={m.id} memory={m} isSelected={isSelected} />;\n })}\n </Box>\n );\n}\n\nfunction MemoryRow({ memory, isSelected }: { memory: Memory; isSelected: boolean }): React.ReactNode {\n const life = computeLifespan(memory);\n const title = truncate(memory.title ?? memory.content.replace(/\\n/g, ' '), 36);\n const project = truncate(memory.project ?? '', 14);\n const type = TYPE_ABBREV[memory.type] ?? memory.type;\n const lifeColor = LIFE_COLORS[life.status] ?? 'white';\n const lifeLabel = formatLifespanLabel(life.status).trim();\n const imp = `${Math.round(memory.importance * 100)}%`;\n const updated = formatRelativeTime(memory.updatedAt);\n\n return (\n <Box>\n <Text inverse={isSelected}>\n <Text bold>{isSelected ? '▸ ' : ' '}</Text>\n <Text bold>{title.padEnd(38)}</Text>\n <Text dimColor>{project.padEnd(16)}</Text>\n <Text color=\"cyan\">{type} </Text>\n <Text color={lifeColor}>{lifeLabel.padEnd(8)}</Text>\n <Text>{imp.padStart(4)} </Text>\n <Text dimColor>{updated.padEnd(8)}</Text>\n <Text color=\"blue\">acc:{memory.accessCount}</Text>\n </Text>\n </Box>\n );\n}\n","import type { MemoryType, RelationType } from \"../types.js\";\n\n// -- Type Colors (blessed-compatible color names) -----------------------------\n\nexport const TYPE_COLORS: Record<MemoryType, string> = {\n working: \"red\",\n episodic: \"yellow\",\n semantic: \"cyan\",\n procedural: \"green\",\n pattern: \"magenta\",\n};\n\n// -- Type Abbreviations (4-char max) ------------------------------------------\n\nexport const TYPE_ABBREV: Record<MemoryType, string> = {\n working: \"WORK\",\n episodic: \"EPIS\",\n semantic: \"SEMA\",\n procedural: \"PROC\",\n pattern: \"PTRN\",\n};\n\n// -- Relation Colors ----------------------------------------------------------\n\nexport const RELATION_COLORS: Record<RelationType, string> = {\n relates_to: \"white\",\n depends_on: \"blue\",\n contradicts: \"red\",\n extends: \"green\",\n implements: \"cyan\",\n derived_from: \"yellow\",\n};\n","import React from 'react';\nimport { Box, Text } from 'ink';\nimport type { Memory, Relation } from '../../types.js';\nimport {\n formatImportanceBar,\n formatRelativeTime,\n computeLifespan,\n formatLifespanLabel,\n} from '../data/formatters.js';\nimport { TYPE_COLORS, RELATION_COLORS } from '../colors.js';\n\ninterface MemoryDetailProps {\n readonly memory?: Memory;\n readonly relations: readonly Relation[];\n readonly isFocused: boolean;\n}\n\nexport function MemoryDetail({ memory, relations, isFocused }: MemoryDetailProps): React.ReactNode {\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={isFocused ? 'blue' : 'gray'}\n paddingX={1}\n >\n <Text bold color={isFocused ? 'blue' : 'gray'}> Detail </Text>\n {!memory ? (\n <Text dimColor>Select a memory to view details</Text>\n ) : (\n <DetailContent memory={memory} relations={relations} />\n )}\n </Box>\n );\n}\n\nfunction DetailContent({ memory, relations }: { memory: Memory; relations: readonly Relation[] }): React.ReactNode {\n const life = computeLifespan(memory);\n const typeColor = TYPE_COLORS[memory.type] ?? 'white';\n\n return (\n <Box flexDirection=\"column\">\n <Text bold>{memory.title ?? '(untitled)'}</Text>\n <Text> </Text>\n <Text>Type: <Text color={typeColor}>{memory.type}</Text></Text>\n <Text>Lifespan: {formatLifespanLabel(life.status)} | age {Math.round(life.ageDays)}d | tau {life.tauDays}d</Text>\n <Text>Health: {formatImportanceBar(life.remaining)} {(life.remaining * 100).toFixed(0)}%</Text>\n <Text>Importance: {formatImportanceBar(memory.importance)} {memory.importance.toFixed(2)}</Text>\n <Text>Project: {memory.project ?? '(none)'}</Text>\n <Text>Tags: {memory.tags.length > 0 ? memory.tags.map((t) => `[${t}]`).join(' ') : '(none)'}</Text>\n <Text>Source: {memory.source ?? 'unknown'}</Text>\n <Text> </Text>\n <Text>Created: {formatRelativeTime(memory.createdAt)}</Text>\n <Text>Updated: {formatRelativeTime(memory.updatedAt)}</Text>\n <Text>Accessed: {memory.accessCount}x{memory.lastAccessed ? ` (last: ${formatRelativeTime(memory.lastAccessed)})` : ''}</Text>\n <Text>Injected: {memory.injectionCount}x</Text>\n <Text> </Text>\n <Text bold>Content</Text>\n <Text dimColor>{'─'.repeat(40)}</Text>\n <Text>{memory.content}</Text>\n {relations.length > 0 && <RelationsList relations={relations} memoryId={memory.id} />}\n </Box>\n );\n}\n\nfunction RelationsList({ relations, memoryId }: { relations: readonly Relation[]; memoryId: string }): React.ReactNode {\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text bold>Relations</Text>\n <Text dimColor>{'─'.repeat(40)}</Text>\n {relations.map((r, i) => {\n const relColor = RELATION_COLORS[r.relationType] ?? 'white';\n const direction = r.sourceId === memoryId ? '→' : '←';\n const otherId = r.sourceId === memoryId ? r.targetId : r.sourceId;\n return (\n <Text key={i}> {direction} <Text color={relColor}>{r.relationType}</Text> {otherId}</Text>\n );\n })}\n </Box>\n );\n}\n","import React, { useMemo } from 'react';\nimport { Box, Text } from 'ink';\nimport type { Memory } from '../../types.js';\nimport { computeLifespan } from '../data/formatters.js';\n\ninterface ProjectListProps {\n readonly memories: readonly Memory[];\n readonly activeProject?: string;\n readonly isFocused: boolean;\n}\n\ninterface ProjectRow {\n readonly project: string | undefined;\n readonly total: number;\n readonly healthPct: number;\n}\n\nexport function ProjectList({ memories, activeProject, isFocused }: ProjectListProps): React.ReactNode {\n const rows = useMemo(() => buildProjectRows(memories), [memories]);\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={isFocused ? 'magenta' : 'gray'}\n >\n <Text bold color={isFocused ? 'magenta' : 'gray'}> Projects </Text>\n {rows.map((row) => {\n const isActive = row.project === activeProject || (row.project === undefined && !activeProject);\n const name = (row.project ?? 'All projects').padEnd(20).slice(0, 20);\n const healthColor = row.healthPct > 62 ? 'green' : row.healthPct > 32 ? 'yellow' : 'red';\n return (\n <Box key={row.project ?? '_all'}>\n <Text bold={isActive}>{isActive ? '> ' : ' '}</Text>\n <Text bold={isActive}>{name}</Text>\n <Text color=\"cyan\">{String(row.total).padStart(4)} mem</Text>\n <Text> </Text>\n <Text color={healthColor}>{String(row.healthPct).padStart(3)}%</Text>\n </Box>\n );\n })}\n </Box>\n );\n}\n\nfunction buildProjectRows(memories: readonly Memory[]): readonly ProjectRow[] {\n const byProject = new Map<string, Memory[]>();\n for (const m of memories) {\n const key = m.project ?? '(none)';\n const list = byProject.get(key) ?? [];\n list.push(m);\n byProject.set(key, list);\n }\n\n const rows: ProjectRow[] = [];\n for (const [project, mems] of byProject) {\n const avg = mems.reduce((s, m) => s + computeLifespan(m).remaining, 0) / mems.length;\n rows.push({ project, total: mems.length, healthPct: Math.round(avg * 100) });\n }\n rows.sort((a, b) => b.total - a.total);\n\n const allHealth = memories.length > 0\n ? Math.round((memories.reduce((s, m) => s + computeLifespan(m).remaining, 0) / memories.length) * 100)\n : 0;\n return [{ project: undefined, total: memories.length, healthPct: allHealth }, ...rows];\n}\n","import React from 'react';\nimport { Box, Text } from 'ink';\nimport type { DashboardStats } from '../data/data-source.js';\nimport type { Memory } from '../../types.js';\nimport { formatBytes, computeLifespan } from '../data/formatters.js';\nimport { TYPE_COLORS } from '../colors.js';\n\ninterface StatsBarProps {\n readonly stats: DashboardStats;\n readonly visible: readonly Memory[];\n}\n\nexport function StatsBar({ stats, visible }: StatsBarProps): React.ReactNode {\n const lifeCounts = { healthy: 0, fading: 0, stale: 0, session: 0 };\n for (const m of visible) {\n lifeCounts[computeLifespan(m).status]++;\n }\n\n const typeEntries = Object.entries(stats.byType).filter(([, c]) => c > 0);\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"single\" borderColor=\"gray\" paddingX={1}>\n <Box gap={2}>\n <Text><Text bold>Total:</Text> {stats.total}</Text>\n <Text><Text bold>Relations:</Text> {stats.relations}</Text>\n <Text><Text bold>Visible:</Text> {visible.length}</Text>\n <Text><Text bold>DB:</Text> {formatBytes(stats.dbSizeBytes)}</Text>\n </Box>\n <Box gap={2}>\n <Text>\n <Text color=\"green\">H:{lifeCounts.healthy}</Text>\n {' '}<Text color=\"yellow\">F:{lifeCounts.fading}</Text>\n {' '}<Text color=\"red\">S:{lifeCounts.stale}</Text>\n {' '}<Text color=\"magenta\">Sess:{lifeCounts.session}</Text>\n </Text>\n {typeEntries.map(([type, count]) => (\n <Text key={type} color={TYPE_COLORS[type as keyof typeof TYPE_COLORS] ?? 'white'}>\n {type}:{count}\n </Text>\n ))}\n </Box>\n </Box>\n );\n}\n","import React from 'react';\nimport { Box, Text, useInput } from 'ink';\n\ninterface HelpOverlayProps {\n readonly onClose: () => void;\n}\n\nconst BINDINGS = [\n ['j / k / ↑↓', 'Navigate list'],\n ['Enter', 'Select memory'],\n ['/', 'Search (live filter)'],\n ['Esc', 'Clear search'],\n ['1-5', 'Filter by type (0 = all)'],\n ['l', 'Cycle lifespan filter'],\n ['s', 'Cycle sort mode'],\n ['p', 'Open project picker'],\n ['[ / ]', 'Previous / next project'],\n ['Tab', 'Focus next pane'],\n ['r', 'Refresh'],\n ['?', 'Show this help'],\n ['q', 'Quit'],\n] as const;\n\nexport function HelpOverlay({ onClose }: HelpOverlayProps): React.ReactNode {\n useInput(() => onClose());\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"double\"\n borderColor=\"yellow\"\n paddingX={2}\n paddingY={1}\n >\n <Text bold color=\"yellow\">Keybindings</Text>\n <Text> </Text>\n {BINDINGS.map(([key, desc]) => (\n <Box key={key} gap={1}>\n <Text color=\"cyan\">{key.padEnd(14)}</Text>\n <Text>{desc}</Text>\n </Box>\n ))}\n <Text> </Text>\n <Text dimColor>Press any key to close</Text>\n </Box>\n );\n}\n","import React from 'react';\nimport { Box, Text, useInput } from 'ink';\n\ninterface ProjectPickerProps {\n readonly projects: readonly string[];\n readonly activeProject?: string;\n readonly onSelect: (project: string | undefined) => void;\n readonly onClose: () => void;\n}\n\nexport function ProjectPicker({ projects, activeProject, onSelect, onClose }: ProjectPickerProps): React.ReactNode {\n const [selectedIdx, setSelectedIdx] = React.useState(() => {\n if (!activeProject) return 0;\n const idx = projects.indexOf(activeProject);\n return idx >= 0 ? idx + 1 : 0;\n });\n\n const options = [\n { label: 'All projects', project: undefined as string | undefined },\n ...projects.map((p) => ({ label: p, project: p as string | undefined })),\n ];\n\n useInput((input, key) => {\n if (key.escape) { onClose(); return; }\n if (input === 'j' || key.downArrow) setSelectedIdx((i) => Math.min(options.length - 1, i + 1));\n if (input === 'k' || key.upArrow) setSelectedIdx((i) => Math.max(0, i - 1));\n if (key.return) {\n onSelect(options[selectedIdx]?.project);\n onClose();\n }\n });\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"double\" borderColor=\"yellow\" paddingX={2} paddingY={1}>\n <Text bold color=\"yellow\">Project Picker</Text>\n <Text dimColor>Enter=select Esc=close</Text>\n <Text> </Text>\n {options.map((opt, i) => {\n const isSelected = i === selectedIdx;\n const isActive = opt.project === activeProject || (opt.project === undefined && !activeProject);\n return (\n <Text key={opt.label} inverse={isSelected}>\n {isActive ? '> ' : ' '}{opt.label}\n </Text>\n );\n })}\n </Box>\n );\n}\n"],"mappings":"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","names":["Box","useState","useEffect","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","useMemo","Box","Text","jsx","jsxs","useMemo","Box","Text","Box","Text","jsx","jsxs","Box","Text","useMemo","Box","Text","jsx","jsxs","useMemo","Box","Text","Box","Text","jsx","jsxs","Box","Text","Box","Text","useInput","jsx","jsxs","React","Box","Text","useInput","jsx","jsxs","jsx","jsxs","Box","jsx"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-launchpad",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "CLI toolkit that makes Claude Code setups measurably good - scaffold, diagnose, evaluate, remember",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -56,14 +56,18 @@
|
|
|
56
56
|
},
|
|
57
57
|
"optionalDependencies": {
|
|
58
58
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
59
|
-
"
|
|
59
|
+
"ink": "^6.8.0",
|
|
60
|
+
"ink-select-input": "^6.2.0",
|
|
61
|
+
"ink-spinner": "^5.0.0",
|
|
62
|
+
"ink-text-input": "^6.0.0",
|
|
63
|
+
"react": "^19.2.4",
|
|
60
64
|
"zod": "^4.0.0"
|
|
61
65
|
},
|
|
62
66
|
"devDependencies": {
|
|
63
67
|
"@anthropic-ai/claude-agent-sdk": "^0.2.86",
|
|
64
68
|
"@types/better-sqlite3": "^7.6.12",
|
|
65
|
-
"@types/blessed": "^0.1.25",
|
|
66
69
|
"@types/node": "^25.5.0",
|
|
70
|
+
"@types/react": "^19.2.14",
|
|
67
71
|
"better-sqlite3": "^11.10.0",
|
|
68
72
|
"sqlite-vec": "^0.1.9",
|
|
69
73
|
"tsup": "^8.5.1",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/memory/types.ts"],"sourcesContent":["import { z } from 'zod';\n\n// ── Memory Types ──────────────────────────────────────────────\n\nexport const MEMORY_TYPES = ['working', 'episodic', 'semantic', 'procedural', 'pattern'] as const;\nexport type MemoryType = typeof MEMORY_TYPES[number];\n\nexport const MEMORY_SOURCES = ['manual', 'session_end', 'consolidation', 'hook', 'import'] as const;\nexport type MemorySource = typeof MEMORY_SOURCES[number];\n\nexport const RELATION_TYPES = [\n 'relates_to', 'depends_on', 'contradicts', 'extends', 'implements', 'derived_from',\n] as const;\nexport type RelationType = typeof RELATION_TYPES[number];\n\n// ── Core Entities ─────────────────────────────────────────────\n\nexport interface Memory {\n readonly id: string;\n readonly type: MemoryType;\n readonly title: string | null;\n readonly content: string;\n readonly context: string | null;\n readonly source: MemorySource | null;\n readonly project: string | null;\n readonly tags: readonly string[];\n readonly importance: number;\n readonly createdAt: string;\n readonly updatedAt: string;\n readonly accessCount: number;\n readonly lastAccessed: string | null;\n readonly injectionCount: number;\n}\n\nexport interface Relation {\n readonly sourceId: string;\n readonly targetId: string;\n readonly relationType: RelationType;\n readonly createdAt: string;\n}\n\n// ── Search Types ──────────────────────────────────────────────\n\nexport interface SearchResult {\n readonly memory: Memory;\n readonly score: number;\n readonly explanation: string;\n}\n\nexport interface FtsMatch {\n readonly rowid: number;\n readonly memoryId: string;\n readonly rank: number;\n}\n\nexport interface ScoredCandidate {\n readonly memoryId: string;\n readonly textScore: number;\n readonly importanceScore: number;\n readonly recencyScore: number;\n readonly accessScore: number;\n readonly contextScore: number;\n readonly composite: number;\n}\n\n// ── Decay Parameters ──────────────────────────────────────────\n\nexport interface DecayParams {\n readonly tauByType: Record<MemoryType, number>;\n readonly accessModifiers: readonly { readonly maxCount: number; readonly multiplier: number }[];\n readonly relationModifier: { readonly connectedThreshold: number; readonly connectedMultiplier: number; readonly isolatedMultiplier: number };\n readonly importanceFloor: number;\n readonly pruneThreshold: number;\n readonly pruneMinAgeDays: number;\n}\n\n// ── Input Schemas (for MCP tools) ─────────────────────────────\n\nexport const StoreInputSchema = z.object({\n type: z.enum(MEMORY_TYPES),\n content: z.string().min(1).max(10000),\n title: z.string().max(200).optional(),\n tags: z.array(z.string()).max(20).default([]),\n importance: z.number().min(0).max(1).default(0.5),\n context: z.string().optional(),\n source: z.enum(MEMORY_SOURCES).default('manual'),\n project: z.string().max(200).optional(),\n});\nexport type StoreInput = z.infer<typeof StoreInputSchema>;\n\nexport const SearchInputSchema = z.object({\n query: z.string().min(1).max(500),\n id: z.string().optional(),\n type: z.enum(MEMORY_TYPES).optional(),\n tags: z.array(z.string()).max(10).optional(),\n limit: z.number().int().min(1).max(50).default(10),\n min_importance: z.number().min(0).max(1).default(0),\n project: z.string().max(200).optional(),\n});\nexport type SearchInput = z.infer<typeof SearchInputSchema>;\n\nexport const ForgetInputSchema = z.object({\n id: z.string(),\n hard_delete: z.boolean().default(false),\n});\nexport type ForgetInput = z.infer<typeof ForgetInputSchema>;\n\nexport const RelateInputSchema = z.object({\n source_id: z.string(),\n target_id: z.string(),\n relation_type: z.enum(RELATION_TYPES),\n});\nexport type RelateInput = z.infer<typeof RelateInputSchema>;\n\n// ── Sync Types ───────────────────────────────────────────────\n\nexport interface SyncPayload {\n readonly version: number;\n readonly machine_id: string;\n readonly pushed_at: string;\n readonly memories: readonly SyncMemoryRow[];\n readonly relations: readonly SyncRelationRow[];\n}\n\nexport interface SyncMemoryRow {\n readonly id: string;\n readonly type: MemoryType;\n readonly title: string | null;\n readonly content: string;\n readonly context: string | null;\n readonly source: MemorySource | null;\n readonly project: string | null;\n readonly tags: readonly string[];\n readonly importance: number;\n readonly access_count: number;\n readonly injection_count: number;\n readonly created_at: string;\n readonly updated_at: string;\n readonly last_accessed: string | null;\n}\n\nexport interface SyncRelationRow {\n readonly source_id: string;\n readonly target_id: string;\n readonly relation_type: RelationType;\n readonly created_at: string;\n}\n\nexport const SyncPayloadSchema = z.object({\n version: z.number(),\n machine_id: z.string(),\n pushed_at: z.string(),\n memories: z.array(z.object({\n id: z.string(),\n type: z.enum(MEMORY_TYPES),\n title: z.string().nullable(),\n content: z.string(),\n context: z.string().nullable(),\n source: z.enum(MEMORY_SOURCES).nullable(),\n project: z.string().nullable(),\n tags: z.array(z.string()),\n importance: z.number(),\n access_count: z.number(),\n injection_count: z.number(),\n created_at: z.string(),\n updated_at: z.string(),\n last_accessed: z.string().nullable(),\n })),\n relations: z.array(z.object({\n source_id: z.string(),\n target_id: z.string(),\n relation_type: z.enum(RELATION_TYPES),\n created_at: z.string(),\n })),\n});\n\nexport interface SyncConfig {\n readonly gistId: string;\n}\n\nexport interface MergeResult {\n readonly inserted: number;\n readonly updated: number;\n readonly relationsAdded: number;\n}\n\n// ── Stats ─────────────────────────────────────────────────────\n\nexport interface MemoryStats {\n readonly totalMemories: number;\n readonly byType: Record<MemoryType, number>;\n readonly totalRelations: number;\n readonly dbSizeBytes: number;\n readonly oldestMemory: string | null;\n readonly newestMemory: string | null;\n readonly topInjected: readonly { readonly id: string; readonly title: string | null; readonly injectionCount: number }[];\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/memory/config.ts","../src/commands/memory/storage/database.ts","../src/commands/memory/storage/migrations/001-initial.ts","../src/commands/memory/storage/migrations/002-add-project.ts","../src/commands/memory/storage/migrator.ts"],"sourcesContent":["import { z } from 'zod';\nimport { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport type { DecayParams } from './types.js';\n\n// ── Config Schema ─────────────────────────────────────────────\n\nconst ConfigSchema = z.object({\n dataDir: z.string().default('~/.agentic-memory'),\n injectionBudget: z.number().int().min(100).max(20000).default(2000),\n consolidationInterval: z.number().int().min(1).default(10),\n enableReranker: z.boolean().default(true),\n logLevel: z.enum(['debug', 'info', 'warn', 'error']).default('warn'),\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\n\n// ── Defaults ──────────────────────────────────────────────────\n\nexport const DEFAULT_CONFIG: Config = {\n dataDir: '~/.agentic-memory',\n injectionBudget: 2000,\n consolidationInterval: 10,\n enableReranker: true,\n logLevel: 'warn',\n};\n\nexport const DEFAULT_DECAY_PARAMS: DecayParams = {\n tauByType: {\n working: 0, // cleared each session, tau irrelevant\n episodic: 60, // fast decay\n semantic: 365, // slow decay\n procedural: 730, // near-permanent\n pattern: 180, // medium decay\n },\n accessModifiers: [\n { maxCount: 3, multiplier: 1.0 },\n { maxCount: 10, multiplier: 2.0 },\n { maxCount: Infinity, multiplier: 4.0 },\n ],\n relationModifier: {\n connectedThreshold: 3,\n connectedMultiplier: 0.7,\n isolatedMultiplier: 1.3,\n },\n importanceFloor: 0.05,\n pruneThreshold: 0.1,\n pruneMinAgeDays: 90,\n};\n\nexport const SCORING_WEIGHTS = {\n text: 0.35,\n importance: 0.20,\n recency: 0.20,\n access: 0.10,\n context: 0.15,\n} as const;\n\n// ── Injection Algorithm Constants ──────────────────────────────\n\nexport const INJECTION_WEIGHTS = {\n context: 0.30,\n value: 0.25,\n importance: 0.20,\n recency: 0.15,\n typeBonus: 0.05,\n noise: 0.05,\n} as const;\n\nexport const TYPE_INJECTION_BONUS: Record<string, number> = {\n procedural: 1.0,\n pattern: 0.8,\n semantic: 0.6,\n episodic: 0.3,\n working: 0.0,\n};\n\nexport const RECENCY_HALF_LIFE: Record<string, number> = {\n working: 1,\n episodic: 7,\n pattern: 14,\n semantic: 30,\n procedural: 90,\n};\n\nexport const INJECTION_MIN_SCORE = 0.25;\nexport const INJECTION_COLD_START_THRESHOLD = 5;\nexport const INJECTION_HEADER_TOKENS = 50;\n\n// ── Config Loader ─────────────────────────────────────────────\n\nexport function resolveDataDir(dataDir: string): string {\n if (dataDir.startsWith('~')) {\n return join(homedir(), dataDir.slice(1));\n }\n return dataDir;\n}\n\nexport function loadConfig(overrides?: Partial<Config>): Config {\n const envOverrides: Record<string, unknown> = {};\n\n const envBudget = process.env['AGENTIC_MEMORY_INJECTION_BUDGET'];\n if (envBudget !== undefined) {\n envOverrides['injectionBudget'] = parseInt(envBudget, 10);\n }\n\n const envLogLevel = process.env['AGENTIC_MEMORY_LOG_LEVEL'];\n if (envLogLevel !== undefined) {\n envOverrides['logLevel'] = envLogLevel;\n }\n\n const envDataDir = process.env['AGENTIC_MEMORY_DATA_DIR'];\n if (envDataDir !== undefined) {\n envOverrides['dataDir'] = envDataDir;\n }\n\n // Try loading config.json from data dir\n let fileConfig: Record<string, unknown> = {};\n const baseDir = resolveDataDir(overrides?.dataDir ?? envOverrides['dataDir'] as string ?? DEFAULT_CONFIG.dataDir);\n try {\n const raw = readFileSync(join(baseDir, 'config.json'), 'utf-8');\n fileConfig = JSON.parse(raw) as Record<string, unknown>;\n } catch (err) {\n const isNotFound = err instanceof Error && 'code' in err && (err as NodeJS.ErrnoException).code === 'ENOENT';\n if (!isNotFound) {\n // Malformed JSON or permissions error - warn, don't silently ignore\n console.error('[agentic-memory] Failed to load config.json:', err instanceof Error ? err.message : err);\n }\n }\n\n const merged = { ...DEFAULT_CONFIG, ...fileConfig, ...envOverrides, ...overrides };\n return ConfigSchema.parse(merged);\n}\n\n// ── Token Estimation ──────────────────────────────────────────\n\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n","import type DatabaseConstructor from 'better-sqlite3';\nimport { resolveDataDir } from '../config.js';\nimport { mkdirSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { cwdRequire } from '../utils/require-deps.js';\n\nexport interface DatabaseOptions {\n readonly dbPath?: string; // full path override (e.g. ':memory:' for tests)\n readonly dataDir?: string; // resolved data dir (default ~/.agentic-memory)\n}\n\nexport function createDatabase(options: DatabaseOptions = {}): DatabaseConstructor.Database {\n const dbPath = options.dbPath ?? resolveDbPath(options.dataDir);\n\n if (dbPath !== ':memory:') {\n mkdirSync(dirname(dbPath), { recursive: true });\n }\n\n const Database = cwdRequire('better-sqlite3') as typeof DatabaseConstructor;\n const sqliteVec = cwdRequire('sqlite-vec') as { load: (db: DatabaseConstructor.Database) => void };\n\n const db = new Database(dbPath);\n\n // Load sqlite-vec extension\n sqliteVec.load(db);\n\n // Configure PRAGMAs (order matters: foreign_keys before any ops, journal_mode is persistent)\n db.pragma('journal_mode = WAL');\n db.pragma('busy_timeout = 5000');\n db.pragma('foreign_keys = ON');\n db.pragma('cache_size = -64000');\n db.pragma('mmap_size = 268435456');\n db.pragma('synchronous = NORMAL');\n db.pragma('temp_store = MEMORY');\n db.pragma('journal_size_limit = 33554432');\n\n return db;\n}\n\nexport function closeDatabase(db: DatabaseConstructor.Database): void {\n try {\n db.pragma('wal_checkpoint(TRUNCATE)');\n } catch {\n // Checkpoint may fail on :memory: - that's fine\n }\n db.close();\n}\n\nfunction resolveDbPath(dataDir?: string): string {\n const dir = resolveDataDir(dataDir ?? '~/.agentic-memory');\n return join(dir, 'memory.db');\n}\n","import type Database from 'better-sqlite3';\n\nexport const version = 1;\n\nexport function up(db: Database.Database): void {\n db.exec(`\n CREATE TABLE IF NOT EXISTS meta (\n key TEXT PRIMARY KEY,\n value TEXT\n );\n\n CREATE TABLE IF NOT EXISTS memories (\n id TEXT PRIMARY KEY,\n type TEXT NOT NULL CHECK(type IN ('episodic','semantic','procedural','working','pattern')),\n title TEXT,\n content TEXT NOT NULL,\n context TEXT,\n source TEXT CHECK(source IN ('manual','session_end','consolidation','hook','import')),\n tags TEXT NOT NULL DEFAULT '[]',\n importance REAL NOT NULL DEFAULT 0.5 CHECK(importance >= 0.0 AND importance <= 1.0),\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now')),\n access_count INTEGER NOT NULL DEFAULT 0 CHECK(access_count >= 0),\n last_accessed TEXT,\n injection_count INTEGER NOT NULL DEFAULT 0 CHECK(injection_count >= 0),\n embedding BLOB\n );\n\n CREATE TABLE IF NOT EXISTS relations (\n source_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n target_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n relation_type TEXT NOT NULL CHECK(relation_type IN (\n 'relates_to','depends_on','contradicts','extends','implements','derived_from'\n )),\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n PRIMARY KEY (source_id, target_id, relation_type)\n );\n\n -- FTS5 external content (no data duplication)\n CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(\n title, content, tags,\n content=memories,\n content_rowid=rowid,\n tokenize='porter unicode61'\n );\n\n -- FTS5 sync triggers\n CREATE TRIGGER IF NOT EXISTS memories_ai AFTER INSERT ON memories BEGIN\n INSERT INTO memories_fts(rowid, title, content, tags)\n VALUES (new.rowid, new.title, new.content, new.tags);\n END;\n\n CREATE TRIGGER IF NOT EXISTS memories_ad AFTER DELETE ON memories BEGIN\n INSERT INTO memories_fts(memories_fts, rowid, title, content, tags)\n VALUES ('delete', old.rowid, old.title, old.content, old.tags);\n END;\n\n CREATE TRIGGER IF NOT EXISTS memories_au AFTER UPDATE ON memories BEGIN\n INSERT INTO memories_fts(memories_fts, rowid, title, content, tags)\n VALUES ('delete', old.rowid, old.title, old.content, old.tags);\n INSERT INTO memories_fts(rowid, title, content, tags)\n VALUES (new.rowid, new.title, new.content, new.tags);\n END;\n\n -- Vector search (synced manually in application code)\n CREATE VIRTUAL TABLE IF NOT EXISTS memories_vec USING vec0(\n memory_id TEXT PRIMARY KEY,\n embedding float[384] distance_metric=cosine\n );\n\n -- Indexes\n CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(type);\n CREATE INDEX IF NOT EXISTS idx_memories_importance ON memories(importance);\n CREATE INDEX IF NOT EXISTS idx_memories_created_at ON memories(created_at);\n CREATE INDEX IF NOT EXISTS idx_relations_target ON relations(target_id);\n `);\n}\n","import type Database from 'better-sqlite3';\n\nexport const version = 2;\n\nexport function up(db: Database.Database): void {\n db.exec(`\n ALTER TABLE memories ADD COLUMN project TEXT;\n CREATE INDEX IF NOT EXISTS idx_memories_project ON memories(project);\n `);\n}\n","import type Database from 'better-sqlite3';\nimport * as migration001 from './migrations/001-initial.js';\nimport * as migration002 from './migrations/002-add-project.js';\n\ninterface Migration {\n readonly version: number;\n readonly up: (db: Database.Database) => void;\n}\n\nconst migrations: readonly Migration[] = [\n migration001,\n migration002,\n];\n\nexport function getSchemaVersion(db: Database.Database): number {\n try {\n const row = db.prepare(\"SELECT value FROM meta WHERE key = 'schema_version'\").get() as\n { value: string } | undefined;\n return row ? parseInt(row.value, 10) : 0;\n } catch {\n return 0;\n }\n}\n\nexport function migrate(db: Database.Database): void {\n const current = getSchemaVersion(db);\n const pending = migrations.filter(m => m.version > current);\n\n if (pending.length === 0) return;\n\n const runMigrations = db.transaction(() => {\n for (const m of pending) {\n m.up(db);\n db.prepare(\"INSERT OR REPLACE INTO meta (key, value) VALUES ('schema_version', ?)\")\n .run(String(m.version));\n }\n });\n\n runMigrations();\n}\n"],"mappings":"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","names":["join","join","up","version"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/memory/subcommands/context.ts","../src/commands/memory/services/decay-service.ts","../src/commands/memory/services/consolidation-service.ts","../src/commands/memory/services/injection-service.ts"],"sourcesContent":["import { readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { DecayService } from '../services/decay-service.js';\nimport { ConsolidationService } from '../services/consolidation-service.js';\nimport { InjectionService } from '../services/injection-service.js';\nimport { detectProject } from '../utils/project.js';\nimport { getGitContext } from '../utils/git-context.js';\nimport { initStorage } from './init-storage.js';\n\ninterface ContextOpts {\n readonly json?: boolean;\n readonly dbPath?: string;\n}\n\nconst CONSOLIDATION_FILE = '.last-consolidation';\n\nfunction shouldConsolidate(dataDir: string, intervalDays: number): boolean {\n const checkpointPath = join(dataDir, CONSOLIDATION_FILE);\n try {\n const raw = readFileSync(checkpointPath, 'utf-8').trim();\n const lastRun = parseInt(raw, 10);\n if (isNaN(lastRun)) return true;\n const daysSince = (Date.now() - lastRun) / 86_400_000;\n return daysSince >= intervalDays;\n } catch {\n return true;\n }\n}\n\nfunction markConsolidated(dataDir: string): void {\n writeFileSync(join(dataDir, CONSOLIDATION_FILE), String(Date.now()), 'utf-8');\n}\n\nfunction write(msg: string): void {\n process.stdout.write(msg + '\\n');\n}\n\nexport async function runContext(opts: ContextOpts): Promise<void> {\n const ctx = initStorage(opts.dbPath);\n\n try {\n // Run maintenance (decay + consolidation) before loading context\n try {\n const decayService = new DecayService({\n memoryRepo: ctx.memoryRepo,\n relationRepo: ctx.relationRepo,\n });\n decayService.run();\n\n if (shouldConsolidate(ctx.dataDir, ctx.config.consolidationInterval)) {\n const consolidationService = new ConsolidationService({\n memoryRepo: ctx.memoryRepo,\n relationRepo: ctx.relationRepo,\n });\n await consolidationService.consolidate();\n markConsolidated(ctx.dataDir);\n }\n } catch (err) {\n process.stderr.write(`[agentic-memory] maintenance error: ${err instanceof Error ? err.message : err}\\n`);\n }\n\n const project = detectProject(process.cwd());\n const gitContext = getGitContext();\n\n const injectionService = new InjectionService({\n memoryRepo: ctx.memoryRepo,\n relationRepo: ctx.relationRepo,\n gitContext: gitContext ?? undefined,\n });\n\n const result = injectionService.selectForInjection(\n ctx.config.injectionBudget,\n project ?? undefined,\n );\n\n write(injectionService.formatInjection(result));\n } finally {\n ctx.close();\n }\n}\n","import type { Memory, DecayParams } from '../types.js';\nimport type { MemoryRepo } from '../storage/memory-repo.js';\nimport type { RelationRepo } from '../storage/relation-repo.js';\nimport { DEFAULT_DECAY_PARAMS } from '../config.js';\n\n// ── Types ────────────────────────────────────────────────────\n\nexport interface DecayServiceDeps {\n readonly memoryRepo: MemoryRepo;\n readonly relationRepo: RelationRepo;\n readonly params?: DecayParams;\n}\n\nexport interface DecayReport {\n readonly decayed: number;\n readonly pruned: number;\n readonly workingCleared: number;\n}\n\n// ── Decay Service ────────────────────────────────────────────\n\nexport class DecayService {\n readonly #memoryRepo: MemoryRepo;\n readonly #relationRepo: RelationRepo;\n readonly #params: DecayParams;\n\n constructor(deps: DecayServiceDeps) {\n this.#memoryRepo = deps.memoryRepo;\n this.#relationRepo = deps.relationRepo;\n this.#params = deps.params ?? DEFAULT_DECAY_PARAMS;\n }\n\n /**\n * Run full decay cycle: clear working memories, apply decay, prune dead memories.\n */\n run(): DecayReport {\n const workingCleared = this.clearWorkingMemories();\n const decayed = this.decayAll();\n const pruned = this.prune();\n return { decayed, pruned, workingCleared };\n }\n\n clearWorkingMemories(): number {\n return this.#memoryRepo.deleteByType('working');\n }\n\n /**\n * Apply decay formula to all non-working memories.\n */\n decayAll(): number {\n const memories = this.#memoryRepo.getAll();\n let updated = 0;\n\n for (const memory of memories) {\n if (memory.type === 'working') continue;\n\n const newImportance = this.computeDecayedImportance(memory);\n if (Math.abs(newImportance - memory.importance) > 0.001) {\n this.#memoryRepo.updateImportanceOnly(memory.id, newImportance);\n updated++;\n }\n }\n\n return updated;\n }\n\n /**\n * Hard-delete memories below prune threshold.\n */\n prune(): number {\n const memories = this.#memoryRepo.getAll();\n const now = Date.now();\n let pruned = 0;\n\n for (const memory of memories) {\n if (memory.type === 'working') continue;\n\n const ageDays = (now - new Date(memory.createdAt).getTime()) / (1000 * 60 * 60 * 24);\n if (\n ageDays > this.#params.pruneMinAgeDays &&\n memory.importance < this.#params.pruneThreshold &&\n memory.accessCount === 0\n ) {\n this.#memoryRepo.hardDelete(memory.id);\n pruned++;\n }\n }\n\n return pruned;\n }\n\n /**\n * Compute decayed importance as a pure function of age from creation.\n * Uses createdAt (immutable) to avoid compounding decay across sessions.\n */\n computeDecayedImportance(memory: Memory): number {\n const tau = this.#params.tauByType[memory.type];\n if (tau === 0) return memory.importance;\n\n const ageDays = (Date.now() - new Date(memory.createdAt).getTime()) / (1000 * 60 * 60 * 24);\n if (ageDays < 0) return memory.importance;\n\n // Synaptic consolidation window (days 0-7)\n if (ageDays <= 7) {\n if (memory.type === 'episodic') {\n const ebbinghaus = Math.exp(-ageDays * 0.4);\n return Math.max(this.#params.importanceFloor, memory.importance * ebbinghaus);\n }\n return memory.importance;\n }\n\n // Access modifier: higher access count = larger tau = slower decay\n const accessModifier = this.getAccessModifier(memory.accessCount);\n\n // Relation modifier: connected memories decay slower\n const relationCount = this.#relationRepo.countByMemory(memory.id);\n const relationModifier = relationCount >= this.#params.relationModifier.connectedThreshold\n ? this.#params.relationModifier.connectedMultiplier\n : this.#params.relationModifier.isolatedMultiplier;\n\n let effectiveTau = tau * accessModifier * relationModifier;\n\n // Injection penalty: surfaced but never used = noise\n if (memory.injectionCount > 5 && memory.accessCount === 0) {\n effectiveTau /= 1.5;\n }\n\n const decayFactor = Math.exp(-(ageDays - 7) / effectiveTau);\n const newImportance = memory.importance * decayFactor;\n\n return Math.max(this.#params.importanceFloor, newImportance);\n }\n\n private getAccessModifier(accessCount: number): number {\n for (const tier of this.#params.accessModifiers) {\n if (accessCount <= tier.maxCount) return tier.multiplier;\n }\n return 1.0;\n }\n}\n","import type { MemoryRepo } from '../storage/memory-repo.js';\nimport type { RelationRepo } from '../storage/relation-repo.js';\n\n// ── Types ────────────────────────────────────────────────────\n\nexport interface ConsolidationDeps {\n readonly memoryRepo: MemoryRepo;\n readonly relationRepo: RelationRepo;\n}\n\nexport interface ConsolidationReport {\n readonly deduplicated: number;\n readonly episodicsCompressed: number;\n readonly pruned: number;\n}\n\n// ── Consolidation Service ────────────────────────────────────\n\nexport class ConsolidationService {\n readonly #deps: ConsolidationDeps;\n\n constructor(deps: ConsolidationDeps) {\n this.#deps = deps;\n }\n\n /**\n * Run consolidation pipeline.\n * Phase 1: Deduplicate exact/near-exact content matches\n * Phase 2: Compress old consolidated episodics\n * Phase 3: Prune dead memories\n */\n async consolidate(): Promise<ConsolidationReport> {\n const deduplicated = this.deduplicateMemories();\n const episodicsCompressed = this.compressEpisodics();\n const pruned = this.prune();\n return { deduplicated, episodicsCompressed, pruned };\n }\n\n /**\n * Phase 1: Deduplication via content similarity.\n */\n deduplicateMemories(): number {\n const memories = this.#deps.memoryRepo.getAll();\n const seen = new Set<string>();\n let merged = 0;\n\n for (const memory of memories) {\n if (seen.has(memory.id)) continue;\n\n const normalizedContent = normalizeText(memory.content);\n\n for (const other of memories) {\n if (other.id === memory.id) continue;\n if (seen.has(other.id)) continue;\n\n const otherNormalized = normalizeText(other.content);\n if (normalizedContent !== otherNormalized) continue;\n\n const [keeper, discard] = memory.importance >= other.importance\n ? [memory, other] : [other, memory];\n\n const mergedTags = [...new Set([...keeper.tags, ...discard.tags])];\n this.#deps.memoryRepo.updateContent(keeper.id, {\n tags: mergedTags,\n importance: Math.max(keeper.importance, discard.importance),\n });\n\n this.#deps.memoryRepo.hardDelete(discard.id);\n seen.add(discard.id);\n merged++;\n\n if (discard.id === memory.id) break;\n }\n\n seen.add(memory.id);\n }\n\n return merged;\n }\n\n /**\n * Phase 2: Compress old episodic memories that have been consolidated.\n */\n compressEpisodics(): number {\n const episodics = this.#deps.memoryRepo.getByType('episodic');\n const now = Date.now();\n let compressed = 0;\n\n for (const memory of episodics) {\n const ageDays = (now - new Date(memory.createdAt).getTime()) / (1000 * 60 * 60 * 24);\n if (ageDays <= 60) continue;\n if (memory.accessCount > 0) continue;\n if (memory.importance >= 0.2) continue;\n\n const relations = this.#deps.relationRepo.getBySource(memory.id);\n const isConsolidated = relations.some(r => r.relationType === 'derived_from');\n if (!isConsolidated) continue;\n\n this.#deps.memoryRepo.hardDelete(memory.id);\n compressed++;\n }\n\n return compressed;\n }\n\n /**\n * Phase 3: Prune dead memories.\n */\n prune(): number {\n const memories = this.#deps.memoryRepo.getAll();\n const now = Date.now();\n let pruned = 0;\n\n for (const memory of memories) {\n if (memory.type === 'working') continue;\n const ageDays = (now - new Date(memory.createdAt).getTime()) / (1000 * 60 * 60 * 24);\n if (ageDays > 90 && memory.importance < 0.1 && memory.accessCount === 0) {\n this.#deps.memoryRepo.hardDelete(memory.id);\n pruned++;\n }\n }\n\n return pruned;\n }\n}\n\n// ── Helpers ──────────────────────────────────────────────────\n\nfunction normalizeText(text: string): string {\n return text.toLowerCase().replace(/\\s+/g, ' ').trim();\n}\n","import type { MemoryRepo } from \"../storage/memory-repo.js\";\nimport type { RelationRepo } from \"../storage/relation-repo.js\";\nimport type { Memory } from \"../types.js\";\nimport {\n estimateTokens,\n INJECTION_WEIGHTS as W,\n TYPE_INJECTION_BONUS,\n RECENCY_HALF_LIFE,\n INJECTION_MIN_SCORE,\n INJECTION_COLD_START_THRESHOLD,\n INJECTION_HEADER_TOKENS,\n} from \"../config.js\";\nimport { computeContextScore, type GitContext } from \"../utils/git-context.js\";\n\n// ── Types ──────────────────────────────────────────────────────\n\nexport type InjectionTier = \"full\" | \"summary\" | \"index\";\n\nexport interface ScoredMemory {\n readonly memory: Memory;\n readonly score: number;\n readonly tier: InjectionTier;\n readonly tokenCost: number;\n}\n\nexport interface InjectionResult {\n readonly memories: readonly ScoredMemory[];\n readonly tokensUsed: number;\n readonly tokenBudget: number;\n readonly totalCount: number;\n}\n\ninterface InjectionDeps {\n readonly memoryRepo: MemoryRepo;\n readonly relationRepo: RelationRepo;\n readonly gitContext?: GitContext;\n}\n\n// ── Service ────────────────────────────────────────────────────\n\nexport class InjectionService {\n readonly #deps: InjectionDeps;\n\n constructor(deps: InjectionDeps) {\n this.#deps = deps;\n }\n\n selectForInjection(tokenBudget: number, project?: string): InjectionResult {\n const allMemories = this.#deps.memoryRepo.getAll(project);\n const totalCount = allMemories.length;\n\n // Gate: skip working memories and below-floor importance\n const candidates = allMemories.filter(\n (m) => m.type !== \"working\" && m.importance >= 0.05,\n );\n\n if (candidates.length === 0) {\n return { memories: [], tokensUsed: 0, tokenBudget, totalCount };\n }\n\n // Cold start: inject all if few memories\n const minScore = candidates.length <= INJECTION_COLD_START_THRESHOLD\n ? 0.10\n : INJECTION_MIN_SCORE;\n\n // Score all candidates\n const scored = candidates\n .map((m) => ({ memory: m, score: this.#scoreMemory(m) }))\n .filter((s) => s.score >= minScore)\n .sort((a, b) => b.score - a.score);\n\n // Greedy token-budget packing with tier assignment\n return this.#packBudget(scored, tokenBudget, totalCount);\n }\n\n formatInjection(result: InjectionResult): string {\n const { memories, tokensUsed, tokenBudget, totalCount } = result;\n\n if (memories.length === 0) {\n return \"No memories stored for this project. Use memory_store to save knowledge across sessions.\";\n }\n\n const lines: string[] = [];\n lines.push(`# Agentic Memory (${memories.length} of ${totalCount} memories, ${tokensUsed}/${tokenBudget} tokens)`);\n lines.push(\"Use memory_search to retrieve full content for any memory listed here.\\n\");\n\n const full = memories.filter((m) => m.tier === \"full\");\n const summary = memories.filter((m) => m.tier === \"summary\");\n const index = memories.filter((m) => m.tier === \"index\");\n\n if (full.length > 0) {\n lines.push(\"## Key Memories\");\n for (const { memory: m } of full) {\n lines.push(`### ${m.title ?? \"(untitled)\"} [${m.type}]`);\n lines.push(m.content.slice(0, 500));\n if (m.tags.length > 0) lines.push(`Tags: ${m.tags.join(\", \")}`);\n lines.push(\"\");\n }\n }\n\n if (summary.length > 0) {\n lines.push(\"## Related Memories\");\n for (const { memory: m } of summary) {\n const snippet = m.content.slice(0, 150);\n const ellipsis = m.content.length > 150 ? \"...\" : \"\";\n lines.push(`- **${m.title ?? \"(untitled)\"}** [${m.type}]: ${snippet}${ellipsis}`);\n }\n lines.push(\"\");\n }\n\n if (index.length > 0) {\n lines.push(\"## Also Available (use memory_search)\");\n for (const { memory: m } of index) {\n lines.push(`- ${m.id.slice(0, 8)} ${m.title ?? \"(untitled)\"} [${m.type}]`);\n }\n }\n\n return lines.join(\"\\n\");\n }\n\n // ── Scoring ────────────────────────────────────────────────\n\n #scoreMemory(memory: Memory): number {\n const ctx = this.#contextRelevance(memory);\n const val = this.#valueSignal(memory);\n const imp = memory.importance;\n const rec = this.#recencyScore(memory);\n const typ = TYPE_INJECTION_BONUS[memory.type] ?? 0.5;\n const noise = this.#noisePenalty(memory);\n\n return (\n ctx * W.context +\n val * W.value +\n imp * W.importance +\n rec * W.recency +\n typ * W.typeBonus +\n noise * W.noise\n );\n }\n\n #contextRelevance(memory: Memory): number {\n if (!this.#deps.gitContext) return 0;\n return computeContextScore(memory.context, this.#deps.gitContext, \"\");\n }\n\n #valueSignal(memory: Memory): number {\n const { accessCount, injectionCount } = memory;\n\n // Never injected or accessed: neutral — give it a chance\n if (accessCount === 0 && injectionCount === 0) return 0.5;\n\n // Injected but never accessed: noise\n if (injectionCount > 0 && accessCount === 0) {\n return Math.max(0.0, 0.5 - Math.min(1.0, injectionCount / 10) * 0.5);\n }\n\n // Access-to-injection ratio\n const ratio = Math.min(1.0, accessCount / Math.max(1, injectionCount));\n return 0.4 + ratio * 0.6;\n }\n\n #recencyScore(memory: Memory): number {\n const halfLife = RECENCY_HALF_LIFE[memory.type] ?? 30;\n const ageDays = (Date.now() - new Date(memory.updatedAt).getTime()) / 86_400_000;\n return Math.exp(-ageDays * Math.LN2 / halfLife);\n }\n\n #noisePenalty(memory: Memory): number {\n if (memory.injectionCount <= 3) return 1.0; // no penalty for first 3\n if (memory.accessCount > 0) return 1.0; // any access = useful\n return Math.max(0.2, 1.0 - Math.log2(memory.injectionCount - 2) * 0.15);\n }\n\n // ── Token Budget Packing ───────────────────────────────────\n\n #packBudget(\n scored: readonly { readonly memory: Memory; readonly score: number }[],\n tokenBudget: number,\n totalCount: number,\n ): InjectionResult {\n const available = tokenBudget - INJECTION_HEADER_TOKENS;\n const selected: ScoredMemory[] = [];\n let tokensUsed = INJECTION_HEADER_TOKENS;\n\n for (const { memory, score } of scored) {\n if (tokensUsed >= tokenBudget) break;\n\n const tier = this.#assignTier(score, selected.length, available - (tokensUsed - INJECTION_HEADER_TOKENS));\n const cost = this.#estimateTierTokens(memory, tier);\n\n if (tokensUsed + cost <= tokenBudget) {\n selected.push({ memory, score, tier, tokenCost: cost });\n tokensUsed += cost;\n continue;\n }\n\n // Try cheaper tier\n const demoted = tier === \"full\" ? \"summary\" as const : tier === \"summary\" ? \"index\" as const : null;\n if (demoted) {\n const demotedCost = this.#estimateTierTokens(memory, demoted);\n if (tokensUsed + demotedCost <= tokenBudget) {\n selected.push({ memory, score, tier: demoted, tokenCost: demotedCost });\n tokensUsed += demotedCost;\n }\n }\n }\n\n // Track injections\n for (const entry of selected) {\n this.#deps.memoryRepo.incrementInjection(entry.memory.id);\n }\n\n return { memories: selected, tokensUsed, tokenBudget, totalCount };\n }\n\n #assignTier(score: number, position: number, remainingBudget: number): InjectionTier {\n if (position < 3 && score >= 0.60 && remainingBudget > 200) return \"full\";\n if (position < 8 && score >= 0.35 && remainingBudget > 80) return \"summary\";\n return \"index\";\n }\n\n #estimateTierTokens(memory: Memory, tier: InjectionTier): number {\n const meta = `[${memory.type}] ${memory.title ?? \"\"} (${memory.tags.join(\", \")})`;\n switch (tier) {\n case \"full\":\n return estimateTokens(memory.content.slice(0, 500)) + estimateTokens(meta) + 10;\n case \"summary\":\n return estimateTokens(memory.content.slice(0, 150)) + estimateTokens(meta) + 8;\n case \"index\":\n return estimateTokens(`${memory.id.slice(0, 8)} [${memory.type}] ${memory.title ?? \"(untitled)\"}`) + 4;\n }\n }\n}\n"],"mappings":"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","names":[]}
|