@nodemint/projectmind
Advanced tools
+25
-0
@@ -6,2 +6,27 @@ # Changelog | ||
| ## [0.5.2] - 2026-07-04 | ||
| ### Fixed | ||
| - **Auto-seed no longer collapses an entire `src/`-layout project into one | ||
| undifferentiated node.** `proposeSeed` grouped strictly by the first path | ||
| segment, so any project nesting everything under `src/` (the near-universal | ||
| convention for modern JS/TS, and common in Rust/Python too) — `src/app/**`, | ||
| `src/lib/**`, `src/components/**`, all of it — seeded as a single "src" | ||
| node covering every file, with a placeholder summary. Real dogfooding on a | ||
| Next.js app surfaced this directly: a 112-file project seeded as exactly | ||
| one node, which meant the embedded digest (v0.5.0) had almost nothing | ||
| specific to say about any given feature. | ||
| - Seeding now descends through a bare `src/` wrapper once, grouping by what's | ||
| actually underneath (`app`, `lib`, `components`, ...) instead. Loose files | ||
| sitting directly in `src/` (no subdirectory) still group under a plain | ||
| `src` node, unchanged. | ||
| **If you already ran `init --seed` on a `src/`-layout project before this | ||
| fix**, your map is stuck with the old one-node shape — `projectmind seed` | ||
| never overwrites an existing node, so simply re-running it won't fix a | ||
| node that already exists. Either ask your agent to call `mind_update` with | ||
| `removeNode: "src"` and then run `projectmind seed` again, or edit | ||
| `.projectmind/map.json` directly: delete the stale `"src"` entry from | ||
| `nodes`, save, then run `projectmind seed`. | ||
| ## [0.5.1] - 2026-07-04 | ||
@@ -8,0 +33,0 @@ |
+1
-1
| { | ||
| "name": "@nodemint/projectmind", | ||
| "version": "0.5.1", | ||
| "version": "0.5.2", | ||
| "mcpName": "io.github.Nodemint-dev/projectmind", | ||
@@ -5,0 +5,0 @@ "publishConfig": { |
+31
-8
@@ -740,2 +740,23 @@ // projectmind core — the only module that touches map.json. | ||
| // Directories that are near-universally a wrapper, never a feature in their | ||
| // own right (the "src layout" convention, used by JS/TS, Rust, Python, and | ||
| // others). Grouping by the FIRST path segment alone collapses every feature | ||
| // of a project like `src/app/**`, `src/lib/**`, `src/components/**` into one | ||
| // undifferentiated "src" blob covering the whole codebase — descend through | ||
| // it once so seeding groups by what's actually underneath instead. | ||
| const PASSTHROUGH_DIRS = new Set(["src"]); | ||
| // Given a repo-relative code file path, return the directory key to group it | ||
| // under for seeding, and the glob prefix that captures that group. Descends | ||
| // one level through a passthrough dir when there's a real subdirectory below | ||
| // it; falls back to the passthrough dir itself for files sitting loose | ||
| // directly inside it (e.g. "src/index.js"). | ||
| function seedGroupFor(relPath) { | ||
| const parts = relPath.split("/"); | ||
| if (parts.length > 2 && PASSTHROUGH_DIRS.has(parts[0])) { | ||
| return { key: parts[1], prefix: `${parts[0]}/${parts[1]}` }; | ||
| } | ||
| return { key: parts[0], prefix: parts[0] }; | ||
| } | ||
| export function proposeSeed(r = root()) { | ||
@@ -763,16 +784,18 @@ const files = walkFiles(r); | ||
| // group code files by their top-level directory | ||
| // group code files by directory, descending through a bare "src/" wrapper | ||
| // so real feature areas (app, lib, components, ...) get their own node | ||
| // instead of collapsing into one "src" blob. | ||
| const byTop = {}; | ||
| for (const f of files) { | ||
| if (!CODE_EXT.test(f)) continue; | ||
| const top = f.split("/")[0]; | ||
| if (f.indexOf("/") === -1) continue; // skip loose top-level files | ||
| (byTop[top] ||= []).push(f); | ||
| const { key, prefix } = seedGroupFor(f); | ||
| (byTop[key] ||= { list: [], prefix }).list.push(f); | ||
| } | ||
| for (const [top, list] of Object.entries(byTop)) { | ||
| if (!SOURCE_DIR_HINTS.has(top) && list.length < 2) continue; // ignore incidental dirs | ||
| proposal.nodes[top] = { | ||
| for (const [key, { list, prefix }] of Object.entries(byTop)) { | ||
| if (!SOURCE_DIR_HINTS.has(key) && list.length < 2) continue; // ignore incidental dirs | ||
| proposal.nodes[key] = { | ||
| type: "module", | ||
| summary: `${top}/ — ${list.length} source file${list.length === 1 ? "" : "s"} (describe me)`, | ||
| files: [`${top}/**`], | ||
| summary: `${prefix}/ — ${list.length} source file${list.length === 1 ? "" : "s"} (describe me)`, | ||
| files: [`${prefix}/**`], | ||
| status: "stable", | ||
@@ -779,0 +802,0 @@ }; |
@@ -182,3 +182,3 @@ #!/usr/bin/env node | ||
| const server = new Server( | ||
| { name: "projectmind", version: "0.5.1" }, | ||
| { name: "projectmind", version: "0.5.2" }, | ||
| { capabilities: { tools: {} } } | ||
@@ -185,0 +185,0 @@ ); |
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
117059
2.38%1812
1.17%