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,79 @@
1
+ # Development Log - Sessions Feature
2
+
3
+ ## Progress
4
+
5
+ - Picked up Ticket 1: Update Configuration Schema & Types
6
+ - Picked up Ticket 2: CLI Flag for Sessions
7
+ - Picked up Ticket 3: State Storage Utilities
8
+
9
+ ## Completed Ticket 3
10
+
11
+ - Implemented `getChatSettingsPath` and `getAgentSessionSettingsPath` path resolution functions.
12
+ - Implemented asynchronous storage utilities `readChatSettings`, `writeChatSettings`, `readAgentSessionSettings`, and `writeAgentSessionSettings` using `node:fs/promises` in `src/shared/workspace.ts`.
13
+ - Created robust test suite `src/shared/workspace.test.ts` to ensure utility correctness, path resolution, and error handling for nonexistent/invalid files.
14
+ - `npm run check` and `npm run test` both completed successfully.
15
+
16
+ ## Completed Ticket 2
17
+
18
+ - Added `-s, --session <id>` flag to the CLI `messages send` command in `src/cli/commands/messages.ts`.
19
+ - Updated tRPC `send-message` schema in `src/daemon/router.ts` to accept an optional `sessionId` string parameter.
20
+ - Added an E2E test in `src/cli/e2e.test.ts` verifying flag parsing and successful payload transmission to the daemon.
21
+ - All checks (`npm run lint`, `npm run check`, `npm run test`) passed.
22
+
23
+ ## Completed Ticket 1
24
+
25
+ - Updated `SettingsSchema` in `src/shared/config.ts` to include `append`, `getSessionId`, and `getMessageContent` commands.
26
+ - Verified that `z.record(z.string(), z.string())` is correctly used.
27
+ - Verified `npm run check` and `npm run test` passed.
28
+
29
+ ## Completed Ticket 4
30
+
31
+ - Updated `handleUserMessage` in `src/daemon/message.ts` to accept an optional `sessionId`.
32
+ - Implemented session resolution logic matching `chatSettings.sessions[agentId]` if `sessionId` is omitted.
33
+ - Implemented environment variable injection and command fallback (`commands.append` vs `commands.new`) depending on whether agent session settings exist.
34
+ - Passed `sessionId` via TRPC mutation in `src/daemon/router.ts`.
35
+ - Updated unit tests in `src/daemon/message.test.ts` heavily mocking `readChatSettings`, `readAgentSessionSettings`, and `spawn` ensuring test isolation by separating cache directories.
36
+ - All checks (`npm run check`, `npm run test`) passed.
37
+
38
+ ## Completed Ticket 5
39
+
40
+ - Modified `runCommand` signature in `src/daemon/message.ts` to return an object `{ stdout, stderr, exitCode }` instead of resolving `void` and internally calling `appendMessage`. Added support for an optional `stdin` argument.
41
+ - Implemented extraction logic inside `handleUserMessage`: after the main command finishes, we spawn `getSessionId` and `getMessageContent` by invoking `runCommand` with `stdin: mainResult.stdout`.
42
+ - Updates the Chat Settings and Agent Session Settings correctly using `writeChatSettings` and `writeAgentSessionSettings` respectively, upon successful execution of `getSessionId`.
43
+ - Propagates any error messages from the extraction commands to `extractionError` which gets gracefully concatenated to `stderr` of the main log output.
44
+ - Refactored `runCommand` in `src/daemon/router.ts` and `src/daemon/message.test.ts` to adhere to the new signature and support piping to `stdin`.
45
+ - Verified changes with extensive unit tests covering the multi-command spawning behavior and state file persistence logic in `src/daemon/message.test.ts`.
46
+ - `npm run check`, `npm run test`, and `npm run lint` all passed successfully.
47
+
48
+ ## Completed Ticket 6
49
+
50
+ - Added `extractedMessage?: string` to the `CommandLogMessage` interface in `src/shared/chats.ts`.
51
+ - Removed TODO comments in `src/daemon/message.ts` regarding `extractedMessage`.
52
+ - Wrote full multi-message session E2E test in `src/cli/e2e.test.ts` verifying that `commands.new`, `commands.append`, `commands.getSessionId`, and `commands.getMessageContent` execute as expected and are safely captured.
53
+ - Tested failure scenarios to ensure extraction errors gracefully fallback into `stderr` and preserve the `chat.jsonl` atomic ordering without breaking the log syntax.
54
+ - `npm run check`, `npm run build`, `npm run lint`, and `npm run test` all pass. This concludes the Sessions Feature implementation!
55
+
56
+ # Fix Session ID bug
57
+
58
+ ## Hypotheses
59
+
60
+ 1. The bug refers to where `writeAgentSessionSettings` is called with an empty `env: {}`. We probably need to set `SESSION_ID: extractedSessionId` in the `env` object.
61
+
62
+ ## Implementation
63
+
64
+ The issue indicates that we need to set the extracted session ID in the environment of the initial agent session settings.
65
+
66
+ In `src/daemon/message.ts`, the daemon creates initial agent session settings by writing an empty `env: {}` object when `getSessionId` successfully extracts the session ID from the `new` command's output.
67
+
68
+ We update this logic to save the extracted session ID as `SESSION_ID` in the `env` object:
69
+
70
+ ```typescript
71
+ await writeAgentSessionSettings(
72
+ agentId,
73
+ extractedSessionId,
74
+ { env: { SESSION_ID: extractedSessionId } },
75
+ cwd
76
+ );
77
+ ```
78
+
79
+ This ensures that on subsequent messages for the same session (using the `append` command), the daemon injects ``into the child process's environment variables. We also updated the corresponding unit test in`message.test.ts` to verify this new behavior.
@@ -0,0 +1,40 @@
1
+ # Notes for Sessions Feature
2
+
3
+ ## Current Implementation
4
+ - **CLI Command**: `clawmini messages send "hi" [-c <chatId>]` sends a `send-message` mutation to the daemon.
5
+ - **Daemon Handling**: `router.ts` reads the global `.clawmini/settings.json` to get agent config (`defaultAgent.commands.new`). It passes this to `handleUserMessage` in `message.ts`.
6
+ - **Message Execution**: `handleUserMessage` sets the `CLAW_CLI_MESSAGE` environment variable and runs the command.
7
+ - **Output Logging**: `router.ts` spawns the command, captures `stdout` and `stderr`, and saves a `CommandLogMessage` via `appendMessage`.
8
+ - **Storage**: Chats are stored in `.clawmini/chats/<chatId>/chat.jsonl`.
9
+
10
+ ## Proposed Architecture
11
+ - **Agent Configuration Update**: Agents need new commands in `.clawmini/settings.json`:
12
+ - `new`: Starts a new session.
13
+ - `append`: Appends to a session.
14
+ - `getSessionId`: A shell command that takes the stdout of `new` via stdin and prints the session ID.
15
+ - `getMessageContent`: A shell command that takes the stdout of `new` or `append` via stdin and prints the message content.
16
+ - **Chat State**: Each chat gets a `settings.json` at `.clawmini/chats/<chatId>/settings.json`:
17
+ ```json
18
+ {
19
+ "defaultAgent": "default",
20
+ "sessions": {
21
+ "default": "<sessionId>" // The ID from --session or 'default'
22
+ }
23
+ }
24
+ ```
25
+ - **Agent Session State**: Each agent session gets a `settings.json` at `.clawmini/agents/<agentId>/sessions/<sessionId>/settings.json`:
26
+ ```json
27
+ {
28
+ "env": {
29
+ "SESSION_ID": "<agent's internal session id>"
30
+ }
31
+ }
32
+ ```
33
+ - **Execution Flow (`messages send`)**:
34
+ 1. Determine `sessionId`: use `--session` if provided. Otherwise, read `.clawmini/chats/<chatId>/settings.json` to get `defaultAgent` and its associated `<sessionId>`. If still not found, use `'default'`.
35
+ 2. Check if `.clawmini/agents/<agentId>/sessions/<sessionId>/settings.json` exists.
36
+ 3. If it exists, execute `append` command (passing the internal `SESSION_ID` in `env` from the session's `settings.json`).
37
+ 4. If session doesn't exist, execute `new`.
38
+ 5. After `new`, run `getSessionId` passing `new`'s stdout via stdin. Save the extracted internal session ID to `.clawmini/agents/<agentId>/sessions/<sessionId>/settings.json`. Update chat's `settings.json` with the new `<sessionId>`.
39
+ 6. After either `new` or `append`, run `getMessageContent` passing the stdout via stdin. Extract the message text.
40
+ 7. Write output logs (`CommandLogMessage`) to `.clawmini/chats/<chatId>/chat.jsonl`, including both the raw stdout and the extracted message text (if any).
@@ -0,0 +1,75 @@
1
+ # Product Requirements Document: Chat Sessions
2
+
3
+ ## 1. Vision & Goals
4
+
5
+ Currently, sending a message to the agent always spawns a fresh process with no memory of the prior context unless the agent itself happens to maintain it invisibly. The "Sessions" feature introduces the capability for `clawmini` to persistently identify and track agent sessions, allowing users to send subsequent messages that extend an existing conversation.
6
+
7
+ The primary goals of this feature are:
8
+ - Introduce persistent session states for agent conversations.
9
+ - Differentiate between starting a new session and appending to an existing one.
10
+ - Enable `clawmini` to extract internal agent session IDs and message content from arbitrary outputs via shell commands.
11
+ - Track mapping between `clawmini` chats and agent sessions locally.
12
+
13
+ ## 2. Product / Market Background
14
+
15
+ AI agents (like LLMs or specialized CLI agents) often require state to maintain context across multiple turns of a conversation. By giving `clawmini` the ability to store a session identifier locally and pass it back to the agent in subsequent commands, we enable stateful conversational loops. This maps well to how users expect standard chat applications or LLM tools to operate.
16
+
17
+ ## 3. Use Cases
18
+
19
+ 1. **Continuing a Conversation**: A user runs `clawmini messages send "Hello"` and a new agent session is started. They then run `clawmini messages send "What did I just say?"` and the CLI sends the message to the same session, allowing the agent to reply accurately based on the history.
20
+ 2. **Multiple Agent States in One Chat**: A user can use `--session foo` to interact with session `foo`, then switch to `--session bar` within the same chat workspace.
21
+ 3. **Structured Agent Responses**: Agents returning complex structures (JSON, YAML, custom text) can have their exact message and session IDs extracted via standard shell pipelines (e.g., using `jq` or `grep`), without enforcing a rigid output format on the agent.
22
+
23
+ ## 4. Requirements
24
+
25
+ ### 4.1 CLI Interface Updates
26
+ - Update the `messages send <message>` command to support an optional `--session <id>` flag.
27
+ - **Session Resolution Logic:**
28
+ - If `--session` is provided, use that session ID.
29
+ - If not provided, read the chat's `settings.json` (at `.clawmini/chats/<chatId>/settings.json`) to find the active session for the `defaultAgent`.
30
+ - If no session is found in the chat settings, default to the ID `'default'`.
31
+
32
+ ### 4.2 Agent Configuration Updates
33
+ Agents defined in `.clawmini/settings.json` will require updated fields:
34
+ - `commands.new`: The command used to initialize a new session.
35
+ - `commands.append`: The command used to append a message to an existing session.
36
+ - `commands.getSessionId`: A shell command that takes the stdout of `new` via `stdin` and outputs the internal session ID.
37
+ - `commands.getMessageContent`: A shell command that takes the stdout of `new` or `append` via `stdin` and outputs the text content to show to the user.
38
+
39
+ ### 4.3 Data Storage & State Management
40
+ - **Chat State**: Maintained at `.clawmini/chats/<chatId>/settings.json`.
41
+ ```json
42
+ {
43
+ "defaultAgent": "default",
44
+ "sessions": {
45
+ "default": "<sessionId>"
46
+ }
47
+ }
48
+ ```
49
+ - **Agent Session State**: Maintained at `.clawmini/agents/<agentId>/sessions/<sessionId>/settings.json`.
50
+ ```json
51
+ {
52
+ "env": {
53
+ "SESSION_ID": "<agent's internal session id>"
54
+ }
55
+ }
56
+ ```
57
+
58
+ ### 4.4 Execution Flow (Daemon)
59
+ When a `send-message` request is processed by the daemon:
60
+ 1. Identify the target `chatId` and `sessionId` (based on the CLI request and chat settings).
61
+ 2. Determine if the agent session exists by checking for `.clawmini/agents/<defaultAgent>/sessions/<sessionId>/settings.json`.
62
+ 3. **If the session exists:**
63
+ - Construct the environment, injecting the agent's internal `SESSION_ID` from the session settings.
64
+ - Execute the `commands.append` command.
65
+ 4. **If the session does not exist:**
66
+ - Execute the `commands.new` command.
67
+ 5. **Post-Execution Extraction:**
68
+ - If a new session was started and `commands.getSessionId` is defined, spawn the `getSessionId` command, writing the `new` command's stdout to its `stdin`. Read the resulting output as the internal session ID. Save this to the agent session settings file, and update the chat settings file.
69
+ - If `commands.getMessageContent` is defined, spawn it, writing the `new`/`append` command's stdout to its `stdin`. Read the resulting output as the extracted message text.
70
+ - Persist the execution details in the chat log (`chat.jsonl`), including both the raw stdout and the extracted message text (if applicable).
71
+
72
+ ## 5. Non-Functional Concerns
73
+ - **Dependencies**: No external JSON parsers (like `jsonpath-plus`) are required. The host system's shell environment (and tools like `jq` or `awk`) will be used via the agent's configured extraction commands.
74
+ - **Error Handling**: Gracefully handle failures in the `getSessionId` or `getMessageContent` commands (e.g., command not found, pipeline failures). Log these errors to `chat.jsonl` as `stderr` so the user is informed of the extraction failure. Provide fallbacks where appropriate (e.g., using raw stdout if text extraction fails).
75
+ - **Security**: The `SESSION_ID` read from `settings.json` and injected into the environment must not allow command injection; relying on `child_process.spawn` with `env` blocks is safe, provided we use it correctly without arbitrary string interpolation in the shell. Running arbitrary shell commands via `getSessionId` and `getMessageContent` follows the same security model as `new` and `append`.
@@ -0,0 +1,7 @@
1
+ # Questions for Sessions Feature
2
+
3
+ **Q1: What syntax or library should we use for the JSON queries in `getSessionId` and `getMessageContent`? Should we use a full JSONPath library (e.g., `jsonpath-plus`) or stick to simple dot-notation parsing to keep dependencies minimal?**
4
+ A1: Actually, let's use shell commands for `getSessionId` and `getMessageContent` that execute with the output of `new`/`append` sent into them as stdin. This removes the dependency on jsonpath and any assumptions that the output is JSON (callers can use jq to parse).
5
+
6
+ **Q2: How should the system generate or determine the `<sessionId>` assigned to a chat in `.clawmini/chats/<chatId>/settings.json`? Should it generate a UUID (e.g. `uuidv4`) for new sessions, or something else?**
7
+ A2: For now, let's have a --session flag that can specify the session ID. If unspecified, first check the settings; then use 'default' if none
@@ -0,0 +1,68 @@
1
+ # Tickets: Sessions Feature
2
+
3
+ ## Ticket 1: Update Configuration Schema & Types
4
+ **Description**: Update the agent configuration types and Zod schemas in `src/shared/config.ts` to support the new commands structure (`new`, `append`, `getSessionId`, `getMessageContent`). Ensure usage of Zod 4 best practices (e.g., `z.record(z.string(), z.string())` for records).
5
+ **Verification**:
6
+ - `npm run check`
7
+ - `npm run test`
8
+ **Status**: complete
9
+
10
+ ## Ticket 2: CLI Flag for Sessions
11
+ **Description**: Update the CLI `messages send` command in `src/cli/commands/messages.ts` to accept an optional `-s, --session <id>` flag. Pass the session ID to the TRPC `send-message` payload.
12
+ **Verification**:
13
+ - Add E2E tests verifying flag parsing and payload structure.
14
+ - `npm run test`
15
+ - `npm run check`
16
+ - `npm run lint`
17
+ **Status**: complete
18
+
19
+ ## Ticket 3: State Storage Utilities
20
+ **Description**: Implement read/write utilities in `src/shared/workspace.ts` to manage Chat State (`.clawmini/chats/<chatId>/settings.json`) and Agent Session State (`.clawmini/agents/<agentId>/sessions/<sessionId>/settings.json`).
21
+ **Verification**:
22
+ - Write unit tests for the new storage utility functions.
23
+ - `npm run test`
24
+ - `npm run check`
25
+ **Status**: complete
26
+
27
+ ## Ticket 4: Daemon Session Resolution & Execution
28
+ **Description**: Update `handleUserMessage` in `src/daemon/message.ts` to resolve the `sessionId` (CLI `--session` -> chat settings -> `'default'`). Check if the agent session state file exists. If it exists, execute `commands.append` (injecting `SESSION_ID` into the `env`). If not, execute `commands.new`.
29
+ **Verification**:
30
+ - Add unit tests mocking `node:child_process.spawn` to verify correct commands and environment variables are used.
31
+ - `npm run test`
32
+ - `npm run check`
33
+ **Status**: complete
34
+
35
+ ## Ticket 5: Command Extraction & State Updates
36
+ **Description**: Implement the extraction logic in the daemon after the primary command finishes. Spawn `getSessionId` (if it was a new session) and `getMessageContent` (if defined), piping the main command's stdout to their stdin. Parse the outputs and update the Chat and Agent Session settings files.
37
+ **Verification**:
38
+ - Add unit tests verifying stdin piping and correct state file updates upon success.
39
+ - `npm run test`
40
+ - `npm run check`
41
+ **Status**: complete
42
+
43
+ ## Ticket 6: Logging & Final Integration
44
+ **Description**: Update the `CommandLogMessage` structure in the chat log (`chat.jsonl`) to include both raw stdout and extracted message text. Gracefully handle extraction command failures by logging them as `stderr` in `chat.jsonl`. Complete the feature by writing an E2E test covering the full multi-message session workflow.
45
+ **Verification**:
46
+ - Full suite of E2E tests in an isolated sandbox testing the daemon and CLI workflows.
47
+ - `npm run build`
48
+ - `npm run check`
49
+ - `npm run lint`
50
+ - `npm run test`
51
+ **Status**: complete
52
+
53
+ ## Ticket 7: DRY Violation in `src/shared/workspace.ts`
54
+ **Priority**: High
55
+ **Description**: The read/write functions for `ChatSettings` and `AgentSessionSettings` contain duplicate file reading, JSON parsing, and directory creation logic. They also unnecessarily use synchronous `fs.existsSync` inside an async function.
56
+ **Verification**:
57
+ - Extract a generic `readJsonFile` and `writeJsonFile` utility.
58
+ - Use `fsPromises.mkdir` natively (with `recursive: true` and swallowing `EEXIST` implicitly) instead of sync directory checking.
59
+ - `npm run format`, `npm run lint`, `npm run check`, `npm run test`.
60
+ **Status**: complete
61
+
62
+ ## Ticket 8: DRY Violation in `src/daemon/message.ts`
63
+ **Priority**: Medium
64
+ **Description**: `extractSessionId` and `extractMessageContent` contain nearly identical execution and error handling logic for running extraction commands.
65
+ **Verification**:
66
+ - Extract a generic `runExtractionCommand` utility.
67
+ - `npm run format`, `npm run lint`, `npm run check`, `npm run test`.
68
+ **Status**: complete
@@ -0,0 +1,60 @@
1
+ # Development Log: Web Interface
2
+
3
+ ## Feb 24, 2026 - Initial SvelteKit Setup (Step 1)
4
+
5
+ - Initialized a new SvelteKit application using the minimal Svelte 5 and Vite 7 template in the `web/` directory.
6
+ - Installed `tailwindcss` (v4), `@tailwindcss/vite`, `lucide-svelte`, `clsx`, and `tailwind-merge` to fulfill the `shadcn-svelte` prerequisites.
7
+ - Configured SvelteKit with `@sveltejs/adapter-static` using the `fallback: 'index.html'` option for single-page application (SPA) behavior.
8
+ - Updated root `eslint.config.js` to ignore the `.svelte-kit` and `build` folders generated by the Vite build step, preventing linting errors on generated server artifacts.
9
+ - Added a `build:web` command to the root `package.json` that hooks into the main `npm run build` command, compiling the Svelte SPA directly into the workspace `dist/web` directory where the Node.js server will serve it from.
10
+ - All workspace checks passing successfully.
11
+
12
+ ## Feb 24, 2026 - Web Server Implementation (Step 2)
13
+
14
+ - Implemented `clawmini web` command in `src/cli/commands/web.ts` using `node:http`.
15
+ - The server binds to `127.0.0.1` and serves static files from `dist/web`, with a fallback to `dist/web/index.html` for SPA routing.
16
+ - Added a basic mime type map to serve correct content types for static assets.
17
+ - Addressed an issue where `tsdown`'s `clean: true` was deleting the `dist/web` directory generated by `build:web`. Updated root `package.json` build script to `tsdown && npm run build:web` to ensure static files are preserved.
18
+ - Added E2E tests in `src/cli/e2e.test.ts` to verify the web server starts correctly, serves the `index.html` file, and falls back gracefully for unknown routes.
19
+ - All workspace checks pass successfully.
20
+
21
+ ## Feb 24, 2026 - Implemented REST API Endpoints (Step 3)
22
+
23
+ - Added routing logic to the Node.js server in `src/cli/commands/web.ts` to handle `/api/*` endpoints.
24
+ - Implemented `GET /api/chats` to return a list of chats utilizing the shared `listChats` function.
25
+ - Implemented `GET /api/chats/:id` to return the chat history utilizing the shared `getMessages` function.
26
+ - Implemented `POST /api/chats/:id/messages` to receive JSON body `{"message": "..."}` and forward it to the daemon via the UNIX socket using `getDaemonClient().sendMessage.mutate`.
27
+ - Added permissive CORS headers (`Access-Control-Allow-Origin`, etc.) to the API routes to allow frontend dev servers to proxy easily.
28
+ - Added comprehensive integration tests in `src/cli/e2e.test.ts` to verify the endpoints correctly read from the file system, list chats, parse the JSON body, and interact with the daemon client.
29
+ - Fixed minor TypeScript errors related to `RegExpMatchArray` bounds and potentially undefined arrays.
30
+ - All verification steps and tests pass successfully.
31
+
32
+ ## Feb 24, 2026 - Server-Sent Events (SSE) Endpoint (Step 4)
33
+
34
+ - Implemented `GET /api/chats/:id/stream` in `src/cli/commands/web.ts` to push real-time updates to connected clients.
35
+ - Used `node:fs` module's `fs.watch` and `fs.createReadStream` to listen for file changes on the specific chat's `chat.jsonl` log file, handling chunking logic carefully to ensure individual messages are read and streamed accurately as Server-Sent Events.
36
+ - Correctly ensured the stream correctly gracefully initializes a blank chat file using `createChat` if a stream request is made for an empty but valid route, preventing 404 read stream errors.
37
+ - Created robust end-to-end integration tests within `e2e.test.ts` mapping the Web Server's child process flow, executing an programmatic file append, and reading the `EventSource` stream through native Fetch `body.getReader` methods to assert real-time event ingestion.
38
+ - Ensured all standard lint, formatting, typescript compiler, and unit test checks ran smoothly.
39
+ ## Feb 25, 2026 - Frontend UI - Layout & Sidebar (Step 5)
40
+ - Added missing shadcn-svelte UI components via the CLI.
41
+ - Implemented the main layout in SvelteKit using Sidebar.Provider.
42
+ - Implemented load function in SvelteKit to fetch /api/chats.
43
+ - Added proxy to SvelteKit vite.config.ts for local dev.
44
+ - Added vitest-browser tests for the AppSidebar.
45
+ - Fixed SvelteKit adapter-static to allow SPA by removing prerender=true.
46
+ ## Feb 25, 2026 - Frontend UI - Chat Pane & Message Input (Step 6)
47
+ - Created web/src/lib/types.ts defining ChatMessage, UserMessage, and CommandLogMessage.
48
+ - Implemented web/src/routes/chats/[id]/+page.svelte with actual message history viewing.
49
+ - Designed chat history UI differentiating user messages and log messages.
50
+ - Formatted log message rendering to be mono-spaced and styled error blocks in red.
51
+ - Created fixed bottom input area via fixed layout allowing scrolling of history above it.
52
+ - Implemented sendMessage binding on forms to POST /api/chats/:id/messages endpoints.
53
+ - Authored component specs ensuring distinct elements for different message kinds using vitest-browser-svelte.
54
+ - Note to self: SvelteKit tests mirroring a Svelte route component like +page.svelte must not include a + in their test file name.
55
+ ## Feb 25, 2026 - Frontend UI - SSE Integration (Step 7)
56
+ - Implemented standard EventSource logic in web/src/routes/chats/[id]/+page.svelte.
57
+ - Refactored data.messages into liveMessages state array synced natively.
58
+ - Connected the component mount and update lifecycle with the GET /api/chats/:id/stream SSE endpoint.
59
+ - Correctly bounded EventSource.onmessage to parse JSON from the socket stream and append new messages.
60
+ - Implemented automatic scroll pinning with Svelte's $effect primitive.
@@ -0,0 +1,29 @@
1
+ # Notes on Web Interface Feature
2
+
3
+ ## Current Architecture
4
+ - `clawmini` is a CLI tool that runs a background daemon (`src/daemon/index.ts`).
5
+ - Communication with the daemon currently happens over a UNIX socket via `tRPC` (`@trpc/server/adapters/standalone`).
6
+ - Chat data is persisted in a local directory structure: `.clawmini/chats/<chat_id>/chat.jsonl`.
7
+ - `src/shared/chats.ts` provides file-system utilities for reading/writing `ChatMessage`s (`UserMessage` or `CommandLogMessage`).
8
+
9
+ ## Web Interface Concept
10
+ - A new command: `clawmini web` which will spawn an HTTP web server on a local TCP port (e.g., 8080).
11
+ - **Backend (API)**:
12
+ - Needs to expose API endpoints for a generic Web UI to connect to.
13
+ - Can read the file system directly using `src/shared/chats.ts` functions or forward actions to the daemon via the existing tRPC socket (to execute commands, etc.).
14
+ - Real-time updates ("pushed any new messages when they arrive") will require either Server-Sent Events (SSE) or WebSockets. File watching (`chokidar` or `fs.watch`) on `chat.jsonl` files or tapping into the daemon's tRPC events can provide the trigger.
15
+ - **Frontend (UI)**:
16
+ - Basic layout: Sidebar (list of chats), Main pane (Chatbox, list of messages).
17
+ - Must be served essentially as a "static" site. If the user hits `localhost:8080/chats/foo`, the server should serve the `index.html` fallback (SPA routing) so the frontend router handles the display.
18
+ - SvelteKit is preferred by the user. SvelteKit's `adapter-static` enables building an SPA that fits exactly this requirement (static files with client-side routing and fallbacks).
19
+
20
+ ## Technology Choices & Integration
21
+ 1. **Frontend Framework**:
22
+ - **Svelte/SvelteKit** (Preferred): Excellent for small, reactive apps. We can build it as an SPA using `@sveltejs/adapter-static` with `fallback: 'index.html'`. The compiled output (HTML/JS/CSS) can be bundled into the `dist/web` directory when the CLI is built, and `clawmini web` will just serve these static files using a basic node server.
23
+ - **Vanilla/Web Components**: Easiest integration (no build step for the CLI besides basic TS compilation), but higher development cost for reactive features and UI components.
24
+ - **React (Vite)**: Similar to SvelteKit, requires a separate build step.
25
+ 2. **API / HTTP Server**:
26
+ - We could use a lightweight web framework like `Express`, `Hono`, or `Fastify` for the `clawmini web` server.
27
+ - The server will serve the Svelte static files AND expose `/api/*` routes.
28
+ 3. **Real-time Updates**:
29
+ - Server-Sent Events (SSE) over HTTP is simpler to implement than WebSockets since it works over standard HTTP without additional upgrade logic, perfect for a one-way "push" of new messages.
@@ -0,0 +1,42 @@
1
+ # PRD: Web Interface for Clawmini (`clawmini web`)
2
+
3
+ ## Vision
4
+ The goal is to provide a local, web-based graphical user interface for `clawmini` that runs alongside the CLI. This interface will allow users to comfortably view their active workspaces, chat sessions, and command outputs in a richer, more persistent format than a standard terminal output.
5
+
6
+ ## Product/Market Background
7
+ `clawmini` operates as a daemonized local AI agent. While the CLI is fast and scriptable, interpreting long chat histories, comparing multi-turn outputs, or simply managing multiple parallel chats can be cumbersome in a pure terminal environment. A dedicated Web UI bridges this gap, offering the ergonomics of modern web applications without compromising the local, file-based architecture of the CLI. The decision to use SvelteKit and Tailwind/shadcn-svelte aligns with modern rapid prototyping preferences, enabling a high-quality UI while shipping as a static asset.
8
+
9
+ ## Use Cases
10
+ 1. **Visual Chat History:** A user wants to review a complex, multi-turn conversation with the agent, complete with distinct visual separation for user messages, daemon logs, and command execution results.
11
+ 2. **Live Monitoring:** A user runs a long-running task via the CLI and wants to monitor the agent's progress and thought process in a dedicated browser tab.
12
+ 3. **Chat Management:** A user wants to easily switch between different chat sessions (e.g., "feature-x", "bugfix-y") using a visual sidebar without needing to type `clawmini chats list` and `clawmini chats set-default`.
13
+ 4. **API Extensibility:** A developer wants to build a custom dashboard that interacts with the `clawmini` local data. The web server must expose clean REST/SSE endpoints.
14
+
15
+ ## Requirements
16
+
17
+ ### Architecture
18
+ 1. **Separate Server Process:** The `clawmini web` command will spin up a new Node.js HTTP server. This server runs independently but communicates with the existing `clawmini` daemon (via its UNIX socket) to execute actions.
19
+ 2. **Static UI Assets:** The frontend will be a SvelteKit application built using `@sveltejs/adapter-static` with an `index.html` fallback. The compiled assets will be bundled into the CLI package (e.g., `dist/web`) and served statically by the `clawmini web` Node server.
20
+ 3. **API Endpoints:** The Node server must expose `/api/*` endpoints to handle data requests from the frontend or third-party tools.
21
+ - `GET /api/chats` - List available chats.
22
+ - `GET /api/chats/:id` - Get history for a specific chat.
23
+ - `POST /api/chats/:id/messages` - Send a new message to the daemon (proxied to the UNIX socket).
24
+
25
+ ### Real-Time Updates (SSE)
26
+ 1. **Server-Sent Events:** The server must provide a `GET /api/chats/:id/stream` endpoint.
27
+ 2. **File Watching:** This endpoint will use `node:fs` watchers on the respective `.clawmini/chats/:id/chat.jsonl` file. When the file is appended to by the daemon, the server must push the new `ChatMessage` to connected SSE clients.
28
+
29
+ ### User Interface (SvelteKit + TailwindCSS + shadcn-svelte)
30
+ 1. **Layout:** A standard two-pane layout:
31
+ - **Sidebar:** Lists all available chats. Highlights the currently selected chat.
32
+ - **Main Area:** Displays the message history of the selected chat. Includes a text input area at the bottom to send new messages.
33
+ 2. **Message Rendering:** Must differentiate between `UserMessage` and `CommandLogMessage` types visually. Command logs should ideally show standard output/error distinctly.
34
+ 3. **Routing:** Standard SPA routing. Hitting `localhost:8080/chats/foo` directly must load the UI and fetch the `foo` chat history.
35
+
36
+ ### Constraints & Considerations
37
+ - **Security:** The web server runs locally. It should bind to `127.0.0.1` (localhost) by default to prevent unauthorized network access unless a specific host flag is provided.
38
+ - **Build Process:** The `package.json` needs to be updated to build the SvelteKit project into a static directory before or alongside the `tsdown` build for the CLI.
39
+
40
+ ## Non-Goals
41
+ - Authentication (it's a local development tool).
42
+ - Cloud syncing of chats (handled by git/filesystem natively if the user chooses).
@@ -0,0 +1,8 @@
1
+ # Questions for Web Interface Feature
2
+
3
+ ## Q1: Web Server vs Daemon Roles
4
+ **Q:** Should `clawmini web` spin up a separate HTTP server process (e.g., at `localhost:8080`) that bridges to the existing Unix socket daemon, or should the daemon itself be modified to optionally listen on a TCP port and serve the web UI/API?
5
+ **A:** `clawmini web` should spin up a separate HTTP server that communicates with the daemon via its Unix socket.
6
+ \n## Q2: SvelteKit Integration\n**Q:** SvelteKit integration requires a dual-build setup with `@sveltejs/adapter-static`. Are you comfortable with this approach?\n**A:** Let's try SvelteKit and see how it goes.
7
+ \n## Q3: Real-time Updates (SSE vs WebSockets)\n**Q:** Is an SSE approach driven by file-watching acceptable for pushing updates to the UI, or do you prefer WebSockets?\n**A:** Yes, SSE sounds great!
8
+ \n## Q4: CSS Preferences\n**Q:** Should we strictly use vanilla CSS to keep dependencies light, or would you prefer a styling framework like TailwindCSS (v3 or v4)?\n**A:** Yeah, let's use tailwind + shadcn-svelte for ui.
@@ -0,0 +1,59 @@
1
+ # Tickets: Web Interface (`clawmini web`)
2
+
3
+ In general, prefer shadcn-svelte UI components when they exist.
4
+
5
+ ## Step 1: Initialize SvelteKit Frontend
6
+
7
+ - **Description:** Scaffold a new SvelteKit project (e.g., in a `web/` directory) configured with `@sveltejs/adapter-static` and an `index.html` fallback. Set up TailwindCSS and shadcn-svelte. Update the root `package.json` to include a build script that compiles the SvelteKit app and outputs the static assets to `dist/web`.
8
+ - **Verification:**
9
+ - Running `npm run build` at the root successfully generates `dist/web/index.html`.
10
+ - All standard checks pass: `npm run format:check && npm run lint && npm run check && npm run test`.
11
+ - **Status:** Complete
12
+
13
+ ## Step 2: Implement `clawmini web` Command & Static Server
14
+
15
+ - **Description:** Create the `src/cli/commands/web.ts` command. Implement a local Node.js HTTP server that binds to `127.0.0.1` (with a configurable `--port` flag, defaulting to 8080). Configure the server to serve static files from `dist/web` and fallback to `dist/web/index.html` for unknown routes (to support SPA routing).
16
+ - **Verification:**
17
+ - Add a CLI test that runs `clawmini web --port 8080` in the background, curls `http://127.0.0.1:8080/`, and asserts a 200 OK response containing the HTML.
18
+ - All standard checks pass: `npm run format:check && npm run lint && npm run check && npm run test`.
19
+ - **Status:** Complete
20
+
21
+ ## Step 3: Implement REST API Endpoints
22
+
23
+ - **Description:** Add routing logic to the Node.js server for `/api/*`. Implement `GET /api/chats` (list chats), `GET /api/chats/:id` (get chat history), and `POST /api/chats/:id/messages` (send a message to the daemon via the UNIX socket using the existing tRPC client).
24
+ - **Verification:**
25
+ - Add integration tests for the new HTTP API endpoints to verify they correctly read from the file system and forward messages to the daemon.
26
+ - All standard checks pass: `npm run format:check && npm run lint && npm run check && npm run test`.
27
+ - **Status:** Complete
28
+
29
+ ## Step 4: Implement Server-Sent Events (SSE) Endpoint
30
+
31
+ - **Description:** Implement `GET /api/chats/:id/stream` in the web server. Use `node:fs` to watch the corresponding `.clawmini/chats/:id/chat.jsonl` file. Push new messages as Server-Sent Events to connected clients and ensure watchers are properly cleaned up on disconnect.
32
+ - **Verification:**
33
+ - Write a test that connects to the SSE endpoint, simulates a daemon appending a message to the `chat.jsonl` file programmatically, and verifies the event is received.
34
+ - All standard checks pass: `npm run format:check && npm run lint && npm run check && npm run test`.
35
+ - **Status:** Complete
36
+
37
+ ## Step 5: Frontend UI - Layout & Sidebar
38
+
39
+ - **Description:** In the SvelteKit app, build the main two-pane layout. Use the shadcn-svelte sidebar component to fetch and display the list of available chats from `GET /api/chats`. Add client-side routing to navigate to `/chats/:id` and visually highlight the active chat.
40
+ - **Verification:**
41
+ - Add basic component/unit tests in the SvelteKit project to ensure the sidebar renders a mock list of chats correctly.
42
+ - All standard checks pass: `npm run format:check && npm run lint && npm run check && npm run test`.
43
+ - **Status:** Complete
44
+
45
+ ## Step 6: Frontend UI - Chat Pane & Message Input
46
+
47
+ - **Description:** Implement the Main Area of the UI. Fetch and display the message history for the selected chat from `GET /api/chats/:id`. Differentiate visually between `UserMessage` and `CommandLogMessage` (e.g., standard output vs. standard error). Add a text input to post new messages via `POST /api/chats/:id/messages`.
48
+ - **Verification:**
49
+ - Add component tests to verify that `UserMessage` and `CommandLogMessage` are rendered with distinct visual styles.
50
+ - All standard checks pass: `npm run format:check && npm run lint && npm run check && npm run test`.
51
+ - **Status:** Complete
52
+
53
+ ## Step 7: Frontend UI - SSE Integration
54
+
55
+ - **Description:** Connect the SvelteKit frontend to the `GET /api/chats/:id/stream` endpoint using the `EventSource` API. Automatically append new messages to the chat history in real-time as they arrive. Implement basic auto-scrolling to the latest message.
56
+ - **Verification:**
57
+ - Add a test or mock simulating an SSE message arrival and verify the UI state updates to include the new message.
58
+ - All standard checks pass: `npm run format:check && npm run lint && npm run check && npm run test`.
59
+ - **Status:** Complete
@@ -0,0 +1,54 @@
1
+ # Development Log
2
+
3
+ ## Ticket 1: Core Configuration and Workspace Utility for Agents
4
+
5
+ - **Implementation**:
6
+ - Extracted `AgentSchema` and `Agent` type to `src/shared/config.ts`.
7
+ - Added utility functions in `src/shared/workspace.ts`: `getAgent`, `listAgents`, `writeAgentSettings`, `deleteAgent`.
8
+ - Implemented `isValidAgentId` to prevent directory traversal attacks by disallowing paths with `../` or `/` or ``.
9
+ - Re-wrote `src/shared/workspace.test.ts` to include tests for all the new functionality and path resolution methods.
10
+ - **Fixes**: Fixed a pre-existing lint issue in `src/cli/commands/web.ts` where a caught error `err` was unused.
11
+ - **Verification**: Ran `npm run format && npm run lint && npm run check && npm run test`, all checks passed. Tests run smoothly, including E2E.
12
+
13
+
14
+ ## Ticket 2: Daemon Support for Agent Execution
15
+
16
+ - **Implementation**:
17
+ - Updated `src/daemon/message.ts` to fetch the chat`'s active agent and override the `defaultAgent` configurations dynamically.
18
+ - Resolved `directory` relative to the workspace root using `getWorkspaceRoot(cwd)` to securely scope execution paths.
19
+ - Allowed merging of custom agent `env` and `commands` correctly.
20
+ - Added test cases in `src/daemon/message.test.ts` to explicitly test configuration merging and working directory assignments.
21
+ - **Fixes**: Fixed `message.test.ts` failing mock bindings after `getAgent` and `getWorkspaceRoot` were added to the `../shared/workspace.js` mock.
22
+ - **Verification**: Ran `npm run format && npm run lint && npm run check && npm run test`, all checks passed. Tests run smoothly, including the e2e tests.
23
+ \n## Ticket 3: Agent CLI Commands (Add, Update, Delete, List)\n\n- **Implementation**:\n - Created `src/cli/commands/agents.ts` with `add`, `update`, `list`, and `delete` subcommands using commander.\n - Added support for parsing multiple `--env KEY=VALUE` flags into an object record.\n - Hooked up `--directory` flag to set the agent's `directory` setting.\n - Imported and registered `agentsCmd` inside `src/cli/index.ts`.\n - Wrote robust E2E tests in `src/cli/e2e.test.ts` simulating adding, listing, updating and deleting an agent.\n- **Verification**: Ran formatting, linting, type-check, and vitest test cases. All passed.
24
+
25
+ ## Ticket 4: CLI Support for Selecting an Agent per Chat
26
+
27
+ - **Implementation**:
28
+ - Updated `src/cli/commands/messages.ts` `send` command to include a new `-a, --agent <name>` flag.
29
+ - Implemented validation for the selected agent by leveraging `isValidAgentId` and verifying its existence using `getAgent`. If the agent fails validation, the CLI gracefully exits with a clear error message.
30
+ - Added logic to automatically persist the selected agent to the chat's `settings.json` file using `readChatSettings` and `writeChatSettings`.
31
+ - Added new E2E tests in `src/cli/e2e.test.ts` to ensure setting the agent works, persists, and using an invalid agent fails appropriately. Also increased the vitest `beforeAll` and `afterAll` hook timeouts for e2e tests from default to 30000ms.
32
+ - **Verification**: Ran `npm run format && npm run lint && npm run check && npm run test`, all checks passed.
33
+
34
+
35
+ ## Ticket 5: Web UI API Endpoints for Agents
36
+
37
+ - **Implementation**:
38
+ - Updated the internal HTTP server in `src/cli/commands/web.ts` to include REST endpoints for agent management under `/api/agents` and `/api/agents/:id`.
39
+ - Added support for `GET`, `POST` (create), `PUT`/`POST` (update), and `DELETE` on these endpoints.
40
+ - Used shared utilities `listAgents`, `getAgent`, `writeAgentSettings`, `deleteAgent`, and `isValidAgentId` from `src/shared/workspace.ts` to ensure interactions are secure.
41
+ - Added API testing to the `should run web command and serve static files` test block in `src/cli/e2e.test.ts` to ensure proper routing, data returning, and persistence.
42
+ - **Verification**: Ran `npm run format && npm run lint && npm run check && npm run test`, fixed ESLint warnings for explicit `any` usage. All checks passed.
43
+
44
+ ## Ticket 6: Web UI Integration for Agent Management & Chat Creation
45
+
46
+ - **Implementation**:
47
+ - Updated src/cli/commands/web.ts POST /api/chats endpoint to accept an optional agent parameter and save it into the chat settings via writeChatSettings.
48
+ - Updated the SvelteKit loader in web/src/routes/+layout.ts to fetch and expose the list of agents so it is globally accessible across the UI.
49
+ - Modified the New Chat dialog within web/src/lib/components/app/app-sidebar.svelte to include an optional dropdown for choosing an initial agent from the fetched agents list.
50
+ - Created a dedicated Agent Management page at web/src/routes/agents/+page.svelte featuring a clean grid layout of existing agents.
51
+ - Provided functionality within the Agents page to view, create, edit, and delete agents. Environment variables are managed efficiently through parsed multiline inputs.
52
+ - Added types and ensured strict TS compatibility across app-sidebar.svelte and the data properties in layout and test mock files.
53
+ - **Fixes**: Reconciled a bug in Svelte tests where agents array was missing in mockData, and updated Svelte page properties type bindings.
54
+ - **Verification**: Ran npm run format:check && npm run lint && npm run check && npm run test, all checks passed. UI changes are fully tested natively.
@@ -0,0 +1,45 @@
1
+ # Notes on Agents Feature
2
+
3
+ ## Current State
4
+
5
+ - `settings.json` in the workspace root (`.clawmini/settings.json`) currently contains a `defaultAgent` object with the schema:
6
+ ```json
7
+ {
8
+ "defaultAgent": {
9
+ "commands": {
10
+ "new": "...",
11
+ "append": "...",
12
+ "getSessionId": "...",
13
+ "getMessageContent": "..."
14
+ },
15
+ "env": {
16
+ "KEY": "VALUE"
17
+ }
18
+ }
19
+ }
20
+ ```
21
+ - Each chat has its own `settings.json` at `.clawmini/chats/<chatId>/settings.json`, which currently just maps a `defaultAgent` string to a session ID (wait, it just has `defaultAgent` pointing to an agent id as a string, e.g., `"defaultAgent": "my-agent"` or `"defaultAgent": "default"`. Let's verify this.)
22
+ - Actually, `message.test.ts` shows `defaultAgent: 'my-agent'`.
23
+
24
+ ## Proposed Agents Feature
25
+ - We need a `clawmini agents` command group with `add`, `delete`, `list`.
26
+ - Agents will be stored at `.clawmini/agents/<id>/settings.json`.
27
+ - The configuration structure for an agent in `.clawmini/agents/<id>/settings.json` will mirror the `defaultAgent` config, plus a new `directory` key:
28
+ ```json
29
+ {
30
+ "commands": { ... },
31
+ "env": { ... },
32
+ "directory": "./<agent_name>"
33
+ }
34
+ ```
35
+ - Agent settings will act as overrides/extensions over the main `settings.json`'s `defaultAgent`.
36
+ - `directory` will be used as the `cwd` when executing the agent's commands. It's either absolute or relative to the workspace root (parent of `.clawmini`).
37
+ - The `clawmini messages send` command should get an `--agent <id>` flag to set the agent for a chat.
38
+ - UI changes: The web UI should let users select the default agent when creating a chat. The web UI needs to create new agents as well.
39
+
40
+ ## Findings from Code
41
+ - `src/shared/config.ts` will need to be updated to support an `Agent` schema.
42
+ - `src/daemon/message.ts` (the daemon message handler) will need to be updated to merge the selected agent's config with the workspace's `defaultAgent` config and use the agent's `directory` as `cwd`.
43
+ - The `src/cli/commands/messages.ts` will need an `--agent` flag that updates the chat's settings to use the specified agent, via `writeChatSettings` in `src/shared/workspace.ts`.
44
+ - The UI is built with SvelteKit. We'll need a new route/dialog to create agents, and a way to choose an agent when creating a chat.
45
+ - UI API endpoints: we'll probably need `/api/agents` to list and create agents, and `/api/agents/:id` to manage them.