@h-rig/cli 0.0.6-alpha.21 → 0.0.6-alpha.23
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 +940 -387
- package/dist/src/commands/_operator-view.js +539 -4
- package/dist/src/commands/_pi-frontend.js +727 -0
- package/dist/src/commands/_pi-worker-bridge-extension.js +645 -0
- package/dist/src/commands/_preflight.js +1 -81
- package/dist/src/commands/_server-client.js +80 -1
- package/dist/src/commands/run.js +541 -115
- package/dist/src/commands/task-run-driver.js +141 -10
- package/dist/src/commands/task.js +544 -197
- package/dist/src/commands.js +940 -387
- package/dist/src/index.js +940 -387
- package/package.json +6 -5
- package/dist/src/commands/_pi-session.js +0 -253
|
@@ -618,6 +618,7 @@ function buildPiRigBridgeEnv(input) {
|
|
|
618
618
|
RIG_SERVER_RUN_ID: input.runId,
|
|
619
619
|
RIG_TASK_ID: input.taskId,
|
|
620
620
|
RIG_RUNTIME_ADAPTER: "pi",
|
|
621
|
+
RIG_STEERING_POLL_MS: "0",
|
|
621
622
|
...input.serverUrl ? { RIG_SERVER_URL: input.serverUrl } : {},
|
|
622
623
|
...input.authToken ? { RIG_AUTH_TOKEN: input.authToken } : {},
|
|
623
624
|
...githubBridgeEnv(githubToken)
|
|
@@ -1220,6 +1221,69 @@ function appendAssistantTimelineFromRecord(input) {
|
|
|
1220
1221
|
}
|
|
1221
1222
|
return nextAssistantText;
|
|
1222
1223
|
}
|
|
1224
|
+
function appendPiRpcProtocolLogFromRecord(input) {
|
|
1225
|
+
const type = typeof input.record.type === "string" ? input.record.type : "";
|
|
1226
|
+
if (type === "response") {
|
|
1227
|
+
const command = typeof input.record.command === "string" ? input.record.command : "rpc";
|
|
1228
|
+
const success = input.record.success !== false;
|
|
1229
|
+
if (success && command !== "prompt" && command !== "steer" && command !== "follow_up" && command !== "set_session_name") {
|
|
1230
|
+
return true;
|
|
1231
|
+
}
|
|
1232
|
+
appendRunLog(input.projectRoot, input.runId, {
|
|
1233
|
+
id: input.nextRunLogId(),
|
|
1234
|
+
title: success ? "Pi RPC response" : "Pi RPC error",
|
|
1235
|
+
detail: success ? `${command}: accepted` : `${command}: ${String(input.record.error ?? "failed")}`,
|
|
1236
|
+
tone: success ? "tool" : "error",
|
|
1237
|
+
status: input.status,
|
|
1238
|
+
payload: input.record,
|
|
1239
|
+
createdAt: new Date().toISOString()
|
|
1240
|
+
});
|
|
1241
|
+
emitServerRunEvent({ type: "log", runId: input.runId, title: success ? "Pi RPC response" : "Pi RPC error" });
|
|
1242
|
+
return true;
|
|
1243
|
+
}
|
|
1244
|
+
if (type !== "extension_ui_request")
|
|
1245
|
+
return false;
|
|
1246
|
+
const method = typeof input.record.method === "string" ? input.record.method : "ui";
|
|
1247
|
+
let title = "Pi UI event";
|
|
1248
|
+
let detail = method;
|
|
1249
|
+
let tone = "info";
|
|
1250
|
+
if (method === "notify") {
|
|
1251
|
+
title = "Pi notification";
|
|
1252
|
+
detail = String(input.record.message ?? "");
|
|
1253
|
+
tone = input.record.notifyType === "error" ? "error" : "info";
|
|
1254
|
+
} else if (method === "setStatus") {
|
|
1255
|
+
title = "Pi UI status";
|
|
1256
|
+
detail = `${String(input.record.statusKey ?? "status")}: ${String(input.record.statusText ?? "cleared")}`;
|
|
1257
|
+
tone = "tool";
|
|
1258
|
+
} else if (method === "setWidget") {
|
|
1259
|
+
title = "Pi UI widget";
|
|
1260
|
+
const lines = Array.isArray(input.record.widgetLines) ? input.record.widgetLines.map((line) => String(line)).join(" | ") : "cleared";
|
|
1261
|
+
detail = `${String(input.record.widgetKey ?? "widget")}: ${lines}`.slice(0, 500);
|
|
1262
|
+
tone = "tool";
|
|
1263
|
+
} else if (method === "setTitle") {
|
|
1264
|
+
title = "Pi UI title";
|
|
1265
|
+
detail = String(input.record.title ?? "");
|
|
1266
|
+
tone = "tool";
|
|
1267
|
+
} else if (method === "set_editor_text") {
|
|
1268
|
+
title = "Pi editor update";
|
|
1269
|
+
detail = String(input.record.text ?? "").slice(0, 500);
|
|
1270
|
+
tone = "tool";
|
|
1271
|
+
} else {
|
|
1272
|
+
title = "Pi UI request";
|
|
1273
|
+
detail = `${method}: ${String(input.record.title ?? input.record.message ?? "")}`.trim();
|
|
1274
|
+
}
|
|
1275
|
+
appendRunLog(input.projectRoot, input.runId, {
|
|
1276
|
+
id: input.nextRunLogId(),
|
|
1277
|
+
title,
|
|
1278
|
+
detail,
|
|
1279
|
+
tone,
|
|
1280
|
+
status: input.status,
|
|
1281
|
+
payload: input.record,
|
|
1282
|
+
createdAt: new Date().toISOString()
|
|
1283
|
+
});
|
|
1284
|
+
emitServerRunEvent({ type: "log", runId: input.runId, title });
|
|
1285
|
+
return true;
|
|
1286
|
+
}
|
|
1223
1287
|
function appendPiToolTimelineFromRecord(input) {
|
|
1224
1288
|
const type = typeof input.record.type === "string" ? input.record.type : "";
|
|
1225
1289
|
if (type !== "tool_execution_start" && type !== "tool_execution_update" && type !== "tool_execution_end")
|
|
@@ -1238,7 +1302,7 @@ function appendPiToolTimelineFromRecord(input) {
|
|
|
1238
1302
|
}
|
|
1239
1303
|
function isNonRenderablePiProtocolRecord(record) {
|
|
1240
1304
|
const type = typeof record.type === "string" ? record.type : "";
|
|
1241
|
-
return type === "message_start" || type === "message_end" || type === "turn_start" || type === "turn_end" || type === "tool_result" || type === "message_update" && (!record.assistantMessageEvent || typeof record.assistantMessageEvent !== "object" || Array.isArray(record.assistantMessageEvent) || record.assistantMessageEvent.type !== "text_delta");
|
|
1305
|
+
return type === "agent_start" || type === "agent_end" || type === "message_start" || type === "message_end" || type === "turn_start" || type === "turn_end" || type === "tool_result" || type === "message_update" && (!record.assistantMessageEvent || typeof record.assistantMessageEvent !== "object" || Array.isArray(record.assistantMessageEvent) || record.assistantMessageEvent.type !== "text_delta");
|
|
1242
1306
|
}
|
|
1243
1307
|
function appendToolTimelineFromLog(input) {
|
|
1244
1308
|
const title = typeof input.log.title === "string" ? input.log.title : "";
|
|
@@ -1401,11 +1465,7 @@ async function executeRigOwnedTaskRun(context, input) {
|
|
|
1401
1465
|
...input.model ? ["--model", input.model] : [],
|
|
1402
1466
|
"--prompt"
|
|
1403
1467
|
] : input.runtimeAdapter === "pi" ? [
|
|
1404
|
-
"
|
|
1405
|
-
"--verbose",
|
|
1406
|
-
"--mode",
|
|
1407
|
-
"json",
|
|
1408
|
-
"--no-session",
|
|
1468
|
+
"__rig_pi_session_daemon__",
|
|
1409
1469
|
...input.model ? ["--model", input.model] : []
|
|
1410
1470
|
] : [
|
|
1411
1471
|
"--print",
|
|
@@ -1502,7 +1562,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
1502
1562
|
projectRoot: context.projectRoot,
|
|
1503
1563
|
runId: input.runId,
|
|
1504
1564
|
stage,
|
|
1505
|
-
detail: stage === "Launch Pi" ? "Pi
|
|
1565
|
+
detail: stage === "Launch Pi" ? "Worker Pi SDK session daemon starting; local frontend will attach over Rig-proxied WebSocket." : stage === "Plan" ? `${planningClassification.planningRequired ? "recorded" : "skipped"} (${planningClassification.reason}; size=${planningClassification.size}; risk=${planningClassification.risk})` : stage === "Implement" ? "Pi implementation pass is running in the worker runtime." : null,
|
|
1506
1566
|
status: stage === "Implement" || stage === "Launch Pi" ? "running" : "completed"
|
|
1507
1567
|
});
|
|
1508
1568
|
}
|
|
@@ -1543,6 +1603,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
1543
1603
|
let latestProviderCommand = null;
|
|
1544
1604
|
let latestRuntimeBranch = resumeMode && typeof existingRunRecord?.branch === "string" ? existingRunRecord.branch : null;
|
|
1545
1605
|
let snapshotSidecarPromise = null;
|
|
1606
|
+
let wrapperManagesRuntimeSnapshot = false;
|
|
1546
1607
|
let dirtyBaselineApplied = false;
|
|
1547
1608
|
const childEnv = {
|
|
1548
1609
|
...process.env,
|
|
@@ -1595,6 +1656,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
1595
1656
|
detail: detail ?? "Verifier review is running."
|
|
1596
1657
|
});
|
|
1597
1658
|
};
|
|
1659
|
+
const nextRunLogId = createRunLogIdFactory(input.runId);
|
|
1598
1660
|
const handleWrapperEvent = (rawPayload) => {
|
|
1599
1661
|
let event = null;
|
|
1600
1662
|
try {
|
|
@@ -1610,6 +1672,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
1610
1672
|
latestSessionDir = typeof payload.sessionDir === "string" ? payload.sessionDir : latestSessionDir;
|
|
1611
1673
|
latestLogsDir = typeof payload.logsDir === "string" ? payload.logsDir : latestLogsDir;
|
|
1612
1674
|
const runtimeId = typeof payload.runtimeId === "string" ? payload.runtimeId : null;
|
|
1675
|
+
wrapperManagesRuntimeSnapshot = payload.snapshotManaged === true;
|
|
1613
1676
|
latestRuntimeBranch = runtimeId;
|
|
1614
1677
|
provisioningAction.complete(latestRuntimeWorkspace ?? "Runtime ready.", {
|
|
1615
1678
|
runtimeId: runtimeId ?? null,
|
|
@@ -1647,7 +1710,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
1647
1710
|
});
|
|
1648
1711
|
emitServerRunEvent({ type: "log", runId: input.runId, title: "Dirty baseline snapshot" });
|
|
1649
1712
|
}
|
|
1650
|
-
if (!snapshotSidecarPromise && runtimeId && loadRuntimeSnapshotConfig(context.projectRoot).enabled) {
|
|
1713
|
+
if (!wrapperManagesRuntimeSnapshot && !snapshotSidecarPromise && runtimeId && loadRuntimeSnapshotConfig(context.projectRoot).enabled) {
|
|
1651
1714
|
snapshotSidecarPromise = (async () => {
|
|
1652
1715
|
const { sidecar, error } = await resolveTaskRunSnapshotSidecar({
|
|
1653
1716
|
projectRoot: context.projectRoot,
|
|
@@ -1729,9 +1792,68 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
1729
1792
|
}
|
|
1730
1793
|
return true;
|
|
1731
1794
|
}
|
|
1795
|
+
if (event.type === "pi.sessiond.starting" || event.type === "pi.sessiond.ready" || event.type === "pi.session.event_stream.connected" || event.type === "pi.prompt.sent" || event.type === "pi.prompt.waiting" || event.type === "pi.session.agent_end" || event.type === "pi.session.error") {
|
|
1796
|
+
const title = event.type === "pi.sessiond.starting" ? "Starting worker Pi session daemon" : event.type === "pi.sessiond.ready" ? "Worker Pi daemon ready" : event.type === "pi.session.event_stream.connected" ? "Worker Pi event stream connected" : event.type === "pi.prompt.sent" ? "Delivered initial prompt to worker Pi" : event.type === "pi.prompt.waiting" ? "Worker Pi prompt waiting" : event.type === "pi.session.agent_end" ? "Worker Pi turn complete" : "Worker Pi session error";
|
|
1797
|
+
const detail = event.type === "pi.sessiond.ready" ? "Daemon accepted control connection; waiting for SDK session metadata." : event.type === "pi.sessiond.starting" ? String(payload.workspaceDir ?? "worker runtime") : event.type === "pi.prompt.sent" ? `${String(payload.bytes ?? "unknown")} prompt bytes sent.` : event.type === "pi.prompt.waiting" ? String(payload.reason ?? "empty prompt") : event.type === "pi.session.error" ? String(payload.message ?? "session error") : String(payload.sessionId ?? payload.runId ?? "worker Pi session");
|
|
1798
|
+
appendRunLog(context.projectRoot, input.runId, {
|
|
1799
|
+
id: nextRunLogId(),
|
|
1800
|
+
title,
|
|
1801
|
+
detail,
|
|
1802
|
+
tone: event.type === "pi.session.error" ? "error" : "info",
|
|
1803
|
+
status: reviewStarted ? "reviewing" : verificationStarted ? "validating" : "running",
|
|
1804
|
+
payload: {
|
|
1805
|
+
eventType: event.type,
|
|
1806
|
+
runId: typeof payload.runId === "string" ? payload.runId : null,
|
|
1807
|
+
runtimeId: typeof payload.runtimeId === "string" ? payload.runtimeId : null,
|
|
1808
|
+
sessionId: typeof payload.sessionId === "string" ? payload.sessionId : null
|
|
1809
|
+
},
|
|
1810
|
+
createdAt: new Date().toISOString()
|
|
1811
|
+
});
|
|
1812
|
+
emitServerRunEvent({ type: "log", runId: input.runId, title });
|
|
1813
|
+
return true;
|
|
1814
|
+
}
|
|
1815
|
+
if (event.type === "pi.session.ready") {
|
|
1816
|
+
const privateMetadata = payload.privateMetadata && typeof payload.privateMetadata === "object" && !Array.isArray(payload.privateMetadata) ? payload.privateMetadata : null;
|
|
1817
|
+
const publicMetadata = payload.metadata && typeof payload.metadata === "object" && !Array.isArray(payload.metadata) ? payload.metadata : null;
|
|
1818
|
+
if (privateMetadata) {
|
|
1819
|
+
patchAuthorityRun(context.projectRoot, input.runId, {
|
|
1820
|
+
piSession: publicMetadata,
|
|
1821
|
+
piSessionPrivate: privateMetadata
|
|
1822
|
+
});
|
|
1823
|
+
const sessionId = typeof publicMetadata?.sessionId === "string" ? publicMetadata.sessionId : typeof privateMetadata.public === "object" && privateMetadata.public && !Array.isArray(privateMetadata.public) ? String(privateMetadata.public.sessionId ?? "") : "";
|
|
1824
|
+
appendRunLog(context.projectRoot, input.runId, {
|
|
1825
|
+
id: `log:${input.runId}:pi-session-ready`,
|
|
1826
|
+
title: "Worker Pi session ready",
|
|
1827
|
+
detail: sessionId ? `Session ${sessionId} is ready for WebSocket attach.` : "Worker Pi SDK session daemon is ready for WebSocket attach.",
|
|
1828
|
+
tone: "info",
|
|
1829
|
+
status: "running",
|
|
1830
|
+
payload: {
|
|
1831
|
+
sessionId: sessionId || null,
|
|
1832
|
+
runtimeId: typeof payload.runtimeId === "string" ? payload.runtimeId : null
|
|
1833
|
+
},
|
|
1834
|
+
createdAt: new Date().toISOString()
|
|
1835
|
+
});
|
|
1836
|
+
emitServerRunEvent({ type: "log", runId: input.runId, title: "Worker Pi session ready" });
|
|
1837
|
+
}
|
|
1838
|
+
return true;
|
|
1839
|
+
}
|
|
1840
|
+
if (event.type === "pi.rpc.prompt.sent" || event.type === "pi.rpc.steering.delivered" || event.type === "pi.rpc.steering.poll.failed" || event.type === "pi.rpc.extension_ui.cancelled") {
|
|
1841
|
+
const title = event.type === "pi.rpc.prompt.sent" ? "Delivered initial prompt to worker Pi" : event.type === "pi.rpc.steering.delivered" ? "Delivered steering to worker Pi" : event.type === "pi.rpc.steering.poll.failed" ? "Worker Pi steering poll failed" : "Pi RPC UI request auto-cancelled";
|
|
1842
|
+
const detail = event.type === "pi.rpc.prompt.sent" ? `${String(payload.kind ?? "prompt")} prompt (${String(payload.bytes ?? "unknown")} bytes)` : event.type === "pi.rpc.steering.delivered" ? `${String(payload.actor ?? "operator")}: ${String(payload.message ?? "")}`.slice(0, 500) : event.type === "pi.rpc.steering.poll.failed" ? String(payload.error ?? "steering poll failed") : `${String(payload.method ?? "ui")}: ${String(payload.reason ?? "noninteractive worker session")}`;
|
|
1843
|
+
appendRunLog(context.projectRoot, input.runId, {
|
|
1844
|
+
id: nextRunLogId(),
|
|
1845
|
+
title,
|
|
1846
|
+
detail,
|
|
1847
|
+
tone: event.type === "pi.rpc.steering.poll.failed" ? "error" : "info",
|
|
1848
|
+
status: reviewStarted ? "reviewing" : verificationStarted ? "validating" : "running",
|
|
1849
|
+
payload,
|
|
1850
|
+
createdAt: new Date().toISOString()
|
|
1851
|
+
});
|
|
1852
|
+
emitServerRunEvent({ type: "log", runId: input.runId, title });
|
|
1853
|
+
return true;
|
|
1854
|
+
}
|
|
1732
1855
|
return false;
|
|
1733
1856
|
};
|
|
1734
|
-
const nextRunLogId = createRunLogIdFactory(input.runId);
|
|
1735
1857
|
const handleAgentStdoutLine = (line) => {
|
|
1736
1858
|
const trimmed = line.trim();
|
|
1737
1859
|
if (!trimmed)
|
|
@@ -1765,6 +1887,15 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
1765
1887
|
try {
|
|
1766
1888
|
const record = JSON.parse(trimmed);
|
|
1767
1889
|
const liveLogStatus = reviewStarted ? "reviewing" : verificationStarted ? "validating" : "running";
|
|
1890
|
+
if (input.runtimeAdapter === "pi" && appendPiRpcProtocolLogFromRecord({
|
|
1891
|
+
projectRoot: context.projectRoot,
|
|
1892
|
+
runId: input.runId,
|
|
1893
|
+
record,
|
|
1894
|
+
status: liveLogStatus,
|
|
1895
|
+
nextRunLogId
|
|
1896
|
+
})) {
|
|
1897
|
+
return;
|
|
1898
|
+
}
|
|
1768
1899
|
if (input.runtimeAdapter === "pi" && appendPiToolTimelineFromRecord({ projectRoot: context.projectRoot, runId: input.runId, record })) {
|
|
1769
1900
|
emitServerRunEvent({ type: "timeline", runId: input.runId });
|
|
1770
1901
|
return;
|
|
@@ -2237,7 +2368,7 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
|
|
|
2237
2368
|
startedAt,
|
|
2238
2369
|
finishedAt: requestedAt
|
|
2239
2370
|
});
|
|
2240
|
-
|
|
2371
|
+
process.exit(0);
|
|
2241
2372
|
}
|
|
2242
2373
|
const runPiPrFeedbackFix = async (message) => {
|
|
2243
2374
|
appendPiStageLog({
|