@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.
- package/LICENSE +21 -0
- package/README.md +190 -0
- package/dist/agent-parser.d.ts +146 -0
- package/dist/agent-parser.d.ts.map +1 -0
- package/dist/agent-parser.js +448 -0
- package/dist/agent-parser.js.map +1 -0
- package/dist/config.d.ts +54 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +146 -0
- package/dist/config.js.map +1 -0
- package/dist/coordination.d.ts +102 -0
- package/dist/coordination.d.ts.map +1 -0
- package/dist/coordination.js +157 -0
- package/dist/coordination.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +256 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer.d.ts +83 -0
- package/dist/indexer.d.ts.map +1 -0
- package/dist/indexer.js +467 -0
- package/dist/indexer.js.map +1 -0
- package/dist/resources/agents-status.d.ts +32 -0
- package/dist/resources/agents-status.d.ts.map +1 -0
- package/dist/resources/agents-status.js +73 -0
- package/dist/resources/agents-status.js.map +1 -0
- package/dist/resources/decisions-log.d.ts +21 -0
- package/dist/resources/decisions-log.d.ts.map +1 -0
- package/dist/resources/decisions-log.js +146 -0
- package/dist/resources/decisions-log.js.map +1 -0
- package/dist/resources/index.d.ts +10 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +74 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/resources/plans-full.d.ts +11 -0
- package/dist/resources/plans-full.d.ts.map +1 -0
- package/dist/resources/plans-full.js +71 -0
- package/dist/resources/plans-full.js.map +1 -0
- package/dist/resources/plans-index.d.ts +30 -0
- package/dist/resources/plans-index.d.ts.map +1 -0
- package/dist/resources/plans-index.js +177 -0
- package/dist/resources/plans-index.js.map +1 -0
- package/dist/resources/plans-summary.d.ts +33 -0
- package/dist/resources/plans-summary.d.ts.map +1 -0
- package/dist/resources/plans-summary.js +238 -0
- package/dist/resources/plans-summary.js.map +1 -0
- package/dist/rlm/extractors.d.ts +39 -0
- package/dist/rlm/extractors.d.ts.map +1 -0
- package/dist/rlm/extractors.js +291 -0
- package/dist/rlm/extractors.js.map +1 -0
- package/dist/rlm/helpers-inject.d.ts +13 -0
- package/dist/rlm/helpers-inject.d.ts.map +1 -0
- package/dist/rlm/helpers-inject.js +586 -0
- package/dist/rlm/helpers-inject.js.map +1 -0
- package/dist/rlm/helpers.d.ts +124 -0
- package/dist/rlm/helpers.d.ts.map +1 -0
- package/dist/rlm/helpers.js +381 -0
- package/dist/rlm/helpers.js.map +1 -0
- package/dist/rlm/index.d.ts +12 -0
- package/dist/rlm/index.d.ts.map +1 -0
- package/dist/rlm/index.js +19 -0
- package/dist/rlm/index.js.map +1 -0
- package/dist/rlm/parallel.d.ts +45 -0
- package/dist/rlm/parallel.d.ts.map +1 -0
- package/dist/rlm/parallel.js +76 -0
- package/dist/rlm/parallel.js.map +1 -0
- package/dist/rlm/recursion.d.ts +96 -0
- package/dist/rlm/recursion.d.ts.map +1 -0
- package/dist/rlm/recursion.js +113 -0
- package/dist/rlm/recursion.js.map +1 -0
- package/dist/rlm/sampling.d.ts +100 -0
- package/dist/rlm/sampling.d.ts.map +1 -0
- package/dist/rlm/sampling.js +96 -0
- package/dist/rlm/sampling.js.map +1 -0
- package/dist/rlm/sandbox.d.ts +73 -0
- package/dist/rlm/sandbox.d.ts.map +1 -0
- package/dist/rlm/sandbox.js +160 -0
- package/dist/rlm/sandbox.js.map +1 -0
- package/dist/rlm/security.d.ts +28 -0
- package/dist/rlm/security.d.ts.map +1 -0
- package/dist/rlm/security.js +154 -0
- package/dist/rlm/security.js.map +1 -0
- package/dist/server.d.ts +21 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +107 -0
- package/dist/server.js.map +1 -0
- package/dist/task-parser.d.ts +47 -0
- package/dist/task-parser.d.ts.map +1 -0
- package/dist/task-parser.js +112 -0
- package/dist/task-parser.js.map +1 -0
- package/dist/test-setup.d.ts +6 -0
- package/dist/test-setup.d.ts.map +1 -0
- package/dist/test-setup.js +37 -0
- package/dist/test-setup.js.map +1 -0
- package/dist/tools/claim-task.d.ts +28 -0
- package/dist/tools/claim-task.d.ts.map +1 -0
- package/dist/tools/claim-task.js +288 -0
- package/dist/tools/claim-task.js.map +1 -0
- package/dist/tools/create-doc.d.ts +47 -0
- package/dist/tools/create-doc.d.ts.map +1 -0
- package/dist/tools/create-doc.js +137 -0
- package/dist/tools/create-doc.js.map +1 -0
- package/dist/tools/create-plan.d.ts +25 -0
- package/dist/tools/create-plan.d.ts.map +1 -0
- package/dist/tools/create-plan.js +179 -0
- package/dist/tools/create-plan.js.map +1 -0
- package/dist/tools/delete-doc.d.ts +51 -0
- package/dist/tools/delete-doc.d.ts.map +1 -0
- package/dist/tools/delete-doc.js +194 -0
- package/dist/tools/delete-doc.js.map +1 -0
- package/dist/tools/get-next-task.d.ts +49 -0
- package/dist/tools/get-next-task.d.ts.map +1 -0
- package/dist/tools/get-next-task.js +204 -0
- package/dist/tools/get-next-task.js.map +1 -0
- package/dist/tools/index.d.ts +10 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +122 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/list-docs.d.ts +53 -0
- package/dist/tools/list-docs.d.ts.map +1 -0
- package/dist/tools/list-docs.js +236 -0
- package/dist/tools/list-docs.js.map +1 -0
- package/dist/tools/open-document-in-cursor.d.ts +62 -0
- package/dist/tools/open-document-in-cursor.d.ts.map +1 -0
- package/dist/tools/open-document-in-cursor.js +211 -0
- package/dist/tools/open-document-in-cursor.js.map +1 -0
- package/dist/tools/read-doc.d.ts +44 -0
- package/dist/tools/read-doc.d.ts.map +1 -0
- package/dist/tools/read-doc.js +174 -0
- package/dist/tools/read-doc.js.map +1 -0
- package/dist/tools/release-task.d.ts +28 -0
- package/dist/tools/release-task.d.ts.map +1 -0
- package/dist/tools/release-task.js +154 -0
- package/dist/tools/release-task.js.map +1 -0
- package/dist/tools/rlm-multi-query.d.ts +110 -0
- package/dist/tools/rlm-multi-query.d.ts.map +1 -0
- package/dist/tools/rlm-multi-query.js +348 -0
- package/dist/tools/rlm-multi-query.js.map +1 -0
- package/dist/tools/rlm-query.d.ts +56 -0
- package/dist/tools/rlm-query.d.ts.map +1 -0
- package/dist/tools/rlm-query.js +228 -0
- package/dist/tools/rlm-query.js.map +1 -0
- package/dist/tools/search-docs.d.ts +34 -0
- package/dist/tools/search-docs.d.ts.map +1 -0
- package/dist/tools/search-docs.js +292 -0
- package/dist/tools/search-docs.js.map +1 -0
- package/dist/tools/update-doc.d.ts +149 -0
- package/dist/tools/update-doc.d.ts.map +1 -0
- package/dist/tools/update-doc.js +195 -0
- package/dist/tools/update-doc.js.map +1 -0
- package/dist/tools/update-task-status.d.ts +31 -0
- package/dist/tools/update-task-status.d.ts.map +1 -0
- package/dist/tools/update-task-status.js +303 -0
- package/dist/tools/update-task-status.js.map +1 -0
- package/dist/types.d.ts +50 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/backup.d.ts +76 -0
- package/dist/utils/backup.d.ts.map +1 -0
- package/dist/utils/backup.js +172 -0
- package/dist/utils/backup.js.map +1 -0
- package/dist/utils/errors.d.ts +93 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +125 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +9 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/os-paths.d.ts +45 -0
- package/dist/utils/os-paths.d.ts.map +1 -0
- package/dist/utils/os-paths.js +81 -0
- package/dist/utils/os-paths.js.map +1 -0
- package/dist/utils/paths.d.ts +71 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +165 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/watcher.d.ts +19 -0
- package/dist/watcher.d.ts.map +1 -0
- package/dist/watcher.js +109 -0
- package/dist/watcher.js.map +1 -0
- package/package.json +85 -0
package/dist/indexer.js
ADDED
|
@@ -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":"AAAA,OAAO,QAA2C,MAAM,gBAAgB,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,IAAI,CAAC;AACrE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AA0BpC;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;IAChC,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,EAAgB;IAC3C,0EAA0E;IAC1E,EAAE,CAAC,IAAI,CAAC;;;;;;;;GAQP,CAAC,CAAC;IAEH,iDAAiD;IACjD,yEAAyE;IACzE,EAAE,CAAC,IAAI,CAAC;;;;;;GAMP,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,SAAS,oBAAoB,CAAC,OAAe;IAI3C,MAAM,SAAS,GAAG,yCAAyC,CAAC;IAC5D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAEvC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC5C,CAAC;IAED,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACtB,MAAM,WAAW,GAA4B,EAAE,CAAC;IAEhD,+CAA+C;IAC/C,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAElD,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,UAAU,KAAK,CAAC,CAAC;YAAE,SAAS;QAEhC,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;QAChD,IAAI,KAAK,GAAY,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAE1D,2BAA2B;QAC3B,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,IACE,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;gBAC9C,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAC9C,CAAC;gBACD,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,kDAAkD;QAClD,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAC/C,IAAI,UAAU,EAAE,CAAC;gBACf,MAAM,QAAQ,GAAG,GAAG,IAAI,OAAO,CAAC;gBAChC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;oBACpE,WAAW,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;gBAC7B,CAAC;gBACA,WAAW,CAAC,QAAQ,CAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,CAAC;gBAC5F,SAAS;YACX,CAAC;QACH,CAAC;QAED,+CAA+C;QAC/C,IAAI,GAAG,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACvE,MAAM,QAAQ,GAAG,GAAG,CAAC;YACrB,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;gBACpE,WAAW,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;YAC7B,CAAC;YACA,WAAW,CAAC,QAAQ,CAAe,CAAC,IAAI,CACvC,KAAK;iBACF,KAAK,CAAC,CAAC,CAAC;iBACR,IAAI,EAAE;iBACN,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAC/B,CAAC;YACF,SAAS;QACX,CAAC;QAED,IAAI,GAAG,EAAE,CAAC;YACR,WAAW,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;AAC/B,CAAC;AAED;;;GAGG;AACH,SAAS,oBAAoB,CAAC,OAAe;IAI3C,MAAM,SAAS,GAAG,+CAA+C,CAAC;IAClE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAEvC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC5C,CAAC;IAED,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACtB,MAAM,WAAW,GAA4B,EAAE,CAAC;IAEhD,+CAA+C;IAC/C,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAElD,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,UAAU,KAAK,CAAC,CAAC;YAAE,SAAS;QAEhC,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;QAChD,IAAI,KAAK,GAAY,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAE1D,2BAA2B;QAC3B,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,IACE,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;gBAC9C,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAC9C,CAAC;gBACD,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,IAAI,GAAG,EAAE,CAAC;YACR,WAAW,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;AAC/B,CAAC;AAED;;;GAGG;AACH,SAAS,YAAY,CAAC,OAAe,EAAE,WAAoC;IACzE,wBAAwB;IACxB,IAAI,WAAW,CAAC,KAAK,IAAI,OAAO,WAAW,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC/D,OAAO,WAAW,CAAC,KAAK,CAAC;IAC3B,CAAC;IAED,wBAAwB;IACxB,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IAC7C,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED,kCAAkC;IAClC,OAAO,mBAAmB,CAAC;AAC7B,CAAC;AAED;;;GAGG;AACH,SAAS,mBAAmB,CAAC,OAAe,EAAE,WAAoC;IAChF,MAAM,IAAI,GAAa,EAAE,CAAC;IAE1B,oBAAoB;IACpB,IAAI,WAAW,CAAC,YAAY,EAAE,CAAC;QAC7B,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE,CAAC;YAC5C,IAAI,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/D,CAAC;aAAM,IAAI,OAAO,WAAW,CAAC,YAAY,KAAK,QAAQ,EAAE,CAAC;YACxD,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAED,gDAAgD;IAChD,MAAM,eAAe,GAAG,6DAA6D,CAAC;IACtF,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;IAElD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACb,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC5B,CAAC;aAAM,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACpB,IAAI,CAAC,IAAI,CAAC,WAAW,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACnC,CAAC;aAAM,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACpB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YAC9D,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IAED,oBAAoB;IACpB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CAAC,OAAe;IACpC,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACzD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,EAAgB,EAAE,QAAgB;IACpE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACjC,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC;IACjC,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IAEpC,gDAAgD;IAChD,IAAI,WAAW,GAA4B,EAAE,CAAC;IAC9C,IAAI,IAAI,GAAG,OAAO,CAAC;IAEnB,MAAM,UAAU,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IACjD,IAAI,UAAU,CAAC,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7E,WAAW,GAAG,UAAU,CAAC,WAAW,CAAC;QACrC,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC;IACzB,CAAC;SAAM,CAAC;QACN,MAAM,UAAU,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;QACjD,IAAI,UAAU,CAAC,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7E,WAAW,GAAG,UAAU,CAAC,WAAW,CAAC;YACrC,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC;QACzB,CAAC;IACH,CAAC;IAED,mBAAmB;IACnB,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAC9C,MAAM,YAAY,GAAG,mBAAmB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAC/D,MAAM,MAAM,GAAG,WAAW,CAAC,MAAoE,CAAC;IAEhG,MAAM,QAAQ,GAAqB;QACjC,IAAI,EAAE,QAAQ;QACd,KAAK;QACL,OAAO;QACP,MAAM;QACN,YAAY,EAAE,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS;QAChE,UAAU;QACV,IAAI;KACL,CAAC;IAEF,mCAAmC;IACnC,MAAM,QAAQ,GAAG,EAAE,CAAC,OAAO,CAAC,2CAA2C,CAAC,CAAC,GAAG,CAAC,QAAQ,CAIxE,CAAC;IAEd,IAAI,QAAQ,IAAI,QAAQ,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;QACvC,sCAAsC;QACtC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,4BAA4B;IAC5B,MAAM,mBAAmB,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;IAExC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,EAAgB,EAChB,QAA0B;IAE1B,MAAM,WAAW,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;QACtC,2BAA2B;QAC3B,MAAM,QAAQ,GAAG,EAAE,CAAC,OAAO,CAAC,2CAA2C,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAE5F,uCAAuC;QACvC,EAAE,CAAC,OAAO,CACR;;;KAGD,CACA,CAAC,GAAG,CACH,QAAQ,CAAC,IAAI,EACb,QAAQ,CAAC,KAAK,EACd,QAAQ,CAAC,OAAO,EAChB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,EAC/B,QAAQ,CAAC,IAAI,CACd,CAAC;QAEF,gGAAgG;QAChG,IAAI,QAAQ,EAAE,CAAC;YACb,EAAE,CAAC,OAAO,CAAC,0CAA0C,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5E,CAAC;QAED,yBAAyB;QACzB,EAAE,CAAC,OAAO,CACR;;;KAGD,CACA,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,WAAW,EAAE,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,EAAgB,EAAE,QAAgB;IACrE,MAAM,WAAW,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;QACtC,8BAA8B;QAC9B,EAAE,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAEjE,yBAAyB;QACzB,EAAE,CAAC,OAAO,CAAC,0CAA0C,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,WAAW,EAAE,CAAC;AAChB,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,SAAS,CAChB,GAAW,EACX,aAAuB,CAAC,KAAK,CAAC,EAC9B,iBAA2B,EAAE;IAE7B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAE1D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAEvC,wBAAwB;QACxB,MAAM,YAAY,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;YACnD,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC1B,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;gBACvD,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACxD,CAAC;YACD,OAAO,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;QAEH,IAAI,YAAY,EAAE,CAAC;YACjB,SAAS;QACX,CAAC;QAED,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,QAAQ,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC,CAAC;QACjE,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1B,8CAA8C;YAC9C,MAAM,gBAAgB,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;YAC5E,IAAI,gBAAgB,EAAE,CAAC;gBACrB,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB,CAAC,GAAW,EAAE,iBAA2B,EAAE;IACnE,OAAO,SAAS,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC,CAAC;AACjD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,EAAgB,EAChB,SAAiB,EACjB,iBAA2B,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,CAAC;IAE3D,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,wBAAwB,SAAS,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,MAAM,GAAmB;QAC7B,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,EAAE;KACX,CAAC;IAEF,MAAM,KAAK,GAAG,iBAAiB,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IAE3D,yCAAyC;IACzC,MAAM,WAAW,GAAG,EAAE,CAAC;IACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,WAAW,EAAE,CAAC;QACnD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC;QAC9C,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;YAC5C,IAAI,CAAC;gBACH,4CAA4C;gBAC5C,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC1B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;oBAChE,OAAO;gBACT,CAAC;gBAED,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBAChD,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;gBAEpC,kCAAkC;gBAClC,MAAM,QAAQ,GAAG,EAAE,CAAC,OAAO,CAAC,2CAA2C,CAAC,CAAC,GAAG,CAAC,QAAQ,CAIxE,CAAC;gBAEd,IAAI,QAAQ,IAAI,QAAQ,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;oBACvC,MAAM,CAAC,OAAO,EAAE,CAAC;oBACjB,OAAO;gBACT,CAAC;gBAED,8DAA8D;gBAC9D,MAAM,WAAW,GAAG,QAAQ,KAAK,SAAS,CAAC;gBAE3C,qBAAqB;gBACrB,MAAM,aAAa,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;gBAElC,2CAA2C;gBAC3C,IAAI,WAAW,EAAE,CAAC;oBAChB,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;oBACjB,IAAI,EAAE,QAAQ;oBACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAC9D,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,EAAgB,EAChB,KAAe,EACf,aAAuB,CAAC,KAAK,CAAC,EAC9B,iBAA2B,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,CAAC;IAE3D,MAAM,MAAM,GAAmB;QAC7B,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,EAAE;KACX,CAAC;IAEF,mCAAmC;IACnC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IAEpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACtB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,wBAAwB,IAAI,EAAE,EAAE,CAAC,CAAC;YACpE,SAAS;QACX,CAAC;QAED,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC;QAC1D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,4CAA4C;YAC5C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzB,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACpB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;IACH,CAAC;IAED,yCAAyC;IACzC,MAAM,WAAW,GAAG,EAAE,CAAC;IACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,WAAW,EAAE,CAAC;QACtD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC;QACjD,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;YAC5C,IAAI,CAAC;gBACH,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC1B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;oBAChE,OAAO;gBACT,CAAC;gBAED,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBAChD,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;gBAEpC,MAAM,QAAQ,GAAG,EAAE,CAAC,OAAO,CAAC,2CAA2C,CAAC,CAAC,GAAG,CAAC,QAAQ,CAIxE,CAAC;gBAEd,IAAI,QAAQ,IAAI,QAAQ,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;oBACvC,MAAM,CAAC,OAAO,EAAE,CAAC;oBACjB,OAAO;gBACT,CAAC;gBAED,MAAM,WAAW,GAAG,QAAQ,KAAK,SAAS,CAAC;gBAC3C,MAAM,aAAa,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;gBAElC,IAAI,WAAW,EAAE,CAAC;oBAChB,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;oBACjB,IAAI,EAAE,QAAQ;oBACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAC9D,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -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"}
|