agent-messenger 1.2.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +27 -1
- package/.claude-plugin/plugin.json +17 -4
- package/.env.template +3 -0
- package/.github/workflows/release.yml +94 -0
- package/AGENTS.md +48 -0
- package/README.md +25 -20
- package/biome.json +15 -39
- package/bun.lock +69 -0
- package/dist/package.json +12 -4
- package/dist/src/cli.d.ts.map +1 -1
- package/dist/src/cli.js +1 -4
- package/dist/src/cli.js.map +1 -1
- package/dist/src/platforms/discord/client.d.ts.map +1 -1
- package/dist/src/platforms/discord/client.js.map +1 -1
- package/dist/src/platforms/discord/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/discord/commands/auth.js.map +1 -1
- package/dist/src/platforms/discord/commands/channel.d.ts.map +1 -1
- package/dist/src/platforms/discord/commands/channel.js.map +1 -1
- package/dist/src/platforms/discord/commands/dm.d.ts.map +1 -1
- package/dist/src/platforms/discord/commands/dm.js.map +1 -1
- package/dist/src/platforms/discord/commands/file.d.ts.map +1 -1
- package/dist/src/platforms/discord/commands/file.js +1 -4
- package/dist/src/platforms/discord/commands/file.js.map +1 -1
- package/dist/src/platforms/discord/commands/friend.d.ts.map +1 -1
- package/dist/src/platforms/discord/commands/friend.js +1 -3
- package/dist/src/platforms/discord/commands/friend.js.map +1 -1
- package/dist/src/platforms/discord/commands/member.d.ts.map +1 -1
- package/dist/src/platforms/discord/commands/member.js.map +1 -1
- package/dist/src/platforms/discord/commands/mention.d.ts.map +1 -1
- package/dist/src/platforms/discord/commands/mention.js.map +1 -1
- package/dist/src/platforms/discord/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/discord/commands/message.js.map +1 -1
- package/dist/src/platforms/discord/commands/note.d.ts.map +1 -1
- package/dist/src/platforms/discord/commands/note.js.map +1 -1
- package/dist/src/platforms/discord/commands/profile.d.ts.map +1 -1
- package/dist/src/platforms/discord/commands/profile.js.map +1 -1
- package/dist/src/platforms/discord/commands/reaction.d.ts.map +1 -1
- package/dist/src/platforms/discord/commands/reaction.js.map +1 -1
- package/dist/src/platforms/discord/commands/server.d.ts.map +1 -1
- package/dist/src/platforms/discord/commands/server.js.map +1 -1
- package/dist/src/platforms/discord/commands/snapshot.d.ts.map +1 -1
- package/dist/src/platforms/discord/commands/snapshot.js.map +1 -1
- package/dist/src/platforms/discord/commands/thread.d.ts.map +1 -1
- package/dist/src/platforms/discord/commands/thread.js.map +1 -1
- package/dist/src/platforms/discord/commands/user.d.ts.map +1 -1
- package/dist/src/platforms/discord/commands/user.js.map +1 -1
- package/dist/src/platforms/discord/credential-manager.d.ts.map +1 -1
- package/dist/src/platforms/discord/credential-manager.js.map +1 -1
- package/dist/src/platforms/discord/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/discord/token-extractor.js +2 -7
- package/dist/src/platforms/discord/token-extractor.js.map +1 -1
- package/dist/src/platforms/slack/client.d.ts.map +1 -1
- package/dist/src/platforms/slack/client.js.map +1 -1
- package/dist/src/platforms/slack/commands/activity.d.ts.map +1 -1
- package/dist/src/platforms/slack/commands/activity.js.map +1 -1
- package/dist/src/platforms/slack/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/slack/commands/auth.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/drafts.d.ts.map +1 -1
- package/dist/src/platforms/slack/commands/drafts.js.map +1 -1
- package/dist/src/platforms/slack/commands/file.d.ts.map +1 -1
- package/dist/src/platforms/slack/commands/file.js +1 -4
- package/dist/src/platforms/slack/commands/file.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/reaction.d.ts.map +1 -1
- package/dist/src/platforms/slack/commands/reaction.js.map +1 -1
- package/dist/src/platforms/slack/commands/saved.d.ts.map +1 -1
- package/dist/src/platforms/slack/commands/saved.js.map +1 -1
- package/dist/src/platforms/slack/commands/sections.d.ts.map +1 -1
- package/dist/src/platforms/slack/commands/sections.js.map +1 -1
- package/dist/src/platforms/slack/commands/snapshot.d.ts.map +1 -1
- package/dist/src/platforms/slack/commands/snapshot.js.map +1 -1
- package/dist/src/platforms/slack/commands/unread.d.ts.map +1 -1
- package/dist/src/platforms/slack/commands/unread.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/workspace.d.ts.map +1 -1
- package/dist/src/platforms/slack/commands/workspace.js.map +1 -1
- package/dist/src/platforms/slack/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/slack/token-extractor.js +4 -5
- package/dist/src/platforms/slack/token-extractor.js.map +1 -1
- package/dist/src/platforms/slackbot/cli.d.ts +5 -0
- package/dist/src/platforms/slackbot/cli.d.ts.map +1 -0
- package/dist/src/platforms/slackbot/cli.js +19 -0
- package/dist/src/platforms/slackbot/cli.js.map +1 -0
- package/dist/src/platforms/slackbot/client.d.ts +43 -0
- package/dist/src/platforms/slackbot/client.d.ts.map +1 -0
- package/dist/src/platforms/slackbot/client.js +347 -0
- package/dist/src/platforms/slackbot/client.js.map +1 -0
- package/dist/src/platforms/slackbot/commands/auth.d.ts +35 -0
- package/dist/src/platforms/slackbot/commands/auth.d.ts.map +1 -0
- package/dist/src/platforms/slackbot/commands/auth.js +185 -0
- package/dist/src/platforms/slackbot/commands/auth.js.map +1 -0
- package/dist/src/platforms/slackbot/commands/channel.d.ts +3 -0
- package/dist/src/platforms/slackbot/commands/channel.d.ts.map +1 -0
- package/dist/src/platforms/slackbot/commands/channel.js +40 -0
- package/dist/src/platforms/slackbot/commands/channel.js.map +1 -0
- package/dist/src/platforms/slackbot/commands/index.d.ts +6 -0
- package/dist/src/platforms/slackbot/commands/index.d.ts.map +1 -0
- package/dist/src/platforms/slackbot/commands/index.js +6 -0
- package/dist/src/platforms/slackbot/commands/index.js.map +1 -0
- package/dist/src/platforms/slackbot/commands/message.d.ts +3 -0
- package/dist/src/platforms/slackbot/commands/message.d.ts.map +1 -0
- package/dist/src/platforms/slackbot/commands/message.js +135 -0
- package/dist/src/platforms/slackbot/commands/message.js.map +1 -0
- package/dist/src/platforms/slackbot/commands/reaction.d.ts +3 -0
- package/dist/src/platforms/slackbot/commands/reaction.d.ts.map +1 -0
- package/dist/src/platforms/slackbot/commands/reaction.js +43 -0
- package/dist/src/platforms/slackbot/commands/reaction.js.map +1 -0
- package/dist/src/platforms/slackbot/commands/shared.d.ts +9 -0
- package/dist/src/platforms/slackbot/commands/shared.d.ts.map +1 -0
- package/dist/src/platforms/slackbot/commands/shared.js +13 -0
- package/dist/src/platforms/slackbot/commands/shared.js.map +1 -0
- package/dist/src/platforms/slackbot/commands/user.d.ts +3 -0
- package/dist/src/platforms/slackbot/commands/user.d.ts.map +1 -0
- package/dist/src/platforms/slackbot/commands/user.js +40 -0
- package/dist/src/platforms/slackbot/commands/user.js.map +1 -0
- package/dist/src/platforms/slackbot/credential-manager.d.ts +18 -0
- package/dist/src/platforms/slackbot/credential-manager.d.ts.map +1 -0
- package/dist/src/platforms/slackbot/credential-manager.js +185 -0
- package/dist/src/platforms/slackbot/credential-manager.js.map +1 -0
- package/dist/src/platforms/slackbot/index.d.ts +4 -0
- package/dist/src/platforms/slackbot/index.d.ts.map +1 -0
- package/dist/src/platforms/slackbot/index.js +4 -0
- package/dist/src/platforms/slackbot/index.js.map +1 -0
- package/dist/src/platforms/slackbot/types.d.ts +460 -0
- package/dist/src/platforms/slackbot/types.d.ts.map +1 -0
- package/dist/src/platforms/slackbot/types.js +114 -0
- package/dist/src/platforms/slackbot/types.js.map +1 -0
- package/dist/src/platforms/teams/client.d.ts.map +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.map +1 -1
- package/dist/src/platforms/teams/commands/channel.d.ts.map +1 -1
- package/dist/src/platforms/teams/commands/channel.js.map +1 -1
- package/dist/src/platforms/teams/commands/file.d.ts.map +1 -1
- package/dist/src/platforms/teams/commands/file.js.map +1 -1
- package/dist/src/platforms/teams/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/teams/commands/message.js.map +1 -1
- package/dist/src/platforms/teams/commands/reaction.d.ts.map +1 -1
- package/dist/src/platforms/teams/commands/reaction.js.map +1 -1
- package/dist/src/platforms/teams/commands/snapshot.d.ts.map +1 -1
- package/dist/src/platforms/teams/commands/snapshot.js.map +1 -1
- package/dist/src/platforms/teams/commands/team.d.ts.map +1 -1
- package/dist/src/platforms/teams/commands/team.js +1 -4
- package/dist/src/platforms/teams/commands/team.js.map +1 -1
- package/dist/src/platforms/teams/commands/user.d.ts.map +1 -1
- package/dist/src/platforms/teams/commands/user.js.map +1 -1
- package/dist/src/platforms/teams/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/teams/token-extractor.js +3 -1
- package/dist/src/platforms/teams/token-extractor.js.map +1 -1
- package/docs/content/docs/agent-skills.mdx +4 -4
- package/docs/content/docs/index.mdx +11 -18
- package/docs/content/docs/integrations/discord.mdx +65 -1
- package/docs/content/docs/integrations/meta.json +1 -1
- package/docs/content/docs/integrations/slack.mdx +51 -1
- package/docs/content/docs/integrations/slackbot.mdx +214 -0
- package/docs/content/docs/integrations/teams.mdx +4 -1
- package/docs/content/docs/quick-start.mdx +3 -2
- package/docs/src/app/icon.png +0 -0
- package/docs/src/app/layout.config.tsx +8 -1
- package/docs/src/app/page.tsx +18 -1
- package/e2e/config.ts +26 -0
- package/e2e/helpers.ts +6 -1
- package/e2e/slackbot.e2e.test.ts +306 -0
- package/package.json +16 -8
- package/scripts/prepublish.ts +11 -0
- package/skills/agent-slackbot/SKILL.md +285 -0
- package/skills/agent-slackbot/references/authentication.md +253 -0
- package/skills/agent-slackbot/references/common-patterns.md +218 -0
- package/skills/agent-slackbot/templates/monitor-channel.sh +98 -0
- package/skills/agent-slackbot/templates/post-message.sh +107 -0
- package/skills/agent-slackbot/templates/workspace-summary.sh +113 -0
- package/src/cli.ts +1 -4
- package/src/platforms/discord/client.test.ts +6 -14
- package/src/platforms/discord/client.ts +12 -34
- package/src/platforms/discord/commands/auth.test.ts +2 -7
- package/src/platforms/discord/commands/auth.ts +14 -19
- package/src/platforms/discord/commands/channel.test.ts +18 -20
- package/src/platforms/discord/commands/channel.ts +9 -18
- package/src/platforms/discord/commands/dm.test.ts +1 -3
- package/src/platforms/discord/commands/dm.ts +6 -10
- package/src/platforms/discord/commands/file.ts +10 -23
- package/src/platforms/discord/commands/friend.ts +33 -35
- package/src/platforms/discord/commands/member.ts +5 -7
- package/src/platforms/discord/commands/mention.ts +5 -11
- package/src/platforms/discord/commands/message.test.ts +1 -3
- package/src/platforms/discord/commands/message.ts +23 -61
- package/src/platforms/discord/commands/note.ts +7 -15
- package/src/platforms/discord/commands/profile.ts +4 -6
- package/src/platforms/discord/commands/reaction.test.ts +1 -3
- package/src/platforms/discord/commands/reaction.ts +19 -29
- package/src/platforms/discord/commands/server.test.ts +14 -18
- package/src/platforms/discord/commands/server.ts +9 -15
- package/src/platforms/discord/commands/snapshot.ts +5 -7
- package/src/platforms/discord/commands/thread.ts +8 -15
- package/src/platforms/discord/commands/user.ts +9 -20
- package/src/platforms/discord/credential-manager.test.ts +2 -2
- package/src/platforms/discord/credential-manager.ts +1 -3
- package/src/platforms/discord/token-extractor.test.ts +28 -57
- package/src/platforms/discord/token-extractor.ts +10 -30
- package/src/platforms/discord/types.ts +1 -1
- package/src/platforms/slack/client.test.ts +14 -20
- package/src/platforms/slack/client.ts +4 -11
- package/src/platforms/slack/commands/activity.test.ts +3 -9
- package/src/platforms/slack/commands/activity.ts +7 -12
- package/src/platforms/slack/commands/auth.test.ts +2 -2
- package/src/platforms/slack/commands/auth.ts +15 -31
- package/src/platforms/slack/commands/channel.ts +10 -32
- package/src/platforms/slack/commands/drafts.ts +5 -14
- package/src/platforms/slack/commands/file.ts +9 -29
- package/src/platforms/slack/commands/message.ts +23 -67
- package/src/platforms/slack/commands/reaction.ts +19 -48
- package/src/platforms/slack/commands/saved.ts +5 -14
- package/src/platforms/slack/commands/sections.ts +4 -11
- package/src/platforms/slack/commands/snapshot.test.ts +1 -3
- package/src/platforms/slack/commands/snapshot.ts +5 -10
- package/src/platforms/slack/commands/unread.test.ts +6 -8
- package/src/platforms/slack/commands/unread.ts +10 -33
- package/src/platforms/slack/commands/user.test.ts +1 -4
- package/src/platforms/slack/commands/user.ts +6 -8
- package/src/platforms/slack/commands/workspace.test.ts +1 -1
- package/src/platforms/slack/commands/workspace.ts +7 -12
- package/src/platforms/slack/token-extractor-node-test.ts +1 -1
- package/src/platforms/slack/token-extractor.ts +8 -17
- package/src/platforms/slack/types.ts +1 -1
- package/src/platforms/slackbot/cli.ts +24 -0
- package/src/platforms/slackbot/client.test.ts +282 -0
- package/src/platforms/slackbot/client.ts +394 -0
- package/src/platforms/slackbot/commands/auth.test.ts +245 -0
- package/src/platforms/slackbot/commands/auth.ts +240 -0
- package/src/platforms/slackbot/commands/channel.ts +46 -0
- package/src/platforms/slackbot/commands/index.ts +5 -0
- package/src/platforms/slackbot/commands/message.ts +169 -0
- package/src/platforms/slackbot/commands/reaction.ts +49 -0
- package/src/platforms/slackbot/commands/shared.ts +21 -0
- package/src/platforms/slackbot/commands/user.ts +46 -0
- package/src/platforms/slackbot/credential-manager.test.ts +264 -0
- package/src/platforms/slackbot/credential-manager.ts +213 -0
- package/src/platforms/slackbot/index.ts +19 -0
- package/src/platforms/slackbot/types.test.ts +90 -0
- package/src/platforms/slackbot/types.ts +222 -0
- package/src/platforms/teams/client.test.ts +15 -32
- package/src/platforms/teams/client.ts +18 -51
- package/src/platforms/teams/commands/auth.test.ts +6 -16
- package/src/platforms/teams/commands/auth.ts +16 -26
- package/src/platforms/teams/commands/channel.test.ts +2 -5
- package/src/platforms/teams/commands/channel.ts +10 -20
- package/src/platforms/teams/commands/file.test.ts +1 -4
- package/src/platforms/teams/commands/file.ts +11 -21
- package/src/platforms/teams/commands/message.test.ts +1 -3
- package/src/platforms/teams/commands/message.ts +15 -25
- package/src/platforms/teams/commands/reaction.test.ts +2 -7
- package/src/platforms/teams/commands/reaction.ts +12 -16
- package/src/platforms/teams/commands/snapshot.ts +6 -11
- package/src/platforms/teams/commands/team.test.ts +15 -26
- package/src/platforms/teams/commands/team.ts +10 -19
- package/src/platforms/teams/commands/user.ts +8 -14
- package/src/platforms/teams/credential-manager.test.ts +2 -5
- package/src/platforms/teams/token-extractor.test.ts +21 -50
- package/src/platforms/teams/token-extractor.ts +12 -20
- package/src/platforms/teams/types.ts +1 -1
- package/src/shared/utils/concurrency.test.ts +2 -2
- package/src/shared/utils/concurrency.ts +1 -1
- package/.claude/commands/release.md +0 -92
- package/dist/src/platforms/discord/commands/guild.d.ts +0 -15
- package/dist/src/platforms/discord/commands/guild.d.ts.map +0 -1
- package/dist/src/platforms/discord/commands/guild.js +0 -102
- package/dist/src/platforms/discord/commands/guild.js.map +0 -1
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# workspace-summary.sh - Generate a workspace summary via bot token
|
|
4
|
+
#
|
|
5
|
+
# Usage:
|
|
6
|
+
# ./workspace-summary.sh [--json]
|
|
7
|
+
#
|
|
8
|
+
# Options:
|
|
9
|
+
# --json Output raw JSON instead of formatted text
|
|
10
|
+
#
|
|
11
|
+
# Example:
|
|
12
|
+
# ./workspace-summary.sh
|
|
13
|
+
# ./workspace-summary.sh --json > summary.json
|
|
14
|
+
|
|
15
|
+
set -euo pipefail
|
|
16
|
+
|
|
17
|
+
OUTPUT_JSON=false
|
|
18
|
+
if [ $# -gt 0 ] && [ "$1" = "--json" ]; then
|
|
19
|
+
OUTPUT_JSON=true
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
RED='\033[0;31m'
|
|
23
|
+
GREEN='\033[0;32m'
|
|
24
|
+
YELLOW='\033[1;33m'
|
|
25
|
+
BLUE='\033[0;34m'
|
|
26
|
+
CYAN='\033[0;36m'
|
|
27
|
+
BOLD='\033[1m'
|
|
28
|
+
NC='\033[0m'
|
|
29
|
+
|
|
30
|
+
if ! command -v agent-slackbot &> /dev/null; then
|
|
31
|
+
echo -e "${RED}Error: agent-slackbot not found${NC}" >&2
|
|
32
|
+
echo "Install: npm install -g agent-messenger" >&2
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
AUTH_STATUS=$(agent-slackbot auth status 2>&1)
|
|
37
|
+
VALID=$(echo "$AUTH_STATUS" | jq -r '.valid // false')
|
|
38
|
+
|
|
39
|
+
if [ "$VALID" != "true" ]; then
|
|
40
|
+
echo -e "${RED}Not authenticated! Run: agent-slackbot auth set xoxb-your-token${NC}" >&2
|
|
41
|
+
exit 1
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
WORKSPACE=$(echo "$AUTH_STATUS" | jq -r '.workspace_name // "Unknown"')
|
|
45
|
+
WORKSPACE_ID=$(echo "$AUTH_STATUS" | jq -r '.workspace_id // "Unknown"')
|
|
46
|
+
BOT_NAME=$(echo "$AUTH_STATUS" | jq -r '.user // "Unknown"')
|
|
47
|
+
|
|
48
|
+
echo -e "${YELLOW}Fetching workspace data...${NC}" >&2
|
|
49
|
+
|
|
50
|
+
CHANNELS=$(agent-slackbot channel list 2>&1)
|
|
51
|
+
CHANNEL_COUNT=$(echo "$CHANNELS" | jq 'length')
|
|
52
|
+
PUBLIC_COUNT=$(echo "$CHANNELS" | jq '[.[] | select(.is_private == false)] | length')
|
|
53
|
+
PRIVATE_COUNT=$(echo "$CHANNELS" | jq '[.[] | select(.is_private == true)] | length')
|
|
54
|
+
|
|
55
|
+
USERS=$(agent-slackbot user list 2>&1)
|
|
56
|
+
USER_COUNT=$(echo "$USERS" | jq 'length')
|
|
57
|
+
|
|
58
|
+
if [ "$OUTPUT_JSON" = true ]; then
|
|
59
|
+
jq -n \
|
|
60
|
+
--arg workspace "$WORKSPACE" \
|
|
61
|
+
--arg workspace_id "$WORKSPACE_ID" \
|
|
62
|
+
--arg bot "$BOT_NAME" \
|
|
63
|
+
--argjson channels "$CHANNELS" \
|
|
64
|
+
--argjson users "$USERS" \
|
|
65
|
+
'{
|
|
66
|
+
workspace: { name: $workspace, id: $workspace_id, bot: $bot },
|
|
67
|
+
channels: $channels,
|
|
68
|
+
users: $users
|
|
69
|
+
}'
|
|
70
|
+
exit 0
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
echo ""
|
|
74
|
+
echo -e "${BOLD}${BLUE}Workspace Summary${NC}"
|
|
75
|
+
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
76
|
+
echo ""
|
|
77
|
+
echo -e "${BOLD}Workspace:${NC} $WORKSPACE"
|
|
78
|
+
echo -e "${BOLD}ID:${NC} $WORKSPACE_ID"
|
|
79
|
+
echo -e "${BOLD}Bot:${NC} $BOT_NAME"
|
|
80
|
+
echo ""
|
|
81
|
+
|
|
82
|
+
echo -e "${BOLD}${CYAN}Channels (${CHANNEL_COUNT} total)${NC}"
|
|
83
|
+
echo -e " Public: $PUBLIC_COUNT"
|
|
84
|
+
echo -e " Private: $PRIVATE_COUNT"
|
|
85
|
+
echo ""
|
|
86
|
+
|
|
87
|
+
echo -e "${BOLD}${CYAN}Channel List:${NC}"
|
|
88
|
+
echo "$CHANNELS" | jq -r '.[0:10] | .[] | " #\(.name) (\(.id))"'
|
|
89
|
+
if [ "$CHANNEL_COUNT" -gt 10 ]; then
|
|
90
|
+
echo " ... and $((CHANNEL_COUNT - 10)) more"
|
|
91
|
+
fi
|
|
92
|
+
echo ""
|
|
93
|
+
|
|
94
|
+
echo -e "${BOLD}${CYAN}Users (${USER_COUNT} total)${NC}"
|
|
95
|
+
echo ""
|
|
96
|
+
echo "$USERS" | jq -r '.[0:10] | .[] | " \(.name) - \(.real_name // "N/A") (\(.id))"'
|
|
97
|
+
if [ "$USER_COUNT" -gt 10 ]; then
|
|
98
|
+
echo " ... and $((USER_COUNT - 10)) more"
|
|
99
|
+
fi
|
|
100
|
+
echo ""
|
|
101
|
+
|
|
102
|
+
echo -e "${BOLD}${CYAN}Quick Actions:${NC}"
|
|
103
|
+
echo ""
|
|
104
|
+
FIRST_CHANNEL=$(echo "$CHANNELS" | jq -r '.[0].id // "C123"')
|
|
105
|
+
FIRST_CHANNEL_NAME=$(echo "$CHANNELS" | jq -r '.[0].name // "general"')
|
|
106
|
+
echo -e " ${GREEN}# Send message to #$FIRST_CHANNEL_NAME${NC}"
|
|
107
|
+
echo -e " agent-slackbot message send $FIRST_CHANNEL \"Hello!\""
|
|
108
|
+
echo ""
|
|
109
|
+
echo -e " ${GREEN}# List recent messages${NC}"
|
|
110
|
+
echo -e " agent-slackbot message list $FIRST_CHANNEL --limit 10"
|
|
111
|
+
echo ""
|
|
112
|
+
|
|
113
|
+
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
package/src/cli.ts
CHANGED
|
@@ -10,10 +10,7 @@ const __dirname = dirname(__filename)
|
|
|
10
10
|
|
|
11
11
|
const program = new Command()
|
|
12
12
|
|
|
13
|
-
program
|
|
14
|
-
.name('agent-messenger')
|
|
15
|
-
.description('Multi-platform messaging CLI for AI agents')
|
|
16
|
-
.version(pkg.version)
|
|
13
|
+
program.name('agent-messenger').description('Multi-platform messaging CLI for AI agents').version(pkg.version)
|
|
17
14
|
|
|
18
15
|
// Use absolute paths for CWD-independence
|
|
19
16
|
program.command('slack', 'Interact with Slack workspaces', {
|
|
@@ -11,10 +11,7 @@ describe('DiscordClient', () => {
|
|
|
11
11
|
fetchCalls = []
|
|
12
12
|
fetchResponses = []
|
|
13
13
|
fetchIndex = 0
|
|
14
|
-
;(globalThis as any).fetch = async (
|
|
15
|
-
url: string | URL | Request,
|
|
16
|
-
options?: RequestInit
|
|
17
|
-
): Promise<Response> => {
|
|
14
|
+
;(globalThis as any).fetch = async (url: string | URL | Request, options?: RequestInit): Promise<Response> => {
|
|
18
15
|
fetchCalls.push({ url: url.toString(), options })
|
|
19
16
|
const response = fetchResponses[fetchIndex]
|
|
20
17
|
fetchIndex++
|
|
@@ -45,7 +42,7 @@ describe('DiscordClient', () => {
|
|
|
45
42
|
new Response(body === null ? null : JSON.stringify(body), {
|
|
46
43
|
status,
|
|
47
44
|
headers: defaultHeaders,
|
|
48
|
-
})
|
|
45
|
+
}),
|
|
49
46
|
)
|
|
50
47
|
}
|
|
51
48
|
|
|
@@ -236,7 +233,7 @@ describe('DiscordClient', () => {
|
|
|
236
233
|
await client.addReaction('ch1', 'msg1', '👍')
|
|
237
234
|
|
|
238
235
|
expect(fetchCalls[0].url).toBe(
|
|
239
|
-
'https://discord.com/api/v10/channels/ch1/messages/msg1/reactions/%F0%9F%91%8D/@me'
|
|
236
|
+
'https://discord.com/api/v10/channels/ch1/messages/msg1/reactions/%F0%9F%91%8D/@me',
|
|
240
237
|
)
|
|
241
238
|
expect(fetchCalls[0].options?.method).toBe('PUT')
|
|
242
239
|
})
|
|
@@ -250,7 +247,7 @@ describe('DiscordClient', () => {
|
|
|
250
247
|
await client.removeReaction('ch1', 'msg1', '👍')
|
|
251
248
|
|
|
252
249
|
expect(fetchCalls[0].url).toBe(
|
|
253
|
-
'https://discord.com/api/v10/channels/ch1/messages/msg1/reactions/%F0%9F%91%8D/@me'
|
|
250
|
+
'https://discord.com/api/v10/channels/ch1/messages/msg1/reactions/%F0%9F%91%8D/@me',
|
|
254
251
|
)
|
|
255
252
|
expect(fetchCalls[0].options?.method).toBe('DELETE')
|
|
256
253
|
})
|
|
@@ -258,10 +255,7 @@ describe('DiscordClient', () => {
|
|
|
258
255
|
|
|
259
256
|
describe('listUsers', () => {
|
|
260
257
|
test('returns list of server members', async () => {
|
|
261
|
-
mockResponse([
|
|
262
|
-
{ user: { id: 'u1', username: 'user1' } },
|
|
263
|
-
{ user: { id: 'u2', username: 'user2' } },
|
|
264
|
-
])
|
|
258
|
+
mockResponse([{ user: { id: 'u1', username: 'user1' } }, { user: { id: 'u2', username: 'user2' } }])
|
|
265
259
|
|
|
266
260
|
const client = new DiscordClient('test-token')
|
|
267
261
|
const users = await client.listUsers('111')
|
|
@@ -324,9 +318,7 @@ describe('DiscordClient', () => {
|
|
|
324
318
|
author: { id: '123', username: 'user1' },
|
|
325
319
|
content: '',
|
|
326
320
|
timestamp: '2024-01-01T00:00:00.000Z',
|
|
327
|
-
attachments: [
|
|
328
|
-
{ id: 'att1', filename: 'file1.txt', size: 100, url: 'https://example.com/file1.txt' },
|
|
329
|
-
],
|
|
321
|
+
attachments: [{ id: 'att1', filename: 'file1.txt', size: 100, url: 'https://example.com/file1.txt' }],
|
|
330
322
|
},
|
|
331
323
|
{
|
|
332
324
|
id: 'msg2',
|
|
@@ -143,7 +143,7 @@ export class DiscordClient {
|
|
|
143
143
|
const errorBody = await response.json().catch(() => ({}))
|
|
144
144
|
throw new DiscordError(
|
|
145
145
|
(errorBody as any).message || `HTTP ${response.status}`,
|
|
146
|
-
(errorBody as any).code?.toString() || `http_${response.status}
|
|
146
|
+
(errorBody as any).code?.toString() || `http_${response.status}`,
|
|
147
147
|
)
|
|
148
148
|
}
|
|
149
149
|
|
|
@@ -176,7 +176,7 @@ export class DiscordClient {
|
|
|
176
176
|
const errorBody = await response.json().catch(() => ({}))
|
|
177
177
|
throw new DiscordError(
|
|
178
178
|
(errorBody as any).message || `HTTP ${response.status}`,
|
|
179
|
-
(errorBody as any).code?.toString() || `http_${response.status}
|
|
179
|
+
(errorBody as any).code?.toString() || `http_${response.status}`,
|
|
180
180
|
)
|
|
181
181
|
}
|
|
182
182
|
|
|
@@ -221,18 +221,12 @@ export class DiscordClient {
|
|
|
221
221
|
|
|
222
222
|
async addReaction(channelId: string, messageId: string, emoji: string): Promise<void> {
|
|
223
223
|
const encodedEmoji = encodeURIComponent(emoji)
|
|
224
|
-
return this.request<void>(
|
|
225
|
-
'PUT',
|
|
226
|
-
`/channels/${channelId}/messages/${messageId}/reactions/${encodedEmoji}/@me`
|
|
227
|
-
)
|
|
224
|
+
return this.request<void>('PUT', `/channels/${channelId}/messages/${messageId}/reactions/${encodedEmoji}/@me`)
|
|
228
225
|
}
|
|
229
226
|
|
|
230
227
|
async removeReaction(channelId: string, messageId: string, emoji: string): Promise<void> {
|
|
231
228
|
const encodedEmoji = encodeURIComponent(emoji)
|
|
232
|
-
return this.request<void>(
|
|
233
|
-
'DELETE',
|
|
234
|
-
`/channels/${channelId}/messages/${messageId}/reactions/${encodedEmoji}/@me`
|
|
235
|
-
)
|
|
229
|
+
return this.request<void>('DELETE', `/channels/${channelId}/messages/${messageId}/reactions/${encodedEmoji}/@me`)
|
|
236
230
|
}
|
|
237
231
|
|
|
238
232
|
async ackMessage(channelId: string, messageId: string): Promise<void> {
|
|
@@ -245,10 +239,7 @@ export class DiscordClient {
|
|
|
245
239
|
interface GuildMember {
|
|
246
240
|
user: DiscordUser
|
|
247
241
|
}
|
|
248
|
-
const members = await this.request<GuildMember[]>(
|
|
249
|
-
'GET',
|
|
250
|
-
`/guilds/${serverId}/members?limit=1000`
|
|
251
|
-
)
|
|
242
|
+
const members = await this.request<GuildMember[]>('GET', `/guilds/${serverId}/members?limit=1000`)
|
|
252
243
|
return members.map((m) => m.user)
|
|
253
244
|
}
|
|
254
245
|
|
|
@@ -266,10 +257,7 @@ export class DiscordClient {
|
|
|
266
257
|
interface MessageWithAttachments extends DiscordMessage {
|
|
267
258
|
attachments: DiscordFile[]
|
|
268
259
|
}
|
|
269
|
-
const message = await this.requestFormData<MessageWithAttachments>(
|
|
270
|
-
`/channels/${channelId}/messages`,
|
|
271
|
-
formData
|
|
272
|
-
)
|
|
260
|
+
const message = await this.requestFormData<MessageWithAttachments>(`/channels/${channelId}/messages`, formData)
|
|
273
261
|
|
|
274
262
|
return message.attachments[0]
|
|
275
263
|
}
|
|
@@ -278,10 +266,7 @@ export class DiscordClient {
|
|
|
278
266
|
interface MessageWithAttachments extends DiscordMessage {
|
|
279
267
|
attachments: DiscordFile[]
|
|
280
268
|
}
|
|
281
|
-
const messages = await this.request<MessageWithAttachments[]>(
|
|
282
|
-
'GET',
|
|
283
|
-
`/channels/${channelId}/messages?limit=100`
|
|
284
|
-
)
|
|
269
|
+
const messages = await this.request<MessageWithAttachments[]>('GET', `/channels/${channelId}/messages?limit=100`)
|
|
285
270
|
|
|
286
271
|
const files: DiscordFile[] = []
|
|
287
272
|
for (const msg of messages) {
|
|
@@ -334,25 +319,18 @@ export class DiscordClient {
|
|
|
334
319
|
return this.request<DiscordRelationship[]>('GET', '/users/@me/relationships')
|
|
335
320
|
}
|
|
336
321
|
|
|
337
|
-
async searchMembers(
|
|
338
|
-
guildId: string,
|
|
339
|
-
query: string,
|
|
340
|
-
limit: number = 10
|
|
341
|
-
): Promise<DiscordGuildMember[]> {
|
|
322
|
+
async searchMembers(guildId: string, query: string, limit: number = 10): Promise<DiscordGuildMember[]> {
|
|
342
323
|
const params = new URLSearchParams()
|
|
343
324
|
params.set('query', query)
|
|
344
325
|
params.set('limit', limit.toString())
|
|
345
326
|
|
|
346
|
-
return this.request<DiscordGuildMember[]>(
|
|
347
|
-
'GET',
|
|
348
|
-
`/guilds/${guildId}/members/search?${params.toString()}`
|
|
349
|
-
)
|
|
327
|
+
return this.request<DiscordGuildMember[]>('GET', `/guilds/${guildId}/members/search?${params.toString()}`)
|
|
350
328
|
}
|
|
351
329
|
|
|
352
330
|
async searchMessages(
|
|
353
331
|
guildId: string,
|
|
354
332
|
query: string,
|
|
355
|
-
options: DiscordSearchOptions = {}
|
|
333
|
+
options: DiscordSearchOptions = {},
|
|
356
334
|
): Promise<{ results: DiscordSearchResult[]; total: number }> {
|
|
357
335
|
const params = new URLSearchParams()
|
|
358
336
|
params.set('content', query)
|
|
@@ -381,7 +359,7 @@ export class DiscordClient {
|
|
|
381
359
|
|
|
382
360
|
const response = await this.request<DiscordSearchResponse>(
|
|
383
361
|
'GET',
|
|
384
|
-
`/guilds/${guildId}/messages/search?${params.toString()}
|
|
362
|
+
`/guilds/${guildId}/messages/search?${params.toString()}`,
|
|
385
363
|
)
|
|
386
364
|
|
|
387
365
|
const results = response.messages
|
|
@@ -413,7 +391,7 @@ export class DiscordClient {
|
|
|
413
391
|
options?: {
|
|
414
392
|
auto_archive_duration?: number
|
|
415
393
|
rate_limit_per_user?: number
|
|
416
|
-
}
|
|
394
|
+
},
|
|
417
395
|
): Promise<DiscordChannel> {
|
|
418
396
|
return this.request<DiscordChannel>('POST', `/channels/${channelId}/threads`, {
|
|
419
397
|
name,
|
|
@@ -34,14 +34,9 @@ beforeEach(() => {
|
|
|
34
34
|
servers: {},
|
|
35
35
|
})
|
|
36
36
|
|
|
37
|
-
credManagerSaveSpy = spyOn(DiscordCredentialManager.prototype, 'save').mockResolvedValue(
|
|
38
|
-
undefined
|
|
39
|
-
)
|
|
37
|
+
credManagerSaveSpy = spyOn(DiscordCredentialManager.prototype, 'save').mockResolvedValue(undefined)
|
|
40
38
|
|
|
41
|
-
credManagerClearTokenSpy = spyOn(
|
|
42
|
-
DiscordCredentialManager.prototype,
|
|
43
|
-
'clearToken'
|
|
44
|
-
).mockResolvedValue(undefined)
|
|
39
|
+
credManagerClearTokenSpy = spyOn(DiscordCredentialManager.prototype, 'clearToken').mockResolvedValue(undefined)
|
|
45
40
|
})
|
|
46
41
|
|
|
47
42
|
afterEach(() => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command } from 'commander'
|
|
2
|
-
import { handleError } from '
|
|
3
|
-
import { formatOutput } from '
|
|
2
|
+
import { handleError } from '@/shared/utils/error-handler'
|
|
3
|
+
import { formatOutput } from '@/shared/utils/output'
|
|
4
4
|
import { DiscordClient } from '../client'
|
|
5
5
|
import { DiscordCredentialManager } from '../credential-manager'
|
|
6
6
|
import { DiscordTokenExtractor } from '../token-extractor'
|
|
@@ -36,12 +36,11 @@ export async function extractAction(options: { pretty?: boolean; debug?: boolean
|
|
|
36
36
|
console.log(
|
|
37
37
|
formatOutput(
|
|
38
38
|
{
|
|
39
|
-
error:
|
|
40
|
-
'No Discord token found. Make sure Discord desktop app is installed and logged in.',
|
|
39
|
+
error: 'No Discord token found. Make sure Discord desktop app is installed and logged in.',
|
|
41
40
|
hint: options.debug ? undefined : 'Run with --debug for more info.',
|
|
42
41
|
},
|
|
43
|
-
options.pretty
|
|
44
|
-
)
|
|
42
|
+
options.pretty,
|
|
43
|
+
),
|
|
45
44
|
)
|
|
46
45
|
process.exit(1)
|
|
47
46
|
}
|
|
@@ -76,8 +75,8 @@ export async function extractAction(options: { pretty?: boolean; debug?: boolean
|
|
|
76
75
|
{
|
|
77
76
|
error: 'No servers found. Make sure you are a member of at least one Discord server.',
|
|
78
77
|
},
|
|
79
|
-
options.pretty
|
|
80
|
-
)
|
|
78
|
+
options.pretty,
|
|
79
|
+
),
|
|
81
80
|
)
|
|
82
81
|
process.exit(1)
|
|
83
82
|
}
|
|
@@ -117,8 +116,8 @@ export async function extractAction(options: { pretty?: boolean; debug?: boolean
|
|
|
117
116
|
error: `Token validation failed: ${(error as Error).message}`,
|
|
118
117
|
hint: 'Make sure your Discord token is valid and has not expired.',
|
|
119
118
|
},
|
|
120
|
-
options.pretty
|
|
121
|
-
)
|
|
119
|
+
options.pretty,
|
|
120
|
+
),
|
|
122
121
|
)
|
|
123
122
|
process.exit(1)
|
|
124
123
|
}
|
|
@@ -133,9 +132,7 @@ export async function logoutAction(options: { pretty?: boolean }): Promise<void>
|
|
|
133
132
|
const config = await credManager.load()
|
|
134
133
|
|
|
135
134
|
if (!config.token) {
|
|
136
|
-
console.log(
|
|
137
|
-
formatOutput({ error: 'Not authenticated. Run "auth extract" first.' }, options.pretty)
|
|
138
|
-
)
|
|
135
|
+
console.log(formatOutput({ error: 'Not authenticated. Run "auth extract" first.' }, options.pretty))
|
|
139
136
|
process.exit(1)
|
|
140
137
|
}
|
|
141
138
|
|
|
@@ -153,9 +150,7 @@ export async function statusAction(options: { pretty?: boolean }): Promise<void>
|
|
|
153
150
|
const config = await credManager.load()
|
|
154
151
|
|
|
155
152
|
if (!config.token) {
|
|
156
|
-
console.log(
|
|
157
|
-
formatOutput({ error: 'Not authenticated. Run "auth extract" first.' }, options.pretty)
|
|
158
|
-
)
|
|
153
|
+
console.log(formatOutput({ error: 'Not authenticated. Run "auth extract" first.' }, options.pretty))
|
|
159
154
|
process.exit(1)
|
|
160
155
|
}
|
|
161
156
|
|
|
@@ -190,17 +185,17 @@ export const authCommand = new Command('auth')
|
|
|
190
185
|
.description('Extract token from Discord desktop app')
|
|
191
186
|
.option('--pretty', 'Pretty print JSON output')
|
|
192
187
|
.option('--debug', 'Show debug output for troubleshooting')
|
|
193
|
-
.action(extractAction)
|
|
188
|
+
.action(extractAction),
|
|
194
189
|
)
|
|
195
190
|
.addCommand(
|
|
196
191
|
new Command('logout')
|
|
197
192
|
.description('Logout from Discord')
|
|
198
193
|
.option('--pretty', 'Pretty print JSON output')
|
|
199
|
-
.action(logoutAction)
|
|
194
|
+
.action(logoutAction),
|
|
200
195
|
)
|
|
201
196
|
.addCommand(
|
|
202
197
|
new Command('status')
|
|
203
198
|
.description('Show authentication status')
|
|
204
199
|
.option('--pretty', 'Pretty print JSON output')
|
|
205
|
-
.action(statusAction)
|
|
200
|
+
.action(statusAction),
|
|
206
201
|
)
|
|
@@ -15,29 +15,27 @@ beforeEach(() => {
|
|
|
15
15
|
{ id: 'ch-3', guild_id: 'guild-1', name: 'voice-channel', type: 2, topic: undefined },
|
|
16
16
|
])
|
|
17
17
|
|
|
18
|
-
clientGetChannelSpy = spyOn(DiscordClient.prototype, 'getChannel').mockImplementation(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
topic: 'General discussion',
|
|
27
|
-
}
|
|
18
|
+
clientGetChannelSpy = spyOn(DiscordClient.prototype, 'getChannel').mockImplementation(async (channelId: string) => {
|
|
19
|
+
if (channelId === 'ch-1') {
|
|
20
|
+
return {
|
|
21
|
+
id: 'ch-1',
|
|
22
|
+
guild_id: 'guild-1',
|
|
23
|
+
name: 'general',
|
|
24
|
+
type: 0,
|
|
25
|
+
topic: 'General discussion',
|
|
28
26
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
27
|
+
}
|
|
28
|
+
if (channelId === 'ch-2') {
|
|
29
|
+
return {
|
|
30
|
+
id: 'ch-2',
|
|
31
|
+
guild_id: 'guild-1',
|
|
32
|
+
name: 'announcements',
|
|
33
|
+
type: 0,
|
|
34
|
+
topic: 'Announcements',
|
|
37
35
|
}
|
|
38
|
-
throw new Error('Channel not found')
|
|
39
36
|
}
|
|
40
|
-
|
|
37
|
+
throw new Error('Channel not found')
|
|
38
|
+
})
|
|
41
39
|
|
|
42
40
|
clientGetMessagesSpy = spyOn(DiscordClient.prototype, 'getMessages').mockResolvedValue([
|
|
43
41
|
{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command } from 'commander'
|
|
2
|
-
import { handleError } from '
|
|
3
|
-
import { formatOutput } from '
|
|
2
|
+
import { handleError } from '@/shared/utils/error-handler'
|
|
3
|
+
import { formatOutput } from '@/shared/utils/output'
|
|
4
4
|
import { DiscordClient } from '../client'
|
|
5
5
|
import { DiscordCredentialManager } from '../credential-manager'
|
|
6
6
|
|
|
@@ -10,9 +10,7 @@ export async function listAction(options: { pretty?: boolean }): Promise<void> {
|
|
|
10
10
|
const config = await credManager.load()
|
|
11
11
|
|
|
12
12
|
if (!config.token || !config.current_server) {
|
|
13
|
-
console.log(
|
|
14
|
-
formatOutput({ error: 'Not authenticated. Run "auth extract" first.' }, options.pretty)
|
|
15
|
-
)
|
|
13
|
+
console.log(formatOutput({ error: 'Not authenticated. Run "auth extract" first.' }, options.pretty))
|
|
16
14
|
process.exit(1)
|
|
17
15
|
}
|
|
18
16
|
|
|
@@ -41,9 +39,7 @@ export async function infoAction(channelId: string, options: { pretty?: boolean
|
|
|
41
39
|
const config = await credManager.load()
|
|
42
40
|
|
|
43
41
|
if (!config.token) {
|
|
44
|
-
console.log(
|
|
45
|
-
formatOutput({ error: 'Not authenticated. Run "auth extract" first.' }, options.pretty)
|
|
46
|
-
)
|
|
42
|
+
console.log(formatOutput({ error: 'Not authenticated. Run "auth extract" first.' }, options.pretty))
|
|
47
43
|
process.exit(1)
|
|
48
44
|
}
|
|
49
45
|
|
|
@@ -65,18 +61,13 @@ export async function infoAction(channelId: string, options: { pretty?: boolean
|
|
|
65
61
|
}
|
|
66
62
|
}
|
|
67
63
|
|
|
68
|
-
export async function historyAction(
|
|
69
|
-
channelId: string,
|
|
70
|
-
options: { limit?: number; pretty?: boolean }
|
|
71
|
-
): Promise<void> {
|
|
64
|
+
export async function historyAction(channelId: string, options: { limit?: number; pretty?: boolean }): Promise<void> {
|
|
72
65
|
try {
|
|
73
66
|
const credManager = new DiscordCredentialManager()
|
|
74
67
|
const config = await credManager.load()
|
|
75
68
|
|
|
76
69
|
if (!config.token) {
|
|
77
|
-
console.log(
|
|
78
|
-
formatOutput({ error: 'Not authenticated. Run "auth extract" first.' }, options.pretty)
|
|
79
|
-
)
|
|
70
|
+
console.log(formatOutput({ error: 'Not authenticated. Run "auth extract" first.' }, options.pretty))
|
|
80
71
|
process.exit(1)
|
|
81
72
|
}
|
|
82
73
|
|
|
@@ -103,14 +94,14 @@ export const channelCommand = new Command('channel')
|
|
|
103
94
|
new Command('list')
|
|
104
95
|
.description('List channels in current server')
|
|
105
96
|
.option('--pretty', 'Pretty print JSON output')
|
|
106
|
-
.action(listAction)
|
|
97
|
+
.action(listAction),
|
|
107
98
|
)
|
|
108
99
|
.addCommand(
|
|
109
100
|
new Command('info')
|
|
110
101
|
.description('Get channel info')
|
|
111
102
|
.argument('<channel-id>', 'Channel ID')
|
|
112
103
|
.option('--pretty', 'Pretty print JSON output')
|
|
113
|
-
.action(infoAction)
|
|
104
|
+
.action(infoAction),
|
|
114
105
|
)
|
|
115
106
|
.addCommand(
|
|
116
107
|
new Command('history')
|
|
@@ -123,5 +114,5 @@ export const channelCommand = new Command('channel')
|
|
|
123
114
|
limit: parseInt(options.limit, 10),
|
|
124
115
|
pretty: options.pretty,
|
|
125
116
|
})
|
|
126
|
-
})
|
|
117
|
+
}),
|
|
127
118
|
)
|
|
@@ -37,9 +37,7 @@ const mockChannels: DiscordDMChannel[] = [
|
|
|
37
37
|
]
|
|
38
38
|
|
|
39
39
|
beforeEach(() => {
|
|
40
|
-
clientListDMChannelsSpy = spyOn(DiscordClient.prototype, 'listDMChannels').mockResolvedValue(
|
|
41
|
-
mockChannels
|
|
42
|
-
)
|
|
40
|
+
clientListDMChannelsSpy = spyOn(DiscordClient.prototype, 'listDMChannels').mockResolvedValue(mockChannels)
|
|
43
41
|
|
|
44
42
|
clientCreateDMSpy = spyOn(DiscordClient.prototype, 'createDM').mockResolvedValue({
|
|
45
43
|
id: '999',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command } from 'commander'
|
|
2
|
-
import { handleError } from '
|
|
3
|
-
import { formatOutput } from '
|
|
2
|
+
import { handleError } from '@/shared/utils/error-handler'
|
|
3
|
+
import { formatOutput } from '@/shared/utils/output'
|
|
4
4
|
import { DiscordClient } from '../client'
|
|
5
5
|
import { DiscordCredentialManager } from '../credential-manager'
|
|
6
6
|
import type { DiscordDMChannel } from '../types'
|
|
@@ -11,9 +11,7 @@ export async function listAction(options: { pretty?: boolean }): Promise<void> {
|
|
|
11
11
|
const config = await credManager.load()
|
|
12
12
|
|
|
13
13
|
if (!config.token) {
|
|
14
|
-
console.log(
|
|
15
|
-
formatOutput({ error: 'Not authenticated. Run "auth extract" first.' }, options.pretty)
|
|
16
|
-
)
|
|
14
|
+
console.log(formatOutput({ error: 'Not authenticated. Run "auth extract" first.' }, options.pretty))
|
|
17
15
|
process.exit(1)
|
|
18
16
|
}
|
|
19
17
|
|
|
@@ -43,9 +41,7 @@ export async function createAction(userId: string, options: { pretty?: boolean }
|
|
|
43
41
|
const config = await credManager.load()
|
|
44
42
|
|
|
45
43
|
if (!config.token) {
|
|
46
|
-
console.log(
|
|
47
|
-
formatOutput({ error: 'Not authenticated. Run "auth extract" first.' }, options.pretty)
|
|
48
|
-
)
|
|
44
|
+
console.log(formatOutput({ error: 'Not authenticated. Run "auth extract" first.' }, options.pretty))
|
|
49
45
|
process.exit(1)
|
|
50
46
|
}
|
|
51
47
|
|
|
@@ -74,12 +70,12 @@ export const dmCommand = new Command('dm')
|
|
|
74
70
|
new Command('list')
|
|
75
71
|
.description('List DM channels')
|
|
76
72
|
.option('--pretty', 'Pretty print JSON output')
|
|
77
|
-
.action(listAction)
|
|
73
|
+
.action(listAction),
|
|
78
74
|
)
|
|
79
75
|
.addCommand(
|
|
80
76
|
new Command('create')
|
|
81
77
|
.description('Create a DM channel')
|
|
82
78
|
.argument('<user-id>', 'User ID to create DM with')
|
|
83
79
|
.option('--pretty', 'Pretty print JSON output')
|
|
84
|
-
.action(createAction)
|
|
80
|
+
.action(createAction),
|
|
85
81
|
)
|