@urugus/slack-cli 0.1.0 → 0.1.3
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/settings.local.json +8 -1
- package/dist/utils/slack-api-client.d.ts.map +1 -1
- package/dist/utils/slack-api-client.js +68 -3
- package/dist/utils/slack-api-client.js.map +1 -1
- package/package.json +2 -2
- package/src/utils/slack-api-client.ts +73 -5
- package/tests/commands/history.test.ts +38 -0
|
@@ -46,7 +46,14 @@
|
|
|
46
46
|
"WebFetch(domain:api.slack.com)",
|
|
47
47
|
"Bash(npm run typecheck:*)",
|
|
48
48
|
"Bash(npm run:*)",
|
|
49
|
-
"Bash(npm whoami:*)"
|
|
49
|
+
"Bash(npm whoami:*)",
|
|
50
|
+
"Bash(npm unlink:*)",
|
|
51
|
+
"Bash(npm update:*)",
|
|
52
|
+
"Bash(npm install:*)",
|
|
53
|
+
"Bash(npm view:*)",
|
|
54
|
+
"Bash(npm publish:*)",
|
|
55
|
+
"Bash(rg:*)",
|
|
56
|
+
"Bash(npm version:*)"
|
|
50
57
|
],
|
|
51
58
|
"deny": []
|
|
52
59
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slack-api-client.d.ts","sourceRoot":"","sources":["../../src/utils/slack-api-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAEpE,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE;QACN,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,OAAO,CAAC,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,OAAO,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5B;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAY;gBAEd,KAAK,EAAE,MAAM;IAInB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAO5E,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAU9D,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"slack-api-client.d.ts","sourceRoot":"","sources":["../../src/utils/slack-api-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,8 +21,48 @@ class SlackApiClient {
|
|
|
21
21
|
return response.channels;
|
|
22
22
|
}
|
|
23
23
|
async getHistory(channel, options) {
|
|
24
|
+
// First, resolve channel name to ID if needed
|
|
25
|
+
let channelId = channel;
|
|
26
|
+
if (!channel.startsWith('C') && !channel.startsWith('D') && !channel.startsWith('G')) {
|
|
27
|
+
// It's a name, not an ID - need to find the ID
|
|
28
|
+
const channels = await this.listChannels({
|
|
29
|
+
types: 'public_channel,private_channel,im,mpim',
|
|
30
|
+
exclude_archived: true,
|
|
31
|
+
limit: 1000,
|
|
32
|
+
});
|
|
33
|
+
// Try multiple matching strategies
|
|
34
|
+
const foundChannel = channels.find((c) => {
|
|
35
|
+
// Direct name match
|
|
36
|
+
if (c.name === channel)
|
|
37
|
+
return true;
|
|
38
|
+
// Match without # prefix
|
|
39
|
+
if (c.name === channel.replace('#', ''))
|
|
40
|
+
return true;
|
|
41
|
+
// Case-insensitive match
|
|
42
|
+
if (c.name?.toLowerCase() === channel.toLowerCase())
|
|
43
|
+
return true;
|
|
44
|
+
// Match with normalized name
|
|
45
|
+
if (c.name_normalized === channel)
|
|
46
|
+
return true;
|
|
47
|
+
return false;
|
|
48
|
+
});
|
|
49
|
+
if (!foundChannel) {
|
|
50
|
+
// Provide helpful error message
|
|
51
|
+
const similarChannels = channels
|
|
52
|
+
.filter((c) => c.name?.toLowerCase().includes(channel.toLowerCase()))
|
|
53
|
+
.slice(0, 5)
|
|
54
|
+
.map((c) => c.name);
|
|
55
|
+
if (similarChannels.length > 0) {
|
|
56
|
+
throw new Error(`Channel '${channel}' not found. Did you mean one of these? ${similarChannels.join(', ')}`);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
throw new Error(`Channel '${channel}' not found. Make sure you are a member of this channel.`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
channelId = foundChannel.id;
|
|
63
|
+
}
|
|
24
64
|
const response = await this.client.conversations.history({
|
|
25
|
-
channel,
|
|
65
|
+
channel: channelId,
|
|
26
66
|
limit: options.limit,
|
|
27
67
|
oldest: options.oldest,
|
|
28
68
|
});
|
|
@@ -89,9 +129,34 @@ class SlackApiClient {
|
|
|
89
129
|
exclude_archived: true,
|
|
90
130
|
limit: 1000,
|
|
91
131
|
});
|
|
92
|
-
|
|
132
|
+
// Try multiple matching strategies (same as getHistory)
|
|
133
|
+
const channel = channels.find((c) => {
|
|
134
|
+
// Direct name match
|
|
135
|
+
if (c.name === channelNameOrId)
|
|
136
|
+
return true;
|
|
137
|
+
// Match without # prefix
|
|
138
|
+
if (c.name === channelNameOrId.replace('#', ''))
|
|
139
|
+
return true;
|
|
140
|
+
// Case-insensitive match
|
|
141
|
+
if (c.name?.toLowerCase() === channelNameOrId.toLowerCase())
|
|
142
|
+
return true;
|
|
143
|
+
// Match with normalized name
|
|
144
|
+
if (c.name_normalized === channelNameOrId)
|
|
145
|
+
return true;
|
|
146
|
+
return false;
|
|
147
|
+
});
|
|
93
148
|
if (!channel) {
|
|
94
|
-
|
|
149
|
+
// Provide helpful error message
|
|
150
|
+
const similarChannels = channels
|
|
151
|
+
.filter((c) => c.name?.toLowerCase().includes(channelNameOrId.toLowerCase()))
|
|
152
|
+
.slice(0, 5)
|
|
153
|
+
.map((c) => c.name);
|
|
154
|
+
if (similarChannels.length > 0) {
|
|
155
|
+
throw new Error(`Channel '${channelNameOrId}' not found. Did you mean one of these? ${similarChannels.join(', ')}`);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
throw new Error(`Channel '${channelNameOrId}' not found. Make sure you are a member of this channel.`);
|
|
159
|
+
}
|
|
95
160
|
}
|
|
96
161
|
channelId = channel.id;
|
|
97
162
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slack-api-client.js","sourceRoot":"","sources":["../../src/utils/slack-api-client.ts"],"names":[],"mappings":";;;AAAA,4CAAoE;AAoEpE,MAAa,cAAc;IAGzB,YAAY,KAAa;QACvB,IAAI,CAAC,MAAM,GAAG,IAAI,mBAAS,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAAe,EAAE,IAAY;QAC7C,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC;YACxC,OAAO;YACP,IAAI;SACL,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,OAA4B;QAC7C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC;YACpD,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;YAC1C,KAAK,EAAE,OAAO,CAAC,KAAK;SACrB,CAAC,CAAC;QAEH,OAAO,QAAQ,CAAC,QAAqB,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,OAAe,EAAE,OAAuB;QACvD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC;YACvD,OAAO;
|
|
1
|
+
{"version":3,"file":"slack-api-client.js","sourceRoot":"","sources":["../../src/utils/slack-api-client.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.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "A command-line tool for sending messages to Slack",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -53,4 +53,4 @@
|
|
|
53
53
|
"engines": {
|
|
54
54
|
"node": ">=16.0.0"
|
|
55
55
|
}
|
|
56
|
-
}
|
|
56
|
+
}
|
|
@@ -91,8 +91,51 @@ export class SlackApiClient {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
async getHistory(channel: string, options: HistoryOptions): Promise<HistoryResult> {
|
|
94
|
+
// First, resolve channel name to ID if needed
|
|
95
|
+
let channelId = channel;
|
|
96
|
+
if (!channel.startsWith('C') && !channel.startsWith('D') && !channel.startsWith('G')) {
|
|
97
|
+
// It's a name, not an ID - need to find the ID
|
|
98
|
+
const channels = await this.listChannels({
|
|
99
|
+
types: 'public_channel,private_channel,im,mpim',
|
|
100
|
+
exclude_archived: true,
|
|
101
|
+
limit: 1000,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// Try multiple matching strategies
|
|
105
|
+
const foundChannel = channels.find((c) => {
|
|
106
|
+
// Direct name match
|
|
107
|
+
if (c.name === channel) return true;
|
|
108
|
+
// Match without # prefix
|
|
109
|
+
if (c.name === channel.replace('#', '')) return true;
|
|
110
|
+
// Case-insensitive match
|
|
111
|
+
if (c.name?.toLowerCase() === channel.toLowerCase()) return true;
|
|
112
|
+
// Match with normalized name
|
|
113
|
+
if (c.name_normalized === channel) return true;
|
|
114
|
+
return false;
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
if (!foundChannel) {
|
|
118
|
+
// Provide helpful error message
|
|
119
|
+
const similarChannels = channels
|
|
120
|
+
.filter((c) => c.name?.toLowerCase().includes(channel.toLowerCase()))
|
|
121
|
+
.slice(0, 5)
|
|
122
|
+
.map((c) => c.name);
|
|
123
|
+
|
|
124
|
+
if (similarChannels.length > 0) {
|
|
125
|
+
throw new Error(
|
|
126
|
+
`Channel '${channel}' not found. Did you mean one of these? ${similarChannels.join(', ')}`
|
|
127
|
+
);
|
|
128
|
+
} else {
|
|
129
|
+
throw new Error(
|
|
130
|
+
`Channel '${channel}' not found. Make sure you are a member of this channel.`
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
channelId = foundChannel.id;
|
|
135
|
+
}
|
|
136
|
+
|
|
94
137
|
const response = await this.client.conversations.history({
|
|
95
|
-
channel,
|
|
138
|
+
channel: channelId,
|
|
96
139
|
limit: options.limit,
|
|
97
140
|
oldest: options.oldest,
|
|
98
141
|
});
|
|
@@ -170,11 +213,36 @@ export class SlackApiClient {
|
|
|
170
213
|
exclude_archived: true,
|
|
171
214
|
limit: 1000,
|
|
172
215
|
});
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
)
|
|
216
|
+
|
|
217
|
+
// Try multiple matching strategies (same as getHistory)
|
|
218
|
+
const channel = channels.find((c) => {
|
|
219
|
+
// Direct name match
|
|
220
|
+
if (c.name === channelNameOrId) return true;
|
|
221
|
+
// Match without # prefix
|
|
222
|
+
if (c.name === channelNameOrId.replace('#', '')) return true;
|
|
223
|
+
// Case-insensitive match
|
|
224
|
+
if (c.name?.toLowerCase() === channelNameOrId.toLowerCase()) return true;
|
|
225
|
+
// Match with normalized name
|
|
226
|
+
if (c.name_normalized === channelNameOrId) return true;
|
|
227
|
+
return false;
|
|
228
|
+
});
|
|
229
|
+
|
|
176
230
|
if (!channel) {
|
|
177
|
-
|
|
231
|
+
// Provide helpful error message
|
|
232
|
+
const similarChannels = channels
|
|
233
|
+
.filter((c) => c.name?.toLowerCase().includes(channelNameOrId.toLowerCase()))
|
|
234
|
+
.slice(0, 5)
|
|
235
|
+
.map((c) => c.name);
|
|
236
|
+
|
|
237
|
+
if (similarChannels.length > 0) {
|
|
238
|
+
throw new Error(
|
|
239
|
+
`Channel '${channelNameOrId}' not found. Did you mean one of these? ${similarChannels.join(', ')}`
|
|
240
|
+
);
|
|
241
|
+
} else {
|
|
242
|
+
throw new Error(
|
|
243
|
+
`Channel '${channelNameOrId}' not found. Make sure you are a member of this channel.`
|
|
244
|
+
);
|
|
245
|
+
}
|
|
178
246
|
}
|
|
179
247
|
channelId = channel.id;
|
|
180
248
|
}
|
|
@@ -176,6 +176,44 @@ describe('history command', () => {
|
|
|
176
176
|
expect(mockConsole.errorSpy).toHaveBeenCalledWith(expect.stringContaining('Error:'), expect.any(String));
|
|
177
177
|
expect(mockConsole.exitSpy).toHaveBeenCalledWith(1);
|
|
178
178
|
});
|
|
179
|
+
|
|
180
|
+
it('should show helpful error when channel not found', async () => {
|
|
181
|
+
vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
|
|
182
|
+
token: 'test-token',
|
|
183
|
+
updatedAt: new Date().toISOString()
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
// Mock getHistory to throw our new helpful error
|
|
187
|
+
vi.mocked(mockSlackClient.getHistory).mockRejectedValue(
|
|
188
|
+
new Error("Channel 'times_sakashi' not found. Make sure you are a member of this channel.")
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
await program.parseAsync(['node', 'slack-cli', 'history', '-c', 'times_sakashi']);
|
|
192
|
+
|
|
193
|
+
expect(mockSlackClient.getHistory).toHaveBeenCalledWith('times_sakashi', { limit: 10 });
|
|
194
|
+
expect(mockConsole.errorSpy).toHaveBeenCalledWith(
|
|
195
|
+
expect.stringContaining('Error:'),
|
|
196
|
+
expect.stringContaining('Make sure you are a member of this channel')
|
|
197
|
+
);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it('should find private channels with underscore in name', async () => {
|
|
201
|
+
vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
|
|
202
|
+
token: 'test-token',
|
|
203
|
+
updatedAt: new Date().toISOString()
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// Mock the getHistory method to simulate successful channel lookup
|
|
207
|
+
vi.mocked(mockSlackClient.getHistory).mockResolvedValue({
|
|
208
|
+
messages: [],
|
|
209
|
+
users: new Map()
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
await program.parseAsync(['node', 'slack-cli', 'history', '-c', 'times_sakashi']);
|
|
213
|
+
|
|
214
|
+
expect(mockSlackClient.getHistory).toHaveBeenCalledWith('times_sakashi', { limit: 10 });
|
|
215
|
+
expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining('No messages found'));
|
|
216
|
+
});
|
|
179
217
|
});
|
|
180
218
|
|
|
181
219
|
describe('output formatting', () => {
|