@everstateai/mcp 1.3.11 → 1.3.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.
- package/README.md +26 -3
- package/dist/index.js +462 -12
- package/dist/index.js.map +1 -1
- package/dist/setup/auto-update.d.ts.map +1 -1
- package/dist/setup/auto-update.js +223 -0
- package/dist/setup/auto-update.js.map +1 -1
- package/dist/setup/hooks/templates.d.ts +18 -1
- package/dist/setup/hooks/templates.d.ts.map +1 -1
- package/dist/setup/hooks/templates.js +381 -41
- package/dist/setup/hooks/templates.js.map +1 -1
- package/dist/setup/types.d.ts +2 -0
- package/dist/setup/types.d.ts.map +1 -1
- package/dist/setup/types.js +3 -1
- package/dist/setup/types.js.map +1 -1
- package/dist/setup.d.ts.map +1 -1
- package/dist/setup.js +108 -8
- package/dist/setup.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +503 -13
- package/src/setup/auto-update.ts +263 -0
- package/src/setup/hooks/templates.ts +398 -41
- package/src/setup/types.ts +3 -1
- package/src/setup.ts +123 -8
package/src/setup.ts
CHANGED
|
@@ -24,6 +24,8 @@ import {
|
|
|
24
24
|
import {
|
|
25
25
|
getSessionStartHook,
|
|
26
26
|
getSessionEndHook,
|
|
27
|
+
getPreCompactHook,
|
|
28
|
+
getSubagentContextHook,
|
|
27
29
|
getSyncTodosHook,
|
|
28
30
|
} from "./setup/hooks/templates.js";
|
|
29
31
|
|
|
@@ -336,11 +338,13 @@ function cleanupOldHooks(projectDir: string) {
|
|
|
336
338
|
|
|
337
339
|
const oldHookFiles = [
|
|
338
340
|
"everstate-session-start.sh",
|
|
339
|
-
"everstate-session-
|
|
341
|
+
"everstate-session-end.sh",
|
|
342
|
+
"everstate-session-stop.sh", // legacy name
|
|
340
343
|
"everstate-sync-todos.js",
|
|
341
344
|
"everstate-pre-compact.sh",
|
|
342
345
|
"session-start.sh",
|
|
343
|
-
"session-
|
|
346
|
+
"session-end.sh",
|
|
347
|
+
"session-stop.sh", // legacy name
|
|
344
348
|
"sync-todos.js",
|
|
345
349
|
"pre-compact.sh",
|
|
346
350
|
];
|
|
@@ -400,7 +404,9 @@ async function installHooks(projectDir: string, force: boolean = false) {
|
|
|
400
404
|
|
|
401
405
|
// Use versioned templates for all hooks
|
|
402
406
|
const sessionStartHook = getSessionStartHook(hookConfig);
|
|
403
|
-
const
|
|
407
|
+
const sessionEndHook = getSessionEndHook(hookConfig);
|
|
408
|
+
const preCompactHook = getPreCompactHook(hookConfig);
|
|
409
|
+
const subagentContextHook = getSubagentContextHook(hookConfig);
|
|
404
410
|
|
|
405
411
|
// Sync-todos hook: try download from server, fallback to embedded template
|
|
406
412
|
let syncTodosHook: string;
|
|
@@ -412,10 +418,26 @@ async function installHooks(projectDir: string, force: boolean = false) {
|
|
|
412
418
|
|
|
413
419
|
// Write project-local hook files
|
|
414
420
|
const startHookPath = path.join(projectHooksDir, "everstate-session-start.sh");
|
|
415
|
-
const
|
|
421
|
+
const endHookPath = path.join(projectHooksDir, "everstate-session-end.sh");
|
|
422
|
+
const preCompactPath = path.join(projectHooksDir, "everstate-pre-compact.js");
|
|
423
|
+
const subagentContextPath = path.join(projectHooksDir, "everstate-subagent-context.js");
|
|
416
424
|
|
|
417
425
|
fs.writeFileSync(startHookPath, sessionStartHook, { mode: 0o755 });
|
|
418
|
-
fs.writeFileSync(
|
|
426
|
+
fs.writeFileSync(endHookPath, sessionEndHook, { mode: 0o755 });
|
|
427
|
+
fs.writeFileSync(preCompactPath, preCompactHook, { mode: 0o755 });
|
|
428
|
+
fs.writeFileSync(subagentContextPath, subagentContextHook, { mode: 0o755 });
|
|
429
|
+
|
|
430
|
+
// Clean up old bash-based pre-compact hook (replaced by JS version)
|
|
431
|
+
const oldPreCompactShPath = path.join(projectHooksDir, "everstate-pre-compact.sh");
|
|
432
|
+
if (fs.existsSync(oldPreCompactShPath)) {
|
|
433
|
+
fs.unlinkSync(oldPreCompactShPath);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// Clean up old session-stop.sh if it exists (renamed to session-end.sh)
|
|
437
|
+
const oldStopPath = path.join(projectHooksDir, "everstate-session-stop.sh");
|
|
438
|
+
if (fs.existsSync(oldStopPath)) {
|
|
439
|
+
fs.unlinkSync(oldStopPath);
|
|
440
|
+
}
|
|
419
441
|
|
|
420
442
|
// Write sync-todos to global location
|
|
421
443
|
const globalSyncTodosPath = path.join(globalHooksDir, "sync-todos.js");
|
|
@@ -483,7 +505,24 @@ async function installHooks(projectDir: string, force: boolean = false) {
|
|
|
483
505
|
}
|
|
484
506
|
|
|
485
507
|
addHookIfNotExists("SessionStart", "*", startHookPath);
|
|
486
|
-
addHookIfNotExists("
|
|
508
|
+
addHookIfNotExists("SessionEnd", "*", endHookPath);
|
|
509
|
+
addHookIfNotExists("PreCompact", "*", `node ${preCompactPath}`);
|
|
510
|
+
addHookIfNotExists("SubagentStart", "*", `node ${subagentContextPath}`);
|
|
511
|
+
|
|
512
|
+
// Migrate: remove stale Stop hooks from older installations
|
|
513
|
+
if (settings.hooks.Stop) {
|
|
514
|
+
const everstateStopEntries = settings.hooks.Stop.filter((entry: any) =>
|
|
515
|
+
entry.hooks?.some((h: any) => h.command?.includes("everstate"))
|
|
516
|
+
);
|
|
517
|
+
if (everstateStopEntries.length > 0) {
|
|
518
|
+
settings.hooks.Stop = settings.hooks.Stop.filter((entry: any) =>
|
|
519
|
+
!entry.hooks?.some((h: any) => h.command?.includes("everstate"))
|
|
520
|
+
);
|
|
521
|
+
if (settings.hooks.Stop.length === 0) {
|
|
522
|
+
settings.hooks.Stop = [];
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
}
|
|
487
526
|
|
|
488
527
|
// Also register PostToolUse for TodoWrite at the project level as fallback
|
|
489
528
|
// This ensures sync works even if global ~/.claude.json is missing the hook
|
|
@@ -498,8 +537,18 @@ async function installHooks(projectDir: string, force: boolean = false) {
|
|
|
498
537
|
}
|
|
499
538
|
}
|
|
500
539
|
|
|
540
|
+
// Add Everstate MCP tools to permissions allow list
|
|
541
|
+
if (!settings.permissions) settings.permissions = {};
|
|
542
|
+
if (!settings.permissions.allow) settings.permissions.allow = [];
|
|
543
|
+
|
|
544
|
+
const everstatePermission = "mcp__everstate__*";
|
|
545
|
+
if (!settings.permissions.allow.includes(everstatePermission)) {
|
|
546
|
+
settings.permissions.allow.push(everstatePermission);
|
|
547
|
+
}
|
|
548
|
+
|
|
501
549
|
writeJsonFile(settingsPath, settings);
|
|
502
550
|
logSuccess("Session hooks installed");
|
|
551
|
+
logSuccess("Everstate tools added to approved commands");
|
|
503
552
|
}
|
|
504
553
|
|
|
505
554
|
// ============================================================================
|
|
@@ -555,7 +604,7 @@ async function createProjectConfig(
|
|
|
555
604
|
|
|
556
605
|
function updateGitignore(projectDir: string) {
|
|
557
606
|
const gitignorePath = path.join(projectDir, ".gitignore");
|
|
558
|
-
const entries = ["# Everstate", ".claude/settings.local.json", ".claude/hooks/"];
|
|
607
|
+
const entries = ["# Everstate", ".claude/settings.local.json", ".claude/hooks/", ".claude/rules/"];
|
|
559
608
|
|
|
560
609
|
let content = fs.existsSync(gitignorePath) ? fs.readFileSync(gitignorePath, "utf8") : "";
|
|
561
610
|
const toAdd = entries.filter((e) => !content.includes(e.replace("# Everstate", "")));
|
|
@@ -566,6 +615,56 @@ function updateGitignore(projectDir: string) {
|
|
|
566
615
|
}
|
|
567
616
|
}
|
|
568
617
|
|
|
618
|
+
// ============================================================================
|
|
619
|
+
// Everstate Rules (.claude/rules/everstate.md)
|
|
620
|
+
// ============================================================================
|
|
621
|
+
// Claude Code auto-loads all .md files from .claude/rules/ — this keeps
|
|
622
|
+
// Everstate instructions separate from the user's CLAUDE.md.
|
|
623
|
+
|
|
624
|
+
const EVERSTATE_CLAUDE_MD_MARKER = "<!-- everstate -->";
|
|
625
|
+
|
|
626
|
+
const EVERSTATE_RULES_CONTENT = `# Everstate - Project Memory
|
|
627
|
+
|
|
628
|
+
This project uses [Everstate](https://www.everstate.ai) for persistent memory across sessions.
|
|
629
|
+
|
|
630
|
+
- Sessions start and end automatically via hooks — no manual calls needed
|
|
631
|
+
- Use \`recall("query")\` to search past session context
|
|
632
|
+
- Use \`log({ type: "achievement", message: "..." })\` to record progress
|
|
633
|
+
- Use \`everstate({ action: "help" })\` to discover all available actions
|
|
634
|
+
- Call \`done()\` before ending for a detailed summary (auto-done runs otherwise)
|
|
635
|
+
`;
|
|
636
|
+
|
|
637
|
+
function ensureClaudeMd(projectDir: string) {
|
|
638
|
+
// Write instructions to .claude/rules/everstate.md (auto-loaded by Claude Code)
|
|
639
|
+
const rulesDir = path.join(projectDir, ".claude", "rules");
|
|
640
|
+
const rulesPath = path.join(rulesDir, "everstate.md");
|
|
641
|
+
|
|
642
|
+
if (!fs.existsSync(rulesDir)) {
|
|
643
|
+
fs.mkdirSync(rulesDir, { recursive: true });
|
|
644
|
+
}
|
|
645
|
+
fs.writeFileSync(rulesPath, EVERSTATE_RULES_CONTENT);
|
|
646
|
+
logSuccess("Created .claude/rules/everstate.md");
|
|
647
|
+
|
|
648
|
+
// Clean up: remove old <!-- everstate --> section from CLAUDE.md if present
|
|
649
|
+
const claudeMdPath = path.join(projectDir, "CLAUDE.md");
|
|
650
|
+
if (fs.existsSync(claudeMdPath)) {
|
|
651
|
+
const content = fs.readFileSync(claudeMdPath, "utf8");
|
|
652
|
+
if (content.includes(EVERSTATE_CLAUDE_MD_MARKER)) {
|
|
653
|
+
// Remove the old Everstate section (marker through end of section)
|
|
654
|
+
const markerIdx = content.indexOf(EVERSTATE_CLAUDE_MD_MARKER);
|
|
655
|
+
const cleaned = content.substring(0, markerIdx).trimEnd();
|
|
656
|
+
if (cleaned.length > 0) {
|
|
657
|
+
fs.writeFileSync(claudeMdPath, cleaned + "\n");
|
|
658
|
+
logSuccess("Removed old Everstate section from CLAUDE.md (moved to .claude/rules/)");
|
|
659
|
+
} else {
|
|
660
|
+
// CLAUDE.md was entirely the Everstate section — remove the file
|
|
661
|
+
fs.unlinkSync(claudeMdPath);
|
|
662
|
+
logSuccess("Removed CLAUDE.md (was only Everstate content, now in .claude/rules/)");
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
569
668
|
// ============================================================================
|
|
570
669
|
// Setup summary
|
|
571
670
|
// ============================================================================
|
|
@@ -679,6 +778,19 @@ async function runUpgrade(args: SetupArgs) {
|
|
|
679
778
|
logInfo("Updating hooks...");
|
|
680
779
|
await installHooks(projectDir, true);
|
|
681
780
|
|
|
781
|
+
// Also run auto-update to install any new hook types (gotcha-check, implicit-progress)
|
|
782
|
+
try {
|
|
783
|
+
const { checkAndApplyUpdates } = await import('./setup/auto-update.js');
|
|
784
|
+
const updateResult = await checkAndApplyUpdates();
|
|
785
|
+
if (updateResult.updates.length > 0) {
|
|
786
|
+
for (const update of updateResult.updates) {
|
|
787
|
+
logSuccess(update);
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
} catch {
|
|
791
|
+
// Auto-update is optional - don't fail upgrade if it errors
|
|
792
|
+
}
|
|
793
|
+
|
|
682
794
|
logInfo("Updating version file...");
|
|
683
795
|
const configData = readJsonFile(configPath);
|
|
684
796
|
const projectId = configData?.projectId;
|
|
@@ -833,7 +945,10 @@ export async function runSetup(argv: string[]) {
|
|
|
833
945
|
// ── Step 7: Update .gitignore ────────────────────────────────────
|
|
834
946
|
updateGitignore(projectDir);
|
|
835
947
|
|
|
836
|
-
// ── Step 8:
|
|
948
|
+
// ── Step 8: Create .claude/rules/everstate.md ─────────────────────
|
|
949
|
+
ensureClaudeMd(projectDir);
|
|
950
|
+
|
|
951
|
+
// ── Step 9: Write version file ───────────────────────────────────
|
|
837
952
|
const versionFile = createVersionFile("setup");
|
|
838
953
|
versionFile.projects[projectConfig.projectId] = {
|
|
839
954
|
projectId: projectConfig.projectId,
|