@exaudeus/memory-mcp 1.9.8 → 1.9.9
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/dist/config-manager.d.ts +3 -1
- package/dist/config-manager.js +5 -0
- package/dist/index.js +57 -9
- package/package.json +1 -1
package/dist/config-manager.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { MemoryConfig } from './types.js';
|
|
1
|
+
import type { MemoryConfig, BehaviorConfig } from './types.js';
|
|
2
2
|
import { type LoadedConfig, type ConfigOrigin } from './config.js';
|
|
3
3
|
import { MarkdownMemoryStore } from './store.js';
|
|
4
4
|
/** Health status for a lobe (matches existing LobeHealth in index.ts) */
|
|
@@ -27,6 +27,7 @@ export declare class ConfigManager {
|
|
|
27
27
|
private stores;
|
|
28
28
|
private lobeHealth;
|
|
29
29
|
private configMtime;
|
|
30
|
+
private behaviorConfig?;
|
|
30
31
|
/** Cached alwaysInclude lobe names — recomputed atomically on reload. */
|
|
31
32
|
private cachedAlwaysIncludeLobes;
|
|
32
33
|
protected statFile(path: string): Promise<{
|
|
@@ -55,6 +56,7 @@ export declare class ConfigManager {
|
|
|
55
56
|
getLobeNames(): readonly string[];
|
|
56
57
|
getLobeHealth(lobe: string): LobeHealth | undefined;
|
|
57
58
|
getConfigOrigin(): ConfigOrigin;
|
|
59
|
+
getBehaviorConfig(): BehaviorConfig | undefined;
|
|
58
60
|
getLobeConfig(lobe: string): MemoryConfig | undefined;
|
|
59
61
|
/** Returns lobe names where alwaysInclude is true. Cached; rebuilt atomically on hot-reload. */
|
|
60
62
|
getAlwaysIncludeLobes(): readonly string[];
|
package/dist/config-manager.js
CHANGED
|
@@ -28,6 +28,7 @@ export class ConfigManager {
|
|
|
28
28
|
this.stores = initialStores;
|
|
29
29
|
this.lobeHealth = initialHealth;
|
|
30
30
|
this.configMtime = Date.now(); // Initial mtime (will be updated on first stat)
|
|
31
|
+
this.behaviorConfig = initial.behavior;
|
|
31
32
|
this.cachedAlwaysIncludeLobes = ConfigManager.computeAlwaysIncludeLobes(this.lobeConfigs);
|
|
32
33
|
}
|
|
33
34
|
/** Derive alwaysInclude lobe names from config — pure, no side effects. */
|
|
@@ -114,6 +115,7 @@ export class ConfigManager {
|
|
|
114
115
|
this.stores = newStores;
|
|
115
116
|
this.lobeHealth = newHealth;
|
|
116
117
|
this.configMtime = newMtime;
|
|
118
|
+
this.behaviorConfig = newConfig.behavior;
|
|
117
119
|
this.cachedAlwaysIncludeLobes = ConfigManager.computeAlwaysIncludeLobes(newConfig.configs);
|
|
118
120
|
const lobeCount = newConfig.configs.size;
|
|
119
121
|
const degradedCount = Array.from(newHealth.values()).filter(h => h.status === 'degraded').length;
|
|
@@ -139,6 +141,9 @@ export class ConfigManager {
|
|
|
139
141
|
getConfigOrigin() {
|
|
140
142
|
return this.configOrigin;
|
|
141
143
|
}
|
|
144
|
+
getBehaviorConfig() {
|
|
145
|
+
return this.behaviorConfig;
|
|
146
|
+
}
|
|
142
147
|
getLobeConfig(lobe) {
|
|
143
148
|
return this.lobeConfigs.get(lobe);
|
|
144
149
|
}
|
package/dist/index.js
CHANGED
|
@@ -497,7 +497,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
497
497
|
lobes: lobeInfo,
|
|
498
498
|
alwaysIncludeLobes: alwaysIncludeNames,
|
|
499
499
|
configFile: configFileDisplay(),
|
|
500
|
-
configSource:
|
|
500
|
+
configSource: configManager.getConfigOrigin().source,
|
|
501
501
|
totalLobes: lobeInfo.length,
|
|
502
502
|
degradedLobes: lobeInfo.filter((l) => l.health === 'degraded').length,
|
|
503
503
|
};
|
|
@@ -778,8 +778,15 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
778
778
|
}
|
|
779
779
|
const ctx = resolveToolContext(effectiveLobe);
|
|
780
780
|
if (!ctx.ok) {
|
|
781
|
+
const availableLobes = configManager.getLobeNames();
|
|
782
|
+
if (availableLobes.length === 0) {
|
|
783
|
+
return {
|
|
784
|
+
content: [{ type: 'text', text: `No lobes configured for preferences. Run memory_bootstrap(lobe: "your-project-name", root: "/absolute/path/to/repo") first, then store the preference with prefer(rule: "...", lobe: "<your-lobe>").` }],
|
|
785
|
+
isError: true,
|
|
786
|
+
};
|
|
787
|
+
}
|
|
781
788
|
return {
|
|
782
|
-
content: [{ type: 'text', text: `No global lobe configured for preferences. Specify a lobe: prefer(rule: "...", lobe: "...").\nAvailable: ${
|
|
789
|
+
content: [{ type: 'text', text: `No global lobe configured for preferences. Specify a lobe: prefer(rule: "...", lobe: "...").\nAvailable: ${availableLobes.join(', ')}` }],
|
|
783
790
|
isError: true,
|
|
784
791
|
};
|
|
785
792
|
}
|
|
@@ -825,8 +832,15 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
825
832
|
}
|
|
826
833
|
}
|
|
827
834
|
if (!effectiveFixLobe) {
|
|
835
|
+
const availableLobes = configManager.getLobeNames();
|
|
836
|
+
if (availableLobes.length === 0) {
|
|
837
|
+
return {
|
|
838
|
+
content: [{ type: 'text', text: `No lobes configured. Run memory_bootstrap(lobe: "your-project-name", root: "/absolute/path/to/repo") first, then retry fix with the entry ID.` }],
|
|
839
|
+
isError: true,
|
|
840
|
+
};
|
|
841
|
+
}
|
|
828
842
|
return {
|
|
829
|
-
content: [{ type: 'text', text: `Entry "${id}" not found in any lobe. Available: ${
|
|
843
|
+
content: [{ type: 'text', text: `Entry "${id}" not found in any lobe. Available: ${availableLobes.join(', ')}` }],
|
|
830
844
|
isError: true,
|
|
831
845
|
};
|
|
832
846
|
}
|
|
@@ -1260,6 +1274,13 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1260
1274
|
sections.push(crashSection);
|
|
1261
1275
|
if (degradedSection)
|
|
1262
1276
|
sections.push(degradedSection);
|
|
1277
|
+
if (allBriefingLobeNames.length === 0) {
|
|
1278
|
+
sections.push('## No Lobes Configured\n\n' +
|
|
1279
|
+
'No memory lobes exist yet. Run **memory_bootstrap** to create one for this project:\n\n' +
|
|
1280
|
+
'```\nmemory_bootstrap(lobe: "your-project-name", root: "/absolute/path/to/repo")\n```\n\n' +
|
|
1281
|
+
'After bootstrapping, call **memory_context** again to load project context.');
|
|
1282
|
+
return { content: [{ type: 'text', text: sections.join('\n\n---\n\n') }] };
|
|
1283
|
+
}
|
|
1263
1284
|
// Collect briefing, stale entries, and entry counts across all lobes
|
|
1264
1285
|
// (alwaysInclude lobes are in the lobe list — no separate global store query needed)
|
|
1265
1286
|
const allStale = [];
|
|
@@ -1472,6 +1493,11 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1472
1493
|
// Combined stats across all lobes
|
|
1473
1494
|
const sections = [];
|
|
1474
1495
|
const allLobeNames = configManager.getLobeNames();
|
|
1496
|
+
if (allLobeNames.length === 0) {
|
|
1497
|
+
return {
|
|
1498
|
+
content: [{ type: 'text', text: 'No lobes configured. Run memory_bootstrap(lobe: "your-project-name", root: "/absolute/path/to/repo") first, then retry memory_stats.' }],
|
|
1499
|
+
};
|
|
1500
|
+
}
|
|
1475
1501
|
const alwaysIncludeSet = new Set(configManager.getAlwaysIncludeLobes());
|
|
1476
1502
|
for (const lobeName of allLobeNames) {
|
|
1477
1503
|
const store = configManager.getStore(lobeName);
|
|
@@ -1487,7 +1513,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1487
1513
|
const { lobe: rawLobe } = z.object({
|
|
1488
1514
|
lobe: z.string().optional(),
|
|
1489
1515
|
}).parse(args ?? {});
|
|
1490
|
-
const
|
|
1516
|
+
const currentLobeNames = configManager.getLobeNames();
|
|
1517
|
+
const lobeName = rawLobe ?? (currentLobeNames.length === 1 ? currentLobeNames[0] : undefined);
|
|
1491
1518
|
const ctx = resolveToolContext(lobeName);
|
|
1492
1519
|
if (!ctx.ok)
|
|
1493
1520
|
return contextError(ctx);
|
|
@@ -1550,10 +1577,31 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1550
1577
|
await configManager.ensureFresh();
|
|
1551
1578
|
}
|
|
1552
1579
|
}
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1580
|
+
const effectiveLobe = rawLobe ?? (configManager.getLobeNames().length === 1 ? configManager.getLobeNames()[0] : undefined);
|
|
1581
|
+
if (!effectiveLobe) {
|
|
1582
|
+
return {
|
|
1583
|
+
content: [{
|
|
1584
|
+
type: 'text',
|
|
1585
|
+
text: `memory_bootstrap requires a lobe when multiple lobes exist. Available: ${configManager.getLobeNames().join(', ')}`,
|
|
1586
|
+
}],
|
|
1587
|
+
isError: true,
|
|
1588
|
+
};
|
|
1589
|
+
}
|
|
1590
|
+
const store = configManager.getStore(effectiveLobe);
|
|
1591
|
+
if (!store) {
|
|
1592
|
+
const origin = configManager.getConfigOrigin();
|
|
1593
|
+
const hint = origin.source === 'file'
|
|
1594
|
+
? `Check ${origin.path} and confirm lobe "${effectiveLobe}" exists and points at a valid repo root.`
|
|
1595
|
+
: `Run memory_bootstrap(lobe: "${effectiveLobe}", root: "/absolute/path/to/repo") again to create the lobe.`;
|
|
1596
|
+
return {
|
|
1597
|
+
content: [{
|
|
1598
|
+
type: 'text',
|
|
1599
|
+
text: `Bootstrap could not resolve lobe "${effectiveLobe}" after config update. ${hint}`,
|
|
1600
|
+
}],
|
|
1601
|
+
isError: true,
|
|
1602
|
+
};
|
|
1603
|
+
}
|
|
1604
|
+
const ctx = { ok: true, store, label: effectiveLobe };
|
|
1557
1605
|
const results = await ctx.store.bootstrap();
|
|
1558
1606
|
const stored = results.filter((r) => r.kind === 'stored');
|
|
1559
1607
|
const failed = results.filter((r) => r.kind !== 'stored');
|
|
@@ -1701,7 +1749,7 @@ async function buildDiagnosticsText(showFullCrashHistory) {
|
|
|
1701
1749
|
sections.push('');
|
|
1702
1750
|
// Active behavior config — shows effective values and highlights user overrides
|
|
1703
1751
|
sections.push('### Active Behavior Config');
|
|
1704
|
-
sections.push(formatBehaviorConfigSection(
|
|
1752
|
+
sections.push(formatBehaviorConfigSection(configManager.getBehaviorConfig()));
|
|
1705
1753
|
sections.push('');
|
|
1706
1754
|
const latestCrash = await readLatestCrash();
|
|
1707
1755
|
if (latestCrash) {
|