pi-recollect 0.1.1 → 0.3.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/README.md +73 -0
- package/dist/categories/memory-categories.d.ts +33 -0
- package/dist/categories/memory-categories.d.ts.map +1 -0
- package/dist/categories/memory-categories.js +61 -0
- package/dist/categories/memory-categories.js.map +1 -0
- package/dist/compound/analyzer.d.ts +15 -0
- package/dist/compound/analyzer.d.ts.map +1 -0
- package/dist/compound/analyzer.js +145 -0
- package/dist/compound/analyzer.js.map +1 -0
- package/dist/compound/dedup.d.ts +34 -0
- package/dist/compound/dedup.d.ts.map +1 -0
- package/dist/compound/dedup.js +80 -0
- package/dist/compound/dedup.js.map +1 -0
- package/dist/compound/extractor.d.ts +47 -0
- package/dist/compound/extractor.d.ts.map +1 -0
- package/dist/compound/extractor.js +82 -0
- package/dist/compound/extractor.js.map +1 -0
- package/dist/compound/router.d.ts +17 -0
- package/dist/compound/router.d.ts.map +1 -0
- package/dist/compound/router.js +64 -0
- package/dist/compound/router.js.map +1 -0
- package/dist/compound/writer.d.ts +21 -0
- package/dist/compound/writer.d.ts.map +1 -0
- package/dist/compound/writer.js +101 -0
- package/dist/compound/writer.js.map +1 -0
- package/dist/config.d.ts +37 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +66 -0
- package/dist/config.js.map +1 -0
- package/dist/context/context-saver.d.ts +96 -0
- package/dist/context/context-saver.d.ts.map +1 -0
- package/dist/context/context-saver.js +234 -0
- package/dist/context/context-saver.js.map +1 -0
- package/dist/continuity/compaction-hook.d.ts +12 -0
- package/dist/continuity/compaction-hook.d.ts.map +1 -0
- package/dist/continuity/compaction-hook.js +19 -0
- package/dist/continuity/compaction-hook.js.map +1 -0
- package/dist/continuity/resumer.d.ts +21 -0
- package/dist/continuity/resumer.d.ts.map +1 -0
- package/dist/continuity/resumer.js +91 -0
- package/dist/continuity/resumer.js.map +1 -0
- package/dist/continuity/tracker.d.ts +13 -0
- package/dist/continuity/tracker.d.ts.map +1 -0
- package/dist/continuity/tracker.js +24 -0
- package/dist/continuity/tracker.js.map +1 -0
- package/dist/extension/register.d.ts +3 -0
- package/dist/extension/register.d.ts.map +1 -0
- package/dist/extension/register.js +269 -0
- package/dist/extension/register.js.map +1 -0
- package/dist/graph/decay.d.ts +52 -0
- package/dist/graph/decay.d.ts.map +1 -0
- package/dist/graph/decay.js +99 -0
- package/dist/graph/decay.js.map +1 -0
- package/dist/graph/graph-store.d.ts +47 -0
- package/dist/graph/graph-store.d.ts.map +1 -0
- package/dist/graph/graph-store.js +107 -0
- package/dist/graph/graph-store.js.map +1 -0
- package/dist/graph/hash-id.d.ts +31 -0
- package/dist/graph/hash-id.d.ts.map +1 -0
- package/dist/graph/hash-id.js +51 -0
- package/dist/graph/hash-id.js.map +1 -0
- package/dist/graph/index.d.ts +8 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +8 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/memory-store.d.ts +55 -0
- package/dist/graph/memory-store.d.ts.map +1 -0
- package/dist/graph/memory-store.js +213 -0
- package/dist/graph/memory-store.js.map +1 -0
- package/{index.ts → dist/index.d.ts} +2 -5
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/memory/hierarchical.d.ts +19 -0
- package/dist/memory/hierarchical.d.ts.map +1 -0
- package/dist/memory/hierarchical.js +103 -0
- package/dist/memory/hierarchical.js.map +1 -0
- package/dist/memory/mental-models.d.ts +32 -0
- package/dist/memory/mental-models.d.ts.map +1 -0
- package/dist/memory/mental-models.js +100 -0
- package/dist/memory/mental-models.js.map +1 -0
- package/dist/memory/recall.d.ts +19 -0
- package/dist/memory/recall.d.ts.map +1 -0
- package/dist/memory/recall.js +88 -0
- package/dist/memory/recall.js.map +1 -0
- package/dist/memory/reflect.d.ts +10 -0
- package/dist/memory/reflect.d.ts.map +1 -0
- package/dist/memory/reflect.js +21 -0
- package/dist/memory/reflect.js.map +1 -0
- package/dist/memory/retain.d.ts +23 -0
- package/dist/memory/retain.d.ts.map +1 -0
- package/dist/memory/retain.js +61 -0
- package/dist/memory/retain.js.map +1 -0
- package/dist/store/events.d.ts +29 -0
- package/dist/store/events.d.ts.map +1 -0
- package/dist/store/events.js +33 -0
- package/dist/store/events.js.map +1 -0
- package/dist/store/fts5-index.d.ts +10 -0
- package/dist/store/fts5-index.d.ts.map +1 -0
- package/dist/store/fts5-index.js +19 -0
- package/dist/store/fts5-index.js.map +1 -0
- package/dist/store/schema.d.ts +7 -0
- package/dist/store/schema.d.ts.map +1 -0
- package/{src/store/schema.ts → dist/store/schema.js} +32 -41
- package/dist/store/schema.js.map +1 -0
- package/dist/store/search.d.ts +21 -0
- package/dist/store/search.d.ts.map +1 -0
- package/dist/store/search.js +160 -0
- package/dist/store/search.js.map +1 -0
- package/dist/store/sqlite.d.ts +20 -0
- package/dist/store/sqlite.d.ts.map +1 -0
- package/dist/store/sqlite.js +50 -0
- package/dist/store/sqlite.js.map +1 -0
- package/dist/store/vocabulary.d.ts +15 -0
- package/dist/store/vocabulary.d.ts.map +1 -0
- package/dist/store/vocabulary.js +26 -0
- package/dist/store/vocabulary.js.map +1 -0
- package/dist/tools/memory-recall.d.ts +10 -0
- package/dist/tools/memory-recall.d.ts.map +1 -0
- package/dist/tools/memory-recall.js +11 -0
- package/dist/tools/memory-recall.js.map +1 -0
- package/dist/tools/memory-search.d.ts +21 -0
- package/dist/tools/memory-search.d.ts.map +1 -0
- package/dist/tools/memory-search.js +33 -0
- package/dist/tools/memory-search.js.map +1 -0
- package/dist/tools/memory-status.d.ts +18 -0
- package/dist/tools/memory-status.d.ts.map +1 -0
- package/dist/tools/memory-status.js +84 -0
- package/dist/tools/memory-status.js.map +1 -0
- package/dist/tools/memory-store.d.ts +16 -0
- package/dist/tools/memory-store.d.ts.map +1 -0
- package/dist/tools/memory-store.js +17 -0
- package/dist/tools/memory-store.js.map +1 -0
- package/dist/trace/correlation.d.ts +111 -0
- package/dist/trace/correlation.d.ts.map +1 -0
- package/dist/trace/correlation.js +234 -0
- package/dist/trace/correlation.js.map +1 -0
- package/package.json +26 -39
- package/skills/compound-note/skill.md +0 -32
- package/skills/memory-search/skill.md +0 -24
- package/skills/memory-store/skill.md +0 -26
- package/src/compound/analyzer.ts +0 -170
- package/src/compound/dedup.ts +0 -111
- package/src/compound/extractor.ts +0 -110
- package/src/compound/router.ts +0 -82
- package/src/compound/writer.ts +0 -110
- package/src/config.ts +0 -114
- package/src/continuity/compaction-hook.ts +0 -32
- package/src/continuity/resumer.ts +0 -104
- package/src/continuity/tracker.ts +0 -36
- package/src/extension/register.ts +0 -279
- package/src/memory/hierarchical.ts +0 -122
- package/src/memory/mental-models.ts +0 -141
- package/src/memory/recall.ts +0 -110
- package/src/memory/reflect.ts +0 -32
- package/src/memory/retain.ts +0 -77
- package/src/store/events.ts +0 -61
- package/src/store/fts5-index.ts +0 -32
- package/src/store/search.ts +0 -222
- package/src/store/sqlite.ts +0 -53
- package/src/store/vocabulary.ts +0 -34
- package/src/tools/memory-recall.ts +0 -17
- package/src/tools/memory-search.ts +0 -56
- package/src/tools/memory-status.ts +0 -113
- package/src/tools/memory-store.ts +0 -30
- package/tsconfig.json +0 -19
package/README.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# pi-recollect
|
|
2
|
+
|
|
3
|
+
Memory and context management extension for coding agents.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Graph Memory** - Hash-based ID memory with dependencies
|
|
8
|
+
- **Context Compaction** - Session compaction for long conversations
|
|
9
|
+
- **Memory Decay** - Semantic summarization of old content
|
|
10
|
+
- **Progressive Disclosure** - Layered context presentation
|
|
11
|
+
- **Session Continuity** - Seamless session recovery
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install pi-recollect
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
### Commands
|
|
22
|
+
|
|
23
|
+
- `/remember [insight]` - Store insight in graph memory
|
|
24
|
+
- `/recall [topic]` - Recall related memories
|
|
25
|
+
- `/compact` - Compact session context
|
|
26
|
+
- `/forget [id]` - Remove from memory
|
|
27
|
+
|
|
28
|
+
### Graph Store
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { createGraphStore, generateHashId } from 'pi-recollect';
|
|
32
|
+
|
|
33
|
+
const store = createGraphStore();
|
|
34
|
+
|
|
35
|
+
// Add memory node
|
|
36
|
+
const node = store.addNode({
|
|
37
|
+
type: 'insight',
|
|
38
|
+
title: 'Important finding',
|
|
39
|
+
content: '...',
|
|
40
|
+
relations: [{ type: 'relates_to', targetId: otherNode.id }],
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Query memories
|
|
44
|
+
const insights = store.query({ type: 'insight', closed: false });
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Architecture
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
src/
|
|
51
|
+
├── graph/
|
|
52
|
+
│ ├── graph-store.ts # Graph memory
|
|
53
|
+
│ ├── hash-id.ts # Hash-based IDs
|
|
54
|
+
│ ├── memory-store.ts # Memory persistence
|
|
55
|
+
│ └── decay.ts # Memory decay
|
|
56
|
+
├── context/
|
|
57
|
+
│ └── context-saver.ts # Context management
|
|
58
|
+
├── session/
|
|
59
|
+
│ └── session-continuity.ts
|
|
60
|
+
└── index.ts
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Patterns Applied
|
|
64
|
+
|
|
65
|
+
- Hash-based IDs from beads
|
|
66
|
+
- Graph memory from beads
|
|
67
|
+
- Memory categories from pi-hermes-memory
|
|
68
|
+
- Context compaction from oh-my-pi
|
|
69
|
+
- Memory decay from beads
|
|
70
|
+
|
|
71
|
+
## License
|
|
72
|
+
|
|
73
|
+
MIT
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory Categories - Pattern from pi-hermes-memory
|
|
3
|
+
*
|
|
4
|
+
* Standardized memory types for organizing persistent knowledge.
|
|
5
|
+
*/
|
|
6
|
+
export type MemoryCategory = 'observation' | 'summary' | 'decision' | 'pattern' | 'task' | 'failure' | 'correction' | 'insight' | 'preference' | 'convention' | 'tool-quirk';
|
|
7
|
+
export interface CategorizedMemory {
|
|
8
|
+
category: MemoryCategory;
|
|
9
|
+
content: string;
|
|
10
|
+
failureReason?: string;
|
|
11
|
+
toolState?: string;
|
|
12
|
+
correctedTo?: string;
|
|
13
|
+
created: string;
|
|
14
|
+
lastReferenced: string;
|
|
15
|
+
}
|
|
16
|
+
export declare const MEMORY_CATEGORY_DESCRIPTIONS: Record<MemoryCategory, string>;
|
|
17
|
+
export declare const CATEGORY_COLORS: Record<MemoryCategory, string>;
|
|
18
|
+
/**
|
|
19
|
+
* Format memory content with category tag
|
|
20
|
+
*/
|
|
21
|
+
export declare function formatMemoryContent(content: string, category: MemoryCategory, options?: {
|
|
22
|
+
failureReason?: string;
|
|
23
|
+
toolState?: string;
|
|
24
|
+
correctedTo?: string;
|
|
25
|
+
}): string;
|
|
26
|
+
/**
|
|
27
|
+
* Parse category from memory text
|
|
28
|
+
*/
|
|
29
|
+
export declare function parseCategory(text: string): {
|
|
30
|
+
category: MemoryCategory | null;
|
|
31
|
+
content: string;
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=memory-categories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-categories.d.ts","sourceRoot":"","sources":["../../src/categories/memory-categories.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,MAAM,cAAc,GACtB,aAAa,GACb,SAAS,GACT,UAAU,GACV,SAAS,GACT,MAAM,GACN,SAAS,GACT,YAAY,GACZ,SAAS,GACT,YAAY,GACZ,YAAY,GACZ,YAAY,CAAC;AAEjB,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,cAAc,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,4BAA4B,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAYvE,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAY1D,CAAC;AAEF;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,cAAc,EACxB,OAAO,CAAC,EAAE;IACR,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GACA,MAAM,CAcR;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAShG"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory Categories - Pattern from pi-hermes-memory
|
|
3
|
+
*
|
|
4
|
+
* Standardized memory types for organizing persistent knowledge.
|
|
5
|
+
*/
|
|
6
|
+
export const MEMORY_CATEGORY_DESCRIPTIONS = {
|
|
7
|
+
observation: 'General observations and facts',
|
|
8
|
+
summary: 'Summarized information',
|
|
9
|
+
decision: 'Decisions made during work',
|
|
10
|
+
pattern: 'Recurring patterns identified',
|
|
11
|
+
task: 'Task-related memories',
|
|
12
|
+
failure: 'What was tried but did not work',
|
|
13
|
+
correction: 'User corrections to agent behavior',
|
|
14
|
+
insight: 'Learning from experience',
|
|
15
|
+
preference: 'User preferences and style',
|
|
16
|
+
convention: 'Project conventions and standards',
|
|
17
|
+
'tool-quirk': 'Tool-specific behavior and quirks',
|
|
18
|
+
};
|
|
19
|
+
export const CATEGORY_COLORS = {
|
|
20
|
+
observation: '🔵',
|
|
21
|
+
summary: '📝',
|
|
22
|
+
decision: '✅',
|
|
23
|
+
pattern: '🔄',
|
|
24
|
+
task: '📋',
|
|
25
|
+
failure: '❌',
|
|
26
|
+
correction: '🔧',
|
|
27
|
+
insight: '💡',
|
|
28
|
+
preference: '❤️',
|
|
29
|
+
convention: '📐',
|
|
30
|
+
'tool-quirk': '🔧',
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Format memory content with category tag
|
|
34
|
+
*/
|
|
35
|
+
export function formatMemoryContent(content, category, options) {
|
|
36
|
+
const parts = [`[${category}] ${content.trim()}`];
|
|
37
|
+
if (options?.failureReason) {
|
|
38
|
+
parts.push(`Failed: ${options.failureReason}`);
|
|
39
|
+
}
|
|
40
|
+
if (options?.toolState) {
|
|
41
|
+
parts.push(`Tool state: ${options.toolState}`);
|
|
42
|
+
}
|
|
43
|
+
if (options?.correctedTo) {
|
|
44
|
+
parts.push(`Corrected to: ${options.correctedTo}`);
|
|
45
|
+
}
|
|
46
|
+
return parts.join(' — ');
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Parse category from memory text
|
|
50
|
+
*/
|
|
51
|
+
export function parseCategory(text) {
|
|
52
|
+
const match = text.match(/^\[([^\]]+)\]\s+(.*)$/);
|
|
53
|
+
if (match) {
|
|
54
|
+
const category = match[1];
|
|
55
|
+
if (MEMORY_CATEGORY_DESCRIPTIONS[category]) {
|
|
56
|
+
return { category, content: match[2] };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return { category: null, content: text };
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=memory-categories.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-categories.js","sourceRoot":"","sources":["../../src/categories/memory-categories.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAyBH,MAAM,CAAC,MAAM,4BAA4B,GAAmC;IAC1E,WAAW,EAAE,gCAAgC;IAC7C,OAAO,EAAE,wBAAwB;IACjC,QAAQ,EAAE,4BAA4B;IACtC,OAAO,EAAE,+BAA+B;IACxC,IAAI,EAAE,uBAAuB;IAC7B,OAAO,EAAE,iCAAiC;IAC1C,UAAU,EAAE,oCAAoC;IAChD,OAAO,EAAE,0BAA0B;IACnC,UAAU,EAAE,4BAA4B;IACxC,UAAU,EAAE,mCAAmC;IAC/C,YAAY,EAAE,mCAAmC;CAClD,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAmC;IAC7D,WAAW,EAAE,IAAI;IACjB,OAAO,EAAE,IAAI;IACb,QAAQ,EAAE,GAAG;IACb,OAAO,EAAE,IAAI;IACb,IAAI,EAAE,IAAI;IACV,OAAO,EAAE,GAAG;IACZ,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,IAAI;IAChB,UAAU,EAAE,IAAI;IAChB,YAAY,EAAE,IAAI;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,OAAe,EACf,QAAwB,EACxB,OAIC;IAED,MAAM,KAAK,GAAa,CAAC,IAAI,QAAQ,KAAK,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAE5D,IAAI,OAAO,EAAE,aAAa,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,WAAW,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IACjD,CAAC;IACD,IAAI,OAAO,EAAE,SAAS,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,eAAe,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACjD,CAAC;IACD,IAAI,OAAO,EAAE,WAAW,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,iBAAiB,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAClD,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAmB,CAAC;QAC5C,IAAI,4BAA4B,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3C,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACzC,CAAC;IACH,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type Database from "better-sqlite3";
|
|
2
|
+
export interface AnalysisResult {
|
|
3
|
+
solutionsFound: number;
|
|
4
|
+
solutionsWritten: number;
|
|
5
|
+
duplicatesMerged: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Analyze a session at shutdown time:
|
|
9
|
+
* 1. Extract findings from session events
|
|
10
|
+
* 2. Route findings to bug/knowledge/decision types
|
|
11
|
+
* 3. Dedup against existing solutions
|
|
12
|
+
* 4. Write new solutions
|
|
13
|
+
*/
|
|
14
|
+
export declare function analyzeSession(db: Database.Database, cwd: string, sessionId: string, dedupThreshold?: number): AnalysisResult;
|
|
15
|
+
//# sourceMappingURL=analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../../src/compound/analyzer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAQ3C,MAAM,WAAW,cAAc;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC7B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,cAAc,GAAE,MAAY,GAC1B,cAAc,CAoDhB"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import * as crypto from "node:crypto";
|
|
2
|
+
import { getSessionEvents } from "../store/events.ts";
|
|
3
|
+
import { routeSessionFindings } from "./router.ts";
|
|
4
|
+
import { extractBugSolution, extractDecision, extractKnowledge } from "./extractor.ts";
|
|
5
|
+
import { findPotentialDuplicates, assessOverlap, shouldDedup } from "./dedup.ts";
|
|
6
|
+
import { writeSolution } from "./writer.ts";
|
|
7
|
+
import { indexContent } from "../store/fts5-index.ts";
|
|
8
|
+
/**
|
|
9
|
+
* Analyze a session at shutdown time:
|
|
10
|
+
* 1. Extract findings from session events
|
|
11
|
+
* 2. Route findings to bug/knowledge/decision types
|
|
12
|
+
* 3. Dedup against existing solutions
|
|
13
|
+
* 4. Write new solutions
|
|
14
|
+
*/
|
|
15
|
+
export function analyzeSession(db, cwd, sessionId, dedupThreshold = 0.7) {
|
|
16
|
+
const events = getSessionEvents(db, sessionId);
|
|
17
|
+
if (events.length === 0)
|
|
18
|
+
return { solutionsFound: 0, solutionsWritten: 0, duplicatesMerged: 0 };
|
|
19
|
+
const findings = routeSessionFindings(events);
|
|
20
|
+
let solutionsFound = 0;
|
|
21
|
+
let solutionsWritten = 0;
|
|
22
|
+
let duplicatesMerged = 0;
|
|
23
|
+
for (const finding of findings) {
|
|
24
|
+
const solution = extractSolution(finding);
|
|
25
|
+
if (!solution)
|
|
26
|
+
continue;
|
|
27
|
+
solutionsFound++;
|
|
28
|
+
const title = buildTitle(finding, finding.events);
|
|
29
|
+
const solForDedup = {
|
|
30
|
+
title,
|
|
31
|
+
content: solutionContent(solution),
|
|
32
|
+
files: solution.files,
|
|
33
|
+
tags: solution.tags,
|
|
34
|
+
};
|
|
35
|
+
// Check for duplicates
|
|
36
|
+
const dupes = findPotentialDuplicates(db, title);
|
|
37
|
+
let isDuplicate = false;
|
|
38
|
+
for (const dupe of dupes) {
|
|
39
|
+
const dupeForCompare = {
|
|
40
|
+
title: dupe.title,
|
|
41
|
+
content: dupe.content,
|
|
42
|
+
files: dupe.files ? JSON.parse(dupe.files) : [],
|
|
43
|
+
tags: dupe.tags ? JSON.parse(dupe.tags) : [],
|
|
44
|
+
};
|
|
45
|
+
const overlap = assessOverlap(solForDedup, dupeForCompare);
|
|
46
|
+
if (shouldDedup(overlap, dedupThreshold)) {
|
|
47
|
+
isDuplicate = true;
|
|
48
|
+
duplicatesMerged++;
|
|
49
|
+
// Increment access count on the existing solution
|
|
50
|
+
db.prepare(`UPDATE solutions SET access_count = access_count + 1, last_accessed_at = ? WHERE title = ?`).run(new Date().toISOString(), dupe.title);
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (!isDuplicate) {
|
|
55
|
+
writeSolutionToDb(db, title, solution);
|
|
56
|
+
writeSolution(cwd, solution, title);
|
|
57
|
+
solutionsWritten++;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return { solutionsFound, solutionsWritten, duplicatesMerged };
|
|
61
|
+
}
|
|
62
|
+
function extractSolution(finding) {
|
|
63
|
+
const events = finding.events;
|
|
64
|
+
switch (finding.type) {
|
|
65
|
+
case "bug": {
|
|
66
|
+
const error = events.find((e) => e.type === "error");
|
|
67
|
+
const fix = events.find((e) => e.type === "command_success") ?? null;
|
|
68
|
+
if (!error)
|
|
69
|
+
return null;
|
|
70
|
+
return extractBugSolution(error, fix);
|
|
71
|
+
}
|
|
72
|
+
case "decision": {
|
|
73
|
+
const decision = events.find((e) => e.type === "user_decision");
|
|
74
|
+
if (!decision)
|
|
75
|
+
return null;
|
|
76
|
+
return extractDecision(decision);
|
|
77
|
+
}
|
|
78
|
+
case "knowledge":
|
|
79
|
+
return extractKnowledge(events);
|
|
80
|
+
default:
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function buildTitle(finding, events) {
|
|
85
|
+
switch (finding.type) {
|
|
86
|
+
case "bug": {
|
|
87
|
+
const error = events.find((e) => e.type === "error");
|
|
88
|
+
if (!error)
|
|
89
|
+
return "Unknown bug";
|
|
90
|
+
try {
|
|
91
|
+
const data = JSON.parse(error.data);
|
|
92
|
+
const msg = typeof data.errorMessage === "string" ? data.errorMessage : "error";
|
|
93
|
+
return msg.slice(0, 80);
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return "Unknown bug";
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
case "decision": {
|
|
100
|
+
const d = events.find((e) => e.type === "user_decision");
|
|
101
|
+
if (!d)
|
|
102
|
+
return "Decision";
|
|
103
|
+
try {
|
|
104
|
+
const data = JSON.parse(d.data);
|
|
105
|
+
return typeof data.message_summary === "string" ? data.message_summary.slice(0, 80) : "Decision";
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return "Decision";
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
case "knowledge": {
|
|
112
|
+
const files = events
|
|
113
|
+
.map((e) => { try {
|
|
114
|
+
return JSON.parse(e.data).file;
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return "";
|
|
118
|
+
} })
|
|
119
|
+
.filter((f) => f.length > 0);
|
|
120
|
+
return files.length > 0 ? `Pattern: ${files.join(", ")}` : "Knowledge pattern";
|
|
121
|
+
}
|
|
122
|
+
default:
|
|
123
|
+
return "Unknown finding";
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function solutionContent(solution) {
|
|
127
|
+
switch (solution.type) {
|
|
128
|
+
case "bug": return `${solution.problem}\n${solution.rootCause}\n${solution.fix}`;
|
|
129
|
+
case "knowledge": return `${solution.whenToUse}\n${solution.how}`;
|
|
130
|
+
case "decision": return `${solution.context}\n${solution.reasoning}`;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function writeSolutionToDb(db, title, solution) {
|
|
134
|
+
const id = crypto.randomUUID();
|
|
135
|
+
const now = new Date().toISOString();
|
|
136
|
+
const content = solutionContent(solution);
|
|
137
|
+
const overlapHash = crypto.createHash("sha256").update(title + content).digest("hex");
|
|
138
|
+
db.prepare(`
|
|
139
|
+
INSERT INTO solutions (id, problem_type, category, title, content, files, tags, severity, overlap_hash, created_at, updated_at)
|
|
140
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
141
|
+
`).run(id, solution.type, solution.type, title, content, JSON.stringify(solution.files), JSON.stringify(solution.tags), "medium", overlapHash, now, now);
|
|
142
|
+
// Index for search
|
|
143
|
+
indexContent(db, id, title, content, solution.type);
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../../src/compound/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AAEtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAsB,MAAM,aAAa,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,gBAAgB,EAAiB,MAAM,gBAAgB,CAAC;AACtG,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,WAAW,EAAyB,MAAM,YAAY,CAAC;AACxG,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAQtD;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAC7B,EAAqB,EACrB,GAAW,EACX,SAAiB,EACjB,iBAAyB,GAAG;IAE5B,MAAM,MAAM,GAAG,gBAAgB,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;IAC/C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,cAAc,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC;IAEhG,MAAM,QAAQ,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC9C,IAAI,cAAc,GAAG,CAAC,CAAC;IACvB,IAAI,gBAAgB,GAAG,CAAC,CAAC;IACzB,IAAI,gBAAgB,GAAG,CAAC,CAAC;IAEzB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;QAC1C,IAAI,CAAC,QAAQ;YAAE,SAAS;QACxB,cAAc,EAAE,CAAC;QAEjB,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,WAAW,GAAqB;YACrC,KAAK;YACL,OAAO,EAAE,eAAe,CAAC,QAAQ,CAAC;YAClC,KAAK,EAAE,QAAQ,CAAC,KAAK;YACrB,IAAI,EAAE,QAAQ,CAAC,IAAI;SACnB,CAAC;QAEF,uBAAuB;QACvB,MAAM,KAAK,GAAG,uBAAuB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QACjD,IAAI,WAAW,GAAG,KAAK,CAAC;QACxB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YAC1B,MAAM,cAAc,GAAqB;gBACxC,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAa,CAAC,CAAC,CAAC,EAAE;gBAC3D,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAa,CAAC,CAAC,CAAC,EAAE;aACxD,CAAC;YACF,MAAM,OAAO,GAAG,aAAa,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;YAC3D,IAAI,WAAW,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE,CAAC;gBAC1C,WAAW,GAAG,IAAI,CAAC;gBACnB,gBAAgB,EAAE,CAAC;gBACnB,kDAAkD;gBAClD,EAAE,CAAC,OAAO,CACT,4FAA4F,CAC5F,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC5C,MAAM;YACP,CAAC;QACF,CAAC;QAED,IAAI,CAAC,WAAW,EAAE,CAAC;YAClB,iBAAiB,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;YACvC,aAAa,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;YACpC,gBAAgB,EAAE,CAAC;QACpB,CAAC;IACF,CAAC;IAED,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;AAC/D,CAAC;AAED,SAAS,eAAe,CAAC,OAAsB;IAC9C,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACtB,KAAK,KAAK,CAAC,CAAC,CAAC;YACZ,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;YACrD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,iBAAiB,CAAC,IAAI,IAAI,CAAC;YACrE,IAAI,CAAC,KAAK;gBAAE,OAAO,IAAI,CAAC;YACxB,OAAO,kBAAkB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACvC,CAAC;QACD,KAAK,UAAU,CAAC,CAAC,CAAC;YACjB,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC;YAChE,IAAI,CAAC,QAAQ;gBAAE,OAAO,IAAI,CAAC;YAC3B,OAAO,eAAe,CAAC,QAAQ,CAAC,CAAC;QAClC,CAAC;QACD,KAAK,WAAW;YACf,OAAO,gBAAgB,CAAC,MAAM,CAAC,CAAC;QACjC;YACC,OAAO,IAAI,CAAC;IACd,CAAC;AACF,CAAC;AAED,SAAS,UAAU,CAAC,OAAsB,EAAE,MAA6B;IACxE,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACtB,KAAK,KAAK,CAAC,CAAC,CAAC;YACZ,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;YACrD,IAAI,CAAC,KAAK;gBAAE,OAAO,aAAa,CAAC;YACjC,IAAI,CAAC;gBACJ,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAA4B,CAAC;gBAC/D,MAAM,GAAG,GAAG,OAAO,IAAI,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC;gBAChF,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACzB,CAAC;YAAC,MAAM,CAAC;gBACR,OAAO,aAAa,CAAC;YACtB,CAAC;QACF,CAAC;QACD,KAAK,UAAU,CAAC,CAAC,CAAC;YACjB,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC;YACzD,IAAI,CAAC,CAAC;gBAAE,OAAO,UAAU,CAAC;YAC1B,IAAI,CAAC;gBACJ,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAA4B,CAAC;gBAC3D,OAAO,OAAO,IAAI,CAAC,eAAe,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;YAClG,CAAC;YAAC,MAAM,CAAC;gBACR,OAAO,UAAU,CAAC;YACnB,CAAC;QACF,CAAC;QACD,KAAK,WAAW,CAAC,CAAC,CAAC;YAClB,MAAM,KAAK,GAAG,MAAM;iBAClB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC;gBAAC,OAAQ,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAA6B,CAAC,IAAc,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC;gBAAC,OAAO,EAAE,CAAC;YAAC,CAAC,CAAC,CAAC,CAAC;iBACnH,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAC9B,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,mBAAmB,CAAC;QAChF,CAAC;QACD;YACC,OAAO,iBAAiB,CAAC;IAC3B,CAAC;AACF,CAAC;AAED,SAAS,eAAe,CAAC,QAAkB;IAC1C,QAAQ,QAAQ,CAAC,IAAI,EAAE,CAAC;QACvB,KAAK,KAAK,CAAC,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,KAAK,QAAQ,CAAC,SAAS,KAAK,QAAQ,CAAC,GAAG,EAAE,CAAC;QACjF,KAAK,WAAW,CAAC,CAAC,OAAO,GAAG,QAAQ,CAAC,SAAS,KAAK,QAAQ,CAAC,GAAG,EAAE,CAAC;QAClE,KAAK,UAAU,CAAC,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,KAAK,QAAQ,CAAC,SAAS,EAAE,CAAC;IACtE,CAAC;AACF,CAAC;AAED,SAAS,iBAAiB,CAAC,EAAqB,EAAE,KAAa,EAAE,QAAkB;IAClF,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;IAC/B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,GAAG,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEtF,EAAE,CAAC,OAAO,CAAC;;;EAGV,CAAC,CAAC,GAAG,CACL,EAAE,EACF,QAAQ,CAAC,IAAI,EACb,QAAQ,CAAC,IAAI,EACb,KAAK,EACL,OAAO,EACP,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,EAC9B,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAC7B,QAAQ,EACR,WAAW,EACX,GAAG,EACH,GAAG,CACH,CAAC;IAEF,mBAAmB;IACnB,YAAY,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type Database from "better-sqlite3";
|
|
2
|
+
export interface OverlapAssessment {
|
|
3
|
+
problemOverlap: number;
|
|
4
|
+
rootCauseOverlap: number;
|
|
5
|
+
solutionOverlap: number;
|
|
6
|
+
filesOverlap: number;
|
|
7
|
+
preventionOverlap: number;
|
|
8
|
+
}
|
|
9
|
+
export interface SolutionForDedup {
|
|
10
|
+
title: string;
|
|
11
|
+
content: string;
|
|
12
|
+
files: string[];
|
|
13
|
+
tags: string[];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Assess overlap between a new solution and an existing solution.
|
|
17
|
+
* Uses token-based text similarity + file set intersection.
|
|
18
|
+
*/
|
|
19
|
+
export declare function assessOverlap(newSol: SolutionForDedup, existingSol: SolutionForDedup): OverlapAssessment;
|
|
20
|
+
/**
|
|
21
|
+
* Determine if two solutions are duplicates using weighted 5-dimension check.
|
|
22
|
+
*/
|
|
23
|
+
export declare function shouldDedup(overlap: OverlapAssessment, threshold?: number): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Find potential duplicates in the database using FTS5 search.
|
|
26
|
+
*/
|
|
27
|
+
export declare function findPotentialDuplicates(db: Database.Database, title: string): Array<{
|
|
28
|
+
id: string;
|
|
29
|
+
title: string;
|
|
30
|
+
content: string;
|
|
31
|
+
files: string;
|
|
32
|
+
tags: string;
|
|
33
|
+
}>;
|
|
34
|
+
//# sourceMappingURL=dedup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dedup.d.ts","sourceRoot":"","sources":["../../src/compound/dedup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAK3C,MAAM,WAAW,iBAAiB;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CACf;AAsCD;;;GAGG;AACH,wBAAgB,aAAa,CAC5B,MAAM,EAAE,gBAAgB,EACxB,WAAW,EAAE,gBAAgB,GAC3B,iBAAiB,CAcnB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,iBAAiB,EAAE,SAAS,GAAE,MAAY,GAAG,OAAO,CAQxF;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACtC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,KAAK,EAAE,MAAM,GACX,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAYpF"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { porterSearch } from "../store/search.ts";
|
|
2
|
+
// ── Overlap assessment ─────────────────────────────────────────────────────────
|
|
3
|
+
/**
|
|
4
|
+
* Compute text similarity between two strings using simple token overlap.
|
|
5
|
+
*/
|
|
6
|
+
function textSimilarity(a, b) {
|
|
7
|
+
const tokenize = (s) => new Set(s.toLowerCase().split(/\s+/).filter((t) => t.length > 2));
|
|
8
|
+
const setA = tokenize(a);
|
|
9
|
+
const setB = tokenize(b);
|
|
10
|
+
if (setA.size === 0 && setB.size === 0)
|
|
11
|
+
return 1;
|
|
12
|
+
if (setA.size === 0 || setB.size === 0)
|
|
13
|
+
return 0;
|
|
14
|
+
let intersection = 0;
|
|
15
|
+
for (const token of setA) {
|
|
16
|
+
if (setB.has(token))
|
|
17
|
+
intersection++;
|
|
18
|
+
}
|
|
19
|
+
const union = setA.size + setB.size - intersection;
|
|
20
|
+
return union > 0 ? intersection / union : 0;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Compute file set overlap (Jaccard similarity).
|
|
24
|
+
*/
|
|
25
|
+
function fileOverlap(filesA, filesB) {
|
|
26
|
+
if (filesA.length === 0 && filesB.length === 0)
|
|
27
|
+
return 0;
|
|
28
|
+
if (filesA.length === 0 || filesB.length === 0)
|
|
29
|
+
return 0;
|
|
30
|
+
const setA = new Set(filesA);
|
|
31
|
+
const setB = new Set(filesB);
|
|
32
|
+
let intersection = 0;
|
|
33
|
+
for (const f of setA) {
|
|
34
|
+
if (setB.has(f))
|
|
35
|
+
intersection++;
|
|
36
|
+
}
|
|
37
|
+
const union = setA.size + setB.size - intersection;
|
|
38
|
+
return union > 0 ? intersection / union : 0;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Assess overlap between a new solution and an existing solution.
|
|
42
|
+
* Uses token-based text similarity + file set intersection.
|
|
43
|
+
*/
|
|
44
|
+
export function assessOverlap(newSol, existingSol) {
|
|
45
|
+
return {
|
|
46
|
+
problemOverlap: textSimilarity(newSol.title, existingSol.title),
|
|
47
|
+
rootCauseOverlap: textSimilarity(newSol.content.slice(0, 500), existingSol.content.slice(0, 500)),
|
|
48
|
+
solutionOverlap: textSimilarity(newSol.content, existingSol.content),
|
|
49
|
+
filesOverlap: fileOverlap(newSol.files, existingSol.files),
|
|
50
|
+
preventionOverlap: textSimilarity(newSol.tags.join(" "), existingSol.tags.join(" ")),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Determine if two solutions are duplicates using weighted 5-dimension check.
|
|
55
|
+
*/
|
|
56
|
+
export function shouldDedup(overlap, threshold = 0.7) {
|
|
57
|
+
const weighted = overlap.problemOverlap * 0.3 +
|
|
58
|
+
overlap.rootCauseOverlap * 0.3 +
|
|
59
|
+
overlap.solutionOverlap * 0.2 +
|
|
60
|
+
overlap.filesOverlap * 0.1 +
|
|
61
|
+
overlap.preventionOverlap * 0.1;
|
|
62
|
+
return weighted > threshold;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Find potential duplicates in the database using FTS5 search.
|
|
66
|
+
*/
|
|
67
|
+
export function findPotentialDuplicates(db, title) {
|
|
68
|
+
try {
|
|
69
|
+
const results = porterSearch(db, title, 5);
|
|
70
|
+
const ids = results.map((r) => r.id);
|
|
71
|
+
if (ids.length === 0)
|
|
72
|
+
return [];
|
|
73
|
+
const placeholders = ids.map(() => "?").join(",");
|
|
74
|
+
return db.prepare(`SELECT id, title, content, files, tags FROM solutions WHERE id IN (${placeholders})`).all(...ids);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return [];
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=dedup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dedup.js","sourceRoot":"","sources":["../../src/compound/dedup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { SessionEvent } from "../store/events.ts";
|
|
2
|
+
export interface BugSolution {
|
|
3
|
+
type: "bug";
|
|
4
|
+
problem: string;
|
|
5
|
+
rootCause: string;
|
|
6
|
+
fix: string;
|
|
7
|
+
files: string[];
|
|
8
|
+
tags: string[];
|
|
9
|
+
}
|
|
10
|
+
export interface KnowledgeSolution {
|
|
11
|
+
type: "knowledge";
|
|
12
|
+
whenToUse: string;
|
|
13
|
+
how: string;
|
|
14
|
+
tradeoffs: {
|
|
15
|
+
pro: string[];
|
|
16
|
+
con: string[];
|
|
17
|
+
};
|
|
18
|
+
files: string[];
|
|
19
|
+
tags: string[];
|
|
20
|
+
}
|
|
21
|
+
export interface DecisionSolution {
|
|
22
|
+
type: "decision";
|
|
23
|
+
context: string;
|
|
24
|
+
options: Array<{
|
|
25
|
+
name: string;
|
|
26
|
+
pros: string[];
|
|
27
|
+
cons: string[];
|
|
28
|
+
}>;
|
|
29
|
+
choice: string;
|
|
30
|
+
reasoning: string;
|
|
31
|
+
files: string[];
|
|
32
|
+
tags: string[];
|
|
33
|
+
}
|
|
34
|
+
export type Solution = BugSolution | KnowledgeSolution | DecisionSolution;
|
|
35
|
+
/**
|
|
36
|
+
* Extract a bug solution from error + fix events.
|
|
37
|
+
*/
|
|
38
|
+
export declare function extractBugSolution(errorEvent: SessionEvent, fixEvent: SessionEvent | null): BugSolution | null;
|
|
39
|
+
/**
|
|
40
|
+
* Extract a knowledge pattern from file edit events.
|
|
41
|
+
*/
|
|
42
|
+
export declare function extractKnowledge(events: SessionEvent[]): KnowledgeSolution | null;
|
|
43
|
+
/**
|
|
44
|
+
* Extract a decision from user decision events.
|
|
45
|
+
*/
|
|
46
|
+
export declare function extractDecision(event: SessionEvent): DecisionSolution | null;
|
|
47
|
+
//# sourceMappingURL=extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../../src/compound/extractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAIvD,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,KAAK,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE;QAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QAAC,GAAG,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC5C,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACjE,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CACf;AAED,MAAM,MAAM,QAAQ,GAAG,WAAW,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;AAI1E;;GAEG;AACH,wBAAgB,kBAAkB,CACjC,UAAU,EAAE,YAAY,EACxB,QAAQ,EAAE,YAAY,GAAG,IAAI,GAC3B,WAAW,GAAG,IAAI,CA0BpB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,iBAAiB,GAAG,IAAI,CAejF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,gBAAgB,GAAG,IAAI,CAgB5E"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// ── Extractors ─────────────────────────────────────────────────────────────────
|
|
2
|
+
/**
|
|
3
|
+
* Extract a bug solution from error + fix events.
|
|
4
|
+
*/
|
|
5
|
+
export function extractBugSolution(errorEvent, fixEvent) {
|
|
6
|
+
let errorData;
|
|
7
|
+
try {
|
|
8
|
+
errorData = JSON.parse(errorEvent.data);
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
const errorMessage = typeof errorData.errorMessage === "string" ? errorData.errorMessage :
|
|
14
|
+
typeof errorData.message === "string" ? errorData.message : "Unknown error";
|
|
15
|
+
const tool = typeof errorData.tool === "string" ? errorData.tool : "unknown";
|
|
16
|
+
let fix = "No fix recorded.";
|
|
17
|
+
if (fixEvent) {
|
|
18
|
+
try {
|
|
19
|
+
const fixData = JSON.parse(fixEvent.data);
|
|
20
|
+
const output = typeof fixData.output_summary === "string" ? fixData.output_summary :
|
|
21
|
+
typeof fixData.command === "string" ? `Ran: ${fixData.command}` : "";
|
|
22
|
+
if (output)
|
|
23
|
+
fix = output;
|
|
24
|
+
}
|
|
25
|
+
catch { /* use default */ }
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
type: "bug",
|
|
29
|
+
problem: errorMessage,
|
|
30
|
+
rootCause: `Error from tool: ${tool}`,
|
|
31
|
+
fix,
|
|
32
|
+
files: [],
|
|
33
|
+
tags: [tool, "auto-extracted"],
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Extract a knowledge pattern from file edit events.
|
|
38
|
+
*/
|
|
39
|
+
export function extractKnowledge(events) {
|
|
40
|
+
if (events.length === 0)
|
|
41
|
+
return null;
|
|
42
|
+
const files = events
|
|
43
|
+
.map((e) => { try {
|
|
44
|
+
return JSON.parse(e.data).file;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return "";
|
|
48
|
+
} })
|
|
49
|
+
.filter((f) => f.length > 0);
|
|
50
|
+
return {
|
|
51
|
+
type: "knowledge",
|
|
52
|
+
whenToUse: `When working with: ${files.join(", ")}`,
|
|
53
|
+
how: "Pattern detected from file edit sequence.",
|
|
54
|
+
tradeoffs: { pro: [], con: [] },
|
|
55
|
+
files,
|
|
56
|
+
tags: ["auto-extracted"],
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Extract a decision from user decision events.
|
|
61
|
+
*/
|
|
62
|
+
export function extractDecision(event) {
|
|
63
|
+
let data;
|
|
64
|
+
try {
|
|
65
|
+
data = JSON.parse(event.data);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
const message = typeof data.message_summary === "string" ? data.message_summary :
|
|
71
|
+
typeof data.message === "string" ? data.message : "Decision made";
|
|
72
|
+
return {
|
|
73
|
+
type: "decision",
|
|
74
|
+
context: message,
|
|
75
|
+
options: [],
|
|
76
|
+
choice: message,
|
|
77
|
+
reasoning: "User decision captured from session.",
|
|
78
|
+
files: [],
|
|
79
|
+
tags: ["auto-extracted", "user-decision"],
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractor.js","sourceRoot":"","sources":["../../src/compound/extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { SessionEvent } from "../store/events.ts";
|
|
2
|
+
export type FindingType = "bug" | "knowledge" | "decision";
|
|
3
|
+
export interface RoutedFinding {
|
|
4
|
+
type: FindingType;
|
|
5
|
+
confidence: number;
|
|
6
|
+
events: SessionEvent[];
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Route session events to the appropriate finding type.
|
|
10
|
+
* Classifies as bug/knowledge/decision based on event patterns.
|
|
11
|
+
*/
|
|
12
|
+
export declare function routeFinding(events: SessionEvent[]): RoutedFinding | null;
|
|
13
|
+
/**
|
|
14
|
+
* Route multiple sessions' events and return all routed findings.
|
|
15
|
+
*/
|
|
16
|
+
export declare function routeSessionFindings(events: SessionEvent[]): RoutedFinding[];
|
|
17
|
+
//# sourceMappingURL=router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/compound/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,WAAW,GAAG,UAAU,CAAC;AAE3D,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,WAAW,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,YAAY,EAAE,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,aAAa,GAAG,IAAI,CA8BzE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,aAAa,EAAE,CAgC5E"}
|