Skip to content

feat: add Amp (Sourcegraph) integration with auto-capture plugin#1049

Open
zuwasi wants to merge 1 commit into
rohitg00:mainfrom
zuwasi:feat/amp-integration
Open

feat: add Amp (Sourcegraph) integration with auto-capture plugin#1049
zuwasi wants to merge 1 commit into
rohitg00:mainfrom
zuwasi:feat/amp-integration

Conversation

@zuwasi

@zuwasi zuwasi commented Jul 12, 2026

Copy link
Copy Markdown

Summary

Adds native Amp (Sourcegraph's coding agent) support to agentmemory, following the same two-layer pattern as the existing Claude Code and Codex integrations.

What's included

1. MCP connectivity (\�gentmemory connect amp)

Writes the canonical MCP block (
px -y @agentmemory/mcp\ + env passthrough) into \�mp.mcpServers\ in the Amp settings file:

  • macOS/Linux: ~/.config/amp/settings.json\
  • Windows: %APPDATA%\amp\settings.json\

Amp uses the \�mp.mcpServers\ wrapper key (not the standard \mcpServers), so a dedicated adapter is needed rather than the shared \json-mcp-adapter.

2. Native plugin (\�gentmemory connect amp --with-hooks)

Also copies \integrations/amp/agentmemory.ts\ to ~/.config/amp/plugins/agentmemory.ts. The plugin uses Amp's Plugin API to hook into agent lifecycle events:

Amp event agentmemory REST endpoint hookType
\session.start\ \POST /agentmemory/session/start\
\�gent.start\ \POST /agentmemory/observe\ \prompt_submit\
\ ool.call\ (allowed, no interception)
\ ool.result\ (done) \POST /agentmemory/observe\ \post_tool_use\
\ ool.result\ (error) \POST /agentmemory/observe\ \post_tool_failure\
\�gent.end\ \POST /agentmemory/summarize\ + /session/end\

The plugin also registers:

  • 4 tools: \memory_recall, \memory_save, \memory_smart_search, \memory_sessions\
  • 3 commands: \�gentmemory-recall, \�gentmemory-remember, \�gentmemory-session-history\
  • Context injection (optional, \AGENTMEMORY_INJECT_CONTEXT=true): recalled memories injected into the agent's first turn via \�gent.start\ return value

Files changed

File Change
\integrations/amp/agentmemory.ts\ New - Amp plugin (auto-capture hooks + tools + commands)
\integrations/amp/README.md\ New - setup guide and event mapping reference
\src/cli/connect/amp.ts\ New - connect adapter (MCP config + plugin file installation)
\src/cli/connect/index.ts\ Modified - register amp in ADAPTERS, add to Windows allowlist
\ est/connect-amp.test.ts\ New - 8 tests: detect, install, already-wired, force, preserve, dry-run, registration
\ est/cli-connect.test.ts\ Modified - add amp to expected agent list (19 adapters)
\README.md\ Modified - add Amp section between Copilot CLI and OpenClaw
\package.json\ Modified - add \integrations/\ to published files so adapter can locate plugin source

Design notes

  • Amp plugins run via Bun, not Node.js. The plugin uses \ etch()\ (global in Bun) and \Bun.spawnSync\ for git toplevel resolution - no Node-specific dependencies.
  • Windows-safe: Amp has a Windows installer and the adapter handles both Unix and Windows config paths. Added \�mp\ to the \�llowWindowsAdapter\ list alongside \copilot-cli.
  • No new dependencies: the adapter reuses existing \AGENTMEMORY_MCP_BLOCK, \�ackupFile,
    eadJsonSafe, \writeJsonAtomic\ utilities from \util.ts.
  • Idempotent: re-running \�gentmemory connect amp\ detects existing config and returns \�lready-wired. --force\ overwrites.
  • Plugin source resolution: \ indPluginSource()\ walks upward from the adapter file to locate \integrations/amp/agentmemory.ts\ in the installed npm package (added to \ iles\ in \package.json).

Test results

\
test/connect-amp.test.ts: 8 passed
test/cli-connect.test.ts: 25 passed (all existing + updated agent list)
\\

All new tests pass. No existing tests broken.

Usage

\\�ash

1. Start the memory server

npx @agentmemory/agentmemory

2. Wire MCP + install the auto-capture plugin

agentmemory connect amp --with-hooks

3. Restart Amp (or run plugins: reload from the command palette)

\\

Summary by CodeRabbit

  • New Features

    • Added Amp (Sourcegraph) integration with automatic memory capture, recall, context injection, and session history.
    • Added connect amp setup for configuring Amp’s MCP connection and optional plugin installation.
    • Added Amp tools and command palette actions for saving, recalling, searching, and reviewing memories.
    • Added configuration options for remote servers, authentication, debugging, and project identification.
  • Documentation

    • Added installation, configuration, event mapping, and troubleshooting guidance for Amp integration.

Add native Amp support via two layers:

1. MCP connectivity — �gentmemory connect amp writes the canonical
   MCP block into �mp.mcpServers in ~/.config/amp/settings.json
   (or %APPDATA%/amp/settings.json on Windows). Amp uses the
   �mp.mcpServers wrapper key, not the standard mcpServers.

2. Native plugin — �gentmemory connect amp --with-hooks also copies
   integrations/amp/agentmemory.ts to ~/.config/amp/plugins/. The
   plugin hooks into Amp's session.start, agent.start, tool.call,
   tool.result, and agent.end events to automatically capture
   observations (prompts, tool calls, tool results, failures) and
   POST them to the agentmemory REST API. It also registers four
   memory tools (memory_recall, memory_save, memory_smart_search,
   memory_sessions) and three command palette commands
   (agentmemory-recall, agentmemory-remember, agentmemory-session-history).

The adapter is Windows-safe and added to the Windows allowlist
alongside copilot-cli. Amp's plugin API runs via Bun, so the plugin
file uses fetch() (available globally in Bun) and Bun.spawnSync for
git toplevel resolution — no Node-specific dependencies.

Tests: 8 new tests in test/connect-amp.test.ts covering detect,
install, already-wired, force, preserve-existing, dry-run, and
adapter registration. Updated test/cli-connect.test.ts to include
amp in the supported agent list (19 adapters).
@vercel

vercel Bot commented Jul 12, 2026

Copy link
Copy Markdown

@zuwasi is attempting to deploy a commit to the rohitg00's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds Amp support through a lifecycle plugin, MCP configuration adapter, CLI registration, tests, package publication, and installation documentation.

Changes

Amp integration

Layer / File(s) Summary
Amp lifecycle plugin
integrations/amp/agentmemory.ts, package.json
Adds lifecycle observation, optional context injection, REST-backed memory tools, UI commands, and publishes the integration directory.
Amp CLI connection adapter
src/cli/connect/amp.ts, src/cli/connect/index.ts, test/connect-amp.test.ts, test/cli-connect.test.ts
Detects Amp, writes amp.mcpServers configuration, optionally installs the plugin, registers the adapter, and tests wiring, idempotency, force, dry-run, and discovery behavior.
Amp integration documentation
README.md, integrations/amp/README.md
Documents automatic and manual setup, lifecycle mappings, tools, commands, environment variables, and remote deployment.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Amp
  participant AgentmemoryPlugin
  participant MemoryServer
  Amp->>AgentmemoryPlugin: Send lifecycle and tool events
  AgentmemoryPlugin->>MemoryServer: Post observations and session data
  MemoryServer-->>AgentmemoryPlugin: Return context and memory results
  AgentmemoryPlugin-->>Amp: Inject context and expose tool responses
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% 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 Amp (Sourcegraph) integration with the auto-capture plugin.
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 unit tests (beta)
  • Create PR with unit tests

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.

@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: 5

🧹 Nitpick comments (2)
integrations/amp/agentmemory.ts (1)

16-50: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consolidate post into postJson to remove duplication.

post and postJson duplicate the same fetch/timeout/error-handling logic; post only differs by discarding the result.

♻️ Proposed consolidation
-async function post(
-  path: string,
-  body: Record<string, unknown>,
-  timeoutMs = 5000,
-): Promise<void> {
-  try {
-    await fetch(`${API_URL}/agentmemory${path}`, {
-      method: 'POST',
-      headers: authHeaders(),
-      body: JSON.stringify(body),
-      signal: AbortSignal.timeout(timeoutMs),
-    })
-  } catch (e) {
-    if (DEBUG) logger?.log(`POST ${path} failed: ${(e as Error).message}`)
-  }
-}
-
 async function postJson(
   path: string,
   body: Record<string, unknown>,
   timeoutMs = 5000,
 ): Promise<Record<string, unknown> | null> {
   try {
     const res = await fetch(`${API_URL}/agentmemory${path}`, {
       method: 'POST',
       headers: authHeaders(),
       body: JSON.stringify(body),
       signal: AbortSignal.timeout(timeoutMs),
     })
     return res.ok ? ((await res.json()) as Record<string, unknown>) : null
   } catch (e) {
     if (DEBUG) logger?.log(`POST ${path} failed: ${(e as Error).message}`)
     return null
   }
 }
+
+async function post(
+  path: string,
+  body: Record<string, unknown>,
+  timeoutMs = 5000,
+): Promise<void> {
+  await postJson(path, body, timeoutMs)
+}
🤖 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 `@integrations/amp/agentmemory.ts` around lines 16 - 50, Remove the duplicate
fetch implementation from post and consolidate its behavior into postJson,
reusing postJson for requests where the response body is discarded. Preserve the
existing POST options, timeout handling, and DEBUG error logging, while keeping
post’s Promise<void> contract for callers.
src/cli/connect/amp.ts (1)

16-24: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

A few comments restate what the code already says.

E.g. // Amp uses "amp.mcpServers" as the wrapper key (not "mcpServers"). right above WRAPPER_KEY, and // Install the plugin file when --with-hooks is passed above if (opts.withHooks). As per coding guidelines, src/**/*.ts should prefer clear naming over comments explaining what code does.

Also applies to: 40-41, 115-115, 135-135

🤖 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 `@src/cli/connect/amp.ts` around lines 16 - 24, Remove comments in the Amp CLI
module that merely restate clear code behavior, including the wrapper-key note
above WRAPPER_KEY and the installation note above the opts.withHooks condition.
Preserve comments that provide necessary external context, such as Amp
configuration paths or non-obvious compatibility details.

Source: Coding guidelines

🤖 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 `@integrations/amp/agentmemory.ts`:
- Around line 52-67: Cache the result of resolveProject() so git resolution is
performed once per process (or once per working directory) rather than on every
observation. Update resolveProject and its surrounding state to return the
cached project name while preserving AGENTMEMORY_PROJECT_NAME precedence and the
existing cwd fallback behavior; ensure observe’s agent.start, tool.result, and
tool.call paths reuse that cached value.
- Around line 205-215: Update the agent.end handler to await both post calls for
/summarize and /session/end before deleting the session from contextCache and
returning. Preserve their existing payloads and timeout values.

In `@src/cli/connect/amp.ts`:
- Around line 57-69: The findPluginSource function derives its starting path
incorrectly from import.meta.url, causing plugin lookup to fail on macOS/Linux.
Replace the manual URL pathname conversion with fileURLToPath(import.meta.url),
and add a withHooks: true test case covering successful plugin installation.
- Around line 107-113: Move the backupFile and logBackup calls in the connect
flow behind the condition that determines whether writeJsonAtomic will modify
the configuration. Preserve directory creation for missing CONFIG_PATH, and
ensure already-wired --with-hooks runs skip both the backup and write
operations.

In `@test/connect-amp.test.ts`:
- Around line 127-134: The AMP adapter tests lack coverage for the withHooks
installation path. Add a test near the existing dry-run case that invokes
adapter.install with withHooks: true and verifies the plugin file is copied to
the PLUGIN_FILE destination, exercising findPluginSource and copyFileSync.

---

Nitpick comments:
In `@integrations/amp/agentmemory.ts`:
- Around line 16-50: Remove the duplicate fetch implementation from post and
consolidate its behavior into postJson, reusing postJson for requests where the
response body is discarded. Preserve the existing POST options, timeout
handling, and DEBUG error logging, while keeping post’s Promise<void> contract
for callers.

In `@src/cli/connect/amp.ts`:
- Around line 16-24: Remove comments in the Amp CLI module that merely restate
clear code behavior, including the wrapper-key note above WRAPPER_KEY and the
installation note above the opts.withHooks condition. Preserve comments that
provide necessary external context, such as Amp configuration paths or
non-obvious compatibility details.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2ae3d533-061f-4baa-bf3d-2f09f341fe06

📥 Commits

Reviewing files that changed from the base of the PR and between 93ae9bc and 7f0f686.

📒 Files selected for processing (8)
  • README.md
  • integrations/amp/README.md
  • integrations/amp/agentmemory.ts
  • package.json
  • src/cli/connect/amp.ts
  • src/cli/connect/index.ts
  • test/cli-connect.test.ts
  • test/connect-amp.test.ts

Comment on lines +52 to +67
// --- Project resolution -------------------------------------------
function resolveProject(): string {
const explicit = process.env.AGENTMEMORY_PROJECT_NAME
if (explicit && explicit.trim()) return explicit.trim()
const cwd = process.cwd()
try {
const top = Bun.spawnSync(['git', 'rev-parse', '--show-toplevel'], {
cwd,
stdout: 'pipe',
stderr: 'ignore',
timeout: 500,
}).stdout?.toString().trim()
if (top) return top.split(/[/\\]/).pop()!
} catch {}
return cwd.split(/[/\\]/).pop()!
}

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.

🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

Cache resolveProject() instead of spawning git synchronously on every event.

resolveProject() runs a blocking Bun.spawnSync on every call, and observe() calls it on every agent.start and every single tool.result/tool.call observation — i.e. potentially dozens of times per session. Amp's own docs note that plugins are long-lived processes that may run for multiple threads concurrently, so a synchronous subprocess spawn in one thread's handler blocks the whole plugin's event loop for every other concurrently-running thread too.

The resolved project name is stable for the process lifetime (or at minimum per cwd); cache it instead of re-spawning git each time.

⚡ Proposed caching fix
+const projectCache = new Map<string, string>()
+
 function resolveProject(): string {
   const explicit = process.env.AGENTMEMORY_PROJECT_NAME
   if (explicit && explicit.trim()) return explicit.trim()
   const cwd = process.cwd()
+  const cached = projectCache.get(cwd)
+  if (cached) return cached
   try {
     const top = Bun.spawnSync(['git', 'rev-parse', '--show-toplevel'], {
       cwd,
       stdout: 'pipe',
       stderr: 'ignore',
       timeout: 500,
     }).stdout?.toString().trim()
-    if (top) return top.split(/[/\\]/).pop()!
+    if (top) {
+      const name = top.split(/[/\\]/).pop()!
+      projectCache.set(cwd, name)
+      return name
+    }
   } catch {}
-  return cwd.split(/[/\\]/).pop()!
+  const fallback = cwd.split(/[/\\]/).pop()!
+  projectCache.set(cwd, fallback)
+  return fallback
 }

Also applies to: 70-83

🤖 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 `@integrations/amp/agentmemory.ts` around lines 52 - 67, Cache the result of
resolveProject() so git resolution is performed once per process (or once per
working directory) rather than on every observation. Update resolveProject and
its surrounding state to return the cached project name while preserving
AGENTMEMORY_PROJECT_NAME precedence and the existing cwd fallback behavior;
ensure observe’s agent.start, tool.result, and tool.call paths reuse that cached
value.

Comment on lines +205 to +215
amp.on('agent.end', async (event) => {
const sessionId = event.thread.id
const toolCalls = amp.helpers.toolCallsInMessages(event.messages)
await observe(sessionId, 'agent_end', {
status: event.status,
tool_call_count: toolCalls.length,
})
post('/summarize', { sessionId }, 120000)
post('/session/end', { sessionId }, 5000)
contextCache.delete(sessionId)
})

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.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Does the Amp (Sourcegraph) plugin API guarantee pending promises/fetches complete after an agent.end hook handler returns?

💡 Result:

No, the Amp (Sourcegraph) plugin API does not guarantee that pending promises or asynchronous fetches complete after an agent.end hook handler returns [1]. The agent.end hook is treated as a fire-and-forget event [1]. In the context of Amp's plugin architecture, lifecycle handlers—including agent.end—are typically invoked without an orchestration mechanism that waits for the handler's internal asynchronous operations to resolve before proceeding [1]. Developers implementing these hooks should assume that any asynchronous tasks, such as network requests (fetches) or other promise-based logic, will continue to run in the background after the handler returns, or may be terminated if the runtime environment ceases execution of the plugin process [1]. For scenarios requiring reliable execution of asynchronous tasks, such as reporting telemetry or state synchronization, developers should handle the lifecycle of those operations independently, as the plugin API does not provide a mechanism to await the completion of tasks triggered within the agent.end hook [1].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the relevant file and locate the post helper / agent.end hook.
git ls-files 'integrations/amp/*' 'integrations/**' | sed -n '1,200p'
printf '\n--- outline agentmemory.ts ---\n'
ast-grep outline integrations/amp/agentmemory.ts --view expanded || true
printf '\n--- search for post definition/usages ---\n'
rg -n "function post|const post|post\\(" integrations/amp -g '!**/dist/**' -g '!**/build/**'
printf '\n--- relevant snippet around agent.end ---\n'
sed -n '180,235p' integrations/amp/agentmemory.ts

Repository: rohitg00/agentmemory

Length of output: 3826


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,70p' integrations/amp/agentmemory.ts

Repository: rohitg00/agentmemory

Length of output: 2366


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
p = Path('integrations/amp/agentmemory.ts')
for i, line in enumerate(p.read_text().splitlines(), 1):
    if 1 <= i <= 70:
        print(f"{i:4d}: {line}")
PY

Repository: rohitg00/agentmemory

Length of output: 2786


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
text = Path('integrations/amp/agentmemory.ts').read_text().splitlines()
for i in range(1, 71):
    print(f"{i:4d}: {text[i-1]}")
PY

Repository: rohitg00/agentmemory

Length of output: 2786


Await the final session writes. agent.end should await /summarize and /session/end; otherwise the hook can return before those last writes complete, and they may be dropped during teardown.

🤖 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 `@integrations/amp/agentmemory.ts` around lines 205 - 215, Update the agent.end
handler to await both post calls for /summarize and /session/end before deleting
the session from contextCache and returning. Preserve their existing payloads
and timeout values.

Comment thread src/cli/connect/amp.ts
Comment on lines +57 to +69
function findPluginSource(): string {
let dir = dirname(new URL(import.meta.url).pathname.replace(/^\//, ""));
for (let i = 0; i < 15; i++) {
const candidate = join(dir, "integrations", "amp", "agentmemory.ts");
if (existsSync(candidate)) return candidate;
const parent = dirname(dir);
if (parent === dir) break;
dir = parent;
}
throw new Error(
"Could not locate integrations/amp/agentmemory.ts — is the package installed correctly?",
);
}

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 | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== src/cli/connect/amp.ts ==\n'
nl -ba src/cli/connect/amp.ts | sed -n '1,220p'

printf '\n== test/connect-amp.test.ts ==\n'
nl -ba test/connect-amp.test.ts | sed -n '1,260p'

printf '\n== search for withHooks / findPluginSource ==\n'
rg -n "withHooks|findPluginSource|agentmemory\.ts|install\(" src test

Repository: rohitg00/agentmemory

Length of output: 228


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== src/cli/connect/amp.ts ==\n'
cat -n src/cli/connect/amp.ts | sed -n '1,220p'

printf '\n== test/connect-amp.test.ts ==\n'
cat -n test/connect-amp.test.ts | sed -n '1,260p'

printf '\n== search for withHooks / findPluginSource ==\n'
rg -n "withHooks|findPluginSource|agentmemory\.ts|install\(" src test

Repository: rohitg00/agentmemory

Length of output: 22491


🏁 Script executed:

#!/bin/bash
set -euo pipefail

node - <<'JS'
const { dirname, join } = require('node:path');

const samples = [
  'file:///home/user/pkg/dist/cli/connect/amp.js',
  'file:///C:/Users/user/pkg/dist/cli/connect/amp.js',
];

for (const url of samples) {
  const pathname = new URL(url).pathname;
  const stripped = pathname.replace(/^\//, '');
  console.log('\nURL:', url);
  console.log('pathname:', pathname);
  console.log('stripped:', stripped);
  console.log('dirname(stripped):', dirname(stripped));
  console.log('candidate:', join(dirname(stripped), 'integrations', 'amp', 'agentmemory.ts'));
}
JS

Repository: rohitg00/agentmemory

Length of output: 724


Use fileURLToPath(import.meta.url) for plugin lookup new URL(import.meta.url).pathname.replace(/^\//, "") turns POSIX absolute paths into relative ones, so findPluginSource() walks from process.cwd() and --with-hooks silently skips plugin installation on macOS/Linux. Add a withHooks: true test case here too.

🤖 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 `@src/cli/connect/amp.ts` around lines 57 - 69, The findPluginSource function
derives its starting path incorrectly from import.meta.url, causing plugin
lookup to fail on macOS/Linux. Replace the manual URL pathname conversion with
fileURLToPath(import.meta.url), and add a withHooks: true test case covering
successful plugin installation.

Comment thread src/cli/connect/amp.ts
Comment on lines +107 to +113
let backupPath: string | undefined;
if (existsSync(CONFIG_PATH)) {
backupPath = backupFile(CONFIG_PATH, this.name);
logBackup(backupPath);
} else {
mkdirSync(dirname(CONFIG_PATH), { recursive: true });
}

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect backupFile() to see if it creates a new timestamped file each call
rg -n -A 15 'export function backupFile' src/cli/connect/util.ts

Repository: rohitg00/agentmemory

Length of output: 648


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the surrounding logic in src/cli/connect/amp.ts
sed -n '70,150p' src/cli/connect/amp.ts

# Inspect backup helper context
sed -n '1,120p' src/cli/connect/util.ts

Repository: rohitg00/agentmemory

Length of output: 6362


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '70,150p' src/cli/connect/amp.ts
printf '\n---\n'
sed -n '1,120p' src/cli/connect/util.ts

Repository: rohitg00/agentmemory

Length of output: 6367


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the control flow around the backup/write decision in src/cli/connect/amp.ts
nl -ba src/cli/connect/amp.ts | sed -n '80,145p'

Repository: rohitg00/agentmemory

Length of output: 198


Skip the backup on no-op runs. When --with-hooks is re-run against an already-wired config, backupFile() still creates a new timestamped copy even though writeJsonAtomic() is skipped. Move the backup behind the write condition so unchanged installs don’t accumulate backups.

🤖 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 `@src/cli/connect/amp.ts` around lines 107 - 113, Move the backupFile and
logBackup calls in the connect flow behind the condition that determines whether
writeJsonAtomic will modify the configuration. Preserve directory creation for
missing CONFIG_PATH, and ensure already-wired --with-hooks runs skip both the
backup and write operations.

Comment thread test/connect-amp.test.ts
Comment on lines +127 to +134
it("dry-run does not write any file", async () => {
const configDir = ampConfigDir(home);
mkdirSync(configDir, { recursive: true });
const { adapter } = await import("../src/cli/connect/amp.js");
const result = await adapter.install({ dryRun: true, force: false });
expect(result.kind).toBe("installed");
expect(existsSync(join(configDir, "settings.json"))).toBe(false);
});

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 | 🟠 Major | ⚡ Quick win

Add coverage for withHooks: true (plugin file install path).

No test exercises adapter.install({ ..., withHooks: true }), so the plugin-copy path in findPluginSource()/copyFileSync is completely untested — this is how the POSIX path-resolution bug flagged in src/cli/connect/amp.ts (lines 57-69) went unnoticed.

Want me to draft a test that runs install({ withHooks: true }) and asserts the plugin file gets copied to PLUGIN_FILE?

🤖 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 `@test/connect-amp.test.ts` around lines 127 - 134, The AMP adapter tests lack
coverage for the withHooks installation path. Add a test near the existing
dry-run case that invokes adapter.install with withHooks: true and verifies the
plugin file is copied to the PLUGIN_FILE destination, exercising
findPluginSource and copyFileSync.

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.

1 participant