replen 1.0.34 → 1.0.36

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.js CHANGED
@@ -534,19 +534,26 @@ async function fetchInventoryStatus(cfg, repo) {
534
534
  return null;
535
535
  const data = (await res.json());
536
536
  const cands = data.candidates ?? [];
537
- if (cands.length === 0)
537
+ const displayText = (typeof data.displayText === "string" && data.displayText) ? data.displayText : null;
538
+ // Surface even with ZERO candidates when the server sent a displayText —
539
+ // notably the onboard-on-first-visit offer for a registered-but-unprofiled
540
+ // repo (needsOnboarding): it has no candidates yet but IS the line to relay.
541
+ // Previously `cands.length === 0 → return null` swallowed it, so the
542
+ // SessionStart hook stayed silent on unprofiled repos.
543
+ if (cands.length === 0 && !displayText)
538
544
  return null;
539
545
  const top = cands[0];
540
546
  // Pull the cosine % out of whyShortlisted if present
541
547
  // (format: "...; semantic similarity: 58%").
542
- const simMatch = top.whyShortlisted?.match(/semantic similarity:\s*(\d+)%/);
548
+ const simMatch = top?.whyShortlisted?.match(/semantic similarity:\s*(\d+)%/);
543
549
  return {
544
550
  count: cands.length,
545
- topRepo: top.repo ?? null,
551
+ topRepo: top?.repo ?? null,
546
552
  topSimilarity: simMatch ? Number(simMatch[1]) : null,
547
553
  // The server's pre-formatted, pattern-aware footnote ("By the way — a
548
- // dependency you use just shipped: …" / "… N candidates queued …").
549
- displayText: (typeof data.displayText === "string" && data.displayText) ? data.displayText : null,
554
+ // dependency you use just shipped: …" / "… N candidates queued …" / the
555
+ // onboard offer).
556
+ displayText,
550
557
  };
551
558
  }
552
559
  catch {
@@ -5,14 +5,11 @@ description: Review Replen's suggestions for the current repo against your code.
5
5
 
6
6
  # Replen Match — in-session candidate triage
7
7
 
8
- You are running **Brainstem**'s matching loop locally. **Watchtower** Replen's
9
- maintained network of ~1,250 sources (vendor changelogs, advisories, pricing
10
- pages, release feeds, standards trackers, EOL calendars) fetched the raw
11
- events; **Brainstem** scored them against this codebase's capabilities; you've
12
- got the user's codebase open and make the final call. Verdicts you record land
13
- in **Atlas** and tune Brainstem's ranking for every future session.
14
- Your job is to decide which (if any) are worth their attention, write up the
15
- strong ones, and capture what they want to do about them.
8
+ You are running the matching loop locally. Replen has fetched a list of
9
+ plausible OSS candidates from the wider ecosystem; you've got the user's
10
+ codebase open. Your job is to decide which (if any) are worth their
11
+ attention, write up the strong ones, and capture what they want to do
12
+ about them.
16
13
 
17
14
  **This runs entirely on the user's subscription tokens.** No API keys
18
15
  get used. Replen's hosted side did the cheap structural filtering; you
@@ -43,85 +40,7 @@ Parse the JSON response. Note:
43
40
 
44
41
  - `filterMode` — `tags`, `zero-knowledge`, or `fingerprint`
45
42
  - `scopedTo` — confirms the project context the user has open
46
- - `projectThesis` — what this project is trying to BE (`purpose`) and where it's
47
- heading (`goals`). **This is your primary relevance lens.** Judge every
48
- candidate against the mission, not just the capability match: a library can fit
49
- a tech slot and still NOT advance what the product is trying to be (a generic
50
- charting lib for a decision-support platform), and a candidate that advances a
51
- `goal` is worth surfacing even if it doesn't map to an existing capability.
52
- Lead your writeups with mission-fit, not just tech-fit. (Null until the project
53
- is onboarded with a thesis — then fall back to capability-fit alone.)
54
- - `keystoneUpgrades` — task-scoped `better_than` upgrades for solutions this
55
- project already uses (from Keystone, the comparative-knowledge ontology): each
56
- is `{current, better, betterKind, task, margin, source}`. A deprecated/inferior
57
- dependency has a maintained/stronger replacement. The footnote may surface one;
58
- if the user wants it, DO the swap (update the dep, adjust call sites). Always
59
- cite the `task` — "better" is task-relative (e.g. text-embedding-3-large beats
60
- 3-small for general retrieval but NOT for short-label matching). Don't push an
61
- upgrade the user didn't ask about beyond the one calm line.
62
43
  - `candidates[]` — the actual list to triage
63
- - `candidates[].priorContext` — server-attached MEMORY: the user's earlier
64
- verdicts on this repo, and whether the matched capability is already
65
- covered by something they adopted/ported. Trust it — fold it into your
66
- verdict instead of re-deriving history, and don't push a candidate whose
67
- capability is covered unless it's materially better than the incumbent.
68
- - `candidates[].source === "re-checked"` — a repo the user DEFERRED months
69
- ago that is still actively developed. Re-evaluate it against today's
70
- state of the project; the original "not now" note is in `priorContext`.
71
- - `leap` — on quiet days the response may carry ONE portfolio connection
72
- (a cross-project / adjacency / cross-user leap) instead of candidates.
73
- `displayText` already words it; relay that and offer to explore it.
74
- - `queuedActions` — work the user queued from their weekly brief / alert
75
- emails (or a past session). The footnote offers the oldest one; if the
76
- user says yes, DO the work (bump the dep, handle the deprecation,
77
- evaluate the repo), then call `replen_queue` with `action: "done"` and
78
- the item's id. If they decline for good, `action: "dismiss"`. Never
79
- leave a handled item queued — it will keep reminding.
80
- - `candidates[].alternatives` — on health/security stakes ("your upstream
81
- is dying / has a CVE"), maintained catalogue libraries similar to the
82
- flagged repo, with cross-user adoption counts. Use them in the writeup:
83
- the verdict isn't just "X is risky" but "X is risky; Y is the maintained
84
- replacement, N similar projects adopted it".
85
-
86
- ### Step 2a — JIT grounding: profile this repo if onboarding hasn't yet
87
-
88
- A large-portfolio `/replen-onboard` grounds the most-active repos fully and
89
- gives the long tail a cheap version-only pass — so a registered repo can have
90
- versions but **no capability profile yet**. Triaging it would fall back to
91
- coarse tag matching (you'll see `filterMode: "tags"` and few/no facet-led
92
- candidates). When that happens, ground it inline FIRST — it's just-in-time
93
- onboarding, and it's why the user opening this repo is the right moment:
94
-
95
- 1. Confirm the gap: call `replen_onboard_state` and find this repo — if
96
- `hasCapabilities` is false, it needs grounding.
97
- 2. Run the grounding contract (same as `/replen-onboard` step 2a–2e, condensed):
98
- read the code, derive 8–15 grounded `{tag, descriptor, modality, paths}`
99
- capabilities + a technical report, and push via `replen_set_capabilities`
100
- (+ `replen_set_tags`, + `replen_set_versions` if not already reported).
101
- Respect the cover — describe the tech, never de-sanitize the application.
102
- 3. Re-pull the inventory (Step 2) — now it returns real facet-led matches.
103
-
104
- Skip this when `hasCapabilities` is already true (the common case). One quiet
105
- line to the user is enough: *"This repo wasn't fully profiled yet — grounding
106
- it now so the matches actually fit."*
107
-
108
- ### Step 2b — Keep the version picture fresh (cheap, do it)
109
-
110
- If `git status` shows the lockfile changed since you last reported, or you
111
- have never reported for this repo, call `replen_set_versions` with the
112
- resolved DIRECT dependency versions from the lockfile (package-lock.json /
113
- poetry.lock / uv.lock / Cargo.lock) plus runtimes under canonical keys
114
- (`node` from .nvmrc/engines/Dockerfile, `python` from .python-version /
115
- requires-python, `postgres`/`redis` when pinned in docker-compose). Names
116
- and versions ONLY — never code. This is what turns Replen's deadline and
117
- security lines from "worth checking your pins" into "affects `aegis`
118
- (3.10.12)" — and silences alarms for versions this repo verifiably isn't on.
119
-
120
- This step is NOT optional, and not only about deadlines: the reported
121
- names are also the matcher's "already a dependency" exclusion list. A
122
- repo that never reports versions WILL get its own dependencies suggested
123
- back to it as candidates (fastapi pinned in requirements.txt, fastapi in
124
- the shortlist) — a shipped failure this step prevents.
125
44
 
126
45
  If `candidates.length === 0`, tell the user "No new candidates today for
127
46
  `<owner/name>`. Calm-cadence working as designed — 1-3 actionable
@@ -151,50 +70,54 @@ For each candidate, do this loop:
151
70
  (e.g. `grep -rln "Canvas\|imageRenderer\|OG"` under `lib/` and `src/`).
152
71
  - If you find one, read the file to understand what the user has built.
153
72
 
154
- #### 3b. Form a verdict
155
-
156
- You're answering: **is this worth the user's attention right now?**
157
-
158
- Verdicts:
159
-
160
- - **adopt** — drop-in replacement / direct dep. The candidate does
161
- something the user genuinely needs and isn't doing well. Wire up.
162
- - **port** the candidate has an idea / pattern / algorithm worth
163
- copying, but the candidate's runtime / language / license is
164
- mismatched. Worth reading + adapting; not worth depending on.
165
- - **skip**the candidate is a worse version of what the user has, the
166
- candidate's runtime is incompatible, or the candidate's not actively
167
- maintained. Honest skips are valuable signal; don't manufacture
168
- reasons to keep something.
169
- - **defer** — genuinely interesting but not NOW (too early / v0.x churn /
170
- blocked on a milestone the project hasn't hit). Defer is a real promise,
171
- not a soft skip: Replen automatically re-surfaces a deferred repo after
172
- ~3 months if it's still actively developed (`source: "re-checked"`).
173
-
174
- **Watch for word-collisions** the most common bad match. The candidate
175
- shares a *word* with the matched capability but its real domain diverges:
176
- the matched facet is "anomaly detection" (the user's is drone TELEMETRY) but
177
- the candidate does IMAGE anomaly detection; "recommendation" means remediation
178
- actions for the user but collaborative-filtering for the candidate; "S3" means
179
- private IAM-managed storage but the candidate scans PUBLIC buckets. These are
180
- skips and worth recording precisely (see Step 4) so Replen stops surfacing
181
- the pairing. Classify the reason: `modality-collision` (different data type),
182
- `task-collision` (same data, different task), `wrong-posture` (e.g. defensive
183
- vs offensive), `covered` (already have it), `low-quality` (workshop/abandoned).
184
-
185
- Score the fit on a 0-100 scale:
186
-
187
- - 80-100 = high (strong fit, clear adopt or port path, no major blockers)
188
- - 50-79 = medium (real value, but caveats — port path required, or
189
- partial overlap, or active-area-mismatched)
190
- - 0-49 = general-awareness or skip (interesting but not directly
191
- actionable; or definitely skip)
192
-
193
- Estimate effort:
194
-
195
- - **quick** <1 day. Single-file swap, drop a dep, copy a file.
196
- - **moderate** 1-3 days. Real API delta, multi-site update, light port.
197
- - **deep** 1+ week. Framework adoption, paradigm shift, full rewrite.
73
+ #### 3b. The four-pass funnel — run ALL FOUR, in order, even after a "no"
74
+
75
+ "Does this fit my repo?" is too narrow: it terminates on the first "no" and
76
+ throws away the lateral value. Evaluating Graphify for Replen was a *skip* on
77
+ direct use — yet it produced Atlas (a borrowed premise) **and** a boundary ("we
78
+ are not Graphify"). The binary question would have lost both.
79
+
80
+ So run **four passes per candidate, in order. Do NOT stop at the first "no"** —
81
+ a skip in Pass 1 does not end the inquiry. Passes 1–2 yield a sourcing
82
+ **verdict**; Passes 3–4 yield optional **insights**.
83
+
84
+ **Pass 1 Direct use.** Could we use their code (we lack this, or do it worse)?
85
+ - **adopt** (use-as-is) drop-in dependency we genuinely need.
86
+ - **port** reimplement their idea/algorithm; runtime/language mismatched.
87
+ - **cherry-pick** lift one specific file / function / technique, not the whole thing.
88
+ - **clean-room** — the premise is strong; rebuild it ourselves from the idea, not the code.
89
+ - *(none apply continue to Pass 2; do NOT record `skip` yet.)*
90
+
91
+ **Pass 2 Better-than-ours.** Do we **already** do this — and do they do it
92
+ **concretely better**? Read *our* implementation (grep + open the actual file)
93
+ and compare honestly. If they beat us with a *specific, nameable* technique:
94
+ - **upgrade** set `matchedFacet` to the capability they improve; in the writeup
95
+ name exactly what's better and how to get it (adopt their lib / port the
96
+ technique / cherry-pick the algo).
97
+ - Examples: "their scraper defeats Cloudflare via TLS-fingerprint rotation; ours
98
+ retries naively"; "they triangulate drone detection across video **and** audio;
99
+ we rely on a single video feed."
100
+ - This flips a `covered` capability from skip → surface. **Bar: a concrete,
101
+ named superiority never "theirs also looks good."**
102
+ - *(If neither Pass 1 nor Pass 2 applies → NOW it's a `skip`, with a reasonCode.
103
+ Still run Passes 3–4.)*
104
+
105
+ **Pass 3 — Transferable idea / premise / way-of-working.** Regardless of whether
106
+ we'd touch their code: is there an idea, premise, or pattern worth keeping? The
107
+ Graphify→Atlas lane. If yes `replen_capture_insight` with kind **`lesson`**.
108
+
109
+ **Pass 4 Boundary.** Does seeing this sharpen what we are explicitly **NOT**?
110
+ ("Atlas models decisions, not files — we are not a code-graph tool.") If yes →
111
+ `replen_capture_insight` with kind **`boundary`**.
112
+
113
+ **Quality bar for Passes 3–4:** they *run* on every candidate but *record*
114
+ rarelyonly a **decision-changing**, Graphify-grade insight, the kind that
115
+ would actually have changed a plan. Most candidates produce no insight. A
116
+ tenuous "you could maybe learn X" is noise do not record it.
117
+
118
+ Then score the sourcing verdict 0-100 (80-100 strong / 50-79 real-with-caveats /
119
+ 0-49 weak-or-skip) and estimate effort: **quick** (<1d) / **moderate** (1-3d) /
120
+ **deep** (1+w).
198
121
 
199
122
  #### 3c. Compose the writeup
200
123
 
@@ -221,62 +144,64 @@ that means here.
221
144
  mismatch, security flag. Empty list is fine; don't manufacture.
222
145
  ```
223
146
 
224
- #### 3d. Record the verdict NOW — don't wait for the user
225
-
226
- As soon as a candidate's verdict is formed, call `replen_record_triage`
227
- for it — **before** you present the batch, and **without asking**.
228
- Recording is observation, not action: it captures what you concluded
229
- (verdict, score, reason code, one-liner, cosine) so the learning loop and
230
- re-surfacing suppression actually fire. It is non-destructive and doesn't
231
- foreclose anything — the user's star / hide / handoff choices in Step 4
232
- are a separate axis layered on top.
233
-
234
- The failure mode this rule exists to kill: a session triages four
235
- candidates, presents them, ends with "want me to record these?", the
236
- user moves on — and Replen learned NOTHING. The same four will come back.
237
- A triage that isn't recorded never happened.
238
-
239
- Only the user-judgment actions (star / hide / handoff / queue work) wait
240
- for the user. Verdicts never do.
241
-
242
- #### 3e. Write back what you LEARNED from the code — not just the verdict
243
-
244
- Triage is the one moment you actually read the source, so feed what you
245
- learned back into Replen's model of the project (it's non-destructive and
246
- makes every future match sharper). Two cheap write-backs, both optional,
247
- both additive:
248
-
249
- - **Capability paths.** When you confirm which file(s) implement the
250
- capability a candidate matched — especially if the candidate's
251
- `matchedFacet` has no paths yet — call `replen_set_capabilities` with
252
- **`mode:"merge"`** and just that one capability:
253
- `{ tag: "<matchedFacet>", paths: ["src/…", "lib/…"] }`. Merge mode adds
254
- the paths without touching the project's other capabilities. This is what
255
- makes "port THIS exact file" possible in later sessions and populates the
256
- Atlas dossier + cross-project leaps. Paths only, never code.
257
- - **Dep corrections.** When the code shows a listed dependency is unused or
258
- superseded (e.g. a stale `ethers` in a repo that's actually on `viem`),
259
- pass `depsSuperseded: ["ethers"]` on the `replen_record_triage` call —
260
- it's marked migrate-off (reversible) so its release/pricing/upgrade noise
261
- stops. Pass `depsConfirmed: [...]` for deps you verified are genuinely
262
- used that Replen didn't already know. Names only.
263
-
264
147
  No marketing voice. No hype. The user is a working engineer; talk to
265
148
  them like a peer. Concrete > clever.
266
149
 
150
+ #### 3d. Record the verdict
151
+
152
+ **After each candidate's writeup**, call the `replen_record_triage` MCP
153
+ tool with the structured verdict so it surfaces on the user's Activity
154
+ feed at the dashboard. Use the same `sessionId` (any opaque string,
155
+ e.g. timestamp `2026-05-26T10-32`) across every call in this session
156
+ so the feed can cluster them as one triage run.
157
+
158
+ ```
159
+ mcp__replen__replen_record_triage(
160
+ repo="owner/name",
161
+ project="tech-news-site", // slug, from scopedTo
162
+ verdict="adopt", // adopt|port|cherry-pick|clean-room|upgrade|skip|defer
163
+ matchedFacet="og image", // REQUIRED for upgrade: the capability they do better
164
+ score=87, // 0-100
165
+ effortBand="quick", // quick|moderate|deep
166
+ oneLine="Drops in for lib/social/imageRenderer.ts — 30 min.",
167
+ writeup="<full markdown body of the writeup you just composed>",
168
+ sessionId="2026-05-26T10-32"
169
+ )
170
+ ```
171
+
172
+ This call is what makes the agent's work visible. Without it, the user
173
+ only sees their own actions (star / hide) — they can't see "the agent
174
+ considered 5 candidates this morning and skipped 4 of them, here's
175
+ why." Record one event per candidate, including skips.
176
+
177
+ **Pass 3/4 insights are recorded separately** — with `replen_capture_insight`,
178
+ NOT `replen_record_triage` (an insight is a portfolio decision, not a candidate
179
+ verdict). Only when genuinely decision-changing (most candidates produce none):
180
+
181
+ ```
182
+ mcp__replen__replen_capture_insight(
183
+ kind="lesson", // lesson | boundary
184
+ text="Borrow Graphify's graph-as-memory premise, but link repos not files (→ Atlas).",
185
+ viaCandidate="owner/name", // the candidate that prompted it
186
+ project="atlas" // optional; omit for a portfolio-wide insight
187
+ )
188
+ ```
189
+
267
190
  ### Step 4 — Present + capture actions
268
191
 
269
- By this point every verdict is ALREADY recorded (3d). After all
270
- writeups, summarise, and ask only about the actions that genuinely need
271
- the user's call — skips need nothing further:
192
+ After all writeups, summarise:
272
193
 
273
194
  ```
274
- 3 candidates triaged for tech-news-site (all verdicts recorded):
275
- ✓ adopt: kribblo/node-ffmpeg-installer (high · quick) — ffmpeg-static swap
276
- ⏭ port: tj/n (medium · moderate) — version-manager pattern
277
- skip: vercel/turbo (medium · deep) — wrong runtime, already have Vite
195
+ 4 candidates triaged for tech-news-site:
196
+ ✓ adopt: kribblo/node-ffmpeg-installer (high · quick) — ffmpeg-static swap
197
+ ⏭ port: tj/n (medium · moderate) — version-manager pattern
198
+ upgrade: someorg/fast-og (high · moderate) — beats our og-image render (streams + caches vs our sync redraw)
199
+ ✗ skip: vercel/turbo (deep) — wrong runtime, already on Vite
200
+
201
+ 💡 lesson (via graphify/graphify): borrow graph-as-memory premise, link repos not files (→ Atlas)
202
+ — captured to Atlas; shown only when a Pass-3/4 insight actually fired
278
203
 
279
- Want the adopt wired up, or any of these starred / hidden / handed off?
204
+ For each verdict, what would you like to do? (star / hide / handoff / skip)
280
205
  ```
281
206
 
282
207
  Then, for each candidate, capture the user's choice. For each action,
@@ -319,107 +244,11 @@ fresh candidate shows up at session start via the hook).
319
244
  **Inventory call returns 401.** User's token expired or got rotated.
320
245
  Tell them to run `npx replen` to re-auth.
321
246
 
322
- **The project isn't scoped — `scopedTo: null`, a `note` about "repo not in
323
- your project list", OR the cwd has no git remote.** Replen can only match
324
- against a repo it has registered, and it scopes by the git remote. When it's
325
- unscoped you'll get the global trending firehose which is noise for this
326
- codebase. **Do NOT triage the firehose** (manufacturing reasons to care about
327
- random trending repos is exactly what this skill must not do).
328
-
329
- Instead, **offer to onboard the project.** Lead with ONE line, not the whole
330
- checklist: *"This project isn't set up with Replen yet, so I can only see the
331
- global firehose (not matches for your code). Want me to scope it — init git,
332
- create the repo, write the docs, and add tags? Then Replen can surface things
333
- that actually fit."* If the user agrees, run this checklist:
334
-
335
- 1. **Git + GitHub.** If there's no git repo, `git init`. Create the GitHub
336
- repo using the user's existing `gh` auth — ask for owner/name or suggest a
337
- sensible default from the folder name, and confirm public vs private:
338
- `gh repo create <owner>/<name> --private --source=. --remote=origin --push`.
339
- If a repo exists locally but has no remote, just add + push the remote.
340
- 2. **Docs Replen can read.** Replen's scorer reads your `README.md` +
341
- `CLAUDE.md` to understand the project — that's the difference between
342
- useful matches and noise. Write a concrete `README.md` (what it is, stack,
343
- domain) if missing, and a `CLAUDE.md` optimised for Replen (run the
344
- `/replen-project-init` protocol, or draft the seven sections directly:
345
- what it is · stack · niche/domain · active areas · constraints/non-goals ·
346
- anti-patterns · integration preferences). Use the project's real domain
347
- vocabulary, not abstractions.
348
- 3. **Register + tag + set capabilities.** Register the repo: `npx replen
349
- sync-projects` (scans the local repos and pushes them to Replen). Then, from
350
- the code you just read:
351
- - **Set domain tags** with `replen_set_tags` — broad domain labels (e.g. for
352
- a Python CCXT market-making engine:
353
- `["crypto","trading","market-making","ccxt","quant","backtesting"]`).
354
- - **Set technical capabilities** with `replen_set_capabilities` — short,
355
- GitHub-searchable tech terms for what the project DOES at the tech level.
356
- Aim for **8-15** and be **SPECIFIC**. **Send GROUNDED objects, not bare
357
- strings** — `{tag, descriptor, modality}` for each capability:
358
- - `tag` — the short searchable term (`"anomaly detection"`).
359
- - `descriptor` — ONE sentence grounding the tag in the ACTUAL CODE you
360
- just read: what DATA it operates on, the specific task, key constraints.
361
- This is what stops word-collisions. `"anomaly detection"` alone collides
362
- with image-defect libraries; `{tag:"anomaly detection", descriptor:
363
- "rule-based detection over drone telemetry time-series — link-loss,
364
- GPS-drop, battery-sag; no ML", modality:["timeseries"]}` does not.
365
- Read the real source (the taxonomy/model/config files), not the README.
366
- - `modality` — array from EXACTLY: `image, video, timeseries, tabular,
367
- text, audio, geospatial, graph, 3d, code, network` (`[]` if none apply).
368
- A satellite-imagery segmenter is `["image","geospatial"]`; a recsys is
369
- `["tabular"]`.
370
-
371
- Break broad capabilities into the concrete techniques the code uses (not
372
- just `"web scraping"` but `headless browser`, `cloudflare bypass`,
373
- `proxy rotation`, …). Derive all of it from the imports/deps and code, not
374
- guesses. This is the highest-leverage step: the server builds the project's
375
- facet vectors from these IMMEDIATELY, and the grounded descriptor + modality
376
- are exactly what make matching separate "same word, different data" — the
377
- single biggest source of bad matches.
378
-
379
- **Do NOT tell the user to set tags/capabilities on the web** — that's the
380
- sticky step this replaces; set them with the tools. (They can fine-tune later
381
- at app.replen.dev/projects.) These matter most right after onboarding — they
382
- give a fresh project working query vectors before any server-side inference.
383
- 4. **Embed it now (don't wait for the daily run).** A freshly-registered
384
- project has no embedding yet, so matching falls back to language/tags only
385
- (noise) until the next scheduled run. Trigger an immediate run with the
386
- `replen_run` tool — it builds the project's summary + embedding + initial
387
- candidates from the README/CLAUDE.md you just pushed. It's async: poll
388
- `replen_status` until the phase reports inventory ready (~1–3 min). Tell the
389
- user it's processing.
390
- 5. **Re-run.** Once the run finishes, call `replen_match` again — now scoped
391
- AND embedded, matching against the real code (a dev-tool that only shared the
392
- project's language now scores low on cosine and gets floored out).
393
-
394
- Note on recording actions: always use the MCP tools — `replen_state` (star /
395
- hide / handoff), `replen_record_triage` (your verdict), `replen_set_tags` — for
396
- any write back to Replen. Don't hand-roll `curl` to the API for these; the MCP
397
- path is the intended mechanism and avoids tripping host permission classifiers
398
- on the candidate repo name in a curl payload.
399
-
400
- **Never record a bare verdict.** Every `replen_record_triage` call — including
401
- quick skips made outside this full protocol (e.g. from the session-start
402
- footnote) — must carry at least `oneLine` and `cosine`. A verdict with no
403
- reasoning shows up in the user's Atlas dossier and vault as "bare verdict —
404
- the agent recorded no reasoning", which is a bug report with your name on it.
405
-
406
- When you call `replen_record_triage`, **pass the contextual fields** so Replen
407
- learns: `matchedFacet` (copy the `matchedFacet` from the candidate's
408
- replen_match data), `facetModality` (the data modality of that capability —
409
- e.g. `"timeseries"`, `"image"`), `reasonCode` (`fit` / `modality-collision`
410
- / `task-collision` / `covered` / `wrong-posture` / `low-quality` / `other`),
411
- and `cosine` (copy the candidate's `cosine` value verbatim — paired with your
412
- verdict it calibrates the relevance floor for this project, and your
413
- adopt/skip pattern continuously tunes the ranking via the taste vector).
414
- A skip coded `modality-collision` teaches Replen that this repo fits a
415
- *different* modality — so it stays available for the right project but stops
416
- colliding with this one. A skip coded `covered` is the strongest signal you
417
- can send: it tells Replen the capability is **already built in this repo**, so
418
- it stops probing that facet entirely and won't surface a different tool for it
419
- next session. Use `covered` ONLY when you've confirmed the implementation in
420
- the code (e.g. the repo has its own `services/llm_client.py`), not just because
421
- a similar dependency exists — that's what makes "we already do this" stick to
422
- the capability instead of replaying every session against a new candidate.
247
+ **Inventory returns `scopedTo: null` with a `note` about "repo not in
248
+ your project list"**. The cwd isn't a known project. Ask the user:
249
+ "This repo isn't in your Replen projects yet. Add it via /projects?"
250
+ Then either stop or re-run with `?repo=` (empty) to see the global
251
+ firehose.
423
252
 
424
253
  **Candidate's README is unreachable (WebFetch 404)**. Note it in the
425
254
  writeup (`Caveats: README unreachable; verdict based on description
@@ -438,21 +267,6 @@ The user hasn't set up filter-mode B's tag list. Mention it once: "Heads
438
267
  up — you'd get sharper matches if you set project tags at /settings.
439
268
  Continuing with unfiltered for now."
440
269
 
441
- ## Atlas tiles — local memory for any agent
442
-
443
- Replen keeps an agent-readable markdown vault at `~/.replen/atlas/` — the
444
- user's whole portfolio as linked notes: every project and what it does,
445
- every capability (with how it's known: `grounded`/`extracted`/`inferred`),
446
- every past decision with its reason code, plus themes and blind spots.
447
- The MCP server refreshes it in the background (at most twice a day);
448
- `replen atlas` forces a rewrite.
449
-
450
- Use it whenever you need CROSS-PROJECT context: "what else does this user
451
- build?", "have we solved X in another repo?", "what did we decide about
452
- Y last quarter?". Start at `MAP.md`, or call `replen_recall` for a direct
453
- query. Reading the tiles beats re-deriving the portfolio from scratch —
454
- they're the memory layer, and they're already on disk.
455
-
456
270
  ## When NOT to run this skill
457
271
 
458
272
  - The user is mid-task and just wants help with the current thing. The
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replen",
3
- "version": "1.0.34",
3
+ "version": "1.0.36",
4
4
  "description": "Make your AI coding tools smarter. One command, no API keys, free. Replen watches what your projects actually do and surfaces a few things worth bringing in each month. Use one as is, port a piece of another, cherry pick an idea, or build it clean room. The match happens inside your AI tool's session. A few actionable matches a month, by design.",
5
5
  "type": "module",
6
6
  "bin": {