Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
name: Build Package

# Main PowerMem release (Python packages). Does not run on plugin-only tags (plugins-v*).
on:
push:
branches: [main, develop]
Expand Down Expand Up @@ -139,7 +140,8 @@ jobs:

build-and-release:
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')
# Only release on version tags v*; do not run for plugin-only tags (plugins-v*)
if: startsWith(github.ref, 'refs/tags/v') && !startsWith(github.ref, 'refs/tags/plugins-')
needs: combine-artifacts
permissions:
contents: write
Expand Down
140 changes: 140 additions & 0 deletions .github/workflows/plugins-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
name: Plugins Build and Release

on:
push:
branches: [main, develop]
paths:
- 'apps/**'
- '.github/workflows/plugins-build.yml'
tags:
- 'plugins-v*'
pull_request:
branches: [main, develop]
paths:
- 'apps/**'
- '.github/workflows/plugins-build.yml'
workflow_dispatch:
inputs:
create_release:
description: 'Create a GitHub Release with plugin assets (only if not tag)'
required: false
default: false
type: boolean

env:
NODE_VERSION: '20'
GO_VERSION: '1.22.x'

jobs:
build-vscode-extension:
name: Build VS Code Extension
runs-on: ubuntu-latest
defaults:
run:
working-directory: apps/vscode-extension

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
cache-dependency-path: apps/vscode-extension/package-lock.json

- name: Install dependencies
run: npm ci

- name: Compile
run: npm run compile

- name: Install vsce
run: npm install -g @vscode/vsce

- name: Package .vsix
run: vsce package --no-dependencies
id: vsce

- name: Upload VS Code extension (.vsix)
uses: actions/upload-artifact@v4
with:
name: powermem-vscode-vsix
path: apps/vscode-extension/*.vsix
retention-days: 30

package-claude-plugin:
name: Package Claude Code Plugin
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}

- name: Package Claude Code plugin (cross-compile hooks + zip)
run: bash apps/claude-code-plugin/scripts/package-plugin.sh

- name: Upload Claude Code plugin (zip)
uses: actions/upload-artifact@v4
with:
name: powermem-claude-code-plugin-zip
path: apps/claude-code-plugin/dist/powermem-claude-code-plugin-*.zip
if-no-files-found: error
retention-days: 30
release-plugins:
name: Release Plugin Assets
runs-on: ubuntu-latest
needs: [build-vscode-extension, package-claude-plugin]
if: startsWith(github.ref, 'refs/tags/plugins-') || (github.event_name == 'workflow_dispatch' && github.event.inputs.create_release == 'true')
permissions:
contents: write

steps:
- name: Download VS Code extension
uses: actions/download-artifact@v4
with:
name: powermem-vscode-vsix
path: vsix

- name: Download Claude Code plugin
uses: actions/download-artifact@v4
with:
name: powermem-claude-code-plugin-zip
path: zip

- name: Get version from tag or default
id: ver
run: |
if [[ "${{ github.ref }}" == refs/tags/plugins-* ]]; then
echo "version=${GITHUB_REF#refs/tags/plugins-}" >> $GITHUB_OUTPUT
else
echo "version=dev-$(date +%Y%m%d-%H%M)" >> $GITHUB_OUTPUT
fi

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.ref_type == 'tag' && github.ref_name || format('plugins-{0}', steps.ver.outputs.version) }}
name: Plugins ${{ steps.ver.outputs.version }}
body: |
## PowerMem IDE Plugins

- **PowerMem for VS Code** (`.vsix`): Download and install from VSIX in VS Code or Cursor.
- **PowerMem for Claude Code** (`.zip`): Download, unzip, and start Claude with `claude --plugin-dir /path/to/powermem-claude-code-plugin`.

See [apps/README.md](https://github.com/${{ github.repository }}/blob/main/apps/README.md).
files: |
vsix/*.vsix
zip/powermem-claude-code-plugin-*.zip
draft: false
prerelease: ${{ contains(github.ref, 'refs/tags/') == false }}
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

64 changes: 64 additions & 0 deletions .github/workflows/plugins-publish-vscode.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Publish VS Code extension to Visual Studio Marketplace / Open VSX (manual trigger only).
# Configure in repo Settings -> Secrets and variables -> Actions:
# - VSCE_PAT: Personal Access Token for Visual Studio Marketplace
# (https://dev.azure.com -> User settings -> Personal access tokens; scope must include Marketplace)
# - OVSX_PAT: Token for Open VSX (optional; create at https://open-vsx.org after sign-in)

name: Publish VS Code Extension

on:
workflow_dispatch:
inputs:
publish_vsce:
description: 'Publish to Visual Studio Marketplace'
required: false
default: true
type: boolean
publish_ovsx:
description: 'Publish to Open VSX'
required: false
default: false
type: boolean

jobs:
publish:
name: Publish to Marketplace(s)
runs-on: ubuntu-latest
permissions:
contents: read

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: apps/vscode-extension/package-lock.json

- name: Build .vsix
run: |
cd apps/vscode-extension
npm ci
npm run compile
npx @vscode/vsce package --no-dependencies
mkdir -p ../.vsix
cp *.vsix ../.vsix/

- name: Publish to Visual Studio Marketplace
if: github.event.inputs.publish_vsce == 'true'
env:
VSCE_TOKEN: ${{ secrets.VSCE_PAT }}
run: |
cd apps/vscode-extension
npx @vscode/vsce publish --pat $VSCE_TOKEN -i ../.vsix/*.vsix

- name: Publish to Open VSX
if: github.event.inputs.publish_ovsx == 'true'
env:
OVSX_TOKEN: ${{ secrets.OVSX_PAT }}
run: |
cd apps/vscode-extension
npx @vscode/vsce publish --pat $OVSX_TOKEN -i ../.vsix/*.vsix --registryUrl https://open-vsx.org
2 changes: 2 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ permissions:

jobs:
release-build:
if: startsWith(github.event.release.tag_name, 'v') && !startsWith(github.event.release.tag_name, 'plugins-')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -57,6 +58,7 @@ jobs:
path: dist/

pypi-publish:
if: startsWith(github.event.release.tag_name, 'v') && !startsWith(github.event.release.tag_name, 'plugins-')
runs-on: ubuntu-latest
needs:
- release-build
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,8 @@ api_data/
server_backup/
*.backup

# apps/vscode-extension (Node / VS Code)
apps/vscode-extension/node_modules/
apps/vscode-extension/out/
apps/vscode-extension/*.vsix

20 changes: 15 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: help install install-dev test test-unit test-integration test-e2e test-coverage test-fast test-slow lint format clean build build-package build-check build-dashboard publish-pypi publish-testpypi install-build-tools upload docs bump-version server-start server-stop server-restart server-status server-logs server-dashboard-start docker-build docker-run docker-up docker-down docker-logs docker-stop docker-restart docker-clean docker-ps
.PHONY: help install install-dev test test-unit test-integration test-e2e test-coverage test-fast test-slow lint format clean build build-package build-check build-dashboard build-claude-hook package-claude-plugin publish-pypi publish-testpypi install-build-tools upload docs bump-version server-start server-stop server-restart server-status server-logs server-dashboard-start docker-build docker-run docker-up docker-down docker-logs docker-stop docker-restart docker-clean docker-ps

help: ## Show help information
@echo "powermem Project Build Tools"
Expand Down Expand Up @@ -122,6 +122,12 @@ build-dashboard: ## Build dashboard frontend and inject into src/server/dashboar
@cp -r dashboard/dist/* src/server/dashboard/
@echo "✓ Dashboard built. Start server with: make server-start-reload (then open http://localhost:$(SERVER_PORT)/dashboard/)"

build-claude-hook: ## Build Claude Code hook binaries (Go; output: apps/claude-code-plugin/hooks/bin/)
@bash apps/claude-code-plugin/scripts/build-hook-binaries.sh

package-claude-plugin: ## Zip Claude Code plugin for sharing (apps/claude-code-plugin/dist/*.zip)
@bash apps/claude-code-plugin/scripts/package-plugin.sh

install-build-tools: ## Install build and upload tools
@echo "Installing build tools..."
pip install --upgrade build twine
Expand Down Expand Up @@ -170,20 +176,24 @@ setup-env: ## Setup development environment
python scripts/setup.py

# Version management
# macOS BSD sed: -i requires a backup extension; use '' for in-place without backup.
# GNU sed accepts plain -i; '' is also valid. \+ in patterns is GNU-specific; use -E and + for portability.
SED_INPLACE := $(if $(filter Darwin,$(shell uname -s)),sed -i '',sed -i)

bump-version: ## Bump version number (usage: make bump-version VERSION=0.2.0)
@if [ -z "$(VERSION)" ]; then \
echo "Error: VERSION is required. Usage: make bump-version VERSION=0.2.0"; \
exit 1; \
fi
@echo "Bumping version to $(VERSION)..."
@# Update pyproject.toml
@sed -i 's/^version = ".*"/version = "$(VERSION)"/' pyproject.toml
@$(SED_INPLACE) 's/^version = ".*"/version = "$(VERSION)"/' pyproject.toml
@# Update src/powermem/version.py
@sed -i 's/^__version__ = ".*"/__version__ = "$(VERSION)"/' src/powermem/version.py
@$(SED_INPLACE) 's/^__version__ = ".*"/__version__ = "$(VERSION)"/' src/powermem/version.py
@# Update src/powermem/core/telemetry.py (all occurrences; match any x.y.z)
@sed -i 's/"version": "[0-9]\+\.[0-9]\+\.[0-9]\+"/"version": "$(VERSION)"/g' src/powermem/core/telemetry.py
@$(SED_INPLACE) -E 's/"version": "[0-9]+\.[0-9]+\.[0-9]+"/"version": "$(VERSION)"/g' src/powermem/core/telemetry.py
@# Update src/powermem/core/audit.py (match any x.y.z)
@sed -i 's/"version": "[0-9]\+\.[0-9]\+\.[0-9]\+"/"version": "$(VERSION)"/g' src/powermem/core/audit.py
@$(SED_INPLACE) -E 's/"version": "[0-9]+\.[0-9]+\.[0-9]+"/"version": "$(VERSION)"/g' src/powermem/core/audit.py
@echo "✓ Version updated to $(VERSION) in all files (excluding examples/)"
@echo ""
@echo "Updated files:"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<p align="center">

*PowerMem integrated with [OpenClaw](https://github.com/openclaw-ai/openclaw): intelligent memory for AI agents. **OpenClaw PowerMem Plugin**: [View Plugin](https://github.com/ob-labs/memory-powermem)*
*PowerMem integrated with [OpenClaw](https://github.com/openclaw/openclaw): intelligent memory for AI agents. **OpenClaw PowerMem Plugin**: [View Plugin](https://github.com/ob-labs/memory-powermem)*

One command to add PowerMem memory to OpenClaw: `openclaw plugins install memory-powermem`.

Expand Down
2 changes: 1 addition & 1 deletion README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<p align="center">

*PowerMem 与 [OpenClaw](https://github.com/openclaw-ai/openclaw) 集成:为 AI 智能体提供智能记忆。**OpenClaw PowerMem 记忆插件**:[查看插件](https://github.com/ob-labs/memory-powermem)*
*PowerMem 与 [OpenClaw](https://github.com/openclaw/openclaw) 集成:为 AI 智能体提供智能记忆。**OpenClaw PowerMem 记忆插件**:[查看插件](https://github.com/ob-labs/memory-powermem)*

一行命令即可为 OpenClaw 接入 PowerMem 记忆:`openclaw plugins install memory-powermem`。

Expand Down
2 changes: 1 addition & 1 deletion README_JP.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<p align="center">

*PowerMem と [OpenClaw](https://github.com/openclaw-ai/openclaw) の連携:AI エージェント向けインテリジェントメモリ。**OpenClaw PowerMem メモリプラグイン**:[プラグインを見る](https://github.com/ob-labs/memory-powermem)*
*PowerMem と [OpenClaw](https://github.com/openclaw/openclaw) の連携:AI エージェント向けインテリジェントメモリ。**OpenClaw PowerMem メモリプラグイン**:[プラグインを見る](https://github.com/ob-labs/memory-powermem)*

1 コマンドで OpenClaw に PowerMem メモリを追加:`openclaw plugins install memory-powermem`。

Expand Down
16 changes: 16 additions & 0 deletions apps/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# PowerMem IDE Apps

## Contents

| Directory | Description |
|-----------|--------------|
| **vscode-extension** | VS Code extension that links PowerMem to Cursor, Claude Code, Codex, Windsurf, and Copilot. Provides commands: Query memories, Add selection, Quick note, Link to AI tools, Setup, Dashboard. |
| **claude-code-plugin** | Claude Code plugin: **HTTP mode by default** (REST hooks; empty `mcpServers`). Optional **MCP mode** via `config/mcp-mode.mcp.json`. See `claude-code-plugin/README.md`. |

## Quick start

1. **Backend**: Start PowerMem (e.g. `powermem-server --port 8000` or `uvx powermem-mcp sse`).
2. **VS Code / Cursor**: Install the extension from `vscode-extension/` (Run and Debug or package as `.vsix`), set backend URL in PowerMem settings, then use **PowerMem: Link to AI tools**.
3. **Claude Code only**: `claude --plugin-dir /path/to/powermem/apps/claude-code-plugin`. **HTTP mode is default**; run `scripts/apply-connection-mode.sh mcp` for in-chat tools (see plugin README).

See each subdirectory’s `README.md` for details.
8 changes: 8 additions & 0 deletions apps/claude-code-plugin/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "memory-powermem",
"description": "PowerMem intelligent memory for Claude Code: add, search, update, and delete memories with Ebbinghaus decay and multi-agent support.",
"version": "0.1.0",
"author": { "name": "OceanBase / PowerMem" },
"homepage": "https://github.com/oceanbase/powermem",
"repository": "https://github.com/oceanbase/powermem"
}
4 changes: 4 additions & 0 deletions apps/claude-code-plugin/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
dist/
*.zip
# Built by scripts/build-hook-binaries.sh (included in release zip; omit from git to keep repo small)
hooks/bin/
3 changes: 3 additions & 0 deletions apps/claude-code-plugin/.mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"mcpServers": {}
}
30 changes: 30 additions & 0 deletions apps/claude-code-plugin/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Changelog

## Unreleased

- **UserPromptSubmit:** `POWERMEM_PROMPT_SEARCH` defaults to **on** (`POST /api/v1/memories/search` + `additionalContext` per prompt). Set `0`, `false`, `no`, or `off` to disable.

## 0.1.0

Initial release of the PowerMem plugin for Claude Code.

**Connection modes**

- **HTTP mode (default):** Root `.mcp.json` ships with empty `mcpServers`; no PowerMem MCP tools in chat. Hooks always call the PowerMem REST API (`POWERMEM_BASE_URL`, default `http://localhost:8000`).
- **MCP mode (optional):** `scripts/apply-connection-mode.sh mcp` copies `config/mcp-mode.mcp.json` to `.mcp.json` so Claude can use PowerMem MCP (`search_memories`, `add_memory`, etc.) over HTTP `/mcp` or stdio.

**Skills**

- `/memory-powermem:remember` and `/memory-powermem:recall` — backed by MCP tools when MCP mode is enabled; in default HTTP mode they have no tools to invoke.

**Hooks (native `powermem-hook` + `run-hook.sh` / `run-hook.ps1`)**

- **SessionEnd:** Upload full session transcript to `POST /api/v1/memories` (detached worker so large uploads do not block exit).
- **PostCompact:** Upload compact summary to `POST /api/v1/memories`.
- **UserPromptSubmit (optional):** When `POWERMEM_PROMPT_SEARCH=1`, `POST /api/v1/memories/search` and inject hits via `additionalContext` (works in HTTP and MCP modes; off by default in this release).

**Other**

- Optional workspace file poller: `sh hooks/run-hook.sh poll` (see `watcher/README.md`).
- Windows: `hooks/hooks.windows.example.json` + PowerShell `run-hook.ps1` when `sh` is unavailable.
- Packaging: `scripts/package-plugin.sh` / `make package-claude-plugin`; hook binaries via `scripts/build-hook-binaries.sh` (Go 1.22+).
Loading
Loading