clawmini 0.0.3 → 0.0.5
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/README.md +19 -0
- package/dist/adapter-discord/index.d.mts.map +1 -1
- package/dist/adapter-discord/index.mjs +398 -193
- package/dist/adapter-discord/index.mjs.map +1 -1
- package/dist/adapter-google-chat/index.d.mts +5 -0
- package/dist/adapter-google-chat/index.d.mts.map +1 -0
- package/dist/adapter-google-chat/index.mjs +1077 -0
- package/dist/adapter-google-chat/index.mjs.map +1 -0
- package/dist/cli/index.mjs +107 -14
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/lite.mjs +175 -16
- package/dist/cli/lite.mjs.map +1 -1
- package/dist/cli/propose-policy.d.mts +1 -0
- package/dist/cli/propose-policy.mjs +7159 -0
- package/dist/cli/propose-policy.mjs.map +1 -0
- package/dist/daemon/index.d.mts.map +1 -1
- package/dist/daemon/index.mjs +1427 -513
- package/dist/daemon/index.mjs.map +1 -1
- package/dist/{lite-oSYSvaOr.mjs → lite-CBxOT1y5.mjs} +101 -24
- package/dist/lite-CBxOT1y5.mjs.map +1 -0
- package/dist/routing-D8rTxtaV.mjs +245 -0
- package/dist/routing-D8rTxtaV.mjs.map +1 -0
- package/dist/web/_app/immutable/assets/0.C-4eziNy.css +1 -0
- package/dist/web/_app/immutable/assets/4.Cc_xwLNl.css +1 -0
- package/dist/web/_app/immutable/chunks/B6YN0Nuq.js +1 -0
- package/dist/web/_app/immutable/chunks/{Dc-UOHw9.js → BmRlVmv6.js} +1 -1
- package/{web/.svelte-kit/output/client/_app/immutable/chunks/8YNcRyEk.js → dist/web/_app/immutable/chunks/C20lZMGz.js} +1 -1
- package/dist/web/_app/immutable/chunks/C9lbZ-kT.js +1 -0
- package/dist/web/_app/immutable/chunks/CK9JZLaG.js +2 -0
- package/dist/web/_app/immutable/chunks/CME08kGM.js +1 -0
- package/dist/web/_app/immutable/chunks/{BPy8HLo7.js → Ck-be5J2.js} +1 -1
- package/dist/web/_app/immutable/chunks/Ck3rYNON.js +1 -0
- package/dist/web/_app/immutable/chunks/DMtIqaiV.js +2 -0
- package/dist/web/_app/immutable/chunks/{B8yYFADm.js → DhD271EB.js} +1 -1
- package/dist/web/_app/immutable/chunks/{DcrmIfTj.js → DpuLqk8d.js} +1 -1
- package/dist/web/_app/immutable/chunks/{ZkLyk0mE.js → Drm9vgeP.js} +1 -1
- package/dist/web/_app/immutable/chunks/DsIToJCP.js +1 -0
- package/dist/web/_app/immutable/chunks/{CyNaE55B.js → Zeh-C-mx.js} +1 -1
- package/{web/.svelte-kit/output/client/_app/immutable/entry/app.DO5eYwVz.js → dist/web/_app/immutable/entry/app.BgB5VkRU.js} +2 -2
- package/dist/web/_app/immutable/entry/start.DuxJo6av.js +1 -0
- package/dist/web/_app/immutable/nodes/0.C9oFZP9h.js +1 -0
- package/dist/web/_app/immutable/nodes/1.BON2Wk6k.js +1 -0
- package/dist/web/_app/immutable/nodes/{2.CK3CLC0f.js → 2.BnwnD1Ki.js} +1 -1
- package/dist/web/_app/immutable/nodes/{3.ncP0xLO6.js → 3.CIs4tjjw.js} +1 -1
- package/dist/web/_app/immutable/nodes/4.DLarELN4.js +60 -0
- package/dist/web/_app/immutable/nodes/{5.BpJUN6QH.js → 5.CE_QKy_3.js} +1 -1
- package/dist/web/_app/version.json +1 -1
- package/dist/web/index.html +12 -12
- package/dist/{workspace-DjoNjhW0.mjs → workspace-BJmJBfKi.mjs} +103 -11
- package/dist/workspace-BJmJBfKi.mjs.map +1 -0
- package/docs/14_google_chat_adapter/development_log.md +40 -0
- package/docs/14_google_chat_adapter/notes.md +28 -0
- package/docs/14_google_chat_adapter/prd.md +35 -0
- package/docs/14_google_chat_adapter/questions.md +9 -0
- package/docs/14_google_chat_adapter/tickets.md +117 -0
- package/docs/15_sandbox_policies/tickets.md +33 -0
- package/docs/16_session_timeout/development_log.md +20 -0
- package/docs/16_session_timeout/notes.md +44 -0
- package/docs/16_session_timeout/prd.md +106 -0
- package/docs/16_session_timeout/questions.md +10 -0
- package/docs/16_session_timeout/tickets.md +64 -0
- package/docs/17_auto_approve_policy/development_log.md +29 -0
- package/docs/17_auto_approve_policy/notes.md +25 -0
- package/docs/17_auto_approve_policy/prd.md +34 -0
- package/docs/17_auto_approve_policy/questions.md +10 -0
- package/docs/17_auto_approve_policy/tickets.md +11 -0
- package/docs/18_clawmini_skills/development_log.md +36 -0
- package/docs/18_clawmini_skills/notes.md +8 -0
- package/docs/18_clawmini_skills/prd.md +45 -0
- package/docs/18_clawmini_skills/questions.md +10 -0
- package/docs/18_clawmini_skills/tickets.md +55 -0
- package/docs/19_subagents/development_log.md +69 -0
- package/docs/19_subagents/notes.md +18 -0
- package/docs/19_subagents/prd.md +156 -0
- package/docs/19_subagents/questions.md +13 -0
- package/docs/19_subagents/tickets.md +113 -0
- package/docs/20_chat_logs_cleanup/development_log.md +50 -0
- package/docs/20_chat_logs_cleanup/notes.md +43 -0
- package/docs/20_chat_logs_cleanup/prd.md +232 -0
- package/docs/20_chat_logs_cleanup/questions.md +2 -0
- package/docs/20_chat_logs_cleanup/tickets.md +98 -0
- package/docs/20_webui_markdown/development_log.md +36 -0
- package/docs/20_webui_markdown/notes.md +23 -0
- package/docs/20_webui_markdown/prd.md +49 -0
- package/docs/20_webui_markdown/questions.md +10 -0
- package/docs/20_webui_markdown/tickets.md +55 -0
- package/docs/21_adapter_filtering/development_log.md +29 -0
- package/docs/21_adapter_filtering/notes.md +25 -0
- package/docs/21_adapter_filtering/prd.md +44 -0
- package/docs/21_adapter_filtering/questions.md +12 -0
- package/docs/21_adapter_filtering/tickets.md +38 -0
- package/docs/21_built_in_routers/development_log.md +17 -0
- package/docs/21_built_in_routers/notes.md +27 -0
- package/docs/21_built_in_routers/prd.md +34 -0
- package/docs/21_built_in_routers/questions.md +4 -0
- package/docs/21_built_in_routers/tickets.md +25 -0
- package/docs/21_fancy_policies/development_log.md +38 -0
- package/docs/21_fancy_policies/notes.md +27 -0
- package/docs/21_fancy_policies/prd.md +58 -0
- package/docs/21_fancy_policies/questions.md +6 -0
- package/docs/21_fancy_policies/tickets.md +48 -0
- package/docs/22_adapter_multi_chat/development_log.md +76 -0
- package/docs/22_adapter_multi_chat/notes.md +42 -0
- package/docs/22_adapter_multi_chat/prd.md +76 -0
- package/docs/22_adapter_multi_chat/questions.md +16 -0
- package/docs/22_adapter_multi_chat/tickets.md +164 -0
- package/docs/23_custom_token_env/development_log.md +31 -0
- package/docs/23_custom_token_env/notes.md +16 -0
- package/docs/23_custom_token_env/prd.md +42 -0
- package/docs/23_custom_token_env/questions.md +8 -0
- package/docs/23_custom_token_env/tickets.md +54 -0
- package/docs/guides/discord_adapter_setup.md +15 -2
- package/docs/guides/google_chat_adapter_setup.md +145 -0
- package/napkin.md +5 -0
- package/package.json +7 -2
- package/src/adapter-discord/config.test.ts +27 -8
- package/src/adapter-discord/config.ts +6 -8
- package/src/adapter-discord/forwarder.test.ts +307 -114
- package/src/adapter-discord/forwarder.ts +260 -75
- package/src/adapter-discord/index.test.ts +278 -0
- package/src/adapter-discord/index.ts +160 -30
- package/src/adapter-discord/interactions.test.ts +96 -0
- package/src/adapter-discord/interactions.ts +156 -0
- package/src/adapter-discord/state.test.ts +9 -8
- package/src/adapter-discord/state.ts +51 -8
- package/src/adapter-google-chat/auth.test.ts +87 -0
- package/src/adapter-google-chat/auth.ts +132 -0
- package/src/adapter-google-chat/cards.ts +71 -0
- package/src/adapter-google-chat/client.test.ts +561 -0
- package/src/adapter-google-chat/client.ts +430 -0
- package/src/adapter-google-chat/config.test.ts +187 -0
- package/src/adapter-google-chat/config.ts +82 -0
- package/src/adapter-google-chat/cron.test.ts +143 -0
- package/src/adapter-google-chat/cron.ts +81 -0
- package/src/adapter-google-chat/forwarder.test.ts +537 -0
- package/src/adapter-google-chat/forwarder.ts +349 -0
- package/src/adapter-google-chat/index.test.ts +62 -0
- package/src/adapter-google-chat/index.ts +61 -0
- package/src/adapter-google-chat/state.test.ts +96 -0
- package/src/adapter-google-chat/state.ts +85 -0
- package/src/adapter-google-chat/subscriptions.ts +124 -0
- package/src/adapter-google-chat/upload.ts +88 -0
- package/src/adapter-google-chat/utils.test.ts +111 -0
- package/src/adapter-google-chat/utils.ts +133 -0
- package/src/cli/commands/init.ts +0 -7
- package/src/cli/commands/messages.ts +18 -3
- package/src/cli/commands/policies.ts +70 -0
- package/src/cli/commands/skills.ts +71 -0
- package/src/cli/commands/web-api/chats.ts +5 -1
- package/src/cli/e2e/basic.test.ts +1 -1
- package/src/cli/e2e/cron.test.ts +1 -1
- package/src/cli/e2e/daemon.test.ts +132 -4
- package/src/cli/e2e/export-lite-func.test.ts +54 -31
- package/src/cli/e2e/fallbacks.test.ts +8 -6
- package/src/cli/e2e/init.test.ts +7 -0
- package/src/cli/e2e/messages.test.ts +90 -55
- package/src/cli/e2e/propose-policy.test.ts +203 -0
- package/src/cli/e2e/requests.test.ts +15 -0
- package/src/cli/e2e/session-timeout.test.ts +192 -0
- package/src/cli/e2e/skills.test.ts +55 -0
- package/src/cli/e2e/slash-new.test.ts +93 -0
- package/src/cli/e2e/subagents.test.ts +106 -0
- package/src/cli/index.ts +4 -0
- package/src/cli/lite.ts +51 -11
- package/src/cli/propose-policy.ts +91 -0
- package/src/cli/subagent-commands.ts +215 -0
- package/src/daemon/agent/agent-context.ts +89 -0
- package/src/daemon/agent/agent-extractors.ts +68 -0
- package/src/daemon/agent/agent-runner.ts +153 -0
- package/src/daemon/agent/agent-session.ts +261 -0
- package/src/daemon/agent/chat-logger.test.ts +158 -0
- package/src/daemon/agent/chat-logger.ts +188 -0
- package/src/daemon/agent/task-scheduler.test.ts +202 -0
- package/src/daemon/agent/task-scheduler.ts +276 -0
- package/src/daemon/agent/types.ts +84 -0
- package/src/daemon/agent/utils.ts +7 -0
- package/src/daemon/api/agent-router.ts +166 -18
- package/src/daemon/api/index.test.ts +50 -18
- package/src/daemon/api/policy-request.test.ts +39 -2
- package/src/daemon/api/subagent-router.test.ts +108 -0
- package/src/daemon/api/subagent-router.ts +296 -0
- package/src/daemon/api/subagent-utils.test.ts +56 -0
- package/src/daemon/api/subagent-utils.ts +130 -0
- package/src/daemon/api/user-router.ts +30 -13
- package/src/daemon/auth.ts +1 -0
- package/src/daemon/chats.ts +6 -0
- package/src/daemon/cron.test.ts +66 -1
- package/src/daemon/cron.ts +35 -8
- package/src/daemon/index.ts +23 -0
- package/src/daemon/message-agent.test.ts +11 -25
- package/src/daemon/message-extraction.test.ts +10 -27
- package/src/daemon/message-fallbacks.test.ts +13 -35
- package/src/daemon/message-interruption.test.ts +70 -53
- package/src/daemon/message-jobs.test.ts +138 -0
- package/src/daemon/message-queue.test.ts +30 -43
- package/src/daemon/message-router.test.ts +12 -11
- package/src/daemon/message-session.test.ts +41 -28
- package/src/daemon/message-typing.test.ts +19 -6
- package/src/daemon/message.ts +103 -515
- package/src/daemon/policy-request-service.ts +8 -3
- package/src/daemon/policy-utils.ts +19 -1
- package/src/daemon/queue.ts +16 -0
- package/src/daemon/request-store.test.ts +4 -0
- package/src/daemon/routers/session-timeout.test.ts +122 -0
- package/src/daemon/routers/session-timeout.ts +71 -0
- package/src/daemon/routers/slash-new.ts +3 -1
- package/src/daemon/routers/slash-policies.test.ts +26 -13
- package/src/daemon/routers/slash-policies.ts +39 -29
- package/src/daemon/routers/types.ts +8 -0
- package/src/daemon/routers.ts +64 -2
- package/src/daemon/utils/spawn.ts +6 -8
- package/src/shared/adapters/commands.test.ts +155 -0
- package/src/shared/adapters/commands.ts +125 -0
- package/src/shared/adapters/filtering.test.ts +111 -0
- package/src/shared/adapters/filtering.ts +57 -0
- package/src/shared/adapters/routing.test.ts +144 -0
- package/src/shared/adapters/routing.ts +109 -0
- package/src/shared/agent-utils.ts +10 -0
- package/src/shared/chats.test.ts +145 -3
- package/src/shared/chats.ts +215 -18
- package/src/shared/config.ts +67 -15
- package/src/shared/lite.ts +22 -18
- package/src/shared/policies.ts +7 -0
- package/src/shared/workspace.test.ts +45 -1
- package/src/shared/workspace.ts +119 -6
- package/templates/debug/settings.json +5 -2
- package/templates/environments/cladding/env.json +2 -2
- package/templates/gemini/.gemini/hooks/check-subagents.mjs +23 -0
- package/templates/gemini/.gemini/hooks/clawmini-logging.sh +17 -0
- package/templates/gemini/.gemini/hooks/insert-pending.sh +9 -0
- package/templates/gemini/.gemini/settings.json +50 -0
- package/templates/gemini/settings.json +22 -8
- package/templates/gemini-claw/.gemini/base-system.md +100 -0
- package/templates/gemini-claw/.gemini/hooks/check-subagents.mjs +23 -0
- package/templates/gemini-claw/.gemini/hooks/clawmini-logging.sh +1 -1
- package/templates/gemini-claw/.gemini/settings.json +13 -0
- package/templates/gemini-claw/.gemini/subagent-system.md +7 -0
- package/templates/gemini-claw/.gemini/system.md +3 -99
- package/templates/gemini-claw/settings.json +27 -22
- package/templates/skills/clawmini-requests/SKILL.md +92 -0
- package/templates/skills/clawmini-subagents/SKILL.md +79 -0
- package/templates/skills/skill-creator/SKILL.md +60 -0
- package/tsdown.config.ts +10 -1
- package/web/.svelte-kit/generated/server/internal.js +2 -1
- package/web/.svelte-kit/non-ambient.d.ts +2 -0
- package/web/.svelte-kit/output/client/.vite/manifest.json +141 -138
- package/web/.svelte-kit/output/client/_app/immutable/assets/0.C-4eziNy.css +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/assets/4.Cc_xwLNl.css +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/B6YN0Nuq.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/{Dc-UOHw9.js → BmRlVmv6.js} +1 -1
- package/{dist/web/_app/immutable/chunks/8YNcRyEk.js → web/.svelte-kit/output/client/_app/immutable/chunks/C20lZMGz.js} +1 -1
- package/web/.svelte-kit/output/client/_app/immutable/chunks/C9lbZ-kT.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/CK9JZLaG.js +2 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/CME08kGM.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/{BPy8HLo7.js → Ck-be5J2.js} +1 -1
- package/web/.svelte-kit/output/client/_app/immutable/chunks/Ck3rYNON.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/DMtIqaiV.js +2 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/{B8yYFADm.js → DhD271EB.js} +1 -1
- package/web/.svelte-kit/output/client/_app/immutable/chunks/{DcrmIfTj.js → DpuLqk8d.js} +1 -1
- package/web/.svelte-kit/output/client/_app/immutable/chunks/{ZkLyk0mE.js → Drm9vgeP.js} +1 -1
- package/web/.svelte-kit/output/client/_app/immutable/chunks/DsIToJCP.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/chunks/{CyNaE55B.js → Zeh-C-mx.js} +1 -1
- package/{dist/web/_app/immutable/entry/app.DO5eYwVz.js → web/.svelte-kit/output/client/_app/immutable/entry/app.BgB5VkRU.js} +2 -2
- package/web/.svelte-kit/output/client/_app/immutable/entry/start.DuxJo6av.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/nodes/0.C9oFZP9h.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/nodes/1.BON2Wk6k.js +1 -0
- package/web/.svelte-kit/output/client/_app/immutable/nodes/{2.CK3CLC0f.js → 2.BnwnD1Ki.js} +1 -1
- package/web/.svelte-kit/output/client/_app/immutable/nodes/{3.ncP0xLO6.js → 3.CIs4tjjw.js} +1 -1
- package/web/.svelte-kit/output/client/_app/immutable/nodes/4.DLarELN4.js +60 -0
- package/web/.svelte-kit/output/client/_app/immutable/nodes/{5.BpJUN6QH.js → 5.CE_QKy_3.js} +1 -1
- package/web/.svelte-kit/output/client/_app/version.json +1 -1
- package/web/.svelte-kit/output/server/.vite/manifest.json +12 -3
- package/web/.svelte-kit/output/server/_app/immutable/assets/_layout.C-4eziNy.css +1 -0
- package/web/.svelte-kit/output/server/_app/immutable/assets/_page.Cc_xwLNl.css +1 -0
- package/web/.svelte-kit/output/server/chunks/app-state.svelte.js +5 -0
- package/web/.svelte-kit/output/server/chunks/bot.js +4 -4
- package/web/.svelte-kit/output/server/chunks/client.js +2 -1
- package/web/.svelte-kit/output/server/chunks/exports.js +0 -1
- package/web/.svelte-kit/output/server/chunks/internal.js +2 -1
- package/web/.svelte-kit/output/server/chunks/root.js +482 -392
- package/web/.svelte-kit/output/server/entries/pages/_layout.svelte.js +57 -7
- package/web/.svelte-kit/output/server/entries/pages/chats/_id_/_page.svelte.js +234 -9
- package/web/.svelte-kit/output/server/index.js +82 -10
- package/web/.svelte-kit/output/server/manifest-full.js +1 -1
- package/web/.svelte-kit/output/server/manifest.js +1 -1
- package/web/.svelte-kit/output/server/nodes/0.js +2 -2
- package/web/.svelte-kit/output/server/nodes/1.js +1 -1
- package/web/.svelte-kit/output/server/nodes/2.js +1 -1
- package/web/.svelte-kit/output/server/nodes/3.js +1 -1
- package/web/.svelte-kit/output/server/nodes/4.js +2 -2
- package/web/.svelte-kit/output/server/nodes/5.js +1 -1
- package/web/.svelte-kit/types/src/routes/$types.d.ts +1 -2
- package/web/.svelte-kit/types/src/routes/agents/$types.d.ts +1 -2
- package/web/.svelte-kit/types/src/routes/chats/[id]/$types.d.ts +1 -2
- package/web/.svelte-kit/types/src/routes/chats/[id]/settings/$types.d.ts +1 -2
- package/web/package.json +8 -0
- package/web/src/lib/app-state.svelte.ts +5 -1
- package/web/src/lib/components/app/markdown-renderer.svelte +56 -0
- package/web/src/lib/components/app/markdown-renderer.svelte.spec.ts +44 -0
- package/web/src/lib/components/app/message-content.svelte +16 -0
- package/web/src/lib/types.ts +67 -3
- package/web/src/routes/+layout.svelte +31 -1
- package/web/src/routes/chats/[id]/+page.svelte +167 -18
- package/web/src/routes/chats/[id]/page.svelte.spec.ts +58 -7
- package/dist/lite-oSYSvaOr.mjs.map +0 -1
- package/dist/web/_app/immutable/assets/0.GI4C4dpV.css +0 -1
- package/dist/web/_app/immutable/chunks/B5abRDXp.js +0 -1
- package/dist/web/_app/immutable/chunks/Bi0jeV7Q.js +0 -1
- package/dist/web/_app/immutable/chunks/BmUXQ3wy.js +0 -2
- package/dist/web/_app/immutable/chunks/C3k55nDF.js +0 -1
- package/dist/web/_app/immutable/chunks/CpaGRn9L.js +0 -1
- package/dist/web/_app/immutable/chunks/DG5RZBw-.js +0 -2
- package/dist/web/_app/immutable/chunks/DQoygso7.js +0 -1
- package/dist/web/_app/immutable/entry/start.D48mVn1m.js +0 -1
- package/dist/web/_app/immutable/nodes/0.B-0CcADM.js +0 -1
- package/dist/web/_app/immutable/nodes/1.FixKgvRO.js +0 -1
- package/dist/web/_app/immutable/nodes/4.CQYJEgv8.js +0 -1
- package/dist/workspace-DjoNjhW0.mjs.map +0 -1
- package/src/daemon/message-verbosity.test.ts +0 -127
- package/web/.svelte-kit/output/client/_app/immutable/assets/0.GI4C4dpV.css +0 -1
- package/web/.svelte-kit/output/client/_app/immutable/chunks/B5abRDXp.js +0 -1
- package/web/.svelte-kit/output/client/_app/immutable/chunks/Bi0jeV7Q.js +0 -1
- package/web/.svelte-kit/output/client/_app/immutable/chunks/BmUXQ3wy.js +0 -2
- package/web/.svelte-kit/output/client/_app/immutable/chunks/C3k55nDF.js +0 -1
- package/web/.svelte-kit/output/client/_app/immutable/chunks/CpaGRn9L.js +0 -1
- package/web/.svelte-kit/output/client/_app/immutable/chunks/DG5RZBw-.js +0 -2
- package/web/.svelte-kit/output/client/_app/immutable/chunks/DQoygso7.js +0 -1
- package/web/.svelte-kit/output/client/_app/immutable/entry/start.D48mVn1m.js +0 -1
- package/web/.svelte-kit/output/client/_app/immutable/nodes/0.B-0CcADM.js +0 -1
- package/web/.svelte-kit/output/client/_app/immutable/nodes/1.FixKgvRO.js +0 -1
- package/web/.svelte-kit/output/client/_app/immutable/nodes/4.CQYJEgv8.js +0 -1
- package/web/.svelte-kit/output/server/_app/immutable/assets/_layout.GI4C4dpV.css +0 -1
- /package/templates/{gemini-claw/.gemini/skills → skills}/clawmini-jobs/SKILL.md +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["fsPromises","fsPromises","fs"],"sources":["../../src/adapter-discord/config.ts","../../src/shared/event-source.ts","../../src/adapter-discord/client.ts","../../src/adapter-discord/state.ts","../../src/adapter-discord/forwarder.ts","../../src/adapter-discord/index.ts"],"sourcesContent":["import fsPromises from 'node:fs/promises';\nimport path from 'node:path';\nimport { z } from 'zod';\nimport { getClawminiDir } from '../shared/workspace.js';\nimport fs from 'node:fs';\n\nexport const DiscordConfigSchema = z.looseObject({\n botToken: z.string().min(1, 'Discord Bot Token is required.'),\n authorizedUserId: z.string().min(1, 'Authorized Discord User ID is required.'),\n chatId: z.string().default('default'),\n maxAttachmentSizeMB: z.number().default(25).optional(),\n});\n\nexport type DiscordConfig = z.infer<typeof DiscordConfigSchema>;\n\nexport function getDiscordConfigPath(startDir = process.cwd()): string {\n return path.join(getClawminiDir(startDir), 'adapters', 'discord', 'config.json');\n}\n\nexport async function readDiscordConfig(startDir = process.cwd()): Promise<DiscordConfig | null> {\n const configPath = getDiscordConfigPath(startDir);\n try {\n const data = await fsPromises.readFile(configPath, 'utf-8');\n const parsed = JSON.parse(data);\n const result = DiscordConfigSchema.safeParse(parsed);\n if (!result.success) {\n console.error('Invalid Discord configuration:', result.error.format());\n return null;\n }\n return result.data;\n } catch {\n // Return null if file doesn't exist or is invalid JSON\n return null;\n }\n}\n\nexport async function initDiscordConfig(startDir = process.cwd()): Promise<void> {\n const configPath = getDiscordConfigPath(startDir);\n const configDir = path.dirname(configPath);\n\n await fsPromises.mkdir(configDir, { recursive: true });\n\n if (fs.existsSync(configPath)) {\n console.log(`Config file already exists at ${configPath}`);\n return;\n }\n\n const templateConfig = {\n botToken: 'YOUR_DISCORD_BOT_TOKEN',\n authorizedUserId: 'YOUR_DISCORD_USER_ID',\n chatId: 'default',\n };\n\n await fsPromises.writeFile(configPath, JSON.stringify(templateConfig, null, 2), 'utf-8');\n console.log(`Created template configuration file at ${configPath}`);\n console.log('Please update it with your actual Discord Bot Token and User ID.');\n}\n\nexport function isAuthorized(userId: string, authorizedUserId: string): boolean {\n return userId === authorizedUserId;\n}\n","import http from 'node:http';\n\nexport function createUnixSocketEventSource(socketPath: string) {\n return class UnixSocketEventSource {\n public readyState: number = 0; // CONNECTING\n public readonly CONNECTING = 0;\n public readonly OPEN = 1;\n public readonly CLOSED = 2;\n\n req: http.ClientRequest | null = null;\n listeners: Record<string, ((event: Record<string, unknown>) => void)[]> = {};\n\n constructor(url: string, init?: Record<string, unknown>) {\n const parsedUrl = new URL(url);\n\n const options: http.RequestOptions = {\n socketPath,\n path: parsedUrl.pathname + parsedUrl.search,\n method: 'GET',\n headers: {\n Accept: 'text/event-stream',\n 'Cache-Control': 'no-cache',\n ...(init?.headers as Record<string, string> | undefined),\n },\n };\n\n this.req = http.request(options, (res) => {\n if (res.statusCode === 200) {\n this.readyState = this.OPEN;\n this.dispatchEvent({ type: 'open' });\n } else {\n this.readyState = this.CLOSED;\n this.dispatchEvent({\n type: 'error',\n message: `Unexpected status code: ${res.statusCode}`,\n });\n return;\n }\n\n let buffer = '';\n res.on('data', (chunk) => {\n buffer += chunk.toString('utf-8');\n const lines = buffer.split(/\\r?\\n\\r?\\n/);\n buffer = lines.pop() || '';\n\n for (const block of lines) {\n this.parseBlock(block);\n }\n });\n\n res.on('end', () => {\n if (buffer) this.parseBlock(buffer);\n this.readyState = this.CLOSED;\n this.dispatchEvent({ type: 'close' });\n });\n });\n\n this.req.on('error', (err) => {\n this.readyState = this.CLOSED;\n this.dispatchEvent({ type: 'error', error: err });\n });\n\n this.req.end();\n }\n\n parseBlock(block: string) {\n if (!block.trim()) return;\n\n const lines = block.split(/\\r?\\n/);\n let eventType = 'message';\n let data = '';\n let id = '';\n\n for (const line of lines) {\n if (line.startsWith('event: ')) {\n eventType = line.slice(7).trim();\n } else if (line.startsWith('data: ')) {\n data += (data ? '\\n' : '') + line.slice(6);\n } else if (line.startsWith('id: ')) {\n id = line.slice(4).trim();\n }\n }\n\n if (data) {\n this.dispatchEvent({\n type: eventType,\n data,\n lastEventId: id,\n });\n }\n }\n\n public addEventListener(type: string, listener: (event: Record<string, unknown>) => void) {\n if (!this.listeners[type]) {\n this.listeners[type] = [];\n }\n this.listeners[type].push(listener);\n }\n\n public removeEventListener(type: string, listener: (event: Record<string, unknown>) => void) {\n if (!this.listeners[type]) return;\n this.listeners[type] = this.listeners[type].filter((l) => l !== listener);\n }\n\n dispatchEvent(event: Record<string, unknown>) {\n const type = event.type as string;\n if (this.listeners[type]) {\n for (const listener of this.listeners[type]) {\n listener(event);\n }\n }\n }\n\n public close() {\n this.readyState = this.CLOSED;\n if (this.req) {\n this.req.destroy();\n }\n }\n };\n}\n","import { createTRPCClient, httpLink, splitLink, httpSubscriptionLink } from '@trpc/client';\nimport type { UserRouter as AppRouter } from '../daemon/api/index.js';\nimport { getSocketPath } from '../shared/workspace.js';\nimport { createUnixSocketFetch } from '../shared/fetch.js';\nimport { createUnixSocketEventSource } from '../shared/event-source.js';\nimport fs from 'node:fs';\n\n/**\n * Creates a TRPC client that connects to the Clawmini daemon via a Unix socket.\n *\n * @param options - Configuration options for the client.\n * @returns A TRPC client instance for the AppRouter.\n */\nexport function getTRPCClient(options: { socketPath?: string } = {}) {\n const socketPath = options.socketPath ?? getSocketPath();\n\n if (!fs.existsSync(socketPath)) {\n throw new Error(`Daemon not running. Socket not found at ${socketPath}`);\n }\n\n const customFetch = createUnixSocketFetch(socketPath);\n const CustomEventSource = createUnixSocketEventSource(socketPath);\n\n return createTRPCClient<AppRouter>({\n links: [\n splitLink({\n condition(op) {\n return op.type === 'subscription';\n },\n true: httpSubscriptionLink({\n url: 'http://localhost',\n EventSource: CustomEventSource,\n }),\n false: httpLink({\n url: 'http://localhost',\n fetch: customFetch,\n }),\n }),\n ],\n });\n}\n","import fsPromises from 'node:fs/promises';\nimport path from 'node:path';\nimport { z } from 'zod';\nimport { getClawminiDir } from '../shared/workspace.js';\n\nexport const DiscordStateSchema = z.object({\n lastSyncedMessageId: z.string().optional(),\n});\n\nexport type DiscordState = z.infer<typeof DiscordStateSchema>;\n\nexport function getDiscordStatePath(startDir = process.cwd()): string {\n return path.join(getClawminiDir(startDir), 'adapters', 'discord', 'state.json');\n}\n\nexport async function readDiscordState(startDir = process.cwd()): Promise<DiscordState> {\n const statePath = getDiscordStatePath(startDir);\n try {\n const data = await fsPromises.readFile(statePath, 'utf-8');\n const parsed = JSON.parse(data);\n const result = DiscordStateSchema.safeParse(parsed);\n if (!result.success) {\n return { lastSyncedMessageId: undefined };\n }\n return result.data;\n } catch {\n // Return default state if file doesn't exist or is invalid JSON\n return { lastSyncedMessageId: undefined };\n }\n}\n\nexport async function writeDiscordState(\n state: DiscordState,\n startDir = process.cwd()\n): Promise<void> {\n const statePath = getDiscordStatePath(startDir);\n const dir = path.dirname(statePath);\n try {\n await fsPromises.mkdir(dir, { recursive: true });\n await fsPromises.writeFile(statePath, JSON.stringify(state, null, 2), 'utf-8');\n } catch (err) {\n console.error(`Failed to write Discord state to ${statePath}:`, err);\n }\n}\n","import type { Client, MessageCreateOptions } from 'discord.js';\nimport path from 'node:path';\nimport type { getTRPCClient } from './client.js';\nimport { readDiscordState, writeDiscordState } from './state.js';\nimport type { ChatMessage, CommandLogMessage } from '../shared/chats.js';\nimport { getWorkspaceRoot } from '../shared/workspace.js';\n\nexport async function startDaemonToDiscordForwarder(\n client: Client,\n trpc: ReturnType<typeof getTRPCClient>,\n discordUserId: string,\n chatId: string = 'default',\n signal?: AbortSignal\n) {\n const state = await readDiscordState();\n let lastMessageId = state.lastSyncedMessageId;\n\n // 1. If we don't have a lastMessageId, get the most recent one from the daemon\n // to avoid sending the entire chat history on first run.\n if (!lastMessageId) {\n try {\n const messages = await trpc.getMessages.query({ chatId, limit: 1 });\n if (Array.isArray(messages) && messages.length > 0) {\n const lastMsg = messages[messages.length - 1];\n if (lastMsg) {\n lastMessageId = lastMsg.id;\n await writeDiscordState({ lastSyncedMessageId: lastMessageId });\n }\n }\n } catch (error) {\n if (signal?.aborted) return;\n console.error('Failed to fetch initial messages from daemon:', error);\n }\n }\n\n console.log(\n `Starting daemon-to-discord forwarder for chat ${chatId}, lastMessageId: ${lastMessageId}`\n );\n\n let retryDelay = 1000;\n const maxRetryDelay = 30000;\n\n // 2. Start the observation loop using tRPC subscription\n return new Promise<void>((resolve) => {\n let subscription: { unsubscribe: () => void } | null = null;\n let messageQueue = Promise.resolve();\n\n const connect = () => {\n if (signal?.aborted) {\n resolve();\n return;\n }\n\n subscription = trpc.waitForMessages.subscribe(\n { chatId, lastMessageId },\n {\n onData: (messages) => {\n retryDelay = 1000; // Reset retry delay on successful data\n\n if (!Array.isArray(messages) || messages.length === 0) {\n return;\n }\n\n // Queue processing to ensure sequential execution\n messageQueue = messageQueue.then(async () => {\n for (const rawMessage of messages) {\n if (signal?.aborted) break;\n\n const message = rawMessage as ChatMessage;\n\n // Only forward logs (agent responses, system messages)\n if (message.role === 'log') {\n const logMessage = message as CommandLogMessage;\n\n if (logMessage.level === 'verbose') {\n lastMessageId = logMessage.id;\n await writeDiscordState({ lastSyncedMessageId: lastMessageId }).catch(\n console.error\n );\n continue;\n }\n\n const hasContent = !!logMessage.content?.trim();\n const hasFiles = Array.isArray(logMessage.files) && logMessage.files.length > 0;\n\n // The daemon stores logMessage.files as paths relative to the WORKSPACE directory\n // (the directory containing .clawmini). We must resolve these against the current\n // workspace root so discord.js can successfully locate and read the files.\n let absoluteFiles: string[] = [];\n if (hasFiles) {\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n absoluteFiles = logMessage.files!.map((f) => path.resolve(workspaceRoot, f));\n }\n\n if (!hasContent && !hasFiles) {\n lastMessageId = logMessage.id;\n await writeDiscordState({ lastSyncedMessageId: lastMessageId }).catch(\n console.error\n );\n continue;\n }\n\n try {\n const user = await client.users.fetch(discordUserId);\n const dm = await user.createDM();\n\n // Discord has a 2000 character limit for messages.\n if (hasContent && logMessage.content.length > 2000) {\n const chunks = chunkString(logMessage.content, 2000);\n for (let i = 0; i < chunks.length; i++) {\n if (signal?.aborted) break;\n const chunkOptions: MessageCreateOptions = { content: chunks[i] as string };\n if (i === chunks.length - 1 && hasFiles) {\n chunkOptions.files = absoluteFiles;\n }\n await dm.send(chunkOptions);\n }\n } else {\n const options: MessageCreateOptions = {};\n if (hasContent) {\n options.content = logMessage.content;\n }\n if (hasFiles) {\n options.files = absoluteFiles;\n }\n await dm.send(options);\n }\n } catch (error) {\n console.error(\n `Failed to send message to Discord user ${discordUserId}:`,\n error\n );\n // We don't advance lastMessageId if sending failed\n break;\n }\n }\n\n lastMessageId = message.id;\n await writeDiscordState({ lastSyncedMessageId: lastMessageId }).catch(\n console.error\n );\n }\n });\n },\n onError: (error) => {\n console.error(\n `Error in daemon-to-discord forwarder subscription. Retrying in ${retryDelay}ms.`,\n error\n );\n subscription?.unsubscribe();\n subscription = null;\n\n if (signal?.aborted) {\n resolve();\n return;\n }\n\n setTimeout(() => {\n retryDelay = Math.min(retryDelay * 2, maxRetryDelay);\n connect();\n }, retryDelay);\n },\n onComplete: () => {\n subscription = null;\n if (!signal?.aborted) {\n setTimeout(() => connect(), retryDelay);\n } else {\n resolve();\n }\n },\n }\n );\n };\n\n let typingSubscription: { unsubscribe: () => void } | null = null;\n let typingRetryDelay = 1000;\n\n const connectTyping = () => {\n if (signal?.aborted) {\n return;\n }\n\n typingSubscription = trpc.waitForTyping.subscribe(\n { chatId },\n {\n onData: async (event) => {\n typingRetryDelay = 1000; // Reset retry delay on successful data\n if (!event) return;\n\n try {\n const user = await client.users.fetch(discordUserId);\n const dm = await user.createDM();\n await dm.sendTyping();\n } catch (error) {\n console.error(\n `Failed to send typing indicator to Discord user ${discordUserId}:`,\n error\n );\n }\n },\n onError: (error) => {\n console.error(\n `Error in daemon-to-discord typing forwarder subscription. Retrying in ${typingRetryDelay}ms.`,\n error\n );\n typingSubscription?.unsubscribe();\n typingSubscription = null;\n\n if (signal?.aborted) {\n return;\n }\n\n setTimeout(() => {\n typingRetryDelay = Math.min(typingRetryDelay * 2, maxRetryDelay);\n connectTyping();\n }, typingRetryDelay);\n },\n onComplete: () => {\n typingSubscription = null;\n if (!signal?.aborted) {\n setTimeout(() => connectTyping(), typingRetryDelay);\n }\n },\n }\n );\n };\n\n connect();\n connectTyping();\n\n signal?.addEventListener('abort', () => {\n subscription?.unsubscribe();\n typingSubscription?.unsubscribe();\n resolve();\n });\n });\n}\n\nfunction chunkString(str: string, size: number): string[] {\n const chunks: string[] = [];\n const chars = Array.from(str);\n for (let i = 0; i < chars.length; i += size) {\n chunks.push(chars.slice(i, i + size).join(''));\n }\n return chunks;\n}\n","#!/usr/bin/env node\n\nimport { Client, Events, GatewayIntentBits, Partials } from 'discord.js';\nimport { readDiscordConfig, isAuthorized, initDiscordConfig } from './config.js';\nimport { getTRPCClient } from './client.js';\nimport { startDaemonToDiscordForwarder } from './forwarder.js';\nimport { getClawminiDir } from '../shared/workspace.js';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\nexport async function main() {\n const args = process.argv.slice(2);\n\n if (args[0] === 'init') {\n await initDiscordConfig();\n return;\n }\n\n console.log('Discord Adapter starting...');\n\n const config = await readDiscordConfig();\n if (!config) {\n console.error(\n 'Failed to load Discord configuration. Please ensure .clawmini/adapters/discord/config.json exists and is valid.'\n );\n process.exit(1);\n }\n\n const trpc = getTRPCClient();\n\n const client = new Client({\n intents: [GatewayIntentBits.DirectMessages, GatewayIntentBits.MessageContent],\n partials: [Partials.Channel],\n });\n\n client.once(Events.ClientReady, (readyClient) => {\n console.log(`Ready! Logged in as ${readyClient.user.tag}`);\n\n // Start forwarding from daemon to Discord\n startDaemonToDiscordForwarder(readyClient, trpc, config.authorizedUserId, config.chatId).catch(\n (error) => {\n console.error('Error in daemon-to-discord forwarder:', error);\n }\n );\n });\n\n client.on(Events.MessageCreate, async (message) => {\n // Ignore messages from the bot itself\n if (message.author.id === client.user?.id) return;\n\n // Only handle DM messages\n if (message.guild) return;\n\n // Check if the user is authorized\n if (!isAuthorized(message.author.id, config.authorizedUserId)) {\n console.log(\n `Unauthorized message from ${message.author.tag} (${message.author.id}) ignored.`\n );\n return;\n }\n\n console.log(`Received message from ${message.author.tag}: ${message.content}`);\n\n const downloadedFiles: string[] = [];\n if (message.attachments.size > 0) {\n const tmpDir = path.join(getClawminiDir(process.cwd()), 'tmp', 'discord');\n await fs.mkdir(tmpDir, { recursive: true });\n const maxSizeMB = config.maxAttachmentSizeMB ?? 25;\n const maxSizeBytes = maxSizeMB * 1024 * 1024;\n\n for (const attachment of message.attachments.values()) {\n if (attachment.size > maxSizeBytes) {\n console.warn(\n `Attachment ${attachment.name} exceeds size limit (${maxSizeMB}MB). Ignoring.`\n );\n await message.reply(\n `Warning: Attachment ${attachment.name} exceeds the size limit of ${maxSizeMB}MB and was ignored.`\n );\n continue;\n }\n\n try {\n const res = await fetch(attachment.url);\n if (!res.ok) {\n console.error(`Failed to download attachment ${attachment.name}`);\n continue;\n }\n\n const uniqueName = `${Date.now()}-${attachment.name}`;\n const filePath = path.join(tmpDir, uniqueName);\n const arrayBuffer = await res.arrayBuffer();\n await fs.writeFile(filePath, Buffer.from(arrayBuffer));\n downloadedFiles.push(filePath);\n } catch (err) {\n console.error(`Error downloading attachment ${attachment.name}:`, err);\n }\n }\n }\n\n let finalContent = message.content;\n\n if (message.reference && message.reference.messageId) {\n try {\n const referencedMessage = await message.fetchReference();\n if (referencedMessage && referencedMessage.content) {\n const quotedContent = referencedMessage.content\n .split('\\n')\n .map((line) => `> ${line}`)\n .join('\\n');\n finalContent = `${quotedContent}\\n${finalContent}`;\n }\n } catch (err) {\n console.error('Failed to fetch referenced message:', err);\n }\n }\n\n console.log(`Forwarding message to daemon: ${finalContent}`);\n try {\n await trpc.sendMessage.mutate({\n type: 'send-message',\n client: 'cli',\n data: {\n message: finalContent,\n chatId: config.chatId,\n files: downloadedFiles.length > 0 ? downloadedFiles : undefined,\n adapter: 'discord',\n noWait: true,\n },\n });\n console.log('Message forwarded to daemon successfully.');\n } catch (error) {\n console.error('Failed to forward message to daemon:', error);\n }\n });\n\n try {\n await client.login(config.botToken);\n } catch (error) {\n console.error('Failed to login to Discord:', error);\n process.exit(1);\n }\n}\n\nimport { fileURLToPath } from 'node:url';\n\nconst isMainModule = (() => {\n try {\n if (typeof process === 'undefined' || !process.argv || process.argv.length < 2) return false;\n const argv1 = process.argv[1];\n if (!argv1) return false;\n const p1 = path.resolve(argv1);\n const p2 = path.resolve(fileURLToPath(import.meta.url));\n return p1 === p2;\n } catch {\n return false;\n }\n})();\n\nif (isMainModule) {\n main().catch((error) => {\n console.error('Unhandled error in Discord Adapter:', error);\n process.exit(1);\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["fsPromises","isAuthorized","fsPromises","isAuthorized","fs"],"sources":["../../src/adapter-discord/config.ts","../../src/adapter-discord/state.ts","../../src/adapter-discord/interactions.ts","../../src/adapter-discord/client.ts","../../src/adapter-discord/forwarder.ts","../../src/adapter-discord/index.ts"],"sourcesContent":["import fsPromises from 'node:fs/promises';\nimport path from 'node:path';\nimport { z } from 'zod';\nimport { getClawminiDir } from '../shared/workspace.js';\nimport fs from 'node:fs';\n\nexport const DiscordConfigSchema = z.looseObject({\n botToken: z.string().min(1, 'Discord Bot Token is required.'),\n authorizedUserId: z.string().min(1, 'Authorized Discord User ID is required.'),\n chatId: z.string().default('default'),\n maxAttachmentSizeMB: z.number().default(25),\n requireMention: z.boolean().default(false),\n});\n\nexport type DiscordConfig = z.infer<typeof DiscordConfigSchema>;\n\nexport function getDiscordConfigPath(startDir = process.cwd()): string {\n return path.join(getClawminiDir(startDir), 'adapters', 'discord', 'config.json');\n}\n\nexport async function readDiscordConfig(startDir = process.cwd()): Promise<DiscordConfig | null> {\n const configPath = getDiscordConfigPath(startDir);\n try {\n const data = await fsPromises.readFile(configPath, 'utf-8');\n const parsed = JSON.parse(data);\n return DiscordConfigSchema.parse(parsed);\n } catch (err: unknown) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n return null;\n }\n throw err;\n }\n}\n\nexport async function initDiscordConfig(startDir = process.cwd()): Promise<void> {\n const configPath = getDiscordConfigPath(startDir);\n const configDir = path.dirname(configPath);\n\n await fsPromises.mkdir(configDir, { recursive: true });\n\n if (fs.existsSync(configPath)) {\n console.log(`Config file already exists at ${configPath}`);\n return;\n }\n\n const templateConfig = {\n botToken: 'YOUR_DISCORD_BOT_TOKEN',\n authorizedUserId: 'YOUR_DISCORD_USER_ID',\n chatId: 'default',\n };\n\n await fsPromises.writeFile(configPath, JSON.stringify(templateConfig, null, 2), 'utf-8');\n console.log(`Created template configuration file at ${configPath}`);\n console.log('Please update it with your actual Discord Bot Token and User ID.');\n}\n\nexport function isAuthorized(userId: string, authorizedUserId: string): boolean {\n return userId === authorizedUserId;\n}\n","import fsPromises from 'node:fs/promises';\nimport path from 'node:path';\nimport { z } from 'zod';\nimport { getClawminiDir } from '../shared/workspace.js';\n\nexport const DiscordStateSchema = z.object({\n lastSyncedMessageIds: z.record(z.string(), z.string()).optional(),\n channelChatMap: z\n .record(\n z.string(),\n z.object({\n chatId: z.string().nullable().optional(),\n requireMention: z.boolean().optional(),\n })\n )\n .optional(),\n filters: z.record(z.string(), z.boolean()).optional(),\n});\n\nexport type DiscordState = z.infer<typeof DiscordStateSchema>;\n\nexport function getDiscordStatePath(startDir = process.cwd()): string {\n return path.join(getClawminiDir(startDir), 'adapters', 'discord', 'state.json');\n}\n\nexport async function readDiscordState(startDir = process.cwd()): Promise<DiscordState> {\n const statePath = getDiscordStatePath(startDir);\n try {\n const data = await fsPromises.readFile(statePath, 'utf-8');\n const parsed = JSON.parse(data);\n\n // Migrate legacy state\n if (parsed.lastSyncedMessageId && !parsed.lastSyncedMessageIds) {\n parsed.lastSyncedMessageIds = { default: parsed.lastSyncedMessageId };\n }\n if (parsed.channelChatMap) {\n for (const [key, value] of Object.entries(parsed.channelChatMap)) {\n if (typeof value === 'string') {\n parsed.channelChatMap[key] = { chatId: value };\n }\n }\n }\n\n return DiscordStateSchema.parse(parsed);\n } catch (err: unknown) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n return {};\n }\n throw err;\n }\n}\n\nexport async function writeDiscordState(\n state: DiscordState,\n startDir = process.cwd()\n): Promise<void> {\n const statePath = getDiscordStatePath(startDir);\n const dir = path.dirname(statePath);\n try {\n await fsPromises.mkdir(dir, { recursive: true });\n await fsPromises.writeFile(statePath, JSON.stringify(state, null, 2), 'utf-8');\n } catch (err) {\n console.error(`Failed to write Discord state to ${statePath}:`, err);\n }\n}\n\nlet stateUpdatePromise = Promise.resolve();\n\nexport function updateDiscordState(\n updates: Partial<DiscordState> | ((state: DiscordState) => Partial<DiscordState>),\n startDir = process.cwd()\n): Promise<DiscordState> {\n return new Promise((resolve, reject) => {\n stateUpdatePromise = stateUpdatePromise.then(async () => {\n try {\n const currentState = await readDiscordState(startDir);\n const resolvedUpdates = typeof updates === 'function' ? updates(currentState) : updates;\n const newState = { ...currentState, ...resolvedUpdates };\n await writeDiscordState(newState, startDir);\n resolve(newState);\n } catch (err) {\n console.error(`Failed to write Discord state:`, err);\n reject(err);\n }\n });\n });\n}\n","import {\n ActionRowBuilder,\n ModalBuilder,\n TextInputBuilder,\n TextInputStyle,\n type Interaction,\n} from 'discord.js';\nimport { readDiscordState } from './state.js';\nimport type { DiscordConfig } from './config.js';\n\nfunction isAuthorized(userId: string, authorizedUserId: string): boolean {\n return userId === authorizedUserId;\n}\n\nexport async function handleDiscordInteraction(\n interaction: Interaction,\n config: DiscordConfig,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n trpc: any\n) {\n if (!interaction.isButton() && !interaction.isModalSubmit()) return;\n\n if (!isAuthorized(interaction.user.id, config.authorizedUserId)) {\n if (interaction.isRepliable()) {\n await interaction.reply({\n content: 'You are not authorized to perform this action.',\n ephemeral: true,\n });\n }\n return;\n }\n\n if (interaction.isButton()) {\n if (\n interaction.customId.startsWith('approve_') ||\n interaction.customId.startsWith('approve|')\n ) {\n let policyId, explicitChatId;\n if (interaction.customId.startsWith('approve|')) {\n const parts = interaction.customId.split('|');\n policyId = parts[1];\n explicitChatId = parts[2] || undefined;\n } else {\n policyId = interaction.customId.replace('approve_', '');\n }\n\n await interaction.update({ components: [] });\n await interaction.followUp({ content: `Approving policy ${policyId}...`, ephemeral: true });\n try {\n const currentState = await readDiscordState();\n const targetChatId =\n explicitChatId ||\n (interaction.channelId\n ? currentState.channelChatMap?.[interaction.channelId]?.chatId || config.chatId\n : config.chatId);\n await trpc.sendMessage.mutate({\n type: 'send-message',\n client: 'cli',\n data: {\n message: `/approve ${policyId}`,\n chatId: targetChatId,\n adapter: 'discord',\n noWait: true,\n },\n });\n } catch (error) {\n console.error('Failed to send approve command to daemon:', error);\n await interaction.followUp({\n content: `Failed to approve policy ${policyId}.`,\n ephemeral: true,\n });\n }\n } else if (\n interaction.customId.startsWith('reject_') ||\n interaction.customId.startsWith('reject|')\n ) {\n let policyId, explicitChatId;\n if (interaction.customId.startsWith('reject|')) {\n const parts = interaction.customId.split('|');\n policyId = parts[1];\n explicitChatId = parts[2] || '';\n } else {\n policyId = interaction.customId.replace('reject_', '');\n explicitChatId = '';\n }\n\n const modal = new ModalBuilder()\n .setCustomId(`modal_reject|${policyId}|${explicitChatId}`)\n .setTitle('Reject Policy');\n\n const rationaleInput = new TextInputBuilder()\n .setCustomId('rationale')\n .setLabel('Rationale (optional)')\n .setStyle(TextInputStyle.Paragraph)\n .setRequired(false);\n\n const actionRow = new ActionRowBuilder<TextInputBuilder>().addComponents(rationaleInput);\n modal.addComponents(actionRow);\n\n await interaction.showModal(modal);\n }\n } else if (interaction.isModalSubmit()) {\n if (\n interaction.customId.startsWith('modal_reject_') ||\n interaction.customId.startsWith('modal_reject|')\n ) {\n let policyId, explicitChatId;\n if (interaction.customId.startsWith('modal_reject|')) {\n const parts = interaction.customId.split('|');\n policyId = parts[1];\n explicitChatId = parts[2] || undefined;\n } else {\n policyId = interaction.customId.replace('modal_reject_', '');\n }\n const rationale = interaction.fields.getTextInputValue('rationale');\n\n const command = rationale ? `/reject ${policyId} ${rationale}` : `/reject ${policyId}`;\n\n if (interaction.isFromMessage()) {\n await interaction.update({ components: [] });\n await interaction.followUp({\n content: `Rejecting policy ${policyId}...`,\n ephemeral: true,\n });\n } else {\n await interaction.reply({ content: `Rejecting policy ${policyId}...`, ephemeral: true });\n }\n\n try {\n const currentState = await readDiscordState();\n const targetChatId =\n explicitChatId ||\n (interaction.channelId\n ? currentState.channelChatMap?.[interaction.channelId]?.chatId || config.chatId\n : config.chatId);\n\n await trpc.sendMessage.mutate({\n type: 'send-message',\n client: 'cli',\n data: {\n message: command,\n chatId: targetChatId,\n adapter: 'discord',\n noWait: true,\n },\n });\n } catch (error) {\n console.error('Failed to send reject command to daemon:', error);\n await interaction.followUp({\n content: `Failed to reject policy ${policyId}.`,\n ephemeral: true,\n });\n }\n }\n }\n}\n","import { createTRPCClient, httpLink, splitLink, httpSubscriptionLink } from '@trpc/client';\nimport type { UserRouter as AppRouter } from '../daemon/api/index.js';\nimport { getSocketPath } from '../shared/workspace.js';\nimport { createUnixSocketFetch } from '../shared/fetch.js';\nimport { createUnixSocketEventSource } from '../shared/event-source.js';\nimport fs from 'node:fs';\n\n/**\n * Creates a TRPC client that connects to the Clawmini daemon via a Unix socket.\n *\n * @param options - Configuration options for the client.\n * @returns A TRPC client instance for the AppRouter.\n */\nexport function getTRPCClient(options: { socketPath?: string } = {}) {\n const socketPath = options.socketPath ?? getSocketPath();\n\n if (!fs.existsSync(socketPath)) {\n throw new Error(`Daemon not running. Socket not found at ${socketPath}`);\n }\n\n const customFetch = createUnixSocketFetch(socketPath);\n const CustomEventSource = createUnixSocketEventSource(socketPath);\n\n return createTRPCClient<AppRouter>({\n links: [\n splitLink({\n condition(op) {\n return op.type === 'subscription';\n },\n true: httpSubscriptionLink({\n url: 'http://localhost',\n EventSource: CustomEventSource,\n }),\n false: httpLink({\n url: 'http://localhost',\n fetch: customFetch,\n }),\n }),\n ],\n });\n}\n","/* eslint-disable max-lines */\nimport type {\n Client,\n MessageCreateOptions,\n TextChannel,\n DMChannel,\n NewsChannel,\n ThreadChannel,\n VoiceChannel,\n StageChannel,\n} from 'discord.js';\nimport { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, Colors } from 'discord.js';\nimport path from 'node:path';\nimport fs from 'node:fs';\nimport type { getTRPCClient } from './client.js';\nimport { readDiscordState, updateDiscordState, getDiscordStatePath } from './state.js';\nimport type { ChatMessage } from '../shared/chats.js';\nimport { getWorkspaceRoot } from '../shared/workspace.js';\nimport {\n shouldDisplayMessage,\n formatMessage,\n type FilteringConfig,\n} from '../shared/adapters/filtering.js';\n\nasync function resolveDiscordDestination(\n client: Client,\n discordUserId: string,\n chatId: string\n): Promise<TextChannel | DMChannel | NewsChannel | ThreadChannel | VoiceChannel | StageChannel> {\n const state = await readDiscordState();\n const channelChatMap = state.channelChatMap || {};\n\n let targetDiscordChannelId: string | undefined;\n for (const [channelId, mappedChatId] of Object.entries(channelChatMap)) {\n if (mappedChatId?.chatId === chatId) {\n targetDiscordChannelId = channelId;\n break;\n }\n }\n\n if (targetDiscordChannelId) {\n try {\n const channel = await client.channels.fetch(targetDiscordChannelId);\n if (channel && channel.isTextBased() && !channel.isDMBased()) {\n return channel as TextChannel | NewsChannel | ThreadChannel | VoiceChannel | StageChannel;\n }\n } catch (error) {\n console.warn(\n `Failed to fetch mapped channel ${targetDiscordChannelId} for chat ${chatId}, falling back to DM.`,\n error\n );\n }\n }\n\n const user = await client.users.fetch(discordUserId);\n return user.createDM();\n}\n\nexport async function startDaemonToDiscordForwarder(\n client: Client,\n trpc: ReturnType<typeof getTRPCClient>,\n discordUserId: string,\n options: {\n chatId?: string;\n signal?: AbortSignal;\n config?: FilteringConfig;\n } = {}\n) {\n const defaultChatId = options.chatId ?? 'default';\n const signal = options.signal;\n const config = options.config ?? {};\n\n const activeSubscriptions = new Map<string, { unsubscribe: () => void }>();\n const activeTypingSubscriptions = new Map<string, { unsubscribe: () => void }>();\n let currentLastSyncedMessageIds = (await readDiscordState()).lastSyncedMessageIds || {};\n\n const saveLastMessageId = async (chatId: string, id: string) => {\n currentLastSyncedMessageIds = { ...currentLastSyncedMessageIds, [chatId]: id };\n return updateDiscordState((state) => ({\n lastSyncedMessageIds: {\n ...state.lastSyncedMessageIds,\n ...currentLastSyncedMessageIds,\n },\n }));\n };\n\n const startSubscriptionForChat = async (chatId: string) => {\n if (activeSubscriptions.has(chatId)) return;\n if (signal?.aborted) return;\n\n let lastMessageId = currentLastSyncedMessageIds[chatId];\n\n if (!lastMessageId) {\n try {\n const messages = await trpc.getMessages.query({ chatId, limit: 1 });\n if (Array.isArray(messages) && messages.length > 0) {\n const lastMsg = messages[messages.length - 1];\n if (lastMsg) {\n await saveLastMessageId(chatId, lastMsg.id);\n lastMessageId = lastMsg.id;\n }\n }\n } catch (error) {\n if (signal?.aborted) return;\n console.error(`Failed to fetch initial messages from daemon for ${chatId}:`, error);\n }\n }\n\n console.log(\n `Starting daemon-to-discord forwarder for chat ${chatId}, lastMessageId: ${lastMessageId}`\n );\n\n let retryDelay = 1000;\n const maxRetryDelay = 30000;\n\n let subscription: { unsubscribe: () => void } | null = null;\n let messageQueue = Promise.resolve();\n\n const connect = () => {\n if (signal?.aborted || !activeSubscriptions.has(chatId)) {\n return;\n }\n\n subscription = trpc.waitForMessages.subscribe(\n { chatId, lastMessageId },\n {\n onData: (messages) => {\n retryDelay = 1000; // Reset retry delay on successful data\n\n if (!Array.isArray(messages) || messages.length === 0) {\n return;\n }\n\n // Queue processing to ensure sequential execution\n messageQueue = messageQueue.then(async () => {\n for (const rawMessage of messages) {\n if (signal?.aborted || !activeSubscriptions.has(chatId)) break;\n\n const message = rawMessage as ChatMessage;\n\n const isDisplayed = shouldDisplayMessage(message, config);\n\n if (isDisplayed) {\n const logMessage = message;\n const isPolicyRequest =\n logMessage.role === 'policy' && logMessage.status === 'pending';\n\n if (isPolicyRequest) {\n try {\n const dm = await resolveDiscordDestination(client, discordUserId, chatId);\n\n const embed = new EmbedBuilder()\n .setTitle('Action Required: Policy Request')\n .setDescription(\n logMessage.content || 'A pending policy request requires your attention.'\n )\n .setColor(Colors.Yellow);\n\n const policyId =\n ('requestId' in logMessage && logMessage.requestId) || logMessage.id;\n const row = new ActionRowBuilder<ButtonBuilder>().addComponents(\n new ButtonBuilder()\n .setCustomId(`approve|${policyId}|${chatId}`)\n .setLabel('Approve')\n .setStyle(ButtonStyle.Success),\n new ButtonBuilder()\n .setCustomId(`reject|${policyId}|${chatId}`)\n .setLabel('Reject')\n .setStyle(ButtonStyle.Danger)\n );\n\n const optionsMsg: MessageCreateOptions = {\n embeds: [embed],\n components: [row],\n };\n\n try {\n await dm.send(optionsMsg);\n } catch (richError) {\n console.warn(\n `Failed to send rich message to Discord user ${discordUserId}, falling back to plain text:`,\n richError\n );\n await dm.send({\n content: `Action Required: Policy Request\\n\\n${logMessage.content || 'A pending policy request requires your attention.'}\\n\\nApprove: \\`/approve ${policyId}\\`\\nReject: \\`/reject ${policyId} <optional_rationale>\\``,\n });\n }\n } catch (error) {\n console.error(\n `Failed to send message to Discord user ${discordUserId}:`,\n error\n );\n }\n\n await saveLastMessageId(chatId, logMessage.id).catch(console.error);\n lastMessageId = logMessage.id;\n continue;\n }\n\n if ('level' in logMessage && logMessage.level === 'verbose') {\n await saveLastMessageId(chatId, logMessage.id).catch(console.error);\n lastMessageId = logMessage.id;\n continue;\n }\n\n const hasContent = !!logMessage.content?.trim();\n const files = 'files' in logMessage ? (logMessage.files as string[]) : undefined;\n const hasFiles = Array.isArray(files) && files.length > 0;\n\n // The daemon stores logMessage.files as paths relative to the WORKSPACE directory\n // (the directory containing .clawmini). We must resolve these against the current\n // workspace root so discord.js can successfully locate and read the files.\n let absoluteFiles: string[] = [];\n if (hasFiles && files) {\n const workspaceRoot = getWorkspaceRoot(process.cwd());\n absoluteFiles = files.map((f) => path.resolve(workspaceRoot, f));\n }\n\n if (!hasContent && !hasFiles) {\n await saveLastMessageId(chatId, logMessage.id).catch(console.error);\n lastMessageId = logMessage.id;\n continue;\n }\n\n try {\n const dm = await resolveDiscordDestination(client, discordUserId, chatId);\n const formattedContent = formatMessage(message);\n\n if (formattedContent && formattedContent.length > 2000) {\n const chunks = chunkString(formattedContent, 2000);\n for (let i = 0; i < chunks.length; i++) {\n if (signal?.aborted || !activeSubscriptions.has(chatId)) break;\n const chunkOptions: MessageCreateOptions = { content: chunks[i] as string };\n if (i === chunks.length - 1 && hasFiles) {\n chunkOptions.files = absoluteFiles;\n }\n await dm.send(chunkOptions);\n }\n } else {\n const optionsMsg: MessageCreateOptions = {};\n if (formattedContent) {\n optionsMsg.content = formattedContent;\n }\n if (hasFiles) {\n optionsMsg.files = absoluteFiles;\n }\n await dm.send(optionsMsg);\n }\n } catch (error) {\n console.error(\n `Failed to send message to Discord user ${discordUserId}:`,\n error\n );\n break; // don't advance lastMessageId\n }\n }\n\n await saveLastMessageId(chatId, message.id).catch(console.error);\n lastMessageId = message.id;\n }\n });\n },\n onError: (error) => {\n console.error(\n `Error in daemon-to-discord forwarder subscription for ${chatId}. Retrying in ${retryDelay}ms.`,\n error\n );\n subscription?.unsubscribe();\n subscription = null;\n\n if (signal?.aborted || !activeSubscriptions.has(chatId)) {\n return;\n }\n\n setTimeout(() => {\n retryDelay = Math.min(retryDelay * 2, maxRetryDelay);\n connect();\n }, retryDelay);\n },\n onComplete: () => {\n subscription = null;\n if (!signal?.aborted && activeSubscriptions.has(chatId)) {\n setTimeout(() => connect(), retryDelay);\n }\n },\n }\n );\n };\n\n let typingSubscription: { unsubscribe: () => void } | null = null;\n let typingRetryDelay = 1000;\n\n const connectTyping = () => {\n if (signal?.aborted || !activeSubscriptions.has(chatId)) {\n return;\n }\n\n typingSubscription = trpc.waitForTyping.subscribe(\n { chatId },\n {\n onData: async (event) => {\n typingRetryDelay = 1000; // Reset retry delay on successful data\n if (!event) return;\n\n try {\n const dm = await resolveDiscordDestination(client, discordUserId, chatId);\n if (dm.sendTyping) {\n await dm.sendTyping();\n }\n } catch (error) {\n console.error(\n `Failed to send typing indicator to Discord user ${discordUserId}:`,\n error\n );\n }\n },\n onError: (error) => {\n console.error(\n `Error in daemon-to-discord typing forwarder subscription for ${chatId}. Retrying in ${typingRetryDelay}ms.`,\n error\n );\n typingSubscription?.unsubscribe();\n typingSubscription = null;\n\n if (signal?.aborted || !activeSubscriptions.has(chatId)) {\n return;\n }\n\n setTimeout(() => {\n typingRetryDelay = Math.min(typingRetryDelay * 2, maxRetryDelay);\n connectTyping();\n }, typingRetryDelay);\n },\n onComplete: () => {\n typingSubscription = null;\n if (!signal?.aborted && activeSubscriptions.has(chatId)) {\n setTimeout(() => connectTyping(), typingRetryDelay);\n }\n },\n }\n );\n };\n\n activeSubscriptions.set(chatId, {\n unsubscribe: () => subscription?.unsubscribe(),\n });\n activeTypingSubscriptions.set(chatId, {\n unsubscribe: () => typingSubscription?.unsubscribe(),\n });\n\n connect();\n connectTyping();\n };\n\n const syncSubscriptions = async () => {\n if (signal?.aborted) return;\n const state = await readDiscordState();\n\n // Update local copy of last message IDs\n if (state.lastSyncedMessageIds) {\n currentLastSyncedMessageIds = {\n ...currentLastSyncedMessageIds,\n ...state.lastSyncedMessageIds,\n };\n }\n\n const targetChatIds = new Set<string>();\n targetChatIds.add(defaultChatId);\n\n if (state.channelChatMap) {\n for (const mappedEntry of Object.values(state.channelChatMap)) {\n if (mappedEntry.chatId) {\n targetChatIds.add(mappedEntry.chatId);\n }\n }\n }\n\n // Start new subscriptions\n for (const targetChatId of targetChatIds) {\n if (!activeSubscriptions.has(targetChatId)) {\n startSubscriptionForChat(targetChatId);\n }\n }\n\n // Teardown old subscriptions\n for (const [activeChatId, sub] of activeSubscriptions.entries()) {\n if (!targetChatIds.has(activeChatId)) {\n sub.unsubscribe();\n activeSubscriptions.delete(activeChatId);\n activeTypingSubscriptions.get(activeChatId)?.unsubscribe();\n activeTypingSubscriptions.delete(activeChatId);\n }\n }\n };\n\n return new Promise<void>((resolve) => {\n syncSubscriptions().catch(console.error);\n\n const statePath = getDiscordStatePath();\n const stateDir = path.dirname(statePath);\n if (!fs.existsSync(stateDir)) {\n fs.mkdirSync(stateDir, { recursive: true });\n }\n let debounceTimer: NodeJS.Timeout | null = null;\n const watcher = fs.watch(stateDir, (eventType: string, filename: string | null) => {\n if (filename === path.basename(statePath)) {\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = setTimeout(() => {\n syncSubscriptions().catch(console.error);\n }, 200);\n }\n });\n\n signal?.addEventListener('abort', () => {\n if (debounceTimer) clearTimeout(debounceTimer);\n watcher.close();\n for (const sub of activeSubscriptions.values()) sub.unsubscribe();\n for (const sub of activeTypingSubscriptions.values()) sub.unsubscribe();\n resolve();\n });\n });\n}\n\nfunction chunkString(str: string, size: number): string[] {\n const chunks: string[] = [];\n const chars = Array.from(str);\n for (let i = 0; i < chars.length; i += size) {\n chunks.push(chars.slice(i, i + size).join(''));\n }\n return chunks;\n}\n","#!/usr/bin/env node\n\nimport { Client, Events, GatewayIntentBits, Partials } from 'discord.js';\nimport { readDiscordConfig, isAuthorized, initDiscordConfig } from './config.js';\nimport { readDiscordState, updateDiscordState } from './state.js';\nimport { handleDiscordInteraction } from './interactions.js';\nimport { getTRPCClient } from './client.js';\nimport { startDaemonToDiscordForwarder } from './forwarder.js';\nimport { getClawminiDir } from '../shared/workspace.js';\nimport { handleAdapterCommand, type CommandTrpcClient } from '../shared/adapters/commands.js';\nimport { formatMessage, type FilteringConfig } from '../shared/adapters/filtering.js';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { handleRoutingCommand, type RoutingTrpcClient } from '../shared/adapters/routing.js';\n\nexport async function main() {\n const args = process.argv.slice(2);\n\n if (args[0] === 'init') {\n await initDiscordConfig();\n return;\n }\n\n console.log('Discord Adapter starting...');\n\n const config = await readDiscordConfig();\n if (!config) {\n console.error(\n 'Failed to load Discord configuration. Please ensure .clawmini/adapters/discord/config.json exists and is valid.'\n );\n process.exit(1);\n }\n\n const trpc = getTRPCClient();\n\n const client = new Client({\n intents: [\n GatewayIntentBits.DirectMessages,\n GatewayIntentBits.MessageContent,\n GatewayIntentBits.Guilds,\n GatewayIntentBits.GuildMessages,\n ],\n partials: [Partials.Channel],\n });\n\n const state = await readDiscordState();\n const filteringConfig: FilteringConfig = { filters: state.filters };\n\n client.once(Events.ClientReady, (readyClient) => {\n console.log(`Ready! Logged in as ${readyClient.user.tag}`);\n\n // Start forwarding from daemon to Discord\n startDaemonToDiscordForwarder(readyClient, trpc, config.authorizedUserId, {\n chatId: config.chatId,\n config: filteringConfig,\n }).catch((error) => {\n console.error('Error in daemon-to-discord forwarder:', error);\n });\n });\n\n client.on(Events.MessageCreate, async (message) => {\n // Ignore messages from the bot itself\n if (message.author.id === client.user?.id) return;\n if (message.author.bot) return;\n\n const externalContextId = message.channelId;\n const currentState = await readDiscordState();\n const mappedChatId = currentState.channelChatMap?.[externalContextId]?.chatId;\n const isRoutingCommand =\n message.content.startsWith('/chat') || message.content.startsWith('/agent');\n\n // Enforce requireMention config for guild messages\n if (message.guild) {\n const channelConfig = currentState.channelChatMap?.[externalContextId];\n const requiresMention =\n channelConfig?.requireMention !== undefined\n ? channelConfig.requireMention\n : config.requireMention;\n\n if (requiresMention) {\n const isMentioned = message.mentions.has(client.user!.id);\n let isReplyToBot = false;\n\n if (message.reference && message.reference.messageId) {\n try {\n const referencedMessage = await message.channel.messages.fetch(\n message.reference.messageId\n );\n isReplyToBot = referencedMessage.author.id === client.user!.id;\n } catch (err) {\n console.error('Failed to fetch referenced message for mention check:', err);\n }\n }\n\n if (!isMentioned && !isReplyToBot) {\n return;\n }\n }\n }\n\n // Check if the user is authorized\n if (!isAuthorized(message.author.id, config.authorizedUserId)) {\n console.log(\n `Unauthorized message from ${message.author.tag} (${message.author.id}) ignored.`\n );\n return;\n }\n\n console.log(`Received message from ${message.author.tag}: ${message.content}`);\n\n if (isRoutingCommand) {\n const stringChatMap = Object.fromEntries(\n Object.entries(currentState.channelChatMap || {}).map(([k, v]) => [k, v.chatId || ''])\n );\n const routingResult = await handleRoutingCommand(\n message.content,\n externalContextId,\n stringChatMap,\n 'discord',\n trpc as unknown as RoutingTrpcClient\n );\n\n if (routingResult) {\n if (routingResult.type === 'mapped') {\n await updateDiscordState((latestState) => ({\n channelChatMap: {\n ...(latestState.channelChatMap || {}),\n [externalContextId]: {\n ...(latestState.channelChatMap?.[externalContextId] || {}),\n chatId: routingResult.newChatId,\n },\n },\n }));\n }\n await message.reply(routingResult.text);\n return;\n }\n }\n\n let targetChatId = mappedChatId;\n\n if (!targetChatId && !isRoutingCommand) {\n const isFirstEverMessage =\n !currentState.channelChatMap ||\n Object.values(currentState.channelChatMap).every((entry) => !entry.chatId);\n\n if (isFirstEverMessage) {\n targetChatId = config.chatId || 'default';\n console.log(\n `First contact detected. Automatically mapping channel ${externalContextId} to chat ${targetChatId}.`\n );\n await updateDiscordState((latestState) => ({\n channelChatMap: {\n ...(latestState.channelChatMap || {}),\n [externalContextId]: {\n ...(latestState.channelChatMap?.[externalContextId] || {}),\n chatId: targetChatId as string,\n },\n },\n }));\n } else {\n const isDirectMessage = !message.guild;\n const isMentioned = message.mentions.has(client.user!.id);\n const isSlashCommand = message.content.startsWith('/');\n if (isDirectMessage || isMentioned || isSlashCommand) {\n console.log(`Unmapped channel ${externalContextId}, sending first contact warning.`);\n await message.reply(\n 'This channel/space is not currently mapped to a daemon chat. Please use `/chat [chat-id]` or `/agent [agent-id]` to map it.'\n );\n } else {\n console.log(\n `Unmapped channel ${externalContextId}, silently ignoring background message.`\n );\n }\n return;\n }\n }\n\n // Fallback typing safeguard\n if (!targetChatId) targetChatId = config.chatId || 'default';\n\n const commandResult = await handleAdapterCommand(\n message.content,\n filteringConfig,\n trpc as unknown as CommandTrpcClient,\n targetChatId\n );\n\n if (commandResult) {\n if (commandResult.type === 'text') {\n if (commandResult.newConfig) {\n filteringConfig.filters = commandResult.newConfig.filters;\n await updateDiscordState({ filters: filteringConfig.filters });\n }\n await message.reply(commandResult.text);\n } else if (commandResult.type === 'debug') {\n const formatted =\n commandResult.messages.length === 0\n ? 'No ignored background messages found.'\n : `**Debug Output (${commandResult.messages.length} ignored messages):**\\n\\n` +\n commandResult.messages.map((msg) => formatMessage(msg)).join('\\n\\n---\\n\\n');\n await message.reply(formatted);\n }\n return;\n }\n\n const downloadedFiles: string[] = [];\n if (message.attachments.size > 0) {\n const tmpDir = path.join(getClawminiDir(process.cwd()), 'tmp', 'discord');\n await fs.mkdir(tmpDir, { recursive: true });\n const maxSizeMB = config.maxAttachmentSizeMB ?? 25;\n const maxSizeBytes = maxSizeMB * 1024 * 1024;\n\n for (const attachment of message.attachments.values()) {\n if (attachment.size > maxSizeBytes) {\n console.warn(\n `Attachment ${attachment.name} exceeds size limit (${maxSizeMB}MB). Ignoring.`\n );\n await message.reply(\n `Warning: Attachment ${attachment.name} exceeds the size limit of ${maxSizeMB}MB and was ignored.`\n );\n continue;\n }\n\n try {\n const res = await fetch(attachment.url);\n if (!res.ok) {\n console.error(`Failed to download attachment ${attachment.name}`);\n continue;\n }\n\n const uniqueName = `${Date.now()}-${attachment.name}`;\n const filePath = path.join(tmpDir, uniqueName);\n const arrayBuffer = await res.arrayBuffer();\n await fs.writeFile(filePath, Buffer.from(arrayBuffer));\n downloadedFiles.push(filePath);\n } catch (err) {\n console.error(`Error downloading attachment ${attachment.name}:`, err);\n }\n }\n }\n\n let finalContent = message.content;\n\n if (message.reference && message.reference.messageId) {\n try {\n const referencedMessage = await message.fetchReference();\n if (referencedMessage && referencedMessage.content) {\n const quotedContent = referencedMessage.content\n .split('\\n')\n .map((line) => `> ${line}`)\n .join('\\n');\n finalContent = `${quotedContent}\\n${finalContent}`;\n }\n } catch (err) {\n console.error('Failed to fetch referenced message:', err);\n }\n }\n\n console.log(`Forwarding message to daemon: ${finalContent}`);\n try {\n await trpc.sendMessage.mutate({\n type: 'send-message',\n client: 'cli',\n data: {\n message: finalContent,\n chatId: targetChatId,\n files: downloadedFiles.length > 0 ? downloadedFiles : undefined,\n adapter: 'discord',\n noWait: true,\n },\n });\n console.log('Message forwarded to daemon successfully.');\n } catch (error) {\n console.error('Failed to forward message to daemon:', error);\n }\n });\n\n client.on(Events.InteractionCreate, async (interaction) => {\n await handleDiscordInteraction(interaction, config, trpc as unknown as CommandTrpcClient);\n });\n\n try {\n await client.login(config.botToken);\n } catch (error) {\n console.error('Failed to login to Discord:', error);\n process.exit(1);\n }\n}\n\nmain().catch((error) => {\n console.error('Unhandled error in Discord Adapter:', error);\n process.exit(1);\n});\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/adapter-google-chat/index.ts"],"mappings":";iBAUsB,IAAA,CAAA,GAAI,OAAA"}
|