@urugus/slack-cli 0.2.4 → 0.2.6

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.
Files changed (33) hide show
  1. package/.claude/settings.local.json +8 -1
  2. package/.github/workflows/pr-validation.yml +0 -10
  3. package/README.md +93 -19
  4. package/dist/commands/send.d.ts.map +1 -1
  5. package/dist/commands/send.js +10 -1
  6. package/dist/commands/send.js.map +1 -1
  7. package/dist/commands/unread.d.ts.map +1 -1
  8. package/dist/commands/unread.js +12 -0
  9. package/dist/commands/unread.js.map +1 -1
  10. package/dist/types/commands.d.ts +2 -0
  11. package/dist/types/commands.d.ts.map +1 -1
  12. package/dist/utils/constants.d.ts +1 -0
  13. package/dist/utils/constants.d.ts.map +1 -1
  14. package/dist/utils/constants.js +1 -0
  15. package/dist/utils/constants.js.map +1 -1
  16. package/dist/utils/slack-api-client.d.ts +2 -1
  17. package/dist/utils/slack-api-client.d.ts.map +1 -1
  18. package/dist/utils/slack-api-client.js +5 -2
  19. package/dist/utils/slack-api-client.js.map +1 -1
  20. package/dist/utils/slack-operations/message-operations.d.ts +2 -1
  21. package/dist/utils/slack-operations/message-operations.d.ts.map +1 -1
  22. package/dist/utils/slack-operations/message-operations.js +13 -3
  23. package/dist/utils/slack-operations/message-operations.js.map +1 -1
  24. package/package.json +1 -1
  25. package/src/commands/send.ts +11 -1
  26. package/src/commands/unread.ts +14 -0
  27. package/src/types/commands.ts +2 -0
  28. package/src/utils/constants.ts +1 -0
  29. package/src/utils/slack-api-client.ts +10 -2
  30. package/src/utils/slack-operations/message-operations.ts +21 -4
  31. package/tests/commands/send.test.ts +69 -2
  32. package/tests/commands/unread.test.ts +60 -0
  33. package/tests/index.test.ts +4 -4
@@ -57,7 +57,14 @@
57
57
  "Bash(npx tsx:*)",
58
58
  "Bash(gh workflow view:*)",
59
59
  "Bash(git tag:*)",
60
- "Bash(./bin/dev:*)"
60
+ "Bash(./bin/dev:*)",
61
+ "Bash(git checkout:*)",
62
+ "Bash(gh pr create:*)",
63
+ "Bash(gh pr checks:*)",
64
+ "Bash(gh pr view:*)",
65
+ "Bash(gh pr merge:*)",
66
+ "Bash(git pull:*)",
67
+ "Bash(gh api graphql:*)"
61
68
  ],
62
69
  "deny": []
63
70
  }
@@ -28,16 +28,6 @@ jobs:
28
28
 
29
29
  - name: Run tests with coverage
30
30
  run: npm run test:coverage
31
-
32
- - name: Comment PR with coverage
33
- uses: ArtiomTr/jest-coverage-report-action@v2
34
- if: github.event_name == 'pull_request'
35
- with:
36
- github-token: ${{ secrets.GITHUB_TOKEN }}
37
- test-script: npm run test:coverage
38
- skip-step: all
39
- coverage-file: ./coverage/coverage-final.json
40
- base-coverage-file: ./coverage/coverage-final.json
41
31
 
42
32
  - name: Check build
43
33
  run: npm run build
package/README.md CHANGED
@@ -13,7 +13,7 @@ npm install -g @urugus/slack-cli
13
13
  You need to configure your Slack API token on first use:
14
14
 
15
15
  ```bash
16
- slack-cli config --token YOUR_SLACK_API_TOKEN
16
+ slack-cli config set --token YOUR_SLACK_API_TOKEN
17
17
  ```
18
18
 
19
19
  ## Usage
@@ -58,6 +58,12 @@ slack-cli send -c general -m "Line 1\nLine 2\nLine 3"
58
58
 
59
59
  # Send message from file
60
60
  slack-cli send -c random -f message.txt
61
+
62
+ # Reply to a thread
63
+ slack-cli send -c channel-name -m "Reply message" --thread 1719207629.000100
64
+
65
+ # Reply to a thread (short option)
66
+ slack-cli send -c channel-name -m "Reply message" -t 1719207629.000100
61
67
  ```
62
68
 
63
69
  ### List Channels
@@ -70,16 +76,29 @@ slack-cli channels
70
76
  slack-cli channels --profile work
71
77
 
72
78
  # List public channels only
73
- slack-cli channels --public
79
+ slack-cli channels --type public
74
80
 
75
81
  # List private channels only
76
- slack-cli channels --private
82
+ slack-cli channels --type private
83
+
84
+ # List all channel types including IMs and MPIMs
85
+ slack-cli channels --type all
86
+
87
+ # Include archived channels
88
+ slack-cli channels --include-archived
89
+
90
+ # Limit number of channels displayed
91
+ slack-cli channels --limit 20
92
+
93
+ # Output in different formats
94
+ slack-cli channels --format json
95
+ slack-cli channels --format simple
77
96
  ```
78
97
 
79
98
  ### View Message History
80
99
 
81
100
  ```bash
82
- # Get latest 10 messages
101
+ # Get latest 10 messages (default)
83
102
  slack-cli history -c general
84
103
 
85
104
  # Specify number of messages
@@ -87,6 +106,9 @@ slack-cli history -c general -n 20
87
106
 
88
107
  # Get messages since specific date
89
108
  slack-cli history -c general --since "2024-01-01 00:00:00"
109
+
110
+ # Use specific profile
111
+ slack-cli history -c general --profile work
90
112
  ```
91
113
 
92
114
  ### Get Unread Messages
@@ -98,14 +120,21 @@ slack-cli unread
98
120
  # Get unread messages from specific channel
99
121
  slack-cli unread -c general
100
122
 
101
- # Get unread messages with channel names
102
- slack-cli unread --show-channel
123
+ # Show only unread counts (no message content)
124
+ slack-cli unread --count-only
103
125
 
104
126
  # Mark messages as read after fetching
105
127
  slack-cli unread --mark-read
106
128
 
107
- # Get unread messages from multiple channels
108
- slack-cli unread -c general,random,development
129
+ # Mark messages as read for specific channel
130
+ slack-cli unread -c general --mark-read
131
+
132
+ # Limit number of channels displayed
133
+ slack-cli unread --limit 10
134
+
135
+ # Output in different formats
136
+ slack-cli unread --format json
137
+ slack-cli unread --format simple
109
138
  ```
110
139
 
111
140
  ### Other Commands
@@ -126,23 +155,43 @@ slack-cli config set --token NEW_TOKEN
126
155
 
127
156
  ## Options
128
157
 
158
+ ### Global Options
159
+ | Option | Short | Description |
160
+ |--------|-------|-------------|
161
+ | --profile | -p | Use specific workspace profile |
162
+
163
+ ### send command
129
164
  | Option | Short | Description |
130
165
  |--------|-------|-------------|
131
- | --channel | -c | Target channel name or ID |
166
+ | --channel | -c | Target channel name or ID (required) |
132
167
  | --message | -m | Message to send |
133
168
  | --file | -f | File containing message content |
134
- | --token | -t | Slack API token (temporary override) |
135
- | --profile | -p | Use specific workspace profile |
136
- | --format | | Message format (text/markdown) |
137
- | --verbose | -v | Show verbose output |
138
- | --show-channel | | Display channel name with unread messages |
139
- | --mark-read | | Mark messages as read after fetching |
169
+ | --thread | -t | Thread timestamp to reply to |
170
+
171
+ ### channels command
172
+ | Option | Short | Description |
173
+ |--------|-------|-------------|
174
+ | --type | | Channel type: public, private, im, mpim, all (default: public) |
175
+ | --include-archived | | Include archived channels |
176
+ | --format | | Output format: table, simple, json (default: table) |
177
+ | --limit | | Maximum number of channels to list (default: 100) |
178
+
179
+ ### history command
180
+ | Option | Short | Description |
181
+ |--------|-------|-------------|
182
+ | --channel | -c | Target channel name or ID (required) |
183
+ | --number | -n | Number of messages to retrieve (default: 10) |
184
+ | --since | | Get messages since specific date (YYYY-MM-DD HH:MM:SS) |
140
185
 
141
- ## Environment Variables
186
+ ### unread command
187
+ | Option | Short | Description |
188
+ |--------|-------|-------------|
189
+ | --channel | -c | Get unread for specific channel |
190
+ | --format | | Output format: table, simple, json (default: table) |
191
+ | --count-only | | Show only unread counts |
192
+ | --limit | | Maximum number of channels to display (default: 50) |
193
+ | --mark-read | | Mark messages as read after fetching |
142
194
 
143
- - `SLACK_API_TOKEN`: Default API token (used when no profile is configured)
144
- - `SLACK_DEFAULT_CHANNEL`: Default target channel
145
- - `SLACK_DEFAULT_PROFILE`: Default profile to use
146
195
 
147
196
  ## Required Permissions
148
197
 
@@ -156,6 +205,31 @@ Your Slack API token needs the following scopes:
156
205
  - `im:history` - Read direct message history
157
206
  - `users:read` - Access user information for unread counts
158
207
 
208
+ ## Advanced Features
209
+
210
+ ### Rate Limiting
211
+ The CLI includes built-in rate limiting to handle Slack API limits:
212
+ - Concurrent requests: 3
213
+ - Automatic retry with exponential backoff (max 3 retries)
214
+ - Graceful error handling for rate limit errors
215
+
216
+ ### Output Formats
217
+ Most commands support multiple output formats:
218
+ - `table` (default) - Human-readable table format
219
+ - `simple` - Simplified text output
220
+ - `json` - Machine-readable JSON format
221
+
222
+ ### Markdown Support
223
+ Messages sent via the `send` command automatically support Slack's mrkdwn formatting:
224
+ - `*bold*` for bold text
225
+ - `_italic_` for italic text
226
+ - `~strikethrough~` for strikethrough
227
+ - `` `code` `` for inline code
228
+ - ` ```code blocks``` ` for multiline code
229
+ - Links are automatically hyperlinked
230
+ - User mentions: `<@USER_ID>`
231
+ - Channel mentions: `<#CHANNEL_ID>`
232
+
159
233
  ## License
160
234
 
161
235
  MIT
@@ -1 +1 @@
1
- {"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../src/commands/send.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,wBAAgB,gBAAgB,IAAI,OAAO,CAyC1C"}
1
+ {"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../src/commands/send.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBpC,wBAAgB,gBAAgB,IAAI,OAAO,CA6C1C"}
@@ -45,12 +45,18 @@ const client_factory_1 = require("../utils/client-factory");
45
45
  const errors_1 = require("../utils/errors");
46
46
  const error_utils_1 = require("../utils/error-utils");
47
47
  const fs = __importStar(require("fs/promises"));
48
+ function isValidThreadTimestamp(timestamp) {
49
+ // Slack timestamp format: 1234567890.123456
50
+ const timestampRegex = /^\d{10}\.\d{6}$/;
51
+ return timestampRegex.test(timestamp);
52
+ }
48
53
  function setupSendCommand() {
49
54
  const sendCommand = new commander_1.Command('send')
50
55
  .description('Send a message to a Slack channel')
51
56
  .requiredOption('-c, --channel <channel>', 'Target channel name or ID')
52
57
  .option('-m, --message <message>', 'Message to send')
53
58
  .option('-f, --file <file>', 'File containing message content')
59
+ .option('-t, --thread <thread>', 'Thread timestamp to reply to')
54
60
  .option('--profile <profile>', 'Use specific workspace profile')
55
61
  .hook('preAction', (thisCommand) => {
56
62
  const options = thisCommand.opts();
@@ -60,6 +66,9 @@ function setupSendCommand() {
60
66
  if (options.message && options.file) {
61
67
  thisCommand.error(`Error: ${constants_1.ERROR_MESSAGES.BOTH_MESSAGE_AND_FILE}`);
62
68
  }
69
+ if (options.thread && !isValidThreadTimestamp(options.thread)) {
70
+ thisCommand.error(`Error: ${constants_1.ERROR_MESSAGES.INVALID_THREAD_TIMESTAMP}`);
71
+ }
63
72
  })
64
73
  .action((0, command_wrapper_1.wrapCommand)(async (options) => {
65
74
  // Get message content
@@ -77,7 +86,7 @@ function setupSendCommand() {
77
86
  }
78
87
  // Send message
79
88
  const client = await (0, client_factory_1.createSlackClient)(options.profile);
80
- await client.sendMessage(options.channel, messageContent);
89
+ await client.sendMessage(options.channel, messageContent, options.thread);
81
90
  console.log(chalk_1.default.green(`✓ ${constants_1.SUCCESS_MESSAGES.MESSAGE_SENT(options.channel)}`));
82
91
  }));
83
92
  return sendCommand;
@@ -1 +1 @@
1
- {"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/commands/send.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUA,4CAyCC;AAnDD,yCAAoC;AACpC,kDAA0B;AAC1B,8DAAuD;AACvD,kDAAsE;AACtE,4DAA4D;AAC5D,4CAA4C;AAE5C,sDAA2D;AAC3D,gDAAkC;AAElC,SAAgB,gBAAgB;IAC9B,MAAM,WAAW,GAAG,IAAI,mBAAO,CAAC,MAAM,CAAC;SACpC,WAAW,CAAC,mCAAmC,CAAC;SAChD,cAAc,CAAC,yBAAyB,EAAE,2BAA2B,CAAC;SACtE,MAAM,CAAC,yBAAyB,EAAE,iBAAiB,CAAC;SACpD,MAAM,CAAC,mBAAmB,EAAE,iCAAiC,CAAC;SAC9D,MAAM,CAAC,qBAAqB,EAAE,gCAAgC,CAAC;SAC/D,IAAI,CAAC,WAAW,EAAE,CAAC,WAAW,EAAE,EAAE;QACjC,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACtC,WAAW,CAAC,KAAK,CAAC,UAAU,0BAAc,CAAC,kBAAkB,EAAE,CAAC,CAAC;QACnE,CAAC;QACD,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACpC,WAAW,CAAC,KAAK,CAAC,UAAU,0BAAc,CAAC,qBAAqB,EAAE,CAAC,CAAC;QACtE,CAAC;IACH,CAAC,CAAC;SACD,MAAM,CACL,IAAA,6BAAW,EAAC,KAAK,EAAE,OAAoB,EAAE,EAAE;QACzC,sBAAsB;QACtB,IAAI,cAAsB,CAAC;QAC3B,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,IAAI,CAAC;gBACH,cAAc,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAC5D,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,kBAAS,CACjB,0BAAc,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,EAAE,IAAA,iCAAmB,EAAC,KAAK,CAAC,CAAC,CACzE,CAAC;YACJ,CAAC;QACH,CAAC;aAAM,CAAC;YACN,cAAc,GAAG,OAAO,CAAC,OAAQ,CAAC,CAAC,+CAA+C;QACpF,CAAC;QAED,eAAe;QACf,MAAM,MAAM,GAAG,MAAM,IAAA,kCAAiB,EAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACxD,MAAM,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;QAE1D,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,KAAK,4BAAgB,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;IAClF,CAAC,CAAC,CACH,CAAC;IAEJ,OAAO,WAAW,CAAC;AACrB,CAAC"}
1
+ {"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/commands/send.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgBA,4CA6CC;AA7DD,yCAAoC;AACpC,kDAA0B;AAC1B,8DAAuD;AACvD,kDAAsE;AACtE,4DAA4D;AAC5D,4CAA4C;AAE5C,sDAA2D;AAC3D,gDAAkC;AAElC,SAAS,sBAAsB,CAAC,SAAiB;IAC/C,4CAA4C;IAC5C,MAAM,cAAc,GAAG,iBAAiB,CAAC;IACzC,OAAO,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AACxC,CAAC;AAED,SAAgB,gBAAgB;IAC9B,MAAM,WAAW,GAAG,IAAI,mBAAO,CAAC,MAAM,CAAC;SACpC,WAAW,CAAC,mCAAmC,CAAC;SAChD,cAAc,CAAC,yBAAyB,EAAE,2BAA2B,CAAC;SACtE,MAAM,CAAC,yBAAyB,EAAE,iBAAiB,CAAC;SACpD,MAAM,CAAC,mBAAmB,EAAE,iCAAiC,CAAC;SAC9D,MAAM,CAAC,uBAAuB,EAAE,8BAA8B,CAAC;SAC/D,MAAM,CAAC,qBAAqB,EAAE,gCAAgC,CAAC;SAC/D,IAAI,CAAC,WAAW,EAAE,CAAC,WAAW,EAAE,EAAE;QACjC,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACtC,WAAW,CAAC,KAAK,CAAC,UAAU,0BAAc,CAAC,kBAAkB,EAAE,CAAC,CAAC;QACnE,CAAC;QACD,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACpC,WAAW,CAAC,KAAK,CAAC,UAAU,0BAAc,CAAC,qBAAqB,EAAE,CAAC,CAAC;QACtE,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9D,WAAW,CAAC,KAAK,CAAC,UAAU,0BAAc,CAAC,wBAAwB,EAAE,CAAC,CAAC;QACzE,CAAC;IACH,CAAC,CAAC;SACD,MAAM,CACL,IAAA,6BAAW,EAAC,KAAK,EAAE,OAAoB,EAAE,EAAE;QACzC,sBAAsB;QACtB,IAAI,cAAsB,CAAC;QAC3B,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,IAAI,CAAC;gBACH,cAAc,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAC5D,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,kBAAS,CACjB,0BAAc,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,EAAE,IAAA,iCAAmB,EAAC,KAAK,CAAC,CAAC,CACzE,CAAC;YACJ,CAAC;QACH,CAAC;aAAM,CAAC;YACN,cAAc,GAAG,OAAO,CAAC,OAAQ,CAAC,CAAC,+CAA+C;QACpF,CAAC;QAED,eAAe;QACf,MAAM,MAAM,GAAG,MAAM,IAAA,kCAAiB,EAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACxD,MAAM,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAE1E,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,KAAK,4BAAgB,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;IAClF,CAAC,CAAC,CACH,CAAC;IAEJ,OAAO,WAAW,CAAC;AACrB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"unread.d.ts","sourceRoot":"","sources":["../../src/commands/unread.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoDpC,wBAAgB,kBAAkB,IAAI,OAAO,CAyB5C"}
1
+ {"version":3,"file":"unread.d.ts","sourceRoot":"","sources":["../../src/commands/unread.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiEpC,wBAAgB,kBAAkB,IAAI,OAAO,CA0B5C"}
@@ -24,6 +24,10 @@ async function handleSpecificChannelUnread(client, options) {
24
24
  countOnly: countOnly,
25
25
  format: format,
26
26
  });
27
+ if ((0, option_parsers_1.parseBoolean)(options.markRead)) {
28
+ await client.markAsRead(result.channel.id);
29
+ console.log(chalk_1.default.green(`✓ Marked messages in #${result.channel.name} as read`));
30
+ }
27
31
  }
28
32
  async function handleAllChannelsUnread(client, options) {
29
33
  const channels = await client.listUnreadChannels();
@@ -38,6 +42,13 @@ async function handleAllChannelsUnread(client, options) {
38
42
  const countOnly = (0, option_parsers_1.parseBoolean)(options.countOnly);
39
43
  const formatter = (0, channel_formatters_1.createChannelFormatter)(format, countOnly);
40
44
  formatter.format({ channels: displayChannels, countOnly: countOnly });
45
+ if ((0, option_parsers_1.parseBoolean)(options.markRead)) {
46
+ // Mark all unread channels as read
47
+ for (const channel of channels) {
48
+ await client.markAsRead(channel.id);
49
+ }
50
+ console.log(chalk_1.default.green('✓ Marked all messages as read'));
51
+ }
41
52
  }
42
53
  function setupUnreadCommand() {
43
54
  const unreadCommand = new commander_1.Command('unread')
@@ -46,6 +57,7 @@ function setupUnreadCommand() {
46
57
  .option('--format <format>', 'Output format: table, simple, json', 'table')
47
58
  .option('--count-only', 'Show only unread counts', false)
48
59
  .option('--limit <number>', 'Maximum number of channels to display', constants_1.DEFAULTS.UNREAD_DISPLAY_LIMIT.toString())
60
+ .option('--mark-read', 'Mark messages as read after fetching', false)
49
61
  .option('--profile <profile>', 'Use specific workspace profile')
50
62
  .action((0, command_wrapper_1.wrapCommand)(async (options) => {
51
63
  const client = await (0, client_factory_1.createSlackClient)(options.profile);
@@ -1 +1 @@
1
- {"version":3,"file":"unread.js","sourceRoot":"","sources":["../../src/commands/unread.ts"],"names":[],"mappings":";;;;;AAoDA,gDAyBC;AA7ED,yCAAoC;AACpC,8DAAuD;AACvD,4DAA4D;AAG5D,kDAA0B;AAC1B,+EAAgF;AAChF,+EAAgF;AAChF,kDAA8C;AAC9C,4DAAgF;AAEhF,KAAK,UAAU,2BAA2B,CACxC,MAAsB,EACtB,OAAsB;IAEtB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAQ,CAAC,CAAC;IAE/D,MAAM,MAAM,GAAG,IAAA,4BAAW,EAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,IAAA,6BAAY,EAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAElD,MAAM,SAAS,GAAG,IAAA,2CAAsB,EAAC,MAAM,CAAC,CAAC;IACjD,SAAS,CAAC,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,SAAS,EAAE,SAAS;QACpB,MAAM,EAAE,MAAM;KACf,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,uBAAuB,CACpC,MAAsB,EACtB,OAAsB;IAEtB,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,kBAAkB,EAAE,CAAC;IAEnD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,CAAC;QACjD,OAAO;IACT,CAAC;IAED,cAAc;IACd,MAAM,KAAK,GAAG,IAAA,2BAAU,EAAC,OAAO,CAAC,KAAK,EAAE,oBAAQ,CAAC,oBAAoB,CAAC,CAAC;IACvE,MAAM,eAAe,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAEjD,MAAM,MAAM,GAAG,IAAA,4BAAW,EAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,IAAA,6BAAY,EAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAElD,MAAM,SAAS,GAAG,IAAA,2CAAsB,EAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC5D,SAAS,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,eAAe,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;AACxE,CAAC;AAED,SAAgB,kBAAkB;IAChC,MAAM,aAAa,GAAG,IAAI,mBAAO,CAAC,QAAQ,CAAC;SACxC,WAAW,CAAC,sCAAsC,CAAC;SACnD,MAAM,CAAC,yBAAyB,EAAE,oCAAoC,CAAC;SACvE,MAAM,CAAC,mBAAmB,EAAE,oCAAoC,EAAE,OAAO,CAAC;SAC1E,MAAM,CAAC,cAAc,EAAE,yBAAyB,EAAE,KAAK,CAAC;SACxD,MAAM,CACL,kBAAkB,EAClB,uCAAuC,EACvC,oBAAQ,CAAC,oBAAoB,CAAC,QAAQ,EAAE,CACzC;SACA,MAAM,CAAC,qBAAqB,EAAE,gCAAgC,CAAC;SAC/D,MAAM,CACL,IAAA,6BAAW,EAAC,KAAK,EAAE,OAAsB,EAAE,EAAE;QAC3C,MAAM,MAAM,GAAG,MAAM,IAAA,kCAAiB,EAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAExD,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,2BAA2B,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACN,MAAM,uBAAuB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACjD,CAAC;IACH,CAAC,CAAC,CACH,CAAC;IAEJ,OAAO,aAAa,CAAC;AACvB,CAAC"}
1
+ {"version":3,"file":"unread.js","sourceRoot":"","sources":["../../src/commands/unread.ts"],"names":[],"mappings":"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"}
@@ -15,6 +15,7 @@ export interface SendOptions {
15
15
  channel: string;
16
16
  message?: string;
17
17
  file?: string;
18
+ thread?: string;
18
19
  profile?: string;
19
20
  }
20
21
  export interface ChannelsOptions {
@@ -35,6 +36,7 @@ export interface UnreadOptions {
35
36
  format?: 'table' | 'simple' | 'json';
36
37
  countOnly?: boolean;
37
38
  limit?: string;
39
+ markRead?: boolean;
38
40
  profile?: string;
39
41
  }
40
42
  //# sourceMappingURL=commands.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/types/commands.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,KAAK,CAAC;IACnD,eAAe,EAAE,OAAO,CAAC;IACzB,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB"}
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/types/commands.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,KAAK,CAAC;IACnD,eAAe,EAAE,OAAO,CAAC;IACzB,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB"}
@@ -8,6 +8,7 @@ export declare const ERROR_MESSAGES: {
8
8
  readonly INVALID_CONFIG_FORMAT: "Invalid config file format";
9
9
  readonly NO_MESSAGE_OR_FILE: "You must specify either --message or --file";
10
10
  readonly BOTH_MESSAGE_AND_FILE: "Cannot use both --message and --file";
11
+ readonly INVALID_THREAD_TIMESTAMP: "Invalid thread timestamp format";
11
12
  readonly API_ERROR: (error: string) => string;
12
13
  readonly CHANNEL_NOT_FOUND: (channel: string) => string;
13
14
  readonly FILE_READ_ERROR: (file: string, error: string) => string;
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/utils/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,IAAI,CAAC;AACnC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,oBAAoB,YAAY,CAAC;AAE9C,eAAO,MAAM,cAAc;sCAEA,MAAM;8CAEE,MAAM;;;;;gCASpB,MAAM;0CACI,MAAM;qCAGX,MAAM,SAAS,MAAM;oCACtB,MAAM;;6CAIG,MAAM;CAC9B,CAAC;AAEX,eAAO,MAAM,gBAAgB;wCACA,MAAM;6CACD,MAAM;4CACP,MAAM;qCACb,MAAM;CACtB,CAAC;AAGX,eAAO,MAAM,gBAAgB;;CAE5B,CAAC;AAGF,eAAO,MAAM,UAAU;;;;CAItB,CAAC;AAGF,eAAO,MAAM,UAAU;;;;;;;;;;CAUtB,CAAC;AAGF,eAAO,MAAM,QAAQ;;;;CAIpB,CAAC;AAGF,eAAO,MAAM,WAAW,wBAAwB,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/utils/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,IAAI,CAAC;AACnC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,oBAAoB,YAAY,CAAC;AAE9C,eAAO,MAAM,cAAc;sCAEA,MAAM;8CAEE,MAAM;;;;;;gCAUpB,MAAM;0CACI,MAAM;qCAGX,MAAM,SAAS,MAAM;oCACtB,MAAM;;6CAIG,MAAM;CAC9B,CAAC;AAEX,eAAO,MAAM,gBAAgB;wCACA,MAAM;6CACD,MAAM;4CACP,MAAM;qCACb,MAAM;CACtB,CAAC;AAGX,eAAO,MAAM,gBAAgB;;CAE5B,CAAC;AAGF,eAAO,MAAM,UAAU;;;;CAItB,CAAC;AAGF,eAAO,MAAM,UAAU;;;;;;;;;;CAUtB,CAAC;AAGF,eAAO,MAAM,QAAQ;;;;CAIpB,CAAC;AAGF,eAAO,MAAM,WAAW,wBAAwB,CAAC"}
@@ -13,6 +13,7 @@ exports.ERROR_MESSAGES = {
13
13
  // Validation errors
14
14
  NO_MESSAGE_OR_FILE: 'You must specify either --message or --file',
15
15
  BOTH_MESSAGE_AND_FILE: 'Cannot use both --message and --file',
16
+ INVALID_THREAD_TIMESTAMP: 'Invalid thread timestamp format',
16
17
  // API errors
17
18
  API_ERROR: (error) => `API Error: ${error}`,
18
19
  CHANNEL_NOT_FOUND: (channel) => `Channel not found: ${channel}`,
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/utils/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,iBAAiB,GAAG,CAAC,CAAC;AACtB,QAAA,gBAAgB,GAAG,CAAC,CAAC;AACrB,QAAA,oBAAoB,GAAG,SAAS,CAAC;AAEjC,QAAA,cAAc,GAAG;IAC5B,uBAAuB;IACvB,SAAS,EAAE,CAAC,WAAmB,EAAE,EAAE,CACjC,uCAAuC,WAAW,0DAA0D,WAAW,cAAc;IACvI,iBAAiB,EAAE,CAAC,WAAmB,EAAE,EAAE,CAAC,YAAY,WAAW,aAAa;IAChF,iBAAiB,EAAE,8EAA8E;IACjG,qBAAqB,EAAE,4BAA4B;IAEnD,oBAAoB;IACpB,kBAAkB,EAAE,6CAA6C;IACjE,qBAAqB,EAAE,sCAAsC;IAE7D,aAAa;IACb,SAAS,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,cAAc,KAAK,EAAE;IACnD,iBAAiB,EAAE,CAAC,OAAe,EAAE,EAAE,CAAC,sBAAsB,OAAO,EAAE;IAEvE,cAAc;IACd,eAAe,EAAE,CAAC,IAAY,EAAE,KAAa,EAAE,EAAE,CAAC,sBAAsB,IAAI,KAAK,KAAK,EAAE;IACxF,cAAc,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,mBAAmB,IAAI,EAAE;IAE3D,0BAA0B;IAC1B,iBAAiB,EAAE,mBAAmB;IACtC,sBAAsB,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,2BAA2B,KAAK,EAAE;CACrE,CAAC;AAEE,QAAA,gBAAgB,GAAG;IAC9B,WAAW,EAAE,CAAC,WAAmB,EAAE,EAAE,CAAC,yCAAyC,WAAW,GAAG;IAC7F,gBAAgB,EAAE,CAAC,WAAmB,EAAE,EAAE,CAAC,wBAAwB,WAAW,GAAG;IACjF,eAAe,EAAE,CAAC,WAAmB,EAAE,EAAE,CAAC,YAAY,WAAW,wBAAwB;IACzF,YAAY,EAAE,CAAC,OAAe,EAAE,EAAE,CAAC,iCAAiC,OAAO,EAAE;CACrE,CAAC;AAEX,4BAA4B;AACf,QAAA,gBAAgB,GAAG;IAC9B,WAAW,EAAE,KAAK,EAAE,4BAA4B;CACjD,CAAC;AAEF,aAAa;AACA,QAAA,UAAU,GAAG;IACxB,iBAAiB,EAAE,IAAI;IACvB,iBAAiB,EAAE,CAAC;IACpB,qBAAqB,EAAE,EAAE;CAC1B,CAAC;AAEF,kCAAkC;AACrB,QAAA,UAAU,GAAG;IACxB,mBAAmB,EAAE,CAAC;IACtB,UAAU,EAAE,EAAE;IACd,cAAc,EAAE,IAAI;IACpB,YAAY,EAAE;QACZ,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,CAAC;QACT,UAAU,EAAE,IAAI;QAChB,UAAU,EAAE,KAAK;KAClB;CACF,CAAC;AAEF,iBAAiB;AACJ,QAAA,QAAQ,GAAG;IACtB,aAAa,EAAE,EAAE;IACjB,cAAc,EAAE,IAAI;IACpB,oBAAoB,EAAE,EAAE;CACzB,CAAC;AAEF,eAAe;AACF,QAAA,WAAW,GAAG,qBAAqB,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/utils/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,iBAAiB,GAAG,CAAC,CAAC;AACtB,QAAA,gBAAgB,GAAG,CAAC,CAAC;AACrB,QAAA,oBAAoB,GAAG,SAAS,CAAC;AAEjC,QAAA,cAAc,GAAG;IAC5B,uBAAuB;IACvB,SAAS,EAAE,CAAC,WAAmB,EAAE,EAAE,CACjC,uCAAuC,WAAW,0DAA0D,WAAW,cAAc;IACvI,iBAAiB,EAAE,CAAC,WAAmB,EAAE,EAAE,CAAC,YAAY,WAAW,aAAa;IAChF,iBAAiB,EAAE,8EAA8E;IACjG,qBAAqB,EAAE,4BAA4B;IAEnD,oBAAoB;IACpB,kBAAkB,EAAE,6CAA6C;IACjE,qBAAqB,EAAE,sCAAsC;IAC7D,wBAAwB,EAAE,iCAAiC;IAE3D,aAAa;IACb,SAAS,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,cAAc,KAAK,EAAE;IACnD,iBAAiB,EAAE,CAAC,OAAe,EAAE,EAAE,CAAC,sBAAsB,OAAO,EAAE;IAEvE,cAAc;IACd,eAAe,EAAE,CAAC,IAAY,EAAE,KAAa,EAAE,EAAE,CAAC,sBAAsB,IAAI,KAAK,KAAK,EAAE;IACxF,cAAc,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,mBAAmB,IAAI,EAAE;IAE3D,0BAA0B;IAC1B,iBAAiB,EAAE,mBAAmB;IACtC,sBAAsB,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,2BAA2B,KAAK,EAAE;CACrE,CAAC;AAEE,QAAA,gBAAgB,GAAG;IAC9B,WAAW,EAAE,CAAC,WAAmB,EAAE,EAAE,CAAC,yCAAyC,WAAW,GAAG;IAC7F,gBAAgB,EAAE,CAAC,WAAmB,EAAE,EAAE,CAAC,wBAAwB,WAAW,GAAG;IACjF,eAAe,EAAE,CAAC,WAAmB,EAAE,EAAE,CAAC,YAAY,WAAW,wBAAwB;IACzF,YAAY,EAAE,CAAC,OAAe,EAAE,EAAE,CAAC,iCAAiC,OAAO,EAAE;CACrE,CAAC;AAEX,4BAA4B;AACf,QAAA,gBAAgB,GAAG;IAC9B,WAAW,EAAE,KAAK,EAAE,4BAA4B;CACjD,CAAC;AAEF,aAAa;AACA,QAAA,UAAU,GAAG;IACxB,iBAAiB,EAAE,IAAI;IACvB,iBAAiB,EAAE,CAAC;IACpB,qBAAqB,EAAE,EAAE;CAC1B,CAAC;AAEF,kCAAkC;AACrB,QAAA,UAAU,GAAG;IACxB,mBAAmB,EAAE,CAAC;IACtB,UAAU,EAAE,EAAE;IACd,cAAc,EAAE,IAAI;IACpB,YAAY,EAAE;QACZ,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,CAAC;QACT,UAAU,EAAE,IAAI;QAChB,UAAU,EAAE,KAAK;KAClB;CACF,CAAC;AAEF,iBAAiB;AACJ,QAAA,QAAQ,GAAG;IACtB,aAAa,EAAE,EAAE;IACjB,cAAc,EAAE,IAAI;IACpB,oBAAoB,EAAE,EAAE;CACzB,CAAC;AAEF,eAAe;AACF,QAAA,WAAW,GAAG,qBAAqB,CAAC"}
@@ -63,11 +63,12 @@ export declare class SlackApiClient {
63
63
  private channelOps;
64
64
  private messageOps;
65
65
  constructor(token: string);
66
- sendMessage(channel: string, text: string): Promise<ChatPostMessageResponse>;
66
+ sendMessage(channel: string, text: string, thread_ts?: string): Promise<ChatPostMessageResponse>;
67
67
  listChannels(options: ListChannelsOptions): Promise<Channel[]>;
68
68
  getHistory(channel: string, options: HistoryOptions): Promise<HistoryResult>;
69
69
  listUnreadChannels(): Promise<Channel[]>;
70
70
  getChannelUnread(channelNameOrId: string): Promise<ChannelUnreadResult>;
71
+ markAsRead(channelId: string): Promise<void>;
71
72
  }
72
73
  export declare const slackApiClient: {
73
74
  listChannels: (token: string, options: ListChannelsOptions) => Promise<Channel[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"slack-api-client.d.ts","sourceRoot":"","sources":["../../src/utils/slack-api-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"slack-api-client.d.ts","sourceRoot":"","sources":["../../src/utils/slack-api-client.ts"],"names":[],"mappings":"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"}
@@ -8,8 +8,8 @@ class SlackApiClient {
8
8
  this.channelOps = new channel_operations_1.ChannelOperations(token);
9
9
  this.messageOps = new message_operations_1.MessageOperations(token);
10
10
  }
11
- async sendMessage(channel, text) {
12
- return this.messageOps.sendMessage(channel, text);
11
+ async sendMessage(channel, text, thread_ts) {
12
+ return this.messageOps.sendMessage(channel, text, thread_ts);
13
13
  }
14
14
  async listChannels(options) {
15
15
  return this.channelOps.listChannels(options);
@@ -23,6 +23,9 @@ class SlackApiClient {
23
23
  async getChannelUnread(channelNameOrId) {
24
24
  return this.messageOps.getChannelUnread(channelNameOrId);
25
25
  }
26
+ async markAsRead(channelId) {
27
+ return this.messageOps.markAsRead(channelId);
28
+ }
26
29
  }
27
30
  exports.SlackApiClient = SlackApiClient;
28
31
  exports.slackApiClient = {
@@ -1 +1 @@
1
- {"version":3,"file":"slack-api-client.js","sourceRoot":"","sources":["../../src/utils/slack-api-client.ts"],"names":[],"mappings":";;;AACA,8EAA0E;AAC1E,8EAA0E;AAoE1E,MAAa,cAAc;IAIzB,YAAY,KAAa;QACvB,IAAI,CAAC,UAAU,GAAG,IAAI,sCAAiB,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,CAAC,UAAU,GAAG,IAAI,sCAAiB,CAAC,KAAK,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAAe,EAAE,IAAY;QAC7C,OAAO,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,OAA4B;QAC7C,OAAO,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,OAAe,EAAE,OAAuB;QACvD,OAAO,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,kBAAkB;QACtB,OAAO,IAAI,CAAC,UAAU,CAAC,kBAAkB,EAAE,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,eAAuB;QAC5C,OAAO,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC;IAC3D,CAAC;CACF;AA5BD,wCA4BC;AAEY,QAAA,cAAc,GAAG;IAC5B,YAAY,EAAE,KAAK,EAAE,KAAa,EAAE,OAA4B,EAAsB,EAAE;QACtF,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,KAAK,CAAC,CAAC;QACzC,OAAO,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"slack-api-client.js","sourceRoot":"","sources":["../../src/utils/slack-api-client.ts"],"names":[],"mappings":";;;AACA,8EAA0E;AAC1E,8EAA0E;AAoE1E,MAAa,cAAc;IAIzB,YAAY,KAAa;QACvB,IAAI,CAAC,UAAU,GAAG,IAAI,sCAAiB,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,CAAC,UAAU,GAAG,IAAI,sCAAiB,CAAC,KAAK,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,WAAW,CACf,OAAe,EACf,IAAY,EACZ,SAAkB;QAElB,OAAO,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;IAC/D,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,OAA4B;QAC7C,OAAO,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,OAAe,EAAE,OAAuB;QACvD,OAAO,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,kBAAkB;QACtB,OAAO,IAAI,CAAC,UAAU,CAAC,kBAAkB,EAAE,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,eAAuB;QAC5C,OAAO,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC;IAC3D,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,SAAiB;QAChC,OAAO,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC;CACF;AApCD,wCAoCC;AAEY,QAAA,cAAc,GAAG;IAC5B,YAAY,EAAE,KAAK,EAAE,KAAa,EAAE,OAA4B,EAAsB,EAAE;QACtF,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,KAAK,CAAC,CAAC;QACzC,OAAO,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;CACF,CAAC"}
@@ -4,9 +4,10 @@ import { HistoryOptions, HistoryResult, ChannelUnreadResult } from '../slack-api
4
4
  export declare class MessageOperations extends BaseSlackClient {
5
5
  private channelOps;
6
6
  constructor(token: string);
7
- sendMessage(channel: string, text: string): Promise<ChatPostMessageResponse>;
7
+ sendMessage(channel: string, text: string, thread_ts?: string): Promise<ChatPostMessageResponse>;
8
8
  getHistory(channel: string, options: HistoryOptions): Promise<HistoryResult>;
9
9
  getChannelUnread(channelNameOrId: string): Promise<ChannelUnreadResult>;
10
10
  private fetchUserInfo;
11
+ markAsRead(channelId: string): Promise<void>;
11
12
  }
12
13
  //# sourceMappingURL=message-operations.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"message-operations.d.ts","sourceRoot":"","sources":["../../../src/utils/slack-operations/message-operations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhD,OAAO,EAAW,cAAc,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAIlG,qBAAa,iBAAkB,SAAQ,eAAe;IACpD,OAAO,CAAC,UAAU,CAAoB;gBAE1B,KAAK,EAAE,MAAM;IAKnB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAO5E,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAyB5E,gBAAgB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;YAsC/D,aAAa;CAmB5B"}
1
+ {"version":3,"file":"message-operations.d.ts","sourceRoot":"","sources":["../../../src/utils/slack-operations/message-operations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAA4B,MAAM,gBAAgB,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhD,OAAO,EAAW,cAAc,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAIlG,qBAAa,iBAAkB,SAAQ,eAAe;IACpD,OAAO,CAAC,UAAU,CAAoB;gBAE1B,KAAK,EAAE,MAAM;IAKnB,WAAW,CACf,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,uBAAuB,CAAC;IAa7B,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAyB5E,gBAAgB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;YAsC/D,aAAa;IAoBrB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAMnD"}
@@ -11,11 +11,15 @@ class MessageOperations extends base_client_1.BaseSlackClient {
11
11
  super(token);
12
12
  this.channelOps = new channel_operations_1.ChannelOperations(token);
13
13
  }
14
- async sendMessage(channel, text) {
15
- return await this.client.chat.postMessage({
14
+ async sendMessage(channel, text, thread_ts) {
15
+ const params = {
16
16
  channel,
17
17
  text,
18
- });
18
+ };
19
+ if (thread_ts) {
20
+ params.thread_ts = thread_ts;
21
+ }
22
+ return await this.client.chat.postMessage(params);
19
23
  }
20
24
  async getHistory(channel, options) {
21
25
  // Resolve channel name to ID if needed
@@ -88,6 +92,12 @@ class MessageOperations extends base_client_1.BaseSlackClient {
88
92
  }
89
93
  return users;
90
94
  }
95
+ async markAsRead(channelId) {
96
+ await this.client.conversations.mark({
97
+ channel: channelId,
98
+ ts: Date.now() / 1000 + '',
99
+ });
100
+ }
91
101
  }
92
102
  exports.MessageOperations = MessageOperations;
93
103
  //# sourceMappingURL=message-operations.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"message-operations.js","sourceRoot":"","sources":["../../../src/utils/slack-operations/message-operations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"message-operations.js","sourceRoot":"","sources":["../../../src/utils/slack-operations/message-operations.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@urugus/slack-cli",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "description": "A command-line tool for sending messages to Slack",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -8,12 +8,19 @@ import { SendOptions } from '../types/commands';
8
8
  import { extractErrorMessage } from '../utils/error-utils';
9
9
  import * as fs from 'fs/promises';
10
10
 
11
+ function isValidThreadTimestamp(timestamp: string): boolean {
12
+ // Slack timestamp format: 1234567890.123456
13
+ const timestampRegex = /^\d{10}\.\d{6}$/;
14
+ return timestampRegex.test(timestamp);
15
+ }
16
+
11
17
  export function setupSendCommand(): Command {
12
18
  const sendCommand = new Command('send')
13
19
  .description('Send a message to a Slack channel')
14
20
  .requiredOption('-c, --channel <channel>', 'Target channel name or ID')
15
21
  .option('-m, --message <message>', 'Message to send')
16
22
  .option('-f, --file <file>', 'File containing message content')
23
+ .option('-t, --thread <thread>', 'Thread timestamp to reply to')
17
24
  .option('--profile <profile>', 'Use specific workspace profile')
18
25
  .hook('preAction', (thisCommand) => {
19
26
  const options = thisCommand.opts();
@@ -23,6 +30,9 @@ export function setupSendCommand(): Command {
23
30
  if (options.message && options.file) {
24
31
  thisCommand.error(`Error: ${ERROR_MESSAGES.BOTH_MESSAGE_AND_FILE}`);
25
32
  }
33
+ if (options.thread && !isValidThreadTimestamp(options.thread)) {
34
+ thisCommand.error(`Error: ${ERROR_MESSAGES.INVALID_THREAD_TIMESTAMP}`);
35
+ }
26
36
  })
27
37
  .action(
28
38
  wrapCommand(async (options: SendOptions) => {
@@ -42,7 +52,7 @@ export function setupSendCommand(): Command {
42
52
 
43
53
  // Send message
44
54
  const client = await createSlackClient(options.profile);
45
- await client.sendMessage(options.channel, messageContent);
55
+ await client.sendMessage(options.channel, messageContent, options.thread);
46
56
 
47
57
  console.log(chalk.green(`✓ ${SUCCESS_MESSAGES.MESSAGE_SENT(options.channel)}`));
48
58
  })
@@ -26,6 +26,11 @@ async function handleSpecificChannelUnread(
26
26
  countOnly: countOnly,
27
27
  format: format,
28
28
  });
29
+
30
+ if (parseBoolean(options.markRead)) {
31
+ await client.markAsRead(result.channel.id);
32
+ console.log(chalk.green(`✓ Marked messages in #${result.channel.name} as read`));
33
+ }
29
34
  }
30
35
 
31
36
  async function handleAllChannelsUnread(
@@ -48,6 +53,14 @@ async function handleAllChannelsUnread(
48
53
 
49
54
  const formatter = createChannelFormatter(format, countOnly);
50
55
  formatter.format({ channels: displayChannels, countOnly: countOnly });
56
+
57
+ if (parseBoolean(options.markRead)) {
58
+ // Mark all unread channels as read
59
+ for (const channel of channels) {
60
+ await client.markAsRead(channel.id);
61
+ }
62
+ console.log(chalk.green('✓ Marked all messages as read'));
63
+ }
51
64
  }
52
65
 
53
66
  export function setupUnreadCommand(): Command {
@@ -61,6 +74,7 @@ export function setupUnreadCommand(): Command {
61
74
  'Maximum number of channels to display',
62
75
  DEFAULTS.UNREAD_DISPLAY_LIMIT.toString()
63
76
  )
77
+ .option('--mark-read', 'Mark messages as read after fetching', false)
64
78
  .option('--profile <profile>', 'Use specific workspace profile')
65
79
  .action(
66
80
  wrapCommand(async (options: UnreadOptions) => {
@@ -19,6 +19,7 @@ export interface SendOptions {
19
19
  channel: string;
20
20
  message?: string;
21
21
  file?: string;
22
+ thread?: string;
22
23
  profile?: string;
23
24
  }
24
25
 
@@ -42,5 +43,6 @@ export interface UnreadOptions {
42
43
  format?: 'table' | 'simple' | 'json';
43
44
  countOnly?: boolean;
44
45
  limit?: string;
46
+ markRead?: boolean;
45
47
  profile?: string;
46
48
  }
@@ -13,6 +13,7 @@ export const ERROR_MESSAGES = {
13
13
  // Validation errors
14
14
  NO_MESSAGE_OR_FILE: 'You must specify either --message or --file',
15
15
  BOTH_MESSAGE_AND_FILE: 'Cannot use both --message and --file',
16
+ INVALID_THREAD_TIMESTAMP: 'Invalid thread timestamp format',
16
17
 
17
18
  // API errors
18
19
  API_ERROR: (error: string) => `API Error: ${error}`,
@@ -77,8 +77,12 @@ export class SlackApiClient {
77
77
  this.messageOps = new MessageOperations(token);
78
78
  }
79
79
 
80
- async sendMessage(channel: string, text: string): Promise<ChatPostMessageResponse> {
81
- return this.messageOps.sendMessage(channel, text);
80
+ async sendMessage(
81
+ channel: string,
82
+ text: string,
83
+ thread_ts?: string
84
+ ): Promise<ChatPostMessageResponse> {
85
+ return this.messageOps.sendMessage(channel, text, thread_ts);
82
86
  }
83
87
 
84
88
  async listChannels(options: ListChannelsOptions): Promise<Channel[]> {
@@ -96,6 +100,10 @@ export class SlackApiClient {
96
100
  async getChannelUnread(channelNameOrId: string): Promise<ChannelUnreadResult> {
97
101
  return this.messageOps.getChannelUnread(channelNameOrId);
98
102
  }
103
+
104
+ async markAsRead(channelId: string): Promise<void> {
105
+ return this.messageOps.markAsRead(channelId);
106
+ }
99
107
  }
100
108
 
101
109
  export const slackApiClient = {
@@ -1,4 +1,4 @@
1
- import { ChatPostMessageResponse } from '@slack/web-api';
1
+ import { ChatPostMessageResponse, ChatPostMessageArguments } from '@slack/web-api';
2
2
  import { BaseSlackClient } from './base-client';
3
3
  import { channelResolver } from '../channel-resolver';
4
4
  import { DEFAULTS } from '../constants';
@@ -14,11 +14,21 @@ export class MessageOperations extends BaseSlackClient {
14
14
  this.channelOps = new ChannelOperations(token);
15
15
  }
16
16
 
17
- async sendMessage(channel: string, text: string): Promise<ChatPostMessageResponse> {
18
- return await this.client.chat.postMessage({
17
+ async sendMessage(
18
+ channel: string,
19
+ text: string,
20
+ thread_ts?: string
21
+ ): Promise<ChatPostMessageResponse> {
22
+ const params: ChatPostMessageArguments = {
19
23
  channel,
20
24
  text,
21
- });
25
+ };
26
+
27
+ if (thread_ts) {
28
+ params.thread_ts = thread_ts;
29
+ }
30
+
31
+ return await this.client.chat.postMessage(params);
22
32
  }
23
33
 
24
34
  async getHistory(channel: string, options: HistoryOptions): Promise<HistoryResult> {
@@ -103,4 +113,11 @@ export class MessageOperations extends BaseSlackClient {
103
113
 
104
114
  return users;
105
115
  }
116
+
117
+ async markAsRead(channelId: string): Promise<void> {
118
+ await this.client.conversations.mark({
119
+ channel: channelId,
120
+ ts: Date.now() / 1000 + '',
121
+ });
122
+ }
106
123
  }
@@ -47,7 +47,7 @@ describe('send command', () => {
47
47
 
48
48
  await program.parseAsync(['node', 'slack-cli', 'send', '-c', 'general', '-m', 'Hello, World!']);
49
49
 
50
- expect(mockSlackClient.sendMessage).toHaveBeenCalledWith('general', 'Hello, World!');
50
+ expect(mockSlackClient.sendMessage).toHaveBeenCalledWith('general', 'Hello, World!', undefined);
51
51
  expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining(SUCCESS_MESSAGES.MESSAGE_SENT('general')));
52
52
  });
53
53
 
@@ -84,7 +84,74 @@ describe('send command', () => {
84
84
  await program.parseAsync(['node', 'slack-cli', 'send', '-c', 'general', '-f', 'message.txt']);
85
85
 
86
86
  expect(fs.readFile).toHaveBeenCalledWith('message.txt', 'utf-8');
87
- expect(mockSlackClient.sendMessage).toHaveBeenCalledWith('general', fileContent);
87
+ expect(mockSlackClient.sendMessage).toHaveBeenCalledWith('general', fileContent, undefined);
88
+ });
89
+ });
90
+
91
+ describe('send reply to thread', () => {
92
+ it('should send a reply to a thread with --thread option', async () => {
93
+ vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
94
+ token: 'test-token',
95
+ updatedAt: new Date().toISOString()
96
+ });
97
+ vi.mocked(mockSlackClient.sendMessage).mockResolvedValue({
98
+ ok: true,
99
+ ts: '1234567890.123456'
100
+ });
101
+
102
+ await program.parseAsync(['node', 'slack-cli', 'send', '-c', 'general', '-m', 'Reply to thread', '--thread', '1719207629.000100']);
103
+
104
+ expect(mockSlackClient.sendMessage).toHaveBeenCalledWith('general', 'Reply to thread', '1719207629.000100');
105
+ expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining(SUCCESS_MESSAGES.MESSAGE_SENT('general')));
106
+ });
107
+
108
+ it('should send a reply to a thread with -t option', async () => {
109
+ vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
110
+ token: 'test-token',
111
+ updatedAt: new Date().toISOString()
112
+ });
113
+ vi.mocked(mockSlackClient.sendMessage).mockResolvedValue({
114
+ ok: true,
115
+ ts: '1234567890.123456'
116
+ });
117
+
118
+ await program.parseAsync(['node', 'slack-cli', 'send', '-c', 'general', '-m', 'Reply to thread', '-t', '1719207629.000100']);
119
+
120
+ expect(mockSlackClient.sendMessage).toHaveBeenCalledWith('general', 'Reply to thread', '1719207629.000100');
121
+ expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining(SUCCESS_MESSAGES.MESSAGE_SENT('general')));
122
+ });
123
+
124
+ it('should validate thread timestamp format', async () => {
125
+ vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
126
+ token: 'test-token',
127
+ updatedAt: new Date().toISOString()
128
+ });
129
+
130
+ const sendCommand = setupSendCommand();
131
+ sendCommand.exitOverride();
132
+
133
+ await expect(
134
+ sendCommand.parseAsync(['-c', 'general', '-m', 'Reply', '-t', 'invalid-timestamp'], { from: 'user' })
135
+ ).rejects.toThrow(ERROR_MESSAGES.INVALID_THREAD_TIMESTAMP);
136
+ });
137
+
138
+ it('should send a reply to a thread with file content', async () => {
139
+ const fileContent = 'Reply from file\nLine 2';
140
+ vi.mocked(fs.readFile).mockResolvedValue(fileContent);
141
+ vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
142
+ token: 'test-token',
143
+ updatedAt: new Date().toISOString()
144
+ });
145
+ vi.mocked(mockSlackClient.sendMessage).mockResolvedValue({
146
+ ok: true,
147
+ ts: '1234567890.123456'
148
+ });
149
+
150
+ await program.parseAsync(['node', 'slack-cli', 'send', '-c', 'general', '-f', 'reply.txt', '-t', '1719207629.000100']);
151
+
152
+ expect(fs.readFile).toHaveBeenCalledWith('reply.txt', 'utf-8');
153
+ expect(mockSlackClient.sendMessage).toHaveBeenCalledWith('general', fileContent, '1719207629.000100');
154
+ expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining(SUCCESS_MESSAGES.MESSAGE_SENT('general')));
88
155
  });
89
156
  });
90
157
 
@@ -429,4 +429,64 @@ describe('unread command', () => {
429
429
  expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining('transitioned ES-4359'));
430
430
  });
431
431
  });
432
+
433
+ describe('mark-read functionality', () => {
434
+ it('should mark messages as read when --mark-read is specified', async () => {
435
+ vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
436
+ token: 'test-token',
437
+ updatedAt: new Date().toISOString()
438
+ });
439
+ vi.mocked(mockSlackClient.listUnreadChannels).mockResolvedValue(
440
+ mockChannelsWithUnread.filter(ch => (ch.unread_count_display || 0) > 0)
441
+ );
442
+ vi.mocked(mockSlackClient.markAsRead).mockResolvedValue(undefined);
443
+
444
+ await program.parseAsync(['node', 'slack-cli', 'unread', '--mark-read']);
445
+
446
+ expect(mockSlackClient.listUnreadChannels).toHaveBeenCalled();
447
+ expect(mockSlackClient.markAsRead).toHaveBeenCalledWith('C123');
448
+ expect(mockSlackClient.markAsRead).toHaveBeenCalledWith('C456');
449
+ expect(mockConsole.logSpy).toHaveBeenCalledWith(chalk.green('✓ Marked all messages as read'));
450
+ });
451
+
452
+ it('should mark messages as read for specific channel when --channel and --mark-read are specified', async () => {
453
+ vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
454
+ token: 'test-token',
455
+ updatedAt: new Date().toISOString()
456
+ });
457
+ vi.mocked(mockSlackClient.getChannelUnread).mockResolvedValue({
458
+ channel: mockChannelsWithUnread[0],
459
+ messages: mockUnreadMessages,
460
+ users: new Map([
461
+ ['U123', 'john.doe'],
462
+ ['U456', 'jane.smith']
463
+ ])
464
+ });
465
+ vi.mocked(mockSlackClient.markAsRead).mockResolvedValue(undefined);
466
+
467
+ await program.parseAsync(['node', 'slack-cli', 'unread', '--channel', 'general', '--mark-read']);
468
+
469
+ expect(mockSlackClient.getChannelUnread).toHaveBeenCalledWith('general');
470
+ expect(mockSlackClient.markAsRead).toHaveBeenCalledWith('C123');
471
+ expect(mockConsole.logSpy).toHaveBeenCalledWith(chalk.green('✓ Marked messages in #general as read'));
472
+ });
473
+
474
+ it('should handle mark as read errors gracefully', async () => {
475
+ vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
476
+ token: 'test-token',
477
+ updatedAt: new Date().toISOString()
478
+ });
479
+ vi.mocked(mockSlackClient.listUnreadChannels).mockResolvedValue(
480
+ mockChannelsWithUnread.filter(ch => (ch.unread_count_display || 0) > 0)
481
+ );
482
+ vi.mocked(mockSlackClient.markAsRead).mockRejectedValue(
483
+ new Error('channel_not_found')
484
+ );
485
+
486
+ await program.parseAsync(['node', 'slack-cli', 'unread', '--mark-read']);
487
+
488
+ expect(mockConsole.errorSpy).toHaveBeenCalledWith(expect.stringContaining('Error:'), expect.any(String));
489
+ expect(mockConsole.exitSpy).toHaveBeenCalledWith(1);
490
+ });
491
+ });
432
492
  });
@@ -11,8 +11,8 @@ describe('slack-cli version', () => {
11
11
  );
12
12
  const expectedVersion = packageJson.version;
13
13
 
14
- // Execute the CLI command to get version
15
- const output = execSync('node dist/index.js --version', {
14
+ // Execute the CLI command to get version using ts-node
15
+ const output = execSync('npx ts-node src/index.ts --version', {
16
16
  encoding: 'utf-8',
17
17
  cwd: join(__dirname, '..')
18
18
  }).trim();
@@ -28,8 +28,8 @@ describe('slack-cli version', () => {
28
28
  );
29
29
  const expectedVersion = packageJson.version;
30
30
 
31
- // Execute the CLI command with -V flag
32
- const output = execSync('node dist/index.js -V', {
31
+ // Execute the CLI command with -V flag using ts-node
32
+ const output = execSync('npx ts-node src/index.ts -V', {
33
33
  encoding: 'utf-8',
34
34
  cwd: join(__dirname, '..')
35
35
  }).trim();