@h-rig/cli 0.0.6-alpha.82 → 0.0.6-alpha.84
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 +23402 -14577
- package/dist/src/app/board.js +217 -41
- 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.d.ts +0 -2
- package/dist/src/app-opentui/adapters/doctor.js +64 -39
- package/dist/src/app-opentui/adapters/family.d.ts +62 -0
- package/dist/src/app-opentui/adapters/family.js +14305 -0
- package/dist/src/app-opentui/adapters/fleet.d.ts +0 -2
- package/dist/src/app-opentui/adapters/fleet.js +90 -60
- package/dist/src/app-opentui/adapters/inbox.d.ts +12 -2
- package/dist/src/app-opentui/adapters/inbox.js +137 -78
- package/dist/src/app-opentui/adapters/init.d.ts +0 -2
- package/dist/src/app-opentui/adapters/init.js +85 -47
- package/dist/src/app-opentui/adapters/inspect.d.ts +52 -0
- package/dist/src/app-opentui/adapters/inspect.js +1024 -0
- package/dist/src/app-opentui/adapters/pi-attach.d.ts +15 -6
- package/dist/src/app-opentui/adapters/pi-attach.js +442 -125
- package/dist/src/app-opentui/adapters/pi.d.ts +23 -0
- package/dist/src/app-opentui/adapters/pi.js +363 -0
- package/dist/src/app-opentui/adapters/plugin.d.ts +84 -0
- package/dist/src/app-opentui/adapters/plugin.js +544 -0
- package/dist/src/app-opentui/adapters/repo.d.ts +37 -0
- package/dist/src/app-opentui/adapters/repo.js +186 -0
- package/dist/src/app-opentui/adapters/run-detail.d.ts +9 -2
- package/dist/src/app-opentui/adapters/run-detail.js +180 -63
- package/dist/src/app-opentui/adapters/server.d.ts +10 -2
- package/dist/src/app-opentui/adapters/server.js +191 -45
- package/dist/src/app-opentui/adapters/tasks.d.ts +11 -2
- package/dist/src/app-opentui/adapters/tasks.js +1123 -143
- package/dist/src/app-opentui/adapters/workspace.d.ts +49 -0
- package/dist/src/app-opentui/adapters/workspace.js +333 -0
- package/dist/src/app-opentui/autocomplete.d.ts +20 -0
- package/dist/src/app-opentui/autocomplete.js +576 -0
- package/dist/src/app-opentui/bootstrap.d.ts +1 -6
- package/dist/src/app-opentui/bootstrap.js +25252 -16474
- package/dist/src/app-opentui/command-palette.d.ts +3 -0
- package/dist/src/app-opentui/command-palette.js +1010 -0
- 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/drone.js +8 -6
- package/dist/src/app-opentui/events.js +1 -1
- package/dist/src/app-opentui/fleet-stats.d.ts +32 -0
- package/dist/src/app-opentui/fleet-stats.js +114 -0
- 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 +5431 -2797
- package/dist/src/app-opentui/intent.js +179 -50
- package/dist/src/app-opentui/keymap.d.ts +21 -0
- package/dist/src/app-opentui/keymap.js +1748 -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.d.ts +7 -0
- package/dist/src/app-opentui/layout.js +13 -6
- package/dist/src/app-opentui/list-search.d.ts +24 -0
- package/dist/src/app-opentui/list-search.js +88 -1
- package/dist/src/app-opentui/pi-host-child.js +99 -17
- package/dist/src/app-opentui/pi-pty-host.d.ts +14 -0
- package/dist/src/app-opentui/pi-pty-host.js +30 -14
- package/dist/src/app-opentui/react/App.d.ts +9 -0
- package/dist/src/app-opentui/react/App.js +5144 -0
- package/dist/src/app-opentui/react/Backdrop.d.ts +5 -0
- package/dist/src/app-opentui/react/Backdrop.js +1834 -0
- package/dist/src/app-opentui/react/ChromeHost.d.ts +5 -0
- package/dist/src/app-opentui/react/ChromeHost.js +2942 -0
- package/dist/src/app-opentui/react/SceneFrameView.d.ts +7 -0
- package/dist/src/app-opentui/react/SceneFrameView.js +529 -0
- package/dist/src/app-opentui/react/context.d.ts +17 -0
- package/dist/src/app-opentui/react/context.js +37 -0
- package/dist/src/app-opentui/react/launch.d.ts +2 -0
- package/dist/src/app-opentui/react/launch.js +5743 -0
- package/dist/src/app-opentui/react/nav.d.ts +18 -0
- package/dist/src/app-opentui/react/nav.js +54 -0
- package/dist/src/app-opentui/react/scroll.d.ts +12 -0
- package/dist/src/app-opentui/react/scroll.js +21 -0
- package/dist/src/app-opentui/react/syntax.d.ts +2 -0
- package/dist/src/app-opentui/react/syntax.js +64 -0
- package/dist/src/app-opentui/registry.js +20428 -4828
- 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/constants.d.ts +31 -0
- package/dist/src/app-opentui/render/constants.js +66 -0
- package/dist/src/app-opentui/render/graphics.d.ts +2 -1
- package/dist/src/app-opentui/render/graphics.js +228 -46
- package/dist/src/app-opentui/render/image-visual-layer-worker.js +469 -930
- package/dist/src/app-opentui/render/image-visual-layer.d.ts +25 -10
- package/dist/src/app-opentui/render/image-visual-layer.js +448 -329
- package/dist/src/app-opentui/render/native-host.d.ts +37 -0
- package/dist/src/app-opentui/render/native-host.js +179 -0
- 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 +78 -38
- package/dist/src/app-opentui/render/preloader.d.ts +10 -0
- package/dist/src/app-opentui/render/preloader.js +165 -0
- package/dist/src/app-opentui/render/scene.d.ts +53 -1
- package/dist/src/app-opentui/render/scene.js +195 -6
- package/dist/src/app-opentui/render/text.d.ts +7 -1
- package/dist/src/app-opentui/render/text.js +15 -8
- package/dist/src/app-opentui/render/type-bar.d.ts +2 -1
- package/dist/src/app-opentui/render/type-bar.js +113 -39
- 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.d.ts +44 -1
- package/dist/src/app-opentui/runtime.js +5415 -2738
- package/dist/src/app-opentui/scenes/command.d.ts +3 -0
- package/dist/src/app-opentui/scenes/command.js +117 -0
- package/dist/src/app-opentui/scenes/doctor.d.ts +2 -1
- package/dist/src/app-opentui/scenes/doctor.js +221 -17
- package/dist/src/app-opentui/scenes/error.js +60 -20
- package/dist/src/app-opentui/scenes/family-domains/agent.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/agent.js +348 -0
- package/dist/src/app-opentui/scenes/family-domains/browser.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/browser.js +195 -0
- package/dist/src/app-opentui/scenes/family-domains/dist.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/dist.js +243 -0
- package/dist/src/app-opentui/scenes/family-domains/git.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/git.js +195 -0
- package/dist/src/app-opentui/scenes/family-domains/github.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/github.js +274 -0
- package/dist/src/app-opentui/scenes/family-domains/harness.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/harness.js +152 -0
- package/dist/src/app-opentui/scenes/family-domains/index.d.ts +4 -0
- package/dist/src/app-opentui/scenes/family-domains/index.js +1679 -0
- package/dist/src/app-opentui/scenes/family-domains/kit.d.ts +76 -0
- package/dist/src/app-opentui/scenes/family-domains/kit.js +305 -0
- package/dist/src/app-opentui/scenes/family-domains/profile.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/profile.js +212 -0
- package/dist/src/app-opentui/scenes/family-domains/queue.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/queue.js +146 -0
- package/dist/src/app-opentui/scenes/family-domains/remote.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/remote.js +518 -0
- package/dist/src/app-opentui/scenes/family-domains/review.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/review.js +280 -0
- package/dist/src/app-opentui/scenes/family-domains/setup.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/setup.js +267 -0
- package/dist/src/app-opentui/scenes/family-domains/stats.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/stats.js +370 -0
- package/dist/src/app-opentui/scenes/family.d.ts +3 -0
- package/dist/src/app-opentui/scenes/family.js +2144 -0
- package/dist/src/app-opentui/scenes/fleet.js +552 -43
- package/dist/src/app-opentui/scenes/handoff.js +342 -35
- package/dist/src/app-opentui/scenes/help.js +640 -56
- package/dist/src/app-opentui/scenes/inbox.d.ts +2 -1
- package/dist/src/app-opentui/scenes/inbox.js +329 -21
- package/dist/src/app-opentui/scenes/init.d.ts +2 -1
- package/dist/src/app-opentui/scenes/init.js +120 -34
- package/dist/src/app-opentui/scenes/inspect.d.ts +3 -0
- package/dist/src/app-opentui/scenes/inspect.js +793 -0
- package/dist/src/app-opentui/scenes/main.d.ts +2 -1
- package/dist/src/app-opentui/scenes/main.js +264 -29
- package/dist/src/app-opentui/scenes/pi.d.ts +3 -0
- package/dist/src/app-opentui/scenes/pi.js +508 -0
- package/dist/src/app-opentui/scenes/plugin.d.ts +3 -0
- package/dist/src/app-opentui/scenes/plugin.js +486 -0
- package/dist/src/app-opentui/scenes/repo.d.ts +3 -0
- package/dist/src/app-opentui/scenes/repo.js +424 -0
- package/dist/src/app-opentui/scenes/run-detail.d.ts +2 -1
- package/dist/src/app-opentui/scenes/run-detail.js +362 -35
- package/dist/src/app-opentui/scenes/server.d.ts +2 -1
- package/dist/src/app-opentui/scenes/server.js +243 -26
- package/dist/src/app-opentui/scenes/tasks.js +518 -41
- package/dist/src/app-opentui/scenes/workspace.d.ts +3 -0
- package/dist/src/app-opentui/scenes/workspace.js +426 -0
- package/dist/src/app-opentui/selectable.d.ts +19 -0
- package/dist/src/app-opentui/selectable.js +79 -0
- package/dist/src/app-opentui/state.js +129 -36
- package/dist/src/app-opentui/surface-catalog.d.ts +20 -0
- package/dist/src/app-opentui/surface-catalog.js +540 -0
- 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/theme.d.ts +28 -6
- package/dist/src/app-opentui/theme.js +61 -8
- package/dist/src/app-opentui/types.d.ts +130 -5
- package/dist/src/commands/_authority-runs.d.ts +1 -1
- package/dist/src/commands/_authority-runs.js +2 -12
- package/dist/src/commands/_doctor-checks.js +62 -13
- package/dist/src/commands/_help-catalog.js +95 -15
- package/dist/src/commands/_operator-view.js +97 -15
- package/dist/src/commands/_pi-frontend.d.ts +2 -0
- package/dist/src/commands/_pi-frontend.js +97 -13
- package/dist/src/commands/_preflight.js +64 -14
- package/dist/src/commands/_server-client.js +82 -18
- package/dist/src/commands/_server-events.d.ts +26 -0
- package/dist/src/commands/_server-events.js +310 -0
- package/dist/src/commands/_snapshot-upload.js +62 -13
- package/dist/src/commands/agent.js +2 -12
- 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 +100 -15
- package/dist/src/commands/server.js +71 -26
- package/dist/src/commands/setup.js +62 -13
- package/dist/src/commands/stats.js +157 -28
- package/dist/src/commands/task-run-driver.js +64 -25
- package/dist/src/commands/task.js +196 -43
- package/dist/src/commands.js +419 -123
- package/dist/src/index.js +426 -130
- package/package.json +11 -10
- 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/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>`."));
|
|
@@ -1591,18 +1656,8 @@ import {
|
|
|
1591
1656
|
readJsonlFile as readJsonlFile2,
|
|
1592
1657
|
writeAuthorityRunRecord
|
|
1593
1658
|
} from "@rig/runtime/control-plane/authority-files";
|
|
1594
|
-
function normalizeRuntimeAdapter(
|
|
1595
|
-
|
|
1596
|
-
if (!normalized) {
|
|
1597
|
-
return "pi";
|
|
1598
|
-
}
|
|
1599
|
-
if (normalized === "codex" || normalized === "codex-cli" || normalized === "codex-app-server" || normalized === "gpt-codex") {
|
|
1600
|
-
return "codex";
|
|
1601
|
-
}
|
|
1602
|
-
if (normalized === "pi" || normalized === "rig-pi" || normalized === "@rig/pi") {
|
|
1603
|
-
return "pi";
|
|
1604
|
-
}
|
|
1605
|
-
return "claude-code";
|
|
1659
|
+
function normalizeRuntimeAdapter(_value) {
|
|
1660
|
+
return "pi";
|
|
1606
1661
|
}
|
|
1607
1662
|
function readLatestBeadRecord(projectRoot, taskId) {
|
|
1608
1663
|
const issuesPath = resolve11(resolveControlPlaneMonorepoRoot(projectRoot), ".beads", "issues.jsonl");
|
|
@@ -2524,7 +2579,7 @@ var init__operator_surface = __esm(() => {
|
|
|
2524
2579
|
});
|
|
2525
2580
|
|
|
2526
2581
|
// packages/cli/src/commands/_pi-frontend.ts
|
|
2527
|
-
import { existsSync as existsSync14, mkdirSync as
|
|
2582
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync9, mkdtempSync, readFileSync as readFileSync10, rmSync as rmSync5, writeFileSync as writeFileSync7 } from "fs";
|
|
2528
2583
|
import { homedir as homedir6, tmpdir } from "os";
|
|
2529
2584
|
import { join as join3 } from "path";
|
|
2530
2585
|
import { main as runPiMain } from "@earendil-works/pi-coding-agent";
|
|
@@ -2556,10 +2611,27 @@ function buildOperatorPiEnv(input) {
|
|
|
2556
2611
|
...input.serverProjectRoot ? { RIG_PROJECT_ROOT: input.serverProjectRoot } : {}
|
|
2557
2612
|
};
|
|
2558
2613
|
}
|
|
2614
|
+
function shouldRequireOperatorTranscript(status) {
|
|
2615
|
+
return typeof status === "string" && TERMINAL_RUN_STATUSES.has(status.trim().toLowerCase());
|
|
2616
|
+
}
|
|
2617
|
+
function missingOperatorTranscriptMessage(runId, status) {
|
|
2618
|
+
const shortRun = runId.trim().slice(0, 8) || "unknown";
|
|
2619
|
+
const statusText = typeof status === "string" && status.trim() ? status.trim() : "terminal";
|
|
2620
|
+
return `Run ${shortRun} is ${statusText}, but no worker Pi session transcript is recorded for this run. It likely failed before Pi started or predates full-session capture. Use \`rig run show ${runId}\` and \`rig run logs ${runId}\` for the lifecycle details.`;
|
|
2621
|
+
}
|
|
2622
|
+
function statusFromRunDetails(run) {
|
|
2623
|
+
if (!run || typeof run !== "object" || Array.isArray(run))
|
|
2624
|
+
return;
|
|
2625
|
+
const record = run;
|
|
2626
|
+
if (typeof record.status === "string")
|
|
2627
|
+
return record.status;
|
|
2628
|
+
const nested = record.run;
|
|
2629
|
+
return nested && typeof nested === "object" && !Array.isArray(nested) ? nested.status : undefined;
|
|
2630
|
+
}
|
|
2559
2631
|
async function prepareOperatorConsole(context, runId, tempSessionDir) {
|
|
2560
2632
|
const server = await ensureServerForCli(context.projectRoot);
|
|
2561
2633
|
const localCwd = join3(homedir6(), ".rig", "drones", runId.slice(0, 8));
|
|
2562
|
-
|
|
2634
|
+
mkdirSync9(localCwd, { recursive: true });
|
|
2563
2635
|
trustDroneCwd(localCwd);
|
|
2564
2636
|
installRigPiTheme();
|
|
2565
2637
|
let sessionFileArg = [];
|
|
@@ -2581,21 +2653,28 @@ async function prepareOperatorConsole(context, runId, tempSessionDir) {
|
|
|
2581
2653
|
return line;
|
|
2582
2654
|
}).join(`
|
|
2583
2655
|
`);
|
|
2584
|
-
|
|
2656
|
+
writeFileSync7(localSessionPath, content);
|
|
2585
2657
|
sessionFileArg = ["--session", localSessionPath];
|
|
2586
2658
|
}
|
|
2587
2659
|
} catch {}
|
|
2660
|
+
if (sessionFileArg.length === 0) {
|
|
2661
|
+
const run = await getRunDetailsViaServer(context, runId).catch(() => null);
|
|
2662
|
+
const status = statusFromRunDetails(run);
|
|
2663
|
+
if (shouldRequireOperatorTranscript(status)) {
|
|
2664
|
+
throw new OperatorTranscriptUnavailableError(missingOperatorTranscriptMessage(runId, status));
|
|
2665
|
+
}
|
|
2666
|
+
}
|
|
2588
2667
|
return { server, sessionFileArg };
|
|
2589
2668
|
}
|
|
2590
2669
|
function trustDroneCwd(localCwd) {
|
|
2591
2670
|
try {
|
|
2592
2671
|
const agentDir = join3(homedir6(), ".pi", "agent");
|
|
2593
|
-
|
|
2672
|
+
mkdirSync9(agentDir, { recursive: true });
|
|
2594
2673
|
const trustPath = join3(agentDir, "trust.json");
|
|
2595
2674
|
const store = existsSync14(trustPath) ? JSON.parse(readFileSync10(trustPath, "utf8")) : {};
|
|
2596
2675
|
if (store[localCwd] !== true) {
|
|
2597
2676
|
store[localCwd] = true;
|
|
2598
|
-
|
|
2677
|
+
writeFileSync7(trustPath, `${JSON.stringify(store, null, "\t")}
|
|
2599
2678
|
`);
|
|
2600
2679
|
}
|
|
2601
2680
|
} catch {}
|
|
@@ -2603,12 +2682,12 @@ function trustDroneCwd(localCwd) {
|
|
|
2603
2682
|
function installRigPiTheme() {
|
|
2604
2683
|
try {
|
|
2605
2684
|
const themesDir = join3(homedir6(), ".pi", "agent", "themes");
|
|
2606
|
-
|
|
2685
|
+
mkdirSync9(themesDir, { recursive: true });
|
|
2607
2686
|
const themePath = join3(themesDir, "rig.json");
|
|
2608
2687
|
const next = `${JSON.stringify(RIG_PI_THEME, null, "\t")}
|
|
2609
2688
|
`;
|
|
2610
2689
|
if (!existsSync14(themePath) || readFileSync10(themePath, "utf8") !== next) {
|
|
2611
|
-
|
|
2690
|
+
writeFileSync7(themePath, next);
|
|
2612
2691
|
}
|
|
2613
2692
|
} catch {}
|
|
2614
2693
|
}
|
|
@@ -2628,6 +2707,7 @@ async function attachRunBundledPiFrontend(context, input) {
|
|
|
2628
2707
|
let detached = false;
|
|
2629
2708
|
try {
|
|
2630
2709
|
await runPiMain([
|
|
2710
|
+
"--offline",
|
|
2631
2711
|
"--no-extensions",
|
|
2632
2712
|
"--no-skills",
|
|
2633
2713
|
"--no-prompt-templates",
|
|
@@ -2655,10 +2735,17 @@ async function attachRunBundledPiFrontend(context, input) {
|
|
|
2655
2735
|
rendered: "stock Pi operator console with the pi-rig extension"
|
|
2656
2736
|
};
|
|
2657
2737
|
}
|
|
2658
|
-
var RIG_PI_THEME;
|
|
2738
|
+
var TERMINAL_RUN_STATUSES, OperatorTranscriptUnavailableError, RIG_PI_THEME;
|
|
2659
2739
|
var init__pi_frontend = __esm(() => {
|
|
2660
2740
|
init__server_client();
|
|
2661
2741
|
init__async_ui();
|
|
2742
|
+
TERMINAL_RUN_STATUSES = new Set(["completed", "failed", "stopped", "cancelled", "canceled", "closed", "merged", "needs_attention", "needs-attention"]);
|
|
2743
|
+
OperatorTranscriptUnavailableError = class OperatorTranscriptUnavailableError extends Error {
|
|
2744
|
+
constructor(message2) {
|
|
2745
|
+
super(message2);
|
|
2746
|
+
this.name = "OperatorTranscriptUnavailableError";
|
|
2747
|
+
}
|
|
2748
|
+
};
|
|
2662
2749
|
RIG_PI_THEME = {
|
|
2663
2750
|
$schema: "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
|
|
2664
2751
|
name: "rig",
|
|
@@ -2813,7 +2900,7 @@ async function attachRunOperatorView(context, input) {
|
|
|
2813
2900
|
}
|
|
2814
2901
|
const pollMs = Math.max(250, Math.trunc(input.pollMs ?? 2000));
|
|
2815
2902
|
let timelineCursor = snapshot.timelineCursor;
|
|
2816
|
-
while (!detached && !
|
|
2903
|
+
while (!detached && !TERMINAL_RUN_STATUSES2.has(runStatusFromPayload(snapshot.run))) {
|
|
2817
2904
|
await Bun.sleep(pollMs);
|
|
2818
2905
|
snapshot = await readOperatorSnapshot(context, input.runId, { timelineCursor });
|
|
2819
2906
|
timelineCursor = snapshot.timelineCursor;
|
|
@@ -2825,13 +2912,13 @@ async function attachRunOperatorView(context, input) {
|
|
|
2825
2912
|
}
|
|
2826
2913
|
return { ...snapshot, steered, detached };
|
|
2827
2914
|
}
|
|
2828
|
-
var
|
|
2915
|
+
var TERMINAL_RUN_STATUSES2;
|
|
2829
2916
|
var init__operator_view = __esm(() => {
|
|
2830
2917
|
init__server_client();
|
|
2831
2918
|
init__operator_surface();
|
|
2832
2919
|
init__pi_frontend();
|
|
2833
2920
|
init__async_ui();
|
|
2834
|
-
|
|
2921
|
+
TERMINAL_RUN_STATUSES2 = new Set(["completed", "failed", "stopped", "cancelled", "canceled", "closed", "merged", "needs_attention", "needs-attention"]);
|
|
2835
2922
|
});
|
|
2836
2923
|
|
|
2837
2924
|
// packages/cli/src/commands/_help-catalog.ts
|
|
@@ -3188,30 +3275,62 @@ var init__help_catalog = __esm(() => {
|
|
|
3188
3275
|
}
|
|
3189
3276
|
];
|
|
3190
3277
|
ADVANCED_GROUPS = [
|
|
3191
|
-
{
|
|
3192
|
-
|
|
3278
|
+
{
|
|
3279
|
+
name: "setup",
|
|
3280
|
+
summary: "Bootstrap/check local setup.",
|
|
3281
|
+
usage: ["rig setup <bootstrap|check|preflight>"],
|
|
3282
|
+
commands: [
|
|
3283
|
+
{ command: "bootstrap", description: "Bootstrap local setup dependencies.", primary: true },
|
|
3284
|
+
{ command: "check", description: "Check local setup state (toolchain, deps, config).", primary: true },
|
|
3285
|
+
{ command: "preflight", description: "Run preflight checks before a run.", primary: true }
|
|
3286
|
+
]
|
|
3287
|
+
},
|
|
3288
|
+
{
|
|
3289
|
+
name: "profile",
|
|
3290
|
+
summary: "Runtime profile/model defaults.",
|
|
3291
|
+
usage: ["rig profile <show|set>"],
|
|
3292
|
+
commands: [
|
|
3293
|
+
{ command: "show", description: "Show the active execution profile.", primary: true },
|
|
3294
|
+
{ command: "set [--model <model>] [--runtime <runtime>] [--plugin <plugin>]", description: "Set model/runtime/plugin profile defaults.", primary: true }
|
|
3295
|
+
]
|
|
3296
|
+
},
|
|
3193
3297
|
{
|
|
3194
3298
|
name: "review",
|
|
3195
3299
|
summary: "Inspect or change completion review gate policy.",
|
|
3196
3300
|
usage: ["rig review <show|set>"],
|
|
3197
3301
|
commands: [
|
|
3198
3302
|
{ command: "show", description: "Show current review gate settings." },
|
|
3199
|
-
{ command: "set <off|advisory|required> [--provider
|
|
3303
|
+
{ command: "set <off|advisory|required> [--provider <provider>]", description: "Change review strictness/provider (e.g. --provider greptile)." }
|
|
3200
3304
|
],
|
|
3201
3305
|
examples: ["rig review show", "rig review set required --provider greptile"],
|
|
3202
3306
|
next: ["Use `rig inbox approvals` for blocked run handoffs."]
|
|
3203
3307
|
},
|
|
3204
3308
|
{
|
|
3205
3309
|
name: "browser",
|
|
3206
|
-
summary: "Browser
|
|
3207
|
-
usage: ["rig browser <help|explain|demo|
|
|
3310
|
+
summary: "Browser workstation actions for browser-required tasks: launch, check, CDP probe, profile reset, and app-specific smokes.",
|
|
3311
|
+
usage: ["rig browser <help|explain|demo|hp-next|cdp-probe|profile-persistence|profile-lock-check|smoke-test> [options]"],
|
|
3208
3312
|
commands: [
|
|
3209
|
-
{ command: "help", description: "Rich browser command help (canonical: `rig browser help`)." },
|
|
3210
|
-
{ command: "explain", description: "Explain the browser-required task contract." },
|
|
3211
|
-
{ command: "demo", description: "Run
|
|
3212
|
-
{ command: "
|
|
3213
|
-
{ command: "hp-next
|
|
3214
|
-
|
|
3313
|
+
{ command: "help", description: "Rich browser command help (canonical: `rig browser help`).", primary: true },
|
|
3314
|
+
{ command: "explain", description: "Explain the browser-required task contract and runtime helper commands.", primary: true },
|
|
3315
|
+
{ command: "demo [--port <n>] [--profile <name>] [--state-dir <path>] [--target-url <url>] [--keep-open] [--no-build]", description: "Run a guided real browser/agent demo flow.", primary: true },
|
|
3316
|
+
{ command: "hp-next dev", description: "Start hp-next Rig Browser in dev/watch mode.", primary: true },
|
|
3317
|
+
{ command: "hp-next start", description: "Build/start the hp-next browser workstation without watch mode.", primary: true },
|
|
3318
|
+
{ command: "hp-next check", description: "Validate the hp-next CDP endpoint on the configured port.", primary: true },
|
|
3319
|
+
{ command: "hp-next e2e", description: "Run hp-next browser e2e smoke checks through Rig Browser.", primary: true },
|
|
3320
|
+
{ command: "hp-next reset", description: "Reset the hp-next browser profile when stale browser state is suspected.", primary: true },
|
|
3321
|
+
{ command: "cdp-probe", description: "Run an isolated CDP attach/evaluate/layout probe." },
|
|
3322
|
+
{ command: "profile-persistence", description: "Verify a named browser profile persists browser state." },
|
|
3323
|
+
{ command: "profile-lock-check", description: "Verify concurrent launches reject the same profile." },
|
|
3324
|
+
{ command: "smoke-test", description: "Run the browser package smoke test." }
|
|
3325
|
+
],
|
|
3326
|
+
examples: [
|
|
3327
|
+
"rig browser help",
|
|
3328
|
+
"rig browser hp-next check",
|
|
3329
|
+
"rig browser hp-next e2e",
|
|
3330
|
+
"rig browser cdp-probe",
|
|
3331
|
+
"rig browser profile-lock-check"
|
|
3332
|
+
],
|
|
3333
|
+
next: ["Inside a task run, use rig-browser-launch, rig-browser-check, and rig-browser-attach-info from the worker PATH."]
|
|
3215
3334
|
},
|
|
3216
3335
|
{
|
|
3217
3336
|
name: "pi",
|
|
@@ -3226,12 +3345,60 @@ var init__help_catalog = __esm(() => {
|
|
|
3226
3345
|
examples: ["rig pi search subagents", "rig pi add pi-subagents", "rig pi list"],
|
|
3227
3346
|
next: ["Config-managed extensions: declare `runtime: { pi: { packages: [...] } }` in rig.config.ts \u2014 workers pick them up automatically."]
|
|
3228
3347
|
},
|
|
3229
|
-
{
|
|
3230
|
-
|
|
3348
|
+
{
|
|
3349
|
+
name: "queue",
|
|
3350
|
+
summary: "Run task queues locally.",
|
|
3351
|
+
usage: ["rig queue run [--workers <n>] [--max-tasks <n>] [--action validate|verify|pipeline] [--isolation off|worktree] [--no-runtime-reuse] [--fail-fast] [--skip-project-sync]"],
|
|
3352
|
+
commands: [
|
|
3353
|
+
{ command: "run [--workers <n>] [--max-tasks <n>] [--action validate|verify|pipeline] [--isolation off|worktree] [--no-runtime-reuse] [--fail-fast] [--skip-project-sync]", description: "Process queue work: drain matching tasks with N workers, optional per-task action and isolation.", primary: true }
|
|
3354
|
+
]
|
|
3355
|
+
},
|
|
3356
|
+
{
|
|
3357
|
+
name: "agent",
|
|
3358
|
+
summary: "Runtime agent workspace helpers.",
|
|
3359
|
+
usage: ["rig agent <list|prepare|run|cleanup>"],
|
|
3360
|
+
commands: [
|
|
3361
|
+
{ command: "list", description: "List prepared agent runtimes.", primary: true },
|
|
3362
|
+
{ command: "prepare [--id <id>] [--mode <mode>] [--task <task>]", description: "Prepare an isolated agent runtime workspace.", primary: true },
|
|
3363
|
+
{ command: "run [--id <id>] [--mode <mode>] [--task <task>] [--skip-project-sync]", description: "Prepare (if needed) and run an agent in its workspace.", primary: true },
|
|
3364
|
+
{ command: "cleanup [--all] [--id <id>]", description: "Remove prepared agent workspaces.", primary: true }
|
|
3365
|
+
]
|
|
3366
|
+
},
|
|
3231
3367
|
{ name: "inspector", summary: "Event stream and drift scanners.", usage: ["rig inspector <stream|scan-upstream-drift>"], commands: [{ command: "stream", description: "Stream events." }] },
|
|
3232
|
-
{
|
|
3368
|
+
{
|
|
3369
|
+
name: "dist",
|
|
3370
|
+
summary: "Build/install packaged Rig CLI.",
|
|
3371
|
+
usage: ["rig dist <build|install|doctor|rebuild-agent>"],
|
|
3372
|
+
commands: [
|
|
3373
|
+
{ command: "build [--output-dir <dir>]", description: "Build the distributable Rig CLI.", primary: true },
|
|
3374
|
+
{ command: "install [--scope <scope>] [--path <path>]", description: "Install the built CLI to a scope/path.", primary: true },
|
|
3375
|
+
{ command: "doctor", description: "Diagnose the dist toolchain and install state.", primary: true },
|
|
3376
|
+
{ command: "rebuild-agent", description: "Rebuild the agent runtime image, pruning stale images.", primary: true }
|
|
3377
|
+
]
|
|
3378
|
+
},
|
|
3233
3379
|
{ name: "workspace", summary: "Workspace topology/service helpers.", usage: ["rig workspace <summary|topology|remote-hosts>"], commands: [{ command: "summary", description: "Show workspace summary." }] },
|
|
3234
|
-
{
|
|
3380
|
+
{
|
|
3381
|
+
name: "remote",
|
|
3382
|
+
summary: "Compatibility remote orchestration controls.",
|
|
3383
|
+
usage: ["rig remote <status|tasks|watch|pause|resume|continue|stop|refresh|add-iterations|remove-iterations|endpoint ...>"],
|
|
3384
|
+
commands: [
|
|
3385
|
+
{ command: "status [--remote <alias>]", description: "Show the remote orchestration state.", primary: true },
|
|
3386
|
+
{ command: "tasks [--remote <alias>]", description: "List the remote's tracked tasks.", primary: true },
|
|
3387
|
+
{ command: "watch [--remote <alias>] [--seconds <n>] [--event <type>]", description: "Stream remote orchestration events.", primary: true },
|
|
3388
|
+
{ command: "pause [--remote <alias>]", description: "Pause the running remote orchestration.", primary: true },
|
|
3389
|
+
{ command: "resume [--remote <alias>] [--max-workers <n>] [--max-iterations <n>] [--direct-merge]", description: "Resume the remote with optional tuning.", primary: true },
|
|
3390
|
+
{ command: "continue [--remote <alias>]", description: "Continue a paused remote orchestration.", primary: true },
|
|
3391
|
+
{ command: "stop [--remote <alias>]", description: "Stop the remote orchestration.", primary: true },
|
|
3392
|
+
{ command: "refresh [--remote <alias>]", description: "Refresh remote state.", primary: true },
|
|
3393
|
+
{ command: "add-iterations [--count <n>] [--remote <alias>]", description: "Grant the remote more iterations.", primary: true },
|
|
3394
|
+
{ command: "remove-iterations [--count <n>] [--remote <alias>]", description: "Reduce the remote's iteration budget.", primary: true },
|
|
3395
|
+
{ command: "endpoint list", description: "List configured remote endpoints.", primary: true },
|
|
3396
|
+
{ command: "endpoint add --alias <alias> --host <host> --port <n> [--token <token>]", description: "Register a remote endpoint.", primary: true },
|
|
3397
|
+
{ command: "endpoint remove --alias <alias>", description: "Remove a remote endpoint.", primary: true },
|
|
3398
|
+
{ command: "endpoint test [--alias <alias>]", description: "Test connectivity to a remote endpoint.", primary: true },
|
|
3399
|
+
{ command: "endpoint doctor", description: "Diagnose remote endpoint configuration.", primary: true }
|
|
3400
|
+
]
|
|
3401
|
+
},
|
|
3235
3402
|
{ name: "git", summary: "Pass through to Rig git-flow helper.", usage: ["rig git <args...>"], commands: [{ command: "<args...>", description: "Advanced git flow operations." }] },
|
|
3236
3403
|
{ name: "harness", summary: "Pass through to runtime harness CLI.", usage: ["rig harness <args...>"], commands: [{ command: "<args...>", description: "Advanced harness operations." }] },
|
|
3237
3404
|
{ name: "test", summary: "Project test wrappers.", usage: ["rig test <unit|e2e|all>"], commands: [{ command: "all", description: "Run configured project tests." }] }
|
|
@@ -3298,7 +3465,7 @@ var init__task_picker = __esm(() => {
|
|
|
3298
3465
|
// packages/cli/src/commands/task.ts
|
|
3299
3466
|
import { readFileSync as readFileSync11 } from "fs";
|
|
3300
3467
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
3301
|
-
import { resolve as
|
|
3468
|
+
import { resolve as resolve22 } from "path";
|
|
3302
3469
|
import {
|
|
3303
3470
|
taskArtifactDir,
|
|
3304
3471
|
taskArtifacts,
|
|
@@ -3576,7 +3743,7 @@ async function executeTask(context, args, options) {
|
|
|
3576
3743
|
const fileFlag = takeOption(rest.slice(1), "--file");
|
|
3577
3744
|
let content;
|
|
3578
3745
|
if (fileFlag.value) {
|
|
3579
|
-
content = readFileSync11(
|
|
3746
|
+
content = readFileSync11(resolve22(context.projectRoot, fileFlag.value), "utf-8");
|
|
3580
3747
|
} else {
|
|
3581
3748
|
content = await readStdin();
|
|
3582
3749
|
}
|
|
@@ -3814,6 +3981,47 @@ var init_task = __esm(() => {
|
|
|
3814
3981
|
init__connection_state();
|
|
3815
3982
|
});
|
|
3816
3983
|
|
|
3984
|
+
// packages/cli/src/commands/_server-events.ts
|
|
3985
|
+
import { WsTransport } from "@rig/client";
|
|
3986
|
+
import { RIG_WS_CHANNELS } from "@rig/contracts";
|
|
3987
|
+
function buildRigWebSocketUrl(baseUrl, authToken) {
|
|
3988
|
+
const url = new URL(baseUrl);
|
|
3989
|
+
url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
|
|
3990
|
+
if (authToken)
|
|
3991
|
+
url.searchParams.set("token", authToken);
|
|
3992
|
+
return url.toString();
|
|
3993
|
+
}
|
|
3994
|
+
async function connectRigServerEvents(projectRoot, handlers) {
|
|
3995
|
+
const { baseUrl, authToken } = await ensureServerForCli(projectRoot);
|
|
3996
|
+
const transport = new WsTransport(buildRigWebSocketUrl(baseUrl, authToken));
|
|
3997
|
+
const unsubscribers = [];
|
|
3998
|
+
if (handlers.onSnapshotInvalidated)
|
|
3999
|
+
unsubscribers.push(transport.subscribe(RIG_WS_CHANNELS.snapshotInvalidated, handlers.onSnapshotInvalidated));
|
|
4000
|
+
if (handlers.onRunLogAppended)
|
|
4001
|
+
unsubscribers.push(transport.subscribe(RIG_WS_CHANNELS.runLogAppended, handlers.onRunLogAppended));
|
|
4002
|
+
if (handlers.onEngineEvent)
|
|
4003
|
+
unsubscribers.push(transport.subscribe(RIG_WS_CHANNELS.event, handlers.onEngineEvent));
|
|
4004
|
+
let status = "connecting";
|
|
4005
|
+
unsubscribers.push(transport.subscribeState((state) => {
|
|
4006
|
+
status = state.status;
|
|
4007
|
+
handlers.onStatus?.(state.status);
|
|
4008
|
+
}));
|
|
4009
|
+
return {
|
|
4010
|
+
connected: () => status === "connected",
|
|
4011
|
+
close: () => {
|
|
4012
|
+
for (const unsubscribe of unsubscribers) {
|
|
4013
|
+
try {
|
|
4014
|
+
unsubscribe();
|
|
4015
|
+
} catch {}
|
|
4016
|
+
}
|
|
4017
|
+
transport.dispose();
|
|
4018
|
+
}
|
|
4019
|
+
};
|
|
4020
|
+
}
|
|
4021
|
+
var init__server_events = __esm(() => {
|
|
4022
|
+
init__server_client();
|
|
4023
|
+
});
|
|
4024
|
+
|
|
3817
4025
|
// packages/cli/src/app/board.ts
|
|
3818
4026
|
var exports_board = {};
|
|
3819
4027
|
__export(exports_board, {
|
|
@@ -4652,21 +4860,39 @@ async function runOperatorBoard(context, options = {}) {
|
|
|
4652
4860
|
tui.requestRender();
|
|
4653
4861
|
}
|
|
4654
4862
|
}, BOARD_TICK_MS);
|
|
4863
|
+
const live = { subscription: null };
|
|
4864
|
+
const refreshActiveView = () => {
|
|
4865
|
+
refresh({ quiet: true });
|
|
4866
|
+
if (view === "tasks")
|
|
4867
|
+
refreshTasks();
|
|
4868
|
+
if (view === "inbox")
|
|
4869
|
+
refreshInbox();
|
|
4870
|
+
};
|
|
4871
|
+
connectRigServerEvents(context.projectRoot, {
|
|
4872
|
+
onSnapshotInvalidated: () => refreshActiveView()
|
|
4873
|
+
}).then((subscription) => {
|
|
4874
|
+
live.subscription = subscription;
|
|
4875
|
+
}).catch(() => {
|
|
4876
|
+
live.subscription = null;
|
|
4877
|
+
});
|
|
4655
4878
|
const refreshTimer = setInterval(() => {
|
|
4879
|
+
if (live.subscription?.connected())
|
|
4880
|
+
return;
|
|
4656
4881
|
refresh();
|
|
4657
4882
|
}, BOARD_REFRESH_MS);
|
|
4658
4883
|
tui.start();
|
|
4659
4884
|
refresh({ quiet: true });
|
|
4660
|
-
await new Promise((
|
|
4885
|
+
await new Promise((resolve25) => {
|
|
4661
4886
|
const poll = setInterval(() => {
|
|
4662
4887
|
if (stopped) {
|
|
4663
4888
|
clearInterval(poll);
|
|
4664
|
-
|
|
4889
|
+
resolve25();
|
|
4665
4890
|
}
|
|
4666
4891
|
}, 50);
|
|
4667
4892
|
});
|
|
4668
4893
|
clearInterval(animation);
|
|
4669
4894
|
clearInterval(refreshTimer);
|
|
4895
|
+
live.subscription?.close();
|
|
4670
4896
|
return outcome;
|
|
4671
4897
|
}
|
|
4672
4898
|
async function runOperatorBoardLoop(context, attach, options = {}) {
|
|
@@ -4685,6 +4911,7 @@ var init_board = __esm(() => {
|
|
|
4685
4911
|
init__help_catalog();
|
|
4686
4912
|
init__server_client();
|
|
4687
4913
|
init__authority_runs();
|
|
4914
|
+
init__server_events();
|
|
4688
4915
|
init_inbox();
|
|
4689
4916
|
init_task();
|
|
4690
4917
|
});
|
|
@@ -4695,7 +4922,7 @@ import {
|
|
|
4695
4922
|
existsSync as existsSync18,
|
|
4696
4923
|
readFileSync as readFileSync13
|
|
4697
4924
|
} from "fs";
|
|
4698
|
-
import { resolve as
|
|
4925
|
+
import { resolve as resolve25 } from "path";
|
|
4699
4926
|
import { readBuildConfig } from "@rig/runtime/build-time-config";
|
|
4700
4927
|
|
|
4701
4928
|
// packages/cli/src/commands/browser.ts
|
|
@@ -8923,14 +9150,64 @@ Usage: rig init`, 1);
|
|
|
8923
9150
|
// packages/cli/src/commands/github.ts
|
|
8924
9151
|
init_runner();
|
|
8925
9152
|
init__server_client();
|
|
9153
|
+
init__connection_state();
|
|
8926
9154
|
init__async_ui();
|
|
8927
9155
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
9156
|
+
import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync6 } from "fs";
|
|
9157
|
+
import { dirname as dirname4, resolve as resolve18 } from "path";
|
|
8928
9158
|
function printPayload(context, payload, fallback) {
|
|
8929
9159
|
if (context.outputMode === "json")
|
|
8930
9160
|
console.log(JSON.stringify(payload, null, 2));
|
|
8931
9161
|
else
|
|
8932
9162
|
console.log(fallback);
|
|
8933
9163
|
}
|
|
9164
|
+
function apiSessionTokenFrom2(payload) {
|
|
9165
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload))
|
|
9166
|
+
return null;
|
|
9167
|
+
const token = payload.apiSessionToken;
|
|
9168
|
+
return typeof token === "string" && token.trim() ? token.trim() : null;
|
|
9169
|
+
}
|
|
9170
|
+
function payloadString(payload, key) {
|
|
9171
|
+
const value = payload[key];
|
|
9172
|
+
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
9173
|
+
}
|
|
9174
|
+
function payloadRecord(payload, key) {
|
|
9175
|
+
const value = payload[key];
|
|
9176
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
9177
|
+
}
|
|
9178
|
+
function remoteNamespaceMetadata(result) {
|
|
9179
|
+
const namespace = payloadRecord(result, "userNamespace");
|
|
9180
|
+
return {
|
|
9181
|
+
...payloadString(result, "login") ? { login: payloadString(result, "login") } : {},
|
|
9182
|
+
...payloadString(result, "userId") ? { userId: payloadString(result, "userId") } : {},
|
|
9183
|
+
...namespace && payloadString(namespace, "key") ? { userNamespaceKey: payloadString(namespace, "key") } : {},
|
|
9184
|
+
...namespace && payloadString(namespace, "root") ? { userNamespaceRoot: payloadString(namespace, "root") } : {},
|
|
9185
|
+
...namespace && payloadString(namespace, "checkoutBaseDir") ? { checkoutBaseDir: payloadString(namespace, "checkoutBaseDir") } : {},
|
|
9186
|
+
...namespace && payloadString(namespace, "snapshotBaseDir") ? { snapshotBaseDir: payloadString(namespace, "snapshotBaseDir") } : {}
|
|
9187
|
+
};
|
|
9188
|
+
}
|
|
9189
|
+
function persistRemoteAuthSession(context, source, result, fallbackToken) {
|
|
9190
|
+
const apiSessionToken = apiSessionTokenFrom2(result);
|
|
9191
|
+
setGitHubBearerTokenForCurrentProcess(apiSessionToken ?? fallbackToken, context.projectRoot);
|
|
9192
|
+
if (!apiSessionToken)
|
|
9193
|
+
return;
|
|
9194
|
+
const repo = readRepoConnection(context.projectRoot);
|
|
9195
|
+
const path = resolve18(context.projectRoot, ".rig", "state", "github-auth.json");
|
|
9196
|
+
mkdirSync8(dirname4(path), { recursive: true });
|
|
9197
|
+
writeFileSync6(path, `${JSON.stringify({
|
|
9198
|
+
authenticated: true,
|
|
9199
|
+
source,
|
|
9200
|
+
storedOnServer: true,
|
|
9201
|
+
...repo?.project ? { selectedRepo: repo.project } : {},
|
|
9202
|
+
...remoteNamespaceMetadata(result),
|
|
9203
|
+
apiSessionToken,
|
|
9204
|
+
updatedAt: new Date().toISOString()
|
|
9205
|
+
}, null, 2)}
|
|
9206
|
+
`, "utf8");
|
|
9207
|
+
}
|
|
9208
|
+
function isSignedIn(status) {
|
|
9209
|
+
return status.signedIn === true || status.authenticated === true;
|
|
9210
|
+
}
|
|
8934
9211
|
function readGhToken() {
|
|
8935
9212
|
const result = spawnSync2("gh", ["auth", "token"], { encoding: "utf8" });
|
|
8936
9213
|
if (result.status !== 0) {
|
|
@@ -8952,7 +9229,7 @@ async function executeGithub(context, args) {
|
|
|
8952
9229
|
if (rest.length > 0)
|
|
8953
9230
|
throw new CliError("Usage: rig github auth status", 1);
|
|
8954
9231
|
const status = await withSpinner("Checking GitHub auth on the server\u2026", () => getGitHubAuthStatusViaServer(context), { outputMode: context.outputMode });
|
|
8955
|
-
printPayload(context, status, `GitHub auth: ${status
|
|
9232
|
+
printPayload(context, status, `GitHub auth: ${isSignedIn(status) ? "authenticated" : "unauthenticated"}`);
|
|
8956
9233
|
return { ok: true, group: "github", command: "auth status", details: status };
|
|
8957
9234
|
}
|
|
8958
9235
|
case "token": {
|
|
@@ -8962,16 +9239,20 @@ async function executeGithub(context, args) {
|
|
|
8962
9239
|
const token = parsed.value?.trim();
|
|
8963
9240
|
if (!token)
|
|
8964
9241
|
throw new CliError("Missing --token value.", 1, { hint: "Re-run as `rig github auth token --token <token>`." });
|
|
8965
|
-
const
|
|
8966
|
-
|
|
9242
|
+
const repo = readRepoConnection(context.projectRoot);
|
|
9243
|
+
const result = await withSpinner("Storing GitHub token on the server\u2026", () => postGitHubTokenViaServer(context, token, repo?.project ? { selectedRepo: repo.project } : {}), { outputMode: context.outputMode });
|
|
9244
|
+
persistRemoteAuthSession(context, "token", result, token);
|
|
9245
|
+
printPayload(context, result, "GitHub token stored on the selected server.");
|
|
8967
9246
|
return { ok: true, group: "github", command: "auth token", details: result };
|
|
8968
9247
|
}
|
|
8969
9248
|
case "import-gh": {
|
|
8970
9249
|
if (rest.length > 0)
|
|
8971
9250
|
throw new CliError("Usage: rig github auth import-gh", 1);
|
|
8972
9251
|
const importedToken = readGhToken();
|
|
8973
|
-
const
|
|
8974
|
-
|
|
9252
|
+
const repo = readRepoConnection(context.projectRoot);
|
|
9253
|
+
const result = await withSpinner("Storing GitHub token on the server\u2026", () => postGitHubTokenViaServer(context, importedToken, repo?.project ? { selectedRepo: repo.project } : {}), { outputMode: context.outputMode });
|
|
9254
|
+
persistRemoteAuthSession(context, "gh", result, importedToken);
|
|
9255
|
+
printPayload(context, result, "GitHub token imported from gh and stored on the selected server.");
|
|
8975
9256
|
return { ok: true, group: "github", command: "auth import-gh", details: result };
|
|
8976
9257
|
}
|
|
8977
9258
|
default:
|
|
@@ -9001,7 +9282,7 @@ init_runner();
|
|
|
9001
9282
|
init__authority_runs();
|
|
9002
9283
|
init__paths();
|
|
9003
9284
|
import { readFileSync as readFileSync8 } from "fs";
|
|
9004
|
-
import { resolve as
|
|
9285
|
+
import { resolve as resolve19 } from "path";
|
|
9005
9286
|
import {
|
|
9006
9287
|
appendRunJournalEvent,
|
|
9007
9288
|
appendRunLogEntry,
|
|
@@ -9038,7 +9319,7 @@ function touchAuthorityRun(projectRoot, runId) {
|
|
|
9038
9319
|
if (!current) {
|
|
9039
9320
|
return;
|
|
9040
9321
|
}
|
|
9041
|
-
writeJsonFile3(
|
|
9322
|
+
writeJsonFile3(resolve19(resolveAuthorityRunDir(projectRoot, runId), "run.json"), {
|
|
9042
9323
|
...current,
|
|
9043
9324
|
updatedAt: new Date().toISOString()
|
|
9044
9325
|
});
|
|
@@ -9276,7 +9557,7 @@ init_runner();
|
|
|
9276
9557
|
init__server_client();
|
|
9277
9558
|
init__async_ui();
|
|
9278
9559
|
import { existsSync as existsSync12, readFileSync as readFileSync9 } from "fs";
|
|
9279
|
-
import { resolve as
|
|
9560
|
+
import { resolve as resolve20 } from "path";
|
|
9280
9561
|
import {
|
|
9281
9562
|
listAuthorityRuns,
|
|
9282
9563
|
readAuthorityRun as readAuthorityRun3,
|
|
@@ -9320,7 +9601,7 @@ async function executeInspect(context, args) {
|
|
|
9320
9601
|
}
|
|
9321
9602
|
return { ok: true, group: "inspect", command, details: { task: requiredTask, runId: fallback.runId, source: "server", entries } };
|
|
9322
9603
|
}
|
|
9323
|
-
const logsPath =
|
|
9604
|
+
const logsPath = resolve20(resolveAuthorityRunDir2(context.projectRoot, latestRun.runId), "logs.jsonl");
|
|
9324
9605
|
if (!existsSync12(logsPath)) {
|
|
9325
9606
|
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
9607
|
}
|
|
@@ -9408,7 +9689,7 @@ async function executeInspect(context, args) {
|
|
|
9408
9689
|
return { ok: true, group: "inspect", command };
|
|
9409
9690
|
case "audit": {
|
|
9410
9691
|
requireNoExtraArgs(rest, "rig inspect audit");
|
|
9411
|
-
const auditPath =
|
|
9692
|
+
const auditPath = resolve20(resolveHarnessPaths2(context.projectRoot).logsDir, "audit.jsonl");
|
|
9412
9693
|
if (!existsSync12(auditPath)) {
|
|
9413
9694
|
console.log("No audit log found.");
|
|
9414
9695
|
} else {
|
|
@@ -10067,7 +10348,7 @@ import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/co
|
|
|
10067
10348
|
|
|
10068
10349
|
// packages/cli/src/commands/_run-replay.ts
|
|
10069
10350
|
import { existsSync as existsSync13, readdirSync as readdirSync2 } from "fs";
|
|
10070
|
-
import { join as join2, resolve as
|
|
10351
|
+
import { join as join2, resolve as resolve21 } from "path";
|
|
10071
10352
|
import {
|
|
10072
10353
|
readAuthorityRun as readAuthorityRun4,
|
|
10073
10354
|
readJsonlFile as readJsonlFile3,
|
|
@@ -10160,7 +10441,7 @@ function resolveRunSessionFile(record) {
|
|
|
10160
10441
|
const sessionId = text(piSession.sessionId);
|
|
10161
10442
|
if (!cwd || !sessionId)
|
|
10162
10443
|
return null;
|
|
10163
|
-
const sessionDir =
|
|
10444
|
+
const sessionDir = resolve21(cwd, ".rig", "session");
|
|
10164
10445
|
try {
|
|
10165
10446
|
const match = readdirSync2(sessionDir).find((name) => name.endsWith(`_${sessionId}.jsonl`));
|
|
10166
10447
|
return match ? join2(sessionDir, match) : null;
|
|
@@ -10658,6 +10939,9 @@ async function executeRun(context, args) {
|
|
|
10658
10939
|
console.log(`Stop requested: ${runId}`);
|
|
10659
10940
|
return { ok: true, group: "run", command, details: stopped };
|
|
10660
10941
|
}
|
|
10942
|
+
if (isRemoteConnectionSelected(context.projectRoot)) {
|
|
10943
|
+
throw new CliError("Remote run stop requires an explicit run id.", 2, { hint: "Run `rig run list`, then `rig run stop <run-id>`." });
|
|
10944
|
+
}
|
|
10661
10945
|
const result = await runStop(context.projectRoot);
|
|
10662
10946
|
if (result.remaining.length > 0) {
|
|
10663
10947
|
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 +11058,13 @@ async function executeConnectionCommand(context, args, options) {
|
|
|
10774
11058
|
if (!state.connections[alias])
|
|
10775
11059
|
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
11060
|
}
|
|
10777
|
-
const
|
|
11061
|
+
const previousRepo = readRepoConnection(context.projectRoot);
|
|
11062
|
+
const repoState = {
|
|
11063
|
+
selected: alias,
|
|
11064
|
+
...previousRepo?.project ? { project: previousRepo.project } : {},
|
|
11065
|
+
linkedAt: new Date().toISOString(),
|
|
11066
|
+
...previousRepo?.serverProjectRoot && previousRepo.selected === alias ? { serverProjectRoot: previousRepo.serverProjectRoot } : {}
|
|
11067
|
+
};
|
|
10778
11068
|
writeRepoConnection(context.projectRoot, repoState);
|
|
10779
11069
|
printJsonOrText(context, repoState, formatSuccessCard("Rig server selected", [
|
|
10780
11070
|
["selected", alias],
|
|
@@ -11009,8 +11299,8 @@ init_task();
|
|
|
11009
11299
|
|
|
11010
11300
|
// packages/cli/src/commands/task-run-driver.ts
|
|
11011
11301
|
init_runner();
|
|
11012
|
-
import { copyFileSync as copyFileSync3, existsSync as existsSync15, mkdirSync as
|
|
11013
|
-
import { resolve as
|
|
11302
|
+
import { copyFileSync as copyFileSync3, existsSync as existsSync15, mkdirSync as mkdirSync10, readFileSync as readFileSync12, statSync as statSync2, writeFileSync as writeFileSync8 } from "fs";
|
|
11303
|
+
import { resolve as resolve23 } from "path";
|
|
11014
11304
|
import { spawn as spawn2, spawnSync as spawnSync4 } from "child_process";
|
|
11015
11305
|
import { createInterface as createLineInterface } from "readline";
|
|
11016
11306
|
import { loadConfig as loadConfig2 } from "@rig/core/load-config";
|
|
@@ -11109,12 +11399,12 @@ function copyUntrackedDirtyFiles(sourceRoot, targetRoot) {
|
|
|
11109
11399
|
return 0;
|
|
11110
11400
|
let copied = 0;
|
|
11111
11401
|
for (const relativePath of listed.stdout.split("\x00").filter(Boolean)) {
|
|
11112
|
-
const sourcePath =
|
|
11113
|
-
const targetPath =
|
|
11402
|
+
const sourcePath = resolve23(sourceRoot, relativePath);
|
|
11403
|
+
const targetPath = resolve23(targetRoot, relativePath);
|
|
11114
11404
|
try {
|
|
11115
11405
|
if (!statSync2(sourcePath).isFile())
|
|
11116
11406
|
continue;
|
|
11117
|
-
|
|
11407
|
+
mkdirSync10(resolve23(targetPath, ".."), { recursive: true });
|
|
11118
11408
|
copyFileSync3(sourcePath, targetPath);
|
|
11119
11409
|
copied += 1;
|
|
11120
11410
|
} catch {}
|
|
@@ -11153,7 +11443,7 @@ function buildDirtyBaselineHandshakeEnv(input) {
|
|
|
11153
11443
|
return { RIG_BASELINE_MODE: input.baselineMode ?? "head" };
|
|
11154
11444
|
return {
|
|
11155
11445
|
RIG_BASELINE_MODE: "dirty-snapshot",
|
|
11156
|
-
RIG_DIRTY_BASELINE_READY_FILE:
|
|
11446
|
+
RIG_DIRTY_BASELINE_READY_FILE: resolve23(input.projectRoot, ".rig", "runs", input.runId, "dirty-baseline.ready.json")
|
|
11157
11447
|
};
|
|
11158
11448
|
}
|
|
11159
11449
|
function positiveInt(value, fallback) {
|
|
@@ -11258,9 +11548,9 @@ function createCommandRunner(binary) {
|
|
|
11258
11548
|
const stderrChunks = [];
|
|
11259
11549
|
child.stdout.on("data", (chunk) => stdoutChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk))));
|
|
11260
11550
|
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) =>
|
|
11551
|
+
return await new Promise((resolve24) => {
|
|
11552
|
+
child.once("error", (error) => resolve24({ exitCode: 1, stderr: error.message }));
|
|
11553
|
+
child.once("close", (code) => resolve24({
|
|
11264
11554
|
exitCode: code ?? 1,
|
|
11265
11555
|
stdout: Buffer.concat(stdoutChunks).toString("utf8"),
|
|
11266
11556
|
stderr: Buffer.concat(stderrChunks).toString("utf8")
|
|
@@ -11334,7 +11624,7 @@ async function runTaskRunPostValidationLifecycle(input) {
|
|
|
11334
11624
|
config,
|
|
11335
11625
|
sourceTask: input.sourceTask,
|
|
11336
11626
|
uploadedSnapshot: input.uploadedSnapshot,
|
|
11337
|
-
artifactRoot:
|
|
11627
|
+
artifactRoot: resolve23(input.projectRoot, "artifacts", taskId3),
|
|
11338
11628
|
command: ghCommand,
|
|
11339
11629
|
gitCommand,
|
|
11340
11630
|
steerPi,
|
|
@@ -11464,7 +11754,7 @@ function summarizeValidationFailure(projectRoot, taskId3) {
|
|
|
11464
11754
|
return null;
|
|
11465
11755
|
}
|
|
11466
11756
|
for (const artifactDir of resolveTaskArtifactDirs2(projectRoot, taskId3)) {
|
|
11467
|
-
const summary = readJsonFile3(
|
|
11757
|
+
const summary = readJsonFile3(resolve23(artifactDir, "validation-summary.json"), null);
|
|
11468
11758
|
if (!summary || summary.status !== "fail") {
|
|
11469
11759
|
continue;
|
|
11470
11760
|
}
|
|
@@ -11545,9 +11835,9 @@ function readTaskRunAcceptedArtifactState(input) {
|
|
|
11545
11835
|
if (!input.taskId || !input.workspaceDir) {
|
|
11546
11836
|
return { accepted: false, reason: null };
|
|
11547
11837
|
}
|
|
11548
|
-
const artifactDir =
|
|
11549
|
-
const reviewStatusPath =
|
|
11550
|
-
const taskResultPath =
|
|
11838
|
+
const artifactDir = resolve23(input.workspaceDir, "artifacts", input.taskId);
|
|
11839
|
+
const reviewStatusPath = resolve23(artifactDir, "review-status.txt");
|
|
11840
|
+
const taskResultPath = resolve23(artifactDir, "task-result.json");
|
|
11551
11841
|
const reviewStatus = readTaskRunReviewStatus(reviewStatusPath);
|
|
11552
11842
|
if (reviewStatus !== "APPROVED") {
|
|
11553
11843
|
return { accepted: false, reason: null };
|
|
@@ -11584,12 +11874,12 @@ function resolveTaskRunRetryContext(input) {
|
|
|
11584
11874
|
if (!input.taskId || !input.workspaceDir) {
|
|
11585
11875
|
return { shouldRetry: false, failureDetail: null, nextPrompt: null };
|
|
11586
11876
|
}
|
|
11587
|
-
const artifactDir =
|
|
11588
|
-
const reviewStatePath =
|
|
11589
|
-
const reviewFeedbackPath =
|
|
11590
|
-
const reviewStatusPath =
|
|
11591
|
-
const failedApproachesPath =
|
|
11592
|
-
const validationSummaryPath =
|
|
11877
|
+
const artifactDir = resolve23(input.workspaceDir, "artifacts", input.taskId);
|
|
11878
|
+
const reviewStatePath = resolve23(artifactDir, "review-state.json");
|
|
11879
|
+
const reviewFeedbackPath = resolve23(artifactDir, "review-feedback.md");
|
|
11880
|
+
const reviewStatusPath = resolve23(artifactDir, "review-status.txt");
|
|
11881
|
+
const failedApproachesPath = resolve23(input.workspaceDir, ".rig", "state", "failed_approaches.md");
|
|
11882
|
+
const validationSummaryPath = resolve23(artifactDir, "validation-summary.json");
|
|
11593
11883
|
const reviewState = readJsonFile3(reviewStatePath, null);
|
|
11594
11884
|
const reviewStatus = readTaskRunReviewStatus(reviewStatusPath);
|
|
11595
11885
|
const reviewRejected = isTaskRunReviewRejected(reviewState);
|
|
@@ -11999,15 +12289,15 @@ async function executeRigOwnedTaskRun(context, input) {
|
|
|
11999
12289
|
const loadedAutomationConfig = await loadTaskRunAutomationConfig(context.projectRoot);
|
|
12000
12290
|
const automationConfig = input.prMode ? { ...loadedAutomationConfig ?? {}, pr: { ...loadedAutomationConfig?.pr ?? {}, mode: input.prMode } } : loadedAutomationConfig;
|
|
12001
12291
|
const planningClassification = classifyPlanningNeed({ config: automationConfig, sourceTask });
|
|
12002
|
-
const planningArtifactPath =
|
|
12292
|
+
const planningArtifactPath = resolve23("artifacts", runtimeTaskId, "implementation-plan.md");
|
|
12003
12293
|
const persistedPlanning = {
|
|
12004
12294
|
...planningClassification,
|
|
12005
12295
|
classifier: input.runtimeAdapter === "pi" ? "pi-rig-structured-policy" : "rig-structured-policy",
|
|
12006
12296
|
artifactPath: planningClassification.planningRequired ? planningArtifactPath : null,
|
|
12007
12297
|
classifiedAt: new Date().toISOString()
|
|
12008
12298
|
};
|
|
12009
|
-
|
|
12010
|
-
|
|
12299
|
+
mkdirSync10(resolve23(context.projectRoot, ".rig", "runs", input.runId), { recursive: true });
|
|
12300
|
+
writeFileSync8(resolve23(context.projectRoot, ".rig", "runs", input.runId, "planning-classification.json"), `${JSON.stringify(persistedPlanning, null, 2)}
|
|
12011
12301
|
`, "utf8");
|
|
12012
12302
|
patchAuthorityRun(context.projectRoot, input.runId, { planning: persistedPlanning });
|
|
12013
12303
|
prompt = `${prompt}
|
|
@@ -12057,7 +12347,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
12057
12347
|
let verificationStarted = false;
|
|
12058
12348
|
let reviewStarted = false;
|
|
12059
12349
|
let latestRuntimeWorkspace = resumeMode && typeof existingRunRecord?.worktreePath === "string" ? existingRunRecord.worktreePath : null;
|
|
12060
|
-
let latestSessionDir = resumeMode && typeof existingRunRecord?.sessionPath === "string" ?
|
|
12350
|
+
let latestSessionDir = resumeMode && typeof existingRunRecord?.sessionPath === "string" ? resolve23(existingRunRecord.sessionPath, "..") : null;
|
|
12061
12351
|
let latestLogsDir = resumeMode && typeof existingRunRecord?.logRoot === "string" ? existingRunRecord.logRoot : null;
|
|
12062
12352
|
let latestProviderCommand = null;
|
|
12063
12353
|
let latestRuntimeBranch = resumeMode && typeof existingRunRecord?.branch === "string" ? existingRunRecord.branch : null;
|
|
@@ -12143,10 +12433,10 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
12143
12433
|
setRunStatusOrFail(context.projectRoot, input.runId, "running");
|
|
12144
12434
|
patchAuthorityRun(context.projectRoot, input.runId, {
|
|
12145
12435
|
worktreePath: latestRuntimeWorkspace,
|
|
12146
|
-
artifactRoot: latestRuntimeWorkspace && input.taskId ?
|
|
12436
|
+
artifactRoot: latestRuntimeWorkspace && input.taskId ? resolve23(latestRuntimeWorkspace, "artifacts", input.taskId) : null,
|
|
12147
12437
|
logRoot: latestLogsDir,
|
|
12148
|
-
sessionPath: latestSessionDir ?
|
|
12149
|
-
sessionLogPath: latestLogsDir ?
|
|
12438
|
+
sessionPath: latestSessionDir ? resolve23(latestSessionDir, "session.json") : null,
|
|
12439
|
+
sessionLogPath: latestLogsDir ? resolve23(latestLogsDir, "agent-stdout.log") : null,
|
|
12150
12440
|
branch: runtimeId
|
|
12151
12441
|
});
|
|
12152
12442
|
if (!dirtyBaselineApplied && input.baselineMode === "dirty-snapshot" && latestRuntimeWorkspace) {
|
|
@@ -12154,8 +12444,8 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
12154
12444
|
const dirty = applyDirtyBaselineSnapshot({ sourceRoot: context.projectRoot, targetRoot: latestRuntimeWorkspace });
|
|
12155
12445
|
const readyFile = childEnv.RIG_DIRTY_BASELINE_READY_FILE;
|
|
12156
12446
|
if (readyFile) {
|
|
12157
|
-
|
|
12158
|
-
|
|
12447
|
+
mkdirSync10(resolve23(readyFile, ".."), { recursive: true });
|
|
12448
|
+
writeFileSync8(readyFile, `${JSON.stringify({ ...dirty, workspaceDir: latestRuntimeWorkspace, appliedAt: new Date().toISOString() }, null, 2)}
|
|
12159
12449
|
`, "utf8");
|
|
12160
12450
|
}
|
|
12161
12451
|
appendRunLog(context.projectRoot, input.runId, {
|
|
@@ -12551,7 +12841,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
12551
12841
|
let acceptedArtifactObservedAt = null;
|
|
12552
12842
|
let acceptedArtifactPollTimer = null;
|
|
12553
12843
|
let acceptedArtifactKillTimer = null;
|
|
12554
|
-
const attemptExit = await new Promise((
|
|
12844
|
+
const attemptExit = await new Promise((resolve24) => {
|
|
12555
12845
|
let settled = false;
|
|
12556
12846
|
const settle = (result) => {
|
|
12557
12847
|
if (settled)
|
|
@@ -12559,7 +12849,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
|
|
|
12559
12849
|
settled = true;
|
|
12560
12850
|
if (acceptedArtifactPollTimer)
|
|
12561
12851
|
clearInterval(acceptedArtifactPollTimer);
|
|
12562
|
-
|
|
12852
|
+
resolve24(result);
|
|
12563
12853
|
};
|
|
12564
12854
|
const pollAcceptedArtifacts = () => {
|
|
12565
12855
|
const artifactState = readTaskRunAcceptedArtifactState({
|
|
@@ -12762,7 +13052,7 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
|
|
|
12762
13052
|
}
|
|
12763
13053
|
if (planningClassification.planningRequired) {
|
|
12764
13054
|
const planWorkspace = latestRuntimeWorkspace ?? context.projectRoot;
|
|
12765
|
-
const expectedPlanPath =
|
|
13055
|
+
const expectedPlanPath = resolve23(planWorkspace, planningArtifactPath);
|
|
12766
13056
|
if (!existsSync15(expectedPlanPath)) {
|
|
12767
13057
|
const failedAt = new Date().toISOString();
|
|
12768
13058
|
const failureDetail = `Planning was required (${planningClassification.reason}) but ${planningArtifactPath} was not written before implementation completed.`;
|
|
@@ -12932,9 +13222,9 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
|
|
|
12932
13222
|
});
|
|
12933
13223
|
emitServerRunEvent({ type: "log", runId: input.runId, title: "Pi PR feedback fix stderr" });
|
|
12934
13224
|
});
|
|
12935
|
-
const exitCode = await new Promise((
|
|
12936
|
-
child.once("error", () =>
|
|
12937
|
-
child.once("close", (code) =>
|
|
13225
|
+
const exitCode = await new Promise((resolve24) => {
|
|
13226
|
+
child.once("error", () => resolve24(1));
|
|
13227
|
+
child.once("close", (code) => resolve24(code ?? 1));
|
|
12938
13228
|
});
|
|
12939
13229
|
for (const pendingLog of flushPendingClaudeToolUseLogs({
|
|
12940
13230
|
runId: input.runId,
|
|
@@ -13075,8 +13365,8 @@ async function executeTest(context, args) {
|
|
|
13075
13365
|
init_runner();
|
|
13076
13366
|
init__parsers();
|
|
13077
13367
|
init__paths();
|
|
13078
|
-
import { existsSync as existsSync16, mkdirSync as
|
|
13079
|
-
import { resolve as
|
|
13368
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync11, readdirSync as readdirSync3, writeFileSync as writeFileSync9 } from "fs";
|
|
13369
|
+
import { resolve as resolve24 } from "path";
|
|
13080
13370
|
import { createPluginHost } from "@rig/core";
|
|
13081
13371
|
import {
|
|
13082
13372
|
isSupportedBunVersion as isSupportedBunVersion2,
|
|
@@ -13131,12 +13421,12 @@ function runSetupInit(projectRoot) {
|
|
|
13131
13421
|
const stateDir = resolveControlPlaneHostStateDir(projectRoot);
|
|
13132
13422
|
const logsDir = resolveControlPlaneHostLogsDir(projectRoot);
|
|
13133
13423
|
const artifactsDir = resolveControlPlaneArtifactsDir(projectRoot);
|
|
13134
|
-
|
|
13135
|
-
|
|
13136
|
-
|
|
13137
|
-
const failuresPath =
|
|
13424
|
+
mkdirSync11(stateDir, { recursive: true });
|
|
13425
|
+
mkdirSync11(logsDir, { recursive: true });
|
|
13426
|
+
mkdirSync11(artifactsDir, { recursive: true });
|
|
13427
|
+
const failuresPath = resolve24(stateDir, "failed_approaches.md");
|
|
13138
13428
|
if (!existsSync16(failuresPath)) {
|
|
13139
|
-
|
|
13429
|
+
writeFileSync9(failuresPath, `# Failed Approaches
|
|
13140
13430
|
|
|
13141
13431
|
`, "utf-8");
|
|
13142
13432
|
}
|
|
@@ -13153,17 +13443,17 @@ async function runSetupCheck(projectRoot, outputMode = "text") {
|
|
|
13153
13443
|
}
|
|
13154
13444
|
async function runSetupPreflight(projectRoot, outputMode = "text") {
|
|
13155
13445
|
await runSetupCheck(projectRoot, outputMode);
|
|
13156
|
-
const validationRoot =
|
|
13446
|
+
const validationRoot = resolve24(resolveControlPlaneDefinitionRoot(projectRoot), "validation");
|
|
13157
13447
|
if (existsSync16(validationRoot)) {
|
|
13158
13448
|
const validators = readdirSync3(validationRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory());
|
|
13159
13449
|
for (const validator of validators) {
|
|
13160
|
-
const script =
|
|
13450
|
+
const script = resolve24(validationRoot, validator.name, "validate.sh");
|
|
13161
13451
|
if (existsSync16(script)) {
|
|
13162
13452
|
console.log(`OK: validator script ${script}`);
|
|
13163
13453
|
}
|
|
13164
13454
|
}
|
|
13165
13455
|
}
|
|
13166
|
-
const hooksRoot =
|
|
13456
|
+
const hooksRoot = resolve24(resolveControlPlaneDefinitionRoot(projectRoot), "hooks");
|
|
13167
13457
|
if (existsSync16(hooksRoot)) {
|
|
13168
13458
|
const hooks = readdirSync3(hooksRoot).filter((name) => name.endsWith(".sh"));
|
|
13169
13459
|
for (const hook of hooks) {
|
|
@@ -13310,7 +13600,7 @@ var PROJECT_REQUIRED_GROUPS = new Set([
|
|
|
13310
13600
|
]);
|
|
13311
13601
|
var RIG_CONFIG_FILENAMES = ["rig.config.ts", "rig.config.mts", "rig.config.json"];
|
|
13312
13602
|
function hasInitializedRigProject(projectRoot) {
|
|
13313
|
-
return RIG_CONFIG_FILENAMES.some((name) => existsSync18(
|
|
13603
|
+
return RIG_CONFIG_FILENAMES.some((name) => existsSync18(resolve25(projectRoot, name))) || existsSync18(resolve25(projectRoot, ".rig"));
|
|
13314
13604
|
}
|
|
13315
13605
|
function requireInitializedRigProject(context, group) {
|
|
13316
13606
|
if (hasInitializedRigProject(context.projectRoot)) {
|
|
@@ -13364,7 +13654,7 @@ function resolveTopLevelLaunchState(context) {
|
|
|
13364
13654
|
let selectedServer = null;
|
|
13365
13655
|
if (projectInitialized) {
|
|
13366
13656
|
try {
|
|
13367
|
-
const statePath =
|
|
13657
|
+
const statePath = resolve25(context.projectRoot, ".rig", "state", "connection.json");
|
|
13368
13658
|
if (existsSync18(statePath)) {
|
|
13369
13659
|
const parsed = JSON.parse(readFileSync13(statePath, "utf-8"));
|
|
13370
13660
|
selectedServer = parsed.remoteUrl || parsed.url || parsed.selected || null;
|
|
@@ -13373,8 +13663,14 @@ function resolveTopLevelLaunchState(context) {
|
|
|
13373
13663
|
}
|
|
13374
13664
|
return { projectInitialized, selectedServer, version: process.env.RIG_CLI_VERSION || readBuildConfig().RIG_CLI_VERSION || undefined };
|
|
13375
13665
|
}
|
|
13666
|
+
function envTruthy(value) {
|
|
13667
|
+
if (!value)
|
|
13668
|
+
return false;
|
|
13669
|
+
const normalized = value.trim().toLowerCase();
|
|
13670
|
+
return normalized !== "0" && normalized !== "false" && normalized !== "no";
|
|
13671
|
+
}
|
|
13376
13672
|
function shouldOpenApp(context) {
|
|
13377
|
-
return context.outputMode === "text" && Boolean(process.stdin.isTTY && process.stdout.isTTY) && process.env.RIG_CLI_PLAIN_HELP !== "1";
|
|
13673
|
+
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
13674
|
}
|
|
13379
13675
|
async function openApp(context, options = {}) {
|
|
13380
13676
|
const { runOperatorBoardLoop: runOperatorBoardLoop2 } = await Promise.resolve().then(() => (init_board(), exports_board));
|