agent-messenger 2.7.0 → 2.9.0
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/.claude-plugin/plugin.json +1 -1
- package/.github/workflows/ci.yml +6 -0
- package/.oxfmtrc.json +13 -1
- package/.oxlintrc.json +10 -1
- package/README.md +1 -12
- package/dist/package.json +59 -58
- package/dist/src/platforms/channeltalk/client.d.ts.map +1 -1
- package/dist/src/platforms/channeltalk/client.js +2 -2
- package/dist/src/platforms/channeltalk/client.js.map +1 -1
- package/dist/src/platforms/channeltalk/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/channeltalk/commands/auth.js.map +1 -1
- package/dist/src/platforms/channeltalk/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/channeltalk/commands/message.js.map +1 -1
- package/dist/src/platforms/channeltalk/commands/snapshot.d.ts +4 -2
- package/dist/src/platforms/channeltalk/commands/snapshot.d.ts.map +1 -1
- package/dist/src/platforms/channeltalk/commands/snapshot.js +86 -31
- package/dist/src/platforms/channeltalk/commands/snapshot.js.map +1 -1
- package/dist/src/platforms/channeltalk/ensure-auth.d.ts.map +1 -1
- package/dist/src/platforms/channeltalk/ensure-auth.js.map +1 -1
- package/dist/src/platforms/channeltalk/token-extractor.d.ts +9 -23
- package/dist/src/platforms/channeltalk/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/channeltalk/token-extractor.js +109 -341
- package/dist/src/platforms/channeltalk/token-extractor.js.map +1 -1
- package/dist/src/platforms/channeltalkbot/client.d.ts +1 -1
- package/dist/src/platforms/channeltalkbot/client.d.ts.map +1 -1
- package/dist/src/platforms/channeltalkbot/client.js +4 -4
- package/dist/src/platforms/channeltalkbot/client.js.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/auth.js +4 -1
- package/dist/src/platforms/channeltalkbot/commands/auth.js.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/shared.d.ts.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/shared.js.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/snapshot.d.ts +3 -1
- package/dist/src/platforms/channeltalkbot/commands/snapshot.d.ts.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/snapshot.js +110 -60
- package/dist/src/platforms/channeltalkbot/commands/snapshot.js.map +1 -1
- package/dist/src/platforms/discord/commands/auth.js.map +1 -1
- package/dist/src/platforms/discord/commands/snapshot.d.ts +1 -0
- package/dist/src/platforms/discord/commands/snapshot.d.ts.map +1 -1
- package/dist/src/platforms/discord/commands/snapshot.js +48 -34
- package/dist/src/platforms/discord/commands/snapshot.js.map +1 -1
- package/dist/src/platforms/discord/commands/whoami.d.ts.map +1 -1
- package/dist/src/platforms/discord/commands/whoami.js.map +1 -1
- package/dist/src/platforms/discord/token-extractor.d.ts +2 -10
- package/dist/src/platforms/discord/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/discord/token-extractor.js +38 -172
- package/dist/src/platforms/discord/token-extractor.js.map +1 -1
- package/dist/src/platforms/discordbot/client.d.ts.map +1 -1
- package/dist/src/platforms/discordbot/client.js.map +1 -1
- package/dist/src/platforms/discordbot/commands/snapshot.d.ts +2 -0
- package/dist/src/platforms/discordbot/commands/snapshot.d.ts.map +1 -1
- package/dist/src/platforms/discordbot/commands/snapshot.js +46 -34
- package/dist/src/platforms/discordbot/commands/snapshot.js.map +1 -1
- package/dist/src/platforms/instagram/cli.d.ts.map +1 -1
- package/dist/src/platforms/instagram/cli.js +1 -4
- package/dist/src/platforms/instagram/cli.js.map +1 -1
- package/dist/src/platforms/instagram/client.d.ts.map +1 -1
- package/dist/src/platforms/instagram/client.js +8 -7
- package/dist/src/platforms/instagram/client.js.map +1 -1
- package/dist/src/platforms/instagram/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/instagram/commands/auth.js.map +1 -1
- package/dist/src/platforms/instagram/commands/chat.d.ts.map +1 -1
- package/dist/src/platforms/instagram/commands/chat.js.map +1 -1
- package/dist/src/platforms/instagram/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/instagram/commands/message.js.map +1 -1
- package/dist/src/platforms/instagram/commands/shared.d.ts.map +1 -1
- package/dist/src/platforms/instagram/commands/shared.js.map +1 -1
- package/dist/src/platforms/instagram/credential-manager.d.ts.map +1 -1
- package/dist/src/platforms/instagram/credential-manager.js +1 -1
- package/dist/src/platforms/instagram/credential-manager.js.map +1 -1
- package/dist/src/platforms/instagram/ensure-auth.d.ts.map +1 -1
- package/dist/src/platforms/instagram/ensure-auth.js.map +1 -1
- package/dist/src/platforms/instagram/token-extractor.d.ts +7 -19
- package/dist/src/platforms/instagram/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/instagram/token-extractor.js +44 -270
- package/dist/src/platforms/instagram/token-extractor.js.map +1 -1
- package/dist/src/platforms/instagram/types.d.ts.map +1 -1
- package/dist/src/platforms/instagram/types.js +4 -2
- package/dist/src/platforms/instagram/types.js.map +1 -1
- package/dist/src/platforms/kakaotalk/auth/kakao-login.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/auth/kakao-login.js +18 -4
- package/dist/src/platforms/kakaotalk/auth/kakao-login.js.map +1 -1
- package/dist/src/platforms/kakaotalk/client.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/client.js +3 -3
- package/dist/src/platforms/kakaotalk/client.js.map +1 -1
- package/dist/src/platforms/kakaotalk/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/commands/auth.js +15 -9
- package/dist/src/platforms/kakaotalk/commands/auth.js.map +1 -1
- package/dist/src/platforms/kakaotalk/commands/shared.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/commands/shared.js.map +1 -1
- package/dist/src/platforms/kakaotalk/protocol/connection.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/protocol/connection.js.map +1 -1
- package/dist/src/platforms/kakaotalk/protocol/crypto.js +1 -1
- package/dist/src/platforms/kakaotalk/protocol/crypto.js.map +1 -1
- package/dist/src/platforms/kakaotalk/protocol/session.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/protocol/session.js +1 -3
- package/dist/src/platforms/kakaotalk/protocol/session.js.map +1 -1
- package/dist/src/platforms/kakaotalk/token-extractor.js +5 -2
- package/dist/src/platforms/kakaotalk/token-extractor.js.map +1 -1
- package/dist/src/platforms/kakaotalk/types.d.ts.map +1 -1
- package/dist/src/platforms/kakaotalk/types.js +4 -2
- package/dist/src/platforms/kakaotalk/types.js.map +1 -1
- package/dist/src/platforms/line/cli.d.ts.map +1 -1
- package/dist/src/platforms/line/cli.js +1 -4
- package/dist/src/platforms/line/cli.js.map +1 -1
- package/dist/src/platforms/line/client.d.ts.map +1 -1
- package/dist/src/platforms/line/client.js +5 -13
- package/dist/src/platforms/line/client.js.map +1 -1
- package/dist/src/platforms/line/commands/chat.d.ts.map +1 -1
- package/dist/src/platforms/line/commands/chat.js.map +1 -1
- package/dist/src/platforms/line/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/line/commands/message.js.map +1 -1
- package/dist/src/platforms/line/listener.js +1 -1
- package/dist/src/platforms/line/listener.js.map +1 -1
- package/dist/src/platforms/slack/cli.d.ts.map +1 -1
- package/dist/src/platforms/slack/cli.js.map +1 -1
- package/dist/src/platforms/slack/client-mappers.d.ts +14 -0
- package/dist/src/platforms/slack/client-mappers.d.ts.map +1 -0
- package/dist/src/platforms/slack/client-mappers.js +245 -0
- package/dist/src/platforms/slack/client-mappers.js.map +1 -0
- package/dist/src/platforms/slack/client.d.ts +0 -1
- package/dist/src/platforms/slack/client.d.ts.map +1 -1
- package/dist/src/platforms/slack/client.js +41 -455
- package/dist/src/platforms/slack/client.js.map +1 -1
- package/dist/src/platforms/slack/commands/channel.d.ts.map +1 -1
- package/dist/src/platforms/slack/commands/channel.js.map +1 -1
- package/dist/src/platforms/slack/commands/emoji.d.ts.map +1 -1
- package/dist/src/platforms/slack/commands/emoji.js +1 -3
- package/dist/src/platforms/slack/commands/emoji.js.map +1 -1
- package/dist/src/platforms/slack/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/slack/commands/message.js.map +1 -1
- package/dist/src/platforms/slack/commands/reminder.d.ts.map +1 -1
- package/dist/src/platforms/slack/commands/reminder.js.map +1 -1
- package/dist/src/platforms/slack/commands/snapshot.d.ts.map +1 -1
- package/dist/src/platforms/slack/commands/snapshot.js +75 -55
- package/dist/src/platforms/slack/commands/snapshot.js.map +1 -1
- package/dist/src/platforms/slack/commands/user.d.ts.map +1 -1
- package/dist/src/platforms/slack/commands/user.js.map +1 -1
- package/dist/src/platforms/slack/commands/usergroup.d.ts.map +1 -1
- package/dist/src/platforms/slack/commands/usergroup.js.map +1 -1
- package/dist/src/platforms/slack/commands/whoami.d.ts.map +1 -1
- package/dist/src/platforms/slack/commands/whoami.js.map +1 -1
- package/dist/src/platforms/slack/token-extractor.d.ts +2 -6
- package/dist/src/platforms/slack/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/slack/token-extractor.js +35 -229
- package/dist/src/platforms/slack/token-extractor.js.map +1 -1
- package/dist/src/platforms/slackbot/cli.d.ts.map +1 -1
- package/dist/src/platforms/slackbot/cli.js +1 -1
- package/dist/src/platforms/slackbot/cli.js.map +1 -1
- package/dist/src/platforms/teams/client.d.ts.map +1 -1
- package/dist/src/platforms/teams/client.js +1 -1
- package/dist/src/platforms/teams/client.js.map +1 -1
- package/dist/src/platforms/teams/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/teams/commands/auth.js +4 -1
- package/dist/src/platforms/teams/commands/auth.js.map +1 -1
- package/dist/src/platforms/teams/commands/snapshot.d.ts +1 -0
- package/dist/src/platforms/teams/commands/snapshot.d.ts.map +1 -1
- package/dist/src/platforms/teams/commands/snapshot.js +44 -31
- package/dist/src/platforms/teams/commands/snapshot.js.map +1 -1
- package/dist/src/platforms/teams/commands/whoami.d.ts.map +1 -1
- package/dist/src/platforms/teams/commands/whoami.js.map +1 -1
- package/dist/src/platforms/teams/token-extractor.d.ts +6 -18
- package/dist/src/platforms/teams/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/teams/token-extractor.js +71 -324
- package/dist/src/platforms/teams/token-extractor.js.map +1 -1
- package/dist/src/platforms/telegram/cli.d.ts.map +1 -1
- package/dist/src/platforms/telegram/cli.js +1 -4
- package/dist/src/platforms/telegram/cli.js.map +1 -1
- package/dist/src/platforms/telegram/client.d.ts.map +1 -1
- package/dist/src/platforms/telegram/client.js.map +1 -1
- package/dist/src/platforms/telegram/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/telegram/commands/auth.js +1 -1
- package/dist/src/platforms/telegram/commands/auth.js.map +1 -1
- package/dist/src/platforms/telegram/commands/chat.d.ts.map +1 -1
- package/dist/src/platforms/telegram/commands/chat.js.map +1 -1
- package/dist/src/platforms/telegram/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/telegram/commands/message.js.map +1 -1
- package/dist/src/platforms/telegram/commands/whoami.js +1 -1
- package/dist/src/platforms/telegram/commands/whoami.js.map +1 -1
- package/dist/src/platforms/telegram/credential-manager.d.ts.map +1 -1
- package/dist/src/platforms/telegram/credential-manager.js +6 -2
- package/dist/src/platforms/telegram/credential-manager.js.map +1 -1
- package/dist/src/platforms/telegram/my-telegram-org.js.map +1 -1
- package/dist/src/platforms/webex/cli.d.ts.map +1 -1
- package/dist/src/platforms/webex/cli.js +1 -4
- package/dist/src/platforms/webex/cli.js.map +1 -1
- package/dist/src/platforms/webex/client.d.ts.map +1 -1
- package/dist/src/platforms/webex/client.js +3 -7
- package/dist/src/platforms/webex/client.js.map +1 -1
- package/dist/src/platforms/webex/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/webex/commands/auth.js +1 -3
- package/dist/src/platforms/webex/commands/auth.js.map +1 -1
- package/dist/src/platforms/webex/commands/member.d.ts.map +1 -1
- package/dist/src/platforms/webex/commands/member.js +1 -3
- package/dist/src/platforms/webex/commands/member.js.map +1 -1
- package/dist/src/platforms/webex/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/webex/commands/message.js.map +1 -1
- package/dist/src/platforms/webex/commands/snapshot.d.ts +1 -0
- package/dist/src/platforms/webex/commands/snapshot.d.ts.map +1 -1
- package/dist/src/platforms/webex/commands/snapshot.js +14 -7
- package/dist/src/platforms/webex/commands/snapshot.js.map +1 -1
- package/dist/src/platforms/webex/commands/space.d.ts.map +1 -1
- package/dist/src/platforms/webex/commands/space.js.map +1 -1
- package/dist/src/platforms/webex/commands/whoami.d.ts.map +1 -1
- package/dist/src/platforms/webex/commands/whoami.js.map +1 -1
- package/dist/src/platforms/webex/credential-manager.d.ts.map +1 -1
- package/dist/src/platforms/webex/credential-manager.js.map +1 -1
- package/dist/src/platforms/webex/ensure-auth.d.ts.map +1 -1
- package/dist/src/platforms/webex/ensure-auth.js +1 -3
- package/dist/src/platforms/webex/ensure-auth.js.map +1 -1
- package/dist/src/platforms/webex/index.d.ts +1 -1
- package/dist/src/platforms/webex/index.d.ts.map +1 -1
- package/dist/src/platforms/webex/index.js.map +1 -1
- package/dist/src/platforms/webex/markdown-to-html.js.map +1 -1
- package/dist/src/platforms/webex/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/webex/token-extractor.js +5 -14
- package/dist/src/platforms/webex/token-extractor.js.map +1 -1
- package/dist/src/platforms/wechatbot/client.d.ts.map +1 -1
- package/dist/src/platforms/wechatbot/client.js.map +1 -1
- package/dist/src/platforms/wechatbot/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/wechatbot/commands/message.js.map +1 -1
- package/dist/src/platforms/whatsapp/cli.d.ts.map +1 -1
- package/dist/src/platforms/whatsapp/cli.js +1 -4
- package/dist/src/platforms/whatsapp/cli.js.map +1 -1
- package/dist/src/platforms/whatsapp/commands/chat.d.ts.map +1 -1
- package/dist/src/platforms/whatsapp/commands/chat.js.map +1 -1
- package/dist/src/platforms/whatsapp/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/whatsapp/commands/message.js.map +1 -1
- package/dist/src/platforms/whatsapp/commands/shared.d.ts.map +1 -1
- package/dist/src/platforms/whatsapp/commands/shared.js.map +1 -1
- package/dist/src/platforms/whatsapp/credential-manager.d.ts.map +1 -1
- package/dist/src/platforms/whatsapp/credential-manager.js +1 -1
- package/dist/src/platforms/whatsapp/credential-manager.js.map +1 -1
- package/dist/src/platforms/whatsapp/ensure-auth.d.ts.map +1 -1
- package/dist/src/platforms/whatsapp/ensure-auth.js.map +1 -1
- package/dist/src/platforms/whatsappbot/client.d.ts.map +1 -1
- package/dist/src/platforms/whatsappbot/client.js +2 -2
- package/dist/src/platforms/whatsappbot/client.js.map +1 -1
- package/dist/src/platforms/whatsappbot/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/whatsappbot/commands/auth.js +4 -1
- package/dist/src/platforms/whatsappbot/commands/auth.js.map +1 -1
- package/dist/src/platforms/whatsappbot/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/whatsappbot/commands/message.js.map +1 -1
- package/dist/src/platforms/whatsappbot/commands/shared.d.ts.map +1 -1
- package/dist/src/platforms/whatsappbot/commands/shared.js.map +1 -1
- package/dist/src/shared/chromium/browsers.d.ts +7 -0
- package/dist/src/shared/chromium/browsers.d.ts.map +1 -0
- package/dist/src/shared/chromium/browsers.js +89 -0
- package/dist/src/shared/chromium/browsers.js.map +1 -0
- package/dist/src/shared/chromium/cookie-reader.d.ts +20 -0
- package/dist/src/shared/chromium/cookie-reader.d.ts.map +1 -0
- package/dist/src/shared/chromium/cookie-reader.js +99 -0
- package/dist/src/shared/chromium/cookie-reader.js.map +1 -0
- package/dist/src/shared/chromium/decryptor.d.ts +42 -0
- package/dist/src/shared/chromium/decryptor.d.ts.map +1 -0
- package/dist/src/shared/chromium/decryptor.js +205 -0
- package/dist/src/shared/chromium/decryptor.js.map +1 -0
- package/dist/src/shared/chromium/index.d.ts +6 -0
- package/dist/src/shared/chromium/index.d.ts.map +1 -0
- package/dist/src/shared/chromium/index.js +4 -0
- package/dist/src/shared/chromium/index.js.map +1 -0
- package/dist/src/shared/chromium/types.d.ts +11 -0
- package/dist/src/shared/chromium/types.d.ts.map +1 -0
- package/dist/src/shared/chromium/types.js +2 -0
- package/dist/src/shared/chromium/types.js.map +1 -0
- package/dist/src/shared/utils/derived-key-cache.d.ts +1 -1
- package/dist/src/shared/utils/derived-key-cache.d.ts.map +1 -1
- package/dist/src/shared/utils/linux-keyring.js +4 -1
- package/dist/src/shared/utils/linux-keyring.js.map +1 -1
- package/dist/src/tui/adapters/kakaotalk-adapter.d.ts.map +1 -1
- package/dist/src/tui/adapters/kakaotalk-adapter.js +6 -1
- package/dist/src/tui/adapters/kakaotalk-adapter.js.map +1 -1
- package/dist/src/tui/adapters/telegram-adapter.js +1 -1
- package/dist/src/tui/adapters/telegram-adapter.js.map +1 -1
- package/dist/src/tui/adapters/webex-adapter.js +1 -1
- package/dist/src/tui/adapters/webex-adapter.js.map +1 -1
- package/dist/src/tui/app.d.ts.map +1 -1
- package/dist/src/tui/app.js +112 -23
- package/dist/src/tui/app.js.map +1 -1
- package/dist/src/tui/utils.d.ts.map +1 -1
- package/dist/src/tui/utils.js +11 -13
- package/dist/src/tui/utils.js.map +1 -1
- package/dist/src/tui/views/channel-picker.d.ts.map +1 -1
- package/dist/src/tui/views/channel-picker.js.map +1 -1
- package/dist/src/tui/views/workspace-picker.d.ts.map +1 -1
- package/dist/src/tui/views/workspace-picker.js.map +1 -1
- package/docs/content/docs/agent-skills.mdx +0 -10
- package/docs/content/docs/cli/channeltalk.mdx +42 -30
- package/docs/content/docs/cli/channeltalkbot.mdx +23 -13
- package/docs/content/docs/cli/discord.mdx +23 -7
- package/docs/content/docs/cli/discordbot.mdx +23 -7
- package/docs/content/docs/cli/instagram.mdx +4 -4
- package/docs/content/docs/cli/kakaotalk.mdx +9 -8
- package/docs/content/docs/cli/line.mdx +14 -14
- package/docs/content/docs/cli/slack.mdx +24 -7
- package/docs/content/docs/cli/teams.mdx +24 -8
- package/docs/content/docs/cli/webex.mdx +34 -21
- package/docs/content/docs/cli/wechatbot.mdx +12 -11
- package/docs/content/docs/cli/whatsapp.mdx +5 -4
- package/docs/content/docs/cli/whatsappbot.mdx +11 -11
- package/docs/content/docs/index.mdx +7 -7
- package/docs/content/docs/meta.json +1 -9
- package/docs/content/docs/sdk/channeltalk.mdx +5 -6
- package/docs/content/docs/sdk/channeltalkbot.mdx +6 -12
- package/docs/content/docs/sdk/discord.mdx +36 -43
- package/docs/content/docs/sdk/instagram.mdx +18 -18
- package/docs/content/docs/sdk/kakaotalk.mdx +27 -18
- package/docs/content/docs/sdk/line.mdx +8 -13
- package/docs/content/docs/sdk/meta.json +14 -1
- package/docs/content/docs/sdk/slack.mdx +36 -42
- package/docs/content/docs/sdk/teams.mdx +2 -8
- package/docs/content/docs/sdk/webex.mdx +2 -12
- package/docs/content/docs/sdk/wechatbot.mdx +1 -5
- package/docs/content/docs/sdk/whatsapp.mdx +10 -19
- package/docs/content/docs/sdk/whatsappbot.mdx +2 -10
- package/docs/content/docs/tui.mdx +23 -23
- package/docs/src/app/page.tsx +353 -108
- package/e2e/channeltalkbot.e2e.test.ts +1 -5
- package/e2e/config.ts +6 -2
- package/package.json +59 -58
- package/scripts/prepublish.ts +1 -3
- package/skills/agent-channeltalk/SKILL.md +19 -9
- package/skills/agent-channeltalk/references/common-patterns.md +10 -9
- package/skills/agent-channeltalkbot/SKILL.md +19 -9
- package/skills/agent-channeltalkbot/references/common-patterns.md +10 -9
- package/skills/agent-discord/SKILL.md +18 -9
- package/skills/agent-discord/references/common-patterns.md +8 -7
- package/skills/agent-discordbot/SKILL.md +18 -9
- package/skills/agent-instagram/SKILL.md +1 -1
- package/skills/agent-kakaotalk/SKILL.md +1 -1
- package/skills/agent-line/SKILL.md +1 -1
- package/skills/agent-slack/SKILL.md +19 -10
- package/skills/agent-slack/references/common-patterns.md +4 -7
- package/skills/agent-slackbot/SKILL.md +1 -1
- package/skills/agent-teams/SKILL.md +18 -9
- package/skills/agent-teams/references/common-patterns.md +9 -7
- package/skills/agent-telegram/SKILL.md +1 -1
- package/skills/agent-webex/SKILL.md +13 -4
- package/skills/agent-webex/references/common-patterns.md +8 -2
- package/skills/agent-wechatbot/SKILL.md +1 -1
- package/skills/agent-whatsapp/SKILL.md +1 -1
- package/skills/agent-whatsappbot/SKILL.md +1 -1
- package/src/platforms/channeltalk/client.test.ts +116 -29
- package/src/platforms/channeltalk/client.ts +26 -6
- package/src/platforms/channeltalk/commands/auth.test.ts +5 -5
- package/src/platforms/channeltalk/commands/auth.ts +19 -5
- package/src/platforms/channeltalk/commands/message.test.ts +2 -6
- package/src/platforms/channeltalk/commands/message.ts +5 -1
- package/src/platforms/channeltalk/commands/snapshot.test.ts +77 -30
- package/src/platforms/channeltalk/commands/snapshot.ts +112 -34
- package/src/platforms/channeltalk/ensure-auth.test.ts +20 -17
- package/src/platforms/channeltalk/ensure-auth.ts +6 -7
- package/src/platforms/channeltalk/index.ts +0 -1
- package/src/platforms/channeltalk/token-extractor.test.ts +33 -25
- package/src/platforms/channeltalk/token-extractor.ts +120 -372
- package/src/platforms/channeltalkbot/client.test.ts +1 -3
- package/src/platforms/channeltalkbot/client.ts +39 -13
- package/src/platforms/channeltalkbot/commands/auth.test.ts +3 -1
- package/src/platforms/channeltalkbot/commands/auth.ts +4 -1
- package/src/platforms/channeltalkbot/commands/bot.test.ts +13 -5
- package/src/platforms/channeltalkbot/commands/message.test.ts +12 -6
- package/src/platforms/channeltalkbot/commands/shared.ts +6 -2
- package/src/platforms/channeltalkbot/commands/snapshot.test.ts +43 -13
- package/src/platforms/channeltalkbot/commands/snapshot.ts +131 -64
- package/src/platforms/channeltalkbot/credential-manager.test.ts +1 -1
- package/src/platforms/channeltalkbot/index.test.ts +0 -2
- package/src/platforms/channeltalkbot/index.ts +0 -1
- package/src/platforms/discord/commands/auth.test.ts +6 -4
- package/src/platforms/discord/commands/auth.ts +14 -14
- package/src/platforms/discord/commands/snapshot.test.ts +1 -1
- package/src/platforms/discord/commands/snapshot.ts +58 -42
- package/src/platforms/discord/commands/whoami.test.ts +2 -4
- package/src/platforms/discord/commands/whoami.ts +2 -0
- package/src/platforms/discord/ensure-auth.test.ts +5 -3
- package/src/platforms/discord/index.ts +0 -1
- package/src/platforms/discord/listener.test.ts +7 -1
- package/src/platforms/discord/token-extractor.test.ts +18 -12
- package/src/platforms/discord/token-extractor.ts +46 -190
- package/src/platforms/discordbot/client.ts +1 -4
- package/src/platforms/discordbot/commands/auth.test.ts +3 -1
- package/src/platforms/discordbot/commands/channel.test.ts +3 -1
- package/src/platforms/discordbot/commands/message.test.ts +3 -1
- package/src/platforms/discordbot/commands/server.test.ts +3 -1
- package/src/platforms/discordbot/commands/snapshot.test.ts +43 -19
- package/src/platforms/discordbot/commands/snapshot.ts +54 -37
- package/src/platforms/discordbot/commands/thread.test.ts +3 -1
- package/src/platforms/discordbot/commands/user.test.ts +3 -1
- package/src/platforms/instagram/cli.ts +1 -4
- package/src/platforms/instagram/client.test.ts +3 -8
- package/src/platforms/instagram/client.ts +39 -34
- package/src/platforms/instagram/commands/auth.test.ts +13 -12
- package/src/platforms/instagram/commands/auth.ts +136 -71
- package/src/platforms/instagram/commands/chat.test.ts +21 -24
- package/src/platforms/instagram/commands/chat.ts +2 -0
- package/src/platforms/instagram/commands/message.test.ts +29 -24
- package/src/platforms/instagram/commands/message.ts +3 -4
- package/src/platforms/instagram/commands/shared.ts +2 -5
- package/src/platforms/instagram/commands/whoami.test.ts +4 -6
- package/src/platforms/instagram/credential-manager.ts +2 -6
- package/src/platforms/instagram/ensure-auth.test.ts +1 -4
- package/src/platforms/instagram/ensure-auth.ts +6 -3
- package/src/platforms/instagram/listener.test.ts +7 -3
- package/src/platforms/instagram/token-extractor.test.ts +4 -16
- package/src/platforms/instagram/token-extractor.ts +55 -309
- package/src/platforms/instagram/types.test.ts +2 -6
- package/src/platforms/instagram/types.ts +4 -2
- package/src/platforms/kakaotalk/auth/kakao-login.ts +30 -8
- package/src/platforms/kakaotalk/client.test.ts +37 -25
- package/src/platforms/kakaotalk/client.ts +23 -12
- package/src/platforms/kakaotalk/commands/auth.test.ts +6 -18
- package/src/platforms/kakaotalk/commands/auth.ts +101 -47
- package/src/platforms/kakaotalk/commands/chat.test.ts +8 -11
- package/src/platforms/kakaotalk/commands/message.test.ts +15 -24
- package/src/platforms/kakaotalk/commands/shared.ts +1 -0
- package/src/platforms/kakaotalk/commands/whoami.test.ts +6 -10
- package/src/platforms/kakaotalk/credential-manager.test.ts +1 -4
- package/src/platforms/kakaotalk/index.test.ts +1 -0
- package/src/platforms/kakaotalk/index.ts +0 -2
- package/src/platforms/kakaotalk/listener.test.ts +7 -1
- package/src/platforms/kakaotalk/protocol/connection.ts +4 -1
- package/src/platforms/kakaotalk/protocol/crypto.ts +1 -1
- package/src/platforms/kakaotalk/protocol/session.ts +12 -6
- package/src/platforms/kakaotalk/token-extractor.ts +5 -5
- package/src/platforms/kakaotalk/types.ts +8 -7
- package/src/platforms/line/cli.ts +1 -4
- package/src/platforms/line/client.ts +12 -20
- package/src/platforms/line/commands/auth.test.ts +2 -1
- package/src/platforms/line/commands/chat.test.ts +2 -1
- package/src/platforms/line/commands/chat.ts +1 -4
- package/src/platforms/line/commands/friend.test.ts +2 -1
- package/src/platforms/line/commands/message.test.ts +2 -1
- package/src/platforms/line/commands/message.ts +2 -9
- package/src/platforms/line/commands/whoami.test.ts +2 -1
- package/src/platforms/line/credential-manager.test.ts +1 -2
- package/src/platforms/line/index.test.ts +1 -0
- package/src/platforms/line/listener.ts +1 -1
- package/src/platforms/line/types.test.ts +1 -0
- package/src/platforms/slack/cli.ts +3 -1
- package/src/platforms/slack/client-mappers.ts +297 -0
- package/src/platforms/slack/client.test.ts +532 -17
- package/src/platforms/slack/client.ts +69 -458
- package/src/platforms/slack/commands/channel.ts +1 -4
- package/src/platforms/slack/commands/emoji.test.ts +6 -4
- package/src/platforms/slack/commands/emoji.ts +20 -22
- package/src/platforms/slack/commands/message.ts +6 -1
- package/src/platforms/slack/commands/pin.test.ts +14 -12
- package/src/platforms/slack/commands/reminder.ts +7 -6
- package/src/platforms/slack/commands/snapshot.test.ts +63 -8
- package/src/platforms/slack/commands/snapshot.ts +98 -66
- package/src/platforms/slack/commands/user.ts +6 -1
- package/src/platforms/slack/commands/usergroup.test.ts +3 -3
- package/src/platforms/slack/commands/usergroup.ts +10 -7
- package/src/platforms/slack/commands/whoami.test.ts +1 -1
- package/src/platforms/slack/commands/whoami.ts +2 -0
- package/src/platforms/slack/index.ts +0 -2
- package/src/platforms/slack/listener.test.ts +1 -0
- package/src/platforms/slack/token-extractor.test.ts +7 -12
- package/src/platforms/slack/token-extractor.ts +47 -255
- package/src/platforms/slackbot/cli.ts +8 -1
- package/src/platforms/slackbot/commands/auth.test.ts +3 -1
- package/src/platforms/teams/client.ts +1 -1
- package/src/platforms/teams/commands/auth.test.ts +1 -1
- package/src/platforms/teams/commands/auth.ts +4 -1
- package/src/platforms/teams/commands/snapshot.test.ts +1 -1
- package/src/platforms/teams/commands/snapshot.ts +53 -38
- package/src/platforms/teams/commands/whoami.test.ts +2 -4
- package/src/platforms/teams/commands/whoami.ts +2 -0
- package/src/platforms/teams/index.ts +0 -1
- package/src/platforms/teams/token-extractor.ts +82 -350
- package/src/platforms/telegram/app-config.test.ts +1 -0
- package/src/platforms/telegram/chat-utils.test.ts +5 -1
- package/src/platforms/telegram/cli.ts +2 -4
- package/src/platforms/telegram/client.test.ts +16 -3
- package/src/platforms/telegram/client.ts +14 -4
- package/src/platforms/telegram/commands/auth.test.ts +1 -0
- package/src/platforms/telegram/commands/auth.ts +3 -4
- package/src/platforms/telegram/commands/chat.test.ts +2 -5
- package/src/platforms/telegram/commands/chat.ts +1 -0
- package/src/platforms/telegram/commands/message.test.ts +2 -5
- package/src/platforms/telegram/commands/message.ts +1 -0
- package/src/platforms/telegram/commands/shared.test.ts +1 -0
- package/src/platforms/telegram/commands/whoami.test.ts +5 -7
- package/src/platforms/telegram/commands/whoami.ts +1 -1
- package/src/platforms/telegram/credential-manager.test.ts +1 -0
- package/src/platforms/telegram/credential-manager.ts +11 -2
- package/src/platforms/telegram/my-telegram-org.ts +6 -2
- package/src/platforms/telegram/types.test.ts +1 -0
- package/src/platforms/webex/app-config.test.ts +1 -0
- package/src/platforms/webex/cli.ts +1 -4
- package/src/platforms/webex/client.test.ts +4 -12
- package/src/platforms/webex/client.ts +14 -52
- package/src/platforms/webex/commands/auth.test.ts +7 -1
- package/src/platforms/webex/commands/auth.ts +12 -15
- package/src/platforms/webex/commands/member.test.ts +1 -3
- package/src/platforms/webex/commands/member.ts +14 -19
- package/src/platforms/webex/commands/message.ts +4 -15
- package/src/platforms/webex/commands/snapshot.test.ts +42 -4
- package/src/platforms/webex/commands/snapshot.ts +19 -11
- package/src/platforms/webex/commands/space.test.ts +3 -3
- package/src/platforms/webex/commands/space.ts +2 -9
- package/src/platforms/webex/commands/whoami.test.ts +12 -5
- package/src/platforms/webex/commands/whoami.ts +2 -0
- package/src/platforms/webex/credential-manager.ts +11 -2
- package/src/platforms/webex/ensure-auth.ts +1 -3
- package/src/platforms/webex/index.ts +1 -7
- package/src/platforms/webex/markdown-to-html.test.ts +6 -18
- package/src/platforms/webex/markdown-to-html.ts +8 -8
- package/src/platforms/webex/token-extractor.ts +6 -29
- package/src/platforms/wechatbot/client.test.ts +6 -2
- package/src/platforms/wechatbot/client.ts +6 -1
- package/src/platforms/wechatbot/commands/auth.test.ts +3 -7
- package/src/platforms/wechatbot/commands/message.test.ts +1 -4
- package/src/platforms/wechatbot/commands/message.ts +5 -1
- package/src/platforms/wechatbot/commands/template.test.ts +1 -4
- package/src/platforms/wechatbot/commands/user.test.ts +2 -7
- package/src/platforms/whatsapp/cli.ts +1 -4
- package/src/platforms/whatsapp/commands/auth.test.ts +19 -22
- package/src/platforms/whatsapp/commands/chat.test.ts +21 -24
- package/src/platforms/whatsapp/commands/chat.ts +2 -0
- package/src/platforms/whatsapp/commands/message.test.ts +22 -24
- package/src/platforms/whatsapp/commands/message.ts +3 -5
- package/src/platforms/whatsapp/commands/shared.ts +2 -5
- package/src/platforms/whatsapp/commands/whoami.test.ts +2 -2
- package/src/platforms/whatsapp/credential-manager.ts +2 -6
- package/src/platforms/whatsapp/ensure-auth.test.ts +1 -4
- package/src/platforms/whatsapp/ensure-auth.ts +14 -6
- package/src/platforms/whatsapp/index.ts +0 -2
- package/src/platforms/whatsappbot/client.test.ts +13 -7
- package/src/platforms/whatsappbot/client.ts +18 -4
- package/src/platforms/whatsappbot/commands/auth.ts +4 -1
- package/src/platforms/whatsappbot/commands/message.test.ts +12 -2
- package/src/platforms/whatsappbot/commands/message.ts +16 -3
- package/src/platforms/whatsappbot/commands/shared.ts +3 -1
- package/src/platforms/whatsappbot/commands/whoami.test.ts +1 -3
- package/src/platforms/whatsappbot/index.ts +0 -2
- package/src/shared/chromium/browsers.test.ts +274 -0
- package/src/shared/chromium/browsers.ts +86 -0
- package/src/shared/chromium/cookie-reader.test.ts +274 -0
- package/src/shared/chromium/cookie-reader.ts +111 -0
- package/src/shared/chromium/decryptor.test.ts +449 -0
- package/src/shared/chromium/decryptor.ts +227 -0
- package/src/shared/chromium/index.ts +11 -0
- package/src/shared/chromium/types.ts +11 -0
- package/src/shared/utils/derived-key-cache.ts +1 -1
- package/src/shared/utils/linux-keyring.ts +4 -4
- package/src/tui/adapters/kakaotalk-adapter.ts +6 -1
- package/src/tui/adapters/telegram-adapter.ts +1 -1
- package/src/tui/adapters/webex-adapter.ts +1 -1
- package/src/tui/app.ts +149 -59
- package/src/tui/utils.test.ts +144 -145
- package/src/tui/utils.ts +27 -29
- package/src/tui/views/channel-picker.ts +1 -1
- package/src/tui/views/workspace-picker.ts +1 -1
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import { execSync, spawn } from 'node:child_process'
|
|
2
|
-
import {
|
|
2
|
+
import { pbkdf2Sync } from 'node:crypto'
|
|
3
3
|
import { existsSync, readdirSync, readFileSync } from 'node:fs'
|
|
4
4
|
import { homedir } from 'node:os'
|
|
5
5
|
import { join } from 'node:path'
|
|
6
6
|
|
|
7
|
+
import {
|
|
8
|
+
BROWSER_KEYCHAIN_VARIANTS,
|
|
9
|
+
CHROMIUM_BROWSERS,
|
|
10
|
+
ChromiumCookieDecryptor,
|
|
11
|
+
discoverBrowserProfileDirs,
|
|
12
|
+
getBrowserBasePath,
|
|
13
|
+
} from '@/shared/chromium'
|
|
14
|
+
import type { KeychainVariant } from '@/shared/chromium'
|
|
7
15
|
import { DerivedKeyCache } from '@/shared/utils/derived-key-cache'
|
|
8
16
|
import { lookupLinuxKeyringPassword } from '@/shared/utils/linux-keyring'
|
|
9
17
|
|
|
@@ -13,11 +21,6 @@ export interface ExtractedDiscordToken {
|
|
|
13
21
|
|
|
14
22
|
export type DiscordVariant = 'stable' | 'canary' | 'ptb'
|
|
15
23
|
|
|
16
|
-
interface KeychainVariant {
|
|
17
|
-
service: string
|
|
18
|
-
account: string
|
|
19
|
-
}
|
|
20
|
-
|
|
21
24
|
interface CDPTarget {
|
|
22
25
|
id: string
|
|
23
26
|
type: string
|
|
@@ -34,13 +37,6 @@ interface CDPMessage {
|
|
|
34
37
|
error?: { code: number; message: string }
|
|
35
38
|
}
|
|
36
39
|
|
|
37
|
-
interface BrowserConfig {
|
|
38
|
-
name: string
|
|
39
|
-
darwin: string
|
|
40
|
-
linux: string
|
|
41
|
-
win32: string
|
|
42
|
-
}
|
|
43
|
-
|
|
44
40
|
const TOKEN_REGEX = /[\w-]{24,}\.[\w-]{6}\.[\w-]{25,110}/
|
|
45
41
|
const MFA_TOKEN_REGEX = /mfa\.[\w-]{84}/
|
|
46
42
|
const ENCRYPTED_PREFIX = 'dQw4w9WgXcQ:'
|
|
@@ -62,49 +58,13 @@ const DISCORD_APP_PATHS: Record<DiscordVariant, { darwin: string }> = {
|
|
|
62
58
|
ptb: { darwin: '/Applications/Discord PTB.app/Contents/MacOS/Discord PTB' },
|
|
63
59
|
}
|
|
64
60
|
|
|
65
|
-
const
|
|
66
|
-
{
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
name: 'Chrome Canary',
|
|
74
|
-
darwin: join('Google', 'Chrome Canary'),
|
|
75
|
-
linux: 'google-chrome-unstable',
|
|
76
|
-
win32: join('Google', 'Chrome SxS', 'User Data'),
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
name: 'Edge',
|
|
80
|
-
darwin: 'Microsoft Edge',
|
|
81
|
-
linux: 'microsoft-edge',
|
|
82
|
-
win32: join('Microsoft', 'Edge', 'User Data'),
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
name: 'Arc',
|
|
86
|
-
darwin: join('Arc', 'User Data'),
|
|
87
|
-
linux: '',
|
|
88
|
-
win32: join('Arc', 'User Data'),
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
name: 'Brave',
|
|
92
|
-
darwin: join('BraveSoftware', 'Brave-Browser'),
|
|
93
|
-
linux: join('BraveSoftware', 'Brave-Browser'),
|
|
94
|
-
win32: join('BraveSoftware', 'Brave-Browser', 'User Data'),
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
name: 'Vivaldi',
|
|
98
|
-
darwin: 'Vivaldi',
|
|
99
|
-
linux: 'vivaldi',
|
|
100
|
-
win32: join('Vivaldi', 'User Data'),
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
name: 'Chromium',
|
|
104
|
-
darwin: 'Chromium',
|
|
105
|
-
linux: 'chromium',
|
|
106
|
-
win32: join('Chromium', 'User Data'),
|
|
107
|
-
},
|
|
61
|
+
const DISCORD_APP_KEYCHAIN_VARIANTS: KeychainVariant[] = [
|
|
62
|
+
{ service: 'discord Safe Storage', account: 'discord Key' },
|
|
63
|
+
{ service: 'discordcanary Safe Storage', account: 'discordcanary Key' },
|
|
64
|
+
{ service: 'discordptb Safe Storage', account: 'discordptb Key' },
|
|
65
|
+
{ service: 'Discord Safe Storage', account: 'Discord' },
|
|
66
|
+
{ service: 'Discord Canary Safe Storage', account: 'Discord Canary' },
|
|
67
|
+
{ service: 'Discord PTB Safe Storage', account: 'Discord PTB' },
|
|
108
68
|
]
|
|
109
69
|
|
|
110
70
|
export class DiscordTokenExtractor {
|
|
@@ -113,12 +73,20 @@ export class DiscordTokenExtractor {
|
|
|
113
73
|
private killWait: number
|
|
114
74
|
private keyCache: DerivedKeyCache
|
|
115
75
|
private cachedKey: Buffer | null = null
|
|
76
|
+
private decryptor: ChromiumCookieDecryptor
|
|
116
77
|
|
|
117
78
|
constructor(platform?: NodeJS.Platform, startupWait?: number, killWait?: number, keyCache?: DerivedKeyCache) {
|
|
118
79
|
this.platform = platform ?? process.platform
|
|
119
80
|
this.startupWait = startupWait ?? DISCORD_STARTUP_WAIT
|
|
120
81
|
this.killWait = killWait ?? 1000
|
|
121
82
|
this.keyCache = keyCache ?? new DerivedKeyCache()
|
|
83
|
+
this.decryptor = new ChromiumCookieDecryptor({
|
|
84
|
+
platform: this.platform,
|
|
85
|
+
appKeychainVariants: DISCORD_APP_KEYCHAIN_VARIANTS,
|
|
86
|
+
keyCache: this.keyCache,
|
|
87
|
+
keyCachePlatform: 'discord',
|
|
88
|
+
linuxKeyringAppNames: ['discord', 'Discord'],
|
|
89
|
+
})
|
|
122
90
|
}
|
|
123
91
|
|
|
124
92
|
getDiscordDirs(): string[] {
|
|
@@ -147,11 +115,11 @@ export class DiscordTokenExtractor {
|
|
|
147
115
|
getBrowserLevelDBDirs(): string[] {
|
|
148
116
|
const dirs: string[] = []
|
|
149
117
|
|
|
150
|
-
for (const browser of
|
|
151
|
-
const browserBase =
|
|
118
|
+
for (const browser of CHROMIUM_BROWSERS) {
|
|
119
|
+
const browserBase = getBrowserBasePath(browser, this.platform)
|
|
152
120
|
if (!browserBase) continue
|
|
153
121
|
|
|
154
|
-
const profileDirs =
|
|
122
|
+
const profileDirs = discoverBrowserProfileDirs(browserBase)
|
|
155
123
|
for (const profileDir of profileDirs) {
|
|
156
124
|
dirs.push(join(profileDir, 'Local Storage', 'leveldb'))
|
|
157
125
|
}
|
|
@@ -160,49 +128,6 @@ export class DiscordTokenExtractor {
|
|
|
160
128
|
return dirs
|
|
161
129
|
}
|
|
162
130
|
|
|
163
|
-
private getBrowserBasePath(browser: BrowserConfig): string | null {
|
|
164
|
-
let relative: string
|
|
165
|
-
|
|
166
|
-
switch (this.platform) {
|
|
167
|
-
case 'darwin':
|
|
168
|
-
relative = browser.darwin
|
|
169
|
-
if (!relative) return null
|
|
170
|
-
return join(homedir(), 'Library', 'Application Support', relative)
|
|
171
|
-
case 'linux':
|
|
172
|
-
relative = browser.linux
|
|
173
|
-
if (!relative) return null
|
|
174
|
-
return join(homedir(), '.config', relative)
|
|
175
|
-
case 'win32':
|
|
176
|
-
relative = browser.win32
|
|
177
|
-
if (!relative) return null
|
|
178
|
-
return join(
|
|
179
|
-
process.env.LOCALAPPDATA || join(homedir(), 'AppData', 'Local'),
|
|
180
|
-
relative,
|
|
181
|
-
)
|
|
182
|
-
default:
|
|
183
|
-
return null
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
private discoverProfileDirs(browserBase: string): string[] {
|
|
188
|
-
const dirs: string[] = []
|
|
189
|
-
|
|
190
|
-
dirs.push(join(browserBase, 'Default'))
|
|
191
|
-
|
|
192
|
-
if (!existsSync(browserBase)) return dirs
|
|
193
|
-
|
|
194
|
-
try {
|
|
195
|
-
const entries = readdirSync(browserBase, { withFileTypes: true })
|
|
196
|
-
for (const entry of entries) {
|
|
197
|
-
if (!entry.isDirectory()) continue
|
|
198
|
-
if (!/^Profile \d+$/i.test(entry.name)) continue
|
|
199
|
-
dirs.push(join(browserBase, entry.name))
|
|
200
|
-
}
|
|
201
|
-
} catch {}
|
|
202
|
-
|
|
203
|
-
return dirs
|
|
204
|
-
}
|
|
205
|
-
|
|
206
131
|
private findBrowserBaseDirForPath(path: string): string | null {
|
|
207
132
|
const parts = path.split(/[/\\]/)
|
|
208
133
|
for (let levels = 2; levels <= 5; levels++) {
|
|
@@ -214,24 +139,7 @@ export class DiscordTokenExtractor {
|
|
|
214
139
|
}
|
|
215
140
|
|
|
216
141
|
getKeychainVariants(): KeychainVariant[] {
|
|
217
|
-
return [
|
|
218
|
-
// Modern Discord (lowercase)
|
|
219
|
-
{ service: 'discord Safe Storage', account: 'discord Key' },
|
|
220
|
-
{ service: 'discordcanary Safe Storage', account: 'discordcanary Key' },
|
|
221
|
-
{ service: 'discordptb Safe Storage', account: 'discordptb Key' },
|
|
222
|
-
// Legacy Discord (capitalized)
|
|
223
|
-
{ service: 'Discord Safe Storage', account: 'Discord' },
|
|
224
|
-
{ service: 'Discord Canary Safe Storage', account: 'Discord Canary' },
|
|
225
|
-
{ service: 'Discord PTB Safe Storage', account: 'Discord PTB' },
|
|
226
|
-
// Browser keychain entries for fallback
|
|
227
|
-
{ service: 'Chrome Safe Storage', account: 'Chrome' },
|
|
228
|
-
{ service: 'Chrome Canary Safe Storage', account: 'Chrome Canary' },
|
|
229
|
-
{ service: 'Microsoft Edge Safe Storage', account: 'Microsoft Edge' },
|
|
230
|
-
{ service: 'Arc Safe Storage', account: 'Arc' },
|
|
231
|
-
{ service: 'Brave Safe Storage', account: 'Brave' },
|
|
232
|
-
{ service: 'Vivaldi Safe Storage', account: 'Vivaldi' },
|
|
233
|
-
{ service: 'Chromium Safe Storage', account: 'Chromium' },
|
|
234
|
-
]
|
|
142
|
+
return [...DISCORD_APP_KEYCHAIN_VARIANTS, ...BROWSER_KEYCHAIN_VARIANTS]
|
|
235
143
|
}
|
|
236
144
|
|
|
237
145
|
getVariantFromPath(path: string): DiscordVariant {
|
|
@@ -283,6 +191,8 @@ export class DiscordTokenExtractor {
|
|
|
283
191
|
private async loadCachedKey(): Promise<void> {
|
|
284
192
|
if (this.platform !== 'darwin') return
|
|
285
193
|
|
|
194
|
+
await this.decryptor.loadCachedKey()
|
|
195
|
+
|
|
286
196
|
const cached = await this.keyCache.get('discord')
|
|
287
197
|
if (cached) {
|
|
288
198
|
this.cachedKey = cached
|
|
@@ -290,7 +200,7 @@ export class DiscordTokenExtractor {
|
|
|
290
200
|
}
|
|
291
201
|
|
|
292
202
|
async clearKeyCache(): Promise<void> {
|
|
293
|
-
await this.
|
|
203
|
+
await this.decryptor.clearKeyCache()
|
|
294
204
|
this.cachedKey = null
|
|
295
205
|
}
|
|
296
206
|
|
|
@@ -445,27 +355,10 @@ export class DiscordTokenExtractor {
|
|
|
445
355
|
const encryptedKey = Buffer.from(localState.os_crypt.encrypted_key, 'base64')
|
|
446
356
|
|
|
447
357
|
const dpapiBlobKey = encryptedKey.subarray(5)
|
|
448
|
-
const masterKey = this.decryptDPAPI(dpapiBlobKey)
|
|
358
|
+
const masterKey = this.decryptor.decryptDPAPI(dpapiBlobKey)
|
|
449
359
|
if (!masterKey) return null
|
|
450
360
|
|
|
451
|
-
return this.decryptAESGCM(encryptedData, masterKey)
|
|
452
|
-
} catch {
|
|
453
|
-
return null
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
private decryptDPAPI(encryptedBlob: Buffer): Buffer | null {
|
|
458
|
-
try {
|
|
459
|
-
const b64 = encryptedBlob.toString('base64')
|
|
460
|
-
const psScript = `
|
|
461
|
-
Add-Type -AssemblyName System.Security
|
|
462
|
-
$bytes = [Convert]::FromBase64String('${b64}')
|
|
463
|
-
$decrypted = [Security.Cryptography.ProtectedData]::Unprotect($bytes, $null, 'CurrentUser')
|
|
464
|
-
[Convert]::ToBase64String($decrypted)
|
|
465
|
-
`.replace(/\n/g, ' ')
|
|
466
|
-
|
|
467
|
-
const result = execSync(`powershell -Command "${psScript}"`, { encoding: 'utf8' })
|
|
468
|
-
return Buffer.from(result.trim(), 'base64')
|
|
361
|
+
return this.decryptor.decryptAESGCM(encryptedData, masterKey)
|
|
469
362
|
} catch {
|
|
470
363
|
return null
|
|
471
364
|
}
|
|
@@ -473,7 +366,7 @@ export class DiscordTokenExtractor {
|
|
|
473
366
|
|
|
474
367
|
private decryptMacToken(encryptedData: Buffer, discordDir: string): string | null {
|
|
475
368
|
if (this.cachedKey) {
|
|
476
|
-
const decrypted = this.decryptAESCBC(encryptedData, this.cachedKey)
|
|
369
|
+
const decrypted = this.decryptor.decryptAESCBC(encryptedData, this.cachedKey)
|
|
477
370
|
if (decrypted && this.isValidToken(decrypted)) return decrypted
|
|
478
371
|
}
|
|
479
372
|
|
|
@@ -500,7 +393,7 @@ export class DiscordTokenExtractor {
|
|
|
500
393
|
).trim()
|
|
501
394
|
|
|
502
395
|
const key = pbkdf2Sync(password, 'saltysalt', 1003, 16, 'sha1')
|
|
503
|
-
const decrypted = this.decryptAESCBC(encryptedData, key)
|
|
396
|
+
const decrypted = this.decryptor.decryptAESCBC(encryptedData, key)
|
|
504
397
|
if (decrypted && this.isValidToken(decrypted)) {
|
|
505
398
|
this.cachedKey = key
|
|
506
399
|
this.keyCache.set('discord', key).catch(() => {})
|
|
@@ -514,63 +407,26 @@ export class DiscordTokenExtractor {
|
|
|
514
407
|
|
|
515
408
|
private decryptLinuxToken(encryptedData: Buffer): string | null {
|
|
516
409
|
const prefix = encryptedData.subarray(0, 3).toString()
|
|
410
|
+
|
|
517
411
|
if (prefix === 'v11') {
|
|
518
|
-
const
|
|
519
|
-
|
|
412
|
+
for (const appName of ['discord', 'Discord']) {
|
|
413
|
+
try {
|
|
414
|
+
const keyringPassword = this.getLinuxKeyringPassword(appName)
|
|
415
|
+
const key = pbkdf2Sync(keyringPassword, 'saltysalt', 1, 16, 'sha1')
|
|
416
|
+
const decrypted = this.decryptor.decryptAESCBC(encryptedData, key)
|
|
417
|
+
if (decrypted) return decrypted
|
|
418
|
+
} catch {}
|
|
419
|
+
}
|
|
520
420
|
}
|
|
521
|
-
|
|
421
|
+
|
|
522
422
|
const key = pbkdf2Sync('peanuts', 'saltysalt', 1, 16, 'sha1')
|
|
523
|
-
return this.decryptAESCBC(encryptedData, key)
|
|
423
|
+
return this.decryptor.decryptAESCBC(encryptedData, key)
|
|
524
424
|
}
|
|
525
425
|
|
|
526
426
|
private getLinuxKeyringPassword(appName: string): string {
|
|
527
427
|
return lookupLinuxKeyringPassword(appName)
|
|
528
428
|
}
|
|
529
429
|
|
|
530
|
-
private decryptV11LinuxToken(encryptedData: Buffer): string | null {
|
|
531
|
-
const appNames = ['discord', 'Discord']
|
|
532
|
-
for (const appName of appNames) {
|
|
533
|
-
try {
|
|
534
|
-
const keyringPassword = this.getLinuxKeyringPassword(appName)
|
|
535
|
-
const key = pbkdf2Sync(keyringPassword, 'saltysalt', 1, 16, 'sha1')
|
|
536
|
-
const result = this.decryptAESCBC(encryptedData, key)
|
|
537
|
-
if (result) return result
|
|
538
|
-
} catch {}
|
|
539
|
-
}
|
|
540
|
-
return null
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
private decryptAESCBC(encryptedData: Buffer, key: Buffer): string | null {
|
|
544
|
-
try {
|
|
545
|
-
const ciphertext = encryptedData.subarray(3)
|
|
546
|
-
const iv = Buffer.alloc(16, 0x20)
|
|
547
|
-
|
|
548
|
-
const decipher = createDecipheriv('aes-128-cbc', key, iv)
|
|
549
|
-
decipher.setAutoPadding(true)
|
|
550
|
-
|
|
551
|
-
const decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()])
|
|
552
|
-
return decrypted.toString('utf8')
|
|
553
|
-
} catch {
|
|
554
|
-
return null
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
private decryptAESGCM(encryptedData: Buffer, key: Buffer): string | null {
|
|
559
|
-
try {
|
|
560
|
-
const iv = encryptedData.subarray(3, 15)
|
|
561
|
-
const authTag = encryptedData.subarray(-16)
|
|
562
|
-
const ciphertext = encryptedData.subarray(15, -16)
|
|
563
|
-
|
|
564
|
-
const decipher = createDecipheriv('aes-256-gcm', key, iv)
|
|
565
|
-
decipher.setAuthTag(authTag)
|
|
566
|
-
|
|
567
|
-
const decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()])
|
|
568
|
-
return decrypted.toString('utf8')
|
|
569
|
-
} catch {
|
|
570
|
-
return null
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
|
|
574
430
|
async isDiscordRunning(variant?: DiscordVariant): Promise<boolean> {
|
|
575
431
|
const variants = variant ? [variant] : (['stable', 'canary', 'ptb'] as DiscordVariant[])
|
|
576
432
|
|
|
@@ -31,10 +31,7 @@ export class DiscordBotClient {
|
|
|
31
31
|
const credManager = new DiscordBotCredentialManager()
|
|
32
32
|
const creds = await credManager.getCredentials()
|
|
33
33
|
if (!creds?.token) {
|
|
34
|
-
throw new DiscordBotError(
|
|
35
|
-
'No Discord bot credentials found. Run "auth set <token>" first.',
|
|
36
|
-
'no_credentials',
|
|
37
|
-
)
|
|
34
|
+
throw new DiscordBotError('No Discord bot credentials found. Run "auth set <token>" first.', 'no_credentials')
|
|
38
35
|
}
|
|
39
36
|
return this.login({ token: creds.token })
|
|
40
37
|
}
|
|
@@ -21,7 +21,9 @@ const mockListGuilds = mock(() =>
|
|
|
21
21
|
|
|
22
22
|
mock.module('../client', () => ({
|
|
23
23
|
DiscordBotClient: class MockDiscordBotClient {
|
|
24
|
-
async login(_credentials?: any) {
|
|
24
|
+
async login(_credentials?: any) {
|
|
25
|
+
return this
|
|
26
|
+
}
|
|
25
27
|
testAuth = mockTestAuth
|
|
26
28
|
listGuilds = mockListGuilds
|
|
27
29
|
},
|
|
@@ -31,7 +31,9 @@ const mockResolveChannel = mock((_guildId: string, channel: string) => {
|
|
|
31
31
|
|
|
32
32
|
mock.module('../client', () => ({
|
|
33
33
|
DiscordBotClient: class MockDiscordBotClient {
|
|
34
|
-
async login(_credentials?: any) {
|
|
34
|
+
async login(_credentials?: any) {
|
|
35
|
+
return this
|
|
36
|
+
}
|
|
35
37
|
listChannels = mockListChannels
|
|
36
38
|
getChannel = mockGetChannel
|
|
37
39
|
resolveChannel = mockResolveChannel
|
|
@@ -68,7 +68,9 @@ const mockResolveChannel = mock((_guildId: string, channel: string) => {
|
|
|
68
68
|
|
|
69
69
|
mock.module('../client', () => ({
|
|
70
70
|
DiscordBotClient: class MockDiscordBotClient {
|
|
71
|
-
async login(_credentials?: any) {
|
|
71
|
+
async login(_credentials?: any) {
|
|
72
|
+
return this
|
|
73
|
+
}
|
|
72
74
|
sendMessage = mockSendMessage
|
|
73
75
|
getMessages = mockGetMessages
|
|
74
76
|
getMessage = mockGetMessage
|
|
@@ -22,7 +22,9 @@ const mockGetGuild = mock((guildId: string) =>
|
|
|
22
22
|
|
|
23
23
|
mock.module('../client', () => ({
|
|
24
24
|
DiscordBotClient: class MockDiscordBotClient {
|
|
25
|
-
async login(_credentials?: any) {
|
|
25
|
+
async login(_credentials?: any) {
|
|
26
|
+
return this
|
|
27
|
+
}
|
|
26
28
|
listGuilds = mockListGuilds
|
|
27
29
|
getGuild = mockGetGuild
|
|
28
30
|
},
|
|
@@ -41,7 +41,9 @@ const mockListUsers = mock((_guildId: string) =>
|
|
|
41
41
|
|
|
42
42
|
mock.module('../client', () => ({
|
|
43
43
|
DiscordBotClient: class MockDiscordBotClient {
|
|
44
|
-
async login(_credentials?: any) {
|
|
44
|
+
async login(_credentials?: any) {
|
|
45
|
+
return this
|
|
46
|
+
}
|
|
45
47
|
listChannels = mockListChannels
|
|
46
48
|
getMessages = mockGetMessages
|
|
47
49
|
listUsers = mockListUsers
|
|
@@ -84,23 +86,17 @@ describe('snapshot command', () => {
|
|
|
84
86
|
process.env = originalEnv
|
|
85
87
|
})
|
|
86
88
|
|
|
87
|
-
describe('default (
|
|
88
|
-
test('returns channels with
|
|
89
|
+
describe('default (brief)', () => {
|
|
90
|
+
test('returns channels with id and name only', async () => {
|
|
89
91
|
const manager = await setupManager(tempDir)
|
|
90
92
|
|
|
91
93
|
const result = await snapshotAction({ _credManager: manager })
|
|
92
94
|
|
|
93
95
|
expect(result.server_id).toBe('guild1')
|
|
94
96
|
expect(result.channels).toHaveLength(2)
|
|
95
|
-
expect(result.channels?.[0]
|
|
96
|
-
expect(result.channels?.[
|
|
97
|
-
expect(result.
|
|
98
|
-
expect(result.channels?.[0].messages?.[0]).toEqual({
|
|
99
|
-
id: 'msg1-ch1',
|
|
100
|
-
author: 'alice',
|
|
101
|
-
content: 'Hello from ch1',
|
|
102
|
-
timestamp: '2025-01-01T00:00:00Z',
|
|
103
|
-
})
|
|
97
|
+
expect(result.channels?.[0]).toEqual({ id: 'ch1', name: 'general' })
|
|
98
|
+
expect(result.channels?.[1]).toEqual({ id: 'ch2', name: 'random' })
|
|
99
|
+
expect(result.hint).toBeDefined()
|
|
104
100
|
})
|
|
105
101
|
|
|
106
102
|
test('filters out non-text channels', async () => {
|
|
@@ -112,11 +108,39 @@ describe('snapshot command', () => {
|
|
|
112
108
|
expect(channelNames).not.toContain('voice')
|
|
113
109
|
})
|
|
114
110
|
|
|
115
|
-
test('
|
|
111
|
+
test('does not fetch messages', async () => {
|
|
116
112
|
const manager = await setupManager(tempDir)
|
|
117
113
|
|
|
118
114
|
await snapshotAction({ _credManager: manager })
|
|
119
115
|
|
|
116
|
+
expect(mockGetMessages).not.toHaveBeenCalled()
|
|
117
|
+
})
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
describe('--full (channels + messages)', () => {
|
|
121
|
+
test('returns channels with recent messages', async () => {
|
|
122
|
+
const manager = await setupManager(tempDir)
|
|
123
|
+
|
|
124
|
+
const result = await snapshotAction({ _credManager: manager, full: true })
|
|
125
|
+
|
|
126
|
+
expect(result.server_id).toBe('guild1')
|
|
127
|
+
expect(result.channels).toHaveLength(2)
|
|
128
|
+
expect(result.channels?.[0].id).toBe('ch1')
|
|
129
|
+
expect(result.channels?.[0].name).toBe('general')
|
|
130
|
+
expect(result.channels?.[0].messages).toHaveLength(2)
|
|
131
|
+
expect(result.channels?.[0].messages?.[0]).toEqual({
|
|
132
|
+
id: 'msg1-ch1',
|
|
133
|
+
author: 'alice',
|
|
134
|
+
content: 'Hello from ch1',
|
|
135
|
+
timestamp: '2025-01-01T00:00:00Z',
|
|
136
|
+
})
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
test('fetches messages in parallel for all text channels', async () => {
|
|
140
|
+
const manager = await setupManager(tempDir)
|
|
141
|
+
|
|
142
|
+
await snapshotAction({ _credManager: manager, full: true })
|
|
143
|
+
|
|
120
144
|
expect(mockGetMessages).toHaveBeenCalledTimes(2)
|
|
121
145
|
expect(mockGetMessages).toHaveBeenCalledWith('ch1', 5)
|
|
122
146
|
expect(mockGetMessages).toHaveBeenCalledWith('ch2', 5)
|
|
@@ -125,7 +149,7 @@ describe('snapshot command', () => {
|
|
|
125
149
|
test('respects --limit option', async () => {
|
|
126
150
|
const manager = await setupManager(tempDir)
|
|
127
151
|
|
|
128
|
-
await snapshotAction({ _credManager: manager, limit: 10 })
|
|
152
|
+
await snapshotAction({ _credManager: manager, full: true, limit: 10 })
|
|
129
153
|
|
|
130
154
|
expect(mockGetMessages).toHaveBeenCalledWith('ch1', 10)
|
|
131
155
|
expect(mockGetMessages).toHaveBeenCalledWith('ch2', 10)
|
|
@@ -134,17 +158,17 @@ describe('snapshot command', () => {
|
|
|
134
158
|
test('defaults limit to 5', async () => {
|
|
135
159
|
const manager = await setupManager(tempDir)
|
|
136
160
|
|
|
137
|
-
await snapshotAction({ _credManager: manager })
|
|
161
|
+
await snapshotAction({ _credManager: manager, full: true })
|
|
138
162
|
|
|
139
163
|
expect(mockGetMessages).toHaveBeenCalledWith('ch1', 5)
|
|
140
164
|
})
|
|
141
165
|
})
|
|
142
166
|
|
|
143
|
-
describe('--channels-only', () => {
|
|
167
|
+
describe('--full --channels-only', () => {
|
|
144
168
|
test('returns only channel list without messages', async () => {
|
|
145
169
|
const manager = await setupManager(tempDir)
|
|
146
170
|
|
|
147
|
-
const result = await snapshotAction({ _credManager: manager, channelsOnly: true })
|
|
171
|
+
const result = await snapshotAction({ _credManager: manager, full: true, channelsOnly: true })
|
|
148
172
|
|
|
149
173
|
expect(result.server_id).toBe('guild1')
|
|
150
174
|
expect(result.channels).toHaveLength(2)
|
|
@@ -154,11 +178,11 @@ describe('snapshot command', () => {
|
|
|
154
178
|
})
|
|
155
179
|
})
|
|
156
180
|
|
|
157
|
-
describe('--users-only', () => {
|
|
181
|
+
describe('--full --users-only', () => {
|
|
158
182
|
test('returns only user list', async () => {
|
|
159
183
|
const manager = await setupManager(tempDir)
|
|
160
184
|
|
|
161
|
-
const result = await snapshotAction({ _credManager: manager, usersOnly: true })
|
|
185
|
+
const result = await snapshotAction({ _credManager: manager, full: true, usersOnly: true })
|
|
162
186
|
|
|
163
187
|
expect(result.server_id).toBe('guild1')
|
|
164
188
|
expect(result.users).toHaveLength(3)
|
|
@@ -10,6 +10,7 @@ import { getClient } from './shared'
|
|
|
10
10
|
interface SnapshotOption extends BotOption {
|
|
11
11
|
channelsOnly?: boolean
|
|
12
12
|
usersOnly?: boolean
|
|
13
|
+
full?: boolean
|
|
13
14
|
limit?: number
|
|
14
15
|
}
|
|
15
16
|
|
|
@@ -31,6 +32,7 @@ interface SnapshotResult {
|
|
|
31
32
|
username: string
|
|
32
33
|
global_name: string | null
|
|
33
34
|
}>
|
|
35
|
+
hint?: string
|
|
34
36
|
error?: string
|
|
35
37
|
}
|
|
36
38
|
|
|
@@ -43,53 +45,66 @@ export async function snapshotAction(options: SnapshotOption): Promise<SnapshotR
|
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
const client = await getClient(options)
|
|
46
|
-
const limit = options.limit ?? 5
|
|
47
48
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
49
|
+
const isFull = options.full || options.channelsOnly || options.usersOnly
|
|
50
|
+
if (isFull) {
|
|
51
|
+
const limit = options.limit ?? 5
|
|
52
|
+
|
|
53
|
+
if (options.usersOnly) {
|
|
54
|
+
const users = await client.listUsers(serverId)
|
|
55
|
+
return {
|
|
56
|
+
server_id: serverId,
|
|
57
|
+
users: users.map((u) => ({
|
|
58
|
+
id: u.id,
|
|
59
|
+
username: u.username,
|
|
60
|
+
global_name: u.global_name ?? null,
|
|
61
|
+
})),
|
|
62
|
+
}
|
|
57
63
|
}
|
|
58
|
-
}
|
|
59
64
|
|
|
60
|
-
|
|
61
|
-
|
|
65
|
+
const allChannels = await client.listChannels(serverId)
|
|
66
|
+
const textChannels = allChannels.filter((ch) => ch.type === 0)
|
|
67
|
+
|
|
68
|
+
if (options.channelsOnly) {
|
|
69
|
+
return {
|
|
70
|
+
server_id: serverId,
|
|
71
|
+
channels: textChannels.map((ch) => ({
|
|
72
|
+
id: ch.id,
|
|
73
|
+
name: ch.name,
|
|
74
|
+
type: ch.type,
|
|
75
|
+
})),
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const channelsWithMessages = await Promise.all(
|
|
80
|
+
textChannels.map(async (ch) => {
|
|
81
|
+
const messages = await client.getMessages(ch.id, limit)
|
|
82
|
+
return {
|
|
83
|
+
id: ch.id,
|
|
84
|
+
name: ch.name,
|
|
85
|
+
messages: messages.map((msg) => ({
|
|
86
|
+
id: msg.id,
|
|
87
|
+
author: msg.author.username,
|
|
88
|
+
content: msg.content,
|
|
89
|
+
timestamp: msg.timestamp,
|
|
90
|
+
})),
|
|
91
|
+
}
|
|
92
|
+
}),
|
|
93
|
+
)
|
|
62
94
|
|
|
63
|
-
if (options.channelsOnly) {
|
|
64
95
|
return {
|
|
65
96
|
server_id: serverId,
|
|
66
|
-
channels:
|
|
67
|
-
id: ch.id,
|
|
68
|
-
name: ch.name,
|
|
69
|
-
type: ch.type,
|
|
70
|
-
})),
|
|
97
|
+
channels: channelsWithMessages,
|
|
71
98
|
}
|
|
72
99
|
}
|
|
73
100
|
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
const messages = await client.getMessages(ch.id, limit)
|
|
77
|
-
return {
|
|
78
|
-
id: ch.id,
|
|
79
|
-
name: ch.name,
|
|
80
|
-
messages: messages.map((msg) => ({
|
|
81
|
-
id: msg.id,
|
|
82
|
-
author: msg.author.username,
|
|
83
|
-
content: msg.content,
|
|
84
|
-
timestamp: msg.timestamp,
|
|
85
|
-
})),
|
|
86
|
-
}
|
|
87
|
-
}),
|
|
88
|
-
)
|
|
101
|
+
const allChannels = await client.listChannels(serverId)
|
|
102
|
+
const textChannels = allChannels.filter((ch) => ch.type === 0)
|
|
89
103
|
|
|
90
104
|
return {
|
|
91
105
|
server_id: serverId,
|
|
92
|
-
channels:
|
|
106
|
+
channels: textChannels.map((ch) => ({ id: ch.id, name: ch.name })),
|
|
107
|
+
hint: "Use 'message list <channel>' for messages, 'channel info <channel>' for channel details, 'user list' for members.",
|
|
93
108
|
}
|
|
94
109
|
} catch (error) {
|
|
95
110
|
return { error: (error as Error).message }
|
|
@@ -97,10 +112,11 @@ export async function snapshotAction(options: SnapshotOption): Promise<SnapshotR
|
|
|
97
112
|
}
|
|
98
113
|
|
|
99
114
|
export const snapshotCommand = new Command('snapshot')
|
|
100
|
-
.description('Server overview for AI
|
|
115
|
+
.description('Server overview for AI agents (brief by default, use --full for comprehensive data)')
|
|
116
|
+
.option('--full', 'Include messages and members (verbose)')
|
|
101
117
|
.option('--channels-only', 'List channels only, skip messages')
|
|
102
118
|
.option('--users-only', 'List users only')
|
|
103
|
-
.option('--limit <n>', 'Messages per channel (default: 5)', '5')
|
|
119
|
+
.option('--limit <n>', 'Messages per channel with --full (default: 5)', '5')
|
|
104
120
|
.option('--server <id>', 'Use specific server')
|
|
105
121
|
.option('--bot <id>', 'Use specific bot')
|
|
106
122
|
.option('--pretty', 'Pretty print JSON output')
|
|
@@ -108,6 +124,7 @@ export const snapshotCommand = new Command('snapshot')
|
|
|
108
124
|
try {
|
|
109
125
|
const result = await snapshotAction({
|
|
110
126
|
...options,
|
|
127
|
+
full: options.full,
|
|
111
128
|
limit: parseInt(options.limit, 10),
|
|
112
129
|
})
|
|
113
130
|
console.log(formatOutput(result, options.pretty))
|
|
@@ -29,7 +29,9 @@ const mockResolveChannel = mock((_guildId: string, channel: string) => {
|
|
|
29
29
|
|
|
30
30
|
mock.module('../client', () => ({
|
|
31
31
|
DiscordBotClient: class MockDiscordBotClient {
|
|
32
|
-
async login(_credentials?: any) {
|
|
32
|
+
async login(_credentials?: any) {
|
|
33
|
+
return this
|
|
34
|
+
}
|
|
33
35
|
createThread = mockCreateThread
|
|
34
36
|
archiveThread = mockArchiveThread
|
|
35
37
|
resolveChannel = mockResolveChannel
|