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
2 changes: 1 addition & 1 deletion latest.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"version": "0.0.12",
"version": "0.0.13",
"updateCommand": "/plugin marketplace update supermemory-plugins\n/plugin install supermemory@supermemory-plugins\n\nOnly if you still have the old \"claude-supermemory\" plugin, also remove it:\n/plugin uninstall claude-supermemory@supermemory-plugins"
}
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "claude-supermemory-dev",
"version": "0.0.12",
"version": "0.0.13",
"description": "Claude code plugin by Supermemory AI",
"private": true,
"type": "commonjs",
Expand Down
2 changes: 1 addition & 1 deletion plugin/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "supermemory",
"displayName": "Supermemory",
"version": "0.0.12",
"version": "0.0.13",
"description": "Persistent memory across Claude Code sessions using Supermemory",
"author": {
"name": "Supermemory",
Expand Down
4 changes: 2 additions & 2 deletions plugin/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion plugin/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "claude-supermemory",
"version": "0.0.12",
"version": "0.0.13",
"description": "Persistent memory for Claude Code using Supermemory",
"private": true,
"engines": {
Expand Down
16 changes: 9 additions & 7 deletions plugin/scripts/add-memory.cjs

Large diffs are not rendered by default.

56 changes: 29 additions & 27 deletions plugin/scripts/context-hook.cjs

Large diffs are not rendered by default.

16 changes: 9 additions & 7 deletions plugin/scripts/save-project-memory.cjs

Large diffs are not rendered by default.

44 changes: 23 additions & 21 deletions plugin/scripts/search-memory.cjs

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions plugin/scripts/status.cjs

Large diffs are not rendered by default.

30 changes: 16 additions & 14 deletions plugin/scripts/summary-hook.cjs

Large diffs are not rendered by default.

74 changes: 74 additions & 0 deletions src/lib/container-tag.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,73 @@ function loadLegacyCodexConfig() {
}
}

function loadLegacyCursorConfig(cwd) {
const globalConfigPath = path.join(
os.homedir(),
'.config',
'cursor',
'supermemory.json',
);
let globalConfig = null;
try {
if (fs.existsSync(globalConfigPath)) {
globalConfig = JSON.parse(fs.readFileSync(globalConfigPath, 'utf-8'));
}
} catch {}

let projectConfig = null;
let directory = path.resolve(cwd);
while (true) {
const configPath = path.join(
directory,
'.cursor',
'.supermemory',
'config.json',
);
try {
if (fs.existsSync(configPath)) {
projectConfig = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
break;
}
} catch {}
const parent = path.dirname(directory);
if (parent === directory) break;
directory = parent;
}

return { ...(globalConfig || {}), ...(projectConfig || {}) };
}

function getLegacyCursorUserTags(cwd) {
const config = loadLegacyCursorConfig(cwd);
let gitEmail = null;
try {
gitEmail = execSync('git config user.email', {
cwd: getProjectBasePath(cwd),
encoding: 'utf-8',
stdio: ['pipe', 'pipe', 'pipe'],
}).trim();
} catch {}
const machineId = `${os.hostname()}_${os.userInfo().username}`;
return uniqueTags([
config.userContainerTag ||
process.env.SUPERMEMORY_USER_TAG ||
process.env.CURSOR_USER_EMAIL ||
gitEmail ||
machineId,
]).map((identity) => `cursor_user_${sha256(identity)}`);
}

function getLegacyCursorProjectTags(cwd) {
const config = loadLegacyCursorConfig(cwd);
const basePath = getProjectBasePath(cwd);
return uniqueTags([
config.projectContainerTag ||
process.env.SUPERMEMORY_PROJECT_TAG ||
basePath,
]).map((identity) => `cursor_project_${sha256(identity)}`);
}

function stripJsoncComments(content) {
let result = '';
let index = 0;
Expand Down Expand Up @@ -317,7 +384,10 @@ function getRepoContainerTag(cwd) {
const projectConfig = loadProjectConfig(cwd);
return (
projectConfig?.repoContainerTag ||
process.env.SUPERMEMORY_REPO_TAG ||
loadLegacyCursorConfig(cwd)?.repoContainerTag ||
loadLegacyCodexConfig()?.projectContainerTag ||
loadLegacyOpenCodeConfig()?.projectContainerTag ||
getGeneratedRepoContainerTag(cwd)
);
}
Expand Down Expand Up @@ -346,6 +416,7 @@ function getPersonalReadTags(cwd) {
getLegacyContainerTag(cwd),
...getLegacyCodexUserTags(cwd),
...getLegacyOpenCodeUserTags(cwd),
...getLegacyCursorUserTags(cwd),
]);
}

Expand All @@ -356,6 +427,7 @@ function getProjectReadTags(cwd) {
getLegacyGeneratedRepoContainerTag(cwd),
...getLegacyCodexProjectTags(cwd),
...getLegacyOpenCodeProjectTags(cwd),
...getLegacyCursorProjectTags(cwd),
]);
}

Expand All @@ -376,6 +448,8 @@ module.exports = {
getLegacyCodexProjectTag,
getLegacyOpenCodeUserTags,
getLegacyOpenCodeProjectTags,
getLegacyCursorUserTags,
getLegacyCursorProjectTags,
getRepoContainerTag,
getGeneratedRepoContainerTag,
getLegacyGeneratedRepoContainerTag,
Expand Down
2 changes: 1 addition & 1 deletion src/lib/plugin-version.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
const PLUGIN_VERSION = '0.0.12';
const PLUGIN_VERSION = '0.0.13';

module.exports = { PLUGIN_VERSION };
2 changes: 1 addition & 1 deletion src/lib/supermemory-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function supportsScopedCanonicalTag(containerTag) {
const AGENT_ENTITY_CONTEXT = `Shared coding-agent memory for one software repository.

RULES:
- Preserve durable context that helps Claude Code, Codex, or OpenCode continue the work
- Preserve durable context that helps Claude Code, Codex, OpenCode, or Cursor continue the work
- Condense assistant responses into decisions, outcomes, and reusable knowledge
- Keep user preferences and project facts concise and independently understandable

Expand Down
8 changes: 6 additions & 2 deletions test/unit.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function readTags(cwd, home) {
}

describe('unified container tags', () => {
test('writes one stable canonical tag and reads Claude, Codex, and OpenCode legacy tags', (t) => {
test('writes one stable canonical tag and reads all agent legacy tags', (t) => {
const { repo, git, home } = makeRepo(t);
const tags = readTags(repo, home);
const pathHash = hash16(git(['rev-parse', '--show-toplevel']));
Expand All @@ -80,12 +80,16 @@ describe('unified container tags', () => {
`claudecode_project_${pathHash}`,
`codex_user_${userHash}`,
`opencode_user_${userHash}`,
`cursor_user_${userHash}`,
]);
assert.deepEqual(tags.projectReads, [
canonicalTag,
'repo_example_project',
`codex_project_${pathHash}`,
`opencode_project_${pathHash}`,
...[...new Set([hash16(repo), pathHash])].map(
(hash) => `opencode_project_${hash}`,
),
`cursor_project_${pathHash}`,
]);
});

Expand Down
Loading