@repomem/memory 0.0.0-stage → 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/LICENSE +21 -0
- package/README.md +208 -2
- package/assets/kiro/hooks/repomem-validate.sh +10 -0
- package/assets/kiro/skills/repomem-distill/SKILL.md +56 -0
- package/assets/kiro/skills/repomem-memory/SKILL.md +41 -0
- package/dist/cli.d.ts +13 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +194 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/schema.d.ts +97 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +86 -0
- package/dist/schema.js.map +1 -0
- package/dist/search.d.ts +55 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +160 -0
- package/dist/search.js.map +1 -0
- package/dist/server.d.ts +26 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +176 -0
- package/dist/server.js.map +1 -0
- package/dist/setup/spec.d.ts +11 -0
- package/dist/setup/spec.d.ts.map +1 -0
- package/dist/setup/spec.js +44 -0
- package/dist/setup/spec.js.map +1 -0
- package/dist/store.d.ts +119 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +350 -0
- package/dist/store.js.map +1 -0
- package/dist/validate.d.ts +42 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +164 -0
- package/dist/validate.js.map +1 -0
- package/package.json +67 -4
- package/templates/context.md +25 -0
- package/templates/convention.md +16 -0
- package/templates/decision.md +20 -0
- package/templates/learning.md +16 -0
- package/templates/limitation.md +16 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nicolás Rickert
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,209 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @repomem/memory
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Your repo's memory, available to every AI tool your team uses.**
|
|
4
|
+
|
|
5
|
+
> npm package: [`@repomem/memory`](https://www.npmjs.com/package/@repomem/memory) ·
|
|
6
|
+
> CLI command: `repomem-memory`.
|
|
7
|
+
|
|
8
|
+
`@repomem/memory` is a local [Model Context Protocol](https://modelcontextprotocol.io)
|
|
9
|
+
(MCP) server that turns a `memory/` folder in your repository into searchable,
|
|
10
|
+
shared context for AI assistants. Decisions, conventions, limitations,
|
|
11
|
+
learnings and project context live as reviewable markdown files with structured
|
|
12
|
+
frontmatter, versioned with git and shared through normal pull requests. AI
|
|
13
|
+
tools can search and read them, and propose new entries as drafts that a human
|
|
14
|
+
approves in the same PR as the code change.
|
|
15
|
+
|
|
16
|
+
## Why it exists
|
|
17
|
+
|
|
18
|
+
Teams accumulate hard-won context — why a library was chosen, which approach
|
|
19
|
+
failed, what a module is allowed to touch. That knowledge usually lives in
|
|
20
|
+
people's heads, scattered chat logs, or stale wiki pages that no AI tool can
|
|
21
|
+
see. `repomem` keeps it next to the code, in git, where both humans and AI
|
|
22
|
+
assistants can find it.
|
|
23
|
+
|
|
24
|
+
Design principles:
|
|
25
|
+
|
|
26
|
+
- **Markdown is the source of truth.** No external database, no derived index
|
|
27
|
+
committed to git.
|
|
28
|
+
- **The AI proposes, the human accepts.** AI-written entries are always created
|
|
29
|
+
as `draft` and reviewed in a pull request.
|
|
30
|
+
- **Zero native dependencies**, so `npx` works everywhere.
|
|
31
|
+
- **Tool-agnostic.** Works with Kiro, Claude Code, and any MCP client.
|
|
32
|
+
|
|
33
|
+
## Quick start
|
|
34
|
+
|
|
35
|
+
Scaffold a `memory/` folder in your repo (no install needed, `npx` fetches it):
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npx --package @repomem/memory repomem-memory init
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Prefer a pinned local install? Add the package (the CLI bin is `repomem-memory`):
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npm install -D @repomem/memory
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Register the server with your AI tool (see [MCP client config](#mcp-client-config)),
|
|
48
|
+
then ask it to search or propose memory. Before committing, validate:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npx --package @repomem/memory repomem-memory validate
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`validate` exits non-zero on any problem, so it fits in a pre-commit hook or CI.
|
|
55
|
+
|
|
56
|
+
## Entry format
|
|
57
|
+
|
|
58
|
+
Entries live at `memory/<type>s/<slug>.md`. The `id` of an entry is its file
|
|
59
|
+
slug. Each file starts with YAML frontmatter:
|
|
60
|
+
|
|
61
|
+
```markdown
|
|
62
|
+
---
|
|
63
|
+
type: decision # decision | convention | limitation | learning | context
|
|
64
|
+
title: Use PostgreSQL as the primary data store
|
|
65
|
+
status: accepted # draft | accepted | deprecated (default: draft)
|
|
66
|
+
date: 2026-01-15 # ISO date
|
|
67
|
+
scope: project # project (default, repo-wide) or a module name (db, auth…)
|
|
68
|
+
author: platform-team # optional
|
|
69
|
+
tags: [database, architecture]
|
|
70
|
+
related_paths: # globs this entry relates to
|
|
71
|
+
- "src/db/**"
|
|
72
|
+
- "migrations/**"
|
|
73
|
+
# supersedes: old-entry-id # optional
|
|
74
|
+
# last_verified: 2026-02-01 # optional
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
We chose PostgreSQL because the domain is relational and we rely on
|
|
78
|
+
transactional guarantees across several tables.
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
| Field | Required | Notes |
|
|
82
|
+
|-----------------|----------|---------------------------------------------------|
|
|
83
|
+
| `type` | yes | One of decision, convention, limitation, learning, context |
|
|
84
|
+
| `title` | yes | Human-readable title; the slug is derived from it |
|
|
85
|
+
| `status` | no | Defaults to `draft` |
|
|
86
|
+
| `date` | yes | ISO date (`YYYY-MM-DD`) |
|
|
87
|
+
| `scope` | no | Free text; defaults to `project`. Use a module name (`db`, `auth`…) for module-specific entries. Complements `related_paths`. |
|
|
88
|
+
| `author` | no | Freeform |
|
|
89
|
+
| `tags` | no | Defaults to `[]` |
|
|
90
|
+
| `related_paths` | no | Globs; power `memory_for_path`. Defaults to `[]` |
|
|
91
|
+
| `supersedes` | no | Id of an entry this one replaces |
|
|
92
|
+
| `last_verified` | no | ISO date |
|
|
93
|
+
|
|
94
|
+
## Tools
|
|
95
|
+
|
|
96
|
+
| Tool | What it does |
|
|
97
|
+
|---------------------|------------------------------------------------------------------------------|
|
|
98
|
+
| `search_memory` | Full-text search returning compact summaries (id, type, title, status, snippet). Excludes deprecated by default. Optional `type` and `tags` (OR) filters. |
|
|
99
|
+
| `get_memory` | Returns the full content of one entry by `id`. |
|
|
100
|
+
| `memory_for_path` | Returns entries whose `related_paths` globs match a file path. Prioritizes accepted over draft; excludes deprecated. |
|
|
101
|
+
| `propose_memory` | Creates a new entry, **always as `draft`**. Rejects duplicates, never overwrites. |
|
|
102
|
+
| `deprecate_memory` | Marks an entry `deprecated`, recording a reason and optional `superseded_by`. |
|
|
103
|
+
|
|
104
|
+
## The propose-then-review workflow
|
|
105
|
+
|
|
106
|
+
1. While working, an AI assistant proposes an entry with `propose_memory`. It
|
|
107
|
+
lands on disk as `status: draft`.
|
|
108
|
+
2. The draft shows up in your working tree as a normal file change.
|
|
109
|
+
3. You review it in the **same pull request** as the related code, edit if
|
|
110
|
+
needed, and flip `status` to `accepted`.
|
|
111
|
+
4. `npx --package @repomem/memory repomem-memory validate` runs in CI to catch
|
|
112
|
+
malformed entries, dangling `supersedes` references, and accidentally
|
|
113
|
+
committed secrets.
|
|
114
|
+
|
|
115
|
+
Nothing becomes "accepted" memory without a human in the loop.
|
|
116
|
+
|
|
117
|
+
## Root discovery
|
|
118
|
+
|
|
119
|
+
The memory root is resolved in this order:
|
|
120
|
+
|
|
121
|
+
1. `--root <dir>` flag
|
|
122
|
+
2. `MEMORY_ROOT` environment variable
|
|
123
|
+
3. `<git root>/.repomem/memory`
|
|
124
|
+
|
|
125
|
+
The server re-checks file modification times before each search, so a
|
|
126
|
+
`git pull` is picked up without a restart.
|
|
127
|
+
|
|
128
|
+
## MCP client config
|
|
129
|
+
|
|
130
|
+
### Kiro — `.kiro/settings/mcp.json`
|
|
131
|
+
|
|
132
|
+
```json
|
|
133
|
+
{
|
|
134
|
+
"mcpServers": {
|
|
135
|
+
"repomem": {
|
|
136
|
+
"command": "npx",
|
|
137
|
+
"args": ["-y", "--package", "@repomem/memory", "repomem-memory", "serve"],
|
|
138
|
+
"env": {},
|
|
139
|
+
"disabled": false,
|
|
140
|
+
"autoApprove": ["search_memory", "get_memory", "memory_for_path"]
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Instead of writing this by hand, run the one-step setup:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
npx --package @repomem/memory repomem-memory setup --agent kiro # from your repository root
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Or configure both repomem servers at once with the installer: `npx @repomem/cli setup`.
|
|
153
|
+
|
|
154
|
+
It installs a `repomem-memory` skill (how to record and recall memory), a
|
|
155
|
+
`repomem-distill` skill (how to distill a finished plan into durable entries as
|
|
156
|
+
its final step), an `agentSpawn` validate hook, a shared
|
|
157
|
+
`.kiro/agents/repomem.json` agent config, and merges the server into
|
|
158
|
+
`.kiro/settings/mcp.json`. The command is idempotent and never overwrites your
|
|
159
|
+
existing entries (pass `--force` to replace repomem's own entry). Only `kiro` is
|
|
160
|
+
supported today.
|
|
161
|
+
|
|
162
|
+
### Claude Code — `.mcp.json`
|
|
163
|
+
|
|
164
|
+
```json
|
|
165
|
+
{
|
|
166
|
+
"mcpServers": {
|
|
167
|
+
"repomem": {
|
|
168
|
+
"command": "npx",
|
|
169
|
+
"args": ["-y", "--package", "@repomem/memory", "repomem-memory", "serve"]
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
In both cases the server resolves its memory root from the git repository it
|
|
176
|
+
runs in. To point at a specific folder, add `"--root", "/path/to/memory"` to
|
|
177
|
+
`args` or set `MEMORY_ROOT` in `env`.
|
|
178
|
+
|
|
179
|
+
## CLI
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
repomem-memory serve [--root <dir>] # start the MCP server over stdio (what agents invoke)
|
|
183
|
+
repomem-memory init [--root <dir>] # scaffold memory/ with templates and a README
|
|
184
|
+
repomem-memory validate [--root <dir>] # validate frontmatter, supersedes refs, and scan for secrets
|
|
185
|
+
repomem-memory setup --agent kiro # install skills, hooks and MCP config for an agent
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
`validate` returns a non-zero exit code on any error, for use in pre-commit and CI.
|
|
189
|
+
|
|
190
|
+
`setup` resolves the repository root via `--root` > `REPOMEM_REPO_ROOT` > the
|
|
191
|
+
enclosing git root, and writes under `.kiro/`.
|
|
192
|
+
|
|
193
|
+
## Development
|
|
194
|
+
|
|
195
|
+
Requires **Node.js 22+**.
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
npm install
|
|
199
|
+
npm run build # tsc -> dist/
|
|
200
|
+
npm test # vitest
|
|
201
|
+
npm run typecheck
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
See [CONTRIBUTING.md](./CONTRIBUTING.md) for the branching model, commit
|
|
205
|
+
conventions, and the test-driven workflow.
|
|
206
|
+
|
|
207
|
+
## License
|
|
208
|
+
|
|
209
|
+
[MIT](./LICENSE)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# repomem-validate.sh — validate the repository's memory folder.
|
|
3
|
+
#
|
|
4
|
+
# Wired as a Kiro `agentSpawn` hook by `repomem setup --agent kiro`. It runs on
|
|
5
|
+
# agent start to surface any invalid memory entries early. The exit code is not
|
|
6
|
+
# used to block (agentSpawn hooks only add stdout to context), so a failure here
|
|
7
|
+
# is informational.
|
|
8
|
+
set -euo pipefail
|
|
9
|
+
|
|
10
|
+
npx -y repomem validate
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: repomem-distill
|
|
3
|
+
description: How to distill a finished piece of work into durable repomem entries. Use as the FINAL STEP after executing a plan or completing a substantial task — review what the session produced and propose the decisions, learnings, limitations, and context worth keeping for next time.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# repomem — distilling a session into memory
|
|
7
|
+
|
|
8
|
+
When you finish executing a plan or a substantial task, the valuable knowledge
|
|
9
|
+
lives only in this session: why you chose an approach, what surprised you, what
|
|
10
|
+
constraints you hit. Once the session ends, it is gone unless you write it down.
|
|
11
|
+
This skill is the final step of a plan: turn that knowledge into a small number
|
|
12
|
+
of durable `repomem` entries.
|
|
13
|
+
|
|
14
|
+
This is NOT about saving the plan. Do not persist the step-by-step plan, task
|
|
15
|
+
lists, progress logs, or any other ephemeral session state — that noise does not
|
|
16
|
+
belong in memory and the agent's own session already holds it. Distill only
|
|
17
|
+
knowledge that will still matter weeks from now.
|
|
18
|
+
|
|
19
|
+
## When to run it
|
|
20
|
+
|
|
21
|
+
- As the explicit final step after completing a plan or a non-trivial task.
|
|
22
|
+
- When the user asks you to "record" or "distill" what was done.
|
|
23
|
+
|
|
24
|
+
## What to distill
|
|
25
|
+
|
|
26
|
+
Review the session and identify, if any:
|
|
27
|
+
|
|
28
|
+
- **decisions** — non-obvious choices and the reasoning behind them.
|
|
29
|
+
- **learnings** — things that surprised you or cost time, worth remembering.
|
|
30
|
+
- **limitations** — new constraints or gotchas you discovered.
|
|
31
|
+
- **context** — project or module-level understanding that changed or is newly
|
|
32
|
+
worth writing down (what a thing is, why it exists, how it fits together).
|
|
33
|
+
|
|
34
|
+
If nothing durable came out of the work, propose nothing. A clean "no entries
|
|
35
|
+
needed" is a valid outcome — do not invent memory.
|
|
36
|
+
|
|
37
|
+
## How to do it
|
|
38
|
+
|
|
39
|
+
1. Reflect on what the session actually accomplished and changed.
|
|
40
|
+
2. For each durable item, call `propose_memory` once, with:
|
|
41
|
+
- a clear, specific `title`,
|
|
42
|
+
- the right `type` (decision / convention / limitation / learning / context),
|
|
43
|
+
- meaningful `related_paths` so `memory_for_path` can surface it later,
|
|
44
|
+
- a `scope`: `project` for repo-wide knowledge, or a module name
|
|
45
|
+
(e.g. `db`, `auth`, `frontend`) for module-specific knowledge.
|
|
46
|
+
3. Keep each entry focused: one decision/learning/limitation/context per file.
|
|
47
|
+
4. **Never** mark an entry `accepted` yourself. Every entry is a `draft` for a
|
|
48
|
+
human to review and accept in the same pull request as the code.
|
|
49
|
+
5. Remind the user to run `repomem validate` before committing.
|
|
50
|
+
|
|
51
|
+
## Guidelines
|
|
52
|
+
|
|
53
|
+
- Prefer a few high-signal entries over many shallow ones.
|
|
54
|
+
- Write for a teammate (human or AI) who was not in this session.
|
|
55
|
+
- Reuse existing entries by proposing a `supersedes` reference when a decision
|
|
56
|
+
replaces an earlier one, rather than silently contradicting it.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: repomem-memory
|
|
3
|
+
description: How to use the repomem MCP server to record and recall a repository's shared memory — decisions, conventions, limitations, and learnings. Use when you make a non-obvious choice worth remembering, when you need prior context before changing code, or when the user asks what the team already decided.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# repomem — the repository's shared memory
|
|
7
|
+
|
|
8
|
+
repomem turns a `memory/` folder into searchable, git-versioned context served
|
|
9
|
+
over MCP. Entries are markdown files with structured frontmatter, grouped by
|
|
10
|
+
type: `decisions/`, `conventions/`, `limitations/`, `learnings/`.
|
|
11
|
+
|
|
12
|
+
## When to use it
|
|
13
|
+
|
|
14
|
+
- **Before changing unfamiliar code**: search memory for related decisions and
|
|
15
|
+
limitations so you don't contradict an earlier choice.
|
|
16
|
+
- **After making a non-obvious decision**: propose a new entry so the rationale
|
|
17
|
+
survives beyond the current conversation.
|
|
18
|
+
- **When the user asks "why is it this way?"**: look it up instead of guessing.
|
|
19
|
+
|
|
20
|
+
## The propose-then-review workflow
|
|
21
|
+
|
|
22
|
+
AI tools **propose** entries as drafts (`status: draft`). A human reviews and
|
|
23
|
+
**accepts** them in the same pull request as the related change. Never mark an
|
|
24
|
+
entry `accepted` yourself — leave it as a draft for review.
|
|
25
|
+
|
|
26
|
+
## Tools
|
|
27
|
+
|
|
28
|
+
- `search_memory` — full-text search across all entries. Start here.
|
|
29
|
+
- `get_memory` — fetch a specific entry by slug.
|
|
30
|
+
- `memory_for_path` — find entries whose `related_paths` match a file you are
|
|
31
|
+
about to touch.
|
|
32
|
+
- Write tools propose new draft entries; prefer small, specific entries with a
|
|
33
|
+
clear title and `related_paths`.
|
|
34
|
+
|
|
35
|
+
## Guidelines
|
|
36
|
+
|
|
37
|
+
- Keep entries focused: one decision/convention/limitation/learning per file.
|
|
38
|
+
- Always set meaningful `related_paths` so `memory_for_path` can surface the
|
|
39
|
+
entry later.
|
|
40
|
+
- Run `repomem validate` before committing — it checks frontmatter, supersedes
|
|
41
|
+
references, and scans for secrets.
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* cli.ts — `repomem-memory` command line.
|
|
4
|
+
*
|
|
5
|
+
* repomem-memory serve [--root <dir>] start the MCP server over stdio
|
|
6
|
+
* repomem-memory init [--root <dir>] scaffold the memory/ folder + templates
|
|
7
|
+
* repomem-memory validate [--root <dir>] check frontmatter, supersedes refs, secrets
|
|
8
|
+
* repomem-memory setup --agent <name> install skills, hooks and MCP config
|
|
9
|
+
*
|
|
10
|
+
* `validate` exits non-zero on any error so it can gate pre-commit and CI.
|
|
11
|
+
*/
|
|
12
|
+
export declare function run(argv?: string[]): Promise<number>;
|
|
13
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG;AA8IH,wBAAsB,GAAG,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,MAAM,CAAC,CAgDjF"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* cli.ts — `repomem-memory` command line.
|
|
4
|
+
*
|
|
5
|
+
* repomem-memory serve [--root <dir>] start the MCP server over stdio
|
|
6
|
+
* repomem-memory init [--root <dir>] scaffold the memory/ folder + templates
|
|
7
|
+
* repomem-memory validate [--root <dir>] check frontmatter, supersedes refs, secrets
|
|
8
|
+
* repomem-memory setup --agent <name> install skills, hooks and MCP config
|
|
9
|
+
*
|
|
10
|
+
* `validate` exits non-zero on any error so it can gate pre-commit and CI.
|
|
11
|
+
*/
|
|
12
|
+
import { promises as fs } from "node:fs";
|
|
13
|
+
import { existsSync } from "node:fs";
|
|
14
|
+
import path from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
16
|
+
import { ENTRY_TYPES, TYPE_DIRS } from "./schema.js";
|
|
17
|
+
import { resolveMemoryRoot } from "./store.js";
|
|
18
|
+
import { validateRoot, formatReport } from "./validate.js";
|
|
19
|
+
import { main as startServer } from "./index.js";
|
|
20
|
+
import { runSetup } from "@repomem/core";
|
|
21
|
+
import { repomemSpec } from "./setup/spec.js";
|
|
22
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
23
|
+
// Templates ship alongside dist/ at the package root: dist/cli.js -> ../templates
|
|
24
|
+
const TEMPLATES_DIR = path.resolve(here, "..", "templates");
|
|
25
|
+
function out(message) {
|
|
26
|
+
process.stdout.write(message + "\n");
|
|
27
|
+
}
|
|
28
|
+
function err(message) {
|
|
29
|
+
process.stderr.write(message + "\n");
|
|
30
|
+
}
|
|
31
|
+
function parseFlag(argv, name) {
|
|
32
|
+
const i = argv.indexOf(name);
|
|
33
|
+
if (i !== -1 && i + 1 < argv.length)
|
|
34
|
+
return argv[i + 1];
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
function hasFlag(argv, name) {
|
|
38
|
+
return argv.includes(name);
|
|
39
|
+
}
|
|
40
|
+
const MEMORY_README = `# Memory
|
|
41
|
+
|
|
42
|
+
This folder is your repository's shared memory, read and extended by AI tools
|
|
43
|
+
through the \`repomem\` MCP server.
|
|
44
|
+
|
|
45
|
+
Each entry is a markdown file with structured frontmatter, organized by type:
|
|
46
|
+
|
|
47
|
+
- \`decisions/\` — choices made and why
|
|
48
|
+
- \`conventions/\` — rules the team follows
|
|
49
|
+
- \`limitations/\` — known constraints and gotchas
|
|
50
|
+
- \`learnings/\` — lessons worth remembering
|
|
51
|
+
- \`contexts/\` — project and module-level context (what things are and why)
|
|
52
|
+
|
|
53
|
+
## How it works
|
|
54
|
+
|
|
55
|
+
AI tools **propose** new entries as drafts (\`status: draft\`). A human reviews
|
|
56
|
+
and **accepts** them in the same pull request as the related change. Entries are
|
|
57
|
+
versioned with git — no external database.
|
|
58
|
+
|
|
59
|
+
Run \`npx --package @repomem/memory repomem-memory validate\` to check entries before committing.
|
|
60
|
+
|
|
61
|
+
See \`templates/\` for a starting point for each entry type.
|
|
62
|
+
`;
|
|
63
|
+
async function cmdInit(root) {
|
|
64
|
+
const created = [];
|
|
65
|
+
const skipped = [];
|
|
66
|
+
async function ensureDir(dir) {
|
|
67
|
+
if (existsSync(dir)) {
|
|
68
|
+
skipped.push(dir);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
await fs.mkdir(dir, { recursive: true });
|
|
72
|
+
created.push(dir);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
await ensureDir(root);
|
|
76
|
+
for (const type of ENTRY_TYPES) {
|
|
77
|
+
await ensureDir(path.join(root, TYPE_DIRS[type]));
|
|
78
|
+
}
|
|
79
|
+
// README (never overwrite).
|
|
80
|
+
const readme = path.join(root, "README.md");
|
|
81
|
+
if (existsSync(readme)) {
|
|
82
|
+
skipped.push(readme);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
await fs.writeFile(readme, MEMORY_README, "utf8");
|
|
86
|
+
created.push(readme);
|
|
87
|
+
}
|
|
88
|
+
// Templates (never overwrite individual files).
|
|
89
|
+
const destTemplates = path.join(root, "templates");
|
|
90
|
+
await ensureDir(destTemplates);
|
|
91
|
+
for (const type of ENTRY_TYPES) {
|
|
92
|
+
const src = path.join(TEMPLATES_DIR, `${type}.md`);
|
|
93
|
+
const dest = path.join(destTemplates, `${type}.md`);
|
|
94
|
+
if (existsSync(dest)) {
|
|
95
|
+
skipped.push(dest);
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
try {
|
|
99
|
+
const content = await fs.readFile(src, "utf8");
|
|
100
|
+
await fs.writeFile(dest, content, "utf8");
|
|
101
|
+
created.push(dest);
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
err(`warning: template not found: ${src}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
out(`Initialized memory at ${root}`);
|
|
108
|
+
if (created.length)
|
|
109
|
+
out(` created:\n${created.map((c) => ` + ${c}`).join("\n")}`);
|
|
110
|
+
if (skipped.length)
|
|
111
|
+
out(` already present (left untouched):\n${skipped.map((c) => ` = ${c}`).join("\n")}`);
|
|
112
|
+
return 0;
|
|
113
|
+
}
|
|
114
|
+
async function cmdValidate(root) {
|
|
115
|
+
if (!existsSync(root)) {
|
|
116
|
+
err(`No memory folder at ${root}. Run \`repomem-memory init\` first.`);
|
|
117
|
+
return 1;
|
|
118
|
+
}
|
|
119
|
+
const report = await validateRoot(root);
|
|
120
|
+
const text = formatReport(report, root);
|
|
121
|
+
if (report.ok) {
|
|
122
|
+
out(text);
|
|
123
|
+
return 0;
|
|
124
|
+
}
|
|
125
|
+
err(text);
|
|
126
|
+
return 1;
|
|
127
|
+
}
|
|
128
|
+
function usage() {
|
|
129
|
+
out([
|
|
130
|
+
"repomem-memory — your repo's memory for AI tools",
|
|
131
|
+
"",
|
|
132
|
+
"Usage:",
|
|
133
|
+
" repomem-memory serve [--root <dir>] Start the MCP server over stdio (default for agents)",
|
|
134
|
+
" repomem-memory init [--root <dir>] Scaffold the memory/ folder and templates",
|
|
135
|
+
" repomem-memory validate [--root <dir>] Validate entries (frontmatter, refs, secrets)",
|
|
136
|
+
" repomem-memory setup --agent <name> Install skills, hooks and MCP config for an agent",
|
|
137
|
+
"",
|
|
138
|
+
"Root resolution: --root > MEMORY_ROOT env > <git root>/.repomem/memory",
|
|
139
|
+
"setup root resolution: --root > REPOMEM_REPO_ROOT env > <git root>",
|
|
140
|
+
].join("\n"));
|
|
141
|
+
}
|
|
142
|
+
export async function run(argv = process.argv.slice(2)) {
|
|
143
|
+
const command = argv[0];
|
|
144
|
+
if (!command || command === "--help" || command === "-h" || command === "help") {
|
|
145
|
+
usage();
|
|
146
|
+
return command ? 0 : 1;
|
|
147
|
+
}
|
|
148
|
+
// `setup` resolves the repository root (not the memory root), so handle it
|
|
149
|
+
// before the memory-root resolution below.
|
|
150
|
+
if (command === "setup") {
|
|
151
|
+
return runSetup(repomemSpec, {
|
|
152
|
+
agent: parseFlag(argv, "--agent"),
|
|
153
|
+
rootFlag: parseFlag(argv, "--root"),
|
|
154
|
+
force: hasFlag(argv, "--force"),
|
|
155
|
+
}, { out, err });
|
|
156
|
+
}
|
|
157
|
+
// `serve` starts the MCP server over stdio. This is what agents invoke
|
|
158
|
+
// through the generated mcp.json. It resolves its own memory root and runs
|
|
159
|
+
// until the transport closes, so it never returns a non-zero code here.
|
|
160
|
+
if (command === "serve") {
|
|
161
|
+
await startServer(argv.slice(1));
|
|
162
|
+
return 0;
|
|
163
|
+
}
|
|
164
|
+
let root;
|
|
165
|
+
try {
|
|
166
|
+
root = resolveMemoryRoot({ rootFlag: parseFlag(argv, "--root") });
|
|
167
|
+
}
|
|
168
|
+
catch (e) {
|
|
169
|
+
err(e.message);
|
|
170
|
+
return 1;
|
|
171
|
+
}
|
|
172
|
+
switch (command) {
|
|
173
|
+
case "init":
|
|
174
|
+
return cmdInit(root);
|
|
175
|
+
case "validate":
|
|
176
|
+
return cmdValidate(root);
|
|
177
|
+
default:
|
|
178
|
+
err(`Unknown command: ${command}`);
|
|
179
|
+
usage();
|
|
180
|
+
return 1;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
// Only auto-run when invoked directly (not when imported by tests).
|
|
184
|
+
const invokedDirectly = process.argv[1] !== undefined &&
|
|
185
|
+
path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
186
|
+
if (invokedDirectly) {
|
|
187
|
+
run()
|
|
188
|
+
.then((code) => process.exit(code))
|
|
189
|
+
.catch((e) => {
|
|
190
|
+
err(`fatal: ${e.message}`);
|
|
191
|
+
process.exit(1);
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAqBH,wBAAsB,IAAI,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAWhF"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* index.ts — bootstrap. Wires the McpServer to a StdioServerTransport.
|
|
3
|
+
*
|
|
4
|
+
* All logging goes to stderr; stdout is reserved for the MCP protocol.
|
|
5
|
+
*/
|
|
6
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
7
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
10
|
+
import { resolveMemoryRoot } from "./store.js";
|
|
11
|
+
import { MemoryIndex } from "./search.js";
|
|
12
|
+
import { registerAllTools, SERVER_INFO } from "./server.js";
|
|
13
|
+
function log(message) {
|
|
14
|
+
process.stderr.write(`[repomem] ${message}\n`);
|
|
15
|
+
}
|
|
16
|
+
/** Read an optional `--root <path>` from argv. */
|
|
17
|
+
function parseRootFlag(argv) {
|
|
18
|
+
const i = argv.indexOf("--root");
|
|
19
|
+
if (i !== -1 && i + 1 < argv.length)
|
|
20
|
+
return argv[i + 1];
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
export async function main(argv = process.argv.slice(2)) {
|
|
24
|
+
const root = resolveMemoryRoot({ rootFlag: parseRootFlag(argv) });
|
|
25
|
+
log(`memory root: ${root}`);
|
|
26
|
+
const index = new MemoryIndex(root);
|
|
27
|
+
const server = new McpServer(SERVER_INFO);
|
|
28
|
+
registerAllTools(server, root, index);
|
|
29
|
+
const transport = new StdioServerTransport();
|
|
30
|
+
await server.connect(transport);
|
|
31
|
+
log("server ready on stdio");
|
|
32
|
+
}
|
|
33
|
+
// Only auto-run when invoked directly (e.g. `node dist/index.js`), not when
|
|
34
|
+
// imported (the CLI imports `main` to implement the `serve` subcommand).
|
|
35
|
+
const invokedDirectly = process.argv[1] !== undefined &&
|
|
36
|
+
path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
37
|
+
if (invokedDirectly) {
|
|
38
|
+
main().catch((err) => {
|
|
39
|
+
log(`fatal: ${err.message}`);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE5D,SAAS,GAAG,CAAC,OAAe;IAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,OAAO,IAAI,CAAC,CAAC;AACjD,CAAC;AAED,kDAAkD;AAClD,SAAS,aAAa,CAAC,IAAc;IACnC,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACxD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,OAAiB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/D,MAAM,IAAI,GAAG,iBAAiB,CAAC,EAAE,QAAQ,EAAE,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClE,GAAG,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC;IAE5B,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,WAAW,CAAC,CAAC;IAC1C,gBAAgB,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;IAEtC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,GAAG,CAAC,uBAAuB,CAAC,CAAC;AAC/B,CAAC;AAED,4EAA4E;AAC5E,yEAAyE;AACzE,MAAM,eAAe,GACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS;IAC7B,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEnE,IAAI,eAAe,EAAE,CAAC;IACpB,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;QAC5B,GAAG,CAAC,UAAW,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
|