hippo-memory 0.36.0 → 0.37.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 +16 -0
- package/dist/api.d.ts +20 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +23 -3
- package/dist/api.js.map +1 -1
- package/dist/benchmarks/e1.3/incident-recall-eval.js +74 -0
- package/dist/benchmarks/e1.3/incident-recall-eval.js.map +1 -0
- package/dist/benchmarks/e1.3/scenarios.json +2587 -0
- package/dist/benchmarks/e1.3/slack-1000-event-smoke.js +102 -0
- package/dist/benchmarks/e1.3/slack-1000-event-smoke.js.map +1 -0
- package/dist/cli.js +82 -0
- package/dist/cli.js.map +1 -1
- package/dist/connectors/slack/backfill.d.ts +42 -0
- package/dist/connectors/slack/backfill.d.ts.map +1 -0
- package/dist/connectors/slack/backfill.js +76 -0
- package/dist/connectors/slack/backfill.js.map +1 -0
- package/dist/connectors/slack/deletion.d.ts +14 -0
- package/dist/connectors/slack/deletion.d.ts.map +1 -0
- package/dist/connectors/slack/deletion.js +46 -0
- package/dist/connectors/slack/deletion.js.map +1 -0
- package/dist/connectors/slack/dlq.d.ts +21 -0
- package/dist/connectors/slack/dlq.d.ts.map +1 -0
- package/dist/connectors/slack/dlq.js +23 -0
- package/dist/connectors/slack/dlq.js.map +1 -0
- package/dist/connectors/slack/idempotency.d.ts +5 -0
- package/dist/connectors/slack/idempotency.d.ts.map +1 -0
- package/dist/connectors/slack/idempotency.js +13 -0
- package/dist/connectors/slack/idempotency.js.map +1 -0
- package/dist/connectors/slack/ingest.d.ts +27 -0
- package/dist/connectors/slack/ingest.d.ts.map +1 -0
- package/dist/connectors/slack/ingest.js +48 -0
- package/dist/connectors/slack/ingest.js.map +1 -0
- package/dist/connectors/slack/ratelimit.d.ts +9 -0
- package/dist/connectors/slack/ratelimit.d.ts.map +1 -0
- package/dist/connectors/slack/ratelimit.js +18 -0
- package/dist/connectors/slack/ratelimit.js.map +1 -0
- package/dist/connectors/slack/scope.d.ts +16 -0
- package/dist/connectors/slack/scope.d.ts.map +1 -0
- package/dist/connectors/slack/scope.js +13 -0
- package/dist/connectors/slack/scope.js.map +1 -0
- package/dist/connectors/slack/signature.d.ts +12 -0
- package/dist/connectors/slack/signature.d.ts.map +1 -0
- package/dist/connectors/slack/signature.js +20 -0
- package/dist/connectors/slack/signature.js.map +1 -0
- package/dist/connectors/slack/tenant-routing.d.ts +13 -0
- package/dist/connectors/slack/tenant-routing.d.ts.map +1 -0
- package/dist/connectors/slack/tenant-routing.js +17 -0
- package/dist/connectors/slack/tenant-routing.js.map +1 -0
- package/dist/connectors/slack/transform.d.ts +20 -0
- package/dist/connectors/slack/transform.d.ts.map +1 -0
- package/dist/connectors/slack/transform.js +31 -0
- package/dist/connectors/slack/transform.js.map +1 -0
- package/dist/connectors/slack/types.d.ts +35 -0
- package/dist/connectors/slack/types.d.ts.map +1 -0
- package/dist/connectors/slack/types.js +23 -0
- package/dist/connectors/slack/types.js.map +1 -0
- package/dist/connectors/slack/web-client.d.ts +12 -0
- package/dist/connectors/slack/web-client.d.ts.map +1 -0
- package/dist/connectors/slack/web-client.js +43 -0
- package/dist/connectors/slack/web-client.js.map +1 -0
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +46 -1
- package/dist/db.js.map +1 -1
- package/dist/importers.js +3 -3
- package/dist/importers.js.map +1 -1
- package/dist/mcp/server.js +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +174 -2
- package/dist/server.js.map +1 -1
- package/dist/src/ambient.js +147 -0
- package/dist/src/ambient.js.map +1 -0
- package/dist/src/api.js +343 -0
- package/dist/src/api.js.map +1 -0
- package/dist/src/audit.js +152 -0
- package/dist/src/audit.js.map +1 -0
- package/dist/src/auth.js +65 -0
- package/dist/src/auth.js.map +1 -0
- package/dist/src/autolearn.js +143 -0
- package/dist/src/autolearn.js.map +1 -0
- package/dist/src/capture.js +512 -0
- package/dist/src/capture.js.map +1 -0
- package/dist/src/cli.js +4971 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/client.js +181 -0
- package/dist/src/client.js.map +1 -0
- package/dist/src/config.js +108 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/connectors/slack/backfill.js +76 -0
- package/dist/src/connectors/slack/backfill.js.map +1 -0
- package/dist/src/connectors/slack/deletion.js +46 -0
- package/dist/src/connectors/slack/deletion.js.map +1 -0
- package/dist/src/connectors/slack/dlq.js +23 -0
- package/dist/src/connectors/slack/dlq.js.map +1 -0
- package/dist/src/connectors/slack/idempotency.js +13 -0
- package/dist/src/connectors/slack/idempotency.js.map +1 -0
- package/dist/src/connectors/slack/ingest.js +48 -0
- package/dist/src/connectors/slack/ingest.js.map +1 -0
- package/dist/src/connectors/slack/ratelimit.js +18 -0
- package/dist/src/connectors/slack/ratelimit.js.map +1 -0
- package/dist/src/connectors/slack/scope.js +13 -0
- package/dist/src/connectors/slack/scope.js.map +1 -0
- package/dist/src/connectors/slack/signature.js +20 -0
- package/dist/src/connectors/slack/signature.js.map +1 -0
- package/dist/src/connectors/slack/tenant-routing.js +17 -0
- package/dist/src/connectors/slack/tenant-routing.js.map +1 -0
- package/dist/src/connectors/slack/transform.js +31 -0
- package/dist/src/connectors/slack/transform.js.map +1 -0
- package/dist/src/connectors/slack/types.js +23 -0
- package/dist/src/connectors/slack/types.js.map +1 -0
- package/dist/src/connectors/slack/web-client.js +43 -0
- package/dist/src/connectors/slack/web-client.js.map +1 -0
- package/dist/src/consolidate.js +517 -0
- package/dist/src/consolidate.js.map +1 -0
- package/dist/src/dag.js +104 -0
- package/dist/src/dag.js.map +1 -0
- package/dist/src/dashboard.js +409 -0
- package/dist/src/dashboard.js.map +1 -0
- package/dist/src/db.js +584 -0
- package/dist/src/db.js.map +1 -0
- package/dist/src/embeddings.js +344 -0
- package/dist/src/embeddings.js.map +1 -0
- package/dist/src/eval-suite.js +289 -0
- package/dist/src/eval-suite.js.map +1 -0
- package/dist/src/eval.js +187 -0
- package/dist/src/eval.js.map +1 -0
- package/dist/src/extract.js +87 -0
- package/dist/src/extract.js.map +1 -0
- package/dist/src/handoff.js +30 -0
- package/dist/src/handoff.js.map +1 -0
- package/dist/src/hooks.js +582 -0
- package/dist/src/hooks.js.map +1 -0
- package/dist/src/importers.js +399 -0
- package/dist/src/importers.js.map +1 -0
- package/dist/src/index.js +25 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/invalidation.js +94 -0
- package/dist/src/invalidation.js.map +1 -0
- package/dist/src/mcp/framing.js +45 -0
- package/dist/src/mcp/framing.js.map +1 -0
- package/dist/src/mcp/server.js +510 -0
- package/dist/src/mcp/server.js.map +1 -0
- package/dist/src/memory.js +280 -0
- package/dist/src/memory.js.map +1 -0
- package/dist/src/multihop.js +32 -0
- package/dist/src/multihop.js.map +1 -0
- package/dist/src/path-context.js +32 -0
- package/dist/src/path-context.js.map +1 -0
- package/dist/src/physics-config.js +26 -0
- package/dist/src/physics-config.js.map +1 -0
- package/dist/src/physics-state.js +163 -0
- package/dist/src/physics-state.js.map +1 -0
- package/dist/src/physics.js +361 -0
- package/dist/src/physics.js.map +1 -0
- package/dist/src/postinstall.js +68 -0
- package/dist/src/postinstall.js.map +1 -0
- package/dist/src/raw-archive.js +72 -0
- package/dist/src/raw-archive.js.map +1 -0
- package/dist/src/refine-llm.js +147 -0
- package/dist/src/refine-llm.js.map +1 -0
- package/dist/src/replay.js +117 -0
- package/dist/src/replay.js.map +1 -0
- package/dist/src/salience.js +74 -0
- package/dist/src/salience.js.map +1 -0
- package/dist/src/scheduler.js +67 -0
- package/dist/src/scheduler.js.map +1 -0
- package/dist/src/scope.js +35 -0
- package/dist/src/scope.js.map +1 -0
- package/dist/src/search.js +801 -0
- package/dist/src/search.js.map +1 -0
- package/dist/src/server-detect.js +70 -0
- package/dist/src/server-detect.js.map +1 -0
- package/dist/src/server.js +784 -0
- package/dist/src/server.js.map +1 -0
- package/dist/src/shared.js +309 -0
- package/dist/src/shared.js.map +1 -0
- package/dist/src/sso.js +22 -0
- package/dist/src/sso.js.map +1 -0
- package/dist/src/store.js +1390 -0
- package/dist/src/store.js.map +1 -0
- package/dist/src/tenant.js +17 -0
- package/dist/src/tenant.js.map +1 -0
- package/dist/src/trace.js +64 -0
- package/dist/src/trace.js.map +1 -0
- package/dist/src/working-memory.js +149 -0
- package/dist/src/working-memory.js.map +1 -0
- package/dist/src/yaml.js +98 -0
- package/dist/src/yaml.js.map +1 -0
- package/dist/store.d.ts +9 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +30 -2
- package/dist/store.js.map +1 -1
- package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
- package/extensions/openclaw-plugin/package.json +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +2 -2
- package/dist/import.d.ts +0 -31
- package/dist/import.d.ts.map +0 -1
- package/dist/import.js +0 -307
- package/dist/import.js.map +0 -1
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory importers for Hippo.
|
|
3
|
+
* Imports memories from ChatGPT, Claude, Cursor, generic files, and structured markdown.
|
|
4
|
+
*/
|
|
5
|
+
import * as fs from 'fs';
|
|
6
|
+
import { createMemory, Layer } from './memory.js';
|
|
7
|
+
import { loadAllEntries, writeEntry } from './store.js';
|
|
8
|
+
import { textOverlap } from './search.js';
|
|
9
|
+
import { getGlobalRoot, initGlobal } from './shared.js';
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// Shared core: dedup + write
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
/**
|
|
14
|
+
* Given an array of raw text chunks, deduplicate against existing memories,
|
|
15
|
+
* create MemoryEntry objects, write them (unless dry-run), and return a result.
|
|
16
|
+
*/
|
|
17
|
+
export function importEntries(chunks, source, tags, options) {
|
|
18
|
+
const targetRoot = options.global ? getGlobalRoot() : options.hippoRoot;
|
|
19
|
+
// Ensure store is ready
|
|
20
|
+
if (options.global) {
|
|
21
|
+
initGlobal();
|
|
22
|
+
}
|
|
23
|
+
const existing = loadAllEntries(targetRoot);
|
|
24
|
+
const allTags = [...new Set([...tags, ...(options.extraTags ?? [])])];
|
|
25
|
+
let total = 0;
|
|
26
|
+
let imported = 0;
|
|
27
|
+
let skipped = 0;
|
|
28
|
+
const entries = [];
|
|
29
|
+
for (const raw of chunks) {
|
|
30
|
+
const trimmed = raw.trim();
|
|
31
|
+
if (trimmed.length > 1000) {
|
|
32
|
+
console.error(`Warning: imported memory truncated from ${trimmed.length} to 1000 chars`);
|
|
33
|
+
}
|
|
34
|
+
const chunk = trimmed.slice(0, 1000);
|
|
35
|
+
// Skip empty or too-short chunks
|
|
36
|
+
if (!chunk || chunk.length < 10) {
|
|
37
|
+
skipped++;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
total++;
|
|
41
|
+
// Dedup check: textOverlap > 0.7 with any existing memory = skip
|
|
42
|
+
let isDuplicate = false;
|
|
43
|
+
for (const existing_entry of existing) {
|
|
44
|
+
if (textOverlap(chunk, existing_entry.content) > 0.7) {
|
|
45
|
+
isDuplicate = true;
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (isDuplicate) {
|
|
50
|
+
skipped++;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
// A3: kind defaults to 'distilled'. ChatGPT/Claude/Cursor exports are curated
|
|
54
|
+
// user pastes, not raw transcripts from a system of record, so distilled is
|
|
55
|
+
// correct here. E1.3 (Slack ingestion) shipped 2026-04-29 in src/connectors/slack/
|
|
56
|
+
// and sets kind: 'raw' + routes deletions through archiveRawMemory() — these
|
|
57
|
+
// importers stay 'distilled' per the original reasoning. See MEMORY_ENVELOPE.md.
|
|
58
|
+
const entry = createMemory(chunk, {
|
|
59
|
+
layer: Layer.Episodic,
|
|
60
|
+
tags: allTags,
|
|
61
|
+
source,
|
|
62
|
+
confidence: 'observed',
|
|
63
|
+
});
|
|
64
|
+
entries.push(entry);
|
|
65
|
+
if (!options.dryRun) {
|
|
66
|
+
writeEntry(targetRoot, entry);
|
|
67
|
+
// Add to existing so subsequent chunks dedup against freshly imported ones
|
|
68
|
+
existing.push(entry);
|
|
69
|
+
}
|
|
70
|
+
imported++;
|
|
71
|
+
}
|
|
72
|
+
return { total, imported, skipped, entries };
|
|
73
|
+
}
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
// ChatGPT importer
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
/**
|
|
78
|
+
* Parse ChatGPT memory export file.
|
|
79
|
+
* Supports:
|
|
80
|
+
* - JSON array of strings: ["memory 1", "memory 2"]
|
|
81
|
+
* - JSON array of objects: [{"content": "...", "created": "..."}]
|
|
82
|
+
* - ChatGPT export format: {"memories": [{"content": "...", "created_at": "..."}]}
|
|
83
|
+
* - Plain text: one memory per line
|
|
84
|
+
*/
|
|
85
|
+
function parseChatGPTFile(filePath) {
|
|
86
|
+
const raw = fs.readFileSync(filePath, 'utf8').trim();
|
|
87
|
+
// Try JSON first
|
|
88
|
+
if (raw.startsWith('[') || raw.startsWith('{')) {
|
|
89
|
+
try {
|
|
90
|
+
const parsed = JSON.parse(raw);
|
|
91
|
+
// {"memories": [...]} - ChatGPT export format
|
|
92
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed) && Array.isArray(parsed.memories)) {
|
|
93
|
+
return parsed.memories
|
|
94
|
+
.map((m) => {
|
|
95
|
+
if (typeof m === 'string')
|
|
96
|
+
return m;
|
|
97
|
+
if (m && typeof m === 'object') {
|
|
98
|
+
const obj = m;
|
|
99
|
+
return String(obj['content'] ?? obj['text'] ?? '');
|
|
100
|
+
}
|
|
101
|
+
return '';
|
|
102
|
+
})
|
|
103
|
+
.filter(Boolean);
|
|
104
|
+
}
|
|
105
|
+
// Array format
|
|
106
|
+
if (Array.isArray(parsed)) {
|
|
107
|
+
return parsed
|
|
108
|
+
.map((m) => {
|
|
109
|
+
if (typeof m === 'string')
|
|
110
|
+
return m;
|
|
111
|
+
if (m && typeof m === 'object') {
|
|
112
|
+
const obj = m;
|
|
113
|
+
return String(obj['content'] ?? obj['text'] ?? '');
|
|
114
|
+
}
|
|
115
|
+
return '';
|
|
116
|
+
})
|
|
117
|
+
.filter(Boolean);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
// Fall through to plain text
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Plain text: one memory per line
|
|
125
|
+
return raw.split('\n').map((l) => l.trim()).filter(Boolean);
|
|
126
|
+
}
|
|
127
|
+
export function importChatGPT(filePath, options) {
|
|
128
|
+
const chunks = parseChatGPTFile(filePath);
|
|
129
|
+
return importEntries(chunks, 'import:chatgpt', ['imported', 'chatgpt'], options);
|
|
130
|
+
}
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
// Claude importer
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
const HIPPO_START = '<!-- hippo:start -->';
|
|
135
|
+
const HIPPO_END = '<!-- hippo:end -->';
|
|
136
|
+
/**
|
|
137
|
+
* Strip the hippo hook block from markdown content.
|
|
138
|
+
*/
|
|
139
|
+
function stripHippoBlock(content) {
|
|
140
|
+
const startIdx = content.indexOf(HIPPO_START);
|
|
141
|
+
const endIdx = content.indexOf(HIPPO_END);
|
|
142
|
+
if (startIdx === -1 || endIdx === -1)
|
|
143
|
+
return content;
|
|
144
|
+
return content.slice(0, startIdx) + content.slice(endIdx + HIPPO_END.length);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Split markdown into meaningful chunks (headings + bullet points).
|
|
148
|
+
*/
|
|
149
|
+
function splitMarkdown(content) {
|
|
150
|
+
const chunks = [];
|
|
151
|
+
const lines = content.split('\n');
|
|
152
|
+
let current = '';
|
|
153
|
+
for (const line of lines) {
|
|
154
|
+
const trimmed = line.trim();
|
|
155
|
+
// Heading: start a new chunk
|
|
156
|
+
if (/^#{1,6}\s+/.test(trimmed)) {
|
|
157
|
+
if (current.trim())
|
|
158
|
+
chunks.push(current.trim());
|
|
159
|
+
current = trimmed;
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
// Bullet point: each bullet is its own chunk (flush previous if not a bullet context)
|
|
163
|
+
if (/^[-*+]\s+/.test(trimmed)) {
|
|
164
|
+
if (current.trim() && !/^[-*+]\s+/.test(current.split('\n')[0])) {
|
|
165
|
+
chunks.push(current.trim());
|
|
166
|
+
current = '';
|
|
167
|
+
}
|
|
168
|
+
if (current.trim()) {
|
|
169
|
+
chunks.push(current.trim());
|
|
170
|
+
current = '';
|
|
171
|
+
}
|
|
172
|
+
current = trimmed.replace(/^[-*+]\s+/, '').trim();
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
// Numbered list item
|
|
176
|
+
if (/^\d+\.\s+/.test(trimmed)) {
|
|
177
|
+
if (current.trim()) {
|
|
178
|
+
chunks.push(current.trim());
|
|
179
|
+
current = '';
|
|
180
|
+
}
|
|
181
|
+
current = trimmed.replace(/^\d+\.\s+/, '').trim();
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
// Empty line
|
|
185
|
+
if (!trimmed) {
|
|
186
|
+
if (current.trim()) {
|
|
187
|
+
chunks.push(current.trim());
|
|
188
|
+
current = '';
|
|
189
|
+
}
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
// Regular line: append to current
|
|
193
|
+
current = current ? current + ' ' + trimmed : trimmed;
|
|
194
|
+
}
|
|
195
|
+
if (current.trim())
|
|
196
|
+
chunks.push(current.trim());
|
|
197
|
+
return chunks.filter(Boolean);
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Parse CLAUDE.md or Claude memory.json.
|
|
201
|
+
*/
|
|
202
|
+
function parseClaudeFile(filePath) {
|
|
203
|
+
const raw = fs.readFileSync(filePath, 'utf8');
|
|
204
|
+
// JSON memory file
|
|
205
|
+
if (filePath.endsWith('.json')) {
|
|
206
|
+
try {
|
|
207
|
+
const parsed = JSON.parse(raw.trim());
|
|
208
|
+
if (Array.isArray(parsed)) {
|
|
209
|
+
return parsed
|
|
210
|
+
.map((m) => {
|
|
211
|
+
if (typeof m === 'string')
|
|
212
|
+
return m;
|
|
213
|
+
if (m && typeof m === 'object') {
|
|
214
|
+
const obj = m;
|
|
215
|
+
return String(obj['content'] ?? obj['text'] ?? '');
|
|
216
|
+
}
|
|
217
|
+
return '';
|
|
218
|
+
})
|
|
219
|
+
.filter(Boolean);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
// Fall through to markdown
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// Markdown file: strip hippo block and split
|
|
227
|
+
const cleaned = stripHippoBlock(raw);
|
|
228
|
+
return splitMarkdown(cleaned);
|
|
229
|
+
}
|
|
230
|
+
export function importClaude(filePath, options) {
|
|
231
|
+
const chunks = parseClaudeFile(filePath);
|
|
232
|
+
return importEntries(chunks, 'import:claude', ['imported', 'claude'], options);
|
|
233
|
+
}
|
|
234
|
+
// ---------------------------------------------------------------------------
|
|
235
|
+
// Cursor importer
|
|
236
|
+
// ---------------------------------------------------------------------------
|
|
237
|
+
/**
|
|
238
|
+
* Split cursor rules file into chunks.
|
|
239
|
+
* Priority: numbered items, then bullet points, then double newlines.
|
|
240
|
+
*/
|
|
241
|
+
function parseCursorFile(content) {
|
|
242
|
+
const chunks = [];
|
|
243
|
+
const lines = content.split('\n');
|
|
244
|
+
let current = '';
|
|
245
|
+
for (const line of lines) {
|
|
246
|
+
const trimmed = line.trim();
|
|
247
|
+
// Skip comment-only lines that are empty after stripping #
|
|
248
|
+
if (!trimmed || trimmed === '#') {
|
|
249
|
+
if (current.trim()) {
|
|
250
|
+
chunks.push(current.trim());
|
|
251
|
+
current = '';
|
|
252
|
+
}
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
// Numbered item: 1. 2. 3.
|
|
256
|
+
if (/^\d+\.\s+/.test(trimmed)) {
|
|
257
|
+
if (current.trim()) {
|
|
258
|
+
chunks.push(current.trim());
|
|
259
|
+
current = '';
|
|
260
|
+
}
|
|
261
|
+
current = trimmed.replace(/^\d+\.\s+/, '').trim();
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
// Bullet: - or *
|
|
265
|
+
if (/^[-*]\s+/.test(trimmed)) {
|
|
266
|
+
if (current.trim()) {
|
|
267
|
+
chunks.push(current.trim());
|
|
268
|
+
current = '';
|
|
269
|
+
}
|
|
270
|
+
current = trimmed.replace(/^[-*]\s+/, '').trim();
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
// Regular line
|
|
274
|
+
current = current ? current + ' ' + trimmed : trimmed;
|
|
275
|
+
}
|
|
276
|
+
if (current.trim())
|
|
277
|
+
chunks.push(current.trim());
|
|
278
|
+
// Also split on double newlines within chunks if they somehow ended up there
|
|
279
|
+
return chunks.flatMap((c) => {
|
|
280
|
+
const parts = c.split(/\n{2,}/);
|
|
281
|
+
return parts.map((p) => p.trim()).filter(Boolean);
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
export function importCursor(filePath, options) {
|
|
285
|
+
const raw = fs.readFileSync(filePath, 'utf8');
|
|
286
|
+
const chunks = parseCursorFile(raw);
|
|
287
|
+
return importEntries(chunks, 'import:cursor', ['imported', 'cursor'], options);
|
|
288
|
+
}
|
|
289
|
+
// ---------------------------------------------------------------------------
|
|
290
|
+
// Generic file importer
|
|
291
|
+
// ---------------------------------------------------------------------------
|
|
292
|
+
/**
|
|
293
|
+
* Split a generic file into chunks.
|
|
294
|
+
* Markdown: split on headings and bullet points.
|
|
295
|
+
* Plain text: split on double newlines or one-per-line.
|
|
296
|
+
*/
|
|
297
|
+
function parseGenericFile(filePath) {
|
|
298
|
+
const raw = fs.readFileSync(filePath, 'utf8');
|
|
299
|
+
const isMarkdown = filePath.endsWith('.md') || filePath.endsWith('.mdx');
|
|
300
|
+
if (isMarkdown) {
|
|
301
|
+
return splitMarkdown(raw);
|
|
302
|
+
}
|
|
303
|
+
// Plain text: try double newlines first
|
|
304
|
+
const byParagraph = raw.split(/\n{2,}/).map((p) => p.trim()).filter(Boolean);
|
|
305
|
+
if (byParagraph.length > 1)
|
|
306
|
+
return byParagraph;
|
|
307
|
+
// Fall back to one-per-line
|
|
308
|
+
return raw.split('\n').map((l) => l.trim()).filter(Boolean);
|
|
309
|
+
}
|
|
310
|
+
export function importGenericFile(filePath, options) {
|
|
311
|
+
const chunks = parseGenericFile(filePath);
|
|
312
|
+
return importEntries(chunks, 'import:file', ['imported'], options);
|
|
313
|
+
}
|
|
314
|
+
// ---------------------------------------------------------------------------
|
|
315
|
+
// Structured markdown importer (MEMORY.md / AGENTS.md format)
|
|
316
|
+
// ---------------------------------------------------------------------------
|
|
317
|
+
/**
|
|
318
|
+
* Slugify a heading for use as a tag.
|
|
319
|
+
* "Data Pipeline & Cache" -> "data-pipeline-cache"
|
|
320
|
+
*/
|
|
321
|
+
function slugify(heading) {
|
|
322
|
+
return heading
|
|
323
|
+
.toLowerCase()
|
|
324
|
+
.replace(/[^a-z0-9\s-]/g, ' ')
|
|
325
|
+
.trim()
|
|
326
|
+
.replace(/\s+/g, '-')
|
|
327
|
+
.replace(/-+/g, '-')
|
|
328
|
+
.slice(0, 50);
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Parse structured markdown into {content, sectionSlug} pairs.
|
|
332
|
+
* Each heading starts a new section. Bullet points / numbered items under
|
|
333
|
+
* the heading become individual memories tagged with the section slug.
|
|
334
|
+
*/
|
|
335
|
+
function parseStructuredMarkdown(raw) {
|
|
336
|
+
const results = [];
|
|
337
|
+
const lines = raw.split('\n');
|
|
338
|
+
let currentSection = '';
|
|
339
|
+
let currentSlug = '';
|
|
340
|
+
let pendingText = '';
|
|
341
|
+
function flush() {
|
|
342
|
+
if (!pendingText.trim())
|
|
343
|
+
return;
|
|
344
|
+
results.push({ content: pendingText.trim(), sectionSlug: currentSlug });
|
|
345
|
+
pendingText = '';
|
|
346
|
+
}
|
|
347
|
+
for (const line of lines) {
|
|
348
|
+
const trimmed = line.trim();
|
|
349
|
+
// Heading
|
|
350
|
+
const headingMatch = trimmed.match(/^(#{1,6})\s+(.+)/);
|
|
351
|
+
if (headingMatch) {
|
|
352
|
+
flush();
|
|
353
|
+
currentSection = headingMatch[2].trim();
|
|
354
|
+
currentSlug = slugify(currentSection);
|
|
355
|
+
continue;
|
|
356
|
+
}
|
|
357
|
+
// Bullet or numbered item: flush previous, start new
|
|
358
|
+
if (/^[-*+]\s+/.test(trimmed) || /^\d+\.\s+/.test(trimmed)) {
|
|
359
|
+
flush();
|
|
360
|
+
const itemText = trimmed.replace(/^[-*+]\s+/, '').replace(/^\d+\.\s+/, '').trim();
|
|
361
|
+
pendingText = itemText;
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
// Empty line: flush current pending
|
|
365
|
+
if (!trimmed) {
|
|
366
|
+
flush();
|
|
367
|
+
continue;
|
|
368
|
+
}
|
|
369
|
+
// Continuation of current item
|
|
370
|
+
pendingText = pendingText ? pendingText + ' ' + trimmed : trimmed;
|
|
371
|
+
}
|
|
372
|
+
flush();
|
|
373
|
+
return results.filter((r) => r.content.length > 0);
|
|
374
|
+
}
|
|
375
|
+
export function importMarkdown(filePath, options) {
|
|
376
|
+
const raw = fs.readFileSync(filePath, 'utf8');
|
|
377
|
+
const parsed = parseStructuredMarkdown(raw);
|
|
378
|
+
// Group by section slug so we can pass per-chunk tags
|
|
379
|
+
// We call importEntries per unique slug to get the right tags per section
|
|
380
|
+
const bySlug = new Map();
|
|
381
|
+
for (const { content, sectionSlug } of parsed) {
|
|
382
|
+
const list = bySlug.get(sectionSlug) ?? [];
|
|
383
|
+
list.push(content);
|
|
384
|
+
bySlug.set(sectionSlug, list);
|
|
385
|
+
}
|
|
386
|
+
let totalResult = { total: 0, imported: 0, skipped: 0, entries: [] };
|
|
387
|
+
for (const [slug, chunks] of bySlug.entries()) {
|
|
388
|
+
const sectionTags = slug ? ['imported', slug] : ['imported'];
|
|
389
|
+
const result = importEntries(chunks, 'import:markdown', sectionTags, options);
|
|
390
|
+
totalResult = {
|
|
391
|
+
total: totalResult.total + result.total,
|
|
392
|
+
imported: totalResult.imported + result.imported,
|
|
393
|
+
skipped: totalResult.skipped + result.skipped,
|
|
394
|
+
entries: [...totalResult.entries, ...result.entries],
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
return totalResult;
|
|
398
|
+
}
|
|
399
|
+
//# sourceMappingURL=importers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"importers.js","sourceRoot":"","sources":["../../src/importers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hippo public API - re-exports for programmatic use.
|
|
3
|
+
*/
|
|
4
|
+
export { Layer, calculateStrength, resolveConfidence, createMemory, applyOutcome, generateId, computeSchemaFit } from './memory.js';
|
|
5
|
+
export { search, hybridSearch, physicsSearch, markRetrieved, estimateTokens, textOverlap, tokenize, explainMatch, detectTemporalDirection, temporalBoost, computeTemporalRange } from './search.js';
|
|
6
|
+
export { multihopSearch } from './multihop.js';
|
|
7
|
+
export { initStore, loadAllEntries, loadSearchEntries, writeEntry, readEntry, deleteEntry, loadIndex, rebuildIndex, saveActiveTaskSnapshot, loadActiveTaskSnapshot, clearActiveTaskSnapshot, appendSessionEvent, listSessionEvents, listMemoryConflicts, replaceDetectedConflicts, resolveConflict, saveSessionHandoff, loadLatestHandoff, loadHandoffById, loadSessionDecayContext, } from './store.js';
|
|
8
|
+
export { consolidate } from './consolidate.js';
|
|
9
|
+
// Feature 1: Embedding search
|
|
10
|
+
export { isEmbeddingAvailable, getEmbedding, cosineSimilarity, loadEmbeddingIndex, saveEmbeddingIndex, embedMemory, embedAll, } from './embeddings.js';
|
|
11
|
+
// Feature 2: Auto-learn from errors
|
|
12
|
+
export { captureError, extractLessons, deduplicateLesson, runWatched, fetchGitLog, } from './autolearn.js';
|
|
13
|
+
// Feature 3: Cross-agent shared memory
|
|
14
|
+
export { getGlobalRoot, initGlobal, promoteToGlobal, searchBoth, searchBothHybrid, syncGlobalToLocal, transferScore, shareMemory, listPeers, autoShare, } from './shared.js';
|
|
15
|
+
// Feature 5: Working memory
|
|
16
|
+
export { wmPush, wmRead, wmClear, wmFlush, WM_MAX_ENTRIES, } from './working-memory.js';
|
|
17
|
+
// Feature 4: Memory importers
|
|
18
|
+
export { importChatGPT, importClaude, importCursor, importGenericFile, importMarkdown, importEntries, } from './importers.js';
|
|
19
|
+
// Feature eval suite
|
|
20
|
+
export { runFeatureEval, formatResult, resultToBaseline, detectRegressions, buildSyntheticCorpus, } from './eval-suite.js';
|
|
21
|
+
// Pineal gland: salience gate
|
|
22
|
+
export { computeSalience, } from './salience.js';
|
|
23
|
+
// Pineal gland: ambient state vector
|
|
24
|
+
export { computeAmbientState, renderAmbientSummary, formatAmbientVector, } from './ambient.js';
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAe,KAAK,EAAmD,iBAAiB,EAAE,iBAAiB,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAClM,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,uBAAuB,EAAE,aAAa,EAAE,oBAAoB,EAAkC,MAAM,aAAa,CAAC;AACpO,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EACL,SAAS,EACT,cAAc,EACd,iBAAiB,EACjB,UAAU,EACV,SAAS,EACT,WAAW,EACX,SAAS,EACT,YAAY,EACZ,sBAAsB,EACtB,sBAAsB,EACtB,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,wBAAwB,EACxB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,uBAAuB,GAExB,MAAM,YAAY,CAAC;AAIpB,OAAO,EAAE,WAAW,EAAuB,MAAM,kBAAkB,CAAC;AAEpE,8BAA8B;AAC9B,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,WAAW,EACX,QAAQ,GACT,MAAM,iBAAiB,CAAC;AAEzB,oCAAoC;AACpC,OAAO,EACL,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,UAAU,EACV,WAAW,GACZ,MAAM,gBAAgB,CAAC;AAExB,uCAAuC;AACvC,OAAO,EACL,aAAa,EACb,UAAU,EACV,eAAe,EACf,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EAEjB,aAAa,EACb,WAAW,EACX,SAAS,EACT,SAAS,GACV,MAAM,aAAa,CAAC;AAErB,4BAA4B;AAC5B,OAAO,EACL,MAAM,EACN,MAAM,EACN,OAAO,EACP,OAAO,EAEP,cAAc,GACf,MAAM,qBAAqB,CAAC;AAE7B,8BAA8B;AAC9B,OAAO,EACL,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,aAAa,GAGd,MAAM,gBAAgB,CAAC;AAExB,qBAAqB;AACrB,OAAO,EACL,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AAEzB,8BAA8B;AAC9B,OAAO,EACL,eAAe,GAIhB,MAAM,eAAe,CAAC;AAEvB,qCAAqC;AACrC,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,GAEpB,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { loadAllEntries, writeEntry } from './store.js';
|
|
2
|
+
/**
|
|
3
|
+
* Extract what was replaced/removed from a commit message.
|
|
4
|
+
* Returns null if the commit isn't a breaking/migration change.
|
|
5
|
+
*/
|
|
6
|
+
export function extractInvalidationTarget(message) {
|
|
7
|
+
// Strip conventional commit prefix (e.g., "feat(scope): ")
|
|
8
|
+
const body = message.replace(/^[a-z]+(\([^)]*\))?:\s*/i, '').trim();
|
|
9
|
+
// Pattern: "migrate/switch/move/convert/transition/upgrade from X to Y"
|
|
10
|
+
const fromToMatch = body.match(/(?:migrat\w+|switch\w*|mov\w+|convert\w*|transition\w*|upgrad\w+)\s+(?:from\s+)?(.+?)\s+to\s+(.+)/i);
|
|
11
|
+
if (fromToMatch) {
|
|
12
|
+
return { from: fromToMatch[1].trim(), to: fromToMatch[2].trim(), type: 'migration' };
|
|
13
|
+
}
|
|
14
|
+
// Pattern: "from X to Y" (standalone)
|
|
15
|
+
const standaloneFromTo = body.match(/from\s+(.+?)\s+to\s+(.+)/i);
|
|
16
|
+
if (standaloneFromTo) {
|
|
17
|
+
return { from: standaloneFromTo[1].trim(), to: standaloneFromTo[2].trim(), type: 'migration' };
|
|
18
|
+
}
|
|
19
|
+
// Pattern: "replace X with Y"
|
|
20
|
+
const replaceMatch = body.match(/replac\w+\s+(.+?)\s+with\s+(.+)/i);
|
|
21
|
+
if (replaceMatch) {
|
|
22
|
+
return { from: replaceMatch[1].trim(), to: replaceMatch[2].trim(), type: 'migration' };
|
|
23
|
+
}
|
|
24
|
+
// Pattern: "deprecate X"
|
|
25
|
+
const deprecateMatch = body.match(/deprecat\w+\s+(.+)/i);
|
|
26
|
+
if (deprecateMatch) {
|
|
27
|
+
return { from: deprecateMatch[1].trim(), to: null, type: 'deprecation' };
|
|
28
|
+
}
|
|
29
|
+
// Pattern: "remove/drop X" (but not trivial removals)
|
|
30
|
+
const removeMatch = body.match(/(?:remov\w+|drop\w*)\s+(.+)/i);
|
|
31
|
+
if (removeMatch) {
|
|
32
|
+
const target = removeMatch[1].trim();
|
|
33
|
+
const words = target.split(/\s+/);
|
|
34
|
+
const trivialWords = new Set(['extra', 'unused', 'empty', 'old', 'whitespace', 'spaces', 'blank', 'dead', 'commented']);
|
|
35
|
+
const isTrivial = words.length <= 2 && words.some(w => trivialWords.has(w.toLowerCase()));
|
|
36
|
+
if (isTrivial)
|
|
37
|
+
return null;
|
|
38
|
+
return { from: target, to: null, type: 'removal' };
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Find memories that reference the invalidated pattern and weaken them.
|
|
44
|
+
* - Halves half_life_days
|
|
45
|
+
* - Sets confidence to 'stale'
|
|
46
|
+
* - Adds 'invalidated' tag
|
|
47
|
+
* - Skips pinned memories
|
|
48
|
+
*/
|
|
49
|
+
export function invalidateMatching(hippoRoot, target) {
|
|
50
|
+
const entries = loadAllEntries(hippoRoot);
|
|
51
|
+
const fromTokens = invalidationTokenize(target.from);
|
|
52
|
+
const result = { invalidated: 0, targets: [] };
|
|
53
|
+
for (const entry of entries) {
|
|
54
|
+
if (entry.pinned)
|
|
55
|
+
continue;
|
|
56
|
+
const contentTokens = invalidationTokenize(entry.content);
|
|
57
|
+
const tagTokens = entry.tags.map(t => t.toLowerCase());
|
|
58
|
+
// Check if the memory references the old pattern
|
|
59
|
+
const tokenMatch = matchScore(fromTokens, contentTokens);
|
|
60
|
+
const tagMatch = fromTokens.some(t => tagTokens.includes(t));
|
|
61
|
+
if (tokenMatch >= 0.5 || tagMatch) {
|
|
62
|
+
entry.half_life_days = Math.max(1, Math.floor(entry.half_life_days / 2));
|
|
63
|
+
entry.confidence = 'stale';
|
|
64
|
+
if (!entry.tags.includes('invalidated')) {
|
|
65
|
+
entry.tags.push('invalidated');
|
|
66
|
+
}
|
|
67
|
+
writeEntry(hippoRoot, entry);
|
|
68
|
+
result.invalidated++;
|
|
69
|
+
result.targets.push(entry.id);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
const STOPWORDS = new Set([
|
|
75
|
+
'the', 'an', 'is', 'it', 'in', 'on', 'at', 'to', 'for', 'of', 'by',
|
|
76
|
+
'and', 'or', 'but', 'not', 'with', 'from', 'that', 'this', 'was', 'are',
|
|
77
|
+
'be', 'has', 'had', 'have', 'been', 'will', 'would', 'could', 'should',
|
|
78
|
+
'do', 'does', 'did', 'all', 'our', 'old', 'new', 'use', 'used', 'using',
|
|
79
|
+
]);
|
|
80
|
+
function invalidationTokenize(text) {
|
|
81
|
+
return text
|
|
82
|
+
.toLowerCase()
|
|
83
|
+
.replace(/[^a-z0-9\s_.-]/g, ' ')
|
|
84
|
+
.split(/\s+/)
|
|
85
|
+
.filter(t => t.length >= 2 && !STOPWORDS.has(t));
|
|
86
|
+
}
|
|
87
|
+
function matchScore(fromTokens, contentTokens) {
|
|
88
|
+
if (fromTokens.length === 0)
|
|
89
|
+
return 0;
|
|
90
|
+
const contentSet = new Set(contentTokens);
|
|
91
|
+
const matches = fromTokens.filter(t => contentSet.has(t)).length;
|
|
92
|
+
return matches / fromTokens.length;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=invalidation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invalidation.js","sourceRoot":"","sources":["../../src/invalidation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// MCP stdio transport framing.
|
|
2
|
+
//
|
|
3
|
+
// Spec: messages are newline-delimited JSON-RPC, with no embedded newlines.
|
|
4
|
+
// https://modelcontextprotocol.io/specification/.../basic/transports#stdio
|
|
5
|
+
// We also accept legacy LSP-style `Content-Length` framing so the
|
|
6
|
+
// printf-and-pipe smoke test from issue #13 still works.
|
|
7
|
+
const HEADER_DELIM = Buffer.from('\r\n\r\n');
|
|
8
|
+
export function parseFrame(buffer) {
|
|
9
|
+
// Strip leading whitespace/newlines between messages.
|
|
10
|
+
let start = 0;
|
|
11
|
+
while (start < buffer.length &&
|
|
12
|
+
(buffer[start] === 0x0a || buffer[start] === 0x0d ||
|
|
13
|
+
buffer[start] === 0x20 || buffer[start] === 0x09)) {
|
|
14
|
+
start++;
|
|
15
|
+
}
|
|
16
|
+
if (start === buffer.length)
|
|
17
|
+
return { kind: 'incomplete' };
|
|
18
|
+
const trimmed = buffer.subarray(start);
|
|
19
|
+
// LSP-style Content-Length framing.
|
|
20
|
+
if (trimmed[0] === 0x43 /* 'C' */ || trimmed[0] === 0x63 /* 'c' */) {
|
|
21
|
+
const headerEnd = trimmed.indexOf(HEADER_DELIM);
|
|
22
|
+
if (headerEnd === -1)
|
|
23
|
+
return { kind: 'incomplete' };
|
|
24
|
+
const header = trimmed.subarray(0, headerEnd).toString('utf-8');
|
|
25
|
+
const match = header.match(/Content-Length:\s*(\d+)/i);
|
|
26
|
+
if (!match)
|
|
27
|
+
return { kind: 'skip', rest: Buffer.from(trimmed.subarray(headerEnd + 4)) };
|
|
28
|
+
const contentLength = parseInt(match[1], 10);
|
|
29
|
+
const bodyStart = headerEnd + 4;
|
|
30
|
+
if (trimmed.length < bodyStart + contentLength)
|
|
31
|
+
return { kind: 'incomplete' };
|
|
32
|
+
const body = trimmed.subarray(bodyStart, bodyStart + contentLength).toString('utf-8');
|
|
33
|
+
return { kind: 'message', body, rest: Buffer.from(trimmed.subarray(bodyStart + contentLength)) };
|
|
34
|
+
}
|
|
35
|
+
// Newline-delimited JSON (MCP spec).
|
|
36
|
+
const newlineIdx = trimmed.indexOf(0x0a);
|
|
37
|
+
if (newlineIdx === -1)
|
|
38
|
+
return { kind: 'incomplete' };
|
|
39
|
+
const line = trimmed.subarray(0, newlineIdx).toString('utf-8').trimEnd();
|
|
40
|
+
const rest = Buffer.from(trimmed.subarray(newlineIdx + 1));
|
|
41
|
+
if (!line)
|
|
42
|
+
return { kind: 'skip', rest };
|
|
43
|
+
return { kind: 'message', body: line, rest };
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=framing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framing.js","sourceRoot":"","sources":["../../../src/mcp/framing.ts"],"names":[],"mappings":"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"}
|