@h-rig/cli 0.0.6-alpha.10 → 0.0.6-alpha.12
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 +54 -15
- package/dist/src/commands/_server-client.js +25 -5
- package/dist/src/commands/init.js +52 -14
- package/dist/src/commands/task-run-driver.js +2 -1
- package/dist/src/commands.js +54 -15
- package/dist/src/index.js +54 -15
- package/package.json +5 -5
package/dist/bin/rig.js
CHANGED
|
@@ -2851,16 +2851,36 @@ async function registerProjectViaServer(context, input) {
|
|
|
2851
2851
|
function sleep(ms) {
|
|
2852
2852
|
return new Promise((resolve10) => setTimeout(resolve10, ms));
|
|
2853
2853
|
}
|
|
2854
|
+
function isRetryableProjectRootSwitchError(error) {
|
|
2855
|
+
if (!(error instanceof Error))
|
|
2856
|
+
return false;
|
|
2857
|
+
const message = error.message.toLowerCase();
|
|
2858
|
+
return message.includes("rig server request failed (401): auth-required") || message.includes("rig server request failed (401): github-token-required") || message.includes("rig server request failed (502)") || message.includes("rig server request failed (503)") || message.includes("bad gateway") || message.includes("fetch failed") || message.includes("econnrefused") || message.includes("connection refused");
|
|
2859
|
+
}
|
|
2854
2860
|
async function switchServerProjectRootViaServer(context, projectRoot, options = {}) {
|
|
2855
|
-
const switched = await requestServerJson(context, "/api/server/project-root", {
|
|
2856
|
-
method: "POST",
|
|
2857
|
-
headers: { "content-type": "application/json" },
|
|
2858
|
-
body: JSON.stringify({ projectRoot })
|
|
2859
|
-
});
|
|
2860
2861
|
const timeoutMs = options.timeoutMs ?? 30000;
|
|
2861
2862
|
const pollMs = options.pollMs ?? 1000;
|
|
2862
2863
|
const deadline = Date.now() + timeoutMs;
|
|
2863
2864
|
let lastError;
|
|
2865
|
+
let switched = null;
|
|
2866
|
+
while (Date.now() < deadline) {
|
|
2867
|
+
try {
|
|
2868
|
+
switched = await requestServerJson(context, "/api/server/project-root", {
|
|
2869
|
+
method: "POST",
|
|
2870
|
+
headers: { "content-type": "application/json" },
|
|
2871
|
+
body: JSON.stringify({ projectRoot })
|
|
2872
|
+
});
|
|
2873
|
+
break;
|
|
2874
|
+
} catch (error) {
|
|
2875
|
+
lastError = error;
|
|
2876
|
+
if (!isRetryableProjectRootSwitchError(error))
|
|
2877
|
+
throw error;
|
|
2878
|
+
await sleep(pollMs);
|
|
2879
|
+
}
|
|
2880
|
+
}
|
|
2881
|
+
if (!switched) {
|
|
2882
|
+
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);
|
|
2883
|
+
}
|
|
2864
2884
|
while (Date.now() < deadline) {
|
|
2865
2885
|
try {
|
|
2866
2886
|
const status = await requestServerJson(context, "/api/server/status");
|
|
@@ -4610,12 +4630,29 @@ function apiSessionTokenFrom(payload) {
|
|
|
4610
4630
|
const token = payload.apiSessionToken;
|
|
4611
4631
|
return typeof token === "string" && token.trim() ? token.trim() : null;
|
|
4612
4632
|
}
|
|
4633
|
+
function cleanPayloadString(value) {
|
|
4634
|
+
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
4635
|
+
}
|
|
4636
|
+
function remoteGitHubAuthMetadata(payload) {
|
|
4637
|
+
if (!payload)
|
|
4638
|
+
return {};
|
|
4639
|
+
const userNamespace = payload.userNamespace && typeof payload.userNamespace === "object" && !Array.isArray(payload.userNamespace) ? payload.userNamespace : null;
|
|
4640
|
+
return {
|
|
4641
|
+
...cleanPayloadString(payload.login) ? { login: cleanPayloadString(payload.login) } : {},
|
|
4642
|
+
...cleanPayloadString(payload.userId) ? { userId: cleanPayloadString(payload.userId) } : {},
|
|
4643
|
+
...cleanPayloadString(userNamespace?.key) ? { userNamespaceKey: cleanPayloadString(userNamespace?.key) } : {},
|
|
4644
|
+
...cleanPayloadString(userNamespace?.root) ? { userNamespaceRoot: cleanPayloadString(userNamespace?.root) } : {},
|
|
4645
|
+
...cleanPayloadString(userNamespace?.checkoutBaseDir) ? { checkoutBaseDir: cleanPayloadString(userNamespace?.checkoutBaseDir) } : {},
|
|
4646
|
+
...cleanPayloadString(userNamespace?.snapshotBaseDir) ? { snapshotBaseDir: cleanPayloadString(userNamespace?.snapshotBaseDir) } : {}
|
|
4647
|
+
};
|
|
4648
|
+
}
|
|
4613
4649
|
function writeRemoteGitHubAuthState(projectRoot, input) {
|
|
4614
4650
|
writeFileSync5(resolve17(projectRoot, ".rig", "state", "github-auth.json"), `${JSON.stringify({
|
|
4615
4651
|
authenticated: true,
|
|
4616
4652
|
source: input.source,
|
|
4617
4653
|
storedOnServer: true,
|
|
4618
4654
|
selectedRepo: input.selectedRepo,
|
|
4655
|
+
...remoteGitHubAuthMetadata(input.authPayload ?? null),
|
|
4619
4656
|
...input.apiSessionToken ? { apiSessionToken: input.apiSessionToken } : {},
|
|
4620
4657
|
updatedAt: new Date().toISOString()
|
|
4621
4658
|
}, null, 2)}
|
|
@@ -4713,7 +4750,8 @@ async function runControlPlaneInit(context, options) {
|
|
|
4713
4750
|
writeRemoteGitHubAuthState(projectRoot, {
|
|
4714
4751
|
source: authMethod === "gh" ? "gh" : "init-token",
|
|
4715
4752
|
selectedRepo: repo.slug,
|
|
4716
|
-
apiSessionToken
|
|
4753
|
+
apiSessionToken,
|
|
4754
|
+
authPayload: githubAuth
|
|
4717
4755
|
});
|
|
4718
4756
|
}
|
|
4719
4757
|
} else if (authMethod === "device") {
|
|
@@ -4734,7 +4772,7 @@ async function runControlPlaneInit(context, options) {
|
|
|
4734
4772
|
if (apiSessionToken) {
|
|
4735
4773
|
setGitHubBearerTokenForCurrentProcess(apiSessionToken);
|
|
4736
4774
|
if (serverKind === "remote") {
|
|
4737
|
-
writeRemoteGitHubAuthState(projectRoot, { source: "device", selectedRepo: repo.slug, apiSessionToken });
|
|
4775
|
+
writeRemoteGitHubAuthState(projectRoot, { source: "device", selectedRepo: repo.slug, apiSessionToken, authPayload: completed });
|
|
4738
4776
|
}
|
|
4739
4777
|
}
|
|
4740
4778
|
deviceAuth = { ...deviceAuth, poll: completed, completed: completed.status === "signed-in" };
|
|
@@ -4752,18 +4790,18 @@ async function runControlPlaneInit(context, options) {
|
|
|
4752
4790
|
Object.assign(checkout, preparedCheckout);
|
|
4753
4791
|
}
|
|
4754
4792
|
}
|
|
4793
|
+
const checkoutPath = typeof checkout.path === "string" ? checkout.path : null;
|
|
4794
|
+
if (serverKind === "remote" && checkoutPath && token) {
|
|
4795
|
+
githubAuth = await postGitHubTokenViaServer(context, token, { selectedRepo: repo.slug, projectRoot: checkoutPath });
|
|
4796
|
+
const apiSessionToken = apiSessionTokenFrom(githubAuth);
|
|
4797
|
+
setGitHubBearerTokenForCurrentProcess(apiSessionToken ?? token);
|
|
4798
|
+
writeRemoteGitHubAuthState(projectRoot, { source: authMethod === "gh" ? "gh" : "init-token", selectedRepo: repo.slug, apiSessionToken, authPayload: githubAuth });
|
|
4799
|
+
}
|
|
4755
4800
|
const registered = await registerProjectViaServer(context, {
|
|
4756
4801
|
repoSlug: repo.slug,
|
|
4757
4802
|
checkout
|
|
4758
4803
|
});
|
|
4759
|
-
const checkoutPath = typeof checkout.path === "string" ? checkout.path : null;
|
|
4760
4804
|
const serverRootSwitch = serverKind === "remote" && checkoutPath ? await switchServerProjectRootViaServer(context, checkoutPath) : null;
|
|
4761
|
-
if (serverRootSwitch && token) {
|
|
4762
|
-
githubAuth = await postGitHubTokenViaServer(context, token, { selectedRepo: repo.slug, projectRoot: checkoutPath ?? undefined });
|
|
4763
|
-
const apiSessionToken = apiSessionTokenFrom(githubAuth);
|
|
4764
|
-
setGitHubBearerTokenForCurrentProcess(apiSessionToken ?? token);
|
|
4765
|
-
writeRemoteGitHubAuthState(projectRoot, { source: authMethod === "gh" ? "gh" : "init-token", selectedRepo: repo.slug, apiSessionToken });
|
|
4766
|
-
}
|
|
4767
4805
|
const activeProjectRegistration = serverRootSwitch ? await registerProjectViaServer(context, { repoSlug: repo.slug, checkout }) : null;
|
|
4768
4806
|
const pi = serverKind === "remote" ? await ensureRemotePiRigInstalled({ requestJson: (pathname, init) => requestServerJson(context, pathname, init) }).catch((error) => ({
|
|
4769
4807
|
remote: true,
|
|
@@ -7405,7 +7443,7 @@ function positiveInt(value, fallback) {
|
|
|
7405
7443
|
}
|
|
7406
7444
|
function resolveTaskRunAutomationLimits(config, env = process.env) {
|
|
7407
7445
|
const configuredValidationAttempts = positiveInt(config?.automation?.maxValidationAttempts, 30);
|
|
7408
|
-
const configuredPrFixIterations = positiveInt(config?.automation?.maxPrFixIterations,
|
|
7446
|
+
const configuredPrFixIterations = positiveInt(config?.automation?.maxPrFixIterations, 100500);
|
|
7409
7447
|
return {
|
|
7410
7448
|
maxValidationAttempts: parsePositiveInt2(env.RIG_TASK_RUN_MAX_ATTEMPTS, "RIG_TASK_RUN_MAX_ATTEMPTS", configuredValidationAttempts),
|
|
7411
7449
|
maxPrFixIterations: configuredPrFixIterations
|
|
@@ -7583,6 +7621,7 @@ async function runTaskRunPostValidationLifecycle(input) {
|
|
|
7583
7621
|
config,
|
|
7584
7622
|
sourceTask: input.sourceTask,
|
|
7585
7623
|
uploadedSnapshot: input.uploadedSnapshot,
|
|
7624
|
+
artifactRoot: resolve22(input.projectRoot, "artifacts", taskId2),
|
|
7586
7625
|
command: ghCommand,
|
|
7587
7626
|
steerPi,
|
|
7588
7627
|
lifecycle: {
|
|
@@ -275,16 +275,36 @@ async function registerProjectViaServer(context, input) {
|
|
|
275
275
|
function sleep(ms) {
|
|
276
276
|
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
277
277
|
}
|
|
278
|
+
function isRetryableProjectRootSwitchError(error) {
|
|
279
|
+
if (!(error instanceof Error))
|
|
280
|
+
return false;
|
|
281
|
+
const message = error.message.toLowerCase();
|
|
282
|
+
return message.includes("rig server request failed (401): auth-required") || message.includes("rig server request failed (401): github-token-required") || message.includes("rig server request failed (502)") || message.includes("rig server request failed (503)") || message.includes("bad gateway") || message.includes("fetch failed") || message.includes("econnrefused") || message.includes("connection refused");
|
|
283
|
+
}
|
|
278
284
|
async function switchServerProjectRootViaServer(context, projectRoot, options = {}) {
|
|
279
|
-
const switched = await requestServerJson(context, "/api/server/project-root", {
|
|
280
|
-
method: "POST",
|
|
281
|
-
headers: { "content-type": "application/json" },
|
|
282
|
-
body: JSON.stringify({ projectRoot })
|
|
283
|
-
});
|
|
284
285
|
const timeoutMs = options.timeoutMs ?? 30000;
|
|
285
286
|
const pollMs = options.pollMs ?? 1000;
|
|
286
287
|
const deadline = Date.now() + timeoutMs;
|
|
287
288
|
let lastError;
|
|
289
|
+
let switched = null;
|
|
290
|
+
while (Date.now() < deadline) {
|
|
291
|
+
try {
|
|
292
|
+
switched = await requestServerJson(context, "/api/server/project-root", {
|
|
293
|
+
method: "POST",
|
|
294
|
+
headers: { "content-type": "application/json" },
|
|
295
|
+
body: JSON.stringify({ projectRoot })
|
|
296
|
+
});
|
|
297
|
+
break;
|
|
298
|
+
} catch (error) {
|
|
299
|
+
lastError = error;
|
|
300
|
+
if (!isRetryableProjectRootSwitchError(error))
|
|
301
|
+
throw error;
|
|
302
|
+
await sleep(pollMs);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
if (!switched) {
|
|
306
|
+
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);
|
|
307
|
+
}
|
|
288
308
|
while (Date.now() < deadline) {
|
|
289
309
|
try {
|
|
290
310
|
const status = await requestServerJson(context, "/api/server/status");
|
|
@@ -290,16 +290,36 @@ async function registerProjectViaServer(context, input) {
|
|
|
290
290
|
function sleep(ms) {
|
|
291
291
|
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
292
292
|
}
|
|
293
|
+
function isRetryableProjectRootSwitchError(error) {
|
|
294
|
+
if (!(error instanceof Error))
|
|
295
|
+
return false;
|
|
296
|
+
const message = error.message.toLowerCase();
|
|
297
|
+
return message.includes("rig server request failed (401): auth-required") || message.includes("rig server request failed (401): github-token-required") || message.includes("rig server request failed (502)") || message.includes("rig server request failed (503)") || message.includes("bad gateway") || message.includes("fetch failed") || message.includes("econnrefused") || message.includes("connection refused");
|
|
298
|
+
}
|
|
293
299
|
async function switchServerProjectRootViaServer(context, projectRoot, options = {}) {
|
|
294
|
-
const switched = await requestServerJson(context, "/api/server/project-root", {
|
|
295
|
-
method: "POST",
|
|
296
|
-
headers: { "content-type": "application/json" },
|
|
297
|
-
body: JSON.stringify({ projectRoot })
|
|
298
|
-
});
|
|
299
300
|
const timeoutMs = options.timeoutMs ?? 30000;
|
|
300
301
|
const pollMs = options.pollMs ?? 1000;
|
|
301
302
|
const deadline = Date.now() + timeoutMs;
|
|
302
303
|
let lastError;
|
|
304
|
+
let switched = null;
|
|
305
|
+
while (Date.now() < deadline) {
|
|
306
|
+
try {
|
|
307
|
+
switched = await requestServerJson(context, "/api/server/project-root", {
|
|
308
|
+
method: "POST",
|
|
309
|
+
headers: { "content-type": "application/json" },
|
|
310
|
+
body: JSON.stringify({ projectRoot })
|
|
311
|
+
});
|
|
312
|
+
break;
|
|
313
|
+
} catch (error) {
|
|
314
|
+
lastError = error;
|
|
315
|
+
if (!isRetryableProjectRootSwitchError(error))
|
|
316
|
+
throw error;
|
|
317
|
+
await sleep(pollMs);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
if (!switched) {
|
|
321
|
+
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);
|
|
322
|
+
}
|
|
303
323
|
while (Date.now() < deadline) {
|
|
304
324
|
try {
|
|
305
325
|
const status = await requestServerJson(context, "/api/server/status");
|
|
@@ -947,12 +967,29 @@ function apiSessionTokenFrom(payload) {
|
|
|
947
967
|
const token = payload.apiSessionToken;
|
|
948
968
|
return typeof token === "string" && token.trim() ? token.trim() : null;
|
|
949
969
|
}
|
|
970
|
+
function cleanPayloadString(value) {
|
|
971
|
+
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
972
|
+
}
|
|
973
|
+
function remoteGitHubAuthMetadata(payload) {
|
|
974
|
+
if (!payload)
|
|
975
|
+
return {};
|
|
976
|
+
const userNamespace = payload.userNamespace && typeof payload.userNamespace === "object" && !Array.isArray(payload.userNamespace) ? payload.userNamespace : null;
|
|
977
|
+
return {
|
|
978
|
+
...cleanPayloadString(payload.login) ? { login: cleanPayloadString(payload.login) } : {},
|
|
979
|
+
...cleanPayloadString(payload.userId) ? { userId: cleanPayloadString(payload.userId) } : {},
|
|
980
|
+
...cleanPayloadString(userNamespace?.key) ? { userNamespaceKey: cleanPayloadString(userNamespace?.key) } : {},
|
|
981
|
+
...cleanPayloadString(userNamespace?.root) ? { userNamespaceRoot: cleanPayloadString(userNamespace?.root) } : {},
|
|
982
|
+
...cleanPayloadString(userNamespace?.checkoutBaseDir) ? { checkoutBaseDir: cleanPayloadString(userNamespace?.checkoutBaseDir) } : {},
|
|
983
|
+
...cleanPayloadString(userNamespace?.snapshotBaseDir) ? { snapshotBaseDir: cleanPayloadString(userNamespace?.snapshotBaseDir) } : {}
|
|
984
|
+
};
|
|
985
|
+
}
|
|
950
986
|
function writeRemoteGitHubAuthState(projectRoot, input) {
|
|
951
987
|
writeFileSync2(resolve6(projectRoot, ".rig", "state", "github-auth.json"), `${JSON.stringify({
|
|
952
988
|
authenticated: true,
|
|
953
989
|
source: input.source,
|
|
954
990
|
storedOnServer: true,
|
|
955
991
|
selectedRepo: input.selectedRepo,
|
|
992
|
+
...remoteGitHubAuthMetadata(input.authPayload ?? null),
|
|
956
993
|
...input.apiSessionToken ? { apiSessionToken: input.apiSessionToken } : {},
|
|
957
994
|
updatedAt: new Date().toISOString()
|
|
958
995
|
}, null, 2)}
|
|
@@ -1050,7 +1087,8 @@ async function runControlPlaneInit(context, options) {
|
|
|
1050
1087
|
writeRemoteGitHubAuthState(projectRoot, {
|
|
1051
1088
|
source: authMethod === "gh" ? "gh" : "init-token",
|
|
1052
1089
|
selectedRepo: repo.slug,
|
|
1053
|
-
apiSessionToken
|
|
1090
|
+
apiSessionToken,
|
|
1091
|
+
authPayload: githubAuth
|
|
1054
1092
|
});
|
|
1055
1093
|
}
|
|
1056
1094
|
} else if (authMethod === "device") {
|
|
@@ -1071,7 +1109,7 @@ async function runControlPlaneInit(context, options) {
|
|
|
1071
1109
|
if (apiSessionToken) {
|
|
1072
1110
|
setGitHubBearerTokenForCurrentProcess(apiSessionToken);
|
|
1073
1111
|
if (serverKind === "remote") {
|
|
1074
|
-
writeRemoteGitHubAuthState(projectRoot, { source: "device", selectedRepo: repo.slug, apiSessionToken });
|
|
1112
|
+
writeRemoteGitHubAuthState(projectRoot, { source: "device", selectedRepo: repo.slug, apiSessionToken, authPayload: completed });
|
|
1075
1113
|
}
|
|
1076
1114
|
}
|
|
1077
1115
|
deviceAuth = { ...deviceAuth, poll: completed, completed: completed.status === "signed-in" };
|
|
@@ -1089,18 +1127,18 @@ async function runControlPlaneInit(context, options) {
|
|
|
1089
1127
|
Object.assign(checkout, preparedCheckout);
|
|
1090
1128
|
}
|
|
1091
1129
|
}
|
|
1130
|
+
const checkoutPath = typeof checkout.path === "string" ? checkout.path : null;
|
|
1131
|
+
if (serverKind === "remote" && checkoutPath && token) {
|
|
1132
|
+
githubAuth = await postGitHubTokenViaServer(context, token, { selectedRepo: repo.slug, projectRoot: checkoutPath });
|
|
1133
|
+
const apiSessionToken = apiSessionTokenFrom(githubAuth);
|
|
1134
|
+
setGitHubBearerTokenForCurrentProcess(apiSessionToken ?? token);
|
|
1135
|
+
writeRemoteGitHubAuthState(projectRoot, { source: authMethod === "gh" ? "gh" : "init-token", selectedRepo: repo.slug, apiSessionToken, authPayload: githubAuth });
|
|
1136
|
+
}
|
|
1092
1137
|
const registered = await registerProjectViaServer(context, {
|
|
1093
1138
|
repoSlug: repo.slug,
|
|
1094
1139
|
checkout
|
|
1095
1140
|
});
|
|
1096
|
-
const checkoutPath = typeof checkout.path === "string" ? checkout.path : null;
|
|
1097
1141
|
const serverRootSwitch = serverKind === "remote" && checkoutPath ? await switchServerProjectRootViaServer(context, checkoutPath) : null;
|
|
1098
|
-
if (serverRootSwitch && token) {
|
|
1099
|
-
githubAuth = await postGitHubTokenViaServer(context, token, { selectedRepo: repo.slug, projectRoot: checkoutPath ?? undefined });
|
|
1100
|
-
const apiSessionToken = apiSessionTokenFrom(githubAuth);
|
|
1101
|
-
setGitHubBearerTokenForCurrentProcess(apiSessionToken ?? token);
|
|
1102
|
-
writeRemoteGitHubAuthState(projectRoot, { source: authMethod === "gh" ? "gh" : "init-token", selectedRepo: repo.slug, apiSessionToken });
|
|
1103
|
-
}
|
|
1104
1142
|
const activeProjectRegistration = serverRootSwitch ? await registerProjectViaServer(context, { repoSlug: repo.slug, checkout }) : null;
|
|
1105
1143
|
const pi = serverKind === "remote" ? await ensureRemotePiRigInstalled({ requestJson: (pathname, init) => requestServerJson(context, pathname, init) }).catch((error) => ({
|
|
1106
1144
|
remote: true,
|
|
@@ -507,7 +507,7 @@ function positiveInt(value, fallback) {
|
|
|
507
507
|
}
|
|
508
508
|
function resolveTaskRunAutomationLimits(config, env = process.env) {
|
|
509
509
|
const configuredValidationAttempts = positiveInt(config?.automation?.maxValidationAttempts, 30);
|
|
510
|
-
const configuredPrFixIterations = positiveInt(config?.automation?.maxPrFixIterations,
|
|
510
|
+
const configuredPrFixIterations = positiveInt(config?.automation?.maxPrFixIterations, 100500);
|
|
511
511
|
return {
|
|
512
512
|
maxValidationAttempts: parsePositiveInt(env.RIG_TASK_RUN_MAX_ATTEMPTS, "RIG_TASK_RUN_MAX_ATTEMPTS", configuredValidationAttempts),
|
|
513
513
|
maxPrFixIterations: configuredPrFixIterations
|
|
@@ -692,6 +692,7 @@ async function runTaskRunPostValidationLifecycle(input) {
|
|
|
692
692
|
config,
|
|
693
693
|
sourceTask: input.sourceTask,
|
|
694
694
|
uploadedSnapshot: input.uploadedSnapshot,
|
|
695
|
+
artifactRoot: resolve4(input.projectRoot, "artifacts", taskId),
|
|
695
696
|
command: ghCommand,
|
|
696
697
|
steerPi,
|
|
697
698
|
lifecycle: {
|
package/dist/src/commands.js
CHANGED
|
@@ -2644,16 +2644,36 @@ async function registerProjectViaServer(context, input) {
|
|
|
2644
2644
|
function sleep(ms) {
|
|
2645
2645
|
return new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
2646
2646
|
}
|
|
2647
|
+
function isRetryableProjectRootSwitchError(error) {
|
|
2648
|
+
if (!(error instanceof Error))
|
|
2649
|
+
return false;
|
|
2650
|
+
const message = error.message.toLowerCase();
|
|
2651
|
+
return message.includes("rig server request failed (401): auth-required") || message.includes("rig server request failed (401): github-token-required") || message.includes("rig server request failed (502)") || message.includes("rig server request failed (503)") || message.includes("bad gateway") || message.includes("fetch failed") || message.includes("econnrefused") || message.includes("connection refused");
|
|
2652
|
+
}
|
|
2647
2653
|
async function switchServerProjectRootViaServer(context, projectRoot, options = {}) {
|
|
2648
|
-
const switched = await requestServerJson(context, "/api/server/project-root", {
|
|
2649
|
-
method: "POST",
|
|
2650
|
-
headers: { "content-type": "application/json" },
|
|
2651
|
-
body: JSON.stringify({ projectRoot })
|
|
2652
|
-
});
|
|
2653
2654
|
const timeoutMs = options.timeoutMs ?? 30000;
|
|
2654
2655
|
const pollMs = options.pollMs ?? 1000;
|
|
2655
2656
|
const deadline = Date.now() + timeoutMs;
|
|
2656
2657
|
let lastError;
|
|
2658
|
+
let switched = null;
|
|
2659
|
+
while (Date.now() < deadline) {
|
|
2660
|
+
try {
|
|
2661
|
+
switched = await requestServerJson(context, "/api/server/project-root", {
|
|
2662
|
+
method: "POST",
|
|
2663
|
+
headers: { "content-type": "application/json" },
|
|
2664
|
+
body: JSON.stringify({ projectRoot })
|
|
2665
|
+
});
|
|
2666
|
+
break;
|
|
2667
|
+
} catch (error) {
|
|
2668
|
+
lastError = error;
|
|
2669
|
+
if (!isRetryableProjectRootSwitchError(error))
|
|
2670
|
+
throw error;
|
|
2671
|
+
await sleep(pollMs);
|
|
2672
|
+
}
|
|
2673
|
+
}
|
|
2674
|
+
if (!switched) {
|
|
2675
|
+
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);
|
|
2676
|
+
}
|
|
2657
2677
|
while (Date.now() < deadline) {
|
|
2658
2678
|
try {
|
|
2659
2679
|
const status = await requestServerJson(context, "/api/server/status");
|
|
@@ -4403,12 +4423,29 @@ function apiSessionTokenFrom(payload) {
|
|
|
4403
4423
|
const token = payload.apiSessionToken;
|
|
4404
4424
|
return typeof token === "string" && token.trim() ? token.trim() : null;
|
|
4405
4425
|
}
|
|
4426
|
+
function cleanPayloadString(value) {
|
|
4427
|
+
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
4428
|
+
}
|
|
4429
|
+
function remoteGitHubAuthMetadata(payload) {
|
|
4430
|
+
if (!payload)
|
|
4431
|
+
return {};
|
|
4432
|
+
const userNamespace = payload.userNamespace && typeof payload.userNamespace === "object" && !Array.isArray(payload.userNamespace) ? payload.userNamespace : null;
|
|
4433
|
+
return {
|
|
4434
|
+
...cleanPayloadString(payload.login) ? { login: cleanPayloadString(payload.login) } : {},
|
|
4435
|
+
...cleanPayloadString(payload.userId) ? { userId: cleanPayloadString(payload.userId) } : {},
|
|
4436
|
+
...cleanPayloadString(userNamespace?.key) ? { userNamespaceKey: cleanPayloadString(userNamespace?.key) } : {},
|
|
4437
|
+
...cleanPayloadString(userNamespace?.root) ? { userNamespaceRoot: cleanPayloadString(userNamespace?.root) } : {},
|
|
4438
|
+
...cleanPayloadString(userNamespace?.checkoutBaseDir) ? { checkoutBaseDir: cleanPayloadString(userNamespace?.checkoutBaseDir) } : {},
|
|
4439
|
+
...cleanPayloadString(userNamespace?.snapshotBaseDir) ? { snapshotBaseDir: cleanPayloadString(userNamespace?.snapshotBaseDir) } : {}
|
|
4440
|
+
};
|
|
4441
|
+
}
|
|
4406
4442
|
function writeRemoteGitHubAuthState(projectRoot, input) {
|
|
4407
4443
|
writeFileSync5(resolve16(projectRoot, ".rig", "state", "github-auth.json"), `${JSON.stringify({
|
|
4408
4444
|
authenticated: true,
|
|
4409
4445
|
source: input.source,
|
|
4410
4446
|
storedOnServer: true,
|
|
4411
4447
|
selectedRepo: input.selectedRepo,
|
|
4448
|
+
...remoteGitHubAuthMetadata(input.authPayload ?? null),
|
|
4412
4449
|
...input.apiSessionToken ? { apiSessionToken: input.apiSessionToken } : {},
|
|
4413
4450
|
updatedAt: new Date().toISOString()
|
|
4414
4451
|
}, null, 2)}
|
|
@@ -4506,7 +4543,8 @@ async function runControlPlaneInit(context, options) {
|
|
|
4506
4543
|
writeRemoteGitHubAuthState(projectRoot, {
|
|
4507
4544
|
source: authMethod === "gh" ? "gh" : "init-token",
|
|
4508
4545
|
selectedRepo: repo.slug,
|
|
4509
|
-
apiSessionToken
|
|
4546
|
+
apiSessionToken,
|
|
4547
|
+
authPayload: githubAuth
|
|
4510
4548
|
});
|
|
4511
4549
|
}
|
|
4512
4550
|
} else if (authMethod === "device") {
|
|
@@ -4527,7 +4565,7 @@ async function runControlPlaneInit(context, options) {
|
|
|
4527
4565
|
if (apiSessionToken) {
|
|
4528
4566
|
setGitHubBearerTokenForCurrentProcess(apiSessionToken);
|
|
4529
4567
|
if (serverKind === "remote") {
|
|
4530
|
-
writeRemoteGitHubAuthState(projectRoot, { source: "device", selectedRepo: repo.slug, apiSessionToken });
|
|
4568
|
+
writeRemoteGitHubAuthState(projectRoot, { source: "device", selectedRepo: repo.slug, apiSessionToken, authPayload: completed });
|
|
4531
4569
|
}
|
|
4532
4570
|
}
|
|
4533
4571
|
deviceAuth = { ...deviceAuth, poll: completed, completed: completed.status === "signed-in" };
|
|
@@ -4545,18 +4583,18 @@ async function runControlPlaneInit(context, options) {
|
|
|
4545
4583
|
Object.assign(checkout, preparedCheckout);
|
|
4546
4584
|
}
|
|
4547
4585
|
}
|
|
4586
|
+
const checkoutPath = typeof checkout.path === "string" ? checkout.path : null;
|
|
4587
|
+
if (serverKind === "remote" && checkoutPath && token) {
|
|
4588
|
+
githubAuth = await postGitHubTokenViaServer(context, token, { selectedRepo: repo.slug, projectRoot: checkoutPath });
|
|
4589
|
+
const apiSessionToken = apiSessionTokenFrom(githubAuth);
|
|
4590
|
+
setGitHubBearerTokenForCurrentProcess(apiSessionToken ?? token);
|
|
4591
|
+
writeRemoteGitHubAuthState(projectRoot, { source: authMethod === "gh" ? "gh" : "init-token", selectedRepo: repo.slug, apiSessionToken, authPayload: githubAuth });
|
|
4592
|
+
}
|
|
4548
4593
|
const registered = await registerProjectViaServer(context, {
|
|
4549
4594
|
repoSlug: repo.slug,
|
|
4550
4595
|
checkout
|
|
4551
4596
|
});
|
|
4552
|
-
const checkoutPath = typeof checkout.path === "string" ? checkout.path : null;
|
|
4553
4597
|
const serverRootSwitch = serverKind === "remote" && checkoutPath ? await switchServerProjectRootViaServer(context, checkoutPath) : null;
|
|
4554
|
-
if (serverRootSwitch && token) {
|
|
4555
|
-
githubAuth = await postGitHubTokenViaServer(context, token, { selectedRepo: repo.slug, projectRoot: checkoutPath ?? undefined });
|
|
4556
|
-
const apiSessionToken = apiSessionTokenFrom(githubAuth);
|
|
4557
|
-
setGitHubBearerTokenForCurrentProcess(apiSessionToken ?? token);
|
|
4558
|
-
writeRemoteGitHubAuthState(projectRoot, { source: authMethod === "gh" ? "gh" : "init-token", selectedRepo: repo.slug, apiSessionToken });
|
|
4559
|
-
}
|
|
4560
4598
|
const activeProjectRegistration = serverRootSwitch ? await registerProjectViaServer(context, { repoSlug: repo.slug, checkout }) : null;
|
|
4561
4599
|
const pi = serverKind === "remote" ? await ensureRemotePiRigInstalled({ requestJson: (pathname, init) => requestServerJson(context, pathname, init) }).catch((error) => ({
|
|
4562
4600
|
remote: true,
|
|
@@ -7198,7 +7236,7 @@ function positiveInt(value, fallback) {
|
|
|
7198
7236
|
}
|
|
7199
7237
|
function resolveTaskRunAutomationLimits(config, env = process.env) {
|
|
7200
7238
|
const configuredValidationAttempts = positiveInt(config?.automation?.maxValidationAttempts, 30);
|
|
7201
|
-
const configuredPrFixIterations = positiveInt(config?.automation?.maxPrFixIterations,
|
|
7239
|
+
const configuredPrFixIterations = positiveInt(config?.automation?.maxPrFixIterations, 100500);
|
|
7202
7240
|
return {
|
|
7203
7241
|
maxValidationAttempts: parsePositiveInt2(env.RIG_TASK_RUN_MAX_ATTEMPTS, "RIG_TASK_RUN_MAX_ATTEMPTS", configuredValidationAttempts),
|
|
7204
7242
|
maxPrFixIterations: configuredPrFixIterations
|
|
@@ -7376,6 +7414,7 @@ async function runTaskRunPostValidationLifecycle(input) {
|
|
|
7376
7414
|
config,
|
|
7377
7415
|
sourceTask: input.sourceTask,
|
|
7378
7416
|
uploadedSnapshot: input.uploadedSnapshot,
|
|
7417
|
+
artifactRoot: resolve21(input.projectRoot, "artifacts", taskId2),
|
|
7379
7418
|
command: ghCommand,
|
|
7380
7419
|
steerPi,
|
|
7381
7420
|
lifecycle: {
|
package/dist/src/index.js
CHANGED
|
@@ -2847,16 +2847,36 @@ async function registerProjectViaServer(context, input) {
|
|
|
2847
2847
|
function sleep(ms) {
|
|
2848
2848
|
return new Promise((resolve10) => setTimeout(resolve10, ms));
|
|
2849
2849
|
}
|
|
2850
|
+
function isRetryableProjectRootSwitchError(error) {
|
|
2851
|
+
if (!(error instanceof Error))
|
|
2852
|
+
return false;
|
|
2853
|
+
const message = error.message.toLowerCase();
|
|
2854
|
+
return message.includes("rig server request failed (401): auth-required") || message.includes("rig server request failed (401): github-token-required") || message.includes("rig server request failed (502)") || message.includes("rig server request failed (503)") || message.includes("bad gateway") || message.includes("fetch failed") || message.includes("econnrefused") || message.includes("connection refused");
|
|
2855
|
+
}
|
|
2850
2856
|
async function switchServerProjectRootViaServer(context, projectRoot, options = {}) {
|
|
2851
|
-
const switched = await requestServerJson(context, "/api/server/project-root", {
|
|
2852
|
-
method: "POST",
|
|
2853
|
-
headers: { "content-type": "application/json" },
|
|
2854
|
-
body: JSON.stringify({ projectRoot })
|
|
2855
|
-
});
|
|
2856
2857
|
const timeoutMs = options.timeoutMs ?? 30000;
|
|
2857
2858
|
const pollMs = options.pollMs ?? 1000;
|
|
2858
2859
|
const deadline = Date.now() + timeoutMs;
|
|
2859
2860
|
let lastError;
|
|
2861
|
+
let switched = null;
|
|
2862
|
+
while (Date.now() < deadline) {
|
|
2863
|
+
try {
|
|
2864
|
+
switched = await requestServerJson(context, "/api/server/project-root", {
|
|
2865
|
+
method: "POST",
|
|
2866
|
+
headers: { "content-type": "application/json" },
|
|
2867
|
+
body: JSON.stringify({ projectRoot })
|
|
2868
|
+
});
|
|
2869
|
+
break;
|
|
2870
|
+
} catch (error) {
|
|
2871
|
+
lastError = error;
|
|
2872
|
+
if (!isRetryableProjectRootSwitchError(error))
|
|
2873
|
+
throw error;
|
|
2874
|
+
await sleep(pollMs);
|
|
2875
|
+
}
|
|
2876
|
+
}
|
|
2877
|
+
if (!switched) {
|
|
2878
|
+
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);
|
|
2879
|
+
}
|
|
2860
2880
|
while (Date.now() < deadline) {
|
|
2861
2881
|
try {
|
|
2862
2882
|
const status = await requestServerJson(context, "/api/server/status");
|
|
@@ -4606,12 +4626,29 @@ function apiSessionTokenFrom(payload) {
|
|
|
4606
4626
|
const token = payload.apiSessionToken;
|
|
4607
4627
|
return typeof token === "string" && token.trim() ? token.trim() : null;
|
|
4608
4628
|
}
|
|
4629
|
+
function cleanPayloadString(value) {
|
|
4630
|
+
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
4631
|
+
}
|
|
4632
|
+
function remoteGitHubAuthMetadata(payload) {
|
|
4633
|
+
if (!payload)
|
|
4634
|
+
return {};
|
|
4635
|
+
const userNamespace = payload.userNamespace && typeof payload.userNamespace === "object" && !Array.isArray(payload.userNamespace) ? payload.userNamespace : null;
|
|
4636
|
+
return {
|
|
4637
|
+
...cleanPayloadString(payload.login) ? { login: cleanPayloadString(payload.login) } : {},
|
|
4638
|
+
...cleanPayloadString(payload.userId) ? { userId: cleanPayloadString(payload.userId) } : {},
|
|
4639
|
+
...cleanPayloadString(userNamespace?.key) ? { userNamespaceKey: cleanPayloadString(userNamespace?.key) } : {},
|
|
4640
|
+
...cleanPayloadString(userNamespace?.root) ? { userNamespaceRoot: cleanPayloadString(userNamespace?.root) } : {},
|
|
4641
|
+
...cleanPayloadString(userNamespace?.checkoutBaseDir) ? { checkoutBaseDir: cleanPayloadString(userNamespace?.checkoutBaseDir) } : {},
|
|
4642
|
+
...cleanPayloadString(userNamespace?.snapshotBaseDir) ? { snapshotBaseDir: cleanPayloadString(userNamespace?.snapshotBaseDir) } : {}
|
|
4643
|
+
};
|
|
4644
|
+
}
|
|
4609
4645
|
function writeRemoteGitHubAuthState(projectRoot, input) {
|
|
4610
4646
|
writeFileSync5(resolve17(projectRoot, ".rig", "state", "github-auth.json"), `${JSON.stringify({
|
|
4611
4647
|
authenticated: true,
|
|
4612
4648
|
source: input.source,
|
|
4613
4649
|
storedOnServer: true,
|
|
4614
4650
|
selectedRepo: input.selectedRepo,
|
|
4651
|
+
...remoteGitHubAuthMetadata(input.authPayload ?? null),
|
|
4615
4652
|
...input.apiSessionToken ? { apiSessionToken: input.apiSessionToken } : {},
|
|
4616
4653
|
updatedAt: new Date().toISOString()
|
|
4617
4654
|
}, null, 2)}
|
|
@@ -4709,7 +4746,8 @@ async function runControlPlaneInit(context, options) {
|
|
|
4709
4746
|
writeRemoteGitHubAuthState(projectRoot, {
|
|
4710
4747
|
source: authMethod === "gh" ? "gh" : "init-token",
|
|
4711
4748
|
selectedRepo: repo.slug,
|
|
4712
|
-
apiSessionToken
|
|
4749
|
+
apiSessionToken,
|
|
4750
|
+
authPayload: githubAuth
|
|
4713
4751
|
});
|
|
4714
4752
|
}
|
|
4715
4753
|
} else if (authMethod === "device") {
|
|
@@ -4730,7 +4768,7 @@ async function runControlPlaneInit(context, options) {
|
|
|
4730
4768
|
if (apiSessionToken) {
|
|
4731
4769
|
setGitHubBearerTokenForCurrentProcess(apiSessionToken);
|
|
4732
4770
|
if (serverKind === "remote") {
|
|
4733
|
-
writeRemoteGitHubAuthState(projectRoot, { source: "device", selectedRepo: repo.slug, apiSessionToken });
|
|
4771
|
+
writeRemoteGitHubAuthState(projectRoot, { source: "device", selectedRepo: repo.slug, apiSessionToken, authPayload: completed });
|
|
4734
4772
|
}
|
|
4735
4773
|
}
|
|
4736
4774
|
deviceAuth = { ...deviceAuth, poll: completed, completed: completed.status === "signed-in" };
|
|
@@ -4748,18 +4786,18 @@ async function runControlPlaneInit(context, options) {
|
|
|
4748
4786
|
Object.assign(checkout, preparedCheckout);
|
|
4749
4787
|
}
|
|
4750
4788
|
}
|
|
4789
|
+
const checkoutPath = typeof checkout.path === "string" ? checkout.path : null;
|
|
4790
|
+
if (serverKind === "remote" && checkoutPath && token) {
|
|
4791
|
+
githubAuth = await postGitHubTokenViaServer(context, token, { selectedRepo: repo.slug, projectRoot: checkoutPath });
|
|
4792
|
+
const apiSessionToken = apiSessionTokenFrom(githubAuth);
|
|
4793
|
+
setGitHubBearerTokenForCurrentProcess(apiSessionToken ?? token);
|
|
4794
|
+
writeRemoteGitHubAuthState(projectRoot, { source: authMethod === "gh" ? "gh" : "init-token", selectedRepo: repo.slug, apiSessionToken, authPayload: githubAuth });
|
|
4795
|
+
}
|
|
4751
4796
|
const registered = await registerProjectViaServer(context, {
|
|
4752
4797
|
repoSlug: repo.slug,
|
|
4753
4798
|
checkout
|
|
4754
4799
|
});
|
|
4755
|
-
const checkoutPath = typeof checkout.path === "string" ? checkout.path : null;
|
|
4756
4800
|
const serverRootSwitch = serverKind === "remote" && checkoutPath ? await switchServerProjectRootViaServer(context, checkoutPath) : null;
|
|
4757
|
-
if (serverRootSwitch && token) {
|
|
4758
|
-
githubAuth = await postGitHubTokenViaServer(context, token, { selectedRepo: repo.slug, projectRoot: checkoutPath ?? undefined });
|
|
4759
|
-
const apiSessionToken = apiSessionTokenFrom(githubAuth);
|
|
4760
|
-
setGitHubBearerTokenForCurrentProcess(apiSessionToken ?? token);
|
|
4761
|
-
writeRemoteGitHubAuthState(projectRoot, { source: authMethod === "gh" ? "gh" : "init-token", selectedRepo: repo.slug, apiSessionToken });
|
|
4762
|
-
}
|
|
4763
4801
|
const activeProjectRegistration = serverRootSwitch ? await registerProjectViaServer(context, { repoSlug: repo.slug, checkout }) : null;
|
|
4764
4802
|
const pi = serverKind === "remote" ? await ensureRemotePiRigInstalled({ requestJson: (pathname, init) => requestServerJson(context, pathname, init) }).catch((error) => ({
|
|
4765
4803
|
remote: true,
|
|
@@ -7401,7 +7439,7 @@ function positiveInt(value, fallback) {
|
|
|
7401
7439
|
}
|
|
7402
7440
|
function resolveTaskRunAutomationLimits(config, env = process.env) {
|
|
7403
7441
|
const configuredValidationAttempts = positiveInt(config?.automation?.maxValidationAttempts, 30);
|
|
7404
|
-
const configuredPrFixIterations = positiveInt(config?.automation?.maxPrFixIterations,
|
|
7442
|
+
const configuredPrFixIterations = positiveInt(config?.automation?.maxPrFixIterations, 100500);
|
|
7405
7443
|
return {
|
|
7406
7444
|
maxValidationAttempts: parsePositiveInt2(env.RIG_TASK_RUN_MAX_ATTEMPTS, "RIG_TASK_RUN_MAX_ATTEMPTS", configuredValidationAttempts),
|
|
7407
7445
|
maxPrFixIterations: configuredPrFixIterations
|
|
@@ -7579,6 +7617,7 @@ async function runTaskRunPostValidationLifecycle(input) {
|
|
|
7579
7617
|
config,
|
|
7580
7618
|
sourceTask: input.sourceTask,
|
|
7581
7619
|
uploadedSnapshot: input.uploadedSnapshot,
|
|
7620
|
+
artifactRoot: resolve22(input.projectRoot, "artifacts", taskId2),
|
|
7582
7621
|
command: ghCommand,
|
|
7583
7622
|
steerPi,
|
|
7584
7623
|
lifecycle: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@h-rig/cli",
|
|
3
|
-
"version": "0.0.6-alpha.
|
|
3
|
+
"version": "0.0.6-alpha.12",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Rig package",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@clack/prompts": "^1.2.0",
|
|
26
|
-
"@rig/core": "npm:@h-rig/core@0.0.6-alpha.
|
|
27
|
-
"@rig/runtime": "npm:@h-rig/runtime@0.0.6-alpha.
|
|
28
|
-
"@rig/client": "npm:@h-rig/client@0.0.6-alpha.
|
|
29
|
-
"@rig/server": "npm:@h-rig/server@0.0.6-alpha.
|
|
26
|
+
"@rig/core": "npm:@h-rig/core@0.0.6-alpha.12",
|
|
27
|
+
"@rig/runtime": "npm:@h-rig/runtime@0.0.6-alpha.12",
|
|
28
|
+
"@rig/client": "npm:@h-rig/client@0.0.6-alpha.12",
|
|
29
|
+
"@rig/server": "npm:@h-rig/server@0.0.6-alpha.12",
|
|
30
30
|
"picocolors": "^1.1.1"
|
|
31
31
|
}
|
|
32
32
|
}
|