@elvatis_com/elvatis-mcp 0.2.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/.env.example +61 -0
- package/LICENSE +190 -0
- package/README.md +471 -0
- package/dist/config.d.ts +39 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +45 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +146 -0
- package/dist/index.js.map +1 -0
- package/dist/spawn.d.ts +12 -0
- package/dist/spawn.d.ts.map +1 -0
- package/dist/spawn.js +55 -0
- package/dist/spawn.js.map +1 -0
- package/dist/ssh.d.ts +28 -0
- package/dist/ssh.d.ts.map +1 -0
- package/dist/ssh.js +171 -0
- package/dist/ssh.js.map +1 -0
- package/dist/tools/codex.d.ts +61 -0
- package/dist/tools/codex.d.ts.map +1 -0
- package/dist/tools/codex.js +63 -0
- package/dist/tools/codex.js.map +1 -0
- package/dist/tools/cron.d.ts +58 -0
- package/dist/tools/cron.d.ts.map +1 -0
- package/dist/tools/cron.js +88 -0
- package/dist/tools/cron.js.map +1 -0
- package/dist/tools/gemini.d.ts +75 -0
- package/dist/tools/gemini.d.ts.map +1 -0
- package/dist/tools/gemini.js +72 -0
- package/dist/tools/gemini.js.map +1 -0
- package/dist/tools/help.d.ts +31 -0
- package/dist/tools/help.d.ts.map +1 -0
- package/dist/tools/help.js +39 -0
- package/dist/tools/help.js.map +1 -0
- package/dist/tools/home.d.ts +108 -0
- package/dist/tools/home.d.ts.map +1 -0
- package/dist/tools/home.js +141 -0
- package/dist/tools/home.js.map +1 -0
- package/dist/tools/local-llm.d.ts +115 -0
- package/dist/tools/local-llm.d.ts.map +1 -0
- package/dist/tools/local-llm.js +123 -0
- package/dist/tools/local-llm.js.map +1 -0
- package/dist/tools/memory.d.ts +52 -0
- package/dist/tools/memory.d.ts.map +1 -0
- package/dist/tools/memory.js +92 -0
- package/dist/tools/memory.js.map +1 -0
- package/dist/tools/openclaw.d.ts +88 -0
- package/dist/tools/openclaw.d.ts.map +1 -0
- package/dist/tools/openclaw.js +119 -0
- package/dist/tools/openclaw.js.map +1 -0
- package/dist/tools/routing-rules.d.ts +21 -0
- package/dist/tools/routing-rules.d.ts.map +1 -0
- package/dist/tools/routing-rules.js +149 -0
- package/dist/tools/routing-rules.js.map +1 -0
- package/dist/tools/splitter.d.ts +49 -0
- package/dist/tools/splitter.d.ts.map +1 -0
- package/dist/tools/splitter.js +375 -0
- package/dist/tools/splitter.js.map +1 -0
- package/package.json +54 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* elvatis-mcp — MCP server exposing OpenClaw tools to Claude Desktop, Cursor, Windsurf, and any MCP client.
|
|
5
|
+
*
|
|
6
|
+
* Transports:
|
|
7
|
+
* stdio (default) — for Claude Desktop / local clients
|
|
8
|
+
* http — for remote clients (set MCP_TRANSPORT=http)
|
|
9
|
+
*
|
|
10
|
+
* Configuration:
|
|
11
|
+
* Copy .env.example to .env and fill in your values.
|
|
12
|
+
* Or set env vars directly in claude_desktop_config.json.
|
|
13
|
+
*
|
|
14
|
+
* Usage:
|
|
15
|
+
* npx @elvatis_com/elvatis-mcp
|
|
16
|
+
* MCP_TRANSPORT=http MCP_HTTP_PORT=3333 npx @elvatis_com/elvatis-mcp
|
|
17
|
+
*/
|
|
18
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
21
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
22
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
23
|
+
}
|
|
24
|
+
Object.defineProperty(o, k2, desc);
|
|
25
|
+
}) : (function(o, m, k, k2) {
|
|
26
|
+
if (k2 === undefined) k2 = k;
|
|
27
|
+
o[k2] = m[k];
|
|
28
|
+
}));
|
|
29
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
30
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
31
|
+
}) : function(o, v) {
|
|
32
|
+
o["default"] = v;
|
|
33
|
+
});
|
|
34
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
35
|
+
var ownKeys = function(o) {
|
|
36
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
37
|
+
var ar = [];
|
|
38
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
39
|
+
return ar;
|
|
40
|
+
};
|
|
41
|
+
return ownKeys(o);
|
|
42
|
+
};
|
|
43
|
+
return function (mod) {
|
|
44
|
+
if (mod && mod.__esModule) return mod;
|
|
45
|
+
var result = {};
|
|
46
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
47
|
+
__setModuleDefault(result, mod);
|
|
48
|
+
return result;
|
|
49
|
+
};
|
|
50
|
+
})();
|
|
51
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
52
|
+
// Load .env — try multiple locations so it works regardless of cwd or client:
|
|
53
|
+
// 1. <project-root>/.env — resolved via __dirname from dist/index.js (most reliable)
|
|
54
|
+
// 2. cwd/.env — fallback for local dev (`node dist/index.js` from repo root)
|
|
55
|
+
// dotenv.config() is a no-op if the file doesn't exist, so ordering is safe.
|
|
56
|
+
const path = __importStar(require("path"));
|
|
57
|
+
const dotenv = __importStar(require("dotenv"));
|
|
58
|
+
dotenv.config({ path: path.resolve(__dirname, '..', '.env') });
|
|
59
|
+
dotenv.config(); // cwd fallback — only loads vars not already set above
|
|
60
|
+
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
61
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
62
|
+
const config_js_1 = require("./config.js");
|
|
63
|
+
const home_js_1 = require("./tools/home.js");
|
|
64
|
+
const memory_js_1 = require("./tools/memory.js");
|
|
65
|
+
const cron_js_1 = require("./tools/cron.js");
|
|
66
|
+
const openclaw_js_1 = require("./tools/openclaw.js");
|
|
67
|
+
const gemini_js_1 = require("./tools/gemini.js");
|
|
68
|
+
const codex_js_1 = require("./tools/codex.js");
|
|
69
|
+
const help_js_1 = require("./tools/help.js");
|
|
70
|
+
const local_llm_js_1 = require("./tools/local-llm.js");
|
|
71
|
+
const splitter_js_1 = require("./tools/splitter.js");
|
|
72
|
+
function toText(result) {
|
|
73
|
+
return JSON.stringify(result, null, 2);
|
|
74
|
+
}
|
|
75
|
+
function registerTool(server, name, description, schema, handler) {
|
|
76
|
+
server.tool(name, description, schema, handler);
|
|
77
|
+
}
|
|
78
|
+
async function main() {
|
|
79
|
+
const config = (0, config_js_1.loadConfig)();
|
|
80
|
+
const server = new mcp_js_1.McpServer({
|
|
81
|
+
name: 'elvatis-mcp',
|
|
82
|
+
version: '0.1.0',
|
|
83
|
+
});
|
|
84
|
+
// --- Home Assistant tools ---
|
|
85
|
+
registerTool(server, 'home_get_state', 'Get the current state of a Home Assistant entity (light, climate, sensor, switch, vacuum, media_player, etc.)', home_js_1.getStateSchema.shape, async (args) => ({ content: [{ type: 'text', text: toText(await (0, home_js_1.handleGetState)(args, config)) }] }));
|
|
86
|
+
registerTool(server, 'home_light', 'Control a light: turn on/off/toggle, set brightness (0-100%), color temperature, or RGB color', home_js_1.lightSchema.shape, async (args) => ({ content: [{ type: 'text', text: toText(await (0, home_js_1.handleLight)(args, config)) }] }));
|
|
87
|
+
registerTool(server, 'home_climate', 'Control Tado thermostats: set target temperature or HVAC mode (heat/auto/off)', home_js_1.climateSchema.shape, async (args) => ({ content: [{ type: 'text', text: toText(await (0, home_js_1.handleClimate)(args, config)) }] }));
|
|
88
|
+
registerTool(server, 'home_scene', 'Activate a Hue scene in a room (wohnzimmer, flur, kuche, schlafzimmer, home)', home_js_1.sceneSchema.shape, async (args) => ({ content: [{ type: 'text', text: toText(await (0, home_js_1.handleScene)(args, config)) }] }));
|
|
89
|
+
registerTool(server, 'home_vacuum', 'Control the Roborock vacuum: start full clean, stop, return to dock, or get status', home_js_1.vacuumSchema.shape, async (args) => ({ content: [{ type: 'text', text: toText(await (0, home_js_1.handleVacuum)(args, config)) }] }));
|
|
90
|
+
registerTool(server, 'home_sensors', 'Read all environmental sensors: temperature, humidity, CO2 for all rooms plus outside temperature', home_js_1.sensorsSchema.shape, async (args) => ({ content: [{ type: 'text', text: toText(await (0, home_js_1.handleSensors)(args, config)) }] }));
|
|
91
|
+
// --- Memory tools (SSH to OpenClaw server) ---
|
|
92
|
+
registerTool(server, 'openclaw_memory_write', 'Write a note to today\'s daily memory log on the OpenClaw server. Use for capturing important context, decisions, or things to remember.', memory_js_1.memoryWriteSchema.shape, async (args) => ({ content: [{ type: 'text', text: toText(await (0, memory_js_1.handleMemoryWrite)(args, config)) }] }));
|
|
93
|
+
registerTool(server, 'openclaw_memory_read_today', 'Read today\'s memory log from the OpenClaw server', memory_js_1.memoryReadTodaySchema.shape, async (args) => ({ content: [{ type: 'text', text: toText(await (0, memory_js_1.handleMemoryReadToday)(args, config)) }] }));
|
|
94
|
+
registerTool(server, 'openclaw_memory_search', 'Search across daily memory files on the OpenClaw server for a keyword (default: last 14 days)', memory_js_1.memorySearchSchema.shape, async (args) => ({ content: [{ type: 'text', text: toText(await (0, memory_js_1.handleMemorySearch)(args, config)) }] }));
|
|
95
|
+
// --- Cron tools (SSH to OpenClaw server) ---
|
|
96
|
+
registerTool(server, 'openclaw_cron_list', 'List all scheduled OpenClaw cron jobs', cron_js_1.cronListSchema.shape, async (args) => ({ content: [{ type: 'text', text: toText(await (0, cron_js_1.handleCronList)(args, config)) }] }));
|
|
97
|
+
registerTool(server, 'openclaw_cron_run', 'Trigger an OpenClaw cron job immediately by its ID', cron_js_1.cronRunSchema.shape, async (args) => ({ content: [{ type: 'text', text: toText(await (0, cron_js_1.handleCronRun)(args, config)) }] }));
|
|
98
|
+
registerTool(server, 'openclaw_cron_status', 'Get OpenClaw cron scheduler status and overview', cron_js_1.cronStatusSchema.shape, async (args) => ({ content: [{ type: 'text', text: toText(await (0, cron_js_1.handleCronStatus)(args, config)) }] }));
|
|
99
|
+
// --- OpenClaw sub-agent tools (SSH orchestration) ---
|
|
100
|
+
registerTool(server, 'openclaw_run', 'Send a task or prompt to the OpenClaw AI agent via SSH. The agent has access to all installed plugins (trading, home automation, etc.) and multiple LLM backends. Use this to delegate complex tasks that OpenClaw already knows how to handle.', openclaw_js_1.openclawRunSchema.shape, async (args) => ({ content: [{ type: 'text', text: toText(await (0, openclaw_js_1.handleOpenclawRun)(args, config)) }] }));
|
|
101
|
+
registerTool(server, 'openclaw_status', 'Check if the OpenClaw daemon is running on the server and get version info', openclaw_js_1.openclawStatusSchema.shape, async (args) => ({ content: [{ type: 'text', text: toText(await (0, openclaw_js_1.handleOpenclawStatus)(args, config)) }] }));
|
|
102
|
+
registerTool(server, 'openclaw_plugins', 'List all plugins installed on the OpenClaw server', openclaw_js_1.openclawPluginsSchema.shape, async (args) => ({ content: [{ type: 'text', text: toText(await (0, openclaw_js_1.handleOpenclawPlugins)(args, config)) }] }));
|
|
103
|
+
// --- Gemini sub-agent (local spawn) ---
|
|
104
|
+
registerTool(server, 'gemini_run', 'Send a prompt to Google Gemini via the local gemini CLI. Fast, direct LLM call with no OpenClaw overhead. Uses cached Google auth — no API key required.', gemini_js_1.geminiRunSchema.shape, async (args) => ({ content: [{ type: 'text', text: toText(await (0, gemini_js_1.handleGeminiRun)(args, config)) }] }));
|
|
105
|
+
// --- Codex sub-agent (local spawn) ---
|
|
106
|
+
registerTool(server, 'codex_run', 'Send a task to OpenAI Codex via the local codex CLI. Specializes in coding tasks, file operations, and technical analysis. Uses cached OpenAI auth — no API key required.', codex_js_1.codexRunSchema.shape, async (args) => ({ content: [{ type: 'text', text: toText(await (0, codex_js_1.handleCodexRun)(args, config)) }] }));
|
|
107
|
+
// --- Local LLM sub-agent ---
|
|
108
|
+
registerTool(server, 'local_llm_run', 'Send a prompt to a local LLM (LM Studio, Ollama, llama.cpp, or any OpenAI-compatible server). Free, private, no API key needed. Best for simple tasks: classify, format, extract, rewrite, proofread.', local_llm_js_1.localLlmRunSchema.shape, async (args) => ({ content: [{ type: 'text', text: toText(await (0, local_llm_js_1.handleLocalLlmRun)(args, config)) }] }));
|
|
109
|
+
// --- Routing and orchestration ---
|
|
110
|
+
registerTool(server, 'mcp_help', 'List all available elvatis-mcp tools with a routing guide. Optionally provide a task description to get a specific recommendation for which sub-agent (openclaw_run, gemini_run, codex_run, local_llm_run) or tool to use.', help_js_1.mcpHelpSchema.shape, async (args) => ({ content: [{ type: 'text', text: toText(await (0, help_js_1.handleMcpHelp)(args)) }] }));
|
|
111
|
+
registerTool(server, 'prompt_split', 'Analyze a complex prompt and split it into sub-tasks with agent assignments. '
|
|
112
|
+
+ 'Returns a structured plan showing which sub-agent (gemini, codex, openclaw, local LLM) handles each part, '
|
|
113
|
+
+ 'dependency ordering, and the actual prompts to send. '
|
|
114
|
+
+ 'Each subtask includes a suggested model that the user can override before execution. '
|
|
115
|
+
+ 'IMPORTANT: Always present the plan to the user for review before executing. '
|
|
116
|
+
+ 'Strategy: "auto" (default), "gemini", "local", or "heuristic".', splitter_js_1.promptSplitSchema.shape, async (args) => ({ content: [{ type: 'text', text: toText(await (0, splitter_js_1.handlePromptSplit)(args, config)) }] }));
|
|
117
|
+
// --- Transport ---
|
|
118
|
+
if (config.transport === 'stdio') {
|
|
119
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
120
|
+
await server.connect(transport);
|
|
121
|
+
process.stderr.write('[elvatis-mcp] Running on stdio transport\n');
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
const { createServer } = await Promise.resolve().then(() => __importStar(require('http')));
|
|
125
|
+
const { StreamableHTTPServerTransport } = await Promise.resolve().then(() => __importStar(require('@modelcontextprotocol/sdk/server/streamableHttp.js')));
|
|
126
|
+
const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
|
|
127
|
+
const httpServer = createServer(async (req, res) => {
|
|
128
|
+
if (req.url === '/mcp') {
|
|
129
|
+
await transport.handleRequest(req, res);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
res.writeHead(404);
|
|
133
|
+
res.end('Not found — MCP endpoint is /mcp');
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
await server.connect(transport);
|
|
137
|
+
httpServer.listen(config.httpPort, () => {
|
|
138
|
+
process.stderr.write(`[elvatis-mcp] Running on HTTP at http://localhost:${config.httpPort}/mcp\n`);
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
main().catch((err) => {
|
|
143
|
+
process.stderr.write(`[elvatis-mcp] Fatal: ${err}\n`);
|
|
144
|
+
process.exit(1);
|
|
145
|
+
});
|
|
146
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/spawn.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local process spawner — runs a command on the same machine as the MCP server.
|
|
3
|
+
* Used by gemini_run and codex_run tools.
|
|
4
|
+
* No SSH required: these CLIs authenticate via their own local credential stores.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Spawn a local command and return stdout as a string.
|
|
8
|
+
* Progress output on stderr is silently collected (not forwarded).
|
|
9
|
+
* Throws if the process exits with a non-zero code or times out.
|
|
10
|
+
*/
|
|
11
|
+
export declare function spawnLocal(cmd: string, args: string[], timeoutMs: number): Promise<string>;
|
|
12
|
+
//# sourceMappingURL=spawn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../src/spawn.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CA4CjB"}
|
package/dist/spawn.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Local process spawner — runs a command on the same machine as the MCP server.
|
|
4
|
+
* Used by gemini_run and codex_run tools.
|
|
5
|
+
* No SSH required: these CLIs authenticate via their own local credential stores.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.spawnLocal = spawnLocal;
|
|
9
|
+
const child_process_1 = require("child_process");
|
|
10
|
+
/**
|
|
11
|
+
* Spawn a local command and return stdout as a string.
|
|
12
|
+
* Progress output on stderr is silently collected (not forwarded).
|
|
13
|
+
* Throws if the process exits with a non-zero code or times out.
|
|
14
|
+
*/
|
|
15
|
+
function spawnLocal(cmd, args, timeoutMs) {
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
const proc = (0, child_process_1.spawn)(cmd, args, {
|
|
18
|
+
shell: false,
|
|
19
|
+
// Inherit the current environment so the CLI can find its auth credentials
|
|
20
|
+
env: process.env,
|
|
21
|
+
});
|
|
22
|
+
let stdout = '';
|
|
23
|
+
let stderr = '';
|
|
24
|
+
proc.stdout.on('data', (d) => { stdout += d.toString(); });
|
|
25
|
+
// Codex streams progress to stderr during execution — collect but don't reject on it
|
|
26
|
+
proc.stderr.on('data', (d) => { stderr += d.toString(); });
|
|
27
|
+
const timer = setTimeout(() => {
|
|
28
|
+
proc.kill('SIGTERM');
|
|
29
|
+
reject(new Error(`Process "${cmd}" timed out after ${timeoutMs}ms`));
|
|
30
|
+
}, timeoutMs);
|
|
31
|
+
proc.on('close', (code) => {
|
|
32
|
+
clearTimeout(timer);
|
|
33
|
+
if (code !== 0) {
|
|
34
|
+
// Include stderr in the error message for easier debugging
|
|
35
|
+
const detail = stderr.trim() || stdout.trim() || '(no output)';
|
|
36
|
+
reject(new Error(`"${cmd}" exited with code ${code}: ${detail.substring(0, 500)}`));
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
resolve(stdout);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
proc.on('error', (err) => {
|
|
43
|
+
clearTimeout(timer);
|
|
44
|
+
if (err.code === 'ENOENT') {
|
|
45
|
+
reject(new Error(`Command not found: "${cmd}". ` +
|
|
46
|
+
`Make sure it is installed globally (npm install -g @google/gemini-cli OR @openai/codex) ` +
|
|
47
|
+
`and available on PATH.`));
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
reject(err);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=spawn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spawn.js","sourceRoot":"","sources":["../src/spawn.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AASH,gCAgDC;AAvDD,iDAAsC;AAEtC;;;;GAIG;AACH,SAAgB,UAAU,CACxB,GAAW,EACX,IAAc,EACd,SAAiB;IAEjB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,IAAI,GAAG,IAAA,qBAAK,EAAC,GAAG,EAAE,IAAI,EAAE;YAC5B,KAAK,EAAE,KAAK;YACZ,2EAA2E;YAC3E,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC,CAAC;QAEH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAEhB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,GAAG,MAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACnE,qFAAqF;QACrF,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,GAAG,MAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAEnE,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACrB,MAAM,CAAC,IAAI,KAAK,CAAC,YAAY,GAAG,qBAAqB,SAAS,IAAI,CAAC,CAAC,CAAC;QACvE,CAAC,EAAE,SAAS,CAAC,CAAC;QAEd,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACxB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACf,2DAA2D;gBAC3D,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC,IAAI,EAAE,IAAI,aAAa,CAAC;gBAC/D,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,GAAG,sBAAsB,IAAI,KAAK,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;YACtF,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,MAAM,CAAC,CAAC;YAClB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAA0B,EAAE,EAAE;YAC9C,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC1B,MAAM,CAAC,IAAI,KAAK,CACd,uBAAuB,GAAG,KAAK;oBAC/B,0FAA0F;oBAC1F,wBAAwB,CACzB,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,GAAG,CAAC,CAAC;YACd,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/ssh.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSH exec helper — runs shell commands on the OpenClaw server.
|
|
3
|
+
* Uses the system `ssh` binary (OpenSSH, available on Windows 10+, macOS, Linux).
|
|
4
|
+
* No additional npm dependencies required.
|
|
5
|
+
*
|
|
6
|
+
* Set SSH_DEBUG=1 in your environment to enable verbose SSH output (-vvv).
|
|
7
|
+
*/
|
|
8
|
+
export interface SshConfig {
|
|
9
|
+
host: string;
|
|
10
|
+
port: number;
|
|
11
|
+
username: string;
|
|
12
|
+
/** Path to private key, ~ is expanded to os.homedir() */
|
|
13
|
+
keyPath: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Execute a shell command on the remote host and return stdout as a string.
|
|
17
|
+
* Throws if the command exits with a non-zero code or times out.
|
|
18
|
+
* On transient failures (exit 255), retries once after a short delay.
|
|
19
|
+
*/
|
|
20
|
+
export declare function sshExec(cfg: SshConfig, command: string, timeoutMs?: number): Promise<string>;
|
|
21
|
+
/** Read a file on the remote host. Returns empty string if file does not exist. */
|
|
22
|
+
export declare function sshReadFile(cfg: SshConfig, remotePath: string): Promise<string>;
|
|
23
|
+
/**
|
|
24
|
+
* Append content to a remote file, creating the directory if needed.
|
|
25
|
+
* Content is base64-encoded to survive shell escaping of special characters.
|
|
26
|
+
*/
|
|
27
|
+
export declare function sshAppendFile(cfg: SshConfig, remotePath: string, content: string): Promise<void>;
|
|
28
|
+
//# sourceMappingURL=ssh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssh.d.ts","sourceRoot":"","sources":["../src/ssh.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,OAAO,EAAE,MAAM,CAAC;CACjB;AAiCD;;;;GAIG;AACH,wBAAsB,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAYlG;AA4ED,mFAAmF;AACnF,wBAAsB,WAAW,CAAC,GAAG,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAErF;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAItG"}
|
package/dist/ssh.js
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SSH exec helper — runs shell commands on the OpenClaw server.
|
|
4
|
+
* Uses the system `ssh` binary (OpenSSH, available on Windows 10+, macOS, Linux).
|
|
5
|
+
* No additional npm dependencies required.
|
|
6
|
+
*
|
|
7
|
+
* Set SSH_DEBUG=1 in your environment to enable verbose SSH output (-vvv).
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.sshExec = sshExec;
|
|
44
|
+
exports.sshReadFile = sshReadFile;
|
|
45
|
+
exports.sshAppendFile = sshAppendFile;
|
|
46
|
+
const child_process_1 = require("child_process");
|
|
47
|
+
const os = __importStar(require("os"));
|
|
48
|
+
const path = __importStar(require("path"));
|
|
49
|
+
/**
|
|
50
|
+
* Resolve the SSH binary to a full path on Windows.
|
|
51
|
+
* Claude Desktop (MSIX) and Claude Code may have a different PATH than the
|
|
52
|
+
* user's interactive shell. We try known locations explicitly so we don't
|
|
53
|
+
* depend on PATH resolution inside a sandboxed child process.
|
|
54
|
+
*/
|
|
55
|
+
/**
|
|
56
|
+
* Build a PATH that guarantees the Windows native OpenSSH directory is included.
|
|
57
|
+
* Claude Desktop (MSIX) and Claude Code may strip PATH entries, so we add
|
|
58
|
+
* the known SSH locations explicitly.
|
|
59
|
+
*/
|
|
60
|
+
function sshEnv() {
|
|
61
|
+
const env = { ...process.env, HOME: os.homedir() };
|
|
62
|
+
if (process.platform === 'win32') {
|
|
63
|
+
const root = process.env['SystemRoot'] || 'C:\\Windows';
|
|
64
|
+
const sshDirs = [
|
|
65
|
+
path.join(root, 'System32', 'OpenSSH'),
|
|
66
|
+
path.join(root, 'Sysnative', 'OpenSSH'),
|
|
67
|
+
];
|
|
68
|
+
const currentPath = env['PATH'] || env['Path'] || '';
|
|
69
|
+
// Prepend SSH directories so they are found first
|
|
70
|
+
env['PATH'] = sshDirs.join(';') + ';' + currentPath;
|
|
71
|
+
}
|
|
72
|
+
return env;
|
|
73
|
+
}
|
|
74
|
+
/** Normalize a file path to forward slashes (SSH on Windows needs this). */
|
|
75
|
+
function normalizePath(p) {
|
|
76
|
+
return p.replace(/\\/g, '/');
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Execute a shell command on the remote host and return stdout as a string.
|
|
80
|
+
* Throws if the command exits with a non-zero code or times out.
|
|
81
|
+
* On transient failures (exit 255), retries once after a short delay.
|
|
82
|
+
*/
|
|
83
|
+
async function sshExec(cfg, command, timeoutMs = 15000) {
|
|
84
|
+
try {
|
|
85
|
+
return await sshExecOnce(cfg, command, timeoutMs);
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
// Retry once on exit 255 (connection-level failure, often transient on Windows)
|
|
89
|
+
const msg = err instanceof Error ? err.message : '';
|
|
90
|
+
if (msg.includes('exit 255')) {
|
|
91
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
92
|
+
return sshExecOnce(cfg, command, timeoutMs);
|
|
93
|
+
}
|
|
94
|
+
throw err;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function sshExecOnce(cfg, command, timeoutMs) {
|
|
98
|
+
return new Promise((resolve, reject) => {
|
|
99
|
+
// Expand ~ and normalize to forward slashes for cross-platform SSH compatibility
|
|
100
|
+
const keyPath = normalizePath(cfg.keyPath.replace(/^~/, os.homedir()));
|
|
101
|
+
const debug = process.env['SSH_DEBUG'] === '1';
|
|
102
|
+
const args = [
|
|
103
|
+
'-i', keyPath,
|
|
104
|
+
'-o', 'StrictHostKeyChecking=no',
|
|
105
|
+
'-o', 'UserKnownHostsFile=/dev/null', // prevent known_hosts divergence across SSH clients
|
|
106
|
+
'-o', 'BatchMode=yes',
|
|
107
|
+
'-o', 'ConnectTimeout=10',
|
|
108
|
+
'-o', 'ServerAliveInterval=5', // detect dead connections faster
|
|
109
|
+
'-o', 'ServerAliveCountMax=2',
|
|
110
|
+
'-p', String(cfg.port),
|
|
111
|
+
];
|
|
112
|
+
if (debug) {
|
|
113
|
+
args.push('-vvv');
|
|
114
|
+
}
|
|
115
|
+
args.push(`${cfg.username}@${cfg.host}`, command);
|
|
116
|
+
// Use plain 'ssh' and rely on PATH (augmented with known SSH dirs via sshEnv).
|
|
117
|
+
// No shell: true, no full path resolution. This avoids cmd.exe backslash escaping
|
|
118
|
+
// issues and WoW64 System32 redirection problems on Windows.
|
|
119
|
+
const proc = (0, child_process_1.spawn)('ssh', args, {
|
|
120
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
121
|
+
windowsHide: true,
|
|
122
|
+
env: sshEnv(),
|
|
123
|
+
});
|
|
124
|
+
let stdout = '';
|
|
125
|
+
let stderr = '';
|
|
126
|
+
proc.stdout.on('data', (d) => { stdout += d.toString(); });
|
|
127
|
+
proc.stderr.on('data', (d) => { stderr += d.toString(); });
|
|
128
|
+
const timer = setTimeout(() => {
|
|
129
|
+
proc.kill();
|
|
130
|
+
reject(new Error(`SSH timed out after ${timeoutMs}ms (host: ${cfg.host}:${cfg.port}, user: ${cfg.username}, key: ${keyPath})`));
|
|
131
|
+
}, timeoutMs);
|
|
132
|
+
proc.on('close', (code) => {
|
|
133
|
+
clearTimeout(timer);
|
|
134
|
+
if (code !== 0) {
|
|
135
|
+
const detail = stderr.trim() || stdout.trim() || 'no output from ssh';
|
|
136
|
+
const hint = code === 255
|
|
137
|
+
? ` | Tip: verify SSH_HOST (${cfg.host}), SSH_USER (${cfg.username}), SSH_KEY_PATH (${keyPath}) in your .env. Set SSH_DEBUG=1 for verbose logs.`
|
|
138
|
+
: '';
|
|
139
|
+
reject(new Error(`SSH failed (exit ${code}) connecting to ${cfg.username}@${cfg.host}:${cfg.port}: ${detail}${hint}`));
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
resolve(stdout);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
proc.on('error', (err) => {
|
|
146
|
+
clearTimeout(timer);
|
|
147
|
+
if (err.code === 'ENOENT') {
|
|
148
|
+
reject(new Error('ssh binary not found on PATH. ' +
|
|
149
|
+
'Windows: Settings > Optional Features > OpenSSH Client. ' +
|
|
150
|
+
'macOS/Linux: should be pre-installed.'));
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
reject(err);
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
/** Read a file on the remote host. Returns empty string if file does not exist. */
|
|
159
|
+
async function sshReadFile(cfg, remotePath) {
|
|
160
|
+
return sshExec(cfg, `cat ${remotePath} 2>/dev/null || true`);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Append content to a remote file, creating the directory if needed.
|
|
164
|
+
* Content is base64-encoded to survive shell escaping of special characters.
|
|
165
|
+
*/
|
|
166
|
+
async function sshAppendFile(cfg, remotePath, content) {
|
|
167
|
+
const encoded = Buffer.from(content).toString('base64');
|
|
168
|
+
const dir = remotePath.replace(/\/[^/]+$/, '');
|
|
169
|
+
await sshExec(cfg, `mkdir -p ${dir} && echo "${encoded}" | base64 -d >> ${remotePath}`);
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=ssh.js.map
|
package/dist/ssh.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssh.js","sourceRoot":"","sources":["../src/ssh.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex sub-agent tool.
|
|
3
|
+
*
|
|
4
|
+
* Uses the @openai/codex CLI in non-interactive mode:
|
|
5
|
+
* codex exec "<prompt>" --approval-mode never [--model <model>]
|
|
6
|
+
*
|
|
7
|
+
* Authentication: the CLI uses locally cached OpenAI credentials
|
|
8
|
+
* (from `codex login`). No OPENAI_API_KEY env var required if logged in.
|
|
9
|
+
*
|
|
10
|
+
* Output behavior (codex exec):
|
|
11
|
+
* - Progress and tool calls stream to stderr (silently collected)
|
|
12
|
+
* - Final agent message is printed to stdout as plain text
|
|
13
|
+
*
|
|
14
|
+
* Use --approval-mode never for non-interactive operation (no pausing for
|
|
15
|
+
* human approval before executing shell commands). Codex may still read and
|
|
16
|
+
* write files on the machine running the MCP server — use accordingly.
|
|
17
|
+
*
|
|
18
|
+
* Use cases vs openclaw_run / gemini_run:
|
|
19
|
+
* - Coding tasks: refactoring, debugging, code generation (Codex specializes here)
|
|
20
|
+
* - OpenAI model stack (o3, gpt-5-codex, etc.)
|
|
21
|
+
* - Long agentic tasks that require multiple tool calls (file read/write, shell)
|
|
22
|
+
*/
|
|
23
|
+
import { z } from 'zod';
|
|
24
|
+
import { Config } from '../config.js';
|
|
25
|
+
export declare const codexRunSchema: z.ZodObject<{
|
|
26
|
+
prompt: z.ZodString;
|
|
27
|
+
model: z.ZodOptional<z.ZodString>;
|
|
28
|
+
approval_mode: z.ZodDefault<z.ZodEnum<["never", "on-request"]>>;
|
|
29
|
+
timeout_seconds: z.ZodDefault<z.ZodNumber>;
|
|
30
|
+
}, "strip", z.ZodTypeAny, {
|
|
31
|
+
prompt: string;
|
|
32
|
+
timeout_seconds: number;
|
|
33
|
+
approval_mode: "never" | "on-request";
|
|
34
|
+
model?: string | undefined;
|
|
35
|
+
}, {
|
|
36
|
+
prompt: string;
|
|
37
|
+
timeout_seconds?: number | undefined;
|
|
38
|
+
model?: string | undefined;
|
|
39
|
+
approval_mode?: "never" | "on-request" | undefined;
|
|
40
|
+
}>;
|
|
41
|
+
export declare function handleCodexRun(args: {
|
|
42
|
+
prompt: string;
|
|
43
|
+
model?: string;
|
|
44
|
+
approval_mode: 'never' | 'on-request';
|
|
45
|
+
timeout_seconds: number;
|
|
46
|
+
}, config: Config): Promise<{
|
|
47
|
+
success: boolean;
|
|
48
|
+
error: string;
|
|
49
|
+
hint: string;
|
|
50
|
+
response?: undefined;
|
|
51
|
+
model?: undefined;
|
|
52
|
+
approval_mode?: undefined;
|
|
53
|
+
} | {
|
|
54
|
+
success: boolean;
|
|
55
|
+
response: string;
|
|
56
|
+
model: string;
|
|
57
|
+
approval_mode: "never" | "on-request";
|
|
58
|
+
error?: undefined;
|
|
59
|
+
hint?: undefined;
|
|
60
|
+
}>;
|
|
61
|
+
//# sourceMappingURL=codex.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/tools/codex.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAKtC,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;EAgBzB,CAAC;AAIH,wBAAsB,cAAc,CAClC,IAAI,EAAE;IACJ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,OAAO,GAAG,YAAY,CAAC;IACtC,eAAe,EAAE,MAAM,CAAC;CACzB,EACD,MAAM,EAAE,MAAM;;;;;;;;;;;;;;GAuBf"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Codex sub-agent tool.
|
|
4
|
+
*
|
|
5
|
+
* Uses the @openai/codex CLI in non-interactive mode:
|
|
6
|
+
* codex exec "<prompt>" --approval-mode never [--model <model>]
|
|
7
|
+
*
|
|
8
|
+
* Authentication: the CLI uses locally cached OpenAI credentials
|
|
9
|
+
* (from `codex login`). No OPENAI_API_KEY env var required if logged in.
|
|
10
|
+
*
|
|
11
|
+
* Output behavior (codex exec):
|
|
12
|
+
* - Progress and tool calls stream to stderr (silently collected)
|
|
13
|
+
* - Final agent message is printed to stdout as plain text
|
|
14
|
+
*
|
|
15
|
+
* Use --approval-mode never for non-interactive operation (no pausing for
|
|
16
|
+
* human approval before executing shell commands). Codex may still read and
|
|
17
|
+
* write files on the machine running the MCP server — use accordingly.
|
|
18
|
+
*
|
|
19
|
+
* Use cases vs openclaw_run / gemini_run:
|
|
20
|
+
* - Coding tasks: refactoring, debugging, code generation (Codex specializes here)
|
|
21
|
+
* - OpenAI model stack (o3, gpt-5-codex, etc.)
|
|
22
|
+
* - Long agentic tasks that require multiple tool calls (file read/write, shell)
|
|
23
|
+
*/
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.codexRunSchema = void 0;
|
|
26
|
+
exports.handleCodexRun = handleCodexRun;
|
|
27
|
+
const zod_1 = require("zod");
|
|
28
|
+
const spawn_js_1 = require("../spawn.js");
|
|
29
|
+
// --- Schemas ---
|
|
30
|
+
exports.codexRunSchema = zod_1.z.object({
|
|
31
|
+
prompt: zod_1.z.string().describe('Task or question to send to the Codex AI agent. ' +
|
|
32
|
+
'Works best for coding tasks, file operations, and technical analysis.'),
|
|
33
|
+
model: zod_1.z.string().optional().describe('OpenAI model to use, e.g. "o3", "gpt-5-codex". ' +
|
|
34
|
+
'Omit to use the configured default (CODEX_MODEL env var or Codex default).'),
|
|
35
|
+
approval_mode: zod_1.z.enum(['never', 'on-request']).default('never').describe('"never": runs all commands without pausing (non-interactive, default). ' +
|
|
36
|
+
'"on-request": pauses for approval before shell commands — not suitable for automation.'),
|
|
37
|
+
timeout_seconds: zod_1.z.number().min(10).max(600).default(120).describe('Max seconds to wait. Codex tasks can take longer than Gemini — 120s default.'),
|
|
38
|
+
});
|
|
39
|
+
// --- Handler ---
|
|
40
|
+
async function handleCodexRun(args, config) {
|
|
41
|
+
const model = args.model ?? config.codexModel;
|
|
42
|
+
const cliArgs = ['exec', args.prompt, '--approval-mode', args.approval_mode];
|
|
43
|
+
if (model)
|
|
44
|
+
cliArgs.push('--model', model);
|
|
45
|
+
let response;
|
|
46
|
+
try {
|
|
47
|
+
response = await (0, spawn_js_1.spawnLocal)('codex', cliArgs, args.timeout_seconds * 1000);
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
return {
|
|
51
|
+
success: false,
|
|
52
|
+
error: String(err),
|
|
53
|
+
hint: 'Run `codex login` to authenticate, or check `codex --version` to confirm the CLI is installed.',
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
success: true,
|
|
58
|
+
response: response.trim(),
|
|
59
|
+
model: model ?? 'default',
|
|
60
|
+
approval_mode: args.approval_mode,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=codex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/tools/codex.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;;;AA4BH,wCA8BC;AAxDD,6BAAwB;AAExB,0CAAyC;AAEzC,kBAAkB;AAEL,QAAA,cAAc,GAAG,OAAC,CAAC,MAAM,CAAC;IACrC,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CACzB,kDAAkD;QAClD,uEAAuE,CACxE;IACD,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CACnC,iDAAiD;QACjD,4EAA4E,CAC7E;IACD,aAAa,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,QAAQ,CACtE,yEAAyE;QACzE,wFAAwF,CACzF;IACD,eAAe,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,CAChE,8EAA8E,CAC/E;CACF,CAAC,CAAC;AAEH,kBAAkB;AAEX,KAAK,UAAU,cAAc,CAClC,IAKC,EACD,MAAc;IAEd,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,UAAU,CAAC;IAC9C,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,iBAAiB,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IAC7E,IAAI,KAAK;QAAE,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAE1C,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,IAAA,qBAAU,EAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IAC7E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC;YAClB,IAAI,EAAE,gGAAgG;SACvG,CAAC;IACJ,CAAC;IAED,OAAO;QACL,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE;QACzB,KAAK,EAAE,KAAK,IAAI,SAAS;QACzB,aAAa,EAAE,IAAI,CAAC,aAAa;KAClC,CAAC;AACJ,CAAC"}
|