agent-knowledge 1.0.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/CHANGELOG.md +77 -0
- package/LICENSE +21 -0
- package/README.md +191 -0
- package/dist/dashboard.d.ts +4 -0
- package/dist/dashboard.d.ts.map +1 -0
- package/dist/dashboard.js +434 -0
- package/dist/dashboard.js.map +1 -0
- package/dist/embeddings/claude.d.ts +21 -0
- package/dist/embeddings/claude.d.ts.map +1 -0
- package/dist/embeddings/claude.js +84 -0
- package/dist/embeddings/claude.js.map +1 -0
- package/dist/embeddings/factory.d.ts +9 -0
- package/dist/embeddings/factory.d.ts.map +1 -0
- package/dist/embeddings/factory.js +60 -0
- package/dist/embeddings/factory.js.map +1 -0
- package/dist/embeddings/gemini.d.ts +21 -0
- package/dist/embeddings/gemini.d.ts.map +1 -0
- package/dist/embeddings/gemini.js +86 -0
- package/dist/embeddings/gemini.js.map +1 -0
- package/dist/embeddings/index.d.ts +4 -0
- package/dist/embeddings/index.d.ts.map +1 -0
- package/dist/embeddings/index.js +3 -0
- package/dist/embeddings/index.js.map +1 -0
- package/dist/embeddings/local.d.ts +20 -0
- package/dist/embeddings/local.d.ts.map +1 -0
- package/dist/embeddings/local.js +73 -0
- package/dist/embeddings/local.js.map +1 -0
- package/dist/embeddings/openai.d.ts +20 -0
- package/dist/embeddings/openai.d.ts.map +1 -0
- package/dist/embeddings/openai.js +84 -0
- package/dist/embeddings/openai.js.map +1 -0
- package/dist/embeddings/types.d.ts +39 -0
- package/dist/embeddings/types.d.ts.map +1 -0
- package/dist/embeddings/types.js +12 -0
- package/dist/embeddings/types.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/knowledge/distill.d.ts +27 -0
- package/dist/knowledge/distill.d.ts.map +1 -0
- package/dist/knowledge/distill.js +407 -0
- package/dist/knowledge/distill.js.map +1 -0
- package/dist/knowledge/git.d.ts +30 -0
- package/dist/knowledge/git.d.ts.map +1 -0
- package/dist/knowledge/git.js +228 -0
- package/dist/knowledge/git.js.map +1 -0
- package/dist/knowledge/search.d.ts +20 -0
- package/dist/knowledge/search.d.ts.map +1 -0
- package/dist/knowledge/search.js +72 -0
- package/dist/knowledge/search.js.map +1 -0
- package/dist/knowledge/store.d.ts +47 -0
- package/dist/knowledge/store.d.ts.map +1 -0
- package/dist/knowledge/store.js +173 -0
- package/dist/knowledge/store.js.map +1 -0
- package/dist/search/excerpt.d.ts +12 -0
- package/dist/search/excerpt.d.ts.map +1 -0
- package/dist/search/excerpt.js +28 -0
- package/dist/search/excerpt.js.map +1 -0
- package/dist/search/fuzzy.d.ts +15 -0
- package/dist/search/fuzzy.d.ts.map +1 -0
- package/dist/search/fuzzy.js +81 -0
- package/dist/search/fuzzy.js.map +1 -0
- package/dist/search/tfidf.d.ts +19 -0
- package/dist/search/tfidf.d.ts.map +1 -0
- package/dist/search/tfidf.js +200 -0
- package/dist/search/tfidf.js.map +1 -0
- package/dist/search/types.d.ts +19 -0
- package/dist/search/types.d.ts.map +1 -0
- package/dist/search/types.js +2 -0
- package/dist/search/types.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +518 -0
- package/dist/server.js.map +1 -0
- package/dist/sessions/indexer.d.ts +15 -0
- package/dist/sessions/indexer.d.ts.map +1 -0
- package/dist/sessions/indexer.js +182 -0
- package/dist/sessions/indexer.js.map +1 -0
- package/dist/sessions/parser.d.ts +58 -0
- package/dist/sessions/parser.d.ts.map +1 -0
- package/dist/sessions/parser.js +142 -0
- package/dist/sessions/parser.js.map +1 -0
- package/dist/sessions/scopes.d.ts +16 -0
- package/dist/sessions/scopes.d.ts.map +1 -0
- package/dist/sessions/scopes.js +153 -0
- package/dist/sessions/scopes.js.map +1 -0
- package/dist/sessions/search.d.ts +26 -0
- package/dist/sessions/search.d.ts.map +1 -0
- package/dist/sessions/search.js +256 -0
- package/dist/sessions/search.js.map +1 -0
- package/dist/sessions/summary.d.ts +28 -0
- package/dist/sessions/summary.d.ts.map +1 -0
- package/dist/sessions/summary.js +135 -0
- package/dist/sessions/summary.js.map +1 -0
- package/dist/types.d.ts +26 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +109 -0
- package/dist/types.js.map +1 -0
- package/dist/ui/app.js +1029 -0
- package/dist/ui/index.html +373 -0
- package/dist/ui/styles.css +1508 -0
- package/dist/ui/ui/app.js +811 -0
- package/dist/ui/ui/index.html +300 -0
- package/dist/ui/ui/styles.css +1154 -0
- package/dist/validate.d.ts +21 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +86 -0
- package/dist/validate.js.map +1 -0
- package/dist/vectorstore/chunker.d.ts +48 -0
- package/dist/vectorstore/chunker.d.ts.map +1 -0
- package/dist/vectorstore/chunker.js +165 -0
- package/dist/vectorstore/chunker.js.map +1 -0
- package/dist/vectorstore/index.d.ts +5 -0
- package/dist/vectorstore/index.d.ts.map +1 -0
- package/dist/vectorstore/index.js +3 -0
- package/dist/vectorstore/index.js.map +1 -0
- package/dist/vectorstore/store.d.ts +139 -0
- package/dist/vectorstore/store.d.ts.map +1 -0
- package/dist/vectorstore/store.js +500 -0
- package/dist/vectorstore/store.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/docs/ARCHITECTURE.md +244 -0
- package/docs/DASHBOARD.md +133 -0
- package/docs/SETUP.md +178 -0
- package/package.json +92 -0
- package/scripts/copy-ui.js +6 -0
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { TfIdfIndex, recencyDecay } from '../search/tfidf.js';
|
|
2
|
+
import { buildExcerpt } from '../search/excerpt.js';
|
|
3
|
+
import { getProjectDirs, getSessionFiles, parseSessionFile, extractMessages, getSessionMeta, } from './parser.js';
|
|
4
|
+
import { getEmbeddingProvider } from '../embeddings/index.js';
|
|
5
|
+
import { VectorStore } from '../vectorstore/index.js';
|
|
6
|
+
import { getConfig } from '../types.js';
|
|
7
|
+
// ── Lazy VectorStore singleton ──────────────────────────────────────────────
|
|
8
|
+
let _vectorStore = null;
|
|
9
|
+
function getVectorStore() {
|
|
10
|
+
if (!_vectorStore) {
|
|
11
|
+
_vectorStore = new VectorStore();
|
|
12
|
+
}
|
|
13
|
+
return _vectorStore;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Search across all session transcripts.
|
|
17
|
+
*
|
|
18
|
+
* Supports three modes:
|
|
19
|
+
* - **hybrid** (default when embeddings available): blends TF-IDF ranking
|
|
20
|
+
* with semantic vector similarity using configurable alpha weighting.
|
|
21
|
+
* - **ranked** (default fallback): builds a TF-IDF index over all messages,
|
|
22
|
+
* returns results ordered by relevance score.
|
|
23
|
+
* - **legacy** (`ranked: false`): regex-based matching, faster for exact
|
|
24
|
+
* phrases and pattern searches.
|
|
25
|
+
*
|
|
26
|
+
* Returns results with excerpts (100 chars before + 100 chars after match).
|
|
27
|
+
*/
|
|
28
|
+
export async function searchSessions(query, options = {}) {
|
|
29
|
+
const { project, role = 'all', caseSensitive = false, maxResults = 20, ranked = true, semantic = true, } = options;
|
|
30
|
+
const projects = getProjectDirs().filter((p) => !project || p.name.toLowerCase().includes(project.toLowerCase()));
|
|
31
|
+
if (!ranked) {
|
|
32
|
+
return regexSearch(query, projects, role, caseSensitive, maxResults);
|
|
33
|
+
}
|
|
34
|
+
const tfidfResults = rankedSearch(query, projects, role, maxResults);
|
|
35
|
+
if (semantic) {
|
|
36
|
+
try {
|
|
37
|
+
const config = getConfig();
|
|
38
|
+
const hybridResults = await hybridSearch(query, tfidfResults, maxResults, config.embeddingAlpha);
|
|
39
|
+
return hybridResults;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// Semantic failed silently — fall back to pure TF-IDF
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return tfidfResults;
|
|
46
|
+
}
|
|
47
|
+
// ── Hybrid search (TF-IDF + semantic) ───────────────────────────────────────
|
|
48
|
+
async function hybridSearch(query, tfidfResults, maxResults, alpha) {
|
|
49
|
+
const provider = await getEmbeddingProvider();
|
|
50
|
+
if (!provider) {
|
|
51
|
+
return tfidfResults;
|
|
52
|
+
}
|
|
53
|
+
let queryVector;
|
|
54
|
+
try {
|
|
55
|
+
queryVector = await provider.embedOne(query);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return tfidfResults;
|
|
59
|
+
}
|
|
60
|
+
const store = getVectorStore();
|
|
61
|
+
let vectorResults;
|
|
62
|
+
try {
|
|
63
|
+
vectorResults = store.searchBySource(queryVector, 'session', maxResults * 2);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return tfidfResults;
|
|
67
|
+
}
|
|
68
|
+
if (vectorResults.length === 0) {
|
|
69
|
+
return tfidfResults;
|
|
70
|
+
}
|
|
71
|
+
// Build a map of semantic scores keyed by sessionId
|
|
72
|
+
// Multiple chunks may match for the same session — take the max score
|
|
73
|
+
const semanticScores = new Map();
|
|
74
|
+
for (const vr of vectorResults) {
|
|
75
|
+
const existing = semanticScores.get(vr.sourceId) ?? 0;
|
|
76
|
+
if (vr.score > existing) {
|
|
77
|
+
semanticScores.set(vr.sourceId, vr.score);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Normalize TF-IDF scores to 0-1 range
|
|
81
|
+
const maxTfidf = tfidfResults.length > 0 ? Math.max(...tfidfResults.map((r) => r.score)) : 1;
|
|
82
|
+
const normFactor = maxTfidf > 0 ? maxTfidf : 1;
|
|
83
|
+
// Merge: start with TF-IDF results, blend in semantic scores
|
|
84
|
+
const merged = new Map();
|
|
85
|
+
for (const result of tfidfResults) {
|
|
86
|
+
const key = `${result.id}:${result.timestamp ?? ''}`;
|
|
87
|
+
const normalizedTfidf = result.score / normFactor;
|
|
88
|
+
const semanticScore = semanticScores.get(result.id) ?? 0;
|
|
89
|
+
const blended = alpha * normalizedTfidf + (1 - alpha) * semanticScore;
|
|
90
|
+
// Apply recency decay on top of blended score
|
|
91
|
+
const ts = result.timestamp ?? result.metadata?.sessionDate;
|
|
92
|
+
const decay = ts ? recencyDecay(ts) : 1;
|
|
93
|
+
const finalScore = blended * decay;
|
|
94
|
+
merged.set(key, {
|
|
95
|
+
...result,
|
|
96
|
+
score: finalScore,
|
|
97
|
+
metadata: {
|
|
98
|
+
...result.metadata,
|
|
99
|
+
tfidfScore: normalizedTfidf,
|
|
100
|
+
semanticScore,
|
|
101
|
+
blendAlpha: alpha,
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
for (const vr of vectorResults) {
|
|
106
|
+
const alreadyPresent = Array.from(merged.values()).some((r) => r.id === vr.sourceId);
|
|
107
|
+
if (!alreadyPresent) {
|
|
108
|
+
const semanticScore = vr.score;
|
|
109
|
+
const blended = (1 - alpha) * semanticScore;
|
|
110
|
+
// Use chunkText metadata for excerpt
|
|
111
|
+
const excerpt = vr.chunkText.length > 200 ? vr.chunkText.slice(0, 200) + '...' : vr.chunkText;
|
|
112
|
+
const timestamp = vr.metadata?.timestamp ?? undefined;
|
|
113
|
+
const decay = timestamp ? recencyDecay(timestamp) : 0.5;
|
|
114
|
+
const finalScore = blended * decay;
|
|
115
|
+
const key = `${vr.sourceId}:${timestamp ?? ''}`;
|
|
116
|
+
if (!merged.has(key)) {
|
|
117
|
+
merged.set(key, {
|
|
118
|
+
source: 'session',
|
|
119
|
+
id: vr.sourceId,
|
|
120
|
+
role: vr.metadata?.role ?? 'unknown',
|
|
121
|
+
timestamp,
|
|
122
|
+
excerpt,
|
|
123
|
+
score: finalScore,
|
|
124
|
+
metadata: {
|
|
125
|
+
tfidfScore: 0,
|
|
126
|
+
semanticScore,
|
|
127
|
+
blendAlpha: alpha,
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
const results = Array.from(merged.values());
|
|
134
|
+
results.sort((a, b) => b.score - a.score);
|
|
135
|
+
return results.slice(0, maxResults);
|
|
136
|
+
}
|
|
137
|
+
function rankedSearch(query, projects, role, maxResults) {
|
|
138
|
+
const index = new TfIdfIndex();
|
|
139
|
+
const docMap = new Map();
|
|
140
|
+
let docCounter = 0;
|
|
141
|
+
for (const proj of projects) {
|
|
142
|
+
const sessions = getSessionFiles(proj.path);
|
|
143
|
+
for (const sess of sessions) {
|
|
144
|
+
try {
|
|
145
|
+
const entries = parseSessionFile(sess.file);
|
|
146
|
+
if (entries.length === 0)
|
|
147
|
+
continue;
|
|
148
|
+
const meta = getSessionMeta(entries);
|
|
149
|
+
const messages = extractMessages(entries);
|
|
150
|
+
for (const msg of messages) {
|
|
151
|
+
if (role !== 'all' && msg.role !== role)
|
|
152
|
+
continue;
|
|
153
|
+
const docId = `doc_${docCounter++}`;
|
|
154
|
+
index.addDocument(docId, msg.content);
|
|
155
|
+
docMap.set(docId, {
|
|
156
|
+
project: proj.name,
|
|
157
|
+
sessionId: sess.id,
|
|
158
|
+
role: msg.role,
|
|
159
|
+
timestamp: msg.timestamp,
|
|
160
|
+
content: msg.content,
|
|
161
|
+
sessionDate: meta.startTime,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
// skip broken files
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
const ranked = index.search(query, maxResults * 2); // over-fetch before decay reranking
|
|
171
|
+
const results = ranked
|
|
172
|
+
.map(({ id, score }) => {
|
|
173
|
+
const doc = docMap.get(id);
|
|
174
|
+
if (!doc)
|
|
175
|
+
return null;
|
|
176
|
+
const excerpt = buildExcerpt(doc.content, query);
|
|
177
|
+
const ts = doc.timestamp ?? doc.sessionDate;
|
|
178
|
+
const decay = recencyDecay(ts);
|
|
179
|
+
const adjustedScore = score * decay;
|
|
180
|
+
return {
|
|
181
|
+
source: 'session',
|
|
182
|
+
id: doc.sessionId,
|
|
183
|
+
project: doc.project,
|
|
184
|
+
role: doc.role,
|
|
185
|
+
timestamp: ts,
|
|
186
|
+
excerpt,
|
|
187
|
+
score: adjustedScore,
|
|
188
|
+
metadata: {
|
|
189
|
+
sessionDate: doc.sessionDate,
|
|
190
|
+
relevanceScore: score,
|
|
191
|
+
recencyMultiplier: Math.round(decay * 100) / 100,
|
|
192
|
+
},
|
|
193
|
+
};
|
|
194
|
+
})
|
|
195
|
+
.filter((r) => r !== null);
|
|
196
|
+
// Re-sort by adjusted score and trim
|
|
197
|
+
results.sort((a, b) => b.score - a.score);
|
|
198
|
+
return results.slice(0, maxResults);
|
|
199
|
+
}
|
|
200
|
+
// ── Regex-based search (legacy mode) ────────────────────────────────────────
|
|
201
|
+
function regexSearch(query, projects, role, caseSensitive, maxResults) {
|
|
202
|
+
const flags = caseSensitive ? 'g' : 'gi';
|
|
203
|
+
let regex;
|
|
204
|
+
try {
|
|
205
|
+
regex = new RegExp(query, flags);
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
regex = new RegExp(query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), flags);
|
|
209
|
+
}
|
|
210
|
+
const matches = [];
|
|
211
|
+
for (const proj of projects) {
|
|
212
|
+
const sessions = getSessionFiles(proj.path);
|
|
213
|
+
for (const sess of sessions) {
|
|
214
|
+
try {
|
|
215
|
+
const entries = parseSessionFile(sess.file);
|
|
216
|
+
if (entries.length === 0)
|
|
217
|
+
continue;
|
|
218
|
+
const meta = getSessionMeta(entries);
|
|
219
|
+
const messages = extractMessages(entries);
|
|
220
|
+
for (const msg of messages) {
|
|
221
|
+
if (role !== 'all' && msg.role !== role)
|
|
222
|
+
continue;
|
|
223
|
+
// Reset lastIndex before test() — global regex is stateful
|
|
224
|
+
regex.lastIndex = 0;
|
|
225
|
+
if (!regex.test(msg.content))
|
|
226
|
+
continue;
|
|
227
|
+
const excerpt = buildExcerpt(msg.content, query, { caseSensitive });
|
|
228
|
+
matches.push({
|
|
229
|
+
source: 'session',
|
|
230
|
+
id: sess.id,
|
|
231
|
+
project: proj.name,
|
|
232
|
+
role: msg.role,
|
|
233
|
+
timestamp: msg.timestamp ?? meta.startTime,
|
|
234
|
+
excerpt,
|
|
235
|
+
score: 1, // no ranking in regex mode
|
|
236
|
+
metadata: {
|
|
237
|
+
sessionDate: meta.startTime,
|
|
238
|
+
},
|
|
239
|
+
});
|
|
240
|
+
if (matches.length >= maxResults)
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
// skip
|
|
246
|
+
}
|
|
247
|
+
if (matches.length >= maxResults)
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
250
|
+
if (matches.length >= maxResults)
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
253
|
+
return matches;
|
|
254
|
+
}
|
|
255
|
+
// buildExcerpt imported from ../search/excerpt.js
|
|
256
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/sessions/search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type SessionMeta } from './parser.js';
|
|
2
|
+
export interface SessionSummary {
|
|
3
|
+
meta: SessionMeta;
|
|
4
|
+
topicCount: number;
|
|
5
|
+
topics: Array<{
|
|
6
|
+
timestamp: string | null;
|
|
7
|
+
content: string;
|
|
8
|
+
}>;
|
|
9
|
+
toolsUsed: string[];
|
|
10
|
+
filesModified: string[];
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Generate a structured summary of a session.
|
|
14
|
+
*
|
|
15
|
+
* - Extracts user messages as topics (first 300 chars each)
|
|
16
|
+
* - Collects unique tool names from tool_use entries
|
|
17
|
+
* - Extracts file paths mentioned in tool results
|
|
18
|
+
*/
|
|
19
|
+
export declare function getSessionSummary(sessionId: string, project?: string): SessionSummary | null;
|
|
20
|
+
/**
|
|
21
|
+
* List all sessions with metadata, sorted by startTime descending.
|
|
22
|
+
* Optionally filter by project name (substring match).
|
|
23
|
+
*/
|
|
24
|
+
export declare function listSessions(project?: string): Array<{
|
|
25
|
+
project: string;
|
|
26
|
+
sessionId: string;
|
|
27
|
+
} & SessionMeta>;
|
|
28
|
+
//# sourceMappingURL=summary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summary.d.ts","sourceRoot":"","sources":["../../src/sessions/summary.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,WAAW,EACjB,MAAM,aAAa,CAAC;AAIrB,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,WAAW,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7D,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAsCD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAiE5F;AAID;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,OAAO,CAAC,EAAE,MAAM,GACf,KAAK,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,WAAW,CAAC,CAiC7D"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { getProjectDirs, getSessionFiles, parseSessionFile, extractMessages, getSessionMeta, } from './parser.js';
|
|
2
|
+
// ── File path extraction ────────────────────────────────────────────────────
|
|
3
|
+
/**
|
|
4
|
+
* Regex to match common file paths in tool results.
|
|
5
|
+
* Captures paths like /src/foo.ts, ./bar.js, C:\path\file.py, etc.
|
|
6
|
+
*/
|
|
7
|
+
const FILE_PATH_RE = /(?:^|[\s"'`(])([./~]?(?:[\w.-]+\/)+[\w.-]+\.(?:ts|tsx|js|jsx|py|rs|go|java|vue|svelte|css|scss|html|json|yaml|yml|toml|md|txt|sh|sql|prisma|graphql|proto))\b/g;
|
|
8
|
+
function extractFilePaths(text) {
|
|
9
|
+
const paths = new Set();
|
|
10
|
+
let match;
|
|
11
|
+
// Reset lastIndex
|
|
12
|
+
FILE_PATH_RE.lastIndex = 0;
|
|
13
|
+
while ((match = FILE_PATH_RE.exec(text)) !== null) {
|
|
14
|
+
paths.add(match[1]);
|
|
15
|
+
}
|
|
16
|
+
return Array.from(paths);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Extract tool names from tool_use entries.
|
|
20
|
+
* The tool name is typically the first word or a JSON "name" field.
|
|
21
|
+
*/
|
|
22
|
+
const TOOL_NAME_RE = /(?:"name"\s*:\s*"([^"]+)"|^(\w+(?:_\w+)*))/;
|
|
23
|
+
function extractToolName(content) {
|
|
24
|
+
const match = content.match(TOOL_NAME_RE);
|
|
25
|
+
return match ? (match[1] ?? match[2] ?? null) : null;
|
|
26
|
+
}
|
|
27
|
+
// ── Session summary ─────────────────────────────────────────────────────────
|
|
28
|
+
/**
|
|
29
|
+
* Generate a structured summary of a session.
|
|
30
|
+
*
|
|
31
|
+
* - Extracts user messages as topics (first 300 chars each)
|
|
32
|
+
* - Collects unique tool names from tool_use entries
|
|
33
|
+
* - Extracts file paths mentioned in tool results
|
|
34
|
+
*/
|
|
35
|
+
export function getSessionSummary(sessionId, project) {
|
|
36
|
+
const projects = getProjectDirs().filter((p) => !project || p.name.toLowerCase().includes(project.toLowerCase()));
|
|
37
|
+
for (const proj of projects) {
|
|
38
|
+
const sessions = getSessionFiles(proj.path);
|
|
39
|
+
const match = sessions.find((s) => s.id === sessionId);
|
|
40
|
+
if (!match)
|
|
41
|
+
continue;
|
|
42
|
+
const entries = parseSessionFile(match.file);
|
|
43
|
+
if (entries.length === 0)
|
|
44
|
+
return null;
|
|
45
|
+
const meta = getSessionMeta(entries);
|
|
46
|
+
const messages = extractMessages(entries);
|
|
47
|
+
// Topics: user messages truncated to 300 chars
|
|
48
|
+
// Filter out tool results, JSON blobs, base64 images, system reminders
|
|
49
|
+
const isHumanMessage = (text) => {
|
|
50
|
+
const t = text.trimStart();
|
|
51
|
+
if (t.startsWith('[{') || t.startsWith('{"'))
|
|
52
|
+
return false;
|
|
53
|
+
if (t.includes('tool_use_id') || t.includes('tool_result'))
|
|
54
|
+
return false;
|
|
55
|
+
if (t.includes('base64') || t.includes('media_type'))
|
|
56
|
+
return false;
|
|
57
|
+
if (t.includes('<system-reminder>'))
|
|
58
|
+
return false;
|
|
59
|
+
if (t.length < 3)
|
|
60
|
+
return false;
|
|
61
|
+
return true;
|
|
62
|
+
};
|
|
63
|
+
const topics = messages
|
|
64
|
+
.filter((m) => m.role === 'user')
|
|
65
|
+
.filter((m) => isHumanMessage(m.content))
|
|
66
|
+
.map((m) => ({
|
|
67
|
+
timestamp: m.timestamp,
|
|
68
|
+
content: m.content.length > 300 ? m.content.substring(0, 300) + '...' : m.content,
|
|
69
|
+
}));
|
|
70
|
+
// Tools: unique tool names from tool_use messages
|
|
71
|
+
const toolNames = new Set();
|
|
72
|
+
for (const msg of messages) {
|
|
73
|
+
if (msg.role === 'tool_use') {
|
|
74
|
+
const name = extractToolName(msg.content);
|
|
75
|
+
if (name)
|
|
76
|
+
toolNames.add(name);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Files: paths mentioned in tool_result messages
|
|
80
|
+
const allFiles = new Set();
|
|
81
|
+
for (const msg of messages) {
|
|
82
|
+
if (msg.role === 'tool_result') {
|
|
83
|
+
for (const fp of extractFilePaths(msg.content)) {
|
|
84
|
+
allFiles.add(fp);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
meta,
|
|
90
|
+
topicCount: topics.length,
|
|
91
|
+
topics,
|
|
92
|
+
toolsUsed: Array.from(toolNames).sort(),
|
|
93
|
+
filesModified: Array.from(allFiles).sort(),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
// ── List sessions ───────────────────────────────────────────────────────────
|
|
99
|
+
/**
|
|
100
|
+
* List all sessions with metadata, sorted by startTime descending.
|
|
101
|
+
* Optionally filter by project name (substring match).
|
|
102
|
+
*/
|
|
103
|
+
export function listSessions(project) {
|
|
104
|
+
const projects = getProjectDirs().filter((p) => !project || p.name.toLowerCase().includes(project.toLowerCase()));
|
|
105
|
+
const results = [];
|
|
106
|
+
for (const proj of projects) {
|
|
107
|
+
const sessions = getSessionFiles(proj.path);
|
|
108
|
+
for (const sess of sessions) {
|
|
109
|
+
try {
|
|
110
|
+
const entries = parseSessionFile(sess.file);
|
|
111
|
+
if (entries.length === 0)
|
|
112
|
+
continue;
|
|
113
|
+
const meta = getSessionMeta(entries);
|
|
114
|
+
results.push({
|
|
115
|
+
project: proj.name,
|
|
116
|
+
sessionId: sess.id,
|
|
117
|
+
...meta,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
// skip broken files
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// Sort by startTime descending (newest first)
|
|
126
|
+
results.sort((a, b) => {
|
|
127
|
+
if (a.startTime === 'unknown')
|
|
128
|
+
return 1;
|
|
129
|
+
if (b.startTime === 'unknown')
|
|
130
|
+
return -1;
|
|
131
|
+
return new Date(b.startTime).getTime() - new Date(a.startTime).getTime();
|
|
132
|
+
});
|
|
133
|
+
return results;
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summary.js","sourceRoot":"","sources":["../../src/sessions/summary.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ProviderName } from './embeddings/types.js';
|
|
2
|
+
export interface KnowledgeConfig {
|
|
3
|
+
memoryDir: string;
|
|
4
|
+
claudeDir: string;
|
|
5
|
+
projectsDir: string;
|
|
6
|
+
embeddingProvider: ProviderName;
|
|
7
|
+
embeddingAlpha: number;
|
|
8
|
+
gitUrl: string | undefined;
|
|
9
|
+
autoDistill: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface PersistedConfig {
|
|
12
|
+
gitUrl?: string;
|
|
13
|
+
memoryDir?: string;
|
|
14
|
+
autoDistill?: boolean;
|
|
15
|
+
embeddingProvider?: string;
|
|
16
|
+
embeddingAlpha?: number;
|
|
17
|
+
}
|
|
18
|
+
export declare function getConfigLocation(): string;
|
|
19
|
+
export declare function loadPersistedConfig(): PersistedConfig;
|
|
20
|
+
export declare function savePersistedConfig(updates: Partial<PersistedConfig>): PersistedConfig;
|
|
21
|
+
export declare function getConfig(): KnowledgeConfig;
|
|
22
|
+
/**
|
|
23
|
+
* Read the version from package.json (cached after first call).
|
|
24
|
+
*/
|
|
25
|
+
export declare function getVersion(): string;
|
|
26
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,YAAY,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,WAAW,EAAE,OAAO,CAAC;CACtB;AAID,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAaD,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAgB,mBAAmB,IAAI,eAAe,CAQrD;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,eAAe,CAgBtF;AAID,wBAAgB,SAAS,IAAI,eAAe,CAkC3C;AAID;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAyBnC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { homedir } from 'os';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
import { dirname } from 'path';
|
|
6
|
+
function getConfigDir() {
|
|
7
|
+
if (process.platform === 'win32') {
|
|
8
|
+
return join(process.env.APPDATA || join(homedir(), 'AppData', 'Roaming'), 'knowledge');
|
|
9
|
+
}
|
|
10
|
+
return join(process.env.XDG_CONFIG_HOME || join(homedir(), '.config'), 'knowledge');
|
|
11
|
+
}
|
|
12
|
+
function getConfigPath() {
|
|
13
|
+
return join(getConfigDir(), 'config.json');
|
|
14
|
+
}
|
|
15
|
+
export function getConfigLocation() {
|
|
16
|
+
return getConfigPath();
|
|
17
|
+
}
|
|
18
|
+
export function loadPersistedConfig() {
|
|
19
|
+
const configPath = getConfigPath();
|
|
20
|
+
if (!existsSync(configPath))
|
|
21
|
+
return {};
|
|
22
|
+
try {
|
|
23
|
+
return JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return {};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export function savePersistedConfig(updates) {
|
|
30
|
+
const configDir = getConfigDir();
|
|
31
|
+
if (!existsSync(configDir)) {
|
|
32
|
+
mkdirSync(configDir, { recursive: true });
|
|
33
|
+
}
|
|
34
|
+
const existing = loadPersistedConfig();
|
|
35
|
+
const merged = { ...existing };
|
|
36
|
+
for (const [key, value] of Object.entries(updates)) {
|
|
37
|
+
if (value === undefined || value === null || value === '') {
|
|
38
|
+
delete merged[key];
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
merged[key] = value;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
writeFileSync(getConfigPath(), JSON.stringify(merged, null, 2) + '\n', 'utf-8');
|
|
45
|
+
return merged;
|
|
46
|
+
}
|
|
47
|
+
// ── Config resolution (env vars > persisted config > defaults) ──────────────
|
|
48
|
+
export function getConfig() {
|
|
49
|
+
const home = homedir();
|
|
50
|
+
const claudeDir = process.env.CLAUDE_DIR || join(home, '.claude');
|
|
51
|
+
const persisted = loadPersistedConfig();
|
|
52
|
+
const memoryDir = process.env.KNOWLEDGE_MEMORY_DIR ||
|
|
53
|
+
process.env.CLAUDE_MEMORY_DIR ||
|
|
54
|
+
persisted.memoryDir ||
|
|
55
|
+
join(home, 'claude-memory');
|
|
56
|
+
const projectsDir = join(claudeDir, 'projects');
|
|
57
|
+
const embeddingProvider = process.env.KNOWLEDGE_EMBEDDING_PROVIDER ||
|
|
58
|
+
persisted.embeddingProvider ||
|
|
59
|
+
'local';
|
|
60
|
+
const embeddingAlpha = parseFloat(process.env.KNOWLEDGE_EMBEDDING_ALPHA || String(persisted.embeddingAlpha ?? 0.3));
|
|
61
|
+
const gitUrl = process.env.KNOWLEDGE_GIT_URL || persisted.gitUrl || undefined;
|
|
62
|
+
const autoDistillEnv = process.env.KNOWLEDGE_AUTO_DISTILL;
|
|
63
|
+
const autoDistill = autoDistillEnv !== undefined
|
|
64
|
+
? autoDistillEnv.toLowerCase() !== 'false'
|
|
65
|
+
: (persisted.autoDistill ?? true);
|
|
66
|
+
return {
|
|
67
|
+
memoryDir,
|
|
68
|
+
claudeDir,
|
|
69
|
+
projectsDir,
|
|
70
|
+
embeddingProvider,
|
|
71
|
+
embeddingAlpha,
|
|
72
|
+
gitUrl,
|
|
73
|
+
autoDistill,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
let _version = null;
|
|
77
|
+
/**
|
|
78
|
+
* Read the version from package.json (cached after first call).
|
|
79
|
+
*/
|
|
80
|
+
export function getVersion() {
|
|
81
|
+
if (_version)
|
|
82
|
+
return _version;
|
|
83
|
+
try {
|
|
84
|
+
const thisFile = fileURLToPath(import.meta.url);
|
|
85
|
+
const thisDir = dirname(thisFile);
|
|
86
|
+
// Try src/../package.json then dist/../package.json
|
|
87
|
+
for (const rel of [
|
|
88
|
+
join(thisDir, '..', 'package.json'),
|
|
89
|
+
join(thisDir, '..', '..', 'package.json'),
|
|
90
|
+
]) {
|
|
91
|
+
try {
|
|
92
|
+
const pkg = JSON.parse(readFileSync(rel, 'utf-8'));
|
|
93
|
+
if (pkg.version) {
|
|
94
|
+
_version = String(pkg.version);
|
|
95
|
+
return _version;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// fallback
|
|
105
|
+
}
|
|
106
|
+
_version = '1.0.0';
|
|
107
|
+
return _version;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|