@h-rig/cli 0.0.6-alpha.82 → 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 +2798 -1440
- 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 +96 -34
- 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 +13769 -12368
- 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 +3802 -2882
- 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 +9 -11
- package/dist/src/app-opentui/registry.js +3231 -2403
- 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 +408 -957
- package/dist/src/app-opentui/render/image-visual-layer.d.ts +18 -10
- package/dist/src/app-opentui/render/image-visual-layer.js +386 -356
- 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 +2322 -1513
- 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 -1484
package/dist/src/index.js
CHANGED
|
@@ -1105,17 +1105,21 @@ function setGitHubBearerTokenForCurrentProcess(token, projectRoot) {
|
|
|
1105
1105
|
const scopedKey = resolve11(projectRoot ?? process.cwd());
|
|
1106
1106
|
scopedGitHubBearerTokens.set(scopedKey, cleanToken(token ?? undefined));
|
|
1107
1107
|
}
|
|
1108
|
-
function
|
|
1108
|
+
function readRemoteAuthState(projectRoot) {
|
|
1109
1109
|
const path = resolve11(projectRoot, ".rig", "state", "github-auth.json");
|
|
1110
1110
|
if (!existsSync7(path))
|
|
1111
1111
|
return null;
|
|
1112
1112
|
try {
|
|
1113
1113
|
const parsed = JSON.parse(readFileSync4(path, "utf8"));
|
|
1114
|
-
return
|
|
1114
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
1115
1115
|
} catch {
|
|
1116
1116
|
return null;
|
|
1117
1117
|
}
|
|
1118
1118
|
}
|
|
1119
|
+
function readPrivateRemoteSessionToken(projectRoot) {
|
|
1120
|
+
const parsed = readRemoteAuthState(projectRoot);
|
|
1121
|
+
return parsed ? cleanToken(typeof parsed.apiSessionToken === "string" ? parsed.apiSessionToken : typeof parsed.sessionToken === "string" ? parsed.sessionToken : undefined) : null;
|
|
1122
|
+
}
|
|
1119
1123
|
function readGitHubBearerTokenForRemote(projectRoot) {
|
|
1120
1124
|
const scopedKey = resolve11(projectRoot);
|
|
1121
1125
|
if (scopedGitHubBearerTokens.has(scopedKey))
|
|
@@ -1126,15 +1130,25 @@ function readGitHubBearerTokenForRemote(projectRoot) {
|
|
|
1126
1130
|
return cleanToken(process.env.RIG_SERVER_AUTH_TOKEN) ?? cleanToken(process.env.RIG_REMOTE_AUTH_TOKEN);
|
|
1127
1131
|
}
|
|
1128
1132
|
function readStoredGitHubAuthToken(projectRoot) {
|
|
1129
|
-
const
|
|
1130
|
-
|
|
1133
|
+
const parsed = readRemoteAuthState(projectRoot);
|
|
1134
|
+
return parsed ? cleanToken(typeof parsed.token === "string" ? parsed.token : undefined) : null;
|
|
1135
|
+
}
|
|
1136
|
+
function inferRemoteServerProjectRootFromAuthState(projectRoot) {
|
|
1137
|
+
const repo = readRepoConnection(projectRoot);
|
|
1138
|
+
const slug = repo?.project?.trim();
|
|
1139
|
+
if (!slug || !/^[^/]+\/[^/]+$/.test(slug))
|
|
1131
1140
|
return null;
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1141
|
+
const auth = readRemoteAuthState(projectRoot);
|
|
1142
|
+
const authUpdatedAt = typeof auth?.updatedAt === "string" ? Date.parse(auth.updatedAt) : Number.NaN;
|
|
1143
|
+
const repoLinkedAt = typeof repo?.linkedAt === "string" ? Date.parse(repo.linkedAt) : Number.NaN;
|
|
1144
|
+
if (Number.isFinite(authUpdatedAt) && Number.isFinite(repoLinkedAt) && authUpdatedAt + 1000 < repoLinkedAt)
|
|
1136
1145
|
return null;
|
|
1137
|
-
|
|
1146
|
+
const checkoutBaseDir = typeof auth?.checkoutBaseDir === "string" && auth.checkoutBaseDir.trim() ? auth.checkoutBaseDir.trim() : null;
|
|
1147
|
+
if (!checkoutBaseDir)
|
|
1148
|
+
return null;
|
|
1149
|
+
const inferred = `${checkoutBaseDir.replace(/\/+$/, "")}/${slug}`;
|
|
1150
|
+
writeRepoServerProjectRoot(projectRoot, inferred);
|
|
1151
|
+
return inferred;
|
|
1138
1152
|
}
|
|
1139
1153
|
function readLocalConnectionFallbackToken(projectRoot) {
|
|
1140
1154
|
return readGitHubBearerTokenForRemote(projectRoot) ?? cleanToken(process.env.RIG_GITHUB_TOKEN) ?? readStoredGitHubAuthToken(projectRoot);
|
|
@@ -1145,7 +1159,7 @@ async function ensureServerForCli(projectRoot) {
|
|
|
1145
1159
|
if (selected?.connection.kind === "remote") {
|
|
1146
1160
|
reportServerPhase(`Connecting to ${selected.alias}\u2026`);
|
|
1147
1161
|
const authToken = readGitHubBearerTokenForRemote(projectRoot);
|
|
1148
|
-
const serverProjectRoot = selected.serverProjectRoot ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
|
|
1162
|
+
const serverProjectRoot = selected.serverProjectRoot ?? inferRemoteServerProjectRootFromAuthState(projectRoot) ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
|
|
1149
1163
|
return {
|
|
1150
1164
|
baseUrl: selected.connection.baseUrl,
|
|
1151
1165
|
authToken,
|
|
@@ -1174,7 +1188,10 @@ async function backfillRemoteServerProjectRoot(projectRoot, baseUrl, authToken)
|
|
|
1174
1188
|
if (!slug)
|
|
1175
1189
|
return null;
|
|
1176
1190
|
try {
|
|
1177
|
-
const
|
|
1191
|
+
const url = new URL(`${baseUrl}/api/projects/${encodeURIComponent(slug)}`);
|
|
1192
|
+
if (authToken && queryAuthFallbackEnabled())
|
|
1193
|
+
url.searchParams.set("rt", authToken);
|
|
1194
|
+
const response = await fetch(url, {
|
|
1178
1195
|
headers: mergeHeaders(undefined, authToken)
|
|
1179
1196
|
});
|
|
1180
1197
|
if (!response.ok)
|
|
@@ -1201,10 +1218,23 @@ function appendTaskFilterParams(url, filters) {
|
|
|
1201
1218
|
if (filters.limit !== undefined)
|
|
1202
1219
|
url.searchParams.set("limit", String(filters.limit));
|
|
1203
1220
|
}
|
|
1221
|
+
function mergeCookie(existing, name, value) {
|
|
1222
|
+
const encoded = `${name}=${encodeURIComponent(value)}`;
|
|
1223
|
+
if (!existing?.trim())
|
|
1224
|
+
return encoded;
|
|
1225
|
+
const parts = existing.split(";").map((part) => part.trim()).filter((part) => part && !part.startsWith(`${name}=`));
|
|
1226
|
+
return [...parts, encoded].join("; ");
|
|
1227
|
+
}
|
|
1228
|
+
function queryAuthFallbackEnabled(env = process.env) {
|
|
1229
|
+
return env.RIG_ENABLE_QUERY_AUTH_FALLBACK === "1" || env.RIG_QUERY_AUTH_FALLBACK === "1";
|
|
1230
|
+
}
|
|
1204
1231
|
function mergeHeaders(headers, authToken) {
|
|
1205
1232
|
const merged = new Headers(headers);
|
|
1206
1233
|
if (authToken) {
|
|
1207
|
-
|
|
1234
|
+
const bearer = `Bearer ${authToken}`;
|
|
1235
|
+
merged.set("authorization", bearer);
|
|
1236
|
+
merged.set("x-auth", bearer);
|
|
1237
|
+
merged.set("cookie", mergeCookie(merged.get("cookie"), "rig_auth", authToken));
|
|
1208
1238
|
}
|
|
1209
1239
|
return merged;
|
|
1210
1240
|
}
|
|
@@ -1264,15 +1294,34 @@ async function buildServerFailureContext(projectRoot, server) {
|
|
|
1264
1294
|
hint: "Check the selected server with `rig server status`, or switch with `rig server use <alias|local>`."
|
|
1265
1295
|
};
|
|
1266
1296
|
}
|
|
1297
|
+
function isLoopbackRemoteBaseUrl(baseUrl) {
|
|
1298
|
+
try {
|
|
1299
|
+
const host = new URL(baseUrl).hostname.toLowerCase();
|
|
1300
|
+
return host === "localhost" || host === "127.0.0.1" || host === "::1" || host === "[::1]";
|
|
1301
|
+
} catch {
|
|
1302
|
+
return false;
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
function canUseRemoteWithoutProjectRoot(pathname) {
|
|
1306
|
+
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/");
|
|
1307
|
+
}
|
|
1267
1308
|
async function requestServerJson(context, pathname, init = {}) {
|
|
1268
1309
|
const server = await ensureServerForCli(context.projectRoot);
|
|
1310
|
+
const requestUrl = new URL(`${server.baseUrl}${pathname}`);
|
|
1311
|
+
if (server.connectionKind === "remote" && !server.serverProjectRoot && !canUseRemoteWithoutProjectRoot(requestUrl.pathname) && (server.authToken || !isLoopbackRemoteBaseUrl(server.baseUrl))) {
|
|
1312
|
+
const repo = readRepoConnection(context.projectRoot);
|
|
1313
|
+
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." });
|
|
1314
|
+
}
|
|
1269
1315
|
const headers = mergeHeaders(init.headers, server.authToken);
|
|
1270
1316
|
if (server.serverProjectRoot)
|
|
1271
1317
|
headers.set("x-rig-project-root", server.serverProjectRoot);
|
|
1318
|
+
if (server.connectionKind === "remote" && server.authToken && queryAuthFallbackEnabled()) {
|
|
1319
|
+
requestUrl.searchParams.set("rt", server.authToken);
|
|
1320
|
+
}
|
|
1272
1321
|
reportServerPhase(`${(init.method ?? "GET").toUpperCase()} ${pathname.split("?")[0]}\u2026`);
|
|
1273
1322
|
let response;
|
|
1274
1323
|
try {
|
|
1275
|
-
response = await fetch(
|
|
1324
|
+
response = await fetch(requestUrl, {
|
|
1276
1325
|
...init,
|
|
1277
1326
|
headers
|
|
1278
1327
|
});
|
|
@@ -1334,11 +1383,26 @@ async function getGitHubAuthStatusViaServer(context) {
|
|
|
1334
1383
|
return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : {};
|
|
1335
1384
|
}
|
|
1336
1385
|
async function postGitHubTokenViaServer(context, token, options = {}) {
|
|
1337
|
-
const
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1386
|
+
const server = await ensureServerForCli(context.projectRoot);
|
|
1387
|
+
const requestUrl = new URL(`${server.baseUrl}/api/github/auth/token`);
|
|
1388
|
+
reportServerPhase("POST /api/github/auth/token\u2026");
|
|
1389
|
+
let response;
|
|
1390
|
+
try {
|
|
1391
|
+
response = await fetch(requestUrl, {
|
|
1392
|
+
method: "POST",
|
|
1393
|
+
headers: { "content-type": "application/json" },
|
|
1394
|
+
body: JSON.stringify({ token, selectedRepo: options.selectedRepo, projectRoot: options.projectRoot ?? server.serverProjectRoot ?? undefined })
|
|
1395
|
+
});
|
|
1396
|
+
} catch (error) {
|
|
1397
|
+
const failure = await buildServerFailureContext(context.projectRoot, server);
|
|
1398
|
+
throw new CliError(`Rig server auth bootstrap failed: ${error instanceof Error ? error.message : String(error)}
|
|
1399
|
+
${failure.contextLine}`, 1, { hint: failure.hint });
|
|
1400
|
+
}
|
|
1401
|
+
const payload = await response.json().catch(() => null);
|
|
1402
|
+
if (!response.ok) {
|
|
1403
|
+
const detail = payload && typeof payload === "object" && !Array.isArray(payload) ? String(payload.error ?? JSON.stringify(payload)) : `HTTP ${response.status}`;
|
|
1404
|
+
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`." });
|
|
1405
|
+
}
|
|
1342
1406
|
return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : {};
|
|
1343
1407
|
}
|
|
1344
1408
|
async function prepareRemoteCheckoutViaServer(context, input) {
|
|
@@ -1669,7 +1733,8 @@ async function runFastTaskRunPreflight(context, options = {}) {
|
|
|
1669
1733
|
}
|
|
1670
1734
|
}
|
|
1671
1735
|
const repo = readRepoConnection(context.projectRoot);
|
|
1672
|
-
|
|
1736
|
+
const remoteWithoutProjectLink = selectedServer?.connectionKind === "remote" && !repo?.project;
|
|
1737
|
+
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>`."));
|
|
1673
1738
|
try {
|
|
1674
1739
|
const auth = await request("/api/github/auth/status");
|
|
1675
1740
|
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>`."));
|
|
@@ -2713,7 +2778,7 @@ var init__operator_surface = __esm(() => {
|
|
|
2713
2778
|
});
|
|
2714
2779
|
|
|
2715
2780
|
// packages/cli/src/commands/_pi-frontend.ts
|
|
2716
|
-
import { existsSync as existsSync15, mkdirSync as
|
|
2781
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync10, mkdtempSync, readFileSync as readFileSync10, rmSync as rmSync5, writeFileSync as writeFileSync7 } from "fs";
|
|
2717
2782
|
import { homedir as homedir6, tmpdir } from "os";
|
|
2718
2783
|
import { join as join3 } from "path";
|
|
2719
2784
|
import { main as runPiMain } from "@earendil-works/pi-coding-agent";
|
|
@@ -2748,7 +2813,7 @@ function buildOperatorPiEnv(input) {
|
|
|
2748
2813
|
async function prepareOperatorConsole(context, runId, tempSessionDir) {
|
|
2749
2814
|
const server = await ensureServerForCli(context.projectRoot);
|
|
2750
2815
|
const localCwd = join3(homedir6(), ".rig", "drones", runId.slice(0, 8));
|
|
2751
|
-
|
|
2816
|
+
mkdirSync10(localCwd, { recursive: true });
|
|
2752
2817
|
trustDroneCwd(localCwd);
|
|
2753
2818
|
installRigPiTheme();
|
|
2754
2819
|
let sessionFileArg = [];
|
|
@@ -2770,7 +2835,7 @@ async function prepareOperatorConsole(context, runId, tempSessionDir) {
|
|
|
2770
2835
|
return line;
|
|
2771
2836
|
}).join(`
|
|
2772
2837
|
`);
|
|
2773
|
-
|
|
2838
|
+
writeFileSync7(localSessionPath, content);
|
|
2774
2839
|
sessionFileArg = ["--session", localSessionPath];
|
|
2775
2840
|
}
|
|
2776
2841
|
} catch {}
|
|
@@ -2779,12 +2844,12 @@ async function prepareOperatorConsole(context, runId, tempSessionDir) {
|
|
|
2779
2844
|
function trustDroneCwd(localCwd) {
|
|
2780
2845
|
try {
|
|
2781
2846
|
const agentDir = join3(homedir6(), ".pi", "agent");
|
|
2782
|
-
|
|
2847
|
+
mkdirSync10(agentDir, { recursive: true });
|
|
2783
2848
|
const trustPath = join3(agentDir, "trust.json");
|
|
2784
2849
|
const store = existsSync15(trustPath) ? JSON.parse(readFileSync10(trustPath, "utf8")) : {};
|
|
2785
2850
|
if (store[localCwd] !== true) {
|
|
2786
2851
|
store[localCwd] = true;
|
|
2787
|
-
|
|
2852
|
+
writeFileSync7(trustPath, `${JSON.stringify(store, null, "\t")}
|
|
2788
2853
|
`);
|
|
2789
2854
|
}
|
|
2790
2855
|
} catch {}
|
|
@@ -2792,12 +2857,12 @@ function trustDroneCwd(localCwd) {
|
|
|
2792
2857
|
function installRigPiTheme() {
|
|
2793
2858
|
try {
|
|
2794
2859
|
const themesDir = join3(homedir6(), ".pi", "agent", "themes");
|
|
2795
|
-
|
|
2860
|
+
mkdirSync10(themesDir, { recursive: true });
|
|
2796
2861
|
const themePath = join3(themesDir, "rig.json");
|
|
2797
2862
|
const next = `${JSON.stringify(RIG_PI_THEME, null, "\t")}
|
|
2798
2863
|
`;
|
|
2799
2864
|
if (!existsSync15(themePath) || readFileSync10(themePath, "utf8") !== next) {
|
|
2800
|
-
|
|
2865
|
+
writeFileSync7(themePath, next);
|
|
2801
2866
|
}
|
|
2802
2867
|
} catch {}
|
|
2803
2868
|
}
|
|
@@ -2817,6 +2882,7 @@ async function attachRunBundledPiFrontend(context, input) {
|
|
|
2817
2882
|
let detached = false;
|
|
2818
2883
|
try {
|
|
2819
2884
|
await runPiMain([
|
|
2885
|
+
"--offline",
|
|
2820
2886
|
"--no-extensions",
|
|
2821
2887
|
"--no-skills",
|
|
2822
2888
|
"--no-prompt-templates",
|
|
@@ -3487,7 +3553,7 @@ var init__task_picker = __esm(() => {
|
|
|
3487
3553
|
// packages/cli/src/commands/task.ts
|
|
3488
3554
|
import { readFileSync as readFileSync11 } from "fs";
|
|
3489
3555
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
3490
|
-
import { resolve as
|
|
3556
|
+
import { resolve as resolve23 } from "path";
|
|
3491
3557
|
import {
|
|
3492
3558
|
taskArtifactDir,
|
|
3493
3559
|
taskArtifacts,
|
|
@@ -3765,7 +3831,7 @@ async function executeTask(context, args, options) {
|
|
|
3765
3831
|
const fileFlag = takeOption(rest.slice(1), "--file");
|
|
3766
3832
|
let content;
|
|
3767
3833
|
if (fileFlag.value) {
|
|
3768
|
-
content = readFileSync11(
|
|
3834
|
+
content = readFileSync11(resolve23(context.projectRoot, fileFlag.value), "utf-8");
|
|
3769
3835
|
} else {
|
|
3770
3836
|
content = await readStdin();
|
|
3771
3837
|
}
|
|
@@ -4846,11 +4912,11 @@ async function runOperatorBoard(context, options = {}) {
|
|
|
4846
4912
|
}, BOARD_REFRESH_MS);
|
|
4847
4913
|
tui.start();
|
|
4848
4914
|
refresh({ quiet: true });
|
|
4849
|
-
await new Promise((
|
|
4915
|
+
await new Promise((resolve26) => {
|
|
4850
4916
|
const poll = setInterval(() => {
|
|
4851
4917
|
if (stopped) {
|
|
4852
4918
|
clearInterval(poll);
|
|
4853
|
-
|
|
4919
|
+
resolve26();
|
|
4854
4920
|
}
|
|
4855
4921
|
}, 50);
|
|
4856
4922
|
});
|
|
@@ -4884,7 +4950,7 @@ import {
|
|
|
4884
4950
|
existsSync as existsSync19,
|
|
4885
4951
|
readFileSync as readFileSync13
|
|
4886
4952
|
} from "fs";
|
|
4887
|
-
import { resolve as
|
|
4953
|
+
import { resolve as resolve26 } from "path";
|
|
4888
4954
|
import { readBuildConfig } from "@rig/runtime/build-time-config";
|
|
4889
4955
|
|
|
4890
4956
|
// packages/cli/src/commands/browser.ts
|
|
@@ -9112,14 +9178,64 @@ Usage: rig init`, 1);
|
|
|
9112
9178
|
// packages/cli/src/commands/github.ts
|
|
9113
9179
|
init_runner();
|
|
9114
9180
|
init__server_client();
|
|
9181
|
+
init__connection_state();
|
|
9115
9182
|
init__async_ui();
|
|
9116
9183
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
9184
|
+
import { mkdirSync as mkdirSync9, writeFileSync as writeFileSync6 } from "fs";
|
|
9185
|
+
import { dirname as dirname4, resolve as resolve19 } from "path";
|
|
9117
9186
|
function printPayload(context, payload, fallback) {
|
|
9118
9187
|
if (context.outputMode === "json")
|
|
9119
9188
|
console.log(JSON.stringify(payload, null, 2));
|
|
9120
9189
|
else
|
|
9121
9190
|
console.log(fallback);
|
|
9122
9191
|
}
|
|
9192
|
+
function apiSessionTokenFrom2(payload) {
|
|
9193
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload))
|
|
9194
|
+
return null;
|
|
9195
|
+
const token = payload.apiSessionToken;
|
|
9196
|
+
return typeof token === "string" && token.trim() ? token.trim() : null;
|
|
9197
|
+
}
|
|
9198
|
+
function payloadString(payload, key) {
|
|
9199
|
+
const value = payload[key];
|
|
9200
|
+
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
9201
|
+
}
|
|
9202
|
+
function payloadRecord(payload, key) {
|
|
9203
|
+
const value = payload[key];
|
|
9204
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
9205
|
+
}
|
|
9206
|
+
function remoteNamespaceMetadata(result) {
|
|
9207
|
+
const namespace = payloadRecord(result, "userNamespace");
|
|
9208
|
+
return {
|
|
9209
|
+
...payloadString(result, "login") ? { login: payloadString(result, "login") } : {},
|
|
9210
|
+
...payloadString(result, "userId") ? { userId: payloadString(result, "userId") } : {},
|
|
9211
|
+
...namespace && payloadString(namespace, "key") ? { userNamespaceKey: payloadString(namespace, "key") } : {},
|
|
9212
|
+
...namespace && payloadString(namespace, "root") ? { userNamespaceRoot: payloadString(namespace, "root") } : {},
|
|
9213
|
+
...namespace && payloadString(namespace, "checkoutBaseDir") ? { checkoutBaseDir: payloadString(namespace, "checkoutBaseDir") } : {},
|
|
9214
|
+
...namespace && payloadString(namespace, "snapshotBaseDir") ? { snapshotBaseDir: payloadString(namespace, "snapshotBaseDir") } : {}
|
|
9215
|
+
};
|
|
9216
|
+
}
|
|
9217
|
+
function persistRemoteAuthSession(context, source, result, fallbackToken) {
|
|
9218
|
+
const apiSessionToken = apiSessionTokenFrom2(result);
|
|
9219
|
+
setGitHubBearerTokenForCurrentProcess(apiSessionToken ?? fallbackToken, context.projectRoot);
|
|
9220
|
+
if (!apiSessionToken)
|
|
9221
|
+
return;
|
|
9222
|
+
const repo = readRepoConnection(context.projectRoot);
|
|
9223
|
+
const path = resolve19(context.projectRoot, ".rig", "state", "github-auth.json");
|
|
9224
|
+
mkdirSync9(dirname4(path), { recursive: true });
|
|
9225
|
+
writeFileSync6(path, `${JSON.stringify({
|
|
9226
|
+
authenticated: true,
|
|
9227
|
+
source,
|
|
9228
|
+
storedOnServer: true,
|
|
9229
|
+
...repo?.project ? { selectedRepo: repo.project } : {},
|
|
9230
|
+
...remoteNamespaceMetadata(result),
|
|
9231
|
+
apiSessionToken,
|
|
9232
|
+
updatedAt: new Date().toISOString()
|
|
9233
|
+
}, null, 2)}
|
|
9234
|
+
`, "utf8");
|
|
9235
|
+
}
|
|
9236
|
+
function isSignedIn(status) {
|
|
9237
|
+
return status.signedIn === true || status.authenticated === true;
|
|
9238
|
+
}
|
|
9123
9239
|
function readGhToken() {
|
|
9124
9240
|
const result = spawnSync2("gh", ["auth", "token"], { encoding: "utf8" });
|
|
9125
9241
|
if (result.status !== 0) {
|
|
@@ -9141,7 +9257,7 @@ async function executeGithub(context, args) {
|
|
|
9141
9257
|
if (rest.length > 0)
|
|
9142
9258
|
throw new CliError("Usage: rig github auth status", 1);
|
|
9143
9259
|
const status = await withSpinner("Checking GitHub auth on the server\u2026", () => getGitHubAuthStatusViaServer(context), { outputMode: context.outputMode });
|
|
9144
|
-
printPayload(context, status, `GitHub auth: ${status
|
|
9260
|
+
printPayload(context, status, `GitHub auth: ${isSignedIn(status) ? "authenticated" : "unauthenticated"}`);
|
|
9145
9261
|
return { ok: true, group: "github", command: "auth status", details: status };
|
|
9146
9262
|
}
|
|
9147
9263
|
case "token": {
|
|
@@ -9151,16 +9267,20 @@ async function executeGithub(context, args) {
|
|
|
9151
9267
|
const token = parsed.value?.trim();
|
|
9152
9268
|
if (!token)
|
|
9153
9269
|
throw new CliError("Missing --token value.", 1, { hint: "Re-run as `rig github auth token --token <token>`." });
|
|
9154
|
-
const
|
|
9155
|
-
|
|
9270
|
+
const repo = readRepoConnection(context.projectRoot);
|
|
9271
|
+
const result = await withSpinner("Storing GitHub token on the server\u2026", () => postGitHubTokenViaServer(context, token, repo?.project ? { selectedRepo: repo.project } : {}), { outputMode: context.outputMode });
|
|
9272
|
+
persistRemoteAuthSession(context, "token", result, token);
|
|
9273
|
+
printPayload(context, result, "GitHub token stored on the selected server.");
|
|
9156
9274
|
return { ok: true, group: "github", command: "auth token", details: result };
|
|
9157
9275
|
}
|
|
9158
9276
|
case "import-gh": {
|
|
9159
9277
|
if (rest.length > 0)
|
|
9160
9278
|
throw new CliError("Usage: rig github auth import-gh", 1);
|
|
9161
9279
|
const importedToken = readGhToken();
|
|
9162
|
-
const
|
|
9163
|
-
|
|
9280
|
+
const repo = readRepoConnection(context.projectRoot);
|
|
9281
|
+
const result = await withSpinner("Storing GitHub token on the server\u2026", () => postGitHubTokenViaServer(context, importedToken, repo?.project ? { selectedRepo: repo.project } : {}), { outputMode: context.outputMode });
|
|
9282
|
+
persistRemoteAuthSession(context, "gh", result, importedToken);
|
|
9283
|
+
printPayload(context, result, "GitHub token imported from gh and stored on the selected server.");
|
|
9164
9284
|
return { ok: true, group: "github", command: "auth import-gh", details: result };
|
|
9165
9285
|
}
|
|
9166
9286
|
default:
|
|
@@ -9190,7 +9310,7 @@ init_runner();
|
|
|
9190
9310
|
init__authority_runs();
|
|
9191
9311
|
init__paths();
|
|
9192
9312
|
import { readFileSync as readFileSync8 } from "fs";
|
|
9193
|
-
import { resolve as
|
|
9313
|
+
import { resolve as resolve20 } from "path";
|
|
9194
9314
|
import {
|
|
9195
9315
|
appendRunJournalEvent,
|
|
9196
9316
|
appendRunLogEntry,
|
|
@@ -9227,7 +9347,7 @@ function touchAuthorityRun(projectRoot, runId) {
|
|
|
9227
9347
|
if (!current) {
|
|
9228
9348
|
return;
|
|
9229
9349
|
}
|
|
9230
|
-
writeJsonFile3(
|
|
9350
|
+
writeJsonFile3(resolve20(resolveAuthorityRunDir(projectRoot, runId), "run.json"), {
|
|
9231
9351
|
...current,
|
|
9232
9352
|
updatedAt: new Date().toISOString()
|
|
9233
9353
|
});
|
|
@@ -9465,7 +9585,7 @@ init_runner();
|
|
|
9465
9585
|
init__server_client();
|
|
9466
9586
|
init__async_ui();
|
|
9467
9587
|
import { existsSync as existsSync13, readFileSync as readFileSync9 } from "fs";
|
|
9468
|
-
import { resolve as
|
|
9588
|
+
import { resolve as resolve21 } from "path";
|
|
9469
9589
|
import {
|
|
9470
9590
|
listAuthorityRuns,
|
|
9471
9591
|
readAuthorityRun as readAuthorityRun3,
|
|
@@ -9509,7 +9629,7 @@ async function executeInspect(context, args) {
|
|
|
9509
9629
|
}
|
|
9510
9630
|
return { ok: true, group: "inspect", command, details: { task: requiredTask, runId: fallback.runId, source: "server", entries } };
|
|
9511
9631
|
}
|
|
9512
|
-
const logsPath =
|
|
9632
|
+
const logsPath = resolve21(resolveAuthorityRunDir2(context.projectRoot, latestRun.runId), "logs.jsonl");
|
|
9513
9633
|
if (!existsSync13(logsPath)) {
|
|
9514
9634
|
throw new CliError(`No logs found for run ${latestRun.runId}.`, 1, { hint: `Try \`rig run show ${latestRun.runId}\` or \`rig run replay ${latestRun.runId}\`.` });
|
|
9515
9635
|
}
|
|
@@ -9597,7 +9717,7 @@ async function executeInspect(context, args) {
|
|
|
9597
9717
|
return { ok: true, group: "inspect", command };
|
|
9598
9718
|
case "audit": {
|
|
9599
9719
|
requireNoExtraArgs(rest, "rig inspect audit");
|
|
9600
|
-
const auditPath =
|
|
9720
|
+
const auditPath = resolve21(resolveHarnessPaths2(context.projectRoot).logsDir, "audit.jsonl");
|
|
9601
9721
|
if (!existsSync13(auditPath)) {
|
|
9602
9722
|
console.log("No audit log found.");
|
|
9603
9723
|
} else {
|
|
@@ -10256,7 +10376,7 @@ import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/co
|
|
|
10256
10376
|
|
|
10257
10377
|
// packages/cli/src/commands/_run-replay.ts
|
|
10258
10378
|
import { existsSync as existsSync14, readdirSync as readdirSync2 } from "fs";
|
|
10259
|
-
import { join as join2, resolve as
|
|
10379
|
+
import { join as join2, resolve as resolve22 } from "path";
|
|
10260
10380
|
import {
|
|
10261
10381
|
readAuthorityRun as readAuthorityRun4,
|
|
10262
10382
|
readJsonlFile as readJsonlFile3,
|
|
@@ -10349,7 +10469,7 @@ function resolveRunSessionFile(record) {
|
|
|
10349
10469
|
const sessionId = text(piSession.sessionId);
|
|
10350
10470
|
if (!cwd || !sessionId)
|
|
10351
10471
|
return null;
|
|
10352
|
-
const sessionDir =
|
|
10472
|
+
const sessionDir = resolve22(cwd, ".rig", "session");
|
|
10353
10473
|
try {
|
|
10354
10474
|
const match = readdirSync2(sessionDir).find((name) => name.endsWith(`_${sessionId}.jsonl`));
|
|
10355
10475
|
return match ? join2(sessionDir, match) : null;
|
|
@@ -10847,6 +10967,9 @@ async function executeRun(context, args) {
|
|
|
10847
10967
|
console.log(`Stop requested: ${runId}`);
|
|
10848
10968
|
return { ok: true, group: "run", command, details: stopped };
|
|
10849
10969
|
}
|
|
10970
|
+
if (isRemoteConnectionSelected(context.projectRoot)) {
|
|
10971
|
+
throw new CliError("Remote run stop requires an explicit run id.", 2, { hint: "Run `rig run list`, then `rig run stop <run-id>`." });
|
|
10972
|
+
}
|
|
10850
10973
|
const result = await runStop(context.projectRoot);
|
|
10851
10974
|
if (result.remaining.length > 0) {
|
|
10852
10975
|
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." });
|
|
@@ -10963,7 +11086,13 @@ async function executeConnectionCommand(context, args, options) {
|
|
|
10963
11086
|
if (!state.connections[alias])
|
|
10964
11087
|
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>`." });
|
|
10965
11088
|
}
|
|
10966
|
-
const
|
|
11089
|
+
const previousRepo = readRepoConnection(context.projectRoot);
|
|
11090
|
+
const repoState = {
|
|
11091
|
+
selected: alias,
|
|
11092
|
+
...previousRepo?.project ? { project: previousRepo.project } : {},
|
|
11093
|
+
linkedAt: new Date().toISOString(),
|
|
11094
|
+
...previousRepo?.serverProjectRoot && previousRepo.selected === alias ? { serverProjectRoot: previousRepo.serverProjectRoot } : {}
|
|
11095
|
+
};
|
|
10967
11096
|
writeRepoConnection(context.projectRoot, repoState);
|
|
10968
11097
|
printJsonOrText(context, repoState, formatSuccessCard("Rig server selected", [
|
|
10969
11098
|
["selected", alias],
|
|
@@ -11198,8 +11327,8 @@ init_task();
|
|
|
11198
11327
|
|
|
11199
11328
|
// packages/cli/src/commands/task-run-driver.ts
|
|
11200
11329
|
init_runner();
|
|
11201
|
-
import { copyFileSync as copyFileSync3, existsSync as existsSync16, mkdirSync as
|
|
11202
|
-
import { resolve as
|
|
11330
|
+
import { copyFileSync as copyFileSync3, existsSync as existsSync16, mkdirSync as mkdirSync11, readFileSync as readFileSync12, statSync as statSync2, writeFileSync as writeFileSync8 } from "fs";
|
|
11331
|
+
import { resolve as resolve24 } from "path";
|
|
11203
11332
|
import { spawn as spawn2, spawnSync as spawnSync4 } from "child_process";
|
|
11204
11333
|
import { createInterface as createLineInterface } from "readline";
|
|
11205
11334
|
import { loadConfig as loadConfig2 } from "@rig/core/load-config";
|
|
@@ -11298,12 +11427,12 @@ function copyUntrackedDirtyFiles(sourceRoot, targetRoot) {
|
|
|
11298
11427
|
return 0;
|
|
11299
11428
|
let copied = 0;
|
|
11300
11429
|
for (const relativePath of listed.stdout.split("\x00").filter(Boolean)) {
|
|
11301
|
-
const sourcePath =
|
|
11302
|
-
const targetPath =
|
|
11430
|
+
const sourcePath = resolve24(sourceRoot, relativePath);
|
|
11431
|
+
const targetPath = resolve24(targetRoot, relativePath);
|
|
11303
11432
|
try {
|
|
11304
11433
|
if (!statSync2(sourcePath).isFile())
|
|
11305
11434
|
continue;
|
|
11306
|
-
|
|
11435
|
+
mkdirSync11(resolve24(targetPath, ".."), { recursive: true });
|
|
11307
11436
|
copyFileSync3(sourcePath, targetPath);
|
|
11308
11437
|
copied += 1;
|
|
11309
11438
|
} catch {}
|
|
@@ -11342,7 +11471,7 @@ function buildDirtyBaselineHandshakeEnv(input) {
|
|
|
11342
11471
|
return { RIG_BASELINE_MODE: input.baselineMode ?? "head" };
|
|
11343
11472
|
return {
|
|
11344
11473
|
RIG_BASELINE_MODE: "dirty-snapshot",
|
|
11345
|
-
RIG_DIRTY_BASELINE_READY_FILE:
|
|
11474
|
+
RIG_DIRTY_BASELINE_READY_FILE: resolve24(input.projectRoot, ".rig", "runs", input.runId, "dirty-baseline.ready.json")
|
|
11346
11475
|
};
|
|
11347
11476
|
}
|
|
11348
11477
|
function positiveInt(value, fallback) {
|
|
@@ -11447,9 +11576,9 @@ function createCommandRunner(binary) {
|
|
|
11447
11576
|
const stderrChunks = [];
|
|
11448
11577
|
child.stdout.on("data", (chunk) => stdoutChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk))));
|
|
11449
11578
|
child.stderr.on("data", (chunk) => stderrChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk))));
|
|
11450
|
-
return await new Promise((
|
|
11451
|
-
child.once("error", (error) =>
|
|
11452
|
-
child.once("close", (code) =>
|
|
11579
|
+
return await new Promise((resolve25) => {
|
|
11580
|
+
child.once("error", (error) => resolve25({ exitCode: 1, stderr: error.message }));
|
|
11581
|
+
child.once("close", (code) => resolve25({
|
|
11453
11582
|
exitCode: code ?? 1,
|
|
11454
11583
|
stdout: Buffer.concat(stdoutChunks).toString("utf8"),
|
|
11455
11584
|
stderr: Buffer.concat(stderrChunks).toString("utf8")
|
|
@@ -11523,7 +11652,7 @@ async function runTaskRunPostValidationLifecycle(input) {
|
|
|
11523
11652
|
config,
|
|
11524
11653
|
sourceTask: input.sourceTask,
|
|
11525
11654
|
uploadedSnapshot: input.uploadedSnapshot,
|
|
11526
|
-
artifactRoot:
|
|
11655
|
+
artifactRoot: resolve24(input.projectRoot, "artifacts", taskId3),
|
|
11527
11656
|
command: ghCommand,
|
|
11528
11657
|
gitCommand,
|
|
11529
11658
|
steerPi,
|
|
@@ -11653,7 +11782,7 @@ function summarizeValidationFailure(projectRoot, taskId3) {
|
|
|
11653
11782
|
return null;
|
|
11654
11783
|
}
|
|
11655
11784
|
for (const artifactDir of resolveTaskArtifactDirs2(projectRoot, taskId3)) {
|
|
11656
|
-
const summary = readJsonFile3(
|
|
11785
|
+
const summary = readJsonFile3(resolve24(artifactDir, "validation-summary.json"), null);
|
|
11657
11786
|
if (!summary || summary.status !== "fail") {
|
|
11658
11787
|
continue;
|
|
11659
11788
|
}
|
|
@@ -11734,9 +11863,9 @@ function readTaskRunAcceptedArtifactState(input) {
|
|
|
11734
11863
|
if (!input.taskId || !input.workspaceDir) {
|
|
11735
11864
|
return { accepted: false, reason: null };
|
|
11736
11865
|
}
|
|
11737
|
-
const artifactDir =
|
|
11738
|
-
const reviewStatusPath =
|
|
11739
|
-
const taskResultPath =
|
|
11866
|
+
const artifactDir = resolve24(input.workspaceDir, "artifacts", input.taskId);
|
|
11867
|
+
const reviewStatusPath = resolve24(artifactDir, "review-status.txt");
|
|
11868
|
+
const taskResultPath = resolve24(artifactDir, "task-result.json");
|
|
11740
11869
|
const reviewStatus = readTaskRunReviewStatus(reviewStatusPath);
|
|
11741
11870
|
if (reviewStatus !== "APPROVED") {
|
|
11742
11871
|
return { accepted: false, reason: null };
|
|
@@ -11773,12 +11902,12 @@ function resolveTaskRunRetryContext(input) {
|
|
|
11773
11902
|
if (!input.taskId || !input.workspaceDir) {
|
|
11774
11903
|
return { shouldRetry: false, failureDetail: null, nextPrompt: null };
|
|
11775
11904
|
}
|
|
11776
|
-
const artifactDir =
|
|
11777
|
-
const reviewStatePath =
|
|
11778
|
-
const reviewFeedbackPath =
|
|
11779
|
-
const reviewStatusPath =
|
|
11780
|
-
const failedApproachesPath =
|
|
11781
|
-
const validationSummaryPath =
|
|
11905
|
+
const artifactDir = resolve24(input.workspaceDir, "artifacts", input.taskId);
|
|
11906
|
+
const reviewStatePath = resolve24(artifactDir, "review-state.json");
|
|
11907
|
+
const reviewFeedbackPath = resolve24(artifactDir, "review-feedback.md");
|
|
11908
|
+
const reviewStatusPath = resolve24(artifactDir, "review-status.txt");
|
|
11909
|
+
const failedApproachesPath = resolve24(input.workspaceDir, ".rig", "state", "failed_approaches.md");
|
|
11910
|
+
const validationSummaryPath = resolve24(artifactDir, "validation-summary.json");
|
|
11782
11911
|
const reviewState = readJsonFile3(reviewStatePath, null);
|
|
11783
11912
|
const reviewStatus = readTaskRunReviewStatus(reviewStatusPath);
|
|
11784
11913
|
const reviewRejected = isTaskRunReviewRejected(reviewState);
|
|
@@ -12188,15 +12317,15 @@ async function executeRigOwnedTaskRun(context, input) {
|
|
|
12188
12317
|
const loadedAutomationConfig = await loadTaskRunAutomationConfig(context.projectRoot);
|
|
12189
12318
|
const automationConfig = input.prMode ? { ...loadedAutomationConfig ?? {}, pr: { ...loadedAutomationConfig?.pr ?? {}, mode: input.prMode } } : loadedAutomationConfig;
|
|
12190
12319
|
const planningClassification = classifyPlanningNeed({ config: automationConfig, sourceTask });
|
|
12191
|
-
const planningArtifactPath =
|
|
12320
|
+
const planningArtifactPath = resolve24("artifacts", runtimeTaskId, "implementation-plan.md");
|
|
12192
12321
|
const persistedPlanning = {
|
|
12193
12322
|
...planningClassification,
|
|
12194
12323
|
classifier: input.runtimeAdapter === "pi" ? "pi-rig-structured-policy" : "rig-structured-policy",
|
|
12195
12324
|
artifactPath: planningClassification.planningRequired ? planningArtifactPath : null,
|
|
12196
12325
|
classifiedAt: new Date().toISOString()
|
|
12197
12326
|
};
|
|
12198
|
-
|
|
12199
|
-
|
|
12327
|
+
mkdirSync11(resolve24(context.projectRoot, ".rig", "runs", input.runId), { recursive: true });
|
|
12328
|
+
writeFileSync8(resolve24(context.projectRoot, ".rig", "runs", input.runId, "planning-classification.json"), `${JSON.stringify(persistedPlanning, null, 2)}
|
|
12200
12329
|
`, "utf8");
|
|
12201
12330
|
patchAuthorityRun(context.projectRoot, input.runId, { planning: persistedPlanning });
|
|
12202
12331
|
prompt = `${prompt}
|
|
@@ -12246,7 +12375,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
12246
12375
|
let verificationStarted = false;
|
|
12247
12376
|
let reviewStarted = false;
|
|
12248
12377
|
let latestRuntimeWorkspace = resumeMode && typeof existingRunRecord?.worktreePath === "string" ? existingRunRecord.worktreePath : null;
|
|
12249
|
-
let latestSessionDir = resumeMode && typeof existingRunRecord?.sessionPath === "string" ?
|
|
12378
|
+
let latestSessionDir = resumeMode && typeof existingRunRecord?.sessionPath === "string" ? resolve24(existingRunRecord.sessionPath, "..") : null;
|
|
12250
12379
|
let latestLogsDir = resumeMode && typeof existingRunRecord?.logRoot === "string" ? existingRunRecord.logRoot : null;
|
|
12251
12380
|
let latestProviderCommand = null;
|
|
12252
12381
|
let latestRuntimeBranch = resumeMode && typeof existingRunRecord?.branch === "string" ? existingRunRecord.branch : null;
|
|
@@ -12332,10 +12461,10 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
12332
12461
|
setRunStatusOrFail(context.projectRoot, input.runId, "running");
|
|
12333
12462
|
patchAuthorityRun(context.projectRoot, input.runId, {
|
|
12334
12463
|
worktreePath: latestRuntimeWorkspace,
|
|
12335
|
-
artifactRoot: latestRuntimeWorkspace && input.taskId ?
|
|
12464
|
+
artifactRoot: latestRuntimeWorkspace && input.taskId ? resolve24(latestRuntimeWorkspace, "artifacts", input.taskId) : null,
|
|
12336
12465
|
logRoot: latestLogsDir,
|
|
12337
|
-
sessionPath: latestSessionDir ?
|
|
12338
|
-
sessionLogPath: latestLogsDir ?
|
|
12466
|
+
sessionPath: latestSessionDir ? resolve24(latestSessionDir, "session.json") : null,
|
|
12467
|
+
sessionLogPath: latestLogsDir ? resolve24(latestLogsDir, "agent-stdout.log") : null,
|
|
12339
12468
|
branch: runtimeId
|
|
12340
12469
|
});
|
|
12341
12470
|
if (!dirtyBaselineApplied && input.baselineMode === "dirty-snapshot" && latestRuntimeWorkspace) {
|
|
@@ -12343,8 +12472,8 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
12343
12472
|
const dirty = applyDirtyBaselineSnapshot({ sourceRoot: context.projectRoot, targetRoot: latestRuntimeWorkspace });
|
|
12344
12473
|
const readyFile = childEnv.RIG_DIRTY_BASELINE_READY_FILE;
|
|
12345
12474
|
if (readyFile) {
|
|
12346
|
-
|
|
12347
|
-
|
|
12475
|
+
mkdirSync11(resolve24(readyFile, ".."), { recursive: true });
|
|
12476
|
+
writeFileSync8(readyFile, `${JSON.stringify({ ...dirty, workspaceDir: latestRuntimeWorkspace, appliedAt: new Date().toISOString() }, null, 2)}
|
|
12348
12477
|
`, "utf8");
|
|
12349
12478
|
}
|
|
12350
12479
|
appendRunLog(context.projectRoot, input.runId, {
|
|
@@ -12740,7 +12869,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
12740
12869
|
let acceptedArtifactObservedAt = null;
|
|
12741
12870
|
let acceptedArtifactPollTimer = null;
|
|
12742
12871
|
let acceptedArtifactKillTimer = null;
|
|
12743
|
-
const attemptExit = await new Promise((
|
|
12872
|
+
const attemptExit = await new Promise((resolve25) => {
|
|
12744
12873
|
let settled = false;
|
|
12745
12874
|
const settle = (result) => {
|
|
12746
12875
|
if (settled)
|
|
@@ -12748,7 +12877,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
12748
12877
|
settled = true;
|
|
12749
12878
|
if (acceptedArtifactPollTimer)
|
|
12750
12879
|
clearInterval(acceptedArtifactPollTimer);
|
|
12751
|
-
|
|
12880
|
+
resolve25(result);
|
|
12752
12881
|
};
|
|
12753
12882
|
const pollAcceptedArtifacts = () => {
|
|
12754
12883
|
const artifactState = readTaskRunAcceptedArtifactState({
|
|
@@ -12951,7 +13080,7 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
|
|
|
12951
13080
|
}
|
|
12952
13081
|
if (planningClassification.planningRequired) {
|
|
12953
13082
|
const planWorkspace = latestRuntimeWorkspace ?? context.projectRoot;
|
|
12954
|
-
const expectedPlanPath =
|
|
13083
|
+
const expectedPlanPath = resolve24(planWorkspace, planningArtifactPath);
|
|
12955
13084
|
if (!existsSync16(expectedPlanPath)) {
|
|
12956
13085
|
const failedAt = new Date().toISOString();
|
|
12957
13086
|
const failureDetail = `Planning was required (${planningClassification.reason}) but ${planningArtifactPath} was not written before implementation completed.`;
|
|
@@ -13121,9 +13250,9 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
|
|
|
13121
13250
|
});
|
|
13122
13251
|
emitServerRunEvent({ type: "log", runId: input.runId, title: "Pi PR feedback fix stderr" });
|
|
13123
13252
|
});
|
|
13124
|
-
const exitCode = await new Promise((
|
|
13125
|
-
child.once("error", () =>
|
|
13126
|
-
child.once("close", (code) =>
|
|
13253
|
+
const exitCode = await new Promise((resolve25) => {
|
|
13254
|
+
child.once("error", () => resolve25(1));
|
|
13255
|
+
child.once("close", (code) => resolve25(code ?? 1));
|
|
13127
13256
|
});
|
|
13128
13257
|
for (const pendingLog of flushPendingClaudeToolUseLogs({
|
|
13129
13258
|
runId: input.runId,
|
|
@@ -13264,8 +13393,8 @@ async function executeTest(context, args) {
|
|
|
13264
13393
|
init_runner();
|
|
13265
13394
|
init__parsers();
|
|
13266
13395
|
init__paths();
|
|
13267
|
-
import { existsSync as existsSync17, mkdirSync as
|
|
13268
|
-
import { resolve as
|
|
13396
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync12, readdirSync as readdirSync3, writeFileSync as writeFileSync9 } from "fs";
|
|
13397
|
+
import { resolve as resolve25 } from "path";
|
|
13269
13398
|
import { createPluginHost } from "@rig/core";
|
|
13270
13399
|
import {
|
|
13271
13400
|
isSupportedBunVersion as isSupportedBunVersion2,
|
|
@@ -13320,12 +13449,12 @@ function runSetupInit(projectRoot) {
|
|
|
13320
13449
|
const stateDir = resolveControlPlaneHostStateDir(projectRoot);
|
|
13321
13450
|
const logsDir = resolveControlPlaneHostLogsDir(projectRoot);
|
|
13322
13451
|
const artifactsDir = resolveControlPlaneArtifactsDir(projectRoot);
|
|
13323
|
-
|
|
13324
|
-
|
|
13325
|
-
|
|
13326
|
-
const failuresPath =
|
|
13452
|
+
mkdirSync12(stateDir, { recursive: true });
|
|
13453
|
+
mkdirSync12(logsDir, { recursive: true });
|
|
13454
|
+
mkdirSync12(artifactsDir, { recursive: true });
|
|
13455
|
+
const failuresPath = resolve25(stateDir, "failed_approaches.md");
|
|
13327
13456
|
if (!existsSync17(failuresPath)) {
|
|
13328
|
-
|
|
13457
|
+
writeFileSync9(failuresPath, `# Failed Approaches
|
|
13329
13458
|
|
|
13330
13459
|
`, "utf-8");
|
|
13331
13460
|
}
|
|
@@ -13342,17 +13471,17 @@ async function runSetupCheck(projectRoot, outputMode = "text") {
|
|
|
13342
13471
|
}
|
|
13343
13472
|
async function runSetupPreflight(projectRoot, outputMode = "text") {
|
|
13344
13473
|
await runSetupCheck(projectRoot, outputMode);
|
|
13345
|
-
const validationRoot =
|
|
13474
|
+
const validationRoot = resolve25(resolveControlPlaneDefinitionRoot(projectRoot), "validation");
|
|
13346
13475
|
if (existsSync17(validationRoot)) {
|
|
13347
13476
|
const validators = readdirSync3(validationRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory());
|
|
13348
13477
|
for (const validator of validators) {
|
|
13349
|
-
const script =
|
|
13478
|
+
const script = resolve25(validationRoot, validator.name, "validate.sh");
|
|
13350
13479
|
if (existsSync17(script)) {
|
|
13351
13480
|
console.log(`OK: validator script ${script}`);
|
|
13352
13481
|
}
|
|
13353
13482
|
}
|
|
13354
13483
|
}
|
|
13355
|
-
const hooksRoot =
|
|
13484
|
+
const hooksRoot = resolve25(resolveControlPlaneDefinitionRoot(projectRoot), "hooks");
|
|
13356
13485
|
if (existsSync17(hooksRoot)) {
|
|
13357
13486
|
const hooks = readdirSync3(hooksRoot).filter((name) => name.endsWith(".sh"));
|
|
13358
13487
|
for (const hook of hooks) {
|
|
@@ -13499,7 +13628,7 @@ var PROJECT_REQUIRED_GROUPS = new Set([
|
|
|
13499
13628
|
]);
|
|
13500
13629
|
var RIG_CONFIG_FILENAMES = ["rig.config.ts", "rig.config.mts", "rig.config.json"];
|
|
13501
13630
|
function hasInitializedRigProject(projectRoot) {
|
|
13502
|
-
return RIG_CONFIG_FILENAMES.some((name) => existsSync19(
|
|
13631
|
+
return RIG_CONFIG_FILENAMES.some((name) => existsSync19(resolve26(projectRoot, name))) || existsSync19(resolve26(projectRoot, ".rig"));
|
|
13503
13632
|
}
|
|
13504
13633
|
function requireInitializedRigProject(context, group) {
|
|
13505
13634
|
if (hasInitializedRigProject(context.projectRoot)) {
|
|
@@ -13553,7 +13682,7 @@ function resolveTopLevelLaunchState(context) {
|
|
|
13553
13682
|
let selectedServer = null;
|
|
13554
13683
|
if (projectInitialized) {
|
|
13555
13684
|
try {
|
|
13556
|
-
const statePath =
|
|
13685
|
+
const statePath = resolve26(context.projectRoot, ".rig", "state", "connection.json");
|
|
13557
13686
|
if (existsSync19(statePath)) {
|
|
13558
13687
|
const parsed = JSON.parse(readFileSync13(statePath, "utf-8"));
|
|
13559
13688
|
selectedServer = parsed.remoteUrl || parsed.url || parsed.selected || null;
|
|
@@ -13562,8 +13691,14 @@ function resolveTopLevelLaunchState(context) {
|
|
|
13562
13691
|
}
|
|
13563
13692
|
return { projectInitialized, selectedServer, version: process.env.RIG_CLI_VERSION || readBuildConfig().RIG_CLI_VERSION || undefined };
|
|
13564
13693
|
}
|
|
13694
|
+
function envTruthy(value) {
|
|
13695
|
+
if (!value)
|
|
13696
|
+
return false;
|
|
13697
|
+
const normalized = value.trim().toLowerCase();
|
|
13698
|
+
return normalized !== "0" && normalized !== "false" && normalized !== "no";
|
|
13699
|
+
}
|
|
13565
13700
|
function shouldOpenApp(context) {
|
|
13566
|
-
return context.outputMode === "text" && Boolean(process.stdin.isTTY && process.stdout.isTTY) && process.env.RIG_CLI_PLAIN_HELP !== "1";
|
|
13701
|
+
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);
|
|
13567
13702
|
}
|
|
13568
13703
|
async function openApp(context, options = {}) {
|
|
13569
13704
|
const { runOperatorBoardLoop: runOperatorBoardLoop2 } = await Promise.resolve().then(() => (init_board(), exports_board));
|
|
@@ -13772,7 +13907,7 @@ var __testOnly = {
|
|
|
13772
13907
|
};
|
|
13773
13908
|
// packages/cli/src/launcher.ts
|
|
13774
13909
|
import { existsSync as existsSync20 } from "fs";
|
|
13775
|
-
import { basename as basename3, resolve as
|
|
13910
|
+
import { basename as basename3, resolve as resolve27 } from "path";
|
|
13776
13911
|
import { loadDotEnvSecrets } from "@rig/runtime/baked-secrets";
|
|
13777
13912
|
import { RIG_DEFINITION_DIRNAME, RIG_STATE_DIRNAME, resolveNearestRigProjectRoot } from "@rig/runtime/layout";
|
|
13778
13913
|
|
|
@@ -13836,7 +13971,7 @@ function parsePolicyMode(value) {
|
|
|
13836
13971
|
throw new Error(`Invalid --policy-mode value: ${value}. Use off|observe|enforce.`);
|
|
13837
13972
|
}
|
|
13838
13973
|
function hasRigProjectMarker(candidate) {
|
|
13839
|
-
return existsSync20(
|
|
13974
|
+
return existsSync20(resolve27(candidate, RIG_DEFINITION_DIRNAME)) || existsSync20(resolve27(candidate, RIG_STATE_DIRNAME)) || existsSync20(resolve27(candidate, "rig.config.ts")) || existsSync20(resolve27(candidate, "rig.config.json")) || existsSync20(resolve27(candidate, ".git"));
|
|
13840
13975
|
}
|
|
13841
13976
|
function resolveProjectRoot({
|
|
13842
13977
|
envProjectRoot,
|
|
@@ -13845,19 +13980,19 @@ function resolveProjectRoot({
|
|
|
13845
13980
|
cwd = process.cwd()
|
|
13846
13981
|
}) {
|
|
13847
13982
|
if (envProjectRoot) {
|
|
13848
|
-
return
|
|
13983
|
+
return resolve27(cwd, envProjectRoot);
|
|
13849
13984
|
}
|
|
13850
13985
|
const fallbackImportDir = importDir ?? cwd;
|
|
13851
13986
|
const execName = basename3(execPath).toLowerCase();
|
|
13852
|
-
const execCandidates = execName === "rig" || execName === "rig.exe" ? [
|
|
13853
|
-
const candidates = [cwd, ...execCandidates,
|
|
13987
|
+
const execCandidates = execName === "rig" || execName === "rig.exe" ? [resolve27(execPath, "..", "..")] : [];
|
|
13988
|
+
const candidates = [cwd, ...execCandidates, resolve27(fallbackImportDir, "..")];
|
|
13854
13989
|
for (const candidate of candidates) {
|
|
13855
13990
|
const nearest = resolveNearestRigProjectRoot(candidate);
|
|
13856
13991
|
if (hasRigProjectMarker(nearest)) {
|
|
13857
13992
|
return nearest;
|
|
13858
13993
|
}
|
|
13859
13994
|
}
|
|
13860
|
-
return
|
|
13995
|
+
return resolve27(cwd);
|
|
13861
13996
|
}
|
|
13862
13997
|
function normalizeCliErrorCode(message2, isCliError) {
|
|
13863
13998
|
if (message2.startsWith("Invalid --policy-mode value:")) {
|
|
@@ -13931,7 +14066,7 @@ async function runRigCli(module, options = {}) {
|
|
|
13931
14066
|
runId: context.runId,
|
|
13932
14067
|
outcome,
|
|
13933
14068
|
eventsFile: context.eventBus.getEventsFile(),
|
|
13934
|
-
policyFile:
|
|
14069
|
+
policyFile: resolve27(projectRoot, "rig", "policy", "policy.json"),
|
|
13935
14070
|
policyMode: context.policyMode ?? policyMode ?? module.loadPolicy(projectRoot).mode
|
|
13936
14071
|
}, null, 2));
|
|
13937
14072
|
}
|