@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.
Files changed (100) hide show
  1. package/dist/bin/build-rig-binaries.js +40 -8
  2. package/dist/bin/rig.js +2798 -1440
  3. package/dist/src/app/board.js +62 -13
  4. package/dist/src/app-opentui/adapters/command.d.ts +2 -0
  5. package/dist/src/app-opentui/adapters/command.js +329 -0
  6. package/dist/src/app-opentui/adapters/common.js +2 -2
  7. package/dist/src/app-opentui/adapters/doctor.js +63 -14
  8. package/dist/src/app-opentui/adapters/fleet.js +84 -20
  9. package/dist/src/app-opentui/adapters/inbox.js +83 -19
  10. package/dist/src/app-opentui/adapters/init.js +87 -23
  11. package/dist/src/app-opentui/adapters/pi-attach.js +96 -34
  12. package/dist/src/app-opentui/adapters/run-detail.js +83 -19
  13. package/dist/src/app-opentui/adapters/server.js +100 -23
  14. package/dist/src/app-opentui/adapters/tasks.d.ts +11 -0
  15. package/dist/src/app-opentui/adapters/tasks.js +742 -94
  16. package/dist/src/app-opentui/bootstrap.d.ts +1 -6
  17. package/dist/src/app-opentui/bootstrap.js +13769 -12368
  18. package/dist/src/app-opentui/command-pty-host.d.ts +62 -0
  19. package/dist/src/app-opentui/command-pty-host.js +248 -0
  20. package/dist/src/app-opentui/events.js +1 -1
  21. package/dist/src/app-opentui/focus-manager.d.ts +14 -0
  22. package/dist/src/app-opentui/focus-manager.js +24 -0
  23. package/dist/src/app-opentui/index.js +3802 -2882
  24. package/dist/src/app-opentui/intent.js +154 -48
  25. package/dist/src/app-opentui/keymap.d.ts +20 -0
  26. package/dist/src/app-opentui/keymap.js +707 -0
  27. package/dist/src/app-opentui/launch-routing.d.ts +16 -0
  28. package/dist/src/app-opentui/launch-routing.js +55 -0
  29. package/dist/src/app-opentui/layout.js +2 -2
  30. package/dist/src/app-opentui/pi-host-child.js +66 -16
  31. package/dist/src/app-opentui/pi-pty-host.d.ts +9 -0
  32. package/dist/src/app-opentui/pi-pty-host.js +9 -11
  33. package/dist/src/app-opentui/registry.js +3231 -2403
  34. package/dist/src/app-opentui/render/ascii-fleet.d.ts +15 -0
  35. package/dist/src/app-opentui/render/ascii-fleet.js +82 -0
  36. package/dist/src/app-opentui/render/graphics.d.ts +1 -1
  37. package/dist/src/app-opentui/render/graphics.js +131 -16
  38. package/dist/src/app-opentui/render/image-visual-layer-worker.js +408 -957
  39. package/dist/src/app-opentui/render/image-visual-layer.d.ts +18 -10
  40. package/dist/src/app-opentui/render/image-visual-layer.js +386 -356
  41. package/dist/src/app-opentui/render/panel-layout.d.ts +38 -0
  42. package/dist/src/app-opentui/render/panel-layout.js +48 -0
  43. package/dist/src/app-opentui/render/panels.d.ts +2 -0
  44. package/dist/src/app-opentui/render/panels.js +62 -29
  45. package/dist/src/app-opentui/render/preloader.d.ts +10 -0
  46. package/dist/src/app-opentui/render/preloader.js +163 -0
  47. package/dist/src/app-opentui/render/scene.d.ts +3 -0
  48. package/dist/src/app-opentui/render/scene.js +12 -0
  49. package/dist/src/app-opentui/render/text.js +5 -1
  50. package/dist/src/app-opentui/render/type-bar.d.ts +2 -1
  51. package/dist/src/app-opentui/render/type-bar.js +51 -16
  52. package/dist/src/app-opentui/runtime-resources.d.ts +16 -0
  53. package/dist/src/app-opentui/runtime-resources.js +62 -0
  54. package/dist/src/app-opentui/runtime.js +2322 -1513
  55. package/dist/src/app-opentui/scenes/command.d.ts +3 -0
  56. package/dist/src/app-opentui/scenes/command.js +103 -0
  57. package/dist/src/app-opentui/scenes/doctor.d.ts +2 -1
  58. package/dist/src/app-opentui/scenes/doctor.js +53 -14
  59. package/dist/src/app-opentui/scenes/error.js +44 -14
  60. package/dist/src/app-opentui/scenes/fleet.js +40 -21
  61. package/dist/src/app-opentui/scenes/handoff.js +142 -27
  62. package/dist/src/app-opentui/scenes/help.js +63 -48
  63. package/dist/src/app-opentui/scenes/inbox.d.ts +2 -1
  64. package/dist/src/app-opentui/scenes/inbox.js +64 -17
  65. package/dist/src/app-opentui/scenes/init.d.ts +2 -1
  66. package/dist/src/app-opentui/scenes/init.js +62 -21
  67. package/dist/src/app-opentui/scenes/main.d.ts +2 -1
  68. package/dist/src/app-opentui/scenes/main.js +80 -24
  69. package/dist/src/app-opentui/scenes/run-detail.d.ts +2 -1
  70. package/dist/src/app-opentui/scenes/run-detail.js +39 -25
  71. package/dist/src/app-opentui/scenes/server.d.ts +2 -1
  72. package/dist/src/app-opentui/scenes/server.js +71 -20
  73. package/dist/src/app-opentui/scenes/tasks.js +44 -22
  74. package/dist/src/app-opentui/state.js +70 -30
  75. package/dist/src/app-opentui/terminal-capabilities.d.ts +7 -0
  76. package/dist/src/app-opentui/terminal-capabilities.js +15 -0
  77. package/dist/src/app-opentui/types.d.ts +10 -2
  78. package/dist/src/commands/_doctor-checks.js +62 -13
  79. package/dist/src/commands/_operator-view.js +63 -13
  80. package/dist/src/commands/_pi-frontend.js +63 -13
  81. package/dist/src/commands/_preflight.js +64 -14
  82. package/dist/src/commands/_server-client.js +82 -18
  83. package/dist/src/commands/_snapshot-upload.js +62 -13
  84. package/dist/src/commands/connect.js +7 -1
  85. package/dist/src/commands/doctor.js +62 -13
  86. package/dist/src/commands/github.js +144 -23
  87. package/dist/src/commands/inbox.js +62 -13
  88. package/dist/src/commands/init.js +82 -18
  89. package/dist/src/commands/inspect.js +62 -13
  90. package/dist/src/commands/run.js +66 -13
  91. package/dist/src/commands/server.js +69 -14
  92. package/dist/src/commands/setup.js +62 -13
  93. package/dist/src/commands/stats.js +62 -13
  94. package/dist/src/commands/task-run-driver.js +62 -13
  95. package/dist/src/commands/task.js +65 -14
  96. package/dist/src/commands.js +227 -92
  97. package/dist/src/index.js +234 -99
  98. package/package.json +8 -9
  99. package/dist/src/app-opentui/render/image-visual-layer-native-canvas.d.ts +0 -2
  100. package/dist/src/app-opentui/render/image-visual-layer-native-canvas.js +0 -1484
@@ -438,17 +438,21 @@ function cleanToken(value) {
438
438
  const trimmed = value?.trim();
439
439
  return trimmed ? trimmed : null;
440
440
  }
441
- function readPrivateRemoteSessionToken(projectRoot) {
441
+ function readRemoteAuthState(projectRoot) {
442
442
  const path = resolve2(projectRoot, ".rig", "state", "github-auth.json");
443
443
  if (!existsSync2(path))
444
444
  return null;
445
445
  try {
446
446
  const parsed = JSON.parse(readFileSync2(path, "utf8"));
447
- return cleanToken(typeof parsed.apiSessionToken === "string" ? parsed.apiSessionToken : typeof parsed.sessionToken === "string" ? parsed.sessionToken : undefined);
447
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
448
448
  } catch {
449
449
  return null;
450
450
  }
451
451
  }
452
+ function readPrivateRemoteSessionToken(projectRoot) {
453
+ const parsed = readRemoteAuthState(projectRoot);
454
+ return parsed ? cleanToken(typeof parsed.apiSessionToken === "string" ? parsed.apiSessionToken : typeof parsed.sessionToken === "string" ? parsed.sessionToken : undefined) : null;
455
+ }
452
456
  function readGitHubBearerTokenForRemote(projectRoot) {
453
457
  const scopedKey = resolve2(projectRoot);
454
458
  if (scopedGitHubBearerTokens.has(scopedKey))
@@ -459,15 +463,25 @@ function readGitHubBearerTokenForRemote(projectRoot) {
459
463
  return cleanToken(process.env.RIG_SERVER_AUTH_TOKEN) ?? cleanToken(process.env.RIG_REMOTE_AUTH_TOKEN);
460
464
  }
461
465
  function readStoredGitHubAuthToken(projectRoot) {
462
- const path = resolve2(projectRoot, ".rig", "state", "github-auth.json");
463
- if (!existsSync2(path))
466
+ const parsed = readRemoteAuthState(projectRoot);
467
+ return parsed ? cleanToken(typeof parsed.token === "string" ? parsed.token : undefined) : null;
468
+ }
469
+ function inferRemoteServerProjectRootFromAuthState(projectRoot) {
470
+ const repo = readRepoConnection(projectRoot);
471
+ const slug = repo?.project?.trim();
472
+ if (!slug || !/^[^/]+\/[^/]+$/.test(slug))
464
473
  return null;
465
- try {
466
- const parsed = JSON.parse(readFileSync2(path, "utf8"));
467
- return cleanToken(typeof parsed.token === "string" ? parsed.token : undefined);
468
- } catch {
474
+ const auth = readRemoteAuthState(projectRoot);
475
+ const authUpdatedAt = typeof auth?.updatedAt === "string" ? Date.parse(auth.updatedAt) : Number.NaN;
476
+ const repoLinkedAt = typeof repo?.linkedAt === "string" ? Date.parse(repo.linkedAt) : Number.NaN;
477
+ if (Number.isFinite(authUpdatedAt) && Number.isFinite(repoLinkedAt) && authUpdatedAt + 1000 < repoLinkedAt)
469
478
  return null;
470
- }
479
+ const checkoutBaseDir = typeof auth?.checkoutBaseDir === "string" && auth.checkoutBaseDir.trim() ? auth.checkoutBaseDir.trim() : null;
480
+ if (!checkoutBaseDir)
481
+ return null;
482
+ const inferred = `${checkoutBaseDir.replace(/\/+$/, "")}/${slug}`;
483
+ writeRepoServerProjectRoot(projectRoot, inferred);
484
+ return inferred;
471
485
  }
472
486
  function readLocalConnectionFallbackToken(projectRoot) {
473
487
  return readGitHubBearerTokenForRemote(projectRoot) ?? cleanToken(process.env.RIG_GITHUB_TOKEN) ?? readStoredGitHubAuthToken(projectRoot);
@@ -478,7 +492,7 @@ async function ensureServerForCli(projectRoot) {
478
492
  if (selected?.connection.kind === "remote") {
479
493
  reportServerPhase(`Connecting to ${selected.alias}\u2026`);
480
494
  const authToken = readGitHubBearerTokenForRemote(projectRoot);
481
- const serverProjectRoot = selected.serverProjectRoot ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
495
+ const serverProjectRoot = selected.serverProjectRoot ?? inferRemoteServerProjectRootFromAuthState(projectRoot) ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
482
496
  return {
483
497
  baseUrl: selected.connection.baseUrl,
484
498
  authToken,
@@ -507,7 +521,10 @@ async function backfillRemoteServerProjectRoot(projectRoot, baseUrl, authToken)
507
521
  if (!slug)
508
522
  return null;
509
523
  try {
510
- const response = await fetch(`${baseUrl}/api/projects/${encodeURIComponent(slug)}`, {
524
+ const url = new URL(`${baseUrl}/api/projects/${encodeURIComponent(slug)}`);
525
+ if (authToken && queryAuthFallbackEnabled())
526
+ url.searchParams.set("rt", authToken);
527
+ const response = await fetch(url, {
511
528
  headers: mergeHeaders(undefined, authToken)
512
529
  });
513
530
  if (!response.ok)
@@ -534,10 +551,23 @@ function appendTaskFilterParams(url, filters) {
534
551
  if (filters.limit !== undefined)
535
552
  url.searchParams.set("limit", String(filters.limit));
536
553
  }
554
+ function mergeCookie(existing, name, value) {
555
+ const encoded = `${name}=${encodeURIComponent(value)}`;
556
+ if (!existing?.trim())
557
+ return encoded;
558
+ const parts = existing.split(";").map((part) => part.trim()).filter((part) => part && !part.startsWith(`${name}=`));
559
+ return [...parts, encoded].join("; ");
560
+ }
561
+ function queryAuthFallbackEnabled(env = process.env) {
562
+ return env.RIG_ENABLE_QUERY_AUTH_FALLBACK === "1" || env.RIG_QUERY_AUTH_FALLBACK === "1";
563
+ }
537
564
  function mergeHeaders(headers, authToken) {
538
565
  const merged = new Headers(headers);
539
566
  if (authToken) {
540
- merged.set("authorization", `Bearer ${authToken}`);
567
+ const bearer = `Bearer ${authToken}`;
568
+ merged.set("authorization", bearer);
569
+ merged.set("x-auth", bearer);
570
+ merged.set("cookie", mergeCookie(merged.get("cookie"), "rig_auth", authToken));
541
571
  }
542
572
  return merged;
543
573
  }
@@ -598,15 +628,34 @@ async function buildServerFailureContext(projectRoot, server) {
598
628
  hint: "Check the selected server with `rig server status`, or switch with `rig server use <alias|local>`."
599
629
  };
600
630
  }
631
+ function isLoopbackRemoteBaseUrl(baseUrl) {
632
+ try {
633
+ const host = new URL(baseUrl).hostname.toLowerCase();
634
+ return host === "localhost" || host === "127.0.0.1" || host === "::1" || host === "[::1]";
635
+ } catch {
636
+ return false;
637
+ }
638
+ }
639
+ function canUseRemoteWithoutProjectRoot(pathname) {
640
+ 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/");
641
+ }
601
642
  async function requestServerJson(context, pathname, init = {}) {
602
643
  const server = await ensureServerForCli(context.projectRoot);
644
+ const requestUrl = new URL(`${server.baseUrl}${pathname}`);
645
+ if (server.connectionKind === "remote" && !server.serverProjectRoot && !canUseRemoteWithoutProjectRoot(requestUrl.pathname) && (server.authToken || !isLoopbackRemoteBaseUrl(server.baseUrl))) {
646
+ const repo = readRepoConnection(context.projectRoot);
647
+ 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." });
648
+ }
603
649
  const headers = mergeHeaders(init.headers, server.authToken);
604
650
  if (server.serverProjectRoot)
605
651
  headers.set("x-rig-project-root", server.serverProjectRoot);
652
+ if (server.connectionKind === "remote" && server.authToken && queryAuthFallbackEnabled()) {
653
+ requestUrl.searchParams.set("rt", server.authToken);
654
+ }
606
655
  reportServerPhase(`${(init.method ?? "GET").toUpperCase()} ${pathname.split("?")[0]}\u2026`);
607
656
  let response;
608
657
  try {
609
- response = await fetch(`${server.baseUrl}${pathname}`, {
658
+ response = await fetch(requestUrl, {
610
659
  ...init,
611
660
  headers
612
661
  });
@@ -863,7 +912,8 @@ async function runFastTaskRunPreflight(context, options = {}) {
863
912
  }
864
913
  }
865
914
  const repo = readRepoConnection(context.projectRoot);
866
- checks.push(repo ? preflightCheck("project-link", "project linked to Rig server", repo.project ? "pass" : "warn", `${repo.selected}${repo.project ? ` -> ${repo.project}` : ""}`, "Run `rig init --yes --repo owner/repo` to record the GitHub repo slug.") : preflightCheck("project-link", "project linked to Rig server", legacyServerCompatibility ? "warn" : "fail", "missing .rig/state/connection.json", "Run `rig init` or `rig server use <alias|local>`."));
915
+ const remoteWithoutProjectLink = selectedServer?.connectionKind === "remote" && !repo?.project;
916
+ 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>`."));
867
917
  try {
868
918
  const auth = await request("/api/github/auth/status");
869
919
  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>`."));
@@ -1495,6 +1545,7 @@ async function attachRunBundledPiFrontend(context, input) {
1495
1545
  let detached = false;
1496
1546
  try {
1497
1547
  await runPiMain([
1548
+ "--offline",
1498
1549
  "--no-extensions",
1499
1550
  "--no-skills",
1500
1551
  "--no-prompt-templates",