From 0da9728e1b1d53c0244d891ad74faaccc555904a Mon Sep 17 00:00:00 2001 From: Wey Gu Date: Tue, 10 Mar 2026 14:08:27 +0800 Subject: [PATCH] refactor: move Gemini CLI integration to dedicated repo Replace the in-tree Gemini extension package with the new nowledge-mem-gemini-cli submodule so gallery discovery, release automation, and local installs all use a dedicated repository. Made-with: Cursor --- .../workflows/release-gemini-extension.yml | 52 ------ .../workflows/validate-gemini-extension.yml | 38 ----- .gitmodules | 3 + README.md | 3 +- nowledge-mem-gemini-cli | 1 + nowledge-mem-gemini-cli-extension/.gitignore | 1 - .../CHANGELOG.md | 55 ------ nowledge-mem-gemini-cli-extension/GEMINI.md | 152 ----------------- nowledge-mem-gemini-cli-extension/README.md | 156 ------------------ .../RELEASING.md | 101 ------------ .../commands/nowledge/distill-memory.toml | 19 --- .../nowledge/read-working-memory.toml | 21 --- .../commands/nowledge/save-handoff.toml | 16 -- .../commands/nowledge/save-thread.toml | 15 -- .../commands/nowledge/search-memory.toml | 18 -- .../commands/nowledge/status.toml | 17 -- .../gemini-extension.json | 6 - .../hooks/hooks.json | 30 ---- .../hooks/session-end.mjs | 31 ---- .../hooks/session-start.mjs | 63 ------- .../package.json | 29 ---- .../release-notes/0.1.0.md | 40 ----- .../release-notes/0.1.1.md | 21 --- .../release-notes/0.1.2.md | 21 --- .../scripts/package-extension.mjs | 128 -------------- .../scripts/validate-extension.mjs | 106 ------------ .../skills/distill-memory/SKILL.md | 23 --- .../skills/read-working-memory/SKILL.md | 21 --- .../skills/save-handoff/SKILL.md | 29 ---- .../skills/save-thread/SKILL.md | 31 ---- .../skills/search-memory/SKILL.md | 28 ---- 31 files changed, 6 insertions(+), 1269 deletions(-) delete mode 100644 .github/workflows/release-gemini-extension.yml delete mode 100644 .github/workflows/validate-gemini-extension.yml create mode 100644 .gitmodules create mode 160000 nowledge-mem-gemini-cli delete mode 100644 nowledge-mem-gemini-cli-extension/.gitignore delete mode 100644 nowledge-mem-gemini-cli-extension/CHANGELOG.md delete mode 100644 nowledge-mem-gemini-cli-extension/GEMINI.md delete mode 100644 nowledge-mem-gemini-cli-extension/README.md delete mode 100644 nowledge-mem-gemini-cli-extension/RELEASING.md delete mode 100644 nowledge-mem-gemini-cli-extension/commands/nowledge/distill-memory.toml delete mode 100644 nowledge-mem-gemini-cli-extension/commands/nowledge/read-working-memory.toml delete mode 100644 nowledge-mem-gemini-cli-extension/commands/nowledge/save-handoff.toml delete mode 100644 nowledge-mem-gemini-cli-extension/commands/nowledge/save-thread.toml delete mode 100644 nowledge-mem-gemini-cli-extension/commands/nowledge/search-memory.toml delete mode 100644 nowledge-mem-gemini-cli-extension/commands/nowledge/status.toml delete mode 100644 nowledge-mem-gemini-cli-extension/gemini-extension.json delete mode 100644 nowledge-mem-gemini-cli-extension/hooks/hooks.json delete mode 100644 nowledge-mem-gemini-cli-extension/hooks/session-end.mjs delete mode 100644 nowledge-mem-gemini-cli-extension/hooks/session-start.mjs delete mode 100644 nowledge-mem-gemini-cli-extension/package.json delete mode 100644 nowledge-mem-gemini-cli-extension/release-notes/0.1.0.md delete mode 100644 nowledge-mem-gemini-cli-extension/release-notes/0.1.1.md delete mode 100644 nowledge-mem-gemini-cli-extension/release-notes/0.1.2.md delete mode 100644 nowledge-mem-gemini-cli-extension/scripts/package-extension.mjs delete mode 100644 nowledge-mem-gemini-cli-extension/scripts/validate-extension.mjs delete mode 100644 nowledge-mem-gemini-cli-extension/skills/distill-memory/SKILL.md delete mode 100644 nowledge-mem-gemini-cli-extension/skills/read-working-memory/SKILL.md delete mode 100644 nowledge-mem-gemini-cli-extension/skills/save-handoff/SKILL.md delete mode 100644 nowledge-mem-gemini-cli-extension/skills/save-thread/SKILL.md delete mode 100644 nowledge-mem-gemini-cli-extension/skills/search-memory/SKILL.md diff --git a/.github/workflows/release-gemini-extension.yml b/.github/workflows/release-gemini-extension.yml deleted file mode 100644 index b653caa4..00000000 --- a/.github/workflows/release-gemini-extension.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: Release Gemini Extension - -on: - push: - tags: - - 'nowledge-mem-gemini-cli-extension-v*' - -permissions: - contents: write - -jobs: - release: - runs-on: ubuntu-latest - defaults: - run: - working-directory: nowledge-mem-gemini-cli-extension - - steps: - - name: Check out repository - uses: actions/checkout@v4 - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - - - name: Resolve release metadata - id: release_meta - run: | - VERSION=$(node -p "require('./package.json').version") - EXPECTED_TAG="nowledge-mem-gemini-cli-extension-v${VERSION}" - if [ "${GITHUB_REF_NAME}" != "${EXPECTED_TAG}" ]; then - echo "Tag ${GITHUB_REF_NAME} does not match package version ${VERSION}" >&2 - exit 1 - fi - echo "version=${VERSION}" >> "$GITHUB_OUTPUT" - echo "expected_tag=${EXPECTED_TAG}" >> "$GITHUB_OUTPUT" - - - name: Validate extension package - run: npm run validate - - - name: Build release archive - run: npm run package:release - - - name: Create GitHub Release - uses: softprops/action-gh-release@v2 - with: - name: Nowledge Mem Gemini CLI Extension v${{ steps.release_meta.outputs.version }} - body_path: nowledge-mem-gemini-cli-extension/release-notes/${{ steps.release_meta.outputs.version }}.md - files: | - nowledge-mem-gemini-cli-extension/dist/nowledge-mem-gemini-cli-extension.tar.gz - nowledge-mem-gemini-cli-extension/dist/nowledge-mem-gemini-cli-extension.tar.gz.sha256 diff --git a/.github/workflows/validate-gemini-extension.yml b/.github/workflows/validate-gemini-extension.yml deleted file mode 100644 index f26218af..00000000 --- a/.github/workflows/validate-gemini-extension.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Validate Gemini Extension - -on: - pull_request: - paths: - - 'nowledge-mem-gemini-cli-extension/**' - - '.github/workflows/validate-gemini-extension.yml' - - '.github/workflows/release-gemini-extension.yml' - push: - branches: - - main - - dev - paths: - - 'nowledge-mem-gemini-cli-extension/**' - - '.github/workflows/validate-gemini-extension.yml' - - '.github/workflows/release-gemini-extension.yml' - -jobs: - validate: - runs-on: ubuntu-latest - defaults: - run: - working-directory: nowledge-mem-gemini-cli-extension - - steps: - - name: Check out repository - uses: actions/checkout@v4 - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - - - name: Validate extension package - run: npm run validate - - - name: Verify release packaging - run: npm run package:release diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..396fc61c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "nowledge-mem-gemini-cli"] + path = nowledge-mem-gemini-cli + url = git@github.com:nowledge-co/nowledge-mem-gemini-cli.git diff --git a/README.md b/README.md index d4009e96..3a7c3a4d 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ **Community integrations for [Nowledge Mem](https://mem.nowledge.co)** + [![Discord](https://img.shields.io/badge/Discord-Join%20Community-5865F2?style=flat&logo=discord&logoColor=white)](https://nowled.ge/discord) [![Docs](https://img.shields.io/badge/Docs-Read-orange?style=flat&logo=readthedocs&logoColor=white)](https://nowled.ge/mem-docs) @@ -21,7 +22,7 @@ Each directory is a standalone integration. Pick the one that matches your tool. |-------------|---------|--------------| | **[Skills](nowledge-mem-npx-skills)** | `npx skills add nowledge-co/community/nowledge-mem-npx-skills` | Reusable workflow package for Working Memory, routed recall, resumable handoffs, and distillation. Prefer native packages when your tool has one. | | **[Claude Code Plugin](nowledge-mem-claude-code-plugin)** | `claude plugin marketplace add nowledge-co/community` then `claude plugin install nowledge-mem@nowledge-community` | Claude Code native plugin with hooks for Working Memory bootstrap, routed recall, and automatic session capture. | -| **[Gemini CLI Extension](nowledge-mem-gemini-cli-extension)** | `cd nowledge-mem-gemini-cli-extension && gemini extensions link .` | Gemini-native context, hooks, commands, and skills for Working Memory, routed recall, real thread save, and handoff summaries. | +| **[Gemini CLI](nowledge-mem-gemini-cli)** | `cd nowledge-mem-gemini-cli && gemini extensions link .` | Gemini-native context, hooks, commands, and skills for Working Memory, routed recall, real thread save, and handoff summaries. | | **[Cursor Plugin](nowledge-mem-cursor-plugin)** | Use the packaged Cursor plugin directory with Cursor's plugin workflow | Cursor-native plugin package with bundled MCP config, rules, Working Memory, routed recall, distillation, and honest `save-handoff` semantics. | | **[Codex Prompts](nowledge-mem-codex-prompts)** | Copy `AGENTS.md` to your project | Codex-native workflow pack for Working Memory, routed recall, real session save, and distillation. | | **[OpenClaw Plugin](nowledge-mem-openclaw-plugin)** | `openclaw plugins install @nowledge/openclaw-nowledge-mem` | Full memory lifecycle with memory tools, thread tools, automatic capture, and distillation. | diff --git a/nowledge-mem-gemini-cli b/nowledge-mem-gemini-cli new file mode 160000 index 00000000..0e0a1b6e --- /dev/null +++ b/nowledge-mem-gemini-cli @@ -0,0 +1 @@ +Subproject commit 0e0a1b6e0dc717b0b4a4d25cbf4d8faeead40ae3 diff --git a/nowledge-mem-gemini-cli-extension/.gitignore b/nowledge-mem-gemini-cli-extension/.gitignore deleted file mode 100644 index 849ddff3..00000000 --- a/nowledge-mem-gemini-cli-extension/.gitignore +++ /dev/null @@ -1 +0,0 @@ -dist/ diff --git a/nowledge-mem-gemini-cli-extension/CHANGELOG.md b/nowledge-mem-gemini-cli-extension/CHANGELOG.md deleted file mode 100644 index 9cef99b3..00000000 --- a/nowledge-mem-gemini-cli-extension/CHANGELOG.md +++ /dev/null @@ -1,55 +0,0 @@ -# Changelog - -All notable changes to the Nowledge Mem Gemini CLI extension will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [0.1.2] - 2026-03-10 - -### Changed - -- Hardened the Gemini release packaging flow so the shipped archive better matches what the marketplace crawler expects from a clean extension bundle -- Refined release instructions to explicitly call out archive verification for macOS metadata drift before publishing - -### Fixed - -- Prevented macOS AppleDouble metadata entries such as `._README.md` from being emitted into the release archive -- Added archive verification that fails packaging if hidden metadata files still appear in the generated `.tar.gz` - -## [0.1.1] - 2026-03-09 - -### Changed - -- Clarified the remote-mode contract so real thread save is explicitly described as client-side transcript capture through `nmem`, not server-side filesystem access -- Sharpened release readiness around hook validation, release packaging, and user-facing documentation for the marketplace path -- Polished command, skill, README, website, and lifecycle wording so Working Memory, routed recall, real thread save, distillation, and handoff summaries present one coherent product model - -### Fixed - -- Corrected the Gemini hook schema to use the top-level `hooks` object Gemini expects during extension linking -- Ensured `save-handoff` remains the resumable-summary surface while `save-thread` remains reserved for the real Gemini transcript importer - -## [0.1.0] - 2026-03-07 - -### Added - -- Initial Gemini CLI extension for Nowledge Mem -- Persistent `GEMINI.md` context for working memory, search, distillation, thread-save, and handoff behavior -- Six custom commands: read working memory, search memory, distill memory, save thread, save handoff, and status -- Five agent skills: `read-working-memory`, `search-memory`, `distill-memory`, `save-thread`, and `save-handoff` -- Native Gemini thread-save guidance built around `nmem t save --from gemini-cli` -- Support for `NMEM_API_URL` and `NMEM_API_KEY` shell-level overrides alongside durable `nmem` config-file setup -- CLI-first remote setup guidance built around `~/.nowledge-mem/config.json` -- Release packaging, checksum generation, and GitHub Actions automation for tagged Gemini extension releases -- Release documentation and versioned release notes for reproducible Gemini marketplace publishing -- Native Gemini extension hooks for Working Memory bootstrap at session start and best-effort thread import at session end - -### Changed - -- Tightened the Gemini manifest to better match Gemini CLI extension reference guidance, including a gallery-facing description field -- Improved search, distillation, thread-save, and handoff prompts to prefer stronger `nmem` patterns like JSON mode, `--mode deep`, `--unit-type`, labels, and `-s gemini-cli` -- Corrected Gemini save semantics by restoring `save-thread` for real session import and keeping `save-handoff` as the distinct resumable-summary action -- Refined handoff guidance around a structured summary format with Goal, Decisions, Files, Risks, and Next -- Fixed collapsed multiline command examples in the Gemini skills so the shipped prompts and docs stay clear and copyable -- Clarified same-machine desktop setup, local-default status expectations, Working Memory empty-state behavior, Gemini install UX for local users, and the cross-agent memory lifecycle contract diff --git a/nowledge-mem-gemini-cli-extension/GEMINI.md b/nowledge-mem-gemini-cli-extension/GEMINI.md deleted file mode 100644 index a9e2aacf..00000000 --- a/nowledge-mem-gemini-cli-extension/GEMINI.md +++ /dev/null @@ -1,152 +0,0 @@ -# Nowledge Mem for Gemini CLI - -You have access to the user's Nowledge Mem through the `nmem` CLI. - -This integration is intentionally CLI-first. Use the bundled commands when convenient, but compose direct `nmem` commands whenever that is clearer, more precise, or more efficient. - -## Core Memory Lifecycle - -Treat Nowledge Mem as four linked surfaces: - -1. Working Memory for current focus and active priorities -2. Distilled memories for durable knowledge -3. Threads for full searchable conversation history -4. Handoff summaries for compact resumability when the user wants a manual handoff - -Prefer the smallest surface that answers the user's need, then move upward only when more context is necessary. - -## Connection Model - -`nmem` resolves remote access in this order: - -1. `--api-url` flag -2. `NMEM_API_URL` / `NMEM_API_KEY` -3. `~/.nowledge-mem/config.json` -4. local defaults - -Preferred persistent remote setup: - -```json -{ - "apiUrl": "https://mem.example.com", - "apiKey": "nmem_your_key" -} -``` - -Save it to: - -```text -~/.nowledge-mem/config.json -``` - -## Working Memory - -At the start of a session, or when recent priorities would help, read Working Memory with: - -```bash -nmem --json wm read -``` - -If the command succeeds but returns `exists: false`, there is no Working Memory briefing yet. Say that clearly instead of pretending a briefing exists. - -Only fall back to the legacy file below for older local-only setups where the user still keeps Working Memory there: - -```bash -test -f ~/ai-now/memory.md && cat ~/ai-now/memory.md -``` - -Read Working Memory once near the start of a session, then reuse that context mentally. Do not re-read on every turn unless the user asks, the session context changed materially, or a long-running session clearly needs a refresh. - -## Search Memory - -Search past knowledge when: - -- the user references previous work, a prior fix, or an earlier decision -- the task resumes a named feature, bug, refactor, incident, or subsystem -- a debugging pattern resembles something solved earlier -- the user asks for rationale, preferences, procedures, or recurring workflow details -- the current result is ambiguous and prior context would make the answer sharper - -Start with durable recall: - -```bash -nmem --json m search "query" -``` - -If the recall need is conceptual or the first pass is weak, use deep search: - -```bash -nmem --json m search "query" --mode deep -``` - -If the user is really asking about a previous conversation or session, search threads directly: - -```bash -nmem --json t search "query" --limit 5 -``` - -If a memory search result includes `source_thread`, or thread search finds the likely conversation, inspect it progressively instead of loading the whole thread at once: - -```bash -nmem --json t show --limit 8 --offset 0 --content-limit 1200 -``` - -Prefer the smallest retrieval surface that answers the question. - -## Distill Memory - -Distill only durable knowledge worth keeping after the current session ends. - -Use `memory_add` for genuinely new decisions, procedures, lessons, preferences, or plans: - -```bash -nmem --json m add "Insight with enough context to stand on its own." -t "Searchable title" -i 0.8 --unit-type decision -l project-name -s gemini-cli -``` - -If an existing memory already captures the same decision, workflow, or preference and the new information refines it, update that memory instead of creating a duplicate: - -```bash -nmem m update -t "Updated title" -``` - -## Save Thread - -Only save a thread when the user explicitly asks to persist the real Gemini session. The extension also performs a best-effort automatic thread import on session end, so this command is mainly for explicit mid-session capture or immediate confirmation. - -This is a real session import, not a summary fallback. Use: - -```bash -nmem --json t save --from gemini-cli -p . -s "Brief summary of what was accomplished" -``` - -The summary is metadata only. The saved thread should come from Gemini's recorded session transcript. - -If the user wants a specific older Gemini session, add `--session-id`. - -## Save Handoff - -Only save a handoff when the user explicitly asks for a resumable summary rather than a full session import. Think of this as a handoff summary, not a transcript save. - -Structure the checkpoint around: - -- Goal -- Major decisions -- Files or surfaces touched -- Open questions or risks -- Next steps - -Then store it with: - -```bash -nmem --json t create -t "Gemini CLI Session - topic" -c "Goal: ... Decisions: ... Files: ... Risks: ... Next: ..." -s gemini-cli -``` - -## Status - -When setup seems broken, run: - -```bash -nmem status -``` - -Be concise, use memory tools naturally, and avoid saving routine or low-value chatter. diff --git a/nowledge-mem-gemini-cli-extension/README.md b/nowledge-mem-gemini-cli-extension/README.md deleted file mode 100644 index a7b2a78c..00000000 --- a/nowledge-mem-gemini-cli-extension/README.md +++ /dev/null @@ -1,156 +0,0 @@ -# Nowledge Mem -- Gemini CLI Extension - -> Bring your Nowledge Mem knowledge base into Gemini CLI with persistent context, reusable slash commands, and agent skills. - -This package is the **Gemini-native product surface** for Nowledge Mem. - -It is deliberately **CLI-first**: - -- Gemini CLI loads `GEMINI.md` plus extension hooks for Working Memory bootstrap and session capture -- bundled commands wrap common `nmem` workflows -- bundled skills teach Gemini when to recall, distill, save real threads, and create handoff summaries -- Gemini can still call `nmem` directly whenever it needs a more flexible path - -The recommended Gemini setup is deliberately simple and stable: Gemini CLI on top, `nmem` underneath. That keeps auth, debugging, and command composition in one place. - -## Requirements - -- [Gemini CLI](https://github.com/google-gemini/gemini-cli) -- [Nowledge Mem](https://mem.nowledge.co) running locally, or a reachable remote Nowledge Mem server -- `nmem` CLI in your `PATH` - -If Nowledge Mem is already running on the same machine through the desktop app, the cleanest setup is to install the bundled CLI from **Settings -> Preferences -> Developer Tools -> Install CLI**. That gives Gemini direct access to the local Mem instance without any remote configuration. - -You can also install `nmem` standalone: - -```bash -# Option 1: pip -pip install nmem-cli - -# Option 2: uvx -curl -LsSf https://astral.sh/uv/install.sh | sh -uvx --from nmem-cli nmem --version -``` - -Verify the connection: - -```bash -nmem status -``` - -For the default same-machine setup, `nmem status` should show `http://127.0.0.1:14242 (default)`. No `~/.nowledge-mem/config.json` is required unless you are connecting to a remote Mem server. - -## Install - -Until this extension ships as a standalone Gemini extension package, install it from a local checkout: - -```bash -git clone https://github.com/nowledge-co/community.git -cd community/nowledge-mem-gemini-cli-extension -gemini extensions link . -``` - -Restart Gemini CLI after linking. - -Gemini's extension release flow expects `gemini-extension.json` at the root of the installable package. This directory already follows that layout, so it can later be published cleanly as its own release artifact without changing the extension design. - -Release packaging and marketplace notes live in [`RELEASING.md`](./RELEASING.md). - -## What You Get - -**Automatic lifecycle hooks** - -- Session start loads Working Memory into Gemini when a briefing exists -- Session end performs a best-effort real Gemini thread import through `nmem t save --from gemini-cli` - -**Persistent context** - -- `GEMINI.md` tells Gemini how to route recall across Working Memory, distilled memories, conversation threads, thread save, distillation, and handoff summaries - -**Custom commands** - -- `/nowledge:read-working-memory` -- Load today's Working Memory briefing -- `/nowledge:search-memory ` -- Search your knowledge base before answering -- `/nowledge:distill-memory` -- Save the high-value insights from the current conversation -- `/nowledge:save-thread` -- Save the real Gemini CLI session through `nmem`'s native Gemini importer -- `/nowledge:save-handoff` -- Save a concise resumable handoff summary for the current Gemini session -- `/nowledge:status` -- Check `nmem` and server connectivity - -**Agent skills** - -- `read-working-memory` -- `search-memory` -- `distill-memory` -- `save-thread` -- `save-handoff` - -## Local vs Remote - -By default, `nmem` connects to the local Mem server at `http://127.0.0.1:14242`. - -For remote Mem, the preferred long-term setup is: - -```json -{ - "apiUrl": "https://mem.example.com", - "apiKey": "nmem_your_key" -} -``` - -Save that to: - -```text -~/.nowledge-mem/config.json -``` - -`nmem` loads connection settings with this priority: - -- `--api-url` flag -- `NMEM_API_URL` / `NMEM_API_KEY` -- `~/.nowledge-mem/config.json` -- defaults - -If you need a temporary override for one Gemini session, launch Gemini from a shell where `NMEM_API_URL` and `NMEM_API_KEY` are already exported. For durable setup, keep using `~/.nowledge-mem/config.json`. - -For thread save in remote mode, the important detail is that `nmem t save --from gemini-cli` reads Gemini's local session files on the machine running Gemini, then uploads the normalized thread messages to Mem. The remote Mem server does not need direct access to your `~/.gemini` directory. - -## Direct `nmem` Use Is Always Allowed - -The bundled commands are convenience paths, not a cage. Gemini should freely compose direct `nmem` commands when that is clearer or more flexible. - -Examples: - -```bash -nmem --json wm read -nmem --json m search "auth token rotation" --mode deep --importance 0.7 -nmem --json m add "JWT refresh failures came from clock skew between the gateway and API nodes." -t "JWT refresh failures traced to clock skew" -i 0.9 --unit-type learning -l auth -l backend -s gemini-cli -nmem --json t save --from gemini-cli -p . -s "Finished the auth refactor and verified the new refresh-token flow." -nmem --json t create -t "Gemini CLI Session - auth refactor" -c "Goal: finish the auth refactor. Decisions: keep refresh verification in the API layer and treat gateway skew as the root cause. Files: api/auth.ts, auth.test.ts. Next: validate expiry behavior against remote sessions." -s gemini-cli -nmem status -``` - -## Thread Save vs Handoff - -Gemini now supports two separate save paths, and they should stay distinct: - -- `/nowledge:save-thread` imports the **real Gemini session messages** into Nowledge Mem with `nmem t save --from gemini-cli`. The summary is only metadata; the stored thread is based on Gemini's recorded transcript. The extension also performs this import automatically at session end as a best-effort, idempotent lifecycle hook. -- `/nowledge:save-handoff` creates a **compact resumable handoff summary** with Goal, Decisions, Files, Risks, and Next. Use this when the user wants a lightweight restart point rather than the full transcript. - -Use `/nowledge:distill-memory` for durable atomic knowledge, `/nowledge:save-thread` for the full session, and `/nowledge:save-handoff` for a resumable handoff. - -## Architecture Choice - -This integration keeps the control plane simple: - -- Gemini provides the extension surface: `GEMINI.md`, commands, and skills -- `nmem` provides the execution path: memory search, Working Memory, capture, thread import, and remote auth -- direct `nmem` composition stays available whenever Gemini needs a more flexible command path - -The result is a setup that is easier to reason about, easier to support, and easier for advanced users to extend. - -## Links - -- [Documentation](https://mem.nowledge.co/docs/integrations/gemini-cli) -- [Nowledge Mem](https://mem.nowledge.co) -- [Discord](https://nowled.ge/discord) -- [GitHub](https://github.com/nowledge-co/community) diff --git a/nowledge-mem-gemini-cli-extension/RELEASING.md b/nowledge-mem-gemini-cli-extension/RELEASING.md deleted file mode 100644 index 74e089cb..00000000 --- a/nowledge-mem-gemini-cli-extension/RELEASING.md +++ /dev/null @@ -1,101 +0,0 @@ -# Releasing the Gemini CLI Extension - -This extension lives inside the `community` repository, so Gemini release readiness should use the **release archive** path from Gemini's extension docs rather than assuming the repository root is the extension root. - -## Why This Release Path - -Gemini's release docs require `gemini-extension.json` to be at the root of the repository **or the release archive**. - -In this repo, the extension lives at `nowledge-mem-gemini-cli-extension/`, not the repository root. That means: - -- local development should keep using `gemini extensions link .` -- public release and marketplace discovery should use a packaged archive whose root is this extension directory - -## Manual Prerequisites - -These are required for Gemini's gallery crawler, but cannot be enforced purely by files in this directory: - -- the GitHub repository must be public -- the repository About section must include the `gemini-cli-extension` topic -- the release must be tagged and published on GitHub -- the attached archive must contain `gemini-extension.json` at the archive root -- the attached archive must be free of macOS AppleDouble metadata entries such as `._README.md` - -## Validate Locally - -```bash -cd community/nowledge-mem-gemini-cli-extension -npm run validate -``` - -## Build The Release Artifact - -```bash -cd community/nowledge-mem-gemini-cli-extension -npm run package:release -``` - -Or run the full pre-release check: - -```bash -cd community/nowledge-mem-gemini-cli-extension -npm run verify:release -``` - -This produces: - -- `dist/nowledge-mem-gemini-cli-extension.tar.gz` -- `dist/nowledge-mem-gemini-cli-extension.tar.gz.sha256` - -The archive is intentionally flat at the root so Gemini can inspect it as an installable extension package. - -## CI Verification - -Pull requests and relevant pushes run the `Validate Gemini Extension` workflow. That workflow validates the manifest and also rebuilds the release archive so packaging drift is caught before tagging. - -## Tagging Convention - -The GitHub Actions workflow watches tags in this form: - -```text -nowledge-mem-gemini-cli-extension-v* -``` - -Example: - -```bash -git tag nowledge-mem-gemini-cli-extension-v0.1.2 -git push origin nowledge-mem-gemini-cli-extension-v0.1.2 -``` - -## Initial Public Release - -For the first public release, use: - -- tag: `nowledge-mem-gemini-cli-extension-v0.1.2` -- release title: `Nowledge Mem Gemini CLI Extension v0.1.2` -- release notes source: `release-notes/0.1.2.md` -- workflow behavior: the release workflow verifies that the pushed tag matches `package.json` and publishes the matching `release-notes/.md` file as the GitHub Release body - -## Installation After Release - -Once the tagged GitHub Release exists, Gemini users can install from the repository and ref: - -```bash -gemini extensions install github.com/nowledge-co/community --ref nowledge-mem-gemini-cli-extension-v0.1.2 -``` - -Gemini's own release docs say GitHub Releases are supported as install sources, and the workflow-created archive is shaped specifically for that path. - -## Release Checklist - -- bump `version` in `package.json` and `gemini-extension.json` -- update `CHANGELOG.md` -- add `release-notes/.md` -- run `npm run verify:release` -- confirm the archive root contains `gemini-extension.json`, `package.json`, `GEMINI.md`, `commands/`, and `skills/` -- create and push a matching tag -- publish the GitHub Release with the generated `.tar.gz` asset and checksum -- verify the repo still has the `gemini-cli-extension` topic -- verify the archive contents with `tar -tzf dist/nowledge-mem-gemini-cli-extension.tar.gz` and make sure there are no `._*` entries -- verify discovery on `geminicli.com/extensions` after the crawler runs diff --git a/nowledge-mem-gemini-cli-extension/commands/nowledge/distill-memory.toml b/nowledge-mem-gemini-cli-extension/commands/nowledge/distill-memory.toml deleted file mode 100644 index 91ee6fcd..00000000 --- a/nowledge-mem-gemini-cli-extension/commands/nowledge/distill-memory.toml +++ /dev/null @@ -1,19 +0,0 @@ -prompt = """ -Distill the most valuable insights from the current Gemini CLI conversation into Nowledge Mem. - -Workflow: - -1. Identify 1-3 durable insights, decisions, lessons, procedures, or preferences. -2. Skip routine chatter, unresolved half-ideas, and low-signal implementation noise. -3. If a memory looks likely to already exist, search first instead of creating a duplicate. -4. Use the shell tool to run `nmem --json m add` for each selected memory. -5. Use strong titles, a fitting `--unit-type`, and 0-3 labels only when they improve retrieval. -6. Set `-s gemini-cli` so the capture path stays auditable. - -Importance guide: -- `0.6-0.7`: useful but routine durable knowledge -- `0.8-0.9`: major lesson, decision, or breakthrough -- `1.0`: rare, foundational memory - -After saving, report what was stored, which unit types were used, and why each memory was worth keeping. -""" diff --git a/nowledge-mem-gemini-cli-extension/commands/nowledge/read-working-memory.toml b/nowledge-mem-gemini-cli-extension/commands/nowledge/read-working-memory.toml deleted file mode 100644 index f2aab663..00000000 --- a/nowledge-mem-gemini-cli-extension/commands/nowledge/read-working-memory.toml +++ /dev/null @@ -1,21 +0,0 @@ -prompt = """ -Load the user's Working Memory briefing before continuing. - -Use the shell tool to try: - -```bash -nmem --json wm read -``` - -If the command succeeds but reports that no Working Memory exists yet, say that clearly. - -Only if `nmem` is unavailable in an older local-only setup, fall back to: - -```bash -cat ~/ai-now/memory.md -``` - -Then summarize the user's active focus areas, priorities, unresolved flags, and the most relevant recent changes when a briefing is actually present. - -If remote access is configured through `~/.nowledge-mem/config.json`, let `nmem` use it naturally. Do not assume environment variables are the only auth path. -""" diff --git a/nowledge-mem-gemini-cli-extension/commands/nowledge/save-handoff.toml b/nowledge-mem-gemini-cli-extension/commands/nowledge/save-handoff.toml deleted file mode 100644 index 4f7dccc5..00000000 --- a/nowledge-mem-gemini-cli-extension/commands/nowledge/save-handoff.toml +++ /dev/null @@ -1,16 +0,0 @@ -prompt = """ -Save a concise handoff summary of the current Gemini CLI session to Nowledge Mem. - -This command is intentionally a handoff-summary action, not a full thread importer. - -If the user wants the real Gemini session messages, use `/nowledge:save-thread` instead. - -Workflow: - -1. Write a short structured handoff with these fields: Goal, Decisions, Files, Risks, Next. -2. Use the shell tool to create a handoff thread with `nmem --json t create -s gemini-cli`. -3. Use a title in the form `Gemini CLI Session - `. -4. Return the created handoff title and the summary that was stored. - -Keep the handoff concise, honest, and useful for resuming work later. -""" diff --git a/nowledge-mem-gemini-cli-extension/commands/nowledge/save-thread.toml b/nowledge-mem-gemini-cli-extension/commands/nowledge/save-thread.toml deleted file mode 100644 index 67134e1d..00000000 --- a/nowledge-mem-gemini-cli-extension/commands/nowledge/save-thread.toml +++ /dev/null @@ -1,15 +0,0 @@ -prompt = """ -Save the real Gemini CLI session to Nowledge Mem. - -This command should persist the actual Gemini session messages, not a summary-only checkpoint. - -Workflow: - -1. Write a short 1-2 sentence summary of what was accomplished. -2. Use the shell tool to run `nmem --json t save --from gemini-cli -p . -s ""`. -3. If the user clearly wants a specific older Gemini session, add `--session-id`. -4. Report whether the thread was created or updated, how many messages were stored, and the thread id. -5. If no Gemini session is found, explain that plainly and suggest `/nowledge:save-handoff` only when the user wants a manual resumable summary instead. - -Do not replace thread-save with `t create`. `save-thread` means importing the recorded Gemini session. -""" diff --git a/nowledge-mem-gemini-cli-extension/commands/nowledge/search-memory.toml b/nowledge-mem-gemini-cli-extension/commands/nowledge/search-memory.toml deleted file mode 100644 index df1f1a99..00000000 --- a/nowledge-mem-gemini-cli-extension/commands/nowledge/search-memory.toml +++ /dev/null @@ -1,18 +0,0 @@ -prompt = """ -Search Nowledge Mem for the user's query: `{{args}}`. - -Workflow: - -1. Rewrite the request into a short retrieval query rather than copying a long prompt verbatim. -2. Start with `nmem --json m search` for distilled knowledge. -3. If the user is asking about a prior conversation, previous session, or exact discussion, or if memory search is weak, use `nmem --json t search` too. -4. If a memory result includes `source_thread` or thread search returns a strong hit, inspect that conversation with `nmem --json t show --limit 8 --offset 0 --content-limit 1200` and page further only when needed. -5. If the recall need is conceptual, historical, or the first memory search is weak, run a second pass with `--mode deep`. -6. Add filters only when the task clearly implies them: - - labels for project or domain scoping - - `--importance` for high-signal recall - - `--event-from` / `--recorded-from` when time matters -7. Summarize only the strongest matches, mention memory ids or source threads when helpful, and clearly say when nothing relevant was found. - -Prefer precise retrieval queries over raw prompts. Use direct `nmem` composition freely when the bundled command shape is not enough. -""" diff --git a/nowledge-mem-gemini-cli-extension/commands/nowledge/status.toml b/nowledge-mem-gemini-cli-extension/commands/nowledge/status.toml deleted file mode 100644 index cbe6bef5..00000000 --- a/nowledge-mem-gemini-cli-extension/commands/nowledge/status.toml +++ /dev/null @@ -1,17 +0,0 @@ -prompt = """ -Check whether Nowledge Mem is reachable from Gemini CLI. - -Use the shell tool to run: - -```bash -nmem status -``` - -Summarize: -- whether the CLI can reach Mem -- the effective API URL -- the config source reported by `nmem` (`env`, `config`, or `default`) -- whether a config file is present or malformed -- whether remote auth appears to be set when the API URL is remote -- the next concrete fix if setup is broken -""" diff --git a/nowledge-mem-gemini-cli-extension/gemini-extension.json b/nowledge-mem-gemini-cli-extension/gemini-extension.json deleted file mode 100644 index ac2cdbff..00000000 --- a/nowledge-mem-gemini-cli-extension/gemini-extension.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "nowledge-mem-gemini-cli-extension", - "version": "0.1.2", - "description": "Gemini CLI extension for Nowledge Mem with persistent context, memory commands, and agent skills.", - "contextFileName": "GEMINI.md" -} diff --git a/nowledge-mem-gemini-cli-extension/hooks/hooks.json b/nowledge-mem-gemini-cli-extension/hooks/hooks.json deleted file mode 100644 index 3220ebbe..00000000 --- a/nowledge-mem-gemini-cli-extension/hooks/hooks.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "hooks": { - "SessionStart": [ - { - "hooks": [ - { - "name": "load-working-memory", - "type": "command", - "command": "node \"${extensionPath}${/}hooks${/}session-start.mjs\"", - "description": "Load Working Memory into Gemini at session start.", - "timeout": 10000 - } - ] - } - ], - "SessionEnd": [ - { - "hooks": [ - { - "name": "auto-save-thread", - "type": "command", - "command": "node \"${extensionPath}${/}hooks${/}session-end.mjs\"", - "description": "Best-effort Gemini session import on shutdown.", - "timeout": 20000 - } - ] - } - ] - } -} diff --git a/nowledge-mem-gemini-cli-extension/hooks/session-end.mjs b/nowledge-mem-gemini-cli-extension/hooks/session-end.mjs deleted file mode 100644 index 6f9d1b1e..00000000 --- a/nowledge-mem-gemini-cli-extension/hooks/session-end.mjs +++ /dev/null @@ -1,31 +0,0 @@ -import { spawnSync } from 'node:child_process'; -import { readFileSync } from 'node:fs'; - -function readHookInput() { - try { - const raw = readFileSync(0, 'utf8'); - return raw.trim() ? JSON.parse(raw) : {}; - } catch { - return {}; - } -} - -const hookInput = readHookInput(); -const cwd = typeof hookInput.cwd === 'string' && hookInput.cwd.trim() - ? hookInput.cwd - : process.cwd(); -const sessionId = typeof hookInput.session_id === 'string' && hookInput.session_id.trim() - ? hookInput.session_id - : undefined; - -const args = ['--json', 't', 'save', '--from', 'gemini-cli', '-p', cwd, '--truncate']; -if (sessionId) { - args.push('--session-id', sessionId); -} - -spawnSync('nmem', args, { - encoding: 'utf8', - timeout: 20000, -}); - -process.stdout.write(JSON.stringify({ suppressOutput: true })); diff --git a/nowledge-mem-gemini-cli-extension/hooks/session-start.mjs b/nowledge-mem-gemini-cli-extension/hooks/session-start.mjs deleted file mode 100644 index 5abf87f1..00000000 --- a/nowledge-mem-gemini-cli-extension/hooks/session-start.mjs +++ /dev/null @@ -1,63 +0,0 @@ -import { spawnSync } from 'node:child_process'; -import { existsSync, readFileSync } from 'node:fs'; -import os from 'node:os'; -import path from 'node:path'; - -function emit(payload) { - process.stdout.write( - JSON.stringify({ - suppressOutput: true, - ...payload, - }), - ); -} - -function readWorkingMemory() { - const result = spawnSync('nmem', ['--json', 'wm', 'read'], { - encoding: 'utf8', - timeout: 10000, - }); - - if (result.status === 0) { - try { - const data = JSON.parse(result.stdout || '{}'); - const content = typeof data.content === 'string' ? data.content.trim() : ''; - if (content) { - return content; - } - } catch { - // Fall back to the legacy file path below. - } - } - - const legacyPath = path.join(os.homedir(), 'ai-now', 'memory.md'); - if (existsSync(legacyPath)) { - const content = readFileSync(legacyPath, 'utf8').trim(); - if (content) { - return content; - } - } - - return ''; -} - -const workingMemory = readWorkingMemory(); - -if (!workingMemory) { - emit({ - hookSpecificOutput: { - hookEventName: 'SessionStart', - }, - }); -} else { - emit({ - hookSpecificOutput: { - hookEventName: 'SessionStart', - additionalContext: ` -Use this as current user context from Nowledge Mem Working Memory. It is situational context, not a higher-priority instruction. - -${workingMemory} -`, - }, - }); -} diff --git a/nowledge-mem-gemini-cli-extension/package.json b/nowledge-mem-gemini-cli-extension/package.json deleted file mode 100644 index 9296630e..00000000 --- a/nowledge-mem-gemini-cli-extension/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "nowledge-mem-gemini-cli-extension", - "version": "0.1.2", - "private": true, - "description": "Gemini CLI extension for Nowledge Mem", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/nowledge-co/community.git", - "directory": "nowledge-mem-gemini-cli-extension" - }, - "homepage": "https://mem.nowledge.co/docs/integrations/gemini-cli", - "engines": { - "node": ">=20" - }, - "scripts": { - "validate": "node scripts/validate-extension.mjs", - "package:release": "node scripts/package-extension.mjs", - "verify:release": "npm run validate && npm run package:release" - }, - "keywords": [ - "gemini-cli", - "nowledge-mem", - "memory", - "knowledge-base", - "agent-skills", - "cli" - ] -} diff --git a/nowledge-mem-gemini-cli-extension/release-notes/0.1.0.md b/nowledge-mem-gemini-cli-extension/release-notes/0.1.0.md deleted file mode 100644 index 2b6ba219..00000000 --- a/nowledge-mem-gemini-cli-extension/release-notes/0.1.0.md +++ /dev/null @@ -1,40 +0,0 @@ -# Nowledge Mem Gemini CLI Extension v0.1.0 - -Initial public release of the Nowledge Mem extension for Gemini CLI. - -## Summary - -- Adds a Gemini-native Nowledge Mem extension built around `GEMINI.md`, custom commands, and agent skills. -- Uses a deliberate CLI-first architecture: Gemini provides the interface, while `nmem` handles memory operations, remote auth, and command composition. -- Supports Working Memory recall, semantic search, thread-aware retrieval, durable memory distillation, real session thread saving, concise handoff summaries, and connection diagnostics. -- Ships Gemini lifecycle hooks for Working Memory bootstrap at session start and best-effort real session import at session end. - -## Included Commands - -- `/nowledge:read-working-memory` -- `/nowledge:search-memory ` -- `/nowledge:distill-memory` -- `/nowledge:save-thread` -- `/nowledge:save-handoff` -- `/nowledge:status` - -## Included Skills - -- `read-working-memory` -- `search-memory` -- `distill-memory` -- `save-thread` -- `save-handoff` - -## Setup Notes - -- Preferred persistent remote setup uses `~/.nowledge-mem/config.json` through `nmem`. -- `NMEM_API_URL` and `NMEM_API_KEY` can still be used as shell-level overrides when you want to launch Gemini with a temporary remote target. -- `/nowledge:save-thread` now uses `nmem t save --from gemini-cli` for real Gemini session import. -- `/nowledge:save-handoff` remains available for structured resumable summaries created with `nmem t create`. - -## Install - -```bash -gemini extensions install github.com/nowledge-co/community --ref nowledge-mem-gemini-cli-extension-v0.1.0 -``` diff --git a/nowledge-mem-gemini-cli-extension/release-notes/0.1.1.md b/nowledge-mem-gemini-cli-extension/release-notes/0.1.1.md deleted file mode 100644 index 394c7257..00000000 --- a/nowledge-mem-gemini-cli-extension/release-notes/0.1.1.md +++ /dev/null @@ -1,21 +0,0 @@ -# Nowledge Mem Gemini CLI Extension v0.1.1 - -Release hardening update for the Gemini CLI extension. - -## Summary - -- Clarifies that `save-thread` remains the real Gemini transcript-backed capture path and that remote Mem setups still read transcript files locally through `nmem` on the Gemini machine. -- Fixes the hook schema to match Gemini's expected top-level `hooks` object. -- Sharpens the package, docs, and release assets so the extension is safer to ship and easier to review in the Gemini marketplace flow. - -## Operational Notes - -- Preferred persistent remote setup remains `~/.nowledge-mem/config.json` through `nmem`. -- `save-handoff` remains the honest resumable-summary surface. -- Release validation and packaging continue to run through `npm run verify:release`. - -## Install - -```bash -gemini extensions install github.com/nowledge-co/community --ref nowledge-mem-gemini-cli-extension-v0.1.1 -``` diff --git a/nowledge-mem-gemini-cli-extension/release-notes/0.1.2.md b/nowledge-mem-gemini-cli-extension/release-notes/0.1.2.md deleted file mode 100644 index 4e83f9e5..00000000 --- a/nowledge-mem-gemini-cli-extension/release-notes/0.1.2.md +++ /dev/null @@ -1,21 +0,0 @@ -# Nowledge Mem Gemini CLI Extension v0.1.2 - -Release packaging hardening update for the Gemini CLI extension. - -## Summary - -- Prevents macOS AppleDouble metadata files from leaking into the published release archive. -- Fails packaging early if hidden metadata entries still appear, so bad archives are caught before tagging or upload. -- Tightens the release checklist and examples so the GitHub Release asset matches what Gemini marketplace discovery expects. - -## Operational Notes - -- Run `npm run verify:release` before tagging. -- Publish the generated `.tar.gz` plus checksum from `dist/`. -- Keep using the matching tag name `nowledge-mem-gemini-cli-extension-v0.1.2`. - -## Install - -```bash -gemini extensions install github.com/nowledge-co/community --ref nowledge-mem-gemini-cli-extension-v0.1.2 -``` diff --git a/nowledge-mem-gemini-cli-extension/scripts/package-extension.mjs b/nowledge-mem-gemini-cli-extension/scripts/package-extension.mjs deleted file mode 100644 index a2346658..00000000 --- a/nowledge-mem-gemini-cli-extension/scripts/package-extension.mjs +++ /dev/null @@ -1,128 +0,0 @@ -import { cp, mkdir, readFile, rm, writeFile } from 'node:fs/promises'; -import { createHash } from 'node:crypto'; -import { spawnSync } from 'node:child_process'; -import path from 'node:path'; -import process from 'node:process'; -import { fileURLToPath } from 'node:url'; - -const extensionRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); -const distDir = path.join(extensionRoot, 'dist'); -const archiveName = 'nowledge-mem-gemini-cli-extension.tar.gz'; -const archivePath = path.join(distDir, archiveName); -const stageDir = path.join(distDir, 'release-root'); -const filesToShip = [ - 'gemini-extension.json', - 'package.json', - 'README.md', - 'CHANGELOG.md', - 'GEMINI.md', - 'commands', - 'skills', - 'hooks' -]; -const requiredArchiveEntries = new Set([ - './gemini-extension.json', - './package.json', - './README.md', - './CHANGELOG.md', - './GEMINI.md', - './commands/nowledge/read-working-memory.toml', - './commands/nowledge/search-memory.toml', - './commands/nowledge/distill-memory.toml', - './commands/nowledge/save-thread.toml', - './commands/nowledge/save-handoff.toml', - './commands/nowledge/status.toml', - './hooks/hooks.json', - './hooks/session-start.mjs', - './hooks/session-end.mjs', - './skills/read-working-memory/SKILL.md', - './skills/search-memory/SKILL.md', - './skills/distill-memory/SKILL.md', - './skills/save-thread/SKILL.md', - './skills/save-handoff/SKILL.md' -]); - -function run(command, args, cwd = extensionRoot, options = {}) { - const result = spawnSync(command, args, { cwd, stdio: 'inherit', ...options }); - if (result.status !== 0) { - process.exit(result.status ?? 1); - } - return result; -} - -async function fileSha256(filePath) { - const contents = await readFile(filePath); - return createHash('sha256').update(contents).digest('hex'); -} - -function verifyArchive(filePath) { - const result = spawnSync('tar', ['-tzf', filePath], { - cwd: extensionRoot, - encoding: 'utf8' - }); - if (result.status !== 0) { - process.exit(result.status ?? 1); - } - - const rawEntries = result.stdout - .split('\n') - .map((line) => line.trim()) - .filter(Boolean); - - const entries = new Set( - rawEntries.map((line) => { - if (line === '.') return './'; - return line.startsWith('./') ? line : `./${line}`; - }) - ); - - for (const entry of rawEntries) { - const normalized = entry.startsWith('./') ? entry.slice(2) : entry; - if (normalized === '._.' || normalized.startsWith('._') || normalized.includes('/._')) { - console.error(`ERROR: release archive contains macOS metadata entry ${entry}`); - process.exit(1); - } - } - - for (const requiredEntry of requiredArchiveEntries) { - if (!entries.has(requiredEntry)) { - console.error(`ERROR: release archive is missing ${requiredEntry}`); - process.exit(1); - } - } -} - -async function main() { - run('node', ['scripts/validate-extension.mjs']); - - await rm(distDir, { recursive: true, force: true }); - await mkdir(stageDir, { recursive: true }); - - for (const relPath of filesToShip) { - await cp(path.join(extensionRoot, relPath), path.join(stageDir, relPath), { - recursive: true, - force: true - }); - } - - run('tar', ['-czf', archivePath, '-C', stageDir, '.'], extensionRoot, { - env: { - ...process.env, - COPYFILE_DISABLE: '1' - } - }); - verifyArchive(archivePath); - - const checksum = await fileSha256(archivePath); - await writeFile( - path.join(distDir, `${archiveName}.sha256`), - `${checksum} ${archiveName} -`, - 'utf8' - ); - - console.log(`Created ${archivePath}`); - console.log(`Created ${path.join(distDir, `${archiveName}.sha256`)}`); -} - -await main(); diff --git a/nowledge-mem-gemini-cli-extension/scripts/validate-extension.mjs b/nowledge-mem-gemini-cli-extension/scripts/validate-extension.mjs deleted file mode 100644 index 5ab8616d..00000000 --- a/nowledge-mem-gemini-cli-extension/scripts/validate-extension.mjs +++ /dev/null @@ -1,106 +0,0 @@ -import { readFile } from 'node:fs/promises'; -import path from 'node:path'; -import process from 'node:process'; -import { fileURLToPath } from 'node:url'; - -const extensionRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); -const manifestPath = path.join(extensionRoot, 'gemini-extension.json'); -const packageJsonPath = path.join(extensionRoot, 'package.json'); - -function fail(message) { - console.error(`ERROR: ${message}`); - process.exit(1); -} - -async function readJson(filePath) { - const text = await readFile(filePath, 'utf8'); - return JSON.parse(text); -} - -function assertString(value, label) { - if (typeof value !== 'string' || value.trim() === '') { - fail(`${label} must be a non-empty string`); - } -} - -async function main() { - const manifest = await readJson(manifestPath); - const packageJson = await readJson(packageJsonPath); - const extensionDirName = path.basename(extensionRoot); - - assertString(manifest.name, 'manifest.name'); - assertString(manifest.version, 'manifest.version'); - assertString(manifest.description, 'manifest.description'); - - if (manifest.name !== extensionDirName) { - fail(`manifest.name must match directory name (${extensionDirName})`); - } - - if (manifest.version !== packageJson.version) { - fail(`manifest.version (${manifest.version}) must match package.json version (${packageJson.version})`); - } - - if (manifest.contextFileName !== 'GEMINI.md') { - fail('manifest.contextFileName must be GEMINI.md'); - } - - if (manifest.settings !== undefined && !Array.isArray(manifest.settings)) { - fail('manifest.settings must be an array when present'); - } - - const requiredPaths = [ - 'GEMINI.md', - 'README.md', - 'CHANGELOG.md', - 'RELEASING.md', - 'commands/nowledge/read-working-memory.toml', - 'commands/nowledge/search-memory.toml', - 'commands/nowledge/distill-memory.toml', - 'commands/nowledge/save-thread.toml', - 'commands/nowledge/save-handoff.toml', - 'commands/nowledge/status.toml', - 'hooks/hooks.json', - 'hooks/session-start.mjs', - 'hooks/session-end.mjs', - 'skills/read-working-memory/SKILL.md', - 'skills/search-memory/SKILL.md', - 'skills/distill-memory/SKILL.md', - 'skills/save-thread/SKILL.md', - 'skills/save-handoff/SKILL.md', - 'scripts/validate-extension.mjs', - 'scripts/package-extension.mjs', - `release-notes/${manifest.version}.md` - ]; - - for (const relPath of requiredPaths) { - const absPath = path.join(extensionRoot, relPath); - try { - const text = await readFile(absPath, 'utf8'); - if (text.trim() === '') { - fail(`${relPath} must not be empty`); - } - - if (relPath === 'hooks/hooks.json') { - const hooksConfig = JSON.parse(text); - if ( - !hooksConfig || - typeof hooksConfig !== 'object' || - typeof hooksConfig.hooks !== 'object' || - hooksConfig.hooks === null || - Array.isArray(hooksConfig.hooks) - ) { - fail('hooks/hooks.json must contain a top-level "hooks" object'); - } - } - } catch (error) { - if (error instanceof SyntaxError) { - fail(`${relPath} must contain valid JSON`); - } - fail(`missing required file: ${relPath}`); - } - } - - console.log('Validated Gemini extension manifest, version alignment, and required release files.'); -} - -await main(); diff --git a/nowledge-mem-gemini-cli-extension/skills/distill-memory/SKILL.md b/nowledge-mem-gemini-cli-extension/skills/distill-memory/SKILL.md deleted file mode 100644 index 1889fe57..00000000 --- a/nowledge-mem-gemini-cli-extension/skills/distill-memory/SKILL.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -name: distill-memory -description: Detect breakthrough moments, durable lessons, and decisions worth preserving. Suggest distillation sparingly, then store high-value knowledge as atomic memories. ---- - -# Distill Memory - -Store only knowledge that should remain useful after the current session ends. - -## Good Candidates - -- decisions with rationale -- repeatable procedures -- lessons from debugging or incident work -- durable preferences or constraints -- plans that future sessions will need to resume cleanly - -## Add vs Update - -- Use `nmem --json m add` when the insight is genuinely new. -- If an existing memory already captures the same decision, workflow, or preference and the new information refines it, use `nmem m update ...` instead of creating a duplicate. - -Prefer atomic, standalone memories with strong titles and structured meaning. Focus on what was learned or decided, not routine chatter. diff --git a/nowledge-mem-gemini-cli-extension/skills/read-working-memory/SKILL.md b/nowledge-mem-gemini-cli-extension/skills/read-working-memory/SKILL.md deleted file mode 100644 index 8bd1f9a3..00000000 --- a/nowledge-mem-gemini-cli-extension/skills/read-working-memory/SKILL.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -name: read-working-memory -description: Read the user's daily Working Memory briefing at session start or when recent priorities matter. This gives Gemini CLI cross-tool continuity without bloating the main prompt. ---- - -# Read Working Memory - -Use `nmem --json wm read` for the user's current priorities, unresolved flags, and recent context. - -## When to Use - -- At session start -- When resuming work after a break -- When the user asks what they are focused on now -- When the current task clearly depends on recent priorities or active initiatives - -## Usage Pattern - -- Read once near the start of a session. -- Reuse that context mentally instead of re-reading on every turn. -- Refresh only if the user asks, the session context changed materially, or a long-running session clearly needs it. diff --git a/nowledge-mem-gemini-cli-extension/skills/save-handoff/SKILL.md b/nowledge-mem-gemini-cli-extension/skills/save-handoff/SKILL.md deleted file mode 100644 index b496b9e3..00000000 --- a/nowledge-mem-gemini-cli-extension/skills/save-handoff/SKILL.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -name: save-handoff -description: Save a concise Gemini CLI handoff summary only when the user explicitly asks. This is intentionally separate from full thread-save, which should use the native Gemini session importer. ---- - -# Save Handoff - -Only use this skill when the user explicitly asks to save progress as a handoff, leave a resumable summary, or create a lightweight restart point. - -## Why This Is A Handoff - -`save-thread` should mean saving the real session messages through the native Gemini importer. - -For Gemini, this skill intentionally creates a structured handoff summary thread instead of importing the full session. - -## Workflow - -1. Write a short but useful handoff summary. -2. Include Goal, Decisions, Files, Risks, and Next. -3. Create a thread with `nmem t create` and `-s gemini-cli`. -4. If the user wants the full session instead, use `save-thread`. - -Example: - -```bash -nmem --json t create -t "Gemini CLI Session - auth refactor" -c "Goal: finish the auth refactor. Decisions: keep refresh verification in the API layer and treat gateway clock skew as the root cause. Files: api/auth.ts, auth.test.ts. Risks: expiry behavior may still differ in remote sessions. Next: validate remote session expiry end to end." -s gemini-cli -``` - -Never present this as a lossless thread save. Never auto-save without an explicit user request. diff --git a/nowledge-mem-gemini-cli-extension/skills/save-thread/SKILL.md b/nowledge-mem-gemini-cli-extension/skills/save-thread/SKILL.md deleted file mode 100644 index acca6b10..00000000 --- a/nowledge-mem-gemini-cli-extension/skills/save-thread/SKILL.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -name: save-thread -description: Save the real Gemini CLI session to Nowledge Mem only when the user explicitly asks. This uses Gemini's native transcript-backed importer rather than a summary-only fallback. ---- - -# Save Thread - -Only use this skill when the user explicitly asks to save the session, persist the thread, or store the actual Gemini conversation. - -## Contract - -`save-thread` means saving the real Gemini session messages. - -Use `nmem t save --from gemini-cli` for that path. A short summary may be attached as metadata, but the stored thread should come from Gemini's recorded transcript. - -Use `save-handoff` instead only when the user wants a lightweight resumable summary rather than the full session. - -## Workflow - -1. Write a concise 1-2 sentence summary. -2. Run `nmem --json t save --from gemini-cli -p . -s "..."`. -3. If the user names a different Gemini session, add `--session-id`. -4. Report whether the thread was created or appended and how many messages were stored. - -Example: - -```bash -nmem --json t save --from gemini-cli -p . -s "Finished the auth refactor and verified the new refresh-token flow." -``` - -Never claim a checkpoint summary is a thread save. Never auto-save without an explicit user request. diff --git a/nowledge-mem-gemini-cli-extension/skills/search-memory/SKILL.md b/nowledge-mem-gemini-cli-extension/skills/search-memory/SKILL.md deleted file mode 100644 index 50ed9784..00000000 --- a/nowledge-mem-gemini-cli-extension/skills/search-memory/SKILL.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -name: search-memory -description: Search the user's personal knowledge base when past insights would improve the response. Trigger proactively for continuity, recurring bugs, design rationale, and remembered workflows. ---- - -# Search Memory - -Use Nowledge Mem proactively when prior knowledge would materially improve the answer. - -## Strong Triggers - -Search when: - -- the user references previous work, a prior fix, or an earlier decision -- the task resumes a named feature, bug, refactor, incident, or subsystem -- a debugging pattern resembles something solved earlier -- the user asks for rationale, preferences, procedures, or recurring workflow details -- the current result is ambiguous and past context would make the answer sharper - -## Retrieval Routing - -1. Start with `nmem --json m search` for durable knowledge. -2. Use `--mode deep` when the first pass is weak or the recall need is conceptual. -3. Use `nmem --json t search` for prior discussions, previous sessions, or exact conversation history. -4. If a memory result includes a `source_thread` or thread search returns a strong hit, inspect the conversation progressively with `nmem --json t show`. -5. Prefer the smallest retrieval surface that answers the question. - -Mention source threads when they add useful historical context.