Skip to content

Add GitHub Copilot CLI support - #534

Merged
rohitg00 merged 14 commits into
rohitg00:mainfrom
Random-Word:feature/copilot-cli-support
May 28, 2026
Merged

Add GitHub Copilot CLI support#534
rohitg00 merged 14 commits into
rohitg00:mainfrom
Random-Word:feature/copilot-cli-support

Conversation

@Random-Word

@Random-Word Random-Word commented May 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds first-class GitHub Copilot CLI support to agentmemory using the same hybrid approach already used for other coding agents:

  • Full plugin install path via a Copilot CLI plugin manifest at plugin/plugin.json.
  • MCP-only quick setup path via agentmemory connect copilot-cli.
  • First-run onboarding support so Copilot CLI appears in the setup picker and is selected by default when onboarding is launched from Copilot CLI.
  • Hook compatibility so existing agentmemory observation hooks can ingest Copilot CLI payload shapes.
  • MCP transport compatibility so the standalone MCP server works with Copilot CLI's stdio framing.
  • Docs and tests covering install paths, adapter behavior, hook config, hook execution, onboarding defaults, and transport framing.

What changed

Copilot plugin assets

  • Added plugin/plugin.json, the root Copilot CLI plugin manifest.
  • Added plugin/.mcp.copilot.json for Copilot's MCP server config shape.
  • Added plugin/hooks/hooks.copilot.json with Copilot event names and lowercase tool matchers.
  • Reused existing plugin skills and generated hook scripts instead of duplicating agentmemory logic.

agentmemory connect copilot-cli

  • Added src/cli/connect/copilot-cli.ts to merge mcpServers.agentmemory into Copilot CLI's mcp-config.json.
  • Honors COPILOT_HOME; otherwise defaults to ~/.copilot/mcp-config.json.
  • Preserves existing MCP servers and top-level config keys.
  • Keeps the operation idempotent and supports --force and --dry-run.
  • Allows explicit copilot-cli setup on Windows while preserving existing manual-install behavior for other Windows adapters.
  • Uses a Windows-safe cmd.exe /d /s /c npx -y @agentmemory/mcp command block for Copilot MCP config on Windows.

First-run onboarding

  • Added GitHub Copilot CLI to the native agent picker.
  • Detects Copilot CLI via COPILOT_CLI / COPILOT_AGENT_SESSION_ID and default-selects copilot-cli instead of the historical Claude Code default when setup is launched from Copilot.
  • Added regression tests for the picker entry and Copilot-specific default selection.

Hook compatibility

  • Normalized Copilot camelCase payload fields alongside existing Claude/Codex snake_case fields, including:
    • sessionId
    • toolName
    • toolArgs
    • toolResult
    • userPrompt
    • errorMessage
    • notificationType
  • Updated source hooks and regenerated plugin/scripts/*.mjs bundles so plugin runtime scripts match the TypeScript sources.
  • Kept pre-tool context injection opt-in behavior unchanged.

MCP transport compatibility

  • Updated the standalone MCP stdio transport to accept both:
    • standard Content-Length framed JSON-RPC messages used by Copilot CLI, and
    • the existing newline-delimited JSON messages used by current tests/clients.
  • Frames responses with Content-Length after receiving framed input, while preserving newline responses for newline clients.
  • Added transport tests for split framed messages, newline messages, and framed response formatting.

Documentation and maintenance rules

  • Added GitHub Copilot CLI to README supported agents and setup docs.
  • Documented both MCP-only and full plugin install options.
  • Updated AGENTS.md consistency rules so future tool-count or version changes include the Copilot plugin manifest/config where relevant.

Testing

Validated locally:

  • npm test -- test/copilot-plugin.test.ts test/cli-connect.test.ts
  • npm test -- test/onboarding.test.ts test/cli-connect.test.ts test/copilot-plugin.test.ts
  • npm test -- test/mcp-transport.test.ts test/mcp-standalone-proxy.test.ts test/onboarding.test.ts test/cli-connect.test.ts test/copilot-plugin.test.ts
  • npx tsdown
  • Direct local Copilot CLI plugin/MCP smoke test: after adding framed stdio support, Copilot CLI successfully loaded the agentmemory MCP server and exposed its tools.

Validated in GitHub Actions on the fork:

Notes:

  • This PR does not add or remove MCP tools.
  • This PR does not add or remove REST endpoints.
  • This PR does not bump the package version.
  • Vercel remains blocked by deployment authorization on the upstream repo; CodeRabbit has completed successfully.

Review process

This was implemented in parallel worktrees and merged back into feature/copilot-cli-support:

  • Copilot plugin assets workstream.
  • Copilot connect/docs/tests workstream.

The branch was reviewed with two frontier-model passes:

  • GPT-5.5
  • Claude Opus 4.7

Validated findings were addressed before the upstream PR was opened. Additional issues discovered during local Copilot CLI testing were fixed and pushed as follow-up commits:

  • First-run onboarding defaulted to Claude Code even inside Copilot CLI.
  • Copilot CLI MCP startup timed out because agentmemory's standalone transport only accepted newline-delimited JSON instead of Content-Length framed JSON-RPC.

Random-Word and others added 6 commits May 18, 2026 19:45
- plugin/.plugin/plugin.json: Copilot manifest with name/version/skills/mcpServers/hooks refs
- plugin/.mcp.copilot.json: MCP server config with type:local, npx, env passthrough, tools:[*]
- plugin/hooks/hooks.copilot.json: Copilot hooks (version:1) with 11 supported events and PreToolUse matcher
- test/copilot-plugin.test.ts: 11 tests covering manifest, MCP config, and hooks validation

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds Copilot CLI support through a root plugin manifest, Copilot-specific MCP and hook configuration, and a connect adapter for MCP-only setup.

Includes Windows-safe Copilot MCP command generation, COPILOT_HOME handling, Copilot hook payload normalization, generated hook scripts, and targeted tests for plugin shape, hook execution, and connect behavior.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@vercel

vercel Bot commented May 19, 2026

Copy link
Copy Markdown

Someone 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 May 19, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds GitHub Copilot CLI support: new Copilot plugin manifests (MCP + hooks), normalizes hook inputs (snake_case/camelCase) across scripts and TS hooks, implements a copilot-cli connect adapter with platform-aware MCP wiring, replaces MCP stdio transport with framing-aware parser, and expands documentation and tests for Copilot integration.

Changes

Copilot CLI Integration

Layer / File(s) Summary
Copilot plugin manifest and hooks configuration
plugin/.mcp.copilot.json, plugin/hooks/hooks.copilot.json, plugin/plugin.json, AGENTS.md, README.md
Adds a Copilot .mcp.copilot.json MCP block, hooks.copilot.json lifecycle mappings to scripts/*.mjs, and updates plugin/plugin.json version to 0.9.20. AGENTS.md and README updated with Copilot checklist and setup docs.
Hook scripts and TS hooks normalization
plugin/scripts/*.mjs, src/hooks/*.ts
All hook implementations now accept snake_case and camelCase input fields for session/tool/agent/error identifiers, normalize values before sending upstream, add toolOutput() and truncation handling where applicable, and adjust matching logic for pre-tool-use (grep/glob).
CLI adapter and Copilot home integration
src/cli/connect/copilot-cli.ts, src/cli/connect/index.ts, src/cli/connect/util.ts, src/cli.ts, test/cli-connect.test.ts
New copilot-cli adapter that detects Copilot home, merges/writes mcp-config.json with an AGENTMEMORY_COPILOT_MCP_BLOCK (Windows-aware command), supports dry-run/force/backups, and registers the adapter in the CLI dispatcher with adjusted Windows gating. Tests added/updated for adapter behavior.
Onboarding, docs and plugin tests
README.md, AGENTS.md, src/cli/onboarding.ts, test/copilot-plugin.test.ts, test/onboarding.test.ts
README documents MCP-only vs full-plugin Copilot setup, adds Copilot to agent tables and quick-starts. Onboarding exports buildAgentOptions() and getInitialAgentValues() with tests. Test suite validates plugin.json, .mcp.copilot.json, hooks.copilot.json structure, referenced scripts exist, and runs integration checks for several hook scripts against a local HTTP capture server.
MCP stdio transport rewrite and tests
src/mcp/transport.ts, test/mcp-transport.test.ts
Replaces readline line-based stdin parsing with a framing-aware buffer parser supporting Content-Length framing and newline-delimited messages; adds parser interface, response formatter (Content-Length framing), in-order request queueing, and tests for framed/unframed parsing and response formatting.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • rohitg00/agentmemory#402: Introduces the CLI connect adapter framework that this PR extends with the new copilot-cli adapter.
  • rohitg00/agentmemory#311: Updates to plugin hook scripts that interact with the same handler scripts modified here.
  • rohitg00/agentmemory#7: Related pre-tool-use hook logic changes overlapping with grep/glob enrichment parsing.

Poem

🐰 npx in paw, I stitched configs tight,
Camel and snake hold hands in the night,
Hooks now agree which names to send,
Copilot and memory walk side-by-side, friend,
A small hop — integration done right.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.27% 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
Title check ✅ Passed The pull request title 'Add GitHub Copilot CLI support' accurately and concisely summarizes the main objective of this changeset, which is to introduce first-class GitHub Copilot CLI integration to the agentmemory project.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

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

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

🧹 Nitpick comments (2)
plugin/scripts/subagent-start.mjs (1)

26-28: ⚡ Quick win

Mixed fallback operators within the same extraction block.

Line 26 uses || for sessionId, while lines 27-28 use ?? for agent fields. This inconsistency means:

  • Empty string sessionId would fall back to "unknown"
  • Empty string agentId or agentType would be preserved

For predictable behavior, use the same operator consistently. Since ?? better represents "use if provided" semantics for optional fields, consider applying it to all three lines.

♻️ Suggested fix
-const sessionId = data.session_id || data.sessionId || "unknown";
-const agentId = data.agent_id ?? data.agentName;
-const agentType = data.agent_type ?? data.agentDisplayName ?? data.agentName;
+const sessionId = data.session_id ?? data.sessionId ?? "unknown";
+const agentId = data.agent_id ?? data.agentName;
+const agentType = data.agent_type ?? data.agentDisplayName ?? data.agentName;
🤖 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 `@plugin/scripts/subagent-start.mjs` around lines 26 - 28, The extraction uses
inconsistent fallback operators: sessionId uses || while agentId and agentType
use ??, causing empty strings to behave differently; update the sessionId
assignment (symbol: sessionId) to use the nullish coalescing operator like
agentId and agentType (symbols: agentId, agentType) — e.g., replace the ||
fallback with ?? so sessionId = data.session_id ?? data.sessionId ?? "unknown"
to ensure consistent "use if provided" semantics across all three fields.
plugin/scripts/prompt-submit.mjs (1)

25-25: ⚡ Quick win

Inconsistent fallback operators: || vs ??.

Line 25 uses || for sessionId fallback, while line 36 uses ?? for prompt fallback. This creates different behavior:

  • || treats empty strings as falsy and falls back
  • ?? only falls back on null/undefined, preserving empty strings

For consistent behavior across all normalized fields, use the same operator. Consider ?? throughout, as it better expresses "use this field if provided, otherwise try the alternative."

♻️ Suggested fix for consistency
-const sessionId = data.session_id || data.sessionId || "unknown";
+const sessionId = data.session_id ?? data.sessionId ?? "unknown";

Also applies to: 36-36

🤖 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 `@plugin/scripts/prompt-submit.mjs` at line 25, The fallback for sessionId uses
the || operator which treats empty strings as falsy while prompt uses ??; change
the sessionId normalization to use nullish coalescing (replace the || chain with
??) so it matches the prompt behavior (i.e., const sessionId = data.session_id
?? data.sessionId ?? "unknown") and scan other normalized fields in this module
to ensure all use ?? for consistent null/undefined-only fallbacks.
🤖 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 `@plugin/hooks/hooks.copilot.json`:
- Around line 16-21: preToolUse matcher is missing "write" and "read" so
pre-tool-use.mjs won't run for those actions; update the "preToolUse" entry's
matcher string (the one currently set to "edit|create|view|glob|grep") to
include "write" and "read" (e.g., "edit|create|view|glob|grep|write|read") so it
matches the allowlist used by pre-tool-use.mjs and ensures context injection for
the write/read tool calls.

In `@src/hooks/notification.ts`:
- Around line 32-35: The code incorrectly casts session values with "as string"
and mixes || with ??; update the sessionId logic to use the same nullish
coalescing pattern as notificationType and explicitly coerce the result to a
string (e.g., use data.session_id ?? data.sessionId ?? "unknown" and then wrap
with String(...) or template interpolation) so sessionId is always a string;
reference the notificationType variable and the sessionId assignment and the
data.session_id/data.sessionId fields when making the change.

In `@src/hooks/pre-tool-use.ts`:
- Around line 53-63: The code assumes data.tool_name/data.toolName is a string
and calls toLowerCase on it and similarly assumes data.tool_input/toolArgs is an
object; add runtime narrowing: for toolName, check typeof data.tool_name ===
"string" or typeof data.toolName === "string" before assigning and calling
toLowerCase (otherwise bail/return), and for toolInput ensure it's an object
(e.g., typeof === "object" && data.tool_input !== null) or default to an empty
Record<string, unknown>; update usages of toolName, normalizedToolName, and
toolInput to rely on these checks so toLowerCase and object operations are safe.

In `@src/hooks/subagent-start.ts`:
- Around line 41-43: The fallback logic is inconsistent: sessionId uses ||
(which treats empty string as falsy) while agentId and agentType use ?? (which
does not treat empty strings as nullish), so empty values like "" won't fall
back to agentName/agentDisplayName; update the assignments for agentId and
agentType in src/hooks/subagent-start.ts to use the same logical OR fallback as
sessionId (replace ?? with ||) so empty strings correctly fall back to the
alternative fields (refer to the variables agentId and agentType).

In `@src/hooks/subagent-stop.ts`:
- Around line 33-35: The fallbacks for sessionId, agentId, and agentType are
inconsistent: sessionId uses || (treats empty string as missing) while agentId
and agentType use ?? (does not treat empty string as missing). Update agentId
and agentType to use the same falsy fallback as sessionId by replacing the
nullish coalescing (??) with logical OR (||) so empty strings fall back to the
alternate fields/values; refer to the variables sessionId, agentId, and
agentType in src/hooks/subagent-stop.ts when making the change.

In `@test/copilot-plugin.test.ts`:
- Around line 171-182: The test allows empty or null command fields because it
only filters out undefined; update the validation in the test that iterates over
loadHooks() / config.hooks so the commandFields array only counts true non-empty
strings: change the filter on [handler.command, handler.bash,
handler.powershell] to accept values where typeof value === "string" and
value.trim() !== "" (reject null, empty, or whitespace-only), then assert
commandFields.length === 1 while leaving the handler.type check unchanged.

---

Nitpick comments:
In `@plugin/scripts/prompt-submit.mjs`:
- Line 25: The fallback for sessionId uses the || operator which treats empty
strings as falsy while prompt uses ??; change the sessionId normalization to use
nullish coalescing (replace the || chain with ??) so it matches the prompt
behavior (i.e., const sessionId = data.session_id ?? data.sessionId ??
"unknown") and scan other normalized fields in this module to ensure all use ??
for consistent null/undefined-only fallbacks.

In `@plugin/scripts/subagent-start.mjs`:
- Around line 26-28: The extraction uses inconsistent fallback operators:
sessionId uses || while agentId and agentType use ??, causing empty strings to
behave differently; update the sessionId assignment (symbol: sessionId) to use
the nullish coalescing operator like agentId and agentType (symbols: agentId,
agentType) — e.g., replace the || fallback with ?? so sessionId =
data.session_id ?? data.sessionId ?? "unknown" to ensure consistent "use if
provided" semantics across all three fields.
🪄 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: 2c0bfbec-f4cc-4ccb-8904-bd231877af9c

📥 Commits

Reviewing files that changed from the base of the PR and between 68fddd4 and 4fd994c.

📒 Files selected for processing (33)
  • AGENTS.md
  • README.md
  • plugin/.mcp.copilot.json
  • plugin/hooks/hooks.copilot.json
  • plugin/plugin.json
  • plugin/scripts/notification.mjs
  • plugin/scripts/post-tool-failure.mjs
  • plugin/scripts/post-tool-use.mjs
  • plugin/scripts/pre-compact.mjs
  • plugin/scripts/pre-tool-use.mjs
  • plugin/scripts/prompt-submit.mjs
  • plugin/scripts/session-end.mjs
  • plugin/scripts/session-start.mjs
  • plugin/scripts/stop.mjs
  • plugin/scripts/subagent-start.mjs
  • plugin/scripts/subagent-stop.mjs
  • src/cli.ts
  • src/cli/connect/copilot-cli.ts
  • src/cli/connect/index.ts
  • src/cli/connect/util.ts
  • src/hooks/notification.ts
  • src/hooks/post-tool-failure.ts
  • src/hooks/post-tool-use.ts
  • src/hooks/pre-compact.ts
  • src/hooks/pre-tool-use.ts
  • src/hooks/prompt-submit.ts
  • src/hooks/session-end.ts
  • src/hooks/session-start.ts
  • src/hooks/stop.ts
  • src/hooks/subagent-start.ts
  • src/hooks/subagent-stop.ts
  • test/cli-connect.test.ts
  • test/copilot-plugin.test.ts

Comment thread plugin/hooks/hooks.copilot.json
Comment thread src/hooks/notification.ts Outdated
Comment thread src/hooks/pre-tool-use.ts Outdated
Comment thread src/hooks/subagent-start.ts Outdated
Comment thread src/hooks/subagent-stop.ts Outdated
Comment thread test/copilot-plugin.test.ts
Addresses upstream AI review suggestions by aligning the Copilot preToolUse matcher with the hook allowlist, narrowing hook payload fields at runtime, normalizing subagent fallbacks, and tightening hook config validation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Random-Word

Copy link
Copy Markdown
Contributor Author

Implemented the small CodeRabbit hardening suggestions in 46b0e86: expanded the Copilot preToolUse matcher to match the hook allowlist, added runtime narrowing for hook payload fields, normalized subagent fallbacks, tightened hook config validation, regenerated plugin scripts, and reran the focused Copilot tests.

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

🤖 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/hooks/pre-tool-use.ts`:
- Line 91: The sessionId assignment currently casts then falls back which can
let non-string truthy values through; update the runtime narrowing in
src/hooks/pre-tool-use.ts to mirror the pattern used for toolName: check typeof
data.session_id === "string" or typeof data.sessionId === "string" and use that
string, otherwise default to "unknown" so only actual strings are sent in the
request; adjust the variable named sessionId accordingly.
🪄 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: e21b0704-7a4c-4e5e-b590-4cbd4deb570d

📥 Commits

Reviewing files that changed from the base of the PR and between 4fd994c and 46b0e86.

📒 Files selected for processing (10)
  • plugin/hooks/hooks.copilot.json
  • plugin/scripts/notification.mjs
  • plugin/scripts/pre-tool-use.mjs
  • plugin/scripts/subagent-start.mjs
  • plugin/scripts/subagent-stop.mjs
  • src/hooks/notification.ts
  • src/hooks/pre-tool-use.ts
  • src/hooks/subagent-start.ts
  • src/hooks/subagent-stop.ts
  • test/copilot-plugin.test.ts
🚧 Files skipped from review as they are similar to previous changes (9)
  • plugin/hooks/hooks.copilot.json
  • src/hooks/notification.ts
  • plugin/scripts/notification.mjs
  • plugin/scripts/subagent-start.mjs
  • plugin/scripts/pre-tool-use.mjs
  • plugin/scripts/subagent-stop.mjs
  • src/hooks/subagent-start.ts
  • src/hooks/subagent-stop.ts
  • test/copilot-plugin.test.ts

Comment thread src/hooks/pre-tool-use.ts Outdated
@Random-Word

Copy link
Copy Markdown
Contributor Author

Note on CodeRabbit's "Docstring Coverage" warning: this repository does not currently enforce docstring/JSDoc coverage in CI, and this PR follows the existing TypeScript style of using descriptive names plus sparse comments for non-obvious behavior. Adding broad docstrings to satisfy a generic 80% threshold would be unrelated churn for this Copilot CLI integration. The actionable review comments were addressed in 46b0e86.

Includes GitHub Copilot CLI in the first-run agent picker and adds a regression test so the Copilot setup path remains discoverable.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Random-Word

Copy link
Copy Markdown
Contributor Author

Fixed the first-run onboarding gap: GitHub Copilot CLI is now included in the agent picker, with a regression test covering the native setup options. Commit: Random-Word/agentmemory@71f4c6b

Detect Copilot CLI environment markers during first-run setup so pressing Enter wires the current agent instead of the historical Claude Code default.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Random-Word

Copy link
Copy Markdown
Contributor Author

Follow-up fix: first-run onboarding now detects Copilot CLI via COPILOT_CLI / COPILOT_AGENT_SESSION_ID and default-selects GitHub Copilot CLI instead of Claude Code when setup is launched from Copilot. Commit: Random-Word/agentmemory@11a0200

Accept Content-Length framed JSON-RPC messages in addition to the existing newline-delimited transport so Copilot CLI can initialize the standalone MCP server.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Random-Word

Copy link
Copy Markdown
Contributor Author

Fixed the Copilot CLI MCP timeout found during local plugin testing. Root cause: Copilot CLI initializes stdio MCP servers with Content-Length framed JSON-RPC, while agentmemory's standalone transport only accepted newline-delimited JSON. The transport now supports both framed and newline-delimited messages, with regression tests and a local framed MCP smoke test. Commit: Random-Word/agentmemory@c21bb06

@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.

🧹 Nitpick comments (1)
src/mcp/transport.ts (1)

246-255: ⚡ Quick win

Queue error handling could stall on unexpected rejection.

If processLine or writeResponse throws unexpectedly, queue becomes a rejected promise. Subsequent .then() calls chain off the rejected promise, skipping handlers and causing all future messages to be dropped.

Inline the catch so the queue recovers:

♻️ Proposed fix
       parser = createMessageParser((message) => {
-        queue = queue.then(() => processLine(message, handler, writeResponse));
-        void queue.catch((err) => {
+        queue = queue.then(() => processLine(message, handler, writeResponse)).catch((err) => {
           process.stderr.write(
             `[mcp-transport] request processing failed: ${
               err instanceof Error ? err.message : String(err)
             }\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/mcp/transport.ts` around lines 246 - 255, The current chaining of queue =
queue.then(() => processLine(message, handler, writeResponse)); with a separate
void queue.catch(...) lets queue become permanently rejected and skip future
handlers; instead, ensure each appended task handles its own errors so the
shared queue always resolves. Replace the two-step pattern by assigning queue =
queue.then(() => processLine(message, handler, writeResponse)).catch(err => {
process.stderr.write(`[mcp-transport] request processing failed: ${err
instanceof Error ? err.message : String(err)}\n`); }); so any rejection from
processLine or writeResponse is caught immediately and the queue is recovered
for subsequent messages (refer to parser/createMessageParser, processLine,
writeResponse, and the queue variable).
🤖 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.

Nitpick comments:
In `@src/mcp/transport.ts`:
- Around line 246-255: The current chaining of queue = queue.then(() =>
processLine(message, handler, writeResponse)); with a separate void
queue.catch(...) lets queue become permanently rejected and skip future
handlers; instead, ensure each appended task handles its own errors so the
shared queue always resolves. Replace the two-step pattern by assigning queue =
queue.then(() => processLine(message, handler, writeResponse)).catch(err => {
process.stderr.write(`[mcp-transport] request processing failed: ${err
instanceof Error ? err.message : String(err)}\n`); }); so any rejection from
processLine or writeResponse is caught immediately and the queue is recovered
for subsequent messages (refer to parser/createMessageParser, processLine,
writeResponse, and the queue variable).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 15390489-fd19-4c73-9f5f-6c9ebff01796

📥 Commits

Reviewing files that changed from the base of the PR and between 11a0200 and c21bb06.

📒 Files selected for processing (2)
  • src/mcp/transport.ts
  • test/mcp-transport.test.ts

Random-Word and others added 3 commits May 20, 2026 13:28
Ensures pre-tool-use only forwards string session IDs and falls back to unknown for invalid Copilot payload values, with regression coverage for the generated plugin script.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Resolves conflicts with current main, keeps Copilot CLI support intact, and preserves the Codex hook idempotency fix from main.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keeps upstream install guidance and retains Copilot CLI in the supported agent list.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@nvtphong200401

Copy link
Copy Markdown

I am using github copilot CLI, look forward to seeing this feature.

@yathu-arulnanthy-gtg

Copy link
Copy Markdown

Looking forward for this to be merged as well

@rohitg00 rohitg00 closed this May 27, 2026
@rohitg00

Copy link
Copy Markdown
Owner

Thanks @Random-Word — VS Code Copilot uses the standard MCP config block; the connect-table docs in README cover the path.

@Random-Word

Copy link
Copy Markdown
Contributor Author

@rohitg00 I'm confused - are you deprecating the hooks + plugin approach for Claude Code, Codex, etc? Are you planning to migrate them to MCP only? The hooks + plugin design seems cleaner than MCP to me.

@rohitg00 rohitg00 reopened this May 28, 2026
@rohitg00

Copy link
Copy Markdown
Owner

@Random-Word — reopening, you were right.

My close message was based on a wrong premise (VS Code Copilot ≠ Copilot CLI — those are separate products). Re-audited this PR top to bottom and the hooks + plugin path you took is the architecturally correct one. We're keeping hooks + plugin as the primary integration story across all agents; MCP-only is the fallback for clients that can't load plugins.

What I liked on the re-read:

  • Plugin manifest + hooks.copilot.json shape mirror the existing plugin/.claude-plugin/plugin.json setup cleanly.
  • src/cli/connect/copilot-cli.ts follows the existing adapter contract (idempotent, atomic write, post-write verification, backup, --dry-run, --force).
  • Hook payload normalization is purely additive — camelCase fallbacks alongside existing snake_case reads, defensive type narrowing where it didn't exist before.
  • Standalone MCP Content-Length framing in src/mcp/transport.ts is real work (LSP-style framing parser + sequential queue) and needed by Copilot CLI's stdio init handshake.
  • COPILOT_CLI / COPILOT_AGENT_SESSION_ID env detection so first-run picks the right default in a Copilot session.
  • Windows cmd.exe /d /s /c npx wrapper matches our existing Windows-path-quoting lesson (fix(hooks): quote plugin script paths #487).
  • 377-line test/copilot-plugin.test.ts + transport tests + onboarding tests — coverage is solid.

Two small bugs and one rebase before this can land:

  1. AGENTMEMORY_COPILOT_MCP_BLOCK is missing the ${VAR:-default} fallback (src/cli/connect/util.ts:29-46). Per Bug: MCP tools not loaded by Claude Code despite healthy server and working plugin #510, bare ${AGENTMEMORY_URL} / ${AGENTMEMORY_SECRET} causes a parse-strict client to silently drop the server when the user hasn't exported those envs. Match the existing AGENTMEMORY_MCP_BLOCK shape:

    env: {
      AGENTMEMORY_URL: "${AGENTMEMORY_URL:-http://localhost:3111}",
      AGENTMEMORY_SECRET: "${AGENTMEMORY_SECRET:-}",
      AGENTMEMORY_TOOLS: "${AGENTMEMORY_TOOLS:-all}",
    }

    Same fix needed in plugin/.mcp.copilot.json.

  2. plugin/plugin.json metadata is stale"version": "0.9.21" should be "0.9.22" and the description says "4 skills" but the canonical plugin/.claude-plugin/plugin.json is at "8 skills". The AGENTS.md consistency rules already require version + skill counts to stay in sync — add the new plugin/plugin.json to that list.

  3. 20-file rebase against current main. Since this PR was opened we landed:

    Your camelCase normalization should compose cleanly on top — for each hook, the order is: read camelCase-or-snake_case → resolveProject(data.cwd ...) → unawaited fetch + setTimeout. Happy to push the rebase to your branch if you'd rather I take it.

Take whichever path is easier for you — rebase + 2 fixes yourself, or pass it back to me and I'll do the rebase + push to a maintainer branch with your commits preserved for attribution.

…view fixes

Merge resolution:
- 9 hook source files: composed PR's camelCase payload normalization
  on top of main's resolveProject() + fire-and-forget pattern.
- pre-tool-use: kept both PR's defensive sessionId narrowing and
  main's explicit project handling (data.project, never cwd-as-project).
- src/cli/connect/index.ts: copilotCli alongside cline / continue / zed /
  droid / warp adapters added on main (ADAPTERS now 17 entries).
- test/cli-connect.test.ts: expect 17 adapters, dropped duplicate spec.
- plugin/scripts/*.mjs regenerated via npm run build (no hand-edits).

Review fixes (per rohitg00#534 audit):
- AGENTMEMORY_COPILOT_MCP_BLOCK (src/cli/connect/util.ts) +
  plugin/.mcp.copilot.json: switched env values to ${VAR:-default}
  shape so parse-strict clients don't drop the server when the user
  has no shell export (rohitg00#510 lesson). AGENTMEMORY_TOOLS:all also added.
- plugin/plugin.json: version 0.9.21 -> 0.9.22, skill count 4 -> 8 to
  match plugin/.claude-plugin/plugin.json source of truth.
- Tests updated to assert the new env shape.
@rohitg00

Copy link
Copy Markdown
Owner

Pushed the rebase + 2 review fixes to feature/copilot-cli-support as dc1cd86 (took advantage of "allow edits by maintainers"). Your commits are preserved.

What landed in the merge commit:

  • 9 hook source files composed cleanly — your camelCase normalization wraps resolveProject() + the fire-and-forget pattern from fix(hooks): send repo basename as project, not full path (#474) #687/perf(hooks): fire-and-forget telemetry hooks (#573) #688. For each telemetry hook the shape is now:
    const sessionId = ((data.session_id || data.sessionId) as string) || "unknown";
    // …camelCase-aware reads…
    fetch(URL, {
      body: JSON.stringify({
        project: resolveProject(data.cwd as string | undefined),
        cwd: (data.cwd as string | undefined) || process.cwd(),
        data: { /* normalized fields */ },
      }),
      signal: AbortSignal.timeout(N),
    }).catch(() => {});
    setTimeout(() => process.exit(0), 500).unref();
  • pre-tool-use.ts kept both your defensive sessionId narrowing and main's data.project-only handling (the comment block on never-cwd-as-project is the load-bearing reason).
  • src/cli/connect/index.tscopilotCli joins cline, continue, zed, droid, warp (added on main since this PR opened). ADAPTERS array is now 17 entries; test updated.
  • plugin/scripts/*.mjs regenerated via npm run build (no hand-edits).

Review fixes:

  1. ${VAR:-default} env shapesrc/cli/connect/util.ts + plugin/.mcp.copilot.json now use ${AGENTMEMORY_URL:-http://localhost:3111} / ${AGENTMEMORY_SECRET:-} / ${AGENTMEMORY_TOOLS:-all} so parse-strict clients don't silently drop the server when the user has no shell export. Tests updated to match.
  2. plugin/plugin.json — version 0.9.210.9.22, description "4 skills""8 skills" to match the canonical plugin/.claude-plugin/plugin.json.

Status: PR is now MERGEABLE. CI is running (UNSTABLE until checks finish). I'll wait for green CI + your sign-off before merging — let me know if you want any of the merge resolutions reworked.

Thanks for pushing back yesterday; the close was wrong and the hooks + plugin path you built is exactly the architecture we want.

@rohitg00
rohitg00 merged commit a0da02b into rohitg00:main May 28, 2026
1 of 2 checks passed
@rohitg00 rohitg00 mentioned this pull request May 28, 2026
5 tasks
rohitg00 added a commit that referenced this pull request May 28, 2026
Bumps version across 9 files + adds CHANGELOG entry summarizing the
18 commits since v0.9.22.

Highlights:
- GitHub Copilot CLI first-class support (#534) — plugin + hooks +
  MCP with LSP-style Content-Length framing on the standalone stdio
  transport.
- Five new MCP adapters: Warp, Cline, Continue, Zed, Droid (#677);
  ADAPTERS count 11 → 17.
- Three silent DX bugs fixed: graph extraction never fired on
  session end (#666 / #698), status reported zero memories (#666),
  consolidation defaulted off even with an LLM provider configured
  (#612 / #696).
- Nine telemetry hooks switched to fire-and-forget so they don't
  block Claude Code's next-prompt boundary (#573 / #688).
- Hook project field now sends repo basename instead of full
  filesystem path so auto-injected context isn't silently filtered
  out (#474 / #687).
- Local-LLM docs: Ollama / LM Studio / vLLM section added (#671 /
  #697).

Version-bump files: package.json, plugin/.claude-plugin/plugin.json,
plugin/plugin.json, plugin/.codex-plugin/plugin.json,
packages/mcp/package.json, src/version.ts, src/types.ts,
src/functions/export-import.ts, test/export-import.test.ts.
rohitg00 added a commit that referenced this pull request May 28, 2026
* chore(release): v0.9.23

Bumps version across 9 files + adds CHANGELOG entry summarizing the
18 commits since v0.9.22.

Highlights:
- GitHub Copilot CLI first-class support (#534) — plugin + hooks +
  MCP with LSP-style Content-Length framing on the standalone stdio
  transport.
- Five new MCP adapters: Warp, Cline, Continue, Zed, Droid (#677);
  ADAPTERS count 11 → 17.
- Three silent DX bugs fixed: graph extraction never fired on
  session end (#666 / #698), status reported zero memories (#666),
  consolidation defaulted off even with an LLM provider configured
  (#612 / #696).
- Nine telemetry hooks switched to fire-and-forget so they don't
  block Claude Code's next-prompt boundary (#573 / #688).
- Hook project field now sends repo basename instead of full
  filesystem path so auto-injected context isn't silently filtered
  out (#474 / #687).
- Local-LLM docs: Ollama / LM Studio / vLLM section added (#671 /
  #697).

Version-bump files: package.json, plugin/.claude-plugin/plugin.json,
plugin/plugin.json, plugin/.codex-plugin/plugin.json,
packages/mcp/package.json, src/version.ts, src/types.ts,
src/functions/export-import.ts, test/export-import.test.ts.

* chore(release): add #701 + #709 to v0.9.23 CHANGELOG
rohitg00 added a commit that referenced this pull request May 29, 2026
* chore(website): refresh agents grid + logos for v0.9.23

Agents section was stale relative to the supported agent matrix that
v0.9.23 ships:

- FEATURED cards bumped from 6 to 7 — adds Copilot CLI (full plugin
  + hooks + MCP from PR #534). Title updates from "SIX FIRST-PARTY"
  to "SEVEN NATIVE PLUGINS".
- MARQUEE tiles expanded from 10 to 17 — adds Warp, Continue, Zed,
  Droid (the 4 covered by `npx skills add` from PR #677) plus Qwen
  Code, Antigravity, and Kiro (the 3 from PR #648).
- Logos switched from `github.com/<org>.png` avatars and stale
  third-party CDNs (freelogovectors.net, exafunction.github.io) to
  svgl.app brand SVGs where available (Anthropic, GitHub, OpenAI,
  Cursor, Warp, Continue, Zed, Gemini, Google, Qwen, Windsurf) or
  the agent's own website favicon where svgl doesn't carry the
  brand (Factory.ai, Kiro, OpenCode, Cline, Roo, Kilo, Goose,
  Aider, OpenClaw, Nous Research). Cursor and Windsurf logo paths
  were specifically broken; the freelogovectors URL was unreliable
  and Codeium → Cognition acquisition stale-dated the Windsurf path.

AgentInstall chip row adds Copilot CLI + Warp alongside the
existing Cursor / VS Code / Claude Code / Claude Desktop / Gemini /
Codex shortcuts. Universal MCP JSON hint and "show more" button
both updated to list the agents we actually support now.

* fix(website): use correct svgl.app slugs + add hostnames to remotePatterns

Previous commit's logo URLs all 404'd:
- svgl.app slugs were wrong (e.g. anthropic.svg vs anthropic_white.svg,
  cursor.svg vs cursor_dark.svg). svgl exposes themed variants
  (`_light`/`_dark`/`_white`/`_black`) but bare `<slug>.svg` only
  exists for a few entries. Verified actual URLs via api.svgl.app for
  every featured + marquee tile.
- Next.js Image `remotePatterns` didn't whitelist svgl.app or the
  agent-domain favicon hosts (factory.ai, kiro.dev, opencode.ai,
  cline.bot, etc.), so even valid URLs were rejected before fetch.

Now uses dark-bg-appropriate variants throughout (white/dark logos on
the black page background). For the few brands not in svgl
(continue, kiro, opencode, cline, roo, goose, aider, openclaw,
hermes, droid), falls back to the agent's own website favicon —
each URL HEAD-probed for 200.

Dropped stale remotePatterns: exafunction.github.io,
www.freelogovectors.net, block.github.io (replaced with goose.dev).
Added: continue.dev, goose.dev.

* revert(website): restore github.com avatars for existing agents

Only new logos (copilot-cli, warp, continue, zed, droid, antigravity,
qwen, kiro) and previously-broken ones (cursor, windsurf) use svgl /
own-site URLs. Original github.com/<org>.png avatars for claude-code,
codex, openclaw, hermes, claude-desktop, gemini, opencode, cline, roo,
kilo, goose, aider restored — they were never broken.

next.config remotePatterns trimmed to: svgl.app, www.factory.ai,
kiro.dev, continue.dev (the only non-github hosts still in use).

* fix(assets): pi logo fill white for dark website bg

User-provided SVG uses #09090b near-black; invisible on the agents
grid's dark background. Same path, fill swapped to #ffffff.
healdigital pushed a commit to healdigital/agentmemory that referenced this pull request Jul 27, 2026
* feat: add Copilot CLI plugin asset slice

- plugin/.plugin/plugin.json: Copilot manifest with name/version/skills/mcpServers/hooks refs
- plugin/.mcp.copilot.json: MCP server config with type:local, npx, env passthrough, tools:[*]
- plugin/hooks/hooks.copilot.json: Copilot hooks (version:1) with 11 supported events and PreToolUse matcher
- test/copilot-plugin.test.ts: 11 tests covering manifest, MCP config, and hooks validation

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add Copilot CLI connect support

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add GitHub Copilot CLI support

Adds Copilot CLI support through a root plugin manifest, Copilot-specific MCP and hook configuration, and a connect adapter for MCP-only setup.

Includes Windows-safe Copilot MCP command generation, COPILOT_HOME handling, Copilot hook payload normalization, generated hook scripts, and targeted tests for plugin shape, hook execution, and connect behavior.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Harden Copilot hook handling

Addresses upstream AI review suggestions by aligning the Copilot preToolUse matcher with the hook allowlist, narrowing hook payload fields at runtime, normalizing subagent fallbacks, and tightening hook config validation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add Copilot to first-run onboarding

Includes GitHub Copilot CLI in the first-run agent picker and adds a regression test so the Copilot setup path remains discoverable.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Default onboarding to Copilot inside Copilot CLI

Detect Copilot CLI environment markers during first-run setup so pressing Enter wires the current agent instead of the historical Claude Code default.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Support framed stdio MCP transport

Accept Content-Length framed JSON-RPC messages in addition to the existing newline-delimited transport so Copilot CLI can initialize the standalone MCP server.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Narrow Copilot pre-tool session ids

Ensures pre-tool-use only forwards string session IDs and falls back to unknown for invalid Copilot payload values, with regression coverage for the generated plugin script.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Ross Story <rostory@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Rohit Ghumare <ghumare64@gmail.com>
healdigital pushed a commit to healdigital/agentmemory that referenced this pull request Jul 27, 2026
* chore(release): v0.9.23

Bumps version across 9 files + adds CHANGELOG entry summarizing the
18 commits since v0.9.22.

Highlights:
- GitHub Copilot CLI first-class support (rohitg00#534) — plugin + hooks +
  MCP with LSP-style Content-Length framing on the standalone stdio
  transport.
- Five new MCP adapters: Warp, Cline, Continue, Zed, Droid (rohitg00#677);
  ADAPTERS count 11 → 17.
- Three silent DX bugs fixed: graph extraction never fired on
  session end (rohitg00#666 / rohitg00#698), status reported zero memories (rohitg00#666),
  consolidation defaulted off even with an LLM provider configured
  (rohitg00#612 / rohitg00#696).
- Nine telemetry hooks switched to fire-and-forget so they don't
  block Claude Code's next-prompt boundary (rohitg00#573 / rohitg00#688).
- Hook project field now sends repo basename instead of full
  filesystem path so auto-injected context isn't silently filtered
  out (rohitg00#474 / rohitg00#687).
- Local-LLM docs: Ollama / LM Studio / vLLM section added (rohitg00#671 /
  rohitg00#697).

Version-bump files: package.json, plugin/.claude-plugin/plugin.json,
plugin/plugin.json, plugin/.codex-plugin/plugin.json,
packages/mcp/package.json, src/version.ts, src/types.ts,
src/functions/export-import.ts, test/export-import.test.ts.

* chore(release): add rohitg00#701 + rohitg00#709 to v0.9.23 CHANGELOG
healdigital pushed a commit to healdigital/agentmemory that referenced this pull request Jul 27, 2026
* chore(website): refresh agents grid + logos for v0.9.23

Agents section was stale relative to the supported agent matrix that
v0.9.23 ships:

- FEATURED cards bumped from 6 to 7 — adds Copilot CLI (full plugin
  + hooks + MCP from PR rohitg00#534). Title updates from "SIX FIRST-PARTY"
  to "SEVEN NATIVE PLUGINS".
- MARQUEE tiles expanded from 10 to 17 — adds Warp, Continue, Zed,
  Droid (the 4 covered by `npx skills add` from PR rohitg00#677) plus Qwen
  Code, Antigravity, and Kiro (the 3 from PR rohitg00#648).
- Logos switched from `github.com/<org>.png` avatars and stale
  third-party CDNs (freelogovectors.net, exafunction.github.io) to
  svgl.app brand SVGs where available (Anthropic, GitHub, OpenAI,
  Cursor, Warp, Continue, Zed, Gemini, Google, Qwen, Windsurf) or
  the agent's own website favicon where svgl doesn't carry the
  brand (Factory.ai, Kiro, OpenCode, Cline, Roo, Kilo, Goose,
  Aider, OpenClaw, Nous Research). Cursor and Windsurf logo paths
  were specifically broken; the freelogovectors URL was unreliable
  and Codeium → Cognition acquisition stale-dated the Windsurf path.

AgentInstall chip row adds Copilot CLI + Warp alongside the
existing Cursor / VS Code / Claude Code / Claude Desktop / Gemini /
Codex shortcuts. Universal MCP JSON hint and "show more" button
both updated to list the agents we actually support now.

* fix(website): use correct svgl.app slugs + add hostnames to remotePatterns

Previous commit's logo URLs all 404'd:
- svgl.app slugs were wrong (e.g. anthropic.svg vs anthropic_white.svg,
  cursor.svg vs cursor_dark.svg). svgl exposes themed variants
  (`_light`/`_dark`/`_white`/`_black`) but bare `<slug>.svg` only
  exists for a few entries. Verified actual URLs via api.svgl.app for
  every featured + marquee tile.
- Next.js Image `remotePatterns` didn't whitelist svgl.app or the
  agent-domain favicon hosts (factory.ai, kiro.dev, opencode.ai,
  cline.bot, etc.), so even valid URLs were rejected before fetch.

Now uses dark-bg-appropriate variants throughout (white/dark logos on
the black page background). For the few brands not in svgl
(continue, kiro, opencode, cline, roo, goose, aider, openclaw,
hermes, droid), falls back to the agent's own website favicon —
each URL HEAD-probed for 200.

Dropped stale remotePatterns: exafunction.github.io,
www.freelogovectors.net, block.github.io (replaced with goose.dev).
Added: continue.dev, goose.dev.

* revert(website): restore github.com avatars for existing agents

Only new logos (copilot-cli, warp, continue, zed, droid, antigravity,
qwen, kiro) and previously-broken ones (cursor, windsurf) use svgl /
own-site URLs. Original github.com/<org>.png avatars for claude-code,
codex, openclaw, hermes, claude-desktop, gemini, opencode, cline, roo,
kilo, goose, aider restored — they were never broken.

next.config remotePatterns trimmed to: svgl.app, www.factory.ai,
kiro.dev, continue.dev (the only non-github hosts still in use).

* fix(assets): pi logo fill white for dark website bg

User-provided SVG uses #09090b near-black; invisible on the agents
grid's dark background. Same path, fill swapped to #ffffff.
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.

4 participants