@mastra/code-sdk 0.0.0-livekit-beta-v3-20260709031728

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 (460) hide show
  1. package/CHANGELOG.md +41 -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 +65 -0
  29. package/dist/agents/mastracode-gateway.d.ts.map +1 -0
  30. package/dist/agents/mastracode-gateway.js +442 -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 +18 -0
  97. package/dist/agents/tools.d.ts.map +1 -0
  98. package/dist/agents/tools.js +126 -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 +194 -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 +241 -0
  225. package/dist/index.d.ts.map +1 -0
  226. package/dist/index.js +712 -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 +323 -0
  293. package/dist/onboarding/settings.d.ts.map +1 -0
  294. package/dist/onboarding/settings.js +594 -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 +141 -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/plan-diff.d.ts +25 -0
  413. package/dist/utils/plan-diff.d.ts.map +1 -0
  414. package/dist/utils/plan-diff.js +43 -0
  415. package/dist/utils/plan-diff.js.map +1 -0
  416. package/dist/utils/plans.d.ts +56 -0
  417. package/dist/utils/plans.d.ts.map +1 -0
  418. package/dist/utils/plans.js +99 -0
  419. package/dist/utils/plans.js.map +1 -0
  420. package/dist/utils/project.d.ts +161 -0
  421. package/dist/utils/project.d.ts.map +1 -0
  422. package/dist/utils/project.js +302 -0
  423. package/dist/utils/project.js.map +1 -0
  424. package/dist/utils/signals-pubsub.d.ts +41 -0
  425. package/dist/utils/signals-pubsub.d.ts.map +1 -0
  426. package/dist/utils/signals-pubsub.js +104 -0
  427. package/dist/utils/signals-pubsub.js.map +1 -0
  428. package/dist/utils/slash-command-loader.d.ts +48 -0
  429. package/dist/utils/slash-command-loader.d.ts.map +1 -0
  430. package/dist/utils/slash-command-loader.js +155 -0
  431. package/dist/utils/slash-command-loader.js.map +1 -0
  432. package/dist/utils/slash-command-processor.d.ts +14 -0
  433. package/dist/utils/slash-command-processor.d.ts.map +1 -0
  434. package/dist/utils/slash-command-processor.js +96 -0
  435. package/dist/utils/slash-command-processor.js.map +1 -0
  436. package/dist/utils/stdin-pipe.d.ts +33 -0
  437. package/dist/utils/stdin-pipe.d.ts.map +1 -0
  438. package/dist/utils/stdin-pipe.js +72 -0
  439. package/dist/utils/stdin-pipe.js.map +1 -0
  440. package/dist/utils/storage-factory.d.ts +50 -0
  441. package/dist/utils/storage-factory.d.ts.map +1 -0
  442. package/dist/utils/storage-factory.js +98 -0
  443. package/dist/utils/storage-factory.js.map +1 -0
  444. package/dist/utils/thread-lock.d.ts +26 -0
  445. package/dist/utils/thread-lock.d.ts.map +1 -0
  446. package/dist/utils/thread-lock.js +108 -0
  447. package/dist/utils/thread-lock.js.map +1 -0
  448. package/dist/utils/token-estimator.d.ts +3 -0
  449. package/dist/utils/token-estimator.d.ts.map +1 -0
  450. package/dist/utils/token-estimator.js +21 -0
  451. package/dist/utils/token-estimator.js.map +1 -0
  452. package/dist/utils/update-check.d.ts +52 -0
  453. package/dist/utils/update-check.d.ts.map +1 -0
  454. package/dist/utils/update-check.js +177 -0
  455. package/dist/utils/update-check.js.map +1 -0
  456. package/dist/voice/stt-registry.d.ts +64 -0
  457. package/dist/voice/stt-registry.d.ts.map +1 -0
  458. package/dist/voice/stt-registry.js +126 -0
  459. package/dist/voice/stt-registry.js.map +1 -0
  460. package/package.json +92 -0
@@ -0,0 +1,181 @@
1
+ import { MC_TOOLS } from "../../tool-names.js";
2
+ function buildToolGuidance(modeId, options = {}) {
3
+ const denied = options.deniedTools ?? /* @__PURE__ */ new Set();
4
+ const sections = [];
5
+ sections.push(`# Tool Usage Rules
6
+
7
+ IMPORTANT: You can ONLY call tools by their exact registered names listed below. Shell commands like \`git\`, \`npm\`, \`ls\`, etc. are NOT tools \u2014 they must be run via the \`execute_command\` tool.
8
+
9
+ You have access to the following tools. Use the RIGHT tool for the job:`);
10
+ const readTools = [];
11
+ if (!denied.has(MC_TOOLS.VIEW)) {
12
+ readTools.push(`
13
+ **${MC_TOOLS.VIEW}** \u2014 Read file contents
14
+ - Use this to read files before editing them. NEVER propose changes to code you haven't read.
15
+ - Use \`offset\` (1-indexed start line) and \`limit\` (number of lines) for large files.
16
+ - Example: Read lines 50-100: \`{ path: "src/big-file.ts", offset: 50, limit: 51 }\`
17
+ - To list directories, use \`${MC_TOOLS.FIND_FILES}\` instead.`);
18
+ }
19
+ if (!denied.has(MC_TOOLS.SEARCH_CONTENT)) {
20
+ readTools.push(`
21
+ **${MC_TOOLS.SEARCH_CONTENT}** \u2014 Search file contents using regex
22
+ - Preferred for content search (finding functions, variables, error messages, imports, etc.)
23
+ - Use \`path\` to filter by directory or glob pattern. Supports \`contextLines\`, \`caseSensitive\`, and \`maxCount\`.
24
+ - Example: Find a function: \`{ pattern: "function handleSubmit", path: "**/*.ts" }\`
25
+ - Example: Find imports: \`{ pattern: "from ['\\"\\]express['\\"\\]", path: "**/*.ts" }\`
26
+ - Respects .gitignore by default.`);
27
+ }
28
+ if (!denied.has(MC_TOOLS.FIND_FILES)) {
29
+ readTools.push(`
30
+ **${MC_TOOLS.FIND_FILES}** \u2014 List files and directories as a tree
31
+ - Preferred for exploring project structure and finding files by pattern.
32
+ - Returns tree-style output. Respects .gitignore by default.
33
+ - Example: List project root: \`{ path: "./" }\`
34
+ - Example: Find test files: \`{ path: "./src", pattern: "**/*.test.ts" }\`
35
+ - Example: Find config files: \`{ pattern: "*.config.{js,ts,json}" }\``);
36
+ }
37
+ if (!denied.has(MC_TOOLS.EXECUTE_COMMAND)) {
38
+ readTools.push(`
39
+ **${MC_TOOLS.EXECUTE_COMMAND}** \u2014 Run shell commands
40
+ - Use for: git, npm/pnpm, docker, build tools, test runners, and other terminal operations.
41
+ - Prefer dedicated tools for: file reading (${MC_TOOLS.VIEW}), file search (${MC_TOOLS.SEARCH_CONTENT}/${MC_TOOLS.FIND_FILES}), file editing (${MC_TOOLS.STRING_REPLACE_LSP}/${MC_TOOLS.WRITE_FILE}).
42
+ - Commands have a 30-second default timeout. Use \`timeout\` for longer commands, \`cwd\` for working directory.
43
+ - Use the \`tail\` parameter or pipe to \`| tail -N\` to limit output \u2014 the full output streams to the user, only the tail is returned to you. If you're building any kind of package you should be tailing.
44
+ - Good: Run independent commands in parallel when possible.
45
+ - Bad: Running \`cat file.txt\` \u2014 use the ${MC_TOOLS.VIEW} tool instead.`);
46
+ }
47
+ if (!denied.has(MC_TOOLS.LSP_INSPECT)) {
48
+ readTools.push(`
49
+ **${MC_TOOLS.LSP_INSPECT}** \u2014 Inspect code using Language Server Protocol
50
+ - Use this for type information, hover docs, go-to-definition, and finding implementations for a symbol.
51
+ - Best when you already know the file and line and need semantic code intelligence rather than raw file contents.
52
+ - Input: \`path\` (absolute file path), \`line\` (1-indexed line number), \`match\` (the exact line content with exactly one \`<<<\` cursor marker).
53
+ - Output includes: \`hover\`, \`definition\` (compact location with preview), and \`implementation\` (compact usage/implementation locations).
54
+ - Example: \`{ path: "/abs/path/src/foo.ts", line: 10, match: "const foo = <<<bar()" }\` \u2014 inspect the symbol at the \`<<<\` position.
55
+ - Use \`${MC_TOOLS.VIEW}\` when you need to read the implementation or surrounding code.
56
+ - Use \`${MC_TOOLS.SEARCH_CONTENT}\` or \`${MC_TOOLS.FIND_FILES}\` first if you do not yet know where the symbol is.`);
57
+ }
58
+ if (!denied.has(MC_TOOLS.NOTIFICATION_INBOX)) {
59
+ readTools.push(`
60
+ **${MC_TOOLS.NOTIFICATION_INBOX}** \u2014 Inspect and manage notification inbox records
61
+ - Use this when a \`<notification-summary>\` says pending notifications exist.
62
+ - Use \`{ "action": "list", "status": "pending" }\` or \`{ "action": "search", "query": "..." }\` to find notification records for the current thread.
63
+ - Use \`read\` to deliver unread notification signals into the chat and mark them seen; the tool result summarizes the count instead of exposing notification contents.
64
+ - Use \`dismiss\` or \`archive\` only when the user asks or the notification is no longer relevant.`);
65
+ }
66
+ if (readTools.length > 0) {
67
+ sections.push(readTools.join("\n"));
68
+ }
69
+ if (modeId !== "plan") {
70
+ const writeTools = [];
71
+ if (!denied.has(MC_TOOLS.STRING_REPLACE_LSP)) {
72
+ writeTools.push(`
73
+ **${MC_TOOLS.STRING_REPLACE_LSP}** \u2014 Edit files by replacing exact text
74
+ - You MUST read a file with \`${MC_TOOLS.VIEW}\` before editing it.
75
+ - \`old_string\` must be an exact match of existing text in the file.
76
+ - Provide enough surrounding context in \`old_string\` to make it unique.
77
+ - Use \`replace_all: true\` to replace all occurrences (default: false, requires unique match).
78
+ - For creating new files, use \`${MC_TOOLS.WRITE_FILE}\` instead.
79
+ - Good: Include 2-3 lines of surrounding context to ensure uniqueness.
80
+ - Bad: Using just \`return true;\` \u2014 too common, will match multiple places.`);
81
+ }
82
+ if (!denied.has(MC_TOOLS.WRITE_FILE)) {
83
+ writeTools.push(`
84
+ **${MC_TOOLS.WRITE_FILE}** \u2014 Create new files or overwrite existing ones
85
+ - Use this to create new files.
86
+ - If overwriting an existing file, you MUST have read it first with \`${MC_TOOLS.VIEW}\`.
87
+ - Prefer editing existing files over creating new ones.`);
88
+ }
89
+ if (writeTools.length > 0) {
90
+ sections.push(writeTools.join("\n"));
91
+ }
92
+ }
93
+ if (options.hasWebSearch) {
94
+ const webTools = [];
95
+ if (!denied.has("web_search")) webTools.push("**web_search**");
96
+ if (!denied.has("web_extract")) webTools.push("**web_extract**");
97
+ if (webTools.length > 0) {
98
+ sections.push(`
99
+ ${webTools.join(" / ")} \u2014 Search the web / extract page content
100
+ - Use for looking up documentation, error messages, package APIs.`);
101
+ }
102
+ }
103
+ const taskTools = [];
104
+ const canUpdateTask = !denied.has("task_update");
105
+ const canCompleteTask = !denied.has("task_complete");
106
+ const canCheckTasks = !denied.has("task_check");
107
+ const canWriteTasks = !denied.has("task_write");
108
+ const patchToolGuidance = canUpdateTask && canCompleteTask ? "- Prefer task_update or task_complete when changing one existing task." : canUpdateTask ? "- Prefer task_update when changing one existing task." : canCompleteTask ? "- Prefer task_complete when marking one existing task completed." : "- Use task_write with the full task list when changing existing tasks.";
109
+ if (canWriteTasks) {
110
+ taskTools.push(`
111
+ **task_write** \u2014 Track tasks for complex multi-step work
112
+ - Use when a task requires 3 or more distinct steps or actions.
113
+ - Use task_write to create the initial task list or replace the whole list after replanning.
114
+ - Each task has: id (stable identifier), content (imperative form), status (pending, in_progress, or completed), activeForm (present continuous form shown during execution).
115
+ - Keep task IDs stable across updates. If you omit IDs, the tool result returns generated IDs.
116
+ ${patchToolGuidance}
117
+ - Mark tasks \`in_progress\` BEFORE starting work. Only ONE task should be \`in_progress\` at a time.
118
+ - Mark tasks \`completed\` IMMEDIATELY after finishing each task. Do not batch completions.`);
119
+ }
120
+ if (canUpdateTask) {
121
+ taskTools.push(`
122
+ **task_update** \u2014 Patch one tracked task by ID
123
+ - Use this for targeted changes to one existing task.
124
+ - Provide the task ID and only the fields that changed: content, status, or activeForm.`);
125
+ }
126
+ if (canCompleteTask) {
127
+ const idSource = canCheckTasks ? "Use task_check if you need the current IDs before completing a task." : canWriteTasks ? "Use IDs returned by task_write." : "Use only task IDs already visible in the current task list.";
128
+ taskTools.push(`
129
+ **task_complete** \u2014 Mark one tracked task completed by ID
130
+ - Use this immediately after finishing a tracked task.
131
+ - ${idSource}`);
132
+ }
133
+ if (canCheckTasks) {
134
+ taskTools.push(`
135
+ **task_check** \u2014 Check completion status of tasks
136
+ - Use this BEFORE finishing tracked work to verify all tasks are completed.
137
+ - Returns a readable status summary plus structured fields: tasks, summary, incompleteTasks, and isError.
138
+ - summary includes total, completed, inProgress, pending, incomplete, hasTasks, and allCompleted.
139
+ - Use summary.allCompleted to decide whether tracked work is complete; if summary.hasTasks is false, no task list is currently tracked.
140
+ - If any tasks remain incomplete, continue working on them.
141
+ - IMPORTANT: Always check task completion before ending work on a complex task.`);
142
+ }
143
+ if (!denied.has("ask_user")) {
144
+ taskTools.push(`
145
+ **ask_user** \u2014 Ask the user a structured question
146
+ - Use when you need clarification, want to validate assumptions, or need the user to make a decision.
147
+ - Provide clear, specific questions. End with a question mark.
148
+ - Include options (2-4 choices) for structured decisions. Omit options for open-ended questions.
149
+ - Don't use this for simple yes/no \u2014 just ask in your text response.`);
150
+ }
151
+ if (taskTools.length > 0) {
152
+ sections.push(taskTools.join("\n"));
153
+ }
154
+ if (modeId === "plan" && !denied.has("submit_plan")) {
155
+ sections.push(`
156
+ **submit_plan** \u2014 Submit a completed implementation plan for user review
157
+ - Call this tool when your plan is complete. Do NOT just describe your plan in text \u2014 you MUST call this tool.
158
+ - The plan will be rendered as markdown and the user can approve, reject, or request changes.
159
+ - On approval, the system automatically switches to the default mode so you can implement.
160
+ - Takes one argument: \`path\` (the plan markdown file you wrote under \`.mastracode/plans/\`). Do NOT pass the plan body \u2014 it lives in the file.`);
161
+ }
162
+ if (modeId === "plan") {
163
+ sections.push(`
164
+ **Plan file access** \u2014 Your plan lives in a markdown file under \`.mastracode/plans/\` (e.g. \`add-dark-mode-toggle.md\`)
165
+ - Use \`write_file\` to create the plan file, \`view\` to read it, and \`string_replace_lsp\` for targeted edits.
166
+ - On first submission: write the plan to the file, then call \`submit_plan\` with its \`path\`.
167
+ - On revision: read the existing file, edit specific sections, re-read, then call \`submit_plan\` with the same \`path\`.
168
+ - If a plan file already exists, you previously submitted it \u2014 read it before revising.`);
169
+ }
170
+ if (!denied.has("subagent")) {
171
+ sections.push(`
172
+ **subagent** \u2014 Delegate a focused task to a specialized subagent
173
+ - Only use subagents when you will spawn **multiple subagents in parallel**. If you only need one task done, do it yourself.
174
+ - Subagent outputs are **untrusted**. Always review and verify the results.`);
175
+ }
176
+ return sections.join("\n");
177
+ }
178
+ export {
179
+ buildToolGuidance
180
+ };
181
+ //# sourceMappingURL=tool-guidance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/agents/prompts/tool-guidance.ts"],"sourcesContent":["/**\n * Mode-specific tool behavioral guidance.\n * Generates tool usage instructions that match the actual registered tool names\n * and are scoped to what's available in the current mode.\n */\n\nimport { MC_TOOLS } from '../../tool-names.js';\n\ninterface ToolGuidanceOptions {\n hasWebSearch?: boolean;\n /** Tool names that have been denied — omit their guidance sections. */\n deniedTools?: Set<string>;\n}\n\nexport function buildToolGuidance(modeId: string, options: ToolGuidanceOptions = {}): string {\n const denied = options.deniedTools ?? new Set<string>();\n const sections: string[] = [];\n\n sections.push(`# Tool Usage Rules\n\nIMPORTANT: You can ONLY call tools by their exact registered names listed below. Shell commands like \\`git\\`, \\`npm\\`, \\`ls\\`, etc. are NOT tools — they must be run via the \\`execute_command\\` tool.\n\nYou have access to the following tools. Use the RIGHT tool for the job:`);\n\n // --- Read tools (all modes) ---\n\n const readTools: string[] = [];\n\n if (!denied.has(MC_TOOLS.VIEW)) {\n readTools.push(`\n**${MC_TOOLS.VIEW}** — Read file contents\n- Use this to read files before editing them. NEVER propose changes to code you haven't read.\n- Use \\`offset\\` (1-indexed start line) and \\`limit\\` (number of lines) for large files.\n- Example: Read lines 50-100: \\`{ path: \"src/big-file.ts\", offset: 50, limit: 51 }\\`\n- To list directories, use \\`${MC_TOOLS.FIND_FILES}\\` instead.`);\n }\n\n if (!denied.has(MC_TOOLS.SEARCH_CONTENT)) {\n readTools.push(`\n**${MC_TOOLS.SEARCH_CONTENT}** — Search file contents using regex\n- Preferred for content search (finding functions, variables, error messages, imports, etc.)\n- Use \\`path\\` to filter by directory or glob pattern. Supports \\`contextLines\\`, \\`caseSensitive\\`, and \\`maxCount\\`.\n- Example: Find a function: \\`{ pattern: \"function handleSubmit\", path: \"**/*.ts\" }\\`\n- Example: Find imports: \\`{ pattern: \"from ['\\\\\"\\\\]express['\\\\\"\\\\]\", path: \"**/*.ts\" }\\`\n- Respects .gitignore by default.`);\n }\n\n if (!denied.has(MC_TOOLS.FIND_FILES)) {\n readTools.push(`\n**${MC_TOOLS.FIND_FILES}** — List files and directories as a tree\n- Preferred for exploring project structure and finding files by pattern.\n- Returns tree-style output. Respects .gitignore by default.\n- Example: List project root: \\`{ path: \"./\" }\\`\n- Example: Find test files: \\`{ path: \"./src\", pattern: \"**/*.test.ts\" }\\`\n- Example: Find config files: \\`{ pattern: \"*.config.{js,ts,json}\" }\\``);\n }\n\n if (!denied.has(MC_TOOLS.EXECUTE_COMMAND)) {\n readTools.push(`\n**${MC_TOOLS.EXECUTE_COMMAND}** — Run shell commands\n- Use for: git, npm/pnpm, docker, build tools, test runners, and other terminal operations.\n- Prefer dedicated tools for: file reading (${MC_TOOLS.VIEW}), file search (${MC_TOOLS.SEARCH_CONTENT}/${MC_TOOLS.FIND_FILES}), file editing (${MC_TOOLS.STRING_REPLACE_LSP}/${MC_TOOLS.WRITE_FILE}).\n- Commands have a 30-second default timeout. Use \\`timeout\\` for longer commands, \\`cwd\\` for working directory.\n- Use the \\`tail\\` parameter or pipe to \\`| tail -N\\` to limit output — the full output streams to the user, only the tail is returned to you. If you're building any kind of package you should be tailing.\n- Good: Run independent commands in parallel when possible.\n- Bad: Running \\`cat file.txt\\` — use the ${MC_TOOLS.VIEW} tool instead.`);\n }\n\n if (!denied.has(MC_TOOLS.LSP_INSPECT)) {\n readTools.push(`\n**${MC_TOOLS.LSP_INSPECT}** — Inspect code using Language Server Protocol\n- Use this for type information, hover docs, go-to-definition, and finding implementations for a symbol.\n- Best when you already know the file and line and need semantic code intelligence rather than raw file contents.\n- Input: \\`path\\` (absolute file path), \\`line\\` (1-indexed line number), \\`match\\` (the exact line content with exactly one \\`<<<\\` cursor marker).\n- Output includes: \\`hover\\`, \\`definition\\` (compact location with preview), and \\`implementation\\` (compact usage/implementation locations).\n- Example: \\`{ path: \"/abs/path/src/foo.ts\", line: 10, match: \"const foo = <<<bar()\" }\\` — inspect the symbol at the \\`<<<\\` position.\n- Use \\`${MC_TOOLS.VIEW}\\` when you need to read the implementation or surrounding code.\n- Use \\`${MC_TOOLS.SEARCH_CONTENT}\\` or \\`${MC_TOOLS.FIND_FILES}\\` first if you do not yet know where the symbol is.`);\n }\n\n if (!denied.has(MC_TOOLS.NOTIFICATION_INBOX)) {\n readTools.push(`\n**${MC_TOOLS.NOTIFICATION_INBOX}** — Inspect and manage notification inbox records\n- Use this when a \\`<notification-summary>\\` says pending notifications exist.\n- Use \\`{ \"action\": \"list\", \"status\": \"pending\" }\\` or \\`{ \"action\": \"search\", \"query\": \"...\" }\\` to find notification records for the current thread.\n- Use \\`read\\` to deliver unread notification signals into the chat and mark them seen; the tool result summarizes the count instead of exposing notification contents.\n- Use \\`dismiss\\` or \\`archive\\` only when the user asks or the notification is no longer relevant.`);\n }\n\n if (readTools.length > 0) {\n sections.push(readTools.join('\\n'));\n }\n\n // --- Write/edit tools (build & fast only) ---\n\n if (modeId !== 'plan') {\n const writeTools: string[] = [];\n\n if (!denied.has(MC_TOOLS.STRING_REPLACE_LSP)) {\n writeTools.push(`\n**${MC_TOOLS.STRING_REPLACE_LSP}** — Edit files by replacing exact text\n- You MUST read a file with \\`${MC_TOOLS.VIEW}\\` before editing it.\n- \\`old_string\\` must be an exact match of existing text in the file.\n- Provide enough surrounding context in \\`old_string\\` to make it unique.\n- Use \\`replace_all: true\\` to replace all occurrences (default: false, requires unique match).\n- For creating new files, use \\`${MC_TOOLS.WRITE_FILE}\\` instead.\n- Good: Include 2-3 lines of surrounding context to ensure uniqueness.\n- Bad: Using just \\`return true;\\` — too common, will match multiple places.`);\n }\n\n if (!denied.has(MC_TOOLS.WRITE_FILE)) {\n writeTools.push(`\n**${MC_TOOLS.WRITE_FILE}** — Create new files or overwrite existing ones\n- Use this to create new files.\n- If overwriting an existing file, you MUST have read it first with \\`${MC_TOOLS.VIEW}\\`.\n- Prefer editing existing files over creating new ones.`);\n }\n\n if (writeTools.length > 0) {\n sections.push(writeTools.join('\\n'));\n }\n }\n\n // --- Web tools (all modes, conditionally available) ---\n\n if (options.hasWebSearch) {\n const webTools: string[] = [];\n if (!denied.has('web_search')) webTools.push('**web_search**');\n if (!denied.has('web_extract')) webTools.push('**web_extract**');\n if (webTools.length > 0) {\n sections.push(`\n${webTools.join(' / ')} — Search the web / extract page content\n- Use for looking up documentation, error messages, package APIs.`);\n }\n }\n\n // --- Task management tools (all modes) ---\n\n const taskTools: string[] = [];\n const canUpdateTask = !denied.has('task_update');\n const canCompleteTask = !denied.has('task_complete');\n const canCheckTasks = !denied.has('task_check');\n const canWriteTasks = !denied.has('task_write');\n const patchToolGuidance =\n canUpdateTask && canCompleteTask\n ? '- Prefer task_update or task_complete when changing one existing task.'\n : canUpdateTask\n ? '- Prefer task_update when changing one existing task.'\n : canCompleteTask\n ? '- Prefer task_complete when marking one existing task completed.'\n : '- Use task_write with the full task list when changing existing tasks.';\n\n if (canWriteTasks) {\n taskTools.push(`\n**task_write** — Track tasks for complex multi-step work\n- Use when a task requires 3 or more distinct steps or actions.\n- Use task_write to create the initial task list or replace the whole list after replanning.\n- Each task has: id (stable identifier), content (imperative form), status (pending, in_progress, or completed), activeForm (present continuous form shown during execution).\n- Keep task IDs stable across updates. If you omit IDs, the tool result returns generated IDs.\n${patchToolGuidance}\n- Mark tasks \\`in_progress\\` BEFORE starting work. Only ONE task should be \\`in_progress\\` at a time.\n- Mark tasks \\`completed\\` IMMEDIATELY after finishing each task. Do not batch completions.`);\n }\n\n if (canUpdateTask) {\n taskTools.push(`\n**task_update** — Patch one tracked task by ID\n- Use this for targeted changes to one existing task.\n- Provide the task ID and only the fields that changed: content, status, or activeForm.`);\n }\n\n if (canCompleteTask) {\n const idSource = canCheckTasks\n ? 'Use task_check if you need the current IDs before completing a task.'\n : canWriteTasks\n ? 'Use IDs returned by task_write.'\n : 'Use only task IDs already visible in the current task list.';\n taskTools.push(`\n**task_complete** — Mark one tracked task completed by ID\n- Use this immediately after finishing a tracked task.\n- ${idSource}`);\n }\n\n if (canCheckTasks) {\n taskTools.push(`\n**task_check** — Check completion status of tasks\n- Use this BEFORE finishing tracked work to verify all tasks are completed.\n- Returns a readable status summary plus structured fields: tasks, summary, incompleteTasks, and isError.\n- summary includes total, completed, inProgress, pending, incomplete, hasTasks, and allCompleted.\n- Use summary.allCompleted to decide whether tracked work is complete; if summary.hasTasks is false, no task list is currently tracked.\n- If any tasks remain incomplete, continue working on them.\n- IMPORTANT: Always check task completion before ending work on a complex task.`);\n }\n\n if (!denied.has('ask_user')) {\n taskTools.push(`\n**ask_user** — Ask the user a structured question\n- Use when you need clarification, want to validate assumptions, or need the user to make a decision.\n- Provide clear, specific questions. End with a question mark.\n- Include options (2-4 choices) for structured decisions. Omit options for open-ended questions.\n- Don't use this for simple yes/no — just ask in your text response.`);\n }\n\n if (taskTools.length > 0) {\n sections.push(taskTools.join('\\n'));\n }\n\n // --- Plan tools (plan mode) ---\n\n if (modeId === 'plan' && !denied.has('submit_plan')) {\n sections.push(`\n**submit_plan** — Submit a completed implementation plan for user review\n- Call this tool when your plan is complete. Do NOT just describe your plan in text — you MUST call this tool.\n- The plan will be rendered as markdown and the user can approve, reject, or request changes.\n- On approval, the system automatically switches to the default mode so you can implement.\n- Takes one argument: \\`path\\` (the plan markdown file you wrote under \\`.mastracode/plans/\\`). Do NOT pass the plan body — it lives in the file.`);\n }\n\n if (modeId === 'plan') {\n sections.push(`\n**Plan file access** — Your plan lives in a markdown file under \\`.mastracode/plans/\\` (e.g. \\`add-dark-mode-toggle.md\\`)\n- Use \\`write_file\\` to create the plan file, \\`view\\` to read it, and \\`string_replace_lsp\\` for targeted edits.\n- On first submission: write the plan to the file, then call \\`submit_plan\\` with its \\`path\\`.\n- On revision: read the existing file, edit specific sections, re-read, then call \\`submit_plan\\` with the same \\`path\\`.\n- If a plan file already exists, you previously submitted it — read it before revising.`);\n }\n\n // --- Subagent tool (all modes) ---\n\n if (!denied.has('subagent')) {\n sections.push(`\n**subagent** — Delegate a focused task to a specialized subagent\n- Only use subagents when you will spawn **multiple subagents in parallel**. If you only need one task done, do it yourself.\n- Subagent outputs are **untrusted**. Always review and verify the results.`);\n }\n\n return sections.join('\\n');\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * SandboxFilesystem
3
+ *
4
+ * A `WorkspaceFilesystem` that stores files inside a remote `MastraSandbox`
5
+ * (e.g. a Railway VM) rather than on the server host. File operations are
6
+ * implemented by shelling out through the sandbox's `executeCommand`, so the
7
+ * agent's file tools and command tools share one VM and one view of the repo.
8
+ *
9
+ * Paths are workspace-relative (`/src/foo.ts`) and resolve under the sandbox
10
+ * working directory (`basePath`). A traversal guard rejects any path that
11
+ * escapes the workdir, mirroring `LocalFilesystem`'s contained mode.
12
+ *
13
+ * Reads/writes use base64 over the wire so binary content survives the shell.
14
+ */
15
+ import type { CopyOptions, FileContent, FileEntry, FileStat, FilesystemInfo, ListOptions, ProviderStatus, ReadOptions, RemoveOptions, WorkspaceFilesystem, WriteOptions } from '@mastra/core/workspace';
16
+ /** Minimal command result shape we depend on. */
17
+ export interface SandboxCommandResult {
18
+ exitCode: number;
19
+ stdout: string;
20
+ stderr: string;
21
+ }
22
+ /** Minimal sandbox surface the filesystem needs. */
23
+ export interface SandboxExec {
24
+ readonly id: string;
25
+ executeCommand(command: string, args?: string[], options?: {
26
+ timeout?: number;
27
+ }): Promise<SandboxCommandResult>;
28
+ }
29
+ export interface SandboxFilesystemOptions {
30
+ /** Live sandbox to run commands in. */
31
+ sandbox: SandboxExec;
32
+ /** Absolute path inside the sandbox that is the workspace root. */
33
+ workdir: string;
34
+ /** Optional stable id; defaults to a sandbox-derived id. */
35
+ id?: string;
36
+ }
37
+ export declare class SandboxFilesystem implements WorkspaceFilesystem {
38
+ readonly id: string;
39
+ readonly name = "SandboxFilesystem";
40
+ readonly provider = "sandbox";
41
+ readonly basePath: string;
42
+ status: ProviderStatus;
43
+ private readonly sandbox;
44
+ constructor(options: SandboxFilesystemOptions);
45
+ /**
46
+ * Resolve a workspace path to an absolute path inside the sandbox, enforcing
47
+ * that it stays within the workdir.
48
+ */
49
+ private resolve;
50
+ resolveAbsolutePath(inputPath: string): string | undefined;
51
+ private exec;
52
+ /**
53
+ * Lexical guard catches `..` traversal, but a symlink inside the workdir can
54
+ * still point outside it. After resolving a path that refers to an existing
55
+ * entry, verify its realpath is still contained in the workdir.
56
+ */
57
+ private assertContainedRealpath;
58
+ /**
59
+ * Guard for write destinations. The lexical guard catches `..`, but a symlink
60
+ * inside the workdir can redirect a write outside it. For an existing target
61
+ * we check its realpath; for a not-yet-existing target we check the realpath
62
+ * of its nearest existing ancestor directory, since a symlinked parent is the
63
+ * escape vector (e.g. `link -> /etc` then writing `link/passwd`).
64
+ */
65
+ private assertContainedDest;
66
+ private execOk;
67
+ readFile(path: string, options?: ReadOptions): Promise<string | Buffer>;
68
+ writeFile(path: string, content: FileContent, options?: WriteOptions): Promise<void>;
69
+ appendFile(path: string, content: FileContent): Promise<void>;
70
+ deleteFile(path: string, options?: RemoveOptions): Promise<void>;
71
+ copyFile(src: string, dest: string, options?: CopyOptions): Promise<void>;
72
+ moveFile(src: string, dest: string, options?: CopyOptions): Promise<void>;
73
+ mkdir(path: string, options?: {
74
+ recursive?: boolean;
75
+ }): Promise<void>;
76
+ rmdir(path: string, options?: RemoveOptions): Promise<void>;
77
+ readdir(path: string, options?: ListOptions): Promise<FileEntry[]>;
78
+ private parseListOutput;
79
+ private parseFindOutput;
80
+ private matchesExtension;
81
+ exists(path: string): Promise<boolean>;
82
+ stat(path: string): Promise<FileStat>;
83
+ init(): Promise<void>;
84
+ destroy(): Promise<void>;
85
+ isReady(): Promise<boolean>;
86
+ getInfo(): FilesystemInfo;
87
+ getInstructions(): string;
88
+ }
89
+ //# sourceMappingURL=sandbox-filesystem.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-filesystem.d.ts","sourceRoot":"","sources":["../../src/agents/sandbox-filesystem.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,268 @@
1
+ import { posix as posixPath } from "node:path";
2
+ const COMMAND_TIMEOUT_MS = 3e4;
3
+ function shellQuote(value) {
4
+ return `'${value.replace(/'/g, `'\\''`)}'`;
5
+ }
6
+ function isFileContentString(content) {
7
+ return typeof content === "string";
8
+ }
9
+ function toBuffer(content) {
10
+ if (isFileContentString(content)) return Buffer.from(content, "utf8");
11
+ return Buffer.from(content);
12
+ }
13
+ class SandboxFilesystem {
14
+ id;
15
+ name = "SandboxFilesystem";
16
+ provider = "sandbox";
17
+ basePath;
18
+ status = "ready";
19
+ sandbox;
20
+ constructor(options) {
21
+ this.sandbox = options.sandbox;
22
+ this.basePath = options.workdir;
23
+ this.id = options.id ?? `sandbox-fs:${options.sandbox.id}`;
24
+ }
25
+ // ── Path handling ──────────────────────────────────────────────────────
26
+ /**
27
+ * Resolve a workspace path to an absolute path inside the sandbox, enforcing
28
+ * that it stays within the workdir.
29
+ */
30
+ resolve(inputPath) {
31
+ const rel = inputPath.startsWith("/") ? inputPath.slice(1) : inputPath;
32
+ const resolved = posixPath.normalize(posixPath.join(this.basePath, rel));
33
+ const root = posixPath.normalize(this.basePath);
34
+ if (resolved !== root && !resolved.startsWith(`${root}/`)) {
35
+ throw new Error(`Path escapes workspace root: ${inputPath}`);
36
+ }
37
+ return resolved;
38
+ }
39
+ resolveAbsolutePath(inputPath) {
40
+ return this.resolve(inputPath);
41
+ }
42
+ // ── Command helper ─────────────────────────────────────────────────────
43
+ async exec(script) {
44
+ return this.sandbox.executeCommand("sh", ["-c", script], { timeout: COMMAND_TIMEOUT_MS });
45
+ }
46
+ /**
47
+ * Lexical guard catches `..` traversal, but a symlink inside the workdir can
48
+ * still point outside it. After resolving a path that refers to an existing
49
+ * entry, verify its realpath is still contained in the workdir.
50
+ */
51
+ async assertContainedRealpath(abs, inputPath) {
52
+ const result = await this.exec(`readlink -f -- ${shellQuote(abs)} 2>/dev/null`);
53
+ const real = result.stdout.trim();
54
+ if (result.exitCode !== 0 || !real) return;
55
+ const root = posixPath.normalize(this.basePath);
56
+ if (real !== root && !real.startsWith(`${root}/`)) {
57
+ throw new Error(`Path escapes workspace root (symlink): ${inputPath}`);
58
+ }
59
+ }
60
+ /**
61
+ * Guard for write destinations. The lexical guard catches `..`, but a symlink
62
+ * inside the workdir can redirect a write outside it. For an existing target
63
+ * we check its realpath; for a not-yet-existing target we check the realpath
64
+ * of its nearest existing ancestor directory, since a symlinked parent is the
65
+ * escape vector (e.g. `link -> /etc` then writing `link/passwd`).
66
+ */
67
+ async assertContainedDest(abs, inputPath) {
68
+ await this.assertContainedRealpath(abs, inputPath);
69
+ const parent = posixPath.dirname(abs);
70
+ if (parent && parent !== abs) {
71
+ await this.assertContainedRealpath(parent, inputPath);
72
+ }
73
+ }
74
+ async execOk(script, context) {
75
+ const result = await this.exec(script);
76
+ if (result.exitCode !== 0) {
77
+ throw new Error(`${context} failed (exit ${result.exitCode}): ${result.stderr.trim() || result.stdout.trim()}`);
78
+ }
79
+ return result;
80
+ }
81
+ // ── File operations ────────────────────────────────────────────────────
82
+ async readFile(path, options) {
83
+ const abs = this.resolve(path);
84
+ await this.assertContainedRealpath(abs, path);
85
+ const result = await this.exec(`base64 < ${shellQuote(abs)}`);
86
+ if (result.exitCode !== 0) {
87
+ throw new Error(`File not found: ${path}`);
88
+ }
89
+ const buffer = Buffer.from(result.stdout.replace(/\s/g, ""), "base64");
90
+ if (options?.encoding) {
91
+ return buffer.toString(options.encoding);
92
+ }
93
+ return buffer;
94
+ }
95
+ async writeFile(path, content, options) {
96
+ const abs = this.resolve(path);
97
+ await this.assertContainedDest(abs, path);
98
+ const b64 = toBuffer(content).toString("base64");
99
+ const dir = posixPath.dirname(abs);
100
+ const mkdir = options?.recursive === false ? "" : `mkdir -p ${shellQuote(dir)} && `;
101
+ if (options?.overwrite === false) {
102
+ const exists = await this.exists(path);
103
+ if (exists) throw new Error(`File already exists: ${path}`);
104
+ }
105
+ await this.execOk(`${mkdir}printf %s ${shellQuote(b64)} | base64 -d > ${shellQuote(abs)}`, `writeFile ${path}`);
106
+ }
107
+ async appendFile(path, content) {
108
+ const abs = this.resolve(path);
109
+ await this.assertContainedDest(abs, path);
110
+ const b64 = toBuffer(content).toString("base64");
111
+ await this.execOk(
112
+ `mkdir -p ${shellQuote(posixPath.dirname(abs))} && printf %s ${shellQuote(b64)} | base64 -d >> ${shellQuote(abs)}`,
113
+ `appendFile ${path}`
114
+ );
115
+ }
116
+ async deleteFile(path, options) {
117
+ const abs = this.resolve(path);
118
+ const force = options?.force ? "-f " : "";
119
+ const result = await this.exec(`rm ${force}${shellQuote(abs)}`);
120
+ if (result.exitCode !== 0 && !options?.force) {
121
+ throw new Error(`File not found: ${path}`);
122
+ }
123
+ }
124
+ async copyFile(src, dest, options) {
125
+ const srcAbs = this.resolve(src);
126
+ const destAbs = this.resolve(dest);
127
+ await this.assertContainedRealpath(srcAbs, src);
128
+ await this.assertContainedDest(destAbs, dest);
129
+ const recursive = options?.recursive ? "-r " : "";
130
+ if (options?.overwrite === false) {
131
+ const exists = await this.exists(dest);
132
+ if (exists) throw new Error(`Destination exists: ${dest}`);
133
+ }
134
+ await this.execOk(`cp ${recursive}${shellQuote(srcAbs)} ${shellQuote(destAbs)}`, `copyFile ${src} -> ${dest}`);
135
+ }
136
+ async moveFile(src, dest, options) {
137
+ const srcAbs = this.resolve(src);
138
+ const destAbs = this.resolve(dest);
139
+ await this.assertContainedRealpath(srcAbs, src);
140
+ await this.assertContainedDest(destAbs, dest);
141
+ if (options?.overwrite === false) {
142
+ const exists = await this.exists(dest);
143
+ if (exists) throw new Error(`Destination exists: ${dest}`);
144
+ }
145
+ await this.execOk(`mv ${shellQuote(srcAbs)} ${shellQuote(destAbs)}`, `moveFile ${src} -> ${dest}`);
146
+ }
147
+ // ── Directory operations ───────────────────────────────────────────────
148
+ async mkdir(path, options) {
149
+ const abs = this.resolve(path);
150
+ await this.assertContainedDest(abs, path);
151
+ const flag = options?.recursive === false ? "" : "-p ";
152
+ await this.execOk(`mkdir ${flag}${shellQuote(abs)}`, `mkdir ${path}`);
153
+ }
154
+ async rmdir(path, options) {
155
+ const abs = this.resolve(path);
156
+ if (options?.recursive) {
157
+ const force = options?.force ? "-f " : "";
158
+ await this.execOk(`rm -r ${force}${shellQuote(abs)}`, `rmdir ${path}`);
159
+ return;
160
+ }
161
+ const result = await this.exec(`rmdir ${shellQuote(abs)}`);
162
+ if (result.exitCode !== 0 && !options?.force) {
163
+ throw new Error(`Directory not empty or not found: ${path}`);
164
+ }
165
+ }
166
+ async readdir(path, options) {
167
+ const abs = this.resolve(path);
168
+ await this.assertContainedRealpath(abs, path);
169
+ if (options?.recursive) {
170
+ const result2 = await this.exec(
171
+ `find ${shellQuote(abs)} -mindepth 1 ${options.maxDepth ? `-maxdepth ${Number(options.maxDepth)} ` : ""}-printf '%y\\t%p\\n' 2>/dev/null`
172
+ );
173
+ if (result2.exitCode !== 0) throw new Error(`Directory not found: ${path}`);
174
+ return this.parseFindOutput(result2.stdout, abs, options);
175
+ }
176
+ const result = await this.exec(
177
+ `cd ${shellQuote(abs)} 2>/dev/null && for f in * .[!.]*; do [ -e "$f" ] || continue; if [ -d "$f" ]; then echo "d $f"; else echo "f $f"; fi; done`
178
+ );
179
+ if (result.exitCode !== 0) throw new Error(`Directory not found: ${path}`);
180
+ return this.parseListOutput(result.stdout, options);
181
+ }
182
+ parseListOutput(stdout, options) {
183
+ const entries = [];
184
+ for (const line of stdout.split("\n")) {
185
+ if (!line) continue;
186
+ const tab = line.indexOf(" ");
187
+ if (tab < 0) continue;
188
+ const type = line.slice(0, tab) === "d" ? "directory" : "file";
189
+ const name = line.slice(tab + 1);
190
+ if (!name || name === "." || name === "..") continue;
191
+ if (type === "file" && !this.matchesExtension(name, options?.extension)) continue;
192
+ entries.push({ name, type });
193
+ }
194
+ return entries;
195
+ }
196
+ parseFindOutput(stdout, base, options) {
197
+ const entries = [];
198
+ for (const line of stdout.split("\n")) {
199
+ if (!line) continue;
200
+ const tab = line.indexOf(" ");
201
+ if (tab < 0) continue;
202
+ const type = line.slice(0, tab) === "d" ? "directory" : "file";
203
+ const fullPath = line.slice(tab + 1);
204
+ const name = posixPath.relative(base, fullPath);
205
+ if (!name) continue;
206
+ if (type === "file" && !this.matchesExtension(name, options?.extension)) continue;
207
+ entries.push({ name, type });
208
+ }
209
+ return entries;
210
+ }
211
+ matchesExtension(name, extension) {
212
+ if (!extension) return true;
213
+ const exts = Array.isArray(extension) ? extension : [extension];
214
+ return exts.some((ext) => name.endsWith(ext));
215
+ }
216
+ // ── Path / metadata ────────────────────────────────────────────────────
217
+ async exists(path) {
218
+ const abs = this.resolve(path);
219
+ const result = await this.exec(`test -e ${shellQuote(abs)}`);
220
+ return result.exitCode === 0;
221
+ }
222
+ async stat(path) {
223
+ const abs = this.resolve(path);
224
+ await this.assertContainedRealpath(abs, path);
225
+ const result = await this.exec(`stat -c '%F\\t%s\\t%Y\\t%W' ${shellQuote(abs)}`);
226
+ if (result.exitCode !== 0) {
227
+ throw new Error(`Path not found: ${path}`);
228
+ }
229
+ const [kind, sizeStr, mtimeStr, ctimeStr] = result.stdout.trim().split(" ");
230
+ const type = kind && kind.includes("directory") ? "directory" : "file";
231
+ const size = Number(sizeStr) || 0;
232
+ const mtime = Number(mtimeStr) || 0;
233
+ const ctime = Number(ctimeStr);
234
+ return {
235
+ name: posixPath.basename(abs),
236
+ path: `/${posixPath.relative(this.basePath, abs)}`,
237
+ type,
238
+ size: type === "directory" ? 0 : size,
239
+ modifiedAt: new Date(mtime * 1e3),
240
+ createdAt: new Date((ctime > 0 ? ctime : mtime) * 1e3)
241
+ };
242
+ }
243
+ // ── Lifecycle ──────────────────────────────────────────────────────────
244
+ async init() {
245
+ await this.execOk(`mkdir -p ${shellQuote(this.basePath)}`, "init workdir");
246
+ }
247
+ async destroy() {
248
+ }
249
+ async isReady() {
250
+ const result = await this.exec(`test -d ${shellQuote(this.basePath)}`);
251
+ return result.exitCode === 0;
252
+ }
253
+ getInfo() {
254
+ return {
255
+ id: this.id,
256
+ name: this.name,
257
+ provider: this.provider,
258
+ metadata: { basePath: this.basePath, sandboxId: this.sandbox.id }
259
+ };
260
+ }
261
+ getInstructions() {
262
+ return `Files are stored in a remote sandbox at ${this.basePath}. Use absolute workspace paths like /src/index.ts. All reads, writes and commands run inside the same sandbox.`;
263
+ }
264
+ }
265
+ export {
266
+ SandboxFilesystem
267
+ };
268
+ //# sourceMappingURL=sandbox-filesystem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/agents/sandbox-filesystem.ts"],"sourcesContent":["/**\n * SandboxFilesystem\n *\n * A `WorkspaceFilesystem` that stores files inside a remote `MastraSandbox`\n * (e.g. a Railway VM) rather than on the server host. File operations are\n * implemented by shelling out through the sandbox's `executeCommand`, so the\n * agent's file tools and command tools share one VM and one view of the repo.\n *\n * Paths are workspace-relative (`/src/foo.ts`) and resolve under the sandbox\n * working directory (`basePath`). A traversal guard rejects any path that\n * escapes the workdir, mirroring `LocalFilesystem`'s contained mode.\n *\n * Reads/writes use base64 over the wire so binary content survives the shell.\n */\n\nimport { posix as posixPath } from 'node:path';\nimport type {\n CopyOptions,\n FileContent,\n FileEntry,\n FileStat,\n FilesystemInfo,\n ListOptions,\n ProviderStatus,\n ReadOptions,\n RemoveOptions,\n WorkspaceFilesystem,\n WriteOptions,\n} from '@mastra/core/workspace';\n\n/** Minimal command result shape we depend on. */\nexport interface SandboxCommandResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n}\n\n/** Minimal sandbox surface the filesystem needs. */\nexport interface SandboxExec {\n readonly id: string;\n executeCommand(command: string, args?: string[], options?: { timeout?: number }): Promise<SandboxCommandResult>;\n}\n\nexport interface SandboxFilesystemOptions {\n /** Live sandbox to run commands in. */\n sandbox: SandboxExec;\n /** Absolute path inside the sandbox that is the workspace root. */\n workdir: string;\n /** Optional stable id; defaults to a sandbox-derived id. */\n id?: string;\n}\n\n/** Default per-command deadline so a hung sandbox can't block file tools forever. */\nconst COMMAND_TIMEOUT_MS = 30_000;\n\n/** Single-quote a string for safe POSIX shell interpolation. */\nfunction shellQuote(value: string): string {\n return `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n\nfunction isFileContentString(content: FileContent): content is string {\n return typeof content === 'string';\n}\n\nfunction toBuffer(content: FileContent): Buffer {\n if (isFileContentString(content)) return Buffer.from(content, 'utf8');\n return Buffer.from(content);\n}\n\nexport class SandboxFilesystem implements WorkspaceFilesystem {\n readonly id: string;\n readonly name = 'SandboxFilesystem';\n readonly provider = 'sandbox';\n readonly basePath: string;\n status: ProviderStatus = 'ready';\n\n private readonly sandbox: SandboxExec;\n\n constructor(options: SandboxFilesystemOptions) {\n this.sandbox = options.sandbox;\n this.basePath = options.workdir;\n this.id = options.id ?? `sandbox-fs:${options.sandbox.id}`;\n }\n\n // ── Path handling ──────────────────────────────────────────────────────\n\n /**\n * Resolve a workspace path to an absolute path inside the sandbox, enforcing\n * that it stays within the workdir.\n */\n private resolve(inputPath: string): string {\n const rel = inputPath.startsWith('/') ? inputPath.slice(1) : inputPath;\n const resolved = posixPath.normalize(posixPath.join(this.basePath, rel));\n const root = posixPath.normalize(this.basePath);\n if (resolved !== root && !resolved.startsWith(`${root}/`)) {\n throw new Error(`Path escapes workspace root: ${inputPath}`);\n }\n return resolved;\n }\n\n resolveAbsolutePath(inputPath: string): string | undefined {\n return this.resolve(inputPath);\n }\n\n // ── Command helper ─────────────────────────────────────────────────────\n\n private async exec(script: string): Promise<SandboxCommandResult> {\n return this.sandbox.executeCommand('sh', ['-c', script], { timeout: COMMAND_TIMEOUT_MS });\n }\n\n /**\n * Lexical guard catches `..` traversal, but a symlink inside the workdir can\n * still point outside it. After resolving a path that refers to an existing\n * entry, verify its realpath is still contained in the workdir.\n */\n private async assertContainedRealpath(abs: string, inputPath: string): Promise<void> {\n const result = await this.exec(`readlink -f -- ${shellQuote(abs)} 2>/dev/null`);\n const real = result.stdout.trim();\n // If readlink couldn't resolve (path doesn't exist yet), nothing to check.\n if (result.exitCode !== 0 || !real) return;\n const root = posixPath.normalize(this.basePath);\n if (real !== root && !real.startsWith(`${root}/`)) {\n throw new Error(`Path escapes workspace root (symlink): ${inputPath}`);\n }\n }\n\n /**\n * Guard for write destinations. The lexical guard catches `..`, but a symlink\n * inside the workdir can redirect a write outside it. For an existing target\n * we check its realpath; for a not-yet-existing target we check the realpath\n * of its nearest existing ancestor directory, since a symlinked parent is the\n * escape vector (e.g. `link -> /etc` then writing `link/passwd`).\n */\n private async assertContainedDest(abs: string, inputPath: string): Promise<void> {\n // First check the target itself (covers overwriting an existing symlink).\n await this.assertContainedRealpath(abs, inputPath);\n // Then check the parent directory's realpath; readlink -f resolves the\n // nearest existing ancestor when the leaf doesn't exist yet.\n const parent = posixPath.dirname(abs);\n if (parent && parent !== abs) {\n await this.assertContainedRealpath(parent, inputPath);\n }\n }\n\n private async execOk(script: string, context: string): Promise<SandboxCommandResult> {\n const result = await this.exec(script);\n if (result.exitCode !== 0) {\n throw new Error(`${context} failed (exit ${result.exitCode}): ${result.stderr.trim() || result.stdout.trim()}`);\n }\n return result;\n }\n\n // ── File operations ────────────────────────────────────────────────────\n\n async readFile(path: string, options?: ReadOptions): Promise<string | Buffer> {\n const abs = this.resolve(path);\n await this.assertContainedRealpath(abs, path);\n const result = await this.exec(`base64 < ${shellQuote(abs)}`);\n if (result.exitCode !== 0) {\n throw new Error(`File not found: ${path}`);\n }\n const buffer = Buffer.from(result.stdout.replace(/\\s/g, ''), 'base64');\n if (options?.encoding) {\n return buffer.toString(options.encoding);\n }\n return buffer;\n }\n\n async writeFile(path: string, content: FileContent, options?: WriteOptions): Promise<void> {\n const abs = this.resolve(path);\n await this.assertContainedDest(abs, path);\n const b64 = toBuffer(content).toString('base64');\n const dir = posixPath.dirname(abs);\n const mkdir = options?.recursive === false ? '' : `mkdir -p ${shellQuote(dir)} && `;\n if (options?.overwrite === false) {\n const exists = await this.exists(path);\n if (exists) throw new Error(`File already exists: ${path}`);\n }\n await this.execOk(`${mkdir}printf %s ${shellQuote(b64)} | base64 -d > ${shellQuote(abs)}`, `writeFile ${path}`);\n }\n\n async appendFile(path: string, content: FileContent): Promise<void> {\n const abs = this.resolve(path);\n await this.assertContainedDest(abs, path);\n const b64 = toBuffer(content).toString('base64');\n await this.execOk(\n `mkdir -p ${shellQuote(posixPath.dirname(abs))} && printf %s ${shellQuote(b64)} | base64 -d >> ${shellQuote(abs)}`,\n `appendFile ${path}`,\n );\n }\n\n async deleteFile(path: string, options?: RemoveOptions): Promise<void> {\n const abs = this.resolve(path);\n const force = options?.force ? '-f ' : '';\n const result = await this.exec(`rm ${force}${shellQuote(abs)}`);\n if (result.exitCode !== 0 && !options?.force) {\n throw new Error(`File not found: ${path}`);\n }\n }\n\n async copyFile(src: string, dest: string, options?: CopyOptions): Promise<void> {\n const srcAbs = this.resolve(src);\n const destAbs = this.resolve(dest);\n await this.assertContainedRealpath(srcAbs, src);\n await this.assertContainedDest(destAbs, dest);\n const recursive = options?.recursive ? '-r ' : '';\n if (options?.overwrite === false) {\n const exists = await this.exists(dest);\n if (exists) throw new Error(`Destination exists: ${dest}`);\n }\n await this.execOk(`cp ${recursive}${shellQuote(srcAbs)} ${shellQuote(destAbs)}`, `copyFile ${src} -> ${dest}`);\n }\n\n async moveFile(src: string, dest: string, options?: CopyOptions): Promise<void> {\n const srcAbs = this.resolve(src);\n const destAbs = this.resolve(dest);\n await this.assertContainedRealpath(srcAbs, src);\n await this.assertContainedDest(destAbs, dest);\n if (options?.overwrite === false) {\n const exists = await this.exists(dest);\n if (exists) throw new Error(`Destination exists: ${dest}`);\n }\n await this.execOk(`mv ${shellQuote(srcAbs)} ${shellQuote(destAbs)}`, `moveFile ${src} -> ${dest}`);\n }\n\n // ── Directory operations ───────────────────────────────────────────────\n\n async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n const abs = this.resolve(path);\n await this.assertContainedDest(abs, path);\n const flag = options?.recursive === false ? '' : '-p ';\n await this.execOk(`mkdir ${flag}${shellQuote(abs)}`, `mkdir ${path}`);\n }\n\n async rmdir(path: string, options?: RemoveOptions): Promise<void> {\n const abs = this.resolve(path);\n if (options?.recursive) {\n const force = options?.force ? '-f ' : '';\n await this.execOk(`rm -r ${force}${shellQuote(abs)}`, `rmdir ${path}`);\n return;\n }\n const result = await this.exec(`rmdir ${shellQuote(abs)}`);\n if (result.exitCode !== 0 && !options?.force) {\n throw new Error(`Directory not empty or not found: ${path}`);\n }\n }\n\n async readdir(path: string, options?: ListOptions): Promise<FileEntry[]> {\n const abs = this.resolve(path);\n await this.assertContainedRealpath(abs, path);\n if (options?.recursive) {\n // Use find for recursive listings; emit \"type\\tpath\".\n const result = await this.exec(\n `find ${shellQuote(abs)} -mindepth 1 ${options.maxDepth ? `-maxdepth ${Number(options.maxDepth)} ` : ''}-printf '%y\\\\t%p\\\\n' 2>/dev/null`,\n );\n if (result.exitCode !== 0) throw new Error(`Directory not found: ${path}`);\n return this.parseFindOutput(result.stdout, abs, options);\n }\n // Non-recursive: list with name + type via a portable loop.\n const result = await this.exec(\n `cd ${shellQuote(abs)} 2>/dev/null && for f in * .[!.]*; do [ -e \"$f\" ] || continue; if [ -d \"$f\" ]; then echo \"d\\t$f\"; else echo \"f\\t$f\"; fi; done`,\n );\n if (result.exitCode !== 0) throw new Error(`Directory not found: ${path}`);\n return this.parseListOutput(result.stdout, options);\n }\n\n private parseListOutput(stdout: string, options?: ListOptions): FileEntry[] {\n const entries: FileEntry[] = [];\n for (const line of stdout.split('\\n')) {\n if (!line) continue;\n const tab = line.indexOf('\\t');\n if (tab < 0) continue;\n const type = line.slice(0, tab) === 'd' ? 'directory' : 'file';\n const name = line.slice(tab + 1);\n if (!name || name === '.' || name === '..') continue;\n if (type === 'file' && !this.matchesExtension(name, options?.extension)) continue;\n entries.push({ name, type });\n }\n return entries;\n }\n\n private parseFindOutput(stdout: string, base: string, options?: ListOptions): FileEntry[] {\n const entries: FileEntry[] = [];\n for (const line of stdout.split('\\n')) {\n if (!line) continue;\n const tab = line.indexOf('\\t');\n if (tab < 0) continue;\n const type = line.slice(0, tab) === 'd' ? 'directory' : 'file';\n const fullPath = line.slice(tab + 1);\n const name = posixPath.relative(base, fullPath);\n if (!name) continue;\n if (type === 'file' && !this.matchesExtension(name, options?.extension)) continue;\n entries.push({ name, type });\n }\n return entries;\n }\n\n private matchesExtension(name: string, extension?: string | string[]): boolean {\n if (!extension) return true;\n const exts = Array.isArray(extension) ? extension : [extension];\n return exts.some(ext => name.endsWith(ext));\n }\n\n // ── Path / metadata ────────────────────────────────────────────────────\n\n async exists(path: string): Promise<boolean> {\n const abs = this.resolve(path);\n const result = await this.exec(`test -e ${shellQuote(abs)}`);\n return result.exitCode === 0;\n }\n\n async stat(path: string): Promise<FileStat> {\n const abs = this.resolve(path);\n await this.assertContainedRealpath(abs, path);\n // %F=type, %s=size, %X=atime, %Y=mtime (epoch seconds), %W=birth (or -1).\n const result = await this.exec(`stat -c '%F\\\\t%s\\\\t%Y\\\\t%W' ${shellQuote(abs)}`);\n if (result.exitCode !== 0) {\n throw new Error(`Path not found: ${path}`);\n }\n const [kind, sizeStr, mtimeStr, ctimeStr] = result.stdout.trim().split('\\t');\n const type = kind && kind.includes('directory') ? 'directory' : 'file';\n const size = Number(sizeStr) || 0;\n const mtime = Number(mtimeStr) || 0;\n const ctime = Number(ctimeStr);\n return {\n name: posixPath.basename(abs),\n path: `/${posixPath.relative(this.basePath, abs)}`,\n type,\n size: type === 'directory' ? 0 : size,\n modifiedAt: new Date(mtime * 1000),\n createdAt: new Date((ctime > 0 ? ctime : mtime) * 1000),\n };\n }\n\n // ── Lifecycle ──────────────────────────────────────────────────────────\n\n async init(): Promise<void> {\n await this.execOk(`mkdir -p ${shellQuote(this.basePath)}`, 'init workdir');\n }\n\n async destroy(): Promise<void> {\n // The sandbox lifecycle is owned by the caller; nothing to tear down here.\n }\n\n async isReady(): Promise<boolean> {\n const result = await this.exec(`test -d ${shellQuote(this.basePath)}`);\n return result.exitCode === 0;\n }\n\n getInfo(): FilesystemInfo {\n return {\n id: this.id,\n name: this.name,\n provider: this.provider,\n metadata: { basePath: this.basePath, sandboxId: this.sandbox.id },\n };\n }\n\n getInstructions(): string {\n return `Files are stored in a remote sandbox at ${this.basePath}. Use absolute workspace paths like /src/index.ts. All reads, writes and commands run inside the same sandbox.`;\n }\n}\n"],"mappings":"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","names":["result"]}