greprag 0.10.0 → 5.0.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/dist/commands/corpus.js +5 -18
- package/dist/commands/corpus.js.map +1 -1
- package/dist/commands/inbox-watch.d.ts +6 -0
- package/dist/commands/inbox-watch.js +12 -1
- package/dist/commands/inbox-watch.js.map +1 -1
- package/dist/commands/init.js +34 -11
- package/dist/commands/init.js.map +1 -1
- package/dist/index.js +90 -25
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/skill/content-advisor/SKILL.md +65 -0
- package/skill/content-advisor/docs/data-sources.md +51 -0
- package/skill/content-advisor/docs/decision-rules.md +114 -0
- package/skill/content-advisor/docs/episodic-memory-queries.md +116 -0
- package/skill/content-advisor/docs/handoff-contract.md +91 -0
- package/skill/content-advisor/docs/output-format.md +89 -0
- package/skill/content-advisor/docs/setup.md +125 -0
- package/skill/content-advisor/docs/writing-activity.md +89 -0
- package/skill/{SKILL.md → greprag/SKILL.md} +36 -18
- package/skill/templates/agent-coordination.md +24 -17
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Setup — First-Run Gateway
|
|
2
|
+
|
|
3
|
+
The advisor's first invocation enters bootstrap. Setup runs once, written to a config file, then subsequent invocations skip directly to the standard protocol.
|
|
4
|
+
|
|
5
|
+
## Portfolio root resolution
|
|
6
|
+
|
|
7
|
+
Resolution order:
|
|
8
|
+
|
|
9
|
+
1. Env var `CONTENT_ADVISOR_ROOT`
|
|
10
|
+
2. Config file `~/.claude/content-advisor.json` with `{ "portfolio_root": "/abs/path" }`
|
|
11
|
+
3. Marker file scan up the cwd tree — looks for `docs/ventures.md` and `docs/strategy/focus.md`
|
|
12
|
+
4. Fallback default: `C:/orchestrator`
|
|
13
|
+
5. None applicable → ask user, save to config
|
|
14
|
+
|
|
15
|
+
The advisor never operates against an unresolved portfolio root.
|
|
16
|
+
|
|
17
|
+
## Setup flow
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
/content-advisor (no config detected)
|
|
21
|
+
↓
|
|
22
|
+
[Step 1] Locate portfolio root
|
|
23
|
+
→ default C:/orchestrator; confirm or override
|
|
24
|
+
→ save to ~/.claude/content-advisor.json
|
|
25
|
+
↓
|
|
26
|
+
[Step 2] Check GrepRAG
|
|
27
|
+
→ command -v greprag → exits 0?
|
|
28
|
+
→ test -n "$GREPRAG_API_KEY"? (source ~/.env if missing)
|
|
29
|
+
→ greprag discover --json → returns ≥1 project?
|
|
30
|
+
→ any failure → walk user through /greprag setup
|
|
31
|
+
↓
|
|
32
|
+
[Step 3] Verify writer skills present
|
|
33
|
+
→ ~/.claude/skills/x-writer/SKILL.md exists?
|
|
34
|
+
→ ~/.claude/skills/blog-writer/SKILL.md exists?
|
|
35
|
+
→ ~/.claude/skills/newsletter-writer/SKILL.md exists?
|
|
36
|
+
→ any missing → "Run /skill-publish from C:/openwriter to install the writer masters."
|
|
37
|
+
↓
|
|
38
|
+
[Step 4] Read WRITER-CONVENTION.md
|
|
39
|
+
→ C:/openwriter/skills/WRITER-CONVENTION.md (source of truth for handoff brief shape)
|
|
40
|
+
→ if absent, advisor still works but warns the contract is unverified
|
|
41
|
+
↓
|
|
42
|
+
[Step 4.5] Per-venture ICP (Ideal Customer Profile) derivation
|
|
43
|
+
→ For each venture in `project_to_venture`:
|
|
44
|
+
a) Search for an existing avatar / audience doc:
|
|
45
|
+
- OpenWriter workspaces with titles like "Audience", "Audience & Reader Journey", "Avatar", "ICP"
|
|
46
|
+
- The venture's marketing-site repo for `content/audience.md` or similar
|
|
47
|
+
- If found → store pointer in config under `icp_per_venture[venture]` as
|
|
48
|
+
`"openwriter:<docId>"` or `"file:<absolute-path>"`
|
|
49
|
+
b) If no doc exists, conduct a short interview (5-7 questions max):
|
|
50
|
+
- Who is the buyer? (one sentence)
|
|
51
|
+
- What's their current state? (the pain that brings them in)
|
|
52
|
+
- What do they pick up your content hoping for?
|
|
53
|
+
- What's the recognition shock they want? (their life mirrored back)
|
|
54
|
+
- What do they walk away with that's actionable this week?
|
|
55
|
+
- What's the failure mode of content that doesn't land?
|
|
56
|
+
- Optional: who do they trust today that you're competing with?
|
|
57
|
+
c) Write the interview output to `docs/icp/<venture>.md` in the portfolio
|
|
58
|
+
root and store the pointer in config.
|
|
59
|
+
→ Per-venture ICP is the demand-side spec the advisor reads at rank time
|
|
60
|
+
(see Rule 5 in `decision-rules.md`).
|
|
61
|
+
↓
|
|
62
|
+
[Step 5] Verify portfolio docs
|
|
63
|
+
→ docs/ventures.md, docs/strategy/focus.md present?
|
|
64
|
+
→ each missing → "Run /business-advisor to scaffold portfolio docs."
|
|
65
|
+
↓
|
|
66
|
+
[Step 6] Project ↔ venture mapping
|
|
67
|
+
→ greprag discover --json lists project names
|
|
68
|
+
→ match each to a venture umbrella (often 1:1; some ventures span multiple repos)
|
|
69
|
+
→ save to ~/.claude/content-advisor.json under `project_to_venture`
|
|
70
|
+
↓
|
|
71
|
+
[Step 7] Optional: per-venture cadence overrides
|
|
72
|
+
→ defaults in docs/decision-rules.md (X daily, newsletter weekly, blog 2×/mo)
|
|
73
|
+
→ user can override per venture in config under `cadence_overrides`
|
|
74
|
+
↓
|
|
75
|
+
[Step 8] Lock in
|
|
76
|
+
→ run one full pass, present opportunity list as the first output
|
|
77
|
+
→ confirm config persisted
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Config file format
|
|
81
|
+
|
|
82
|
+
`~/.claude/content-advisor.json`:
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"portfolio_root": "C:/orchestrator",
|
|
87
|
+
"greprag_api_url": "https://api.greprag.com",
|
|
88
|
+
"project_to_venture": {
|
|
89
|
+
"openwriter": "openwriter",
|
|
90
|
+
"openwriter-site": "openwriter",
|
|
91
|
+
"openwriter-publish": "openwriter",
|
|
92
|
+
"paybot": "paybot",
|
|
93
|
+
"paybot-portal": "paybot",
|
|
94
|
+
"tournamentmale": "tournament-male",
|
|
95
|
+
"tm-book": "tournament-male",
|
|
96
|
+
"orchestrator": "personal"
|
|
97
|
+
},
|
|
98
|
+
"cadence_overrides": {
|
|
99
|
+
"openwriter": { "blog": "weekly" }
|
|
100
|
+
},
|
|
101
|
+
"icp_per_venture": {
|
|
102
|
+
"your-venture-here": "openwriter:doc_abc123",
|
|
103
|
+
"another-venture": "file:C:/path/to/portfolio/docs/icp/another-venture.md"
|
|
104
|
+
},
|
|
105
|
+
"channels_per_venture": {
|
|
106
|
+
"tournament-male": ["x", "newsletter", "blog"],
|
|
107
|
+
"paybot": ["x", "blog"],
|
|
108
|
+
"openwriter": ["x", "blog"],
|
|
109
|
+
"personal": ["x", "newsletter"]
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
`channels_per_venture` is the gate that prevents the advisor from proposing a blog post for a venture that has no blog. Default behavior when a venture is missing from this map: assume all three channels eligible.
|
|
115
|
+
|
|
116
|
+
## Re-running setup
|
|
117
|
+
|
|
118
|
+
Delete `~/.claude/content-advisor.json` and re-invoke. Or invoke with "redo setup step N" to re-enter one sub-flow.
|
|
119
|
+
|
|
120
|
+
## Failure modes
|
|
121
|
+
|
|
122
|
+
- **GrepRAG unreachable** → advisor cannot run. Setup blocks. Source-farmer rule needs ship-events; nothing else compensates.
|
|
123
|
+
- **Writer skills missing** → advisor still produces the list but flags handoff commands as unverified.
|
|
124
|
+
- **Portfolio docs missing** → tier prioritization disabled (all opportunities treated equal). Surface a warning.
|
|
125
|
+
- **No projects in greprag discover** → no source material. Advisor exits with "no episodic memory yet — write code, ship something, then check back."
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Writing Activity
|
|
2
|
+
|
|
3
|
+
The "what have we already written" stream. Pairs with episodic memory to drive the anti-duplication and cadence-floor rules.
|
|
4
|
+
|
|
5
|
+
## What we want to know per channel per venture
|
|
6
|
+
|
|
7
|
+
| Channel | The question | Source |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| X | When was the last post? What topics in last 7d? | x-strategy cache, or fxtwitter recent timeline |
|
|
10
|
+
| Blog | When was the last post? What topics in last 30d? | git log on the venture's marketing-site repo + frontmatter scan |
|
|
11
|
+
| Newsletter | When was the last issue sent? What was its through-line? | `mcp__openwriter__list_newsletter_issues` |
|
|
12
|
+
| OpenWriter drafts | What's in flight right now (un-shipped drafts touched in last 14d)? | `mcp__openwriter__list_documents` filtered by recency |
|
|
13
|
+
|
|
14
|
+
## Per-source procedure
|
|
15
|
+
|
|
16
|
+
### OpenWriter drafts (in-flight)
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
list_workspaces → for each workspace:
|
|
20
|
+
list_documents → filter where updatedAt > now-14d AND not in trash
|
|
21
|
+
→ for each doc: extract { id, title, workspace_name, updatedAt, tags }
|
|
22
|
+
→ infer channel from workspace name conventions (blog/newsletter/x/scratch)
|
|
23
|
+
OR from tags if present
|
|
24
|
+
→ infer venture from workspace name OR explicit metadata
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
These are CRUCIAL — an in-flight draft on topic X means "don't propose another piece on X." Surface them as "in progress" markers, not opportunities.
|
|
28
|
+
|
|
29
|
+
### Newsletter sends
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
list_newsletter_issues → sort desc by sentAt → take top 4
|
|
33
|
+
→ for each: { id, subject, sentAt, doc_id }
|
|
34
|
+
→ most recent sentAt → "newsletter last sent N days ago"
|
|
35
|
+
→ if N > cadence floor (default 7d): cadence-floor opportunity for newsletter
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Blog history
|
|
39
|
+
|
|
40
|
+
For each venture with a marketing-site repo (path resolved via `project_to_venture` config + scanning `ventures.md` for repo paths):
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
git -C <repo> log --since="30 days ago" --name-only --pretty=format:'%h|%ci|%s'
|
|
44
|
+
→ filter file changes to blog content paths (src/content/blog/**, content/posts/**, etc.)
|
|
45
|
+
→ group commits by post file → { post_file, first_commit_date, latest_commit_date }
|
|
46
|
+
→ most recent → "blog last shipped N days ago"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The blog-content path convention varies per site; try common patterns:
|
|
50
|
+
- `src/content/blog/**` (Astro)
|
|
51
|
+
- `content/posts/**` (Hugo)
|
|
52
|
+
- `_posts/**` (Jekyll)
|
|
53
|
+
- `app/blog/**/page.mdx` (Next.js)
|
|
54
|
+
|
|
55
|
+
If no match, fall back to scanning frontmatter (`---\npubDate:`) in any `.md`/`.mdx` file modified in window.
|
|
56
|
+
|
|
57
|
+
### X activity
|
|
58
|
+
|
|
59
|
+
Three options, in preference order:
|
|
60
|
+
|
|
61
|
+
1. **`/x-strategy` cache** — if present at a known path, parse the latest cached export.
|
|
62
|
+
2. **`mcp__x__*` tools** — if the X MCP is connected, query recent tweets for @Meta_Trav.
|
|
63
|
+
3. **fxtwitter timeline** — public, free; parse the user's recent posts.
|
|
64
|
+
|
|
65
|
+
What we want: list of `{ posted_at, text, type: thread|single|article|comic, topic_inferred }`. Topic inference is best-effort — a 30-word excerpt is enough to dedupe against memory rows.
|
|
66
|
+
|
|
67
|
+
## Output of this stream
|
|
68
|
+
|
|
69
|
+
A per-venture-per-channel activity map:
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"tournament-male": {
|
|
74
|
+
"x": { "last_at": "2026-05-24T...", "topics_7d": ["six-week challenge", "kettlebell program"] },
|
|
75
|
+
"newsletter": { "last_at": "2026-05-19T...", "subject": "Week of May 19" },
|
|
76
|
+
"blog": { "last_at": "2026-04-30T...", "recent_topics": ["bible study cohort"] }
|
|
77
|
+
},
|
|
78
|
+
"paybot": {
|
|
79
|
+
"x": { "last_at": "2026-05-23T...", "topics_7d": ["upgrade flow ship"] },
|
|
80
|
+
"blog": { "last_at": "2026-05-10T...", "recent_topics": ["new pricing"] }
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Plus a separate "in-flight drafts" list across all ventures (the OpenWriter list_documents output, filtered by recency).
|
|
86
|
+
|
|
87
|
+
## Failure tolerance
|
|
88
|
+
|
|
89
|
+
Any one of these sources can be down without breaking the advisor — they're enrichment. The minimum viable run is: greprag memory + ventures.md + focus.md. Everything else just sharpens ranking.
|
|
@@ -133,9 +133,15 @@ Delegating work — `spawn_task` chip vs `Agent` tool, two chip modes, the workt
|
|
|
133
133
|
|
|
134
134
|
**Non-negotiables for every `spawn_task` chip prompt:** (0.5) project facts pulled from `greprag fact`, (1) worktree-first setup, (2) `greprag send` report-back, (3) `Monitor` on own inbox for follow-ups. Without them the chip pollutes the main checkout, has no return channel, or dies after one report. Copy the boilerplate verbatim from the deep doc.
|
|
135
135
|
|
|
136
|
-
**Reply listening (any session, not just chips).** Any time you `greprag send` a message that could draw a directive in response, arm a `Monitor` watcher on your own inbox in the same turn
|
|
136
|
+
**Reply listening (any session, not just chips).** Any time you `greprag send` a message that could draw a directive in response, arm a `Monitor` watcher on your own inbox in the same turn. Use the bash-wrapper form so the watcher auto-restarts if the inner SSE process dies (network blip, supervisor bug, Cygwin fork failure):
|
|
137
137
|
|
|
138
|
-
|
|
138
|
+
```bash
|
|
139
|
+
while true; do greprag inbox watch --session <own-session-id> --json; echo "[wrapper] watcher exited, restarting in 1s" >&2; sleep 1; done
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Run under `Monitor` with `persistent: true`. Fall back to `--project <own-project>` instead of `--session` when no session identity is available. The Stop hook only fires between user prompts; without Monitor, mid-task replies are invisible until the next stop boundary.
|
|
143
|
+
|
|
144
|
+
For real-time chip reports, the parent arms the same wrapped watcher (`--session <parent-session-id>` preferred, `--project <parent-project>` for multi-chip campaigns) under `Monitor` BEFORE spawning. Each stdout line = one notification. Do NOT use `Bash(run_in_background)` — it only fires on process completion, not per line; a watcher never exits, so the parent gets zero events. Do NOT use the bare `greprag inbox watch` without the `while true` wrapper — if the inner watcher dies you go silently deaf with no restart.
|
|
139
145
|
<!-- greprag-conventions:end v3 -->
|
|
140
146
|
```
|
|
141
147
|
|
|
@@ -289,7 +295,7 @@ greprag send "<markdown body>" --to <address>
|
|
|
289
295
|
|
|
290
296
|
`send` prints two lines on success — the delivered-to confirmation **and a retract code**:
|
|
291
297
|
```
|
|
292
|
-
Sent to alice@
|
|
298
|
+
Sent to alice@greprag.com/abc12345 (a7f3c5e2)
|
|
293
299
|
Retract: greprag retract K9M2X4P7QV
|
|
294
300
|
```
|
|
295
301
|
The retract code lets the sender pull the message back without layering follow-up "SUPERSEDES" notes on top. See Step 5d.
|
|
@@ -297,7 +303,7 @@ The retract code lets the sender pull the message back without layering follow-u
|
|
|
297
303
|
To send a **rich message** with back-pointers — preferred whenever the message refers to a memory row, a shipped artifact, or specific code lines:
|
|
298
304
|
```bash
|
|
299
305
|
greprag send "Quick heads up — the auth bug I described yesterday repros here." \
|
|
300
|
-
--to alice@
|
|
306
|
+
--to alice@greprag.com/abc12345 \
|
|
301
307
|
--memory 04f3e0d4-aa12-44ef-9a01-bb3df2c7e911 \
|
|
302
308
|
--file src/auth/handler.ts:42 \
|
|
303
309
|
--file src/middleware/check.ts:10-15 \
|
|
@@ -310,8 +316,9 @@ Flags (all repeatable, all optional):
|
|
|
310
316
|
- `--artifact <type:id>` — point to a shipped thing. Types: `commit`, `pr`, `deploy`, `release`, `push`, `merge`
|
|
311
317
|
- `--file <path[:lines]>` — point to a code location. Lines are `42` or `10-15`
|
|
312
318
|
- `--ref-json '<json>'` — escape hatch for a fully-formed references object (mutually exclusive with the above)
|
|
313
|
-
- `--session <id>` —
|
|
314
|
-
|
|
319
|
+
- `--from-session <id>` — sender's own session UUID. Denormalized onto the message so the recipient learns your session and can address replies back without re-discovery. Use whenever you expect a reply.
|
|
320
|
+
|
|
321
|
+
The target lives in the `--to` address itself (see "Address formats" below). The legacy `--session` and `--project` flags were removed in v0.11 — passing them now errors out with a migration hint.
|
|
315
322
|
|
|
316
323
|
**When to populate references vs. when to leave them off:**
|
|
317
324
|
- Short chat messages ("pinging you", "deploy is up", "ack") — no references, just body.
|
|
@@ -319,16 +326,24 @@ Flags (all repeatable, all optional):
|
|
|
319
326
|
- Cross-referencing prior memory — pull memory IDs from a `greprag inbox` listing or from the recap and pass via `--memory`. The recipient agent can fetch the row directly.
|
|
320
327
|
- Don't hallucinate references. If you can't name a real file path or artifact ID, leave the flag off.
|
|
321
328
|
|
|
322
|
-
Address formats (
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
329
|
+
Address formats (v0.11+):
|
|
330
|
+
|
|
331
|
+
| Form | Use | Behavior |
|
|
332
|
+
|---|---|---|
|
|
333
|
+
| `<handle>@greprag.com` | What you SHARE | Identity-only / receive form. Errors on send — the bare handle has no target. |
|
|
334
|
+
| `<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. |
|
|
335
|
+
| `<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" messages. |
|
|
336
|
+
| `me` / `self` | Shortcut for your own tenant | Receive form only. |
|
|
337
|
+
|
|
338
|
+
Disambiguation rule: 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 so this is always unambiguous.
|
|
339
|
+
|
|
340
|
+
`<handle>` is one of:
|
|
341
|
+
- `1834729@greprag.com` — canonical numeric handle. Opaque, leaks nothing. Get yours from `greprag status --json | jq -r .identity.handle` or `greprag whoami`.
|
|
326
342
|
- `alice@greprag.com` — opt-in vanity alias (claim with `greprag identity claim alice`).
|
|
327
|
-
- `me` / `self` — shortcut for your own tenant inbox (server resolves).
|
|
328
343
|
|
|
329
344
|
**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
|
|
330
345
|
|
|
331
|
-
|
|
346
|
+
Session targeting is the default and expected form. Project broadcasts are intentional opt-ins for the rare case where everyone in a project should hear something. adr: adr/address-grammar.md
|
|
332
347
|
|
|
333
348
|
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.
|
|
334
349
|
|
|
@@ -359,7 +374,9 @@ Each message arrives within ~500ms of the sender's `greprag send` (210ms verifie
|
|
|
359
374
|
# (chip prompt's Block 2 sends with --session <parent-session-id>).
|
|
360
375
|
# Each chip's "done" report becomes one Monitor notification, with no cross-talk
|
|
361
376
|
# from other chips or sessions sharing the parent's project inbox.
|
|
362
|
-
|
|
377
|
+
# The while-loop wrapper auto-restarts the SSE process if it dies — a bare
|
|
378
|
+
# `greprag inbox watch` would silently end the Monitor task on any inner crash.
|
|
379
|
+
while true; do greprag inbox watch --session <parent-session-id> --json; echo "[wrapper] watcher exited, restarting in 1s" >&2; sleep 1; done
|
|
363
380
|
```
|
|
364
381
|
|
|
365
382
|
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.
|
|
@@ -371,7 +388,8 @@ Any session that sends a message that could draw a directive in response arms th
|
|
|
371
388
|
```bash
|
|
372
389
|
# After: greprag send "..." --to <someone>/<their-project>/<their-session> \
|
|
373
390
|
# --from-session <own-session-id>
|
|
374
|
-
# Arm
|
|
391
|
+
# Arm under Monitor (persistent: true):
|
|
392
|
+
while true; do greprag inbox watch --session <own-session-id> --json; echo "[wrapper] watcher exited, restarting in 1s" >&2; sleep 1; done
|
|
375
393
|
```
|
|
376
394
|
|
|
377
395
|
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 general broadcasts). No more sibling-chip cross-talk and no self-echo from tenant-wide sends.
|
|
@@ -438,11 +456,11 @@ Triggers: "load this book into greprag", "upload the docs", "ingest this PDF" (a
|
|
|
438
456
|
### Upload
|
|
439
457
|
|
|
440
458
|
```bash
|
|
441
|
-
greprag corpus upload <file-or-url> [--name "Display Name"] [--kind book]
|
|
459
|
+
greprag corpus upload <file-or-url> [--name "Display Name"] [--kind book]
|
|
442
460
|
```
|
|
443
461
|
|
|
444
|
-
- `--kind`
|
|
445
|
-
-
|
|
462
|
+
- `--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.
|
|
463
|
+
- Enrichment is GR5 phrase-aware, applied uniformly to all corpus kinds — the single Narrow C prompt extracts single-word synonyms (graph expansion) and multi-word phrase variants (concept-level bridging). No per-kind prompt forking.
|
|
446
464
|
- `--name` defaults to the filename basename. Prefer an explicit name — the user references the store by name later.
|
|
447
465
|
- File or URL must be plain text or markdown. PDFs: ask the user to convert first.
|
|
448
466
|
- Cost: one round-trip to ingest + N async Gemini Flash-Lite calls (one per substantive node, drained every 2 min). Read-time cost: $0.
|
|
@@ -523,7 +541,7 @@ greprag corpus delete "<store>" --yes
|
|
|
523
541
|
| Pull yesterday's daily summary, last week's weekly | `/v1/memory/by-period` (Step 6 briefing flow) |
|
|
524
542
|
| Ask "what did I work on with the auth migration?" | `/v1/memory/by-period` filtered by keywords |
|
|
525
543
|
| Load a book the user paste-bombed into the chat | `corpus upload` then `corpus search` |
|
|
526
|
-
| Search a codebase the user wants the agent to learn | `corpus upload --kind codebase
|
|
544
|
+
| Search a codebase the user wants the agent to learn | `corpus upload --kind codebase` |
|
|
527
545
|
| Cross-corpus question across multiple uploads | `POST /v1/search` with omitted `storeIds` |
|
|
528
546
|
|
|
529
547
|
Episodic memory is the agent's own past. Corpus is everything else.
|
|
@@ -59,7 +59,7 @@ All edits, tests, and commits happen in the worktree. The main checkout stays un
|
|
|
59
59
|
**Your parent's session id is `<parent-session-id>`** — record it; you'll need it in Block 2 to address the report-back so only the parent sees it, not every sibling chip watching the same project inbox.
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
Fill `<parent-session-id>` from your own (parent) session UUID when composing the spawn_task prompt. If you don't know your session UUID, fall back to project-level addressing throughout Block 2/3 — the chip then sends to `--to <
|
|
62
|
+
Fill `<parent-session-id>` from your own (parent) session UUID when composing the spawn_task prompt. If you don't know your session UUID, fall back to project-level addressing throughout Block 2/3 — the chip then sends to `--to <handle>@greprag.com/<parent-project>` (project broadcast, intentional) and the parent watches `--project <parent-project>` (no `--session`). Less precise, still correct — both sides have to be project-scoped for the loop to close.
|
|
63
63
|
|
|
64
64
|
Path convention: `<project>/.claude/worktrees/<slug>/` — same parent directory Claude Code Desktop uses for IDE-checkbox worktrees. One place to look for any active Claude worktree. Branch prefix `chip/` distinguishes agent-spawned from IDE-spawned (`claude/<auto-name>`), so `git branch` output shows provenance at a glance. `/clean-worktrees` skill cleans both.
|
|
65
65
|
|
|
@@ -67,6 +67,8 @@ Path convention: `<project>/.claude/worktrees/<slug>/` — same parent directory
|
|
|
67
67
|
|
|
68
68
|
**Chip cleanup discipline (HARD RULE — every chip prompt must enforce this).** Chips **commit and exit**. They do NOT run `git clean -fd`, `git reset --hard`, `git worktree remove` (any target), `git checkout <other-branch>`, raw `rm -rf` of directories, or any destructive shell command outside their own worktree's tracked files. If a chip needs to delete a file it created, use `git rm` and commit the deletion — never raw `rm`. The parent session owns post-merge worktree cleanup; chips never reach for it themselves. This rule exists because parallel worktrees share `.git`, a poorly-scoped cleanup command can wipe another worktree's working tree, and the main checkout has been observed to lose `packages/*/src/` files in this exact pattern. Spawning agents: include "Chip cleanup discipline" verbatim in Block 1 of every chip prompt.
|
|
69
69
|
|
|
70
|
+
**`npm link` discipline.** If a chip needs to smoke-test a CLI build globally, run `npm link` from the main checkout's package dir (`cd <main>/packages/<pkg> && npm link`), NOT from the worktree. Linking from the worktree registers a global symlink that points INTO the worktree; after `git worktree remove` runs in /commit's Phase 4, the symlink dangles and the CLI breaks system-wide until reinstalled. The /commit skill's `guard-npm-links.sh` auto-recovers (re-points at main or unlinks), but the cleanest path is to never create the worktree-pointed symlink in the first place.
|
|
71
|
+
|
|
70
72
|
### Block 2 — Report back via greprag inbox (append to prompt)
|
|
71
73
|
|
|
72
74
|
```
|
|
@@ -74,21 +76,20 @@ Path convention: `<project>/.claude/worktrees/<slug>/` — same parent directory
|
|
|
74
76
|
|
|
75
77
|
```bash
|
|
76
78
|
greprag send "<status>: <commit hash> on chip/<slug> — <one-line>" \
|
|
77
|
-
--to <your-tenant-
|
|
78
|
-
--session <parent-session-id> \
|
|
79
|
+
--to <your-tenant-handle>@greprag.com/<parent-session-id> \
|
|
79
80
|
--from-session <own-session-id> \
|
|
80
81
|
--artifact commit:<hash> \
|
|
81
82
|
--file <key-file-path>
|
|
82
83
|
```
|
|
83
84
|
|
|
84
85
|
- `<status>`: `done` | `blocked` | `partial`
|
|
85
|
-
- `<
|
|
86
|
-
- `<parent-session-id>`: filled in by the spawning session in Block 1 of this prompt.
|
|
86
|
+
- `<your-tenant-handle>`: parent's `@greprag.com` handle (e.g. `1834729` or a claimed alias like `travis`).
|
|
87
|
+
- `<parent-session-id>`: filled in by the spawning session in Block 1 of this prompt. The full UUID or 8-hex short form both work. This trailing segment IS the target — only the parent's session-scoped watcher receives the message.
|
|
87
88
|
- `<own-session-id>`: this chip's own session UUID. Denormalized onto the message so the parent can address replies back without re-discovering the chip's identity.
|
|
88
89
|
- Body ≤280 chars where possible. If blocked, name the blocker explicitly.
|
|
89
90
|
- Use `--artifact` and `--file` flags to back-reference the actual work (see `/greprag` skill).
|
|
90
91
|
|
|
91
|
-
If `<parent-session-id>` is unknown (parent didn't pass one),
|
|
92
|
+
If `<parent-session-id>` is unknown (parent didn't pass one), send to the parent's project instead: `--to <handle>@greprag.com/<parent-project>` (no session suffix). That's an intentional project broadcast — every watcher in `<parent-project>` receives it, including the parent. Use sparingly; session-targeting is the default. adr: adr/address-grammar.md
|
|
92
93
|
|
|
93
94
|
Send the report BEFORE exiting. The parent agent reads `greprag inbox` on its next turn and picks it up — no polling, no manual chasing.
|
|
94
95
|
```
|
|
@@ -98,33 +99,38 @@ Send the report BEFORE exiting. The parent agent reads `greprag inbox` on its ne
|
|
|
98
99
|
```
|
|
99
100
|
**After sending the done report, stay reachable for follow-ups:**
|
|
100
101
|
|
|
101
|
-
Arm a `Monitor` on your own inbox so any directive from main lands as an in-session event. Run this under the **`Monitor`** tool with `persistent: true`:
|
|
102
|
+
Arm a `Monitor` on your own inbox so any directive from main lands as an in-session event. Use the bash-wrapper form — the `while` loop auto-restarts the watcher if the inner SSE process dies (network blip, crash, fork failure). Run this under the **`Monitor`** tool with `persistent: true`:
|
|
102
103
|
|
|
103
104
|
```bash
|
|
104
|
-
greprag inbox watch --session <own-session-id> --json
|
|
105
|
+
while true; do greprag inbox watch --session <own-session-id> --json; echo "[wrapper] watcher exited, restarting in 1s" >&2; sleep 1; done
|
|
105
106
|
```
|
|
106
107
|
|
|
107
108
|
- `<own-session-id>` is the chip's own session UUID — same one passed as `--from-session` in Block 2. The filter narrows the stream to messages aimed at this exact session plus broadcasts; sibling chips watching the same project no longer pollute this feed.
|
|
108
|
-
- If you don't have a session id (older sessions),
|
|
109
|
+
- If you don't have a session id (older sessions), substitute `--project <own-project>` instead of `--session <id>` — wider net but still correct.
|
|
109
110
|
- The chip then idles between events — no token burn, no polling. Each new inbox line = one notification.
|
|
111
|
+
- Restart events go to stderr as `[wrapper] watcher exited…` — visible in the Monitor output file but not as a Monitor notification.
|
|
110
112
|
- When the work is truly done and no follow-up is expected, call `TaskStop` on the Monitor task. Otherwise leave it armed until the session closes.
|
|
113
|
+
- Do NOT drop the `while … done` wrapper. A bare `greprag inbox watch …` will silently end the Monitor task on any inner crash, and any directive sent in the gap is lost until the next user prompt.
|
|
111
114
|
```
|
|
112
115
|
|
|
113
116
|
**Why not the Stop hook?** 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.
|
|
114
117
|
|
|
115
118
|
## Reply listening (any session, not just chips)
|
|
116
119
|
|
|
117
|
-
The chip Block 3 pattern generalizes. Any session that sends a message expecting a directive in response should arm a Monitor on its own inbox in the same turn — before the send if you can, so a fast reply doesn't slip past. Use
|
|
120
|
+
The chip Block 3 pattern generalizes. Any session that sends a message expecting a directive in response should arm a Monitor on its own inbox in the same turn — before the send if you can, so a fast reply doesn't slip past. Use the same bash-wrapper form shown in Block 3 (substitute `--project <own-project>` when no session identity is available), `persistent: true`. Same reasoning: the Stop hook is best-effort for session-end ingestion; Monitor is the only path that catches mid-task replies.
|
|
118
121
|
|
|
119
|
-
**Session scoping
|
|
122
|
+
**Session scoping is the default in v0.11.** The send-side address grammar — `<handle>@greprag.com/<session-uuid>` — makes the session the only segment, so messages land in exactly one inbox. Project-name addresses (`<handle>@greprag.com/<project>`) are intentional broadcasts, used only when the sender genuinely means "everyone in this project should hear this." A `--session` watcher still passes broadcasts through (by design, so tenant-wide announcements aren't lost), but with session-targeting as the dominant pattern those broadcasts are now rare and recognizable.
|
|
120
123
|
|
|
121
124
|
## Parent-side: watch for the report
|
|
122
125
|
|
|
123
126
|
If you want the chip's report the instant it lands (not on next turn), start an SSE watcher in the background BEFORE spawning the chip:
|
|
124
127
|
|
|
125
128
|
```bash
|
|
126
|
-
|
|
127
|
-
greprag inbox watch --
|
|
129
|
+
# preferred — single chip (bash wrapper auto-restarts on inner death)
|
|
130
|
+
while true; do greprag inbox watch --session <parent-session-id> --json; echo "[wrapper] watcher exited, restarting in 1s" >&2; sleep 1; done
|
|
131
|
+
|
|
132
|
+
# fallback / multi-chip campaigns
|
|
133
|
+
while true; do greprag inbox watch --project <parent-project>; echo "[wrapper] watcher exited, restarting in 1s" >&2; sleep 1; done
|
|
128
134
|
```
|
|
129
135
|
|
|
130
136
|
`--session` is the right default when the chip's Block 2 sends with `--session <parent-session-id>` — exactly one report lands in this watcher per chip. Use `--project` when you've spawned several chips at once and want all their reports on one stream (each chip still tags `--from-session <own-id>`, so the parent reads provenance per message).
|
|
@@ -183,7 +189,7 @@ Chip continues
|
|
|
183
189
|
|
|
184
190
|
**Communication channels:**
|
|
185
191
|
|
|
186
|
-
- Main ↔ chip: greprag inbox (`<
|
|
192
|
+
- Main ↔ chip: greprag inbox (`<handle>@greprag.com/<parent-session-id>` ↔ `<handle>@greprag.com/<chip-session-id>`, falling back to `/<project>` only when a session id is unknown).
|
|
187
193
|
- Chip ↔ subagent: direct return value from the `Agent` tool (no inbox needed — same session).
|
|
188
194
|
|
|
189
195
|
Skip the layering when one Agent call would do — direct dispatch from main is simpler.
|
|
@@ -216,9 +222,10 @@ The chip lands NOT to ship code, but to be a context-rich conversation partner f
|
|
|
216
222
|
|
|
217
223
|
**Why this beats arguing in main:** orchestrator runs on what it can grep + read in-context. Anything beyond that is plausible-sounding extrapolation. A chip with the repo loaded catches "this coupling exists" / "this billing dependency is non-obvious" / "you missed a callsite" — corrections the orchestrator can't surface itself.
|
|
218
224
|
|
|
219
|
-
### Picking the slug, model, and subagent_type
|
|
225
|
+
### Picking the title, slug, model, and subagent_type
|
|
220
226
|
|
|
221
|
-
- **
|
|
227
|
+
- **Title** — ALWAYS prefix with `Chip: ` then the imperative action phrase. Format: `Chip: <verb-phrase>` (e.g. `Chip: Fix stale README badge`, `Chip: Wire Narrow C into core`, `Chip: GR5 collapse style prompts`). The `Chip: ` prefix is non-negotiable — it makes chip-spawned sessions instantly recognizable in the FleetView UI vs. IDE-checkbox-spawned `claude/` sessions and human-driven sessions. The verb phrase MUST NOT itself repeat "chip" — the prefix already marks it as one. Imperative verb phrase under ~50 chars after the prefix.
|
|
228
|
+
- **Slug** — kebab-case, short, matches the post-prefix portion of the title. Becomes the worktree branch name (`chip/<slug>`) and the worktree directory (`<project>/.claude/worktrees/<slug>/`).
|
|
222
229
|
- **Model at the chip layer** — defaults to whatever the FleetView/CCD runtime assigns (currently Opus). `spawn_task` has no model param.
|
|
223
230
|
- **Model at the subagent layer** — pass `model: "sonnet"`/`"haiku"`/`"opus"` to the `Agent` tool. Default to the cheapest that fits the task.
|
|
224
231
|
- **subagent_type** — `Explore` for read-only search, `Plan` for design work, `general-purpose` for execution, `code-reviewer` (if installed) for second opinion. Full list in the `Agent` tool description.
|
|
@@ -238,7 +245,7 @@ The chip lands NOT to ship code, but to be a context-rich conversation partner f
|
|
|
238
245
|
|
|
239
246
|
- **Block 0 — Pre-spawn checklist.** Auto-fill parent-project name, generate slug from title, dry-run the worktree path for collisions. Reduces the boilerplate the spawning agent has to compose by hand.
|
|
240
247
|
|
|
241
|
-
**Shipped:** session-scoped routing
|
|
248
|
+
**Shipped:** session-scoped routing via the single-segment address grammar `<handle>@greprag.com/<target>` where `<target>` is a session UUID (normal) or a project name (intentional broadcast). v0.11 dropped the legacy `--session`/`--project` send flags and the 3-segment `email/project/session` address — the address itself now carries the target, so missing-target sends error loudly instead of silently broadcasting. adr: adr/address-grammar.md
|
|
242
249
|
|
|
243
250
|
## See also
|
|
244
251
|
|