@maadb/core 0.0.1 → 0.7.9

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 (407) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +371 -3
  3. package/dist/architect.d.ts +2 -0
  4. package/dist/architect.d.ts.map +1 -0
  5. package/dist/architect.js +273 -0
  6. package/dist/architect.js.map +1 -0
  7. package/dist/auth/resolve.d.ts +36 -0
  8. package/dist/auth/resolve.d.ts.map +1 -0
  9. package/dist/auth/resolve.js +77 -0
  10. package/dist/auth/resolve.js.map +1 -0
  11. package/dist/auth/token-store.d.ts +82 -0
  12. package/dist/auth/token-store.d.ts.map +1 -0
  13. package/dist/auth/token-store.js +464 -0
  14. package/dist/auth/token-store.js.map +1 -0
  15. package/dist/auth/types.d.ts +75 -0
  16. package/dist/auth/types.d.ts.map +1 -0
  17. package/dist/auth/types.js +15 -0
  18. package/dist/auth/types.js.map +1 -0
  19. package/dist/backend/adapter.d.ts +57 -0
  20. package/dist/backend/adapter.d.ts.map +1 -0
  21. package/dist/backend/adapter.js +6 -0
  22. package/dist/backend/adapter.js.map +1 -0
  23. package/dist/backend/index.d.ts +3 -0
  24. package/dist/backend/index.d.ts.map +1 -0
  25. package/dist/backend/index.js +2 -0
  26. package/dist/backend/index.js.map +1 -0
  27. package/dist/backend/sqlite/index.d.ts +63 -0
  28. package/dist/backend/sqlite/index.d.ts.map +1 -0
  29. package/dist/backend/sqlite/index.js +521 -0
  30. package/dist/backend/sqlite/index.js.map +1 -0
  31. package/dist/backend/sqlite/schema.d.ts +2 -0
  32. package/dist/backend/sqlite/schema.d.ts.map +1 -0
  33. package/dist/backend/sqlite/schema.js +88 -0
  34. package/dist/backend/sqlite/schema.js.map +1 -0
  35. package/dist/claude-md.d.ts +2 -0
  36. package/dist/claude-md.d.ts.map +1 -0
  37. package/dist/claude-md.js +97 -0
  38. package/dist/claude-md.js.map +1 -0
  39. package/dist/cli/commands/audit.d.ts +4 -0
  40. package/dist/cli/commands/audit.d.ts.map +1 -0
  41. package/dist/cli/commands/audit.js +39 -0
  42. package/dist/cli/commands/audit.js.map +1 -0
  43. package/dist/cli/commands/auth.d.ts +8 -0
  44. package/dist/cli/commands/auth.d.ts.map +1 -0
  45. package/dist/cli/commands/auth.js +242 -0
  46. package/dist/cli/commands/auth.js.map +1 -0
  47. package/dist/cli/commands/discover.d.ts +5 -0
  48. package/dist/cli/commands/discover.d.ts.map +1 -0
  49. package/dist/cli/commands/discover.js +48 -0
  50. package/dist/cli/commands/discover.js.map +1 -0
  51. package/dist/cli/commands/maintain.d.ts +6 -0
  52. package/dist/cli/commands/maintain.d.ts.map +1 -0
  53. package/dist/cli/commands/maintain.js +168 -0
  54. package/dist/cli/commands/maintain.js.map +1 -0
  55. package/dist/cli/commands/read.d.ts +7 -0
  56. package/dist/cli/commands/read.d.ts.map +1 -0
  57. package/dist/cli/commands/read.js +139 -0
  58. package/dist/cli/commands/read.js.map +1 -0
  59. package/dist/cli/commands/write.d.ts +4 -0
  60. package/dist/cli/commands/write.d.ts.map +1 -0
  61. package/dist/cli/commands/write.js +99 -0
  62. package/dist/cli/commands/write.js.map +1 -0
  63. package/dist/cli/helpers.d.ts +8 -0
  64. package/dist/cli/helpers.d.ts.map +1 -0
  65. package/dist/cli/helpers.js +17 -0
  66. package/dist/cli/helpers.js.map +1 -0
  67. package/dist/cli/index.d.ts +3 -0
  68. package/dist/cli/index.d.ts.map +1 -0
  69. package/dist/cli/index.js +296 -0
  70. package/dist/cli/index.js.map +1 -0
  71. package/dist/cli.d.ts +3 -0
  72. package/dist/cli.d.ts.map +1 -0
  73. package/dist/cli.js +7 -0
  74. package/dist/cli.js.map +1 -0
  75. package/dist/engine/audit.d.ts +15 -0
  76. package/dist/engine/audit.d.ts.map +1 -0
  77. package/dist/engine/audit.js +42 -0
  78. package/dist/engine/audit.js.map +1 -0
  79. package/dist/engine/composites.d.ts +6 -0
  80. package/dist/engine/composites.d.ts.map +1 -0
  81. package/dist/engine/composites.js +102 -0
  82. package/dist/engine/composites.js.map +1 -0
  83. package/dist/engine/context.d.ts +47 -0
  84. package/dist/engine/context.d.ts.map +1 -0
  85. package/dist/engine/context.js +55 -0
  86. package/dist/engine/context.js.map +1 -0
  87. package/dist/engine/docid-safe.d.ts +8 -0
  88. package/dist/engine/docid-safe.d.ts.map +1 -0
  89. package/dist/engine/docid-safe.js +0 -0
  90. package/dist/engine/docid-safe.js.map +1 -0
  91. package/dist/engine/helpers.d.ts +8 -0
  92. package/dist/engine/helpers.d.ts.map +1 -0
  93. package/dist/engine/helpers.js +102 -0
  94. package/dist/engine/helpers.js.map +1 -0
  95. package/dist/engine/index.d.ts +209 -0
  96. package/dist/engine/index.d.ts.map +1 -0
  97. package/dist/engine/index.js +489 -0
  98. package/dist/engine/index.js.map +1 -0
  99. package/dist/engine/indexing.d.ts +14 -0
  100. package/dist/engine/indexing.d.ts.map +1 -0
  101. package/dist/engine/indexing.js +225 -0
  102. package/dist/engine/indexing.js.map +1 -0
  103. package/dist/engine/journal.d.ts +32 -0
  104. package/dist/engine/journal.d.ts.map +1 -0
  105. package/dist/engine/journal.js +111 -0
  106. package/dist/engine/journal.js.map +1 -0
  107. package/dist/engine/logger.d.ts +19 -0
  108. package/dist/engine/logger.d.ts.map +1 -0
  109. package/dist/engine/logger.js +40 -0
  110. package/dist/engine/logger.js.map +1 -0
  111. package/dist/engine/maintenance.d.ts +15 -0
  112. package/dist/engine/maintenance.d.ts.map +1 -0
  113. package/dist/engine/maintenance.js +87 -0
  114. package/dist/engine/maintenance.js.map +1 -0
  115. package/dist/engine/mutex.d.ts +24 -0
  116. package/dist/engine/mutex.d.ts.map +1 -0
  117. package/dist/engine/mutex.js +50 -0
  118. package/dist/engine/mutex.js.map +1 -0
  119. package/dist/engine/pathguard.d.ts +16 -0
  120. package/dist/engine/pathguard.d.ts.map +1 -0
  121. package/dist/engine/pathguard.js +41 -0
  122. package/dist/engine/pathguard.js.map +1 -0
  123. package/dist/engine/reads.d.ts +24 -0
  124. package/dist/engine/reads.d.ts.map +1 -0
  125. package/dist/engine/reads.js +701 -0
  126. package/dist/engine/reads.js.map +1 -0
  127. package/dist/engine/types.d.ts +350 -0
  128. package/dist/engine/types.d.ts.map +1 -0
  129. package/dist/engine/types.js +5 -0
  130. package/dist/engine/types.js.map +1 -0
  131. package/dist/engine/writes.d.ts +10 -0
  132. package/dist/engine/writes.d.ts.map +1 -0
  133. package/dist/engine/writes.js +606 -0
  134. package/dist/engine/writes.js.map +1 -0
  135. package/dist/engine.d.ts +3 -0
  136. package/dist/engine.d.ts.map +1 -0
  137. package/dist/engine.js +6 -0
  138. package/dist/engine.js.map +1 -0
  139. package/dist/errors.d.ts +20 -0
  140. package/dist/errors.d.ts.map +1 -0
  141. package/dist/errors.js +17 -0
  142. package/dist/errors.js.map +1 -0
  143. package/dist/extractor/fields.d.ts +3 -0
  144. package/dist/extractor/fields.d.ts.map +1 -0
  145. package/dist/extractor/fields.js +58 -0
  146. package/dist/extractor/fields.js.map +1 -0
  147. package/dist/extractor/index.d.ts +7 -0
  148. package/dist/extractor/index.d.ts.map +1 -0
  149. package/dist/extractor/index.js +22 -0
  150. package/dist/extractor/index.js.map +1 -0
  151. package/dist/extractor/normalizers.d.ts +22 -0
  152. package/dist/extractor/normalizers.d.ts.map +1 -0
  153. package/dist/extractor/normalizers.js +250 -0
  154. package/dist/extractor/normalizers.js.map +1 -0
  155. package/dist/extractor/objects.d.ts +3 -0
  156. package/dist/extractor/objects.d.ts.map +1 -0
  157. package/dist/extractor/objects.js +33 -0
  158. package/dist/extractor/objects.js.map +1 -0
  159. package/dist/extractor/relationships.d.ts +3 -0
  160. package/dist/extractor/relationships.d.ts.map +1 -0
  161. package/dist/extractor/relationships.js +58 -0
  162. package/dist/extractor/relationships.js.map +1 -0
  163. package/dist/git/commit.d.ts +63 -0
  164. package/dist/git/commit.d.ts.map +1 -0
  165. package/dist/git/commit.js +161 -0
  166. package/dist/git/commit.js.map +1 -0
  167. package/dist/git/diff.d.ts +4 -0
  168. package/dist/git/diff.d.ts.map +1 -0
  169. package/dist/git/diff.js +56 -0
  170. package/dist/git/diff.js.map +1 -0
  171. package/dist/git/index.d.ts +41 -0
  172. package/dist/git/index.d.ts.map +1 -0
  173. package/dist/git/index.js +86 -0
  174. package/dist/git/index.js.map +1 -0
  175. package/dist/git/log.d.ts +13 -0
  176. package/dist/git/log.d.ts.map +1 -0
  177. package/dist/git/log.js +116 -0
  178. package/dist/git/log.js.map +1 -0
  179. package/dist/git/snapshot.d.ts +4 -0
  180. package/dist/git/snapshot.d.ts.map +1 -0
  181. package/dist/git/snapshot.js +65 -0
  182. package/dist/git/snapshot.js.map +1 -0
  183. package/dist/instance/config.d.ts +19 -0
  184. package/dist/instance/config.d.ts.map +1 -0
  185. package/dist/instance/config.js +107 -0
  186. package/dist/instance/config.js.map +1 -0
  187. package/dist/instance/pool.d.ts +138 -0
  188. package/dist/instance/pool.d.ts.map +1 -0
  189. package/dist/instance/pool.js +335 -0
  190. package/dist/instance/pool.js.map +1 -0
  191. package/dist/instance/session.d.ts +140 -0
  192. package/dist/instance/session.d.ts.map +1 -0
  193. package/dist/instance/session.js +267 -0
  194. package/dist/instance/session.js.map +1 -0
  195. package/dist/logging.d.ts +108 -0
  196. package/dist/logging.d.ts.map +1 -0
  197. package/dist/logging.js +120 -0
  198. package/dist/logging.js.map +1 -0
  199. package/dist/maad-md.d.ts +11 -0
  200. package/dist/maad-md.d.ts.map +1 -0
  201. package/dist/maad-md.js +252 -0
  202. package/dist/maad-md.js.map +1 -0
  203. package/dist/mcp/bulk-cap.d.ts +10 -0
  204. package/dist/mcp/bulk-cap.d.ts.map +1 -0
  205. package/dist/mcp/bulk-cap.js +37 -0
  206. package/dist/mcp/bulk-cap.js.map +1 -0
  207. package/dist/mcp/config.d.ts +18 -0
  208. package/dist/mcp/config.d.ts.map +1 -0
  209. package/dist/mcp/config.js +20 -0
  210. package/dist/mcp/config.js.map +1 -0
  211. package/dist/mcp/ctx.d.ts +17 -0
  212. package/dist/mcp/ctx.d.ts.map +1 -0
  213. package/dist/mcp/ctx.js +7 -0
  214. package/dist/mcp/ctx.js.map +1 -0
  215. package/dist/mcp/guardrails.d.ts +21 -0
  216. package/dist/mcp/guardrails.d.ts.map +1 -0
  217. package/dist/mcp/guardrails.js +39 -0
  218. package/dist/mcp/guardrails.js.map +1 -0
  219. package/dist/mcp/idempotency.d.ts +69 -0
  220. package/dist/mcp/idempotency.d.ts.map +1 -0
  221. package/dist/mcp/idempotency.js +168 -0
  222. package/dist/mcp/idempotency.js.map +1 -0
  223. package/dist/mcp/instance-reload.d.ts +23 -0
  224. package/dist/mcp/instance-reload.d.ts.map +1 -0
  225. package/dist/mcp/instance-reload.js +126 -0
  226. package/dist/mcp/instance-reload.js.map +1 -0
  227. package/dist/mcp/kinds.d.ts +22 -0
  228. package/dist/mcp/kinds.d.ts.map +1 -0
  229. package/dist/mcp/kinds.js +110 -0
  230. package/dist/mcp/kinds.js.map +1 -0
  231. package/dist/mcp/lifecycle.d.ts +8 -0
  232. package/dist/mcp/lifecycle.d.ts.map +1 -0
  233. package/dist/mcp/lifecycle.js +65 -0
  234. package/dist/mcp/lifecycle.js.map +1 -0
  235. package/dist/mcp/notifications.d.ts +87 -0
  236. package/dist/mcp/notifications.d.ts.map +1 -0
  237. package/dist/mcp/notifications.js +154 -0
  238. package/dist/mcp/notifications.js.map +1 -0
  239. package/dist/mcp/query-depth.d.ts +28 -0
  240. package/dist/mcp/query-depth.d.ts.map +1 -0
  241. package/dist/mcp/query-depth.js +43 -0
  242. package/dist/mcp/query-depth.js.map +1 -0
  243. package/dist/mcp/rate-limit.d.ts +60 -0
  244. package/dist/mcp/rate-limit.d.ts.map +1 -0
  245. package/dist/mcp/rate-limit.js +203 -0
  246. package/dist/mcp/rate-limit.js.map +1 -0
  247. package/dist/mcp/reload-signal.d.ts +13 -0
  248. package/dist/mcp/reload-signal.d.ts.map +1 -0
  249. package/dist/mcp/reload-signal.js +68 -0
  250. package/dist/mcp/reload-signal.js.map +1 -0
  251. package/dist/mcp/response.d.ts +109 -0
  252. package/dist/mcp/response.d.ts.map +1 -0
  253. package/dist/mcp/response.js +132 -0
  254. package/dist/mcp/response.js.map +1 -0
  255. package/dist/mcp/roles.d.ts +7 -0
  256. package/dist/mcp/roles.d.ts.map +1 -0
  257. package/dist/mcp/roles.js +56 -0
  258. package/dist/mcp/roles.js.map +1 -0
  259. package/dist/mcp/server.d.ts +33 -0
  260. package/dist/mcp/server.d.ts.map +1 -0
  261. package/dist/mcp/server.js +242 -0
  262. package/dist/mcp/server.js.map +1 -0
  263. package/dist/mcp/shutdown.d.ts +32 -0
  264. package/dist/mcp/shutdown.d.ts.map +1 -0
  265. package/dist/mcp/shutdown.js +130 -0
  266. package/dist/mcp/shutdown.js.map +1 -0
  267. package/dist/mcp/tools/audit.d.ts +4 -0
  268. package/dist/mcp/tools/audit.d.ts.map +1 -0
  269. package/dist/mcp/tools/audit.js +45 -0
  270. package/dist/mcp/tools/audit.js.map +1 -0
  271. package/dist/mcp/tools/auth.d.ts +4 -0
  272. package/dist/mcp/tools/auth.d.ts.map +1 -0
  273. package/dist/mcp/tools/auth.js +181 -0
  274. package/dist/mcp/tools/auth.js.map +1 -0
  275. package/dist/mcp/tools/discover.d.ts +4 -0
  276. package/dist/mcp/tools/discover.d.ts.map +1 -0
  277. package/dist/mcp/tools/discover.js +83 -0
  278. package/dist/mcp/tools/discover.js.map +1 -0
  279. package/dist/mcp/tools/instance.d.ts +15 -0
  280. package/dist/mcp/tools/instance.d.ts.map +1 -0
  281. package/dist/mcp/tools/instance.js +207 -0
  282. package/dist/mcp/tools/instance.js.map +1 -0
  283. package/dist/mcp/tools/maintain.d.ts +4 -0
  284. package/dist/mcp/tools/maintain.d.ts.map +1 -0
  285. package/dist/mcp/tools/maintain.js +118 -0
  286. package/dist/mcp/tools/maintain.js.map +1 -0
  287. package/dist/mcp/tools/read.d.ts +4 -0
  288. package/dist/mcp/tools/read.d.ts.map +1 -0
  289. package/dist/mcp/tools/read.js +260 -0
  290. package/dist/mcp/tools/read.js.map +1 -0
  291. package/dist/mcp/tools/write.d.ts +4 -0
  292. package/dist/mcp/tools/write.d.ts.map +1 -0
  293. package/dist/mcp/tools/write.js +342 -0
  294. package/dist/mcp/tools/write.js.map +1 -0
  295. package/dist/mcp/transport/auth.d.ts +41 -0
  296. package/dist/mcp/transport/auth.d.ts.map +1 -0
  297. package/dist/mcp/transport/auth.js +115 -0
  298. package/dist/mcp/transport/auth.js.map +1 -0
  299. package/dist/mcp/transport/http.d.ts +62 -0
  300. package/dist/mcp/transport/http.d.ts.map +1 -0
  301. package/dist/mcp/transport/http.js +357 -0
  302. package/dist/mcp/transport/http.js.map +1 -0
  303. package/dist/mcp/transport/pin.d.ts +15 -0
  304. package/dist/mcp/transport/pin.d.ts.map +1 -0
  305. package/dist/mcp/transport/pin.js +71 -0
  306. package/dist/mcp/transport/pin.js.map +1 -0
  307. package/dist/mcp/transport/telemetry.d.ts +79 -0
  308. package/dist/mcp/transport/telemetry.d.ts.map +1 -0
  309. package/dist/mcp/transport/telemetry.js +97 -0
  310. package/dist/mcp/transport/telemetry.js.map +1 -0
  311. package/dist/mcp/with-session.d.ts +26 -0
  312. package/dist/mcp/with-session.d.ts.map +1 -0
  313. package/dist/mcp/with-session.js +275 -0
  314. package/dist/mcp/with-session.js.map +1 -0
  315. package/dist/parser/annotations.d.ts +3 -0
  316. package/dist/parser/annotations.d.ts.map +1 -0
  317. package/dist/parser/annotations.js +41 -0
  318. package/dist/parser/annotations.js.map +1 -0
  319. package/dist/parser/blocks.d.ts +3 -0
  320. package/dist/parser/blocks.d.ts.map +1 -0
  321. package/dist/parser/blocks.js +99 -0
  322. package/dist/parser/blocks.js.map +1 -0
  323. package/dist/parser/frontmatter.d.ts +9 -0
  324. package/dist/parser/frontmatter.d.ts.map +1 -0
  325. package/dist/parser/frontmatter.js +33 -0
  326. package/dist/parser/frontmatter.js.map +1 -0
  327. package/dist/parser/index.d.ts +11 -0
  328. package/dist/parser/index.d.ts.map +1 -0
  329. package/dist/parser/index.js +54 -0
  330. package/dist/parser/index.js.map +1 -0
  331. package/dist/parser/matter.d.ts +3 -0
  332. package/dist/parser/matter.d.ts.map +1 -0
  333. package/dist/parser/matter.js +32 -0
  334. package/dist/parser/matter.js.map +1 -0
  335. package/dist/parser/tags.d.ts +3 -0
  336. package/dist/parser/tags.d.ts.map +1 -0
  337. package/dist/parser/tags.js +32 -0
  338. package/dist/parser/tags.js.map +1 -0
  339. package/dist/parser/verbatim.d.ts +4 -0
  340. package/dist/parser/verbatim.d.ts.map +1 -0
  341. package/dist/parser/verbatim.js +121 -0
  342. package/dist/parser/verbatim.js.map +1 -0
  343. package/dist/parser/yaml-profile.d.ts +4 -0
  344. package/dist/parser/yaml-profile.d.ts.map +1 -0
  345. package/dist/parser/yaml-profile.js +73 -0
  346. package/dist/parser/yaml-profile.js.map +1 -0
  347. package/dist/registry/index.d.ts +2 -0
  348. package/dist/registry/index.d.ts.map +1 -0
  349. package/dist/registry/index.js +2 -0
  350. package/dist/registry/index.js.map +1 -0
  351. package/dist/registry/loader.d.ts +4 -0
  352. package/dist/registry/loader.d.ts.map +1 -0
  353. package/dist/registry/loader.js +147 -0
  354. package/dist/registry/loader.js.map +1 -0
  355. package/dist/registry/types.d.ts +2 -0
  356. package/dist/registry/types.d.ts.map +1 -0
  357. package/dist/registry/types.js +5 -0
  358. package/dist/registry/types.js.map +1 -0
  359. package/dist/scanner.d.ts +57 -0
  360. package/dist/scanner.d.ts.map +1 -0
  361. package/dist/scanner.js +223 -0
  362. package/dist/scanner.js.map +1 -0
  363. package/dist/schema/index.d.ts +3 -0
  364. package/dist/schema/index.d.ts.map +1 -0
  365. package/dist/schema/index.js +3 -0
  366. package/dist/schema/index.js.map +1 -0
  367. package/dist/schema/loader.d.ts +4 -0
  368. package/dist/schema/loader.d.ts.map +1 -0
  369. package/dist/schema/loader.js +303 -0
  370. package/dist/schema/loader.js.map +1 -0
  371. package/dist/schema/precision.d.ts +6 -0
  372. package/dist/schema/precision.d.ts.map +1 -0
  373. package/dist/schema/precision.js +59 -0
  374. package/dist/schema/precision.js.map +1 -0
  375. package/dist/schema/validator.d.ts +21 -0
  376. package/dist/schema/validator.d.ts.map +1 -0
  377. package/dist/schema/validator.js +200 -0
  378. package/dist/schema/validator.js.map +1 -0
  379. package/dist/schema-md.d.ts +8 -0
  380. package/dist/schema-md.d.ts.map +1 -0
  381. package/dist/schema-md.js +98 -0
  382. package/dist/schema-md.js.map +1 -0
  383. package/dist/skill-files.d.ts +3 -0
  384. package/dist/skill-files.d.ts.map +1 -0
  385. package/dist/skill-files.js +362 -0
  386. package/dist/skill-files.js.map +1 -0
  387. package/dist/skills-scaffold.d.ts +10 -0
  388. package/dist/skills-scaffold.d.ts.map +1 -0
  389. package/dist/skills-scaffold.js +52 -0
  390. package/dist/skills-scaffold.js.map +1 -0
  391. package/dist/types.d.ts +309 -0
  392. package/dist/types.d.ts.map +1 -0
  393. package/dist/types.js +111 -0
  394. package/dist/types.js.map +1 -0
  395. package/dist/writer/index.d.ts +7 -0
  396. package/dist/writer/index.d.ts.map +1 -0
  397. package/dist/writer/index.js +32 -0
  398. package/dist/writer/index.js.map +1 -0
  399. package/dist/writer/serializer.d.ts +4 -0
  400. package/dist/writer/serializer.d.ts.map +1 -0
  401. package/dist/writer/serializer.js +103 -0
  402. package/dist/writer/serializer.js.map +1 -0
  403. package/dist/writer/template.d.ts +3 -0
  404. package/dist/writer/template.d.ts.map +1 -0
  405. package/dist/writer/template.js +27 -0
  406. package/dist/writer/template.js.map +1 -0
  407. package/package.json +59 -7
@@ -0,0 +1,335 @@
1
+ // ============================================================================
2
+ // EnginePool — lazy, per-project MaadEngine cache for multi-project routing
3
+ //
4
+ // First call to get(name) initializes the engine and scaffolds _skills/.
5
+ // Subsequent calls return the cached engine. evict(name) is a public seam
6
+ // for future policies (LRU/TTL) layered in 0.9.0; v1 never calls it from
7
+ // inside the pool.
8
+ //
9
+ // reloadInstance(newInstance) swaps the live instance config, applying
10
+ // project additions (lazy — just make them declarable) and removals (evict
11
+ // engines + callbacks for session cancellation). Mutations of existing
12
+ // projects' path/role fail the whole reload with INSTANCE_MUTATION_UNSUPPORTED;
13
+ // that seam opens when the 0.9.0 eviction policy lands.
14
+ // ============================================================================
15
+ import { MaadEngine } from '../engine/index.js';
16
+ import { ensureProjectSkills } from '../skills-scaffold.js';
17
+ import { ok, singleErr } from '../errors.js';
18
+ import { getProject } from './config.js';
19
+ export class EnginePool {
20
+ instance;
21
+ engines = new Map();
22
+ initPromises = new Map();
23
+ reloadInFlight = false;
24
+ stats = {
25
+ lastReloadAt: null,
26
+ reloadsAttempted: 0,
27
+ reloadsSucceeded: 0,
28
+ reloadsFailed: 0,
29
+ projectsAdded: 0,
30
+ projectsRemoved: 0,
31
+ };
32
+ // 0.7.3 — Idle-timeout eviction state. lastTouchedAt is bumped on every
33
+ // successful get(); refcount is bumped by acquire() / decremented by
34
+ // release() so the sweeper never evicts a project with in-flight ops.
35
+ lastTouchedAt = new Map();
36
+ refcount = new Map();
37
+ sweepHandle = null;
38
+ sweepConfig = null;
39
+ evictionStats = {
40
+ evictionsTotal: 0,
41
+ lastEvictionAt: null,
42
+ lastEvictionProjects: [],
43
+ sweepsRun: 0,
44
+ lastSweepAt: null,
45
+ };
46
+ nowFn = Date.now;
47
+ constructor(instance) {
48
+ this.instance = instance;
49
+ }
50
+ /** Test seam — override the time source so sweeper logic is testable. */
51
+ setNowFn(fn) {
52
+ this.nowFn = fn;
53
+ }
54
+ getInstance() {
55
+ return this.instance;
56
+ }
57
+ listProjects() {
58
+ return [...this.instance.projects];
59
+ }
60
+ has(name) {
61
+ return this.engines.has(name);
62
+ }
63
+ reloadStats() {
64
+ return { ...this.stats };
65
+ }
66
+ // Returns the cached engine or initializes it. Concurrent calls for the
67
+ // same project await the same init promise so we don't double-init.
68
+ async get(name) {
69
+ const cached = this.engines.get(name);
70
+ if (cached) {
71
+ this.lastTouchedAt.set(name, this.nowFn());
72
+ return ok(cached);
73
+ }
74
+ const inFlight = this.initPromises.get(name);
75
+ if (inFlight) {
76
+ const r = await inFlight;
77
+ if (r.ok)
78
+ this.lastTouchedAt.set(name, this.nowFn());
79
+ return r;
80
+ }
81
+ const project = getProject(this.instance, name);
82
+ if (!project) {
83
+ return singleErr('PROJECT_UNKNOWN', `Project "${name}" is not declared in instance "${this.instance.name}"`);
84
+ }
85
+ const initPromise = this.initEngine(project);
86
+ this.initPromises.set(name, initPromise);
87
+ try {
88
+ const result = await initPromise;
89
+ if (result.ok) {
90
+ this.engines.set(name, result.value);
91
+ this.lastTouchedAt.set(name, this.nowFn());
92
+ }
93
+ return result;
94
+ }
95
+ finally {
96
+ this.initPromises.delete(name);
97
+ }
98
+ }
99
+ /**
100
+ * 0.7.3 — In-flight refcount. Caller increments before invoking the
101
+ * handler, decrements in finally. The idle sweeper refuses to evict any
102
+ * project with refcount > 0.
103
+ */
104
+ acquire(name) {
105
+ this.refcount.set(name, (this.refcount.get(name) ?? 0) + 1);
106
+ this.lastTouchedAt.set(name, this.nowFn());
107
+ }
108
+ release(name) {
109
+ const cur = this.refcount.get(name) ?? 0;
110
+ if (cur <= 1) {
111
+ this.refcount.delete(name);
112
+ }
113
+ else {
114
+ this.refcount.set(name, cur - 1);
115
+ }
116
+ this.lastTouchedAt.set(name, this.nowFn());
117
+ }
118
+ refcountFor(name) {
119
+ return this.refcount.get(name) ?? 0;
120
+ }
121
+ lastTouchedFor(name) {
122
+ return this.lastTouchedAt.get(name) ?? null;
123
+ }
124
+ async initEngine(project) {
125
+ const engine = new MaadEngine();
126
+ const initResult = await engine.init(project.path);
127
+ if (!initResult.ok)
128
+ return initResult;
129
+ ensureProjectSkills(project.path);
130
+ return ok(engine);
131
+ }
132
+ // Public eviction seam. 0.7.3 — also called by the idle sweeper. Closes
133
+ // SQLite cleanly before removing. Refcount-protected callers should check
134
+ // refcount before calling; this method is unconditional.
135
+ async evict(name) {
136
+ const engine = this.engines.get(name);
137
+ if (!engine)
138
+ return;
139
+ engine.close();
140
+ this.engines.delete(name);
141
+ this.lastTouchedAt.delete(name);
142
+ this.refcount.delete(name);
143
+ }
144
+ /**
145
+ * 0.7.3 — Idle eviction sweep. Returns the names of projects evicted in
146
+ * this sweep. Skips projects with refcount > 0 (in-flight ops) and any
147
+ * project whose lastTouchedAt is missing (defensive — would mean it's not
148
+ * actually loaded). idleTimeoutMs=0 is a no-op (eviction disabled).
149
+ */
150
+ async evictIdle(idleTimeoutMs) {
151
+ this.evictionStats.sweepsRun++;
152
+ this.evictionStats.lastSweepAt = new Date(this.nowFn());
153
+ if (idleTimeoutMs <= 0)
154
+ return [];
155
+ const now = this.nowFn();
156
+ const candidates = [];
157
+ for (const name of this.engines.keys()) {
158
+ if ((this.refcount.get(name) ?? 0) > 0)
159
+ continue;
160
+ const touched = this.lastTouchedAt.get(name);
161
+ if (touched === undefined)
162
+ continue;
163
+ if (now - touched >= idleTimeoutMs)
164
+ candidates.push(name);
165
+ }
166
+ for (const name of candidates)
167
+ await this.evict(name);
168
+ if (candidates.length > 0) {
169
+ this.evictionStats.evictionsTotal += candidates.length;
170
+ this.evictionStats.lastEvictionAt = new Date(now);
171
+ this.evictionStats.lastEvictionProjects = candidates;
172
+ }
173
+ return candidates;
174
+ }
175
+ /**
176
+ * 0.7.3 — Start the background idle sweeper. Idempotent — calling twice
177
+ * replaces the existing schedule. Use stopIdleSweeper() during shutdown.
178
+ * Sweep timer is unref()'d so it never blocks process exit.
179
+ */
180
+ startIdleSweeper(config) {
181
+ this.stopIdleSweeper();
182
+ this.sweepConfig = config;
183
+ if (config.idleTimeoutMs <= 0 || config.sweepIntervalMs <= 0)
184
+ return;
185
+ this.sweepHandle = setInterval(() => {
186
+ void this.evictIdle(config.idleTimeoutMs).catch(() => { });
187
+ }, config.sweepIntervalMs);
188
+ if (typeof this.sweepHandle.unref === 'function')
189
+ this.sweepHandle.unref();
190
+ }
191
+ stopIdleSweeper() {
192
+ if (this.sweepHandle) {
193
+ clearInterval(this.sweepHandle);
194
+ this.sweepHandle = null;
195
+ }
196
+ this.sweepConfig = null;
197
+ }
198
+ evictionStatsSnapshot() {
199
+ return { ...this.evictionStats, lastEvictionProjects: [...this.evictionStats.lastEvictionProjects] };
200
+ }
201
+ idleSweepConfig() {
202
+ return this.sweepConfig ? { ...this.sweepConfig } : null;
203
+ }
204
+ static readIdleSweepEnv(env = process.env) {
205
+ // Default: 30 min idle timeout, 60s sweep interval. Set
206
+ // MAAD_PROJECT_IDLE_TIMEOUT_MS=0 to disable.
207
+ const idleRaw = env.MAAD_PROJECT_IDLE_TIMEOUT_MS;
208
+ const sweepRaw = env.MAAD_PROJECT_SWEEP_INTERVAL_MS;
209
+ const idle = idleRaw !== undefined ? Number.parseInt(idleRaw, 10) : 30 * 60 * 1000;
210
+ const sweep = sweepRaw !== undefined ? Number.parseInt(sweepRaw, 10) : 60 * 1000;
211
+ return {
212
+ idleTimeoutMs: Number.isFinite(idle) && idle >= 0 ? idle : 30 * 60 * 1000,
213
+ sweepIntervalMs: Number.isFinite(sweep) && sweep > 0 ? sweep : 60 * 1000,
214
+ };
215
+ }
216
+ async closeAll() {
217
+ this.stopIdleSweeper();
218
+ for (const [name, engine] of this.engines) {
219
+ try {
220
+ engine.close();
221
+ }
222
+ catch {
223
+ // swallow — shutdown best-effort
224
+ }
225
+ this.engines.delete(name);
226
+ }
227
+ this.lastTouchedAt.clear();
228
+ this.refcount.clear();
229
+ }
230
+ /**
231
+ * Sum of `writeQueueDepth()` across every initialized engine. Used by the
232
+ * shutdown drain loop to know when it's safe to exit. Uninitialized engines
233
+ * contribute 0 and are not lazy-initialized.
234
+ */
235
+ totalWriteQueueDepth() {
236
+ let total = 0;
237
+ for (const engine of this.engines.values()) {
238
+ total += engine.writeQueueDepth();
239
+ }
240
+ return total;
241
+ }
242
+ /**
243
+ * Atomic reload slot — acquired before any I/O (config parse), released
244
+ * after diff + stats are recorded. The orchestrator in
245
+ * `src/mcp/instance-reload.ts` holds this for the lifetime of the reload
246
+ * so concurrent callers fail fast with INSTANCE_RELOAD_IN_PROGRESS instead
247
+ * of racing to swap the instance ref.
248
+ *
249
+ * Returns false if a reload is already in progress or the instance is
250
+ * synthetic (tested separately so the error code can be distinguished).
251
+ */
252
+ tryBeginReload() {
253
+ if (this.instance.source === 'synthetic') {
254
+ return { ok: false, code: 'INSTANCE_RELOAD_SYNTHETIC' };
255
+ }
256
+ if (this.reloadInFlight) {
257
+ return { ok: false, code: 'INSTANCE_RELOAD_IN_PROGRESS' };
258
+ }
259
+ this.reloadInFlight = true;
260
+ this.stats.reloadsAttempted++;
261
+ return { ok: true };
262
+ }
263
+ /**
264
+ * Release the reload slot. Called by the orchestrator in a `finally` so
265
+ * success + failure paths both land here. Updates the success/failure
266
+ * counters + project-diff stats.
267
+ */
268
+ endReload(outcome) {
269
+ if (outcome.ok) {
270
+ this.stats.reloadsSucceeded++;
271
+ this.stats.lastReloadAt = new Date();
272
+ this.stats.projectsAdded += outcome.diff.added.length;
273
+ this.stats.projectsRemoved += outcome.diff.removed.length;
274
+ }
275
+ else {
276
+ this.stats.reloadsFailed++;
277
+ }
278
+ this.reloadInFlight = false;
279
+ }
280
+ /**
281
+ * Apply a parsed instance config: detect mutations (fail-fast, no partial),
282
+ * evict engines for removed projects, swap the internal instance ref.
283
+ * Must be called between `tryBeginReload` and `endReload` — does not manage
284
+ * the reload slot itself.
285
+ *
286
+ * Mutations (same name, different path or role) fail the whole reload with
287
+ * INSTANCE_MUTATION_UNSUPPORTED — no partial apply. The 0.9.0 eviction
288
+ * policy unlocks safe in-place project mutations.
289
+ */
290
+ async applyDiff(newInstance) {
291
+ const oldByName = new Map(this.instance.projects.map(p => [p.name, p]));
292
+ const newByName = new Map(newInstance.projects.map(p => [p.name, p]));
293
+ // Detect mutations first — fail fast before touching state.
294
+ const mutations = [];
295
+ for (const [name, oldP] of oldByName) {
296
+ const newP = newByName.get(name);
297
+ if (!newP)
298
+ continue; // removal, handled below
299
+ if (oldP.path !== newP.path || oldP.role !== newP.role) {
300
+ mutations.push(`"${name}" (${oldP.path}/${oldP.role} → ${newP.path}/${newP.role})`);
301
+ }
302
+ }
303
+ if (mutations.length > 0) {
304
+ return singleErr('INSTANCE_MUTATION_UNSUPPORTED', `Cannot mutate existing projects in place (path/role change). Affected: ${mutations.join(', ')}. Remove and re-add, or wait for 0.9.0 eviction policy.`);
305
+ }
306
+ const added = [];
307
+ const removed = [];
308
+ for (const name of newByName.keys()) {
309
+ if (!oldByName.has(name))
310
+ added.push(name);
311
+ }
312
+ for (const name of oldByName.keys()) {
313
+ if (!newByName.has(name))
314
+ removed.push(name);
315
+ }
316
+ // Evict removed engines. Do this BEFORE swapping the instance ref so
317
+ // getProject() during evict still sees the old config (not strictly
318
+ // required — evict only uses `name` — but preserves invariant).
319
+ for (const name of removed) {
320
+ await this.evict(name);
321
+ }
322
+ // Atomic swap: instance ref + downstream refs (caller's responsibility
323
+ // to propagate to SessionRegistry + InstanceCtx).
324
+ this.instance = newInstance;
325
+ return ok({ added, removed });
326
+ }
327
+ /**
328
+ * Swap the instance config without diff/eviction. Used by the reload
329
+ * orchestrator if it needs to keep downstream refs in sync, or by tests.
330
+ */
331
+ setInstance(newInstance) {
332
+ this.instance = newInstance;
333
+ }
334
+ }
335
+ //# sourceMappingURL=pool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pool.js","sourceRoot":"","sources":["../../src/instance/pool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,140 @@
1
+ import { type Result } from '../errors.js';
2
+ import { type Role } from '../mcp/roles.js';
3
+ import type { InstanceConfig } from './config.js';
4
+ import type { TokenRecord } from '../auth/types.js';
5
+ export type SessionMode = 'single' | 'multi';
6
+ /**
7
+ * How a session was bound to its project(s). Load-bearing for gateway-pinned
8
+ * sessions: rebind-rejection in maad_use_project/maad_use_projects checks
9
+ * `bindingSource === 'gateway_pin'` to distinguish trusted-gateway pins from
10
+ * client-initiated binds. `null` = session exists but is unbound.
11
+ *
12
+ * - `client_tool` — bound by client calling maad_use_project/maad_use_projects
13
+ * - `gateway_pin` — bound by HTTP transport honoring X-Maad-Pin-Project header
14
+ * (multi-tenant hosted deployments, 0.6.8+); irrevocable
15
+ */
16
+ export type BindingSource = 'client_tool' | 'gateway_pin';
17
+ export interface SessionState {
18
+ sessionId: string;
19
+ mode: SessionMode | null;
20
+ activeProject?: string;
21
+ whitelist?: string[];
22
+ effectiveRoles: Map<string, Role>;
23
+ bindingSource: BindingSource | null;
24
+ createdAt: Date;
25
+ lastActivityAt: Date;
26
+ /**
27
+ * Set to true by `cancelByProject` when the session's bound project was
28
+ * removed via instance reload. The next tool call checks this flag and
29
+ * returns SESSION_CANCELLED, then destroys the session. Multi-mode sessions
30
+ * whose whitelist merely contained the removed project are NOT cancelled —
31
+ * their whitelist is pruned via `pruneProjectFromWhitelist` instead.
32
+ */
33
+ cancelled?: boolean;
34
+ /**
35
+ * 0.6.11 — Live notification subscription. Set by `maad_subscribe`,
36
+ * cleared by `maad_unsubscribe` or session destroy. When present, durable
37
+ * writes matching the filter fire `notifications/resources/updated` to
38
+ * this session via its registered notifier (see NotifierRegistry).
39
+ * docTypes null = match all types; project null = match the session's
40
+ * bound project (single-mode) or any project in the whitelist (multi-mode).
41
+ */
42
+ subscription?: {
43
+ docTypes: string[] | null;
44
+ project: string | null;
45
+ createdAt: Date;
46
+ };
47
+ /**
48
+ * 0.7.0 — The token record resolved from the Authorization header at
49
+ * session initialize (HTTP+registry mode only). undefined in stdio /
50
+ * synthetic / legacy modes (which don't have a bearer channel). Used by
51
+ * bindSingle/bindMulti for three-cap effective-role composition, and by
52
+ * audit log identity propagation (P3).
53
+ */
54
+ token?: TokenRecord;
55
+ }
56
+ export interface BindOptions {
57
+ as?: Role;
58
+ /**
59
+ * Who initiated the bind. Defaults to `client_tool`. HTTP transport passes
60
+ * `gateway_pin` when the X-Maad-Pin-Project header was honored at initialize.
61
+ * Once a session is bound with `gateway_pin`, rebind attempts via
62
+ * maad_use_project/maad_use_projects reject with SESSION_PINNED.
63
+ */
64
+ source?: BindingSource;
65
+ }
66
+ export type SessionCloseReason = 'client' | 'transport' | 'idle' | 'shutdown';
67
+ export type SessionCloseHandler = (sessionId: string, reason: SessionCloseReason) => void;
68
+ export type SessionCreateHandler = (sessionId: string) => void;
69
+ export declare class SessionRegistry {
70
+ private instance;
71
+ private sessions;
72
+ private closeHandlers;
73
+ private createHandlers;
74
+ constructor(instance: InstanceConfig);
75
+ /**
76
+ * Swap the live instance config. Called by the instance-reload path after
77
+ * the pool has applied diffs. Does not touch existing sessions — cancellation
78
+ * and whitelist pruning are separate explicit calls.
79
+ */
80
+ setInstance(newInstance: InstanceConfig): void;
81
+ create(sessionId: string): SessionState;
82
+ get(sessionId: string): SessionState | undefined;
83
+ /**
84
+ * Peek without bumping lastActivityAt. Used by the idle sweeper — it must
85
+ * not reset the very activity timestamp it's checking against.
86
+ */
87
+ peek(sessionId: string): SessionState | undefined;
88
+ /**
89
+ * Register a handler fired when a session is destroyed, regardless of cause.
90
+ * Handlers should be cheap (syncronous, no throws); failures in one handler
91
+ * must not block others. Multiple handlers compose in registration order.
92
+ */
93
+ registerCloseHandler(handler: SessionCloseHandler): void;
94
+ /**
95
+ * 0.6.11 — Register a handler fired when a session is created. Used by
96
+ * stdio mode to register a notifier once the synthesized stdio session ID
97
+ * becomes known (HTTP knows the sid earlier via onsessioninitialized).
98
+ * Same best-effort / non-throwing contract as closeHandlers.
99
+ */
100
+ registerCreateHandler(handler: SessionCreateHandler): void;
101
+ destroy(sessionId: string, reason?: SessionCloseReason): void;
102
+ size(): number;
103
+ /**
104
+ * Iterate session snapshots without triggering lastActivityAt updates.
105
+ * Returned array is a copy — safe to mutate during iteration (the sweeper
106
+ * calls destroy() which mutates the underlying map).
107
+ */
108
+ snapshot(): SessionState[];
109
+ /**
110
+ * Mark sessions whose single-mode binding (or gateway-pin) targets the
111
+ * named project as `cancelled`. The next tool call on a cancelled session
112
+ * returns SESSION_CANCELLED and then destroys the session. Multi-mode
113
+ * sessions are NOT cancelled here — use `pruneProjectFromWhitelist` for
114
+ * those. Returns the session IDs that were cancelled.
115
+ */
116
+ cancelByProject(projectName: string): string[];
117
+ /**
118
+ * Remove a project from multi-mode sessions' whitelist + effectiveRoles.
119
+ * Single-mode sessions are not touched (handled by `cancelByProject`).
120
+ * A multi-mode session whose whitelist becomes empty after pruning is
121
+ * marked cancelled — it has no remaining projects to route to.
122
+ * Returns { prunedSessions, cancelledSessions } lists.
123
+ */
124
+ pruneProjectFromWhitelist(projectName: string): {
125
+ prunedSessions: string[];
126
+ cancelledSessions: string[];
127
+ };
128
+ bindSingle(sessionId: string, projectName: string, opts?: BindOptions): Result<SessionState>;
129
+ bindMulti(sessionId: string, projectNames: string[], opts?: BindOptions): Result<SessionState>;
130
+ /**
131
+ * Compose the effective role for a (project, token?, requested?) tuple.
132
+ * Three-cap when a token is present (HTTP+registry mode); two-cap legacy
133
+ * behavior when token is undefined (stdio, synthetic, or any path that
134
+ * never populated state.token).
135
+ */
136
+ private composeEffective;
137
+ }
138
+ export declare function resolveSessionId(extra: unknown): string;
139
+ export declare function __resetStdioSessionId(): void;
140
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/instance/session.ts"],"names":[],"mappings":"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"}