Skip to content

feat(cli): agentmemory connect — automate native-plugin install for 8 agents#402

Merged
rohitg00 merged 1 commit into
mainfrom
feat/cli-connect
May 15, 2026
Merged

feat(cli): agentmemory connect — automate native-plugin install for 8 agents#402
rohitg00 merged 1 commit into
mainfrom
feat/cli-connect

Conversation

@rohitg00
Copy link
Copy Markdown
Owner

@rohitg00 rohitg00 commented May 15, 2026

Summary

agentmemory connect <agent> automates wiring agentmemory into each supported coding agent — no more reading integrations/<agent>/README.md and copy-pasting JSON by hand. Modeled on skillkit install <skill>.

Each adapter: detect → backup → merge → verify → idempotent.

agentmemory connect                    # interactive: detect + multi-select
agentmemory connect claude-code        # wire one
agentmemory connect --all              # wire every detected
agentmemory connect claude-code --dry-run
agentmemory connect claude-code --force

Backups land in ~/.agentmemory/backups/<agent>-<timestamp>.<ext> before any write. Re-running is a no-op unless --force is passed.

Status table

Agent Status Target Notes
claude-code ✅ working ~/.claude.json (mcpServers merge) Live-tested end-to-end on macOS
codex ✅ working ~/.codex/config.toml (TOML block append/rewrite) Text-based merge — no new TOML dep
cursor ✅ working ~/.cursor/mcp.json (mcpServers merge)
gemini-cli ✅ working ~/.gemini/settings.json (mcpServers merge)
openclaw ✅ working ~/.openclaw/openclaw.json (mcpServers merge)
hermes ⚠ stubbed ~/.hermes/config.yaml YAML merge deferred — needs yaml dep; prints manual steps + docs link
pi ⚠ stubbed ~/.pi/agent/extensions/agentmemory/ TS-file copy deferred; prints manual steps
openhuman ⚠ stubbed n/a integrations/openhuman/ doesn't exist yet in the repo

Windows: every adapter prints "Windows: manual install required — see docs" and exits cleanly. Symlink semantics differ enough that I didn't try.

Layout

  • src/cli/connect/index.ts — dispatcher + argv parsing + interactive picker
  • src/cli/connect/types.tsConnectAdapter interface + result types
  • src/cli/connect/util.ts — backup, atomic JSON write, log helpers
  • src/cli/connect/json-mcp-adapter.ts — shared adapter factory for cursor / gemini-cli / openclaw
  • src/cli/connect/{claude-code,codex,cursor,gemini-cli,openclaw,hermes,pi,openhuman}.ts — one file per agent
  • src/cli.ts — wires connect into the commands map + --help text
  • test/cli-connect.test.ts — 13 tests (dispatcher resolution, fail-loud on unknown, claude-code mock-fs happy path + idempotency + dry-run + backup, stub adapters)

Test plan

  • npm run build — passes (added dist/connect-*.mjs chunk, 15.98 kB)
  • npx vitest run test/cli-connect.test.ts — 13/13 pass
  • Full suite: 924 pass / 9 fail. The 9 failures are pre-existing in test/mcp-standalone.test.ts (spec called out ~11) — my additions are net-positive
  • node dist/cli.mjs --helpconnect documented alongside init/status/doctor/demo
  • node dist/cli.mjs connect claude-code --dry-run on live machine — detects ~/.claude/, prints planned diff, no file mutated
  • node dist/cli.mjs connect not-a-real-agent — fails loud with exit 1 + supported list

Out of scope

Disconnect / uninstall is sibling work — agentmemory remove will undo what this wrote (backups already exist for it).

Summary by CodeRabbit

  • New Features

    • Added connect [agent] command for integrating AgentMemory with multiple AI agents: Claude Code, Codex, Cursor, Gemini CLI, Hermes, OpenClaw, OpenHuman, and Pi.
    • Supports interactive agent selection, --all (connect all detected agents), --dry-run, and --force re-installation flags.
    • Automatic MCP server configuration with backup creation.
  • Tests

    • Added comprehensive test suite for connection functionality across all supported agents.

Review Change Stack

…for 8 agents

agentmemory connect <agent> wires agentmemory into each supported coding agent: detect install, back up existing config to ~/.agentmemory/backups/, merge agentmemory MCP entry, verify, idempotent on re-run.

Working: claude-code, codex, cursor, gemini-cli, openclaw. Stubbed with manual-install hints: hermes (YAML), pi (TS extension copy), openhuman (no integrations folder). Windows prints manual-install message and exits.

Argv: agentmemory connect [agent] [--all] [--dry-run] [--force]
@vercel
Copy link
Copy Markdown

vercel Bot commented May 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agentmemory Ready Ready Preview, Comment May 15, 2026 2:53pm

Request Review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 15, 2026

📝 Walkthrough

Walkthrough

This PR introduces a comprehensive agentmemory connect CLI command that automates MCP (Model Context Protocol) server configuration across eight AI agent applications. The feature includes interactive agent selection, dry-run and force-reinstall modes, and adapters for both automated JSON/TOML configuration and manual setup flows.

Changes

AgentMemory connect command for MCP server wiring

Layer / File(s) Summary
Type contracts and shared utilities
src/cli/connect/types.ts, src/cli/connect/util.ts
ConnectAdapter and ConnectResult types define the adapter contract. Utilities provide filesystem backup, atomic JSON writing, safe JSON reading, and CLI logging for a consistent wiring experience across all adapters.
JSON MCP adapter factory
src/cli/connect/json-mcp-adapter.ts
Reusable factory createJsonMcpAdapter() encapsulates config detection, merging, atomic writes, and verification for agents using JSON-based MCP configuration (Cursor, Gemini CLI, OpenClaw).
JSON-based adapter implementations
src/cli/connect/cursor.ts, src/cli/connect/gemini-cli.ts, src/cli/connect/openclaw.ts
Three adapters configured via the JSON factory with platform-specific name, displayName, detection directory, and config file paths.
Custom adapter implementations
src/cli/connect/claude-code.ts, src/cli/connect/codex.ts
Claude Code (JSON config) and Codex (TOML config) adapters implement platform-specific file merging, MCP entry detection, and verification without using the JSON factory.
Stub adapters with manual installation
src/cli/connect/hermes.ts, src/cli/connect/openhuman.ts, src/cli/connect/pi.ts
Three adapters for platforms not yet supporting automated wiring; they emit user-facing setup instructions and return stub results indicating unsupported automation.
Connect command entry point and control flow
src/cli/connect/index.ts
Core orchestration: Windows platform gating, flag parsing (--dry-run, --force, --all), interactive multi-select of detected agents via @clack/prompts, adapter invocation, and per-agent outcome summarization with restart guidance.
CLI command registration and help
src/cli.ts
Adds connect [agent] to the help text and registers the command dispatcher, routing agentmemory connect ... to the new runConnectCmd() handler via dynamic import.
Test coverage
test/cli-connect.test.ts
Vitest suite validating adapter discovery, name resolution, and detailed claude-code behaviors including configuration persistence, idempotency, force rewrites, dry-run safety, and backup creation. Stub adapter outcomes are also verified.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

The changes introduce a multi-adapter wiring infrastructure across 14 new files with varying logic density. While most adapters follow a pattern, Claude Code and Codex adapters use custom JSON/TOML handling logic requiring separate review. The orchestration layer combines interactive selection, platform gating, and flag parsing. Comprehensive test coverage validates the main paths but the infrastructure itself is substantial and heterogeneous.

🐰 A rabbit's ode to configuration:

From cursor to code, from Claude to Pi,
This connect command makes wiring fly,
Adapters adapt in their unique ways,
While backups keep safe our agent days. 🔧✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.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 and specifically summarizes the main change: a new CLI feature that automates installation of the agentmemory plugin into 8 supported coding agents.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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/cli-connect

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (5)
src/cli/connect/index.ts (2)

141-143: ⚡ Quick win

Simplify the type narrowing.

The cast (result as { reason: string }).reason is fragile. TypeScript should narrow result automatically after checking result.kind === "skipped". If it doesn't, the type definition in types.ts may need adjustment (discriminated union).

♻️ Proposed fix to rely on automatic narrowing
   const result = await runAdapter(adapter, opts);
   summarize([{ name: agentName, result }]);
-  if (result.kind === "skipped" && (result as { reason: string }).reason !== "not-detected") {
+  if (result.kind === "skipped" && result.reason !== "not-detected") {
     process.exit(1);
   }

If TypeScript complains, the ConnectResult type in types.ts may not be properly defined as a discriminated union.

🤖 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/index.ts` around lines 141 - 143, Remove the unsafe cast by
relying on TypeScript's discriminated union: after the existing check if
(result.kind === "skipped") use result.reason directly instead of (result as {
reason: string }).reason; if the compiler still complains, update the
ConnectResult definition in types.ts to be a proper discriminated union where
the "skipped" variant includes a string reason (e.g., an interface/type with
kind: "skipped" and reason: string) so the check on result.kind narrows the type
automatically.

93-93: ⚡ Quick win

Add outro before exit for consistency.

Lines 136 calls p.outro() before process.exit(1), but lines 93 and 118 exit without an outro message. This creates an inconsistent UX where some error paths show a closing banner and others don't.

♻️ Proposed fix to add outro before exit
     if (detected.length === 0) {
       p.log.error("No supported agents detected on this machine.");
       p.outro(`Supported: ${knownAgents().join(", ")}`);
+      // Note: outro already called above
       process.exit(1);
     }

And for line 118:

     if (detected.length === 0) {
       p.log.error("No supported agents detected on this machine.");
+      p.outro(`Supported: ${knownAgents().join(", ")}`);
       process.exit(1);
     }

Also applies to: 118-118

🤖 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/index.ts` at line 93, Several error paths in
src/cli/connect/index.ts call process.exit(1) without printing the CLI closing
banner; before each bare process.exit(1) (the ones next to the existing call at
the top-level and the one around the failure at line 118), call p.outro() so the
outro is shown consistently on all exits—i.e., locate the places where
process.exit(1) is invoked (the same contexts as the existing p.outro() +
process.exit(1) combo) and insert a p.outro() immediately before each
process.exit(1), guarding against double-calling only if an earlier code path
already called p.outro().
test/cli-connect.test.ts (1)

94-94: ⚡ Quick win

Use the imported mkdirSync instead of require.

The file imports mkdirSync from node:fs at line 2, but lines 94, 116, 132, and 145 use require("node:fs").mkdirSync(...) instead. This creates unnecessary inconsistency.

♻️ Proposed fix to use imported function

Replace all occurrences of require("node:fs").mkdirSync(...) with mkdirSync(...):

-    require("node:fs").mkdirSync(claudeDir, { recursive: true });
+    mkdirSync(claudeDir, { recursive: true });

Apply the same change to lines 116, 132, and 145.

Also applies to: 116-116, 132-132, 145-145

🤖 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/cli-connect.test.ts` at line 94, Replace the inline require calls with
the imported function: change every occurrence of
require("node:fs").mkdirSync(...) to use the already-imported mkdirSync(...)
(the calls that create claudeDir and the other three similar directories),
ensuring you keep the same options (e.g., { recursive: true }) and argument
order; look for the four spots where require("node:fs").mkdirSync is used and
swap them to mkdirSync to maintain consistency with the import at the top.
src/cli/connect/codex.ts (2)

52-52: 💤 Low value

Simplify confusing no-op regex replace.

The .replace(/\n{3,}$/, "\n\n") is immediately undone by .trimEnd(), which removes all trailing whitespace including the newlines just added. The net effect is out.join("\n").trimEnd() + "\n". While this produces the correct result, the intermediate replace step is confusing and serves no purpose.

♻️ Proposed simplification
-  return out.join("\n").replace(/\n{3,}$/, "\n\n").trimEnd() + "\n";
+  return out.join("\n").trimEnd() + "\n";
🤖 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/codex.ts` at line 52, The trailing-newline normalization
currently does a no-op replace: change the return that uses
out.join("\n").replace(/\n{3,}$/, "\n\n").trimEnd() + "\n" to simply join the
lines, trim trailing whitespace, and append a single newline (i.e., use
out.join("\n").trimEnd() + "\n") so remove the unnecessary .replace call; locate
the expression referencing the variable out in the return statement in codex.ts
to update it.

89-91: 💤 Low value

Consider clearer formatting for complex string concatenation.

The nested ternary operators in line 91 make the spacing logic hard to parse at a glance. While correct, extracting the logic or adding intermediate variables would improve readability.

♻️ Example refactor for clarity
     const cleaned = wired ? stripExistingBlock(current) : current;
-    const joiner = cleaned.length === 0 || cleaned.endsWith("\n") ? "" : "\n";
-    const next = `${cleaned}${joiner}${cleaned.length > 0 ? "\n" : ""}${TOML_BLOCK}`;
+    let next = cleaned;
+    if (!next.endsWith("\n") && next.length > 0) {
+      next += "\n";
+    }
+    if (next.length > 0) {
+      next += "\n";
+    }
+    next += TOML_BLOCK;
     writeFileSync(CODEX_TOML, next, "utf-8");
🤖 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/codex.ts` around lines 89 - 91, The string-concatenation that
builds next (using cleaned, joiner and nested ternaries) is hard to read;
refactor by extracting the spacing logic into clear intermediate variables and a
small helper so the expression in next is a single straightforward template.
Specifically, compute a prefix (e.g., empty vs "\n"), a suffix (whether to add
an extra "\n" when cleaned.length > 0), and reuse joiner, then compose next from
cleaned + prefix + suffix + TOML_BLOCK; update usages of cleaned, joiner and
next and keep stripExistingBlock, current, wired and TOML_BLOCK names intact.
🤖 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 `@src/cli/connect/claude-code.ts`:
- Around line 67-69: Remove the redundant intermediate write of an empty JSON
object: keep the directory creation using mkdirSync(CLAUDE_DIR, { recursive:
true }) but delete the writeFileSync(CLAUDE_JSON, "{}\n", "utf-8") call and let
writeJsonAtomic(CLAUDE_JSON, data, ...) perform the initial write atomically;
update any related comments and ensure CLAUDE_DIR and CLAUDE_JSON are still
created/available before calling writeJsonAtomic.

---

Nitpick comments:
In `@src/cli/connect/codex.ts`:
- Line 52: The trailing-newline normalization currently does a no-op replace:
change the return that uses out.join("\n").replace(/\n{3,}$/, "\n\n").trimEnd()
+ "\n" to simply join the lines, trim trailing whitespace, and append a single
newline (i.e., use out.join("\n").trimEnd() + "\n") so remove the unnecessary
.replace call; locate the expression referencing the variable out in the return
statement in codex.ts to update it.
- Around line 89-91: The string-concatenation that builds next (using cleaned,
joiner and nested ternaries) is hard to read; refactor by extracting the spacing
logic into clear intermediate variables and a small helper so the expression in
next is a single straightforward template. Specifically, compute a prefix (e.g.,
empty vs "\n"), a suffix (whether to add an extra "\n" when cleaned.length > 0),
and reuse joiner, then compose next from cleaned + prefix + suffix + TOML_BLOCK;
update usages of cleaned, joiner and next and keep stripExistingBlock, current,
wired and TOML_BLOCK names intact.

In `@src/cli/connect/index.ts`:
- Around line 141-143: Remove the unsafe cast by relying on TypeScript's
discriminated union: after the existing check if (result.kind === "skipped") use
result.reason directly instead of (result as { reason: string }).reason; if the
compiler still complains, update the ConnectResult definition in types.ts to be
a proper discriminated union where the "skipped" variant includes a string
reason (e.g., an interface/type with kind: "skipped" and reason: string) so the
check on result.kind narrows the type automatically.
- Line 93: Several error paths in src/cli/connect/index.ts call process.exit(1)
without printing the CLI closing banner; before each bare process.exit(1) (the
ones next to the existing call at the top-level and the one around the failure
at line 118), call p.outro() so the outro is shown consistently on all
exits—i.e., locate the places where process.exit(1) is invoked (the same
contexts as the existing p.outro() + process.exit(1) combo) and insert a
p.outro() immediately before each process.exit(1), guarding against
double-calling only if an earlier code path already called p.outro().

In `@test/cli-connect.test.ts`:
- Line 94: Replace the inline require calls with the imported function: change
every occurrence of require("node:fs").mkdirSync(...) to use the
already-imported mkdirSync(...) (the calls that create claudeDir and the other
three similar directories), ensuring you keep the same options (e.g., {
recursive: true }) and argument order; look for the four spots where
require("node:fs").mkdirSync is used and swap them to mkdirSync to maintain
consistency with the import at the top.
🪄 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: 5adc883b-a4f2-4d17-a29a-04d1c6544296

📥 Commits

Reviewing files that changed from the base of the PR and between 372c6a6 and a92c342.

📒 Files selected for processing (14)
  • src/cli.ts
  • src/cli/connect/claude-code.ts
  • src/cli/connect/codex.ts
  • src/cli/connect/cursor.ts
  • src/cli/connect/gemini-cli.ts
  • src/cli/connect/hermes.ts
  • src/cli/connect/index.ts
  • src/cli/connect/json-mcp-adapter.ts
  • src/cli/connect/openclaw.ts
  • src/cli/connect/openhuman.ts
  • src/cli/connect/pi.ts
  • src/cli/connect/types.ts
  • src/cli/connect/util.ts
  • test/cli-connect.test.ts

Comment on lines +67 to +69
mkdirSync(CLAUDE_DIR, { recursive: true });
writeFileSync(CLAUDE_JSON, "{}\n", "utf-8");
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove unnecessary intermediate file write.

Line 68 writes an empty JSON object {} to CLAUDE_JSON, but line 73 immediately overwrites it via writeJsonAtomic. The intermediate write serves no purpose—only the directory creation on line 67 is needed before the atomic write.

♻️ Proposed fix
     } else {
       mkdirSync(CLAUDE_DIR, { recursive: true });
-      writeFileSync(CLAUDE_JSON, "{}\n", "utf-8");
     }
📝 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
mkdirSync(CLAUDE_DIR, { recursive: true });
writeFileSync(CLAUDE_JSON, "{}\n", "utf-8");
}
mkdirSync(CLAUDE_DIR, { recursive: true });
}
🤖 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/claude-code.ts` around lines 67 - 69, Remove the redundant
intermediate write of an empty JSON object: keep the directory creation using
mkdirSync(CLAUDE_DIR, { recursive: true }) but delete the
writeFileSync(CLAUDE_JSON, "{}\n", "utf-8") call and let
writeJsonAtomic(CLAUDE_JSON, data, ...) perform the initial write atomically;
update any related comments and ensure CLAUDE_DIR and CLAUDE_JSON are still
created/available before calling writeJsonAtomic.

@rohitg00 rohitg00 merged commit b36a6d7 into main May 15, 2026
5 checks passed
rohitg00 added a commit that referenced this pull request May 15, 2026
… remove, silent killers) (#407)

Patch bump per the established rule: all changes additive, no breaks
to MemoryProvider trait or exported types or default behaviour. New
top-level subcommands (connect, remove, --reset, --force) are opt-in.

PRs included since v0.9.14:
  #405 — silent killers: viewer port auto-bump, engine version-match
         warning, stop --force, adopt-on-attach, npx PATH hint
  #402 — agentmemory connect — automate native-plugin install for 8
         agents (claude-code, codex, cursor, gemini-cli, openclaw
         end-to-end; hermes/pi/openhuman stubbed)
  #406 — interactive doctor v2 + agentmemory remove (destruction plan
         + two-confirmation flow)
  #403 — splash banner + agent grid + provider picker + smart-defaults
         preferences + bootLog shim (30+ lines of log spam → 10)

Files bumped (9):
  package.json, packages/mcp/package.json, plugin/.claude-plugin/plugin.json,
  plugin/.codex-plugin/plugin.json, src/version.ts, src/types.ts,
  src/functions/export-import.ts, test/export-import.test.ts,
  CHANGELOG.md
rohitg00 added a commit that referenced this pull request May 15, 2026
* docs(website): refresh agent-memory.dev for v0.9.15+ DevEx surface

Drift accumulated across the website from v0.9.0 through v0.9.15.
Each section caught up:

CommandCenter:
- "iii CONSOLE · OPTIONAL" → "iii CONSOLE · FIRST-CLASS". User
  pushback: the console gives engine-level visibility (workers,
  functions, queues, traces) and is now installed inline by the
  agentmemory CLI on first run from v0.9.16. Not optional.
- Bullet "49 HTTP TRIGGERS" → "107 HTTP ENDPOINTS" to match
  generated-meta.json restEndpoints count. Dropped the stale "33
  REGISTERED FUNCTIONS" subhead.
- Section lede now mentions both UIs are first-class + inline-
  installed.

Compare:
- MCP TOOLS our column 44 → 51 (matches generated-meta.json).
- New REST ENDPOINTS row (107) — competitors don't ship a REST
  shape per their docs, so dashes for mem0/letta/cognee.
- New NATIVE PLUGINS row listing the 6 first-party agents +
  Cursor/Gemini CLI.

Agents:
- FEATURED expanded from 4 to 6 (added pi + OpenHuman). Codex CLI
  pitch updated to "6 hooks + MCP · native plugin" reflecting the
  hooks addition in PR #383.
- Section title "FOUR FIRST-PARTY" → "SIX FIRST-PARTY".
- Section lede now mentions `agentmemory connect <agent>`
  (shipped in v0.9.15 PR #402).

Hero:
- "START IN 60 SECONDS" CTA → "START IN 30 SECONDS". Cold install
  + engine spawn measured 8-12s on v0.9.15 with the native binary
  path; 60s was the v0.9.0-era Docker-first claim.

generated-meta.json regenerated by the build (auto-derive rule).
Website build clean.

* chore(website): refresh generated-meta timestamp

* feat(website): AS FEATURED IN bar — AlphaSignal, AAIF, Trendshift

Wedges between Hero and Stats. Three text-cells in a 3-col row (1-col
on mobile), each links to the source article. Matches the existing
brutalist mono aesthetic — no logo files, no marquee animation, no
JS. Border + small ↗ glyph on each card; gold border on hover.

Sources chosen for brand authority + independence:
- AlphaSignal (180K technical subscribers) →
  alphasignalai.substack.com/p/how-agentmemory-works-and-how-to
- Agentic AI Foundation (Linux Foundation backed) → aaif.io
- Trendshift "NEW 2026 · Position #19" → trendshift.io/repositories/25123

Static, server-rendered, no client bundle impact.

* feat(website): real logos in AS FEATURED IN bar

Replaced text-only treatment with actual brand marks:

- AlphaSignal — github.com/Alpha-Signal org avatar (verified)
  https://avatars.githubusercontent.com/u/64016073?s=200&v=4
- Agentic AI Foundation — aaif.io's own favicon PNG (verified by
  fetching their site)
- Trendshift — their official badge endpoint
  trendshift.io/api/badge/repositories/25123 — bakes the repo's live
  star + position count into the image, so the cell tracks the
  Trendshift state automatically

Layout split: AlphaSignal + AAIF render logo-left / text-right with
↗ arrow. Trendshift renders centered with the full badge image (it's
already a wide brand mark with the rank + stars baked in, so making
it text-bound looks cramped).

next.config.ts adds the three new image hosts to remotePatterns
(aaif.io, trendshift.io, raw.githubusercontent.com). Existing
unoptimized={true} per image so we don't proxy through Vercel's
optimizer.

Build clean. No new deps.

* feat(website): use real AAIF wordmark logo + center 3-card grid

User pushed the actual Agentic AI Foundation wordmark — 838x203 PNG
on transparent background, black artwork. Dropped the favicon and
self-hosted the wordmark at /featured/aaif-logo.png so the brand
reads cleanly on the dark cell.

Rendered as a badge-style cell (centered, wide-form) like Trendshift,
with a `filter: invert(1) brightness(1.05)` so the black artwork
inverts to white-on-dark and matches the site palette without
shipping a second asset.

Grid template balanced: 1fr / 1.3fr / 1fr — gives AAIF the extra
horizontal room its wordmark needs while keeping AlphaSignal and
Trendshift consistent on either side. Max width bumped to 1000px.

`badgeImg` got `object-fit: contain` and an explicit `max-height` so
the AAIF + Trendshift badges sit at the same vertical baseline.

* fix(website): coderabbit PR #415 — meta drift + a11y + dead CSS

Five findings, all valid against the branch:

1. CommandCenter line 48 hardcoded "107 HTTP ENDPOINTS" but
   website/lib/generated-meta.json reports restEndpoints: 121.
   Bumped to 121. The meta file is the source of truth (auto-derived
   from src/triggers/api.ts at build via scripts/derive-meta.js).

2. Compare.tsx REST ENDPOINTS row same drift: "107" → "121".

3. Compare.tsx NATIVE PLUGINS row claimed "6" in the label but the
   parenthesized list had 8 names (Cursor + Gemini included). Per
   README: those two are MCP-server tier, not native plugin. List
   trimmed to the actual 6 native-plugin agents:
   Claude/Codex/OpenClaw/Hermes/pi/OpenHuman.

4. FeaturedIn.module.css .cell had :hover only — keyboard users
   tabbing through saw no focus indicator (WCAG 2.4.7). Added
   :focus-visible with gold border + outline.

5. .cellBadge declared `grid-template-columns: none` while using
   display: flex. Dead property removed.
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