replicas-cli 0.2.29 → 0.2.30
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 +60 -48
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1662,8 +1662,12 @@ function safeJsonParse(str, fallback) {
|
|
|
1662
1662
|
function getStatusFromExitCode(exitCode) {
|
|
1663
1663
|
return exitCode === 0 ? "completed" : "failed";
|
|
1664
1664
|
}
|
|
1665
|
-
function
|
|
1666
|
-
|
|
1665
|
+
function parseShellOutput(raw) {
|
|
1666
|
+
const exitCodeMatch = raw.match(/^Exit code: (\d+)/);
|
|
1667
|
+
const exitCode = exitCodeMatch ? parseInt(exitCodeMatch[1], 10) : 0;
|
|
1668
|
+
const outputIndex = raw.indexOf("Output:\n");
|
|
1669
|
+
const output = outputIndex >= 0 ? raw.slice(outputIndex + "Output:\n".length) : raw;
|
|
1670
|
+
return { exitCode, output };
|
|
1667
1671
|
}
|
|
1668
1672
|
function parsePatch(input) {
|
|
1669
1673
|
const operations = [];
|
|
@@ -1720,11 +1724,12 @@ function parsePatch(input) {
|
|
|
1720
1724
|
}
|
|
1721
1725
|
function parseCodexEvents(events) {
|
|
1722
1726
|
const messages = [];
|
|
1727
|
+
const pendingCommands = /* @__PURE__ */ new Map();
|
|
1723
1728
|
const pendingPatches = /* @__PURE__ */ new Map();
|
|
1724
|
-
events.forEach((event) => {
|
|
1729
|
+
events.forEach((event, eventIndex) => {
|
|
1725
1730
|
if (event.type === "event_msg" && event.payload?.type === "user_message") {
|
|
1726
1731
|
messages.push({
|
|
1727
|
-
id: `user-${event.timestamp}`,
|
|
1732
|
+
id: `user-${event.timestamp}-${eventIndex}`,
|
|
1728
1733
|
type: "user",
|
|
1729
1734
|
content: event.payload.message || "",
|
|
1730
1735
|
timestamp: event.timestamp
|
|
@@ -1732,7 +1737,7 @@ function parseCodexEvents(events) {
|
|
|
1732
1737
|
}
|
|
1733
1738
|
if (event.type === "event_msg" && event.payload?.type === "agent_reasoning") {
|
|
1734
1739
|
messages.push({
|
|
1735
|
-
id: `reasoning-${event.timestamp}-${messages.length}`,
|
|
1740
|
+
id: `reasoning-${event.timestamp}-${eventIndex}-${messages.length}`,
|
|
1736
1741
|
type: "reasoning",
|
|
1737
1742
|
content: event.payload.text || "",
|
|
1738
1743
|
status: "completed",
|
|
@@ -1746,38 +1751,40 @@ function parseCodexEvents(events) {
|
|
|
1746
1751
|
const textContent = content.filter((c) => c.type === "output_text").map((c) => c.text || "").join("\n");
|
|
1747
1752
|
if (textContent) {
|
|
1748
1753
|
messages.push({
|
|
1749
|
-
id: `agent-${event.timestamp}`,
|
|
1754
|
+
id: `agent-${event.timestamp}-${eventIndex}`,
|
|
1750
1755
|
type: "agent",
|
|
1751
1756
|
content: textContent,
|
|
1752
1757
|
timestamp: event.timestamp
|
|
1753
1758
|
});
|
|
1754
1759
|
}
|
|
1755
1760
|
}
|
|
1756
|
-
if (payloadType === "function_call" && event.payload?.name === "shell") {
|
|
1761
|
+
if (payloadType === "function_call" && (event.payload?.name === "shell" || event.payload?.name === "shell_command")) {
|
|
1762
|
+
const callId = event.payload.call_id;
|
|
1757
1763
|
const args = safeJsonParse(event.payload.arguments || "{}", {});
|
|
1758
1764
|
const command = Array.isArray(args.command) ? args.command.join(" ") : args.command || "";
|
|
1759
|
-
|
|
1760
|
-
id: `command-${
|
|
1765
|
+
const msg = {
|
|
1766
|
+
id: `command-${callId || "no-call-id"}-${eventIndex}`,
|
|
1761
1767
|
type: "command",
|
|
1762
1768
|
command,
|
|
1763
1769
|
output: "",
|
|
1764
|
-
// Will be filled by function_call_output
|
|
1765
1770
|
status: "in_progress",
|
|
1766
1771
|
timestamp: event.timestamp
|
|
1767
|
-
}
|
|
1772
|
+
};
|
|
1773
|
+
messages.push(msg);
|
|
1774
|
+
if (callId) {
|
|
1775
|
+
pendingCommands.set(callId, msg);
|
|
1776
|
+
}
|
|
1768
1777
|
}
|
|
1769
1778
|
if (payloadType === "function_call_output") {
|
|
1770
|
-
const
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
)
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
commandMsg.status = getStatusFromExitCode(output.metadata?.exit_code);
|
|
1780
|
-
}
|
|
1779
|
+
const callId = event.payload.call_id;
|
|
1780
|
+
const rawOutput = event.payload.output || "";
|
|
1781
|
+
const commandMsg = callId ? pendingCommands.get(callId) : void 0;
|
|
1782
|
+
if (commandMsg) {
|
|
1783
|
+
const { exitCode, output } = parseShellOutput(rawOutput);
|
|
1784
|
+
commandMsg.output = output;
|
|
1785
|
+
commandMsg.exitCode = exitCode;
|
|
1786
|
+
commandMsg.status = getStatusFromExitCode(exitCode);
|
|
1787
|
+
pendingCommands.delete(callId);
|
|
1781
1788
|
}
|
|
1782
1789
|
}
|
|
1783
1790
|
if (payloadType === "custom_tool_call") {
|
|
@@ -1790,7 +1797,7 @@ function parseCodexEvents(events) {
|
|
|
1790
1797
|
pendingPatches.set(callId, { input, status, timestamp: event.timestamp, operations });
|
|
1791
1798
|
} else {
|
|
1792
1799
|
messages.push({
|
|
1793
|
-
id: `toolcall-${event.timestamp}`,
|
|
1800
|
+
id: `toolcall-${event.timestamp}-${eventIndex}`,
|
|
1794
1801
|
type: "tool_call",
|
|
1795
1802
|
server: "custom",
|
|
1796
1803
|
tool: name,
|
|
@@ -1808,7 +1815,7 @@ function parseCodexEvents(events) {
|
|
|
1808
1815
|
const pendingPatch = pendingPatches.get(callId);
|
|
1809
1816
|
if (pendingPatch) {
|
|
1810
1817
|
messages.push({
|
|
1811
|
-
id: `patch-${pendingPatch.timestamp}`,
|
|
1818
|
+
id: `patch-${pendingPatch.timestamp}-${eventIndex}`,
|
|
1812
1819
|
type: "patch",
|
|
1813
1820
|
operations: pendingPatch.operations,
|
|
1814
1821
|
output: output.output || "",
|
|
@@ -1818,7 +1825,7 @@ function parseCodexEvents(events) {
|
|
|
1818
1825
|
});
|
|
1819
1826
|
pendingPatches.delete(callId);
|
|
1820
1827
|
} else {
|
|
1821
|
-
const toolCallMsg =
|
|
1828
|
+
const toolCallMsg = messages.findLast((m) => m.type === "tool_call");
|
|
1822
1829
|
if (toolCallMsg) {
|
|
1823
1830
|
toolCallMsg.status = getStatusFromExitCode(output.metadata?.exit_code);
|
|
1824
1831
|
}
|
|
@@ -1835,7 +1842,7 @@ function parseCodexEvents(events) {
|
|
|
1835
1842
|
completed: item.status === "completed"
|
|
1836
1843
|
}));
|
|
1837
1844
|
messages.push({
|
|
1838
|
-
id: `todo-${event.timestamp}`,
|
|
1845
|
+
id: `todo-${event.timestamp}-${eventIndex}`,
|
|
1839
1846
|
type: "todo_list",
|
|
1840
1847
|
items: todoItems,
|
|
1841
1848
|
status: "completed",
|
|
@@ -2195,15 +2202,15 @@ Replicas (Page ${response.page} of ${response.totalPages}, Total: ${response.tot
|
|
|
2195
2202
|
for (const replica of response.replicas) {
|
|
2196
2203
|
console.log(import_chalk15.default.white(` ${replica.name}`));
|
|
2197
2204
|
console.log(import_chalk15.default.gray(` ID: ${replica.id}`));
|
|
2198
|
-
if (replica.
|
|
2199
|
-
console.log(import_chalk15.default.gray(`
|
|
2205
|
+
if (replica.repositories.length > 0) {
|
|
2206
|
+
console.log(import_chalk15.default.gray(` Repositories: ${replica.repositories.map((repository) => repository.name).join(", ")}`));
|
|
2200
2207
|
}
|
|
2201
2208
|
console.log(import_chalk15.default.gray(` Status: ${formatStatus(replica.status)}`));
|
|
2202
2209
|
console.log(import_chalk15.default.gray(` Created: ${formatDate(replica.created_at)}`));
|
|
2203
2210
|
if (replica.pull_requests && replica.pull_requests.length > 0) {
|
|
2204
2211
|
console.log(import_chalk15.default.gray(` Pull Requests:`));
|
|
2205
2212
|
for (const pr of replica.pull_requests) {
|
|
2206
|
-
console.log(import_chalk15.default.cyan(` - #${pr.number}: ${pr.url}`));
|
|
2213
|
+
console.log(import_chalk15.default.cyan(` - ${pr.repository} #${pr.number}: ${pr.url}`));
|
|
2207
2214
|
}
|
|
2208
2215
|
}
|
|
2209
2216
|
console.log();
|
|
@@ -2225,8 +2232,8 @@ async function replicaGetCommand(id) {
|
|
|
2225
2232
|
Replica: ${replica.name}
|
|
2226
2233
|
`));
|
|
2227
2234
|
console.log(import_chalk15.default.gray(` ID: ${replica.id}`));
|
|
2228
|
-
if (replica.
|
|
2229
|
-
console.log(import_chalk15.default.gray(`
|
|
2235
|
+
if (replica.repositories.length > 0) {
|
|
2236
|
+
console.log(import_chalk15.default.gray(` Repositories: ${replica.repositories.map((repository) => repository.name).join(", ")}`));
|
|
2230
2237
|
}
|
|
2231
2238
|
console.log(import_chalk15.default.gray(` Status: ${formatStatus(replica.status)}`));
|
|
2232
2239
|
console.log(import_chalk15.default.gray(` Created: ${formatDate(replica.created_at)}`));
|
|
@@ -2236,17 +2243,18 @@ Replica: ${replica.name}
|
|
|
2236
2243
|
if (replica.coding_agent) {
|
|
2237
2244
|
console.log(import_chalk15.default.gray(` Coding Agent: ${replica.coding_agent}`));
|
|
2238
2245
|
}
|
|
2239
|
-
if (replica.
|
|
2240
|
-
console.log(import_chalk15.default.gray(
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2246
|
+
if (replica.repository_statuses && replica.repository_statuses.length > 0) {
|
|
2247
|
+
console.log(import_chalk15.default.gray(" Repository Statuses:"));
|
|
2248
|
+
for (const repositoryStatus of replica.repository_statuses) {
|
|
2249
|
+
const changeText = repositoryStatus.git_diff ? ` (${import_chalk15.default.green(`+${repositoryStatus.git_diff.added}`)} / ${import_chalk15.default.red(`-${repositoryStatus.git_diff.removed}`)})` : "";
|
|
2250
|
+
console.log(import_chalk15.default.gray(` - ${repositoryStatus.repository}: ${repositoryStatus.branch || "unknown"}${changeText}`));
|
|
2251
|
+
}
|
|
2244
2252
|
}
|
|
2245
2253
|
}
|
|
2246
2254
|
if (replica.pull_requests && replica.pull_requests.length > 0) {
|
|
2247
2255
|
console.log(import_chalk15.default.gray(` Pull Requests:`));
|
|
2248
2256
|
for (const pr of replica.pull_requests) {
|
|
2249
|
-
console.log(import_chalk15.default.cyan(` - #${pr.number}: ${pr.url}`));
|
|
2257
|
+
console.log(import_chalk15.default.cyan(` - ${pr.repository} #${pr.number}: ${pr.url}`));
|
|
2250
2258
|
}
|
|
2251
2259
|
}
|
|
2252
2260
|
console.log();
|
|
@@ -2269,7 +2277,7 @@ async function replicaCreateCommand(name, options) {
|
|
|
2269
2277
|
}
|
|
2270
2278
|
let replicaName = name;
|
|
2271
2279
|
let message = options.message;
|
|
2272
|
-
let
|
|
2280
|
+
let selectedRepositories = options.repositories?.split(",").map((repository) => repository.trim()).filter((repository) => repository.length > 0);
|
|
2273
2281
|
let codingAgent = options.agent;
|
|
2274
2282
|
if (replicaName && /\s/.test(replicaName)) {
|
|
2275
2283
|
console.log(import_chalk15.default.red("Replica name cannot contain spaces."));
|
|
@@ -2292,22 +2300,23 @@ async function replicaCreateCommand(name, options) {
|
|
|
2292
2300
|
}
|
|
2293
2301
|
replicaName = response2.name;
|
|
2294
2302
|
}
|
|
2295
|
-
if (!
|
|
2303
|
+
if (!selectedRepositories || selectedRepositories.length === 0) {
|
|
2296
2304
|
const response2 = await (0, import_prompts3.default)({
|
|
2297
|
-
type: "
|
|
2298
|
-
name: "
|
|
2299
|
-
message: "Select
|
|
2305
|
+
type: "multiselect",
|
|
2306
|
+
name: "repositories",
|
|
2307
|
+
message: "Select repositories:",
|
|
2300
2308
|
choices: repositories.map((repo) => ({
|
|
2301
2309
|
title: repo.name,
|
|
2302
2310
|
value: repo.name,
|
|
2303
2311
|
description: repo.url
|
|
2304
|
-
}))
|
|
2312
|
+
})),
|
|
2313
|
+
min: 1
|
|
2305
2314
|
});
|
|
2306
|
-
if (!response2.
|
|
2315
|
+
if (!response2.repositories || response2.repositories.length === 0) {
|
|
2307
2316
|
console.log(import_chalk15.default.yellow("\nCancelled."));
|
|
2308
2317
|
return;
|
|
2309
2318
|
}
|
|
2310
|
-
|
|
2319
|
+
selectedRepositories = response2.repositories;
|
|
2311
2320
|
}
|
|
2312
2321
|
if (!message) {
|
|
2313
2322
|
const response2 = await (0, import_prompts3.default)({
|
|
@@ -2346,7 +2355,7 @@ async function replicaCreateCommand(name, options) {
|
|
|
2346
2355
|
const body = {
|
|
2347
2356
|
name: replicaName,
|
|
2348
2357
|
message,
|
|
2349
|
-
|
|
2358
|
+
repositories: selectedRepositories,
|
|
2350
2359
|
coding_agent: codingAgent
|
|
2351
2360
|
};
|
|
2352
2361
|
console.log(import_chalk15.default.gray("\nCreating replica..."));
|
|
@@ -2359,6 +2368,9 @@ async function replicaCreateCommand(name, options) {
|
|
|
2359
2368
|
Created replica: ${replica.name}`));
|
|
2360
2369
|
console.log(import_chalk15.default.gray(` ID: ${replica.id}`));
|
|
2361
2370
|
console.log(import_chalk15.default.gray(` Status: ${formatStatus(replica.status)}`));
|
|
2371
|
+
if (replica.repositories.length > 0) {
|
|
2372
|
+
console.log(import_chalk15.default.gray(` Repositories: ${replica.repositories.map((repository) => repository.name).join(", ")}`));
|
|
2373
|
+
}
|
|
2362
2374
|
console.log();
|
|
2363
2375
|
} catch (error) {
|
|
2364
2376
|
console.error(import_chalk15.default.red(`Error: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
@@ -2529,7 +2541,7 @@ Repositories (${response.repositories.length}):
|
|
|
2529
2541
|
}
|
|
2530
2542
|
|
|
2531
2543
|
// src/index.ts
|
|
2532
|
-
var CLI_VERSION = "0.2.
|
|
2544
|
+
var CLI_VERSION = "0.2.30";
|
|
2533
2545
|
var program = new import_commander.Command();
|
|
2534
2546
|
program.name("replicas").description("CLI for managing Replicas workspaces").version(CLI_VERSION);
|
|
2535
2547
|
program.command("login").description("Authenticate with your Replicas account").action(async () => {
|
|
@@ -2726,7 +2738,7 @@ program.command("get <id>").description("Get replica details by ID").action(asyn
|
|
|
2726
2738
|
process.exit(1);
|
|
2727
2739
|
}
|
|
2728
2740
|
});
|
|
2729
|
-
program.command("create [name]").description("Create a new replica").option("-m, --message <message>", "Initial message for the replica").option("-r, --
|
|
2741
|
+
program.command("create [name]").description("Create a new replica").option("-m, --message <message>", "Initial message for the replica").option("-r, --repositories <repositories>", "Comma-separated repository names").option("-a, --agent <agent>", "Coding agent (claude, codex)").action(async (name, options) => {
|
|
2730
2742
|
try {
|
|
2731
2743
|
await replicaCreateCommand(name, options);
|
|
2732
2744
|
} catch (error) {
|