@everstateai/mcp 1.3.12 → 1.3.14
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 +470 -15
- 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 +98 -8
- package/dist/setup.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +514 -17
- 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 +113 -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
|
|
@@ -565,7 +604,7 @@ async function createProjectConfig(
|
|
|
565
604
|
|
|
566
605
|
function updateGitignore(projectDir: string) {
|
|
567
606
|
const gitignorePath = path.join(projectDir, ".gitignore");
|
|
568
|
-
const entries = ["# Everstate", ".claude/settings.local.json", ".claude/hooks/"];
|
|
607
|
+
const entries = ["# Everstate", ".claude/settings.local.json", ".claude/hooks/", ".claude/rules/"];
|
|
569
608
|
|
|
570
609
|
let content = fs.existsSync(gitignorePath) ? fs.readFileSync(gitignorePath, "utf8") : "";
|
|
571
610
|
const toAdd = entries.filter((e) => !content.includes(e.replace("# Everstate", "")));
|
|
@@ -576,6 +615,56 @@ function updateGitignore(projectDir: string) {
|
|
|
576
615
|
}
|
|
577
616
|
}
|
|
578
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
|
+
|
|
579
668
|
// ============================================================================
|
|
580
669
|
// Setup summary
|
|
581
670
|
// ============================================================================
|
|
@@ -689,6 +778,19 @@ async function runUpgrade(args: SetupArgs) {
|
|
|
689
778
|
logInfo("Updating hooks...");
|
|
690
779
|
await installHooks(projectDir, true);
|
|
691
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
|
+
|
|
692
794
|
logInfo("Updating version file...");
|
|
693
795
|
const configData = readJsonFile(configPath);
|
|
694
796
|
const projectId = configData?.projectId;
|
|
@@ -843,7 +945,10 @@ export async function runSetup(argv: string[]) {
|
|
|
843
945
|
// ── Step 7: Update .gitignore ────────────────────────────────────
|
|
844
946
|
updateGitignore(projectDir);
|
|
845
947
|
|
|
846
|
-
// ── Step 8:
|
|
948
|
+
// ── Step 8: Create .claude/rules/everstate.md ─────────────────────
|
|
949
|
+
ensureClaudeMd(projectDir);
|
|
950
|
+
|
|
951
|
+
// ── Step 9: Write version file ───────────────────────────────────
|
|
847
952
|
const versionFile = createVersionFile("setup");
|
|
848
953
|
versionFile.projects[projectConfig.projectId] = {
|
|
849
954
|
projectId: projectConfig.projectId,
|