@sudosandwich/limps 0.2.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 (183) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +190 -0
  3. package/dist/agent-parser.d.ts +146 -0
  4. package/dist/agent-parser.d.ts.map +1 -0
  5. package/dist/agent-parser.js +448 -0
  6. package/dist/agent-parser.js.map +1 -0
  7. package/dist/config.d.ts +54 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +146 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/coordination.d.ts +102 -0
  12. package/dist/coordination.d.ts.map +1 -0
  13. package/dist/coordination.js +157 -0
  14. package/dist/coordination.js.map +1 -0
  15. package/dist/index.d.ts +3 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +256 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/indexer.d.ts +83 -0
  20. package/dist/indexer.d.ts.map +1 -0
  21. package/dist/indexer.js +467 -0
  22. package/dist/indexer.js.map +1 -0
  23. package/dist/resources/agents-status.d.ts +32 -0
  24. package/dist/resources/agents-status.d.ts.map +1 -0
  25. package/dist/resources/agents-status.js +73 -0
  26. package/dist/resources/agents-status.js.map +1 -0
  27. package/dist/resources/decisions-log.d.ts +21 -0
  28. package/dist/resources/decisions-log.d.ts.map +1 -0
  29. package/dist/resources/decisions-log.js +146 -0
  30. package/dist/resources/decisions-log.js.map +1 -0
  31. package/dist/resources/index.d.ts +10 -0
  32. package/dist/resources/index.d.ts.map +1 -0
  33. package/dist/resources/index.js +74 -0
  34. package/dist/resources/index.js.map +1 -0
  35. package/dist/resources/plans-full.d.ts +11 -0
  36. package/dist/resources/plans-full.d.ts.map +1 -0
  37. package/dist/resources/plans-full.js +71 -0
  38. package/dist/resources/plans-full.js.map +1 -0
  39. package/dist/resources/plans-index.d.ts +30 -0
  40. package/dist/resources/plans-index.d.ts.map +1 -0
  41. package/dist/resources/plans-index.js +177 -0
  42. package/dist/resources/plans-index.js.map +1 -0
  43. package/dist/resources/plans-summary.d.ts +33 -0
  44. package/dist/resources/plans-summary.d.ts.map +1 -0
  45. package/dist/resources/plans-summary.js +238 -0
  46. package/dist/resources/plans-summary.js.map +1 -0
  47. package/dist/rlm/extractors.d.ts +39 -0
  48. package/dist/rlm/extractors.d.ts.map +1 -0
  49. package/dist/rlm/extractors.js +291 -0
  50. package/dist/rlm/extractors.js.map +1 -0
  51. package/dist/rlm/helpers-inject.d.ts +13 -0
  52. package/dist/rlm/helpers-inject.d.ts.map +1 -0
  53. package/dist/rlm/helpers-inject.js +586 -0
  54. package/dist/rlm/helpers-inject.js.map +1 -0
  55. package/dist/rlm/helpers.d.ts +124 -0
  56. package/dist/rlm/helpers.d.ts.map +1 -0
  57. package/dist/rlm/helpers.js +381 -0
  58. package/dist/rlm/helpers.js.map +1 -0
  59. package/dist/rlm/index.d.ts +12 -0
  60. package/dist/rlm/index.d.ts.map +1 -0
  61. package/dist/rlm/index.js +19 -0
  62. package/dist/rlm/index.js.map +1 -0
  63. package/dist/rlm/parallel.d.ts +45 -0
  64. package/dist/rlm/parallel.d.ts.map +1 -0
  65. package/dist/rlm/parallel.js +76 -0
  66. package/dist/rlm/parallel.js.map +1 -0
  67. package/dist/rlm/recursion.d.ts +96 -0
  68. package/dist/rlm/recursion.d.ts.map +1 -0
  69. package/dist/rlm/recursion.js +113 -0
  70. package/dist/rlm/recursion.js.map +1 -0
  71. package/dist/rlm/sampling.d.ts +100 -0
  72. package/dist/rlm/sampling.d.ts.map +1 -0
  73. package/dist/rlm/sampling.js +96 -0
  74. package/dist/rlm/sampling.js.map +1 -0
  75. package/dist/rlm/sandbox.d.ts +73 -0
  76. package/dist/rlm/sandbox.d.ts.map +1 -0
  77. package/dist/rlm/sandbox.js +160 -0
  78. package/dist/rlm/sandbox.js.map +1 -0
  79. package/dist/rlm/security.d.ts +28 -0
  80. package/dist/rlm/security.d.ts.map +1 -0
  81. package/dist/rlm/security.js +154 -0
  82. package/dist/rlm/security.js.map +1 -0
  83. package/dist/server.d.ts +21 -0
  84. package/dist/server.d.ts.map +1 -0
  85. package/dist/server.js +107 -0
  86. package/dist/server.js.map +1 -0
  87. package/dist/task-parser.d.ts +47 -0
  88. package/dist/task-parser.d.ts.map +1 -0
  89. package/dist/task-parser.js +112 -0
  90. package/dist/task-parser.js.map +1 -0
  91. package/dist/test-setup.d.ts +6 -0
  92. package/dist/test-setup.d.ts.map +1 -0
  93. package/dist/test-setup.js +37 -0
  94. package/dist/test-setup.js.map +1 -0
  95. package/dist/tools/claim-task.d.ts +28 -0
  96. package/dist/tools/claim-task.d.ts.map +1 -0
  97. package/dist/tools/claim-task.js +288 -0
  98. package/dist/tools/claim-task.js.map +1 -0
  99. package/dist/tools/create-doc.d.ts +47 -0
  100. package/dist/tools/create-doc.d.ts.map +1 -0
  101. package/dist/tools/create-doc.js +137 -0
  102. package/dist/tools/create-doc.js.map +1 -0
  103. package/dist/tools/create-plan.d.ts +25 -0
  104. package/dist/tools/create-plan.d.ts.map +1 -0
  105. package/dist/tools/create-plan.js +179 -0
  106. package/dist/tools/create-plan.js.map +1 -0
  107. package/dist/tools/delete-doc.d.ts +51 -0
  108. package/dist/tools/delete-doc.d.ts.map +1 -0
  109. package/dist/tools/delete-doc.js +194 -0
  110. package/dist/tools/delete-doc.js.map +1 -0
  111. package/dist/tools/get-next-task.d.ts +49 -0
  112. package/dist/tools/get-next-task.d.ts.map +1 -0
  113. package/dist/tools/get-next-task.js +204 -0
  114. package/dist/tools/get-next-task.js.map +1 -0
  115. package/dist/tools/index.d.ts +10 -0
  116. package/dist/tools/index.d.ts.map +1 -0
  117. package/dist/tools/index.js +122 -0
  118. package/dist/tools/index.js.map +1 -0
  119. package/dist/tools/list-docs.d.ts +53 -0
  120. package/dist/tools/list-docs.d.ts.map +1 -0
  121. package/dist/tools/list-docs.js +236 -0
  122. package/dist/tools/list-docs.js.map +1 -0
  123. package/dist/tools/open-document-in-cursor.d.ts +62 -0
  124. package/dist/tools/open-document-in-cursor.d.ts.map +1 -0
  125. package/dist/tools/open-document-in-cursor.js +211 -0
  126. package/dist/tools/open-document-in-cursor.js.map +1 -0
  127. package/dist/tools/read-doc.d.ts +44 -0
  128. package/dist/tools/read-doc.d.ts.map +1 -0
  129. package/dist/tools/read-doc.js +174 -0
  130. package/dist/tools/read-doc.js.map +1 -0
  131. package/dist/tools/release-task.d.ts +28 -0
  132. package/dist/tools/release-task.d.ts.map +1 -0
  133. package/dist/tools/release-task.js +154 -0
  134. package/dist/tools/release-task.js.map +1 -0
  135. package/dist/tools/rlm-multi-query.d.ts +110 -0
  136. package/dist/tools/rlm-multi-query.d.ts.map +1 -0
  137. package/dist/tools/rlm-multi-query.js +348 -0
  138. package/dist/tools/rlm-multi-query.js.map +1 -0
  139. package/dist/tools/rlm-query.d.ts +56 -0
  140. package/dist/tools/rlm-query.d.ts.map +1 -0
  141. package/dist/tools/rlm-query.js +228 -0
  142. package/dist/tools/rlm-query.js.map +1 -0
  143. package/dist/tools/search-docs.d.ts +34 -0
  144. package/dist/tools/search-docs.d.ts.map +1 -0
  145. package/dist/tools/search-docs.js +292 -0
  146. package/dist/tools/search-docs.js.map +1 -0
  147. package/dist/tools/update-doc.d.ts +149 -0
  148. package/dist/tools/update-doc.d.ts.map +1 -0
  149. package/dist/tools/update-doc.js +195 -0
  150. package/dist/tools/update-doc.js.map +1 -0
  151. package/dist/tools/update-task-status.d.ts +31 -0
  152. package/dist/tools/update-task-status.d.ts.map +1 -0
  153. package/dist/tools/update-task-status.js +303 -0
  154. package/dist/tools/update-task-status.js.map +1 -0
  155. package/dist/types.d.ts +50 -0
  156. package/dist/types.d.ts.map +1 -0
  157. package/dist/types.js +2 -0
  158. package/dist/types.js.map +1 -0
  159. package/dist/utils/backup.d.ts +76 -0
  160. package/dist/utils/backup.d.ts.map +1 -0
  161. package/dist/utils/backup.js +172 -0
  162. package/dist/utils/backup.js.map +1 -0
  163. package/dist/utils/errors.d.ts +93 -0
  164. package/dist/utils/errors.d.ts.map +1 -0
  165. package/dist/utils/errors.js +125 -0
  166. package/dist/utils/errors.js.map +1 -0
  167. package/dist/utils/index.d.ts +8 -0
  168. package/dist/utils/index.d.ts.map +1 -0
  169. package/dist/utils/index.js +9 -0
  170. package/dist/utils/index.js.map +1 -0
  171. package/dist/utils/os-paths.d.ts +45 -0
  172. package/dist/utils/os-paths.d.ts.map +1 -0
  173. package/dist/utils/os-paths.js +81 -0
  174. package/dist/utils/os-paths.js.map +1 -0
  175. package/dist/utils/paths.d.ts +71 -0
  176. package/dist/utils/paths.d.ts.map +1 -0
  177. package/dist/utils/paths.js +165 -0
  178. package/dist/utils/paths.js.map +1 -0
  179. package/dist/watcher.d.ts +19 -0
  180. package/dist/watcher.d.ts.map +1 -0
  181. package/dist/watcher.js +109 -0
  182. package/dist/watcher.js.map +1 -0
  183. package/package.json +85 -0
@@ -0,0 +1,467 @@
1
+ import Database from 'better-sqlite3';
2
+ import { readFileSync, statSync, existsSync, readdirSync } from 'fs';
3
+ import { join } from 'path';
4
+ import { createHash } from 'crypto';
5
+ /**
6
+ * Initialize a SQLite database at the given path.
7
+ * Creates the database file if it doesn't exist.
8
+ *
9
+ * @param dbPath - Path to the SQLite database file
10
+ * @returns Database instance
11
+ */
12
+ export function initializeDatabase(dbPath) {
13
+ const db = new Database(dbPath);
14
+ return db;
15
+ }
16
+ /**
17
+ * Create the database schema including documents table and FTS5 virtual table.
18
+ * Must be called after initializeDatabase.
19
+ *
20
+ * @param db - Database instance
21
+ */
22
+ export function createSchema(db) {
23
+ // Create documents table first (required for FTS5 foreign key constraint)
24
+ db.exec(`
25
+ CREATE TABLE IF NOT EXISTS documents (
26
+ path TEXT PRIMARY KEY,
27
+ title TEXT NOT NULL,
28
+ content TEXT NOT NULL,
29
+ modified_at INTEGER NOT NULL,
30
+ hash TEXT NOT NULL
31
+ )
32
+ `);
33
+ // Create FTS5 virtual table for full-text search
34
+ // FTS5 has its own internal rowid - we store path as a searchable column
35
+ db.exec(`
36
+ CREATE VIRTUAL TABLE IF NOT EXISTS documents_fts USING fts5(
37
+ path,
38
+ title,
39
+ content
40
+ )
41
+ `);
42
+ }
43
+ /**
44
+ * Parse YAML frontmatter from markdown content.
45
+ * Returns parsed frontmatter and remaining content.
46
+ */
47
+ function parseYamlFrontmatter(content) {
48
+ const yamlRegex = /^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/;
49
+ const match = content.match(yamlRegex);
50
+ if (!match) {
51
+ return { frontmatter: {}, body: content };
52
+ }
53
+ const frontmatterText = match[1];
54
+ const body = match[2];
55
+ const frontmatter = {};
56
+ // Simple YAML parser for basic key-value pairs
57
+ const lines = frontmatterText.split('\n');
58
+ for (const line of lines) {
59
+ const trimmed = line.trim();
60
+ if (!trimmed || trimmed.startsWith('#'))
61
+ continue;
62
+ const colonIndex = trimmed.indexOf(':');
63
+ if (colonIndex === -1)
64
+ continue;
65
+ const key = trimmed.slice(0, colonIndex).trim();
66
+ let value = trimmed.slice(colonIndex + 1).trim();
67
+ // Remove quotes if present
68
+ if (typeof value === 'string') {
69
+ if ((value.startsWith('"') && value.endsWith('"')) ||
70
+ (value.startsWith("'") && value.endsWith("'"))) {
71
+ value = value.slice(1, -1);
72
+ }
73
+ }
74
+ // Handle arrays (simple format: - item1, - item2)
75
+ if (trimmed.includes('-')) {
76
+ const arrayMatch = trimmed.match(/^-\s*(.+)$/);
77
+ if (arrayMatch) {
78
+ const arrayKey = key || 'items';
79
+ if (!frontmatter[arrayKey] || !Array.isArray(frontmatter[arrayKey])) {
80
+ frontmatter[arrayKey] = [];
81
+ }
82
+ frontmatter[arrayKey].push(arrayMatch[1].trim().replace(/^["']|["']$/g, ''));
83
+ continue;
84
+ }
85
+ }
86
+ // Handle nested arrays (dependencies: - item1)
87
+ if (key && value && typeof value === 'string' && value.startsWith('-')) {
88
+ const arrayKey = key;
89
+ if (!frontmatter[arrayKey] || !Array.isArray(frontmatter[arrayKey])) {
90
+ frontmatter[arrayKey] = [];
91
+ }
92
+ frontmatter[arrayKey].push(value
93
+ .slice(1)
94
+ .trim()
95
+ .replace(/^["']|["']$/g, ''));
96
+ continue;
97
+ }
98
+ if (key) {
99
+ frontmatter[key] = value;
100
+ }
101
+ }
102
+ return { frontmatter, body };
103
+ }
104
+ /**
105
+ * Parse TOML frontmatter from markdown content.
106
+ * Returns parsed frontmatter and remaining content.
107
+ */
108
+ function parseTomlFrontmatter(content) {
109
+ const tomlRegex = /^\+\+\+\s*\n([\s\S]*?)\n\+\+\+\s*\n([\s\S]*)$/;
110
+ const match = content.match(tomlRegex);
111
+ if (!match) {
112
+ return { frontmatter: {}, body: content };
113
+ }
114
+ const frontmatterText = match[1];
115
+ const body = match[2];
116
+ const frontmatter = {};
117
+ // Simple TOML parser for basic key-value pairs
118
+ const lines = frontmatterText.split('\n');
119
+ for (const line of lines) {
120
+ const trimmed = line.trim();
121
+ if (!trimmed || trimmed.startsWith('#'))
122
+ continue;
123
+ const equalIndex = trimmed.indexOf('=');
124
+ if (equalIndex === -1)
125
+ continue;
126
+ const key = trimmed.slice(0, equalIndex).trim();
127
+ let value = trimmed.slice(equalIndex + 1).trim();
128
+ // Remove quotes if present
129
+ if (typeof value === 'string') {
130
+ if ((value.startsWith('"') && value.endsWith('"')) ||
131
+ (value.startsWith("'") && value.endsWith("'"))) {
132
+ value = value.slice(1, -1);
133
+ }
134
+ }
135
+ if (key) {
136
+ frontmatter[key] = value;
137
+ }
138
+ }
139
+ return { frontmatter, body };
140
+ }
141
+ /**
142
+ * Extract title from markdown content.
143
+ * Tries frontmatter first, then H1 heading.
144
+ */
145
+ function extractTitle(content, frontmatter) {
146
+ // Try frontmatter first
147
+ if (frontmatter.title && typeof frontmatter.title === 'string') {
148
+ return frontmatter.title;
149
+ }
150
+ // Extract from first H1
151
+ const h1Match = content.match(/^#\s+(.+)$/m);
152
+ if (h1Match) {
153
+ return h1Match[1].trim();
154
+ }
155
+ // Fallback to filename or default
156
+ return 'Untitled Document';
157
+ }
158
+ /**
159
+ * Extract dependencies from markdown content.
160
+ * Looks for patterns like #1, #2, feature-1, etc.
161
+ */
162
+ function extractDependencies(content, frontmatter) {
163
+ const deps = [];
164
+ // Check frontmatter
165
+ if (frontmatter.dependencies) {
166
+ if (Array.isArray(frontmatter.dependencies)) {
167
+ deps.push(...frontmatter.dependencies.map((d) => String(d)));
168
+ }
169
+ else if (typeof frontmatter.dependencies === 'string') {
170
+ deps.push(frontmatter.dependencies);
171
+ }
172
+ }
173
+ // Extract from content: #1, #2, feature-1, etc.
174
+ const featureRefRegex = /#(\d+)|feature[_-]?(\d+)|depends[_\s]+on[:\s]+([#\w\s,]+)/gi;
175
+ const matches = content.matchAll(featureRefRegex);
176
+ for (const match of matches) {
177
+ if (match[1]) {
178
+ deps.push(`#${match[1]}`);
179
+ }
180
+ else if (match[2]) {
181
+ deps.push(`feature-${match[2]}`);
182
+ }
183
+ else if (match[3]) {
184
+ const refs = match[3].split(/[,\s]+/).filter((r) => r.trim());
185
+ deps.push(...refs.map((r) => r.trim()));
186
+ }
187
+ }
188
+ // Remove duplicates
189
+ return Array.from(new Set(deps));
190
+ }
191
+ /**
192
+ * Calculate MD5 hash of content.
193
+ */
194
+ function calculateHash(content) {
195
+ return createHash('md5').update(content).digest('hex');
196
+ }
197
+ /**
198
+ * Index a single document into the database.
199
+ *
200
+ * @param db - Database instance
201
+ * @param filePath - Path to the markdown file
202
+ * @returns Document metadata
203
+ */
204
+ export async function indexDocument(db, filePath) {
205
+ if (!existsSync(filePath)) {
206
+ throw new Error(`File not found: ${filePath}`);
207
+ }
208
+ const content = readFileSync(filePath, 'utf-8');
209
+ const stats = statSync(filePath);
210
+ const modifiedAt = stats.mtimeMs;
211
+ const hash = calculateHash(content);
212
+ // Parse frontmatter (try YAML first, then TOML)
213
+ let frontmatter = {};
214
+ let body = content;
215
+ const yamlResult = parseYamlFrontmatter(content);
216
+ if (yamlResult.frontmatter && Object.keys(yamlResult.frontmatter).length > 0) {
217
+ frontmatter = yamlResult.frontmatter;
218
+ body = yamlResult.body;
219
+ }
220
+ else {
221
+ const tomlResult = parseTomlFrontmatter(content);
222
+ if (tomlResult.frontmatter && Object.keys(tomlResult.frontmatter).length > 0) {
223
+ frontmatter = tomlResult.frontmatter;
224
+ body = tomlResult.body;
225
+ }
226
+ }
227
+ // Extract metadata
228
+ const title = extractTitle(body, frontmatter);
229
+ const dependencies = extractDependencies(content, frontmatter);
230
+ const status = frontmatter.status;
231
+ const metadata = {
232
+ path: filePath,
233
+ title,
234
+ content,
235
+ status,
236
+ dependencies: dependencies.length > 0 ? dependencies : undefined,
237
+ modifiedAt,
238
+ hash,
239
+ };
240
+ // Check if document already exists
241
+ const existing = db.prepare('SELECT hash FROM documents WHERE path = ?').get(filePath);
242
+ if (existing && existing.hash === hash) {
243
+ // No change, return existing metadata
244
+ return metadata;
245
+ }
246
+ // Update or insert document
247
+ await updateDocumentIndex(db, metadata);
248
+ return metadata;
249
+ }
250
+ /**
251
+ * Update document index in database and FTS5.
252
+ *
253
+ * @param db - Database instance
254
+ * @param metadata - Document metadata
255
+ */
256
+ export async function updateDocumentIndex(db, metadata) {
257
+ const transaction = db.transaction(() => {
258
+ // Check if document exists
259
+ const existing = db.prepare('SELECT path FROM documents WHERE path = ?').get(metadata.path);
260
+ // Insert or replace in documents table
261
+ db.prepare(`
262
+ INSERT OR REPLACE INTO documents (path, title, content, modified_at, hash)
263
+ VALUES (?, ?, ?, ?, ?)
264
+ `).run(metadata.path, metadata.title, metadata.content, Math.floor(metadata.modifiedAt), metadata.hash);
265
+ // For FTS5, delete first if exists, then insert (INSERT OR REPLACE doesn't work well with FTS5)
266
+ if (existing) {
267
+ db.prepare('DELETE FROM documents_fts WHERE path = ?').run(metadata.path);
268
+ }
269
+ // Insert into FTS5 index
270
+ db.prepare(`
271
+ INSERT INTO documents_fts (path, title, content)
272
+ VALUES (?, ?, ?)
273
+ `).run(metadata.path, metadata.title, metadata.content);
274
+ });
275
+ transaction();
276
+ }
277
+ /**
278
+ * Remove document from database and FTS5 index.
279
+ *
280
+ * @param db - Database instance
281
+ * @param filePath - Path to the document
282
+ */
283
+ export async function removeDocument(db, filePath) {
284
+ const transaction = db.transaction(() => {
285
+ // Remove from documents table
286
+ db.prepare('DELETE FROM documents WHERE path = ?').run(filePath);
287
+ // Remove from FTS5 index
288
+ db.prepare('DELETE FROM documents_fts WHERE path = ?').run(filePath);
289
+ });
290
+ transaction();
291
+ }
292
+ /**
293
+ * Recursively find all files with specified extensions in a directory.
294
+ *
295
+ * @param dir - Directory to search
296
+ * @param extensions - File extensions to match (e.g., ['.md', '.jsx', '.tsx'])
297
+ * @param ignorePatterns - Patterns to ignore
298
+ * @returns Array of file paths
299
+ */
300
+ function findFiles(dir, extensions = ['.md'], ignorePatterns = []) {
301
+ const files = [];
302
+ const entries = readdirSync(dir, { withFileTypes: true });
303
+ for (const entry of entries) {
304
+ const fullPath = join(dir, entry.name);
305
+ // Check ignore patterns
306
+ const shouldIgnore = ignorePatterns.some((pattern) => {
307
+ if (pattern.includes('*')) {
308
+ const regex = new RegExp(pattern.replace(/\*/g, '.*'));
309
+ return regex.test(fullPath) || regex.test(entry.name);
310
+ }
311
+ return fullPath.includes(pattern) || entry.name.includes(pattern);
312
+ });
313
+ if (shouldIgnore) {
314
+ continue;
315
+ }
316
+ if (entry.isDirectory()) {
317
+ files.push(...findFiles(fullPath, extensions, ignorePatterns));
318
+ }
319
+ else if (entry.isFile()) {
320
+ // Check if file matches any of the extensions
321
+ const matchesExtension = extensions.some((ext) => entry.name.endsWith(ext));
322
+ if (matchesExtension) {
323
+ files.push(fullPath);
324
+ }
325
+ }
326
+ }
327
+ return files;
328
+ }
329
+ /**
330
+ * Legacy function name for backward compatibility.
331
+ * @deprecated Use findFiles instead
332
+ */
333
+ function findMarkdownFiles(dir, ignorePatterns = []) {
334
+ return findFiles(dir, ['.md'], ignorePatterns);
335
+ }
336
+ /**
337
+ * Index all documents in a directory.
338
+ *
339
+ * @param db - Database instance
340
+ * @param plansPath - Path to the plans directory
341
+ * @param ignorePatterns - Patterns to ignore (e.g., ['node_modules', '.git'])
342
+ * @returns Indexing result
343
+ */
344
+ export async function indexAllDocuments(db, plansPath, ignorePatterns = ['.git', 'node_modules', '.tmp']) {
345
+ if (!existsSync(plansPath)) {
346
+ throw new Error(`Directory not found: ${plansPath}`);
347
+ }
348
+ const result = {
349
+ indexed: 0,
350
+ updated: 0,
351
+ skipped: 0,
352
+ errors: [],
353
+ };
354
+ const files = findMarkdownFiles(plansPath, ignorePatterns);
355
+ // Process files with limited concurrency
356
+ const concurrency = 10;
357
+ for (let i = 0; i < files.length; i += concurrency) {
358
+ const batch = files.slice(i, i + concurrency);
359
+ const promises = batch.map(async (filePath) => {
360
+ try {
361
+ // Check if file exists and get current hash
362
+ if (!existsSync(filePath)) {
363
+ result.errors.push({ path: filePath, error: 'File not found' });
364
+ return;
365
+ }
366
+ const content = readFileSync(filePath, 'utf-8');
367
+ const hash = calculateHash(content);
368
+ // Check existing hash in database
369
+ const existing = db.prepare('SELECT hash FROM documents WHERE path = ?').get(filePath);
370
+ if (existing && existing.hash === hash) {
371
+ result.skipped++;
372
+ return;
373
+ }
374
+ // Determine if this is an update or new index before indexing
375
+ const wasExisting = existing !== undefined;
376
+ // Index the document
377
+ await indexDocument(db, filePath);
378
+ // Count based on whether it existed before
379
+ if (wasExisting) {
380
+ result.updated++;
381
+ }
382
+ else {
383
+ result.indexed++;
384
+ }
385
+ }
386
+ catch (error) {
387
+ result.errors.push({
388
+ path: filePath,
389
+ error: error instanceof Error ? error.message : String(error),
390
+ });
391
+ }
392
+ });
393
+ await Promise.all(promises);
394
+ }
395
+ return result;
396
+ }
397
+ /**
398
+ * Index all documents from multiple paths with configurable file extensions.
399
+ *
400
+ * @param db - Database instance
401
+ * @param paths - Array of paths to index
402
+ * @param extensions - File extensions to index (e.g., ['.md', '.jsx', '.tsx'])
403
+ * @param ignorePatterns - Patterns to ignore (e.g., ['node_modules', '.git'])
404
+ * @returns Combined indexing result
405
+ */
406
+ export async function indexAllPaths(db, paths, extensions = ['.md'], ignorePatterns = ['.git', 'node_modules', '.tmp']) {
407
+ const result = {
408
+ indexed: 0,
409
+ updated: 0,
410
+ skipped: 0,
411
+ errors: [],
412
+ };
413
+ // Collect all files from all paths
414
+ const allFiles = [];
415
+ const seenFiles = new Set();
416
+ for (const path of paths) {
417
+ if (!existsSync(path)) {
418
+ result.errors.push({ path, error: `Directory not found: ${path}` });
419
+ continue;
420
+ }
421
+ const files = findFiles(path, extensions, ignorePatterns);
422
+ for (const file of files) {
423
+ // Deduplicate files (in case paths overlap)
424
+ if (!seenFiles.has(file)) {
425
+ seenFiles.add(file);
426
+ allFiles.push(file);
427
+ }
428
+ }
429
+ }
430
+ // Process files with limited concurrency
431
+ const concurrency = 10;
432
+ for (let i = 0; i < allFiles.length; i += concurrency) {
433
+ const batch = allFiles.slice(i, i + concurrency);
434
+ const promises = batch.map(async (filePath) => {
435
+ try {
436
+ if (!existsSync(filePath)) {
437
+ result.errors.push({ path: filePath, error: 'File not found' });
438
+ return;
439
+ }
440
+ const content = readFileSync(filePath, 'utf-8');
441
+ const hash = calculateHash(content);
442
+ const existing = db.prepare('SELECT hash FROM documents WHERE path = ?').get(filePath);
443
+ if (existing && existing.hash === hash) {
444
+ result.skipped++;
445
+ return;
446
+ }
447
+ const wasExisting = existing !== undefined;
448
+ await indexDocument(db, filePath);
449
+ if (wasExisting) {
450
+ result.updated++;
451
+ }
452
+ else {
453
+ result.indexed++;
454
+ }
455
+ }
456
+ catch (error) {
457
+ result.errors.push({
458
+ path: filePath,
459
+ error: error instanceof Error ? error.message : String(error),
460
+ });
461
+ }
462
+ });
463
+ await Promise.all(promises);
464
+ }
465
+ return result;
466
+ }
467
+ //# sourceMappingURL=indexer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexer.js","sourceRoot":"","sources":["../src/indexer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { ResourceContext, ResourceResult } from '../types.js';
2
+ /**
3
+ * Agent status interface.
4
+ */
5
+ export interface AgentStatus {
6
+ id: string;
7
+ persona: 'coder' | 'reviewer' | 'pm' | 'customer';
8
+ status: 'idle' | 'WIP';
9
+ taskId?: string;
10
+ filesLocked: string[];
11
+ lastHeartbeat: string;
12
+ isStale: boolean;
13
+ }
14
+ /**
15
+ * Agents status interface.
16
+ */
17
+ export interface AgentsStatus {
18
+ agents: AgentStatus[];
19
+ totalAgents: number;
20
+ activeAgents: number;
21
+ staleAgents: number;
22
+ }
23
+ /**
24
+ * Handle agents://status resource request.
25
+ * Returns real-time status matrix of all active agents from coordination.json.
26
+ *
27
+ * @param uri - Resource URI (should be 'agents://status')
28
+ * @param context - Resource context
29
+ * @returns Resource result with agents status
30
+ */
31
+ export declare function handleAgentsStatus(uri: string, context: ResourceContext): Promise<ResourceResult>;
32
+ //# sourceMappingURL=agents-status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents-status.d.ts","sourceRoot":"","sources":["../../src/resources/agents-status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,OAAO,GAAG,UAAU,GAAG,IAAI,GAAG,UAAU,CAAC;IAClD,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAeD;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CAyDzB"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Check if heartbeat is stale (older than threshold).
3
+ */
4
+ function isStaleHeartbeat(heartbeat, thresholdMs) {
5
+ try {
6
+ const heartbeatTime = new Date(heartbeat).getTime();
7
+ const now = Date.now();
8
+ return now - heartbeatTime > thresholdMs;
9
+ }
10
+ catch {
11
+ return true; // Invalid date is considered stale
12
+ }
13
+ }
14
+ /**
15
+ * Handle agents://status resource request.
16
+ * Returns real-time status matrix of all active agents from coordination.json.
17
+ *
18
+ * @param uri - Resource URI (should be 'agents://status')
19
+ * @param context - Resource context
20
+ * @returns Resource result with agents status
21
+ */
22
+ export async function handleAgentsStatus(uri, context) {
23
+ const { coordination, config } = context;
24
+ const heartbeatTimeout = config.heartbeatTimeout || 300000; // Default 5 minutes
25
+ const agents = [];
26
+ let activeAgents = 0;
27
+ let staleAgents = 0;
28
+ // Process all agents from coordination state
29
+ for (const [agentId, agentState] of Object.entries(coordination.agents)) {
30
+ const isStale = isStaleHeartbeat(agentState.heartbeat, heartbeatTimeout);
31
+ const isActive = agentState.status === 'WIP';
32
+ if (isActive) {
33
+ activeAgents++;
34
+ }
35
+ if (isStale) {
36
+ staleAgents++;
37
+ }
38
+ agents.push({
39
+ id: agentId,
40
+ persona: agentState.persona,
41
+ status: agentState.status,
42
+ taskId: agentState.taskId,
43
+ filesLocked: agentState.filesLocked || [],
44
+ lastHeartbeat: agentState.heartbeat,
45
+ isStale,
46
+ });
47
+ }
48
+ // Sort by status (WIP first), then by heartbeat (newest first)
49
+ agents.sort((a, b) => {
50
+ if (a.status !== b.status) {
51
+ return a.status === 'WIP' ? -1 : 1;
52
+ }
53
+ const timeA = new Date(a.lastHeartbeat).getTime();
54
+ const timeB = new Date(b.lastHeartbeat).getTime();
55
+ return timeB - timeA; // Descending (newest first)
56
+ });
57
+ const status = {
58
+ agents,
59
+ totalAgents: agents.length,
60
+ activeAgents,
61
+ staleAgents,
62
+ };
63
+ return {
64
+ contents: [
65
+ {
66
+ uri,
67
+ mimeType: 'application/json',
68
+ text: JSON.stringify(status),
69
+ },
70
+ ],
71
+ };
72
+ }
73
+ //# sourceMappingURL=agents-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents-status.js","sourceRoot":"","sources":["../../src/resources/agents-status.ts"],"names":[],"mappings":"AAyBA;;GAEG;AACH,SAAS,gBAAgB,CAAC,SAAiB,EAAE,WAAmB;IAC9D,IAAI,CAAC;QACH,MAAM,aAAa,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;QACpD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,OAAO,GAAG,GAAG,aAAa,GAAG,WAAW,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC,CAAC,mCAAmC;IAClD,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,GAAW,EACX,OAAwB;IAExB,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IACzC,MAAM,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,IAAI,MAAM,CAAC,CAAC,oBAAoB;IAEhF,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,6CAA6C;IAC7C,KAAK,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;QACxE,MAAM,OAAO,GAAG,gBAAgB,CAAC,UAAU,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;QACzE,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,KAAK,KAAK,CAAC;QAE7C,IAAI,QAAQ,EAAE,CAAC;YACb,YAAY,EAAE,CAAC;QACjB,CAAC;QACD,IAAI,OAAO,EAAE,CAAC;YACZ,WAAW,EAAE,CAAC;QAChB,CAAC;QAED,MAAM,CAAC,IAAI,CAAC;YACV,EAAE,EAAE,OAAO;YACX,OAAO,EAAE,UAAU,CAAC,OAAO;YAC3B,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,WAAW,EAAE,UAAU,CAAC,WAAW,IAAI,EAAE;YACzC,aAAa,EAAE,UAAU,CAAC,SAAS;YACnC,OAAO;SACR,CAAC,CAAC;IACL,CAAC;IAED,+DAA+D;IAC/D,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACnB,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;YAC1B,OAAO,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACrC,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,OAAO,EAAE,CAAC;QAClD,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,OAAO,EAAE,CAAC;QAClD,OAAO,KAAK,GAAG,KAAK,CAAC,CAAC,4BAA4B;IACpD,CAAC,CAAC,CAAC;IAEH,MAAM,MAAM,GAAiB;QAC3B,MAAM;QACN,WAAW,EAAE,MAAM,CAAC,MAAM;QAC1B,YAAY;QACZ,WAAW;KACZ,CAAC;IAEF,OAAO;QACL,QAAQ,EAAE;YACR;gBACE,GAAG;gBACH,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;aAC7B;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { ResourceContext, ResourceResult } from '../types.js';
2
+ /**
3
+ * Decision entry interface.
4
+ */
5
+ export interface DecisionEntry {
6
+ date: string;
7
+ planId: string;
8
+ title: string;
9
+ rationale: string;
10
+ context: string;
11
+ }
12
+ /**
13
+ * Handle decisions://log resource request.
14
+ * Returns chronological decision log with rationale from planning documents.
15
+ *
16
+ * @param uri - Resource URI (should be 'decisions://log')
17
+ * @param context - Resource context
18
+ * @returns Resource result with decisions log
19
+ */
20
+ export declare function handleDecisionsLog(uri: string, context: ResourceContext): Promise<ResourceResult>;
21
+ //# sourceMappingURL=decisions-log.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decisions-log.d.ts","sourceRoot":"","sources":["../../src/resources/decisions-log.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AA4HD;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CAmDzB"}