@rangerchaz/aimem 0.1.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 (163) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +380 -0
  3. package/dist/cli/commands/git.d.ts +6 -0
  4. package/dist/cli/commands/git.d.ts.map +1 -0
  5. package/dist/cli/commands/git.js +298 -0
  6. package/dist/cli/commands/git.js.map +1 -0
  7. package/dist/cli/commands/hook-session-end.d.ts +7 -0
  8. package/dist/cli/commands/hook-session-end.d.ts.map +1 -0
  9. package/dist/cli/commands/hook-session-end.js +109 -0
  10. package/dist/cli/commands/hook-session-end.js.map +1 -0
  11. package/dist/cli/commands/hook-session-start.d.ts +7 -0
  12. package/dist/cli/commands/hook-session-start.d.ts.map +1 -0
  13. package/dist/cli/commands/hook-session-start.js +116 -0
  14. package/dist/cli/commands/hook-session-start.js.map +1 -0
  15. package/dist/cli/commands/import.d.ts +14 -0
  16. package/dist/cli/commands/import.d.ts.map +1 -0
  17. package/dist/cli/commands/import.js +527 -0
  18. package/dist/cli/commands/import.js.map +1 -0
  19. package/dist/cli/commands/init.d.ts +2 -0
  20. package/dist/cli/commands/init.d.ts.map +1 -0
  21. package/dist/cli/commands/init.js +32 -0
  22. package/dist/cli/commands/init.js.map +1 -0
  23. package/dist/cli/commands/mcp-serve.d.ts +2 -0
  24. package/dist/cli/commands/mcp-serve.d.ts.map +1 -0
  25. package/dist/cli/commands/mcp-serve.js +5 -0
  26. package/dist/cli/commands/mcp-serve.js.map +1 -0
  27. package/dist/cli/commands/query.d.ts +8 -0
  28. package/dist/cli/commands/query.d.ts.map +1 -0
  29. package/dist/cli/commands/query.js +83 -0
  30. package/dist/cli/commands/query.js.map +1 -0
  31. package/dist/cli/commands/setup.d.ts +10 -0
  32. package/dist/cli/commands/setup.d.ts.map +1 -0
  33. package/dist/cli/commands/setup.js +504 -0
  34. package/dist/cli/commands/setup.js.map +1 -0
  35. package/dist/cli/commands/start.d.ts +8 -0
  36. package/dist/cli/commands/start.d.ts.map +1 -0
  37. package/dist/cli/commands/start.js +90 -0
  38. package/dist/cli/commands/start.js.map +1 -0
  39. package/dist/cli/commands/status.d.ts +2 -0
  40. package/dist/cli/commands/status.d.ts.map +1 -0
  41. package/dist/cli/commands/status.js +85 -0
  42. package/dist/cli/commands/status.js.map +1 -0
  43. package/dist/cli/commands/stop.d.ts +7 -0
  44. package/dist/cli/commands/stop.d.ts.map +1 -0
  45. package/dist/cli/commands/stop.js +46 -0
  46. package/dist/cli/commands/stop.js.map +1 -0
  47. package/dist/cli/commands/visualize.d.ts +8 -0
  48. package/dist/cli/commands/visualize.d.ts.map +1 -0
  49. package/dist/cli/commands/visualize.js +96 -0
  50. package/dist/cli/commands/visualize.js.map +1 -0
  51. package/dist/cli/index.d.ts +3 -0
  52. package/dist/cli/index.d.ts.map +1 -0
  53. package/dist/cli/index.js +114 -0
  54. package/dist/cli/index.js.map +1 -0
  55. package/dist/db/index.d.ts +55 -0
  56. package/dist/db/index.d.ts.map +1 -0
  57. package/dist/db/index.js +464 -0
  58. package/dist/db/index.js.map +1 -0
  59. package/dist/db/schema.d.ts +4 -0
  60. package/dist/db/schema.d.ts.map +1 -0
  61. package/dist/db/schema.js +200 -0
  62. package/dist/db/schema.js.map +1 -0
  63. package/dist/extractor/index.d.ts +27 -0
  64. package/dist/extractor/index.d.ts.map +1 -0
  65. package/dist/extractor/index.js +227 -0
  66. package/dist/extractor/index.js.map +1 -0
  67. package/dist/git/extractor.d.ts +30 -0
  68. package/dist/git/extractor.d.ts.map +1 -0
  69. package/dist/git/extractor.js +126 -0
  70. package/dist/git/extractor.js.map +1 -0
  71. package/dist/git/hooks.d.ts +36 -0
  72. package/dist/git/hooks.d.ts.map +1 -0
  73. package/dist/git/hooks.js +142 -0
  74. package/dist/git/hooks.js.map +1 -0
  75. package/dist/git/index.d.ts +69 -0
  76. package/dist/git/index.d.ts.map +1 -0
  77. package/dist/git/index.js +250 -0
  78. package/dist/git/index.js.map +1 -0
  79. package/dist/indexer/index.d.ts +20 -0
  80. package/dist/indexer/index.d.ts.map +1 -0
  81. package/dist/indexer/index.js +173 -0
  82. package/dist/indexer/index.js.map +1 -0
  83. package/dist/indexer/parsers/base.d.ts +19 -0
  84. package/dist/indexer/parsers/base.d.ts.map +1 -0
  85. package/dist/indexer/parsers/base.js +46 -0
  86. package/dist/indexer/parsers/base.js.map +1 -0
  87. package/dist/indexer/parsers/cpp.d.ts +3 -0
  88. package/dist/indexer/parsers/cpp.d.ts.map +1 -0
  89. package/dist/indexer/parsers/cpp.js +180 -0
  90. package/dist/indexer/parsers/cpp.js.map +1 -0
  91. package/dist/indexer/parsers/go.d.ts +3 -0
  92. package/dist/indexer/parsers/go.d.ts.map +1 -0
  93. package/dist/indexer/parsers/go.js +98 -0
  94. package/dist/indexer/parsers/go.js.map +1 -0
  95. package/dist/indexer/parsers/java.d.ts +3 -0
  96. package/dist/indexer/parsers/java.d.ts.map +1 -0
  97. package/dist/indexer/parsers/java.js +204 -0
  98. package/dist/indexer/parsers/java.js.map +1 -0
  99. package/dist/indexer/parsers/javascript.d.ts +3 -0
  100. package/dist/indexer/parsers/javascript.d.ts.map +1 -0
  101. package/dist/indexer/parsers/javascript.js +157 -0
  102. package/dist/indexer/parsers/javascript.js.map +1 -0
  103. package/dist/indexer/parsers/kotlin.d.ts +3 -0
  104. package/dist/indexer/parsers/kotlin.d.ts.map +1 -0
  105. package/dist/indexer/parsers/kotlin.js +182 -0
  106. package/dist/indexer/parsers/kotlin.js.map +1 -0
  107. package/dist/indexer/parsers/php.d.ts +3 -0
  108. package/dist/indexer/parsers/php.d.ts.map +1 -0
  109. package/dist/indexer/parsers/php.js +190 -0
  110. package/dist/indexer/parsers/php.js.map +1 -0
  111. package/dist/indexer/parsers/python.d.ts +3 -0
  112. package/dist/indexer/parsers/python.d.ts.map +1 -0
  113. package/dist/indexer/parsers/python.js +101 -0
  114. package/dist/indexer/parsers/python.js.map +1 -0
  115. package/dist/indexer/parsers/ruby.d.ts +3 -0
  116. package/dist/indexer/parsers/ruby.d.ts.map +1 -0
  117. package/dist/indexer/parsers/ruby.js +92 -0
  118. package/dist/indexer/parsers/ruby.js.map +1 -0
  119. package/dist/indexer/parsers/rust.d.ts +3 -0
  120. package/dist/indexer/parsers/rust.d.ts.map +1 -0
  121. package/dist/indexer/parsers/rust.js +190 -0
  122. package/dist/indexer/parsers/rust.js.map +1 -0
  123. package/dist/indexer/watcher-daemon.d.ts +2 -0
  124. package/dist/indexer/watcher-daemon.d.ts.map +1 -0
  125. package/dist/indexer/watcher-daemon.js +27 -0
  126. package/dist/indexer/watcher-daemon.js.map +1 -0
  127. package/dist/indexer/watcher.d.ts +7 -0
  128. package/dist/indexer/watcher.d.ts.map +1 -0
  129. package/dist/indexer/watcher.js +77 -0
  130. package/dist/indexer/watcher.js.map +1 -0
  131. package/dist/mcp/server.d.ts +2 -0
  132. package/dist/mcp/server.d.ts.map +1 -0
  133. package/dist/mcp/server.js +241 -0
  134. package/dist/mcp/server.js.map +1 -0
  135. package/dist/proxy/interceptor-mockttp.d.ts +27 -0
  136. package/dist/proxy/interceptor-mockttp.d.ts.map +1 -0
  137. package/dist/proxy/interceptor-mockttp.js +274 -0
  138. package/dist/proxy/interceptor-mockttp.js.map +1 -0
  139. package/dist/proxy/proxy-daemon.d.ts +5 -0
  140. package/dist/proxy/proxy-daemon.d.ts.map +1 -0
  141. package/dist/proxy/proxy-daemon.js +26 -0
  142. package/dist/proxy/proxy-daemon.js.map +1 -0
  143. package/dist/query/index.d.ts +32 -0
  144. package/dist/query/index.d.ts.map +1 -0
  145. package/dist/query/index.js +135 -0
  146. package/dist/query/index.js.map +1 -0
  147. package/dist/types/index.d.ts +89 -0
  148. package/dist/types/index.d.ts.map +1 -0
  149. package/dist/types/index.js +3 -0
  150. package/dist/types/index.js.map +1 -0
  151. package/dist/visualize/index.d.ts +144 -0
  152. package/dist/visualize/index.d.ts.map +1 -0
  153. package/dist/visualize/index.js +707 -0
  154. package/dist/visualize/index.js.map +1 -0
  155. package/dist/visualize/server.d.ts +7 -0
  156. package/dist/visualize/server.d.ts.map +1 -0
  157. package/dist/visualize/server.js +77 -0
  158. package/dist/visualize/server.js.map +1 -0
  159. package/dist/visualize/template.d.ts +3 -0
  160. package/dist/visualize/template.d.ts.map +1 -0
  161. package/dist/visualize/template.js +3465 -0
  162. package/dist/visualize/template.js.map +1 -0
  163. package/package.json +56 -0
@@ -0,0 +1,200 @@
1
+ // Database schema for aimem
2
+ export const SCHEMA = `
3
+ -- Projects table
4
+ CREATE TABLE IF NOT EXISTS projects (
5
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
6
+ path TEXT NOT NULL UNIQUE,
7
+ name TEXT NOT NULL,
8
+ created_at TEXT DEFAULT (datetime('now'))
9
+ );
10
+
11
+ -- Files table
12
+ CREATE TABLE IF NOT EXISTS files (
13
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
14
+ project_id INTEGER NOT NULL,
15
+ path TEXT NOT NULL,
16
+ hash TEXT NOT NULL,
17
+ last_indexed TEXT DEFAULT (datetime('now')),
18
+ FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
19
+ UNIQUE(project_id, path)
20
+ );
21
+
22
+ -- Structures table (functions, classes, methods, etc.)
23
+ CREATE TABLE IF NOT EXISTS structures (
24
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
25
+ file_id INTEGER NOT NULL,
26
+ type TEXT NOT NULL CHECK (type IN ('function', 'class', 'method', 'interface', 'type', 'variable', 'module')),
27
+ name TEXT NOT NULL,
28
+ line_start INTEGER NOT NULL,
29
+ line_end INTEGER NOT NULL,
30
+ signature TEXT,
31
+ raw_content TEXT NOT NULL,
32
+ metadata TEXT DEFAULT '{}',
33
+ FOREIGN KEY (file_id) REFERENCES files(id) ON DELETE CASCADE
34
+ );
35
+
36
+ -- Conversations table
37
+ CREATE TABLE IF NOT EXISTS conversations (
38
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
39
+ project_id INTEGER,
40
+ timestamp TEXT DEFAULT (datetime('now')),
41
+ model TEXT,
42
+ tool TEXT,
43
+ summary TEXT,
44
+ raw_content TEXT NOT NULL,
45
+ FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE SET NULL
46
+ );
47
+
48
+ -- Links table (graph edges)
49
+ CREATE TABLE IF NOT EXISTS links (
50
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
51
+ source_type TEXT NOT NULL CHECK (source_type IN ('file', 'structure', 'conversation', 'extraction')),
52
+ source_id INTEGER NOT NULL,
53
+ target_type TEXT NOT NULL CHECK (target_type IN ('file', 'structure', 'conversation', 'extraction')),
54
+ target_id INTEGER NOT NULL,
55
+ link_type TEXT NOT NULL CHECK (link_type IN ('decision', 'touched', 'rejected', 'calls', 'called_by', 'references')),
56
+ UNIQUE(source_type, source_id, target_type, target_id, link_type)
57
+ );
58
+
59
+ -- Extractions table (decisions, patterns, rejections from conversations)
60
+ CREATE TABLE IF NOT EXISTS extractions (
61
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
62
+ conversation_id INTEGER NOT NULL,
63
+ type TEXT NOT NULL CHECK (type IN ('decision', 'pattern', 'rejection', 'question')),
64
+ content TEXT NOT NULL,
65
+ metadata TEXT DEFAULT '{}',
66
+ FOREIGN KEY (conversation_id) REFERENCES conversations(id) ON DELETE CASCADE
67
+ );
68
+
69
+ -- Indexes for common queries
70
+ CREATE INDEX IF NOT EXISTS idx_files_project ON files(project_id);
71
+ CREATE INDEX IF NOT EXISTS idx_files_path ON files(path);
72
+ CREATE INDEX IF NOT EXISTS idx_structures_file ON structures(file_id);
73
+ CREATE INDEX IF NOT EXISTS idx_structures_name ON structures(name);
74
+ CREATE INDEX IF NOT EXISTS idx_structures_type ON structures(type);
75
+ CREATE INDEX IF NOT EXISTS idx_conversations_project ON conversations(project_id);
76
+ CREATE INDEX IF NOT EXISTS idx_links_source ON links(source_type, source_id);
77
+ CREATE INDEX IF NOT EXISTS idx_links_target ON links(target_type, target_id);
78
+ CREATE INDEX IF NOT EXISTS idx_extractions_conversation ON extractions(conversation_id);
79
+ CREATE INDEX IF NOT EXISTS idx_extractions_type ON extractions(type);
80
+
81
+ -- Full-text search for structures
82
+ CREATE VIRTUAL TABLE IF NOT EXISTS structures_fts USING fts5(
83
+ name,
84
+ signature,
85
+ raw_content,
86
+ content='structures',
87
+ content_rowid='id'
88
+ );
89
+
90
+ -- Triggers to keep FTS in sync
91
+ CREATE TRIGGER IF NOT EXISTS structures_ai AFTER INSERT ON structures BEGIN
92
+ INSERT INTO structures_fts(rowid, name, signature, raw_content)
93
+ VALUES (new.id, new.name, new.signature, new.raw_content);
94
+ END;
95
+
96
+ CREATE TRIGGER IF NOT EXISTS structures_ad AFTER DELETE ON structures BEGIN
97
+ INSERT INTO structures_fts(structures_fts, rowid, name, signature, raw_content)
98
+ VALUES ('delete', old.id, old.name, old.signature, old.raw_content);
99
+ END;
100
+
101
+ CREATE TRIGGER IF NOT EXISTS structures_au AFTER UPDATE ON structures BEGIN
102
+ INSERT INTO structures_fts(structures_fts, rowid, name, signature, raw_content)
103
+ VALUES ('delete', old.id, old.name, old.signature, old.raw_content);
104
+ INSERT INTO structures_fts(rowid, name, signature, raw_content)
105
+ VALUES (new.id, new.name, new.signature, new.raw_content);
106
+ END;
107
+
108
+ -- Full-text search for conversations
109
+ CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
110
+ summary,
111
+ raw_content,
112
+ content='conversations',
113
+ content_rowid='id'
114
+ );
115
+
116
+ CREATE TRIGGER IF NOT EXISTS conversations_ai AFTER INSERT ON conversations BEGIN
117
+ INSERT INTO conversations_fts(rowid, summary, raw_content)
118
+ VALUES (new.id, new.summary, new.raw_content);
119
+ END;
120
+
121
+ CREATE TRIGGER IF NOT EXISTS conversations_ad AFTER DELETE ON conversations BEGIN
122
+ INSERT INTO conversations_fts(conversations_fts, rowid, summary, raw_content)
123
+ VALUES ('delete', old.id, old.summary, old.raw_content);
124
+ END;
125
+
126
+ CREATE TRIGGER IF NOT EXISTS conversations_au AFTER UPDATE ON conversations BEGIN
127
+ INSERT INTO conversations_fts(conversations_fts, rowid, summary, raw_content)
128
+ VALUES ('delete', old.id, old.summary, old.raw_content);
129
+ INSERT INTO conversations_fts(rowid, summary, raw_content)
130
+ VALUES (new.id, new.summary, new.raw_content);
131
+ END;
132
+
133
+ -- Git commits table
134
+ CREATE TABLE IF NOT EXISTS commits (
135
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
136
+ project_id INTEGER NOT NULL,
137
+ hash TEXT NOT NULL,
138
+ short_hash TEXT,
139
+ author_name TEXT,
140
+ author_email TEXT,
141
+ timestamp TEXT NOT NULL,
142
+ subject TEXT NOT NULL,
143
+ body TEXT,
144
+ parent_hashes TEXT,
145
+ FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
146
+ UNIQUE(project_id, hash)
147
+ );
148
+
149
+ CREATE INDEX IF NOT EXISTS idx_commits_project ON commits(project_id);
150
+ CREATE INDEX IF NOT EXISTS idx_commits_hash ON commits(hash);
151
+ CREATE INDEX IF NOT EXISTS idx_commits_timestamp ON commits(timestamp);
152
+
153
+ -- Full-text search for commits
154
+ CREATE VIRTUAL TABLE IF NOT EXISTS commits_fts USING fts5(
155
+ subject,
156
+ body,
157
+ content='commits',
158
+ content_rowid='id'
159
+ );
160
+
161
+ CREATE TRIGGER IF NOT EXISTS commits_ai AFTER INSERT ON commits BEGIN
162
+ INSERT INTO commits_fts(rowid, subject, body)
163
+ VALUES (new.id, new.subject, new.body);
164
+ END;
165
+
166
+ CREATE TRIGGER IF NOT EXISTS commits_ad AFTER DELETE ON commits BEGIN
167
+ INSERT INTO commits_fts(commits_fts, rowid, subject, body)
168
+ VALUES ('delete', old.id, old.subject, old.body);
169
+ END;
170
+
171
+ CREATE TRIGGER IF NOT EXISTS commits_au AFTER UPDATE ON commits BEGIN
172
+ INSERT INTO commits_fts(commits_fts, rowid, subject, body)
173
+ VALUES ('delete', old.id, old.subject, old.body);
174
+ INSERT INTO commits_fts(rowid, subject, body)
175
+ VALUES (new.id, new.subject, new.body);
176
+ END;
177
+ `;
178
+ // Migrations for existing databases
179
+ export const MIGRATIONS = [
180
+ // Migration 1: Add git authorship columns to structures
181
+ `ALTER TABLE structures ADD COLUMN last_author TEXT;`,
182
+ `ALTER TABLE structures ADD COLUMN last_author_email TEXT;`,
183
+ `ALTER TABLE structures ADD COLUMN last_commit_hash TEXT;`,
184
+ ];
185
+ // Links between commits and other entities use a separate table to avoid schema migration issues
186
+ export const COMMIT_LINKS_SCHEMA = `
187
+ CREATE TABLE IF NOT EXISTS commit_links (
188
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
189
+ commit_id INTEGER NOT NULL,
190
+ target_type TEXT NOT NULL CHECK (target_type IN ('structure', 'file', 'extraction', 'conversation')),
191
+ target_id INTEGER NOT NULL,
192
+ link_type TEXT NOT NULL CHECK (link_type IN ('modified', 'committed_in', 'introduced')),
193
+ FOREIGN KEY (commit_id) REFERENCES commits(id) ON DELETE CASCADE,
194
+ UNIQUE(commit_id, target_type, target_id, link_type)
195
+ );
196
+
197
+ CREATE INDEX IF NOT EXISTS idx_commit_links_commit ON commit_links(commit_id);
198
+ CREATE INDEX IF NOT EXISTS idx_commit_links_target ON commit_links(target_type, target_id);
199
+ `;
200
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAE5B,MAAM,CAAC,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+KrB,CAAC;AAEF,oCAAoC;AACpC,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,wDAAwD;IACxD,qDAAqD;IACrD,2DAA2D;IAC3D,0DAA0D;CAC3D,CAAC;AAEF,iGAAiG;AACjG,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;CAalC,CAAC"}
@@ -0,0 +1,27 @@
1
+ export interface TranscriptMessage {
2
+ type: string;
3
+ role?: string;
4
+ content?: string | {
5
+ type: string;
6
+ text?: string;
7
+ }[];
8
+ tool_name?: string;
9
+ tool_input?: Record<string, unknown>;
10
+ tool_result?: unknown;
11
+ }
12
+ export interface ExtractedItem {
13
+ type: 'decision' | 'rejection' | 'pattern' | 'question';
14
+ content: string;
15
+ mentionedEntities: string[];
16
+ metadata: Record<string, unknown>;
17
+ }
18
+ /**
19
+ * Extract decisions, rejections, and patterns from conversation messages.
20
+ * Uses pattern matching - no LLM required.
21
+ */
22
+ export declare function extractDecisions(messages: TranscriptMessage[]): ExtractedItem[];
23
+ /**
24
+ * Generate a summary of the conversation for storage
25
+ */
26
+ export declare function generateSummary(messages: TranscriptMessage[]): string;
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/extractor/index.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,UAAU,GAAG,WAAW,GAAG,SAAS,GAAG,UAAU,CAAC;IACxD,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,aAAa,EAAE,CA2E/E;AA2JD;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,MAAM,CAiBrE"}
@@ -0,0 +1,227 @@
1
+ // Decision and pattern extraction from conversation transcripts
2
+ /**
3
+ * Extract decisions, rejections, and patterns from conversation messages.
4
+ * Uses pattern matching - no LLM required.
5
+ */
6
+ export function extractDecisions(messages) {
7
+ const extractions = [];
8
+ // Decision patterns - phrases that indicate a choice was made
9
+ const decisionPatterns = [
10
+ /(?:we should|let's|I'll|I will|going to|decided to|will use|using|chose|choosing|the best approach is|recommend using)\s+(.+?)(?:\.|$)/gi,
11
+ /(?:the approach|the solution|the fix|the implementation|the strategy)\s+(?:is|will be|should be)\s+(.+?)(?:\.|$)/gi,
12
+ /(?:because|since|the reason is|this is because)\s+(.+?)(?:\.|$)/gi,
13
+ /(?:I've implemented|I've added|I've created|I've updated)\s+(.+?)(?:\.|$)/gi,
14
+ ];
15
+ // Rejection patterns - phrases that indicate something was ruled out
16
+ const rejectionPatterns = [
17
+ /(?:instead of|rather than|not using|won't use|shouldn't use|avoid using|don't use)\s+(.+?)(?:\.|$)/gi,
18
+ /(?:rejected|ruled out|decided against|not recommended|wouldn't work)\s+(.+?)(?:\.|$)/gi,
19
+ /(?:the problem with|the issue with|doesn't work because)\s+(.+?)(?:\.|$)/gi,
20
+ ];
21
+ // Entity patterns for linking to code structures
22
+ const classPattern = /\b([A-Z][a-zA-Z0-9]*(?:Service|Controller|Model|Helper|Manager|Handler|Factory|Builder|Provider|Middleware|Client|Server|Worker|Job|Task|Command|Query|Event|Listener|Observer|Strategy|Adapter|Decorator|Proxy|Repository|Gateway|Validator|Serializer|Parser|Formatter|Renderer|Component|Module|Plugin|Extension)?)\b/g;
23
+ const functionPattern = /\b([a-z_][a-z0-9_]*)\s*\(/g;
24
+ const methodPattern = /(?:def|function|const|let|var)\s+([a-z_][a-z0-9_]*)/g;
25
+ const filePattern = /(?:in|from|file|at)\s+[`"']?([a-zA-Z0-9_/.-]+\.[a-z]+)[`"']?/gi;
26
+ for (const msg of messages) {
27
+ if (msg.role !== 'assistant')
28
+ continue;
29
+ const content = getMessageContent(msg);
30
+ if (!content)
31
+ continue;
32
+ // Extract decisions
33
+ for (const pattern of decisionPatterns) {
34
+ pattern.lastIndex = 0; // Reset regex state
35
+ let match;
36
+ while ((match = pattern.exec(content)) !== null) {
37
+ const sentence = getSentenceAround(content, match.index);
38
+ if (isValidExtraction(sentence)) {
39
+ const entities = extractEntities(sentence, classPattern, functionPattern, methodPattern);
40
+ extractions.push({
41
+ type: 'decision',
42
+ content: cleanSentence(sentence),
43
+ mentionedEntities: entities,
44
+ metadata: {
45
+ patternType: 'decision',
46
+ originalMatch: match[0].slice(0, 100)
47
+ }
48
+ });
49
+ }
50
+ }
51
+ }
52
+ // Extract rejections
53
+ for (const pattern of rejectionPatterns) {
54
+ pattern.lastIndex = 0;
55
+ let match;
56
+ while ((match = pattern.exec(content)) !== null) {
57
+ const sentence = getSentenceAround(content, match.index);
58
+ if (isValidExtraction(sentence)) {
59
+ const entities = extractEntities(sentence, classPattern, functionPattern, methodPattern);
60
+ extractions.push({
61
+ type: 'rejection',
62
+ content: cleanSentence(sentence),
63
+ mentionedEntities: entities,
64
+ metadata: {
65
+ patternType: 'rejection',
66
+ originalMatch: match[0].slice(0, 100)
67
+ }
68
+ });
69
+ }
70
+ }
71
+ }
72
+ }
73
+ // Deduplicate and return
74
+ return deduplicateExtractions(extractions);
75
+ }
76
+ /**
77
+ * Get text content from a message, handling different content formats
78
+ */
79
+ function getMessageContent(msg) {
80
+ if (typeof msg.content === 'string') {
81
+ return msg.content;
82
+ }
83
+ if (Array.isArray(msg.content)) {
84
+ return msg.content
85
+ .map(c => c.text)
86
+ .filter(Boolean)
87
+ .join('\n');
88
+ }
89
+ return '';
90
+ }
91
+ /**
92
+ * Get the sentence containing the match index
93
+ */
94
+ function getSentenceAround(text, index) {
95
+ // Find sentence boundaries (., !, ?, or newlines)
96
+ const sentenceEnders = /[.!?]\s|\n\n/g;
97
+ let start = 0;
98
+ let end = text.length;
99
+ // Find start of sentence
100
+ const beforeText = text.slice(0, index);
101
+ const lastEnder = beforeText.search(/[.!?]\s[^.!?]*$/);
102
+ if (lastEnder !== -1) {
103
+ start = lastEnder + 2;
104
+ }
105
+ const lastNewline = beforeText.lastIndexOf('\n\n');
106
+ if (lastNewline > start) {
107
+ start = lastNewline + 2;
108
+ }
109
+ // Find end of sentence
110
+ const afterText = text.slice(index);
111
+ const nextEnderMatch = afterText.match(/[.!?](?:\s|$)/);
112
+ if (nextEnderMatch && nextEnderMatch.index !== undefined) {
113
+ end = index + nextEnderMatch.index + 1;
114
+ }
115
+ const nextNewline = afterText.indexOf('\n\n');
116
+ if (nextNewline !== -1 && index + nextNewline < end) {
117
+ end = index + nextNewline;
118
+ }
119
+ return text.slice(start, end).trim();
120
+ }
121
+ /**
122
+ * Check if extraction is valid (not too short, not too long, not code)
123
+ */
124
+ function isValidExtraction(sentence) {
125
+ // Too short or too long
126
+ if (sentence.length < 30 || sentence.length > 500) {
127
+ return false;
128
+ }
129
+ // Looks like code (too many special characters)
130
+ const codeIndicators = sentence.match(/[{}()\[\];=<>]/g);
131
+ if (codeIndicators && codeIndicators.length > 5) {
132
+ return false;
133
+ }
134
+ // Is a code block
135
+ if (sentence.includes('```') || sentence.startsWith(' ') || sentence.startsWith('\t')) {
136
+ return false;
137
+ }
138
+ // Is just a list item number or bullet
139
+ if (/^[\d\-*•]\s/.test(sentence) && sentence.length < 50) {
140
+ return false;
141
+ }
142
+ return true;
143
+ }
144
+ /**
145
+ * Clean up a sentence for storage
146
+ */
147
+ function cleanSentence(sentence) {
148
+ return sentence
149
+ .replace(/\s+/g, ' ') // Normalize whitespace
150
+ .replace(/^[-*•]\s*/, '') // Remove list markers
151
+ .replace(/^\d+\.\s*/, '') // Remove numbered list markers
152
+ .trim();
153
+ }
154
+ /**
155
+ * Extract entity names from text using patterns
156
+ */
157
+ function extractEntities(text, ...patterns) {
158
+ const entities = new Set();
159
+ for (const pattern of patterns) {
160
+ const p = new RegExp(pattern.source, pattern.flags);
161
+ let match;
162
+ while ((match = p.exec(text)) !== null) {
163
+ const entity = match[1];
164
+ // Filter out common false positives
165
+ if (entity && entity.length > 2 && !isCommonWord(entity)) {
166
+ entities.add(entity);
167
+ }
168
+ }
169
+ }
170
+ return [...entities];
171
+ }
172
+ /**
173
+ * Check if a word is too common to be a meaningful entity
174
+ */
175
+ function isCommonWord(word) {
176
+ const commonWords = new Set([
177
+ 'the', 'this', 'that', 'these', 'those', 'then', 'than',
178
+ 'will', 'would', 'should', 'could', 'can', 'may', 'might',
179
+ 'have', 'has', 'had', 'get', 'set', 'let', 'var', 'const',
180
+ 'function', 'class', 'def', 'return', 'true', 'false', 'null',
181
+ 'undefined', 'new', 'for', 'while', 'if', 'else', 'try', 'catch',
182
+ 'import', 'export', 'from', 'require', 'module', 'use', 'using',
183
+ 'not', 'and', 'but', 'with', 'was', 'were', 'are', 'been',
184
+ 'being', 'does', 'done', 'doing', 'did', 'make', 'made', 'making',
185
+ 'String', 'Number', 'Boolean', 'Array', 'Object', 'Date', 'Error',
186
+ 'Promise', 'Map', 'Set', 'JSON', 'Math', 'console', 'process',
187
+ ]);
188
+ return commonWords.has(word) || commonWords.has(word.toLowerCase());
189
+ }
190
+ /**
191
+ * Remove duplicate or very similar extractions
192
+ */
193
+ function deduplicateExtractions(extractions) {
194
+ const seen = new Set();
195
+ const result = [];
196
+ for (const ext of extractions) {
197
+ // Create a normalized key for comparison
198
+ const key = ext.content
199
+ .toLowerCase()
200
+ .replace(/\s+/g, ' ')
201
+ .slice(0, 80);
202
+ if (!seen.has(key)) {
203
+ seen.add(key);
204
+ result.push(ext);
205
+ }
206
+ }
207
+ return result;
208
+ }
209
+ /**
210
+ * Generate a summary of the conversation for storage
211
+ */
212
+ export function generateSummary(messages) {
213
+ const userMessages = messages
214
+ .filter(m => m.role === 'user')
215
+ .map(m => getMessageContent(m))
216
+ .filter(c => c.length > 0);
217
+ if (userMessages.length === 0) {
218
+ return 'Empty conversation';
219
+ }
220
+ // Use first user message as base for summary
221
+ const firstMessage = userMessages[0].slice(0, 200);
222
+ const topicHint = userMessages.length > 1
223
+ ? ` (${userMessages.length} exchanges)`
224
+ : '';
225
+ return `${firstMessage}${topicHint}`;
226
+ }
227
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/extractor/index.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAkBhE;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAA6B;IAC5D,MAAM,WAAW,GAAoB,EAAE,CAAC;IAExC,8DAA8D;IAC9D,MAAM,gBAAgB,GAAG;QACvB,0IAA0I;QAC1I,oHAAoH;QACpH,mEAAmE;QACnE,6EAA6E;KAC9E,CAAC;IAEF,qEAAqE;IACrE,MAAM,iBAAiB,GAAG;QACxB,sGAAsG;QACtG,wFAAwF;QACxF,4EAA4E;KAC7E,CAAC;IAEF,iDAAiD;IACjD,MAAM,YAAY,GAAG,2TAA2T,CAAC;IACjV,MAAM,eAAe,GAAG,4BAA4B,CAAC;IACrD,MAAM,aAAa,GAAG,sDAAsD,CAAC;IAC7E,MAAM,WAAW,GAAG,gEAAgE,CAAC;IAErF,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW;YAAE,SAAS;QAEvC,MAAM,OAAO,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,CAAC,OAAO;YAAE,SAAS;QAEvB,oBAAoB;QACpB,KAAK,MAAM,OAAO,IAAI,gBAAgB,EAAE,CAAC;YACvC,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,oBAAoB;YAC3C,IAAI,KAAK,CAAC;YACV,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;gBAChD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;gBACzD,IAAI,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAChC,MAAM,QAAQ,GAAG,eAAe,CAAC,QAAQ,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,CAAC,CAAC;oBACzF,WAAW,CAAC,IAAI,CAAC;wBACf,IAAI,EAAE,UAAU;wBAChB,OAAO,EAAE,aAAa,CAAC,QAAQ,CAAC;wBAChC,iBAAiB,EAAE,QAAQ;wBAC3B,QAAQ,EAAE;4BACR,WAAW,EAAE,UAAU;4BACvB,aAAa,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;yBACtC;qBACF,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,qBAAqB;QACrB,KAAK,MAAM,OAAO,IAAI,iBAAiB,EAAE,CAAC;YACxC,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;YACtB,IAAI,KAAK,CAAC;YACV,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;gBAChD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;gBACzD,IAAI,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAChC,MAAM,QAAQ,GAAG,eAAe,CAAC,QAAQ,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,CAAC,CAAC;oBACzF,WAAW,CAAC,IAAI,CAAC;wBACf,IAAI,EAAE,WAAW;wBACjB,OAAO,EAAE,aAAa,CAAC,QAAQ,CAAC;wBAChC,iBAAiB,EAAE,QAAQ;wBAC3B,QAAQ,EAAE;4BACR,WAAW,EAAE,WAAW;4BACxB,aAAa,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;yBACtC;qBACF,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,yBAAyB;IACzB,OAAO,sBAAsB,CAAC,WAAW,CAAC,CAAC;AAC7C,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,GAAsB;IAC/C,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QACpC,OAAO,GAAG,CAAC,OAAO,CAAC;IACrB,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/B,OAAO,GAAG,CAAC,OAAO;aACf,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;aAChB,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,IAAY,EAAE,KAAa;IACpD,kDAAkD;IAClD,MAAM,cAAc,GAAG,eAAe,CAAC;IAEvC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;IAEtB,yBAAyB;IACzB,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACxC,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IACvD,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE,CAAC;QACrB,KAAK,GAAG,SAAS,GAAG,CAAC,CAAC;IACxB,CAAC;IACD,MAAM,WAAW,GAAG,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACnD,IAAI,WAAW,GAAG,KAAK,EAAE,CAAC;QACxB,KAAK,GAAG,WAAW,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED,uBAAuB;IACvB,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,cAAc,GAAG,SAAS,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IACxD,IAAI,cAAc,IAAI,cAAc,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QACzD,GAAG,GAAG,KAAK,GAAG,cAAc,CAAC,KAAK,GAAG,CAAC,CAAC;IACzC,CAAC;IACD,MAAM,WAAW,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9C,IAAI,WAAW,KAAK,CAAC,CAAC,IAAI,KAAK,GAAG,WAAW,GAAG,GAAG,EAAE,CAAC;QACpD,GAAG,GAAG,KAAK,GAAG,WAAW,CAAC;IAC5B,CAAC;IAED,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,QAAgB;IACzC,wBAAwB;IACxB,IAAI,QAAQ,CAAC,MAAM,GAAG,EAAE,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QAClD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,gDAAgD;IAChD,MAAM,cAAc,GAAG,QAAQ,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACzD,IAAI,cAAc,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,kBAAkB;IAClB,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACvF,OAAO,KAAK,CAAC;IACf,CAAC;IAED,uCAAuC;IACvC,IAAI,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QACzD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CAAC,QAAgB;IACrC,OAAO,QAAQ;SACZ,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAE,uBAAuB;SAC7C,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAE,sBAAsB;SAChD,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAE,+BAA+B;SACzD,IAAI,EAAE,CAAC;AACZ,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,IAAY,EAAE,GAAG,QAAkB;IAC1D,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IAEnC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QACpD,IAAI,KAAK,CAAC;QACV,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACvC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACxB,oCAAoC;YACpC,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;gBACzD,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CAAC,IAAY;IAChC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC;QAC1B,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM;QACvD,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO;QACzD,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO;QACzD,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;QAC7D,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;QAChE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO;QAC/D,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;QACzD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ;QACjE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO;QACjE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS;KAC9D,CAAC,CAAC;IACH,OAAO,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;AACtE,CAAC;AAED;;GAEG;AACH,SAAS,sBAAsB,CAAC,WAA4B;IAC1D,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAAoB,EAAE,CAAC;IAEnC,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,yCAAyC;QACzC,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO;aACpB,WAAW,EAAE;aACb,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;aACpB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAEhB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACnB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACd,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,QAA6B;IAC3D,MAAM,YAAY,GAAG,QAAQ;SAC1B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;SAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;SAC9B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAE7B,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,oBAAoB,CAAC;IAC9B,CAAC;IAED,6CAA6C;IAC7C,MAAM,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACnD,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC;QACvC,CAAC,CAAC,KAAK,YAAY,CAAC,MAAM,aAAa;QACvC,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO,GAAG,YAAY,GAAG,SAAS,EAAE,CAAC;AACvC,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Extract decisions and context from git commit messages
3
+ */
4
+ import type { GitCommit } from './index.js';
5
+ export interface ConventionalCommit {
6
+ type: string;
7
+ scope: string | null;
8
+ breaking: boolean;
9
+ description: string;
10
+ body: string | null;
11
+ footers: Record<string, string>;
12
+ }
13
+ export interface CommitExtraction {
14
+ type: 'decision' | 'pattern' | 'rejection';
15
+ content: string;
16
+ source: 'commit';
17
+ }
18
+ /**
19
+ * Parse a conventional commit message
20
+ */
21
+ export declare function parseConventionalCommit(subject: string, body?: string): ConventionalCommit | null;
22
+ /**
23
+ * Extract decisions from a commit message
24
+ */
25
+ export declare function extractFromCommit(commit: GitCommit): CommitExtraction[];
26
+ /**
27
+ * Check if a commit message contains decision-related content
28
+ */
29
+ export declare function hasDecisionContent(commit: GitCommit): boolean;
30
+ //# sourceMappingURL=extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../../src/git/extractor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,UAAU,GAAG,SAAS,GAAG,WAAW,CAAC;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,QAAQ,CAAC;CAClB;AA2BD;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CA0BjG;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,gBAAgB,EAAE,CAmDvE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAoB7D"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Extract decisions and context from git commit messages
3
+ */
4
+ // Conventional commit regex: type(scope)!: description
5
+ const CONVENTIONAL_REGEX = /^(\w+)(?:\(([^)]+)\))?(!)?:\s*(.+)$/;
6
+ // Patterns that indicate decisions in commit messages
7
+ const DECISION_PATTERNS = [
8
+ /\bdecid(?:e|ed|ing)\s+to\b/i,
9
+ /\bchoos(?:e|ing)\s+to\b/i,
10
+ /\bswitch(?:ed|ing)?\s+(?:to|from)\b/i,
11
+ /\bmigrat(?:e|ed|ing)\s+(?:to|from)\b/i,
12
+ /\breplace(?:d|ing)?\s+.+\s+with\b/i,
13
+ /\buse\s+.+\s+instead\s+of\b/i,
14
+ /\badopt(?:ed|ing)?\b/i,
15
+ /\bimplement(?:ed|ing)?\s+.+\s+using\b/i,
16
+ ];
17
+ // Patterns that indicate rejections
18
+ const REJECTION_PATTERNS = [
19
+ /\bremov(?:e|ed|ing)\s+.+\s+(?:because|due\s+to)\b/i,
20
+ /\bdeprecate(?:d|ing)?\b/i,
21
+ /\brevert(?:ed|ing)?\b/i,
22
+ /\bdon't\s+use\b/i,
23
+ /\bavoid(?:ed|ing)?\b/i,
24
+ /\bstop(?:ped|ping)?\s+using\b/i,
25
+ ];
26
+ /**
27
+ * Parse a conventional commit message
28
+ */
29
+ export function parseConventionalCommit(subject, body) {
30
+ const match = subject.match(CONVENTIONAL_REGEX);
31
+ if (!match)
32
+ return null;
33
+ const [, type, scope, breaking, description] = match;
34
+ const footers = {};
35
+ // Parse footers from body (lines matching "Key: Value" or "Key #value")
36
+ if (body) {
37
+ const lines = body.split('\n');
38
+ for (const line of lines) {
39
+ const footerMatch = line.match(/^([\w-]+)(?::\s*|\s+#)(.+)$/);
40
+ if (footerMatch) {
41
+ footers[footerMatch[1].toLowerCase()] = footerMatch[2];
42
+ }
43
+ }
44
+ }
45
+ return {
46
+ type: type.toLowerCase(),
47
+ scope: scope || null,
48
+ breaking: !!breaking || 'breaking-change' in footers || 'breaking change' in footers,
49
+ description,
50
+ body: body || null,
51
+ footers,
52
+ };
53
+ }
54
+ /**
55
+ * Extract decisions from a commit message
56
+ */
57
+ export function extractFromCommit(commit) {
58
+ const extractions = [];
59
+ const fullMessage = `${commit.subject}\n${commit.body || ''}`;
60
+ // Check for decision patterns
61
+ for (const pattern of DECISION_PATTERNS) {
62
+ if (pattern.test(fullMessage)) {
63
+ extractions.push({
64
+ type: 'decision',
65
+ content: `[${commit.shortHash}] ${commit.subject}`,
66
+ source: 'commit',
67
+ });
68
+ break;
69
+ }
70
+ }
71
+ // Check for rejection patterns
72
+ for (const pattern of REJECTION_PATTERNS) {
73
+ if (pattern.test(fullMessage)) {
74
+ extractions.push({
75
+ type: 'rejection',
76
+ content: `[${commit.shortHash}] ${commit.subject}`,
77
+ source: 'commit',
78
+ });
79
+ break;
80
+ }
81
+ }
82
+ // Check for conventional commits with specific types
83
+ const conventional = parseConventionalCommit(commit.subject, commit.body);
84
+ if (conventional) {
85
+ // feat and refactor often represent decisions
86
+ if (['feat', 'refactor'].includes(conventional.type) && extractions.length === 0) {
87
+ extractions.push({
88
+ type: 'decision',
89
+ content: `[${commit.shortHash}] ${conventional.type}${conventional.scope ? `(${conventional.scope})` : ''}: ${conventional.description}`,
90
+ source: 'commit',
91
+ });
92
+ }
93
+ // Breaking changes are important decisions
94
+ if (conventional.breaking && !extractions.some(e => e.content.includes('BREAKING'))) {
95
+ extractions.push({
96
+ type: 'decision',
97
+ content: `[${commit.shortHash}] BREAKING: ${conventional.description}`,
98
+ source: 'commit',
99
+ });
100
+ }
101
+ }
102
+ return extractions;
103
+ }
104
+ /**
105
+ * Check if a commit message contains decision-related content
106
+ */
107
+ export function hasDecisionContent(commit) {
108
+ const fullMessage = `${commit.subject}\n${commit.body || ''}`;
109
+ // Check decision patterns
110
+ for (const pattern of DECISION_PATTERNS) {
111
+ if (pattern.test(fullMessage))
112
+ return true;
113
+ }
114
+ // Check rejection patterns
115
+ for (const pattern of REJECTION_PATTERNS) {
116
+ if (pattern.test(fullMessage))
117
+ return true;
118
+ }
119
+ // Check for conventional commit with meaningful type
120
+ const conventional = parseConventionalCommit(commit.subject);
121
+ if (conventional && ['feat', 'refactor', 'fix'].includes(conventional.type)) {
122
+ return true;
123
+ }
124
+ return false;
125
+ }
126
+ //# sourceMappingURL=extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractor.js","sourceRoot":"","sources":["../../src/git/extractor.ts"],"names":[],"mappings":"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"}