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 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.39";
3269
+ var CLIENT_VERSION = "0.4.41";
3270
3270
  function hashFile(filePath) {
3271
3271
  try {
3272
3272
  if (!existsSync3(filePath))
@@ -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.39",
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,