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,46 @@
1
+ {
2
+ "tools": {
3
+ "allowed": [
4
+ "write_file",
5
+ "replace",
6
+ "activate_skill",
7
+ "run_shell_command(cat)",
8
+ "run_shell_command(grep)",
9
+ "run_shell_command(find)",
10
+ "run_shell_command(tail)",
11
+ "run_shell_command(head)",
12
+ "run_shell_command(wc)",
13
+ "run_shell_command(sort)",
14
+ "run_shell_command(echo)",
15
+ "run_shell_command(ls)",
16
+ "run_shell_command(pwd)",
17
+ "run_shell_command(cd)",
18
+ "run_shell_command(git diff)",
19
+ "run_shell_command(git status)",
20
+ "run_shell_command(git log)",
21
+ "run_shell_command(git show)",
22
+ "run_shell_command(git add)",
23
+ "run_shell_command(git commit)",
24
+ "run_shell_command(sed)",
25
+ "run_shell_command(awk)",
26
+ "run_shell_command(cp)",
27
+ "run_shell_command(mv)",
28
+ "run_shell_command(chmod)",
29
+ "run_shell_command(chown)",
30
+ "run_shell_command(touch)",
31
+ "run_shell_command(rm)",
32
+ "run_shell_command(mkdir)",
33
+ "run_shell_command(rmdir)",
34
+ "run_shell_command(npm)",
35
+ "run_shell_command(>)",
36
+ "run_shell_command(<<)",
37
+ "run_shell_command(heredoc)",
38
+ "run_shell_command(redirection)"
39
+ ],
40
+ "exclude": [
41
+ "ask_user",
42
+ "save_memory",
43
+ "write_todos"
44
+ ]
45
+ }
46
+ }
package/.prettierrc ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "semi": true,
3
+ "trailingComma": "es5",
4
+ "singleQuote": true,
5
+ "printWidth": 100,
6
+ "tabWidth": 2
7
+ }
package/GEMINI.md ADDED
@@ -0,0 +1,11 @@
1
+ When editing or creating files, ALWAYS use the write_tool/replace tools over run_shell_command with `cat` or `echo`.
2
+
3
+ # Take notes in napkin.md
4
+
5
+ ./napkin.md contains notes for development.
6
+ At the start of any session, read napkin.md.
7
+ As you work, take notes in napkin.md including:
8
+
9
+ - corrections the user has given you that future developers may care about
10
+ - mistakes you made when running a command, with the corrections
11
+ - challenges you had to resolve, with the final solution
package/README.md ADDED
@@ -0,0 +1,137 @@
1
+ # Clawmini
2
+
3
+ Clawmini is an orchestration layer for command-line AI agents, providing a unified chat experience that can span multiple conversations and multiple agents. Ultimately, it aims to deliver a personal assistant experience built entirely on top of your local tools and agents.
4
+
5
+ ## Features
6
+
7
+ - **Persistent, Multi-Agent Chat Sessions:** Maintain separate chats for different tasks, allowing you to converse with multiple agents across multiple conversations.
8
+ - **Safe Concurrency:** Automatically manages state and handles race conditions, queuing background commands safely to prevent file lock issues.
9
+ - **Built-in & Bring-Your-Own UI:** Includes a fast, beautifully designed SvelteKit Web UI to visually manage agents, chats, and monitor real-time execution. Alternatively, easily build and connect your own interfaces to its local API.
10
+ - **Agent Templates:** Quickly scaffold new agents using built-in or custom templates (e.g. `gemini`), automatically merging configuration settings.
11
+ - **Routers & Middleware Pipeline:** Process user messages through an extensible pipeline to dynamically alter content, target specific agents or sessions, and expand slash commands before they reach an agent.
12
+ - **Local File System Storage:** Everything is stored completely locally in `.clawmini/` within your workspace as transparent JSON/JSONL files. No cloud syncing required.
13
+ - **Sandboxed Agent API:** The daemon can optionally expose a secure HTTP server configured via the `api` setting in `.clawmini/settings.json`, allowing remote or containerized access. Give agents a minimal zero-dependency standalone client exported via `clawmini export-lite`. It securely authenticates with the Agent API using dynamically generated HMAC tokens (`CLAW_API_TOKEN`) to allow sandboxed agents to log messages and manage cron jobs without needing direct access to the host's Unix socket.
14
+ - **Proactivity:** Incoming messages or events from various external sources can be proactively routed back to the user or directly to the agent for autonomous handling.
15
+
16
+ ### Coming Soon
17
+
18
+ - **Human Approval Requests:** When an agent needs permission to execute a sensitive action or requires input, it will pause and ask the user for approval via a dedicated UI or dashboard.
19
+
20
+ ## Quick Start
21
+
22
+ Assuming you have built and linked the package globally:
23
+
24
+ ```bash
25
+ # Initialize a new .clawmini settings folder, create an agent named 'coder' with the 'gemini-cladding' template, and set it as the default chat
26
+ clawmini init --agent coder --agent-template gemini-cladding
27
+
28
+ # Start the local web interface on http://localhost:8080
29
+ clawmini web
30
+ ```
31
+
32
+ ## Command Reference
33
+
34
+ ### Initialization & Daemon
35
+
36
+ - `clawmini init`: Initialize a new `.clawmini` configuration folder.
37
+ - `clawmini up`: Start the local daemon server in the background.
38
+ - `clawmini down`: Stop the local daemon server.
39
+ - `clawmini export-lite [--out <path>] [--stdout]`: Export the standalone `clawmini-lite` client script for use in sandboxed environments.
40
+
41
+ ### Chat Management
42
+
43
+ - `clawmini chats list`: Display all existing chats in the workspace.
44
+ - `clawmini chats add <id>`: Create a new chat with the specified identifier.
45
+ - `clawmini chats delete <id>`: Remove a chat and its associated history.
46
+ - `clawmini chats set-default <id>`: Update the globally configured default chat for the workspace.
47
+
48
+ ### Messaging
49
+
50
+ - `clawmini messages send <message> [--chat <id>] [--agent <name>]`: Send a message to a specific chat (defaults to the workspace default chat). Use `--agent` to assign a specific agent to handle the message.
51
+ - `clawmini messages tail [-n NUM] [--json] [--chat <id>]`: Display the most recent messages and command logs in a chat.
52
+
53
+ ### Agents
54
+
55
+ - `clawmini agents list`: Display all existing agents.
56
+ - `clawmini agents add <id> [-d, --directory <dir>] [-t, --template <name>] [-e, --env <KEY=VALUE>...]`: Create a new agent, optionally setting its working directory, applying a template, and environment variables.
57
+ - `clawmini agents update <id> [-d, --directory <dir>] [-e, --env <KEY=VALUE>...]`: Update an existing agent's configuration.
58
+ - `clawmini agents delete <id>`: Remove an agent.
59
+
60
+ ### Cron Jobs
61
+
62
+ - `clawmini cron list [--chat <id>]`: Display all cron jobs configured for a chat.
63
+ - `clawmini cron add <name> [--cron <expr> | --every <duration> | --at <iso-time>] [-m, --message <text>]`: Create a new scheduled job. Supports standard cron expressions, recurring intervals (e.g., `10m`), or one-off executions at a specific time.
64
+ - `clawmini cron delete <name> [--chat <id>]`: Remove an existing scheduled job.
65
+
66
+ ### Web Interface
67
+
68
+ - `clawmini web [-p, --port <number>]`: Start the local web interface (default port: 8080).
69
+
70
+ ## Configuration
71
+
72
+ ## Global settings
73
+
74
+ **TODO**
75
+
76
+ ## Routers
77
+
78
+ Clawmini provides an extensible pipeline for processing user messages before they reach an agent using **Routers**. By defining a sequence of routers in your `.clawmini/settings.json` (global) or per-chat settings, you can dynamically alter message content, target specific agents or sessions, inject environment variables, and add automated replies.
79
+
80
+ Built-in routers include:
81
+
82
+ - `@clawmini/slash-new`: Creates a new session ID when a message starts with `/new`, effectively clearing the context window for the agent.
83
+ - `@clawmini/slash-command`: Expands slash commands (e.g., `/foo`) with the contents of matching files in your `.clawmini/commands/` directory.
84
+
85
+ You can also write custom shell script routers that accept the current state via `stdin` and output JSON to dynamically control the routing logic. See the [`RouterState` interface](src/daemon/routers/types.ts) for the exact input and output schema.
86
+
87
+ ## Agent Templates
88
+
89
+ Clawmini provides built-in templates to help you quickly scaffold new agents with pre-configured settings and files. When you run `clawmini agents add <id> --template <name>`, it copies the template's files into the agent's working directory and merges any provided environment variables or directory options with the template's `settings.json`.
90
+
91
+ The currently available built-in templates are:
92
+
93
+ - `gemini`: A basic template configured to use the `gemini` CLI as the agent's backend.
94
+ - `gemini-cladding`: A template configured to run the `gemini` CLI wrapped inside `cladding` for enhanced security.
95
+ - `gemini-claw-cladding`: A comprehensive template that sets up an autonomous personal assistant workspace (OpenClaw). It includes the `gemini-cladding` setup plus a full suite of scaffolding files like `GEMINI.md`, `SOUL.md`, `MEMORY.md`, and `HEARTBEAT.md` to establish the agent's identity, memory, and proactive capabilities.
96
+
97
+ ## Development Setup
98
+
99
+ Clawmini is a monorepo consisting of a Node.js TypeScript CLI/Daemon and an embedded SvelteKit frontend (in the `web/` workspace).
100
+
101
+ ### Prerequisites
102
+
103
+ - Node.js (v18+)
104
+ - npm
105
+
106
+ ### Setup
107
+
108
+ ```bash
109
+ # Install dependencies for both the root CLI and the web workspace
110
+ npm install
111
+
112
+ # Build the CLI, Daemon, and statically compile the Web UI
113
+ npm run build
114
+ ```
115
+
116
+ ### Development Scripts
117
+
118
+ During development, you can run the following commands from the root:
119
+
120
+ ```bash
121
+ # Watch mode for the CLI
122
+ npm run dev:cli
123
+
124
+ # Watch mode for the Daemon
125
+ npm run dev:daemon
126
+
127
+ # Run formatting, linting, type-checking, and tests
128
+ npm run format
129
+ npm run lint
130
+ npm run check
131
+ npm run test
132
+ ```
133
+
134
+ ## Architecture Notes
135
+
136
+ - **Separation of Concerns:** The daemon (`src/daemon`) acts as the stateful orchestrator and queue manager, while the CLI (`src/cli`) is simply a thin TRPC client connecting via a UNIX socket.
137
+ - **Web UI:** The `web/` directory is a SvelteKit application built with `@sveltejs/adapter-static`. Running `npm run build` bundles the web UI into `dist/web`, which is then served statically by the `clawmini web` Node.js server. Real-time updates to the web UI are powered by Server-Sent Events (SSE) tailing the local `.clawmini/chats/:id/chat.jsonl` files.
@@ -0,0 +1,5 @@
1
+ //#region src/adapter-discord/index.d.ts
2
+ declare function main(): Promise<void>;
3
+ //#endregion
4
+ export { main };
5
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/adapter-discord/index.ts"],"mappings":";iBASsB,IAAA,CAAA,GAAI,OAAA"}
@@ -0,0 +1,456 @@
1
+ #!/usr/bin/env node
2
+ import { l as getSocketPath, o as getClawminiDir, u as getWorkspaceRoot } from "../workspace-CSgfo_2J.mjs";
3
+ import { t as createUnixSocketFetch } from "../fetch-BjZVyU3Z.mjs";
4
+ import fs from "node:fs";
5
+ import path from "node:path";
6
+ import fs$1 from "node:fs/promises";
7
+ import { z } from "zod";
8
+ import { createTRPCClient, httpLink, httpSubscriptionLink, splitLink } from "@trpc/client";
9
+ import http from "node:http";
10
+ import { Client, Events, GatewayIntentBits, Partials } from "discord.js";
11
+
12
+ //#region src/adapter-discord/config.ts
13
+ const DiscordConfigSchema = z.looseObject({
14
+ botToken: z.string().min(1, "Discord Bot Token is required."),
15
+ authorizedUserId: z.string().min(1, "Authorized Discord User ID is required."),
16
+ chatId: z.string().default("default"),
17
+ maxAttachmentSizeMB: z.number().default(25).optional()
18
+ });
19
+ function getDiscordConfigPath(startDir = process.cwd()) {
20
+ return path.join(getClawminiDir(startDir), "adapters", "discord", "config.json");
21
+ }
22
+ async function readDiscordConfig(startDir = process.cwd()) {
23
+ const configPath = getDiscordConfigPath(startDir);
24
+ try {
25
+ const data = await fs$1.readFile(configPath, "utf-8");
26
+ const parsed = JSON.parse(data);
27
+ const result = DiscordConfigSchema.safeParse(parsed);
28
+ if (!result.success) {
29
+ console.error("Invalid Discord configuration:", result.error.format());
30
+ return null;
31
+ }
32
+ return result.data;
33
+ } catch {
34
+ return null;
35
+ }
36
+ }
37
+ async function initDiscordConfig(startDir = process.cwd()) {
38
+ const configPath = getDiscordConfigPath(startDir);
39
+ const configDir = path.dirname(configPath);
40
+ await fs$1.mkdir(configDir, { recursive: true });
41
+ if (fs.existsSync(configPath)) {
42
+ console.log(`Config file already exists at ${configPath}`);
43
+ return;
44
+ }
45
+ await fs$1.writeFile(configPath, JSON.stringify({
46
+ botToken: "YOUR_DISCORD_BOT_TOKEN",
47
+ authorizedUserId: "YOUR_DISCORD_USER_ID",
48
+ chatId: "default"
49
+ }, null, 2), "utf-8");
50
+ console.log(`Created template configuration file at ${configPath}`);
51
+ console.log("Please update it with your actual Discord Bot Token and User ID.");
52
+ }
53
+ function isAuthorized(userId, authorizedUserId) {
54
+ return userId === authorizedUserId;
55
+ }
56
+
57
+ //#endregion
58
+ //#region src/shared/event-source.ts
59
+ function createUnixSocketEventSource(socketPath) {
60
+ return class UnixSocketEventSource {
61
+ readyState = 0;
62
+ CONNECTING = 0;
63
+ OPEN = 1;
64
+ CLOSED = 2;
65
+ req = null;
66
+ listeners = {};
67
+ constructor(url, init) {
68
+ const parsedUrl = new URL(url);
69
+ const options = {
70
+ socketPath,
71
+ path: parsedUrl.pathname + parsedUrl.search,
72
+ method: "GET",
73
+ headers: {
74
+ Accept: "text/event-stream",
75
+ "Cache-Control": "no-cache",
76
+ ...init?.headers
77
+ }
78
+ };
79
+ this.req = http.request(options, (res) => {
80
+ if (res.statusCode === 200) {
81
+ this.readyState = this.OPEN;
82
+ this.dispatchEvent({ type: "open" });
83
+ } else {
84
+ this.readyState = this.CLOSED;
85
+ this.dispatchEvent({
86
+ type: "error",
87
+ message: `Unexpected status code: ${res.statusCode}`
88
+ });
89
+ return;
90
+ }
91
+ let buffer = "";
92
+ res.on("data", (chunk) => {
93
+ buffer += chunk.toString("utf-8");
94
+ const lines = buffer.split(/\r?\n\r?\n/);
95
+ buffer = lines.pop() || "";
96
+ for (const block of lines) this.parseBlock(block);
97
+ });
98
+ res.on("end", () => {
99
+ if (buffer) this.parseBlock(buffer);
100
+ this.readyState = this.CLOSED;
101
+ this.dispatchEvent({ type: "close" });
102
+ });
103
+ });
104
+ this.req.on("error", (err) => {
105
+ this.readyState = this.CLOSED;
106
+ this.dispatchEvent({
107
+ type: "error",
108
+ error: err
109
+ });
110
+ });
111
+ this.req.end();
112
+ }
113
+ parseBlock(block) {
114
+ if (!block.trim()) return;
115
+ const lines = block.split(/\r?\n/);
116
+ let eventType = "message";
117
+ let data = "";
118
+ let id = "";
119
+ for (const line of lines) if (line.startsWith("event: ")) eventType = line.slice(7).trim();
120
+ else if (line.startsWith("data: ")) data += (data ? "\n" : "") + line.slice(6);
121
+ else if (line.startsWith("id: ")) id = line.slice(4).trim();
122
+ if (data) this.dispatchEvent({
123
+ type: eventType,
124
+ data,
125
+ lastEventId: id
126
+ });
127
+ }
128
+ addEventListener(type, listener) {
129
+ if (!this.listeners[type]) this.listeners[type] = [];
130
+ this.listeners[type].push(listener);
131
+ }
132
+ removeEventListener(type, listener) {
133
+ if (!this.listeners[type]) return;
134
+ this.listeners[type] = this.listeners[type].filter((l) => l !== listener);
135
+ }
136
+ dispatchEvent(event) {
137
+ const type = event.type;
138
+ if (this.listeners[type]) for (const listener of this.listeners[type]) listener(event);
139
+ }
140
+ close() {
141
+ this.readyState = this.CLOSED;
142
+ if (this.req) this.req.destroy();
143
+ }
144
+ };
145
+ }
146
+
147
+ //#endregion
148
+ //#region src/adapter-discord/client.ts
149
+ /**
150
+ * Creates a TRPC client that connects to the Clawmini daemon via a Unix socket.
151
+ *
152
+ * @param options - Configuration options for the client.
153
+ * @returns A TRPC client instance for the AppRouter.
154
+ */
155
+ function getTRPCClient(options = {}) {
156
+ const socketPath = options.socketPath ?? getSocketPath();
157
+ if (!fs.existsSync(socketPath)) throw new Error(`Daemon not running. Socket not found at ${socketPath}`);
158
+ const customFetch = createUnixSocketFetch(socketPath);
159
+ return createTRPCClient({ links: [splitLink({
160
+ condition(op) {
161
+ return op.type === "subscription";
162
+ },
163
+ true: httpSubscriptionLink({
164
+ url: "http://localhost",
165
+ EventSource: createUnixSocketEventSource(socketPath)
166
+ }),
167
+ false: httpLink({
168
+ url: "http://localhost",
169
+ fetch: customFetch
170
+ })
171
+ })] });
172
+ }
173
+
174
+ //#endregion
175
+ //#region src/adapter-discord/state.ts
176
+ const DiscordStateSchema = z.object({ lastSyncedMessageId: z.string().optional() });
177
+ function getDiscordStatePath(startDir = process.cwd()) {
178
+ return path.join(getClawminiDir(startDir), "adapters", "discord", "state.json");
179
+ }
180
+ async function readDiscordState(startDir = process.cwd()) {
181
+ const statePath = getDiscordStatePath(startDir);
182
+ try {
183
+ const data = await fs$1.readFile(statePath, "utf-8");
184
+ const parsed = JSON.parse(data);
185
+ const result = DiscordStateSchema.safeParse(parsed);
186
+ if (!result.success) return { lastSyncedMessageId: void 0 };
187
+ return result.data;
188
+ } catch {
189
+ return { lastSyncedMessageId: void 0 };
190
+ }
191
+ }
192
+ async function writeDiscordState(state, startDir = process.cwd()) {
193
+ const statePath = getDiscordStatePath(startDir);
194
+ const dir = path.dirname(statePath);
195
+ try {
196
+ await fs$1.mkdir(dir, { recursive: true });
197
+ await fs$1.writeFile(statePath, JSON.stringify(state, null, 2), "utf-8");
198
+ } catch (err) {
199
+ console.error(`Failed to write Discord state to ${statePath}:`, err);
200
+ }
201
+ }
202
+
203
+ //#endregion
204
+ //#region src/adapter-discord/forwarder.ts
205
+ async function startDaemonToDiscordForwarder(client, trpc, discordUserId, chatId = "default", signal) {
206
+ let lastMessageId = (await readDiscordState()).lastSyncedMessageId;
207
+ if (!lastMessageId) try {
208
+ const messages = await trpc.getMessages.query({
209
+ chatId,
210
+ limit: 1
211
+ });
212
+ if (Array.isArray(messages) && messages.length > 0) {
213
+ const lastMsg = messages[messages.length - 1];
214
+ if (lastMsg) {
215
+ lastMessageId = lastMsg.id;
216
+ await writeDiscordState({ lastSyncedMessageId: lastMessageId });
217
+ }
218
+ }
219
+ } catch (error) {
220
+ if (signal?.aborted) return;
221
+ console.error("Failed to fetch initial messages from daemon:", error);
222
+ }
223
+ console.log(`Starting daemon-to-discord forwarder for chat ${chatId}, lastMessageId: ${lastMessageId}`);
224
+ let retryDelay = 1e3;
225
+ const maxRetryDelay = 3e4;
226
+ return new Promise((resolve) => {
227
+ let subscription = null;
228
+ let messageQueue = Promise.resolve();
229
+ const connect = () => {
230
+ if (signal?.aborted) {
231
+ resolve();
232
+ return;
233
+ }
234
+ subscription = trpc.waitForMessages.subscribe({
235
+ chatId,
236
+ lastMessageId
237
+ }, {
238
+ onData: (messages) => {
239
+ retryDelay = 1e3;
240
+ if (!Array.isArray(messages) || messages.length === 0) return;
241
+ messageQueue = messageQueue.then(async () => {
242
+ for (const rawMessage of messages) {
243
+ if (signal?.aborted) break;
244
+ const message = rawMessage;
245
+ if (message.role === "log") {
246
+ const logMessage = message;
247
+ if (logMessage.level === "verbose") {
248
+ lastMessageId = logMessage.id;
249
+ await writeDiscordState({ lastSyncedMessageId: lastMessageId }).catch(console.error);
250
+ continue;
251
+ }
252
+ const hasContent = !!logMessage.content?.trim();
253
+ const hasFiles = Array.isArray(logMessage.files) && logMessage.files.length > 0;
254
+ let absoluteFiles = [];
255
+ if (hasFiles) {
256
+ const workspaceRoot = getWorkspaceRoot(process.cwd());
257
+ absoluteFiles = logMessage.files.map((f) => path.resolve(workspaceRoot, f));
258
+ }
259
+ if (!hasContent && !hasFiles) {
260
+ lastMessageId = logMessage.id;
261
+ await writeDiscordState({ lastSyncedMessageId: lastMessageId }).catch(console.error);
262
+ continue;
263
+ }
264
+ try {
265
+ const dm = await (await client.users.fetch(discordUserId)).createDM();
266
+ if (hasContent && logMessage.content.length > 2e3) {
267
+ const chunks = chunkString(logMessage.content, 2e3);
268
+ for (let i = 0; i < chunks.length; i++) {
269
+ if (signal?.aborted) break;
270
+ const chunkOptions = { content: chunks[i] };
271
+ if (i === chunks.length - 1 && hasFiles) chunkOptions.files = absoluteFiles;
272
+ await dm.send(chunkOptions);
273
+ }
274
+ } else {
275
+ const options = {};
276
+ if (hasContent) options.content = logMessage.content;
277
+ if (hasFiles) options.files = absoluteFiles;
278
+ await dm.send(options);
279
+ }
280
+ } catch (error) {
281
+ console.error(`Failed to send message to Discord user ${discordUserId}:`, error);
282
+ break;
283
+ }
284
+ }
285
+ lastMessageId = message.id;
286
+ await writeDiscordState({ lastSyncedMessageId: lastMessageId }).catch(console.error);
287
+ }
288
+ });
289
+ },
290
+ onError: (error) => {
291
+ console.error(`Error in daemon-to-discord forwarder subscription. Retrying in ${retryDelay}ms.`, error);
292
+ subscription?.unsubscribe();
293
+ subscription = null;
294
+ if (signal?.aborted) {
295
+ resolve();
296
+ return;
297
+ }
298
+ setTimeout(() => {
299
+ retryDelay = Math.min(retryDelay * 2, maxRetryDelay);
300
+ connect();
301
+ }, retryDelay);
302
+ },
303
+ onComplete: () => {
304
+ subscription = null;
305
+ if (!signal?.aborted) setTimeout(() => connect(), retryDelay);
306
+ else resolve();
307
+ }
308
+ });
309
+ };
310
+ let typingSubscription = null;
311
+ let typingRetryDelay = 1e3;
312
+ const connectTyping = () => {
313
+ if (signal?.aborted) return;
314
+ typingSubscription = trpc.waitForTyping.subscribe({ chatId }, {
315
+ onData: async (event) => {
316
+ typingRetryDelay = 1e3;
317
+ if (!event) return;
318
+ try {
319
+ await (await (await client.users.fetch(discordUserId)).createDM()).sendTyping();
320
+ } catch (error) {
321
+ console.error(`Failed to send typing indicator to Discord user ${discordUserId}:`, error);
322
+ }
323
+ },
324
+ onError: (error) => {
325
+ console.error(`Error in daemon-to-discord typing forwarder subscription. Retrying in ${typingRetryDelay}ms.`, error);
326
+ typingSubscription?.unsubscribe();
327
+ typingSubscription = null;
328
+ if (signal?.aborted) return;
329
+ setTimeout(() => {
330
+ typingRetryDelay = Math.min(typingRetryDelay * 2, maxRetryDelay);
331
+ connectTyping();
332
+ }, typingRetryDelay);
333
+ },
334
+ onComplete: () => {
335
+ typingSubscription = null;
336
+ if (!signal?.aborted) setTimeout(() => connectTyping(), typingRetryDelay);
337
+ }
338
+ });
339
+ };
340
+ connect();
341
+ connectTyping();
342
+ signal?.addEventListener("abort", () => {
343
+ subscription?.unsubscribe();
344
+ typingSubscription?.unsubscribe();
345
+ resolve();
346
+ });
347
+ });
348
+ }
349
+ function chunkString(str, size) {
350
+ const chunks = [];
351
+ const chars = Array.from(str);
352
+ for (let i = 0; i < chars.length; i += size) chunks.push(chars.slice(i, i + size).join(""));
353
+ return chunks;
354
+ }
355
+
356
+ //#endregion
357
+ //#region src/adapter-discord/index.ts
358
+ async function main() {
359
+ if (process.argv.slice(2)[0] === "init") {
360
+ await initDiscordConfig();
361
+ return;
362
+ }
363
+ console.log("Discord Adapter starting...");
364
+ const config = await readDiscordConfig();
365
+ if (!config) {
366
+ console.error("Failed to load Discord configuration. Please ensure .clawmini/adapters/discord/config.json exists and is valid.");
367
+ process.exit(1);
368
+ }
369
+ const trpc = getTRPCClient();
370
+ const client = new Client({
371
+ intents: [GatewayIntentBits.DirectMessages, GatewayIntentBits.MessageContent],
372
+ partials: [Partials.Channel]
373
+ });
374
+ client.once(Events.ClientReady, (readyClient) => {
375
+ console.log(`Ready! Logged in as ${readyClient.user.tag}`);
376
+ startDaemonToDiscordForwarder(readyClient, trpc, config.authorizedUserId, config.chatId).catch((error) => {
377
+ console.error("Error in daemon-to-discord forwarder:", error);
378
+ });
379
+ });
380
+ client.on(Events.MessageCreate, async (message) => {
381
+ if (message.author.id === client.user?.id) return;
382
+ if (message.guild) return;
383
+ if (!isAuthorized(message.author.id, config.authorizedUserId)) {
384
+ console.log(`Unauthorized message from ${message.author.tag} (${message.author.id}) ignored.`);
385
+ return;
386
+ }
387
+ console.log(`Received message from ${message.author.tag}: ${message.content}`);
388
+ const downloadedFiles = [];
389
+ if (message.attachments.size > 0) {
390
+ const { getClawminiDir } = await import("../workspace-CSgfo_2J.mjs").then((n) => n._);
391
+ const tmpDir = path.join(getClawminiDir(process.cwd()), "tmp", "discord");
392
+ await fs$1.mkdir(tmpDir, { recursive: true });
393
+ const maxSizeMB = config.maxAttachmentSizeMB ?? 25;
394
+ const maxSizeBytes = maxSizeMB * 1024 * 1024;
395
+ for (const attachment of message.attachments.values()) {
396
+ if (attachment.size > maxSizeBytes) {
397
+ console.warn(`Attachment ${attachment.name} exceeds size limit (${maxSizeMB}MB). Ignoring.`);
398
+ await message.reply(`Warning: Attachment ${attachment.name} exceeds the size limit of ${maxSizeMB}MB and was ignored.`);
399
+ continue;
400
+ }
401
+ try {
402
+ const res = await fetch(attachment.url);
403
+ if (!res.ok) {
404
+ console.error(`Failed to download attachment ${attachment.name}`);
405
+ continue;
406
+ }
407
+ const uniqueName = `${Date.now()}-${attachment.name}`;
408
+ const filePath = path.join(tmpDir, uniqueName);
409
+ const arrayBuffer = await res.arrayBuffer();
410
+ await fs$1.writeFile(filePath, Buffer.from(arrayBuffer));
411
+ downloadedFiles.push(filePath);
412
+ } catch (err) {
413
+ console.error(`Error downloading attachment ${attachment.name}:`, err);
414
+ }
415
+ }
416
+ }
417
+ let finalContent = message.content;
418
+ if (message.reference && message.reference.messageId) try {
419
+ const referencedMessage = await message.fetchReference();
420
+ if (referencedMessage && referencedMessage.content) finalContent = `${referencedMessage.content.split("\n").map((line) => `> ${line}`).join("\n")}\n${finalContent}`;
421
+ } catch (err) {
422
+ console.error("Failed to fetch referenced message:", err);
423
+ }
424
+ console.log(`Forwarding message to daemon: ${finalContent}`);
425
+ try {
426
+ await trpc.sendMessage.mutate({
427
+ type: "send-message",
428
+ client: "cli",
429
+ data: {
430
+ message: finalContent,
431
+ chatId: config.chatId,
432
+ files: downloadedFiles.length > 0 ? downloadedFiles : void 0,
433
+ adapter: "discord",
434
+ noWait: true
435
+ }
436
+ });
437
+ console.log("Message forwarded to daemon successfully.");
438
+ } catch (error) {
439
+ console.error("Failed to forward message to daemon:", error);
440
+ }
441
+ });
442
+ try {
443
+ await client.login(config.botToken);
444
+ } catch (error) {
445
+ console.error("Failed to login to Discord:", error);
446
+ process.exit(1);
447
+ }
448
+ }
449
+ main().catch((error) => {
450
+ console.error("Unhandled error in Discord Adapter:", error);
451
+ process.exit(1);
452
+ });
453
+
454
+ //#endregion
455
+ export { main };
456
+ //# sourceMappingURL=index.mjs.map