@mastra/code-sdk 0.0.0-fix-workflow-step-timing-and-parallel-status-20260715180716

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 (468) hide show
  1. package/CHANGELOG.md +285 -0
  2. package/LICENSE.md +30 -0
  3. package/README.md +50 -0
  4. package/dist/acp/agent.d.ts +35 -0
  5. package/dist/acp/agent.d.ts.map +1 -0
  6. package/dist/acp/agent.js +173 -0
  7. package/dist/acp/agent.js.map +1 -0
  8. package/dist/acp/event-mapper.d.ts +22 -0
  9. package/dist/acp/event-mapper.d.ts.map +1 -0
  10. package/dist/acp/event-mapper.js +166 -0
  11. package/dist/acp/event-mapper.js.map +1 -0
  12. package/dist/acp/index.d.ts +8 -0
  13. package/dist/acp/index.d.ts.map +1 -0
  14. package/dist/acp/index.js +54 -0
  15. package/dist/acp/index.js.map +1 -0
  16. package/dist/acp/server.d.ts +7 -0
  17. package/dist/acp/server.d.ts.map +1 -0
  18. package/dist/acp/server.js +34 -0
  19. package/dist/acp/server.js.map +1 -0
  20. package/dist/acp.d.ts +2 -0
  21. package/dist/acp.d.ts.map +1 -0
  22. package/dist/acp.js +5 -0
  23. package/dist/acp.js.map +1 -0
  24. package/dist/agents/instructions.d.ts +6 -0
  25. package/dist/agents/instructions.d.ts.map +1 -0
  26. package/dist/agents/instructions.js +41 -0
  27. package/dist/agents/instructions.js.map +1 -0
  28. package/dist/agents/mastracode-gateway.d.ts +67 -0
  29. package/dist/agents/mastracode-gateway.d.ts.map +1 -0
  30. package/dist/agents/mastracode-gateway.js +446 -0
  31. package/dist/agents/mastracode-gateway.js.map +1 -0
  32. package/dist/agents/memory.d.ts +13 -0
  33. package/dist/agents/memory.d.ts.map +1 -0
  34. package/dist/agents/memory.js +107 -0
  35. package/dist/agents/memory.js.map +1 -0
  36. package/dist/agents/model.d.ts +55 -0
  37. package/dist/agents/model.d.ts.map +1 -0
  38. package/dist/agents/model.js +115 -0
  39. package/dist/agents/model.js.map +1 -0
  40. package/dist/agents/modes/build.d.ts +10 -0
  41. package/dist/agents/modes/build.d.ts.map +1 -0
  42. package/dist/agents/modes/build.js +45 -0
  43. package/dist/agents/modes/build.js.map +1 -0
  44. package/dist/agents/modes/explore.d.ts +10 -0
  45. package/dist/agents/modes/explore.d.ts.map +1 -0
  46. package/dist/agents/modes/explore.js +38 -0
  47. package/dist/agents/modes/explore.js.map +1 -0
  48. package/dist/agents/modes/plan.d.ts +6 -0
  49. package/dist/agents/modes/plan.d.ts.map +1 -0
  50. package/dist/agents/modes/plan.js +38 -0
  51. package/dist/agents/modes/plan.js.map +1 -0
  52. package/dist/agents/prompts/agent-instructions.d.ts +20 -0
  53. package/dist/agents/prompts/agent-instructions.d.ts.map +1 -0
  54. package/dist/agents/prompts/agent-instructions.js +82 -0
  55. package/dist/agents/prompts/agent-instructions.js.map +1 -0
  56. package/dist/agents/prompts/build.d.ts +12 -0
  57. package/dist/agents/prompts/build.d.ts.map +1 -0
  58. package/dist/agents/prompts/build.js +73 -0
  59. package/dist/agents/prompts/build.js.map +1 -0
  60. package/dist/agents/prompts/fast.d.ts +5 -0
  61. package/dist/agents/prompts/fast.d.ts.map +1 -0
  62. package/dist/agents/prompts/fast.js +22 -0
  63. package/dist/agents/prompts/fast.js.map +1 -0
  64. package/dist/agents/prompts/index.d.ts +19 -0
  65. package/dist/agents/prompts/index.d.ts.map +1 -0
  66. package/dist/agents/prompts/index.js +57 -0
  67. package/dist/agents/prompts/index.js.map +1 -0
  68. package/dist/agents/prompts/model.d.ts +5 -0
  69. package/dist/agents/prompts/model.d.ts.map +1 -0
  70. package/dist/agents/prompts/model.js +22 -0
  71. package/dist/agents/prompts/model.js.map +1 -0
  72. package/dist/agents/prompts/plan.d.ts +6 -0
  73. package/dist/agents/prompts/plan.d.ts.map +1 -0
  74. package/dist/agents/prompts/plan.js +107 -0
  75. package/dist/agents/prompts/plan.js.map +1 -0
  76. package/dist/agents/prompts/tool-guidance.d.ts +13 -0
  77. package/dist/agents/prompts/tool-guidance.d.ts.map +1 -0
  78. package/dist/agents/prompts/tool-guidance.js +181 -0
  79. package/dist/agents/prompts/tool-guidance.js.map +1 -0
  80. package/dist/agents/sandbox-filesystem.d.ts +89 -0
  81. package/dist/agents/sandbox-filesystem.d.ts.map +1 -0
  82. package/dist/agents/sandbox-filesystem.js +268 -0
  83. package/dist/agents/sandbox-filesystem.js.map +1 -0
  84. package/dist/agents/sandbox-reattach.d.ts +19 -0
  85. package/dist/agents/sandbox-reattach.d.ts.map +1 -0
  86. package/dist/agents/sandbox-reattach.js +17 -0
  87. package/dist/agents/sandbox-reattach.js.map +1 -0
  88. package/dist/agents/thread-caveman-state.d.ts +17 -0
  89. package/dist/agents/thread-caveman-state.d.ts.map +1 -0
  90. package/dist/agents/thread-caveman-state.js +96 -0
  91. package/dist/agents/thread-caveman-state.js.map +1 -0
  92. package/dist/agents/tool-availability.d.ts +10 -0
  93. package/dist/agents/tool-availability.d.ts.map +1 -0
  94. package/dist/agents/tool-availability.js +105 -0
  95. package/dist/agents/tool-availability.js.map +1 -0
  96. package/dist/agents/tools.d.ts +19 -0
  97. package/dist/agents/tools.d.ts.map +1 -0
  98. package/dist/agents/tools.js +145 -0
  99. package/dist/agents/tools.js.map +1 -0
  100. package/dist/agents/workspace.d.ts +22 -0
  101. package/dist/agents/workspace.d.ts.map +1 -0
  102. package/dist/agents/workspace.js +226 -0
  103. package/dist/agents/workspace.js.map +1 -0
  104. package/dist/analytics.d.ts +18 -0
  105. package/dist/analytics.d.ts.map +1 -0
  106. package/dist/analytics.js +152 -0
  107. package/dist/analytics.js.map +1 -0
  108. package/dist/auth/index.d.ts +9 -0
  109. package/dist/auth/index.d.ts.map +1 -0
  110. package/dist/auth/index.js +11 -0
  111. package/dist/auth/index.js.map +1 -0
  112. package/dist/auth/pkce.d.ts +13 -0
  113. package/dist/auth/pkce.d.ts.map +1 -0
  114. package/dist/auth/pkce.js +21 -0
  115. package/dist/auth/pkce.js.map +1 -0
  116. package/dist/auth/providers/anthropic.d.ts +17 -0
  117. package/dist/auth/providers/anthropic.d.ts.map +1 -0
  118. package/dist/auth/providers/anthropic.js +94 -0
  119. package/dist/auth/providers/anthropic.js.map +1 -0
  120. package/dist/auth/providers/github-copilot.d.ts +100 -0
  121. package/dist/auth/providers/github-copilot.d.ts.map +1 -0
  122. package/dist/auth/providers/github-copilot.js +302 -0
  123. package/dist/auth/providers/github-copilot.js.map +1 -0
  124. package/dist/auth/providers/openai-codex.d.ts +95 -0
  125. package/dist/auth/providers/openai-codex.d.ts.map +1 -0
  126. package/dist/auth/providers/openai-codex.js +527 -0
  127. package/dist/auth/providers/openai-codex.js.map +1 -0
  128. package/dist/auth/storage.d.ts +91 -0
  129. package/dist/auth/storage.d.ts.map +1 -0
  130. package/dist/auth/storage.js +187 -0
  131. package/dist/auth/storage.js.map +1 -0
  132. package/dist/auth/types.d.ts +68 -0
  133. package/dist/auth/types.d.ts.map +1 -0
  134. package/dist/auth/types.js +1 -0
  135. package/dist/auth/types.js.map +1 -0
  136. package/dist/clipboard/index.d.ts +26 -0
  137. package/dist/clipboard/index.d.ts.map +1 -0
  138. package/dist/clipboard/index.js +192 -0
  139. package/dist/clipboard/index.js.map +1 -0
  140. package/dist/constants.d.ts +10 -0
  141. package/dist/constants.d.ts.map +1 -0
  142. package/dist/constants.js +23 -0
  143. package/dist/constants.js.map +1 -0
  144. package/dist/error-classification.d.ts +10 -0
  145. package/dist/error-classification.d.ts.map +1 -0
  146. package/dist/error-classification.js +14 -0
  147. package/dist/error-classification.js.map +1 -0
  148. package/dist/evals/context-builder.d.ts +41 -0
  149. package/dist/evals/context-builder.d.ts.map +1 -0
  150. package/dist/evals/context-builder.js +120 -0
  151. package/dist/evals/context-builder.js.map +1 -0
  152. package/dist/evals/index.d.ts +4 -0
  153. package/dist/evals/index.d.ts.map +1 -0
  154. package/dist/evals/index.js +8 -0
  155. package/dist/evals/index.js.map +1 -0
  156. package/dist/evals/scorers/classify-command.d.ts +31 -0
  157. package/dist/evals/scorers/classify-command.d.ts.map +1 -0
  158. package/dist/evals/scorers/classify-command.js +52 -0
  159. package/dist/evals/scorers/classify-command.js.map +1 -0
  160. package/dist/evals/scorers/efficiency.d.ts +44 -0
  161. package/dist/evals/scorers/efficiency.d.ts.map +1 -0
  162. package/dist/evals/scorers/efficiency.js +201 -0
  163. package/dist/evals/scorers/efficiency.js.map +1 -0
  164. package/dist/evals/scorers/extract-tools.d.ts +25 -0
  165. package/dist/evals/scorers/extract-tools.d.ts.map +1 -0
  166. package/dist/evals/scorers/extract-tools.js +56 -0
  167. package/dist/evals/scorers/extract-tools.js.map +1 -0
  168. package/dist/evals/scorers/index.d.ts +3 -0
  169. package/dist/evals/scorers/index.d.ts.map +1 -0
  170. package/dist/evals/scorers/index.js +7 -0
  171. package/dist/evals/scorers/index.js.map +1 -0
  172. package/dist/evals/scorers/outcome.d.ts +49 -0
  173. package/dist/evals/scorers/outcome.d.ts.map +1 -0
  174. package/dist/evals/scorers/outcome.js +238 -0
  175. package/dist/evals/scorers/outcome.js.map +1 -0
  176. package/dist/headless/cli.d.ts +42 -0
  177. package/dist/headless/cli.d.ts.map +1 -0
  178. package/dist/headless/cli.js +196 -0
  179. package/dist/headless/cli.js.map +1 -0
  180. package/dist/headless/flags.d.ts +33 -0
  181. package/dist/headless/flags.d.ts.map +1 -0
  182. package/dist/headless/flags.js +188 -0
  183. package/dist/headless/flags.js.map +1 -0
  184. package/dist/headless/format.d.ts +38 -0
  185. package/dist/headless/format.d.ts.map +1 -0
  186. package/dist/headless/format.js +85 -0
  187. package/dist/headless/format.js.map +1 -0
  188. package/dist/headless/index.d.ts +25 -0
  189. package/dist/headless/index.d.ts.map +1 -0
  190. package/dist/headless/index.js +32 -0
  191. package/dist/headless/index.js.map +1 -0
  192. package/dist/headless/policy.d.ts +17 -0
  193. package/dist/headless/policy.d.ts.map +1 -0
  194. package/dist/headless/policy.js +38 -0
  195. package/dist/headless/policy.js.map +1 -0
  196. package/dist/headless/run-mc.d.ts +7 -0
  197. package/dist/headless/run-mc.d.ts.map +1 -0
  198. package/dist/headless/run-mc.js +296 -0
  199. package/dist/headless/run-mc.js.map +1 -0
  200. package/dist/headless/types.d.ts +134 -0
  201. package/dist/headless/types.d.ts.map +1 -0
  202. package/dist/headless/types.js +9 -0
  203. package/dist/headless/types.js.map +1 -0
  204. package/dist/hooks/config.d.ts +11 -0
  205. package/dist/hooks/config.d.ts.map +1 -0
  206. package/dist/hooks/config.js +78 -0
  207. package/dist/hooks/config.js.map +1 -0
  208. package/dist/hooks/executor.d.ts +13 -0
  209. package/dist/hooks/executor.d.ts.map +1 -0
  210. package/dist/hooks/executor.js +125 -0
  211. package/dist/hooks/executor.js.map +1 -0
  212. package/dist/hooks/index.d.ts +6 -0
  213. package/dist/hooks/index.d.ts.map +1 -0
  214. package/dist/hooks/index.js +16 -0
  215. package/dist/hooks/index.js.map +1 -0
  216. package/dist/hooks/manager.d.ts +47 -0
  217. package/dist/hooks/manager.d.ts.map +1 -0
  218. package/dist/hooks/manager.js +284 -0
  219. package/dist/hooks/manager.js.map +1 -0
  220. package/dist/hooks/types.d.ts +152 -0
  221. package/dist/hooks/types.d.ts.map +1 -0
  222. package/dist/hooks/types.js +7 -0
  223. package/dist/hooks/types.js.map +1 -0
  224. package/dist/index.d.ts +243 -0
  225. package/dist/index.d.ts.map +1 -0
  226. package/dist/index.js +730 -0
  227. package/dist/index.js.map +1 -0
  228. package/dist/ipc/ipc-reporter.d.ts +14 -0
  229. package/dist/ipc/ipc-reporter.d.ts.map +1 -0
  230. package/dist/ipc/ipc-reporter.js +24 -0
  231. package/dist/ipc/ipc-reporter.js.map +1 -0
  232. package/dist/lsp/client.d.ts +56 -0
  233. package/dist/lsp/client.d.ts.map +1 -0
  234. package/dist/lsp/client.js +309 -0
  235. package/dist/lsp/client.js.map +1 -0
  236. package/dist/lsp/index.d.ts +4 -0
  237. package/dist/lsp/index.d.ts.map +1 -0
  238. package/dist/lsp/index.js +9 -0
  239. package/dist/lsp/index.js.map +1 -0
  240. package/dist/lsp/language.d.ts +9 -0
  241. package/dist/lsp/language.d.ts.map +1 -0
  242. package/dist/lsp/language.js +48 -0
  243. package/dist/lsp/language.js.map +1 -0
  244. package/dist/lsp/manager.d.ts +34 -0
  245. package/dist/lsp/manager.d.ts.map +1 -0
  246. package/dist/lsp/manager.js +97 -0
  247. package/dist/lsp/manager.js.map +1 -0
  248. package/dist/lsp/server.d.ts +27 -0
  249. package/dist/lsp/server.d.ts.map +1 -0
  250. package/dist/lsp/server.js +128 -0
  251. package/dist/lsp/server.js.map +1 -0
  252. package/dist/lsp/workspace.d.ts +9 -0
  253. package/dist/lsp/workspace.d.ts.map +1 -0
  254. package/dist/lsp/workspace.js +52 -0
  255. package/dist/lsp/workspace.js.map +1 -0
  256. package/dist/mcp/config.d.ts +34 -0
  257. package/dist/mcp/config.d.ts.map +1 -0
  258. package/dist/mcp/config.js +205 -0
  259. package/dist/mcp/config.js.map +1 -0
  260. package/dist/mcp/index.d.ts +5 -0
  261. package/dist/mcp/index.d.ts.map +1 -0
  262. package/dist/mcp/index.js +10 -0
  263. package/dist/mcp/index.js.map +1 -0
  264. package/dist/mcp/manager.d.ts +49 -0
  265. package/dist/mcp/manager.d.ts.map +1 -0
  266. package/dist/mcp/manager.js +374 -0
  267. package/dist/mcp/manager.js.map +1 -0
  268. package/dist/mcp/types.d.ts +85 -0
  269. package/dist/mcp/types.d.ts.map +1 -0
  270. package/dist/mcp/types.js +1 -0
  271. package/dist/mcp/types.js.map +1 -0
  272. package/dist/onboarding/custom-packs.d.ts +7 -0
  273. package/dist/onboarding/custom-packs.d.ts.map +1 -0
  274. package/dist/onboarding/custom-packs.js +20 -0
  275. package/dist/onboarding/custom-packs.js.map +1 -0
  276. package/dist/onboarding/custom-providers.d.ts +4 -0
  277. package/dist/onboarding/custom-providers.d.ts.map +1 -0
  278. package/dist/onboarding/custom-providers.js +28 -0
  279. package/dist/onboarding/custom-providers.js.map +1 -0
  280. package/dist/onboarding/index.d.ts +5 -0
  281. package/dist/onboarding/index.d.ts.map +1 -0
  282. package/dist/onboarding/index.js +21 -0
  283. package/dist/onboarding/index.js.map +1 -0
  284. package/dist/onboarding/om-settings.d.ts +20 -0
  285. package/dist/onboarding/om-settings.d.ts.map +1 -0
  286. package/dist/onboarding/om-settings.js +26 -0
  287. package/dist/onboarding/om-settings.js.map +1 -0
  288. package/dist/onboarding/packs.d.ts +48 -0
  289. package/dist/onboarding/packs.d.ts.map +1 -0
  290. package/dist/onboarding/packs.js +111 -0
  291. package/dist/onboarding/packs.js.map +1 -0
  292. package/dist/onboarding/settings.d.ts +327 -0
  293. package/dist/onboarding/settings.d.ts.map +1 -0
  294. package/dist/onboarding/settings.js +598 -0
  295. package/dist/onboarding/settings.js.map +1 -0
  296. package/dist/permissions.d.ts +55 -0
  297. package/dist/permissions.d.ts.map +1 -0
  298. package/dist/permissions.js +119 -0
  299. package/dist/permissions.js.map +1 -0
  300. package/dist/plugin.d.ts +81 -0
  301. package/dist/plugin.d.ts.map +1 -0
  302. package/dist/plugin.js +30 -0
  303. package/dist/plugin.js.map +1 -0
  304. package/dist/plugins/dependencies.d.ts +9 -0
  305. package/dist/plugins/dependencies.d.ts.map +1 -0
  306. package/dist/plugins/dependencies.js +111 -0
  307. package/dist/plugins/dependencies.js.map +1 -0
  308. package/dist/plugins/install.d.ts +21 -0
  309. package/dist/plugins/install.d.ts.map +1 -0
  310. package/dist/plugins/install.js +200 -0
  311. package/dist/plugins/install.js.map +1 -0
  312. package/dist/plugins/loader.d.ts +15 -0
  313. package/dist/plugins/loader.d.ts.map +1 -0
  314. package/dist/plugins/loader.js +221 -0
  315. package/dist/plugins/loader.js.map +1 -0
  316. package/dist/plugins/manager.d.ts +60 -0
  317. package/dist/plugins/manager.d.ts.map +1 -0
  318. package/dist/plugins/manager.js +378 -0
  319. package/dist/plugins/manager.js.map +1 -0
  320. package/dist/plugins/manifest.d.ts +14 -0
  321. package/dist/plugins/manifest.d.ts.map +1 -0
  322. package/dist/plugins/manifest.js +75 -0
  323. package/dist/plugins/manifest.js.map +1 -0
  324. package/dist/plugins/package-link.d.ts +3 -0
  325. package/dist/plugins/package-link.d.ts.map +1 -0
  326. package/dist/plugins/package-link.js +77 -0
  327. package/dist/plugins/package-link.js.map +1 -0
  328. package/dist/plugins/paths.d.ts +10 -0
  329. package/dist/plugins/paths.d.ts.map +1 -0
  330. package/dist/plugins/paths.js +26 -0
  331. package/dist/plugins/paths.js.map +1 -0
  332. package/dist/plugins/registry.d.ts +8 -0
  333. package/dist/plugins/registry.d.ts.map +1 -0
  334. package/dist/plugins/registry.js +96 -0
  335. package/dist/plugins/registry.js.map +1 -0
  336. package/dist/plugins/scaffold.d.ts +10 -0
  337. package/dist/plugins/scaffold.d.ts.map +1 -0
  338. package/dist/plugins/scaffold.js +152 -0
  339. package/dist/plugins/scaffold.js.map +1 -0
  340. package/dist/plugins/types.d.ts +45 -0
  341. package/dist/plugins/types.d.ts.map +1 -0
  342. package/dist/plugins/types.js +1 -0
  343. package/dist/plugins/types.js.map +1 -0
  344. package/dist/processors/plan-rejection-abort.d.ts +12 -0
  345. package/dist/processors/plan-rejection-abort.d.ts.map +1 -0
  346. package/dist/processors/plan-rejection-abort.js +53 -0
  347. package/dist/processors/plan-rejection-abort.js.map +1 -0
  348. package/dist/providers/amazon-bedrock-gateway.d.ts +40 -0
  349. package/dist/providers/amazon-bedrock-gateway.d.ts.map +1 -0
  350. package/dist/providers/amazon-bedrock-gateway.js +79 -0
  351. package/dist/providers/amazon-bedrock-gateway.js.map +1 -0
  352. package/dist/providers/amazon-bedrock.d.ts +28 -0
  353. package/dist/providers/amazon-bedrock.d.ts.map +1 -0
  354. package/dist/providers/amazon-bedrock.js +62 -0
  355. package/dist/providers/amazon-bedrock.js.map +1 -0
  356. package/dist/providers/claude-max.d.ts +50 -0
  357. package/dist/providers/claude-max.d.ts.map +1 -0
  358. package/dist/providers/claude-max.js +151 -0
  359. package/dist/providers/claude-max.js.map +1 -0
  360. package/dist/providers/github-copilot.d.ts +58 -0
  361. package/dist/providers/github-copilot.d.ts.map +1 -0
  362. package/dist/providers/github-copilot.js +263 -0
  363. package/dist/providers/github-copilot.js.map +1 -0
  364. package/dist/providers/openai-codex.d.ts +70 -0
  365. package/dist/providers/openai-codex.d.ts.map +1 -0
  366. package/dist/providers/openai-codex.js +291 -0
  367. package/dist/providers/openai-codex.js.map +1 -0
  368. package/dist/schema.d.ts +167 -0
  369. package/dist/schema.d.ts.map +1 -0
  370. package/dist/schema.js +92 -0
  371. package/dist/schema.js.map +1 -0
  372. package/dist/theme-palette.d.ts +17 -0
  373. package/dist/theme-palette.d.ts.map +1 -0
  374. package/dist/theme-palette.js +17 -0
  375. package/dist/theme-palette.js.map +1 -0
  376. package/dist/tool-names.d.ts +73 -0
  377. package/dist/tool-names.d.ts.map +1 -0
  378. package/dist/tool-names.js +43 -0
  379. package/dist/tool-names.js.map +1 -0
  380. package/dist/tools/index.d.ts +6 -0
  381. package/dist/tools/index.d.ts.map +1 -0
  382. package/dist/tools/index.js +9 -0
  383. package/dist/tools/index.js.map +1 -0
  384. package/dist/tools/request-sandbox-access.d.ts +6 -0
  385. package/dist/tools/request-sandbox-access.d.ts.map +1 -0
  386. package/dist/tools/request-sandbox-access.js +88 -0
  387. package/dist/tools/request-sandbox-access.js.map +1 -0
  388. package/dist/tools/utils.d.ts +20 -0
  389. package/dist/tools/utils.d.ts.map +1 -0
  390. package/dist/tools/utils.js +22 -0
  391. package/dist/tools/utils.js.map +1 -0
  392. package/dist/tools/web-search.d.ts +35 -0
  393. package/dist/tools/web-search.d.ts.map +1 -0
  394. package/dist/tools/web-search.js +65 -0
  395. package/dist/tools/web-search.js.map +1 -0
  396. package/dist/utils/binaries.d.ts +7 -0
  397. package/dist/utils/binaries.d.ts.map +1 -0
  398. package/dist/utils/binaries.js +74 -0
  399. package/dist/utils/binaries.js.map +1 -0
  400. package/dist/utils/debug-log.d.ts +12 -0
  401. package/dist/utils/debug-log.d.ts.map +1 -0
  402. package/dist/utils/debug-log.js +55 -0
  403. package/dist/utils/debug-log.js.map +1 -0
  404. package/dist/utils/errors.d.ts +36 -0
  405. package/dist/utils/errors.d.ts.map +1 -0
  406. package/dist/utils/errors.js +207 -0
  407. package/dist/utils/errors.js.map +1 -0
  408. package/dist/utils/gateway-sync.d.ts +26 -0
  409. package/dist/utils/gateway-sync.d.ts.map +1 -0
  410. package/dist/utils/gateway-sync.js +49 -0
  411. package/dist/utils/gateway-sync.js.map +1 -0
  412. package/dist/utils/path-security.d.ts +2 -0
  413. package/dist/utils/path-security.d.ts.map +1 -0
  414. package/dist/utils/path-security.js +9 -0
  415. package/dist/utils/path-security.js.map +1 -0
  416. package/dist/utils/plan-diff.d.ts +25 -0
  417. package/dist/utils/plan-diff.d.ts.map +1 -0
  418. package/dist/utils/plan-diff.js +43 -0
  419. package/dist/utils/plan-diff.js.map +1 -0
  420. package/dist/utils/plans.d.ts +56 -0
  421. package/dist/utils/plans.d.ts.map +1 -0
  422. package/dist/utils/plans.js +99 -0
  423. package/dist/utils/plans.js.map +1 -0
  424. package/dist/utils/project.d.ts +160 -0
  425. package/dist/utils/project.d.ts.map +1 -0
  426. package/dist/utils/project.js +302 -0
  427. package/dist/utils/project.js.map +1 -0
  428. package/dist/utils/signals-pubsub.d.ts +41 -0
  429. package/dist/utils/signals-pubsub.d.ts.map +1 -0
  430. package/dist/utils/signals-pubsub.js +104 -0
  431. package/dist/utils/signals-pubsub.js.map +1 -0
  432. package/dist/utils/slash-command-loader.d.ts +52 -0
  433. package/dist/utils/slash-command-loader.d.ts.map +1 -0
  434. package/dist/utils/slash-command-loader.js +177 -0
  435. package/dist/utils/slash-command-loader.js.map +1 -0
  436. package/dist/utils/slash-command-processor.d.ts +14 -0
  437. package/dist/utils/slash-command-processor.d.ts.map +1 -0
  438. package/dist/utils/slash-command-processor.js +96 -0
  439. package/dist/utils/slash-command-processor.js.map +1 -0
  440. package/dist/utils/stdin-pipe.d.ts +33 -0
  441. package/dist/utils/stdin-pipe.d.ts.map +1 -0
  442. package/dist/utils/stdin-pipe.js +72 -0
  443. package/dist/utils/stdin-pipe.js.map +1 -0
  444. package/dist/utils/storage-factory.d.ts +50 -0
  445. package/dist/utils/storage-factory.d.ts.map +1 -0
  446. package/dist/utils/storage-factory.js +101 -0
  447. package/dist/utils/storage-factory.js.map +1 -0
  448. package/dist/utils/storage-maintenance.d.ts +103 -0
  449. package/dist/utils/storage-maintenance.d.ts.map +1 -0
  450. package/dist/utils/storage-maintenance.js +236 -0
  451. package/dist/utils/storage-maintenance.js.map +1 -0
  452. package/dist/utils/thread-lock.d.ts +26 -0
  453. package/dist/utils/thread-lock.d.ts.map +1 -0
  454. package/dist/utils/thread-lock.js +108 -0
  455. package/dist/utils/thread-lock.js.map +1 -0
  456. package/dist/utils/token-estimator.d.ts +3 -0
  457. package/dist/utils/token-estimator.d.ts.map +1 -0
  458. package/dist/utils/token-estimator.js +21 -0
  459. package/dist/utils/token-estimator.js.map +1 -0
  460. package/dist/utils/update-check.d.ts +52 -0
  461. package/dist/utils/update-check.d.ts.map +1 -0
  462. package/dist/utils/update-check.js +177 -0
  463. package/dist/utils/update-check.js.map +1 -0
  464. package/dist/voice/stt-registry.d.ts +64 -0
  465. package/dist/voice/stt-registry.d.ts.map +1 -0
  466. package/dist/voice/stt-registry.js +126 -0
  467. package/dist/voice/stt-registry.js.map +1 -0
  468. package/package.json +94 -0
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Clean up raw piped output so the agent sees readable text, not terminal
3
+ * control noise.
4
+ *
5
+ * 1. Strip all ANSI escape sequences (colors, cursor movement, line clears).
6
+ * 2. Simulate carriage-return overwrites: for each line, split on `\r` and
7
+ * keep only the last segment — this is what the terminal would display
8
+ * after a spinner/progress bar finishes.
9
+ * 3. Collapse runs of blank lines.
10
+ */
11
+ export declare function sanitizePipedOutput(raw: string): string;
12
+ /**
13
+ * If stdin is a pipe (not a TTY), read **all** data until EOF and return it as
14
+ * a string. The returned promise only resolves once the write end of the pipe
15
+ * is closed — i.e. the sending process has fully exited — so callers are
16
+ * guaranteed to receive the complete output, not a partial snapshot from a
17
+ * program that writes progressively.
18
+ *
19
+ * Returns `null` when:
20
+ * - stdin is a TTY (interactive terminal)
21
+ * - the pipe was empty or contained only whitespace
22
+ */
23
+ export declare function drainPipedStdin(): Promise<string | null>;
24
+ /**
25
+ * Reopen `/dev/tty` (or `CON` on Windows) as `process.stdin` so that the
26
+ * interactive TUI can read keyboard input after the original piped stdin has
27
+ * been consumed.
28
+ *
29
+ * @returns `true` if the swap succeeded, `false` if a TTY could not be opened
30
+ * (e.g. running in a headless CI container with no controlling terminal).
31
+ */
32
+ export declare function reopenStdinFromTTY(): boolean;
33
+ //# sourceMappingURL=stdin-pipe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdin-pipe.d.ts","sourceRoot":"","sources":["../../src/utils/stdin-pipe.ts"],"names":[],"mappings":"AAYA;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CA0BvD;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA2C9D;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAmB5C"}
@@ -0,0 +1,72 @@
1
+ import * as fs from "node:fs";
2
+ import * as tty from "node:tty";
3
+ const MAX_PIPE_BYTES = 1024 * 1024;
4
+ const ANSI_RE = /\x1b(?:\[[0-9;?]*[A-Za-z]|\][^\x07\x1b]*(?:\x07|\x1b\\)?|\([A-Z])/g;
5
+ function sanitizePipedOutput(raw) {
6
+ let text = raw.replace(ANSI_RE, "");
7
+ text = text.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, "");
8
+ text = text.split("\n").map((line) => {
9
+ if (!line.includes("\r")) return line;
10
+ const segments = line.split("\r");
11
+ for (let i = segments.length - 1; i >= 0; i--) {
12
+ if (segments[i].length > 0) return segments[i];
13
+ }
14
+ return "";
15
+ }).join("\n");
16
+ text = text.replace(/\n{3,}/g, "\n\n");
17
+ return text.trim();
18
+ }
19
+ async function drainPipedStdin() {
20
+ if (process.stdin.isTTY) return null;
21
+ const chunks = [];
22
+ let totalBytes = 0;
23
+ let truncated = false;
24
+ for await (const chunk of process.stdin) {
25
+ const buf = chunk;
26
+ if (totalBytes + buf.length > MAX_PIPE_BYTES) {
27
+ const remaining = MAX_PIPE_BYTES - totalBytes;
28
+ if (remaining > 0) {
29
+ chunks.push(Buffer.from(buf.subarray(0, remaining)));
30
+ }
31
+ buf.fill(0);
32
+ totalBytes = MAX_PIPE_BYTES;
33
+ truncated = true;
34
+ continue;
35
+ }
36
+ chunks.push(buf);
37
+ totalBytes += buf.length;
38
+ }
39
+ if (truncated) {
40
+ process.stderr.write(`Warning: Piped input exceeded ${MAX_PIPE_BYTES / 1024 / 1024}MB and was truncated.
41
+ `);
42
+ }
43
+ const raw = Buffer.concat(chunks).toString("utf-8");
44
+ for (const buf of chunks) {
45
+ buf.fill(0);
46
+ }
47
+ chunks.length = 0;
48
+ const content = sanitizePipedOutput(raw);
49
+ return content.length > 0 ? content : null;
50
+ }
51
+ function reopenStdinFromTTY() {
52
+ const ttyPath = process.platform === "win32" ? "CON" : "/dev/tty";
53
+ let fd;
54
+ try {
55
+ fd = fs.openSync(ttyPath, "r");
56
+ } catch {
57
+ return false;
58
+ }
59
+ const ttyStream = new tty.ReadStream(fd);
60
+ Object.defineProperty(process, "stdin", {
61
+ value: ttyStream,
62
+ writable: true,
63
+ configurable: true
64
+ });
65
+ return true;
66
+ }
67
+ export {
68
+ drainPipedStdin,
69
+ reopenStdinFromTTY,
70
+ sanitizePipedOutput
71
+ };
72
+ //# sourceMappingURL=stdin-pipe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/stdin-pipe.ts"],"sourcesContent":["import * as fs from 'node:fs';\nimport * as tty from 'node:tty';\n\n/** Maximum piped input size (1 MB). Content beyond this is truncated. */\nconst MAX_PIPE_BYTES = 1024 * 1024;\n\n/**\n * Matches all ANSI escape sequences — SGR (colors), cursor movement, line\n * clears, scrolling, window titles, etc.\n */\nconst ANSI_RE = /\\x1b(?:\\[[0-9;?]*[A-Za-z]|\\][^\\x07\\x1b]*(?:\\x07|\\x1b\\\\)?|\\([A-Z])/g;\n\n/**\n * Clean up raw piped output so the agent sees readable text, not terminal\n * control noise.\n *\n * 1. Strip all ANSI escape sequences (colors, cursor movement, line clears).\n * 2. Simulate carriage-return overwrites: for each line, split on `\\r` and\n * keep only the last segment — this is what the terminal would display\n * after a spinner/progress bar finishes.\n * 3. Collapse runs of blank lines.\n */\nexport function sanitizePipedOutput(raw: string): string {\n // Strip ANSI escapes first\n let text = raw.replace(ANSI_RE, '');\n\n // Strip binary control characters (everything below 0x20 except \\t, \\n, \\r)\n text = text.replace(/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]/g, '');\n\n // Simulate \\r overwrites: for each line, the last \\r-segment wins\n text = text\n .split('\\n')\n .map(line => {\n if (!line.includes('\\r')) return line;\n const segments = line.split('\\r');\n // Walk backwards to find the last non-empty segment — a trailing \\r\n // produces an empty final segment that would otherwise discard visible text.\n for (let i = segments.length - 1; i >= 0; i--) {\n if (segments[i]!.length > 0) return segments[i]!;\n }\n return '';\n })\n .join('\\n');\n\n // Collapse 3+ consecutive blank lines into 2\n text = text.replace(/\\n{3,}/g, '\\n\\n');\n\n return text.trim();\n}\n\n/**\n * If stdin is a pipe (not a TTY), read **all** data until EOF and return it as\n * a string. The returned promise only resolves once the write end of the pipe\n * is closed — i.e. the sending process has fully exited — so callers are\n * guaranteed to receive the complete output, not a partial snapshot from a\n * program that writes progressively.\n *\n * Returns `null` when:\n * - stdin is a TTY (interactive terminal)\n * - the pipe was empty or contained only whitespace\n */\nexport async function drainPipedStdin(): Promise<string | null> {\n if (process.stdin.isTTY) return null;\n\n const chunks: Buffer[] = [];\n let totalBytes = 0;\n let truncated = false;\n\n for await (const chunk of process.stdin) {\n const buf = chunk as Buffer;\n\n if (totalBytes + buf.length > MAX_PIPE_BYTES) {\n // Take only what fits under the cap — copy so we don't retain the\n // original backing buffer, then zero the source.\n const remaining = MAX_PIPE_BYTES - totalBytes;\n if (remaining > 0) {\n chunks.push(Buffer.from(buf.subarray(0, remaining)));\n }\n buf.fill(0);\n totalBytes = MAX_PIPE_BYTES;\n truncated = true;\n // Keep draining so we don't leave unread data in the pipe, but don't\n // store it — we still need to wait for EOF.\n continue;\n }\n\n chunks.push(buf);\n totalBytes += buf.length;\n }\n\n if (truncated) {\n process.stderr.write(`Warning: Piped input exceeded ${MAX_PIPE_BYTES / 1024 / 1024}MB and was truncated.\\n`);\n }\n\n const raw = Buffer.concat(chunks).toString('utf-8');\n\n // Zero out raw buffers so piped secrets don't linger in memory\n for (const buf of chunks) {\n buf.fill(0);\n }\n chunks.length = 0;\n\n const content = sanitizePipedOutput(raw);\n return content.length > 0 ? content : null;\n}\n\n/**\n * Reopen `/dev/tty` (or `CON` on Windows) as `process.stdin` so that the\n * interactive TUI can read keyboard input after the original piped stdin has\n * been consumed.\n *\n * @returns `true` if the swap succeeded, `false` if a TTY could not be opened\n * (e.g. running in a headless CI container with no controlling terminal).\n */\nexport function reopenStdinFromTTY(): boolean {\n const ttyPath = process.platform === 'win32' ? 'CON' : '/dev/tty';\n\n let fd: number;\n try {\n fd = fs.openSync(ttyPath, 'r');\n } catch {\n return false;\n }\n\n const ttyStream = new tty.ReadStream(fd);\n\n Object.defineProperty(process, 'stdin', {\n value: ttyStream,\n writable: true,\n configurable: true,\n });\n\n return true;\n}\n"],"mappings":"AAAA,YAAY,QAAQ;AACpB,YAAY,SAAS;AAGrB,MAAM,iBAAiB,OAAO;AAM9B,MAAM,UAAU;AAYT,SAAS,oBAAoB,KAAqB;AAEvD,MAAI,OAAO,IAAI,QAAQ,SAAS,EAAE;AAGlC,SAAO,KAAK,QAAQ,qCAAqC,EAAE;AAG3D,SAAO,KACJ,MAAM,IAAI,EACV,IAAI,UAAQ;AACX,QAAI,CAAC,KAAK,SAAS,IAAI,EAAG,QAAO;AACjC,UAAM,WAAW,KAAK,MAAM,IAAI;AAGhC,aAAS,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK;AAC7C,UAAI,SAAS,CAAC,EAAG,SAAS,EAAG,QAAO,SAAS,CAAC;AAAA,IAChD;AACA,WAAO;AAAA,EACT,CAAC,EACA,KAAK,IAAI;AAGZ,SAAO,KAAK,QAAQ,WAAW,MAAM;AAErC,SAAO,KAAK,KAAK;AACnB;AAaA,eAAsB,kBAA0C;AAC9D,MAAI,QAAQ,MAAM,MAAO,QAAO;AAEhC,QAAM,SAAmB,CAAC;AAC1B,MAAI,aAAa;AACjB,MAAI,YAAY;AAEhB,mBAAiB,SAAS,QAAQ,OAAO;AACvC,UAAM,MAAM;AAEZ,QAAI,aAAa,IAAI,SAAS,gBAAgB;AAG5C,YAAM,YAAY,iBAAiB;AACnC,UAAI,YAAY,GAAG;AACjB,eAAO,KAAK,OAAO,KAAK,IAAI,SAAS,GAAG,SAAS,CAAC,CAAC;AAAA,MACrD;AACA,UAAI,KAAK,CAAC;AACV,mBAAa;AACb,kBAAY;AAGZ;AAAA,IACF;AAEA,WAAO,KAAK,GAAG;AACf,kBAAc,IAAI;AAAA,EACpB;AAEA,MAAI,WAAW;AACb,YAAQ,OAAO,MAAM,iCAAiC,iBAAiB,OAAO,IAAI;AAAA,CAAyB;AAAA,EAC7G;AAEA,QAAM,MAAM,OAAO,OAAO,MAAM,EAAE,SAAS,OAAO;AAGlD,aAAW,OAAO,QAAQ;AACxB,QAAI,KAAK,CAAC;AAAA,EACZ;AACA,SAAO,SAAS;AAEhB,QAAM,UAAU,oBAAoB,GAAG;AACvC,SAAO,QAAQ,SAAS,IAAI,UAAU;AACxC;AAUO,SAAS,qBAA8B;AAC5C,QAAM,UAAU,QAAQ,aAAa,UAAU,QAAQ;AAEvD,MAAI;AACJ,MAAI;AACF,SAAK,GAAG,SAAS,SAAS,GAAG;AAAA,EAC/B,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,IAAI,IAAI,WAAW,EAAE;AAEvC,SAAO,eAAe,SAAS,SAAS;AAAA,IACtC,OAAO;AAAA,IACP,UAAU;AAAA,IACV,cAAc;AAAA,EAChB,CAAC;AAED,SAAO;AACT;","names":[]}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Storage factory — creates the appropriate storage backend based on resolved config.
3
+ *
4
+ * If PG is selected but fails to connect, falls back to LibSQL so the TUI
5
+ * can start and the user can fix the connection via /settings.
6
+ */
7
+ import type { MastraCompositeStore, RetentionConfig } from '@mastra/core/storage';
8
+ import type { MastraVector } from '@mastra/core/vector';
9
+ import type { StorageConfig } from './project.js';
10
+ export declare const MASTRA_CODE_LOCAL_PRAGMAS: {
11
+ cacheSize: number;
12
+ mmapSize: number;
13
+ };
14
+ /**
15
+ * Construct a LibSQL store for an arbitrary url/authToken, applying the same
16
+ * local pragmas the default factory uses.
17
+ */
18
+ export declare function buildLibSQLStore(opts: {
19
+ id?: string;
20
+ url: string;
21
+ authToken?: string;
22
+ retention?: RetentionConfig;
23
+ }): MastraCompositeStore;
24
+ /** Construct a LibSQL vector store for an arbitrary url/authToken. */
25
+ export declare function buildLibSQLVector(opts: {
26
+ id?: string;
27
+ url: string;
28
+ authToken?: string;
29
+ }): MastraVector;
30
+ export interface StorageResult {
31
+ storage: MastraCompositeStore;
32
+ /** The effective backend after any fallback logic has run. */
33
+ backend: 'libsql' | 'pg';
34
+ /** Non-null when PG was requested but failed — contains a user-facing warning. */
35
+ warning?: string;
36
+ }
37
+ /**
38
+ * Create a storage instance from the resolved config.
39
+ *
40
+ * - `libsql` backend → LibSQLStore (always available)
41
+ * - `pg` backend → PostgresStore, falls back to LibSQL on connection failure
42
+ */
43
+ export declare function createStorage(config: StorageConfig): Promise<StorageResult>;
44
+ /**
45
+ * Create a vector store for recall search.
46
+ * Uses a separate LibSQL file to avoid bloating the main storage DB with embedding data.
47
+ * For PG backends, reuses the same connection (PG handles the extra tables fine).
48
+ */
49
+ export declare function createVectorStore(config: StorageConfig, effectiveBackend?: 'libsql' | 'pg'): Promise<MastraVector | undefined>;
50
+ //# sourceMappingURL=storage-factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-factory.d.ts","sourceRoot":"","sources":["../../src/utils/storage-factory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAIxD,OAAO,KAAK,EAAE,aAAa,EAAmB,MAAM,cAAc,CAAC;AAInE,eAAO,MAAM,yBAAyB;;;CAGrC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,eAAe,CAAC;CAC7B,GAAG,oBAAoB,CAQvB;AAED,sEAAsE;AACtE,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,YAAY,CAMtG;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,oBAAoB,CAAC;IAC9B,8DAA8D;IAC9D,OAAO,EAAE,QAAQ,GAAG,IAAI,CAAC;IACzB,kFAAkF;IAClF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAMD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAUjF;AAyDD;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,aAAa,EACrB,gBAAgB,GAAE,QAAQ,GAAG,IAAqB,GACjD,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAuBnC"}
@@ -0,0 +1,101 @@
1
+ import { LibSQLStore, LibSQLVector } from "@mastra/libsql";
2
+ import { PostgresStore } from "@mastra/pg";
3
+ import { getDatabasePath, getVectorDatabasePath } from "./project.js";
4
+ import { DEFAULT_RETENTION } from "./storage-maintenance.js";
5
+ const MASTRA_CODE_LOCAL_PRAGMAS = {
6
+ cacheSize: -128e3,
7
+ mmapSize: 536870912
8
+ };
9
+ function buildLibSQLStore(opts) {
10
+ return new LibSQLStore({
11
+ id: opts.id ?? "mastra-code-storage",
12
+ url: opts.url,
13
+ ...opts.authToken ? { authToken: opts.authToken } : {},
14
+ ...opts.retention ? { retention: opts.retention } : {},
15
+ localPragmas: MASTRA_CODE_LOCAL_PRAGMAS
16
+ });
17
+ }
18
+ function buildLibSQLVector(opts) {
19
+ return new LibSQLVector({
20
+ id: opts.id ?? "mastra-code-vectors",
21
+ url: opts.url,
22
+ ...opts.authToken ? { authToken: opts.authToken } : {}
23
+ });
24
+ }
25
+ function createFallbackLibSQL() {
26
+ return buildLibSQLStore({ url: `file:${getDatabasePath()}`, retention: DEFAULT_RETENTION });
27
+ }
28
+ async function createStorage(config) {
29
+ if (config.backend === "pg") {
30
+ return createPgStorage(config);
31
+ }
32
+ return {
33
+ storage: buildLibSQLStore({ url: config.url, authToken: config.authToken, retention: DEFAULT_RETENTION }),
34
+ backend: "libsql"
35
+ };
36
+ }
37
+ async function createPgStorage(config) {
38
+ if (!config.connectionString && !config.host) {
39
+ return {
40
+ storage: createFallbackLibSQL(),
41
+ backend: "libsql",
42
+ warning: "PostgreSQL backend selected but no connection info configured. Using LibSQL fallback. Set a connection string via /settings."
43
+ };
44
+ }
45
+ const base = {
46
+ id: "mastra-code-storage",
47
+ retention: DEFAULT_RETENTION,
48
+ ...config.schemaName ? { schemaName: config.schemaName } : {},
49
+ ...config.disableInit ? { disableInit: config.disableInit } : {},
50
+ ...config.skipDefaultIndexes ? { skipDefaultIndexes: config.skipDefaultIndexes } : {}
51
+ };
52
+ const store = config.connectionString ? new PostgresStore({ ...base, connectionString: config.connectionString }) : new PostgresStore({
53
+ ...base,
54
+ host: config.host,
55
+ port: config.port,
56
+ database: config.database,
57
+ user: config.user,
58
+ password: config.password
59
+ });
60
+ try {
61
+ await store.init();
62
+ } catch (err) {
63
+ const msg = err?.message ?? String(err);
64
+ const target = config.connectionString ?? `${config.host}:${config.port ?? 5432}`;
65
+ try {
66
+ await store.close();
67
+ } catch {
68
+ }
69
+ return {
70
+ storage: createFallbackLibSQL(),
71
+ backend: "libsql",
72
+ warning: `Failed to connect to PostgreSQL at ${target}: ${msg}
73
+ Using LibSQL fallback. Fix the connection via /settings.`
74
+ };
75
+ }
76
+ return { storage: store, backend: "pg" };
77
+ }
78
+ async function createVectorStore(config, effectiveBackend = config.backend) {
79
+ if (effectiveBackend === "pg") {
80
+ const pgConfig = config;
81
+ if (!pgConfig.connectionString && !pgConfig.host) return void 0;
82
+ const { PgVector } = await import("@mastra/pg");
83
+ return new PgVector({
84
+ id: "mastra-code-vectors",
85
+ connectionString: pgConfig.connectionString ?? `postgresql://${pgConfig.user}:${pgConfig.password}@${pgConfig.host}:${pgConfig.port ?? 5432}/${pgConfig.database}`
86
+ });
87
+ }
88
+ const libsqlConfig = config;
89
+ return buildLibSQLVector({
90
+ url: libsqlConfig.vectorUrl ?? `file:${getVectorDatabasePath()}`,
91
+ authToken: libsqlConfig.vectorAuthToken
92
+ });
93
+ }
94
+ export {
95
+ MASTRA_CODE_LOCAL_PRAGMAS,
96
+ buildLibSQLStore,
97
+ buildLibSQLVector,
98
+ createStorage,
99
+ createVectorStore
100
+ };
101
+ //# sourceMappingURL=storage-factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/storage-factory.ts"],"sourcesContent":["/**\n * Storage factory — creates the appropriate storage backend based on resolved config.\n *\n * If PG is selected but fails to connect, falls back to LibSQL so the TUI\n * can start and the user can fix the connection via /settings.\n */\n\nimport type { MastraCompositeStore, RetentionConfig } from '@mastra/core/storage';\nimport type { MastraVector } from '@mastra/core/vector';\nimport { LibSQLStore, LibSQLVector } from '@mastra/libsql';\nimport { PostgresStore } from '@mastra/pg';\n\nimport type { StorageConfig, PgStorageConfig } from './project.js';\nimport { getDatabasePath, getVectorDatabasePath } from './project.js';\nimport { DEFAULT_RETENTION } from './storage-maintenance.js';\n\nexport const MASTRA_CODE_LOCAL_PRAGMAS = {\n cacheSize: -128000,\n mmapSize: 536870912,\n};\n\n/**\n * Construct a LibSQL store for an arbitrary url/authToken, applying the same\n * local pragmas the default factory uses.\n */\nexport function buildLibSQLStore(opts: {\n id?: string;\n url: string;\n authToken?: string;\n retention?: RetentionConfig;\n}): MastraCompositeStore {\n return new LibSQLStore({\n id: opts.id ?? 'mastra-code-storage',\n url: opts.url,\n ...(opts.authToken ? { authToken: opts.authToken } : {}),\n ...(opts.retention ? { retention: opts.retention } : {}),\n localPragmas: MASTRA_CODE_LOCAL_PRAGMAS,\n });\n}\n\n/** Construct a LibSQL vector store for an arbitrary url/authToken. */\nexport function buildLibSQLVector(opts: { id?: string; url: string; authToken?: string }): MastraVector {\n return new LibSQLVector({\n id: opts.id ?? 'mastra-code-vectors',\n url: opts.url,\n ...(opts.authToken ? { authToken: opts.authToken } : {}),\n });\n}\n\nexport interface StorageResult {\n storage: MastraCompositeStore;\n /** The effective backend after any fallback logic has run. */\n backend: 'libsql' | 'pg';\n /** Non-null when PG was requested but failed — contains a user-facing warning. */\n warning?: string;\n}\n\nfunction createFallbackLibSQL(): MastraCompositeStore {\n return buildLibSQLStore({ url: `file:${getDatabasePath()}`, retention: DEFAULT_RETENTION });\n}\n\n/**\n * Create a storage instance from the resolved config.\n *\n * - `libsql` backend → LibSQLStore (always available)\n * - `pg` backend → PostgresStore, falls back to LibSQL on connection failure\n */\nexport async function createStorage(config: StorageConfig): Promise<StorageResult> {\n if (config.backend === 'pg') {\n return createPgStorage(config);\n }\n\n // Default: LibSQL\n return {\n storage: buildLibSQLStore({ url: config.url, authToken: config.authToken, retention: DEFAULT_RETENTION }),\n backend: 'libsql',\n };\n}\n\nasync function createPgStorage(config: PgStorageConfig): Promise<StorageResult> {\n // No connection info → fall back with guidance\n if (!config.connectionString && !config.host) {\n return {\n storage: createFallbackLibSQL(),\n backend: 'libsql',\n warning:\n 'PostgreSQL backend selected but no connection info configured. ' +\n 'Using LibSQL fallback. Set a connection string via /settings.',\n };\n }\n\n const base = {\n id: 'mastra-code-storage' as const,\n retention: DEFAULT_RETENTION,\n ...(config.schemaName ? { schemaName: config.schemaName } : {}),\n ...(config.disableInit ? { disableInit: config.disableInit } : {}),\n ...(config.skipDefaultIndexes ? { skipDefaultIndexes: config.skipDefaultIndexes } : {}),\n };\n\n const store = config.connectionString\n ? new PostgresStore({ ...base, connectionString: config.connectionString })\n : new PostgresStore({\n ...base,\n host: config.host!,\n port: config.port,\n database: config.database,\n user: config.user,\n password: config.password,\n });\n\n // Test the connection before committing — if it fails, fall back to LibSQL\n // so the user can fix the config via /settings.\n try {\n await store.init();\n } catch (err: any) {\n const msg = err?.message ?? String(err);\n const target = config.connectionString ?? `${config.host}:${config.port ?? 5432}`;\n try {\n await store.close();\n } catch {\n // ignore cleanup errors\n }\n return {\n storage: createFallbackLibSQL(),\n backend: 'libsql',\n warning:\n `Failed to connect to PostgreSQL at ${target}: ${msg}\\n` +\n 'Using LibSQL fallback. Fix the connection via /settings.',\n };\n }\n\n return { storage: store, backend: 'pg' };\n}\n\n/**\n * Create a vector store for recall search.\n * Uses a separate LibSQL file to avoid bloating the main storage DB with embedding data.\n * For PG backends, reuses the same connection (PG handles the extra tables fine).\n */\nexport async function createVectorStore(\n config: StorageConfig,\n effectiveBackend: 'libsql' | 'pg' = config.backend,\n): Promise<MastraVector | undefined> {\n if (effectiveBackend === 'pg') {\n // PG can handle vector tables in the same database\n const pgConfig = config as PgStorageConfig;\n if (!pgConfig.connectionString && !pgConfig.host) return undefined;\n\n const { PgVector } = await import('@mastra/pg');\n return new PgVector({\n id: 'mastra-code-vectors',\n connectionString:\n pgConfig.connectionString ??\n `postgresql://${pgConfig.user}:${pgConfig.password}@${pgConfig.host}:${pgConfig.port ?? 5432}/${pgConfig.database}`,\n });\n }\n\n // LibSQL: separate file for vectors. Per-tenant configs supply an explicit\n // vectorUrl so each tenant's recall vectors are isolated; otherwise use the\n // shared default file.\n const libsqlConfig = config as { vectorUrl?: string; vectorAuthToken?: string };\n return buildLibSQLVector({\n url: libsqlConfig.vectorUrl ?? `file:${getVectorDatabasePath()}`,\n authToken: libsqlConfig.vectorAuthToken,\n });\n}\n"],"mappings":"AASA,SAAS,aAAa,oBAAoB;AAC1C,SAAS,qBAAqB;AAG9B,SAAS,iBAAiB,6BAA6B;AACvD,SAAS,yBAAyB;AAE3B,MAAM,4BAA4B;AAAA,EACvC,WAAW;AAAA,EACX,UAAU;AACZ;AAMO,SAAS,iBAAiB,MAKR;AACvB,SAAO,IAAI,YAAY;AAAA,IACrB,IAAI,KAAK,MAAM;AAAA,IACf,KAAK,KAAK;AAAA,IACV,GAAI,KAAK,YAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;AAAA,IACtD,GAAI,KAAK,YAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;AAAA,IACtD,cAAc;AAAA,EAChB,CAAC;AACH;AAGO,SAAS,kBAAkB,MAAsE;AACtG,SAAO,IAAI,aAAa;AAAA,IACtB,IAAI,KAAK,MAAM;AAAA,IACf,KAAK,KAAK;AAAA,IACV,GAAI,KAAK,YAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;AAAA,EACxD,CAAC;AACH;AAUA,SAAS,uBAA6C;AACpD,SAAO,iBAAiB,EAAE,KAAK,QAAQ,gBAAgB,CAAC,IAAI,WAAW,kBAAkB,CAAC;AAC5F;AAQA,eAAsB,cAAc,QAA+C;AACjF,MAAI,OAAO,YAAY,MAAM;AAC3B,WAAO,gBAAgB,MAAM;AAAA,EAC/B;AAGA,SAAO;AAAA,IACL,SAAS,iBAAiB,EAAE,KAAK,OAAO,KAAK,WAAW,OAAO,WAAW,WAAW,kBAAkB,CAAC;AAAA,IACxG,SAAS;AAAA,EACX;AACF;AAEA,eAAe,gBAAgB,QAAiD;AAE9E,MAAI,CAAC,OAAO,oBAAoB,CAAC,OAAO,MAAM;AAC5C,WAAO;AAAA,MACL,SAAS,qBAAqB;AAAA,MAC9B,SAAS;AAAA,MACT,SACE;AAAA,IAEJ;AAAA,EACF;AAEA,QAAM,OAAO;AAAA,IACX,IAAI;AAAA,IACJ,WAAW;AAAA,IACX,GAAI,OAAO,aAAa,EAAE,YAAY,OAAO,WAAW,IAAI,CAAC;AAAA,IAC7D,GAAI,OAAO,cAAc,EAAE,aAAa,OAAO,YAAY,IAAI,CAAC;AAAA,IAChE,GAAI,OAAO,qBAAqB,EAAE,oBAAoB,OAAO,mBAAmB,IAAI,CAAC;AAAA,EACvF;AAEA,QAAM,QAAQ,OAAO,mBACjB,IAAI,cAAc,EAAE,GAAG,MAAM,kBAAkB,OAAO,iBAAiB,CAAC,IACxE,IAAI,cAAc;AAAA,IAChB,GAAG;AAAA,IACH,MAAM,OAAO;AAAA,IACb,MAAM,OAAO;AAAA,IACb,UAAU,OAAO;AAAA,IACjB,MAAM,OAAO;AAAA,IACb,UAAU,OAAO;AAAA,EACnB,CAAC;AAIL,MAAI;AACF,UAAM,MAAM,KAAK;AAAA,EACnB,SAAS,KAAU;AACjB,UAAM,MAAM,KAAK,WAAW,OAAO,GAAG;AACtC,UAAM,SAAS,OAAO,oBAAoB,GAAG,OAAO,IAAI,IAAI,OAAO,QAAQ,IAAI;AAC/E,QAAI;AACF,YAAM,MAAM,MAAM;AAAA,IACpB,QAAQ;AAAA,IAER;AACA,WAAO;AAAA,MACL,SAAS,qBAAqB;AAAA,MAC9B,SAAS;AAAA,MACT,SACE,sCAAsC,MAAM,KAAK,GAAG;AAAA;AAAA,IAExD;AAAA,EACF;AAEA,SAAO,EAAE,SAAS,OAAO,SAAS,KAAK;AACzC;AAOA,eAAsB,kBACpB,QACA,mBAAoC,OAAO,SACR;AACnC,MAAI,qBAAqB,MAAM;AAE7B,UAAM,WAAW;AACjB,QAAI,CAAC,SAAS,oBAAoB,CAAC,SAAS,KAAM,QAAO;AAEzD,UAAM,EAAE,SAAS,IAAI,MAAM,OAAO,YAAY;AAC9C,WAAO,IAAI,SAAS;AAAA,MAClB,IAAI;AAAA,MACJ,kBACE,SAAS,oBACT,gBAAgB,SAAS,IAAI,IAAI,SAAS,QAAQ,IAAI,SAAS,IAAI,IAAI,SAAS,QAAQ,IAAI,IAAI,SAAS,QAAQ;AAAA,IACrH,CAAC;AAAA,EACH;AAKA,QAAM,eAAe;AACrB,SAAO,kBAAkB;AAAA,IACvB,KAAK,aAAa,aAAa,QAAQ,sBAAsB,CAAC;AAAA,IAC9D,WAAW,aAAa;AAAA,EAC1B,CAAC;AACH;","names":[]}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Storage maintenance — retention defaults and disk reclamation for mastracode.
3
+ *
4
+ * Retention (`DEFAULT_RETENTION`) is wired into the inner store by the storage
5
+ * factory so `storage.prune()` can delete aged rows across every domain,
6
+ * including the legacy libsql observability spans table.
7
+ *
8
+ * `prune()` only deletes rows — SQLite keeps the freed pages inside the file.
9
+ * `reclaimLibSQLDisk()` returns that space to the OS by streaming a
10
+ * `VACUUM INTO` copy of each file and swapping it into place. It requires all
11
+ * connections to be closed first, so it only runs from the post-TUI
12
+ * maintenance flow. We deliberately do NOT expose VACUUM as a public API on
13
+ * LibSQLStore.
14
+ */
15
+ import type { MastraCompositeStore, PruneOptions, PruneResult, RetentionConfig } from '@mastra/core/storage';
16
+ import type { StorageConfig } from './project.js';
17
+ /**
18
+ * Default retention for mastracode's own storage. Tables not listed are kept
19
+ * forever. Ages chosen for a local dev tool where observability data dwarfs
20
+ * everything else (spans have been observed at 17+ GB):
21
+ * - spans/logs: short-lived debugging telemetry → 14d
22
+ * - scorer results & workflow snapshots: medium-lived run records → 30d
23
+ * - chat history (messages/threads): long-lived, user-visible → 90d
24
+ */
25
+ export declare const DEFAULT_RETENTION: RetentionConfig;
26
+ /** Result of reclaiming disk for one database file (sizes include the WAL). */
27
+ export interface ReclaimResult {
28
+ file: string;
29
+ bytesBefore: number;
30
+ bytesAfter: number;
31
+ }
32
+ /** Handle the TUI uses to run storage maintenance without reaching into store internals. */
33
+ export interface StorageMaintenance {
34
+ backend: 'libsql' | 'pg';
35
+ /** Retention policies in effect (for display in /prune output). */
36
+ retention: RetentionConfig;
37
+ /** Delete rows older than the retention policies. Safe to re-run; batched and cancellable. `options.retention` replaces the standing policies for this call only. */
38
+ prune: (options?: PruneOptions) => Promise<PruneResult[]>;
39
+ /** Close the long-lived storage connection (checkpoints WAL for local libsql). Nothing can use the store afterwards. */
40
+ closeStorage?: () => Promise<void>;
41
+ /** Compact local libsql files (VACUUM INTO + swap) to return freed pages to the OS. Only set for local libsql backends. */
42
+ reclaimDisk?: (onFileStart?: (file: string, bytesBefore: number, liveBytes: number) => void) => Promise<ReclaimResult[]>;
43
+ }
44
+ /** Free bytes required before compacting: the compacted copy plus 20% + 256 MB headroom. */
45
+ export declare function requiredFreeBytes(liveBytes: number): number;
46
+ /**
47
+ * Compact each local libsql db file by streaming a `VACUUM INTO` copy next to
48
+ * it, then swapping the copy into place. Reports before/after sizes.
49
+ *
50
+ * Deliberately NOT an in-place `VACUUM`: that copies all live content into a
51
+ * temp store (held in memory by libsql builds with `temp_store=MEMORY`) and
52
+ * then rewrites the entire database back through the WAL — on multi-GB
53
+ * databases that has frozen whole machines via memory/IO exhaustion.
54
+ * `VACUUM INTO` reads the logical database once and writes the compacted copy
55
+ * sequentially with bounded memory, and the WAL never grows.
56
+ *
57
+ * Each file is preflighted: live bytes are estimated from
58
+ * `page_count - freelist_count` and the copy is refused unless the volume has
59
+ * `requiredFreeBytes()` available.
60
+ *
61
+ * MUST run with every connection to these files closed (the swap replaces the
62
+ * inode — a surviving connection would keep writing to the unlinked old file).
63
+ * `runStorageMaintenance()` closes storage before calling this.
64
+ */
65
+ export declare function reclaimLibSQLDisk(dbFiles: string[], onFileStart?: (file: string, bytesBefore: number, liveBytes: number) => void): Promise<ReclaimResult[]>;
66
+ /**
67
+ * Resolve the local libsql db files eligible for checkpoint + VACUUM.
68
+ * Returns [] for remote (turso) urls and PG backends. When PG was requested
69
+ * but the factory fell back to libsql, the fallback uses the default files.
70
+ */
71
+ export declare function resolveLocalDbFiles(config: StorageConfig, effectiveBackend: 'libsql' | 'pg'): string[];
72
+ /**
73
+ * Build the maintenance handle for the effective storage backend.
74
+ * `localDbFiles` are the local libsql file paths eligible for VACUUM;
75
+ * pass an empty array for remote (turso) or PG backends.
76
+ */
77
+ export declare function createStorageMaintenance(opts: {
78
+ storage: MastraCompositeStore;
79
+ backend: 'libsql' | 'pg';
80
+ retention: RetentionConfig;
81
+ localDbFiles: string[];
82
+ /** Closes the vector store's connection; required for local libsql so the compaction swap isn't blocked by our own handle. */
83
+ closeVector?: () => Promise<void>;
84
+ }): StorageMaintenance;
85
+ export declare function formatBytes(bytes: number): string;
86
+ /**
87
+ * Run storage maintenance with exclusive access to the database, reporting
88
+ * progress through `log` (one line per pass so large deletes are visible).
89
+ *
90
+ * Must run AFTER the TUI is stopped and background writers are quiesced —
91
+ * batched deletes and VACUUM contend with live writes (SQLITE_BUSY) and can
92
+ * starve the event loop that renders the TUI. The storage connection is
93
+ * closed at the end (checkpointing the WAL for local libsql), so the process
94
+ * must exit afterwards.
95
+ */
96
+ export declare function runStorageMaintenance(opts: {
97
+ maintenance: StorageMaintenance;
98
+ vacuum: boolean;
99
+ /** Skip the memory domain (messages/threads) so chat history is preserved. */
100
+ keepMemory?: boolean;
101
+ log: (line: string) => void;
102
+ }): Promise<void>;
103
+ //# sourceMappingURL=storage-maintenance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-maintenance.d.ts","sourceRoot":"","sources":["../../src/utils/storage-maintenance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAQ7G,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlD;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,EAAE,eAe/B,CAAC;AAEF,+EAA+E;AAC/E,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,4FAA4F;AAC5F,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,QAAQ,GAAG,IAAI,CAAC;IACzB,mEAAmE;IACnE,SAAS,EAAE,eAAe,CAAC;IAC3B,qKAAqK;IACrK,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAC1D,wHAAwH;IACxH,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,2HAA2H;IAC3H,WAAW,CAAC,EAAE,CACZ,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,KACzE,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;CAC/B;AAeD,4FAA4F;AAC5F,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE3D;AA0BD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EAAE,EACjB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,GAC3E,OAAO,CAAC,aAAa,EAAE,CAAC,CA0G1B;AAQD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,EAAE,gBAAgB,EAAE,QAAQ,GAAG,IAAI,GAAG,MAAM,EAAE,CAatG;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC7C,OAAO,EAAE,oBAAoB,CAAC;IAC9B,OAAO,EAAE,QAAQ,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,eAAe,CAAC;IAC3B,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,8HAA8H;IAC9H,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC,GAAG,kBAAkB,CAiBrB;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAWjD;AAKD;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,WAAW,EAAE,kBAAkB,CAAC;IAChC,MAAM,EAAE,OAAO,CAAC;IAChB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B,GAAG,OAAO,CAAC,IAAI,CAAC,CA2EhB"}
@@ -0,0 +1,236 @@
1
+ import { closeSync, existsSync, openSync, readSync, renameSync, rmSync, statSync, statfsSync } from "node:fs";
2
+ import { dirname } from "node:path";
3
+ import Database from "libsql";
4
+ import { getDatabasePath, getVectorDatabasePath } from "./project.js";
5
+ const DEFAULT_RETENTION = {
6
+ memory: {
7
+ messages: { maxAge: "90d" },
8
+ threads: { maxAge: "90d" }
9
+ },
10
+ observability: {
11
+ spans: { maxAge: "14d" },
12
+ logs: { maxAge: "14d" }
13
+ },
14
+ scores: {
15
+ scorers: { maxAge: "30d" }
16
+ },
17
+ workflows: {
18
+ workflowSnapshot: { maxAge: "30d" }
19
+ }
20
+ };
21
+ function fileSizeWithWal(dbFile) {
22
+ let total = 0;
23
+ for (const candidate of [dbFile, `${dbFile}-wal`]) {
24
+ try {
25
+ total += statSync(candidate).size;
26
+ } catch {
27
+ }
28
+ }
29
+ return total;
30
+ }
31
+ function requiredFreeBytes(liveBytes) {
32
+ return Math.ceil(liveBytes * 1.2) + 256 * 1024 * 1024;
33
+ }
34
+ function pragmaNumber(db, pragma) {
35
+ const rows = db.pragma(pragma);
36
+ const row = rows?.[0];
37
+ return row ? Number(Object.values(row)[0]) : 0;
38
+ }
39
+ function journalModeFromHeader(file) {
40
+ const fd = openSync(file, "r");
41
+ try {
42
+ const buf = Buffer.alloc(2);
43
+ if (readSync(fd, buf, 0, 2, 18) !== 2) return "unknown";
44
+ if (buf[0] === 2 && buf[1] === 2) return "wal";
45
+ if (buf[0] === 1 && buf[1] === 1) return "delete";
46
+ return "unknown";
47
+ } finally {
48
+ closeSync(fd);
49
+ }
50
+ }
51
+ async function reclaimLibSQLDisk(dbFiles, onFileStart) {
52
+ const results = [];
53
+ for (const file of dbFiles) {
54
+ if (!existsSync(file) || statSync(file).size < 100) continue;
55
+ const bytesBefore = fileSizeWithWal(file);
56
+ const tmp = `${file}.vacuum-tmp`;
57
+ rmSync(tmp, { force: true });
58
+ const probe = new Database(file);
59
+ try {
60
+ probe.exec("PRAGMA busy_timeout = 2000");
61
+ probe.exec("PRAGMA journal_mode = WAL");
62
+ probe.exec("PRAGMA journal_mode = DELETE");
63
+ } catch {
64
+ } finally {
65
+ probe.close();
66
+ }
67
+ if (journalModeFromHeader(file) !== "delete") {
68
+ throw new Error(
69
+ `${file} is in use by another process \u2014 is another Mastra Code session running? Close other sessions and run /prune vacuum again.`
70
+ );
71
+ }
72
+ const db = new Database(file);
73
+ try {
74
+ db.exec("PRAGMA busy_timeout = 2000");
75
+ const pageSize = pragmaNumber(db, "page_size");
76
+ const pageCount = pragmaNumber(db, "page_count");
77
+ const freelistCount = pragmaNumber(db, "freelist_count");
78
+ const liveBytes = Math.max(0, pageCount - freelistCount) * pageSize;
79
+ const { bsize, bavail } = statfsSync(dirname(file));
80
+ const freeBytes = bsize * bavail;
81
+ if (freeBytes < requiredFreeBytes(liveBytes)) {
82
+ throw new Error(
83
+ `Not enough free disk space to compact ${file}: need ${formatBytes(requiredFreeBytes(liveBytes))} for a ${formatBytes(liveBytes)} compacted copy, but only ${formatBytes(freeBytes)} is free.`
84
+ );
85
+ }
86
+ onFileStart?.(file, bytesBefore, liveBytes);
87
+ db.exec(`VACUUM INTO '${tmp.replace(/'/g, "''")}'`);
88
+ } catch (err) {
89
+ rmSync(tmp, { force: true });
90
+ throw err;
91
+ } finally {
92
+ db.close();
93
+ }
94
+ if (journalModeFromHeader(file) !== "delete") {
95
+ rmSync(tmp, { force: true });
96
+ throw new Error(
97
+ `${file} was opened by another process during compaction \u2014 is another Mastra Code session running? Close other sessions and run /prune vacuum again.`
98
+ );
99
+ }
100
+ renameSync(file, `${file}.old`);
101
+ try {
102
+ rmSync(`${file}-wal`, { force: true });
103
+ rmSync(`${file}-shm`, { force: true });
104
+ renameSync(tmp, file);
105
+ } catch (err) {
106
+ try {
107
+ renameSync(`${file}.old`, file);
108
+ } catch {
109
+ throw new Error(
110
+ `Failed to swap compacted copy into place AND failed to restore the original \u2014 your data is intact at ${file}.old; rename it back to ${file} manually. Original error: ${err instanceof Error ? err.message : String(err)}`
111
+ );
112
+ }
113
+ rmSync(tmp, { force: true });
114
+ throw err;
115
+ }
116
+ rmSync(`${file}.old`, { force: true });
117
+ results.push({ file, bytesBefore, bytesAfter: fileSizeWithWal(file) });
118
+ }
119
+ return results;
120
+ }
121
+ function fileUrlToPath(url) {
122
+ if (!url.startsWith("file:")) return void 0;
123
+ return url.replace(/^file:\/\//, "").replace(/^file:/, "");
124
+ }
125
+ function resolveLocalDbFiles(config, effectiveBackend) {
126
+ if (effectiveBackend !== "libsql") return [];
127
+ if (config.backend === "pg") {
128
+ return [getDatabasePath(), getVectorDatabasePath()];
129
+ }
130
+ if (config.isRemote) return [];
131
+ const files = [];
132
+ const main = fileUrlToPath(config.url);
133
+ if (main) files.push(main);
134
+ const vector = config.vectorUrl ? fileUrlToPath(config.vectorUrl) : getVectorDatabasePath();
135
+ if (vector) files.push(vector);
136
+ return files;
137
+ }
138
+ function createStorageMaintenance(opts) {
139
+ const { storage, backend, retention, localDbFiles, closeVector } = opts;
140
+ return {
141
+ backend,
142
+ retention,
143
+ prune: (options) => storage.prune(options),
144
+ closeStorage: async () => {
145
+ await storage.close?.();
146
+ await closeVector?.();
147
+ },
148
+ ...backend === "libsql" && localDbFiles.length > 0 ? {
149
+ reclaimDisk: (onFileStart) => reclaimLibSQLDisk(localDbFiles, onFileStart)
150
+ } : {}
151
+ };
152
+ }
153
+ function formatBytes(bytes) {
154
+ if (bytes < 1024) return `${bytes} B`;
155
+ const units = ["KB", "MB", "GB", "TB"];
156
+ let value = bytes;
157
+ let unit = "B";
158
+ for (const next of units) {
159
+ if (value < 1024) break;
160
+ value /= 1024;
161
+ unit = next;
162
+ }
163
+ return `${value.toFixed(1)} ${unit}`;
164
+ }
165
+ const PASS_MAX_BATCHES = 20;
166
+ async function runStorageMaintenance(opts) {
167
+ const { maintenance, vacuum, keepMemory = false, log } = opts;
168
+ const { memory: _memory, ...withoutMemory } = maintenance.retention;
169
+ const retentionForRun = keepMemory ? { retention: withoutMemory } : {};
170
+ log("Pruning rows older than the retention policies:");
171
+ for (const [domain, tables] of Object.entries(maintenance.retention)) {
172
+ for (const [table, policy] of Object.entries(tables ?? {})) {
173
+ const kept = keepMemory && domain === "memory";
174
+ log(` ${domain}.${table}: ${kept ? "kept (keep-memory)" : policy.maxAge}`);
175
+ }
176
+ }
177
+ const totals = /* @__PURE__ */ new Map();
178
+ for (; ; ) {
179
+ const results = await maintenance.prune({ maxBatches: PASS_MAX_BATCHES, ...retentionForRun });
180
+ if (results.length === 0) break;
181
+ let remaining = false;
182
+ let deletedThisPass = 0;
183
+ for (const r of results) {
184
+ const key = `${r.domain}.${r.table}`;
185
+ totals.set(key, (totals.get(key) ?? 0) + r.deleted);
186
+ deletedThisPass += r.deleted;
187
+ if (!r.done) remaining = true;
188
+ if (r.deleted > 0) {
189
+ log(` ${key}: ${totals.get(key)} rows deleted${r.done ? "" : " so far\u2026"}`);
190
+ }
191
+ }
192
+ if (!remaining) break;
193
+ if (deletedThisPass === 0) {
194
+ log(" stopping: no progress in the last pass.");
195
+ break;
196
+ }
197
+ }
198
+ const totalDeleted = [...totals.values()].reduce((sum, n) => sum + n, 0);
199
+ log(
200
+ totalDeleted === 0 ? "Nothing to prune \u2014 no retention-eligible rows found." : `Prune complete: ${totalDeleted} rows deleted.`
201
+ );
202
+ await maintenance.closeStorage?.();
203
+ if (!vacuum) {
204
+ if (maintenance.reclaimDisk) {
205
+ log("Deleted rows free pages inside the db file but not on disk. Run /prune vacuum to reclaim disk space.");
206
+ }
207
+ return;
208
+ }
209
+ if (!maintenance.reclaimDisk) {
210
+ log("Disk reclamation (VACUUM) is only available for local libsql storage.");
211
+ return;
212
+ }
213
+ log("Reclaiming disk (compacting database files)\u2026 this can take several minutes on large databases.");
214
+ const reclaimed = await maintenance.reclaimDisk((file, bytesBefore, liveBytes) => {
215
+ log(` vacuuming ${file} (${formatBytes(bytesBefore)}, ~${formatBytes(liveBytes)} live)\u2026`);
216
+ });
217
+ if (reclaimed.length === 0) {
218
+ log("No local database files found to vacuum.");
219
+ return;
220
+ }
221
+ for (const r of reclaimed) {
222
+ log(` ${r.file}: ${formatBytes(r.bytesBefore)} \u2192 ${formatBytes(r.bytesAfter)}`);
223
+ }
224
+ const saved = reclaimed.reduce((sum, r) => sum + Math.max(0, r.bytesBefore - r.bytesAfter), 0);
225
+ log(`Reclaimed ${formatBytes(saved)}.`);
226
+ }
227
+ export {
228
+ DEFAULT_RETENTION,
229
+ createStorageMaintenance,
230
+ formatBytes,
231
+ reclaimLibSQLDisk,
232
+ requiredFreeBytes,
233
+ resolveLocalDbFiles,
234
+ runStorageMaintenance
235
+ };
236
+ //# sourceMappingURL=storage-maintenance.js.map