@h-rig/core 0.0.6-alpha.176 → 0.0.6-alpha.177
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/baked-secrets.d.ts +3 -6
- package/dist/src/baked-secrets.js +9 -67
- package/dist/src/capability-loaders.js +132 -20
- package/dist/src/declarative-config.js +5 -2
- package/dist/src/harness-paths.d.ts +0 -9
- package/dist/src/harness-paths.js +1 -16
- package/dist/src/hook-materializer.d.ts +9 -60
- package/dist/src/hook-materializer.js +3 -132
- package/dist/src/hook-protocol.js +1 -31
- package/dist/src/hook-runner.d.ts +3 -3
- package/dist/src/hook-runner.js +132 -20
- package/dist/src/hook-runtime.js +1 -31
- package/dist/src/json-files.js +0 -1
- package/dist/src/kernel-entrypoint.js +132 -20
- package/dist/src/layout.d.ts +2 -2
- package/dist/src/layout.js +2 -8
- package/dist/src/load-config.js +132 -20
- package/dist/src/placement.d.ts +16 -8
- package/dist/src/placement.js +18 -961
- package/dist/src/plugin-host-context.d.ts +2 -3
- package/dist/src/plugin-host-context.js +170 -294
- package/dist/src/project-plugins.js +132 -20
- package/dist/src/remote-config.d.ts +38 -96
- package/dist/src/remote-config.js +35 -524
- package/dist/src/root-resolver.js +0 -1
- package/dist/src/run-provisioning.d.ts +17 -38
- package/dist/src/run-provisioning.js +19 -112
- package/dist/src/runtime-events.js +0 -4
- package/dist/src/runtime-overlay.js +0 -2
- package/dist/src/server-paths.d.ts +0 -4
- package/dist/src/server-paths.js +36 -125
- package/package.json +3 -7
- package/dist/src/profile-ops.d.ts +0 -9
- package/dist/src/profile-ops.js +0 -252
|
@@ -1,89 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
// packages/core/src/remote-config.ts
|
|
3
|
-
import { randomUUID } from "crypto";
|
|
4
|
-
import { chmodSync, existsSync as existsSync2, mkdirSync, mkdtempSync, readFileSync, writeFileSync } from "fs";
|
|
5
|
-
import { homedir, tmpdir } from "os";
|
|
6
|
-
import { dirname as dirname2, join, resolve as resolve2 } from "path";
|
|
7
|
-
import { parse as parseToml, stringify as stringifyToml } from "smol-toml";
|
|
8
|
-
|
|
9
|
-
// packages/core/src/authority-paths.ts
|
|
10
|
-
import { existsSync } from "fs";
|
|
11
|
-
import { dirname, resolve } from "path";
|
|
12
|
-
function normalizeOptionalString(value) {
|
|
13
|
-
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
14
|
-
}
|
|
15
|
-
function resolveAuthorityPaths(projectRoot) {
|
|
16
|
-
const normalizedRoot = resolve(projectRoot);
|
|
17
|
-
const stateRoot = resolveAuthorityStateRoot(normalizedRoot);
|
|
18
|
-
const stateDir = resolveAuthorityStateDir(normalizedRoot);
|
|
19
|
-
return {
|
|
20
|
-
projectRoot: normalizedRoot,
|
|
21
|
-
harnessRoot: resolve(normalizedRoot, "rig"),
|
|
22
|
-
runsDir: resolve(stateRoot, "runs"),
|
|
23
|
-
remoteDir: resolve(stateRoot, "remote"),
|
|
24
|
-
stateDir,
|
|
25
|
-
remoteEndpointsPath: resolve(stateRoot, "remote", "endpoints.toml"),
|
|
26
|
-
remoteSecretsPath: resolve(stateDir, "remote-secrets.toml")
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
function resolveAuthorityStateRoot(projectRoot) {
|
|
30
|
-
const normalizedRoot = resolve(projectRoot);
|
|
31
|
-
const taskWorkspace = normalizeOptionalString(process.env.RIG_TASK_WORKSPACE);
|
|
32
|
-
if (taskWorkspace) {
|
|
33
|
-
return resolve(taskWorkspace, ".rig");
|
|
34
|
-
}
|
|
35
|
-
const stateDir = normalizeOptionalString(process.env.RIG_STATE_DIR);
|
|
36
|
-
if (stateDir) {
|
|
37
|
-
return dirname(resolve(stateDir));
|
|
38
|
-
}
|
|
39
|
-
const logsDir = normalizeOptionalString(process.env.RIG_LOGS_DIR);
|
|
40
|
-
if (logsDir) {
|
|
41
|
-
return dirname(resolve(logsDir));
|
|
42
|
-
}
|
|
43
|
-
const sessionFile = normalizeOptionalString(process.env.RIG_SESSION_FILE);
|
|
44
|
-
if (sessionFile) {
|
|
45
|
-
return dirname(dirname(resolve(sessionFile)));
|
|
46
|
-
}
|
|
47
|
-
const projectStateRoot = resolve(normalizedRoot, ".rig");
|
|
48
|
-
if (existsSync(projectStateRoot)) {
|
|
49
|
-
return projectStateRoot;
|
|
50
|
-
}
|
|
51
|
-
return resolve(normalizedRoot, ".rig");
|
|
52
|
-
}
|
|
53
|
-
function resolveAuthorityStateDir(projectRoot) {
|
|
54
|
-
const explicit = normalizeOptionalString(process.env.RIG_STATE_DIR);
|
|
55
|
-
if (explicit) {
|
|
56
|
-
return resolve(explicit);
|
|
57
|
-
}
|
|
58
|
-
return resolve(resolveAuthorityStateRoot(projectRoot), "state");
|
|
59
|
-
}
|
|
60
|
-
|
|
61
2
|
// packages/core/src/remote-config.ts
|
|
62
3
|
var DEFAULT_REMOTE_PORT = 7890;
|
|
63
|
-
var
|
|
64
|
-
function backboneDefaultsState() {
|
|
65
|
-
const global = globalThis;
|
|
66
|
-
return global[BACKBONE_DEFAULTS_KEY] ??= {};
|
|
67
|
-
}
|
|
68
|
-
function registerBackboneDefaults(defaults) {
|
|
69
|
-
const relayUrl = normalizeString(defaults.relayUrl);
|
|
70
|
-
const registryBaseUrl = normalizeString(defaults.registryBaseUrl);
|
|
71
|
-
const sshTarget = normalizeString(defaults.sshTarget);
|
|
72
|
-
const state = backboneDefaultsState();
|
|
73
|
-
if (relayUrl)
|
|
74
|
-
state.relayUrl = relayUrl;
|
|
75
|
-
if (registryBaseUrl)
|
|
76
|
-
state.registryBaseUrl = registryBaseUrl;
|
|
77
|
-
if (sshTarget)
|
|
78
|
-
state.sshTarget = sshTarget;
|
|
79
|
-
}
|
|
80
|
-
function resolveRelayUrl(env = process.env) {
|
|
81
|
-
return normalizeString(env.RIG_COLLAB_RELAY) || normalizeString(env.RIG_SPIKE_RELAY) || backboneDefaultsState().relayUrl || "";
|
|
82
|
-
}
|
|
83
|
-
function resolveSshTarget(env = process.env) {
|
|
84
|
-
return normalizeString(env.RIG_SSH_TARGET) || backboneDefaultsState().sshTarget || "";
|
|
85
|
-
}
|
|
86
|
-
var REMOTES_CONFIG_PATH = join(homedir(), ".config", "rig", "remotes.toml");
|
|
4
|
+
var REMOTES_CONFIG_PATH = "";
|
|
87
5
|
|
|
88
6
|
class RemoteCliError extends Error {
|
|
89
7
|
code;
|
|
@@ -97,457 +15,53 @@ class RemoteCliError extends Error {
|
|
|
97
15
|
this.details = details;
|
|
98
16
|
}
|
|
99
17
|
}
|
|
100
|
-
function
|
|
101
|
-
|
|
102
|
-
return { version: 1, remotes: {} };
|
|
103
|
-
}
|
|
104
|
-
try {
|
|
105
|
-
const content = readFileSync(configPath, "utf-8");
|
|
106
|
-
if (!content.trim()) {
|
|
107
|
-
return { version: 1, remotes: {} };
|
|
108
|
-
}
|
|
109
|
-
const parsed = parseToml(content);
|
|
110
|
-
return {
|
|
111
|
-
version: parsed.version ?? 1,
|
|
112
|
-
remotes: parsed.remotes ?? {}
|
|
113
|
-
};
|
|
114
|
-
} catch (error) {
|
|
115
|
-
throw new RemoteCliError("RIG_REMOTE_CONFIG_PARSE_ERROR", `Failed to parse remotes config at ${configPath}: ${error instanceof Error ? error.message : String(error)}`, 2, { configPath });
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
function saveRemotesConfig(config, configPath = REMOTES_CONFIG_PATH) {
|
|
119
|
-
mkdirSync(dirname2(configPath), { recursive: true });
|
|
120
|
-
writeFileSync(configPath, `${stringifyToml(config).trimEnd()}
|
|
121
|
-
`, "utf-8");
|
|
122
|
-
try {
|
|
123
|
-
chmodSync(configPath, 384);
|
|
124
|
-
} catch {}
|
|
18
|
+
function remoteConfigOwnerRequired() {
|
|
19
|
+
throw new Error("This remote config compatibility API is deprecated. Resolve transport-owned remote config through the TRANSPORT_CONFIG capability.");
|
|
125
20
|
}
|
|
126
|
-
function
|
|
127
|
-
|
|
128
|
-
return fallback;
|
|
129
|
-
const raw = readFileSync(path, "utf8");
|
|
130
|
-
if (!raw.trim())
|
|
131
|
-
return fallback;
|
|
132
|
-
return parseToml(raw);
|
|
21
|
+
function registerBackboneDefaults(_defaults) {
|
|
22
|
+
remoteConfigOwnerRequired();
|
|
133
23
|
}
|
|
134
|
-
function
|
|
135
|
-
|
|
136
|
-
writeFileSync(path, `${stringifyToml(value).trimEnd()}
|
|
137
|
-
`, "utf8");
|
|
24
|
+
function resolveRelayUrl(_env = process.env) {
|
|
25
|
+
return remoteConfigOwnerRequired();
|
|
138
26
|
}
|
|
139
|
-
function
|
|
140
|
-
|
|
141
|
-
return [];
|
|
142
|
-
return value.map((entry) => normalizeString(entry)).filter((entry) => entry !== "");
|
|
27
|
+
function resolveSshTarget(_env = process.env) {
|
|
28
|
+
return remoteConfigOwnerRequired();
|
|
143
29
|
}
|
|
144
|
-
function
|
|
145
|
-
|
|
146
|
-
return Number.isInteger(port) && port > 0 && port <= 65535 ? port : DEFAULT_REMOTE_PORT;
|
|
30
|
+
function loadRemotesConfig(_configPath) {
|
|
31
|
+
return remoteConfigOwnerRequired();
|
|
147
32
|
}
|
|
148
|
-
function
|
|
149
|
-
|
|
150
|
-
if (!trimmed)
|
|
151
|
-
return trimmed;
|
|
152
|
-
return /\/registry$/.test(trimmed) ? trimmed : `${trimmed}/registry`;
|
|
33
|
+
function listManagedRemoteEndpoints(_configPath, _projectRoot) {
|
|
34
|
+
return remoteConfigOwnerRequired();
|
|
153
35
|
}
|
|
154
|
-
function
|
|
155
|
-
|
|
156
|
-
const parsed = readTomlFile(paths.remoteEndpointsPath, { version: 1, endpoints: {} });
|
|
157
|
-
return {
|
|
158
|
-
version: parsed.version ?? 1,
|
|
159
|
-
endpoints: parsed.endpoints ?? {}
|
|
160
|
-
};
|
|
36
|
+
function resolveManagedRemoteEndpoint(_alias, _configPath, _projectRoot) {
|
|
37
|
+
return remoteConfigOwnerRequired();
|
|
161
38
|
}
|
|
162
|
-
function
|
|
163
|
-
|
|
164
|
-
const parsed = readTomlFile(paths.remoteSecretsPath, { version: 1, secrets: {} });
|
|
165
|
-
return {
|
|
166
|
-
version: parsed.version ?? 1,
|
|
167
|
-
secrets: parsed.secrets ?? {}
|
|
168
|
-
};
|
|
39
|
+
function upsertManagedRemoteEndpoint(_input, _configPath, _projectRoot) {
|
|
40
|
+
return remoteConfigOwnerRequired();
|
|
169
41
|
}
|
|
170
|
-
function
|
|
171
|
-
|
|
172
|
-
if (!existsSync2(path))
|
|
173
|
-
return {};
|
|
174
|
-
const raw = readFileSync(path, "utf8");
|
|
175
|
-
if (!raw.trim())
|
|
176
|
-
return {};
|
|
177
|
-
const parsed = JSON.parse(raw);
|
|
178
|
-
return parsed && typeof parsed === "object" ? parsed : {};
|
|
179
|
-
} catch {
|
|
180
|
-
return {};
|
|
181
|
-
}
|
|
42
|
+
function updateAuthorityRemoteEndpoint(_projectRoot, _input) {
|
|
43
|
+
return remoteConfigOwnerRequired();
|
|
182
44
|
}
|
|
183
|
-
function
|
|
184
|
-
return
|
|
45
|
+
function removeManagedRemoteEndpoint(_alias, _configPath, _projectRoot) {
|
|
46
|
+
return remoteConfigOwnerRequired();
|
|
185
47
|
}
|
|
186
|
-
function
|
|
187
|
-
|
|
188
|
-
if (fromEnv)
|
|
189
|
-
return fromEnv;
|
|
190
|
-
const stateDir = resolveAuthorityPaths(projectRoot).stateDir;
|
|
191
|
-
const auth = readJsonRecordFile(resolve2(stateDir, "github-auth.json"));
|
|
192
|
-
const namespaceKey = coerceString(auth.userNamespaceKey);
|
|
193
|
-
if (namespaceKey)
|
|
194
|
-
return namespaceKey;
|
|
195
|
-
const userId = coerceString(auth.userId);
|
|
196
|
-
return userId ? `gh:${userId}` : undefined;
|
|
48
|
+
function resolveSelectedRemote(_projectRoot, _env = process.env) {
|
|
49
|
+
return remoteConfigOwnerRequired();
|
|
197
50
|
}
|
|
198
|
-
function
|
|
199
|
-
return
|
|
51
|
+
function resolveDispatchTransportPlacement(_projectRoot, _env = process.env) {
|
|
52
|
+
return remoteConfigOwnerRequired();
|
|
200
53
|
}
|
|
201
|
-
function
|
|
202
|
-
|
|
203
|
-
return { kind: "local", alias: "local", sshTarget: null, selected: null };
|
|
204
|
-
}
|
|
205
|
-
const stateDir = resolveAuthorityPaths(projectRoot).stateDir;
|
|
206
|
-
const conn = readJsonRecordFile(resolve2(stateDir, "connection.json"));
|
|
207
|
-
const selectedAlias = normalizeString(env.RIG_REMOTE_ALIAS) || coerceString(conn.selected);
|
|
208
|
-
if (selectedAlias === "local") {
|
|
209
|
-
return { kind: "local", alias: "local", sshTarget: null, selected: null };
|
|
210
|
-
}
|
|
211
|
-
const selected = resolveSelectedRemote(projectRoot, env);
|
|
212
|
-
const sshTarget = selected?.sshTarget ?? resolveSshTarget(env);
|
|
213
|
-
if (!sshTarget) {
|
|
214
|
-
return { kind: "local", alias: "local", sshTarget: null, selected: null };
|
|
215
|
-
}
|
|
216
|
-
return { kind: "remote", alias: selected?.alias ?? sshTarget, sshTarget, selected };
|
|
54
|
+
function resolveRegistryBaseUrl(_projectRoot, _env = process.env) {
|
|
55
|
+
return remoteConfigOwnerRequired();
|
|
217
56
|
}
|
|
218
|
-
function
|
|
219
|
-
|
|
220
|
-
const conn = readJsonRecordFile(resolve2(stateDir, "connection.json"));
|
|
221
|
-
const selected = normalizeString(env.RIG_REMOTE_ALIAS) || coerceString(conn.selected);
|
|
222
|
-
if (!selected || selected === "local")
|
|
223
|
-
return null;
|
|
224
|
-
const endpoints = Object.values(loadRemoteEndpointsToml(projectRoot).endpoints ?? {});
|
|
225
|
-
const match = endpoints.find((entry) => normalizeString(entry.alias) === selected);
|
|
226
|
-
if (!match) {
|
|
227
|
-
if (selected === "remote") {
|
|
228
|
-
const sshTarget = resolveSshTarget(env);
|
|
229
|
-
if (!sshTarget)
|
|
230
|
-
return null;
|
|
231
|
-
return {
|
|
232
|
-
alias: "remote",
|
|
233
|
-
host: sshTarget,
|
|
234
|
-
port: 22,
|
|
235
|
-
sshTarget,
|
|
236
|
-
checkout: coerceString(conn.serverProjectRoot) || null,
|
|
237
|
-
registryBaseUrl: null,
|
|
238
|
-
secretRef: null
|
|
239
|
-
};
|
|
240
|
-
}
|
|
241
|
-
return null;
|
|
242
|
-
}
|
|
243
|
-
const host = normalizeString(match.host) || selected;
|
|
244
|
-
const explicitRegistryUrl = normalizeString(env.RIG_REGISTRY_URL) || normalizeString(env.REGISTRY_URL);
|
|
245
|
-
const registryBaseUrl = explicitRegistryUrl ? normalizeRegistryBaseUrl(explicitRegistryUrl) : null;
|
|
246
|
-
return {
|
|
247
|
-
alias: selected,
|
|
248
|
-
host,
|
|
249
|
-
port: normalizePort(match.port),
|
|
250
|
-
sshTarget: host || normalizeString(match.alias) || coerceString(conn.serverProjectRootAlias),
|
|
251
|
-
checkout: coerceString(conn.serverProjectRoot) || null,
|
|
252
|
-
registryBaseUrl,
|
|
253
|
-
secretRef: normalizeString(match.secret_ref) || null
|
|
254
|
-
};
|
|
57
|
+
function resolveOwnerNamespaceKey(_projectRoot, _env = process.env) {
|
|
58
|
+
return remoteConfigOwnerRequired();
|
|
255
59
|
}
|
|
256
|
-
function
|
|
257
|
-
return
|
|
60
|
+
function resolveRigOmpConfigOverlayPath(_projectRoot = process.cwd()) {
|
|
61
|
+
return remoteConfigOwnerRequired();
|
|
258
62
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
if (rigOmpConfigOverlayPath && existsSync2(rigOmpConfigOverlayPath))
|
|
262
|
-
return rigOmpConfigOverlayPath;
|
|
263
|
-
const overlay = [
|
|
264
|
-
`collab.relayUrl: ${resolveRelayUrl()}`,
|
|
265
|
-
`registry.url: ${resolveRegistryBaseUrl(projectRoot)}`,
|
|
266
|
-
"# Cockpit owns the screen: skip OMP's welcome/startup so the drone board renders cleanly.",
|
|
267
|
-
"startup.quiet: true",
|
|
268
|
-
""
|
|
269
|
-
].join(`
|
|
270
|
-
`);
|
|
271
|
-
const base = tmpdir();
|
|
272
|
-
mkdirSync(base, { recursive: true });
|
|
273
|
-
const dir = mkdtempSync(join(base, "rig-config-"));
|
|
274
|
-
const file = join(dir, "rig-default-config.yml");
|
|
275
|
-
writeFileSync(file, overlay);
|
|
276
|
-
rigOmpConfigOverlayPath = file;
|
|
277
|
-
return file;
|
|
278
|
-
}
|
|
279
|
-
function saveRemoteEndpointsToml(projectRoot, payload) {
|
|
280
|
-
writeTomlFile(resolveAuthorityPaths(projectRoot).remoteEndpointsPath, payload);
|
|
281
|
-
}
|
|
282
|
-
function saveRemoteSecretsToml(projectRoot, payload) {
|
|
283
|
-
const paths = resolveAuthorityPaths(projectRoot);
|
|
284
|
-
writeTomlFile(paths.remoteSecretsPath, payload);
|
|
285
|
-
try {
|
|
286
|
-
chmodSync(paths.remoteSecretsPath, 384);
|
|
287
|
-
} catch {}
|
|
288
|
-
}
|
|
289
|
-
function listAuthorityRemoteEndpoints(projectRoot) {
|
|
290
|
-
const endpoints = loadRemoteEndpointsToml(projectRoot).endpoints ?? {};
|
|
291
|
-
const secrets = loadRemoteSecretsToml(projectRoot).secrets ?? {};
|
|
292
|
-
return Object.values(endpoints).map((entry) => {
|
|
293
|
-
const token = secrets[entry.secret_ref] ?? "";
|
|
294
|
-
return {
|
|
295
|
-
id: entry.id,
|
|
296
|
-
alias: entry.alias,
|
|
297
|
-
host: entry.host,
|
|
298
|
-
port: normalizePort(entry.port),
|
|
299
|
-
token,
|
|
300
|
-
autoConnect: Boolean(entry.auto_connect),
|
|
301
|
-
addedAt: entry.created_at,
|
|
302
|
-
updatedAt: entry.updated_at,
|
|
303
|
-
lastConnectedAt: normalizeString(entry.last_connected_at) || null,
|
|
304
|
-
labels: normalizeStringArray(entry.labels),
|
|
305
|
-
capabilities: normalizeStringArray(entry.capabilities),
|
|
306
|
-
transport: normalizeString(entry.transport) || "websocket",
|
|
307
|
-
secretRef: entry.secret_ref
|
|
308
|
-
};
|
|
309
|
-
}).sort((left, right) => left.alias.localeCompare(right.alias));
|
|
310
|
-
}
|
|
311
|
-
function nextRemoteEndpointRecord(input) {
|
|
312
|
-
const timestamp = new Date().toISOString();
|
|
313
|
-
const secretRef = input.existing?.secret_ref ?? randomUUID();
|
|
314
|
-
return {
|
|
315
|
-
record: {
|
|
316
|
-
id: input.endpointId ?? input.existing?.id ?? randomUUID(),
|
|
317
|
-
alias: input.alias,
|
|
318
|
-
host: input.host,
|
|
319
|
-
port: normalizePort(input.port),
|
|
320
|
-
transport: normalizeString(input.transport) || normalizeString(input.existing?.transport) || "websocket",
|
|
321
|
-
auto_connect: input.autoConnect ?? input.existing?.auto_connect ?? false,
|
|
322
|
-
labels: input.labels ?? normalizeStringArray(input.existing?.labels),
|
|
323
|
-
capabilities: input.capabilities ?? normalizeStringArray(input.existing?.capabilities),
|
|
324
|
-
secret_ref: secretRef,
|
|
325
|
-
created_at: input.existing?.created_at ?? timestamp,
|
|
326
|
-
updated_at: timestamp,
|
|
327
|
-
last_connected_at: input.existing?.last_connected_at ?? null
|
|
328
|
-
},
|
|
329
|
-
secretRef
|
|
330
|
-
};
|
|
331
|
-
}
|
|
332
|
-
function upsertAuthorityRemoteEndpoint(projectRoot, input) {
|
|
333
|
-
const endpointsToml = loadRemoteEndpointsToml(projectRoot);
|
|
334
|
-
const secretsToml = loadRemoteSecretsToml(projectRoot);
|
|
335
|
-
const existing = Object.values(endpointsToml.endpoints ?? {}).find((entry) => entry.alias === input.alias) ?? null;
|
|
336
|
-
const { record, secretRef } = nextRemoteEndpointRecord({
|
|
337
|
-
existing,
|
|
338
|
-
alias: input.alias,
|
|
339
|
-
host: input.host,
|
|
340
|
-
port: input.port,
|
|
341
|
-
token: input.token,
|
|
342
|
-
...input.endpointId !== undefined ? { endpointId: input.endpointId } : {},
|
|
343
|
-
...input.autoConnect !== undefined ? { autoConnect: input.autoConnect } : {},
|
|
344
|
-
...input.transport !== undefined ? { transport: input.transport } : {},
|
|
345
|
-
...input.labels !== undefined ? { labels: input.labels } : {},
|
|
346
|
-
...input.capabilities !== undefined ? { capabilities: input.capabilities } : {}
|
|
347
|
-
});
|
|
348
|
-
endpointsToml.endpoints = {
|
|
349
|
-
...endpointsToml.endpoints ?? {},
|
|
350
|
-
[record.id]: record
|
|
351
|
-
};
|
|
352
|
-
secretsToml.secrets = {
|
|
353
|
-
...secretsToml.secrets ?? {},
|
|
354
|
-
[secretRef]: input.token
|
|
355
|
-
};
|
|
356
|
-
saveRemoteEndpointsToml(projectRoot, endpointsToml);
|
|
357
|
-
saveRemoteSecretsToml(projectRoot, secretsToml);
|
|
358
|
-
return listAuthorityRemoteEndpoints(projectRoot).find((entry) => entry.id === record.id);
|
|
359
|
-
}
|
|
360
|
-
function updateAuthorityRemoteEndpoint(projectRoot, input) {
|
|
361
|
-
const endpointsToml = loadRemoteEndpointsToml(projectRoot);
|
|
362
|
-
const secretsToml = loadRemoteSecretsToml(projectRoot);
|
|
363
|
-
const current = Object.values(endpointsToml.endpoints ?? {}).find((entry) => input.endpointId && entry.id === input.endpointId || input.alias && entry.alias === input.alias);
|
|
364
|
-
if (!current)
|
|
365
|
-
return null;
|
|
366
|
-
const record = {
|
|
367
|
-
...current,
|
|
368
|
-
alias: normalizeString(input.alias) || current.alias,
|
|
369
|
-
host: normalizeString(input.host) || current.host,
|
|
370
|
-
port: input.port !== undefined ? normalizePort(input.port) : current.port,
|
|
371
|
-
auto_connect: input.autoConnect ?? current.auto_connect,
|
|
372
|
-
transport: normalizeString(input.transport) || current.transport,
|
|
373
|
-
labels: input.labels ?? normalizeStringArray(current.labels),
|
|
374
|
-
capabilities: input.capabilities ?? normalizeStringArray(current.capabilities),
|
|
375
|
-
updated_at: new Date().toISOString()
|
|
376
|
-
};
|
|
377
|
-
endpointsToml.endpoints = {
|
|
378
|
-
...endpointsToml.endpoints ?? {},
|
|
379
|
-
[record.id]: record
|
|
380
|
-
};
|
|
381
|
-
if (input.token !== undefined) {
|
|
382
|
-
secretsToml.secrets = {
|
|
383
|
-
...secretsToml.secrets ?? {},
|
|
384
|
-
[record.secret_ref]: input.token
|
|
385
|
-
};
|
|
386
|
-
}
|
|
387
|
-
saveRemoteEndpointsToml(projectRoot, endpointsToml);
|
|
388
|
-
saveRemoteSecretsToml(projectRoot, secretsToml);
|
|
389
|
-
return listAuthorityRemoteEndpoints(projectRoot).find((entry) => entry.id === record.id) ?? null;
|
|
390
|
-
}
|
|
391
|
-
function removeAuthorityRemoteEndpoint(projectRoot, endpointIdOrAlias) {
|
|
392
|
-
const endpointsToml = loadRemoteEndpointsToml(projectRoot);
|
|
393
|
-
const secretsToml = loadRemoteSecretsToml(projectRoot);
|
|
394
|
-
const entry = Object.values(endpointsToml.endpoints ?? {}).find((candidate) => candidate.id === endpointIdOrAlias || candidate.alias === endpointIdOrAlias);
|
|
395
|
-
if (!entry)
|
|
396
|
-
return false;
|
|
397
|
-
const nextEndpoints = { ...endpointsToml.endpoints ?? {} };
|
|
398
|
-
delete nextEndpoints[entry.id];
|
|
399
|
-
const nextSecrets = { ...secretsToml.secrets ?? {} };
|
|
400
|
-
delete nextSecrets[entry.secret_ref];
|
|
401
|
-
saveRemoteEndpointsToml(projectRoot, { version: endpointsToml.version ?? 1, endpoints: nextEndpoints });
|
|
402
|
-
saveRemoteSecretsToml(projectRoot, { version: secretsToml.version ?? 1, secrets: nextSecrets });
|
|
403
|
-
return true;
|
|
404
|
-
}
|
|
405
|
-
function markAuthorityRemoteEndpointConnected(projectRoot, endpointId, connectedAt = new Date().toISOString()) {
|
|
406
|
-
const endpointsToml = loadRemoteEndpointsToml(projectRoot);
|
|
407
|
-
const entry = endpointsToml.endpoints?.[endpointId];
|
|
408
|
-
if (!entry)
|
|
409
|
-
return;
|
|
410
|
-
endpointsToml.endpoints = {
|
|
411
|
-
...endpointsToml.endpoints ?? {},
|
|
412
|
-
[endpointId]: {
|
|
413
|
-
...entry,
|
|
414
|
-
last_connected_at: connectedAt,
|
|
415
|
-
updated_at: connectedAt
|
|
416
|
-
}
|
|
417
|
-
};
|
|
418
|
-
saveRemoteEndpointsToml(projectRoot, endpointsToml);
|
|
419
|
-
}
|
|
420
|
-
function importLegacyRemoteEndpoints(projectRoot, legacyPath = REMOTES_CONFIG_PATH) {
|
|
421
|
-
if (!existsSync2(legacyPath)) {
|
|
422
|
-
return { imported: 0, skipped: 0, sourcePath: legacyPath };
|
|
423
|
-
}
|
|
424
|
-
const parsed = readTomlFile(legacyPath, { version: 1, remotes: {} });
|
|
425
|
-
let imported = 0;
|
|
426
|
-
let skipped = 0;
|
|
427
|
-
for (const [alias, entry] of Object.entries(parsed.remotes ?? {})) {
|
|
428
|
-
const host = normalizeString(entry.host);
|
|
429
|
-
const token = normalizeString(entry.token);
|
|
430
|
-
if (!host || !token) {
|
|
431
|
-
skipped += 1;
|
|
432
|
-
continue;
|
|
433
|
-
}
|
|
434
|
-
upsertAuthorityRemoteEndpoint(projectRoot, {
|
|
435
|
-
alias,
|
|
436
|
-
host,
|
|
437
|
-
port: normalizePort(entry.port),
|
|
438
|
-
token
|
|
439
|
-
});
|
|
440
|
-
imported += 1;
|
|
441
|
-
}
|
|
442
|
-
return { imported, skipped, sourcePath: legacyPath };
|
|
443
|
-
}
|
|
444
|
-
function doctorAuthorityRemoteEndpoints(projectRoot) {
|
|
445
|
-
const paths = resolveAuthorityPaths(projectRoot);
|
|
446
|
-
const endpoints = loadRemoteEndpointsToml(projectRoot).endpoints ?? {};
|
|
447
|
-
const secrets = loadRemoteSecretsToml(projectRoot).secrets ?? {};
|
|
448
|
-
const missingSecrets = Object.values(endpoints).filter((entry) => !normalizeString(secrets[entry.secret_ref])).map((entry) => entry.alias);
|
|
449
|
-
const warnings = [];
|
|
450
|
-
if (!existsSync2(paths.remoteEndpointsPath)) {
|
|
451
|
-
warnings.push("Remote endpoint manifest is missing.");
|
|
452
|
-
}
|
|
453
|
-
if (!existsSync2(paths.remoteSecretsPath)) {
|
|
454
|
-
warnings.push("Remote secret store is missing.");
|
|
455
|
-
}
|
|
456
|
-
return {
|
|
457
|
-
manifestPath: paths.remoteEndpointsPath,
|
|
458
|
-
secretsPath: paths.remoteSecretsPath,
|
|
459
|
-
endpointCount: Object.keys(endpoints).length,
|
|
460
|
-
missingSecrets,
|
|
461
|
-
warnings
|
|
462
|
-
};
|
|
463
|
-
}
|
|
464
|
-
function listManagedRemoteEndpoints(configPath = REMOTES_CONFIG_PATH, projectRoot) {
|
|
465
|
-
if (projectRoot) {
|
|
466
|
-
return listAuthorityRemoteEndpoints(projectRoot).map((entry) => ({
|
|
467
|
-
id: entry.id,
|
|
468
|
-
alias: entry.alias,
|
|
469
|
-
host: entry.host,
|
|
470
|
-
port: entry.port,
|
|
471
|
-
token: entry.token,
|
|
472
|
-
addedAt: entry.addedAt,
|
|
473
|
-
lastConnected: entry.lastConnectedAt
|
|
474
|
-
}));
|
|
475
|
-
}
|
|
476
|
-
const config = loadRemotesConfig(configPath);
|
|
477
|
-
return Object.entries(config.remotes ?? {}).map(([alias, entry]) => ({
|
|
478
|
-
id: alias,
|
|
479
|
-
alias,
|
|
480
|
-
host: normalizeString(entry.host) || "",
|
|
481
|
-
port: Number.isFinite(entry.port) ? Number(entry.port) : DEFAULT_REMOTE_PORT,
|
|
482
|
-
token: normalizeString(entry.token) || "",
|
|
483
|
-
addedAt: normalizeString(entry.addedAt) || null,
|
|
484
|
-
lastConnected: normalizeString(entry.lastConnected) || null
|
|
485
|
-
})).sort((left, right) => left.alias.localeCompare(right.alias));
|
|
486
|
-
}
|
|
487
|
-
function upsertManagedRemoteEndpoint(input, configPath = REMOTES_CONFIG_PATH, projectRoot) {
|
|
488
|
-
if (projectRoot) {
|
|
489
|
-
const saved = upsertAuthorityRemoteEndpoint(projectRoot, {
|
|
490
|
-
...input,
|
|
491
|
-
token: input.token ?? ""
|
|
492
|
-
});
|
|
493
|
-
return {
|
|
494
|
-
id: saved.id,
|
|
495
|
-
alias: saved.alias,
|
|
496
|
-
host: saved.host,
|
|
497
|
-
port: saved.port,
|
|
498
|
-
token: saved.token,
|
|
499
|
-
addedAt: saved.addedAt,
|
|
500
|
-
lastConnected: saved.lastConnectedAt
|
|
501
|
-
};
|
|
502
|
-
}
|
|
503
|
-
const config = loadRemotesConfig(configPath);
|
|
504
|
-
const existing = config.remotes?.[input.alias];
|
|
505
|
-
const nextEntry = {
|
|
506
|
-
host: input.host,
|
|
507
|
-
port: input.port,
|
|
508
|
-
...input.token !== undefined ? { token: input.token } : {},
|
|
509
|
-
addedAt: normalizeString(existing?.addedAt) || new Date().toISOString(),
|
|
510
|
-
...normalizeString(existing?.lastConnected) ? { lastConnected: normalizeString(existing?.lastConnected) } : {}
|
|
511
|
-
};
|
|
512
|
-
const nextConfig = {
|
|
513
|
-
version: config.version ?? 1,
|
|
514
|
-
remotes: {
|
|
515
|
-
...config.remotes ?? {},
|
|
516
|
-
[input.alias]: nextEntry
|
|
517
|
-
}
|
|
518
|
-
};
|
|
519
|
-
saveRemotesConfig(nextConfig, configPath);
|
|
520
|
-
return {
|
|
521
|
-
id: input.alias,
|
|
522
|
-
alias: input.alias,
|
|
523
|
-
host: input.host,
|
|
524
|
-
port: input.port,
|
|
525
|
-
token: input.token ?? "",
|
|
526
|
-
addedAt: nextEntry.addedAt ?? null,
|
|
527
|
-
lastConnected: nextEntry.lastConnected ?? null
|
|
528
|
-
};
|
|
529
|
-
}
|
|
530
|
-
function removeManagedRemoteEndpoint(alias, configPath = REMOTES_CONFIG_PATH, projectRoot) {
|
|
531
|
-
if (projectRoot) {
|
|
532
|
-
return removeAuthorityRemoteEndpoint(projectRoot, alias);
|
|
533
|
-
}
|
|
534
|
-
const config = loadRemotesConfig(configPath);
|
|
535
|
-
if (!config.remotes?.[alias]) {
|
|
536
|
-
return false;
|
|
537
|
-
}
|
|
538
|
-
const nextRemotes = { ...config.remotes ?? {} };
|
|
539
|
-
delete nextRemotes[alias];
|
|
540
|
-
saveRemotesConfig({
|
|
541
|
-
version: config.version ?? 1,
|
|
542
|
-
remotes: nextRemotes
|
|
543
|
-
}, configPath);
|
|
544
|
-
return true;
|
|
545
|
-
}
|
|
546
|
-
function normalizeString(value) {
|
|
547
|
-
if (!value) {
|
|
548
|
-
return "";
|
|
549
|
-
}
|
|
550
|
-
return value.trim();
|
|
63
|
+
function materializeRigOmpConfigOverlay(_projectRoot, _env = process.env) {
|
|
64
|
+
return remoteConfigOwnerRequired();
|
|
551
65
|
}
|
|
552
66
|
export {
|
|
553
67
|
upsertManagedRemoteEndpoint,
|
|
@@ -558,16 +72,13 @@ export {
|
|
|
558
72
|
resolveRelayUrl,
|
|
559
73
|
resolveRegistryBaseUrl,
|
|
560
74
|
resolveOwnerNamespaceKey,
|
|
75
|
+
resolveManagedRemoteEndpoint,
|
|
561
76
|
resolveDispatchTransportPlacement,
|
|
562
77
|
removeManagedRemoteEndpoint,
|
|
563
78
|
registerBackboneDefaults,
|
|
564
|
-
|
|
565
|
-
markAuthorityRemoteEndpointConnected,
|
|
79
|
+
materializeRigOmpConfigOverlay,
|
|
566
80
|
loadRemotesConfig,
|
|
567
81
|
listManagedRemoteEndpoints,
|
|
568
|
-
listAuthorityRemoteEndpoints,
|
|
569
|
-
importLegacyRemoteEndpoints,
|
|
570
|
-
doctorAuthorityRemoteEndpoints,
|
|
571
82
|
RemoteCliError,
|
|
572
83
|
REMOTES_CONFIG_PATH,
|
|
573
84
|
DEFAULT_REMOTE_PORT
|
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
readonly taskId: string;
|
|
9
|
-
readonly mode: typeof RUN_WORKSPACE_ISOLATION_MODE;
|
|
10
|
-
readonly provider: typeof RUN_WORKSPACE_PROVIDER;
|
|
11
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* Deprecated compatibility subpath. Run launch/provisioning behavior is owned
|
|
3
|
+
* outside @rig/core (transport/run-host). Resolve the typed owner services or
|
|
4
|
+
* import the owner plugin's run-provisioning helper instead.
|
|
5
|
+
*/
|
|
6
|
+
import type { EnsureAgentRuntimeOptions } from "@rig/contracts";
|
|
7
|
+
export type RunWorkspaceProvisioningOptions = Pick<EnsureAgentRuntimeOptions, "projectRoot" | "id" | "taskId" | "mode" | "provider">;
|
|
12
8
|
export type RigRunLaunchOptions = {
|
|
13
9
|
readonly taskId: string;
|
|
14
10
|
readonly title?: string | null | undefined;
|
|
@@ -16,42 +12,25 @@ export type RigRunLaunchOptions = {
|
|
|
16
12
|
readonly prompt?: string | null | undefined;
|
|
17
13
|
readonly forceSteerOnce?: boolean | undefined;
|
|
18
14
|
};
|
|
19
|
-
export
|
|
20
|
-
readonly mode: "configured" | "managed";
|
|
21
|
-
readonly repoName: string;
|
|
22
|
-
readonly checkoutPath: string;
|
|
23
|
-
readonly checkoutPathKind: "literal" | "home-relative";
|
|
24
|
-
readonly originUrl: string | null;
|
|
25
|
-
};
|
|
26
|
-
export type RunGithubAuthMaterialization = {
|
|
27
|
-
readonly operatorAuthPath: string;
|
|
28
|
-
readonly operatorStateDir: string;
|
|
29
|
-
readonly remoteAuthPath: string;
|
|
30
|
-
readonly remoteStateDir: string;
|
|
31
|
-
};
|
|
32
|
-
export declare function buildRunWorkspaceProvisioningOptions(input: {
|
|
15
|
+
export declare function buildRunWorkspaceProvisioningOptions(_input: {
|
|
33
16
|
readonly projectRoot: string;
|
|
34
17
|
readonly runId: string;
|
|
35
18
|
readonly taskId: string;
|
|
19
|
+
readonly mode: EnsureAgentRuntimeOptions["mode"];
|
|
20
|
+
readonly provider?: EnsureAgentRuntimeOptions["provider"];
|
|
36
21
|
}): RunWorkspaceProvisioningOptions;
|
|
37
|
-
export declare function buildRigRunLaunchArgs(
|
|
38
|
-
export declare function
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
export declare function resolveRunGithubAuthMaterialization(projectRoot: string, checkoutExpression?: string): RunGithubAuthMaterialization;
|
|
43
|
-
export declare function readGithubAuthStateBase64(operatorAuthPath: string): string;
|
|
44
|
-
export declare function buildRemoteRigRunResolutionShell(installUrl: string, command?: "rig-run"): string[];
|
|
45
|
-
export declare function isCompiledBunBinary(importMetaUrl: string): boolean;
|
|
46
|
-
export declare function resolveCompiledRigRunSiblingPath(execPath: string, platform?: NodeJS.Platform): string;
|
|
47
|
-
export declare function ensureRigRunSiblingCurrent(rigBin: string, rigRun: string): void;
|
|
48
|
-
export declare function resolveLocalDispatchRigRunBin(input: {
|
|
22
|
+
export declare function buildRigRunLaunchArgs(_input: RigRunLaunchOptions, _runId: string, _projectRoot: string): string[];
|
|
23
|
+
export declare function isCompiledBunBinary(_importMetaUrl: string): boolean;
|
|
24
|
+
export declare function resolveCompiledSiblingPath(_execPath: string, _siblingBinaryName: string, _platform?: NodeJS.Platform): string;
|
|
25
|
+
export declare function ensureSiblingBinaryCurrent(_sourceBin: string, _siblingBin: string): void;
|
|
26
|
+
export declare function resolveLocalDispatchRigRunBin(_input: {
|
|
49
27
|
readonly importMetaUrl: string;
|
|
50
28
|
readonly sourceRigRunPath: string;
|
|
29
|
+
readonly compiledSiblingName: string;
|
|
51
30
|
readonly execPath?: string;
|
|
52
31
|
readonly platform?: NodeJS.Platform;
|
|
53
32
|
}): string;
|
|
54
|
-
export declare function resolveInProcessRigRunBin(
|
|
33
|
+
export declare function resolveInProcessRigRunBin(_input: {
|
|
55
34
|
readonly importMetaUrl: string;
|
|
56
35
|
readonly sourceRigRunPath: string;
|
|
57
36
|
readonly execPath?: string;
|