cord-bot 1.0.5 → 1.1.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/bin/cord.ts +51 -0
- package/data/threads.db +0 -0
- package/package.json +1 -1
- package/skills/cord/SKILL.md +59 -8
- package/src/bot.ts +44 -0
package/bin/cord.ts
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
* cord reply <channel> <messageId> "message"
|
|
21
21
|
* cord thread <channel> <messageId> "name"
|
|
22
22
|
* cord react <channel> <messageId> "emoji"
|
|
23
|
+
* cord state <channel> <messageId> <state> (processing, done, error, or custom)
|
|
23
24
|
*/
|
|
24
25
|
|
|
25
26
|
import { spawn, spawnSync } from 'bun';
|
|
@@ -375,6 +376,47 @@ async function addReaction() {
|
|
|
375
376
|
console.log(`Added reaction: ${emoji}`);
|
|
376
377
|
}
|
|
377
378
|
|
|
379
|
+
// State presets for thread status updates
|
|
380
|
+
const STATE_PRESETS: Record<string, string> = {
|
|
381
|
+
processing: '🤖 Processing...',
|
|
382
|
+
thinking: '🧠 Thinking...',
|
|
383
|
+
searching: '🔍 Searching...',
|
|
384
|
+
writing: '✍️ Writing...',
|
|
385
|
+
done: '✅ Done',
|
|
386
|
+
error: '❌ Something went wrong',
|
|
387
|
+
waiting: '⏳ Waiting for input...',
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
async function updateState() {
|
|
391
|
+
const channel = args[0];
|
|
392
|
+
const messageId = args[1];
|
|
393
|
+
const stateOrCustom = args[2];
|
|
394
|
+
|
|
395
|
+
if (!channel || !messageId || !stateOrCustom) {
|
|
396
|
+
console.error('Usage: cord state <channel> <messageId> <state>');
|
|
397
|
+
console.error('');
|
|
398
|
+
console.error('Preset states:');
|
|
399
|
+
console.error(' processing - 🤖 Processing...');
|
|
400
|
+
console.error(' thinking - 🧠 Thinking...');
|
|
401
|
+
console.error(' searching - 🔍 Searching...');
|
|
402
|
+
console.error(' writing - ✍️ Writing...');
|
|
403
|
+
console.error(' done - ✅ Done');
|
|
404
|
+
console.error(' error - ❌ Something went wrong');
|
|
405
|
+
console.error(' waiting - ⏳ Waiting for input...');
|
|
406
|
+
console.error('');
|
|
407
|
+
console.error('Or use custom text: cord state <channel> <messageId> "Custom status"');
|
|
408
|
+
process.exit(1);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
const content = STATE_PRESETS[stateOrCustom.toLowerCase()] || stateOrCustom;
|
|
412
|
+
|
|
413
|
+
await apiCall('/command', {
|
|
414
|
+
command: 'edit-message',
|
|
415
|
+
args: { channel, message: messageId, content },
|
|
416
|
+
});
|
|
417
|
+
console.log(`Updated state: ${content}`);
|
|
418
|
+
}
|
|
419
|
+
|
|
378
420
|
// ============ Management Commands ============
|
|
379
421
|
|
|
380
422
|
async function setup() {
|
|
@@ -603,11 +645,17 @@ Discord Commands:
|
|
|
603
645
|
react <channel> <messageId> "emoji"
|
|
604
646
|
Add a reaction to a message
|
|
605
647
|
|
|
648
|
+
state <channel> <messageId> <state>
|
|
649
|
+
Update thread status with preset or custom text
|
|
650
|
+
Presets: processing, thinking, searching, writing, done, error, waiting
|
|
651
|
+
|
|
606
652
|
Examples:
|
|
607
653
|
cord send 123456789 "Hello world!"
|
|
608
654
|
cord embed 123456789 "Status update" --title "Daily Report" --color green --field "Tasks:5 done:inline"
|
|
609
655
|
cord buttons 123456789 "Approve?" --button label="Yes" id="approve" style="success" reply="Approved!"
|
|
610
656
|
cord file 123456789 ./report.md "Here's the report"
|
|
657
|
+
cord state 123456789 1234567890 processing
|
|
658
|
+
cord state 123456789 1234567890 done
|
|
611
659
|
`);
|
|
612
660
|
}
|
|
613
661
|
|
|
@@ -668,6 +716,9 @@ switch (command) {
|
|
|
668
716
|
case 'react':
|
|
669
717
|
addReaction();
|
|
670
718
|
break;
|
|
719
|
+
case 'state':
|
|
720
|
+
updateState();
|
|
721
|
+
break;
|
|
671
722
|
|
|
672
723
|
default:
|
|
673
724
|
console.log(`Unknown command: ${command}`);
|
package/data/threads.db
ADDED
|
Binary file
|
package/package.json
CHANGED
package/skills/cord/SKILL.md
CHANGED
|
@@ -223,6 +223,40 @@ cord react 123456789 987654321 "👍"
|
|
|
223
223
|
|
|
224
224
|
---
|
|
225
225
|
|
|
226
|
+
### state
|
|
227
|
+
|
|
228
|
+
Update a message with a status indicator. Use this to show work progress on a thread starter or status message.
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
cord state <channel> <messageId> <state>
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**Preset states:**
|
|
235
|
+
| State | Display |
|
|
236
|
+
|-------|---------|
|
|
237
|
+
| `processing` | 🤖 Processing... |
|
|
238
|
+
| `thinking` | 🧠 Thinking... |
|
|
239
|
+
| `searching` | 🔍 Searching... |
|
|
240
|
+
| `writing` | ✍️ Writing... |
|
|
241
|
+
| `done` | ✅ Done |
|
|
242
|
+
| `error` | ❌ Something went wrong |
|
|
243
|
+
| `waiting` | ⏳ Waiting for input... |
|
|
244
|
+
|
|
245
|
+
**Examples:**
|
|
246
|
+
|
|
247
|
+
Using presets:
|
|
248
|
+
```bash
|
|
249
|
+
cord state 123456789 987654321 processing
|
|
250
|
+
cord state 123456789 987654321 done
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Custom status:
|
|
254
|
+
```bash
|
|
255
|
+
cord state 123456789 987654321 "🔄 Syncing database..."
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
226
260
|
## Choosing the Right Command
|
|
227
261
|
|
|
228
262
|
| Use Case | Command |
|
|
@@ -231,7 +265,8 @@ cord react 123456789 987654321 "👍"
|
|
|
231
265
|
| Formatted status update | `cord embed` |
|
|
232
266
|
| Long content (logs, reports) | `cord file` |
|
|
233
267
|
| User needs to make a choice | `cord buttons` |
|
|
234
|
-
| Indicate processing | `cord typing` |
|
|
268
|
+
| Indicate processing (typing bubble) | `cord typing` |
|
|
269
|
+
| Update thread/message status | `cord state` |
|
|
235
270
|
| Update previous message | `cord edit` |
|
|
236
271
|
| Start a focused discussion | `cord thread` |
|
|
237
272
|
| Quick acknowledgment | `cord react` |
|
|
@@ -263,15 +298,21 @@ cord buttons 123456789 "What would you like to do?" \
|
|
|
263
298
|
# Start with typing indicator
|
|
264
299
|
cord typing 123456789
|
|
265
300
|
|
|
266
|
-
# Send initial status
|
|
267
|
-
MSGID=$(cord send 123456789 "Processing...
|
|
301
|
+
# Send initial status message
|
|
302
|
+
MSGID=$(cord send 123456789 "🤖 Processing..." | grep -o '[0-9]*$')
|
|
268
303
|
|
|
269
|
-
# Update as
|
|
270
|
-
cord
|
|
271
|
-
cord
|
|
304
|
+
# Update state as work progresses
|
|
305
|
+
cord state 123456789 $MSGID searching
|
|
306
|
+
cord state 123456789 $MSGID writing
|
|
307
|
+
cord state 123456789 $MSGID done
|
|
308
|
+
```
|
|
272
309
|
|
|
273
|
-
|
|
274
|
-
|
|
310
|
+
Or with custom progress:
|
|
311
|
+
```bash
|
|
312
|
+
cord state 123456789 $MSGID "🔄 Step 1/3: Fetching data..."
|
|
313
|
+
cord state 123456789 $MSGID "🔄 Step 2/3: Processing..."
|
|
314
|
+
cord state 123456789 $MSGID "🔄 Step 3/3: Generating report..."
|
|
315
|
+
cord state 123456789 $MSGID done
|
|
275
316
|
```
|
|
276
317
|
|
|
277
318
|
### Report delivery
|
|
@@ -299,6 +340,16 @@ cord buttons 123456789 "Delete all archived items older than 30 days?" \
|
|
|
299
340
|
|
|
300
341
|
---
|
|
301
342
|
|
|
343
|
+
## Auto-Complete Behavior
|
|
344
|
+
|
|
345
|
+
When a user adds a ✅ reaction to the **last message** in a thread, Cord automatically:
|
|
346
|
+
1. Detects the reaction
|
|
347
|
+
2. Updates the thread starter message to "✅ Done"
|
|
348
|
+
|
|
349
|
+
This provides a quick way for users to signal "conversation complete" without explicit commands.
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
302
353
|
## HTTP API
|
|
303
354
|
|
|
304
355
|
For advanced use cases (webhooks, external scripts), see [HTTP-API.md](./HTTP-API.md).
|
package/src/bot.ts
CHANGED
|
@@ -29,6 +29,7 @@ const client = new Client({
|
|
|
29
29
|
GatewayIntentBits.Guilds,
|
|
30
30
|
GatewayIntentBits.GuildMessages,
|
|
31
31
|
GatewayIntentBits.MessageContent,
|
|
32
|
+
GatewayIntentBits.GuildMessageReactions,
|
|
32
33
|
],
|
|
33
34
|
});
|
|
34
35
|
|
|
@@ -176,6 +177,49 @@ client.on(Events.MessageCreate, async (message: Message) => {
|
|
|
176
177
|
});
|
|
177
178
|
});
|
|
178
179
|
|
|
180
|
+
// =========================================================================
|
|
181
|
+
// REACTION HANDLER: ✅ on last message marks thread as done
|
|
182
|
+
// =========================================================================
|
|
183
|
+
client.on(Events.MessageReactionAdd, async (reaction, user) => {
|
|
184
|
+
// Ignore bot reactions
|
|
185
|
+
if (user.bot) return;
|
|
186
|
+
|
|
187
|
+
// Only handle ✅ reactions
|
|
188
|
+
if (reaction.emoji.name !== '✅') return;
|
|
189
|
+
|
|
190
|
+
// Only handle reactions in threads
|
|
191
|
+
const channel = reaction.message.channel;
|
|
192
|
+
if (!channel.isThread()) return;
|
|
193
|
+
|
|
194
|
+
try {
|
|
195
|
+
const thread = channel;
|
|
196
|
+
const parentChannelId = thread.parentId;
|
|
197
|
+
if (!parentChannelId) return;
|
|
198
|
+
|
|
199
|
+
// Check if this is the last message in the thread
|
|
200
|
+
const messages = await thread.messages.fetch({ limit: 1 });
|
|
201
|
+
const lastMessage = messages.first();
|
|
202
|
+
|
|
203
|
+
if (!lastMessage || lastMessage.id !== reaction.message.id) {
|
|
204
|
+
// Reaction is not on the last message, ignore
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
log(`✅ reaction on last message in thread ${thread.id}`);
|
|
209
|
+
|
|
210
|
+
// Update thread starter message to "Done"
|
|
211
|
+
// The thread ID equals the starter message ID (thread was created from that message)
|
|
212
|
+
const parentChannel = await client.channels.fetch(parentChannelId);
|
|
213
|
+
if (parentChannel?.isTextBased()) {
|
|
214
|
+
const starterMessage = await (parentChannel as TextChannel).messages.fetch(thread.id);
|
|
215
|
+
await starterMessage.edit('✅ Done');
|
|
216
|
+
log(`Thread ${thread.id} marked as Done`);
|
|
217
|
+
}
|
|
218
|
+
} catch (error) {
|
|
219
|
+
log(`Failed to mark thread done: ${error}`);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
|
|
179
223
|
// Start the bot
|
|
180
224
|
const token = process.env.DISCORD_BOT_TOKEN;
|
|
181
225
|
if (!token) {
|