hipocampus
Advanced tools
+48
-1
@@ -123,3 +123,8 @@ #!/usr/bin/env node | ||
| copyTemplate("USER.md"); | ||
| copyTemplate("HEARTBEAT.md"); | ||
| // HEARTBEAT.md uses marker-based replacement (see Step 7b below) | ||
| const heartbeatDest = join(CWD, "HEARTBEAT.md"); | ||
| if (!existsSync(heartbeatDest)) { | ||
| copyFileSync(join(ROOT, "templates", "HEARTBEAT.md"), heartbeatDest); | ||
| console.log(" + HEARTBEAT.md"); | ||
| } | ||
| } | ||
@@ -501,2 +506,44 @@ | ||
| appendCompactionRoot(); | ||
| // ── HEARTBEAT.md marker-based update ── | ||
| const heartbeatDest = join(CWD, "HEARTBEAT.md"); | ||
| if (existsSync(heartbeatDest)) { | ||
| const HB_MARKER_START = "<!-- hipocampus:heartbeat:start -->"; | ||
| const HB_MARKER_END = "<!-- hipocampus:heartbeat:end -->"; | ||
| const templateContent = readFileSync(join(ROOT, "templates", "HEARTBEAT.md"), "utf8"); | ||
| // Extract the hipocampus section from template (between markers) | ||
| const markerRe = new RegExp( | ||
| HB_MARKER_START.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") | ||
| + "[\\s\\S]*?" | ||
| + HB_MARKER_END.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") | ||
| ); | ||
| const templateMatch = templateContent.match(markerRe); | ||
| if (templateMatch) { | ||
| let hbContent = readFileSync(heartbeatDest, "utf8"); | ||
| if (hbContent.includes(HB_MARKER_START)) { | ||
| // Replace existing marked section | ||
| hbContent = hbContent.replace(markerRe, templateMatch[0]); | ||
| writeFileSync(heartbeatDest, hbContent); | ||
| console.log(" + HEARTBEAT.md hipocampus section updated"); | ||
| } else if (hbContent.includes("Hipocampus Compaction Maintenance")) { | ||
| // Legacy: replace old section (from "## 1. Hipocampus" to next "## " or "HEARTBEAT_OK") | ||
| const legacyRe = /## 1\. Hipocampus Compaction Maintenance[\s\S]*?(?=\n## (?!#)|HEARTBEAT_OK)/; | ||
| if (legacyRe.test(hbContent)) { | ||
| hbContent = hbContent.replace(legacyRe, templateMatch[0] + "\n\n"); | ||
| writeFileSync(heartbeatDest, hbContent); | ||
| console.log(" + HEARTBEAT.md hipocampus section updated (legacy migration)"); | ||
| } | ||
| } else { | ||
| // No hipocampus section at all — inject after the header | ||
| const headerEnd = hbContent.indexOf("\n\n"); | ||
| if (headerEnd !== -1) { | ||
| hbContent = hbContent.slice(0, headerEnd + 2) + templateMatch[0] + "\n\n" + hbContent.slice(headerEnd + 2); | ||
| } else { | ||
| hbContent = hbContent + "\n\n" + templateMatch[0] + "\n"; | ||
| } | ||
| writeFileSync(heartbeatDest, hbContent); | ||
| console.log(" + HEARTBEAT.md hipocampus section injected"); | ||
| } | ||
| } | ||
| } | ||
| } else { | ||
@@ -503,0 +550,0 @@ // ── Claude Code path ── |
+1
-1
| { | ||
| "name": "hipocampus", | ||
| "version": "0.3.1", | ||
| "version": "0.3.2", | ||
| "description": "Drop-in memory harness for AI agents — 3-tier memory, compaction tree, hybrid search via qmd", | ||
@@ -5,0 +5,0 @@ "type": "module", |
@@ -5,2 +5,3 @@ # Heartbeat Checklist | ||
| <!-- hipocampus:heartbeat:start --> | ||
| ## 1. Hipocampus Compaction Maintenance | ||
@@ -11,3 +12,3 @@ | ||
| 1. Search `memory/daily/`, `memory/weekly/`, `memory/monthly/` for files containing `needs-summarization` | ||
| 2. If found: generate LLM keyword-dense summaries per `.claude/skills/hipocampus-compaction/SKILL.md` using subagents | ||
| 2. If found: generate LLM keyword-dense summaries per `skills/hipocampus-compaction/SKILL.md` using subagents | ||
| - Read source files listed in each node's frontmatter | ||
@@ -21,2 +22,3 @@ - Generate summary, update status from `needs-summarization` to `tentative` or `fixed` | ||
| Skip this section if no `needs-summarization` files exist. | ||
| <!-- hipocampus:heartbeat:end --> | ||
@@ -23,0 +25,0 @@ ## 2. (Add your own heartbeat tasks below) |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
158136
1.54%1105
4.34%