hippocamp 0.2.4 → 0.2.5
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 +5 -5
- package/package.json +1 -1
- package/scripts/hippocamp-mcp.cjs +1 -1
- package/scripts/install-common.cjs +14 -5
- package/test/install-common.test.cjs +21 -4
package/README.md
CHANGED
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
|
|
9
9
|
Agent memory you can `git log`.
|
|
10
10
|
|
|
11
|
-
Hippocamp gives Claude Code
|
|
11
|
+
Hippocamp gives all your coding agents, like Claude Code and Codex, one shared memory: plain Markdown in a private Git repo you own. Every session starts by waking up from it, and every decision an agent records is a commit you can read, diff, and revert.
|
|
12
12
|
|
|
13
|
-
Open source (MIT). No account, no API key, no
|
|
13
|
+
Open source (MIT). No account, no API key, no Hippocamp server: it runs on your machine and works the moment it is installed. Your memory lives in a private Git repo. No database, no vector store, nothing to pay for.
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
16
|
npx hippocamp@latest install
|
|
@@ -22,10 +22,10 @@ This installs Hippocamp into every supported agent CLI it finds, creates `~/.lag
|
|
|
22
22
|
|
|
23
23
|
Claude Code and Codex now ship their own memory. Use Hippocamp when you want:
|
|
24
24
|
|
|
25
|
-
- **One memory for every agent.** Claude Code, Codex, and
|
|
25
|
+
- **One memory for every agent.** Claude Code, Codex, and your other agents read and write the same repo. Built-in memory stays inside one tool.
|
|
26
26
|
- **History you can audit.** Every memory change is a Git commit with an author, a diff, and a timestamp. Roll back a bad memory like bad code.
|
|
27
27
|
- **Files you own.** Markdown in your own private repo, readable without any UI, portable across machines through your normal Git credentials.
|
|
28
|
-
- **Nothing to sign up for.** Open source
|
|
28
|
+
- **Nothing to sign up for.** Open source and free, running on your machine. No account, no API key, no vendor that can change terms or shut down.
|
|
29
29
|
- **Reviewed compaction.** Optional Dream mode summarizes memory offline and proposes the result as a pull request.
|
|
30
30
|
|
|
31
31
|
## Results
|
|
@@ -111,7 +111,7 @@ npx hippocamp@latest install-grok
|
|
|
111
111
|
|
|
112
112
|
Upgrade with the same command: `npx hippocamp@latest upgrade`. Installers default to `~/.lagoon` as the memory repo; pass `--global-root /absolute/path/to/lagoon` to use another clone.
|
|
113
113
|
|
|
114
|
-
Installed through npx, the
|
|
114
|
+
Installed through npx, the installer copies the package to `~/.hippocamp/<version>/` and registers that copy, so the server starts without npx or network and keeps working if npm cleans its cache. From a source checkout, `npm install` then `npm run install:claude` (or `install:codex`, `install:grok`) registers the checkout directly.
|
|
115
115
|
|
|
116
116
|
The Codex installer refreshes `~/.codex/AGENTS.md`. The Claude installer refreshes `~/.claude/CLAUDE.md`. The Grok installer refreshes `~/.grok/rules/hippocamp.md` and registers the MCP server with `HIPPOCAMP_AGENT=grok`.
|
|
117
117
|
Managed instruction blocks tell the agent to call `wake_up` at the start of new top-level coding tasks before repo exploration or edits.
|
package/package.json
CHANGED
|
@@ -1,22 +1,31 @@
|
|
|
1
1
|
const fsSync = require("node:fs");
|
|
2
2
|
const fs = require("node:fs/promises");
|
|
3
|
+
const os = require("node:os");
|
|
3
4
|
const path = require("node:path");
|
|
4
5
|
const { execFile } = require("node:child_process");
|
|
5
6
|
const { promisify } = require("node:util");
|
|
6
7
|
|
|
7
8
|
const execFileAsync = promisify(execFile);
|
|
8
9
|
|
|
9
|
-
// How an agent starts the MCP server. Run through npx, the package
|
|
10
|
-
//
|
|
11
|
-
|
|
10
|
+
// How an agent starts the MCP server. Run through npx, the package sits in npm's cache, which
|
|
11
|
+
// npm may clean. Copy it with its dependencies to ~/.hippocamp/<version> and start it from
|
|
12
|
+
// there: no npx or network at start, so it also works offline.
|
|
13
|
+
function mcpServerCommand(repoRoot, home = os.homedir()) {
|
|
12
14
|
if (!repoRoot.split(path.sep).includes("_npx")) {
|
|
13
15
|
return [process.execPath, path.join(repoRoot, "scripts", "hippocamp-mcp.cjs")];
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
const { version } = require(path.join(repoRoot, "package.json"));
|
|
17
|
-
const
|
|
19
|
+
const target = path.join(home, ".hippocamp", version, "node_modules");
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
// Copy into a staging folder first, so a failed copy never removes a working install.
|
|
22
|
+
const staging = `${target}.staging-${process.pid}`;
|
|
23
|
+
fsSync.rmSync(staging, { recursive: true, force: true });
|
|
24
|
+
fsSync.cpSync(path.dirname(repoRoot), staging, { recursive: true, dereference: true });
|
|
25
|
+
fsSync.rmSync(target, { recursive: true, force: true });
|
|
26
|
+
fsSync.renameSync(staging, target);
|
|
27
|
+
|
|
28
|
+
return [process.execPath, path.join(target, path.basename(repoRoot), "scripts", "hippocamp-mcp.cjs")];
|
|
20
29
|
}
|
|
21
30
|
|
|
22
31
|
async function git(args, cwd) {
|
|
@@ -36,13 +36,30 @@ async function tempDir(t, name) {
|
|
|
36
36
|
return root;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
test("mcpServerCommand
|
|
39
|
+
test("mcpServerCommand copies npx installs to a stable folder and keeps source checkouts direct", async (t) => {
|
|
40
40
|
const root = await tempDir(t, "npx");
|
|
41
|
-
const
|
|
42
|
-
|
|
41
|
+
const modules = path.join(root, "_npx", "abc", "node_modules");
|
|
42
|
+
const npxRoot = path.join(modules, "hippocamp");
|
|
43
|
+
const home = path.join(root, "home");
|
|
44
|
+
await fs.mkdir(path.join(npxRoot, "scripts"), { recursive: true });
|
|
45
|
+
await fs.mkdir(path.join(modules, "minisearch"), { recursive: true });
|
|
43
46
|
await fs.writeFile(path.join(npxRoot, "package.json"), '{ "version": "9.9.9" }');
|
|
47
|
+
await fs.writeFile(path.join(npxRoot, "scripts", "hippocamp-mcp.cjs"), "// server\n");
|
|
48
|
+
await fs.writeFile(path.join(modules, "minisearch", "index.js"), "// dependency\n");
|
|
49
|
+
|
|
50
|
+
const command = mcpServerCommand(npxRoot, home);
|
|
51
|
+
const stable = path.join(home, ".hippocamp", "9.9.9", "node_modules");
|
|
52
|
+
|
|
53
|
+
assert.deepEqual(command, [process.execPath, path.join(stable, "hippocamp", "scripts", "hippocamp-mcp.cjs")]);
|
|
54
|
+
await fs.stat(command[1]);
|
|
55
|
+
await fs.stat(path.join(stable, "minisearch", "index.js"));
|
|
56
|
+
|
|
57
|
+
// A reinstall of the same version replaces the copy: no stale files, no staging left behind.
|
|
58
|
+
await fs.writeFile(path.join(stable, "stale.js"), "// old\n");
|
|
59
|
+
mcpServerCommand(npxRoot, home);
|
|
60
|
+
await assert.rejects(fs.stat(path.join(stable, "stale.js")));
|
|
61
|
+
assert.deepEqual(await fs.readdir(path.join(home, ".hippocamp", "9.9.9")), ["node_modules"]);
|
|
44
62
|
|
|
45
|
-
assert.deepEqual(mcpServerCommand(npxRoot).slice(1), ["-y", "--prefer-offline", "hippocamp@9.9.9", "mcp"]);
|
|
46
63
|
const source = path.join(root, "src", "hippocamp");
|
|
47
64
|
assert.deepEqual(mcpServerCommand(source), [process.execPath, path.join(source, "scripts", "hippocamp-mcp.cjs")]);
|
|
48
65
|
});
|