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,147 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { Client, Events, GatewayIntentBits, Partials } from 'discord.js';
4
+ import { readDiscordConfig, isAuthorized, initDiscordConfig } from './config.js';
5
+ import { getTRPCClient } from './client.js';
6
+ import { startDaemonToDiscordForwarder } from './forwarder.js';
7
+ import fs from 'node:fs/promises';
8
+ import path from 'node:path';
9
+
10
+ export async function main() {
11
+ const args = process.argv.slice(2);
12
+
13
+ if (args[0] === 'init') {
14
+ await initDiscordConfig();
15
+ return;
16
+ }
17
+
18
+ console.log('Discord Adapter starting...');
19
+
20
+ const config = await readDiscordConfig();
21
+ if (!config) {
22
+ console.error(
23
+ 'Failed to load Discord configuration. Please ensure .clawmini/adapters/discord/config.json exists and is valid.'
24
+ );
25
+ process.exit(1);
26
+ }
27
+
28
+ const trpc = getTRPCClient();
29
+
30
+ const client = new Client({
31
+ intents: [GatewayIntentBits.DirectMessages, GatewayIntentBits.MessageContent],
32
+ partials: [Partials.Channel],
33
+ });
34
+
35
+ client.once(Events.ClientReady, (readyClient) => {
36
+ console.log(`Ready! Logged in as ${readyClient.user.tag}`);
37
+
38
+ // Start forwarding from daemon to Discord
39
+ startDaemonToDiscordForwarder(readyClient, trpc, config.authorizedUserId, config.chatId).catch(
40
+ (error) => {
41
+ console.error('Error in daemon-to-discord forwarder:', error);
42
+ }
43
+ );
44
+ });
45
+
46
+ client.on(Events.MessageCreate, async (message) => {
47
+ // Ignore messages from the bot itself
48
+ if (message.author.id === client.user?.id) return;
49
+
50
+ // Only handle DM messages
51
+ if (message.guild) return;
52
+
53
+ // Check if the user is authorized
54
+ if (!isAuthorized(message.author.id, config.authorizedUserId)) {
55
+ console.log(
56
+ `Unauthorized message from ${message.author.tag} (${message.author.id}) ignored.`
57
+ );
58
+ return;
59
+ }
60
+
61
+ console.log(`Received message from ${message.author.tag}: ${message.content}`);
62
+
63
+ const downloadedFiles: string[] = [];
64
+ if (message.attachments.size > 0) {
65
+ const { getClawminiDir } = await import('../shared/workspace.js');
66
+ const tmpDir = path.join(getClawminiDir(process.cwd()), 'tmp', 'discord');
67
+ await fs.mkdir(tmpDir, { recursive: true });
68
+ const maxSizeMB = config.maxAttachmentSizeMB ?? 25;
69
+ const maxSizeBytes = maxSizeMB * 1024 * 1024;
70
+
71
+ for (const attachment of message.attachments.values()) {
72
+ if (attachment.size > maxSizeBytes) {
73
+ console.warn(
74
+ `Attachment ${attachment.name} exceeds size limit (${maxSizeMB}MB). Ignoring.`
75
+ );
76
+ await message.reply(
77
+ `Warning: Attachment ${attachment.name} exceeds the size limit of ${maxSizeMB}MB and was ignored.`
78
+ );
79
+ continue;
80
+ }
81
+
82
+ try {
83
+ const res = await fetch(attachment.url);
84
+ if (!res.ok) {
85
+ console.error(`Failed to download attachment ${attachment.name}`);
86
+ continue;
87
+ }
88
+
89
+ const uniqueName = `${Date.now()}-${attachment.name}`;
90
+ const filePath = path.join(tmpDir, uniqueName);
91
+ const arrayBuffer = await res.arrayBuffer();
92
+ await fs.writeFile(filePath, Buffer.from(arrayBuffer));
93
+ downloadedFiles.push(filePath);
94
+ } catch (err) {
95
+ console.error(`Error downloading attachment ${attachment.name}:`, err);
96
+ }
97
+ }
98
+ }
99
+
100
+ let finalContent = message.content;
101
+
102
+ if (message.reference && message.reference.messageId) {
103
+ try {
104
+ const referencedMessage = await message.fetchReference();
105
+ if (referencedMessage && referencedMessage.content) {
106
+ const quotedContent = referencedMessage.content
107
+ .split('\n')
108
+ .map((line) => `> ${line}`)
109
+ .join('\n');
110
+ finalContent = `${quotedContent}\n${finalContent}`;
111
+ }
112
+ } catch (err) {
113
+ console.error('Failed to fetch referenced message:', err);
114
+ }
115
+ }
116
+
117
+ console.log(`Forwarding message to daemon: ${finalContent}`);
118
+ try {
119
+ await trpc.sendMessage.mutate({
120
+ type: 'send-message',
121
+ client: 'cli',
122
+ data: {
123
+ message: finalContent,
124
+ chatId: config.chatId,
125
+ files: downloadedFiles.length > 0 ? downloadedFiles : undefined,
126
+ adapter: 'discord',
127
+ noWait: true,
128
+ },
129
+ });
130
+ console.log('Message forwarded to daemon successfully.');
131
+ } catch (error) {
132
+ console.error('Failed to forward message to daemon:', error);
133
+ }
134
+ });
135
+
136
+ try {
137
+ await client.login(config.botToken);
138
+ } catch (error) {
139
+ console.error('Failed to login to Discord:', error);
140
+ process.exit(1);
141
+ }
142
+ }
143
+
144
+ main().catch((error) => {
145
+ console.error('Unhandled error in Discord Adapter:', error);
146
+ process.exit(1);
147
+ });
@@ -0,0 +1,65 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import fsPromises from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { readDiscordState, writeDiscordState, getDiscordStatePath } from './state.js';
5
+
6
+ vi.mock('node:fs/promises');
7
+ vi.mock('../shared/workspace.js', () => ({
8
+ getClawminiDir: vi.fn(() => '/mock/clawmini'),
9
+ getWorkspaceRoot: vi.fn(() => '/mock/workspace'),
10
+ }));
11
+
12
+ describe('Discord State Management', () => {
13
+ beforeEach(() => {
14
+ vi.clearAllMocks();
15
+ });
16
+
17
+ it('should return default state if file does not exist', async () => {
18
+ vi.mocked(fsPromises.readFile).mockRejectedValue(new Error('File not found'));
19
+
20
+ const state = await readDiscordState();
21
+ expect(state).toEqual({ lastSyncedMessageId: undefined });
22
+ });
23
+
24
+ it('should read state from file', async () => {
25
+ const mockState = { lastSyncedMessageId: '12345' };
26
+ vi.mocked(fsPromises.readFile).mockResolvedValue(JSON.stringify(mockState));
27
+
28
+ const state = await readDiscordState();
29
+ expect(state).toEqual(mockState);
30
+ });
31
+
32
+ it('should return default state if file contains invalid JSON', async () => {
33
+ vi.mocked(fsPromises.readFile).mockResolvedValue('invalid-json');
34
+
35
+ const state = await readDiscordState();
36
+ expect(state).toEqual({ lastSyncedMessageId: undefined });
37
+ });
38
+
39
+ it('should write state to file', async () => {
40
+ const mockState = { lastSyncedMessageId: '67890' };
41
+ const statePath = getDiscordStatePath();
42
+
43
+ await writeDiscordState(mockState);
44
+
45
+ expect(fsPromises.mkdir).toHaveBeenCalledWith(path.dirname(statePath), { recursive: true });
46
+ expect(fsPromises.writeFile).toHaveBeenCalledWith(
47
+ statePath,
48
+ JSON.stringify(mockState, null, 2),
49
+ 'utf-8'
50
+ );
51
+ });
52
+
53
+ it('should handle errors when writing state', async () => {
54
+ vi.mocked(fsPromises.writeFile).mockRejectedValue(new Error('Permission denied'));
55
+ const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
56
+
57
+ await writeDiscordState({ lastSyncedMessageId: '123' });
58
+
59
+ expect(consoleSpy).toHaveBeenCalledWith(
60
+ expect.stringContaining('Failed to write Discord state'),
61
+ expect.any(Error)
62
+ );
63
+ consoleSpy.mockRestore();
64
+ });
65
+ });
@@ -0,0 +1,44 @@
1
+ import fsPromises from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { z } from 'zod';
4
+ import { getClawminiDir } from '../shared/workspace.js';
5
+
6
+ export const DiscordStateSchema = z.object({
7
+ lastSyncedMessageId: z.string().optional(),
8
+ });
9
+
10
+ export type DiscordState = z.infer<typeof DiscordStateSchema>;
11
+
12
+ export function getDiscordStatePath(startDir = process.cwd()): string {
13
+ return path.join(getClawminiDir(startDir), 'adapters', 'discord', 'state.json');
14
+ }
15
+
16
+ export async function readDiscordState(startDir = process.cwd()): Promise<DiscordState> {
17
+ const statePath = getDiscordStatePath(startDir);
18
+ try {
19
+ const data = await fsPromises.readFile(statePath, 'utf-8');
20
+ const parsed = JSON.parse(data);
21
+ const result = DiscordStateSchema.safeParse(parsed);
22
+ if (!result.success) {
23
+ return { lastSyncedMessageId: undefined };
24
+ }
25
+ return result.data;
26
+ } catch {
27
+ // Return default state if file doesn't exist or is invalid JSON
28
+ return { lastSyncedMessageId: undefined };
29
+ }
30
+ }
31
+
32
+ export async function writeDiscordState(
33
+ state: DiscordState,
34
+ startDir = process.cwd()
35
+ ): Promise<void> {
36
+ const statePath = getDiscordStatePath(startDir);
37
+ const dir = path.dirname(statePath);
38
+ try {
39
+ await fsPromises.mkdir(dir, { recursive: true });
40
+ await fsPromises.writeFile(statePath, JSON.stringify(state, null, 2), 'utf-8');
41
+ } catch (err) {
42
+ console.error(`Failed to write Discord state to ${statePath}:`, err);
43
+ }
44
+ }
@@ -0,0 +1,46 @@
1
+ import { createTRPCClient, httpLink } from '@trpc/client';
2
+ import type { AppRouter } from '../daemon/router.js';
3
+ import { getSocketPath, getClawminiDir } from '../shared/workspace.js';
4
+ import { createUnixSocketFetch } from '../shared/fetch.js';
5
+ import { spawn } from 'node:child_process';
6
+ import fs from 'node:fs';
7
+ import path from 'node:path';
8
+
9
+ export async function getDaemonClient(options: { autoStart?: boolean } = {}) {
10
+ const { autoStart = true } = options;
11
+ const socketPath = getSocketPath();
12
+
13
+ // Check if server is running by verifying socket exists
14
+ // (A better check would be to ping it, but this is a start)
15
+ if (!fs.existsSync(socketPath)) {
16
+ if (!autoStart) {
17
+ throw new Error('Daemon not running.');
18
+ }
19
+ console.log('Daemon not running. Starting daemon...');
20
+
21
+ // Start daemon in the background
22
+ const daemonPath = new URL('../daemon/index.mjs', import.meta.url).pathname;
23
+ const logFile = fs.openSync(path.join(getClawminiDir(), 'daemon.log'), 'a');
24
+ const child = spawn(process.execPath, [daemonPath], {
25
+ detached: true,
26
+ stdio: ['ignore', logFile, logFile],
27
+ });
28
+ child.unref();
29
+
30
+ // Wait a moment for the daemon to start and create the socket
31
+ await new Promise((resolve) => setTimeout(resolve, 500));
32
+
33
+ if (!fs.existsSync(socketPath)) {
34
+ throw new Error('Failed to start daemon.');
35
+ }
36
+ }
37
+
38
+ return createTRPCClient<AppRouter>({
39
+ links: [
40
+ httpLink({
41
+ url: 'http://localhost',
42
+ fetch: createUnixSocketFetch(socketPath),
43
+ }),
44
+ ],
45
+ });
46
+ }
@@ -0,0 +1,138 @@
1
+ import { Command } from 'commander';
2
+ import {
3
+ listAgents,
4
+ getAgent,
5
+ writeAgentSettings,
6
+ deleteAgent,
7
+ isValidAgentId,
8
+ } from '../../shared/workspace.js';
9
+ import { type Agent } from '../../shared/config.js';
10
+ import { createAgentWithChat } from '../../shared/agent-utils.js';
11
+ import { handleError } from '../utils.js';
12
+
13
+ export const agentsCmd = new Command('agents').description('Manage agents');
14
+
15
+ function parseEnv(envArray: string[] | undefined): Record<string, string> | undefined {
16
+ if (!envArray || envArray.length === 0) return undefined;
17
+ const env: Record<string, string> = {};
18
+ for (const e of envArray) {
19
+ const [key, ...rest] = e.split('=');
20
+ if (key && rest.length >= 0) {
21
+ env[key] = rest.join('=');
22
+ }
23
+ }
24
+ return env;
25
+ }
26
+
27
+ function assertValidAgentId(id: string): void {
28
+ if (!isValidAgentId(id)) {
29
+ throw new Error(`Invalid agent ID: ${id}`);
30
+ }
31
+ }
32
+
33
+ agentsCmd
34
+ .command('list')
35
+ .description('Display existing agents')
36
+ .action(async () => {
37
+ try {
38
+ const agents = await listAgents();
39
+ if (agents.length === 0) {
40
+ console.log('No agents found.');
41
+ return;
42
+ }
43
+ for (const id of agents) {
44
+ console.log(`- ${id}`);
45
+ }
46
+ } catch (err) {
47
+ handleError('list agents', err);
48
+ }
49
+ });
50
+
51
+ agentsCmd
52
+ .command('add <id>')
53
+ .description('Create a new agent')
54
+ .option('-d, --directory <dir>', 'Working directory for the agent')
55
+ .option('-t, --template <name>', 'Template to use for the agent')
56
+ .option(
57
+ '-e, --env <env...>',
58
+ 'Environment variables in KEY=VALUE format (can be specified multiple times)'
59
+ )
60
+ .action(
61
+ async (id: string, options: { directory?: string; template?: string; env?: string[] }) => {
62
+ try {
63
+ assertValidAgentId(id);
64
+ const existing = await getAgent(id);
65
+ if (existing) {
66
+ throw new Error(`Agent ${id} already exists.`);
67
+ }
68
+
69
+ const agentData: Agent = {};
70
+
71
+ if (options.directory) {
72
+ agentData.directory = options.directory;
73
+ }
74
+ const env = parseEnv(options.env);
75
+ if (env) {
76
+ agentData.env = { ...(agentData.env || {}), ...env };
77
+ }
78
+
79
+ await createAgentWithChat(id, agentData, options.template);
80
+
81
+ console.log(`Agent ${id} created successfully.`);
82
+ } catch (err) {
83
+ handleError('create agent', err);
84
+ }
85
+ }
86
+ );
87
+
88
+ agentsCmd
89
+ .command('update <id>')
90
+ .description('Update an existing agent')
91
+ .option('-d, --directory <dir>', 'Working directory for the agent')
92
+ .option(
93
+ '-e, --env <env...>',
94
+ 'Environment variables in KEY=VALUE format (can be specified multiple times)'
95
+ )
96
+ .action(async (id: string, options: { directory?: string; env?: string[] }) => {
97
+ try {
98
+ assertValidAgentId(id);
99
+ const existing = await getAgent(id);
100
+ if (!existing) {
101
+ throw new Error(`Agent ${id} does not exist.`);
102
+ }
103
+
104
+ const agentData: Agent = { ...existing };
105
+
106
+ if (options.directory !== undefined) {
107
+ agentData.directory = options.directory;
108
+ }
109
+
110
+ const env = parseEnv(options.env);
111
+ if (env) {
112
+ agentData.env = { ...(agentData.env || {}), ...env };
113
+ }
114
+
115
+ await writeAgentSettings(id, agentData);
116
+ console.log(`Agent ${id} updated successfully.`);
117
+ } catch (err) {
118
+ handleError('update agent', err);
119
+ }
120
+ });
121
+
122
+ agentsCmd
123
+ .command('delete <id>')
124
+ .description('Remove an agent')
125
+ .action(async (id: string) => {
126
+ try {
127
+ assertValidAgentId(id);
128
+ const existing = await getAgent(id);
129
+ if (!existing) {
130
+ throw new Error(`Agent ${id} does not exist.`);
131
+ }
132
+
133
+ await deleteAgent(id);
134
+ console.log(`Agent ${id} deleted successfully.`);
135
+ } catch (err) {
136
+ handleError('delete agent', err);
137
+ }
138
+ });
@@ -0,0 +1,79 @@
1
+ import { Command } from 'commander';
2
+ import {
3
+ listChats,
4
+ createChat,
5
+ deleteChat,
6
+ setDefaultChatId,
7
+ getDefaultChatId,
8
+ DEFAULT_CHAT_ID,
9
+ } from '../../shared/chats.js';
10
+
11
+ export const chatsCmd = new Command('chats').description('Manage chat sessions');
12
+
13
+ chatsCmd
14
+ .command('list')
15
+ .description('Display existing chats')
16
+ .action(async () => {
17
+ try {
18
+ const chats = await listChats();
19
+ const defaultId = await getDefaultChatId();
20
+ if (chats.length === 0) {
21
+ console.log('No chats found.');
22
+ return;
23
+ }
24
+ for (const id of chats) {
25
+ const marker = id === defaultId ? ' *' : '';
26
+ console.log(`- ${id}${marker}`);
27
+ }
28
+ } catch (err) {
29
+ console.error('Failed to list chats:', err instanceof Error ? err.message : String(err));
30
+ process.exit(1);
31
+ }
32
+ });
33
+
34
+ chatsCmd
35
+ .command('add <id>')
36
+ .description('Initialize a new chat')
37
+ .action(async (id: string) => {
38
+ try {
39
+ await createChat(id);
40
+ console.log(`Chat ${id} created successfully.`);
41
+ } catch (err) {
42
+ console.error('Failed to create chat:', err instanceof Error ? err.message : String(err));
43
+ process.exit(1);
44
+ }
45
+ });
46
+
47
+ chatsCmd
48
+ .command('delete <id>')
49
+ .description('Remove a chat')
50
+ .action(async (id: string) => {
51
+ try {
52
+ const defaultId = await getDefaultChatId();
53
+ await deleteChat(id);
54
+ console.log(`Chat ${id} deleted successfully.`);
55
+ if (id === defaultId) {
56
+ await setDefaultChatId(DEFAULT_CHAT_ID);
57
+ console.log(`Default chat reset to default.`);
58
+ }
59
+ } catch (err) {
60
+ console.error('Failed to delete chat:', err instanceof Error ? err.message : String(err));
61
+ process.exit(1);
62
+ }
63
+ });
64
+
65
+ chatsCmd
66
+ .command('set-default <id>')
67
+ .description('Update the workspace default chat')
68
+ .action(async (id: string) => {
69
+ try {
70
+ await setDefaultChatId(id);
71
+ console.log(`Default chat set to ${id}.`);
72
+ } catch (err) {
73
+ console.error(
74
+ 'Failed to set default chat:',
75
+ err instanceof Error ? err.message : String(err)
76
+ );
77
+ process.exit(1);
78
+ }
79
+ });
@@ -0,0 +1,32 @@
1
+ import { Command } from 'commander';
2
+ import { getDaemonClient } from '../client.js';
3
+ import { getSocketPath } from '../../shared/workspace.js';
4
+ import fs from 'node:fs';
5
+
6
+ export const downCmd = new Command('down')
7
+ .description('Stop the local clawmini daemon server')
8
+ .action(async () => {
9
+ try {
10
+ const client = await getDaemonClient({ autoStart: false });
11
+ process.stdout.write('Shutting down clawmini daemon...');
12
+ await client.shutdown.mutate();
13
+
14
+ const socketPath = getSocketPath();
15
+ // Wait for the socket file to be removed by the daemon's exit handler
16
+ while (fs.existsSync(socketPath)) {
17
+ await new Promise((resolve) => setTimeout(resolve, 200));
18
+ process.stdout.write('.');
19
+ }
20
+ console.log('\nSuccessfully shut down clawmini daemon.');
21
+ } catch (err: unknown) {
22
+ if (err instanceof Error && err.message === 'Daemon not running.') {
23
+ console.log('Daemon is not running.');
24
+ } else {
25
+ console.error(
26
+ '\nFailed to shut down daemon:',
27
+ err instanceof Error ? err.message : String(err)
28
+ );
29
+ process.exit(1);
30
+ }
31
+ }
32
+ });
@@ -0,0 +1,39 @@
1
+ import { Command } from 'commander';
2
+ import { readSettings, writeSettings, enableEnvironment } from '../../shared/workspace.js';
3
+ import { handleError } from '../utils.js';
4
+
5
+ export const environmentsCmd = new Command('environments').description('Manage environments');
6
+
7
+ environmentsCmd
8
+ .command('enable <name>')
9
+ .description('Enable an environment for a path in the workspace')
10
+ .option('-p, --path <subpath>', 'Path to apply the environment to', './')
11
+ .action(async (name: string, options: { path: string }) => {
12
+ try {
13
+ await enableEnvironment(name, options.path);
14
+ } catch (err) {
15
+ handleError('enable environment', err);
16
+ }
17
+ });
18
+
19
+ environmentsCmd
20
+ .command('disable')
21
+ .description('Disable an environment mapping')
22
+ .option('-p, --path <subpath>', 'Path to remove the environment from', './')
23
+ .action(async (options: { path: string }) => {
24
+ try {
25
+ const settings = await readSettings();
26
+ if (!settings?.environments || !settings.environments[options.path]) {
27
+ console.log(`No environment mapping found for path '${options.path}'.`);
28
+ return;
29
+ }
30
+
31
+ const name = settings.environments[options.path];
32
+ delete settings.environments[options.path];
33
+ await writeSettings(settings);
34
+
35
+ console.log(`Disabled environment '${name}' for path '${options.path}'.`);
36
+ } catch (err) {
37
+ handleError('disable environment', err);
38
+ }
39
+ });
@@ -0,0 +1,62 @@
1
+ import { Command } from 'commander';
2
+ import path from 'node:path';
3
+ import {
4
+ getLiteScriptContent,
5
+ writeLiteScript,
6
+ exportLiteToAllEnvironments,
7
+ } from '../../shared/lite.js';
8
+
9
+ export const exportLiteCmd = new Command('export-lite')
10
+ .description('Export the standalone clawmini-lite client script')
11
+ .option(
12
+ '-o, --out <path>',
13
+ 'Output path or directory for the script (defaults to current directory)'
14
+ )
15
+ .option('--stdout', 'Output the script to stdout instead of a file')
16
+ .action(async (options: { out?: string; stdout?: boolean }) => {
17
+ let liteScriptContent = '';
18
+ try {
19
+ liteScriptContent = await getLiteScriptContent();
20
+ } catch (err) {
21
+ console.error(
22
+ `Failed to read compiled clawmini-lite script. Ensure you have built the project (npm run build). Error: ${err instanceof Error ? err.message : String(err)}`
23
+ );
24
+ process.exit(1);
25
+ }
26
+
27
+ if (options.stdout) {
28
+ process.stdout.write(liteScriptContent);
29
+ return;
30
+ }
31
+
32
+ const defaultFilename = 'clawmini-lite.js';
33
+ let finalPath = path.resolve(process.cwd(), defaultFilename);
34
+
35
+ if (options.out) {
36
+ finalPath = path.resolve(process.cwd(), options.out);
37
+ try {
38
+ const writtenPath = await writeLiteScript(finalPath);
39
+ console.log(`Successfully exported clawmini-lite to ${writtenPath}`);
40
+ } catch (err) {
41
+ console.error(
42
+ `Failed to export script: ${err instanceof Error ? err.message : String(err)}`
43
+ );
44
+ process.exit(1);
45
+ }
46
+ return;
47
+ }
48
+
49
+ const exportedToEnvironments = await exportLiteToAllEnvironments(process.cwd());
50
+
51
+ if (!exportedToEnvironments) {
52
+ try {
53
+ const writtenPath = await writeLiteScript(finalPath);
54
+ console.log(`Successfully exported clawmini-lite to ${writtenPath}`);
55
+ } catch (err) {
56
+ console.error(
57
+ `Failed to export script: ${err instanceof Error ? err.message : String(err)}`
58
+ );
59
+ process.exit(1);
60
+ }
61
+ }
62
+ });