From f39d49b3235f15771a716468b7d3e61deba31f5b Mon Sep 17 00:00:00 2001 From: IceCodeNew <32576256+IceCodeNew@users.noreply.github.com> Date: Sat, 8 Aug 2026 21:36:34 +0800 Subject: [PATCH 1/6] feat(zcode): add Nowledge Mem plugin --- README.md | 1 + integrations.json | 28 ++-- marketplace.json | 21 +++ .../skills/check-integration/SKILL.md | 1 + nowledge-mem-zcode-plugin/.mcp.json | 11 ++ .../.zcode-plugin/plugin.json | 20 +++ nowledge-mem-zcode-plugin/CHANGELOG.md | 14 ++ nowledge-mem-zcode-plugin/README.md | 87 ++++++++++++ .../scripts/validate-plugin.mjs | 127 ++++++++++++++++++ .../skills/check-integration/SKILL.md | 52 +++++++ .../skills/distill-memory/SKILL.md | 40 ++++++ .../skills/read-working-memory/SKILL.md | 44 ++++++ .../skills/save-handoff/SKILL.md | 31 +++++ .../skills/search-memory/SKILL.md | 53 ++++++++ .../skills/status/SKILL.md | 26 ++++ tests/plugin_e2e/test_key_plugins_e2e.py | 61 ++++++++- 16 files changed, 602 insertions(+), 15 deletions(-) create mode 100644 marketplace.json create mode 100644 nowledge-mem-zcode-plugin/.mcp.json create mode 100644 nowledge-mem-zcode-plugin/.zcode-plugin/plugin.json create mode 100644 nowledge-mem-zcode-plugin/CHANGELOG.md create mode 100644 nowledge-mem-zcode-plugin/README.md create mode 100644 nowledge-mem-zcode-plugin/scripts/validate-plugin.mjs create mode 100644 nowledge-mem-zcode-plugin/skills/check-integration/SKILL.md create mode 100644 nowledge-mem-zcode-plugin/skills/distill-memory/SKILL.md create mode 100644 nowledge-mem-zcode-plugin/skills/read-working-memory/SKILL.md create mode 100644 nowledge-mem-zcode-plugin/skills/save-handoff/SKILL.md create mode 100644 nowledge-mem-zcode-plugin/skills/search-memory/SKILL.md create mode 100644 nowledge-mem-zcode-plugin/skills/status/SKILL.md diff --git a/README.md b/README.md index b40a6d63..6c799ac5 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,7 @@ Each directory is a standalone integration. Pick the one that matches your tool. | **[Windsurf Trajectory Extractor](https://github.com/jijiamoer/windsurf-trajectory-extractor)** | `git clone https://github.com/jijiamoer/windsurf-trajectory-extractor.git` | Offline protobuf extraction for Windsurf Cascade conversation history. | | **[Cursor Plugin](nowledge-mem-cursor-plugin)** | Link `nowledge-mem-cursor-plugin` into `~/.cursor/plugins/local/nowledge-mem-cursor` | Cursor-native plugin package with session-start context guidance, bundled MCP config, rules, and honest `save-handoff` semantics. | | **[Codex Plugin](nowledge-mem-codex-plugin)** | `codex plugin marketplace add nowledge-co/community --sparse .agents --sparse nowledge-mem-codex-plugin` then `codex plugin add nowledge-mem@nowledge-community`; enable `plugins` and `hooks`, run setup, then trust the hooks when Codex asks | Native startup context and memory routing, bundled MCP retrieval and writes, plus Stop-hook capture of real Codex sessions. Coexists cleanly with Codex local Memory. | +| **[ZCode Plugin](nowledge-mem-zcode-plugin)** | In ZCode **Settings → Plugins → Create → Add marketplace**, add the repository `marketplace.json`, then install `nowledge-mem-zcode` and reload the Agent runtime | ZCode-native MCP + Skills package for guided Working Memory, proactive recall, distillation, status, and honest handoff summaries. It does not claim automatic transcript capture. | | **Raft (formerly Slock)** | Configure per-worker environment variables in Raft runtime config | Install the child runtime connector, set `NMEM_AGENT_ID=` per worker, and use Mem skills/MCP inside Raft. Raft-managed Codex rollouts are execution traces and are excluded from Codex Thread capture. | | **Lody** | Configure the child runtime in Lody Agent Config | Runtime launcher setup: install the child runtime connector first; set `NMEM_AGENT_ID=` only when that Agent Config represents a stable role. | | **Multica** | Configure the Multica agent MCP settings and custom environment | Multi-agent orchestrator setup: install the child runtime connector first; for Claude Code agents, save the Mem MCP config on the Multica agent; then set `NMEM_AGENT_ID=` in custom env. | diff --git a/integrations.json b/integrations.json index f6a10995..09e79f1b 100644 --- a/integrations.json +++ b/integrations.json @@ -1062,10 +1062,10 @@ "id": "zcode", "name": "ZCode", "category": "coding", - "type": "connector", - "version": null, - "directory": null, - "transport": "mcp+skills", + "type": "plugin", + "version": "0.1.0", + "directory": "nowledge-mem-zcode-plugin", + "transport": "plugin+mcp+skills", "capabilities": { "workingMemory": true, "search": true, @@ -1077,7 +1077,7 @@ }, "threadSave": { "method": "none", - "note": "ZCode supports plugins, MCP servers, hooks, and skills, but Nowledge Mem does not yet publish a ZCode-native hook package. Use MCP and skills now; add transcript import only after the ZCode session/hook contract is verified." + "note": "The ZCode package provides MCP and Skills, but Nowledge Mem does not yet have a verified ZCode transcript path or lifecycle capture contract. Use save-handoff for structured summaries; add transcript import only after the ZCode session/hook contract is independently verified." }, "autonomy": { "bootstrap": "guided", @@ -1085,27 +1085,27 @@ "distill": "guided", "threads": "handoff-only", "bestResultRequires": [ - "Add Nowledge Mem under Settings -> MCP Servers", - "Import or copy the Nowledge Mem skills under Settings -> Skills", - "Use the ZCode Agent restart/reload flow after MCP or skill changes", + "Add the Nowledge Mem ZCode marketplace under Settings -> Plugins", + "Install and enable nowledge-mem-zcode, then reload the ZCode Agent runtime", + "Use the ZCode-owned MCP settings for remote or custom Mem endpoints", "Ask ZCode to save handoff summaries when a conversation should be searchable later" ] }, "install": { - "command": "nmem config mcp show --host zcode", - "updateCommand": "nmem config mcp show --host zcode", + "command": "Add https://github.com/nowledge-co/community/tree/main/marketplace.json under ZCode Settings -> Plugins -> Create -> Add marketplace, then install nowledge-mem-zcode", + "updateCommand": "Refresh the nowledge-community-zcode marketplace in ZCode Settings -> Plugins, then update nowledge-mem-zcode", "detectionHint": "Running inside ZCode; ~/.zcode/ exists", "agentGuide": { - "prompt": "Read https://mem.nowledge.co/SKILL.md and follow the instructions to install or update Nowledge Mem for ZCode. Verify with nmem status and the Context Bundle or Working Memory check, then summarize what changed.", - "promptZh": "读取 https://mem.nowledge.co/SKILL.md,按其中说明为 ZCode 安装或更新 Nowledge Mem。用 nmem status 和 Context Bundle 或 Working Memory 检查验证结果,并总结你改了什么。" + "prompt": "Read https://mem.nowledge.co/SKILL.md and follow the instructions to install or update Nowledge Mem for ZCode. Prefer the nowledge-mem-zcode plugin when ZCode plugin support is available. Verify with nmem status and the Context Bundle or Working Memory check, reload ZCode after changes, and summarize what changed.", + "promptZh": "读取 https://mem.nowledge.co/SKILL.md,按其中说明为 ZCode 安装或更新 Nowledge Mem。ZCode 支持插件时优先安装 nowledge-mem-zcode。用 nmem status 和 Context Bundle 或 Working Memory 检查验证结果,修改后重新加载 ZCode,并总结你改了什么。" }, "docsUrl": "/docs/integrations/zcode" }, "toolNaming": { "convention": "mcp-backend", - "note": "ZCode can use manually configured or plugin-provided MCP servers; this connector uses the Nowledge Mem MCP tools." + "note": "ZCode namespaces plugin MCP servers; this package exposes the standard Nowledge Mem MCP tools." }, - "skills": ["read-working-memory", "search-memory", "distill-memory", "save-handoff", "status"], + "skills": ["read-working-memory", "search-memory", "distill-memory", "save-handoff", "status", "check-integration"], "slashCommands": [] }, { diff --git a/marketplace.json b/marketplace.json new file mode 100644 index 00000000..9a054560 --- /dev/null +++ b/marketplace.json @@ -0,0 +1,21 @@ +{ + "name": "nowledge-community-zcode", + "description": "Official Nowledge Labs ZCode plugins.", + "owner": { + "name": "Nowledge Labs", + "email": "hello@nowledge-labs.ai", + "url": "https://nowledge-labs.ai" + }, + "plugins": [ + { + "name": "nowledge-mem-zcode", + "version": "0.1.0", + "description": "Guided cross-tool memory for ZCode through Nowledge Mem MCP and Skills.", + "category": "knowledge", + "tags": ["memory", "mcp", "skills", "zcode"], + "source": "./nowledge-mem-zcode-plugin", + "homepage": "https://mem.nowledge.co/docs/integrations/zcode", + "repository": "https://github.com/nowledge-co/community/tree/main/nowledge-mem-zcode-plugin" + } + ] +} diff --git a/nowledge-mem-npx-skills/skills/check-integration/SKILL.md b/nowledge-mem-npx-skills/skills/check-integration/SKILL.md index eab3dcf5..10428aa8 100644 --- a/nowledge-mem-npx-skills/skills/check-integration/SKILL.md +++ b/nowledge-mem-npx-skills/skills/check-integration/SKILL.md @@ -93,6 +93,7 @@ The canonical source for this table is `community/integrations.json`. | **Alma** | Running inside Alma; `~/.config/alma/` exists | In Alma: Settings > Plugins > Marketplace, search "Nowledge Mem" | [Guide](https://mem.nowledge.co/docs/integrations/alma) | | **Droid** | Running inside Droid (Factory) | Add nowledge-co/community marketplace, install nowledge-mem@nowledge-community | [Guide](https://mem.nowledge.co/docs/integrations/droid) | | **Codex** | Running inside Codex desktop or Codex CLI; `~/.codex/` exists | `codex plugin marketplace add nowledge-co/community --sparse .agents --sparse nowledge-mem-codex-plugin && codex plugin add nowledge-mem@nowledge-community`, enable `[features] plugins = true`, `hooks = true`, and `[plugins."nowledge-mem@nowledge-community"] enabled = true`, then run the installed `scripts/install_hooks.py`. It adds the legacy `plugin_hooks` gate only when the host still needs it. Restart Codex and trust the Nowledge Mem hooks when prompted. If Codex local Memory is enabled, turn off **Allow memory generation from tool-assisted tasks**. | [Guide](https://mem.nowledge.co/docs/integrations/codex-cli) | +| **ZCode** | Running inside ZCode; `~/.zcode/` exists | In **Settings → Plugins → Create → Add marketplace**, add `https://github.com/nowledge-co/community/tree/main/marketplace.json`, install `nowledge-mem-zcode`, enable it, and reload the Agent runtime. Use `nmem config mcp show --host zcode` in ZCode's own MCP settings for remote Mem. This is guided MCP + Skills with handoff-only threads, not automatic transcript capture. | [Guide](https://mem.nowledge.co/docs/integrations/zcode) | | **Bub** | Running inside Bub | `pip install nowledge-mem-bub` | [Guide](https://mem.nowledge.co/docs/integrations/bub) | | **Pi** | Running as Pi agent; `~/.pi/` exists | `pi install npm:nowledge-mem-pi` | [Guide](https://mem.nowledge.co/docs/integrations/pi) | | **OMP** | Running as OMP agent; `~/.omp/` exists | `omp plugin install nowledge-mem-omp` | [Guide](https://mem.nowledge.co/docs/integrations/omp) | diff --git a/nowledge-mem-zcode-plugin/.mcp.json b/nowledge-mem-zcode-plugin/.mcp.json new file mode 100644 index 00000000..5f20f162 --- /dev/null +++ b/nowledge-mem-zcode-plugin/.mcp.json @@ -0,0 +1,11 @@ +{ + "mcpServers": { + "nowledge-mem": { + "type": "http", + "url": "http://127.0.0.1:14242/mcp/", + "headers": { + "APP": "ZCode" + } + } + } +} diff --git a/nowledge-mem-zcode-plugin/.zcode-plugin/plugin.json b/nowledge-mem-zcode-plugin/.zcode-plugin/plugin.json new file mode 100644 index 00000000..5d74ca3b --- /dev/null +++ b/nowledge-mem-zcode-plugin/.zcode-plugin/plugin.json @@ -0,0 +1,20 @@ +{ + "name": "nowledge-mem-zcode", + "version": "0.1.0", + "description": "Guided cross-tool memory for ZCode through Nowledge Mem MCP and Skills.", + "author": { + "name": "Nowledge Labs", + "email": "hello@nowledge-labs.ai", + "url": "https://nowledge-labs.ai" + }, + "homepage": "https://mem.nowledge.co/docs/integrations/zcode", + "repository": "https://github.com/nowledge-co/community/tree/main/nowledge-mem-zcode-plugin", + "license": "MIT", + "keywords": [ + "zcode", + "memory", + "mcp", + "skills", + "nowledge" + ] +} diff --git a/nowledge-mem-zcode-plugin/CHANGELOG.md b/nowledge-mem-zcode-plugin/CHANGELOG.md new file mode 100644 index 00000000..e6c15418 --- /dev/null +++ b/nowledge-mem-zcode-plugin/CHANGELOG.md @@ -0,0 +1,14 @@ +# Changelog + +## [0.1.0] - 2026-08-08 + +### Added + +- Initial ZCode Plugin package with official `.zcode-plugin/plugin.json` metadata. +- Bundled Nowledge Mem HTTP MCP configuration with a credential-free local default. +- Skills for Context Bundle / Working Memory, proactive search, distillation, status, integration checks, and honest handoff summaries. +- Documentation of local and remote setup, reload behavior, user-owned overrides, and the handoff-only thread boundary. + +### Not included + +- Automatic recall injection, automatic transcript capture, pre-compaction capture, and full `save-thread` import remain deferred until ZCode exposes a verified lifecycle and transcript contract. diff --git a/nowledge-mem-zcode-plugin/README.md b/nowledge-mem-zcode-plugin/README.md new file mode 100644 index 00000000..2096de96 --- /dev/null +++ b/nowledge-mem-zcode-plugin/README.md @@ -0,0 +1,87 @@ +# Nowledge Mem for ZCode + +> A ZCode Plugin package that adds guided Nowledge Mem MCP tools and reusable Skills. + +## What it provides + +After the plugin is enabled, ZCode can use the Nowledge Mem MCP server and these Skills: + +- `read-working-memory` — read Context Bundle or Working Memory when starting or resuming work +- `search-memory` — proactively search memories and exact prior threads +- `distill-memory` — save durable decisions, procedures, learnings, and context +- `save-handoff` — save a structured, resumable summary when explicitly requested +- `status` — diagnose Nowledge Mem connectivity +- `check-integration` — verify setup and explain the capability contract + +This is a guided `MCP + Skills` integration. MCP tools are available to the agent, while Skills teach when to use them. Version 0.1.0 does not claim automatic recall injection, automatic full-transcript capture, pre-compaction capture, or `save-thread`: ZCode's session/transcript lifecycle contract has not been verified for this connector. + +## Install from a marketplace + +Open a ZCode workspace, then: + +1. Open **Settings → Plugins**. +2. Choose **Create → Add marketplace**. +3. Add the repository or a local marketplace directory containing `marketplace.json`. +4. Install and enable `nowledge-mem-zcode`. +5. Reload or restart the ZCode Agent runtime. +6. After local source changes, refresh the marketplace source before testing again. + +For a local checkout, add the repository directory or the root `marketplace.json` through the same flow. The package itself is under `nowledge-mem-zcode-plugin/`. + +## Mem connection + +The package's default `.mcp.json` uses the local Nowledge Mem Desktop endpoint: + +```text +http://127.0.0.1:14242/mcp/ +``` + +Start Nowledge Mem Desktop and verify the CLI when using local mode: + +```bash +nmem --json status +``` + +For Cloud, Access Anywhere, self-hosted, or another remote endpoint, configure the ZCode-owned MCP settings rather than editing the installed package: + +```bash +nmem config client set url https://mem.example.com +nmem config client set api-key nmem_your_key +nmem config mcp show --host zcode +``` + +Paste the generated MCP block into ZCode's own MCP settings and reload the Agent runtime. API keys are intentionally absent from this repository and must not be passed as command-line arguments or written to logs. Direct MCP clients do not automatically inherit `~/.nowledge-mem/config.json`. + +## Capability contract + +| Capability | ZCode behavior in 0.1.0 | +|---|---| +| Context Bundle / Working Memory | Guided by Skills and MCP | +| Memory and thread search | Guided and proactive when relevant | +| Distillation | Guided; search before update/add | +| Status | CLI fallback plus MCP server tools | +| Handoff | Explicit structured summary only | +| Automatic recall injection | Not provided | +| Automatic transcript capture | Not provided | +| Pre-compaction capture | Not provided | +| Full `save-thread` import | Not provided | + +A handoff is not a transcript. Do not describe `save-handoff` as lossless session capture. + +## Customize without editing the plugin + +Do not modify files under ZCode's installed plugin cache. Put project-specific memory guidance in the host's user/project instruction surface when available, or use ZCode's own settings and prompt customization. This keeps changes durable across plugin updates. + +## Permissions and security + +Enabling a third-party ZCode plugin grants it the permissions provided by its declared components. Review the manifest, `.mcp.json`, and Skills before enabling it. This package contains no executable hook or custom runtime process; its MCP server still has the access granted by the ZCode MCP client and the endpoint you configure. + +## Development + +Validate the self-contained package without credentials or a running ZCode UI: + +```bash +node scripts/validate-plugin.mjs +``` + +The repository also has a static integration contract test. There is currently no verified headless ZCode plugin harness, so a successful static test is not a claim of live UI verification. diff --git a/nowledge-mem-zcode-plugin/scripts/validate-plugin.mjs b/nowledge-mem-zcode-plugin/scripts/validate-plugin.mjs new file mode 100644 index 00000000..6d22e510 --- /dev/null +++ b/nowledge-mem-zcode-plugin/scripts/validate-plugin.mjs @@ -0,0 +1,127 @@ +#!/usr/bin/env node + +import { readFileSync, readdirSync, statSync } from "node:fs"; +import { join, relative, resolve } from "node:path"; + +const pluginRoot = resolve(new URL("..", import.meta.url).pathname); +const manifestPath = join(pluginRoot, ".zcode-plugin", "plugin.json"); +const mcpPath = join(pluginRoot, ".mcp.json"); +const expectedSkills = [ + "check-integration", + "read-working-memory", + "search-memory", + "distill-memory", + "save-handoff", + "status", +]; + +function fail(message) { + console.error(`ZCode plugin validation failed: ${message}`); + process.exitCode = 1; +} + +function readJson(path, label) { + try { + return JSON.parse(readFileSync(path, "utf8")); + } catch (error) { + const detail = error instanceof Error ? error.message : String(error); + throw new Error(`${label} is not valid JSON: ${detail}`); + } +} + +function requireString(value, label) { + if (typeof value !== "string" || value.trim() === "") { + throw new Error(`${label} must be a non-empty string`); + } +} + +function validateManifest(manifest) { + requireString(manifest.name, "manifest.name"); + if (!/^[a-z0-9][a-z0-9._-]{0,127}$/.test(manifest.name)) { + throw new Error("manifest.name does not match the ZCode name format"); + } + requireString(manifest.version, "manifest.version"); + if (!/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/.test(manifest.version)) { + throw new Error("manifest.version must be a semantic version"); + } + requireString(manifest.description, "manifest.description"); + if (!manifest.author || typeof manifest.author !== "object") { + throw new Error("manifest.author must be an object"); + } + requireString(manifest.author.name, "manifest.author.name"); + if (manifest.hooks !== undefined || manifest.agents !== undefined) { + throw new Error("0.1.0 does not declare unverified hooks or agents"); + } +} + +function validateMcp(mcp) { + if (!mcp.mcpServers || typeof mcp.mcpServers !== "object") { + throw new Error(".mcp.json must contain mcpServers"); + } + const names = Object.keys(mcp.mcpServers); + if (names.length !== 1 || names[0] !== "nowledge-mem") { + throw new Error(".mcp.json must declare exactly the nowledge-mem server"); + } + const server = mcp.mcpServers["nowledge-mem"]; + if (!server || server.type !== "http") { + throw new Error("nowledge-mem MCP server must use the ZCode http transport"); + } + requireString(server.url, "nowledge-mem.url"); + const url = new URL(server.url); + if (!/^https?:$/.test(url.protocol)) { + throw new Error("nowledge-mem.url must use http or https"); + } + const serialized = JSON.stringify(mcp).toLowerCase(); + for (const forbidden of ["api-key", "api_key", "authorization", "bearer", "password", "secret"]) { + if (serialized.includes(forbidden)) { + throw new Error(`.mcp.json contains a credential field: ${forbidden}`); + } + } +} + +function validateSkills() { + const skillsRoot = join(pluginRoot, "skills"); + const actualSkills = readdirSync(skillsRoot).filter((name) => + statSync(join(skillsRoot, name)).isDirectory(), + ).sort(); + if (JSON.stringify(actualSkills) !== JSON.stringify([...expectedSkills].sort())) { + throw new Error(`skills must be exactly: ${expectedSkills.join(", ")}`); + } + for (const skillName of expectedSkills) { + const skillPath = join(skillsRoot, skillName, "SKILL.md"); + const source = readFileSync(skillPath, "utf8"); + const match = source.match(/^---\n([\s\S]*?)\n---\n/); + if (!match) { + throw new Error(`${relative(pluginRoot, skillPath)} is missing YAML frontmatter`); + } + const frontmatter = match[1]; + const name = frontmatter.match(/^name:\s*(.+)$/m)?.[1]?.trim(); + const description = frontmatter.match(/^description:\s*(.+)$/m)?.[1]?.trim(); + if (name !== skillName) { + throw new Error(`${relative(pluginRoot, skillPath)} has frontmatter name ${name ?? ""}`); + } + if (!description || description.length > 1024) { + throw new Error(`${relative(pluginRoot, skillPath)} needs a description of 1-1024 characters`); + } + if (/^name:\s*save-thread\s*$/m.test(frontmatter)) { + throw new Error(`${relative(pluginRoot, skillPath)} must not declare save-thread`); + } + } +} + +try { + validateManifest(readJson(manifestPath, ".zcode-plugin/plugin.json")); + validateMcp(readJson(mcpPath, ".mcp.json")); + validateSkills(); + for (const forbiddenPath of ["hooks", "agents"]) { + try { + statSync(join(pluginRoot, forbiddenPath)); + throw new Error(`unexpected ${forbiddenPath}/ directory`); + } catch (error) { + if (error?.code !== "ENOENT") throw error; + } + } + console.log("ZCode plugin validation passed"); +} catch (error) { + fail(error instanceof Error ? error.message : String(error)); +} diff --git a/nowledge-mem-zcode-plugin/skills/check-integration/SKILL.md b/nowledge-mem-zcode-plugin/skills/check-integration/SKILL.md new file mode 100644 index 00000000..c5c217be --- /dev/null +++ b/nowledge-mem-zcode-plugin/skills/check-integration/SKILL.md @@ -0,0 +1,52 @@ +--- +name: check-integration +description: Check Nowledge Mem setup in ZCode, explain what the plugin provides, and guide local or remote MCP configuration when memory tools are unavailable. +--- + +# Check ZCode Integration + +Use this when Nowledge Mem setup is new, a memory tool is missing, or the user asks whether the integration is working. + +## Verify the client + +Run: + +```bash +nmem --json status +``` + +If the command is missing, use the Nowledge Mem desktop app's bundled CLI installation, or install the standalone `nmem-cli` on a separate client machine. Do not replace a desktop-managed CLI with a standalone install unless the user asks for that. + +If status fails: + +- local machine: open Nowledge Mem Desktop and retry; +- remote machine: verify the URL and API key in the user's own client configuration; +- ZCode: check **Settings → MCP → Plugin MCP servers**, then reload/restart the Agent runtime. + +Never put an API key in a command argument, plugin file, or log. + +## Expected behavior + +This ZCode package provides: + +- **Working Memory and Context Bundle:** guided through Skills and MCP; +- **Recall:** guided proactive searches across memories and threads; +- **Distillation:** guided durable saves using search-before-update/add; +- **Status:** CLI/MCP diagnostics; +- **Threads:** explicit structured handoff summaries only. + +It does **not** provide automatic recall injection, automatic full-transcript capture, pre-compaction capture, or a `save-thread` operation. The current registry intentionally remains `mcp+skills`, `autoCapture: false`, and `handoff-only` until ZCode's session and hook contract is verified. + +## Local installation + +For local testing, add the repository's ZCode marketplace or plugin directory from **Settings → Plugins → Create → Add marketplace**, install the ZCode package, enable it, and reload the Agent runtime. After package changes, refresh the marketplace source. + +## Remote Mem + +Do not edit installed plugin files. Configure the user's own ZCode MCP settings with: + +```bash +nmem config mcp show --host zcode +``` + +Paste the generated host-owned MCP block into ZCode and reload the Agent runtime. This is the supported path for Cloud, Access Anywhere, self-hosted, or any endpoint requiring authentication. diff --git a/nowledge-mem-zcode-plugin/skills/distill-memory/SKILL.md b/nowledge-mem-zcode-plugin/skills/distill-memory/SKILL.md new file mode 100644 index 00000000..c67c0a54 --- /dev/null +++ b/nowledge-mem-zcode-plugin/skills/distill-memory/SKILL.md @@ -0,0 +1,40 @@ +--- +name: distill-memory +description: Save durable Nowledge Mem facts, preferences, decisions, plans, procedures, learnings, events, and important context when a ZCode conversation produces something worth remembering; do not wait to be asked. +--- + +# Distill Memory + +Save proactively when the conversation produces a durable fact, preference, decision, plan, procedure, learning, event, or important context. Do not wait to be asked. + +## Good candidates + +- Decisions with their rationale +- Repeatable procedures and non-obvious workarounds +- Lessons from debugging, incidents, or root-cause analysis +- Durable preferences or constraints +- Plans needed to resume work later +- Important context that would otherwise be lost + +Skip routine fixes, unstable work in progress, generic facts, and simple documentation answers. + +## Workflow + +1. Search first with MCP `memory_search` to avoid duplicates. +2. If the same decision, procedure, or preference already exists, refine it with `memory_update`. +3. Otherwise use `memory_add` with an atomic title and standalone content. +4. Use the matching `unit_type` (`fact`, `preference`, `decision`, `plan`, `procedure`, `learning`, `context`, or `event`) and meaningful labels/importance when known. +5. At the end of a substantial task, explicitly review whether one durable memory should be added or updated. + +Keep the new memory focused on what was learned or decided, not routine activity. If an ambient space is real and known, write to that space; otherwise keep the default lane. + +## CLI fallback + +If MCP is unavailable, use: + +```bash +nmem --json m search "" +nmem --json m add "" -t "" --unit-type decision -l "<label>" -i 0.8 +``` + +Use `nmem --json m update <memory_id> -c "<updated content>"` when an existing memory should evolve. diff --git a/nowledge-mem-zcode-plugin/skills/read-working-memory/SKILL.md b/nowledge-mem-zcode-plugin/skills/read-working-memory/SKILL.md new file mode 100644 index 00000000..692a7a25 --- /dev/null +++ b/nowledge-mem-zcode-plugin/skills/read-working-memory/SKILL.md @@ -0,0 +1,44 @@ +--- +name: read-working-memory +description: Read Nowledge Mem Context Bundle or Working Memory at the beginning of a ZCode session, when resuming work, or when the user asks about current priorities and context. +--- + +# Read Working Memory + +Start with the context that matters. When the Nowledge Mem MCP server is available, prefer `read_context_bundle` when identity, active space, rules, and Working Memory all matter. Use `read_working_memory` for a lightweight briefing. + +## When to use + +- Beginning a new conversation or returning to a project +- Resuming a review, regression, release, or earlier decision +- The user asks what they are working on or what the current context is + +## How to use + +1. Read the Context Bundle once when the task needs owner identity, AI Identity, active scope, active rules, or Working Memory. +2. Otherwise read Working Memory once near session start. +3. If Context Bundle already includes Working Memory, do not call it again unless the user asks or the session changes materially. +4. Use only relevant parts in the response; do not overwhelm the user. +5. For continuation work, follow the briefing with `search-memory` instead of stopping at the briefing. + +The MCP tool names are provided by ZCode's Nowledge Mem server. Do not invent host-specific tool names or claim that this Skill itself injects context automatically. + +## CLI fallback + +If MCP is unavailable and the `nmem` CLI is configured, use: + +```bash +nmem --json context --source-app zcode +``` + +For a lightweight briefing: + +```bash +nmem --json wm read +``` + +If the result says `exists: false`, explain that no Working Memory briefing exists yet and continue normally. If the command fails, report the connection issue without polluting the user's task. + +## Spaces + +If ZCode or the user provides a real ambient space, pass it through explicitly. Otherwise stay on the Default space; do not invent a new space because a prompt mentions a new topic. diff --git a/nowledge-mem-zcode-plugin/skills/save-handoff/SKILL.md b/nowledge-mem-zcode-plugin/skills/save-handoff/SKILL.md new file mode 100644 index 00000000..3ea74acb --- /dev/null +++ b/nowledge-mem-zcode-plugin/skills/save-handoff/SKILL.md @@ -0,0 +1,31 @@ +--- +name: save-handoff +description: Save a concise, structured Nowledge Mem handoff when the ZCode user explicitly requests a checkpoint, resumable summary, or place to continue later. +--- + +# Save Handoff + +Use this only when the user explicitly asks for a handoff, checkpoint, summary to resume later, or to remember where the work stands. + +This Skill creates a structured summary. It is **not** a full transcript import. ZCode's current Nowledge Mem integration has no verified transcript path or lifecycle contract, so do not call it `save-thread` and do not claim that the complete conversation was preserved. + +## Handoff format + +Include: + +- **Goal** +- **Decisions** +- **Files** +- **Risks** +- **Next** + +Prefer MCP thread creation when available. Otherwise use: + +```bash +nmem --json t create \ + -t "Session Handoff - <topic>" \ + -c "Goal: ... Decisions: ... Files: ... Risks: ... Next: ..." \ + -s generic-agent +``` + +After success, report that a handoff was saved, include its title and thread ID when available, and state that it is a summary rather than a transcript import. If saving fails, report the error and do not imply that a checkpoint exists. diff --git a/nowledge-mem-zcode-plugin/skills/search-memory/SKILL.md b/nowledge-mem-zcode-plugin/skills/search-memory/SKILL.md new file mode 100644 index 00000000..d267826a --- /dev/null +++ b/nowledge-mem-zcode-plugin/skills/search-memory/SKILL.md @@ -0,0 +1,53 @@ +--- +name: search-memory +description: Proactively search Nowledge Mem memories and prior threads when earlier work, decisions, procedures, regressions, or exact conversation history could improve a ZCode response. +--- + +# Search Memory + +Search before rediscovering. Use Nowledge Mem when past knowledge would make the current task sharper; do not wait for the user to say “search my memory.” + +## Search signals + +Search strongly when: + +- The user references previous work, a prior fix, or an earlier decision +- The task resumes a named feature, bug, refactor, incident, release, or subsystem +- The user asks for rationale, procedures, or exact prior conversation history +- A current debugging pattern resembles something solved earlier +- The user says “like before,” “that approach,” or similar recall language + +For durable knowledge, use the MCP `memory_search` tool. For exact prior conversations, use `thread_search` and then fetch only the relevant messages with `thread_fetch_messages`. If the first results are weak, use deeper matching rather than over-fetching. + +## Routing rules + +1. Search memories first for decisions, facts, procedures, and learnings. +2. Search threads when the user needs the prior conversation itself. +3. Inspect the smallest result set that answers the question. +4. Keep an ambient space in the host's real lane; cross-space retrieval must be explicit. +5. Summarize only the strongest matches and say when nothing relevant was found. + +## Knowledge Filesystem + +When the task needs nearby objects or a tree-like view, use the MCP `mem_fs` surface: + +```text +capabilities +recall "session token strategy" --in /memories -k 5 +find /memories --label decisions --since 2026-01-01 +grep "JWT rotation" /memories +cat /memories/by-id/<id>.memory.md +``` + +Call `capabilities` before assuming roots or verbs. These paths identify Nowledge Mem objects; they are not local operating-system paths. + +## CLI fallback + +If the MCP server is unavailable, use: + +```bash +nmem --json m search "<query>" +nmem --json t search "<query>" --limit 5 +``` + +Use `nmem --json t show <thread_id> --limit 8 --offset 0 --content-limit 1200` only after a thread result identifies a relevant conversation. diff --git a/nowledge-mem-zcode-plugin/skills/status/SKILL.md b/nowledge-mem-zcode-plugin/skills/status/SKILL.md new file mode 100644 index 00000000..0befedb0 --- /dev/null +++ b/nowledge-mem-zcode-plugin/skills/status/SKILL.md @@ -0,0 +1,26 @@ +--- +name: status +description: Check whether Nowledge Mem is reachable and configured for ZCode, especially after setup or when memory operations fail. +--- + +# Status + +Run a quick health check when the user asks whether Mem is working, when an operation fails, or after initial setup. + +```bash +nmem --json status +``` + +Interpret the result briefly: + +- report reachability, mode, server version, and memory count when healthy; +- if there is no briefing or data yet, distinguish that from a connection failure; +- do not print API keys or copy credentials into logs. + +If the check fails, guide the user through the relevant path: + +1. **Local:** open the Nowledge Mem desktop app and retry. +2. **Remote:** verify the URL and API key in the user's own `nmem` client configuration. +3. **ZCode MCP:** restart/reload the Agent runtime after changing Plugin MCP settings. + +If MCP is available, the server's status tool may provide a more direct check; use it when appropriate and keep the CLI as a fallback. diff --git a/tests/plugin_e2e/test_key_plugins_e2e.py b/tests/plugin_e2e/test_key_plugins_e2e.py index f3ce4592..870674e3 100644 --- a/tests/plugin_e2e/test_key_plugins_e2e.py +++ b/tests/plugin_e2e/test_key_plugins_e2e.py @@ -39,6 +39,7 @@ WORKBUDDY_PLUGIN = COMMUNITY_ROOT / "nowledge-mem-workbuddy-plugin" BENCH_PACKAGE = COMMUNITY_ROOT / "nowledge-mem-bench" ALMA_PLUGIN = COMMUNITY_ROOT / "nowledge-mem-alma-plugin" +ZCODE_PLUGIN = COMMUNITY_ROOT / "nowledge-mem-zcode-plugin" KEY_HOSTS = {"claude", "codex", "openclaw", "hermes", "opencode", "pi"} @@ -1419,7 +1420,7 @@ def test_registry_connect_contract_points_agent_prompts_to_universal_skill(): assert "nmem t sync --from antigravity" in by_id["antigravity-extractor"][ "autonomy" ]["bestResultRequires"][0] - for connector_id in ["zcode", "mimo-code"]: + for connector_id in ["mimo-code"]: connector = by_id[connector_id] assert connector["version"] is None assert connector["transport"] == "mcp+skills" @@ -1434,6 +1435,9 @@ def test_registry_connect_contract_points_agent_prompts_to_universal_skill(): assert connector["threadSave"]["historicalCommand"] == ( f"nmem t sync --from {connector_id}" ) + assert by_id["zcode"]["version"] == "0.1.0" + assert by_id["zcode"]["directory"] == "nowledge-mem-zcode-plugin" + assert by_id["zcode"]["transport"] == "plugin+mcp+skills" assert by_id["zcode"]["threadSave"]["method"] == "none" assert by_id["zcode"]["autonomy"]["threads"] == "handoff-only" assert by_id["alma"]["version"] == "0.7.4" @@ -1457,6 +1461,61 @@ def test_registry_connect_contract_points_agent_prompts_to_universal_skill(): assert "nowledge_mem_context_bundle" in by_id["opencode"]["toolNaming"]["tools"] +def test_zcode_plugin_static_contract_is_self_contained(): + manifest = _read_json(ZCODE_PLUGIN / ".zcode-plugin" / "plugin.json") + mcp = _read_json(ZCODE_PLUGIN / ".mcp.json") + marketplace = _read_json(COMMUNITY_ROOT / "marketplace.json") + readme = (ZCODE_PLUGIN / "README.md").read_text(encoding="utf-8") + changelog = (ZCODE_PLUGIN / "CHANGELOG.md").read_text(encoding="utf-8") + registry = _read_json(COMMUNITY_ROOT / "integrations.json") + zcode_registry = next(item for item in registry["integrations"] if item.get("id") == "zcode") + marketplace_plugin = next(item for item in marketplace["plugins"] if item.get("name") == manifest["name"]) + expected_skills = [ + "check-integration", + "read-working-memory", + "search-memory", + "distill-memory", + "save-handoff", + "status", + ] + + assert manifest["name"] == "nowledge-mem-zcode" + assert manifest["version"] == "0.1.0" + assert marketplace_plugin["version"] == manifest["version"] + assert marketplace_plugin["source"] == "./nowledge-mem-zcode-plugin" + assert zcode_registry["type"] == "plugin" + assert zcode_registry["version"] == manifest["version"] + assert zcode_registry["directory"] == "nowledge-mem-zcode-plugin" + assert zcode_registry["transport"] == "plugin+mcp+skills" + assert zcode_registry["capabilities"]["autoRecall"] is False + assert zcode_registry["capabilities"]["autoCapture"] is False + assert zcode_registry["threadSave"]["method"] == "none" + assert zcode_registry["autonomy"]["threads"] == "handoff-only" + assert zcode_registry["skills"] == [ + "read-working-memory", + "search-memory", + "distill-memory", + "save-handoff", + "status", + "check-integration", + ] + assert mcp["mcpServers"]["nowledge-mem"]["type"] == "http" + assert mcp["mcpServers"]["nowledge-mem"]["url"] == "http://127.0.0.1:14242/mcp/" + assert mcp["mcpServers"]["nowledge-mem"]["headers"]["APP"] == "ZCode" + assert "Authorization" not in json.dumps(mcp) + assert "X-NMEM-API-Key" not in json.dumps(mcp) + assert not (ZCODE_PLUGIN / "hooks").exists() + assert not (ZCODE_PLUGIN / "agents").exists() + assert not (ZCODE_PLUGIN / "skills" / "save-thread").exists() + for skill in expected_skills: + source = (ZCODE_PLUGIN / "skills" / skill / "SKILL.md").read_text(encoding="utf-8") + assert f"name: {skill}" in source + assert "description:" in source + assert "save-handoff" in readme + assert "not a transcript" in readme.lower() + assert "0.1.0" in changelog + + def test_opencode_plugin_static_contract_is_self_contained(): pkg = _read_json(OPENCODE_PLUGIN / "package.json") source = (OPENCODE_PLUGIN / "src" / "index.ts").read_text(encoding="utf-8") From db4b4d3d3e244832c67afacc3aae54d56dc7a3ee Mon Sep 17 00:00:00 2001 From: IceCodeNew <32576256+IceCodeNew@users.noreply.github.com> Date: Sat, 8 Aug 2026 23:04:09 +0800 Subject: [PATCH 2/6] docs(zcode): document persistent manual installation --- README.md | 2 +- integrations.json | 8 +- marketplace.json | 21 ---- .../skills/check-integration/SKILL.md | 2 +- nowledge-mem-zcode-plugin/README.md | 115 ++++++++++++++++-- tests/plugin_e2e/test_key_plugins_e2e.py | 14 ++- 6 files changed, 123 insertions(+), 39 deletions(-) delete mode 100644 marketplace.json diff --git a/README.md b/README.md index fad7731c..75ce26f7 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ Each directory is a standalone integration. Pick the one that matches your tool. | **[Windsurf Trajectory Extractor](https://github.com/jijiamoer/windsurf-trajectory-extractor)** | `git clone https://github.com/jijiamoer/windsurf-trajectory-extractor.git` | Offline protobuf extraction for Windsurf Cascade conversation history. | | **[Cursor Plugin](nowledge-mem-cursor-plugin)** | Link `nowledge-mem-cursor-plugin` into `~/.cursor/plugins/local/nowledge-mem-cursor` | Cursor-native plugin with session-start context, MCP recall, exact-session transcript capture, manual `save-thread`, and summary-only `save-handoff`. | | **[Codex Plugin](nowledge-mem-codex-plugin)** | `codex plugin marketplace add nowledge-co/community --sparse .agents --sparse nowledge-mem-codex-plugin` then `codex plugin add nowledge-mem@nowledge-community`; enable `plugins` and `hooks`, run setup, then trust the hooks when Codex asks | Native startup context and memory routing, bundled MCP retrieval and writes, plus Stop-hook capture of real Codex sessions. Coexists cleanly with Codex local Memory. | -| **[ZCode Plugin](nowledge-mem-zcode-plugin)** | In ZCode **Settings → Plugins → Create → Add marketplace**, add the repository `marketplace.json`, then install `nowledge-mem-zcode` and reload the Agent runtime | ZCode-native MCP + Skills package for guided Working Memory, proactive recall, distillation, status, and honest handoff summaries. It does not claim automatic transcript capture. | +| **[ZCode Plugin](nowledge-mem-zcode-plugin)** | Clone this repository, use the ZCode plugin README to create a persistent user-owned local marketplace catalog, then add that directory in **Settings → Plugins → Create → Add marketplace** and reload the Agent runtime | ZCode-native MCP + Skills package for guided Working Memory, proactive recall, distillation, status, and honest handoff summaries. It does not claim automatic transcript capture. | | **Raft (formerly Slock)** | Configure per-worker environment variables in Raft runtime config | Install the child runtime connector, set `NMEM_AGENT_ID=<agent-slug>` per worker, and use Mem skills/MCP inside Raft. Raft-managed Codex rollouts are execution traces and are excluded from Codex Thread capture. | | **Lody** | Configure the child runtime in Lody Agent Config | Runtime launcher setup: install the child runtime connector first; set `NMEM_AGENT_ID=<agent-slug>` only when that Agent Config represents a stable role. | | **Multica** | Configure the Multica agent MCP settings and custom environment | Multi-agent orchestrator setup: install the child runtime connector first; for Claude Code agents, save the Mem MCP config on the Multica agent; then set `NMEM_AGENT_ID=<agent-slug>` in custom env. | diff --git a/integrations.json b/integrations.json index 37787ec5..88082755 100644 --- a/integrations.json +++ b/integrations.json @@ -1150,15 +1150,15 @@ "distill": "guided", "threads": "handoff-only", "bestResultRequires": [ - "Add the Nowledge Mem ZCode marketplace under Settings -> Plugins", - "Install and enable nowledge-mem-zcode, then reload the ZCode Agent runtime", + "Clone or update the community repository and follow nowledge-mem-zcode-plugin/README.md to create a persistent user-owned marketplace catalog", + "Add that local marketplace directory under ZCode Settings -> Plugins -> Create -> Add marketplace, then install and enable nowledge-mem-zcode", "Use the ZCode-owned MCP settings for remote or custom Mem endpoints", "Ask ZCode to save handoff summaries when a conversation should be searchable later" ] }, "install": { - "command": "Add https://github.com/nowledge-co/community/tree/main/marketplace.json under ZCode Settings -> Plugins -> Create -> Add marketplace, then install nowledge-mem-zcode", - "updateCommand": "Refresh the nowledge-community-zcode marketplace in ZCode Settings -> Plugins, then update nowledge-mem-zcode", + "command": "Clone https://github.com/nowledge-co/community.git, create the persistent local marketplace described in nowledge-mem-zcode-plugin/README.md, then add it under ZCode Settings -> Plugins -> Create -> Add marketplace", + "updateCommand": "Pull the community checkout, refresh the user-owned ZCode marketplace source, and reload the ZCode Agent runtime", "detectionHint": "Running inside ZCode; ~/.zcode/ exists", "agentGuide": { "prompt": "Read https://mem.nowledge.co/SKILL.md and follow the instructions to install or update Nowledge Mem for ZCode. Prefer the nowledge-mem-zcode plugin when ZCode plugin support is available. Verify with nmem status and the Context Bundle or Working Memory check, reload ZCode after changes, and summarize what changed.", diff --git a/marketplace.json b/marketplace.json deleted file mode 100644 index 9a054560..00000000 --- a/marketplace.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "nowledge-community-zcode", - "description": "Official Nowledge Labs ZCode plugins.", - "owner": { - "name": "Nowledge Labs", - "email": "hello@nowledge-labs.ai", - "url": "https://nowledge-labs.ai" - }, - "plugins": [ - { - "name": "nowledge-mem-zcode", - "version": "0.1.0", - "description": "Guided cross-tool memory for ZCode through Nowledge Mem MCP and Skills.", - "category": "knowledge", - "tags": ["memory", "mcp", "skills", "zcode"], - "source": "./nowledge-mem-zcode-plugin", - "homepage": "https://mem.nowledge.co/docs/integrations/zcode", - "repository": "https://github.com/nowledge-co/community/tree/main/nowledge-mem-zcode-plugin" - } - ] -} diff --git a/nowledge-mem-npx-skills/skills/check-integration/SKILL.md b/nowledge-mem-npx-skills/skills/check-integration/SKILL.md index 97d03ee1..aec7a716 100644 --- a/nowledge-mem-npx-skills/skills/check-integration/SKILL.md +++ b/nowledge-mem-npx-skills/skills/check-integration/SKILL.md @@ -95,7 +95,7 @@ The canonical source for this table is `community/integrations.json`. | **Alma** | Running inside Alma; `~/.config/alma/` exists | In Alma: Settings > Plugins > Marketplace, search "Nowledge Mem" | [Guide](https://mem.nowledge.co/docs/integrations/alma) | | **Droid** | Running inside Droid (Factory) | Add nowledge-co/community marketplace, install nowledge-mem@nowledge-community | [Guide](https://mem.nowledge.co/docs/integrations/droid) | | **Codex** | Running inside Codex desktop or Codex CLI; `~/.codex/` exists | `codex plugin marketplace add nowledge-co/community --sparse .agents --sparse nowledge-mem-codex-plugin && codex plugin add nowledge-mem@nowledge-community`, enable `[features] plugins = true`, `hooks = true`, and `[plugins."nowledge-mem@nowledge-community"] enabled = true`, then run the installed `scripts/install_hooks.py`. It adds the legacy `plugin_hooks` gate only when the host still needs it. Restart Codex and trust the Nowledge Mem hooks when prompted. If Codex local Memory is enabled, turn off **Allow memory generation from tool-assisted tasks**. | [Guide](https://mem.nowledge.co/docs/integrations/codex-cli) | -| **ZCode** | Running inside ZCode; `~/.zcode/` exists | In **Settings → Plugins → Create → Add marketplace**, add `https://github.com/nowledge-co/community/tree/main/marketplace.json`, install `nowledge-mem-zcode`, enable it, and reload the Agent runtime. Use `nmem config mcp show --host zcode` in ZCode's own MCP settings for remote Mem. This is guided MCP + Skills with handoff-only threads, not automatic transcript capture. | [Guide](https://mem.nowledge.co/docs/integrations/zcode) | +| **ZCode** | Running inside ZCode; `~/.zcode/` exists | Clone or update `https://github.com/nowledge-co/community`, follow `nowledge-mem-zcode-plugin/README.md` to create a persistent user-owned local marketplace catalog, then add that directory in **Settings → Plugins → Create → Add marketplace**, install `nowledge-mem-zcode`, enable it, and reload the Agent runtime. Use `nmem config mcp show --host zcode` in ZCode's own MCP settings for remote Mem. This is guided MCP + Skills with handoff-only threads, not automatic transcript capture. | [Guide](https://mem.nowledge.co/docs/integrations/zcode) | | **Bub** | Running inside Bub | `pip install nowledge-mem-bub` | [Guide](https://mem.nowledge.co/docs/integrations/bub) | | **Pi** | Running as Pi agent; `~/.pi/` exists | `pi install npm:nowledge-mem-pi` | [Guide](https://mem.nowledge.co/docs/integrations/pi) | | **OMP** | Running as OMP agent; `~/.omp/` exists | `omp plugin install nowledge-mem-omp` | [Guide](https://mem.nowledge.co/docs/integrations/omp) | diff --git a/nowledge-mem-zcode-plugin/README.md b/nowledge-mem-zcode-plugin/README.md index 2096de96..9d820c0f 100644 --- a/nowledge-mem-zcode-plugin/README.md +++ b/nowledge-mem-zcode-plugin/README.md @@ -15,18 +15,117 @@ After the plugin is enabled, ZCode can use the Nowledge Mem MCP server and these This is a guided `MCP + Skills` integration. MCP tools are available to the agent, while Skills teach when to use them. Version 0.1.0 does not claim automatic recall injection, automatic full-transcript capture, pre-compaction capture, or `save-thread`: ZCode's session/transcript lifecycle contract has not been verified for this connector. -## Install from a marketplace +## Manual installation -Open a ZCode workspace, then: +ZCode's plugin package only requires `.zcode-plugin/plugin.json`. The package does not contain a `marketplace.json`, and the project does not claim that ZCode has a documented default marketplace directory. ZCode's documented local UI entry point is a marketplace source, so the commands below create a persistent, user-owned local marketplace outside this repository. -1. Open **Settings → Plugins**. -2. Choose **Create → Add marketplace**. -3. Add the repository or a local marketplace directory containing `marketplace.json`. -4. Install and enable `nowledge-mem-zcode`. +### macOS/Linux + +Choose a stable checkout location and clone the community repository: + +```bash +COMMUNITY_DIR="$HOME/src/nowledge-community" +git clone https://github.com/nowledge-co/community.git "$COMMUNITY_DIR" +``` + +If you already cloned it, update it later with: + +```bash +git -C "$HOME/src/nowledge-community" pull --ff-only +``` + +Create a persistent local marketplace directory under the user data directory. This is a project-recommended location, not a ZCode-defined default path. ZCode has not published a default marketplace directory: + +```bash +COMMUNITY_DIR="$HOME/src/nowledge-community" +MARKETPLACE_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/nowledge/zcode-marketplace" +mkdir -p "$MARKETPLACE_DIR" +python3 - "$MARKETPLACE_DIR" "$COMMUNITY_DIR/nowledge-mem-zcode-plugin" <<'PY' +import json +import pathlib +import sys + +marketplace_dir = pathlib.Path(sys.argv[1]).expanduser().resolve() +plugin_dir = pathlib.Path(sys.argv[2]).expanduser().resolve() +marketplace_dir.mkdir(parents=True, exist_ok=True) +marketplace = { + "name": "nowledge-community-zcode-local", + "description": "Local Nowledge Mem ZCode plugin source", + "plugins": [{ + "name": "nowledge-mem-zcode", + "version": "0.1.0", + "description": "Guided cross-tool memory for ZCode through Nowledge Mem MCP and Skills.", + "source": {"source": "directory", "path": str(plugin_dir)}, + }], +} +(marketplace_dir / "marketplace.json").write_text( + json.dumps(marketplace, indent=2) + "\n", encoding="utf-8" +) +print(f"Add this local marketplace directory in ZCode: {marketplace_dir}") +PY +``` + +Then open a ZCode workspace and: + +1. Go to **Settings → Plugins**. +2. Select **Create → Add marketplace**. +3. Choose the persistent directory printed by the command above. +4. In the **Personal** section, install and enable `nowledge-mem-zcode`. 5. Reload or restart the ZCode Agent runtime. -6. After local source changes, refresh the marketplace source before testing again. -For a local checkout, add the repository directory or the root `marketplace.json` through the same flow. The package itself is under `nowledge-mem-zcode-plugin/`. +The generated `marketplace.json` is only a local installation catalog. It is not part of this plugin package and is not a ZCode plugin manifest. + +### Windows PowerShell + +Clone or update the community repository: + +```powershell +$CommunityDir = Join-Path $HOME "src\nowledge-community" +git clone https://github.com/nowledge-co/community.git $CommunityDir +# For an existing checkout instead: +# git -C $CommunityDir pull --ff-only +``` + +Create the persistent user-owned marketplace directory and its catalog: + +```powershell +$CommunityDir = Join-Path $HOME "src\nowledge-community" +$MarketplaceDir = Join-Path $env:LOCALAPPDATA "Nowledge\ZCode\marketplace" +$PluginDir = (Join-Path $CommunityDir "nowledge-mem-zcode-plugin") +New-Item -ItemType Directory -Force -Path $MarketplaceDir | Out-Null +@{ + name = "nowledge-community-zcode-local" + description = "Local Nowledge Mem ZCode plugin source" + plugins = @(@{ + name = "nowledge-mem-zcode" + version = "0.1.0" + description = "Guided cross-tool memory for ZCode through Nowledge Mem MCP and Skills." + source = @{ + source = "directory" + path = (Resolve-Path $PluginDir).Path + } + }) +} | ConvertTo-Json -Depth 5 | Set-Content -Encoding UTF8 (Join-Path $MarketplaceDir "marketplace.json") +Write-Host "Add this local marketplace directory in ZCode: $MarketplaceDir" +``` + +In ZCode, use **Settings → Plugins → Create → Add marketplace**, choose `$MarketplaceDir`, install and enable `nowledge-mem-zcode`, and reload the Agent runtime. + +### Updating the plugin and adding future plugins + +Keep both the community checkout and the user-owned marketplace directory at stable, accessible paths. ZCode does not document whether local marketplace sources are copied, cached, watched, or referenced directly, nor does it document a default storage path. Do not delete or move the source if you want the documented refresh workflow to keep working. + +To update this plugin: + +```bash +git -C "$HOME/src/nowledge-community" pull --ff-only +``` + +Then open **Settings → Plugins → Marketplace sources** and choose **Refresh this marketplace**. Use **Manage installed → Check for updates** when ZCode offers that action, and reload the Agent runtime if components do not appear immediately. + +To add another local plugin in the future, edit the persistent marketplace's `marketplace.json` and append another `plugins[]` entry with a unique `name`, version, description, and a valid absolute `directory` source path. Refresh the marketplace, then install and enable the new plugin from the Personal section. ZCode's documentation does not promise that a newly listed local plugin is automatically installed or that an existing install is automatically upgraded. + +For remote SSH/WSL workspaces, local plugins do not automatically move with the workspace. ZCode documents that marketplace plugins are reinstalled remotely and that the remote environment must be able to reach the marketplace source. Keep the source available on the remote side or use a reachable GitHub/Git source instead. ## Mem connection diff --git a/tests/plugin_e2e/test_key_plugins_e2e.py b/tests/plugin_e2e/test_key_plugins_e2e.py index 7839a980..b786bbcd 100644 --- a/tests/plugin_e2e/test_key_plugins_e2e.py +++ b/tests/plugin_e2e/test_key_plugins_e2e.py @@ -1534,12 +1534,10 @@ def test_registry_connect_contract_points_agent_prompts_to_universal_skill(): def test_zcode_plugin_static_contract_is_self_contained(): manifest = _read_json(ZCODE_PLUGIN / ".zcode-plugin" / "plugin.json") mcp = _read_json(ZCODE_PLUGIN / ".mcp.json") - marketplace = _read_json(COMMUNITY_ROOT / "marketplace.json") readme = (ZCODE_PLUGIN / "README.md").read_text(encoding="utf-8") changelog = (ZCODE_PLUGIN / "CHANGELOG.md").read_text(encoding="utf-8") registry = _read_json(COMMUNITY_ROOT / "integrations.json") zcode_registry = next(item for item in registry["integrations"] if item.get("id") == "zcode") - marketplace_plugin = next(item for item in marketplace["plugins"] if item.get("name") == manifest["name"]) expected_skills = [ "check-integration", "read-working-memory", @@ -1551,8 +1549,16 @@ def test_zcode_plugin_static_contract_is_self_contained(): assert manifest["name"] == "nowledge-mem-zcode" assert manifest["version"] == "0.1.0" - assert marketplace_plugin["version"] == manifest["version"] - assert marketplace_plugin["source"] == "./nowledge-mem-zcode-plugin" + assert not (COMMUNITY_ROOT / "marketplace.json").exists() + assert "git clone" in readme + assert "marketplace.json" in readme + assert "persistent" in readme.lower() + assert "Refresh this marketplace" in readme + assert "Add marketplace" in readme + assert "not a ZCode-defined default path" in readme + assert "separate Git" not in readme + assert "submodule" not in readme + assert "community/tree/main/marketplace.json" not in (COMMUNITY_ROOT / "README.md").read_text(encoding="utf-8") assert zcode_registry["type"] == "plugin" assert zcode_registry["version"] == manifest["version"] assert zcode_registry["directory"] == "nowledge-mem-zcode-plugin" From 8168a749b43986db9432b3f892f136376e4d9593 Mon Sep 17 00:00:00 2001 From: IceCodeNew <32576256+IceCodeNew@users.noreply.github.com> Date: Sat, 8 Aug 2026 23:19:44 +0800 Subject: [PATCH 3/6] fix(zcode): finalize standalone plugin contract --- README.md | 2 +- integrations.json | 8 ++--- .../skills/check-integration/SKILL.md | 2 +- .../.zcode-plugin/plugin.json | 2 +- nowledge-mem-zcode-plugin/README.md | 14 +++++--- nowledge-mem-zcode-plugin/marketplace.json | 21 ++++++++++++ .../scripts/validate-plugin.mjs | 32 ++++++++++++++++--- .../skills/check-integration/SKILL.md | 12 ++++++- .../skills/search-memory/SKILL.md | 4 +-- .../skills/status/SKILL.md | 15 ++++++--- tests/plugin_e2e/test_key_plugins_e2e.py | 17 ++++++++++ 11 files changed, 107 insertions(+), 22 deletions(-) create mode 100644 nowledge-mem-zcode-plugin/marketplace.json diff --git a/README.md b/README.md index 75ce26f7..866340e7 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ Each directory is a standalone integration. Pick the one that matches your tool. | **[Windsurf Trajectory Extractor](https://github.com/jijiamoer/windsurf-trajectory-extractor)** | `git clone https://github.com/jijiamoer/windsurf-trajectory-extractor.git` | Offline protobuf extraction for Windsurf Cascade conversation history. | | **[Cursor Plugin](nowledge-mem-cursor-plugin)** | Link `nowledge-mem-cursor-plugin` into `~/.cursor/plugins/local/nowledge-mem-cursor` | Cursor-native plugin with session-start context, MCP recall, exact-session transcript capture, manual `save-thread`, and summary-only `save-handoff`. | | **[Codex Plugin](nowledge-mem-codex-plugin)** | `codex plugin marketplace add nowledge-co/community --sparse .agents --sparse nowledge-mem-codex-plugin` then `codex plugin add nowledge-mem@nowledge-community`; enable `plugins` and `hooks`, run setup, then trust the hooks when Codex asks | Native startup context and memory routing, bundled MCP retrieval and writes, plus Stop-hook capture of real Codex sessions. Coexists cleanly with Codex local Memory. | -| **[ZCode Plugin](nowledge-mem-zcode-plugin)** | Clone this repository, use the ZCode plugin README to create a persistent user-owned local marketplace catalog, then add that directory in **Settings → Plugins → Create → Add marketplace** and reload the Agent runtime | ZCode-native MCP + Skills package for guided Working Memory, proactive recall, distillation, status, and honest handoff summaries. It does not claim automatic transcript capture. | +| **[ZCode Plugin](https://github.com/nowledge-co/zcode-plugin)** | In ZCode **Settings → Plugins → Create → Add marketplace**, add `https://github.com/nowledge-co/zcode-plugin`, install `nowledge-mem-zcode`, and reload the Agent runtime | Standalone ZCode-native MCP + Skills package for guided Working Memory, proactive recall, distillation, status, and honest handoff summaries. It does not claim automatic transcript capture. | | **Raft (formerly Slock)** | Configure per-worker environment variables in Raft runtime config | Install the child runtime connector, set `NMEM_AGENT_ID=<agent-slug>` per worker, and use Mem skills/MCP inside Raft. Raft-managed Codex rollouts are execution traces and are excluded from Codex Thread capture. | | **Lody** | Configure the child runtime in Lody Agent Config | Runtime launcher setup: install the child runtime connector first; set `NMEM_AGENT_ID=<agent-slug>` only when that Agent Config represents a stable role. | | **Multica** | Configure the Multica agent MCP settings and custom environment | Multi-agent orchestrator setup: install the child runtime connector first; for Claude Code agents, save the Mem MCP config on the Multica agent; then set `NMEM_AGENT_ID=<agent-slug>` in custom env. | diff --git a/integrations.json b/integrations.json index 88082755..9e8cdfd2 100644 --- a/integrations.json +++ b/integrations.json @@ -1150,15 +1150,15 @@ "distill": "guided", "threads": "handoff-only", "bestResultRequires": [ - "Clone or update the community repository and follow nowledge-mem-zcode-plugin/README.md to create a persistent user-owned marketplace catalog", - "Add that local marketplace directory under ZCode Settings -> Plugins -> Create -> Add marketplace, then install and enable nowledge-mem-zcode", + "Add https://github.com/nowledge-co/zcode-plugin under ZCode Settings -> Plugins -> Create -> Add marketplace", + "Install and enable nowledge-mem-zcode, then reload the ZCode Agent runtime", "Use the ZCode-owned MCP settings for remote or custom Mem endpoints", "Ask ZCode to save handoff summaries when a conversation should be searchable later" ] }, "install": { - "command": "Clone https://github.com/nowledge-co/community.git, create the persistent local marketplace described in nowledge-mem-zcode-plugin/README.md, then add it under ZCode Settings -> Plugins -> Create -> Add marketplace", - "updateCommand": "Pull the community checkout, refresh the user-owned ZCode marketplace source, and reload the ZCode Agent runtime", + "command": "Add https://github.com/nowledge-co/zcode-plugin under ZCode Settings -> Plugins -> Create -> Add marketplace, then install nowledge-mem-zcode", + "updateCommand": "Refresh the nowledge-co/zcode-plugin marketplace in ZCode Settings -> Plugins, then update nowledge-mem-zcode", "detectionHint": "Running inside ZCode; ~/.zcode/ exists", "agentGuide": { "prompt": "Read https://mem.nowledge.co/SKILL.md and follow the instructions to install or update Nowledge Mem for ZCode. Prefer the nowledge-mem-zcode plugin when ZCode plugin support is available. Verify with nmem status and the Context Bundle or Working Memory check, reload ZCode after changes, and summarize what changed.", diff --git a/nowledge-mem-npx-skills/skills/check-integration/SKILL.md b/nowledge-mem-npx-skills/skills/check-integration/SKILL.md index aec7a716..86e2e06e 100644 --- a/nowledge-mem-npx-skills/skills/check-integration/SKILL.md +++ b/nowledge-mem-npx-skills/skills/check-integration/SKILL.md @@ -95,7 +95,7 @@ The canonical source for this table is `community/integrations.json`. | **Alma** | Running inside Alma; `~/.config/alma/` exists | In Alma: Settings > Plugins > Marketplace, search "Nowledge Mem" | [Guide](https://mem.nowledge.co/docs/integrations/alma) | | **Droid** | Running inside Droid (Factory) | Add nowledge-co/community marketplace, install nowledge-mem@nowledge-community | [Guide](https://mem.nowledge.co/docs/integrations/droid) | | **Codex** | Running inside Codex desktop or Codex CLI; `~/.codex/` exists | `codex plugin marketplace add nowledge-co/community --sparse .agents --sparse nowledge-mem-codex-plugin && codex plugin add nowledge-mem@nowledge-community`, enable `[features] plugins = true`, `hooks = true`, and `[plugins."nowledge-mem@nowledge-community"] enabled = true`, then run the installed `scripts/install_hooks.py`. It adds the legacy `plugin_hooks` gate only when the host still needs it. Restart Codex and trust the Nowledge Mem hooks when prompted. If Codex local Memory is enabled, turn off **Allow memory generation from tool-assisted tasks**. | [Guide](https://mem.nowledge.co/docs/integrations/codex-cli) | -| **ZCode** | Running inside ZCode; `~/.zcode/` exists | Clone or update `https://github.com/nowledge-co/community`, follow `nowledge-mem-zcode-plugin/README.md` to create a persistent user-owned local marketplace catalog, then add that directory in **Settings → Plugins → Create → Add marketplace**, install `nowledge-mem-zcode`, enable it, and reload the Agent runtime. Use `nmem config mcp show --host zcode` in ZCode's own MCP settings for remote Mem. This is guided MCP + Skills with handoff-only threads, not automatic transcript capture. | [Guide](https://mem.nowledge.co/docs/integrations/zcode) | +| **ZCode** | Running inside ZCode; `~/.zcode/` exists | In **Settings → Plugins → Create → Add marketplace**, add `https://github.com/nowledge-co/zcode-plugin`, install `nowledge-mem-zcode`, enable it, and reload the Agent runtime. Use `nmem config mcp show --host zcode` in ZCode's own MCP settings for remote Mem. This is guided MCP + Skills with handoff-only threads, not automatic transcript capture. | [Guide](https://mem.nowledge.co/docs/integrations/zcode) | | **Bub** | Running inside Bub | `pip install nowledge-mem-bub` | [Guide](https://mem.nowledge.co/docs/integrations/bub) | | **Pi** | Running as Pi agent; `~/.pi/` exists | `pi install npm:nowledge-mem-pi` | [Guide](https://mem.nowledge.co/docs/integrations/pi) | | **OMP** | Running as OMP agent; `~/.omp/` exists | `omp plugin install nowledge-mem-omp` | [Guide](https://mem.nowledge.co/docs/integrations/omp) | diff --git a/nowledge-mem-zcode-plugin/.zcode-plugin/plugin.json b/nowledge-mem-zcode-plugin/.zcode-plugin/plugin.json index 5d74ca3b..f0c3f8dd 100644 --- a/nowledge-mem-zcode-plugin/.zcode-plugin/plugin.json +++ b/nowledge-mem-zcode-plugin/.zcode-plugin/plugin.json @@ -8,7 +8,7 @@ "url": "https://nowledge-labs.ai" }, "homepage": "https://mem.nowledge.co/docs/integrations/zcode", - "repository": "https://github.com/nowledge-co/community/tree/main/nowledge-mem-zcode-plugin", + "repository": "https://github.com/nowledge-co/zcode-plugin", "license": "MIT", "keywords": [ "zcode", diff --git a/nowledge-mem-zcode-plugin/README.md b/nowledge-mem-zcode-plugin/README.md index 9d820c0f..6440a6a0 100644 --- a/nowledge-mem-zcode-plugin/README.md +++ b/nowledge-mem-zcode-plugin/README.md @@ -17,11 +17,17 @@ This is a guided `MCP + Skills` integration. MCP tools are available to the agen ## Manual installation -ZCode's plugin package only requires `.zcode-plugin/plugin.json`. The package does not contain a `marketplace.json`, and the project does not claim that ZCode has a documented default marketplace directory. ZCode's documented local UI entry point is a marketplace source, so the commands below create a persistent, user-owned local marketplace outside this repository. +The plugin package includes `.zcode-plugin/plugin.json` and a `marketplace.json` catalog for the standalone repository `https://github.com/nowledge-co/zcode-plugin`. ZCode has not published a default marketplace directory. For normal installation, use the standalone repository's marketplace source; the community checkout instructions below are only a development/review mirror. ### macOS/Linux -Choose a stable checkout location and clone the community repository: +For normal installation, add the standalone repository's marketplace source in ZCode using the repository URL: + +```text +https://github.com/nowledge-co/zcode-plugin +``` + +For local development or review of this community checkout, choose a stable checkout location and clone the community repository: ```bash COMMUNITY_DIR="$HOME/src/nowledge-community" @@ -34,7 +40,7 @@ If you already cloned it, update it later with: git -C "$HOME/src/nowledge-community" pull --ff-only ``` -Create a persistent local marketplace directory under the user data directory. This is a project-recommended location, not a ZCode-defined default path. ZCode has not published a default marketplace directory: +Create a persistent local marketplace directory under the user data directory. This is a project-recommended location, not a ZCode-defined default path: ```bash COMMUNITY_DIR="$HOME/src/nowledge-community" @@ -73,7 +79,7 @@ Then open a ZCode workspace and: 4. In the **Personal** section, install and enable `nowledge-mem-zcode`. 5. Reload or restart the ZCode Agent runtime. -The generated `marketplace.json` is only a local installation catalog. It is not part of this plugin package and is not a ZCode plugin manifest. +The standalone repository's `marketplace.json` is the catalog used by the ZCode marketplace flow; `.zcode-plugin/plugin.json` remains the plugin manifest. The development-only generated catalog above is not a replacement for the standalone repository catalog. ### Windows PowerShell diff --git a/nowledge-mem-zcode-plugin/marketplace.json b/nowledge-mem-zcode-plugin/marketplace.json new file mode 100644 index 00000000..d86157bb --- /dev/null +++ b/nowledge-mem-zcode-plugin/marketplace.json @@ -0,0 +1,21 @@ +{ + "name": "nowledge-zcode", + "description": "Official Nowledge Mem plugin for ZCode.", + "owner": { + "name": "Nowledge Labs", + "email": "hello@nowledge-labs.ai", + "url": "https://nowledge-labs.ai" + }, + "plugins": [ + { + "name": "nowledge-mem-zcode", + "version": "0.1.0", + "description": "Guided cross-tool memory for ZCode through Nowledge Mem MCP and Skills.", + "category": "knowledge", + "tags": ["memory", "mcp", "skills", "zcode"], + "source": ".", + "homepage": "https://mem.nowledge.co/docs/integrations/zcode", + "repository": "https://github.com/nowledge-co/zcode-plugin" + } + ] +} diff --git a/nowledge-mem-zcode-plugin/scripts/validate-plugin.mjs b/nowledge-mem-zcode-plugin/scripts/validate-plugin.mjs index 6d22e510..d9e18492 100644 --- a/nowledge-mem-zcode-plugin/scripts/validate-plugin.mjs +++ b/nowledge-mem-zcode-plugin/scripts/validate-plugin.mjs @@ -1,10 +1,12 @@ #!/usr/bin/env node import { readFileSync, readdirSync, statSync } from "node:fs"; -import { join, relative, resolve } from "node:path"; +import { join, relative } from "node:path"; +import { fileURLToPath } from "node:url"; -const pluginRoot = resolve(new URL("..", import.meta.url).pathname); +const pluginRoot = fileURLToPath(new URL("..", import.meta.url)); const manifestPath = join(pluginRoot, ".zcode-plugin", "plugin.json"); +const marketplacePath = join(pluginRoot, "marketplace.json"); const mcpPath = join(pluginRoot, ".mcp.json"); const expectedSkills = [ "check-integration", @@ -54,6 +56,26 @@ function validateManifest(manifest) { } } +function validateMarketplace(marketplace, manifest) { + if (!marketplace || typeof marketplace !== "object") { + throw new Error("marketplace.json must contain an object"); + } + requireString(marketplace.name, "marketplace.name"); + if (!Array.isArray(marketplace.plugins) || marketplace.plugins.length !== 1) { + throw new Error("marketplace.json must declare exactly one plugin"); + } + const plugin = marketplace.plugins[0]; + if (!plugin || plugin.name !== manifest.name || plugin.version !== manifest.version) { + throw new Error("marketplace plugin name/version must match plugin.json"); + } + if (plugin.source !== ".") { + throw new Error("marketplace plugin source must be the standalone package root (.)"); + } + if (plugin.repository !== "https://github.com/nowledge-co/zcode-plugin") { + throw new Error("marketplace plugin repository must point to the standalone repository"); + } +} + function validateMcp(mcp) { if (!mcp.mcpServers || typeof mcp.mcpServers !== "object") { throw new Error(".mcp.json must contain mcpServers"); @@ -90,7 +112,7 @@ function validateSkills() { for (const skillName of expectedSkills) { const skillPath = join(skillsRoot, skillName, "SKILL.md"); const source = readFileSync(skillPath, "utf8"); - const match = source.match(/^---\n([\s\S]*?)\n---\n/); + const match = source.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n/); if (!match) { throw new Error(`${relative(pluginRoot, skillPath)} is missing YAML frontmatter`); } @@ -110,7 +132,9 @@ function validateSkills() { } try { - validateManifest(readJson(manifestPath, ".zcode-plugin/plugin.json")); + const manifest = readJson(manifestPath, ".zcode-plugin/plugin.json"); + validateManifest(manifest); + validateMarketplace(readJson(marketplacePath, "marketplace.json"), manifest); validateMcp(readJson(mcpPath, ".mcp.json")); validateSkills(); for (const forbiddenPath of ["hooks", "agents"]) { diff --git a/nowledge-mem-zcode-plugin/skills/check-integration/SKILL.md b/nowledge-mem-zcode-plugin/skills/check-integration/SKILL.md index c5c217be..870beb98 100644 --- a/nowledge-mem-zcode-plugin/skills/check-integration/SKILL.md +++ b/nowledge-mem-zcode-plugin/skills/check-integration/SKILL.md @@ -7,7 +7,7 @@ description: Check Nowledge Mem setup in ZCode, explain what the plugin provides Use this when Nowledge Mem setup is new, a memory tool is missing, or the user asks whether the integration is working. -## Verify the client +## Step 1: Verify the client Run: @@ -25,6 +25,16 @@ If status fails: Never put an API key in a command argument, plugin file, or log. +## Step 2: Install for ZCode + +In ZCode, open **Settings → Plugins → Create → Add marketplace**, add: + +```text +https://github.com/nowledge-co/zcode-plugin +``` + +Install and enable `nowledge-mem-zcode`, then reload the Agent runtime. After a standalone repository update, use **Marketplace sources → Refresh this marketplace** and reload if components do not appear immediately. + ## Expected behavior This ZCode package provides: diff --git a/nowledge-mem-zcode-plugin/skills/search-memory/SKILL.md b/nowledge-mem-zcode-plugin/skills/search-memory/SKILL.md index d267826a..22fb7f04 100644 --- a/nowledge-mem-zcode-plugin/skills/search-memory/SKILL.md +++ b/nowledge-mem-zcode-plugin/skills/search-memory/SKILL.md @@ -27,9 +27,9 @@ For durable knowledge, use the MCP `memory_search` tool. For exact prior convers 4. Keep an ambient space in the host's real lane; cross-space retrieval must be explicit. 5. Summarize only the strongest matches and say when nothing relevant was found. -## Knowledge Filesystem +## Knowledge Filesystem (optional, host-specific) -When the task needs nearby objects or a tree-like view, use the MCP `mem_fs` surface: +When the task needs nearby objects or a tree-like view, and the connected ZCode MCP server exposes the optional Knowledge Filesystem, use its `mem_fs` surface. The examples below are not guaranteed to be available in every host and the returned paths are Nowledge Mem object identifiers, not local operating-system paths: ```text capabilities diff --git a/nowledge-mem-zcode-plugin/skills/status/SKILL.md b/nowledge-mem-zcode-plugin/skills/status/SKILL.md index 0befedb0..c2f01a7f 100644 --- a/nowledge-mem-zcode-plugin/skills/status/SKILL.md +++ b/nowledge-mem-zcode-plugin/skills/status/SKILL.md @@ -17,10 +17,17 @@ Interpret the result briefly: - if there is no briefing or data yet, distinguish that from a connection failure; - do not print API keys or copy credentials into logs. -If the check fails, guide the user through the relevant path: +The CLI check and ZCode MCP check are separate diagnostics. A remote or custom ZCode MCP endpoint can be healthy even when the local CLI is not configured for the same server. + +If the local CLI check fails: 1. **Local:** open the Nowledge Mem desktop app and retry. -2. **Remote:** verify the URL and API key in the user's own `nmem` client configuration. -3. **ZCode MCP:** restart/reload the Agent runtime after changing Plugin MCP settings. +2. **Remote CLI:** verify the URL and API key in the user's own `nmem` client configuration. + +For the ZCode MCP path, use the server's status tool when it is available. For remote or custom Mem, generate the host-owned configuration, paste it into ZCode's own MCP settings, and reload the Agent runtime: + +```bash +nmem config mcp show --host zcode +``` -If MCP is available, the server's status tool may provide a more direct check; use it when appropriate and keep the CLI as a fallback. +Do not treat a local `nmem --json status` failure as proof that the ZCode MCP server is unavailable, or vice versa. diff --git a/tests/plugin_e2e/test_key_plugins_e2e.py b/tests/plugin_e2e/test_key_plugins_e2e.py index b786bbcd..676d6bb1 100644 --- a/tests/plugin_e2e/test_key_plugins_e2e.py +++ b/tests/plugin_e2e/test_key_plugins_e2e.py @@ -1533,6 +1533,7 @@ def test_registry_connect_contract_points_agent_prompts_to_universal_skill(): def test_zcode_plugin_static_contract_is_self_contained(): manifest = _read_json(ZCODE_PLUGIN / ".zcode-plugin" / "plugin.json") + marketplace = _read_json(ZCODE_PLUGIN / "marketplace.json") mcp = _read_json(ZCODE_PLUGIN / ".mcp.json") readme = (ZCODE_PLUGIN / "README.md").read_text(encoding="utf-8") changelog = (ZCODE_PLUGIN / "CHANGELOG.md").read_text(encoding="utf-8") @@ -1549,6 +1550,19 @@ def test_zcode_plugin_static_contract_is_self_contained(): assert manifest["name"] == "nowledge-mem-zcode" assert manifest["version"] == "0.1.0" + assert manifest["repository"] == "https://github.com/nowledge-co/zcode-plugin" + assert marketplace["plugins"] == [ + { + "name": "nowledge-mem-zcode", + "version": "0.1.0", + "description": "Guided cross-tool memory for ZCode through Nowledge Mem MCP and Skills.", + "category": "knowledge", + "tags": ["memory", "mcp", "skills", "zcode"], + "source": ".", + "homepage": "https://mem.nowledge.co/docs/integrations/zcode", + "repository": "https://github.com/nowledge-co/zcode-plugin", + } + ] assert not (COMMUNITY_ROOT / "marketplace.json").exists() assert "git clone" in readme assert "marketplace.json" in readme @@ -1558,7 +1572,10 @@ def test_zcode_plugin_static_contract_is_self_contained(): assert "not a ZCode-defined default path" in readme assert "separate Git" not in readme assert "submodule" not in readme + assert "https://github.com/nowledge-co/zcode-plugin" in readme assert "community/tree/main/marketplace.json" not in (COMMUNITY_ROOT / "README.md").read_text(encoding="utf-8") + assert "https://github.com/nowledge-co/zcode-plugin" in (COMMUNITY_ROOT / "README.md").read_text(encoding="utf-8") + assert "https://github.com/nowledge-co/zcode-plugin" in (COMMUNITY_ROOT / "nowledge-mem-npx-skills" / "skills" / "check-integration" / "SKILL.md").read_text(encoding="utf-8") assert zcode_registry["type"] == "plugin" assert zcode_registry["version"] == manifest["version"] assert zcode_registry["directory"] == "nowledge-mem-zcode-plugin" From cd6de935e645cd376b53180d60418d5fc00db828 Mon Sep 17 00:00:00 2001 From: IceCodeNew <32576256+IceCodeNew@users.noreply.github.com> Date: Sun, 9 Aug 2026 00:01:18 +0800 Subject: [PATCH 4/6] fix(zcode): harden release guidance and CLI fallbacks --- nowledge-mem-zcode-plugin/scripts/validate-plugin.mjs | 2 +- .../skills/check-integration/SKILL.md | 2 +- .../skills/distill-memory/SKILL.md | 10 ++++++---- .../skills/read-working-memory/SKILL.md | 8 +++++--- nowledge-mem-zcode-plugin/skills/save-handoff/SKILL.md | 2 +- .../skills/search-memory/SKILL.md | 8 +++++--- 6 files changed, 19 insertions(+), 13 deletions(-) diff --git a/nowledge-mem-zcode-plugin/scripts/validate-plugin.mjs b/nowledge-mem-zcode-plugin/scripts/validate-plugin.mjs index d9e18492..65b02c3a 100644 --- a/nowledge-mem-zcode-plugin/scripts/validate-plugin.mjs +++ b/nowledge-mem-zcode-plugin/scripts/validate-plugin.mjs @@ -43,7 +43,7 @@ function validateManifest(manifest) { throw new Error("manifest.name does not match the ZCode name format"); } requireString(manifest.version, "manifest.version"); - if (!/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/.test(manifest.version)) { + if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(manifest.version)) { throw new Error("manifest.version must be a semantic version"); } requireString(manifest.description, "manifest.description"); diff --git a/nowledge-mem-zcode-plugin/skills/check-integration/SKILL.md b/nowledge-mem-zcode-plugin/skills/check-integration/SKILL.md index 870beb98..6811bcc5 100644 --- a/nowledge-mem-zcode-plugin/skills/check-integration/SKILL.md +++ b/nowledge-mem-zcode-plugin/skills/check-integration/SKILL.md @@ -33,7 +33,7 @@ In ZCode, open **Settings → Plugins → Create → Add marketplace**, add: https://github.com/nowledge-co/zcode-plugin ``` -Install and enable `nowledge-mem-zcode`, then reload the Agent runtime. After a standalone repository update, use **Marketplace sources → Refresh this marketplace** and reload if components do not appear immediately. +Install and enable `nowledge-mem-zcode`, then reload the Agent runtime. After a standalone repository update, use **Marketplace sources → Refresh this marketplace**, then **Manage installed → Check for updates** for `nowledge-mem-zcode`, and reload if components do not appear immediately. ## Expected behavior diff --git a/nowledge-mem-zcode-plugin/skills/distill-memory/SKILL.md b/nowledge-mem-zcode-plugin/skills/distill-memory/SKILL.md index c67c0a54..ee4204fa 100644 --- a/nowledge-mem-zcode-plugin/skills/distill-memory/SKILL.md +++ b/nowledge-mem-zcode-plugin/skills/distill-memory/SKILL.md @@ -30,11 +30,13 @@ Keep the new memory focused on what was learned or decided, not routine activity ## CLI fallback -If MCP is unavailable, use: +If MCP is unavailable, use the active ambient space when one is known: ```bash -nmem --json m search "<concept>" -nmem --json m add "<content>" -t "<title>" --unit-type decision -l "<label>" -i 0.8 +nmem --json m search "<concept>" --space "<space name>" +nmem --json m add "<content>" -t "<title>" --unit-type decision -l "<label>" -i 0.8 --space "<space name>" ``` -Use `nmem --json m update <memory_id> -c "<updated content>"` when an existing memory should evolve. +If no real ambient space is configured, omit `--space` and use the default lane. + +Use `nmem --json m update <memory_id> --content "<updated content>"` when an existing memory should evolve. diff --git a/nowledge-mem-zcode-plugin/skills/read-working-memory/SKILL.md b/nowledge-mem-zcode-plugin/skills/read-working-memory/SKILL.md index 692a7a25..28a7a57d 100644 --- a/nowledge-mem-zcode-plugin/skills/read-working-memory/SKILL.md +++ b/nowledge-mem-zcode-plugin/skills/read-working-memory/SKILL.md @@ -25,18 +25,20 @@ The MCP tool names are provided by ZCode's Nowledge Mem server. Do not invent ho ## CLI fallback -If MCP is unavailable and the `nmem` CLI is configured, use: +If MCP is unavailable and the `nmem` CLI is configured, use the active ambient space when one is known: ```bash -nmem --json context --source-app zcode +nmem --json context --source-app zcode --space "<space name>" ``` For a lightweight briefing: ```bash -nmem --json wm read +nmem --json wm read --space "<space name>" ``` +If no real ambient space is configured, omit `--space` and use the default lane. + If the result says `exists: false`, explain that no Working Memory briefing exists yet and continue normally. If the command fails, report the connection issue without polluting the user's task. ## Spaces diff --git a/nowledge-mem-zcode-plugin/skills/save-handoff/SKILL.md b/nowledge-mem-zcode-plugin/skills/save-handoff/SKILL.md index 3ea74acb..559f2f55 100644 --- a/nowledge-mem-zcode-plugin/skills/save-handoff/SKILL.md +++ b/nowledge-mem-zcode-plugin/skills/save-handoff/SKILL.md @@ -25,7 +25,7 @@ Prefer MCP thread creation when available. Otherwise use: nmem --json t create \ -t "Session Handoff - <topic>" \ -c "Goal: ... Decisions: ... Files: ... Risks: ... Next: ..." \ - -s generic-agent + --source zcode ``` After success, report that a handoff was saved, include its title and thread ID when available, and state that it is a summary rather than a transcript import. If saving fails, report the error and do not imply that a checkpoint exists. diff --git a/nowledge-mem-zcode-plugin/skills/search-memory/SKILL.md b/nowledge-mem-zcode-plugin/skills/search-memory/SKILL.md index 22fb7f04..2625e3cd 100644 --- a/nowledge-mem-zcode-plugin/skills/search-memory/SKILL.md +++ b/nowledge-mem-zcode-plugin/skills/search-memory/SKILL.md @@ -43,11 +43,13 @@ Call `capabilities` before assuming roots or verbs. These paths identify Nowledg ## CLI fallback -If the MCP server is unavailable, use: +If the MCP server is unavailable, use the active ambient space when one is known: ```bash -nmem --json m search "<query>" -nmem --json t search "<query>" --limit 5 +nmem --json m search "<query>" --space "<space name>" +nmem --json t search "<query>" --limit 5 --space "<space name>" ``` +If no real ambient space is configured, omit `--space` and use the default lane. Do not invent a space merely because the topic changes. + Use `nmem --json t show <thread_id> --limit 8 --offset 0 --content-limit 1200` only after a thread result identifies a relevant conversation. From 1f4299699dec7301d4ea1d70a1909990d15c1de3 Mon Sep 17 00:00:00 2001 From: IceCodeNew <32576256+IceCodeNew@users.noreply.github.com> Date: Sun, 9 Aug 2026 00:05:21 +0800 Subject: [PATCH 5/6] docs(zcode): scope thread fallback by space --- nowledge-mem-zcode-plugin/skills/search-memory/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nowledge-mem-zcode-plugin/skills/search-memory/SKILL.md b/nowledge-mem-zcode-plugin/skills/search-memory/SKILL.md index 2625e3cd..085eabe5 100644 --- a/nowledge-mem-zcode-plugin/skills/search-memory/SKILL.md +++ b/nowledge-mem-zcode-plugin/skills/search-memory/SKILL.md @@ -52,4 +52,4 @@ nmem --json t search "<query>" --limit 5 --space "<space name>" If no real ambient space is configured, omit `--space` and use the default lane. Do not invent a space merely because the topic changes. -Use `nmem --json t show <thread_id> --limit 8 --offset 0 --content-limit 1200` only after a thread result identifies a relevant conversation. +Use `nmem --json t show <thread_id> --limit 8 --offset 0 --content-limit 1200 --space "<space name>"` only after a thread result identifies a relevant conversation. If no real ambient space is configured, omit `--space`. From 85ebc848d48d03190afa46070e9c682722dfcc83 Mon Sep 17 00:00:00 2001 From: IceCodeNew <32576256+IceCodeNew@users.noreply.github.com> Date: Sun, 9 Aug 2026 00:09:54 +0800 Subject: [PATCH 6/6] fix(zcode): preserve handoff space and transport contract --- nowledge-mem-zcode-plugin/skills/check-integration/SKILL.md | 2 +- nowledge-mem-zcode-plugin/skills/save-handoff/SKILL.md | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/nowledge-mem-zcode-plugin/skills/check-integration/SKILL.md b/nowledge-mem-zcode-plugin/skills/check-integration/SKILL.md index 6811bcc5..ccc437c4 100644 --- a/nowledge-mem-zcode-plugin/skills/check-integration/SKILL.md +++ b/nowledge-mem-zcode-plugin/skills/check-integration/SKILL.md @@ -45,7 +45,7 @@ This ZCode package provides: - **Status:** CLI/MCP diagnostics; - **Threads:** explicit structured handoff summaries only. -It does **not** provide automatic recall injection, automatic full-transcript capture, pre-compaction capture, or a `save-thread` operation. The current registry intentionally remains `mcp+skills`, `autoCapture: false`, and `handoff-only` until ZCode's session and hook contract is verified. +It does **not** provide automatic recall injection, automatic full-transcript capture, pre-compaction capture, or a `save-thread` operation. The current registry intentionally remains `plugin+mcp+skills`, `autoCapture: false`, and `handoff-only` until ZCode's session and hook contract is verified. ## Local installation diff --git a/nowledge-mem-zcode-plugin/skills/save-handoff/SKILL.md b/nowledge-mem-zcode-plugin/skills/save-handoff/SKILL.md index 559f2f55..cea0b262 100644 --- a/nowledge-mem-zcode-plugin/skills/save-handoff/SKILL.md +++ b/nowledge-mem-zcode-plugin/skills/save-handoff/SKILL.md @@ -25,7 +25,10 @@ Prefer MCP thread creation when available. Otherwise use: nmem --json t create \ -t "Session Handoff - <topic>" \ -c "Goal: ... Decisions: ... Files: ... Risks: ... Next: ..." \ - --source zcode + --source zcode \ + --space "<space name>" ``` +If no real ambient space is configured, omit `--space` and use the default lane. + After success, report that a handoff was saved, include its title and thread ID when available, and state that it is a summary rather than a transcript import. If saving fails, report the error and do not imply that a checkpoint exists.