@h-rig/cli 0.0.6-alpha.81 → 0.0.6-alpha.83
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/build-rig-binaries.js +40 -8
- package/dist/bin/rig.js +2807 -1443
- package/dist/src/app/board.js +62 -13
- package/dist/src/app-opentui/adapters/command.d.ts +2 -0
- package/dist/src/app-opentui/adapters/command.js +329 -0
- package/dist/src/app-opentui/adapters/common.js +2 -2
- package/dist/src/app-opentui/adapters/doctor.js +63 -14
- package/dist/src/app-opentui/adapters/fleet.js +84 -20
- package/dist/src/app-opentui/adapters/inbox.js +83 -19
- package/dist/src/app-opentui/adapters/init.js +87 -23
- package/dist/src/app-opentui/adapters/pi-attach.js +102 -36
- package/dist/src/app-opentui/adapters/run-detail.js +83 -19
- package/dist/src/app-opentui/adapters/server.js +100 -23
- package/dist/src/app-opentui/adapters/tasks.d.ts +11 -0
- package/dist/src/app-opentui/adapters/tasks.js +742 -94
- package/dist/src/app-opentui/bootstrap.d.ts +1 -6
- package/dist/src/app-opentui/bootstrap.js +13776 -12369
- package/dist/src/app-opentui/command-pty-host.d.ts +62 -0
- package/dist/src/app-opentui/command-pty-host.js +248 -0
- package/dist/src/app-opentui/events.js +1 -1
- package/dist/src/app-opentui/focus-manager.d.ts +14 -0
- package/dist/src/app-opentui/focus-manager.js +24 -0
- package/dist/src/app-opentui/index.js +3806 -2878
- package/dist/src/app-opentui/intent.js +154 -48
- package/dist/src/app-opentui/keymap.d.ts +20 -0
- package/dist/src/app-opentui/keymap.js +707 -0
- package/dist/src/app-opentui/launch-routing.d.ts +16 -0
- package/dist/src/app-opentui/launch-routing.js +55 -0
- package/dist/src/app-opentui/layout.js +2 -2
- package/dist/src/app-opentui/pi-host-child.js +66 -16
- package/dist/src/app-opentui/pi-pty-host.d.ts +9 -0
- package/dist/src/app-opentui/pi-pty-host.js +15 -13
- package/dist/src/app-opentui/registry.js +3228 -2396
- package/dist/src/app-opentui/render/ascii-fleet.d.ts +15 -0
- package/dist/src/app-opentui/render/ascii-fleet.js +82 -0
- package/dist/src/app-opentui/render/graphics.d.ts +1 -1
- package/dist/src/app-opentui/render/graphics.js +131 -16
- package/dist/src/app-opentui/render/image-visual-layer-worker.js +413 -958
- package/dist/src/app-opentui/render/image-visual-layer.d.ts +19 -10
- package/dist/src/app-opentui/render/image-visual-layer.js +391 -357
- package/dist/src/app-opentui/render/panel-layout.d.ts +38 -0
- package/dist/src/app-opentui/render/panel-layout.js +48 -0
- package/dist/src/app-opentui/render/panels.d.ts +2 -0
- package/dist/src/app-opentui/render/panels.js +62 -29
- package/dist/src/app-opentui/render/preloader.d.ts +10 -0
- package/dist/src/app-opentui/render/preloader.js +163 -0
- package/dist/src/app-opentui/render/scene.d.ts +3 -0
- package/dist/src/app-opentui/render/scene.js +12 -0
- package/dist/src/app-opentui/render/text.js +5 -1
- package/dist/src/app-opentui/render/type-bar.d.ts +2 -1
- package/dist/src/app-opentui/render/type-bar.js +51 -16
- package/dist/src/app-opentui/runtime-resources.d.ts +16 -0
- package/dist/src/app-opentui/runtime-resources.js +62 -0
- package/dist/src/app-opentui/runtime.js +2329 -1512
- package/dist/src/app-opentui/scenes/command.d.ts +3 -0
- package/dist/src/app-opentui/scenes/command.js +103 -0
- package/dist/src/app-opentui/scenes/doctor.d.ts +2 -1
- package/dist/src/app-opentui/scenes/doctor.js +53 -14
- package/dist/src/app-opentui/scenes/error.js +44 -14
- package/dist/src/app-opentui/scenes/fleet.js +40 -21
- package/dist/src/app-opentui/scenes/handoff.js +142 -27
- package/dist/src/app-opentui/scenes/help.js +63 -48
- package/dist/src/app-opentui/scenes/inbox.d.ts +2 -1
- package/dist/src/app-opentui/scenes/inbox.js +64 -17
- package/dist/src/app-opentui/scenes/init.d.ts +2 -1
- package/dist/src/app-opentui/scenes/init.js +62 -21
- package/dist/src/app-opentui/scenes/main.d.ts +2 -1
- package/dist/src/app-opentui/scenes/main.js +80 -24
- package/dist/src/app-opentui/scenes/run-detail.d.ts +2 -1
- package/dist/src/app-opentui/scenes/run-detail.js +39 -25
- package/dist/src/app-opentui/scenes/server.d.ts +2 -1
- package/dist/src/app-opentui/scenes/server.js +71 -20
- package/dist/src/app-opentui/scenes/tasks.js +44 -22
- package/dist/src/app-opentui/state.js +70 -30
- package/dist/src/app-opentui/terminal-capabilities.d.ts +7 -0
- package/dist/src/app-opentui/terminal-capabilities.js +15 -0
- package/dist/src/app-opentui/types.d.ts +10 -2
- package/dist/src/commands/_doctor-checks.js +62 -13
- package/dist/src/commands/_operator-view.js +63 -13
- package/dist/src/commands/_pi-frontend.js +63 -13
- package/dist/src/commands/_preflight.js +64 -14
- package/dist/src/commands/_server-client.js +82 -18
- package/dist/src/commands/_snapshot-upload.js +62 -13
- package/dist/src/commands/connect.js +7 -1
- package/dist/src/commands/doctor.js +62 -13
- package/dist/src/commands/github.js +144 -23
- package/dist/src/commands/inbox.js +62 -13
- package/dist/src/commands/init.js +82 -18
- package/dist/src/commands/inspect.js +62 -13
- package/dist/src/commands/run.js +66 -13
- package/dist/src/commands/server.js +69 -14
- package/dist/src/commands/setup.js +62 -13
- package/dist/src/commands/stats.js +62 -13
- package/dist/src/commands/task-run-driver.js +62 -13
- package/dist/src/commands/task.js +65 -14
- package/dist/src/commands.js +227 -92
- package/dist/src/index.js +234 -99
- package/package.json +8 -9
- package/dist/src/app-opentui/render/image-visual-layer-native-canvas.d.ts +0 -2
- package/dist/src/app-opentui/render/image-visual-layer-native-canvas.js +0 -1480
package/dist/src/commands.js
CHANGED
|
@@ -916,17 +916,21 @@ function setGitHubBearerTokenForCurrentProcess(token, projectRoot) {
|
|
|
916
916
|
const scopedKey = resolve10(projectRoot ?? process.cwd());
|
|
917
917
|
scopedGitHubBearerTokens.set(scopedKey, cleanToken(token ?? undefined));
|
|
918
918
|
}
|
|
919
|
-
function
|
|
919
|
+
function readRemoteAuthState(projectRoot) {
|
|
920
920
|
const path = resolve10(projectRoot, ".rig", "state", "github-auth.json");
|
|
921
921
|
if (!existsSync6(path))
|
|
922
922
|
return null;
|
|
923
923
|
try {
|
|
924
924
|
const parsed = JSON.parse(readFileSync4(path, "utf8"));
|
|
925
|
-
return
|
|
925
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
926
926
|
} catch {
|
|
927
927
|
return null;
|
|
928
928
|
}
|
|
929
929
|
}
|
|
930
|
+
function readPrivateRemoteSessionToken(projectRoot) {
|
|
931
|
+
const parsed = readRemoteAuthState(projectRoot);
|
|
932
|
+
return parsed ? cleanToken(typeof parsed.apiSessionToken === "string" ? parsed.apiSessionToken : typeof parsed.sessionToken === "string" ? parsed.sessionToken : undefined) : null;
|
|
933
|
+
}
|
|
930
934
|
function readGitHubBearerTokenForRemote(projectRoot) {
|
|
931
935
|
const scopedKey = resolve10(projectRoot);
|
|
932
936
|
if (scopedGitHubBearerTokens.has(scopedKey))
|
|
@@ -937,15 +941,25 @@ function readGitHubBearerTokenForRemote(projectRoot) {
|
|
|
937
941
|
return cleanToken(process.env.RIG_SERVER_AUTH_TOKEN) ?? cleanToken(process.env.RIG_REMOTE_AUTH_TOKEN);
|
|
938
942
|
}
|
|
939
943
|
function readStoredGitHubAuthToken(projectRoot) {
|
|
940
|
-
const
|
|
941
|
-
|
|
944
|
+
const parsed = readRemoteAuthState(projectRoot);
|
|
945
|
+
return parsed ? cleanToken(typeof parsed.token === "string" ? parsed.token : undefined) : null;
|
|
946
|
+
}
|
|
947
|
+
function inferRemoteServerProjectRootFromAuthState(projectRoot) {
|
|
948
|
+
const repo = readRepoConnection(projectRoot);
|
|
949
|
+
const slug = repo?.project?.trim();
|
|
950
|
+
if (!slug || !/^[^/]+\/[^/]+$/.test(slug))
|
|
942
951
|
return null;
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
952
|
+
const auth = readRemoteAuthState(projectRoot);
|
|
953
|
+
const authUpdatedAt = typeof auth?.updatedAt === "string" ? Date.parse(auth.updatedAt) : Number.NaN;
|
|
954
|
+
const repoLinkedAt = typeof repo?.linkedAt === "string" ? Date.parse(repo.linkedAt) : Number.NaN;
|
|
955
|
+
if (Number.isFinite(authUpdatedAt) && Number.isFinite(repoLinkedAt) && authUpdatedAt + 1000 < repoLinkedAt)
|
|
947
956
|
return null;
|
|
948
|
-
|
|
957
|
+
const checkoutBaseDir = typeof auth?.checkoutBaseDir === "string" && auth.checkoutBaseDir.trim() ? auth.checkoutBaseDir.trim() : null;
|
|
958
|
+
if (!checkoutBaseDir)
|
|
959
|
+
return null;
|
|
960
|
+
const inferred = `${checkoutBaseDir.replace(/\/+$/, "")}/${slug}`;
|
|
961
|
+
writeRepoServerProjectRoot(projectRoot, inferred);
|
|
962
|
+
return inferred;
|
|
949
963
|
}
|
|
950
964
|
function readLocalConnectionFallbackToken(projectRoot) {
|
|
951
965
|
return readGitHubBearerTokenForRemote(projectRoot) ?? cleanToken(process.env.RIG_GITHUB_TOKEN) ?? readStoredGitHubAuthToken(projectRoot);
|
|
@@ -956,7 +970,7 @@ async function ensureServerForCli(projectRoot) {
|
|
|
956
970
|
if (selected?.connection.kind === "remote") {
|
|
957
971
|
reportServerPhase(`Connecting to ${selected.alias}\u2026`);
|
|
958
972
|
const authToken = readGitHubBearerTokenForRemote(projectRoot);
|
|
959
|
-
const serverProjectRoot = selected.serverProjectRoot ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
|
|
973
|
+
const serverProjectRoot = selected.serverProjectRoot ?? inferRemoteServerProjectRootFromAuthState(projectRoot) ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
|
|
960
974
|
return {
|
|
961
975
|
baseUrl: selected.connection.baseUrl,
|
|
962
976
|
authToken,
|
|
@@ -985,7 +999,10 @@ async function backfillRemoteServerProjectRoot(projectRoot, baseUrl, authToken)
|
|
|
985
999
|
if (!slug)
|
|
986
1000
|
return null;
|
|
987
1001
|
try {
|
|
988
|
-
const
|
|
1002
|
+
const url = new URL(`${baseUrl}/api/projects/${encodeURIComponent(slug)}`);
|
|
1003
|
+
if (authToken && queryAuthFallbackEnabled())
|
|
1004
|
+
url.searchParams.set("rt", authToken);
|
|
1005
|
+
const response = await fetch(url, {
|
|
989
1006
|
headers: mergeHeaders(undefined, authToken)
|
|
990
1007
|
});
|
|
991
1008
|
if (!response.ok)
|
|
@@ -1012,10 +1029,23 @@ function appendTaskFilterParams(url, filters) {
|
|
|
1012
1029
|
if (filters.limit !== undefined)
|
|
1013
1030
|
url.searchParams.set("limit", String(filters.limit));
|
|
1014
1031
|
}
|
|
1032
|
+
function mergeCookie(existing, name, value) {
|
|
1033
|
+
const encoded = `${name}=${encodeURIComponent(value)}`;
|
|
1034
|
+
if (!existing?.trim())
|
|
1035
|
+
return encoded;
|
|
1036
|
+
const parts = existing.split(";").map((part) => part.trim()).filter((part) => part && !part.startsWith(`${name}=`));
|
|
1037
|
+
return [...parts, encoded].join("; ");
|
|
1038
|
+
}
|
|
1039
|
+
function queryAuthFallbackEnabled(env = process.env) {
|
|
1040
|
+
return env.RIG_ENABLE_QUERY_AUTH_FALLBACK === "1" || env.RIG_QUERY_AUTH_FALLBACK === "1";
|
|
1041
|
+
}
|
|
1015
1042
|
function mergeHeaders(headers, authToken) {
|
|
1016
1043
|
const merged = new Headers(headers);
|
|
1017
1044
|
if (authToken) {
|
|
1018
|
-
|
|
1045
|
+
const bearer = `Bearer ${authToken}`;
|
|
1046
|
+
merged.set("authorization", bearer);
|
|
1047
|
+
merged.set("x-auth", bearer);
|
|
1048
|
+
merged.set("cookie", mergeCookie(merged.get("cookie"), "rig_auth", authToken));
|
|
1019
1049
|
}
|
|
1020
1050
|
return merged;
|
|
1021
1051
|
}
|
|
@@ -1075,15 +1105,34 @@ async function buildServerFailureContext(projectRoot, server) {
|
|
|
1075
1105
|
hint: "Check the selected server with `rig server status`, or switch with `rig server use <alias|local>`."
|
|
1076
1106
|
};
|
|
1077
1107
|
}
|
|
1108
|
+
function isLoopbackRemoteBaseUrl(baseUrl) {
|
|
1109
|
+
try {
|
|
1110
|
+
const host = new URL(baseUrl).hostname.toLowerCase();
|
|
1111
|
+
return host === "localhost" || host === "127.0.0.1" || host === "::1" || host === "[::1]";
|
|
1112
|
+
} catch {
|
|
1113
|
+
return false;
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
function canUseRemoteWithoutProjectRoot(pathname) {
|
|
1117
|
+
return pathname === "/health" || pathname === "/api/health" || pathname === "/api/server/status" || pathname === "/api/server/project-root" || pathname.startsWith("/api/github/auth/") || pathname === "/api/projects" || pathname.startsWith("/api/projects/");
|
|
1118
|
+
}
|
|
1078
1119
|
async function requestServerJson(context, pathname, init = {}) {
|
|
1079
1120
|
const server = await ensureServerForCli(context.projectRoot);
|
|
1121
|
+
const requestUrl = new URL(`${server.baseUrl}${pathname}`);
|
|
1122
|
+
if (server.connectionKind === "remote" && !server.serverProjectRoot && !canUseRemoteWithoutProjectRoot(requestUrl.pathname) && (server.authToken || !isLoopbackRemoteBaseUrl(server.baseUrl))) {
|
|
1123
|
+
const repo = readRepoConnection(context.projectRoot);
|
|
1124
|
+
throw new CliError(`Remote server is selected for ${repo?.project ?? "this repo"}, but this checkout has no server-host project root link.`, 1, { hint: "Run `rig init --repair` or `rig init --yes --repo owner/repo --server remote` to repair the remote project link before task/run commands." });
|
|
1125
|
+
}
|
|
1080
1126
|
const headers = mergeHeaders(init.headers, server.authToken);
|
|
1081
1127
|
if (server.serverProjectRoot)
|
|
1082
1128
|
headers.set("x-rig-project-root", server.serverProjectRoot);
|
|
1129
|
+
if (server.connectionKind === "remote" && server.authToken && queryAuthFallbackEnabled()) {
|
|
1130
|
+
requestUrl.searchParams.set("rt", server.authToken);
|
|
1131
|
+
}
|
|
1083
1132
|
reportServerPhase(`${(init.method ?? "GET").toUpperCase()} ${pathname.split("?")[0]}\u2026`);
|
|
1084
1133
|
let response;
|
|
1085
1134
|
try {
|
|
1086
|
-
response = await fetch(
|
|
1135
|
+
response = await fetch(requestUrl, {
|
|
1087
1136
|
...init,
|
|
1088
1137
|
headers
|
|
1089
1138
|
});
|
|
@@ -1145,11 +1194,26 @@ async function getGitHubAuthStatusViaServer(context) {
|
|
|
1145
1194
|
return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : {};
|
|
1146
1195
|
}
|
|
1147
1196
|
async function postGitHubTokenViaServer(context, token, options = {}) {
|
|
1148
|
-
const
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1197
|
+
const server = await ensureServerForCli(context.projectRoot);
|
|
1198
|
+
const requestUrl = new URL(`${server.baseUrl}/api/github/auth/token`);
|
|
1199
|
+
reportServerPhase("POST /api/github/auth/token\u2026");
|
|
1200
|
+
let response;
|
|
1201
|
+
try {
|
|
1202
|
+
response = await fetch(requestUrl, {
|
|
1203
|
+
method: "POST",
|
|
1204
|
+
headers: { "content-type": "application/json" },
|
|
1205
|
+
body: JSON.stringify({ token, selectedRepo: options.selectedRepo, projectRoot: options.projectRoot ?? server.serverProjectRoot ?? undefined })
|
|
1206
|
+
});
|
|
1207
|
+
} catch (error) {
|
|
1208
|
+
const failure = await buildServerFailureContext(context.projectRoot, server);
|
|
1209
|
+
throw new CliError(`Rig server auth bootstrap failed: ${error instanceof Error ? error.message : String(error)}
|
|
1210
|
+
${failure.contextLine}`, 1, { hint: failure.hint });
|
|
1211
|
+
}
|
|
1212
|
+
const payload = await response.json().catch(() => null);
|
|
1213
|
+
if (!response.ok) {
|
|
1214
|
+
const detail = payload && typeof payload === "object" && !Array.isArray(payload) ? String(payload.error ?? JSON.stringify(payload)) : `HTTP ${response.status}`;
|
|
1215
|
+
throw new CliError(`Rig server auth bootstrap failed (${response.status}): ${detail}`, 1, { hint: "Re-run `rig github auth import-gh`, or check the selected server with `rig server status`." });
|
|
1216
|
+
}
|
|
1153
1217
|
return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : {};
|
|
1154
1218
|
}
|
|
1155
1219
|
async function prepareRemoteCheckoutViaServer(context, input) {
|
|
@@ -1480,7 +1544,8 @@ async function runFastTaskRunPreflight(context, options = {}) {
|
|
|
1480
1544
|
}
|
|
1481
1545
|
}
|
|
1482
1546
|
const repo = readRepoConnection(context.projectRoot);
|
|
1483
|
-
|
|
1547
|
+
const remoteWithoutProjectLink = selectedServer?.connectionKind === "remote" && !repo?.project;
|
|
1548
|
+
checks.push(repo ? preflightCheck("project-link", "project linked to selected server", repo.project ? "pass" : remoteWithoutProjectLink ? "fail" : "warn", `${repo.selected}${repo.project ? ` -> ${repo.project}` : " (missing project link)"}`, remoteWithoutProjectLink ? "Run `rig init --repair` or `rig init --yes --repo owner/repo --server remote` to restore the remote project link." : "Run `rig init --yes --repo owner/repo` to record the GitHub repo slug.") : preflightCheck("project-link", "project linked to selected server", legacyServerCompatibility ? "warn" : "fail", "missing .rig/state/connection.json", "Run `rig init` or `rig server use <alias|local>`."));
|
|
1484
1549
|
try {
|
|
1485
1550
|
const auth = await request("/api/github/auth/status");
|
|
1486
1551
|
checks.push(isAuthenticated(auth) ? preflightCheck("github-auth", "GitHub auth valid", "pass") : preflightCheck("github-auth", "GitHub auth valid", legacyServerCompatibility ? "warn" : "fail", "not authenticated", "Run `rig github auth import-gh` or `rig github auth token --token <token>`."));
|
|
@@ -2524,7 +2589,7 @@ var init__operator_surface = __esm(() => {
|
|
|
2524
2589
|
});
|
|
2525
2590
|
|
|
2526
2591
|
// packages/cli/src/commands/_pi-frontend.ts
|
|
2527
|
-
import { existsSync as existsSync14, mkdirSync as
|
|
2592
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync9, mkdtempSync, readFileSync as readFileSync10, rmSync as rmSync5, writeFileSync as writeFileSync7 } from "fs";
|
|
2528
2593
|
import { homedir as homedir6, tmpdir } from "os";
|
|
2529
2594
|
import { join as join3 } from "path";
|
|
2530
2595
|
import { main as runPiMain } from "@earendil-works/pi-coding-agent";
|
|
@@ -2559,7 +2624,7 @@ function buildOperatorPiEnv(input) {
|
|
|
2559
2624
|
async function prepareOperatorConsole(context, runId, tempSessionDir) {
|
|
2560
2625
|
const server = await ensureServerForCli(context.projectRoot);
|
|
2561
2626
|
const localCwd = join3(homedir6(), ".rig", "drones", runId.slice(0, 8));
|
|
2562
|
-
|
|
2627
|
+
mkdirSync9(localCwd, { recursive: true });
|
|
2563
2628
|
trustDroneCwd(localCwd);
|
|
2564
2629
|
installRigPiTheme();
|
|
2565
2630
|
let sessionFileArg = [];
|
|
@@ -2581,7 +2646,7 @@ async function prepareOperatorConsole(context, runId, tempSessionDir) {
|
|
|
2581
2646
|
return line;
|
|
2582
2647
|
}).join(`
|
|
2583
2648
|
`);
|
|
2584
|
-
|
|
2649
|
+
writeFileSync7(localSessionPath, content);
|
|
2585
2650
|
sessionFileArg = ["--session", localSessionPath];
|
|
2586
2651
|
}
|
|
2587
2652
|
} catch {}
|
|
@@ -2590,12 +2655,12 @@ async function prepareOperatorConsole(context, runId, tempSessionDir) {
|
|
|
2590
2655
|
function trustDroneCwd(localCwd) {
|
|
2591
2656
|
try {
|
|
2592
2657
|
const agentDir = join3(homedir6(), ".pi", "agent");
|
|
2593
|
-
|
|
2658
|
+
mkdirSync9(agentDir, { recursive: true });
|
|
2594
2659
|
const trustPath = join3(agentDir, "trust.json");
|
|
2595
2660
|
const store = existsSync14(trustPath) ? JSON.parse(readFileSync10(trustPath, "utf8")) : {};
|
|
2596
2661
|
if (store[localCwd] !== true) {
|
|
2597
2662
|
store[localCwd] = true;
|
|
2598
|
-
|
|
2663
|
+
writeFileSync7(trustPath, `${JSON.stringify(store, null, "\t")}
|
|
2599
2664
|
`);
|
|
2600
2665
|
}
|
|
2601
2666
|
} catch {}
|
|
@@ -2603,12 +2668,12 @@ function trustDroneCwd(localCwd) {
|
|
|
2603
2668
|
function installRigPiTheme() {
|
|
2604
2669
|
try {
|
|
2605
2670
|
const themesDir = join3(homedir6(), ".pi", "agent", "themes");
|
|
2606
|
-
|
|
2671
|
+
mkdirSync9(themesDir, { recursive: true });
|
|
2607
2672
|
const themePath = join3(themesDir, "rig.json");
|
|
2608
2673
|
const next = `${JSON.stringify(RIG_PI_THEME, null, "\t")}
|
|
2609
2674
|
`;
|
|
2610
2675
|
if (!existsSync14(themePath) || readFileSync10(themePath, "utf8") !== next) {
|
|
2611
|
-
|
|
2676
|
+
writeFileSync7(themePath, next);
|
|
2612
2677
|
}
|
|
2613
2678
|
} catch {}
|
|
2614
2679
|
}
|
|
@@ -2628,6 +2693,7 @@ async function attachRunBundledPiFrontend(context, input) {
|
|
|
2628
2693
|
let detached = false;
|
|
2629
2694
|
try {
|
|
2630
2695
|
await runPiMain([
|
|
2696
|
+
"--offline",
|
|
2631
2697
|
"--no-extensions",
|
|
2632
2698
|
"--no-skills",
|
|
2633
2699
|
"--no-prompt-templates",
|
|
@@ -3298,7 +3364,7 @@ var init__task_picker = __esm(() => {
|
|
|
3298
3364
|
// packages/cli/src/commands/task.ts
|
|
3299
3365
|
import { readFileSync as readFileSync11 } from "fs";
|
|
3300
3366
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
3301
|
-
import { resolve as
|
|
3367
|
+
import { resolve as resolve22 } from "path";
|
|
3302
3368
|
import {
|
|
3303
3369
|
taskArtifactDir,
|
|
3304
3370
|
taskArtifacts,
|
|
@@ -3576,7 +3642,7 @@ async function executeTask(context, args, options) {
|
|
|
3576
3642
|
const fileFlag = takeOption(rest.slice(1), "--file");
|
|
3577
3643
|
let content;
|
|
3578
3644
|
if (fileFlag.value) {
|
|
3579
|
-
content = readFileSync11(
|
|
3645
|
+
content = readFileSync11(resolve22(context.projectRoot, fileFlag.value), "utf-8");
|
|
3580
3646
|
} else {
|
|
3581
3647
|
content = await readStdin();
|
|
3582
3648
|
}
|
|
@@ -4657,11 +4723,11 @@ async function runOperatorBoard(context, options = {}) {
|
|
|
4657
4723
|
}, BOARD_REFRESH_MS);
|
|
4658
4724
|
tui.start();
|
|
4659
4725
|
refresh({ quiet: true });
|
|
4660
|
-
await new Promise((
|
|
4726
|
+
await new Promise((resolve25) => {
|
|
4661
4727
|
const poll = setInterval(() => {
|
|
4662
4728
|
if (stopped) {
|
|
4663
4729
|
clearInterval(poll);
|
|
4664
|
-
|
|
4730
|
+
resolve25();
|
|
4665
4731
|
}
|
|
4666
4732
|
}, 50);
|
|
4667
4733
|
});
|
|
@@ -4695,7 +4761,7 @@ import {
|
|
|
4695
4761
|
existsSync as existsSync18,
|
|
4696
4762
|
readFileSync as readFileSync13
|
|
4697
4763
|
} from "fs";
|
|
4698
|
-
import { resolve as
|
|
4764
|
+
import { resolve as resolve25 } from "path";
|
|
4699
4765
|
import { readBuildConfig } from "@rig/runtime/build-time-config";
|
|
4700
4766
|
|
|
4701
4767
|
// packages/cli/src/commands/browser.ts
|
|
@@ -8923,14 +8989,64 @@ Usage: rig init`, 1);
|
|
|
8923
8989
|
// packages/cli/src/commands/github.ts
|
|
8924
8990
|
init_runner();
|
|
8925
8991
|
init__server_client();
|
|
8992
|
+
init__connection_state();
|
|
8926
8993
|
init__async_ui();
|
|
8927
8994
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
8995
|
+
import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync6 } from "fs";
|
|
8996
|
+
import { dirname as dirname4, resolve as resolve18 } from "path";
|
|
8928
8997
|
function printPayload(context, payload, fallback) {
|
|
8929
8998
|
if (context.outputMode === "json")
|
|
8930
8999
|
console.log(JSON.stringify(payload, null, 2));
|
|
8931
9000
|
else
|
|
8932
9001
|
console.log(fallback);
|
|
8933
9002
|
}
|
|
9003
|
+
function apiSessionTokenFrom2(payload) {
|
|
9004
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload))
|
|
9005
|
+
return null;
|
|
9006
|
+
const token = payload.apiSessionToken;
|
|
9007
|
+
return typeof token === "string" && token.trim() ? token.trim() : null;
|
|
9008
|
+
}
|
|
9009
|
+
function payloadString(payload, key) {
|
|
9010
|
+
const value = payload[key];
|
|
9011
|
+
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
9012
|
+
}
|
|
9013
|
+
function payloadRecord(payload, key) {
|
|
9014
|
+
const value = payload[key];
|
|
9015
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
9016
|
+
}
|
|
9017
|
+
function remoteNamespaceMetadata(result) {
|
|
9018
|
+
const namespace = payloadRecord(result, "userNamespace");
|
|
9019
|
+
return {
|
|
9020
|
+
...payloadString(result, "login") ? { login: payloadString(result, "login") } : {},
|
|
9021
|
+
...payloadString(result, "userId") ? { userId: payloadString(result, "userId") } : {},
|
|
9022
|
+
...namespace && payloadString(namespace, "key") ? { userNamespaceKey: payloadString(namespace, "key") } : {},
|
|
9023
|
+
...namespace && payloadString(namespace, "root") ? { userNamespaceRoot: payloadString(namespace, "root") } : {},
|
|
9024
|
+
...namespace && payloadString(namespace, "checkoutBaseDir") ? { checkoutBaseDir: payloadString(namespace, "checkoutBaseDir") } : {},
|
|
9025
|
+
...namespace && payloadString(namespace, "snapshotBaseDir") ? { snapshotBaseDir: payloadString(namespace, "snapshotBaseDir") } : {}
|
|
9026
|
+
};
|
|
9027
|
+
}
|
|
9028
|
+
function persistRemoteAuthSession(context, source, result, fallbackToken) {
|
|
9029
|
+
const apiSessionToken = apiSessionTokenFrom2(result);
|
|
9030
|
+
setGitHubBearerTokenForCurrentProcess(apiSessionToken ?? fallbackToken, context.projectRoot);
|
|
9031
|
+
if (!apiSessionToken)
|
|
9032
|
+
return;
|
|
9033
|
+
const repo = readRepoConnection(context.projectRoot);
|
|
9034
|
+
const path = resolve18(context.projectRoot, ".rig", "state", "github-auth.json");
|
|
9035
|
+
mkdirSync8(dirname4(path), { recursive: true });
|
|
9036
|
+
writeFileSync6(path, `${JSON.stringify({
|
|
9037
|
+
authenticated: true,
|
|
9038
|
+
source,
|
|
9039
|
+
storedOnServer: true,
|
|
9040
|
+
...repo?.project ? { selectedRepo: repo.project } : {},
|
|
9041
|
+
...remoteNamespaceMetadata(result),
|
|
9042
|
+
apiSessionToken,
|
|
9043
|
+
updatedAt: new Date().toISOString()
|
|
9044
|
+
}, null, 2)}
|
|
9045
|
+
`, "utf8");
|
|
9046
|
+
}
|
|
9047
|
+
function isSignedIn(status) {
|
|
9048
|
+
return status.signedIn === true || status.authenticated === true;
|
|
9049
|
+
}
|
|
8934
9050
|
function readGhToken() {
|
|
8935
9051
|
const result = spawnSync2("gh", ["auth", "token"], { encoding: "utf8" });
|
|
8936
9052
|
if (result.status !== 0) {
|
|
@@ -8952,7 +9068,7 @@ async function executeGithub(context, args) {
|
|
|
8952
9068
|
if (rest.length > 0)
|
|
8953
9069
|
throw new CliError("Usage: rig github auth status", 1);
|
|
8954
9070
|
const status = await withSpinner("Checking GitHub auth on the server\u2026", () => getGitHubAuthStatusViaServer(context), { outputMode: context.outputMode });
|
|
8955
|
-
printPayload(context, status, `GitHub auth: ${status
|
|
9071
|
+
printPayload(context, status, `GitHub auth: ${isSignedIn(status) ? "authenticated" : "unauthenticated"}`);
|
|
8956
9072
|
return { ok: true, group: "github", command: "auth status", details: status };
|
|
8957
9073
|
}
|
|
8958
9074
|
case "token": {
|
|
@@ -8962,16 +9078,20 @@ async function executeGithub(context, args) {
|
|
|
8962
9078
|
const token = parsed.value?.trim();
|
|
8963
9079
|
if (!token)
|
|
8964
9080
|
throw new CliError("Missing --token value.", 1, { hint: "Re-run as `rig github auth token --token <token>`." });
|
|
8965
|
-
const
|
|
8966
|
-
|
|
9081
|
+
const repo = readRepoConnection(context.projectRoot);
|
|
9082
|
+
const result = await withSpinner("Storing GitHub token on the server\u2026", () => postGitHubTokenViaServer(context, token, repo?.project ? { selectedRepo: repo.project } : {}), { outputMode: context.outputMode });
|
|
9083
|
+
persistRemoteAuthSession(context, "token", result, token);
|
|
9084
|
+
printPayload(context, result, "GitHub token stored on the selected server.");
|
|
8967
9085
|
return { ok: true, group: "github", command: "auth token", details: result };
|
|
8968
9086
|
}
|
|
8969
9087
|
case "import-gh": {
|
|
8970
9088
|
if (rest.length > 0)
|
|
8971
9089
|
throw new CliError("Usage: rig github auth import-gh", 1);
|
|
8972
9090
|
const importedToken = readGhToken();
|
|
8973
|
-
const
|
|
8974
|
-
|
|
9091
|
+
const repo = readRepoConnection(context.projectRoot);
|
|
9092
|
+
const result = await withSpinner("Storing GitHub token on the server\u2026", () => postGitHubTokenViaServer(context, importedToken, repo?.project ? { selectedRepo: repo.project } : {}), { outputMode: context.outputMode });
|
|
9093
|
+
persistRemoteAuthSession(context, "gh", result, importedToken);
|
|
9094
|
+
printPayload(context, result, "GitHub token imported from gh and stored on the selected server.");
|
|
8975
9095
|
return { ok: true, group: "github", command: "auth import-gh", details: result };
|
|
8976
9096
|
}
|
|
8977
9097
|
default:
|
|
@@ -9001,7 +9121,7 @@ init_runner();
|
|
|
9001
9121
|
init__authority_runs();
|
|
9002
9122
|
init__paths();
|
|
9003
9123
|
import { readFileSync as readFileSync8 } from "fs";
|
|
9004
|
-
import { resolve as
|
|
9124
|
+
import { resolve as resolve19 } from "path";
|
|
9005
9125
|
import {
|
|
9006
9126
|
appendRunJournalEvent,
|
|
9007
9127
|
appendRunLogEntry,
|
|
@@ -9038,7 +9158,7 @@ function touchAuthorityRun(projectRoot, runId) {
|
|
|
9038
9158
|
if (!current) {
|
|
9039
9159
|
return;
|
|
9040
9160
|
}
|
|
9041
|
-
writeJsonFile3(
|
|
9161
|
+
writeJsonFile3(resolve19(resolveAuthorityRunDir(projectRoot, runId), "run.json"), {
|
|
9042
9162
|
...current,
|
|
9043
9163
|
updatedAt: new Date().toISOString()
|
|
9044
9164
|
});
|
|
@@ -9276,7 +9396,7 @@ init_runner();
|
|
|
9276
9396
|
init__server_client();
|
|
9277
9397
|
init__async_ui();
|
|
9278
9398
|
import { existsSync as existsSync12, readFileSync as readFileSync9 } from "fs";
|
|
9279
|
-
import { resolve as
|
|
9399
|
+
import { resolve as resolve20 } from "path";
|
|
9280
9400
|
import {
|
|
9281
9401
|
listAuthorityRuns,
|
|
9282
9402
|
readAuthorityRun as readAuthorityRun3,
|
|
@@ -9320,7 +9440,7 @@ async function executeInspect(context, args) {
|
|
|
9320
9440
|
}
|
|
9321
9441
|
return { ok: true, group: "inspect", command, details: { task: requiredTask, runId: fallback.runId, source: "server", entries } };
|
|
9322
9442
|
}
|
|
9323
|
-
const logsPath =
|
|
9443
|
+
const logsPath = resolve20(resolveAuthorityRunDir2(context.projectRoot, latestRun.runId), "logs.jsonl");
|
|
9324
9444
|
if (!existsSync12(logsPath)) {
|
|
9325
9445
|
throw new CliError(`No logs found for run ${latestRun.runId}.`, 1, { hint: `Try \`rig run show ${latestRun.runId}\` or \`rig run replay ${latestRun.runId}\`.` });
|
|
9326
9446
|
}
|
|
@@ -9408,7 +9528,7 @@ async function executeInspect(context, args) {
|
|
|
9408
9528
|
return { ok: true, group: "inspect", command };
|
|
9409
9529
|
case "audit": {
|
|
9410
9530
|
requireNoExtraArgs(rest, "rig inspect audit");
|
|
9411
|
-
const auditPath =
|
|
9531
|
+
const auditPath = resolve20(resolveHarnessPaths2(context.projectRoot).logsDir, "audit.jsonl");
|
|
9412
9532
|
if (!existsSync12(auditPath)) {
|
|
9413
9533
|
console.log("No audit log found.");
|
|
9414
9534
|
} else {
|
|
@@ -10067,7 +10187,7 @@ import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/co
|
|
|
10067
10187
|
|
|
10068
10188
|
// packages/cli/src/commands/_run-replay.ts
|
|
10069
10189
|
import { existsSync as existsSync13, readdirSync as readdirSync2 } from "fs";
|
|
10070
|
-
import { join as join2, resolve as
|
|
10190
|
+
import { join as join2, resolve as resolve21 } from "path";
|
|
10071
10191
|
import {
|
|
10072
10192
|
readAuthorityRun as readAuthorityRun4,
|
|
10073
10193
|
readJsonlFile as readJsonlFile3,
|
|
@@ -10160,7 +10280,7 @@ function resolveRunSessionFile(record) {
|
|
|
10160
10280
|
const sessionId = text(piSession.sessionId);
|
|
10161
10281
|
if (!cwd || !sessionId)
|
|
10162
10282
|
return null;
|
|
10163
|
-
const sessionDir =
|
|
10283
|
+
const sessionDir = resolve21(cwd, ".rig", "session");
|
|
10164
10284
|
try {
|
|
10165
10285
|
const match = readdirSync2(sessionDir).find((name) => name.endsWith(`_${sessionId}.jsonl`));
|
|
10166
10286
|
return match ? join2(sessionDir, match) : null;
|
|
@@ -10658,6 +10778,9 @@ async function executeRun(context, args) {
|
|
|
10658
10778
|
console.log(`Stop requested: ${runId}`);
|
|
10659
10779
|
return { ok: true, group: "run", command, details: stopped };
|
|
10660
10780
|
}
|
|
10781
|
+
if (isRemoteConnectionSelected(context.projectRoot)) {
|
|
10782
|
+
throw new CliError("Remote run stop requires an explicit run id.", 2, { hint: "Run `rig run list`, then `rig run stop <run-id>`." });
|
|
10783
|
+
}
|
|
10661
10784
|
const result = await runStop(context.projectRoot);
|
|
10662
10785
|
if (result.remaining.length > 0) {
|
|
10663
10786
|
throw new CliError(`Failed to stop run(s): ${result.remaining.join(", ")}`, 1, { hint: "Check `rig run status`, then retry `rig run stop <run-id>` for the remaining runs." });
|
|
@@ -10774,7 +10897,13 @@ async function executeConnectionCommand(context, args, options) {
|
|
|
10774
10897
|
if (!state.connections[alias])
|
|
10775
10898
|
throw new CliError(`Unknown Rig server: ${alias}`, 1, { hint: "Run `rig server list` to see saved aliases, or save one with `rig server add <alias> <url>`." });
|
|
10776
10899
|
}
|
|
10777
|
-
const
|
|
10900
|
+
const previousRepo = readRepoConnection(context.projectRoot);
|
|
10901
|
+
const repoState = {
|
|
10902
|
+
selected: alias,
|
|
10903
|
+
...previousRepo?.project ? { project: previousRepo.project } : {},
|
|
10904
|
+
linkedAt: new Date().toISOString(),
|
|
10905
|
+
...previousRepo?.serverProjectRoot && previousRepo.selected === alias ? { serverProjectRoot: previousRepo.serverProjectRoot } : {}
|
|
10906
|
+
};
|
|
10778
10907
|
writeRepoConnection(context.projectRoot, repoState);
|
|
10779
10908
|
printJsonOrText(context, repoState, formatSuccessCard("Rig server selected", [
|
|
10780
10909
|
["selected", alias],
|
|
@@ -11009,8 +11138,8 @@ init_task();
|
|
|
11009
11138
|
|
|
11010
11139
|
// packages/cli/src/commands/task-run-driver.ts
|
|
11011
11140
|
init_runner();
|
|
11012
|
-
import { copyFileSync as copyFileSync3, existsSync as existsSync15, mkdirSync as
|
|
11013
|
-
import { resolve as
|
|
11141
|
+
import { copyFileSync as copyFileSync3, existsSync as existsSync15, mkdirSync as mkdirSync10, readFileSync as readFileSync12, statSync as statSync2, writeFileSync as writeFileSync8 } from "fs";
|
|
11142
|
+
import { resolve as resolve23 } from "path";
|
|
11014
11143
|
import { spawn as spawn2, spawnSync as spawnSync4 } from "child_process";
|
|
11015
11144
|
import { createInterface as createLineInterface } from "readline";
|
|
11016
11145
|
import { loadConfig as loadConfig2 } from "@rig/core/load-config";
|
|
@@ -11109,12 +11238,12 @@ function copyUntrackedDirtyFiles(sourceRoot, targetRoot) {
|
|
|
11109
11238
|
return 0;
|
|
11110
11239
|
let copied = 0;
|
|
11111
11240
|
for (const relativePath of listed.stdout.split("\x00").filter(Boolean)) {
|
|
11112
|
-
const sourcePath =
|
|
11113
|
-
const targetPath =
|
|
11241
|
+
const sourcePath = resolve23(sourceRoot, relativePath);
|
|
11242
|
+
const targetPath = resolve23(targetRoot, relativePath);
|
|
11114
11243
|
try {
|
|
11115
11244
|
if (!statSync2(sourcePath).isFile())
|
|
11116
11245
|
continue;
|
|
11117
|
-
|
|
11246
|
+
mkdirSync10(resolve23(targetPath, ".."), { recursive: true });
|
|
11118
11247
|
copyFileSync3(sourcePath, targetPath);
|
|
11119
11248
|
copied += 1;
|
|
11120
11249
|
} catch {}
|
|
@@ -11153,7 +11282,7 @@ function buildDirtyBaselineHandshakeEnv(input) {
|
|
|
11153
11282
|
return { RIG_BASELINE_MODE: input.baselineMode ?? "head" };
|
|
11154
11283
|
return {
|
|
11155
11284
|
RIG_BASELINE_MODE: "dirty-snapshot",
|
|
11156
|
-
RIG_DIRTY_BASELINE_READY_FILE:
|
|
11285
|
+
RIG_DIRTY_BASELINE_READY_FILE: resolve23(input.projectRoot, ".rig", "runs", input.runId, "dirty-baseline.ready.json")
|
|
11157
11286
|
};
|
|
11158
11287
|
}
|
|
11159
11288
|
function positiveInt(value, fallback) {
|
|
@@ -11258,9 +11387,9 @@ function createCommandRunner(binary) {
|
|
|
11258
11387
|
const stderrChunks = [];
|
|
11259
11388
|
child.stdout.on("data", (chunk) => stdoutChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk))));
|
|
11260
11389
|
child.stderr.on("data", (chunk) => stderrChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk))));
|
|
11261
|
-
return await new Promise((
|
|
11262
|
-
child.once("error", (error) =>
|
|
11263
|
-
child.once("close", (code) =>
|
|
11390
|
+
return await new Promise((resolve24) => {
|
|
11391
|
+
child.once("error", (error) => resolve24({ exitCode: 1, stderr: error.message }));
|
|
11392
|
+
child.once("close", (code) => resolve24({
|
|
11264
11393
|
exitCode: code ?? 1,
|
|
11265
11394
|
stdout: Buffer.concat(stdoutChunks).toString("utf8"),
|
|
11266
11395
|
stderr: Buffer.concat(stderrChunks).toString("utf8")
|
|
@@ -11334,7 +11463,7 @@ async function runTaskRunPostValidationLifecycle(input) {
|
|
|
11334
11463
|
config,
|
|
11335
11464
|
sourceTask: input.sourceTask,
|
|
11336
11465
|
uploadedSnapshot: input.uploadedSnapshot,
|
|
11337
|
-
artifactRoot:
|
|
11466
|
+
artifactRoot: resolve23(input.projectRoot, "artifacts", taskId3),
|
|
11338
11467
|
command: ghCommand,
|
|
11339
11468
|
gitCommand,
|
|
11340
11469
|
steerPi,
|
|
@@ -11464,7 +11593,7 @@ function summarizeValidationFailure(projectRoot, taskId3) {
|
|
|
11464
11593
|
return null;
|
|
11465
11594
|
}
|
|
11466
11595
|
for (const artifactDir of resolveTaskArtifactDirs2(projectRoot, taskId3)) {
|
|
11467
|
-
const summary = readJsonFile3(
|
|
11596
|
+
const summary = readJsonFile3(resolve23(artifactDir, "validation-summary.json"), null);
|
|
11468
11597
|
if (!summary || summary.status !== "fail") {
|
|
11469
11598
|
continue;
|
|
11470
11599
|
}
|
|
@@ -11545,9 +11674,9 @@ function readTaskRunAcceptedArtifactState(input) {
|
|
|
11545
11674
|
if (!input.taskId || !input.workspaceDir) {
|
|
11546
11675
|
return { accepted: false, reason: null };
|
|
11547
11676
|
}
|
|
11548
|
-
const artifactDir =
|
|
11549
|
-
const reviewStatusPath =
|
|
11550
|
-
const taskResultPath =
|
|
11677
|
+
const artifactDir = resolve23(input.workspaceDir, "artifacts", input.taskId);
|
|
11678
|
+
const reviewStatusPath = resolve23(artifactDir, "review-status.txt");
|
|
11679
|
+
const taskResultPath = resolve23(artifactDir, "task-result.json");
|
|
11551
11680
|
const reviewStatus = readTaskRunReviewStatus(reviewStatusPath);
|
|
11552
11681
|
if (reviewStatus !== "APPROVED") {
|
|
11553
11682
|
return { accepted: false, reason: null };
|
|
@@ -11584,12 +11713,12 @@ function resolveTaskRunRetryContext(input) {
|
|
|
11584
11713
|
if (!input.taskId || !input.workspaceDir) {
|
|
11585
11714
|
return { shouldRetry: false, failureDetail: null, nextPrompt: null };
|
|
11586
11715
|
}
|
|
11587
|
-
const artifactDir =
|
|
11588
|
-
const reviewStatePath =
|
|
11589
|
-
const reviewFeedbackPath =
|
|
11590
|
-
const reviewStatusPath =
|
|
11591
|
-
const failedApproachesPath =
|
|
11592
|
-
const validationSummaryPath =
|
|
11716
|
+
const artifactDir = resolve23(input.workspaceDir, "artifacts", input.taskId);
|
|
11717
|
+
const reviewStatePath = resolve23(artifactDir, "review-state.json");
|
|
11718
|
+
const reviewFeedbackPath = resolve23(artifactDir, "review-feedback.md");
|
|
11719
|
+
const reviewStatusPath = resolve23(artifactDir, "review-status.txt");
|
|
11720
|
+
const failedApproachesPath = resolve23(input.workspaceDir, ".rig", "state", "failed_approaches.md");
|
|
11721
|
+
const validationSummaryPath = resolve23(artifactDir, "validation-summary.json");
|
|
11593
11722
|
const reviewState = readJsonFile3(reviewStatePath, null);
|
|
11594
11723
|
const reviewStatus = readTaskRunReviewStatus(reviewStatusPath);
|
|
11595
11724
|
const reviewRejected = isTaskRunReviewRejected(reviewState);
|
|
@@ -11999,15 +12128,15 @@ async function executeRigOwnedTaskRun(context, input) {
|
|
|
11999
12128
|
const loadedAutomationConfig = await loadTaskRunAutomationConfig(context.projectRoot);
|
|
12000
12129
|
const automationConfig = input.prMode ? { ...loadedAutomationConfig ?? {}, pr: { ...loadedAutomationConfig?.pr ?? {}, mode: input.prMode } } : loadedAutomationConfig;
|
|
12001
12130
|
const planningClassification = classifyPlanningNeed({ config: automationConfig, sourceTask });
|
|
12002
|
-
const planningArtifactPath =
|
|
12131
|
+
const planningArtifactPath = resolve23("artifacts", runtimeTaskId, "implementation-plan.md");
|
|
12003
12132
|
const persistedPlanning = {
|
|
12004
12133
|
...planningClassification,
|
|
12005
12134
|
classifier: input.runtimeAdapter === "pi" ? "pi-rig-structured-policy" : "rig-structured-policy",
|
|
12006
12135
|
artifactPath: planningClassification.planningRequired ? planningArtifactPath : null,
|
|
12007
12136
|
classifiedAt: new Date().toISOString()
|
|
12008
12137
|
};
|
|
12009
|
-
|
|
12010
|
-
|
|
12138
|
+
mkdirSync10(resolve23(context.projectRoot, ".rig", "runs", input.runId), { recursive: true });
|
|
12139
|
+
writeFileSync8(resolve23(context.projectRoot, ".rig", "runs", input.runId, "planning-classification.json"), `${JSON.stringify(persistedPlanning, null, 2)}
|
|
12011
12140
|
`, "utf8");
|
|
12012
12141
|
patchAuthorityRun(context.projectRoot, input.runId, { planning: persistedPlanning });
|
|
12013
12142
|
prompt = `${prompt}
|
|
@@ -12057,7 +12186,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
12057
12186
|
let verificationStarted = false;
|
|
12058
12187
|
let reviewStarted = false;
|
|
12059
12188
|
let latestRuntimeWorkspace = resumeMode && typeof existingRunRecord?.worktreePath === "string" ? existingRunRecord.worktreePath : null;
|
|
12060
|
-
let latestSessionDir = resumeMode && typeof existingRunRecord?.sessionPath === "string" ?
|
|
12189
|
+
let latestSessionDir = resumeMode && typeof existingRunRecord?.sessionPath === "string" ? resolve23(existingRunRecord.sessionPath, "..") : null;
|
|
12061
12190
|
let latestLogsDir = resumeMode && typeof existingRunRecord?.logRoot === "string" ? existingRunRecord.logRoot : null;
|
|
12062
12191
|
let latestProviderCommand = null;
|
|
12063
12192
|
let latestRuntimeBranch = resumeMode && typeof existingRunRecord?.branch === "string" ? existingRunRecord.branch : null;
|
|
@@ -12143,10 +12272,10 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
12143
12272
|
setRunStatusOrFail(context.projectRoot, input.runId, "running");
|
|
12144
12273
|
patchAuthorityRun(context.projectRoot, input.runId, {
|
|
12145
12274
|
worktreePath: latestRuntimeWorkspace,
|
|
12146
|
-
artifactRoot: latestRuntimeWorkspace && input.taskId ?
|
|
12275
|
+
artifactRoot: latestRuntimeWorkspace && input.taskId ? resolve23(latestRuntimeWorkspace, "artifacts", input.taskId) : null,
|
|
12147
12276
|
logRoot: latestLogsDir,
|
|
12148
|
-
sessionPath: latestSessionDir ?
|
|
12149
|
-
sessionLogPath: latestLogsDir ?
|
|
12277
|
+
sessionPath: latestSessionDir ? resolve23(latestSessionDir, "session.json") : null,
|
|
12278
|
+
sessionLogPath: latestLogsDir ? resolve23(latestLogsDir, "agent-stdout.log") : null,
|
|
12150
12279
|
branch: runtimeId
|
|
12151
12280
|
});
|
|
12152
12281
|
if (!dirtyBaselineApplied && input.baselineMode === "dirty-snapshot" && latestRuntimeWorkspace) {
|
|
@@ -12154,8 +12283,8 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
12154
12283
|
const dirty = applyDirtyBaselineSnapshot({ sourceRoot: context.projectRoot, targetRoot: latestRuntimeWorkspace });
|
|
12155
12284
|
const readyFile = childEnv.RIG_DIRTY_BASELINE_READY_FILE;
|
|
12156
12285
|
if (readyFile) {
|
|
12157
|
-
|
|
12158
|
-
|
|
12286
|
+
mkdirSync10(resolve23(readyFile, ".."), { recursive: true });
|
|
12287
|
+
writeFileSync8(readyFile, `${JSON.stringify({ ...dirty, workspaceDir: latestRuntimeWorkspace, appliedAt: new Date().toISOString() }, null, 2)}
|
|
12159
12288
|
`, "utf8");
|
|
12160
12289
|
}
|
|
12161
12290
|
appendRunLog(context.projectRoot, input.runId, {
|
|
@@ -12551,7 +12680,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
12551
12680
|
let acceptedArtifactObservedAt = null;
|
|
12552
12681
|
let acceptedArtifactPollTimer = null;
|
|
12553
12682
|
let acceptedArtifactKillTimer = null;
|
|
12554
|
-
const attemptExit = await new Promise((
|
|
12683
|
+
const attemptExit = await new Promise((resolve24) => {
|
|
12555
12684
|
let settled = false;
|
|
12556
12685
|
const settle = (result) => {
|
|
12557
12686
|
if (settled)
|
|
@@ -12559,7 +12688,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
12559
12688
|
settled = true;
|
|
12560
12689
|
if (acceptedArtifactPollTimer)
|
|
12561
12690
|
clearInterval(acceptedArtifactPollTimer);
|
|
12562
|
-
|
|
12691
|
+
resolve24(result);
|
|
12563
12692
|
};
|
|
12564
12693
|
const pollAcceptedArtifacts = () => {
|
|
12565
12694
|
const artifactState = readTaskRunAcceptedArtifactState({
|
|
@@ -12762,7 +12891,7 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
|
|
|
12762
12891
|
}
|
|
12763
12892
|
if (planningClassification.planningRequired) {
|
|
12764
12893
|
const planWorkspace = latestRuntimeWorkspace ?? context.projectRoot;
|
|
12765
|
-
const expectedPlanPath =
|
|
12894
|
+
const expectedPlanPath = resolve23(planWorkspace, planningArtifactPath);
|
|
12766
12895
|
if (!existsSync15(expectedPlanPath)) {
|
|
12767
12896
|
const failedAt = new Date().toISOString();
|
|
12768
12897
|
const failureDetail = `Planning was required (${planningClassification.reason}) but ${planningArtifactPath} was not written before implementation completed.`;
|
|
@@ -12932,9 +13061,9 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
|
|
|
12932
13061
|
});
|
|
12933
13062
|
emitServerRunEvent({ type: "log", runId: input.runId, title: "Pi PR feedback fix stderr" });
|
|
12934
13063
|
});
|
|
12935
|
-
const exitCode = await new Promise((
|
|
12936
|
-
child.once("error", () =>
|
|
12937
|
-
child.once("close", (code) =>
|
|
13064
|
+
const exitCode = await new Promise((resolve24) => {
|
|
13065
|
+
child.once("error", () => resolve24(1));
|
|
13066
|
+
child.once("close", (code) => resolve24(code ?? 1));
|
|
12938
13067
|
});
|
|
12939
13068
|
for (const pendingLog of flushPendingClaudeToolUseLogs({
|
|
12940
13069
|
runId: input.runId,
|
|
@@ -13075,8 +13204,8 @@ async function executeTest(context, args) {
|
|
|
13075
13204
|
init_runner();
|
|
13076
13205
|
init__parsers();
|
|
13077
13206
|
init__paths();
|
|
13078
|
-
import { existsSync as existsSync16, mkdirSync as
|
|
13079
|
-
import { resolve as
|
|
13207
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync11, readdirSync as readdirSync3, writeFileSync as writeFileSync9 } from "fs";
|
|
13208
|
+
import { resolve as resolve24 } from "path";
|
|
13080
13209
|
import { createPluginHost } from "@rig/core";
|
|
13081
13210
|
import {
|
|
13082
13211
|
isSupportedBunVersion as isSupportedBunVersion2,
|
|
@@ -13131,12 +13260,12 @@ function runSetupInit(projectRoot) {
|
|
|
13131
13260
|
const stateDir = resolveControlPlaneHostStateDir(projectRoot);
|
|
13132
13261
|
const logsDir = resolveControlPlaneHostLogsDir(projectRoot);
|
|
13133
13262
|
const artifactsDir = resolveControlPlaneArtifactsDir(projectRoot);
|
|
13134
|
-
|
|
13135
|
-
|
|
13136
|
-
|
|
13137
|
-
const failuresPath =
|
|
13263
|
+
mkdirSync11(stateDir, { recursive: true });
|
|
13264
|
+
mkdirSync11(logsDir, { recursive: true });
|
|
13265
|
+
mkdirSync11(artifactsDir, { recursive: true });
|
|
13266
|
+
const failuresPath = resolve24(stateDir, "failed_approaches.md");
|
|
13138
13267
|
if (!existsSync16(failuresPath)) {
|
|
13139
|
-
|
|
13268
|
+
writeFileSync9(failuresPath, `# Failed Approaches
|
|
13140
13269
|
|
|
13141
13270
|
`, "utf-8");
|
|
13142
13271
|
}
|
|
@@ -13153,17 +13282,17 @@ async function runSetupCheck(projectRoot, outputMode = "text") {
|
|
|
13153
13282
|
}
|
|
13154
13283
|
async function runSetupPreflight(projectRoot, outputMode = "text") {
|
|
13155
13284
|
await runSetupCheck(projectRoot, outputMode);
|
|
13156
|
-
const validationRoot =
|
|
13285
|
+
const validationRoot = resolve24(resolveControlPlaneDefinitionRoot(projectRoot), "validation");
|
|
13157
13286
|
if (existsSync16(validationRoot)) {
|
|
13158
13287
|
const validators = readdirSync3(validationRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory());
|
|
13159
13288
|
for (const validator of validators) {
|
|
13160
|
-
const script =
|
|
13289
|
+
const script = resolve24(validationRoot, validator.name, "validate.sh");
|
|
13161
13290
|
if (existsSync16(script)) {
|
|
13162
13291
|
console.log(`OK: validator script ${script}`);
|
|
13163
13292
|
}
|
|
13164
13293
|
}
|
|
13165
13294
|
}
|
|
13166
|
-
const hooksRoot =
|
|
13295
|
+
const hooksRoot = resolve24(resolveControlPlaneDefinitionRoot(projectRoot), "hooks");
|
|
13167
13296
|
if (existsSync16(hooksRoot)) {
|
|
13168
13297
|
const hooks = readdirSync3(hooksRoot).filter((name) => name.endsWith(".sh"));
|
|
13169
13298
|
for (const hook of hooks) {
|
|
@@ -13310,7 +13439,7 @@ var PROJECT_REQUIRED_GROUPS = new Set([
|
|
|
13310
13439
|
]);
|
|
13311
13440
|
var RIG_CONFIG_FILENAMES = ["rig.config.ts", "rig.config.mts", "rig.config.json"];
|
|
13312
13441
|
function hasInitializedRigProject(projectRoot) {
|
|
13313
|
-
return RIG_CONFIG_FILENAMES.some((name) => existsSync18(
|
|
13442
|
+
return RIG_CONFIG_FILENAMES.some((name) => existsSync18(resolve25(projectRoot, name))) || existsSync18(resolve25(projectRoot, ".rig"));
|
|
13314
13443
|
}
|
|
13315
13444
|
function requireInitializedRigProject(context, group) {
|
|
13316
13445
|
if (hasInitializedRigProject(context.projectRoot)) {
|
|
@@ -13364,7 +13493,7 @@ function resolveTopLevelLaunchState(context) {
|
|
|
13364
13493
|
let selectedServer = null;
|
|
13365
13494
|
if (projectInitialized) {
|
|
13366
13495
|
try {
|
|
13367
|
-
const statePath =
|
|
13496
|
+
const statePath = resolve25(context.projectRoot, ".rig", "state", "connection.json");
|
|
13368
13497
|
if (existsSync18(statePath)) {
|
|
13369
13498
|
const parsed = JSON.parse(readFileSync13(statePath, "utf-8"));
|
|
13370
13499
|
selectedServer = parsed.remoteUrl || parsed.url || parsed.selected || null;
|
|
@@ -13373,8 +13502,14 @@ function resolveTopLevelLaunchState(context) {
|
|
|
13373
13502
|
}
|
|
13374
13503
|
return { projectInitialized, selectedServer, version: process.env.RIG_CLI_VERSION || readBuildConfig().RIG_CLI_VERSION || undefined };
|
|
13375
13504
|
}
|
|
13505
|
+
function envTruthy(value) {
|
|
13506
|
+
if (!value)
|
|
13507
|
+
return false;
|
|
13508
|
+
const normalized = value.trim().toLowerCase();
|
|
13509
|
+
return normalized !== "0" && normalized !== "false" && normalized !== "no";
|
|
13510
|
+
}
|
|
13376
13511
|
function shouldOpenApp(context) {
|
|
13377
|
-
return context.outputMode === "text" && Boolean(process.stdin.isTTY && process.stdout.isTTY) && process.env.RIG_CLI_PLAIN_HELP !== "1";
|
|
13512
|
+
return context.outputMode === "text" && Boolean(process.stdin.isTTY && process.stdout.isTTY) && process.env.RIG_CLI_PLAIN_HELP !== "1" && process.env.RIG_PLAIN !== "1" && !envTruthy(process.env.CI);
|
|
13378
13513
|
}
|
|
13379
13514
|
async function openApp(context, options = {}) {
|
|
13380
13515
|
const { runOperatorBoardLoop: runOperatorBoardLoop2 } = await Promise.resolve().then(() => (init_board(), exports_board));
|