diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 5bd07057..a5c8dc61 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,17 +1,24 @@ { "name": "claude-mem", - "version": "10.4.1", - "description": "Persistent memory system for Claude Code - seamlessly preserve context across sessions", + "version": "10.6.3", + "description": "Memory compression system for Claude Code - persist context across sessions", "author": { "name": "Alex Newman" }, "repository": "https://github.com/thedotmack/claude-mem", "license": "AGPL-3.0", "keywords": [ + "claude", + "claude-code", + "claude-agent-sdk", + "mcp", + "plugin", "memory", - "context", - "persistence", - "hooks", - "mcp" - ] + "compression", + "knowledge-graph", + "transcript", + "typescript", + "nodejs" + ], + "homepage": "https://github.com/thedotmack/claude-mem#readme" } diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json new file mode 100644 index 00000000..45de195f --- /dev/null +++ b/.codex-plugin/plugin.json @@ -0,0 +1,43 @@ +{ + "name": "claude-mem", + "version": "10.6.3", + "description": "Memory compression system for Claude Code - persist context across sessions", + "author": { + "name": "Alex Newman", + "url": "https://github.com/thedotmack" + }, + "homepage": "https://github.com/thedotmack/claude-mem#readme", + "repository": "https://github.com/thedotmack/claude-mem", + "license": "AGPL-3.0", + "keywords": [ + "claude", + "claude-code", + "claude-agent-sdk", + "mcp", + "plugin", + "memory", + "compression", + "knowledge-graph", + "transcript", + "typescript", + "nodejs" + ], + "interface": { + "displayName": "claude-mem", + "shortDescription": "Persistent memory and context compression across coding sessions.", + "longDescription": "claude-mem captures coding-session activity, compresses it into reusable observations, and injects relevant context back into future Claude Code and Codex-compatible sessions.", + "developerName": "Alex Newman", + "category": "Productivity", + "capabilities": [ + "Interactive", + "Write" + ], + "websiteURL": "https://github.com/thedotmack/claude-mem", + "defaultPrompt": [ + "Find what I already learned about this codebase before I start a new task.", + "Show recent observations related to the files I am editing right now.", + "Summarize the last session and inject the most relevant context into this one." + ], + "brandColor": "#1F6FEB" + } +} diff --git a/package.json b/package.json index 8970f40a..125d3224 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ }, "scripts": { "dev": "npm run build-and-sync", - "build": "node scripts/build-hooks.js", + "build": "node scripts/sync-plugin-manifests.js && node scripts/build-hooks.js", "build-and-sync": "npm run build && npm run sync-marketplace && sleep 1 && cd ~/.claude/plugins/marketplaces/thedotmack && npm run worker:restart", "sync-marketplace": "node scripts/sync-marketplace.cjs", "sync-marketplace:force": "node scripts/sync-marketplace.cjs --force", diff --git a/scripts/sync-plugin-manifests.js b/scripts/sync-plugin-manifests.js new file mode 100644 index 00000000..3a364978 --- /dev/null +++ b/scripts/sync-plugin-manifests.js @@ -0,0 +1,95 @@ +#!/usr/bin/env node + +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const rootDir = path.resolve(__dirname, '..'); + +const packageJsonPath = path.join(rootDir, 'package.json'); +const codexPluginPath = path.join(rootDir, '.codex-plugin', 'plugin.json'); +const claudePluginPath = path.join(rootDir, '.claude-plugin', 'plugin.json'); + +function readJson(filePath) { + return JSON.parse(fs.readFileSync(filePath, 'utf8')); +} + +function writeJson(filePath, value) { + fs.writeFileSync(filePath, JSON.stringify(value, null, 2) + '\n'); +} + +function syncCodexPlugin(plugin, pkg) { + const author = + typeof plugin.author === 'object' && plugin.author ? plugin.author : {}; + + return { + ...plugin, + name: pkg.name, + version: pkg.version, + description: pkg.description, + homepage: pkg.homepage, + repository: normalizeRepositoryUrl(pkg.repository), + license: pkg.license, + keywords: pkg.keywords, + author: { + ...author, + name: normalizeAuthorName(pkg.author), + }, + interface: { + ...plugin.interface, + developerName: normalizeAuthorName(pkg.author), + websiteURL: normalizeRepositoryUrl(pkg.repository), + }, + }; +} + +function syncClaudePlugin(plugin, pkg) { + return { + ...plugin, + name: pkg.name, + version: pkg.version, + description: pkg.description, + homepage: pkg.homepage, + repository: normalizeRepositoryUrl(pkg.repository), + license: pkg.license, + keywords: pkg.keywords, + author: { + ...(typeof plugin.author === 'object' && plugin.author ? plugin.author : {}), + name: normalizeAuthorName(pkg.author), + }, + }; +} + +function normalizeAuthorName(author) { + if (typeof author === 'string') return author; + if (author && typeof author === 'object' && typeof author.name === 'string') return author.name; + return ''; +} + +function normalizeRepositoryUrl(repository) { + if (typeof repository === 'string') return repository.replace(/\.git$/, ''); + if (repository && typeof repository === 'object' && typeof repository.url === 'string') + return repository.url.replace(/\.git$/, ''); + return ''; +} + +function main() { + for (const filePath of [packageJsonPath, codexPluginPath, claudePluginPath]) { + if (!fs.existsSync(filePath)) { + console.error(`Missing required file: ${filePath}`); + process.exit(1); + } + } + + const pkg = readJson(packageJsonPath); + const codexPlugin = readJson(codexPluginPath); + const claudePlugin = readJson(claudePluginPath); + + writeJson(codexPluginPath, syncCodexPlugin(codexPlugin, pkg)); + writeJson(claudePluginPath, syncClaudePlugin(claudePlugin, pkg)); + + console.log('✓ Synced plugin manifests from package.json'); +} + +main();