@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.
Files changed (136) hide show
  1. package/bin/aigentry-brain-mcp.mjs +17 -0
  2. package/bin/aigentry-brain-setup.mjs +17 -0
  3. package/bin/aigentry-brain.mjs +17 -0
  4. package/dist/audit/AuditTrail.d.ts +15 -0
  5. package/dist/audit/AuditTrail.js +43 -0
  6. package/dist/audit/AuditTrail.js.map +1 -0
  7. package/dist/backend/GitBackend.d.ts +27 -0
  8. package/dist/backend/GitBackend.js +201 -0
  9. package/dist/backend/GitBackend.js.map +1 -0
  10. package/dist/backend/SyncBackend.d.ts +13 -0
  11. package/dist/backend/SyncBackend.js +2 -0
  12. package/dist/backend/SyncBackend.js.map +1 -0
  13. package/dist/cli/AutoUpdater.d.ts +7 -0
  14. package/dist/cli/AutoUpdater.js +275 -0
  15. package/dist/cli/AutoUpdater.js.map +1 -0
  16. package/dist/cli/ConfigStore.d.ts +17 -0
  17. package/dist/cli/ConfigStore.js +50 -0
  18. package/dist/cli/ConfigStore.js.map +1 -0
  19. package/dist/cli/GhIntegration.d.ts +55 -0
  20. package/dist/cli/GhIntegration.js +192 -0
  21. package/dist/cli/GhIntegration.js.map +1 -0
  22. package/dist/cli/Prerequisites.d.ts +48 -0
  23. package/dist/cli/Prerequisites.js +182 -0
  24. package/dist/cli/Prerequisites.js.map +1 -0
  25. package/dist/cli/SetupWizard.d.ts +26 -0
  26. package/dist/cli/SetupWizard.js +407 -0
  27. package/dist/cli/SetupWizard.js.map +1 -0
  28. package/dist/cli/braincli.d.ts +2 -0
  29. package/dist/cli/braincli.js +260 -0
  30. package/dist/cli/braincli.js.map +1 -0
  31. package/dist/cli/setup.d.ts +25 -0
  32. package/dist/cli/setup.js +238 -0
  33. package/dist/cli/setup.js.map +1 -0
  34. package/dist/context/ConfidenceGuard.d.ts +11 -0
  35. package/dist/context/ConfidenceGuard.js +32 -0
  36. package/dist/context/ConfidenceGuard.js.map +1 -0
  37. package/dist/context/ContextBudgetPolicy.d.ts +21 -0
  38. package/dist/context/ContextBudgetPolicy.js +136 -0
  39. package/dist/context/ContextBudgetPolicy.js.map +1 -0
  40. package/dist/context/ContextPacker.d.ts +30 -0
  41. package/dist/context/ContextPacker.js +219 -0
  42. package/dist/context/ContextPacker.js.map +1 -0
  43. package/dist/context/ContextRestoreService.d.ts +39 -0
  44. package/dist/context/ContextRestoreService.js +134 -0
  45. package/dist/context/ContextRestoreService.js.map +1 -0
  46. package/dist/contract/BrainContract.d.ts +93 -0
  47. package/dist/contract/BrainContract.js +245 -0
  48. package/dist/contract/BrainContract.js.map +1 -0
  49. package/dist/core/ContentDedup.d.ts +43 -0
  50. package/dist/core/ContentDedup.js +145 -0
  51. package/dist/core/ContentDedup.js.map +1 -0
  52. package/dist/core/EntityGraph.d.ts +66 -0
  53. package/dist/core/EntityGraph.js +196 -0
  54. package/dist/core/EntityGraph.js.map +1 -0
  55. package/dist/core/EntrySchema.d.ts +46 -0
  56. package/dist/core/EntrySchema.js +4 -0
  57. package/dist/core/EntrySchema.js.map +1 -0
  58. package/dist/core/GraphStore.d.ts +16 -0
  59. package/dist/core/GraphStore.js +29 -0
  60. package/dist/core/GraphStore.js.map +1 -0
  61. package/dist/core/MemoryDecay.d.ts +49 -0
  62. package/dist/core/MemoryDecay.js +113 -0
  63. package/dist/core/MemoryDecay.js.map +1 -0
  64. package/dist/core/ProfileFormat.d.ts +38 -0
  65. package/dist/core/ProfileFormat.js +254 -0
  66. package/dist/core/ProfileFormat.js.map +1 -0
  67. package/dist/core/ProfileManager.d.ts +80 -0
  68. package/dist/core/ProfileManager.js +269 -0
  69. package/dist/core/ProfileManager.js.map +1 -0
  70. package/dist/core/SchemaMigration.d.ts +12 -0
  71. package/dist/core/SchemaMigration.js +34 -0
  72. package/dist/core/SchemaMigration.js.map +1 -0
  73. package/dist/crypto/AgeCrypto.d.ts +26 -0
  74. package/dist/crypto/AgeCrypto.js +101 -0
  75. package/dist/crypto/AgeCrypto.js.map +1 -0
  76. package/dist/index.d.ts +38 -0
  77. package/dist/index.js +30 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/mcp/BrainMcpServer.d.ts +13 -0
  80. package/dist/mcp/BrainMcpServer.js +223 -0
  81. package/dist/mcp/BrainMcpServer.js.map +1 -0
  82. package/dist/mcp/cli.d.ts +2 -0
  83. package/dist/mcp/cli.js +107 -0
  84. package/dist/mcp/cli.js.map +1 -0
  85. package/dist/metrics/ResumeMetrics.d.ts +20 -0
  86. package/dist/metrics/ResumeMetrics.js +46 -0
  87. package/dist/metrics/ResumeMetrics.js.map +1 -0
  88. package/dist/peers/PeerStore.d.ts +17 -0
  89. package/dist/peers/PeerStore.js +65 -0
  90. package/dist/peers/PeerStore.js.map +1 -0
  91. package/dist/policy/PolicyEngine.d.ts +16 -0
  92. package/dist/policy/PolicyEngine.js +70 -0
  93. package/dist/policy/PolicyEngine.js.map +1 -0
  94. package/dist/policy/PolicyEnvelope.d.ts +7 -0
  95. package/dist/policy/PolicyEnvelope.js +2 -0
  96. package/dist/policy/PolicyEnvelope.js.map +1 -0
  97. package/dist/policy/RetentionParser.d.ts +6 -0
  98. package/dist/policy/RetentionParser.js +48 -0
  99. package/dist/policy/RetentionParser.js.map +1 -0
  100. package/dist/shared/AtomicWrite.d.ts +1 -0
  101. package/dist/shared/AtomicWrite.js +11 -0
  102. package/dist/shared/AtomicWrite.js.map +1 -0
  103. package/dist/shared/Clock.d.ts +11 -0
  104. package/dist/shared/Clock.js +17 -0
  105. package/dist/shared/Clock.js.map +1 -0
  106. package/dist/shared/Config.d.ts +15 -0
  107. package/dist/shared/Config.js +67 -0
  108. package/dist/shared/Config.js.map +1 -0
  109. package/dist/shared/Encryption.d.ts +19 -0
  110. package/dist/shared/Encryption.js +47 -0
  111. package/dist/shared/Encryption.js.map +1 -0
  112. package/dist/shared/Logger.d.ts +12 -0
  113. package/dist/shared/Logger.js +40 -0
  114. package/dist/shared/Logger.js.map +1 -0
  115. package/dist/shared/Mutex.d.ts +7 -0
  116. package/dist/shared/Mutex.js +34 -0
  117. package/dist/shared/Mutex.js.map +1 -0
  118. package/dist/shared/SetupErrors.d.ts +31 -0
  119. package/dist/shared/SetupErrors.js +155 -0
  120. package/dist/shared/SetupErrors.js.map +1 -0
  121. package/dist/status/SyncStatusStore.d.ts +17 -0
  122. package/dist/status/SyncStatusStore.js +48 -0
  123. package/dist/status/SyncStatusStore.js.map +1 -0
  124. package/dist/sync/AutoCommitter.d.ts +17 -0
  125. package/dist/sync/AutoCommitter.js +68 -0
  126. package/dist/sync/AutoCommitter.js.map +1 -0
  127. package/dist/sync/ConflictResolver.d.ts +7 -0
  128. package/dist/sync/ConflictResolver.js +56 -0
  129. package/dist/sync/ConflictResolver.js.map +1 -0
  130. package/dist/sync/PushPullManager.d.ts +23 -0
  131. package/dist/sync/PushPullManager.js +155 -0
  132. package/dist/sync/PushPullManager.js.map +1 -0
  133. package/dist/sync/SyncEngine.d.ts +43 -0
  134. package/dist/sync/SyncEngine.js +145 -0
  135. package/dist/sync/SyncEngine.js.map +1 -0
  136. 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":"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"}
@@ -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,4 @@
1
+ export function createEntryId() {
2
+ return `mem_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
3
+ }
4
+ //# sourceMappingURL=EntrySchema.js.map
@@ -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
+ }