@hyperlynq/synaptic 0.7.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 (98) hide show
  1. package/LICENSE +19 -0
  2. package/README.md +427 -0
  3. package/build/scripts/rebuild-index.d.ts +5 -0
  4. package/build/scripts/rebuild-index.js +33 -0
  5. package/build/src/cli/init.d.ts +13 -0
  6. package/build/src/cli/init.js +222 -0
  7. package/build/src/cli/init.js.map +1 -0
  8. package/build/src/cli/pre-commit.d.ts +6 -0
  9. package/build/src/cli/pre-commit.js +159 -0
  10. package/build/src/cli/pre-commit.js.map +1 -0
  11. package/build/src/cli.d.ts +2 -0
  12. package/build/src/cli.js +36 -0
  13. package/build/src/cli.js.map +1 -0
  14. package/build/src/hooks/pre-compact.d.ts +6 -0
  15. package/build/src/hooks/pre-compact.js +64 -0
  16. package/build/src/hooks/pre-compact.js.map +1 -0
  17. package/build/src/hooks/session-start.d.ts +13 -0
  18. package/build/src/hooks/session-start.js +277 -0
  19. package/build/src/hooks/session-start.js.map +1 -0
  20. package/build/src/hooks/stop.d.ts +7 -0
  21. package/build/src/hooks/stop.js +248 -0
  22. package/build/src/hooks/stop.js.map +1 -0
  23. package/build/src/index.d.ts +1 -0
  24. package/build/src/index.js +8 -0
  25. package/build/src/index.js.map +1 -0
  26. package/build/src/server.d.ts +6 -0
  27. package/build/src/server.js +133 -0
  28. package/build/src/server.js.map +1 -0
  29. package/build/src/storage/embedder.d.ts +27 -0
  30. package/build/src/storage/embedder.js +126 -0
  31. package/build/src/storage/embedder.js.map +1 -0
  32. package/build/src/storage/git.d.ts +20 -0
  33. package/build/src/storage/git.js +98 -0
  34. package/build/src/storage/git.js.map +1 -0
  35. package/build/src/storage/maintenance.d.ts +9 -0
  36. package/build/src/storage/maintenance.js +46 -0
  37. package/build/src/storage/maintenance.js.map +1 -0
  38. package/build/src/storage/markdown.d.ts +21 -0
  39. package/build/src/storage/markdown.js +79 -0
  40. package/build/src/storage/markdown.js.map +1 -0
  41. package/build/src/storage/paths.d.ts +6 -0
  42. package/build/src/storage/paths.js +17 -0
  43. package/build/src/storage/paths.js.map +1 -0
  44. package/build/src/storage/project.d.ts +2 -0
  45. package/build/src/storage/project.js +35 -0
  46. package/build/src/storage/project.js.map +1 -0
  47. package/build/src/storage/session.d.ts +1 -0
  48. package/build/src/storage/session.js +17 -0
  49. package/build/src/storage/session.js.map +1 -0
  50. package/build/src/storage/sqlite.d.ts +102 -0
  51. package/build/src/storage/sqlite.js +830 -0
  52. package/build/src/storage/sqlite.js.map +1 -0
  53. package/build/src/storage/watcher.d.ts +22 -0
  54. package/build/src/storage/watcher.js +126 -0
  55. package/build/src/storage/watcher.js.map +1 -0
  56. package/build/src/tools/context-archive.d.ts +11 -0
  57. package/build/src/tools/context-archive.js +13 -0
  58. package/build/src/tools/context-archive.js.map +1 -0
  59. package/build/src/tools/context-chain.d.ts +12 -0
  60. package/build/src/tools/context-chain.js +26 -0
  61. package/build/src/tools/context-chain.js.map +1 -0
  62. package/build/src/tools/context-cochanges.d.ts +20 -0
  63. package/build/src/tools/context-cochanges.js +25 -0
  64. package/build/src/tools/context-cochanges.js.map +1 -0
  65. package/build/src/tools/context-delete-rule.d.ts +11 -0
  66. package/build/src/tools/context-delete-rule.js +12 -0
  67. package/build/src/tools/context-delete-rule.js.map +1 -0
  68. package/build/src/tools/context-dna.d.ts +18 -0
  69. package/build/src/tools/context-dna.js +197 -0
  70. package/build/src/tools/context-dna.js.map +1 -0
  71. package/build/src/tools/context-git-index.d.ts +17 -0
  72. package/build/src/tools/context-git-index.js +59 -0
  73. package/build/src/tools/context-git-index.js.map +1 -0
  74. package/build/src/tools/context-list-rules.d.ts +8 -0
  75. package/build/src/tools/context-list-rules.js +11 -0
  76. package/build/src/tools/context-list-rules.js.map +1 -0
  77. package/build/src/tools/context-list.d.ts +26 -0
  78. package/build/src/tools/context-list.js +42 -0
  79. package/build/src/tools/context-list.js.map +1 -0
  80. package/build/src/tools/context-resolve-pattern.d.ts +11 -0
  81. package/build/src/tools/context-resolve-pattern.js +9 -0
  82. package/build/src/tools/context-resolve-pattern.js.map +1 -0
  83. package/build/src/tools/context-save-rule.d.ts +14 -0
  84. package/build/src/tools/context-save-rule.js +15 -0
  85. package/build/src/tools/context-save-rule.js.map +1 -0
  86. package/build/src/tools/context-save.d.ts +26 -0
  87. package/build/src/tools/context-save.js +68 -0
  88. package/build/src/tools/context-save.js.map +1 -0
  89. package/build/src/tools/context-search.d.ts +31 -0
  90. package/build/src/tools/context-search.js +99 -0
  91. package/build/src/tools/context-search.js.map +1 -0
  92. package/build/src/tools/context-session.d.ts +13 -0
  93. package/build/src/tools/context-session.js +29 -0
  94. package/build/src/tools/context-session.js.map +1 -0
  95. package/build/src/tools/context-status.d.ts +13 -0
  96. package/build/src/tools/context-status.js +15 -0
  97. package/build/src/tools/context-status.js.map +1 -0
  98. package/package.json +57 -0
@@ -0,0 +1,133 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { ContextIndex } from "./storage/sqlite.js";
3
+ import { Embedder } from "./storage/embedder.js";
4
+ import { ensureDirs } from "./storage/paths.js";
5
+ import { detectProject } from "./storage/project.js";
6
+ import { contextSave, contextSaveSchema } from "./tools/context-save.js";
7
+ import { contextSearch, contextSearchSchema } from "./tools/context-search.js";
8
+ import { contextList, contextListSchema } from "./tools/context-list.js";
9
+ import { contextStatus } from "./tools/context-status.js";
10
+ import { contextArchive, contextArchiveSchema } from "./tools/context-archive.js";
11
+ import { contextGitIndex, contextGitIndexSchema } from "./tools/context-git-index.js";
12
+ import { contextResolvePattern, contextResolvePatternSchema } from "./tools/context-resolve-pattern.js";
13
+ import { contextSaveRule, contextSaveRuleSchema } from "./tools/context-save-rule.js";
14
+ import { contextDeleteRule, contextDeleteRuleSchema } from "./tools/context-delete-rule.js";
15
+ import { contextListRules } from "./tools/context-list-rules.js";
16
+ import { contextSession, contextSessionSchema } from "./tools/context-session.js";
17
+ import { contextCochanges, contextCochangesSchema } from "./tools/context-cochanges.js";
18
+ import { contextDna, contextDnaSchema } from "./tools/context-dna.js";
19
+ import { contextChain, contextChainSchema } from "./tools/context-chain.js";
20
+ import { GitWatcher } from "./storage/watcher.js";
21
+ let _embedder;
22
+ let _currentProject = null;
23
+ export function getEmbedder() {
24
+ return _embedder;
25
+ }
26
+ export function getCurrentProject() {
27
+ return _currentProject;
28
+ }
29
+ export { getSessionId } from "./storage/session.js";
30
+ export function createServer() {
31
+ ensureDirs();
32
+ _currentProject = detectProject();
33
+ const index = new ContextIndex();
34
+ _embedder = new Embedder();
35
+ const embedder = _embedder;
36
+ // Start git event watcher (silent no-op if not a git repo)
37
+ const watcher = new GitWatcher({
38
+ index,
39
+ embedder,
40
+ getCurrentProject: () => _currentProject,
41
+ });
42
+ watcher.start();
43
+ const server = new McpServer({
44
+ name: "synaptic",
45
+ version: "0.6.0",
46
+ });
47
+ server.tool("context_save", "Save a context entry (decision, progress, issue, etc.) to persistent local storage", contextSaveSchema, async (args) => {
48
+ const result = await contextSave(args, index, embedder);
49
+ return {
50
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
51
+ };
52
+ });
53
+ server.tool("context_search", "Search saved context entries using hybrid semantic + keyword search", contextSearchSchema, async (args) => {
54
+ const result = await contextSearch(args, index, embedder);
55
+ return {
56
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
57
+ };
58
+ });
59
+ server.tool("context_list", "List context entries by date range, optionally filtered by type", contextListSchema, async (args) => {
60
+ const result = contextList(args, index);
61
+ return {
62
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
63
+ };
64
+ });
65
+ server.tool("context_status", "Show storage stats: total entries, date range, database size, tier distribution, active patterns", {}, async () => {
66
+ const result = contextStatus(index);
67
+ return {
68
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
69
+ };
70
+ });
71
+ server.tool("context_archive", "Bulk-archive entries by ID list. Archived entries are excluded from search/list by default.", contextArchiveSchema, async (args) => {
72
+ const result = contextArchive(args, index);
73
+ return {
74
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
75
+ };
76
+ });
77
+ server.tool("context_git_index", "Index git commits as searchable context entries. Deduplicates by SHA.", contextGitIndexSchema, async (args) => {
78
+ const result = await contextGitIndex(args, index, embedder);
79
+ return {
80
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
81
+ };
82
+ });
83
+ server.tool("context_resolve_pattern", "Mark a recurring issue pattern as resolved. Stops surfacing in search and session-start.", contextResolvePatternSchema, async (args) => {
84
+ const result = contextResolvePattern(args, index);
85
+ return {
86
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
87
+ };
88
+ });
89
+ server.tool("context_save_rule", "Save or update a persistent rule by label. Rules are injected every session and always enforced. If a rule with this label exists, it is overwritten.", contextSaveRuleSchema, async (args) => {
90
+ const result = contextSaveRule(args, index);
91
+ return {
92
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
93
+ };
94
+ });
95
+ server.tool("context_delete_rule", "Delete a persistent rule by its label.", contextDeleteRuleSchema, async (args) => {
96
+ const result = contextDeleteRule(args, index);
97
+ return {
98
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
99
+ };
100
+ });
101
+ server.tool("context_list_rules", "List all active rules with their labels and content.", {}, async () => {
102
+ const result = contextListRules(index);
103
+ return {
104
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
105
+ };
106
+ });
107
+ server.tool("context_session", "List all entries from the current or specified session. Use for agent context sharing.", contextSessionSchema, async (args) => {
108
+ const result = contextSession(args, index);
109
+ return {
110
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
111
+ };
112
+ });
113
+ server.tool("context_cochanges", "Get files that frequently co-change with a given file, based on git history.", contextCochangesSchema, async (args) => {
114
+ const result = contextCochanges(args, index);
115
+ return {
116
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
117
+ };
118
+ });
119
+ server.tool("context_dna", "Analyze git history to discover codebase patterns, hotspots, architectural layers, and co-change clusters. Saves a longterm reference entry.", contextDnaSchema, async (args) => {
120
+ const result = await contextDna(args, index, embedder);
121
+ return {
122
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
123
+ };
124
+ });
125
+ server.tool("context_chain", "Retrieve all entries in a decision chain by chain ID. Returns entries chronologically.", contextChainSchema, async (args) => {
126
+ const result = contextChain(args, index);
127
+ return {
128
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
129
+ };
130
+ });
131
+ return server;
132
+ }
133
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ export interface TemplateEmbedding {
2
+ category: string;
3
+ text: string;
4
+ embedding: Float32Array;
5
+ }
6
+ export declare class Embedder {
7
+ private extractor;
8
+ private cache;
9
+ private directiveTemplates;
10
+ private categoryTemplates;
11
+ private intentTemplates;
12
+ /** Pre-load the model so first real query is fast. */
13
+ warmup(): Promise<void>;
14
+ private ensureModel;
15
+ embed(text: string): Promise<Float32Array>;
16
+ /** Pre-computed directive templates for correction detection */
17
+ getDirectiveTemplates(): Promise<TemplateEmbedding[]>;
18
+ /** Pre-computed category templates for distillation */
19
+ getCategoryTemplates(): Promise<TemplateEmbedding[]>;
20
+ /** Pre-computed intent templates for autonomous capture */
21
+ getIntentTemplates(): Promise<TemplateEmbedding[]>;
22
+ /** Classify a sentence against templates, return best match if above threshold */
23
+ classifySentence(sentence: string, templates: TemplateEmbedding[], threshold?: number): Promise<{
24
+ category: string;
25
+ similarity: number;
26
+ } | null>;
27
+ }
@@ -0,0 +1,126 @@
1
+ import { pipeline, env, } from "@huggingface/transformers";
2
+ import { MODELS_DIR } from "./paths.js";
3
+ const MAX_CACHE = 100;
4
+ export class Embedder {
5
+ extractor = null;
6
+ cache = new Map();
7
+ directiveTemplates = null;
8
+ categoryTemplates = null;
9
+ intentTemplates = null;
10
+ /** Pre-load the model so first real query is fast. */
11
+ async warmup() {
12
+ await this.ensureModel();
13
+ }
14
+ async ensureModel() {
15
+ if (!this.extractor) {
16
+ env.cacheDir = MODELS_DIR;
17
+ // @ts-expect-error -- pipeline() union type too complex for TS; runtime type is correct
18
+ this.extractor = await pipeline("feature-extraction", "Xenova/all-MiniLM-L6-v2", { dtype: "q8" });
19
+ }
20
+ return this.extractor;
21
+ }
22
+ async embed(text) {
23
+ const key = text.trim().toLowerCase();
24
+ const cached = this.cache.get(key);
25
+ if (cached)
26
+ return cached;
27
+ const extractor = await this.ensureModel();
28
+ const result = await extractor(text, {
29
+ pooling: "mean",
30
+ normalize: true,
31
+ });
32
+ const embedding = result.data;
33
+ // LRU eviction: delete oldest if at capacity
34
+ if (this.cache.size >= MAX_CACHE) {
35
+ const oldest = this.cache.keys().next().value;
36
+ this.cache.delete(oldest);
37
+ }
38
+ this.cache.set(key, embedding);
39
+ return embedding;
40
+ }
41
+ /** Pre-computed directive templates for correction detection */
42
+ async getDirectiveTemplates() {
43
+ if (this.directiveTemplates)
44
+ return this.directiveTemplates;
45
+ const directives = [
46
+ { category: "always", text: "always do this from now on" },
47
+ { category: "never", text: "never do that again" },
48
+ { category: "stop", text: "stop doing this please" },
49
+ { category: "remember", text: "please remember to do this going forward" },
50
+ { category: "preference", text: "I prefer this approach instead" },
51
+ { category: "correction", text: "that's wrong, do it this way instead" },
52
+ ];
53
+ this.directiveTemplates = [];
54
+ for (const d of directives) {
55
+ const embedding = await this.embed(d.text);
56
+ this.directiveTemplates.push({ ...d, embedding });
57
+ }
58
+ return this.directiveTemplates;
59
+ }
60
+ /** Pre-computed category templates for distillation */
61
+ async getCategoryTemplates() {
62
+ if (this.categoryTemplates)
63
+ return this.categoryTemplates;
64
+ const categories = [
65
+ { category: "decision", text: "we decided to go with this approach" },
66
+ { category: "decision", text: "let's use this option instead" },
67
+ { category: "solution", text: "the fix was to change this" },
68
+ { category: "solution", text: "this worked because of that reason" },
69
+ { category: "discovery", text: "turns out the issue was caused by this" },
70
+ { category: "discovery", text: "I found out that this is how it works" },
71
+ ];
72
+ this.categoryTemplates = [];
73
+ for (const c of categories) {
74
+ const embedding = await this.embed(c.text);
75
+ this.categoryTemplates.push({ ...c, embedding });
76
+ }
77
+ return this.categoryTemplates;
78
+ }
79
+ /** Pre-computed intent templates for autonomous capture */
80
+ async getIntentTemplates() {
81
+ if (this.intentTemplates)
82
+ return this.intentTemplates;
83
+ const intents = [
84
+ { category: "declaration", text: "this is my project" },
85
+ { category: "declaration", text: "that's my app" },
86
+ { category: "declaration", text: "my app is called" },
87
+ { category: "declaration", text: "I built this" },
88
+ { category: "declaration", text: "this is called my tool" },
89
+ { category: "identity", text: "my name is" },
90
+ { category: "identity", text: "my username is" },
91
+ { category: "identity", text: "my account name is" },
92
+ { category: "preference", text: "I like using this tool" },
93
+ { category: "preference", text: "I usually do it this way" },
94
+ { category: "preference", text: "I prefer this approach" },
95
+ { category: "preference", text: "I prefer using this over that" },
96
+ { category: "frustration", text: "this keeps happening over and over" },
97
+ { category: "frustration", text: "why does this always break" },
98
+ { category: "ownership", text: "this belongs to me" },
99
+ { category: "ownership", text: "I own this repository" },
100
+ { category: "ownership", text: "this is my repo" },
101
+ ];
102
+ this.intentTemplates = [];
103
+ for (const i of intents) {
104
+ const embedding = await this.embed(i.text);
105
+ this.intentTemplates.push({ ...i, embedding });
106
+ }
107
+ return this.intentTemplates;
108
+ }
109
+ /** Classify a sentence against templates, return best match if above threshold */
110
+ async classifySentence(sentence, templates, threshold = 0.7) {
111
+ const sentenceEmb = await this.embed(sentence);
112
+ let bestMatch = null;
113
+ for (const tpl of templates) {
114
+ let dot = 0;
115
+ for (let i = 0; i < sentenceEmb.length; i++) {
116
+ dot += sentenceEmb[i] * tpl.embedding[i];
117
+ }
118
+ // Embeddings are L2-normalized, so dot product = cosine similarity
119
+ if (dot >= threshold && (!bestMatch || dot > bestMatch.similarity)) {
120
+ bestMatch = { category: tpl.category, similarity: dot };
121
+ }
122
+ }
123
+ return bestMatch;
124
+ }
125
+ }
126
+ //# sourceMappingURL=embedder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedder.js","sourceRoot":"","sources":["../../../src/storage/embedder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ export interface GitCommit {
2
+ sha: string;
3
+ message: string;
4
+ author: string;
5
+ date: string;
6
+ branch: string;
7
+ files: Array<{
8
+ path: string;
9
+ insertions: number;
10
+ deletions: number;
11
+ }>;
12
+ }
13
+ export declare function isGitRepo(dir: string): boolean;
14
+ export declare function getCurrentBranch(repoPath: string): string;
15
+ export declare function getGitLog(repoPath: string, opts?: {
16
+ days?: number;
17
+ branch?: string;
18
+ }): GitCommit[];
19
+ export declare function getRecentlyChangedFiles(repoPath: string): string[];
20
+ export declare function formatCommitAsContent(commit: GitCommit): string;
@@ -0,0 +1,98 @@
1
+ import { execFileSync, execSync } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ export function isGitRepo(dir) {
5
+ return existsSync(join(dir, ".git"));
6
+ }
7
+ export function getCurrentBranch(repoPath) {
8
+ try {
9
+ return execSync("git rev-parse --abbrev-ref HEAD", {
10
+ cwd: repoPath,
11
+ encoding: "utf-8",
12
+ }).trim();
13
+ }
14
+ catch {
15
+ return "unknown";
16
+ }
17
+ }
18
+ export function getGitLog(repoPath, opts = {}) {
19
+ const days = opts.days ?? 7;
20
+ const branch = opts.branch ?? getCurrentBranch(repoPath);
21
+ try {
22
+ // Get commits with stats (execFileSync to avoid shell injection via branch name)
23
+ const raw = execFileSync("git", [
24
+ "log", branch, `--since=${days} days ago`,
25
+ "--format=COMMIT_SEP%n%H%n%s%n%an%n%aI", "--numstat",
26
+ ], { cwd: repoPath, encoding: "utf-8", maxBuffer: 10 * 1024 * 1024 });
27
+ const commits = [];
28
+ const blocks = raw.split("COMMIT_SEP\n").filter(Boolean);
29
+ for (const block of blocks) {
30
+ const lines = block.trim().split("\n");
31
+ if (lines.length < 4)
32
+ continue;
33
+ const sha = lines[0];
34
+ const message = lines[1];
35
+ const author = lines[2];
36
+ const dateStr = lines[3].slice(0, 10); // YYYY-MM-DD
37
+ const files = [];
38
+ for (let i = 4; i < lines.length; i++) {
39
+ const line = lines[i].trim();
40
+ if (!line)
41
+ continue;
42
+ const parts = line.split("\t");
43
+ if (parts.length === 3) {
44
+ files.push({
45
+ insertions: parseInt(parts[0]) || 0,
46
+ deletions: parseInt(parts[1]) || 0,
47
+ path: parts[2],
48
+ });
49
+ }
50
+ }
51
+ commits.push({ sha, message, author, date: dateStr, branch, files });
52
+ }
53
+ return commits;
54
+ }
55
+ catch {
56
+ return [];
57
+ }
58
+ }
59
+ export function getRecentlyChangedFiles(repoPath) {
60
+ const files = new Set();
61
+ try {
62
+ // Last 3 commits
63
+ const committed = execSync("git diff --name-only HEAD~3", {
64
+ cwd: repoPath,
65
+ encoding: "utf-8",
66
+ timeout: 3000,
67
+ }).trim();
68
+ if (committed)
69
+ committed.split("\n").forEach(f => files.add(f));
70
+ }
71
+ catch {
72
+ // May fail if fewer than 3 commits
73
+ }
74
+ try {
75
+ // Uncommitted changes
76
+ const uncommitted = execSync("git diff --name-only", {
77
+ cwd: repoPath,
78
+ encoding: "utf-8",
79
+ timeout: 3000,
80
+ }).trim();
81
+ if (uncommitted)
82
+ uncommitted.split("\n").forEach(f => files.add(f));
83
+ }
84
+ catch {
85
+ // Ignore
86
+ }
87
+ return Array.from(files);
88
+ }
89
+ export function formatCommitAsContent(commit) {
90
+ const fileList = commit.files
91
+ .map(f => {
92
+ const stats = `+${f.insertions}/-${f.deletions}`;
93
+ return `${f.path} (${stats})`;
94
+ })
95
+ .join(", ");
96
+ return `[${commit.branch}] ${commit.message}\nFiles: ${fileList || "none"}`;
97
+ }
98
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../../src/storage/git.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { ContextIndex } from "./sqlite.js";
2
+ export interface MaintenanceReport {
3
+ decayed: number;
4
+ demoted: number;
5
+ promotedStable: number;
6
+ promotedFrequent: number;
7
+ consolidated: number;
8
+ }
9
+ export declare function runMaintenance(index: ContextIndex): MaintenanceReport;
@@ -0,0 +1,46 @@
1
+ export function runMaintenance(index) {
2
+ const decayed = index.decayEphemeral();
3
+ const demoted = index.demoteIdle();
4
+ const promotedStable = index.promoteStable();
5
+ const promotedFrequent = index.promoteFrequent();
6
+ const consolidated = consolidate(index);
7
+ return { decayed, demoted, promotedStable, promotedFrequent, consolidated };
8
+ }
9
+ function consolidate(index) {
10
+ const groups = index.findConsolidationCandidates(0.75);
11
+ if (groups.length === 0)
12
+ return 0;
13
+ let consolidated = 0;
14
+ for (const group of groups) {
15
+ // Filter to entries older than 3 days
16
+ const now = Date.now();
17
+ const threeDaysMs = 3 * 24 * 60 * 60 * 1000;
18
+ const eligible = group.entries.filter(e => {
19
+ const entryDate = new Date(e.date).getTime();
20
+ return (now - entryDate) > threeDaysMs;
21
+ });
22
+ if (eligible.length < 3)
23
+ continue; // Need 3+ to consolidate
24
+ // Skip rule and reference types
25
+ if (eligible.some(e => e.type === "rule" || e.type === "reference"))
26
+ continue;
27
+ // Find survivor: highest access count
28
+ eligible.sort((a, b) => (b.accessCount ?? 0) - (a.accessCount ?? 0));
29
+ const survivor = eligible[0];
30
+ const others = eligible.slice(1);
31
+ // Merge tags from others into survivor
32
+ index.mergeTagsInto(survivor.id, others.map(e => e.id));
33
+ // Update survivor content with consolidation note
34
+ const updatedContent = `${survivor.content}\n[Consolidated from ${eligible.length} entries]`;
35
+ index.updateEntryContent(survivor.id, updatedContent);
36
+ // Promote survivor if ephemeral
37
+ if (survivor.tier === "ephemeral") {
38
+ index.changeTier(survivor.id, "working");
39
+ }
40
+ // Archive others
41
+ index.archiveEntries(others.map(e => e.id));
42
+ consolidated++;
43
+ }
44
+ return consolidated;
45
+ }
46
+ //# sourceMappingURL=maintenance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"maintenance.js","sourceRoot":"","sources":["../../../src/storage/maintenance.ts"],"names":[],"mappings":"AAUA,MAAM,UAAU,cAAc,CAAC,KAAmB;IAChD,MAAM,OAAO,GAAG,KAAK,CAAC,cAAc,EAAE,CAAC;IACvC,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC;IACnC,MAAM,cAAc,GAAG,KAAK,CAAC,aAAa,EAAE,CAAC;IAC7C,MAAM,gBAAgB,GAAG,KAAK,CAAC,eAAe,EAAE,CAAC;IACjD,MAAM,YAAY,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IACxC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,YAAY,EAAE,CAAC;AAC9E,CAAC;AAED,SAAS,WAAW,CAAC,KAAmB;IACtC,MAAM,MAAM,GAAG,KAAK,CAAC,2BAA2B,CAAC,IAAI,CAAC,CAAC;IACvD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAElC,IAAI,YAAY,GAAG,CAAC,CAAC;IAErB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,sCAAsC;QACtC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;QAC5C,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;YACxC,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;YAC7C,OAAO,CAAC,GAAG,GAAG,SAAS,CAAC,GAAG,WAAW,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS,CAAC,yBAAyB;QAE5D,gCAAgC;QAChC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC;YAAE,SAAS;QAE9E,sCAAsC;QACtC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,CAAC;QACrE,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAEjC,uCAAuC;QACvC,KAAK,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAExD,kDAAkD;QAClD,MAAM,cAAc,GAAG,GAAG,QAAQ,CAAC,OAAO,wBAAwB,QAAQ,CAAC,MAAM,WAAW,CAAC;QAC7F,KAAK,CAAC,kBAAkB,CAAC,QAAQ,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;QAEtD,gCAAgC;QAChC,IAAI,QAAQ,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAClC,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;QAC3C,CAAC;QAED,iBAAiB;QACjB,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAE5C,YAAY,EAAE,CAAC;IACjB,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC"}
@@ -0,0 +1,21 @@
1
+ export interface ContextEntry {
2
+ id: string;
3
+ date: string;
4
+ time: string;
5
+ type: string;
6
+ tags: string[];
7
+ content: string;
8
+ sourceFile: string;
9
+ tier?: "ephemeral" | "working" | "longterm";
10
+ accessCount?: number;
11
+ lastAccessed?: string | null;
12
+ pinned?: boolean;
13
+ archived?: boolean;
14
+ project?: string | null;
15
+ sessionId?: string | null;
16
+ agentId?: string | null;
17
+ }
18
+ export declare function appendEntry(content: string, type: string, tags: string[]): ContextEntry;
19
+ export declare function parseMarkdownFile(filePath: string): ContextEntry[];
20
+ export declare function parseMarkdownText(text: string, sourceFile: string): ContextEntry[];
21
+ export declare function listMarkdownFiles(): string[];
@@ -0,0 +1,79 @@
1
+ import { readFileSync, writeFileSync, existsSync, readdirSync } from "node:fs";
2
+ import { dateToFilePath, CONTEXT_DIR } from "./paths.js";
3
+ function generateId() {
4
+ return Date.now().toString(36) + Math.random().toString(36).slice(2, 6);
5
+ }
6
+ function formatTime() {
7
+ const now = new Date();
8
+ return now.toTimeString().slice(0, 5); // HH:MM
9
+ }
10
+ function formatDate() {
11
+ const now = new Date();
12
+ return now.toISOString().slice(0, 10); // YYYY-MM-DD
13
+ }
14
+ export function appendEntry(content, type, tags) {
15
+ const date = formatDate();
16
+ const time = formatTime();
17
+ const id = generateId();
18
+ const filePath = dateToFilePath(date);
19
+ const tagStr = tags.join(", ");
20
+ let fileContent = "";
21
+ if (existsSync(filePath)) {
22
+ fileContent = readFileSync(filePath, "utf-8");
23
+ }
24
+ else {
25
+ fileContent = `# Context Log: ${date}\n`;
26
+ }
27
+ const entryBlock = `\n## ${time} | ${type} | ${tagStr}\n<!-- id:${id} -->\n${content}\n`;
28
+ fileContent += entryBlock;
29
+ writeFileSync(filePath, fileContent, "utf-8");
30
+ return { id, date, time, type, tags, content, sourceFile: filePath };
31
+ }
32
+ export function parseMarkdownFile(filePath) {
33
+ if (!existsSync(filePath))
34
+ return [];
35
+ const text = readFileSync(filePath, "utf-8");
36
+ return parseMarkdownText(text, filePath);
37
+ }
38
+ export function parseMarkdownText(text, sourceFile) {
39
+ const entries = [];
40
+ // Extract date from header or filename
41
+ const dateMatch = text.match(/^# Context Log: (\d{4}-\d{2}-\d{2})/m) ??
42
+ sourceFile.match(/(\d{4}-\d{2}-\d{2})\.md$/);
43
+ const date = dateMatch?.[1] ?? "unknown";
44
+ // Split on ## headers
45
+ const sections = text.split(/^## /m).slice(1);
46
+ for (const section of sections) {
47
+ const headerEnd = section.indexOf("\n");
48
+ if (headerEnd === -1)
49
+ continue;
50
+ const header = section.slice(0, headerEnd).trim();
51
+ const body = section.slice(headerEnd + 1).trim();
52
+ // Parse header: "HH:MM | type | tags"
53
+ const parts = header.split("|").map((s) => s.trim());
54
+ if (parts.length < 2)
55
+ continue;
56
+ const time = parts[0];
57
+ const type = parts[1];
58
+ const tagStr = parts.slice(2).join(", ");
59
+ const tags = tagStr
60
+ ? tagStr.split(",").map((t) => t.trim()).filter(Boolean)
61
+ : [];
62
+ // Extract id from <!-- id:xxx --> comment
63
+ const idMatch = body.match(/<!-- id:(\S+) -->/);
64
+ const id = idMatch?.[1] ?? generateId();
65
+ // Content is everything after the id comment (or all of body if no id)
66
+ const content = body.replace(/<!-- id:\S+ -->\n?/, "").trim();
67
+ entries.push({ id, date, time, type, tags, content, sourceFile });
68
+ }
69
+ return entries;
70
+ }
71
+ export function listMarkdownFiles() {
72
+ if (!existsSync(CONTEXT_DIR))
73
+ return [];
74
+ return readdirSync(CONTEXT_DIR)
75
+ .filter((f) => f.endsWith(".md"))
76
+ .sort()
77
+ .map((f) => `${CONTEXT_DIR}/${f}`);
78
+ }
79
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../../src/storage/markdown.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export declare const CONTEXT_DIR: string;
2
+ export declare const DB_DIR: string;
3
+ export declare const DB_PATH: string;
4
+ export declare const MODELS_DIR: string;
5
+ export declare function ensureDirs(): void;
6
+ export declare function dateToFilePath(date: string): string;
@@ -0,0 +1,17 @@
1
+ import { join } from "node:path";
2
+ import { homedir } from "node:os";
3
+ import { mkdirSync } from "node:fs";
4
+ const BASE_DIR = join(homedir(), ".claude-context");
5
+ export const CONTEXT_DIR = join(BASE_DIR, "context");
6
+ export const DB_DIR = join(BASE_DIR, "db");
7
+ export const DB_PATH = join(DB_DIR, "context.db");
8
+ export const MODELS_DIR = join(BASE_DIR, "models");
9
+ export function ensureDirs() {
10
+ mkdirSync(CONTEXT_DIR, { recursive: true });
11
+ mkdirSync(DB_DIR, { recursive: true });
12
+ mkdirSync(MODELS_DIR, { recursive: true });
13
+ }
14
+ export function dateToFilePath(date) {
15
+ return join(CONTEXT_DIR, `${date}.md`);
16
+ }
17
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/storage/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,iBAAiB,CAAC,CAAC;AACpD,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AACrD,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AAC3C,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AAClD,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAEnD,MAAM,UAAU,UAAU;IACxB,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,IAAI,CAAC,WAAW,EAAE,GAAG,IAAI,KAAK,CAAC,CAAC;AACzC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function detectProject(cwd?: string): string | null;
2
+ export declare function resetProjectCache(): void;