Skip to content

Add hook-based thread capture for major integrations#220

Merged
wey-gu merged 4 commits into
mainfrom
dev_081
May 2, 2026
Merged

Add hook-based thread capture for major integrations#220
wey-gu merged 4 commits into
mainfrom
dev_081

Conversation

@wey-gu

@wey-gu wey-gu commented May 2, 2026

Copy link
Copy Markdown
Member

Summary

Release-ready update for the major Nowledge Mem agent integrations.

  • Adds hook-driven thread capture for Codex CLI and hardens Claude Code capture retries.
  • Adds Hermes per-turn sync fallback for hosts that expose lifecycle hooks before full provider discovery.
  • Fixes OpenClaw empty dashboard space settings so launcher-owned NMEM_SPACE can still scope release/test profiles.
  • Updates OpenCode session message capture for current SDK shapes with legacy fallback and diagnostics.
  • Expands the plugin E2E playbook/tests while keeping live host state isolated from real user config.

Validation

  • uv run --with pytest pytest tests/plugin_e2e -q
  • node nowledge-mem-codex-plugin/scripts/validate-plugin.mjs
  • npm test in nowledge-mem-openclaw-plugin
  • node scripts/validate-plugin.mjs && npm pack --dry-run in nowledge-mem-openclaw-plugin
  • npm pack --dry-run in nowledge-mem-opencode-plugin
  • python3 nowledge-mem-codex-plugin/tests/test_codex_plugin.py
  • python3 nowledge-mem-hermes/tests/test_space_resolution.py

Release Notes

  • OpenClaw 0.8.23 is published to ClawHub.
  • nmem-cli is already released.
  • npm packages still need manual OTP publish for @nowledge/openclaw-nowledge-mem@0.8.23 and opencode-nowledge-mem@0.3.3.

@coderabbitai

coderabbitai Bot commented May 2, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR updates integration registry versions across multiple language model platforms and implements automated thread capture via lifecycle hooks. It adds Stop-hook-based transcript capture for Codex and Claude Code, introduces a post-LLM-call fallback for Hermes, fixes configuration cascade issues in OpenClaw, normalizes SDK response shapes in OpenCode, and expands E2E test coverage to validate the new capture mechanisms across live-agent scenarios.

Changes

Automated Thread Capture & Integration Alignment

Layer / File(s) Summary
Integration Registry & Manifest Versions
integrations.json, nowledge-mem-*/.../plugin.json, nowledge-mem-*/plugin.yaml, nowledge-mem-*/package.json
Integration versions bumped: claude-code 0.7.5→0.7.7, codex-cli added hook+autonomy contracts, openclaw 0.8.22→0.8.23, hermes 0.5.11→0.5.13, opencode 0.3.2→0.3.3. Manifest entries updated with hooks path (codex-plugin), version fields synced across JSON/YAML/package formats, and registry autonomy/capability fields configured for hook-driven capture.
Hook Definitions & Capture Scripts
nowledge-mem-claude-code-plugin/hooks/hooks.json, nowledge-mem-claude-code-plugin/scripts/nmem-hook-save.py, nowledge-mem-codex-plugin/hooks/hooks.json, nowledge-mem-codex-plugin/hooks/nmem-stop-save.py, nowledge-mem-hermes/__init__.py, nowledge-mem-hermes/plugin.yaml
Claude Code: Stop hook status message updated; hook script adds retry logic with --json fallback detection and legacy nmem compatibility. Codex: new Stop hook definition and dedicated nmem-stop-save.py with session-id retry, log-path derivation, and capture result validation. Hermes: conditional post_llm_call hook registration and fallback provider caching for one-shot turn capture.
Hook Installation & Setup Infrastructure
nowledge-mem-codex-plugin/scripts/install_hooks.py, nowledge-mem-codex-plugin/scripts/validate-plugin.mjs, nowledge-mem-hermes/setup.sh
Codex: new installer deploys hook script to ~/.codex/hooks.json, merges Stop hooks, and enables codex_hooks feature flag in config.toml. Hermes: setup.sh extended with helpers for legacy provider-discovery compatibility and conditional dual-path plugin installation. Codex validation script checks hook wiring, manifest version, and integrations.json contract alignment.
Client & Provider Thread Synchronization
nowledge-mem-hermes/client.py, nowledge-mem-hermes/provider.py, nowledge-mem-hermes/tests/test_session_sync.py
Hermes client appends now include explicit space_id in JSON payload when space is configured. Provider adds sync_turn() method for per-LLM-call turn capture, refactors on_session_end to delegate import/append via new helpers, and introduces internal response helpers to normalize success/error detection across single and batch result shapes.
Configuration Fixes & SDK Compatibility
nowledge-mem-openclaw-plugin/src/config.js, nowledge-mem-openclaw-plugin/tests/space-config.test.mjs, nowledge-mem-opencode-plugin/src/index.ts, integrations.json (codex-cli autonomy fields)
OpenClaw: parseConfig treats empty space: "" as unset, allowing environment/template values to cascade instead of being short-circuited. OpenCode: new helpers normalize session message shapes across SDK variants and retry fetch with multiple request options. Codex integrations.json adds automatic-capture autonomy thread mode and hook setup command to install.updateCommand.
Documentation & Changelog
nowledge-mem-claude-code-plugin/README.md, nowledge-mem-claude-code-plugin/CHANGELOG.md, nowledge-mem-codex-plugin/AGENTS.md, nowledge-mem-codex-plugin/README.md, nowledge-mem-codex-plugin/CHANGELOG.md, nowledge-mem-hermes/README.md, nowledge-mem-hermes/CHANGELOG.md, nowledge-mem-openclaw-plugin/CHANGELOG.md, nowledge-mem-opencode-plugin/README.md, nowledge-mem-opencode-plugin/CHANGELOG.md, nowledge-mem-npx-skills/skills/check-integration/SKILL.md, codex.config.example.toml, tests/plugin_e2e/README.md
Clarified hook-driven capture lifecycle, concurrent session handling, retry/fallback behavior, feature-flag enablement, and installation/troubleshooting steps. Added codex_hooks = true example config and expanded E2E scope documentation.
Unit & E2E Tests
nowledge-mem-claude-code-plugin/tests/test_nmem_hook_save.py, nowledge-mem-codex-plugin/tests/test_codex_plugin.py, nowledge-mem-hermes/tests/test_setup.sh, nowledge-mem-hermes/tests/test_space_resolution.py, nowledge-mem-openclaw-plugin/tests/space-config.test.mjs, tests/plugin_e2e/test_key_plugins_e2e.py, tests/plugin_e2e/README.md
Added tests for symlink resolution, retry/legacy fallback, hook installation/merging, space payload inclusion, empty config handling. Extended E2E suite with Codex stop-hook verification, OpenCode live tool-invocation scenario, enhanced Claude/OpenClaw/Hermes harnesses, and improved failure tolerance for budget-limited scenarios.

Sequence Diagram(s)

sequenceDiagram
    actor User as User / Agent
    participant Claude as Claude Code
    participant Hook as Stop Hook<br/>(nmem-hook-save.py)
    participant CLI as nmem CLI
    participant Mem as Nowledge Mem
    
    User->>Claude: Interact (turn completed)
    Claude->>Hook: Trigger Stop lifecycle event
    Hook->>Hook: Read session_id & project path
    Hook->>Hook: Resolve symlink (if macOS)
    Hook->>CLI: Run nmem t save --from claude-code<br/>--json (with retries)
    alt JSON supported
        CLI-->>Hook: {results: [{action: "created"}]}
        Hook->>Mem: ✓ Capture succeeded
    else JSON unsupported
        CLI-->>Hook: Error: unknown option --json
        Hook->>Hook: Detect incompatibility
        Hook->>CLI: Rerun without --json (legacy)
        CLI-->>Hook: Exit 0 (non-JSON output)
        Hook->>Mem: ✓ Capture succeeded (legacy)
    end
    Hook-->>Claude: Capture complete
Loading
sequenceDiagram
    actor User as User
    participant Codex as Codex Agent
    participant Config as config.toml<br/>(codex_hooks=true)
    participant HookRuntime as ~/.codex/hooks.json<br/>(Stop hook)
    participant Script as nmem-stop-save.py
    participant CLI as nmem CLI
    participant Mem as Nowledge Mem
    
    User->>User: Run codex setup
    User->>Script: Install hooks via<br/>scripts/install_hooks.py
    Script->>Config: Enable codex_hooks feature
    Script->>HookRuntime: Merge/install Stop hook
    Script-->>User: ✓ Setup complete
    
    User->>Codex: Chat (turn completed)
    Codex->>HookRuntime: Trigger on Stop event
    HookRuntime->>Script: Execute nmem-stop-save.py
    Script->>Script: Read session_id from payload
    Script->>CLI: nmem t save --from codex<br/>--session-id <id> --json (with retry)
    alt Saved result received
        CLI-->>Script: {results: [{action: "created"}]}
        Script->>Mem: ✓ Turn captured
    else Session-id lookup miss
        Script->>Script: Detect lookup miss marker
        Script->>CLI: Retry without --session-id
        CLI-->>Script: Success (latest session)
        Script->>Mem: ✓ Turn captured (latest)
    end
    Script-->>Codex: Exit 0 (non-fatal)
Loading
sequenceDiagram
    participant Hermes as Hermes Agent
    participant Provider as NowledgeMemProvider<br/>(via plugin __init__)
    participant Fallback as Fallback Hook<br/>(post_llm_call)
    participant Client as NowledgeMemClient
    participant Mem as Nowledge Mem
    
    Hermes->>Hermes: Check plugin registration path
    alt Full provider API available
        Hermes->>Provider: Register memory_provider
        Provider->>Client: Configured & ready
    else Hook-only (older Hermes)
        Hermes->>Fallback: Register post_llm_call hook
        Fallback->>Provider: Lazy-initialize on first call
    end
    
    Hermes->>Hermes: LLM turn completed
    alt Provider path
        Hermes->>Provider: on_memory_write (or via lifecycle)
        Provider->>Provider: sync_turn(user, assistant)
        Provider->>Client: import_thread or append_thread
        Client->>Mem: POST /threads
    else Hook path
        Hermes->>Fallback: post_llm_call hook fired
        Fallback->>Provider: Extract session_id, user, assistant
        Fallback->>Provider: sync_turn(...)
        Provider->>Client: import_thread or append_thread
        Client->>Mem: POST /threads
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

🐰 Hooks are hopping through the agents,
Threads now dance with less impatience!
Codex, Hermes, Claude Code too—
Captured turns in Mem, brand new.
Retries, fallbacks, spaces aligned,
Live-agent trust, at long last signed!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.42% 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.
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.
Title check ✅ Passed The title 'Add hook-based thread capture for major integrations' accurately summarizes the main change: implementing lifecycle hooks for automatic thread capture across multiple plugins (Claude Code, Codex, OpenClaw, Hermes, OpenCode).

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev_081

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@wey-gu wey-gu changed the title refactor all plugins refactor all plugins && e2e test included May 2, 2026

@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: 1

🧹 Nitpick comments (5)
nowledge-mem-opencode-plugin/src/index.ts (1)

190-215: ⚡ Quick win

normalizeSessionMessages looks robust; consider logging in fetchSessionMessages's catch block.

The { path: { id }, query } shape in the first attempt matches the current OpenCode SDK convention (the official docs show client.session.get({ path: { id: "invalid-id" } }) as the canonical pattern), so the first attempt should succeed on current builds and the second acts as a correct legacy fallback.

However, the empty catch {} at line 210 silently swallows every exception — including real failures like a dead server, auth errors, or a future SDK breaking change. When both attempts fail, the caller receives [] and returns "No messages found in current session", with no diagnostic signal about why. A single console.warn (or client.app.log if the client is in scope) would let users distinguish a genuine empty session from a transport/API failure without changing any behavior.

🔍 Suggested change
-      try {
-        const messages = normalizeSessionMessages(await client.session.messages(options as any))
-        if (messages.length > 0) return messages
-      } catch {
-        // Keep compatibility across OpenCode SDK shapes.
-      }
+      try {
+        const messages = normalizeSessionMessages(await client.session.messages(options as any))
+        if (messages.length > 0) return messages
+      } catch (err: any) {
+        // Keep compatibility across OpenCode SDK shapes; log for diagnosability.
+        console.warn("[nowledge-mem] session.messages attempt failed:", err?.message ?? err)
+      }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@nowledge-mem-opencode-plugin/src/index.ts` around lines 190 - 215, The empty
catch in fetchSessionMessages silently swallows errors; update the catch in
fetchSessionMessages (the try around client.session.messages calls) to log the
caught error details (e.g., using console.warn or client.app.log if client is
available) along with context such as the options/attempt being used and the
sessionID so transient transport/auth/SDK errors are visible while preserving
the existing fallback behavior to the legacy attempt and the final return of [].
nowledge-mem-hermes/tests/test_space_resolution.py (1)

283-336: ⚡ Quick win

Add a negative test to assert space_id is absent when no space is configured.

The updated test now covers the positive path, but there is no companion assertion confirming that space_id is not included in the payload when NowledgeMemClient() is constructed without a space argument. Without it, silently removing the if self._has_explicit_space and self._space: guard in client.py would go undetected.

✅ Suggested companion test
def test_thread_append_omits_space_id_when_no_space_configured(self):
    captured: dict[str, object] = {}
    original_run = client_module.subprocess.run
    original_urlopen = client_module.urlrequest.urlopen
    previous_url = os.environ.get("NMEM_API_URL")
    previous_key = os.environ.get("NMEM_API_KEY")
    os.environ["NMEM_API_URL"] = "http://mem.test"
    os.environ["NMEM_API_KEY"] = ""

    def _bad_run(*_args, **_kwargs):
        raise AssertionError("thread append must not use subprocess")

    class _Response:
        def __enter__(self): return self
        def __exit__(self, *_): return False
        def read(self): return b'{"success": true, "messages_added": 1}'

    def _fake_urlopen(request, **_kwargs):
        captured["body"] = request.data.decode("utf-8")
        return _Response()

    try:
        client_module.subprocess.run = _bad_run
        client_module.urlrequest.urlopen = _fake_urlopen
        # No space argument — space_id must not appear in payload
        client = client_module.NowledgeMemClient()
        client.append_thread("s1", [{"role": "user", "content": "hello"}])
        payload = json.loads(captured["body"])
        self.assertNotIn("space_id", payload)
    finally:
        client_module.subprocess.run = original_run
        client_module.urlrequest.urlopen = original_urlopen
        if previous_url is None:
            os.environ.pop("NMEM_API_URL", None)
        else:
            os.environ["NMEM_API_URL"] = previous_url
        if previous_key is None:
            os.environ.pop("NMEM_API_KEY", None)
        else:
            os.environ["NMEM_API_KEY"] = previous_key
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@nowledge-mem-hermes/tests/test_space_resolution.py` around lines 283 - 336,
Add a negative test that constructs NowledgeMemClient() without the space
argument and asserts that the outgoing append_thread payload does not include
"space_id": copy the mocking pattern from
test_thread_append_posts_payload_without_subprocess_argv (override
client_module.subprocess.run to raise, monkeypatch
client_module.urlrequest.urlopen to capture request.data in captured["body"],
create a fake response that returns success), call client =
client_module.NowledgeMemClient() then client.append_thread(...), parse json
from captured["body"] and assert "space_id" is not in the payload; this will
validate the guard around NowledgeMemClient._has_explicit_space /
NowledgeMemClient._space in client.py remains effective.
nowledge-mem-opencode-plugin/package.json (1)

31-33: Consider tightening the @opencode-ai/plugin peer dependency lower bound to ^1.3.7.

The { path: { id } } call shape for client.session.messages() was introduced in version 1.3.7 or earlier. The current peer dependency ^1.3.0 permits versions 1.3.0–1.3.6, which would not support the primary call pattern that fetchSessionMessages targets on line 208. While the code includes a fallback attempt with { sessionID } syntax for broader compatibility, tightening the lower bound to ^1.3.7 would eliminate the risk of silent failures on outdated SDK versions and clarify the actual minimum SDK requirement for this plugin.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@nowledge-mem-opencode-plugin/package.json` around lines 31 - 33, Update the
package peer dependency for `@opencode-ai/plugin` from "^1.3.0" to "^1.3.7" to
reflect the minimum SDK that implements the { path: { id } } call shape used by
fetchSessionMessages; this ensures client.session.messages() supports the {
path: { id } } signature (and avoids relying solely on the fallback using {
sessionID }) and clearly documents the required minimum version for the plugin.
nowledge-mem-codex-plugin/scripts/install_hooks.py (1)

139-148: 💤 Low value

TOML validation doesn't prevent writing if input is invalid.

_validate_toml_if_possible parses the existing config but doesn't raise or warn if parsing fails. If the existing config.toml is malformed, the script will proceed to modify it with string manipulation, potentially making it worse or creating a hybrid invalid file.

Consider either warning the user or backing up invalid TOML before modification.

♻️ Proposed enhancement
 def _validate_toml_if_possible(text: str) -> None:
     if not text.strip():
         return
     try:
         import tomllib
 
         tomllib.loads(text)
-    except ModuleNotFoundError:
+    except ModuleNotFoundError:
+        return
+    except Exception as exc:
+        print(f"warning: existing config.toml may be invalid: {exc}", file=sys.stderr)
         return
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@nowledge-mem-codex-plugin/scripts/install_hooks.py` around lines 139 - 148,
The _validate_toml_if_possible function currently swallows TOML parse errors and
does nothing, allowing the script to continue modifying an invalid config;
update _validate_toml_if_possible to catch tomllib.TOMLDecodeError (or generic
Exception if tomllib lacks that name) and either raise a descriptive exception
or return a flag indicating invalid TOML, then update callers (e.g., the code
that writes/edits config.toml) to abort or create a backup copy of the existing
file before making changes and log a clear warning including the parse error;
reference the function name _validate_toml_if_possible and ensure callers check
its result or handle the raised exception to avoid in-place modifications of
malformed TOML.
nowledge-mem-hermes/__init__.py (1)

60-64: 💤 Low value

Consider logging shutdown failures for diagnostics.

The static analysis tool flagged the silent try-except-pass pattern. While swallowing shutdown errors is appropriate here (the provider is being replaced anyway), logging at debug level would help diagnose issues without affecting runtime.

♻️ Proposed fix
         if _fallback_provider is not None:
             try:
                 _fallback_provider.shutdown()
-            except Exception:
-                pass
+            except Exception as exc:
+                logger.debug("Fallback provider shutdown error (ignored): %s", exc)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@nowledge-mem-hermes/__init__.py` around lines 60 - 64, The silent except in
the shutdown of _fallback_provider should log the exception at debug level for
diagnostics: wrap the call to _fallback_provider.shutdown() in the existing
try/except, capture the Exception as e, and call a module logger (e.g. logger =
logging.getLogger(__name__)) with logger.debug("Fallback provider shutdown
failed", exc_info=e) or logger.debug(..., exc_info=True) so the stacktrace is
available; keep swallowing the exception after logging so behavior is unchanged
and reference the symbol _fallback_provider.shutdown to locate the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/plugin_e2e/test_key_plugins_e2e.py`:
- Around line 340-344: The test calls the install_hooks.py script which writes
to the real ~/.codex; modify the test to isolate Codex state by creating a
temporary directory and setting CODEX_HOME in a fresh env dict, pass that env to
_run (the invocation of install_hooks.py) and to any subsequent Codex-related
commands instead of reusing e2e_context.env, and ensure the temp directory is
cleaned up after the test; locate the call to _run in test_key_plugins_e2e.py
and update it to use the temp CODEX_HOME environment variable when invoking
install_hooks.py and later Codex operations.

---

Nitpick comments:
In `@nowledge-mem-codex-plugin/scripts/install_hooks.py`:
- Around line 139-148: The _validate_toml_if_possible function currently
swallows TOML parse errors and does nothing, allowing the script to continue
modifying an invalid config; update _validate_toml_if_possible to catch
tomllib.TOMLDecodeError (or generic Exception if tomllib lacks that name) and
either raise a descriptive exception or return a flag indicating invalid TOML,
then update callers (e.g., the code that writes/edits config.toml) to abort or
create a backup copy of the existing file before making changes and log a clear
warning including the parse error; reference the function name
_validate_toml_if_possible and ensure callers check its result or handle the
raised exception to avoid in-place modifications of malformed TOML.

In `@nowledge-mem-hermes/__init__.py`:
- Around line 60-64: The silent except in the shutdown of _fallback_provider
should log the exception at debug level for diagnostics: wrap the call to
_fallback_provider.shutdown() in the existing try/except, capture the Exception
as e, and call a module logger (e.g. logger = logging.getLogger(__name__)) with
logger.debug("Fallback provider shutdown failed", exc_info=e) or
logger.debug(..., exc_info=True) so the stacktrace is available; keep swallowing
the exception after logging so behavior is unchanged and reference the symbol
_fallback_provider.shutdown to locate the change.

In `@nowledge-mem-hermes/tests/test_space_resolution.py`:
- Around line 283-336: Add a negative test that constructs NowledgeMemClient()
without the space argument and asserts that the outgoing append_thread payload
does not include "space_id": copy the mocking pattern from
test_thread_append_posts_payload_without_subprocess_argv (override
client_module.subprocess.run to raise, monkeypatch
client_module.urlrequest.urlopen to capture request.data in captured["body"],
create a fake response that returns success), call client =
client_module.NowledgeMemClient() then client.append_thread(...), parse json
from captured["body"] and assert "space_id" is not in the payload; this will
validate the guard around NowledgeMemClient._has_explicit_space /
NowledgeMemClient._space in client.py remains effective.

In `@nowledge-mem-opencode-plugin/package.json`:
- Around line 31-33: Update the package peer dependency for `@opencode-ai/plugin`
from "^1.3.0" to "^1.3.7" to reflect the minimum SDK that implements the { path:
{ id } } call shape used by fetchSessionMessages; this ensures
client.session.messages() supports the { path: { id } } signature (and avoids
relying solely on the fallback using { sessionID }) and clearly documents the
required minimum version for the plugin.

In `@nowledge-mem-opencode-plugin/src/index.ts`:
- Around line 190-215: The empty catch in fetchSessionMessages silently swallows
errors; update the catch in fetchSessionMessages (the try around
client.session.messages calls) to log the caught error details (e.g., using
console.warn or client.app.log if client is available) along with context such
as the options/attempt being used and the sessionID so transient
transport/auth/SDK errors are visible while preserving the existing fallback
behavior to the legacy attempt and the final return of [].
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b8edbd26-750a-4ef4-89dd-7b1d67243f5f

📥 Commits

Reviewing files that changed from the base of the PR and between 316599e and 16642d0.

⛔ Files ignored due to path filters (1)
  • nowledge-mem-openclaw-plugin/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (39)
  • integrations.json
  • nowledge-mem-claude-code-plugin/.claude-plugin/plugin.json
  • nowledge-mem-claude-code-plugin/CHANGELOG.md
  • nowledge-mem-claude-code-plugin/README.md
  • nowledge-mem-claude-code-plugin/hooks/hooks.json
  • nowledge-mem-claude-code-plugin/scripts/nmem-hook-save.py
  • nowledge-mem-claude-code-plugin/tests/test_nmem_hook_save.py
  • nowledge-mem-codex-plugin/.codex-plugin/plugin.json
  • nowledge-mem-codex-plugin/AGENTS.md
  • nowledge-mem-codex-plugin/CHANGELOG.md
  • nowledge-mem-codex-plugin/README.md
  • nowledge-mem-codex-plugin/codex.config.example.toml
  • nowledge-mem-codex-plugin/hooks/hooks.json
  • nowledge-mem-codex-plugin/hooks/nmem-stop-save.py
  • nowledge-mem-codex-plugin/scripts/install_hooks.py
  • nowledge-mem-codex-plugin/scripts/validate-plugin.mjs
  • nowledge-mem-codex-plugin/tests/test_codex_plugin.py
  • nowledge-mem-hermes/CHANGELOG.md
  • nowledge-mem-hermes/README.md
  • nowledge-mem-hermes/__init__.py
  • nowledge-mem-hermes/client.py
  • nowledge-mem-hermes/plugin.yaml
  • nowledge-mem-hermes/provider.py
  • nowledge-mem-hermes/setup.sh
  • nowledge-mem-hermes/tests/test_session_sync.py
  • nowledge-mem-hermes/tests/test_setup.sh
  • nowledge-mem-hermes/tests/test_space_resolution.py
  • nowledge-mem-npx-skills/skills/check-integration/SKILL.md
  • nowledge-mem-openclaw-plugin/CHANGELOG.md
  • nowledge-mem-openclaw-plugin/openclaw.plugin.json
  • nowledge-mem-openclaw-plugin/package.json
  • nowledge-mem-openclaw-plugin/src/config.js
  • nowledge-mem-openclaw-plugin/tests/space-config.test.mjs
  • nowledge-mem-opencode-plugin/CHANGELOG.md
  • nowledge-mem-opencode-plugin/README.md
  • nowledge-mem-opencode-plugin/package.json
  • nowledge-mem-opencode-plugin/src/index.ts
  • tests/plugin_e2e/README.md
  • tests/plugin_e2e/test_key_plugins_e2e.py

Comment thread tests/plugin_e2e/test_key_plugins_e2e.py
@wey-gu wey-gu changed the title refactor all plugins && e2e test included Add hook-based thread capture for major integrations May 2, 2026
@wey-gu wey-gu merged commit eb8e303 into main May 2, 2026
1 check passed
@wey-gu wey-gu deleted the dev_081 branch May 14, 2026 13:42
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.

1 participant