@jafreck/lore 0.3.6 → 0.3.8

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 (206) hide show
  1. package/README.md +38 -150
  2. package/dist/cli.d.ts +2 -1
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +80 -32
  5. package/dist/cli.js.map +1 -1
  6. package/dist/db/read-only.d.ts +22 -43
  7. package/dist/db/read-only.d.ts.map +1 -1
  8. package/dist/db/read-only.js +80 -156
  9. package/dist/db/read-only.js.map +1 -1
  10. package/dist/db/schema.d.ts +9 -0
  11. package/dist/db/schema.d.ts.map +1 -1
  12. package/dist/db/schema.js +171 -85
  13. package/dist/db/schema.js.map +1 -1
  14. package/dist/discovery/poller.d.ts +6 -16
  15. package/dist/discovery/poller.d.ts.map +1 -1
  16. package/dist/discovery/poller.js +21 -52
  17. package/dist/discovery/poller.js.map +1 -1
  18. package/dist/discovery/scip-flush.d.ts +44 -0
  19. package/dist/discovery/scip-flush.d.ts.map +1 -0
  20. package/dist/discovery/scip-flush.js +67 -0
  21. package/dist/discovery/scip-flush.js.map +1 -0
  22. package/dist/discovery/watcher.d.ts +6 -16
  23. package/dist/discovery/watcher.d.ts.map +1 -1
  24. package/dist/discovery/watcher.js +22 -54
  25. package/dist/discovery/watcher.js.map +1 -1
  26. package/dist/docs/docs.d.ts +0 -2
  27. package/dist/docs/docs.d.ts.map +1 -1
  28. package/dist/docs/docs.js +0 -27
  29. package/dist/docs/docs.js.map +1 -1
  30. package/dist/embeddings/embedder.d.ts +12 -8
  31. package/dist/embeddings/embedder.d.ts.map +1 -1
  32. package/dist/embeddings/embedder.js +35 -19
  33. package/dist/embeddings/embedder.js.map +1 -1
  34. package/dist/index.d.ts +5 -2
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +3 -2
  37. package/dist/index.js.map +1 -1
  38. package/dist/indexer/index.d.ts +19 -10
  39. package/dist/indexer/index.d.ts.map +1 -1
  40. package/dist/indexer/index.js +135 -28
  41. package/dist/indexer/index.js.map +1 -1
  42. package/dist/indexer/pipeline.d.ts +44 -21
  43. package/dist/indexer/pipeline.d.ts.map +1 -1
  44. package/dist/indexer/pipeline.js +48 -26
  45. package/dist/indexer/pipeline.js.map +1 -1
  46. package/dist/indexer/stages/docs-index.d.ts +1 -3
  47. package/dist/indexer/stages/docs-index.d.ts.map +1 -1
  48. package/dist/indexer/stages/docs-index.js +1 -25
  49. package/dist/indexer/stages/docs-index.js.map +1 -1
  50. package/dist/indexer/stages/index.d.ts +4 -2
  51. package/dist/indexer/stages/index.d.ts.map +1 -1
  52. package/dist/indexer/stages/index.js +3 -2
  53. package/dist/indexer/stages/index.js.map +1 -1
  54. package/dist/indexer/stages/lsp-enrichment.d.ts +1 -1
  55. package/dist/indexer/stages/lsp-enrichment.d.ts.map +1 -1
  56. package/dist/indexer/stages/lsp-enrichment.js +44 -21
  57. package/dist/indexer/stages/lsp-enrichment.js.map +1 -1
  58. package/dist/indexer/stages/overlay-cleanup.d.ts +31 -0
  59. package/dist/indexer/stages/overlay-cleanup.d.ts.map +1 -0
  60. package/dist/indexer/stages/overlay-cleanup.js +64 -0
  61. package/dist/indexer/stages/overlay-cleanup.js.map +1 -0
  62. package/dist/indexer/stages/reverse-deps.d.ts +13 -0
  63. package/dist/indexer/stages/reverse-deps.d.ts.map +1 -0
  64. package/dist/indexer/stages/reverse-deps.js +81 -0
  65. package/dist/indexer/stages/reverse-deps.js.map +1 -0
  66. package/dist/indexer/stages/{scip-source.d.ts → scip-indexer.d.ts} +38 -9
  67. package/dist/indexer/stages/scip-indexer.d.ts.map +1 -0
  68. package/dist/indexer/stages/{scip-source.js → scip-indexer.js} +359 -98
  69. package/dist/indexer/stages/scip-indexer.js.map +1 -0
  70. package/dist/indexer/stages/source-index.d.ts +3 -3
  71. package/dist/indexer/stages/source-index.d.ts.map +1 -1
  72. package/dist/indexer/stages/source-index.js +188 -70
  73. package/dist/indexer/stages/source-index.js.map +1 -1
  74. package/dist/lsp/enrichment.d.ts.map +1 -1
  75. package/dist/lsp/enrichment.js +1 -18
  76. package/dist/lsp/enrichment.js.map +1 -1
  77. package/dist/parsing/extractors/go.d.ts.map +1 -1
  78. package/dist/parsing/extractors/go.js +0 -38
  79. package/dist/parsing/extractors/go.js.map +1 -1
  80. package/dist/parsing/extractors/javascript.d.ts.map +1 -1
  81. package/dist/parsing/extractors/javascript.js +0 -47
  82. package/dist/parsing/extractors/javascript.js.map +1 -1
  83. package/dist/parsing/extractors/python.d.ts.map +1 -1
  84. package/dist/parsing/extractors/python.js +0 -22
  85. package/dist/parsing/extractors/python.js.map +1 -1
  86. package/dist/parsing/extractors/types.d.ts +0 -16
  87. package/dist/parsing/extractors/types.d.ts.map +1 -1
  88. package/dist/parsing/extractors/types.js +1 -1
  89. package/dist/parsing/extractors/types.js.map +1 -1
  90. package/dist/parsing/extractors/typescript.d.ts.map +1 -1
  91. package/dist/parsing/extractors/typescript.js +18 -2
  92. package/dist/parsing/extractors/typescript.js.map +1 -1
  93. package/dist/resolution/call-graph.d.ts +3 -1
  94. package/dist/resolution/call-graph.d.ts.map +1 -1
  95. package/dist/resolution/call-graph.js +15 -13
  96. package/dist/resolution/call-graph.js.map +1 -1
  97. package/dist/resolution/resolution-method.d.ts +1 -1
  98. package/dist/resolution/resolution-method.d.ts.map +1 -1
  99. package/dist/resolution/resolution-method.js +2 -0
  100. package/dist/resolution/resolution-method.js.map +1 -1
  101. package/dist/resolution/resolver.d.ts +6 -0
  102. package/dist/resolution/resolver.d.ts.map +1 -1
  103. package/dist/resolution/resolver.js +21 -0
  104. package/dist/resolution/resolver.js.map +1 -1
  105. package/dist/runtime.d.ts +0 -2
  106. package/dist/runtime.d.ts.map +1 -1
  107. package/dist/runtime.js.map +1 -1
  108. package/dist/scip/compdb.d.ts +38 -0
  109. package/dist/scip/compdb.d.ts.map +1 -0
  110. package/dist/scip/compdb.js +138 -0
  111. package/dist/scip/compdb.js.map +1 -0
  112. package/dist/scip/enrichment.d.ts +6 -1
  113. package/dist/scip/enrichment.d.ts.map +1 -1
  114. package/dist/scip/enrichment.js +62 -5
  115. package/dist/scip/enrichment.js.map +1 -1
  116. package/dist/scip/installer.d.ts +59 -0
  117. package/dist/scip/installer.d.ts.map +1 -0
  118. package/dist/scip/installer.js +302 -0
  119. package/dist/scip/installer.js.map +1 -0
  120. package/dist/scip/registry.d.ts +1 -1
  121. package/dist/scip/registry.d.ts.map +1 -1
  122. package/dist/scip/registry.js +33 -5
  123. package/dist/scip/registry.js.map +1 -1
  124. package/dist/server/server.d.ts +3 -8
  125. package/dist/server/server.d.ts.map +1 -1
  126. package/dist/server/server.js +7 -66
  127. package/dist/server/server.js.map +1 -1
  128. package/dist/server/tool-registry.d.ts +2 -2
  129. package/dist/server/tool-registry.d.ts.map +1 -1
  130. package/dist/server/tool-registry.js +37 -41
  131. package/dist/server/tool-registry.js.map +1 -1
  132. package/dist/server/tools/cohesion.d.ts +46 -0
  133. package/dist/server/tools/cohesion.d.ts.map +1 -0
  134. package/dist/server/tools/cohesion.js +100 -0
  135. package/dist/server/tools/cohesion.js.map +1 -0
  136. package/dist/server/tools/dependents.d.ts +139 -0
  137. package/dist/server/tools/dependents.d.ts.map +1 -0
  138. package/dist/server/tools/dependents.js +354 -0
  139. package/dist/server/tools/dependents.js.map +1 -0
  140. package/dist/server/tools/diff.d.ts +73 -0
  141. package/dist/server/tools/diff.d.ts.map +1 -0
  142. package/dist/server/tools/diff.js +157 -0
  143. package/dist/server/tools/diff.js.map +1 -0
  144. package/dist/server/tools/graph.d.ts +7 -3
  145. package/dist/server/tools/graph.d.ts.map +1 -1
  146. package/dist/server/tools/graph.js +15 -85
  147. package/dist/server/tools/graph.js.map +1 -1
  148. package/dist/server/tools/metrics.d.ts +5 -30
  149. package/dist/server/tools/metrics.d.ts.map +1 -1
  150. package/dist/server/tools/metrics.js +21 -57
  151. package/dist/server/tools/metrics.js.map +1 -1
  152. package/dist/server/tools/structure.d.ts +77 -0
  153. package/dist/server/tools/structure.d.ts.map +1 -0
  154. package/dist/server/tools/structure.js +309 -0
  155. package/dist/server/tools/structure.js.map +1 -0
  156. package/dist/server/tools/test-map.d.ts +7 -0
  157. package/dist/server/tools/test-map.d.ts.map +1 -1
  158. package/dist/server/tools/test-map.js +18 -1
  159. package/dist/server/tools/test-map.js.map +1 -1
  160. package/dist/server/tools/trace.d.ts +84 -0
  161. package/dist/server/tools/trace.d.ts.map +1 -0
  162. package/dist/server/tools/trace.js +317 -0
  163. package/dist/server/tools/trace.js.map +1 -0
  164. package/dist/testing/coverage.d.ts +11 -0
  165. package/dist/testing/coverage.d.ts.map +1 -1
  166. package/dist/testing/coverage.js +34 -2
  167. package/dist/testing/coverage.js.map +1 -1
  168. package/dist/testing/test-mapper.d.ts +1 -1
  169. package/dist/testing/test-mapper.d.ts.map +1 -1
  170. package/dist/testing/test-mapper.js +1 -0
  171. package/dist/testing/test-mapper.js.map +1 -1
  172. package/package.json +3 -1
  173. package/dist/indexer/stages/scip-enrichment.d.ts +0 -43
  174. package/dist/indexer/stages/scip-enrichment.d.ts.map +0 -1
  175. package/dist/indexer/stages/scip-enrichment.js +0 -174
  176. package/dist/indexer/stages/scip-enrichment.js.map +0 -1
  177. package/dist/indexer/stages/scip-source.d.ts.map +0 -1
  178. package/dist/indexer/stages/scip-source.js.map +0 -1
  179. package/dist/server/tools/annotations.d.ts +0 -40
  180. package/dist/server/tools/annotations.d.ts.map +0 -1
  181. package/dist/server/tools/annotations.js +0 -35
  182. package/dist/server/tools/annotations.js.map +0 -1
  183. package/dist/server/tools/architecture.d.ts +0 -67
  184. package/dist/server/tools/architecture.d.ts.map +0 -1
  185. package/dist/server/tools/architecture.js +0 -209
  186. package/dist/server/tools/architecture.js.map +0 -1
  187. package/dist/server/tools/coverage.d.ts +0 -67
  188. package/dist/server/tools/coverage.d.ts.map +0 -1
  189. package/dist/server/tools/coverage.js +0 -74
  190. package/dist/server/tools/coverage.js.map +0 -1
  191. package/dist/server/tools/graph-analysis.d.ts +0 -64
  192. package/dist/server/tools/graph-analysis.d.ts.map +0 -1
  193. package/dist/server/tools/graph-analysis.js +0 -82
  194. package/dist/server/tools/graph-analysis.js.map +0 -1
  195. package/dist/server/tools/notes.d.ts +0 -165
  196. package/dist/server/tools/notes.d.ts.map +0 -1
  197. package/dist/server/tools/notes.js +0 -214
  198. package/dist/server/tools/notes.js.map +0 -1
  199. package/dist/server/tools/routes.d.ts +0 -38
  200. package/dist/server/tools/routes.d.ts.map +0 -1
  201. package/dist/server/tools/routes.js +0 -38
  202. package/dist/server/tools/routes.js.map +0 -1
  203. package/dist/server/tools/writeback.d.ts +0 -49
  204. package/dist/server/tools/writeback.d.ts.map +0 -1
  205. package/dist/server/tools/writeback.js +0 -68
  206. package/dist/server/tools/writeback.js.map +0 -1
@@ -1,214 +0,0 @@
1
- /**
2
- * @module lore-server/tools/notes
3
- *
4
- * MCP tools:
5
- * - lore_notes_write: upsert notes by (key, scope)
6
- * - lore_notes_read: retrieve notes with staleness/recency metadata
7
- */
8
- import Database from 'better-sqlite3';
9
- const DEFAULT_SCOPE = 'global';
10
- const DEFAULT_LIMIT = 20;
11
- const MAX_LIMIT = 200;
12
- /** Escape SQL LIKE wildcard characters (`%` and `_`) so they match literally. */
13
- function escapeLikeWildcards(value) {
14
- return value.replace(/[%_]/g, (ch) => `\\${ch}`);
15
- }
16
- export const loreNotesWriteToolDef = {
17
- name: 'lore_notes_write',
18
- description: 'Upsert an LLM-authored note in the knowledge base by key and scope. ' +
19
- 'Defaults scope to "global" and updates updated_at on existing notes.',
20
- inputSchema: {
21
- type: 'object',
22
- properties: {
23
- key: { type: 'string', description: 'Topic identifier, e.g. "architecture/overview".' },
24
- scope: {
25
- type: 'string',
26
- description: 'Optional scope (default "global"), e.g. file:<path>, module:<name>.',
27
- },
28
- content: { type: 'string', description: 'The note text.' },
29
- model: { type: 'string', description: 'Model identifier that authored the note.' },
30
- source_hash: {
31
- type: 'string',
32
- description: 'Optional source hash used for staleness detection.',
33
- },
34
- },
35
- required: ['key', 'content'],
36
- },
37
- };
38
- export const loreNotesReadToolDef = {
39
- name: 'lore_notes_read',
40
- description: 'Read notes by exact key and/or key prefix, optionally filtered by scope. ' +
41
- 'Returns staleness metadata for file-scoped notes and recency metadata for global notes.',
42
- inputSchema: {
43
- type: 'object',
44
- properties: {
45
- key: { type: 'string', description: 'Exact key match.' },
46
- key_prefix: { type: 'string', description: 'Prefix match (e.g. "architecture/").' },
47
- scope: { type: 'string', description: 'Optional scope filter.' },
48
- limit: { type: 'number', description: 'Max notes to return (default 20, max 200).' },
49
- },
50
- required: [],
51
- },
52
- };
53
- function normalizeScope(scope) {
54
- const normalized = scope?.trim();
55
- return normalized ? normalized : DEFAULT_SCOPE;
56
- }
57
- function clampLimit(limit) {
58
- if (limit == null)
59
- return DEFAULT_LIMIT;
60
- return Math.min(Math.max(1, Math.floor(limit)), MAX_LIMIT);
61
- }
62
- function parseDocScope(scope) {
63
- if (!scope.startsWith('doc:'))
64
- return null;
65
- const encoded = scope.slice('doc:'.length);
66
- const branchSeparator = encoded.lastIndexOf('@');
67
- if (branchSeparator <= 0)
68
- return null;
69
- return {
70
- path: encoded.slice(0, branchSeparator),
71
- branch: encoded.slice(branchSeparator + 1),
72
- };
73
- }
74
- export function loreNotesWriteHandler(dbPath, args) {
75
- const db = new Database(dbPath);
76
- try {
77
- db.pragma('foreign_keys = ON');
78
- const scope = normalizeScope(args.scope);
79
- const model = args.model ?? '';
80
- const sourceHash = args.source_hash ?? null;
81
- db.prepare(`INSERT INTO notes (key, scope, content, model, source_hash, created_at, updated_at)
82
- VALUES (?, ?, ?, ?, ?, unixepoch(), unixepoch())
83
- ON CONFLICT(key, scope) DO UPDATE SET
84
- content = excluded.content,
85
- model = excluded.model,
86
- source_hash = excluded.source_hash,
87
- updated_at = unixepoch()`).run(args.key, scope, args.content, model, sourceHash);
88
- const row = db
89
- .prepare('SELECT updated_at FROM notes WHERE key = ? AND scope = ?')
90
- .get(args.key, scope);
91
- return {
92
- ok: true,
93
- key: args.key,
94
- scope,
95
- updated_at: row.updated_at,
96
- };
97
- }
98
- finally {
99
- db.close();
100
- }
101
- }
102
- export function loreNotesReadHandler(db, args) {
103
- const limit = clampLimit(args.limit);
104
- const where = [];
105
- const params = [];
106
- const key = args.key?.trim();
107
- if (key) {
108
- where.push('key = ?');
109
- params.push(key);
110
- }
111
- const keyPrefix = args.key_prefix?.trim();
112
- if (keyPrefix) {
113
- where.push(`key LIKE ? ESCAPE '\\'`);
114
- params.push(`${escapeLikeWildcards(keyPrefix)}%`);
115
- }
116
- const scope = args.scope?.trim();
117
- if (scope) {
118
- where.push('scope = ?');
119
- params.push(scope);
120
- }
121
- const whereSql = where.length ? `WHERE ${where.join(' AND ')}` : '';
122
- const rows = db
123
- .prepare(`SELECT key, scope, content, model, source_hash, created_at, updated_at
124
- FROM notes
125
- ${whereSql}
126
- ORDER BY updated_at DESC, id DESC
127
- LIMIT ?`)
128
- .all(...params, limit);
129
- const loreIndexedAtRow = db
130
- .prepare('SELECT MAX(indexed_at) AS indexed_at FROM files')
131
- .get();
132
- const loreIndexedAt = loreIndexedAtRow.indexed_at;
133
- const getFileRecency = db.prepare(`SELECT last_hash, indexed_at
134
- FROM files
135
- WHERE path = ?
136
- ORDER BY indexed_at DESC
137
- LIMIT 1`);
138
- const getDocRecency = db.prepare(`SELECT content_hash, indexed_at
139
- FROM docs
140
- WHERE path = ? AND branch = ?
141
- ORDER BY indexed_at DESC
142
- LIMIT 1`);
143
- const notes = rows.map((row) => {
144
- const docScope = parseDocScope(row.scope);
145
- if (docScope) {
146
- const docRow = getDocRecency.get(docScope.path, docScope.branch);
147
- const stale = !docRow || (row.source_hash != null && row.source_hash !== docRow.content_hash);
148
- const staleReason = !docRow
149
- ? 'doc_missing'
150
- : stale
151
- ? 'source_hash_mismatch'
152
- : null;
153
- return {
154
- ...row,
155
- stale,
156
- stale_reason: staleReason,
157
- file_last_hash: null,
158
- file_indexed_at: null,
159
- lore_indexed_at: null,
160
- };
161
- }
162
- if (row.scope.startsWith('file:')) {
163
- const filePath = row.scope.slice('file:'.length);
164
- const fileRow = getFileRecency.get(filePath);
165
- let stale = false;
166
- let staleReason = null;
167
- if (!fileRow) {
168
- stale = true;
169
- staleReason = 'file_missing';
170
- }
171
- else if (row.source_hash && fileRow.last_hash && row.source_hash !== fileRow.last_hash) {
172
- stale = true;
173
- staleReason = 'source_hash_mismatch';
174
- }
175
- else if (fileRow.indexed_at > row.updated_at) {
176
- stale = true;
177
- staleReason = 'indexed_after_note';
178
- }
179
- return {
180
- ...row,
181
- stale,
182
- stale_reason: staleReason,
183
- file_last_hash: fileRow?.last_hash ?? null,
184
- file_indexed_at: fileRow?.indexed_at ?? null,
185
- lore_indexed_at: null,
186
- };
187
- }
188
- if (row.scope === DEFAULT_SCOPE) {
189
- const stale = loreIndexedAt != null ? row.updated_at < loreIndexedAt : false;
190
- return {
191
- ...row,
192
- stale,
193
- stale_reason: stale ? 'lore_reindexed_since_note' : null,
194
- file_last_hash: null,
195
- file_indexed_at: null,
196
- lore_indexed_at: loreIndexedAt,
197
- };
198
- }
199
- return {
200
- ...row,
201
- stale: false,
202
- stale_reason: null,
203
- file_last_hash: null,
204
- file_indexed_at: null,
205
- lore_indexed_at: null,
206
- };
207
- });
208
- return { notes, count: notes.length };
209
- }
210
- export const writeToolDef = loreNotesWriteToolDef;
211
- export const readToolDef = loreNotesReadToolDef;
212
- export const writeHandler = loreNotesWriteHandler;
213
- export const readHandler = loreNotesReadHandler;
214
- //# sourceMappingURL=notes.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"notes.js","sourceRoot":"","sources":["../../../src/server/tools/notes.ts"],"names":[],"mappings":"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"}
@@ -1,38 +0,0 @@
1
- /**
2
- * @module lore-server/tools/routes
3
- *
4
- * MCP tool: query extracted API routes/endpoints.
5
- */
6
- import type { Database } from '../../db/read-only.js';
7
- import { type ApiRouteRow } from '../../db/read-only.js';
8
- export declare const toolDef: {
9
- readonly name: "lore_routes";
10
- readonly description: string;
11
- readonly inputSchema: {
12
- readonly type: "object";
13
- readonly properties: {
14
- readonly method: {
15
- readonly type: "string";
16
- readonly description: "Optional HTTP method filter (for example GET, POST).";
17
- };
18
- readonly path_prefix: {
19
- readonly type: "string";
20
- readonly description: "Optional route path prefix filter.";
21
- };
22
- readonly framework: {
23
- readonly type: "string";
24
- readonly description: "Optional framework filter (for example express, fastapi, gin).";
25
- };
26
- };
27
- };
28
- };
29
- export interface RoutesArgs {
30
- method?: string;
31
- path_prefix?: string;
32
- framework?: string;
33
- }
34
- export interface RoutesResult {
35
- results: ApiRouteRow[];
36
- }
37
- export declare function handler(db: Database.Database, args: RoutesArgs): RoutesResult;
38
- //# sourceMappingURL=routes.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/server/tools/routes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAiB,KAAK,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAExE,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;CAsBV,CAAC;AAEX,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAED,wBAAgB,OAAO,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,UAAU,GAAG,YAAY,CAQ7E"}
@@ -1,38 +0,0 @@
1
- /**
2
- * @module lore-server/tools/routes
3
- *
4
- * MCP tool: query extracted API routes/endpoints.
5
- */
6
- import { listApiRoutes } from '../../db/read-only.js';
7
- export const toolDef = {
8
- name: 'lore_routes',
9
- description: 'Query extracted API routes/endpoints from the knowledge-base index. ' +
10
- 'Optional filters: `method`, `path_prefix`, and `framework`.',
11
- inputSchema: {
12
- type: 'object',
13
- properties: {
14
- method: {
15
- type: 'string',
16
- description: 'Optional HTTP method filter (for example GET, POST).',
17
- },
18
- path_prefix: {
19
- type: 'string',
20
- description: 'Optional route path prefix filter.',
21
- },
22
- framework: {
23
- type: 'string',
24
- description: 'Optional framework filter (for example express, fastapi, gin).',
25
- },
26
- },
27
- },
28
- };
29
- export function handler(db, args) {
30
- return {
31
- results: listApiRoutes(db, {
32
- method: args.method,
33
- pathPrefix: args.path_prefix,
34
- framework: args.framework,
35
- }),
36
- };
37
- }
38
- //# sourceMappingURL=routes.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../../src/server/tools/routes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,aAAa,EAAoB,MAAM,uBAAuB,CAAC;AAExE,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,IAAI,EAAE,aAAa;IACnB,WAAW,EACT,sEAAsE;QACtE,6DAA6D;IAC/D,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,sDAAsD;aACpE;YACD,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,oCAAoC;aAClD;YACD,SAAS,EAAE;gBACT,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,gEAAgE;aAC9E;SACF;KACF;CACO,CAAC;AAYX,MAAM,UAAU,OAAO,CAAC,EAAqB,EAAE,IAAgB;IAC7D,OAAO;QACL,OAAO,EAAE,aAAa,CAAC,EAAE,EAAE;YACzB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,UAAU,EAAE,IAAI,CAAC,WAAW;YAC5B,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC;KACH,CAAC;AACJ,CAAC"}
@@ -1,49 +0,0 @@
1
- /**
2
- * @module lore-server/tools/writeback
3
- *
4
- * MCP tool: write LLM-generated summaries back to the `symbol_summaries`
5
- * table. Unlike other tools this handler opens a **read-write** DB
6
- * connection so it can INSERT/REPLACE rows.
7
- */
8
- export declare const toolDef: {
9
- readonly name: "lore_writeback";
10
- readonly description: string;
11
- readonly inputSchema: {
12
- readonly type: "object";
13
- readonly properties: {
14
- readonly symbol_id: {
15
- readonly type: "number";
16
- readonly description: "The id of the symbol row to attach the summary to.";
17
- };
18
- readonly summary: {
19
- readonly type: "string";
20
- readonly description: "The natural-language summary text.";
21
- };
22
- readonly model: {
23
- readonly type: "string";
24
- readonly description: "Identifier of the LLM model that produced the summary.";
25
- };
26
- };
27
- readonly required: readonly ["symbol_id", "summary", "model"];
28
- };
29
- };
30
- export interface WritebackArgs {
31
- symbol_id: number;
32
- summary: string;
33
- model: string;
34
- branch?: string;
35
- }
36
- export interface WritebackResult {
37
- ok: boolean;
38
- symbol_id: number;
39
- }
40
- /**
41
- * Upsert a symbol summary.
42
- *
43
- * @param dbPath Absolute path to the knowledge-base SQLite file.
44
- * A **new** read-write connection is opened for each call so
45
- * this function can safely be used alongside read-only handles.
46
- * @param args Tool arguments.
47
- */
48
- export declare function handler(dbPath: string, args: WritebackArgs): WritebackResult;
49
- //# sourceMappingURL=writeback.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"writeback.d.ts","sourceRoot":"","sources":["../../../src/server/tools/writeback.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;CAwBV,CAAC;AAIX,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,eAAe,CAgC5E"}
@@ -1,68 +0,0 @@
1
- /**
2
- * @module lore-server/tools/writeback
3
- *
4
- * MCP tool: write LLM-generated summaries back to the `symbol_summaries`
5
- * table. Unlike other tools this handler opens a **read-write** DB
6
- * connection so it can INSERT/REPLACE rows.
7
- */
8
- import Database from 'better-sqlite3';
9
- // ─── Tool definition ──────────────────────────────────────────────────────────
10
- export const toolDef = {
11
- name: 'lore_writeback',
12
- description: 'Persist an LLM-generated natural-language summary for a symbol back into ' +
13
- 'the knowledge-base `symbol_summaries` table. The summary can be retrieved ' +
14
- 'later via lore_lookup.',
15
- inputSchema: {
16
- type: 'object',
17
- properties: {
18
- symbol_id: {
19
- type: 'number',
20
- description: 'The id of the symbol row to attach the summary to.',
21
- },
22
- summary: {
23
- type: 'string',
24
- description: 'The natural-language summary text.',
25
- },
26
- model: {
27
- type: 'string',
28
- description: 'Identifier of the LLM model that produced the summary.',
29
- },
30
- },
31
- required: ['symbol_id', 'summary', 'model'],
32
- },
33
- };
34
- /**
35
- * Upsert a symbol summary.
36
- *
37
- * @param dbPath Absolute path to the knowledge-base SQLite file.
38
- * A **new** read-write connection is opened for each call so
39
- * this function can safely be used alongside read-only handles.
40
- * @param args Tool arguments.
41
- */
42
- export function handler(dbPath, args) {
43
- // Open a fresh read-write connection (separate from any read-only handle).
44
- const db = new Database(dbPath);
45
- try {
46
- db.pragma('foreign_keys = ON');
47
- // When branch is supplied, verify the symbol belongs to that branch.
48
- if (args.branch !== undefined) {
49
- const row = db
50
- .prepare(`SELECT s.id FROM symbols s
51
- JOIN files f ON f.id = s.file_id
52
- WHERE s.id = ? AND f.branch = ?`)
53
- .get(args.symbol_id, args.branch);
54
- if (!row) {
55
- throw new Error(`Symbol ${args.symbol_id} not found in branch '${args.branch}'`);
56
- }
57
- }
58
- db
59
- .prepare(`INSERT OR REPLACE INTO symbol_summaries (symbol_id, summary, model, created_at)
60
- VALUES (?, ?, ?, unixepoch())`)
61
- .run(args.symbol_id, args.summary, args.model);
62
- return { ok: true, symbol_id: args.symbol_id };
63
- }
64
- finally {
65
- db.close();
66
- }
67
- }
68
- //# sourceMappingURL=writeback.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"writeback.js","sourceRoot":"","sources":["../../../src/server/tools/writeback.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC,iFAAiF;AAEjF,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,IAAI,EAAE,gBAAgB;IACtB,WAAW,EACT,2EAA2E;QAC3E,6EAA6E;QAC7E,wBAAwB;IAC1B,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,SAAS,EAAE;gBACT,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,oDAAoD;aAClE;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,oCAAoC;aAClD;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,wDAAwD;aACtE;SACF;QACD,QAAQ,EAAE,CAAC,WAAW,EAAE,SAAS,EAAE,OAAO,CAAC;KAC5C;CACO,CAAC;AAgBX;;;;;;;GAOG;AACH,MAAM,UAAU,OAAO,CAAC,MAAc,EAAE,IAAmB;IACzD,2EAA2E;IAC3E,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC;QACH,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;QAE/B,qEAAqE;QACrE,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,GAAG,GAAG,EAAE;iBACX,OAAO,CACN;;4CAEkC,CACnC;iBACA,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YACpC,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,MAAM,IAAI,KAAK,CACb,UAAU,IAAI,CAAC,SAAS,yBAAyB,IAAI,CAAC,MAAM,GAAG,CAChE,CAAC;YACJ,CAAC;QACH,CAAC;QAED,EAAE;aACC,OAAO,CACN;uCAC+B,CAChC;aACA,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QACjD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;IACjD,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC"}