@h-rig/runtime 0.0.6-alpha.0

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 (176) hide show
  1. package/README.md +27 -0
  2. package/dist/bin/rig-agent-dispatch.js +9615 -0
  3. package/dist/bin/rig-agent.js +9512 -0
  4. package/dist/bin/rig-browser-tool.js +269 -0
  5. package/dist/src/agent-mode.js +48 -0
  6. package/dist/src/baked-secrets.js +121 -0
  7. package/dist/src/binary-build-worker.js +312 -0
  8. package/dist/src/binary-run.js +540 -0
  9. package/dist/src/boundaries.js +1 -0
  10. package/dist/src/build-time-config.js +25 -0
  11. package/dist/src/control-plane/agent-roles.js +27 -0
  12. package/dist/src/control-plane/agent-wrapper.js +9621 -0
  13. package/dist/src/control-plane/authority-files.js +582 -0
  14. package/dist/src/control-plane/browser-contract.js +135 -0
  15. package/dist/src/control-plane/controlled-bash.js +1111 -0
  16. package/dist/src/control-plane/errors.js +13 -0
  17. package/dist/src/control-plane/harness-main.js +10828 -0
  18. package/dist/src/control-plane/hook-materializer.js +75 -0
  19. package/dist/src/control-plane/hooks/audit-trail.js +353 -0
  20. package/dist/src/control-plane/hooks/completion-verification.js +7552 -0
  21. package/dist/src/control-plane/hooks/import-guard.js +890 -0
  22. package/dist/src/control-plane/hooks/inject-context.js +4189 -0
  23. package/dist/src/control-plane/hooks/post-edit-lint.js +43 -0
  24. package/dist/src/control-plane/hooks/safety-guard.js +910 -0
  25. package/dist/src/control-plane/hooks/scope-guard.js +907 -0
  26. package/dist/src/control-plane/hooks/shared.js +44 -0
  27. package/dist/src/control-plane/hooks/submodule-branch.js +7797 -0
  28. package/dist/src/control-plane/hooks/task-runtime-start.js +7799 -0
  29. package/dist/src/control-plane/hooks/test-integrity-guard.js +891 -0
  30. package/dist/src/control-plane/materialize-task-config.js +453 -0
  31. package/dist/src/control-plane/memory-sync/cli.js +2019 -0
  32. package/dist/src/control-plane/memory-sync/db.js +753 -0
  33. package/dist/src/control-plane/memory-sync/embed.js +281 -0
  34. package/dist/src/control-plane/memory-sync/index.js +2049 -0
  35. package/dist/src/control-plane/memory-sync/query.js +294 -0
  36. package/dist/src/control-plane/memory-sync/read.js +784 -0
  37. package/dist/src/control-plane/memory-sync/types.js +6 -0
  38. package/dist/src/control-plane/memory-sync/write.js +1547 -0
  39. package/dist/src/control-plane/native/git-native.js +490 -0
  40. package/dist/src/control-plane/native/git-ops.js +2860 -0
  41. package/dist/src/control-plane/native/harness-cli.js +9721 -0
  42. package/dist/src/control-plane/native/pr-automation.js +373 -0
  43. package/dist/src/control-plane/native/profile-ops.js +481 -0
  44. package/dist/src/control-plane/native/repo-ops.js +2342 -0
  45. package/dist/src/control-plane/native/root-resolver.js +66 -0
  46. package/dist/src/control-plane/native/run-ops.js +3281 -0
  47. package/dist/src/control-plane/native/runtime-native-sidecar.js +299 -0
  48. package/dist/src/control-plane/native/runtime-native.js +392 -0
  49. package/dist/src/control-plane/native/scope-rules.js +17 -0
  50. package/dist/src/control-plane/native/task-ops.js +6320 -0
  51. package/dist/src/control-plane/native/task-state.js +1512 -0
  52. package/dist/src/control-plane/native/utils.js +535 -0
  53. package/dist/src/control-plane/native/validator-binaries.js +889 -0
  54. package/dist/src/control-plane/native/validator.js +2197 -0
  55. package/dist/src/control-plane/native/verifier.js +3249 -0
  56. package/dist/src/control-plane/native/workspace-ops.js +1635 -0
  57. package/dist/src/control-plane/plugin-host-context.js +334 -0
  58. package/dist/src/control-plane/project-main-pre-run-sync.js +630 -0
  59. package/dist/src/control-plane/provider/claude-stream-records.js +158 -0
  60. package/dist/src/control-plane/provider/codex-app-server.js +885 -0
  61. package/dist/src/control-plane/provider/codex-exec-records.js +203 -0
  62. package/dist/src/control-plane/provider/rig-task-run-skill.js +39 -0
  63. package/dist/src/control-plane/provider/runtime-instructions.js +96 -0
  64. package/dist/src/control-plane/remote.js +854 -0
  65. package/dist/src/control-plane/repos/index.js +473 -0
  66. package/dist/src/control-plane/repos/layout.js +124 -0
  67. package/dist/src/control-plane/repos/mirror/bootstrap.js +268 -0
  68. package/dist/src/control-plane/repos/mirror/refresh.js +398 -0
  69. package/dist/src/control-plane/repos/mirror/state.js +167 -0
  70. package/dist/src/control-plane/repos/registry.js +77 -0
  71. package/dist/src/control-plane/repos/types.js +1 -0
  72. package/dist/src/control-plane/runtime/agent-mode.js +48 -0
  73. package/dist/src/control-plane/runtime/baked-secrets.js +120 -0
  74. package/dist/src/control-plane/runtime/claude-tool-router-binary.js +343 -0
  75. package/dist/src/control-plane/runtime/claude-tool-router.js +520 -0
  76. package/dist/src/control-plane/runtime/context.js +216 -0
  77. package/dist/src/control-plane/runtime/events.js +218 -0
  78. package/dist/src/control-plane/runtime/guard-types.js +6 -0
  79. package/dist/src/control-plane/runtime/guard.js +880 -0
  80. package/dist/src/control-plane/runtime/image/fingerprint-sidecar.js +1194 -0
  81. package/dist/src/control-plane/runtime/image/index.js +2255 -0
  82. package/dist/src/control-plane/runtime/image-fingerprint-sidecar.js +1191 -0
  83. package/dist/src/control-plane/runtime/image.js +2255 -0
  84. package/dist/src/control-plane/runtime/index.js +8511 -0
  85. package/dist/src/control-plane/runtime/isolation/discovery.js +599 -0
  86. package/dist/src/control-plane/runtime/isolation/home.js +1217 -0
  87. package/dist/src/control-plane/runtime/isolation/index.js +8193 -0
  88. package/dist/src/control-plane/runtime/isolation/runner.js +2651 -0
  89. package/dist/src/control-plane/runtime/isolation/shared.js +501 -0
  90. package/dist/src/control-plane/runtime/isolation/toolchain.js +1892 -0
  91. package/dist/src/control-plane/runtime/isolation/types.js +1 -0
  92. package/dist/src/control-plane/runtime/isolation/worktree.js +509 -0
  93. package/dist/src/control-plane/runtime/isolation.js +8193 -0
  94. package/dist/src/control-plane/runtime/overlay.js +67 -0
  95. package/dist/src/control-plane/runtime/plugin-mode.js +41 -0
  96. package/dist/src/control-plane/runtime/plugins.js +1131 -0
  97. package/dist/src/control-plane/runtime/provisioning-env.js +220 -0
  98. package/dist/src/control-plane/runtime/queue.js +8358 -0
  99. package/dist/src/control-plane/runtime/rig-shell.js +205 -0
  100. package/dist/src/control-plane/runtime/rig-tools.js +182 -0
  101. package/dist/src/control-plane/runtime/runner-context.js +1 -0
  102. package/dist/src/control-plane/runtime/runtime-paths.js +184 -0
  103. package/dist/src/control-plane/runtime/sandbox/backend-bwrap.js +311 -0
  104. package/dist/src/control-plane/runtime/sandbox/backend-none.js +21 -0
  105. package/dist/src/control-plane/runtime/sandbox/backend-seatbelt.js +268 -0
  106. package/dist/src/control-plane/runtime/sandbox/backend.js +1718 -0
  107. package/dist/src/control-plane/runtime/sandbox/orchestrator.js +1745 -0
  108. package/dist/src/control-plane/runtime/sandbox/utils.js +137 -0
  109. package/dist/src/control-plane/runtime/sandbox-backend-bwrap.js +311 -0
  110. package/dist/src/control-plane/runtime/sandbox-backend-none.js +21 -0
  111. package/dist/src/control-plane/runtime/sandbox-backend-seatbelt.js +268 -0
  112. package/dist/src/control-plane/runtime/sandbox-backend.js +1718 -0
  113. package/dist/src/control-plane/runtime/sandbox-orchestrator.js +1745 -0
  114. package/dist/src/control-plane/runtime/sandbox-utils.js +137 -0
  115. package/dist/src/control-plane/runtime/snapshot/index.js +454 -0
  116. package/dist/src/control-plane/runtime/snapshot/sidecar.js +502 -0
  117. package/dist/src/control-plane/runtime/snapshot/task-run.js +1578 -0
  118. package/dist/src/control-plane/runtime/snapshot-sidecar.js +498 -0
  119. package/dist/src/control-plane/runtime/snapshot.js +454 -0
  120. package/dist/src/control-plane/runtime/task-run-snapshot.js +1578 -0
  121. package/dist/src/control-plane/runtime/tool-gateway.js +422 -0
  122. package/dist/src/control-plane/runtime/tooling/browser-tools.js +32 -0
  123. package/dist/src/control-plane/runtime/tooling/claude-router-binary.js +343 -0
  124. package/dist/src/control-plane/runtime/tooling/claude-router.js +524 -0
  125. package/dist/src/control-plane/runtime/tooling/file-tools.js +182 -0
  126. package/dist/src/control-plane/runtime/tooling/gateway.js +422 -0
  127. package/dist/src/control-plane/runtime/tooling/index.js +1290 -0
  128. package/dist/src/control-plane/runtime/tooling/shell.js +205 -0
  129. package/dist/src/control-plane/runtime/types.js +1 -0
  130. package/dist/src/control-plane/setup-version.js +14 -0
  131. package/dist/src/control-plane/state-sync/index.js +1509 -0
  132. package/dist/src/control-plane/state-sync/read.js +856 -0
  133. package/dist/src/control-plane/state-sync/reconcile.js +260 -0
  134. package/dist/src/control-plane/state-sync/repo.js +302 -0
  135. package/dist/src/control-plane/state-sync/types.js +111 -0
  136. package/dist/src/control-plane/state-sync/write.js +1469 -0
  137. package/dist/src/control-plane/task-fields.js +38 -0
  138. package/dist/src/control-plane/task-source-bootstrap.js +46 -0
  139. package/dist/src/control-plane/task-source.js +30 -0
  140. package/dist/src/control-plane/tasks/legacy-task-config-source.js +130 -0
  141. package/dist/src/control-plane/tasks/plugin-task-source.js +103 -0
  142. package/dist/src/control-plane/tasks/source-aware-task-config-source.js +611 -0
  143. package/dist/src/control-plane/tasks/source-lifecycle.js +1093 -0
  144. package/dist/src/control-plane/tasks/task-record-reader.js +9 -0
  145. package/dist/src/control-plane/validators/boundary/public-apis.js +107 -0
  146. package/dist/src/control-plane/validators/integration/_shared.js +51 -0
  147. package/dist/src/control-plane/validators/integration/adm-audit-http.js +85 -0
  148. package/dist/src/control-plane/validators/integration/adm-auth-http.js +78 -0
  149. package/dist/src/control-plane/validators/integration/adm-issuer-http.js +80 -0
  150. package/dist/src/control-plane/validators/integration/adm-migration.js +78 -0
  151. package/dist/src/control-plane/validators/integration/adm-scaffold.js +78 -0
  152. package/dist/src/control-plane/validators/runtime-registration.js +64 -0
  153. package/dist/src/control-plane/validators/shared.js +683 -0
  154. package/dist/src/events.js +218 -0
  155. package/dist/src/execution.js +35 -0
  156. package/dist/src/index.js +1633 -0
  157. package/dist/src/layout.js +145 -0
  158. package/dist/src/local-server.js +202 -0
  159. package/dist/src/plugins.js +329 -0
  160. package/dist/src/remote-http.js +83 -0
  161. package/dist/src/runtime-context.js +216 -0
  162. package/dist/src/types.js +1 -0
  163. package/native/darwin-arm64/bin/rig-git +0 -0
  164. package/native/darwin-arm64/bin/rig-shell +0 -0
  165. package/native/darwin-arm64/bin/rig-tools +0 -0
  166. package/native/darwin-arm64/lib/runtime-native-darwin-arm64.dylib +0 -0
  167. package/native/darwin-arm64/lib/runtime-native.dylib +0 -0
  168. package/native/darwin-arm64/manifest.json +1 -0
  169. package/native/linux-x64/bin/rig-git +0 -0
  170. package/native/linux-x64/bin/rig-shell +0 -0
  171. package/native/linux-x64/bin/rig-tools +0 -0
  172. package/native/linux-x64/lib/runtime-native-linux-x64.so +0 -0
  173. package/native/linux-x64/lib/runtime-native.so +0 -0
  174. package/native/linux-x64/manifest.json +1 -0
  175. package/package.json +74 -0
  176. package/skills/rig-task-run.md +71 -0
@@ -0,0 +1,582 @@
1
+ // @bun
2
+ // packages/runtime/src/control-plane/authority-files.ts
3
+ import { existsSync as existsSync2, mkdirSync, readFileSync, writeFileSync, appendFileSync, copyFileSync, statSync, readdirSync, chmodSync } from "fs";
4
+ import { homedir } from "os";
5
+ import { dirname as dirname2, join, relative, resolve as resolve2 } from "path";
6
+ import { randomUUID } from "crypto";
7
+ import { parse as parseToml, stringify as stringifyToml } from "smol-toml";
8
+
9
+ // packages/runtime/src/layout.ts
10
+ import { existsSync } from "fs";
11
+ import { basename, dirname, resolve } from "path";
12
+ function resolveMonorepoRoot(projectRoot) {
13
+ const normalizedProjectRoot = resolve(projectRoot);
14
+ const explicit = process.env.MONOREPO_ROOT?.trim();
15
+ if (explicit) {
16
+ const explicitRoot = resolve(explicit);
17
+ const explicitParent = dirname(explicitRoot);
18
+ if (basename(explicitParent) === ".worktrees") {
19
+ const owner = dirname(explicitParent);
20
+ const ownerHasGit = existsSync(resolve(owner, ".git"));
21
+ const ownerHasTaskConfig = existsSync(resolve(owner, ".rig", "task-config.json"));
22
+ const ownerHasRigConfig = existsSync(resolve(owner, "rig.config.ts"));
23
+ if (ownerHasGit && (ownerHasTaskConfig || ownerHasRigConfig)) {
24
+ return owner;
25
+ }
26
+ throw new Error(`MONOREPO_ROOT points to worktree ${explicitRoot}, but the owner checkout is incomplete at ${owner}.`);
27
+ }
28
+ if (!existsSync(resolve(explicitRoot, ".git"))) {
29
+ throw new Error(`MONOREPO_ROOT points to ${explicitRoot}, but no git checkout was found there.`);
30
+ }
31
+ const hasTaskConfig = existsSync(resolve(explicitRoot, ".rig", "task-config.json"));
32
+ const hasRigConfig = existsSync(resolve(explicitRoot, "rig.config.ts"));
33
+ if (!hasTaskConfig && !hasRigConfig) {
34
+ throw new Error(`MONOREPO_ROOT points to ${explicitRoot}, but neither .rig/task-config.json nor rig.config.ts exists there.`);
35
+ }
36
+ return explicitRoot;
37
+ }
38
+ const projectParent = dirname(normalizedProjectRoot);
39
+ if (basename(projectParent) === ".worktrees") {
40
+ const worktreeOwner = dirname(projectParent);
41
+ const ownerHasGit = existsSync(resolve(worktreeOwner, ".git"));
42
+ const ownerHasTaskConfig = existsSync(resolve(worktreeOwner, ".rig", "task-config.json"));
43
+ const ownerHasRigConfig = existsSync(resolve(worktreeOwner, "rig.config.ts"));
44
+ if (ownerHasGit && (ownerHasTaskConfig || ownerHasRigConfig)) {
45
+ return worktreeOwner;
46
+ }
47
+ }
48
+ return normalizedProjectRoot;
49
+ }
50
+
51
+ // packages/runtime/src/control-plane/authority-files.ts
52
+ function readTomlFile(path, fallback) {
53
+ if (!existsSync2(path))
54
+ return fallback;
55
+ const raw = readFileSync(path, "utf8");
56
+ if (!raw.trim())
57
+ return fallback;
58
+ return parseToml(raw);
59
+ }
60
+ function writeTomlFile(path, value) {
61
+ mkdirSync(dirname2(path), { recursive: true });
62
+ writeFileSync(path, `${stringifyToml(value).trimEnd()}
63
+ `, "utf8");
64
+ }
65
+ function normalizeString(value) {
66
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
67
+ }
68
+ function normalizeStringArray(value) {
69
+ if (!Array.isArray(value))
70
+ return [];
71
+ return value.map((entry) => normalizeString(entry)).filter((entry) => entry !== null);
72
+ }
73
+ function normalizePort(value) {
74
+ const port = typeof value === "number" ? value : Number(value);
75
+ return Number.isInteger(port) && port > 0 && port <= 65535 ? port : 7890;
76
+ }
77
+ function loadRemoteEndpointsToml(projectRoot) {
78
+ const paths = resolveAuthorityPaths(projectRoot);
79
+ const parsed = readTomlFile(paths.remoteEndpointsPath, { version: 1, endpoints: {} });
80
+ return {
81
+ version: parsed.version ?? 1,
82
+ endpoints: parsed.endpoints ?? {}
83
+ };
84
+ }
85
+ function loadRemoteSecretsToml(projectRoot) {
86
+ const paths = resolveAuthorityPaths(projectRoot);
87
+ const parsed = readTomlFile(paths.remoteSecretsPath, { version: 1, secrets: {} });
88
+ return {
89
+ version: parsed.version ?? 1,
90
+ secrets: parsed.secrets ?? {}
91
+ };
92
+ }
93
+ function saveRemoteEndpointsToml(projectRoot, payload) {
94
+ const paths = resolveAuthorityPaths(projectRoot);
95
+ writeTomlFile(paths.remoteEndpointsPath, payload);
96
+ }
97
+ function saveRemoteSecretsToml(projectRoot, payload) {
98
+ const paths = resolveAuthorityPaths(projectRoot);
99
+ writeTomlFile(paths.remoteSecretsPath, payload);
100
+ try {
101
+ chmodSync(paths.remoteSecretsPath, 384);
102
+ } catch {}
103
+ }
104
+ function resolveAuthorityPaths(projectRoot) {
105
+ const normalizedRoot = resolve2(projectRoot);
106
+ const stateRoot = resolveAuthorityStateRoot(normalizedRoot);
107
+ const stateDir = resolveAuthorityStateDir(normalizedRoot);
108
+ return {
109
+ projectRoot: normalizedRoot,
110
+ harnessRoot: resolve2(normalizedRoot, "rig"),
111
+ runsDir: resolve2(stateRoot, "runs"),
112
+ remoteDir: resolve2(stateRoot, "remote"),
113
+ stateDir,
114
+ remoteEndpointsPath: resolve2(stateRoot, "remote", "endpoints.toml"),
115
+ remoteSecretsPath: resolve2(stateDir, "remote-secrets.toml")
116
+ };
117
+ }
118
+ function resolveAuthorityStateRoot(projectRoot) {
119
+ const normalizedRoot = resolve2(projectRoot);
120
+ const taskWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
121
+ if (taskWorkspace) {
122
+ return resolve2(taskWorkspace, ".rig");
123
+ }
124
+ const stateDir = process.env.RIG_STATE_DIR?.trim();
125
+ if (stateDir) {
126
+ return dirname2(resolve2(stateDir));
127
+ }
128
+ const logsDir = process.env.RIG_LOGS_DIR?.trim();
129
+ if (logsDir) {
130
+ return dirname2(resolve2(logsDir));
131
+ }
132
+ const sessionFile = process.env.RIG_SESSION_FILE?.trim();
133
+ if (sessionFile) {
134
+ return dirname2(dirname2(resolve2(sessionFile)));
135
+ }
136
+ const projectStateRoot = resolve2(normalizedRoot, ".rig");
137
+ if (existsSync2(projectStateRoot)) {
138
+ return projectStateRoot;
139
+ }
140
+ return resolve2(normalizedRoot, ".rig");
141
+ }
142
+ function resolveAuthorityStateDir(projectRoot) {
143
+ const explicit = process.env.RIG_STATE_DIR?.trim();
144
+ if (explicit) {
145
+ return resolve2(explicit);
146
+ }
147
+ return resolve2(resolveAuthorityStateRoot(projectRoot), "state");
148
+ }
149
+ function resolveAuthorityProjectStateDir(projectRoot) {
150
+ const explicit = process.env.RIG_STATE_DIR?.trim();
151
+ if (explicit) {
152
+ return resolve2(explicit);
153
+ }
154
+ return resolve2(resolve2(projectRoot), ".rig", "state");
155
+ }
156
+ function readJsonAtPath(path, fallback) {
157
+ if (!existsSync2(path)) {
158
+ return fallback;
159
+ }
160
+ try {
161
+ return JSON.parse(readFileSync(path, "utf-8"));
162
+ } catch {
163
+ return fallback;
164
+ }
165
+ }
166
+ function writeJsonAtPath(path, value) {
167
+ mkdirSync(dirname2(path), { recursive: true });
168
+ writeFileSync(path, `${JSON.stringify(value, null, 2)}
169
+ `, "utf8");
170
+ return path;
171
+ }
172
+ function readAuthorityStateJson(projectRoot, relativePath, fallback) {
173
+ return readJsonAtPath(resolve2(resolveAuthorityStateDir(projectRoot), relativePath), fallback);
174
+ }
175
+ function writeAuthorityStateJson(projectRoot, relativePath, value) {
176
+ return writeJsonAtPath(resolve2(resolveAuthorityStateDir(projectRoot), relativePath), value);
177
+ }
178
+ function readAuthorityProjectStateJson(projectRoot, relativePath, fallback) {
179
+ return readJsonAtPath(resolve2(resolveAuthorityProjectStateDir(projectRoot), relativePath), fallback);
180
+ }
181
+ function writeAuthorityProjectStateJson(projectRoot, relativePath, value) {
182
+ return writeJsonAtPath(resolve2(resolveAuthorityProjectStateDir(projectRoot), relativePath), value);
183
+ }
184
+ function resolveAuthorityArtifactsRoot(projectRoot) {
185
+ const explicit = process.env.ARTIFACTS_DIR?.trim();
186
+ if (explicit) {
187
+ return resolve2(explicit);
188
+ }
189
+ const projectArtifactsRoot = resolve2(projectRoot, "artifacts");
190
+ if (existsSync2(projectArtifactsRoot)) {
191
+ return projectArtifactsRoot;
192
+ }
193
+ const taskWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
194
+ if (taskWorkspace) {
195
+ return resolve2(taskWorkspace, "artifacts");
196
+ }
197
+ if (process.env.MONOREPO_ROOT?.trim()) {
198
+ return resolve2(resolveMonorepoRoot(projectRoot), "artifacts");
199
+ }
200
+ const normalizedRoot = resolve2(projectRoot);
201
+ const projectLooksLikeMonorepo = existsSync2(resolve2(normalizedRoot, ".git")) && existsSync2(resolve2(normalizedRoot, ".rig", "task-config.json"));
202
+ if (!projectLooksLikeMonorepo) {
203
+ return projectArtifactsRoot;
204
+ }
205
+ return resolve2(resolveMonorepoRoot(projectRoot), "artifacts");
206
+ }
207
+ function resolveAuthorityRuntimeDir(projectRoot) {
208
+ return resolve2(resolveAuthorityStateRoot(projectRoot), "runtime");
209
+ }
210
+ function uniquePaths(paths) {
211
+ const seen = new Set;
212
+ const result = [];
213
+ for (const value of paths) {
214
+ const normalized = normalizeString(value);
215
+ if (!normalized || seen.has(normalized))
216
+ continue;
217
+ seen.add(normalized);
218
+ result.push(normalized);
219
+ }
220
+ return result;
221
+ }
222
+ function listAuthorityRunRoots(projectRoot) {
223
+ const normalizedRoot = resolve2(projectRoot);
224
+ const monorepoRoot = resolveMonorepoRoot(normalizedRoot);
225
+ return uniquePaths([
226
+ resolve2(resolveAuthorityStateRoot(normalizedRoot), "runs"),
227
+ resolve2(monorepoRoot, ".rig", "runs")
228
+ ]);
229
+ }
230
+ function listAuthorityArtifactRoots(projectRoot) {
231
+ return uniquePaths([
232
+ resolveAuthorityArtifactsRoot(projectRoot)
233
+ ]);
234
+ }
235
+ function listAuthorityRuntimeAgentsRoots(projectRoot) {
236
+ return uniquePaths([
237
+ resolve2(resolveAuthorityRuntimeDir(projectRoot), "agents")
238
+ ]);
239
+ }
240
+ function listAuthorityRemoteEndpoints(projectRoot) {
241
+ const endpoints = loadRemoteEndpointsToml(projectRoot).endpoints ?? {};
242
+ const secrets = loadRemoteSecretsToml(projectRoot).secrets ?? {};
243
+ return Object.values(endpoints).map((entry) => {
244
+ const token = secrets[entry.secret_ref] ?? "";
245
+ return {
246
+ id: entry.id,
247
+ alias: entry.alias,
248
+ host: entry.host,
249
+ port: normalizePort(entry.port),
250
+ token,
251
+ autoConnect: Boolean(entry.auto_connect),
252
+ addedAt: entry.created_at,
253
+ updatedAt: entry.updated_at,
254
+ lastConnectedAt: normalizeString(entry.last_connected_at) ?? null,
255
+ labels: normalizeStringArray(entry.labels),
256
+ capabilities: normalizeStringArray(entry.capabilities),
257
+ transport: normalizeString(entry.transport) ?? "websocket",
258
+ secretRef: entry.secret_ref
259
+ };
260
+ }).sort((left, right) => left.alias.localeCompare(right.alias));
261
+ }
262
+ function nextRemoteEndpointRecord(input) {
263
+ const timestamp = new Date().toISOString();
264
+ const secretRef = input.existing?.secret_ref ?? randomUUID();
265
+ return {
266
+ record: {
267
+ id: input.endpointId ?? input.existing?.id ?? randomUUID(),
268
+ alias: input.alias,
269
+ host: input.host,
270
+ port: normalizePort(input.port),
271
+ transport: normalizeString(input.transport) ?? normalizeString(input.existing?.transport) ?? "websocket",
272
+ auto_connect: input.autoConnect ?? input.existing?.auto_connect ?? false,
273
+ labels: input.labels ?? normalizeStringArray(input.existing?.labels),
274
+ capabilities: input.capabilities ?? normalizeStringArray(input.existing?.capabilities),
275
+ secret_ref: secretRef,
276
+ created_at: input.existing?.created_at ?? timestamp,
277
+ updated_at: timestamp,
278
+ last_connected_at: input.existing?.last_connected_at ?? null
279
+ },
280
+ secretRef
281
+ };
282
+ }
283
+ function upsertAuthorityRemoteEndpoint(projectRoot, input) {
284
+ const endpointsToml = loadRemoteEndpointsToml(projectRoot);
285
+ const secretsToml = loadRemoteSecretsToml(projectRoot);
286
+ const existing = Object.values(endpointsToml.endpoints ?? {}).find((entry) => entry.alias === input.alias) ?? null;
287
+ const { record, secretRef } = nextRemoteEndpointRecord({
288
+ endpointId: input.endpointId,
289
+ existing,
290
+ alias: input.alias,
291
+ host: input.host,
292
+ port: input.port,
293
+ token: input.token,
294
+ autoConnect: input.autoConnect,
295
+ transport: input.transport,
296
+ labels: input.labels,
297
+ capabilities: input.capabilities
298
+ });
299
+ endpointsToml.endpoints = {
300
+ ...endpointsToml.endpoints ?? {},
301
+ [record.id]: record
302
+ };
303
+ secretsToml.secrets = {
304
+ ...secretsToml.secrets ?? {},
305
+ [secretRef]: input.token
306
+ };
307
+ saveRemoteEndpointsToml(projectRoot, endpointsToml);
308
+ saveRemoteSecretsToml(projectRoot, secretsToml);
309
+ return listAuthorityRemoteEndpoints(projectRoot).find((entry) => entry.id === record.id);
310
+ }
311
+ function updateAuthorityRemoteEndpoint(projectRoot, input) {
312
+ const endpointsToml = loadRemoteEndpointsToml(projectRoot);
313
+ const secretsToml = loadRemoteSecretsToml(projectRoot);
314
+ const current = Object.values(endpointsToml.endpoints ?? {}).find((entry) => input.endpointId && entry.id === input.endpointId || input.alias && entry.alias === input.alias);
315
+ if (!current)
316
+ return null;
317
+ const record = {
318
+ ...current,
319
+ alias: normalizeString(input.alias) ?? current.alias,
320
+ host: normalizeString(input.host) ?? current.host,
321
+ port: input.port !== undefined ? normalizePort(input.port) : current.port,
322
+ auto_connect: input.autoConnect ?? current.auto_connect,
323
+ transport: normalizeString(input.transport) ?? current.transport,
324
+ labels: input.labels ?? normalizeStringArray(current.labels),
325
+ capabilities: input.capabilities ?? normalizeStringArray(current.capabilities),
326
+ updated_at: new Date().toISOString()
327
+ };
328
+ endpointsToml.endpoints = {
329
+ ...endpointsToml.endpoints ?? {},
330
+ [record.id]: record
331
+ };
332
+ if (input.token !== undefined) {
333
+ secretsToml.secrets = {
334
+ ...secretsToml.secrets ?? {},
335
+ [record.secret_ref]: input.token
336
+ };
337
+ }
338
+ saveRemoteEndpointsToml(projectRoot, endpointsToml);
339
+ saveRemoteSecretsToml(projectRoot, secretsToml);
340
+ return listAuthorityRemoteEndpoints(projectRoot).find((entry) => entry.id === record.id) ?? null;
341
+ }
342
+ function removeAuthorityRemoteEndpoint(projectRoot, endpointIdOrAlias) {
343
+ const endpointsToml = loadRemoteEndpointsToml(projectRoot);
344
+ const secretsToml = loadRemoteSecretsToml(projectRoot);
345
+ const entry = Object.values(endpointsToml.endpoints ?? {}).find((candidate) => candidate.id === endpointIdOrAlias || candidate.alias === endpointIdOrAlias);
346
+ if (!entry)
347
+ return false;
348
+ const nextEndpoints = { ...endpointsToml.endpoints ?? {} };
349
+ delete nextEndpoints[entry.id];
350
+ const nextSecrets = { ...secretsToml.secrets ?? {} };
351
+ delete nextSecrets[entry.secret_ref];
352
+ saveRemoteEndpointsToml(projectRoot, { version: endpointsToml.version ?? 1, endpoints: nextEndpoints });
353
+ saveRemoteSecretsToml(projectRoot, { version: secretsToml.version ?? 1, secrets: nextSecrets });
354
+ return true;
355
+ }
356
+ function markAuthorityRemoteEndpointConnected(projectRoot, endpointId, connectedAt = new Date().toISOString()) {
357
+ const endpointsToml = loadRemoteEndpointsToml(projectRoot);
358
+ const entry = endpointsToml.endpoints?.[endpointId];
359
+ if (!entry)
360
+ return;
361
+ endpointsToml.endpoints = {
362
+ ...endpointsToml.endpoints ?? {},
363
+ [endpointId]: {
364
+ ...entry,
365
+ last_connected_at: connectedAt,
366
+ updated_at: connectedAt
367
+ }
368
+ };
369
+ saveRemoteEndpointsToml(projectRoot, endpointsToml);
370
+ }
371
+ function importLegacyRemoteEndpoints(projectRoot, legacyPath = join(homedir(), ".config", "rig", "remotes.toml")) {
372
+ if (!existsSync2(legacyPath)) {
373
+ return { imported: 0, skipped: 0, sourcePath: legacyPath };
374
+ }
375
+ const parsed = readTomlFile(legacyPath, { version: 1, remotes: {} });
376
+ let imported = 0;
377
+ let skipped = 0;
378
+ for (const [alias, entry] of Object.entries(parsed.remotes ?? {})) {
379
+ const host = normalizeString(entry.host);
380
+ const token = normalizeString(entry.token);
381
+ if (!host || !token) {
382
+ skipped += 1;
383
+ continue;
384
+ }
385
+ upsertAuthorityRemoteEndpoint(projectRoot, {
386
+ alias,
387
+ host,
388
+ port: normalizePort(entry.port),
389
+ token
390
+ });
391
+ imported += 1;
392
+ }
393
+ return { imported, skipped, sourcePath: legacyPath };
394
+ }
395
+ function doctorAuthorityRemoteEndpoints(projectRoot) {
396
+ const paths = resolveAuthorityPaths(projectRoot);
397
+ const endpoints = loadRemoteEndpointsToml(projectRoot).endpoints ?? {};
398
+ const secrets = loadRemoteSecretsToml(projectRoot).secrets ?? {};
399
+ const missingSecrets = Object.values(endpoints).filter((entry) => !normalizeString(secrets[entry.secret_ref])).map((entry) => entry.alias);
400
+ const warnings = [];
401
+ if (!existsSync2(paths.remoteEndpointsPath)) {
402
+ warnings.push("Remote endpoint manifest is missing.");
403
+ }
404
+ if (!existsSync2(paths.remoteSecretsPath)) {
405
+ warnings.push("Remote secret store is missing.");
406
+ }
407
+ return {
408
+ manifestPath: paths.remoteEndpointsPath,
409
+ secretsPath: paths.remoteSecretsPath,
410
+ endpointCount: Object.keys(endpoints).length,
411
+ missingSecrets,
412
+ warnings
413
+ };
414
+ }
415
+ function resolveAuthorityRunDir(projectRoot, runId) {
416
+ const roots = listAuthorityRunRoots(projectRoot);
417
+ for (const runsDir of roots) {
418
+ const candidate = resolve2(runsDir, runId);
419
+ if (existsSync2(candidate)) {
420
+ return candidate;
421
+ }
422
+ }
423
+ return resolve2(roots[0] ?? resolveAuthorityPaths(projectRoot).runsDir, runId);
424
+ }
425
+ function appendJsonlRecord(path, value) {
426
+ mkdirSync(dirname2(path), { recursive: true });
427
+ appendFileSync(path, `${JSON.stringify(value)}
428
+ `, "utf8");
429
+ }
430
+ function writeJsonFile(path, value) {
431
+ mkdirSync(dirname2(path), { recursive: true });
432
+ writeFileSync(path, `${JSON.stringify(value, null, 2)}
433
+ `, "utf8");
434
+ }
435
+ function readJsonFile(path, fallback) {
436
+ if (!existsSync2(path))
437
+ return fallback;
438
+ try {
439
+ return JSON.parse(readFileSync(path, "utf8"));
440
+ } catch {
441
+ return fallback;
442
+ }
443
+ }
444
+ function listAuthorityRuns(projectRoot) {
445
+ const runs = new Map;
446
+ for (const runsDir of listAuthorityRunRoots(projectRoot)) {
447
+ if (!existsSync2(runsDir))
448
+ continue;
449
+ for (const runId of readDirRuns(runsDir)) {
450
+ if (runs.has(runId))
451
+ continue;
452
+ const entry = readJsonFile(resolve2(runsDir, runId, "run.json"), null);
453
+ if (entry && runBelongsToProject(projectRoot, entry, runsDir)) {
454
+ runs.set(runId, entry);
455
+ }
456
+ }
457
+ }
458
+ return [...runs.values()].sort((left, right) => right.updatedAt.localeCompare(left.updatedAt));
459
+ }
460
+ function runBelongsToProject(projectRoot, run, runsDir) {
461
+ const normalizedRoot = resolve2(projectRoot);
462
+ const record = run;
463
+ const recordedProjectRoot = normalizeString(record.projectRoot);
464
+ if (recordedProjectRoot) {
465
+ return resolve2(recordedProjectRoot) === normalizedRoot;
466
+ }
467
+ const projectLocalRunsDir = resolve2(normalizedRoot, ".rig", "runs");
468
+ if (isPathWithin(projectLocalRunsDir, resolve2(runsDir))) {
469
+ return true;
470
+ }
471
+ const pathFields = [
472
+ run.worktreePath,
473
+ run.artifactRoot,
474
+ run.logRoot,
475
+ run.sessionPath,
476
+ run.sessionLogPath
477
+ ].filter((value) => typeof value === "string" && value.trim().length > 0);
478
+ if (pathFields.length === 0) {
479
+ return true;
480
+ }
481
+ return pathFields.some((value) => isPathWithin(normalizedRoot, resolve2(value)));
482
+ }
483
+ function isPathWithin(root, candidate) {
484
+ const relativePath = relative(root, candidate);
485
+ return relativePath === "" || !relativePath.startsWith("..") && !relativePath.startsWith(`/`) && !relativePath.startsWith(`\\`);
486
+ }
487
+ function readDirRuns(runsDir) {
488
+ try {
489
+ return readdirSync(runsDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
490
+ } catch {
491
+ return [];
492
+ }
493
+ }
494
+ function readAuthorityRun(projectRoot, runId) {
495
+ for (const runsDir of listAuthorityRunRoots(projectRoot)) {
496
+ const entry = readJsonFile(resolve2(runsDir, runId, "run.json"), null);
497
+ if (entry) {
498
+ return entry;
499
+ }
500
+ }
501
+ return null;
502
+ }
503
+ function resolveTaskArtifactDirs(projectRoot, taskId) {
504
+ const candidates = [];
505
+ const seen = new Set;
506
+ const add = (value) => {
507
+ const normalized = normalizeString(value);
508
+ if (!normalized || seen.has(normalized))
509
+ return;
510
+ seen.add(normalized);
511
+ candidates.push(normalized);
512
+ };
513
+ for (const run of listAuthorityRuns(projectRoot)) {
514
+ if (run.taskId !== taskId)
515
+ continue;
516
+ add(run.artifactRoot);
517
+ if (run.worktreePath) {
518
+ add(resolve2(run.worktreePath, "artifacts", taskId));
519
+ }
520
+ }
521
+ for (const artifactsRoot of listAuthorityArtifactRoots(projectRoot)) {
522
+ add(resolve2(artifactsRoot, taskId));
523
+ }
524
+ return candidates;
525
+ }
526
+ function readJsonlFile(path) {
527
+ if (!existsSync2(path))
528
+ return [];
529
+ return readFileSync(path, "utf8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).flatMap((line) => {
530
+ try {
531
+ return [JSON.parse(line)];
532
+ } catch {
533
+ return [];
534
+ }
535
+ });
536
+ }
537
+ function copyFileIfPresent(sourcePath, targetPath) {
538
+ if (!existsSync2(sourcePath))
539
+ return false;
540
+ mkdirSync(dirname2(targetPath), { recursive: true });
541
+ copyFileSync(sourcePath, targetPath);
542
+ return true;
543
+ }
544
+ function fileSizeIfPresent(path) {
545
+ try {
546
+ return statSync(path).size;
547
+ } catch {
548
+ return null;
549
+ }
550
+ }
551
+ export {
552
+ writeJsonFile,
553
+ writeAuthorityStateJson,
554
+ writeAuthorityProjectStateJson,
555
+ upsertAuthorityRemoteEndpoint,
556
+ updateAuthorityRemoteEndpoint,
557
+ resolveTaskArtifactDirs,
558
+ resolveAuthorityStateRoot,
559
+ resolveAuthorityStateDir,
560
+ resolveAuthorityRuntimeDir,
561
+ resolveAuthorityRunDir,
562
+ resolveAuthorityProjectStateDir,
563
+ resolveAuthorityPaths,
564
+ resolveAuthorityArtifactsRoot,
565
+ removeAuthorityRemoteEndpoint,
566
+ readJsonlFile,
567
+ readJsonFile,
568
+ readAuthorityStateJson,
569
+ readAuthorityRun,
570
+ readAuthorityProjectStateJson,
571
+ markAuthorityRemoteEndpointConnected,
572
+ listAuthorityRuntimeAgentsRoots,
573
+ listAuthorityRuns,
574
+ listAuthorityRunRoots,
575
+ listAuthorityRemoteEndpoints,
576
+ listAuthorityArtifactRoots,
577
+ importLegacyRemoteEndpoints,
578
+ fileSizeIfPresent,
579
+ doctorAuthorityRemoteEndpoints,
580
+ copyFileIfPresent,
581
+ appendJsonlRecord
582
+ };