replicas-mcp 0.1.6 → 0.1.7
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/dist/index.js +35 -28
- package/package.json +1 -1
- package/src/index.ts +4 -4
package/dist/index.js
CHANGED
|
@@ -24,8 +24,12 @@ function safeJsonParse(str, fallback) {
|
|
|
24
24
|
function getStatusFromExitCode(exitCode) {
|
|
25
25
|
return exitCode === 0 ? "completed" : "failed";
|
|
26
26
|
}
|
|
27
|
-
function
|
|
28
|
-
|
|
27
|
+
function parseShellOutput(raw) {
|
|
28
|
+
const exitCodeMatch = raw.match(/^Exit code: (\d+)/);
|
|
29
|
+
const exitCode = exitCodeMatch ? parseInt(exitCodeMatch[1], 10) : 0;
|
|
30
|
+
const outputIndex = raw.indexOf("Output:\n");
|
|
31
|
+
const output = outputIndex >= 0 ? raw.slice(outputIndex + "Output:\n".length) : raw;
|
|
32
|
+
return { exitCode, output };
|
|
29
33
|
}
|
|
30
34
|
function parsePatch(input) {
|
|
31
35
|
const operations = [];
|
|
@@ -82,11 +86,12 @@ function parsePatch(input) {
|
|
|
82
86
|
}
|
|
83
87
|
function parseCodexEvents(events) {
|
|
84
88
|
const messages = [];
|
|
89
|
+
const pendingCommands = /* @__PURE__ */ new Map();
|
|
85
90
|
const pendingPatches = /* @__PURE__ */ new Map();
|
|
86
|
-
events.forEach((event) => {
|
|
91
|
+
events.forEach((event, eventIndex) => {
|
|
87
92
|
if (event.type === "event_msg" && event.payload?.type === "user_message") {
|
|
88
93
|
messages.push({
|
|
89
|
-
id: `user-${event.timestamp}`,
|
|
94
|
+
id: `user-${event.timestamp}-${eventIndex}`,
|
|
90
95
|
type: "user",
|
|
91
96
|
content: event.payload.message || "",
|
|
92
97
|
timestamp: event.timestamp
|
|
@@ -94,7 +99,7 @@ function parseCodexEvents(events) {
|
|
|
94
99
|
}
|
|
95
100
|
if (event.type === "event_msg" && event.payload?.type === "agent_reasoning") {
|
|
96
101
|
messages.push({
|
|
97
|
-
id: `reasoning-${event.timestamp}-${messages.length}`,
|
|
102
|
+
id: `reasoning-${event.timestamp}-${eventIndex}-${messages.length}`,
|
|
98
103
|
type: "reasoning",
|
|
99
104
|
content: event.payload.text || "",
|
|
100
105
|
status: "completed",
|
|
@@ -108,38 +113,40 @@ function parseCodexEvents(events) {
|
|
|
108
113
|
const textContent = content.filter((c) => c.type === "output_text").map((c) => c.text || "").join("\n");
|
|
109
114
|
if (textContent) {
|
|
110
115
|
messages.push({
|
|
111
|
-
id: `agent-${event.timestamp}`,
|
|
116
|
+
id: `agent-${event.timestamp}-${eventIndex}`,
|
|
112
117
|
type: "agent",
|
|
113
118
|
content: textContent,
|
|
114
119
|
timestamp: event.timestamp
|
|
115
120
|
});
|
|
116
121
|
}
|
|
117
122
|
}
|
|
118
|
-
if (payloadType === "function_call" && event.payload?.name === "shell") {
|
|
123
|
+
if (payloadType === "function_call" && (event.payload?.name === "shell" || event.payload?.name === "shell_command")) {
|
|
124
|
+
const callId = event.payload.call_id;
|
|
119
125
|
const args = safeJsonParse(event.payload.arguments || "{}", {});
|
|
120
126
|
const command = Array.isArray(args.command) ? args.command.join(" ") : args.command || "";
|
|
121
|
-
|
|
122
|
-
id: `command-${
|
|
127
|
+
const msg = {
|
|
128
|
+
id: `command-${callId || "no-call-id"}-${eventIndex}`,
|
|
123
129
|
type: "command",
|
|
124
130
|
command,
|
|
125
131
|
output: "",
|
|
126
|
-
// Will be filled by function_call_output
|
|
127
132
|
status: "in_progress",
|
|
128
133
|
timestamp: event.timestamp
|
|
129
|
-
}
|
|
134
|
+
};
|
|
135
|
+
messages.push(msg);
|
|
136
|
+
if (callId) {
|
|
137
|
+
pendingCommands.set(callId, msg);
|
|
138
|
+
}
|
|
130
139
|
}
|
|
131
140
|
if (payloadType === "function_call_output") {
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
)
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
commandMsg.status = getStatusFromExitCode(output.metadata?.exit_code);
|
|
142
|
-
}
|
|
141
|
+
const callId = event.payload.call_id;
|
|
142
|
+
const rawOutput = event.payload.output || "";
|
|
143
|
+
const commandMsg = callId ? pendingCommands.get(callId) : void 0;
|
|
144
|
+
if (commandMsg) {
|
|
145
|
+
const { exitCode, output } = parseShellOutput(rawOutput);
|
|
146
|
+
commandMsg.output = output;
|
|
147
|
+
commandMsg.exitCode = exitCode;
|
|
148
|
+
commandMsg.status = getStatusFromExitCode(exitCode);
|
|
149
|
+
pendingCommands.delete(callId);
|
|
143
150
|
}
|
|
144
151
|
}
|
|
145
152
|
if (payloadType === "custom_tool_call") {
|
|
@@ -152,7 +159,7 @@ function parseCodexEvents(events) {
|
|
|
152
159
|
pendingPatches.set(callId, { input, status, timestamp: event.timestamp, operations });
|
|
153
160
|
} else {
|
|
154
161
|
messages.push({
|
|
155
|
-
id: `toolcall-${event.timestamp}`,
|
|
162
|
+
id: `toolcall-${event.timestamp}-${eventIndex}`,
|
|
156
163
|
type: "tool_call",
|
|
157
164
|
server: "custom",
|
|
158
165
|
tool: name,
|
|
@@ -170,7 +177,7 @@ function parseCodexEvents(events) {
|
|
|
170
177
|
const pendingPatch = pendingPatches.get(callId);
|
|
171
178
|
if (pendingPatch) {
|
|
172
179
|
messages.push({
|
|
173
|
-
id: `patch-${pendingPatch.timestamp}`,
|
|
180
|
+
id: `patch-${pendingPatch.timestamp}-${eventIndex}`,
|
|
174
181
|
type: "patch",
|
|
175
182
|
operations: pendingPatch.operations,
|
|
176
183
|
output: output.output || "",
|
|
@@ -180,7 +187,7 @@ function parseCodexEvents(events) {
|
|
|
180
187
|
});
|
|
181
188
|
pendingPatches.delete(callId);
|
|
182
189
|
} else {
|
|
183
|
-
const toolCallMsg =
|
|
190
|
+
const toolCallMsg = messages.findLast((m) => m.type === "tool_call");
|
|
184
191
|
if (toolCallMsg) {
|
|
185
192
|
toolCallMsg.status = getStatusFromExitCode(output.metadata?.exit_code);
|
|
186
193
|
}
|
|
@@ -197,7 +204,7 @@ function parseCodexEvents(events) {
|
|
|
197
204
|
completed: item.status === "completed"
|
|
198
205
|
}));
|
|
199
206
|
messages.push({
|
|
200
|
-
id: `todo-${event.timestamp}`,
|
|
207
|
+
id: `todo-${event.timestamp}-${eventIndex}`,
|
|
201
208
|
type: "todo_list",
|
|
202
209
|
items: todoItems,
|
|
203
210
|
status: "completed",
|
|
@@ -477,7 +484,7 @@ registerTool(
|
|
|
477
484
|
inputSchema: {
|
|
478
485
|
name: z.string().regex(/^\S+$/, "Name cannot contain spaces"),
|
|
479
486
|
message: z.string(),
|
|
480
|
-
|
|
487
|
+
repositories: z.array(z.string()).min(1),
|
|
481
488
|
coding_agent: z.enum(["claude", "codex"]).optional()
|
|
482
489
|
}
|
|
483
490
|
},
|
|
@@ -486,7 +493,7 @@ registerTool(
|
|
|
486
493
|
const body = {
|
|
487
494
|
name: args.name,
|
|
488
495
|
message: args.message,
|
|
489
|
-
|
|
496
|
+
repositories: args.repositories
|
|
490
497
|
};
|
|
491
498
|
if (args.coding_agent) body.coding_agent = args.coding_agent;
|
|
492
499
|
return result(await api("POST", "/v1/replica", body));
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
|
2
2
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
5
|
-
import { parseAgentEvents, type
|
|
5
|
+
import { parseAgentEvents, type AgentProvider, type ReadReplicaHistoryResponse } from '@replicas/shared';
|
|
6
6
|
|
|
7
7
|
const API_URL = process.env.REPLICAS_API_URL || 'https://api.replicas.dev';
|
|
8
8
|
const API_KEY = process.env.REPLICAS_API_KEY;
|
|
@@ -69,7 +69,7 @@ registerTool(
|
|
|
69
69
|
inputSchema: {
|
|
70
70
|
name: z.string().regex(/^\S+$/, 'Name cannot contain spaces'),
|
|
71
71
|
message: z.string(),
|
|
72
|
-
|
|
72
|
+
repositories: z.array(z.string()).min(1),
|
|
73
73
|
coding_agent: z.enum(['claude', 'codex']).optional(),
|
|
74
74
|
},
|
|
75
75
|
},
|
|
@@ -78,7 +78,7 @@ registerTool(
|
|
|
78
78
|
const body: Record<string, unknown> = {
|
|
79
79
|
name: args.name,
|
|
80
80
|
message: args.message,
|
|
81
|
-
|
|
81
|
+
repositories: args.repositories,
|
|
82
82
|
};
|
|
83
83
|
if (args.coding_agent) body.coding_agent = args.coding_agent;
|
|
84
84
|
return result(await api('POST', '/v1/replica', body));
|
|
@@ -205,7 +205,7 @@ registerTool(
|
|
|
205
205
|
}
|
|
206
206
|
|
|
207
207
|
// Parse raw events into DisplayMessage format
|
|
208
|
-
const agentType = (response.coding_agent || 'claude') as
|
|
208
|
+
const agentType = (response.coding_agent || 'claude') as AgentProvider;
|
|
209
209
|
const messages = parseAgentEvents(response.events, agentType);
|
|
210
210
|
|
|
211
211
|
return result({
|