memorix 0.9.24 → 0.9.26

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/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [0.9.25] — 2026-02-28
6
+
7
+ ### Fixed
8
+ - **Windsurf "no tools returned"** — Transport-first architecture caused Windsurf to query `tools/list` before tools were registered. Normal path now registers tools first, then connects transport. Roots path (invalid cwd) still connects first to query `listRoots`.
9
+ - **Windsurf rules not activated** — Generated `.windsurf/rules/memorix.md` lacked YAML frontmatter (`trigger: always_on`). Windsurf ignored the file without it. Also added `alwaysApply: true` frontmatter for Cursor `.mdc` files.
10
+ - **Windsurf hook `post_command` content too short** — Normalizer didn't extract `commandOutput` from Windsurf `post_command` events, causing content to be <30 chars and filtered out.
11
+ - **Hook hot-reload broken on Windows** — `fs.watch()` lost track of `observations.json` after `atomicWriteFile` (which uses `rename()`). Switched to `fs.watchFile` with 2s polling for reliable cross-platform hot-reload. Hook-written memories are now searchable within ~4 seconds.
12
+
5
13
  ## [0.9.18] — 2026-02-26
6
14
 
7
15
  ### Fixed
package/dist/cli/index.js CHANGED
@@ -40695,44 +40695,48 @@ function generateKiroHookFiles() {
40695
40695
  return [
40696
40696
  {
40697
40697
  filename: "memorix-agent-stop.kiro.hook",
40698
- content: `---
40699
- title: Memorix Session Memory
40700
- description: Record session context when agent completes a turn
40701
- event: agent_stop
40702
- ---
40703
-
40704
- Call memorix MCP tools to store important context from this conversation:
40705
- 1. Use memorix_store to record any decisions, bug fixes, gotchas, or configuration changes
40706
- 2. Include relevant file paths and concepts for searchability
40707
- `
40698
+ content: JSON.stringify({
40699
+ enabled: true,
40700
+ name: "Memorix Session Memory",
40701
+ description: "Record session context when agent completes a turn",
40702
+ version: "1",
40703
+ when: { type: "agentStop" },
40704
+ then: {
40705
+ type: "askAgent",
40706
+ prompt: "Call memorix MCP tools to store important context from this conversation:\n1. Use memorix_store to record any decisions, bug fixes, gotchas, or configuration changes\n2. Include relevant file paths and concepts for searchability"
40707
+ }
40708
+ }, null, 2)
40708
40709
  },
40709
40710
  {
40710
40711
  filename: "memorix-prompt-submit.kiro.hook",
40711
- content: `---
40712
- title: Memorix Context Loader
40713
- description: Load relevant memories when user submits a prompt
40714
- event: prompt_submit
40715
- ---
40716
-
40717
- Before responding, search for relevant context:
40718
- 1. Call memorix_search with a query related to the user's prompt
40719
- 2. If results are found, use memorix_detail to fetch the most relevant ones
40720
- 3. Reference relevant memories naturally in your response
40721
- `
40712
+ content: JSON.stringify({
40713
+ enabled: true,
40714
+ name: "Memorix Context Loader",
40715
+ description: "Load relevant memories when user submits a prompt",
40716
+ version: "1",
40717
+ when: { type: "promptSubmit" },
40718
+ then: {
40719
+ type: "askAgent",
40720
+ prompt: "Before responding, search for relevant context:\n1. Call memorix_search with a query related to the user's prompt\n2. If results are found, use memorix_detail to fetch the most relevant ones\n3. Reference relevant memories naturally in your response"
40721
+ }
40722
+ }, null, 2)
40722
40723
  },
40723
40724
  {
40724
40725
  filename: "memorix-file-save.kiro.hook",
40725
- content: `---
40726
- title: Memorix File Change Tracker
40727
- description: Track significant file changes for cross-session memory
40728
- event: file_save
40729
- filePattern: "**/*.{ts,js,tsx,jsx,py,rs,go,java,md}"
40730
- ---
40731
-
40732
- \`\`\`bash
40733
- ${cmd}
40734
- \`\`\`
40735
- `
40726
+ content: JSON.stringify({
40727
+ enabled: true,
40728
+ name: "Memorix File Change Tracker",
40729
+ description: "Track significant file changes for cross-session memory",
40730
+ version: "1",
40731
+ when: {
40732
+ type: "fileEdited",
40733
+ patterns: ["**/*.ts", "**/*.js", "**/*.tsx", "**/*.jsx", "**/*.py", "**/*.rs", "**/*.go", "**/*.java", "**/*.md"]
40734
+ },
40735
+ then: {
40736
+ type: "runCommand",
40737
+ command: cmd
40738
+ }
40739
+ }, null, 2)
40736
40740
  }
40737
40741
  ];
40738
40742
  }
@@ -40907,7 +40911,7 @@ async function installHooks(agent, projectRoot, global = false) {
40907
40911
  };
40908
40912
  }
40909
40913
  async function installAgentRules(agent, projectRoot) {
40910
- const rulesContent = getAgentRulesContent();
40914
+ const rulesContent = getAgentRulesContent(agent);
40911
40915
  let rulesPath;
40912
40916
  switch (agent) {
40913
40917
  case "windsurf":
@@ -40952,8 +40956,23 @@ async function installAgentRules(agent, projectRoot) {
40952
40956
  } catch {
40953
40957
  }
40954
40958
  }
40955
- function getAgentRulesContent() {
40956
- return `# Memorix \u2014 Automatic Memory Rules
40959
+ function getAgentRulesContent(agent) {
40960
+ let frontmatter = "";
40961
+ if (agent === "windsurf") {
40962
+ frontmatter = `---
40963
+ trigger: always_on
40964
+ ---
40965
+
40966
+ `;
40967
+ } else if (agent === "cursor") {
40968
+ frontmatter = `---
40969
+ description: Memorix automatic memory recording rules
40970
+ alwaysApply: true
40971
+ ---
40972
+
40973
+ `;
40974
+ }
40975
+ return `${frontmatter}# Memorix \u2014 Automatic Memory Rules
40957
40976
 
40958
40977
  You have access to Memorix memory tools. Follow these rules to maintain persistent context across sessions.
40959
40978
 
@@ -41084,7 +41103,7 @@ var server_exports2 = {};
41084
41103
  __export(server_exports2, {
41085
41104
  createMemorixServer: () => createMemorixServer
41086
41105
  });
41087
- import { watch } from "fs";
41106
+ import { watchFile } from "fs";
41088
41107
  function coerceNumberArray(val) {
41089
41108
  if (Array.isArray(val)) return val.map(Number);
41090
41109
  if (typeof val === "string") {
@@ -42288,7 +42307,8 @@ ${json}
42288
42307
  const observationsFile = projectDir2 + "/observations.json";
42289
42308
  let reloadDebounce = null;
42290
42309
  try {
42291
- watch(observationsFile, () => {
42310
+ watchFile(observationsFile, { interval: 2e3 }, (curr, prev) => {
42311
+ if (curr.mtimeMs === prev.mtimeMs) return;
42292
42312
  if (reloadDebounce) clearTimeout(reloadDebounce);
42293
42313
  reloadDebounce = setTimeout(async () => {
42294
42314
  try {
@@ -42378,13 +42398,12 @@ var init_serve = __esm({
42378
42398
  }
42379
42399
  let projectRoot = args.cwd || process.env.MEMORIX_PROJECT_ROOT || process.env.INIT_CWD || safeCwd;
42380
42400
  console.error(`[memorix] Starting with cwd: ${projectRoot}`);
42381
- const mcpServer = new McpServer2({ name: "memorix", version: "0.1.0" });
42382
- const transport = new StdioServerTransport2();
42383
- await mcpServer.connect(transport);
42384
- console.error(`[memorix] Transport connected, initializing...`);
42385
42401
  const looksValid = existsSync5(join12(projectRoot, ".git")) || existsSync5(join12(projectRoot, "package.json")) || existsSync5(join12(projectRoot, "Cargo.toml")) || existsSync5(join12(projectRoot, "go.mod")) || existsSync5(join12(projectRoot, "pyproject.toml"));
42386
42402
  if (!looksValid) {
42387
42403
  console.error(`[memorix] cwd may not be a valid project, trying MCP roots protocol...`);
42404
+ const mcpServer = new McpServer2({ name: "memorix", version: "0.1.0" });
42405
+ const transport = new StdioServerTransport2();
42406
+ await mcpServer.connect(transport);
42388
42407
  let rootResolved = false;
42389
42408
  try {
42390
42409
  const rootsResult = await Promise.race([
@@ -42412,11 +42431,18 @@ var init_serve = __esm({
42412
42431
  process.exit(1);
42413
42432
  }
42414
42433
  }
42434
+ const { projectId, deferredInit } = await createMemorixServer2(projectRoot, mcpServer);
42435
+ console.error(`[memorix] MCP Server running on stdio (project: ${projectId})`);
42436
+ console.error(`[memorix] Project root: ${projectRoot}`);
42437
+ deferredInit().catch((e3) => console.error(`[memorix] Deferred init error:`, e3));
42438
+ } else {
42439
+ const { server, projectId, deferredInit } = await createMemorixServer2(projectRoot);
42440
+ const transport = new StdioServerTransport2();
42441
+ await server.connect(transport);
42442
+ console.error(`[memorix] MCP Server running on stdio (project: ${projectId})`);
42443
+ console.error(`[memorix] Project root: ${projectRoot}`);
42444
+ deferredInit().catch((e3) => console.error(`[memorix] Deferred init error:`, e3));
42415
42445
  }
42416
- const { projectId, deferredInit } = await createMemorixServer2(projectRoot, mcpServer);
42417
- console.error(`[memorix] MCP Server running on stdio (project: ${projectId})`);
42418
- console.error(`[memorix] Project root: ${projectRoot}`);
42419
- deferredInit().catch((e3) => console.error(`[memorix] Deferred init error:`, e3));
42420
42446
  }
42421
42447
  });
42422
42448
  }
@@ -43428,6 +43454,7 @@ function normalizeWindsurf(payload, event) {
43428
43454
  case "post_command":
43429
43455
  result.command = toolInfo.command_line;
43430
43456
  result.cwd = toolInfo.cwd ?? "";
43457
+ result.commandOutput = toolInfo.output ?? toolInfo.stdout ?? void 0;
43431
43458
  break;
43432
43459
  case "post_tool":
43433
43460
  result.toolName = toolInfo.mcp_tool_name;