agent-calling 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +73 -0
- package/README.zh-CN.md +73 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +197 -0
- package/package.json +37 -0
package/README.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Agent Calling
|
|
2
|
+
|
|
3
|
+
Calling other proxies and language models within the Gemini CLI.
|
|
4
|
+
|
|
5
|
+
[English](README.md) | [简体中文](README.zh-CN.md)
|
|
6
|
+
|
|
7
|
+
- [x] Claude code
|
|
8
|
+
- [ ] Codex
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Core Architecture
|
|
13
|
+
|
|
14
|
+
Agent Calling integrates Claude into the Gemini CLI ecosystem through three key mechanisms:
|
|
15
|
+
|
|
16
|
+
1. **Path Hijacking**: Creates a temporary directory containing a proxy script named `claude` (or `claude.cmd`) and forces this directory to the front of the system `PATH` environment variable.
|
|
17
|
+
2. **Context Injection**: The proxy script injects the current state of the Gemini CLI (such as workspace paths) as environment variables, allowing Claude to be aware of the Gemini context.
|
|
18
|
+
3. **Lifecycle Monitoring**: The proxy script sends notifications before and after calling the actual Claude CLI, enabling the host (Gemini CLI) to synchronize UI states or execute subsequent logic.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
### 1. Prerequisites
|
|
25
|
+
* **Official Claude CLI**: Ensure that Anthropic's `claude` command-line tool is installed and configured on your system.
|
|
26
|
+
* **Node.js Environment**: Node.js 18+ is recommended.
|
|
27
|
+
|
|
28
|
+
### 2. Method 1: Gemini CLI Direct Installation
|
|
29
|
+
```bash
|
|
30
|
+
gemini extension install https://github.com/xuansheep/agent-calling
|
|
31
|
+
cd ~/.gemini/extensions/agent-calling
|
|
32
|
+
npm install
|
|
33
|
+
npm run build
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 3. Method 2: Via npm
|
|
37
|
+
```bash
|
|
38
|
+
npm install -g agent-calling
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Usage
|
|
44
|
+
|
|
45
|
+
### 1. Direct Command Invocation
|
|
46
|
+
Once installed, Gemini CLI will expose a tool named `claude`. You can send instructions directly:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
gemini claude "Analyze the architecture of src/index.ts and suggest refactorings"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### 2. Advanced Parameter Passthrough
|
|
53
|
+
You can pass additional command-line options to the original Claude CLI via the `args` parameter:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
gemini claude "Scan codebase" --args "--output-format json"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Automation (GEMINI.md)
|
|
62
|
+
|
|
63
|
+
To achieve automatic delegation of complex tasks, this project includes a `GEMINI.md` configuration file. When you perform the following operations in the Gemini CLI, the Agent will automatically invoke this extension based on the instruction set:
|
|
64
|
+
|
|
65
|
+
### Delegation Criteria
|
|
66
|
+
- **System Architecture Analysis**: e.g., "Analyze overall project architecture", "Identify dependencies between modules".
|
|
67
|
+
- **Long-term Planning**: e.g., "Generate a detailed implementation plan", "Create a refactoring roadmap".
|
|
68
|
+
- **Deep Code Review**: e.g., "Scan the codebase for potential security vulnerabilities".
|
|
69
|
+
- **Complex Refactoring Suggestions**: Involving decoupling logic or pattern refactoring.
|
|
70
|
+
|
|
71
|
+
### Automated Execution Protocol
|
|
72
|
+
1. **Context Injection**: The Agent automatically injects the list of files currently being processed or related documents into the `prompt`.
|
|
73
|
+
2. **Structured Output**: Claude is required to return results in JSON format by default (e.g., using `--output-format json`) for subsequent automated processing.
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Agent Calling (Gemini CLI 增强扩展)
|
|
2
|
+
|
|
3
|
+
在 Gemini CLI 中调用其他代理和语言模型。
|
|
4
|
+
|
|
5
|
+
[English](README.md) | [简体中文](README.zh-CN.md)
|
|
6
|
+
|
|
7
|
+
- [x] Claude code
|
|
8
|
+
- [ ] Codex
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 核心架构原理
|
|
13
|
+
|
|
14
|
+
Agent Calling 通过以下三个核心机制将 Claude 融入 Gemini CLI 生态系统:
|
|
15
|
+
|
|
16
|
+
1. **路径劫持**: 创建一个包含名为 `claude`(或 `claude.cmd`)的代理脚本的临时目录,并将该目录强行置于系统 `PATH` 环境变量的最前面。
|
|
17
|
+
2. **上下文注入**: 在代理脚本中,将 Gemini CLI 的当前状态(如工作区路径)作为环境变量注入,使 Claude 能够感知 Gemini 的上下文。
|
|
18
|
+
3. **生命周期监听**: 代理脚本在调用真正的 Claude CLI 前后发送通知,以便宿主(Gemini CLI)同步 UI 状态或执行后续逻辑。
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 安装说明
|
|
23
|
+
|
|
24
|
+
### 1. 先决条件
|
|
25
|
+
* **安装官方 Claude CLI**: 确保系统中已安装并配置好 Anthropic 的 `claude` 命令行工具。
|
|
26
|
+
* **Node.js 环境**: 建议使用 Node.js 18+。
|
|
27
|
+
|
|
28
|
+
### 2. 方式一:Gemini CLI 直接安装
|
|
29
|
+
```bash
|
|
30
|
+
gemini extension install https://github.com/xuansheep/agent-calling
|
|
31
|
+
cd ~/.gemini/extensions/agent-calling
|
|
32
|
+
npm install
|
|
33
|
+
npm run build
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 3. 方式二:使用 npm
|
|
37
|
+
```bash
|
|
38
|
+
npm install -g agent-calling
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 使用方法
|
|
44
|
+
|
|
45
|
+
### 1. 通过命令行直接调用
|
|
46
|
+
安装完成后,Gemini CLI 将暴露一个名为 `claude` 的工具。你可以直接发送指令:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
gemini claude "分析 src/index.ts 的架构并提出重构建议"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### 2. 高级参数透传
|
|
53
|
+
你可以通过 `args` 参数向原始 Claude CLI 传递额外的命令行选项:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
gemini claude "扫描代码库" --args "--output-format json"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## 自动化执行 (GEMINI.md)
|
|
62
|
+
|
|
63
|
+
为了实现复杂任务的自动委派,本项目包含了一个 `GEMINI.md` 配置文件。当你在 Gemini CLI 中执行以下操作时,Agent 将根据指令集自动调用本扩展:
|
|
64
|
+
|
|
65
|
+
### 任务委派准则
|
|
66
|
+
- **系统架构分析**: 如“分析项目整体架构”、“识别模块间依赖关系”。
|
|
67
|
+
- **长程计划制定**: 如“生成详细的项目实现计划”、“制定重构路线图”。
|
|
68
|
+
- **深度代码审查**: 如“扫描代码库中的潜在安全漏洞”。
|
|
69
|
+
- **复杂重构建议**: 涉及项目逻辑解耦或模式重构。
|
|
70
|
+
|
|
71
|
+
### 自动化执行协议
|
|
72
|
+
1. **上下文注入**: Agent 自动将当前处理的文件列表或相关文档注入到 `prompt`。
|
|
73
|
+
2. **结构化输出**: 默认要求 Claude 返回 JSON 格式(如使用 `--output-format json`),以便后续自动化处理。
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
37
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
38
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
39
|
+
const child_process_1 = require("child_process");
|
|
40
|
+
const path = __importStar(require("path"));
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
42
|
+
const os = __importStar(require("os"));
|
|
43
|
+
/**
|
|
44
|
+
* Generate proxy wrapper script (Windows uses .cmd, Unix uses Bash)
|
|
45
|
+
*/
|
|
46
|
+
function generateWrapperScript(wrapperPath, port) {
|
|
47
|
+
const isWindows = os.platform() === 'win32';
|
|
48
|
+
const CRLF = '\r\n';
|
|
49
|
+
let scriptContent = '';
|
|
50
|
+
if (isWindows) {
|
|
51
|
+
scriptContent = [
|
|
52
|
+
'@echo off',
|
|
53
|
+
'setlocal',
|
|
54
|
+
'set GEMINI_CLI_WORKSPACE_ID=current-workspace-id',
|
|
55
|
+
`powershell -NoProfile -Command "Invoke-RestMethod -Method Post -Uri 'http://127.0.0.1:${port}/notify' -Body '{\\"status\\": \\"starting\\", \\"agent\\": \\"run_claude\\"}' -ContentType 'application/json'" > nul 2>&1`,
|
|
56
|
+
'set REAL_CLAUDE=',
|
|
57
|
+
'for /f "tokens=*" %%i in (\'where claude\') do (',
|
|
58
|
+
' if /i not "%%i"=="%~f0" (',
|
|
59
|
+
' set REAL_CLAUDE="%%i"',
|
|
60
|
+
' goto :found',
|
|
61
|
+
' )',
|
|
62
|
+
')',
|
|
63
|
+
':found',
|
|
64
|
+
'if "%REAL_CLAUDE%"=="" (',
|
|
65
|
+
' echo Original Claude CLI not found in system, please install it first.',
|
|
66
|
+
' exit /b 1',
|
|
67
|
+
')',
|
|
68
|
+
'%REAL_CLAUDE% %*',
|
|
69
|
+
'set EXIT_CODE=%ERRORLEVEL%',
|
|
70
|
+
`powershell -NoProfile -Command "Invoke-RestMethod -Method Post -Uri 'http://127.0.0.1:${port}/notify' -Body '{\\"status\\": \\"finished\\", \\"exit_code\\": \\"%EXIT_CODE%\\"}' -ContentType 'application/json'" > nul 2>&1`,
|
|
71
|
+
'exit /b %EXIT_CODE%'
|
|
72
|
+
].join(CRLF);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
scriptContent = `#!/usr/bin/env bash
|
|
76
|
+
export GEMINI_CLI_WORKSPACE_ID="current-workspace-id"
|
|
77
|
+
curl -s -X POST http://127.0.0.1:${port}/notify -d '{"status": "starting", "agent": "run_claude"}' > /dev/null
|
|
78
|
+
REAL_CLAUDE=$(which -a claude | grep -v "$0" | head -n 1)
|
|
79
|
+
if [ -z "$REAL_CLAUDE" ]; then
|
|
80
|
+
echo "Original Claude CLI not found in system, please install it first."
|
|
81
|
+
exit 1
|
|
82
|
+
fi
|
|
83
|
+
"$REAL_CLAUDE" "$@"
|
|
84
|
+
EXIT_CODE=$?
|
|
85
|
+
curl -s -X POST http://127.0.0.1:${port}/notify -d '{"status": "finished", "exit_code": "'"$EXIT_CODE"'"}' > /dev/null
|
|
86
|
+
exit $EXIT_CODE
|
|
87
|
+
`;
|
|
88
|
+
}
|
|
89
|
+
fs.writeFileSync(wrapperPath, scriptContent, { mode: 0o755 });
|
|
90
|
+
}
|
|
91
|
+
async function runClaude(prompt, extraArgs = []) {
|
|
92
|
+
const wrapperDir = path.join(os.tmpdir(), 'gemini-cli-wrappers');
|
|
93
|
+
if (!fs.existsSync(wrapperDir)) {
|
|
94
|
+
fs.mkdirSync(wrapperDir, { recursive: true });
|
|
95
|
+
}
|
|
96
|
+
const isWindows = os.platform() === 'win32';
|
|
97
|
+
const wrapperName = isWindows ? 'claude.cmd' : 'claude';
|
|
98
|
+
const wrapperPath = path.join(wrapperDir, wrapperName);
|
|
99
|
+
const port = process.env.GEMINI_CLI_PORT || "8080";
|
|
100
|
+
generateWrapperScript(wrapperPath, port);
|
|
101
|
+
const originalPath = process.env.PATH || '';
|
|
102
|
+
const pathSeparator = isWindows ? ';' : ':';
|
|
103
|
+
const customEnv = {
|
|
104
|
+
...process.env,
|
|
105
|
+
PATH: `${wrapperDir}${pathSeparator}${originalPath}`,
|
|
106
|
+
GEMINI_CLI_PORT: port
|
|
107
|
+
};
|
|
108
|
+
// Integrate parameters
|
|
109
|
+
const finalArgs = [...extraArgs];
|
|
110
|
+
if (prompt) {
|
|
111
|
+
finalArgs.push('-p', prompt);
|
|
112
|
+
}
|
|
113
|
+
return new Promise((resolve) => {
|
|
114
|
+
let output = '';
|
|
115
|
+
const child = (0, child_process_1.spawn)(isWindows ? 'claude.cmd' : 'claude', finalArgs, {
|
|
116
|
+
env: customEnv,
|
|
117
|
+
shell: isWindows,
|
|
118
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
119
|
+
});
|
|
120
|
+
child.stdout.on('data', (data) => {
|
|
121
|
+
output += data.toString();
|
|
122
|
+
});
|
|
123
|
+
child.stderr.on('data', (data) => {
|
|
124
|
+
output += data.toString();
|
|
125
|
+
});
|
|
126
|
+
child.on('close', (code) => {
|
|
127
|
+
resolve({ output, exitCode: code || 0 });
|
|
128
|
+
});
|
|
129
|
+
child.on('error', (err) => {
|
|
130
|
+
resolve({ output: `Error: ${err.message}`, exitCode: 1 });
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
// Create MCP Server
|
|
135
|
+
const server = new index_js_1.Server({
|
|
136
|
+
name: "claude-mcp",
|
|
137
|
+
version: "1.0.0",
|
|
138
|
+
}, {
|
|
139
|
+
capabilities: {
|
|
140
|
+
tools: {},
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
// List tools
|
|
144
|
+
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
|
|
145
|
+
return {
|
|
146
|
+
tools: [
|
|
147
|
+
{
|
|
148
|
+
name: "run_claude",
|
|
149
|
+
description: "Invokes Anthropic's Claude CLI. Supports complex codebase analysis, architectural design, and planning. It automatically injects current workspace context and hijacks the PATH environment variable. Note: When calling in a sub-agent, be sure to use the full tool name 'agent-claude__run_claude'.",
|
|
150
|
+
inputSchema: {
|
|
151
|
+
type: "object",
|
|
152
|
+
properties: {
|
|
153
|
+
prompt: {
|
|
154
|
+
type: "string",
|
|
155
|
+
description: "Prompt or instruction sent to Claude CLI."
|
|
156
|
+
},
|
|
157
|
+
args: {
|
|
158
|
+
type: "array",
|
|
159
|
+
items: {
|
|
160
|
+
type: "string"
|
|
161
|
+
},
|
|
162
|
+
description: "Original command-line arguments passed through to Claude CLI."
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
required: ["prompt"]
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
]
|
|
169
|
+
};
|
|
170
|
+
});
|
|
171
|
+
// Tool call handler
|
|
172
|
+
server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
173
|
+
if (request.params.name === "run_claude") {
|
|
174
|
+
const { prompt, args } = request.params.arguments;
|
|
175
|
+
const result = await runClaude(prompt, args);
|
|
176
|
+
return {
|
|
177
|
+
content: [
|
|
178
|
+
{
|
|
179
|
+
type: "text",
|
|
180
|
+
text: result.output,
|
|
181
|
+
},
|
|
182
|
+
],
|
|
183
|
+
isError: result.exitCode !== 0,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
throw new Error(`Tool not found: ${request.params.name}`);
|
|
187
|
+
});
|
|
188
|
+
// Start server
|
|
189
|
+
async function main() {
|
|
190
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
191
|
+
await server.connect(transport);
|
|
192
|
+
console.error("Agent Claude (MCP Server) started.");
|
|
193
|
+
}
|
|
194
|
+
main().catch((error) => {
|
|
195
|
+
console.error("Server error:", error);
|
|
196
|
+
process.exit(1);
|
|
197
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agent-calling",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A Gemini CLI plugin that wraps Claude CLI with path hijacking.",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/xuansheep/agent-calling.git"
|
|
8
|
+
},
|
|
9
|
+
"engines": {
|
|
10
|
+
"node": ">=18.0.0"
|
|
11
|
+
},
|
|
12
|
+
"main": "dist/index.js",
|
|
13
|
+
"types": "dist/index.d.ts",
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc",
|
|
22
|
+
"prepublishOnly": "npm run build",
|
|
23
|
+
"start": "node dist/index.js",
|
|
24
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [],
|
|
27
|
+
"author": "",
|
|
28
|
+
"license": "ISC",
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/node": "^20.11.0",
|
|
31
|
+
"typescript": "^5.3.3"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
35
|
+
"zod": "^4.3.6"
|
|
36
|
+
}
|
|
37
|
+
}
|