greprag 5.4.0 → 5.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skill/discord/SKILL.md +131 -0
package/package.json
CHANGED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: discord
|
|
3
|
+
description: |
|
|
4
|
+
Discord DM bridge for greprag. Pair your Discord account once, then DM the
|
|
5
|
+
bot to talk to the agent in any open Claude session. Handoff temporarily
|
|
6
|
+
pins your DMs to one specific session — say "let's continue on Discord"
|
|
7
|
+
before stepping away from the desk and your phone keeps the same thread
|
|
8
|
+
alive.
|
|
9
|
+
|
|
10
|
+
Use when: "/discord", "discord", "pair my discord", "step away", "let's
|
|
11
|
+
continue on discord", "let's continue on phone", "DM me", "handoff to
|
|
12
|
+
discord", "discord handoff", "discord status", "am I paired", "what's my
|
|
13
|
+
discord state", "I'm going for a walk", "I'll be afk".
|
|
14
|
+
metadata:
|
|
15
|
+
author: travsteward
|
|
16
|
+
version: "1.0.0"
|
|
17
|
+
repository: https://github.com/travsteward/greprag
|
|
18
|
+
license: MIT
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# Discord DM bridge
|
|
22
|
+
|
|
23
|
+
The agent runs `greprag discord me` to learn the current state, then branches into pair / handoff / status. Everything else is one shell command per branch.
|
|
24
|
+
|
|
25
|
+
## Step 1 — Get the state
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
greprag discord me
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Parse the JSON. Three states:
|
|
32
|
+
|
|
33
|
+
- `paired: false` → user has never paired this tenant. Run **pair flow**.
|
|
34
|
+
- `paired: true` and `handoff === null` → paired, no active pin. If the user asked to step away (any trigger phrase), run **handoff flow**. Otherwise just print **status**.
|
|
35
|
+
- `paired: true` and `handoff !== null` → active pin live. Print **status with handoff details**.
|
|
36
|
+
|
|
37
|
+
## Step 2 — Pair flow (only if not paired)
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
greprag discord pair
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Prints the 6-char code. Tell the user verbatim:
|
|
44
|
+
|
|
45
|
+
> DM `@greprag` on Discord: `/pair <CODE>` (expires in 15 min).
|
|
46
|
+
|
|
47
|
+
When they confirm the bot replied with "Paired," re-run `greprag discord me` to verify, then continue. If the user wanted a handoff (their original request mentioned stepping away), proceed to Step 3 once paired.
|
|
48
|
+
|
|
49
|
+
## Step 3 — Handoff flow (the killer feature)
|
|
50
|
+
|
|
51
|
+
Trigger: user said anything implying "I'm leaving the desk and want this thread to follow me to Discord" — *step away*, *continue on phone*, *handoff*, *DM me*, *afk*, *I'll be walking*.
|
|
52
|
+
|
|
53
|
+
Resolve the session id from the SessionStart hook's `additionalContext` (8-hex form). Resolve the project name from the current anchor (`greprag project-id`'s sibling lookup, or the explicit `--project` flag).
|
|
54
|
+
|
|
55
|
+
Arm the watcher under **Monitor with `persistent: true`**, wrapped in the `while true` restart loop so a process death (npm install mid-session, network blip, supervisor bug) auto-recovers:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
greprag discord handoff --session <8-hex> --project <name> --ttl 60 --no-watch && \
|
|
59
|
+
while true; do
|
|
60
|
+
greprag inbox watch --project <name> --session <8-hex> --json --no-supervise
|
|
61
|
+
echo "[wrapper] watcher exited, restarting in 1s" >&2
|
|
62
|
+
sleep 1
|
|
63
|
+
done
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Two halves on purpose:
|
|
67
|
+
1. `discord handoff --no-watch` writes the pin server-side (`active_project_id`, `active_session_id`, `active_expires_at`) and fires the confirmation DM to the user's phone. Returns immediately.
|
|
68
|
+
2. The `while true` loop tails the session inbox via SSE. Each line printed = one Discord DM landing as a Monitor notification.
|
|
69
|
+
|
|
70
|
+
**Never use the bare `greprag discord handoff` form without `--no-watch` for production handoff.** It self-streams, but a process death (e.g. `npm i -g greprag@latest` from another shell wipes the install dir) takes the watcher down with no restart. The wrapped two-step is the resilient form.
|
|
71
|
+
|
|
72
|
+
Tell the user: "Handoff pinned for 60 min. Reply on Discord — your messages route to this session. Bot already DMed you a confirmation."
|
|
73
|
+
|
|
74
|
+
## Step 4 — Replying to inbound DMs
|
|
75
|
+
|
|
76
|
+
Each Monitor notification carries the full event payload: `body` is the user's message text, `references.discord.snowflake` is their Discord ID.
|
|
77
|
+
|
|
78
|
+
Send your reply via the CLI:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
greprag send --to discord:<snowflake> "your reply text"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
The CLI uses Node fetch (UTF-8 native) — em-dashes, curly quotes, emoji all render correctly. **Do NOT use curl from bash on Windows** for Discord sends — the local code page (Win-1252) mangles non-ASCII bytes into `?` on the user's phone.
|
|
85
|
+
|
|
86
|
+
For long agent turns where you're drafting >10s, refresh the typing indicator between work steps:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
greprag discord typing
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Silent on success. Tells Discord to show "GrepRAG is typing…" for another 10s.
|
|
93
|
+
|
|
94
|
+
If the reply exceeds 2000 chars (Discord's hard limit), split on paragraph boundaries and send multiple messages with continuation markers.
|
|
95
|
+
|
|
96
|
+
## Step 5 — Status (when paired with no handoff intent, or to inspect)
|
|
97
|
+
|
|
98
|
+
Print verbatim:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
Discord pairing:
|
|
102
|
+
Tenant: travis (or whatever me.snowflake points to)
|
|
103
|
+
Default route: <me.project_name> (project_id <me.project_id>)
|
|
104
|
+
Snowflake: <me.snowflake>
|
|
105
|
+
Paired at: <me.paired_at>
|
|
106
|
+
Last DM in: <me.last_seen_inbound_at or "(never)">
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
If `handoff !== null`:
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
Active handoff pin:
|
|
113
|
+
Project: <me.handoff.project_name>
|
|
114
|
+
Session: <me.handoff.session_id>
|
|
115
|
+
Expires: <me.handoff.expires_at> (sliding — each inbound DM extends by ≥30 min)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Offer: *"Run `greprag discord unhandoff` to clear the pin and revert DMs to default routing."*
|
|
119
|
+
|
|
120
|
+
## Hard rules
|
|
121
|
+
|
|
122
|
+
- **Don't auto-handoff without user intent.** If the user just asked "am I paired?", show status — don't arm a Monitor.
|
|
123
|
+
- **Always use the wrapped form** in production. The bare `discord handoff` is for testing only.
|
|
124
|
+
- **Send replies via the CLI**, not curl. UTF-8 correctness, parser correctness, and the success-print all break in subtle ways otherwise.
|
|
125
|
+
- **Never `npm i -g greprag@latest`** from a session with a running handoff watcher — it kills the watcher mid-stream. Either land the upgrade before arming, or stop the Monitor first.
|
|
126
|
+
- **Pin scope is one snowflake → one session at a time.** A new handoff in another session supersedes the prior one silently.
|
|
127
|
+
|
|
128
|
+
## Related skills
|
|
129
|
+
|
|
130
|
+
- `/greprag` — broader greprag setup (memory, inbox, corpus). Step 5g there carries the same handoff guidance for sessions invoked through greprag-as-orchestrator.
|
|
131
|
+
- The `discord-notify` skill (separate, global) sends one-off Discord webhook pings for attention. Not related to this skill — that's a webhook, this is a paired DM bridge.
|