@h-rig/runtime 0.0.6-alpha.22 → 0.0.6-alpha.24

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.
Files changed (25) hide show
  1. package/dist/bin/rig-agent-dispatch.js +333 -23
  2. package/dist/src/control-plane/agent-wrapper.js +336 -23
  3. package/dist/src/control-plane/harness-main.js +142 -17
  4. package/dist/src/control-plane/hooks/completion-verification.js +142 -17
  5. package/dist/src/control-plane/native/harness-cli.js +142 -17
  6. package/dist/src/control-plane/native/pr-automation.js +142 -17
  7. package/dist/src/control-plane/native/pr-review-gate.js +142 -17
  8. package/dist/src/control-plane/native/run-ops.js +1 -1
  9. package/dist/src/control-plane/native/task-ops.js +142 -17
  10. package/dist/src/control-plane/native/verifier.js +142 -17
  11. package/dist/src/control-plane/pi-sessiond/bin.js +793 -0
  12. package/dist/src/control-plane/pi-sessiond/client.js +41 -0
  13. package/dist/src/control-plane/pi-sessiond/event-hub.js +59 -0
  14. package/dist/src/control-plane/pi-sessiond/extension-ui-context.js +198 -0
  15. package/dist/src/control-plane/pi-sessiond/launcher.js +163 -0
  16. package/dist/src/control-plane/pi-sessiond/server.js +802 -0
  17. package/dist/src/control-plane/pi-sessiond/session-service.js +540 -0
  18. package/dist/src/control-plane/pi-sessiond/types.js +1 -0
  19. package/dist/src/control-plane/runtime/index.js +17 -0
  20. package/dist/src/control-plane/runtime/isolation/home.js +17 -0
  21. package/dist/src/control-plane/runtime/isolation/index.js +17 -0
  22. package/dist/src/control-plane/runtime/isolation/runner.js +17 -0
  23. package/dist/src/control-plane/runtime/isolation.js +17 -0
  24. package/dist/src/control-plane/runtime/queue.js +17 -0
  25. package/package.json +7 -7
@@ -568,8 +568,8 @@ var init_backend_bwrap = __esm(() => {
568
568
 
569
569
  // packages/runtime/src/control-plane/agent-wrapper.ts
570
570
  import { createRequire } from "module";
571
- import { resolve as resolve35 } from "path";
572
- import { existsSync as existsSync33, mkdirSync as mkdirSync19, writeFileSync as writeFileSync13 } from "fs";
571
+ import { resolve as resolve36 } from "path";
572
+ import { existsSync as existsSync34, mkdirSync as mkdirSync20, writeFileSync as writeFileSync13 } from "fs";
573
573
 
574
574
  // packages/runtime/src/control-plane/runtime/context.ts
575
575
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
@@ -5518,6 +5518,21 @@ var GITHUB_KNOWN_HOSTS = [
5518
5518
  "github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk="
5519
5519
  ].join(`
5520
5520
  `);
5521
+ function resolveControlPlaneSourceRoot(projectRoot) {
5522
+ const candidates = [
5523
+ process.env.RIG_CONTROL_PLANE_SOURCE_ROOT?.trim(),
5524
+ process.env.RIG_HOST_PROJECT_ROOT?.trim(),
5525
+ resolve25(import.meta.dir, "../../../../.."),
5526
+ projectRoot
5527
+ ].filter((value) => Boolean(value));
5528
+ for (const candidate of candidates) {
5529
+ const root = resolve25(candidate);
5530
+ if (existsSync24(resolve25(root, "packages/runtime/src/control-plane/pi-sessiond/bin.ts"))) {
5531
+ return root;
5532
+ }
5533
+ }
5534
+ return "";
5535
+ }
5521
5536
  async function runtimeEnv(projectRoot, runtime) {
5522
5537
  const bunBinaryPath = resolveBunBinaryPath();
5523
5538
  const bunDir = resolveBunInstallDir(bunBinaryPath);
@@ -5563,9 +5578,11 @@ async function runtimeEnv(projectRoot, runtime) {
5563
5578
  const runtimeRigGit = resolve25(runtime.binDir, runtimeRigGitFileName());
5564
5579
  const preferredShell = existsSync24(runtimeBash) ? runtimeBash : "/bin/bash";
5565
5580
  const nativeRuntimeLibraryPath = await materializeNativeRuntimeLibrary(runtime.binDir);
5581
+ const controlPlaneSourceRoot = resolveControlPlaneSourceRoot(projectRoot);
5566
5582
  const env = {
5567
5583
  PROJECT_RIG_ROOT: projectRoot,
5568
5584
  RIG_HOST_PROJECT_ROOT: projectRoot,
5585
+ ...controlPlaneSourceRoot ? { RIG_CONTROL_PLANE_SOURCE_ROOT: controlPlaneSourceRoot } : {},
5569
5586
  HOME: runtime.homeDir,
5570
5587
  TMPDIR: runtime.tmpDir,
5571
5588
  XDG_CACHE_HOME: runtime.cacheDir,
@@ -8884,6 +8901,163 @@ function formatJsonRpcError(error) {
8884
8901
  return parts.join(" ");
8885
8902
  }
8886
8903
 
8904
+ // packages/runtime/src/control-plane/pi-sessiond/launcher.ts
8905
+ import { randomBytes } from "crypto";
8906
+ import { existsSync as existsSync33, mkdirSync as mkdirSync19, readFileSync as readFileSync16, rmSync as rmSync13 } from "fs";
8907
+ import { dirname as dirname14, resolve as resolve35 } from "path";
8908
+ import { fileURLToPath as fileURLToPath2 } from "url";
8909
+
8910
+ // packages/runtime/src/control-plane/pi-sessiond/client.ts
8911
+ class RigPiSessionDaemonClient {
8912
+ baseUrl;
8913
+ token;
8914
+ constructor(options) {
8915
+ this.baseUrl = options.baseUrl.replace(/\/+$/, "");
8916
+ this.token = options.token;
8917
+ }
8918
+ static fromConnection(connection, token) {
8919
+ if (connection.mode === "http")
8920
+ return new RigPiSessionDaemonClient({ baseUrl: connection.baseUrl, token });
8921
+ throw new Error("Unix-socket Rig Pi daemon connections are not implemented in this build; use loopback HTTP.");
8922
+ }
8923
+ async request(method, path, body) {
8924
+ const response = await fetch(`${this.baseUrl}${path.startsWith("/") ? path : `/${path}`}`, {
8925
+ method,
8926
+ headers: {
8927
+ authorization: `Bearer ${this.token}`,
8928
+ ...body === undefined ? {} : { "content-type": "application/json" }
8929
+ },
8930
+ body: body === undefined ? undefined : JSON.stringify(body)
8931
+ });
8932
+ const text = await response.text();
8933
+ const payload = text.trim() ? JSON.parse(text) : undefined;
8934
+ if (!response.ok) {
8935
+ const message = payload && typeof payload === "object" && !Array.isArray(payload) && typeof payload.error === "string" ? payload.error : text || response.statusText;
8936
+ throw new Error(`Rig Pi session daemon request failed (${response.status}): ${message}`);
8937
+ }
8938
+ return payload;
8939
+ }
8940
+ webSocketUrl(path) {
8941
+ const url = new URL(`${this.baseUrl}${path.startsWith("/") ? path : `/${path}`}`);
8942
+ url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
8943
+ url.searchParams.set("token", this.token);
8944
+ return url.toString();
8945
+ }
8946
+ }
8947
+
8948
+ // packages/runtime/src/control-plane/pi-sessiond/launcher.ts
8949
+ var BUILD_CONFIG2 = {};
8950
+ var BAKED_RIG_SOURCE_ROOT = BUILD_CONFIG2.RIG_SOURCE_ROOT ?? "";
8951
+ async function ensureRigPiSessionDaemon(input) {
8952
+ const rootDir = resolve35(input.rootDir);
8953
+ mkdirSync19(rootDir, { recursive: true });
8954
+ const readyFile = resolve35(rootDir, "ready.json");
8955
+ const existing = readDaemonReadyFile(readyFile);
8956
+ const existingHandle = existing ? await tryReady(existing) : null;
8957
+ if (existingHandle)
8958
+ return existingHandle;
8959
+ try {
8960
+ rmSync13(readyFile, { force: true });
8961
+ } catch {}
8962
+ const token = randomBytes(32).toString("hex");
8963
+ const binPath = resolveRigPiSessionDaemonBinPath(input.env);
8964
+ const bunPath = input.env.RIG_BUN_PATH || process.execPath;
8965
+ const proc = Bun.spawn([bunPath, binPath], {
8966
+ cwd: rootDir,
8967
+ env: {
8968
+ ...input.env,
8969
+ RIG_PI_SESSIOND_ROOT: rootDir,
8970
+ RIG_PI_SESSIOND_TOKEN: token,
8971
+ RIG_PI_SESSIOND_READY_FILE: readyFile,
8972
+ RIG_PI_SESSIOND_HOST: "127.0.0.1",
8973
+ RIG_PI_SESSIOND_PORT: "0",
8974
+ ...input.version ? { RIG_VERSION: input.version } : {},
8975
+ ...input.commit ? { RIG_GIT_COMMIT: input.commit } : {}
8976
+ },
8977
+ stdin: "ignore",
8978
+ stdout: "ignore",
8979
+ stderr: "inherit"
8980
+ });
8981
+ proc.unref();
8982
+ const deadline = Date.now() + (input.timeoutMs ?? 15000);
8983
+ while (Date.now() < deadline) {
8984
+ const ready = readDaemonReadyFile(readyFile);
8985
+ const handle = ready ? await tryReady(ready) : null;
8986
+ if (handle)
8987
+ return handle;
8988
+ await sleep(100);
8989
+ }
8990
+ throw new Error(`Rig Pi session daemon did not become ready at ${readyFile}`);
8991
+ }
8992
+ function privateMetadataForDaemon(input) {
8993
+ return { public: input.publicMetadata, daemonConnection: input.connection };
8994
+ }
8995
+ async function tryReady(ready) {
8996
+ const host = typeof ready.host === "string" ? ready.host : "127.0.0.1";
8997
+ const port = typeof ready.port === "number" ? ready.port : Number(ready.port);
8998
+ const token = typeof ready.token === "string" ? ready.token : "";
8999
+ if (!Number.isFinite(port) || port <= 0 || !token)
9000
+ return null;
9001
+ const baseUrl = `http://${host}:${port}`;
9002
+ const client = new RigPiSessionDaemonClient({ baseUrl, token });
9003
+ try {
9004
+ await client.request("GET", "/health");
9005
+ } catch {
9006
+ return null;
9007
+ }
9008
+ return {
9009
+ client,
9010
+ connection: { mode: "http", baseUrl, tokenRef: tokenRefFromReady(ready) },
9011
+ token,
9012
+ ready
9013
+ };
9014
+ }
9015
+ function tokenRefFromReady(ready) {
9016
+ const token = typeof ready.token === "string" ? ready.token : "";
9017
+ return token ? `inline:${token}` : "missing";
9018
+ }
9019
+ function resolveRigPiSessionDaemonBinPath(env) {
9020
+ const explicit = env.RIG_PI_SESSIOND_BIN?.trim();
9021
+ if (explicit)
9022
+ return explicit;
9023
+ const roots = [
9024
+ env.RIG_CONTROL_PLANE_SOURCE_ROOT?.trim(),
9025
+ BAKED_RIG_SOURCE_ROOT.trim(),
9026
+ process.env.RIG_CONTROL_PLANE_SOURCE_ROOT?.trim(),
9027
+ process.env.RIG_HOST_PROJECT_ROOT?.trim(),
9028
+ process.env.PROJECT_RIG_ROOT?.trim()
9029
+ ].filter((value) => Boolean(value));
9030
+ for (const root of roots) {
9031
+ const candidate = resolve35(root, "packages/runtime/src/control-plane/pi-sessiond/bin.ts");
9032
+ if (existsSync33(candidate))
9033
+ return candidate;
9034
+ }
9035
+ const moduleCandidate = fileURLToPath2(new URL("./bin.ts", import.meta.url));
9036
+ if (existsSync33(moduleCandidate))
9037
+ return moduleCandidate;
9038
+ 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.");
9039
+ }
9040
+ function readDaemonReadyFile(path) {
9041
+ if (!existsSync33(path))
9042
+ return null;
9043
+ try {
9044
+ const parsed = JSON.parse(readFileSync16(path, "utf8"));
9045
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
9046
+ } catch {
9047
+ return null;
9048
+ }
9049
+ }
9050
+ function sleep(ms) {
9051
+ return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
9052
+ }
9053
+ function resolveRigPiSessionDaemonRoot(stateDir) {
9054
+ const root = resolve35(stateDir, "pi-sessiond");
9055
+ mkdirSync19(dirname14(root), { recursive: true });
9056
+ if (!existsSync33(root))
9057
+ mkdirSync19(root, { recursive: true });
9058
+ return root;
9059
+ }
9060
+
8887
9061
  // packages/runtime/src/control-plane/agent-wrapper.ts
8888
9062
  var requireFromRuntime = createRequire(import.meta.url);
8889
9063
  async function finalizeRuntimeSnapshot(snapshotSidecar, providerCommand, exitCode, context) {
@@ -8918,7 +9092,7 @@ async function startOptionalRuntimeSnapshotSidecar(runtime, startSidecar = start
8918
9092
  }
8919
9093
  }
8920
9094
  async function runAgentWrapper(options = {}) {
8921
- const projectRoot = resolve35(options.projectRoot || process.env.PROJECT_RIG_ROOT || process.cwd());
9095
+ const projectRoot = resolve36(options.projectRoot || process.env.PROJECT_RIG_ROOT || process.cwd());
8922
9096
  const monorepoRoot = resolveMonorepoRoot2(projectRoot);
8923
9097
  const argv = options.argv || process.argv.slice(2);
8924
9098
  if (argv.length === 0 || argv[0] === "--version" || argv[0] === "--help" || argv[0] === "help") {
@@ -8981,7 +9155,8 @@ async function runAgentWrapper(options = {}) {
8981
9155
  return 1;
8982
9156
  }
8983
9157
  const providerArgs = buildProviderArgs(provider, runtime, argv);
8984
- const providerCommand = [providerBinary(provider), ...providerArgs];
9158
+ const normalPiDaemonPath = provider === "pi" && process.env.RIG_PI_RPC_FALLBACK !== "1";
9159
+ const providerCommand = normalPiDaemonPath ? ["rig-pi-sessiond", ...providerArgs] : [providerBinary(provider), ...providerArgs];
8985
9160
  emitWrapperEvent("provider.launch", {
8986
9161
  provider,
8987
9162
  runtimeId: runtime.id,
@@ -8993,11 +9168,11 @@ async function runAgentWrapper(options = {}) {
8993
9168
  const bypassOuterRuntimeSandbox = shouldBypassProviderSandboxOnPlatform(provider, process.platform);
8994
9169
  const runClaudeCompatUnsandboxed = provider === "claude-code" && bypassOuterRuntimeSandbox;
8995
9170
  if (runClaudeCompatUnsandboxed && process.env.HOME?.trim()) {
8996
- env.CLAUDE_HOME = resolve35(process.env.HOME.trim(), ".claude");
9171
+ env.CLAUDE_HOME = resolve36(process.env.HOME.trim(), ".claude");
8997
9172
  env.RIG_CLAUDE_RUNTIME_HOME = runtime.claudeHomeDir;
8998
9173
  }
8999
9174
  if (provider === "pi") {
9000
- env.PI_CODING_AGENT_DIR = resolve35(runtime.homeDir, ".pi", "agent");
9175
+ env.PI_CODING_AGENT_DIR = resolve36(runtime.homeDir, ".pi", "agent");
9001
9176
  env.PI_CODING_AGENT_SESSION_DIR = runtime.sessionDir;
9002
9177
  }
9003
9178
  env.RIG_RUNTIME_SANDBOX = "enforce";
@@ -9031,9 +9206,19 @@ async function runAgentWrapper(options = {}) {
9031
9206
  },
9032
9207
  command: providerCommand
9033
9208
  })).command;
9034
- if (provider === "pi" && isPiRpcArgs(providerArgs)) {
9209
+ if (provider === "pi" && process.env.RIG_PI_RPC_FALLBACK !== "1") {
9035
9210
  const prompt = await readProcessStdin();
9036
- exitCode = await runPiRpcProvider({
9211
+ exitCode = await runPiSessionDaemonProvider({
9212
+ projectRoot,
9213
+ runtime,
9214
+ env,
9215
+ prompt,
9216
+ runId: process.env.RIG_SERVER_RUN_ID?.trim() || process.env.RIG_RUN_ID?.trim() || undefined,
9217
+ sessionName: process.env.RIG_SERVER_RUN_ID?.trim() ? `Rig ${process.env.RIG_SERVER_RUN_ID.trim()}` : `Rig ${runtime.taskId}`
9218
+ });
9219
+ } else if (provider === "pi" && isPiRpcArgs(providerArgs)) {
9220
+ const prompt = await readProcessStdin();
9221
+ exitCode = await runPiRpcProviderFallback({
9037
9222
  command,
9038
9223
  cwd: runtime.workspaceDir,
9039
9224
  env,
@@ -9164,7 +9349,129 @@ function steeringMessageText(entry) {
9164
9349
  function isPiRpcArgs(args) {
9165
9350
  return cliOptionValue(args, "--mode") === "rpc";
9166
9351
  }
9167
- async function runPiRpcProvider(input) {
9352
+ async function runPiSessionDaemonProvider(input) {
9353
+ const stdout = input.stdout ?? process.stdout;
9354
+ const stderr = input.stderr ?? process.stderr;
9355
+ const runId = input.runId ?? input.runtime.taskId;
9356
+ emitWrapperEvent("pi.sessiond.starting", {
9357
+ runId,
9358
+ runtimeId: input.runtime.id,
9359
+ workspaceDir: input.runtime.workspaceDir
9360
+ });
9361
+ const daemon = await ensureRigPiSessionDaemon({
9362
+ rootDir: resolveRigPiSessionDaemonRoot(input.runtime.stateDir),
9363
+ env: input.env,
9364
+ version: process.env.RIG_VERSION?.trim() || "dev",
9365
+ commit: process.env.RIG_GIT_COMMIT?.trim() || undefined
9366
+ });
9367
+ emitWrapperEvent("pi.sessiond.ready", {
9368
+ runId,
9369
+ runtimeId: input.runtime.id,
9370
+ connection: daemon.connection,
9371
+ ready: daemon.ready
9372
+ });
9373
+ const start = await daemon.client.request("POST", "/sessions", {
9374
+ runId,
9375
+ cwd: input.runtime.workspaceDir,
9376
+ agentDir: input.env.PI_CODING_AGENT_DIR || resolve36(input.runtime.homeDir, ".pi", "agent"),
9377
+ sessionDir: input.runtime.sessionDir,
9378
+ sessionName: input.sessionName
9379
+ });
9380
+ const privateMetadata = privateMetadataForDaemon({ publicMetadata: start.metadata, connection: daemon.connection });
9381
+ emitWrapperEvent("pi.session.ready", {
9382
+ runId,
9383
+ runtimeId: input.runtime.id,
9384
+ metadata: start.metadata,
9385
+ privateMetadata
9386
+ });
9387
+ const eventStream = waitForPiSessionEvents({
9388
+ url: daemon.client.webSocketUrl(`/sessions/${encodeURIComponent(start.metadata.sessionId)}/events`),
9389
+ stdout,
9390
+ stderr,
9391
+ runId
9392
+ });
9393
+ emitWrapperEvent("pi.session.event_stream.connected", { runId, sessionId: start.metadata.sessionId });
9394
+ const forwardSigterm = () => {
9395
+ daemon.client.request("POST", `/sessions/${encodeURIComponent(start.metadata.sessionId)}/abort`).catch(() => {
9396
+ return;
9397
+ });
9398
+ eventStream.close();
9399
+ };
9400
+ process.once("SIGTERM", forwardSigterm);
9401
+ try {
9402
+ if (input.prompt.trim()) {
9403
+ await daemon.client.request("POST", `/sessions/${encodeURIComponent(start.metadata.sessionId)}/prompt`, { text: input.prompt });
9404
+ emitWrapperEvent("pi.prompt.sent", { runId, sessionId: start.metadata.sessionId, bytes: Buffer.byteLength(input.prompt) });
9405
+ } else {
9406
+ emitWrapperEvent("pi.prompt.waiting", { runId, sessionId: start.metadata.sessionId, reason: "empty-initial-prompt" });
9407
+ }
9408
+ const result = await eventStream.done;
9409
+ if (result.error) {
9410
+ stderr.write(`[rig-agent] Pi session daemon stream failed: ${result.error}
9411
+ `);
9412
+ return 1;
9413
+ }
9414
+ return 0;
9415
+ } finally {
9416
+ process.off("SIGTERM", forwardSigterm);
9417
+ eventStream.close();
9418
+ }
9419
+ }
9420
+ function waitForPiSessionEvents(input) {
9421
+ let closed = false;
9422
+ let resolved = false;
9423
+ let socket = null;
9424
+ let resolveDone = () => {
9425
+ return;
9426
+ };
9427
+ const done = new Promise((resolveDoneInner) => {
9428
+ resolveDone = resolveDoneInner;
9429
+ });
9430
+ const finish = (value) => {
9431
+ if (resolved)
9432
+ return;
9433
+ resolved = true;
9434
+ resolveDone(value);
9435
+ };
9436
+ socket = new WebSocket(input.url);
9437
+ socket.addEventListener("message", (message) => {
9438
+ const text = typeof message.data === "string" ? message.data : Buffer.from(message.data).toString("utf8");
9439
+ input.stdout.write(`${text}
9440
+ `);
9441
+ const envelope = parseJsonRecord(text);
9442
+ if (!envelope)
9443
+ return;
9444
+ if (envelope.type === "pi.event") {
9445
+ const event = envelope.event && typeof envelope.event === "object" && !Array.isArray(envelope.event) ? envelope.event : null;
9446
+ if (event?.type === "agent_end") {
9447
+ emitWrapperEvent("pi.session.agent_end", { runId: input.runId, sessionId: envelope.sessionId });
9448
+ finish({});
9449
+ }
9450
+ }
9451
+ if (envelope.type === "error") {
9452
+ emitWrapperEvent("pi.session.error", { runId: input.runId, message: envelope.message, detail: envelope.detail ?? null });
9453
+ finish({ error: envelope.message });
9454
+ }
9455
+ });
9456
+ socket.addEventListener("error", () => {
9457
+ if (!closed)
9458
+ finish({ error: "WebSocket error" });
9459
+ });
9460
+ socket.addEventListener("close", () => {
9461
+ if (!closed && !resolved)
9462
+ finish({ error: "WebSocket closed before agent_end" });
9463
+ });
9464
+ return {
9465
+ done,
9466
+ close: () => {
9467
+ closed = true;
9468
+ try {
9469
+ socket?.close();
9470
+ } catch {}
9471
+ }
9472
+ };
9473
+ }
9474
+ async function runPiRpcProviderFallback(input) {
9168
9475
  const stdout = input.stdout ?? process.stdout;
9169
9476
  const stderr = input.stderr ?? process.stderr;
9170
9477
  const proc = Bun.spawn(input.command, {
@@ -9231,7 +9538,7 @@ async function runPiRpcProvider(input) {
9231
9538
  error: error instanceof Error ? error.message : String(error)
9232
9539
  });
9233
9540
  }
9234
- await sleep(1000);
9541
+ await sleep2(1000);
9235
9542
  }
9236
9543
  };
9237
9544
  const stdoutPump = pumpReadableLines(proc.stdout, (line) => {
@@ -9327,6 +9634,9 @@ function buildProviderArgs(provider, runtime, argv) {
9327
9634
  }
9328
9635
  if (provider === "pi") {
9329
9636
  const piArgs = [...argv];
9637
+ if (piArgs.includes("__rig_pi_session_daemon__")) {
9638
+ return piArgs.filter((arg) => arg !== "__rig_pi_session_daemon__");
9639
+ }
9330
9640
  const piProvider = cliOptionValue(piArgs, "--provider") || process.env.RIG_PI_PROVIDER?.trim() || "openai-codex";
9331
9641
  if (!hasCliOption(piArgs, "--provider")) {
9332
9642
  piArgs.unshift(piProvider);
@@ -9457,8 +9767,8 @@ function resolveFromShellPath(binary) {
9457
9767
  function resolveBundledPiBinary() {
9458
9768
  try {
9459
9769
  const packageJson = requireFromRuntime.resolve("@earendil-works/pi-coding-agent/package.json");
9460
- const binaryPath = resolve35(packageJson, "..", "dist", "cli.js");
9461
- return existsSync33(binaryPath) ? binaryPath : null;
9770
+ const binaryPath = resolve36(packageJson, "..", "dist", "cli.js");
9771
+ return existsSync34(binaryPath) ? binaryPath : null;
9462
9772
  } catch {
9463
9773
  return null;
9464
9774
  }
@@ -9479,7 +9789,7 @@ function providerBinary(provider) {
9479
9789
  function emitWrapperEvent(type, payload) {
9480
9790
  console.log(`__RIG_WRAPPER_EVENT__${JSON.stringify({ type, payload, at: new Date().toISOString() })}`);
9481
9791
  }
9482
- function sleep(ms) {
9792
+ function sleep2(ms) {
9483
9793
  return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
9484
9794
  }
9485
9795
  async function waitForDirtyBaselineReady(runtime, taskId) {
@@ -9494,11 +9804,11 @@ async function waitForDirtyBaselineReady(runtime, taskId) {
9494
9804
  workspaceDir: runtime.workspaceDir,
9495
9805
  readyFile
9496
9806
  });
9497
- while (!existsSync33(readyFile)) {
9807
+ while (!existsSync34(readyFile)) {
9498
9808
  if (Date.now() >= deadline) {
9499
9809
  throw new Error(`Timed out waiting for dirty baseline ready file: ${readyFile}`);
9500
9810
  }
9501
- await sleep(50);
9811
+ await sleep2(50);
9502
9812
  }
9503
9813
  emitWrapperEvent("runtime.baseline.completed", {
9504
9814
  runtimeId: runtime.id,
@@ -9562,9 +9872,9 @@ async function readPluginTaskStatus(projectRoot, taskId) {
9562
9872
  }
9563
9873
  }
9564
9874
  function recordRuntimeHandoff(hostProjectRoot, runtime, taskId, exitCode) {
9565
- const handoffDir = resolve35(hostProjectRoot, ".rig/runtime/handoffs");
9566
- mkdirSync19(handoffDir, { recursive: true });
9567
- const handoffPath = resolve35(handoffDir, `${taskId}-${Date.now()}.json`);
9875
+ const handoffDir = resolve36(hostProjectRoot, ".rig/runtime/handoffs");
9876
+ mkdirSync20(handoffDir, { recursive: true });
9877
+ const handoffPath = resolve36(handoffDir, `${taskId}-${Date.now()}.json`);
9568
9878
  const handoff = {
9569
9879
  taskId,
9570
9880
  runtimeId: runtime.id,
@@ -9630,13 +9940,13 @@ async function readTaskMetadata2(taskRoot, taskId) {
9630
9940
  async function readTaskConfigHints(taskRoot, taskId) {
9631
9941
  const runtimeContext = loadRuntimeContextFromEnv();
9632
9942
  const candidates = [
9633
- runtimeContext?.monorepoMainRoot ? resolve35(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
9634
- process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve35(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
9635
- resolve35(taskRoot, ".rig", "task-config.json"),
9636
- resolve35(taskRoot, "rig", "task-config.json")
9943
+ runtimeContext?.monorepoMainRoot ? resolve36(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
9944
+ process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve36(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
9945
+ resolve36(taskRoot, ".rig", "task-config.json"),
9946
+ resolve36(taskRoot, "rig", "task-config.json")
9637
9947
  ].filter(Boolean);
9638
9948
  for (const configPath of candidates) {
9639
- if (!existsSync33(configPath)) {
9949
+ if (!existsSync34(configPath)) {
9640
9950
  continue;
9641
9951
  }
9642
9952
  try {