@h-rig/provider-plugin 0.0.6-alpha.156 → 0.0.6-alpha.158

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 (73) hide show
  1. package/dist/bin/rig-agent-dispatch.d.ts +2 -0
  2. package/dist/bin/rig-agent-dispatch.js +863 -0
  3. package/dist/src/agent-harness/agent-mode.d.ts +1 -0
  4. package/dist/src/agent-harness/agent-mode.js +48 -0
  5. package/dist/src/agent-harness/agent-wrapper.d.ts +53 -0
  6. package/dist/src/agent-harness/agent-wrapper.js +916 -0
  7. package/dist/src/agent-harness/controlled-bash.d.ts +3 -0
  8. package/dist/src/agent-harness/controlled-bash.js +45 -0
  9. package/dist/src/agent-harness/git-ops.d.ts +2 -0
  10. package/dist/src/agent-harness/git-ops.js +27 -0
  11. package/dist/src/agent-harness/repo-ops.d.ts +8 -0
  12. package/dist/src/agent-harness/repo-ops.js +471 -0
  13. package/dist/src/agent-harness/rig-agent-entrypoint.d.ts +1 -0
  14. package/dist/src/agent-harness/rig-agent-entrypoint.js +1277 -0
  15. package/dist/src/agent-harness/rig-agent.d.ts +2 -0
  16. package/dist/src/agent-harness/rig-agent.js +1244 -0
  17. package/dist/src/agent-harness/runtime-snapshot-config.d.ts +2 -0
  18. package/dist/src/agent-harness/runtime-snapshot-config.js +25 -0
  19. package/dist/src/agent-harness/task-data.d.ts +2 -0
  20. package/dist/src/agent-harness/task-data.js +12 -0
  21. package/dist/src/agent-harness/task-ops.d.ts +10 -0
  22. package/dist/src/agent-harness/task-ops.js +53 -0
  23. package/dist/src/index.js +3366 -16
  24. package/dist/src/pi-settings-materializer.d.ts +10 -0
  25. package/dist/src/pi-settings-materializer.js +52 -0
  26. package/dist/src/plugin.d.ts +9 -2
  27. package/dist/src/plugin.js +3360 -8
  28. package/dist/src/service.d.ts +1 -1
  29. package/dist/src/session-asset-materializer-service.d.ts +13 -0
  30. package/dist/src/session-asset-materializer-service.js +124 -0
  31. package/dist/src/skill-materializer.d.ts +25 -0
  32. package/dist/src/skill-materializer.js +46 -0
  33. package/dist/src/tooling/binary-build-worker.d.ts +1 -0
  34. package/dist/src/tooling/binary-build-worker.js +323 -0
  35. package/dist/src/tooling/browser-tool-entrypoint.d.ts +2 -0
  36. package/dist/src/tooling/browser-tool-entrypoint.js +125 -0
  37. package/dist/src/tooling/browser-tools.d.ts +3 -0
  38. package/dist/src/tooling/browser-tools.js +27 -0
  39. package/dist/src/tooling/claude-router-binary.d.ts +3 -0
  40. package/dist/src/tooling/claude-router-binary.js +381 -0
  41. package/dist/src/tooling/claude-router.d.ts +22 -0
  42. package/dist/src/tooling/claude-router.js +524 -0
  43. package/dist/src/tooling/embedded-native-assets.d.ts +7 -0
  44. package/dist/src/tooling/embedded-native-assets.js +6 -0
  45. package/dist/src/tooling/file-tools.d.ts +5 -0
  46. package/dist/src/tooling/file-tools.js +224 -0
  47. package/dist/src/tooling/gateway.d.ts +4 -0
  48. package/dist/src/tooling/gateway.js +430 -0
  49. package/dist/src/tooling/native-extract.d.ts +2 -0
  50. package/dist/src/tooling/native-extract.js +44 -0
  51. package/dist/src/tooling/runtime-binary-build.d.ts +88 -0
  52. package/dist/src/tooling/runtime-binary-build.js +480 -0
  53. package/dist/src/tooling/shell-tools.d.ts +5 -0
  54. package/dist/src/tooling/shell-tools.js +217 -0
  55. package/native/darwin-arm64/rig-shell +0 -0
  56. package/native/darwin-arm64/rig-shell.build-manifest.json +4 -0
  57. package/native/darwin-arm64/rig-tools +0 -0
  58. package/native/darwin-arm64/rig-tools.build-manifest.json +4 -0
  59. package/native/darwin-x64/rig-shell +0 -0
  60. package/native/darwin-x64/rig-tools +0 -0
  61. package/native/linux-arm64/rig-shell +0 -0
  62. package/native/linux-arm64/rig-tools +0 -0
  63. package/native/linux-x64/rig-shell +0 -0
  64. package/native/linux-x64/rig-tools +0 -0
  65. package/native/win32-x64/rig-shell.exe +0 -0
  66. package/native/win32-x64/rig-tools.exe +0 -0
  67. package/package.json +54 -5
  68. package/dist/src/claude-stream-records.d.ts +0 -24
  69. package/dist/src/claude-stream-records.js +0 -158
  70. package/dist/src/codex-app-server.d.ts +0 -16
  71. package/dist/src/codex-app-server.js +0 -548
  72. package/dist/src/codex-exec-records.d.ts +0 -27
  73. package/dist/src/codex-exec-records.js +0 -203
@@ -14,6 +14,2311 @@ var __export = (target, all) => {
14
14
  });
15
15
  };
16
16
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
17
+ var __require = import.meta.require;
18
+
19
+ // packages/provider-plugin/src/agent-harness/controlled-bash.ts
20
+ import { existsSync } from "fs";
21
+ import { resolve } from "path";
22
+ import { resolveRigLayout } from "@rig/core/layout";
23
+ function controlledBashCandidates(projectRoot) {
24
+ const layout = resolveRigLayout(projectRoot);
25
+ const candidates = [
26
+ process.env.RIG_CONTROLLED_BASH_BIN?.trim() || "",
27
+ resolve(layout.binDir, "controlled-bash"),
28
+ Bun.which("controlled-bash") || ""
29
+ ];
30
+ return candidates.filter((candidate) => Boolean(candidate));
31
+ }
32
+ function resolveControlledBash(projectRoot) {
33
+ for (const candidate of controlledBashCandidates(projectRoot)) {
34
+ if (existsSync(candidate))
35
+ return candidate;
36
+ }
37
+ return null;
38
+ }
39
+ async function runControlledBash(args, options) {
40
+ const projectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim() || process.env.PROJECT_RIG_ROOT?.trim() || process.env.RIG_TASK_WORKSPACE?.trim() || process.cwd() || options.projectRootFallbackDir;
41
+ const controlled = resolveControlledBash(projectRoot);
42
+ if (!controlled) {
43
+ console.error("[rig-agent] controlled-bash entrypoint unavailable; refusing to run an unguarded shell.");
44
+ return 126;
45
+ }
46
+ const command = [controlled, ...args];
47
+ const child = Bun.spawn(command, {
48
+ stdin: "inherit",
49
+ stdout: "inherit",
50
+ stderr: "inherit",
51
+ cwd: process.cwd(),
52
+ env: {
53
+ ...process.env,
54
+ PROJECT_RIG_ROOT: projectRoot,
55
+ RIG_BASH_ACTIVE: "1"
56
+ }
57
+ });
58
+ return await child.exited;
59
+ }
60
+ var init_controlled_bash = () => {};
61
+
62
+ // packages/provider-plugin/src/agent-harness/agent-mode.ts
63
+ function looksLikeShellInvocation(args, mode = process.env.RIG_AGENT_MODE) {
64
+ if (mode === "shell") {
65
+ return true;
66
+ }
67
+ if (mode === "agent") {
68
+ return false;
69
+ }
70
+ if (args.length === 0) {
71
+ return false;
72
+ }
73
+ const first = args[0];
74
+ if (!first) {
75
+ return false;
76
+ }
77
+ const bashLikeFlags = new Set([
78
+ "-c",
79
+ "-lc",
80
+ "-l",
81
+ "-i",
82
+ "-s",
83
+ "--login",
84
+ "--noprofile",
85
+ "--norc",
86
+ "--posix",
87
+ "--rcfile",
88
+ "--init-file",
89
+ "--restricted",
90
+ "--debug",
91
+ "--debugger",
92
+ "--verbose",
93
+ "--wordexp",
94
+ "--dump-strings",
95
+ "--dump-po-strings",
96
+ "--help"
97
+ ]);
98
+ if (bashLikeFlags.has(first)) {
99
+ return true;
100
+ }
101
+ if (!first.startsWith("-")) {
102
+ return first.endsWith(".sh");
103
+ }
104
+ return false;
105
+ }
106
+
107
+ // packages/provider-plugin/src/agent-harness/git-ops.ts
108
+ import { LIFECYCLE_GIT_AGENT } from "@rig/contracts";
109
+ import { defineCapability } from "@rig/core/capability";
110
+ import { buildPluginHostContext } from "@rig/core/plugin-host-context";
111
+ import { loadCapabilityForRoot } from "@rig/core/capability-loaders";
112
+ async function ensureHostContext(projectRoot) {
113
+ let cached = hostContextByRoot.get(projectRoot);
114
+ if (!cached) {
115
+ cached = buildPluginHostContext(projectRoot);
116
+ hostContextByRoot.set(projectRoot, cached);
117
+ }
118
+ await cached;
119
+ }
120
+ async function loadLifecycleGit(projectRoot) {
121
+ await ensureHostContext(projectRoot);
122
+ const git = await loadCapabilityForRoot(projectRoot, LifecycleGitAgentCap);
123
+ if (!git) {
124
+ throw new Error("lifecycle git capability unavailable: load @rig/bundle-default-lifecycle (default bundle) before running rig-agent git commands.");
125
+ }
126
+ return git;
127
+ }
128
+ var LifecycleGitAgentCap, hostContextByRoot;
129
+ var init_git_ops = __esm(() => {
130
+ LifecycleGitAgentCap = defineCapability(LIFECYCLE_GIT_AGENT);
131
+ hostContextByRoot = new Map;
132
+ });
133
+
134
+ // packages/provider-plugin/src/agent-harness/repo-ops.ts
135
+ import { existsSync as existsSync2, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "fs";
136
+ import { basename, dirname, resolve as resolve2 } from "path";
137
+ import { loadRuntimeContext } from "@rig/core/runtime-context";
138
+ import {
139
+ MANAGED_REPO_SERVICE_CAPABILITY,
140
+ TASK_DATA_SERVICE_CAPABILITY
141
+ } from "@rig/contracts";
142
+ import { defineCapability as defineCapability2 } from "@rig/core/capability";
143
+ import { getInstalledCapability, requireInstalledCapability } from "@rig/core/capability-loaders";
144
+ import { resolveHarnessPaths } from "@rig/core/harness-paths";
145
+ function runCapture(command, cwd, env) {
146
+ const result = Bun.spawnSync(command, {
147
+ cwd,
148
+ env: env ? { ...process.env, ...env } : process.env,
149
+ stdout: "pipe",
150
+ stderr: "pipe",
151
+ stdin: "ignore"
152
+ });
153
+ return {
154
+ exitCode: result.exitCode,
155
+ stdout: result.stdout.toString(),
156
+ stderr: result.stderr.toString()
157
+ };
158
+ }
159
+ function readJsonFile(path, fallback) {
160
+ if (!existsSync2(path))
161
+ return fallback;
162
+ try {
163
+ return JSON.parse(readFileSync(path, "utf8"));
164
+ } catch {
165
+ return fallback;
166
+ }
167
+ }
168
+ function nowIso() {
169
+ return new Date().toISOString();
170
+ }
171
+ function managedRepoEntries() {
172
+ return getManagedRepoService()?.listManagedRepoEntries() ?? [];
173
+ }
174
+ function requireManagedRepoService() {
175
+ const service = getManagedRepoService();
176
+ if (!service) {
177
+ throw new Error("managed-repo service not installed: configure @rig/repos-plugin in rig.config to use managed-repo operations.");
178
+ }
179
+ return service;
180
+ }
181
+ function primaryManagedRepoId() {
182
+ const entries = managedRepoEntries();
183
+ return entries.length > 0 ? entries[0].id : null;
184
+ }
185
+ function primaryManagedRepoAlias() {
186
+ const entries = managedRepoEntries();
187
+ return entries.length > 0 ? entries[0].alias : null;
188
+ }
189
+ function repoEnsure(projectRoot, taskId) {
190
+ const monorepo = ensureMonorepoReady(projectRoot);
191
+ const resolvedTask = taskId || taskData().currentTaskId(projectRoot);
192
+ if (!resolvedTask) {
193
+ if (monorepo) {
194
+ const alias = primaryManagedRepoAlias();
195
+ if (alias) {
196
+ persistBaselinePins(projectRoot, { [alias]: monorepo.headCommit });
197
+ }
198
+ }
199
+ console.log("No active task. Refreshed baseline repo pins.");
200
+ return;
201
+ }
202
+ const pins = resolvedPins(projectRoot, resolvedTask);
203
+ applyPins(projectRoot, pins);
204
+ verifyPins(projectRoot, pins);
205
+ }
206
+ function repoPins(projectRoot, taskId) {
207
+ const resolvedTask = taskId || taskData().currentTaskId(projectRoot);
208
+ if (!resolvedTask) {
209
+ return {};
210
+ }
211
+ return resolvedPins(projectRoot, resolvedTask);
212
+ }
213
+ function repoVerify(projectRoot, taskId) {
214
+ const resolvedTask = taskId || taskData().currentTaskId(projectRoot);
215
+ if (!resolvedTask) {
216
+ console.log("No active task. Nothing to verify.");
217
+ return true;
218
+ }
219
+ const pins = resolvedPins(projectRoot, resolvedTask);
220
+ return verifyPins(projectRoot, pins);
221
+ }
222
+ function repoDiscover(projectRoot, taskId) {
223
+ const resolvedTask = taskId || taskData().currentTaskId(projectRoot);
224
+ if (!resolvedTask) {
225
+ return {};
226
+ }
227
+ const explicit = explicitPins(projectRoot, resolvedTask);
228
+ if (Object.keys(explicit).length > 0) {
229
+ return explicit;
230
+ }
231
+ return discoverPins(projectRoot, resolvedTask);
232
+ }
233
+ function repoBaseline(projectRoot, refresh = false) {
234
+ const paths = resolveRepoDiscoveryPaths(projectRoot);
235
+ if (!refresh && existsSync2(paths.baseRepoPinsPath)) {
236
+ const baseline = readJsonFile(paths.baseRepoPinsPath, { recorded_at: nowIso(), repos: {} });
237
+ return baseline.repos || {};
238
+ }
239
+ const id = primaryManagedRepoId();
240
+ if (!id) {
241
+ return persistBaselinePins(projectRoot, {});
242
+ }
243
+ const synced = requireManagedRepoService().syncManagedRepo(projectRoot, id);
244
+ const alias = primaryManagedRepoAlias() ?? id;
245
+ return persistBaselinePins(projectRoot, { [alias]: synced.headCommit });
246
+ }
247
+ function ensureMonorepoReady(projectRoot) {
248
+ const id = primaryManagedRepoId();
249
+ if (!id) {
250
+ return null;
251
+ }
252
+ const synced = requireManagedRepoService().syncManagedRepo(projectRoot, id);
253
+ const sha = synced.headCommit.slice(0, 7);
254
+ console.log(`Monorepo ready: ${synced.layout.alias}@${sha}`);
255
+ return synced;
256
+ }
257
+ function persistBaselinePins(projectRoot, repos) {
258
+ const paths = resolveRepoDiscoveryPaths(projectRoot);
259
+ mkdirSync(resolve2(paths.baseRepoPinsPath, ".."), { recursive: true });
260
+ writeFileSync(paths.baseRepoPinsPath, `${JSON.stringify({ recorded_at: nowIso(), repos }, null, 2)}
261
+ `, "utf-8");
262
+ return repos;
263
+ }
264
+ function resolvedPins(projectRoot, taskId) {
265
+ const explicit = explicitPins(projectRoot, taskId);
266
+ if (Object.keys(explicit).length > 0) {
267
+ return explicit;
268
+ }
269
+ return discoverPins(projectRoot, taskId);
270
+ }
271
+ function explicitPins(projectRoot, taskId) {
272
+ const repoPins2 = readRepoDiscoveryTaskConfig(projectRoot)[taskId]?.repo_pins || {};
273
+ const normalized = {};
274
+ const validAliases = new Set(managedRepoEntries().map((e) => e.alias));
275
+ for (const [key, value] of Object.entries(repoPins2)) {
276
+ if (!value) {
277
+ continue;
278
+ }
279
+ if (validAliases.size > 0 && !validAliases.has(key)) {
280
+ throw new Error(`Unsupported repo pin key for ${taskId}: ${key}. Known aliases: ${[...validAliases].join(", ") || "(none registered)"}`);
281
+ }
282
+ const existing = normalized[key];
283
+ if (existing && existing !== value) {
284
+ throw new Error(`Conflicting explicit repo pins for ${key}: ${existing} vs ${value}`);
285
+ }
286
+ normalized[key] = value;
287
+ }
288
+ return normalized;
289
+ }
290
+ function taskDependencies(projectRoot, taskId) {
291
+ return taskData().taskDependencyIds(projectRoot, taskId);
292
+ }
293
+ function discoverPins(projectRoot, taskId) {
294
+ const deps = taskDependencies(projectRoot, taskId);
295
+ if (deps.length === 0) {
296
+ return repoBaseline(projectRoot, true);
297
+ }
298
+ const paths = resolveRepoDiscoveryPaths(projectRoot);
299
+ const state = readJsonFile(paths.taskRepoCommitsPath, {});
300
+ const pinKeys = managedRepoEntries().map((e) => e.alias);
301
+ if (pinKeys.length === 0) {
302
+ return {};
303
+ }
304
+ const discovered = {};
305
+ for (const key of pinKeys) {
306
+ const commits = new Set;
307
+ for (const dep of deps) {
308
+ const fromState = state[dep]?.repos?.[key];
309
+ if (fromState) {
310
+ commits.add(fromState);
311
+ }
312
+ const fromArtifact = readPinFromArtifact(projectRoot, dep, key);
313
+ if (fromArtifact) {
314
+ commits.add(fromArtifact);
315
+ }
316
+ }
317
+ if (commits.size > 1) {
318
+ const values = [...commits].join(`
319
+ - `);
320
+ throw new Error(`Conflicting discovered pins for ${key} from dependency graph of ${taskId}:
321
+ - ${values}`);
322
+ }
323
+ if (commits.size === 1) {
324
+ discovered[key] = [...commits][0];
325
+ }
326
+ }
327
+ return discovered;
328
+ }
329
+ function readRepoDiscoveryTaskConfig(projectRoot) {
330
+ try {
331
+ return taskData().readSourceTaskConfig(projectRoot);
332
+ } catch {
333
+ return taskData().readTaskConfig(projectRoot);
334
+ }
335
+ }
336
+ function resolveRepoDiscoveryPaths(projectRoot) {
337
+ const monorepoRoot = requireManagedRepoService().resolveMonorepoRepoLayout(projectRoot).checkoutRoot;
338
+ const explicitHostProjectRoot = (process.env.RIG_HOST_PROJECT_ROOT || "").trim();
339
+ const normalizedProjectRoot = resolve2(projectRoot);
340
+ const hostProjectRoot = explicitHostProjectRoot && shouldUseHostProjectStateRoot(normalizedProjectRoot) ? explicitHostProjectRoot : normalizedProjectRoot;
341
+ const stateDir = resolve2(hostProjectRoot, ".rig", "state");
342
+ return {
343
+ monorepoRoot,
344
+ taskRepoCommitsPath: resolve2(stateDir, "task-repo-commits.json"),
345
+ baseRepoPinsPath: resolve2(stateDir, "base-repo-pins.json")
346
+ };
347
+ }
348
+ function shouldUseHostProjectStateRoot(projectRoot) {
349
+ const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
350
+ if (runtimeWorkspace && resolve2(runtimeWorkspace) === projectRoot) {
351
+ return true;
352
+ }
353
+ return basename(dirname(projectRoot)) === ".worktrees";
354
+ }
355
+ function readPinFromArtifact(projectRoot, depTask, repoKey) {
356
+ const snapshot = resolve2(taskData().artifactDirForId(projectRoot, depTask), "git-state.txt");
357
+ if (!existsSync2(snapshot)) {
358
+ return "";
359
+ }
360
+ const content = readFileSync(snapshot, "utf-8");
361
+ const chunk = content.split(/\r?\n/);
362
+ let inSection = false;
363
+ for (const line of chunk) {
364
+ if (line.startsWith("## ")) {
365
+ inSection = line.startsWith(`## ${repoKey}`);
366
+ continue;
367
+ }
368
+ if (!inSection) {
369
+ continue;
370
+ }
371
+ if (line.startsWith("head:")) {
372
+ return line.replace(/^head:\s*/, "").trim();
373
+ }
374
+ }
375
+ return "";
376
+ }
377
+ function repoPath(projectRoot, key) {
378
+ const managed = getManagedRepoService()?.resolveManagedRepoLayoutByAlias(projectRoot, key) ?? null;
379
+ if (managed) {
380
+ return managed.checkoutRoot;
381
+ }
382
+ return key.startsWith("/") ? key : resolve2(projectRoot, key);
383
+ }
384
+ function applyPins(projectRoot, pins) {
385
+ for (const [key, commit] of Object.entries(pins)) {
386
+ const path = repoPath(projectRoot, key);
387
+ if (!existsSync2(resolve2(path, ".git"))) {
388
+ throw new Error(`Repo for pin not available: ${key} (${path})`);
389
+ }
390
+ let hasCommit = runGitCapture(["git", "-C", path, "cat-file", "-e", `${commit}^{commit}`], projectRoot).exitCode === 0;
391
+ if (!hasCommit) {
392
+ runGitCapture(["git", "-C", path, "fetch", "--all", "--tags", "--prune"], projectRoot);
393
+ hasCommit = runGitCapture(["git", "-C", path, "cat-file", "-e", `${commit}^{commit}`], projectRoot).exitCode === 0;
394
+ }
395
+ if (!hasCommit) {
396
+ throw new Error(`Commit not found for ${key}: ${commit}`);
397
+ }
398
+ const current = runGitCapture(["git", "-C", path, "rev-parse", "HEAD"], projectRoot).stdout.trim();
399
+ if (current === commit) {
400
+ console.log(`Repo pin: ${key} already at ${commit}`);
401
+ continue;
402
+ }
403
+ const branch = runGitCapture(["git", "-C", path, "rev-parse", "--abbrev-ref", "HEAD"], projectRoot).stdout.trim();
404
+ const checkout = branch.startsWith("rig/") ? runGitCapture(["git", "-C", path, "reset", "--hard", commit], projectRoot) : runGitCapture(["git", "-C", path, "checkout", "--detach", commit], projectRoot);
405
+ if (checkout.exitCode !== 0) {
406
+ throw new Error(`Failed to apply repo pin ${key} -> ${commit}:
407
+ ${checkout.stderr || checkout.stdout}`);
408
+ }
409
+ console.log(`Repo pin: ${key} -> ${commit}`);
410
+ }
411
+ }
412
+ function verifyPins(projectRoot, pins) {
413
+ let ok = true;
414
+ for (const [key, expected] of Object.entries(pins)) {
415
+ const path = repoPath(projectRoot, key);
416
+ if (!existsSync2(resolve2(path, ".git"))) {
417
+ console.error(`ERROR: repo missing during pin verification: ${key}`);
418
+ ok = false;
419
+ continue;
420
+ }
421
+ const current = runGitCapture(["git", "-C", path, "rev-parse", "HEAD"], projectRoot).stdout.trim();
422
+ if (current === expected) {
423
+ console.log(`Repo verify: ${key} at ${current}`);
424
+ } else {
425
+ console.error(`ERROR: repo pin mismatch for ${key}: expected ${expected}, got ${current}`);
426
+ ok = false;
427
+ }
428
+ }
429
+ return ok;
430
+ }
431
+ function runGitCapture(command, projectRoot) {
432
+ return runCapture(command, projectRoot, resolveRuntimeGitEnv());
433
+ }
434
+ function resolveRuntimeGitEnv() {
435
+ if (process.env.GIT_SSH_COMMAND?.trim()) {
436
+ return {
437
+ HOME: process.env.HOME ?? "",
438
+ GIT_SSH_COMMAND: process.env.GIT_SSH_COMMAND
439
+ };
440
+ }
441
+ const runtimeRoot = process.env.RIG_RUNTIME_HOME?.trim() || (process.env.RIG_RUNTIME_CONTEXT_FILE?.trim() ? resolve2(process.env.RIG_RUNTIME_CONTEXT_FILE, "..") : inferRuntimeRootFromWorkspace(process.cwd()));
442
+ const runtimeHome = runtimeRoot ? resolve2(runtimeRoot, "home") : process.env.HOME?.trim() || "";
443
+ if (!runtimeHome) {
444
+ return;
445
+ }
446
+ const knownHostsPath = resolve2(runtimeHome, ".ssh", "known_hosts");
447
+ if (!existsSync2(knownHostsPath)) {
448
+ return { HOME: runtimeHome };
449
+ }
450
+ const agentSshKey = resolve2(runtimeHome, ".ssh", "rig-agent-key");
451
+ const sshParts = [
452
+ "ssh",
453
+ `-o UserKnownHostsFile="${knownHostsPath}"`,
454
+ "-o StrictHostKeyChecking=yes",
455
+ "-F /dev/null"
456
+ ];
457
+ if (existsSync2(agentSshKey)) {
458
+ sshParts.splice(1, 0, `-i "${agentSshKey}"`, "-o IdentitiesOnly=yes");
459
+ }
460
+ return {
461
+ HOME: runtimeHome,
462
+ GIT_SSH_COMMAND: sshParts.join(" ")
463
+ };
464
+ }
465
+ function inferRuntimeRootFromWorkspace(cwd) {
466
+ const contextPath = findRuntimeContextFile(cwd);
467
+ if (!contextPath || !existsSync2(contextPath)) {
468
+ return "";
469
+ }
470
+ try {
471
+ loadRuntimeContext(contextPath);
472
+ return resolve2(contextPath, "..");
473
+ } catch {
474
+ return "";
475
+ }
476
+ }
477
+ function findRuntimeContextFile(startPath) {
478
+ let current = resolve2(startPath);
479
+ while (true) {
480
+ const candidate = resolve2(current, "runtime-context.json");
481
+ if (existsSync2(candidate)) {
482
+ return candidate;
483
+ }
484
+ const parent = resolve2(current, "..");
485
+ if (parent === current) {
486
+ return "";
487
+ }
488
+ current = parent;
489
+ }
490
+ }
491
+ var ManagedRepoCap, getManagedRepoService = () => getInstalledCapability(ManagedRepoCap), TaskDataCap, taskData = () => requireInstalledCapability(TaskDataCap, "task-data capability unavailable: load @rig/task-sources-plugin (default bundle) before resolving task repos.");
492
+ var init_repo_ops = __esm(() => {
493
+ ManagedRepoCap = defineCapability2(MANAGED_REPO_SERVICE_CAPABILITY);
494
+ TaskDataCap = defineCapability2(TASK_DATA_SERVICE_CAPABILITY);
495
+ });
496
+
497
+ // packages/provider-plugin/src/agent-harness/task-data.ts
498
+ import { TASK_DATA_SERVICE_CAPABILITY as TASK_DATA_SERVICE_CAPABILITY2 } from "@rig/contracts";
499
+ import { defineCapability as defineCapability3 } from "@rig/core/capability";
500
+ import { requireInstalledCapability as requireInstalledCapability2 } from "@rig/core/capability-loaders";
501
+ function taskData2() {
502
+ return requireInstalledCapability2(TaskDataCap2, "task-data capability unavailable: load @rig/task-sources-plugin (default bundle) before running the provider agent harness.");
503
+ }
504
+ var TaskDataCap2;
505
+ var init_task_data = __esm(() => {
506
+ TaskDataCap2 = defineCapability3(TASK_DATA_SERVICE_CAPABILITY2);
507
+ });
508
+
509
+ // packages/provider-plugin/src/agent-harness/task-ops.ts
510
+ function taskArtifactDir(projectRoot, taskId) {
511
+ return taskData2().taskArtifactDir(projectRoot, taskId);
512
+ }
513
+ function taskArtifacts(projectRoot, taskId) {
514
+ taskData2().taskArtifacts(projectRoot, taskId);
515
+ }
516
+ function taskArtifactWrite(projectRoot, filename, content, taskId) {
517
+ taskData2().taskArtifactWrite(projectRoot, filename, content, taskId);
518
+ }
519
+ function taskDeps(projectRoot, taskId) {
520
+ return taskData2().taskDeps(projectRoot, taskId);
521
+ }
522
+ function taskInfo(projectRoot, taskId) {
523
+ return taskData2().taskInfo(projectRoot, taskId);
524
+ }
525
+ function taskLookup(projectRoot, id) {
526
+ return taskData2().taskLookup(projectRoot, id);
527
+ }
528
+ function taskRecord(projectRoot, type, text, taskId) {
529
+ taskData2().taskRecord(projectRoot, type, text, taskId);
530
+ }
531
+ function taskScope(projectRoot, expandFiles, taskId) {
532
+ return taskData2().taskScope(projectRoot, expandFiles, taskId);
533
+ }
534
+ function taskStatus(projectRoot) {
535
+ taskData2().taskStatus(projectRoot);
536
+ }
537
+ function taskValidate(projectRoot, taskId, validatorRegistry) {
538
+ return taskData2().taskValidate(projectRoot, taskId, validatorRegistry);
539
+ }
540
+ var init_task_ops = __esm(() => {
541
+ init_task_data();
542
+ });
543
+
544
+ // packages/provider-plugin/src/agent-harness/rig-agent.ts
545
+ var exports_rig_agent = {};
546
+ __export(exports_rig_agent, {
547
+ looksLikeShellInvocation: () => looksLikeShellInvocation
548
+ });
549
+ import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
550
+ import { dirname as dirname2, resolve as resolve3 } from "path";
551
+ import { readBuildConfig } from "@rig/core/build-time-config";
552
+ import { COMPLETION_VERIFICATION_CAPABILITY, MEMORY } from "@rig/contracts";
553
+ import { defineCapability as defineCapability4 } from "@rig/core/capability";
554
+ import { buildProjectPluginHost, loadCapabilityForRoot as loadCapabilityForRoot2 } from "@rig/core/capability-loaders";
555
+ import { resolveCheckoutRoot as resolveMonorepoRoot } from "@rig/core/checkout-root";
556
+ import { browserEnvFromContext, loadRuntimeContext as loadRuntimeContext2, loadRuntimeContextFromEnv } from "@rig/core/runtime-context";
557
+ import { loadDotEnvSecrets, resolveRuntimeSecrets } from "@rig/core/baked-secrets";
558
+ import { RuntimeEventBus } from "@rig/core/runtime-events";
559
+ import {
560
+ setProfile,
561
+ setReviewProfile,
562
+ showProfile,
563
+ showReviewProfile
564
+ } from "@rig/core/profile-ops";
565
+ function getContext() {
566
+ if (cachedContext !== undefined)
567
+ return cachedContext;
568
+ cachedContext = loadRuntimeContextFromEnv() ?? inferRuntimeContext();
569
+ return cachedContext;
570
+ }
571
+ function getEventBus() {
572
+ if (cachedEventBus !== undefined) {
573
+ return cachedEventBus ?? undefined;
574
+ }
575
+ const ctx = getContext();
576
+ if (!ctx) {
577
+ cachedEventBus = null;
578
+ return;
579
+ }
580
+ const runId = ctx.runtimeId || BAKED_RUNTIME_ID || "";
581
+ cachedEventBus = new RuntimeEventBus({
582
+ projectRoot: ctx.workspaceDir,
583
+ ...runId ? { runId } : {}
584
+ });
585
+ return cachedEventBus;
586
+ }
587
+ function inferRuntimeContext() {
588
+ for (const candidate of runtimeContextCandidates()) {
589
+ if (!candidate || !existsSync3(candidate)) {
590
+ continue;
591
+ }
592
+ try {
593
+ process.env.RIG_RUNTIME_CONTEXT_FILE = candidate;
594
+ return loadRuntimeContext2(candidate);
595
+ } catch {}
596
+ }
597
+ return null;
598
+ }
599
+ function runtimeContextCandidates() {
600
+ const cwd = process.cwd();
601
+ const candidates = [
602
+ resolve3(cwd, "..", "runtime-context.json"),
603
+ resolve3(cwd, ".rig", "runtime-context.json")
604
+ ];
605
+ const argv1 = process.argv[1]?.trim();
606
+ if (argv1) {
607
+ candidates.push(resolve3(argv1, "..", "..", "runtime-context.json"));
608
+ }
609
+ if (BAKED_BINARY_PATH) {
610
+ candidates.push(resolve3(BAKED_BINARY_PATH, "..", "..", "runtime-context.json"));
611
+ }
612
+ return Array.from(new Set(candidates));
613
+ }
614
+ function sha256Hex(input) {
615
+ const hasher = new Bun.CryptoHasher("sha256");
616
+ hasher.update(input);
617
+ return hasher.digest("hex");
618
+ }
619
+ function ensureRuntimeKnownHosts(runtimeHome) {
620
+ const sshDir = resolve3(runtimeHome, ".ssh");
621
+ const knownHostsPath = resolve3(sshDir, "known_hosts");
622
+ if (!existsSync3(sshDir)) {
623
+ mkdirSync2(sshDir, { recursive: true });
624
+ }
625
+ const existing = existsSync3(knownHostsPath) ? readFileSync2(knownHostsPath, "utf-8") : "";
626
+ const existingLines = new Set(existing.split(/\r?\n/).map((line) => line.trim()).filter(Boolean));
627
+ const missing = GITHUB_KNOWN_HOSTS.filter((line) => !existingLines.has(line));
628
+ if (missing.length === 0) {
629
+ return knownHostsPath;
630
+ }
631
+ try {
632
+ for (const line of missing) {
633
+ existingLines.add(line);
634
+ }
635
+ writeFileSync2(knownHostsPath, `${Array.from(existingLines).join(`
636
+ `)}
637
+ `, { mode: 420 });
638
+ } catch (err) {
639
+ const hint = existsSync3(knownHostsPath) ? "" : " \u2014 known_hosts is missing; git SSH operations may fail";
640
+ console.warn(`[rig-agent] Could not update ${knownHostsPath}: ${err instanceof Error ? err.message : String(err)}${hint}`);
641
+ }
642
+ return knownHostsPath;
643
+ }
644
+ function hydrateRuntimeProcessEnv(ctx) {
645
+ if (!ctx) {
646
+ return;
647
+ }
648
+ const contextFile = process.env.RIG_RUNTIME_CONTEXT_FILE?.trim() || inferRuntimeContextFileFromWorkspace(ctx.workspaceDir);
649
+ if (!contextFile) {
650
+ return;
651
+ }
652
+ process.env.RIG_RUNTIME_CONTEXT_FILE = contextFile;
653
+ const runtimeRoot = dirname2(resolve3(contextFile));
654
+ const runtimeHome = resolve3(runtimeRoot, "home");
655
+ const runtimeTmp = resolve3(runtimeRoot, "tmp");
656
+ const runtimeCache = resolve3(runtimeRoot, "cache");
657
+ const runtimeBin = resolve3(runtimeRoot, "bin");
658
+ const runtimeWorkspaceBin = resolve3(ctx.workspaceDir, ".rig", "bin");
659
+ const runtimeTools = resolve3(ctx.workspaceDir, "rig", "tools");
660
+ if (ctx.hostProjectRoot) {
661
+ process.env.PROJECT_RIG_ROOT = ctx.hostProjectRoot;
662
+ }
663
+ process.env.RIG_TASK_ID = ctx.taskId;
664
+ process.env.RIG_TASK_WORKSPACE = ctx.workspaceDir;
665
+ process.env.RIG_STATE_DIR = ctx.stateDir;
666
+ process.env.RIG_LOGS_DIR = ctx.logsDir;
667
+ process.env.RIG_SESSION_FILE = ctx.sessionFile;
668
+ process.env.RIG_RUNTIME_HOME = runtimeRoot;
669
+ if (!process.env.RIG_HOST_PROJECT_ROOT && ctx.hostProjectRoot) {
670
+ process.env.RIG_HOST_PROJECT_ROOT = ctx.hostProjectRoot;
671
+ }
672
+ for (const [key, value] of Object.entries(browserEnvFromContext(ctx.browser))) {
673
+ process.env[key] = value;
674
+ }
675
+ if (existsSync3(runtimeHome)) {
676
+ process.env.HOME = runtimeHome;
677
+ }
678
+ if (existsSync3(runtimeTmp)) {
679
+ process.env.TMPDIR = runtimeTmp;
680
+ }
681
+ if (existsSync3(runtimeCache)) {
682
+ process.env.XDG_CACHE_HOME = runtimeCache;
683
+ }
684
+ const workspaceSecrets = loadDotEnvSecrets(ctx.workspaceDir, process.env);
685
+ const hostWorkspaceSecrets = ctx.hostProjectRoot && ctx.hostProjectRoot !== ctx.workspaceDir ? loadDotEnvSecrets(ctx.hostProjectRoot, process.env) : {};
686
+ const resolvedSecrets = resolveRuntimeSecrets(process.env, {
687
+ ...hostWorkspaceSecrets,
688
+ ...workspaceSecrets
689
+ });
690
+ for (const [key, value] of Object.entries(resolvedSecrets)) {
691
+ if (value && !process.env[key]) {
692
+ process.env[key] = value;
693
+ }
694
+ }
695
+ if (!process.env.GITHUB_TOKEN && process.env.GH_TOKEN) {
696
+ process.env.GITHUB_TOKEN = process.env.GH_TOKEN;
697
+ }
698
+ if (!process.env.GH_TOKEN && process.env.GITHUB_TOKEN) {
699
+ process.env.GH_TOKEN = process.env.GITHUB_TOKEN;
700
+ }
701
+ if (!process.env.GREPTILE_GITHUB_TOKEN && process.env.GITHUB_TOKEN) {
702
+ process.env.GREPTILE_GITHUB_TOKEN = process.env.GITHUB_TOKEN;
703
+ }
704
+ const currentPath = process.env.PATH || "";
705
+ const pathEntries = currentPath.split(":").filter(Boolean);
706
+ for (const entry of [runtimeBin, runtimeWorkspaceBin, runtimeTools, "/usr/bin", "/bin", "/usr/sbin", "/sbin"]) {
707
+ if (existsSync3(entry) && !pathEntries.includes(entry)) {
708
+ pathEntries.unshift(entry);
709
+ }
710
+ }
711
+ process.env.PATH = pathEntries.join(":");
712
+ if (!process.env.RIG_GIT_BIN) {
713
+ const runtimeGit = resolve3(runtimeBin, "git");
714
+ process.env.RIG_GIT_BIN = existsSync3(runtimeGit) ? runtimeGit : Bun.which("git") || "/usr/bin/git";
715
+ }
716
+ const knownHosts = ensureRuntimeKnownHosts(runtimeHome);
717
+ const agentKey = resolve3(runtimeHome, ".ssh", "rig-agent-key");
718
+ const sshParts = [
719
+ "ssh",
720
+ `-o UserKnownHostsFile="${knownHosts}"`,
721
+ "-o StrictHostKeyChecking=yes",
722
+ "-F /dev/null"
723
+ ];
724
+ if (existsSync3(agentKey)) {
725
+ sshParts.splice(1, 0, `-i "${agentKey}"`, "-o IdentitiesOnly=yes");
726
+ }
727
+ process.env.GIT_SSH_COMMAND = sshParts.join(" ");
728
+ }
729
+ function inferRuntimeContextFileFromWorkspace(workspaceDir) {
730
+ const candidate = resolve3(workspaceDir, "..", "runtime-context.json");
731
+ return existsSync3(candidate) ? candidate : "";
732
+ }
733
+ async function main() {
734
+ const args = process.argv.slice(2);
735
+ hydrateRuntimeProcessEnv(getContext());
736
+ if (isVersionProbe(args)) {
737
+ await printVersion();
738
+ return;
739
+ }
740
+ if (args[0] === "internal") {
741
+ await runInternal(args.slice(1));
742
+ return;
743
+ }
744
+ const ctx = getContext();
745
+ if (!BAKED_PROJECT_ROOT && !ctx) {
746
+ console.error("[rig-agent] Runtime binary is missing baked task context and no runtime context file found.");
747
+ console.error("[rig-agent] Set RIG_RUNTIME_CONTEXT_FILE or use the compiled host dispatch binary.");
748
+ process.exit(1);
749
+ }
750
+ await verifyRuntimeManifest();
751
+ const commandResult = await runAgentCommand(args);
752
+ if (commandResult !== undefined) {
753
+ process.exit(commandResult);
754
+ }
755
+ if (looksLikeShellInvocation(args)) {
756
+ const code = await runControlledBash(args, { projectRootFallbackDir: import.meta.dir });
757
+ process.exit(code);
758
+ }
759
+ console.error(`[rig-agent] Unknown command: ${args[0] || "(none)"}. Run 'rig-agent help' for usage.`);
760
+ process.exit(1);
761
+ }
762
+ function isVersionProbe(args) {
763
+ if (args.length !== 1) {
764
+ return false;
765
+ }
766
+ return args[0] === "--version" || args[0] === "-v" || args[0] === "version";
767
+ }
768
+ async function printVersion() {
769
+ const probe = await Bun.$`claude --version`.cwd(process.cwd()).env(process.env).quiet().nothrow();
770
+ if (probe.exitCode === 0) {
771
+ const output = probe.stdout.toString().trim();
772
+ if (output) {
773
+ console.log(output);
774
+ return;
775
+ }
776
+ }
777
+ console.log("rig-agent 1.0.0");
778
+ }
779
+ async function runAgentCommand(args) {
780
+ const [command, ...rest] = args;
781
+ if (!command || !TASK_COMMANDS.has(command)) {
782
+ return;
783
+ }
784
+ const ctx = getContext();
785
+ const projectRoot = ctx?.workspaceDir || BAKED_PROJECT_ROOT || "";
786
+ const taskId = ctx?.taskId || BAKED_TASK_ID || "";
787
+ if (!projectRoot) {
788
+ console.error("[rig-agent] No project root baked in.");
789
+ return 1;
790
+ }
791
+ if (!taskId) {
792
+ console.error("[rig-agent] No task ID baked in.");
793
+ return 1;
794
+ }
795
+ try {
796
+ switch (command) {
797
+ case "info":
798
+ await taskInfo(projectRoot, taskId);
799
+ return 0;
800
+ case "scope":
801
+ await taskScope(projectRoot, rest.includes("--files"), taskId);
802
+ return 0;
803
+ case "deps":
804
+ await taskDeps(projectRoot, taskId);
805
+ return 0;
806
+ case "status":
807
+ taskStatus(projectRoot);
808
+ return 0;
809
+ case "artifacts":
810
+ taskArtifacts(projectRoot, taskId);
811
+ return 0;
812
+ case "artifact-dir":
813
+ console.log(taskArtifactDir(projectRoot, taskId));
814
+ return 0;
815
+ case "project-root":
816
+ console.log(projectRoot);
817
+ return 0;
818
+ case "monorepo-root":
819
+ console.log(resolveMonorepoRoot(projectRoot));
820
+ return 0;
821
+ case "artifact-write": {
822
+ const filename = rest[0];
823
+ if (!filename) {
824
+ console.error(`Usage: rig-agent artifact-write <filename> [--file <path>]
825
+ ` + ` Reads content from stdin (or --file), writes to the active task artifact dir.
826
+ ` + " Example: echo '...' | rig-agent artifact-write collection-audit.md");
827
+ return 1;
828
+ }
829
+ let content;
830
+ const fileIdx = rest.indexOf("--file");
831
+ const inputFile = fileIdx !== -1 ? rest[fileIdx + 1] : undefined;
832
+ if (inputFile) {
833
+ content = readFileSync2(resolve3(projectRoot, inputFile), "utf-8");
834
+ } else {
835
+ const chunks = [];
836
+ for await (const chunk of process.stdin) {
837
+ chunks.push(Buffer.from(chunk));
838
+ }
839
+ content = Buffer.concat(chunks).toString("utf-8");
840
+ }
841
+ taskArtifactWrite(projectRoot, filename, content, taskId);
842
+ return 0;
843
+ }
844
+ case "validate": {
845
+ const passed = await taskValidate(projectRoot, taskId);
846
+ return passed ? 0 : 1;
847
+ }
848
+ case "completion-verification":
849
+ case "completition-verification":
850
+ return await runCompletionVerification(projectRoot);
851
+ case "lookup": {
852
+ if (rest.length !== 1) {
853
+ console.error("Usage: rig-agent lookup <beads-id>");
854
+ return 1;
855
+ }
856
+ const lookupId = rest[0];
857
+ if (!lookupId) {
858
+ console.error("Usage: rig-agent lookup <beads-id>");
859
+ return 1;
860
+ }
861
+ console.log(taskLookup(projectRoot, lookupId));
862
+ return 0;
863
+ }
864
+ case "record": {
865
+ if (rest.length < 2) {
866
+ console.error("Usage: rig-agent record <decision|failure> <text>");
867
+ return 1;
868
+ }
869
+ const type = rest[0];
870
+ if (type !== "decision" && type !== "failure") {
871
+ console.error("Usage: rig-agent record <decision|failure> <text>");
872
+ return 1;
873
+ }
874
+ taskRecord(projectRoot, type, rest.slice(1).join(" "), taskId);
875
+ return 0;
876
+ }
877
+ case "memory": {
878
+ const memoryService = await loadCapabilityForRoot2(projectRoot, defineCapability4(MEMORY));
879
+ if (!memoryService) {
880
+ console.error("[rig-agent] Shared memory requires the @rig/memory-plugin plugin in rig.config.");
881
+ return 1;
882
+ }
883
+ const eventBus = getEventBus();
884
+ console.log(await memoryService.executeMemoryCommand({
885
+ projectRoot,
886
+ taskId,
887
+ runtimeContext: ctx,
888
+ args: rest,
889
+ ...eventBus ? { eventBus } : {}
890
+ }));
891
+ return 0;
892
+ }
893
+ case "git":
894
+ await runGitCommand(projectRoot, taskId, rest);
895
+ return 0;
896
+ case "repo":
897
+ case "repo-sync":
898
+ runRepoSyncCommand(projectRoot, taskId, rest);
899
+ return 0;
900
+ case "profile":
901
+ runProfileCommand(projectRoot, rest);
902
+ return 0;
903
+ case "review":
904
+ runReviewCommand(projectRoot, rest);
905
+ return 0;
906
+ case "help":
907
+ printAgentHelp();
908
+ return 0;
909
+ default:
910
+ return;
911
+ }
912
+ } catch (error) {
913
+ console.error(error instanceof Error ? error.message : String(error));
914
+ return 1;
915
+ }
916
+ }
917
+ async function runGitCommand(projectRoot, bakedTaskId, args) {
918
+ const [sub = "status", ...rest] = args;
919
+ const task = takeOption(rest, "--task");
920
+ const tid = task.value || bakedTaskId;
921
+ const flags = task.rest;
922
+ const git = await loadLifecycleGit(projectRoot);
923
+ switch (sub) {
924
+ case "status":
925
+ git.gitStatus(projectRoot, tid);
926
+ return;
927
+ case "changed": {
928
+ const scoped = flags.includes("--scoped");
929
+ const files = git.gitChanged(projectRoot, tid, scoped);
930
+ console.log(files.length > 0 ? files.join(`
931
+ `) : "(none)");
932
+ return;
933
+ }
934
+ case "preflight": {
935
+ const strict = flags.includes("--strict");
936
+ const ok = git.gitPreflight(projectRoot, tid, strict);
937
+ if (!ok)
938
+ throw new Error("Git preflight failed.");
939
+ return;
940
+ }
941
+ case "sync-branch":
942
+ case "ensure-branch":
943
+ git.gitSyncBranch(projectRoot, tid);
944
+ return;
945
+ case "commit": {
946
+ const target = takeOption(flags, "--target");
947
+ const message = takeOption(target.rest, "--message");
948
+ const allowEmpty = message.rest.includes("--allow-empty");
949
+ const scoped = git.shouldScopeGitCommit(message.rest, Boolean(tid));
950
+ git.gitCommit({
951
+ projectRoot,
952
+ taskId: tid,
953
+ target: target.value || "monorepo",
954
+ allowEmpty,
955
+ scoped,
956
+ ...message.value ? { message: message.value } : {}
957
+ });
958
+ return;
959
+ }
960
+ case "snapshot": {
961
+ const output = takeOption(flags, "--output");
962
+ const file = git.gitSnapshot(projectRoot, tid, output.value);
963
+ console.log(`Snapshot written: ${file}`);
964
+ return;
965
+ }
966
+ case "open-pr": {
967
+ const target = takeOption(flags, "--target");
968
+ const reviewer = takeOption(target.rest, "--reviewer");
969
+ const base = takeOption(reviewer.rest, "--base");
970
+ const title = takeOption(base.rest, "--title");
971
+ const body = takeOption(title.rest, "--body");
972
+ const draft = body.rest.includes("--draft");
973
+ const result = git.gitOpenPr({
974
+ projectRoot,
975
+ taskId: tid,
976
+ ...target.value ? { target: target.value } : {},
977
+ ...reviewer.value ? { reviewer: reviewer.value } : {},
978
+ ...base.value ? { base: base.value } : {},
979
+ ...title.value ? { title: title.value } : {},
980
+ ...body.value ? { body: body.value } : {},
981
+ draft
982
+ });
983
+ console.log(`PR ready (${result.repoLabel}): ${result.url}`);
984
+ console.log(`Reviewer assigned: ${result.reviewer} (${result.reviewerSource})`);
985
+ return;
986
+ }
987
+ default:
988
+ throw new Error(`Unknown git subcommand: ${sub}. Try: status, changed, preflight, sync-branch, commit, snapshot, open-pr`);
989
+ }
990
+ }
991
+ function runRepoSyncCommand(projectRoot, bakedTaskId, args) {
992
+ const [sub = "ensure", ...rest] = args;
993
+ const task = takeOption(rest, "--task");
994
+ const tid = task.value || bakedTaskId;
995
+ switch (sub) {
996
+ case "sync":
997
+ case "ensure":
998
+ repoEnsure(projectRoot, tid);
999
+ return;
1000
+ case "pins": {
1001
+ const pins = repoPins(projectRoot, tid);
1002
+ printPins(pins);
1003
+ return;
1004
+ }
1005
+ case "verify": {
1006
+ const ok = repoVerify(projectRoot, tid);
1007
+ if (!ok)
1008
+ throw new Error("Repo pin verification failed.");
1009
+ return;
1010
+ }
1011
+ case "discover": {
1012
+ const pins = repoDiscover(projectRoot, tid);
1013
+ printPins(pins);
1014
+ return;
1015
+ }
1016
+ case "baseline": {
1017
+ const refresh = task.rest.includes("--refresh");
1018
+ const pins = repoBaseline(projectRoot, refresh);
1019
+ printPins(pins);
1020
+ return;
1021
+ }
1022
+ default:
1023
+ throw new Error(`Unknown repo subcommand: ${sub}. Try: sync, ensure, pins, verify, discover, baseline`);
1024
+ }
1025
+ }
1026
+ function runProfileCommand(projectRoot, args) {
1027
+ const [sub = "show", ...rest] = args;
1028
+ if (sub === "show") {
1029
+ showProfile(projectRoot, rest.includes("--compact"));
1030
+ return;
1031
+ }
1032
+ if (sub === "set") {
1033
+ const first = rest[0];
1034
+ if (first === "claude-code" || first === "codex-cli" || first === "codex-app-server") {
1035
+ setProfile(projectRoot, { preset: first });
1036
+ return;
1037
+ }
1038
+ const model = takeOption(rest, "--model");
1039
+ const runtime = takeOption(model.rest, "--runtime");
1040
+ const plugin = takeOption(runtime.rest, "--plugin");
1041
+ setProfile(projectRoot, {
1042
+ ...model.value ? { model: model.value } : {},
1043
+ ...runtime.value ? { runtime: runtime.value } : {},
1044
+ ...plugin.value ? { plugin: plugin.value } : {}
1045
+ });
1046
+ return;
1047
+ }
1048
+ throw new Error(`Unknown profile subcommand: ${sub}. Try: show, set`);
1049
+ }
1050
+ function runReviewCommand(projectRoot, args) {
1051
+ const [sub = "show", ...rest] = args;
1052
+ if (sub === "show") {
1053
+ showReviewProfile(projectRoot);
1054
+ return;
1055
+ }
1056
+ if (sub === "set") {
1057
+ const mode = rest[0];
1058
+ if (!mode) {
1059
+ throw new Error("Usage: rig-agent review set <off|advisory|required> [--provider github|greptile]");
1060
+ }
1061
+ const provider = takeOption(rest.slice(1), "--provider");
1062
+ setReviewProfile(projectRoot, mode, provider.value);
1063
+ return;
1064
+ }
1065
+ throw new Error(`Unknown review subcommand: ${sub}. Try: show, set`);
1066
+ }
1067
+ function takeOption(args, option) {
1068
+ const rest = [];
1069
+ let value;
1070
+ for (let i = 0;i < args.length; i += 1) {
1071
+ const current = args[i];
1072
+ if (current === option) {
1073
+ const next = args[i + 1];
1074
+ if (!next || next.startsWith("-")) {
1075
+ throw new Error(`Missing value for ${option}`);
1076
+ }
1077
+ value = next;
1078
+ i += 1;
1079
+ continue;
1080
+ }
1081
+ if (current !== undefined) {
1082
+ rest.push(current);
1083
+ }
1084
+ }
1085
+ return { value, rest };
1086
+ }
1087
+ function printPins(pins) {
1088
+ if (Object.keys(pins).length === 0) {
1089
+ console.log("(none)");
1090
+ return;
1091
+ }
1092
+ for (const [key, value] of Object.entries(pins)) {
1093
+ console.log(`${key} ${value}`);
1094
+ }
1095
+ }
1096
+ function printAgentHelp() {
1097
+ console.log(`rig-agent \u2014 CLI for Project Rig agents
1098
+
1099
+ ORIENTATION:
1100
+ rig-agent info Your task, role, scope, deps \u2014 start here
1101
+ rig-agent scope [--files] Scope globs; --files expands to file list
1102
+ rig-agent deps Read dependency artifacts (decisions, next-actions)
1103
+ rig-agent lookup <id> Validate a beads task ID
1104
+ rig-agent status Epic/task progress overview
1105
+
1106
+ EXECUTION:
1107
+ rig-agent validate Run validation commands for your task
1108
+ rig-agent record decision "..." Record an architectural decision
1109
+ rig-agent record failure "..." Record a failed approach (cross-session only \u2014 not re-read in this session)
1110
+ rig-agent memory observe ... Promote a shared memory immediately
1111
+ rig-agent memory recall [query] Recall relevant shared memories
1112
+ rig-agent git status Task-aware git status
1113
+ rig-agent git changed Changed files (--scoped for scope-filtered)
1114
+ rig-agent git commit Task-aware commit (--target monorepo|project|both)
1115
+ rig-agent git snapshot Capture worktree state
1116
+ rig-agent git sync-branch Ensure task branch exists
1117
+ rig-agent git open-pr Create PR for task changes
1118
+ rig-agent repo sync Ensure monorepo checkout + task repo pins
1119
+ rig-agent profile show Show runtime profile
1120
+ rig-agent review show Show AI review gate settings
1121
+
1122
+ COMPLETION:
1123
+ rig-agent artifacts Scaffold completion artifacts (templates)
1124
+ rig-agent artifact-dir Print absolute artifact directory path
1125
+ rig-agent project-root Print absolute task worktree root
1126
+ rig-agent monorepo-root Print absolute monorepo root in the task worktree
1127
+ rig-agent artifact-write <filename> Write artifact from stdin
1128
+ rig-agent completion-verification Run final validation/review gate
1129
+ rig-agent completition-verification Alias for the same final gate
1130
+
1131
+ WORKFLOW:
1132
+ 1. rig-agent info Understand your assignment
1133
+ 2. rig-agent deps Read what prior tasks decided
1134
+ 3. rig-agent repo sync Align monorepo checkout + repo pins
1135
+ 4. (do your work)
1136
+ 5. rig-agent record decision "chose X because Y"
1137
+ 6. rig-agent validate Check your work
1138
+ 7. rig-agent artifacts Scaffold completion artifacts
1139
+ 8. rig-agent artifact-write collection-audit.md (write custom artifacts)
1140
+ 9. rig-agent completion-verification
1141
+ `);
1142
+ }
1143
+ async function runCompletionVerification(projectRoot) {
1144
+ const host = await buildProjectPluginHost(projectRoot);
1145
+ const run = host ? await defineCapability4(COMPLETION_VERIFICATION_CAPABILITY).resolve(host) : null;
1146
+ if (!run) {
1147
+ console.error("[rig-agent] Completion verification requires the @rig/bundle-default-lifecycle plugin in rig.config.");
1148
+ return 1;
1149
+ }
1150
+ const { ok } = await run({ projectRoot });
1151
+ return ok ? 0 : 1;
1152
+ }
1153
+ async function runInternal(args) {
1154
+ const [command = "", ...rest] = args;
1155
+ if (command === "shell") {
1156
+ const code = await runControlledBash(rest, { projectRootFallbackDir: import.meta.dir });
1157
+ process.exit(code);
1158
+ }
1159
+ if (command === "manifest-verify") {
1160
+ await verifyRuntimeManifest();
1161
+ console.log("manifest: ok");
1162
+ return;
1163
+ }
1164
+ throw new Error("Unknown internal command. Use `rig-agent internal shell <bash-args...>` or `rig-agent internal manifest-verify`.");
1165
+ }
1166
+ async function verifyRuntimeManifest() {
1167
+ if (getContext()) {
1168
+ return;
1169
+ }
1170
+ const manifestPath = BAKED_MANIFEST_PATH;
1171
+ if (!manifestPath) {
1172
+ return;
1173
+ }
1174
+ if (!existsSync3(manifestPath)) {
1175
+ throw new Error(`[rig-agent] Runtime manifest missing: ${manifestPath}`);
1176
+ }
1177
+ let manifest;
1178
+ try {
1179
+ manifest = await Bun.file(manifestPath).json();
1180
+ } catch (error) {
1181
+ throw new Error(`[rig-agent] Failed to parse runtime manifest at ${manifestPath}: ${error instanceof Error ? error.message : String(error)}`);
1182
+ }
1183
+ assertMatch("taskId", BAKED_TASK_ID, manifest.taskId);
1184
+ assertMatch("runtimeId", BAKED_RUNTIME_ID, manifest.runtimeId);
1185
+ assertMatch("scopeHash", BAKED_SCOPE_HASH, manifest.scopeHash);
1186
+ const manifestBinaryPath = manifest.binary?.path || BAKED_BINARY_PATH || process.execPath;
1187
+ const expectedHash = manifest.binary?.sha256 || "";
1188
+ if (!manifestBinaryPath || !expectedHash) {
1189
+ throw new Error(`[rig-agent] Runtime manifest is missing binary hash data (${manifestPath}).`);
1190
+ }
1191
+ if (!existsSync3(manifestBinaryPath)) {
1192
+ throw new Error(`[rig-agent] Runtime binary not found at ${manifestBinaryPath}.`);
1193
+ }
1194
+ const actualHash = sha256Hex(readFileSync2(resolve3(manifestBinaryPath)));
1195
+ if (actualHash !== expectedHash) {
1196
+ throw new Error(`[rig-agent] Runtime manifest mismatch for binary hash.
1197
+ ` + `expected=${expectedHash}
1198
+ ` + `actual=${actualHash}
1199
+ ` + `path=${manifestBinaryPath}`);
1200
+ }
1201
+ }
1202
+ function assertMatch(name, expected, actual) {
1203
+ if (!expected && !actual) {
1204
+ return;
1205
+ }
1206
+ if (expected !== (actual || "")) {
1207
+ throw new Error(`[rig-agent] Runtime manifest mismatch for ${name}: expected='${expected}' actual='${actual || ""}'.`);
1208
+ }
1209
+ }
1210
+ var BUILD_CONFIG, BAKED_BINARY_PATH, BAKED_MANIFEST_PATH, BAKED_PROJECT_ROOT, BAKED_RUNTIME_ID, BAKED_TASK_ID, BAKED_SCOPE_HASH, BAKED_INFO_OUTPUT, BAKED_DEPS_OUTPUT, BAKED_STATUS_OUTPUT, BAKED_GIT_BRANCH, BAKED_BASE_COMMIT, cachedContext, cachedEventBus, GITHUB_KNOWN_HOSTS, TASK_COMMANDS;
1211
+ var init_rig_agent = __esm(() => {
1212
+ init_controlled_bash();
1213
+ init_git_ops();
1214
+ init_repo_ops();
1215
+ init_task_ops();
1216
+ BUILD_CONFIG = readBuildConfig();
1217
+ BAKED_BINARY_PATH = BUILD_CONFIG.AGENT_BINARY_PATH ?? "";
1218
+ BAKED_MANIFEST_PATH = BUILD_CONFIG.AGENT_MANIFEST_PATH ?? "";
1219
+ BAKED_PROJECT_ROOT = BUILD_CONFIG.AGENT_PROJECT_ROOT ?? "";
1220
+ BAKED_RUNTIME_ID = BUILD_CONFIG.AGENT_RUNTIME_ID ?? "";
1221
+ BAKED_TASK_ID = BUILD_CONFIG.AGENT_TASK_ID ?? "";
1222
+ BAKED_SCOPE_HASH = BUILD_CONFIG.AGENT_SCOPE_HASH ?? "";
1223
+ BAKED_INFO_OUTPUT = BUILD_CONFIG.AGENT_INFO_OUTPUT ?? "";
1224
+ BAKED_DEPS_OUTPUT = BUILD_CONFIG.AGENT_DEPS_OUTPUT ?? "";
1225
+ BAKED_STATUS_OUTPUT = BUILD_CONFIG.AGENT_STATUS_OUTPUT ?? "";
1226
+ BAKED_GIT_BRANCH = BUILD_CONFIG.AGENT_GIT_BRANCH ?? "";
1227
+ BAKED_BASE_COMMIT = BUILD_CONFIG.AGENT_BASE_COMMIT ?? "";
1228
+ if (BAKED_BINARY_PATH) {
1229
+ const binaryDir = dirname2(BAKED_BINARY_PATH);
1230
+ const currentPath = process.env.PATH || "";
1231
+ const pathEntries = currentPath.split(":").filter(Boolean);
1232
+ if (!pathEntries.includes(binaryDir)) {
1233
+ process.env.PATH = currentPath ? `${binaryDir}:${currentPath}` : binaryDir;
1234
+ }
1235
+ }
1236
+ GITHUB_KNOWN_HOSTS = [
1237
+ "github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl",
1238
+ "github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=",
1239
+ "github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk="
1240
+ ];
1241
+ TASK_COMMANDS = new Set([
1242
+ "info",
1243
+ "scope",
1244
+ "deps",
1245
+ "status",
1246
+ "artifacts",
1247
+ "artifact-dir",
1248
+ "artifact-write",
1249
+ "project-root",
1250
+ "monorepo-root",
1251
+ "validate",
1252
+ "lookup",
1253
+ "record",
1254
+ "help",
1255
+ "completion-verification",
1256
+ "completition-verification",
1257
+ "git",
1258
+ "repo",
1259
+ "repo-sync",
1260
+ "profile",
1261
+ "review",
1262
+ "memory"
1263
+ ]);
1264
+ main().catch((error) => {
1265
+ console.error(error instanceof Error ? error.message : String(error));
1266
+ process.exit(1);
1267
+ });
1268
+ });
1269
+
1270
+ // packages/provider-plugin/src/agent-harness/rig-agent-entrypoint.ts
1271
+ var exports_rig_agent_entrypoint = {};
1272
+ __export(exports_rig_agent_entrypoint, {
1273
+ runRigAgentEntrypoint: () => runRigAgentEntrypoint
1274
+ });
1275
+ import { adopt } from "@rig/core/kernel-entrypoint";
1276
+ async function runRigAgentEntrypoint() {
1277
+ await adopt(undefined, { entrypoint: "rig-agent" });
1278
+ await Promise.resolve().then(() => (init_rig_agent(), exports_rig_agent));
1279
+ }
1280
+ var init_rig_agent_entrypoint = () => {};
1281
+
1282
+ // packages/provider-plugin/src/agent-harness/runtime-snapshot-config.ts
1283
+ import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
1284
+ import { resolve as resolve4 } from "path";
1285
+ function loadRuntimeSnapshotConfig(projectRoot) {
1286
+ const configPath = resolve4(projectRoot, "rig/policy/policy.json");
1287
+ if (!existsSync4(configPath))
1288
+ return { ...DEFAULT_RUNTIME_SNAPSHOT };
1289
+ try {
1290
+ const parsed = JSON.parse(readFileSync3(configPath, "utf8"));
1291
+ const runtimeSnapshot = parsed.runtime_snapshot;
1292
+ if (runtimeSnapshot && typeof runtimeSnapshot === "object" && !Array.isArray(runtimeSnapshot)) {
1293
+ const enabled = runtimeSnapshot.enabled;
1294
+ if (typeof enabled === "boolean")
1295
+ return { enabled };
1296
+ }
1297
+ } catch {
1298
+ return { ...DEFAULT_RUNTIME_SNAPSHOT };
1299
+ }
1300
+ return { ...DEFAULT_RUNTIME_SNAPSHOT };
1301
+ }
1302
+ var DEFAULT_RUNTIME_SNAPSHOT;
1303
+ var init_runtime_snapshot_config = __esm(() => {
1304
+ DEFAULT_RUNTIME_SNAPSHOT = { enabled: true };
1305
+ });
1306
+
1307
+ // packages/provider-plugin/src/agent-harness/agent-wrapper.ts
1308
+ var exports_agent_wrapper = {};
1309
+ __export(exports_agent_wrapper, {
1310
+ updateTaskSourceAfterRun: () => updateTaskSourceAfterRun,
1311
+ startOptionalRuntimeSnapshotSidecar: () => startOptionalRuntimeSnapshotSidecar,
1312
+ shouldBypassProviderSandboxOnPlatform: () => shouldBypassProviderSandboxOnPlatform,
1313
+ runPiRpcProviderFallback: () => runPiRpcProviderFallback,
1314
+ runPiRpcProvider: () => runPiRpcProvider,
1315
+ runAgentWrapper: () => runAgentWrapper,
1316
+ resolveTaskFromBeads: () => resolveTaskFromBeads,
1317
+ resolveRuntimeHandoffPath: () => resolveRuntimeHandoffPath,
1318
+ resolveProvider: () => resolveProvider,
1319
+ resolveFinalProviderExitCode: () => resolveFinalProviderExitCode,
1320
+ recordSnapshotMissingTaskSourceEvidence: () => recordSnapshotMissingTaskSourceEvidence,
1321
+ recordRuntimeHandoff: () => recordRuntimeHandoff,
1322
+ isTaskClosed: () => isTaskClosed,
1323
+ finalizeRuntimeSnapshot: () => finalizeRuntimeSnapshot,
1324
+ buildProviderArgs: () => buildProviderArgs
1325
+ });
1326
+ import { createRequire } from "module";
1327
+ import { resolve as resolve5 } from "path";
1328
+ import { existsSync as existsSync5, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "fs";
1329
+ import { assertPathInsideRoot, safePathSegment, taskRuntimeId } from "@rig/core/safe-identifiers";
1330
+ import {
1331
+ ISOLATION_BACKEND,
1332
+ TASK_DATA_SERVICE_CAPABILITY as TASK_DATA_SERVICE_CAPABILITY3
1333
+ } from "@rig/contracts";
1334
+ import { defineCapability as defineCapability5 } from "@rig/core/capability";
1335
+ import { requireCapabilityForRoot } from "@rig/core/capability-loaders";
1336
+ import { loadRuntimeContextFromEnv as loadRuntimeContextFromEnv2 } from "@rig/core/runtime-context";
1337
+ import { resolveCheckoutRoot as resolveMonorepoRoot2 } from "@rig/core/checkout-root";
1338
+ import { buildPluginHostContext as buildPluginHostContext2 } from "@rig/core/plugin-host-context";
1339
+ function resolveTaskDataService(projectRoot) {
1340
+ let cached = taskDataServiceByRoot.get(projectRoot);
1341
+ if (!cached) {
1342
+ cached = requireCapabilityForRoot(projectRoot, defineCapability5(TASK_DATA_SERVICE_CAPABILITY3), `No TASK_DATA_SERVICE capability is registered for project root "${projectRoot}". ` + "Install @rig/task-sources-plugin (it ships in the default bundle) so the agent " + "executor can resolve task-state reads and lifecycle updates.");
1343
+ taskDataServiceByRoot.set(projectRoot, cached);
1344
+ }
1345
+ return cached;
1346
+ }
1347
+ async function finalizeRuntimeSnapshot(snapshotSidecar, providerCommand, exitCode, context) {
1348
+ try {
1349
+ await snapshotSidecar.finalize(providerCommand, exitCode);
1350
+ return { ok: true };
1351
+ } catch (error) {
1352
+ emitWrapperEvent("runtime.snapshot.finalize.failed", {
1353
+ runtimeId: context.runtimeId,
1354
+ taskId: context.taskId,
1355
+ exitCode,
1356
+ error: error instanceof Error ? error.message : String(error)
1357
+ });
1358
+ console.error(`[rig-agent] Snapshot finalize failed for ${context.taskId}: ${error instanceof Error ? error.message : String(error)}`);
1359
+ if (exitCode !== 0) {
1360
+ throw error;
1361
+ }
1362
+ const message = error instanceof Error ? error.message : String(error);
1363
+ return { ok: false, snapshotMissing: true, error: message };
1364
+ }
1365
+ }
1366
+ async function startOptionalRuntimeSnapshotSidecar(runtime, startSidecar) {
1367
+ try {
1368
+ return await startSidecar(runtime, { instanceId: `${runtime.id}-wrapper` });
1369
+ } catch (error) {
1370
+ emitWrapperEvent("runtime.snapshot.start.failed", {
1371
+ runtimeId: runtime.id,
1372
+ taskId: runtime.taskId,
1373
+ error: error instanceof Error ? error.message : String(error)
1374
+ });
1375
+ console.error(`[rig-agent] Runtime snapshotting unavailable for ${runtime.taskId}: ${error instanceof Error ? error.message : String(error)}`);
1376
+ return null;
1377
+ }
1378
+ }
1379
+ async function runAgentWrapper(options = {}) {
1380
+ const projectRoot = resolve5(options.projectRoot || process.env.PROJECT_RIG_ROOT || process.cwd());
1381
+ const monorepoRoot = resolveMonorepoRoot2(projectRoot);
1382
+ const argv = options.argv || process.argv.slice(2);
1383
+ if (argv.length === 0 || argv[0] === "--version" || argv[0] === "--help" || argv[0] === "help") {
1384
+ console.log("[rig-agent] dispatch ready");
1385
+ return 0;
1386
+ }
1387
+ const taskId = await resolveTaskId(projectRoot, monorepoRoot);
1388
+ if (!taskId) {
1389
+ console.error("[rig-agent] No active task ID found (checked env, session, beads).");
1390
+ console.error("[rig-agent] Refusing to run unsandboxed. Ensure task runtime/session injection is active.");
1391
+ return 1;
1392
+ }
1393
+ const provider = resolveProvider();
1394
+ await printTaskContext(monorepoRoot, taskId);
1395
+ let runtime;
1396
+ let isolationBackend;
1397
+ try {
1398
+ emitWrapperEvent("runtime.provision.started", {
1399
+ projectRoot,
1400
+ taskId,
1401
+ mode: "worktree"
1402
+ });
1403
+ isolationBackend = await requireCapabilityForRoot(projectRoot, defineCapability5(ISOLATION_BACKEND), `No ISOLATION_BACKEND capability is registered for project root "${projectRoot}". ` + "Install @rig/isolation-plugin (it ships in the default bundle) so runtime provisioning can resolve a backend.");
1404
+ const taskRecordReader = taskRecordReaderFromEnv(taskId);
1405
+ runtime = await isolationBackend.ensureAgentRuntime({
1406
+ projectRoot,
1407
+ id: taskRuntimeId(taskId),
1408
+ taskId,
1409
+ mode: "worktree",
1410
+ provider,
1411
+ ...taskRecordReader ? { taskRecordReader } : {},
1412
+ preserveTaskArtifacts: process.env.RIG_RUN_RESUME === "1" || process.env.RIG_RUNTIME_ARTIFACT_CLEANUP === "preserve"
1413
+ });
1414
+ emitWrapperEvent("runtime.provision.completed", {
1415
+ runtimeId: runtime.id,
1416
+ taskId,
1417
+ workspaceDir: runtime.workspaceDir,
1418
+ sessionDir: runtime.sessionDir,
1419
+ logsDir: runtime.logsDir,
1420
+ stateDir: runtime.stateDir,
1421
+ contextFile: runtime.contextFile,
1422
+ snapshotManaged: true
1423
+ });
1424
+ } catch (error) {
1425
+ emitWrapperEvent("runtime.provision.failed", {
1426
+ taskId,
1427
+ error: error instanceof Error ? error.message : String(error)
1428
+ });
1429
+ console.error(`[rig-agent] Failed to provision runtime: ${error}`);
1430
+ return 1;
1431
+ }
1432
+ try {
1433
+ await waitForDirtyBaselineReady(runtime, taskId);
1434
+ } catch (error) {
1435
+ emitWrapperEvent("runtime.baseline.failed", {
1436
+ runtimeId: runtime.id,
1437
+ taskId,
1438
+ workspaceDir: runtime.workspaceDir,
1439
+ error: error instanceof Error ? error.message : String(error)
1440
+ });
1441
+ console.error(`[rig-agent] Failed to apply selected baseline before provider launch: ${error}`);
1442
+ return 1;
1443
+ }
1444
+ const providerArgs = buildProviderArgs(provider, runtime, argv);
1445
+ const providerCommand = [providerBinary(provider), ...providerArgs];
1446
+ emitWrapperEvent("provider.launch", {
1447
+ provider,
1448
+ runtimeId: runtime.id,
1449
+ taskId,
1450
+ workspaceDir: runtime.workspaceDir,
1451
+ command: providerCommand
1452
+ });
1453
+ const env = await isolationBackend.runtimeEnv(projectRoot, runtime);
1454
+ const bypassOuterRuntimeSandbox = shouldBypassProviderSandboxOnPlatform(provider, process.platform);
1455
+ if (provider === "pi") {
1456
+ env.PI_CODING_AGENT_DIR = resolve5(runtime.homeDir, ".pi", "agent");
1457
+ env.PI_CODING_AGENT_SESSION_DIR = runtime.sessionDir;
1458
+ }
1459
+ env.RIG_RUNTIME_SANDBOX = process.env.RIG_RUNTIME_SANDBOX?.trim() || "enforce";
1460
+ const snapshotEnabled = loadRuntimeSnapshotConfig(projectRoot).enabled;
1461
+ const snapshotSidecar = snapshotEnabled ? await startOptionalRuntimeSnapshotSidecar(runtime, (rt, opts) => isolationBackend.startRuntimeSnapshotSidecar(rt, opts)) : null;
1462
+ let exitCode = 1;
1463
+ let snapshotFinalizeResult = { ok: true };
1464
+ try {
1465
+ const command = bypassOuterRuntimeSandbox ? providerCommand : (await isolationBackend.wrapRuntimeSandbox({
1466
+ projectRoot,
1467
+ runtime: {
1468
+ id: runtime.id,
1469
+ mode: runtime.mode,
1470
+ rootDir: runtime.rootDir,
1471
+ workspaceDir: runtime.workspaceDir,
1472
+ binDir: runtime.binDir,
1473
+ homeDir: runtime.homeDir,
1474
+ tmpDir: runtime.tmpDir,
1475
+ cacheDir: runtime.cacheDir,
1476
+ stateDir: runtime.stateDir,
1477
+ sessionDir: runtime.sessionDir,
1478
+ claudeHomeDir: runtime.claudeHomeDir
1479
+ },
1480
+ command: providerCommand
1481
+ })).command;
1482
+ if (isPiRpcArgs(providerArgs)) {
1483
+ const prompt = await readProcessStdin();
1484
+ const runId = process.env.RIG_SERVER_RUN_ID?.trim();
1485
+ exitCode = await runPiRpcProviderFallback({
1486
+ command,
1487
+ cwd: runtime.workspaceDir,
1488
+ env,
1489
+ prompt,
1490
+ ...runId ? { runId } : {},
1491
+ sessionName: runId ? `Rig ${runId}` : `Rig ${runtime.taskId}`
1492
+ });
1493
+ } else {
1494
+ const proc = Bun.spawn(command, {
1495
+ cwd: runtime.workspaceDir,
1496
+ env,
1497
+ stdin: "inherit",
1498
+ stdout: "inherit",
1499
+ stderr: "inherit"
1500
+ });
1501
+ exitCode = await proc.exited;
1502
+ }
1503
+ if (snapshotSidecar) {
1504
+ snapshotFinalizeResult = await finalizeRuntimeSnapshot(snapshotSidecar, providerCommand, exitCode, {
1505
+ runtimeId: runtime.id,
1506
+ taskId
1507
+ });
1508
+ }
1509
+ } catch (error) {
1510
+ if (snapshotSidecar) {
1511
+ await snapshotSidecar.cancel();
1512
+ }
1513
+ throw error;
1514
+ }
1515
+ const serverManagedRun = Boolean(process.env.RIG_SERVER_RUN_ID?.trim());
1516
+ const taskClosed = await isTaskClosed(monorepoRoot, taskId);
1517
+ const finalExitCode = resolveFinalProviderExitCode({
1518
+ providerExitCode: exitCode,
1519
+ taskClosed,
1520
+ serverManagedRun
1521
+ });
1522
+ const snapshotMissing = !snapshotFinalizeResult.ok;
1523
+ const handoffRequired = exitCode !== 0 || snapshotMissing || !taskClosed && !serverManagedRun;
1524
+ emitWrapperEvent("provider.completed", {
1525
+ provider,
1526
+ runtimeId: runtime.id,
1527
+ taskId,
1528
+ exitCode: finalExitCode,
1529
+ providerExitCode: exitCode,
1530
+ taskClosed,
1531
+ serverManagedRun,
1532
+ handoffRequired,
1533
+ snapshotMissing,
1534
+ ...!snapshotFinalizeResult.ok ? { snapshotFinalizeError: snapshotFinalizeResult.error } : {}
1535
+ });
1536
+ if (handoffRequired) {
1537
+ recordRuntimeHandoff(projectRoot, runtime, taskId, exitCode, {
1538
+ snapshotMissing,
1539
+ snapshotFinalizeError: snapshotFinalizeResult.ok ? null : snapshotFinalizeResult.error
1540
+ });
1541
+ if (!snapshotFinalizeResult.ok) {
1542
+ await recordSnapshotMissingTaskSourceEvidence(projectRoot, taskId, runtime, snapshotFinalizeResult.error);
1543
+ }
1544
+ }
1545
+ return finalExitCode;
1546
+ }
1547
+ function parseJsonRecord(line) {
1548
+ try {
1549
+ const parsed = JSON.parse(line);
1550
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
1551
+ } catch {
1552
+ return null;
1553
+ }
1554
+ }
1555
+ async function readProcessStdin() {
1556
+ if (process.stdin.isTTY)
1557
+ return "";
1558
+ return await new Promise((resolveRead) => {
1559
+ let data = "";
1560
+ process.stdin.setEncoding("utf8");
1561
+ process.stdin.on("data", (chunk) => {
1562
+ data += String(chunk);
1563
+ });
1564
+ process.stdin.on("end", () => resolveRead(data));
1565
+ process.stdin.resume();
1566
+ });
1567
+ }
1568
+ async function pumpReadableLines(stream, onLine) {
1569
+ if (!stream)
1570
+ return;
1571
+ const reader = stream.getReader();
1572
+ const decoder = new TextDecoder;
1573
+ let buffer = "";
1574
+ try {
1575
+ while (true) {
1576
+ const { done, value } = await reader.read();
1577
+ if (done)
1578
+ break;
1579
+ buffer += decoder.decode(value, { stream: true });
1580
+ const parts = buffer.split(/\r?\n/);
1581
+ buffer = parts.pop() ?? "";
1582
+ for (const part of parts)
1583
+ onLine(part);
1584
+ }
1585
+ buffer += decoder.decode();
1586
+ if (buffer)
1587
+ onLine(buffer);
1588
+ } finally {
1589
+ reader.releaseLock();
1590
+ }
1591
+ }
1592
+ function isBlockingPiRpcUiRequest(record) {
1593
+ if (record.type !== "extension_ui_request")
1594
+ return false;
1595
+ return record.method === "select" || record.method === "confirm" || record.method === "input" || record.method === "editor";
1596
+ }
1597
+ function writeRpcCommand(stdin, command) {
1598
+ stdin.write(`${JSON.stringify(command)}
1599
+ `);
1600
+ }
1601
+ function joinUrl(baseUrl, pathname) {
1602
+ return `${baseUrl.replace(/\/+$/, "")}${pathname.startsWith("/") ? pathname : `/${pathname}`}`;
1603
+ }
1604
+ async function readQueuedSteeringFromServer(input) {
1605
+ if (!input.serverUrl || !input.runId)
1606
+ return [];
1607
+ const headers = {};
1608
+ if (input.authToken)
1609
+ headers.authorization = `Bearer ${input.authToken}`;
1610
+ if (input.projectRoot)
1611
+ headers["x-rig-project-root"] = input.projectRoot;
1612
+ const response = await fetch(joinUrl(input.serverUrl, `/api/runs/${encodeURIComponent(input.runId)}/steering?ack=1`), { headers });
1613
+ if (!response.ok) {
1614
+ throw new Error(`steering read rejected (${response.status}) at ${input.serverUrl}`);
1615
+ }
1616
+ const payload = await response.json().catch(() => null);
1617
+ const messages = payload && typeof payload === "object" && !Array.isArray(payload) ? payload.messages : null;
1618
+ return Array.isArray(messages) ? messages.filter((entry) => Boolean(entry && typeof entry === "object" && !Array.isArray(entry))) : [];
1619
+ }
1620
+ function steeringMessageText(entry) {
1621
+ const message = typeof entry.message === "string" ? entry.message.trim() : "";
1622
+ return message || null;
1623
+ }
1624
+ function isPiRpcArgs(args) {
1625
+ return cliOptionValue(args, "--mode") === "rpc";
1626
+ }
1627
+ async function runPiRpcProviderFallback(input) {
1628
+ const stdout = input.stdout ?? process.stdout;
1629
+ const stderr = input.stderr ?? process.stderr;
1630
+ const proc = Bun.spawn(input.command, {
1631
+ cwd: input.cwd,
1632
+ env: input.env,
1633
+ stdin: "pipe",
1634
+ stdout: "pipe",
1635
+ stderr: "pipe"
1636
+ });
1637
+ let sawAgentEnd = false;
1638
+ let promptError = null;
1639
+ let stdinOpen = true;
1640
+ let steeringPollStopped = false;
1641
+ const closeStdin = () => {
1642
+ if (!stdinOpen)
1643
+ return;
1644
+ stdinOpen = false;
1645
+ try {
1646
+ steeringPollStopped = true;
1647
+ proc.stdin.end();
1648
+ } catch {}
1649
+ };
1650
+ const send = (command) => {
1651
+ if (!stdinOpen)
1652
+ return;
1653
+ try {
1654
+ writeRpcCommand(proc.stdin, command);
1655
+ } catch (error) {
1656
+ promptError ??= error instanceof Error ? error.message : String(error);
1657
+ }
1658
+ };
1659
+ const forwardSigterm = () => {
1660
+ try {
1661
+ proc.kill("SIGTERM");
1662
+ } catch {}
1663
+ };
1664
+ process.once("SIGTERM", forwardSigterm);
1665
+ const pollSteering = async () => {
1666
+ const serverUrl = input.env.RIG_SERVER_URL || input.env.RIG_SERVER_BASE_URL;
1667
+ const authToken = input.env.RIG_AUTH_TOKEN || input.env.RIG_SERVER_AUTH_TOKEN;
1668
+ const projectRoot = input.env.PROJECT_RIG_ROOT || input.env.RIG_HOST_PROJECT_ROOT || process.env.PROJECT_RIG_ROOT;
1669
+ let lastReportedPollError = null;
1670
+ while (!steeringPollStopped && stdinOpen) {
1671
+ try {
1672
+ const messages = await readQueuedSteeringFromServer({
1673
+ ...serverUrl ? { serverUrl } : {},
1674
+ ...authToken ? { authToken } : {},
1675
+ ...input.runId ? { runId: input.runId } : {},
1676
+ ...projectRoot ? { projectRoot } : {}
1677
+ });
1678
+ lastReportedPollError = null;
1679
+ for (const message of messages) {
1680
+ const text = steeringMessageText(message);
1681
+ if (!text || !stdinOpen)
1682
+ continue;
1683
+ send({
1684
+ id: typeof message.id === "string" ? `rig_steer_${message.id}` : `rig_steer_${Date.now()}`,
1685
+ type: "prompt",
1686
+ message: text,
1687
+ streamingBehavior: "steer"
1688
+ });
1689
+ emitWrapperEvent("pi.rpc.steering.delivered", {
1690
+ runId: input.runId ?? null,
1691
+ steeringId: typeof message.id === "string" ? message.id : null,
1692
+ actor: typeof message.actor === "string" ? message.actor : "operator",
1693
+ message: text
1694
+ });
1695
+ }
1696
+ } catch (error) {
1697
+ const message = error instanceof Error ? error.message : String(error);
1698
+ if (message !== lastReportedPollError) {
1699
+ lastReportedPollError = message;
1700
+ emitWrapperEvent("pi.rpc.steering.poll.failed", {
1701
+ runId: input.runId ?? null,
1702
+ error: message
1703
+ });
1704
+ }
1705
+ }
1706
+ await sleep(1000);
1707
+ }
1708
+ };
1709
+ const stdoutPump = pumpReadableLines(proc.stdout, (line) => {
1710
+ stdout.write(`${line}
1711
+ `);
1712
+ const record = parseJsonRecord(line.trim());
1713
+ if (!record)
1714
+ return;
1715
+ if (record.type === "agent_end") {
1716
+ sawAgentEnd = true;
1717
+ closeStdin();
1718
+ return;
1719
+ }
1720
+ if (record.type === "response" && record.command === "prompt" && record.success === false) {
1721
+ promptError = typeof record.error === "string" ? record.error : "Pi RPC prompt failed.";
1722
+ closeStdin();
1723
+ return;
1724
+ }
1725
+ if (isBlockingPiRpcUiRequest(record)) {
1726
+ const id = typeof record.id === "string" ? record.id : "";
1727
+ if (id) {
1728
+ send({ type: "extension_ui_response", id, cancelled: true });
1729
+ emitWrapperEvent("pi.rpc.extension_ui.cancelled", {
1730
+ id,
1731
+ method: record.method,
1732
+ reason: "noninteractive Rig worker RPC session"
1733
+ });
1734
+ }
1735
+ }
1736
+ });
1737
+ const stderrPump = pumpReadableLines(proc.stderr, (line) => {
1738
+ stderr.write(`${line}
1739
+ `);
1740
+ });
1741
+ if (input.sessionName?.trim()) {
1742
+ send({ id: "rig_set_session_name", type: "set_session_name", name: input.sessionName.trim() });
1743
+ }
1744
+ const steeringPollPromise = pollSteering();
1745
+ if (input.prompt.trim()) {
1746
+ send({ id: "rig_initial_prompt", type: "prompt", message: input.prompt });
1747
+ emitWrapperEvent("pi.rpc.prompt.sent", {
1748
+ runId: input.runId ?? null,
1749
+ kind: "initial",
1750
+ bytes: Buffer.byteLength(input.prompt)
1751
+ });
1752
+ } else {
1753
+ closeStdin();
1754
+ }
1755
+ const exitCode = await proc.exited;
1756
+ process.off("SIGTERM", forwardSigterm);
1757
+ steeringPollStopped = true;
1758
+ await Promise.all([stdoutPump, stderrPump, steeringPollPromise]);
1759
+ if (promptError) {
1760
+ stderr.write(`[rig-agent] Pi RPC prompt failed: ${promptError}
1761
+ `);
1762
+ return exitCode === 0 ? 1 : exitCode;
1763
+ }
1764
+ if (input.prompt.trim() && !sawAgentEnd && exitCode === 0) {
1765
+ stderr.write(`[rig-agent] Pi RPC exited before emitting agent_end.
1766
+ `);
1767
+ return 1;
1768
+ }
1769
+ return exitCode;
1770
+ }
1771
+ function resolveFinalProviderExitCode(input) {
1772
+ if (input.providerExitCode !== 0) {
1773
+ return input.providerExitCode;
1774
+ }
1775
+ if (input.taskClosed || input.serverManagedRun) {
1776
+ return 0;
1777
+ }
1778
+ return 0;
1779
+ }
1780
+ function shouldBypassProviderSandboxOnPlatform(provider, platform) {
1781
+ if (platform !== "darwin") {
1782
+ return false;
1783
+ }
1784
+ return provider === "pi";
1785
+ }
1786
+ function buildProviderArgs(_provider, _runtime, argv) {
1787
+ const piArgs = argv.filter((arg) => arg !== "__rig_pi_session_daemon__");
1788
+ const piProvider = cliOptionValue(piArgs, "--provider") || process.env.RIG_PI_PROVIDER?.trim() || "openai-codex";
1789
+ if (!hasCliOption(piArgs, "--provider")) {
1790
+ piArgs.unshift(piProvider);
1791
+ piArgs.unshift("--provider");
1792
+ }
1793
+ const model = cliOptionValue(piArgs, "--model") || process.env.RIG_PI_MODEL?.trim() || "gpt-5.5";
1794
+ if (hasCliOption(piArgs, "--model")) {
1795
+ rewriteCliOptionValue(piArgs, "--model", normalizePiModelForProvider(model, piProvider));
1796
+ } else {
1797
+ piArgs.unshift(normalizePiModelForProvider(model, piProvider));
1798
+ piArgs.unshift("--model");
1799
+ }
1800
+ if (!hasCliOption(piArgs, "--mode")) {
1801
+ piArgs.push("--mode", process.env.RIG_PI_TRANSPORT?.trim() === "print" ? "json" : "rpc");
1802
+ if (process.env.RIG_PI_TRANSPORT?.trim() === "print" && !hasCliOption(piArgs, "--print")) {
1803
+ piArgs.push("--print");
1804
+ }
1805
+ }
1806
+ return piArgs;
1807
+ }
1808
+ function taskRecordReaderFromEnv(taskId) {
1809
+ const raw = process.env.RIG_SOURCE_TASK_JSON?.trim();
1810
+ if (!raw) {
1811
+ return;
1812
+ }
1813
+ try {
1814
+ const parsed = JSON.parse(raw);
1815
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
1816
+ return;
1817
+ }
1818
+ const task = parsed;
1819
+ if (typeof task.id !== "string" || task.id !== taskId) {
1820
+ return;
1821
+ }
1822
+ return {
1823
+ async listTasks() {
1824
+ return [task];
1825
+ },
1826
+ async getTask(id) {
1827
+ return id === task.id ? task : null;
1828
+ }
1829
+ };
1830
+ } catch {
1831
+ return;
1832
+ }
1833
+ }
1834
+ async function runBeadsJson(projectRoot, args) {
1835
+ const output = await Bun.$`br --no-db ${args} --json`.cwd(projectRoot).quiet().nothrow();
1836
+ if (output.exitCode !== 0) {
1837
+ return null;
1838
+ }
1839
+ try {
1840
+ return await output.json();
1841
+ } catch {
1842
+ return null;
1843
+ }
1844
+ }
1845
+ function resolveProvider() {
1846
+ return "pi";
1847
+ }
1848
+ function hasCliOption(argv, option) {
1849
+ return argv.some((arg) => arg === option || arg.startsWith(`${option}=`));
1850
+ }
1851
+ function cliOptionValue(argv, option) {
1852
+ for (let index = 0;index < argv.length; index += 1) {
1853
+ const arg = argv[index];
1854
+ if (arg === option) {
1855
+ const next = argv[index + 1];
1856
+ return next && !next.startsWith("--") ? next : undefined;
1857
+ }
1858
+ if (arg?.startsWith(`${option}=`)) {
1859
+ return arg.slice(option.length + 1);
1860
+ }
1861
+ }
1862
+ return;
1863
+ }
1864
+ function rewriteCliOptionValue(argv, option, value) {
1865
+ for (let index = 0;index < argv.length; index += 1) {
1866
+ const arg = argv[index];
1867
+ if (arg === option && argv[index + 1] && !argv[index + 1].startsWith("--")) {
1868
+ argv[index + 1] = value;
1869
+ return;
1870
+ }
1871
+ if (arg?.startsWith(`${option}=`)) {
1872
+ argv[index] = `${option}=${value}`;
1873
+ return;
1874
+ }
1875
+ }
1876
+ }
1877
+ function normalizePiModelForProvider(model, provider) {
1878
+ if (provider === "openrouter" && model === "openai-codex/gpt-5.5") {
1879
+ return "openai/gpt-5.5";
1880
+ }
1881
+ return model;
1882
+ }
1883
+ function resolveFromShellPath(binary) {
1884
+ const resolved = Bun.spawnSync(["sh", "-lc", `command -v ${binary}`], {
1885
+ stdout: "pipe",
1886
+ stderr: "ignore",
1887
+ stdin: "ignore",
1888
+ env: process.env
1889
+ });
1890
+ if (resolved.exitCode !== 0)
1891
+ return null;
1892
+ const path = resolved.stdout.toString().trim().split(/\r?\n/)[0]?.trim();
1893
+ return path || null;
1894
+ }
1895
+ function resolveBundledPiBinary() {
1896
+ try {
1897
+ const packageJson = requireFromRuntime.resolve("@oh-my-pi/pi-coding-agent/package.json");
1898
+ const binaryPath = resolve5(packageJson, "..", "dist", "cli.js");
1899
+ return existsSync5(binaryPath) ? binaryPath : null;
1900
+ } catch {
1901
+ return null;
1902
+ }
1903
+ }
1904
+ function providerBinary(_provider) {
1905
+ return process.env.RIG_PI_BINARY?.trim() || resolveBundledPiBinary() || resolveFromShellPath("pi") || Bun.which("pi") || "pi";
1906
+ }
1907
+ function emitWrapperEvent(type, payload) {
1908
+ console.log(`__RIG_WRAPPER_EVENT__${JSON.stringify({ type, payload, at: new Date().toISOString() })}`);
1909
+ }
1910
+ function sleep(ms) {
1911
+ return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
1912
+ }
1913
+ async function waitForDirtyBaselineReady(runtime, taskId) {
1914
+ const readyFile = process.env.RIG_DIRTY_BASELINE_READY_FILE?.trim();
1915
+ if (process.env.RIG_BASELINE_MODE !== "dirty-snapshot" || !readyFile)
1916
+ return;
1917
+ const timeoutMs = Number.parseInt(process.env.RIG_DIRTY_BASELINE_TIMEOUT_MS ?? "30000", 10);
1918
+ const deadline = Date.now() + (Number.isFinite(timeoutMs) && timeoutMs > 0 ? timeoutMs : 30000);
1919
+ emitWrapperEvent("runtime.baseline.waiting", {
1920
+ runtimeId: runtime.id,
1921
+ taskId,
1922
+ workspaceDir: runtime.workspaceDir,
1923
+ readyFile
1924
+ });
1925
+ while (!existsSync5(readyFile)) {
1926
+ if (Date.now() >= deadline) {
1927
+ throw new Error(`Timed out waiting for dirty baseline ready file: ${readyFile}`);
1928
+ }
1929
+ await sleep(50);
1930
+ }
1931
+ emitWrapperEvent("runtime.baseline.completed", {
1932
+ runtimeId: runtime.id,
1933
+ taskId,
1934
+ workspaceDir: runtime.workspaceDir,
1935
+ readyFile
1936
+ });
1937
+ }
1938
+ async function resolveTaskId(projectRoot, monorepoRoot) {
1939
+ if (process.env.RIG_TASK_ID) {
1940
+ return process.env.RIG_TASK_ID;
1941
+ }
1942
+ const fromState = (await resolveTaskDataService(projectRoot)).currentTaskId(projectRoot);
1943
+ if (fromState) {
1944
+ return fromState;
1945
+ }
1946
+ return resolveTaskFromBeads(monorepoRoot);
1947
+ }
1948
+ async function resolveTaskFromBeads(projectRoot, readBeadsJson = runBeadsJson) {
1949
+ const inProgress = await readBeadsJson(projectRoot, ["list", "--status", "in_progress"]);
1950
+ if (inProgress) {
1951
+ const task = inProgress.find((t) => t.issue_type === "task");
1952
+ if (task?.id) {
1953
+ return task.id;
1954
+ }
1955
+ }
1956
+ const ready = await readBeadsJson(projectRoot, ["ready"]);
1957
+ if (ready) {
1958
+ const task = ready.find((t) => t.issue_type === "task");
1959
+ if (task?.id) {
1960
+ return task.id;
1961
+ }
1962
+ }
1963
+ return "";
1964
+ }
1965
+ async function isTaskClosed(projectRoot, taskId, readBeadsJson = runBeadsJson) {
1966
+ const pluginStatus = await readPluginTaskStatus(projectRoot, taskId);
1967
+ if (isTerminalTaskStatus(pluginStatus)) {
1968
+ return true;
1969
+ }
1970
+ const parsed = await readBeadsJson(projectRoot, ["show", taskId]);
1971
+ const record = Array.isArray(parsed) ? parsed[0] : parsed;
1972
+ if (record && typeof record === "object" && !Array.isArray(record)) {
1973
+ return isTerminalTaskStatus(record.status);
1974
+ }
1975
+ return false;
1976
+ }
1977
+ function isTerminalTaskStatus(status) {
1978
+ return status === "closed" || status === "CLOSED" || status === "completed" || status === "cancelled" || status === "blocked";
1979
+ }
1980
+ async function readPluginTaskStatus(projectRoot, taskId) {
1981
+ const taskData3 = await resolveTaskDataService(projectRoot);
1982
+ try {
1983
+ const ctx = await buildPluginHostContext2(projectRoot);
1984
+ const [source] = ctx?.taskSourceRegistry.list() ?? [];
1985
+ if (!source?.get) {
1986
+ return taskData3.readSourceAwareTaskStatus(projectRoot, taskId);
1987
+ }
1988
+ return (await source.get(taskId))?.status ?? taskData3.readSourceAwareTaskStatus(projectRoot, taskId);
1989
+ } catch {
1990
+ return taskData3.readSourceAwareTaskStatus(projectRoot, taskId);
1991
+ }
1992
+ }
1993
+ async function recordSnapshotMissingTaskSourceEvidence(projectRoot, taskId, runtime, snapshotFinalizeError) {
1994
+ const taskData3 = await resolveTaskDataService(projectRoot);
1995
+ const comment = taskData3.buildTaskRunLifecycleComment({
1996
+ runId: process.env.RIG_SERVER_RUN_ID || "(unknown)",
1997
+ status: "snapshot-missing",
1998
+ summary: "Rig runtime completed, but the after-snapshot finalize failed. Closeout evidence is degraded until the runtime workspace is inspected directly.",
1999
+ runtimeWorkspace: runtime.workspaceDir,
2000
+ logsDir: runtime.logsDir,
2001
+ sessionDir: runtime.sessionDir,
2002
+ errorText: snapshotFinalizeError
2003
+ });
2004
+ try {
2005
+ const result = await taskData3.updateConfiguredTaskSourceTask(projectRoot, {
2006
+ taskId,
2007
+ update: { comment }
2008
+ });
2009
+ if (result.updated) {
2010
+ return;
2011
+ }
2012
+ throw new Error(result.source === "plugin" || result.sourceKind ? `configured task source${result.sourceKind ? ` (${result.sourceKind})` : ""} does not support comment updates` : "no source-aware task source is configured");
2013
+ } catch (error) {
2014
+ let fallbackUpdated = false;
2015
+ try {
2016
+ const sourceIssueId = loadRuntimeContextFromEnv2()?.sourceTask?.sourceIssueId;
2017
+ fallbackUpdated = taskData3.updateGithubIssueTaskBySourceIssueId(sourceIssueId, taskId, { comment });
2018
+ fallbackUpdated = taskData3.updateSourceAwareTaskConfigTask(projectRoot, taskId, { comment }) || fallbackUpdated;
2019
+ } catch (fallbackError) {
2020
+ console.error(`[rig-agent] Snapshot-missing compatibility comment also failed for ${taskId}: ${fallbackError instanceof Error ? fallbackError.message : String(fallbackError)}`);
2021
+ }
2022
+ const message = `[rig-agent] Failed to record snapshot-missing evidence for ${taskId}${fallbackUpdated ? "; applied source-aware compatibility comment" : ""}: ${error instanceof Error ? error.message : String(error)}`;
2023
+ if (fallbackUpdated) {
2024
+ console.log(message);
2025
+ } else {
2026
+ console.error(message);
2027
+ }
2028
+ }
2029
+ }
2030
+ async function updateTaskSourceAfterRun(projectRoot, taskId, runtime) {
2031
+ const taskData3 = await resolveTaskDataService(projectRoot);
2032
+ const comment = taskData3.buildTaskRunLifecycleComment({
2033
+ runId: process.env.RIG_SERVER_RUN_ID || "(unknown)",
2034
+ status: "completed",
2035
+ summary: "Rig task run completed; source closeout waits for approved PR merge.",
2036
+ runtimeWorkspace: runtime.workspaceDir,
2037
+ logsDir: runtime.logsDir,
2038
+ sessionDir: runtime.sessionDir
2039
+ });
2040
+ try {
2041
+ const result = await taskData3.updateConfiguredTaskSourceTask(projectRoot, {
2042
+ taskId,
2043
+ update: { status: "completed", comment }
2044
+ });
2045
+ if (result.updated) {
2046
+ return;
2047
+ }
2048
+ throw new Error(result.source === "plugin" || result.sourceKind ? `configured task source${result.sourceKind ? ` (${result.sourceKind})` : ""} does not support lifecycle updates` : "no source-aware task source is configured");
2049
+ } catch (error) {
2050
+ let fallbackUpdated = false;
2051
+ try {
2052
+ const sourceIssueId = loadRuntimeContextFromEnv2()?.sourceTask?.sourceIssueId;
2053
+ fallbackUpdated = taskData3.updateGithubIssueTaskBySourceIssueId(sourceIssueId, taskId, { status: "completed", comment });
2054
+ fallbackUpdated = taskData3.updateSourceAwareTaskConfigTask(projectRoot, taskId, { status: "completed", comment }) || fallbackUpdated;
2055
+ } catch (fallbackError) {
2056
+ console.error(`[rig-agent] Source-aware compatibility update also failed for ${taskId}: ${fallbackError instanceof Error ? fallbackError.message : String(fallbackError)}`);
2057
+ }
2058
+ const message = `[rig-agent] Failed to update task source for ${taskId}${fallbackUpdated ? "; applied source-aware compatibility update" : ""}: ${error instanceof Error ? error.message : String(error)}`;
2059
+ if (fallbackUpdated) {
2060
+ console.log(message);
2061
+ } else {
2062
+ console.error(message);
2063
+ }
2064
+ }
2065
+ }
2066
+ function resolveRuntimeHandoffPath(hostProjectRoot, taskId, timestampMs = Date.now()) {
2067
+ const handoffDir = resolve5(hostProjectRoot, ".rig/runtime/handoffs");
2068
+ const safeTaskId = safePathSegment(taskId, { fallback: "task", maxLength: 96 });
2069
+ return assertPathInsideRoot(handoffDir, resolve5(handoffDir, `${safeTaskId}-${timestampMs}.json`), "runtime handoff path");
2070
+ }
2071
+ function recordRuntimeHandoff(hostProjectRoot, runtime, taskId, exitCode, options = {}) {
2072
+ const handoffDir = resolve5(hostProjectRoot, ".rig/runtime/handoffs");
2073
+ mkdirSync3(handoffDir, { recursive: true });
2074
+ const handoffPath = resolveRuntimeHandoffPath(hostProjectRoot, taskId);
2075
+ const snapshotMissing = options.snapshotMissing === true;
2076
+ const handoff = {
2077
+ taskId,
2078
+ runtimeId: runtime.id,
2079
+ runtimeMode: runtime.mode,
2080
+ workspaceDir: runtime.workspaceDir,
2081
+ logsDir: runtime.logsDir,
2082
+ sessionDir: runtime.sessionDir,
2083
+ exitCode,
2084
+ degraded: snapshotMissing,
2085
+ snapshotMissing,
2086
+ snapshotFinalizeError: options.snapshotFinalizeError ?? null,
2087
+ recordedAt: new Date().toISOString(),
2088
+ message: snapshotMissing ? "Runtime completed but the after-snapshot finalize failed; closeout evidence is degraded until the runtime workspace is inspected directly." : "Completion verification did not finish in this run. Open or refresh the PR from the runtime workspace for verifier review, or rerun completion verification once the workspace is ready.",
2089
+ nextSteps: snapshotMissing ? [
2090
+ `cd ${runtime.workspaceDir}`,
2091
+ "inspect the runtime workspace directly before relying on closeout evidence",
2092
+ `rig git status --task ${taskId}`
2093
+ ] : [
2094
+ `cd ${runtime.workspaceDir}`,
2095
+ `rig git status --task ${taskId}`,
2096
+ `rig completion-verification --task ${taskId}`,
2097
+ `rig git open-pr --task ${taskId}`
2098
+ ]
2099
+ };
2100
+ writeFileSync3(handoffPath, `${JSON.stringify(handoff, null, 2)}
2101
+ `, "utf-8");
2102
+ if (snapshotMissing) {
2103
+ console.log(`[rig-agent] Runtime after-snapshot missing for ${taskId}; degraded handoff saved: ${handoffPath}`);
2104
+ console.log(`[rig-agent] Inspect runtime workspace before relying on closeout evidence: ${runtime.workspaceDir}`);
2105
+ } else {
2106
+ console.log(`[rig-agent] Completion verification paused for ${taskId}.`);
2107
+ console.log(`[rig-agent] Runtime handoff saved: ${handoffPath}`);
2108
+ console.log(`[rig-agent] Review and open PR from runtime workspace: ${runtime.workspaceDir}`);
2109
+ }
2110
+ }
2111
+ async function printTaskContext(projectRoot, taskId) {
2112
+ const metadata = await readTaskMetadata(projectRoot, taskId);
2113
+ const configHints = await readTaskConfigHints(projectRoot, taskId);
2114
+ const description = firstNonEmpty(metadata?.description, configHints.description);
2115
+ const acceptanceCriteria = firstNonEmpty(metadata?.acceptanceCriteria, configHints.acceptanceCriteria);
2116
+ if (metadata?.title) {
2117
+ console.log(`[rig-agent] Task ${taskId}: ${metadata.title}`);
2118
+ } else {
2119
+ console.log(`[rig-agent] Task ${taskId}`);
2120
+ }
2121
+ if (description) {
2122
+ console.log("[rig-agent] Description:");
2123
+ for (const line of description.split(/\r?\n/)) {
2124
+ console.log(`[rig-agent] ${line}`);
2125
+ }
2126
+ } else {
2127
+ console.log(`[rig-agent] Description: (not set; use \`br update ${taskId} --description "..."\`)`);
2128
+ }
2129
+ if (acceptanceCriteria) {
2130
+ console.log("[rig-agent] Acceptance Criteria:");
2131
+ for (const line of acceptanceCriteria.split(/\r?\n/)) {
2132
+ console.log(`[rig-agent] ${line}`);
2133
+ }
2134
+ }
2135
+ }
2136
+ async function readTaskMetadata(taskRoot, taskId) {
2137
+ const parsed = await runBeadsJson(taskRoot, ["show", taskId]);
2138
+ if (!parsed) {
2139
+ return null;
2140
+ }
2141
+ const record = Array.isArray(parsed) ? parsed[0] : parsed;
2142
+ if (!record || typeof record !== "object" || Array.isArray(record)) {
2143
+ return null;
2144
+ }
2145
+ const value = record;
2146
+ return {
2147
+ title: asNonEmptyString(value.title),
2148
+ description: asNonEmptyString(value.description),
2149
+ acceptanceCriteria: firstNonEmpty(asNonEmptyString(value.acceptance_criteria), asNonEmptyString(value.acceptanceCriteria))
2150
+ };
2151
+ }
2152
+ async function readTaskConfigHints(taskRoot, taskId) {
2153
+ const runtimeContext = loadRuntimeContextFromEnv2();
2154
+ const candidates = [
2155
+ runtimeContext?.monorepoMainRoot ? resolve5(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
2156
+ process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve5(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
2157
+ resolve5(taskRoot, ".rig", "task-config.json"),
2158
+ resolve5(taskRoot, "rig", "task-config.json")
2159
+ ].filter(Boolean);
2160
+ for (const configPath of candidates) {
2161
+ if (!existsSync5(configPath)) {
2162
+ continue;
2163
+ }
2164
+ try {
2165
+ const config = await Bun.file(configPath).json();
2166
+ const entry = config[taskId] || {};
2167
+ return {
2168
+ description: asNonEmptyString(entry.description),
2169
+ acceptanceCriteria: asNonEmptyString(entry.acceptance_criteria)
2170
+ };
2171
+ } catch {
2172
+ continue;
2173
+ }
2174
+ }
2175
+ return { description: "", acceptanceCriteria: "" };
2176
+ }
2177
+ function asNonEmptyString(value) {
2178
+ return typeof value === "string" ? value.trim() : "";
2179
+ }
2180
+ function firstNonEmpty(...values) {
2181
+ for (const value of values) {
2182
+ if (typeof value === "string" && value.trim()) {
2183
+ return value.trim();
2184
+ }
2185
+ }
2186
+ return "";
2187
+ }
2188
+ var taskDataServiceByRoot, requireFromRuntime, runPiRpcProvider;
2189
+ var init_agent_wrapper = __esm(() => {
2190
+ init_runtime_snapshot_config();
2191
+ taskDataServiceByRoot = new Map;
2192
+ requireFromRuntime = createRequire(import.meta.url);
2193
+ runPiRpcProvider = runPiRpcProviderFallback;
2194
+ if (false) {}
2195
+ });
2196
+
2197
+ // packages/provider-plugin/src/tooling/browser-tool-entrypoint.ts
2198
+ var exports_browser_tool_entrypoint = {};
2199
+ import { existsSync as existsSync6, rmSync as rmSync2 } from "fs";
2200
+ import { basename as basename2, dirname as dirname3, resolve as resolve6 } from "path";
2201
+ import { loadRuntimeContext as loadRuntimeContext3 } from "@rig/core/runtime-context";
2202
+ function currentCommand() {
2203
+ return basename2(process.argv[1] || "");
2204
+ }
2205
+ function runtimeContextPath() {
2206
+ const explicit = process.env.RIG_RUNTIME_CONTEXT_FILE?.trim();
2207
+ if (explicit) {
2208
+ return explicit;
2209
+ }
2210
+ return resolve6(dirname3(resolve6(process.argv[1] || "")), "..", "runtime-context.json");
2211
+ }
2212
+ function loadBrowserContext() {
2213
+ const contextPath = runtimeContextPath();
2214
+ if (!existsSync6(contextPath)) {
2215
+ throw new Error(`Runtime context file not found for ${currentCommand()}: ${contextPath}`);
2216
+ }
2217
+ const runtimeContext = loadRuntimeContext3(contextPath);
2218
+ if (!runtimeContext.browser?.required) {
2219
+ throw new Error(`No browser contract is configured for ${runtimeContext.taskId}.`);
2220
+ }
2221
+ if (!runtimeContext.hostProjectRoot) {
2222
+ throw new Error(`Runtime browser command ${currentCommand()} requires hostProjectRoot in runtime context.`);
2223
+ }
2224
+ return {
2225
+ browser: runtimeContext.browser,
2226
+ hostProjectRoot: runtimeContext.hostProjectRoot
2227
+ };
2228
+ }
2229
+ async function runConfiguredCommand(command, browser, hostProjectRoot) {
2230
+ if (!command) {
2231
+ throw new Error(`No backing command is configured for ${currentCommand()}.`);
2232
+ }
2233
+ const attachUrl = new URL(browser.effectiveAttachUrl);
2234
+ const child = Bun.spawn({
2235
+ cmd: ["/bin/bash", "-lc", command],
2236
+ cwd: hostProjectRoot,
2237
+ stdin: "inherit",
2238
+ stdout: "inherit",
2239
+ stderr: "inherit",
2240
+ env: {
2241
+ ...process.env,
2242
+ RIG_STATE_DIR: browser.stateDir,
2243
+ T3CODE_STATE_DIR: browser.stateDir,
2244
+ RIG_BROWSER_PROFILE: browser.effectiveProfile,
2245
+ RIG_BROWSER_REMOTE_DEBUGGING_PORT: attachUrl.port,
2246
+ RIG_BROWSER_ATTACH_URL: browser.effectiveAttachUrl
2247
+ }
2248
+ });
2249
+ return await child.exited;
2250
+ }
2251
+ function printAttachInfo(browser, hostProjectRoot) {
2252
+ const payload = {
2253
+ preset: browser.preset,
2254
+ mode: browser.mode,
2255
+ stateDir: browser.stateDir,
2256
+ hostProjectRoot,
2257
+ defaultProfile: browser.defaultProfile,
2258
+ effectiveProfile: browser.effectiveProfile,
2259
+ defaultAttachUrl: browser.defaultAttachUrl,
2260
+ effectiveAttachUrl: browser.effectiveAttachUrl,
2261
+ launchHelper: browser.launchHelper,
2262
+ checkHelper: browser.checkHelper,
2263
+ attachInfoHelper: browser.attachInfoHelper,
2264
+ e2eHelper: browser.e2eHelper,
2265
+ resetProfileHelper: browser.resetProfileHelper,
2266
+ devCommand: browser.devCommand,
2267
+ launchCommand: browser.launchCommand,
2268
+ checkCommand: browser.checkCommand,
2269
+ e2eCommand: browser.e2eCommand
2270
+ };
2271
+ if (process.argv.includes("--json")) {
2272
+ console.log(JSON.stringify(payload, null, 2));
2273
+ return;
2274
+ }
2275
+ console.log("Rig Browser");
2276
+ console.log(` Preset: ${browser.preset}`);
2277
+ console.log(` Mode: ${browser.mode}`);
2278
+ console.log(` State dir: ${browser.stateDir}`);
2279
+ console.log(` Default profile: ${browser.defaultProfile}`);
2280
+ console.log(` Effective profile: ${browser.effectiveProfile}`);
2281
+ console.log(` Default attach URL: ${browser.defaultAttachUrl}`);
2282
+ console.log(` Effective attach URL: ${browser.effectiveAttachUrl}`);
2283
+ console.log(` Launch helper: ${browser.launchHelper}${browser.devCommand ? " [--dev]" : ""}`);
2284
+ console.log(` Check helper: ${browser.checkHelper}`);
2285
+ console.log(` E2E helper: ${browser.e2eHelper}`);
2286
+ console.log(` Reset helper: ${browser.resetProfileHelper}`);
2287
+ }
2288
+ function resetProfile(browser) {
2289
+ const profileRoot = resolve6(browser.stateDir, "browser", "profiles", browser.effectiveProfile);
2290
+ rmSync2(profileRoot, { recursive: true, force: true });
2291
+ console.log(`Removed Rig Browser profile: ${profileRoot}`);
2292
+ }
2293
+ async function main2() {
2294
+ const { browser, hostProjectRoot } = loadBrowserContext();
2295
+ const command = currentCommand();
2296
+ if (command === browser.attachInfoHelper) {
2297
+ printAttachInfo(browser, hostProjectRoot);
2298
+ return;
2299
+ }
2300
+ if (command === browser.resetProfileHelper) {
2301
+ resetProfile(browser);
2302
+ return;
2303
+ }
2304
+ if (command === browser.launchHelper) {
2305
+ const launchCommand = process.argv.includes("--dev") ? browser.devCommand : browser.launchCommand;
2306
+ process.exit(await runConfiguredCommand(launchCommand, browser, hostProjectRoot));
2307
+ }
2308
+ if (command === browser.checkHelper) {
2309
+ process.exit(await runConfiguredCommand(browser.checkCommand, browser, hostProjectRoot));
2310
+ }
2311
+ if (command === browser.e2eHelper) {
2312
+ process.exit(await runConfiguredCommand(browser.e2eCommand ?? browser.checkCommand, browser, hostProjectRoot));
2313
+ }
2314
+ throw new Error(`Unknown Rig Browser helper: ${command}`);
2315
+ }
2316
+ var init_browser_tool_entrypoint = __esm(() => {
2317
+ main2().catch((error) => {
2318
+ console.error(error instanceof Error ? error.message : String(error));
2319
+ process.exit(1);
2320
+ });
2321
+ });
17
2322
 
18
2323
  // packages/provider-plugin/src/runtime-instructions.ts
19
2324
  function normalizeRuntimeInstructionProvider(_value) {
@@ -52,22 +2357,1068 @@ var init_service = __esm(() => {
52
2357
  runtimeInstructionService = svc;
53
2358
  });
54
2359
 
2360
+ // packages/provider-plugin/src/skill-materializer.ts
2361
+ import { existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync4, readdirSync as readdirSync2, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "fs";
2362
+ import { resolve as resolve7 } from "path";
2363
+ import { loadSkill } from "@rig/skill-loader";
2364
+ function skillDirName(id) {
2365
+ return id.replace(/[^a-zA-Z0-9._-]+/g, "-");
2366
+ }
2367
+ async function materializeSkills(projectRoot, entries) {
2368
+ const skillsRoot = resolve7(projectRoot, ".pi", "skills");
2369
+ if (existsSync7(skillsRoot)) {
2370
+ for (const name of readdirSync2(skillsRoot)) {
2371
+ const dir = resolve7(skillsRoot, name);
2372
+ if (existsSync7(resolve7(dir, MARKER_FILENAME))) {
2373
+ rmSync3(dir, { recursive: true, force: true });
2374
+ }
2375
+ }
2376
+ }
2377
+ const written = [];
2378
+ for (const { pluginName, skill } of entries) {
2379
+ const sourcePath = resolve7(projectRoot, skill.path);
2380
+ if (!existsSync7(sourcePath)) {
2381
+ console.warn(`[plugin-host] skill "${skill.id}" from plugin "${pluginName}" not materialized: ${sourcePath} does not exist`);
2382
+ continue;
2383
+ }
2384
+ let body;
2385
+ try {
2386
+ await loadSkill(sourcePath);
2387
+ body = readFileSync4(sourcePath, "utf-8");
2388
+ } catch (err) {
2389
+ console.warn(`[plugin-host] skill "${skill.id}" from plugin "${pluginName}" not materialized: ${err instanceof Error ? err.message : err}`);
2390
+ continue;
2391
+ }
2392
+ const dir = resolve7(skillsRoot, skillDirName(skill.id));
2393
+ mkdirSync4(dir, { recursive: true });
2394
+ writeFileSync4(resolve7(dir, "SKILL.md"), body, "utf-8");
2395
+ writeFileSync4(resolve7(dir, MARKER_FILENAME), `${JSON.stringify({ plugin: pluginName, skillId: skill.id }, null, 2)}
2396
+ `, "utf-8");
2397
+ written.push({ id: skill.id, pluginName, directory: dir });
2398
+ }
2399
+ return written;
2400
+ }
2401
+ var MARKER_FILENAME = ".rig-plugin";
2402
+ var init_skill_materializer = () => {};
2403
+
2404
+ // packages/provider-plugin/src/pi-settings-materializer.ts
2405
+ import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "fs";
2406
+ import { dirname as dirname4, resolve as resolve8 } from "path";
2407
+ function readJson(path, fallback) {
2408
+ if (!existsSync8(path))
2409
+ return fallback;
2410
+ try {
2411
+ return JSON.parse(readFileSync5(path, "utf-8"));
2412
+ } catch {
2413
+ return fallback;
2414
+ }
2415
+ }
2416
+ function packageKey(entry) {
2417
+ if (typeof entry === "string")
2418
+ return entry;
2419
+ if (entry && typeof entry === "object" && typeof entry.source === "string") {
2420
+ return entry.source;
2421
+ }
2422
+ return JSON.stringify(entry);
2423
+ }
2424
+ function materializePiPackages(projectRoot, declaredPackages) {
2425
+ const settingsPath = resolve8(projectRoot, SETTINGS_RELATIVE_PATH);
2426
+ const managedRecordPath = resolve8(projectRoot, MANAGED_RECORD_RELATIVE_PATH);
2427
+ const settings = readJson(settingsPath, {});
2428
+ const previouslyManaged = new Set(readJson(managedRecordPath, []));
2429
+ const existing = Array.isArray(settings.packages) ? settings.packages : [];
2430
+ const operatorEntries = existing.filter((entry) => !previouslyManaged.has(packageKey(entry)));
2431
+ const operatorKeys = new Set(operatorEntries.map(packageKey));
2432
+ const managedToAdd = declaredPackages.filter((pkg) => !operatorKeys.has(pkg));
2433
+ const nextPackages = [...operatorEntries, ...managedToAdd];
2434
+ if (nextPackages.length > 0 || existsSync8(settingsPath)) {
2435
+ const nextSettings = { ...settings };
2436
+ if (nextPackages.length > 0) {
2437
+ nextSettings.packages = nextPackages;
2438
+ } else {
2439
+ delete nextSettings.packages;
2440
+ }
2441
+ mkdirSync5(dirname4(settingsPath), { recursive: true });
2442
+ writeFileSync5(settingsPath, `${JSON.stringify(nextSettings, null, 2)}
2443
+ `, "utf-8");
2444
+ }
2445
+ mkdirSync5(dirname4(managedRecordPath), { recursive: true });
2446
+ writeFileSync5(managedRecordPath, `${JSON.stringify(managedToAdd, null, 2)}
2447
+ `, "utf-8");
2448
+ return { settingsPath, packages: managedToAdd };
2449
+ }
2450
+ var SETTINGS_RELATIVE_PATH = ".pi/settings.json", MANAGED_RECORD_RELATIVE_PATH = ".rig/state/pi-managed-packages.json";
2451
+ var init_pi_settings_materializer = () => {};
2452
+
2453
+ // packages/provider-plugin/src/session-asset-materializer-service.ts
2454
+ var exports_session_asset_materializer_service = {};
2455
+ __export(exports_session_asset_materializer_service, {
2456
+ sessionAssetMaterializer: () => sessionAssetMaterializer
2457
+ });
2458
+ import { existsSync as existsSync9 } from "fs";
2459
+ import { resolve as resolvePath } from "path";
2460
+ var sessionAssetMaterializer;
2461
+ var init_session_asset_materializer_service = __esm(() => {
2462
+ init_skill_materializer();
2463
+ init_pi_settings_materializer();
2464
+ sessionAssetMaterializer = {
2465
+ async materializeSessionAssets(projectRoot, config) {
2466
+ try {
2467
+ const skillEntries = config.plugins.flatMap((plugin) => (plugin.contributes?.skills ?? []).map((skill) => ({
2468
+ pluginName: plugin.name,
2469
+ skill
2470
+ })));
2471
+ if (skillEntries.length > 0) {
2472
+ await materializeSkills(projectRoot, skillEntries);
2473
+ }
2474
+ } catch (err) {
2475
+ console.warn(`[session-assets] skill materialization failed: ${err instanceof Error ? err.message : err}`);
2476
+ }
2477
+ try {
2478
+ const piPackages = config.runtime?.pi?.packages ?? [];
2479
+ if (piPackages.length > 0 || existsSync9(resolvePath(projectRoot, ".rig/state/pi-managed-packages.json"))) {
2480
+ materializePiPackages(projectRoot, piPackages);
2481
+ }
2482
+ } catch (err) {
2483
+ console.warn(`[session-assets] Pi package materialization failed: ${err instanceof Error ? err.message : err}`);
2484
+ }
2485
+ }
2486
+ };
2487
+ });
2488
+
2489
+ // packages/provider-plugin/src/tooling/embedded-native-assets.ts
2490
+ var embeddedNatives = null;
2491
+
2492
+ // packages/provider-plugin/src/tooling/native-extract.ts
2493
+ import { existsSync as existsSync10, mkdirSync as mkdirSync6, readFileSync as readFileSync6, renameSync, statSync, writeFileSync as writeFileSync6 } from "fs";
2494
+ import { tmpdir } from "os";
2495
+ import { resolve as resolve9 } from "path";
2496
+ function hasEmbeddedNatives() {
2497
+ return embeddedNatives != null;
2498
+ }
2499
+ function extractEmbeddedNative(name) {
2500
+ if (name in extractionCache) {
2501
+ return extractionCache[name] ?? null;
2502
+ }
2503
+ const entry = embeddedNatives?.[name];
2504
+ if (!entry) {
2505
+ extractionCache[name] = null;
2506
+ return null;
2507
+ }
2508
+ try {
2509
+ const targetPath = resolve9(sharedNativeOutputDir, entry.fileName);
2510
+ mkdirSync6(sharedNativeOutputDir, { recursive: true });
2511
+ const upToDate = existsSync10(targetPath) && statSync(targetPath).size === entry.size;
2512
+ if (!upToDate) {
2513
+ const bytes = readFileSync6(entry.filePath);
2514
+ const tempPath = `${targetPath}.${process.pid}.${Date.now()}.tmp`;
2515
+ writeFileSync6(tempPath, bytes, { mode: 493 });
2516
+ renameSync(tempPath, targetPath);
2517
+ }
2518
+ extractionCache[name] = targetPath;
2519
+ } catch {
2520
+ extractionCache[name] = null;
2521
+ }
2522
+ return extractionCache[name] ?? null;
2523
+ }
2524
+ var sharedNativeOutputDir, extractionCache;
2525
+ var init_native_extract = __esm(() => {
2526
+ sharedNativeOutputDir = resolve9(tmpdir(), "rig-native");
2527
+ extractionCache = {};
2528
+ });
2529
+
2530
+ // packages/provider-plugin/src/tooling/shell-tools.ts
2531
+ import { chmodSync, copyFileSync, existsSync as existsSync11, mkdirSync as mkdirSync7 } from "fs";
2532
+ import { tmpdir as tmpdir2 } from "os";
2533
+ import { basename as basename3, dirname as dirname5, resolve as resolve10 } from "path";
2534
+ import { RUNTIME_SHELL_TOOL_NAMES } from "@rig/contracts";
2535
+ function runtimeRigShellFileName() {
2536
+ return `rig-shell${process.platform === "win32" ? ".exe" : ""}`;
2537
+ }
2538
+ async function ensureRigShellBinaryPath(outputPath = sharedNativeShellOutputPath) {
2539
+ const explicitBin = process.env.RIG_NATIVE_SHELL_BIN?.trim();
2540
+ if (explicitBin && existsSync11(explicitBin)) {
2541
+ return explicitBin;
2542
+ }
2543
+ const embedded = extractEmbeddedNative("rig-shell");
2544
+ if (embedded) {
2545
+ return embedded;
2546
+ }
2547
+ const sourcePath = resolveRigShellSourcePath();
2548
+ if (!sourcePath) {
2549
+ const bundledBinary = resolveBundledRigShellBinaryPath();
2550
+ if (bundledBinary) {
2551
+ return bundledBinary;
2552
+ }
2553
+ throw new Error("rig-shell.zig source file not found.");
2554
+ }
2555
+ const zigBinary = Bun.which("zig");
2556
+ if (!zigBinary) {
2557
+ throw new Error("zig is required to build the native Rig shell.");
2558
+ }
2559
+ mkdirSync7(dirname5(outputPath), { recursive: true });
2560
+ const sourceDigest = await sha256File(sourcePath);
2561
+ const buildKey = JSON.stringify({
2562
+ version: 1,
2563
+ zigBinary,
2564
+ platform: process.platform,
2565
+ arch: process.arch,
2566
+ sourcePath,
2567
+ sourceDigest
2568
+ });
2569
+ const manifestPath = nativeBuildManifestPath(outputPath);
2570
+ const needsBuild = !existsSync11(outputPath) || !await hasMatchingNativeBuildManifest(manifestPath, buildKey);
2571
+ if (!needsBuild) {
2572
+ return outputPath;
2573
+ }
2574
+ const build = Bun.spawn([
2575
+ zigBinary,
2576
+ "build-exe",
2577
+ sourcePath,
2578
+ "-O",
2579
+ "ReleaseFast",
2580
+ `-femit-bin=${outputPath}`
2581
+ ], {
2582
+ cwd: dirname5(sourcePath),
2583
+ stdout: "pipe",
2584
+ stderr: "pipe"
2585
+ });
2586
+ const [exitCode, stdout, stderr] = await Promise.all([
2587
+ build.exited,
2588
+ new Response(build.stdout).text(),
2589
+ new Response(build.stderr).text()
2590
+ ]);
2591
+ if (exitCode !== 0 || !existsSync11(outputPath)) {
2592
+ const details = [stderr.trim(), stdout.trim()].filter(Boolean).join(`
2593
+ `);
2594
+ throw new Error(`Failed to build native Rig shell: ${details || `zig exited with code ${exitCode}`}`);
2595
+ }
2596
+ await Bun.write(manifestPath, `${JSON.stringify({ version: 1, buildKey }, null, 2)}
2597
+ `);
2598
+ return outputPath;
2599
+ }
2600
+ async function materializeRigShellBinary(targetDir) {
2601
+ const sourcePath = await ensureRigShellBinaryPath();
2602
+ const targetPath = resolve10(targetDir, runtimeRigShellFileName());
2603
+ mkdirSync7(targetDir, { recursive: true });
2604
+ const sourceDigest = await sha256File(sourcePath);
2605
+ const buildKey = JSON.stringify({
2606
+ version: 1,
2607
+ sourcePath,
2608
+ sourceDigest
2609
+ });
2610
+ const needsCopy = !existsSync11(targetPath) || !await hasMatchingNativeBuildManifest(nativeBuildManifestPath(targetPath), buildKey);
2611
+ if (needsCopy) {
2612
+ copyFileSync(sourcePath, targetPath);
2613
+ chmodSync(targetPath, 493);
2614
+ await Bun.write(nativeBuildManifestPath(targetPath), `${JSON.stringify({ version: 1, buildKey }, null, 2)}
2615
+ `);
2616
+ }
2617
+ return targetPath;
2618
+ }
2619
+ function resolveRigShellSourcePath() {
2620
+ for (const candidate of rigShellSourceCandidates()) {
2621
+ if (candidate && existsSync11(candidate)) {
2622
+ return candidate;
2623
+ }
2624
+ }
2625
+ return null;
2626
+ }
2627
+ function resolveBundledRigShellBinaryPath() {
2628
+ for (const candidate of rigShellBinaryCandidates()) {
2629
+ if (candidate && existsSync11(candidate)) {
2630
+ return candidate;
2631
+ }
2632
+ }
2633
+ return null;
2634
+ }
2635
+ function rigShellSourceCandidates() {
2636
+ const execDir = process.execPath?.trim() ? dirname5(process.execPath.trim()) : "";
2637
+ const cwd = process.cwd()?.trim() || "";
2638
+ const projectRoot = process.env.PROJECT_RIG_ROOT?.trim() || "";
2639
+ const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim() || "";
2640
+ return [...new Set([
2641
+ process.env.RIG_NATIVE_SHELL_SOURCE?.trim() || "",
2642
+ cwd ? resolve10(cwd, "packages/provider-plugin/native/rig-shell.zig") : "",
2643
+ projectRoot ? resolve10(projectRoot, "packages/provider-plugin/native/rig-shell.zig") : "",
2644
+ hostProjectRoot ? resolve10(hostProjectRoot, "packages/provider-plugin/native/rig-shell.zig") : "",
2645
+ execDir ? resolve10(execDir, "..", "..", "packages/provider-plugin/native/rig-shell.zig") : "",
2646
+ execDir ? resolve10(execDir, "..", "native", "rig-shell.zig") : "",
2647
+ resolve10(import.meta.dir, "../../native/rig-shell.zig")
2648
+ ].filter(Boolean))];
2649
+ }
2650
+ function nativePackageBinaryCandidates(fromDir, fileName) {
2651
+ const candidates = [];
2652
+ let cursor = resolve10(fromDir);
2653
+ for (let index = 0;index < 8; index += 1) {
2654
+ candidates.push(resolve10(cursor, "native", `${process.platform}-${process.arch}`, fileName), resolve10(cursor, "native", `${process.platform}-${process.arch}`, "bin", fileName), resolve10(cursor, "native", fileName), resolve10(cursor, "native", "bin", fileName));
2655
+ const parent = dirname5(cursor);
2656
+ if (parent === cursor)
2657
+ break;
2658
+ cursor = parent;
2659
+ }
2660
+ return candidates;
2661
+ }
2662
+ function rigShellBinaryCandidates() {
2663
+ const execDir = process.execPath?.trim() ? dirname5(process.execPath.trim()) : "";
2664
+ const fileName = runtimeRigShellFileName();
2665
+ return [...new Set([
2666
+ process.env.RIG_NATIVE_SHELL_BIN?.trim() || "",
2667
+ ...nativePackageBinaryCandidates(import.meta.dir, fileName),
2668
+ execDir ? resolve10(execDir, fileName) : "",
2669
+ execDir ? resolve10(execDir, "..", fileName) : "",
2670
+ execDir ? resolve10(execDir, "..", "bin", fileName) : ""
2671
+ ].filter(Boolean))];
2672
+ }
2673
+ function nativeBuildManifestPath(outputPath) {
2674
+ return `${outputPath}.build-manifest.json`;
2675
+ }
2676
+ async function hasMatchingNativeBuildManifest(manifestPath, buildKey) {
2677
+ if (!existsSync11(manifestPath)) {
2678
+ return false;
2679
+ }
2680
+ try {
2681
+ const manifest = await Bun.file(manifestPath).json();
2682
+ return manifest.version === 1 && manifest.buildKey === buildKey;
2683
+ } catch {
2684
+ return false;
2685
+ }
2686
+ }
2687
+ async function sha256File(path) {
2688
+ const hasher = new Bun.CryptoHasher("sha256");
2689
+ hasher.update(await Bun.file(path).arrayBuffer());
2690
+ return hasher.digest("hex");
2691
+ }
2692
+ var sharedNativeShellOutputDir, sharedNativeShellOutputPath;
2693
+ var init_shell_tools = __esm(() => {
2694
+ init_native_extract();
2695
+ sharedNativeShellOutputDir = resolve10(tmpdir2(), "rig-native");
2696
+ sharedNativeShellOutputPath = resolve10(sharedNativeShellOutputDir, `rig-shell-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
2697
+ });
2698
+
2699
+ // packages/provider-plugin/src/tooling/browser-tools.ts
2700
+ var exports_browser_tools = {};
2701
+ __export(exports_browser_tools, {
2702
+ runtimeBrowserToolNames: () => runtimeBrowserToolNames,
2703
+ runtimeBrowserToolBinaryName: () => runtimeBrowserToolBinaryName,
2704
+ materializeRuntimeBrowserTools: () => materializeRuntimeBrowserTools
2705
+ });
2706
+ import { existsSync as existsSync12, rmSync as rmSync4, symlinkSync } from "fs";
2707
+ import { resolve as resolve11 } from "path";
2708
+ import { RUNTIME_BROWSER_TOOL_NAMES } from "@rig/contracts";
2709
+ function runtimeBrowserToolBinaryName() {
2710
+ return `rig-browser-tool${process.platform === "win32" ? ".exe" : ""}`;
2711
+ }
2712
+ function runtimeBrowserToolNames() {
2713
+ return [...RUNTIME_BROWSER_TOOL_NAMES];
2714
+ }
2715
+ async function materializeRuntimeBrowserTools(targetDir) {
2716
+ const binaryPath = resolve11(targetDir, runtimeBrowserToolBinaryName());
2717
+ for (const tool of runtimeBrowserToolNames()) {
2718
+ const toolPath = resolve11(targetDir, tool);
2719
+ if (existsSync12(toolPath)) {
2720
+ rmSync4(toolPath, { force: true, recursive: true });
2721
+ }
2722
+ symlinkSync(binaryPath, toolPath);
2723
+ }
2724
+ return binaryPath;
2725
+ }
2726
+ var init_browser_tools = () => {};
2727
+
2728
+ // packages/provider-plugin/src/tooling/file-tools.ts
2729
+ var exports_file_tools = {};
2730
+ __export(exports_file_tools, {
2731
+ runtimeRigToolsFileName: () => runtimeRigToolsFileName,
2732
+ runtimeFileToolNames: () => runtimeFileToolNames,
2733
+ runtimeFileToolBasename: () => runtimeFileToolBasename,
2734
+ materializeRuntimeFileTools: () => materializeRuntimeFileTools,
2735
+ ensureRigToolsBinaryPath: () => ensureRigToolsBinaryPath
2736
+ });
2737
+ import { chmodSync as chmodSync2, copyFileSync as copyFileSync2, existsSync as existsSync13, mkdirSync as mkdirSync8, rmSync as rmSync5, symlinkSync as symlinkSync2 } from "fs";
2738
+ import { tmpdir as tmpdir3 } from "os";
2739
+ import { basename as basename4, dirname as dirname6, resolve as resolve12 } from "path";
2740
+ import { RUNTIME_FILE_TOOL_NAMES } from "@rig/contracts";
2741
+ function runtimeRigToolsFileName() {
2742
+ return `rig-tools${process.platform === "win32" ? ".exe" : ""}`;
2743
+ }
2744
+ function runtimeFileToolNames() {
2745
+ return [...RUNTIME_FILE_TOOL_NAMES];
2746
+ }
2747
+ async function ensureRigToolsBinaryPath(outputPath = sharedNativeToolsOutputPath) {
2748
+ const explicitBin = process.env.RIG_NATIVE_TOOLS_BIN?.trim();
2749
+ if (explicitBin && existsSync13(explicitBin)) {
2750
+ return explicitBin;
2751
+ }
2752
+ const embedded = extractEmbeddedNative("rig-tools");
2753
+ if (embedded) {
2754
+ return embedded;
2755
+ }
2756
+ const sourcePath = resolveRigToolsSourcePath();
2757
+ if (!sourcePath) {
2758
+ const bundledBinary = resolveBundledRigToolsBinaryPath();
2759
+ if (bundledBinary) {
2760
+ return bundledBinary;
2761
+ }
2762
+ throw new Error("rig-tools.zig source file not found.");
2763
+ }
2764
+ const zigBinary = Bun.which("zig");
2765
+ if (!zigBinary) {
2766
+ throw new Error("zig is required to build native Rig file tools.");
2767
+ }
2768
+ mkdirSync8(dirname6(outputPath), { recursive: true });
2769
+ const sourceDigest = await sha256File2(sourcePath);
2770
+ const buildKey = JSON.stringify({
2771
+ version: 1,
2772
+ zigBinary,
2773
+ platform: process.platform,
2774
+ arch: process.arch,
2775
+ sourcePath,
2776
+ sourceDigest
2777
+ });
2778
+ const manifestPath = nativeBuildManifestPath2(outputPath);
2779
+ const needsBuild = !existsSync13(outputPath) || !await hasMatchingNativeBuildManifest2(manifestPath, buildKey);
2780
+ if (!needsBuild) {
2781
+ return outputPath;
2782
+ }
2783
+ const build = Bun.spawn([
2784
+ zigBinary,
2785
+ "build-exe",
2786
+ sourcePath,
2787
+ "-O",
2788
+ "ReleaseFast",
2789
+ `-femit-bin=${outputPath}`
2790
+ ], {
2791
+ cwd: dirname6(sourcePath),
2792
+ stdout: "pipe",
2793
+ stderr: "pipe"
2794
+ });
2795
+ const [exitCode, stdout, stderr] = await Promise.all([
2796
+ build.exited,
2797
+ new Response(build.stdout).text(),
2798
+ new Response(build.stderr).text()
2799
+ ]);
2800
+ if (exitCode !== 0 || !existsSync13(outputPath)) {
2801
+ const details = [stderr.trim(), stdout.trim()].filter(Boolean).join(`
2802
+ `);
2803
+ throw new Error(`Failed to build native Rig file tools: ${details || `zig exited with code ${exitCode}`}`);
2804
+ }
2805
+ await Bun.write(manifestPath, `${JSON.stringify({ version: 1, buildKey }, null, 2)}
2806
+ `);
2807
+ return outputPath;
2808
+ }
2809
+ async function materializeRuntimeFileTools(targetDir) {
2810
+ const sourcePath = await ensureRigToolsBinaryPath();
2811
+ const targetPath = resolve12(targetDir, runtimeRigToolsFileName());
2812
+ mkdirSync8(targetDir, { recursive: true });
2813
+ const sourceDigest = await sha256File2(sourcePath);
2814
+ const buildKey = JSON.stringify({
2815
+ version: 1,
2816
+ sourcePath,
2817
+ sourceDigest
2818
+ });
2819
+ const needsCopy = !existsSync13(targetPath) || !await hasMatchingNativeBuildManifest2(nativeBuildManifestPath2(targetPath), buildKey);
2820
+ if (needsCopy) {
2821
+ copyFileSync2(sourcePath, targetPath);
2822
+ chmodSync2(targetPath, 493);
2823
+ await Bun.write(nativeBuildManifestPath2(targetPath), `${JSON.stringify({ version: 1, buildKey }, null, 2)}
2824
+ `);
2825
+ }
2826
+ for (const tool of runtimeFileToolNames()) {
2827
+ const toolPath = resolve12(targetDir, tool);
2828
+ if (existsSync13(toolPath)) {
2829
+ rmSync5(toolPath, { force: true, recursive: true });
2830
+ }
2831
+ symlinkSync2(targetPath, toolPath);
2832
+ }
2833
+ return targetPath;
2834
+ }
2835
+ function resolveRigToolsSourcePath() {
2836
+ for (const candidate of rigToolsSourceCandidates()) {
2837
+ if (candidate && existsSync13(candidate)) {
2838
+ return candidate;
2839
+ }
2840
+ }
2841
+ return null;
2842
+ }
2843
+ function resolveBundledRigToolsBinaryPath() {
2844
+ for (const candidate of rigToolsBinaryCandidates()) {
2845
+ if (candidate && existsSync13(candidate)) {
2846
+ return candidate;
2847
+ }
2848
+ }
2849
+ return null;
2850
+ }
2851
+ function rigToolsSourceCandidates() {
2852
+ const execDir = process.execPath?.trim() ? dirname6(process.execPath.trim()) : "";
2853
+ const cwd = process.cwd()?.trim() || "";
2854
+ const projectRoot = process.env.PROJECT_RIG_ROOT?.trim() || "";
2855
+ const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim() || "";
2856
+ return [...new Set([
2857
+ process.env.RIG_NATIVE_TOOLS_SOURCE?.trim() || "",
2858
+ cwd ? resolve12(cwd, "packages/provider-plugin/native/rig-tools.zig") : "",
2859
+ projectRoot ? resolve12(projectRoot, "packages/provider-plugin/native/rig-tools.zig") : "",
2860
+ hostProjectRoot ? resolve12(hostProjectRoot, "packages/provider-plugin/native/rig-tools.zig") : "",
2861
+ execDir ? resolve12(execDir, "..", "..", "packages/provider-plugin/native/rig-tools.zig") : "",
2862
+ execDir ? resolve12(execDir, "..", "native", "rig-tools.zig") : "",
2863
+ resolve12(import.meta.dir, "../../native/rig-tools.zig")
2864
+ ].filter(Boolean))];
2865
+ }
2866
+ function nativePackageBinaryCandidates2(fromDir, fileName) {
2867
+ const candidates = [];
2868
+ let cursor = resolve12(fromDir);
2869
+ for (let index = 0;index < 8; index += 1) {
2870
+ candidates.push(resolve12(cursor, "native", `${process.platform}-${process.arch}`, fileName), resolve12(cursor, "native", `${process.platform}-${process.arch}`, "bin", fileName), resolve12(cursor, "native", fileName), resolve12(cursor, "native", "bin", fileName));
2871
+ const parent = dirname6(cursor);
2872
+ if (parent === cursor)
2873
+ break;
2874
+ cursor = parent;
2875
+ }
2876
+ return candidates;
2877
+ }
2878
+ function rigToolsBinaryCandidates() {
2879
+ const execDir = process.execPath?.trim() ? dirname6(process.execPath.trim()) : "";
2880
+ const fileName = runtimeRigToolsFileName();
2881
+ return [...new Set([
2882
+ process.env.RIG_NATIVE_TOOLS_BIN?.trim() || "",
2883
+ ...nativePackageBinaryCandidates2(import.meta.dir, fileName),
2884
+ execDir ? resolve12(execDir, fileName) : "",
2885
+ execDir ? resolve12(execDir, "..", fileName) : "",
2886
+ execDir ? resolve12(execDir, "..", "bin", fileName) : ""
2887
+ ].filter(Boolean))];
2888
+ }
2889
+ function runtimeFileToolBasename(path) {
2890
+ return basename4(path);
2891
+ }
2892
+ function nativeBuildManifestPath2(outputPath) {
2893
+ return `${outputPath}.build-manifest.json`;
2894
+ }
2895
+ async function hasMatchingNativeBuildManifest2(manifestPath, buildKey) {
2896
+ if (!existsSync13(manifestPath)) {
2897
+ return false;
2898
+ }
2899
+ try {
2900
+ const manifest = await Bun.file(manifestPath).json();
2901
+ return manifest.version === 1 && manifest.buildKey === buildKey;
2902
+ } catch {
2903
+ return false;
2904
+ }
2905
+ }
2906
+ async function sha256File2(path) {
2907
+ const hasher = new Bun.CryptoHasher("sha256");
2908
+ hasher.update(await Bun.file(path).arrayBuffer());
2909
+ return hasher.digest("hex");
2910
+ }
2911
+ var sharedNativeToolsOutputDir, sharedNativeToolsOutputPath;
2912
+ var init_file_tools = __esm(() => {
2913
+ init_native_extract();
2914
+ sharedNativeToolsOutputDir = resolve12(tmpdir3(), "rig-native");
2915
+ sharedNativeToolsOutputPath = resolve12(sharedNativeToolsOutputDir, `rig-tools-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
2916
+ });
2917
+
2918
+ // packages/provider-plugin/src/tooling/gateway.ts
2919
+ var exports_gateway = {};
2920
+ __export(exports_gateway, {
2921
+ runtimeGatewayToolNames: () => runtimeGatewayToolNames,
2922
+ runtimeFileToolNames: () => runtimeFileToolNames,
2923
+ runtimeBrowserToolNames: () => runtimeBrowserToolNames,
2924
+ materializeRuntimeToolGateway: () => materializeRuntimeToolGateway,
2925
+ materializeRuntimeFileTools: () => materializeRuntimeFileTools,
2926
+ materializeRuntimeBrowserTools: () => materializeRuntimeBrowserTools
2927
+ });
2928
+ import { existsSync as existsSync14, rmSync as rmSync6, symlinkSync as symlinkSync3 } from "fs";
2929
+ import { resolve as resolve13 } from "path";
2930
+ import { RUNTIME_SHELL_TOOL_NAMES as RUNTIME_SHELL_TOOL_NAMES2 } from "@rig/contracts";
2931
+ function runtimeGatewayToolNames() {
2932
+ return [...RUNTIME_SHELL_TOOL_NAMES2];
2933
+ }
2934
+ async function materializeRuntimeToolGateway(binDir) {
2935
+ const shellPath = await materializeRigShellBinary(binDir);
2936
+ for (const tool of runtimeGatewayToolNames()) {
2937
+ const toolPath = resolve13(binDir, tool);
2938
+ if (existsSync14(toolPath)) {
2939
+ rmSync6(toolPath, { force: true, recursive: true });
2940
+ }
2941
+ symlinkSync3(shellPath, toolPath);
2942
+ }
2943
+ await materializeRuntimeBrowserTools(binDir);
2944
+ return resolve13(binDir, runtimeRigShellFileName());
2945
+ }
2946
+ var init_gateway = __esm(() => {
2947
+ init_shell_tools();
2948
+ init_browser_tools();
2949
+ init_browser_tools();
2950
+ init_file_tools();
2951
+ });
2952
+
2953
+ // packages/provider-plugin/src/tooling/runtime-binary-build.ts
2954
+ import { chmodSync as chmodSync3, copyFileSync as copyFileSync3, cpSync, existsSync as existsSync15, linkSync, mkdirSync as mkdirSync9, renameSync as renameSync2, rmSync as rmSync7, writeFileSync as writeFileSync7 } from "fs";
2955
+ import { basename as basename5, dirname as dirname7, resolve as resolve14 } from "path";
2956
+ import { fileURLToPath } from "url";
2957
+ import { drainMicrotasks, gcAndSweep } from "bun:jsc";
2958
+ import { resolveRigLayout as resolveRigLayout2 } from "@rig/core/layout";
2959
+ import { runtimeProvisioningEnv } from "@rig/core/runtime-provisioning-env";
2960
+ function materializeSelfExecRole(outputPath, define) {
2961
+ const selfPath = process.execPath;
2962
+ mkdirSync9(dirname7(outputPath), { recursive: true });
2963
+ rmSync7(outputPath, { force: true });
2964
+ try {
2965
+ linkSync(selfPath, outputPath);
2966
+ } catch {
2967
+ copyFileSync3(selfPath, outputPath);
2968
+ }
2969
+ chmodSync3(outputPath, 493);
2970
+ const role = basename5(outputPath).replace(/\.exe$/i, "");
2971
+ writeFileSync7(`${outputPath}.rig-runconfig.json`, `${JSON.stringify({ role, define: define ?? {} }, null, 2)}
2972
+ `, { mode: 384 });
2973
+ }
2974
+ async function buildRuntimeBinary(options) {
2975
+ return runSerializedRuntimeBinaryBuild(async () => {
2976
+ const resolved = resolveRuntimeBinaryBuildOptions(options);
2977
+ runBestEffortBuildGc();
2978
+ const manifestPath = runtimeBinaryCacheManifestPath(resolved.outputPath);
2979
+ const buildKey = createRuntimeBinaryBuildKey({
2980
+ entrypoint: resolved.entrypoint,
2981
+ define: resolved.define,
2982
+ env: resolved.env,
2983
+ external: resolved.external
2984
+ });
2985
+ if (await isRuntimeBinaryBuildFresh({ outputPath: resolved.outputPath, manifestPath, buildKey })) {
2986
+ return;
2987
+ }
2988
+ if (shouldUseRuntimeBinaryBuildWorker()) {
2989
+ await buildRuntimeBinaryViaWorker(resolved);
2990
+ } else {
2991
+ await buildRuntimeBinaryInProcess(resolved, { manifestPath, buildKey });
2992
+ }
2993
+ runBestEffortBuildGc();
2994
+ });
2995
+ }
2996
+ async function buildRuntimeBinaryInProcess(options, manifest) {
2997
+ const tempBuildDir = resolve14(dirname7(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
2998
+ const tempOutputPath = resolve14(tempBuildDir, basename5(options.outputPath));
2999
+ mkdirSync9(tempBuildDir, { recursive: true });
3000
+ await withTemporaryEnv({
3001
+ ...options.env,
3002
+ ...options.define ? { RIG_BUILD_CONFIG_JSON: JSON.stringify(options.define) } : {}
3003
+ }, async () => withTemporaryCwd(tempBuildDir, async () => {
3004
+ const buildResult = await Bun.build({
3005
+ entrypoints: [options.entrypoint],
3006
+ compile: {
3007
+ target: currentCompileTarget(),
3008
+ outfile: tempOutputPath
3009
+ },
3010
+ target: "bun",
3011
+ format: "esm",
3012
+ minify: true,
3013
+ bytecode: true,
3014
+ metafile: true,
3015
+ ...options.external ? { external: options.external } : {},
3016
+ ...options.define ? { define: { __RIG_BUILD_CONFIG__: JSON.stringify(options.define) } } : {}
3017
+ });
3018
+ if (!buildResult.success) {
3019
+ const details = buildResult.logs.map((log) => [log.message, log.position?.file ? `${log.position.file}:${log.position.line}:${log.position.column}` : ""].filter(Boolean).join(" ")).filter(Boolean).join(`
3020
+ `);
3021
+ throw new Error(`Failed to build ${options.entrypoint}: ${details || "Bun.build() returned errors"}`);
3022
+ }
3023
+ if (!existsSync15(tempOutputPath)) {
3024
+ const emitted = buildResult.outputs.map((output) => output.path).join(", ") || "(none)";
3025
+ throw new Error(`Failed to build ${options.entrypoint}: Bun.build() did not emit ${tempOutputPath}. Emitted: ${emitted}`);
3026
+ }
3027
+ renameSync2(tempOutputPath, options.outputPath);
3028
+ chmodSync3(options.outputPath, 493);
3029
+ if (manifest) {
3030
+ await writeRuntimeBinaryCacheManifest({
3031
+ manifestPath: manifest.manifestPath,
3032
+ buildKey: manifest.buildKey,
3033
+ cwd: tempBuildDir,
3034
+ metafile: buildResult.metafile
3035
+ });
3036
+ }
3037
+ })).finally(() => {
3038
+ rmSync7(tempBuildDir, { recursive: true, force: true });
3039
+ });
3040
+ }
3041
+ function runBestEffortBuildGc() {
3042
+ try {
3043
+ drainMicrotasks();
3044
+ } catch {}
3045
+ try {
3046
+ gcAndSweep();
3047
+ } catch {}
3048
+ }
3049
+ function runtimeBinaryCacheManifestPath(outputPath) {
3050
+ return `${outputPath}.build-manifest.json`;
3051
+ }
3052
+ function resolveRuntimeBinaryBuildOptions(options) {
3053
+ return {
3054
+ ...options,
3055
+ entrypoint: resolve14(options.cwd, options.sourcePath),
3056
+ outputPath: resolve14(options.outputPath)
3057
+ };
3058
+ }
3059
+ function shouldUseRuntimeBinaryBuildWorker() {
3060
+ if (process.env.RIG_RUNTIME_BUILD_WORKER === "1") {
3061
+ return false;
3062
+ }
3063
+ if (process.env.RIG_RUNTIME_BUILD_IN_PROCESS === "1") {
3064
+ return false;
3065
+ }
3066
+ return true;
3067
+ }
3068
+ async function buildRuntimeBinaryViaWorker(options) {
3069
+ const workerSourcePath = resolveRuntimeBinaryBuildWorkerSourcePath(options);
3070
+ if (!workerSourcePath || !existsSync15(workerSourcePath)) {
3071
+ await buildRuntimeBinaryInProcess(options, {
3072
+ manifestPath: runtimeBinaryCacheManifestPath(options.outputPath),
3073
+ buildKey: createRuntimeBinaryBuildKey({
3074
+ entrypoint: options.entrypoint,
3075
+ define: options.define,
3076
+ env: options.env,
3077
+ external: options.external
3078
+ })
3079
+ });
3080
+ return;
3081
+ }
3082
+ const payloadPath = createRuntimeBinaryBuildWorkerPayloadPath(options.outputPath);
3083
+ const bunCli = resolveRuntimeBinaryBuildWorkerInvocation();
3084
+ await Bun.write(payloadPath, `${JSON.stringify(options)}
3085
+ `);
3086
+ const build = Bun.spawn([bunCli.command, workerSourcePath, payloadPath], {
3087
+ cwd: options.cwd,
3088
+ stdout: "pipe",
3089
+ stderr: "pipe",
3090
+ env: {
3091
+ ...process.env,
3092
+ ...options.env,
3093
+ ...bunCli.env,
3094
+ RIG_RUNTIME_BUILD_WORKER: "1"
3095
+ }
3096
+ });
3097
+ const [exitCode, stdout, stderr] = await Promise.all([
3098
+ build.exited,
3099
+ new Response(build.stdout).text(),
3100
+ new Response(build.stderr).text()
3101
+ ]);
3102
+ rmSync7(payloadPath, { force: true });
3103
+ if (exitCode !== 0) {
3104
+ throw new Error(`Failed to build ${options.entrypoint}: ${(stderr || stdout || `worker exited ${exitCode}`).trim()}`);
3105
+ }
3106
+ }
3107
+ function createRuntimeBinaryBuildWorkerPayloadPath(outputPath) {
3108
+ return resolve14(dirname7(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
3109
+ }
3110
+ function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
3111
+ const envRoots = [
3112
+ options.cwd?.trim(),
3113
+ process.env.RIG_HOST_PROJECT_ROOT?.trim(),
3114
+ process.env.PROJECT_RIG_ROOT?.trim()
3115
+ ].filter(Boolean);
3116
+ for (const root of envRoots) {
3117
+ const candidate = resolve14(root, "packages/provider-plugin/src/tooling/binary-build-worker.ts");
3118
+ if (existsSync15(candidate)) {
3119
+ return candidate;
3120
+ }
3121
+ }
3122
+ const localCandidate = resolve14(import.meta.dir, "binary-build-worker.ts");
3123
+ return existsSync15(localCandidate) ? localCandidate : null;
3124
+ }
3125
+ function resolveRuntimeBinaryBuildWorkerInvocation() {
3126
+ const bunPath = Bun.which("bun");
3127
+ if (bunPath) {
3128
+ return { command: bunPath, env: {} };
3129
+ }
3130
+ if (process.execPath?.trim()) {
3131
+ return {
3132
+ command: process.execPath,
3133
+ env: { BUN_BE_BUN: "1" }
3134
+ };
3135
+ }
3136
+ throw new Error("bun is required to run the runtime binary build worker.");
3137
+ }
3138
+ function currentCompileTarget() {
3139
+ if (process.platform === "darwin") {
3140
+ return process.arch === "arm64" ? "bun-darwin-arm64" : "bun-darwin-x64";
3141
+ }
3142
+ if (process.platform === "linux") {
3143
+ return process.arch === "arm64" ? "bun-linux-arm64" : "bun-linux-x64";
3144
+ }
3145
+ return "bun-windows-x64";
3146
+ }
3147
+ function createRuntimeBinaryBuildKey(input) {
3148
+ return JSON.stringify({
3149
+ version: 1,
3150
+ bunVersion: Bun.version,
3151
+ platform: process.platform,
3152
+ arch: process.arch,
3153
+ entrypoint: input.entrypoint,
3154
+ define: sortRecord(input.define),
3155
+ external: input.external ? [...input.external].sort() : undefined,
3156
+ env: sortRecord(input.env)
3157
+ });
3158
+ }
3159
+ async function isRuntimeBinaryBuildFresh(input) {
3160
+ if (!existsSync15(input.outputPath) || !existsSync15(input.manifestPath)) {
3161
+ return false;
3162
+ }
3163
+ let manifest = null;
3164
+ try {
3165
+ manifest = await Bun.file(input.manifestPath).json();
3166
+ } catch {
3167
+ return false;
3168
+ }
3169
+ if (!manifest || manifest.version !== 1 || manifest.buildKey !== input.buildKey) {
3170
+ return false;
3171
+ }
3172
+ for (const [filePath, expectedDigest] of Object.entries(manifest.inputs || {})) {
3173
+ if (!existsSync15(filePath)) {
3174
+ return false;
3175
+ }
3176
+ if (await sha256File3(filePath) !== expectedDigest) {
3177
+ return false;
3178
+ }
3179
+ }
3180
+ return true;
3181
+ }
3182
+ async function writeRuntimeBinaryCacheManifest(input) {
3183
+ const inputs = {};
3184
+ for (const inputPath of Object.keys(input.metafile?.inputs || {}).sort()) {
3185
+ const normalized = normalizeBuildInputPath(input.cwd, inputPath);
3186
+ if (!normalized || !existsSync15(normalized)) {
3187
+ continue;
3188
+ }
3189
+ inputs[normalized] = await sha256File3(normalized);
3190
+ }
3191
+ const manifest = {
3192
+ version: 1,
3193
+ buildKey: input.buildKey,
3194
+ inputs
3195
+ };
3196
+ await Bun.write(input.manifestPath, `${JSON.stringify(manifest, null, 2)}
3197
+ `);
3198
+ }
3199
+ function normalizeBuildInputPath(cwd, inputPath) {
3200
+ if (!inputPath) {
3201
+ return null;
3202
+ }
3203
+ if (inputPath.startsWith("file://")) {
3204
+ return fileURLToPath(inputPath);
3205
+ }
3206
+ if (inputPath.startsWith("<")) {
3207
+ return null;
3208
+ }
3209
+ return resolve14(cwd, inputPath);
3210
+ }
3211
+ async function sha256File3(path) {
3212
+ const hasher = new Bun.CryptoHasher("sha256");
3213
+ hasher.update(await Bun.file(path).arrayBuffer());
3214
+ return hasher.digest("hex");
3215
+ }
3216
+ function sortRecord(value) {
3217
+ if (!value) {
3218
+ return;
3219
+ }
3220
+ return Object.fromEntries(Object.entries(value).sort(([left], [right]) => left.localeCompare(right)));
3221
+ }
3222
+ async function runSerializedRuntimeBinaryBuild(action) {
3223
+ const previous = runtimeBinaryBuildQueue;
3224
+ let release;
3225
+ runtimeBinaryBuildQueue = new Promise((resolve15) => {
3226
+ release = resolve15;
3227
+ });
3228
+ await previous;
3229
+ try {
3230
+ return await action();
3231
+ } finally {
3232
+ release();
3233
+ }
3234
+ }
3235
+ async function withTemporaryEnv(env, action) {
3236
+ if (!env) {
3237
+ return action();
3238
+ }
3239
+ const previousValues = new Map;
3240
+ for (const [key, value] of Object.entries(env)) {
3241
+ previousValues.set(key, process.env[key]);
3242
+ if (value === undefined) {
3243
+ delete process.env[key];
3244
+ } else {
3245
+ process.env[key] = value;
3246
+ }
3247
+ }
3248
+ try {
3249
+ return await action();
3250
+ } finally {
3251
+ for (const [key, value] of previousValues.entries()) {
3252
+ if (value === undefined) {
3253
+ delete process.env[key];
3254
+ } else {
3255
+ process.env[key] = value;
3256
+ }
3257
+ }
3258
+ }
3259
+ }
3260
+ async function withTemporaryCwd(cwd, action) {
3261
+ const previousCwd = process.cwd();
3262
+ process.chdir(cwd);
3263
+ try {
3264
+ return await action();
3265
+ } finally {
3266
+ process.chdir(previousCwd);
3267
+ }
3268
+ }
3269
+ var runtimeBinaryBuildQueue;
3270
+ var init_runtime_binary_build = __esm(() => {
3271
+ init_native_extract();
3272
+ runtimeBinaryBuildQueue = Promise.resolve();
3273
+ });
3274
+
3275
+ // packages/provider-plugin/src/tooling/claude-router-binary.ts
3276
+ var exports_claude_router_binary = {};
3277
+ __export(exports_claude_router_binary, {
3278
+ runtimeClaudeToolRouterFileName: () => runtimeClaudeToolRouterFileName,
3279
+ materializeClaudeToolRouterBinary: () => materializeClaudeToolRouterBinary,
3280
+ ensureClaudeToolRouterBinaryPath: () => ensureClaudeToolRouterBinaryPath
3281
+ });
3282
+ import { chmodSync as chmodSync4, copyFileSync as copyFileSync4, existsSync as existsSync16, mkdirSync as mkdirSync10, statSync as statSync3 } from "fs";
3283
+ import { tmpdir as tmpdir4 } from "os";
3284
+ import { dirname as dirname8, resolve as resolve15 } from "path";
3285
+ function runtimeClaudeToolRouterFileName() {
3286
+ return `rig-tool-router${process.platform === "win32" ? ".exe" : ""}`;
3287
+ }
3288
+ async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = sharedRouterOutputPath) {
3289
+ const sourcePath = resolve15(projectRoot, "packages/provider-plugin/src/tooling/claude-router.ts");
3290
+ mkdirSync10(dirname8(outputPath), { recursive: true });
3291
+ const needsBuild = !existsSync16(outputPath) || statSync3(sourcePath).mtimeMs > statSync3(outputPath).mtimeMs;
3292
+ if (!needsBuild) {
3293
+ return outputPath;
3294
+ }
3295
+ await buildRuntimeBinary({
3296
+ sourcePath: "packages/provider-plugin/src/tooling/claude-router.ts",
3297
+ outputPath,
3298
+ cwd: projectRoot
3299
+ });
3300
+ chmodSync4(outputPath, 493);
3301
+ return outputPath;
3302
+ }
3303
+ async function materializeClaudeToolRouterBinary(projectRoot, targetDir) {
3304
+ if (hasEmbeddedNatives()) {
3305
+ const targetPath2 = resolve15(targetDir, runtimeClaudeToolRouterFileName());
3306
+ materializeSelfExecRole(targetPath2);
3307
+ return targetPath2;
3308
+ }
3309
+ const sourcePath = await ensureClaudeToolRouterBinaryPath(projectRoot);
3310
+ const targetPath = resolve15(targetDir, runtimeClaudeToolRouterFileName());
3311
+ mkdirSync10(targetDir, { recursive: true });
3312
+ const needsCopy = !existsSync16(targetPath) || statSync3(sourcePath).mtimeMs > statSync3(targetPath).mtimeMs;
3313
+ if (needsCopy) {
3314
+ copyFileSync4(sourcePath, targetPath);
3315
+ chmodSync4(targetPath, 493);
3316
+ }
3317
+ return targetPath;
3318
+ }
3319
+ var sharedRouterOutputDir, sharedRouterOutputPath;
3320
+ var init_claude_router_binary = __esm(() => {
3321
+ init_runtime_binary_build();
3322
+ init_native_extract();
3323
+ sharedRouterOutputDir = resolve15(tmpdir4(), "rig-native");
3324
+ sharedRouterOutputPath = resolve15(sharedRouterOutputDir, `rig-tool-router-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
3325
+ });
3326
+
55
3327
  // packages/provider-plugin/src/plugin.ts
56
3328
  import { definePlugin } from "@rig/core/config";
57
- import { RUNTIME_INSTRUCTION_SERVICE_CAPABILITY_ID } from "@rig/contracts";
3329
+ import { defineCapability as defineCapability6 } from "@rig/core/capability";
3330
+ import { RUNTIME_INSTRUCTION, SESSION_ASSET_MATERIALIZER, TOOL_MATERIALIZER } from "@rig/contracts";
58
3331
  var PROVIDER_PLUGIN_NAME = "@rig/provider-plugin";
3332
+ var DEFAULT_PROVIDER_KIND = "codex";
3333
+ var RuntimeInstructionCap = defineCapability6(RUNTIME_INSTRUCTION);
3334
+ var SessionAssetMaterializerCap = defineCapability6(SESSION_ASSET_MATERIALIZER);
3335
+ var ToolMaterializerCap = defineCapability6(TOOL_MATERIALIZER);
3336
+ var PROVIDER_SEED_ENTRYPOINTS = [
3337
+ {
3338
+ id: `${PROVIDER_PLUGIN_NAME}:rig-agent`,
3339
+ basename: "rig-agent",
3340
+ description: "Provider-owned per-runtime Rig agent entrypoint.",
3341
+ run: async (context) => {
3342
+ const args = [...context.argv].slice(2);
3343
+ if (args.length === 0 || args[0] === "--help" || args[0] === "help" || args[0] === "--version" || args[0] === "-V") {
3344
+ console.log("[rig-agent] runtime shim ready");
3345
+ return 0;
3346
+ }
3347
+ const { runRigAgentEntrypoint: runRigAgentEntrypoint2 } = await Promise.resolve().then(() => (init_rig_agent_entrypoint(), exports_rig_agent_entrypoint));
3348
+ await runRigAgentEntrypoint2();
3349
+ }
3350
+ },
3351
+ {
3352
+ id: `${PROVIDER_PLUGIN_NAME}:rig-agent-dispatch`,
3353
+ basename: "rig-agent-dispatch",
3354
+ description: "Provider-owned agent dispatch/provisioning shim.",
3355
+ run: async (context) => {
3356
+ const { runAgentWrapper: runAgentWrapper2 } = await Promise.resolve().then(() => (init_agent_wrapper(), exports_agent_wrapper));
3357
+ const exitCode = await runAgentWrapper2({ argv: [...context.argv].slice(2) });
3358
+ return exitCode;
3359
+ }
3360
+ },
3361
+ {
3362
+ id: `${PROVIDER_PLUGIN_NAME}:rig-browser-tool`,
3363
+ basename: "rig-browser-tool",
3364
+ description: "Provider-owned runtime browser helper shim.",
3365
+ run: async (context) => {
3366
+ const args = [...context.argv].slice(2);
3367
+ if (args.length === 0 || args[0] === "--help" || args[0] === "help" || args[0] === "--version" || args[0] === "-V") {
3368
+ console.log("[rig-browser-tool] runtime shim ready");
3369
+ return 0;
3370
+ }
3371
+ if (context.execPath)
3372
+ process.argv[1] = context.execPath;
3373
+ else if (context.basename)
3374
+ process.argv[1] = context.basename;
3375
+ await Promise.resolve().then(() => (init_browser_tool_entrypoint(), exports_browser_tool_entrypoint));
3376
+ }
3377
+ },
3378
+ {
3379
+ id: `${PROVIDER_PLUGIN_NAME}:rig-tool-router`,
3380
+ basename: "rig-tool-router",
3381
+ description: "Claude-compatible provider tool router sidecar.",
3382
+ run: async () => {
3383
+ const { runClaudeToolRouterServer } = await import("@rig/provider-plugin/tooling/claude-router");
3384
+ await runClaudeToolRouterServer();
3385
+ }
3386
+ }
3387
+ ];
59
3388
  var providerPlugin = definePlugin({
60
3389
  name: PROVIDER_PLUGIN_NAME,
61
3390
  version: "0.0.0-alpha.1",
62
3391
  contributes: {
63
3392
  capabilities: [
64
- {
65
- id: RUNTIME_INSTRUCTION_SERVICE_CAPABILITY_ID,
3393
+ RuntimeInstructionCap.provide(async () => (await Promise.resolve().then(() => (init_service(), exports_service))).svc, {
66
3394
  title: "Agent harness provider instructions",
67
- description: "Provide the agent-harness file-tool contract and runtime-context instruction lines.",
68
- run: async () => (await Promise.resolve().then(() => (init_service(), exports_service))).svc
69
- }
70
- ]
3395
+ description: "Provide the agent-harness file-tool contract and runtime-context instruction lines."
3396
+ }),
3397
+ SessionAssetMaterializerCap.provide(async () => (await Promise.resolve().then(() => (init_session_asset_materializer_service(), exports_session_asset_materializer_service))).sessionAssetMaterializer, {
3398
+ title: "Pi session asset materializer",
3399
+ description: "Materialize plugin-contributed Pi skills and config-declared Pi packages into the workspace .pi/ directory."
3400
+ }),
3401
+ ToolMaterializerCap.provide(async () => {
3402
+ const [gateway, fileTools, claudeRouter, browserTools] = await Promise.all([
3403
+ Promise.resolve().then(() => (init_gateway(), exports_gateway)),
3404
+ Promise.resolve().then(() => (init_file_tools(), exports_file_tools)),
3405
+ Promise.resolve().then(() => (init_claude_router_binary(), exports_claude_router_binary)),
3406
+ Promise.resolve().then(() => (init_browser_tools(), exports_browser_tools))
3407
+ ]);
3408
+ return {
3409
+ materializeRuntimeToolGateway: gateway.materializeRuntimeToolGateway,
3410
+ materializeRuntimeFileTools: fileTools.materializeRuntimeFileTools,
3411
+ materializeClaudeToolRouterBinary: claudeRouter.materializeClaudeToolRouterBinary,
3412
+ materializeRuntimeBrowserTools: browserTools.materializeRuntimeBrowserTools,
3413
+ runtimeBrowserToolBinaryName: browserTools.runtimeBrowserToolBinaryName
3414
+ };
3415
+ }, {
3416
+ title: "Runtime tool materializer",
3417
+ description: "Materializes provider-plugin-owned tool binaries (gateway, file-tools, claude-router, browser-tools) into the runtime bin directory."
3418
+ })
3419
+ ],
3420
+ seedEntrypoints: PROVIDER_SEED_ENTRYPOINTS,
3421
+ config: { defaults: () => ({ runtime: { harness: "pi", mode: "yolo" } }) }
71
3422
  }
72
3423
  });
73
3424
  function createProviderPlugin() {
@@ -78,5 +3429,6 @@ export {
78
3429
  providerPlugin,
79
3430
  plugin_default as default,
80
3431
  createProviderPlugin,
81
- PROVIDER_PLUGIN_NAME
3432
+ PROVIDER_PLUGIN_NAME,
3433
+ DEFAULT_PROVIDER_KIND
82
3434
  };