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.
Files changed (35) hide show
  1. package/README.md +12 -23
  2. package/dist/{chunk-JXFTVFPC.js → chunk-4D3EBDNB.js} +20 -2
  3. package/dist/{chunk-JXFTVFPC.js.map → chunk-4D3EBDNB.js.map} +1 -1
  4. package/dist/{chunk-UCU3PG3D.js → chunk-6IXA2NQN.js} +2 -2
  5. package/dist/{chunk-JTKRLIEV.js → chunk-JWT7EHTU.js} +18 -9
  6. package/dist/chunk-JWT7EHTU.js.map +1 -0
  7. package/dist/{chunk-LRJW32ZW.js → chunk-QMWQOL75.js} +3 -3
  8. package/dist/{chunk-J5NT4JGE.js → chunk-VDXWW5H5.js} +2 -2
  9. package/dist/chunk-VDXWW5H5.js.map +1 -0
  10. package/dist/cli.js +8 -8
  11. package/dist/cli.js.map +1 -1
  12. package/dist/commands/memory/server.js +58 -7
  13. package/dist/commands/memory/server.js.map +1 -1
  14. package/dist/{context-HB6EK2LE.js → context-U2JJISLS.js} +71 -34
  15. package/dist/context-U2JJISLS.js.map +1 -0
  16. package/dist/{extract-SRE5TBS2.js → extract-HMAN7RW4.js} +4 -4
  17. package/dist/{install-PSSMUGLO.js → install-C5XDWATE.js} +2 -2
  18. package/dist/{pull-OGPDUNZ2.js → pull-7ZF3OBPZ.js} +6 -6
  19. package/dist/{push-EXJEKBU4.js → push-SYSRB6OP.js} +6 -6
  20. package/dist/{stats-W3BHM3WF.js → stats-AYVXQIJJ.js} +4 -4
  21. package/dist/tui-YMBDAVTI.js +1008 -0
  22. package/dist/tui-YMBDAVTI.js.map +1 -0
  23. package/package.json +7 -3
  24. package/dist/chunk-J5NT4JGE.js.map +0 -1
  25. package/dist/chunk-JTKRLIEV.js.map +0 -1
  26. package/dist/context-HB6EK2LE.js.map +0 -1
  27. package/dist/tui-R6XSBUKS.js +0 -1101
  28. package/dist/tui-R6XSBUKS.js.map +0 -1
  29. /package/dist/{chunk-UCU3PG3D.js.map → chunk-6IXA2NQN.js.map} +0 -0
  30. /package/dist/{chunk-LRJW32ZW.js.map → chunk-QMWQOL75.js.map} +0 -0
  31. /package/dist/{extract-SRE5TBS2.js.map → extract-HMAN7RW4.js.map} +0 -0
  32. /package/dist/{install-PSSMUGLO.js.map → install-C5XDWATE.js.map} +0 -0
  33. /package/dist/{pull-OGPDUNZ2.js.map → pull-7ZF3OBPZ.js.map} +0 -0
  34. /package/dist/{push-EXJEKBU4.js.map → push-SYSRB6OP.js.map} +0 -0
  35. /package/dist/{stats-W3BHM3WF.js.map → stats-AYVXQIJJ.js.map} +0 -0
@@ -8,18 +8,21 @@ import {
8
8
  } from "./chunk-NAW47BYA.js";
9
9
  import {
10
10
  initStorage
11
- } from "./chunk-LRJW32ZW.js";
12
- import "./chunk-JXFTVFPC.js";
11
+ } from "./chunk-QMWQOL75.js";
12
+ import "./chunk-4D3EBDNB.js";
13
13
  import {
14
14
  DEFAULT_DECAY_PARAMS,
15
+ INJECTION_COLD_START_RAMP_END,
15
16
  INJECTION_COLD_START_THRESHOLD,
16
17
  INJECTION_HEADER_TOKENS,
18
+ INJECTION_MAX_SAME_TYPE_FULL,
17
19
  INJECTION_MIN_SCORE,
20
+ INJECTION_PINNED_BUDGET_PCT,
18
21
  INJECTION_WEIGHTS,
19
22
  RECENCY_HALF_LIFE,
20
23
  TYPE_INJECTION_BONUS,
21
24
  estimateTokens
22
- } from "./chunk-JTKRLIEV.js";
25
+ } from "./chunk-JWT7EHTU.js";
23
26
  import "./chunk-Z6FBT44W.js";
24
27
  import "./chunk-RJGXPH7P.js";
25
28
 
@@ -93,14 +96,15 @@ var DecayService = class {
93
96
  if (ageDays < 0) return memory.importance;
94
97
  if (ageDays <= 7) {
95
98
  if (memory.type === "episodic") {
96
- const ebbinghaus = Math.exp(-ageDays * 0.4);
97
- return Math.max(this.#params.importanceFloor, memory.importance * ebbinghaus);
99
+ const ebbinghaus = Math.exp(-ageDays * 0.7) + 0.2;
100
+ return Math.max(this.#params.importanceFloor, memory.importance * Math.min(1, ebbinghaus));
98
101
  }
99
102
  return memory.importance;
100
103
  }
101
104
  const accessModifier = this.getAccessModifier(memory.accessCount);
102
105
  const relationCount = this.#relationRepo.countByMemory(memory.id);
103
- const relationModifier = relationCount >= this.#params.relationModifier.connectedThreshold ? this.#params.relationModifier.connectedMultiplier : this.#params.relationModifier.isolatedMultiplier;
106
+ const rm = this.#params.relationModifier;
107
+ const relationModifier = relationCount >= rm.highlyConnectedThreshold ? rm.highlyConnectedMultiplier : relationCount >= rm.connectedThreshold ? rm.connectedMultiplier : rm.isolatedMultiplier;
104
108
  let effectiveTau = tau * accessModifier * relationModifier;
105
109
  if (memory.injectionCount > 5 && memory.accessCount === 0) {
106
110
  effectiveTau /= 1.5;
@@ -110,10 +114,7 @@ var DecayService = class {
110
114
  return Math.max(this.#params.importanceFloor, newImportance);
111
115
  }
112
116
  getAccessModifier(accessCount) {
113
- for (const tier of this.#params.accessModifiers) {
114
- if (accessCount <= tier.maxCount) return tier.multiplier;
115
- }
116
- return 1;
117
+ return 1 + Math.log2(1 + accessCount);
117
118
  }
118
119
  };
119
120
 
@@ -217,12 +218,12 @@ var InjectionService = class {
217
218
  const allMemories = this.#deps.memoryRepo.getAll(project);
218
219
  const totalCount = allMemories.length;
219
220
  const candidates = allMemories.filter(
220
- (m) => m.type !== "working" && m.importance >= 0.05
221
+ (m) => m.type !== "working" && m.importance >= DEFAULT_DECAY_PARAMS.importanceFloor
221
222
  );
222
223
  if (candidates.length === 0) {
223
224
  return { memories: [], tokensUsed: 0, tokenBudget, totalCount };
224
225
  }
225
- const minScore = candidates.length <= INJECTION_COLD_START_THRESHOLD ? 0.1 : INJECTION_MIN_SCORE;
226
+ const minScore = candidates.length <= INJECTION_COLD_START_THRESHOLD ? 0.1 : candidates.length <= INJECTION_COLD_START_RAMP_END ? 0.1 + (INJECTION_MIN_SCORE - 0.1) * (candidates.length - INJECTION_COLD_START_THRESHOLD) / (INJECTION_COLD_START_RAMP_END - INJECTION_COLD_START_THRESHOLD) : INJECTION_MIN_SCORE;
226
227
  const scored = candidates.map((m) => ({ memory: m, score: this.#scoreMemory(m) })).filter((s) => s.score >= minScore).sort((a, b) => b.score - a.score);
227
228
  return this.#packBudget(scored, tokenBudget, totalCount);
228
229
  }
@@ -249,8 +250,8 @@ var InjectionService = class {
249
250
  if (summary.length > 0) {
250
251
  lines.push("## Related Memories");
251
252
  for (const { memory: m } of summary) {
252
- const snippet = m.content.slice(0, 150);
253
- const ellipsis = m.content.length > 150 ? "..." : "";
253
+ const snippet = m.content.slice(0, 350);
254
+ const ellipsis = m.content.length > 350 ? "..." : "";
254
255
  lines.push(`- **${m.title ?? "(untitled)"}** [${m.type}]: ${snippet}${ellipsis}`);
255
256
  }
256
257
  lines.push("");
@@ -265,18 +266,34 @@ var InjectionService = class {
265
266
  }
266
267
  // ── Scoring ────────────────────────────────────────────────
267
268
  #scoreMemory(memory) {
268
- const ctx = this.#contextRelevance(memory);
269
+ const hasGit = !!this.#deps.gitContext;
270
+ const ctx = hasGit ? this.#contextRelevance(memory) : 0;
269
271
  const val = this.#valueSignal(memory);
270
272
  const imp = memory.importance;
271
273
  const rec = this.#recencyScore(memory);
272
274
  const typ = TYPE_INJECTION_BONUS[memory.type] ?? 0.5;
273
275
  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;
276
+ const branch = this.#branchHeuristic(memory);
277
+ if (!hasGit) {
278
+ return val * (INJECTION_WEIGHTS.value + INJECTION_WEIGHTS.context * 0.4) + imp * (INJECTION_WEIGHTS.importance + INJECTION_WEIGHTS.context * 0.3) + rec * (INJECTION_WEIGHTS.recency + INJECTION_WEIGHTS.context * 0.3) + typ * INJECTION_WEIGHTS.typeBonus + noise * INJECTION_WEIGHTS.noise;
279
+ }
280
+ 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 + branch * 0.05;
275
281
  }
276
282
  #contextRelevance(memory) {
277
283
  if (!this.#deps.gitContext) return 0;
278
284
  return computeContextScore(memory.context, this.#deps.gitContext, "");
279
285
  }
286
+ #branchHeuristic(memory) {
287
+ if (!this.#deps.gitContext?.branch) return 0;
288
+ const branch = this.#deps.gitContext.branch.toLowerCase();
289
+ if (branch.startsWith("fix/") || branch.startsWith("bugfix/")) {
290
+ return memory.type === "pattern" ? 1 : memory.type === "episodic" ? 0.5 : 0;
291
+ }
292
+ if (branch.startsWith("feat/") || branch.startsWith("feature/")) {
293
+ return memory.type === "procedural" ? 1 : memory.type === "semantic" ? 0.5 : 0;
294
+ }
295
+ return 0;
296
+ }
280
297
  #valueSignal(memory) {
281
298
  const { accessCount, injectionCount } = memory;
282
299
  if (accessCount === 0 && injectionCount === 0) return 0.5;
@@ -298,32 +315,52 @@ var InjectionService = class {
298
315
  }
299
316
  // ── Token Budget Packing ───────────────────────────────────
300
317
  #packBudget(scored, tokenBudget, totalCount) {
301
- const available = tokenBudget - INJECTION_HEADER_TOKENS;
302
318
  const selected = [];
303
319
  let tokensUsed = INJECTION_HEADER_TOKENS;
320
+ const fullTypeCount = /* @__PURE__ */ new Map();
321
+ const pinnedBudget = INJECTION_HEADER_TOKENS + Math.floor(tokenBudget * INJECTION_PINNED_BUDGET_PCT);
322
+ for (const { memory, score } of scored) {
323
+ if (memory.importance < 0.8 || tokensUsed >= pinnedBudget) continue;
324
+ const cost = this.#estimateTierTokens(memory, "full");
325
+ if (tokensUsed + cost > pinnedBudget) continue;
326
+ selected.push({ memory, score, tier: "full", tokenCost: cost });
327
+ tokensUsed += cost;
328
+ this.#bumpTypeCount(fullTypeCount, memory.type);
329
+ }
304
330
  for (const { memory, score } of scored) {
305
331
  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
- }
332
+ if (selected.some((s) => s.memory.id === memory.id)) continue;
333
+ tokensUsed = this.#tryPack(memory, score, tokenBudget, tokensUsed, selected, fullTypeCount);
321
334
  }
322
335
  for (const entry of selected) {
323
336
  this.#deps.memoryRepo.incrementInjection(entry.memory.id);
324
337
  }
325
338
  return { memories: selected, tokensUsed, tokenBudget, totalCount };
326
339
  }
340
+ #tryPack(memory, score, tokenBudget, tokensUsed, selected, fullTypeCount) {
341
+ const remaining = tokenBudget - tokensUsed;
342
+ let tier = this.#assignTier(score, selected.length, remaining);
343
+ if (tier === "full" && (fullTypeCount.get(memory.type) ?? 0) >= INJECTION_MAX_SAME_TYPE_FULL) {
344
+ tier = "summary";
345
+ }
346
+ const cost = this.#estimateTierTokens(memory, tier);
347
+ if (tokensUsed + cost <= tokenBudget) {
348
+ selected.push({ memory, score, tier, tokenCost: cost });
349
+ if (tier === "full") this.#bumpTypeCount(fullTypeCount, memory.type);
350
+ return tokensUsed + cost;
351
+ }
352
+ const demoted = tier === "full" ? "summary" : tier === "summary" ? "index" : null;
353
+ if (!demoted) return tokensUsed;
354
+ const demotedCost = this.#estimateTierTokens(memory, demoted);
355
+ if (tokensUsed + demotedCost <= tokenBudget) {
356
+ selected.push({ memory, score, tier: demoted, tokenCost: demotedCost });
357
+ return tokensUsed + demotedCost;
358
+ }
359
+ return tokensUsed;
360
+ }
361
+ #bumpTypeCount(counts, type) {
362
+ counts.set(type, (counts.get(type) ?? 0) + 1);
363
+ }
327
364
  #assignTier(score, position, remainingBudget) {
328
365
  if (position < 3 && score >= 0.6 && remainingBudget > 200) return "full";
329
366
  if (position < 8 && score >= 0.35 && remainingBudget > 80) return "summary";
@@ -335,7 +372,7 @@ var InjectionService = class {
335
372
  case "full":
336
373
  return estimateTokens(memory.content.slice(0, 500)) + estimateTokens(meta) + 10;
337
374
  case "summary":
338
- return estimateTokens(memory.content.slice(0, 150)) + estimateTokens(meta) + 8;
375
+ return estimateTokens(memory.content.slice(0, 350)) + estimateTokens(meta) + 8;
339
376
  case "index":
340
377
  return estimateTokens(`${memory.id.slice(0, 8)} [${memory.type}] ${memory.title ?? "(untitled)"}`) + 4;
341
378
  }
@@ -402,4 +439,4 @@ async function runContext(opts) {
402
439
  export {
403
440
  runContext
404
441
  };
405
- //# sourceMappingURL=context-HB6EK2LE.js.map
442
+ //# sourceMappingURL=context-U2JJISLS.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 // Ebbinghaus curve: steep initial drop with residual floor\n const ebbinghaus = Math.exp(-ageDays * 0.7) + 0.2;\n return Math.max(this.#params.importanceFloor, memory.importance * Math.min(1, ebbinghaus));\n }\n return memory.importance;\n }\n\n // Access modifier: logarithmic curve (spacing effect)\n const accessModifier = this.getAccessModifier(memory.accessCount);\n\n // Relation modifier: connected memories decay slower, highly connected near-immune\n const relationCount = this.#relationRepo.countByMemory(memory.id);\n const rm = this.#params.relationModifier;\n const relationModifier = relationCount >= rm.highlyConnectedThreshold\n ? rm.highlyConnectedMultiplier\n : relationCount >= rm.connectedThreshold\n ? rm.connectedMultiplier\n : rm.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 // Logarithmic curve: 1 + log2(1 + count). Smoother than step function.\n // At 0: 1.0, at 3: 2.0, at 10: 3.5, at 30: 5.0\n return 1 + Math.log2(1 + accessCount);\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 DEFAULT_DECAY_PARAMS,\n INJECTION_WEIGHTS as W,\n TYPE_INJECTION_BONUS,\n RECENCY_HALF_LIFE,\n INJECTION_MIN_SCORE,\n INJECTION_COLD_START_THRESHOLD,\n INJECTION_COLD_START_RAMP_END,\n INJECTION_HEADER_TOKENS,\n INJECTION_MAX_SAME_TYPE_FULL,\n INJECTION_PINNED_BUDGET_PCT,\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 >= DEFAULT_DECAY_PARAMS.importanceFloor,\n );\n\n if (candidates.length === 0) {\n return { memories: [], tokensUsed: 0, tokenBudget, totalCount };\n }\n\n // Cold start: smooth ramp from 0.10 to INJECTION_MIN_SCORE\n const minScore = candidates.length <= INJECTION_COLD_START_THRESHOLD\n ? 0.10\n : candidates.length <= INJECTION_COLD_START_RAMP_END\n ? 0.10 + (INJECTION_MIN_SCORE - 0.10) * (candidates.length - INJECTION_COLD_START_THRESHOLD) / (INJECTION_COLD_START_RAMP_END - INJECTION_COLD_START_THRESHOLD)\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, 350);\n const ellipsis = m.content.length > 350 ? \"...\" : \"\";\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 hasGit = !!this.#deps.gitContext;\n const ctx = hasGit ? this.#contextRelevance(memory) : 0;\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 const branch = this.#branchHeuristic(memory);\n\n // Redistribute context weight when git is unavailable\n if (!hasGit) {\n return (\n val * (W.value + W.context * 0.4) +\n imp * (W.importance + W.context * 0.3) +\n rec * (W.recency + W.context * 0.3) +\n typ * W.typeBonus +\n noise * W.noise\n );\n }\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 branch * 0.05\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 #branchHeuristic(memory: Memory): number {\n if (!this.#deps.gitContext?.branch) return 0;\n const branch = this.#deps.gitContext.branch.toLowerCase();\n if (branch.startsWith('fix/') || branch.startsWith('bugfix/')) {\n return memory.type === 'pattern' ? 1.0 : memory.type === 'episodic' ? 0.5 : 0;\n }\n if (branch.startsWith('feat/') || branch.startsWith('feature/')) {\n return memory.type === 'procedural' ? 1.0 : memory.type === 'semantic' ? 0.5 : 0;\n }\n return 0;\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 selected: ScoredMemory[] = [];\n let tokensUsed = INJECTION_HEADER_TOKENS;\n const fullTypeCount = new Map<string, number>();\n\n // Phase 1: pinned memories get guaranteed slots\n const pinnedBudget = INJECTION_HEADER_TOKENS + Math.floor(tokenBudget * INJECTION_PINNED_BUDGET_PCT);\n for (const { memory, score } of scored) {\n if (memory.importance < 0.8 || tokensUsed >= pinnedBudget) continue;\n const cost = this.#estimateTierTokens(memory, \"full\");\n if (tokensUsed + cost > pinnedBudget) continue;\n selected.push({ memory, score, tier: \"full\", tokenCost: cost });\n tokensUsed += cost;\n this.#bumpTypeCount(fullTypeCount, memory.type);\n }\n\n // Phase 2: remaining memories packed by score\n for (const { memory, score } of scored) {\n if (tokensUsed >= tokenBudget) break;\n if (selected.some((s) => s.memory.id === memory.id)) continue;\n tokensUsed = this.#tryPack(memory, score, tokenBudget, tokensUsed, selected, fullTypeCount);\n }\n\n for (const entry of selected) {\n this.#deps.memoryRepo.incrementInjection(entry.memory.id);\n }\n return { memories: selected, tokensUsed, tokenBudget, totalCount };\n }\n\n #tryPack(\n memory: Memory, score: number, tokenBudget: number, tokensUsed: number,\n selected: ScoredMemory[], fullTypeCount: Map<string, number>,\n ): number {\n const remaining = tokenBudget - tokensUsed;\n let tier = this.#assignTier(score, selected.length, remaining);\n\n if (tier === 'full' && (fullTypeCount.get(memory.type) ?? 0) >= INJECTION_MAX_SAME_TYPE_FULL) {\n tier = 'summary';\n }\n\n const cost = this.#estimateTierTokens(memory, tier);\n if (tokensUsed + cost <= tokenBudget) {\n selected.push({ memory, score, tier, tokenCost: cost });\n if (tier === 'full') this.#bumpTypeCount(fullTypeCount, memory.type);\n return tokensUsed + cost;\n }\n\n const demoted = tier === \"full\" ? \"summary\" as const : tier === \"summary\" ? \"index\" as const : null;\n if (!demoted) return tokensUsed;\n const demotedCost = this.#estimateTierTokens(memory, demoted);\n if (tokensUsed + demotedCost <= tokenBudget) {\n selected.push({ memory, score, tier: demoted, tokenCost: demotedCost });\n return tokensUsed + demotedCost;\n }\n return tokensUsed;\n }\n\n #bumpTypeCount(counts: Map<string, number>, type: string): void {\n counts.set(type, (counts.get(type) ?? 0) + 1);\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, 350)) + 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-LRJW32ZW.js";
8
- import "./chunk-JXFTVFPC.js";
9
- import "./chunk-JTKRLIEV.js";
7
+ } from "./chunk-QMWQOL75.js";
8
+ import "./chunk-4D3EBDNB.js";
9
+ import "./chunk-JWT7EHTU.js";
10
10
  import "./chunk-Z6FBT44W.js";
11
11
  import "./chunk-RJGXPH7P.js";
12
12
 
@@ -215,4 +215,4 @@ function readStdin(timeoutMs) {
215
215
  export {
216
216
  runExtract
217
217
  };
218
- //# sourceMappingURL=extract-SRE5TBS2.js.map
218
+ //# sourceMappingURL=extract-HMAN7RW4.js.map
@@ -9,7 +9,7 @@ import {
9
9
  loadConfig,
10
10
  migrate,
11
11
  resolveDataDir
12
- } from "./chunk-JTKRLIEV.js";
12
+ } from "./chunk-JWT7EHTU.js";
13
13
  import "./chunk-Z6FBT44W.js";
14
14
  import {
15
15
  log
@@ -255,4 +255,4 @@ function installSkills(projectDir) {
255
255
  export {
256
256
  runInstall
257
257
  };
258
- //# sourceMappingURL=install-PSSMUGLO.js.map
258
+ //# sourceMappingURL=install-C5XDWATE.js.map
@@ -8,16 +8,16 @@ import {
8
8
  parsePayload,
9
9
  projectToFilename,
10
10
  readGistFile
11
- } from "./chunk-UCU3PG3D.js";
12
- import "./chunk-J5NT4JGE.js";
11
+ } from "./chunk-6IXA2NQN.js";
12
+ import "./chunk-VDXWW5H5.js";
13
13
  import {
14
14
  detectProject
15
15
  } from "./chunk-NAW47BYA.js";
16
16
  import {
17
17
  initStorage
18
- } from "./chunk-LRJW32ZW.js";
19
- import "./chunk-JXFTVFPC.js";
20
- import "./chunk-JTKRLIEV.js";
18
+ } from "./chunk-QMWQOL75.js";
19
+ import "./chunk-4D3EBDNB.js";
20
+ import "./chunk-JWT7EHTU.js";
21
21
  import "./chunk-Z6FBT44W.js";
22
22
  import {
23
23
  log
@@ -106,4 +106,4 @@ function printResult(result, project) {
106
106
  export {
107
107
  runPull
108
108
  };
109
- //# sourceMappingURL=pull-OGPDUNZ2.js.map
109
+ //# sourceMappingURL=pull-7ZF3OBPZ.js.map
@@ -9,16 +9,16 @@ import {
9
9
  projectToFilename,
10
10
  readGistFile,
11
11
  updateGistFiles
12
- } from "./chunk-UCU3PG3D.js";
13
- import "./chunk-J5NT4JGE.js";
12
+ } from "./chunk-6IXA2NQN.js";
13
+ import "./chunk-VDXWW5H5.js";
14
14
  import {
15
15
  detectProject
16
16
  } from "./chunk-NAW47BYA.js";
17
17
  import {
18
18
  initStorage
19
- } from "./chunk-LRJW32ZW.js";
20
- import "./chunk-JXFTVFPC.js";
21
- import "./chunk-JTKRLIEV.js";
19
+ } from "./chunk-QMWQOL75.js";
20
+ import "./chunk-4D3EBDNB.js";
21
+ import "./chunk-JWT7EHTU.js";
22
22
  import "./chunk-Z6FBT44W.js";
23
23
  import {
24
24
  log
@@ -138,4 +138,4 @@ async function confirmCreate() {
138
138
  export {
139
139
  runPush
140
140
  };
141
- //# sourceMappingURL=push-EXJEKBU4.js.map
141
+ //# sourceMappingURL=push-SYSRB6OP.js.map
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  initStorage
4
- } from "./chunk-LRJW32ZW.js";
5
- import "./chunk-JXFTVFPC.js";
6
- import "./chunk-JTKRLIEV.js";
4
+ } from "./chunk-QMWQOL75.js";
5
+ import "./chunk-4D3EBDNB.js";
6
+ import "./chunk-JWT7EHTU.js";
7
7
  import "./chunk-Z6FBT44W.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-W3BHM3WF.js.map
75
+ //# sourceMappingURL=stats-AYVXQIJJ.js.map