agent-messenger 1.0.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/commands/release.md +92 -0
- package/.claude-plugin/README.md +144 -0
- package/.claude-plugin/marketplace.json +37 -0
- package/.claude-plugin/plugin.json +17 -0
- package/.github/workflows/ci.yml +30 -0
- package/CLAUDE.md +106 -0
- package/CONTRIBUTING.md +131 -0
- package/README.md +140 -0
- package/biome.json +34 -0
- package/bun.lock +252 -0
- package/dist/cli.d.ts +5 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +21 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/auth.d.ts +3 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +140 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/channel.d.ts +3 -0
- package/dist/commands/channel.d.ts.map +1 -0
- package/dist/commands/channel.js +118 -0
- package/dist/commands/channel.js.map +1 -0
- package/dist/commands/file.d.ts +3 -0
- package/dist/commands/file.d.ts.map +1 -0
- package/dist/commands/file.js +113 -0
- package/dist/commands/file.js.map +1 -0
- package/dist/commands/index.d.ts +9 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +9 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/message.d.ts +3 -0
- package/dist/commands/message.d.ts.map +1 -0
- package/dist/commands/message.js +214 -0
- package/dist/commands/message.js.map +1 -0
- package/dist/commands/reaction.d.ts +3 -0
- package/dist/commands/reaction.d.ts.map +1 -0
- package/dist/commands/reaction.js +100 -0
- package/dist/commands/reaction.js.map +1 -0
- package/dist/commands/snapshot.d.ts +3 -0
- package/dist/commands/snapshot.d.ts.map +1 -0
- package/dist/commands/snapshot.js +88 -0
- package/dist/commands/snapshot.js.map +1 -0
- package/dist/commands/user.d.ts +3 -0
- package/dist/commands/user.d.ts.map +1 -0
- package/dist/commands/user.js +96 -0
- package/dist/commands/user.js.map +1 -0
- package/dist/commands/workspace.d.ts +3 -0
- package/dist/commands/workspace.d.ts.map +1 -0
- package/dist/commands/workspace.js +89 -0
- package/dist/commands/workspace.js.map +1 -0
- package/dist/lib/credential-manager.d.ts +13 -0
- package/dist/lib/credential-manager.d.ts.map +1 -0
- package/dist/lib/credential-manager.js +58 -0
- package/dist/lib/credential-manager.js.map +1 -0
- package/dist/lib/index.d.ts +3 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +3 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/ref-manager.d.ts +26 -0
- package/dist/lib/ref-manager.d.ts.map +1 -0
- package/dist/lib/ref-manager.js +92 -0
- package/dist/lib/ref-manager.js.map +1 -0
- package/dist/lib/slack-client.d.ts +37 -0
- package/dist/lib/slack-client.d.ts.map +1 -0
- package/dist/lib/slack-client.js +379 -0
- package/dist/lib/slack-client.js.map +1 -0
- package/dist/lib/token-extractor.d.ts +28 -0
- package/dist/lib/token-extractor.d.ts.map +1 -0
- package/dist/lib/token-extractor.js +401 -0
- package/dist/lib/token-extractor.js.map +1 -0
- package/dist/package.json +37 -0
- package/dist/src/cli.d.ts +5 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +22 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/platforms/discord/cli.d.ts +5 -0
- package/dist/src/platforms/discord/cli.d.ts.map +1 -0
- package/dist/src/platforms/discord/cli.js +22 -0
- package/dist/src/platforms/discord/cli.js.map +1 -0
- package/dist/src/platforms/discord/client.d.ts +34 -0
- package/dist/src/platforms/discord/client.d.ts.map +1 -0
- package/dist/src/platforms/discord/client.js +187 -0
- package/dist/src/platforms/discord/client.js.map +1 -0
- package/dist/src/platforms/discord/client.test.d.ts +2 -0
- package/dist/src/platforms/discord/client.test.d.ts.map +1 -0
- package/dist/src/platforms/discord/client.test.js +367 -0
- package/dist/src/platforms/discord/client.test.js.map +1 -0
- package/dist/src/platforms/discord/commands/auth.d.ts +13 -0
- package/dist/src/platforms/discord/commands/auth.d.ts.map +1 -0
- package/dist/src/platforms/discord/commands/auth.js +155 -0
- package/dist/src/platforms/discord/commands/auth.js.map +1 -0
- package/dist/src/platforms/discord/commands/auth.test.d.ts +2 -0
- package/dist/src/platforms/discord/commands/auth.test.d.ts.map +1 -0
- package/dist/src/platforms/discord/commands/auth.test.js +65 -0
- package/dist/src/platforms/discord/commands/auth.test.js.map +1 -0
- package/dist/src/platforms/discord/commands/channel.d.ts +13 -0
- package/dist/src/platforms/discord/commands/channel.d.ts.map +1 -0
- package/dist/src/platforms/discord/commands/channel.js +99 -0
- package/dist/src/platforms/discord/commands/channel.js.map +1 -0
- package/dist/src/platforms/discord/commands/channel.test.d.ts +2 -0
- package/dist/src/platforms/discord/commands/channel.test.d.ts.map +1 -0
- package/dist/src/platforms/discord/commands/channel.test.js +136 -0
- package/dist/src/platforms/discord/commands/channel.test.js.map +1 -0
- package/dist/src/platforms/discord/commands/file.d.ts +13 -0
- package/dist/src/platforms/discord/commands/file.d.ts.map +1 -0
- package/dist/src/platforms/discord/commands/file.js +99 -0
- package/dist/src/platforms/discord/commands/file.js.map +1 -0
- package/dist/src/platforms/discord/commands/file.test.d.ts +2 -0
- package/dist/src/platforms/discord/commands/file.test.d.ts.map +1 -0
- package/dist/src/platforms/discord/commands/file.test.js +83 -0
- package/dist/src/platforms/discord/commands/file.test.js.map +1 -0
- package/dist/src/platforms/discord/commands/guild.d.ts +15 -0
- package/dist/src/platforms/discord/commands/guild.d.ts.map +1 -0
- package/dist/src/platforms/discord/commands/guild.js +102 -0
- package/dist/src/platforms/discord/commands/guild.js.map +1 -0
- package/dist/src/platforms/discord/commands/guild.test.d.ts +2 -0
- package/dist/src/platforms/discord/commands/guild.test.d.ts.map +1 -0
- package/dist/src/platforms/discord/commands/guild.test.js +100 -0
- package/dist/src/platforms/discord/commands/guild.test.js.map +1 -0
- package/dist/src/platforms/discord/commands/index.d.ts +9 -0
- package/dist/src/platforms/discord/commands/index.d.ts.map +1 -0
- package/dist/src/platforms/discord/commands/index.js +9 -0
- package/dist/src/platforms/discord/commands/index.js.map +1 -0
- package/dist/src/platforms/discord/commands/message.d.ts +17 -0
- package/dist/src/platforms/discord/commands/message.d.ts.map +1 -0
- package/dist/src/platforms/discord/commands/message.js +131 -0
- package/dist/src/platforms/discord/commands/message.js.map +1 -0
- package/dist/src/platforms/discord/commands/message.test.d.ts +2 -0
- package/dist/src/platforms/discord/commands/message.test.d.ts.map +1 -0
- package/dist/src/platforms/discord/commands/message.test.js +91 -0
- package/dist/src/platforms/discord/commands/message.test.js.map +1 -0
- package/dist/src/platforms/discord/commands/reaction.d.ts +12 -0
- package/dist/src/platforms/discord/commands/reaction.d.ts.map +1 -0
- package/dist/src/platforms/discord/commands/reaction.js +99 -0
- package/dist/src/platforms/discord/commands/reaction.js.map +1 -0
- package/dist/src/platforms/discord/commands/reaction.test.d.ts +2 -0
- package/dist/src/platforms/discord/commands/reaction.test.d.ts.map +1 -0
- package/dist/src/platforms/discord/commands/reaction.test.js +115 -0
- package/dist/src/platforms/discord/commands/reaction.test.js.map +1 -0
- package/dist/src/platforms/discord/commands/snapshot.d.ts +9 -0
- package/dist/src/platforms/discord/commands/snapshot.d.ts.map +1 -0
- package/dist/src/platforms/discord/commands/snapshot.js +80 -0
- package/dist/src/platforms/discord/commands/snapshot.js.map +1 -0
- package/dist/src/platforms/discord/commands/snapshot.test.d.ts +2 -0
- package/dist/src/platforms/discord/commands/snapshot.test.d.ts.map +1 -0
- package/dist/src/platforms/discord/commands/snapshot.test.js +25 -0
- package/dist/src/platforms/discord/commands/snapshot.test.js.map +1 -0
- package/dist/src/platforms/discord/commands/user.d.ts +3 -0
- package/dist/src/platforms/discord/commands/user.d.ts.map +1 -0
- package/dist/src/platforms/discord/commands/user.js +94 -0
- package/dist/src/platforms/discord/commands/user.js.map +1 -0
- package/dist/src/platforms/discord/commands/user.test.d.ts +2 -0
- package/dist/src/platforms/discord/commands/user.test.d.ts.map +1 -0
- package/dist/src/platforms/discord/commands/user.test.js +103 -0
- package/dist/src/platforms/discord/commands/user.test.js.map +1 -0
- package/dist/src/platforms/discord/credential-manager.d.ts +33 -0
- package/dist/src/platforms/discord/credential-manager.d.ts.map +1 -0
- package/dist/src/platforms/discord/credential-manager.js +73 -0
- package/dist/src/platforms/discord/credential-manager.js.map +1 -0
- package/dist/src/platforms/discord/credential-manager.test.d.ts +2 -0
- package/dist/src/platforms/discord/credential-manager.test.d.ts.map +1 -0
- package/dist/src/platforms/discord/credential-manager.test.js +136 -0
- package/dist/src/platforms/discord/credential-manager.test.js.map +1 -0
- package/dist/src/platforms/discord/token-extractor.d.ts +55 -0
- package/dist/src/platforms/discord/token-extractor.d.ts.map +1 -0
- package/dist/src/platforms/discord/token-extractor.js +462 -0
- package/dist/src/platforms/discord/token-extractor.js.map +1 -0
- package/dist/src/platforms/discord/token-extractor.test.d.ts +2 -0
- package/dist/src/platforms/discord/token-extractor.test.d.ts.map +1 -0
- package/dist/src/platforms/discord/token-extractor.test.js +789 -0
- package/dist/src/platforms/discord/token-extractor.test.js.map +1 -0
- package/dist/src/platforms/discord/types.d.ts +251 -0
- package/dist/src/platforms/discord/types.d.ts.map +1 -0
- package/dist/src/platforms/discord/types.js +74 -0
- package/dist/src/platforms/discord/types.js.map +1 -0
- package/dist/src/platforms/discord/types.test.d.ts +2 -0
- package/dist/src/platforms/discord/types.test.d.ts.map +1 -0
- package/dist/src/platforms/discord/types.test.js +211 -0
- package/dist/src/platforms/discord/types.test.js.map +1 -0
- package/dist/src/platforms/slack/cli.d.ts +5 -0
- package/dist/src/platforms/slack/cli.d.ts.map +1 -0
- package/dist/src/platforms/slack/cli.js +22 -0
- package/dist/src/platforms/slack/cli.js.map +1 -0
- package/dist/src/platforms/slack/client.d.ts +47 -0
- package/dist/src/platforms/slack/client.d.ts.map +1 -0
- package/dist/src/platforms/slack/client.js +412 -0
- package/dist/src/platforms/slack/client.js.map +1 -0
- package/dist/src/platforms/slack/commands/auth.d.ts +3 -0
- package/dist/src/platforms/slack/commands/auth.d.ts.map +1 -0
- package/dist/src/platforms/slack/commands/auth.js +156 -0
- package/dist/src/platforms/slack/commands/auth.js.map +1 -0
- package/dist/src/platforms/slack/commands/channel.d.ts +3 -0
- package/dist/src/platforms/slack/commands/channel.d.ts.map +1 -0
- package/dist/src/platforms/slack/commands/channel.js +118 -0
- package/dist/src/platforms/slack/commands/channel.js.map +1 -0
- package/dist/src/platforms/slack/commands/file.d.ts +3 -0
- package/dist/src/platforms/slack/commands/file.d.ts.map +1 -0
- package/dist/src/platforms/slack/commands/file.js +113 -0
- package/dist/src/platforms/slack/commands/file.js.map +1 -0
- package/dist/src/platforms/slack/commands/index.d.ts +9 -0
- package/dist/src/platforms/slack/commands/index.d.ts.map +1 -0
- package/dist/src/platforms/slack/commands/index.js +9 -0
- package/dist/src/platforms/slack/commands/index.js.map +1 -0
- package/dist/src/platforms/slack/commands/message.d.ts +3 -0
- package/dist/src/platforms/slack/commands/message.d.ts.map +1 -0
- package/dist/src/platforms/slack/commands/message.js +263 -0
- package/dist/src/platforms/slack/commands/message.js.map +1 -0
- package/dist/src/platforms/slack/commands/reaction.d.ts +3 -0
- package/dist/src/platforms/slack/commands/reaction.d.ts.map +1 -0
- package/dist/src/platforms/slack/commands/reaction.js +100 -0
- package/dist/src/platforms/slack/commands/reaction.js.map +1 -0
- package/dist/src/platforms/slack/commands/snapshot.d.ts +3 -0
- package/dist/src/platforms/slack/commands/snapshot.d.ts.map +1 -0
- package/dist/src/platforms/slack/commands/snapshot.js +87 -0
- package/dist/src/platforms/slack/commands/snapshot.js.map +1 -0
- package/dist/src/platforms/slack/commands/user.d.ts +3 -0
- package/dist/src/platforms/slack/commands/user.d.ts.map +1 -0
- package/dist/src/platforms/slack/commands/user.js +96 -0
- package/dist/src/platforms/slack/commands/user.js.map +1 -0
- package/dist/src/platforms/slack/commands/workspace.d.ts +3 -0
- package/dist/src/platforms/slack/commands/workspace.d.ts.map +1 -0
- package/dist/src/platforms/slack/commands/workspace.js +89 -0
- package/dist/src/platforms/slack/commands/workspace.js.map +1 -0
- package/dist/src/platforms/slack/credential-manager.d.ts +13 -0
- package/dist/src/platforms/slack/credential-manager.d.ts.map +1 -0
- package/dist/src/platforms/slack/credential-manager.js +58 -0
- package/dist/src/platforms/slack/credential-manager.js.map +1 -0
- package/dist/src/platforms/slack/index.d.ts +3 -0
- package/dist/src/platforms/slack/index.d.ts.map +1 -0
- package/dist/src/platforms/slack/index.js +3 -0
- package/dist/src/platforms/slack/index.js.map +1 -0
- package/dist/src/platforms/slack/token-extractor.d.ts +28 -0
- package/dist/src/platforms/slack/token-extractor.d.ts.map +1 -0
- package/dist/src/platforms/slack/token-extractor.js +401 -0
- package/dist/src/platforms/slack/token-extractor.js.map +1 -0
- package/dist/src/platforms/slack/types.d.ts +369 -0
- package/dist/src/platforms/slack/types.d.ts.map +1 -0
- package/dist/src/platforms/slack/types.js +92 -0
- package/dist/src/platforms/slack/types.js.map +1 -0
- package/dist/src/shared/utils/concurrency.d.ts +2 -0
- package/dist/src/shared/utils/concurrency.d.ts.map +1 -0
- package/dist/src/shared/utils/concurrency.js +14 -0
- package/dist/src/shared/utils/concurrency.js.map +1 -0
- package/dist/src/shared/utils/concurrency.test.d.ts +2 -0
- package/dist/src/shared/utils/concurrency.test.d.ts.map +1 -0
- package/dist/src/shared/utils/concurrency.test.js +39 -0
- package/dist/src/shared/utils/concurrency.test.js.map +1 -0
- package/dist/src/shared/utils/error-handler.d.ts +2 -0
- package/dist/src/shared/utils/error-handler.d.ts.map +1 -0
- package/dist/src/shared/utils/error-handler.js +5 -0
- package/dist/src/shared/utils/error-handler.js.map +1 -0
- package/dist/src/shared/utils/output.d.ts +2 -0
- package/dist/src/shared/utils/output.d.ts.map +1 -0
- package/dist/src/shared/utils/output.js +4 -0
- package/dist/src/shared/utils/output.js.map +1 -0
- package/dist/tests/cli.test.d.ts +2 -0
- package/dist/tests/cli.test.d.ts.map +1 -0
- package/dist/tests/cli.test.js +83 -0
- package/dist/tests/cli.test.js.map +1 -0
- package/dist/tests/commands/.test-slack-data/Local Storage/leveldb/CURRENT +1 -0
- package/dist/tests/commands/.test-slack-data/Local Storage/leveldb/LOCK +0 -0
- package/dist/tests/commands/.test-slack-data/Local Storage/leveldb/LOG +3 -0
- package/dist/tests/commands/.test-slack-data/Local Storage/leveldb/LOG.old +1 -0
- package/dist/tests/commands/.test-slack-data/Local Storage/leveldb/MANIFEST-000004 +0 -0
- package/dist/tests/commands/auth.test.d.ts +2 -0
- package/dist/tests/commands/auth.test.d.ts.map +1 -0
- package/dist/tests/commands/auth.test.js +304 -0
- package/dist/tests/commands/auth.test.js.map +1 -0
- package/dist/tests/commands/channel.test.d.ts +2 -0
- package/dist/tests/commands/channel.test.d.ts.map +1 -0
- package/dist/tests/commands/channel.test.js +166 -0
- package/dist/tests/commands/channel.test.js.map +1 -0
- package/dist/tests/commands/file.test.d.ts +2 -0
- package/dist/tests/commands/file.test.d.ts.map +1 -0
- package/dist/tests/commands/file.test.js +175 -0
- package/dist/tests/commands/file.test.js.map +1 -0
- package/dist/tests/commands/message.test.d.ts +2 -0
- package/dist/tests/commands/message.test.d.ts.map +1 -0
- package/dist/tests/commands/message.test.js +293 -0
- package/dist/tests/commands/message.test.js.map +1 -0
- package/dist/tests/commands/reaction.test.d.ts +2 -0
- package/dist/tests/commands/reaction.test.d.ts.map +1 -0
- package/dist/tests/commands/reaction.test.js +84 -0
- package/dist/tests/commands/reaction.test.js.map +1 -0
- package/dist/tests/commands/snapshot.test.d.ts +2 -0
- package/dist/tests/commands/snapshot.test.d.ts.map +1 -0
- package/dist/tests/commands/snapshot.test.js +280 -0
- package/dist/tests/commands/snapshot.test.js.map +1 -0
- package/dist/tests/commands/user.test.d.ts +2 -0
- package/dist/tests/commands/user.test.d.ts.map +1 -0
- package/dist/tests/commands/user.test.js +117 -0
- package/dist/tests/commands/user.test.js.map +1 -0
- package/dist/tests/commands/workspace.test.d.ts +2 -0
- package/dist/tests/commands/workspace.test.d.ts.map +1 -0
- package/dist/tests/commands/workspace.test.js +453 -0
- package/dist/tests/commands/workspace.test.js.map +1 -0
- package/dist/tests/credential-manager.test.d.ts +2 -0
- package/dist/tests/credential-manager.test.d.ts.map +1 -0
- package/dist/tests/credential-manager.test.js +199 -0
- package/dist/tests/credential-manager.test.js.map +1 -0
- package/dist/tests/slack-client.test.d.ts +2 -0
- package/dist/tests/slack-client.test.d.ts.map +1 -0
- package/dist/tests/slack-client.test.js +741 -0
- package/dist/tests/slack-client.test.js.map +1 -0
- package/dist/tests/types.test.d.ts +2 -0
- package/dist/tests/types.test.d.ts.map +1 -0
- package/dist/tests/types.test.js +215 -0
- package/dist/tests/types.test.js.map +1 -0
- package/dist/types/index.d.ts +369 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +92 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/error-handler.d.ts +2 -0
- package/dist/utils/error-handler.d.ts.map +1 -0
- package/dist/utils/error-handler.js +5 -0
- package/dist/utils/error-handler.js.map +1 -0
- package/dist/utils/output.d.ts +2 -0
- package/dist/utils/output.d.ts.map +1 -0
- package/dist/utils/output.js +4 -0
- package/dist/utils/output.js.map +1 -0
- package/docs/discord.md +182 -0
- package/docs/slack.md +160 -0
- package/package.json +37 -0
- package/skills/agent-discord/SKILL.md +273 -0
- package/skills/agent-discord/references/authentication.md +294 -0
- package/skills/agent-discord/references/common-patterns.md +455 -0
- package/skills/agent-discord/templates/guild-summary.sh +167 -0
- package/skills/agent-discord/templates/monitor-channel.sh +180 -0
- package/skills/agent-discord/templates/post-message.sh +173 -0
- package/skills/agent-slack/SKILL.md +268 -0
- package/skills/agent-slack/references/authentication.md +332 -0
- package/skills/agent-slack/references/common-patterns.md +527 -0
- package/skills/agent-slack/templates/monitor-channel.sh +186 -0
- package/skills/agent-slack/templates/post-message.sh +130 -0
- package/skills/agent-slack/templates/workspace-summary.sh +149 -0
- package/src/cli.ts +29 -0
- package/src/platforms/discord/cli.ts +36 -0
- package/src/platforms/discord/client.test.ts +456 -0
- package/src/platforms/discord/client.ts +281 -0
- package/src/platforms/discord/commands/auth.test.ts +72 -0
- package/src/platforms/discord/commands/auth.ts +206 -0
- package/src/platforms/discord/commands/channel.test.ts +153 -0
- package/src/platforms/discord/commands/channel.ts +127 -0
- package/src/platforms/discord/commands/file.test.ts +98 -0
- package/src/platforms/discord/commands/file.ts +134 -0
- package/src/platforms/discord/commands/guild.test.ts +117 -0
- package/src/platforms/discord/commands/guild.ts +129 -0
- package/src/platforms/discord/commands/index.ts +8 -0
- package/src/platforms/discord/commands/message.test.ts +107 -0
- package/src/platforms/discord/commands/message.ts +182 -0
- package/src/platforms/discord/commands/reaction.test.ts +123 -0
- package/src/platforms/discord/commands/reaction.ts +156 -0
- package/src/platforms/discord/commands/snapshot.test.ts +29 -0
- package/src/platforms/discord/commands/snapshot.ts +104 -0
- package/src/platforms/discord/commands/user.test.ts +115 -0
- package/src/platforms/discord/commands/user.ts +124 -0
- package/src/platforms/discord/credential-manager.test.ts +173 -0
- package/src/platforms/discord/credential-manager.ts +95 -0
- package/src/platforms/discord/token-extractor.test.ts +918 -0
- package/src/platforms/discord/token-extractor.ts +549 -0
- package/src/platforms/discord/types.test.ts +245 -0
- package/src/platforms/discord/types.ts +158 -0
- package/src/platforms/slack/cli.ts +36 -0
- package/src/platforms/slack/client.ts +466 -0
- package/src/platforms/slack/commands/auth.ts +211 -0
- package/src/platforms/slack/commands/channel.ts +158 -0
- package/src/platforms/slack/commands/file.ts +153 -0
- package/src/platforms/slack/commands/index.ts +8 -0
- package/src/platforms/slack/commands/message.ts +369 -0
- package/src/platforms/slack/commands/reaction.ts +166 -0
- package/src/platforms/slack/commands/snapshot.ts +114 -0
- package/src/platforms/slack/commands/user.ts +110 -0
- package/src/platforms/slack/commands/workspace.ts +111 -0
- package/src/platforms/slack/credential-manager.ts +74 -0
- package/src/platforms/slack/index.ts +2 -0
- package/src/platforms/slack/token-extractor.ts +496 -0
- package/src/platforms/slack/types.ts +193 -0
- package/src/shared/utils/concurrency.test.ts +53 -0
- package/src/shared/utils/concurrency.ts +20 -0
- package/src/shared/utils/error-handler.ts +4 -0
- package/src/shared/utils/output.ts +3 -0
- package/tests/cli.test.ts +94 -0
- package/tests/commands/auth.test.ts +383 -0
- package/tests/commands/channel.test.ts +185 -0
- package/tests/commands/file.test.ts +204 -0
- package/tests/commands/message.test.ts +344 -0
- package/tests/commands/reaction.test.ts +101 -0
- package/tests/commands/snapshot.test.ts +308 -0
- package/tests/commands/user.test.ts +138 -0
- package/tests/commands/workspace.test.ts +528 -0
- package/tests/credential-manager.test.ts +241 -0
- package/tests/slack-client.test.ts +916 -0
- package/tests/types.test.ts +241 -0
- package/tsconfig.json +36 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test'
|
|
2
|
+
import { parallelMap } from './concurrency'
|
|
3
|
+
|
|
4
|
+
describe('parallelMap', () => {
|
|
5
|
+
test('processes items in parallel', async () => {
|
|
6
|
+
const items = [1, 2, 3, 4, 5]
|
|
7
|
+
const results = await parallelMap(items, async (n) => n * 2)
|
|
8
|
+
expect(results).toEqual([2, 4, 6, 8, 10])
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
test('maintains order of results', async () => {
|
|
12
|
+
const items = [100, 50, 10]
|
|
13
|
+
const results = await parallelMap(
|
|
14
|
+
items,
|
|
15
|
+
async (delay) => {
|
|
16
|
+
await new Promise((r) => setTimeout(r, delay))
|
|
17
|
+
return delay
|
|
18
|
+
},
|
|
19
|
+
3
|
|
20
|
+
)
|
|
21
|
+
expect(results).toEqual([100, 50, 10])
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
test('respects concurrency limit', async () => {
|
|
25
|
+
let concurrent = 0
|
|
26
|
+
let maxConcurrent = 0
|
|
27
|
+
const items = [1, 2, 3, 4, 5, 6]
|
|
28
|
+
|
|
29
|
+
await parallelMap(
|
|
30
|
+
items,
|
|
31
|
+
async () => {
|
|
32
|
+
concurrent++
|
|
33
|
+
maxConcurrent = Math.max(maxConcurrent, concurrent)
|
|
34
|
+
await new Promise((r) => setTimeout(r, 10))
|
|
35
|
+
concurrent--
|
|
36
|
+
},
|
|
37
|
+
2
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
expect(maxConcurrent).toBe(2)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
test('handles empty array', async () => {
|
|
44
|
+
const results = await parallelMap([], async (n: number) => n * 2)
|
|
45
|
+
expect(results).toEqual([])
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
test('passes index to function', async () => {
|
|
49
|
+
const items = ['a', 'b', 'c']
|
|
50
|
+
const results = await parallelMap(items, async (item, index) => `${item}${index}`)
|
|
51
|
+
expect(results).toEqual(['a0', 'b1', 'c2'])
|
|
52
|
+
})
|
|
53
|
+
})
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export async function parallelMap<T, R>(
|
|
2
|
+
items: T[],
|
|
3
|
+
fn: (item: T, index: number) => Promise<R>,
|
|
4
|
+
concurrency = 5
|
|
5
|
+
): Promise<R[]> {
|
|
6
|
+
const results: R[] = new Array(items.length)
|
|
7
|
+
let currentIndex = 0
|
|
8
|
+
|
|
9
|
+
async function worker(): Promise<void> {
|
|
10
|
+
while (currentIndex < items.length) {
|
|
11
|
+
const index = currentIndex++
|
|
12
|
+
results[index] = await fn(items[index], index)
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const workers = Array.from({ length: Math.min(concurrency, items.length) }, () => worker())
|
|
17
|
+
await Promise.all(workers)
|
|
18
|
+
|
|
19
|
+
return results
|
|
20
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test'
|
|
2
|
+
import { spawn } from 'bun'
|
|
3
|
+
import pkg from '../package.json'
|
|
4
|
+
import { handleError } from '../src/shared/utils/error-handler'
|
|
5
|
+
import { formatOutput } from '../src/shared/utils/output'
|
|
6
|
+
|
|
7
|
+
describe('CLI Framework', () => {
|
|
8
|
+
describe('formatOutput utility', () => {
|
|
9
|
+
test('formats JSON without pretty flag', () => {
|
|
10
|
+
const data = { message: 'hello', count: 42 }
|
|
11
|
+
const result = formatOutput(data, false)
|
|
12
|
+
expect(result).toBe('{"message":"hello","count":42}')
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
test('formats JSON with pretty flag', () => {
|
|
16
|
+
const data = { message: 'hello', count: 42 }
|
|
17
|
+
const result = formatOutput(data, true)
|
|
18
|
+
const expected = JSON.stringify(data, null, 2)
|
|
19
|
+
expect(result).toBe(expected)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
test('handles arrays', () => {
|
|
23
|
+
const data = [1, 2, 3]
|
|
24
|
+
const result = formatOutput(data, false)
|
|
25
|
+
expect(result).toBe('[1,2,3]')
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
test('handles nested objects with pretty flag', () => {
|
|
29
|
+
const data = { user: { name: 'Alice', id: 1 } }
|
|
30
|
+
const result = formatOutput(data, true)
|
|
31
|
+
expect(result).toContain('"user"')
|
|
32
|
+
expect(result).toContain('"name"')
|
|
33
|
+
})
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
describe('handleError utility', () => {
|
|
37
|
+
test('logs error as JSON and exits', () => {
|
|
38
|
+
const originalExit = process.exit
|
|
39
|
+
const originalError = console.error
|
|
40
|
+
let capturedOutput = ''
|
|
41
|
+
|
|
42
|
+
console.error = (msg: string) => {
|
|
43
|
+
capturedOutput = msg
|
|
44
|
+
}
|
|
45
|
+
process.exit = (() => {
|
|
46
|
+
throw new Error('EXIT_CALLED')
|
|
47
|
+
}) as never
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
handleError(new Error('Test error'))
|
|
51
|
+
} catch (e) {
|
|
52
|
+
if (e instanceof Error && e.message === 'EXIT_CALLED') {
|
|
53
|
+
expect(capturedOutput).toContain('Test error')
|
|
54
|
+
expect(capturedOutput).toContain('error')
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
console.error = originalError
|
|
59
|
+
process.exit = originalExit
|
|
60
|
+
})
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
describe('Slack CLI program structure', () => {
|
|
64
|
+
test('--help shows all commands and global options', async () => {
|
|
65
|
+
const proc = spawn(['bun', 'run', './src/platforms/slack/cli.ts', '--help'], {
|
|
66
|
+
cwd: process.cwd(),
|
|
67
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
const output = await new Response(proc.stdout).text()
|
|
71
|
+
|
|
72
|
+
expect(output).toContain('auth')
|
|
73
|
+
expect(output).toContain('workspace')
|
|
74
|
+
expect(output).toContain('message')
|
|
75
|
+
expect(output).toContain('channel')
|
|
76
|
+
expect(output).toContain('user')
|
|
77
|
+
expect(output).toContain('reaction')
|
|
78
|
+
expect(output).toContain('file')
|
|
79
|
+
expect(output).toContain('snapshot')
|
|
80
|
+
expect(output).toContain('--pretty')
|
|
81
|
+
expect(output).toContain('--workspace')
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
test('--version shows package version', async () => {
|
|
85
|
+
const proc = spawn(['bun', 'run', './src/platforms/slack/cli.ts', '--version'], {
|
|
86
|
+
cwd: process.cwd(),
|
|
87
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
const output = await new Response(proc.stdout).text()
|
|
91
|
+
expect(output.trim()).toBe(pkg.version)
|
|
92
|
+
})
|
|
93
|
+
})
|
|
94
|
+
})
|
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
import { afterAll, beforeEach, describe, expect, mock, test } from 'bun:test'
|
|
2
|
+
import { mkdirSync, rmSync } from 'node:fs'
|
|
3
|
+
import { homedir } from 'node:os'
|
|
4
|
+
import { join } from 'node:path'
|
|
5
|
+
import { CredentialManager } from '../../src/platforms/slack/credential-manager'
|
|
6
|
+
import { type ExtractedWorkspace, TokenExtractor } from '../../src/platforms/slack/token-extractor'
|
|
7
|
+
|
|
8
|
+
const testConfigDir = join(import.meta.dir, '.test-auth-config')
|
|
9
|
+
const testSlackDir = join(import.meta.dir, '.test-slack-data')
|
|
10
|
+
|
|
11
|
+
describe('TokenExtractor', () => {
|
|
12
|
+
let extractor: TokenExtractor
|
|
13
|
+
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
rmSync(testSlackDir, { recursive: true, force: true })
|
|
16
|
+
mkdirSync(testSlackDir, { recursive: true })
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
afterAll(() => {
|
|
20
|
+
rmSync(testSlackDir, { recursive: true, force: true })
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
describe('getSlackDir', () => {
|
|
24
|
+
test('returns correct path for darwin', () => {
|
|
25
|
+
// Given: Platform is darwin
|
|
26
|
+
extractor = new TokenExtractor('darwin')
|
|
27
|
+
|
|
28
|
+
// When: getSlackDir is called
|
|
29
|
+
const dir = extractor.getSlackDir()
|
|
30
|
+
|
|
31
|
+
// Then: Should return macOS path (direct or sandboxed depending on what exists)
|
|
32
|
+
const directPath = join(homedir(), 'Library', 'Application Support', 'Slack')
|
|
33
|
+
const sandboxedPath = join(
|
|
34
|
+
homedir(),
|
|
35
|
+
'Library',
|
|
36
|
+
'Containers',
|
|
37
|
+
'com.tinyspeck.slackmacgap',
|
|
38
|
+
'Data',
|
|
39
|
+
'Library',
|
|
40
|
+
'Application Support',
|
|
41
|
+
'Slack'
|
|
42
|
+
)
|
|
43
|
+
expect([directPath, sandboxedPath]).toContain(dir)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
test('returns correct path for linux', () => {
|
|
47
|
+
// Given: Platform is linux
|
|
48
|
+
extractor = new TokenExtractor('linux')
|
|
49
|
+
|
|
50
|
+
// When: getSlackDir is called
|
|
51
|
+
const dir = extractor.getSlackDir()
|
|
52
|
+
|
|
53
|
+
// Then: Should return Linux path
|
|
54
|
+
expect(dir).toBe(join(homedir(), '.config', 'Slack'))
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
test('returns correct path for win32', () => {
|
|
58
|
+
// Given: Platform is win32
|
|
59
|
+
extractor = new TokenExtractor('win32')
|
|
60
|
+
|
|
61
|
+
// When: getSlackDir is called
|
|
62
|
+
const dir = extractor.getSlackDir()
|
|
63
|
+
|
|
64
|
+
// Then: Should return Windows path
|
|
65
|
+
expect(dir).toContain('Slack')
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
test('throws error for unsupported platform', () => {
|
|
69
|
+
// Given: Platform is unsupported
|
|
70
|
+
// When/Then: Constructor should throw
|
|
71
|
+
expect(() => new TokenExtractor('freebsd' as NodeJS.Platform)).toThrow('Unsupported platform')
|
|
72
|
+
})
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
describe('extract', () => {
|
|
76
|
+
test('throws error when Slack directory does not exist', async () => {
|
|
77
|
+
// Given: Slack directory does not exist
|
|
78
|
+
extractor = new TokenExtractor('darwin', '/nonexistent/path')
|
|
79
|
+
|
|
80
|
+
// When/Then: extract should throw
|
|
81
|
+
await expect(extractor.extract()).rejects.toThrow('Slack directory not found')
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
test('returns empty array when no tokens found', async () => {
|
|
85
|
+
// Given: Slack directory exists but has no tokens
|
|
86
|
+
mkdirSync(join(testSlackDir, 'storage'), { recursive: true })
|
|
87
|
+
extractor = new TokenExtractor('darwin', testSlackDir)
|
|
88
|
+
|
|
89
|
+
// When: extract is called
|
|
90
|
+
const result = await extractor.extract()
|
|
91
|
+
|
|
92
|
+
// Then: Should return empty array
|
|
93
|
+
expect(result).toEqual([])
|
|
94
|
+
})
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
describe('extractTokensFromLevelDB', () => {
|
|
98
|
+
test('extracts xoxc tokens from LevelDB', async () => {
|
|
99
|
+
// Given: LevelDB with xoxc token data
|
|
100
|
+
// This test requires mocking LevelDB - we'll test the integration
|
|
101
|
+
extractor = new TokenExtractor('darwin', testSlackDir)
|
|
102
|
+
|
|
103
|
+
// When: extractTokensFromLevelDB is called
|
|
104
|
+
// Then: Should extract tokens (mocked in integration test)
|
|
105
|
+
expect(extractor).toBeDefined()
|
|
106
|
+
})
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
describe('extractCookieFromSQLite', () => {
|
|
110
|
+
test('extracts xoxd cookie from SQLite', async () => {
|
|
111
|
+
// Given: SQLite Cookies database with d cookie
|
|
112
|
+
// This test requires mocking SQLite - we'll test the integration
|
|
113
|
+
extractor = new TokenExtractor('darwin', testSlackDir)
|
|
114
|
+
|
|
115
|
+
// When: extractCookieFromSQLite is called
|
|
116
|
+
// Then: Should extract cookie (mocked in integration test)
|
|
117
|
+
expect(extractor).toBeDefined()
|
|
118
|
+
})
|
|
119
|
+
})
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
describe('Auth Commands Integration', () => {
|
|
123
|
+
let credManager: CredentialManager
|
|
124
|
+
|
|
125
|
+
beforeEach(() => {
|
|
126
|
+
rmSync(testConfigDir, { recursive: true, force: true })
|
|
127
|
+
credManager = new CredentialManager(testConfigDir)
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
afterAll(() => {
|
|
131
|
+
rmSync(testConfigDir, { recursive: true, force: true })
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
describe('auth extract', () => {
|
|
135
|
+
test('stores extracted workspaces in credential manager', async () => {
|
|
136
|
+
// Given: Extracted workspaces
|
|
137
|
+
const workspaces: ExtractedWorkspace[] = [
|
|
138
|
+
{
|
|
139
|
+
workspace_id: 'T123',
|
|
140
|
+
workspace_name: 'acme-corp',
|
|
141
|
+
token: 'xoxc-123-456',
|
|
142
|
+
cookie: 'xoxd-abc',
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
workspace_id: 'T456',
|
|
146
|
+
workspace_name: 'side-project',
|
|
147
|
+
token: 'xoxc-789-012',
|
|
148
|
+
cookie: 'xoxd-def',
|
|
149
|
+
},
|
|
150
|
+
]
|
|
151
|
+
|
|
152
|
+
// When: Workspaces are stored
|
|
153
|
+
for (const ws of workspaces) {
|
|
154
|
+
await credManager.setWorkspace(ws)
|
|
155
|
+
}
|
|
156
|
+
await credManager.setCurrentWorkspace('T123')
|
|
157
|
+
|
|
158
|
+
// Then: All workspaces should be retrievable
|
|
159
|
+
const config = await credManager.load()
|
|
160
|
+
expect(Object.keys(config.workspaces)).toHaveLength(2)
|
|
161
|
+
expect(config.current_workspace).toBe('T123')
|
|
162
|
+
expect(config.workspaces.T123.token).toBe('xoxc-123-456')
|
|
163
|
+
expect(config.workspaces.T456.token).toBe('xoxc-789-012')
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
test('sets first workspace as current if none exists', async () => {
|
|
167
|
+
// Given: No current workspace
|
|
168
|
+
const workspace: ExtractedWorkspace = {
|
|
169
|
+
workspace_id: 'T789',
|
|
170
|
+
workspace_name: 'new-workspace',
|
|
171
|
+
token: 'xoxc-new',
|
|
172
|
+
cookie: 'xoxd-new',
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// When: First workspace is stored
|
|
176
|
+
await credManager.setWorkspace(workspace)
|
|
177
|
+
const config = await credManager.load()
|
|
178
|
+
|
|
179
|
+
// Then: If no current, should set first as current
|
|
180
|
+
if (!config.current_workspace) {
|
|
181
|
+
await credManager.setCurrentWorkspace('T789')
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const updated = await credManager.load()
|
|
185
|
+
expect(updated.current_workspace).toBe('T789')
|
|
186
|
+
})
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
describe('auth logout', () => {
|
|
190
|
+
test('removes workspace by id', async () => {
|
|
191
|
+
// Given: A workspace exists
|
|
192
|
+
await credManager.setWorkspace({
|
|
193
|
+
workspace_id: 'T-logout',
|
|
194
|
+
workspace_name: 'to-logout',
|
|
195
|
+
token: 'xoxc-logout',
|
|
196
|
+
cookie: 'xoxd-logout',
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
// When: Workspace is removed
|
|
200
|
+
await credManager.removeWorkspace('T-logout')
|
|
201
|
+
|
|
202
|
+
// Then: Workspace should not exist
|
|
203
|
+
const ws = await credManager.getWorkspace('T-logout')
|
|
204
|
+
expect(ws).toBeNull()
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
test('removes current workspace and clears current', async () => {
|
|
208
|
+
// Given: Current workspace is set
|
|
209
|
+
await credManager.setWorkspace({
|
|
210
|
+
workspace_id: 'T-current',
|
|
211
|
+
workspace_name: 'current',
|
|
212
|
+
token: 'xoxc-current',
|
|
213
|
+
cookie: 'xoxd-current',
|
|
214
|
+
})
|
|
215
|
+
await credManager.setCurrentWorkspace('T-current')
|
|
216
|
+
|
|
217
|
+
// When: Current workspace is removed
|
|
218
|
+
await credManager.removeWorkspace('T-current')
|
|
219
|
+
|
|
220
|
+
// Then: Current should be null
|
|
221
|
+
const config = await credManager.load()
|
|
222
|
+
expect(config.current_workspace).toBeNull()
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
test('throws error when workspace not found', async () => {
|
|
226
|
+
// Given: Workspace does not exist
|
|
227
|
+
// When: Trying to get non-existent workspace
|
|
228
|
+
const ws = await credManager.getWorkspace('nonexistent')
|
|
229
|
+
|
|
230
|
+
// Then: Should return null (command should handle this)
|
|
231
|
+
expect(ws).toBeNull()
|
|
232
|
+
})
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
describe('auth status', () => {
|
|
236
|
+
test('returns current workspace info', async () => {
|
|
237
|
+
// Given: A current workspace is set
|
|
238
|
+
await credManager.setWorkspace({
|
|
239
|
+
workspace_id: 'T-status',
|
|
240
|
+
workspace_name: 'status-test',
|
|
241
|
+
token: 'xoxc-status',
|
|
242
|
+
cookie: 'xoxd-status',
|
|
243
|
+
})
|
|
244
|
+
await credManager.setCurrentWorkspace('T-status')
|
|
245
|
+
|
|
246
|
+
// When: Getting current workspace
|
|
247
|
+
const ws = await credManager.getWorkspace()
|
|
248
|
+
|
|
249
|
+
// Then: Should return workspace info
|
|
250
|
+
expect(ws).not.toBeNull()
|
|
251
|
+
expect(ws?.workspace_id).toBe('T-status')
|
|
252
|
+
expect(ws?.workspace_name).toBe('status-test')
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
test('returns null when no workspace configured', async () => {
|
|
256
|
+
// Given: No workspace configured
|
|
257
|
+
// When: Getting current workspace
|
|
258
|
+
const ws = await credManager.getWorkspace()
|
|
259
|
+
|
|
260
|
+
// Then: Should return null
|
|
261
|
+
expect(ws).toBeNull()
|
|
262
|
+
})
|
|
263
|
+
|
|
264
|
+
test('validates token with Slack API', async () => {
|
|
265
|
+
// Given: A workspace with valid credentials
|
|
266
|
+
// This would require mocking SlackClient.testAuth()
|
|
267
|
+
// We test the integration pattern here
|
|
268
|
+
|
|
269
|
+
const mockTestAuth = mock(() =>
|
|
270
|
+
Promise.resolve({
|
|
271
|
+
user_id: 'U123',
|
|
272
|
+
team_id: 'T123',
|
|
273
|
+
user: 'testuser',
|
|
274
|
+
team: 'Test Team',
|
|
275
|
+
})
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
// When: testAuth is called
|
|
279
|
+
const result = await mockTestAuth()
|
|
280
|
+
|
|
281
|
+
// Then: Should return auth info
|
|
282
|
+
expect(result.user_id).toBe('U123')
|
|
283
|
+
expect(result.team_id).toBe('T123')
|
|
284
|
+
expect(result.user).toBe('testuser')
|
|
285
|
+
expect(result.team).toBe('Test Team')
|
|
286
|
+
})
|
|
287
|
+
})
|
|
288
|
+
})
|
|
289
|
+
|
|
290
|
+
describe('Platform Detection', () => {
|
|
291
|
+
test('auto-detects current platform', () => {
|
|
292
|
+
// Given: Running on current platform
|
|
293
|
+
const platform = process.platform
|
|
294
|
+
|
|
295
|
+
// When: TokenExtractor is created without explicit platform
|
|
296
|
+
const _extractor = new TokenExtractor()
|
|
297
|
+
|
|
298
|
+
// Then: Should use current platform
|
|
299
|
+
expect(['darwin', 'linux', 'win32']).toContain(platform)
|
|
300
|
+
})
|
|
301
|
+
})
|
|
302
|
+
|
|
303
|
+
describe('Output Formatting', () => {
|
|
304
|
+
test('formats extract output correctly', () => {
|
|
305
|
+
// Given: Extracted workspaces
|
|
306
|
+
const output = {
|
|
307
|
+
workspaces: ['T123/acme-corp', 'T456/side-project'],
|
|
308
|
+
current: 'T123',
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// When: Formatted as JSON
|
|
312
|
+
const json = JSON.stringify(output)
|
|
313
|
+
const pretty = JSON.stringify(output, null, 2)
|
|
314
|
+
|
|
315
|
+
// Then: Should be valid JSON
|
|
316
|
+
expect(JSON.parse(json)).toEqual(output)
|
|
317
|
+
expect(pretty).toContain('\n')
|
|
318
|
+
})
|
|
319
|
+
|
|
320
|
+
test('formats status output correctly', () => {
|
|
321
|
+
// Given: Status info
|
|
322
|
+
const output = {
|
|
323
|
+
workspace_id: 'T123',
|
|
324
|
+
workspace_name: 'acme-corp',
|
|
325
|
+
user: 'testuser',
|
|
326
|
+
team: 'Acme Corp',
|
|
327
|
+
valid: true,
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// When: Formatted as JSON
|
|
331
|
+
const json = JSON.stringify(output)
|
|
332
|
+
|
|
333
|
+
// Then: Should be valid JSON
|
|
334
|
+
expect(JSON.parse(json)).toEqual(output)
|
|
335
|
+
})
|
|
336
|
+
|
|
337
|
+
test('formats logout output correctly', () => {
|
|
338
|
+
// Given: Logout result
|
|
339
|
+
const output = {
|
|
340
|
+
removed: 'T123',
|
|
341
|
+
success: true,
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// When: Formatted as JSON
|
|
345
|
+
const json = JSON.stringify(output)
|
|
346
|
+
|
|
347
|
+
// Then: Should be valid JSON
|
|
348
|
+
expect(JSON.parse(json)).toEqual(output)
|
|
349
|
+
})
|
|
350
|
+
})
|
|
351
|
+
|
|
352
|
+
describe('Error Handling', () => {
|
|
353
|
+
test('handles missing Slack installation gracefully', async () => {
|
|
354
|
+
// Given: Slack is not installed
|
|
355
|
+
const extractor = new TokenExtractor('darwin', '/nonexistent/slack')
|
|
356
|
+
|
|
357
|
+
// When/Then: Should throw descriptive error
|
|
358
|
+
await expect(extractor.extract()).rejects.toThrow('Slack directory not found')
|
|
359
|
+
})
|
|
360
|
+
|
|
361
|
+
test('handles corrupted LevelDB gracefully', async () => {
|
|
362
|
+
// Given: Corrupted LevelDB
|
|
363
|
+
// This would require creating a corrupted LevelDB file
|
|
364
|
+
// We test that the extractor handles errors gracefully
|
|
365
|
+
const extractor = new TokenExtractor('darwin', testSlackDir)
|
|
366
|
+
|
|
367
|
+
// When: Trying to extract from non-existent storage
|
|
368
|
+
// Then: Should handle gracefully (return empty or throw)
|
|
369
|
+
await expect(extractor.extract()).rejects.toThrow()
|
|
370
|
+
})
|
|
371
|
+
|
|
372
|
+
test('handles missing Cookies database gracefully', async () => {
|
|
373
|
+
// Given: No Cookies database
|
|
374
|
+
mkdirSync(join(testSlackDir, 'storage'), { recursive: true })
|
|
375
|
+
const extractor = new TokenExtractor('darwin', testSlackDir)
|
|
376
|
+
|
|
377
|
+
// When: Trying to extract
|
|
378
|
+
const result = await extractor.extract()
|
|
379
|
+
|
|
380
|
+
// Then: Should return empty array (no tokens found)
|
|
381
|
+
expect(result).toEqual([])
|
|
382
|
+
})
|
|
383
|
+
})
|