// SPEC: PJ2026-010606 GitHub入口 draft-2026-06-25-gh-split
// Moved mechanically from scripts/src/gh.ts:8348-8845.

import { issueAttachmentDownload, issueAttachmentList } from "./attachments";
import { actionBenchmark } from "./actions-benchmark";
import { actionRunList, actionRunLogs, actionRunView } from "./actions-runs";
import { resolveToken } from "./auth-and-safety";
import { authStatus, prFiles, prList, prRead, prView } from "./auth-pr-read";
import { issueBoardAudit } from "./board-audit";
import { issueBoardRowAdd, issueBoardRowDelete, issueBoardRowGet, issueBoardRowList, issueBoardRowMove, issueBoardRowUpdate, issueBoardRowUpsert } from "./board-commands";
import { authRequired, unsupportedCommand, validationError } from "./client";
import { commentDelete, commentPatch, commentUpdate, commentView, issueComment, issueState } from "./comments-and-state";
import { issueScanEscape } from "./escape-scan";
import { ghHelp, ghScopedHelp } from "./help";
import { issueList } from "./issue-list";
import { issueComments, issueRead, issueView } from "./issue-read";
import { repoCreate, repoView } from "./issue-summary";
import { issueCreate, issueEdit, issuePatch } from "./issue-write";
import { allowsNumberTargetAlias, isIssueReadCommand, isPrReadCommand, optionValue, optionWasProvided, parseOptions } from "./options";
import { prComment, prCreate, prState, prUpdate } from "./pr-commands";
import { prMerge, prPreflight } from "./pr-merge";
import { prReady } from "./pr-ready";
import { prDiffFile, prReviewPlan } from "./pr-review";
import { isGitHubCommandResult, issueReadJsonFields, prReadJsonFields, readDisclosureOptions, readViewSupportedJsonFields, resolvePositionalIssueReference, resolvePositionalNumberReference, resolvePositionalPrReference, resolveReadViewNumberReference, unknownGhOptionDetails, withNumberOptionHint } from "./refs";
import { issueStaleClose } from "./stale-close";
import { DEFAULT_REPO } from "./types";
import type { GitHubCommandResult, GitHubOptions } from "./types";

export async function runGhCommand(args: string[]): Promise<GitHubCommandResult | unknown> {
  const scopedHelp = ghScopedHelp(args);
  if (scopedHelp !== null) return scopedHelp;
  const [top, sub, third] = args;
  if (top === undefined || top === "help" || top === "--help" || top === "-h") return ghHelp();
  let options: GitHubOptions;
  try {
    options = parseOptions(args);
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error);
    const command = [top, sub].filter((value): value is string => value !== undefined).join(" ") || "gh";
    const repo = optionValue(args, "--repo") ?? DEFAULT_REPO;
    const unknownOption = /^unknown gh option:\s+(.+)$/u.exec(message)?.[1];
    return unknownOption !== undefined
      ? unsupportedCommand(command, repo, message, unknownGhOptionDetails(args, unknownOption))
      : validationError(command, repo, message);
  }
  if (options.notifyClaudeQqBriefDiff && !(top === "issue" && sub === "edit")) {
    const command = [top, sub].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--notify-claudeqq-brief-diff is only supported by gh issue edit 24");
  }
  if (optionWasProvided(args, "--state") && !(top === "issue" && (sub === "list" || sub === "board-row" && third === "list") || top === "pr" && sub === "list")) {
    const command = [top, sub].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--state is only supported by gh issue list, gh issue board-row list, and gh pr list");
  }
  if (optionWasProvided(args, "--json") && !(top === "issue" && (isIssueReadCommand(sub) || sub === "list"))) {
    const command = [top, sub].filter((value): value is string => value !== undefined).join(" ") || "gh";
    if (!(top === "pr" && (isPrReadCommand(sub) || sub === "list"))) {
      return validationError(command, options.repo, "--json field selection is only supported by gh issue read/view/list and gh pr read/view/list");
    }
  }
  const isIssueCommentReadCommand = top === "issue" && sub === "comment" && (third === "view" || third === "read");
  const isPrCommentReadCommand = top === "pr" && sub === "comment" && (third === "view" || third === "read");
  const isPrDiffFileCommand = top === "pr" && sub === "diff" && optionWasProvided(args, "--file");
  if ((optionWasProvided(args, "--raw") || optionWasProvided(args, "--full")) && !((top === "issue" && (isIssueReadCommand(sub) || sub === "comments" || sub === "list" || sub === "update" || sub === "edit" || sub === "patch")) || isIssueCommentReadCommand || top === "preflight" || top === "run" || (top === "pr" && (isPrReadCommand(sub) || sub === "list" || sub === "preflight" || sub === "closeout")) || isPrCommentReadCommand || isPrDiffFileCommand)) {
    const command = [top, sub].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--raw and --full are explicit full-disclosure aliases only for gh issue list/read/view/comments/update/edit/patch/comment view, gh pr list/read/view/comment view, gh pr preflight/closeout, and gh pr diff --file.", {
      supportedCommands: [
        "bun scripts/cli.ts gh issue list --repo owner/name --limit 200 --full",
        "bun scripts/cli.ts gh issue view owner/name#<number> --raw",
        "bun scripts/cli.ts gh issue comments <number> --repo owner/name --limit 8 --full",
        "bun scripts/cli.ts gh issue view <number> --repo owner/name --json body,title,state,comments",
        "bun scripts/cli.ts gh issue comment view <commentId> --repo owner/name --full",
        "bun scripts/cli.ts gh issue update <number> --repo owner/name --body-stdin --full <<'EOF'\n<reviewed body>\nEOF",
        "bun scripts/cli.ts gh issue patch <number> --repo owner/name --body-patch-stdin --full <<'PATCH'\n*** Begin Patch\n*** Update File: issue.md\n@@\n-old\n+new\n*** End Patch\nPATCH",
        "bun scripts/cli.ts gh pr list --repo owner/name --limit 100 --full",
        "bun scripts/cli.ts gh pr view owner/name#<number> --raw",
        `bun scripts/cli.ts gh pr view <number> --repo owner/name --json ${readViewSupportedJsonFields("pr")}`,
        "bun scripts/cli.ts gh pr preflight <number> --repo owner/name --full",
        "bun scripts/cli.ts gh pr diff <number> --repo owner/name --file path/to/file --full",
      ],
    });
  }
  if (optionWasProvided(args, "--attachment") && !(top === "issue" && sub === "attachment" && third === "download")) {
    const command = [top, sub, third].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--attachment is only supported by gh issue attachment download");
  }
  if (optionWasProvided(args, "--output") && !(top === "issue" && sub === "attachment" && third === "download")) {
    const command = [top, sub, third].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--output is only supported by gh issue attachment download");
  }
  if (optionWasProvided(args, "--stat") && !(top === "pr" && (sub === "diff" || sub === "files"))) {
    const command = [top, sub].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--stat is only supported by gh pr diff <number> --stat.", {
      supportedCommands: [
        "bun scripts/cli.ts gh pr files <number> --repo owner/name --limit 30",
        "bun scripts/cli.ts gh pr diff <number> --stat --repo owner/name --limit 30",
      ],
    });
  }
  if (optionWasProvided(args, "--file") && !(top === "pr" && sub === "diff")) {
    const command = [top, sub].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--file is only supported by gh pr diff <number> --file <path>", {
      supportedCommands: [
        "bun scripts/cli.ts gh pr review-plan <number> --repo owner/name",
        "bun scripts/cli.ts gh pr diff <number> --repo owner/name --file path/to/file",
      ],
    });
  }
  if (optionWasProvided(args, "--hunk") && !(top === "pr" && sub === "diff" && optionWasProvided(args, "--file"))) {
    const command = [top, sub].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--hunk is only supported by gh pr diff <number> --file <path> --hunk <n>", {
      supportedCommands: [
        "bun scripts/cli.ts gh pr diff <number> --repo owner/name --file path/to/file --hunk 1",
      ],
    });
  }
  if (optionWasProvided(args, "--job") && !(top === "run" && sub === "logs")) {
    return validationError([top, sub].filter(Boolean).join(" "), options.repo, "--job is only supported by gh run logs <run-id> --job <job-id>");
  }
  if ((optionWasProvided(args, "--url") || optionWasProvided(args, "--commit")) && !(top === "run" && sub === "benchmark")) {
    return validationError([top, sub].filter(Boolean).join(" "), options.repo, "--url and --commit are only supported by gh run benchmark");
  }
  if (optionWasProvided(args, "--number") && !allowsNumberTargetAlias(top, sub, third)) {
    const command = [top, sub].filter((value): value is string => value !== undefined).join(" ") || "gh";
    const standardViewCommand = top === "issue" || top === "pr" ? `gh ${top} view` : "gh issue/pr view";
    return validationError(command, options.repo, `--number is only a compatibility alias for single numeric target commands; standard ${standardViewCommand} uses a positional number or URL target.`, {
      supportedCommands: [
        "trans gh:/owner/name/issue/<number> cat",
        "trans gh:/owner/name/issue/<number> rg <pattern>",
        "trans gh:/owner/name/pr/<number> cat",
        "trans gh:/owner/name/pr/<number> rg <pattern>",
      ],
      rejectedOption: "--number",
    });
  }
  if (optionWasProvided(args, "--mode") && !((top === "issue" && (sub === "update" || sub === "edit")) || (top === "pr" && (sub === "update" || sub === "edit")))) {
    const command = [top, sub].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--mode is only supported by gh issue update/edit and gh pr update/edit");
  }
  const issueBodyGuardCommand = top === "issue" && (sub === "edit" || sub === "update" || sub === "patch" || sub === "board-row" && ["update", "add", "move", "delete", "upsert"].includes(third ?? ""));
  const issueCommentPatchCommand = top === "issue" && sub === "comment" && third === "patch";
  if ((options.allowShortBody || optionWasProvided(args, "--body-profile")) && !issueBodyGuardCommand) {
    const command = [top, sub].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--allow-short-body and --body-profile are only supported by gh issue update/edit/patch and gh issue board-row update/add/move/delete/upsert");
  }
  if ((options.expectUpdatedAt !== undefined || options.expectBodySha !== undefined) && !(issueBodyGuardCommand || issueCommentPatchCommand)) {
    const command = [top, sub].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--expect-updated-at and --expect-body-sha are only supported by gh issue update/edit/patch, gh issue comment patch, and gh issue board-row update/add/move/delete/upsert");
  }
  if ((optionWasProvided(args, "--body-patch-file") || optionWasProvided(args, "--body-patch-stdin")) && !(top === "issue" && (sub === "patch" || sub === "comment" && third === "patch"))) {
    const command = [top, sub, third].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--body-patch-file and --body-patch-stdin are only supported by gh issue patch and gh issue comment patch", {
      supportedCommands: [
        "bun scripts/cli.ts gh issue patch <number> --repo owner/name --body-patch-stdin",
        "bun scripts/cli.ts gh issue comment patch <commentId> --repo owner/name --body-patch-stdin",
      ],
    });
  }
  if ((optionWasProvided(args, "--board-issue") || optionWasProvided(args, "--known-meta-issue") || optionWasProvided(args, "--ignore-issue")) && !(top === "issue" && (sub === "board-audit" || sub === "board-row"))) {
    const command = [top, sub].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--board-issue, --known-meta-issue, and --ignore-issue are only supported by gh issue board-audit and --board-issue by gh issue board-row");
  }
  if ((optionWasProvided(args, "--known-meta-issue") || optionWasProvided(args, "--ignore-issue")) && !(top === "issue" && sub === "board-audit")) {
    const command = [top, sub, third].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--known-meta-issue and --ignore-issue are only supported by gh issue board-audit");
  }
  if ((optionWasProvided(args, "--field") || optionWasProvided(args, "--value")) && !(top === "issue" && sub === "board-row" && third === "update")) {
    const command = [top, sub, third].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--field and --value are only supported by gh issue board-row update");
  }
  if (optionWasProvided(args, "--row-file") && !(top === "issue" && sub === "board-row" && third === "add")) {
    const command = [top, sub, third].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--row-file is only supported by gh issue board-row add");
  }
  if (optionWasProvided(args, "--section") && !(top === "issue" && sub === "board-row" && (third === "add" || third === "upsert"))) {
    const command = [top, sub, third].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--section is only supported by gh issue board-row add/upsert");
  }
  if (optionWasProvided(args, "--to") && !(top === "issue" && sub === "board-row" && third === "move")) {
    const command = [top, sub, third].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--to is only supported by gh issue board-row move");
  }
  if (optionWasProvided(args, "--status") && !(top === "issue" && sub === "board-row" && (third === "move" || third === "upsert"))) {
    const command = [top, sub, third].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--status is only supported by gh issue board-row move/upsert");
  }
  if ((optionWasProvided(args, "--category") || optionWasProvided(args, "--branch") || optionWasProvided(args, "--tasks") || optionWasProvided(args, "--summary") || optionWasProvided(args, "--focus") || optionWasProvided(args, "--validation") || optionWasProvided(args, "--progress")) && !(top === "issue" && sub === "board-row" && third === "upsert")) {
    const command = [top, sub, third].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--category, --branch, --tasks, --summary, --focus, --validation, and --progress are only supported by gh issue board-row upsert");
  }
  if (optionWasProvided(args, "--label") && !(top === "issue" && (sub === "create" || sub === "list" || sub === "stale-close"))) {
    const command = [top, sub].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--label is only supported by gh issue create, gh issue list, and gh issue stale-close");
  }
  if (optionWasProvided(args, "--search") && !(top === "issue" && sub === "list")) {
    const command = [top, sub].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--search is only supported by gh issue list");
  }
  if (optionWasProvided(args, "--title-prefix") && !(top === "issue" && sub === "list")) {
    const command = [top, sub].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--title-prefix is only supported by gh issue list");
  }
  if (optionWasProvided(args, "--inactive-hours") && !(top === "issue" && sub === "stale-close")) {
    const command = [top, sub].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--inactive-hours is only supported by gh issue stale-close");
  }
  if (optionWasProvided(args, "--comment")) {
    const command = [top, sub].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "inline --comment is unsupported because shell quoting corrupts Markdown; use --comment-stdin with a quoted heredoc", {
      supportedCommands: [
        "bun scripts/cli.ts gh issue close <number> --repo owner/name --comment-stdin <<'EOF'\n<comment markdown>\nEOF",
        "bun scripts/cli.ts gh issue reopen <number> --repo owner/name --comment-stdin <<'EOF'\n<comment markdown>\nEOF",
      ],
    });
  }
  if (optionWasProvided(args, "--comment-file")) {
    const command = [top, sub].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--comment-file is unsupported for issue lifecycle comments; use --comment-stdin with a quoted heredoc", {
      supportedCommands: [
        "bun scripts/cli.ts gh issue close <number> --repo owner/name --comment-stdin <<'EOF'\n<comment markdown>\nEOF",
        "bun scripts/cli.ts gh issue reopen <number> --repo owner/name --comment-stdin <<'EOF'\n<comment markdown>\nEOF",
      ],
    });
  }
  if ((optionWasProvided(args, "--description") || optionWasProvided(args, "--private") || optionWasProvided(args, "--public") || optionWasProvided(args, "--auto-init")) && !(top === "repo" && sub === "create")) {
    const command = [top, sub].filter((value): value is string => value !== undefined).join(" ") || "gh";
    return validationError(command, options.repo, "--description, --private, --public, and --auto-init are only supported by gh repo create");
  }

  if (top === "auth" && sub === "status") return authStatus(options.repo);

  if (top === "run") {
    const commandName = `run ${sub ?? ""}`.trim();
    if (sub !== "list" && sub !== "view" && sub !== "logs" && sub !== "benchmark") {
      return unsupportedCommand(commandName, options.repo, "run supported commands are list, view, logs, and benchmark.");
    }
    if (sub === "benchmark") {
      return actionBenchmark(options.repo, {
        url: options.benchmarkUrl,
        commit: options.benchmarkCommit,
        limit: options.limit,
      });
    }
    const { token, probe } = resolveToken(options.repo, true);
    const missing = authRequired(options.repo, commandName, probe);
    if (missing !== null || token === null) return missing ?? authRequired(options.repo, commandName, { present: false, source: null, ghFallbackAttempted: true });
    if (sub === "list") return actionRunList(options.repo, token, options.limit);
    const runId = Number(third);
    if (!Number.isSafeInteger(runId) || runId <= 0) return validationError(commandName, options.repo, `${commandName} requires a positive positional run id`);
    if (sub === "view") return actionRunView(options.repo, token, runId);
    const jobId = Number(optionValue(args, "--job"));
    if (!Number.isSafeInteger(jobId) || jobId <= 0) return validationError(commandName, options.repo, "run logs requires --job <positive-job-id>");
    return actionRunLogs(options.repo, token, runId, jobId);
  }

  if (top === "repo") {
    if (sub !== "view" && sub !== "create") {
      return unsupportedCommand(`repo ${sub ?? ""}`.trim(), options.repo, "repo supported commands are view and create.", {
        supportedCommands: [
          `bun scripts/cli.ts gh repo view ${options.repo}`,
          `bun scripts/cli.ts gh repo create ${options.repo} --private --dry-run`,
        ],
      });
    }
    if (sub === "create" && options.dryRun) return repoCreate(options.repo, "", options);
    const { token, probe } = resolveToken(options.repo, true);
    const commandName = `repo ${sub}`;
    const missing = authRequired(options.repo, commandName, probe);
    if (missing !== null || token === null) return missing ?? authRequired(options.repo, commandName, { present: false, source: null, ghFallbackAttempted: true });
    if (sub === "view") return repoView(options.repo, token);
    return repoCreate(options.repo, token, options);
  }

  if (top === "preflight") {
    const resolved = resolvePositionalPrReference(args, 1, "preflight", options);
    if (isGitHubCommandResult(resolved)) return resolved;
    return withNumberOptionHint(prPreflight(resolved.repo, resolved.number, "preflight", options.full || options.raw), resolved);
  }

  if (top === "issue") {
    if (sub === "delete") return unsupportedCommand("issue delete", options.repo, "GitHub REST does not support hard-deleting issues; use gh issue close for lifecycle deletion semantics.");
    if (sub === "attachment") {
      const action = third;
      const commandName = `issue attachment ${action ?? ""}`.trim();
      if (action !== "list" && action !== "download") {
        return unsupportedCommand(commandName, options.repo, "issue attachment supported commands are list and download.", {
          supportedCommands: [
            "bun scripts/cli.ts gh issue attachment list <number> --repo owner/name",
            "bun scripts/cli.ts gh issue attachment download <number> --repo owner/name --attachment 1 --output /tmp/issue-attachment.png",
          ],
        });
      }
      const resolved = resolvePositionalIssueReference(args, 3, commandName, options);
      if (isGitHubCommandResult(resolved)) return resolved;
      const { token, probe } = resolveToken(resolved.repo, true);
      const missing = authRequired(resolved.repo, commandName, probe);
      if (missing !== null || token === null) return missing ?? authRequired(resolved.repo, commandName, { present: false, source: null, ghFallbackAttempted: true });
      if (action === "list") return withNumberOptionHint(issueAttachmentList(resolved.repo, token, resolved.number), resolved);
      return withNumberOptionHint(issueAttachmentDownload(resolved.repo, token, resolved.number, { ...options, repo: resolved.repo }), resolved);
    }
    if (sub === "comment" && (third === "view" || third === "read")) {
      const commandName = `issue comment ${third}`;
      const resolved = resolvePositionalNumberReference("issue", args, 3, commandName, options);
      if (isGitHubCommandResult(resolved)) return resolved;
      const commentId = resolved.number;
      if (typeof commentId !== "number") return commentId;
      const { token, probe } = resolveToken(resolved.repo, true);
      const missing = authRequired(resolved.repo, commandName, probe);
      if (missing !== null || token === null) return missing ?? authRequired(resolved.repo, commandName, { present: false, source: null, ghFallbackAttempted: true });
      return withNumberOptionHint(commentView(resolved.repo, token, "issue", commentId, options.raw || options.full, commandName), resolved);
    }
    if (sub === "comment" && third === "delete") {
      const resolved = resolvePositionalNumberReference("issue", args, 3, "issue comment delete", options);
      if (isGitHubCommandResult(resolved)) return resolved;
      const commentId = resolved.number;
      if (typeof commentId !== "number") return commentId;
      if (options.dryRun) return withNumberOptionHint(commentDelete(resolved.repo, "", "issue", commentId, true), resolved);
      const { token, probe } = resolveToken(resolved.repo, true);
      const missing = authRequired(resolved.repo, "issue comment delete", probe);
      if (missing !== null || token === null) return missing ?? authRequired(resolved.repo, "issue comment delete", { present: false, source: null, ghFallbackAttempted: true });
      return withNumberOptionHint(commentDelete(resolved.repo, token, "issue", commentId, false), resolved);
    }
    if (sub === "comment" && third === "patch") {
      const commandName = "issue comment patch";
      const resolved = resolvePositionalNumberReference("issue", args, 3, commandName, options);
      if (isGitHubCommandResult(resolved)) return resolved;
      const commentId = resolved.number;
      if (typeof commentId !== "number") return commentId;
      const { token, probe } = resolveToken(resolved.repo, true);
      const missing = authRequired(resolved.repo, commandName, probe);
      if (missing !== null || token === null) return missing ?? authRequired(resolved.repo, commandName, { present: false, source: null, ghFallbackAttempted: true });
      return withNumberOptionHint(commentPatch(resolved.repo, token, "issue", commentId, { ...options, repo: resolved.repo }, commandName), resolved);
    }
    if (sub === "comment" && (third === "update" || third === "edit")) {
      const commandName = `issue comment ${third}`;
      const resolved = resolvePositionalNumberReference("issue", args, 3, commandName, options);
      if (isGitHubCommandResult(resolved)) return resolved;
      const commentId = resolved.number;
      if (typeof commentId !== "number") return commentId;
      const updateOptions = { ...options, repo: resolved.repo };
      if (options.dryRun) return withNumberOptionHint(commentUpdate(resolved.repo, "", "issue", commentId, updateOptions, commandName), resolved);
      const { token, probe } = resolveToken(resolved.repo, true);
      const missing = authRequired(resolved.repo, commandName, probe);
      if (missing !== null || token === null) return missing ?? authRequired(resolved.repo, commandName, { present: false, source: null, ghFallbackAttempted: true });
      return withNumberOptionHint(commentUpdate(resolved.repo, token, "issue", commentId, updateOptions, commandName), resolved);
    }
    if (sub === "comment" && third === "create") {
      const resolved = resolvePositionalIssueReference(args, 3, "issue comment create", options);
      if (isGitHubCommandResult(resolved)) return resolved;
      const issueNumber = resolved.number;
      if (typeof issueNumber !== "number") return issueNumber;
      if (options.dryRun) return withNumberOptionHint(issueComment(resolved.repo, "", issueNumber, { ...options, repo: resolved.repo }), resolved);
      const { token, probe } = resolveToken(resolved.repo, true);
      const missing = authRequired(resolved.repo, "issue comment create", probe);
      if (missing !== null || token === null) return missing ?? authRequired(resolved.repo, "issue comment create", { present: false, source: null, ghFallbackAttempted: true });
      return withNumberOptionHint(issueComment(resolved.repo, token, issueNumber, { ...options, repo: resolved.repo }), resolved);
    }
    if (sub === "comments") {
      const resolved = resolvePositionalIssueReference(args, 2, "issue comments", options);
      if (isGitHubCommandResult(resolved)) return resolved;
      const { token, probe } = resolveToken(resolved.repo, true);
      const missing = authRequired(resolved.repo, "issue comments", probe);
      if (missing !== null || token === null) return missing ?? authRequired(resolved.repo, "issue comments", { present: false, source: null, ghFallbackAttempted: true });
      return withNumberOptionHint(issueComments(resolved.repo, token, resolved.number, options.limit, { includeFullCommentBodies: options.full || options.raw }), resolved);
    }
    if (sub === "scan-escape" || sub === "cleanup-plan") {
      const { token, probe } = resolveToken(options.repo, true);
      const commandName = sub === "cleanup-plan" ? "issue cleanup-plan" : "issue scan-escape";
      const missing = authRequired(options.repo, commandName, probe);
      if (missing !== null || token === null) return missing ?? authRequired(options.repo, commandName, { present: false, source: null, ghFallbackAttempted: true });
      return issueScanEscape(options.repo, token, options.limit, options.dryRun || sub === "cleanup-plan", commandName);
    }
    if (sub === "board-audit") {
      const { token, probe } = resolveToken(options.repo, true);
      const missing = authRequired(options.repo, "issue board-audit", probe);
      if (missing !== null || token === null) return missing ?? authRequired(options.repo, "issue board-audit", { present: false, source: null, ghFallbackAttempted: true });
      return issueBoardAudit(options.repo, token, options);
    }
    if (sub === "board-row") {
      const action = third;
      const commandName = `issue board-row ${action ?? ""}`.trim();
      if (action !== "list" && action !== "get" && action !== "update" && action !== "add" && action !== "move" && action !== "delete" && action !== "upsert") {
        return unsupportedCommand(commandName, options.repo, "board-row supported commands are list, get, update, add, move, delete, and upsert.");
      }
      if (action === "list") {
        const { token, probe } = resolveToken(options.repo, true);
        const missing = authRequired(options.repo, commandName, probe);
        if (missing !== null || token === null) return missing ?? authRequired(options.repo, commandName, { present: false, source: null, ghFallbackAttempted: true });
        return issueBoardRowList(options.repo, token, options);
      }
      const resolvedBoardRow = resolvePositionalIssueReference(args, 3, commandName, options);
      if (isGitHubCommandResult(resolvedBoardRow)) return resolvedBoardRow;
      const issueNumber = resolvedBoardRow.number;
      if (typeof issueNumber !== "number") return issueNumber;
      const boardRowOptions = { ...options, repo: resolvedBoardRow.repo };
      const { token, probe } = resolveToken(resolvedBoardRow.repo, true);
      const missing = authRequired(resolvedBoardRow.repo, commandName, probe);
      if (missing !== null || token === null) return missing ?? authRequired(resolvedBoardRow.repo, commandName, { present: false, source: null, ghFallbackAttempted: true });
      if (action === "get") return withNumberOptionHint(issueBoardRowGet(resolvedBoardRow.repo, token, issueNumber, boardRowOptions), resolvedBoardRow);
      if (action === "update") return withNumberOptionHint(issueBoardRowUpdate(resolvedBoardRow.repo, token, issueNumber, boardRowOptions), resolvedBoardRow);
      if (action === "add") return withNumberOptionHint(issueBoardRowAdd(resolvedBoardRow.repo, token, issueNumber, boardRowOptions), resolvedBoardRow);
      if (action === "upsert") return withNumberOptionHint(issueBoardRowUpsert(resolvedBoardRow.repo, token, issueNumber, boardRowOptions), resolvedBoardRow);
      if (action === "move") return withNumberOptionHint(issueBoardRowMove(resolvedBoardRow.repo, token, issueNumber, boardRowOptions), resolvedBoardRow);
      return withNumberOptionHint(issueBoardRowDelete(resolvedBoardRow.repo, token, issueNumber, boardRowOptions), resolvedBoardRow);
    }
    if (sub === "patch") {
      const resolved = resolvePositionalIssueReference(args, 2, "issue patch", options);
      if (isGitHubCommandResult(resolved)) return resolved;
      const { token, probe } = resolveToken(resolved.repo, true);
      const missing = authRequired(resolved.repo, "issue patch", probe);
      if (missing !== null || token === null) return missing ?? authRequired(resolved.repo, "issue patch", { present: false, source: null, ghFallbackAttempted: true });
      return withNumberOptionHint(issuePatch(resolved.repo, token, resolved.number, { ...options, repo: resolved.repo }), resolved);
    }
    if (options.dryRun) {
      if (sub === "create") return issueCreate(options.repo, "", options);
      if (sub === "edit") {
        const issueEditRef = resolvePositionalIssueReference(args, 2, "issue edit", options);
        if (isGitHubCommandResult(issueEditRef)) return issueEditRef;
        const issueNumber = issueEditRef.number;
        const { token } = resolveToken(issueEditRef.repo, false);
        return withNumberOptionHint(issueEdit(issueEditRef.repo, token ?? "", issueNumber, { ...options, repo: issueEditRef.repo }), issueEditRef);
      }
      if (sub === "update") {
        const issueUpdateRef = resolvePositionalIssueReference(args, 2, "issue update", options);
        if (isGitHubCommandResult(issueUpdateRef)) return issueUpdateRef;
        const issueNumber = issueUpdateRef.number;
        const { token } = resolveToken(issueUpdateRef.repo, false);
        return withNumberOptionHint(issueEdit(issueUpdateRef.repo, token ?? "", issueNumber, { ...options, repo: issueUpdateRef.repo }, "issue update"), issueUpdateRef);
      }
      if (sub === "comment") {
        const r = resolvePositionalIssueReference(args, 2, "issue comment", options);
        if (isGitHubCommandResult(r)) return r;
        return withNumberOptionHint(issueComment(r.repo, "", r.number, { ...options, repo: r.repo }), r);
      }
      if (sub === "close") {
        const r = resolvePositionalIssueReference(args, 2, "issue close", options);
        if (isGitHubCommandResult(r)) return r;
        return withNumberOptionHint(issueState(r.repo, "", r.number, "closed", true, { ...options, repo: r.repo }), r);
      }
      if (sub === "reopen") {
        const r = resolvePositionalIssueReference(args, 2, "issue reopen", options);
        if (isGitHubCommandResult(r)) return r;
        return withNumberOptionHint(issueState(r.repo, "", r.number, "open", true, { ...options, repo: r.repo }), r);
      }
    }
    if (sub === "read" || sub === "view") {
      const resolved = resolveReadViewNumberReference("issue", sub, third, options, args);
      if (isGitHubCommandResult(resolved)) return resolved;
      const { token, probe } = resolveToken(resolved.repo, true);
      const missing = authRequired(resolved.repo, `issue ${sub}`, probe);
      if (missing !== null || token === null) return missing ?? authRequired(resolved.repo, `issue ${sub}`, { present: false, source: null, ghFallbackAttempted: true });
      const disclosure = readDisclosureOptions(options, resolved.shorthand);
      if (sub === "read") return withNumberOptionHint(issueRead(resolved.repo, token, resolved.number, issueReadJsonFields(options), "issue read", disclosure, { includeFullCommentBodies: options.raw }), resolved);
      return withNumberOptionHint(issueView(resolved.repo, token, resolved.number, issueReadJsonFields(options), disclosure, { includeFullCommentBodies: options.raw }), resolved);
    }
    if (sub === "list" || sub === "stale-close" || sub === "create") {
      const commandName = `issue ${sub}`;
      const { token, probe } = resolveToken(options.repo, true);
      const missing = authRequired(options.repo, commandName, probe);
      if (missing !== null || token === null) return missing ?? authRequired(options.repo, commandName, { present: false, source: null, ghFallbackAttempted: true });
      if (sub === "list") return issueList(options.repo, token, options.listState, options.limit, options.issueListJsonFields, options.search, options.labels, options.raw || options.full, options.titlePrefix);
      if (sub === "stale-close") return issueStaleClose(options.repo, token, options);
      return issueCreate(options.repo, token, options);
    }
    if (sub === "edit") {
      const r = resolvePositionalIssueReference(args, 2, "issue edit", options);
      if (isGitHubCommandResult(r)) return r;
      const { token, probe } = resolveToken(r.repo, true);
      const missing = authRequired(r.repo, "issue edit", probe);
      if (missing !== null || token === null) return missing ?? authRequired(r.repo, "issue edit", { present: false, source: null, ghFallbackAttempted: true });
      return withNumberOptionHint(issueEdit(r.repo, token, r.number, { ...options, repo: r.repo }), r);
    }
    if (sub === "update") {
      const r = resolvePositionalIssueReference(args, 2, "issue update", options);
      if (isGitHubCommandResult(r)) return r;
      const { token, probe } = resolveToken(r.repo, true);
      const missing = authRequired(r.repo, "issue update", probe);
      if (missing !== null || token === null) return missing ?? authRequired(r.repo, "issue update", { present: false, source: null, ghFallbackAttempted: true });
      return withNumberOptionHint(issueEdit(r.repo, token, r.number, { ...options, repo: r.repo }, "issue update"), r);
    }
    if (sub === "comment") {
      const r = resolvePositionalIssueReference(args, 2, "issue comment", options);
      if (isGitHubCommandResult(r)) return r;
      const { token, probe } = resolveToken(r.repo, true);
      const missing = authRequired(r.repo, "issue comment", probe);
      if (missing !== null || token === null) return missing ?? authRequired(r.repo, "issue comment", { present: false, source: null, ghFallbackAttempted: true });
      return withNumberOptionHint(issueComment(r.repo, token, r.number, { ...options, repo: r.repo }), r);
    }
    if (sub === "close") {
      const r = resolvePositionalIssueReference(args, 2, "issue close", options);
      if (isGitHubCommandResult(r)) return r;
      const { token, probe } = resolveToken(r.repo, true);
      const missing = authRequired(r.repo, "issue close", probe);
      if (missing !== null || token === null) return missing ?? authRequired(r.repo, "issue close", { present: false, source: null, ghFallbackAttempted: true });
      return withNumberOptionHint(issueState(r.repo, token, r.number, "closed", options.dryRun, { ...options, repo: r.repo }), r);
    }
    if (sub === "reopen") {
      const r = resolvePositionalIssueReference(args, 2, "issue reopen", options);
      if (isGitHubCommandResult(r)) return r;
      const { token, probe } = resolveToken(r.repo, true);
      const missing = authRequired(r.repo, "issue reopen", probe);
      if (missing !== null || token === null) return missing ?? authRequired(r.repo, "issue reopen", { present: false, source: null, ghFallbackAttempted: true });
      return withNumberOptionHint(issueState(r.repo, token, r.number, "open", options.dryRun, { ...options, repo: r.repo }), r);
    }
  }

  if (top === "pr") {
    if (sub === "diff") {
      const resolved = resolvePositionalPrReference(args, 2, "pr diff", options);
      if (isGitHubCommandResult(resolved)) return resolved;
      if (optionWasProvided(args, "--stat") && optionWasProvided(args, "--file")) {
        return validationError("pr diff", resolved.repo, "choose either --stat for file/stat summary or --file for bounded patch drill-down, not both", {
          supportedCommands: [
            `bun scripts/cli.ts gh pr diff ${resolved.number} --stat --repo ${resolved.repo} --limit 30`,
            `bun scripts/cli.ts gh pr diff ${resolved.number} --repo ${resolved.repo} --file ${options.filePath ?? "path/to/file"}`,
          ],
        });
      }
      if (optionWasProvided(args, "--file")) {
        const { token, probe } = resolveToken(resolved.repo, true);
        const missing = authRequired(resolved.repo, "pr diff", probe);
        if (missing !== null || token === null) return missing ?? authRequired(resolved.repo, "pr diff", { present: false, source: null, ghFallbackAttempted: true });
        return withNumberOptionHint(prDiffFile(resolved.repo, token, resolved.number, { ...options, repo: resolved.repo }), resolved);
      }
      if (!optionWasProvided(args, "--stat")) {
        return unsupportedCommand("pr diff", options.repo, "Raw PR diff output is intentionally unsupported by default; use gh pr review-plan for an index, gh pr diff <number> --file <path> for bounded patch drill-down, or gh pr diff <number> --stat for a file/stat summary.", {
          rawDiffIncluded: false,
          supportedCommands: [
            `bun scripts/cli.ts gh pr review-plan ${resolved.number} --repo ${resolved.repo}`,
            `bun scripts/cli.ts gh pr diff ${resolved.number} --repo ${resolved.repo} --file path/to/file`,
            `bun scripts/cli.ts gh pr files ${resolved.number} --repo ${resolved.repo} --limit 30`,
            `bun scripts/cli.ts gh pr diff ${resolved.number} --stat --repo ${resolved.repo} --limit 30`,
          ],
        });
      }
      const { token, probe } = resolveToken(resolved.repo, true);
      const missing = authRequired(resolved.repo, "pr diff --stat", probe);
      if (missing !== null || token === null) return missing ?? authRequired(resolved.repo, "pr diff --stat", { present: false, source: null, ghFallbackAttempted: true });
      return withNumberOptionHint(prFiles(resolved.repo, token, resolved.number, options.limit, "pr diff --stat"), resolved);
    }
    if (sub === "review-plan") {
      const resolved = resolvePositionalPrReference(args, 2, "pr review-plan", options);
      if (isGitHubCommandResult(resolved)) return resolved;
      const { token, probe } = resolveToken(resolved.repo, true);
      const missing = authRequired(resolved.repo, "pr review-plan", probe);
      if (missing !== null || token === null) return missing ?? authRequired(resolved.repo, "pr review-plan", { present: false, source: null, ghFallbackAttempted: true });
      return withNumberOptionHint(prReviewPlan(resolved.repo, token, resolved.number, options.limit), resolved);
    }
    if (sub === "files") {
      const resolved = resolvePositionalPrReference(args, 2, "pr files", options);
      if (isGitHubCommandResult(resolved)) return resolved;
      const { token, probe } = resolveToken(resolved.repo, true);
      const missing = authRequired(resolved.repo, "pr files", probe);
      if (missing !== null || token === null) return missing ?? authRequired(resolved.repo, "pr files", { present: false, source: null, ghFallbackAttempted: true });
      return withNumberOptionHint(prFiles(resolved.repo, token, resolved.number, options.limit, "pr files"), resolved);
    }
    if (sub === "delete") return unsupportedCommand("pr delete", options.repo, "GitHub REST does not support hard-deleting pull requests; use gh pr close for lifecycle deletion semantics.");
    if (sub === "preflight" || sub === "closeout") {
      const resolved = resolvePositionalPrReference(args, 2, `pr ${sub}`, options);
      if (isGitHubCommandResult(resolved)) return resolved;
      return withNumberOptionHint(prPreflight(resolved.repo, resolved.number, sub === "closeout" ? "pr closeout" : "pr preflight", options.full || options.raw), resolved);
    }
    if (sub === "comment" && third === "delete") {
      const resolved = resolvePositionalNumberReference("pr", args, 3, "pr comment delete", options);
      if (isGitHubCommandResult(resolved)) return resolved;
      if (options.dryRun) return withNumberOptionHint(commentDelete(resolved.repo, "", "pr", resolved.number, true), resolved);
      const { token, probe } = resolveToken(resolved.repo, true);
      const missing = authRequired(resolved.repo, "pr comment delete", probe);
      if (missing !== null || token === null) return missing ?? authRequired(resolved.repo, "pr comment delete", { present: false, source: null, ghFallbackAttempted: true });
      return withNumberOptionHint(commentDelete(resolved.repo, token, "pr", resolved.number, false), resolved);
    }
    if (sub === "comment" && (third === "view" || third === "read")) {
      const commandName = `pr comment ${third}`;
      const resolved = resolvePositionalNumberReference("pr", args, 3, commandName, options);
      if (isGitHubCommandResult(resolved)) return resolved;
      const { token, probe } = resolveToken(resolved.repo, true);
      const missing = authRequired(resolved.repo, commandName, probe);
      if (missing !== null || token === null) return missing ?? authRequired(resolved.repo, commandName, { present: false, source: null, ghFallbackAttempted: true });
      return withNumberOptionHint(commentView(resolved.repo, token, "pr", resolved.number, options.raw || options.full, commandName), resolved);
    }
    if (sub === "comment" && (third === "update" || third === "edit")) {
      const commandName = `pr comment ${third}`;
      const resolved = resolvePositionalNumberReference("pr", args, 3, commandName, options);
      if (isGitHubCommandResult(resolved)) return resolved;
      const updateOptions = { ...options, repo: resolved.repo };
      if (options.dryRun) return withNumberOptionHint(commentUpdate(resolved.repo, "", "pr", resolved.number, updateOptions, commandName), resolved);
      const { token, probe } = resolveToken(resolved.repo, true);
      const missing = authRequired(resolved.repo, commandName, probe);
      if (missing !== null || token === null) return missing ?? authRequired(resolved.repo, commandName, { present: false, source: null, ghFallbackAttempted: true });
      return withNumberOptionHint(commentUpdate(resolved.repo, token, "pr", resolved.number, updateOptions, commandName), resolved);
    }
    if (sub === "comment" && third === "create") {
      const resolved = resolvePositionalPrReference(args, 3, "pr comment create", options);
      if (isGitHubCommandResult(resolved)) return resolved;
      if (options.dryRun) return withNumberOptionHint(prComment(resolved.repo, "", resolved.number, { ...options, repo: resolved.repo }), resolved);
      const { token, probe } = resolveToken(resolved.repo, true);
      const missing = authRequired(resolved.repo, "pr comment create", probe);
      if (missing !== null || token === null) return missing ?? authRequired(resolved.repo, "pr comment create", { present: false, source: null, ghFallbackAttempted: true });
      return withNumberOptionHint(prComment(resolved.repo, token, resolved.number, { ...options, repo: resolved.repo }), resolved);
    }
    if (sub === "create") {
      if (options.dryRun) return prCreate(options.repo, "", options);
      const { token, probe } = resolveToken(options.repo, true);
      const missing = authRequired(options.repo, "pr create", probe);
      if (missing !== null || token === null) return missing ?? authRequired(options.repo, "pr create", { present: false, source: null, ghFallbackAttempted: true });
      return prCreate(options.repo, token, options);
    }
    if (sub === "comment") {
      if (options.dryRun) {
        const resolved = resolvePositionalPrReference(args, 2, "pr comment", options);
        if (isGitHubCommandResult(resolved)) return resolved;
        return withNumberOptionHint(prComment(resolved.repo, "", resolved.number, { ...options, repo: resolved.repo }), resolved);
      }
      const resolved = resolvePositionalPrReference(args, 2, "pr comment", options);
      if (isGitHubCommandResult(resolved)) return resolved;
      const { token, probe } = resolveToken(resolved.repo, true);
      const missing = authRequired(resolved.repo, "pr comment", probe);
      if (missing !== null || token === null) return missing ?? authRequired(resolved.repo, "pr comment", { present: false, source: null, ghFallbackAttempted: true });
      return withNumberOptionHint(prComment(resolved.repo, token, resolved.number, { ...options, repo: resolved.repo }), resolved);
    }
    if (sub === "update" || sub === "edit") {
      const commandName = `pr ${sub}`;
      const resolved = resolvePositionalPrReference(args, 2, commandName, options);
      if (isGitHubCommandResult(resolved)) return resolved;
      if (options.dryRun && options.mode === "replace") return withNumberOptionHint(prUpdate(resolved.repo, "", resolved.number, { ...options, repo: resolved.repo }, commandName), resolved);
      const { token, probe } = resolveToken(resolved.repo, true);
      const missing = authRequired(resolved.repo, commandName, probe);
      if (missing !== null || token === null) return missing ?? authRequired(resolved.repo, commandName, { present: false, source: null, ghFallbackAttempted: true });
      return withNumberOptionHint(prUpdate(resolved.repo, token, resolved.number, { ...options, repo: resolved.repo }, commandName), resolved);
    }
    if (sub === "close" || sub === "reopen") {
      const resolved = resolvePositionalPrReference(args, 2, `pr ${sub}`, options);
      if (isGitHubCommandResult(resolved)) return resolved;
      if (options.dryRun) return withNumberOptionHint(prState(resolved.repo, "", resolved.number, sub === "close" ? "closed" : "open", true), resolved);
      const { token, probe } = resolveToken(resolved.repo, true);
      const missing = authRequired(resolved.repo, `pr ${sub}`, probe);
      if (missing !== null || token === null) return missing ?? authRequired(resolved.repo, `pr ${sub}`, { present: false, source: null, ghFallbackAttempted: true });
      return withNumberOptionHint(prState(resolved.repo, token, resolved.number, sub === "close" ? "closed" : "open", false), resolved);
    }
    if (sub === "ready") {
      const resolved = resolvePositionalPrReference(args, 2, "pr ready", options);
      if (isGitHubCommandResult(resolved)) return resolved;
      const { token, probe } = resolveToken(resolved.repo, true);
      const missing = authRequired(resolved.repo, "pr ready", probe);
      if (missing !== null || token === null) return missing ?? authRequired(resolved.repo, "pr ready", { present: false, source: null, ghFallbackAttempted: true });
      return withNumberOptionHint(prReady(resolved.repo, token, resolved.number, options.dryRun), resolved);
    }
    if (sub === "merge") {
      const resolved = resolvePositionalPrReference(args, 2, "pr merge", options);
      if (isGitHubCommandResult(resolved)) return resolved;
      const { token, probe } = resolveToken(resolved.repo, true);
      const missing = authRequired(resolved.repo, "pr merge", probe);
      if (missing !== null || token === null) return missing ?? authRequired(resolved.repo, "pr merge", { present: false, source: null, ghFallbackAttempted: true });
      return withNumberOptionHint(prMerge(resolved.repo, token, resolved.number, options), resolved);
    }
    if (sub !== "list" && !isPrReadCommand(sub)) {
      return unsupportedCommand(`pr ${sub ?? ""}`.trim(), options.repo, "PR supported commands are list, files, diff --stat, read/view, preflight/closeout, create, update/edit, close, reopen, ready, merge, comment create/update/edit/delete, and unsupported delete.");
    }
    if (sub === "read" || sub === "view") {
      const resolved = resolveReadViewNumberReference("pr", sub, third, options, args);
      if (isGitHubCommandResult(resolved)) return resolved;
      const { token, probe } = resolveToken(resolved.repo, true);
      const missing = authRequired(resolved.repo, `pr ${sub}`, probe);
      if (missing !== null || token === null) return missing ?? authRequired(resolved.repo, `pr ${sub}`, { present: false, source: null, ghFallbackAttempted: true });
      const disclosure = readDisclosureOptions(options, resolved.shorthand);
      if (sub === "read") return withNumberOptionHint(prRead(resolved.repo, token, resolved.number, prReadJsonFields(options), "pr read", disclosure), resolved);
      return withNumberOptionHint(prView(resolved.repo, token, resolved.number, prReadJsonFields(options), disclosure), resolved);
    }
    const { token, probe } = resolveToken(options.repo, true);
    const missing = authRequired(options.repo, `pr ${sub}`, probe);
    if (missing !== null || token === null) return missing ?? authRequired(options.repo, `pr ${sub}`, { present: false, source: null, ghFallbackAttempted: true });
    if (sub === "list") return prList(options.repo, token, options.prListState, options.limit, options.prListJsonFields, options.raw || options.full);
  }

  return unsupportedCommand(args.join(" ") || "gh", options.repo, "Unsupported gh command", { help: ghHelp() });
}
