squish-memory 1.0.2 → 1.1.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.
Files changed (341) hide show
  1. package/.env.example +130 -0
  2. package/CHANGELOG.md +55 -0
  3. package/README.md +150 -287
  4. package/config/hooks/claude-code-hooks.json +39 -0
  5. package/config/hooks/cursor-hooks.json +30 -0
  6. package/config/hooks/opencode-hooks.json +30 -0
  7. package/config/hooks/windsurf-hooks.json +30 -0
  8. package/config/mcp-mode-semantics.json +23 -21
  9. package/config/plugin-manifest.json +101 -152
  10. package/{plugin.json → config/plugin.json} +2 -2
  11. package/config/settings.json +52 -51
  12. package/{commands → core/commands}/init.md +39 -39
  13. package/dist/config.d.ts +28 -4
  14. package/dist/config.js +97 -29
  15. package/dist/core/adapters/config/claude-code.d.ts +45 -0
  16. package/dist/core/adapters/config/claude-code.js +113 -0
  17. package/dist/core/adapters/config/cursor.d.ts +26 -0
  18. package/dist/core/adapters/config/cursor.js +74 -0
  19. package/dist/core/adapters/config/opencode.d.ts +23 -0
  20. package/dist/core/adapters/config/opencode.js +73 -0
  21. package/dist/core/adapters/config/windsurf.d.ts +26 -0
  22. package/dist/core/adapters/config/windsurf.js +74 -0
  23. package/dist/core/adapters/index.d.ts +45 -0
  24. package/dist/core/adapters/index.js +84 -0
  25. package/dist/core/adapters/scripts/install-adapter.d.ts +19 -0
  26. package/dist/core/adapters/scripts/install-adapter.js +149 -0
  27. package/dist/core/adapters/timeline.d.ts +23 -0
  28. package/dist/core/adapters/timeline.js +88 -0
  29. package/dist/core/adapters/types.d.ts +157 -0
  30. package/dist/core/adapters/types.js +50 -0
  31. package/dist/{algorithms → core/algorithms}/analytics/token-estimator.d.ts +1 -1
  32. package/dist/{algorithms → core/algorithms}/analytics/token-estimator.js +3 -3
  33. package/dist/{algorithms → core/algorithms}/detection/semantic-ranker.d.ts +1 -1
  34. package/dist/{algorithms → core/algorithms}/detection/semantic-ranker.js +1 -1
  35. package/dist/{algorithms → core/algorithms}/detection/two-stage-detector.d.ts +1 -1
  36. package/dist/{algorithms → core/algorithms}/detection/two-stage-detector.js +7 -10
  37. package/dist/{algorithms → core/algorithms}/handlers/approve-merge.js +4 -4
  38. package/dist/{algorithms → core/algorithms}/handlers/detect-duplicates.js +3 -3
  39. package/dist/{algorithms → core/algorithms}/handlers/get-stats.js +3 -3
  40. package/dist/{algorithms → core/algorithms}/handlers/list-proposals.js +3 -3
  41. package/dist/{algorithms → core/algorithms}/handlers/preview-merge.js +3 -3
  42. package/dist/{algorithms → core/algorithms}/handlers/reject-merge.js +3 -3
  43. package/dist/{algorithms → core/algorithms}/handlers/reverse-merge.js +3 -3
  44. package/dist/core/algorithms/index.d.ts +21 -0
  45. package/dist/core/algorithms/index.js +26 -0
  46. package/dist/core/algorithms/operations/cache-maintenance.d.ts +12 -0
  47. package/dist/core/algorithms/operations/cache-maintenance.js +157 -0
  48. package/dist/{algorithms → core/algorithms}/safety/safety-checks.d.ts +1 -1
  49. package/dist/{algorithms → core/algorithms}/strategies/merge-strategies.d.ts +19 -1
  50. package/dist/{algorithms → core/algorithms}/strategies/merge-strategies.js +74 -123
  51. package/dist/core/algorithms/types.d.ts +133 -0
  52. package/dist/core/algorithms/types.js +5 -0
  53. package/dist/core/associations.d.ts +1 -2
  54. package/dist/core/associations.js +1 -2
  55. package/dist/core/autosave.d.ts +19 -0
  56. package/dist/core/autosave.js +16 -0
  57. package/dist/{commands → core/commands}/managed-sync.js +5 -5
  58. package/dist/core/commands/mcp-server.js +739 -0
  59. package/dist/core/context/agent-context.d.ts +106 -0
  60. package/dist/core/context/agent-context.js +274 -0
  61. package/dist/core/{context-paging.d.ts → context/context-paging.d.ts} +2 -12
  62. package/dist/core/{context-paging.js → context/context-paging.js} +19 -39
  63. package/dist/core/context/context-window.d.ts +40 -0
  64. package/dist/core/context/context-window.js +177 -0
  65. package/dist/core/context/context.js +22 -0
  66. package/dist/core/embeddings.d.ts +1 -1
  67. package/dist/core/embeddings.js +54 -2
  68. package/dist/core/error-handling.d.ts +63 -0
  69. package/dist/core/error-handling.js +173 -0
  70. package/dist/core/external-folder/index.d.ts +102 -0
  71. package/dist/core/external-folder/index.js +294 -0
  72. package/dist/core/hooks/agent-hooks.d.ts +74 -0
  73. package/dist/core/hooks/agent-hooks.js +244 -0
  74. package/dist/core/hooks/auto-tagger.d.ts +19 -0
  75. package/dist/core/hooks/auto-tagger.js +155 -0
  76. package/dist/core/hooks/capture-filter.d.ts +41 -0
  77. package/dist/core/hooks/capture-filter.js +128 -0
  78. package/dist/core/index.d.ts +6 -6
  79. package/dist/core/index.js +6 -6
  80. package/dist/core/{agent-memory.js → ingestion/agent-memory.js} +5 -7
  81. package/dist/core/{core-memory.js → ingestion/core-memory.js} +4 -4
  82. package/dist/core/ingestion/learnings.d.ts +57 -0
  83. package/dist/core/ingestion/learnings.js +202 -0
  84. package/dist/core/lib/db-client.d.ts +114 -0
  85. package/dist/core/lib/db-client.js +130 -0
  86. package/dist/core/lib/schemas.d.ts +129 -0
  87. package/dist/core/lib/schemas.js +87 -0
  88. package/dist/core/{utils.d.ts → lib/utils.d.ts} +1 -0
  89. package/dist/core/{utils.js → lib/utils.js} +31 -15
  90. package/dist/core/lib/validation.d.ts +38 -0
  91. package/dist/core/lib/validation.js +151 -0
  92. package/dist/core/lifecycle.d.ts +7 -0
  93. package/dist/core/lifecycle.js +140 -20
  94. package/dist/core/local-embeddings.d.ts +6 -1
  95. package/dist/core/local-embeddings.js +6 -15
  96. package/dist/core/logger.js +7 -1
  97. package/dist/core/mcp/tools.js +35 -3
  98. package/dist/core/memory/categorizer.js +1 -0
  99. package/dist/core/memory/conflict-detector.js +1 -1
  100. package/dist/core/memory/consolidation.d.ts +1 -10
  101. package/dist/core/memory/consolidation.js +2 -11
  102. package/dist/core/memory/context-collector.js +1 -1
  103. package/dist/core/memory/edit-workflow.js +1 -1
  104. package/dist/core/memory/entity-resolver.js +7 -7
  105. package/dist/core/memory/fact-extractor.js +12 -12
  106. package/dist/core/memory/feedback-tracker.js +1 -1
  107. package/dist/core/memory/hooks.d.ts +88 -0
  108. package/dist/core/memory/hooks.js +174 -0
  109. package/dist/core/memory/hybrid-retrieval.js +2 -2
  110. package/dist/core/memory/hybrid-search.d.ts +1 -6
  111. package/dist/core/memory/hybrid-search.js +70 -84
  112. package/dist/core/memory/importance.d.ts +8 -13
  113. package/dist/core/memory/importance.js +47 -74
  114. package/dist/core/memory/loader.d.ts +31 -0
  115. package/dist/core/memory/loader.js +141 -0
  116. package/dist/core/memory/markdown/markdown-storage.d.ts +72 -0
  117. package/dist/core/memory/markdown/markdown-storage.js +243 -0
  118. package/dist/core/memory/memories.d.ts +12 -4
  119. package/dist/core/memory/memories.js +192 -180
  120. package/dist/core/memory/memory-lifecycle.d.ts +8 -0
  121. package/dist/core/memory/memory-lifecycle.js +55 -0
  122. package/dist/core/memory/migrate.d.ts +21 -0
  123. package/dist/core/memory/migrate.js +134 -0
  124. package/dist/core/memory/normalization.d.ts +22 -0
  125. package/dist/core/memory/normalization.js +26 -0
  126. package/dist/core/memory/progressive-disclosure.js +1 -1
  127. package/dist/core/memory/query-rewriter.js +9 -9
  128. package/dist/core/memory/serialization.d.ts +4 -0
  129. package/dist/core/memory/serialization.js +49 -0
  130. package/dist/core/memory/stats.d.ts +5 -0
  131. package/dist/core/memory/stats.js +63 -12
  132. package/dist/core/memory/temporal-facts.js +21 -0
  133. package/dist/core/memory/write-gate.js +1 -1
  134. package/dist/core/obsidian-vault.d.ts +30 -0
  135. package/dist/core/obsidian-vault.js +94 -0
  136. package/dist/core/places/index.d.ts +14 -0
  137. package/dist/core/places/index.js +14 -0
  138. package/dist/core/places/memory-places.d.ts +68 -0
  139. package/dist/core/places/memory-places.js +261 -0
  140. package/dist/core/places/places.d.ts +88 -0
  141. package/dist/core/places/places.js +314 -0
  142. package/dist/core/places/rules.d.ts +74 -0
  143. package/dist/core/places/rules.js +240 -0
  144. package/dist/core/places/walking.d.ts +56 -0
  145. package/dist/core/places/walking.js +121 -0
  146. package/dist/core/projects.d.ts +5 -0
  147. package/dist/core/projects.js +39 -18
  148. package/dist/core/responses.d.ts +96 -0
  149. package/dist/core/responses.js +122 -0
  150. package/dist/core/scheduler/cron-scheduler.js +29 -7
  151. package/dist/core/scheduler/index.d.ts +1 -1
  152. package/dist/core/scheduler/index.js +1 -1
  153. package/dist/core/scheduler/job-runner.js +1 -1
  154. package/dist/core/search/conversations.js +40 -42
  155. package/dist/core/search/entities.js +6 -9
  156. package/dist/core/search/graph-boost.d.ts +7 -0
  157. package/dist/core/search/graph-boost.js +23 -0
  158. package/dist/core/search/qmd-search.js +4 -4
  159. package/dist/core/security/encrypt.d.ts +6 -0
  160. package/dist/core/security/encrypt.js +47 -0
  161. package/dist/core/{governance.d.ts → security/governance.d.ts} +6 -1
  162. package/dist/core/security/governance.js +79 -0
  163. package/dist/core/session/auto-load.js +6 -6
  164. package/dist/core/session/index.d.ts +1 -1
  165. package/dist/core/session/index.js +1 -1
  166. package/dist/core/session/self-iteration-job.d.ts +20 -0
  167. package/dist/core/session/self-iteration-job.js +282 -0
  168. package/dist/core/session/session-hooks.d.ts +18 -0
  169. package/dist/core/session/session-hooks.js +58 -0
  170. package/dist/core/session-hooks/self-iteration-job.js +35 -35
  171. package/dist/core/{cache.js → storage/cache.js} +2 -2
  172. package/dist/core/sync/qmd-sync.d.ts +1 -13
  173. package/dist/core/sync/qmd-sync.js +1 -13
  174. package/dist/core/toon.d.ts +43 -0
  175. package/dist/core/toon.js +160 -0
  176. package/dist/core/utils/memory-operations.js +1 -1
  177. package/dist/core/utils/vector-operations.d.ts +71 -0
  178. package/dist/core/utils/vector-operations.js +129 -0
  179. package/dist/db/adapter.d.ts +3 -3
  180. package/dist/db/adapter.js +99 -88
  181. package/dist/db/bootstrap.js +820 -522
  182. package/dist/{drizzle → db/drizzle}/schema-sqlite.d.ts +74 -25
  183. package/dist/{drizzle → db/drizzle}/schema-sqlite.js +91 -24
  184. package/dist/{drizzle → db/drizzle}/schema.d.ts +79 -32
  185. package/dist/{drizzle → db/drizzle}/schema.js +106 -35
  186. package/dist/db/drizzle.config.d.ts +3 -0
  187. package/dist/db/drizzle.config.js +12 -0
  188. package/dist/db/index.d.ts +1 -5
  189. package/dist/db/index.js +51 -8
  190. package/dist/db/neon.d.ts +8 -0
  191. package/dist/db/neon.js +20 -0
  192. package/dist/db/schema/index.d.ts +40 -0
  193. package/dist/db/schema/index.js +105 -0
  194. package/dist/db/schema/tables/context-sessions.d.ts +9 -0
  195. package/dist/db/schema/tables/context-sessions.js +37 -0
  196. package/dist/db/schema/tables/conversations.d.ts +9 -0
  197. package/dist/db/schema/tables/conversations.js +47 -0
  198. package/dist/db/schema/tables/core-memory.d.ts +9 -0
  199. package/dist/db/schema/tables/core-memory.js +41 -0
  200. package/dist/db/schema/tables/entities.d.ts +9 -0
  201. package/dist/db/schema/tables/entities.js +39 -0
  202. package/dist/db/schema/tables/entity-relations.d.ts +9 -0
  203. package/dist/db/schema/tables/entity-relations.js +31 -0
  204. package/dist/db/schema/tables/learnings.d.ts +9 -0
  205. package/dist/db/schema/tables/learnings.js +66 -0
  206. package/dist/db/schema/tables/memories.d.ts +9 -0
  207. package/dist/db/schema/tables/memories.js +161 -0
  208. package/dist/db/schema/tables/memory-associations.d.ts +9 -0
  209. package/dist/db/schema/tables/memory-associations.js +39 -0
  210. package/dist/db/schema/tables/memory-hash-cache.d.ts +9 -0
  211. package/dist/db/schema/tables/memory-hash-cache.js +29 -0
  212. package/dist/db/schema/tables/memory-merge-history.d.ts +9 -0
  213. package/dist/db/schema/tables/memory-merge-history.js +33 -0
  214. package/dist/db/schema/tables/memory-merge-proposals.d.ts +9 -0
  215. package/dist/db/schema/tables/memory-merge-proposals.js +39 -0
  216. package/dist/db/schema/tables/messages.d.ts +9 -0
  217. package/dist/db/schema/tables/messages.js +41 -0
  218. package/dist/db/schema/tables/namespaces.d.ts +9 -0
  219. package/dist/db/schema/tables/namespaces.js +37 -0
  220. package/dist/db/schema/tables/projects.d.ts +9 -0
  221. package/dist/db/schema/tables/projects.js +31 -0
  222. package/dist/db/schema/tables/users.d.ts +9 -0
  223. package/dist/db/schema/tables/users.js +27 -0
  224. package/dist/db/schema.d.ts +1 -1
  225. package/dist/db/schema.js +2 -2
  226. package/dist/db/supabase.d.ts +9 -0
  227. package/dist/db/supabase.js +24 -0
  228. package/dist/index.d.ts +2 -14
  229. package/dist/index.js +1320 -640
  230. package/dist/vendor/sql.js/sql-wasm.wasm +0 -0
  231. package/dist/webui/server.d.ts +5 -0
  232. package/dist/{api/web/web.js → webui/server.js} +511 -508
  233. package/generated/mcp/manifest.json +1 -1
  234. package/{.mcp.json → mcp.json.example} +1 -1
  235. package/package.json +159 -181
  236. package/scripts/README.md +60 -0
  237. package/scripts/copy-runtime-assets.mjs +26 -0
  238. package/scripts/generate-mcp.mjs +264 -264
  239. package/scripts/github-release.sh +4 -4
  240. package/scripts/install-claude-code.sh +85 -0
  241. package/scripts/install-cursor.sh +56 -0
  242. package/scripts/install-hooks.sh +73 -0
  243. package/scripts/install-interactive.mjs +357 -677
  244. package/scripts/install-opencode.sh +75 -0
  245. package/scripts/install-windsurf.sh +67 -0
  246. package/skills/squish-memory/SKILL.md +104 -114
  247. package/skills/squish-memory/{install.mjs → scripts/install.mjs} +2 -2
  248. package/skills/squish-memory/{install.sh → scripts/install.sh} +2 -2
  249. package/skills/squish-memory/write_skill.js +2 -0
  250. package/.claude-plugin/marketplace.json +0 -20
  251. package/.claude-plugin/plugin.json +0 -32
  252. package/.env.mcp.example +0 -60
  253. package/QUICK-START.md +0 -71
  254. package/bin/squish-add.mjs +0 -32
  255. package/bin/squish-rm.mjs +0 -21
  256. package/commands/observe.md +0 -5
  257. package/dist/api/web/index.d.ts +0 -3
  258. package/dist/api/web/index.js +0 -4
  259. package/dist/api/web/web-server.d.ts +0 -3
  260. package/dist/api/web/web-server.js +0 -6
  261. package/dist/api/web/web.d.ts +0 -4
  262. package/dist/commands/mcp-server.js +0 -393
  263. package/dist/core/context.js +0 -24
  264. package/dist/core/governance.js +0 -64
  265. package/dist/core/observations.d.ts +0 -26
  266. package/dist/core/observations.js +0 -110
  267. package/dist/core/requirements.d.ts +0 -20
  268. package/dist/core/requirements.js +0 -35
  269. package/hooks/hooks.json +0 -52
  270. package/hooks/post-tool-use.js +0 -26
  271. package/hooks/session-end.js +0 -28
  272. package/hooks/session-start.js +0 -33
  273. package/hooks/user-prompt-submit.js +0 -26
  274. package/hooks/utils.js +0 -153
  275. package/npx-installer.js +0 -208
  276. package/packages/plugin-claude-code/README.md +0 -73
  277. package/packages/plugin-claude-code/dist/plugin-wrapper.d.ts +0 -35
  278. package/packages/plugin-claude-code/dist/plugin-wrapper.js +0 -191
  279. package/packages/plugin-claude-code/package.json +0 -31
  280. package/packages/plugin-openclaw/README.md +0 -70
  281. package/packages/plugin-openclaw/dist/index.d.ts +0 -49
  282. package/packages/plugin-openclaw/dist/index.js +0 -262
  283. package/packages/plugin-openclaw/openclaw.plugin.json +0 -94
  284. package/packages/plugin-openclaw/package.json +0 -31
  285. package/packages/plugin-opencode/install.mjs +0 -217
  286. package/packages/plugin-opencode/package.json +0 -21
  287. package/scripts/db/check-db.mjs +0 -88
  288. package/scripts/db/fix-all-columns.mjs +0 -52
  289. package/scripts/db/fix-schema-all.mjs +0 -55
  290. package/scripts/db/fix-schema-full.mjs +0 -46
  291. package/scripts/db/fix-schema.mjs +0 -38
  292. package/scripts/db/init-db.mjs +0 -13
  293. package/scripts/db/recreate-db.mjs +0 -14
  294. package/scripts/install-mcp.mjs +0 -116
  295. package/scripts/install-web.sh +0 -120
  296. package/scripts/install.mjs +0 -340
  297. package/scripts/openclaw-bootstrap.mjs +0 -127
  298. package/scripts/package-release.sh +0 -71
  299. package/scripts/test/test-all-systems.mjs +0 -139
  300. package/scripts/test/test-memory-system.mjs +0 -139
  301. package/scripts/test/test-v0.5.0.mjs +0 -210
  302. package/skills/memory-guide/SKILL.md +0 -332
  303. package/skills/squish-cli/SKILL.md +0 -240
  304. package/skills/squish-mcp/SKILL.md +0 -355
  305. package/skills/squish-memory/claude-desktop.json +0 -12
  306. package/skills/squish-memory/openclaw.json +0 -13
  307. package/skills/squish-memory/opencode.json +0 -14
  308. package/skills/squish-memory/skill.json +0 -32
  309. /package/{commands → core/commands}/context-paging.md +0 -0
  310. /package/{commands → core/commands}/context-status.md +0 -0
  311. /package/{commands → core/commands}/context.md +0 -0
  312. /package/{commands → core/commands}/core-memory.md +0 -0
  313. /package/{commands → core/commands}/health.md +0 -0
  314. /package/{commands → core/commands}/merge.md +0 -0
  315. /package/{commands → core/commands}/recall.md +0 -0
  316. /package/{commands → core/commands}/remember.md +0 -0
  317. /package/{commands → core/commands}/search.md +0 -0
  318. /package/dist/{algorithms → core/algorithms}/detection/hash-filters.d.ts +0 -0
  319. /package/dist/{algorithms → core/algorithms}/detection/hash-filters.js +0 -0
  320. /package/dist/{algorithms → core/algorithms}/handlers/approve-merge.d.ts +0 -0
  321. /package/dist/{algorithms → core/algorithms}/handlers/detect-duplicates.d.ts +0 -0
  322. /package/dist/{algorithms → core/algorithms}/handlers/get-stats.d.ts +0 -0
  323. /package/dist/{algorithms → core/algorithms}/handlers/list-proposals.d.ts +0 -0
  324. /package/dist/{algorithms → core/algorithms}/handlers/preview-merge.d.ts +0 -0
  325. /package/dist/{algorithms → core/algorithms}/handlers/reject-merge.d.ts +0 -0
  326. /package/dist/{algorithms → core/algorithms}/handlers/reverse-merge.d.ts +0 -0
  327. /package/dist/{algorithms → core/algorithms}/safety/safety-checks.js +0 -0
  328. /package/dist/{algorithms → core/algorithms}/utils/response-builder.d.ts +0 -0
  329. /package/dist/{algorithms → core/algorithms}/utils/response-builder.js +0 -0
  330. /package/dist/{commands → core/commands}/managed-sync.d.ts +0 -0
  331. /package/dist/{commands → core/commands}/mcp-server.d.ts +0 -0
  332. /package/dist/core/{context.d.ts → context/context.d.ts} +0 -0
  333. /package/dist/core/{agent-memory.d.ts → ingestion/agent-memory.d.ts} +0 -0
  334. /package/dist/core/{core-memory.d.ts → ingestion/core-memory.d.ts} +0 -0
  335. /package/dist/core/{privacy.d.ts → security/privacy.d.ts} +0 -0
  336. /package/dist/core/{privacy.js → security/privacy.js} +0 -0
  337. /package/dist/core/{secret-detector.d.ts → security/secret-detector.d.ts} +0 -0
  338. /package/dist/core/{secret-detector.js → security/secret-detector.js} +0 -0
  339. /package/dist/core/{cache.d.ts → storage/cache.d.ts} +0 -0
  340. /package/dist/core/{database.d.ts → storage/database.d.ts} +0 -0
  341. /package/dist/core/{database.js → storage/database.js} +0 -0
@@ -1,264 +1,264 @@
1
- #!/usr/bin/env node
2
-
3
- import fs from "node:fs";
4
- import path from "node:path";
5
- import crypto from "node:crypto";
6
-
7
- const root = process.cwd();
8
- const defaultSourcePath = path.join(root, "config", "mcp.json");
9
- const defaultOutDir = path.join(root, "generated", "mcp");
10
- const defaultImports = [
11
- "cursor",
12
- "claude-code",
13
- "claude-desktop",
14
- "codex",
15
- "windsurf",
16
- "opencode",
17
- "vscode"
18
- ];
19
-
20
- function parseArgs(argv) {
21
- const args = {
22
- configPath: defaultSourcePath,
23
- outDir: defaultOutDir,
24
- strictEnv: false
25
- };
26
-
27
- for (let i = 2; i < argv.length; i += 1) {
28
- const token = argv[i];
29
- if (token === "--strict-env") {
30
- args.strictEnv = true;
31
- continue;
32
- }
33
- if (token === "--config") {
34
- args.configPath = path.resolve(argv[i + 1]);
35
- i += 1;
36
- continue;
37
- }
38
- if (token === "--out") {
39
- args.outDir = path.resolve(argv[i + 1]);
40
- i += 1;
41
- continue;
42
- }
43
- throw new Error(`Unknown argument: ${token}`);
44
- }
45
-
46
- return args;
47
- }
48
-
49
- function readJson(filePath) {
50
- return JSON.parse(fs.readFileSync(filePath, "utf8"));
51
- }
52
-
53
- function ensureDir(dirPath) {
54
- fs.mkdirSync(dirPath, { recursive: true });
55
- }
56
-
57
- function writeJson(filePath, data) {
58
- fs.writeFileSync(filePath, `${JSON.stringify(data, null, 2)}\n`, "utf8");
59
- }
60
-
61
- function sha256File(filePath) {
62
- const hash = crypto.createHash("sha256");
63
- hash.update(fs.readFileSync(filePath));
64
- return hash.digest("hex");
65
- }
66
-
67
- function sortObjectKeys(input) {
68
- if (Array.isArray(input)) {
69
- return input.map(sortObjectKeys);
70
- }
71
- if (input && typeof input === "object") {
72
- const sorted = {};
73
- for (const key of Object.keys(input).sort()) {
74
- sorted[key] = sortObjectKeys(input[key]);
75
- }
76
- return sorted;
77
- }
78
- return input;
79
- }
80
-
81
- function extractEnvPlaceholders(servers) {
82
- const placeholders = [];
83
- for (const [serverName, server] of Object.entries(servers)) {
84
- const env = server?.env || {};
85
- for (const [envKey, value] of Object.entries(env)) {
86
- if (typeof value !== "string") continue;
87
- const match = value.match(/^\$\{([A-Z0-9_]+)\}$/);
88
- if (match) {
89
- placeholders.push({ serverName, envKey, variable: match[1] });
90
- }
91
- }
92
- }
93
- return placeholders;
94
- }
95
-
96
- function validateConfig(config, strictEnv) {
97
- if (!config || typeof config !== "object") {
98
- throw new Error("Invalid config: expected object");
99
- }
100
-
101
- if (!config.defaults || typeof config.defaults !== "object") {
102
- throw new Error("Invalid config: defaults must be an object");
103
- }
104
-
105
- if (!config.servers || typeof config.servers !== "object") {
106
- throw new Error("Invalid config: servers must be an object");
107
- }
108
-
109
- const serverNames = Object.keys(config.servers);
110
- if (serverNames.length === 0) {
111
- throw new Error("Invalid config: at least one server is required");
112
- }
113
-
114
- for (const [serverName, server] of Object.entries(config.servers)) {
115
- if (!server || typeof server !== "object") {
116
- throw new Error(`Invalid server ${serverName}: expected object`);
117
- }
118
- if (!server.command || typeof server.command !== "string") {
119
- throw new Error(`Invalid server ${serverName}: command is required`);
120
- }
121
- if (!Array.isArray(server.args)) {
122
- throw new Error(`Invalid server ${serverName}: args must be an array`);
123
- }
124
- if (!server.transport || typeof server.transport !== "string") {
125
- throw new Error(`Invalid server ${serverName}: transport is required`);
126
- }
127
- if (!server.env || typeof server.env !== "object") {
128
- throw new Error(`Invalid server ${serverName}: env must be an object`);
129
- }
130
- }
131
-
132
- const includeServers = config.includeServers || [];
133
- if (includeServers.length > 0) {
134
- const unique = new Set(includeServers);
135
- if (unique.size !== includeServers.length) {
136
- throw new Error("Invalid config: includeServers contains duplicates");
137
- }
138
- for (const name of includeServers) {
139
- if (!config.servers[name]) {
140
- throw new Error(`Invalid config: includeServers references unknown server ${name}`);
141
- }
142
- }
143
- }
144
-
145
- if (strictEnv) {
146
- const unresolved = extractEnvPlaceholders(config.servers)
147
- .filter((entry) => !process.env[entry.variable]);
148
- if (unresolved.length > 0) {
149
- const first = unresolved[0];
150
- throw new Error(
151
- `Missing required env for strict mode: ${first.variable} (server=${first.serverName}, key=${first.envKey})`
152
- );
153
- }
154
- }
155
- }
156
-
157
- function selectServers(config) {
158
- const include = config.includeServers || [];
159
- if (include.length === 0) {
160
- return config.servers;
161
- }
162
- const selected = {};
163
- for (const serverName of include) {
164
- selected[serverName] = config.servers[serverName];
165
- }
166
- return selected;
167
- }
168
-
169
- function toOpenClawMemoryConfig(runtime) {
170
- return {
171
- memory: {
172
- backend: "qmd",
173
- qmd: {
174
- mcporter: {
175
- enabled: true,
176
- serverName: "qmd",
177
- startDaemon: true
178
- },
179
- limits: {
180
- timeoutMs: runtime.requestTimeoutMs,
181
- maxSnippetChars: runtime.resultMaxChars,
182
- maxResults: 12
183
- }
184
- }
185
- }
186
- };
187
- }
188
-
189
- function toMcporterConfig(servers) {
190
- return {
191
- mcpServers: servers,
192
- imports: defaultImports
193
- };
194
- }
195
-
196
- function removeLegacyProfileDirectories(outDir) {
197
- const removed = [];
198
- if (!fs.existsSync(outDir)) return;
199
- const entries = fs.readdirSync(outDir, { withFileTypes: true });
200
- for (const entry of entries) {
201
- if (entry.isDirectory()) {
202
- fs.rmSync(path.join(outDir, entry.name), { recursive: true, force: true });
203
- removed.push(entry.name);
204
- }
205
- }
206
- return removed;
207
- }
208
-
209
- function main() {
210
- const args = parseArgs(process.argv);
211
- const config = readJson(args.configPath);
212
-
213
- validateConfig(config, args.strictEnv);
214
-
215
- ensureDir(args.outDir);
216
- const removedLegacyDirs = removeLegacyProfileDirectories(args.outDir) || [];
217
-
218
- if (config.profiles && typeof config.profiles === "object") {
219
- console.warn(
220
- "[mcp-migration] legacy profiles detected in config/mcp.json and ignored by universal generator"
221
- );
222
- }
223
- if (removedLegacyDirs.length > 0) {
224
- console.warn(
225
- `[mcp-migration] removed legacy profile output directories: ${removedLegacyDirs.join(", ")}`
226
- );
227
- }
228
-
229
- const runtime = sortObjectKeys(config.defaults);
230
- const selectedServers = sortObjectKeys(selectServers(config));
231
-
232
- const fileMap = {
233
- "runtime.json": runtime,
234
- "mcp-servers.json": { mcpServers: selectedServers },
235
- "mcporter.json": toMcporterConfig(selectedServers),
236
- "openclaw-memory-qmd.json": toOpenClawMemoryConfig(runtime)
237
- };
238
-
239
- for (const [fileName, json] of Object.entries(fileMap)) {
240
- writeJson(path.join(args.outDir, fileName), json);
241
- }
242
-
243
- const manifestFiles = Object.keys(fileMap)
244
- .sort()
245
- .map((fileName) => {
246
- const filePath = path.join(args.outDir, fileName);
247
- return {
248
- file: fileName,
249
- sha256: sha256File(filePath)
250
- };
251
- });
252
-
253
- const manifest = {
254
- mode: "universal",
255
- generatedAt: new Date().toISOString(),
256
- source: path.relative(root, args.configPath).replace(/\\/g, "/"),
257
- files: manifestFiles
258
- };
259
-
260
- writeJson(path.join(args.outDir, "manifest.json"), manifest);
261
- console.log(`Generated universal MCP artifacts in ${args.outDir}`);
262
- }
263
-
264
- main();
1
+ #!/usr/bin/env node
2
+
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+ import crypto from "node:crypto";
6
+
7
+ const root = process.cwd();
8
+ const defaultSourcePath = path.join(root, "config", "mcp.json");
9
+ const defaultOutDir = path.join(root, "generated", "mcp");
10
+ const defaultImports = [
11
+ "cursor",
12
+ "claude-code",
13
+ "claude-desktop",
14
+ "codex",
15
+ "windsurf",
16
+ "opencode",
17
+ "vscode"
18
+ ];
19
+
20
+ function parseArgs(argv) {
21
+ const args = {
22
+ configPath: defaultSourcePath,
23
+ outDir: defaultOutDir,
24
+ strictEnv: false
25
+ };
26
+
27
+ for (let i = 2; i < argv.length; i += 1) {
28
+ const token = argv[i];
29
+ if (token === "--strict-env") {
30
+ args.strictEnv = true;
31
+ continue;
32
+ }
33
+ if (token === "--config") {
34
+ args.configPath = path.resolve(argv[i + 1]);
35
+ i += 1;
36
+ continue;
37
+ }
38
+ if (token === "--out") {
39
+ args.outDir = path.resolve(argv[i + 1]);
40
+ i += 1;
41
+ continue;
42
+ }
43
+ throw new Error(`Unknown argument: ${token}`);
44
+ }
45
+
46
+ return args;
47
+ }
48
+
49
+ function readJson(filePath) {
50
+ return JSON.parse(fs.readFileSync(filePath, "utf8"));
51
+ }
52
+
53
+ function ensureDir(dirPath) {
54
+ fs.mkdirSync(dirPath, { recursive: true });
55
+ }
56
+
57
+ function writeJson(filePath, data) {
58
+ fs.writeFileSync(filePath, `${JSON.stringify(data, null, 2)}\n`, "utf8");
59
+ }
60
+
61
+ function sha256File(filePath) {
62
+ const hash = crypto.createHash("sha256");
63
+ hash.update(fs.readFileSync(filePath));
64
+ return hash.digest("hex");
65
+ }
66
+
67
+ function sortObjectKeys(input) {
68
+ if (Array.isArray(input)) {
69
+ return input.map(sortObjectKeys);
70
+ }
71
+ if (input && typeof input === "object") {
72
+ const sorted = {};
73
+ for (const key of Object.keys(input).sort()) {
74
+ sorted[key] = sortObjectKeys(input[key]);
75
+ }
76
+ return sorted;
77
+ }
78
+ return input;
79
+ }
80
+
81
+ function extractEnvPlaceholders(servers) {
82
+ const placeholders = [];
83
+ for (const [serverName, server] of Object.entries(servers)) {
84
+ const env = server?.env || {};
85
+ for (const [envKey, value] of Object.entries(env)) {
86
+ if (typeof value !== "string") continue;
87
+ const match = value.match(/^\$\{([A-Z0-9_]+)\}$/);
88
+ if (match) {
89
+ placeholders.push({ serverName, envKey, variable: match[1] });
90
+ }
91
+ }
92
+ }
93
+ return placeholders;
94
+ }
95
+
96
+ function validateConfig(config, strictEnv) {
97
+ if (!config || typeof config !== "object") {
98
+ throw new Error("Invalid config: expected object");
99
+ }
100
+
101
+ if (!config.defaults || typeof config.defaults !== "object") {
102
+ throw new Error("Invalid config: defaults must be an object");
103
+ }
104
+
105
+ if (!config.servers || typeof config.servers !== "object") {
106
+ throw new Error("Invalid config: servers must be an object");
107
+ }
108
+
109
+ const serverNames = Object.keys(config.servers);
110
+ if (serverNames.length === 0) {
111
+ throw new Error("Invalid config: at least one server is required");
112
+ }
113
+
114
+ for (const [serverName, server] of Object.entries(config.servers)) {
115
+ if (!server || typeof server !== "object") {
116
+ throw new Error(`Invalid server ${serverName}: expected object`);
117
+ }
118
+ if (!server.command || typeof server.command !== "string") {
119
+ throw new Error(`Invalid server ${serverName}: command is required`);
120
+ }
121
+ if (!Array.isArray(server.args)) {
122
+ throw new Error(`Invalid server ${serverName}: args must be an array`);
123
+ }
124
+ if (!server.transport || typeof server.transport !== "string") {
125
+ throw new Error(`Invalid server ${serverName}: transport is required`);
126
+ }
127
+ if (!server.env || typeof server.env !== "object") {
128
+ throw new Error(`Invalid server ${serverName}: env must be an object`);
129
+ }
130
+ }
131
+
132
+ const includeServers = config.includeServers || [];
133
+ if (includeServers.length > 0) {
134
+ const unique = new Set(includeServers);
135
+ if (unique.size !== includeServers.length) {
136
+ throw new Error("Invalid config: includeServers contains duplicates");
137
+ }
138
+ for (const name of includeServers) {
139
+ if (!config.servers[name]) {
140
+ throw new Error(`Invalid config: includeServers references unknown server ${name}`);
141
+ }
142
+ }
143
+ }
144
+
145
+ if (strictEnv) {
146
+ const unresolved = extractEnvPlaceholders(config.servers)
147
+ .filter((entry) => !process.env[entry.variable]);
148
+ if (unresolved.length > 0) {
149
+ const first = unresolved[0];
150
+ throw new Error(
151
+ `Missing required env for strict mode: ${first.variable} (server=${first.serverName}, key=${first.envKey})`
152
+ );
153
+ }
154
+ }
155
+ }
156
+
157
+ function selectServers(config) {
158
+ const include = config.includeServers || [];
159
+ if (include.length === 0) {
160
+ return config.servers;
161
+ }
162
+ const selected = {};
163
+ for (const serverName of include) {
164
+ selected[serverName] = config.servers[serverName];
165
+ }
166
+ return selected;
167
+ }
168
+
169
+ function toOpenClawMemoryConfig(runtime) {
170
+ return {
171
+ memory: {
172
+ backend: "qmd",
173
+ qmd: {
174
+ mcporter: {
175
+ enabled: true,
176
+ serverName: "qmd",
177
+ startDaemon: true
178
+ },
179
+ limits: {
180
+ timeoutMs: runtime.requestTimeoutMs,
181
+ maxSnippetChars: runtime.resultMaxChars,
182
+ maxResults: 12
183
+ }
184
+ }
185
+ }
186
+ };
187
+ }
188
+
189
+ function toMcporterConfig(servers) {
190
+ return {
191
+ mcpServers: servers,
192
+ imports: defaultImports
193
+ };
194
+ }
195
+
196
+ function removeLegacyProfileDirectories(outDir) {
197
+ const removed = [];
198
+ if (!fs.existsSync(outDir)) return;
199
+ const entries = fs.readdirSync(outDir, { withFileTypes: true });
200
+ for (const entry of entries) {
201
+ if (entry.isDirectory()) {
202
+ fs.rmSync(path.join(outDir, entry.name), { recursive: true, force: true });
203
+ removed.push(entry.name);
204
+ }
205
+ }
206
+ return removed;
207
+ }
208
+
209
+ function main() {
210
+ const args = parseArgs(process.argv);
211
+ const config = readJson(args.configPath);
212
+
213
+ validateConfig(config, args.strictEnv);
214
+
215
+ ensureDir(args.outDir);
216
+ const removedLegacyDirs = removeLegacyProfileDirectories(args.outDir) || [];
217
+
218
+ if (config.profiles && typeof config.profiles === "object") {
219
+ console.warn(
220
+ "[mcp-migration] legacy profiles detected in config/mcp.json and ignored by universal generator"
221
+ );
222
+ }
223
+ if (removedLegacyDirs.length > 0) {
224
+ console.warn(
225
+ `[mcp-migration] removed legacy profile output directories: ${removedLegacyDirs.join(", ")}`
226
+ );
227
+ }
228
+
229
+ const runtime = sortObjectKeys(config.defaults);
230
+ const selectedServers = sortObjectKeys(selectServers(config));
231
+
232
+ const fileMap = {
233
+ "runtime.json": runtime,
234
+ "mcp-servers.json": { mcpServers: selectedServers },
235
+ "mcporter.json": toMcporterConfig(selectedServers),
236
+ "openclaw-memory-qmd.json": toOpenClawMemoryConfig(runtime)
237
+ };
238
+
239
+ for (const [fileName, json] of Object.entries(fileMap)) {
240
+ writeJson(path.join(args.outDir, fileName), json);
241
+ }
242
+
243
+ const manifestFiles = Object.keys(fileMap)
244
+ .sort()
245
+ .map((fileName) => {
246
+ const filePath = path.join(args.outDir, fileName);
247
+ return {
248
+ file: fileName,
249
+ sha256: sha256File(filePath)
250
+ };
251
+ });
252
+
253
+ const manifest = {
254
+ mode: "universal",
255
+ generatedAt: new Date().toISOString(),
256
+ source: path.relative(root, args.configPath).replace(/\\/g, "/"),
257
+ files: manifestFiles
258
+ };
259
+
260
+ writeJson(path.join(args.outDir, "manifest.json"), manifest);
261
+ console.log(`Generated universal MCP artifacts in ${args.outDir}`);
262
+ }
263
+
264
+ main();
@@ -19,22 +19,22 @@ cd release-assets
19
19
  # Linux x64
20
20
  echo "Building linux-x64..."
21
21
  npx pkg ../dist/index.js --targets node18-linux-x64 --output squish-linux-x64
22
- tar -czf "../squish-v${VERSION}-linux-x64.tar.gz" squish-linux-x64 ../dist/ ../plugin.json ../README.md ../LICENSE
22
+ tar -czf "../squish-v${VERSION}-linux-x64.tar.gz" squish-linux-x64 ../dist/ ../config/plugin.json ../README.md ../LICENSE
23
23
 
24
24
  # Linux ARM64
25
25
  echo "Building linux-arm64..."
26
26
  npx pkg ../dist/index.js --targets node18-linux-arm64 --output squish-linux-arm64
27
- tar -czf "../squish-v${VERSION}-linux-arm64.tar.gz" squish-linux-arm64 ../dist/ ../plugin.json ../README.md ../LICENSE
27
+ tar -czf "../squish-v${VERSION}-linux-arm64.tar.gz" squish-linux-arm64 ../dist/ ../config/plugin.json ../README.md ../LICENSE
28
28
 
29
29
  # macOS ARM64 (Apple Silicon)
30
30
  echo "Building macos-arm64..."
31
31
  npx pkg ../dist/index.js --targets node18-macos-arm64 --output squish-macos-arm64
32
- tar -czf "../squish-v${VERSION}-macos-arm64.tar.gz" squish-macos-arm64 ../dist/ ../plugin.json ../README.md ../LICENSE
32
+ tar -czf "../squish-v${VERSION}-macos-arm64.tar.gz" squish-macos-arm64 ../dist/ ../config/plugin.json ../README.md ../LICENSE
33
33
 
34
34
  # Windows x64
35
35
  echo "Building windows-x64..."
36
36
  npx pkg ../dist/index.js --targets node18-win-x64 --output squish-windows-x64.exe
37
- zip "../squish-v${VERSION}-windows-x64.zip" squish-windows-x64.exe ../dist/ ../plugin.json ../README.md ../LICENSE
37
+ zip "../squish-v${VERSION}-windows-x64.zip" squish-windows-x64.exe ../dist/ ../config/plugin.json ../README.md ../LICENSE
38
38
 
39
39
  cd ..
40
40
  rm -rf release-assets
@@ -0,0 +1,85 @@
1
+ #!/bin/bash
2
+ # Install Squish hooks for Claude Code
3
+ # Run from the squish project directory
4
+
5
+ set -e
6
+
7
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
+ SQUISH_DIR="${SQUISH_DIR:-$HOME/.squish}"
9
+ HOOKS_CONFIG="$SCRIPT_DIR/config/hooks/claude-code-hooks.json"
10
+
11
+ echo "Installing Squish hooks for Claude Code..."
12
+
13
+ # Create Squish config directory
14
+ mkdir -p "$SQUISH_DIR"
15
+
16
+ # Copy hook config
17
+ if [ -f "$HOOKS_CONFIG" ]; then
18
+ cp "$HOOKS_CONFIG" "$SQUISH_DIR/hooks-claude-code.json"
19
+ echo "Copied hook config to $SQUISH_DIR/hooks-claude-code.json"
20
+ else
21
+ echo "ERROR: Hook config not found at $HOOKS_CONFIG"
22
+ exit 1
23
+ fi
24
+
25
+ # Create hooks directory
26
+ mkdir -p "$SQUISH_DIR/hooks"
27
+
28
+ # Check for Claude Code settings file
29
+ SETTINGS_FILE="$HOME/.claude/settings.json"
30
+ HOOKS_DIR="$HOME/.claude/hooks/squish"
31
+
32
+ if [ -f "$SETTINGS_FILE" ]; then
33
+ echo ""
34
+ echo "Found Claude Code settings at $SETTINGS_FILE"
35
+ echo ""
36
+ echo "To enable hooks, add this to your settings.json:"
37
+ echo ""
38
+ cat << 'SETTINGS_JSON'
39
+ {
40
+ "hooks": {
41
+ "SessionStart": [
42
+ { "matcher": "startup", "hooks": [{ "type": "command", "command": "squish", "args": ["hooks", "session-start", "--agent", "claude-code", "--mode", "startup"], "matcher": "startup" }] },
43
+ { "matcher": "resume", "hooks": [{ "type": "command", "command": "squish", "args": ["hooks", "session-start", "--agent", "claude-code", "--mode", "resume"], "matcher": "resume" }] },
44
+ { "matcher": "compact", "hooks": [{ "type": "command", "command": "squish", "args": ["hooks", "session-start", "--agent", "claude-code", "--mode", "compact"], "matcher": "compact" }] }
45
+ ],
46
+ "PostToolUse": [
47
+ { "hooks": [{ "type": "command", "command": "squish", "args": ["hooks", "post-tool-use", "--agent", "claude-code"], "timeout": 5 }] }
48
+ ],
49
+ "SessionEnd": [
50
+ { "hooks": [{ "type": "command", "command": "squish", "args": ["hooks", "session-end", "--agent", "claude-code"], "timeout": 10 }] }
51
+ ],
52
+ "PreCompact": [
53
+ { "matcher": "auto", "hooks": [{ "type": "command", "command": "squish", "args": ["hooks", "pre-compact", "--agent", "claude-code"], "matcher": "auto" }] }
54
+ ]
55
+ }
56
+ }
57
+ SETTINGS_JSON
58
+
59
+ echo ""
60
+ echo "OR use the simplified approach - add MCP servers for memory:"
61
+ echo ""
62
+ cat << 'MCP_CONFIG'
63
+ {
64
+ "mcpServers": {
65
+ "squish-memory": {
66
+ "command": "squish",
67
+ "args": ["run", "mcp"]
68
+ }
69
+ }
70
+ }
71
+ MCP_CONFIG
72
+ else
73
+ echo ""
74
+ echo "WARNING: Claude Code settings file not found at $SETTINGS_FILE"
75
+ echo "Install Claude Code first, then rerun this script"
76
+ fi
77
+
78
+ echo ""
79
+ echo "Installation complete!"
80
+ echo ""
81
+ echo "Next steps:"
82
+ echo "1. Add MCP server config to your .claude.json or settings.json"
83
+ echo "2. Restart Claude Code"
84
+ echo "3. Run 'squish health' to verify"
85
+ echo ""