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.
- package/.gemini/settings.json +46 -0
- package/.prettierrc +7 -0
- package/GEMINI.md +11 -0
- package/README.md +137 -0
- package/dist/adapter-discord/index.d.mts +5 -0
- package/dist/adapter-discord/index.d.mts.map +1 -0
- package/dist/adapter-discord/index.mjs +456 -0
- package/dist/adapter-discord/index.mjs.map +1 -0
- package/dist/chats-DKgTeU7i.mjs +91 -0
- package/dist/chats-DKgTeU7i.mjs.map +1 -0
- package/dist/chats-Zd_HXDHx.mjs +29 -0
- package/dist/chats-Zd_HXDHx.mjs.map +1 -0
- package/dist/cli/index.d.mts +1 -0
- package/dist/cli/index.mjs +850 -0
- package/dist/cli/index.mjs.map +1 -0
- package/dist/cli/lite.d.mts +1 -0
- package/dist/cli/lite.mjs +4434 -0
- package/dist/cli/lite.mjs.map +1 -0
- package/dist/daemon/index.d.mts +5 -0
- package/dist/daemon/index.d.mts.map +1 -0
- package/dist/daemon/index.mjs +1222 -0
- package/dist/daemon/index.mjs.map +1 -0
- package/dist/fetch-BjZVyU3Z.mjs +37 -0
- package/dist/fetch-BjZVyU3Z.mjs.map +1 -0
- package/dist/fs-B5wW0oaH.mjs +14 -0
- package/dist/fs-B5wW0oaH.mjs.map +1 -0
- package/dist/lite-Dl7WXyaH.mjs +80 -0
- package/dist/lite-Dl7WXyaH.mjs.map +1 -0
- package/dist/rolldown-runtime-95iHPtFO.mjs +18 -0
- package/dist/web/_app/env.js +1 -0
- package/dist/web/_app/immutable/assets/0.GI4C4dpV.css +1 -0
- package/dist/web/_app/immutable/chunks/B5abRDXp.js +1 -0
- package/dist/web/_app/immutable/chunks/B8yYFADm.js +1 -0
- package/dist/web/_app/immutable/chunks/BPy8HLo7.js +5 -0
- package/dist/web/_app/immutable/chunks/Bi0jeV7Q.js +1 -0
- package/dist/web/_app/immutable/chunks/BmUXQ3wy.js +2 -0
- package/dist/web/_app/immutable/chunks/C3k55nDF.js +1 -0
- package/dist/web/_app/immutable/chunks/COekwvP2.js +1 -0
- package/dist/web/_app/immutable/chunks/CSvS_NwK.js +1 -0
- package/dist/web/_app/immutable/chunks/CpaGRn9L.js +1 -0
- package/dist/web/_app/immutable/chunks/CyNaE55B.js +1 -0
- package/dist/web/_app/immutable/chunks/DG5RZBw-.js +2 -0
- package/dist/web/_app/immutable/chunks/Dc-UOHw9.js +1 -0
- package/dist/web/_app/immutable/chunks/DcrmIfTj.js +1 -0
- package/dist/web/_app/immutable/chunks/ZkLyk0mE.js +1 -0
- package/dist/web/_app/immutable/entry/app.B-vZe7PN.js +2 -0
- package/dist/web/_app/immutable/entry/start.oP1AgKhs.js +1 -0
- package/dist/web/_app/immutable/nodes/0.B5WFN0zw.js +1 -0
- package/dist/web/_app/immutable/nodes/1.D1wtJb2k.js +1 -0
- package/dist/web/_app/immutable/nodes/2.CK3CLC0f.js +1 -0
- package/dist/web/_app/immutable/nodes/3.BB5wCoBf.js +4 -0
- package/dist/web/_app/immutable/nodes/4.Dr2jvAXK.js +1 -0
- package/dist/web/_app/immutable/nodes/5.BJl7oM3b.js +1 -0
- package/dist/web/_app/version.json +1 -0
- package/dist/web/index.html +37 -0
- package/dist/web/robots.txt +3 -0
- package/dist/workspace-CSgfo_2J.mjs +383 -0
- package/dist/workspace-CSgfo_2J.mjs.map +1 -0
- package/docs/01_chats/development_log.md +36 -0
- package/docs/01_chats/notes.md +27 -0
- package/docs/01_chats/prd.md +47 -0
- package/docs/01_chats/questions.md +19 -0
- package/docs/01_chats/tickets.md +67 -0
- package/docs/02_sessions/development_log.md +79 -0
- package/docs/02_sessions/notes.md +40 -0
- package/docs/02_sessions/prd.md +75 -0
- package/docs/02_sessions/questions.md +7 -0
- package/docs/02_sessions/tickets.md +68 -0
- package/docs/03_web_interface/development_log.md +60 -0
- package/docs/03_web_interface/notes.md +29 -0
- package/docs/03_web_interface/prd.md +42 -0
- package/docs/03_web_interface/questions.md +8 -0
- package/docs/03_web_interface/tickets.md +59 -0
- package/docs/04_agents/development_log.md +54 -0
- package/docs/04_agents/notes.md +45 -0
- package/docs/04_agents/prd.md +47 -0
- package/docs/04_agents/questions.md +13 -0
- package/docs/04_agents/tickets.md +107 -0
- package/docs/05_routers/development_log.md +13 -0
- package/docs/05_routers/notes.md +40 -0
- package/docs/05_routers/prd.md +55 -0
- package/docs/05_routers/questions.md +21 -0
- package/docs/05_routers/tickets.md +109 -0
- package/docs/06_agent_templates/development_log.md +38 -0
- package/docs/06_agent_templates/notes.md +25 -0
- package/docs/06_agent_templates/prd.md +34 -0
- package/docs/06_agent_templates/questions.md +11 -0
- package/docs/06_agent_templates/tickets.md +49 -0
- package/docs/06_cron/development_log.md +51 -0
- package/docs/06_cron/notes.md +14 -0
- package/docs/06_cron/prd.md +92 -0
- package/docs/06_cron/questions.md +15 -0
- package/docs/06_cron/tickets.md +75 -0
- package/docs/07_web_chat_ux/development_log.md +30 -0
- package/docs/07_web_chat_ux/notes.md +25 -0
- package/docs/07_web_chat_ux/prd.md +46 -0
- package/docs/07_web_chat_ux/questions.md +7 -0
- package/docs/07_web_chat_ux/tickets.md +48 -0
- package/docs/08_agent_api/development_log.md +52 -0
- package/docs/08_agent_api/notes.md +31 -0
- package/docs/08_agent_api/prd.md +56 -0
- package/docs/08_agent_api/questions.md +14 -0
- package/docs/08_agent_api/tickets.md +104 -0
- package/docs/09_agent_fallbacks/development_log.md +52 -0
- package/docs/09_agent_fallbacks/notes.md +40 -0
- package/docs/09_agent_fallbacks/prd.md +55 -0
- package/docs/09_agent_fallbacks/questions.md +10 -0
- package/docs/09_agent_fallbacks/tickets.md +88 -0
- package/docs/09_discord_adapter/development_log.md +95 -0
- package/docs/09_discord_adapter/notes.md +18 -0
- package/docs/09_discord_adapter/prd.md +57 -0
- package/docs/09_discord_adapter/questions.md +16 -0
- package/docs/09_discord_adapter/tickets.md +116 -0
- package/docs/10_file_attachments/development_log.md +55 -0
- package/docs/10_file_attachments/notes.md +59 -0
- package/docs/10_file_attachments/prd.md +73 -0
- package/docs/10_file_attachments/questions.md +15 -0
- package/docs/10_file_attachments/tickets.md +88 -0
- package/docs/11_message_verbosity/development_log.md +43 -0
- package/docs/11_message_verbosity/notes.md +26 -0
- package/docs/11_message_verbosity/prd.md +44 -0
- package/docs/11_message_verbosity/questions.md +8 -0
- package/docs/11_message_verbosity/tickets.md +33 -0
- package/docs/12_environments/development_log.md +43 -0
- package/docs/12_environments/notes.md +45 -0
- package/docs/12_environments/prd.md +113 -0
- package/docs/12_environments/questions.md +17 -0
- package/docs/12_environments/tickets.md +87 -0
- package/docs/12_setup_flow_improvements/development_log.md +40 -0
- package/docs/12_setup_flow_improvements/notes.md +34 -0
- package/docs/12_setup_flow_improvements/prd.md +35 -0
- package/docs/12_setup_flow_improvements/questions.md +8 -0
- package/docs/12_setup_flow_improvements/tickets.md +122 -0
- package/docs/13_discord_typing_indicators/development_log.md +38 -0
- package/docs/13_discord_typing_indicators/notes.md +18 -0
- package/docs/13_discord_typing_indicators/prd.md +41 -0
- package/docs/13_discord_typing_indicators/questions.md +6 -0
- package/docs/13_discord_typing_indicators/tickets.md +60 -0
- package/docs/14_interruptions/development_log.md +50 -0
- package/docs/14_interruptions/notes.md +38 -0
- package/docs/14_interruptions/prd.md +46 -0
- package/docs/14_interruptions/questions.md +12 -0
- package/docs/14_interruptions/tickets.md +69 -0
- package/docs/15_sandbox_policies/development_log.md +95 -0
- package/docs/15_sandbox_policies/notes.md +33 -0
- package/docs/15_sandbox_policies/prd.md +163 -0
- package/docs/15_sandbox_policies/questions.md +10 -0
- package/docs/15_sandbox_policies/tickets.md +196 -0
- package/docs/CHECKS.md +9 -0
- package/docs/guides/discord_adapter_setup.md +69 -0
- package/docs/guides/sandbox_policies.md +76 -0
- package/eslint.config.js +47 -0
- package/napkin.md +21 -0
- package/package.json +50 -0
- package/scripts/create_worktree.sh +49 -0
- package/scripts/get_pr_comments.sh +36 -0
- package/src/adapter-discord/client.test.ts +65 -0
- package/src/adapter-discord/client.ts +41 -0
- package/src/adapter-discord/config.test.ts +156 -0
- package/src/adapter-discord/config.ts +61 -0
- package/src/adapter-discord/forwarder.test.ts +493 -0
- package/src/adapter-discord/forwarder.ts +246 -0
- package/src/adapter-discord/index.test.ts +399 -0
- package/src/adapter-discord/index.ts +147 -0
- package/src/adapter-discord/state.test.ts +65 -0
- package/src/adapter-discord/state.ts +44 -0
- package/src/cli/client.ts +46 -0
- package/src/cli/commands/agents.ts +138 -0
- package/src/cli/commands/chats.ts +79 -0
- package/src/cli/commands/down.ts +32 -0
- package/src/cli/commands/environments.ts +39 -0
- package/src/cli/commands/export-lite.ts +62 -0
- package/src/cli/commands/init.ts +79 -0
- package/src/cli/commands/jobs.ts +141 -0
- package/src/cli/commands/messages.ts +103 -0
- package/src/cli/commands/up.ts +26 -0
- package/src/cli/commands/web-api/agents.ts +138 -0
- package/src/cli/commands/web-api/chats.ts +213 -0
- package/src/cli/commands/web-api/utils.ts +27 -0
- package/src/cli/commands/web.ts +105 -0
- package/src/cli/e2e/adapter-discord.test.ts +76 -0
- package/src/cli/e2e/agents.test.ts +140 -0
- package/src/cli/e2e/basic.test.ts +43 -0
- package/src/cli/e2e/cron.test.ts +132 -0
- package/src/cli/e2e/daemon.test.ts +293 -0
- package/src/cli/e2e/environments.test.ts +66 -0
- package/src/cli/e2e/export-lite-func.test.ts +155 -0
- package/src/cli/e2e/export-lite.test.ts +51 -0
- package/src/cli/e2e/fallbacks.test.ts +169 -0
- package/src/cli/e2e/global-setup.ts +15 -0
- package/src/cli/e2e/init.test.ts +70 -0
- package/src/cli/e2e/messages.test.ts +294 -0
- package/src/cli/e2e/requests.test.ts +165 -0
- package/src/cli/e2e/utils.ts +66 -0
- package/src/cli/index.test.ts +7 -0
- package/src/cli/index.ts +29 -0
- package/src/cli/lite.ts +247 -0
- package/src/cli/utils.ts +4 -0
- package/src/daemon/auth.test.ts +50 -0
- package/src/daemon/auth.ts +69 -0
- package/src/daemon/chats.ts +26 -0
- package/src/daemon/cron.test.ts +28 -0
- package/src/daemon/cron.ts +159 -0
- package/src/daemon/events.ts +15 -0
- package/src/daemon/index.ts +212 -0
- package/src/daemon/message-agent.test.ts +132 -0
- package/src/daemon/message-extraction.test.ts +166 -0
- package/src/daemon/message-fallbacks.test.ts +313 -0
- package/src/daemon/message-interruption.test.ts +125 -0
- package/src/daemon/message-queue.test.ts +143 -0
- package/src/daemon/message-router.test.ts +106 -0
- package/src/daemon/message-session.test.ts +127 -0
- package/src/daemon/message-test-utils.ts +41 -0
- package/src/daemon/message-typing.test.ts +93 -0
- package/src/daemon/message-verbosity.test.ts +127 -0
- package/src/daemon/message.ts +600 -0
- package/src/daemon/observation.test.ts +118 -0
- package/src/daemon/policy-request-service.test.ts +87 -0
- package/src/daemon/policy-request-service.ts +62 -0
- package/src/daemon/policy-utils.test.ts +138 -0
- package/src/daemon/policy-utils.ts +152 -0
- package/src/daemon/queue.test.ts +89 -0
- package/src/daemon/queue.ts +87 -0
- package/src/daemon/request-store.test.ts +103 -0
- package/src/daemon/request-store.ts +96 -0
- package/src/daemon/router-policy-request.test.ts +99 -0
- package/src/daemon/router.test.ts +380 -0
- package/src/daemon/router.ts +510 -0
- package/src/daemon/routers/slash-command.test.ts +145 -0
- package/src/daemon/routers/slash-command.ts +58 -0
- package/src/daemon/routers/slash-interrupt.test.ts +30 -0
- package/src/daemon/routers/slash-interrupt.ts +7 -0
- package/src/daemon/routers/slash-new.test.ts +59 -0
- package/src/daemon/routers/slash-new.ts +14 -0
- package/src/daemon/routers/slash-policies.test.ts +167 -0
- package/src/daemon/routers/slash-policies.ts +131 -0
- package/src/daemon/routers/slash-stop.test.ts +30 -0
- package/src/daemon/routers/slash-stop.ts +3 -0
- package/src/daemon/routers/types.ts +10 -0
- package/src/daemon/routers/utils.ts +22 -0
- package/src/daemon/routers.test.ts +141 -0
- package/src/daemon/routers.ts +115 -0
- package/src/daemon/utils/spawn.ts +61 -0
- package/src/shared/agent-utils.ts +30 -0
- package/src/shared/chats.test.ts +112 -0
- package/src/shared/chats.ts +164 -0
- package/src/shared/config.test.ts +90 -0
- package/src/shared/config.ts +100 -0
- package/src/shared/event-source.ts +121 -0
- package/src/shared/fetch.ts +45 -0
- package/src/shared/lite.ts +129 -0
- package/src/shared/policies.ts +24 -0
- package/src/shared/utils/env.ts +27 -0
- package/src/shared/utils/fs.ts +13 -0
- package/src/shared/workspace.test.ts +345 -0
- package/src/shared/workspace.ts +500 -0
- package/templates/environments/cladding/env.json +7 -0
- package/templates/environments/macos/env.json +8 -0
- package/templates/environments/macos/sandbox.sb +21 -0
- package/templates/environments/macos-proxy/allowlist.txt +1 -0
- package/templates/environments/macos-proxy/env.json +14 -0
- package/templates/environments/macos-proxy/proxy.mjs +86 -0
- package/templates/environments/macos-proxy/sandbox.sb +34 -0
- package/templates/gemini/settings.json +11 -0
- package/templates/gemini-claw/.gemini/hooks/clawmini-logging.sh +17 -0
- package/templates/gemini-claw/.gemini/settings.json +24 -0
- package/templates/gemini-claw/.gemini/skills/clawmini-jobs/SKILL.md +40 -0
- package/templates/gemini-claw/.gemini/system.md +98 -0
- package/templates/gemini-claw/BOOTSTRAP.md +54 -0
- package/templates/gemini-claw/GEMINI.md +107 -0
- package/templates/gemini-claw/HEARTBEAT.md +3 -0
- package/templates/gemini-claw/MEMORY.md +2 -0
- package/templates/gemini-claw/SOUL.md +42 -0
- package/templates/gemini-claw/TOOLS.md +38 -0
- package/templates/gemini-claw/USER.md +15 -0
- package/templates/gemini-claw/memory/.gitkeep +0 -0
- package/templates/gemini-claw/settings.json +24 -0
- package/templates/opencode/settings.json +11 -0
- package/tsconfig.json +42 -0
- package/tsdown.config.ts +19 -0
- package/vitest.config.ts +9 -0
- package/web/.svelte-kit/ambient.d.ts +382 -0
- package/web/.svelte-kit/generated/client/app.js +35 -0
- package/web/.svelte-kit/generated/client/matchers.js +1 -0
- package/web/.svelte-kit/generated/client/nodes/0.js +3 -0
- package/web/.svelte-kit/generated/client/nodes/1.js +1 -0
- package/web/.svelte-kit/generated/client/nodes/2.js +1 -0
- package/web/.svelte-kit/generated/client/nodes/3.js +1 -0
- package/web/.svelte-kit/generated/client/nodes/4.js +3 -0
- package/web/.svelte-kit/generated/client/nodes/5.js +3 -0
- package/web/.svelte-kit/generated/client-optimized/app.js +35 -0
- package/web/.svelte-kit/generated/client-optimized/matchers.js +1 -0
- package/web/.svelte-kit/generated/client-optimized/nodes/0.js +3 -0
- package/web/.svelte-kit/generated/client-optimized/nodes/1.js +1 -0
- package/web/.svelte-kit/generated/client-optimized/nodes/2.js +1 -0
- package/web/.svelte-kit/generated/client-optimized/nodes/3.js +1 -0
- package/web/.svelte-kit/generated/client-optimized/nodes/4.js +3 -0
- package/web/.svelte-kit/generated/client-optimized/nodes/5.js +3 -0
- package/web/.svelte-kit/generated/root.js +3 -0
- package/web/.svelte-kit/generated/root.svelte +68 -0
- package/web/.svelte-kit/generated/server/internal.js +53 -0
- package/web/.svelte-kit/non-ambient.d.ts +46 -0
- package/web/.svelte-kit/output/client/.vite/manifest.json +251 -0
- package/web/.svelte-kit/output/client/_app/immutable/assets/0.GI4C4dpV.css +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/B5abRDXp.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/B8yYFADm.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/BPy8HLo7.js +5 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/Bi0jeV7Q.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/BmUXQ3wy.js +2 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/C3k55nDF.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/COekwvP2.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/CSvS_NwK.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/CpaGRn9L.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/CyNaE55B.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/DG5RZBw-.js +2 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/Dc-UOHw9.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/DcrmIfTj.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/ZkLyk0mE.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/entry/app.B-vZe7PN.js +2 -0
- package/web/.svelte-kit/output/client/_app/immutable/entry/start.oP1AgKhs.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/nodes/0.B5WFN0zw.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/nodes/1.D1wtJb2k.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/nodes/2.CK3CLC0f.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/nodes/3.BB5wCoBf.js +4 -0
- package/web/.svelte-kit/output/client/_app/immutable/nodes/4.Dr2jvAXK.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/nodes/5.BJl7oM3b.js +1 -0
- package/web/.svelte-kit/output/client/_app/version.json +1 -0
- package/web/.svelte-kit/output/client/robots.txt +3 -0
- package/web/.svelte-kit/output/prerendered/dependencies/_app/env.js +1 -0
- package/web/.svelte-kit/output/server/.vite/manifest.json +215 -0
- package/web/.svelte-kit/output/server/_app/immutable/assets/_layout.GI4C4dpV.css +1 -0
- package/web/.svelte-kit/output/server/chunks/Icon.js +153 -0
- package/web/.svelte-kit/output/server/chunks/bot.js +2753 -0
- package/web/.svelte-kit/output/server/chunks/client.js +47 -0
- package/web/.svelte-kit/output/server/chunks/environment.js +34 -0
- package/web/.svelte-kit/output/server/chunks/exports.js +231 -0
- package/web/.svelte-kit/output/server/chunks/false.js +4 -0
- package/web/.svelte-kit/output/server/chunks/index-server.js +20 -0
- package/web/.svelte-kit/output/server/chunks/index.js +24 -0
- package/web/.svelte-kit/output/server/chunks/internal.js +133 -0
- package/web/.svelte-kit/output/server/chunks/plus.js +81 -0
- package/web/.svelte-kit/output/server/chunks/root.js +4076 -0
- package/web/.svelte-kit/output/server/chunks/shared.js +789 -0
- package/web/.svelte-kit/output/server/chunks/utils.js +43 -0
- package/web/.svelte-kit/output/server/entries/fallbacks/error.svelte.js +11 -0
- package/web/.svelte-kit/output/server/entries/pages/_layout.svelte.js +3944 -0
- package/web/.svelte-kit/output/server/entries/pages/_layout.ts.js +28 -0
- package/web/.svelte-kit/output/server/entries/pages/_page.svelte.js +7 -0
- package/web/.svelte-kit/output/server/entries/pages/agents/_page.svelte.js +379 -0
- package/web/.svelte-kit/output/server/entries/pages/chats/_id_/_page.svelte.js +292 -0
- package/web/.svelte-kit/output/server/entries/pages/chats/_id_/_page.ts.js +17 -0
- package/web/.svelte-kit/output/server/entries/pages/chats/_id_/settings/_page.svelte.js +259 -0
- package/web/.svelte-kit/output/server/entries/pages/chats/_id_/settings/_page.ts.js +17 -0
- package/web/.svelte-kit/output/server/index.js +3748 -0
- package/web/.svelte-kit/output/server/internal.js +14 -0
- package/web/.svelte-kit/output/server/manifest-full.js +63 -0
- package/web/.svelte-kit/output/server/manifest.js +63 -0
- package/web/.svelte-kit/output/server/nodes/0.js +13 -0
- package/web/.svelte-kit/output/server/nodes/1.js +8 -0
- package/web/.svelte-kit/output/server/nodes/2.js +8 -0
- package/web/.svelte-kit/output/server/nodes/3.js +8 -0
- package/web/.svelte-kit/output/server/nodes/4.js +13 -0
- package/web/.svelte-kit/output/server/nodes/5.js +13 -0
- package/web/.svelte-kit/output/server/remote-entry.js +557 -0
- package/web/.svelte-kit/tsconfig.json +67 -0
- package/web/.svelte-kit/types/route_meta_data.json +17 -0
- package/web/.svelte-kit/types/src/routes/$types.d.ts +26 -0
- package/web/.svelte-kit/types/src/routes/agents/$types.d.ts +18 -0
- package/web/.svelte-kit/types/src/routes/chats/[id]/$types.d.ts +21 -0
- package/web/.svelte-kit/types/src/routes/chats/[id]/proxy+page.ts +20 -0
- package/web/.svelte-kit/types/src/routes/chats/[id]/settings/$types.d.ts +21 -0
- package/web/.svelte-kit/types/src/routes/chats/[id]/settings/proxy+page.ts +19 -0
- package/web/.svelte-kit/types/src/routes/proxy+layout.ts +35 -0
- package/web/README.md +42 -0
- package/web/components.json +16 -0
- package/web/package.json +41 -0
- package/web/src/app.css +121 -0
- package/web/src/app.d.ts +13 -0
- package/web/src/app.html +11 -0
- package/web/src/demo.spec.ts +7 -0
- package/web/src/lib/app-state.svelte.ts +3 -0
- package/web/src/lib/assets/favicon.svg +1 -0
- package/web/src/lib/components/app/app-sidebar-test-wrapper.svelte +10 -0
- package/web/src/lib/components/app/app-sidebar.svelte +171 -0
- package/web/src/lib/components/app/app-sidebar.svelte.spec.ts +13 -0
- package/web/src/lib/components/ui/button/button.svelte +82 -0
- package/web/src/lib/components/ui/button/index.ts +17 -0
- package/web/src/lib/components/ui/dialog/dialog-close.svelte +7 -0
- package/web/src/lib/components/ui/dialog/dialog-content.svelte +45 -0
- package/web/src/lib/components/ui/dialog/dialog-description.svelte +17 -0
- package/web/src/lib/components/ui/dialog/dialog-footer.svelte +20 -0
- package/web/src/lib/components/ui/dialog/dialog-header.svelte +20 -0
- package/web/src/lib/components/ui/dialog/dialog-overlay.svelte +20 -0
- package/web/src/lib/components/ui/dialog/dialog-portal.svelte +7 -0
- package/web/src/lib/components/ui/dialog/dialog-title.svelte +17 -0
- package/web/src/lib/components/ui/dialog/dialog-trigger.svelte +7 -0
- package/web/src/lib/components/ui/dialog/dialog.svelte +7 -0
- package/web/src/lib/components/ui/dialog/index.ts +34 -0
- package/web/src/lib/components/ui/input/index.ts +7 -0
- package/web/src/lib/components/ui/input/input.svelte +52 -0
- package/web/src/lib/components/ui/separator/index.ts +7 -0
- package/web/src/lib/components/ui/separator/separator.svelte +21 -0
- package/web/src/lib/components/ui/sheet/index.ts +34 -0
- package/web/src/lib/components/ui/sheet/sheet-close.svelte +7 -0
- package/web/src/lib/components/ui/sheet/sheet-content.svelte +60 -0
- package/web/src/lib/components/ui/sheet/sheet-description.svelte +17 -0
- package/web/src/lib/components/ui/sheet/sheet-footer.svelte +20 -0
- package/web/src/lib/components/ui/sheet/sheet-header.svelte +20 -0
- package/web/src/lib/components/ui/sheet/sheet-overlay.svelte +20 -0
- package/web/src/lib/components/ui/sheet/sheet-portal.svelte +7 -0
- package/web/src/lib/components/ui/sheet/sheet-title.svelte +17 -0
- package/web/src/lib/components/ui/sheet/sheet-trigger.svelte +7 -0
- package/web/src/lib/components/ui/sheet/sheet.svelte +7 -0
- package/web/src/lib/components/ui/sidebar/constants.ts +6 -0
- package/web/src/lib/components/ui/sidebar/context.svelte.ts +79 -0
- package/web/src/lib/components/ui/sidebar/index.ts +75 -0
- package/web/src/lib/components/ui/sidebar/sidebar-content.svelte +24 -0
- package/web/src/lib/components/ui/sidebar/sidebar-footer.svelte +21 -0
- package/web/src/lib/components/ui/sidebar/sidebar-group-action.svelte +36 -0
- package/web/src/lib/components/ui/sidebar/sidebar-group-content.svelte +21 -0
- package/web/src/lib/components/ui/sidebar/sidebar-group-label.svelte +34 -0
- package/web/src/lib/components/ui/sidebar/sidebar-group.svelte +21 -0
- package/web/src/lib/components/ui/sidebar/sidebar-header.svelte +21 -0
- package/web/src/lib/components/ui/sidebar/sidebar-input.svelte +21 -0
- package/web/src/lib/components/ui/sidebar/sidebar-inset.svelte +24 -0
- package/web/src/lib/components/ui/sidebar/sidebar-menu-action.svelte +43 -0
- package/web/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte +29 -0
- package/web/src/lib/components/ui/sidebar/sidebar-menu-button.svelte +103 -0
- package/web/src/lib/components/ui/sidebar/sidebar-menu-item.svelte +21 -0
- package/web/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte +36 -0
- package/web/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte +43 -0
- package/web/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte +21 -0
- package/web/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte +25 -0
- package/web/src/lib/components/ui/sidebar/sidebar-menu.svelte +21 -0
- package/web/src/lib/components/ui/sidebar/sidebar-provider.svelte +53 -0
- package/web/src/lib/components/ui/sidebar/sidebar-rail.svelte +36 -0
- package/web/src/lib/components/ui/sidebar/sidebar-separator.svelte +19 -0
- package/web/src/lib/components/ui/sidebar/sidebar-trigger.svelte +35 -0
- package/web/src/lib/components/ui/sidebar/sidebar.svelte +104 -0
- package/web/src/lib/components/ui/skeleton/index.ts +7 -0
- package/web/src/lib/components/ui/skeleton/skeleton.svelte +17 -0
- package/web/src/lib/components/ui/switch/index.ts +7 -0
- package/web/src/lib/components/ui/switch/switch.svelte +29 -0
- package/web/src/lib/components/ui/textarea/index.ts +7 -0
- package/web/src/lib/components/ui/textarea/textarea.svelte +23 -0
- package/web/src/lib/components/ui/tooltip/index.ts +19 -0
- package/web/src/lib/components/ui/tooltip/tooltip-content.svelte +52 -0
- package/web/src/lib/components/ui/tooltip/tooltip-portal.svelte +7 -0
- package/web/src/lib/components/ui/tooltip/tooltip-provider.svelte +7 -0
- package/web/src/lib/components/ui/tooltip/tooltip-trigger.svelte +7 -0
- package/web/src/lib/components/ui/tooltip/tooltip.svelte +7 -0
- package/web/src/lib/hooks/is-mobile.svelte.ts +9 -0
- package/web/src/lib/index.ts +1 -0
- package/web/src/lib/types.ts +23 -0
- package/web/src/lib/utils.ts +13 -0
- package/web/src/routes/+layout.svelte +67 -0
- package/web/src/routes/+layout.ts +34 -0
- package/web/src/routes/+page.svelte +7 -0
- package/web/src/routes/agents/+page.svelte +206 -0
- package/web/src/routes/chats/[id]/+page.svelte +406 -0
- package/web/src/routes/chats/[id]/+page.ts +19 -0
- package/web/src/routes/chats/[id]/page.svelte.spec.ts +102 -0
- package/web/src/routes/chats/[id]/settings/+page.svelte +165 -0
- package/web/src/routes/chats/[id]/settings/+page.ts +18 -0
- package/web/src/routes/page.svelte.spec.ts +13 -0
- package/web/static/robots.txt +3 -0
- package/web/svelte.config.js +21 -0
- package/web/tsconfig.json +20 -0
- package/web/vite.config.ts +41 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Agent API Tickets
|
|
2
|
+
|
|
3
|
+
## Step 1: Configuration Updates
|
|
4
|
+
**Description:** Update the global settings schema to support the new `api` configuration option.
|
|
5
|
+
**Tasks:**
|
|
6
|
+
- Modify `src/shared/config.ts` (or relevant config file) to add an `api` property to the `SettingsSchema`.
|
|
7
|
+
- The `api` property should accept:
|
|
8
|
+
- `false` (default): Web server does not start.
|
|
9
|
+
- `true`: Web server starts on `127.0.0.1:3000` (or similar default).
|
|
10
|
+
- An object `{ host: string, port: number }`: Web server starts on the specified host and port.
|
|
11
|
+
- Add/update tests for config parsing to ensure the new `api` property is handled correctly.
|
|
12
|
+
**Verification:**
|
|
13
|
+
- Run `npm run format:check && npm run lint && npm run check && npm run test`
|
|
14
|
+
**Status:** Completed
|
|
15
|
+
|
|
16
|
+
## Step 2: Daemon HTTP Server
|
|
17
|
+
**Description:** Optionally start an HTTP server in the daemon to expose the tRPC router based on configuration.
|
|
18
|
+
**Tasks:**
|
|
19
|
+
- Modify `src/daemon/index.ts` to check the `api` configuration.
|
|
20
|
+
- If enabled, start an HTTP server (e.g., using `@trpc/server/adapters/node-http` or similar depending on the existing setup).
|
|
21
|
+
- Bind the tRPC router to this HTTP server.
|
|
22
|
+
- Ensure the server gracefully shuts down when the daemon stops.
|
|
23
|
+
**Verification:**
|
|
24
|
+
- Add unit/e2e tests to verify the HTTP server starts with the correct config and responds to tRPC requests.
|
|
25
|
+
- Run `npm run format:check && npm run lint && npm run check && npm run test`
|
|
26
|
+
**Status:** Completed
|
|
27
|
+
|
|
28
|
+
## Step 3: Agent Execution Context & Token Security
|
|
29
|
+
**Description:** Inject context and secure tokens into agent processes and validate them on the HTTP server.
|
|
30
|
+
**Tasks:**
|
|
31
|
+
- Implement a secure token generation and validation mechanism (e.g., HMAC with a secret or a simple JWT). The token must encode `chatId`, `agentId`, `sessionId`, and a `timestamp`.
|
|
32
|
+
- Update the daemon's tRPC context/middleware to validate `CLAW_API_TOKEN` (e.g., from the `Authorization` header) for HTTP requests, ensuring requests are scoped to the authorized chat/agent.
|
|
33
|
+
- Modify the agent spawning logic (likely in `src/daemon/message.ts` or related) to generate this token.
|
|
34
|
+
- Inject `CLAW_API_URL` and `CLAW_API_TOKEN` into the environment variables (`env`) of the spawned agent process.
|
|
35
|
+
**Verification:**
|
|
36
|
+
- Add unit tests for token generation and validation.
|
|
37
|
+
- Add integration tests verifying that spawned agents receive the correct environment variables.
|
|
38
|
+
- Run `npm run format:check && npm run lint && npm run check && npm run test`
|
|
39
|
+
**Status:** Completed
|
|
40
|
+
|
|
41
|
+
## Step 4: `clawmini export-lite` Command
|
|
42
|
+
**Description:** Add a new CLI command to export the standalone `clawmini-lite` client script.
|
|
43
|
+
**Tasks:**
|
|
44
|
+
- Create the source for `clawmini-lite` as a standalone, zero-dependency Node.js script (using native `fetch`).
|
|
45
|
+
- Add a new command `export-lite` to the CLI (`src/cli/commands/export-lite.ts` or similar).
|
|
46
|
+
- The command should output the script to the current directory by default, or to a specified path, or to stdout if `--stdout` is passed.
|
|
47
|
+
**Verification:**
|
|
48
|
+
- Add CLI tests to verify `clawmini export-lite` correctly writes the script file or outputs to stdout.
|
|
49
|
+
- Run `npm run format:check && npm run lint && npm run check && npm run test`
|
|
50
|
+
**Status:** Completed
|
|
51
|
+
|
|
52
|
+
## Step 5: `clawmini-lite` Client Functionality
|
|
53
|
+
**Description:** Implement the functionality within the exported `clawmini-lite` script.
|
|
54
|
+
**Tasks:**
|
|
55
|
+
- Ensure the `clawmini-lite` script reads `CLAW_API_URL` and `CLAW_API_TOKEN` from `process.env`.
|
|
56
|
+
- Implement a lightweight tRPC client (using `fetch`) inside the script.
|
|
57
|
+
- Implement the supported subcommands:
|
|
58
|
+
- `log <message>`: Appends a `{type: "log"}` message to the chat.
|
|
59
|
+
- `jobs list`: Lists cron jobs for the chat.
|
|
60
|
+
- `jobs add <...>`: Adds a job for the chat.
|
|
61
|
+
- `jobs delete <id>`: Deletes a job from the chat.
|
|
62
|
+
**Verification:**
|
|
63
|
+
- Add e2e tests that execute the exported `clawmini-lite` script as a subprocess against a running daemon HTTP server to verify all subcommands work correctly.
|
|
64
|
+
- Run `npm run format:check && npm run lint && npm run check && npm run test`
|
|
65
|
+
**Status:** Completed
|
|
66
|
+
|
|
67
|
+
## Issue 1: Refactor repeated `chatId` resolution in `router.ts`
|
|
68
|
+
**Priority:** High
|
|
69
|
+
**Description:** DRY violation in `src/daemon/router.ts`. The logic to resolve `chatId` (checking `input.chatId`, `ctx.tokenPayload.chatId`, or `getDefaultChatId()`) and calling `checkScope(ctx, chatId)` is duplicated 4 times across endpoints.
|
|
70
|
+
**Tasks:**
|
|
71
|
+
- Create an async helper `resolveAndCheckChatId(ctx: Context, inputChatId?: string): Promise<string>` that performs this logic.
|
|
72
|
+
- Replace the repeated logic in `logMessage`, `listCronJobs`, `addCronJob`, and `deleteCronJob` with a single call to this helper.
|
|
73
|
+
**Verification:**
|
|
74
|
+
- Run checks from `docs/CHECKS.md` to ensure all tests pass.
|
|
75
|
+
**Status:** Completed
|
|
76
|
+
|
|
77
|
+
## Issue 2: Refactor API settings parsing in `index.ts`
|
|
78
|
+
**Priority:** Medium
|
|
79
|
+
**Description:** DRY violation in `src/daemon/index.ts`. The parsing of API settings duplicates logic present in `getApiContext` in `src/daemon/auth.ts`.
|
|
80
|
+
**Tasks:**
|
|
81
|
+
- Import and use `getApiContext` in `src/daemon/index.ts` instead of manually checking `typeof parsed.data.api`.
|
|
82
|
+
**Verification:**
|
|
83
|
+
- Run checks from `docs/CHECKS.md` to ensure all tests pass.
|
|
84
|
+
**Status:** Completed
|
|
85
|
+
|
|
86
|
+
## Issue 3: Remove unnecessary `console.error` in `checkScope`
|
|
87
|
+
**Priority:** Low
|
|
88
|
+
**Description:** `checkScope` in `src/daemon/router.ts` uses `console.error` before throwing a TRPCError. This is unnecessary since it's an API validation failure that should be handled gracefully.
|
|
89
|
+
**Tasks:**
|
|
90
|
+
- Remove the `console.error` call in `checkScope`.
|
|
91
|
+
**Verification:**
|
|
92
|
+
- Run checks from `docs/CHECKS.md` to ensure all tests pass.
|
|
93
|
+
**Status:** Completed
|
|
94
|
+
|
|
95
|
+
## Issue 4: Prevent Timing Attacks on Token Validation
|
|
96
|
+
**Priority:** High
|
|
97
|
+
**Description:** The token validation in `src/daemon/auth.ts` uses strict equality (`!==`) to compare the provided HMAC signature against the expected signature. This exposes the daemon to timing attacks, where an attacker could potentially guess the signature character by character based on comparison times.
|
|
98
|
+
**Tasks:**
|
|
99
|
+
- Replace the strict equality check (`signature !== expectedHmac`) with a constant-time comparison using `crypto.timingSafeEqual`.
|
|
100
|
+
- Ensure the strings are converted to Buffers before comparison.
|
|
101
|
+
- Add a length check to prevent `timingSafeEqual` from throwing if the lengths differ.
|
|
102
|
+
**Verification:**
|
|
103
|
+
- Run checks from `docs/CHECKS.md` to ensure all tests pass, including the `auth.test.ts` which should still succeed for valid tokens and fail for tampered ones.
|
|
104
|
+
**Status:** Completed
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Development Log - Agent Fallbacks
|
|
2
|
+
|
|
3
|
+
## 2026-03-03
|
|
4
|
+
|
|
5
|
+
- Initializing development log.
|
|
6
|
+
- Starting on Ticket 1: Configuration Schema and Type Updates.
|
|
7
|
+
- Discovered pre-existing test failure in `src/cli/e2e/messages.test.ts` (`should maintain atomic ordering of user and log messages with --no-wait`). Proceeding with Ticket 1 as it is unrelated to this failure.
|
|
8
|
+
- Updated `src/shared/config.ts` with `FallbackSchema` and `fallbacks` in `AgentSchema`.
|
|
9
|
+
- Verified schema with a temporary unit test.
|
|
10
|
+
- Ticket 1 complete.
|
|
11
|
+
|
|
12
|
+
- Refactored `src/daemon/message.ts`:
|
|
13
|
+
- Updated `prepareCommandAndEnv` to merge base agent with fallback overrides.
|
|
14
|
+
- Refactored `executeDirectMessage` to include a nested retry loop (base attempt + fallback attempts).
|
|
15
|
+
- Implemented failure detection (non-zero exit code or empty extracted message content).
|
|
16
|
+
- Added `src/daemon/message-fallbacks.test.ts` with unit tests covering base failures, empty extraction, and multiple retries.
|
|
17
|
+
- Verified all checks and tests pass (including pre-existing flakiness in E2E tests which resolved themselves).
|
|
18
|
+
- Ticket 2 complete.
|
|
19
|
+
|
|
20
|
+
- Implemented exponential backoff logic in `src/daemon/message.ts`:
|
|
21
|
+
- Added `calculateDelay` helper with doubling logic and 15s cap.
|
|
22
|
+
- Added `sleep` helper.
|
|
23
|
+
- Integrated backoff into the retry loop in `executeDirectMessage`.
|
|
24
|
+
- Added unit tests for `calculateDelay` in `src/daemon/message-fallbacks.test.ts`.
|
|
25
|
+
- Verified all checks and tests pass.
|
|
26
|
+
- Ticket 3 complete.
|
|
27
|
+
|
|
28
|
+
## 2026-03-03 (continued)
|
|
29
|
+
|
|
30
|
+
- Starting on Ticket 4: UX Retry Notifications.
|
|
31
|
+
- Identifying insertion point in `src/daemon/message.ts` for retry log messages.
|
|
32
|
+
- Implemented `retry-delay` log message in `executeDirectMessage`.
|
|
33
|
+
- Added unit test in `src/daemon/message-fallbacks.test.ts` to verify the log message is appended before the sleep delay.
|
|
34
|
+
- Verified all checks and tests pass.
|
|
35
|
+
- Ticket 4 complete.
|
|
36
|
+
|
|
37
|
+
- Starting on Ticket 5: Comprehensive E2E Validation.
|
|
38
|
+
- Planning E2E test cases for various fallback scenarios:
|
|
39
|
+
- Base fails (exit code), fallback succeeds via env override.
|
|
40
|
+
- Base fails (empty content), fallback succeeds via command override.
|
|
41
|
+
- Exponential backoff (checking log messages).
|
|
42
|
+
- Exhausted fallbacks (all fail).
|
|
43
|
+
- Implemented Ticket 5:
|
|
44
|
+
- Discovered that "retrying" log messages were not appearing when moving between execution configurations (base -> fallback).
|
|
45
|
+
- Updated `calculateDelay` in `src/daemon/message.ts` to support an `isFallback` flag, ensuring a delay (and thus a log message) is triggered when starting a fallback if `delayMs` is present.
|
|
46
|
+
- Fixed `logMsg` construction to always include `stdout` property, as per `CommandLogMessage` definition and `napkin.md` notes.
|
|
47
|
+
- Created `src/cli/e2e/fallbacks.test.ts` to house all fallback-related E2E tests, keeping `src/cli/e2e/messages.test.ts` within the `max-lines` limit.
|
|
48
|
+
- Updated existing E2E test `should handle full multi-message session workflow` to expect `stdout` in log messages.
|
|
49
|
+
- Verified all checks (`npm run format:check && npm run lint && npm run check && npm run test`) pass.
|
|
50
|
+
- Ticket 5 complete.
|
|
51
|
+
|
|
52
|
+
ALL DONE
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Agent Fallbacks Research Notes
|
|
2
|
+
|
|
3
|
+
## Current State
|
|
4
|
+
|
|
5
|
+
**Agent Configuration (`src/shared/config.ts`)**
|
|
6
|
+
- `AgentSchema` currently has `commands`, `env`, and `directory`.
|
|
7
|
+
- No fallback logic exists.
|
|
8
|
+
|
|
9
|
+
**Execution Logic (`src/daemon/message.ts`)**
|
|
10
|
+
- `executeDirectMessage` runs the main command (either `new` or `append`).
|
|
11
|
+
- `mainResult` gives `stdout`, `stderr`, and `exitCode`.
|
|
12
|
+
- If `exitCode === 0`:
|
|
13
|
+
- It tries to extract the session ID (if `getSessionId` is defined).
|
|
14
|
+
- It tries to extract the message content (if `getMessageContent` is defined).
|
|
15
|
+
- The `logMsg` is created and appended to the chat.
|
|
16
|
+
|
|
17
|
+
## Proposed Changes for Fallbacks
|
|
18
|
+
|
|
19
|
+
**Configuration**
|
|
20
|
+
- Add an array of `fallbacks` to `AgentSchema`.
|
|
21
|
+
- Each fallback could have:
|
|
22
|
+
- `commands` (Partial override of `new`, `append`, `getMessageContent`, `getSessionId`)
|
|
23
|
+
- `env` (Partial override of environment variables, e.g., `$MODEL`)
|
|
24
|
+
- `delayMs` (Optional backoff time before executing the fallback)
|
|
25
|
+
|
|
26
|
+
**Detection of Errors**
|
|
27
|
+
- Failure condition 1: `mainResult.exitCode !== 0`.
|
|
28
|
+
- Failure condition 2: `getMessageContent` results in an empty string (`result.trim() === ''`).
|
|
29
|
+
|
|
30
|
+
**Execution Loop**
|
|
31
|
+
- Wrap the main execution block in `executeDirectMessage` inside a retry loop.
|
|
32
|
+
- The loop tries the base agent configuration first.
|
|
33
|
+
- If it fails, and there are fallbacks left, it picks the next fallback, merges its `env` and `commands` into the base agent config.
|
|
34
|
+
- Before running the fallback, if a delay is specified, it appends a message to the chat: "Error running agent, retrying in N seconds..." and waits.
|
|
35
|
+
- Empty fallback config just reruns the original command.
|
|
36
|
+
|
|
37
|
+
## Questions for PRD
|
|
38
|
+
- Should the retry message be a standard system message or replace the previous message?
|
|
39
|
+
- Are fallbacks evaluated one-by-one in sequence, or is there a max retry count for a single fallback?
|
|
40
|
+
- Should we add a `timeout` configuration for the command itself as part of failure detection?
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Product Requirements Document (PRD): Agent Fallbacks
|
|
2
|
+
|
|
3
|
+
## 1. Vision
|
|
4
|
+
To enhance the reliability and resilience of the Gemini CLI application by providing robust fallback mechanisms when agent commands fail. This will allow the application to automatically recover from transient issues, rate limits, or specific command failures, ensuring a smoother user experience.
|
|
5
|
+
|
|
6
|
+
## 2. Product/Market Background
|
|
7
|
+
In AI-driven CLI applications or agentic frameworks, execution errors are common due to external dependencies like API quotas, network timeouts, or model availability. Currently, if an agent fails (e.g., due to an empty response or an error code), the interaction stops, and the user must manually diagnose and retry. By introducing configurable fallbacks, agents can automatically retry operations or switch to alternative configurations (e.g., swapping a `$MODEL` environment variable to use a less restricted model) without user intervention.
|
|
8
|
+
|
|
9
|
+
## 3. Use Cases
|
|
10
|
+
- **Transient Network Errors:** An agent's curl command to an API fails due to a temporary network blip. The fallback simply re-runs the exact same command after a short delay.
|
|
11
|
+
- **Quota Exceeded/Rate Limits:** An agent hits a rate limit for an expensive AI model. A fallback changes the `$MODEL` environment variable to a cheaper, higher-quota model and retries.
|
|
12
|
+
- **Command Tuning:** An agent's primary prompt strategy fails to produce parsable output (resulting in an empty extracted message). The fallback tries a slightly modified `new` or `append` command with stronger formatting instructions.
|
|
13
|
+
|
|
14
|
+
## 4. Requirements
|
|
15
|
+
|
|
16
|
+
### 4.1 Configuration
|
|
17
|
+
- Expand the `AgentSchema` in `src/shared/config.ts` to support an array of `fallbacks`.
|
|
18
|
+
- A fallback configuration object will contain:
|
|
19
|
+
- `commands`: Optional partial override for `new`, `append`, `getSessionId`, and `getMessageContent`.
|
|
20
|
+
- `env`: Optional partial override of environment variables.
|
|
21
|
+
- `retries`: Optional integer denoting how many times this specific fallback (or the base configuration, if an empty fallback object is provided) should be retried before giving up. Defaults to 1.
|
|
22
|
+
- `delayMs`: Optional base delay in milliseconds before initiating a retry. Defaults to 1000ms.
|
|
23
|
+
|
|
24
|
+
### 4.2 Error Detection
|
|
25
|
+
An agent execution is considered "failed" if:
|
|
26
|
+
1. The main command's exit code is not zero (`mainResult.exitCode !== 0`).
|
|
27
|
+
2. The `getMessageContent` extraction command yields an empty string (`result.trim() === ''`) after successful execution.
|
|
28
|
+
|
|
29
|
+
*Note: Command execution timeouts are explicitly out of scope for this feature.*
|
|
30
|
+
|
|
31
|
+
### 4.3 Execution Logic & Retries
|
|
32
|
+
- When a failure is detected, the daemon (`src/daemon/message.ts`) must evaluate the fallbacks in the order they are defined.
|
|
33
|
+
- Before executing a fallback, its `env` and `commands` are merged with the original agent configuration.
|
|
34
|
+
- Retries for a given fallback will use an **exponential backoff** strategy.
|
|
35
|
+
- Delay calculation: `delayMs * (2 ^ (attempt - 1))`.
|
|
36
|
+
- The maximum delay between retries must be capped at 15 seconds (15,000ms).
|
|
37
|
+
- If all retries for a fallback fail, the system moves to the next fallback in the array.
|
|
38
|
+
- If all fallbacks are exhausted and the final attempt fails, the standard failure behavior occurs (logging the final error to the user).
|
|
39
|
+
|
|
40
|
+
### 4.4 Notifications / UX
|
|
41
|
+
- Upon detecting a failure that will be retried, a new "log" message must be appended to the chat history.
|
|
42
|
+
- The log message format should be: `"Error running agent, retrying in <N> seconds..."` where `<N>` is the computed delay for the current attempt.
|
|
43
|
+
- This log message is immediately sent to the user and persists in the chat history.
|
|
44
|
+
|
|
45
|
+
## 5. Security, Privacy, and Accessibility Concerns
|
|
46
|
+
- **Security:** Ensure that merged environment variables do not inadvertently leak secrets into logs. Standard logging practices for command execution must continue to sanitize or hide sensitive variables if applicable.
|
|
47
|
+
- **Privacy:** Fallback configurations must reside within the existing user-controlled settings files. No new telemetry or external reporting is introduced.
|
|
48
|
+
- **Accessibility:** Ensure that the retry log messages are clear and easily readable in terminal outputs or web interfaces, avoiding excessive spam (the exponential backoff helps mitigate rapid-fire log spam).
|
|
49
|
+
|
|
50
|
+
## 6. Development Strategy
|
|
51
|
+
1. **Schema Update:** Update `AgentSchema` in `src/shared/config.ts` to include `fallbacks`.
|
|
52
|
+
2. **Refactor Execution:** In `src/daemon/message.ts`, refactor the core execution inside `executeDirectMessage` to be callable within a retry loop.
|
|
53
|
+
3. **Implement Backoff & Retry Logic:** Add the loop with the exponential backoff calculation (capped at 15s) and fallback iteration.
|
|
54
|
+
4. **Log Messaging:** Integrate the retry notification log message generation into the retry loop.
|
|
55
|
+
5. **Testing:** Update unit tests (`daemon/message.test.ts` or similar) and e2e tests (`cli/e2e/messages.test.ts`) to verify failure detection, correct merging of fallback config, exponential backoff timing logic, and log message creation.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# PRD Questions
|
|
2
|
+
|
|
3
|
+
**Q1: Are fallbacks evaluated strictly one-by-one in the array sequence (meaning each fallback configuration only gets one attempt before moving to the next), or should a single fallback have its own retry count (e.g., trying the exact same fallback multiple times before giving up)?**
|
|
4
|
+
A1: Let's add an optional retry count per fallback; defaults to 1.
|
|
5
|
+
|
|
6
|
+
**Q2: For the notification message ("Error running agent, retrying in N seconds..."), should this be appended as a new system message to the chat that remains in the history, or should we update/replace a temporary message, or just include it as standard `stderr` output in the final message log?**
|
|
7
|
+
A2: This should be a new "log" message in the chat that is immediately sent to the user and persists.
|
|
8
|
+
|
|
9
|
+
**Q3: Should the delay for fallbacks and their retries use a fixed delay or an exponential backoff strategy? Additionally, should we add a command execution `timeoutMs` to detect if an agent hangs and trigger a fallback based on that timeout?**
|
|
10
|
+
A3: Use whatever is recommended for retries, but cap the retry delay at something reasonable (15s). No timeout is needed for the commands themselves.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Tickets for Agent Fallbacks
|
|
2
|
+
|
|
3
|
+
## Ticket 1: Configuration Schema and Type Updates
|
|
4
|
+
**Status:** completed
|
|
5
|
+
|
|
6
|
+
### Task
|
|
7
|
+
Update `src/shared/config.ts` to include the `fallbacks` property in `AgentSchema`.
|
|
8
|
+
- Create `FallbackSchema` with optional:
|
|
9
|
+
- `commands`: Partial override for `new`, `append`, `getSessionId`, and `getMessageContent`.
|
|
10
|
+
- `env`: `z.record(z.string(), z.string())` for environment overrides.
|
|
11
|
+
- `retries`: `z.number().int().min(0)` (default 1).
|
|
12
|
+
- `delayMs`: `z.number().int().min(0)` (default 1000).
|
|
13
|
+
- Update `AgentSchema` to include an optional `fallbacks: z.array(FallbackSchema)`.
|
|
14
|
+
- Update `Agent` type.
|
|
15
|
+
|
|
16
|
+
### Verification
|
|
17
|
+
- Run `npm run check` to ensure type consistency.
|
|
18
|
+
- Follow `./docs/CHECKS.md`: `npm run format:check && npm run lint`.
|
|
19
|
+
- (Optional) Verify with a small script that `AgentSchema.parse` handles a sample agent with multiple fallbacks.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Ticket 2: Refactor Execution Loop and Error Detection
|
|
24
|
+
**Status:** completed
|
|
25
|
+
|
|
26
|
+
### Task
|
|
27
|
+
Refactor `executeDirectMessage` in `src/daemon/message.ts` to support a retry loop and implement failure detection.
|
|
28
|
+
- **Failure Detection**: A run is failed if:
|
|
29
|
+
1. `mainResult.exitCode !== 0`
|
|
30
|
+
2. OR `getMessageContent` returns an empty string (`result.trim() === ''`).
|
|
31
|
+
- **Loop Structure**:
|
|
32
|
+
- Wrap the inner queue task logic in a loop that iterates through:
|
|
33
|
+
1. Base configuration (first attempt).
|
|
34
|
+
2. Each entry in `agent.fallbacks`.
|
|
35
|
+
- For each fallback, support multiple attempts based on its `retries` count.
|
|
36
|
+
- Update `prepareCommandAndEnv` (or implement a new helper) to handle merging of the base agent with fallback overrides (`commands` and `env`).
|
|
37
|
+
|
|
38
|
+
### Verification
|
|
39
|
+
- Run existing tests `npm run test` to ensure no regressions.
|
|
40
|
+
- Add unit tests in `src/daemon/message-fallbacks.test.ts` mocking `runCommand` to fail once and then succeed, verifying the loop triggers.
|
|
41
|
+
- Follow `./docs/CHECKS.md`.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Ticket 3: Exponential Backoff Logic
|
|
46
|
+
**Status:** completed
|
|
47
|
+
|
|
48
|
+
### Task
|
|
49
|
+
Implement the exponential backoff timing logic within the retry loop.
|
|
50
|
+
- **Delay Calculation**: `delay = delayMs * (2 ^ (attempt - 1))`.
|
|
51
|
+
- **Constraint**: Cap maximum delay at 15,000ms.
|
|
52
|
+
- **Implementation**: Use a `Promise`-based delay/sleep function before re-executing a command.
|
|
53
|
+
- Ensure the base `delayMs` defaults to 1000 if not provided in the fallback.
|
|
54
|
+
|
|
55
|
+
### Verification
|
|
56
|
+
- Add unit tests for the delay calculation logic to ensure it doubles correctly and caps at 15s.
|
|
57
|
+
- Follow `./docs/CHECKS.md`.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Ticket 4: UX Retry Notifications
|
|
62
|
+
**Status:** completed
|
|
63
|
+
|
|
64
|
+
### Task
|
|
65
|
+
Integrate log messages for retries into the execution loop in `src/daemon/message.ts`.
|
|
66
|
+
- Before waiting for a retry delay, append a "log" message to the chat: `"Error running agent, retrying in <N> seconds..."`.
|
|
67
|
+
- Ensure the message is appended and persisted so the user can see the progress.
|
|
68
|
+
- Ensure the final successful (or final failed) output replaces or follows these retry logs correctly in the UI.
|
|
69
|
+
|
|
70
|
+
### Verification
|
|
71
|
+
- Run E2E or manual tests to confirm the "retrying in..." message appears in the `messages.json` of the chat during a failure.
|
|
72
|
+
- Follow `./docs/CHECKS.md`.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Ticket 5: Comprehensive E2E Validation
|
|
77
|
+
**Status:** completed
|
|
78
|
+
|
|
79
|
+
### Task
|
|
80
|
+
Add E2E tests in `src/cli/e2e/messages.test.ts` to verify all fallback scenarios.
|
|
81
|
+
- **Scenario 1**: Base fails (exit code), fallback with env override succeeds.
|
|
82
|
+
- **Scenario 2**: Base succeeds but `getMessageContent` is empty, fallback with modified command succeeds.
|
|
83
|
+
- **Scenario 3**: Multiple retries for a single fallback (exponential backoff check).
|
|
84
|
+
- **Scenario 4**: All fallbacks exhausted, final failure reported.
|
|
85
|
+
|
|
86
|
+
### Verification
|
|
87
|
+
- Run `npm run test` and ensure all E2E tests pass.
|
|
88
|
+
- Final check of `./docs/CHECKS.md`.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Development Log - Discord Adapter
|
|
2
|
+
|
|
3
|
+
## 2026-03-03 - Tuesday
|
|
4
|
+
|
|
5
|
+
### Initial Session Start
|
|
6
|
+
- Identified `09_discord_adapter` as the active feature folder.
|
|
7
|
+
- Starting Step 1: Scaffold Discord Adapter.
|
|
8
|
+
|
|
9
|
+
### Step 1: Scaffold Discord Adapter
|
|
10
|
+
- **Goal:** Create basic structure and build setup for the Discord adapter.
|
|
11
|
+
- **Tasks:**
|
|
12
|
+
- Create `src/adapter-discord` directory. (Done)
|
|
13
|
+
- Create `src/adapter-discord/index.ts`. (Done)
|
|
14
|
+
- Update `tsdown.config.ts` to include the new entry point. (Done)
|
|
15
|
+
- Add `discord.js` to `package.json`. (Done)
|
|
16
|
+
- **Status:** Completed. Verified with `npm run build` and `node dist/adapter-discord/index.mjs`. All tests and checks passed.
|
|
17
|
+
|
|
18
|
+
### Step 2: Configuration & Security Implementation
|
|
19
|
+
- **Goal:** Define configuration schema and loading logic.
|
|
20
|
+
- **Tasks:**
|
|
21
|
+
- Create `src/adapter-discord/config.ts` with Zod schema. (Done)
|
|
22
|
+
- Implement configuration loading from `.clawmini/adapters/discord/config.json`. (Done)
|
|
23
|
+
- Add `isAuthorized(userId: string)` helper. (Done)
|
|
24
|
+
- Add unit tests in `src/adapter-discord/config.test.ts`. (Done)
|
|
25
|
+
- **Status:** Completed. Verified with unit tests and full automated checks.
|
|
26
|
+
|
|
27
|
+
### Step 3: TRPC Client Connection
|
|
28
|
+
- **Goal:** Implement TRPC client to connect to the daemon.
|
|
29
|
+
- **Tasks:**
|
|
30
|
+
- Create `src/adapter-discord/client.ts`. (Done)
|
|
31
|
+
- Implement a TRPC client that connects to the daemon via the Unix socket. (Done)
|
|
32
|
+
- Create unit tests in `src/adapter-discord/client.test.ts`. (Done)
|
|
33
|
+
- **Status:** Completed. Verified with unit tests. All checks and tests passed.
|
|
34
|
+
|
|
35
|
+
### Step 4: Discord to Daemon Forwarding
|
|
36
|
+
- **Goal:** Forward authorized Discord DM messages to the Clawmini daemon.
|
|
37
|
+
- **Tasks:**
|
|
38
|
+
- Initialize `discord.js` client in `src/adapter-discord/index.ts`. (Done)
|
|
39
|
+
- Implement `messageCreate` listener for DMs. (Done)
|
|
40
|
+
- Integrate with `readDiscordConfig` and `isAuthorized`. (Done)
|
|
41
|
+
- Implement TRPC `sendMessage` forwarding. (Done)
|
|
42
|
+
- Create comprehensive unit tests in `src/adapter-discord/index.test.ts`. (Done)
|
|
43
|
+
- **Status:** Completed. Verified with mocked `discord.js` tests. All checks and tests passed.
|
|
44
|
+
|
|
45
|
+
### Step 5: Daemon Message Observation Enhancement
|
|
46
|
+
- **Goal:** Update the daemon to support real-time message observation via TRPC.
|
|
47
|
+
- **Tasks:**
|
|
48
|
+
- Create `src/daemon/events.ts` with a global `EventEmitter` for the daemon.
|
|
49
|
+
- Create `src/daemon/chats.ts` as a daemon-specific wrapper for `shared/chats.ts` that emits `message-appended` events.
|
|
50
|
+
- Update `src/daemon/message.ts` and `src/daemon/router.ts` to use the new `chats.ts` wrapper.
|
|
51
|
+
- Add `getMessages` and `waitForMessages` (long-polling) endpoints to the TRPC router in `src/daemon/router.ts`.
|
|
52
|
+
- Update existing daemon tests (`message-extraction.test.ts`, `message-queue.test.ts`, `message-router.test.ts`) to mock the new `./chats.js` module.
|
|
53
|
+
- Create comprehensive unit tests in `src/daemon/observation.test.ts`.
|
|
54
|
+
- **Status:** Completed. Verified with unit tests. All checks and tests passed.
|
|
55
|
+
|
|
56
|
+
### Step 6: Daemon to Discord Forwarding
|
|
57
|
+
- **Goal:** Forward messages from the Clawmini daemon back to the authorized Discord user.
|
|
58
|
+
- **Tasks:**
|
|
59
|
+
- Create `src/adapter-discord/forwarder.ts` with the observation loop logic.
|
|
60
|
+
- Implement long-polling using `waitForMessages` TRPC endpoint.
|
|
61
|
+
- Implement message chunking for Discord's 2000 character limit.
|
|
62
|
+
- Update `src/adapter-discord/index.ts` to start the forwarder when the client is ready.
|
|
63
|
+
- Create comprehensive unit tests in `src/adapter-discord/forwarder.test.ts`.
|
|
64
|
+
- **Status:** Completed. Verified with unit tests. All checks and tests passed.
|
|
65
|
+
|
|
66
|
+
### Step 7: State Management & Startup Sync
|
|
67
|
+
- **Goal:** Implement persistent state to track synced messages and ensure no messages are missed on startup.
|
|
68
|
+
- **Tasks:**
|
|
69
|
+
- Create `src/adapter-discord/state.ts` for `.clawmini/adapters/discord/state.json` management.
|
|
70
|
+
- Implement `lastSyncedMessageId` tracking and persistence.
|
|
71
|
+
- Update `src/adapter-discord/forwarder.ts` to load initial state and update it during the forwarding loop.
|
|
72
|
+
- Create unit tests for state management.
|
|
73
|
+
- **Status:** Completed. Verified with unit tests and full automated checks.
|
|
74
|
+
|
|
75
|
+
### Step 8: Debouncing & Robustness
|
|
76
|
+
- **Goal:** Improve adapter reliability with message aggregation and error handling.
|
|
77
|
+
- **Tasks:**
|
|
78
|
+
- Create `Debouncer` utility in `src/adapter-discord/utils.ts`.
|
|
79
|
+
- Use `Debouncer` in `src/adapter-discord/index.ts` to aggregate messages sent within 1 second.
|
|
80
|
+
- Implement exponential backoff for daemon connection retries in `src/adapter-discord/forwarder.ts`.
|
|
81
|
+
- Add/Update unit tests for debouncing and backoff logic.
|
|
82
|
+
- **Status:** Completed. Verified with unit tests and full automated checks.
|
|
83
|
+
|
|
84
|
+
### Step 9: Documentation
|
|
85
|
+
- **Goal:** Create setup documentation for the Discord adapter.
|
|
86
|
+
- **Tasks:**
|
|
87
|
+
- Create `./docs/guides/discord_adapter_setup.md` with instructions for bot creation, token retrieval, and configuration. (Done)
|
|
88
|
+
- **Status:** Completed. Documentation created and verified.
|
|
89
|
+
|
|
90
|
+
## Final Review
|
|
91
|
+
- All steps for the Discord adapter are completed.
|
|
92
|
+
- Unit and integration tests cover all core components (client, config, forwarder, state, utils, index).
|
|
93
|
+
- TRPC observation enhancement implemented in daemon to support real-time message forwarding.
|
|
94
|
+
- State management ensures no messages are missed during restarts.
|
|
95
|
+
- Setup documentation provided.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Research Notes for Discord Adapter
|
|
2
|
+
|
|
3
|
+
## Architecture
|
|
4
|
+
- The daemon handles running commands and stores messages in `.gemini/chats/<chat_id>/chat.jsonl`.
|
|
5
|
+
- The CLI (`src/cli/client.ts`) communicates with the daemon via TRPC over a Unix socket (`http://localhost` using a custom fetch with `socketPath`).
|
|
6
|
+
- The TRPC router (`src/daemon/router.ts`) exposes endpoints like `sendMessage` to trigger an agent run.
|
|
7
|
+
- There is currently no TRPC endpoint to *read* messages or *subscribe* to new messages, though `src/shared/chats.ts` provides `getMessages` and `listChats` to read from the filesystem directly.
|
|
8
|
+
- The adapter will be a new top-level entry point (e.g., `src/adapter-discord/`) or a CLI command (e.g. `clawmini-lite discord-adapter`). The prompt implies a standalone CLI (`its own src/adapter-discord/ CLI`).
|
|
9
|
+
|
|
10
|
+
## Requirements Extracted
|
|
11
|
+
- **Security:** Ensure ONLY one configured user can communicate with it. Messages from other users must be ignored or logged as an error.
|
|
12
|
+
- **Bi-directional forwarding:**
|
|
13
|
+
- Discord -> Daemon: Listen for messages from Discord (via discord.js or similar), verify user ID, send via TRPC `sendMessage` (or equivalent).
|
|
14
|
+
- Daemon -> Discord: Watch for new messages in the `chat.jsonl` file (or add a TRPC subscription), and send them to the Discord user via the bot.
|
|
15
|
+
- **Startup Sync:** Upon startup, check for any missed messages in both directions.
|
|
16
|
+
- **Debouncing:** Debounce incoming messages to prevent duplication.
|
|
17
|
+
- **Configuration:** Needs a Discord Bot Token, a single allowed Discord User ID, and potentially the Chat ID to sync with (or it could sync with a specific chat or the default chat).
|
|
18
|
+
- **Documentation:** Step-by-step setup instructions in `./docs/guides/discord_adapter_setup.md`.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# PRD: Discord Adapter for Clawmini
|
|
2
|
+
|
|
3
|
+
## Vision
|
|
4
|
+
To provide a seamless, secure, and optional way for users to interact with their Clawmini agents via Discord. This allows users to leverage Discord's mobile and desktop interfaces as a bridge to their local development workflows, while maintaining strict security through single-user authorization.
|
|
5
|
+
|
|
6
|
+
## Product/Market Background
|
|
7
|
+
Clawmini is a local-first agentic CLI tool. While the terminal and web interface are powerful, users often want to interact with their agents on the go or through familiar communication apps. Discord is a natural fit for developers, offering robust APIs, cross-platform support, and a structured environment (channels/threads) that maps well to chat-based agent interactions.
|
|
8
|
+
|
|
9
|
+
## Use Cases
|
|
10
|
+
- **Mobile Access:** A developer wants to check the status of a long-running task or trigger a quick agent action from their phone.
|
|
11
|
+
- **Unified Interface:** A user wants to keep their agent interactions alongside their other developer communications in Discord.
|
|
12
|
+
- **Asynchronous Interaction:** A user sends a message to an agent on Discord, goes offline, and checks the agent's detailed output later when they return to their workstation.
|
|
13
|
+
|
|
14
|
+
## Requirements
|
|
15
|
+
|
|
16
|
+
### 1. Discord Bot Adapter (CLI)
|
|
17
|
+
- A new standalone CLI component located in `src/adapter-discord/`.
|
|
18
|
+
- Communicates with the Clawmini daemon via TRPC over a Unix socket.
|
|
19
|
+
- Manages a Discord Bot connection using a bot token provided in configuration.
|
|
20
|
+
|
|
21
|
+
### 2. Security & Authorization
|
|
22
|
+
- **Single User Lock:** The adapter MUST be configured with a specific Discord User ID.
|
|
23
|
+
- **Strict Filtering:** The bot MUST ignore all messages (and log an error for unauthorized attempts) from any user other than the configured ID.
|
|
24
|
+
- **Local Config:** Bot tokens and User IDs are stored locally in `.clawmini/adapters/discord/config.json`.
|
|
25
|
+
|
|
26
|
+
### 3. Bi-directional Synchronization
|
|
27
|
+
- **Discord -> Daemon:**
|
|
28
|
+
- Listen for DMs from the authorized user.
|
|
29
|
+
- Forward messages to the Clawmini daemon using the `sendMessage` TRPC endpoint.
|
|
30
|
+
- Map the Discord DM channel to a specific Clawmini chat (1:1 mapping).
|
|
31
|
+
- **Daemon -> Discord:**
|
|
32
|
+
- The daemon will be updated to support a message subscription/observation mechanism.
|
|
33
|
+
- The adapter will subscribe to new messages from the daemon and forward them to the appropriate Discord channel.
|
|
34
|
+
- Support "replay" on startup: Check for messages in the daemon's history that haven't been synced to Discord yet.
|
|
35
|
+
|
|
36
|
+
### 4. Reliability & State Management
|
|
37
|
+
- **Sync State:** Store a local cursor (e.g., last synced message timestamp or ID) in `.clawmini/adapters/discord/state.json` to prevent duplicates and ensure no messages are missed during downtime.
|
|
38
|
+
- **Debouncing:** Implement debouncing for incoming messages to handle rapid-fire inputs or redundant events.
|
|
39
|
+
- **Startup Sync:** On launch, the adapter syncs any missed messages in both directions.
|
|
40
|
+
|
|
41
|
+
### 5. Daemon Enhancements
|
|
42
|
+
- Add a new TRPC endpoint or event-driven mechanism to the daemon to allow external adapters (and the `web` interface) to receive real-time message updates without polling the filesystem.
|
|
43
|
+
|
|
44
|
+
### 6. Documentation
|
|
45
|
+
- Provide a step-by-step setup guide in `./docs/guides/discord_adapter_setup.md` covering:
|
|
46
|
+
- Creating a Discord Application/Bot in the Developer Portal.
|
|
47
|
+
- Retrieving the Bot Token.
|
|
48
|
+
- Finding your Discord User ID.
|
|
49
|
+
- Configuring and running the adapter.
|
|
50
|
+
|
|
51
|
+
## Privacy & Security
|
|
52
|
+
- **No Data Exfiltration:** The adapter only forwards messages to the user's own Discord DM channel. No data is sent to third-party servers other than Discord's own infrastructure.
|
|
53
|
+
- **Token Safety:** Bot tokens must never be logged or shared.
|
|
54
|
+
- **Access Control:** The single-user lock is the primary defense against unauthorized agent access.
|
|
55
|
+
|
|
56
|
+
## Accessibility
|
|
57
|
+
- Leverages Discord's native accessibility features (screen readers, high contrast modes) for interacting with Clawmini.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Questions for Discord Adapter
|
|
2
|
+
|
|
3
|
+
1. **Adapter Scope:** Should the Discord adapter sync with only the `default` chat, or should the user be able to specify a `chatId` to sync with (or multiple)?
|
|
4
|
+
- **Answer:** There should always be a 1:1 mapping between discord channels/DMs and clawmini chats.
|
|
5
|
+
|
|
6
|
+
2. **Daemon Output Synchronization:** Since the daemon writes messages directly to `.gemini/chats/<chatId>/chat.jsonl`, should the adapter simply tail/watch this file to detect new messages to forward to Discord, or should we add a new TRPC endpoint for reading/subscribing to messages?
|
|
7
|
+
- **Answer:** Let's add support to the daemon; and the CLI's `web` command should likely use the same endpoint to receive messages. We can move its logic for observing the chat's jsonl file to the daemon.
|
|
8
|
+
|
|
9
|
+
3. **Persisting Sync State:** To know which messages were already forwarded upon startup, should the adapter store a local cursor (e.g. last read message ID or timestamp) in a file like `.gemini/discord-cursor.json`?
|
|
10
|
+
- **Answer:** Yes, let's let adapters store config + state in `.clawmini/adapters/discord/{config,state}.json`.
|
|
11
|
+
|
|
12
|
+
4. **Discord Bot vs User Token:** I assume we are using a standard Discord Bot application (requires a bot token) rather than a selfbot (user token), which requires the user to create a bot in the Discord Developer Portal and invite it to a server or DM it directly. Is this correct?
|
|
13
|
+
- **Answer:** Yes, standard Discord Bot.
|
|
14
|
+
|
|
15
|
+
5. **Direct Messages vs Channel:** Should the bot only respond to Direct Messages from the configured user, or also respond to messages in a specific channel where the configured user mentions the bot?
|
|
16
|
+
- **Answer:** Start with just DMs for now, but eventually support adding the bot to a server to respond in each channel. It must ignore any messages not from the configured user.
|