@cairnkeep/cli 2.3.0 → 2.4.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.
Files changed (125) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/README.md +221 -6
  3. package/bin/cairn +43 -2
  4. package/claude/capability-contract/hooks/capability-command-finish.sh +81 -0
  5. package/claude/capability-contract/hooks/capability-command-start.sh +76 -0
  6. package/claude/hooks/compaction-capture.sh +34 -0
  7. package/claude/hooks/memory-capture.sh +47 -5
  8. package/claude/hooks/memory-wakeup.sh +55 -2
  9. package/docs/building-an-overlay.md +1 -1
  10. package/docs/design/meta-agent.md +439 -0
  11. package/docs/learning/lessons/L00-why-cairnkeep.md +1 -1
  12. package/docs/learning/lessons/L01-safe-trial.md +3 -3
  13. package/docs/learning/lessons/L02-installation.md +2 -2
  14. package/docs/learning/lessons/L03-first-project.md +1 -1
  15. package/docs/operating.md +531 -4
  16. package/docs/privacy-and-data-flow.md +417 -0
  17. package/docs/storage.md +252 -0
  18. package/examples/eval/README.md +42 -0
  19. package/examples/eval/adapter.json +12 -0
  20. package/examples/eval/bundled-fake.json +1 -0
  21. package/examples/eval/task-set.json +1 -0
  22. package/mcp-memory-server/dist/artifact-cli.js +184 -0
  23. package/mcp-memory-server/dist/artifact-schema.js +218 -0
  24. package/mcp-memory-server/dist/artifact-store.js +812 -0
  25. package/mcp-memory-server/dist/capability-adapter.js +286 -0
  26. package/mcp-memory-server/dist/capability-cli.js +361 -0
  27. package/mcp-memory-server/dist/capability-config.js +310 -0
  28. package/mcp-memory-server/dist/capability-harness.js +496 -0
  29. package/mcp-memory-server/dist/capability-registry.js +123 -0
  30. package/mcp-memory-server/dist/capability-schema.js +65 -0
  31. package/mcp-memory-server/dist/capability-store.js +431 -0
  32. package/mcp-memory-server/dist/compaction-normalize.js +267 -0
  33. package/mcp-memory-server/dist/eval-cli.js +523 -0
  34. package/mcp-memory-server/dist/eval-plan.js +346 -0
  35. package/mcp-memory-server/dist/eval-process.js +273 -0
  36. package/mcp-memory-server/dist/eval-report.js +609 -0
  37. package/mcp-memory-server/dist/eval-runner.js +827 -0
  38. package/mcp-memory-server/dist/eval-schema.js +368 -0
  39. package/mcp-memory-server/dist/eval-statistics.js +161 -0
  40. package/mcp-memory-server/dist/eval-workspace.js +313 -0
  41. package/mcp-memory-server/dist/failure-signature.js +141 -0
  42. package/mcp-memory-server/dist/index.js +600 -55
  43. package/mcp-memory-server/dist/node-cli.js +84 -0
  44. package/mcp-memory-server/dist/node-schema.js +170 -0
  45. package/mcp-memory-server/dist/node-store.js +455 -0
  46. package/mcp-memory-server/dist/note-cli.js +235 -0
  47. package/mcp-memory-server/dist/note-distiller.js +177 -0
  48. package/mcp-memory-server/dist/note-enrichment.js +93 -0
  49. package/mcp-memory-server/dist/note-schema.js +4 -0
  50. package/mcp-memory-server/dist/note-store.js +985 -0
  51. package/mcp-memory-server/dist/trajectory-cli.js +141 -0
  52. package/mcp-memory-server/dist/trajectory-normalize.js +448 -0
  53. package/mcp-memory-server/dist/trajectory-redaction.js +155 -0
  54. package/mcp-memory-server/dist/trajectory-schema.js +73 -0
  55. package/mcp-memory-server/dist/trajectory-store.js +339 -0
  56. package/mcp-memory-server/package.json +24 -2
  57. package/mcp-memory-server/scripts/fixtures/compaction-claude-code-2.1.219.json +9 -0
  58. package/mcp-memory-server/scripts/fixtures/compaction-claude-code-2.1.220.json +9 -0
  59. package/mcp-memory-server/scripts/fixtures/compaction-opencode-1.17.20-event.json +6 -0
  60. package/mcp-memory-server/scripts/fixtures/compaction-opencode-1.17.20-messages.json +119 -0
  61. package/mcp-memory-server/scripts/fixtures/compaction-unknown-version.json +17 -0
  62. package/opencode/capability-contract/plugins/capability-command.ts +319 -0
  63. package/opencode/command/graphify.md +25 -14
  64. package/opencode/plugins/memory-capture.ts +76 -10
  65. package/opencode/plugins/memory-wakeup.ts +58 -6
  66. package/package.json +9 -4
  67. package/pi/extensions/cairnkeep-trajectory.ts +55 -0
  68. package/schemas/artifact.schema.json +133 -0
  69. package/schemas/capability-callback.schema.json +68 -0
  70. package/schemas/capability-contract.schema.json +126 -0
  71. package/schemas/eval-adapter.schema.json +43 -0
  72. package/schemas/eval-protocol.schema.json +114 -0
  73. package/schemas/eval-report.schema.json +423 -0
  74. package/schemas/eval-task-set.schema.json +114 -0
  75. package/schemas/memory-node.schema.json +90 -0
  76. package/schemas/note.schema.json +112 -0
  77. package/schemas/trajectory-redaction.schema.json +25 -0
  78. package/schemas/trajectory.schema.json +82 -0
  79. package/scripts/bootstrap.sh +4 -0
  80. package/scripts/completion.sh +119 -5
  81. package/scripts/doctor.sh +284 -0
  82. package/scripts/fake-eval-adapter.mjs +120 -0
  83. package/scripts/fixtures/capability-harness-contracts.json +408 -0
  84. package/scripts/install-audit-timer.sh +3 -1
  85. package/scripts/lib/capability-opencode-plugin-harness.mjs +291 -0
  86. package/scripts/lib/trajectory-opencode-plugin-harness.mjs +25 -0
  87. package/scripts/lib/trajectory-pi-extension-harness.mjs +42 -0
  88. package/scripts/memory-wiki-audit.sh +49 -0
  89. package/scripts/smoke-bash32.sh +9 -0
  90. package/scripts/sync-claude-assets.sh +99 -6
  91. package/scripts/sync-opencode-graphify-assets.sh +24 -3
  92. package/scripts/sync-opencode-plugin-assets.sh +31 -5
  93. package/scripts/sync-opencode-security-assets.sh +24 -3
  94. package/scripts/sync-opencode-wiki-assets.sh +24 -3
  95. package/scripts/sync-pi-assets.sh +72 -0
  96. package/scripts/test-audit-timer.sh +98 -0
  97. package/scripts/test-bootstrap-untracked.sh +48 -0
  98. package/scripts/test-cli-dispatch.sh +41 -2
  99. package/scripts/test-compaction-hooks.sh +495 -0
  100. package/scripts/test-completion.sh +77 -0
  101. package/scripts/test-doctor.sh +348 -1
  102. package/scripts/test-eval-cli.sh +175 -0
  103. package/scripts/test-launcher-hooks.sh +602 -3
  104. package/scripts/test-notes-cli.sh +114 -0
  105. package/scripts/test-package-install.sh +251 -0
  106. package/scripts/test-phase16-node-lifecycle.sh +50 -0
  107. package/scripts/test-phase17-artifact-lifecycle.sh +370 -0
  108. package/scripts/test-phase18-capability-lifecycle.sh +504 -0
  109. package/scripts/test-phase18-harness-boundary.sh +1060 -0
  110. package/scripts/test-phase19-eval-lifecycle.sh +1015 -0
  111. package/scripts/test-trajectory-cli.sh +87 -0
  112. package/scripts/test-trajectory-hooks.sh +142 -0
  113. package/scripts/test-uninstall.sh +231 -5
  114. package/scripts/uninstall.sh +37 -5
  115. package/scripts/verify-dependency-security.mjs +121 -0
  116. package/scripts/verify-docs-parity.sh +527 -1
  117. package/scripts/verify-phase18-runtime-evidence.mjs +895 -0
  118. package/scripts/verify-phase19-runtime-evidence.mjs +947 -0
  119. package/templates/capabilities.json.template +7 -0
  120. package/templates/env.example.template +51 -0
  121. package/templates/memory-wiki-audit.service.template +1 -1
  122. package/templates/start-claude.sh.template +36 -0
  123. package/templates/start-opencode.sh.template +47 -5
  124. package/templates/start-pi.sh.template +30 -0
  125. package/templates/trajectory-redaction.json.template +4 -0
@@ -0,0 +1,121 @@
1
+ #!/usr/bin/env node
2
+ import assert from "node:assert/strict";
3
+ import { readFileSync } from "node:fs";
4
+ import { resolve } from "node:path";
5
+
6
+ const ROOT = resolve(process.cwd());
7
+ const MINIMUM_SDK = [1, 30, 0];
8
+ const MINIMUM_NODE_SERVER = [2, 0, 5];
9
+ const DIRECT_HONO_PACKAGES = new Set(["hono", "@hono/node-server"]);
10
+ const PACKAGE_ROOTS = [
11
+ { label: "root", directory: "." },
12
+ { label: "mcp-memory-server", directory: "mcp-memory-server" },
13
+ ];
14
+
15
+ function readJson(path) {
16
+ return JSON.parse(readFileSync(resolve(ROOT, path), "utf8"));
17
+ }
18
+
19
+ function parseVersion(value, label) {
20
+ assert.equal(typeof value, "string", `${label}: version must be a string`);
21
+ const match = /^(\d+)\.(\d+)\.(\d+)$/.exec(value);
22
+ assert.ok(match, `${label}: expected a stable numeric semver triplet, found ${JSON.stringify(value)}`);
23
+ return match.slice(1).map(Number);
24
+ }
25
+
26
+ function compareVersions(left, right) {
27
+ for (let index = 0; index < 3; index += 1) {
28
+ if (left[index] !== right[index]) return left[index] - right[index];
29
+ }
30
+ return 0;
31
+ }
32
+
33
+ function minimumAdmittedVersion(range, label) {
34
+ assert.equal(typeof range, "string", `${label}: SDK range must be a string`);
35
+ const match = /^(?:\^|~|>=)?\s*(\d+)\.(\d+)\.(\d+)$/.exec(range);
36
+ assert.ok(
37
+ match,
38
+ `${label}: SDK range must have one explicit numeric lower bound, found ${JSON.stringify(range)}`,
39
+ );
40
+ return match.slice(1).map(Number);
41
+ }
42
+
43
+ function assertMinimum(version, minimum, label) {
44
+ assert.ok(
45
+ compareVersions(version, minimum) >= 0,
46
+ `${label}: requires >=${minimum.join(".")}, found ${version.join(".")}`,
47
+ );
48
+ }
49
+
50
+ function dependencySections(packageValue) {
51
+ return Object.entries(packageValue).filter(([key, value]) => (
52
+ /dependencies$/i.test(key) && (Array.isArray(value) || (value !== null && typeof value === "object"))
53
+ ));
54
+ }
55
+
56
+ function assertNoDirectHono(packageValue, label) {
57
+ for (const [section, dependencies] of dependencySections(packageValue)) {
58
+ const names = Array.isArray(dependencies) ? dependencies : Object.keys(dependencies);
59
+ for (const name of names) {
60
+ assert.equal(
61
+ DIRECT_HONO_PACKAGES.has(name),
62
+ false,
63
+ `${label}: ${section} must not directly declare ${name}`,
64
+ );
65
+ }
66
+ }
67
+ }
68
+
69
+ function resolvedPackages(lock, packageName) {
70
+ const suffix = `node_modules/${packageName}`;
71
+ return Object.entries(lock.packages ?? {}).filter(([key]) => key === suffix || key.endsWith(`/${suffix}`));
72
+ }
73
+
74
+ function verifyPackageRoot({ label, directory }) {
75
+ const manifest = readJson(`${directory}/package.json`);
76
+ const lock = readJson(`${directory}/package-lock.json`);
77
+ const lockRoot = lock.packages?.[""];
78
+ assert.ok(lockRoot, `${label}: package-lock root record is missing`);
79
+
80
+ assertNoDirectHono(manifest, `${label} manifest`);
81
+ assertNoDirectHono(lockRoot, `${label} lock root`);
82
+ assert.equal(
83
+ Object.prototype.hasOwnProperty.call(manifest, "overrides"),
84
+ false,
85
+ `${label} manifest: npm overrides are forbidden`,
86
+ );
87
+
88
+ const manifestRange = manifest.dependencies?.["@modelcontextprotocol/sdk"];
89
+ const lockRange = lockRoot.dependencies?.["@modelcontextprotocol/sdk"];
90
+ assertMinimum(minimumAdmittedVersion(manifestRange, `${label} manifest`), MINIMUM_SDK, `${label} manifest SDK range`);
91
+ assertMinimum(minimumAdmittedVersion(lockRange, `${label} lock root`), MINIMUM_SDK, `${label} lock SDK range`);
92
+ assert.equal(lockRange, manifestRange, `${label}: manifest and lock root SDK ranges differ`);
93
+
94
+ const sdkPackages = resolvedPackages(lock, "@modelcontextprotocol/sdk");
95
+ assert.ok(sdkPackages.length > 0, `${label}: resolved @modelcontextprotocol/sdk is missing`);
96
+ for (const [path, packageValue] of sdkPackages) {
97
+ assertMinimum(
98
+ parseVersion(packageValue.version, `${label} ${path}`),
99
+ MINIMUM_SDK,
100
+ `${label} resolved @modelcontextprotocol/sdk`,
101
+ );
102
+ }
103
+
104
+ const nodeServers = resolvedPackages(lock, "@hono/node-server");
105
+ assert.ok(nodeServers.length > 0, `${label}: resolved @hono/node-server is missing`);
106
+ for (const [path, packageValue] of nodeServers) {
107
+ assertMinimum(
108
+ parseVersion(packageValue.version, `${label} ${path}`),
109
+ MINIMUM_NODE_SERVER,
110
+ `${label} resolved @hono/node-server`,
111
+ );
112
+ }
113
+ }
114
+
115
+ try {
116
+ PACKAGE_ROOTS.forEach(verifyPackageRoot);
117
+ process.stdout.write("PASS: dependency manifests and lock graphs use the patched MCP Hono transport\n");
118
+ } catch (error) {
119
+ process.stderr.write(`FAIL: dependency security policy: ${error instanceof Error ? error.message : String(error)}\n`);
120
+ process.exitCode = 1;
121
+ }