replicas-cli 0.2.322 → 0.2.324
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.mjs +79 -15
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -8026,7 +8026,7 @@ Prints the live noVNC viewer URL (\`https://6080-<hash>.tryreplicas.com/\`) for
|
|
|
8026
8026
|
If invoked very early in the workspace lifecycle, \`info\` will poll briefly while the engine finishes registering the preview, then error if it's still not available.
|
|
8027
8027
|
|
|
8028
8028
|
### \`replicas computer status\`
|
|
8029
|
-
|
|
8029
|
+
Checks and repairs the desktop bridge, then prints which desktop services are running and the active preview URL (if any). Useful for debugging when a tool call seems to be doing nothing.
|
|
8030
8030
|
|
|
8031
8031
|
### \`replicas computer screenshot <path> [--raw] [--grid [px]]\`
|
|
8032
8032
|
Captures the current desktop to a PNG at the given path.
|
|
@@ -8143,7 +8143,7 @@ Then embed the printed \`\` line in your chat reply. See \`MEDI
|
|
|
8143
8143
|
## Failure modes
|
|
8144
8144
|
|
|
8145
8145
|
- **"Desktop services script missing"**: workspace image is older than this skill. Tell the user - nothing you can do from the CLI side.
|
|
8146
|
-
- **\`xdotool ... failed: Can't open display\`**: Xvfb didn't come up. \`replicas computer status\` will show which service is dead
|
|
8146
|
+
- **\`xdotool ... failed: Can't open display\`**: Xvfb didn't come up. \`replicas computer status\` will show which service is dead and auto-repair the desktop bridge.
|
|
8147
8147
|
- **Browser doesn't appear after \`launch chrome\`**: run \`replicas computer observe /tmp/state.png\`. Chrome cold-start on the virtual display takes ~500ms but bigger pages take longer.
|
|
8148
8148
|
- **Live preview shows static / black screen**: the browser may have crashed. \`replicas computer status\` should show no Chrome process - re-launch.
|
|
8149
8149
|
- **\`replicas computer info\` errors with "not registered"**: engine couldn't register the preview at startup (transient monolith error, or warming mode). Re-running the engine usually fixes it. Until it's registered, the Desktop tab will show a placeholder.
|
|
@@ -9536,7 +9536,7 @@ var HOOK_EXEC_MAX_BUFFER_BYTES = 10 * 1024 * 1024;
|
|
|
9536
9536
|
var REPLICAS_CONFIG_FILENAMES = ["replicas.json", "replicas.yaml", "replicas.yml"];
|
|
9537
9537
|
|
|
9538
9538
|
// ../shared/src/cli-version.ts
|
|
9539
|
-
var CLI_VERSION = "0.2.
|
|
9539
|
+
var CLI_VERSION = "0.2.324";
|
|
9540
9540
|
|
|
9541
9541
|
// ../shared/src/engine/environment.ts
|
|
9542
9542
|
var DESKTOP_NOVNC_PORT = 6080;
|
|
@@ -10486,6 +10486,11 @@ function parseClaudeEvents(events, parentToolUseId) {
|
|
|
10486
10486
|
const toolCallMap = /* @__PURE__ */ new Map();
|
|
10487
10487
|
const taskMessageMap = /* @__PURE__ */ new Map();
|
|
10488
10488
|
const partialIndexes = /* @__PURE__ */ new Map();
|
|
10489
|
+
const completedStreamIds = /* @__PURE__ */ new Set();
|
|
10490
|
+
const supersededStreamIds = /* @__PURE__ */ new Set();
|
|
10491
|
+
let liveStreamId = null;
|
|
10492
|
+
const assistantThinking = /* @__PURE__ */ new Map();
|
|
10493
|
+
const assistantTextCounts = /* @__PURE__ */ new Map();
|
|
10489
10494
|
const taskAccumulator = new TaskAccumulator();
|
|
10490
10495
|
const taskSnapshot = () => taskAccumulator.getTasks().map((task) => ({
|
|
10491
10496
|
text: task.subject,
|
|
@@ -10496,6 +10501,10 @@ function parseClaudeEvents(events, parentToolUseId) {
|
|
|
10496
10501
|
if (event.type === CLAUDE_PARTIAL_MESSAGE_EVENT_TYPE) {
|
|
10497
10502
|
const payload = coerceClaudePartialMessagePayload(event.payload);
|
|
10498
10503
|
if (!payload) return;
|
|
10504
|
+
if (liveStreamId !== null && liveStreamId !== payload.streamId) {
|
|
10505
|
+
supersededStreamIds.add(liveStreamId);
|
|
10506
|
+
}
|
|
10507
|
+
liveStreamId = payload.streamId;
|
|
10499
10508
|
const existing = partialIndexes.get(payload.streamId) ?? {};
|
|
10500
10509
|
if (payload.thinking) {
|
|
10501
10510
|
const reasoningMessage = {
|
|
@@ -10558,24 +10567,51 @@ function parseClaudeEvents(events, parentToolUseId) {
|
|
|
10558
10567
|
if (event.type === "claude-assistant") {
|
|
10559
10568
|
const messageId = event.payload.message?.id;
|
|
10560
10569
|
const contentBlocks = normalizeContentBlocks(event.payload.message?.content);
|
|
10561
|
-
const
|
|
10562
|
-
|
|
10563
|
-
|
|
10564
|
-
|
|
10570
|
+
const messageKey = messageId || event.timestamp;
|
|
10571
|
+
const streamRefs = messageId ? partialIndexes.get(messageId) : void 0;
|
|
10572
|
+
if (messageId) {
|
|
10573
|
+
completedStreamIds.add(messageId);
|
|
10574
|
+
if (liveStreamId !== null && liveStreamId !== messageId) {
|
|
10575
|
+
supersededStreamIds.add(liveStreamId);
|
|
10576
|
+
}
|
|
10577
|
+
liveStreamId = null;
|
|
10578
|
+
}
|
|
10579
|
+
const thinkingBlocks = contentBlocks.flatMap(
|
|
10580
|
+
(block) => block.type === "thinking" && typeof block.thinking === "string" ? [block.thinking] : []
|
|
10581
|
+
);
|
|
10582
|
+
if (thinkingBlocks.length > 0) {
|
|
10583
|
+
const allThinking = [...assistantThinking.get(messageKey) ?? [], ...thinkingBlocks];
|
|
10584
|
+
assistantThinking.set(messageKey, allThinking);
|
|
10585
|
+
const reasoningMessage = {
|
|
10586
|
+
id: `reasoning-${messageKey}-thinking`,
|
|
10565
10587
|
type: "reasoning",
|
|
10566
|
-
content:
|
|
10588
|
+
content: allThinking.join("\n\n"),
|
|
10567
10589
|
status: "completed",
|
|
10568
10590
|
timestamp: event.timestamp
|
|
10569
|
-
}
|
|
10591
|
+
};
|
|
10592
|
+
if (streamRefs?.reasoning !== void 0) {
|
|
10593
|
+
messages[streamRefs.reasoning] = reasoningMessage;
|
|
10594
|
+
streamRefs.reasoning = void 0;
|
|
10595
|
+
} else {
|
|
10596
|
+
upsertDisplayMessage(messages, reasoningMessage);
|
|
10597
|
+
}
|
|
10570
10598
|
}
|
|
10571
|
-
contentBlocks.forEach((block
|
|
10599
|
+
contentBlocks.forEach((block) => {
|
|
10572
10600
|
if (block.type === "text" && block.text) {
|
|
10573
|
-
|
|
10574
|
-
|
|
10601
|
+
const textIndex = assistantTextCounts.get(messageKey) ?? 0;
|
|
10602
|
+
assistantTextCounts.set(messageKey, textIndex + 1);
|
|
10603
|
+
const agentMessage = {
|
|
10604
|
+
id: `agent-${messageKey}-${textIndex}`,
|
|
10575
10605
|
type: "agent",
|
|
10576
10606
|
content: block.text,
|
|
10577
10607
|
timestamp: event.timestamp
|
|
10578
|
-
}
|
|
10608
|
+
};
|
|
10609
|
+
if (streamRefs?.agent !== void 0) {
|
|
10610
|
+
messages[streamRefs.agent] = agentMessage;
|
|
10611
|
+
streamRefs.agent = void 0;
|
|
10612
|
+
} else {
|
|
10613
|
+
upsertDisplayMessage(messages, agentMessage);
|
|
10614
|
+
}
|
|
10579
10615
|
}
|
|
10580
10616
|
if (block.type === "tool_use" && block.id) {
|
|
10581
10617
|
const toolName = block.name || "unknown";
|
|
@@ -10847,7 +10883,14 @@ function parseClaudeEvents(events, parentToolUseId) {
|
|
|
10847
10883
|
}
|
|
10848
10884
|
}
|
|
10849
10885
|
});
|
|
10850
|
-
|
|
10886
|
+
const staleIndexes = /* @__PURE__ */ new Set();
|
|
10887
|
+
for (const streamId of [...completedStreamIds, ...supersededStreamIds]) {
|
|
10888
|
+
const refs = partialIndexes.get(streamId);
|
|
10889
|
+
if (refs?.reasoning !== void 0) staleIndexes.add(refs.reasoning);
|
|
10890
|
+
if (refs?.agent !== void 0) staleIndexes.add(refs.agent);
|
|
10891
|
+
}
|
|
10892
|
+
if (staleIndexes.size === 0) return messages;
|
|
10893
|
+
return messages.filter((_, index) => !staleIndexes.has(index));
|
|
10851
10894
|
}
|
|
10852
10895
|
|
|
10853
10896
|
// ../shared/src/agent-event-utils.ts
|
|
@@ -14482,6 +14525,24 @@ function parseScreenCoord(value, label, size) {
|
|
|
14482
14525
|
function resolvePath(p) {
|
|
14483
14526
|
return isAbsolute(p) ? p : resolve(process.cwd(), p);
|
|
14484
14527
|
}
|
|
14528
|
+
function desktopBridgeStatus() {
|
|
14529
|
+
const r = spawnSync("bash", [SERVICES_SCRIPT, "--status-json"], { stdio: "pipe" });
|
|
14530
|
+
if (r.status !== 0) return null;
|
|
14531
|
+
try {
|
|
14532
|
+
return JSON.parse(r.stdout.toString());
|
|
14533
|
+
} catch {
|
|
14534
|
+
return null;
|
|
14535
|
+
}
|
|
14536
|
+
}
|
|
14537
|
+
function bridgeStatus(details, includeBacklog = false, rootsOnly = false) {
|
|
14538
|
+
const pids = rootsOnly ? details.rootPids ?? [] : details.listenerPids ?? [];
|
|
14539
|
+
const listenerCount = rootsOnly ? details.rootListeners ?? pids.length : details.listeners ?? pids.length;
|
|
14540
|
+
const listenerLabel = rootsOnly ? "root listener" : "listener";
|
|
14541
|
+
const parts = [`${listenerCount} ${listenerLabel}${listenerCount === 1 ? "" : "s"} on ${details.port}`];
|
|
14542
|
+
if (includeBacklog) parts.push(`backlog ${details.backlog ?? 0}`);
|
|
14543
|
+
if (pids.length > 0) parts.push(`pid${pids.length === 1 ? "" : "s"} ${pids.join(",")}`);
|
|
14544
|
+
return ` (${parts.join(", ")})`;
|
|
14545
|
+
}
|
|
14485
14546
|
var sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
14486
14547
|
async function lookupDesktopViewerUrl() {
|
|
14487
14548
|
try {
|
|
@@ -14512,11 +14573,14 @@ async function computerInfoCommand() {
|
|
|
14512
14573
|
console.error(chalk20.dim(`Share this URL with the user to let them watch the desktop live.`));
|
|
14513
14574
|
}
|
|
14514
14575
|
async function computerStatusCommand() {
|
|
14576
|
+
ensureServicesRunning();
|
|
14577
|
+
const bridge = desktopBridgeStatus();
|
|
14515
14578
|
const procs = ["Xvfb", "openbox", "tint2", "x11vnc", "websockify"];
|
|
14516
14579
|
for (const p of procs) {
|
|
14517
14580
|
const r = spawnSync("pgrep", ["-af", p], { stdio: "pipe" });
|
|
14518
14581
|
const running = r.status === 0 && !!r.stdout?.toString().trim();
|
|
14519
|
-
|
|
14582
|
+
const suffix = p === "x11vnc" && bridge ? bridgeStatus(bridge.x11vnc, true) : p === "websockify" && bridge ? bridgeStatus(bridge.websockify, false, true) : "";
|
|
14583
|
+
console.log(` ${running ? chalk20.green("\u25CF") : chalk20.red("\u25CB")} ${p}${suffix}`);
|
|
14520
14584
|
}
|
|
14521
14585
|
const viewerUrl = await lookupDesktopViewerUrl();
|
|
14522
14586
|
if (viewerUrl) {
|