mindlink 1.1.3 → 1.1.5

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 CHANGED
@@ -12,15 +12,17 @@ Three things break AI-assisted development:
12
12
 
13
13
  MindLink fixes all three. One command per project.
14
14
 
15
+ Git gave every developer a shared version history. MindLink gives your AI team a shared memory — persistent, version-controlled, and not locked inside any one tool.
16
+
15
17
  [![npm version](https://img.shields.io/npm/v/mindlink)](https://www.npmjs.com/package/mindlink)
16
18
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
17
19
  [![Platform](https://img.shields.io/badge/platform-macOS%20%7C%20Linux%20%7C%20Windows-lightgrey)](#installation)
18
20
 
19
21
  ---
20
22
 
21
- > ### ◉ Latest — v1.1.3
22
- > **Session memory · Cross-session sync · Cross-agent · 8 AI agents supported · Auto-refresh agent files on every update**
23
- > [→ Full release notes](https://github.com/404-not-found/mindlink/releases/tag/v1.1.3)
23
+ > ### ◉ Latest — v1.1.5
24
+ > **Stronger memory enforcement · MEMORY.md trigger checklist · mtime-based session verification · "git for AI memory" positioning · Claude Code best-in-class section**
25
+ > [→ Full release notes](https://github.com/404-not-found/mindlink/releases/tag/v1.1.5)
24
26
 
25
27
  ---
26
28
 
@@ -32,7 +34,7 @@ MindLink fixes all three. One command per project.
32
34
  - [Supported Agents](#supported-agents)
33
35
  - [Commands](#commands)
34
36
  - [Can My AI Run These Commands?](#can-my-ai-run-these-commands-itself)
35
- - [The Hook (Claude Code)](#the-hook-claude-code-users)
37
+ - [Best with Claude Code](#best-with-claude-code)
36
38
  - [License](#license)
37
39
  - [Contributing](#contributing)
38
40
 
@@ -90,7 +92,7 @@ Close any AI session whenever you want — Claude Code, Cursor, Codex, whatever
90
92
 
91
93
  **One memory, every agent** — use Claude Code in the morning, switch to Cursor in the afternoon — both read the exact same `.brain/` folder. No syncing. No duplicating context. No "but I told the other AI this already." Every agent you use shares one brain, because the memory lives in your project, not inside any particular tool. This is something no AI vendor can replicate — they each only know their own product.
92
94
 
93
- **Team memory out of the box** — commit `.brain/` to git and your whole team shares the same AI context. New teammate joins, does `git pull`, and their AI agent is already fully briefed on the project. No onboarding session, no copying notes, no "let me catch you up."
95
+ **Team memory, like git** — commit `.brain/` to git and your whole team shares the same AI context, automatically. New developer joins, does `git pull` their AI is already fully briefed. Two developers in the same project? Their agents share context in real time, just like working off the same branch. No onboarding session, no copying notes, no "let me catch you up." This is what git did for code history — MindLink does for AI memory.
94
96
 
95
97
  **Plug in, not lock in** — works with Claude Code, Cursor, Codex, Gemini CLI, GitHub Copilot, Windsurf, Cline, Aider, and more. Because MindLink just writes files that agents read — no APIs, no SDKs, no version dependencies — it works with whatever version you have installed today and every version that comes after.
96
98
 
@@ -179,9 +181,28 @@ The one exception: `mindlink sync` in watch mode runs continuously — keep it i
179
181
 
180
182
  ---
181
183
 
182
- ## The Hook (Claude Code users)
184
+ ## Best with Claude Code
185
+
186
+ MindLink works with every agent listed above. But Claude Code users get something the others don't: **a second enforcement layer**.
187
+
188
+ Every other agent reads the instruction file at startup and follows it as best it can. That's the instruction layer — guidance, not guarantees. The agent can skip a step, misread a section, or forget to write after a long session.
189
+
190
+ Claude Code gets both the instruction file **and** an OS-level hook that fires before every single message — outside the AI's control. This hook:
191
+
192
+ - Scans for memory triggers and reminds the agent to write `MEMORY.md` before answering
193
+ - Forces `SESSION.md` to be updated as the last action of every response
194
+ - Runs a shell-level check after every response: if `MEMORY.md` still contains only placeholders, the agent is immediately flagged and must fill it in before continuing
195
+
196
+ **The practical difference:**
197
+
198
+ | | All other agents | Claude Code |
199
+ |---|---|---|
200
+ | Persistent memory | ✓ instruction file | ✓ instruction file + hook |
201
+ | Enforced on every message | ✗ | ✓ OS-level hook |
202
+ | Post-response memory verification | ✗ | ✓ shell check |
203
+ | Context compaction recovery | ✓ instruction | ✓ instruction + hook |
183
204
 
184
- Claude Code users get an extra layer: a `UserPromptSubmit` hook in `.claude/settings.json` that fires on every message, reminding your agent to re-read `.brain/` if its context was just compacted. Other agents rely on their instruction files — Claude Code gets both because it supports OS-level hooks. Same protection, different delivery.
205
+ If you're choosing an agent specifically to use with MindLink, Claude Code gives you the most reliable memory behavior. Other agents work well — Claude Code works harder.
185
206
 
186
207
  ---
187
208
 
package/dist/cli.js CHANGED
@@ -5,7 +5,7 @@ import { Command as Command15 } from "commander";
5
5
  import chalk16 from "chalk";
6
6
 
7
7
  // src/utils/version.ts
8
- var VERSION = "1.1.3";
8
+ var VERSION = "1.1.5";
9
9
 
10
10
  // src/commands/init.ts
11
11
  import { Command } from "commander";
@@ -88,6 +88,11 @@ function registerProject(projectPath) {
88
88
  function getRegisteredProjects() {
89
89
  return load();
90
90
  }
91
+ function pruneRegistry(isValid) {
92
+ const paths = load();
93
+ const pruned = paths.filter(isValid);
94
+ if (pruned.length !== paths.length) save(pruned);
95
+ }
91
96
 
92
97
  // src/commands/init.ts
93
98
  function detectProjectInfo(projectPath) {
@@ -577,7 +582,7 @@ Examples:
577
582
  // src/commands/clear.ts
578
583
  import { Command as Command4 } from "commander";
579
584
  import chalk5 from "chalk";
580
- import { existsSync as existsSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "fs";
585
+ import { existsSync as existsSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync3, unlinkSync } from "fs";
581
586
  import { join as join6, resolve as resolve4 } from "path";
582
587
  var clearCommand = new Command4("clear").description("Reset SESSION.md for a fresh session start").option("-y, --yes", "Skip confirmation prompt").addHelpText("after", `
583
588
  What it does:
@@ -606,6 +611,8 @@ Examples:
606
611
  const templatePath = join6(BRAIN_TEMPLATES_DIR, "SESSION.md");
607
612
  const destPath = join6(brainDir, "SESSION.md");
608
613
  writeFileSync3(destPath, readFileSync5(templatePath, "utf8"));
614
+ const tsDest = join6(brainDir, ".session_ts");
615
+ if (existsSync5(tsDest)) unlinkSync(tsDest);
609
616
  } catch (err) {
610
617
  console.log(` ${chalk5.red("\u2717")} ${err instanceof Error ? err.message : String(err)}`);
611
618
  console.log("");
@@ -694,7 +701,7 @@ import {
694
701
  writeFileSync as writeFileSync5,
695
702
  appendFileSync as appendFileSync2,
696
703
  mkdirSync as mkdirSync3,
697
- unlinkSync
704
+ unlinkSync as unlinkSync2
698
705
  } from "fs";
699
706
  import { join as join8, resolve as resolve6, dirname as dirname3 } from "path";
700
707
  function readConfig(brainDir) {
@@ -734,7 +741,7 @@ function removeAgentFile(projectPath, agentValue) {
734
741
  if (!agent) return null;
735
742
  const destPath = join8(projectPath, agent.destFile);
736
743
  if (!existsSync7(destPath)) return null;
737
- unlinkSync(destPath);
744
+ unlinkSync2(destPath);
738
745
  return agent.destFile;
739
746
  }
740
747
  function addClaudeHook(projectPath) {
@@ -1128,7 +1135,11 @@ Examples:
1128
1135
  process.exit(1);
1129
1136
  }
1130
1137
  }
1131
- const projects = getRegisteredProjects().filter((p) => existsSync9(join10(p, BRAIN_DIR, "config.json")));
1138
+ const cwd = process.cwd();
1139
+ const validProjects = getRegisteredProjects().filter((p) => existsSync9(join10(p, BRAIN_DIR, "config.json")));
1140
+ pruneRegistry((p) => existsSync9(join10(p, BRAIN_DIR, "config.json")));
1141
+ const cwdHasBrain = existsSync9(join10(cwd, BRAIN_DIR, "config.json"));
1142
+ const projects = cwdHasBrain && !validProjects.includes(cwd) ? [cwd, ...validProjects] : validProjects;
1132
1143
  if (projects.length > 0) {
1133
1144
  console.log("");
1134
1145
  console.log(` Refreshing agent files in ${projects.length} project${projects.length > 1 ? "s" : ""}...`);
@@ -1162,6 +1173,30 @@ Examples:
1162
1173
  } catch {
1163
1174
  }
1164
1175
  }
1176
+ const memoryPath = join10(projectPath, BRAIN_DIR, "MEMORY.md");
1177
+ if (existsSync9(memoryPath)) {
1178
+ try {
1179
+ const content = readFileSync9(memoryPath, "utf8");
1180
+ if (!content.includes("## User Profile") && content.includes("## Important Context")) {
1181
+ const userProfileBlock = `## User Profile <!-- READ EVERY SESSION \u2014 personal facts about the user -->
1182
+
1183
+ <!-- Job, company, level, years of experience, immigration status -->
1184
+ <!-- Age, health, physical details -->
1185
+ <!-- Family, relationships, major life events -->
1186
+ <!-- Long-term goals: career, financial, personal -->
1187
+ <!-- Strong opinions, values, preferences -->
1188
+ <!-- Update in place \u2014 do not append; consolidate when it grows -->
1189
+
1190
+
1191
+ ---
1192
+
1193
+ `;
1194
+ writeFileSync6(memoryPath, content.replace("## Important Context", userProfileBlock + "## Important Context"));
1195
+ refreshed.push(".brain/MEMORY.md");
1196
+ }
1197
+ } catch {
1198
+ }
1199
+ }
1165
1200
  console.log(` ${chalk9.bold(projectPath)}`);
1166
1201
  for (const f of refreshed) {
1167
1202
  console.log(` ${chalk9.green("\u2713")} ${f}`);
@@ -1292,7 +1327,7 @@ to get a full briefing on the current project state.
1292
1327
  import { Command as Command10 } from "commander";
1293
1328
  import { select as select4, isCancel as isCancel5, cancel as cancel5 } from "@clack/prompts";
1294
1329
  import chalk11 from "chalk";
1295
- import { existsSync as existsSync11, readFileSync as readFileSync11, rmSync, unlinkSync as unlinkSync2 } from "fs";
1330
+ import { existsSync as existsSync11, readFileSync as readFileSync11, rmSync, unlinkSync as unlinkSync3 } from "fs";
1296
1331
  import { join as join12, resolve as resolve9 } from "path";
1297
1332
  var uninstallCommand = new Command10("uninstall").description("Remove MindLink from the current project").option("-y, --yes", "Skip confirmation and remove all project files").addHelpText("after", `
1298
1333
  What gets removed:
@@ -1374,7 +1409,7 @@ Examples:
1374
1409
  const destPath = join12(projectPath, agent.destFile);
1375
1410
  if (existsSync11(destPath)) {
1376
1411
  try {
1377
- unlinkSync2(destPath);
1412
+ unlinkSync3(destPath);
1378
1413
  removed.push(agent.destFile);
1379
1414
  } catch (err) {
1380
1415
  errors.push(`${agent.destFile}: ${err instanceof Error ? err.message : String(err)}`);
@@ -1385,7 +1420,7 @@ Examples:
1385
1420
  const hookPath = join12(projectPath, ".claude", "settings.json");
1386
1421
  if (existsSync11(hookPath)) {
1387
1422
  try {
1388
- unlinkSync2(hookPath);
1423
+ unlinkSync3(hookPath);
1389
1424
  removed.push(".claude/settings.json");
1390
1425
  } catch {
1391
1426
  }