clawmini 0.0.1

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 (469) hide show
  1. package/.gemini/settings.json +46 -0
  2. package/.prettierrc +7 -0
  3. package/GEMINI.md +11 -0
  4. package/README.md +137 -0
  5. package/dist/adapter-discord/index.d.mts +5 -0
  6. package/dist/adapter-discord/index.d.mts.map +1 -0
  7. package/dist/adapter-discord/index.mjs +456 -0
  8. package/dist/adapter-discord/index.mjs.map +1 -0
  9. package/dist/chats-DKgTeU7i.mjs +91 -0
  10. package/dist/chats-DKgTeU7i.mjs.map +1 -0
  11. package/dist/chats-Zd_HXDHx.mjs +29 -0
  12. package/dist/chats-Zd_HXDHx.mjs.map +1 -0
  13. package/dist/cli/index.d.mts +1 -0
  14. package/dist/cli/index.mjs +850 -0
  15. package/dist/cli/index.mjs.map +1 -0
  16. package/dist/cli/lite.d.mts +1 -0
  17. package/dist/cli/lite.mjs +4434 -0
  18. package/dist/cli/lite.mjs.map +1 -0
  19. package/dist/daemon/index.d.mts +5 -0
  20. package/dist/daemon/index.d.mts.map +1 -0
  21. package/dist/daemon/index.mjs +1222 -0
  22. package/dist/daemon/index.mjs.map +1 -0
  23. package/dist/fetch-BjZVyU3Z.mjs +37 -0
  24. package/dist/fetch-BjZVyU3Z.mjs.map +1 -0
  25. package/dist/fs-B5wW0oaH.mjs +14 -0
  26. package/dist/fs-B5wW0oaH.mjs.map +1 -0
  27. package/dist/lite-Dl7WXyaH.mjs +80 -0
  28. package/dist/lite-Dl7WXyaH.mjs.map +1 -0
  29. package/dist/rolldown-runtime-95iHPtFO.mjs +18 -0
  30. package/dist/web/_app/env.js +1 -0
  31. package/dist/web/_app/immutable/assets/0.GI4C4dpV.css +1 -0
  32. package/dist/web/_app/immutable/chunks/B5abRDXp.js +1 -0
  33. package/dist/web/_app/immutable/chunks/B8yYFADm.js +1 -0
  34. package/dist/web/_app/immutable/chunks/BPy8HLo7.js +5 -0
  35. package/dist/web/_app/immutable/chunks/Bi0jeV7Q.js +1 -0
  36. package/dist/web/_app/immutable/chunks/BmUXQ3wy.js +2 -0
  37. package/dist/web/_app/immutable/chunks/C3k55nDF.js +1 -0
  38. package/dist/web/_app/immutable/chunks/COekwvP2.js +1 -0
  39. package/dist/web/_app/immutable/chunks/CSvS_NwK.js +1 -0
  40. package/dist/web/_app/immutable/chunks/CpaGRn9L.js +1 -0
  41. package/dist/web/_app/immutable/chunks/CyNaE55B.js +1 -0
  42. package/dist/web/_app/immutable/chunks/DG5RZBw-.js +2 -0
  43. package/dist/web/_app/immutable/chunks/Dc-UOHw9.js +1 -0
  44. package/dist/web/_app/immutable/chunks/DcrmIfTj.js +1 -0
  45. package/dist/web/_app/immutable/chunks/ZkLyk0mE.js +1 -0
  46. package/dist/web/_app/immutable/entry/app.B-vZe7PN.js +2 -0
  47. package/dist/web/_app/immutable/entry/start.oP1AgKhs.js +1 -0
  48. package/dist/web/_app/immutable/nodes/0.B5WFN0zw.js +1 -0
  49. package/dist/web/_app/immutable/nodes/1.D1wtJb2k.js +1 -0
  50. package/dist/web/_app/immutable/nodes/2.CK3CLC0f.js +1 -0
  51. package/dist/web/_app/immutable/nodes/3.BB5wCoBf.js +4 -0
  52. package/dist/web/_app/immutable/nodes/4.Dr2jvAXK.js +1 -0
  53. package/dist/web/_app/immutable/nodes/5.BJl7oM3b.js +1 -0
  54. package/dist/web/_app/version.json +1 -0
  55. package/dist/web/index.html +37 -0
  56. package/dist/web/robots.txt +3 -0
  57. package/dist/workspace-CSgfo_2J.mjs +383 -0
  58. package/dist/workspace-CSgfo_2J.mjs.map +1 -0
  59. package/docs/01_chats/development_log.md +36 -0
  60. package/docs/01_chats/notes.md +27 -0
  61. package/docs/01_chats/prd.md +47 -0
  62. package/docs/01_chats/questions.md +19 -0
  63. package/docs/01_chats/tickets.md +67 -0
  64. package/docs/02_sessions/development_log.md +79 -0
  65. package/docs/02_sessions/notes.md +40 -0
  66. package/docs/02_sessions/prd.md +75 -0
  67. package/docs/02_sessions/questions.md +7 -0
  68. package/docs/02_sessions/tickets.md +68 -0
  69. package/docs/03_web_interface/development_log.md +60 -0
  70. package/docs/03_web_interface/notes.md +29 -0
  71. package/docs/03_web_interface/prd.md +42 -0
  72. package/docs/03_web_interface/questions.md +8 -0
  73. package/docs/03_web_interface/tickets.md +59 -0
  74. package/docs/04_agents/development_log.md +54 -0
  75. package/docs/04_agents/notes.md +45 -0
  76. package/docs/04_agents/prd.md +47 -0
  77. package/docs/04_agents/questions.md +13 -0
  78. package/docs/04_agents/tickets.md +107 -0
  79. package/docs/05_routers/development_log.md +13 -0
  80. package/docs/05_routers/notes.md +40 -0
  81. package/docs/05_routers/prd.md +55 -0
  82. package/docs/05_routers/questions.md +21 -0
  83. package/docs/05_routers/tickets.md +109 -0
  84. package/docs/06_agent_templates/development_log.md +38 -0
  85. package/docs/06_agent_templates/notes.md +25 -0
  86. package/docs/06_agent_templates/prd.md +34 -0
  87. package/docs/06_agent_templates/questions.md +11 -0
  88. package/docs/06_agent_templates/tickets.md +49 -0
  89. package/docs/06_cron/development_log.md +51 -0
  90. package/docs/06_cron/notes.md +14 -0
  91. package/docs/06_cron/prd.md +92 -0
  92. package/docs/06_cron/questions.md +15 -0
  93. package/docs/06_cron/tickets.md +75 -0
  94. package/docs/07_web_chat_ux/development_log.md +30 -0
  95. package/docs/07_web_chat_ux/notes.md +25 -0
  96. package/docs/07_web_chat_ux/prd.md +46 -0
  97. package/docs/07_web_chat_ux/questions.md +7 -0
  98. package/docs/07_web_chat_ux/tickets.md +48 -0
  99. package/docs/08_agent_api/development_log.md +52 -0
  100. package/docs/08_agent_api/notes.md +31 -0
  101. package/docs/08_agent_api/prd.md +56 -0
  102. package/docs/08_agent_api/questions.md +14 -0
  103. package/docs/08_agent_api/tickets.md +104 -0
  104. package/docs/09_agent_fallbacks/development_log.md +52 -0
  105. package/docs/09_agent_fallbacks/notes.md +40 -0
  106. package/docs/09_agent_fallbacks/prd.md +55 -0
  107. package/docs/09_agent_fallbacks/questions.md +10 -0
  108. package/docs/09_agent_fallbacks/tickets.md +88 -0
  109. package/docs/09_discord_adapter/development_log.md +95 -0
  110. package/docs/09_discord_adapter/notes.md +18 -0
  111. package/docs/09_discord_adapter/prd.md +57 -0
  112. package/docs/09_discord_adapter/questions.md +16 -0
  113. package/docs/09_discord_adapter/tickets.md +116 -0
  114. package/docs/10_file_attachments/development_log.md +55 -0
  115. package/docs/10_file_attachments/notes.md +59 -0
  116. package/docs/10_file_attachments/prd.md +73 -0
  117. package/docs/10_file_attachments/questions.md +15 -0
  118. package/docs/10_file_attachments/tickets.md +88 -0
  119. package/docs/11_message_verbosity/development_log.md +43 -0
  120. package/docs/11_message_verbosity/notes.md +26 -0
  121. package/docs/11_message_verbosity/prd.md +44 -0
  122. package/docs/11_message_verbosity/questions.md +8 -0
  123. package/docs/11_message_verbosity/tickets.md +33 -0
  124. package/docs/12_environments/development_log.md +43 -0
  125. package/docs/12_environments/notes.md +45 -0
  126. package/docs/12_environments/prd.md +113 -0
  127. package/docs/12_environments/questions.md +17 -0
  128. package/docs/12_environments/tickets.md +87 -0
  129. package/docs/12_setup_flow_improvements/development_log.md +40 -0
  130. package/docs/12_setup_flow_improvements/notes.md +34 -0
  131. package/docs/12_setup_flow_improvements/prd.md +35 -0
  132. package/docs/12_setup_flow_improvements/questions.md +8 -0
  133. package/docs/12_setup_flow_improvements/tickets.md +122 -0
  134. package/docs/13_discord_typing_indicators/development_log.md +38 -0
  135. package/docs/13_discord_typing_indicators/notes.md +18 -0
  136. package/docs/13_discord_typing_indicators/prd.md +41 -0
  137. package/docs/13_discord_typing_indicators/questions.md +6 -0
  138. package/docs/13_discord_typing_indicators/tickets.md +60 -0
  139. package/docs/14_interruptions/development_log.md +50 -0
  140. package/docs/14_interruptions/notes.md +38 -0
  141. package/docs/14_interruptions/prd.md +46 -0
  142. package/docs/14_interruptions/questions.md +12 -0
  143. package/docs/14_interruptions/tickets.md +69 -0
  144. package/docs/15_sandbox_policies/development_log.md +95 -0
  145. package/docs/15_sandbox_policies/notes.md +33 -0
  146. package/docs/15_sandbox_policies/prd.md +163 -0
  147. package/docs/15_sandbox_policies/questions.md +10 -0
  148. package/docs/15_sandbox_policies/tickets.md +196 -0
  149. package/docs/CHECKS.md +9 -0
  150. package/docs/guides/discord_adapter_setup.md +69 -0
  151. package/docs/guides/sandbox_policies.md +76 -0
  152. package/eslint.config.js +47 -0
  153. package/napkin.md +21 -0
  154. package/package.json +50 -0
  155. package/scripts/create_worktree.sh +49 -0
  156. package/scripts/get_pr_comments.sh +36 -0
  157. package/src/adapter-discord/client.test.ts +65 -0
  158. package/src/adapter-discord/client.ts +41 -0
  159. package/src/adapter-discord/config.test.ts +156 -0
  160. package/src/adapter-discord/config.ts +61 -0
  161. package/src/adapter-discord/forwarder.test.ts +493 -0
  162. package/src/adapter-discord/forwarder.ts +246 -0
  163. package/src/adapter-discord/index.test.ts +399 -0
  164. package/src/adapter-discord/index.ts +147 -0
  165. package/src/adapter-discord/state.test.ts +65 -0
  166. package/src/adapter-discord/state.ts +44 -0
  167. package/src/cli/client.ts +46 -0
  168. package/src/cli/commands/agents.ts +138 -0
  169. package/src/cli/commands/chats.ts +79 -0
  170. package/src/cli/commands/down.ts +32 -0
  171. package/src/cli/commands/environments.ts +39 -0
  172. package/src/cli/commands/export-lite.ts +62 -0
  173. package/src/cli/commands/init.ts +79 -0
  174. package/src/cli/commands/jobs.ts +141 -0
  175. package/src/cli/commands/messages.ts +103 -0
  176. package/src/cli/commands/up.ts +26 -0
  177. package/src/cli/commands/web-api/agents.ts +138 -0
  178. package/src/cli/commands/web-api/chats.ts +213 -0
  179. package/src/cli/commands/web-api/utils.ts +27 -0
  180. package/src/cli/commands/web.ts +105 -0
  181. package/src/cli/e2e/adapter-discord.test.ts +76 -0
  182. package/src/cli/e2e/agents.test.ts +140 -0
  183. package/src/cli/e2e/basic.test.ts +43 -0
  184. package/src/cli/e2e/cron.test.ts +132 -0
  185. package/src/cli/e2e/daemon.test.ts +293 -0
  186. package/src/cli/e2e/environments.test.ts +66 -0
  187. package/src/cli/e2e/export-lite-func.test.ts +155 -0
  188. package/src/cli/e2e/export-lite.test.ts +51 -0
  189. package/src/cli/e2e/fallbacks.test.ts +169 -0
  190. package/src/cli/e2e/global-setup.ts +15 -0
  191. package/src/cli/e2e/init.test.ts +70 -0
  192. package/src/cli/e2e/messages.test.ts +294 -0
  193. package/src/cli/e2e/requests.test.ts +165 -0
  194. package/src/cli/e2e/utils.ts +66 -0
  195. package/src/cli/index.test.ts +7 -0
  196. package/src/cli/index.ts +29 -0
  197. package/src/cli/lite.ts +247 -0
  198. package/src/cli/utils.ts +4 -0
  199. package/src/daemon/auth.test.ts +50 -0
  200. package/src/daemon/auth.ts +69 -0
  201. package/src/daemon/chats.ts +26 -0
  202. package/src/daemon/cron.test.ts +28 -0
  203. package/src/daemon/cron.ts +159 -0
  204. package/src/daemon/events.ts +15 -0
  205. package/src/daemon/index.ts +212 -0
  206. package/src/daemon/message-agent.test.ts +132 -0
  207. package/src/daemon/message-extraction.test.ts +166 -0
  208. package/src/daemon/message-fallbacks.test.ts +313 -0
  209. package/src/daemon/message-interruption.test.ts +125 -0
  210. package/src/daemon/message-queue.test.ts +143 -0
  211. package/src/daemon/message-router.test.ts +106 -0
  212. package/src/daemon/message-session.test.ts +127 -0
  213. package/src/daemon/message-test-utils.ts +41 -0
  214. package/src/daemon/message-typing.test.ts +93 -0
  215. package/src/daemon/message-verbosity.test.ts +127 -0
  216. package/src/daemon/message.ts +600 -0
  217. package/src/daemon/observation.test.ts +118 -0
  218. package/src/daemon/policy-request-service.test.ts +87 -0
  219. package/src/daemon/policy-request-service.ts +62 -0
  220. package/src/daemon/policy-utils.test.ts +138 -0
  221. package/src/daemon/policy-utils.ts +152 -0
  222. package/src/daemon/queue.test.ts +89 -0
  223. package/src/daemon/queue.ts +87 -0
  224. package/src/daemon/request-store.test.ts +103 -0
  225. package/src/daemon/request-store.ts +96 -0
  226. package/src/daemon/router-policy-request.test.ts +99 -0
  227. package/src/daemon/router.test.ts +380 -0
  228. package/src/daemon/router.ts +510 -0
  229. package/src/daemon/routers/slash-command.test.ts +145 -0
  230. package/src/daemon/routers/slash-command.ts +58 -0
  231. package/src/daemon/routers/slash-interrupt.test.ts +30 -0
  232. package/src/daemon/routers/slash-interrupt.ts +7 -0
  233. package/src/daemon/routers/slash-new.test.ts +59 -0
  234. package/src/daemon/routers/slash-new.ts +14 -0
  235. package/src/daemon/routers/slash-policies.test.ts +167 -0
  236. package/src/daemon/routers/slash-policies.ts +131 -0
  237. package/src/daemon/routers/slash-stop.test.ts +30 -0
  238. package/src/daemon/routers/slash-stop.ts +3 -0
  239. package/src/daemon/routers/types.ts +10 -0
  240. package/src/daemon/routers/utils.ts +22 -0
  241. package/src/daemon/routers.test.ts +141 -0
  242. package/src/daemon/routers.ts +115 -0
  243. package/src/daemon/utils/spawn.ts +61 -0
  244. package/src/shared/agent-utils.ts +30 -0
  245. package/src/shared/chats.test.ts +112 -0
  246. package/src/shared/chats.ts +164 -0
  247. package/src/shared/config.test.ts +90 -0
  248. package/src/shared/config.ts +100 -0
  249. package/src/shared/event-source.ts +121 -0
  250. package/src/shared/fetch.ts +45 -0
  251. package/src/shared/lite.ts +129 -0
  252. package/src/shared/policies.ts +24 -0
  253. package/src/shared/utils/env.ts +27 -0
  254. package/src/shared/utils/fs.ts +13 -0
  255. package/src/shared/workspace.test.ts +345 -0
  256. package/src/shared/workspace.ts +500 -0
  257. package/templates/environments/cladding/env.json +7 -0
  258. package/templates/environments/macos/env.json +8 -0
  259. package/templates/environments/macos/sandbox.sb +21 -0
  260. package/templates/environments/macos-proxy/allowlist.txt +1 -0
  261. package/templates/environments/macos-proxy/env.json +14 -0
  262. package/templates/environments/macos-proxy/proxy.mjs +86 -0
  263. package/templates/environments/macos-proxy/sandbox.sb +34 -0
  264. package/templates/gemini/settings.json +11 -0
  265. package/templates/gemini-claw/.gemini/hooks/clawmini-logging.sh +17 -0
  266. package/templates/gemini-claw/.gemini/settings.json +24 -0
  267. package/templates/gemini-claw/.gemini/skills/clawmini-jobs/SKILL.md +40 -0
  268. package/templates/gemini-claw/.gemini/system.md +98 -0
  269. package/templates/gemini-claw/BOOTSTRAP.md +54 -0
  270. package/templates/gemini-claw/GEMINI.md +107 -0
  271. package/templates/gemini-claw/HEARTBEAT.md +3 -0
  272. package/templates/gemini-claw/MEMORY.md +2 -0
  273. package/templates/gemini-claw/SOUL.md +42 -0
  274. package/templates/gemini-claw/TOOLS.md +38 -0
  275. package/templates/gemini-claw/USER.md +15 -0
  276. package/templates/gemini-claw/memory/.gitkeep +0 -0
  277. package/templates/gemini-claw/settings.json +24 -0
  278. package/templates/opencode/settings.json +11 -0
  279. package/tsconfig.json +42 -0
  280. package/tsdown.config.ts +19 -0
  281. package/vitest.config.ts +9 -0
  282. package/web/.svelte-kit/ambient.d.ts +382 -0
  283. package/web/.svelte-kit/generated/client/app.js +35 -0
  284. package/web/.svelte-kit/generated/client/matchers.js +1 -0
  285. package/web/.svelte-kit/generated/client/nodes/0.js +3 -0
  286. package/web/.svelte-kit/generated/client/nodes/1.js +1 -0
  287. package/web/.svelte-kit/generated/client/nodes/2.js +1 -0
  288. package/web/.svelte-kit/generated/client/nodes/3.js +1 -0
  289. package/web/.svelte-kit/generated/client/nodes/4.js +3 -0
  290. package/web/.svelte-kit/generated/client/nodes/5.js +3 -0
  291. package/web/.svelte-kit/generated/client-optimized/app.js +35 -0
  292. package/web/.svelte-kit/generated/client-optimized/matchers.js +1 -0
  293. package/web/.svelte-kit/generated/client-optimized/nodes/0.js +3 -0
  294. package/web/.svelte-kit/generated/client-optimized/nodes/1.js +1 -0
  295. package/web/.svelte-kit/generated/client-optimized/nodes/2.js +1 -0
  296. package/web/.svelte-kit/generated/client-optimized/nodes/3.js +1 -0
  297. package/web/.svelte-kit/generated/client-optimized/nodes/4.js +3 -0
  298. package/web/.svelte-kit/generated/client-optimized/nodes/5.js +3 -0
  299. package/web/.svelte-kit/generated/root.js +3 -0
  300. package/web/.svelte-kit/generated/root.svelte +68 -0
  301. package/web/.svelte-kit/generated/server/internal.js +53 -0
  302. package/web/.svelte-kit/non-ambient.d.ts +46 -0
  303. package/web/.svelte-kit/output/client/.vite/manifest.json +251 -0
  304. package/web/.svelte-kit/output/client/_app/immutable/assets/0.GI4C4dpV.css +1 -0
  305. package/web/.svelte-kit/output/client/_app/immutable/chunks/B5abRDXp.js +1 -0
  306. package/web/.svelte-kit/output/client/_app/immutable/chunks/B8yYFADm.js +1 -0
  307. package/web/.svelte-kit/output/client/_app/immutable/chunks/BPy8HLo7.js +5 -0
  308. package/web/.svelte-kit/output/client/_app/immutable/chunks/Bi0jeV7Q.js +1 -0
  309. package/web/.svelte-kit/output/client/_app/immutable/chunks/BmUXQ3wy.js +2 -0
  310. package/web/.svelte-kit/output/client/_app/immutable/chunks/C3k55nDF.js +1 -0
  311. package/web/.svelte-kit/output/client/_app/immutable/chunks/COekwvP2.js +1 -0
  312. package/web/.svelte-kit/output/client/_app/immutable/chunks/CSvS_NwK.js +1 -0
  313. package/web/.svelte-kit/output/client/_app/immutable/chunks/CpaGRn9L.js +1 -0
  314. package/web/.svelte-kit/output/client/_app/immutable/chunks/CyNaE55B.js +1 -0
  315. package/web/.svelte-kit/output/client/_app/immutable/chunks/DG5RZBw-.js +2 -0
  316. package/web/.svelte-kit/output/client/_app/immutable/chunks/Dc-UOHw9.js +1 -0
  317. package/web/.svelte-kit/output/client/_app/immutable/chunks/DcrmIfTj.js +1 -0
  318. package/web/.svelte-kit/output/client/_app/immutable/chunks/ZkLyk0mE.js +1 -0
  319. package/web/.svelte-kit/output/client/_app/immutable/entry/app.B-vZe7PN.js +2 -0
  320. package/web/.svelte-kit/output/client/_app/immutable/entry/start.oP1AgKhs.js +1 -0
  321. package/web/.svelte-kit/output/client/_app/immutable/nodes/0.B5WFN0zw.js +1 -0
  322. package/web/.svelte-kit/output/client/_app/immutable/nodes/1.D1wtJb2k.js +1 -0
  323. package/web/.svelte-kit/output/client/_app/immutable/nodes/2.CK3CLC0f.js +1 -0
  324. package/web/.svelte-kit/output/client/_app/immutable/nodes/3.BB5wCoBf.js +4 -0
  325. package/web/.svelte-kit/output/client/_app/immutable/nodes/4.Dr2jvAXK.js +1 -0
  326. package/web/.svelte-kit/output/client/_app/immutable/nodes/5.BJl7oM3b.js +1 -0
  327. package/web/.svelte-kit/output/client/_app/version.json +1 -0
  328. package/web/.svelte-kit/output/client/robots.txt +3 -0
  329. package/web/.svelte-kit/output/prerendered/dependencies/_app/env.js +1 -0
  330. package/web/.svelte-kit/output/server/.vite/manifest.json +215 -0
  331. package/web/.svelte-kit/output/server/_app/immutable/assets/_layout.GI4C4dpV.css +1 -0
  332. package/web/.svelte-kit/output/server/chunks/Icon.js +153 -0
  333. package/web/.svelte-kit/output/server/chunks/bot.js +2753 -0
  334. package/web/.svelte-kit/output/server/chunks/client.js +47 -0
  335. package/web/.svelte-kit/output/server/chunks/environment.js +34 -0
  336. package/web/.svelte-kit/output/server/chunks/exports.js +231 -0
  337. package/web/.svelte-kit/output/server/chunks/false.js +4 -0
  338. package/web/.svelte-kit/output/server/chunks/index-server.js +20 -0
  339. package/web/.svelte-kit/output/server/chunks/index.js +24 -0
  340. package/web/.svelte-kit/output/server/chunks/internal.js +133 -0
  341. package/web/.svelte-kit/output/server/chunks/plus.js +81 -0
  342. package/web/.svelte-kit/output/server/chunks/root.js +4076 -0
  343. package/web/.svelte-kit/output/server/chunks/shared.js +789 -0
  344. package/web/.svelte-kit/output/server/chunks/utils.js +43 -0
  345. package/web/.svelte-kit/output/server/entries/fallbacks/error.svelte.js +11 -0
  346. package/web/.svelte-kit/output/server/entries/pages/_layout.svelte.js +3944 -0
  347. package/web/.svelte-kit/output/server/entries/pages/_layout.ts.js +28 -0
  348. package/web/.svelte-kit/output/server/entries/pages/_page.svelte.js +7 -0
  349. package/web/.svelte-kit/output/server/entries/pages/agents/_page.svelte.js +379 -0
  350. package/web/.svelte-kit/output/server/entries/pages/chats/_id_/_page.svelte.js +292 -0
  351. package/web/.svelte-kit/output/server/entries/pages/chats/_id_/_page.ts.js +17 -0
  352. package/web/.svelte-kit/output/server/entries/pages/chats/_id_/settings/_page.svelte.js +259 -0
  353. package/web/.svelte-kit/output/server/entries/pages/chats/_id_/settings/_page.ts.js +17 -0
  354. package/web/.svelte-kit/output/server/index.js +3748 -0
  355. package/web/.svelte-kit/output/server/internal.js +14 -0
  356. package/web/.svelte-kit/output/server/manifest-full.js +63 -0
  357. package/web/.svelte-kit/output/server/manifest.js +63 -0
  358. package/web/.svelte-kit/output/server/nodes/0.js +13 -0
  359. package/web/.svelte-kit/output/server/nodes/1.js +8 -0
  360. package/web/.svelte-kit/output/server/nodes/2.js +8 -0
  361. package/web/.svelte-kit/output/server/nodes/3.js +8 -0
  362. package/web/.svelte-kit/output/server/nodes/4.js +13 -0
  363. package/web/.svelte-kit/output/server/nodes/5.js +13 -0
  364. package/web/.svelte-kit/output/server/remote-entry.js +557 -0
  365. package/web/.svelte-kit/tsconfig.json +67 -0
  366. package/web/.svelte-kit/types/route_meta_data.json +17 -0
  367. package/web/.svelte-kit/types/src/routes/$types.d.ts +26 -0
  368. package/web/.svelte-kit/types/src/routes/agents/$types.d.ts +18 -0
  369. package/web/.svelte-kit/types/src/routes/chats/[id]/$types.d.ts +21 -0
  370. package/web/.svelte-kit/types/src/routes/chats/[id]/proxy+page.ts +20 -0
  371. package/web/.svelte-kit/types/src/routes/chats/[id]/settings/$types.d.ts +21 -0
  372. package/web/.svelte-kit/types/src/routes/chats/[id]/settings/proxy+page.ts +19 -0
  373. package/web/.svelte-kit/types/src/routes/proxy+layout.ts +35 -0
  374. package/web/README.md +42 -0
  375. package/web/components.json +16 -0
  376. package/web/package.json +41 -0
  377. package/web/src/app.css +121 -0
  378. package/web/src/app.d.ts +13 -0
  379. package/web/src/app.html +11 -0
  380. package/web/src/demo.spec.ts +7 -0
  381. package/web/src/lib/app-state.svelte.ts +3 -0
  382. package/web/src/lib/assets/favicon.svg +1 -0
  383. package/web/src/lib/components/app/app-sidebar-test-wrapper.svelte +10 -0
  384. package/web/src/lib/components/app/app-sidebar.svelte +171 -0
  385. package/web/src/lib/components/app/app-sidebar.svelte.spec.ts +13 -0
  386. package/web/src/lib/components/ui/button/button.svelte +82 -0
  387. package/web/src/lib/components/ui/button/index.ts +17 -0
  388. package/web/src/lib/components/ui/dialog/dialog-close.svelte +7 -0
  389. package/web/src/lib/components/ui/dialog/dialog-content.svelte +45 -0
  390. package/web/src/lib/components/ui/dialog/dialog-description.svelte +17 -0
  391. package/web/src/lib/components/ui/dialog/dialog-footer.svelte +20 -0
  392. package/web/src/lib/components/ui/dialog/dialog-header.svelte +20 -0
  393. package/web/src/lib/components/ui/dialog/dialog-overlay.svelte +20 -0
  394. package/web/src/lib/components/ui/dialog/dialog-portal.svelte +7 -0
  395. package/web/src/lib/components/ui/dialog/dialog-title.svelte +17 -0
  396. package/web/src/lib/components/ui/dialog/dialog-trigger.svelte +7 -0
  397. package/web/src/lib/components/ui/dialog/dialog.svelte +7 -0
  398. package/web/src/lib/components/ui/dialog/index.ts +34 -0
  399. package/web/src/lib/components/ui/input/index.ts +7 -0
  400. package/web/src/lib/components/ui/input/input.svelte +52 -0
  401. package/web/src/lib/components/ui/separator/index.ts +7 -0
  402. package/web/src/lib/components/ui/separator/separator.svelte +21 -0
  403. package/web/src/lib/components/ui/sheet/index.ts +34 -0
  404. package/web/src/lib/components/ui/sheet/sheet-close.svelte +7 -0
  405. package/web/src/lib/components/ui/sheet/sheet-content.svelte +60 -0
  406. package/web/src/lib/components/ui/sheet/sheet-description.svelte +17 -0
  407. package/web/src/lib/components/ui/sheet/sheet-footer.svelte +20 -0
  408. package/web/src/lib/components/ui/sheet/sheet-header.svelte +20 -0
  409. package/web/src/lib/components/ui/sheet/sheet-overlay.svelte +20 -0
  410. package/web/src/lib/components/ui/sheet/sheet-portal.svelte +7 -0
  411. package/web/src/lib/components/ui/sheet/sheet-title.svelte +17 -0
  412. package/web/src/lib/components/ui/sheet/sheet-trigger.svelte +7 -0
  413. package/web/src/lib/components/ui/sheet/sheet.svelte +7 -0
  414. package/web/src/lib/components/ui/sidebar/constants.ts +6 -0
  415. package/web/src/lib/components/ui/sidebar/context.svelte.ts +79 -0
  416. package/web/src/lib/components/ui/sidebar/index.ts +75 -0
  417. package/web/src/lib/components/ui/sidebar/sidebar-content.svelte +24 -0
  418. package/web/src/lib/components/ui/sidebar/sidebar-footer.svelte +21 -0
  419. package/web/src/lib/components/ui/sidebar/sidebar-group-action.svelte +36 -0
  420. package/web/src/lib/components/ui/sidebar/sidebar-group-content.svelte +21 -0
  421. package/web/src/lib/components/ui/sidebar/sidebar-group-label.svelte +34 -0
  422. package/web/src/lib/components/ui/sidebar/sidebar-group.svelte +21 -0
  423. package/web/src/lib/components/ui/sidebar/sidebar-header.svelte +21 -0
  424. package/web/src/lib/components/ui/sidebar/sidebar-input.svelte +21 -0
  425. package/web/src/lib/components/ui/sidebar/sidebar-inset.svelte +24 -0
  426. package/web/src/lib/components/ui/sidebar/sidebar-menu-action.svelte +43 -0
  427. package/web/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte +29 -0
  428. package/web/src/lib/components/ui/sidebar/sidebar-menu-button.svelte +103 -0
  429. package/web/src/lib/components/ui/sidebar/sidebar-menu-item.svelte +21 -0
  430. package/web/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte +36 -0
  431. package/web/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte +43 -0
  432. package/web/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte +21 -0
  433. package/web/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte +25 -0
  434. package/web/src/lib/components/ui/sidebar/sidebar-menu.svelte +21 -0
  435. package/web/src/lib/components/ui/sidebar/sidebar-provider.svelte +53 -0
  436. package/web/src/lib/components/ui/sidebar/sidebar-rail.svelte +36 -0
  437. package/web/src/lib/components/ui/sidebar/sidebar-separator.svelte +19 -0
  438. package/web/src/lib/components/ui/sidebar/sidebar-trigger.svelte +35 -0
  439. package/web/src/lib/components/ui/sidebar/sidebar.svelte +104 -0
  440. package/web/src/lib/components/ui/skeleton/index.ts +7 -0
  441. package/web/src/lib/components/ui/skeleton/skeleton.svelte +17 -0
  442. package/web/src/lib/components/ui/switch/index.ts +7 -0
  443. package/web/src/lib/components/ui/switch/switch.svelte +29 -0
  444. package/web/src/lib/components/ui/textarea/index.ts +7 -0
  445. package/web/src/lib/components/ui/textarea/textarea.svelte +23 -0
  446. package/web/src/lib/components/ui/tooltip/index.ts +19 -0
  447. package/web/src/lib/components/ui/tooltip/tooltip-content.svelte +52 -0
  448. package/web/src/lib/components/ui/tooltip/tooltip-portal.svelte +7 -0
  449. package/web/src/lib/components/ui/tooltip/tooltip-provider.svelte +7 -0
  450. package/web/src/lib/components/ui/tooltip/tooltip-trigger.svelte +7 -0
  451. package/web/src/lib/components/ui/tooltip/tooltip.svelte +7 -0
  452. package/web/src/lib/hooks/is-mobile.svelte.ts +9 -0
  453. package/web/src/lib/index.ts +1 -0
  454. package/web/src/lib/types.ts +23 -0
  455. package/web/src/lib/utils.ts +13 -0
  456. package/web/src/routes/+layout.svelte +67 -0
  457. package/web/src/routes/+layout.ts +34 -0
  458. package/web/src/routes/+page.svelte +7 -0
  459. package/web/src/routes/agents/+page.svelte +206 -0
  460. package/web/src/routes/chats/[id]/+page.svelte +406 -0
  461. package/web/src/routes/chats/[id]/+page.ts +19 -0
  462. package/web/src/routes/chats/[id]/page.svelte.spec.ts +102 -0
  463. package/web/src/routes/chats/[id]/settings/+page.svelte +165 -0
  464. package/web/src/routes/chats/[id]/settings/+page.ts +18 -0
  465. package/web/src/routes/page.svelte.spec.ts +13 -0
  466. package/web/static/robots.txt +3 -0
  467. package/web/svelte.config.js +21 -0
  468. package/web/tsconfig.json +20 -0
  469. package/web/vite.config.ts +41 -0
@@ -0,0 +1,47 @@
1
+ # Product Requirements Document: Multiple Agents Support
2
+
3
+ ## Vision
4
+ To enhance the flexibility of `clawmini` by allowing users to define and interact with multiple distinct agents within a single workspace. This enables multi-agent workflows where different tasks can be delegated to differently-configured agents (e.g., different LLM models, varying temperature settings, or distinct operating directories).
5
+
6
+ ## Product/Market Background
7
+ Currently, `clawmini` supports a single, globally defined `defaultAgent` in the workspace `.clawmini/settings.json`. While effective for simple use cases, power users need the ability to maintain concurrent chats with different configurations. By treating the workspace `defaultAgent` as a base configuration and allowing specific agents to extend and override it, users gain maximum flexibility with minimal boilerplate.
8
+
9
+ ## Use Cases
10
+ - A user wants one chat to use a fast, lightweight model (e.g., for quick queries) and another to use a slower, "thinking" model (e.g., for complex reasoning), seamlessly switching between them or creating them via the Web UI.
11
+ - A user wants an agent to execute its commands within a specific subdirectory of the project instead of the project root.
12
+ - A user wants to define specialized agents with different prompt instructions injected via environment variables.
13
+
14
+ ## Requirements
15
+
16
+ ### 1. Agent Configuration
17
+ - **Storage Location**: Agents must be stored in `.clawmini/agents/<agentId>/settings.json`.
18
+ - **Schema**:
19
+ - `commands`: Inherits and overrides individual command strings (`new`, `append`, `getSessionId`, `getMessageContent`) from the global `defaultAgent.commands`.
20
+ - `env`: Key-value pairs that extend/override the global `defaultAgent.env`.
21
+ - `directory`: The absolute or relative path (from the workspace root) used as the `cwd` when executing the agent's commands. Defaults to `./<agentId>`.
22
+ - **Resolution Logic**: When an agent's command is executed, its configuration must be deep-merged over the workspace `defaultAgent` configuration.
23
+
24
+ ### 2. CLI Interface
25
+ Add a new command group: `clawmini agents` with the following subcommands:
26
+ - `add <name> [--directory <dir>] [--env <key=value>...]`: Creates a new agent.
27
+ - `update <name> [--directory <dir>] [--env <key=value>...]`: Updates an existing agent.
28
+ - `delete <name>`: Deletes the agent and its directory under `.clawmini/agents/<name>`.
29
+ - `list`: Lists all configured agents.
30
+
31
+ Update the `messages` command:
32
+ - `clawmini messages send [--agent <name>] "message"`: The `--agent` flag updates the chat's `.clawmini/chats/<chatId>/settings.json` so that subsequent messages in the chat use this agent. If omitted, it defaults to the existing agent for the chat, or the global `defaultAgent` if none is set. If the specified agent does not exist, the command must fail and output an error message (e.g., "Error: agent '<name>' does not exist").
33
+
34
+ ### 3. Web UI Integration
35
+ - **Agent Creation**: A form to create new agents (providing name, and optional directory/env variables) must be added to the Web UI.
36
+ - **Chat Creation**: When creating a new chat, the user must be presented with a dropdown to select the initial agent for that chat. The default option should be the workspace's default agent.
37
+ - **Backend API**: New REST API endpoints (e.g., `/api/agents`) must be implemented to support listing, creating, updating, and deleting agents from the UI.
38
+
39
+ ### 4. Daemon Updates
40
+ - The daemon message handler (`src/daemon/message.ts`) must read the targeted chat's configuration to identify its active agent.
41
+ - It must then fetch the specified agent's configuration from `.clawmini/agents/<agentId>/settings.json` (falling back to just the global settings if the agent is "default").
42
+ - It must apply the agent-specific `env` and `commands` overrides over the global `defaultAgent` configuration.
43
+ - It must use the agent's `directory` as the `cwd` for the spawned child process.
44
+
45
+ ## Security & Constraints
46
+ - **Path Traversal**: Ensure that agent creation validates the `<name>` to prevent directory traversal attacks (e.g., rejecting `../`).
47
+ - **Data Integrity**: When merging the configurations, it must be a pure override, ensuring that sensitive command definitions in the global settings are not corrupted.
@@ -0,0 +1,13 @@
1
+ # Questions
2
+
3
+ **Q1: For the `clawmini agents add <name>` command, should it take any other flags (like `--directory`, `--env`) or just the name, defaulting the directory to `./<name>` and leaving other settings empty for the user to edit manually?**
4
+ A: Let's let it provide `--directory ./path/to/dir` and `--env FOO=bar`
5
+
6
+ **Q2: The prompt mentions that agent config overrides the workspace `defaultAgent` settings. When resolving commands (like `new`, `append`), do we overwrite the whole object or just individual properties? For example, if `defaultAgent.commands.new` is set globally, and the agent only overrides `env`, does the agent inherit the `commands.new` from the global `defaultAgent`?**
7
+ A: Yes, the agent should inherit commands from `defaultAgent.commands` and be able to override commands individually.
8
+
9
+ **Q3: The UI needs to allow users to create new agents. Should the web UI creation form also support specifying the `directory` and `env` variables, matching the CLI?**
10
+ A: Yes, but as with the flags they should be optional.
11
+
12
+ **Q4: Should there be a CLI command to update an existing agent's settings, like `clawmini agents update <name> --env FOO=baz`, or is it expected that users manually edit the `.clawmini/agents/<name>/settings.json` file?**
13
+ A: Sure, let's add an update command too.
@@ -0,0 +1,107 @@
1
+ # Agents Feature Tickets
2
+
3
+ ## Ticket 1: Core Configuration and Workspace Utility for Agents
4
+ **Description**: Define the `Agent` schema and add workspace utilities to manage agent configurations.
5
+ **Tasks**:
6
+ - Update `src/shared/config.ts` to include the `Agent` schema (with `commands`, `env`, and `directory` fields).
7
+ - Add utility functions to `src/shared/workspace.ts` to manage agent configurations (e.g., `getAgent`, `listAgents`, `writeAgentSettings`, `deleteAgent`).
8
+ - Ensure agent IDs are validated to prevent directory traversal attacks (e.g., rejecting paths with `../`).
9
+ - Add comprehensive unit tests in `src/shared/workspace.test.ts`.
10
+ **Verification**:
11
+ Run automated checks:
12
+ ```bash
13
+ npm run format:check && npm run lint && npm run check && npm run test
14
+ ```
15
+ **Status**: Complete
16
+
17
+ ## Ticket 2: Daemon Support for Agent Execution
18
+ **Description**: Update the daemon message handler to respect agent configurations and directory paths.
19
+ **Tasks**:
20
+ - Update `src/daemon/message.ts` to read the chat's active agent and merge its configuration over the global `defaultAgent` settings.
21
+ - Apply the merged `env` and `commands` to the agent execution.
22
+ - Adjust the child process execution to use the agent's `directory` as its `cwd` (resolving it relative to the workspace root, defaulting to `./<agentId>`).
23
+ - Add tests in `src/daemon/message.test.ts` to verify merging and directory assignment.
24
+ **Verification**:
25
+ Run automated checks:
26
+ ```bash
27
+ npm run format:check && npm run lint && npm run check && npm run test
28
+ ```
29
+ **Status**: Complete
30
+
31
+ ## Ticket 3: Agent CLI Commands (Add, Update, Delete, List)
32
+ **Description**: Implement the `clawmini agents` command group.
33
+ **Tasks**:
34
+ - Create `src/cli/commands/agents.ts` with subcommands: `add`, `update`, `delete`, and `list`.
35
+ - Parse `--directory` and `--env` flags for `add` and `update` commands.
36
+ - Register the `agents` command group in the main CLI entrypoint (`src/cli/index.ts`).
37
+ **Verification**:
38
+ Run automated checks:
39
+ ```bash
40
+ npm run format:check && npm run lint && npm run check && npm run test
41
+ ```
42
+ **Status**: Complete
43
+
44
+ ## Ticket 4: CLI Support for Selecting an Agent per Chat
45
+ **Description**: Update the CLI to allow switching the active agent for a specific chat.
46
+ **Tasks**:
47
+ - Update the `send` command in `src/cli/commands/messages.ts` to accept an `--agent <name>` flag.
48
+ - Validate that the requested agent exists; fail with a clear error if it doesn't.
49
+ - Update the chat's `.clawmini/chats/<chatId>/settings.json` to persist the selected agent for future messages.
50
+ **Verification**:
51
+ Run automated checks:
52
+ ```bash
53
+ npm run format:check && npm run lint && npm run check && npm run test
54
+ ```
55
+ **Status**: Complete
56
+
57
+ ## Ticket 5: Web UI API Endpoints for Agents
58
+ **Description**: Build REST API endpoints in the web project to manage agents.
59
+ **Tasks**:
60
+ - Create endpoints (e.g., `/api/agents` and `/api/agents/:id`) to handle fetching, creating, updating, and deleting agents from the Web UI.
61
+ - Use the shared workspace utilities to interact with the file system securely.
62
+ **Verification**:
63
+ Run automated checks:
64
+ ```bash
65
+ npm run format:check && npm run lint && npm run check && npm run test
66
+ ```
67
+ **Status**: Complete
68
+
69
+ ## Ticket 6: Web UI Integration for Agent Management & Chat Creation
70
+ **Description**: Build the frontend components for users to interact with agents.
71
+ **Tasks**:
72
+ - Add a new dialog or dedicated page in the UI to view, create, and manage agents (supporting `directory` and `env` configurations).
73
+ - Update the "New Chat" flow to include a dropdown for selecting the chat's initial agent.
74
+ - Integrate the frontend with the API endpoints created in Ticket 5.
75
+ **Verification**:
76
+ Run automated checks:
77
+ ```bash
78
+ npm run format:check && npm run lint && npm run check && npm run test
79
+ ```
80
+ **Status**: Complete
81
+
82
+ ## Ticket 7: Fix handleUserMessage Dependency on Global Default Agent
83
+ **Description**: `handleUserMessage` incorrectly asserts that the global `defaultAgent.commands.new` must be defined, failing if a custom agent has its own `commands.new` but the global default agent doesn't.
84
+ **Tasks**:
85
+ - Modify `src/daemon/message.ts` to merge the active agent configuration before asserting that `commands.new` is defined.
86
+ **Verification**:
87
+ Run automated checks.
88
+ **Status**: Complete
89
+
90
+ ## Ticket 8: DRY Violations in agents.ts Command Error Handling
91
+ **Description**: The error handling (`catch` block with `console.error` and `process.exit`) and `isValidAgentId` checks are repeated across multiple subcommands in `src/cli/commands/agents.ts`.
92
+ **Tasks**:
93
+ - Extract a helper function for error handling in `agents.ts`.
94
+ - Extract a helper function for asserting valid agent IDs that throws the appropriate error.
95
+ **Verification**:
96
+ Run automated checks.
97
+ **Status**: Complete
98
+
99
+ ## Ticket 9: DRY Violations in web.ts API Endpoints
100
+ **Description**: Reading/parsing JSON bodies and sending JSON error responses are repeated multiple times in `src/cli/commands/web.ts`.
101
+ **Tasks**:
102
+ - Create a `parseJsonBody(req)` helper function.
103
+ - Create a `sendJsonResponse(res, statusCode, data)` or similar helper.
104
+ - Update the API routes to use these helpers.
105
+ **Verification**:
106
+ Run automated checks.
107
+ **Status**: Complete
@@ -0,0 +1,13 @@
1
+ # Development Log
2
+
3
+ ## 2026-02-27 - Routers Feature
4
+ - **Ticket 1 Completed:** Updated `src/shared/config.ts` to add the `routers` property (an optional array of strings) to both `SettingsSchema` and `ChatSettingsSchema`. Ran the required formatting, linting, and testing checks, which all passed successfully.
5
+ - **Ticket 2 Completed:** Updated `CommandLogMessage` schema in `src/shared/chats.ts` to support the optional `source?: 'router'` property. Added a unit test case for it in `src/shared/chats.test.ts`. Ran all checks and they passed successfully.
6
+ - **Ticket 3 Completed:** Implemented internal logic for the built-in routers `@clawmini/slash-new` and `@clawmini/slash-command` in `src/daemon/routers/slash-new.ts` and `src/daemon/routers/slash-command.ts`. Created robust unit tests, handling edge cases like path traversal attempts via regex definition and `pathIsInsideDir`. Successfully resolved TS, formatting, and linting errors. All automated checks and tests passing successfully.
7
+ - **Ticket 4 Completed:** Created `src/daemon/routers.ts` to implement the `executeRouterPipeline` function. It sequentially iterates through defined routers, applies built-in handlers (`@clawmini/slash-new` and `@clawmini/slash-command`), and executes custom shell command routers while gracefully parsing standard output for JSON state merges. Wrote thorough tests in `src/daemon/routers.test.ts` to verify state mutations and silent failure handling for custom scripts. All automated checks and unit tests successfully passed.
8
+ - **Ticket 5 Completed:** Integrated the router pipeline into `handleUserMessage` in `src/daemon/message.ts`. Passed the initial state through `executeRouterPipeline`, and applied resulting changes to the message, agent, session, and environment before enqueueing the task. Included injection of a router reply `CommandLogMessage` if one is returned by the pipeline. Updated `src/daemon/message.test.ts` with tests covering router integration. Verified logic and automated checks to ensure all pass.
9
+ - **Bug Fixes:**
10
+ - Fixed an issue where the `/new` command wasn't actually saving the updated session ID to the chat's `settings.json`. The settings are now persisted immediately after the router pipeline executes.
11
+ - Implemented logic to skip sending the message to the model (queueing) if the processed message ends up being empty (e.g., when the user only types `/new`).
12
+ - Updated tests to handle `crypto.randomUUID()` mocking accurately.
13
+ - Ensured the original message content is appended to the chat timeline, even if the router pipeline modifies the message content sent to the agent.
@@ -0,0 +1,40 @@
1
+ # Notes: Routers Feature
2
+
3
+ ## Current Architecture
4
+ - **Messages**: Users send messages through the CLI (`cli/client.ts` or `daemon/router.ts`), which get processed by `daemon/message.ts`.
5
+ - **Agents**: Agents handle messages. Each agent has its own `new` and `append` command. Agents might be assigned by default or manually overridden.
6
+ - **Sessions**: Chat instances maintain sessions, and an agent can have multiple sessions in a chat.
7
+ - **Config Files**: Settings live in `.clawmini/settings.json` (global workspace) and `.clawmini/chats/ID/settings.json` (per-chat).
8
+
9
+ ## Router Concept
10
+ A router acts as a middleware pipeline that intercepts the user's message before it's passed to the queue for the agent to process.
11
+ - **Input**: `{ message: string, chatId?: string, agentId?: string, sessionId?: string, env?: object }` (or similar JSON representation of current state).
12
+ - **Output**: Returns a JSON object specifying modifications.
13
+ - **Built-in Routers**:
14
+ - `@clawmini/slash-new`: Detects `/new` prefix. Modifies `sessionId` to a new random UUID.
15
+ - `@clawmini/slash-command`: Detects slash prefixes (e.g. `/foo`) and replaces the command with file content from `.clawmini/commands/foo.md`.
16
+
17
+ ## Execution Flow
18
+ 1. User sends message `M1`.
19
+ 2. System loads defined `routers` array from local chat `settings.json`, falling back to global `settings.json`.
20
+ 3. For each router `R` in `routers`:
21
+ - System invokes `R` (likely spawning a subprocess, or handling natively if built-in).
22
+ - `R` receives `{ message: "...", ... }` via stdin (or argument).
23
+ - `R` outputs `{ message: "new text", agent: "coder", env: { ... } }` via stdout.
24
+ - System merges output back into state.
25
+ 4. Final state is passed to `handleUserMessage` in `src/daemon/message.ts`.
26
+
27
+ ## Possible Output Properties for a Router
28
+ - `message` (string): Replace or modify the message text.
29
+ - `agent` (string): Re-route the message to a different agent ID.
30
+ - `session` (string): Specify a specific session ID to use (like `/new`).
31
+ - `env` (Record<string, string>): Inject environment variables to pass to the agent process.
32
+ - `cwd` (string): Override the execution directory for the agent.
33
+ - `abort` (boolean): If true, stop processing the message entirely (don't invoke any agent, just log it or drop it).
34
+ - `reply` (string): Immediately log a response to the user and (optionally) `abort`. Useful for simple query commands without invoking an LLM.
35
+
36
+ ## Implementation details to discover
37
+ - How should built-in routers be differentiated from user-defined ones? User-defined could be shell scripts or executables, while `@clawmini/...` are handled natively in TypeScript.
38
+ - Should user-defined routers receive input via `stdin` or environment variable? stdin seems best for JSON.
39
+ - Is there a timeout for routers?
40
+ - Should the `routers` array allow arguments? Like `["@clawmini/slash-command", "./my-router.sh"]`.
@@ -0,0 +1,55 @@
1
+ # Product Requirements Document: Routers
2
+
3
+ ## Vision
4
+ The Routers feature aims to provide an extensible, middleware-like pipeline for processing user messages before they reach an agent. By allowing users to define a sequence of routers, they can dynamically alter message content, target specific agents or sessions, inject environment variables, and add automated replies. This gives users powerful, scriptable control over the routing logic of their chat sessions.
5
+
6
+ ## Product/Market Background
7
+ Currently, Clawmini routes a user's message directly to an agent based on static chat settings. While effective, it lacks the flexibility to adapt to dynamic conditions—such as creating a new session from a slash command (e.g., `/new`), expanding macros or file contents (e.g., `/command`), or redirecting messages based on content analysis (e.g., sending simple questions to a fast model and complex ones to a reasoning model). Routers solve this by introducing an interception layer.
8
+
9
+ ## Use Cases
10
+ 1. **Starting Fresh (`/new`)**: A user types `/new` at the beginning of a message. A router intercepts this, generates a new session UUID, and redirects the message to this new session, effectively clearing the context window for the agent.
11
+ 2. **Text Expansion (`/command`)**: A user types `/foo` in their message. A router intercepts this, reads the contents of `.clawmini/commands/foo.md`, and replaces `/foo` with the file's content before passing it to the agent.
12
+ 3. **Dynamic Agent Routing**: A user writes a custom shell script router that analyzes the message length. If the message is short, it sets `agent: "fast-model"`. If long, it sets `agent: "reasoning-model"`.
13
+ 4. **Environment Injection**: A custom router looks up a specific context (e.g., the current git branch) and injects it as an environment variable (`env: { GIT_BRANCH: "main" }`) for the agent to use.
14
+ 5. **Immediate Replies**: A router detects a simple query (e.g., `/ping`) and immediately responds with `reply: "pong"` without ever invoking the heavier agent process.
15
+
16
+ ## Requirements
17
+
18
+ ### Configuration
19
+ 1. **Settings Definition**: Routers are defined as an array of strings under the `routers` key in `.clawmini/settings.json` (global) or `.clawmini/chats/ID/settings.json` (per-chat).
20
+ 2. **Opt-in Nature**: Built-in routers are not enabled by default. Users must explicitly add them to the `routers` array.
21
+ 3. **Execution Order**: Routers defined in the array execute sequentially, in the order they are listed.
22
+
23
+ ### Router Execution
24
+ 1. **Built-in Routers**: Strings prefixed with `@clawmini/` map to internal TypeScript functions.
25
+ - `@clawmini/slash-new`: Checks if the message starts with `/new`. If so, creates a new session ID (random UUID), sets the session property, and removes `/new` from the message.
26
+ - `@clawmini/slash-command`: Checks if the message contains a slash command (e.g., `/foo` or `/foo:bar`). It looks for a matching file in `.clawmini/commands/` (`.clawmini/commands/foo.md` or `.clawmini/commands/foo/bar.md`). If found, it replaces the slash command with the file's contents.
27
+ 2. **Custom Shell Routers**: Strings not prefixed with `@clawmini/` are treated as shell commands executed in the workspace root.
28
+ 3. **Input Mechanism**: The system serializes the current state (e.g., `{ "message": "...", "chatId": "...", "agentId": "...", "sessionId": "...", "env": {} }`) to JSON and passes it to the shell command via `stdin`.
29
+ 4. **Output Processing**: The system reads the stdout of the shell command, expecting a JSON object.
30
+
31
+ ### Router Capabilities (Output Properties)
32
+ Routers can return a JSON object with any of the following properties to modify the state for the next router or the final agent execution:
33
+ - `message` (string): Replaces the original user message text.
34
+ - `agent` (string): Overrides the target agent ID for this message.
35
+ - `session` (string): Specifies a specific session ID to use.
36
+ - `env` (Record<string, string>): Injects or overrides environment variables for the agent process.
37
+ - `reply` (string): A text response to be injected into the chat timeline immediately before the agent's response.
38
+
39
+ ### Chat Timeline Integration
40
+ 1. **Reply Injection**: If a router returns a `reply` string, a new `ChatMessage` must be appended to the chat log *before* the agent is invoked.
41
+ 2. **Reply Format**: This injected message must have `role: 'log'` and a new property `source: 'router'`.
42
+
43
+ ### Error Handling
44
+ 1. **Silent Failure**: If a custom shell router exits with a non-zero code, fails to output valid JSON, or times out, the system should log an error for debugging purposes (e.g., console log or internal debug log) but must *not* halt processing. It should continue passing the current (unmodified by the failing router) state to the next router or agent.
45
+
46
+ ## Privacy, Security & Accessibility Concerns
47
+ - **Security (Shell Execution)**: Custom routers are executed as shell commands. This carries inherent risks if malicious commands are placed in the `settings.json`. However, this is consistent with Clawmini's existing trust model where users control their local `.clawmini` configuration and workspace scripts.
48
+ - **Security (Path Traversal)**: The `@clawmini/slash-command` router must ensure it does not allow path traversal (e.g., `/../../../etc/passwd`) when looking up command files. It must rigidly confine lookups to the `.clawmini/commands/` directory.
49
+
50
+ ## Implementation Plan
51
+ 1. Update schema definitions in `src/shared/config.ts` to support the `routers` array.
52
+ 2. Update `ChatMessage` schema in `src/shared/chats.ts` to support the optional `source: 'router'` property for log messages.
53
+ 3. Create a new `src/daemon/routers.ts` file to handle the pipeline execution (parsing settings, running built-in vs shell routers, managing state transitions).
54
+ 4. Implement the `@clawmini/slash-new` and `@clawmini/slash-command` internal functions.
55
+ 5. Integrate the pipeline into `handleUserMessage` in `src/daemon/message.ts` before the queue execution.
@@ -0,0 +1,21 @@
1
+ # Questions for Routers Feature
2
+
3
+ ## Q1
4
+ **Question**: How should user-defined routers be executed? For example, should the string in the `routers` array be treated as a shell command where the system passes the current state as a JSON string via `stdin` and expects the modified JSON object on `stdout`?
5
+ **Answer**: Yes, as a shell command executed in the workspace root. We may have some built-in ones (all prefixed with "@clawmini") that just map to internal functions.
6
+
7
+ ## Q2
8
+ **Question**: When a router returns its output JSON, what specific properties should we support merging back into the state? Beyond `message`, `agent`, `session`, and `env`, are there others you'd like to support? (e.g., `abort` to cancel the message entirely, `reply` to send a response back immediately without invoking an agent, or `cwd` to change the agent's working directory?)
9
+ **Answer**: `reply` is interesting for the router to inject a message about what it did. `abort` could be useful but we'll hold off for now. We will stick to `message`, `agent`, `session`, `env`, and `reply`.
10
+
11
+ ## Q3
12
+ **Question**: If a router returns a `reply` property, should that reply be inserted as an independent message in the chat timeline, or should it be appended to the current log message? If it is a separate message, what role should it have (`log`, `system`, etc.)?
13
+ **Answer**: Injected into the timeline before the agent's response. It should be an independent message with `role: 'log'` and `source: 'router'`.
14
+
15
+ ## Q4
16
+ **Question**: Regarding the built-in routers `@clawmini/slash-new` and `@clawmini/slash-command`, should these be enabled by default for all chats if the user does not specify a `routers` array in `settings.json`, or should users have to explicitly opt-in to them?
17
+ **Answer**: Explicit opt in.
18
+
19
+ ## Q5
20
+ **Question**: If a user-defined shell router returns a non-zero exit code or fails to output valid JSON, how should the system handle it? Should it silently fail and pass the original un-routed message to the agent, or should it log an error message to the user and halt the message processing entirely?
21
+ **Answer**: Log an error (debug-only?), but continue on.
@@ -0,0 +1,109 @@
1
+ # Routers Feature Tickets
2
+
3
+ ## Ticket 1: Update Configuration Schema
4
+ **Description:**
5
+ Update the schema definitions in `src/shared/config.ts` to support a new `routers` property. This should be an optional array of strings, available in both global (`.clawmini/settings.json`) and per-chat settings.
6
+
7
+ **Verification:**
8
+ - Ensure type definitions are updated.
9
+ - Verify that default settings parsing still succeeds.
10
+ - Run the full suite of automated checks: `npm run format:check && npm run lint && npm run check && npm run test`
11
+
12
+ **Status:** Complete
13
+
14
+ ---
15
+
16
+ ## Ticket 2: Update ChatMessage Schema
17
+ **Description:**
18
+ Update the `ChatMessage` schema in `src/shared/chats.ts` to support an optional `source` property. This property should allow the literal value `'router'` for messages where `role` is `'log'`.
19
+
20
+ **Verification:**
21
+ - Update `src/shared/chats.test.ts` to test the new schema properties.
22
+ - Run the full suite of automated checks: `npm run format:check && npm run lint && npm run check && npm run test`
23
+
24
+ **Status:** Complete
25
+
26
+ ---
27
+
28
+ ## Ticket 3: Implement Built-in Routers
29
+ **Description:**
30
+ Implement the internal logic for the built-in routers `@clawmini/slash-new` and `@clawmini/slash-command`.
31
+ - `@clawmini/slash-new`: Detects if the message starts with `/new`, removes it from the message text, and generates a new random UUID for the session.
32
+ - `@clawmini/slash-command`: Detects slash commands (e.g., `/foo` or `/foo:bar`) and replaces them with the contents of the matching file in `.clawmini/commands/`. **Crucial:** Implement strict path traversal protection to ensure only files within `.clawmini/commands/` can be read.
33
+
34
+ **Verification:**
35
+ - Create dedicated unit tests for these built-in router functions.
36
+ - Run the full suite of automated checks: `npm run format:check && npm run lint && npm run check && npm run test`
37
+
38
+ **Status:** Complete
39
+
40
+ ---
41
+
42
+ ## Ticket 4: Create Router Pipeline Execution Logic
43
+ **Description:**
44
+ Create a new file `src/daemon/routers.ts` to handle the middleware pipeline execution.
45
+ - Implement a function that takes an initial state (`message`, `chatId`, `agentId`, `sessionId`, `env`).
46
+ - Fetch the `routers` array from the current settings.
47
+ - Iterate through the routers sequentially:
48
+ - For built-in routers, call the respective internal functions.
49
+ - For custom routers, execute them as shell commands passing the current JSON state to `stdin` and parsing `stdout` as JSON.
50
+ - Merge valid output properties (`message`, `agent`, `session`, `env`, `reply`) into the state for the next step.
51
+ - Implement silent failure handling (non-zero exits, invalid JSON, timeouts should log errors but not halt the pipeline).
52
+
53
+ **Verification:**
54
+ - Create `src/daemon/routers.test.ts` to test both built-in router invocation and custom shell script execution (using mock scripts).
55
+ - Run the full suite of automated checks: `npm run format:check && npm run lint && npm run check && npm run test`
56
+
57
+ **Status:** Complete
58
+
59
+ ---
60
+
61
+ ## Ticket 5: Integrate Router Pipeline into Message Handling
62
+ **Description:**
63
+ Integrate the router pipeline into `handleUserMessage` in `src/daemon/message.ts`.
64
+ - Before adding the message to the queue for agent execution, pass the current state through the router pipeline.
65
+ - Apply the resulting state changes (updated `message`, `agentId`, `sessionId`, `env`).
66
+ - If the pipeline returns a `reply` string, inject a new `ChatMessage` with `role: 'log'` and `source: 'router'` into the chat timeline immediately before the agent is invoked.
67
+
68
+ **Verification:**
69
+ - Update `src/daemon/message.test.ts` to verify that routing modifications apply correctly (e.g., sessions are changed, text is replaced) and replies are properly injected into the timeline.
70
+ - Run the full suite of automated checks: `npm run format:check && npm run lint && npm run check && npm run test`
71
+
72
+ **Status:** Complete
73
+
74
+ ---
75
+
76
+ ## Ticket 6: Fix Custom Router Timeout Handle (High Priority)
77
+ **Description:**
78
+ The custom router shell execution in `src/daemon/routers.ts` sets a 10-second timeout, but it doesn't clear this timeout (`clearTimeout`) if the execution finishes (either successfully or with an error) before the timeout expires. This causes the Node.js event loop to stay active longer than necessary, acting as a potential memory leak and blocking process exit.
79
+
80
+ **Verification:**
81
+ - Ensure `clearTimeout` is called on both successful exit and error paths.
82
+ - Run the full suite of automated checks: `npm run format:check && npm run lint && npm run check && npm run test`
83
+
84
+ **Status:** Complete
85
+
86
+ ---
87
+
88
+ ## Ticket 7: Refactor Web API Monolithic Handler (Medium Priority)
89
+ **Description:**
90
+ The HTTP server implementation in `src/cli/commands/web.ts` handles all `/api/agents` and `/api/chats` routes within a single, monolithic 300+ line `if/else` block inside the `request` event callback. This violates clear organization and SRP. Also, utility functions like `parseJsonBody` and `sendJsonResponse` are instantiated inside the action scope instead of at the module level.
91
+ Extract the route handling into discrete functions (e.g., `handleApiAgents`, `handleApiChats`) and move the utilities outside the `webCmd.action` closure.
92
+
93
+ **Verification:**
94
+ - Verify all web API routes still work via `npm run test` or similar.
95
+ - Run the full suite of automated checks: `npm run format:check && npm run lint && npm run check && npm run test`
96
+
97
+ **Status:** Complete
98
+
99
+ ---
100
+
101
+ ## Ticket 8: Improve Error UX in Agents Web UI (Low Priority)
102
+ **Description:**
103
+ In `web/src/routes/agents/+page.svelte`, errors from the API are currently surfaced to the user using the browser's native `alert()` function. This is a poor user experience. Replace `alert()` with a modern approach, such as displaying an inline error message within the modal or form.
104
+
105
+ **Verification:**
106
+ - Simulate an error (e.g., trying to create a duplicate agent) and ensure the error message is displayed within the UI instead of an alert dialog.
107
+ - Run the full suite of automated checks: `npm run format:check && npm run lint && npm run check && npm run test`
108
+
109
+ **Status:** Complete
@@ -0,0 +1,38 @@
1
+ # Development Log: Agent Templates
2
+
3
+ ## Step 1: Update CLI flag parsing for `clawmini agent add`
4
+ - [x] Read tickets.md
5
+ - [x] Read `src/cli/commands/agents.ts` to see how `agent add` currently works.
6
+ - [x] Add the `--template <name>` flag to `clawmini agent add`.
7
+ - [x] Update `src/cli/e2e/agents.test.ts` to verify the new flag.
8
+ - [x] Run validations and fix any formatting issues.
9
+
10
+ ## Step 2: Implement template resolution and copy logic
11
+ - [x] Add `resolveTemplatePath` to `src/shared/workspace.ts` which checks local `.clawmini/templates/` first, and then falls back to `dist/templates/` (using relative path from dist/shared to templates folder).
12
+ - [x] Add `copyTemplate` to `src/shared/workspace.ts` to recursively copy template files into the target agent directory if the directory is empty.
13
+ - [x] Implement comprehensive unit tests in `src/shared/workspace.test.ts`.
14
+ - [x] Run code quality checks (`npm run lint`, `check`, `test`). All pass.
15
+
16
+ ## Step 3: Process template configuration (`settings.json`)
17
+ - [x] Wire up `copyTemplate` to the `clawmini agent add` command in `src/cli/commands/agents.ts`.
18
+ - [x] Implement logic to read, validate, and process `settings.json` from the newly copied template directory.
19
+ - [x] Ensure that the `directory` setting from the template is ignored with a warning and CLI flags correctly override template settings.
20
+ - [x] Delete `settings.json` from the agent's working directory after processing.
21
+ - [x] Create a dedicated E2E test in `src/cli/e2e/agents.test.ts` to verify the complete `--template` flow.
22
+ - [x] Ensure all code quality checks, including Prettier, ESLint, and TypeScript, are passing successfully.
23
+
24
+ ## Bug Fix: Template not found
25
+ ### Hypotheses
26
+ 1. `__dirname` resolution is incorrect when running via CLI, pointing to the wrong path.
27
+ 2. The folder `templates/default` exists but `fsPromises.stat` fails.
28
+
29
+ ### Exploration
30
+ By adding debug output to the `Template not found` error, it was clear that `../../templates` was resolving to the project root directory from a depth that was flatter than `src/shared`. Since the bundler output `dist/cli/index.mjs` was flattening the chunk structure, the `__dirname` relative to the bundle entrypoint was pointing directly to `dist/cli` rather than `dist/shared`.
31
+
32
+ ### Resolution
33
+ The bug was resolved by updating `resolveTemplatePath` to iterate over several common potential depth paths:
34
+ - `__dirname/templates`
35
+ - `__dirname/../templates`
36
+ - `__dirname/../../templates`
37
+
38
+ This successfully fixes the bug in the CLI.
@@ -0,0 +1,25 @@
1
+ # Agent Templates Research Notes
2
+
3
+ ## Current Implementation
4
+
5
+ - `clawmini agent add <id>` is handled in `src/cli/commands/agents.ts`.
6
+ - It currently accepts `--directory` and `--env`.
7
+ - It uses `getAgent` to check existence.
8
+ - It uses `writeAgentSettings(id, agentData)` to persist the configuration, which internally calls `ensureAgentWorkDir(agentId, data.directory, startDir)`.
9
+ - `ensureAgentWorkDir` (in `src/shared/workspace.ts`) resolves the directory (either `<workspace-root>/<agent-id>` or the custom directory) and creates it using `fsPromises.mkdir` if it doesn't exist.
10
+ - Agent configurations (`AgentSettings` / `AgentSchema`) are stored at `.clawmini/agents/<id>/settings.json`.
11
+ - There is a root-level `templates/` folder in the project which might be intended for built-in templates.
12
+
13
+ ## Required Changes
14
+
15
+ - Add `--template <name>` flag to `clawmini agent add`.
16
+ - Define template resolution order:
17
+ 1. `.clawmini/templates/<name>`
18
+ 2. Built-in template (e.g., `templates/<name>`)
19
+ - The copy logic must:
20
+ - Copy the contents of the resolved template folder into the agent's working directory.
21
+ - This should likely occur only when creating the work dir (or if the directory is empty).
22
+ - Look for `settings.json` in the newly copied workdir.
23
+ - If it exists and is valid `AgentSettings` (validates with `AgentSchema`), use it as the base configuration for the agent.
24
+ - Remove `settings.json` from the working directory after using it.
25
+ - Flags passed explicitly to `clawmini agent add` (like `--env` or `--directory`) should probably override values from the template's `settings.json`.
@@ -0,0 +1,34 @@
1
+ # Agent Templates
2
+
3
+ ## Vision
4
+ To provide a smooth and predictable onboarding experience for new agents by enabling pre-configured templates. These templates give users a solid starting point for their agents, complete with files and configurations, saving time and reducing errors when setting up boilerplate environments.
5
+
6
+ ## Product / Market Background
7
+ Currently, users add agents with `clawmini agent add <id>`, which creates a raw configuration and optionally an empty working directory. As the system scales and use-cases expand, users often need specialized agents (e.g., specific prompting frameworks, pre-installed tool configurations, or project structures). Allowing folder templates bridges this gap by letting users seed an agent's working directory with necessary files and configurations.
8
+
9
+ ## Use Cases
10
+ 1. **Quickstart Default:** A user creates an agent with `clawmini agent add foo --template default`. The `default` template provides an initial structure (e.g., standard files or instructions) ready for immediate use.
11
+ 2. **Custom Workflows:** A user defines a project-specific template in `.clawmini/templates/my-custom-agent` and uses `clawmini agent add bar --template my-custom-agent` to initialize an agent with standard tools tailored for their current workspace.
12
+ 3. **Configuration Inheritance:** A template provides default environment variables or descriptions in a `settings.json` file. When the agent is created, these settings are merged, saving the user from manually typing out complex environment parameters.
13
+
14
+ ## Requirements
15
+ 1. **CLI Flag (`--template <name>`):** The `clawmini agent add <id>` command must accept an optional `--template <name>` flag.
16
+ 2. **Template Resolution:**
17
+ - First, search in `.clawmini/templates/<name>`.
18
+ - If not found locally, search in built-in templates. Built-in templates will be located at a package-level `templates/` directory (accessible via `import.meta.url` or standard path resolution relative to `dist/cli`).
19
+ 3. **Directory Constraints:**
20
+ - If the agent's resolved working directory already exists and is **not empty**, the command MUST fail, preventing accidental overwrites.
21
+ 4. **Copy Process:**
22
+ - The entire contents of the resolved template folder must be copied to the new agent's working directory recursively.
23
+ 5. **Configuration Handling (`settings.json`):**
24
+ - After copying, if a `settings.json` file exists in the copied directory, it must be read and validated against `AgentSchema` (ignoring strict workspace checks during read).
25
+ - If valid, this configuration becomes the default state of the new agent.
26
+ - **Important:** If the template's `settings.json` includes a `directory` field, it MUST be explicitly ignored, and a warning should be printed to the user indicating that template directory configurations are ignored. If no `--directory` flag is specified, the agent's working directory will be created in the default folder (`./<agent-id>`).
27
+ - The CLI flags (`--env`, `--directory`) provided by the user MUST override matching values from the template's `settings.json`.
28
+ - The `settings.json` file MUST be removed from the agent's working directory after processing.
29
+ 6. **Built-in Templates Accessibility:**
30
+ - The build process must be updated or source code logic must guarantee that the `templates/` folder is accessible by the CLI binary after the project is built. Since `tsdown` is used, resolving `templates/` relative to `__dirname` or using a copy-plugin might be necessary. Given Node's `import.meta.url`, resolving paths to `../../../templates` from the built code is a common approach.
31
+
32
+ ## Open / Technical Concerns
33
+ - Built-in template location: Ensuring `dist/` execution properly resolves the `templates/` folder. A reliable method like `path.join(path.dirname(fileURLToPath(import.meta.url)), '../../templates')` should be tested during implementation.
34
+ - Race conditions: Validating the target directory is empty before starting the asynchronous copy process.
@@ -0,0 +1,11 @@
1
+ # Agent Templates Questions and Answers
2
+
3
+ **Q1:** Where are the "built-in templates" located? Is it the `templates/` folder at the root of the project?
4
+ **A1:** Wherever makes the most sense. The project is built to `./dist` with `npm run build`, so it must maintain access to the templates.
5
+ *(Note: I will propose copying the `templates/` folder to `dist/templates` during the build process, or resolving from `dist/../templates` in the source code.)*
6
+
7
+ **Q2:** If the template's `settings.json` includes a `directory` field, should it be ignored, used as the default unless overridden by an explicit `--directory` flag, or something else?
8
+ **A2:** The `directory` field should always be ignored, likely with a warning.
9
+
10
+ **Q3:** Should the agent creation (and template copying) fail if the destination working directory already exists and is not empty?
11
+ **A3:** Yes, it should fail if the directory is not empty.
@@ -0,0 +1,49 @@
1
+ # Agent Templates Tickets
2
+
3
+ ## Step 1: Update CLI flag parsing for `clawmini agent add`
4
+ - **Description:** Add the `--template <name>` flag to the `clawmini agent add` command. Ensure it correctly parses alongside existing flags like `--directory` and `--env`.
5
+ - **Verification:**
6
+ - Update or add tests in `src/cli/e2e/agents.test.ts` to verify the `--template` flag is parsed and passed to the handler correctly.
7
+ - Run `npm run format:check && npm run lint && npm run check && npm run test`.
8
+ - **Status:** Completed
9
+
10
+ ## Step 2: Implement template resolution and copy logic
11
+ - **Description:**
12
+ - Implement a function to resolve the template path, checking `.clawmini/templates/<name>` first, then falling back to a built-in `templates/<name>` folder relative to the built CLI executable.
13
+ - Add logic to check if the target agent working directory exists and is **not empty**. If it is not empty, the command must fail to prevent overwriting.
14
+ - Recursively copy the contents of the resolved template folder into the new agent's working directory.
15
+ - **Verification:**
16
+ - Add unit tests verifying correct resolution order (local workspace vs. built-in), successful file copying to an empty directory, and failure when the target directory is not empty.
17
+ - Verify that built-in templates are correctly resolved from the compiled `dist/` directory.
18
+ - Run `npm run format:check && npm run lint && npm run check && npm run test`.
19
+ - **Status:** Completed
20
+
21
+ ## Step 3: Process template configuration (`settings.json`)
22
+ - **Description:**
23
+ - After copying the template files, check for a `settings.json` in the newly created agent working directory.
24
+ - If present, read and validate it against `AgentSchema`.
25
+ - If the template's `settings.json` includes a `directory` field, ignore it, print a warning to the user, and use the default `./<agent-id>` or the one provided by `--directory`.
26
+ - Merge the configuration: CLI flags (`--env`, `--directory`) MUST override values from the template's `settings.json`.
27
+ - Remove the `settings.json` file from the agent's working directory after processing.
28
+ - Pass the resulting merged configuration to `writeAgentSettings`.
29
+ - **Verification:**
30
+ - Add unit tests for the configuration merging logic, ensuring CLI flags override template settings and that the `directory` field in the template is ignored with a warning.
31
+ - Verify `settings.json` is deleted from the working directory after creation.
32
+ - Add/update an end-to-end test in `src/cli/e2e/agents.test.ts` for `clawmini agent add <id> --template <name>` simulating the entire flow.
33
+ - Run `npm run format:check && npm run lint && npm run check && npm run test`.
34
+ - **Status:** Completed
35
+
36
+ ## Issue 1 (High): Extract template settings logic
37
+ - **Description:** Move the complex template settings merging and validation logic out of the CLI command handler (`src/cli/commands/agents.ts`) and into a dedicated function in `src/shared/workspace.ts` (e.g., `applyTemplateSettings`). This improves separation of concerns.
38
+ - **Verification:** Ensure tests pass. Run `npm run format:check && npm run lint && npm run check && npm run test`.
39
+ - **Status:** Completed
40
+
41
+ ## Issue 2 (Medium): DRY up directory checking in `resolveTemplatePath`
42
+ - **Description:** In `src/shared/workspace.ts`, the `try/catch` block for checking if a directory exists using `fsPromises.stat(dir).isDirectory()` is duplicated. Extract this into a helper function `async function isDirectory(path: string): Promise<boolean>`.
43
+ - **Verification:** Ensure tests pass. Run `npm run format:check && npm run lint && npm run check && npm run test`.
44
+ - **Status:** Completed
45
+
46
+ ## Issue 3 (Low): Use asynchronous `fs` methods consistently
47
+ - **Description:** Replace synchronous `fs.existsSync` calls with asynchronous alternatives or `try/catch` blocks using `fsPromises` in `src/cli/commands/agents.ts` and `src/shared/workspace.ts` for consistency.
48
+ - **Verification:** Ensure tests pass. Run `npm run format:check && npm run lint && npm run check && npm run test`.
49
+ - **Status:** Completed