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,182 @@
|
|
|
1
|
+
import { getEmbeddingProvider } from '../embeddings/index.js';
|
|
2
|
+
import { VectorStore, chunkKnowledge, chunkSession } from '../vectorstore/index.js';
|
|
3
|
+
import { listEntries, readEntry } from '../knowledge/store.js';
|
|
4
|
+
import { getProjectDirs, getSessionFiles, parseSessionFile, extractMessages, getSessionMeta, } from './parser.js';
|
|
5
|
+
import { getConfig } from '../types.js';
|
|
6
|
+
import { distillSessions } from '../knowledge/distill.js';
|
|
7
|
+
let _vectorStore = null;
|
|
8
|
+
function getVectorStore() {
|
|
9
|
+
if (!_vectorStore) {
|
|
10
|
+
_vectorStore = new VectorStore();
|
|
11
|
+
}
|
|
12
|
+
return _vectorStore;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Index a single knowledge entry into the vector store.
|
|
16
|
+
*/
|
|
17
|
+
export async function indexKnowledgeEntry(path, content) {
|
|
18
|
+
const provider = await getEmbeddingProvider();
|
|
19
|
+
if (!provider)
|
|
20
|
+
return;
|
|
21
|
+
const store = getVectorStore();
|
|
22
|
+
const chunks = chunkKnowledge(content);
|
|
23
|
+
if (chunks.length === 0)
|
|
24
|
+
return;
|
|
25
|
+
const texts = chunks.map((c) => c.text);
|
|
26
|
+
const embeddings = await provider.embed(texts);
|
|
27
|
+
const entries = chunks.map((chunk, i) => ({
|
|
28
|
+
id: `knowledge:${path}:${chunk.index}`,
|
|
29
|
+
source: 'knowledge',
|
|
30
|
+
sourceId: path,
|
|
31
|
+
chunkIndex: chunk.index,
|
|
32
|
+
chunkText: chunk.text,
|
|
33
|
+
provider: provider.name,
|
|
34
|
+
dimensions: provider.dimensions,
|
|
35
|
+
embedding: embeddings[i],
|
|
36
|
+
metadata: chunk.metadata,
|
|
37
|
+
}));
|
|
38
|
+
store.upsert(entries);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Index session messages into the vector store.
|
|
42
|
+
*/
|
|
43
|
+
export async function indexSessionMessages(sessionId, messages) {
|
|
44
|
+
const provider = await getEmbeddingProvider();
|
|
45
|
+
if (!provider)
|
|
46
|
+
return;
|
|
47
|
+
const store = getVectorStore();
|
|
48
|
+
const chunks = chunkSession(messages);
|
|
49
|
+
if (chunks.length === 0)
|
|
50
|
+
return;
|
|
51
|
+
const texts = chunks.map((c) => c.text);
|
|
52
|
+
const embeddings = await provider.embed(texts);
|
|
53
|
+
const entries = chunks.map((chunk, i) => ({
|
|
54
|
+
id: `session:${sessionId}:${chunk.index}`,
|
|
55
|
+
source: 'session',
|
|
56
|
+
sourceId: sessionId,
|
|
57
|
+
chunkIndex: chunk.index,
|
|
58
|
+
chunkText: chunk.text,
|
|
59
|
+
provider: provider.name,
|
|
60
|
+
dimensions: provider.dimensions,
|
|
61
|
+
embedding: embeddings[i],
|
|
62
|
+
metadata: chunk.metadata,
|
|
63
|
+
}));
|
|
64
|
+
store.upsert(entries);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Background indexer that embeds all unindexed knowledge entries and session
|
|
68
|
+
* messages. Runs non-blocking after server startup.
|
|
69
|
+
*/
|
|
70
|
+
export async function backgroundIndex() {
|
|
71
|
+
const provider = await getEmbeddingProvider();
|
|
72
|
+
if (!provider) {
|
|
73
|
+
console.error('[knowledge] No embedding provider available, skipping background index');
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const store = getVectorStore();
|
|
77
|
+
const wiped = store.setProvider(provider.name, provider.dimensions);
|
|
78
|
+
if (wiped) {
|
|
79
|
+
console.error('[knowledge] Embedding provider changed, wiped existing vectors');
|
|
80
|
+
}
|
|
81
|
+
const config = getConfig();
|
|
82
|
+
// ── Index knowledge entries ─────────────────────────────────────────────
|
|
83
|
+
try {
|
|
84
|
+
const entries = listEntries(config.memoryDir);
|
|
85
|
+
let indexed = 0;
|
|
86
|
+
const total = entries.length;
|
|
87
|
+
for (const entry of entries) {
|
|
88
|
+
try {
|
|
89
|
+
if (store.hasEmbeddings(entry.path)) {
|
|
90
|
+
indexed++;
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
const { content } = readEntry(config.memoryDir, entry.path);
|
|
94
|
+
await indexKnowledgeEntry(entry.path, content);
|
|
95
|
+
indexed++;
|
|
96
|
+
if (indexed % 10 === 0 || indexed === total) {
|
|
97
|
+
console.error(`[knowledge] Indexed ${indexed}/${total} knowledge entries...`);
|
|
98
|
+
}
|
|
99
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
console.error(`[knowledge] Failed to index knowledge entry ${entry.path}: ${err}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (total > 0) {
|
|
106
|
+
console.error(`[knowledge] Knowledge indexing complete: ${indexed}/${total}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
console.error(`[knowledge] Knowledge indexing failed: ${err}`);
|
|
111
|
+
}
|
|
112
|
+
// ── Index session messages ──────────────────────────────────────────────
|
|
113
|
+
try {
|
|
114
|
+
const projects = getProjectDirs();
|
|
115
|
+
let totalSessions = 0;
|
|
116
|
+
let indexedSessions = 0;
|
|
117
|
+
for (const proj of projects) {
|
|
118
|
+
const sessions = getSessionFiles(proj.path);
|
|
119
|
+
totalSessions += sessions.length;
|
|
120
|
+
}
|
|
121
|
+
for (const proj of projects) {
|
|
122
|
+
const sessions = getSessionFiles(proj.path);
|
|
123
|
+
for (const sess of sessions) {
|
|
124
|
+
try {
|
|
125
|
+
if (store.hasEmbeddings(sess.id)) {
|
|
126
|
+
indexedSessions++;
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
const entries = parseSessionFile(sess.file);
|
|
130
|
+
if (entries.length === 0) {
|
|
131
|
+
indexedSessions++;
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
const meta = getSessionMeta(entries);
|
|
135
|
+
const messages = extractMessages(entries);
|
|
136
|
+
const sessionMessages = messages.map((m) => ({
|
|
137
|
+
role: m.role,
|
|
138
|
+
text: m.content,
|
|
139
|
+
timestamp: m.timestamp ?? meta.startTime,
|
|
140
|
+
sessionId: sess.id,
|
|
141
|
+
}));
|
|
142
|
+
await indexSessionMessages(sess.id, sessionMessages);
|
|
143
|
+
indexedSessions++;
|
|
144
|
+
if (indexedSessions % 20 === 0 || indexedSessions === totalSessions) {
|
|
145
|
+
console.error(`[knowledge] Indexed ${indexedSessions}/${totalSessions} sessions...`);
|
|
146
|
+
}
|
|
147
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
console.error(`[knowledge] Failed to index session ${sess.id}: ${err}`);
|
|
151
|
+
indexedSessions++;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (totalSessions > 0) {
|
|
156
|
+
console.error(`[knowledge] Session indexing complete: ${indexedSessions}/${totalSessions}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
catch (err) {
|
|
160
|
+
console.error(`[knowledge] Session indexing failed: ${err}`);
|
|
161
|
+
}
|
|
162
|
+
console.error('[knowledge] Background indexing complete');
|
|
163
|
+
// ── Auto-distill session insights into knowledge base ───────────────────
|
|
164
|
+
const config2 = getConfig();
|
|
165
|
+
if (config2.autoDistill) {
|
|
166
|
+
try {
|
|
167
|
+
console.error('[knowledge] Starting auto-distillation...');
|
|
168
|
+
const result = await distillSessions();
|
|
169
|
+
const total = result.updated.length + result.created.length;
|
|
170
|
+
if (total > 0) {
|
|
171
|
+
console.error(`[knowledge] Distilled ${total} project(s): ${result.updated.length} updated, ${result.created.length} created`);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
console.error('[knowledge] No new sessions to distill');
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
catch (err) {
|
|
178
|
+
console.error(`[knowledge] Auto-distillation failed: ${err}`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=indexer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexer.js","sourceRoot":"","sources":["../../src/sessions/indexer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export interface SessionEntry {
|
|
2
|
+
type: string;
|
|
3
|
+
timestamp?: string;
|
|
4
|
+
sessionId?: string;
|
|
5
|
+
cwd?: string;
|
|
6
|
+
gitBranch?: string;
|
|
7
|
+
message?: {
|
|
8
|
+
role?: string;
|
|
9
|
+
content: unknown;
|
|
10
|
+
};
|
|
11
|
+
content?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface SessionMessage {
|
|
14
|
+
role: 'user' | 'assistant' | 'tool_use' | 'tool_result';
|
|
15
|
+
content: string;
|
|
16
|
+
timestamp: string | null;
|
|
17
|
+
}
|
|
18
|
+
export interface SessionMeta {
|
|
19
|
+
startTime: string;
|
|
20
|
+
endTime: string;
|
|
21
|
+
cwd: string;
|
|
22
|
+
branch: string;
|
|
23
|
+
messageCount: number;
|
|
24
|
+
userMessageCount: number;
|
|
25
|
+
preview: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Parse a JSONL session file into an array of entries.
|
|
29
|
+
* Malformed lines are silently skipped.
|
|
30
|
+
*/
|
|
31
|
+
export declare function parseSessionFile(filePath: string): SessionEntry[];
|
|
32
|
+
/**
|
|
33
|
+
* Extract structured messages from raw session entries.
|
|
34
|
+
*
|
|
35
|
+
* - User messages: entry.message.content (string or stringified)
|
|
36
|
+
* - Assistant messages: text parts from content array
|
|
37
|
+
* - Tool use / result: content truncated to 500 chars
|
|
38
|
+
*/
|
|
39
|
+
export declare function extractMessages(entries: SessionEntry[]): SessionMessage[];
|
|
40
|
+
/**
|
|
41
|
+
* Extract metadata from session entries (first/last entry, counts, preview).
|
|
42
|
+
*/
|
|
43
|
+
export declare function getSessionMeta(entries: SessionEntry[]): SessionMeta;
|
|
44
|
+
/**
|
|
45
|
+
* Discover all project directories under ~/.claude/projects/
|
|
46
|
+
*/
|
|
47
|
+
export declare function getProjectDirs(): Array<{
|
|
48
|
+
name: string;
|
|
49
|
+
path: string;
|
|
50
|
+
}>;
|
|
51
|
+
/**
|
|
52
|
+
* List all .jsonl session files in a given project directory.
|
|
53
|
+
*/
|
|
54
|
+
export declare function getSessionFiles(projectPath: string): Array<{
|
|
55
|
+
id: string;
|
|
56
|
+
file: string;
|
|
57
|
+
}>;
|
|
58
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/sessions/parser.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,GAAG,aAAa,CAAC;IACxD,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB;AAID;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,EAAE,CAoBjE;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,cAAc,EAAE,CAuDzE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,WAAW,CA2BnE;AAID;;GAEG;AACH,wBAAgB,cAAc,IAAI,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAWtE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAUxF"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { getConfig } from '../types.js';
|
|
4
|
+
// ── Parsing ─────────────────────────────────────────────────────────────────
|
|
5
|
+
/**
|
|
6
|
+
* Parse a JSONL session file into an array of entries.
|
|
7
|
+
* Malformed lines are silently skipped.
|
|
8
|
+
*/
|
|
9
|
+
export function parseSessionFile(filePath) {
|
|
10
|
+
let raw;
|
|
11
|
+
try {
|
|
12
|
+
raw = fs.readFileSync(filePath, 'utf-8');
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return [];
|
|
16
|
+
}
|
|
17
|
+
const lines = raw.split('\n').filter((l) => l.trim());
|
|
18
|
+
const entries = [];
|
|
19
|
+
for (const line of lines) {
|
|
20
|
+
try {
|
|
21
|
+
entries.push(JSON.parse(line));
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
// skip malformed lines gracefully
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return entries;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Extract structured messages from raw session entries.
|
|
31
|
+
*
|
|
32
|
+
* - User messages: entry.message.content (string or stringified)
|
|
33
|
+
* - Assistant messages: text parts from content array
|
|
34
|
+
* - Tool use / result: content truncated to 500 chars
|
|
35
|
+
*/
|
|
36
|
+
export function extractMessages(entries) {
|
|
37
|
+
const messages = [];
|
|
38
|
+
for (const entry of entries) {
|
|
39
|
+
const ts = entry.timestamp ?? null;
|
|
40
|
+
if (entry.type === 'user' && entry.message?.content) {
|
|
41
|
+
const content = typeof entry.message.content === 'string'
|
|
42
|
+
? entry.message.content
|
|
43
|
+
: JSON.stringify(entry.message.content);
|
|
44
|
+
messages.push({ role: 'user', content, timestamp: ts });
|
|
45
|
+
}
|
|
46
|
+
else if (entry.type === 'assistant' && entry.message?.content) {
|
|
47
|
+
const parts = Array.isArray(entry.message.content)
|
|
48
|
+
? entry.message.content
|
|
49
|
+
: [entry.message.content];
|
|
50
|
+
const textParts = parts
|
|
51
|
+
.filter((p) => typeof p === 'string' ||
|
|
52
|
+
(typeof p === 'object' &&
|
|
53
|
+
p !== null &&
|
|
54
|
+
'type' in p &&
|
|
55
|
+
p.type === 'text'))
|
|
56
|
+
.map((p) => (typeof p === 'string' ? p : p.text))
|
|
57
|
+
.filter(Boolean);
|
|
58
|
+
if (textParts.length > 0) {
|
|
59
|
+
messages.push({
|
|
60
|
+
role: 'assistant',
|
|
61
|
+
content: textParts.join('\n'),
|
|
62
|
+
timestamp: ts,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else if (entry.type === 'tool_use' || entry.type === 'tool_result') {
|
|
67
|
+
const content = typeof entry.content === 'string'
|
|
68
|
+
? entry.content
|
|
69
|
+
: typeof entry.message?.content === 'string'
|
|
70
|
+
? entry.message.content
|
|
71
|
+
: null;
|
|
72
|
+
if (content) {
|
|
73
|
+
messages.push({
|
|
74
|
+
role: entry.type,
|
|
75
|
+
content: content.substring(0, 500),
|
|
76
|
+
timestamp: ts,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return messages;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Extract metadata from session entries (first/last entry, counts, preview).
|
|
85
|
+
*/
|
|
86
|
+
export function getSessionMeta(entries) {
|
|
87
|
+
if (entries.length === 0) {
|
|
88
|
+
return {
|
|
89
|
+
startTime: 'unknown',
|
|
90
|
+
endTime: 'unknown',
|
|
91
|
+
cwd: 'unknown',
|
|
92
|
+
branch: 'unknown',
|
|
93
|
+
messageCount: 0,
|
|
94
|
+
userMessageCount: 0,
|
|
95
|
+
preview: 'N/A',
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
const first = entries[0];
|
|
99
|
+
const last = entries[entries.length - 1];
|
|
100
|
+
const userMessages = entries.filter((e) => e.type === 'user');
|
|
101
|
+
const firstUserMsg = userMessages[0]?.message?.content;
|
|
102
|
+
return {
|
|
103
|
+
startTime: first?.timestamp ?? 'unknown',
|
|
104
|
+
endTime: last?.timestamp ?? 'unknown',
|
|
105
|
+
cwd: first?.cwd ?? 'unknown',
|
|
106
|
+
branch: first?.gitBranch ?? 'unknown',
|
|
107
|
+
messageCount: entries.length,
|
|
108
|
+
userMessageCount: userMessages.length,
|
|
109
|
+
preview: typeof firstUserMsg === 'string' ? firstUserMsg.substring(0, 200) : 'N/A',
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
// ── Discovery ───────────────────────────────────────────────────────────────
|
|
113
|
+
/**
|
|
114
|
+
* Discover all project directories under ~/.claude/projects/
|
|
115
|
+
*/
|
|
116
|
+
export function getProjectDirs() {
|
|
117
|
+
const { projectsDir } = getConfig();
|
|
118
|
+
if (!fs.existsSync(projectsDir))
|
|
119
|
+
return [];
|
|
120
|
+
return fs
|
|
121
|
+
.readdirSync(projectsDir, { withFileTypes: true })
|
|
122
|
+
.filter((d) => d.isDirectory())
|
|
123
|
+
.map((d) => ({
|
|
124
|
+
name: d.name,
|
|
125
|
+
path: path.join(projectsDir, d.name),
|
|
126
|
+
}));
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* List all .jsonl session files in a given project directory.
|
|
130
|
+
*/
|
|
131
|
+
export function getSessionFiles(projectPath) {
|
|
132
|
+
if (!fs.existsSync(projectPath))
|
|
133
|
+
return [];
|
|
134
|
+
return fs
|
|
135
|
+
.readdirSync(projectPath)
|
|
136
|
+
.filter((f) => f.endsWith('.jsonl'))
|
|
137
|
+
.map((f) => ({
|
|
138
|
+
id: f.replace('.jsonl', ''),
|
|
139
|
+
file: path.join(projectPath, f),
|
|
140
|
+
}));
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/sessions/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { SearchResult } from '../search/types.js';
|
|
2
|
+
export type SearchScope = 'errors' | 'plans' | 'configs' | 'tools' | 'files' | 'decisions' | 'all';
|
|
3
|
+
export interface ScopedSearchOptions {
|
|
4
|
+
project?: string;
|
|
5
|
+
maxResults?: number;
|
|
6
|
+
semantic?: boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Perform a search scoped to a specific category of content.
|
|
10
|
+
*
|
|
11
|
+
* Each scope pre-filters messages by role/content patterns, then applies TF-IDF
|
|
12
|
+
* ranking with the user query on the remaining messages. When semantic search
|
|
13
|
+
* is available, blends vector similarity with TF-IDF scores.
|
|
14
|
+
*/
|
|
15
|
+
export declare function scopedSearch(scope: SearchScope, query: string, options?: ScopedSearchOptions): Promise<SearchResult[]>;
|
|
16
|
+
//# sourceMappingURL=scopes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scopes.d.ts","sourceRoot":"","sources":["../../src/sessions/scopes.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAOvD,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,WAAW,GAAG,KAAK,CAAC;AAEnG,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA8BD;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,YAAY,EAAE,CAAC,CAuIzB"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { getProjectDirs, getSessionFiles, parseSessionFile, extractMessages, getSessionMeta, } from './parser.js';
|
|
2
|
+
import { TfIdfIndex, recencyDecay } from '../search/tfidf.js';
|
|
3
|
+
import { buildExcerpt } from '../search/excerpt.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
|
+
// ── Scope pattern definitions ───────────────────────────────────────────────
|
|
16
|
+
const SCOPE_PATTERNS = {
|
|
17
|
+
errors: /\b(error|exception|failed|failure|crash|stack\s*trace|ENOENT|EACCES|EPERM|ECONNREFUSED|TypeError|ReferenceError|SyntaxError|FATAL|panic|segfault|abort|unhandled|rejected)\b/i,
|
|
18
|
+
plans: /\b(plan|step\s+\d|phase|approach|strategy|TODO|FIXME|architecture|roadmap|milestone|objective|next\s+steps|action\s+items)\b/i,
|
|
19
|
+
configs: /\b(config|settings|\.env|\.json|\.yaml|\.yml|\.toml|tsconfig|package\.json|webpack|vite|eslint|prettier|docker|compose|nginx)\b/i,
|
|
20
|
+
files: /(?:src\/|lib\/|dist\/|\.ts\b|\.js\b|\.py\b|\.rs\b|\.go\b|\.java\b|\.vue\b|\.tsx\b|\.jsx\b|\/[\w.-]+\/|created|modified|deleted|renamed|moved)\b/i,
|
|
21
|
+
decisions: /\b(decided|chose|chosen|because|tradeoff|trade-off|instead\s+of|going\s+with|opted\s+for|rationale|reasoning|prefer|alternative|pros\s+and\s+cons|conclusion)\b/i,
|
|
22
|
+
};
|
|
23
|
+
// ── Scoped search ───────────────────────────────────────────────────────────
|
|
24
|
+
/**
|
|
25
|
+
* Perform a search scoped to a specific category of content.
|
|
26
|
+
*
|
|
27
|
+
* Each scope pre-filters messages by role/content patterns, then applies TF-IDF
|
|
28
|
+
* ranking with the user query on the remaining messages. When semantic search
|
|
29
|
+
* is available, blends vector similarity with TF-IDF scores.
|
|
30
|
+
*/
|
|
31
|
+
export async function scopedSearch(scope, query, options = {}) {
|
|
32
|
+
const { project, maxResults = 20, semantic = true } = options;
|
|
33
|
+
const projects = getProjectDirs().filter((p) => !project || p.name.toLowerCase().includes(project.toLowerCase()));
|
|
34
|
+
const index = new TfIdfIndex();
|
|
35
|
+
const docMap = new Map();
|
|
36
|
+
let docCounter = 0;
|
|
37
|
+
for (const proj of projects) {
|
|
38
|
+
const sessions = getSessionFiles(proj.path);
|
|
39
|
+
for (const sess of sessions) {
|
|
40
|
+
try {
|
|
41
|
+
const entries = parseSessionFile(sess.file);
|
|
42
|
+
if (entries.length === 0)
|
|
43
|
+
continue;
|
|
44
|
+
const meta = getSessionMeta(entries);
|
|
45
|
+
const messages = extractMessages(entries);
|
|
46
|
+
const filtered = filterByScope(scope, messages);
|
|
47
|
+
for (const msg of filtered) {
|
|
48
|
+
const docId = `doc_${docCounter++}`;
|
|
49
|
+
index.addDocument(docId, msg.content);
|
|
50
|
+
docMap.set(docId, {
|
|
51
|
+
project: proj.name,
|
|
52
|
+
sessionId: sess.id,
|
|
53
|
+
role: msg.role,
|
|
54
|
+
timestamp: msg.timestamp,
|
|
55
|
+
content: msg.content,
|
|
56
|
+
sessionDate: meta.startTime,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// skip broken files
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const ranked = index.search(query, maxResults * 2);
|
|
66
|
+
const tfidfResults = ranked
|
|
67
|
+
.map(({ id, score }) => {
|
|
68
|
+
const doc = docMap.get(id);
|
|
69
|
+
if (!doc)
|
|
70
|
+
return null;
|
|
71
|
+
const excerpt = buildExcerpt(doc.content, query);
|
|
72
|
+
const ts = doc.timestamp ?? doc.sessionDate;
|
|
73
|
+
const decay = recencyDecay(ts);
|
|
74
|
+
const adjustedScore = score * decay;
|
|
75
|
+
return {
|
|
76
|
+
source: 'session',
|
|
77
|
+
id: doc.sessionId,
|
|
78
|
+
project: doc.project,
|
|
79
|
+
role: doc.role,
|
|
80
|
+
timestamp: ts,
|
|
81
|
+
excerpt,
|
|
82
|
+
score: adjustedScore,
|
|
83
|
+
metadata: {
|
|
84
|
+
scope,
|
|
85
|
+
sessionDate: doc.sessionDate,
|
|
86
|
+
relevanceScore: score,
|
|
87
|
+
recencyMultiplier: Math.round(decay * 100) / 100,
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
})
|
|
91
|
+
.filter((r) => r !== null);
|
|
92
|
+
tfidfResults.sort((a, b) => b.score - a.score);
|
|
93
|
+
const trimmedTfidf = tfidfResults.slice(0, maxResults);
|
|
94
|
+
if (!semantic) {
|
|
95
|
+
return trimmedTfidf;
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
const provider = await getEmbeddingProvider();
|
|
99
|
+
if (!provider)
|
|
100
|
+
return trimmedTfidf;
|
|
101
|
+
const queryVector = await provider.embedOne(query);
|
|
102
|
+
const store = getVectorStore();
|
|
103
|
+
const vectorResults = store.searchBySource(queryVector, 'session', maxResults * 2);
|
|
104
|
+
if (vectorResults.length === 0)
|
|
105
|
+
return trimmedTfidf;
|
|
106
|
+
const config = getConfig();
|
|
107
|
+
const alpha = config.embeddingAlpha;
|
|
108
|
+
const semanticScores = new Map();
|
|
109
|
+
for (const vr of vectorResults) {
|
|
110
|
+
const existing = semanticScores.get(vr.sourceId) ?? 0;
|
|
111
|
+
if (vr.score > existing) {
|
|
112
|
+
semanticScores.set(vr.sourceId, vr.score);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const maxTfidf = trimmedTfidf.length > 0 ? Math.max(...trimmedTfidf.map((r) => r.score)) : 1;
|
|
116
|
+
const normFactor = maxTfidf > 0 ? maxTfidf : 1;
|
|
117
|
+
const results = trimmedTfidf.map((result) => {
|
|
118
|
+
const normalizedTfidf = result.score / normFactor;
|
|
119
|
+
const semanticScore = semanticScores.get(result.id) ?? 0;
|
|
120
|
+
const blended = alpha * normalizedTfidf + (1 - alpha) * semanticScore;
|
|
121
|
+
const ts = result.timestamp ?? result.metadata?.sessionDate;
|
|
122
|
+
const decay = ts ? recencyDecay(ts) : 1;
|
|
123
|
+
const finalScore = blended * decay;
|
|
124
|
+
return {
|
|
125
|
+
...result,
|
|
126
|
+
score: finalScore,
|
|
127
|
+
metadata: {
|
|
128
|
+
...result.metadata,
|
|
129
|
+
tfidfScore: normalizedTfidf,
|
|
130
|
+
semanticScore,
|
|
131
|
+
blendAlpha: alpha,
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
});
|
|
135
|
+
results.sort((a, b) => b.score - a.score);
|
|
136
|
+
return results.slice(0, maxResults);
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return trimmedTfidf;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// ── Scope filters ───────────────────────────────────────────────────────────
|
|
143
|
+
function filterByScope(scope, messages) {
|
|
144
|
+
if (scope === 'all') {
|
|
145
|
+
return messages;
|
|
146
|
+
}
|
|
147
|
+
if (scope === 'tools') {
|
|
148
|
+
return messages.filter((m) => m.role === 'tool_use' || m.role === 'tool_result');
|
|
149
|
+
}
|
|
150
|
+
const pattern = SCOPE_PATTERNS[scope];
|
|
151
|
+
return messages.filter((m) => pattern.test(m.content));
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=scopes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scopes.js","sourceRoot":"","sources":["../../src/sessions/scopes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { SearchResult } from '../search/types.js';
|
|
2
|
+
export interface SearchSessionOptions {
|
|
3
|
+
project?: string;
|
|
4
|
+
role?: 'user' | 'assistant' | 'all';
|
|
5
|
+
caseSensitive?: boolean;
|
|
6
|
+
maxResults?: number;
|
|
7
|
+
/** When true (default), use TF-IDF ranking. When false, use regex matching. */
|
|
8
|
+
ranked?: boolean;
|
|
9
|
+
/** When true (default when embeddings available), blend semantic similarity with TF-IDF. */
|
|
10
|
+
semantic?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Search across all session transcripts.
|
|
14
|
+
*
|
|
15
|
+
* Supports three modes:
|
|
16
|
+
* - **hybrid** (default when embeddings available): blends TF-IDF ranking
|
|
17
|
+
* with semantic vector similarity using configurable alpha weighting.
|
|
18
|
+
* - **ranked** (default fallback): builds a TF-IDF index over all messages,
|
|
19
|
+
* returns results ordered by relevance score.
|
|
20
|
+
* - **legacy** (`ranked: false`): regex-based matching, faster for exact
|
|
21
|
+
* phrases and pattern searches.
|
|
22
|
+
*
|
|
23
|
+
* Returns results with excerpts (100 chars before + 100 chars after match).
|
|
24
|
+
*/
|
|
25
|
+
export declare function searchSessions(query: string, options?: SearchSessionOptions): Promise<SearchResult[]>;
|
|
26
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/sessions/search.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAKvD,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,KAAK,CAAC;IACpC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+EAA+E;IAC/E,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,4FAA4F;IAC5F,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAaD;;;;;;;;;;;;GAYG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,YAAY,EAAE,CAAC,CAoCzB"}
|