greprag 5.13.0 → 5.15.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/README.md +7 -6
- package/dist/commands/checkpoint-helpers.js +4 -1
- package/dist/commands/checkpoint-helpers.js.map +1 -1
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +270 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/lore.js +7 -5
- package/dist/commands/lore.js.map +1 -1
- package/dist/commands/memory.d.ts +31 -0
- package/dist/commands/memory.js +514 -0
- package/dist/commands/memory.js.map +1 -0
- package/dist/commands/project.d.ts +16 -0
- package/dist/commands/project.js +430 -0
- package/dist/commands/project.js.map +1 -0
- package/dist/hook.d.ts +1 -1
- package/dist/hook.js +9 -10
- package/dist/hook.js.map +1 -1
- package/dist/index.js +57 -19
- package/dist/index.js.map +1 -1
- package/dist/project-anchor.d.ts +1 -1
- package/dist/project-anchor.js +1 -1
- package/dist/session-id.d.ts +30 -25
- package/dist/session-id.js +39 -33
- package/dist/session-id.js.map +1 -1
- package/package.json +2 -1
- package/plugin/.claude-plugin/marketplace.json +13 -0
- package/plugin/plugins/greprag-inbox/.claude-plugin/plugin.json +7 -0
- package/plugin/plugins/greprag-inbox/monitors/monitors.json +8 -0
- package/skill/commander/SKILL.md +2 -2
- package/skill/content-advisor/SKILL.md +1 -1
- package/skill/greprag/SKILL.md +61 -661
- package/skill/greprag/docs/corpus.md +98 -0
- package/skill/greprag/docs/discord-handoff.md +47 -0
- package/skill/greprag/docs/discover.md +28 -0
- package/skill/greprag/docs/doctor.md +22 -0
- package/skill/greprag/docs/inbox-watch.md +57 -0
- package/skill/greprag/docs/inbox.md +100 -0
- package/skill/greprag/docs/lore.md +70 -0
- package/skill/greprag/docs/memory-advanced.md +23 -0
- package/skill/greprag/docs/per-project-flags.md +14 -0
- package/skill/greprag/docs/setup.md +208 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Corpus
|
|
2
|
+
|
|
3
|
+
Upload arbitrary text (book, codebase, reference doc, writing-sample library), search it with lexical grep enriched by write-side vocabulary bridging. Distinct from memory (the agent's own captured work, marketed as Odyssey).
|
|
4
|
+
|
|
5
|
+
**Design contract (post-v0.8):** GrepRAG does no LLM work at read time. The agent formulates lexical queries. Write-side enrichment bridges modern vocabulary to archaic registers (e.g. "insulted" finds "wrongeth" via tsvector OR). Read-side is pure SQL: field-weighted tsvector + ts_rank_cd + websearch_to_tsquery + adjacency-clustered ranking.
|
|
6
|
+
|
|
7
|
+
Triggers: "load this book into greprag", "upload the docs", "ingest this PDF" (after they convert it), "search the Marcus Aurelius corpus", "what does the codebase say about X", "find the passage about Y in the book I uploaded".
|
|
8
|
+
|
|
9
|
+
## Upload
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
greprag corpus upload <file-or-url> [--name "Display Name"] [--kind book]
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
- `--kind` is organizational metadata. Valid: `book`, `codebase`, `voice`, `generic`. Defaults to `book`. Lets you filter `greprag corpus list --kind codebase` later; doesn't change the enrichment prompt.
|
|
16
|
+
- Enrichment is GR5 phrase-aware, applied uniformly — single Narrow C prompt extracts single-word synonyms (graph expansion) and multi-word phrase variants (concept-level bridging). No per-kind prompt forking.
|
|
17
|
+
- `--name` defaults to filename basename. Prefer an explicit name — the user references the store by name later.
|
|
18
|
+
- File or URL must be plain text or markdown. PDFs: ask user to convert first.
|
|
19
|
+
- Cost: one round-trip to ingest + N async Gemini Flash-Lite calls (one per substantive node, drained every 2 min). Read-time cost: $0.
|
|
20
|
+
|
|
21
|
+
## Search — chain protocol
|
|
22
|
+
|
|
23
|
+
Searches are agent-driven. You decompose the user's intent into 1–3 lexical queries.
|
|
24
|
+
|
|
25
|
+
### Query operator syntax (websearch_to_tsquery)
|
|
26
|
+
|
|
27
|
+
- `term1 term2` — both required (AND)
|
|
28
|
+
- `term1 OR term2` — either suffices
|
|
29
|
+
- `"quoted phrase"` — exact adjacent words
|
|
30
|
+
- `-excluded` — must NOT contain
|
|
31
|
+
- Parenthesize: `(insulted OR wronged) -metadata`
|
|
32
|
+
|
|
33
|
+
Build queries that bridge user's modern vocabulary to corpus register. Stale prompts ("how should I respond when insulted") force every word — useless against archaic text. Decomposed queries ("insulted OR reproach OR contempt") win.
|
|
34
|
+
|
|
35
|
+
### Chain — probe, narrow, expand, cross-reference
|
|
36
|
+
|
|
37
|
+
1. **Probe** — `greprag corpus search "<store>" "<2-3 broad-vocab query>"` to find topic region.
|
|
38
|
+
2. **Narrow** — if results scatter, refine with `--section "Chapter VII"` or tighter operators and re-search.
|
|
39
|
+
3. **Expand** — for each promising hit, `greprag corpus walk "<store>" <nodeId>` to read surrounding ±2 nodes.
|
|
40
|
+
4. **Cross-reference** — re-search with a new angle if the first probe missed something the read-back suggests.
|
|
41
|
+
|
|
42
|
+
Each call is ~50–150ms. Two to four calls is normal.
|
|
43
|
+
|
|
44
|
+
### Single-store search
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
greprag corpus search "<store name or UUID>" "<lexical query>" [--limit 5] [--section "Book VII"] [--shape dialogue]
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Each result carries: `nodeId` (stable 8-char anchor), `position`, `headingPath`, `score`, `content`.
|
|
51
|
+
|
|
52
|
+
### Multistore search
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
curl -sf -X POST "$GREPRAG_API_URL/v1/search" \
|
|
56
|
+
-H "Authorization: Bearer $GREPRAG_API_KEY" \
|
|
57
|
+
-H "Content-Type: application/json" \
|
|
58
|
+
-d '{
|
|
59
|
+
"queries": ["insulted OR reproach", "wronged OR injustice"],
|
|
60
|
+
"storeIds": ["..."],
|
|
61
|
+
"limit": 8,
|
|
62
|
+
"adjacencyWindow": 3,
|
|
63
|
+
"adjacencyAlpha": 0.3,
|
|
64
|
+
"filters": {"section": "Book VII"}
|
|
65
|
+
}'
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Omit `storeIds` to search every store under the calling tenant. RRF fuses across (store × query) pairs; adjacency boosts surface semantic clusters.
|
|
69
|
+
|
|
70
|
+
## Walk
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
greprag corpus walk "<store>" <nodeId> [--before 2 --after 2]
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Surrounding-context fetch. ~50ms, no LLM.
|
|
77
|
+
|
|
78
|
+
## List / delete / status
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
greprag corpus list [--kind book]
|
|
82
|
+
greprag corpus status "<store>" # write-side enrichment progress
|
|
83
|
+
greprag corpus delete "<store>" --yes
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Corpus vs memory
|
|
87
|
+
|
|
88
|
+
| Want to … | Use |
|
|
89
|
+
|---|---|
|
|
90
|
+
| Look up a specific problem, bug, or topic in past sessions | `greprag memory search "<query>"` |
|
|
91
|
+
| Pull yesterday's daily, last week's weekly | `greprag memory recap` |
|
|
92
|
+
| "What shipped on this branch last week?" | `greprag memory ships --last 50` or `memory daily --last 7` |
|
|
93
|
+
| Backfill a missed compaction window | `greprag memory compact <hour\|day\|week>` |
|
|
94
|
+
| Load a book the user paste-bombed | `corpus upload` then `corpus search` |
|
|
95
|
+
| Search a codebase the user wants the agent to learn | `corpus upload --kind codebase` |
|
|
96
|
+
| Cross-corpus question across multiple uploads | `POST /v1/search` with omitted `storeIds` |
|
|
97
|
+
|
|
98
|
+
Memory is the agent's own past (marketed as Odyssey). Corpus is everything else.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Discord Handoff (Commander)
|
|
2
|
+
|
|
3
|
+
Discord DM bridge — user steps away from desk, conversation continues on phone. Orchestrator-side summary; operator-facing flow lives at `~/.claude/skills/commander/SKILL.md`.
|
|
4
|
+
|
|
5
|
+
Two surfaces: one-time pairing (identity) + per-session handoff (active routing). Emergency-router fallback: if the user DMs the bot with no handoff active, the bot auto-links to the most-recently-attached session watcher under their tenant. Tag `references.discord.emergency_route` on the inbox row flags the auto-link; reply with self-identification on first response.
|
|
6
|
+
|
|
7
|
+
## Pairing (one-time per tenant)
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
greprag discord pair
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Generates a 6-char code. User DMs `@greprag` on Discord with `/pair <code>`. After that, the user's snowflake is bound to their greprag tenant. DMs from that snowflake land as inbox messages on `default_project_id` (the project they paired from).
|
|
14
|
+
|
|
15
|
+
You don't run this — one-time setup the user does themselves. Detect "I'm paired" via `greprag discord me`: returns `paired: true` and the pairing's project_name.
|
|
16
|
+
|
|
17
|
+
## Handoff (per-session routing pin)
|
|
18
|
+
|
|
19
|
+
The pattern the user almost always means by "let's continue on Discord":
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
greprag discord handoff --ttl 60 --json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Run under `Monitor` (persistent: true). The command pins DMs from the user's snowflake to (this project, this session) for 60 min, fires a confirmation DM, then **blocks** streaming the session's inbox to stdout as JSON. Each line that prints is one Discord DM — Monitor delivers them as notifications back into your turn. Pin slides forward 30+ min on every inbound; an active thread stays anchored.
|
|
26
|
+
|
|
27
|
+
Replies go out via:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
greprag send --to discord:<snowflake> "your message body"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
CLI handles UTF-8, Discord's 2000-char limit, optional `--ref-json '{"discord":{"reply_to_message_id":"..."}}'` for threading. **Do not use curl for this** — bash on Windows mangles em-dashes / curly quotes / emoji into Win-1252 bytes that render as `?` on Discord. Node fetch (which the CLI uses) is UTF-8 native.
|
|
34
|
+
|
|
35
|
+
For long agent turns where auto-typing's 10-second window expires, call `greprag discord typing` between work steps to refresh the indicator. Silent on success.
|
|
36
|
+
|
|
37
|
+
`greprag discord unhandoff` releases the pin early (DMs revert to default project). Pin also expires naturally via TTL.
|
|
38
|
+
|
|
39
|
+
## Canonical handoff flow
|
|
40
|
+
|
|
41
|
+
User says "let's keep going on Discord" / "DM me" / "I'm stepping out":
|
|
42
|
+
|
|
43
|
+
1. Confirm pairing with `greprag discord me`. If unpaired, tell the user to run `greprag discord pair` and DM `/pair <code>` first.
|
|
44
|
+
2. Resolve current session_id (`CLAUDE_SESSION_ID` env, or the 8-hex from SessionStart context).
|
|
45
|
+
3. Arm: `Monitor` with command `greprag discord handoff --session <8-hex> --project <name> --ttl 60 --json`, persistent.
|
|
46
|
+
4. Tell the user the pin is live; the bot already DMed them. Each reply from Discord fires as a Monitor notification.
|
|
47
|
+
5. On each notification, parse the JSON body (`body` field = user's message text). Draft your reply. Send via `greprag send --to discord:<snowflake> "..."`. Snowflake is in `references.discord.snowflake`.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Discover (Cross-Project)
|
|
2
|
+
|
|
3
|
+
For advisor agents (`content-advisor`, `business-advisor`) that need to know which projects a tenant has memory in. One request returns every project plus per-shape row counts and activity ranges. No need to know directory paths upfront, no need to page through `/v1/memory/by-period` and risk one high-activity project crowding out structured rows from quieter ones.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
greprag discover --json
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Response shape:
|
|
10
|
+
```json
|
|
11
|
+
{
|
|
12
|
+
"tenant": { "id": "...", "userEmail": "..." },
|
|
13
|
+
"projects": [
|
|
14
|
+
{ "id": "<uuid>", "name": "openwriter", "anchor": "registered",
|
|
15
|
+
"row_counts": { "turn": 197, "hourly": 8, "daily": 1, "weekly": 0, "ship-event": 12 },
|
|
16
|
+
"first_activity": "2026-05-12T08:00:00Z",
|
|
17
|
+
"last_activity": "2026-05-25T11:42:00Z" }
|
|
18
|
+
],
|
|
19
|
+
"crystallization_types": ["turn","hourly","daily","weekly","ship-event"],
|
|
20
|
+
"totals": { "rows": 1234, "projects": 7 }
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`anchor: "registered"` means the project was registered via `/v1/inbox/projects/register` (has a row in the `projects` table — inbox addressing as `<email>/<project_name>` works).
|
|
25
|
+
|
|
26
|
+
`anchor: "fallback"` means the project is only known via memory-store metadata — still has memory, but no registry entry. Its name may be the path-derived basename and inbox-by-name resolution will not find it.
|
|
27
|
+
|
|
28
|
+
From there, pick a `projectId` and fetch its recap via the standard CLI verbs (`greprag memory recap --project <name>` etc.).
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Doctor (Health & Repair)
|
|
2
|
+
|
|
3
|
+
Triggers: user says "memory looks empty", "I'm missing my history", "fix greprag here", "are there orphans", "consolidate my project IDs"; or `greprag status` reports identity drift; or session-start recap printed `[GrepRAG memory: identity drift detected ...]`.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
greprag doctor
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
What it does:
|
|
10
|
+
1. Reads the current project's identity (project_id + which cascade level resolved it — file / git-derived / global / path-hash)
|
|
11
|
+
2. Computes what the git-derived UUID *would* be (if in a git repo with commits)
|
|
12
|
+
3. Queries the API for sibling project_ids under the same profile name (orphans — usually from old anchor files lost to gitignore or a hash-fallback period before init)
|
|
13
|
+
4. Presents findings and offers actions:
|
|
14
|
+
- **Migrate to git-derived UUID** (recommended on drift) — moves current + orphan rows onto the git-derived ID and strips `project_id` from `.claude/project.json` so identity flows from git history going forward
|
|
15
|
+
- **Consolidate orphans into current UUID** — keeps current identity but pulls orphan rows in
|
|
16
|
+
- **Dry-run** — runs the recommended action through the API with `dry_run: true` so the user sees exactly what would change before committing
|
|
17
|
+
|
|
18
|
+
Flags:
|
|
19
|
+
- `--inspect` — diagnose only, no prompts ("tell me what's wrong here")
|
|
20
|
+
- `--yes` / `-y` — non-interactive; picks the recommended action and runs it
|
|
21
|
+
|
|
22
|
+
Repair is fully tenant-scoped via the API — only touches rows under the caller's tenant. Merge runs in a transaction so a partial failure rolls back cleanly.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Inbox Watch (SSE)
|
|
2
|
+
|
|
3
|
+
Live push delivery via SSE. Use whenever you'd otherwise loop `greprag inbox` on a heartbeat — lower latency, cheaper, doesn't burn quota on empty polls.
|
|
4
|
+
|
|
5
|
+
## Commands
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
greprag inbox watch # tenant-wide stream
|
|
9
|
+
greprag inbox watch --project <name> # only messages addressed to this project
|
|
10
|
+
greprag inbox watch --session <id> # only messages targeting this session (plus broadcasts)
|
|
11
|
+
greprag inbox watch --since <id-or-iso> # resume from a known cursor
|
|
12
|
+
greprag inbox watch --json # one JSON object per line (preferred under Monitor)
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
`--project` and `--session` compose. `--session` is the strictest filter: only messages with matching `to_session_id` (or `to_session_id IS NULL` for broadcasts) get through. This eliminates cross-session noise when several Claude sessions watch the same project's inbox at once.
|
|
16
|
+
|
|
17
|
+
Each message arrives within ~500ms of the sender's `greprag send` (210ms verified end-to-end). Connection auto-reconnects with exponential backoff; the watcher tracks last seen message id and uses it as `since=` on reconnect — nothing dropped, nothing duplicated.
|
|
18
|
+
|
|
19
|
+
## Liveness model (post v0.8.5)
|
|
20
|
+
|
|
21
|
+
Server emits an SSE `: ping` comment every 15s. Client tracks time since last byte; 60s of silence (4 missed pings) = dead stream. Watcher aborts the fetch, reconnects with preserved cursor, server's per-tenant InboxDO replays any rows from the gap from its tail buffer (or backfills from DB for older gaps). After replay, server emits `event: replay-complete` with the row count — watcher logs `replayed N missed row(s), resuming live tail` to stderr.
|
|
22
|
+
|
|
23
|
+
Disconnects and reconnect attempts also log to stderr with the cursor. Pre-fix, a silently half-open TCP socket would hang the watcher indefinitely with no log; that failure mode is gone, but delivery is still opportunistic — the `UserPromptSubmit` hook remains the correctness guarantee.
|
|
24
|
+
|
|
25
|
+
## Pattern: parent watches for chip reports
|
|
26
|
+
|
|
27
|
+
Parent arms a Monitor scoped to its own session, then spawns the chip (chip's Block 2 sends with `--session <parent-session-id>`):
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
while true; do greprag inbox watch --session <parent-session-id> --json; echo "[wrapper] watcher exited, restarting in 1s" >&2; sleep 1; done
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
The `while`-loop wrapper auto-restarts the SSE process if it dies — a bare `greprag inbox watch` would silently end the Monitor task on any inner crash.
|
|
34
|
+
|
|
35
|
+
If the parent has no session identity (rare — older sessions before session-scope shipped), fall back to `--project <parent-project>`. The chip then sends without `--session` and the message reaches every watcher under the project.
|
|
36
|
+
|
|
37
|
+
## Pattern: post-send listens for replies
|
|
38
|
+
|
|
39
|
+
Any session that sends a message that could draw a directive in response arms the same watcher on its own inbox in the same turn. Without this, the Stop hook is the only path for the reply to surface — and Stop fires only between user prompts. Mid-task replies are invisible until the next stop boundary.
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# After: greprag send "..." --to <someone> --from-session <own-session-id>
|
|
43
|
+
# Arm under Monitor (persistent: true):
|
|
44
|
+
while true; do greprag inbox watch --session <own-session-id> --json; echo "[wrapper] watcher exited, restarting in 1s" >&2; sleep 1; done
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The `--from-session` flag on the outgoing message tells the recipient where to address replies; the `--session` filter on the watcher narrows incoming traffic to messages aimed at this exact session (plus broadcasts).
|
|
48
|
+
|
|
49
|
+
## Why Monitor, not Bash background
|
|
50
|
+
|
|
51
|
+
Run watchers under the `Monitor` agent tool with `persistent: true`. Monitor emits one notification per stdout line — the agent reacts the moment a message lands.
|
|
52
|
+
|
|
53
|
+
**Do NOT use `Bash(run_in_background: true)`** — Bash background notifies only on process completion. A watcher runs forever, so the agent gets zero events until it manually reads the output file. Stop with `TaskStop` on the Monitor task when the watch is truly no longer needed.
|
|
54
|
+
|
|
55
|
+
## Why not the Stop hook for replies
|
|
56
|
+
|
|
57
|
+
The greprag Stop hook ingests inbox messages between user prompts. A Mode B chip running autonomously may never hit a stop boundary; a Mode A chip waiting on a reply mid-task gets the reply only on the next manual interaction. Monitor delivers the reply as an in-session event the moment it lands — no hook lag, no missed directive.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Inbox
|
|
2
|
+
|
|
3
|
+
Send and read messages across sessions/projects/tenants. Plus the retract path for messages sent in error.
|
|
4
|
+
|
|
5
|
+
## Read
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
greprag inbox # list unread (auto-marks read)
|
|
9
|
+
greprag inbox --all # full history
|
|
10
|
+
greprag inbox keep <id> # extend a read message's TTL
|
|
11
|
+
greprag inbox delete <id>
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Auto-read semantics: any message returned by `greprag inbox` (without `--all`) is marked read in the same call. Once read, it stops appearing in notifications. TTL deletes read messages after 14 days. Use `keep` to extend before expiry.
|
|
15
|
+
|
|
16
|
+
## Send
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
greprag send "<markdown body>" --to <address>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
`send` prints two lines on success — the delivered-to confirmation **and a retract code**:
|
|
23
|
+
```
|
|
24
|
+
Sent to alice@greprag.com/abc12345 (a7f3c5e2)
|
|
25
|
+
Retract: greprag retract K9M2X4P7QV
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The retract code lets the sender pull the message back without layering follow-up "SUPERSEDES" notes. See § retract.
|
|
29
|
+
|
|
30
|
+
## Rich messages (back-pointers)
|
|
31
|
+
|
|
32
|
+
Preferred whenever the message refers to a memory row, a shipped artifact, or specific code lines:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
greprag send "Quick heads up — the auth bug I described yesterday repros here." \
|
|
36
|
+
--to alice@greprag.com/abc12345 \
|
|
37
|
+
--memory 04f3e0d4-aa12-44ef-9a01-bb3df2c7e911 \
|
|
38
|
+
--file src/auth/handler.ts:42 \
|
|
39
|
+
--file src/middleware/check.ts:10-15 \
|
|
40
|
+
--artifact commit:7a4d35b \
|
|
41
|
+
--artifact pr:#42
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Flags (all repeatable, all optional):
|
|
45
|
+
- `--memory <uuid>` — point to a memory row (turn, ship event, episodic summary)
|
|
46
|
+
- `--artifact <type:id>` — point to a shipped thing. Types: `commit`, `pr`, `deploy`, `release`, `push`, `merge`
|
|
47
|
+
- `--file <path[:lines]>` — point to a code location. Lines are `42` or `10-15`
|
|
48
|
+
- `--ref-json '<json>'` — escape hatch for a fully-formed references object (mutually exclusive with the above)
|
|
49
|
+
- `--from-session <id>` — sender's own session UUID. Denormalized onto the message so the recipient can address replies back without re-discovery. Use whenever you expect a reply.
|
|
50
|
+
|
|
51
|
+
When to populate references:
|
|
52
|
+
- Short chat ("pinging you", "deploy is up", "ack") → no references, just body.
|
|
53
|
+
- Bug reports, follow-ups, design decisions → always add `--file` and any `--artifact`.
|
|
54
|
+
- Cross-referencing prior memory → pull memory IDs from `greprag inbox` or the recap, pass via `--memory`.
|
|
55
|
+
- Don't hallucinate references. If you can't name a real file path or artifact ID, leave the flag off.
|
|
56
|
+
|
|
57
|
+
The legacy `--session` and `--project` flags were removed in v0.11 — passing them errors out with a migration hint. The target lives in the `--to` address itself.
|
|
58
|
+
|
|
59
|
+
## address
|
|
60
|
+
|
|
61
|
+
v0.11+ grammar:
|
|
62
|
+
|
|
63
|
+
| Form | Use | Behavior |
|
|
64
|
+
|---|---|---|
|
|
65
|
+
| `<handle>@greprag.com` | What you SHARE | Identity-only / receive form. Errors on send — the bare handle has no target. |
|
|
66
|
+
| `<handle>@greprag.com/<session-uuid>` | What you SEND with (normal) | Targets one specific session. UUID or 8-hex short form. Only that session's watcher receives. |
|
|
67
|
+
| `<handle>@greprag.com/<project-name>` | What you SEND with (rare) | Project-wide broadcast — every watcher in that project receives. Reserve for genuine "everyone in this project should know." |
|
|
68
|
+
| `me` / `self` | Shortcut for your own tenant | Receive form only. |
|
|
69
|
+
|
|
70
|
+
Disambiguation: a single segment after `/` is a session if it matches `[0-9a-f]{8}` (8-hex short form) or full UUID, otherwise a project name. Project names that look like UUIDs are rejected at registration time.
|
|
71
|
+
|
|
72
|
+
`<handle>` is one of:
|
|
73
|
+
- `1834729@greprag.com` — canonical numeric handle. Opaque, leaks nothing. Get yours from `greprag status --json | jq -r .identity.handle` or `greprag whoami`.
|
|
74
|
+
- `alice@greprag.com` — opt-in vanity alias (claim with `greprag identity claim alice`).
|
|
75
|
+
|
|
76
|
+
**Real emails are NEVER routing addresses.** `users.email` is auth credential only. If you don't know the recipient's numeric handle, ask the user — don't guess from their email. adr: adr/numeric-handles.md
|
|
77
|
+
|
|
78
|
+
Session targeting is the default and expected form. Project broadcasts are intentional opt-ins. adr: adr/address-grammar.md
|
|
79
|
+
|
|
80
|
+
## retract
|
|
81
|
+
|
|
82
|
+
`send` returns a retract code (printed after `Retract:` on the second line of success output). Use when you realize a message was wrong-framed and want to pull it back instead of stacking a follow-up note:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
greprag retract <code>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Server-decided behavior based on whether the recipient has read:
|
|
89
|
+
|
|
90
|
+
- **Unread** → row hard-deleted. Output: `Retracted (status: deleted — recipient had not read it).`
|
|
91
|
+
- **Read** → body replaced with `[RETRACTED BY SENDER at <ts>]`. Output: `Marked retracted (status: retracted_after_read — recipient had already read; they'll see the retraction notice in place of the original body).`
|
|
92
|
+
- **Already retracted** → no-op. Output: `Already retracted (status: already_retracted — no change).`
|
|
93
|
+
- **Unknown code** → no error. Output: `Not found (status: not_found — code does not match any message you sent, or the message has already expired).`
|
|
94
|
+
|
|
95
|
+
When to retract vs. SUPERSEDES follow-up:
|
|
96
|
+
- Just sent, recipient hasn't read, framing was wrong → `greprag retract`.
|
|
97
|
+
- Recipient has already read → `greprag retract` still beats stacked follow-up (placeholder vs. stale message), then send a fresh `greprag send` with corrected framing.
|
|
98
|
+
- Recipient already acted on the message (committed code, made a decision) → send `SUPERSEDES <old-id>: <correction>` so they have full context. Retract still cleans the original.
|
|
99
|
+
|
|
100
|
+
Retract codes are sender-scoped — your code cannot retract someone else's message. Codes stay valid until the message expires (14 days unread, longer if `keep`'d).
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Lore (LEARNINGS substrate)
|
|
2
|
+
|
|
3
|
+
Lore = what was learned. Project-specific emergent knowledge — gotchas, discovered constraints, drift-prone observations. Distinct from static project knowledge (which belongs in CLAUDE.md / docs / code structure).
|
|
4
|
+
|
|
5
|
+
Whenever you waste tokens *discovering* something a future agent shouldn't have to re-discover, seed it as project lore. Discovery is fine the first time — the failure mode is repeating it every time a chip spawns or a new session opens.
|
|
6
|
+
|
|
7
|
+
## When to seed
|
|
8
|
+
|
|
9
|
+
Three signatures of discovery waste:
|
|
10
|
+
|
|
11
|
+
- **Search cascade.** ≥3 `Glob` / `Grep` calls to find a path that should be obvious (where do migrations live? where's the inbox table? which file owns the CLI dispatch?). Seed with `scope: chip-startup`.
|
|
12
|
+
- **Schema archaeology.** ≥3 file `Read`s to reconstruct the shape of a data type, a JSONB column, or an API request body. Seed the shape (1–3 lines) with `scope: <subsystem>-touch`.
|
|
13
|
+
- **Trial-and-error env probing.** Multiple `Bash` attempts at the same env operation (different SSL flags, different connection strings, repeated "is this var set?" checks). Seed the working invocation with `scope: env`.
|
|
14
|
+
|
|
15
|
+
## How to seed
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
greprag lore add "<one-sentence learning, optionally with a file path>" --scope <scope> [--project <name>]
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Examples:
|
|
22
|
+
```bash
|
|
23
|
+
greprag lore add "Migrations live at repo root: migrations/<NNN>_<name>.sql. Apply with node scripts/apply-migration.cjs migrations/<file>.sql." --scope chip-startup
|
|
24
|
+
|
|
25
|
+
greprag lore add "Inbox storage uses JSONB metadata on nodes (store kind='inbox'). No inbox_messages table — dropped in migration 035. See packages/core/src/inbox.ts." --scope inbox-touch
|
|
26
|
+
|
|
27
|
+
greprag lore add "Build everything from repo root: npm run build (Turborepo). Forced rebuild: npm run build -- --force." --scope general
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Scope naming
|
|
31
|
+
|
|
32
|
+
Free-form strings — no enum. Check what's already in use first:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
greprag lore scopes [--project <name>]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Conventional scopes:
|
|
39
|
+
- `chip-startup` — what a freshly-spawned chip needs in its first 5 turns. Layout, build commands, test runners, key file paths.
|
|
40
|
+
- `general` — applies to almost any session in this project.
|
|
41
|
+
- `<subsystem>-touch` — lore that matters only when editing a specific subsystem (`inbox-touch`, `episodic-touch`, `enrichment-touch`).
|
|
42
|
+
- `env` — environment / credentials / DB connection gotchas.
|
|
43
|
+
|
|
44
|
+
Pick the narrowest scope that still applies. A lore entry about migration paths is `chip-startup` (every chip needs it); one about how the hourly compactor's prompt versioning works is `episodic-touch` (only relevant if you're editing that subsystem).
|
|
45
|
+
|
|
46
|
+
## Reading lore back
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
greprag lore query --scope chip-startup --limit 10 --format markdown # for inlining into a chip prompt
|
|
50
|
+
greprag lore query --scope inbox-touch --query "session routing" # lexical-rank within a scope
|
|
51
|
+
greprag lore query --query "how do migrations apply" --limit 5 # cross-scope, lexical-rank only
|
|
52
|
+
greprag lore list # human-review every entry, grouped by scope
|
|
53
|
+
greprag lore delete <nodeId> # prune stale entry
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`--format markdown` returns a numbered list with no decoration — drop straight into a `**Project Lore**` block when spawning a chip.
|
|
57
|
+
|
|
58
|
+
## Deliberate review
|
|
59
|
+
|
|
60
|
+
Lore decays as code moves — paths change, conventions die. Run `/lore-advisor` periodically (especially after a refactor or rename) to audit drift, mine episodic memory for newly-emerged learnings, and promote project-agnostic entries to global rules.
|
|
61
|
+
|
|
62
|
+
## Chip-spawn pull pattern
|
|
63
|
+
|
|
64
|
+
When composing a `spawn_task` chip prompt, pull `chip-startup` lore into the prompt before dispatching. Full convention: `~/.claude/docs/chip-spawn.md`. One-liner:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
greprag lore query --scope chip-startup --project <project> --limit 10 --format markdown
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Wrap the output in a `**Project Lore**` block at the top of the prompt. Skip the block when the output is empty.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Memory — Advanced
|
|
2
|
+
|
|
3
|
+
Raw curl recipes and the HTTP surface beneath `greprag memory`. Use only when the CLI verbs in SKILL.md don't cover the case (scripted use, automation, debugging).
|
|
4
|
+
|
|
5
|
+
## Raw curl
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
PROJECT_ID=$(greprag project-id)
|
|
9
|
+
TO=$(node -e "console.log(new Date().toISOString())")
|
|
10
|
+
FROM=$(node -e "const d=new Date(); d.setDate(d.getDate()-7); console.log(d.toISOString())")
|
|
11
|
+
curl -sf "https://api.greprag.com/v1/memory/by-period?projectId=${PROJECT_ID}&from=${FROM}&to=${TO}&type=daily&limit=7" \
|
|
12
|
+
-H "Authorization: Bearer ${GREPRAG_API_KEY}"
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## `/v1/memory/by-period` `--type` values
|
|
16
|
+
|
|
17
|
+
Valid: `turn`, `hourly`, `daily`, `weekly`, `ship-event`.
|
|
18
|
+
|
|
19
|
+
Earlier doc versions referenced `episodic-daily` / `episodic-weekly` — those values silently return zero rows because no node ever had that shape. The `greprag memory` CLI uses the correct values; prefer the CLI over raw curl.
|
|
20
|
+
|
|
21
|
+
## Naming note
|
|
22
|
+
|
|
23
|
+
The HTTP route stayed `/v1/memory/by-period`. The marketing brand for the product line is still "Odyssey" (see /odyssey/ on the website); the CLI verb is the literal noun `memory`. The `greprag odyssey ...` verb still works as a silent back-compat alias.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Per-Project Flags
|
|
2
|
+
|
|
3
|
+
Triggered when the user says "turn off recaps here", "stop capturing memory in this folder", or "only notify me of inbox at session start".
|
|
4
|
+
|
|
5
|
+
1. Read `<anchor_path>` from `greprag status --json`
|
|
6
|
+
2. Edit the JSON in-place — flip `memory_capture`, `session_start_recap`, or `inbox_notify`
|
|
7
|
+
3. Write it back
|
|
8
|
+
|
|
9
|
+
Hooks honor these flags on next fire — no restart needed.
|
|
10
|
+
|
|
11
|
+
Valid values:
|
|
12
|
+
- `memory_capture`: `true | false`
|
|
13
|
+
- `session_start_recap`: `true | false`
|
|
14
|
+
- `inbox_notify`: `"every_turn" | "session_start_only" | "off"`
|