@cairnkeep/cli 1.1.3 → 2.0.0

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
@@ -3,6 +3,24 @@
3
3
  All notable user-facing changes are documented here. This project follows
4
4
  [Semantic Versioning](https://semver.org/).
5
5
 
6
+ ## [2.0.0] - 2026-07-15
7
+
8
+ ### Breaking
9
+
10
+ - Require Node.js 22 or newer. Node.js 18 and 20 are end-of-life upstream;
11
+ Cairnkeep 1.x remains available for machines that cannot upgrade yet.
12
+
13
+ ### Changed
14
+
15
+ - Upgrade the runtime schema dependency to Zod 4 in both package manifests.
16
+ - Build with TypeScript 7 against Node.js 22 type definitions.
17
+ - Exercise Node.js 22, 24, and 26 on Linux, retain real macOS installation
18
+ coverage, and verify the packed package at the Node.js 22 runtime floor.
19
+
20
+ The memory database format, default storage location, remote HTTP protocol,
21
+ and project scaffold format are unchanged. Upgrading does not migrate or delete
22
+ stored memories.
23
+
6
24
  ## [1.1.3] - 2026-07-14
7
25
 
8
26
  ### Fixed
@@ -51,6 +69,9 @@ All notable user-facing changes are documented here. This project follows
51
69
  - Preserve executable permissions and Bash 3.2 portability on macOS.
52
70
  - Add backup-first uninstall and SQLite-safe memory export/import guidance.
53
71
 
72
+ [2.0.0]: https://github.com/cairnkeep/cairnkeep/compare/v1.1.3...v2.0.0
73
+ [1.1.3]: https://github.com/cairnkeep/cairnkeep/compare/v1.1.2...v1.1.3
74
+ [1.1.2]: https://github.com/cairnkeep/cairnkeep/compare/v1.1.1...v1.1.2
54
75
  [1.1.1]: https://github.com/cairnkeep/cairnkeep/compare/v1.1.0...v1.1.1
55
76
  [1.1.0]: https://github.com/cairnkeep/cairnkeep/compare/v1.0.5...v1.1.0
56
77
  [1.0.5]: https://github.com/cairnkeep/cairnkeep/compare/v1.0.4...v1.0.5
package/CONTRIBUTING.md CHANGED
@@ -15,9 +15,9 @@ Contributions are welcome through GitHub issues and pull requests.
15
15
 
16
16
  ## Development setup
17
17
 
18
- The memory server requires Node.js 18 or newer. Node.js 22 or 24 is recommended
19
- for development; current CI uses Node.js 24 and retains a clean Node.js 18
20
- compatibility boot check.
18
+ The memory server requires Node.js 22 or newer. CI builds and tests on Node.js
19
+ 22, 24, and 26, including a clean packed-install boot check at the Node.js 22
20
+ runtime floor.
21
21
 
22
22
  ```bash
23
23
  git clone https://github.com/cairnkeep/cairnkeep.git
package/README.md CHANGED
@@ -26,9 +26,9 @@ cairnkeep-org sibling project.
26
26
 
27
27
  ## Compatibility
28
28
 
29
- Node.js 22 or 24 is recommended. Node.js 18 and 20 remain compatible for the
30
- 1.x line but are end-of-life upstream; the minimum will move in the next major
31
- release.
29
+ Node.js 22, 24, and 26 are supported. Cairnkeep 2.x requires Node.js 22 or
30
+ newer; Cairnkeep 1.x remains available for older runtimes, although Node.js 18
31
+ and 20 are end-of-life upstream.
32
32
 
33
33
  | Client or platform | Support level |
34
34
  |---|---|
@@ -38,7 +38,7 @@ release.
38
38
  | Other MCP clients | Memory and optional domain-knowledge MCP tools |
39
39
  | Native Windows | Not supported by the Bash-based installer; use WSL (not yet CI-verified) |
40
40
 
41
- Linux, macOS, Bash 3.2 portability, and a clean Node 18 compatibility install
41
+ Linux, macOS, Bash 3.2 portability, and clean Node 22/24/26 runtime checks
42
42
  are exercised in CI.
43
43
 
44
44
  ## Components
package/docs/operating.md CHANGED
@@ -16,8 +16,8 @@ installs. This guide covers all three in order.
16
16
 
17
17
  ## Prerequisites
18
18
 
19
- - Node.js (for the memory server) and a supported harness: Claude Code or
20
- OpenCode.
19
+ - Node.js 22 or newer (for the memory server) and a supported harness: Claude
20
+ Code or OpenCode.
21
21
  - Optional: the `sqlite3` CLI for `cairn memory export`. Runtime memory and
22
22
  `cairn memory import` do not require it.
23
23
  - Optional: an OpenAI-compatible LLM endpoint for memory extraction and
@@ -13,6 +13,12 @@ import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/
13
13
  import { z } from "zod";
14
14
  import { EmbeddingCache, cosineSimilarity, embedTexts, getEmbeddingConfig, hashText, } from "./embeddings.js";
15
15
  import { computeRepoState, exploreCacheKey, normalizeExploreQuery, readExploreCache, writeExploreCache, } from "./explore-cache.js";
16
+ const MINIMUM_NODE_MAJOR = 22;
17
+ const nodeMajor = Number.parseInt(process.versions.node, 10);
18
+ if (!Number.isInteger(nodeMajor) || nodeMajor < MINIMUM_NODE_MAJOR) {
19
+ process.stderr.write(`cairn-memory requires Node.js ${MINIMUM_NODE_MAJOR} or newer; found ${process.versions.node}\n`);
20
+ process.exit(1);
21
+ }
16
22
  class ClientContextError extends Error {
17
23
  }
18
24
  const moduleDir = dirname(fileURLToPath(import.meta.url));
@@ -5,6 +5,9 @@
5
5
  "description": "Durable, harness-agnostic memory MCP server for coding agents — the core of Cairnkeep.",
6
6
  "license": "Apache-2.0",
7
7
  "type": "module",
8
+ "engines": {
9
+ "node": ">=22"
10
+ },
8
11
  "scripts": {
9
12
  "build": "tsc -p tsconfig.json",
10
13
  "start": "node dist/index.js",
@@ -28,10 +31,10 @@
28
31
  "dependencies": {
29
32
  "@modelcontextprotocol/sdk": "^1.29.0",
30
33
  "agentfs-sdk": "^0.6.4",
31
- "zod": "^3.25.76"
34
+ "zod": "^4.4.3"
32
35
  },
33
36
  "devDependencies": {
34
- "@types/node": "^22.15.21",
35
- "typescript": "^5.8.3"
37
+ "@types/node": "^22.20.1",
38
+ "typescript": "^7.0.2"
36
39
  }
37
40
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cairnkeep/cli",
3
- "version": "1.1.3",
3
+ "version": "2.0.0",
4
4
  "description": "A durable, harness-agnostic memory + context layer for coding agents (Claude Code, OpenCode).",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -28,12 +28,12 @@
28
28
  "AGENTS.md"
29
29
  ],
30
30
  "engines": {
31
- "node": ">=18"
31
+ "node": ">=22"
32
32
  },
33
33
  "dependencies": {
34
34
  "@modelcontextprotocol/sdk": "^1.29.0",
35
35
  "agentfs-sdk": "^0.6.4",
36
- "zod": "^3.25.76"
36
+ "zod": "^4.4.3"
37
37
  },
38
38
  "scripts": {
39
39
  "build:server": "npm --prefix mcp-memory-server ci --include=dev --global=false --dry-run=false && npm --prefix mcp-memory-server run build --global=false --dry-run=false",
package/scripts/doctor.sh CHANGED
@@ -35,7 +35,12 @@ echo "cairn doctor"
35
35
  server="$CAIRN_ROOT/mcp-memory-server/dist/index.js"
36
36
  probe="$CAIRN_ROOT/scripts/probe-memory-server.mjs"
37
37
  if ! command -v node >/dev/null 2>&1; then
38
- fail "Node.js not found (Node.js 18 or newer is required)"
38
+ fail "Node.js not found (Node.js 22 or newer is required)"
39
+ elif ! node_major=$(node -p 'Number(process.versions.node.split(".")[0])' 2>/dev/null) ||
40
+ [[ ! "$node_major" =~ ^[0-9]+$ ]]; then
41
+ fail "could not determine the Node.js version (Node.js 22 or newer is required)"
42
+ elif [[ "$node_major" -lt 22 ]]; then
43
+ fail "Node.js $(node --version 2>/dev/null || printf unknown) is unsupported (Node.js 22 or newer is required)"
39
44
  elif [[ ! -f "$server" ]]; then
40
45
  fail "memory server not built — run: (cd \"$CAIRN_ROOT/mcp-memory-server\" && npm install && npm run build)"
41
46
  elif node "$probe" "$server" >/dev/null 2>&1; then
@@ -17,7 +17,24 @@ proj="$tmp/clean"; mkdir -p "$proj"
17
17
  ( cd "$proj" && "$doctor" ) >"$tmp/out1" 2>&1 || fail "doctor exited non-zero with nothing configured:\n$(cat "$tmp/out1")"
18
18
  grep -q "\[SKIP\]" "$tmp/out1" || fail "expected SKIP lines when nothing is configured"
19
19
 
20
- # 2. A configured but unreachable endpoint → FAIL + non-zero exit.
20
+ # 2. An unsupported runtime is diagnosed before the server probe.
21
+ mkdir -p "$tmp/old-node"
22
+ cat > "$tmp/old-node/node" <<'EOF'
23
+ #!/usr/bin/env bash
24
+ case "${1:-}" in
25
+ -p) echo 20 ;;
26
+ --version) echo v20.19.0 ;;
27
+ *) exit 1 ;;
28
+ esac
29
+ EOF
30
+ chmod 755 "$tmp/old-node/node"
31
+ if ( cd "$proj" && PATH="$tmp/old-node:$PATH" "$doctor" ) >"$tmp/out-old-node" 2>&1; then
32
+ fail "doctor should exit non-zero for an unsupported Node.js runtime:\n$(cat "$tmp/out-old-node")"
33
+ fi
34
+ grep -q "Node.js v20.19.0 is unsupported" "$tmp/out-old-node" ||
35
+ fail "expected a clear unsupported-Node.js diagnostic"
36
+
37
+ # 3. A configured but unreachable endpoint → FAIL + non-zero exit.
21
38
  if command -v curl >/dev/null 2>&1; then
22
39
  proj2="$tmp/broken"; mkdir -p "$proj2/.ai"
23
40
  echo 'CAIRN_LLM_API_URL=http://127.0.0.1:1' > "$proj2/.ai/.env"
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
5
+
6
+ node --input-type=module - "$ROOT" <<'EOF'
7
+ import { readFileSync } from "node:fs";
8
+ import { join } from "node:path";
9
+
10
+ const root = process.argv[2];
11
+ const rootPackage = JSON.parse(readFileSync(join(root, "package.json"), "utf8"));
12
+ const serverPackage = JSON.parse(
13
+ readFileSync(join(root, "mcp-memory-server", "package.json"), "utf8"),
14
+ );
15
+
16
+ const failures = [];
17
+ if (rootPackage.engines?.node !== ">=22") failures.push("root Node.js engine must be >=22");
18
+ if (serverPackage.engines?.node !== rootPackage.engines?.node) {
19
+ failures.push("root and memory-server Node.js engines differ");
20
+ }
21
+ if (rootPackage.dependencies?.zod !== serverPackage.dependencies?.zod) {
22
+ failures.push("root and memory-server Zod declarations differ");
23
+ }
24
+ if (!rootPackage.dependencies?.zod?.startsWith("^4.")) failures.push("Zod must use major 4");
25
+ if (!serverPackage.devDependencies?.typescript?.startsWith("^7.")) {
26
+ failures.push("TypeScript must use major 7");
27
+ }
28
+ if (!serverPackage.devDependencies?.["@types/node"]?.startsWith("^22.")) {
29
+ failures.push("Node.js types must match the Node.js 22 runtime floor");
30
+ }
31
+
32
+ if (failures.length > 0) {
33
+ for (const failure of failures) console.error(`FAIL: ${failure}`);
34
+ process.exit(1);
35
+ }
36
+ EOF
37
+
38
+ grep -q 'node: \["22", "24", "26"\]' "$ROOT/.github/workflows/ci.yml"
39
+ if grep -Eq 'node-version: "(18|20)"|node:(18|20)-slim' "$ROOT/.github/workflows/ci.yml"; then
40
+ echo "FAIL: CI still declares an end-of-life Node.js runtime" >&2
41
+ exit 1
42
+ fi
43
+
44
+ echo "PASS: runtime and toolchain declarations are aligned"