@h-rig/runtime 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-agent-dispatch.js +588 -28
- package/dist/src/control-plane/agent-wrapper.js +592 -28
- package/dist/src/control-plane/harness-main.js +142 -17
- package/dist/src/control-plane/hooks/completion-verification.js +142 -17
- package/dist/src/control-plane/native/harness-cli.js +142 -17
- package/dist/src/control-plane/native/pr-automation.js +142 -17
- package/dist/src/control-plane/native/pr-review-gate.js +142 -17
- package/dist/src/control-plane/native/run-ops.js +1 -1
- package/dist/src/control-plane/native/task-ops.js +142 -17
- package/dist/src/control-plane/native/verifier.js +142 -17
- package/dist/src/control-plane/pi-sessiond/bin.js +793 -0
- package/dist/src/control-plane/pi-sessiond/client.js +41 -0
- package/dist/src/control-plane/pi-sessiond/event-hub.js +59 -0
- package/dist/src/control-plane/pi-sessiond/extension-ui-context.js +198 -0
- package/dist/src/control-plane/pi-sessiond/launcher.js +163 -0
- package/dist/src/control-plane/pi-sessiond/server.js +802 -0
- package/dist/src/control-plane/pi-sessiond/session-service.js +540 -0
- package/dist/src/control-plane/pi-sessiond/types.js +1 -0
- package/dist/src/control-plane/runtime/index.js +17 -0
- package/dist/src/control-plane/runtime/isolation/home.js +17 -0
- package/dist/src/control-plane/runtime/isolation/index.js +17 -0
- package/dist/src/control-plane/runtime/isolation/runner.js +17 -0
- package/dist/src/control-plane/runtime/isolation.js +17 -0
- package/dist/src/control-plane/runtime/queue.js +17 -0
- package/package.json +7 -6
|
@@ -567,8 +567,9 @@ var init_backend_bwrap = __esm(() => {
|
|
|
567
567
|
});
|
|
568
568
|
|
|
569
569
|
// packages/runtime/src/control-plane/agent-wrapper.ts
|
|
570
|
-
import {
|
|
571
|
-
import {
|
|
570
|
+
import { createRequire } from "module";
|
|
571
|
+
import { resolve as resolve36 } from "path";
|
|
572
|
+
import { existsSync as existsSync34, mkdirSync as mkdirSync20, writeFileSync as writeFileSync13 } from "fs";
|
|
572
573
|
|
|
573
574
|
// packages/runtime/src/control-plane/runtime/context.ts
|
|
574
575
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
@@ -5785,6 +5786,21 @@ var GITHUB_KNOWN_HOSTS = [
|
|
|
5785
5786
|
"github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk="
|
|
5786
5787
|
].join(`
|
|
5787
5788
|
`);
|
|
5789
|
+
function resolveControlPlaneSourceRoot(projectRoot) {
|
|
5790
|
+
const candidates = [
|
|
5791
|
+
process.env.RIG_CONTROL_PLANE_SOURCE_ROOT?.trim(),
|
|
5792
|
+
process.env.RIG_HOST_PROJECT_ROOT?.trim(),
|
|
5793
|
+
resolve25(import.meta.dir, "../../../../.."),
|
|
5794
|
+
projectRoot
|
|
5795
|
+
].filter((value) => Boolean(value));
|
|
5796
|
+
for (const candidate of candidates) {
|
|
5797
|
+
const root = resolve25(candidate);
|
|
5798
|
+
if (existsSync24(resolve25(root, "packages/runtime/src/control-plane/pi-sessiond/bin.ts"))) {
|
|
5799
|
+
return root;
|
|
5800
|
+
}
|
|
5801
|
+
}
|
|
5802
|
+
return "";
|
|
5803
|
+
}
|
|
5788
5804
|
async function runtimeEnv(projectRoot, runtime) {
|
|
5789
5805
|
const bunBinaryPath = resolveBunBinaryPath();
|
|
5790
5806
|
const bunDir = resolveBunInstallDir(bunBinaryPath);
|
|
@@ -5830,9 +5846,11 @@ async function runtimeEnv(projectRoot, runtime) {
|
|
|
5830
5846
|
const runtimeRigGit = resolve25(runtime.binDir, runtimeRigGitFileName());
|
|
5831
5847
|
const preferredShell = existsSync24(runtimeBash) ? runtimeBash : "/bin/bash";
|
|
5832
5848
|
const nativeRuntimeLibraryPath = await materializeNativeRuntimeLibrary(runtime.binDir);
|
|
5849
|
+
const controlPlaneSourceRoot = resolveControlPlaneSourceRoot(projectRoot);
|
|
5833
5850
|
const env = {
|
|
5834
5851
|
PROJECT_RIG_ROOT: projectRoot,
|
|
5835
5852
|
RIG_HOST_PROJECT_ROOT: projectRoot,
|
|
5853
|
+
...controlPlaneSourceRoot ? { RIG_CONTROL_PLANE_SOURCE_ROOT: controlPlaneSourceRoot } : {},
|
|
5836
5854
|
HOME: runtime.homeDir,
|
|
5837
5855
|
TMPDIR: runtime.tmpDir,
|
|
5838
5856
|
XDG_CACHE_HOME: runtime.cacheDir,
|
|
@@ -9151,7 +9169,165 @@ function formatJsonRpcError(error) {
|
|
|
9151
9169
|
return parts.join(" ");
|
|
9152
9170
|
}
|
|
9153
9171
|
|
|
9172
|
+
// packages/runtime/src/control-plane/pi-sessiond/launcher.ts
|
|
9173
|
+
import { randomBytes } from "crypto";
|
|
9174
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync19, readFileSync as readFileSync16, rmSync as rmSync13 } from "fs";
|
|
9175
|
+
import { dirname as dirname14, resolve as resolve35 } from "path";
|
|
9176
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
9177
|
+
|
|
9178
|
+
// packages/runtime/src/control-plane/pi-sessiond/client.ts
|
|
9179
|
+
class RigPiSessionDaemonClient {
|
|
9180
|
+
baseUrl;
|
|
9181
|
+
token;
|
|
9182
|
+
constructor(options) {
|
|
9183
|
+
this.baseUrl = options.baseUrl.replace(/\/+$/, "");
|
|
9184
|
+
this.token = options.token;
|
|
9185
|
+
}
|
|
9186
|
+
static fromConnection(connection, token) {
|
|
9187
|
+
if (connection.mode === "http")
|
|
9188
|
+
return new RigPiSessionDaemonClient({ baseUrl: connection.baseUrl, token });
|
|
9189
|
+
throw new Error("Unix-socket Rig Pi daemon connections are not implemented in this build; use loopback HTTP.");
|
|
9190
|
+
}
|
|
9191
|
+
async request(method, path, body) {
|
|
9192
|
+
const response = await fetch(`${this.baseUrl}${path.startsWith("/") ? path : `/${path}`}`, {
|
|
9193
|
+
method,
|
|
9194
|
+
headers: {
|
|
9195
|
+
authorization: `Bearer ${this.token}`,
|
|
9196
|
+
...body === undefined ? {} : { "content-type": "application/json" }
|
|
9197
|
+
},
|
|
9198
|
+
body: body === undefined ? undefined : JSON.stringify(body)
|
|
9199
|
+
});
|
|
9200
|
+
const text = await response.text();
|
|
9201
|
+
const payload = text.trim() ? JSON.parse(text) : undefined;
|
|
9202
|
+
if (!response.ok) {
|
|
9203
|
+
const message = payload && typeof payload === "object" && !Array.isArray(payload) && typeof payload.error === "string" ? payload.error : text || response.statusText;
|
|
9204
|
+
throw new Error(`Rig Pi session daemon request failed (${response.status}): ${message}`);
|
|
9205
|
+
}
|
|
9206
|
+
return payload;
|
|
9207
|
+
}
|
|
9208
|
+
webSocketUrl(path) {
|
|
9209
|
+
const url = new URL(`${this.baseUrl}${path.startsWith("/") ? path : `/${path}`}`);
|
|
9210
|
+
url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
|
|
9211
|
+
url.searchParams.set("token", this.token);
|
|
9212
|
+
return url.toString();
|
|
9213
|
+
}
|
|
9214
|
+
}
|
|
9215
|
+
|
|
9216
|
+
// packages/runtime/src/control-plane/pi-sessiond/launcher.ts
|
|
9217
|
+
var BUILD_CONFIG2 = {};
|
|
9218
|
+
var BAKED_RIG_SOURCE_ROOT = BUILD_CONFIG2.RIG_SOURCE_ROOT ?? "";
|
|
9219
|
+
async function ensureRigPiSessionDaemon(input) {
|
|
9220
|
+
const rootDir = resolve35(input.rootDir);
|
|
9221
|
+
mkdirSync19(rootDir, { recursive: true });
|
|
9222
|
+
const readyFile = resolve35(rootDir, "ready.json");
|
|
9223
|
+
const existing = readDaemonReadyFile(readyFile);
|
|
9224
|
+
const existingHandle = existing ? await tryReady(existing) : null;
|
|
9225
|
+
if (existingHandle)
|
|
9226
|
+
return existingHandle;
|
|
9227
|
+
try {
|
|
9228
|
+
rmSync13(readyFile, { force: true });
|
|
9229
|
+
} catch {}
|
|
9230
|
+
const token = randomBytes(32).toString("hex");
|
|
9231
|
+
const binPath = resolveRigPiSessionDaemonBinPath(input.env);
|
|
9232
|
+
const bunPath = input.env.RIG_BUN_PATH || process.execPath;
|
|
9233
|
+
const proc = Bun.spawn([bunPath, binPath], {
|
|
9234
|
+
cwd: rootDir,
|
|
9235
|
+
env: {
|
|
9236
|
+
...input.env,
|
|
9237
|
+
RIG_PI_SESSIOND_ROOT: rootDir,
|
|
9238
|
+
RIG_PI_SESSIOND_TOKEN: token,
|
|
9239
|
+
RIG_PI_SESSIOND_READY_FILE: readyFile,
|
|
9240
|
+
RIG_PI_SESSIOND_HOST: "127.0.0.1",
|
|
9241
|
+
RIG_PI_SESSIOND_PORT: "0",
|
|
9242
|
+
...input.version ? { RIG_VERSION: input.version } : {},
|
|
9243
|
+
...input.commit ? { RIG_GIT_COMMIT: input.commit } : {}
|
|
9244
|
+
},
|
|
9245
|
+
stdin: "ignore",
|
|
9246
|
+
stdout: "ignore",
|
|
9247
|
+
stderr: "inherit"
|
|
9248
|
+
});
|
|
9249
|
+
proc.unref();
|
|
9250
|
+
const deadline = Date.now() + (input.timeoutMs ?? 15000);
|
|
9251
|
+
while (Date.now() < deadline) {
|
|
9252
|
+
const ready = readDaemonReadyFile(readyFile);
|
|
9253
|
+
const handle = ready ? await tryReady(ready) : null;
|
|
9254
|
+
if (handle)
|
|
9255
|
+
return handle;
|
|
9256
|
+
await sleep(100);
|
|
9257
|
+
}
|
|
9258
|
+
throw new Error(`Rig Pi session daemon did not become ready at ${readyFile}`);
|
|
9259
|
+
}
|
|
9260
|
+
function privateMetadataForDaemon(input) {
|
|
9261
|
+
return { public: input.publicMetadata, daemonConnection: input.connection };
|
|
9262
|
+
}
|
|
9263
|
+
async function tryReady(ready) {
|
|
9264
|
+
const host = typeof ready.host === "string" ? ready.host : "127.0.0.1";
|
|
9265
|
+
const port = typeof ready.port === "number" ? ready.port : Number(ready.port);
|
|
9266
|
+
const token = typeof ready.token === "string" ? ready.token : "";
|
|
9267
|
+
if (!Number.isFinite(port) || port <= 0 || !token)
|
|
9268
|
+
return null;
|
|
9269
|
+
const baseUrl = `http://${host}:${port}`;
|
|
9270
|
+
const client = new RigPiSessionDaemonClient({ baseUrl, token });
|
|
9271
|
+
try {
|
|
9272
|
+
await client.request("GET", "/health");
|
|
9273
|
+
} catch {
|
|
9274
|
+
return null;
|
|
9275
|
+
}
|
|
9276
|
+
return {
|
|
9277
|
+
client,
|
|
9278
|
+
connection: { mode: "http", baseUrl, tokenRef: tokenRefFromReady(ready) },
|
|
9279
|
+
token,
|
|
9280
|
+
ready
|
|
9281
|
+
};
|
|
9282
|
+
}
|
|
9283
|
+
function tokenRefFromReady(ready) {
|
|
9284
|
+
const token = typeof ready.token === "string" ? ready.token : "";
|
|
9285
|
+
return token ? `inline:${token}` : "missing";
|
|
9286
|
+
}
|
|
9287
|
+
function resolveRigPiSessionDaemonBinPath(env) {
|
|
9288
|
+
const explicit = env.RIG_PI_SESSIOND_BIN?.trim();
|
|
9289
|
+
if (explicit)
|
|
9290
|
+
return explicit;
|
|
9291
|
+
const roots = [
|
|
9292
|
+
env.RIG_CONTROL_PLANE_SOURCE_ROOT?.trim(),
|
|
9293
|
+
BAKED_RIG_SOURCE_ROOT.trim(),
|
|
9294
|
+
process.env.RIG_CONTROL_PLANE_SOURCE_ROOT?.trim(),
|
|
9295
|
+
process.env.RIG_HOST_PROJECT_ROOT?.trim(),
|
|
9296
|
+
process.env.PROJECT_RIG_ROOT?.trim()
|
|
9297
|
+
].filter((value) => Boolean(value));
|
|
9298
|
+
for (const root of roots) {
|
|
9299
|
+
const candidate = resolve35(root, "packages/runtime/src/control-plane/pi-sessiond/bin.ts");
|
|
9300
|
+
if (existsSync33(candidate))
|
|
9301
|
+
return candidate;
|
|
9302
|
+
}
|
|
9303
|
+
const moduleCandidate = fileURLToPath2(new URL("./bin.ts", import.meta.url));
|
|
9304
|
+
if (existsSync33(moduleCandidate))
|
|
9305
|
+
return moduleCandidate;
|
|
9306
|
+
throw new Error("Unable to locate rig-pi-sessiond entrypoint. Set RIG_PI_SESSIOND_BIN or RIG_CONTROL_PLANE_SOURCE_ROOT to the Rig source checkout.");
|
|
9307
|
+
}
|
|
9308
|
+
function readDaemonReadyFile(path) {
|
|
9309
|
+
if (!existsSync33(path))
|
|
9310
|
+
return null;
|
|
9311
|
+
try {
|
|
9312
|
+
const parsed = JSON.parse(readFileSync16(path, "utf8"));
|
|
9313
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
9314
|
+
} catch {
|
|
9315
|
+
return null;
|
|
9316
|
+
}
|
|
9317
|
+
}
|
|
9318
|
+
function sleep(ms) {
|
|
9319
|
+
return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
|
|
9320
|
+
}
|
|
9321
|
+
function resolveRigPiSessionDaemonRoot(stateDir) {
|
|
9322
|
+
const root = resolve35(stateDir, "pi-sessiond");
|
|
9323
|
+
mkdirSync19(dirname14(root), { recursive: true });
|
|
9324
|
+
if (!existsSync33(root))
|
|
9325
|
+
mkdirSync19(root, { recursive: true });
|
|
9326
|
+
return root;
|
|
9327
|
+
}
|
|
9328
|
+
|
|
9154
9329
|
// packages/runtime/src/control-plane/agent-wrapper.ts
|
|
9330
|
+
var requireFromRuntime = createRequire(import.meta.url);
|
|
9155
9331
|
async function finalizeRuntimeSnapshot(snapshotSidecar, providerCommand, exitCode, context) {
|
|
9156
9332
|
try {
|
|
9157
9333
|
await snapshotSidecar.finalize(providerCommand, exitCode);
|
|
@@ -9184,7 +9360,7 @@ async function startOptionalRuntimeSnapshotSidecar(runtime, startSidecar = start
|
|
|
9184
9360
|
}
|
|
9185
9361
|
}
|
|
9186
9362
|
async function runAgentWrapper(options = {}) {
|
|
9187
|
-
const projectRoot =
|
|
9363
|
+
const projectRoot = resolve36(options.projectRoot || process.env.PROJECT_RIG_ROOT || process.cwd());
|
|
9188
9364
|
const monorepoRoot = resolveMonorepoRoot2(projectRoot);
|
|
9189
9365
|
const argv = options.argv || process.argv.slice(2);
|
|
9190
9366
|
if (argv.length === 0 || argv[0] === "--version" || argv[0] === "--help" || argv[0] === "help") {
|
|
@@ -9247,7 +9423,8 @@ async function runAgentWrapper(options = {}) {
|
|
|
9247
9423
|
return 1;
|
|
9248
9424
|
}
|
|
9249
9425
|
const providerArgs = buildProviderArgs(provider, runtime, argv);
|
|
9250
|
-
const
|
|
9426
|
+
const normalPiDaemonPath = provider === "pi" && process.env.RIG_PI_RPC_FALLBACK !== "1";
|
|
9427
|
+
const providerCommand = normalPiDaemonPath ? ["rig-pi-sessiond", ...providerArgs] : [providerBinary(provider), ...providerArgs];
|
|
9251
9428
|
emitWrapperEvent("provider.launch", {
|
|
9252
9429
|
provider,
|
|
9253
9430
|
runtimeId: runtime.id,
|
|
@@ -9259,11 +9436,11 @@ async function runAgentWrapper(options = {}) {
|
|
|
9259
9436
|
const bypassOuterRuntimeSandbox = shouldBypassProviderSandboxOnPlatform(provider, process.platform);
|
|
9260
9437
|
const runClaudeCompatUnsandboxed = provider === "claude-code" && bypassOuterRuntimeSandbox;
|
|
9261
9438
|
if (runClaudeCompatUnsandboxed && process.env.HOME?.trim()) {
|
|
9262
|
-
env.CLAUDE_HOME =
|
|
9439
|
+
env.CLAUDE_HOME = resolve36(process.env.HOME.trim(), ".claude");
|
|
9263
9440
|
env.RIG_CLAUDE_RUNTIME_HOME = runtime.claudeHomeDir;
|
|
9264
9441
|
}
|
|
9265
9442
|
if (provider === "pi") {
|
|
9266
|
-
env.PI_CODING_AGENT_DIR =
|
|
9443
|
+
env.PI_CODING_AGENT_DIR = resolve36(runtime.homeDir, ".pi", "agent");
|
|
9267
9444
|
env.PI_CODING_AGENT_SESSION_DIR = runtime.sessionDir;
|
|
9268
9445
|
}
|
|
9269
9446
|
env.RIG_RUNTIME_SANDBOX = "enforce";
|
|
@@ -9297,14 +9474,36 @@ async function runAgentWrapper(options = {}) {
|
|
|
9297
9474
|
},
|
|
9298
9475
|
command: providerCommand
|
|
9299
9476
|
})).command;
|
|
9300
|
-
|
|
9301
|
-
|
|
9302
|
-
|
|
9303
|
-
|
|
9304
|
-
|
|
9305
|
-
|
|
9306
|
-
|
|
9307
|
-
|
|
9477
|
+
if (provider === "pi" && process.env.RIG_PI_RPC_FALLBACK !== "1") {
|
|
9478
|
+
const prompt = await readProcessStdin();
|
|
9479
|
+
exitCode = await runPiSessionDaemonProvider({
|
|
9480
|
+
projectRoot,
|
|
9481
|
+
runtime,
|
|
9482
|
+
env,
|
|
9483
|
+
prompt,
|
|
9484
|
+
runId: process.env.RIG_SERVER_RUN_ID?.trim() || process.env.RIG_RUN_ID?.trim() || undefined,
|
|
9485
|
+
sessionName: process.env.RIG_SERVER_RUN_ID?.trim() ? `Rig ${process.env.RIG_SERVER_RUN_ID.trim()}` : `Rig ${runtime.taskId}`
|
|
9486
|
+
});
|
|
9487
|
+
} else if (provider === "pi" && isPiRpcArgs(providerArgs)) {
|
|
9488
|
+
const prompt = await readProcessStdin();
|
|
9489
|
+
exitCode = await runPiRpcProviderFallback({
|
|
9490
|
+
command,
|
|
9491
|
+
cwd: runtime.workspaceDir,
|
|
9492
|
+
env,
|
|
9493
|
+
prompt,
|
|
9494
|
+
runId: process.env.RIG_SERVER_RUN_ID?.trim() || undefined,
|
|
9495
|
+
sessionName: process.env.RIG_SERVER_RUN_ID?.trim() ? `Rig ${process.env.RIG_SERVER_RUN_ID.trim()}` : `Rig ${runtime.taskId}`
|
|
9496
|
+
});
|
|
9497
|
+
} else {
|
|
9498
|
+
const proc = Bun.spawn(command, {
|
|
9499
|
+
cwd: runtime.workspaceDir,
|
|
9500
|
+
env,
|
|
9501
|
+
stdin: "inherit",
|
|
9502
|
+
stdout: "inherit",
|
|
9503
|
+
stderr: "inherit"
|
|
9504
|
+
});
|
|
9505
|
+
exitCode = await proc.exited;
|
|
9506
|
+
}
|
|
9308
9507
|
}
|
|
9309
9508
|
if (snapshotSidecar) {
|
|
9310
9509
|
await finalizeRuntimeSnapshot(snapshotSidecar, providerCommand, exitCode, {
|
|
@@ -9341,6 +9540,338 @@ async function runAgentWrapper(options = {}) {
|
|
|
9341
9540
|
}
|
|
9342
9541
|
return finalExitCode;
|
|
9343
9542
|
}
|
|
9543
|
+
function parseJsonRecord(line) {
|
|
9544
|
+
try {
|
|
9545
|
+
const parsed = JSON.parse(line);
|
|
9546
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
9547
|
+
} catch {
|
|
9548
|
+
return null;
|
|
9549
|
+
}
|
|
9550
|
+
}
|
|
9551
|
+
async function readProcessStdin() {
|
|
9552
|
+
if (process.stdin.isTTY)
|
|
9553
|
+
return "";
|
|
9554
|
+
return await new Promise((resolveRead) => {
|
|
9555
|
+
let data = "";
|
|
9556
|
+
process.stdin.setEncoding("utf8");
|
|
9557
|
+
process.stdin.on("data", (chunk) => {
|
|
9558
|
+
data += String(chunk);
|
|
9559
|
+
});
|
|
9560
|
+
process.stdin.on("end", () => resolveRead(data));
|
|
9561
|
+
process.stdin.resume();
|
|
9562
|
+
});
|
|
9563
|
+
}
|
|
9564
|
+
async function pumpReadableLines(stream, onLine) {
|
|
9565
|
+
if (!stream)
|
|
9566
|
+
return;
|
|
9567
|
+
const reader = stream.getReader();
|
|
9568
|
+
const decoder = new TextDecoder;
|
|
9569
|
+
let buffer = "";
|
|
9570
|
+
try {
|
|
9571
|
+
while (true) {
|
|
9572
|
+
const { done, value } = await reader.read();
|
|
9573
|
+
if (done)
|
|
9574
|
+
break;
|
|
9575
|
+
buffer += decoder.decode(value, { stream: true });
|
|
9576
|
+
const parts = buffer.split(/\r?\n/);
|
|
9577
|
+
buffer = parts.pop() ?? "";
|
|
9578
|
+
for (const part of parts)
|
|
9579
|
+
onLine(part);
|
|
9580
|
+
}
|
|
9581
|
+
buffer += decoder.decode();
|
|
9582
|
+
if (buffer)
|
|
9583
|
+
onLine(buffer);
|
|
9584
|
+
} finally {
|
|
9585
|
+
reader.releaseLock();
|
|
9586
|
+
}
|
|
9587
|
+
}
|
|
9588
|
+
function isBlockingPiRpcUiRequest(record) {
|
|
9589
|
+
if (record.type !== "extension_ui_request")
|
|
9590
|
+
return false;
|
|
9591
|
+
return record.method === "select" || record.method === "confirm" || record.method === "input" || record.method === "editor";
|
|
9592
|
+
}
|
|
9593
|
+
function writeRpcCommand(stdin, command) {
|
|
9594
|
+
stdin.write(`${JSON.stringify(command)}
|
|
9595
|
+
`);
|
|
9596
|
+
}
|
|
9597
|
+
function joinUrl(baseUrl, pathname) {
|
|
9598
|
+
return `${baseUrl.replace(/\/+$/, "")}${pathname.startsWith("/") ? pathname : `/${pathname}`}`;
|
|
9599
|
+
}
|
|
9600
|
+
async function readQueuedSteeringFromServer(input) {
|
|
9601
|
+
if (!input.serverUrl || !input.runId)
|
|
9602
|
+
return [];
|
|
9603
|
+
const headers = {};
|
|
9604
|
+
if (input.authToken)
|
|
9605
|
+
headers.authorization = `Bearer ${input.authToken}`;
|
|
9606
|
+
const response = await fetch(joinUrl(input.serverUrl, `/api/runs/${encodeURIComponent(input.runId)}/steering?ack=1`), { headers });
|
|
9607
|
+
if (!response.ok)
|
|
9608
|
+
return [];
|
|
9609
|
+
const payload = await response.json().catch(() => null);
|
|
9610
|
+
const messages = payload && typeof payload === "object" && !Array.isArray(payload) ? payload.messages : null;
|
|
9611
|
+
return Array.isArray(messages) ? messages.filter((entry) => Boolean(entry && typeof entry === "object" && !Array.isArray(entry))) : [];
|
|
9612
|
+
}
|
|
9613
|
+
function steeringMessageText(entry) {
|
|
9614
|
+
const message = typeof entry.message === "string" ? entry.message.trim() : "";
|
|
9615
|
+
return message || null;
|
|
9616
|
+
}
|
|
9617
|
+
function isPiRpcArgs(args) {
|
|
9618
|
+
return cliOptionValue(args, "--mode") === "rpc";
|
|
9619
|
+
}
|
|
9620
|
+
async function runPiSessionDaemonProvider(input) {
|
|
9621
|
+
const stdout = input.stdout ?? process.stdout;
|
|
9622
|
+
const stderr = input.stderr ?? process.stderr;
|
|
9623
|
+
const runId = input.runId ?? input.runtime.taskId;
|
|
9624
|
+
emitWrapperEvent("pi.sessiond.starting", {
|
|
9625
|
+
runId,
|
|
9626
|
+
runtimeId: input.runtime.id,
|
|
9627
|
+
workspaceDir: input.runtime.workspaceDir
|
|
9628
|
+
});
|
|
9629
|
+
const daemon = await ensureRigPiSessionDaemon({
|
|
9630
|
+
rootDir: resolveRigPiSessionDaemonRoot(input.runtime.stateDir),
|
|
9631
|
+
env: input.env,
|
|
9632
|
+
version: process.env.RIG_VERSION?.trim() || "dev",
|
|
9633
|
+
commit: process.env.RIG_GIT_COMMIT?.trim() || undefined
|
|
9634
|
+
});
|
|
9635
|
+
emitWrapperEvent("pi.sessiond.ready", {
|
|
9636
|
+
runId,
|
|
9637
|
+
runtimeId: input.runtime.id,
|
|
9638
|
+
connection: daemon.connection,
|
|
9639
|
+
ready: daemon.ready
|
|
9640
|
+
});
|
|
9641
|
+
const start = await daemon.client.request("POST", "/sessions", {
|
|
9642
|
+
runId,
|
|
9643
|
+
cwd: input.runtime.workspaceDir,
|
|
9644
|
+
agentDir: input.env.PI_CODING_AGENT_DIR || resolve36(input.runtime.homeDir, ".pi", "agent"),
|
|
9645
|
+
sessionDir: input.runtime.sessionDir,
|
|
9646
|
+
sessionName: input.sessionName
|
|
9647
|
+
});
|
|
9648
|
+
const privateMetadata = privateMetadataForDaemon({ publicMetadata: start.metadata, connection: daemon.connection });
|
|
9649
|
+
emitWrapperEvent("pi.session.ready", {
|
|
9650
|
+
runId,
|
|
9651
|
+
runtimeId: input.runtime.id,
|
|
9652
|
+
metadata: start.metadata,
|
|
9653
|
+
privateMetadata
|
|
9654
|
+
});
|
|
9655
|
+
const eventStream = waitForPiSessionEvents({
|
|
9656
|
+
url: daemon.client.webSocketUrl(`/sessions/${encodeURIComponent(start.metadata.sessionId)}/events`),
|
|
9657
|
+
stdout,
|
|
9658
|
+
stderr,
|
|
9659
|
+
runId
|
|
9660
|
+
});
|
|
9661
|
+
emitWrapperEvent("pi.session.event_stream.connected", { runId, sessionId: start.metadata.sessionId });
|
|
9662
|
+
const forwardSigterm = () => {
|
|
9663
|
+
daemon.client.request("POST", `/sessions/${encodeURIComponent(start.metadata.sessionId)}/abort`).catch(() => {
|
|
9664
|
+
return;
|
|
9665
|
+
});
|
|
9666
|
+
eventStream.close();
|
|
9667
|
+
};
|
|
9668
|
+
process.once("SIGTERM", forwardSigterm);
|
|
9669
|
+
try {
|
|
9670
|
+
if (input.prompt.trim()) {
|
|
9671
|
+
await daemon.client.request("POST", `/sessions/${encodeURIComponent(start.metadata.sessionId)}/prompt`, { text: input.prompt });
|
|
9672
|
+
emitWrapperEvent("pi.prompt.sent", { runId, sessionId: start.metadata.sessionId, bytes: Buffer.byteLength(input.prompt) });
|
|
9673
|
+
} else {
|
|
9674
|
+
emitWrapperEvent("pi.prompt.waiting", { runId, sessionId: start.metadata.sessionId, reason: "empty-initial-prompt" });
|
|
9675
|
+
}
|
|
9676
|
+
const result = await eventStream.done;
|
|
9677
|
+
if (result.error) {
|
|
9678
|
+
stderr.write(`[rig-agent] Pi session daemon stream failed: ${result.error}
|
|
9679
|
+
`);
|
|
9680
|
+
return 1;
|
|
9681
|
+
}
|
|
9682
|
+
return 0;
|
|
9683
|
+
} finally {
|
|
9684
|
+
process.off("SIGTERM", forwardSigterm);
|
|
9685
|
+
eventStream.close();
|
|
9686
|
+
}
|
|
9687
|
+
}
|
|
9688
|
+
function waitForPiSessionEvents(input) {
|
|
9689
|
+
let closed = false;
|
|
9690
|
+
let resolved = false;
|
|
9691
|
+
let socket = null;
|
|
9692
|
+
let resolveDone = () => {
|
|
9693
|
+
return;
|
|
9694
|
+
};
|
|
9695
|
+
const done = new Promise((resolveDoneInner) => {
|
|
9696
|
+
resolveDone = resolveDoneInner;
|
|
9697
|
+
});
|
|
9698
|
+
const finish = (value) => {
|
|
9699
|
+
if (resolved)
|
|
9700
|
+
return;
|
|
9701
|
+
resolved = true;
|
|
9702
|
+
resolveDone(value);
|
|
9703
|
+
};
|
|
9704
|
+
socket = new WebSocket(input.url);
|
|
9705
|
+
socket.addEventListener("message", (message) => {
|
|
9706
|
+
const text = typeof message.data === "string" ? message.data : Buffer.from(message.data).toString("utf8");
|
|
9707
|
+
input.stdout.write(`${text}
|
|
9708
|
+
`);
|
|
9709
|
+
const envelope = parseJsonRecord(text);
|
|
9710
|
+
if (!envelope)
|
|
9711
|
+
return;
|
|
9712
|
+
if (envelope.type === "pi.event") {
|
|
9713
|
+
const event = envelope.event && typeof envelope.event === "object" && !Array.isArray(envelope.event) ? envelope.event : null;
|
|
9714
|
+
if (event?.type === "agent_end") {
|
|
9715
|
+
emitWrapperEvent("pi.session.agent_end", { runId: input.runId, sessionId: envelope.sessionId });
|
|
9716
|
+
finish({});
|
|
9717
|
+
}
|
|
9718
|
+
}
|
|
9719
|
+
if (envelope.type === "error") {
|
|
9720
|
+
emitWrapperEvent("pi.session.error", { runId: input.runId, message: envelope.message, detail: envelope.detail ?? null });
|
|
9721
|
+
finish({ error: envelope.message });
|
|
9722
|
+
}
|
|
9723
|
+
});
|
|
9724
|
+
socket.addEventListener("error", () => {
|
|
9725
|
+
if (!closed)
|
|
9726
|
+
finish({ error: "WebSocket error" });
|
|
9727
|
+
});
|
|
9728
|
+
socket.addEventListener("close", () => {
|
|
9729
|
+
if (!closed && !resolved)
|
|
9730
|
+
finish({ error: "WebSocket closed before agent_end" });
|
|
9731
|
+
});
|
|
9732
|
+
return {
|
|
9733
|
+
done,
|
|
9734
|
+
close: () => {
|
|
9735
|
+
closed = true;
|
|
9736
|
+
try {
|
|
9737
|
+
socket?.close();
|
|
9738
|
+
} catch {}
|
|
9739
|
+
}
|
|
9740
|
+
};
|
|
9741
|
+
}
|
|
9742
|
+
async function runPiRpcProviderFallback(input) {
|
|
9743
|
+
const stdout = input.stdout ?? process.stdout;
|
|
9744
|
+
const stderr = input.stderr ?? process.stderr;
|
|
9745
|
+
const proc = Bun.spawn(input.command, {
|
|
9746
|
+
cwd: input.cwd,
|
|
9747
|
+
env: input.env,
|
|
9748
|
+
stdin: "pipe",
|
|
9749
|
+
stdout: "pipe",
|
|
9750
|
+
stderr: "pipe"
|
|
9751
|
+
});
|
|
9752
|
+
let sawAgentEnd = false;
|
|
9753
|
+
let promptError = null;
|
|
9754
|
+
let stdinOpen = true;
|
|
9755
|
+
let steeringPollStopped = false;
|
|
9756
|
+
const closeStdin = () => {
|
|
9757
|
+
if (!stdinOpen)
|
|
9758
|
+
return;
|
|
9759
|
+
stdinOpen = false;
|
|
9760
|
+
try {
|
|
9761
|
+
steeringPollStopped = true;
|
|
9762
|
+
proc.stdin.end();
|
|
9763
|
+
} catch {}
|
|
9764
|
+
};
|
|
9765
|
+
const send = (command) => {
|
|
9766
|
+
if (!stdinOpen)
|
|
9767
|
+
return;
|
|
9768
|
+
try {
|
|
9769
|
+
writeRpcCommand(proc.stdin, command);
|
|
9770
|
+
} catch (error) {
|
|
9771
|
+
promptError ??= error instanceof Error ? error.message : String(error);
|
|
9772
|
+
}
|
|
9773
|
+
};
|
|
9774
|
+
const forwardSigterm = () => {
|
|
9775
|
+
try {
|
|
9776
|
+
proc.kill("SIGTERM");
|
|
9777
|
+
} catch {}
|
|
9778
|
+
};
|
|
9779
|
+
process.once("SIGTERM", forwardSigterm);
|
|
9780
|
+
const pollSteering = async () => {
|
|
9781
|
+
const serverUrl = input.env.RIG_SERVER_URL || input.env.RIG_SERVER_BASE_URL;
|
|
9782
|
+
const authToken = input.env.RIG_AUTH_TOKEN || input.env.RIG_SERVER_AUTH_TOKEN;
|
|
9783
|
+
while (!steeringPollStopped && stdinOpen) {
|
|
9784
|
+
try {
|
|
9785
|
+
const messages = await readQueuedSteeringFromServer({ serverUrl, authToken, runId: input.runId });
|
|
9786
|
+
for (const message of messages) {
|
|
9787
|
+
const text = steeringMessageText(message);
|
|
9788
|
+
if (!text || !stdinOpen)
|
|
9789
|
+
continue;
|
|
9790
|
+
send({
|
|
9791
|
+
id: typeof message.id === "string" ? `rig_steer_${message.id}` : `rig_steer_${Date.now()}`,
|
|
9792
|
+
type: "prompt",
|
|
9793
|
+
message: text,
|
|
9794
|
+
streamingBehavior: "steer"
|
|
9795
|
+
});
|
|
9796
|
+
emitWrapperEvent("pi.rpc.steering.delivered", {
|
|
9797
|
+
runId: input.runId ?? null,
|
|
9798
|
+
steeringId: typeof message.id === "string" ? message.id : null,
|
|
9799
|
+
actor: typeof message.actor === "string" ? message.actor : "operator",
|
|
9800
|
+
message: text
|
|
9801
|
+
});
|
|
9802
|
+
}
|
|
9803
|
+
} catch (error) {
|
|
9804
|
+
emitWrapperEvent("pi.rpc.steering.poll.failed", {
|
|
9805
|
+
runId: input.runId ?? null,
|
|
9806
|
+
error: error instanceof Error ? error.message : String(error)
|
|
9807
|
+
});
|
|
9808
|
+
}
|
|
9809
|
+
await sleep2(1000);
|
|
9810
|
+
}
|
|
9811
|
+
};
|
|
9812
|
+
const stdoutPump = pumpReadableLines(proc.stdout, (line) => {
|
|
9813
|
+
stdout.write(`${line}
|
|
9814
|
+
`);
|
|
9815
|
+
const record = parseJsonRecord(line.trim());
|
|
9816
|
+
if (!record)
|
|
9817
|
+
return;
|
|
9818
|
+
if (record.type === "agent_end") {
|
|
9819
|
+
sawAgentEnd = true;
|
|
9820
|
+
closeStdin();
|
|
9821
|
+
return;
|
|
9822
|
+
}
|
|
9823
|
+
if (record.type === "response" && record.command === "prompt" && record.success === false) {
|
|
9824
|
+
promptError = typeof record.error === "string" ? record.error : "Pi RPC prompt failed.";
|
|
9825
|
+
closeStdin();
|
|
9826
|
+
return;
|
|
9827
|
+
}
|
|
9828
|
+
if (isBlockingPiRpcUiRequest(record)) {
|
|
9829
|
+
const id = typeof record.id === "string" ? record.id : "";
|
|
9830
|
+
if (id) {
|
|
9831
|
+
send({ type: "extension_ui_response", id, cancelled: true });
|
|
9832
|
+
emitWrapperEvent("pi.rpc.extension_ui.cancelled", {
|
|
9833
|
+
id,
|
|
9834
|
+
method: record.method,
|
|
9835
|
+
reason: "noninteractive Rig worker RPC session"
|
|
9836
|
+
});
|
|
9837
|
+
}
|
|
9838
|
+
}
|
|
9839
|
+
});
|
|
9840
|
+
const stderrPump = pumpReadableLines(proc.stderr, (line) => {
|
|
9841
|
+
stderr.write(`${line}
|
|
9842
|
+
`);
|
|
9843
|
+
});
|
|
9844
|
+
if (input.sessionName?.trim()) {
|
|
9845
|
+
send({ id: "rig_set_session_name", type: "set_session_name", name: input.sessionName.trim() });
|
|
9846
|
+
}
|
|
9847
|
+
const steeringPollPromise = pollSteering();
|
|
9848
|
+
if (input.prompt.trim()) {
|
|
9849
|
+
send({ id: "rig_initial_prompt", type: "prompt", message: input.prompt });
|
|
9850
|
+
emitWrapperEvent("pi.rpc.prompt.sent", {
|
|
9851
|
+
runId: input.runId ?? null,
|
|
9852
|
+
kind: "initial",
|
|
9853
|
+
bytes: Buffer.byteLength(input.prompt)
|
|
9854
|
+
});
|
|
9855
|
+
} else {
|
|
9856
|
+
closeStdin();
|
|
9857
|
+
}
|
|
9858
|
+
const exitCode = await proc.exited;
|
|
9859
|
+
process.off("SIGTERM", forwardSigterm);
|
|
9860
|
+
steeringPollStopped = true;
|
|
9861
|
+
await Promise.all([stdoutPump, stderrPump, steeringPollPromise]);
|
|
9862
|
+
if (promptError) {
|
|
9863
|
+
stderr.write(`[rig-agent] Pi RPC prompt failed: ${promptError}
|
|
9864
|
+
`);
|
|
9865
|
+
return exitCode === 0 ? 1 : exitCode;
|
|
9866
|
+
}
|
|
9867
|
+
if (input.prompt.trim() && !sawAgentEnd && exitCode === 0) {
|
|
9868
|
+
stderr.write(`[rig-agent] Pi RPC exited before emitting agent_end.
|
|
9869
|
+
`);
|
|
9870
|
+
return 1;
|
|
9871
|
+
}
|
|
9872
|
+
return exitCode;
|
|
9873
|
+
}
|
|
9874
|
+
var runPiRpcProvider = runPiRpcProviderFallback;
|
|
9344
9875
|
function resolveFinalProviderExitCode(input) {
|
|
9345
9876
|
if (input.providerExitCode !== 0) {
|
|
9346
9877
|
return input.providerExitCode;
|
|
@@ -9372,6 +9903,9 @@ function buildProviderArgs(provider, runtime, argv) {
|
|
|
9372
9903
|
}
|
|
9373
9904
|
if (provider === "pi") {
|
|
9374
9905
|
const piArgs = [...argv];
|
|
9906
|
+
if (piArgs.includes("__rig_pi_session_daemon__")) {
|
|
9907
|
+
return piArgs.filter((arg) => arg !== "__rig_pi_session_daemon__");
|
|
9908
|
+
}
|
|
9375
9909
|
const piProvider = cliOptionValue(piArgs, "--provider") || process.env.RIG_PI_PROVIDER?.trim() || "openai-codex";
|
|
9376
9910
|
if (!hasCliOption(piArgs, "--provider")) {
|
|
9377
9911
|
piArgs.unshift(piProvider);
|
|
@@ -9384,6 +9918,12 @@ function buildProviderArgs(provider, runtime, argv) {
|
|
|
9384
9918
|
piArgs.unshift(normalizePiModelForProvider(model, piProvider));
|
|
9385
9919
|
piArgs.unshift("--model");
|
|
9386
9920
|
}
|
|
9921
|
+
if (!hasCliOption(piArgs, "--mode")) {
|
|
9922
|
+
piArgs.push("--mode", process.env.RIG_PI_TRANSPORT?.trim() === "print" ? "json" : "rpc");
|
|
9923
|
+
if (process.env.RIG_PI_TRANSPORT?.trim() === "print" && !hasCliOption(piArgs, "--print")) {
|
|
9924
|
+
piArgs.push("--print");
|
|
9925
|
+
}
|
|
9926
|
+
}
|
|
9387
9927
|
return piArgs;
|
|
9388
9928
|
}
|
|
9389
9929
|
return [
|
|
@@ -9481,23 +10021,44 @@ function normalizePiModelForProvider(model, provider) {
|
|
|
9481
10021
|
}
|
|
9482
10022
|
return model;
|
|
9483
10023
|
}
|
|
10024
|
+
function resolveFromShellPath(binary) {
|
|
10025
|
+
const resolved = Bun.spawnSync(["sh", "-lc", `command -v ${binary}`], {
|
|
10026
|
+
stdout: "pipe",
|
|
10027
|
+
stderr: "ignore",
|
|
10028
|
+
stdin: "ignore",
|
|
10029
|
+
env: process.env
|
|
10030
|
+
});
|
|
10031
|
+
if (resolved.exitCode !== 0)
|
|
10032
|
+
return null;
|
|
10033
|
+
const path = resolved.stdout.toString().trim().split(/\r?\n/)[0]?.trim();
|
|
10034
|
+
return path || null;
|
|
10035
|
+
}
|
|
10036
|
+
function resolveBundledPiBinary() {
|
|
10037
|
+
try {
|
|
10038
|
+
const packageJson = requireFromRuntime.resolve("@earendil-works/pi-coding-agent/package.json");
|
|
10039
|
+
const binaryPath = resolve36(packageJson, "..", "dist", "cli.js");
|
|
10040
|
+
return existsSync34(binaryPath) ? binaryPath : null;
|
|
10041
|
+
} catch {
|
|
10042
|
+
return null;
|
|
10043
|
+
}
|
|
10044
|
+
}
|
|
9484
10045
|
function providerBinary(provider) {
|
|
9485
10046
|
if (provider === "codex") {
|
|
9486
|
-
return Bun.which("codex") || "codex";
|
|
10047
|
+
return resolveFromShellPath("codex") || Bun.which("codex") || "codex";
|
|
9487
10048
|
}
|
|
9488
10049
|
if (provider === "pi") {
|
|
9489
|
-
return Bun.which("pi") || "pi";
|
|
10050
|
+
return process.env.RIG_PI_BINARY?.trim() || resolveBundledPiBinary() || resolveFromShellPath("pi") || Bun.which("pi") || "pi";
|
|
9490
10051
|
}
|
|
9491
10052
|
try {
|
|
9492
10053
|
return resolveClaudeBinaryPath();
|
|
9493
10054
|
} catch {
|
|
9494
|
-
return Bun.which("claude") || "claude";
|
|
10055
|
+
return resolveFromShellPath("claude") || Bun.which("claude") || "claude";
|
|
9495
10056
|
}
|
|
9496
10057
|
}
|
|
9497
10058
|
function emitWrapperEvent(type, payload) {
|
|
9498
10059
|
console.log(`__RIG_WRAPPER_EVENT__${JSON.stringify({ type, payload, at: new Date().toISOString() })}`);
|
|
9499
10060
|
}
|
|
9500
|
-
function
|
|
10061
|
+
function sleep2(ms) {
|
|
9501
10062
|
return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
|
|
9502
10063
|
}
|
|
9503
10064
|
async function waitForDirtyBaselineReady(runtime, taskId) {
|
|
@@ -9512,11 +10073,11 @@ async function waitForDirtyBaselineReady(runtime, taskId) {
|
|
|
9512
10073
|
workspaceDir: runtime.workspaceDir,
|
|
9513
10074
|
readyFile
|
|
9514
10075
|
});
|
|
9515
|
-
while (!
|
|
10076
|
+
while (!existsSync34(readyFile)) {
|
|
9516
10077
|
if (Date.now() >= deadline) {
|
|
9517
10078
|
throw new Error(`Timed out waiting for dirty baseline ready file: ${readyFile}`);
|
|
9518
10079
|
}
|
|
9519
|
-
await
|
|
10080
|
+
await sleep2(50);
|
|
9520
10081
|
}
|
|
9521
10082
|
emitWrapperEvent("runtime.baseline.completed", {
|
|
9522
10083
|
runtimeId: runtime.id,
|
|
@@ -9615,9 +10176,9 @@ async function updateTaskSourceAfterRun(projectRoot, taskId, runtime) {
|
|
|
9615
10176
|
}
|
|
9616
10177
|
}
|
|
9617
10178
|
function recordRuntimeHandoff(hostProjectRoot, runtime, taskId, exitCode) {
|
|
9618
|
-
const handoffDir =
|
|
9619
|
-
|
|
9620
|
-
const handoffPath =
|
|
10179
|
+
const handoffDir = resolve36(hostProjectRoot, ".rig/runtime/handoffs");
|
|
10180
|
+
mkdirSync20(handoffDir, { recursive: true });
|
|
10181
|
+
const handoffPath = resolve36(handoffDir, `${taskId}-${Date.now()}.json`);
|
|
9621
10182
|
const handoff = {
|
|
9622
10183
|
taskId,
|
|
9623
10184
|
runtimeId: runtime.id,
|
|
@@ -9683,13 +10244,13 @@ async function readTaskMetadata2(taskRoot, taskId) {
|
|
|
9683
10244
|
async function readTaskConfigHints(taskRoot, taskId) {
|
|
9684
10245
|
const runtimeContext = loadRuntimeContextFromEnv();
|
|
9685
10246
|
const candidates = [
|
|
9686
|
-
runtimeContext?.monorepoMainRoot ?
|
|
9687
|
-
process.env.MONOREPO_MAIN_ROOT?.trim() ?
|
|
9688
|
-
|
|
9689
|
-
|
|
10247
|
+
runtimeContext?.monorepoMainRoot ? resolve36(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
|
|
10248
|
+
process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve36(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
|
|
10249
|
+
resolve36(taskRoot, ".rig", "task-config.json"),
|
|
10250
|
+
resolve36(taskRoot, "rig", "task-config.json")
|
|
9690
10251
|
].filter(Boolean);
|
|
9691
10252
|
for (const configPath of candidates) {
|
|
9692
|
-
if (!
|
|
10253
|
+
if (!existsSync34(configPath)) {
|
|
9693
10254
|
continue;
|
|
9694
10255
|
}
|
|
9695
10256
|
try {
|
|
@@ -9726,6 +10287,9 @@ export {
|
|
|
9726
10287
|
updateTaskSourceAfterRun,
|
|
9727
10288
|
startOptionalRuntimeSnapshotSidecar,
|
|
9728
10289
|
shouldBypassProviderSandboxOnPlatform,
|
|
10290
|
+
runPiSessionDaemonProvider,
|
|
10291
|
+
runPiRpcProviderFallback,
|
|
10292
|
+
runPiRpcProvider,
|
|
9729
10293
|
runAgentWrapper,
|
|
9730
10294
|
resolveTaskFromBeads,
|
|
9731
10295
|
resolveFinalProviderExitCode,
|