Skip to content

Add Claude Code skills Memanto bridge example#581

Closed
aindrewkwk wants to merge 2 commits into
moorcheh-ai:mainfrom
aindrewkwk:feat/claudecode-skills-memanto-aindrew
Closed

Add Claude Code skills Memanto bridge example#581
aindrewkwk wants to merge 2 commits into
moorcheh-ai:mainfrom
aindrewkwk:feat/claudecode-skills-memanto-aindrew

Conversation

@aindrewkwk

@aindrewkwk aindrewkwk commented May 28, 2026

Copy link
Copy Markdown

/claim #508

Bounty: https://www.bountyhub.dev/bounty/view/3a63800c-7c18-41d2-870f-c62344f8a3fe

What it adds:

  • examples/claudecode-skills-memanto, a Claude Code Skills-style memory bridge for Memanto.
  • pre hook: recalls task/path-relevant engineering memory before a skill starts.
  • post hook: distills completed skill output into durable project memory.
  • Credential-free local JSONL backend for review and tests, plus live Memanto backend via MEMANTO_SKILLS_BACKEND=memanto.
  • Session A/B demo showing one skill storing a Stripe webhook architecture decision and a later /tdd session receiving it as injected context.

Social showcase:

Validation run locally:

  • uv run python -m py_compile examples/claudecode-skills-memanto/memanto_skills.py examples/claudecode-skills-memanto/run_session_a.py examples/claudecode-skills-memanto/run_session_b.py
  • uv run pytest examples/claudecode-skills-memanto/tests -q
  • uv run ruff check examples/claudecode-skills-memanto
  • uv run ruff format --check examples/claudecode-skills-memanto
  • uv run python examples/claudecode-skills-memanto/run_session_a.py && uv run python examples/claudecode-skills-memanto/run_session_b.py

Summary by CodeRabbit

  • New Features

    • Added an example that captures post-session memories and injects relevant pre-session context using configurable local or remote backends.
  • Documentation

    • Added detailed setup, configuration, and demo instructions for running the memory bridge example.
  • Tests

    • Added tests covering memory capture, context injection, isolation cases, robustness to corrupted stores, and decision-vs-session-content handling.
  • Chores

    • Included example configuration template and updated ignore rules for local store files.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 42bbc141-63c7-44f0-8b13-15e41d0bd291

📥 Commits

Reviewing files that changed from the base of the PR and between a4a606f and 0a9f909.

📒 Files selected for processing (5)
  • examples/claudecode-skills-memanto/README.md
  • examples/claudecode-skills-memanto/memanto_skills.py
  • examples/claudecode-skills-memanto/run_session_a.py
  • examples/claudecode-skills-memanto/run_session_b.py
  • examples/claudecode-skills-memanto/tests/test_memanto_skills.py
✅ Files skipped from review due to trivial changes (1)
  • examples/claudecode-skills-memanto/README.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • examples/claudecode-skills-memanto/run_session_b.py
  • examples/claudecode-skills-memanto/run_session_a.py
  • examples/claudecode-skills-memanto/memanto_skills.py

📝 Walkthrough

Walkthrough

This PR adds an example project that bridges Claude Code skills and Memanto: a SkillMemory model, pluggable backends (local JSONL and Memanto SDK), API functions to recall and persist memories (pre/post hooks), a CLI, example session scripts, configuration files, and tests.

Changes

Claude Code Skills Memanto Memory Bridge

Layer / File(s) Summary
Memory data model and backend interface
examples/claudecode-skills-memanto/memanto_skills.py (init, 20–35)
SkillMemory dataclass with memory type, title, content, skill/path context and confidence; MemoryBackend protocol with remember() and recall(); dotenv loading and default constants.
Backend implementations and factory
examples/claudecode-skills-memanto/memanto_skills.py (36–136)
LocalJsonlBackend appends/reads JSONL and ranks recalls by token overlap; MemantoBackend wraps the Memanto SDK to create/activate agents, remember and recall items; build_backend() chooses and validates the backend from env.
Memory access API and distillation logic
examples/claudecode-skills-memanto/memanto_skills.py (138–246)
pre_skill_context() builds queries and formats recalled memories; post_skill_capture() distills transcript into a SkillMemory and persists it; distill_engineering_memory() detects explicit decisions via regex or falls back to first-sentence preferences; helper utilities handle tokenization and tolerant JSONL parsing.
CLI and example usage scripts
examples/claudecode-skills-memanto/memanto_skills.py, run_session_a.py, run_session_b.py
Argparse main() with pre and post commands; module entrypoint; run_session_a.py demonstrates storing a memory; run_session_b.py demonstrates retrieving pre-skill context.
Configuration, dependencies, and documentation
requirements.txt, .env.example, .gitignore, README.md
New requirements.txt (memanto, python-dotenv, pytest); .env.example with MOORCHEH_API_KEY, MEMANTO_AGENT_ID, MEMANTO_SKILLS_BACKEND, MEMANTO_SKILLS_STORE; .gitignore excludes local JSONL store; README documents setup and demo workflow.
Test infrastructure and functional tests
tests/conftest.py, tests/test_memanto_skills.py
conftest.py adjusts sys.path for imports; tests cover cross-skill round-trip, isolation, single-shared-token non-injection, empty-query handling, corrupted JSONL resilience, and prompt-classification behavior.

Sequence Diagram

sequenceDiagram
  participant Skill
  participant pre_skill_context
  participant Backend
  participant post_skill_capture
  participant distill_engineering_memory
  Skill->>pre_skill_context: (skill, prompt, path_hint)
  pre_skill_context->>Backend: recall(query, limit=3)
  Backend-->>pre_skill_context: list[SkillMemory]
  pre_skill_context-->>Skill: formatted_context
  Skill->>post_skill_capture: (skill, prompt, transcript, path_hint)
  post_skill_capture->>distill_engineering_memory: (skill, prompt, transcript, path_hint)
  distill_engineering_memory-->>post_skill_capture: SkillMemory
  post_skill_capture->>Backend: remember(memory)
  Backend-->>post_skill_capture: persisted
  post_skill_capture-->>Skill: SkillMemory
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A bridge of memories, oh how it springs!
From post-skill transcripts to pre-skill wings,
Local files or cloud agents hum along,
Tokens whisper what the past held strong,
Engineers recall, and the sessions sing.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding a Memanto bridge example for Claude Code skills.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@aindrewkwk

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (6)
examples/claudecode-skills-memanto/run_session_b.py (2)

6-6: Consider adding a docstring.

A brief docstring would clarify what this example demonstrates and how it relates to Session A.

📝 Suggested docstring
 def main() -> None:
+    """Demonstrate pre-skill context retrieval (Session B).
+    
+    Retrieves the Stripe webhook architecture decision stored by
+    Session A when working on a related /tdd task in the same path.
+    """
     backend = build_backend()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/claudecode-skills-memanto/run_session_b.py` at line 6, Add a one- or
two-line docstring to the top of the main() function explaining what this
example demonstrates (e.g., what the script does, how it relates to Session A,
and any expected inputs/outputs or behaviors) so readers quickly understand the
purpose of run_session_b.py; locate the top of the main() function and insert
the docstring immediately after def main() -> None: (referencing the main
function) following standard Python triple-quoted string conventions.

6-15: ⚡ Quick win

Consider adding error handling for robustness.

Like Session A, this script would benefit from try-except blocks around build_backend() and pre_skill_context() to handle potential failures gracefully and demonstrate best practices.

🛡️ Suggested error handling pattern
 def main() -> None:
-    backend = build_backend()
-    context = pre_skill_context(
-        backend=backend,
-        skill="/tdd",
-        prompt="Add tests for Stripe webhook retries.",
-        path_hint="services/payments",
-    )
-    print("Session B injected context:")
-    print(context or "No relevant engineering memory found.")
+    try:
+        backend = build_backend()
+        context = pre_skill_context(
+            backend=backend,
+            skill="/tdd",
+            prompt="Add tests for Stripe webhook retries.",
+            path_hint="services/payments",
+        )
+        print("Session B injected context:")
+        print(context or "No relevant engineering memory found.")
+    except Exception as e:
+        print(f"Error retrieving context: {e}")
+        raise
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/claudecode-skills-memanto/run_session_b.py` around lines 6 - 15,
Wrap the backend creation and context injection in try/except blocks inside main
to handle failures from build_backend() and pre_skill_context(); specifically,
catch exceptions raised by build_backend() and log/print a clear error message
including exception details and exit or return early, then similarly wrap
pre_skill_context() to report errors and avoid printing an invalid context;
ensure you reference the existing main, build_backend, and pre_skill_context
symbols and keep behavior consistent with Session A (graceful failure,
informative error output).
examples/claudecode-skills-memanto/run_session_a.py (2)

6-6: Consider adding a docstring.

Adding a brief docstring would help users understand what this example demonstrates.

📝 Suggested docstring
 def main() -> None:
+    """Demonstrate post-skill memory capture (Session A).
+    
+    Stores a Stripe webhook architecture decision that will be
+    retrieved by Session B when working on related tasks.
+    """
     backend = build_backend()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/claudecode-skills-memanto/run_session_a.py` at line 6, Add a concise
docstring to the main function to explain what this example demonstrates and how
to run it; specifically, update the def main() function by inserting a short
triple-quoted docstring immediately under the signature (e.g., one- to
three-line description of the example's purpose, inputs/outputs if any, and
usage) so readers understand the example without inspecting the implementation.

6-20: ⚡ Quick win

Consider adding error handling for robustness.

The script lacks try-except blocks around build_backend() and post_skill_capture(). For example code, wrapping these calls in error handling would make the script more robust and educational by demonstrating proper error management patterns.

🛡️ Suggested error handling pattern
 def main() -> None:
-    backend = build_backend()
-    memory = post_skill_capture(
-        backend=backend,
-        skill="/grill-with-docs",
-        prompt="Review the payments service architecture.",
-        transcript=(
-            "Decision: use a repository layer for Stripe webhook persistence. "
-            "Keep webhook signature verification at the HTTP boundary and store "
-            "only normalized event records under services/payments."
-        ),
-        path_hint="services/payments",
-    )
-    print("Session A stored memory:")
-    print(f"- {memory.title}: {memory.content}")
+    try:
+        backend = build_backend()
+        memory = post_skill_capture(
+            backend=backend,
+            skill="/grill-with-docs",
+            prompt="Review the payments service architecture.",
+            transcript=(
+                "Decision: use a repository layer for Stripe webhook persistence. "
+                "Keep webhook signature verification at the HTTP boundary and store "
+                "only normalized event records under services/payments."
+            ),
+            path_hint="services/payments",
+        )
+        print("Session A stored memory:")
+        print(f"- {memory.title}: {memory.content}")
+    except Exception as e:
+        print(f"Error capturing memory: {e}")
+        raise
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/claudecode-skills-memanto/run_session_a.py` around lines 6 - 20, The
script calls build_backend() and post_skill_capture() in main() without error
handling; wrap those calls in a try/except block inside main (or separate
try/except around each call) to catch exceptions, log or print a concise error
message, and exit or re-raise as appropriate; locate the calls to build_backend
and post_skill_capture in the main function and ensure exceptions include
context (e.g., "failed to build backend" or "failed to store memory") so
failures are handled cleanly for this example script.
examples/claudecode-skills-memanto/README.md (2)

16-27: 💤 Low value

Consider adding .gitignore to the file listing.

The directory structure omits .gitignore, which is part of this PR and helps reviewers understand the complete project layout.

📝 Suggested addition
 examples/claudecode-skills-memanto/
 ├── README.md
 ├── requirements.txt
 ├── .env.example
+├── .gitignore
 ├── memanto_skills.py
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/claudecode-skills-memanto/README.md` around lines 16 - 27, Update
the examples/claudecode-skills-memanto/ README.md tree to include the .gitignore
entry so the project layout matches the PR; edit the code block in README.md
(the directory listing) to add a line for ".gitignore" (e.g., between
.env.example and memanto_skills.py) and ensure the actual .gitignore file is
present in the repo so the README and repository contents stay in sync.

83-89: 💤 Low value

Consider documenting ruff validation mentioned in PR description.

The PR description lists "ruff check/format" as validation commands, but the README only mentions pytest and py_compile. Including ruff commands would provide complete validation coverage.

📝 Suggested addition
 ```bash
 cd examples/claudecode-skills-memanto
 python -m pytest tests -q
 python -m py_compile memanto_skills.py run_session_a.py run_session_b.py
+ruff check .
+ruff format --check .
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @examples/claudecode-skills-memanto/README.md around lines 83 - 89,
Validation section in README.md omits the ruff lint/format checks referenced in
the PR description; update the Validation block in
examples/claudecode-skills-memanto/README.md to include the ruff commands (e.g.,
add "ruff check ." and "ruff format --check .") alongside the existing pytest
and python -m py_compile commands that target memanto_skills.py,
run_session_a.py and run_session_b.py so the README reflects full validation
steps.


</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @examples/claudecode-skills-memanto/memanto_skills.py:

  • Around line 55-57: The current recall logic treats any single shared token as
    a match (score = len(query_terms & _tokens(haystack))) which allows common words
    to trigger unrelated memories; update the matching in both places where this
    appears (the score calculation and append to scored involving query_terms,
    _tokens(haystack), score, and memory) to require a stricter threshold (e.g.,
    require score >= 2 or score >= max(1, int(len(query_terms) * 0.3))) before
    appending to scored so that at least multiple or a meaningful proportion of
    query tokens must overlap to qualify as a memory match.
  • Around line 65-68: The JSONL parsing in the loop that builds memories (using
    self.path.read_text, json.loads and SkillMemory(**...)) should be guarded so a
    single corrupted/truncated line doesn't raise and abort recall; wrap the
    per-line parsing and dataclass construction in a try/except (catch
    json.JSONDecodeError and ValueError/TypeError from SkillMemory construction),
    skip the bad line on exception (optionally log a warning with the offending
    line), and continue appending only successfully parsed SkillMemory instances to
    memories.
  • Around line 170-172: Explicit decision extraction currently concatenates
    prompt and transcript (text = f"{prompt}\n{transcript}") before calling
    _find_explicit_decision, which can surface prompt phrasing as a decision; change
    the call to run _find_explicit_decision against the transcript only (e.g., pass
    transcript or set text = transcript) so that only session output is analyzed;
    update references to text/explicit accordingly (look for variable text, the
    function _find_explicit_decision, and the prompt/transcript variables) and
    ensure no prompt content is included in the explicit decision check.

Nitpick comments:
In @examples/claudecode-skills-memanto/README.md:

  • Around line 16-27: Update the examples/claudecode-skills-memanto/ README.md
    tree to include the .gitignore entry so the project layout matches the PR; edit
    the code block in README.md (the directory listing) to add a line for
    ".gitignore" (e.g., between .env.example and memanto_skills.py) and ensure the
    actual .gitignore file is present in the repo so the README and repository
    contents stay in sync.
  • Around line 83-89: Validation section in README.md omits the ruff lint/format
    checks referenced in the PR description; update the Validation block in
    examples/claudecode-skills-memanto/README.md to include the ruff commands (e.g.,
    add "ruff check ." and "ruff format --check .") alongside the existing pytest
    and python -m py_compile commands that target memanto_skills.py,
    run_session_a.py and run_session_b.py so the README reflects full validation
    steps.

In @examples/claudecode-skills-memanto/run_session_a.py:

  • Line 6: Add a concise docstring to the main function to explain what this
    example demonstrates and how to run it; specifically, update the def main()
    function by inserting a short triple-quoted docstring immediately under the
    signature (e.g., one- to three-line description of the example's purpose,
    inputs/outputs if any, and usage) so readers understand the example without
    inspecting the implementation.
  • Around line 6-20: The script calls build_backend() and post_skill_capture() in
    main() without error handling; wrap those calls in a try/except block inside
    main (or separate try/except around each call) to catch exceptions, log or print
    a concise error message, and exit or re-raise as appropriate; locate the calls
    to build_backend and post_skill_capture in the main function and ensure
    exceptions include context (e.g., "failed to build backend" or "failed to store
    memory") so failures are handled cleanly for this example script.

In @examples/claudecode-skills-memanto/run_session_b.py:

  • Line 6: Add a one- or two-line docstring to the top of the main() function
    explaining what this example demonstrates (e.g., what the script does, how it
    relates to Session A, and any expected inputs/outputs or behaviors) so readers
    quickly understand the purpose of run_session_b.py; locate the top of the main()
    function and insert the docstring immediately after def main() -> None:
    (referencing the main function) following standard Python triple-quoted string
    conventions.
  • Around line 6-15: Wrap the backend creation and context injection in
    try/except blocks inside main to handle failures from build_backend() and
    pre_skill_context(); specifically, catch exceptions raised by build_backend()
    and log/print a clear error message including exception details and exit or
    return early, then similarly wrap pre_skill_context() to report errors and avoid
    printing an invalid context; ensure you reference the existing main,
    build_backend, and pre_skill_context symbols and keep behavior consistent with
    Session A (graceful failure, informative error output).

</details>

<details>
<summary>🪄 Autofix (Beta)</summary>

Fix all unresolved CodeRabbit comments on this PR:

- [ ] <!-- {"checkboxId": "4b0d0e0a-96d7-4f10-b296-3a18ea78f0b9"} --> Push a commit to this branch (recommended)
- [ ] <!-- {"checkboxId": "ff5b1114-7d8c-49e6-8ac1-43f82af23a33"} --> Create a new PR with the fixes

</details>

---

<details>
<summary>ℹ️ Review info</summary>

<details>
<summary>⚙️ Run configuration</summary>

**Configuration used**: defaults

**Review profile**: CHILL

**Plan**: Pro Plus

**Run ID**: `ec059a79-e3ec-4ddd-b633-0e94ac48398b`

</details>

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 01b8b24151e7efa9f56fe9979fa8e8dd54c9c455 and a4a606f8c557d20903e8a8a9cbfe58386822e9b3.

</details>

<details>
<summary>📒 Files selected for processing (9)</summary>

* `examples/claudecode-skills-memanto/.env.example`
* `examples/claudecode-skills-memanto/.gitignore`
* `examples/claudecode-skills-memanto/README.md`
* `examples/claudecode-skills-memanto/memanto_skills.py`
* `examples/claudecode-skills-memanto/requirements.txt`
* `examples/claudecode-skills-memanto/run_session_a.py`
* `examples/claudecode-skills-memanto/run_session_b.py`
* `examples/claudecode-skills-memanto/tests/conftest.py`
* `examples/claudecode-skills-memanto/tests/test_memanto_skills.py`

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Comment thread examples/claudecode-skills-memanto/memanto_skills.py
Comment thread examples/claudecode-skills-memanto/memanto_skills.py
Comment thread examples/claudecode-skills-memanto/memanto_skills.py Outdated
@Xenogents

Copy link
Copy Markdown
Collaborator

We were blown away by the community's creativity and the sheer volume of high-quality submissions! After reviewing all the pull requests against the bounty's success matrix, we have decided to move forward with merging PR #692, which implemented a highly portable prompt-injection architecture via CLAUDE.md.

We are closing this PR because it falls into one of the architectural approaches that we ultimately decided against for the ecosystem:

  • High Friction (CLI Wrappers): Many submissions used Python or Bash wrappers (e.g., forcing the user to type memanto-wrap /tdd instead of the native claude /tdd). While effective at passing context, managing child PTY processes introduces terminal overhead and breaks the developer's native muscle memory
  • Incomplete Lifecycle (Manual Scripts): Some submissions successfully implemented the context extraction logic but failed to automate it, requiring the user to manually run pre and post scripts around every skill session.

We deeply appreciate the time and engineering effort you put into this submission. The codebase was fantastic to review, and we hope to see you in future Moorcheh bounties!

@Xenogents Xenogents closed this Jun 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants