replen 1.0.12 → 1.0.13
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.
|
@@ -169,14 +169,15 @@ export function discoverProjects(roots) {
|
|
|
169
169
|
if (seenGithub.has(githubFullName))
|
|
170
170
|
continue;
|
|
171
171
|
seenGithub.add(githubFullName);
|
|
172
|
-
|
|
173
|
-
//
|
|
174
|
-
//
|
|
175
|
-
//
|
|
176
|
-
//
|
|
177
|
-
//
|
|
178
|
-
//
|
|
172
|
+
// Slug + display name both anchor on the GitHub repo NAME, not the
|
|
173
|
+
// local folder name. Deriving from the folder meant a folder rename (or
|
|
174
|
+
// an org rename like Covelent→nsokin) minted a fresh slug and the server
|
|
175
|
+
// inserted a duplicate row. `~/code/drone` with remote
|
|
176
|
+
// `nsokin/palisade-website` now registers as slug `palisade-website`.
|
|
177
|
+
// The repo name is also the fallback display name, so a generic
|
|
178
|
+
// package.json name (the Next.js starter's "nextn", etc.) doesn't stick.
|
|
179
179
|
const repoName = githubFullName.split("/").pop() || dirName;
|
|
180
|
+
const { name, tags, primaryLanguage } = extractMetadata(repoPath, repoName);
|
|
180
181
|
projects.push({
|
|
181
182
|
localPath: repoPath,
|
|
182
183
|
slug: normaliseSlug(repoName),
|
|
@@ -292,6 +293,17 @@ function readGitRemote(repoPath) {
|
|
|
292
293
|
return null;
|
|
293
294
|
return `${m[1]}/${m[2]}`;
|
|
294
295
|
}
|
|
296
|
+
// Scaffold/template default package.json names that aren't real project
|
|
297
|
+
// names — repos cloned from the same starter all share one (the Next.js
|
|
298
|
+
// starter's "nextn"). Mirrors the server's GENERIC_NAMES guard.
|
|
299
|
+
const GENERIC_PROJECT_NAMES = new Set([
|
|
300
|
+
"nextn", "next-app", "create-next-app", "nextjs", "next", "my-app", "myapp",
|
|
301
|
+
"my-project", "myproject", "app", "web", "webapp", "frontend", "backend",
|
|
302
|
+
"client", "server", "project", "vite-project", "vite-app", "react-app",
|
|
303
|
+
"turborepo", "my-turborepo", "monorepo", "example", "template", "starter",
|
|
304
|
+
"boilerplate", "hello-world", "test", "demo", "untitled",
|
|
305
|
+
]);
|
|
306
|
+
const isGenericProjectName = (n) => GENERIC_PROJECT_NAMES.has(n.trim().toLowerCase());
|
|
295
307
|
function extractMetadata(repoPath, fallbackName) {
|
|
296
308
|
const tags = new Set();
|
|
297
309
|
let name = fallbackName;
|
|
@@ -302,7 +314,7 @@ function extractMetadata(repoPath, fallbackName) {
|
|
|
302
314
|
primaryLanguage = "TypeScript"; // updated below if no TS detected
|
|
303
315
|
try {
|
|
304
316
|
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
305
|
-
if (typeof pkg.name === "string" && pkg.name.length > 0)
|
|
317
|
+
if (typeof pkg.name === "string" && pkg.name.length > 0 && !isGenericProjectName(pkg.name))
|
|
306
318
|
name = pkg.name;
|
|
307
319
|
if (Array.isArray(pkg.keywords)) {
|
|
308
320
|
for (const k of pkg.keywords) {
|
|
@@ -41,6 +41,17 @@ Parse the JSON response. Note:
|
|
|
41
41
|
- `filterMode` — `tags`, `zero-knowledge`, or `fingerprint`
|
|
42
42
|
- `scopedTo` — confirms the project context the user has open
|
|
43
43
|
- `candidates[]` — the actual list to triage
|
|
44
|
+
- `candidates[].priorContext` — server-attached MEMORY: the user's earlier
|
|
45
|
+
verdicts on this repo, and whether the matched capability is already
|
|
46
|
+
covered by something they adopted/ported. Trust it — fold it into your
|
|
47
|
+
verdict instead of re-deriving history, and don't push a candidate whose
|
|
48
|
+
capability is covered unless it's materially better than the incumbent.
|
|
49
|
+
- `candidates[].source === "re-checked"` — a repo the user DEFERRED months
|
|
50
|
+
ago that is still actively developed. Re-evaluate it against today's
|
|
51
|
+
state of the project; the original "not now" note is in `priorContext`.
|
|
52
|
+
- `leap` — on quiet days the response may carry ONE portfolio connection
|
|
53
|
+
(a cross-project / adjacency / cross-user leap) instead of candidates.
|
|
54
|
+
`displayText` already words it; relay that and offer to explore it.
|
|
44
55
|
|
|
45
56
|
If `candidates.length === 0`, tell the user "No new candidates today for
|
|
46
57
|
`<owner/name>`. Calm-cadence working as designed — 1-3 actionable
|
|
@@ -85,6 +96,10 @@ Verdicts:
|
|
|
85
96
|
candidate's runtime is incompatible, or the candidate's not actively
|
|
86
97
|
maintained. Honest skips are valuable signal; don't manufacture
|
|
87
98
|
reasons to keep something.
|
|
99
|
+
- **defer** — genuinely interesting but not NOW (too early / v0.x churn /
|
|
100
|
+
blocked on a milestone the project hasn't hit). Defer is a real promise,
|
|
101
|
+
not a soft skip: Replen automatically re-surfaces a deferred repo after
|
|
102
|
+
~3 months if it's still actively developed (`source: "re-checked"`).
|
|
88
103
|
|
|
89
104
|
**Watch for word-collisions** — the most common bad match. The candidate
|
|
90
105
|
shares a *word* with the matched capability but its real domain diverges:
|
|
@@ -296,6 +311,21 @@ The user hasn't set up filter-mode B's tag list. Mention it once: "Heads
|
|
|
296
311
|
up — you'd get sharper matches if you set project tags at /settings.
|
|
297
312
|
Continuing with unfiltered for now."
|
|
298
313
|
|
|
314
|
+
## The Atlas vault — local memory for any agent
|
|
315
|
+
|
|
316
|
+
Replen keeps an agent-readable markdown vault at `~/.replen/atlas/` — the
|
|
317
|
+
user's whole portfolio as linked notes: every project and what it does,
|
|
318
|
+
every capability (with how it's known: `grounded`/`extracted`/`inferred`),
|
|
319
|
+
every past decision with its reason code, plus themes and blind spots.
|
|
320
|
+
The MCP server refreshes it in the background (at most twice a day);
|
|
321
|
+
`replen atlas` forces a rewrite.
|
|
322
|
+
|
|
323
|
+
Use it whenever you need CROSS-PROJECT context: "what else does this user
|
|
324
|
+
build?", "have we solved X in another repo?", "what did we decide about
|
|
325
|
+
Y last quarter?". Start at `MAP.md`, or call `replen_recall` for a direct
|
|
326
|
+
query. Reading the vault beats re-deriving the portfolio from scratch —
|
|
327
|
+
it's the memory layer, and it's already on disk.
|
|
328
|
+
|
|
299
329
|
## When NOT to run this skill
|
|
300
330
|
|
|
301
331
|
- 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.
|
|
3
|
+
"version": "1.0.13",
|
|
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": {
|