replen 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -2
- package/dist/commands.js +22 -0
- package/dist/mcp-setup.js +22 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
# replen
|
|
2
2
|
|
|
3
|
-
**Make your AI coding tools aware of
|
|
3
|
+
**Make your AI coding tools aware of everything your code depends on, implements, and builds on.** One command, no API keys.
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
npx replen
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
Claude Code, Codex, Cursor already know your code. Replen tells them what
|
|
9
|
+
Claude Code, Codex, Cursor already know your code. Replen tells them what's happening *outside* it. The match decision happens *inside your AI tool's session* on your subscription tokens. Your code stays on your laptop. Replen never sees it.
|
|
10
|
+
|
|
11
|
+
Four lenses, all surfaced the same calm way — quietly, in your AI tool's next reply, only when there's something real:
|
|
12
|
+
|
|
13
|
+
- **🔭 OSS repos** — a new library that replaces code you maintain, a pattern worth porting, a dead dep to swap.
|
|
14
|
+
- **📦 Your stack** — a release in a dependency you actually use (`next`, `openai`, `prisma`, `viem`, … matched against your manifest).
|
|
15
|
+
- **📜 Standards you implement** — EIP/ERC, TC39, and Chrome-deprecation changes matched to what your code touches.
|
|
16
|
+
- **🩺 Upstream health** — a dep gone stale/archived, a hot bug others hit in your deps, or an incident on a service you use.
|
|
17
|
+
|
|
18
|
+
One discipline throughout: **silence beats a weak match** — if nothing clears the bar, Replen says nothing.
|
|
10
19
|
|
|
11
20
|
## What `npx replen` does
|
|
12
21
|
|
package/dist/commands.js
CHANGED
|
@@ -196,6 +196,25 @@ export async function runCheckNew(argv) {
|
|
|
196
196
|
console.error("Not signed in. Run `npx replen` first.");
|
|
197
197
|
process.exit(1);
|
|
198
198
|
}
|
|
199
|
+
// Hook mode surfaces the repo-scoped SKILL inventory directly — the good data
|
|
200
|
+
// (semantic + dependency / spec / health matches, with the relevance floor +
|
|
201
|
+
// cool-off applied server-side), using the server's pre-formatted footnote.
|
|
202
|
+
// It deliberately skips the legacy hosted `check-new` below, which returns
|
|
203
|
+
// generic, un-scoped, high-star matches that aren't useful to skill-tier
|
|
204
|
+
// users. Output is injected into the agent's opening context by Claude Code's
|
|
205
|
+
// SessionStart-hook stdout injection; the framing nudges the agent to relay
|
|
206
|
+
// it verbatim (final surfacing is still the model's call).
|
|
207
|
+
if (hookMode && !json) {
|
|
208
|
+
const cwdRepo = await detectCwdRepo();
|
|
209
|
+
if (!cwdRepo)
|
|
210
|
+
return; // not in a GitHub repo with a remote — silent
|
|
211
|
+
const inv = await fetchInventoryStatus(cfg, cwdRepo);
|
|
212
|
+
if (inv?.displayText) {
|
|
213
|
+
console.log("[Replen] Relay the following line to the user, verbatim, as a footnote at the very end of your first reply:");
|
|
214
|
+
console.log(inv.displayText);
|
|
215
|
+
}
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
199
218
|
const query = {};
|
|
200
219
|
if (repo !== undefined)
|
|
201
220
|
query.repo = repo;
|
|
@@ -482,6 +501,9 @@ async function fetchInventoryStatus(cfg, repo) {
|
|
|
482
501
|
count: cands.length,
|
|
483
502
|
topRepo: top.repo ?? null,
|
|
484
503
|
topSimilarity: simMatch ? Number(simMatch[1]) : null,
|
|
504
|
+
// The server's pre-formatted, pattern-aware footnote ("By the way — a
|
|
505
|
+
// dependency you use just shipped: …" / "… N candidates queued …").
|
|
506
|
+
displayText: (typeof data.displayText === "string" && data.displayText) ? data.displayText : null,
|
|
485
507
|
};
|
|
486
508
|
}
|
|
487
509
|
catch {
|
package/dist/mcp-setup.js
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
import { readFileSync, writeFileSync, existsSync, mkdirSync, renameSync, chmodSync } from "node:fs";
|
|
23
23
|
import { homedir } from "node:os";
|
|
24
24
|
import { join, dirname } from "node:path";
|
|
25
|
+
import { fileURLToPath } from "node:url";
|
|
25
26
|
import { parse as parseToml, stringify as stringifyToml } from "smol-toml";
|
|
26
27
|
import { installSkills } from "./skill-install.js";
|
|
27
28
|
const SERVER_NAME = "replen";
|
|
@@ -239,8 +240,27 @@ function backupIfExists(path) {
|
|
|
239
240
|
// their current docs). Both rely on the AGENTS.md / GEMINI.md project-
|
|
240
241
|
// context file being read at session start, which our inject step
|
|
241
242
|
// covers.
|
|
242
|
-
|
|
243
|
-
|
|
243
|
+
// Version-PIN the hook command. A bare `npx replen` resolves a LOCAL package
|
|
244
|
+
// named "replen" when one exists in cwd (e.g. the replen repo itself, whose
|
|
245
|
+
// server package is also "replen" and has no bin) → "could not determine
|
|
246
|
+
// executable to run", and the hook silently dies every session there. Pinning
|
|
247
|
+
// to the published version forces npx to the registry (collision-proof) and,
|
|
248
|
+
// because the exact version is cached, avoids the per-session `@latest`
|
|
249
|
+
// registry round-trip. Re-running setup refreshes the pin.
|
|
250
|
+
const HOOK_COMMAND = `npx --quiet replen@${cliVersion()} check-new --hook`;
|
|
251
|
+
// Match on the stable substring so we find/replace our hook regardless of the
|
|
252
|
+
// pinned version in any previously-written command.
|
|
253
|
+
const HOOK_MARKER = "check-new --hook";
|
|
254
|
+
function cliVersion() {
|
|
255
|
+
try {
|
|
256
|
+
const here = dirname(fileURLToPath(import.meta.url)); // cli/dist
|
|
257
|
+
const pkg = JSON.parse(readFileSync(join(here, "..", "package.json"), "utf8"));
|
|
258
|
+
return typeof pkg.version === "string" && pkg.version ? pkg.version : "latest";
|
|
259
|
+
}
|
|
260
|
+
catch {
|
|
261
|
+
return "latest";
|
|
262
|
+
}
|
|
263
|
+
}
|
|
244
264
|
function installSessionStartHook(existing) {
|
|
245
265
|
const sessionStart = (existing.SessionStart ?? []).slice();
|
|
246
266
|
const ours = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "replen",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Make your AI coding tools smarter. One command, no API keys. Replen scouts the OSS firehose against your projects and surfaces drop-in libraries, ideas to port, and dead deps to swap — the match decision happens inside your AI tool's session on your subscription tokens. 1-3 actionable matches a month, by design.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|