Skip to content

feat: add cross-project user preference memory MCP - #319

Open
jellydn wants to merge 4 commits into
mainfrom
feat/user-preference-memory
Open

feat: add cross-project user preference memory MCP#319
jellydn wants to merge 4 commits into
mainfrom
feat/user-preference-memory

Conversation

@jellydn

@jellydn jellydn commented Jul 18, 2026

Copy link
Copy Markdown
Owner

What

Add @jellydn/user-memory-mcp, a structured MCP server for durable user preferences shared across projects and coding agents.

The repository now has four distinct memory lanes:

Memory lane Scope Mechanism
Session discoveries Current session and project agentmemory
Project knowledge Durable, project-specific qmd
Task continuation Resume unfinished work /handoffs and /pickup
User preferences Durable, cross-project user-memory

The new server exposes five tools:

  • memory_preference_set
  • memory_preference_get
  • memory_preference_list
  • memory_preference_delete
  • memory_preference_reset

Preferences are stored under ~/.ai-tools/user-memory/ in structured JSON with a value-free audit log. The server is registered alongside agentmemory across all supported MCP client configurations.

Why

The repository already supports session memory, durable project knowledge, and task handoffs. Building another generic memory service would duplicate those capabilities.

The missing lane is user-level preferences that should follow someone between projects and tools, such as:

  • Prefer TypeScript examples.
  • Use pnpm instead of npm.
  • Keep explanations concise.
  • Prefer Vitest for unit tests.
  • Never commit generated files.

Project-scoped qmd collections are not the right place for these preferences, while agentmemory is intentionally limited to short-lived session discoveries. A separate preference store gives users deterministic lookup, exact inspection, deletion/reset controls, and a clear rule that agents must not infer preferences.

How

  • Add an npm workspace at packages/user-memory-mcp using the stable MCP TypeScript SDK v1.
  • Store versioned key/value preferences with source: "explicit" and creation/update timestamps.
  • Require caller attestation with confirmed: true; MCP schema validation rejects unconfirmed writes.
  • Perform best-effort rejection of common secret-like keys and values. This is a guardrail, not an encryption or comprehensive secret-scanning boundary.
  • Write preference state atomically with user-only permissions.
  • Serialize concurrent processes with an ownership-aware inter-process lock.
  • Write best-effort audit records containing operations and keys, never preference values.
  • Register user-memory in the central registry and every existing agent configuration that includes agentmemory.
  • Update MEMORY.md, README guidance, npm workspace metadata, Docker's dependency layer, and release changesets.

Validation

  • Full BATS suite: 412 tests passed (one existing optional jsonschema skip)
  • User-memory package: 10 tests passed
  • Store/update/list/delete/reset acceptance flows
  • Separate MCP sessions retrieve the same durable preference
  • Unconfirmed writes rejected at the MCP boundary
  • Common secret-like inputs rejected
  • 20 concurrent writers preserve every preference
  • Package build and root TypeScript check
  • Packed tarball installs and runs over real stdio
  • Docker manifest-layer npm ci simulation
  • Installer dry-run, Biome checks, and git diff --check

Release requirement

The checked-in configurations invoke npx -y @jellydn/user-memory-mcp@latest. Publish the package before marking this PR ready to merge so external clients can start the configured server.

Summary by CodeRabbit

  • New Features
    • Added a new user-memory MCP server for durable cross-project user preferences with set/get/list/delete/reset tools.
    • Enforced explicit confirmation for preference writes and included protections against secret-like keys/values.
    • Enabled the user-memory server across supported MCP integrations and config presets.
  • Documentation
    • Updated README and MEMORY.md with the new user-memory lane, decision guidance, and tool descriptions.
  • Tests
    • Added automated test coverage for persistence, validation, auditing, concurrency, and MCP registration/config consistency.
  • Chores
    • Improved monorepo build/test scripts and ensured workspace manifests are available during Docker builds.

Co-authored-by: Dung Huynh Duc <dunghd.it@gmail.com>
@changeset-bot

changeset-bot Bot commented Jul 18, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: def18fa

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Adds the @jellydn/user-memory-mcp package with durable preference storage, five MCP tools, filesystem locking and auditing, broad client registration, tests, documentation, and workspace integration.

Changes

User memory MCP server

Layer / File(s) Summary
Preference storage and package contract
packages/user-memory-mcp/package.json, packages/user-memory-mcp/tsconfig.json, packages/user-memory-mcp/src/schema.ts, packages/user-memory-mcp/src/store.ts
Defines validated preference schemas, atomic persistence, locking, auditing, timestamps, and secret-like input rejection.
MCP server and tool workflow
packages/user-memory-mcp/src/server.ts, packages/user-memory-mcp/src/tools.ts, packages/user-memory-mcp/tests/*
Exposes five preference tools over stdio, requires confirmation for writes and resets, and tests persistence, validation, concurrency, auditing, and discovery.
MCP client registration and validation
configs/*, cli.sh, lib/install.sh, tests/pr_user_memory_mcp.bats
Registers user-memory-mcp across supported client formats, adds installation handling, and validates configuration coverage.
Repository integration and documentation
package.json, Dockerfile, README.md, MEMORY.md, .changeset/*, packages/user-memory-mcp/README.md, .github/workflows/test.yml
Adds workspace/build wiring, release metadata, CI coverage, setup documentation, and four-lane memory guidance.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant MCPClient
  participant MCPServer
  participant PreferenceStore
  participant Filesystem
  MCPClient->>MCPServer: Call memory_preference_set
  MCPServer->>PreferenceStore: Validate confirmed preference
  PreferenceStore->>Filesystem: Lock and atomically persist preference
  Filesystem-->>PreferenceStore: Preference and audit result
  PreferenceStore-->>MCPServer: Return preference
  MCPServer-->>MCPClient: JSON MCP response
Loading

Possibly related PRs

Suggested reviewers: copilot

Poem

I’m a rabbit with preferences tucked safe in a file,
Confirmed with a carrot and stored with a smile.
Five tools hop through the MCP gate,
While locks keep memories orderly and straight.
Across projects, choices can stay.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding a cross-project user preference memory MCP server.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/user-preference-memory

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new MCP server, @jellydn/user-memory-mcp, designed to manage explicit, durable user preferences across projects and coding agents. The changes include adding the package, updating configuration files for various AI tools to integrate the server, and documenting its usage. The review feedback provides valuable robustness and performance improvements, such as handling potential resolution errors in the entry point, optimizing preference lookups with findIndex, cleaning up temporary files on write failures, and removing redundant chmod calls.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +21 to +26
if (process.argv[1] && fileURLToPath(import.meta.url) === realpathSync(process.argv[1])) {
main().catch((error: unknown) => {
console.error("user-memory MCP server failed:", error);
process.exitCode = 1;
});
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

If process.argv[1] is not a valid file path (which can happen in certain test runners, bundlers, or custom execution environments), realpathSync will throw an ENOENT error and crash the process immediately upon importing this module. Wrapping this check in a try-catch block makes the module safe to import in any environment.

Suggested change
if (process.argv[1] && fileURLToPath(import.meta.url) === realpathSync(process.argv[1])) {
main().catch((error: unknown) => {
console.error("user-memory MCP server failed:", error);
process.exitCode = 1;
});
}
try {
if (process.argv[1] && fileURLToPath(import.meta.url) === realpathSync(process.argv[1])) {
main().catch((error: unknown) => {
console.error("user-memory MCP server failed:", error);
process.exitCode = 1;
});
}
} catch {
// Ignore errors from realpathSync if process.argv[1] cannot be resolved
}

Comment thread packages/user-memory-mcp/src/store.ts Outdated
@@ -0,0 +1,198 @@
import { randomUUID } from "node:crypto";
import { appendFile, chmod, mkdir, readFile, rename, writeFile } from "node:fs/promises";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Import unlink from node:fs/promises to allow cleaning up temporary files on write failures.

Suggested change
import { appendFile, chmod, mkdir, readFile, rename, writeFile } from "node:fs/promises";
import { appendFile, chmod, mkdir, readFile, rename, unlink, writeFile } from "node:fs/promises";

Comment thread packages/user-memory-mcp/src/store.ts Outdated
Comment on lines +74 to +83
const existing = memory.preferences.find((preference) => preference.key === key);
const preference: UserPreference = existing
? { ...existing, value, updatedAt: timestamp }
: { key, value, source: "explicit", createdAt: timestamp, updatedAt: timestamp };

if (existing) {
memory.preferences[memory.preferences.indexOf(existing)] = preference;
} else {
memory.preferences.push(preference);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Optimize the array search by using findIndex instead of calling both find and indexOf, which performs two full scans of the array in the worst case.

Suggested change
const existing = memory.preferences.find((preference) => preference.key === key);
const preference: UserPreference = existing
? { ...existing, value, updatedAt: timestamp }
: { key, value, source: "explicit", createdAt: timestamp, updatedAt: timestamp };
if (existing) {
memory.preferences[memory.preferences.indexOf(existing)] = preference;
} else {
memory.preferences.push(preference);
}
const existingIndex = memory.preferences.findIndex((preference) => preference.key === key);
const existing = existingIndex !== -1 ? memory.preferences[existingIndex] : undefined;
const preference: UserPreference = existing
? { ...existing, value, updatedAt: timestamp }
: { key, value, source: "explicit", createdAt: timestamp, updatedAt: timestamp };
if (existingIndex !== -1) {
memory.preferences[existingIndex] = preference;
} else {
memory.preferences.push(preference);
}

Comment on lines +164 to +170
private async writeMemory(memory: UserMemory): Promise<void> {
await this.ensureDirectory();
const temporaryPath = `${this.memoryPath}.${process.pid}.${randomUUID()}.tmp`;
await writeFile(temporaryPath, `${JSON.stringify(memory, null, 2)}\n`, { encoding: "utf8", mode: 0o600 });
await rename(temporaryPath, this.memoryPath);
await chmod(this.memoryPath, 0o600);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Ensure that the temporary file is cleaned up if writeFile or rename fails, preventing orphaned .tmp files from cluttering the user's directory. Additionally, calling chmod after rename is redundant because rename preserves the permissions of the source file, which was already created with 0o600 mode.

	private async writeMemory(memory: UserMemory): Promise<void> {
		await this.ensureDirectory();
		const temporaryPath = `${this.memoryPath}.${process.pid}.${randomUUID()}.tmp`;
		try {
			await writeFile(temporaryPath, `${JSON.stringify(memory, null, 2)}\n`, { encoding: "utf8", mode: 0o600 });
			await rename(temporaryPath, this.memoryPath);
		} catch (error) {
			try {
				await unlink(temporaryPath);
			} catch {
				// Ignore cleanup errors to propagate the original error
			}
			throw error;
		}
	}

Comment on lines +172 to +180
private async appendAuditBestEffort(entry: AuditEntry): Promise<void> {
try {
await this.ensureDirectory();
await appendFile(this.auditPath, `${JSON.stringify(entry)}\n`, { encoding: "utf8", mode: 0o600 });
await chmod(this.auditPath, 0o600);
} catch (error) {
console.error("user-memory: preference was saved, but its audit entry could not be written", error);
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Calling chmod on every audit log append is redundant. The appendFile function's mode: 0o600 option already ensures that the file is created with the correct permissions if it does not exist. If the file already exists, its permissions are already set, making the extra chmod system call unnecessary and inefficient.

	private async appendAuditBestEffort(entry: AuditEntry): Promise<void> {
		try {
			await this.ensureDirectory();
			await appendFile(this.auditPath, `${JSON.stringify(entry)}\n`, { encoding: "utf8", mode: 0o600 });
		} catch (error) {
			console.error("user-memory: preference was saved, but its audit entry could not be written", error);
		}
	}

@jellydn
jellydn marked this pull request as ready for review July 18, 2026 13:16

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@MEMORY.md`:
- Line 131: Update the sentence in MEMORY.md so “that is two separate stores”
uses the grammatically correct plural phrasing “those are two separate stores,”
while preserving the surrounding guidance.

In `@packages/user-memory-mcp/src/store.ts`:
- Around line 96-99: Update UserPreferenceStore.list() to sort keys using direct
string comparison instead of localeCompare(), ensuring deterministic code-point
ordering for mixed-case or punctuation-bearing keys. Add a focused test covering
one such key ordering case.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b17f1a92-0232-468a-802b-09482641cab6

📥 Commits

Reviewing files that changed from the base of the PR and between 230a2b7 and cd97600.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (36)
  • .changeset/user-memory-mcp.md
  • Dockerfile
  • MEMORY.md
  • README.md
  • configs/amp/settings.json
  • configs/antigravity-cli/plugins/my-ai-tools-gemini-migration/mcp_config.json
  • configs/claude/mcp-servers.json
  • configs/cline/mcp-settings.json
  • configs/codex/config.toml
  • configs/commandcode/mcp.json
  • configs/copilot/mcp-config.json
  • configs/cursor/mcp.json
  • configs/devin/config.json
  • configs/factory/mcp.json
  • configs/gemini/settings.json
  • configs/grok/config.toml
  • configs/kilo/config.json
  • configs/kimi-code/mcp.json
  • configs/kiro/mcp.json
  • configs/kiro/settings.json
  • configs/mcp-registry.json
  • configs/mimo/mimocode.jsonc
  • configs/opencode/opencode.json
  • configs/pi/mcp.json
  • configs/qodercli/settings.json
  • package.json
  • packages/user-memory-mcp/README.md
  • packages/user-memory-mcp/package.json
  • packages/user-memory-mcp/src/schema.ts
  • packages/user-memory-mcp/src/server.ts
  • packages/user-memory-mcp/src/store.ts
  • packages/user-memory-mcp/src/tools.ts
  • packages/user-memory-mcp/tests/mcp.test.ts
  • packages/user-memory-mcp/tests/store.test.ts
  • packages/user-memory-mcp/tsconfig.json
  • tests/pr_user_memory_mcp.bats

Comment thread MEMORY.md
| `agentmemory` | Today, same session/project | `mcp__agentmemory__memory_save` |
| `/handoffs` | Continue a task in a future session | `/handoffs` slash command → resume with `/pickup` |

If you find yourself wanting both "remember this for me next time" and "let me continue this tomorrow" — that is two separate stores; pick the lane that matches the actual horizon.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Fix grammar.

The phrase "that is two separate stores" contains a grammatical error. Consider using "those are two separate stores".

📝 Proposed fix
-If you find yourself wanting both "remember this for me next time" and "let me continue this tomorrow" — that is two separate stores; pick the lane that matches the actual horizon.
+If you find yourself wanting both "remember this for me next time" and "let me continue this tomorrow" — those are two separate stores; pick the lane that matches the actual horizon.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
If you find yourself wanting both "remember this for me next time" and "let me continue this tomorrow" — that is two separate stores; pick the lane that matches the actual horizon.
If you find yourself wanting both "remember this for me next time" and "let me continue this tomorrow" — those are two separate stores; pick the lane that matches the actual horizon.
🧰 Tools
🪛 LanguageTool

[grammar] ~131-~131: Ensure spelling is correct
Context: ...e this tomorrow" — that is two separate stores; pick the lane that matches the actual h...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@MEMORY.md` at line 131, Update the sentence in MEMORY.md so “that is two
separate stores” uses the grammatically correct plural phrasing “those are two
separate stores,” while preserving the surrounding guidance.

Source: Linters/SAST tools

Comment on lines +96 to +99
async list(): Promise<UserPreference[]> {
const memory = await this.readMemory();
return [...memory.preferences].sort((left, right) => left.key.localeCompare(right.key));
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n -C3 '\.localeCompare\s*\(' packages/user-memory-mcp
rg -n -C3 'deterministic order' packages/user-memory-mcp/tests

Repository: jellydn/my-ai-tools

Length of output: 1289


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== store.ts =="
sed -n '1,180p' packages/user-memory-mcp/src/store.ts

echo
echo "== store.test.ts =="
sed -n '1,220p' packages/user-memory-mcp/tests/store.test.ts

Repository: jellydn/my-ai-tools

Length of output: 10521


🏁 Script executed:

#!/bin/bash
set -euo pipefail

node - <<'JS'
const pairs = [
  ["a", "A"],
  ["a", "b"],
  ["a", "_"],
  ["A", "a"],
  ["testRunner", "packageManager"],
  ["a-b", "a_b"],
];

for (const locale of [undefined, "en", "sv", "de", "tr", "und"]) {
  const label = locale ?? "(default)";
  console.log(`\nLocale: ${label}`);
  for (const [x, y] of pairs) {
    const r = locale === undefined ? x.localeCompare(y) : x.localeCompare(y, locale);
    console.log(`${JSON.stringify(x)} vs ${JSON.stringify(y)} => ${r}`);
  }
}
JS

Repository: jellydn/my-ai-tools

Length of output: 981


Use code-point ordering for list()
localeCompare() can produce locale-dependent ordering for mixed-case or punctuation-bearing keys. Switch to direct string comparison and add a test that covers one of those cases.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/user-memory-mcp/src/store.ts` around lines 96 - 99, Update
UserPreferenceStore.list() to sort keys using direct string comparison instead
of localeCompare(), ensuring deterministic code-point ordering for mixed-case or
punctuation-bearing keys. Add a focused test covering one such key ordering
case.

jellydn added 3 commits July 18, 2026 23:08
Model preferences as a keyed map instead of an array so get/set/delete
are O(1) and the key is not duplicated. Drop the constant source field
and the store-level explicit flag; MCP confirmed:true owns consent.
The package is not on npm yet, so configs and the registry now invoke
the linked bin instead of npx @jellydn/user-memory-mcp@latest. cli.sh
auto-links from the monorepo when the prerequisite is missing.
Run build/test for packages/* in CI so user-memory-mcp is not
config-only coverage. Dockerfile copies packages/ generically instead
of hardcoding one package path.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
packages/user-memory-mcp/src/store.ts (1)

102-107: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use code-point ordering for list().

localeCompare() can produce locale-dependent ordering for mixed-case or punctuation-bearing keys. Switch to direct string comparison to ensure deterministic code-point ordering.

🐛 Proposed fix
-			.sort((left, right) => left.key.localeCompare(right.key));
+			.sort((left, right) => (left.key < right.key ? -1 : left.key > right.key ? 1 : 0));
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/user-memory-mcp/src/store.ts` around lines 102 - 107, Update the
sorting comparator in UserPreferenceStore.list() to use direct string comparison
between left.key and right.key instead of localeCompare(), ensuring
deterministic code-point ordering for mixed-case and punctuation-bearing keys.
🧹 Nitpick comments (2)
configs/antigravity-cli/plugins/my-ai-tools-gemini-migration/mcp_config.json (1)

45-46: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Format both added JSON blocks with Biome’s tab indentation.

The repository guideline requires tabs for JSON files; both changed blocks use spaces.

  • configs/antigravity-cli/plugins/my-ai-tools-gemini-migration/mcp_config.json#L45-L46: reformat the added command and args lines with tabs.
  • configs/commandcode/mcp.json#L65-L66: reformat the added command and args lines with tabs.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@configs/antigravity-cli/plugins/my-ai-tools-gemini-migration/mcp_config.json`
around lines 45 - 46, Reformat the added command and args entries using Biome’s
tab indentation in
configs/antigravity-cli/plugins/my-ai-tools-gemini-migration/mcp_config.json
lines 45-46 and configs/commandcode/mcp.json lines 65-66; no content changes are
needed.

Source: Coding guidelines

.github/workflows/test.yml (1)

30-31: 🩺 Stability & Availability | 🔵 Trivial

Disable persisted checkout credentials.
This checkout step only needs read access, so set persist-credentials: false to avoid leaving the token in the runner’s git config.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/test.yml around lines 30 - 31, Add persist-credentials:
false to the actions/checkout@v7 step identified by the Checkout name, while
preserving its existing read-only checkout behavior.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@packages/user-memory-mcp/src/store.ts`:
- Around line 102-107: Update the sorting comparator in
UserPreferenceStore.list() to use direct string comparison between left.key and
right.key instead of localeCompare(), ensuring deterministic code-point ordering
for mixed-case and punctuation-bearing keys.

---

Nitpick comments:
In @.github/workflows/test.yml:
- Around line 30-31: Add persist-credentials: false to the actions/checkout@v7
step identified by the Checkout name, while preserving its existing read-only
checkout behavior.

In
`@configs/antigravity-cli/plugins/my-ai-tools-gemini-migration/mcp_config.json`:
- Around line 45-46: Reformat the added command and args entries using Biome’s
tab indentation in
configs/antigravity-cli/plugins/my-ai-tools-gemini-migration/mcp_config.json
lines 45-46 and configs/commandcode/mcp.json lines 65-66; no content changes are
needed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 08b625ee-f156-42c8-89e6-ba09cdb2ef69

📥 Commits

Reviewing files that changed from the base of the PR and between cd97600 and def18fa.

📒 Files selected for processing (35)
  • .github/workflows/test.yml
  • Dockerfile
  • README.md
  • cli.sh
  • configs/amp/settings.json
  • configs/antigravity-cli/plugins/my-ai-tools-gemini-migration/mcp_config.json
  • configs/claude/mcp-servers.json
  • configs/cline/mcp-settings.json
  • configs/codex/config.toml
  • configs/commandcode/mcp.json
  • configs/copilot/mcp-config.json
  • configs/cursor/mcp.json
  • configs/devin/config.json
  • configs/factory/mcp.json
  • configs/gemini/settings.json
  • configs/grok/config.toml
  • configs/kilo/config.json
  • configs/kimi-code/mcp.json
  • configs/kiro/mcp.json
  • configs/kiro/settings.json
  • configs/mcp-registry.json
  • configs/mimo/mimocode.jsonc
  • configs/opencode/opencode.json
  • configs/pi/mcp.json
  • configs/qodercli/settings.json
  • lib/install.sh
  • package.json
  • packages/user-memory-mcp/README.md
  • packages/user-memory-mcp/package.json
  • packages/user-memory-mcp/src/schema.ts
  • packages/user-memory-mcp/src/store.ts
  • packages/user-memory-mcp/src/tools.ts
  • packages/user-memory-mcp/tests/mcp.test.ts
  • packages/user-memory-mcp/tests/store.test.ts
  • tests/pr_user_memory_mcp.bats
🚧 Files skipped from review as they are similar to previous changes (9)
  • configs/pi/mcp.json
  • configs/kilo/config.json
  • configs/mimo/mimocode.jsonc
  • packages/user-memory-mcp/package.json
  • packages/user-memory-mcp/README.md
  • packages/user-memory-mcp/src/tools.ts
  • configs/copilot/mcp-config.json
  • tests/pr_user_memory_mcp.bats
  • README.md

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants