engrm 0.4.39 → 0.4.41
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 +6 -0
- package/dist/cli.js +55 -0
- package/dist/hooks/session-start.js +1 -1
- package/dist/hooks/stop.js +1 -1
- package/dist/server.js +1515 -1403
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -60,6 +60,12 @@ openclaw plugins install engrm-openclaw-plugin
|
|
|
60
60
|
/engrm status
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
+
To register a remote Engrm HTTP MCP endpoint in OpenClaw after enabling `engrm serve --http`:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
./openclaw/install-or-update-openclaw-mcp.sh http://HOST:3767/mcp YOUR_BEARER_TOKEN
|
|
67
|
+
```
|
|
68
|
+
|
|
63
69
|
**What works:**
|
|
64
70
|
- ✅ Session startup memory injection
|
|
65
71
|
- ✅ Automatic session capture
|
package/dist/cli.js
CHANGED
|
@@ -4150,18 +4150,23 @@ function getCaptureStatus(db, input = {}) {
|
|
|
4150
4150
|
const codexHooks = join7(home, ".codex", "hooks.json");
|
|
4151
4151
|
const opencodeConfig = join7(home, ".config", "opencode", "opencode.json");
|
|
4152
4152
|
const opencodePlugin = join7(home, ".config", "opencode", "plugins", "engrm.js");
|
|
4153
|
+
const openclawConfig = join7(home, ".openclaw", "openclaw.json");
|
|
4154
|
+
const openclawPlugin = join7(home, ".openclaw", "extensions", "engrm", "openclaw.plugin.json");
|
|
4153
4155
|
const config = configExists2() ? loadConfig2() : null;
|
|
4154
4156
|
const claudeJsonContent = existsSync7(claudeJson) ? readFileSync7(claudeJson, "utf-8") : "";
|
|
4155
4157
|
const claudeSettingsContent = existsSync7(claudeSettings) ? readFileSync7(claudeSettings, "utf-8") : "";
|
|
4156
4158
|
const codexConfigContent = existsSync7(codexConfig) ? readFileSync7(codexConfig, "utf-8") : "";
|
|
4157
4159
|
const codexHooksContent = existsSync7(codexHooks) ? readFileSync7(codexHooks, "utf-8") : "";
|
|
4158
4160
|
const opencodeConfigContent = existsSync7(opencodeConfig) ? readFileSync7(opencodeConfig, "utf-8") : "";
|
|
4161
|
+
const openclawConfigContent = existsSync7(openclawConfig) ? readFileSync7(openclawConfig, "utf-8") : "";
|
|
4159
4162
|
const claudeMcpRegistered = claudeJsonContent.includes('"engrm"');
|
|
4160
4163
|
const claudeHooksRegistered = claudeSettingsContent.includes("engrm") || claudeSettingsContent.includes("session-start") || claudeSettingsContent.includes("user-prompt-submit");
|
|
4161
4164
|
const codexMcpRegistered = codexConfigContent.includes("[mcp_servers.engrm]") || codexConfigContent.includes(`[mcp_servers.${LEGACY_CODEX_SERVER_NAME2}]`);
|
|
4162
4165
|
const codexHooksRegistered = codexHooksContent.includes('"SessionStart"') && codexHooksContent.includes('"Stop"');
|
|
4163
4166
|
const opencodeMcpRegistered = opencodeConfigContent.includes('"engrm"') && opencodeConfigContent.includes('"type"') && opencodeConfigContent.includes('"local"');
|
|
4164
4167
|
const opencodePluginRegistered = existsSync7(opencodePlugin);
|
|
4168
|
+
const openclawMcpRegistered = hasOpenClawMcpRegistration(openclawConfigContent);
|
|
4169
|
+
const openclawPluginRegistered = existsSync7(openclawPlugin);
|
|
4165
4170
|
let claudeHookCount = 0;
|
|
4166
4171
|
let claudeSessionStartHook = false;
|
|
4167
4172
|
let claudeUserPromptHook = false;
|
|
@@ -4251,6 +4256,8 @@ function getCaptureStatus(db, input = {}) {
|
|
|
4251
4256
|
codex_session_start_hook: codexSessionStartHook,
|
|
4252
4257
|
codex_stop_hook: codexStopHook,
|
|
4253
4258
|
codex_raw_chronology_supported: false,
|
|
4259
|
+
openclaw_mcp_registered: openclawMcpRegistered,
|
|
4260
|
+
openclaw_plugin_registered: openclawPluginRegistered,
|
|
4254
4261
|
opencode_mcp_registered: opencodeMcpRegistered,
|
|
4255
4262
|
opencode_plugin_registered: opencodePluginRegistered,
|
|
4256
4263
|
recent_user_prompts: recentUserPrompts,
|
|
@@ -4271,6 +4278,16 @@ function parseNullableInt(value) {
|
|
|
4271
4278
|
const parsed = Number.parseInt(value, 10);
|
|
4272
4279
|
return Number.isFinite(parsed) ? parsed : null;
|
|
4273
4280
|
}
|
|
4281
|
+
function hasOpenClawMcpRegistration(content) {
|
|
4282
|
+
if (!content)
|
|
4283
|
+
return false;
|
|
4284
|
+
try {
|
|
4285
|
+
const parsed = JSON.parse(content);
|
|
4286
|
+
return Boolean(parsed.mcp?.servers?.engrm);
|
|
4287
|
+
} catch {
|
|
4288
|
+
return content.includes('"mcp"') && content.includes('"servers"') && content.includes('"engrm"');
|
|
4289
|
+
}
|
|
4290
|
+
}
|
|
4274
4291
|
|
|
4275
4292
|
// src/sync/auth.ts
|
|
4276
4293
|
var LEGACY_PUBLIC_HOSTS = new Set(["www.candengo.com", "candengo.com"]);
|
|
@@ -4713,16 +4730,21 @@ function handleStatus() {
|
|
|
4713
4730
|
const claudeSettings = join8(homedir5(), ".claude", "settings.json");
|
|
4714
4731
|
const codexConfig = join8(homedir5(), ".codex", "config.toml");
|
|
4715
4732
|
const codexHooks = join8(homedir5(), ".codex", "hooks.json");
|
|
4733
|
+
const openclawConfig = join8(homedir5(), ".openclaw", "openclaw.json");
|
|
4734
|
+
const openclawPlugin = join8(homedir5(), ".openclaw", "extensions", "engrm", "openclaw.plugin.json");
|
|
4716
4735
|
const opencodeConfig = join8(homedir5(), ".config", "opencode", "opencode.json");
|
|
4717
4736
|
const opencodePlugin = join8(homedir5(), ".config", "opencode", "plugins", "engrm.js");
|
|
4718
4737
|
const mcpRegistered = existsSync8(claudeJson) && readFileSync8(claudeJson, "utf-8").includes('"engrm"');
|
|
4719
4738
|
const settingsContent = existsSync8(claudeSettings) ? readFileSync8(claudeSettings, "utf-8") : "";
|
|
4720
4739
|
const codexContent = existsSync8(codexConfig) ? readFileSync8(codexConfig, "utf-8") : "";
|
|
4721
4740
|
const codexHooksContent = existsSync8(codexHooks) ? readFileSync8(codexHooks, "utf-8") : "";
|
|
4741
|
+
const openclawConfigContent = existsSync8(openclawConfig) ? readFileSync8(openclawConfig, "utf-8") : "";
|
|
4722
4742
|
const opencodeConfigContent = existsSync8(opencodeConfig) ? readFileSync8(opencodeConfig, "utf-8") : "";
|
|
4723
4743
|
const hooksRegistered = settingsContent.includes("engrm") || settingsContent.includes("session-start") || settingsContent.includes("user-prompt-submit");
|
|
4724
4744
|
const codexRegistered = codexContent.includes("[mcp_servers.engrm]") || codexContent.includes(`[mcp_servers.${LEGACY_CODEX_SERVER_NAME3}]`);
|
|
4725
4745
|
const codexHooksRegistered = codexHooksContent.includes('"SessionStart"') && codexHooksContent.includes('"Stop"');
|
|
4746
|
+
const openclawMcpRegistered = hasOpenClawMcpRegistration2(openclawConfigContent);
|
|
4747
|
+
const openclawPluginRegistered = existsSync8(openclawPlugin);
|
|
4726
4748
|
const opencodeRegistered = opencodeConfigContent.includes('"engrm"') && opencodeConfigContent.includes('"local"');
|
|
4727
4749
|
const opencodePluginRegistered = existsSync8(opencodePlugin);
|
|
4728
4750
|
let hookCount = 0;
|
|
@@ -4744,6 +4766,8 @@ function handleStatus() {
|
|
|
4744
4766
|
}
|
|
4745
4767
|
console.log(` MCP server: ${mcpRegistered ? "registered" : "not registered"}`);
|
|
4746
4768
|
console.log(` Codex MCP: ${codexRegistered ? "registered" : "not registered"}`);
|
|
4769
|
+
console.log(` OpenClaw MCP: ${openclawMcpRegistered ? "registered" : "not registered"}`);
|
|
4770
|
+
console.log(` OpenClaw plug: ${openclawPluginRegistered ? "registered" : "not registered"}`);
|
|
4747
4771
|
console.log(` OpenCode MCP: ${opencodeRegistered ? "registered" : "not registered"}`);
|
|
4748
4772
|
console.log(` Hooks: ${hooksRegistered ? `registered (${hookCount || "?"} hooks)` : "not registered"}`);
|
|
4749
4773
|
console.log(` Codex hooks: ${codexHooksRegistered ? "registered (2 hooks)" : "not registered"}`);
|
|
@@ -5179,6 +5203,27 @@ async function handleDoctor() {
|
|
|
5179
5203
|
} catch {
|
|
5180
5204
|
warn("Could not check Codex hooks registration");
|
|
5181
5205
|
}
|
|
5206
|
+
const openclawConfig = join8(homedir5(), ".openclaw", "openclaw.json");
|
|
5207
|
+
try {
|
|
5208
|
+
if (existsSync8(openclawConfig)) {
|
|
5209
|
+
const content = readFileSync8(openclawConfig, "utf-8");
|
|
5210
|
+
if (hasOpenClawMcpRegistration2(content)) {
|
|
5211
|
+
pass("MCP server registered in OpenClaw");
|
|
5212
|
+
} else {
|
|
5213
|
+
warn("MCP server not registered in OpenClaw");
|
|
5214
|
+
}
|
|
5215
|
+
} else {
|
|
5216
|
+
warn("OpenClaw config not found (~/.openclaw/openclaw.json)");
|
|
5217
|
+
}
|
|
5218
|
+
} catch {
|
|
5219
|
+
warn("Could not check OpenClaw MCP registration");
|
|
5220
|
+
}
|
|
5221
|
+
const openclawPlugin = join8(homedir5(), ".openclaw", "extensions", "engrm", "openclaw.plugin.json");
|
|
5222
|
+
if (existsSync8(openclawPlugin)) {
|
|
5223
|
+
pass("Plugin installed in OpenClaw");
|
|
5224
|
+
} else {
|
|
5225
|
+
warn("OpenClaw plugin not installed (~/.openclaw/extensions/engrm/openclaw.plugin.json)");
|
|
5226
|
+
}
|
|
5182
5227
|
const opencodeConfig = join8(homedir5(), ".config", "opencode", "opencode.json");
|
|
5183
5228
|
try {
|
|
5184
5229
|
if (existsSync8(opencodeConfig)) {
|
|
@@ -5463,6 +5508,16 @@ And copy the OpenCode plugin file to ~/.config/opencode/plugins/engrm.js:`);
|
|
|
5463
5508
|
function formatTomlArray(values) {
|
|
5464
5509
|
return `[${values.map((value) => JSON.stringify(value)).join(", ")}]`;
|
|
5465
5510
|
}
|
|
5511
|
+
function hasOpenClawMcpRegistration2(content) {
|
|
5512
|
+
if (!content)
|
|
5513
|
+
return false;
|
|
5514
|
+
try {
|
|
5515
|
+
const parsed = JSON.parse(content);
|
|
5516
|
+
return Boolean(parsed.mcp?.servers?.engrm);
|
|
5517
|
+
} catch {
|
|
5518
|
+
return content.includes('"mcp"') && content.includes('"servers"') && content.includes('"engrm"');
|
|
5519
|
+
}
|
|
5520
|
+
}
|
|
5466
5521
|
function printUsage() {
|
|
5467
5522
|
console.log(`Engrm \u2014 Memory layer for AI coding agents
|
|
5468
5523
|
`);
|
|
@@ -3266,7 +3266,7 @@ import { existsSync as existsSync3, readFileSync as readFileSync2, writeFileSync
|
|
|
3266
3266
|
import { join as join3 } from "node:path";
|
|
3267
3267
|
import { homedir } from "node:os";
|
|
3268
3268
|
var STATE_PATH = join3(homedir(), ".engrm", "config-fingerprint.json");
|
|
3269
|
-
var CLIENT_VERSION = "0.4.
|
|
3269
|
+
var CLIENT_VERSION = "0.4.41";
|
|
3270
3270
|
function hashFile(filePath) {
|
|
3271
3271
|
try {
|
|
3272
3272
|
if (!existsSync3(filePath))
|
package/dist/hooks/stop.js
CHANGED
|
@@ -3338,7 +3338,7 @@ function buildBeacon(db, config, sessionId, metrics) {
|
|
|
3338
3338
|
sentinel_used: valueSignals.security_findings_count > 0,
|
|
3339
3339
|
risk_score: riskScore,
|
|
3340
3340
|
stacks_detected: stacks,
|
|
3341
|
-
client_version: "0.4.
|
|
3341
|
+
client_version: "0.4.41",
|
|
3342
3342
|
context_observations_injected: metrics?.contextObsInjected ?? 0,
|
|
3343
3343
|
context_total_available: metrics?.contextTotalAvailable ?? 0,
|
|
3344
3344
|
recall_attempts: metrics?.recallAttempts ?? 0,
|