mirror of
https://github.com/rohitg00/agentmemory.git
synced 2026-09-14 20:16:33 +08:00
fix/engine-spawn-absolute-paths
17 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
37ea1b99ad |
feat: cursor marketplace plugin with hooks, mcp, and skills (#1213)
* feat: cursor marketplace plugin with native hooks and mcp config * fix: cursor payload compat and transcript prompt backfill in hooks * fix: plugin-root hook paths, backfill ordering, session-id fallbacks * docs: cursor plugin rows in readme, translations, and changelog * fix: cursor native-plugin card, broken agent logos * chore: sync openclaw and hermes plugin manifest versions * docs: openclaw hook permission and hermes tool count * chore: clawhub compat metadata for openclaw plugin * docs: tested openclaw and hermes install rows in readme |
||
|
|
9c82d2aa7d |
chore(release): v0.9.29 with project-scope parity across capture surfaces (#1141)
* chore(release): v0.9.29 with project-scope parity across surfaces Version trio + plugin manifests + supportedVersions + ExportData union bumped to 0.9.29; CHANGELOG entry covering everything since v0.9.28 with upgrade notes for the four visible behavior changes. Fixes the endpoint-count drift on main (130 registered routes vs docs saying 129 after #1132 landed in parallel with #1136). Project-scope parity: OpenCode plugin, Hermes plugin, Pi extension, and JSONL replay now resolve project the same way the hooks do (env override, git toplevel basename, cwd basename) instead of sending raw filesystem paths, closing #903 and #1135 and pre-empting the same bug in pi. The filesystem watcher accepts AGENTMEMORY_PROJECT_NAME with the old AGENTMEMORY_PROJECT kept as a deprecated alias, replay handles Windows-recorded paths, and OpenCode file enrichment matches the agent's lowercase tool names (the capitalized set never matched). Tests: opencode fallback expectations updated to basenames per the canonicalization, git-toplevel resolution covered with a fixture repo, new project-scope-parity suite for replay and fs-watcher. * fix(release): review findings, git-toplevel parity, doc counts - skills generator dedupes routes on method plus path, so the REST reference lists all 130 registered routes instead of hiding the second method on ten dual-method paths (header said 119) - fs-watcher trims AGENTMEMORY_PROJECT_NAME and the deprecated alias, treating whitespace as unset, and derives the git toplevel basename when watching a subdirectory - replay resolves the git toplevel basename when the recorded cwd still exists locally (memoized per cwd), keeping the basename fallback for historical or cross-platform paths; no env override here since a bulk import spans many projects - parity tests for replay git-root resolution, watcher git-root and trim behavior - stat-tests badge updated from 1428+ to 1550+ passing * fix(cli): refuse second-instance boot over a live daemon Closes the class behind issue 1140: agentmemory consolidate (or any unrecognized word) fell through the command table into the full server boot, registering a duplicate worker on the running engine; on iii 0.11.2 the second instance's shutdown tears down the daemon's HTTP trigger routing until a full engine restart. Unknown subcommands now error with the supported list, and main() probes livez on the resolved port and refuses to boot over a live daemon, so multi-instance setups on other ports are unaffected. Verified behaviorally against the built CLI: both paths refuse with exit 1. Also from review: the watcher stamps each event with its own root's project via a per-root map (an explicit config.project still overrides for every root), and replay only accepts a non-empty string cwd from parsed JSONL so malformed entries cannot reach the filesystem probe. * test(watcher): two-repository flush events scope to their own project * chore(release): bump packages/mcp, guard it, refresh CONTRIBUTING packages/mcp was still 0.9.28 after the release bump because nothing guarded it; a consistency test now pins it to package.json. CONTRIBUTING release list corrected to the files a bump actually touches (no tracked lockfile, the two extra plugin manifests, the export test derives from VERSION now), and the subsystems table gains src/cli, integrations/pi, and the generated-manifest note. * fix(export): refuse over-frame export instead of dropping the worker Closes the availability bug in issue 1142: GET /agentmemory/export assembles the full store and returns it through sdk.trigger, so a store whose serialized export passes the engine's 16 MiB WebSocket frame (tungstenite max_frame_size, not raisable under the 0.11.2 pin) dies on the worker->engine hop, drops the worker, and 404s every endpoint for ~1s. The session collections page on maxSessions/offset but ~18 others do not, so a large store hits this at any parameter combination. A shared frame-guard measures the serialized size before returning: mem::export returns a small oversized error instead of the giant object, and api::mesh-export returns 413 (same dead-end as #890). Either way the over-frame payload never crosses the boundary, so the daemon stays up and the failure is one clean request with a hint to narrow the range. Full pagination of the non-session collections is a follow-up. Layer 1 of the fix; verified with a synthetic oversized export returning the error object (tiny) rather than the payload. * ci: collapse to a single npm install to fix Node 24/26 CI The two-step install (npm install --package-lock-only then npm ci) failed only on the Node 24/26 matrix rows: their stricter npm rejects rolldown's optional platform bindings (@rolldown/binding-android-arm64) that a --package-lock-only pass does not fully enumerate. Lockfiles are gitignored, so npm ci re-validation buys no reproducibility here. A single lenient npm install resolves and installs in one pass. * fix(mesh): scope exported memories by project like actions api::mesh-export filtered actions by ?project but returned every project's memories. On a mesh instance federating one project to a peer, the peer pulled other projects' memories (cross-project leak), and those extras could push the payload past the 16 MiB transport frame into a 413 even when the requested project's own slice fit. Memories carry the same optional project field as actions, so filter both before the frame-size guard runs. Adds a regression test asserting a project-scoped export excludes other projects' memories and that an oversized memory in another project no longer 413s the scoped request. * chore(release): credit the Antigravity native hooks adapter in 0.9.29 notes * chore(release): sweep stale 0.9.28 refs for 0.9.29 Deploy Dockerfiles/compose/render pins, AGENTS.md stats header, opencode plugin manifest, website meta snapshot, test-count claims (1,428 -> 1,596) in README/AGENTS/stat SVGs, and the missing 0.9.29 CHANGELOG compare link. * chore(release): sync stat-tests badge to 1596+ and commit bridge exec bit * refactor: trim frame-guard comments and drop issue refs from code |
||
|
|
d38a1c6950 |
fix(hermes): seed AGENTMEMORY_URL default at import (closes #520) (#643)
Hermes was reporting agentmemory as Missing/not-available even when the service was running fine and live sessions could use it. Root cause: `hermes memory status` reads os.environ in the Hermes CLI process. When agentmemory is launched by systemd (or any process manager that loads ~/.agentmemory/.env via EnvironmentFile=), those values never reach the interactive shell. Our plugin already preloads ~/.agentmemory/.env via setdefault, but only catches uncommented key=value lines. Users whose .env file has AGENTMEMORY_URL commented out (because it matches the default http://localhost:3111) end up with the var unset, and Hermes reports Missing. Fix: after preload, os.environ.setdefault('AGENTMEMORY_URL', DEFAULT_BASE_URL). Guarantees the var is set to the documented default so Hermes status reflects the real runtime. Anything explicit from the shell or .env still wins (setdefault is no-op when value is present). AGENTMEMORY_SECRET stays untouched — it's optional per the config schema. |
||
|
|
c1c2c3a944 |
fix(hermes): declare all plugin hooks (#486)
* fix(hermes): declare all plugin hooks * test(hermes): compare manifest hooks to provider --------- Co-authored-by: honor2030 <19909783+honor2030@users.noreply.github.com> |
||
|
|
1c8713f978 | fix(hermes): is_available() must not do network calls (#377) | ||
|
|
57ffe91302 |
fix(hermes): use correct API keys tool_input/tool_output in sync_turn (#384)
The Hermes plugin's sync_turn() method sends conversation observations to the agentmemory /observe endpoint using keys 'input' and 'output', but the server's mem::observe handler extracts data using 'tool_input' and 'tool_output' (see src/functions/observe.ts). This key mismatch means raw.toolInput and raw.toolOutput are always undefined. When auto-compress is enabled, the LLM receives a nearly empty compression prompt (only timestamp + hookType + toolName), which produces generic, useless observations like: title: "Agent initiated conversation" narrative: "No specific content was provided" importance: 1 With the corrected keys, DeepSeek/Vision models receive the actual conversation content and produce meaningful, structured observations: title: "Verified fix for agentmemory plugin key naming" importance: 6 concepts: ["agentmemory plugin", "tool_input/tool_output key renaming"] facts: ["The fix replaces 'input'/'output' keys with..."] |
||
|
|
1a706ca2d6 |
fix(integrations): warn when bearer auth crosses plaintext HTTP to non-loopback (#315)
* fix(integrations): warn when bearer auth crosses plaintext HTTP to non-loopback (#275) Signed-off-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> * test(integrations/315): edge cases for IPv6 loopback + LAN IPs + lookalike hostnames + docs @mvanhorn's PR #315 lands the right plaintext-bearer-auth warn-once pattern across three runtimes (hermes/python, openclaw/mjs, pi/typescript). Reviewed cleanly. Adding test cases + docs before merge so the contract is locked: Test additions (test/integration-plaintext-http.test.ts pi suite, +4 cases, 13 total in suite): - IPv6 loopback (http://[::1]:3111) — URL parser strips brackets, hostname comes back as `::1`, the LOOPBACK_HOSTS set already covers this. Test pins the parsing semantic so a future refactor can't silently break it. - Private LAN IPs (RFC1918 ranges 192.168.x.y, 10.x.x.x) — NOT loopback, guard MUST warn. RFC1918 was a deliberate design choice (loopback set stays minimal: localhost / 127.0.0.1 / ::1). LAN deployment behind a tunnel still leaks the bearer over the wire. - No-secret short-circuit (guard with secret="" or undefined) — guard never fires when a bearer wouldn't actually be sent. Mirrors the usesPlaintextBearerAuth() early-return. - Lookalike hostname (http://localhost.evil.com:3111) — `parsed.hostname` returns the full `localhost.evil.com` string, which is NOT in LOOPBACK_HOSTS. Guard warns. This pins the exact-match (vs prefix) loopback semantic. Docs additions: - integrations/pi/README.md and integrations/hermes/README.md now document AGENTMEMORY_REQUIRE_HTTPS in the env-vars table — same row shape as AGENTMEMORY_SECRET, names the env value (=1), describes the warn-vs-throw semantic, and lists the loopback hostnames the guard recognises. No code changes to the guard itself — it's already correct. Pre-merge hardening only. 899 / 899 tests pass on rebased branch. Build clean. --------- Signed-off-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Co-authored-by: Rohit Ghumare <ghumare64@gmail.com> |
||
|
|
eaecc658d3 |
fix(hermes): serialize handle_tool_call returns to JSON string (closes #254) (#255)
Hermes stores handle_tool_call's return value as the tool result
`content` field in the session history. Anthropic-protocol LLM providers
reject non-string content on the next request with:
Failed to deserialize the JSON body into the target type:
messages[N]: content should be a string or a list at line 1 column XXXXX
Once triggered, every subsequent request in that session 400s until the
session JSON is manually cleaned.
The plugin's handle_tool_call returned raw Python dicts in all 4 paths
(memory_recall, memory_save, memory_search, unknown-tool fallback). Wrap
each return in json.dumps so the result is always a string.
This matches the contract that agentmemory's own MCP server already
honors in src/mcp/standalone.ts:
{ type: "text", text: JSON.stringify(payload, null, ...) }
Tightens the return-type annotation on both the abstract base and the
concrete class from Any -> str so mypy / type checkers catch any future
regression.
Reported by @KyoMio with full Anthropic-protocol repro.
|
||
|
|
c2f2618c74 |
fix(hermes): preload ~/.agentmemory/.env so status reflects service env (closes #250) (#253)
When agentmemory runs as a systemd user service (or any process manager that loads ~/.agentmemory/.env directly), the values never reach the shell that runs `hermes memory status`. Status then reads os.environ in the Hermes CLI process, finds AGENTMEMORY_URL / AGENTMEMORY_SECRET unset, and reports the plugin as "Missing" even though the service is healthy and live sessions can use it. Preload the documented config file at plugin-import time using os.environ.setdefault so anything explicitly set in the shell still wins. Best-effort: silently skip when the file is absent, unreadable, or malformed — the plugin falls back to its existing defaults. Both ~/.agentmemory/.env (primary, per agentmemory's own README) and $XDG_CONFIG_HOME/agentmemory/.env (fallback) are checked. Reported by @OptionalCoin. Tested: $ printf 'AGENTMEMORY_URL=http://example\nAGENTMEMORY_SECRET=s\n' \ > ~/.agentmemory/.env $ unset AGENTMEMORY_URL AGENTMEMORY_SECRET $ python -c "import sys; sys.path.insert(0, 'integrations'); \ import hermes; \ import os; \ print(os.environ['AGENTMEMORY_URL'])" http://example $ AGENTMEMORY_URL=http://shell-wins python -c "..." http://shell-wins # explicit shell value still wins |
||
|
|
2c24c9077e |
fix(hermes): accept passthrough kwargs in memory provider hooks (closes #249) (#252)
Hermes calls memory provider hooks with extra context kwargs (e.g. session_id) that the strict signatures rejected with: Memory provider 'agentmemory' sync_turn failed: AgentMemoryProvider. sync_turn() got an unexpected keyword argument 'session_id' Add **kwargs: Any to every hook so extra context fields are tolerated: sync_turn, on_session_end, on_pre_compress, on_memory_write, prefetch, queue_prefetch, shutdown. Mirror the same change on the abstract fallback MemoryProvider used when `agent.memory_provider` is unavailable at import time. Where Hermes passes session_id, prefer it over the cached self._session_id so per-turn observations land on the correct session when Hermes routes a hook through a different conversation than the one the provider was initialized with. Reported and locally verified by @OptionalCoin. |
||
|
|
2daeb5afda | Add tested Pi/OpenClaw/Hermes integration fixes (#230) | ||
|
|
8f44c3ddde |
docs(hermes): correct plugin install path
Hermes scans `~/.hermes/plugins/<name>/` flat. Memory category namespace (`memory/`) is reserved for bundled providers and won't discover user plugins nested under it. Closes #197 |
||
|
|
416fa15af4 |
chore: release 0.8.6 — scope the MCP shim as @agentmemory/mcp (#134)
0.8.5's publish workflow got blocked on the unscoped `agentmemory-mcp` name by npm's name-similarity policy (there's an unrelated third-party package called `agent-memory-mcp`). Publishing the shim under the `@agentmemory` scope we already own sidesteps the conflict. Changes: - Rename packages/agentmemory-mcp → packages/mcp - Package name: agentmemory-mcp → @agentmemory/mcp (0.8.4 → 0.8.6) - Keep bin name `agentmemory-mcp` so `npm i -g @agentmemory/mcp` still installs a binary at `agentmemory-mcp` for muscle memory - Log prefix [agentmemory-mcp] → [@agentmemory/mcp] in standalone.ts and in-memory-kv.ts - README / integrations/openclaw / integrations/hermes / src/cli.ts all point at `npx -y @agentmemory/mcp` - .github/workflows/publish.yml working-directory and npm view queries target packages/mcp and @agentmemory/mcp - Shim dependency on @agentmemory/agentmemory bumped to ~0.8.6 - Main package 0.8.5 → 0.8.6 across the 8 version files - CHANGELOG [0.8.6] entry documenting the scope move |
||
|
|
8a36fe7867 |
fix: retention scoring (#119) + npx agentmemory-mcp 404 (#120), release 0.8.3 (#123)
* fix: retention scoring (#119) + npx agentmemory-mcp 404 (#120), release 0.8.3 Issue #119 — retention score ignored agent-side reads `mem::retention-score` previously hardcoded `accessCount=0` and `accessTimestamps=[]` for episodic memories and used only a single-sample `lastAccessedAt` for semantic memories, so the time-frequency decay formula was a dead path. All read endpoints now record access events to a new `mem:access` KV namespace via a keyed-mutex'd access tracker: - mem::search, mem::smart-search (compact + expand), mem::context, mem::timeline, mem::file-context, mem::get-related, mem::working-context - retention.ts pre-fetches the full access log in one kv.list call, normalizes every row defensively, and builds an O(1) lookup Map - recordAccessBatch uses Promise.allSettled so a slow keyed-lock on one id does not block the rest of the batch - Bounded ring buffer of the last 20 access timestamps per memory - Backwards-compat fallback: pre-0.8.3 semantic memories with only the legacy sem.lastAccessedAt still score correctly - Corrupt lastAccessedAt values are NaN-safe via Date.parse + isFinite - reinforcementBoost is reported as the raw formula output, not the clamped residual Memory deletion sites (retention-evict, evict, auto-forget, governance-delete, governance-bulk, forget, import replace) now call deleteAccessLog to prevent mem:access from accumulating zombie entries. mem::export / mem::import and mem::snapshot-create / mem::snapshot-restore round-trip the new namespace so backup/restore cycles no longer zero out reinforcement signals. Issue #120 — npx agentmemory-mcp returned npm registry 404 The README instructed users to run `npx agentmemory-mcp`, but `agentmemory-mcp` only existed as a `bin` entry inside `@agentmemory/agentmemory`, not a real registry package. Two-part fix: - New sibling package `packages/agentmemory-mcp/` — a thin shim that depends on `@agentmemory/agentmemory` (~0.8.3, tilde to block 0.9.x supply-chain drift) and forwards to dist/standalone.mjs via the new `exports` field on the main package - Canonical `npx @agentmemory/agentmemory mcp` subcommand on the CLI for users who already have the main package installed - Removed the dead `agentmemory-mcp` bin from the main package so the shim owns the name unambiguously - publish.yml publishes both packages in order with idempotent guards and npm-view registry polling (no more fixed sleep) - All MCP install snippets in README + integrations/openclaw + hermes + shim README use `npx -y agentmemory-mcp` to skip install prompts Release 0.8.3 - 670 tests passing (665 + 11 new: access tracker, retention, smart-search integration, corrupt-input, kv.list failure path, Promise.allSettled resilience) - Version bumped across package.json, src/version.ts, types.ts, export-import supportedVersions, plugin.json - package-lock.json regenerated * fix: address CodeRabbit review feedback on #123 Real issues caught and fixed: - access-tracker: deleteAccessLog now takes the same mem:access:<id> keyed mutex used by recordAccess, eliminating the race where a concurrent delete could drop an in-flight RMW update and leave a stale access log for an evicted memory - access-tracker: normalizeAccessLog now coerces count to a non-negative integer, drops non-finite recent[] entries, truncates recent[] to the last 20 on read (enforcing the ring-buffer invariant), and guarantees count >= recent.length so a malformed row can't produce NaN downstream. count is NOT capped at 20 — it is the lifetime access counter, while recent[] is the 20-entry window - export-import: import path now rejects accessLogs arrays above MAX_ACCESS_LOGS (50_000), normalizes each entry via normalizeAccessLog, and drops entries whose memoryId is not in the imported memories set, so a crafted export can't blow up memory or resurrect zombie access rows for memories that don't exist - publish.yml: added a post-publish npm view polling loop for agentmemory-mcp mirroring the one that already guards the main package, so the workflow only succeeds when `npx agentmemory-mcp` is actually visible on the registry - CHANGELOG.md: added the missing [0.8.3] reference-style link target at the bottom to match the [0.8.2]/[0.8.1]/[0.8.0] pattern - README.md: standalone MCP inline examples now use `npx -y` to match the MCP config snippets and skip the install confirmation prompt Tests: 680/680 (+10 new — deleteAccessLog behavior, normalizeAccessLog invariants, malformed mem:access row handling in retention scoring). Findings deliberately not applied: - auto-forget.ts / remember.ts / evict.ts recordAudit calls: existing pattern in the codebase only audits governance deletes (user-initiated admin actions), not automatic eviction. Adding audit everywhere is a policy change, out of scope for this PR - evict.ts gating deleteAccessLog on memory delete success: current order is defensible, deleteAccessLog is already best-effort with its own try/catch, and calling it after a failed memory delete is harmless - snapshot.ts fail-fast on kv.list failure: inconsistent with the existing .catch(() => []) pattern used for observations in the same function - retention.ts semantic evict only deletes KV.memories rows: real bug but pre-existing on main (RetentionScore has no source/type field). Tracked separately — out of scope for this PR - bin.mjs fallback command: already present in the existing catch handler - Promise.all parallelization of delete+deleteAccessLog: micro optimization not worth the readability cost |
||
|
|
79a7a8ec04 |
feat: real agent logos + paste-this-prompt blocks for integrations (#114)
* feat: flashy README with real agent logos + paste-this-prompt blocks for integrations ## Main README — real logos in Supported Agents grid Replaced plain text cells with real brand logos for all 16 supported agents: - simple-icons CDN for: Claude Code (Anthropic), Cursor, Gemini CLI (Google Gemini), Codex CLI (OpenAI), Windsurf, Claude Desktop, Claude SDK - GitHub org avatars for: OpenClaw, OpenCode (opencode-ai), Cline, Hermes (NousResearch), Goose (block), Kilo Code (kilo-org), Aider (Aider-AI), Roo Code (RooCodeInc) - Shield badge for the generic "Any agent" cell Each logo is clickable and links to the upstream project. The OpenClaw and Hermes cells now link directly to integrations/openclaw and integrations/hermes so users can find the deeper plugin integration. Added tagline footer below the grid reinforcing the cross-agent story. ## Integration READMEs — paste-this-prompt blocks Following the gstack pattern, both integration READMEs now open with a visual hero (upstream logo + agentmemory logo) and a copy-pasteable text block the user can drop into their agent. The agent handles the entire setup — start server, update MCP config, verify health, open viewer. This matches the "paste this into Claude Code" block we already have in the main README for Claude Code users. ### openclaw/README.md - Centered hero: OpenClaw org avatar + agentmemory icon - Shield badges: 43 MCP tools, 4 lifecycle hooks, 95.2% R@5, self-hosted - "Install it in 30 seconds" section with the paste-this prompt ### hermes/README.md - Centered hero: NousResearch avatar + agentmemory icon - Shield badges: 43 MCP tools, 6 lifecycle hooks, 95.2% R@5, self-hosted - "Install it in 30 seconds" section with the paste-this prompt All 654 tests still passing. * fix: reorder agents, replace broken logos, add OpenClaw/Hermes paste blocks, cleaner hero ## Main README ### Supported Agents grid — 3 fixes 1. **Reorder**: OpenClaw and Hermes now in positions 2 and 3 (right after Claude Code), since they have first-class gateway plugins in integrations/. Users shouldn't have to scroll to find them. 2. **Fix broken Codex logo**: simple-icons CDN returned 404 for the OpenAI slug with black color. Switched ALL logos to GitHub org avatars (github.com/<org>.png?size=120) which are bulletproof and always return real images. Verified 7/7 resolve to actual PNGs. 3. **Bigger logos**: bumped from 40px to 48px for more visual weight. ### Paste-this-prompt toggles Added two collapsible <details> blocks after the Claude Code paste prompt: one for OpenClaw, one for Hermes. Each contains a complete copy-pasteable setup prompt that the agent can execute, plus a link to the full integration guide. ## Integration README heroes — redesigned The old hero had two logos separated by an ugly gray "+" shield badge that looked cheap. Replaced with: - agentmemory banner.png as the centered hero image - H1 title with a small inline upstream logo (28px) next to the title - Bolded tagline + subtitle with upstream link - Shield badge row (MCP tools, hooks, R@5, self-hosted, license) Much cleaner and follows the main README's visual pattern. Verified: 654/654 tests passing. * Update README.md * feat: custom SVG tags for section headers (no emojis) Replaces emoji section headers with custom SVG badges matching the agentmemory brand style (orange #FF6B35 accent on dark #1A1A1A). Inspired by shanraisshan/claude-code-best-practice's custom tag approach in its !/ directory. ## Custom SVG tags created (30 total in assets/tags/) ### 14 section headers (section-*.svg) Each is a 44px-tall dark rounded badge with: - Orange gradient accent strip on the left (brand color #FF6B35 → #FF8F5E) - Uppercase title in white, 800 weight, 2.2 letter-spacing - Light gray subtitle (#9CA3AF) with section context - Subtle #2A2A2A border on dark #1A1A1A → #0F0F0F gradient Sections: works-with-every-agent, benchmarks, vs-competitors, quick-start, why, how-it-works, search, mcp-server, real-time-viewer, configuration, api, architecture, development, license. ### 6 hero stat blocks (stat-*.svg) Big numbers with small uppercase labels, replacing the shield.io badge row in two places (hero + benchmarks section): - stat-recall: 95.2% R@5 (green) - stat-tokens: 92% fewer tokens (green) - stat-tools: 43 MCP tools (orange) - stat-hooks: 12 auto hooks (orange) - stat-deps: 0 external DBs (purple) - stat-tests: 654 tests passing (green) ### 8 pill tags (pill-*.svg) Rounded pills with colored dot indicator for inline status tags: MCP, AUTO HOOK, SKILL, NEW, BETA, STABLE, PLUGIN, SECURE. ### 1 "New in v0.8.2" version tag Dark pill with orange v0.8.2 version marker. ### 1 section divider Horizontal line with orange diamond in the middle (unused for now, available for future sections). ## README changes - All <h2> section headers now use <img> tags pointing to the SVG - Hero stats row replaced with stat-*.svg row (same visual position) - Benchmarks stats row replaced with the same stat-*.svg row - Nav links updated to match the new h2 anchor IDs - "New in v0.8.2" callout uses new-v082.svg tag + note - Cursor grid cell fixed (was missing <strong>Cursor</strong> label) - Zero emojis in the entire README All 30 SVGs validated with xmllint, 654/654 tests passing. * Remove version 0.8.2 image from README Removed image tag for version 0.8.2 from README. |
||
|
|
9173b090f4 |
fix: address review findings on Hermes plugin
- SSRF prevention: validate URL scheme (http/https only) before urlopen - on_pre_compress: inject fetched context into messages list (was no-op) - Remove unused self._secret; _api reads from env directly |
||
|
|
112e6f4bc0 |
feat: add Hermes Agent memory provider plugin
Two integration paths: 1. MCP server (zero code) - add to ~/.hermes/config.yaml 2. Memory provider plugin (deeper) - hooks into Hermes agent loop Plugin implements the full MemoryProvider ABC: - prefetch() injects relevant memories before each LLM call - sync_turn() captures conversation turns in background (non-blocking) - on_session_end() marks sessions for summarization - on_pre_compress() re-injects context before compaction - on_memory_write() mirrors MEMORY.md writes - system_prompt_block() injects project profile - 3 tools: memory_recall, memory_save, memory_search Uses only stdlib (urllib, json, threading). No new dependencies. |