@jcmrs/opencode-vmem 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.
Files changed (140) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/LICENSE +21 -0
  3. package/README.md +172 -0
  4. package/dist/capture/classification.d.ts +37 -0
  5. package/dist/capture/classification.d.ts.map +1 -0
  6. package/dist/capture/classification.js +181 -0
  7. package/dist/capture/classification.js.map +1 -0
  8. package/dist/capture/filtering.d.ts +63 -0
  9. package/dist/capture/filtering.d.ts.map +1 -0
  10. package/dist/capture/filtering.js +195 -0
  11. package/dist/capture/filtering.js.map +1 -0
  12. package/dist/capture/observation.d.ts +28 -0
  13. package/dist/capture/observation.d.ts.map +1 -0
  14. package/dist/capture/observation.js +188 -0
  15. package/dist/capture/observation.js.map +1 -0
  16. package/dist/commands/index.d.ts +38 -0
  17. package/dist/commands/index.d.ts.map +1 -0
  18. package/dist/commands/index.js +375 -0
  19. package/dist/commands/index.js.map +1 -0
  20. package/dist/config.d.ts +5 -0
  21. package/dist/config.d.ts.map +1 -0
  22. package/dist/config.js +41 -0
  23. package/dist/config.js.map +1 -0
  24. package/dist/context/builder.d.ts +19 -0
  25. package/dist/context/builder.d.ts.map +1 -0
  26. package/dist/context/builder.js +209 -0
  27. package/dist/context/builder.js.map +1 -0
  28. package/dist/context/format.d.ts +32 -0
  29. package/dist/context/format.d.ts.map +1 -0
  30. package/dist/context/format.js +211 -0
  31. package/dist/context/format.js.map +1 -0
  32. package/dist/embedding/index.d.ts +3 -0
  33. package/dist/embedding/index.d.ts.map +1 -0
  34. package/dist/embedding/index.js +3 -0
  35. package/dist/embedding/index.js.map +1 -0
  36. package/dist/embedding/provider.d.ts +15 -0
  37. package/dist/embedding/provider.d.ts.map +1 -0
  38. package/dist/embedding/provider.js +19 -0
  39. package/dist/embedding/provider.js.map +1 -0
  40. package/dist/embedding/transformers.d.ts +14 -0
  41. package/dist/embedding/transformers.d.ts.map +1 -0
  42. package/dist/embedding/transformers.js +55 -0
  43. package/dist/embedding/transformers.js.map +1 -0
  44. package/dist/extract/confidence.d.ts +48 -0
  45. package/dist/extract/confidence.d.ts.map +1 -0
  46. package/dist/extract/confidence.js +230 -0
  47. package/dist/extract/confidence.js.map +1 -0
  48. package/dist/extract/llm-extractor.d.ts +35 -0
  49. package/dist/extract/llm-extractor.d.ts.map +1 -0
  50. package/dist/extract/llm-extractor.js +204 -0
  51. package/dist/extract/llm-extractor.js.map +1 -0
  52. package/dist/extract/pipeline.d.ts +44 -0
  53. package/dist/extract/pipeline.d.ts.map +1 -0
  54. package/dist/extract/pipeline.js +171 -0
  55. package/dist/extract/pipeline.js.map +1 -0
  56. package/dist/extract/rules-engine.d.ts +14 -0
  57. package/dist/extract/rules-engine.d.ts.map +1 -0
  58. package/dist/extract/rules-engine.js +314 -0
  59. package/dist/extract/rules-engine.js.map +1 -0
  60. package/dist/extract/summarizer.d.ts +27 -0
  61. package/dist/extract/summarizer.d.ts.map +1 -0
  62. package/dist/extract/summarizer.js +148 -0
  63. package/dist/extract/summarizer.js.map +1 -0
  64. package/dist/hooks/session-idle.d.ts +38 -0
  65. package/dist/hooks/session-idle.d.ts.map +1 -0
  66. package/dist/hooks/session-idle.js +142 -0
  67. package/dist/hooks/session-idle.js.map +1 -0
  68. package/dist/hooks/system-transform.d.ts +41 -0
  69. package/dist/hooks/system-transform.d.ts.map +1 -0
  70. package/dist/hooks/system-transform.js +98 -0
  71. package/dist/hooks/system-transform.js.map +1 -0
  72. package/dist/hooks/tool-after.d.ts +66 -0
  73. package/dist/hooks/tool-after.d.ts.map +1 -0
  74. package/dist/hooks/tool-after.js +155 -0
  75. package/dist/hooks/tool-after.js.map +1 -0
  76. package/dist/index.d.ts +10 -0
  77. package/dist/index.d.ts.map +1 -0
  78. package/dist/index.js +10 -0
  79. package/dist/index.js.map +1 -0
  80. package/dist/mind.d.ts +69 -0
  81. package/dist/mind.d.ts.map +1 -0
  82. package/dist/mind.js +368 -0
  83. package/dist/mind.js.map +1 -0
  84. package/dist/procedural/index.d.ts +4 -0
  85. package/dist/procedural/index.d.ts.map +1 -0
  86. package/dist/procedural/index.js +4 -0
  87. package/dist/procedural/index.js.map +1 -0
  88. package/dist/procedural/induction.d.ts +23 -0
  89. package/dist/procedural/induction.d.ts.map +1 -0
  90. package/dist/procedural/induction.js +104 -0
  91. package/dist/procedural/induction.js.map +1 -0
  92. package/dist/procedural/miner.d.ts +45 -0
  93. package/dist/procedural/miner.d.ts.map +1 -0
  94. package/dist/procedural/miner.js +171 -0
  95. package/dist/procedural/miner.js.map +1 -0
  96. package/dist/procedural/suggester.d.ts +20 -0
  97. package/dist/procedural/suggester.d.ts.map +1 -0
  98. package/dist/procedural/suggester.js +69 -0
  99. package/dist/procedural/suggester.js.map +1 -0
  100. package/dist/store/archive.d.ts +31 -0
  101. package/dist/store/archive.d.ts.map +1 -0
  102. package/dist/store/archive.js +137 -0
  103. package/dist/store/archive.js.map +1 -0
  104. package/dist/store/backup.d.ts +36 -0
  105. package/dist/store/backup.d.ts.map +1 -0
  106. package/dist/store/backup.js +163 -0
  107. package/dist/store/backup.js.map +1 -0
  108. package/dist/store/memorycards.d.ts +31 -0
  109. package/dist/store/memorycards.d.ts.map +1 -0
  110. package/dist/store/memorycards.js +161 -0
  111. package/dist/store/memorycards.js.map +1 -0
  112. package/dist/store/mv2-adapter.d.ts +29 -0
  113. package/dist/store/mv2-adapter.d.ts.map +1 -0
  114. package/dist/store/mv2-adapter.js +359 -0
  115. package/dist/store/mv2-adapter.js.map +1 -0
  116. package/dist/store/procedures.d.ts +79 -0
  117. package/dist/store/procedures.d.ts.map +1 -0
  118. package/dist/store/procedures.js +183 -0
  119. package/dist/store/procedures.js.map +1 -0
  120. package/dist/store/tombstone.d.ts +27 -0
  121. package/dist/store/tombstone.d.ts.map +1 -0
  122. package/dist/store/tombstone.js +136 -0
  123. package/dist/store/tombstone.js.map +1 -0
  124. package/dist/tools/index.d.ts +36 -0
  125. package/dist/tools/index.d.ts.map +1 -0
  126. package/dist/tools/index.js +236 -0
  127. package/dist/tools/index.js.map +1 -0
  128. package/dist/types.d.ts +301 -0
  129. package/dist/types.d.ts.map +1 -0
  130. package/dist/types.js +69 -0
  131. package/dist/types.js.map +1 -0
  132. package/dist/utils/error.d.ts +57 -0
  133. package/dist/utils/error.d.ts.map +1 -0
  134. package/dist/utils/error.js +143 -0
  135. package/dist/utils/error.js.map +1 -0
  136. package/dist/utils/uuid.d.ts +2 -0
  137. package/dist/utils/uuid.d.ts.map +1 -0
  138. package/dist/utils/uuid.js +5 -0
  139. package/dist/utils/uuid.js.map +1 -0
  140. package/package.json +67 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,83 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [1.0.0] - 2026-02-19
6
+
7
+ ### Added
8
+
9
+ #### Episodic Memory
10
+ - Observation capture from tool executions
11
+ - Tool after hook for automatic capture
12
+ - Observation filtering and classification
13
+ - Session tracking and summaries
14
+
15
+ #### Semantic Memory
16
+ - Memory card storage (fact, preference, profile, goal)
17
+ - Rules-based extraction (16 default rules)
18
+ - LLM-based extraction with z.ai/OpenAI support
19
+ - Confidence scoring with auto-tombstoning
20
+
21
+ #### Procedural Memory
22
+ - Pattern mining from observations
23
+ - Procedure induction (SAR tuples)
24
+ - Procedure suggestion based on context
25
+
26
+ #### Search & Retrieval
27
+ - Lexical search (exact word matching)
28
+ - Semantic search (embedding-based similarity)
29
+ - Hybrid search mode (auto fallback)
30
+ - Cosine similarity for embeddings
31
+
32
+ #### Context Building
33
+ - Token-aware context assembly
34
+ - Memory card prioritization
35
+ - Markdown and plain text formatting
36
+ - System prompt transformation hook
37
+
38
+ #### Export & Archive
39
+ - Export to JSON, Markdown, Plain text
40
+ - Memory archiving for large files
41
+ - Backup and recovery system
42
+ - Archive listing and pruning
43
+
44
+ #### Plugin Interface
45
+ - 6 agent-callable tools (mind_search, mind_state, etc.)
46
+ - 9 user commands (/mind:stats, /mind:search, etc.)
47
+ - 3 hooks (tool-after, session-idle, system-transform)
48
+
49
+ #### Infrastructure
50
+ - MV2 file format adapter with backup/recovery
51
+ - Crash recovery for corrupted files
52
+ - Cross-platform support (Windows, macOS, Linux)
53
+ - Configurable embedding model caching
54
+
55
+ ### Tests
56
+ - 353 tests passing
57
+ - 74% statement coverage
58
+ - 78% branch coverage
59
+ - 82% function coverage
60
+
61
+ ### Documentation
62
+ - User-facing README
63
+ - Configuration reference
64
+ - Commands reference
65
+ - Troubleshooting guide
66
+ - Testing guide
67
+ - Manual testing checklist
68
+
69
+ ### Packaging
70
+ - npm-ready with `files` field in package.json
71
+ - .npmignore for clean package
72
+ - LICENSE file (MIT)
73
+ - Repository, bugs, homepage fields
74
+
75
+ ### Fixed
76
+ - LLM authentication (API key support)
77
+ - MV2Adapter data loss (full round-trip)
78
+ - mind_suggest stub (now uses ProcedureSuggester)
79
+ - Windows file locking issues
80
+ - Corruption recovery patterns
81
+ - Console.log replaced with console.error for consistency
82
+ - Embedding and procedural modules now exported from main index
83
+ - Path duplication bug in embedding cacheDir (was joined twice)
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,172 @@
1
+ # @jcmrs/opencode-vmem
2
+
3
+ [![CI](https://github.com/jcmrs/opencode-vmem/actions/workflows/ci.yml/badge.svg)](https://github.com/jcmrs/opencode-vmem/actions/workflows/ci.yml)
4
+
5
+ A portable, persistent memory plugin for AI/LLM/Agent contexts. Provides episodic, semantic, and procedural memory capabilities.
6
+
7
+ ## Features
8
+
9
+ - **Episodic Memory** - Captures and stores observations from tool executions
10
+ - **Semantic Memory** - Extracts and stores facts, preferences, and profiles
11
+ - **Procedural Memory** - Learns workflows and suggests relevant procedures
12
+ - **Semantic Search** - Embedding-based similarity search with hybrid fallback
13
+ - **Context Injection** - Builds relevant context for AI sessions
14
+ - **Export & Archive** - Export to JSON/Markdown, archive old memories
15
+
16
+ ## Installation
17
+
18
+ ### From GitHub (no registry account needed)
19
+
20
+ ```bash
21
+ npm install jcmrs/opencode-vmem
22
+ ```
23
+
24
+ ### From GitHub Packages (requires authentication)
25
+
26
+ ```bash
27
+ # Configure npm for GitHub Packages
28
+ echo "@jcmrs:registry=https://npm.pkg.github.com" >> .npmrc
29
+
30
+ # Install
31
+ npm install @jcmrs/opencode-vmem
32
+ ```
33
+
34
+ ## Quick Start
35
+
36
+ ```typescript
37
+ import { Mind } from '@jcmrs/opencode-vmem';
38
+
39
+ const mind = await Mind.open('/path/to/project');
40
+
41
+ await mind.observe({
42
+ type: 'tool_execution',
43
+ content: 'User prefers TypeScript over JavaScript',
44
+ tool: 'bash'
45
+ });
46
+
47
+ const results = await mind.search('typescript preferences', 5);
48
+ console.log(results);
49
+ ```
50
+
51
+ ## Tools (Agent-Callable)
52
+
53
+ | Tool | Description |
54
+ |------|-------------|
55
+ | `mind_search` | Search memories by query |
56
+ | `mind_state` | Get memory system statistics |
57
+ | `mind_forget` | Mark a memory for deletion |
58
+ | `mind_add_card` | Add a memory card |
59
+ | `mind_context` | Build current memory context |
60
+ | `mind_suggest` | Get procedure suggestions |
61
+
62
+ ## Commands (User-Callable)
63
+
64
+ | Command | Description |
65
+ |---------|-------------|
66
+ | `/mind:stats` | Display memory statistics |
67
+ | `/mind:search <query>` | Search memories |
68
+ | `/mind:context` | Show current context |
69
+ | `/mind:forget <id>` | Mark memory for deletion |
70
+ | `/mind:add <entity> <slot> <value>` | Add memory card |
71
+ | `/mind:cards` | List all memory cards |
72
+ | `/mind:export` | Export memory (json/md/plain) |
73
+ | `/mind:archive` | Archive current memory |
74
+ | `/mind:help` | Show help |
75
+
76
+ ## Configuration
77
+
78
+ Create `.opencode/vmem.json` in your project:
79
+
80
+ ```json
81
+ {
82
+ "capture": {
83
+ "enabled": true,
84
+ "minOutputLength": 50
85
+ },
86
+ "embedding": {
87
+ "enabled": true,
88
+ "model": "Xenova/nomic-embed-text-v1"
89
+ },
90
+ "context": {
91
+ "maxTokens": 3000,
92
+ "format": "markdown"
93
+ }
94
+ }
95
+ ```
96
+
97
+ See [docs/configuration.md](docs/configuration.md) for all options.
98
+
99
+ ## Architecture
100
+
101
+ ```
102
+ .opencode/
103
+ ├── memory/
104
+ │ ├── mind.mv2 # Main memory store (MV2 format)
105
+ │ ├── cards.json # Memory cards (extracted facts)
106
+ │ ├── procedures.json # Learned procedures
107
+ │ └── tombstones.json # Soft-deleted frames
108
+ ├── archives/ # Archived memories
109
+ └── vmem.json # Configuration
110
+ ```
111
+
112
+ ## Memory Types
113
+
114
+ ### Episodic (Observations)
115
+ Raw events captured from tool executions:
116
+ - Tool inputs and outputs
117
+ - User interactions
118
+ - Session context
119
+
120
+ ### Semantic (Memory Cards)
121
+ Extracted knowledge:
122
+ - **fact** - Verified information
123
+ - **preference** - User preferences
124
+ - **profile** - User/Project profiles
125
+ - **goal** - Stated objectives
126
+
127
+ ### Procedural (Workflows)
128
+ Learned patterns:
129
+ - State-Action-Result tuples
130
+ - Workflow templates
131
+ - Success/failure rates
132
+
133
+ ## Search Modes
134
+
135
+ | Mode | Description |
136
+ |------|-------------|
137
+ | `lex` | Lexical search (exact words) |
138
+ | `sem` | Semantic search (embeddings) |
139
+ | `auto` | Hybrid (tries semantic, falls back to lexical) |
140
+
141
+ ## Development
142
+
143
+ ```bash
144
+ # Clone and install
145
+ git clone https://github.com/jcmrs/opencode-vmem.git
146
+ cd opencode-vmem
147
+ npm install
148
+
149
+ # Run tests
150
+ npm test
151
+
152
+ # Run smoke test
153
+ npm run smoke
154
+
155
+ # Build
156
+ npm run build
157
+
158
+ # Validate real-world usage
159
+ npm run validate
160
+ ```
161
+
162
+ ## CI/CD
163
+
164
+ This project uses GitHub Actions for:
165
+ - Multi-platform testing (Ubuntu, Windows, macOS)
166
+ - Node.js 18 and 20 support
167
+ - Automated smoke tests
168
+ - Coverage reporting
169
+
170
+ ## License
171
+
172
+ MIT
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Observation type classification
3
+ *
4
+ * Provides confidence-weighted classification of observations.
5
+ */
6
+ import { ObservationType, ConfidenceScore } from '../types.js';
7
+ export interface ClassificationResult {
8
+ type: ObservationType;
9
+ confidence: number;
10
+ factors: string[];
11
+ shouldFlag: boolean;
12
+ shouldTombstone: boolean;
13
+ }
14
+ export interface ClassificationContext {
15
+ tool: string;
16
+ input?: Record<string, unknown>;
17
+ output?: string;
18
+ exitCode?: number;
19
+ }
20
+ /**
21
+ * Classify an observation context
22
+ */
23
+ export declare function classify(context: ClassificationContext): ClassificationResult;
24
+ /**
25
+ * Calculate confidence score from result
26
+ */
27
+ export declare function calculateConfidence(result: ClassificationResult): ConfidenceScore;
28
+ /**
29
+ * Adjust confidence based on additional factors
30
+ */
31
+ export declare function adjustConfidence(base: number, factors: {
32
+ outputLength?: number;
33
+ isRepeat?: boolean;
34
+ hasSensitiveData?: boolean;
35
+ age?: number;
36
+ }): number;
37
+ //# sourceMappingURL=classification.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classification.d.ts","sourceRoot":"","sources":["../../src/capture/classification.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE/D,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,eAAe,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAsED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,qBAAqB,GAAG,oBAAoB,CAwC7E;AAmED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,oBAAoB,GAAG,eAAe,CAOjF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;IACP,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GACA,MAAM,CAmBR"}
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Observation type classification
3
+ *
4
+ * Provides confidence-weighted classification of observations.
5
+ */
6
+ /**
7
+ * Default classification rules
8
+ */
9
+ const CLASSIFICATION_RULES = [
10
+ {
11
+ type: 'error',
12
+ priority: 100,
13
+ patterns: [
14
+ { pattern: /error[::]/i, confidence: 0.95, field: 'output' },
15
+ { pattern: /exception[::]/i, confidence: 0.95, field: 'output' },
16
+ { pattern: /failed[::]/i, confidence: 0.90, field: 'output' },
17
+ { pattern: /cannot \w+/i, confidence: 0.85, field: 'output' },
18
+ { pattern: /unable to \w+/i, confidence: 0.85, field: 'output' },
19
+ { pattern: /fatal[::]/i, confidence: 0.95, field: 'output' }
20
+ ]
21
+ },
22
+ {
23
+ type: 'decision',
24
+ priority: 90,
25
+ patterns: [
26
+ { pattern: /(?:decided|chose|selected) to/i, confidence: 0.90, field: 'output' },
27
+ { pattern: /(?:will use|going with)/i, confidence: 0.85, field: 'output' },
28
+ { pattern: /(?:decided|chose|selected)[::]/i, confidence: 0.90, field: 'output' }
29
+ ]
30
+ },
31
+ {
32
+ type: 'preference_expressed',
33
+ priority: 85,
34
+ patterns: [
35
+ { pattern: /(?:I |we )?(?:prefer|like|dislike|hate)/i, confidence: 0.85, field: 'output' },
36
+ { pattern: /(?:my |our )?(?:favorite|preference)/i, confidence: 0.80, field: 'output' }
37
+ ]
38
+ },
39
+ {
40
+ type: 'goal_stated',
41
+ priority: 80,
42
+ patterns: [
43
+ { pattern: /(?:goal|objective|aim|target)[::]/i, confidence: 0.85, field: 'output' },
44
+ { pattern: /(?:want|need) to/i, confidence: 0.70, field: 'output' }
45
+ ]
46
+ },
47
+ {
48
+ type: 'constraint_identified',
49
+ priority: 75,
50
+ patterns: [
51
+ { pattern: /(?:constraint|limitation|restriction)[::]/i, confidence: 0.85, field: 'output' },
52
+ { pattern: /(?:must|cannot|don't|do not)[::]/i, confidence: 0.75, field: 'output' }
53
+ ]
54
+ }
55
+ ];
56
+ // Confidence thresholds
57
+ const FLAG_THRESHOLD = 0.5;
58
+ const TOMBSTONE_THRESHOLD = 0.3;
59
+ /**
60
+ * Classify an observation context
61
+ */
62
+ export function classify(context) {
63
+ const factors = [];
64
+ let bestType = getDefaultType(context.tool);
65
+ let bestConfidence = 0.0;
66
+ // Check exit code first
67
+ if (context.exitCode !== undefined && context.exitCode !== 0) {
68
+ bestType = 'error';
69
+ bestConfidence = 0.9;
70
+ factors.push('non_zero_exit_code');
71
+ }
72
+ // Apply classification rules
73
+ for (const rule of CLASSIFICATION_RULES) {
74
+ const matchResult = matchRule(rule, context);
75
+ if (matchResult.matched && matchResult.confidence > bestConfidence) {
76
+ bestType = rule.type;
77
+ bestConfidence = matchResult.confidence;
78
+ factors.push(...matchResult.factors);
79
+ }
80
+ }
81
+ // If no rules matched, use tool-based default with moderate confidence
82
+ if (bestConfidence === 0.0) {
83
+ bestConfidence = 0.5;
84
+ factors.push('default_by_tool');
85
+ }
86
+ // Calculate flags
87
+ const shouldFlag = bestConfidence < FLAG_THRESHOLD;
88
+ const shouldTombstone = bestConfidence < TOMBSTONE_THRESHOLD;
89
+ return {
90
+ type: bestType,
91
+ confidence: bestConfidence,
92
+ factors,
93
+ shouldFlag,
94
+ shouldTombstone
95
+ };
96
+ }
97
+ /**
98
+ * Match a classification rule against context
99
+ */
100
+ function matchRule(rule, context) {
101
+ const factors = [];
102
+ let maxConfidence = 0.0;
103
+ let matched = false;
104
+ for (const { pattern, confidence, field } of rule.patterns) {
105
+ const text = getTextForField(field, context);
106
+ if (!text)
107
+ continue;
108
+ if (pattern.test(text)) {
109
+ matched = true;
110
+ if (confidence > maxConfidence) {
111
+ maxConfidence = confidence;
112
+ factors.push(`pattern_match:${pattern.source.slice(0, 20)}`);
113
+ }
114
+ }
115
+ }
116
+ return { matched, confidence: maxConfidence, factors };
117
+ }
118
+ /**
119
+ * Get text for a field
120
+ */
121
+ function getTextForField(field, context) {
122
+ switch (field) {
123
+ case 'output':
124
+ return context.output || null;
125
+ case 'input':
126
+ return context.input ? JSON.stringify(context.input) : null;
127
+ case 'content':
128
+ // Content is output for our purposes
129
+ return context.output || null;
130
+ }
131
+ }
132
+ /**
133
+ * Get default observation type for a tool
134
+ */
135
+ function getDefaultType(tool) {
136
+ switch (tool) {
137
+ case 'read':
138
+ case 'glob':
139
+ case 'grep':
140
+ return 'file_read';
141
+ case 'write':
142
+ return 'file_write';
143
+ case 'edit':
144
+ return 'file_edit';
145
+ case 'bash':
146
+ return 'command_run';
147
+ default:
148
+ return 'tool_execution';
149
+ }
150
+ }
151
+ /**
152
+ * Calculate confidence score from result
153
+ */
154
+ export function calculateConfidence(result) {
155
+ return {
156
+ score: result.confidence,
157
+ factors: result.factors,
158
+ shouldFlag: result.shouldFlag,
159
+ shouldTombstone: result.shouldTombstone
160
+ };
161
+ }
162
+ /**
163
+ * Adjust confidence based on additional factors
164
+ */
165
+ export function adjustConfidence(base, factors) {
166
+ let adjusted = base;
167
+ // Penalize very short outputs
168
+ if (factors.outputLength !== undefined && factors.outputLength < 20) {
169
+ adjusted *= 0.8;
170
+ }
171
+ // Boost repeated patterns
172
+ if (factors.isRepeat) {
173
+ adjusted = Math.min(1.0, adjusted * 1.1);
174
+ }
175
+ // Penalize sensitive data
176
+ if (factors.hasSensitiveData) {
177
+ adjusted *= 0.7;
178
+ }
179
+ return Math.max(0, Math.min(1, adjusted));
180
+ }
181
+ //# sourceMappingURL=classification.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classification.js","sourceRoot":"","sources":["../../src/capture/classification.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Noise filtering for observation capture
3
+ *
4
+ * Filters out low-value observations to reduce memory bloat.
5
+ */
6
+ import { CaptureInput } from './observation.js';
7
+ export interface FilterRule {
8
+ name: string;
9
+ description: string;
10
+ test: (input: CaptureInput) => boolean;
11
+ }
12
+ /**
13
+ * Default filter rules
14
+ *
15
+ * Returns true if the observation should be FILTERED OUT (skipped)
16
+ */
17
+ declare const DEFAULT_FILTERS: FilterRule[];
18
+ export declare class ObservationFilter {
19
+ private filters;
20
+ private disabledFilters;
21
+ constructor(options?: {
22
+ filters?: FilterRule[];
23
+ disabledFilters?: string[];
24
+ });
25
+ /**
26
+ * Check if an observation should be filtered out
27
+ *
28
+ * @returns true if the observation should be skipped
29
+ */
30
+ shouldFilter(input: CaptureInput): boolean;
31
+ /**
32
+ * Get the reason why an observation was filtered
33
+ *
34
+ * @returns filter name if filtered, null otherwise
35
+ */
36
+ getFilterReason(input: CaptureInput): string | null;
37
+ /**
38
+ * Add a custom filter
39
+ */
40
+ addFilter(filter: FilterRule): void;
41
+ /**
42
+ * Remove a filter by name
43
+ */
44
+ removeFilter(name: string): void;
45
+ /**
46
+ * Enable a previously disabled filter
47
+ */
48
+ enableFilter(name: string): void;
49
+ /**
50
+ * Disable a filter
51
+ */
52
+ disableFilter(name: string): void;
53
+ /**
54
+ * Get list of active filter names
55
+ */
56
+ getActiveFilters(): string[];
57
+ }
58
+ /**
59
+ * Create default observation filter
60
+ */
61
+ export declare function createDefaultFilter(): ObservationFilter;
62
+ export { DEFAULT_FILTERS };
63
+ //# sourceMappingURL=filtering.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filtering.d.ts","sourceRoot":"","sources":["../../src/capture/filtering.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC;CACxC;AAED;;;;GAIG;AACH,QAAA,MAAM,eAAe,EAAE,UAAU,EAkFhC,CAAC;AAEF,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,eAAe,CAAc;gBAEzB,OAAO,GAAE;QACnB,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;QACvB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;KACvB;IAUN;;;;OAIG;IACH,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO;IAmB1C;;;;OAIG;IACH,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI;IAkBnD;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAInC;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIhC;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIhC;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIjC;;OAEG;IACH,gBAAgB,IAAI,MAAM,EAAE;CAK7B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,iBAAiB,CAEvD;AAED,OAAO,EAAE,eAAe,EAAE,CAAC"}