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
@@ -0,0 +1,177 @@
1
+ import { eq, sql } from 'drizzle-orm';
2
+ import { getDb } from '../../db/index.js';
3
+ import { getSchema } from '../../db/schema.js';
4
+ import { createDatabaseClient } from '../storage/database.js';
5
+ import { requireProject } from '../projects.js';
6
+ export const DEFAULT_CONTEXT_CONFIG = {
7
+ maxTokens: 128000,
8
+ warningThreshold: 0.80,
9
+ criticalThreshold: 0.95,
10
+ };
11
+ export function estimateTokens(content) {
12
+ if (!content)
13
+ return 0;
14
+ return Math.ceil(content.length / 4);
15
+ }
16
+ export async function getTokenUsage(projectPath) {
17
+ const project = await requireProject(projectPath);
18
+ const projectId = project.id;
19
+ const db = createDatabaseClient(await getDb());
20
+ const schema = await getSchema();
21
+ const memories = schema.memories;
22
+ const coreMemory = schema.coreMemory;
23
+ const coreMemoryRows = await db
24
+ .select()
25
+ .from(coreMemory)
26
+ .where(eq(coreMemory.projectId, projectId));
27
+ let coreMemoryTokens = 0;
28
+ for (const row of coreMemoryRows) {
29
+ coreMemoryTokens += row.tokensEstimate || estimateTokens(row.content || '');
30
+ }
31
+ const memoryRows = await db
32
+ .select({
33
+ tokens: memories.tokensEstimate,
34
+ content: memories.content,
35
+ })
36
+ .from(memories)
37
+ .where(eq(memories.projectId, projectId));
38
+ let memoriesTokens = 0;
39
+ for (const row of memoryRows) {
40
+ memoriesTokens += row.tokens || estimateTokens(row.content || '');
41
+ }
42
+ const totalTokens = coreMemoryTokens + memoriesTokens;
43
+ const config = DEFAULT_CONTEXT_CONFIG;
44
+ const usagePercent = (totalTokens / config.maxTokens) * 100;
45
+ const remainingTokens = Math.max(0, config.maxTokens - totalTokens);
46
+ let status = 'ok';
47
+ if (usagePercent >= config.criticalThreshold * 100) {
48
+ status = 'critical';
49
+ }
50
+ else if (usagePercent >= config.warningThreshold * 100) {
51
+ status = 'warning';
52
+ }
53
+ return {
54
+ coreMemoryTokens,
55
+ memoriesTokens,
56
+ totalTokens,
57
+ maxTokens: config.maxTokens,
58
+ usagePercent,
59
+ status,
60
+ remainingTokens,
61
+ };
62
+ }
63
+ export async function checkContextLimit(projectPath, additionalTokens) {
64
+ const stats = await getTokenUsage(projectPath);
65
+ const projectedTotal = stats.totalTokens + additionalTokens;
66
+ const projectedPercent = (projectedTotal / stats.maxTokens) * 100;
67
+ if (projectedPercent >= DEFAULT_CONTEXT_CONFIG.criticalThreshold * 100) {
68
+ return {
69
+ ok: false,
70
+ warning: `CRITICAL: Adding ${additionalTokens} tokens would exceed ${(DEFAULT_CONTEXT_CONFIG.criticalThreshold * 100).toFixed(0)}% of context limit (${projectedPercent.toFixed(1)}% projected). Consider optimizing first.`,
71
+ stats,
72
+ };
73
+ }
74
+ if (projectedPercent >= DEFAULT_CONTEXT_CONFIG.warningThreshold * 100) {
75
+ return {
76
+ ok: true,
77
+ warning: `WARNING: Adding ${additionalTokens} tokens would reach ${(projectedPercent.toFixed(1))}% of context limit. Consider optimizing soon.`,
78
+ stats,
79
+ };
80
+ }
81
+ return { ok: true, stats };
82
+ }
83
+ export async function getOptimizationSuggestions(projectPath) {
84
+ const project = await requireProject(projectPath);
85
+ const projectId = project.id;
86
+ const db = createDatabaseClient(await getDb());
87
+ const schema = await getSchema();
88
+ const memories = schema.memories;
89
+ const candidates = await db
90
+ .select({
91
+ id: memories.id,
92
+ type: memories.type,
93
+ content: memories.content,
94
+ tokens: memories.tokensEstimate,
95
+ importanceScore: memories.importanceScore,
96
+ accessCount: memories.accessCount,
97
+ createdAt: memories.createdAt,
98
+ isPinned: memories.isPinned,
99
+ isProtected: memories.isProtected,
100
+ })
101
+ .from(memories)
102
+ .where(eq(memories.projectId, projectId))
103
+ .orderBy(sql `(importance_score * 0.4 + (100 - COALESCE(access_count, 0)) * 0.3 + (strftime('%s', 'now') - created_at / 1000) / 86400 * 0.3) ASC`)
104
+ .limit(20);
105
+ const suggestions = [];
106
+ for (const mem of candidates) {
107
+ const tokens = mem.tokens || estimateTokens(mem.content || '');
108
+ const contentPreview = mem.content?.substring(0, 100) + '...';
109
+ const isPinned = mem.isPinned === 1 || mem.isPinned === true;
110
+ const isProtected = mem.isProtected === 1 || mem.isProtected === true;
111
+ const accessCount = mem.accessCount || 0;
112
+ const importanceScore = mem.importanceScore || 50;
113
+ if (isPinned || isProtected) {
114
+ continue;
115
+ }
116
+ if (importanceScore < 30 && accessCount < 3) {
117
+ suggestions.push({
118
+ type: 'drop',
119
+ memoryId: mem.id,
120
+ memoryType: mem.type,
121
+ contentPreview,
122
+ tokens,
123
+ reason: `Low importance (${importanceScore}) and rarely accessed (${accessCount} times)`,
124
+ priority: 1,
125
+ });
126
+ }
127
+ else if (importanceScore < 50 && tokens > 500) {
128
+ suggestions.push({
129
+ type: 'summarize',
130
+ memoryId: mem.id,
131
+ memoryType: mem.type,
132
+ contentPreview,
133
+ tokens,
134
+ reason: `Large memory (${tokens} tokens) with moderate importance`,
135
+ priority: 2,
136
+ });
137
+ }
138
+ else if (tokens > 1000) {
139
+ suggestions.push({
140
+ type: 'consolidate',
141
+ memoryId: mem.id,
142
+ memoryType: mem.type,
143
+ contentPreview,
144
+ tokens,
145
+ reason: `Very large memory (${tokens} tokens) - candidate for consolidation`,
146
+ priority: 3,
147
+ });
148
+ }
149
+ }
150
+ return suggestions.sort((a, b) => a.priority - b.priority).slice(0, 10);
151
+ }
152
+ export async function getContextWindowStatus(projectPath) {
153
+ const project = await requireProject(projectPath);
154
+ const projectId = project.id;
155
+ const db = createDatabaseClient(await getDb());
156
+ const schema = await getSchema();
157
+ const [usage, suggestions] = await Promise.all([
158
+ getTokenUsage(projectPath),
159
+ getOptimizationSuggestions(projectPath),
160
+ ]);
161
+ const memoryCount = await db
162
+ .select({ count: sql `COUNT(*)` })
163
+ .from(schema.memories)
164
+ .where(eq(schema.memories.projectId, projectId));
165
+ const coreMemorySections = await db
166
+ .select({ count: sql `COUNT(*)` })
167
+ .from(schema.coreMemory)
168
+ .where(eq(schema.coreMemory.projectId, projectId));
169
+ return {
170
+ config: DEFAULT_CONTEXT_CONFIG,
171
+ usage,
172
+ suggestions,
173
+ memoryCount: memoryCount[0]?.count || 0,
174
+ coreMemorySections: coreMemorySections[0]?.count || 0,
175
+ };
176
+ }
177
+ //# sourceMappingURL=context-window.js.map
@@ -0,0 +1,22 @@
1
+ import { requireProject } from '../projects.js';
2
+ import { getRecent } from '../memory/memories.js';
3
+ import { getObservations } from '../ingestion/learnings.js';
4
+ import { getEntitiesForProject } from '../search/entities.js';
5
+ import { validateLimit } from '../lib/validation.js';
6
+ export async function getProjectContext(input) {
7
+ const project = await requireProject(input.project);
8
+ const include = input.include ?? ['memories', 'observations'];
9
+ const limit = validateLimit(input.limit, 10, 1, 100);
10
+ const result = { project };
11
+ if (include.includes('memories')) {
12
+ result.memories = await getRecent(project.path, limit);
13
+ }
14
+ if (include.includes('observations')) {
15
+ result.observations = await getObservations(project.path, limit);
16
+ }
17
+ if (include.includes('entities')) {
18
+ result.entities = await getEntitiesForProject(project.path, limit);
19
+ }
20
+ return result;
21
+ }
22
+ //# sourceMappingURL=context.js.map
@@ -1,5 +1,5 @@
1
1
  import { MultimodalInput } from './embeddings/google-multimodal.js';
2
- export type EmbeddingProvider = 'local' | 'openai' | 'ollama' | 'google' | 'none' | 'auto';
2
+ export type EmbeddingProvider = 'local' | 'openai' | 'ollama' | 'lmstudio' | 'google' | 'none' | 'auto';
3
3
  export declare function getEmbedding(input: string | MultimodalInput): Promise<number[] | null>;
4
4
  /**
5
5
  * Get embeddings for multiple inputs in parallel batches
@@ -125,6 +125,9 @@ export async function getEmbedding(input) {
125
125
  else if (provider === 'ollama') {
126
126
  result = await getOllamaEmbedding(textInput);
127
127
  }
128
+ else if (provider === 'lmstudio') {
129
+ result = await getLmStudioEmbedding(textInput);
130
+ }
128
131
  else if (provider === 'local') {
129
132
  result = getLocalEmbedding(textInput);
130
133
  }
@@ -136,6 +139,9 @@ export async function getEmbedding(input) {
136
139
  if (!result && config.ollamaUrl) {
137
140
  result = await getOllamaEmbedding(textInput);
138
141
  }
142
+ if (!result && config.lmStudioUrl) {
143
+ result = await getLmStudioEmbedding(textInput);
144
+ }
139
145
  if (!result) {
140
146
  result = getLocalEmbedding(textInput);
141
147
  }
@@ -306,7 +312,7 @@ async function getOllamaEmbedding(input) {
306
312
  method: 'POST',
307
313
  headers: { 'Content-Type': 'application/json' },
308
314
  body: JSON.stringify({
309
- model: config.ollamaEmbeddingModel,
315
+ model: config.ollamaEmbeddingModel || 'nomic-embed-text',
310
316
  prompt: input,
311
317
  }),
312
318
  }, config.ollamaTimeoutMs);
@@ -323,13 +329,37 @@ async function getOllamaEmbedding(input) {
323
329
  return null; // Return null to allow fallback
324
330
  }
325
331
  }
332
+ // LM Studio uses OpenAI-compatible API
333
+ async function getLmStudioEmbedding(input) {
334
+ try {
335
+ const response = await fetchWithRetryAndTimeout(`${config.lmStudioUrl}/v1/embeddings`, {
336
+ method: 'POST',
337
+ headers: { 'Content-Type': 'application/json' },
338
+ body: JSON.stringify({
339
+ model: config.lmStudioEmbeddingModel || 'text-embedding-nomic-embed-text-v1.5',
340
+ input: input,
341
+ }),
342
+ }, config.ollamaTimeoutMs); // Reuse Ollama timeout
343
+ if (!response.ok) {
344
+ const message = await response.text();
345
+ logger.warn(`LM Studio embeddings failed: ${response.status} ${message}`);
346
+ return null; // Return null to allow fallback
347
+ }
348
+ const payload = await response.json();
349
+ return payload.data?.[0]?.embedding ?? null;
350
+ }
351
+ catch (error) {
352
+ logger.warn('LM Studio embeddings error:', { error: error });
353
+ return null; // Return null to allow fallback
354
+ }
355
+ }
326
356
  /**
327
357
  * Check health of all configured embedding providers
328
358
  * Returns availability and latency for each provider
329
359
  */
330
360
  export async function checkEmbeddingProviderHealth() {
331
361
  const results = new Map();
332
- const providers = ['local', 'openai', 'ollama', 'google', 'none', 'auto'];
362
+ const providers = ['local', 'openai', 'ollama', 'lmstudio', 'google', 'none', 'auto'];
333
363
  // Test local provider (always available)
334
364
  results.set('local', { available: true, latencyMs: 0 });
335
365
  // Test OpenAI if configured
@@ -376,6 +406,28 @@ export async function checkEmbeddingProviderHealth() {
376
406
  else {
377
407
  results.set('ollama', { available: false, error: 'Not configured' });
378
408
  }
409
+ // Test LM Studio if configured
410
+ if (config.lmStudioUrl) {
411
+ const start = Date.now();
412
+ try {
413
+ const testInput = 'health check';
414
+ const embedding = await withRetry(() => withTimeout(getLmStudioEmbedding(testInput), config.ollamaTimeoutMs), config.embeddingsMaxRetries, config.embeddingsRetryDelayMs);
415
+ const latency = Date.now() - start;
416
+ results.set('lmstudio', {
417
+ available: embedding !== null && embedding.length > 0,
418
+ latencyMs: latency
419
+ });
420
+ }
421
+ catch (error) {
422
+ results.set('lmstudio', {
423
+ available: false,
424
+ error: error.message
425
+ });
426
+ }
427
+ }
428
+ else {
429
+ results.set('lmstudio', { available: false, error: 'Not configured' });
430
+ }
379
431
  // Test Google if configured
380
432
  if (config.googleCloudApiKey || config.googleCloudProject) {
381
433
  const start = Date.now();
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Unified Error Handling System for Squish
3
+ * Provides standardized error handling across CLI, Web API, MCP server, and algorithm handlers
4
+ */
5
+ import { isDatabaseUnavailableError } from './lib/utils.js';
6
+ export { isDatabaseUnavailableError };
7
+ /**
8
+ * Wraps database operations with standardized error handling
9
+ */
10
+ export declare function withDbErrorHandling<T>(operation: () => Promise<T>, context: string): Promise<T>;
11
+ /**
12
+ * Formats errors for Web API responses
13
+ */
14
+ export declare function formatApiError(error: any, defaultStatus?: number): {
15
+ status: number;
16
+ response: {
17
+ status: string;
18
+ message: string;
19
+ };
20
+ };
21
+ /**
22
+ * Formats errors for MCP tool responses
23
+ */
24
+ export declare function formatMcpError(error: any, context?: string): never;
25
+ /**
26
+ * Formats errors for CLI commands
27
+ */
28
+ export declare function formatCliError(error: any, exitCode?: number): never;
29
+ /**
30
+ * Formats errors for algorithm handlers
31
+ */
32
+ export declare function formatAlgorithmError(error: any, context?: string): {
33
+ ok: false;
34
+ error: string;
35
+ };
36
+ /**
37
+ * Formats successful responses for algorithm handlers.
38
+ *
39
+ * @param data - The success data to return
40
+ * @param message - Optional success message
41
+ * @returns Object with ok: true, optional message, and data
42
+ */
43
+ export declare function formatAlgorithmSuccess<T>(data: T, message?: string): {
44
+ ok: true;
45
+ data: T;
46
+ message?: string;
47
+ };
48
+ /**
49
+ * Error thrown when validation fails
50
+ */
51
+ export declare class ValidationError extends Error {
52
+ field?: string | undefined;
53
+ constructor(message: string, field?: string | undefined);
54
+ }
55
+ /**
56
+ * Error thrown when a requested resource is not found.
57
+ * Used for missing memories, projects, etc.
58
+ */
59
+ export declare class NotFoundError extends Error {
60
+ resource?: string | undefined;
61
+ constructor(message: string, resource?: string | undefined);
62
+ }
63
+ //# sourceMappingURL=error-handling.d.ts.map
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Unified Error Handling System for Squish
3
+ * Provides standardized error handling across CLI, Web API, MCP server, and algorithm handlers
4
+ */
5
+ import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
6
+ import { isDatabaseUnavailableError } from './lib/utils.js';
7
+ export { isDatabaseUnavailableError };
8
+ // Database operation wrapper
9
+ /**
10
+ * Wraps database operations with standardized error handling
11
+ */
12
+ export async function withDbErrorHandling(operation, context) {
13
+ try {
14
+ return await operation();
15
+ }
16
+ catch (dbError) {
17
+ if (isDatabaseUnavailableError(dbError)) {
18
+ throw new Error(`Database unavailable: ${context}. Please check your database connection.`);
19
+ }
20
+ throw dbError;
21
+ }
22
+ }
23
+ // API Response Formatters
24
+ /**
25
+ * Formats errors for Web API responses
26
+ */
27
+ export function formatApiError(error, defaultStatus = 500) {
28
+ let message;
29
+ if (typeof error === 'string') {
30
+ message = error;
31
+ }
32
+ else if (error instanceof Error) {
33
+ message = error.message;
34
+ }
35
+ else if (error && typeof error === 'object' && 'message' in error) {
36
+ message = String(error.message);
37
+ }
38
+ else if (error && typeof error === 'object') {
39
+ message = 'Unknown error';
40
+ }
41
+ else {
42
+ message = 'Unknown error';
43
+ }
44
+ // Check if it's a database unavailable error
45
+ if (isDatabaseUnavailableError(error)) {
46
+ return {
47
+ status: 503,
48
+ response: {
49
+ status: 'error',
50
+ message: `Service unavailable: ${message}`
51
+ }
52
+ };
53
+ }
54
+ // Check for custom error classes with status hints
55
+ if (error.status) {
56
+ return {
57
+ status: error.status,
58
+ response: {
59
+ status: 'error',
60
+ message
61
+ }
62
+ };
63
+ }
64
+ return {
65
+ status: defaultStatus,
66
+ response: {
67
+ status: 'error',
68
+ message
69
+ }
70
+ };
71
+ }
72
+ // MCP Error Formatter
73
+ /**
74
+ * Formats errors for MCP tool responses
75
+ */
76
+ export function formatMcpError(error, context) {
77
+ const message = error?.message || error?.toString() || 'Unknown error';
78
+ const fullMessage = context ? `${context}: ${message}` : message;
79
+ // Determine appropriate error code
80
+ let code;
81
+ if (isDatabaseUnavailableError(error)) {
82
+ code = ErrorCode.InternalError; // -32603
83
+ }
84
+ else if (error instanceof ValidationError) {
85
+ code = ErrorCode.InvalidParams; // -32602
86
+ }
87
+ else {
88
+ code = ErrorCode.InternalError;
89
+ }
90
+ throw new McpError(code, fullMessage);
91
+ }
92
+ // CLI Error Formatter
93
+ /**
94
+ * Formats errors for CLI commands
95
+ */
96
+ export function formatCliError(error, exitCode = 1) {
97
+ let message;
98
+ if (typeof error === 'string') {
99
+ message = error;
100
+ }
101
+ else if (error instanceof Error) {
102
+ message = error.message;
103
+ }
104
+ else if (error && typeof error === 'object' && 'message' in error) {
105
+ message = String(error.message);
106
+ }
107
+ else {
108
+ message = 'Unknown error';
109
+ }
110
+ // Output JSON to stdout for CLI consumers
111
+ console.log(JSON.stringify({ ok: false, error: message }, null, 2));
112
+ process.exit(exitCode);
113
+ }
114
+ // Algorithm Handler Formatters
115
+ /**
116
+ * Formats errors for algorithm handlers
117
+ */
118
+ export function formatAlgorithmError(error, context) {
119
+ let message;
120
+ if (typeof error === 'string') {
121
+ message = error;
122
+ }
123
+ else if (error instanceof Error) {
124
+ message = error.message;
125
+ }
126
+ else if (error && typeof error === 'object' && 'message' in error) {
127
+ message = String(error.message);
128
+ }
129
+ else {
130
+ message = 'Unknown error';
131
+ }
132
+ const fullMessage = context ? `${context}: ${message}` : message;
133
+ return { ok: false, error: fullMessage };
134
+ }
135
+ /**
136
+ * Formats successful responses for algorithm handlers.
137
+ *
138
+ * @param data - The success data to return
139
+ * @param message - Optional success message
140
+ * @returns Object with ok: true, optional message, and data
141
+ */
142
+ export function formatAlgorithmSuccess(data, message) {
143
+ const result = { ok: true, data };
144
+ if (message) {
145
+ result.message = message;
146
+ }
147
+ return result;
148
+ }
149
+ // Custom Error Classes
150
+ /**
151
+ * Error thrown when validation fails
152
+ */
153
+ export class ValidationError extends Error {
154
+ field;
155
+ constructor(message, field) {
156
+ super(message);
157
+ this.field = field;
158
+ this.name = 'ValidationError';
159
+ }
160
+ }
161
+ /**
162
+ * Error thrown when a requested resource is not found.
163
+ * Used for missing memories, projects, etc.
164
+ */
165
+ export class NotFoundError extends Error {
166
+ resource;
167
+ constructor(message, resource) {
168
+ super(message);
169
+ this.resource = resource;
170
+ this.name = 'NotFoundError';
171
+ }
172
+ }
173
+ //# sourceMappingURL=error-handling.js.map
@@ -0,0 +1,102 @@
1
+ /**
2
+ * External Folder Memory Manager
3
+ *
4
+ * Wraps QMD to treat an external folder as a secondary memory layer.
5
+ * - Writes hot memories to daily notes (YYYY-MM-DD.md) with frontmatter
6
+ * - Uses QMD to search both Squish DB and external folder
7
+ * - Auto-indexes on mount and write
8
+ *
9
+ * Usage:
10
+ * squish mount /path/to/folder # Enable external memory
11
+ * squish mount status # Show status
12
+ * squish mount unmount # Disable
13
+ */
14
+ import type { MemoryRecord, MemoryType } from '../memory/memories.js';
15
+ export interface ExternalMemoryConfig {
16
+ enabled: boolean;
17
+ path: string;
18
+ }
19
+ export interface ExternalMemoryStatus {
20
+ mounted: boolean;
21
+ path: string | null;
22
+ qmdIndexed: boolean;
23
+ memoryCount: number;
24
+ lastIndexed: string | null;
25
+ }
26
+ export interface MemoryAsMarkdown {
27
+ id: string;
28
+ type: MemoryType;
29
+ content: string;
30
+ tags: string[];
31
+ createdAt: string;
32
+ confidence?: string;
33
+ projectId?: string | null;
34
+ }
35
+ /**
36
+ * External Folder Memory Manager class
37
+ */
38
+ export declare class ExternalFolderMemory {
39
+ private mountedPath;
40
+ /**
41
+ * Check if external memory is enabled and mounted
42
+ */
43
+ isEnabled(): boolean;
44
+ /**
45
+ * Get the mounted path
46
+ */
47
+ getPath(): string | null;
48
+ /**
49
+ * Mount external memory at a path
50
+ * Creates folder if needed, initializes structure
51
+ */
52
+ mount(path: string): Promise<{
53
+ success: boolean;
54
+ error?: string;
55
+ }>;
56
+ /**
57
+ * Unmount external memory
58
+ */
59
+ unmount(): {
60
+ success: boolean;
61
+ };
62
+ /**
63
+ * Ensure QMD indexes the external folder
64
+ */
65
+ ensureIndexed(folderPath?: string): Promise<boolean>;
66
+ /**
67
+ * Write a memory to the external folder (daily note)
68
+ */
69
+ writeMemory(memory: MemoryAsMarkdown): Promise<{
70
+ success: boolean;
71
+ error?: string;
72
+ }>;
73
+ /**
74
+ * Trigger background re-index via QMD
75
+ */
76
+ private triggerReindex;
77
+ /**
78
+ * Get current status of external memory
79
+ */
80
+ getStatus(): Promise<ExternalMemoryStatus>;
81
+ /**
82
+ * Check if folder is indexed by QMD
83
+ */
84
+ private checkQMDIndexed;
85
+ /**
86
+ * Convert a MemoryRecord to MemoryAsMarkdown format
87
+ */
88
+ toMarkdownFormat(memory: MemoryRecord): MemoryAsMarkdown;
89
+ }
90
+ /**
91
+ * Get the singleton ExternalFolderMemory instance
92
+ */
93
+ export declare function getExternalMemory(): ExternalFolderMemory;
94
+ /**
95
+ * Check if external memory is enabled
96
+ */
97
+ export declare function isExternalMemoryEnabled(): boolean;
98
+ /**
99
+ * Get external memory path
100
+ */
101
+ export declare function getExternalMemoryPath(): string | null;
102
+ //# sourceMappingURL=index.d.ts.map