@h-rig/cli 0.0.6-alpha.45 → 0.0.6-alpha.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/rig.js +50 -22
- package/dist/src/commands/_connection-state.js +11 -3
- package/dist/src/commands/_doctor-checks.js +51 -7
- package/dist/src/commands/_operator-view.js +53 -7
- package/dist/src/commands/_pi-frontend.js +53 -7
- package/dist/src/commands/_pi-remote-session.js +53 -7
- package/dist/src/commands/_pi-worker-bridge-extension.js +53 -7
- package/dist/src/commands/_preflight.js +51 -7
- package/dist/src/commands/_server-client.js +58 -22
- package/dist/src/commands/_snapshot-upload.js +51 -7
- package/dist/src/commands/connect.js +2 -1
- package/dist/src/commands/doctor.js +51 -7
- package/dist/src/commands/github.js +51 -7
- package/dist/src/commands/inbox.js +51 -7
- package/dist/src/commands/init.js +48 -22
- package/dist/src/commands/inspect.js +51 -7
- package/dist/src/commands/run.js +53 -7
- package/dist/src/commands/server.js +43 -7
- package/dist/src/commands/setup.js +51 -7
- package/dist/src/commands/task-run-driver.js +51 -7
- package/dist/src/commands/task.js +53 -7
- package/dist/src/commands.js +50 -22
- package/dist/src/index.js +50 -22
- package/package.json +6 -6
|
@@ -146,7 +146,8 @@ function readRepoConnection(projectRoot) {
|
|
|
146
146
|
return {
|
|
147
147
|
selected,
|
|
148
148
|
project: typeof record.project === "string" ? record.project : undefined,
|
|
149
|
-
linkedAt: typeof record.linkedAt === "string" ? record.linkedAt : undefined
|
|
149
|
+
linkedAt: typeof record.linkedAt === "string" ? record.linkedAt : undefined,
|
|
150
|
+
serverProjectRoot: typeof record.serverProjectRoot === "string" && record.serverProjectRoot.trim() ? record.serverProjectRoot.trim() : undefined
|
|
150
151
|
};
|
|
151
152
|
}
|
|
152
153
|
function writeRepoConnection(projectRoot, state) {
|
|
@@ -157,13 +158,19 @@ function resolveSelectedConnection(projectRoot, options = {}) {
|
|
|
157
158
|
if (!repo)
|
|
158
159
|
return null;
|
|
159
160
|
if (repo.selected === "local")
|
|
160
|
-
return { alias: "local", connection: { kind: "local", mode: "auto" } };
|
|
161
|
+
return { alias: "local", connection: { kind: "local", mode: "auto" }, serverProjectRoot: repo.serverProjectRoot };
|
|
161
162
|
const global = readGlobalConnections(options);
|
|
162
163
|
const connection = global.connections[repo.selected];
|
|
163
164
|
if (!connection) {
|
|
164
165
|
throw new CliError2(`Selected Rig server "${repo.selected}" was not found. Run \`rig server list\` or \`rig server use local\`.`, 1);
|
|
165
166
|
}
|
|
166
|
-
return { alias: repo.selected, connection };
|
|
167
|
+
return { alias: repo.selected, connection, serverProjectRoot: repo.serverProjectRoot };
|
|
168
|
+
}
|
|
169
|
+
function writeRepoServerProjectRoot(projectRoot, serverProjectRoot) {
|
|
170
|
+
const repo = readRepoConnection(projectRoot);
|
|
171
|
+
if (!repo)
|
|
172
|
+
return;
|
|
173
|
+
writeRepoConnection(projectRoot, { ...repo, serverProjectRoot });
|
|
167
174
|
}
|
|
168
175
|
|
|
169
176
|
// packages/cli/src/commands/_cli-format.ts
|
|
@@ -374,17 +381,21 @@ async function ensureServerForCli(projectRoot) {
|
|
|
374
381
|
try {
|
|
375
382
|
const selected = resolveSelectedConnection(projectRoot);
|
|
376
383
|
if (selected?.connection.kind === "remote") {
|
|
384
|
+
const authToken = readGitHubBearerTokenForRemote(projectRoot);
|
|
385
|
+
const serverProjectRoot = selected.serverProjectRoot ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
|
|
377
386
|
return {
|
|
378
387
|
baseUrl: selected.connection.baseUrl,
|
|
379
|
-
authToken
|
|
380
|
-
connectionKind: "remote"
|
|
388
|
+
authToken,
|
|
389
|
+
connectionKind: "remote",
|
|
390
|
+
serverProjectRoot
|
|
381
391
|
};
|
|
382
392
|
}
|
|
383
393
|
const connection = await ensureLocalRigServerConnection(projectRoot);
|
|
384
394
|
return {
|
|
385
395
|
baseUrl: connection.baseUrl,
|
|
386
396
|
authToken: connection.authToken,
|
|
387
|
-
connectionKind: "local"
|
|
397
|
+
connectionKind: "local",
|
|
398
|
+
serverProjectRoot: resolve2(projectRoot)
|
|
388
399
|
};
|
|
389
400
|
} catch (error) {
|
|
390
401
|
if (error instanceof Error) {
|
|
@@ -393,6 +404,28 @@ async function ensureServerForCli(projectRoot) {
|
|
|
393
404
|
throw error;
|
|
394
405
|
}
|
|
395
406
|
}
|
|
407
|
+
async function backfillRemoteServerProjectRoot(projectRoot, baseUrl, authToken) {
|
|
408
|
+
const repo = readRepoConnection(projectRoot);
|
|
409
|
+
const slug = repo?.project?.trim();
|
|
410
|
+
if (!slug)
|
|
411
|
+
return null;
|
|
412
|
+
try {
|
|
413
|
+
const response = await fetch(`${baseUrl}/api/projects/${encodeURIComponent(slug)}`, {
|
|
414
|
+
headers: mergeHeaders(undefined, authToken)
|
|
415
|
+
});
|
|
416
|
+
if (!response.ok)
|
|
417
|
+
return null;
|
|
418
|
+
const payload = await response.json();
|
|
419
|
+
const project = payload.project && typeof payload.project === "object" && !Array.isArray(payload.project) ? payload.project : null;
|
|
420
|
+
const checkout = project?.checkout && typeof project.checkout === "object" && !Array.isArray(project.checkout) ? project.checkout : null;
|
|
421
|
+
const path = typeof checkout?.path === "string" && checkout.path.trim() ? checkout.path.trim() : typeof project?.path === "string" && project.path.trim() ? project.path.trim() : null;
|
|
422
|
+
if (path)
|
|
423
|
+
writeRepoServerProjectRoot(projectRoot, path);
|
|
424
|
+
return path;
|
|
425
|
+
} catch {
|
|
426
|
+
return null;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
396
429
|
function mergeHeaders(headers, authToken) {
|
|
397
430
|
const merged = new Headers(headers);
|
|
398
431
|
if (authToken) {
|
|
@@ -417,9 +450,12 @@ function diagnosticMessage(payload) {
|
|
|
417
450
|
}
|
|
418
451
|
async function requestServerJson(context, pathname, init = {}) {
|
|
419
452
|
const server = await ensureServerForCli(context.projectRoot);
|
|
453
|
+
const headers = mergeHeaders(init.headers, server.authToken);
|
|
454
|
+
if (server.serverProjectRoot)
|
|
455
|
+
headers.set("x-rig-project-root", server.serverProjectRoot);
|
|
420
456
|
const response = await fetch(`${server.baseUrl}${pathname}`, {
|
|
421
457
|
...init,
|
|
422
|
-
headers
|
|
458
|
+
headers
|
|
423
459
|
});
|
|
424
460
|
const text = await response.text();
|
|
425
461
|
const payload = text.trim().length > 0 ? (() => {
|
|
@@ -199,6 +199,11 @@ function readJsonFile(path) {
|
|
|
199
199
|
throw new CliError2(`Invalid Rig connection state at ${path}: ${error instanceof Error ? error.message : String(error)}`, 1);
|
|
200
200
|
}
|
|
201
201
|
}
|
|
202
|
+
function writeJsonFile(path, value) {
|
|
203
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
204
|
+
writeFileSync(path, `${JSON.stringify(value, null, 2)}
|
|
205
|
+
`, "utf8");
|
|
206
|
+
}
|
|
202
207
|
function normalizeConnection(value) {
|
|
203
208
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
204
209
|
return null;
|
|
@@ -239,21 +244,31 @@ function readRepoConnection(projectRoot) {
|
|
|
239
244
|
return {
|
|
240
245
|
selected,
|
|
241
246
|
project: typeof record.project === "string" ? record.project : undefined,
|
|
242
|
-
linkedAt: typeof record.linkedAt === "string" ? record.linkedAt : undefined
|
|
247
|
+
linkedAt: typeof record.linkedAt === "string" ? record.linkedAt : undefined,
|
|
248
|
+
serverProjectRoot: typeof record.serverProjectRoot === "string" && record.serverProjectRoot.trim() ? record.serverProjectRoot.trim() : undefined
|
|
243
249
|
};
|
|
244
250
|
}
|
|
251
|
+
function writeRepoConnection(projectRoot, state) {
|
|
252
|
+
writeJsonFile(resolveRepoConnectionPath(projectRoot), state);
|
|
253
|
+
}
|
|
245
254
|
function resolveSelectedConnection(projectRoot, options = {}) {
|
|
246
255
|
const repo = readRepoConnection(projectRoot);
|
|
247
256
|
if (!repo)
|
|
248
257
|
return null;
|
|
249
258
|
if (repo.selected === "local")
|
|
250
|
-
return { alias: "local", connection: { kind: "local", mode: "auto" } };
|
|
259
|
+
return { alias: "local", connection: { kind: "local", mode: "auto" }, serverProjectRoot: repo.serverProjectRoot };
|
|
251
260
|
const global = readGlobalConnections(options);
|
|
252
261
|
const connection = global.connections[repo.selected];
|
|
253
262
|
if (!connection) {
|
|
254
263
|
throw new CliError2(`Selected Rig server "${repo.selected}" was not found. Run \`rig server list\` or \`rig server use local\`.`, 1);
|
|
255
264
|
}
|
|
256
|
-
return { alias: repo.selected, connection };
|
|
265
|
+
return { alias: repo.selected, connection, serverProjectRoot: repo.serverProjectRoot };
|
|
266
|
+
}
|
|
267
|
+
function writeRepoServerProjectRoot(projectRoot, serverProjectRoot) {
|
|
268
|
+
const repo = readRepoConnection(projectRoot);
|
|
269
|
+
if (!repo)
|
|
270
|
+
return;
|
|
271
|
+
writeRepoConnection(projectRoot, { ...repo, serverProjectRoot });
|
|
257
272
|
}
|
|
258
273
|
|
|
259
274
|
// packages/cli/src/commands/_server-client.ts
|
|
@@ -289,17 +304,21 @@ async function ensureServerForCli(projectRoot) {
|
|
|
289
304
|
try {
|
|
290
305
|
const selected = resolveSelectedConnection(projectRoot);
|
|
291
306
|
if (selected?.connection.kind === "remote") {
|
|
307
|
+
const authToken = readGitHubBearerTokenForRemote(projectRoot);
|
|
308
|
+
const serverProjectRoot = selected.serverProjectRoot ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
|
|
292
309
|
return {
|
|
293
310
|
baseUrl: selected.connection.baseUrl,
|
|
294
|
-
authToken
|
|
295
|
-
connectionKind: "remote"
|
|
311
|
+
authToken,
|
|
312
|
+
connectionKind: "remote",
|
|
313
|
+
serverProjectRoot
|
|
296
314
|
};
|
|
297
315
|
}
|
|
298
316
|
const connection = await ensureLocalRigServerConnection(projectRoot);
|
|
299
317
|
return {
|
|
300
318
|
baseUrl: connection.baseUrl,
|
|
301
319
|
authToken: connection.authToken,
|
|
302
|
-
connectionKind: "local"
|
|
320
|
+
connectionKind: "local",
|
|
321
|
+
serverProjectRoot: resolve4(projectRoot)
|
|
303
322
|
};
|
|
304
323
|
} catch (error) {
|
|
305
324
|
if (error instanceof Error) {
|
|
@@ -308,6 +327,28 @@ async function ensureServerForCli(projectRoot) {
|
|
|
308
327
|
throw error;
|
|
309
328
|
}
|
|
310
329
|
}
|
|
330
|
+
async function backfillRemoteServerProjectRoot(projectRoot, baseUrl, authToken) {
|
|
331
|
+
const repo = readRepoConnection(projectRoot);
|
|
332
|
+
const slug = repo?.project?.trim();
|
|
333
|
+
if (!slug)
|
|
334
|
+
return null;
|
|
335
|
+
try {
|
|
336
|
+
const response = await fetch(`${baseUrl}/api/projects/${encodeURIComponent(slug)}`, {
|
|
337
|
+
headers: mergeHeaders(undefined, authToken)
|
|
338
|
+
});
|
|
339
|
+
if (!response.ok)
|
|
340
|
+
return null;
|
|
341
|
+
const payload = await response.json();
|
|
342
|
+
const project = payload.project && typeof payload.project === "object" && !Array.isArray(payload.project) ? payload.project : null;
|
|
343
|
+
const checkout = project?.checkout && typeof project.checkout === "object" && !Array.isArray(project.checkout) ? project.checkout : null;
|
|
344
|
+
const path = typeof checkout?.path === "string" && checkout.path.trim() ? checkout.path.trim() : typeof project?.path === "string" && project.path.trim() ? project.path.trim() : null;
|
|
345
|
+
if (path)
|
|
346
|
+
writeRepoServerProjectRoot(projectRoot, path);
|
|
347
|
+
return path;
|
|
348
|
+
} catch {
|
|
349
|
+
return null;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
311
352
|
function mergeHeaders(headers, authToken) {
|
|
312
353
|
const merged = new Headers(headers);
|
|
313
354
|
if (authToken) {
|
|
@@ -332,9 +373,12 @@ function diagnosticMessage(payload) {
|
|
|
332
373
|
}
|
|
333
374
|
async function requestServerJson(context, pathname, init = {}) {
|
|
334
375
|
const server = await ensureServerForCli(context.projectRoot);
|
|
376
|
+
const headers = mergeHeaders(init.headers, server.authToken);
|
|
377
|
+
if (server.serverProjectRoot)
|
|
378
|
+
headers.set("x-rig-project-root", server.serverProjectRoot);
|
|
335
379
|
const response = await fetch(`${server.baseUrl}${pathname}`, {
|
|
336
380
|
...init,
|
|
337
|
-
headers
|
|
381
|
+
headers
|
|
338
382
|
});
|
|
339
383
|
const text = await response.text();
|
|
340
384
|
const payload = text.trim().length > 0 ? (() => {
|
|
@@ -418,6 +418,11 @@ function readJsonFile(path) {
|
|
|
418
418
|
throw new CliError2(`Invalid Rig connection state at ${path}: ${error instanceof Error ? error.message : String(error)}`, 1);
|
|
419
419
|
}
|
|
420
420
|
}
|
|
421
|
+
function writeJsonFile3(path, value) {
|
|
422
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
423
|
+
writeFileSync(path, `${JSON.stringify(value, null, 2)}
|
|
424
|
+
`, "utf8");
|
|
425
|
+
}
|
|
421
426
|
function normalizeConnection(value) {
|
|
422
427
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
423
428
|
return null;
|
|
@@ -458,21 +463,31 @@ function readRepoConnection(projectRoot) {
|
|
|
458
463
|
return {
|
|
459
464
|
selected,
|
|
460
465
|
project: typeof record.project === "string" ? record.project : undefined,
|
|
461
|
-
linkedAt: typeof record.linkedAt === "string" ? record.linkedAt : undefined
|
|
466
|
+
linkedAt: typeof record.linkedAt === "string" ? record.linkedAt : undefined,
|
|
467
|
+
serverProjectRoot: typeof record.serverProjectRoot === "string" && record.serverProjectRoot.trim() ? record.serverProjectRoot.trim() : undefined
|
|
462
468
|
};
|
|
463
469
|
}
|
|
470
|
+
function writeRepoConnection(projectRoot, state) {
|
|
471
|
+
writeJsonFile3(resolveRepoConnectionPath(projectRoot), state);
|
|
472
|
+
}
|
|
464
473
|
function resolveSelectedConnection(projectRoot, options = {}) {
|
|
465
474
|
const repo = readRepoConnection(projectRoot);
|
|
466
475
|
if (!repo)
|
|
467
476
|
return null;
|
|
468
477
|
if (repo.selected === "local")
|
|
469
|
-
return { alias: "local", connection: { kind: "local", mode: "auto" } };
|
|
478
|
+
return { alias: "local", connection: { kind: "local", mode: "auto" }, serverProjectRoot: repo.serverProjectRoot };
|
|
470
479
|
const global = readGlobalConnections(options);
|
|
471
480
|
const connection = global.connections[repo.selected];
|
|
472
481
|
if (!connection) {
|
|
473
482
|
throw new CliError2(`Selected Rig server "${repo.selected}" was not found. Run \`rig server list\` or \`rig server use local\`.`, 1);
|
|
474
483
|
}
|
|
475
|
-
return { alias: repo.selected, connection };
|
|
484
|
+
return { alias: repo.selected, connection, serverProjectRoot: repo.serverProjectRoot };
|
|
485
|
+
}
|
|
486
|
+
function writeRepoServerProjectRoot(projectRoot, serverProjectRoot) {
|
|
487
|
+
const repo = readRepoConnection(projectRoot);
|
|
488
|
+
if (!repo)
|
|
489
|
+
return;
|
|
490
|
+
writeRepoConnection(projectRoot, { ...repo, serverProjectRoot });
|
|
476
491
|
}
|
|
477
492
|
|
|
478
493
|
// packages/cli/src/commands/_server-client.ts
|
|
@@ -505,17 +520,21 @@ async function ensureServerForCli(projectRoot) {
|
|
|
505
520
|
try {
|
|
506
521
|
const selected = resolveSelectedConnection(projectRoot);
|
|
507
522
|
if (selected?.connection.kind === "remote") {
|
|
523
|
+
const authToken = readGitHubBearerTokenForRemote(projectRoot);
|
|
524
|
+
const serverProjectRoot = selected.serverProjectRoot ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
|
|
508
525
|
return {
|
|
509
526
|
baseUrl: selected.connection.baseUrl,
|
|
510
|
-
authToken
|
|
511
|
-
connectionKind: "remote"
|
|
527
|
+
authToken,
|
|
528
|
+
connectionKind: "remote",
|
|
529
|
+
serverProjectRoot
|
|
512
530
|
};
|
|
513
531
|
}
|
|
514
532
|
const connection = await ensureLocalRigServerConnection(projectRoot);
|
|
515
533
|
return {
|
|
516
534
|
baseUrl: connection.baseUrl,
|
|
517
535
|
authToken: connection.authToken,
|
|
518
|
-
connectionKind: "local"
|
|
536
|
+
connectionKind: "local",
|
|
537
|
+
serverProjectRoot: resolve5(projectRoot)
|
|
519
538
|
};
|
|
520
539
|
} catch (error) {
|
|
521
540
|
if (error instanceof Error) {
|
|
@@ -524,6 +543,28 @@ async function ensureServerForCli(projectRoot) {
|
|
|
524
543
|
throw error;
|
|
525
544
|
}
|
|
526
545
|
}
|
|
546
|
+
async function backfillRemoteServerProjectRoot(projectRoot, baseUrl, authToken) {
|
|
547
|
+
const repo = readRepoConnection(projectRoot);
|
|
548
|
+
const slug = repo?.project?.trim();
|
|
549
|
+
if (!slug)
|
|
550
|
+
return null;
|
|
551
|
+
try {
|
|
552
|
+
const response = await fetch(`${baseUrl}/api/projects/${encodeURIComponent(slug)}`, {
|
|
553
|
+
headers: mergeHeaders(undefined, authToken)
|
|
554
|
+
});
|
|
555
|
+
if (!response.ok)
|
|
556
|
+
return null;
|
|
557
|
+
const payload = await response.json();
|
|
558
|
+
const project = payload.project && typeof payload.project === "object" && !Array.isArray(payload.project) ? payload.project : null;
|
|
559
|
+
const checkout = project?.checkout && typeof project.checkout === "object" && !Array.isArray(project.checkout) ? project.checkout : null;
|
|
560
|
+
const path = typeof checkout?.path === "string" && checkout.path.trim() ? checkout.path.trim() : typeof project?.path === "string" && project.path.trim() ? project.path.trim() : null;
|
|
561
|
+
if (path)
|
|
562
|
+
writeRepoServerProjectRoot(projectRoot, path);
|
|
563
|
+
return path;
|
|
564
|
+
} catch {
|
|
565
|
+
return null;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
527
568
|
function mergeHeaders(headers, authToken) {
|
|
528
569
|
const merged = new Headers(headers);
|
|
529
570
|
if (authToken) {
|
|
@@ -548,9 +589,12 @@ function diagnosticMessage(payload) {
|
|
|
548
589
|
}
|
|
549
590
|
async function requestServerJson(context, pathname, init = {}) {
|
|
550
591
|
const server = await ensureServerForCli(context.projectRoot);
|
|
592
|
+
const headers = mergeHeaders(init.headers, server.authToken);
|
|
593
|
+
if (server.serverProjectRoot)
|
|
594
|
+
headers.set("x-rig-project-root", server.serverProjectRoot);
|
|
551
595
|
const response = await fetch(`${server.baseUrl}${pathname}`, {
|
|
552
596
|
...init,
|
|
553
|
-
headers
|
|
597
|
+
headers
|
|
554
598
|
});
|
|
555
599
|
const text = await response.text();
|
|
556
600
|
const payload = text.trim().length > 0 ? (() => {
|
|
@@ -128,6 +128,11 @@ function readJsonFile(path) {
|
|
|
128
128
|
throw new CliError2(`Invalid Rig connection state at ${path}: ${error instanceof Error ? error.message : String(error)}`, 1);
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
|
+
function writeJsonFile2(path, value) {
|
|
132
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
133
|
+
writeFileSync(path, `${JSON.stringify(value, null, 2)}
|
|
134
|
+
`, "utf8");
|
|
135
|
+
}
|
|
131
136
|
function normalizeConnection(value) {
|
|
132
137
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
133
138
|
return null;
|
|
@@ -168,21 +173,31 @@ function readRepoConnection(projectRoot) {
|
|
|
168
173
|
return {
|
|
169
174
|
selected,
|
|
170
175
|
project: typeof record.project === "string" ? record.project : undefined,
|
|
171
|
-
linkedAt: typeof record.linkedAt === "string" ? record.linkedAt : undefined
|
|
176
|
+
linkedAt: typeof record.linkedAt === "string" ? record.linkedAt : undefined,
|
|
177
|
+
serverProjectRoot: typeof record.serverProjectRoot === "string" && record.serverProjectRoot.trim() ? record.serverProjectRoot.trim() : undefined
|
|
172
178
|
};
|
|
173
179
|
}
|
|
180
|
+
function writeRepoConnection(projectRoot, state) {
|
|
181
|
+
writeJsonFile2(resolveRepoConnectionPath(projectRoot), state);
|
|
182
|
+
}
|
|
174
183
|
function resolveSelectedConnection(projectRoot, options = {}) {
|
|
175
184
|
const repo = readRepoConnection(projectRoot);
|
|
176
185
|
if (!repo)
|
|
177
186
|
return null;
|
|
178
187
|
if (repo.selected === "local")
|
|
179
|
-
return { alias: "local", connection: { kind: "local", mode: "auto" } };
|
|
188
|
+
return { alias: "local", connection: { kind: "local", mode: "auto" }, serverProjectRoot: repo.serverProjectRoot };
|
|
180
189
|
const global = readGlobalConnections(options);
|
|
181
190
|
const connection = global.connections[repo.selected];
|
|
182
191
|
if (!connection) {
|
|
183
192
|
throw new CliError2(`Selected Rig server "${repo.selected}" was not found. Run \`rig server list\` or \`rig server use local\`.`, 1);
|
|
184
193
|
}
|
|
185
|
-
return { alias: repo.selected, connection };
|
|
194
|
+
return { alias: repo.selected, connection, serverProjectRoot: repo.serverProjectRoot };
|
|
195
|
+
}
|
|
196
|
+
function writeRepoServerProjectRoot(projectRoot, serverProjectRoot) {
|
|
197
|
+
const repo = readRepoConnection(projectRoot);
|
|
198
|
+
if (!repo)
|
|
199
|
+
return;
|
|
200
|
+
writeRepoConnection(projectRoot, { ...repo, serverProjectRoot });
|
|
186
201
|
}
|
|
187
202
|
|
|
188
203
|
// packages/cli/src/commands/_server-client.ts
|
|
@@ -218,17 +233,21 @@ async function ensureServerForCli(projectRoot) {
|
|
|
218
233
|
try {
|
|
219
234
|
const selected = resolveSelectedConnection(projectRoot);
|
|
220
235
|
if (selected?.connection.kind === "remote") {
|
|
236
|
+
const authToken = readGitHubBearerTokenForRemote(projectRoot);
|
|
237
|
+
const serverProjectRoot = selected.serverProjectRoot ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
|
|
221
238
|
return {
|
|
222
239
|
baseUrl: selected.connection.baseUrl,
|
|
223
|
-
authToken
|
|
224
|
-
connectionKind: "remote"
|
|
240
|
+
authToken,
|
|
241
|
+
connectionKind: "remote",
|
|
242
|
+
serverProjectRoot
|
|
225
243
|
};
|
|
226
244
|
}
|
|
227
245
|
const connection = await ensureLocalRigServerConnection(projectRoot);
|
|
228
246
|
return {
|
|
229
247
|
baseUrl: connection.baseUrl,
|
|
230
248
|
authToken: connection.authToken,
|
|
231
|
-
connectionKind: "local"
|
|
249
|
+
connectionKind: "local",
|
|
250
|
+
serverProjectRoot: resolve2(projectRoot)
|
|
232
251
|
};
|
|
233
252
|
} catch (error) {
|
|
234
253
|
if (error instanceof Error) {
|
|
@@ -237,6 +256,28 @@ async function ensureServerForCli(projectRoot) {
|
|
|
237
256
|
throw error;
|
|
238
257
|
}
|
|
239
258
|
}
|
|
259
|
+
async function backfillRemoteServerProjectRoot(projectRoot, baseUrl, authToken) {
|
|
260
|
+
const repo = readRepoConnection(projectRoot);
|
|
261
|
+
const slug = repo?.project?.trim();
|
|
262
|
+
if (!slug)
|
|
263
|
+
return null;
|
|
264
|
+
try {
|
|
265
|
+
const response = await fetch(`${baseUrl}/api/projects/${encodeURIComponent(slug)}`, {
|
|
266
|
+
headers: mergeHeaders(undefined, authToken)
|
|
267
|
+
});
|
|
268
|
+
if (!response.ok)
|
|
269
|
+
return null;
|
|
270
|
+
const payload = await response.json();
|
|
271
|
+
const project = payload.project && typeof payload.project === "object" && !Array.isArray(payload.project) ? payload.project : null;
|
|
272
|
+
const checkout = project?.checkout && typeof project.checkout === "object" && !Array.isArray(project.checkout) ? project.checkout : null;
|
|
273
|
+
const path = typeof checkout?.path === "string" && checkout.path.trim() ? checkout.path.trim() : typeof project?.path === "string" && project.path.trim() ? project.path.trim() : null;
|
|
274
|
+
if (path)
|
|
275
|
+
writeRepoServerProjectRoot(projectRoot, path);
|
|
276
|
+
return path;
|
|
277
|
+
} catch {
|
|
278
|
+
return null;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
240
281
|
function appendTaskFilterParams(url, filters) {
|
|
241
282
|
if (filters.assignee)
|
|
242
283
|
url.searchParams.set("assignee", filters.assignee);
|
|
@@ -271,9 +312,12 @@ function diagnosticMessage(payload) {
|
|
|
271
312
|
}
|
|
272
313
|
async function requestServerJson(context, pathname, init = {}) {
|
|
273
314
|
const server = await ensureServerForCli(context.projectRoot);
|
|
315
|
+
const headers = mergeHeaders(init.headers, server.authToken);
|
|
316
|
+
if (server.serverProjectRoot)
|
|
317
|
+
headers.set("x-rig-project-root", server.serverProjectRoot);
|
|
274
318
|
const response = await fetch(`${server.baseUrl}${pathname}`, {
|
|
275
319
|
...init,
|
|
276
|
-
headers
|
|
320
|
+
headers
|
|
277
321
|
});
|
|
278
322
|
const text = await response.text();
|
|
279
323
|
const payload = text.trim().length > 0 ? (() => {
|
|
@@ -419,6 +463,8 @@ async function buildRunPiEventsWebSocketUrl(context, runId) {
|
|
|
419
463
|
url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
|
|
420
464
|
if (server.authToken)
|
|
421
465
|
url.searchParams.set("token", server.authToken);
|
|
466
|
+
if (server.serverProjectRoot)
|
|
467
|
+
url.searchParams.set("rigProjectRoot", server.serverProjectRoot);
|
|
422
468
|
return url.toString();
|
|
423
469
|
}
|
|
424
470
|
async function submitTaskRunViaServer(context, input) {
|
package/dist/src/commands.js
CHANGED
|
@@ -2694,7 +2694,8 @@ function readRepoConnection(projectRoot) {
|
|
|
2694
2694
|
return {
|
|
2695
2695
|
selected,
|
|
2696
2696
|
project: typeof record.project === "string" ? record.project : undefined,
|
|
2697
|
-
linkedAt: typeof record.linkedAt === "string" ? record.linkedAt : undefined
|
|
2697
|
+
linkedAt: typeof record.linkedAt === "string" ? record.linkedAt : undefined,
|
|
2698
|
+
serverProjectRoot: typeof record.serverProjectRoot === "string" && record.serverProjectRoot.trim() ? record.serverProjectRoot.trim() : undefined
|
|
2698
2699
|
};
|
|
2699
2700
|
}
|
|
2700
2701
|
function writeRepoConnection(projectRoot, state) {
|
|
@@ -2705,13 +2706,19 @@ function resolveSelectedConnection(projectRoot, options = {}) {
|
|
|
2705
2706
|
if (!repo)
|
|
2706
2707
|
return null;
|
|
2707
2708
|
if (repo.selected === "local")
|
|
2708
|
-
return { alias: "local", connection: { kind: "local", mode: "auto" } };
|
|
2709
|
+
return { alias: "local", connection: { kind: "local", mode: "auto" }, serverProjectRoot: repo.serverProjectRoot };
|
|
2709
2710
|
const global = readGlobalConnections(options);
|
|
2710
2711
|
const connection = global.connections[repo.selected];
|
|
2711
2712
|
if (!connection) {
|
|
2712
2713
|
throw new CliError2(`Selected Rig server "${repo.selected}" was not found. Run \`rig server list\` or \`rig server use local\`.`, 1);
|
|
2713
2714
|
}
|
|
2714
|
-
return { alias: repo.selected, connection };
|
|
2715
|
+
return { alias: repo.selected, connection, serverProjectRoot: repo.serverProjectRoot };
|
|
2716
|
+
}
|
|
2717
|
+
function writeRepoServerProjectRoot(projectRoot, serverProjectRoot) {
|
|
2718
|
+
const repo = readRepoConnection(projectRoot);
|
|
2719
|
+
if (!repo)
|
|
2720
|
+
return;
|
|
2721
|
+
writeRepoConnection(projectRoot, { ...repo, serverProjectRoot });
|
|
2715
2722
|
}
|
|
2716
2723
|
|
|
2717
2724
|
// packages/cli/src/commands/_server-client.ts
|
|
@@ -2752,17 +2759,21 @@ async function ensureServerForCli(projectRoot) {
|
|
|
2752
2759
|
try {
|
|
2753
2760
|
const selected = resolveSelectedConnection(projectRoot);
|
|
2754
2761
|
if (selected?.connection.kind === "remote") {
|
|
2762
|
+
const authToken = readGitHubBearerTokenForRemote(projectRoot);
|
|
2763
|
+
const serverProjectRoot = selected.serverProjectRoot ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
|
|
2755
2764
|
return {
|
|
2756
2765
|
baseUrl: selected.connection.baseUrl,
|
|
2757
|
-
authToken
|
|
2758
|
-
connectionKind: "remote"
|
|
2766
|
+
authToken,
|
|
2767
|
+
connectionKind: "remote",
|
|
2768
|
+
serverProjectRoot
|
|
2759
2769
|
};
|
|
2760
2770
|
}
|
|
2761
2771
|
const connection = await ensureLocalRigServerConnection(projectRoot);
|
|
2762
2772
|
return {
|
|
2763
2773
|
baseUrl: connection.baseUrl,
|
|
2764
2774
|
authToken: connection.authToken,
|
|
2765
|
-
connectionKind: "local"
|
|
2775
|
+
connectionKind: "local",
|
|
2776
|
+
serverProjectRoot: resolve10(projectRoot)
|
|
2766
2777
|
};
|
|
2767
2778
|
} catch (error) {
|
|
2768
2779
|
if (error instanceof Error) {
|
|
@@ -2771,6 +2782,28 @@ async function ensureServerForCli(projectRoot) {
|
|
|
2771
2782
|
throw error;
|
|
2772
2783
|
}
|
|
2773
2784
|
}
|
|
2785
|
+
async function backfillRemoteServerProjectRoot(projectRoot, baseUrl, authToken) {
|
|
2786
|
+
const repo = readRepoConnection(projectRoot);
|
|
2787
|
+
const slug = repo?.project?.trim();
|
|
2788
|
+
if (!slug)
|
|
2789
|
+
return null;
|
|
2790
|
+
try {
|
|
2791
|
+
const response = await fetch(`${baseUrl}/api/projects/${encodeURIComponent(slug)}`, {
|
|
2792
|
+
headers: mergeHeaders(undefined, authToken)
|
|
2793
|
+
});
|
|
2794
|
+
if (!response.ok)
|
|
2795
|
+
return null;
|
|
2796
|
+
const payload = await response.json();
|
|
2797
|
+
const project = payload.project && typeof payload.project === "object" && !Array.isArray(payload.project) ? payload.project : null;
|
|
2798
|
+
const checkout = project?.checkout && typeof project.checkout === "object" && !Array.isArray(project.checkout) ? project.checkout : null;
|
|
2799
|
+
const path = typeof checkout?.path === "string" && checkout.path.trim() ? checkout.path.trim() : typeof project?.path === "string" && project.path.trim() ? project.path.trim() : null;
|
|
2800
|
+
if (path)
|
|
2801
|
+
writeRepoServerProjectRoot(projectRoot, path);
|
|
2802
|
+
return path;
|
|
2803
|
+
} catch {
|
|
2804
|
+
return null;
|
|
2805
|
+
}
|
|
2806
|
+
}
|
|
2774
2807
|
function appendTaskFilterParams(url, filters) {
|
|
2775
2808
|
if (filters.assignee)
|
|
2776
2809
|
url.searchParams.set("assignee", filters.assignee);
|
|
@@ -2805,9 +2838,12 @@ function diagnosticMessage(payload) {
|
|
|
2805
2838
|
}
|
|
2806
2839
|
async function requestServerJson(context, pathname, init = {}) {
|
|
2807
2840
|
const server = await ensureServerForCli(context.projectRoot);
|
|
2841
|
+
const headers = mergeHeaders(init.headers, server.authToken);
|
|
2842
|
+
if (server.serverProjectRoot)
|
|
2843
|
+
headers.set("x-rig-project-root", server.serverProjectRoot);
|
|
2808
2844
|
const response = await fetch(`${server.baseUrl}${pathname}`, {
|
|
2809
2845
|
...init,
|
|
2810
|
-
headers
|
|
2846
|
+
headers
|
|
2811
2847
|
});
|
|
2812
2848
|
const text2 = await response.text();
|
|
2813
2849
|
const payload = text2.trim().length > 0 ? (() => {
|
|
@@ -2914,22 +2950,12 @@ async function switchServerProjectRootViaServer(context, projectRoot, options =
|
|
|
2914
2950
|
if (!switched) {
|
|
2915
2951
|
throw new CliError2(`Rig server did not accept project-root switch to ${projectRoot} before timeout (${lastError instanceof Error ? lastError.message : String(lastError ?? "no response")}).`, 1);
|
|
2916
2952
|
}
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
const record = status;
|
|
2922
|
-
if (record.projectRoot === projectRoot) {
|
|
2923
|
-
return { ok: true, switched, status: record };
|
|
2924
|
-
}
|
|
2925
|
-
lastError = `server projectRoot=${String(record.projectRoot ?? "unknown")}`;
|
|
2926
|
-
}
|
|
2927
|
-
} catch (error) {
|
|
2928
|
-
lastError = error;
|
|
2929
|
-
}
|
|
2930
|
-
await sleep(pollMs);
|
|
2953
|
+
const record = switched && typeof switched === "object" && !Array.isArray(switched) ? switched : {};
|
|
2954
|
+
if (record.ok === true) {
|
|
2955
|
+
writeRepoServerProjectRoot(context.projectRoot, projectRoot);
|
|
2956
|
+
return { ok: true, switched: record };
|
|
2931
2957
|
}
|
|
2932
|
-
throw new CliError2(`Rig server
|
|
2958
|
+
throw new CliError2(`Rig server rejected project-root scope ${projectRoot}: ${String(record.message ?? record.error ?? "unknown error")}`, 1);
|
|
2933
2959
|
}
|
|
2934
2960
|
async function listRunsViaServer(context, options = {}) {
|
|
2935
2961
|
const url = new URL("http://rig.local/api/runs");
|
|
@@ -3061,6 +3087,8 @@ async function buildRunPiEventsWebSocketUrl(context, runId) {
|
|
|
3061
3087
|
url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
|
|
3062
3088
|
if (server.authToken)
|
|
3063
3089
|
url.searchParams.set("token", server.authToken);
|
|
3090
|
+
if (server.serverProjectRoot)
|
|
3091
|
+
url.searchParams.set("rigProjectRoot", server.serverProjectRoot);
|
|
3064
3092
|
return url.toString();
|
|
3065
3093
|
}
|
|
3066
3094
|
async function submitTaskRunViaServer(context, input) {
|