@dmsdc-ai/aigentry-brain 0.0.1
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/bin/aigentry-brain-mcp.mjs +17 -0
- package/bin/aigentry-brain-setup.mjs +17 -0
- package/bin/aigentry-brain.mjs +17 -0
- package/dist/audit/AuditTrail.d.ts +15 -0
- package/dist/audit/AuditTrail.js +43 -0
- package/dist/audit/AuditTrail.js.map +1 -0
- package/dist/backend/GitBackend.d.ts +27 -0
- package/dist/backend/GitBackend.js +201 -0
- package/dist/backend/GitBackend.js.map +1 -0
- package/dist/backend/SyncBackend.d.ts +13 -0
- package/dist/backend/SyncBackend.js +2 -0
- package/dist/backend/SyncBackend.js.map +1 -0
- package/dist/cli/AutoUpdater.d.ts +7 -0
- package/dist/cli/AutoUpdater.js +275 -0
- package/dist/cli/AutoUpdater.js.map +1 -0
- package/dist/cli/ConfigStore.d.ts +17 -0
- package/dist/cli/ConfigStore.js +50 -0
- package/dist/cli/ConfigStore.js.map +1 -0
- package/dist/cli/GhIntegration.d.ts +55 -0
- package/dist/cli/GhIntegration.js +192 -0
- package/dist/cli/GhIntegration.js.map +1 -0
- package/dist/cli/Prerequisites.d.ts +48 -0
- package/dist/cli/Prerequisites.js +182 -0
- package/dist/cli/Prerequisites.js.map +1 -0
- package/dist/cli/SetupWizard.d.ts +26 -0
- package/dist/cli/SetupWizard.js +407 -0
- package/dist/cli/SetupWizard.js.map +1 -0
- package/dist/cli/braincli.d.ts +2 -0
- package/dist/cli/braincli.js +260 -0
- package/dist/cli/braincli.js.map +1 -0
- package/dist/cli/setup.d.ts +25 -0
- package/dist/cli/setup.js +238 -0
- package/dist/cli/setup.js.map +1 -0
- package/dist/context/ConfidenceGuard.d.ts +11 -0
- package/dist/context/ConfidenceGuard.js +32 -0
- package/dist/context/ConfidenceGuard.js.map +1 -0
- package/dist/context/ContextBudgetPolicy.d.ts +21 -0
- package/dist/context/ContextBudgetPolicy.js +136 -0
- package/dist/context/ContextBudgetPolicy.js.map +1 -0
- package/dist/context/ContextPacker.d.ts +30 -0
- package/dist/context/ContextPacker.js +219 -0
- package/dist/context/ContextPacker.js.map +1 -0
- package/dist/context/ContextRestoreService.d.ts +39 -0
- package/dist/context/ContextRestoreService.js +134 -0
- package/dist/context/ContextRestoreService.js.map +1 -0
- package/dist/contract/BrainContract.d.ts +93 -0
- package/dist/contract/BrainContract.js +245 -0
- package/dist/contract/BrainContract.js.map +1 -0
- package/dist/core/ContentDedup.d.ts +43 -0
- package/dist/core/ContentDedup.js +145 -0
- package/dist/core/ContentDedup.js.map +1 -0
- package/dist/core/EntityGraph.d.ts +66 -0
- package/dist/core/EntityGraph.js +196 -0
- package/dist/core/EntityGraph.js.map +1 -0
- package/dist/core/EntrySchema.d.ts +46 -0
- package/dist/core/EntrySchema.js +4 -0
- package/dist/core/EntrySchema.js.map +1 -0
- package/dist/core/GraphStore.d.ts +16 -0
- package/dist/core/GraphStore.js +29 -0
- package/dist/core/GraphStore.js.map +1 -0
- package/dist/core/MemoryDecay.d.ts +49 -0
- package/dist/core/MemoryDecay.js +113 -0
- package/dist/core/MemoryDecay.js.map +1 -0
- package/dist/core/ProfileFormat.d.ts +38 -0
- package/dist/core/ProfileFormat.js +254 -0
- package/dist/core/ProfileFormat.js.map +1 -0
- package/dist/core/ProfileManager.d.ts +80 -0
- package/dist/core/ProfileManager.js +269 -0
- package/dist/core/ProfileManager.js.map +1 -0
- package/dist/core/SchemaMigration.d.ts +12 -0
- package/dist/core/SchemaMigration.js +34 -0
- package/dist/core/SchemaMigration.js.map +1 -0
- package/dist/crypto/AgeCrypto.d.ts +26 -0
- package/dist/crypto/AgeCrypto.js +101 -0
- package/dist/crypto/AgeCrypto.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/BrainMcpServer.d.ts +13 -0
- package/dist/mcp/BrainMcpServer.js +223 -0
- package/dist/mcp/BrainMcpServer.js.map +1 -0
- package/dist/mcp/cli.d.ts +2 -0
- package/dist/mcp/cli.js +107 -0
- package/dist/mcp/cli.js.map +1 -0
- package/dist/metrics/ResumeMetrics.d.ts +20 -0
- package/dist/metrics/ResumeMetrics.js +46 -0
- package/dist/metrics/ResumeMetrics.js.map +1 -0
- package/dist/peers/PeerStore.d.ts +17 -0
- package/dist/peers/PeerStore.js +65 -0
- package/dist/peers/PeerStore.js.map +1 -0
- package/dist/policy/PolicyEngine.d.ts +16 -0
- package/dist/policy/PolicyEngine.js +70 -0
- package/dist/policy/PolicyEngine.js.map +1 -0
- package/dist/policy/PolicyEnvelope.d.ts +7 -0
- package/dist/policy/PolicyEnvelope.js +2 -0
- package/dist/policy/PolicyEnvelope.js.map +1 -0
- package/dist/policy/RetentionParser.d.ts +6 -0
- package/dist/policy/RetentionParser.js +48 -0
- package/dist/policy/RetentionParser.js.map +1 -0
- package/dist/shared/AtomicWrite.d.ts +1 -0
- package/dist/shared/AtomicWrite.js +11 -0
- package/dist/shared/AtomicWrite.js.map +1 -0
- package/dist/shared/Clock.d.ts +11 -0
- package/dist/shared/Clock.js +17 -0
- package/dist/shared/Clock.js.map +1 -0
- package/dist/shared/Config.d.ts +15 -0
- package/dist/shared/Config.js +67 -0
- package/dist/shared/Config.js.map +1 -0
- package/dist/shared/Encryption.d.ts +19 -0
- package/dist/shared/Encryption.js +47 -0
- package/dist/shared/Encryption.js.map +1 -0
- package/dist/shared/Logger.d.ts +12 -0
- package/dist/shared/Logger.js +40 -0
- package/dist/shared/Logger.js.map +1 -0
- package/dist/shared/Mutex.d.ts +7 -0
- package/dist/shared/Mutex.js +34 -0
- package/dist/shared/Mutex.js.map +1 -0
- package/dist/shared/SetupErrors.d.ts +31 -0
- package/dist/shared/SetupErrors.js +155 -0
- package/dist/shared/SetupErrors.js.map +1 -0
- package/dist/status/SyncStatusStore.d.ts +17 -0
- package/dist/status/SyncStatusStore.js +48 -0
- package/dist/status/SyncStatusStore.js.map +1 -0
- package/dist/sync/AutoCommitter.d.ts +17 -0
- package/dist/sync/AutoCommitter.js +68 -0
- package/dist/sync/AutoCommitter.js.map +1 -0
- package/dist/sync/ConflictResolver.d.ts +7 -0
- package/dist/sync/ConflictResolver.js +56 -0
- package/dist/sync/ConflictResolver.js.map +1 -0
- package/dist/sync/PushPullManager.d.ts +23 -0
- package/dist/sync/PushPullManager.js +155 -0
- package/dist/sync/PushPullManager.js.map +1 -0
- package/dist/sync/SyncEngine.d.ts +43 -0
- package/dist/sync/SyncEngine.js +145 -0
- package/dist/sync/SyncEngine.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Entity extraction (deterministic, no LLM)
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
/** Known technology keywords for deterministic matching. */
|
|
5
|
+
const TECH_KEYWORDS = new Set([
|
|
6
|
+
'react', 'vue', 'angular', 'svelte', 'next', 'nuxt',
|
|
7
|
+
'node', 'deno', 'bun', 'typescript', 'javascript', 'python', 'rust', 'go',
|
|
8
|
+
'docker', 'kubernetes', 'postgres', 'redis', 'mongodb', 'sqlite',
|
|
9
|
+
'graphql', 'rest', 'grpc', 'websocket',
|
|
10
|
+
'git', 'github', 'gitlab', 'npm', 'yarn', 'pnpm',
|
|
11
|
+
'vitest', 'jest', 'mocha', 'pytest',
|
|
12
|
+
'aws', 'gcp', 'azure', 'vercel', 'netlify',
|
|
13
|
+
'linux', 'macos', 'windows',
|
|
14
|
+
'age', 'sops', 'encryption', 'oauth', 'jwt',
|
|
15
|
+
]);
|
|
16
|
+
/** Common English words excluded from capitalized-phrase detection. */
|
|
17
|
+
const COMMON_WORDS = new Set([
|
|
18
|
+
'the', 'a', 'an', 'is', 'are', 'was', 'were', 'be', 'been', 'being',
|
|
19
|
+
'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could',
|
|
20
|
+
'should', 'may', 'might', 'can', 'shall', 'for', 'and', 'nor', 'but',
|
|
21
|
+
'or', 'yet', 'so', 'in', 'on', 'at', 'to', 'of', 'by', 'with', 'from',
|
|
22
|
+
'up', 'about', 'into', 'over', 'after', 'this', 'that', 'these', 'those',
|
|
23
|
+
'it', 'its', 'not', 'no', 'all', 'each', 'every', 'both', 'few', 'more',
|
|
24
|
+
'most', 'other', 'some', 'such', 'only', 'own', 'same', 'than', 'too',
|
|
25
|
+
'very',
|
|
26
|
+
]);
|
|
27
|
+
/**
|
|
28
|
+
* Extract entities from text using pattern matching.
|
|
29
|
+
* Patterns:
|
|
30
|
+
* - URLs → url
|
|
31
|
+
* - File paths (/, .ts, .js, etc.) → path
|
|
32
|
+
* - @mentions → person
|
|
33
|
+
* - Kebab-case multi-part names → project
|
|
34
|
+
* - Known tech keywords → technology
|
|
35
|
+
* - Capitalized multi-word phrases → concept
|
|
36
|
+
*
|
|
37
|
+
* Deterministic: same input always produces same output.
|
|
38
|
+
*/
|
|
39
|
+
export function extractEntities(text) {
|
|
40
|
+
const entities = [];
|
|
41
|
+
const seen = new Set();
|
|
42
|
+
function add(name, type) {
|
|
43
|
+
const normalized = name.toLowerCase().trim();
|
|
44
|
+
if (normalized.length < 2 || seen.has(normalized))
|
|
45
|
+
return;
|
|
46
|
+
seen.add(normalized);
|
|
47
|
+
entities.push({ name: normalized, type });
|
|
48
|
+
}
|
|
49
|
+
// URLs
|
|
50
|
+
const urlRegex = /https?:\/\/[^\s<>"']+/g;
|
|
51
|
+
for (const m of text.matchAll(urlRegex)) {
|
|
52
|
+
add(m[0], 'url');
|
|
53
|
+
}
|
|
54
|
+
// File paths (Unix-style or with extensions)
|
|
55
|
+
const pathRegex = /(?:\/[\w.-]+){2,}|[\w.-]+\.(?:ts|js|tsx|jsx|py|go|rs|json|yaml|yml|md|toml|sh)/g;
|
|
56
|
+
for (const m of text.matchAll(pathRegex)) {
|
|
57
|
+
add(m[0], 'path');
|
|
58
|
+
}
|
|
59
|
+
// @mentions
|
|
60
|
+
const mentionRegex = /@([\w-]+)/g;
|
|
61
|
+
for (const m of text.matchAll(mentionRegex)) {
|
|
62
|
+
add(m[1], 'person');
|
|
63
|
+
}
|
|
64
|
+
// Project-like names (kebab-case: word-word-word)
|
|
65
|
+
const projectRegex = /\b([a-z][a-z0-9]+-[a-z][a-z0-9]+(?:-[a-z][a-z0-9]+)*)\b/g;
|
|
66
|
+
for (const m of text.matchAll(projectRegex)) {
|
|
67
|
+
if (m[1].length >= 5)
|
|
68
|
+
add(m[1], 'project');
|
|
69
|
+
}
|
|
70
|
+
// Known technology keywords
|
|
71
|
+
const words = text.toLowerCase().split(/[\s\p{P}]+/u);
|
|
72
|
+
for (const word of words) {
|
|
73
|
+
if (TECH_KEYWORDS.has(word)) {
|
|
74
|
+
add(word, 'technology');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Capitalized multi-word phrases (likely names / concepts) — skip common words
|
|
78
|
+
const capitalRegex = /\b([A-Z][a-z]+(?:\s+[A-Z][a-z]+)+)\b/g;
|
|
79
|
+
for (const m of text.matchAll(capitalRegex)) {
|
|
80
|
+
const phraseWords = m[1].split(/\s+/);
|
|
81
|
+
if (phraseWords.every(w => !COMMON_WORDS.has(w.toLowerCase()))) {
|
|
82
|
+
add(m[1], 'concept');
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return entities;
|
|
86
|
+
}
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
// Graph building
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
/**
|
|
91
|
+
* Build an entity graph from entries.
|
|
92
|
+
* Only considers active (non-deleted) entries.
|
|
93
|
+
*/
|
|
94
|
+
export function buildEntityGraph(entries) {
|
|
95
|
+
const nodes = {};
|
|
96
|
+
const edges = [];
|
|
97
|
+
const activeEntries = entries.filter(e => !e.deleted);
|
|
98
|
+
// Extract entities from each entry
|
|
99
|
+
for (const entry of activeEntries) {
|
|
100
|
+
const extracted = extractEntities(entry.content);
|
|
101
|
+
const entryEntityNames = [];
|
|
102
|
+
for (const { name, type } of extracted) {
|
|
103
|
+
if (!nodes[name]) {
|
|
104
|
+
nodes[name] = { name, type, entryIds: [] };
|
|
105
|
+
}
|
|
106
|
+
if (!nodes[name].entryIds.includes(entry.id)) {
|
|
107
|
+
nodes[name].entryIds.push(entry.id);
|
|
108
|
+
}
|
|
109
|
+
entryEntityNames.push(name);
|
|
110
|
+
}
|
|
111
|
+
// Create edges for co-occurring entities within same entry
|
|
112
|
+
for (let i = 0; i < entryEntityNames.length; i++) {
|
|
113
|
+
for (let j = i + 1; j < entryEntityNames.length; j++) {
|
|
114
|
+
edges.push({
|
|
115
|
+
source: entryEntityNames[i],
|
|
116
|
+
target: entryEntityNames[j],
|
|
117
|
+
entryId: entry.id,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
nodes,
|
|
124
|
+
edges,
|
|
125
|
+
metadata: {
|
|
126
|
+
builtAt: new Date().toISOString(),
|
|
127
|
+
entryCount: activeEntries.length,
|
|
128
|
+
nodeCount: Object.keys(nodes).length,
|
|
129
|
+
edgeCount: edges.length,
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
// Scoring
|
|
135
|
+
// ---------------------------------------------------------------------------
|
|
136
|
+
/**
|
|
137
|
+
* Score entries by their entity connectedness.
|
|
138
|
+
* Hub entries (connected to many other entries via shared entities) get higher scores.
|
|
139
|
+
*/
|
|
140
|
+
export function scoreEntries(entries, graph) {
|
|
141
|
+
const activeEntries = entries.filter(e => !e.deleted);
|
|
142
|
+
return activeEntries.map(entry => {
|
|
143
|
+
// Find all entities this entry references
|
|
144
|
+
const myEntities = [];
|
|
145
|
+
for (const [name, node] of Object.entries(graph.nodes)) {
|
|
146
|
+
if (node.entryIds.includes(entry.id)) {
|
|
147
|
+
myEntities.push(name);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Count unique other entries that share entities
|
|
151
|
+
const connectedEntries = new Set();
|
|
152
|
+
for (const entityName of myEntities) {
|
|
153
|
+
const node = graph.nodes[entityName];
|
|
154
|
+
if (node) {
|
|
155
|
+
for (const eid of node.entryIds) {
|
|
156
|
+
if (eid !== entry.id)
|
|
157
|
+
connectedEntries.add(eid);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
entryId: entry.id,
|
|
163
|
+
hubScore: myEntities.length,
|
|
164
|
+
connectedness: connectedEntries.size,
|
|
165
|
+
};
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Get confidence boost based on entity connectedness.
|
|
170
|
+
* Entries connected to 3+ others get a boost.
|
|
171
|
+
*/
|
|
172
|
+
export function connectednessBoost(score) {
|
|
173
|
+
if (score.connectedness >= 5)
|
|
174
|
+
return 0.2;
|
|
175
|
+
if (score.connectedness >= 3)
|
|
176
|
+
return 0.1;
|
|
177
|
+
if (score.connectedness >= 1)
|
|
178
|
+
return 0.05;
|
|
179
|
+
return 0;
|
|
180
|
+
}
|
|
181
|
+
// ---------------------------------------------------------------------------
|
|
182
|
+
// Serialization (git-diffable JSON)
|
|
183
|
+
// ---------------------------------------------------------------------------
|
|
184
|
+
/**
|
|
185
|
+
* Serialize graph to JSON (for graph.json file, git-diffable).
|
|
186
|
+
*/
|
|
187
|
+
export function serializeGraph(graph) {
|
|
188
|
+
return JSON.stringify(graph, null, 2);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Deserialize graph from JSON string.
|
|
192
|
+
*/
|
|
193
|
+
export function deserializeGraph(json) {
|
|
194
|
+
return JSON.parse(json);
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=EntityGraph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EntityGraph.js","sourceRoot":"","sources":["../../src/core/EntityGraph.ts"],"names":[],"mappings":"AAqCA,8EAA8E;AAC9E,4CAA4C;AAC5C,8EAA8E;AAE9E,4DAA4D;AAC5D,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC;IAC5B,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM;IACnD,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI;IACzE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ;IAChE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW;IACtC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM;IAChD,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ;IACnC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS;IAC1C,OAAO,EAAE,OAAO,EAAE,SAAS;IAC3B,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,KAAK;CAC5C,CAAC,CAAC;AAEH,uEAAuE;AACvE,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;IAC3B,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO;IACnE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IACnE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK;IACpE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM;IACrE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IACxE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IACvE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK;IACrE,MAAM;CACP,CAAC,CAAC;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,MAAM,QAAQ,GAA8C,EAAE,CAAC;IAC/D,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,SAAS,GAAG,CAAC,IAAY,EAAE,IAAgB;QACzC,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;QAC7C,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC;YAAE,OAAO;QAC1D,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO;IACP,MAAM,QAAQ,GAAG,wBAAwB,CAAC;IAC1C,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACnB,CAAC;IAED,6CAA6C;IAC7C,MAAM,SAAS,GAAG,iFAAiF,CAAC;IACpG,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACzC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACpB,CAAC;IAED,YAAY;IACZ,MAAM,YAAY,GAAG,YAAY,CAAC;IAClC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QAC5C,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACtB,CAAC;IAED,kDAAkD;IAClD,MAAM,YAAY,GAAG,0DAA0D,CAAC;IAChF,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QAC5C,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC;YAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAC7C,CAAC;IAED,4BAA4B;IAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IACtD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,+EAA+E;IAC/E,MAAM,YAAY,GAAG,uCAAuC,CAAC;IAC7D,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QAC5C,MAAM,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC;YAC/D,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,MAAM,KAAK,GAA+B,EAAE,CAAC;IAC7C,MAAM,KAAK,GAAiB,EAAE,CAAC;IAC/B,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAEtD,mCAAmC;IACnC,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACjD,MAAM,gBAAgB,GAAa,EAAE,CAAC;QAEtC,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,SAAS,EAAE,CAAC;YACvC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBACjB,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;YAC7C,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC7C,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACtC,CAAC;YACD,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAED,2DAA2D;QAC3D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,gBAAgB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACjD,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,gBAAgB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACrD,KAAK,CAAC,IAAI,CAAC;oBACT,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;oBAC3B,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;oBAC3B,OAAO,EAAE,KAAK,CAAC,EAAE;iBAClB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK;QACL,KAAK;QACL,QAAQ,EAAE;YACR,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACjC,UAAU,EAAE,aAAa,CAAC,MAAM;YAChC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM;YACpC,SAAS,EAAE,KAAK,CAAC,MAAM;SACxB;KACF,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,OAAgB,EAAE,KAAkB;IAC/D,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAEtD,OAAO,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;QAC/B,0CAA0C;QAC1C,MAAM,UAAU,GAAa,EAAE,CAAC;QAChC,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACvD,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;gBACrC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxB,CAAC;QACH,CAAC;QAED,iDAAiD;QACjD,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAC;QAC3C,KAAK,MAAM,UAAU,IAAI,UAAU,EAAE,CAAC;YACpC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YACrC,IAAI,IAAI,EAAE,CAAC;gBACT,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;oBAChC,IAAI,GAAG,KAAK,KAAK,CAAC,EAAE;wBAAE,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAClD,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO;YACL,OAAO,EAAE,KAAK,CAAC,EAAE;YACjB,QAAQ,EAAE,UAAU,CAAC,MAAM;YAC3B,aAAa,EAAE,gBAAgB,CAAC,IAAI;SACrC,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAkB;IACnD,IAAI,KAAK,CAAC,aAAa,IAAI,CAAC;QAAE,OAAO,GAAG,CAAC;IACzC,IAAI,KAAK,CAAC,aAAa,IAAI,CAAC;QAAE,OAAO,GAAG,CAAC;IACzC,IAAI,KAAK,CAAC,aAAa,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,OAAO,CAAC,CAAC;AACX,CAAC;AAED,8EAA8E;AAC9E,oCAAoC;AACpC,8EAA8E;AAE9E;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,KAAkB;IAC/C,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAgB,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { PolicyEnvelope } from '../policy/PolicyEnvelope.js';
|
|
2
|
+
export interface ConflictLogEntry {
|
|
3
|
+
at: string;
|
|
4
|
+
loser_device: string;
|
|
5
|
+
loser_updated: string;
|
|
6
|
+
resolution: 'lww' | 'append' | 'tie_deleted' | 'tie_id';
|
|
7
|
+
}
|
|
8
|
+
export type MediaKind = 'video' | 'audio' | 'image';
|
|
9
|
+
export type MediaChannel = 'platform' | 'messenger';
|
|
10
|
+
export type MediaPurpose = 'storage' | 'share';
|
|
11
|
+
export type MediaStatus = 'ready' | 'pending' | 'broken';
|
|
12
|
+
export interface MediaPointer {
|
|
13
|
+
kind: MediaKind;
|
|
14
|
+
provider: string;
|
|
15
|
+
url: string;
|
|
16
|
+
title?: string;
|
|
17
|
+
duration_sec?: number;
|
|
18
|
+
checksum?: string;
|
|
19
|
+
channel?: MediaChannel;
|
|
20
|
+
purpose?: MediaPurpose;
|
|
21
|
+
status?: MediaStatus;
|
|
22
|
+
}
|
|
23
|
+
export interface Entry {
|
|
24
|
+
id: string;
|
|
25
|
+
created: string;
|
|
26
|
+
updated: string;
|
|
27
|
+
category: string;
|
|
28
|
+
content: string;
|
|
29
|
+
source: string;
|
|
30
|
+
confidence: number;
|
|
31
|
+
tags?: string[];
|
|
32
|
+
device_id?: string;
|
|
33
|
+
pinned?: boolean;
|
|
34
|
+
deleted?: boolean;
|
|
35
|
+
deleted_at?: string;
|
|
36
|
+
conflict_log?: ConflictLogEntry[];
|
|
37
|
+
policy?: PolicyEnvelope;
|
|
38
|
+
media_pointers?: MediaPointer[];
|
|
39
|
+
}
|
|
40
|
+
export interface MemoryProfile {
|
|
41
|
+
version: number;
|
|
42
|
+
device_id: string;
|
|
43
|
+
last_sync: string;
|
|
44
|
+
entries: Entry[];
|
|
45
|
+
}
|
|
46
|
+
export declare function createEntryId(): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EntrySchema.js","sourceRoot":"","sources":["../../src/core/EntrySchema.ts"],"names":[],"mappings":"AAmDA,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AACpF,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { EntityGraph } from './EntityGraph.js';
|
|
2
|
+
/**
|
|
3
|
+
* Derive graph.json path from profile path.
|
|
4
|
+
* e.g. "memory-profile.enc.json" → "memory-profile.graph.json"
|
|
5
|
+
* "memory-profile.yaml" → "memory-profile.graph.json"
|
|
6
|
+
*/
|
|
7
|
+
export declare function deriveGraphPath(profilePath: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Read an EntityGraph from a graph.json file.
|
|
10
|
+
* Returns null if file doesn't exist.
|
|
11
|
+
*/
|
|
12
|
+
export declare function readGraphFile(graphPath: string): Promise<EntityGraph | null>;
|
|
13
|
+
/**
|
|
14
|
+
* Write an EntityGraph to a graph.json file using atomic write.
|
|
15
|
+
*/
|
|
16
|
+
export declare function writeGraphFile(graphPath: string, graph: EntityGraph): Promise<void>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { atomicWrite } from '../shared/AtomicWrite.js';
|
|
4
|
+
import { serializeGraph, deserializeGraph } from './EntityGraph.js';
|
|
5
|
+
/**
|
|
6
|
+
* Derive graph.json path from profile path.
|
|
7
|
+
* e.g. "memory-profile.enc.json" → "memory-profile.graph.json"
|
|
8
|
+
* "memory-profile.yaml" → "memory-profile.graph.json"
|
|
9
|
+
*/
|
|
10
|
+
export function deriveGraphPath(profilePath) {
|
|
11
|
+
return profilePath.replace(/\.enc\.json$|\.yaml$/, '.graph.json');
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Read an EntityGraph from a graph.json file.
|
|
15
|
+
* Returns null if file doesn't exist.
|
|
16
|
+
*/
|
|
17
|
+
export async function readGraphFile(graphPath) {
|
|
18
|
+
if (!existsSync(graphPath))
|
|
19
|
+
return null;
|
|
20
|
+
const content = await readFile(graphPath, 'utf-8');
|
|
21
|
+
return deserializeGraph(content);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Write an EntityGraph to a graph.json file using atomic write.
|
|
25
|
+
*/
|
|
26
|
+
export async function writeGraphFile(graphPath, graph) {
|
|
27
|
+
await atomicWrite(graphPath, serializeGraph(graph));
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=GraphStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GraphStore.js","sourceRoot":"","sources":["../../src/core/GraphStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpE;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,WAAmB;IACjD,OAAO,WAAW,CAAC,OAAO,CAAC,sBAAsB,EAAE,aAAa,CAAC,CAAC;AACpE,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,SAAiB;IACnD,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IACxC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACnD,OAAO,gBAAgB,CAAC,OAAO,CAAC,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,SAAiB,EAAE,KAAkB;IACxE,MAAM,WAAW,CAAC,SAAS,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Entry } from './EntrySchema.js';
|
|
2
|
+
export interface DecayConfig {
|
|
3
|
+
halfLife: {
|
|
4
|
+
user: number | null;
|
|
5
|
+
observation: number;
|
|
6
|
+
inference: number;
|
|
7
|
+
session: number;
|
|
8
|
+
[key: string]: number | null;
|
|
9
|
+
};
|
|
10
|
+
threshold: number;
|
|
11
|
+
minAge: number;
|
|
12
|
+
}
|
|
13
|
+
export interface MemoryConfig {
|
|
14
|
+
maxEntries: number;
|
|
15
|
+
decay: DecayConfig;
|
|
16
|
+
}
|
|
17
|
+
export declare const DEFAULT_CONFIG: MemoryConfig;
|
|
18
|
+
export interface CompactResult {
|
|
19
|
+
tombstonesRemoved: number;
|
|
20
|
+
softDeleted: number;
|
|
21
|
+
survived: number;
|
|
22
|
+
byCategory: Record<string, number>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Compute the effective (time-decayed) confidence for an entry.
|
|
26
|
+
* Pure function -- no side effects.
|
|
27
|
+
*/
|
|
28
|
+
export declare function effectiveConfidence(entry: Entry, now: Date, config: DecayConfig): number;
|
|
29
|
+
/**
|
|
30
|
+
* Apply decay-based soft-delete to entries whose effective confidence
|
|
31
|
+
* has dropped below the configured threshold (and are older than minAge).
|
|
32
|
+
*/
|
|
33
|
+
export declare function applyDecay(entries: Entry[], now: Date, config: MemoryConfig): {
|
|
34
|
+
entries: Entry[];
|
|
35
|
+
softDeleted: number;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Enforce maxEntries limit by soft-deleting the lowest effectiveConfidence
|
|
39
|
+
* entries. Pinned entries are never removed.
|
|
40
|
+
*/
|
|
41
|
+
export declare function enforceMaxEntries(entries: Entry[], now: Date, config: MemoryConfig): {
|
|
42
|
+
entries: Entry[];
|
|
43
|
+
softDeleted: number;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Parse a MemoryConfig from raw JSON data (e.g. from enc.json),
|
|
47
|
+
* merging missing fields with DEFAULT_CONFIG.
|
|
48
|
+
*/
|
|
49
|
+
export declare function parseMemoryConfig(raw: unknown): MemoryConfig;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
export const DEFAULT_CONFIG = {
|
|
2
|
+
maxEntries: 2000,
|
|
3
|
+
decay: {
|
|
4
|
+
halfLife: {
|
|
5
|
+
user: null,
|
|
6
|
+
observation: 90,
|
|
7
|
+
inference: 30,
|
|
8
|
+
session: 10,
|
|
9
|
+
},
|
|
10
|
+
threshold: 0.1,
|
|
11
|
+
minAge: 1,
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Pure functions
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
/**
|
|
18
|
+
* Compute the effective (time-decayed) confidence for an entry.
|
|
19
|
+
* Pure function -- no side effects.
|
|
20
|
+
*/
|
|
21
|
+
export function effectiveConfidence(entry, now, config) {
|
|
22
|
+
if (entry.pinned)
|
|
23
|
+
return entry.confidence;
|
|
24
|
+
const days = (now.getTime() - new Date(entry.updated).getTime()) / 86_400_000;
|
|
25
|
+
const rawHl = config.halfLife[entry.source];
|
|
26
|
+
if (rawHl === null)
|
|
27
|
+
return entry.confidence;
|
|
28
|
+
const hl = rawHl ?? 30;
|
|
29
|
+
return entry.confidence * Math.pow(0.5, days / hl);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Apply decay-based soft-delete to entries whose effective confidence
|
|
33
|
+
* has dropped below the configured threshold (and are older than minAge).
|
|
34
|
+
*/
|
|
35
|
+
export function applyDecay(entries, now, config) {
|
|
36
|
+
let softDeleted = 0;
|
|
37
|
+
const result = entries.map(entry => {
|
|
38
|
+
// Skip already deleted entries
|
|
39
|
+
if (entry.deleted)
|
|
40
|
+
return entry;
|
|
41
|
+
// Skip pinned entries
|
|
42
|
+
if (entry.pinned)
|
|
43
|
+
return entry;
|
|
44
|
+
// Skip entries whose source has null halfLife (no decay, e.g. user source)
|
|
45
|
+
if (config.decay.halfLife[entry.source] === null)
|
|
46
|
+
return entry;
|
|
47
|
+
const ec = effectiveConfidence(entry, now, config.decay);
|
|
48
|
+
const ageDays = (now.getTime() - new Date(entry.created).getTime()) / 86_400_000;
|
|
49
|
+
if (ec < config.decay.threshold && ageDays > config.decay.minAge) {
|
|
50
|
+
softDeleted++;
|
|
51
|
+
return { ...entry, deleted: true, deleted_at: now.toISOString() };
|
|
52
|
+
}
|
|
53
|
+
return entry;
|
|
54
|
+
});
|
|
55
|
+
return { entries: result, softDeleted };
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Enforce maxEntries limit by soft-deleting the lowest effectiveConfidence
|
|
59
|
+
* entries. Pinned entries are never removed.
|
|
60
|
+
*/
|
|
61
|
+
export function enforceMaxEntries(entries, now, config) {
|
|
62
|
+
const active = entries.filter(e => !e.deleted);
|
|
63
|
+
if (active.length <= config.maxEntries) {
|
|
64
|
+
return { entries, softDeleted: 0 };
|
|
65
|
+
}
|
|
66
|
+
// Sort unpinned active entries by effectiveConfidence (ascending)
|
|
67
|
+
const scored = active
|
|
68
|
+
.filter(e => !e.pinned)
|
|
69
|
+
.map(e => ({ entry: e, score: effectiveConfidence(e, now, config.decay) }))
|
|
70
|
+
.sort((a, b) => a.score - b.score);
|
|
71
|
+
const toDelete = active.length - config.maxEntries;
|
|
72
|
+
const deleteIds = new Set(scored.slice(0, toDelete).map(s => s.entry.id));
|
|
73
|
+
let softDeleted = 0;
|
|
74
|
+
const result = entries.map(entry => {
|
|
75
|
+
if (deleteIds.has(entry.id)) {
|
|
76
|
+
softDeleted++;
|
|
77
|
+
return { ...entry, deleted: true, deleted_at: now.toISOString() };
|
|
78
|
+
}
|
|
79
|
+
return entry;
|
|
80
|
+
});
|
|
81
|
+
return { entries: result, softDeleted };
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Parse a MemoryConfig from raw JSON data (e.g. from enc.json),
|
|
85
|
+
* merging missing fields with DEFAULT_CONFIG.
|
|
86
|
+
*/
|
|
87
|
+
export function parseMemoryConfig(raw) {
|
|
88
|
+
if (!raw || typeof raw !== 'object')
|
|
89
|
+
return { ...DEFAULT_CONFIG };
|
|
90
|
+
const obj = raw;
|
|
91
|
+
const rawDecay = (typeof obj.decay === 'object' && obj.decay !== null)
|
|
92
|
+
? obj.decay
|
|
93
|
+
: {};
|
|
94
|
+
const rawHL = (typeof rawDecay.halfLife === 'object' && rawDecay.halfLife !== null)
|
|
95
|
+
? rawDecay.halfLife
|
|
96
|
+
: {};
|
|
97
|
+
return {
|
|
98
|
+
maxEntries: typeof obj.maxEntries === 'number' ? obj.maxEntries : DEFAULT_CONFIG.maxEntries,
|
|
99
|
+
decay: {
|
|
100
|
+
halfLife: {
|
|
101
|
+
...DEFAULT_CONFIG.decay.halfLife,
|
|
102
|
+
...rawHL,
|
|
103
|
+
},
|
|
104
|
+
threshold: typeof rawDecay.threshold === 'number'
|
|
105
|
+
? rawDecay.threshold
|
|
106
|
+
: DEFAULT_CONFIG.decay.threshold,
|
|
107
|
+
minAge: typeof rawDecay.minAge === 'number'
|
|
108
|
+
? rawDecay.minAge
|
|
109
|
+
: DEFAULT_CONFIG.decay.minAge,
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=MemoryDecay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MemoryDecay.js","sourceRoot":"","sources":["../../src/core/MemoryDecay.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { MemoryProfile } from './EntrySchema.js';
|
|
2
|
+
/** Encrypted profile JSON structure (v2 age-block format). */
|
|
3
|
+
export interface EncryptedProfile {
|
|
4
|
+
_aigentry: {
|
|
5
|
+
version: number;
|
|
6
|
+
format: 'age-block' | 'plaintext-fallback';
|
|
7
|
+
recipients: string[];
|
|
8
|
+
modified: string;
|
|
9
|
+
device_id?: string;
|
|
10
|
+
};
|
|
11
|
+
entries: Record<string, string>;
|
|
12
|
+
}
|
|
13
|
+
export declare class ProfileFormat {
|
|
14
|
+
static serialize(profile: MemoryProfile): string;
|
|
15
|
+
static deserialize(content: string): MemoryProfile;
|
|
16
|
+
/**
|
|
17
|
+
* Read profile from file, handling all formats:
|
|
18
|
+
* - age-block JSON (v2 encrypted)
|
|
19
|
+
* - plaintext JSON (v2 fallback)
|
|
20
|
+
* - plaintext YAML (legacy v1/v2)
|
|
21
|
+
* - sops YAML (legacy, read as plaintext — sops binary no longer used)
|
|
22
|
+
*/
|
|
23
|
+
static readFromFile(filePath: string): Promise<MemoryProfile>;
|
|
24
|
+
/**
|
|
25
|
+
* Write profile to encrypted JSON format.
|
|
26
|
+
* Falls back to plaintext JSON if encryption fails (Invisible Security).
|
|
27
|
+
*/
|
|
28
|
+
static writeToFile(filePath: string, profile: MemoryProfile): Promise<void>;
|
|
29
|
+
/** Read and decrypt an age-block JSON profile. */
|
|
30
|
+
private static readEncryptedJson;
|
|
31
|
+
/** Encrypt a MemoryProfile into EncryptedProfile format. Preserves existing recipients from file. */
|
|
32
|
+
private static encryptProfile;
|
|
33
|
+
/**
|
|
34
|
+
* Migrate legacy YAML to new enc.json format.
|
|
35
|
+
* Called after reading legacy format — backs up .yaml to .yaml.bak.
|
|
36
|
+
*/
|
|
37
|
+
static migrateLegacyYaml(yamlPath: string): Promise<void>;
|
|
38
|
+
}
|