greprag 5.40.1 → 5.42.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.
Files changed (80) hide show
  1. package/dist/archive/glyph-font.d.ts +22 -0
  2. package/dist/archive/glyph-font.js +72 -0
  3. package/dist/archive/glyph-font.js.map +1 -0
  4. package/dist/archive/page-renderer.d.ts +67 -0
  5. package/dist/archive/page-renderer.js +197 -0
  6. package/dist/archive/page-renderer.js.map +1 -0
  7. package/dist/archive/png-codec.d.ts +21 -0
  8. package/dist/archive/png-codec.js +197 -0
  9. package/dist/archive/png-codec.js.map +1 -0
  10. package/dist/archive/transcript-extract.d.ts +39 -0
  11. package/dist/archive/transcript-extract.js +187 -0
  12. package/dist/archive/transcript-extract.js.map +1 -0
  13. package/dist/ccr-store.d.ts +49 -0
  14. package/dist/ccr-store.js +171 -0
  15. package/dist/ccr-store.js.map +1 -0
  16. package/dist/commands/archive.d.ts +81 -0
  17. package/dist/commands/archive.js +358 -0
  18. package/dist/commands/archive.js.map +1 -0
  19. package/dist/commands/context-governor.d.ts +82 -0
  20. package/dist/commands/context-governor.js +344 -0
  21. package/dist/commands/context-governor.js.map +1 -0
  22. package/dist/commands/crush-stats.d.ts +36 -0
  23. package/dist/commands/crush-stats.js +142 -0
  24. package/dist/commands/crush-stats.js.map +1 -0
  25. package/dist/commands/crush.d.ts +24 -0
  26. package/dist/commands/crush.js +183 -0
  27. package/dist/commands/crush.js.map +1 -0
  28. package/dist/commands/email.js +158 -9
  29. package/dist/commands/email.js.map +1 -1
  30. package/dist/commands/inbox-watch-supervisor.js +8 -65
  31. package/dist/commands/inbox-watch-supervisor.js.map +1 -1
  32. package/dist/commands/init.js +93 -0
  33. package/dist/commands/init.js.map +1 -1
  34. package/dist/commands/pipe-wrap.d.ts +75 -0
  35. package/dist/commands/pipe-wrap.js +255 -0
  36. package/dist/commands/pipe-wrap.js.map +1 -0
  37. package/dist/commands/watcher-registry.d.ts +1 -8
  38. package/dist/commands/watcher-registry.js +10 -47
  39. package/dist/commands/watcher-registry.js.map +1 -1
  40. package/dist/crush/adaptive-sizer.d.ts +40 -0
  41. package/dist/crush/adaptive-sizer.js +156 -0
  42. package/dist/crush/adaptive-sizer.js.map +1 -0
  43. package/dist/crush/crush-keywords.d.ts +40 -0
  44. package/dist/crush/crush-keywords.js +110 -0
  45. package/dist/crush/crush-keywords.js.map +1 -0
  46. package/dist/crush/crush-types.d.ts +38 -0
  47. package/dist/crush/crush-types.js +36 -0
  48. package/dist/crush/crush-types.js.map +1 -0
  49. package/dist/crush/index.d.ts +16 -0
  50. package/dist/crush/index.js +48 -0
  51. package/dist/crush/index.js.map +1 -0
  52. package/dist/crush/json-crusher.d.ts +38 -0
  53. package/dist/crush/json-crusher.js +250 -0
  54. package/dist/crush/json-crusher.js.map +1 -0
  55. package/dist/crush/json-detectors.d.ts +48 -0
  56. package/dist/crush/json-detectors.js +211 -0
  57. package/dist/crush/json-detectors.js.map +1 -0
  58. package/dist/crush/log-compressor.d.ts +60 -0
  59. package/dist/crush/log-compressor.js +394 -0
  60. package/dist/crush/log-compressor.js.map +1 -0
  61. package/dist/crush/search-compressor.d.ts +60 -0
  62. package/dist/crush/search-compressor.js +210 -0
  63. package/dist/crush/search-compressor.js.map +1 -0
  64. package/dist/email-pull.d.ts +25 -3
  65. package/dist/email-pull.js +25 -5
  66. package/dist/email-pull.js.map +1 -1
  67. package/dist/email-send.d.ts +4 -0
  68. package/dist/email-send.js +2 -0
  69. package/dist/email-send.js.map +1 -1
  70. package/dist/hook.js +49 -1
  71. package/dist/hook.js.map +1 -1
  72. package/dist/index.js +487 -449
  73. package/dist/index.js.map +1 -1
  74. package/dist/session-id.js +7 -12
  75. package/dist/session-id.js.map +1 -1
  76. package/package.json +2 -2
  77. package/skill/greprag/SKILL.md +2 -2
  78. package/skill/greprag/docs/email.md +28 -4
  79. package/skill/mechanic/SKILL.md +1 -1
  80. package/skill/templates/chip-spawn.md +4 -2
package/dist/index.js CHANGED
@@ -53,6 +53,7 @@ const mechanic_1 = require("./commands/mechanic");
53
53
  const memory_1 = require("./commands/memory");
54
54
  const session_1 = require("./commands/session");
55
55
  const checkpoint_1 = require("./commands/checkpoint");
56
+ const context_governor_1 = require("./commands/context-governor");
56
57
  const identity_1 = require("./commands/identity");
57
58
  const skill_1 = require("./commands/skill");
58
59
  const project_1 = require("./commands/project");
@@ -62,6 +63,9 @@ const codex_1 = require("./commands/codex");
62
63
  const opencode_relay_1 = require("./commands/opencode-relay");
63
64
  const opencode_watch_1 = require("./commands/opencode-watch");
64
65
  const inbox_retract_1 = require("./commands/inbox-retract");
66
+ const crush_1 = require("./commands/crush");
67
+ const crush_stats_1 = require("./commands/crush-stats");
68
+ const archive_1 = require("./commands/archive");
65
69
  const inbox_watch_1 = require("./commands/inbox-watch");
66
70
  const discord_1 = require("./commands/discord");
67
71
  const project_anchor_1 = require("./project-anchor");
@@ -182,71 +186,64 @@ async function apiDelete(url, apiKey) {
182
186
  throw new Error(`API ${res.status}: ${await res.text()}`);
183
187
  return res.json();
184
188
  }
185
- const INBOX_HELP = `greprag inbox — read + manage your async message inbox.
186
-
187
- greprag inbox List unread for THIS session: its own lines
188
- only (sender or recipient). Other sessions'
189
- private lines AND the front desk are hidden;
190
- a footer counts any front-desk mail waiting.
191
- greprag inbox --front-desk Read the front desk: the tenant catch-all
192
- (cold opens + inbound email). Add --peek to
193
- survey without marking read.
194
- greprag inbox --all Audit peek: drop the per-session scope (every
195
- session's lines) AND include already-read.
196
- greprag inbox --peek List WITHOUT marking read (non-mutating).
197
- greprag inbox --session <8hex> Scope to one specific session's view.
198
- greprag inbox --project <name> Filter to one project's inbox.
199
- greprag inbox watch [...] Long-lived SSE stream (run under Monitor).
200
- [--receptionist] Attend the front desk — wake live on a cold
201
- open / inbound email (else only manual check).
202
- greprag inbox watchers [--json] List live armed watchers under your tenant.
203
- greprag inbox reap Kill orphaned watcher processes (consumer gone)
204
- + sweep stale pidfiles. Runs auto at session start.
205
- greprag inbox claim <id> Receptionist: claim a front-desk record so a
206
- co-armed receptionist stands down (no dup reply).
207
- greprag inbox keep <id> Extend a message's TTL.
208
- greprag inbox delete <id> Delete a message.
209
-
210
- To SEND or REPLY (top-level command, NOT an inbox subcommand):
211
- greprag send --to discord:<snowflake> "reply" Reply to a Discord DM.
212
- greprag send "msg" --to <handle>@greprag.com Cold open (tenant catch-all).
213
- greprag send "msg" --to <handle>@greprag.com/<session> Message a specific session.
214
- greprag send "msg" --to <h>@greprag.com/<session> --in-reply-to <front-desk-id>
189
+ const INBOX_HELP = `greprag inbox — read + manage your async message inbox.
190
+
191
+ greprag inbox List unread for THIS session: its own lines
192
+ only (sender or recipient). Other sessions'
193
+ private lines AND the front desk are hidden;
194
+ a footer counts any front-desk mail waiting.
195
+ greprag inbox --front-desk Read the front desk: the tenant catch-all
196
+ (cold opens + inbound email). Add --peek to
197
+ survey without marking read.
198
+ greprag inbox --all Audit peek: drop the per-session scope (every
199
+ session's lines) AND include already-read.
200
+ greprag inbox --peek List WITHOUT marking read (non-mutating).
201
+ greprag inbox --session <8hex> Scope to one specific session's view.
202
+ greprag inbox --project <name> Filter to one project's inbox.
203
+ greprag inbox watch [...] Long-lived SSE stream (run under Monitor).
204
+ [--receptionist] Attend the front desk — wake live on a cold
205
+ open / inbound email (else only manual check).
206
+ greprag inbox watchers [--json] List live armed watchers under your tenant.
207
+ greprag inbox reap Kill orphaned watcher processes (consumer gone)
208
+ + sweep stale pidfiles. Runs auto at session start.
209
+ greprag inbox claim <id> Receptionist: claim a front-desk record so a
210
+ co-armed receptionist stands down (no dup reply).
211
+ greprag inbox keep <id> Extend a message's TTL.
212
+ greprag inbox delete <id> Delete a message.
213
+
214
+ To SEND or REPLY (top-level command, NOT an inbox subcommand):
215
+ greprag send --to discord:<snowflake> "reply" Reply to a Discord DM.
216
+ greprag send "msg" --to <handle>@greprag.com Cold open (tenant catch-all).
217
+ greprag send "msg" --to <handle>@greprag.com/<session> Message a specific session.
218
+ greprag send "msg" --to <h>@greprag.com/<session> --in-reply-to <front-desk-id>
215
219
  Reply that threads a cold open.`;
216
- const INBOX_WATCH_HELP = `greprag inbox watch — long-lived SSE subscriber for live inbox delivery.
217
-
218
- Run under the Claude Code Monitor tool: each printed line becomes one
219
- notification, so a parent waiting on a chip report gets it the instant it
220
- lands instead of polling.
221
-
222
- greprag inbox watch Tenant-wide stream.
223
- greprag inbox watch --project <name> Only messages addressed to this project.
224
- greprag inbox watch --session <id> Only messages targeting this session
225
- (plus the front-desk catch-all). Strictest.
226
- greprag inbox watch --since <id|iso> Resume from a known cursor.
227
- greprag inbox watch --json One JSON object per line (preferred under Monitor).
228
- greprag inbox watch --receptionist Attend the front desk — wake live on a
229
- cold open / inbound email.
230
- greprag inbox watch --no-supervise Run the SSE loop directly, skipping the
231
- in-process supervisor (tests/debugging).
232
- greprag inbox watch --owner-pid <n> Owning claude.exe PID (stamped by the arm
233
- directive; the reaper keeps this watcher
234
- iff that PID is a live claude.exe).
235
- greprag inbox watch --monitor-pid <n> Monitor-task bash PID, Windows pid space
236
- (the arm command stamps it from
237
- /proc/$$/winpid). The watcher self-
238
- terminates when it diescovers TaskStop,
239
- which kills the Monitor task but not
240
- claude.exe. 0 = no stamp.
241
-
242
- Arm it BARE under Monitor (persistent:true) no "while true ... sleep 1" wrapper
243
- (removed 2026-06-04; it orphaned and OOM-crashed the host). Resilience by default:
244
- the watch SUPERVISES itself — a parent spawns the SSE loop as a child (Win32
245
- CreateProcess, not Cygwin fork) and respawns it on any non-clean exit (crash,
246
- undici error, OS kill); and it SELF-TERMINATES when its Monitor consumer's pipe
247
- breaks (session reload/end) OR its Monitor task's stamped bash PID dies
248
- (TaskStop) so it never orphans. Within-session robustness only; a watcher cannot
249
- survive session reload / --resume / /compact.
220
+ const INBOX_WATCH_HELP = `greprag inbox watch — long-lived SSE subscriber for live inbox delivery.
221
+
222
+ Run under the Claude Code Monitor tool: each printed line becomes one
223
+ notification, so a parent waiting on a chip report gets it the instant it
224
+ lands instead of polling.
225
+
226
+ greprag inbox watch Tenant-wide stream.
227
+ greprag inbox watch --project <name> Only messages addressed to this project.
228
+ greprag inbox watch --session <id> Only messages targeting this session
229
+ (plus the front-desk catch-all). Strictest.
230
+ greprag inbox watch --since <id|iso> Resume from a known cursor.
231
+ greprag inbox watch --json One JSON object per line (preferred under Monitor).
232
+ greprag inbox watch --receptionist Attend the front desk — wake live on a
233
+ cold open / inbound email.
234
+ greprag inbox watch --no-supervise Run the SSE loop directly, skipping the
235
+ in-process supervisor (tests/debugging).
236
+ greprag inbox watch --owner-pid <n> Owning claude.exe PID (stamped by the arm
237
+ directive; the reaper keeps this watcher
238
+ iff that PID is a live claude.exe).
239
+
240
+ Arm it BARE under Monitor (persistent:true) no "while true ... sleep 1" wrapper
241
+ (removed 2026-06-04; it orphaned and OOM-crashed the host). Resilience by default:
242
+ the watch SUPERVISES itselfa parent spawns the SSE loop as a child (Win32
243
+ CreateProcess, not Cygwin fork) and respawns it on any non-clean exit (crash,
244
+ undici error, OS kill); and it SELF-TERMINATES when its Monitor consumer's pipe
245
+ breaks (session reload/end) so it never orphans. Within-session robustness only;
246
+ a watcher cannot survive session reload / --resume / /compact.
250
247
  adr: adr/monitor-resilience.md`;
251
248
  /** greprag inbox [--all] [--session <id>] | inbox keep <id> | inbox delete <id> | inbox watch */
252
249
  /** greprag desk — the machine's desk-line (reverse-RPC relay to the cloud).
@@ -1177,274 +1174,305 @@ async function retract(args) {
1177
1174
  console.log((0, inbox_retract_1.formatRetractResult)(result.status));
1178
1175
  }
1179
1176
  // -- Main ------------------------------------------------------------------
1180
- const INIT_HELP = `greprag init — configure GrepRAG for an agent client.
1181
-
1182
- greprag init
1183
- greprag init --codex [--tenant-id <handle>|--api-key <key>] [--install-watcher]
1184
- greprag init --claude [--tenant-id <handle>|--api-key <key>]
1185
- greprag init --opencode [--tenant-id <handle>|--api-key <key>]
1186
- greprag init --all [--root <path>]
1187
- greprag init --global [--name <name>]
1188
-
1189
- Options:
1190
- --tenant-id <handle> Provision/use public handle <handle>@greprag.com.
1191
- Example: --tenant-id tanya -> tanya@greprag.com
1192
- --api-key <key> Use an existing GrepRAG API key instead of provisioning.
1193
- --codex Configure Codex hooks + /greprag skill.
1194
- --install-watcher With --codex, install the live inbox watcher at login.
1195
- --claude Configure Claude Code hooks + /greprag skill.
1196
- --opencode Configure OpenCode plugin.
1197
-
1198
- Codex Desktop trust step:
1199
- After init, start a fresh Codex session, then open Settings -> Settings -> Hooks
1177
+ const INIT_HELP = `greprag init — configure GrepRAG for an agent client.
1178
+
1179
+ greprag init
1180
+ greprag init --codex [--tenant-id <handle>|--api-key <key>] [--install-watcher]
1181
+ greprag init --claude [--tenant-id <handle>|--api-key <key>]
1182
+ greprag init --opencode [--tenant-id <handle>|--api-key <key>]
1183
+ greprag init --all [--root <path>]
1184
+ greprag init --global [--name <name>]
1185
+
1186
+ Options:
1187
+ --tenant-id <handle> Provision/use public handle <handle>@greprag.com.
1188
+ Example: --tenant-id tanya -> tanya@greprag.com
1189
+ --api-key <key> Use an existing GrepRAG API key instead of provisioning.
1190
+ --codex Configure Codex hooks + /greprag skill.
1191
+ --install-watcher With --codex, install the live inbox watcher at login.
1192
+ --claude Configure Claude Code hooks + /greprag skill.
1193
+ --opencode Configure OpenCode plugin.
1194
+
1195
+ Codex Desktop trust step:
1196
+ After init, start a fresh Codex session, then open Settings -> Settings -> Hooks
1200
1197
  and trust the GrepRAG hooks.`;
1201
- const HELP = `
1202
- greprag — agent memory for Claude Code, Codex, and OpenCode
1203
-
1204
- Commands:
1205
- init [--api-key <key>] [--tenant-id <handle>]
1206
- Auto-detect/ask for Codex, Claude Code, or OpenCode
1207
- init --claude [--api-key <key>] [--tenant-id <handle>]
1208
- Configure hooks + API key for Claude Code
1209
- init --global [--name <name>] Create ~/.greprag/project.json (global anchor)
1210
- init --opencode [--api-key <key>] [--tenant-id <handle>]
1211
- Configure plugin + anchor for OpenCode
1212
- init --codex [--api-key <key>] [--tenant-id <handle>] [--install-watcher]
1213
- Configure lifecycle hooks + anchor for Codex
1214
- init --all [--root <path>] Standard init for cwd, then bulk-register every
1215
- other git repo at depth 1 under <path> (default:
1216
- parent of repo root). Each becomes inbox-addressable.
1217
- status [--json] [--claude|--codex|--opencode]
1218
- Installation, auth, platform hooks/plugins, and project state
1219
- codex watch [--session <id>] Foreground live-push sidecar for Codex.
1220
- codex startup install Start the Codex live-push sidecar at login.
1221
- project-id Print the current project_id
1222
- session-id [--full] Print this session's id (8-hex, or full UUID with --full).
1223
- discover [--json] Tenant-wide structure: every project, per-shape row counts,
1224
- activity ranges. For cross-project advisors.
1225
- doctor [--inspect] [--yes] Diagnose + repair orphan project_ids and identity drift
1226
- smell "<text>" Shortcut for \`greprag fix log "<text>"\`.
1227
-
1228
- Inbox (email-style messaging across tenants):
1229
- inbox [--all] [--session <id>] [--project <name>] [--peek]
1230
- List unread, auto-scoped to THIS session: its own
1231
- lines (sender OR recipient) + the front desk
1232
- (tenant catch-all). Other sessions' private lines
1233
- are hidden by default.
1234
- --all = audit peek: drop the per-session scope
1235
- (every session's lines) AND include read history.
1236
- --session scopes to one specific session's view.
1237
- --project filters by project name.
1238
- --peek: NON-MUTATING does not mark any message read.
1239
- inbox watchers [--json] List currently-attached live watchers under this
1240
- tenant. Each row: project · title (session_id) —
1241
- project + nano title resolved from session memory.
1242
- Use to find session ids the orchestrator can message into.
1243
- inbox watch Long-lived SSE stream prints each message as it lands.
1244
- Self-supervising by default: a parent process
1245
- respawns the SSE loop (via CreateProcess) on any
1246
- non-clean exitwithin-session robustness, not
1247
- reload-survival. "inbox watch --help" for details.
1248
- [--project <name>] Filter to one project inbox (default: tenant-wide).
1249
- [--session <id>] Filter to messages targeting this session
1250
- (plus the front-desk catch-all).
1251
- [--receptionist] Attend the front desk wake live on a tenant
1252
- catch-all (cold open / inbound email). Without it,
1253
- cold opens surface only on a manual inbox check.
1254
- [--since <id|iso>] Resume after a message id or timestamp.
1255
- [--json] Emit raw JSON per line (for piping to Monitor).
1256
- [--no-supervise] Run the SSE loop directly (no supervisor) tests/debug.
1257
- inbox claim <id> Receptionist: claim a front-desk record (cold open /
1258
- inbound email). First claimant wins; a co-armed
1259
- receptionist stands down no double-reply.
1260
- inbox keep <id> Extend a read message's TTL (default delete after 14 days)
1261
- inbox delete <id> Permanently delete a message
1262
- send "body" --to <addr> Send a message. Body is markdown.
1263
- <addr> is a bare handle (tenant catch-all) or
1264
- handle/<target> see Addresses below.
1265
- send --body-file <path> --to <addr>
1266
- Send a long/multiline body from a file.
1267
- send --stdin --to <addr> Read message body from stdin.
1268
- --from-session <id> Sender's session — denormalized so the recipient can
1269
- reply by session without re-discovery.
1270
- --memory <uuid> (repeatable) back-pointer to a memory row
1271
- --artifact <type:id> (repeatable) e.g. commit:abc123, pr:#42, deploy:def
1272
- --file <path[:lines]> (repeatable) e.g. src/auth.ts, src/auth.ts:42, src/x.ts:10-15
1273
- --ref-json '<json>' escape hatch full references object
1274
- --in-reply-to <id> Thread a reply back to a front-desk record (cold open /
1275
- inbound email) sets references.in_reply_to so the
1276
- ensuing private line continues that conversation.
1277
- --to-desk Self-addressed internal mail posts to THIS project's own
1278
- desk (no recipient; omit --to). Requires --type.
1279
- --type <internal-type> Internal messageType for --to-desk (e.g. lore_smell). Queue
1280
- item drained by its consumer never wakes a watcher and is
1281
- hidden from the default inbox (audit via 'inbox --all').
1282
- retract <code> Pull back a previously-sent message (code is printed on send).
1283
- discord pair Pair Discord DMs to this project generates a code to DM the bot.
1284
- discord unpair Remove the Discord pairing.
1285
- discord me Show current Discord pairing + handoff state.
1286
- discord handoff [--ttl N] Pin DMs to this session for N min (default 60); bot DMs a confirmation.
1287
- discord unhandoff Clear the handoff pin (DMs revert to default project).
1288
- discord typing Refresh the "typing…" indicator on the paired DM thread.
1289
- send "body" --to discord:<snowflake>
1290
- Outbound DM to a paired Discord user from any session.
1291
- Unread hard delete. Read body replaced with a retracted notice.
1292
- Idempotent: double-retract is a no-op.
1293
-
1294
- Addresses:
1295
- Cold open: <handle>@greprag.com tenant catch-all first contact when
1296
- you don't know their session. Lands on
1297
- their front desk for a manual check;
1298
- no live ping.
1299
- Session: <handle>@greprag.com/<session-uuid> session-to-session (normal, live)
1300
- Self-desk: --to-desk --type <internal-type> internal queue item on your own project
1301
- desk — no recipient, no wake; drained by
1302
- its typed consumer (e.g. lore_smell).
1303
- --session and --project flags were removed; the address carries the target.
1304
- Project broadcasts (<handle>@greprag.com/<project-name>) were removed.
1305
-
1306
- Email (agent-email front desk drain inbound attachments to local disk):
1307
- email [pending] List pending front-desk email (envelope only).
1308
- email pull --id <record> Pull ONE record's attachments to local disk.
1309
- email pull --all-pending Pull EVERY pending record's attachments.
1310
- [--to <dir>] Save dir. Default: --to > $GREPRAG_EMAIL_DIR >
1311
- anchor email_dir > ~/.greprag/email/<project>.
1312
- [--quiet] Only print the one-line summary.
1313
- Saved as <subject-slug>-<index>.<ext>; re-pulls
1314
- are idempotent. Auto-save: set email_autosave=true
1315
- in .greprag/project.json so the mail hook pulls
1316
- new attachments each turn.
1317
-
1318
- Memory (episodic project memory turn/hourly/daily/ship-event):
1319
- memory search "<query>" Lexical retrieval over the project's memory.
1320
- Same v5 RRF + adjacency pipeline as 'corpus
1321
- search'. Use when looking up a specific
1322
- problem, bug, or topic.
1323
- [--limit N=5] [--shape <name>] [--project <name>] [--format markdown|json]
1324
- memory recap Recent daily summaries (SessionStart shape).
1325
- [--daily-last N=7] [--project <name>] [--format markdown|json]
1326
- memory daily [--last N=7] Most-recent daily summaries.
1327
- memory hourly [--last N=24] Most-recent hourly summaries.
1328
- memory turns [--last N=20] Raw per-turn envelopes (21-day TTL).
1329
- memory ships [--last N=50] Ship-event rows (commits/PRs/deploys/releases).
1330
- Common flags: [--project <name>] [--from ISO --to ISO] [--format markdown|json]
1331
- memory compact <hour|day|week> [--now ISO]
1332
- Manual compaction trigger (backfill / admin use).
1333
- (Aliases: 'briefing' 'recap' (renamed v5.16.0); 'odyssey' 'memory'
1334
- top-level verb (kept for v5.8.0 scripts).)
1335
-
1336
- Project fixes (emergent frictionfix repair, reviewed via /mechanic):
1337
- fix log "<text>" [--scope <S>] [--repaired] [--project <name>] [--source-session <id>]
1338
- Open a fix. Default: raw friction queued for /mechanic
1339
- to digest (no flags needed). --repaired records a known
1340
- durable rule directly (requires --scope).
1341
- Top-level alias: greprag smell "<text>".
1342
- fix list [--all] [--repaired] [--project <name>] [--format json]
1343
- Open queue by default; --repaired = resolved durable
1344
- rules grouped by scope; --all = tenant-wide census.
1345
- fix repair <id> "<rule>" [--scope <S>] [--project <name>]
1346
- Resolve a fix: record the durable rule, close the entry.
1347
- fix delete <nodeId> [--project <name>]
1348
- Hard-remove a fix (noise / cleanup).
1349
- fix search "<query>" [--scope <S>] [--limit N=10] [--project <name>] [--format markdown|json]
1350
- Lexical search across the project's fixes.
1351
- fix scopes [--project <name>] Distinct scope labels present in this project.
1352
-
1353
- Mechanic control plane (repairs as data — 'greprag mechanic --help'):
1354
- mechanic status [--format json] Inventory of live repairs; = ready to graduate.
1355
- mechanic enable <nodeId> Ratify a shadow repair → active.
1356
- mechanic disable <nodeId> [--retire] active shadow (default) or terminal retire.
1357
- mechanic why <nodeId> Provenance: friction fix repair chain.
1358
- mechanic off | on Panic switch suspend/resume ALL repairs (local file).
1359
-
1360
- Checkpoints (operator-triggered episodic bookmarks):
1361
- checkpoint save "<title>" [--note "<text>"] [--since "<duration>"]
1362
- [--project <name>] [--source-session <id>] [--force]
1363
- Server synthesizes the session window into a
1364
- summary + claims (gemini-2.5-flash), stores as
1365
- shape='checkpoint' in the project's memory store.
1366
- Title must be 5+ words & specific (server
1367
- hard-rejects generic / project-name-only).
1368
- checkpoint list [--project <name>] [--status open|closed|all] [--all]
1369
- Default: open only. --all drops the status filter.
1370
- checkpoint show <nodeId> [--project <name>]
1371
- Print summary + NEXT line + claims + note.
1372
- checkpoint edit-note <nodeId> --append "<text>" | --replace "<text>"
1373
- Update the operator-note overlay rendered below
1374
- the synthesis on show.
1375
- checkpoint close <nodeId> [--project <name>]
1376
- Flip to closed (keeps history). Idempotent.
1377
- checkpoint delete <nodeId> [--project <name>] [--yes]
1378
- Hard delete. "close keeps history; delete is
1379
- for typos."
1380
-
1381
- Corpus (upload + search arbitrary text — books, codebases, references):
1382
- corpus upload <file|url> --raw|--enriched Create a store + ingest. Mode REQUIRED:
1383
- [--name <N>] [--kind <K>] --raw (lexical — docs/code) | --enriched (per-node
1384
- [--refresh hourly|daily|manual|off] LLM vocab bridgeprose/voice). K: docs|
1385
- prose|transcript|codebase|voice|generic (default docs). html/pdf/docx/
1386
- xlsx/csv convert server-side. --refresh tracks a URL
1387
- for the freshness loop (URLs only; default off).
1388
- corpus search <store> "<intent>" [--limit 5] [--section "<h>"] [--shape S]
1389
- Single-store search. <store> is a UUID or name.
1390
- corpus search "<intent>" --all|--store <ref>... [--kind K] [--limit 8]
1391
- Multistore search (RRF-fused). --all = every store.
1392
- corpus section <store> "<heading>"
1393
- Every node under a heading (forgiving: any depth,
1394
- dash/case-insensitive).
1395
- corpus walk <store> <nodeId> [--before 2 --after 2]
1396
- Show a node and its surrounding context.
1397
- corpus status <store> Write-side enrichment progress (per-node vocab bridge).
1398
- corpus refresh <store> Manually re-check a tracked source (re-ingest changed blocks).
1399
- corpus sources <store> Freshness state: source, policy, last change, next check.
1400
- corpus list [--kind K] List stores under this tenant.
1401
- corpus delete <store> [--yes] Delete a store and its nodes.
1402
-
1403
- Identity (public handle + vanity alias real email is auth-only, never a routing address):
1404
- identity show | whoami Print numeric handle + claimed aliases.
1405
- identity claim <alias> Claim a vanity alias (e.g. "travis" → travis@greprag.com).
1406
- identity release <alias> Drop a claimed alias.
1407
-
1408
- Skills (opt-in advisor skills bundled with the CLI):
1409
- skill list Show bundled skills and install status
1410
- skill install <name> Install a bundled advisor (e.g. discord, content-advisor)
1411
- skill uninstall <name> Remove a previously-installed advisor
1412
-
1413
- Project metadata (rename / merge / list):
1414
- project rename <new-name> [--yes]
1415
- Rename the project at cwd (anchor + registry + API
1416
- + store metadata). Confirms before writing.
1417
- project merge --from <X> --into <Y> [--apply] [--name <override>] [--json]
1418
- Consolidate one project into another. Defaults to
1419
- dry-run. --from/--into accept a UUID or project_name.
1420
- --name renames the target in the same step.
1421
- project list [--json] Every project under this tenant, with anchor + rows.
1422
-
1423
- Opencode (bridge inbox SSE into a running opencode desktop session — the
1424
- Monitor equivalent, since opencode is turn-based by default):
1425
- opencode relay --session <id> [options]
1426
- Subscribe to /v1/inbox/stream and inject each
1427
- message as a fresh turn in the named opencode
1428
- desktop session via /session/{id}/prompt_async.
1429
- See \`greprag opencode --help\` for flags.
1430
-
1431
- Other:
1432
- expand --chunk <id> Expand a memory cluster (siblings, adjacent, linked)
1433
- help [--all] Show this overview. --all appends every command's
1434
- full --helpthe complete, always-current guide.
1435
-
1436
- Examples:
1437
- greprag init # standard repo setup
1438
- greprag init --global # Cowork / unanchored sessions
1439
- greprag init --all # register every sibling repo for inbox
1440
- greprag init --all --root C:\\ # scan a specific directory
1441
- greprag inbox
1442
- greprag send "done with migration" --to alice@greprag.com/abc12345
1443
- # session-targeted (normal)
1444
- greprag send "deploy approved" --to alice@greprag.com
1445
- # cold open — alice's front desk
1446
- greprag send "Bug in auth flow repro at line 42" --to alice@greprag.com/abc12345 \
1447
- --file src/auth.ts:42 --artifact commit:abc123
1198
+ const HELP = `
1199
+ greprag — agent memory for Claude Code, Codex, and OpenCode
1200
+
1201
+ Commands:
1202
+ init [--api-key <key>] [--tenant-id <handle>]
1203
+ Auto-detect/ask for Codex, Claude Code, or OpenCode
1204
+ init --claude [--api-key <key>] [--tenant-id <handle>]
1205
+ Configure hooks + API key for Claude Code
1206
+ init --global [--name <name>] Create ~/.greprag/project.json (global anchor)
1207
+ init --opencode [--api-key <key>] [--tenant-id <handle>]
1208
+ Configure plugin + anchor for OpenCode
1209
+ init --codex [--api-key <key>] [--tenant-id <handle>] [--install-watcher]
1210
+ Configure lifecycle hooks + anchor for Codex
1211
+ init --all [--root <path>] Standard init for cwd, then bulk-register every
1212
+ other git repo at depth 1 under <path> (default:
1213
+ parent of repo root). Each becomes inbox-addressable.
1214
+ status [--json] [--claude|--codex|--opencode]
1215
+ Installation, auth, platform hooks/plugins, and project state
1216
+ codex watch [--session <id>] Foreground live-push sidecar for Codex.
1217
+ codex startup install Start the Codex live-push sidecar at login.
1218
+ project-id Print the current project_id
1219
+ session-id [--full] Print this session's id (8-hex, or full UUID with --full).
1220
+ discover [--json] Tenant-wide structure: every project, per-shape row counts,
1221
+ activity ranges. For cross-project advisors.
1222
+ doctor [--inspect] [--yes] Diagnose + repair orphan project_ids and identity drift
1223
+ smell "<text>" Shortcut for \`greprag fix log "<text>"\`.
1224
+ context status [--session <id>] Context-size governor readout: live tokens, threshold,
1225
+ % consumed, turns since the crossover advisory last fired.
1226
+ "context --help" for config (threshold + off-switch).
1227
+
1228
+ Inbox (email-style messaging across tenants):
1229
+ inbox [--all] [--session <id>] [--project <name>] [--peek]
1230
+ List unread, auto-scoped to THIS session: its own
1231
+ lines (sender OR recipient) + the front desk
1232
+ (tenant catch-all). Other sessions' private lines
1233
+ are hidden by default.
1234
+ --all = audit peek: drop the per-session scope
1235
+ (every session's lines) AND include read history.
1236
+ --session scopes to one specific session's view.
1237
+ --project filters by project name.
1238
+ --peek: NON-MUTATING does not mark any message read.
1239
+ inbox watchers [--json] List currently-attached live watchers under this
1240
+ tenant. Each row: project · title (session_id)
1241
+ project + nano title resolved from session memory.
1242
+ Use to find session ids the orchestrator can message into.
1243
+ inbox watch Long-lived SSE stream prints each message as it lands.
1244
+ Self-supervising by default: a parent process
1245
+ respawns the SSE loop (via CreateProcess) on any
1246
+ non-clean exit within-session robustness, not
1247
+ reload-survival. "inbox watch --help" for details.
1248
+ [--project <name>] Filter to one project inbox (default: tenant-wide).
1249
+ [--session <id>] Filter to messages targeting this session
1250
+ (plus the front-desk catch-all).
1251
+ [--receptionist] Attend the front desk wake live on a tenant
1252
+ catch-all (cold open / inbound email). Without it,
1253
+ cold opens surface only on a manual inbox check.
1254
+ [--since <id|iso>] Resume after a message id or timestamp.
1255
+ [--json] Emit raw JSON per line (for piping to Monitor).
1256
+ [--no-supervise] Run the SSE loop directly (no supervisor) — tests/debug.
1257
+ inbox claim <id> Receptionist: claim a front-desk record (cold open /
1258
+ inbound email). First claimant wins; a co-armed
1259
+ receptionist stands down no double-reply.
1260
+ inbox keep <id> Extend a read message's TTL (default delete after 14 days)
1261
+ inbox delete <id> Permanently delete a message
1262
+ send "body" --to <addr> Send a message. Body is markdown.
1263
+ <addr> is a bare handle (tenant catch-all) or
1264
+ handle/<target> see Addresses below.
1265
+ send --body-file <path> --to <addr>
1266
+ Send a long/multiline body from a file.
1267
+ send --stdin --to <addr> Read message body from stdin.
1268
+ --from-session <id> Sender's session denormalized so the recipient can
1269
+ reply by session without re-discovery.
1270
+ --memory <uuid> (repeatable) back-pointer to a memory row
1271
+ --artifact <type:id> (repeatable) e.g. commit:abc123, pr:#42, deploy:def
1272
+ --file <path[:lines]> (repeatable) e.g. src/auth.ts, src/auth.ts:42, src/x.ts:10-15
1273
+ --ref-json '<json>' escape hatch full references object
1274
+ --in-reply-to <id> Thread a reply back to a front-desk record (cold open /
1275
+ inbound email) sets references.in_reply_to so the
1276
+ ensuing private line continues that conversation.
1277
+ --to-desk Self-addressed internal mailposts to THIS project's own
1278
+ desk (no recipient; omit --to). Requires --type.
1279
+ --type <internal-type> Internal messageType for --to-desk (e.g. lore_smell). Queue
1280
+ item drained by its consumer never wakes a watcher and is
1281
+ hidden from the default inbox (audit via 'inbox --all').
1282
+ retract <code> Pull back a previously-sent message (code is printed on send).
1283
+ discord pair Pair Discord DMs to this project generates a code to DM the bot.
1284
+ discord unpair Remove the Discord pairing.
1285
+ discord me Show current Discord pairing + handoff state.
1286
+ discord handoff [--ttl N] Pin DMs to this session for N min (default 60); bot DMs a confirmation.
1287
+ discord unhandoff Clear the handoff pin (DMs revert to default project).
1288
+ discord typing Refresh the "typing…" indicator on the paired DM thread.
1289
+ send "body" --to discord:<snowflake>
1290
+ Outbound DM to a paired Discord user from any session.
1291
+ Unread → hard delete. Read → body replaced with a retracted notice.
1292
+ Idempotent: double-retract is a no-op.
1293
+
1294
+ Addresses:
1295
+ Cold open: <handle>@greprag.com tenant catch-all — first contact when
1296
+ you don't know their session. Lands on
1297
+ their front desk for a manual check;
1298
+ no live ping.
1299
+ Session: <handle>@greprag.com/<session-uuid> session-to-session (normal, live)
1300
+ Self-desk: --to-desk --type <internal-type> internal queue item on your own project
1301
+ desk no recipient, no wake; drained by
1302
+ its typed consumer (e.g. lore_smell).
1303
+ --session and --project flags were removed; the address carries the target.
1304
+ Project broadcasts (<handle>@greprag.com/<project-name>) were removed.
1305
+
1306
+ Email (agent-email front desk drain inbound attachments to local disk):
1307
+ email [pending] List pending front-desk email (envelope only).
1308
+ email pull --id <record> Pull ONE record's attachments to local disk.
1309
+ email pull --all-pending Pull EVERY pending record's attachments.
1310
+ [--to <dir>] Save dir. Default: --to > $GREPRAG_EMAIL_DIR >
1311
+ anchor email_dir > ~/.greprag/email/<project>.
1312
+ [--quiet] Only print the one-line summary.
1313
+ Saved as <subject-slug>-<index>.<ext>; re-pulls
1314
+ are idempotent. Auto-save: set email_autosave=true
1315
+ in .greprag/project.json so the mail hook pulls
1316
+ new attachments each turn.
1317
+
1318
+ Memory (episodic project memory turn/hourly/daily/ship-event):
1319
+ memory search "<query>" Lexical retrieval over the project's memory.
1320
+ Same v5 RRF + adjacency pipeline as 'corpus
1321
+ search'. Use when looking up a specific
1322
+ problem, bug, or topic.
1323
+ [--limit N=5] [--shape <name>] [--project <name>] [--format markdown|json]
1324
+ memory recap Recent daily summaries (SessionStart shape).
1325
+ [--daily-last N=7] [--project <name>] [--format markdown|json]
1326
+ memory daily [--last N=7] Most-recent daily summaries.
1327
+ memory hourly [--last N=24] Most-recent hourly summaries.
1328
+ memory turns [--last N=20] Raw per-turn envelopes (21-day TTL).
1329
+ memory ships [--last N=50] Ship-event rows (commits/PRs/deploys/releases).
1330
+ Common flags: [--project <name>] [--from ISO --to ISO] [--format markdown|json]
1331
+ memory compact <hour|day|week> [--now ISO]
1332
+ Manual compaction trigger (backfill / admin use).
1333
+ (Aliases: 'briefing''recap' (renamed v5.16.0); 'odyssey' 'memory'
1334
+ top-level verb (kept for v5.8.0 scripts).)
1335
+
1336
+ Project fixes (emergent friction fix repair, reviewed via /mechanic):
1337
+ fix log "<text>" [--scope <S>] [--repaired] [--project <name>] [--source-session <id>]
1338
+ Open a fix. Default: raw friction queued for /mechanic
1339
+ to digest (no flags needed). --repaired records a known
1340
+ durable rule directly (requires --scope).
1341
+ Top-level alias: greprag smell "<text>".
1342
+ fix list [--all] [--repaired] [--project <name>] [--format json]
1343
+ Open queue by default; --repaired = resolved durable
1344
+ rules grouped by scope; --all = tenant-wide census.
1345
+ fix repair <id> "<rule>" [--scope <S>] [--project <name>]
1346
+ Resolve a fix: record the durable rule, close the entry.
1347
+ fix delete <nodeId> [--project <name>]
1348
+ Hard-remove a fix (noise / cleanup).
1349
+ fix search "<query>" [--scope <S>] [--limit N=10] [--project <name>] [--format markdown|json]
1350
+ Lexical search across the project's fixes.
1351
+ fix scopes [--project <name>] Distinct scope labels present in this project.
1352
+
1353
+ Mechanic control plane (repairs as data 'greprag mechanic --help'):
1354
+ mechanic status [--format json] Inventory of live repairs; = ready to graduate.
1355
+ mechanic enable <nodeId> Ratify a shadow repair active.
1356
+ mechanic disable <nodeId> [--retire] active → shadow (default) or terminal retire.
1357
+ mechanic why <nodeId> Provenance: friction → fix → repair chain.
1358
+ mechanic off | on Panic switch suspend/resume ALL repairs (local file).
1359
+
1360
+ Checkpoints (operator-triggered episodic bookmarks):
1361
+ checkpoint save "<title>" [--note "<text>"] [--since "<duration>"]
1362
+ [--project <name>] [--source-session <id>] [--force]
1363
+ Server synthesizes the session window into a
1364
+ summary + claims (gemini-2.5-flash), stores as
1365
+ shape='checkpoint' in the project's memory store.
1366
+ Title must be 5+ words & specific (server
1367
+ hard-rejects generic / project-name-only).
1368
+ checkpoint list [--project <name>] [--status open|closed|all] [--all]
1369
+ Default: open only. --all drops the status filter.
1370
+ checkpoint show <nodeId> [--project <name>]
1371
+ Print summary + NEXT line + claims + note.
1372
+ checkpoint edit-note <nodeId> --append "<text>" | --replace "<text>"
1373
+ Update the operator-note overlay rendered below
1374
+ the synthesis on show.
1375
+ checkpoint close <nodeId> [--project <name>]
1376
+ Flip to closed (keeps history). Idempotent.
1377
+ checkpoint delete <nodeId> [--project <name>] [--yes]
1378
+ Hard delete. "close keeps history; delete is
1379
+ for typos."
1380
+
1381
+ Corpus (upload + search arbitrary text books, codebases, references):
1382
+ corpus upload <file|url> --raw|--enriched Create a store + ingest. Mode REQUIRED:
1383
+ [--name <N>] [--kind <K>] --raw (lexical docs/code) | --enriched (per-node
1384
+ [--refresh hourly|daily|manual|off] LLM vocab bridge prose/voice). K: docs|
1385
+ prose|transcript|codebase|voice|generic (default docs). html/pdf/docx/
1386
+ xlsx/csv convert server-side. --refresh tracks a URL
1387
+ for the freshness loop (URLs only; default off).
1388
+ corpus search <store> "<intent>" [--limit 5] [--section "<h>"] [--shape S]
1389
+ Single-store search. <store> is a UUID or name.
1390
+ corpus search "<intent>" --all|--store <ref>... [--kind K] [--limit 8]
1391
+ Multistore search (RRF-fused). --all = every store.
1392
+ corpus section <store> "<heading>"
1393
+ Every node under a heading (forgiving: any depth,
1394
+ dash/case-insensitive).
1395
+ corpus walk <store> <nodeId> [--before 2 --after 2]
1396
+ Show a node and its surrounding context.
1397
+ corpus status <store> Write-side enrichment progress (per-node vocab bridge).
1398
+ corpus refresh <store> Manually re-check a tracked source (re-ingest changed blocks).
1399
+ corpus sources <store> Freshness state: source, policy, last change, next check.
1400
+ corpus list [--kind K] List stores under this tenant.
1401
+ corpus delete <store> [--yes] Delete a store and its nodes.
1402
+
1403
+ Crush (pre-LLM tool-output compression safe inside pipes, always exits 0):
1404
+ crush --type <log|search|json> [--ccr] [--query "words"]
1405
+ Read stdin, write the crushed version to stdout.
1406
+ log = build/test output (keep errors/traces/summaries),
1407
+ search = grep/rg output (keep scored top matches),
1408
+ json = large arrays (keep errors/outliers/first+last).
1409
+ --ccr stashes the ORIGINAL locally and appends a
1410
+ trailing <<ccr:HASH>> marker. If compression wouldn't
1411
+ save tokens (or input is tiny), stdin passes through
1412
+ verbatim never breaks the pipe.
1413
+ crush stats Totals + ratios from the pipe-wrap stats log
1414
+ (~/.greprag/crush-stats.jsonl one record per
1415
+ --stats invocation; the PreToolUse pipe-wrap
1416
+ hook passes --stats on every rewrite).
1417
+ retrieve <hash> Print a CCR-stashed original back to stdout.
1418
+ Store: ~/.greprag/ccr.db (override GREPRAG_CCR_DB).
1419
+
1420
+ Archive (governed compact lossless PNG snapshot of the pre-compact transcript):
1421
+ archive render --transcript <path> [--out-dir <dir>] [--session <8hex>]
1422
+ Render the transcript main chain to pixel-font
1423
+ PNGs (~30K chars/page, pixel round-trip verified)
1424
+ and index pages in the CCR store. The PreCompact
1425
+ hook runs this automatically before compaction.
1426
+ archive list [--session <id>] Indexed archives with page -> turn ranges.
1427
+ archive snippet [--session <id>]
1428
+ Print the documented /compact instruction block
1429
+ (preserve/compress rules + archive pointer line).
1430
+
1431
+ Identity (public handle + vanity alias real email is auth-only, never a routing address):
1432
+ identity show | whoami Print numeric handle + claimed aliases.
1433
+ identity claim <alias> Claim a vanity alias (e.g. "travis" → travis@greprag.com).
1434
+ identity release <alias> Drop a claimed alias.
1435
+
1436
+ Skills (opt-in advisor skills bundled with the CLI):
1437
+ skill list Show bundled skills and install status
1438
+ skill install <name> Install a bundled advisor (e.g. discord, content-advisor)
1439
+ skill uninstall <name> Remove a previously-installed advisor
1440
+
1441
+ Project metadata (rename / merge / list):
1442
+ project rename <new-name> [--yes]
1443
+ Rename the project at cwd (anchor + registry + API
1444
+ + store metadata). Confirms before writing.
1445
+ project merge --from <X> --into <Y> [--apply] [--name <override>] [--json]
1446
+ Consolidate one project into another. Defaults to
1447
+ dry-run. --from/--into accept a UUID or project_name.
1448
+ --name renames the target in the same step.
1449
+ project list [--json] Every project under this tenant, with anchor + rows.
1450
+
1451
+ Opencode (bridge inbox SSE into a running opencode desktop session — the
1452
+ Monitor equivalent, since opencode is turn-based by default):
1453
+ opencode relay --session <id> [options]
1454
+ Subscribe to /v1/inbox/stream and inject each
1455
+ message as a fresh turn in the named opencode
1456
+ desktop session via /session/{id}/prompt_async.
1457
+ See \`greprag opencode --help\` for flags.
1458
+
1459
+ Other:
1460
+ expand --chunk <id> Expand a memory cluster (siblings, adjacent, linked)
1461
+ help [--all] Show this overview. --all appends every command's
1462
+ full --help — the complete, always-current guide.
1463
+
1464
+ Examples:
1465
+ greprag init # standard repo setup
1466
+ greprag init --global # Cowork / unanchored sessions
1467
+ greprag init --all # register every sibling repo for inbox
1468
+ greprag init --all --root C:\\ # scan a specific directory
1469
+ greprag inbox
1470
+ greprag send "done with migration" --to alice@greprag.com/abc12345
1471
+ # session-targeted (normal)
1472
+ greprag send "deploy approved" --to alice@greprag.com
1473
+ # cold open — alice's front desk
1474
+ greprag send "Bug in auth flow — repro at line 42" --to alice@greprag.com/abc12345 \
1475
+ --file src/auth.ts:42 --artifact commit:abc123
1448
1476
  `.trim();
1449
1477
  /** Groups that ship their own detailed `--help`. `help --all` invokes each one
1450
1478
  * live and captures its output, so the assembled guide is rendered from the
@@ -1466,125 +1494,127 @@ const HELP_ALL_GROUPS = [
1466
1494
  ['project', project_1.runProject],
1467
1495
  ['skill', skill_1.runSkill],
1468
1496
  ['opencode', opencode],
1497
+ ['crush', crush_1.runCrush],
1498
+ ['archive', archive_1.runArchive],
1469
1499
  ];
1470
- const OPENCODE_HELP = `greprag opencode — bridge greprag inbox into a running opencode desktop
1471
- session, plus a file-watching capture pipeline for episodic memory.
1472
-
1473
- Two subcommands:
1474
-
1475
- greprag opencode relay Bridge greprag inbox into a running opencode
1476
- desktop session. Single POST to
1477
- /session/{id}/prompt_async enqueues a fresh turn;
1478
- the desktop app renders it into the conversation
1479
- feed via the same SSE channel the engine uses.
1480
- Desktop-only by design — the TUI control plane
1481
- is deprecated.
1482
-
1483
- Session-to-session by default: the relay derives
1484
- the greprag 8-hex from the opencode session UUID
1485
- and filters the inbox stream to only messages
1486
- addressed to THIS session. Use --tenant-wide to
1487
- opt into the noisy debug mode (every message in
1488
- the tenant, including messages for other
1489
- sessions).
1490
-
1491
- greprag opencode watch Long-lived SQLite poller on opencode's local DB.
1492
- Captures every (user, assistant) turn pair to
1493
- greprag memory. Bypasses opencode's event bus
1494
- entirely — reads the same rows the engine writes
1495
- the moment a turn completes.
1496
-
1497
- opencode is turn-based: it has no built-in "Monitor" tool like Claude Code.
1498
- \`relay\` is the bridge for live inbox delivery. \`watch\` is the capture
1499
- pipeline. Run both, in separate processes, as long-lived siblings.
1500
-
1501
- opencode relay — bridge greprag inbox into a running opencode desktop
1502
- session.
1503
-
1504
- This command subscribes to /v1/inbox/stream (same SSE channel inbox watch
1505
- uses) and POSTs every inbound message to /session/{id}/prompt_async on
1506
- the running opencode server. The receiving desktop session renders the
1507
- injected prompt as a fresh turn in its conversation feed.
1508
-
1509
- Usage:
1510
- greprag opencode relay --session <opencode-session-id> [options]
1511
-
1512
- Required:
1513
- --session <id> opencode session id (UUID). Find via
1514
- \`opencode session list\` or the session header in
1515
- the opencode UI.
1516
-
1517
- Options:
1518
- --opencode-url <u> opencode server base URL.
1519
- Default http://127.0.0.1:4096.
1520
- Env override: OPENCODE_URL.
1521
- --project <name> Filter the inbox stream to one project.
1522
- --inbox-session <8hex> Filter to one greprag session (8-hex id). Default
1523
- is auto-derived from --session (truncateSessionId)
1524
- so the relay only sees messages addressed to THIS
1525
- opencode session. Pass explicitly to override
1526
- (e.g. share one greprag session across multiple
1527
- opencode sessions).
1528
- --tenant-wide See every message in the tenant's inbox stream,
1529
- including messages addressed to other sessions.
1530
- Debug flag — noisy, usually wrong.
1531
- --since <id-or-iso> Resume cursor.
1532
- --print Pretty-print each message to stdout.
1533
- --dry-run Resolve + format, do not POST.
1534
-
1535
- Resilience mirrors inbox-watch: exponential backoff, idle timeout,
1536
- cursor-preserving reconnect. Production wraps this in a \`while true\` shell
1537
- loop so process death auto-restarts:
1538
-
1539
- while true; do greprag opencode relay --session <id>; \\
1540
- echo "[restart]" >&2; sleep 1; done
1541
-
1542
- Senders reach THIS session by addressing
1543
- \`<handle>@greprag.com/<8hex>\` where <8hex> is the first 8 hex chars of the
1544
- opencode session id (or pass \`--from-session <8hex>\` so the recipient can
1545
- reply back by session without re-discovering it).
1546
-
1547
-
1548
- opencode watch — SQLite-polling turn capture for episodic memory.
1549
-
1550
- opencode persists every message + part as a row in
1551
- %USERPROFILE%\\.local\\share\\opencode\\opencode.db (SQLite, WAL mode)
1552
- the moment the AI finishes streaming. This command polls that DB every
1553
- 1-2s, joins \`message\` to \`session\` to recover the working directory,
1554
- walks up to the greprag anchor, and POSTs the (user, assistant) pair to
1555
- /v1/memory/turn. No event bus. No sidecar auth. No plugin loader.
1556
-
1557
- Why this exists: opencode Desktop's event bus does not reliably emit
1558
- \`message.updated\` for the user's active session, so a plugin hook is
1559
- unreliable for capture. The on-disk DB is the source of truth — it is
1560
- written by the engine itself the moment a turn completes.
1561
-
1562
- Usage:
1563
- greprag opencode watch [options]
1564
-
1565
- Options:
1566
- --interval <ms> Poll interval. Default 1500.
1567
- --db <path> Override DB path. Default
1568
- %USERPROFILE%\\.local\\share\\opencode\\opencode.db
1569
- --project <dir> Only capture turns whose session.directory
1570
- resolves to this directory (anchor walk-up
1571
- target). Useful when running this once per
1572
- worktree.
1573
- --since <ms> Resume from this epoch ms. Default reads the
1574
- cursor (~/.greprag/opencode-watch.cursor).
1575
- On first run, captures every historical turn.
1576
- --cursor <file> Override the cursor file path.
1577
- --reset-cursor Delete the cursor file before starting. Use
1578
- with --since <ms> to re-capture from a point.
1579
- --json Print one JSON object per captured turn to
1580
- stdout, instead of human-readable status to
1581
- stderr.
1582
- --dry-run Print the would-be POST body, do not send.
1583
-
1584
- Run under a long-lived shell loop or as a Windows service:
1585
-
1586
- while true; do greprag opencode watch; \\
1587
- echo "[restart]" >&2; sleep 1; done
1500
+ const OPENCODE_HELP = `greprag opencode — bridge greprag inbox into a running opencode desktop
1501
+ session, plus a file-watching capture pipeline for episodic memory.
1502
+
1503
+ Two subcommands:
1504
+
1505
+ greprag opencode relay Bridge greprag inbox into a running opencode
1506
+ desktop session. Single POST to
1507
+ /session/{id}/prompt_async enqueues a fresh turn;
1508
+ the desktop app renders it into the conversation
1509
+ feed via the same SSE channel the engine uses.
1510
+ Desktop-only by design — the TUI control plane
1511
+ is deprecated.
1512
+
1513
+ Session-to-session by default: the relay derives
1514
+ the greprag 8-hex from the opencode session UUID
1515
+ and filters the inbox stream to only messages
1516
+ addressed to THIS session. Use --tenant-wide to
1517
+ opt into the noisy debug mode (every message in
1518
+ the tenant, including messages for other
1519
+ sessions).
1520
+
1521
+ greprag opencode watch Long-lived SQLite poller on opencode's local DB.
1522
+ Captures every (user, assistant) turn pair to
1523
+ greprag memory. Bypasses opencode's event bus
1524
+ entirely — reads the same rows the engine writes
1525
+ the moment a turn completes.
1526
+
1527
+ opencode is turn-based: it has no built-in "Monitor" tool like Claude Code.
1528
+ \`relay\` is the bridge for live inbox delivery. \`watch\` is the capture
1529
+ pipeline. Run both, in separate processes, as long-lived siblings.
1530
+
1531
+ opencode relay — bridge greprag inbox into a running opencode desktop
1532
+ session.
1533
+
1534
+ This command subscribes to /v1/inbox/stream (same SSE channel inbox watch
1535
+ uses) and POSTs every inbound message to /session/{id}/prompt_async on
1536
+ the running opencode server. The receiving desktop session renders the
1537
+ injected prompt as a fresh turn in its conversation feed.
1538
+
1539
+ Usage:
1540
+ greprag opencode relay --session <opencode-session-id> [options]
1541
+
1542
+ Required:
1543
+ --session <id> opencode session id (UUID). Find via
1544
+ \`opencode session list\` or the session header in
1545
+ the opencode UI.
1546
+
1547
+ Options:
1548
+ --opencode-url <u> opencode server base URL.
1549
+ Default http://127.0.0.1:4096.
1550
+ Env override: OPENCODE_URL.
1551
+ --project <name> Filter the inbox stream to one project.
1552
+ --inbox-session <8hex> Filter to one greprag session (8-hex id). Default
1553
+ is auto-derived from --session (truncateSessionId)
1554
+ so the relay only sees messages addressed to THIS
1555
+ opencode session. Pass explicitly to override
1556
+ (e.g. share one greprag session across multiple
1557
+ opencode sessions).
1558
+ --tenant-wide See every message in the tenant's inbox stream,
1559
+ including messages addressed to other sessions.
1560
+ Debug flag — noisy, usually wrong.
1561
+ --since <id-or-iso> Resume cursor.
1562
+ --print Pretty-print each message to stdout.
1563
+ --dry-run Resolve + format, do not POST.
1564
+
1565
+ Resilience mirrors inbox-watch: exponential backoff, idle timeout,
1566
+ cursor-preserving reconnect. Production wraps this in a \`while true\` shell
1567
+ loop so process death auto-restarts:
1568
+
1569
+ while true; do greprag opencode relay --session <id>; \\
1570
+ echo "[restart]" >&2; sleep 1; done
1571
+
1572
+ Senders reach THIS session by addressing
1573
+ \`<handle>@greprag.com/<8hex>\` where <8hex> is the first 8 hex chars of the
1574
+ opencode session id (or pass \`--from-session <8hex>\` so the recipient can
1575
+ reply back by session without re-discovering it).
1576
+
1577
+
1578
+ opencode watch — SQLite-polling turn capture for episodic memory.
1579
+
1580
+ opencode persists every message + part as a row in
1581
+ %USERPROFILE%\\.local\\share\\opencode\\opencode.db (SQLite, WAL mode)
1582
+ the moment the AI finishes streaming. This command polls that DB every
1583
+ 1-2s, joins \`message\` to \`session\` to recover the working directory,
1584
+ walks up to the greprag anchor, and POSTs the (user, assistant) pair to
1585
+ /v1/memory/turn. No event bus. No sidecar auth. No plugin loader.
1586
+
1587
+ Why this exists: opencode Desktop's event bus does not reliably emit
1588
+ \`message.updated\` for the user's active session, so a plugin hook is
1589
+ unreliable for capture. The on-disk DB is the source of truth — it is
1590
+ written by the engine itself the moment a turn completes.
1591
+
1592
+ Usage:
1593
+ greprag opencode watch [options]
1594
+
1595
+ Options:
1596
+ --interval <ms> Poll interval. Default 1500.
1597
+ --db <path> Override DB path. Default
1598
+ %USERPROFILE%\\.local\\share\\opencode\\opencode.db
1599
+ --project <dir> Only capture turns whose session.directory
1600
+ resolves to this directory (anchor walk-up
1601
+ target). Useful when running this once per
1602
+ worktree.
1603
+ --since <ms> Resume from this epoch ms. Default reads the
1604
+ cursor (~/.greprag/opencode-watch.cursor).
1605
+ On first run, captures every historical turn.
1606
+ --cursor <file> Override the cursor file path.
1607
+ --reset-cursor Delete the cursor file before starting. Use
1608
+ with --since <ms> to re-capture from a point.
1609
+ --json Print one JSON object per captured turn to
1610
+ stdout, instead of human-readable status to
1611
+ stderr.
1612
+ --dry-run Print the would-be POST body, do not send.
1613
+
1614
+ Run under a long-lived shell loop or as a Windows service:
1615
+
1616
+ while true; do greprag opencode watch; \\
1617
+ echo "[restart]" >&2; sleep 1; done
1588
1618
  `;
1589
1619
  /** greprag opencode <subcommand> — TUI bridge + capture watcher. */
1590
1620
  async function opencode(args) {
@@ -1708,7 +1738,15 @@ async function main() {
1708
1738
  case 'smell': return (0, fix_1.runFix)(['log', ...subArgs]); // field shortcut for `fix log`
1709
1739
  case 'memory': return (0, memory_1.runMemory)(subArgs);
1710
1740
  case 'odyssey': return (0, memory_1.runMemory)(subArgs); // silent alias kept for v5.8.0-era scripts; brand stays on marketing surfaces only.
1741
+ case 'crush':
1742
+ // `crush stats` is the savings readout; everything else is the stdin pipe.
1743
+ if (subArgs[0] === 'stats')
1744
+ return (0, crush_stats_1.runCrushStats)(subArgs.slice(1));
1745
+ return (0, crush_1.runCrush)(subArgs);
1746
+ case 'retrieve': return (0, crush_1.runRetrieve)(subArgs);
1747
+ case 'archive': return (0, archive_1.runArchive)(subArgs); // governed compact: PNG transcript archive
1711
1748
  case 'checkpoint': return (0, checkpoint_1.runCheckpoint)(subArgs);
1749
+ case 'context': return (0, context_governor_1.runContext)(subArgs); // context-size governor: status readout
1712
1750
  case 'identity': return (0, identity_1.runIdentity)(subArgs);
1713
1751
  case 'whoami': return (0, identity_1.runIdentity)(['show']);
1714
1752
  case 'skill': return (0, skill_1.runSkill)(subArgs);