🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@nodemint/projectmind

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@nodemint/projectmind - npm Package Compare versions

Comparing version
0.5.3
to
0.6.0
+35
-0
CHANGELOG.md

@@ -6,2 +6,37 @@ # Changelog

## [0.6.0] - 2026-07-06
The "works out of the box" release — setup collapsed to one command, and the
map goes local-first by default.
### Changed (behavior)
- **`projectmind init` now does everything in one command**: scaffold, seed
from repo layout, detect which AI agents are installed on this machine
(via their config dirs) and wire only those, embed the live digest in their
rules files, gitignore the map, and install the git freshness hook — then
print the one manual step left (restart your agent / reload the VS Code
window) instead of assuming users know. `init --bare` restores the old
scaffold-only behavior; `--seed` is accepted as a no-op for back-compat.
- **Local-first by default**: `init` now gitignores the whole `.projectmind/`
directory — the raw map, personal overlay, and ledger never leave your
machine, and there's nothing to push or review. The shareable knowledge
still travels via the digest embedded in committed rules files. Teams that
want the full map in git delete one `.gitignore` line; `init` detects and
respects an existing sharing choice (including the pre-0.6 per-file ignore
scheme) and never overrides it.
### Added
- `detectInstalledAgents()` — filesystem-only detection of Claude Code,
Cursor, Windsurf, and Gemini CLI; AGENTS.md always included as the
cross-agent standard. A Claude-only user no longer gets six rules files.
- Explicit reload/restart guidance in `init` and `setup` output, including
the honest boundary: an already-open chat session keeps its old context
(an MCP-client limitation no server can bypass); everything is automatic
from the next session on.
### Docs
- README rewritten around the one-command flow, the local-first/team-mode
choice, and a new Trust-FAQ entry stating exactly what does and doesn't
work in an already-open session. Demo GIF regenerated for the new flow.
## [0.5.3] - 2026-07-04

@@ -8,0 +43,0 @@

+1
-1
{
"name": "@nodemint/projectmind",
"version": "0.5.3",
"version": "0.6.0",
"mcpName": "io.github.Nodemint-dev/projectmind",

@@ -5,0 +5,0 @@ "publishConfig": {

+61
-23

@@ -8,3 +8,3 @@ # projectmind

[![CI](https://github.com/Nodemint-dev/projectmind/actions/workflows/ci.yml/badge.svg)](https://github.com/Nodemint-dev/projectmind/actions/workflows/ci.yml)
![tests](https://img.shields.io/badge/tests-63%20passing-brightgreen)
![tests](https://img.shields.io/badge/tests-85%20passing-brightgreen)
![platforms](https://img.shields.io/badge/platforms-linux%20%7C%20macos%20%7C%20windows-blue)

@@ -16,3 +16,3 @@ ![node](https://img.shields.io/badge/node-%E2%89%A518-blue)

![Demo: init --seed scaffolds the map, setup wires every agent, the digest opens with the session handoff, and projectmind savings shows ~20.5k tokens saved](docs/assets/demo.gif)
![Demo: one projectmind init command scaffolds, seeds, wires every installed agent, gitignores the map, and installs the git hook; the digest opens with the session handoff and projectmind savings shows ~20.5k tokens saved](docs/assets/demo.gif)

@@ -26,3 +26,3 @@ ![Benchmark: reading the codebase ~1,953 tokens vs projectmind digest ~412 tokens, −78.9%](docs/assets/benchmark.svg)

`projectmind` fixes this with a **structured, git-committed project map**
`projectmind` fixes this with a **structured, persistent project map**
(`.projectmind/map.json`): your modules, their dependencies, your architectural

@@ -37,15 +37,31 @@ decisions, your conventions, your domain glossary. The agent reads a ~400-token

## Quick start
## Quick start — one command
```bash
npm install -g @nodemint/projectmind # installs the `projectmind` CLI
npm install -g @nodemint/projectmind
cd your-repo
projectmind init --seed # scaffold + propose a starter map from your repo layout
projectmind setup # wire the MCP server + rules into every agent you use
projectmind install-hook # optional: auto-update module freshness on commit
projectmind init
```
That's it. Your agent now calls `mind_digest` at the start of a task instead of
scanning files.
That single `init` does everything: scaffolds the map, **seeds it from your
repo layout**, detects which AI agents are installed on your machine and
**wires each one** (MCP server + a rules file carrying the live map), adds
`.projectmind/` to your `.gitignore` (the map stays local — nothing to push),
and installs the git hook that keeps the map fresh on every commit.
**Then the one step no tool can do for you: restart your agent** (or start a
new chat session). AI agents load their config and rules files at session
start — a chat that was already open keeps its old context, and every session
after that has the map automatically. Using the VS Code savings extension?
`Cmd+Shift+P` → *"Developer: Reload Window"* once.
Want it available in **every future project without even running `init`**?
```bash
projectmind setup --global # registers the MCP server once, user-wide
```
(`projectmind init --bare` scaffolds only, and `projectmind setup` re-wires
agents on demand, if you prefer the pieces separately.)
## See what it saves you — measured, not promised

@@ -128,3 +144,3 @@

No language assumptions, no platform assumptions: the full test suite (63
No language assumptions, no platform assumptions: the full test suite (85
tests, including the git-hook end-to-end and offline-guarantee tests) runs in

@@ -165,5 +181,5 @@ CI on **Linux, macOS, and Windows × Node 18/20/22**. Paths, globs, atomic

end
subgraph repo["Your repo (git-committed)"]
subgraph repo["Your repo"]
MAP[".projectmind/map.json\nnodes · edges · decisions\nconventions · glossary"]
DIG[".projectmind/digest.md\nreviewable in PRs"]
DIG[".projectmind/digest.md\n+ embedded in CLAUDE.md etc."]
end

@@ -405,6 +421,15 @@ LEDGER[".projectmind/ledger.json\nlocal savings ledger (gitignored)"]

Two scopes: the committed `map.json` (shared with your team) and an optional
gitignored `map.local.json` overlay for personal context ("mid-refactor on X").
`digest.md` is committed too, so map changes show up as **readable diffs in PRs**.
**Local-first by default:** `init` gitignores the whole `.projectmind/`
directory — the raw map, your personal overlay ("mid-refactor on X",
handoffs), and the savings ledger all stay on your machine. Nothing to push,
nothing to review. The *shareable* knowledge still travels with the repo,
because the digest is embedded in your committed rules files (`CLAUDE.md`
etc.) and auto-synced on every change.
**Team mode (opt-in):** want the full raw map in git so teammates and CI share
one source of truth? Delete the `.projectmind/` line from `.gitignore` —
that's the whole switch. Every write is deterministic (sorted keys, atomic),
so `map.json` and `digest.md` produce clean, reviewable PR diffs. `init` never
overrides this choice once you've made it.
## Trust FAQ

@@ -418,5 +443,8 @@

**What gets committed?** `map.json`, `digest.md`, `config.json`. Your personal
overlay (`map.local.json`) and your savings ledger (`ledger.json`) are
gitignored automatically.
**What gets committed?** By default, nothing under `.projectmind/` — the map is
local-first and gitignored at `init`. What *is* committed: the digest embedded
in your rules files (`CLAUDE.md`, `.cursorrules`, …), which is exactly the
part meant to be shared — and it never includes your personal overlay or
handoff notes (regression-tested). Teams can opt into committing the full map
by removing one `.gitignore` line.

@@ -427,6 +455,16 @@ **Are the savings numbers real?** They're honest estimates, clearly labelled,

**Can the map rot?** The git hook and watch mode keep file↔module freshness
current for free; `doctor` flags dangling and stale nodes; `validate` checks
integrity. And because the digest is committed, drift is visible in code review.
**Does it work in a chat session that's already open?** Partially, and we'd
rather tell you exactly where the line is: every MCP client loads servers and
rules files at session start, so a conversation that was open before `init`
ran keeps its old context — no tool (ours or anyone's) can inject into it.
From the very next session on, everything is automatic. If the MCP server was
already registered globally (`setup --global`), the `mind_*` tools work even
mid-session in a brand-new project — only the embedded rules-file digest
waits for the next session.
**Can the map rot?** The git hook (installed by `init`) and watch mode keep
file↔module freshness current for free; `doctor` flags dangling and stale
nodes; `validate` checks integrity; and the embedded digest re-syncs on every
map write, so what agents see never lags what's recorded.
**Does it lock me into one AI tool?** No. Any MCP-capable agent can use it, the

@@ -439,3 +477,3 @@ rules files cover the rest, and the map itself is plain JSON any tool can read.

npm install
npm test # 63 tests: schema, atomicity, corruption self-heal, scopes,
npm test # 85 tests: schema, atomicity, corruption self-heal, scopes,
# globs, MCP round-trip, ledger, handoff, offline guarantee

@@ -442,0 +480,0 @@ npm run benchmark # prints the estimated savings number

@@ -8,3 +8,3 @@ #!/usr/bin/env node

import { installHook } from "../hooks/install.js";
import { setupAgents, setupGlobalAgents, SUPPORTED_AGENTS, SUPPORTED_GLOBAL_AGENTS } from "../setup/index.js";
import { setupAgents, setupGlobalAgents, detectInstalledAgents, SUPPORTED_AGENTS, SUPPORTED_GLOBAL_AGENTS } from "../setup/index.js";
import { watch } from "../watch/index.js";

@@ -22,3 +22,4 @@ import { savingsSummary, resolvePrice } from "../core/ledger.js";

Commands:
init [--seed] Scaffold .projectmind/; --seed proposes a starter map from repo layout
init ONE command: scaffold + seed a starter map + wire your installed
agents + gitignore + git hook. (--bare: scaffold only)
seed Propose a starter map from repo layout (adds missing nodes only)

@@ -47,3 +48,3 @@ setup [--agent <name>] Wire the MCP server + rules into agents (${SUPPORTED_AGENTS.join(", ")}, or all)

--root <dir> Operate on a specific project root
--seed (init) seed a starter map after scaffolding
--bare (init) scaffold only — skip seeding, agent wiring, and the git hook
--agent <name> (setup) target one agent; default all

@@ -67,3 +68,4 @@ --global (setup) register once for every future project, instead of just this repo

if (a === "--local") opts.local = true;
else if (a === "--seed") opts.seed = true;
else if (a === "--seed") opts.seed = true; // legacy no-op: init seeds by default now
else if (a === "--bare") opts.bare = true;
else if (a === "--root") opts.root = argv[++i];

@@ -110,9 +112,32 @@ else if (a === "--agent") opts.agent = argv[++i];

case "init": {
// One command, everything wired — the codegraph-style out-of-the-box
// experience. `--bare` restores the old scaffold-only behavior.
core.init(r);
out(`Initialized .projectmind/ at ${r}`);
if (opts.seed) {
out(`✓ Initialized .projectmind/ at ${r} (gitignored — the map stays local)`);
if (!opts.bare) {
const res = core.seed(r);
out(`Seeded ${res.added.length} node(s) from repo layout: ${res.added.join(", ") || "(none)"}`);
out(`✓ Seeded ${res.added.length} node(s) from repo layout: ${res.added.join(", ") || "(map already covers the source dirs)"}`);
const detected = detectInstalledAgents();
const results = setupAgents(r, detected);
const rulesFiles = results.filter((x) => !x.file.endsWith(".json")).map((x) => x.file);
out(`✓ Wired agents detected on this machine (${detected.join(", ")}): ${[...new Set(rulesFiles)].join(", ")}`);
out(` The live project map is embedded in those files — agents see it with zero tool calls.`);
try {
const hook = installHook(r);
out(hook.alreadyInstalled ? `✓ Git hook already installed` : `✓ Git post-commit hook installed (keeps the map fresh automatically)`);
} catch {
out(`- Skipped git hook (not a git repository yet — run \`projectmind install-hook\` after \`git init\`)`);
}
out(``);
out(`One-time step left — reload your tools so they pick this up:`);
out(` • Restart your AI agent (Claude Code, Cursor, ...) or start a new chat session.`);
out(` An already-open session keeps its old context; the map loads from the next session on.`);
out(` • Using the VS Code savings extension? Cmd+Shift+P → "Developer: Reload Window".`);
out(``);
out(`Optional: \`projectmind setup --global\` registers the MCP server once for ALL projects,`);
out(`and \`projectmind setup --agent <name>\` wires an agent this machine-scan missed.`);
}
out(core.digest(r));
break;

@@ -141,3 +166,5 @@ }

for (const x of results) out(` ${x.status.padEnd(18)} ${x.file}`);
out("\nRestart your agent so it picks up the new MCP server.");
out("\nOne-time step: restart your AI agent (or start a new chat session) so it picks this up.");
out("An already-open session keeps its old context — the map loads from the next session on.");
out("VS Code savings extension users: Cmd+Shift+P → \"Developer: Reload Window\".");
break;

@@ -144,0 +171,0 @@ }

@@ -401,12 +401,21 @@ // projectmind core — the only module that touches map.json.

const gi = path.join(r, ".gitignore");
// Per-developer files: the local overlay and the savings ledger. Both are
// private to the machine and must never be committed.
const lines = [`${DIR}/${LOCAL}`, `${DIR}/ledger.json`];
// Local-first by default: the whole .projectmind/ directory stays on the
// developer's machine — nothing to push, nothing to review, works out of
// the box. The shareable knowledge still travels with the repo via the
// digest embedded in committed rules files (CLAUDE.md etc.). Teams that
// want the full raw map in git can simply delete this line from
// .gitignore — every write is deterministic and diff-friendly by design.
const line = `${DIR}/`;
let content = "";
try { content = fs.readFileSync(gi, "utf8"); } catch { /* none yet */ }
const present = new Set(content.split(/\r?\n/).map((l) => l.trim()));
const missing = lines.filter((l) => !present.has(l));
if (!missing.length) return false;
// Respect a team that already shares the map: if any .projectmind path is
// deliberately committed (line absent but map tracked), we still only
// APPEND to .gitignore on first init — if the user previously removed the
// ignore line to share, `present` won't have it but the old per-file lines
// might; never fight the user's explicit choice, so skip when either the
// dir line or the legacy overlay line is already there.
if (present.has(line) || present.has(`${DIR}/${LOCAL}`)) return false;
const prefix = content && !content.endsWith("\n") ? "\n" : "";
fs.appendFileSync(gi, `${prefix}${missing.join("\n")}\n`);
fs.appendFileSync(gi, `${prefix}${line}\n`);
return true;

@@ -413,0 +422,0 @@ }

@@ -182,3 +182,3 @@ #!/usr/bin/env node

const server = new Server(
{ name: "projectmind", version: "0.5.3" },
{ name: "projectmind", version: "0.6.0" },
{ capabilities: { tools: {} } }

@@ -185,0 +185,0 @@ );

@@ -123,2 +123,20 @@ // Multi-agent wiring. Writes the MCP server config and a workflow rules block

// ---------------------------------------------------------------------------
// Agent auto-detection — which agents does this machine actually have?
// Used by one-command `init` so a Claude-only user doesn't get six rules
// files of clutter. Detection is filesystem-only (config dirs each agent
// creates on first run), deterministic, and overridable for tests.
// "codex" (AGENTS.md) is always included: it's the emerging cross-agent
// standard and costs one small file.
// ---------------------------------------------------------------------------
export function detectInstalledAgents({ homeDir = os.homedir() } = {}) {
const has = (...segs) => fs.existsSync(path.join(homeDir, ...segs));
const found = ["codex"];
if (has(".claude.json") || has(".claude")) found.push("claude");
if (has(".cursor")) found.push("cursor");
if (has(".codeium", "windsurf")) found.push("windsurf");
if (has(".gemini")) found.push("gemini");
return found;
}
// ---------------------------------------------------------------------------
// Global (user) scope — register once, available in every future project

@@ -125,0 +143,0 @@ // without a per-project .mcp.json. Only the MCP server entry is global; rules