mirror of
https://github.com/morluto/rea.git
synced 2026-10-12 02:19:24 +00:00
feat(setup): support Command Code MCP registration (#645)
Configure Command Code's user-scope MCP config (~/.commandcode/mcp.json)
with an explicit stdio registration ({ transport, enabled, command, args })
under mcpServers, matching the shape Command Code writes itself.
Adds the commandcode setup client and dialect, detection/alignment support,
README/docs entries, and regenerated product catalog.
This commit is contained in:
@@ -110,7 +110,7 @@ Setup shows its changes before applying them and backs up existing configuration
|
||||
|
||||
After setup, restart your agent and [describe the app or feature](#just-ask-your-agent) you want to understand. Hopper can run in demo mode; if it shows a first-run prompt, choose the demo or enter an existing license.
|
||||
|
||||
REA supports Claude Code, Claude Desktop, Codex, Cursor, Gemini CLI, Windsurf, Devin, OpenCode, Antigravity, GitHub Copilot CLI, and VS Code. Existing REA registrations are selected by default during setup; other detected agents remain unselected until chosen. Other agents can use the [manual MCP configuration](#manual-mcp-configuration).
|
||||
REA supports Claude Code, Claude Desktop, Codex, Cursor, Gemini CLI, Windsurf, Devin, OpenCode, Antigravity, GitHub Copilot CLI, Command Code, and VS Code. Existing REA registrations are selected by default during setup; other detected agents remain unselected until chosen. Other agents can use the [manual MCP configuration](#manual-mcp-configuration).
|
||||
|
||||
### From the terminal with npx
|
||||
|
||||
|
||||
+2
-2
@@ -92,7 +92,7 @@ npx rea-agents setup
|
||||
|
||||
### الاستخدام مع وكيل
|
||||
|
||||
بعد الإعداد، أعد تشغيل الوكيل واشرح التطبيق أو الميزة التي تريد استقصاءها. يدعم REA Claude Code وClaude Desktop وCodex وCursor وGemini CLI وWindsurf وDevin وOpenCode وAntigravity وGitHub Copilot CLI وVS Code. تكون تسجيلات REA الموجودة محددة افتراضياً، ويجب اختيار العملاء المكتشفين الآخرين يدوياً. يمكن للوكلاء الآخرين استخدام إعداد MCP أدناه.
|
||||
بعد الإعداد، أعد تشغيل الوكيل واشرح التطبيق أو الميزة التي تريد استقصاءها. يدعم REA Claude Code وClaude Desktop وCodex وCursor وGemini CLI وWindsurf وDevin وOpenCode وAntigravity وGitHub Copilot CLI وCommand Code وVS Code. تكون تسجيلات REA الموجودة محددة افتراضياً، ويجب اختيار العملاء المكتشفين الآخرين يدوياً. يمكن للوكلاء الآخرين استخدام إعداد MCP أدناه.
|
||||
|
||||
يمكن تشغيل Hopper في الوضع التجريبي. إذا ظهرت رسالة عند التشغيل الأول، فاختر التجربة أو أدخل ترخيصًا موجودًا.
|
||||
|
||||
@@ -219,7 +219,7 @@ rea setup
|
||||
|
||||
## استخدام REA مع وكلاء برمجة آخرين
|
||||
|
||||
يدعم Setup Claude Code وClaude Desktop وCodex وCursor وGemini CLI وWindsurf وDevin وOpenCode وAntigravity وGitHub Copilot CLI وVS Code. تكون تسجيلات REA الموجودة محددة افتراضياً، ويجب اختيار العملاء المكتشفين الآخرين يدوياً. يمكن لأي وكيل يدعم خوادم MCP المحلية الاتصال باستخدام الإعداد التالي:
|
||||
يدعم Setup Claude Code وClaude Desktop وCodex وCursor وGemini CLI وWindsurf وDevin وOpenCode وAntigravity وGitHub Copilot CLI وCommand Code وVS Code. تكون تسجيلات REA الموجودة محددة افتراضياً، ويجب اختيار العملاء المكتشفين الآخرين يدوياً. يمكن لأي وكيل يدعم خوادم MCP المحلية الاتصال باستخدام الإعداد التالي:
|
||||
|
||||
<!-- x-release-please-start-version -->
|
||||
|
||||
|
||||
+2
-2
@@ -92,7 +92,7 @@ Setup は最初に連携するエージェントを複数選択できるよう
|
||||
|
||||
### エージェントで使う
|
||||
|
||||
設定後にエージェントを再起動し、調べたいアプリや機能を説明します。REA は Claude Code、Claude Desktop、Codex、Cursor、Gemini CLI、Windsurf、Devin、OpenCode、Antigravity、GitHub Copilot CLI、VS Code に対応します。既存の REA 登録は初期選択され、それ以外の検出済みクライアントは選択が必要です。その他のエージェントは下記の MCP 設定を使えます。
|
||||
設定後にエージェントを再起動し、調べたいアプリや機能を説明します。REA は Claude Code、Claude Desktop、Codex、Cursor、Gemini CLI、Windsurf、Devin、OpenCode、Antigravity、GitHub Copilot CLI、Command Code、VS Code に対応します。既存の REA 登録は初期選択され、それ以外の検出済みクライアントは選択が必要です。その他のエージェントは下記の MCP 設定を使えます。
|
||||
|
||||
Hopper はデモモードで使えます。初回起動の画面ではデモを選択するか、既存のライセンスを入力してください。
|
||||
|
||||
@@ -208,7 +208,7 @@ REA は手順 1〜5 のバイナリ解析を処理し、手順 6 はエージェ
|
||||
|
||||
## 他のコーディングエージェントで使う
|
||||
|
||||
Setup は Claude Code、Claude Desktop、Codex、Cursor、Gemini CLI、Windsurf、Devin、OpenCode、Antigravity、GitHub Copilot CLI、VS Code に対応します。既存の REA 登録は初期選択され、それ以外の検出済みクライアントは選択が必要です。ローカル MCP サーバーに対応するエージェントは、次の設定でも接続できます。
|
||||
Setup は Claude Code、Claude Desktop、Codex、Cursor、Gemini CLI、Windsurf、Devin、OpenCode、Antigravity、GitHub Copilot CLI、Command Code、VS Code に対応します。既存の REA 登録は初期選択され、それ以外の検出済みクライアントは選択が必要です。ローカル MCP サーバーに対応するエージェントは、次の設定でも接続できます。
|
||||
|
||||
<!-- x-release-please-start-version -->
|
||||
|
||||
|
||||
+2
-2
@@ -93,7 +93,7 @@ Setup은 먼저 연결할 에이전트를 여러 개 선택하도록 안내합
|
||||
|
||||
### 에이전트에서 사용하기
|
||||
|
||||
설정 후 에이전트를 다시 시작하고 조사할 앱이나 기능을 설명하세요. REA는 Claude Code, Claude Desktop, Codex, Cursor, Gemini CLI, Windsurf, Devin, OpenCode, Antigravity, GitHub Copilot CLI, VS Code를 지원합니다. 기존 REA 등록은 기본 선택되고, 그 밖의 감지된 클라이언트는 직접 선택해야 합니다. 다른 에이전트는 아래 MCP 설정을 사용할 수 있습니다.
|
||||
설정 후 에이전트를 다시 시작하고 조사할 앱이나 기능을 설명하세요. REA는 Claude Code, Claude Desktop, Codex, Cursor, Gemini CLI, Windsurf, Devin, OpenCode, Antigravity, GitHub Copilot CLI, Command Code, VS Code를 지원합니다. 기존 REA 등록은 기본 선택되고, 그 밖의 감지된 클라이언트는 직접 선택해야 합니다. 다른 에이전트는 아래 MCP 설정을 사용할 수 있습니다.
|
||||
|
||||
Hopper는 데모 모드로 사용할 수 있습니다. 첫 실행 안내가 나오면 데모를 선택하거나 기존 라이선스를 입력하세요.
|
||||
|
||||
@@ -209,7 +209,7 @@ REA는 1–5단계의 바이너리 분석을 처리합니다. 6단계는 에이
|
||||
|
||||
## 다른 코딩 에이전트에서 사용하기
|
||||
|
||||
Setup은 Claude Code, Claude Desktop, Codex, Cursor, Gemini CLI, Windsurf, Devin, OpenCode, Antigravity, GitHub Copilot CLI, VS Code를 지원합니다. 기존 REA 등록은 기본 선택되고, 그 밖의 감지된 클라이언트는 직접 선택해야 합니다. 로컬 MCP 서버를 지원하는 에이전트는 다음 설정으로 연결할 수 있습니다.
|
||||
Setup은 Claude Code, Claude Desktop, Codex, Cursor, Gemini CLI, Windsurf, Devin, OpenCode, Antigravity, GitHub Copilot CLI, Command Code, VS Code를 지원합니다. 기존 REA 등록은 기본 선택되고, 그 밖의 감지된 클라이언트는 직접 선택해야 합니다. 로컬 MCP 서버를 지원하는 에이전트는 다음 설정으로 연결할 수 있습니다.
|
||||
|
||||
<!-- x-release-please-start-version -->
|
||||
|
||||
|
||||
+2
-2
@@ -92,7 +92,7 @@ Setup 会先展示变更并备份已有配置。要求与更多选项见[安装
|
||||
|
||||
### 使用智能体
|
||||
|
||||
设置完成后,重启智能体并描述你想了解的应用或功能。REA 支持 Claude Code、Claude Desktop、Codex、Cursor、Gemini CLI、Windsurf、Devin、OpenCode、Antigravity、GitHub Copilot CLI 和 VS Code。已有 REA 注册默认选中;其他检测到的客户端需手动选择。其他智能体可以使用下方的 MCP 配置。
|
||||
设置完成后,重启智能体并描述你想了解的应用或功能。REA 支持 Claude Code、Claude Desktop、Codex、Cursor、Gemini CLI、Windsurf、Devin、OpenCode、Antigravity、GitHub Copilot CLI、Command Code 和 VS Code。已有 REA 注册默认选中;其他检测到的客户端需手动选择。其他智能体可以使用下方的 MCP 配置。
|
||||
|
||||
Hopper 支持演示模式。如果首次启动时出现提示,选择演示模式或输入已有许可证。
|
||||
|
||||
@@ -208,7 +208,7 @@ REA 负责第 1–5 步中的二进制分析。第 6 步由智能体使用其常
|
||||
|
||||
## 与其他编程智能体一起使用
|
||||
|
||||
Setup 支持 Claude Code、Claude Desktop、Codex、Cursor、Gemini CLI、Windsurf、Devin、OpenCode、Antigravity、GitHub Copilot CLI 和 VS Code。已有 REA 注册默认选中;其他检测到的客户端需手动选择。任何支持本地 MCP 服务器的智能体都可以使用以下配置连接 REA。
|
||||
Setup 支持 Claude Code、Claude Desktop、Codex、Cursor、Gemini CLI、Windsurf、Devin、OpenCode、Antigravity、GitHub Copilot CLI、Command Code 和 VS Code。已有 REA 注册默认选中;其他检测到的客户端需手动选择。任何支持本地 MCP 服务器的智能体都可以使用以下配置连接 REA。
|
||||
|
||||
<!-- x-release-please-start-version -->
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ Setup can configure these clients for REA's local MCP server:
|
||||
| OpenCode | `opencode` |
|
||||
| Antigravity | `antigravity` |
|
||||
| GitHub Copilot CLI | `copilot_cli` |
|
||||
| Command Code | `commandcode` |
|
||||
| VS Code | `vscode` |
|
||||
|
||||
## Review setup changes
|
||||
|
||||
@@ -451,6 +451,12 @@
|
||||
"format": "copilot_cli",
|
||||
"configuration": "managed"
|
||||
},
|
||||
{
|
||||
"id": "commandcode",
|
||||
"display_name": "Command Code",
|
||||
"format": "commandcode",
|
||||
"configuration": "managed"
|
||||
},
|
||||
{
|
||||
"id": "vscode",
|
||||
"display_name": "VS Code",
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ REA setup lets you select agent integration and optional Hopper installation.
|
||||
It installs the bundled workflow, configures detected agents, and can save
|
||||
verified paths for an existing Ghidra installation. It configures Claude Code,
|
||||
Claude Desktop, Codex, Cursor, Gemini CLI, Windsurf, Devin, OpenCode, Antigravity,
|
||||
GitHub Copilot CLI, and VS Code using each client's configuration format.
|
||||
GitHub Copilot CLI, Command Code, and VS Code using each client's configuration format.
|
||||
|
||||
Ghidra analysis supports Linux x64 and macOS x64/arm64 with Ghidra 12.1.4 and a
|
||||
64-bit full JDK 21. macOS also requires the matching native decompiler. The
|
||||
|
||||
@@ -150,6 +150,14 @@ export const clientRegistrationEntry = (
|
||||
tools: ["*"],
|
||||
...(Object.keys(environment).length === 0 ? {} : { env: environment }),
|
||||
};
|
||||
case "commandcode":
|
||||
return {
|
||||
transport: "stdio",
|
||||
enabled: true,
|
||||
command: executable,
|
||||
args,
|
||||
...(Object.keys(environment).length === 0 ? {} : { env: environment }),
|
||||
};
|
||||
default:
|
||||
return {
|
||||
command: executable,
|
||||
|
||||
@@ -47,6 +47,7 @@ const registrationSchema = z
|
||||
args: z.array(z.string()).default([]),
|
||||
startup_timeout_sec: z.number().positive().optional(),
|
||||
type: z.string().optional(),
|
||||
transport: z.string().optional(),
|
||||
tools: z.array(z.string()).optional(),
|
||||
disabled: z.boolean().optional(),
|
||||
enabled: z.boolean().optional(),
|
||||
@@ -152,6 +153,8 @@ const registrationAligned = (
|
||||
JSON.stringify(registration.tools) !== JSON.stringify(["*"]))
|
||||
)
|
||||
return false;
|
||||
if (client.format === "commandcode" && registration.transport !== "stdio")
|
||||
return false;
|
||||
if (
|
||||
command.length === 4 &&
|
||||
command[0] === "npx" &&
|
||||
@@ -193,6 +196,8 @@ const parseRegistration = (
|
||||
registration.type !== "stdio"
|
||||
)
|
||||
throw new TypeError("Expected an stdio registration");
|
||||
if (client.format === "commandcode" && registration.transport !== "stdio")
|
||||
throw new TypeError("Expected an stdio registration");
|
||||
return registration;
|
||||
};
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ export interface SetupClient {
|
||||
| "vscode"
|
||||
| "copilot_cli"
|
||||
| "opencode"
|
||||
| "commandcode"
|
||||
| "unsupported";
|
||||
}
|
||||
|
||||
@@ -79,6 +80,9 @@ const codexDirectory = ({ home, env }: ClientPathContext): string =>
|
||||
const copilotDirectory = ({ home, env }: ClientPathContext): string =>
|
||||
env.COPILOT_HOME ?? join(home, ".copilot");
|
||||
|
||||
const commandCodeDirectory = ({ home }: ClientPathContext): string =>
|
||||
join(home, ".commandcode");
|
||||
|
||||
const opencodeDirectory = ({ home, env }: ClientPathContext): string =>
|
||||
join(env.XDG_CONFIG_HOME ?? join(home, ".config"), "opencode");
|
||||
|
||||
@@ -192,6 +196,14 @@ export const SUPPORTED_CLIENT_DEFINITIONS = [
|
||||
markerPath: copilotDirectory,
|
||||
format: "copilot_cli",
|
||||
},
|
||||
{
|
||||
name: "commandcode",
|
||||
displayName: "Command Code",
|
||||
configPath: (context: ClientPathContext) =>
|
||||
join(commandCodeDirectory(context), "mcp.json"),
|
||||
markerPath: commandCodeDirectory,
|
||||
format: "commandcode",
|
||||
},
|
||||
{
|
||||
name: "vscode",
|
||||
displayName: "VS Code",
|
||||
|
||||
@@ -35,9 +35,14 @@ afterEach(() => vi.unstubAllEnvs());
|
||||
|
||||
const getClients = (home: string) =>
|
||||
supportedClients(home).filter(({ name }) =>
|
||||
["opencode", "antigravity", "copilot_cli", "vscode", "devin"].includes(
|
||||
name,
|
||||
),
|
||||
[
|
||||
"opencode",
|
||||
"antigravity",
|
||||
"copilot_cli",
|
||||
"commandcode",
|
||||
"vscode",
|
||||
"devin",
|
||||
].includes(name),
|
||||
);
|
||||
|
||||
describe("additional client configuration dialects", () => {
|
||||
@@ -45,6 +50,7 @@ describe("additional client configuration dialects", () => {
|
||||
"opencode",
|
||||
"antigravity",
|
||||
"copilot_cli",
|
||||
"commandcode",
|
||||
"vscode",
|
||||
"devin",
|
||||
] as const)("registers, reads back, and uninstalls %s", async (name) => {
|
||||
@@ -90,6 +96,13 @@ describe("additional client configuration dialects", () => {
|
||||
});
|
||||
if (name === "copilot_cli")
|
||||
expect(registration).toMatchObject({ type: "stdio", tools: ["*"] });
|
||||
if (name === "commandcode")
|
||||
expect(registration).toMatchObject({
|
||||
transport: "stdio",
|
||||
enabled: true,
|
||||
command: "npx",
|
||||
args: command.slice(1),
|
||||
});
|
||||
|
||||
const statuses = await readClientRegistrationStatuses(home);
|
||||
expect(statuses).toEqual(
|
||||
|
||||
@@ -60,6 +60,7 @@ describe("client configuration filesystem lifecycle", () => {
|
||||
"opencode",
|
||||
"antigravity",
|
||||
"copilot_cli",
|
||||
"commandcode",
|
||||
"vscode",
|
||||
]);
|
||||
expect(
|
||||
|
||||
@@ -126,3 +126,59 @@ describe("client registration status", () => {
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("commandcode registration status", () => {
|
||||
const writeCommandcodeRegistration = async (
|
||||
home: string,
|
||||
registration: Record<string, unknown>,
|
||||
): Promise<void> => {
|
||||
await mkdir(join(home, ".commandcode"));
|
||||
await writeFile(
|
||||
join(home, ".commandcode/mcp.json"),
|
||||
JSON.stringify({ mcpServers: { rea: registration } }),
|
||||
);
|
||||
};
|
||||
|
||||
const ownedArgs = (): readonly string[] => [
|
||||
"-y",
|
||||
PRODUCT_IDENTITY.registrationPackageSpecifier,
|
||||
"mcp",
|
||||
];
|
||||
|
||||
it.each([undefined, "sse"])(
|
||||
"reports transport %j as invalid",
|
||||
async (transport) => {
|
||||
const home = await createTestTempDirectory("rea-commandcode-transport-");
|
||||
await writeCommandcodeRegistration(home, {
|
||||
...(transport === undefined ? {} : { transport }),
|
||||
command: "npx",
|
||||
args: [...ownedArgs()],
|
||||
});
|
||||
|
||||
expect(await readClientRegistrationStatuses(home)).toEqual([
|
||||
expect.objectContaining({
|
||||
client: "commandcode",
|
||||
state: "invalid",
|
||||
command: [],
|
||||
}),
|
||||
]);
|
||||
},
|
||||
);
|
||||
|
||||
it("reports a disabled registration as stale", async () => {
|
||||
const home = await createTestTempDirectory("rea-commandcode-disabled-");
|
||||
await writeCommandcodeRegistration(home, {
|
||||
transport: "stdio",
|
||||
enabled: false,
|
||||
command: "npx",
|
||||
args: [...ownedArgs()],
|
||||
});
|
||||
|
||||
expect(await readClientRegistrationStatuses(home)).toEqual([
|
||||
expect.objectContaining({
|
||||
client: "commandcode",
|
||||
state: "stale",
|
||||
}),
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user