@h-rig/cli 0.0.6-alpha.41 → 0.0.6-alpha.43
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/bin/rig.js +156 -18
- package/dist/src/commands/_cli-format.js +1 -1
- package/dist/src/commands/_help-catalog.js +1 -1
- package/dist/src/commands/_operator-view.js +154 -16
- package/dist/src/commands/_pi-frontend.js +154 -16
- package/dist/src/commands/_pi-remote-session.js +52 -7
- package/dist/src/commands/_pi-worker-bridge-extension.js +109 -12
- package/dist/src/commands/_server-client.js +5 -0
- package/dist/src/commands/_spinner.js +63 -0
- package/dist/src/commands/run.js +154 -16
- package/dist/src/commands/task.js +156 -18
- package/dist/src/commands.js +156 -18
- package/dist/src/index.js +156 -18
- package/package.json +6 -6
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/cli/src/commands/_spinner.ts
|
|
3
|
+
var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
4
|
+
function createTtySpinner(input) {
|
|
5
|
+
const output = input.output ?? process.stdout;
|
|
6
|
+
const isTty = output.isTTY === true;
|
|
7
|
+
let label = input.label;
|
|
8
|
+
let frame = 0;
|
|
9
|
+
let paused = false;
|
|
10
|
+
let stopped = false;
|
|
11
|
+
let lastPrintedLabel = "";
|
|
12
|
+
const render = () => {
|
|
13
|
+
if (stopped || paused)
|
|
14
|
+
return;
|
|
15
|
+
if (!isTty) {
|
|
16
|
+
if (label !== lastPrintedLabel) {
|
|
17
|
+
output.write(`${label}
|
|
18
|
+
`);
|
|
19
|
+
lastPrintedLabel = label;
|
|
20
|
+
}
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
frame = (frame + 1) % SPINNER_FRAMES.length;
|
|
24
|
+
output.write(`\r\x1B[2K${SPINNER_FRAMES[frame]} ${label}`);
|
|
25
|
+
};
|
|
26
|
+
const clearLine = () => {
|
|
27
|
+
if (isTty)
|
|
28
|
+
output.write("\r\x1B[2K");
|
|
29
|
+
};
|
|
30
|
+
render();
|
|
31
|
+
const timer = isTty ? setInterval(render, input.intervalMs ?? 120) : null;
|
|
32
|
+
return {
|
|
33
|
+
setLabel(next) {
|
|
34
|
+
label = next;
|
|
35
|
+
render();
|
|
36
|
+
},
|
|
37
|
+
pause() {
|
|
38
|
+
paused = true;
|
|
39
|
+
clearLine();
|
|
40
|
+
},
|
|
41
|
+
resume() {
|
|
42
|
+
if (stopped)
|
|
43
|
+
return;
|
|
44
|
+
paused = false;
|
|
45
|
+
render();
|
|
46
|
+
},
|
|
47
|
+
stop(finalLine) {
|
|
48
|
+
if (stopped)
|
|
49
|
+
return;
|
|
50
|
+
stopped = true;
|
|
51
|
+
if (timer)
|
|
52
|
+
clearInterval(timer);
|
|
53
|
+
clearLine();
|
|
54
|
+
if (finalLine)
|
|
55
|
+
output.write(`${finalLine}
|
|
56
|
+
`);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export {
|
|
61
|
+
createTtySpinner,
|
|
62
|
+
SPINNER_FRAMES
|
|
63
|
+
};
|
package/dist/src/commands/run.js
CHANGED
|
@@ -319,6 +319,10 @@ async function getRunPiCommandsViaServer(context, runId) {
|
|
|
319
319
|
const payload = await requestServerJson(context, `/api/runs/${encodeURIComponent(runId)}/pi/commands`);
|
|
320
320
|
return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : { commands: [] };
|
|
321
321
|
}
|
|
322
|
+
async function getRunPiCapabilitiesViaServer(context, runId) {
|
|
323
|
+
const payload = await requestServerJson(context, `/api/runs/${encodeURIComponent(runId)}/pi/capabilities`);
|
|
324
|
+
return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : { capabilities: null };
|
|
325
|
+
}
|
|
322
326
|
async function sendRunPiPromptViaServer(context, runId, text, streamingBehavior) {
|
|
323
327
|
const payload = await requestServerJson(context, `/api/runs/${encodeURIComponent(runId)}/pi/prompt`, {
|
|
324
328
|
method: "POST",
|
|
@@ -567,7 +571,7 @@ import {
|
|
|
567
571
|
} from "@earendil-works/pi-coding-agent";
|
|
568
572
|
|
|
569
573
|
// packages/cli/src/commands/_pi-remote-session.ts
|
|
570
|
-
import { AgentSession as PiAgentSession } from "@earendil-works/pi-coding-agent";
|
|
574
|
+
import { AgentSession as PiAgentSession, expandPromptTemplate } from "@earendil-works/pi-coding-agent";
|
|
571
575
|
var TERMINAL_RUN_STATUSES = new Set(["completed", "failed", "stopped", "cancelled", "canceled", "closed", "merged", "needs_attention", "needs-attention"]);
|
|
572
576
|
function defaultTransport() {
|
|
573
577
|
return {
|
|
@@ -575,6 +579,7 @@ function defaultTransport() {
|
|
|
575
579
|
getMessages: getRunPiMessagesViaServer,
|
|
576
580
|
getStatus: getRunPiStatusViaServer,
|
|
577
581
|
getCommands: getRunPiCommandsViaServer,
|
|
582
|
+
getCapabilities: getRunPiCapabilitiesViaServer,
|
|
578
583
|
sendPrompt: sendRunPiPromptViaServer,
|
|
579
584
|
sendShell: sendRunPiShellViaServer,
|
|
580
585
|
runCommand: runRunPiCommandViaServer,
|
|
@@ -662,16 +667,18 @@ class RigRemoteSessionController {
|
|
|
662
667
|
this.hooks.onStatusText?.("worker Pi WebSocket disconnected");
|
|
663
668
|
};
|
|
664
669
|
try {
|
|
665
|
-
const [messagesPayload, statusPayload, commandsPayload] = await Promise.all([
|
|
670
|
+
const [messagesPayload, statusPayload, commandsPayload, capabilitiesPayload] = await Promise.all([
|
|
666
671
|
this.transport.getMessages(this.context, this.runId),
|
|
667
672
|
this.transport.getStatus(this.context, this.runId),
|
|
668
|
-
this.transport.getCommands(this.context, this.runId)
|
|
673
|
+
this.transport.getCommands(this.context, this.runId),
|
|
674
|
+
this.transport.getCapabilities(this.context, this.runId).catch(() => ({ capabilities: null }))
|
|
669
675
|
]);
|
|
670
676
|
const messages = Array.isArray(messagesPayload.messages) ? messagesPayload.messages : [];
|
|
671
677
|
this.applyStatusPayload(statusPayload);
|
|
672
678
|
this.session?.replaceRemoteMessages(messages);
|
|
673
679
|
const commands = Array.isArray(commandsPayload.commands) ? commandsPayload.commands : [];
|
|
674
|
-
|
|
680
|
+
const capabilities = capabilitiesPayload.capabilities && typeof capabilitiesPayload.capabilities === "object" && !Array.isArray(capabilitiesPayload.capabilities) ? capabilitiesPayload.capabilities : null;
|
|
681
|
+
this.hooks.onCatchUp?.(messages, commands, capabilities);
|
|
675
682
|
catchupDone = true;
|
|
676
683
|
for (const payload of buffered.splice(0))
|
|
677
684
|
this.applyEnvelope(payload);
|
|
@@ -848,6 +855,20 @@ class RigRemoteAgentSession extends PiAgentSession {
|
|
|
848
855
|
replaceRemoteMessages(messages) {
|
|
849
856
|
this.agent.state.messages = messages;
|
|
850
857
|
}
|
|
858
|
+
async expandLocalInput(text) {
|
|
859
|
+
let current = text;
|
|
860
|
+
const runner = this.extensionRunner;
|
|
861
|
+
if (runner.hasHandlers("input")) {
|
|
862
|
+
const result = await runner.emitInput(current, undefined, "interactive");
|
|
863
|
+
if (result.action === "handled")
|
|
864
|
+
return null;
|
|
865
|
+
if (result.action === "transform")
|
|
866
|
+
current = result.text;
|
|
867
|
+
}
|
|
868
|
+
current = this._expandSkillCommand(current);
|
|
869
|
+
current = expandPromptTemplate(current, [...this.promptTemplates]);
|
|
870
|
+
return current;
|
|
871
|
+
}
|
|
851
872
|
async prompt(text, options) {
|
|
852
873
|
const trimmed = text.trim();
|
|
853
874
|
if (!trimmed)
|
|
@@ -855,6 +876,15 @@ class RigRemoteAgentSession extends PiAgentSession {
|
|
|
855
876
|
if (trimmed.startsWith("/")) {
|
|
856
877
|
if (await this._tryExecuteExtensionCommand(trimmed))
|
|
857
878
|
return;
|
|
879
|
+
const expanded2 = await this.expandLocalInput(trimmed);
|
|
880
|
+
if (expanded2 === null)
|
|
881
|
+
return;
|
|
882
|
+
if (expanded2 !== trimmed) {
|
|
883
|
+
const behavior2 = options?.streamingBehavior ?? (this.isStreaming || this.isCompacting ? "steer" : undefined);
|
|
884
|
+
options?.preflightResult?.(true);
|
|
885
|
+
await this.remote.sendPrompt(expanded2, behavior2);
|
|
886
|
+
return;
|
|
887
|
+
}
|
|
858
888
|
await this.remote.sendCommand(trimmed);
|
|
859
889
|
return;
|
|
860
890
|
}
|
|
@@ -862,15 +892,30 @@ class RigRemoteAgentSession extends PiAgentSession {
|
|
|
862
892
|
await this.remote.sendShell(trimmed);
|
|
863
893
|
return;
|
|
864
894
|
}
|
|
895
|
+
const expanded = await this.expandLocalInput(trimmed);
|
|
896
|
+
if (expanded === null)
|
|
897
|
+
return;
|
|
865
898
|
const behavior = options?.streamingBehavior ?? (this.isStreaming || this.isCompacting ? "steer" : undefined);
|
|
866
899
|
options?.preflightResult?.(true);
|
|
867
|
-
await this.remote.sendPrompt(
|
|
900
|
+
await this.remote.sendPrompt(expanded, behavior);
|
|
868
901
|
}
|
|
869
902
|
async steer(text) {
|
|
870
|
-
|
|
903
|
+
const trimmed = text.trim();
|
|
904
|
+
if (trimmed.startsWith("/") && await this._tryExecuteExtensionCommand(trimmed))
|
|
905
|
+
return;
|
|
906
|
+
const expanded = await this.expandLocalInput(trimmed);
|
|
907
|
+
if (expanded === null)
|
|
908
|
+
return;
|
|
909
|
+
await this.remote.sendPrompt(expanded, "steer");
|
|
871
910
|
}
|
|
872
911
|
async followUp(text) {
|
|
873
|
-
|
|
912
|
+
const trimmed = text.trim();
|
|
913
|
+
if (trimmed.startsWith("/") && await this._tryExecuteExtensionCommand(trimmed))
|
|
914
|
+
return;
|
|
915
|
+
const expanded = await this.expandLocalInput(trimmed);
|
|
916
|
+
if (expanded === null)
|
|
917
|
+
return;
|
|
918
|
+
await this.remote.sendPrompt(expanded, "followUp");
|
|
874
919
|
}
|
|
875
920
|
async abort() {
|
|
876
921
|
await this.remote.abort();
|
|
@@ -983,6 +1028,9 @@ function createRemoteBashOperations(controller, excludeFromContext) {
|
|
|
983
1028
|
};
|
|
984
1029
|
}
|
|
985
1030
|
|
|
1031
|
+
// packages/cli/src/commands/_spinner.ts
|
|
1032
|
+
var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
1033
|
+
|
|
986
1034
|
// packages/cli/src/commands/_pi-worker-bridge-extension.ts
|
|
987
1035
|
function recordOf2(value) {
|
|
988
1036
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
@@ -1000,6 +1048,50 @@ function asText(value) {
|
|
|
1000
1048
|
return String(value);
|
|
1001
1049
|
}
|
|
1002
1050
|
}
|
|
1051
|
+
function names(value, key = "name") {
|
|
1052
|
+
if (!Array.isArray(value))
|
|
1053
|
+
return [];
|
|
1054
|
+
return value.flatMap((entry) => {
|
|
1055
|
+
if (typeof entry === "string")
|
|
1056
|
+
return [entry];
|
|
1057
|
+
const record = recordOf2(entry);
|
|
1058
|
+
const name = record?.[key];
|
|
1059
|
+
return typeof name === "string" ? [name] : [];
|
|
1060
|
+
});
|
|
1061
|
+
}
|
|
1062
|
+
function renderWorkerCapabilities(capabilities) {
|
|
1063
|
+
const lines = ["Worker session capabilities (in effect for this run)"];
|
|
1064
|
+
const tools = Array.isArray(capabilities.tools) ? capabilities.tools : [];
|
|
1065
|
+
const activeTools = tools.flatMap((tool) => {
|
|
1066
|
+
const record = recordOf2(tool);
|
|
1067
|
+
return record && record.active === true && typeof record.name === "string" ? [record.name] : [];
|
|
1068
|
+
});
|
|
1069
|
+
const inactiveCount = tools.length - activeTools.length;
|
|
1070
|
+
lines.push(` tools ${activeTools.join(", ") || "(none)"}${inactiveCount > 0 ? ` (+${inactiveCount} inactive)` : ""}`);
|
|
1071
|
+
const extensions = Array.isArray(capabilities.extensions) ? capabilities.extensions : [];
|
|
1072
|
+
const extensionLabels = extensions.flatMap((entry) => {
|
|
1073
|
+
const record = recordOf2(entry);
|
|
1074
|
+
if (!record)
|
|
1075
|
+
return [];
|
|
1076
|
+
const path = typeof record.path === "string" ? record.path : "";
|
|
1077
|
+
const short = path.split("/").filter(Boolean).slice(-2).join("/") || path || "extension";
|
|
1078
|
+
return [short];
|
|
1079
|
+
});
|
|
1080
|
+
lines.push(` extensions ${extensionLabels.join(", ") || "(none)"}`);
|
|
1081
|
+
const hookEvents = names(capabilities.hookEvents);
|
|
1082
|
+
const hookList = Array.isArray(capabilities.hookEvents) ? capabilities.hookEvents.map(asText).filter(Boolean) : hookEvents;
|
|
1083
|
+
lines.push(` hooks ${hookList.join(", ") || "(none)"}`);
|
|
1084
|
+
lines.push(` skills ${names(capabilities.skills).join(", ") || "(none)"}`);
|
|
1085
|
+
lines.push(` prompts ${names(capabilities.prompts).join(", ") || "(none)"}`);
|
|
1086
|
+
const model = typeof capabilities.model === "string" ? capabilities.model : "(unknown)";
|
|
1087
|
+
const thinking = typeof capabilities.thinkingLevel === "string" ? capabilities.thinkingLevel : "";
|
|
1088
|
+
const cwd = typeof capabilities.cwd === "string" ? capabilities.cwd : "";
|
|
1089
|
+
lines.push(` model ${model}${thinking ? ` \xB7 ${thinking}` : ""}`);
|
|
1090
|
+
if (cwd)
|
|
1091
|
+
lines.push(` cwd ${cwd}`);
|
|
1092
|
+
lines.push(" (worker commands are in your palette as [worker \u2026] \xB7 /worker shows this again)");
|
|
1093
|
+
return lines;
|
|
1094
|
+
}
|
|
1003
1095
|
async function answerExtensionUiRequest(options, ctx, request) {
|
|
1004
1096
|
const requestId = String(request.requestId ?? request.id ?? `ui-${Date.now()}`);
|
|
1005
1097
|
const method = String(request.method ?? request.type ?? "input");
|
|
@@ -1026,7 +1118,7 @@ async function answerExtensionUiRequest(options, ctx, request) {
|
|
|
1026
1118
|
ctx.ui.notify(`Failed to answer worker UI request: ${error instanceof Error ? error.message : String(error)}`, "error");
|
|
1027
1119
|
}
|
|
1028
1120
|
}
|
|
1029
|
-
var LOCALLY_OWNED_COMMANDS = new Set(["detach", "quit", "q", "stop", "settings", "model", "thinking", "compact", "session", "name", "reload"]);
|
|
1121
|
+
var LOCALLY_OWNED_COMMANDS = new Set(["detach", "quit", "q", "stop", "worker", "settings", "model", "thinking", "compact", "session", "name", "reload"]);
|
|
1030
1122
|
function registerDaemonCommands(pi, options, ctx, commands, registered) {
|
|
1031
1123
|
for (const command of commands) {
|
|
1032
1124
|
const record = recordOf2(command);
|
|
@@ -1054,6 +1146,21 @@ function registerDaemonCommands(pi, options, ctx, commands, registered) {
|
|
|
1054
1146
|
function createRigWorkerPiBridgeExtension(options) {
|
|
1055
1147
|
return (pi) => {
|
|
1056
1148
|
const registeredDaemonCommands = new Set;
|
|
1149
|
+
let capabilityLines = null;
|
|
1150
|
+
let statusText = "connecting to worker session";
|
|
1151
|
+
let busy = true;
|
|
1152
|
+
let connected = false;
|
|
1153
|
+
let frame = 0;
|
|
1154
|
+
let spinnerTimer = null;
|
|
1155
|
+
const renderStatus = (ctx) => {
|
|
1156
|
+
const prefix = busy ? `${SPINNER_FRAMES[frame]} ` : connected ? "\u25CF " : "\u25CB ";
|
|
1157
|
+
ctx.ui.setStatus("rig-worker-pi", `${prefix}${statusText}`);
|
|
1158
|
+
};
|
|
1159
|
+
const setStatus = (ctx, text, isBusy) => {
|
|
1160
|
+
statusText = text;
|
|
1161
|
+
busy = isBusy;
|
|
1162
|
+
renderStatus(ctx);
|
|
1163
|
+
};
|
|
1057
1164
|
pi.registerCommand("detach", {
|
|
1058
1165
|
description: "Detach from this run; the worker keeps going",
|
|
1059
1166
|
handler: async (_args, ctx) => {
|
|
@@ -1069,31 +1176,57 @@ function createRigWorkerPiBridgeExtension(options) {
|
|
|
1069
1176
|
ctx.shutdown();
|
|
1070
1177
|
}
|
|
1071
1178
|
});
|
|
1179
|
+
pi.registerCommand("worker", {
|
|
1180
|
+
description: "Show the worker session's real capabilities (tools, extensions, hooks, skills)",
|
|
1181
|
+
handler: async (_args, ctx) => {
|
|
1182
|
+
if (capabilityLines)
|
|
1183
|
+
ctx.ui.setWidget("rig-worker-capabilities", capabilityLines, { placement: "aboveEditor" });
|
|
1184
|
+
else
|
|
1185
|
+
ctx.ui.notify("Worker capabilities are not available yet (still connecting).", "info");
|
|
1186
|
+
}
|
|
1187
|
+
});
|
|
1072
1188
|
pi.on("user_bash", (event) => ({
|
|
1073
1189
|
operations: createRemoteBashOperations(options.controller, event.excludeFromContext === true)
|
|
1074
1190
|
}));
|
|
1075
1191
|
pi.on("session_start", async (_event, ctx) => {
|
|
1076
|
-
ctx.ui.setTitle("Rig \xB7
|
|
1077
|
-
|
|
1078
|
-
|
|
1192
|
+
ctx.ui.setTitle("Rig \xB7 enriched bundled Pi");
|
|
1193
|
+
setStatus(ctx, "waiting for worker Pi daemon", true);
|
|
1194
|
+
spinnerTimer = setInterval(() => {
|
|
1195
|
+
frame = (frame + 1) % SPINNER_FRAMES.length;
|
|
1196
|
+
if (busy)
|
|
1197
|
+
renderStatus(ctx);
|
|
1198
|
+
}, 150);
|
|
1199
|
+
ctx.ui.notify(`Enriched bundled Pi \u2014 native UI + Rig layers, worker brain. Attached to run ${options.runId}. /worker shows live capabilities \xB7 /detach exits \xB7 /stop cancels.`, "info");
|
|
1079
1200
|
if (options.initialMessageSent)
|
|
1080
1201
|
ctx.ui.notify("Initial message sent to the worker Pi daemon.", "info");
|
|
1081
1202
|
const nativeUi = ctx.ui;
|
|
1082
1203
|
options.controller.setUiHooks({
|
|
1083
|
-
onStatusText: (text) =>
|
|
1084
|
-
onActivity: (label, detail) =>
|
|
1085
|
-
|
|
1204
|
+
onStatusText: (text) => setStatus(ctx, text, !connected),
|
|
1205
|
+
onActivity: (label, detail) => {
|
|
1206
|
+
const active = label !== "idle" && !/complete|ready/i.test(label);
|
|
1207
|
+
setStatus(ctx, [label, detail].filter(Boolean).join(" \u2014 "), active);
|
|
1208
|
+
if (/agent running|tool:/.test(label))
|
|
1209
|
+
ctx.ui.setWidget("rig-worker-capabilities", undefined);
|
|
1210
|
+
},
|
|
1211
|
+
onConnectionChange: (nextConnected) => {
|
|
1212
|
+
connected = nextConnected;
|
|
1213
|
+
setStatus(ctx, nextConnected ? "worker session live" : "worker session disconnected", false);
|
|
1214
|
+
},
|
|
1086
1215
|
onError: (message) => ctx.ui.notify(message, "error"),
|
|
1087
1216
|
onExtensionUiRequest: (request) => {
|
|
1088
1217
|
answerExtensionUiRequest(options, ctx, request);
|
|
1089
1218
|
},
|
|
1090
|
-
onCatchUp: (messages, commands) => {
|
|
1219
|
+
onCatchUp: (messages, commands, capabilities) => {
|
|
1091
1220
|
if (nativeUi.appendSessionMessages)
|
|
1092
1221
|
nativeUi.appendSessionMessages(messages);
|
|
1093
1222
|
const cwd = options.controller.status.cwd;
|
|
1094
1223
|
if (nativeUi.setDisplayCwd && cwd)
|
|
1095
1224
|
nativeUi.setDisplayCwd(cwd);
|
|
1096
1225
|
registerDaemonCommands(pi, options, ctx, commands, registeredDaemonCommands);
|
|
1226
|
+
if (capabilities) {
|
|
1227
|
+
capabilityLines = renderWorkerCapabilities(capabilities);
|
|
1228
|
+
ctx.ui.setWidget("rig-worker-capabilities", capabilityLines, { placement: "aboveEditor" });
|
|
1229
|
+
}
|
|
1097
1230
|
}
|
|
1098
1231
|
});
|
|
1099
1232
|
options.controller.connect().catch((error) => {
|
|
@@ -1101,6 +1234,8 @@ function createRigWorkerPiBridgeExtension(options) {
|
|
|
1101
1234
|
});
|
|
1102
1235
|
});
|
|
1103
1236
|
pi.on("session_shutdown", () => {
|
|
1237
|
+
if (spinnerTimer)
|
|
1238
|
+
clearInterval(spinnerTimer);
|
|
1104
1239
|
options.controller.close();
|
|
1105
1240
|
});
|
|
1106
1241
|
};
|
|
@@ -1142,6 +1277,9 @@ async function attachRunBundledPiFrontend(context, input) {
|
|
|
1142
1277
|
initialMessageSent: input.steered === true
|
|
1143
1278
|
})
|
|
1144
1279
|
],
|
|
1280
|
+
noExtensions: true,
|
|
1281
|
+
noSkills: true,
|
|
1282
|
+
noPromptTemplates: true,
|
|
1145
1283
|
noContextFiles: true
|
|
1146
1284
|
}
|
|
1147
1285
|
});
|
|
@@ -1176,7 +1314,7 @@ async function attachRunBundledPiFrontend(context, input) {
|
|
|
1176
1314
|
timelineCursor: null,
|
|
1177
1315
|
steered: input.steered === true,
|
|
1178
1316
|
detached,
|
|
1179
|
-
rendered: "
|
|
1317
|
+
rendered: "enriched bundled Pi frontend with remote worker session runtime"
|
|
1180
1318
|
};
|
|
1181
1319
|
}
|
|
1182
1320
|
|