claude-launchpad 0.8.2 → 0.8.4-dev.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.
Files changed (31) hide show
  1. package/dist/chunk-CSLWJEGD.js +0 -0
  2. package/dist/chunk-FL3JGYDM.js +0 -0
  3. package/dist/{chunk-NNVJCKEP.js → chunk-JPVLFY2R.js} +36 -1
  4. package/dist/chunk-JPVLFY2R.js.map +1 -0
  5. package/dist/chunk-MQJA7TGY.js +60 -0
  6. package/dist/chunk-MQJA7TGY.js.map +1 -0
  7. package/dist/chunk-NAW47BYA.js +0 -0
  8. package/dist/chunk-TALTTAMW.js +0 -0
  9. package/dist/chunk-UN2XVQ5K.js +0 -0
  10. package/dist/{chunk-EUAVDA7W.js → chunk-X7ZY2Y2Z.js} +2 -2
  11. package/dist/cli.js +6 -6
  12. package/dist/cli.js.map +1 -1
  13. package/dist/commands/memory/server.js +252 -3
  14. package/dist/commands/memory/server.js.map +1 -1
  15. package/dist/{context-QU2QFVS3.js → context-HX5BOXYM.js} +158 -70
  16. package/dist/context-HX5BOXYM.js.map +1 -0
  17. package/dist/{extract-ADZYHMUP.js → extract-7D2EEXYD.js} +3 -3
  18. package/dist/{install-3IW2PDOS.js → install-ULZUZI7T.js} +2 -2
  19. package/dist/require-deps-6D6IBICL.js +0 -0
  20. package/dist/{stats-XLVVS3JA.js → stats-Y5ZFAZVF.js} +3 -3
  21. package/dist/{tui-BXRHLYAS.js → tui-DTIXPD2V.js} +2 -2
  22. package/package.json +21 -14
  23. package/dist/chunk-NNVJCKEP.js.map +0 -1
  24. package/dist/chunk-OYSKBXBB.js +0 -311
  25. package/dist/chunk-OYSKBXBB.js.map +0 -1
  26. package/dist/context-QU2QFVS3.js.map +0 -1
  27. /package/dist/{chunk-EUAVDA7W.js.map → chunk-X7ZY2Y2Z.js.map} +0 -0
  28. /package/dist/{extract-ADZYHMUP.js.map → extract-7D2EEXYD.js.map} +0 -0
  29. /package/dist/{install-3IW2PDOS.js.map → install-ULZUZI7T.js.map} +0 -0
  30. /package/dist/{stats-XLVVS3JA.js.map → stats-Y5ZFAZVF.js.map} +0 -0
  31. /package/dist/{tui-BXRHLYAS.js.map → tui-DTIXPD2V.js.map} +0 -0
@@ -1,17 +1,25 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- RetrievalService
4
- } from "./chunk-OYSKBXBB.js";
3
+ computeContextScore,
4
+ getGitContext
5
+ } from "./chunk-MQJA7TGY.js";
5
6
  import {
6
7
  detectProject
7
8
  } from "./chunk-NAW47BYA.js";
8
9
  import {
9
10
  initStorage
10
- } from "./chunk-EUAVDA7W.js";
11
+ } from "./chunk-X7ZY2Y2Z.js";
11
12
  import "./chunk-TALTTAMW.js";
12
13
  import {
13
- DEFAULT_DECAY_PARAMS
14
- } from "./chunk-NNVJCKEP.js";
14
+ DEFAULT_DECAY_PARAMS,
15
+ INJECTION_COLD_START_THRESHOLD,
16
+ INJECTION_HEADER_TOKENS,
17
+ INJECTION_MIN_SCORE,
18
+ INJECTION_WEIGHTS,
19
+ RECENCY_HALF_LIFE,
20
+ TYPE_INJECTION_BONUS,
21
+ estimateTokens
22
+ } from "./chunk-JPVLFY2R.js";
15
23
  import "./chunk-UN2XVQ5K.js";
16
24
  import "./chunk-FL3JGYDM.js";
17
25
 
@@ -199,8 +207,142 @@ function normalizeText(text) {
199
207
  return text.toLowerCase().replace(/\s+/g, " ").trim();
200
208
  }
201
209
 
210
+ // src/commands/memory/services/injection-service.ts
211
+ var InjectionService = class {
212
+ #deps;
213
+ constructor(deps) {
214
+ this.#deps = deps;
215
+ }
216
+ selectForInjection(tokenBudget, project) {
217
+ const allMemories = this.#deps.memoryRepo.getAll(project);
218
+ const totalCount = allMemories.length;
219
+ const candidates = allMemories.filter(
220
+ (m) => m.type !== "working" && m.importance >= 0.05
221
+ );
222
+ if (candidates.length === 0) {
223
+ return { memories: [], tokensUsed: 0, tokenBudget, totalCount };
224
+ }
225
+ const minScore = candidates.length <= INJECTION_COLD_START_THRESHOLD ? 0.1 : INJECTION_MIN_SCORE;
226
+ const scored = candidates.map((m) => ({ memory: m, score: this.#scoreMemory(m) })).filter((s) => s.score >= minScore).sort((a, b) => b.score - a.score);
227
+ return this.#packBudget(scored, tokenBudget, totalCount);
228
+ }
229
+ formatInjection(result) {
230
+ const { memories, tokensUsed, tokenBudget, totalCount } = result;
231
+ if (memories.length === 0) {
232
+ return "No memories stored for this project. Use memory_store to save knowledge across sessions.";
233
+ }
234
+ const lines = [];
235
+ lines.push(`# Agentic Memory (${memories.length} of ${totalCount} memories, ${tokensUsed}/${tokenBudget} tokens)`);
236
+ lines.push("Use memory_search to retrieve full content for any memory listed here.\n");
237
+ const full = memories.filter((m) => m.tier === "full");
238
+ const summary = memories.filter((m) => m.tier === "summary");
239
+ const index = memories.filter((m) => m.tier === "index");
240
+ if (full.length > 0) {
241
+ lines.push("## Key Memories");
242
+ for (const { memory: m } of full) {
243
+ lines.push(`### ${m.title ?? "(untitled)"} [${m.type}]`);
244
+ lines.push(m.content.slice(0, 500));
245
+ if (m.tags.length > 0) lines.push(`Tags: ${m.tags.join(", ")}`);
246
+ lines.push("");
247
+ }
248
+ }
249
+ if (summary.length > 0) {
250
+ lines.push("## Related Memories");
251
+ for (const { memory: m } of summary) {
252
+ const snippet = m.content.slice(0, 150);
253
+ const ellipsis = m.content.length > 150 ? "..." : "";
254
+ lines.push(`- **${m.title ?? "(untitled)"}** [${m.type}]: ${snippet}${ellipsis}`);
255
+ }
256
+ lines.push("");
257
+ }
258
+ if (index.length > 0) {
259
+ lines.push("## Also Available (use memory_search)");
260
+ for (const { memory: m } of index) {
261
+ lines.push(`- ${m.id.slice(0, 8)} ${m.title ?? "(untitled)"} [${m.type}]`);
262
+ }
263
+ }
264
+ return lines.join("\n");
265
+ }
266
+ // ── Scoring ────────────────────────────────────────────────
267
+ #scoreMemory(memory) {
268
+ const ctx = this.#contextRelevance(memory);
269
+ const val = this.#valueSignal(memory);
270
+ const imp = memory.importance;
271
+ const rec = this.#recencyScore(memory);
272
+ const typ = TYPE_INJECTION_BONUS[memory.type] ?? 0.5;
273
+ const noise = this.#noisePenalty(memory);
274
+ return ctx * INJECTION_WEIGHTS.context + val * INJECTION_WEIGHTS.value + imp * INJECTION_WEIGHTS.importance + rec * INJECTION_WEIGHTS.recency + typ * INJECTION_WEIGHTS.typeBonus + noise * INJECTION_WEIGHTS.noise;
275
+ }
276
+ #contextRelevance(memory) {
277
+ if (!this.#deps.gitContext) return 0;
278
+ return computeContextScore(memory.context, this.#deps.gitContext, "");
279
+ }
280
+ #valueSignal(memory) {
281
+ const { accessCount, injectionCount } = memory;
282
+ if (accessCount === 0 && injectionCount === 0) return 0.5;
283
+ if (injectionCount > 0 && accessCount === 0) {
284
+ return Math.max(0, 0.5 - Math.min(1, injectionCount / 10) * 0.5);
285
+ }
286
+ const ratio = Math.min(1, accessCount / Math.max(1, injectionCount));
287
+ return 0.4 + ratio * 0.6;
288
+ }
289
+ #recencyScore(memory) {
290
+ const halfLife = RECENCY_HALF_LIFE[memory.type] ?? 30;
291
+ const ageDays = (Date.now() - new Date(memory.updatedAt).getTime()) / 864e5;
292
+ return Math.exp(-ageDays * Math.LN2 / halfLife);
293
+ }
294
+ #noisePenalty(memory) {
295
+ if (memory.injectionCount <= 3) return 1;
296
+ if (memory.accessCount > 0) return 1;
297
+ return Math.max(0.2, 1 - Math.log2(memory.injectionCount - 2) * 0.15);
298
+ }
299
+ // ── Token Budget Packing ───────────────────────────────────
300
+ #packBudget(scored, tokenBudget, totalCount) {
301
+ const available = tokenBudget - INJECTION_HEADER_TOKENS;
302
+ const selected = [];
303
+ let tokensUsed = INJECTION_HEADER_TOKENS;
304
+ for (const { memory, score } of scored) {
305
+ if (tokensUsed >= tokenBudget) break;
306
+ const tier = this.#assignTier(score, selected.length, available - (tokensUsed - INJECTION_HEADER_TOKENS));
307
+ const cost = this.#estimateTierTokens(memory, tier);
308
+ if (tokensUsed + cost <= tokenBudget) {
309
+ selected.push({ memory, score, tier, tokenCost: cost });
310
+ tokensUsed += cost;
311
+ continue;
312
+ }
313
+ const demoted = tier === "full" ? "summary" : tier === "summary" ? "index" : null;
314
+ if (demoted) {
315
+ const demotedCost = this.#estimateTierTokens(memory, demoted);
316
+ if (tokensUsed + demotedCost <= tokenBudget) {
317
+ selected.push({ memory, score, tier: demoted, tokenCost: demotedCost });
318
+ tokensUsed += demotedCost;
319
+ }
320
+ }
321
+ }
322
+ for (const entry of selected) {
323
+ this.#deps.memoryRepo.incrementInjection(entry.memory.id);
324
+ }
325
+ return { memories: selected, tokensUsed, tokenBudget, totalCount };
326
+ }
327
+ #assignTier(score, position, remainingBudget) {
328
+ if (position < 3 && score >= 0.6 && remainingBudget > 200) return "full";
329
+ if (position < 8 && score >= 0.35 && remainingBudget > 80) return "summary";
330
+ return "index";
331
+ }
332
+ #estimateTierTokens(memory, tier) {
333
+ const meta = `[${memory.type}] ${memory.title ?? ""} (${memory.tags.join(", ")})`;
334
+ switch (tier) {
335
+ case "full":
336
+ return estimateTokens(memory.content.slice(0, 500)) + estimateTokens(meta) + 10;
337
+ case "summary":
338
+ return estimateTokens(memory.content.slice(0, 150)) + estimateTokens(meta) + 8;
339
+ case "index":
340
+ return estimateTokens(`${memory.id.slice(0, 8)} [${memory.type}] ${memory.title ?? "(untitled)"}`) + 4;
341
+ }
342
+ }
343
+ };
344
+
202
345
  // src/commands/memory/subcommands/context.ts
203
- var FULL_INJECT_THRESHOLD = 10;
204
346
  var CONSOLIDATION_FILE = ".last-consolidation";
205
347
  function shouldConsolidate(dataDir, intervalDays) {
206
348
  const checkpointPath = join(dataDir, CONSOLIDATION_FILE);
@@ -241,77 +383,23 @@ async function runContext(opts) {
241
383
  process.stderr.write(`[agentic-memory] maintenance error: ${err instanceof Error ? err.message : err}
242
384
  `);
243
385
  }
244
- const retrievalService = new RetrievalService({
386
+ const project = detectProject(process.cwd());
387
+ const gitContext = getGitContext();
388
+ const injectionService = new InjectionService({
245
389
  memoryRepo: ctx.memoryRepo,
246
390
  relationRepo: ctx.relationRepo,
247
- searchRepo: ctx.searchRepo
391
+ gitContext: gitContext ?? void 0
248
392
  });
249
- const project = detectProject(process.cwd());
250
- const totalCount = ctx.memoryRepo.count(project ?? void 0);
251
- const results = retrievalService.loadSessionContext({
252
- limit: opts.limit ?? FULL_INJECT_THRESHOLD,
253
- project: project ?? void 0,
254
- type: opts.type
255
- });
256
- if (results.length === 0) {
257
- write("No memories found for this project.");
258
- return;
259
- }
260
- const useGraph = totalCount > FULL_INJECT_THRESHOLD;
261
- if (opts.json) {
262
- write("# Agentic Memory - Session Context");
263
- if (useGraph) {
264
- write(`${totalCount} memories stored. Showing index only - use memory_search to get full content.
265
- `);
266
- const graph = results.map((r) => formatGraphEntry(r));
267
- write(JSON.stringify({ mode: "graph", totalMemories: totalCount, memories: graph }, null, 2));
268
- } else {
269
- write("The following memories were loaded from previous sessions. Treat these as known facts.");
270
- write("When the user asks about something covered here, answer from these memories directly.\n");
271
- const sections = {
272
- contextMatched: results.filter((r) => r.section === "context").map(formatFullEntry),
273
- recent: results.filter((r) => r.section === "recent").map(formatFullEntry),
274
- related: results.filter((r) => r.section === "related").map(formatFullEntry)
275
- };
276
- write(JSON.stringify({ mode: "full", ...sections }, null, 2));
277
- }
278
- } else {
279
- write(`agentic-memory - Session context (${results.length}/${totalCount} memories)
280
- `);
281
- for (const r of results) {
282
- const m = r.result.memory;
283
- write(` ${m.title ?? "(untitled)"} [${m.type}] - ${m.content.slice(0, 100)}${m.content.length > 100 ? "..." : ""}`);
284
- }
285
- }
393
+ const result = injectionService.selectForInjection(
394
+ ctx.config.injectionBudget,
395
+ project ?? void 0
396
+ );
397
+ write(injectionService.formatInjection(result));
286
398
  } finally {
287
399
  ctx.close();
288
400
  }
289
401
  }
290
- function formatFullEntry(entry) {
291
- const m = entry.result.memory;
292
- return {
293
- id: m.id,
294
- type: m.type,
295
- title: m.title,
296
- content: m.content.slice(0, 500),
297
- importance: m.importance,
298
- tags: m.tags,
299
- score: Math.round(entry.result.score * 100) / 100,
300
- createdAt: m.createdAt
301
- };
302
- }
303
- function formatGraphEntry(entry) {
304
- const m = entry.result.memory;
305
- return {
306
- id: m.id,
307
- type: m.type,
308
- title: m.title,
309
- importance: m.importance,
310
- tags: m.tags,
311
- section: entry.section
312
- };
313
- }
314
402
  export {
315
403
  runContext
316
404
  };
317
- //# sourceMappingURL=context-QU2QFVS3.js.map
405
+ //# sourceMappingURL=context-HX5BOXYM.js.map
@@ -0,0 +1 @@
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":[]}
@@ -4,9 +4,9 @@ import {
4
4
  } from "./chunk-NAW47BYA.js";
5
5
  import {
6
6
  initStorage
7
- } from "./chunk-EUAVDA7W.js";
7
+ } from "./chunk-X7ZY2Y2Z.js";
8
8
  import "./chunk-TALTTAMW.js";
9
- import "./chunk-NNVJCKEP.js";
9
+ import "./chunk-JPVLFY2R.js";
10
10
  import "./chunk-UN2XVQ5K.js";
11
11
  import "./chunk-FL3JGYDM.js";
12
12
 
@@ -215,4 +215,4 @@ function readStdin(timeoutMs) {
215
215
  export {
216
216
  runExtract
217
217
  };
218
- //# sourceMappingURL=extract-ADZYHMUP.js.map
218
+ //# sourceMappingURL=extract-7D2EEXYD.js.map
@@ -9,7 +9,7 @@ import {
9
9
  loadConfig,
10
10
  migrate,
11
11
  resolveDataDir
12
- } from "./chunk-NNVJCKEP.js";
12
+ } from "./chunk-JPVLFY2R.js";
13
13
  import "./chunk-UN2XVQ5K.js";
14
14
  import {
15
15
  log
@@ -250,4 +250,4 @@ function installSkills(projectDir) {
250
250
  export {
251
251
  runInstall
252
252
  };
253
- //# sourceMappingURL=install-3IW2PDOS.js.map
253
+ //# sourceMappingURL=install-ULZUZI7T.js.map
File without changes
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  initStorage
4
- } from "./chunk-EUAVDA7W.js";
4
+ } from "./chunk-X7ZY2Y2Z.js";
5
5
  import "./chunk-TALTTAMW.js";
6
- import "./chunk-NNVJCKEP.js";
6
+ import "./chunk-JPVLFY2R.js";
7
7
  import "./chunk-UN2XVQ5K.js";
8
8
  import {
9
9
  log
@@ -72,4 +72,4 @@ async function runStats(opts) {
72
72
  export {
73
73
  runStats
74
74
  };
75
- //# sourceMappingURL=stats-XLVVS3JA.js.map
75
+ //# sourceMappingURL=stats-Y5ZFAZVF.js.map
@@ -11,7 +11,7 @@ import {
11
11
  loadConfig,
12
12
  migrate,
13
13
  resolveDataDir
14
- } from "./chunk-NNVJCKEP.js";
14
+ } from "./chunk-JPVLFY2R.js";
15
15
  import "./chunk-UN2XVQ5K.js";
16
16
  import "./chunk-FL3JGYDM.js";
17
17
 
@@ -1098,4 +1098,4 @@ async function startTui(options) {
1098
1098
  export {
1099
1099
  startTui
1100
1100
  };
1101
- //# sourceMappingURL=tui-BXRHLYAS.js.map
1101
+ //# sourceMappingURL=tui-DTIXPD2V.js.map
package/package.json CHANGED
@@ -1,11 +1,25 @@
1
1
  {
2
2
  "name": "claude-launchpad",
3
- "version": "0.8.2",
3
+ "version": "0.8.4-dev.0",
4
4
  "description": "CLI toolkit that makes Claude Code setups measurably good - scaffold, diagnose, evaluate, remember",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "claude-launchpad": "./dist/cli.js"
8
8
  },
9
+ "scripts": {
10
+ "dev": "tsx watch src/cli.ts",
11
+ "build": "tsup",
12
+ "start": "tsx src/cli.ts",
13
+ "test": "vitest",
14
+ "test:run": "vitest run",
15
+ "lint": "eslint src/ --ext .ts",
16
+ "typecheck": "tsc --noEmit",
17
+ "prepublishOnly": "pnpm build",
18
+ "publish:dev": "npm version prerelease --preid=dev --no-git-tag-version && node scripts/sync-version.mjs && npm publish --tag dev",
19
+ "publish:release": "npm publish",
20
+ "docs:dev": "cd docs && pnpm dev",
21
+ "docs:build": "cd docs && pnpm build"
22
+ },
9
23
  "keywords": [
10
24
  "claude",
11
25
  "claude-code",
@@ -32,6 +46,7 @@
32
46
  "engines": {
33
47
  "node": ">=22"
34
48
  },
49
+ "packageManager": "pnpm@10.26.1",
35
50
  "dependencies": {
36
51
  "@inquirer/prompts": "^8.3.2",
37
52
  "chalk": "^5.6.2",
@@ -56,17 +71,9 @@
56
71
  "typescript": "^6.0.2",
57
72
  "vitest": "^4.1.2"
58
73
  },
59
- "scripts": {
60
- "dev": "tsx watch src/cli.ts",
61
- "build": "tsup",
62
- "start": "tsx src/cli.ts",
63
- "test": "vitest",
64
- "test:run": "vitest run",
65
- "lint": "eslint src/ --ext .ts",
66
- "typecheck": "tsc --noEmit",
67
- "publish:dev": "npm version prerelease --preid=dev --no-git-tag-version && node scripts/sync-version.mjs && npm publish --tag dev",
68
- "publish:release": "npm publish",
69
- "docs:dev": "cd docs && pnpm dev",
70
- "docs:build": "cd docs && pnpm build"
74
+ "pnpm": {
75
+ "onlyBuiltDependencies": [
76
+ "better-sqlite3"
77
+ ]
71
78
  }
72
- }
79
+ }
@@ -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// ── 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"]}