memoryrail 0.1.0 → 0.1.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.
package/README.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # MemoryRail
2
2
 
3
- **Git-native project memory for coding agents.**
3
+ [![npm](https://img.shields.io/npm/v/memoryrail)](https://www.npmjs.com/package/memoryrail)
4
+ [![CI](https://github.com/OutVersus/memoryrail/actions/workflows/ci.yml/badge.svg)](https://github.com/OutVersus/memoryrail/actions/workflows/ci.yml)
5
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
6
+
7
+ **Git-native project memory for coding agents.** Website: [memoryrail.si](https://memoryrail.si)
4
8
 
5
9
  Decisions, constraints, gotchas and failed attempts live in your repo as plain Markdown. People can read and review them in a PR. Any agent that speaks MCP (Claude Code, Cursor, Codex, Copilot, Aider, ...) can read and write them, and gets warned before it repeats a mistake.
6
10
 
@@ -45,14 +49,13 @@ Six types: `decision`, `constraint`, `gotcha`, `attempt` (tried and failed, with
45
49
 
46
50
  ## Install
47
51
 
48
- Not published to npm yet. From a clone:
52
+ Needs Node 20 or newer.
49
53
 
50
54
  ```sh
51
- git clone https://github.com/OutVersus/memoryrail && cd memoryrail
52
- npm install && npm run build && npm link # puts `memoryrail` on your PATH
55
+ npm install -g memoryrail # puts `memoryrail` on your PATH
53
56
  ```
54
57
 
55
- Once published, every `memoryrail ...` below can be run as `npx memoryrail ...`.
58
+ Or run any command without installing, as `npx memoryrail <command>`. Note that `memoryrail install` registers the server as the command `memoryrail`, so that needs the global install; use `memoryrail install claude --npx` to register `npx -y memoryrail serve` instead.
56
59
 
57
60
  ## Quick start
58
61
 
@@ -69,6 +72,8 @@ git add .memoryrail AGENTS.md CLAUDE.md .mcp.json && git commit -m "Add project
69
72
 
70
73
  ## Connect an agent (MCP)
71
74
 
75
+ Setup for **Claude Code, Cursor, OpenAI Codex and GitHub Copilot** (VS Code, CLI and the cloud agent) is in [docs/CLIENTS.md](docs/CLIENTS.md). The short version for Claude Code and Cursor:
76
+
72
77
  ```sh
73
78
  # Claude Code or Cursor, written into the repo's own config (keeps other servers)
74
79
  memoryrail install claude # .mcp.json
@@ -116,7 +121,7 @@ memoryrail review | approve <id>... [--all] | reject <id>...
116
121
  memoryrail config review [off|agents]
117
122
  memoryrail handoff --summary <text> [--next <step>]... [--title ..] [--link ..]
118
123
  memoryrail resume
119
- memoryrail sync [--check]
124
+ memoryrail sync [--check] [--also <path>]...
120
125
  memoryrail lint [--strict] [--no-git] [--json]
121
126
  memoryrail doctor
122
127
  memoryrail install <claude|cursor|all> [--npx]
@@ -156,7 +161,9 @@ memoryrail precheck --staged --fail || echo "Review the memories above before co
156
161
  - **Search is lexical** (BM25 over title, tags, links and body, with a mild recency boost). It has no synonym or semantic matching, so `recall "database"` will not find a memory that only says "Postgres". Write titles that state the conclusion in the words you would search for, and use tags. Optional embeddings are planned.
157
162
  - `maybe-stale` relies on git history; it is skipped outside a git repository.
158
163
  - **The secret scanner is a pattern check, not a guarantee.** It catches common key formats and `password = ...` assignments, and it will miss secrets in unusual shapes. Treat it as a safety net, and don't paste credentials into memory.
159
- - `install` configures Claude Code and Cursor only. Other MCP clients need the config added by hand (see above).
164
+ - `install` configures Claude Code and Cursor only. For Codex and Copilot, follow [docs/CLIENTS.md](docs/CLIENTS.md); those snippets come from the vendors' documentation and haven't been run against MemoryRail by us.
165
+ - Codex stops reading `AGENTS.md` after 32 KiB by default. `memoryrail doctor` warns when yours gets that large.
166
+ - This is an early release (0.x). The format and commands may change before 1.0, and it has had little use on real projects so far. Please open issues.
160
167
  - The memory is only as good as what agents and people record. MemoryRail makes recording cheap and reviewable; it does not do it for you.
161
168
 
162
169
  ## Library
package/dist/cli.js CHANGED
@@ -11,7 +11,7 @@ import { precheck } from "./precheck.js";
11
11
  import { refOf } from "./refs.js";
12
12
  import { recall, renderMemory } from "./search.js";
13
13
  import { Store, DIR_NAME, initRoot, openStore, writeConfig } from "./store.js";
14
- import { sync } from "./sync.js";
14
+ import { DEFAULT_TARGETS, sync } from "./sync.js";
15
15
  import { VERSION } from "./version.js";
16
16
  import { isMemoryType, MEMORY_TYPES } from "./types.js";
17
17
  const HELP = `memoryrail ${VERSION} — git-native project memory for coding agents
@@ -48,6 +48,8 @@ Commands:
48
48
  resume Print a prompt that brings a fresh agent up to speed
49
49
  sync Write AGENTS.md, CLAUDE.md and .cursor/rules from memory
50
50
  --check Exit 1 if generated files are out of date (for CI)
51
+ --also <path> Also write the block into this file (repeatable), e.g.
52
+ .github/copilot-instructions.md
51
53
  lint Find stale links, duplicates, and broken files
52
54
  --strict Treat warnings as errors --no-git --json
53
55
  doctor Health check: valid, safe, synced, and reachable by agents
@@ -319,8 +321,9 @@ async function run(argv) {
319
321
  return 0;
320
322
  }
321
323
  case "sync": {
322
- const { values } = parse({ check: { type: "boolean" } });
323
- const changes = sync(openStore(), { check: values.check });
324
+ const { values } = parse({ check: { type: "boolean" }, also: { type: "string", multiple: true } });
325
+ const targets = [...DEFAULT_TARGETS, ...(values.also ?? []).map((p) => ({ path: p }))];
326
+ const changes = sync(openStore(), { check: values.check, targets });
324
327
  const pending = changes.filter((c) => c.action !== "unchanged");
325
328
  for (const c of changes)
326
329
  out(`${values.check && c.action !== "unchanged" ? "out of date" : c.action}: ${c.path}`);
package/dist/doctor.js CHANGED
@@ -2,7 +2,7 @@ import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { CLIENT_FILES, isInstalled } from "./install.js";
4
4
  import { lint } from "./lint.js";
5
- import { sync } from "./sync.js";
5
+ import { CODEX_DOC_LIMIT_BYTES, sync } from "./sync.js";
6
6
  import { DIR_NAME, FORMAT_VERSION } from "./store.js";
7
7
  /** One-shot health report: is memory present, valid, safe, synced and reachable by agents? */
8
8
  export function doctor(store) {
@@ -42,6 +42,15 @@ export function doctor(store) {
42
42
  add("warn", "sync", `${drift.map((d) => d.path).join(", ")} out of date; run \`memoryrail sync\``);
43
43
  else
44
44
  add("ok", "sync", "AGENTS.md, CLAUDE.md and Cursor rules are up to date");
45
+ try {
46
+ const bytes = fs.statSync(path.join(store.root, "AGENTS.md")).size;
47
+ if (bytes > CODEX_DOC_LIMIT_BYTES) {
48
+ add("warn", "size", `AGENTS.md is ${Math.round(bytes / 1024)} KiB; Codex stops reading it after 32 KiB by default. Archive stale memories or raise project_doc_max_bytes`);
49
+ }
50
+ }
51
+ catch {
52
+ /* no AGENTS.md yet; the sync check above already says so */
53
+ }
45
54
  const wired = Object.keys(CLIENT_FILES).filter((c) => isInstalled(store.root, c));
46
55
  if (wired.length)
47
56
  add("ok", "agents", `MCP server registered for: ${wired.join(", ")}`);
package/dist/sync.d.ts CHANGED
@@ -14,6 +14,8 @@ export interface SyncChange {
14
14
  path: string;
15
15
  action: "created" | "updated" | "unchanged";
16
16
  }
17
+ /** Codex stops reading AGENTS.md after this many bytes by default (project_doc_max_bytes). */
18
+ export declare const CODEX_DOC_LIMIT_BYTES: number;
17
19
  export declare function sync(store: Store, opts?: {
18
20
  check?: boolean;
19
21
  targets?: Target[];
package/dist/sync.js CHANGED
@@ -60,11 +60,16 @@ function applyBlock(existing, block, preamble = "") {
60
60
  return existing.slice(0, s) + block + existing.slice(e + END.length);
61
61
  return existing.replace(/\s+$/, "") + `\n\n${block}\n`;
62
62
  }
63
+ /** Codex stops reading AGENTS.md after this many bytes by default (project_doc_max_bytes). */
64
+ export const CODEX_DOC_LIMIT_BYTES = 32 * 1024;
63
65
  export function sync(store, opts = {}) {
64
66
  const block = renderBlock(store.list());
65
67
  const changes = [];
66
68
  for (const t of opts.targets ?? DEFAULT_TARGETS) {
67
- const abs = path.join(store.root, t.path);
69
+ const abs = path.resolve(store.root, t.path);
70
+ if (!abs.startsWith(store.root + path.sep)) {
71
+ throw new Error(`refusing to write outside the repository: ${t.path}`);
72
+ }
68
73
  const existing = fs.existsSync(abs) ? fs.readFileSync(abs, "utf8").replace(/\r\n/g, "\n") : null;
69
74
  const next = applyBlock(existing, block, t.preamble);
70
75
  if (existing === next) {
@@ -0,0 +1,163 @@
1
+ # Connect your agent
2
+
3
+ MemoryRail reaches an agent in two ways:
4
+
5
+ 1. **The MCP server** (`memoryrail serve`): the agent calls tools like `precheck`, `recall` and `remember`. This is the full experience.
6
+ 2. **Generated instruction files** (`memoryrail sync`): your rules, decisions and failed attempts are written into `AGENTS.md`, `CLAUDE.md` and `.cursor/rules/memoryrail.mdc`. Agents that read those files see the memory even without MCP, but can't write to it.
7
+
8
+ Install the CLI first: `npm install -g memoryrail` (Node 20 or newer). Then pick your client below.
9
+
10
+ > **How much of this is tested.** The server is tested with the official MCP SDK client over stdio, and the config shapes below were checked against each vendor's documentation (linked in each section, checked 2026-10-10). We have **not** run Codex or any Copilot surface against MemoryRail ourselves. If a snippet doesn't work, please open an issue with the client version and the error.
11
+
12
+ ## How the server finds your memory
13
+
14
+ The server looks for `.memoryrail/` starting in the directory the client launches it in, then walks up. If your client launches servers somewhere else (a user-level config shared by many projects, or a cloud runner), point it at the repo:
15
+
16
+ ```
17
+ memoryrail serve --root /path/to/repo
18
+ ```
19
+
20
+ or set `MEMORYRAIL_ROOT=/path/to/repo` in the server's environment.
21
+
22
+ ## Claude Code
23
+
24
+ ```sh
25
+ memoryrail install claude
26
+ ```
27
+
28
+ This adds a `memoryrail` server to the project's `.mcp.json`, keeping any other servers. Restart Claude Code. `CLAUDE.md` is updated by `memoryrail sync`.
29
+
30
+ ## Cursor
31
+
32
+ ```sh
33
+ memoryrail install cursor
34
+ ```
35
+
36
+ This adds the server to `.cursor/mcp.json`. `memoryrail sync` also writes `.cursor/rules/memoryrail.mdc` (always applied).
37
+
38
+ ## OpenAI Codex
39
+
40
+ Codex reads MCP servers from `~/.codex/config.toml`, or from `.codex/config.toml` in a project (trusted projects only). Add one with the CLI:
41
+
42
+ ```sh
43
+ codex mcp add memoryrail -- memoryrail serve
44
+ ```
45
+
46
+ or edit the TOML:
47
+
48
+ ```toml
49
+ [mcp_servers.memoryrail]
50
+ command = "memoryrail"
51
+ args = ["serve"]
52
+ ```
53
+
54
+ If you haven't installed MemoryRail globally, use `command = "npx"` and `args = ["-y", "memoryrail", "serve"]`. The server looks for `.memoryrail/` from the directory Codex launches it in (we haven't confirmed which directory that is for a user-level config), so for a single project you can pin it with `args = ["serve", "--root", "/path/to/repo"]`.
55
+
56
+ **Instructions:** Codex reads `AGENTS.md` from the project root down to your working directory, which `memoryrail sync` writes. By default Codex **stops reading after 32 KiB** of combined instructions (`project_doc_max_bytes`), so a large memory can be silently cut off. `memoryrail doctor` warns when `AGENTS.md` passes 32 KiB; archive stale memories (`memoryrail forget <ref>`) or raise the limit in your Codex config.
57
+
58
+ Sources: [Codex MCP](https://developers.openai.com/codex/mcp), [Codex AGENTS.md](https://developers.openai.com/codex/guides/agents-md).
59
+
60
+ ## GitHub Copilot
61
+
62
+ Copilot has several surfaces, and they are configured differently.
63
+
64
+ ### Copilot in VS Code
65
+
66
+ Create `.vscode/mcp.json` in the workspace. The top-level key is `servers` (not `mcpServers`):
67
+
68
+ ```json
69
+ {
70
+ "servers": {
71
+ "memoryrail": {
72
+ "type": "stdio",
73
+ "command": "memoryrail",
74
+ "args": ["serve"]
75
+ }
76
+ }
77
+ }
78
+ ```
79
+
80
+ MCP tools are available in Copilot's agent mode. VS Code starts the server with the workspace folder as its working directory by default, so no `--root` is needed.
81
+
82
+ Source: [VS Code MCP configuration reference](https://code.visualstudio.com/docs/agents/reference/mcp-configuration).
83
+
84
+ ### Copilot CLI
85
+
86
+ ```sh
87
+ copilot mcp add memoryrail -- memoryrail serve
88
+ ```
89
+
90
+ This writes to `~/.copilot/mcp-config.json`. To configure it by hand, or per project in `.github/mcp.json`, the top-level key is `mcpServers` and each server has a `type`:
91
+
92
+ ```json
93
+ {
94
+ "mcpServers": {
95
+ "memoryrail": {
96
+ "type": "local",
97
+ "command": "memoryrail",
98
+ "args": ["serve"],
99
+ "tools": ["*"]
100
+ }
101
+ }
102
+ }
103
+ ```
104
+
105
+ Copilot CLI can also read a project-level `.mcp.json`, but expects its own format. The entry that `memoryrail install claude` writes has no `type` field, which the Copilot CLI docs show, so use `copilot mcp add` or the JSON above for Copilot CLI instead of relying on that file.
106
+
107
+ Source: [Adding MCP servers for GitHub Copilot CLI](https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-mcp-servers).
108
+
109
+ ### Copilot cloud agent (assigned issues and pull requests)
110
+
111
+ The cloud agent doesn't read a file from your repo for MCP. A repository administrator pastes JSON into the repository's settings on GitHub.com (under Copilot, in the cloud/coding agent section; the exact menu name has changed between releases). `tools` is required:
112
+
113
+ ```json
114
+ {
115
+ "mcpServers": {
116
+ "memoryrail": {
117
+ "type": "local",
118
+ "command": "npx",
119
+ "args": ["-y", "memoryrail", "serve"],
120
+ "tools": ["resume", "precheck", "recall", "list_memories"]
121
+ }
122
+ }
123
+ }
124
+ ```
125
+
126
+ Notes:
127
+
128
+ - The cloud agent runs on GitHub's side, not on your machine, so MemoryRail isn't installed there. Use `npx`.
129
+ - The example allows **read-only** tools. Add `"remember"` and `"handoff"` to let the agent write memory; its changes then appear in the pull request for you to review. Turning on `memoryrail config review agents` makes those writes wait for your approval.
130
+ - The cloud agent supports MCP **tools** only, not resources or prompts. MemoryRail exposes tools only, so nothing is lost.
131
+ - **Not verified:** which directory the cloud agent starts MCP servers in. If the server reports that it can't find `.memoryrail/`, add `"--root", "."` or the checkout path to `args`.
132
+
133
+ Source: [Configure MCP servers for the Copilot cloud agent](https://docs.github.com/en/copilot/how-tos/agents/copilot-coding-agent/extending-copilot-coding-agent-with-mcp).
134
+
135
+ ### Copilot instructions
136
+
137
+ - The Copilot cloud agent and Copilot CLI read `AGENTS.md` from the repository root, which `memoryrail sync` writes. ([Changelog](https://github.blog/changelog/2025-08-28-copilot-coding-agent-now-supports-agents-md-custom-instructions/))
138
+ - Copilot also reads **`.github/copilot-instructions.md`**. `sync` doesn't write that file by default. To have it written there too, add `--also`:
139
+
140
+ ```sh
141
+ memoryrail sync --also .github/copilot-instructions.md
142
+ ```
143
+
144
+ Pass the same flag to `sync --check` in CI. Existing content in that file is kept; MemoryRail only manages the block between its markers. ([Copilot custom instructions](https://docs.github.com/copilot/customizing-copilot/adding-custom-instructions-for-github-copilot))
145
+
146
+ ## Any other MCP client
147
+
148
+ Register this as a stdio server in the client's MCP config:
149
+
150
+ ```
151
+ command: memoryrail
152
+ args: serve
153
+ ```
154
+
155
+ Clients differ in file name and top-level key (`mcpServers` or `servers`) and some require a `type`; check the client's docs. If the client can't use MCP, the same commands work in a terminal (`memoryrail precheck "..." --file path`), and any tool that reads `AGENTS.md` still gets the summary from `memoryrail sync`.
156
+
157
+ ## Check it worked
158
+
159
+ ```sh
160
+ memoryrail doctor
161
+ ```
162
+
163
+ reports whether memory is valid, synced, and registered for Claude Code or Cursor (it doesn't detect Codex or Copilot config). To test the server itself, ask your agent to call `list_memories`; it should return the memories in the repo.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memoryrail",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Git-native project memory for coding agents. Plain Markdown in your repo, readable by people and any MCP-capable agent.",
5
5
  "license": "MIT",
6
6
  "type": "module",